diff --git a/.env.example b/.env.example index 9920f34e706e4df5793c45ca4e1242b892322235..203c78740f26a84d23ea43b4336bdc226cbafecc 100644 --- a/.env.example +++ b/.env.example @@ -25,9 +25,10 @@ AllowedOrigins__0=http://localhost:8080 AllowedOrigins__1=https://www.yourdomain.com # Quartz jobs -JobKeys__0=ReservationExpirationCheckJob -JobKeys__1=MailServiceCheckJob -JobKeys__2=RedisServiceCheckJob +JobKeys__0=ReservationExpirationCheckJob:0 0 1 * * ? +JobKeys__1=MailServiceCheckJob:0 */5 * * * ? +JobKeys__2=RedisServiceCheckJob:0 */5 * * * ? +JobKeys__3=AutomaticallyUpgradeMembershipLevelJob:0 30 1 * * ? ExpirationSettings__NotifyDaysBefore=3 ExpirationSettings__CheckIntervalMinutes=5 @@ -52,6 +53,14 @@ Mail__DisplayName=TSHotel Redis__Enabled=false Redis__ConnectionString=${REDIS_CONNECTION_STRING} Redis__DefaultDatabase=0 +Redis__ConnectTimeoutMs=5000 +Redis__AsyncTimeoutMs=2000 +Redis__SyncTimeoutMs=2000 +Redis__KeepAliveSeconds=15 +Redis__ConnectRetry=3 +Redis__ReconnectRetryBaseDelayMs=3000 +Redis__OperationTimeoutMs=1200 +Redis__FailureCooldownSeconds=30 # Lsky (optional) Lsky__Enabled=false diff --git a/.gitignore b/.gitignore index 46058609ea76f1a2f4b7d3c4e1189f0572099e80..aa1f521d7d74a546fae9a7ca5fd7c0132ff100b3 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ frontend/ .version *.txt docs/ +.codex-staging/ # Visual Studio 2015/2017 cache/options directory .vs/ diff --git a/EOM.TSHotelManagement.API/Authorization/PermissionsAuthorization.cs b/EOM.TSHotelManagement.API/Authorization/PermissionsAuthorization.cs index e37fa554ac097e2c92e756db28bb331f8281a261..b2884f678c2f8e51b6534b63e0fcb652e6494c89 100644 --- a/EOM.TSHotelManagement.API/Authorization/PermissionsAuthorization.cs +++ b/EOM.TSHotelManagement.API/Authorization/PermissionsAuthorization.cs @@ -135,7 +135,7 @@ namespace EOM.TSHotelManagement.WebApi.Authorization // 获取用户绑定的有效角色 var roleNumbers = await _db.Queryable() - .Where(ur => ur.UserNumber == userNumber && ur.IsDelete != 1) + .Where(ur => ur.UserNumber == userNumber) .Select(ur => ur.RoleNumber) .ToListAsync(); @@ -147,8 +147,7 @@ namespace EOM.TSHotelManagement.WebApi.Authorization // 判断角色是否拥有该权限 var hasPermission = await _db.Queryable() - .Where(rp => rp.IsDelete != 1 - && roleNumbers.Contains(rp.RoleNumber) + .Where(rp => roleNumbers.Contains(rp.RoleNumber) && rp.PermissionNumber == requirement.Code) .AnyAsync(); diff --git a/EOM.TSHotelManagement.API/Controllers/Application/FavoriteCollection/FavoriteCollectionController.cs b/EOM.TSHotelManagement.API/Controllers/Application/FavoriteCollection/FavoriteCollectionController.cs new file mode 100644 index 0000000000000000000000000000000000000000..80936838b47619fb262a43f732badbf0ca40f21f --- /dev/null +++ b/EOM.TSHotelManagement.API/Controllers/Application/FavoriteCollection/FavoriteCollectionController.cs @@ -0,0 +1,44 @@ +using EOM.TSHotelManagement.Contract; +using EOM.TSHotelManagement.Service; +using Microsoft.AspNetCore.Mvc; + +namespace EOM.TSHotelManagement.WebApi.Controllers +{ + /// + /// 收藏夹持久化接口 + /// + public class FavoriteCollectionController : ControllerBase + { + private readonly IFavoriteCollectionService _favoriteCollectionService; + + /// + /// 构造收藏夹控制器 + /// + /// 收藏夹服务 + public FavoriteCollectionController(IFavoriteCollectionService favoriteCollectionService) + { + _favoriteCollectionService = favoriteCollectionService; + } + + /// + /// 保存当前登录用户的收藏夹快照 + /// + /// 收藏夹保存请求 + /// 保存结果 + [HttpPost] + public SingleOutputDto SaveFavoriteCollection([FromBody] SaveFavoriteCollectionInputDto input) + { + return _favoriteCollectionService.SaveFavoriteCollection(input); + } + + /// + /// 获取当前登录用户的收藏夹快照 + /// + /// 收藏夹读取结果 + [HttpGet] + public SingleOutputDto GetFavoriteCollection() + { + return _favoriteCollectionService.GetFavoriteCollection(); + } + } +} diff --git a/EOM.TSHotelManagement.API/Controllers/Application/Profile/ProfileController.cs b/EOM.TSHotelManagement.API/Controllers/Application/Profile/ProfileController.cs new file mode 100644 index 0000000000000000000000000000000000000000..02db3036cc7c953532a587bdb25f29545fdf6c68 --- /dev/null +++ b/EOM.TSHotelManagement.API/Controllers/Application/Profile/ProfileController.cs @@ -0,0 +1,78 @@ +using EOM.TSHotelManagement.Common; +using EOM.TSHotelManagement.Contract; +using EOM.TSHotelManagement.Service; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using System; +using System.Security.Claims; +using System.Threading.Tasks; + +namespace EOM.TSHotelManagement.WebApi.Controllers +{ + /// + /// 个人中心控制器 + /// + public class ProfileController( + IProfileService profileService, + JwtTokenRevocationService tokenRevocationService, + ILogger logger) : ControllerBase + { + private readonly IProfileService _profileService = profileService; + private readonly JwtTokenRevocationService _tokenRevocationService = tokenRevocationService; + private readonly ILogger _logger = logger; + + /// + /// 获取当前登录人基础资料 + /// + [HttpGet] + public SingleOutputDto GetCurrentProfile() + { + return _profileService.GetCurrentProfile(GetCurrentSerialNumber()); + } + + /// + /// 上传当前登录人头像 + /// + [HttpPost] + public async Task> UploadAvatar([FromForm] UploadAvatarInputDto inputDto, IFormFile file) + { + return await _profileService.UploadAvatar(GetCurrentSerialNumber(), inputDto, file); + } + + /// + /// 修改当前登录人密码 + /// + [HttpPost] + public BaseResponse ChangePassword([FromBody] ChangePasswordInputDto inputDto) + { + var response = _profileService.ChangePassword(GetCurrentSerialNumber(), inputDto); + if (!response.Success) + { + return response; + } + + try + { + var authorizationHeader = Request.Headers["Authorization"].ToString(); + if (JwtTokenRevocationService.TryGetBearerToken(authorizationHeader, out var token)) + { + Task.Run(async () => { await _tokenRevocationService.RevokeTokenAsync(token); }); + } + } + catch (Exception ex) + { + _logger.LogWarning(ex, "Failed to revoke current token after password change."); + } + + return response; + } + + private string GetCurrentSerialNumber() + { + return User.FindFirstValue(ClaimTypes.SerialNumber) + ?? User.FindFirst("serialnumber")?.Value + ?? string.Empty; + } + } +} diff --git a/EOM.TSHotelManagement.API/Controllers/Business/Spend/SpendController.cs b/EOM.TSHotelManagement.API/Controllers/Business/Spend/SpendController.cs index 136169da66e4c93a1506e79368e6a964149c780f..227cca3dc477067d8348859645c25ef984e65248 100644 --- a/EOM.TSHotelManagement.API/Controllers/Business/Spend/SpendController.cs +++ b/EOM.TSHotelManagement.API/Controllers/Business/Spend/SpendController.cs @@ -67,13 +67,13 @@ namespace EOM.TSHotelManagement.WebApi.Controllers /// /// 撤回客户消费信息 /// - /// + /// /// [RequirePermission("customerspend.ucs")] [HttpPost] - public BaseResponse UndoCustomerSpend([FromBody] UpdateSpendInputDto updateSpendInputDto) + public BaseResponse UndoCustomerSpend([FromBody] UndoCustomerSpendInputDto undoCustomerSpendInputDto) { - return spendService.UndoCustomerSpend(updateSpendInputDto); + return spendService.UndoCustomerSpend(undoCustomerSpendInputDto); } /// diff --git a/EOM.TSHotelManagement.API/Controllers/SystemManagement/Quartz/QuartzController.cs b/EOM.TSHotelManagement.API/Controllers/SystemManagement/Quartz/QuartzController.cs new file mode 100644 index 0000000000000000000000000000000000000000..019999a1e8c2beace1bc0c01a1f38a097ba9325e --- /dev/null +++ b/EOM.TSHotelManagement.API/Controllers/SystemManagement/Quartz/QuartzController.cs @@ -0,0 +1,27 @@ +using EOM.TSHotelManagement.Contract; +using EOM.TSHotelManagement.Service; +using Microsoft.AspNetCore.Mvc; +using System.Threading.Tasks; + +namespace EOM.TSHotelManagement.WebApi.Controllers +{ + public class QuartzController : ControllerBase + { + private readonly IQuartzAppService _quartzAppService; + + public QuartzController(IQuartzAppService quartzAppService) + { + _quartzAppService = quartzAppService; + } + + /// + /// 查询当前已注册的Quartz任务和触发器列表 + /// + /// + [HttpGet] + public async Task> SelectQuartzJobList() + { + return await _quartzAppService.SelectQuartzJobList(); + } + } +} diff --git a/EOM.TSHotelManagement.API/Controllers/SystemManagement/Role/RoleController.cs b/EOM.TSHotelManagement.API/Controllers/SystemManagement/Role/RoleController.cs index 04c9eeb98accad45b71e311871b54db86a821bea..76573330c3733fb0740acbf5cec70ad1d1ef2d1f 100644 --- a/EOM.TSHotelManagement.API/Controllers/SystemManagement/Role/RoleController.cs +++ b/EOM.TSHotelManagement.API/Controllers/SystemManagement/Role/RoleController.cs @@ -87,6 +87,16 @@ namespace EOM.TSHotelManagement.WebApi.Controllers return _roleAppService.ReadRolePermissions(input.RoleNumber); } + /// + /// 读取指定角色菜单和权限授权(菜单与权限独立) + /// + [RequirePermission("system:role:rrg")] + [HttpPost] + public SingleOutputDto ReadRoleGrants([FromBody] ReadByRoleNumberInputDto input) + { + return _roleAppService.ReadRoleGrants(input.RoleNumber); + } + /// /// 读取隶属于指定角色的管理员用户编码集合 /// diff --git a/EOM.TSHotelManagement.API/EOM.TSHotelManagement.API.csproj b/EOM.TSHotelManagement.API/EOM.TSHotelManagement.API.csproj index 4e8ca9d199776ef3b1a3212389728f54a9dac19e..5030be8fdd562c93d7fe195082f560da56500e3d 100644 --- a/EOM.TSHotelManagement.API/EOM.TSHotelManagement.API.csproj +++ b/EOM.TSHotelManagement.API/EOM.TSHotelManagement.API.csproj @@ -23,7 +23,7 @@ - + diff --git a/EOM.TSHotelManagement.API/Extensions/ApplicationExtensions.cs b/EOM.TSHotelManagement.API/Extensions/ApplicationExtensions.cs index f3342a52482ace48f38036a44b7503bd6eb1b8d0..c08e4fc2e2b03de26bf0cfca34b853419c3cb650 100644 --- a/EOM.TSHotelManagement.API/Extensions/ApplicationExtensions.cs +++ b/EOM.TSHotelManagement.API/Extensions/ApplicationExtensions.cs @@ -85,7 +85,7 @@ namespace EOM.TSHotelManagement.WebApi { app.MapControllers(); app.MapGet("api/version", () => - $"Software Version: {Environment.GetEnvironmentVariable("SoftwareVersion") ?? "Local Mode"}"); + $"Software Version: {SoftwareVersionHelper.GetSoftwareVersion(app.Configuration["SoftwareVersion"], "Local Mode")}"); } public static void ConfigureSwaggerUI(this WebApplication app) diff --git a/EOM.TSHotelManagement.API/Extensions/PermissionSyncExtensions.cs b/EOM.TSHotelManagement.API/Extensions/PermissionSyncExtensions.cs index 53b471808706cf310113bafcc2ad9822df228f94..52efbb6c28c153434c77e1f537b3df1fed346611 100644 --- a/EOM.TSHotelManagement.API/Extensions/PermissionSyncExtensions.cs +++ b/EOM.TSHotelManagement.API/Extensions/PermissionSyncExtensions.cs @@ -67,7 +67,6 @@ namespace EOM.TSHotelManagement.WebApi // 查询已有权限 var existing = db.Queryable() - .Where(p => p.IsDelete != 1) .Select(p => p.PermissionNumber) .ToList(); @@ -88,7 +87,6 @@ namespace EOM.TSHotelManagement.WebApi Description = "Auto-synced from [RequirePermission] on API action", MenuKey = null, ParentNumber = null, - IsDelete = 0, DataInsUsr = "System", DataInsDate = now }).ToList(); @@ -104,7 +102,9 @@ namespace EOM.TSHotelManagement.WebApi // 默认将所有扫描到的权限与超级管理员角色关联 // 如角色不存在,DatabaseInitializer 已负责创建;此处仅做映射补齐 var existingRolePerms = db.Queryable() - .Where(rp => rp.RoleNumber == AdminRoleNumber && rp.IsDelete != 1) + .Where(rp => rp.RoleNumber == AdminRoleNumber + && rp.PermissionNumber != null + && rp.PermissionNumber != "") .Select(rp => rp.PermissionNumber) .ToList(); @@ -121,7 +121,6 @@ namespace EOM.TSHotelManagement.WebApi { RoleNumber = AdminRoleNumber, PermissionNumber = p, - IsDelete = 0, DataInsUsr = "System", DataInsDate = now }).ToList(); @@ -161,4 +160,4 @@ namespace EOM.TSHotelManagement.WebApi return "api"; } } -} \ No newline at end of file +} diff --git a/EOM.TSHotelManagement.API/Extensions/ServiceExtensions.cs b/EOM.TSHotelManagement.API/Extensions/ServiceExtensions.cs index 14b066ad61bcb5e91ec920a3407d194bbbb28cd6..083b0c1df00d49dafd5e73096c3a2b17af0fb160 100644 --- a/EOM.TSHotelManagement.API/Extensions/ServiceExtensions.cs +++ b/EOM.TSHotelManagement.API/Extensions/ServiceExtensions.cs @@ -20,6 +20,7 @@ using NSwag; using NSwag.Generation.Processors.Security; using Quartz; using System; +using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.IO; using System.Linq; @@ -59,57 +60,35 @@ namespace EOM.TSHotelManagement.WebApi services.AddQuartz(q => { var jobs = configuration.GetSection(SystemConstant.JobKeys.Code).Get() ?? Array.Empty(); + var jobRegistrations = new Dictionary>(StringComparer.OrdinalIgnoreCase) + { + [nameof(ReservationExpirationCheckJob)] = (configurator, jobName, cronExpression) => + RegisterJobAndTrigger(configurator, jobName, cronExpression), + [nameof(MailServiceCheckJob)] = (configurator, jobName, cronExpression) => + RegisterJobAndTrigger(configurator, jobName, cronExpression), + [nameof(ImageHostingServiceCheckJob)] = (configurator, jobName, cronExpression) => + RegisterJobAndTrigger(configurator, jobName, cronExpression), + [nameof(RedisServiceCheckJob)] = (configurator, jobName, cronExpression) => + RegisterJobAndTrigger(configurator, jobName, cronExpression), + [nameof(AutomaticallyUpgradeMembershipLevelJob)] = (configurator, jobName, cronExpression) => + RegisterJobAndTrigger(configurator, jobName, cronExpression) + }; + var registeredJobs = new HashSet(StringComparer.OrdinalIgnoreCase); - foreach (var job in jobs) + foreach (var job in jobs.Where(a => !string.IsNullOrWhiteSpace(a)).Distinct(StringComparer.OrdinalIgnoreCase)) { - var reservationJobKey = $"{job}-Reservation"; - var mailJobKey = $"{job}-Mail"; - var imageHostingJobKey = $"{job}-ImageHosting"; - var redisJobKey = $"{job}-Redis"; - - q.AddJob(opts => opts - .WithIdentity(reservationJobKey) - .StoreDurably() - .WithDescription($"{reservationJobKey} 定时作业")); - - q.AddTrigger(opts => opts - .ForJob(reservationJobKey) - .WithIdentity($"{reservationJobKey}-Trigger") - //.WithCronSchedule("* * * * * ? ")); // Debug Use Only 每秒执行一次 - .WithCronSchedule("0 0 1 * * ?")); // 每天1:00 AM执行 - - q.AddJob(opts => opts - .WithIdentity(mailJobKey) - .StoreDurably() - .WithDescription($"{mailJobKey} 定时作业")); - - q.AddTrigger(opts => opts - .ForJob(mailJobKey) - .WithIdentity($"{mailJobKey}-Trigger") - //.WithCronSchedule("* * * * * ? ")); // Debug Use Only 每秒执行一次 - .WithCronSchedule("0 */5 * * * ?")); // 每5分钟执行一次 - - q.AddJob(opts => opts - .WithIdentity(imageHostingJobKey) - .StoreDurably() - .WithDescription($"{imageHostingJobKey} 定时作业")); - - q.AddTrigger(opts => opts - .ForJob(imageHostingJobKey) - .WithIdentity($"{imageHostingJobKey}-Trigger") - //.WithCronSchedule("* * * * * ? ")); // Debug Use Only 每秒执行一次 - .WithCronSchedule("0 */5 * * * ?")); // 每5分钟执行一次 - - q.AddJob(opts => opts - .WithIdentity(redisJobKey) - .StoreDurably() - .WithDescription($"{redisJobKey} 定时作业")); - - q.AddTrigger(opts => opts - .ForJob(redisJobKey) - .WithIdentity($"{redisJobKey}-Trigger") - //.WithCronSchedule("* * * * * ? ")); // Debug Use Only 每秒执行一次 - .WithCronSchedule("0 */5 * * * ?")); // 每5分钟执行一次 + var (jobName, cronExpression) = ParseJobRegistration(job); + if (!registeredJobs.Add(jobName)) + { + throw new InvalidOperationException($"Duplicate quartz job configuration found for '{jobName}'."); + } + + if (!jobRegistrations.TryGetValue(jobName, out var register)) + { + throw new InvalidOperationException($"Unsupported quartz job '{jobName}' in '{SystemConstant.JobKeys.Code}'."); + } + + register(q, jobName, cronExpression); } }); @@ -121,6 +100,41 @@ namespace EOM.TSHotelManagement.WebApi }); } + private static void RegisterJobAndTrigger(IServiceCollectionQuartzConfigurator quartz, string jobName, string cronExpression) + where TJob : IJob + { + quartz.AddJob(opts => opts + .WithIdentity(jobName) + .StoreDurably() + .WithDescription($"{jobName} 定时作业")); + + quartz.AddTrigger(opts => opts + .ForJob(jobName) + .WithIdentity($"{jobName}-Trigger") + .WithCronSchedule(cronExpression)); + } + + private static (string JobName, string CronExpression) ParseJobRegistration( + string jobConfiguration) + { + var entry = jobConfiguration?.Trim() ?? string.Empty; + if (string.IsNullOrWhiteSpace(entry)) + { + throw new InvalidOperationException($"Invalid quartz job configuration value in '{SystemConstant.JobKeys.Code}'."); + } + + var separatorIndex = entry.IndexOf(':'); + if (separatorIndex > 0 && separatorIndex < entry.Length - 1) + { + var jobName = entry[..separatorIndex].Trim(); + var cronExpression = entry[(separatorIndex + 1)..].Trim(); + return (jobName, cronExpression); + } + + throw new InvalidOperationException( + $"Quartz job '{entry}' is missing cron expression. Use 'JobName:CronExpression' format."); + } + public static void ConfigureXForward(this IServiceCollection services) { services.Configure(options => diff --git a/EOM.TSHotelManagement.API/Filters/RequestLoggingMiddleware.cs b/EOM.TSHotelManagement.API/Filters/RequestLoggingMiddleware.cs index ddad22c74577a1301d1dbc4f35007eddb06da29c..a930483960c1ee0fec7858c7434f94192be22738 100644 --- a/EOM.TSHotelManagement.API/Filters/RequestLoggingMiddleware.cs +++ b/EOM.TSHotelManagement.API/Filters/RequestLoggingMiddleware.cs @@ -25,9 +25,7 @@ public class RequestLoggingMiddleware { _next = next; _logger = logger; - _softwareVersion = Environment.GetEnvironmentVariable("APP_VERSION") - ?? config["SoftwareVersion"] - ?? GetDefaultVersion(); + _softwareVersion = EOM.TSHotelManagement.Common.SoftwareVersionHelper.GetSoftwareVersion(config["SoftwareVersion"]); } public async Task InvokeAsync(HttpContext context) @@ -147,30 +145,6 @@ public class RequestLoggingMiddleware return (long)((stop - start) * 1000 / (double)Stopwatch.Frequency); } - private string GetDefaultVersion() - { - try - { - var rootPath = Path.GetDirectoryName(GetType().Assembly.Location); - var versionFilePath = Path.Combine(rootPath, "version.txt"); - - if (File.Exists(versionFilePath)) - { - var versionContent = File.ReadAllText(versionFilePath).Trim(); - if (!string.IsNullOrWhiteSpace(versionContent)) - { - return versionContent; - } - } - } - catch (Exception ex) - { - Debug.WriteLine($"Error reading version.txt: {ex.Message}"); - } - - return GetType().Assembly.GetName().Version?.ToString(3) ?? "1.0.0"; - } - private async Task GetRequestParametersAsync(HttpRequest request) { if (request.Method.Equals("GET", StringComparison.OrdinalIgnoreCase)) @@ -245,4 +219,4 @@ public class RequestLoggingMiddleware ip.StartsWith("172.30.") || ip.StartsWith("172.31."); } -} \ No newline at end of file +} diff --git a/EOM.TSHotelManagement.API/appsettings.Application.json b/EOM.TSHotelManagement.API/appsettings.Application.json index b77796a8dd15e4a5d466c257ffb92b47f94e8cc8..f5f5b47fb267df1d8a2f3d130d20eaf323e1211f 100644 --- a/EOM.TSHotelManagement.API/appsettings.Application.json +++ b/EOM.TSHotelManagement.API/appsettings.Application.json @@ -12,9 +12,17 @@ ], "AllowedHosts": "*", "JobKeys": [ - "ReservationExpirationCheckJob", - "MailServiceCheckJob", - "RedisServiceCheckJob" + // For production + "ReservationExpirationCheckJob:0 0 1 * * ?", + "MailServiceCheckJob:0 */5 * * * ?", + "RedisServiceCheckJob:0 */5 * * * ?", + "AutomaticallyUpgradeMembershipLevelJob:0 */5 * * * ?" + + // For testing "* * * * * ? " + //"ReservationExpirationCheckJob:* * * * * ? ", + //"MailServiceCheckJob:* * * * * ? ", + //"RedisServiceCheckJob:* * * * * ? ", + //"AutomaticallyUpgradeMembershipLevelJob:* * * * * ? " ], "ExpirationSettings": { "NotifyDaysBefore": 3, diff --git a/EOM.TSHotelManagement.API/appsettings.Database.json b/EOM.TSHotelManagement.API/appsettings.Database.json index f4844c299062d2f9cfed4867e12420aadcb53eab..0c7186c7c647d9cc19897377a9a7ecbde3c778db 100644 --- a/EOM.TSHotelManagement.API/appsettings.Database.json +++ b/EOM.TSHotelManagement.API/appsettings.Database.json @@ -10,7 +10,15 @@ "Redis": { "Enabled": false, "ConnectionString": "host:port,password=your_redis_password", - "DefaultDatabase": 0 + "DefaultDatabase": 1, + "ConnectTimeoutMs": 5000, + "AsyncTimeoutMs": 2000, + "SyncTimeoutMs": 2000, + "KeepAliveSeconds": 15, + "ConnectRetry": 3, + "ReconnectRetryBaseDelayMs": 3000, + "OperationTimeoutMs": 1200, + "FailureCooldownSeconds": 30 }, "InitializeDatabase": false } diff --git a/EOM.TSHotelManagement.Common/Constant/CheckTypeConstant.cs b/EOM.TSHotelManagement.Common/Constant/CheckTypeConstant.cs new file mode 100644 index 0000000000000000000000000000000000000000..9568ac66bf82ab4767205a280dc9dd86885f8e0d --- /dev/null +++ b/EOM.TSHotelManagement.Common/Constant/CheckTypeConstant.cs @@ -0,0 +1,22 @@ +using EOM.TSHotelManagement.Infrastructure; +using System; +using System.Collections.Generic; +using System.Text; + +namespace EOM.TSHotelManagement.Common; + +public class CheckTypeConstant : CodeConstantBase +{ + /// + /// 客户端 + /// + public static readonly CheckTypeConstant Client = new CheckTypeConstant("Client", "客户端"); + /// + /// 网页端 + /// + public static readonly CheckTypeConstant Web = new CheckTypeConstant("Web", "网页端"); + private CheckTypeConstant(string code, string description) : base(code, description) + { + + } +} diff --git a/EOM.TSHotelManagement.Common/Constant/SpendTypeConstant.cs b/EOM.TSHotelManagement.Common/Constant/SpendTypeConstant.cs index c03aee1695da5acd98a883f474e5f2b038246ecc..a1dca3720c7b3e978a7a8f5dcdff30c56ffaa789 100644 --- a/EOM.TSHotelManagement.Common/Constant/SpendTypeConstant.cs +++ b/EOM.TSHotelManagement.Common/Constant/SpendTypeConstant.cs @@ -1,10 +1,10 @@ -using EOM.TSHotelManagement.Infrastructure; +using EOM.TSHotelManagement.Infrastructure; namespace EOM.TSHotelManagement.Common { public class SpendTypeConstant : CodeConstantBase { - public static readonly SpendTypeConstant Product = new SpendTypeConstant("Product", "商品"); + public static readonly SpendTypeConstant Product = new SpendTypeConstant("Goods", "商品"); public static readonly SpendTypeConstant Room = new SpendTypeConstant("Room", "房间"); public static readonly SpendTypeConstant Other = new SpendTypeConstant("Other", "其他"); diff --git a/EOM.TSHotelManagement.Common/EOM.TSHotelManagement.Common.csproj b/EOM.TSHotelManagement.Common/EOM.TSHotelManagement.Common.csproj index a0d5fece4ab1882fc2fd811c905c27459c354859..1f099603be5c6402db6c64340e0be20a841ca24b 100644 --- a/EOM.TSHotelManagement.Common/EOM.TSHotelManagement.Common.csproj +++ b/EOM.TSHotelManagement.Common/EOM.TSHotelManagement.Common.csproj @@ -20,18 +20,18 @@ - - + + - + + - + - diff --git a/EOM.TSHotelManagement.Common/Helper/ClaimsPrincipalExtensions.cs b/EOM.TSHotelManagement.Common/Helper/ClaimsPrincipalExtensions.cs new file mode 100644 index 0000000000000000000000000000000000000000..91e6dbc58b60efed4e25b1bb95bff32af14cb1e0 --- /dev/null +++ b/EOM.TSHotelManagement.Common/Helper/ClaimsPrincipalExtensions.cs @@ -0,0 +1,15 @@ +using System.Security.Claims; + +namespace EOM.TSHotelManagement.Common +{ + public static class ClaimsPrincipalExtensions + { + public static string GetUserNumber(this ClaimsPrincipal? principal) + { + return principal?.FindFirst(ClaimTypes.SerialNumber)?.Value + ?? principal?.FindFirst("serialnumber")?.Value + ?? principal?.FindFirst(ClaimTypes.NameIdentifier)?.Value + ?? string.Empty; + } + } +} diff --git a/EOM.TSHotelManagement.Common/Helper/DataProtectionHelper.cs b/EOM.TSHotelManagement.Common/Helper/DataProtectionHelper.cs index 8241879cae3b29d555e3baba3eef53fdd76ddfcd..267eb3325d8e3f9ced25cda94e7d051b5909f862 100644 --- a/EOM.TSHotelManagement.Common/Helper/DataProtectionHelper.cs +++ b/EOM.TSHotelManagement.Common/Helper/DataProtectionHelper.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.DataProtection; using System.Security.Cryptography; namespace EOM.TSHotelManagement.Common @@ -67,6 +67,10 @@ namespace EOM.TSHotelManagement.Common private string EncryptData(string plainText, IDataProtector protector) { + if (LooksLikeDataProtectionPayload(plainText)) + { + return plainText; + } return string.IsNullOrEmpty(plainText) ? plainText : protector.Protect(plainText); diff --git a/EOM.TSHotelManagement.Common/Helper/EntityMapper.cs b/EOM.TSHotelManagement.Common/Helper/EntityMapper.cs index db5d8687c3ce69a1892aeb2c0cb5c4cd9ee4ad40..0599119c6c318f1108dbca845a2d5341ef917448 100644 --- a/EOM.TSHotelManagement.Common/Helper/EntityMapper.cs +++ b/EOM.TSHotelManagement.Common/Helper/EntityMapper.cs @@ -2,19 +2,95 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; +using Mapster; namespace EOM.TSHotelManagement.Common { public static class EntityMapper { /// - /// 映射单个实体 + /// Maps a single object instance. /// public static TDestination Map(TSource source) where TDestination : new() { if (source == null) return default; + try + { + var destination = source.Adapt(); + ApplyLegacyOverrides(source, destination); + return destination; + } + catch + { + return LegacyMap(source); + } + } + + /// + /// Maps a list of objects. + /// + public static List MapList(List sourceList) + where TDestination : new() + { + return sourceList?.Select(Map).ToList(); + } + + // Preserve the legacy edge cases while Mapster handles the common path. + private static void ApplyLegacyOverrides(TSource source, TDestination destination) + { + var sourceProperties = typeof(TSource).GetProperties( + BindingFlags.Public | BindingFlags.Instance); + var destinationProperties = typeof(TDestination).GetProperties( + BindingFlags.Public | BindingFlags.Instance); + + foreach (var destinationProperty in destinationProperties) + { + if (!destinationProperty.CanWrite) continue; + + var exactSourceProperty = sourceProperties + .SingleOrDefault(p => p.Name.Equals(destinationProperty.Name, StringComparison.Ordinal)); + var matchedSourceProperty = exactSourceProperty ?? sourceProperties + .SingleOrDefault(p => p.Name.Equals(destinationProperty.Name, StringComparison.OrdinalIgnoreCase)); + + if (matchedSourceProperty == null) continue; + + var sourceValue = matchedSourceProperty.GetValue(source); + + if (sourceValue == null) + { + if (destinationProperty.Name.Equals("RowVersion", StringComparison.OrdinalIgnoreCase) + && destinationProperty.PropertyType == typeof(long)) + { + destinationProperty.SetValue(destination, 0L); + continue; + } + + if (destinationProperty.PropertyType.IsValueType && + Nullable.GetUnderlyingType(destinationProperty.PropertyType) != null) + { + destinationProperty.SetValue(destination, null); + } + + continue; + } + + if (matchedSourceProperty.Name.Equals(destinationProperty.Name, StringComparison.Ordinal) && + !NeedConversion(matchedSourceProperty.PropertyType, destinationProperty.PropertyType)) + { + continue; + } + + destinationProperty.SetValue( + destination, + ConvertValue(sourceValue, destinationProperty.PropertyType)); + } + } + + private static TDestination LegacyMap(TSource source) + where TDestination : new() + { var destination = new TDestination(); var sourceProperties = typeof(TSource).GetProperties( @@ -34,23 +110,8 @@ namespace EOM.TSHotelManagement.Common var sourceValue = sourceProperty.GetValue(source); - if (sourceValue is DateOnly dateOnlyValue && - destinationProperty.PropertyType == typeof(DateTime?)) - { - if (dateOnlyValue == DateOnly.MinValue || dateOnlyValue == new DateOnly(1900, 1, 1)) - { - destinationProperty.SetValue(destination, null); - } - else - { - destinationProperty.SetValue(destination, dateOnlyValue.ToDateTime(TimeOnly.MinValue)); - } - continue; - } - if (sourceValue == null) { - // Ensure optimistic-lock version does not silently fall back to entity defaults. if (destinationProperty.Name.Equals("RowVersion", StringComparison.OrdinalIgnoreCase) && destinationProperty.PropertyType == typeof(long)) { @@ -63,22 +124,30 @@ namespace EOM.TSHotelManagement.Common { destinationProperty.SetValue(destination, null); } - continue; - } - if (NeedConversion(sourceProperty.PropertyType, destinationProperty.PropertyType)) - { - sourceValue = SmartConvert(sourceValue, destinationProperty.PropertyType); + continue; } - destinationProperty.SetValue(destination, sourceValue); + destinationProperty.SetValue( + destination, + ConvertValue(sourceValue, destinationProperty.PropertyType)); } return destination; } + private static object ConvertValue(object value, Type targetType) + { + if (!NeedConversion(value.GetType(), targetType)) + { + return value; + } + + return SmartConvert(value, targetType); + } + /// - /// 智能类型转换 + /// Performs legacy type conversions. /// private static object SmartConvert(object value, Type targetType) { @@ -117,7 +186,6 @@ namespace EOM.TSHotelManagement.Common } catch { - } } @@ -127,7 +195,7 @@ namespace EOM.TSHotelManagement.Common } /// - /// 检查是否为最小值 + /// Checks whether a value is treated as a legacy minimum sentinel. /// private static bool IsMinValue(object value) { @@ -141,7 +209,7 @@ namespace EOM.TSHotelManagement.Common } /// - /// 将最小值转换为空值 + /// Converts legacy minimum sentinel values to null or empty string. /// private static object ConvertMinValueToNull(object value, Type targetType) { @@ -159,7 +227,7 @@ namespace EOM.TSHotelManagement.Common } /// - /// 处理 DateOnly 类型转换 + /// Handles DateOnly conversions. /// private static object HandleDateOnlyConversion(DateOnly dateOnly, Type targetType) { @@ -190,7 +258,7 @@ namespace EOM.TSHotelManagement.Common } /// - /// 处理 DateTime 类型转换 + /// Handles DateTime conversions. /// private static object HandleDateTimeConversion(DateTime dateTime, Type targetType) { @@ -221,7 +289,7 @@ namespace EOM.TSHotelManagement.Common } /// - /// 处理字符串日期转换 + /// Handles string-to-date conversions. /// private static object HandleStringConversion(string dateString, Type targetType) { @@ -244,25 +312,14 @@ namespace EOM.TSHotelManagement.Common } /// - /// 判断是否需要类型转换 + /// Determines whether source and target types still need a custom conversion. /// private static bool NeedConversion(Type sourceType, Type targetType) { var underlyingSource = Nullable.GetUnderlyingType(sourceType) ?? sourceType; var underlyingTarget = Nullable.GetUnderlyingType(targetType) ?? targetType; - if (underlyingSource == underlyingTarget) return false; - - return true; - } - - /// - /// 映射实体列表 - /// - public static List MapList(List sourceList) - where TDestination : new() - { - return sourceList?.Select(Map).ToList(); + return underlyingSource != underlyingTarget; } } } diff --git a/EOM.TSHotelManagement.Common/Helper/JwtTokenRevocationService.cs b/EOM.TSHotelManagement.Common/Helper/JwtTokenRevocationService.cs index 500266b3c9e42b4f01339c57de43e3114a041e8f..ea69ddcd4bc78b294ded9e8968221a213aa13fe7 100644 --- a/EOM.TSHotelManagement.Common/Helper/JwtTokenRevocationService.cs +++ b/EOM.TSHotelManagement.Common/Helper/JwtTokenRevocationService.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; +using StackExchange.Redis; using System; using System.Collections.Concurrent; using System.IdentityModel.Tokens.Jwt; @@ -15,11 +16,14 @@ namespace EOM.TSHotelManagement.Common private const string RevokedTokenKeyPrefix = "auth:revoked:"; private readonly ConcurrentDictionary _memoryStore = new(); private long _memoryProbeCount; + private long _redisBypassUntilUtcTicks; private readonly RedisHelper _redisHelper; private readonly ILogger _logger; private readonly bool _useRedis; private readonly TimeSpan _fallbackTtl = TimeSpan.FromMinutes(30); + private readonly TimeSpan _redisOperationTimeout; + private readonly TimeSpan _redisFailureCooldown; public JwtTokenRevocationService( @@ -30,6 +34,13 @@ namespace EOM.TSHotelManagement.Common _redisHelper = redisHelper; _logger = logger; _useRedis = ResolveRedisEnabled(configuration); + + var redisSection = configuration.GetSection("Redis"); + var operationTimeoutMs = redisSection.GetValue("OperationTimeoutMs") ?? 1200; + var failureCooldownSeconds = redisSection.GetValue("FailureCooldownSeconds") ?? 30; + + _redisOperationTimeout = TimeSpan.FromMilliseconds(Math.Clamp(operationTimeoutMs, 200, 5000)); + _redisFailureCooldown = TimeSpan.FromSeconds(Math.Clamp(failureCooldownSeconds, 5, 300)); } public async Task RevokeTokenAsync(string token) @@ -43,14 +54,21 @@ namespace EOM.TSHotelManagement.Common var key = BuildRevokedTokenKey(normalizedToken); var ttl = CalculateRevokedTtl(normalizedToken); - if (_useRedis) + if (CanUseRedis()) { try { var db = _redisHelper.GetDatabase(); - await db.StringSetAsync(key, "1", ttl); + await ExecuteRedisWithTimeoutAsync( + () => db.StringSetAsync(key, "1", ttl), + "revoke-token"); + ClearRedisBypass(); return; } + catch (Exception ex) when (IsRedisUnavailableException(ex)) + { + MarkRedisUnavailable(ex, "revoke-token"); + } catch (Exception ex) { _logger.LogError(ex, "Redis token revoke failed, fallback to memory store."); @@ -71,12 +89,20 @@ namespace EOM.TSHotelManagement.Common var key = BuildRevokedTokenKey(normalizedToken); - if (_useRedis) + if (CanUseRedis()) { try { var db = _redisHelper.GetDatabase(); - return await db.KeyExistsAsync(key); + var isRevoked = await ExecuteRedisWithTimeoutAsync( + () => db.KeyExistsAsync(key), + "revoke-check"); + ClearRedisBypass(); + return isRevoked; + } + catch (Exception ex) when (IsRedisUnavailableException(ex)) + { + MarkRedisUnavailable(ex, "revoke-check"); } catch (Exception ex) { @@ -111,6 +137,81 @@ namespace EOM.TSHotelManagement.Common return !string.IsNullOrWhiteSpace(token); } + private bool CanUseRedis() + { + if (!_useRedis) + { + return false; + } + + var bypassUntilTicks = Interlocked.Read(ref _redisBypassUntilUtcTicks); + if (bypassUntilTicks <= 0) + { + return true; + } + + return DateTime.UtcNow.Ticks >= bypassUntilTicks; + } + + private void MarkRedisUnavailable(Exception ex, string operation) + { + var bypassUntil = DateTime.UtcNow.Add(_redisFailureCooldown).Ticks; + Interlocked.Exchange(ref _redisBypassUntilUtcTicks, bypassUntil); + + _logger.LogWarning( + ex, + "Redis {Operation} failed, bypass Redis for {CooldownSeconds}s and fallback to memory store.", + operation, + _redisFailureCooldown.TotalSeconds); + } + + private void ClearRedisBypass() + { + Interlocked.Exchange(ref _redisBypassUntilUtcTicks, 0); + } + + private static bool IsRedisUnavailableException(Exception ex) + { + return ex is TimeoutException || ex is RedisException; + } + + private async Task ExecuteRedisWithTimeoutAsync(Func redisOperation, string operation) + { + var redisTask = redisOperation(); + if (await Task.WhenAny(redisTask, Task.Delay(_redisOperationTimeout)) == redisTask) + { + await redisTask; + return; + } + + ObserveTaskFailure(redisTask); + throw new TimeoutException($"Redis operation '{operation}' timed out after {_redisOperationTimeout.TotalMilliseconds}ms."); + } + + private async Task ExecuteRedisWithTimeoutAsync(Func> redisOperation, string operation) + { + var redisTask = redisOperation(); + if (await Task.WhenAny(redisTask, Task.Delay(_redisOperationTimeout)) == redisTask) + { + return await redisTask; + } + + ObserveTaskFailure(redisTask); + throw new TimeoutException($"Redis operation '{operation}' timed out after {_redisOperationTimeout.TotalMilliseconds}ms."); + } + + private static void ObserveTaskFailure(Task task) + { + task.ContinueWith( + t => + { + var _ = t.Exception; + }, + CancellationToken.None, + TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously, + TaskScheduler.Default); + } + private static string BuildRevokedTokenKey(string token) { var hash = SHA256.HashData(Encoding.UTF8.GetBytes(token)); @@ -188,7 +289,8 @@ namespace EOM.TSHotelManagement.Common private static bool ResolveRedisEnabled(IConfiguration configuration) { var redisSection = configuration.GetSection("Redis"); - var enable = redisSection.GetValue("Enabled"); + var enable = redisSection.GetValue("Enable") + ?? redisSection.GetValue("Enabled"); if (enable.HasValue) { return enable.Value; @@ -197,4 +299,4 @@ namespace EOM.TSHotelManagement.Common return redisSection.GetValue("Enabled"); } } -} +} \ No newline at end of file diff --git a/EOM.TSHotelManagement.Common/Helper/LskyHelper.cs b/EOM.TSHotelManagement.Common/Helper/LskyHelper.cs index 7fab1b32c0b981d5f3607b022e71fb12147d251d..27fa423dda325e585b78aedd5c42a332ced656d0 100644 --- a/EOM.TSHotelManagement.Common/Helper/LskyHelper.cs +++ b/EOM.TSHotelManagement.Common/Helper/LskyHelper.cs @@ -1,4 +1,4 @@ -using EOM.TSHotelManagement.Infrastructure; +using EOM.TSHotelManagement.Infrastructure; using Microsoft.Extensions.Logging; using System; using System.IO; @@ -155,7 +155,7 @@ namespace EOM.TSHotelManagement.Common } var result = await response.Content.ReadFromJsonAsync(); - return result?.Data?.Links?.Url ?? throw new Exception("响应中未包含有效URL"); + return result?.Data?.Links?.Url ?? throw new Exception("无效图片,请重新选择图片上传"); } catch (Exception ex) { diff --git a/EOM.TSHotelManagement.Common/Helper/RedisHelper.cs b/EOM.TSHotelManagement.Common/Helper/RedisHelper.cs index 1238879225c1d203bef93855a89e92f8d4b764b1..52b26ca4f975bc8f0f4d50b9d48479cf0ae5c6a9 100644 --- a/EOM.TSHotelManagement.Common/Helper/RedisHelper.cs +++ b/EOM.TSHotelManagement.Common/Helper/RedisHelper.cs @@ -2,6 +2,7 @@ using EOM.TSHotelManagement.Infrastructure; using Microsoft.Extensions.Logging; using StackExchange.Redis; using System; +using System.Threading.Tasks; namespace EOM.TSHotelManagement.Common { @@ -9,6 +10,7 @@ namespace EOM.TSHotelManagement.Common { private readonly object _lock = new object(); private IConnectionMultiplexer _connection; + private int _defaultDatabase = -1; private readonly ILogger logger; private readonly RedisConfigFactory configFactory; @@ -23,29 +25,44 @@ namespace EOM.TSHotelManagement.Common { lock (_lock) { - if (_connection != null) return; + if (_connection != null) + { + return; + } + try { var redisConfig = configFactory.GetRedisConfig(); - if (!redisConfig.Enable) { logger.LogInformation("Redis功能未启用,跳过初始化"); return; } - int defaultDatabase = redisConfig.DefaultDatabase ?? -1; - - if (string.IsNullOrWhiteSpace(redisConfig?.ConnectionString)) + if (string.IsNullOrWhiteSpace(redisConfig.ConnectionString)) + { throw new ArgumentException("Redis连接字符串不能为空"); + } - var options = ConfigurationOptions.Parse(redisConfig.ConnectionString); + _defaultDatabase = redisConfig.DefaultDatabase ?? -1; + + var options = ConfigurationOptions.Parse(redisConfig.ConnectionString, ignoreUnknown: true); options.AbortOnConnectFail = false; - options.ConnectTimeout = 5000; - options.ReconnectRetryPolicy = new ExponentialRetry(3000); + options.ConnectTimeout = Clamp(redisConfig.ConnectTimeoutMs, 1000, 30000, 5000); + options.SyncTimeout = Clamp(redisConfig.SyncTimeoutMs, 500, 30000, 2000); + options.AsyncTimeout = Clamp(redisConfig.AsyncTimeoutMs, 500, 30000, 2000); + options.KeepAlive = Clamp(redisConfig.KeepAliveSeconds, 5, 300, 15); + options.ConnectRetry = Clamp(redisConfig.ConnectRetry, 1, 10, 3); + options.ReconnectRetryPolicy = new ExponentialRetry( + Clamp(redisConfig.ReconnectRetryBaseDelayMs, 500, 30000, 3000)); + + if (_defaultDatabase >= 0) + { + options.DefaultDatabase = _defaultDatabase; + } _connection = ConnectionMultiplexer.Connect(options); - _connection.GetDatabase(defaultDatabase).Ping(); + _connection.GetDatabase(_defaultDatabase).Ping(); } catch (Exception ex) { @@ -58,13 +75,27 @@ namespace EOM.TSHotelManagement.Common public IDatabase GetDatabase() { if (_connection == null) - throw new System.Exception("RedisHelper not initialized. Call Initialize first."); + { + throw new Exception("RedisHelper not initialized. Call Initialize first."); + } - return _connection.GetDatabase(); + return _connection.GetDatabase(_defaultDatabase); } public async Task CheckServiceStatusAsync() { + var redisConfig = configFactory.GetRedisConfig(); + if (!redisConfig.Enable) + { + logger.LogInformation("Redis功能未启用,跳过初始化"); + return false; + } + + if (string.IsNullOrWhiteSpace(redisConfig.ConnectionString)) + { + throw new ArgumentException("Redis连接字符串不能为空"); + } + try { var db = GetDatabase(); @@ -86,12 +117,10 @@ namespace EOM.TSHotelManagement.Common var db = GetDatabase(); if (expiry.HasValue) { - return await db.StringSetAsync(key, value, new StackExchange.Redis.Expiration(expiry.Value)); - } - else - { - return await db.StringSetAsync(key, value); + return await db.StringSetAsync(key, value, expiry.Value); } + + return await db.StringSetAsync(key, value); } catch (Exception ex) { @@ -142,5 +171,10 @@ namespace EOM.TSHotelManagement.Common } } + private static int Clamp(int? value, int min, int max, int fallback) + { + return Math.Clamp(value ?? fallback, min, max); + } } } + diff --git a/EOM.TSHotelManagement.Common/Helper/SoftwareVersionHelper.cs b/EOM.TSHotelManagement.Common/Helper/SoftwareVersionHelper.cs new file mode 100644 index 0000000000000000000000000000000000000000..dca993253d0cdd132394803c33e89fa33d2d9dae --- /dev/null +++ b/EOM.TSHotelManagement.Common/Helper/SoftwareVersionHelper.cs @@ -0,0 +1,51 @@ +using System.Reflection; + +namespace EOM.TSHotelManagement.Common +{ + public static class SoftwareVersionHelper + { + public static string GetSoftwareVersion(string? configuredVersion = null, string defaultVersion = "1.0.0") + { + var version = Environment.GetEnvironmentVariable("APP_VERSION") + ?? Environment.GetEnvironmentVariable("SoftwareVersion") + ?? configuredVersion + ?? GetVersionFromFile() + ?? GetAssemblyVersion(); + + return string.IsNullOrWhiteSpace(version) ? defaultVersion : version.Trim(); + } + + private static string? GetVersionFromFile() + { + try + { + var assembly = Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly(); + var rootPath = Path.GetDirectoryName(assembly.Location); + if (string.IsNullOrWhiteSpace(rootPath)) + { + return null; + } + + var versionFilePath = Path.Combine(rootPath, "version.txt"); + if (!File.Exists(versionFilePath)) + { + return null; + } + + var versionContent = File.ReadAllText(versionFilePath).Trim(); + return string.IsNullOrWhiteSpace(versionContent) ? null : versionContent; + } + catch + { + return null; + } + } + + private static string? GetAssemblyVersion() + { + var assembly = Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly(); + return assembly.GetCustomAttribute()?.InformationalVersion + ?? assembly.GetName().Version?.ToString(3); + } + } +} diff --git a/EOM.TSHotelManagement.Common/QuartzWorkspace/BusinessJob/AutomaticallyUpgradeMembershipLevelJob.cs b/EOM.TSHotelManagement.Common/QuartzWorkspace/BusinessJob/AutomaticallyUpgradeMembershipLevelJob.cs new file mode 100644 index 0000000000000000000000000000000000000000..ffd37afd62d1465598589b7a26ee46bef4dd8c46 --- /dev/null +++ b/EOM.TSHotelManagement.Common/QuartzWorkspace/BusinessJob/AutomaticallyUpgradeMembershipLevelJob.cs @@ -0,0 +1,199 @@ +using EOM.TSHotelManagement.Domain; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Quartz; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace EOM.TSHotelManagement.Common +{ + [DisallowConcurrentExecution] + public class AutomaticallyUpgradeMembershipLevelJob : IJob + { + private readonly ILogger _logger; + private readonly IServiceProvider _serviceProvider; + + public AutomaticallyUpgradeMembershipLevelJob( + ILogger logger, + IServiceProvider serviceProvider) + { + _logger = logger; + _serviceProvider = serviceProvider; + } + + public Task Execute(IJobExecutionContext context) + { + _logger.LogInformation("开始批量处理会员等级升级。"); + + try + { + var result = ValidateAndUpdateCustomerInfo(); + _logger.LogInformation( + "会员等级升级完成,扫描客户 {ScannedCount} 个,需升级 {NeedUpgradeCount} 个,实际更新 {UpdatedCount} 个。", + result.ScannedCount, + result.NeedUpgradeCount, + result.UpdatedCount); + } + catch (Exception ex) + { + _logger.LogError(ex, "处理会员等级升级时发生异常"); + } + + return Task.CompletedTask; + } + + private MembershipUpgradeResult ValidateAndUpdateCustomerInfo() + { + using var scope = _serviceProvider.CreateScope(); + var db = scope.ServiceProvider.GetRequiredService(); + + var listVipRules = db.Queryable() + .Where(v => v.IsDelete != 1) + .OrderByDescending(a => a.RuleValue) + .ToList(); + + if (listVipRules.Count == 0) + { + _logger.LogWarning("会员等级升级已跳过:未找到有效的会员规则。"); + return MembershipUpgradeResult.Empty; + } + + var enabledCustomerTypes = db.Queryable() + .Where(x => x.IsDelete != 1) + .Select(x => x.CustomerType) + .ToList() + .ToHashSet(); + + listVipRules = listVipRules + .Where(x => enabledCustomerTypes.Contains(x.VipLevelId)) + .ToList(); + + if (listVipRules.Count == 0) + { + _logger.LogWarning("会员等级升级已跳过:规则指向的会员等级不存在或已被删除。"); + return MembershipUpgradeResult.Empty; + } + + var customerSpends = db.Queryable() + .Where(s => s.IsDelete != 1 && s.CustomerNumber != null && s.CustomerNumber != string.Empty) + .GroupBy(s => s.CustomerNumber) + .Select((s) => new CustomerSpendAggregate + { + CustomerNumber = s.CustomerNumber, + TotalConsumptionAmount = SqlFunc.AggregateSum(s.ConsumptionAmount) + }) + .ToList(); + + if (customerSpends.Count == 0) + { + _logger.LogInformation("会员等级升级已跳过:未找到有效消费记录。"); + return MembershipUpgradeResult.Empty; + } + + var customerNumbers = customerSpends + .Select(x => x.CustomerNumber) + .Where(x => !string.IsNullOrWhiteSpace(x)) + .Distinct() + .ToList(); + + var customers = db.Queryable() + .Where(c => c.IsDelete != 1 && customerNumbers.Contains(c.CustomerNumber)) + .ToList(); + + var customerLookup = customers + .Where(c => !string.IsNullOrWhiteSpace(c.CustomerNumber)) + .GroupBy(c => c.CustomerNumber) + .ToDictionary(g => g.Key, g => g.First()); + + var updateTime = DateTime.Now; + var customerToUpdate = new List(); + + foreach (var customerSpend in customerSpends) + { + if (string.IsNullOrWhiteSpace(customerSpend.CustomerNumber)) + { + continue; + } + + if (!customerLookup.TryGetValue(customerSpend.CustomerNumber, out var customer)) + { + continue; + } + + var targetVipLevel = listVipRules + .FirstOrDefault(vipRule => customerSpend.TotalConsumptionAmount >= vipRule.RuleValue)? + .VipLevelId ?? 0; + + if (targetVipLevel <= 0 || targetVipLevel == customer.CustomerType) + { + continue; + } + + customer.CustomerType = targetVipLevel; + customer.DataChgDate = updateTime; + customer.DataChgUsr = "BatchJobSystem"; + customerToUpdate.Add(customer); + } + + if (customerToUpdate.Count == 0) + { + return new MembershipUpgradeResult + { + ScannedCount = customerSpends.Count, + NeedUpgradeCount = 0, + UpdatedCount = 0 + }; + } + + var updatedCount = 0; + + db.Ado.BeginTran(); + try + { + foreach (var batch in customerToUpdate.Chunk(200)) + { + var currentBatch = batch.ToList(); + updatedCount += db.Updateable(currentBatch) + .UpdateColumns( + nameof(Customer.CustomerType), + nameof(Customer.DataChgDate), + nameof(Customer.DataChgUsr)) + .ExecuteCommand(); + } + + db.Ado.CommitTran(); + } + catch + { + db.Ado.RollbackTran(); + throw; + } + + return new MembershipUpgradeResult + { + ScannedCount = customerSpends.Count, + NeedUpgradeCount = customerToUpdate.Count, + UpdatedCount = updatedCount + }; + } + + private sealed class CustomerSpendAggregate + { + public string CustomerNumber { get; set; } = string.Empty; + public decimal TotalConsumptionAmount { get; set; } + } + + private sealed class MembershipUpgradeResult + { + public static MembershipUpgradeResult Empty { get; } = new MembershipUpgradeResult(); + + public int ScannedCount { get; set; } + public int NeedUpgradeCount { get; set; } + public int UpdatedCount { get; set; } + } + } +} diff --git a/EOM.TSHotelManagement.Common/QuartzWorkspace/Job/ReservationExpirationCheckJob.cs b/EOM.TSHotelManagement.Common/QuartzWorkspace/BusinessJob/ReservationExpirationCheckJob.cs similarity index 94% rename from EOM.TSHotelManagement.Common/QuartzWorkspace/Job/ReservationExpirationCheckJob.cs rename to EOM.TSHotelManagement.Common/QuartzWorkspace/BusinessJob/ReservationExpirationCheckJob.cs index 6431906bb483d9a28921f8e58700bf04d03ea051..04f1299162ba92e4b8446ed4765826e0e6bfd0e6 100644 --- a/EOM.TSHotelManagement.Common/QuartzWorkspace/Job/ReservationExpirationCheckJob.cs +++ b/EOM.TSHotelManagement.Common/QuartzWorkspace/BusinessJob/ReservationExpirationCheckJob.cs @@ -1,4 +1,4 @@ -using EOM.TSHotelManagement.Domain; +using EOM.TSHotelManagement.Domain; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -105,7 +105,10 @@ namespace EOM.TSHotelManagement.Common .SetColumns(r => new Room { RoomStateId = (int)RoomState.Vacant }) .Where(r => shouldReleaseRooms.Contains(r.RoomNumber)) .ExecuteCommand(); - db.Deleteable(r => shouldDeleteReservations.Contains(r.Id)); + db.Updateable() + .SetColumns(r => new Reser { ReservationStatus = 2 }) + .Where(r => shouldDeleteReservations.Contains(r.Id)) + .ExecuteCommand(); } _logger.LogInformation("已为 {ItemName} 发送过期提醒", item.ReservationId); diff --git a/EOM.TSHotelManagement.Contract/Application/FavoriteCollection/Dto/ReadFavoriteCollectionOutputDto.cs b/EOM.TSHotelManagement.Contract/Application/FavoriteCollection/Dto/ReadFavoriteCollectionOutputDto.cs new file mode 100644 index 0000000000000000000000000000000000000000..36e670cce75d76ba474204b721137cb6c7edd7b8 --- /dev/null +++ b/EOM.TSHotelManagement.Contract/Application/FavoriteCollection/Dto/ReadFavoriteCollectionOutputDto.cs @@ -0,0 +1,23 @@ +namespace EOM.TSHotelManagement.Contract +{ + /// + /// 读取收藏夹响应 DTO + /// + public class ReadFavoriteCollectionOutputDto + { + /// + /// 收藏路由列表 + /// + public List FavoriteRoutes { get; set; } = new(); + + /// + /// 收藏夹最后更新时间 + /// + public DateTime? UpdatedAt { get; set; } + + /// + /// 当前快照版本号 + /// + public long? RowVersion { get; set; } + } +} \ No newline at end of file diff --git a/EOM.TSHotelManagement.Contract/Application/FavoriteCollection/Dto/SaveFavoriteCollectionInputDto.cs b/EOM.TSHotelManagement.Contract/Application/FavoriteCollection/Dto/SaveFavoriteCollectionInputDto.cs new file mode 100644 index 0000000000000000000000000000000000000000..55ec5b6c8307e7dad801744092142b78ce091054 --- /dev/null +++ b/EOM.TSHotelManagement.Contract/Application/FavoriteCollection/Dto/SaveFavoriteCollectionInputDto.cs @@ -0,0 +1,44 @@ +using System.ComponentModel.DataAnnotations; + +namespace EOM.TSHotelManagement.Contract +{ + /// + /// 保存收藏夹请求 DTO + /// + public class SaveFavoriteCollectionInputDto + { + /// + /// 乐观锁版本号,更新已有快照时必填 + /// + public long? RowVersion { get; set; } + + /// + /// 登录类型,前端可能传 admin 或 employee + /// + [MaxLength(32, ErrorMessage = "LoginType length cannot exceed 32 characters.")] + public string? LoginType { get; set; } + + /// + /// 前端当前账号 + /// + [MaxLength(128, ErrorMessage = "Account length cannot exceed 128 characters.")] + public string? Account { get; set; } + + /// + /// 当前完整收藏路由列表 + /// + [Required(ErrorMessage = "FavoriteRoutes is required.")] + public List FavoriteRoutes { get; set; } = new(); + + /// + /// 前端最后一次修改收藏夹的时间 + /// + public DateTime? UpdatedAt { get; set; } + + /// + /// 触发来源,例如 logout、pagehide、beforeunload、manual + /// + [MaxLength(32, ErrorMessage = "TriggeredBy length cannot exceed 32 characters.")] + public string? TriggeredBy { get; set; } + } +} \ No newline at end of file diff --git a/EOM.TSHotelManagement.Contract/Application/FavoriteCollection/Dto/SaveFavoriteCollectionOutputDto.cs b/EOM.TSHotelManagement.Contract/Application/FavoriteCollection/Dto/SaveFavoriteCollectionOutputDto.cs new file mode 100644 index 0000000000000000000000000000000000000000..eaceb54edddc780725db26eeef037c438fe99c6e --- /dev/null +++ b/EOM.TSHotelManagement.Contract/Application/FavoriteCollection/Dto/SaveFavoriteCollectionOutputDto.cs @@ -0,0 +1,28 @@ +namespace EOM.TSHotelManagement.Contract +{ + /// + /// 保存收藏夹响应 DTO + /// + public class SaveFavoriteCollectionOutputDto + { + /// + /// 是否保存成功 + /// + public bool Saved { get; set; } + + /// + /// 保存后的收藏数量 + /// + public int RouteCount { get; set; } + + /// + /// 最终生效的更新时间 + /// + public DateTime UpdatedAt { get; set; } + + /// + /// 保存成功后的最新版本号 + /// + public long RowVersion { get; set; } + } +} \ No newline at end of file diff --git a/EOM.TSHotelManagement.Contract/Application/Profile/Dto/ChangePasswordInputDto.cs b/EOM.TSHotelManagement.Contract/Application/Profile/Dto/ChangePasswordInputDto.cs new file mode 100644 index 0000000000000000000000000000000000000000..f91dc4d193d88475be5f1290eb358b27c1f606c6 --- /dev/null +++ b/EOM.TSHotelManagement.Contract/Application/Profile/Dto/ChangePasswordInputDto.cs @@ -0,0 +1,19 @@ +using System.ComponentModel.DataAnnotations; + +namespace EOM.TSHotelManagement.Contract +{ + public class ChangePasswordInputDto + { + [Required(ErrorMessage = "旧密码为必填字段")] + [MaxLength(256, ErrorMessage = "旧密码长度不能超过256字符")] + public string OldPassword { get; set; } + + [Required(ErrorMessage = "新密码为必填字段")] + [MaxLength(256, ErrorMessage = "新密码长度不能超过256字符")] + public string NewPassword { get; set; } + + [Required(ErrorMessage = "确认密码为必填字段")] + [MaxLength(256, ErrorMessage = "确认密码长度不能超过256字符")] + public string ConfirmPassword { get; set; } + } +} diff --git a/EOM.TSHotelManagement.Contract/Application/Profile/Dto/CurrentProfileOutputDto.cs b/EOM.TSHotelManagement.Contract/Application/Profile/Dto/CurrentProfileOutputDto.cs new file mode 100644 index 0000000000000000000000000000000000000000..ea9e96dbfc2a85668d68fc7b3241b23bd2da0e9f --- /dev/null +++ b/EOM.TSHotelManagement.Contract/Application/Profile/Dto/CurrentProfileOutputDto.cs @@ -0,0 +1,57 @@ +namespace EOM.TSHotelManagement.Contract +{ + public class CurrentProfileOutputDto + { + public string LoginType { get; set; } + + public string UserNumber { get; set; } + + public string Account { get; set; } + + public string DisplayName { get; set; } + + public string PhotoUrl { get; set; } + + public object? Profile { get; set; } + } + + public class CurrentProfileEmployeeDto + { + public string EmployeeId { get; set; } + + public string Name { get; set; } + + public string DepartmentName { get; set; } + + public string PositionName { get; set; } + + public string PhoneNumber { get; set; } + + public string EmailAddress { get; set; } + + public string Address { get; set; } + + public string HireDate { get; set; } + + public string DateOfBirth { get; set; } + + public string PhotoUrl { get; set; } + } + + public class CurrentProfileAdminDto + { + public string Number { get; set; } + + public string Account { get; set; } + + public string Name { get; set; } + + public string TypeName { get; set; } + + public string Type { get; set; } + + public int IsSuperAdmin { get; set; } + + public string PhotoUrl { get; set; } + } +} diff --git a/EOM.TSHotelManagement.Contract/Application/Profile/Dto/UploadAvatarInputDto.cs b/EOM.TSHotelManagement.Contract/Application/Profile/Dto/UploadAvatarInputDto.cs new file mode 100644 index 0000000000000000000000000000000000000000..52d50e2b3e0c751c00e8e8089d0459d843d5d245 --- /dev/null +++ b/EOM.TSHotelManagement.Contract/Application/Profile/Dto/UploadAvatarInputDto.cs @@ -0,0 +1,10 @@ +using System.ComponentModel.DataAnnotations; + +namespace EOM.TSHotelManagement.Contract +{ + public class UploadAvatarInputDto + { + [MaxLength(32, ErrorMessage = "账号类型长度不能超过32字符")] + public string? LoginType { get; set; } + } +} diff --git a/EOM.TSHotelManagement.Contract/Application/Profile/Dto/UploadAvatarOutputDto.cs b/EOM.TSHotelManagement.Contract/Application/Profile/Dto/UploadAvatarOutputDto.cs new file mode 100644 index 0000000000000000000000000000000000000000..750e186a69cfaea429ebb0deb6b26373fa734a97 --- /dev/null +++ b/EOM.TSHotelManagement.Contract/Application/Profile/Dto/UploadAvatarOutputDto.cs @@ -0,0 +1,7 @@ +namespace EOM.TSHotelManagement.Contract +{ + public class UploadAvatarOutputDto + { + public string PhotoUrl { get; set; } + } +} diff --git a/EOM.TSHotelManagement.Contract/Business/Asset/Dto/Asset/ReadAssetOutputDto.cs b/EOM.TSHotelManagement.Contract/Business/Asset/Dto/Asset/ReadAssetOutputDto.cs index 30a584e0a12c7d97af2f9fa8ce618e2671b3d1fb..c660305bfaf71fe4100d25dbc4c98215eea9cc02 100644 --- a/EOM.TSHotelManagement.Contract/Business/Asset/Dto/Asset/ReadAssetOutputDto.cs +++ b/EOM.TSHotelManagement.Contract/Business/Asset/Dto/Asset/ReadAssetOutputDto.cs @@ -1,4 +1,4 @@ -namespace EOM.TSHotelManagement.Contract +namespace EOM.TSHotelManagement.Contract { public class ReadAssetOutputDto : BaseOutputDto { @@ -17,7 +17,7 @@ public string AssetSource { get; set; } public string AcquiredByEmployeeId { get; set; } - public string AcquiredByEmployeeName { get; set; } + public string AcquiredByName { get; set; } } } diff --git a/EOM.TSHotelManagement.Contract/Business/Customer/Dto/Customer/CreateCustomerInputDto.cs b/EOM.TSHotelManagement.Contract/Business/Customer/Dto/Customer/CreateCustomerInputDto.cs index 5de097a00cfa8d8251ea74b95788bb6a396afacb..7faacf2b7c7ab4a0a102fb71ab4e80ee196f645a 100644 --- a/EOM.TSHotelManagement.Contract/Business/Customer/Dto/Customer/CreateCustomerInputDto.cs +++ b/EOM.TSHotelManagement.Contract/Business/Customer/Dto/Customer/CreateCustomerInputDto.cs @@ -8,16 +8,16 @@ namespace EOM.TSHotelManagement.Contract public string CustomerNumber { get; set; } [Required(ErrorMessage = "客户名称为必填字段"), MaxLength(250, ErrorMessage = "客户名称长度不超过250字符")] - public string CustomerName { get; set; } + public string Name { get; set; } [Required(ErrorMessage = "客户性别为必填字段")] - public int? CustomerGender { get; set; } + public int? Gender { get; set; } [Required(ErrorMessage = "证件类型为必填字段")] - public int PassportId { get; set; } + public int IdCardType { get; set; } [Required(ErrorMessage = "客户电话为必填字段"), MaxLength(256, ErrorMessage = "客户电话长度不超过256字符")] - public string CustomerPhoneNumber { get; set; } + public string PhoneNumber { get; set; } [Required(ErrorMessage = "出生日期为必填字段")] public DateTime DateOfBirth { get; set; } @@ -26,7 +26,7 @@ namespace EOM.TSHotelManagement.Contract public string IdCardNumber { get; set; } [MaxLength(256, ErrorMessage = "客户地址长度不超过256字符")] - public string CustomerAddress { get; set; } + public string Address { get; set; } [Required(ErrorMessage = "客户类型为必填字段")] public int CustomerType { get; set; } diff --git a/EOM.TSHotelManagement.Contract/Business/Customer/Dto/Customer/ReadCustomerInputDto.cs b/EOM.TSHotelManagement.Contract/Business/Customer/Dto/Customer/ReadCustomerInputDto.cs index 976b4c5421b9f5078009f70f9c863af9392ad0b6..18d1b949665fc91166d0f7fdede836f320adf336 100644 --- a/EOM.TSHotelManagement.Contract/Business/Customer/Dto/Customer/ReadCustomerInputDto.cs +++ b/EOM.TSHotelManagement.Contract/Business/Customer/Dto/Customer/ReadCustomerInputDto.cs @@ -1,14 +1,14 @@ -using EOM.TSHotelManagement.Common; +using EOM.TSHotelManagement.Common; namespace EOM.TSHotelManagement.Contract { public class ReadCustomerInputDto : ListInputDto { - public string? CustomerName { get; set; } + public string? Name { get; set; } public string? CustomerNumber { get; set; } - public string? CustomerPhoneNumber { get; set; } + public string? PhoneNumber { get; set; } public string? IdCardNumber { get; set; } - public int? CustomerGender { get; set; } + public int? Gender { get; set; } public int? CustomerType { get; set; } public DateRangeDto DateRangeDto { get; set; } } diff --git a/EOM.TSHotelManagement.Contract/Business/Customer/Dto/Customer/ReadCustomerOutputDto.cs b/EOM.TSHotelManagement.Contract/Business/Customer/Dto/Customer/ReadCustomerOutputDto.cs index abd0fdd05cd25ddedc2fda784656969c11e168f0..9bb26096e9be57a9dcc623cebaf5951f1b0b5ba1 100644 --- a/EOM.TSHotelManagement.Contract/Business/Customer/Dto/Customer/ReadCustomerOutputDto.cs +++ b/EOM.TSHotelManagement.Contract/Business/Customer/Dto/Customer/ReadCustomerOutputDto.cs @@ -1,4 +1,4 @@ - + using EOM.TSHotelManagement.Common; namespace EOM.TSHotelManagement.Contract @@ -12,19 +12,19 @@ namespace EOM.TSHotelManagement.Contract public string CustomerNumber { get; set; } [UIDisplay("客户姓名")] - public string CustomerName { get; set; } + public string Name { get; set; } [UIDisplay("性别", true, false)] - public int? CustomerGender { get; set; } + public int? Gender { get; set; } [UIDisplay("证件类型", true, false)] - public int PassportId { get; set; } + public int IdCardType { get; set; } [UIDisplay("性别", false, true)] public string GenderName { get; set; } [UIDisplay("联系方式")] - public string CustomerPhoneNumber { get; set; } + public string PhoneNumber { get; set; } [UIDisplay("出生日期")] public DateTime DateOfBirth { get; set; } @@ -42,7 +42,7 @@ namespace EOM.TSHotelManagement.Contract public string IdCardNumber { get; set; } [UIDisplay("客户地址")] - public string CustomerAddress { get; set; } + public string Address { get; set; } } } diff --git a/EOM.TSHotelManagement.Contract/Business/Customer/Dto/Customer/UpdateCustomerInputDto.cs b/EOM.TSHotelManagement.Contract/Business/Customer/Dto/Customer/UpdateCustomerInputDto.cs index e982f8f15e56546ed67686927b3a180cf9f68800..f6a434895d714a9b9fb8fa7a7b2fc215a43a4f78 100644 --- a/EOM.TSHotelManagement.Contract/Business/Customer/Dto/Customer/UpdateCustomerInputDto.cs +++ b/EOM.TSHotelManagement.Contract/Business/Customer/Dto/Customer/UpdateCustomerInputDto.cs @@ -8,16 +8,16 @@ namespace EOM.TSHotelManagement.Contract public string CustomerNumber { get; set; } [Required(ErrorMessage = "客户名称为必填字段"), MaxLength(250, ErrorMessage = "客户名称长度不超过250字符")] - public string CustomerName { get; set; } + public string Name { get; set; } [Required(ErrorMessage = "客户性别为必填字段")] - public int? CustomerGender { get; set; } + public int? Gender { get; set; } [Required(ErrorMessage = "证件类型为必填字段")] - public int PassportId { get; set; } + public int IdCardType { get; set; } [Required(ErrorMessage = "客户电话为必填字段"), MaxLength(256, ErrorMessage = "客户电话长度不超过256字符")] - public string CustomerPhoneNumber { get; set; } + public string PhoneNumber { get; set; } [Required(ErrorMessage = "出生日期为必填字段")] public DateOnly DateOfBirth { get; set; } @@ -26,7 +26,7 @@ namespace EOM.TSHotelManagement.Contract public string IdCardNumber { get; set; } [MaxLength(256, ErrorMessage = "客户地址长度不超过256字符")] - public string CustomerAddress { get; set; } + public string Address { get; set; } [Required(ErrorMessage = "客户类型为必填字段")] public int CustomerType { get; set; } diff --git a/EOM.TSHotelManagement.Contract/Business/Reser/Dto/CreateReserInputDto.cs b/EOM.TSHotelManagement.Contract/Business/Reser/Dto/CreateReserInputDto.cs index 187e6fe58ae4483ab0da3bde439dae0a8337054c..26d2e7f4a9f1978747a374e965f149a351b131ec 100644 --- a/EOM.TSHotelManagement.Contract/Business/Reser/Dto/CreateReserInputDto.cs +++ b/EOM.TSHotelManagement.Contract/Business/Reser/Dto/CreateReserInputDto.cs @@ -24,6 +24,7 @@ namespace EOM.TSHotelManagement.Contract [Required(ErrorMessage = "预约结束日期为必填字段")] public DateTime ReservationEndDate { get; set; } + public int ReservationStatus { get; set; } = 0; } } diff --git a/EOM.TSHotelManagement.Contract/Business/Spend/Dto/Spend/AddCustomerSpendInputDto.cs b/EOM.TSHotelManagement.Contract/Business/Spend/Dto/Spend/AddCustomerSpendInputDto.cs index 6b0e286a45124b4be3cc794d61935bfe694887cb..5894dd36fa29fcaff839c5d6ccc21c742030304c 100644 --- a/EOM.TSHotelManagement.Contract/Business/Spend/Dto/Spend/AddCustomerSpendInputDto.cs +++ b/EOM.TSHotelManagement.Contract/Business/Spend/Dto/Spend/AddCustomerSpendInputDto.cs @@ -1,9 +1,12 @@ -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; namespace EOM.TSHotelManagement.Contract { public class AddCustomerSpendInputDto { + [Required(ErrorMessage = "消费编号为必填字段")] + public string SpendNumber { get; set; } + [Required(ErrorMessage = "房间编号为必填字段")] public string RoomNumber { get; set; } @@ -14,12 +17,10 @@ namespace EOM.TSHotelManagement.Contract public string ProductName { get; set; } [Required(ErrorMessage = "数量为必填字段")] - public int Quantity { get; set; } + public int ConsumptionQuantity { get; set; } [Required(ErrorMessage = "价格为必填字段")] - public decimal Price { get; set; } - - public string WorkerNo { get; set; } + public decimal ProductPrice { get; set; } public string SoftwareVersion { get; set; } } diff --git a/EOM.TSHotelManagement.Contract/Business/Spend/Dto/Spend/UndoCustomerSpendInputDto.cs b/EOM.TSHotelManagement.Contract/Business/Spend/Dto/Spend/UndoCustomerSpendInputDto.cs new file mode 100644 index 0000000000000000000000000000000000000000..f9905c4dd65ac6c30ddb5f5a7cf9b0b40dd362ec --- /dev/null +++ b/EOM.TSHotelManagement.Contract/Business/Spend/Dto/Spend/UndoCustomerSpendInputDto.cs @@ -0,0 +1,9 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace EOM.TSHotelManagement.Contract; + +public class UndoCustomerSpendInputDto : BaseInputDto +{ +} diff --git a/EOM.TSHotelManagement.Contract/Employee/Dto/Employee/CreateEmployeeInputDto.cs b/EOM.TSHotelManagement.Contract/Employee/Dto/Employee/CreateEmployeeInputDto.cs index c8d99c4e60ccc45df8367be57d1a69cdb83ea124..5fb8e54e245cc6deb5564039b37fa14fe3d6a289 100644 --- a/EOM.TSHotelManagement.Contract/Employee/Dto/Employee/CreateEmployeeInputDto.cs +++ b/EOM.TSHotelManagement.Contract/Employee/Dto/Employee/CreateEmployeeInputDto.cs @@ -10,7 +10,7 @@ namespace EOM.TSHotelManagement.Contract [Required(ErrorMessage = "员工姓名为必填字段")] [MaxLength(250, ErrorMessage = "员工姓名长度不超过250字符")] - public string EmployeeName { get; set; } + public string Name { get; set; } [Required(ErrorMessage = "员工性别为必填字段")] public int Gender { get; set; } diff --git a/EOM.TSHotelManagement.Contract/Employee/Dto/Employee/ReadEmployeeInputDto.cs b/EOM.TSHotelManagement.Contract/Employee/Dto/Employee/ReadEmployeeInputDto.cs index f465bf22519545cebe8128dfece6fb9ebf113f67..f527745cbb6162379994f259c8d55a50f63c13e3 100644 --- a/EOM.TSHotelManagement.Contract/Employee/Dto/Employee/ReadEmployeeInputDto.cs +++ b/EOM.TSHotelManagement.Contract/Employee/Dto/Employee/ReadEmployeeInputDto.cs @@ -1,11 +1,11 @@ -using EOM.TSHotelManagement.Common; +using EOM.TSHotelManagement.Common; namespace EOM.TSHotelManagement.Contract { public class ReadEmployeeInputDto : ListInputDto { public string? EmployeeId { get; set; } - public string? EmployeeName { get; set; } + public string? Name { get; set; } public string? Gender { get; set; } public DateOnly? DateOfBirth { get; set; } diff --git a/EOM.TSHotelManagement.Contract/Employee/Dto/Employee/ReadEmployeeOutputDto.cs b/EOM.TSHotelManagement.Contract/Employee/Dto/Employee/ReadEmployeeOutputDto.cs index 66b0108424ba7de38a6684b0b35cc618e0a0aa07..ee59de2c87680799fa548d88d50f4a5dc3aba7ea 100644 --- a/EOM.TSHotelManagement.Contract/Employee/Dto/Employee/ReadEmployeeOutputDto.cs +++ b/EOM.TSHotelManagement.Contract/Employee/Dto/Employee/ReadEmployeeOutputDto.cs @@ -1,10 +1,10 @@ -namespace EOM.TSHotelManagement.Contract +namespace EOM.TSHotelManagement.Contract { public class ReadEmployeeOutputDto : BaseOutputDto { public string EmployeeId { get; set; } - public string EmployeeName { get; set; } + public string Name { get; set; } public int Gender { get; set; } diff --git a/EOM.TSHotelManagement.Contract/Employee/Dto/Employee/UpdateEmployeeInputDto.cs b/EOM.TSHotelManagement.Contract/Employee/Dto/Employee/UpdateEmployeeInputDto.cs index f0364f535c18741289f6ad8a3526ddd20cdd5b52..7d12dc348bb7b31e43ce6e869bf97a0b9884a1f9 100644 --- a/EOM.TSHotelManagement.Contract/Employee/Dto/Employee/UpdateEmployeeInputDto.cs +++ b/EOM.TSHotelManagement.Contract/Employee/Dto/Employee/UpdateEmployeeInputDto.cs @@ -10,7 +10,7 @@ namespace EOM.TSHotelManagement.Contract [Required(ErrorMessage = "员工姓名为必填字段")] [MaxLength(250, ErrorMessage = "员工姓名长度不超过250字符")] - public string EmployeeName { get; set; } + public string Name { get; set; } [Required(ErrorMessage = "员工性别为必填字段")] public int Gender { get; set; } diff --git a/EOM.TSHotelManagement.Contract/Employee/Dto/EmployeeCheck/CreateEmployeeCheckInputDto.cs b/EOM.TSHotelManagement.Contract/Employee/Dto/EmployeeCheck/CreateEmployeeCheckInputDto.cs index 7f2e1f5106d08ed530728f4bce50019897f68779..d0d7526c7a1f8e7d24d2f2c701c8da992b2ec708 100644 --- a/EOM.TSHotelManagement.Contract/Employee/Dto/EmployeeCheck/CreateEmployeeCheckInputDto.cs +++ b/EOM.TSHotelManagement.Contract/Employee/Dto/EmployeeCheck/CreateEmployeeCheckInputDto.cs @@ -4,36 +4,12 @@ namespace EOM.TSHotelManagement.Contract { public class CreateEmployeeCheckInputDto : BaseInputDto { - /// - /// 打卡编号 (Check-in/Check-out Number) - /// - [Required(ErrorMessage = "打卡编号为必填字段")] - [MaxLength(128, ErrorMessage = "打卡编号长度不超过128字符")] - public string CheckNumber { get; set; } /// /// 员工工号 (Employee ID) /// [Required(ErrorMessage = "员工工号为必填字段")] [MaxLength(128, ErrorMessage = "员工工号长度不超过128字符")] public string EmployeeId { get; set; } - - /// - /// 打卡时间 (Check-in/Check-out Time) - /// - [Required(ErrorMessage = "打卡时间为必填字段")] - public DateTime CheckTime { get; set; } - - /// - /// 打卡方式 (Check-in/Check-out Method) - /// - [Required(ErrorMessage = "打卡方式为必填字段")] - public string CheckMethod { get; set; } - - /// - /// 打卡状态 (Check-in/Check-out Status) - /// - [Required(ErrorMessage = "打卡状态为必填字段")] - public int CheckStatus { get; set; } } } diff --git a/EOM.TSHotelManagement.Contract/SystemManagement/Dto/Permission/GrantRolePermissionsInputDto.cs b/EOM.TSHotelManagement.Contract/SystemManagement/Dto/Permission/GrantRolePermissionsInputDto.cs index f593d5a3e1083e2587bad89382f92fa829c98612..769edea31c9ac16c1407cbe6e8b6f6078b55496d 100644 --- a/EOM.TSHotelManagement.Contract/SystemManagement/Dto/Permission/GrantRolePermissionsInputDto.cs +++ b/EOM.TSHotelManagement.Contract/SystemManagement/Dto/Permission/GrantRolePermissionsInputDto.cs @@ -10,5 +10,7 @@ namespace EOM.TSHotelManagement.Contract.SystemManagement.Dto.Permission [Required(ErrorMessage = "权限编码集合为必填字段")] public List PermissionNumbers { get; set; } = new List(); + + public List MenuIds { get; set; } = new List(); } -} \ No newline at end of file +} diff --git a/EOM.TSHotelManagement.Contract/SystemManagement/Dto/Permission/ReadRoleGrantOutputDto.cs b/EOM.TSHotelManagement.Contract/SystemManagement/Dto/Permission/ReadRoleGrantOutputDto.cs new file mode 100644 index 0000000000000000000000000000000000000000..7f5e87bbaaf31dd2c372cf28a2f6cc92e7e95574 --- /dev/null +++ b/EOM.TSHotelManagement.Contract/SystemManagement/Dto/Permission/ReadRoleGrantOutputDto.cs @@ -0,0 +1,14 @@ +namespace EOM.TSHotelManagement.Contract.SystemManagement.Dto.Permission +{ + /// + /// 角色授权读取结果(菜单与权限独立) + /// + public class ReadRoleGrantOutputDto : BaseOutputDto + { + public string RoleNumber { get; set; } = string.Empty; + + public List PermissionNumbers { get; set; } = new(); + + public List MenuIds { get; set; } = new(); + } +} diff --git a/EOM.TSHotelManagement.Contract/SystemManagement/Dto/Permission/UserRolePermissionOutputDto.cs b/EOM.TSHotelManagement.Contract/SystemManagement/Dto/Permission/UserRolePermissionOutputDto.cs index 2e22503f512d6a5b8c05e43b0ab87ef102c05ef0..59830c471cbd449960f1efe5921f16e2ae397b09 100644 --- a/EOM.TSHotelManagement.Contract/SystemManagement/Dto/Permission/UserRolePermissionOutputDto.cs +++ b/EOM.TSHotelManagement.Contract/SystemManagement/Dto/Permission/UserRolePermissionOutputDto.cs @@ -16,7 +16,9 @@ namespace EOM.TSHotelManagement.Contract [MaxLength(256, ErrorMessage = "菜单键长度不超过256字符")] public string? MenuKey { get; set; } + public int? MenuId { get; set; } + [MaxLength(256, ErrorMessage = "菜单名称长度不超过256字符")] public string? MenuName { get; set; } } -} \ No newline at end of file +} diff --git a/EOM.TSHotelManagement.Contract/SystemManagement/Dto/Quartz/ReadQuartzJobOutputDto.cs b/EOM.TSHotelManagement.Contract/SystemManagement/Dto/Quartz/ReadQuartzJobOutputDto.cs new file mode 100644 index 0000000000000000000000000000000000000000..8c9d2abbd250d08787e92336595bf2c69434c6bc --- /dev/null +++ b/EOM.TSHotelManagement.Contract/SystemManagement/Dto/Quartz/ReadQuartzJobOutputDto.cs @@ -0,0 +1,26 @@ +namespace EOM.TSHotelManagement.Contract +{ + public class ReadQuartzJobOutputDto + { + public string JobName { get; set; } + public string JobGroup { get; set; } + public string JobDescription { get; set; } + public bool IsDurable { get; set; } + public bool RequestsRecovery { get; set; } + + public string TriggerName { get; set; } + public string TriggerGroup { get; set; } + public string TriggerType { get; set; } + public string TriggerState { get; set; } + + public string CronExpression { get; set; } + public string TimeZoneId { get; set; } + public int? RepeatCount { get; set; } + public double? RepeatIntervalMs { get; set; } + + public DateTime? StartTimeUtc { get; set; } + public DateTime? EndTimeUtc { get; set; } + public DateTime? NextFireTimeUtc { get; set; } + public DateTime? PreviousFireTimeUtc { get; set; } + } +} diff --git a/EOM.TSHotelManagement.Data/DatabaseInitializer/DatabaseInitializer.cs b/EOM.TSHotelManagement.Data/DatabaseInitializer/DatabaseInitializer.cs index e86d9cf0e9153c4b339c74707da7d2c2f630dc36..5e931f85b6db2bb81c4441e8f5a723bbb8a10702 100644 --- a/EOM.TSHotelManagement.Data/DatabaseInitializer/DatabaseInitializer.cs +++ b/EOM.TSHotelManagement.Data/DatabaseInitializer/DatabaseInitializer.cs @@ -102,7 +102,6 @@ namespace EOM.TSHotelManagement.Data .ToArray(); db.CodeFirst.InitTables(needCreateTableTypes); - EnsureTwoFactorForeignKeys(db, dbSettings.DbType); Console.WriteLine("Database schema initialized"); @@ -259,58 +258,6 @@ namespace EOM.TSHotelManagement.Data return configString; } - private void EnsureTwoFactorForeignKeys(ISqlSugarClient db, DbType dbType) - { - try - { - if (dbType is DbType.MySql or DbType.MySqlConnector) - { - EnsureMySqlForeignKey(db, "two_factor_auth", "fk_2fa_employee", "employee_pk", "employee", "id"); - EnsureMySqlForeignKey(db, "two_factor_auth", "fk_2fa_administrator", "administrator_pk", "administrator", "id"); - EnsureMySqlForeignKey(db, "two_factor_auth", "fk_2fa_customer_account", "customer_account_pk", "customer_account", "id"); - EnsureMySqlForeignKey(db, "two_factor_recovery_code", "fk_2fa_recovery_auth", "two_factor_auth_pk", "two_factor_auth", "id", "CASCADE"); - } - } - catch (Exception ex) - { - Console.WriteLine($"EnsureTwoFactorForeignKeys skipped: {ex.Message}"); - } - } - - private static void EnsureMySqlForeignKey( - ISqlSugarClient db, - string tableName, - string constraintName, - string columnName, - string referenceTable, - string referenceColumn, - string onDeleteAction = "SET NULL") - { - var existsSql = @"SELECT COUNT(1) - FROM information_schema.TABLE_CONSTRAINTS - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = @tableName - AND CONSTRAINT_NAME = @constraintName"; - - var exists = db.Ado.GetInt( - existsSql, - new SugarParameter("@tableName", tableName), - new SugarParameter("@constraintName", constraintName)) > 0; - if (exists) - { - return; - } - - var addConstraintSql = $@"ALTER TABLE `{tableName}` - ADD CONSTRAINT `{constraintName}` - FOREIGN KEY (`{columnName}`) - REFERENCES `{referenceTable}`(`{referenceColumn}`) - ON UPDATE RESTRICT - ON DELETE {onDeleteAction};"; - - db.Ado.ExecuteCommand(addConstraintSql); - } - private void SeedInitialData(ISqlSugarClient db) { Console.WriteLine("Initializing database data..."); @@ -333,10 +280,10 @@ namespace EOM.TSHotelManagement.Data PassportType _ => 6, Menu _ => 7, NavBar _ => 8, - SystemInformation _ => 9, - PromotionContent _ => 10, - Administrator _ => 11, - Employee _ => 12, + PromotionContent _ => 9, + Administrator _ => 10, + Employee _ => 11, + UserFavoriteCollection _ => 12, _ => 99 }) .ToList(); @@ -373,10 +320,6 @@ namespace EOM.TSHotelManagement.Data alreadyExists = db.Queryable().Any(a => a.PromotionContentMessage == promoContent.PromotionContentMessage); break; - case SystemInformation sysInfo: - alreadyExists = db.Queryable().Any(a => a.UrlAddress == sysInfo.UrlAddress); - break; - case Nation nation: alreadyExists = db.Queryable().Any(a => a.NationName == nation.NationName); break; @@ -401,6 +344,10 @@ namespace EOM.TSHotelManagement.Data alreadyExists = db.Queryable().Any(a => a.EmployeeId == employee.EmployeeId); break; + case UserFavoriteCollection favoriteCollection: + alreadyExists = db.Queryable().Any(a => a.UserNumber == favoriteCollection.UserNumber); + break; + case Permission permission: alreadyExists = db.Queryable().Any(a => a.PermissionNumber == permission.PermissionNumber); break; @@ -511,7 +458,7 @@ namespace EOM.TSHotelManagement.Data if (adminUser != null) { var hasBind = db.Queryable() - .Any(ur => ur.UserNumber == adminUser.Number && ur.RoleNumber == adminRoleNumber && ur.IsDelete != 1); + .Any(ur => ur.UserNumber == adminUser.Number && ur.RoleNumber == adminRoleNumber); if (!hasBind) { @@ -519,7 +466,6 @@ namespace EOM.TSHotelManagement.Data { UserNumber = adminUser.Number, RoleNumber = adminRoleNumber, - IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }).ExecuteCommand(); @@ -533,12 +479,13 @@ namespace EOM.TSHotelManagement.Data // 3) Grant ALL permissions to admin role var allPermNumbers = db.Queryable() - .Where(p => p.IsDelete != 1) .Select(p => p.PermissionNumber) .ToList(); var existingRolePerms = db.Queryable() - .Where(rp => rp.RoleNumber == adminRoleNumber && rp.IsDelete != 1) + .Where(rp => rp.RoleNumber == adminRoleNumber + && rp.PermissionNumber != null + && rp.PermissionNumber != "") .Select(rp => rp.PermissionNumber) .ToList(); @@ -554,7 +501,6 @@ namespace EOM.TSHotelManagement.Data { RoleNumber = adminRoleNumber, PermissionNumber = p!, - IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }).ToList(); @@ -650,4 +596,3 @@ namespace EOM.TSHotelManagement.Data #endregion } } - diff --git a/EOM.TSHotelManagement.Data/EOM.TSHotelManagement.Data.csproj b/EOM.TSHotelManagement.Data/EOM.TSHotelManagement.Data.csproj index bf70ab1b27d447da3e1e08a5ce210eed7478c331..ba5ee0de0f43c5c9e648384d6107e58d8bb4ce4b 100644 --- a/EOM.TSHotelManagement.Data/EOM.TSHotelManagement.Data.csproj +++ b/EOM.TSHotelManagement.Data/EOM.TSHotelManagement.Data.csproj @@ -8,8 +8,8 @@ - - + + diff --git a/EOM.TSHotelManagement.Data/Repository/GenericRepository.cs b/EOM.TSHotelManagement.Data/Repository/GenericRepository.cs index 415449c1f36aea27d5911dd554c870cd14d5ccec..36992f4d5c498d4764d1f035a5f11769c64d493e 100644 --- a/EOM.TSHotelManagement.Data/Repository/GenericRepository.cs +++ b/EOM.TSHotelManagement.Data/Repository/GenericRepository.cs @@ -45,7 +45,7 @@ namespace EOM.TSHotelManagement.Data public override bool Insert(T entity) { - if (entity is BaseEntity baseEntity) + if (entity is AuditEntity baseEntity) { var currentUser = GetCurrentUser(); if (!baseEntity.DataInsDate.HasValue) @@ -62,7 +62,7 @@ namespace EOM.TSHotelManagement.Data { Expression>? rowVersionWhere = null; - if (entity is BaseEntity baseEntity) + if (entity is AuditEntity baseEntity) { var currentUser = GetCurrentUser(); if (!baseEntity.DataChgDate.HasValue) @@ -110,7 +110,7 @@ namespace EOM.TSHotelManagement.Data foreach (var entity in updateObjs) { - if (entity is BaseEntity baseEntity) + if (entity is AuditEntity baseEntity) { var currentUser = GetCurrentUser(); if (!baseEntity.DataChgDate.HasValue) @@ -146,7 +146,7 @@ namespace EOM.TSHotelManagement.Data public bool SoftDelete(T entity) { - if (entity is BaseEntity baseEntity) + if (entity is SoftDeleteEntity baseEntity) { var currentUser = GetCurrentUser(); if (!baseEntity.DataChgDate.HasValue) @@ -220,7 +220,7 @@ namespace EOM.TSHotelManagement.Data // 更新内存中的实体状态 foreach (var entity in entities) { - if (entity is BaseEntity baseEntity) + if (entity is SoftDeleteEntity baseEntity) { hasBaseEntity = true; baseEntity.IsDelete = 1; @@ -242,9 +242,9 @@ namespace EOM.TSHotelManagement.Data totalAffected += base.Context.Updateable(batch) .UpdateColumns(new[] { - nameof(BaseEntity.IsDelete), - nameof(BaseEntity.DataChgUsr), - nameof(BaseEntity.DataChgDate) + nameof(SoftDeleteEntity.IsDelete), + nameof(AuditEntity.DataChgUsr), + nameof(AuditEntity.DataChgDate) }) .ExecuteCommand(); } diff --git a/EOM.TSHotelManagement.Domain/Application/FavoriteCollection/UserFavoriteCollection.cs b/EOM.TSHotelManagement.Domain/Application/FavoriteCollection/UserFavoriteCollection.cs new file mode 100644 index 0000000000000000000000000000000000000000..3e8412ab1297361bf9731463bc6a9ec4462c3f48 --- /dev/null +++ b/EOM.TSHotelManagement.Domain/Application/FavoriteCollection/UserFavoriteCollection.cs @@ -0,0 +1,94 @@ +using SqlSugar; + +namespace EOM.TSHotelManagement.Domain +{ + /// + /// 用户收藏夹快照实体 + /// + [SugarTable("user_favorite_collection", "User favorite collection snapshot", true)] + public class UserFavoriteCollection : AuditEntity + { + /// + /// 主键 + /// + [SugarColumn(ColumnName = "id", IsIdentity = true, IsPrimaryKey = true, IsNullable = false, ColumnDescription = "Id")] + public int Id { get; set; } + + /// + /// JWT 中的用户编号 + /// + [SugarColumn( + ColumnName = "user_number", + Length = 128, + IsNullable = false, + UniqueGroupNameList = new[] { "UK_user_favorite_collection_user_number" }, + ColumnDescription = "User number resolved from JWT" + )] + public string UserNumber { get; set; } = string.Empty; + + /// + /// 登录类型 + /// + [SugarColumn( + ColumnName = "login_type", + Length = 32, + IsNullable = true, + ColumnDescription = "Login type" + )] + public string? LoginType { get; set; } + + /// + /// 当前账号 + /// + [SugarColumn( + ColumnName = "account", + Length = 128, + IsNullable = true, + ColumnDescription = "Account" + )] + public string? Account { get; set; } + + /// + /// 收藏路由 JSON 快照 + /// + [SugarColumn( + ColumnName = "favorite_routes_json", + ColumnDataType = "text", + IsNullable = false, + ColumnDescription = "Favorite routes JSON snapshot" + )] + public string FavoriteRoutesJson { get; set; } = "[]"; + + /// + /// 收藏数量 + /// + [SugarColumn( + ColumnName = "route_count", + IsNullable = false, + DefaultValue = "0", + ColumnDescription = "Favorite route count" + )] + public int RouteCount { get; set; } + + /// + /// 业务更新时间 + /// + [SugarColumn( + ColumnName = "updated_at", + IsNullable = false, + ColumnDescription = "Snapshot updated time from client" + )] + public DateTime UpdatedAt { get; set; } + + /// + /// 最后触发来源 + /// + [SugarColumn( + ColumnName = "triggered_by", + Length = 32, + IsNullable = true, + ColumnDescription = "Last trigger source" + )] + public string? TriggeredBy { get; set; } + } +} diff --git a/EOM.TSHotelManagement.Domain/Application/NavBar/NavBar.cs b/EOM.TSHotelManagement.Domain/Application/NavBar/NavBar.cs index b264880f45638f9d67b6d2b1f6b5fa107b44b3e1..d38eda20f455c917faf772afa19a5acaff2c0876 100644 --- a/EOM.TSHotelManagement.Domain/Application/NavBar/NavBar.cs +++ b/EOM.TSHotelManagement.Domain/Application/NavBar/NavBar.cs @@ -1,4 +1,4 @@ -using SqlSugar; +using SqlSugar; namespace EOM.TSHotelManagement.Domain { @@ -6,7 +6,7 @@ namespace EOM.TSHotelManagement.Domain /// 导航栏配置表 (Navigation Bar Configuration) /// [SugarTable("nav_bar", "导航栏配置表 (Navigation Bar Configuration)", true)] - public class NavBar : BaseEntity + public class NavBar : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/BaseEntity.cs b/EOM.TSHotelManagement.Domain/BaseEntity.cs deleted file mode 100644 index 68954f79cd610901814f60bbe159981e32d5b17b..0000000000000000000000000000000000000000 --- a/EOM.TSHotelManagement.Domain/BaseEntity.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; - -namespace EOM.TSHotelManagement.Domain -{ - public class BaseEntity - { - /// - /// 删除标识 - /// - [SqlSugar.SugarColumn(ColumnName = "delete_mk", Length = 11, IsNullable = false, DefaultValue = "0")] - public int? IsDelete { get; set; } = 0; - /// - /// 资料创建人 - /// - [SqlSugar.SugarColumn(ColumnName = "datains_usr", Length = 128, IsOnlyIgnoreUpdate = true, IsNullable = true)] - public string? DataInsUsr { get; set; } - /// - /// 资料创建时间 - /// - [SqlSugar.SugarColumn(ColumnName = "datains_date", IsOnlyIgnoreUpdate = true, IsNullable = true)] - public DateTime? DataInsDate { get; set; } - /// - /// 资料更新人 - /// - [SqlSugar.SugarColumn(ColumnName = "datachg_usr", Length = 128, IsOnlyIgnoreInsert = true, IsNullable = true)] - public string? DataChgUsr { get; set; } - /// - /// 资料更新时间 - /// - [SqlSugar.SugarColumn(ColumnName = "datachg_date", IsOnlyIgnoreInsert = true, IsNullable = true)] - public DateTime? DataChgDate { get; set; } - /// - /// 行版本(乐观锁) - /// - [SqlSugar.SugarColumn(ColumnName = "row_version", IsNullable = false, DefaultValue = "1")] - public long RowVersion { get; set; } = 1; - /// - /// Token - /// - [SqlSugar.SugarColumn(IsIgnore = true)] - public string? UserToken { get; set; } - } -} diff --git a/EOM.TSHotelManagement.Domain/Business/Asset/Asset.cs b/EOM.TSHotelManagement.Domain/Business/Asset/Asset.cs index 7f79ea6e4e685a1e92ff4d8e0233ceaa08f54b21..4435c37776b820c6d3e2df9f975b8a2eb10a0a41 100644 --- a/EOM.TSHotelManagement.Domain/Business/Asset/Asset.cs +++ b/EOM.TSHotelManagement.Domain/Business/Asset/Asset.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -31,7 +31,7 @@ namespace EOM.TSHotelManagement.Domain /// 资产管理 /// [SqlSugar.SugarTable("asset")] - public class Asset : BaseEntity + public class Asset : SoftDeleteEntity { /// /// 编号 (ID) @@ -105,7 +105,7 @@ namespace EOM.TSHotelManagement.Domain /// 资产经办人姓名 (Acquired By - Employee Name) /// [SqlSugar.SugarColumn(IsIgnore = true)] - public string AcquiredByEmployeeName { get; set; } + public string AcquiredByName { get; set; } } diff --git a/EOM.TSHotelManagement.Domain/Business/Customer/CustoSpend.cs b/EOM.TSHotelManagement.Domain/Business/Customer/CustoSpend.cs deleted file mode 100644 index b189e5b313af9564a96cd0d2dea9c319bf8cfd51..0000000000000000000000000000000000000000 --- a/EOM.TSHotelManagement.Domain/Business/Customer/CustoSpend.cs +++ /dev/null @@ -1,42 +0,0 @@ -/* - * MIT License - *Copyright (c) 2021 易开元(Easy-Open-Meta) - - *Permission is hereby granted, free of charge, to any person obtaining a copy - *of this software and associated documentation files (the "Software"), to deal - *in the Software without restriction, including without limitation the rights - *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - *copies of the Software, and to permit persons to whom the Software is - *furnished to do so, subject to the following conditions: - - *The above copyright notice and this permission notice shall be included in all - *copies or substantial portions of the Software. - - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - *SOFTWARE. - * - *模块说明:酒店盈利情况类 - */ -namespace EOM.TSHotelManagement.Domain -{ - /// - /// 酒店盈利情况 - /// - public class CustoSpend - { - /// - /// 年 - /// - public string Years { get; set; } - /// - /// 总金额 - /// - public decimal Money { get; set; } - - } -} diff --git a/EOM.TSHotelManagement.Domain/Business/Customer/CustoType.cs b/EOM.TSHotelManagement.Domain/Business/Customer/CustoType.cs index 311987e5c4d8ec68f8c7c4eedc4a687dd4a967e6..0f3f379f511ba4c7c5d3259aedf2127081731859 100644 --- a/EOM.TSHotelManagement.Domain/Business/Customer/CustoType.cs +++ b/EOM.TSHotelManagement.Domain/Business/Customer/CustoType.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -30,7 +30,7 @@ namespace EOM.TSHotelManagement.Domain /// 客户类型 /// [SqlSugar.SugarTable("custo_type")] - public class CustoType : BaseEntity + public class CustoType : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/Business/Customer/Customer.cs b/EOM.TSHotelManagement.Domain/Business/Customer/Customer.cs index ec5865384ee92b8c55e5ee71f5f2806fc9315be8..6c49b2e5fe742917cd1f8181d4023264a042faed 100644 --- a/EOM.TSHotelManagement.Domain/Business/Customer/Customer.cs +++ b/EOM.TSHotelManagement.Domain/Business/Customer/Customer.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -31,7 +31,7 @@ namespace EOM.TSHotelManagement.Domain /// 客户信息 /// [SqlSugar.SugarTable("customer")] - public class Customer : BaseEntity + public class Customer : Personnel //SoftDeleteEntity { /// /// 编号 (ID) @@ -45,66 +45,6 @@ namespace EOM.TSHotelManagement.Domain [SqlSugar.SugarColumn(ColumnName = "custo_no", IsPrimaryKey = true, IsNullable = false, Length = 128, ColumnDescription = "客户编号 (Customer Number)")] public string CustomerNumber { get; set; } - /// - /// 客户名称 (Customer Name) - /// - [SqlSugar.SugarColumn(ColumnName = "custo_name", IsNullable = false, Length = 250, ColumnDescription = "客户名称 (Customer Name)")] - public string CustomerName { get; set; } - - /// - /// 客户性别 (Customer Gender) - /// - [SqlSugar.SugarColumn(ColumnName = "custo_gender", IsNullable = false, ColumnDescription = "客户性别 (Customer Gender)")] - public int? CustomerGender { get; set; } - - /// - /// 证件类型 (Passport Type) - /// - [SqlSugar.SugarColumn(ColumnName = "passport_type", IsNullable = false, ColumnDescription = "客户性别 (Customer Gender)")] - public int PassportId { get; set; } - - /// - /// 性别 (Gender) - /// - [SqlSugar.SugarColumn(IsIgnore = true)] - public string GenderName { get; set; } - - /// - /// 客户电话 (Customer Phone Number) - /// - [SqlSugar.SugarColumn(ColumnName = "custo_tel", IsNullable = false, Length = 256, ColumnDescription = "客户电话 (Customer Phone Number)")] - public string CustomerPhoneNumber { get; set; } - - /// - /// 出生日期 (Date of Birth) - /// - [SqlSugar.SugarColumn(ColumnName = "custo_birth", IsNullable = false, ColumnDescription = "出生日期 (Date of Birth)")] - public DateOnly DateOfBirth { get; set; } - - /// - /// 客户类型名称 (Customer Type Name) - /// - [SqlSugar.SugarColumn(IsIgnore = true)] - public string CustomerTypeName { get; set; } - - /// - /// 证件类型名称 (Passport Type Name) - /// - [SqlSugar.SugarColumn(IsIgnore = true)] - public string PassportName { get; set; } - - /// - /// 证件号码 (Passport ID) - /// - [SqlSugar.SugarColumn(ColumnName = "passport_id", IsNullable = false, Length = 256, ColumnDescription = "证件号码 (Passport ID)")] - public string IdCardNumber { get; set; } - - /// - /// 居住地址 (Customer Address) - /// - [SqlSugar.SugarColumn(ColumnName = "custo_address", IsNullable = true, Length = 256, ColumnDescription = "居住地址 (Customer Address)")] - public string CustomerAddress { get; set; } - /// /// 客户类型 (Customer Type) /// diff --git a/EOM.TSHotelManagement.Domain/Business/Customer/CustomerAccount.cs b/EOM.TSHotelManagement.Domain/Business/Customer/CustomerAccount.cs index 957fe625782f6fa655d3fbd8a8a146f957bf1043..79046f0e5dd53623b8e244bd71152dd3113e1918 100644 --- a/EOM.TSHotelManagement.Domain/Business/Customer/CustomerAccount.cs +++ b/EOM.TSHotelManagement.Domain/Business/Customer/CustomerAccount.cs @@ -3,7 +3,7 @@ using System; namespace EOM.TSHotelManagement.Domain { [SqlSugar.SugarTable("customer_account", "客户账号表")] - public class CustomerAccount : BaseEntity + public class CustomerAccount : SoftDeleteEntity { /// /// ID (索引ID) diff --git a/EOM.TSHotelManagement.Domain/Business/Customer/PassPortType.cs b/EOM.TSHotelManagement.Domain/Business/Customer/PassPortType.cs index 66a071716106580b8975eac0a26995871c9ed72e..79dccabeb769e56973673e67521e02db2b9331cf 100644 --- a/EOM.TSHotelManagement.Domain/Business/Customer/PassPortType.cs +++ b/EOM.TSHotelManagement.Domain/Business/Customer/PassPortType.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -30,7 +30,7 @@ namespace EOM.TSHotelManagement.Domain /// 证件类型 /// [SqlSugar.SugarTable("passport_type")] - public class PassportType : BaseEntity + public class PassportType : SoftDeleteEntity { [SugarColumn(ColumnName = "id", IsIdentity = true, IsPrimaryKey = true, IsNullable = false, ColumnDescription = "编号 (ID)")] public int Id { get; set; } diff --git a/EOM.TSHotelManagement.Domain/Business/EnergyManagement/EnergyManagement.cs b/EOM.TSHotelManagement.Domain/Business/EnergyManagement/EnergyManagement.cs index 84bbe0675e0156a8136e286b509c825bf19b48ca..d12bc48c69e7e07e23b67da888e1da1c22c44c5a 100644 --- a/EOM.TSHotelManagement.Domain/Business/EnergyManagement/EnergyManagement.cs +++ b/EOM.TSHotelManagement.Domain/Business/EnergyManagement/EnergyManagement.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -31,7 +31,7 @@ namespace EOM.TSHotelManagement.Domain /// 水电信息 /// [SqlSugar.SugarTable("energy_management", "水电信息")] - public class EnergyManagement : BaseEntity + public class EnergyManagement : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/Business/News/News.cs b/EOM.TSHotelManagement.Domain/Business/News/News.cs index fe1706e664c8eee8a4b4465b3cc427889c9bdd0f..57c66bbe88ac54b1c6d1fcbccff161e45d54484f 100644 --- a/EOM.TSHotelManagement.Domain/Business/News/News.cs +++ b/EOM.TSHotelManagement.Domain/Business/News/News.cs @@ -1,9 +1,9 @@ -using System; +using System; namespace EOM.TSHotelManagement.Domain { [SqlSugar.SugarTable("news", "新闻动态")] - public class News : BaseEntity + public class News : SoftDeleteEntity { [SqlSugar.SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "索引ID")] public int Id { get; set; } diff --git a/EOM.TSHotelManagement.Domain/Business/PromotionContent/PromotionContent.cs b/EOM.TSHotelManagement.Domain/Business/PromotionContent/PromotionContent.cs index d6eec3e3890ccda2a6e9d886538be53486b70d77..211ff73570abe57138d316c45931af0f9f6645b1 100644 --- a/EOM.TSHotelManagement.Domain/Business/PromotionContent/PromotionContent.cs +++ b/EOM.TSHotelManagement.Domain/Business/PromotionContent/PromotionContent.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -30,7 +30,7 @@ namespace EOM.TSHotelManagement.Domain /// APP横幅配置表 (APP Banner Configuration) /// [SugarTable("app_banner", "APP横幅配置表 (APP Banner Configuration)")] - public class PromotionContent : BaseEntity + public class PromotionContent : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/Business/Reser/Reser.cs b/EOM.TSHotelManagement.Domain/Business/Reser/Reser.cs index cf497f24e1732492d954b3ebe368894ecf59654f..8e27af87ea71260c87651b6d5054f8c7ee0f27ad 100644 --- a/EOM.TSHotelManagement.Domain/Business/Reser/Reser.cs +++ b/EOM.TSHotelManagement.Domain/Business/Reser/Reser.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -31,7 +31,7 @@ namespace EOM.TSHotelManagement.Domain /// 预约信息表 (Reservation Information) /// [SugarTable("reser", "预约信息表 (Reservation Information)")] - public class Reser : BaseEntity + public class Reser : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/Business/Room/Room.cs b/EOM.TSHotelManagement.Domain/Business/Room/Room.cs index b161cef714cfc7cd040478118fff434cf6461f4c..7be37c6e624e17fdae5ff89e60edec81a8eacdb3 100644 --- a/EOM.TSHotelManagement.Domain/Business/Room/Room.cs +++ b/EOM.TSHotelManagement.Domain/Business/Room/Room.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -32,7 +32,7 @@ namespace EOM.TSHotelManagement.Domain /// 酒店房间信息表 (Hotel Room Information) /// [SugarTable("room", "酒店房间信息表 (Hotel Room Information)")] - public class Room : BaseEntity + public class Room : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/Business/Room/RoomType.cs b/EOM.TSHotelManagement.Domain/Business/Room/RoomType.cs index 783f7c2e73d2892eb34b7e64d746e39e6cb4a9b7..95c2f323044eb380385badc0933cb123f7a0efe1 100644 --- a/EOM.TSHotelManagement.Domain/Business/Room/RoomType.cs +++ b/EOM.TSHotelManagement.Domain/Business/Room/RoomType.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -31,7 +31,7 @@ namespace EOM.TSHotelManagement.Domain /// 房间类型配置表 (Room Type Configuration) /// [SugarTable("room_type", "房间类型配置表 (Room Type Configuration)")] - public class RoomType : BaseEntity + public class RoomType : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/Business/Sellthing/SellThing.cs b/EOM.TSHotelManagement.Domain/Business/Sellthing/SellThing.cs index 8039a86f016d9ff85e50233303b56cede0a86d75..80ebc57e9e32abcb3e338c6c9a175a6029906d33 100644 --- a/EOM.TSHotelManagement.Domain/Business/Sellthing/SellThing.cs +++ b/EOM.TSHotelManagement.Domain/Business/Sellthing/SellThing.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -32,7 +32,7 @@ namespace EOM.TSHotelManagement.Domain /// 商品信息表 (Product Information) /// [SugarTable("sellthing", "商品信息表 (Product Information)")] - public class SellThing : BaseEntity + public class SellThing : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/Business/Spend/Spend.cs b/EOM.TSHotelManagement.Domain/Business/Spend/Spend.cs index 514641fe30c2334dd84903a28abea66ff5a9d3c2..c1ecda6804a78fcd96f5867105bb8ee53bf1b187 100644 --- a/EOM.TSHotelManagement.Domain/Business/Spend/Spend.cs +++ b/EOM.TSHotelManagement.Domain/Business/Spend/Spend.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -31,7 +31,7 @@ namespace EOM.TSHotelManagement.Domain /// 消费信息 (Consumption Information) /// [SugarTable("customer_spend")] - public class Spend : BaseEntity + public class Spend : SoftDeleteEntity { [SugarColumn(ColumnName = "id", IsIdentity = true, IsPrimaryKey = true, IsNullable = false, ColumnDescription = "编号 (ID)")] public int Id { get; set; } diff --git a/EOM.TSHotelManagement.Domain/Common/AuditEntity.cs b/EOM.TSHotelManagement.Domain/Common/AuditEntity.cs new file mode 100644 index 0000000000000000000000000000000000000000..b2e854eb10cd7184f0fc74d5f1b48dde26b4f2d1 --- /dev/null +++ b/EOM.TSHotelManagement.Domain/Common/AuditEntity.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace EOM.TSHotelManagement.Domain; + +public class AuditEntity: BaseEntity +{ + /// + /// 资料创建人 + /// + [SqlSugar.SugarColumn(ColumnName = "datains_usr", Length = 128, IsOnlyIgnoreUpdate = true, IsNullable = true)] + public string? DataInsUsr { get; set; } + /// + /// 资料创建时间 + /// + [SqlSugar.SugarColumn(ColumnName = "datains_date", IsOnlyIgnoreUpdate = true, IsNullable = true)] + public DateTime? DataInsDate { get; set; } + /// + /// 资料更新人 + /// + [SqlSugar.SugarColumn(ColumnName = "datachg_usr", Length = 128, IsOnlyIgnoreInsert = true, IsNullable = true)] + public string? DataChgUsr { get; set; } + /// + /// 资料更新时间 + /// + [SqlSugar.SugarColumn(ColumnName = "datachg_date", IsOnlyIgnoreInsert = true, IsNullable = true)] + public DateTime? DataChgDate { get; set; } +} diff --git a/EOM.TSHotelManagement.Domain/Common/BaseEntity.cs b/EOM.TSHotelManagement.Domain/Common/BaseEntity.cs new file mode 100644 index 0000000000000000000000000000000000000000..7a0b7af276f2ee8cba0ec17fb93104078fdcf85d --- /dev/null +++ b/EOM.TSHotelManagement.Domain/Common/BaseEntity.cs @@ -0,0 +1,18 @@ +using System; + +namespace EOM.TSHotelManagement.Domain +{ + public class BaseEntity + { + /// + /// 行版本(乐观锁) + /// + [SqlSugar.SugarColumn(ColumnName = "row_version", IsNullable = false, DefaultValue = "1")] + public long RowVersion { get; set; } = 1; + /// + /// Token + /// + [SqlSugar.SugarColumn(IsIgnore = true)] + public string? UserToken { get; set; } + } +} diff --git a/EOM.TSHotelManagement.Domain/Common/Personnel.cs b/EOM.TSHotelManagement.Domain/Common/Personnel.cs new file mode 100644 index 0000000000000000000000000000000000000000..f383a2625a9915314bacf61d7a1edf0b6f4f439b --- /dev/null +++ b/EOM.TSHotelManagement.Domain/Common/Personnel.cs @@ -0,0 +1,30 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Text; + +namespace EOM.TSHotelManagement.Domain; + +public class Personnel : SoftDeleteEntity +{ + [SugarColumn(ColumnName = "name", IsNullable = false, ColumnDescription = "姓名", Length = 250)] + public string Name { get; set; } = string.Empty; + [SugarColumn(ColumnName = "phone_number", IsNullable = false, ColumnDescription = "电话号码", Length = 256)] + public string PhoneNumber { get; set; } = string.Empty; + [SugarColumn(ColumnName = "id_number", IsNullable = false, ColumnDescription = "证件号码", Length = 256)] + public string IdCardNumber { get; set; } = string.Empty; + [SugarColumn(ColumnName = "address", IsNullable = false, ColumnDescription = "联系地址", Length = 500)] + public string Address { get; set; } = string.Empty; + [SugarColumn(ColumnName = "date_of_birth", IsNullable = false, ColumnDescription = "出生日期")] + public DateOnly DateOfBirth { get; set; } = DateOnly.MinValue; + [SugarColumn(ColumnName = "gender", IsNullable = false, ColumnDescription = "性别(0/女,1/男)")] + public int Gender { get; set; } = 0; + [SugarColumn(ColumnName = "id_type", IsNullable = false, ColumnDescription = "证件类型")] + public int IdCardType { get; set; } = 0; + [SugarColumn(ColumnName = "ethnicity", IsNullable = false, ColumnDescription = "民族", Length = 128)] + public string Ethnicity { get; set; } = string.Empty; + [SugarColumn(ColumnName = "education_level", IsNullable = false, ColumnDescription = "教育程度", Length = 128)] + public string EducationLevel { get; set; } = string.Empty; + [SugarColumn(ColumnName = "email_address", IsNullable = false, Length = 256, ColumnDescription = "邮箱地址")] + public string EmailAddress { get; set; } = string.Empty; +} diff --git a/EOM.TSHotelManagement.Domain/Common/SoftDeleteEntity.cs b/EOM.TSHotelManagement.Domain/Common/SoftDeleteEntity.cs new file mode 100644 index 0000000000000000000000000000000000000000..e8a8663b9620c3d3bb0af9a9477cc34fcf5789af --- /dev/null +++ b/EOM.TSHotelManagement.Domain/Common/SoftDeleteEntity.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace EOM.TSHotelManagement.Domain; + +public class SoftDeleteEntity : AuditEntity +{ + /// + /// 删除标识 + /// + [SqlSugar.SugarColumn(ColumnName = "delete_mk", Length = 11, IsNullable = false, DefaultValue = "0")] + public int? IsDelete { get; set; } = 0; +} diff --git a/EOM.TSHotelManagement.Domain/EOM.TSHotelManagement.Domain.csproj b/EOM.TSHotelManagement.Domain/EOM.TSHotelManagement.Domain.csproj index befa5d96705b7aae64858c5e4f3df64f211d4c61..9a50f0f8b089cc06273ca89c2dbc00862b243015 100644 --- a/EOM.TSHotelManagement.Domain/EOM.TSHotelManagement.Domain.csproj +++ b/EOM.TSHotelManagement.Domain/EOM.TSHotelManagement.Domain.csproj @@ -12,7 +12,7 @@ - + diff --git a/EOM.TSHotelManagement.Domain/Employee/Employee.cs b/EOM.TSHotelManagement.Domain/Employee/Employee.cs index 77db18547700769da750e5b205b98a70693e54fa..1b167468e8edea7f6acb0e7722663b215dd65a4f 100644 --- a/EOM.TSHotelManagement.Domain/Employee/Employee.cs +++ b/EOM.TSHotelManagement.Domain/Employee/Employee.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -31,7 +31,7 @@ namespace EOM.TSHotelManagement.Domain /// 员工信息 (Employee Information) /// [SugarTable("employee")] - public class Employee : BaseEntity + public class Employee : Personnel //SoftDeleteEntity { /// /// 编号 (ID) @@ -45,90 +45,18 @@ namespace EOM.TSHotelManagement.Domain [SugarColumn(ColumnName = "employee_number", IsPrimaryKey = true, IsNullable = false, Length = 128, ColumnDescription = "员工账号/工号 (Employee Account/ID)")] public string EmployeeId { get; set; } - /// - /// 员工姓名 (Employee Name) - /// - [SugarColumn(ColumnName = "employee_name", IsNullable = false, Length = 250, ColumnDescription = "员工姓名 (Employee Name)")] - public string EmployeeName { get; set; } - - /// - /// 出生日期 (Date of Birth) - /// - [SugarColumn(ColumnName = "employee_date_of_birth", IsNullable = false, ColumnDescription = "出生日期 (Date of Birth)")] - public DateOnly DateOfBirth { get; set; } - - /// - /// 员工性别 (Employee Gender) - /// - [SugarColumn(ColumnName = "employee_gender", IsNullable = false, ColumnDescription = "员工性别 (Employee Gender)")] - public int Gender { get; set; } - - /// - /// 员工性别(名称描述) (Employee Gender (Name Description)) - /// - [SugarColumn(IsIgnore = true)] - public string GenderName { get; set; } - - /// - /// 民族类型 (Ethnicity) - /// - [SugarColumn(ColumnName = "employee_nation", IsNullable = false, Length = 128, ColumnDescription = "民族类型 (Ethnicity)")] - public string Ethnicity { get; set; } - - /// - /// 民族名称 (Ethnicity Name) - /// - [SugarColumn(IsIgnore = true)] - public string EthnicityName { get; set; } - - /// - /// 员工电话 (Employee Phone Number) - /// - [SugarColumn(ColumnName = "employee_tel", IsNullable = false, Length = 256, ColumnDescription = "员工电话 (Employee Phone Number)")] - public string PhoneNumber { get; set; } - /// /// 所属部门 (Department) /// [SugarColumn(ColumnName = "employee_department", IsNullable = false, Length = 128, ColumnDescription = "所属部门 (Department)")] public string Department { get; set; } - /// - /// 部门名称 (Department Name) - /// - [SugarColumn(IsIgnore = true)] - public string DepartmentName { get; set; } - - /// - /// 居住地址 (Residential Address) - /// - [SugarColumn(ColumnName = "employee_address", IsNullable = true, Length = 500, ColumnDescription = "居住地址 (Residential Address)")] - public string Address { get; set; } - /// /// 员工职位 (Employee Position) /// [SugarColumn(ColumnName = "employee_postion", IsNullable = false, Length = 128, ColumnDescription = "员工职位 (Employee Position)")] public string Position { get; set; } - /// - /// 职位名称 (Position Name) - /// - [SugarColumn(IsIgnore = true)] - public string PositionName { get; set; } - - /// - /// 证件类型 (ID Card Type) - /// - [SugarColumn(ColumnName = "card_type", IsNullable = false, ColumnDescription = "证件类型 (ID Card Type)")] - public int IdCardType { get; set; } - - /// - /// 证件号码 (ID Card Number) - /// - [SugarColumn(ColumnName = "card_number", IsNullable = false, Length = 256, ColumnDescription = "证件号码 (ID Card Number)")] - public string IdCardNumber { get; set; } - /// /// 员工密码 (Employee Password) /// @@ -147,30 +75,6 @@ namespace EOM.TSHotelManagement.Domain [SugarColumn(ColumnName = "employee_political", IsNullable = false, Length = 128, ColumnDescription = "员工面貌 (Political Affiliation)")] public string PoliticalAffiliation { get; set; } - /// - /// 群众面貌描述 (Political Affiliation Description) - /// - [SugarColumn(IsIgnore = true)] - public string PoliticalAffiliationName { get; set; } - - /// - /// 证件类型 (ID Card Type) - /// - [SugarColumn(IsIgnore = true)] - public string IdCardTypeName { get; set; } - - /// - /// 教育程度 (Education Level) - /// - [SugarColumn(ColumnName = "employee_quality", IsNullable = false, Length = 128, ColumnDescription = "教育程度 (Education Level)")] - public string EducationLevel { get; set; } - - /// - /// 教育程度名称 (Education Level Name) - /// - [SugarColumn(IsIgnore = true)] - public string EducationLevelName { get; set; } - /// /// 禁用标记 /// @@ -182,11 +86,5 @@ namespace EOM.TSHotelManagement.Domain /// [SugarColumn(ColumnName = "initialize_mk", IsNullable = false, ColumnDescription = "初始化标记")] public int IsInitialize { get; set; } - - /// - /// 邮箱地址 - /// - [SugarColumn(ColumnName = "email_address", IsNullable = false, Length = 256, ColumnDescription = "邮箱地址")] - public string EmailAddress { get; set; } } } diff --git a/EOM.TSHotelManagement.Domain/Employee/EmployeeCheck.cs b/EOM.TSHotelManagement.Domain/Employee/EmployeeCheck.cs index 92e40db7c3dbee7254824e7c10cf53c07ce4c57a..89e567b4c5828bb498270861ff004e211e8a3ee4 100644 --- a/EOM.TSHotelManagement.Domain/Employee/EmployeeCheck.cs +++ b/EOM.TSHotelManagement.Domain/Employee/EmployeeCheck.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -31,7 +31,7 @@ namespace EOM.TSHotelManagement.Domain /// 员工打卡考勤 (Employee Check-in/Check-out Record) /// [SugarTable("employee_check", "员工打卡考勤 (Employee Check-in/Check-out Record)")] - public class EmployeeCheck : BaseEntity + public class EmployeeCheck : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/Employee/EmployeeHistory.cs b/EOM.TSHotelManagement.Domain/Employee/EmployeeHistory.cs index b1a93b0562953aedfd4172e1324eda29b099c786..56ccbbc2cd2f08263a776f8f5968da46cc5d374f 100644 --- a/EOM.TSHotelManagement.Domain/Employee/EmployeeHistory.cs +++ b/EOM.TSHotelManagement.Domain/Employee/EmployeeHistory.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -31,7 +31,7 @@ namespace EOM.TSHotelManagement.Domain /// 员工履历 (Employee History) /// [SugarTable("employee_history")] - public class EmployeeHistory : BaseEntity + public class EmployeeHistory : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/Employee/EmployeePhoto.cs b/EOM.TSHotelManagement.Domain/Employee/EmployeePhoto.cs index 2a86f21bd035cb93d9c9d3d6f62e17ebc96529d8..b216028d28fcfecf4e1d80119d63742f9ae39a74 100644 --- a/EOM.TSHotelManagement.Domain/Employee/EmployeePhoto.cs +++ b/EOM.TSHotelManagement.Domain/Employee/EmployeePhoto.cs @@ -1,4 +1,4 @@ -using SqlSugar; +using SqlSugar; namespace EOM.TSHotelManagement.Domain { @@ -6,7 +6,7 @@ namespace EOM.TSHotelManagement.Domain /// 员工照片 (Employee Photo) /// [SugarTable("employee_pic", "员工照片 (Employee Photo)")] - public class EmployeePhoto : BaseEntity + public class EmployeePhoto : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/Employee/EmployeeRewardPunishment.cs b/EOM.TSHotelManagement.Domain/Employee/EmployeeRewardPunishment.cs index e88ee2e0fa2e26e1b43064aede62414e3b0e849f..38d311a32ddac9bb351d07f585bf383b248b0170 100644 --- a/EOM.TSHotelManagement.Domain/Employee/EmployeeRewardPunishment.cs +++ b/EOM.TSHotelManagement.Domain/Employee/EmployeeRewardPunishment.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -31,7 +31,7 @@ namespace EOM.TSHotelManagement.Domain /// 员工奖惩 (Employee Rewards/Punishments) /// [SugarTable("reward_punishment", "员工奖惩 (Employee Rewards/Punishments)")] - public class EmployeeRewardPunishment : BaseEntity + public class EmployeeRewardPunishment : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/Employee/RewardPunishmentType.cs b/EOM.TSHotelManagement.Domain/Employee/RewardPunishmentType.cs index 028cbaa5a2de3af05bc396a682cc18a4f97f1eab..2e97cd3183f8f1fe769c4056d786286bc61ad0ec 100644 --- a/EOM.TSHotelManagement.Domain/Employee/RewardPunishmentType.cs +++ b/EOM.TSHotelManagement.Domain/Employee/RewardPunishmentType.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -31,7 +31,7 @@ namespace EOM.TSHotelManagement.Domain /// 奖惩类型配置表 (Reward/Punishment Type Configuration) /// [SugarTable("reward_punishment_type", "奖惩类型配置表 (Reward/Punishment Type Configuration)")] - public class RewardPunishmentType : BaseEntity + public class RewardPunishmentType : SoftDeleteEntity { /// /// 编号 (ID) @@ -62,4 +62,4 @@ namespace EOM.TSHotelManagement.Domain )] public string RewardPunishmentTypeName { get; set; } } -} \ No newline at end of file +} diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/Administrator.cs b/EOM.TSHotelManagement.Domain/SystemManagement/Administrator.cs index fb52e734c76c5371719a6b8b5ddae7b63aea5dc5..1b52c3dcb4df9e54392bd850eef1bbd4eb228ff6 100644 --- a/EOM.TSHotelManagement.Domain/SystemManagement/Administrator.cs +++ b/EOM.TSHotelManagement.Domain/SystemManagement/Administrator.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -31,7 +31,7 @@ namespace EOM.TSHotelManagement.Domain /// 管理员实体类 (Administrator Entity) /// [SugarTable("administrator", "管理员实体类 (Administrator Entity)", true)] - public class Administrator : BaseEntity + public class Administrator : Personnel //SoftDeleteEntity { /// /// 编号 (ID) @@ -67,35 +67,10 @@ namespace EOM.TSHotelManagement.Domain public string Type { get; set; } - /// - /// 管理员名称 (Administrator Name) - /// - [SugarColumn(ColumnName = "admin_name", IsNullable = false, Length = 200, ColumnDescription = "管理员名称 (Administrator Name)")] - - public string Name { get; set; } - /// /// 是否为超级管理员 (Is Super Administrator) /// [SugarColumn(ColumnName = "is_admin", IsNullable = false, ColumnDescription = "是否为超级管理员 (Is Super Administrator)")] public int IsSuperAdmin { get; set; } - - /// - /// 是否为超级管理员描述 (Is Super Administrator Description) - /// - [SugarColumn(IsIgnore = true)] - public string IsSuperAdminDescription { get; set; } - - /// - /// 管理员类型名称 (Administrator Type Name) - /// - [SugarColumn(IsIgnore = true)] - public string TypeName { get; set; } - - /// - /// 删除标记描述 (Delete Flag Description) - /// - [SugarColumn(IsIgnore = true)] - public string DeleteDescription { get; set; } } } diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/AdministratorPhoto.cs b/EOM.TSHotelManagement.Domain/SystemManagement/AdministratorPhoto.cs new file mode 100644 index 0000000000000000000000000000000000000000..d0eebf4388abcdd1f08f21f48e2ecec37d4b5fdb --- /dev/null +++ b/EOM.TSHotelManagement.Domain/SystemManagement/AdministratorPhoto.cs @@ -0,0 +1,20 @@ +using SqlSugar; + +namespace EOM.TSHotelManagement.Domain +{ + /// + /// 管理员头像 + /// + [SugarTable("administrator_pic", "管理员头像")] + public class AdministratorPhoto : SoftDeleteEntity + { + [SugarColumn(ColumnName = "id", IsIdentity = true, IsPrimaryKey = true, IsNullable = false, ColumnDescription = "编号")] + public int Id { get; set; } + + [SugarColumn(ColumnName = "admin_number", ColumnDescription = "管理员编号", Length = 128, IsNullable = false, IsPrimaryKey = true)] + public string AdminNumber { get; set; } + + [SugarColumn(ColumnName = "pic_url", ColumnDescription = "头像地址", Length = 256, IsNullable = true)] + public string PhotoPath { get; set; } + } +} diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/AdministratorType.cs b/EOM.TSHotelManagement.Domain/SystemManagement/AdministratorType.cs index d8d04c536aa39101a04c61b535c3b7e5d48a475a..b46121660e8a24b136299d2b57b67191b8c322de 100644 --- a/EOM.TSHotelManagement.Domain/SystemManagement/AdministratorType.cs +++ b/EOM.TSHotelManagement.Domain/SystemManagement/AdministratorType.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -30,7 +30,7 @@ namespace EOM.TSHotelManagement.Domain /// 管理员类型 (Administrator Type) /// [SugarTable("administrator_type", "管理员类型 (Administrator Type)", true)] - public class AdministratorType : BaseEntity + public class AdministratorType : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/AppointmentNotice.cs b/EOM.TSHotelManagement.Domain/SystemManagement/AppointmentNotice.cs index d9acdd4a55485a908d8fdb81ee4c42203cb780c9..f639ed72f6cccbdbe77a99d4217b091df54dc21d 100644 --- a/EOM.TSHotelManagement.Domain/SystemManagement/AppointmentNotice.cs +++ b/EOM.TSHotelManagement.Domain/SystemManagement/AppointmentNotice.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -31,7 +31,7 @@ namespace EOM.TSHotelManagement.Domain /// 任命公告 (Appointment AppointmentNotice) /// [SugarTable("appointment_notice", "任命公告 (Appointment AppointmentNotice)")] - public class AppointmentNotice : BaseEntity + public class AppointmentNotice : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/AppointmentNoticeType.cs b/EOM.TSHotelManagement.Domain/SystemManagement/AppointmentNoticeType.cs index 1afdeec95c233949b65b9df065a3b84d3c1cb569..4bd65db8feddc2ad6a322ed85be25f703cf80fd4 100644 --- a/EOM.TSHotelManagement.Domain/SystemManagement/AppointmentNoticeType.cs +++ b/EOM.TSHotelManagement.Domain/SystemManagement/AppointmentNoticeType.cs @@ -1,9 +1,9 @@ -using SqlSugar; +using SqlSugar; namespace EOM.TSHotelManagement.Domain { [SugarTable("appointment_notice_type", "任命公告类型 (Appointment AppointmentNotice Type)")] - public class AppointmentNoticeType : BaseEntity + public class AppointmentNoticeType : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/Department.cs b/EOM.TSHotelManagement.Domain/SystemManagement/Department.cs index 00e5a5eac8d690560764de9fd831bcab83a6360c..98721a73b3ec19c54fb8f8fafff1267e1a3dce46 100644 --- a/EOM.TSHotelManagement.Domain/SystemManagement/Department.cs +++ b/EOM.TSHotelManagement.Domain/SystemManagement/Department.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -31,7 +31,7 @@ namespace EOM.TSHotelManagement.Domain /// 部门表 (Department Table) /// [SugarTable("department")] - public class Department : BaseEntity + public class Department : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/Education.cs b/EOM.TSHotelManagement.Domain/SystemManagement/Education.cs index e96f210145de3099c780750c84847fd1b9727082..6a7d0879b5d7079dcc9d1c91949b5aba5ae93073 100644 --- a/EOM.TSHotelManagement.Domain/SystemManagement/Education.cs +++ b/EOM.TSHotelManagement.Domain/SystemManagement/Education.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -30,7 +30,7 @@ namespace EOM.TSHotelManagement.Domain /// 学历 (Education) /// [SugarTable("qualification", "学历 (Education)")] - public class Education : BaseEntity + public class Education : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/Menu.cs b/EOM.TSHotelManagement.Domain/SystemManagement/Menu.cs index ad8152ce4021ff3d97fe724f5c1bef7d9069fcf7..c0468ce5e0232ad6704e9f864a3e9a69e0ca978b 100644 --- a/EOM.TSHotelManagement.Domain/SystemManagement/Menu.cs +++ b/EOM.TSHotelManagement.Domain/SystemManagement/Menu.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -29,7 +29,7 @@ namespace EOM.TSHotelManagement.Domain /// 菜单表 (Menu Table) /// [SugarTable("menu", "菜单表 (Menu Table)", true)] - public class Menu : BaseEntity + public class Menu : SoftDeleteEntity { /// /// 编号 (ID) @@ -72,4 +72,4 @@ namespace EOM.TSHotelManagement.Domain public string Icon { get; set; } } -} \ No newline at end of file +} diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/Nation.cs b/EOM.TSHotelManagement.Domain/SystemManagement/Nation.cs index 3f3ce961a9fc00b0c8143698ab6db45c9751ef77..168efa172b29deff6cddc6d0eacf7eb8299ad9ad 100644 --- a/EOM.TSHotelManagement.Domain/SystemManagement/Nation.cs +++ b/EOM.TSHotelManagement.Domain/SystemManagement/Nation.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -30,7 +30,7 @@ namespace EOM.TSHotelManagement.Domain /// 民族 (Nation) /// [SugarTable("nation", "民族信息表 (Nation Information)")] - public class Nation : BaseEntity + public class Nation : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/Permission.cs b/EOM.TSHotelManagement.Domain/SystemManagement/Permission.cs index 9f96ad8f67162dc333f2e3eba14a03a111b104cc..8bc0bad79723ed21bb4a5ddfa39d8fce603155d2 100644 --- a/EOM.TSHotelManagement.Domain/SystemManagement/Permission.cs +++ b/EOM.TSHotelManagement.Domain/SystemManagement/Permission.cs @@ -6,7 +6,7 @@ namespace EOM.TSHotelManagement.Domain /// 系统权限定义表 (Permission Definition) /// [SugarTable("permission", "系统权限定义表 (Permission Definition)")] - public class Permission : BaseEntity + public class Permission : AuditEntity { /// /// 编号 (ID) @@ -81,4 +81,4 @@ namespace EOM.TSHotelManagement.Domain )] public string? ParentNumber { get; set; } } -} \ No newline at end of file +} diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/Position.cs b/EOM.TSHotelManagement.Domain/SystemManagement/Position.cs index de74ca00575b4a0992830a43f78c0a125d74823c..2f1f31076515e5e927dc502984dec7280a9fd3bf 100644 --- a/EOM.TSHotelManagement.Domain/SystemManagement/Position.cs +++ b/EOM.TSHotelManagement.Domain/SystemManagement/Position.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -30,7 +30,7 @@ namespace EOM.TSHotelManagement.Domain /// 职位信息表 (Position Information) /// [SugarTable("position", "职位信息表 (Position Information)")] - public class Position : BaseEntity + public class Position : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/Role.cs b/EOM.TSHotelManagement.Domain/SystemManagement/Role.cs index faf24143ed810e3f4820228b67dfca062270241c..5dceac4e75a6f881b04093579e0c50a0001ba9d3 100644 --- a/EOM.TSHotelManagement.Domain/SystemManagement/Role.cs +++ b/EOM.TSHotelManagement.Domain/SystemManagement/Role.cs @@ -1,11 +1,11 @@ -using SqlSugar; +using SqlSugar; namespace EOM.TSHotelManagement.Domain { /// /// 系统角色配置表 (System Role Configuration) /// [SugarTable("role", "系统角色配置表 (System Role Configuration)")] - public class Role : BaseEntity + public class Role : SoftDeleteEntity { /// /// 编号 (ID) @@ -48,4 +48,4 @@ namespace EOM.TSHotelManagement.Domain public string? RoleDescription { get; set; } } -} \ No newline at end of file +} diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/RolePermission.cs b/EOM.TSHotelManagement.Domain/SystemManagement/RolePermission.cs index b2737df70f9becba27e4814b15c13e6449ec9005..38a73783f8771055643edd9a6ed39896718166d6 100644 --- a/EOM.TSHotelManagement.Domain/SystemManagement/RolePermission.cs +++ b/EOM.TSHotelManagement.Domain/SystemManagement/RolePermission.cs @@ -1,11 +1,11 @@ -using SqlSugar; +using SqlSugar; namespace EOM.TSHotelManagement.Domain { /// /// 角色权限关联表 (Role-Permission Mapping) /// [SugarTable("role_permission", "角色权限关联表 (Role-Permission Mapping)")] - public class RolePermission : BaseEntity + public class RolePermission : AuditEntity { /// /// 编号 (ID) @@ -18,7 +18,6 @@ namespace EOM.TSHotelManagement.Domain /// [SugarColumn( ColumnName = "role_number", - IsPrimaryKey = true, ColumnDescription = "关联角色编码 (Linked Role Code)", IsNullable = false, Length = 128, @@ -31,13 +30,23 @@ namespace EOM.TSHotelManagement.Domain /// [SugarColumn( ColumnName = "permission_number", - IsPrimaryKey = true, ColumnDescription = "关联权限编码 (Linked Permission Code)", - IsNullable = false, + IsNullable = true, Length = 128, IndexGroupNameList = new[] { "IX_permission_number" } )] - public string PermissionNumber { get; set; } = null!; + public string? PermissionNumber { get; set; } + + /// + /// 菜单主键(关联菜单表) (Menu Id) + /// + [SugarColumn( + ColumnName = "menu_id", + ColumnDescription = "关联菜单主键 (Linked Menu Id)", + IsNullable = true, + IndexGroupNameList = new[] { "IX_menu_id" } + )] + public int? MenuId { get; set; } } -} \ No newline at end of file +} diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/SupervisionStatistics.cs b/EOM.TSHotelManagement.Domain/SystemManagement/SupervisionStatistics.cs index 63594098cd3936f54deafb6d73c67d0274f74312..3bd6c0eca45410e7b4636a62da05486da4cfc7b9 100644 --- a/EOM.TSHotelManagement.Domain/SystemManagement/SupervisionStatistics.cs +++ b/EOM.TSHotelManagement.Domain/SystemManagement/SupervisionStatistics.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -31,7 +31,7 @@ namespace EOM.TSHotelManagement.Domain /// 监管统计信息表 (Supervision Statistics) /// [SugarTable("supervision_statistics", "监管统计信息表 (Supervision Statistics)")] - public class SupervisionStatistics : BaseEntity + public class SupervisionStatistics : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/SystemInformation.cs b/EOM.TSHotelManagement.Domain/SystemManagement/SystemInformation.cs deleted file mode 100644 index ec4876b71152e375f20e829a0a7c822124fa5527..0000000000000000000000000000000000000000 --- a/EOM.TSHotelManagement.Domain/SystemManagement/SystemInformation.cs +++ /dev/null @@ -1,53 +0,0 @@ -/* - * MIT License - *Copyright (c) 2021 易开元(Easy-Open-Meta) - - *Permission is hereby granted, free of charge, to any person obtaining a copy - *of this software and associated documentation files (the "Software"), to deal - *in the Software without restriction, including without limitation the rights - *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - *copies of the Software, and to permit persons to whom the Software is - *furnished to do so, subject to the following conditions: - - *The above copyright notice and this permission notice shall be included in all - *copies or substantial portions of the Software. - - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - *SOFTWARE. - * - *模块说明:系统信息静态类 - */ -using SqlSugar; - -namespace EOM.TSHotelManagement.Domain -{ - /// - /// 系统信息 (System Information) - /// - [SugarTable("app_config_base", "系统信息 (System Information)", true)] - public class SystemInformation - { - /// - /// 编号 (ID) - /// - [SugarColumn(ColumnName = "id", IsIdentity = true, IsPrimaryKey = true, IsNullable = false, ColumnDescription = "编号 (ID)")] - public int Id { get; set; } - - /// - /// 地址编号 (URL Number) - /// - [SugarColumn(ColumnName = "url_no", IsPrimaryKey = true, ColumnDescription = "地址编号 (URL Number)")] - public int UrlNumber { get; set; } - - /// - /// 地址 (URL Address) - /// - [SugarColumn(ColumnName = "url_addr", Length = 256, ColumnDescription = "地址 (URL Address)")] - public string UrlAddress { get; set; } - } -} diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/TwoFactorAuth.cs b/EOM.TSHotelManagement.Domain/SystemManagement/TwoFactorAuth.cs index a87512de1263ed621183552e44b024e7fb96bf0a..db9225396e3ba0cb855ce449d1ca89b15d926d54 100644 --- a/EOM.TSHotelManagement.Domain/SystemManagement/TwoFactorAuth.cs +++ b/EOM.TSHotelManagement.Domain/SystemManagement/TwoFactorAuth.cs @@ -6,7 +6,7 @@ namespace EOM.TSHotelManagement.Domain [SugarIndex("ux_2fa_employee_pk", nameof(EmployeePk), OrderByType.Asc, true)] [SugarIndex("ux_2fa_administrator_pk", nameof(AdministratorPk), OrderByType.Asc, true)] [SugarIndex("ux_2fa_customer_account_pk", nameof(CustomerAccountPk), OrderByType.Asc, true)] - public class TwoFactorAuth : BaseEntity + public class TwoFactorAuth : SoftDeleteEntity { [SugarColumn(ColumnName = "id", IsIdentity = true, IsPrimaryKey = true, IsNullable = false, ColumnDescription = "索引ID")] public int Id { get; set; } diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/TwoFactorRecoveryCode.cs b/EOM.TSHotelManagement.Domain/SystemManagement/TwoFactorRecoveryCode.cs index 108125ac2cde198de047cf1728a83f7b53ce9978..5ddc562d883419dfcc2c7a8c88625b47ba723e77 100644 --- a/EOM.TSHotelManagement.Domain/SystemManagement/TwoFactorRecoveryCode.cs +++ b/EOM.TSHotelManagement.Domain/SystemManagement/TwoFactorRecoveryCode.cs @@ -5,7 +5,7 @@ namespace EOM.TSHotelManagement.Domain [SugarTable("two_factor_recovery_code", "2FA recovery codes")] [SugarIndex("idx_2fa_recovery_auth", nameof(TwoFactorAuthPk), OrderByType.Asc)] [SugarIndex("idx_2fa_recovery_used", nameof(IsUsed), OrderByType.Asc)] - public class TwoFactorRecoveryCode : BaseEntity + public class TwoFactorRecoveryCode : SoftDeleteEntity { [SugarColumn(ColumnName = "id", IsIdentity = true, IsPrimaryKey = true, IsNullable = false, ColumnDescription = "Primary key")] public int Id { get; set; } diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/UserRole.cs b/EOM.TSHotelManagement.Domain/SystemManagement/UserRole.cs index 11e2f3600041978505959c11bb3c81afe9863209..df93d59b9e438240d32791c761e2770cfbf6eb3b 100644 --- a/EOM.TSHotelManagement.Domain/SystemManagement/UserRole.cs +++ b/EOM.TSHotelManagement.Domain/SystemManagement/UserRole.cs @@ -1,11 +1,11 @@ -using SqlSugar; +using SqlSugar; namespace EOM.TSHotelManagement.Domain { // /// 用户角色关联表 (User-Role Mapping) /// [SugarTable("user_role", "用户角色关联表 (User-Role Mapping)")] - public class UserRole : BaseEntity + public class UserRole : AuditEntity { /// /// 编号 (ID) @@ -40,4 +40,4 @@ namespace EOM.TSHotelManagement.Domain public string UserNumber { get; set; } = null!; } -} \ No newline at end of file +} diff --git a/EOM.TSHotelManagement.Domain/SystemManagement/VipLevelRule.cs b/EOM.TSHotelManagement.Domain/SystemManagement/VipLevelRule.cs index 31b9546cccf6bea5e5abfb4cf26e9fccee20cf32..87d5c61325c475135c35086cb058418459d19a8c 100644 --- a/EOM.TSHotelManagement.Domain/SystemManagement/VipLevelRule.cs +++ b/EOM.TSHotelManagement.Domain/SystemManagement/VipLevelRule.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -30,7 +30,7 @@ namespace EOM.TSHotelManagement.Domain /// 会员等级规则表 (VIP Level Rules) /// [SugarTable("vip_rule", "会员等级规则配置表 (VIP Level Rule Configuration)")] - public class VipLevelRule : BaseEntity + public class VipLevelRule : SoftDeleteEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/Util/OperationLog.cs b/EOM.TSHotelManagement.Domain/Util/OperationLog.cs index 995bfbab3821fdf6de4a5a7ab0fc2f70db729ed6..01be2b39718ab0353ff449e3a8e514cd7c73a437 100644 --- a/EOM.TSHotelManagement.Domain/Util/OperationLog.cs +++ b/EOM.TSHotelManagement.Domain/Util/OperationLog.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -31,7 +31,7 @@ namespace EOM.TSHotelManagement.Domain /// 操作日志表 (Operation Log) /// [SugarTable("operation_log", "操作日志表 (Operation Log)")] - public class OperationLog : BaseEntity + public class OperationLog : AuditEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Domain/Util/RequestLog.cs b/EOM.TSHotelManagement.Domain/Util/RequestLog.cs index c2531657972fdf2fcd5f1806348b8e0c4cf5e9ee..03c2ad8bc802cf996cec222e1457d8a080ecc160 100644 --- a/EOM.TSHotelManagement.Domain/Util/RequestLog.cs +++ b/EOM.TSHotelManagement.Domain/Util/RequestLog.cs @@ -1,10 +1,10 @@ -using SqlSugar; +using SqlSugar; using System; namespace EOM.TSHotelManagement.Domain { [SugarTable("request_log", "请求日志表 (Request Log)")] - public class RequestLog : BaseEntity + public class RequestLog : AuditEntity { /// /// 编号 (ID) diff --git a/EOM.TSHotelManagement.Infrastructure/Config/MailConfig.cs b/EOM.TSHotelManagement.Infrastructure/Config/MailConfig.cs index 078f1c04d7452cb87f8ac4cee3fb003e87f00774..ace9a51bcfa3e821570dc07fece152f9dfb8eb91 100644 --- a/EOM.TSHotelManagement.Infrastructure/Config/MailConfig.cs +++ b/EOM.TSHotelManagement.Infrastructure/Config/MailConfig.cs @@ -1,4 +1,4 @@ -namespace EOM.TSHotelManagement.Infrastructure +namespace EOM.TSHotelManagement.Infrastructure { public class MailConfig { @@ -6,6 +6,7 @@ /// 是否启用邮件服务 /// public bool Enabled { get; set; } = false; + /// /// SMTP服务器地址 /// diff --git a/EOM.TSHotelManagement.Infrastructure/Config/RedisConfig.cs b/EOM.TSHotelManagement.Infrastructure/Config/RedisConfig.cs index 967ad81bb3c4c85e77aa4eca7dfa7ef5ab8fe41f..c50896be0b907bef17a10c4508bfcae663405ef3 100644 --- a/EOM.TSHotelManagement.Infrastructure/Config/RedisConfig.cs +++ b/EOM.TSHotelManagement.Infrastructure/Config/RedisConfig.cs @@ -5,5 +5,13 @@ namespace EOM.TSHotelManagement.Infrastructure public string ConnectionString { get; set; } public bool Enable { get; set; } public int? DefaultDatabase { get; set; } + public int? ConnectTimeoutMs { get; set; } + public int? AsyncTimeoutMs { get; set; } + public int? SyncTimeoutMs { get; set; } + public int? KeepAliveSeconds { get; set; } + public int? ConnectRetry { get; set; } + public int? ReconnectRetryBaseDelayMs { get; set; } + public int? OperationTimeoutMs { get; set; } + public int? FailureCooldownSeconds { get; set; } } } diff --git a/EOM.TSHotelManagement.Infrastructure/EOM.TSHotelManagement.Infrastructure.csproj b/EOM.TSHotelManagement.Infrastructure/EOM.TSHotelManagement.Infrastructure.csproj index d6e07bfdc3270ae58329f8dd6cd3d85ee351a183..a60e237a19e7e6ee2cdf43931b131686f3d7538a 100644 --- a/EOM.TSHotelManagement.Infrastructure/EOM.TSHotelManagement.Infrastructure.csproj +++ b/EOM.TSHotelManagement.Infrastructure/EOM.TSHotelManagement.Infrastructure.csproj @@ -12,8 +12,8 @@ - - + + diff --git a/EOM.TSHotelManagement.Infrastructure/Factory/LskyConfigFactory.cs b/EOM.TSHotelManagement.Infrastructure/Factory/LskyConfigFactory.cs index f36a3d5d97b2eab4084736eca908b7bebe70cd1d..729e2e88d5da6758f1b0b280e0065fedd93268e3 100644 --- a/EOM.TSHotelManagement.Infrastructure/Factory/LskyConfigFactory.cs +++ b/EOM.TSHotelManagement.Infrastructure/Factory/LskyConfigFactory.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration; namespace EOM.TSHotelManagement.Infrastructure { @@ -16,6 +16,7 @@ namespace EOM.TSHotelManagement.Infrastructure var lskySection = _configuration.GetSection("Lsky"); var lskyConfig = new LskyConfig { + Enabled = lskySection.GetValue("Enabled") ?? false, BaseAddress = lskySection.GetValue("BaseAddress") ?? string.Empty, Email = lskySection.GetValue("Email") ?? string.Empty, Password = lskySection.GetValue("Password") ?? string.Empty, @@ -25,4 +26,4 @@ namespace EOM.TSHotelManagement.Infrastructure return lskyConfig; } } -} \ No newline at end of file +} diff --git a/EOM.TSHotelManagement.Infrastructure/Factory/MailConfigFactory.cs b/EOM.TSHotelManagement.Infrastructure/Factory/MailConfigFactory.cs index 63a8bef3abff09d8e55e0e66765397c6bfd96597..b2939eb37be0cee9d0203c0ed57af18acc480ff3 100644 --- a/EOM.TSHotelManagement.Infrastructure/Factory/MailConfigFactory.cs +++ b/EOM.TSHotelManagement.Infrastructure/Factory/MailConfigFactory.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration; namespace EOM.TSHotelManagement.Infrastructure { @@ -20,7 +20,8 @@ namespace EOM.TSHotelManagement.Infrastructure UserName = _configuration.GetSection("Mail").GetValue("UserName") ?? string.Empty, Password = _configuration.GetSection("Mail").GetValue("Password") ?? string.Empty, EnableSsl = _configuration.GetSection("Mail").GetValue("EnableSsl") ?? false, - DisplayName = _configuration.GetSection("Mail").GetValue("DisplayName") ?? string.Empty + DisplayName = _configuration.GetSection("Mail").GetValue("DisplayName") ?? string.Empty, + Enabled = _configuration.GetSection("Mail").GetValue("Enabled") ?? false, }; return mailConfig; } diff --git a/EOM.TSHotelManagement.Infrastructure/Factory/RedisConfigFactory.cs b/EOM.TSHotelManagement.Infrastructure/Factory/RedisConfigFactory.cs index 981eeafaadc5f92b953104d26cce9ed66041c6e7..056ae5bfa52d175b37193be75039d81c6ece5752 100644 --- a/EOM.TSHotelManagement.Infrastructure/Factory/RedisConfigFactory.cs +++ b/EOM.TSHotelManagement.Infrastructure/Factory/RedisConfigFactory.cs @@ -24,7 +24,16 @@ namespace EOM.TSHotelManagement.Infrastructure var redisConfig = new RedisConfig { ConnectionString = redisSection.GetValue("ConnectionString"), - Enable = enable + Enable = enable, + DefaultDatabase = redisSection.GetValue("DefaultDatabase"), + ConnectTimeoutMs = redisSection.GetValue("ConnectTimeoutMs"), + AsyncTimeoutMs = redisSection.GetValue("AsyncTimeoutMs"), + SyncTimeoutMs = redisSection.GetValue("SyncTimeoutMs"), + KeepAliveSeconds = redisSection.GetValue("KeepAliveSeconds"), + ConnectRetry = redisSection.GetValue("ConnectRetry"), + ReconnectRetryBaseDelayMs = redisSection.GetValue("ReconnectRetryBaseDelayMs"), + OperationTimeoutMs = redisSection.GetValue("OperationTimeoutMs"), + FailureCooldownSeconds = redisSection.GetValue("FailureCooldownSeconds") }; return redisConfig; } diff --git a/EOM.TSHotelManagement.Migration/EntityBuilder.cs b/EOM.TSHotelManagement.Migration/EntityBuilder.cs index 97c460d66e9be526707281945cdb484d39cff22b..4393fadbfd22cc145ac44375a555168ea9f5f46f 100644 --- a/EOM.TSHotelManagement.Migration/EntityBuilder.cs +++ b/EOM.TSHotelManagement.Migration/EntityBuilder.cs @@ -34,6 +34,7 @@ namespace EOM.TSHotelManagement.Migration { typeof(Administrator), typeof(AdministratorType), + typeof(AdministratorPhoto), typeof(AppointmentNotice), typeof(AppointmentNoticeType), typeof(Asset), @@ -52,6 +53,7 @@ namespace EOM.TSHotelManagement.Migration typeof(Menu), typeof(Nation), typeof(NavBar), + typeof(UserFavoriteCollection), typeof(OperationLog), typeof(Position), typeof(PromotionContent), @@ -65,7 +67,6 @@ namespace EOM.TSHotelManagement.Migration typeof(SellThing), typeof(Spend), typeof(SupervisionStatistics), - typeof(SystemInformation), typeof(UserRole), typeof(VipLevelRule), typeof(RequestLog), @@ -87,11 +88,20 @@ namespace EOM.TSHotelManagement.Migration }, new Administrator { - Number = "1263785187301658678", + Number = "AD-202005060001", Account = "admin", Password = string.Empty, - Name = "Administrator", + Name = "超级管理员", Type = "Admin", + Address = "广东珠海", + DateOfBirth = DateOnly.FromDateTime(new DateTime(1990,1,1,0,0,0)), + EducationLevel = "E-000001", + EmailAddress = string.Empty, + Ethnicity = "N-000001", + Gender = 1, + IdCardNumber = "666", + IdCardType = 0, + PhoneNumber = "666", IsSuperAdmin = 1, IsDelete = 0, DataInsUsr = "System", @@ -483,6 +493,17 @@ namespace EOM.TSHotelManagement.Migration DataInsDate = DateTime.Now, }, new Menu // 36 + { + Key = "quartzjoblist", + Title = "Quartz任务列表", + Path = "/quartzjoblist", + Parent = 31, + Icon = "OrderedListOutlined", + IsDelete = 0, + DataInsUsr = "System", + DataInsDate = DateTime.Now, + }, + new Menu // 37 { Key = "my", Title = "我的", @@ -493,7 +514,7 @@ namespace EOM.TSHotelManagement.Migration DataInsUsr = "System", DataInsDate = DateTime.Now, }, - new Menu // 37 + new Menu // 38 { Key = "dashboard", Title = "仪表盘", @@ -504,7 +525,7 @@ namespace EOM.TSHotelManagement.Migration DataInsUsr = "System", DataInsDate = DateTime.Now, }, - new Menu // 38 + new Menu // 39 { Key = "promotioncontent", Title = "宣传联动内容", @@ -515,7 +536,7 @@ namespace EOM.TSHotelManagement.Migration DataInsUsr = "System", DataInsDate = DateTime.Now, }, - new Menu // 39 + new Menu // 40 { Key = "requestlog", Title = "请求日志", @@ -530,7 +551,7 @@ namespace EOM.TSHotelManagement.Migration { NavigationBarName = "客房管理", NavigationBarOrder = 1, - NavigationBarImage = null, + NavigationBarImage = string.Empty, NavigationBarEvent = "RoomManager_Event", IsDelete = 0, MarginLeft = 0, @@ -541,7 +562,7 @@ namespace EOM.TSHotelManagement.Migration { NavigationBarName = "客户管理", NavigationBarOrder = 2, - NavigationBarImage = null, + NavigationBarImage = string.Empty, NavigationBarEvent = "CustomerManager_Event", IsDelete = 0, MarginLeft = 120, @@ -552,7 +573,7 @@ namespace EOM.TSHotelManagement.Migration { NavigationBarName = "商品消费", NavigationBarOrder = 3, - NavigationBarImage = null, + NavigationBarImage = string.Empty, NavigationBarEvent = "SellManager_Event", IsDelete = 0, MarginLeft = 120, @@ -605,7 +626,7 @@ namespace EOM.TSHotelManagement.Migration new Employee { EmployeeId = "WK010", - EmployeeName = "阿杰", + Name = "阿杰", DateOfBirth = DateOnly.FromDateTime(new DateTime(1999,7,20,0,0,0)), Password = string.Empty, Department = "D-000001", @@ -625,10 +646,17 @@ namespace EOM.TSHotelManagement.Migration DataInsUsr = "System", DataInsDate = DateTime.Now }, - new SystemInformation + new UserFavoriteCollection { - UrlNumber = 1, - UrlAddress = "https://gitee.com/java-and-net/TopskyHotelManagerSystem/releases", + UserNumber = "WK010", + LoginType = "employee", + Account = "WK010", + FavoriteRoutesJson = "[\"/roommap\"]", + RouteCount = 1, + UpdatedAt = DateTime.UtcNow, + TriggeredBy = "seed", + DataInsUsr = "System", + DataInsDate = DateTime.Now }, new PromotionContent { @@ -666,251 +694,288 @@ namespace EOM.TSHotelManagement.Migration , // ===== Permission seeds synced from controller [RequirePermission] ===== - // 客户信息 - new Permission { PermissionNumber = "customer.dci", PermissionName = "删除客户信息", Module = "customer", Description = "删除客户信息", MenuKey = "customer", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "customer.ici", PermissionName = "添加客户信息", Module = "customer", Description = "添加客户信息", MenuKey = "customer", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "customer.scbi", PermissionName = "查询指定客户信息", Module = "customer", Description = "查询指定客户信息", MenuKey = "customer", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "customer.scs", PermissionName = "查询所有客户信息", Module = "customer", Description = "查询所有客户信息", MenuKey = "customer", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "customer.uci", PermissionName = "更新客户信息", Module = "customer", Description = "更新客户信息", MenuKey = "customer", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "customer.uctbcn", PermissionName = "更新会员等级", Module = "customer", Description = "更新会员等级", MenuKey = "customer", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - - // 客户消费信息 - new Permission { PermissionNumber = "customerspend.acs", PermissionName = "添加客户消费信息", Module = "customerspend", Description = "添加客户消费信息", MenuKey = "customerspend", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "customerspend.ssbrn", PermissionName = "查询房间消费信息", Module = "customerspend", Description = "查询房间消费信息", MenuKey = "customerspend", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "customerspend.ssia", PermissionName = "查询所有消费信息", Module = "customerspend", Description = "查询所有消费信息", MenuKey = "customerspend", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "customerspend.shsia", PermissionName = "查询客户历史消费信息", Module = "customerspend", Description = "查询客户历史消费信息", MenuKey = "customerspend", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "customerspend.sca", PermissionName = "查询消费总金额", Module = "customerspend", Description = "查询消费总金额", MenuKey = "customerspend", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "customerspend.ucs", PermissionName = "撤回客户消费信息", Module = "customerspend", Description = "撤回客户消费信息", MenuKey = "customerspend", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "customerspend.usi", PermissionName = "更新消费信息", Module = "customerspend", Description = "更新消费信息", MenuKey = "customerspend", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - - // 客户类型 - new Permission { PermissionNumber = "customertype.create", PermissionName = "新增客户类型", Module = "customertype", Description = "基础信息-客户类型-新增", MenuKey = "customertype", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "customertype.delete", PermissionName = "删除客户类型", Module = "customertype", Description = "基础信息-客户类型-删除", MenuKey = "customertype", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "customertype.update", PermissionName = "更新客户类型", Module = "customertype", Description = "基础信息-客户类型-更新", MenuKey = "customertype", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "customertype.view", PermissionName = "查询客户类型列表", Module = "customertype", Description = "基础信息-客户类型-查询列表", MenuKey = "customertype", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - + // Basic (基础信息管理) // 部门 - new Permission { PermissionNumber = "department.create", PermissionName = "新增部门", Module = "department", Description = "基础信息-部门-新增", MenuKey = "department", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "department.delete", PermissionName = "删除部门", Module = "department", Description = "基础信息-部门-删除", MenuKey = "department", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "department.update", PermissionName = "更新部门", Module = "department", Description = "基础信息-部门-更新", MenuKey = "department", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "department.view", PermissionName = "查询部门列表", Module = "department", Description = "基础信息-部门-查询列表", MenuKey = "department", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "department.create", PermissionName = "新增部门", Module = "basic", Description = "基础信息-部门-新增", MenuKey = "department", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "department.delete", PermissionName = "删除部门", Module = "basic", Description = "基础信息-部门-删除", MenuKey = "department", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "department.export", PermissionName = "导出部门", Module = "basic", Description = "基础信息-部门-导出列表", MenuKey = "department", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "department.update", PermissionName = "更新部门", Module = "basic", Description = "基础信息-部门-更新", MenuKey = "department", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "department.view", PermissionName = "查询部门列表", Module = "basic", Description = "基础信息-部门-查询列表", MenuKey = "department", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, // 民族 - new Permission { PermissionNumber = "nation.create", PermissionName = "新增民族", Module = "nation", Description = "基础信息-民族-新增", MenuKey = "nation", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "nation.delete", PermissionName = "删除民族", Module = "nation", Description = "基础信息-民族-删除", MenuKey = "nation", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "nation.update", PermissionName = "更新民族", Module = "nation", Description = "基础信息-民族-更新", MenuKey = "nation", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "nation.view", PermissionName = "查询民族列表", Module = "nation", Description = "基础信息-民族-查询列表", MenuKey = "nation", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "nation.create", PermissionName = "新增民族", Module = "basic", Description = "基础信息-民族-新增", MenuKey = "nation", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "nation.delete", PermissionName = "删除民族", Module = "basic", Description = "基础信息-民族-删除", MenuKey = "nation", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "nation.export", PermissionName = "导出民族", Module = "basic", Description = "基础信息-民族-导出列表", MenuKey = "nation", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "nation.update", PermissionName = "更新民族", Module = "basic", Description = "基础信息-民族-更新", MenuKey = "nation", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "nation.view", PermissionName = "查询民族列表", Module = "basic", Description = "基础信息-民族-查询列表", MenuKey = "nation", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, // 证件类型 - new Permission { PermissionNumber = "passport.create", PermissionName = "新增证件类型", Module = "passport", Description = "基础信息-证件类型-新增", MenuKey = "passport", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "passport.delete", PermissionName = "删除证件类型", Module = "passport", Description = "基础信息-证件类型-删除", MenuKey = "passport", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "passport.update", PermissionName = "更新证件类型", Module = "passport", Description = "基础信息-证件类型-更新", MenuKey = "passport", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "passport.view", PermissionName = "查询证件类型列表", Module = "passport", Description = "基础信息-证件类型-查询列表", MenuKey = "passport", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "passport.create", PermissionName = "新增证件类型", Module = "basic", Description = "基础信息-证件类型-新增", MenuKey = "passport", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "passport.delete", PermissionName = "删除证件类型", Module = "basic", Description = "基础信息-证件类型-删除", MenuKey = "passport", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "passport.export", PermissionName = "导出证件类型", Module = "basic", Description = "基础信息-证件类型-导出列表", MenuKey = "passport", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "passport.update", PermissionName = "更新证件类型", Module = "basic", Description = "基础信息-证件类型-更新", MenuKey = "passport", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "passport.view", PermissionName = "查询证件类型列表", Module = "basic", Description = "基础信息-证件类型-查询列表", MenuKey = "passport", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, // 职位 - new Permission { PermissionNumber = "position.create", PermissionName = "新增职位", Module = "position", Description = "基础信息-职位-新增", MenuKey = "position", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "position.delete", PermissionName = "删除职位", Module = "position", Description = "基础信息-职位-删除", MenuKey = "position", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "position.update", PermissionName = "更新职位", Module = "position", Description = "基础信息-职位-更新", MenuKey = "position", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "position.view", PermissionName = "查询职位列表", Module = "position", Description = "基础信息-职位-查询列表", MenuKey = "position", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "position.create", PermissionName = "新增职位", Module = "basic", Description = "基础信息-职位-新增", MenuKey = "position", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "position.delete", PermissionName = "删除职位", Module = "basic", Description = "基础信息-职位-删除", MenuKey = "position", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "position.export", PermissionName = "导出职位", Module = "basic", Description = "基础信息-职位-导出列表", MenuKey = "position", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "position.update", PermissionName = "更新职位", Module = "basic", Description = "基础信息-职位-更新", MenuKey = "position", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "position.view", PermissionName = "查询职位列表", Module = "basic", Description = "基础信息-职位-查询列表", MenuKey = "position", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, // 学历 - new Permission { PermissionNumber = "qualification.create", PermissionName = "新增学历", Module = "qualification", Description = "基础信息-学历-新增", MenuKey = "qualification", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "qualification.delete", PermissionName = "删除学历", Module = "qualification", Description = "基础信息-学历-删除", MenuKey = "qualification", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "qualification.update", PermissionName = "更新学历", Module = "qualification", Description = "基础信息-学历-更新", MenuKey = "qualification", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "qualification.view", PermissionName = "查询学历列表", Module = "qualification", Description = "基础信息-学历-查询列表", MenuKey = "qualification", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "qualification.create", PermissionName = "新增学历", Module = "basic", Description = "基础信息-学历-新增", MenuKey = "qualification", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "qualification.delete", PermissionName = "删除学历", Module = "basic", Description = "基础信息-学历-删除", MenuKey = "qualification", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "qualification.export", PermissionName = "导出学历", Module = "basic", Description = "基础信息-学历-导出列表", MenuKey = "qualification", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "qualification.update", PermissionName = "更新学历", Module = "basic", Description = "基础信息-学历-更新", MenuKey = "qualification", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "qualification.view", PermissionName = "查询学历列表", Module = "basic", Description = "基础信息-学历-查询列表", MenuKey = "qualification", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, - // 会员等级规则管理 - new Permission { PermissionNumber = "viplevel.addviprule", PermissionName = "添加会员等级规则", Module = "viplevel", Description = "添加会员等级规则", MenuKey = "viplevel", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "viplevel.delviprule", PermissionName = "删除会员等级规则", Module = "viplevel", Description = "删除会员等级规则", MenuKey = "viplevel", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "viplevel.svr", PermissionName = "查询会员等级规则", Module = "viplevel", Description = "查询会员等级规则", MenuKey = "viplevel", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "viplevel.svrlist", PermissionName = "查询会员等级规则列表", Module = "viplevel", Description = "查询会员等级规则列表", MenuKey = "viplevel", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "viplevel.updviprule", PermissionName = "更新会员等级规则", Module = "viplevel", Description = "更新会员等级规则", MenuKey = "viplevel", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - - // 仪表盘 - new Permission { PermissionNumber = "dashboard.bs", PermissionName = "获取业务统计信息", Module = "dashboard", Description = "获取业务统计信息", MenuKey = "dashboard", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "dashboard.hrs", PermissionName = "获取人事统计信息", Module = "dashboard", Description = "获取人事统计信息", MenuKey = "dashboard", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "dashboard.ls", PermissionName = "获取后勤统计信息", Module = "dashboard", Description = "获取后勤统计信息", MenuKey = "dashboard", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "dashboard.rs", PermissionName = "获取房间统计信息", Module = "dashboard", Description = "获取房间统计信息", MenuKey = "dashboard", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - - // 商品管理 - new Permission { PermissionNumber = "goodsmanagement.dst", PermissionName = "删除商品信息", Module = "goodsmanagement", Description = "删除商品信息", MenuKey = "goodsmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "goodsmanagement.ist", PermissionName = "添加商品", Module = "goodsmanagement", Description = "添加商品", MenuKey = "goodsmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "goodsmanagement.ssta", PermissionName = "查询所有商品", Module = "goodsmanagement", Description = "查询所有商品", MenuKey = "goodsmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "goodsmanagement.sstbnap", PermissionName = "根据商品名称和价格查询商品编号", Module = "goodsmanagement", Description = "根据商品名称和价格查询商品编号", MenuKey = "goodsmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "goodsmanagement.ust", PermissionName = "修改商品", Module = "goodsmanagement", Description = "修改商品", MenuKey = "goodsmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - - // 水电费信息管理 - new Permission { PermissionNumber = "hydroelectricinformation.demi", PermissionName = "删除水电费信息", Module = "hydroelectricinformation", Description = "删除水电费信息", MenuKey = "hydroelectricinformation", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "hydroelectricinformation.iemi", PermissionName = "添加水电费信息", Module = "hydroelectricinformation", Description = "添加水电费信息", MenuKey = "hydroelectricinformation", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "hydroelectricinformation.semi", PermissionName = "查询水电费信息", Module = "hydroelectricinformation", Description = "查询水电费信息", MenuKey = "hydroelectricinformation", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "hydroelectricinformation.uemi", PermissionName = "修改水电费信息", Module = "hydroelectricinformation", Description = "修改水电费信息", MenuKey = "hydroelectricinformation", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - + // 公告类型 + new Permission { PermissionNumber = "noticetype.create", PermissionName = "添加公告类型", Module = "basic", Description = "添加公告类型", MenuKey = "noticetype", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "noticetype.delete", PermissionName = "删除公告类型", Module = "basic", Description = "删除公告类型", MenuKey = "noticetype", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "noticetype.export", PermissionName = "导出公告类型", Module = "basic", Description = "导出公告类型列表", MenuKey = "noticetype", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "noticetype.update", PermissionName = "更新公告类型", Module = "basic", Description = "更新公告类型", MenuKey = "noticetype", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "noticetype.view", PermissionName = "查询所有公告类型", Module = "basic", Description = "查询所有公告类型", MenuKey = "noticetype", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + + // 宣传联动内容 + new Permission { PermissionNumber = "promotioncontent.apc", PermissionName = "添加宣传联动内容", Module = "basic", Description = "添加宣传联动内容", MenuKey = "promotioncontent", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "promotioncontent.dpc", PermissionName = "删除宣传联动内容", Module = "basic", Description = "删除宣传联动内容", MenuKey = "promotioncontent", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "promotioncontent.export", PermissionName = "导出宣传联动内容", Module = "basic", Description = "导出宣传联动内容列表", MenuKey = "promotioncontent", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "promotioncontent.spca", PermissionName = "查询所有宣传联动内容", Module = "basic", Description = "查询所有宣传联动内容", MenuKey = "promotioncontent", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "promotioncontent.spcs", PermissionName = "查询所有宣传联动内容(跑马灯)", Module = "basic", Description = "查询所有宣传联动内容(跑马灯)", MenuKey = "promotioncontent", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "promotioncontent.upc", PermissionName = "更新宣传联动内容", Module = "basic", Description = "更新宣传联动内容", MenuKey = "promotioncontent", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + + // Finance (财务信息管理) // 资产信息管理 - new Permission { PermissionNumber = "internalfinance.aai", PermissionName = "添加资产信息", Module = "internalfinance", Description = "添加资产信息", MenuKey = "internalfinance", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "internalfinance.dai", PermissionName = "删除资产信息", Module = "internalfinance", Description = "删除资产信息", MenuKey = "internalfinance", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "internalfinance.saia", PermissionName = "查询资产信息", Module = "internalfinance", Description = "查询资产信息", MenuKey = "internalfinance", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "internalfinance.uai", PermissionName = "更新资产信息", Module = "internalfinance", Description = "更新资产信息", MenuKey = "internalfinance", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - - // 菜单管理 - new Permission { PermissionNumber = "menumanagement.bma", PermissionName = "构建菜单树", Module = "menumanagement", Description = "构建菜单树", MenuKey = "menumanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "menumanagement.deletemenu", PermissionName = "删除菜单", Module = "menumanagement", Description = "删除菜单", MenuKey = "menumanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "menumanagement.insertmenu", PermissionName = "插入菜单", Module = "menumanagement", Description = "插入菜单", MenuKey = "menumanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "menumanagement.sma", PermissionName = "查询所有菜单信息", Module = "menumanagement", Description = "查询所有菜单信息", MenuKey = "menumanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "menumanagement.updatemenu", PermissionName = "更新菜单", Module = "menumanagement", Description = "更新菜单", MenuKey = "menumanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "internalfinance.aai", PermissionName = "添加资产信息", Module = "internalfinance", Description = "添加资产信息", MenuKey = "internalfinance", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "internalfinance.dai", PermissionName = "删除资产信息", Module = "internalfinance", Description = "删除资产信息", MenuKey = "internalfinance", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "internalfinance.export", PermissionName = "导出资产信息", Module = "internalfinance", Description = "导出资产信息列表", MenuKey = "internalfinance", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "internalfinance.saia", PermissionName = "查询资产信息", Module = "internalfinance", Description = "查询资产信息", MenuKey = "internalfinance", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "internalfinance.uai", PermissionName = "更新资产信息", Module = "internalfinance", Description = "更新资产信息", MenuKey = "internalfinance", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + // Nav Bar (导航栏管理) // 导航控件管理 - new Permission { PermissionNumber = "navbar.addnavbar", PermissionName = "添加导航控件", Module = "navbar", Description = "添加导航控件", MenuKey = "navbar", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "navbar.dn", PermissionName = "删除导航控件", Module = "navbar", Description = "删除导航控件", MenuKey = "navbar", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "navbar.navbarlist", PermissionName = "导航控件列表", Module = "navbar", Description = "导航控件列表", MenuKey = "navbar", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "navbar.un", PermissionName = "更新导航控件", Module = "navbar", Description = "更新导航控件", MenuKey = "navbar", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "navbar.addnavbar", PermissionName = "添加导航控件", Module = "client", Description = "添加导航控件", MenuKey = "navbar", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "navbar.dn", PermissionName = "删除导航控件", Module = "client", Description = "删除导航控件", MenuKey = "navbar", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "navbar.navbarlist", PermissionName = "导航控件列表", Module = "client", Description = "导航控件列表", MenuKey = "navbar", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "navbar.un", PermissionName = "更新导航控件", Module = "client", Description = "更新导航控件", MenuKey = "navbar", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, - // 公告类型 - new Permission { PermissionNumber = "noticetype.create", PermissionName = "添加公告类型", Module = "noticetype", Description = "添加公告类型", MenuKey = "noticetype", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "noticetype.delete", PermissionName = "删除公告类型", Module = "noticetype", Description = "删除公告类型", MenuKey = "noticetype", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "noticetype.update", PermissionName = "更新公告类型", Module = "noticetype", Description = "更新公告类型", MenuKey = "noticetype", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "noticetype.view", PermissionName = "查询所有公告类型", Module = "noticetype", Description = "查询所有公告类型", MenuKey = "noticetype", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - // 操作日志 - new Permission { PermissionNumber = "operationlog.delete", PermissionName = "删除时间范围的操作日志", Module = "operationlog", Description = "删除时间范围的操作日志", MenuKey = "operationlog", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "operationlog.view", PermissionName = "查询所有操作日志", Module = "operationlog", Description = "查询所有操作日志", MenuKey = "operationlog", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, + // Hydroelectricity (水电信息管理) + // 水电费信息管理 + new Permission { PermissionNumber = "hydroelectricinformation.demi", PermissionName = "删除水电费信息", Module = "hydroelectricity", Description = "删除水电费信息", MenuKey = "hydroelectricinformation", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "hydroelectricinformation.export", PermissionName = "导出水电费信息", Module = "hydroelectricity", Description = "导出水电费信息列表", MenuKey = "hydroelectricinformation", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "hydroelectricinformation.iemi", PermissionName = "添加水电费信息", Module = "hydroelectricity", Description = "添加水电费信息", MenuKey = "hydroelectricinformation", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "hydroelectricinformation.semi", PermissionName = "查询水电费信息", Module = "hydroelectricity", Description = "查询水电费信息", MenuKey = "hydroelectricinformation", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "hydroelectricinformation.uemi", PermissionName = "修改水电费信息", Module = "hydroelectricity", Description = "修改水电费信息", MenuKey = "hydroelectricinformation", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, - // 宣传联动内容 - new Permission { PermissionNumber = "promotioncontent.apc", PermissionName = "添加宣传联动内容", Module = "promotioncontent", Description = "添加宣传联动内容", MenuKey = "promotioncontent", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "promotioncontent.dpc", PermissionName = "删除宣传联动内容", Module = "promotioncontent", Description = "删除宣传联动内容", MenuKey = "promotioncontent", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "promotioncontent.spca", PermissionName = "查询所有宣传联动内容", Module = "promotioncontent", Description = "查询所有宣传联动内容", MenuKey = "promotioncontent", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "promotioncontent.spcs", PermissionName = "查询所有宣传联动内容(跑马灯)", Module = "promotioncontent", Description = "查询所有宣传联动内容(跑马灯)", MenuKey = "promotioncontent", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "promotioncontent.upc", PermissionName = "更新宣传联动内容", Module = "promotioncontent", Description = "更新宣传联动内容", MenuKey = "promotioncontent", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - // 请求日志 - new Permission { PermissionNumber = "requestlog.delete", PermissionName = "删除时间范围的请求日志", Module = "requestlog", Description = "删除时间范围的请求日志", MenuKey = "requestlog", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "requestlog.view", PermissionName = "查询所有请求日志", Module = "requestlog", Description = "查询所有请求日志", MenuKey = "requestlog", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, + // Supervision (监管统计管理) + // 监管统计信息管理 + new Permission { PermissionNumber = "supervisioninfo.dss", PermissionName = "删除监管统计信息", Module = "supervision", Description = "删除监管统计信息", MenuKey = "supervisioninfo", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "supervisioninfo.export", PermissionName = "导出监管统计信息", Module = "supervision", Description = "导出监管统计信息列表", MenuKey = "supervisioninfo", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "supervisioninfo.iss", PermissionName = "插入监管统计信息", Module = "supervision", Description = "插入监管统计信息", MenuKey = "supervisioninfo", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "supervisioninfo.sssa", PermissionName = "查询所有监管统计信息", Module = "supervision", Description = "查询所有监管统计信息", MenuKey = "supervisioninfo", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "supervisioninfo.uss", PermissionName = "更新监管统计信息", Module = "supervision", Description = "更新监管统计信息", MenuKey = "supervisioninfo", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + + // Room information (客房信息管理) + // 房间管理 + new Permission { PermissionNumber = "roommap.view", PermissionName = "房态图-查看", Module = "room", Description = "房态图一览-查看", MenuKey = "roommap", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.crbr", PermissionName = "根据预约信息办理入住", Module = "room", Description = "根据预约信息办理入住", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.cr", PermissionName = "退房操作", Module = "room", Description = "退房操作", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.dbrn", PermissionName = "根据房间编号查询截止到今天住了多少天", Module = "room", Description = "根据房间编号查询截止到今天住了多少天", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.deleteroom", PermissionName = "删除房间", Module = "room", Description = "删除房间", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.export", PermissionName = "导出房间信息", Module = "room", Description = "导出房间信息列表", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.insertroom", PermissionName = "添加房间", Module = "room", Description = "添加房间", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.scura", PermissionName = "根据房间状态来查询可使用的房间", Module = "room", Description = "根据房间状态来查询可使用的房间", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.scurabrs", PermissionName = "查询可入住房间数量", Module = "room", Description = "查询可入住房间数量", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.sfrabrs", PermissionName = "查询维修房数量", Module = "room", Description = "查询维修房数量", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.sncrabrs", PermissionName = "查询脏房数量", Module = "room", Description = "查询脏房数量", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.snurabrs", PermissionName = "查询已入住房间数量", Module = "room", Description = "查询已入住房间数量", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.srrabrs", PermissionName = "查询预约房数量", Module = "room", Description = "查询预约房数量", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.sra", PermissionName = "获取所有房间信息", Module = "room", Description = "获取所有房间信息", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.srbrn", PermissionName = "根据房间编号查询房间信息", Module = "room", Description = "根据房间编号查询房间信息", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.srbrp", PermissionName = "根据房间编号查询房间价格", Module = "room", Description = "根据房间编号查询房间价格", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.srbrs", PermissionName = "根据房间状态获取相应状态的房间信息", Module = "room", Description = "根据房间状态获取相应状态的房间信息", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.srbtn", PermissionName = "获取房间分区的信息", Module = "room", Description = "获取房间分区的信息", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.tr", PermissionName = "转房操作", Module = "room", Description = "转房操作", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.updateroom", PermissionName = "更新房间", Module = "room", Description = "更新房间", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.uri", PermissionName = "根据房间编号修改房间信息(入住)", Module = "room", Description = "根据房间编号修改房间信息(入住)", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.uriwr", PermissionName = "根据房间编号修改房间信息(预约)", Module = "room", Description = "根据房间编号修改房间信息(预约)", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roommanagement.ursbrn", PermissionName = "根据房间编号更改房间状态", Module = "room", Description = "根据房间编号更改房间状态", MenuKey = "roommanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + // 房间配置管理 + new Permission { PermissionNumber = "roomconfig.drt", PermissionName = "删除房间配置", Module = "room", Description = "删除房间配置", MenuKey = "roomconfig", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roomconfig.export", PermissionName = "导出房间配置", Module = "room", Description = "导出房间配置列表", MenuKey = "roomconfig", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roomconfig.irt", PermissionName = "添加房间配置", Module = "room", Description = "添加房间配置", MenuKey = "roomconfig", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roomconfig.srtbrn", PermissionName = "根据房间编号查询房间类型名称", Module = "room", Description = "根据房间编号查询房间类型名称", MenuKey = "roomconfig", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roomconfig.srta", PermissionName = "获取所有房间类型", Module = "room", Description = "获取所有房间类型", MenuKey = "roomconfig", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "roomconfig.urt", PermissionName = "更新房间配置", Module = "room", Description = "更新房间配置", MenuKey = "roomconfig", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, // 预约信息管理 - new Permission { PermissionNumber = "resermanagement.dri", PermissionName = "删除预约信息", Module = "resermanagement", Description = "删除预约信息", MenuKey = "resermanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "resermanagement.iri", PermissionName = "添加预约信息", Module = "resermanagement", Description = "添加预约信息", MenuKey = "resermanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "resermanagement.sra", PermissionName = "获取所有预约信息", Module = "resermanagement", Description = "获取所有预约信息", MenuKey = "resermanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "resermanagement.sribrn", PermissionName = "根据房间编号获取预约信息", Module = "resermanagement", Description = "根据房间编号获取预约信息", MenuKey = "resermanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "resermanagement.srta", PermissionName = "查询所有预约类型", Module = "resermanagement", Description = "查询所有预约类型", MenuKey = "resermanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "resermanagement.uri", PermissionName = "更新预约信息", Module = "resermanagement", Description = "更新预约信息", MenuKey = "resermanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "resermanagement.dri", PermissionName = "删除预约信息", Module = "room", Description = "删除预约信息", MenuKey = "resermanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "resermanagement.export", PermissionName = "导出预约信息", Module = "room", Description = "导出预约信息列表", MenuKey = "resermanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "resermanagement.iri", PermissionName = "添加预约信息", Module = "room", Description = "添加预约信息", MenuKey = "resermanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "resermanagement.sra", PermissionName = "获取所有预约信息", Module = "room", Description = "获取所有预约信息", MenuKey = "resermanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "resermanagement.sribrn", PermissionName = "根据房间编号获取预约信息", Module = "room", Description = "根据房间编号获取预约信息", MenuKey = "resermanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "resermanagement.srta", PermissionName = "查询所有预约类型", Module = "room", Description = "查询所有预约类型", MenuKey = "resermanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "resermanagement.uri", PermissionName = "更新预约信息", Module = "room", Description = "更新预约信息", MenuKey = "resermanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, - // 房间配置管理 - new Permission { PermissionNumber = "roomconfig.drt", PermissionName = "删除房间配置", Module = "roomconfig", Description = "删除房间配置", MenuKey = "roomconfig", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roomconfig.irt", PermissionName = "添加房间配置", Module = "roomconfig", Description = "添加房间配置", MenuKey = "roomconfig", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roomconfig.srtbrn", PermissionName = "根据房间编号查询房间类型名称", Module = "roomconfig", Description = "根据房间编号查询房间类型名称", MenuKey = "roomconfig", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roomconfig.srta", PermissionName = "获取所有房间类型", Module = "roomconfig", Description = "获取所有房间类型", MenuKey = "roomconfig", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roomconfig.urt", PermissionName = "更新房间配置", Module = "roomconfig", Description = "更新房间配置", MenuKey = "roomconfig", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - // 房间管理 - new Permission { PermissionNumber = "roommanagement.crbr", PermissionName = "根据预约信息办理入住", Module = "roommanagement", Description = "根据预约信息办理入住", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.cr", PermissionName = "退房操作", Module = "roommanagement", Description = "退房操作", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.dbrn", PermissionName = "根据房间编号查询截止到今天住了多少天", Module = "roommanagement", Description = "根据房间编号查询截止到今天住了多少天", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.deleteroom", PermissionName = "删除房间", Module = "roommanagement", Description = "删除房间", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.insertroom", PermissionName = "添加房间", Module = "roommanagement", Description = "添加房间", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.scura", PermissionName = "根据房间状态来查询可使用的房间", Module = "roommanagement", Description = "根据房间状态来查询可使用的房间", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.scurabrs", PermissionName = "查询可入住房间数量", Module = "roommanagement", Description = "查询可入住房间数量", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.sfrabrs", PermissionName = "查询维修房数量", Module = "roommanagement", Description = "查询维修房数量", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.sncrabrs", PermissionName = "查询脏房数量", Module = "roommanagement", Description = "查询脏房数量", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.snurabrs", PermissionName = "查询已入住房间数量", Module = "roommanagement", Description = "查询已入住房间数量", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.srrabrs", PermissionName = "查询预约房数量", Module = "roommanagement", Description = "查询预约房数量", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.sra", PermissionName = "获取所有房间信息", Module = "roommanagement", Description = "获取所有房间信息", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.srbrn", PermissionName = "根据房间编号查询房间信息", Module = "roommanagement", Description = "根据房间编号查询房间信息", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.srbrp", PermissionName = "根据房间编号查询房间价格", Module = "roommanagement", Description = "根据房间编号查询房间价格", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.srbrs", PermissionName = "根据房间状态获取相应状态的房间信息", Module = "roommanagement", Description = "根据房间状态获取相应状态的房间信息", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.srbtn", PermissionName = "获取房间分区的信息", Module = "roommanagement", Description = "获取房间分区的信息", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.tr", PermissionName = "转房操作", Module = "roommanagement", Description = "转房操作", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.updateroom", PermissionName = "更新房间", Module = "roommanagement", Description = "更新房间", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.uri", PermissionName = "根据房间编号修改房间信息(入住)", Module = "roommanagement", Description = "根据房间编号修改房间信息(入住)", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.uriwr", PermissionName = "根据房间编号修改房间信息(预约)", Module = "roommanagement", Description = "根据房间编号修改房间信息(预约)", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "roommanagement.ursbrn", PermissionName = "根据房间编号更改房间状态", Module = "roommanagement", Description = "根据房间编号更改房间状态", MenuKey = "roommanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, + // Customer management (客户管理) + // 会员等级规则管理 + new Permission { PermissionNumber = "viplevel.addviprule", PermissionName = "添加会员等级规则", Module = "customer", Description = "添加会员等级规则", MenuKey = "viplevel", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "viplevel.delviprule", PermissionName = "删除会员等级规则", Module = "customer", Description = "删除会员等级规则", MenuKey = "viplevel", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "viplevel.export", PermissionName = "导出会员等级规则", Module = "customer", Description = "导出会员等级规则列表", MenuKey = "viplevel", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "viplevel.svr", PermissionName = "查询会员等级规则", Module = "customer", Description = "查询会员等级规则", MenuKey = "viplevel", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "viplevel.svrlist", PermissionName = "查询会员等级规则列表", Module = "customer", Description = "查询会员等级规则列表", MenuKey = "viplevel", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "viplevel.updviprule", PermissionName = "更新会员等级规则", Module = "customer", Description = "更新会员等级规则", MenuKey = "viplevel", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + // 客户信息 + new Permission { PermissionNumber = "customer.dci", PermissionName = "删除客户信息", Module = "customer", Description = "删除客户信息", MenuKey = "customer", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "customer.export", PermissionName = "导出客户信息", Module = "customer", Description = "导出客户信息列表", MenuKey = "customer", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "customer.ici", PermissionName = "添加客户信息", Module = "customer", Description = "添加客户信息", MenuKey = "customer", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "customer.scbi", PermissionName = "查询指定客户信息", Module = "customer", Description = "查询指定客户信息", MenuKey = "customer", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "customer.scs", PermissionName = "查询所有客户信息", Module = "customer", Description = "查询所有客户信息", MenuKey = "customer", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "customer.uci", PermissionName = "更新客户信息", Module = "customer", Description = "更新客户信息", MenuKey = "customer", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "customer.uctbcn", PermissionName = "更新会员等级", Module = "customer", Description = "更新会员等级", MenuKey = "customer", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + // 客户消费信息 + new Permission { PermissionNumber = "customerspend.acs", PermissionName = "添加客户消费信息", Module = "customer", Description = "添加客户消费信息", MenuKey = "customerspend", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "customerspend.export", PermissionName = "导出客户消费信息", Module = "customer", Description = "导出客户消费信息列表", MenuKey = "customerspend", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "customerspend.ssbrn", PermissionName = "查询房间消费信息", Module = "customer", Description = "查询房间消费信息", MenuKey = "customerspend", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "customerspend.ssia", PermissionName = "查询所有消费信息", Module = "customer", Description = "查询所有消费信息", MenuKey = "customerspend", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "customerspend.shsia", PermissionName = "查询客户历史消费信息", Module = "customer", Description = "查询客户历史消费信息", MenuKey = "customerspend", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "customerspend.sca", PermissionName = "查询消费总金额", Module = "customer", Description = "查询消费总金额", MenuKey = "customerspend", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "customerspend.ucs", PermissionName = "撤回客户消费信息", Module = "customer", Description = "撤回客户消费信息", MenuKey = "customerspend", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "customerspend.usi", PermissionName = "更新消费信息", Module = "customer", Description = "更新消费信息", MenuKey = "customerspend", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + // 客户类型 + new Permission { PermissionNumber = "customertype.create", PermissionName = "新增客户类型", Module = "customer", Description = "基础信息-客户类型-新增", MenuKey = "customertype", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "customertype.delete", PermissionName = "删除客户类型", Module = "customer", Description = "基础信息-客户类型-删除", MenuKey = "customertype", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "customertype.export", PermissionName = "导出客户类型", Module = "customer", Description = "基础信息-客户类型-导出列表", MenuKey = "customertype", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "customertype.update", PermissionName = "更新客户类型", Module = "customer", Description = "基础信息-客户类型-更新", MenuKey = "customertype", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "customertype.view", PermissionName = "查询客户类型列表", Module = "customer", Description = "基础信息-客户类型-查询列表", MenuKey = "customertype", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + + // Human resource (酒店人事管理) // 员工管理 - new Permission { PermissionNumber = "staffmanagement.ae", PermissionName = "添加员工信息", Module = "staffmanagement", Description = "添加员工信息", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "staffmanagement.mea", PermissionName = "员工账号禁/启用", Module = "staffmanagement", Description = "员工账号禁/启用", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "staffmanagement.reap", PermissionName = "重置员工账号密码", Module = "staffmanagement", Description = "重置员工账号密码", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "staffmanagement.sea", PermissionName = "获取所有工作人员信息", Module = "staffmanagement", Description = "获取所有工作人员信息", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "staffmanagement.seibei", PermissionName = "根据登录名称查询员工信息", Module = "staffmanagement", Description = "根据登录名称查询员工信息", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "staffmanagement.ue", PermissionName = "修改员工信息", Module = "staffmanagement", Description = "修改员工信息", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - + new Permission { PermissionNumber = "staffmanagement.ae", PermissionName = "添加员工信息", Module = "humanresource", Description = "添加员工信息", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.export", PermissionName = "导出员工信息", Module = "humanresource", Description = "导出员工信息列表", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.mea", PermissionName = "员工账号禁/启用", Module = "humanresource", Description = "员工账号禁/启用", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.reap", PermissionName = "重置员工账号密码", Module = "humanresource", Description = "重置员工账号密码", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.sea", PermissionName = "获取所有工作人员信息", Module = "humanresource", Description = "获取所有工作人员信息", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.seibei", PermissionName = "根据登录名称查询员工信息", Module = "humanresource", Description = "根据登录名称查询员工信息", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.ue", PermissionName = "修改员工信息", Module = "humanresource", Description = "修改员工信息", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, // 员工履历管理 - new Permission { PermissionNumber = "staffmanagement.shbei", PermissionName = "根据工号查询履历信息", Module = "staffmanagement", Description = "根据工号查询履历信息", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "staffmanagement.ahbei", PermissionName = "根据工号添加员工履历", Module = "staffmanagement", Description = "根据工号添加员工履历", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - + new Permission { PermissionNumber = "staffmanagement.shbei", PermissionName = "根据工号查询履历信息", Module = "humanresource", Description = "根据工号查询履历信息", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.ahbei", PermissionName = "根据工号添加员工履历", Module = "humanresource", Description = "根据工号添加员工履历", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, // 员工打卡管理 - new Permission { PermissionNumber = "staffmanagement.stcfobwn", PermissionName = "查询今天员工是否已签到", Module = "staffmanagement", Description = "查询今天员工是否已签到", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "staffmanagement.swcdsbei", PermissionName = "查询员工签到天数", Module = "staffmanagement", Description = "查询员工签到天数", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "staffmanagement.acfo", PermissionName = "添加员工打卡数据", Module = "staffmanagement", Description = "添加员工打卡数据", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "staffmanagement.scfobei", PermissionName = "根据员工编号查询其所有的打卡记录", Module = "staffmanagement", Description = "根据员工编号查询其所有的打卡记录", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - + new Permission { PermissionNumber = "staffmanagement.stcfobwn", PermissionName = "查询今天员工是否已签到", Module = "humanresource", Description = "查询今天员工是否已签到", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.swcdsbei", PermissionName = "查询员工签到天数", Module = "humanresource", Description = "查询员工签到天数", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.acfo", PermissionName = "添加员工打卡数据", Module = "humanresource", Description = "添加员工打卡数据", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.scfobei", PermissionName = "根据员工编号查询其所有的打卡记录", Module = "humanresource", Description = "根据员工编号查询其所有的打卡记录", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, // 员工照片管理 - new Permission { PermissionNumber = "staffmanagement.ueap", PermissionName = "修改员工账号密码", Module = "staffmanagement", Description = "修改员工账号密码", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "staffmanagement.uwp", PermissionName = "更新员工照片", Module = "staffmanagement", Description = "更新员工照片", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "staffmanagement.dwp", PermissionName = "删除员工照片", Module = "staffmanagement", Description = "删除员工照片", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "staffmanagement.iwp", PermissionName = "添加员工照片", Module = "staffmanagement", Description = "添加员工照片", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "staffmanagement.ep", PermissionName = "查询员工照片", Module = "staffmanagement", Description = "查询员工照片", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - + new Permission { PermissionNumber = "staffmanagement.ueap", PermissionName = "修改员工账号密码", Module = "humanresource", Description = "修改员工账号密码", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.uwp", PermissionName = "更新员工照片", Module = "humanresource", Description = "更新员工照片", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.dwp", PermissionName = "删除员工照片", Module = "humanresource", Description = "删除员工照片", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.iwp", PermissionName = "添加员工照片", Module = "humanresource", Description = "添加员工照片", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.ep", PermissionName = "查询员工照片", Module = "humanresource", Description = "查询员工照片", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, // 员工两步验证管理 - new Permission { PermissionNumber = "staffmanagement.dtf", PermissionName = "关闭当前员工账号 2FA", Module = "staffmanagement", Description = "关闭当前员工账号 2FA", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "staffmanagement.etf", PermissionName = "启用当前员工账号 2FA", Module = "staffmanagement", Description = "启用当前员工账号 2FA", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "staffmanagement.gtfs", PermissionName = "生成当前员工账号的 2FA 绑定信息", Module = "staffmanagement", Description = "生成当前员工账号的 2FA 绑定信息", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "staffmanagement.gtfse", PermissionName = "获取当前员工账号的 2FA 状态", Module = "staffmanagement", Description = "获取当前员工账号的 2FA 状态", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "staffmanagement.rtfrc", PermissionName = "重置当前员工账号恢复备用码", Module = "staffmanagement", Description = "重置当前员工账号恢复备用码", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.dtf", PermissionName = "关闭当前员工账号 2FA", Module = "humanresource", Description = "关闭当前员工账号 2FA", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.etf", PermissionName = "启用当前员工账号 2FA", Module = "humanresource", Description = "启用当前员工账号 2FA", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.gtfs", PermissionName = "生成当前员工账号的 2FA 绑定信息", Module = "humanresource", Description = "生成当前员工账号的 2FA 绑定信息", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.gtfse", PermissionName = "获取当前员工账号的 2FA 状态", Module = "humanresource", Description = "获取当前员工账号的 2FA 状态", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "staffmanagement.rtfrc", PermissionName = "重置当前员工账号恢复备用码", Module = "humanresource", Description = "重置当前员工账号恢复备用码", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, - // 监管统计信息管理 - new Permission { PermissionNumber = "supervisioninfo.dss", PermissionName = "删除监管统计信息", Module = "supervisioninfo", Description = "删除监管统计信息", MenuKey = "supervisioninfo", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "supervisioninfo.iss", PermissionName = "插入监管统计信息", Module = "supervisioninfo", Description = "插入监管统计信息", MenuKey = "supervisioninfo", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "supervisioninfo.sssa", PermissionName = "查询所有监管统计信息", Module = "supervisioninfo", Description = "查询所有监管统计信息", MenuKey = "supervisioninfo", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "supervisioninfo.uss", PermissionName = "更新监管统计信息", Module = "supervisioninfo", Description = "更新监管统计信息", MenuKey = "supervisioninfo", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, + + // Material management (酒店物资管理) + // 商品管理 + new Permission { PermissionNumber = "goodsmanagement.dst", PermissionName = "删除商品信息", Module = "material", Description = "删除商品信息", MenuKey = "goodsmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "goodsmanagement.export", PermissionName = "导出商品信息", Module = "material", Description = "导出商品信息列表", MenuKey = "goodsmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "goodsmanagement.ist", PermissionName = "添加商品", Module = "material", Description = "添加商品", MenuKey = "goodsmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "goodsmanagement.ssta", PermissionName = "查询所有商品", Module = "material", Description = "查询所有商品", MenuKey = "goodsmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "goodsmanagement.sstbnap", PermissionName = "根据商品名称和价格查询商品编号", Module = "material", Description = "根据商品名称和价格查询商品编号", MenuKey = "goodsmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "goodsmanagement.ust", PermissionName = "修改商品", Module = "material", Description = "修改商品", MenuKey = "goodsmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, - // 管理员管理 - new Permission { PermissionNumber = "system:admin:addadmin", PermissionName = "添加管理员", Module = "system", Description = "添加管理员", MenuKey = "administratormanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:admin:deladmin", PermissionName = "删除管理员", Module = "system", Description = "删除管理员", MenuKey = "administratormanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:admin:gaal", PermissionName = "获取所有管理员列表", Module = "system", Description = "获取所有管理员列表", MenuKey = "administratormanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:admin:updadmin", PermissionName = "更新管理员", Module = "system", Description = "更新管理员", MenuKey = "administratormanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - // 管理员类型管理 - new Permission { PermissionNumber = "system:admintype:aat", PermissionName = "添加管理员类型", Module = "system", Description = "添加管理员类型", MenuKey = "admintypemanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:admintype:dat", PermissionName = "删除管理员类型", Module = "system", Description = "删除管理员类型", MenuKey = "admintypemanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:admintype:gaat", PermissionName = "获取所有管理员类型", Module = "system", Description = "获取所有管理员类型", MenuKey = "admintypemanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:admintype:uat", PermissionName = "更新管理员类型", Module = "system", Description = "更新管理员类型", MenuKey = "admintypemanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, + // Operation management (行为操作管理) + // 操作日志 + new Permission { PermissionNumber = "operationlog.delete", PermissionName = "删除时间范围的操作日志", Module = "operation", Description = "删除时间范围的操作日志", MenuKey = "operationlog", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "operationlog.export", PermissionName = "导出操作日志", Module = "operation", Description = "导出操作日志列表", MenuKey = "operationlog", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "operationlog.view", PermissionName = "查询所有操作日志", Module = "operation", Description = "查询所有操作日志", MenuKey = "operationlog", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + // 请求日志 + new Permission { PermissionNumber = "requestlog.delete", PermissionName = "删除时间范围的请求日志", Module = "operation", Description = "删除时间范围的请求日志", MenuKey = "requestlog", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "requestlog.export", PermissionName = "导出请求日志", Module = "operation", Description = "导出请求日志列表", MenuKey = "requestlog", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "requestlog.view", PermissionName = "查询所有请求日志", Module = "operation", Description = "查询所有请求日志", MenuKey = "requestlog", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + + // System management (系统管理) + // 管理员管理 + new Permission { PermissionNumber = "system:admin:addadmin", PermissionName = "添加管理员", Module = "system", Description = "添加管理员", MenuKey = "administratormanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:admin:deladmin", PermissionName = "删除管理员", Module = "system", Description = "删除管理员", MenuKey = "administratormanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:admin:export", PermissionName = "导出管理员", Module = "system", Description = "导出管理员列表", MenuKey = "administratormanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:admin:gaal", PermissionName = "获取所有管理员列表", Module = "system", Description = "获取所有管理员列表", MenuKey = "administratormanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:admin:updadmin", PermissionName = "更新管理员", Module = "system", Description = "更新管理员", MenuKey = "administratormanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + // 管理员类型管理 + new Permission { PermissionNumber = "system:admintype:aat", PermissionName = "添加管理员类型", Module = "system", Description = "添加管理员类型", MenuKey = "admintypemanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:admintype:dat", PermissionName = "删除管理员类型", Module = "system", Description = "删除管理员类型", MenuKey = "admintypemanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:admintype:export", PermissionName = "导出管理员类型", Module = "system", Description = "导出管理员类型列表", MenuKey = "admintypemanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:admintype:gaat", PermissionName = "获取所有管理员类型", Module = "system", Description = "获取所有管理员类型", MenuKey = "admintypemanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:admintype:uat", PermissionName = "更新管理员类型", Module = "system", Description = "更新管理员类型", MenuKey = "admintypemanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, // 管理员两步验证管理 - new Permission { PermissionNumber = "system:admin:gtfs", PermissionName = "获取当前管理员账号的 2FA 状态", Module = "system", Description = "获取当前管理员账号的 2FA 状态", MenuKey = "administratormanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:admin:dtf", PermissionName = "关闭当前管理员账号 2FA", Module = "system", Description = "关闭当前管理员账号 2FA", MenuKey = "administratormanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:admin:etf", PermissionName = "启用当前管理员账号 2FA", Module = "system", Description = "启用当前管理员账号 2FA", MenuKey = "administratormanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:admin:gtfsu", PermissionName = "生成当前管理员账号的 2FA 绑定信息", Module = "system", Description = "生成当前管理员账号的 2FA 绑定信息", MenuKey = "administratormanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:admin:rtfrc", PermissionName = "重置当前管理员账号恢复备用码", Module = "system", Description = "重置当前管理员账号恢复备用码", MenuKey = "administratormanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - + new Permission { PermissionNumber = "system:admin:gtfs", PermissionName = "获取当前管理员账号的 2FA 状态", Module = "system", Description = "获取当前管理员账号的 2FA 状态", MenuKey = "administratormanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:admin:dtf", PermissionName = "关闭当前管理员账号 2FA", Module = "system", Description = "关闭当前管理员账号 2FA", MenuKey = "administratormanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:admin:etf", PermissionName = "启用当前管理员账号 2FA", Module = "system", Description = "启用当前管理员账号 2FA", MenuKey = "administratormanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:admin:gtfsu", PermissionName = "生成当前管理员账号的 2FA 绑定信息", Module = "system", Description = "生成当前管理员账号的 2FA 绑定信息", MenuKey = "administratormanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:admin:rtfrc", PermissionName = "重置当前管理员账号恢复备用码", Module = "system", Description = "重置当前管理员账号恢复备用码", MenuKey = "administratormanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, // 角色管理 - new Permission { PermissionNumber = "system:role:aru", PermissionName = "为角色分配管理员(全量覆盖)", Module = "system", Description = "为角色分配管理员(全量覆盖)", MenuKey = "rolemanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:role:deleterole", PermissionName = "删除角色", Module = "system", Description = "删除角色", MenuKey = "rolemanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:role:grp", PermissionName = "为角色授予权限(全量覆盖)", Module = "system", Description = "为角色授予权限(全量覆盖)", MenuKey = "rolemanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:role:insertrole", PermissionName = "添加角色", Module = "system", Description = "添加角色", MenuKey = "rolemanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:role:rrp", PermissionName = "读取指定角色已授予的权限编码集合", Module = "system", Description = "读取指定角色已授予的权限编码集合", MenuKey = "rolemanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:role:rru", PermissionName = "读取隶属于指定角色的管理员用户编码集合", Module = "system", Description = "读取隶属于指定角色的管理员用户编码集合", MenuKey = "rolemanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:role:srl", PermissionName = "查询角色列表", Module = "system", Description = "查询角色列表", MenuKey = "rolemanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:role:updaterole", PermissionName = "更新角色", Module = "system", Description = "更新角色", MenuKey = "rolemanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:role:aru", PermissionName = "为角色分配管理员(全量覆盖)", Module = "system", Description = "为角色分配管理员(全量覆盖)", MenuKey = "rolemanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:role:deleterole", PermissionName = "删除角色", Module = "system", Description = "删除角色", MenuKey = "rolemanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:role:export", PermissionName = "导出角色", Module = "system", Description = "导出角色列表", MenuKey = "rolemanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:role:grp", PermissionName = "为角色授予权限(全量覆盖)", Module = "system", Description = "为角色授予权限(全量覆盖)", MenuKey = "rolemanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:role:insertrole", PermissionName = "添加角色", Module = "system", Description = "添加角色", MenuKey = "rolemanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:role:rrp", PermissionName = "读取指定角色已授予的权限编码集合", Module = "system", Description = "读取指定角色已授予的权限编码集合", MenuKey = "rolemanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:role:rrg", PermissionName = "读取指定角色菜单和权限授权(菜单与权限独立)", Module = "system", Description = "读取指定角色菜单和权限授权(菜单与权限独立)", MenuKey = "rolemanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:role:rru", PermissionName = "读取隶属于指定角色的管理员用户编码集合", Module = "system", Description = "读取隶属于指定角色的管理员用户编码集合", MenuKey = "rolemanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:role:srl", PermissionName = "查询角色列表", Module = "system", Description = "查询角色列表", MenuKey = "rolemanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:role:updaterole", PermissionName = "更新角色", Module = "system", Description = "更新角色", MenuKey = "rolemanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + // 菜单管理 + new Permission { PermissionNumber = "menumanagement.bma", PermissionName = "构建菜单树", Module = "system", Description = "构建菜单树", MenuKey = "menumanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "menumanagement.deletemenu", PermissionName = "删除菜单", Module = "system", Description = "删除菜单", MenuKey = "menumanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "menumanagement.export", PermissionName = "导出菜单", Module = "system", Description = "导出菜单列表", MenuKey = "menumanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "menumanagement.insertmenu", PermissionName = "插入菜单", Module = "system", Description = "插入菜单", MenuKey = "menumanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "menumanagement.sma", PermissionName = "查询所有菜单信息", Module = "system", Description = "查询所有菜单信息", MenuKey = "menumanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "menumanagement.updatemenu", PermissionName = "更新菜单", Module = "system", Description = "更新菜单", MenuKey = "menumanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:quartzjob:export", PermissionName = "导出Quartz任务", Module = "system", Description = "导出Quartz任务列表", MenuKey = "quartzjoblist", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, - // 管理员-角色权限管理(网页端) - new Permission { PermissionNumber = "system:user:admin.rudp", PermissionName = "读取指定用户的“直接权限”", Module = "system", Description = "读取指定用户的“直接权限”", MenuKey = "administratormanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:user:admin.rurp", PermissionName = "读取指定用户的“角色-权限”明细", Module = "system", Description = "读取指定用户的“角色-权限”明细", MenuKey = "administratormanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:user:admin.rur", PermissionName = "读取指定用户已分配的角色编码集合", Module = "system", Description = "读取指定用户已分配的角色编码集合", MenuKey = "administratormanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:user:admin:aup", PermissionName = "为指定用户分配“直接权限”", Module = "system", Description = "为指定用户分配“直接权限”", MenuKey = "administratormanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:user:admin:aur", PermissionName = "为用户分配角色(全量覆盖)", Module = "system", Description = "为用户分配角色(全量覆盖)", MenuKey = "administratormanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:user:assign.spl", PermissionName = "查询权限列表(支持条件过滤与分页/忽略分页)", Module = "system", Description = "查询权限列表(支持条件过滤与分页/忽略分页)", MenuKey = "administratormanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - // 客户-角色权限管理(网页端) - new Permission { PermissionNumber = "system:user:customer.rudp", PermissionName = "读取客户“直接权限”权限编码集合", Module = "system", Description = "读取客户“直接权限”权限编码集合", MenuKey = "customer", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:user:customer.rurp", PermissionName = "读取客户“角色-权限”明细", Module = "system", Description = "读取客户“角色-权限”明细", MenuKey = "customer", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:user:customer.rur", PermissionName = "读取客户已分配的角色编码集合", Module = "system", Description = "读取客户已分配的角色编码集合", MenuKey = "customer", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:user:customer:aup", PermissionName = "为客户分配“直接权限”", Module = "system", Description = "为客户分配“直接权限”", MenuKey = "customer", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:user:customer:aur", PermissionName = "为客户分配角色(全量覆盖)", Module = "system", Description = "为客户分配角色(全量覆盖)", MenuKey = "customer", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, + // 主页 + // 仪表盘 + new Permission { PermissionNumber = "dashboard.view", PermissionName = "仪表盘-查看", Module = "home", Description = "仪表盘-查看", MenuKey = "dashboard", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "home.view", PermissionName = "首页-查看", Module = "home", Description = "首页-查看", MenuKey = "home", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "dashboard.bs", PermissionName = "获取业务统计信息", Module = "dashboard", Description = "获取业务统计信息", MenuKey = "dashboard", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "dashboard.hrs", PermissionName = "获取人事统计信息", Module = "dashboard", Description = "获取人事统计信息", MenuKey = "dashboard", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "dashboard.ls", PermissionName = "获取后勤统计信息", Module = "dashboard", Description = "获取后勤统计信息", MenuKey = "dashboard", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "dashboard.rs", PermissionName = "获取房间统计信息", Module = "dashboard", Description = "获取房间统计信息", MenuKey = "dashboard", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + + // 权限分配 + // 管理员-角色权限管理(网页端) + new Permission { PermissionNumber = "system:user:admin.rudp", PermissionName = "读取指定用户的“直接权限”", Module = "system", Description = "读取指定用户的“直接权限”", MenuKey = "administratormanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:user:admin.rurp", PermissionName = "读取指定用户的“角色-权限”明细", Module = "system", Description = "读取指定用户的“角色-权限”明细", MenuKey = "administratormanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:user:admin.rur", PermissionName = "读取指定用户已分配的角色编码集合", Module = "system", Description = "读取指定用户已分配的角色编码集合", MenuKey = "administratormanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:user:admin:aup", PermissionName = "为指定用户分配“直接权限”", Module = "system", Description = "为指定用户分配“直接权限”", MenuKey = "administratormanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:user:admin:aur", PermissionName = "为用户分配角色(全量覆盖)", Module = "system", Description = "为用户分配角色(全量覆盖)", MenuKey = "administratormanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:user:assign.spl", PermissionName = "查询权限列表(支持条件过滤与分页/忽略分页)", Module = "system", Description = "查询权限列表(支持条件过滤与分页/忽略分页)", MenuKey = "administratormanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + // 客户-角色权限管理(网页端) + new Permission { PermissionNumber = "system:user:customer.rudp", PermissionName = "读取客户“直接权限”权限编码集合", Module = "system", Description = "读取客户“直接权限”权限编码集合", MenuKey = "customer", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:user:customer.rurp", PermissionName = "读取客户“角色-权限”明细", Module = "system", Description = "读取客户“角色-权限”明细", MenuKey = "customer", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:user:customer.rur", PermissionName = "读取客户已分配的角色编码集合", Module = "system", Description = "读取客户已分配的角色编码集合", MenuKey = "customer", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:user:customer:aup", PermissionName = "为客户分配“直接权限”", Module = "system", Description = "为客户分配“直接权限”", MenuKey = "customer", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:user:customer:aur", PermissionName = "为客户分配角色(全量覆盖)", Module = "system", Description = "为客户分配角色(全量覆盖)", MenuKey = "customer", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, // 员工-角色权限管理(网页端) - new Permission { PermissionNumber = "system:user:employee.rudp", PermissionName = "读取员工“直接权限”权限编码集合", Module = "system", Description = "读取员工“直接权限”权限编码集合", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:user:employee.rurp", PermissionName = "读取员工“角色-权限”明细", Module = "system", Description = "读取员工“角色-权限”明细", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:user:employee.rur", PermissionName = "读取员工已分配的角色编码集合", Module = "system", Description = "读取员工已分配的角色编码集合", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:user:employee:aup", PermissionName = "为员工分配“直接权限”", Module = "system", Description = "为员工分配“直接权限”", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, - new Permission { PermissionNumber = "system:user:employee:aur", PermissionName = "为员工分配角色(全量覆盖)", Module = "system", Description = "为员工分配角色(全量覆盖)", MenuKey = "staffmanagement", ParentNumber = null, IsDelete = 0, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:user:employee.rudp", PermissionName = "读取员工“直接权限”权限编码集合", Module = "system", Description = "读取员工“直接权限”权限编码集合", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:user:employee.rurp", PermissionName = "读取员工“角色-权限”明细", Module = "system", Description = "读取员工“角色-权限”明细", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:user:employee.rur", PermissionName = "读取员工已分配的角色编码集合", Module = "system", Description = "读取员工已分配的角色编码集合", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:user:employee:aup", PermissionName = "为员工分配“直接权限”", Module = "system", Description = "为员工分配“直接权限”", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, + new Permission { PermissionNumber = "system:user:employee:aur", PermissionName = "为员工分配角色(全量覆盖)", Module = "system", Description = "为员工分配角色(全量覆盖)", MenuKey = "staffmanagement", ParentNumber = null, DataInsUsr = "System", DataInsDate = DateTime.Now }, }; diff --git a/EOM.TSHotelManagement.Service/Application/FavoriteCollection/FavoriteCollectionService.cs b/EOM.TSHotelManagement.Service/Application/FavoriteCollection/FavoriteCollectionService.cs new file mode 100644 index 0000000000000000000000000000000000000000..b78b673fdb337fcafb8159bdb44b8297404b58da --- /dev/null +++ b/EOM.TSHotelManagement.Service/Application/FavoriteCollection/FavoriteCollectionService.cs @@ -0,0 +1,433 @@ +using EOM.TSHotelManagement.Common; +using EOM.TSHotelManagement.Contract; +using EOM.TSHotelManagement.Data; +using EOM.TSHotelManagement.Domain; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using System.Security.Claims; +using System.Text.Json; + +namespace EOM.TSHotelManagement.Service +{ + /// + /// 收藏夹服务实现 + /// + public class FavoriteCollectionService : IFavoriteCollectionService + { + private static readonly JsonSerializerOptions JsonSerializerOptions = new(JsonSerializerDefaults.Web); + + private readonly GenericRepository _favoriteCollectionRepository; + private readonly GenericRepository _administratorRepository; + private readonly GenericRepository _employeeRepository; + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly ILogger _logger; + + /// + /// 构造收藏夹服务 + /// + /// 收藏夹仓储 + /// 管理员仓储 + /// 员工仓储 + /// HTTP 上下文访问器 + /// 日志组件 + public FavoriteCollectionService( + GenericRepository favoriteCollectionRepository, + GenericRepository administratorRepository, + GenericRepository employeeRepository, + IHttpContextAccessor httpContextAccessor, + ILogger logger) + { + _favoriteCollectionRepository = favoriteCollectionRepository; + _administratorRepository = administratorRepository; + _employeeRepository = employeeRepository; + _httpContextAccessor = httpContextAccessor; + _logger = logger; + } + + /// + /// 保存当前登录用户的收藏夹快照 + /// + /// 收藏夹保存请求 + /// 保存结果 + public SingleOutputDto SaveFavoriteCollection(SaveFavoriteCollectionInputDto input) + { + input ??= new SaveFavoriteCollectionInputDto(); + + try + { + var currentUser = ResolveCurrentUser(); + if (currentUser == null) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.Unauthorized, + Message = LocalizationHelper.GetLocalizedString("Unauthorized.", "Unauthorized."), + Data = null + }; + } + + if (!TryValidateRequestedIdentity(currentUser, input, out var forbiddenResponse)) + { + return forbiddenResponse!; + } + + var normalizedRoutes = NormalizeRoutes(input.FavoriteRoutes); + var normalizedUpdatedAt = NormalizeUpdatedAt(input.UpdatedAt); + var normalizedTriggeredBy = NormalizeText(input.TriggeredBy, 32); + var favoriteRoutesJson = JsonSerializer.Serialize(normalizedRoutes, JsonSerializerOptions); + var saveResult = TrySaveSnapshot(currentUser, input.RowVersion, favoriteRoutesJson, normalizedRoutes.Count, normalizedUpdatedAt, normalizedTriggeredBy); + + if (saveResult.Outcome == SaveSnapshotOutcome.Conflict) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.Conflict, + Message = LocalizationHelper.GetLocalizedString( + "Data has been modified by another user. Please refresh and retry.", + "数据已被其他用户修改,请刷新后重试。"), + Data = null + }; + } + + if (saveResult.Outcome == SaveSnapshotOutcome.Failed) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.InternalServerError, + Message = LocalizationHelper.GetLocalizedString("Failed to save favorite collection.", "Failed to save favorite collection."), + Data = null + }; + } + + return new SingleOutputDto + { + Message = LocalizationHelper.GetLocalizedString("Favorite collection saved.", "Favorite collection saved."), + Data = new SaveFavoriteCollectionOutputDto + { + Saved = true, + RouteCount = normalizedRoutes.Count, + UpdatedAt = normalizedUpdatedAt, + RowVersion = saveResult.RowVersion + } + }; + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to save favorite collection."); + return new SingleOutputDto + { + Code = BusinessStatusCode.InternalServerError, + Message = LocalizationHelper.GetLocalizedString("Failed to save favorite collection.", "Failed to save favorite collection."), + Data = null + }; + } + } + + /// + /// 获取当前登录用户的收藏夹快照 + /// + /// 收藏夹读取结果 + public SingleOutputDto GetFavoriteCollection() + { + try + { + var currentUser = ResolveCurrentUser(); + if (currentUser == null) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.Unauthorized, + Message = LocalizationHelper.GetLocalizedString("Unauthorized.", "Unauthorized."), + Data = null + }; + } + + var collection = _favoriteCollectionRepository.GetFirst(x => x.UserNumber == currentUser.UserNumber); + if (collection == null) + { + return new SingleOutputDto + { + Message = "OK", + Data = new ReadFavoriteCollectionOutputDto() + }; + } + + return new SingleOutputDto + { + Message = "OK", + Data = new ReadFavoriteCollectionOutputDto + { + FavoriteRoutes = DeserializeRoutes(collection.FavoriteRoutesJson), + UpdatedAt = DateTime.SpecifyKind(collection.UpdatedAt, DateTimeKind.Utc), + RowVersion = collection.RowVersion + } + }; + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to get favorite collection."); + return new SingleOutputDto + { + Code = BusinessStatusCode.InternalServerError, + Message = LocalizationHelper.GetLocalizedString("Failed to get favorite collection.", "Failed to get favorite collection."), + Data = null + }; + } + } + + private SaveSnapshotResult TrySaveSnapshot( + CurrentUserSnapshot currentUser, + long? rowVersion, + string favoriteRoutesJson, + int routeCount, + DateTime updatedAt, + string? triggeredBy) + { + const int maxInsertRetryCount = 2; + + for (var attempt = 1; attempt <= maxInsertRetryCount; attempt++) + { + var existing = _favoriteCollectionRepository.GetFirst(x => x.UserNumber == currentUser.UserNumber); + + if (existing == null) + { + if (rowVersion.HasValue && rowVersion.Value > 0) + { + _logger.LogWarning( + "Favorite collection insert rejected because client provided stale row version {RowVersion} for user {UserNumber}.", + rowVersion.Value, + currentUser.UserNumber); + return new SaveSnapshotResult(SaveSnapshotOutcome.Conflict); + } + + var entity = new UserFavoriteCollection + { + UserNumber = currentUser.UserNumber, + LoginType = currentUser.LoginType, + Account = currentUser.Account, + FavoriteRoutesJson = favoriteRoutesJson, + RouteCount = routeCount, + UpdatedAt = updatedAt, + TriggeredBy = triggeredBy + }; + + try + { + if (_favoriteCollectionRepository.Insert(entity)) + { + return new SaveSnapshotResult(SaveSnapshotOutcome.Saved, entity.RowVersion); + } + } + catch (Exception ex) + { + _logger.LogWarning( + ex, + "Insert favorite collection snapshot failed on attempt {Attempt} for user {UserNumber}.", + attempt, + currentUser.UserNumber); + } + + continue; + } + + if (!rowVersion.HasValue || rowVersion.Value <= 0) + { + _logger.LogWarning( + "Favorite collection update rejected because row version is missing for user {UserNumber}. CurrentRowVersion={CurrentRowVersion}.", + currentUser.UserNumber, + existing.RowVersion); + return new SaveSnapshotResult(SaveSnapshotOutcome.Conflict); + } + + existing.RowVersion = rowVersion.Value; + existing.LoginType = currentUser.LoginType; + existing.Account = currentUser.Account; + existing.FavoriteRoutesJson = favoriteRoutesJson; + existing.RouteCount = routeCount; + existing.UpdatedAt = updatedAt; + existing.TriggeredBy = triggeredBy; + + if (_favoriteCollectionRepository.Update(existing)) + { + return new SaveSnapshotResult(SaveSnapshotOutcome.Saved, existing.RowVersion); + } + + _logger.LogWarning( + "Favorite collection update hit a concurrency conflict for user {UserNumber}. ExpectedRowVersion={ExpectedRowVersion}.", + currentUser.UserNumber, + rowVersion.Value); + return new SaveSnapshotResult(SaveSnapshotOutcome.Conflict); + } + + return new SaveSnapshotResult(SaveSnapshotOutcome.Failed); + } + + private bool TryValidateRequestedIdentity( + CurrentUserSnapshot currentUser, + SaveFavoriteCollectionInputDto input, + out SingleOutputDto? forbiddenResponse) + { + forbiddenResponse = null; + + var requestAccount = NormalizeText(input.Account, 128); + if (!string.IsNullOrWhiteSpace(requestAccount) && !IsCurrentAccount(currentUser, requestAccount)) + { + _logger.LogWarning( + "Favorite collection request account mismatch. UserNumber={UserNumber}, RequestAccount={RequestAccount}, ResolvedAccount={ResolvedAccount}.", + currentUser.UserNumber, + requestAccount, + currentUser.Account); + + forbiddenResponse = new SingleOutputDto + { + Code = BusinessStatusCode.Forbidden, + Message = LocalizationHelper.GetLocalizedString( + "Requested identity does not match current user.", + "请求身份与当前登录用户不一致。"), + Data = null + }; + + return false; + } + + var requestLoginType = NormalizeText(input.LoginType, 32); + if (!string.IsNullOrWhiteSpace(requestLoginType) + && !string.Equals(requestLoginType, currentUser.LoginType, StringComparison.OrdinalIgnoreCase)) + { + _logger.LogWarning( + "Favorite collection request login type mismatch. UserNumber={UserNumber}, RequestLoginType={RequestLoginType}, ResolvedLoginType={ResolvedLoginType}.", + currentUser.UserNumber, + requestLoginType, + currentUser.LoginType); + + forbiddenResponse = new SingleOutputDto + { + Code = BusinessStatusCode.Forbidden, + Message = LocalizationHelper.GetLocalizedString( + "Requested identity does not match current user.", + "请求身份与当前登录用户不一致。"), + Data = null + }; + + return false; + } + + return true; + } + + private CurrentUserSnapshot? ResolveCurrentUser() + { + var principal = _httpContextAccessor.HttpContext?.User; + var userNumber = principal?.FindFirst(ClaimTypes.SerialNumber)?.Value + ?? principal?.FindFirst("serialnumber")?.Value + ?? principal?.FindFirst(ClaimTypes.NameIdentifier)?.Value; + + if (string.IsNullOrWhiteSpace(userNumber)) + { + return null; + } + + var administrator = _administratorRepository.GetFirst(x => x.Number == userNumber && x.IsDelete != 1); + if (administrator != null) + { + return new CurrentUserSnapshot(userNumber, "admin", administrator.Account); + } + + var employee = _employeeRepository.GetFirst(x => x.EmployeeId == userNumber && x.IsDelete != 1); + if (employee != null) + { + return new CurrentUserSnapshot(userNumber, "employee", employee.EmployeeId); + } + + var fallbackAccount = NormalizeText( + principal?.FindFirst("account")?.Value ?? principal?.Identity?.Name, + 128); + var loginType = NormalizeText( + principal?.FindFirst("login_type")?.Value ?? principal?.FindFirst("logintype")?.Value, + 32) ?? "unknown"; + + return new CurrentUserSnapshot(userNumber, loginType, fallbackAccount); + } + + private static bool IsCurrentAccount(CurrentUserSnapshot currentUser, string requestAccount) + { + return string.Equals(requestAccount, currentUser.Account, StringComparison.OrdinalIgnoreCase) + || string.Equals(requestAccount, currentUser.UserNumber, StringComparison.OrdinalIgnoreCase); + } + + private static List NormalizeRoutes(IEnumerable? routes) + { + var result = new List(); + var uniqueRoutes = new HashSet(StringComparer.Ordinal); + + foreach (var route in routes ?? Enumerable.Empty()) + { + var normalizedRoute = NormalizeText(route, 2048); + if (string.IsNullOrWhiteSpace(normalizedRoute)) + { + continue; + } + + if (uniqueRoutes.Add(normalizedRoute)) + { + result.Add(normalizedRoute); + } + } + + return result; + } + + private static List DeserializeRoutes(string? favoriteRoutesJson) + { + if (string.IsNullOrWhiteSpace(favoriteRoutesJson)) + { + return new List(); + } + + try + { + return JsonSerializer.Deserialize>(favoriteRoutesJson, JsonSerializerOptions) ?? new List(); + } + catch + { + return new List(); + } + } + + private static DateTime NormalizeUpdatedAt(DateTime? updatedAt) + { + if (!updatedAt.HasValue) + { + return DateTime.UtcNow; + } + + return updatedAt.Value.Kind switch + { + DateTimeKind.Utc => updatedAt.Value, + DateTimeKind.Local => updatedAt.Value.ToUniversalTime(), + _ => DateTime.SpecifyKind(updatedAt.Value, DateTimeKind.Utc) + }; + } + + private static string? NormalizeText(string? value, int maxLength) + { + if (string.IsNullOrWhiteSpace(value)) + { + return null; + } + + var trimmed = value.Trim(); + return trimmed.Length <= maxLength ? trimmed : trimmed[..maxLength]; + } + + private sealed record CurrentUserSnapshot(string UserNumber, string LoginType, string? Account); + private sealed record SaveSnapshotResult(SaveSnapshotOutcome Outcome, long RowVersion = 0); + + private enum SaveSnapshotOutcome + { + Saved, + Conflict, + Failed + } + } +} \ No newline at end of file diff --git a/EOM.TSHotelManagement.Service/Application/FavoriteCollection/IFavoriteCollectionService.cs b/EOM.TSHotelManagement.Service/Application/FavoriteCollection/IFavoriteCollectionService.cs new file mode 100644 index 0000000000000000000000000000000000000000..cdb5e3966ef6884accee0f064555faae589b9f30 --- /dev/null +++ b/EOM.TSHotelManagement.Service/Application/FavoriteCollection/IFavoriteCollectionService.cs @@ -0,0 +1,23 @@ +using EOM.TSHotelManagement.Contract; + +namespace EOM.TSHotelManagement.Service +{ + /// + /// 收藏夹服务接口 + /// + public interface IFavoriteCollectionService + { + /// + /// 保存当前用户的收藏夹快照 + /// + /// 收藏夹保存请求 + /// 保存结果 + SingleOutputDto SaveFavoriteCollection(SaveFavoriteCollectionInputDto input); + + /// + /// 获取当前用户的收藏夹快照 + /// + /// 收藏夹读取结果 + SingleOutputDto GetFavoriteCollection(); + } +} diff --git a/EOM.TSHotelManagement.Service/Application/Profile/IProfileService.cs b/EOM.TSHotelManagement.Service/Application/Profile/IProfileService.cs new file mode 100644 index 0000000000000000000000000000000000000000..13c277d2f003aa5a6c038654a5f577d6c0843423 --- /dev/null +++ b/EOM.TSHotelManagement.Service/Application/Profile/IProfileService.cs @@ -0,0 +1,15 @@ +using EOM.TSHotelManagement.Contract; +using Microsoft.AspNetCore.Http; +using System.Threading.Tasks; + +namespace EOM.TSHotelManagement.Service +{ + public interface IProfileService + { + SingleOutputDto GetCurrentProfile(string serialNumber); + + Task> UploadAvatar(string serialNumber, UploadAvatarInputDto inputDto, IFormFile file); + + BaseResponse ChangePassword(string serialNumber, ChangePasswordInputDto inputDto); + } +} diff --git a/EOM.TSHotelManagement.Service/Application/Profile/ProfileService.cs b/EOM.TSHotelManagement.Service/Application/Profile/ProfileService.cs new file mode 100644 index 0000000000000000000000000000000000000000..6ce688887c229a7ba3182171188aa72533f89f9a --- /dev/null +++ b/EOM.TSHotelManagement.Service/Application/Profile/ProfileService.cs @@ -0,0 +1,586 @@ +using EOM.TSHotelManagement.Common; +using EOM.TSHotelManagement.Contract; +using EOM.TSHotelManagement.Data; +using EOM.TSHotelManagement.Domain; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.IO; +using System.Net.Mail; +using System.Threading.Tasks; + +namespace EOM.TSHotelManagement.Service +{ + public class ProfileService( + GenericRepository adminRepository, + GenericRepository adminPhotoRepository, + GenericRepository adminTypeRepository, + GenericRepository employeeRepository, + GenericRepository employeePhotoRepository, + GenericRepository departmentRepository, + GenericRepository positionRepository, + DataProtectionHelper dataProtectionHelper, + LskyHelper lskyHelper, + MailHelper mailHelper, + ILogger logger) : IProfileService + { + private const string AdminLoginType = "admin"; + private const string EmployeeLoginType = "employee"; + private readonly GenericRepository _adminRepository = adminRepository; + private readonly GenericRepository _adminPhotoRepository = adminPhotoRepository; + private readonly GenericRepository _adminTypeRepository = adminTypeRepository; + private readonly GenericRepository _employeeRepository = employeeRepository; + private readonly GenericRepository _employeePhotoRepository = employeePhotoRepository; + private readonly GenericRepository _departmentRepository = departmentRepository; + private readonly GenericRepository _positionRepository = positionRepository; + private readonly DataProtectionHelper _dataProtectionHelper = dataProtectionHelper; + private readonly LskyHelper _lskyHelper = lskyHelper; + private readonly MailHelper _mailHelper = mailHelper; + private readonly ILogger _logger = logger; + + public SingleOutputDto GetCurrentProfile(string serialNumber) + { + try + { + var currentUser = ResolveCurrentUser(serialNumber); + if (currentUser == null) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.NotFound, + Message = LocalizationHelper.GetLocalizedString("Current profile not found", "未找到当前登录人资料") + }; + } + + return new SingleOutputDto + { + Message = LocalizationHelper.GetLocalizedString("ok", "成功"), + Data = BuildCurrentProfileOutput(currentUser) + }; + } + catch (Exception ex) + { + _logger.LogError(ex, "Error getting current profile for serial number: {SerialNumber}", serialNumber); + return new SingleOutputDto + { + Code = BusinessStatusCode.InternalServerError, + Message = LocalizationHelper.GetLocalizedString(ex.Message, ex.Message) + }; + } + } + + public async Task> UploadAvatar(string serialNumber, UploadAvatarInputDto inputDto, IFormFile file) + { + try + { + var currentUser = ResolveCurrentUser(serialNumber); + if (currentUser == null) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.NotFound, + Message = LocalizationHelper.GetLocalizedString("Current profile not found", "未找到当前登录人资料") + }; + } + + if (!string.IsNullOrWhiteSpace(inputDto?.LoginType) + && !string.Equals(inputDto.LoginType, currentUser.LoginType, StringComparison.OrdinalIgnoreCase)) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.BadRequest, + Message = LocalizationHelper.GetLocalizedString("Login type does not match current user", "账号类型与当前登录人不匹配") + }; + } + + var uploadResult = await UploadImageAsync(file); + if (!uploadResult.Success) + { + return uploadResult; + } + + var saveResult = SaveAvatarPath(currentUser, uploadResult.Data.PhotoUrl); + if (!saveResult.Success) + { + return saveResult; + } + + return new SingleOutputDto + { + Message = LocalizationHelper.GetLocalizedString("ok", "成功"), + Data = new UploadAvatarOutputDto + { + PhotoUrl = uploadResult.Data.PhotoUrl + } + }; + } + catch (Exception ex) + { + _logger.LogError(ex, "Error uploading avatar for serial number: {SerialNumber}", serialNumber); + return new SingleOutputDto + { + Code = BusinessStatusCode.InternalServerError, + Message = LocalizationHelper.GetLocalizedString(ex.Message, ex.Message) + }; + } + } + + public BaseResponse ChangePassword(string serialNumber, ChangePasswordInputDto inputDto) + { + try + { + var currentUser = ResolveCurrentUser(serialNumber); + if (currentUser == null) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.NotFound, + Message = LocalizationHelper.GetLocalizedString("Current profile not found", "未找到当前登录人资料") + }; + } + + if (!string.Equals(inputDto.NewPassword, inputDto.ConfirmPassword, StringComparison.Ordinal)) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.BadRequest, + Message = LocalizationHelper.GetLocalizedString("The new password and confirmation password do not match", "新密码与确认密码不一致") + }; + } + + if (string.Equals(inputDto.OldPassword, inputDto.NewPassword, StringComparison.Ordinal)) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.BadRequest, + Message = LocalizationHelper.GetLocalizedString("The new password cannot be the same as the old password", "新密码不能与旧密码相同") + }; + } + + BaseResponse updateResponse = currentUser.LoginType switch + { + AdminLoginType => ChangeAdminPassword(currentUser.Admin, inputDto), + EmployeeLoginType => ChangeEmployeePassword(currentUser.Employee, inputDto), + _ => new BaseResponse(BusinessStatusCode.BadRequest, LocalizationHelper.GetLocalizedString("Unsupported login type", "不支持的登录类型")) + }; + + if (!updateResponse.Success) + { + return new SingleOutputDto + { + Code = updateResponse.Code, + Message = updateResponse.Message + }; + } + + return new SingleOutputDto + { + Message = LocalizationHelper.GetLocalizedString("Password changed successfully", "密码修改成功"), + Data = null + }; + } + catch (Exception ex) + { + _logger.LogError(ex, "Error changing password for serial number: {SerialNumber}", serialNumber); + return new SingleOutputDto + { + Code = BusinessStatusCode.InternalServerError, + Message = LocalizationHelper.GetLocalizedString(ex.Message, ex.Message), + Data = null + }; + } + } + + private CurrentProfileOutputDto BuildCurrentProfileOutput(CurrentUserProfile currentUser) + { + return string.Equals(currentUser.LoginType, AdminLoginType, StringComparison.OrdinalIgnoreCase) + ? BuildAdminCurrentProfile(currentUser.Admin, currentUser.PhotoUrl) + : BuildEmployeeCurrentProfile(currentUser.Employee, currentUser.PhotoUrl); + } + + private CurrentProfileOutputDto BuildAdminCurrentProfile(Administrator admin, string photoUrl) + { + var account = FirstNonEmpty(admin.Account, admin.Number); + var displayName = FirstNonEmpty(admin.Name, account); + var typeCode = FirstNonEmpty(admin.Type, string.Empty); + var typeName = FirstNonEmpty( + _adminTypeRepository.GetFirst(a => a.TypeId == admin.Type && a.IsDelete != 1)?.TypeName, + typeCode); + + return new CurrentProfileOutputDto + { + LoginType = AdminLoginType, + UserNumber = FirstNonEmpty(admin.Number, account), + Account = account, + DisplayName = displayName, + PhotoUrl = FirstNonEmpty(photoUrl, string.Empty), + Profile = new CurrentProfileAdminDto + { + Number = FirstNonEmpty(admin.Number, account), + Account = account, + Name = displayName, + TypeName = typeName, + Type = typeCode, + IsSuperAdmin = admin.IsSuperAdmin, + PhotoUrl = FirstNonEmpty(photoUrl, string.Empty) + } + }; + } + + private CurrentProfileOutputDto BuildEmployeeCurrentProfile(Employee employee, string photoUrl) + { + var account = FirstNonEmpty(employee.EmailAddress, employee.EmployeeId); + var displayName = FirstNonEmpty(employee.Name, employee.EmployeeId); + var departmentName = FirstNonEmpty( + _departmentRepository.GetFirst(a => a.DepartmentNumber == employee.Department && a.IsDelete != 1)?.DepartmentName, + employee.Department); + var positionName = FirstNonEmpty( + _positionRepository.GetFirst(a => a.PositionNumber == employee.Position && a.IsDelete != 1)?.PositionName, + employee.Position); + + return new CurrentProfileOutputDto + { + LoginType = EmployeeLoginType, + UserNumber = FirstNonEmpty(employee.EmployeeId, account), + Account = account, + DisplayName = displayName, + PhotoUrl = FirstNonEmpty(photoUrl, string.Empty), + Profile = new CurrentProfileEmployeeDto + { + EmployeeId = FirstNonEmpty(employee.EmployeeId, account), + Name = displayName, + DepartmentName = departmentName, + PositionName = positionName, + PhoneNumber = FirstNonEmpty(dataProtectionHelper.SafeDecryptEmployeeData(employee.PhoneNumber), string.Empty), + EmailAddress = FirstNonEmpty(employee.EmailAddress, account), + Address = FirstNonEmpty(employee.Address, string.Empty), + HireDate = FormatDate(employee.HireDate), + DateOfBirth = FormatDate(employee.DateOfBirth), + PhotoUrl = FirstNonEmpty(photoUrl, string.Empty) + } + }; + } + + private BaseResponse ChangeAdminPassword(Administrator admin, ChangePasswordInputDto inputDto) + { + var currentPassword = _dataProtectionHelper.SafeDecryptAdministratorData(admin.Password); + if (!string.Equals(inputDto.OldPassword, currentPassword, StringComparison.Ordinal)) + { + return new BaseResponse( + BusinessStatusCode.BadRequest, + LocalizationHelper.GetLocalizedString("The old password is incorrect", "旧密码不正确")); + } + + admin.Password = _dataProtectionHelper.EncryptAdministratorData(inputDto.NewPassword); + var updateResult = _adminRepository.Update(admin); + if (!updateResult) + { + return BaseResponseFactory.ConcurrencyConflict(); + } + + TrySendPasswordChangeEmail(admin.Account, admin.Name, inputDto.NewPassword); + return new BaseResponse(); + } + + private BaseResponse ChangeEmployeePassword(Employee employee, ChangePasswordInputDto inputDto) + { + var currentPassword = _dataProtectionHelper.SafeDecryptEmployeeData(employee.Password); + if (!string.Equals(inputDto.OldPassword, currentPassword, StringComparison.Ordinal)) + { + return new BaseResponse( + BusinessStatusCode.BadRequest, + LocalizationHelper.GetLocalizedString("The old password is incorrect", "旧密码不正确")); + } + + employee.Password = _dataProtectionHelper.EncryptEmployeeData(inputDto.NewPassword); + employee.IsInitialize = 1; + var updateResult = _employeeRepository.Update(employee); + if (!updateResult) + { + return BaseResponseFactory.ConcurrencyConflict(); + } + + TrySendPasswordChangeEmail(employee.EmailAddress, employee.Name, inputDto.NewPassword); + return new BaseResponse(); + } + + private async Task> UploadImageAsync(IFormFile file) + { + if (!await _lskyHelper.GetEnabledState()) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.BadRequest, + Message = LocalizationHelper.GetLocalizedString("Image upload service is not enabled", "图片上传服务未启用") + }; + } + + if (file == null || file.Length == 0) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.BadRequest, + Message = LocalizationHelper.GetLocalizedString("File cannot null", "文件不能为空") + }; + } + + if (file.Length > 1048576) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.BadRequest, + Message = LocalizationHelper.GetLocalizedString("Image size exceeds 1MB limit", "图片大小不能超过1MB") + }; + } + + if (file.ContentType != "image/jpeg" && file.ContentType != "image/png") + { + return new SingleOutputDto + { + Code = BusinessStatusCode.BadRequest, + Message = LocalizationHelper.GetLocalizedString("Invalid image format", "图片格式不正确") + }; + } + + using var stream = file.OpenReadStream(); + if (!TryDetectImageContentType(stream, out var detectedContentType)) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.BadRequest, + Message = LocalizationHelper.GetLocalizedString("Invalid image format", "图片格式不正确") + }; + } + + if (!IsAllowedDeclaredImageContentType(file.ContentType, detectedContentType)) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.BadRequest, + Message = LocalizationHelper.GetLocalizedString("Invalid image format", "图片格式不正确") + }; + } + + var token = await _lskyHelper.GetImageStorageTokenAsync(); + if (string.IsNullOrWhiteSpace(token)) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.InternalServerError, + Message = LocalizationHelper.GetLocalizedString("Get Token Fail", "获取Token失败") + }; + } + + if (stream.CanSeek) + { + stream.Seek(0, SeekOrigin.Begin); + } + + var imageUrl = await _lskyHelper.UploadImageAsync( + fileStream: stream, + fileName: file.FileName, + contentType: detectedContentType, + token: token); + + if (string.IsNullOrWhiteSpace(imageUrl)) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.InternalServerError, + Message = LocalizationHelper.GetLocalizedString("Image upload failed", "图片上传失败") + }; + } + + return new SingleOutputDto + { + Data = new UploadAvatarOutputDto + { + PhotoUrl = imageUrl + } + }; + } + + private SingleOutputDto SaveAvatarPath(CurrentUserProfile currentUser, string photoUrl) + { + if (string.Equals(currentUser.LoginType, AdminLoginType, StringComparison.OrdinalIgnoreCase)) + { + var adminPhoto = _adminPhotoRepository.GetFirst(a => a.AdminNumber == currentUser.UserNumber && a.IsDelete != 1); + if (adminPhoto == null) + { + _adminPhotoRepository.Insert(new AdministratorPhoto + { + AdminNumber = currentUser.UserNumber, + PhotoPath = photoUrl + }); + + return new SingleOutputDto(); + } + + adminPhoto.PhotoPath = photoUrl; + if (!_adminPhotoRepository.Update(adminPhoto)) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.Conflict, + Message = LocalizationHelper.GetLocalizedString("Data has been modified by another user. Please refresh and retry.", "数据已被其他用户修改,请刷新后重试。") + }; + } + + return new SingleOutputDto(); + } + + var employeePhoto = _employeePhotoRepository.GetFirst(a => a.EmployeeId == currentUser.UserNumber && a.IsDelete != 1); + if (employeePhoto == null) + { + _employeePhotoRepository.Insert(new EmployeePhoto + { + EmployeeId = currentUser.UserNumber, + PhotoPath = photoUrl + }); + + return new SingleOutputDto(); + } + + employeePhoto.PhotoPath = photoUrl; + if (!_employeePhotoRepository.Update(employeePhoto)) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.Conflict, + Message = LocalizationHelper.GetLocalizedString("Data has been modified by another user. Please refresh and retry.", "数据已被其他用户修改,请刷新后重试。") + }; + } + + return new SingleOutputDto(); + } + + private CurrentUserProfile? ResolveCurrentUser(string serialNumber) + { + if (string.IsNullOrWhiteSpace(serialNumber)) + { + return null; + } + + var admin = _adminRepository.GetFirst(a => a.Number == serialNumber && a.IsDelete != 1); + if (admin != null) + { + var adminPhoto = _adminPhotoRepository.GetFirst(a => a.AdminNumber == admin.Number && a.IsDelete != 1); + return new CurrentUserProfile + { + LoginType = AdminLoginType, + UserNumber = admin.Number, + Account = admin.Account, + DisplayName = admin.Name, + PhotoUrl = adminPhoto?.PhotoPath ?? string.Empty, + Admin = admin + }; + } + + var employee = _employeeRepository.GetFirst(a => a.EmployeeId == serialNumber && a.IsDelete != 1); + if (employee != null) + { + var employeePhoto = _employeePhotoRepository.GetFirst(a => a.EmployeeId == employee.EmployeeId && a.IsDelete != 1); + return new CurrentUserProfile + { + LoginType = EmployeeLoginType, + UserNumber = employee.EmployeeId, + Account = string.IsNullOrWhiteSpace(employee.EmailAddress) ? employee.EmployeeId : employee.EmailAddress, + DisplayName = employee.Name, + PhotoUrl = employeePhoto?.PhotoPath ?? string.Empty, + Employee = employee + }; + } + + return null; + } + + private void TrySendPasswordChangeEmail(string? emailAddress, string? displayName, string newPassword) + { + if (string.IsNullOrWhiteSpace(emailAddress) || !MailAddress.TryCreate(emailAddress, out _)) + { + return; + } + + try + { + var template = EmailTemplate.GetUpdatePasswordTemplate(displayName ?? "User", newPassword); + _mailHelper.SendMail(new List { emailAddress }, template.Subject, template.Body, new List { emailAddress }); + } + catch (Exception ex) + { + _logger.LogWarning(ex, "Password change email send failed for account: {Account}", emailAddress); + } + } + + private static bool IsAllowedDeclaredImageContentType(string? declaredContentType, string detectedContentType) + { + if (string.IsNullOrWhiteSpace(declaredContentType)) + { + return true; + } + + return string.Equals(declaredContentType, detectedContentType, StringComparison.OrdinalIgnoreCase); + } + + private static bool TryDetectImageContentType(Stream stream, out string detectedContentType) + { + detectedContentType = string.Empty; + if (stream == null || !stream.CanRead) + { + return false; + } + + var header = new byte[8]; + var bytesRead = stream.Read(header, 0, header.Length); + if (stream.CanSeek) + { + stream.Seek(0, SeekOrigin.Begin); + } + + var signature = header.AsSpan(0, bytesRead); + if (signature.SequenceEqual(new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A })) + { + detectedContentType = "image/png"; + return true; + } + + if (signature.Length >= 3 + && signature[0] == 0xFF + && signature[1] == 0xD8 + && signature[2] == 0xFF) + { + detectedContentType = "image/jpeg"; + return true; + } + + return false; + } + + private static string FirstNonEmpty(string? primary, string? fallback) + { + if (!string.IsNullOrWhiteSpace(primary)) + { + return primary; + } + + return fallback ?? string.Empty; + } + + private static string FormatDate(DateOnly date) + { + return date == default ? string.Empty : date.ToString("yyyy-MM-dd"); + } + + private sealed class CurrentUserProfile + { + public string LoginType { get; set; } + public string UserNumber { get; set; } + public string Account { get; set; } + public string DisplayName { get; set; } + public string PhotoUrl { get; set; } + public Administrator Admin { get; set; } + public Employee Employee { get; set; } + } + } +} diff --git a/EOM.TSHotelManagement.Service/Business/Asset/AssetService.cs b/EOM.TSHotelManagement.Service/Business/Asset/AssetService.cs index a3763018cf880abe5dd1c5499b902cdaee90d6f1..969313ad445de47ab25dca520a89ef62da2bc847 100644 --- a/EOM.TSHotelManagement.Service/Business/Asset/AssetService.cs +++ b/EOM.TSHotelManagement.Service/Business/Asset/AssetService.cs @@ -107,7 +107,7 @@ namespace EOM.TSHotelManagement.Service int count = 0; List assets = new List(); - if (asset.Page != 0 && asset.PageSize != 0) + if (!asset.IgnorePaging) { assets = assetRepository.AsQueryable().Where(where.ToExpression()).OrderBy(a => a.AssetNumber) .ToPageList((int)asset.Page, (int)asset.PageSize, ref count); @@ -125,7 +125,7 @@ namespace EOM.TSHotelManagement.Service var dept = depts.SingleOrDefault(a => a.DepartmentNumber.Equals(source.DepartmentCode)); source.DepartmentName = dept == null ? "" : dept.DepartmentName; var worker = employees.SingleOrDefault(a => a.EmployeeId.Equals(source.AcquiredByEmployeeId)); - source.AcquiredByEmployeeName = worker == null ? "" : worker.EmployeeName; + source.AcquiredByName = worker == null ? "" : worker.Name; source.AssetValueFormatted = source.AssetValue == 0 ? "" : Decimal.Parse(source.AssetValue.ToString()).ToString("#,##0.00").ToString(); }); diff --git a/EOM.TSHotelManagement.Service/Business/Customer/Account/CustomerAccountService.cs b/EOM.TSHotelManagement.Service/Business/Customer/Account/CustomerAccountService.cs index 80cb10a259471ad7587167008847c1cfda9fb129..2f348bbe7f4b6b9c44e242a7a1541fb819d2581c 100644 --- a/EOM.TSHotelManagement.Service/Business/Customer/Account/CustomerAccountService.cs +++ b/EOM.TSHotelManagement.Service/Business/Customer/Account/CustomerAccountService.cs @@ -1,4 +1,4 @@ -using EOM.TSHotelManagement.Common; +using EOM.TSHotelManagement.Common; using EOM.TSHotelManagement.Contract; using EOM.TSHotelManagement.Data; using EOM.TSHotelManagement.Domain; @@ -284,14 +284,14 @@ namespace EOM.TSHotelManagement.Service var customerResult = customerRepository.Insert(new Customer { CustomerNumber = customerNumber, - CustomerName = string.Empty, - CustomerGender = 0, + Name = string.Empty, + Gender = 0, CustomerType = 0, - CustomerPhoneNumber = string.Empty, - CustomerAddress = string.Empty, + PhoneNumber = string.Empty, + Address = string.Empty, DateOfBirth = DateOnly.MinValue, IdCardNumber = string.Empty, - PassportId = 0, + IdCardType = 0, IsDelete = 0, DataInsUsr = readCustomerAccountInputDto.Account, DataInsDate = DateTime.Now @@ -319,13 +319,12 @@ namespace EOM.TSHotelManagement.Service } // 绑定客户到客户组角色 - if (!userRoleRepository.AsQueryable().Any(ur => ur.UserNumber == customerNumber && ur.RoleNumber == customerRoleNumber && ur.IsDelete != 1)) + if (!userRoleRepository.AsQueryable().Any(ur => ur.UserNumber == customerNumber && ur.RoleNumber == customerRoleNumber)) { userRoleRepository.Insert(new UserRole { UserNumber = customerNumber, RoleNumber = customerRoleNumber, - IsDelete = 0, DataInsUsr = readCustomerAccountInputDto.Account, DataInsDate = DateTime.Now }); diff --git a/EOM.TSHotelManagement.Service/Business/Customer/CustomerService.cs b/EOM.TSHotelManagement.Service/Business/Customer/CustomerService.cs index ef10f0c3b96c7d885fe4ac1cd3db9821dc8c859e..05603dce959d89b118404b09b79c89f96ab8426d 100644 --- a/EOM.TSHotelManagement.Service/Business/Customer/CustomerService.cs +++ b/EOM.TSHotelManagement.Service/Business/Customer/CustomerService.cs @@ -110,9 +110,9 @@ namespace EOM.TSHotelManagement.Service public BaseResponse InsertCustomerInfo(CreateCustomerInputDto custo) { string NewID = dataProtector.EncryptCustomerData(custo.IdCardNumber); - string NewTel = dataProtector.EncryptCustomerData(custo.CustomerPhoneNumber); + string NewTel = dataProtector.EncryptCustomerData(custo.PhoneNumber); custo.IdCardNumber = NewID; - custo.CustomerPhoneNumber = NewTel; + custo.PhoneNumber = NewTel; try { if (custoRepository.IsAny(a => a.CustomerNumber == custo.CustomerNumber)) @@ -145,13 +145,12 @@ namespace EOM.TSHotelManagement.Service } // 绑定客户到客户组角色 - if (!userRoleRepository.AsQueryable().Any(ur => ur.UserNumber == customer.CustomerNumber && ur.RoleNumber == customerRoleNumber && ur.IsDelete != 1)) + if (!userRoleRepository.AsQueryable().Any(ur => ur.UserNumber == customer.CustomerNumber && ur.RoleNumber == customerRoleNumber)) { userRoleRepository.Insert(new UserRole { UserNumber = customer.CustomerNumber, RoleNumber = customerRoleNumber, - IsDelete = 0, DataInsUsr = customer.DataInsUsr, DataInsDate = DateTime.Now }); @@ -174,9 +173,9 @@ namespace EOM.TSHotelManagement.Service public BaseResponse UpdCustomerInfo(UpdateCustomerInputDto custo) { string NewID = dataProtector.EncryptCustomerData(custo.IdCardNumber); - string NewTel = dataProtector.EncryptCustomerData(custo.CustomerPhoneNumber); + string NewTel = dataProtector.EncryptCustomerData(custo.PhoneNumber); custo.IdCardNumber = NewID; - custo.CustomerPhoneNumber = NewTel; + custo.PhoneNumber = NewTel; try { if (!custoRepository.IsAny(a => a.CustomerNumber == custo.CustomerNumber)) @@ -357,18 +356,18 @@ namespace EOM.TSHotelManagement.Service { Id = source.Id, CustomerNumber = source.CustomerNumber, - CustomerName = source.CustomerName, - CustomerGender = source.CustomerGender, - PassportId = source.PassportId, - GenderName = genderMap.TryGetValue(source.CustomerGender ?? 0, out var genderName) ? genderName : "", - CustomerPhoneNumber = dataProtector.SafeDecryptCustomerData(source.CustomerPhoneNumber), + Name = source.Name, + Gender = source.Gender, + IdCardType = source.IdCardType, + GenderName = genderMap.TryGetValue(source.Gender, out var genderName) ? genderName : "", + PhoneNumber = dataProtector.SafeDecryptCustomerData(source.PhoneNumber), DateOfBirth = source.DateOfBirth.ToDateTime(TimeOnly.MinValue), CustomerType = source.CustomerType, - CustomerTypeName = custoTypeMap.TryGetValue(source.CustomerType, out var customerTypeName) ? customerTypeName : "", - PassportName = passPortTypeMap.TryGetValue(source.PassportId, out var passportName) ? passportName : "", - IdCardNumber = dataProtector.SafeDecryptCustomerData(source.IdCardNumber), - CustomerAddress = source.CustomerAddress ?? "", - DataInsUsr = source.DataInsUsr, + CustomerTypeName = custoTypeMap.TryGetValue(source.CustomerType, out var customerTypeName) ? customerTypeName : "", + PassportName = passPortTypeMap.TryGetValue(source.IdCardType, out var passportName) ? passportName : "", + IdCardNumber = dataProtector.SafeDecryptCustomerData(source.IdCardNumber), + Address = source.Address ?? "", + DataInsUsr = source.DataInsUsr, DataInsDate = source.DataInsDate, DataChgUsr = source.DataChgUsr, DataChgDate = source.DataChgDate, @@ -387,17 +386,17 @@ namespace EOM.TSHotelManagement.Service { Id = source.Id, CustomerNumber = source.CustomerNumber, - CustomerName = source.CustomerName, - CustomerGender = source.CustomerGender, - PassportId = source.PassportId, - GenderName = genderMap.TryGetValue(source.CustomerGender ?? 0, out var genderName) ? genderName : "", - CustomerPhoneNumber = dataProtector.SafeDecryptCustomerData(source.CustomerPhoneNumber), + Name = source.Name, + Gender = source.Gender, + IdCardType = source.IdCardType, + GenderName = genderMap.TryGetValue(source.Gender, out var genderName) ? genderName : "", + PhoneNumber = dataProtector.SafeDecryptCustomerData(source.PhoneNumber), DateOfBirth = source.DateOfBirth.ToDateTime(TimeOnly.MinValue), CustomerType = source.CustomerType, CustomerTypeName = custoTypeMap.TryGetValue(source.CustomerType, out var customerTypeName) ? customerTypeName : "", - PassportName = passPortTypeMap.TryGetValue(source.PassportId, out var passportName) ? passportName : "", + PassportName = passPortTypeMap.TryGetValue(source.IdCardType, out var passportName) ? passportName : "", IdCardNumber = dataProtector.SafeDecryptCustomerData(source.IdCardNumber), - CustomerAddress = source.CustomerAddress ?? "", + Address = source.Address ?? "", DataInsUsr = source.DataInsUsr, DataInsDate = source.DataInsDate, DataChgUsr = source.DataChgUsr, @@ -455,17 +454,17 @@ namespace EOM.TSHotelManagement.Service return new SingleOutputDto { Code = BusinessStatusCode.InternalServerError, Message = "该用户不存在" }; } + singleOutputDto.Data = EntityMapper.Map(customer); + //解密身份证号码/联系方式(失败时回退原值) - customer.IdCardNumber = dataProtector.SafeDecryptCustomerData(customer.IdCardNumber); - customer.CustomerPhoneNumber = dataProtector.SafeDecryptCustomerData(customer.CustomerPhoneNumber); + singleOutputDto.Data.IdCardNumber = dataProtector.SafeDecryptCustomerData(customer.IdCardNumber); + singleOutputDto.Data.PhoneNumber = dataProtector.SafeDecryptCustomerData(customer.PhoneNumber); //性别类型 - customer.GenderName = genderMap.TryGetValue((int)customer.CustomerGender!, out var genderName) ? genderName : ""; + singleOutputDto.Data.GenderName = genderMap.TryGetValue((int)customer.Gender!, out var genderName) ? genderName : ""; //证件类型 - customer.PassportName = passPortTypeMap.TryGetValue(customer.PassportId, out var passportName) ? passportName : ""; + singleOutputDto.Data.PassportName = passPortTypeMap.TryGetValue(customer.IdCardType, out var passportName) ? passportName : ""; //客户类型 - customer.CustomerTypeName = custoTypeMap.TryGetValue(customer.CustomerType, out var customerTypeName) ? customerTypeName : ""; - - singleOutputDto.Data = EntityMapper.Map(customer); + singleOutputDto.Data.CustomerTypeName = custoTypeMap.TryGetValue(customer.CustomerType, out var customerTypeName) ? customerTypeName : ""; return singleOutputDto; } diff --git a/EOM.TSHotelManagement.Service/Business/Customer/Permission/CustomerPermissionService.cs b/EOM.TSHotelManagement.Service/Business/Customer/Permission/CustomerPermissionService.cs index 02fa017dbe4b4a772e080dc501452a96b1ac901e..421b42a33ba8b15f30e1c1ad39cba53da6442782 100644 --- a/EOM.TSHotelManagement.Service/Business/Customer/Permission/CustomerPermissionService.cs +++ b/EOM.TSHotelManagement.Service/Business/Customer/Permission/CustomerPermissionService.cs @@ -19,6 +19,7 @@ namespace EOM.TSHotelManagement.Service private readonly GenericRepository userRoleRepository; private readonly GenericRepository rolePermissionRepository; private readonly GenericRepository permissionRepository; + private readonly GenericRepository menuRepository; private readonly GenericRepository roleRepository; public CustomerPermissionService( @@ -26,12 +27,14 @@ namespace EOM.TSHotelManagement.Service GenericRepository userRoleRepository, GenericRepository rolePermissionRepository, GenericRepository permissionRepository, + GenericRepository menuRepository, GenericRepository roleRepository) { this.customerRepository = customerRepository; this.userRoleRepository = userRoleRepository; this.rolePermissionRepository = rolePermissionRepository; this.permissionRepository = permissionRepository; + this.menuRepository = menuRepository; this.roleRepository = roleRepository; } @@ -53,15 +56,15 @@ namespace EOM.TSHotelManagement.Service return new BaseResponse(BusinessStatusCode.NotFound, LocalizationHelper.GetLocalizedString("User not found", "用户不存在")); } - // 软删除当前用户下所有有效的角色绑定 + // 硬删除当前用户下所有有效的角色绑定 var existing = userRoleRepository.AsQueryable() - .Where(x => x.UserNumber == input.UserNumber && x.IsDelete != 1) - .Select(x => new UserRole { UserNumber = x.UserNumber, RoleNumber = x.RoleNumber, IsDelete = 1 }) + .Where(x => x.UserNumber == input.UserNumber) + .Select(x => new UserRole { UserNumber = x.UserNumber, RoleNumber = x.RoleNumber }) .ToList(); foreach (var ur in existing) { - userRoleRepository.SoftDelete(ur); + userRoleRepository.Delete(ur); } // 过滤、去重、忽略空白 @@ -77,8 +80,7 @@ namespace EOM.TSHotelManagement.Service var entity = new UserRole { UserNumber = input.UserNumber, - RoleNumber = role, - IsDelete = 0 + RoleNumber = role }; userRoleRepository.Insert(entity); } @@ -108,7 +110,7 @@ namespace EOM.TSHotelManagement.Service try { var roleNumbers = userRoleRepository.AsQueryable() - .Where(ur => ur.UserNumber == userNumber && ur.IsDelete != 1) + .Where(ur => ur.UserNumber == userNumber) .Select(ur => ur.RoleNumber) .ToList(); @@ -158,7 +160,7 @@ namespace EOM.TSHotelManagement.Service { // 1) 用户 -> 角色 var roleNumbers = userRoleRepository.AsQueryable() - .Where(ur => ur.UserNumber == userNumber && ur.IsDelete != 1) + .Where(ur => ur.UserNumber == userNumber) .Select(ur => ur.RoleNumber) .ToList(); @@ -183,8 +185,10 @@ namespace EOM.TSHotelManagement.Service // 2) 角色 -> 权限编码(RolePermission) var rolePermList = rolePermissionRepository.AsQueryable() - .Where(rp => rp.IsDelete != 1 && roleNumbers.Contains(rp.RoleNumber)) - .Select(rp => new { rp.RoleNumber, rp.PermissionNumber }) + .Where(rp => roleNumbers.Contains(rp.RoleNumber) + && rp.PermissionNumber != null + && rp.PermissionNumber != "") + .Select(rp => new { rp.RoleNumber, rp.PermissionNumber, rp.MenuId }) .ToList(); var permNumbers = rolePermList @@ -194,30 +198,61 @@ namespace EOM.TSHotelManagement.Service .ToList(); // 3) 权限详情(Permission) - var permInfo = new Dictionary(StringComparer.OrdinalIgnoreCase); + var permInfo = new Dictionary(StringComparer.OrdinalIgnoreCase); if (permNumbers.Count > 0) { var info = permissionRepository.AsQueryable() - .Where(p => p.IsDelete != 1 && permNumbers.Contains(p.PermissionNumber)) - .Select(p => new { p.PermissionNumber, p.PermissionName, p.MenuKey }) + .Where(p => permNumbers.Contains(p.PermissionNumber)) + .Select(p => new { p.PermissionNumber, p.PermissionName }) .ToList(); foreach (var p in info) { - permInfo[p.PermissionNumber] = (p.PermissionName, p.MenuKey ?? string.Empty); + permInfo[p.PermissionNumber] = p.PermissionName; } } // 4) 组装输出 + var menuIds = rolePermList + .Where(x => x.MenuId.HasValue && x.MenuId.Value > 0) + .Select(x => x.MenuId!.Value) + .Distinct() + .ToList(); + + var menuInfo = new Dictionary(); + if (menuIds.Count > 0) + { + var menus = menuRepository.AsQueryable() + .Where(m => m.IsDelete != 1 && menuIds.Contains(m.Id)) + .Select(m => new { m.Id, m.Key, m.Title }) + .ToList(); + + foreach (var m in menus) + { + menuInfo[m.Id] = (m.Key ?? string.Empty, m.Title ?? string.Empty); + } + } + var resultItems = rolePermList.Select(x => { - permInfo.TryGetValue(x.PermissionNumber, out var meta); + permInfo.TryGetValue(x.PermissionNumber!, out var permName); + var menuId = x.MenuId; + var menuKey = string.Empty; + var menuName = string.Empty; + if (menuId.HasValue && menuInfo.TryGetValue(menuId.Value, out var menuMeta)) + { + menuKey = menuMeta.Key; + menuName = menuMeta.Name; + } + return new UserRolePermissionOutputDto { RoleNumber = x.RoleNumber, - PermissionNumber = x.PermissionNumber, - PermissionName = meta.Name, - MenuKey = meta.MenuKey + PermissionNumber = x.PermissionNumber!, + PermissionName = permName, + MenuId = menuId, + MenuKey = menuKey, + MenuName = menuName }; }).ToList(); @@ -281,15 +316,13 @@ namespace EOM.TSHotelManagement.Service roleRepository.Insert(role); } - // 软删除当前专属角色下所有有效的角色-权限绑定 + // 硬删除当前专属角色下所有有效的角色-权限绑定 var existing = rolePermissionRepository.AsQueryable() - .Where(x => x.RoleNumber == userRoleNumber && x.IsDelete != 1) - .Select(x => new RolePermission { RoleNumber = x.RoleNumber, PermissionNumber = x.PermissionNumber, IsDelete = 1 }) + .Where(x => x.RoleNumber == userRoleNumber) .ToList(); - - foreach (var rp in existing) + if (existing.Count > 0) { - rolePermissionRepository.SoftDelete(rp); + rolePermissionRepository.Delete(existing); } // 过滤、去重、忽略空白 @@ -303,7 +336,7 @@ namespace EOM.TSHotelManagement.Service { // 仅保留系统中存在的权限码 var validPerms = permissionRepository.AsQueryable() - .Where(p => p.IsDelete != 1 && perms.Contains(p.PermissionNumber)) + .Where(p => perms.Contains(p.PermissionNumber)) .Select(p => p.PermissionNumber) .ToList(); @@ -312,22 +345,20 @@ namespace EOM.TSHotelManagement.Service var entity = new RolePermission { RoleNumber = userRoleNumber, - PermissionNumber = pnum, - IsDelete = 0 + PermissionNumber = pnum }; rolePermissionRepository.Insert(entity); } } // 确保用户与专属角色绑定存在 - var hasBinding = userRoleRepository.IsAny(ur => ur.UserNumber == input.UserNumber && ur.RoleNumber == userRoleNumber && ur.IsDelete != 1); + var hasBinding = userRoleRepository.IsAny(ur => ur.UserNumber == input.UserNumber && ur.RoleNumber == userRoleNumber); if (!hasBinding) { userRoleRepository.Insert(new UserRole { UserNumber = input.UserNumber, - RoleNumber = userRoleNumber, - IsDelete = 0 + RoleNumber = userRoleNumber }); } @@ -357,7 +388,7 @@ namespace EOM.TSHotelManagement.Service { var roleNumber = $"R-USER-{userNumber}"; var list = rolePermissionRepository.AsQueryable() - .Where(rp => rp.RoleNumber == roleNumber && rp.IsDelete != 1) + .Where(rp => rp.RoleNumber == roleNumber) .Select(rp => rp.PermissionNumber) .ToList(); @@ -381,4 +412,4 @@ namespace EOM.TSHotelManagement.Service } } } -} \ No newline at end of file +} diff --git a/EOM.TSHotelManagement.Service/Business/Reser/ReserService.cs b/EOM.TSHotelManagement.Service/Business/Reser/ReserService.cs index 888c7e0eb59d27c639973223fcece540b03c14a2..23f86b865482ce4689831064b43c8fb9ff0a6de5 100644 --- a/EOM.TSHotelManagement.Service/Business/Reser/ReserService.cs +++ b/EOM.TSHotelManagement.Service/Business/Reser/ReserService.cs @@ -184,7 +184,7 @@ namespace EOM.TSHotelManagement.Service .ToList(); Reser res = null; - res = reserRepository.GetFirst(a => a.ReservationRoomNumber == readReserInputDt.ReservationRoomNumber && a.IsDelete != 1); + res = reserRepository.GetFirst(a => a.ReservationRoomNumber == readReserInputDt.ReservationRoomNumber && a.ReservationStatus == 0 && a.IsDelete != 1); //解密联系方式 var sourceTelStr = dataProtector.SafeDecryptReserData(res.ReservationPhoneNumber); res.ReservationPhoneNumber = sourceTelStr; diff --git a/EOM.TSHotelManagement.Service/Business/Room/RoomService.cs b/EOM.TSHotelManagement.Service/Business/Room/RoomService.cs index c32440a4b44173882417295604260679207949e1..9fff45ffaa8117693ccb770a0eb4df63ee9bccfc 100644 --- a/EOM.TSHotelManagement.Service/Business/Room/RoomService.cs +++ b/EOM.TSHotelManagement.Service/Business/Room/RoomService.cs @@ -192,7 +192,7 @@ namespace EOM.TSHotelManagement.Service .Where(a => a.IsDelete != 1 && customerNumbers.Contains(a.CustomerNumber)) .ToList() .GroupBy(a => a.CustomerNumber) - .ToDictionary(g => g.Key, g => g.FirstOrDefault()?.CustomerName ?? "", StringComparer.OrdinalIgnoreCase); + .ToDictionary(g => g.Key, g => g.FirstOrDefault()?.Name ?? "", StringComparer.OrdinalIgnoreCase); } var helper = new EnumHelper(); @@ -705,7 +705,7 @@ namespace EOM.TSHotelManagement.Service }, a => a.CustomerNumber == transferRoomDto.CustomerNumber); } - var customerType = custoTypeRepository.GetFirst(a => a.CustomerType == customer.CustomerType); + var customerType = custoTypeRepository.GetFirst(a => a.CustomerType == customer.CustomerType && a.IsDelete != 1); if (customerType.IsNullOrEmpty()) return new BaseResponse { Message = LocalizationHelper.GetLocalizedString("The customer type does not exist", "客户类型不存在"), Code = BusinessStatusCode.InternalServerError }; @@ -801,9 +801,14 @@ namespace EOM.TSHotelManagement.Service return new BaseResponse { Message = LocalizationHelper.GetLocalizedString("The customer does not exist", "客户不存在"), Code = BusinessStatusCode.InternalServerError }; var room = roomRepository.GetFirst(a => a.RoomNumber == checkoutRoomDto.RoomNumber); + + var checkinDate = room.LastCheckInTime; + var checkoutDate = room.LastCheckOutTime; + //更新房间状态 room.CustomerNumber = string.Empty; - room.LastCheckOutTime = DateOnly.FromDateTime(DateTime.Now); + room.LastCheckInTime = DateOnly.MinValue; + room.LastCheckOutTime = DateOnly.MinValue; room.RoomStateId = (int)RoomState.Dirty; var roomUpdateResult = roomRepository.Update(room); if (!roomUpdateResult) @@ -815,14 +820,14 @@ namespace EOM.TSHotelManagement.Service var energy = new EnergyManagement { InformationId = uniqueCode.GetNewId("EM-"), - StartDate = (DateOnly)room.LastCheckInTime, - EndDate = DateOnly.FromDateTime((DateTime)checkoutRoomDto.DataChgDate), + StartDate = checkinDate ?? DateOnly.MinValue, + EndDate = DateOnly.FromDateTime(DateTime.Today), WaterUsage = checkoutRoomDto.WaterUsage, PowerUsage = checkoutRoomDto.ElectricityUsage, - Recorder = checkoutRoomDto.DataChgUsr, + Recorder = "System", CustomerNumber = room.CustomerNumber, RoomNumber = checkoutRoomDto.RoomNumber, - IsDelete = 0 + IsDelete = 0, }; energyRepository.Insert(energy); @@ -846,6 +851,34 @@ namespace EOM.TSHotelManagement.Service } } + // 插入住房消费记录 + var staySpan = DateTime.Now - room.LastCheckInTime.Value.ToDateTime(TimeOnly.MinValue); + var stayDays = Math.Max((int)Math.Ceiling(staySpan.TotalDays), 1); + var customerType = custoTypeRepository.GetSingle(a => a.CustomerType == customer.First().CustomerType && a.IsDelete != 1); + if (customerType.IsNullOrEmpty()) + return new BaseResponse { Message = LocalizationHelper.GetLocalizedString("The customer type does not exist", "客户类型不存在"), Code = BusinessStatusCode.InternalServerError }; + + decimal discount = (customerType != null && customerType.Discount > 0 && customerType.Discount < 100) + ? customerType.Discount / 100M + : 1M; + decimal roomBill = room.RoomRent * stayDays * discount; + var bill = new Spend + { + SpendNumber = uniqueCode.GetNewId("SP-"), + ProductName = $"居住 {checkoutRoomDto.RoomNumber} 共 {stayDays} 天", + SettlementStatus = ConsumptionConstant.Settled.Code, + ConsumptionType = SpendTypeConstant.Room.Code, + ConsumptionQuantity = stayDays, + ConsumptionTime = checkinDate.Value.ToDateTime(TimeOnly.MinValue), + ProductNumber = room.RoomNumber, + ProductPrice = room.RoomRent, + ConsumptionAmount = roomBill, + CustomerNumber = room.CustomerNumber, + RoomNumber = checkoutRoomDto.RoomNumber, + IsDelete = 0, + }; + spendRepository.Insert(bill); + scope.Complete(); } } @@ -871,12 +904,12 @@ namespace EOM.TSHotelManagement.Service var customer = new Customer { CustomerNumber = checkinRoomByReservationDto.CustomerNumber, - CustomerName = checkinRoomByReservationDto.CustomerName, - CustomerGender = checkinRoomByReservationDto.CustomerGender, - CustomerPhoneNumber = checkinRoomByReservationDto.CustomerPhoneNumber, - PassportId = checkinRoomByReservationDto.PassportId, + Name = checkinRoomByReservationDto.CustomerName, + Gender = checkinRoomByReservationDto.CustomerGender ?? 0, + PhoneNumber = checkinRoomByReservationDto.CustomerPhoneNumber, + IdCardType = checkinRoomByReservationDto.PassportId, IdCardNumber = checkinRoomByReservationDto.IdCardNumber, - CustomerAddress = checkinRoomByReservationDto.CustomerAddress, + Address = checkinRoomByReservationDto.CustomerAddress, DateOfBirth = checkinRoomByReservationDto.DateOfBirth, CustomerType = checkinRoomByReservationDto.CustomerType, IsDelete = 0, @@ -901,6 +934,7 @@ namespace EOM.TSHotelManagement.Service } var reser = reserRepository.GetFirst(a => a.ReservationId == checkinRoomByReservationDto.ReservationId && a.IsDelete != 1); + reser.ReservationStatus = 1; reser.IsDelete = 1; var reserUpdateResult = reserRepository.Update(reser); diff --git a/EOM.TSHotelManagement.Service/Business/Spend/ISpendService.cs b/EOM.TSHotelManagement.Service/Business/Spend/ISpendService.cs index bd9d152066a23999347526f525d71bb39bef3b2b..e94eb7232c1d3013475ac42be9394adbbd873ad9 100644 --- a/EOM.TSHotelManagement.Service/Business/Spend/ISpendService.cs +++ b/EOM.TSHotelManagement.Service/Business/Spend/ISpendService.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -68,9 +68,9 @@ namespace EOM.TSHotelManagement.Service /// /// 撤回客户消费信息 /// - /// + /// /// - BaseResponse UndoCustomerSpend(UpdateSpendInputDto updateSpendInputDto); + BaseResponse UndoCustomerSpend(UndoCustomerSpendInputDto undoCustomerSpendInputDto); /// /// 添加客户消费信息 @@ -86,4 +86,4 @@ namespace EOM.TSHotelManagement.Service /// BaseResponse UpdSpendInfo(UpdateSpendInputDto updateSpendInputDto); } -} \ No newline at end of file +} diff --git a/EOM.TSHotelManagement.Service/Business/Spend/SpendService.cs b/EOM.TSHotelManagement.Service/Business/Spend/SpendService.cs index 1fb1e461ea618bd5f4d50b8197efcc113570d41d..65eb0d6d93d043e47fabe15416986735d8afcd5b 100644 --- a/EOM.TSHotelManagement.Service/Business/Spend/SpendService.cs +++ b/EOM.TSHotelManagement.Service/Business/Spend/SpendService.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -276,24 +276,76 @@ namespace EOM.TSHotelManagement.Service /// /// 撤回客户消费信息 /// - /// + /// /// - public BaseResponse UndoCustomerSpend(UpdateSpendInputDto updateSpendInputDto) + public BaseResponse UndoCustomerSpend(UndoCustomerSpendInputDto undoCustomerSpendInputDto) { + var httpContext = _httpContextAccessor.HttpContext; + using var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled); + try { - var existingSpend = spendRepository.GetFirst(a => a.SpendNumber == updateSpendInputDto.SpendNumber && a.IsDelete != 1); + var existingSpend = spendRepository.GetFirst(a => a.Id == undoCustomerSpendInputDto.Id && a.IsDelete != 1); if (existingSpend == null) { return new BaseResponse(BusinessStatusCode.NotFound, LocalizationHelper.GetLocalizedString("Spend record not found", "消费记录不存在")); } + + if (existingSpend.ConsumptionType != SpendTypeConstant.Product.Code) + { + return new BaseResponse(BusinessStatusCode.BadRequest, LocalizationHelper.GetLocalizedString("Cancellation of non-commodity consumption records is not allowed", "不允许撤销非商品消费记录")); + } + + var isProductSpend = string.Equals(existingSpend.ConsumptionType, SpendTypeConstant.Product.Code, StringComparison.OrdinalIgnoreCase) + && !string.IsNullOrWhiteSpace(existingSpend.ProductNumber) + && existingSpend.ConsumptionQuantity > 0; + + if (isProductSpend) + { + var product = sellThingRepository.GetFirst(a => a.ProductNumber == existingSpend.ProductNumber && a.IsDelete != 1); + if (product == null) + { + return new BaseResponse(BusinessStatusCode.NotFound, LocalizationHelper.GetLocalizedString("Product not found", "商品不存在")); + } + + product.Stock += existingSpend.ConsumptionQuantity; + var productUpdateResult = sellThingRepository.Update(product); + if (!productUpdateResult) + { + return BaseResponseFactory.ConcurrencyConflict(); + } + } + existingSpend.IsDelete = 1; - existingSpend.RowVersion = updateSpendInputDto.RowVersion ?? 0; + existingSpend.RowVersion = undoCustomerSpendInputDto.RowVersion ?? 0; var updateResult = spendRepository.Update(existingSpend); if (!updateResult) { return BaseResponseFactory.ConcurrencyConflict(); } + + var logContent = $"{ClaimsPrincipalExtensions.GetUserNumber(httpContext.User)} 撤销了消费记录: " + + $"房间 {existingSpend.RoomNumber}, " + + $"商品 {existingSpend.ProductName}, " + + $"数量 {existingSpend.ConsumptionQuantity}, " + + $"金额 {existingSpend.ConsumptionAmount.ToString("#,##0.00")}"; + + var context = _httpContextAccessor.HttpContext; + + var log = new OperationLog + { + OperationId = new UniqueCode().GetNewId("OP-"), + OperationTime = Convert.ToDateTime(DateTime.Now), + LogContent = logContent, + LoginIpAddress = context.Connection.RemoteIpAddress?.ToString() ?? string.Empty, + OperationAccount = ClaimsPrincipalExtensions.GetUserNumber(httpContext.User), + LogLevel = (int)Common.LogLevel.Warning, + SoftwareVersion = SoftwareVersionHelper.GetSoftwareVersion(), + }; + operationLogRepository.Insert(log); + + + scope.Complete(); } catch (Exception ex) { @@ -310,7 +362,8 @@ namespace EOM.TSHotelManagement.Service /// public BaseResponse AddCustomerSpend(AddCustomerSpendInputDto addCustomerSpendInputDto) { - if (addCustomerSpendInputDto?.Quantity <= 0 || addCustomerSpendInputDto.Price <= 0) + var httpContext = _httpContextAccessor.HttpContext; + if (addCustomerSpendInputDto?.ConsumptionQuantity <= 0 || addCustomerSpendInputDto.ProductPrice <= 0) { return new BaseResponse() { Message = "商品数量和价格必须大于零", Code = BusinessStatusCode.BadRequest }; } @@ -336,17 +389,15 @@ namespace EOM.TSHotelManagement.Service ? customerType.Discount / 100M : 1M; - decimal realAmount = addCustomerSpendInputDto.Price * addCustomerSpendInputDto.Quantity * discount; + decimal realAmount = addCustomerSpendInputDto.ProductPrice * addCustomerSpendInputDto.ConsumptionQuantity * discount; var existingSpend = spendRepository.AsQueryable().Single(a => a.RoomNumber == addCustomerSpendInputDto.RoomNumber && a.ProductNumber == addCustomerSpendInputDto.ProductNumber && a.IsDelete != 1 && a.SettlementStatus == ConsumptionConstant.UnSettle.Code); if (existingSpend != null) { existingSpend.ConsumptionType = SpendTypeConstant.Product.Code; - existingSpend.ConsumptionQuantity += addCustomerSpendInputDto.Quantity; + existingSpend.ConsumptionQuantity += addCustomerSpendInputDto.ConsumptionQuantity; existingSpend.ConsumptionAmount += realAmount; - existingSpend.DataChgDate = DateTime.Now; - existingSpend.DataChgUsr = addCustomerSpendInputDto.WorkerNo; var result = spendRepository.Update(existingSpend); if (!result) @@ -362,15 +413,13 @@ namespace EOM.TSHotelManagement.Service RoomNumber = addCustomerSpendInputDto.RoomNumber, ProductNumber = addCustomerSpendInputDto.ProductNumber, ProductName = addCustomerSpendInputDto.ProductName, - ConsumptionQuantity = addCustomerSpendInputDto.Quantity, + ConsumptionQuantity = addCustomerSpendInputDto.ConsumptionQuantity, CustomerNumber = room.CustomerNumber, - ProductPrice = addCustomerSpendInputDto.Price, + ProductPrice = addCustomerSpendInputDto.ProductPrice, ConsumptionAmount = realAmount, ConsumptionTime = DateTime.Now, ConsumptionType = SpendTypeConstant.Product.Code, - SettlementStatus = ConsumptionConstant.UnSettle.Code, - DataInsUsr = addCustomerSpendInputDto.WorkerNo, - DataInsDate = DateTime.Now + SettlementStatus = ConsumptionConstant.UnSettle.Code }; var result = spendRepository.Insert(newSpend); @@ -381,17 +430,17 @@ namespace EOM.TSHotelManagement.Service } var product = sellThingRepository.AsQueryable().Single(a => a.ProductNumber == addCustomerSpendInputDto.ProductNumber); - product.Stock = product.Stock - addCustomerSpendInputDto.Quantity; + product.Stock = product.Stock - addCustomerSpendInputDto.ConsumptionQuantity; var updateResult = sellThingRepository.Update(product); if (!updateResult) { return BaseResponseFactory.ConcurrencyConflict(); } - var logContent = $"{addCustomerSpendInputDto.WorkerNo} 添加了消费记录: " + + var logContent = $"{ClaimsPrincipalExtensions.GetUserNumber(httpContext.User)} 添加了消费记录: " + $"房间 {addCustomerSpendInputDto.RoomNumber}, " + $"商品 {addCustomerSpendInputDto.ProductName}, " + - $"数量 {addCustomerSpendInputDto.Quantity}, " + + $"数量 {addCustomerSpendInputDto.ConsumptionQuantity}, " + $"金额 {realAmount.ToString("#,##0.00")}"; var context = _httpContextAccessor.HttpContext; @@ -402,12 +451,9 @@ namespace EOM.TSHotelManagement.Service OperationTime = Convert.ToDateTime(DateTime.Now), LogContent = logContent, LoginIpAddress = context.Connection.RemoteIpAddress?.ToString() ?? string.Empty, - OperationAccount = addCustomerSpendInputDto.WorkerNo, + OperationAccount = ClaimsPrincipalExtensions.GetUserNumber(httpContext.User), LogLevel = (int)Common.LogLevel.Warning, - SoftwareVersion = addCustomerSpendInputDto.SoftwareVersion, - IsDelete = 0, - DataInsUsr = addCustomerSpendInputDto.WorkerNo, - DataInsDate = Convert.ToDateTime(DateTime.Now) + SoftwareVersion = SoftwareVersionHelper.GetSoftwareVersion(), }; operationLogRepository.Insert(log); diff --git a/EOM.TSHotelManagement.Service/Dashboard/DashboardService.cs b/EOM.TSHotelManagement.Service/Dashboard/DashboardService.cs index 1517faa73d973d00bf2b3a26e92956db06e679b6..5248f942f9867c04a2aa69d867770b0da66beeed 100644 --- a/EOM.TSHotelManagement.Service/Dashboard/DashboardService.cs +++ b/EOM.TSHotelManagement.Service/Dashboard/DashboardService.cs @@ -1,4 +1,4 @@ -using EOM.TSHotelManagement.Common; +using EOM.TSHotelManagement.Common; using EOM.TSHotelManagement.Contract; using EOM.TSHotelManagement.Data; using EOM.TSHotelManagement.Domain; @@ -116,7 +116,7 @@ namespace EOM.TSHotelManagement.Service var roomTypes = roomTypeRepository.AsQueryable().Where(a => a.IsDelete != 1).ToList(); var resers = reserRepository.AsQueryable() - .Where(a => a.IsDelete != 1).ToList(); + .Where(a => a.ReservationStatus == 0).ToList(); var roomStateData = roomRepository.AsQueryable().Where(a => roomStates.Select(b => b.Id).ToList().Contains(a.RoomStateId)).ToList(); @@ -207,8 +207,8 @@ namespace EOM.TSHotelManagement.Service businessStatisticsOutputDto.GenderRatio = new TempGenderRatio { - Male = customers.Count(a => a.CustomerGender == (int)GenderType.Male), - Female = customers.Count(a => a.CustomerGender == (int)GenderType.Female) + Male = customers.Count(a => a.Gender == (int)GenderType.Male), + Female = customers.Count(a => a.Gender == (int)GenderType.Female) }; var memberTypeDict = customerTypes.ToDictionary(rt => rt.CustomerType, rt => rt.CustomerTypeName); diff --git a/EOM.TSHotelManagement.Service/EOM.TSHotelManagement.Service.csproj b/EOM.TSHotelManagement.Service/EOM.TSHotelManagement.Service.csproj index be64ba7f1203062da366e1a9b60b73ac61d5f349..0a7c44b825306868ed2f9c9343d595ac1638fd30 100644 --- a/EOM.TSHotelManagement.Service/EOM.TSHotelManagement.Service.csproj +++ b/EOM.TSHotelManagement.Service/EOM.TSHotelManagement.Service.csproj @@ -26,7 +26,7 @@ - + diff --git a/EOM.TSHotelManagement.Service/Employee/Check/EmployeeCheckService.cs b/EOM.TSHotelManagement.Service/Employee/Check/EmployeeCheckService.cs index 82e0d9a79be2bfb01830964f61d206713ffab6cc..13f6eae0731c9650a26275aa45bccb46ba202ec6 100644 --- a/EOM.TSHotelManagement.Service/Employee/Check/EmployeeCheckService.cs +++ b/EOM.TSHotelManagement.Service/Employee/Check/EmployeeCheckService.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -25,6 +25,8 @@ using EOM.TSHotelManagement.Common; using EOM.TSHotelManagement.Contract; using EOM.TSHotelManagement.Data; using EOM.TSHotelManagement.Domain; +using jvncorelib.CodeLib; +using Microsoft.Extensions.Logging; namespace EOM.TSHotelManagement.Service { @@ -39,12 +41,14 @@ namespace EOM.TSHotelManagement.Service private readonly GenericRepository workerCheckRepository; /// - /// + /// 唯一编码 /// - /// - public EmployeeCheckService(GenericRepository workerCheckRepository) + private readonly UniqueCode uniqueCode; + + public EmployeeCheckService(GenericRepository workerCheckRepository, UniqueCode uniqueCode) { this.workerCheckRepository = workerCheckRepository; + this.uniqueCode = uniqueCode; } /// @@ -60,7 +64,7 @@ namespace EOM.TSHotelManagement.Service var count = 0; - if (wid.Page != 0 && wid.PageSize != 0) + if (!wid.IgnorePaging) { workerChecks = workerCheckRepository.AsQueryable().Where(where.ToExpression()) .OrderByDescending(a => a.CheckTime) @@ -172,18 +176,85 @@ namespace EOM.TSHotelManagement.Service { try { - var entity = EntityMapper.Map(workerCheck); + if (workerCheck == null || string.IsNullOrWhiteSpace(workerCheck.EmployeeId)) + { + return new BaseResponse + { + Message = LocalizationHelper.GetLocalizedString( + "Employee ID is required.", + "员工工号为必填字段" + ), + Code = BusinessStatusCode.InternalServerError + }; + } + + var employeeId = workerCheck.EmployeeId.Trim(); + var now = DateTime.Now; + var isMorningShift = now.Hour < 12; + + var shiftStart = isMorningShift + ? now.Date + : now.Date.AddHours(12); + + var shiftEnd = isMorningShift + ? now.Date.AddHours(12) + : now.Date.AddDays(1); + + var shiftStatus = isMorningShift ? 0 : 1; + var shiftName = isMorningShift ? "早班" : "晚班"; + + var alreadyChecked = workerCheckRepository.IsAny(x => + x.EmployeeId == employeeId && + x.CheckStatus == shiftStatus && + x.CheckTime >= shiftStart && + x.CheckTime < shiftEnd + ); + + if (alreadyChecked) + { + return new BaseResponse + { + Message = LocalizationHelper.GetLocalizedString( + $"{shiftName} already checked in.", + $"{shiftName}已打卡" + ), + Code = BusinessStatusCode.InternalServerError + }; + } + + var entity = new EmployeeCheck + { + CheckNumber = uniqueCode.GetNewId("CK-"), + EmployeeId = employeeId, + CheckTime = now, + CheckMethod = CheckTypeConstant.Web.Code, + CheckStatus = shiftStatus + }; + var result = workerCheckRepository.Insert(entity); if (!result) { - return new BaseResponse { Message = LocalizationHelper.GetLocalizedString("insert employee check failed.", "员工打卡添加失败"), Code = BusinessStatusCode.InternalServerError }; + return new BaseResponse + { + Message = LocalizationHelper.GetLocalizedString( + "insert employee check failed.", + "员工打卡添加失败" + ), + Code = BusinessStatusCode.InternalServerError + }; } + + return new BaseResponse(); } catch (Exception ex) { - return new BaseResponse { Message = LocalizationHelper.GetLocalizedString(ex.Message, ex.Message), Code = BusinessStatusCode.InternalServerError }; + return new BaseResponse + { + Message = LocalizationHelper.GetLocalizedString(ex.Message, ex.Message), + Code = BusinessStatusCode.InternalServerError + }; } - return new BaseResponse(); } + } } diff --git a/EOM.TSHotelManagement.Service/Employee/EmployeeService.cs b/EOM.TSHotelManagement.Service/Employee/EmployeeService.cs index 205f18924d32a39375da08fdc0a64a19a2d9800e..59ed29912fe3020295a1dbdfc49632ae663c2e80 100644 --- a/EOM.TSHotelManagement.Service/Employee/EmployeeService.cs +++ b/EOM.TSHotelManagement.Service/Employee/EmployeeService.cs @@ -194,7 +194,7 @@ namespace EOM.TSHotelManagement.Service var newPassword = new RandomStringGenerator().GenerateSecurePassword(); sourcePwdStr = dataProtector.EncryptEmployeeData(newPassword); - var emailTemplate = EmailTemplate.GetNewRegistrationTemplate(createEmployeeInputDto.EmployeeName, newPassword); + var emailTemplate = EmailTemplate.GetNewRegistrationTemplate(createEmployeeInputDto.Name, newPassword); var result = mailHelper.SendMail(new List { createEmployeeInputDto.EmailAddress }, emailTemplate.Subject, emailTemplate.Body, new List { createEmployeeInputDto.EmailAddress }); if (!result) { @@ -284,7 +284,7 @@ namespace EOM.TSHotelManagement.Service { Id = source.Id, EmployeeId = source.EmployeeId, - EmployeeName = source.EmployeeName, + Name = source.Name, Gender = source.Gender, GenderName = genderMap.TryGetValue(source.Gender, out var genderName) ? genderName : "", DateOfBirth = source.DateOfBirth.ToDateTime(TimeOnly.MinValue), @@ -328,7 +328,7 @@ namespace EOM.TSHotelManagement.Service { Id = source.Id, EmployeeId = source.EmployeeId, - EmployeeName = source.EmployeeName, + Name = source.Name, Gender = source.Gender, GenderName = genderMap.TryGetValue(source.Gender, out var genderName) ? genderName : "", DateOfBirth = source.DateOfBirth.ToDateTime(TimeOnly.MinValue), @@ -392,33 +392,34 @@ namespace EOM.TSHotelManagement.Service }) .ToList(); w = workerRepository.GetFirst(a => a.EmployeeId == readEmployeeInputDto.EmployeeId); + + var source = EntityMapper.Map(w); + //解密身份证号码 var sourceStr = w.IdCardNumber.IsNullOrEmpty() ? "" : dataProtector.SafeDecryptEmployeeData(w.IdCardNumber); - w.IdCardNumber = sourceStr; + source.IdCardNumber = sourceStr; //解密联系方式 var sourceTelStr = w.PhoneNumber.IsNullOrEmpty() ? "" : dataProtector.SafeDecryptEmployeeData(w.PhoneNumber); - w.PhoneNumber = sourceTelStr; + source.PhoneNumber = sourceTelStr; //性别类型 - var sexType = genders.SingleOrDefault(a => a.Id == w.Gender); - w.GenderName = sexType.Description.IsNullOrEmpty() ? "" : sexType.Description; + var genderType = genders.SingleOrDefault(a => a.Id == w.Gender); + source.GenderName = genderType.Description.IsNullOrEmpty() ? "" : genderType.Description; //教育程度 var eduction = educationRepository.GetFirst(a => a.EducationNumber == w.EducationLevel); - w.EducationLevelName = eduction.EducationName.IsNullOrEmpty() ? "" : eduction.EducationName; + source.EducationLevelName = eduction.EducationName.IsNullOrEmpty() ? "" : eduction.EducationName; //民族类型 var nation = nationRepository.GetFirst(a => a.NationNumber == w.Ethnicity); - w.EthnicityName = nation.NationName.IsNullOrEmpty() ? "" : nation.NationName; + source.EthnicityName = nation.NationName.IsNullOrEmpty() ? "" : nation.NationName; //部门 var dept = deptRepository.GetFirst(a => a.DepartmentNumber == w.Department); - w.DepartmentName = dept.DepartmentName.IsNullOrEmpty() ? "" : dept.DepartmentName; + source.DepartmentName = dept.DepartmentName.IsNullOrEmpty() ? "" : dept.DepartmentName; //职位 var position = positionRepository.GetFirst(a => a.PositionNumber == w.Position); - w.PositionName = position.PositionName.IsNullOrEmpty() ? "" : position.PositionName; + source.PositionName = position.PositionName.IsNullOrEmpty() ? "" : position.PositionName; var passport = passportTypeRepository.GetFirst(a => a.PassportId == w.IdCardType); - w.IdCardTypeName = passport.IsNullOrEmpty() ? "" : passport.PassportName; + source.IdCardTypeName = passport.IsNullOrEmpty() ? "" : passport.PassportName; //面貌 - w.PoliticalAffiliationName = new EnumHelper().GetDescriptionByName(w.PoliticalAffiliation); - - var source = EntityMapper.Map(w); + source.PoliticalAffiliationName = new EnumHelper().GetDescriptionByName(w.PoliticalAffiliation); var employeePhoto = photoRepository.GetFirst(a => a.EmployeeId.Equals(source.EmployeeId)); if (employeePhoto != null && !string.IsNullOrEmpty(employeePhoto.PhotoPath)) @@ -470,7 +471,7 @@ namespace EOM.TSHotelManagement.Service Data = new ReadEmployeeOutputDto { EmployeeId = w.EmployeeId, - EmployeeName = w.EmployeeName, + Name = w.Name, RequiresTwoFactor = true } }; @@ -486,7 +487,7 @@ namespace EOM.TSHotelManagement.Service Data = new ReadEmployeeOutputDto { EmployeeId = w.EmployeeId, - EmployeeName = w.EmployeeName, + Name = w.Name, RequiresTwoFactor = true } }; @@ -494,33 +495,35 @@ namespace EOM.TSHotelManagement.Service } w.Password = ""; + + var output = EntityMapper.Map(w); + //性别类型 - var sexType = genders.SingleOrDefault(a => a.Id == w.Gender); - w.GenderName = sexType.Description.IsNullOrEmpty() ? "" : sexType.Description; + var genderType = genders.SingleOrDefault(a => a.Id == w.Gender); + output.GenderName = genderType.Description.IsNullOrEmpty() ? "" : genderType.Description; //教育程度 var eduction = educationRepository.GetFirst(a => a.EducationNumber == w.EducationLevel); - w.EducationLevelName = eduction.EducationName.IsNullOrEmpty() ? "" : eduction.EducationName; + output.EducationLevelName = eduction.EducationName.IsNullOrEmpty() ? "" : eduction.EducationName; //民族类型 var nation = nationRepository.GetFirst(a => a.NationNumber == w.Ethnicity); - w.EthnicityName = nation.NationName.IsNullOrEmpty() ? "" : nation.NationName; + output.EthnicityName = nation.NationName.IsNullOrEmpty() ? "" : nation.NationName; //部门 var dept = deptRepository.GetFirst(a => a.DepartmentNumber == w.Department); - w.DepartmentName = dept.DepartmentName.IsNullOrEmpty() ? "" : dept.DepartmentName; + output.DepartmentName = dept.DepartmentName.IsNullOrEmpty() ? "" : dept.DepartmentName; //职位 var position = positionRepository.GetFirst(a => a.PositionNumber == w.Position); - w.PositionName = position.PositionName.IsNullOrEmpty() ? "" : position.PositionName; + output.PositionName = position.PositionName.IsNullOrEmpty() ? "" : position.PositionName; - w.UserToken = jWTHelper.GenerateJWT(new ClaimsIdentity(new Claim[] + output.UserToken = jWTHelper.GenerateJWT(new ClaimsIdentity(new Claim[] { - new Claim(ClaimTypes.Name, w.EmployeeName), + new Claim(ClaimTypes.Name, w.Name), new Claim(ClaimTypes.SerialNumber, w.EmployeeId) })); - var output = EntityMapper.Map(w); output.RequiresTwoFactor = false; output.UsedRecoveryCodeLogin = usedRecoveryCode; if (usedRecoveryCode) { - NotifyRecoveryCodeLoginByEmail(w.EmailAddress, w.EmployeeName, w.EmployeeId); + NotifyRecoveryCodeLoginByEmail(w.EmailAddress, w.Name, w.EmployeeId); } return new SingleOutputDto { Data = output }; } @@ -621,7 +624,7 @@ namespace EOM.TSHotelManagement.Service if (!employee.EmailAddress.IsNullOrEmpty()) { - var mailTemplate = EmailTemplate.GetUpdatePasswordTemplate(employee.EmployeeName, newPwd); + var mailTemplate = EmailTemplate.GetUpdatePasswordTemplate(employee.Name, newPwd); mailHelper.SendMail(new List { employee.EmailAddress }, mailTemplate.Subject, mailTemplate.Body, new List { employee.EmailAddress }); } @@ -664,7 +667,7 @@ namespace EOM.TSHotelManagement.Service }; } - var mailTemplate = EmailTemplate.GetResetPasswordTemplate(employee.EmployeeName, newPwd); + var mailTemplate = EmailTemplate.GetResetPasswordTemplate(employee.Name, newPwd); var result = mailHelper.SendMail(new List { emailAddress }, mailTemplate.Subject, mailTemplate.Body, diff --git a/EOM.TSHotelManagement.Service/Employee/Permission/EmployeePermissionService.cs b/EOM.TSHotelManagement.Service/Employee/Permission/EmployeePermissionService.cs index c59a2a8be30667ff0604f2ee1cc8dec3bec44e3f..3ca136ee0435397069e092cb82c8d25e8d027c67 100644 --- a/EOM.TSHotelManagement.Service/Employee/Permission/EmployeePermissionService.cs +++ b/EOM.TSHotelManagement.Service/Employee/Permission/EmployeePermissionService.cs @@ -19,6 +19,7 @@ namespace EOM.TSHotelManagement.Service private readonly GenericRepository userRoleRepository; private readonly GenericRepository rolePermissionRepository; private readonly GenericRepository permissionRepository; + private readonly GenericRepository menuRepository; private readonly GenericRepository roleRepository; public EmployeePermissionService( @@ -26,12 +27,14 @@ namespace EOM.TSHotelManagement.Service GenericRepository userRoleRepository, GenericRepository rolePermissionRepository, GenericRepository permissionRepository, + GenericRepository menuRepository, GenericRepository roleRepository) { this.employeeRepository = employeeRepository; this.userRoleRepository = userRoleRepository; this.rolePermissionRepository = rolePermissionRepository; this.permissionRepository = permissionRepository; + this.menuRepository = menuRepository; this.roleRepository = roleRepository; } @@ -55,8 +58,8 @@ namespace EOM.TSHotelManagement.Service // 软删除当前用户下所有有效的角色绑定 var existing = userRoleRepository.AsQueryable() - .Where(x => x.UserNumber == input.UserNumber && x.IsDelete != 1) - .Select(x => new UserRole { UserNumber = x.UserNumber, RoleNumber = x.RoleNumber, IsDelete = 1 }) + .Where(x => x.UserNumber == input.UserNumber) + .Select(x => new UserRole { UserNumber = x.UserNumber, RoleNumber = x.RoleNumber }) .ToList(); foreach (var ur in existing) @@ -77,8 +80,7 @@ namespace EOM.TSHotelManagement.Service var entity = new UserRole { UserNumber = input.UserNumber, - RoleNumber = role, - IsDelete = 0 + RoleNumber = role }; userRoleRepository.Insert(entity); } @@ -108,7 +110,7 @@ namespace EOM.TSHotelManagement.Service try { var roleNumbers = userRoleRepository.AsQueryable() - .Where(ur => ur.UserNumber == userNumber && ur.IsDelete != 1) + .Where(ur => ur.UserNumber == userNumber) .Select(ur => ur.RoleNumber) .ToList(); @@ -158,7 +160,7 @@ namespace EOM.TSHotelManagement.Service { // 1) 用户 -> 角色 var roleNumbers = userRoleRepository.AsQueryable() - .Where(ur => ur.UserNumber == userNumber && ur.IsDelete != 1) + .Where(ur => ur.UserNumber == userNumber) .Select(ur => ur.RoleNumber) .ToList(); @@ -183,8 +185,10 @@ namespace EOM.TSHotelManagement.Service // 2) 角色 -> 权限编码(RolePermission) var rolePermList = rolePermissionRepository.AsQueryable() - .Where(rp => rp.IsDelete != 1 && roleNumbers.Contains(rp.RoleNumber)) - .Select(rp => new { rp.RoleNumber, rp.PermissionNumber }) + .Where(rp => roleNumbers.Contains(rp.RoleNumber) + && rp.PermissionNumber != null + && rp.PermissionNumber != "") + .Select(rp => new { rp.RoleNumber, rp.PermissionNumber, rp.MenuId }) .ToList(); var permNumbers = rolePermList @@ -194,30 +198,61 @@ namespace EOM.TSHotelManagement.Service .ToList(); // 3) 权限详情(Permission) - var permInfo = new Dictionary(StringComparer.OrdinalIgnoreCase); + var permInfo = new Dictionary(StringComparer.OrdinalIgnoreCase); if (permNumbers.Count > 0) { var info = permissionRepository.AsQueryable() - .Where(p => p.IsDelete != 1 && permNumbers.Contains(p.PermissionNumber)) - .Select(p => new { p.PermissionNumber, p.PermissionName, p.MenuKey }) + .Where(p => permNumbers.Contains(p.PermissionNumber)) + .Select(p => new { p.PermissionNumber, p.PermissionName }) .ToList(); foreach (var p in info) { - permInfo[p.PermissionNumber] = (p.PermissionName, p.MenuKey ?? string.Empty); + permInfo[p.PermissionNumber] = p.PermissionName; } } // 4) 组装输出 + var menuIds = rolePermList + .Where(x => x.MenuId.HasValue && x.MenuId.Value > 0) + .Select(x => x.MenuId!.Value) + .Distinct() + .ToList(); + + var menuInfo = new Dictionary(); + if (menuIds.Count > 0) + { + var menus = menuRepository.AsQueryable() + .Where(m => m.IsDelete != 1 && menuIds.Contains(m.Id)) + .Select(m => new { m.Id, m.Key, m.Title }) + .ToList(); + + foreach (var m in menus) + { + menuInfo[m.Id] = (m.Key ?? string.Empty, m.Title ?? string.Empty); + } + } + var resultItems = rolePermList.Select(x => { - permInfo.TryGetValue(x.PermissionNumber, out var meta); + permInfo.TryGetValue(x.PermissionNumber!, out var permName); + var menuId = x.MenuId; + var menuKey = string.Empty; + var menuName = string.Empty; + if (menuId.HasValue && menuInfo.TryGetValue(menuId.Value, out var menuMeta)) + { + menuKey = menuMeta.Key; + menuName = menuMeta.Name; + } + return new UserRolePermissionOutputDto { RoleNumber = x.RoleNumber, - PermissionNumber = x.PermissionNumber, - PermissionName = meta.Name, - MenuKey = meta.MenuKey + PermissionNumber = x.PermissionNumber!, + PermissionName = permName, + MenuId = menuId, + MenuKey = menuKey, + MenuName = menuName }; }).ToList(); @@ -281,15 +316,13 @@ namespace EOM.TSHotelManagement.Service roleRepository.Insert(role); } - // 软删除当前专属角色下所有有效的角色-权限绑定 + // 硬删除当前专属角色下所有有效的角色-权限绑定 var existing = rolePermissionRepository.AsQueryable() - .Where(x => x.RoleNumber == userRoleNumber && x.IsDelete != 1) - .Select(x => new RolePermission { RoleNumber = x.RoleNumber, PermissionNumber = x.PermissionNumber, IsDelete = 1 }) + .Where(x => x.RoleNumber == userRoleNumber) .ToList(); - - foreach (var rp in existing) + if (existing.Count > 0) { - rolePermissionRepository.SoftDelete(rp); + rolePermissionRepository.Delete(existing); } // 过滤、去重、忽略空白 @@ -303,7 +336,7 @@ namespace EOM.TSHotelManagement.Service { // 仅保留系统中存在的权限码 var validPerms = permissionRepository.AsQueryable() - .Where(p => p.IsDelete != 1 && perms.Contains(p.PermissionNumber)) + .Where(p => perms.Contains(p.PermissionNumber)) .Select(p => p.PermissionNumber) .ToList(); @@ -312,22 +345,20 @@ namespace EOM.TSHotelManagement.Service var entity = new RolePermission { RoleNumber = userRoleNumber, - PermissionNumber = pnum, - IsDelete = 0 + PermissionNumber = pnum }; rolePermissionRepository.Insert(entity); } } // 确保用户与专属角色绑定存在 - var hasBinding = userRoleRepository.IsAny(ur => ur.UserNumber == input.UserNumber && ur.RoleNumber == userRoleNumber && ur.IsDelete != 1); + var hasBinding = userRoleRepository.IsAny(ur => ur.UserNumber == input.UserNumber && ur.RoleNumber == userRoleNumber); if (!hasBinding) { userRoleRepository.Insert(new UserRole { UserNumber = input.UserNumber, - RoleNumber = userRoleNumber, - IsDelete = 0 + RoleNumber = userRoleNumber }); } @@ -357,7 +388,7 @@ namespace EOM.TSHotelManagement.Service { var roleNumber = $"R-USER-{userNumber}"; var list = rolePermissionRepository.AsQueryable() - .Where(rp => rp.RoleNumber == roleNumber && rp.IsDelete != 1) + .Where(rp => rp.RoleNumber == roleNumber) .Select(rp => rp.PermissionNumber) .ToList(); @@ -381,4 +412,4 @@ namespace EOM.TSHotelManagement.Service } } } -} \ No newline at end of file +} diff --git a/EOM.TSHotelManagement.Service/Employee/RewardPunishment/RewardPunishmentService.cs b/EOM.TSHotelManagement.Service/Employee/RewardPunishment/RewardPunishmentService.cs index 28546682e753ee71482bb32573e6f0b141fe70d3..079de15f5d3eec28e9bb3d7d35da47c97959c09a 100644 --- a/EOM.TSHotelManagement.Service/Employee/RewardPunishment/RewardPunishmentService.cs +++ b/EOM.TSHotelManagement.Service/Employee/RewardPunishment/RewardPunishmentService.cs @@ -1,4 +1,4 @@ -/* +/* * MIT License *Copyright (c) 2021 易开元(Easy-Open-Meta) @@ -102,7 +102,7 @@ namespace EOM.TSHotelManagement.Service var count = 0; - if (wn.Page != 0 && wn.PageSize != 0) + if (!wn.IgnorePaging) { gb = rewardPunishmentRepository.AsQueryable().Where(where.ToExpression()) .OrderByDescending(a => a.RewardPunishmentTime) diff --git a/EOM.TSHotelManagement.Service/SystemManagement/Administrator/AdminService.cs b/EOM.TSHotelManagement.Service/SystemManagement/Administrator/AdminService.cs index 6ad64760ef5fa594d9687a9862abc6c1a36853be..bce0291fa2d1d7a1388f94cd48469264b8d87c28 100644 --- a/EOM.TSHotelManagement.Service/SystemManagement/Administrator/AdminService.cs +++ b/EOM.TSHotelManagement.Service/SystemManagement/Administrator/AdminService.cs @@ -63,6 +63,11 @@ namespace EOM.TSHotelManagement.Service /// private readonly GenericRepository permissionRepository; + /// + /// 菜单 + /// + private readonly GenericRepository menuRepository; + /// /// 角色 /// @@ -90,13 +95,14 @@ namespace EOM.TSHotelManagement.Service private readonly ILogger logger; - public AdminService(GenericRepository adminRepository, GenericRepository adminTypeRepository, GenericRepository userRoleRepository, GenericRepository rolePermissionRepository, GenericRepository permissionRepository, GenericRepository roleRepository, DataProtectionHelper dataProtector, JWTHelper jWTHelper, ITwoFactorAuthService twoFactorAuthService, MailHelper mailHelper, ILogger logger) + public AdminService(GenericRepository adminRepository, GenericRepository adminTypeRepository, GenericRepository userRoleRepository, GenericRepository rolePermissionRepository, GenericRepository permissionRepository, GenericRepository menuRepository, GenericRepository roleRepository, DataProtectionHelper dataProtector, JWTHelper jWTHelper, ITwoFactorAuthService twoFactorAuthService, MailHelper mailHelper, ILogger logger) { this.adminRepository = adminRepository; this.adminTypeRepository = adminTypeRepository; this.userRoleRepository = userRoleRepository; this.rolePermissionRepository = rolePermissionRepository; this.permissionRepository = permissionRepository; + this.menuRepository = menuRepository; this.roleRepository = roleRepository; this.dataProtector = dataProtector; this.jWTHelper = jWTHelper; @@ -374,7 +380,7 @@ namespace EOM.TSHotelManagement.Service { if (createAdministratorInputDto.IsSuperAdmin == (int)AdminRole.SuperAdmin) { - var haveSuperAdmin = adminRepository.IsAny(a => a.IsSuperAdmin == 1 && a.IsDelete != 1); + var haveSuperAdmin = adminRepository.IsAny(a => a.IsSuperAdmin == 1); if (haveSuperAdmin) { return new BaseResponse { Message = LocalizationHelper.GetLocalizedString("Super Administrator already exists", "超级管理员已存在"), Code = BusinessStatusCode.InternalServerError }; @@ -639,7 +645,7 @@ namespace EOM.TSHotelManagement.Service } // cannot be delete if have administrators - var haveAdmin = adminRepository.IsAny(a => administratorTypes.Select(a => a.TypeId).Contains(a.Type) && a.IsDelete != 1); + var haveAdmin = adminRepository.IsAny(a => administratorTypes.Select(a => a.TypeId).Contains(a.Type)); if (haveAdmin) { return new BaseResponse @@ -675,21 +681,21 @@ namespace EOM.TSHotelManagement.Service try { // 校验用户是否存在且未删除 - var userExists = adminRepository.IsAny(a => a.Number == input.UserNumber && a.IsDelete != 1); + var userExists = adminRepository.IsAny(a => a.Number == input.UserNumber); if (!userExists) { return new BaseResponse(BusinessStatusCode.NotFound, LocalizationHelper.GetLocalizedString("User not found", "用户不存在")); } - // 软删除当前用户下所有有效的角色绑定 + // 硬删除当前用户下所有有效的角色绑定 var existing = userRoleRepository.AsQueryable() - .Where(x => x.UserNumber == input.UserNumber && x.IsDelete != 1) - .Select(x => new UserRole { UserNumber = x.UserNumber, RoleNumber = x.RoleNumber, IsDelete = 1 }) + .Where(x => x.UserNumber == input.UserNumber) + .Select(x => new UserRole { UserNumber = x.UserNumber, RoleNumber = x.RoleNumber }) .ToList(); foreach (var ur in existing) { - userRoleRepository.SoftDelete(ur); + userRoleRepository.Delete(ur); } // 过滤、去重、忽略空白 @@ -705,8 +711,7 @@ namespace EOM.TSHotelManagement.Service var entity = new UserRole { UserNumber = input.UserNumber, - RoleNumber = role, - IsDelete = 0 + RoleNumber = role }; userRoleRepository.Insert(entity); } @@ -740,7 +745,7 @@ namespace EOM.TSHotelManagement.Service try { var roleNumbers = userRoleRepository.AsQueryable() - .Where(ur => ur.UserNumber == userNumber && ur.IsDelete != 1) + .Where(ur => ur.UserNumber == userNumber) .Select(ur => ur.RoleNumber) .ToList(); @@ -793,7 +798,7 @@ namespace EOM.TSHotelManagement.Service { // 1) 用户 -> 角色 var roleNumbers = userRoleRepository.AsQueryable() - .Where(ur => ur.UserNumber == userNumber && ur.IsDelete != 1) + .Where(ur => ur.UserNumber == userNumber) .Select(ur => ur.RoleNumber) .ToList(); @@ -816,10 +821,12 @@ namespace EOM.TSHotelManagement.Service }; } - // 2) 角色 -> 权限编码(RolePermission) + // 2) 角色 -> 权限映射(RolePermission) var rolePermList = rolePermissionRepository.AsQueryable() - .Where(rp => rp.IsDelete != 1 && roleNumbers.Contains(rp.RoleNumber)) - .Select(rp => new { rp.RoleNumber, rp.PermissionNumber }) + .Where(rp => roleNumbers.Contains(rp.RoleNumber) + && rp.PermissionNumber != null + && rp.PermissionNumber != "") + .Select(rp => new { rp.RoleNumber, rp.PermissionNumber, rp.MenuId }) .ToList(); var permNumbers = rolePermList @@ -829,30 +836,61 @@ namespace EOM.TSHotelManagement.Service .ToList(); // 3) 权限详情(Permission) - var permInfo = new Dictionary(StringComparer.OrdinalIgnoreCase); + var permInfo = new Dictionary(StringComparer.OrdinalIgnoreCase); if (permNumbers.Count > 0) { var info = permissionRepository.AsQueryable() - .Where(p => p.IsDelete != 1 && permNumbers.Contains(p.PermissionNumber)) - .Select(p => new { p.PermissionNumber, p.PermissionName, p.MenuKey }) + .Where(p => permNumbers.Contains(p.PermissionNumber)) + .Select(p => new { p.PermissionNumber, p.PermissionName }) .ToList(); foreach (var p in info) { - permInfo[p.PermissionNumber] = (p.PermissionName, p.MenuKey ?? string.Empty); + permInfo[p.PermissionNumber] = p.PermissionName; } } // 4) 组装输出 + var menuIds = rolePermList + .Where(x => x.MenuId.HasValue && x.MenuId.Value > 0) + .Select(x => x.MenuId!.Value) + .Distinct() + .ToList(); + + var menuInfo = new Dictionary(); + if (menuIds.Count > 0) + { + var menus = menuRepository.AsQueryable() + .Where(m => m.IsDelete != 1 && menuIds.Contains(m.Id)) + .Select(m => new { m.Id, m.Key, m.Title }) + .ToList(); + + foreach (var m in menus) + { + menuInfo[m.Id] = (m.Key ?? string.Empty, m.Title ?? string.Empty); + } + } + var resultItems = rolePermList.Select(x => { - permInfo.TryGetValue(x.PermissionNumber, out var meta); + permInfo.TryGetValue(x.PermissionNumber!, out var permName); + var menuId = x.MenuId; + var menuKey = string.Empty; + var menuName = string.Empty; + if (menuId.HasValue && menuInfo.TryGetValue(menuId.Value, out var menuMeta)) + { + menuKey = menuMeta.Key; + menuName = menuMeta.Name; + } + return new UserRolePermissionOutputDto { RoleNumber = x.RoleNumber, - PermissionNumber = x.PermissionNumber, - PermissionName = meta.Name, - MenuKey = meta.MenuKey + PermissionNumber = x.PermissionNumber!, + PermissionName = permName, + MenuId = menuId, + MenuKey = menuKey, + MenuName = menuName }; }).ToList(); @@ -896,7 +934,7 @@ namespace EOM.TSHotelManagement.Service try { // 校验用户是否存在且未删除 - var userExists = adminRepository.IsAny(a => a.Number == input.UserNumber && a.IsDelete != 1); + var userExists = adminRepository.IsAny(a => a.Number == input.UserNumber); if (!userExists) { return new BaseResponse(BusinessStatusCode.NotFound, LocalizationHelper.GetLocalizedString("User not found", "用户不存在")); @@ -905,7 +943,7 @@ namespace EOM.TSHotelManagement.Service var userRoleNumber = $"R-USER-{input.UserNumber}"; // 确保专属角色存在 - var existsRole = roleRepository.IsAny(r => r.RoleNumber == userRoleNumber && r.IsDelete != 1); + var existsRole = roleRepository.IsAny(r => r.RoleNumber == userRoleNumber); if (!existsRole) { var role = new Role @@ -918,15 +956,13 @@ namespace EOM.TSHotelManagement.Service roleRepository.Insert(role); } - // 软删除当前专属角色下所有有效的角色-权限绑定 + // 硬删除当前专属角色下所有有效的角色-权限绑定 var existing = rolePermissionRepository.AsQueryable() - .Where(x => x.RoleNumber == userRoleNumber && x.IsDelete != 1) - .Select(x => new RolePermission { RoleNumber = x.RoleNumber, PermissionNumber = x.PermissionNumber, IsDelete = 1 }) + .Where(x => x.RoleNumber == userRoleNumber) .ToList(); - - foreach (var rp in existing) + if (existing.Count > 0) { - rolePermissionRepository.SoftDelete(rp); + rolePermissionRepository.Delete(existing); } // 过滤、去重、忽略空白 @@ -940,7 +976,7 @@ namespace EOM.TSHotelManagement.Service { // 仅保留系统中存在的权限码 var validPerms = permissionRepository.AsQueryable() - .Where(p => p.IsDelete != 1 && perms.Contains(p.PermissionNumber)) + .Where(p => perms.Contains(p.PermissionNumber)) .Select(p => p.PermissionNumber) .ToList(); @@ -949,22 +985,20 @@ namespace EOM.TSHotelManagement.Service var entity = new RolePermission { RoleNumber = userRoleNumber, - PermissionNumber = pnum, - IsDelete = 0 + PermissionNumber = pnum }; rolePermissionRepository.Insert(entity); } } // 确保用户与专属角色绑定存在 - var hasBinding = userRoleRepository.IsAny(ur => ur.UserNumber == input.UserNumber && ur.RoleNumber == userRoleNumber && ur.IsDelete != 1); + var hasBinding = userRoleRepository.IsAny(ur => ur.UserNumber == input.UserNumber && ur.RoleNumber == userRoleNumber); if (!hasBinding) { userRoleRepository.Insert(new UserRole { UserNumber = input.UserNumber, - RoleNumber = userRoleNumber, - IsDelete = 0 + RoleNumber = userRoleNumber }); } @@ -996,7 +1030,7 @@ namespace EOM.TSHotelManagement.Service { var roleNumber = $"R-USER-{userNumber}"; var list = rolePermissionRepository.AsQueryable() - .Where(rp => rp.RoleNumber == roleNumber && rp.IsDelete != 1) + .Where(rp => rp.RoleNumber == roleNumber) .Select(rp => rp.PermissionNumber) .ToList(); diff --git a/EOM.TSHotelManagement.Service/SystemManagement/Base/BaseService.cs b/EOM.TSHotelManagement.Service/SystemManagement/Base/BaseService.cs index 23dd1d28e2022abc9d4896a1f01fc90cd95c8eb2..3a33895e228f84590fbe39b9573dcd726772b13b 100644 --- a/EOM.TSHotelManagement.Service/SystemManagement/Base/BaseService.cs +++ b/EOM.TSHotelManagement.Service/SystemManagement/Base/BaseService.cs @@ -76,11 +76,6 @@ namespace EOM.TSHotelManagement.Service /// private readonly GenericRepository goodbadTypeRepository; - /// - /// 基础URL - /// - private readonly GenericRepository baseRepository; - /// /// 公告类型 /// @@ -94,7 +89,7 @@ namespace EOM.TSHotelManagement.Service private readonly ILogger logger; - public BaseService(GenericRepository workerRepository, GenericRepository educationRepository, GenericRepository nationRepository, GenericRepository deptRepository, GenericRepository positionRepository, GenericRepository passPortTypeRepository, GenericRepository custoTypeRepository, GenericRepository goodbadTypeRepository, GenericRepository baseRepository, GenericRepository appointmentNoticeTypeRepository, GenericRepository employeeRepository, GenericRepository customerRepository, GenericRepository appointmentNoticeRepository, ILogger logger) + public BaseService(GenericRepository workerRepository, GenericRepository educationRepository, GenericRepository nationRepository, GenericRepository deptRepository, GenericRepository positionRepository, GenericRepository passPortTypeRepository, GenericRepository custoTypeRepository, GenericRepository goodbadTypeRepository, GenericRepository appointmentNoticeTypeRepository, GenericRepository employeeRepository, GenericRepository customerRepository, GenericRepository appointmentNoticeRepository, ILogger logger) { this.workerRepository = workerRepository; this.educationRepository = educationRepository; @@ -104,7 +99,6 @@ namespace EOM.TSHotelManagement.Service this.passPortTypeRepository = passPortTypeRepository; this.custoTypeRepository = custoTypeRepository; this.goodbadTypeRepository = goodbadTypeRepository; - this.baseRepository = baseRepository; this.appointmentNoticeTypeRepository = appointmentNoticeTypeRepository; this.employeeRepository = employeeRepository; this.customerRepository = customerRepository; @@ -729,7 +723,7 @@ namespace EOM.TSHotelManagement.Service source.ParentDepartmentName = parentDepartment.IsNullOrEmpty() ? "" : parentDepartment.DepartmentName; var departmentLeader = departmentLeaders.SingleOrDefault(a => a.EmployeeId.Equals(source.DepartmentLeader)); - source.LeaderName = departmentLeader.IsNullOrEmpty() ? "" : departmentLeader.EmployeeName; + source.LeaderName = departmentLeader.IsNullOrEmpty() ? "" : departmentLeader.Name; }); var result = EntityMapper.MapList(depts); return new ListOutputDto @@ -1138,7 +1132,7 @@ namespace EOM.TSHotelManagement.Service // 当前证件类型下是否有客户 var passportTypeNumbers = passPortTypes.Select(a => a.PassportId).ToList(); - var customerCount = customerRepository.AsQueryable().Count(a => passportTypeNumbers.Contains(a.PassportId)); + var customerCount = customerRepository.AsQueryable().Count(a => passportTypeNumbers.Contains(a.IdCardType)); if (customerCount > 0) { return new BaseResponse diff --git a/EOM.TSHotelManagement.Service/SystemManagement/Menu/MenuService.cs b/EOM.TSHotelManagement.Service/SystemManagement/Menu/MenuService.cs index e774e304d08abf16358bd2aeeb9efad266eb8d0d..1c4b0225e2ee736906c28d73d2b9ccf0f7be6541 100644 --- a/EOM.TSHotelManagement.Service/SystemManagement/Menu/MenuService.cs +++ b/EOM.TSHotelManagement.Service/SystemManagement/Menu/MenuService.cs @@ -68,13 +68,12 @@ namespace EOM.TSHotelManagement.Service /// public ListOutputDto BuildMenuAll(BaseInputDto baseInputDto) { - // 1) 读取所有未删除的菜单 + // 1) 读取所有未删除菜单 List allMenus = menuRepository.GetList(a => a.IsDelete != 1).OrderBy(a => a.Id).ToList(); - // 默认:空用户/无权限 -> 返回空树 + // 默认:无权限返回空树 List filteredMenus = new(); - // 前端按钮权限:按菜单Key聚合的“用户拥有的权限编码”集合 - Dictionary> menuPermMap = null; + Dictionary> menuPermMap = new(); try { @@ -89,12 +88,10 @@ namespace EOM.TSHotelManagement.Service } catch { - // token 无效则按无权限处理 userNumber = string.Empty; } } - // 超级管理员放行所有菜单 var isSuperAdmin = false; if (!string.IsNullOrWhiteSpace(userNumber)) { @@ -105,112 +102,139 @@ namespace EOM.TSHotelManagement.Service if (isSuperAdmin) { filteredMenus = allMenus; - - // 超管:加载所有与菜单绑定的权限编码 - var allPermPairs = permissionRepository.AsQueryable() - .Where(p => p.IsDelete != 1 && p.MenuKey != null) - .Select(p => new { p.MenuKey, p.PermissionNumber }) + var allPermNumbers = permissionRepository.AsQueryable() + .Select(p => p.PermissionNumber) + .ToList() + .Where(p => !p.IsNullOrEmpty()) + .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); - menuPermMap = allPermPairs - .GroupBy(x => x.MenuKey!) - .ToDictionary(g => g.Key!, g => g.Select(x => x.PermissionNumber).Distinct().ToList()); + menuPermMap = BuildDefaultMenuPermissionMap(filteredMenus, allPermNumbers); + return BuildMenuTree(filteredMenus, menuPermMap); } - else if (!string.IsNullOrWhiteSpace(userNumber)) + + if (string.IsNullOrWhiteSpace(userNumber)) { - // 2) 用户 -> 角色 - var roleNumbers = userRoleRepository.AsQueryable() - .Where(ur => ur.UserNumber == userNumber && ur.IsDelete != 1) - .Select(ur => ur.RoleNumber) - .ToList(); + return BuildMenuTree(filteredMenus, menuPermMap); + } - if (roleNumbers != null && roleNumbers.Count > 0) - { - // 3) 角色 -> 权限 - var permNumbers = rolePermissionRepository.AsQueryable() - .Where(rp => rp.IsDelete != 1 && roleNumbers.Contains(rp.RoleNumber)) - .Select(rp => rp.PermissionNumber) - .ToList(); - - if (permNumbers != null && permNumbers.Count > 0) - { - // 4) 权限 -> 绑定的菜单Key(Permission.MenuKey) - var permQuery = permissionRepository.AsQueryable() - .Where(p => p.IsDelete != 1 && p.MenuKey != null && permNumbers.Contains(p.PermissionNumber)); - - var allowedKeys = new HashSet( - permQuery - .Select(p => p.MenuKey) - .ToList() - .Where(k => !string.IsNullOrWhiteSpace(k))! - ); - - // 同时按菜单Key聚合当前用户拥有的权限编码,供前端按钮级控制 - var userPermPairs = permQuery - .Select(p => new { p.MenuKey, p.PermissionNumber }) - .ToList(); - - menuPermMap = userPermPairs - .GroupBy(x => x.MenuKey!) - .ToDictionary(g => g.Key!, g => g.Select(x => x.PermissionNumber).Distinct().ToList()); - - // 5) 仅保留有权限的菜单,并补齐其父级(保证树连通) - var menuById = allMenus.ToDictionary(m => m.Id); - var menuByKey = allMenus.Where(m => !string.IsNullOrWhiteSpace(m.Key)) - .ToDictionary(m => m.Key!); - var allowedMenuIds = new HashSet(); - - foreach (var key in allowedKeys) - { - if (menuByKey.TryGetValue(key, out var menu)) - { - var current = menu; - while (current != null && !allowedMenuIds.Contains(current.Id)) - { - allowedMenuIds.Add(current.Id); - if (current.Parent.HasValue && menuById.TryGetValue(current.Parent.Value, out var parentMenu)) - { - current = parentMenu; - } - else - { - current = null; - } - } - } - } - - filteredMenus = allMenus.Where(m => allowedMenuIds.Contains(m.Id)).ToList(); - } - else - { - filteredMenus = new List(); - } - } - else - { - filteredMenus = new List(); - } + // 2) 用户 -> 角色 + var roleNumbers = userRoleRepository.AsQueryable() + .Where(ur => ur.UserNumber == userNumber) + .Select(ur => ur.RoleNumber) + .ToList(); + + if (roleNumbers == null || roleNumbers.Count == 0) + { + return BuildMenuTree(filteredMenus, menuPermMap); + } + + // 3) 角色 -> 授权(菜单与权限独立) + var roleGrants = rolePermissionRepository.AsQueryable() + .Where(rp => roleNumbers.Contains(rp.RoleNumber)) + .Select(rp => new { rp.MenuId, rp.PermissionNumber }) + .ToList(); + + var grantedPermNumbers = roleGrants + .Where(x => !x.PermissionNumber.IsNullOrEmpty()) + .Select(x => x.PermissionNumber!) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList(); + + var directMenuIds = roleGrants + .Where(x => x.MenuId.HasValue && x.MenuId.Value > 0) + .Select(x => x.MenuId!.Value) + .Distinct() + .ToHashSet(); + + if (directMenuIds.Count == 0) + { + return BuildMenuTree(filteredMenus, menuPermMap); + } + + // 4) 保留已授权菜单并补齐其父级,保证树连通 + var menuById = allMenus.ToDictionary(m => m.Id); + var allowedMenuIds = BuildAllowedMenuIdsWithAncestors(menuById, directMenuIds); + filteredMenus = allMenus.Where(m => allowedMenuIds.Contains(m.Id)).ToList(); + + // 5) 构建按菜单聚合的权限映射 + var menuSpecificPerms = roleGrants + .Where(x => x.MenuId.HasValue && x.MenuId.Value > 0 && !x.PermissionNumber.IsNullOrEmpty()) + .GroupBy(x => x.MenuId!.Value) + .ToDictionary( + g => g.Key, + g => g.Select(x => x.PermissionNumber!) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList()); + + if (menuSpecificPerms.Count > 0) + { + menuPermMap = filteredMenus + .Where(m => !string.IsNullOrWhiteSpace(m.Key)) + .ToDictionary( + m => m.Key!, + m => menuSpecificPerms.TryGetValue(m.Id, out var perms) + ? perms + : new List()); } else { - filteredMenus = new List(); + // 独立授权模式:将已授权权限作为可见菜单的全局权限集 + menuPermMap = BuildDefaultMenuPermissionMap(filteredMenus, grantedPermNumbers); } } catch { - // 异常情况下,回退为空树,避免泄露菜单 filteredMenus = new List(); + menuPermMap = new Dictionary>(); } - // 6) 构建(过滤后的)菜单树(附带每个菜单Key下的用户权限编码集合) return BuildMenuTree(filteredMenus, menuPermMap); } - /// - /// 查询所有菜单信息 - /// - /// + private static HashSet BuildAllowedMenuIdsWithAncestors( + Dictionary menuById, + HashSet directMenuIds) + { + var allowedMenuIds = new HashSet(); + + foreach (var menuId in directMenuIds) + { + if (!menuById.TryGetValue(menuId, out var current)) + { + continue; + } + + while (current != null && allowedMenuIds.Add(current.Id)) + { + if (current.Parent.HasValue && menuById.TryGetValue(current.Parent.Value, out var parentMenu)) + { + current = parentMenu; + } + else + { + current = null; + } + } + } + + return allowedMenuIds; + } + + private static Dictionary> BuildDefaultMenuPermissionMap( + List menus, + List permissionNumbers) + { + var normalizedPerms = (permissionNumbers ?? new List()) + .Where(p => !p.IsNullOrEmpty()) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList(); + + return menus + .Where(m => !string.IsNullOrWhiteSpace(m.Key)) + .ToDictionary(m => m.Key!, _ => normalizedPerms.ToList()); + } + public ListOutputDto SelectMenuAll(ReadMenuInputDto readMenuInputDto) { var where = SqlFilterBuilder.BuildExpression(readMenuInputDto ?? new ReadMenuInputDto()); @@ -411,4 +435,3 @@ namespace EOM.TSHotelManagement.Service } } } - diff --git a/EOM.TSHotelManagement.Service/SystemManagement/Notice/NoticeService.cs b/EOM.TSHotelManagement.Service/SystemManagement/Notice/NoticeService.cs index 4d11897848a943434e8cc8f21faea5844618c0ab..260897d5563c38ad1e337681f7f57dfa7c6c4b2f 100644 --- a/EOM.TSHotelManagement.Service/SystemManagement/Notice/NoticeService.cs +++ b/EOM.TSHotelManagement.Service/SystemManagement/Notice/NoticeService.cs @@ -56,7 +56,17 @@ namespace EOM.TSHotelManagement.Service var ntc = new List(); var where = SqlFilterBuilder.BuildExpression(readAppointmentNoticeInputDto); var count = 0; - ntc = noticeRepository.AsQueryable().Where(where.ToExpression()).ToPageList(readAppointmentNoticeInputDto.Page, readAppointmentNoticeInputDto.PageSize, ref count); + + if (!readAppointmentNoticeInputDto.IgnorePaging) + { + ntc = noticeRepository.AsQueryable().Where(where.ToExpression()).ToPageList(readAppointmentNoticeInputDto.Page, readAppointmentNoticeInputDto.PageSize, ref count); + } + else + { + ntc = noticeRepository.AsQueryable().Where(where.ToExpression()).ToList(); + count = ntc.Count; + } + ntc.ForEach(source => { switch (source.NoticeType) diff --git a/EOM.TSHotelManagement.Service/SystemManagement/Quartz/IQuartzAppService.cs b/EOM.TSHotelManagement.Service/SystemManagement/Quartz/IQuartzAppService.cs new file mode 100644 index 0000000000000000000000000000000000000000..7e20009d14baf304b04231900a1e539f761cd98b --- /dev/null +++ b/EOM.TSHotelManagement.Service/SystemManagement/Quartz/IQuartzAppService.cs @@ -0,0 +1,10 @@ +using EOM.TSHotelManagement.Contract; +using System.Threading.Tasks; + +namespace EOM.TSHotelManagement.Service +{ + public interface IQuartzAppService + { + Task> SelectQuartzJobList(); + } +} diff --git a/EOM.TSHotelManagement.Service/SystemManagement/Quartz/QuartzAppService.cs b/EOM.TSHotelManagement.Service/SystemManagement/Quartz/QuartzAppService.cs new file mode 100644 index 0000000000000000000000000000000000000000..9a33109145769143193576f2cf6c89b8392c1fa9 --- /dev/null +++ b/EOM.TSHotelManagement.Service/SystemManagement/Quartz/QuartzAppService.cs @@ -0,0 +1,100 @@ +using EOM.TSHotelManagement.Common; +using EOM.TSHotelManagement.Contract; +using Quartz; +using Quartz.Impl.Matchers; + +namespace EOM.TSHotelManagement.Service +{ + public class QuartzAppService : IQuartzAppService + { + private readonly ISchedulerFactory _schedulerFactory; + + public QuartzAppService(ISchedulerFactory schedulerFactory) + { + _schedulerFactory = schedulerFactory; + } + + public async Task> SelectQuartzJobList() + { + try + { + var scheduler = await _schedulerFactory.GetScheduler(); + var jobKeys = await scheduler.GetJobKeys(GroupMatcher.AnyGroup()); + var rows = new List(); + + foreach (var jobKey in jobKeys.OrderBy(a => a.Group).ThenBy(a => a.Name)) + { + var jobDetail = await scheduler.GetJobDetail(jobKey); + if (jobDetail == null) + { + continue; + } + + var triggers = await scheduler.GetTriggersOfJob(jobKey); + if (triggers == null || triggers.Count == 0) + { + rows.Add(new ReadQuartzJobOutputDto + { + JobName = jobKey.Name, + JobGroup = jobKey.Group, + JobDescription = jobDetail.Description, + IsDurable = jobDetail.Durable, + RequestsRecovery = jobDetail.RequestsRecovery + }); + continue; + } + + foreach (var trigger in triggers.OrderBy(a => a.Key.Group).ThenBy(a => a.Key.Name)) + { + var state = await scheduler.GetTriggerState(trigger.Key); + var cronTrigger = trigger as ICronTrigger; + var simpleTrigger = trigger as ISimpleTrigger; + + rows.Add(new ReadQuartzJobOutputDto + { + JobName = jobKey.Name, + JobGroup = jobKey.Group, + JobDescription = jobDetail.Description, + IsDurable = jobDetail.Durable, + RequestsRecovery = jobDetail.RequestsRecovery, + TriggerName = trigger.Key.Name, + TriggerGroup = trigger.Key.Group, + TriggerType = trigger.GetType().Name, + TriggerState = state.ToString(), + CronExpression = cronTrigger?.CronExpressionString, + TimeZoneId = cronTrigger?.TimeZone?.Id, + RepeatCount = simpleTrigger?.RepeatCount, + RepeatIntervalMs = simpleTrigger?.RepeatInterval.TotalMilliseconds, + StartTimeUtc = trigger.StartTimeUtc.UtcDateTime, + EndTimeUtc = trigger.EndTimeUtc?.UtcDateTime, + NextFireTimeUtc = trigger.GetNextFireTimeUtc()?.UtcDateTime, + PreviousFireTimeUtc = trigger.GetPreviousFireTimeUtc()?.UtcDateTime + }); + } + } + + return new ListOutputDto + { + Data = new PagedData + { + Items = rows, + TotalCount = rows.Count + } + }; + } + catch (Exception ex) + { + return new ListOutputDto + { + Code = BusinessStatusCode.InternalServerError, + Message = LocalizationHelper.GetLocalizedString(ex.Message, ex.Message), + Data = new PagedData + { + Items = new List(), + TotalCount = 0 + } + }; + } + } + } +} diff --git a/EOM.TSHotelManagement.Service/SystemManagement/Role/IRoleAppService.cs b/EOM.TSHotelManagement.Service/SystemManagement/Role/IRoleAppService.cs index cc5218dd088f9ba93285a1764d26ec1f6bb23861..49eb25b0a00227f3f61b4b9fc1460d9c486f5f8c 100644 --- a/EOM.TSHotelManagement.Service/SystemManagement/Role/IRoleAppService.cs +++ b/EOM.TSHotelManagement.Service/SystemManagement/Role/IRoleAppService.cs @@ -47,6 +47,13 @@ namespace EOM.TSHotelManagement.Service /// 权限编码集合 ListOutputDto ReadRolePermissions(string roleNumber); + /// + /// 读取指定角色已授予的菜单与权限(菜单和权限独立) + /// + /// 角色编码 + /// 角色授权明细 + SingleOutputDto ReadRoleGrants(string roleNumber); + /// /// 读取隶属于指定角色的管理员用户编码集合 /// diff --git a/EOM.TSHotelManagement.Service/SystemManagement/Role/RoleAppService.cs b/EOM.TSHotelManagement.Service/SystemManagement/Role/RoleAppService.cs index 390b67c33b0d122b5dc2e8ed6d9f3b52354cb7f5..3863db75684da777858cb96595509d899516b58c 100644 --- a/EOM.TSHotelManagement.Service/SystemManagement/Role/RoleAppService.cs +++ b/EOM.TSHotelManagement.Service/SystemManagement/Role/RoleAppService.cs @@ -30,13 +30,31 @@ namespace EOM.TSHotelManagement.Service /// private readonly GenericRepository userRoleRepository; + /// + /// 权限 仓储 + /// + private readonly GenericRepository permissionRepository; + + /// + /// 菜单 仓储 + /// + private readonly GenericRepository menuRepository; + private readonly ILogger logger; - public RoleAppService(GenericRepository roleRepository, GenericRepository rolePermissionRepository, GenericRepository userRoleRepository, ILogger logger) + public RoleAppService( + GenericRepository roleRepository, + GenericRepository rolePermissionRepository, + GenericRepository userRoleRepository, + GenericRepository permissionRepository, + GenericRepository menuRepository, + ILogger logger) { this.roleRepository = roleRepository; this.rolePermissionRepository = rolePermissionRepository; this.userRoleRepository = userRoleRepository; + this.permissionRepository = permissionRepository; + this.menuRepository = menuRepository; this.logger = logger; } @@ -78,8 +96,8 @@ namespace EOM.TSHotelManagement.Service // 如果角色组存在关联的权限映射或用户绑定,则不允许删除 var roleNumbers = roles.Select(r => r.RoleNumber).ToList(); - var hasRolePermissions = rolePermissionRepository.IsAny(rp => roleNumbers.Contains(rp.RoleNumber) && rp.IsDelete != 1); - var hasUserRoles = userRoleRepository.IsAny(ur => roleNumbers.Contains(ur.RoleNumber) && ur.IsDelete != 1); + var hasRolePermissions = rolePermissionRepository.IsAny(rp => roleNumbers.Contains(rp.RoleNumber)); + var hasUserRoles = userRoleRepository.IsAny(ur => roleNumbers.Contains(ur.RoleNumber)); if (hasRolePermissions || hasUserRoles) { return new BaseResponse @@ -215,15 +233,13 @@ namespace EOM.TSHotelManagement.Service return new BaseResponse(BusinessStatusCode.NotFound, LocalizationHelper.GetLocalizedString("Role not found", "角色不存在")); } - // 软删除该角色现有有效的权限映射 + // 硬删除该角色现有有效授权映射(菜单 + 权限) var existing = rolePermissionRepository.AsQueryable() - .Where(x => x.RoleNumber == input.RoleNumber && x.IsDelete != 1) - .Select(x => new RolePermission { RoleNumber = x.RoleNumber, PermissionNumber = x.PermissionNumber, IsDelete = 1 }) + .Where(x => x.RoleNumber == input.RoleNumber) .ToList(); - - foreach (var rp in existing) + if (existing.Count > 0) { - rolePermissionRepository.SoftDelete(rp); + rolePermissionRepository.Delete(existing); } // 过滤去重并忽略空白权限码 @@ -233,14 +249,52 @@ namespace EOM.TSHotelManagement.Service .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); - // 插入新的权限映射 - foreach (var perm in distinctPerms) + // 过滤去重并忽略非法菜单主键 + var distinctMenuIds = (input.MenuIds ?? new List()) + .Where(id => id > 0) + .Distinct() + .ToList(); + + // 仅保留系统中真实存在的权限编码和菜单主键 + var validPerms = distinctPerms.Count == 0 + ? new List() + : permissionRepository.AsQueryable() + .Where(p => distinctPerms.Contains(p.PermissionNumber)) + .Select(p => p.PermissionNumber) + .ToList() + .Where(p => !p.IsNullOrEmpty()) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList(); + + var validMenuIds = distinctMenuIds.Count == 0 + ? new List() + : menuRepository.AsQueryable() + .Where(m => m.IsDelete != 1 && distinctMenuIds.Contains(m.Id)) + .Select(m => m.Id) + .ToList() + .Distinct() + .ToList(); + + // 写入角色-权限映射 + foreach (var perm in validPerms) { var entity = new RolePermission { RoleNumber = input.RoleNumber, PermissionNumber = perm, - IsDelete = 0 + MenuId = null + }; + rolePermissionRepository.Insert(entity); + } + + // 写入角色-菜单映射 + foreach (var menuId in validMenuIds) + { + var entity = new RolePermission + { + RoleNumber = input.RoleNumber, + MenuId = menuId, + PermissionNumber = null }; rolePermissionRepository.Insert(entity); } @@ -272,7 +326,9 @@ namespace EOM.TSHotelManagement.Service try { var list = rolePermissionRepository.AsQueryable() - .Where(rp => rp.RoleNumber == roleNumber && rp.IsDelete != 1) + .Where(rp => rp.RoleNumber == roleNumber + && rp.PermissionNumber != null + && rp.PermissionNumber != "") .Select(rp => rp.PermissionNumber) .ToList() ?? new List(); @@ -299,6 +355,74 @@ namespace EOM.TSHotelManagement.Service } } + /// + /// 读取指定角色已授予的菜单与权限(菜单与权限独立) + /// + public SingleOutputDto ReadRoleGrants(string roleNumber) + { + if (roleNumber.IsNullOrEmpty()) + { + return new SingleOutputDto + { + Code = BusinessStatusCode.BadRequest, + Message = LocalizationHelper.GetLocalizedString("RoleNumber is required", "缺少角色编码"), + Data = new ReadRoleGrantOutputDto + { + RoleNumber = string.Empty, + PermissionNumbers = new List(), + MenuIds = new List() + } + }; + } + + try + { + var grants = rolePermissionRepository.AsQueryable() + .Where(rp => rp.RoleNumber == roleNumber) + .Select(rp => new { rp.PermissionNumber, rp.MenuId }) + .ToList(); + + var permissionNumbers = grants + .Where(x => !x.PermissionNumber.IsNullOrEmpty()) + .Select(x => x.PermissionNumber!) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList(); + + var menuIds = grants + .Where(x => x.MenuId.HasValue && x.MenuId.Value > 0) + .Select(x => x.MenuId!.Value) + .Distinct() + .ToList(); + + return new SingleOutputDto + { + Code = BusinessStatusCode.Success, + Message = LocalizationHelper.GetLocalizedString("Query success", "查询成功"), + Data = new ReadRoleGrantOutputDto + { + RoleNumber = roleNumber, + PermissionNumbers = permissionNumbers, + MenuIds = menuIds + } + }; + } + catch (Exception ex) + { + logger.LogError(ex, "Error reading grants for role {RoleNumber}: {Message}", roleNumber, ex.Message); + return new SingleOutputDto + { + Code = BusinessStatusCode.InternalServerError, + Message = LocalizationHelper.GetLocalizedString($"Query failed: {ex.Message}", $"查询失败:{ex.Message}"), + Data = new ReadRoleGrantOutputDto + { + RoleNumber = roleNumber, + PermissionNumbers = new List(), + MenuIds = new List() + } + }; + } + } + /// /// 读取隶属于指定角色的管理员用户编码集合 /// @@ -317,7 +441,7 @@ namespace EOM.TSHotelManagement.Service try { var list = userRoleRepository.AsQueryable() - .Where(ur => ur.RoleNumber == roleNumber && ur.IsDelete != 1) + .Where(ur => ur.RoleNumber == roleNumber) .Select(ur => ur.UserNumber) .ToList() ?? new List(); @@ -365,8 +489,8 @@ namespace EOM.TSHotelManagement.Service // 软删除该角色当前所有有效的用户绑定 var existing = userRoleRepository.AsQueryable() - .Where(ur => ur.RoleNumber == input.RoleNumber && ur.IsDelete != 1) - .Select(ur => new UserRole { RoleNumber = ur.RoleNumber, UserNumber = ur.UserNumber, IsDelete = 1 }) + .Where(ur => ur.RoleNumber == input.RoleNumber) + .Select(ur => new UserRole { RoleNumber = ur.RoleNumber, UserNumber = ur.UserNumber }) .ToList(); foreach (var ur in existing) @@ -387,8 +511,7 @@ namespace EOM.TSHotelManagement.Service var entity = new UserRole { RoleNumber = input.RoleNumber, - UserNumber = u, - IsDelete = 0 + UserNumber = u }; userRoleRepository.Insert(entity); } diff --git a/EOM.TSHotelManagement.Service/SystemManagement/SupervisionStatistics/SupervisionStatisticsService.cs b/EOM.TSHotelManagement.Service/SystemManagement/SupervisionStatistics/SupervisionStatisticsService.cs index 1b370db4567c385fbfd1af5c233af6a8a2c52444..95e446b7ef231bc04b33a4a1644fde29fdcaabbb 100644 --- a/EOM.TSHotelManagement.Service/SystemManagement/SupervisionStatistics/SupervisionStatisticsService.cs +++ b/EOM.TSHotelManagement.Service/SystemManagement/SupervisionStatistics/SupervisionStatisticsService.cs @@ -64,7 +64,16 @@ namespace EOM.TSHotelManagement.Service var where = SqlFilterBuilder.BuildExpression(readSupervisionStatisticsInputDto ?? new ReadSupervisionStatisticsInputDto()); var count = 0; - cif = checkInfoRepository.AsQueryable().Where(where.ToExpression()).ToPageList(readSupervisionStatisticsInputDto.Page, readSupervisionStatisticsInputDto.PageSize, ref count); + + if (!readSupervisionStatisticsInputDto.IgnorePaging) + { + cif = checkInfoRepository.AsQueryable().Where(where.ToExpression()).ToPageList(readSupervisionStatisticsInputDto.Page, readSupervisionStatisticsInputDto.PageSize, ref count); + } + else + { + cif = checkInfoRepository.AsQueryable().Where(where.ToExpression()).ToList(); + } + var deptId = cif.Select(a => a.SupervisingDepartment).ToList(); var depts = checkInfoRepository.Change().GetList(a => deptId.Contains(a.DepartmentNumber)); cif.ForEach(c => diff --git a/EOM.TSHotelManagement.Service/SystemManagement/VipRule/VipRuleAppService.cs b/EOM.TSHotelManagement.Service/SystemManagement/VipRule/VipRuleAppService.cs index 2de9ecbc0a179364462ba2ff20184837917b5735..d7a7e2375643c91c900887ea46a8b6f012f049c0 100644 --- a/EOM.TSHotelManagement.Service/SystemManagement/VipRule/VipRuleAppService.cs +++ b/EOM.TSHotelManagement.Service/SystemManagement/VipRule/VipRuleAppService.cs @@ -65,17 +65,25 @@ namespace EOM.TSHotelManagement.Service var where = SqlFilterBuilder.BuildExpression(readVipLevelRuleInputDto ?? new ReadVipLevelRuleInputDto()); var count = 0; - var Data = vipRuleRepository.AsQueryable().Where(where.ToExpression()).ToPageList(readVipLevelRuleInputDto.Page, readVipLevelRuleInputDto.PageSize, ref count); + var data = new List(); + if (readVipLevelRuleInputDto.IgnorePaging) + { + data = vipRuleRepository.AsQueryable().Where(where.ToExpression()).ToList(); + } + else + { + data = vipRuleRepository.AsQueryable().Where(where.ToExpression()).ToPageList(readVipLevelRuleInputDto.Page, readVipLevelRuleInputDto.PageSize, ref count); + } var listUserType = custoTypeRepository.GetList(a => a.IsDelete != 1); - Data.ForEach(source => + data.ForEach(source => { var userType = listUserType.SingleOrDefault(a => a.CustomerType == source.VipLevelId); source.VipLevelName = userType == null ? "" : userType.CustomerTypeName; }); - var viprules = EntityMapper.MapList(Data); + var viprules = EntityMapper.MapList(data); return new ListOutputDto { diff --git a/EOM.TSHotelManagement.Service/Util/UtilService.cs b/EOM.TSHotelManagement.Service/Util/UtilService.cs index 1f04c1e665382f2f9780c89bbde0a7867c515f8c..f0d28876d5c8ff68ac6f3652486f2e63c2db2d2a 100644 --- a/EOM.TSHotelManagement.Service/Util/UtilService.cs +++ b/EOM.TSHotelManagement.Service/Util/UtilService.cs @@ -86,7 +86,7 @@ namespace EOM.TSHotelManagement.Service var where = SqlFilterBuilder.BuildExpression(readOperationLogInputDto, nameof(OperationLog.OperationTime)); var count = 0; - if (readOperationLogInputDto.Page != 0 && readOperationLogInputDto.PageSize != 0) + if (!readOperationLogInputDto.IgnorePaging) { operationLogs = operationLogRepository.AsQueryable().Where(where.ToExpression()).OrderByDescending(a => a.OperationTime).ToPageList(readOperationLogInputDto.Page, readOperationLogInputDto.PageSize, ref count); } @@ -125,7 +125,7 @@ namespace EOM.TSHotelManagement.Service var where = SqlFilterBuilder.BuildExpression(readRequestLogInputDto, nameof(RequestLog.RequestTime)); var count = 0; - if (readRequestLogInputDto.Page != 0 && readRequestLogInputDto.PageSize != 0) + if (!readRequestLogInputDto.IgnorePaging) { requestLogs = requestLogRepository.AsQueryable().Where(where.ToExpression()).OrderByDescending(a => a.RequestTime).ToPageList(readRequestLogInputDto.Page, readRequestLogInputDto.PageSize, ref count); } diff --git a/README.en.md b/README.en.md index 424be9cad3678ff58938caa3da145e12584776a5..88d4a10a5fac8271a0cc77d44c779756fc3a1fe2 100644 --- a/README.en.md +++ b/README.en.md @@ -8,6 +8,7 @@

## Project Overview @@ -193,12 +194,20 @@ docker run -d \ |AllowedOrigins__0|Allowed Domain Sites (for Development Environments)|Y|http://localhost:8080|http://localhost:8080| |AllowedOrigins__1|Allowed domain sites for production environment|Y|https://www.yourdomain.com|https://www.yourdomain.com| |SoftwareVersion|Software version number for documentation purposes|N|N/A|N/A| -|JobKeys__0|Quartz Job 1|Y|ReservationExpirationCheckJob|ReservationExpirationCheckJob| -|JobKeys__1|Quartz Job 2|Y|MailServiceCheckJob|MailServiceCheckJob| -|JobKeys__2|Quartz Job 3|Y|RedisServiceCheckJob|RedisServiceCheckJob| +|JobKeys__0|Quartz Job 1|Y|ReservationExpirationCheckJob:0 0 1 * * ?|JobName:CronExpression| +|JobKeys__1|Quartz Job 2|Y|MailServiceCheckJob:0 */5 * * * ?|JobName:CronExpression| +|JobKeys__2|Quartz Job 3|Y|RedisServiceCheckJob:0 */5 * * * ?|JobName:CronExpression| |Redis__Enabled|Enable Redis|N|false|true/false| |Redis__ConnectionString|Redis ConnectString|N|N/A|N/A| |Redis__DefaultDatabase|Default Database of Redis|N|0|0| +|Redis__ConnectTimeoutMs|Redis connect timeout (ms)|N|5000|1000~30000| +|Redis__AsyncTimeoutMs|Redis async command timeout (ms)|N|2000|500~30000| +|Redis__SyncTimeoutMs|Redis sync command timeout (ms)|N|2000|500~30000| +|Redis__KeepAliveSeconds|Redis keepalive interval (seconds)|N|15|5~300| +|Redis__ConnectRetry|Redis connect retry count|N|3|1~10| +|Redis__ReconnectRetryBaseDelayMs|Redis reconnect exponential retry base delay (ms)|N|3000|500~30000| +|Redis__OperationTimeoutMs|JWT revocation check operation timeout (ms)|N|1200|200~5000| +|Redis__FailureCooldownSeconds|Fallback cooldown after Redis failure (seconds)|N|30|5~300| |Idempotency__Enabled|Enable Idempotency-Key middleware|N|true|true/false| |Idempotency__EnforceKey|Require Idempotency-Key for write requests|N|false|true/false| |Idempotency__MaxKeyLength|Maximum Idempotency-Key length|N|128|integer >= 16| diff --git a/README.md b/README.md index 79cae06b4a42029a9cf0b21e94cd9dea5308875d..ba8b8cba5db3dee17d22435297d1af4be3fe706a 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@

## 项目简介 @@ -193,12 +194,20 @@ docker run -d \ |AllowedOrigins__0|允许域站点,用于开发环境|Y|http://localhost:8080|http://localhost:8080| |AllowedOrigins__1|允许域站点,用于生产环境|Y|https://www.yourdomain.com|https://www.yourdomain.com| |SoftwareVersion|软件版本号,用于标记说明|N|N/A|N/A| -|JobKeys__0|定时任务1|Y|ReservationExpirationCheckJob|ReservationExpirationCheckJob| -|JobKeys__1|定时任务2|Y|MailServiceCheckJob|MailServiceCheckJob| -|JobKeys__2|定时任务3|Y|RedisServiceCheckJob|RedisServiceCheckJob| +|JobKeys__0|定时任务1|Y|ReservationExpirationCheckJob:0 0 1 * * ?|JobName:CronExpression| +|JobKeys__1|定时任务2|Y|MailServiceCheckJob:0 */5 * * * ?|JobName:CronExpression| +|JobKeys__2|定时任务3|Y|RedisServiceCheckJob:0 */5 * * * ?|JobName:CronExpression| |Redis__Enabled|是否启用Redis服务|N|false|true/false| |Redis__ConnectionString|Redis连接字符串|N|N/A|N/A| |Redis__DefaultDatabase|默认数据库|N|0|0| +|Redis__ConnectTimeoutMs|Redis 建连超时(毫秒)|N|5000|1000~30000| +|Redis__AsyncTimeoutMs|Redis 异步命令超时(毫秒)|N|2000|500~30000| +|Redis__SyncTimeoutMs|Redis 同步命令超时(毫秒)|N|2000|500~30000| +|Redis__KeepAliveSeconds|Redis KeepAlive 间隔(秒)|N|15|5~300| +|Redis__ConnectRetry|Redis 连接重试次数|N|3|1~10| +|Redis__ReconnectRetryBaseDelayMs|Redis 重连指数退避基准延迟(毫秒)|N|3000|500~30000| +|Redis__OperationTimeoutMs|JWT 吊销检查操作超时(毫秒)|N|1200|200~5000| +|Redis__FailureCooldownSeconds|Redis 失败后熔断冷却时间(秒)|N|30|5~300| |Idempotency__Enabled|是否启用幂等键中间件|N|true|true/false| |Idempotency__EnforceKey|是否强制写请求必须携带 Idempotency-Key|N|false|true/false| |Idempotency__MaxKeyLength|Idempotency-Key 最大长度|N|128|>=16 的整数|