From 3b0c316928d33a05dda6cd9946d0434fad8c9122 Mon Sep 17 00:00:00 2001 From: lq1405 <2769838458@qq.com> Date: Wed, 13 Nov 2024 14:00:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=8F=90=E7=A4=BA=E8=AF=8D?= =?UTF-8?q?=E9=A2=84=E8=AE=BE=E7=9A=84=E6=8E=A5=E5=8F=A3=EF=BC=8C=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E8=BD=AC=E5=8F=91=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LMS.Common/Dictionary/AllOptions.cs | 3 +- LMS.Common/Enum/PromptEnum.cs | 23 +- LMS.DAO/ApplicationDbContext.cs | 4 + LMS.DAO/UserDAO/UserBasicDAO.cs | 19 + LMS.Repository/DB/Options.cs | 68 ++-- LMS.Repository/DB/Prompt.cs | 6 +- LMS.Repository/DB/PromptType.cs | 38 +- LMS.Repository/DB/Role.cs | 3 +- LMS.Repository/DTO/PromptDto/PromptDto.cs | 15 + LMS.Repository/DTO/PromptDto/PromptNameDto.cs | 10 + .../DTO/PromptTypeDto/PrompTypeNameModel.cs | 8 + .../DTO/PromptTypeDto/PromptTypeBasic.cs | 29 ++ .../DTO/PromptTypeDto/PromptTypeDto.cs | 12 + LMS.Repository/Forward/ForwardModel.cs | 48 +++ LMS.Repository/LMS.Repository.csproj | 4 - .../PromptModel/ModifyPromptModel.cs | 45 +++ .../PromptModel/ModifyPromptTypeModal.cs | 29 ++ LMS.service/Configuration/AutoMapperConfig.cs | 11 + .../DatabaseConfiguration.cs | 1 + .../Configuration/ServiceConfiguration.cs | 5 + LMS.service/Controllers/ForwardController.cs | 73 ++++ LMS.service/Controllers/PromptController.cs | 216 ++++++++++ LMS.service/LMS.service.csproj | 1 + LMS.service/Service/ForwardWordService.cs | 147 +++++++ LMS.service/Service/MachineService.cs | 33 +- .../Service/PromptService/PromptService.cs | 377 ++++++++++++++++++ .../PromptService/PromptTypeService.cs | 358 +++++++++++++++++ 27 files changed, 1487 insertions(+), 99 deletions(-) create mode 100644 LMS.Repository/DTO/PromptDto/PromptDto.cs create mode 100644 LMS.Repository/DTO/PromptDto/PromptNameDto.cs create mode 100644 LMS.Repository/DTO/PromptTypeDto/PrompTypeNameModel.cs create mode 100644 LMS.Repository/DTO/PromptTypeDto/PromptTypeBasic.cs create mode 100644 LMS.Repository/DTO/PromptTypeDto/PromptTypeDto.cs create mode 100644 LMS.Repository/Forward/ForwardModel.cs create mode 100644 LMS.Repository/PromptModel/ModifyPromptModel.cs create mode 100644 LMS.Repository/PromptModel/ModifyPromptTypeModal.cs create mode 100644 LMS.service/Controllers/ForwardController.cs create mode 100644 LMS.service/Controllers/PromptController.cs create mode 100644 LMS.service/Service/ForwardWordService.cs create mode 100644 LMS.service/Service/PromptService/PromptService.cs create mode 100644 LMS.service/Service/PromptService/PromptTypeService.cs diff --git a/LMS.Common/Dictionary/AllOptions.cs b/LMS.Common/Dictionary/AllOptions.cs index baebdc9..f44015c 100644 --- a/LMS.Common/Dictionary/AllOptions.cs +++ b/LMS.Common/Dictionary/AllOptions.cs @@ -6,6 +6,7 @@ public class AllOptions { { "all", [] }, { "tts", ["EdgeTTsRoles"] }, - { "software", ["LaitoolHomePage", "LaitoolNotice", "LaitoolUpdateContent","LaitoolVersion"]} + { "software", ["LaitoolHomePage", "LaitoolNotice", "LaitoolUpdateContent","LaitoolVersion"]}, + { "trial" , ["LaiToolTrialDays"] } }; } diff --git a/LMS.Common/Enum/PromptEnum.cs b/LMS.Common/Enum/PromptEnum.cs index 2e66584..c3b2bfe 100644 --- a/LMS.Common/Enum/PromptEnum.cs +++ b/LMS.Common/Enum/PromptEnum.cs @@ -2,14 +2,6 @@ { public class PromptEnum { - public enum PromptType - { - /// - /// 开头提示词 - /// - StartPrompt = 0, - } - public class PromptStatus { /// @@ -21,6 +13,15 @@ ///提示词状态:禁用 /// public const string Disable = "disable"; + + /// + /// 所有有效的提示词类型状态 + /// + public static readonly HashSet ValidStatuses = + [ + Enable, + Disable + ]; } public class PromptTypeStatus @@ -38,11 +39,11 @@ /// /// 所有有效的提示词类型状态 /// - public static readonly HashSet ValidStatuses = new HashSet - { + public static readonly HashSet ValidStatuses = + [ Enable, Disable - }; + ]; } } diff --git a/LMS.DAO/ApplicationDbContext.cs b/LMS.DAO/ApplicationDbContext.cs index 723eedd..5d8fff3 100644 --- a/LMS.DAO/ApplicationDbContext.cs +++ b/LMS.DAO/ApplicationDbContext.cs @@ -20,6 +20,10 @@ namespace LMS.DAO public DbSet PermissionType { get; set; } + public DbSet PromptType { get; set; } + + public DbSet Prompt { get; set; } + public DbSet Machine { get; set; } public DbSet RefreshTokens { get; set; } diff --git a/LMS.DAO/UserDAO/UserBasicDAO.cs b/LMS.DAO/UserDAO/UserBasicDAO.cs index f8cdea4..efdcc69 100644 --- a/LMS.DAO/UserDAO/UserBasicDAO.cs +++ b/LMS.DAO/UserDAO/UserBasicDAO.cs @@ -1,5 +1,6 @@ using LMS.Repository.Models.DB; using Microsoft.AspNetCore.Identity; +using OneOf.Types; using System; using System.Collections.Generic; using System.Linq; @@ -24,6 +25,24 @@ namespace LMS.DAO.UserDAO } return await _userManager.FindByIdAsync(userId.ToString()) != null; } + + /// + /// 判断传入的数据是不是有管理员权限或者是超级管理员权限 + /// + /// + /// + /// + public async Task CheckUserIsAdminOrSuperAdmin(long? userId) + { + if (userId == null) + { + return false; + } + User? user = await _userManager.FindByIdAsync(userId.ToString() ?? "0") ?? throw new Exception("用户不存在"); + + bool isAdminOrSuperAdmin = await _userManager.IsInRoleAsync(user, "Admin") || await _userManager.IsInRoleAsync(user, "Super Admin"); + return isAdminOrSuperAdmin; + } } } diff --git a/LMS.Repository/DB/Options.cs b/LMS.Repository/DB/Options.cs index cab9e8a..5695cad 100644 --- a/LMS.Repository/DB/Options.cs +++ b/LMS.Repository/DB/Options.cs @@ -1,5 +1,6 @@ using LMS.Common.Enum; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; @@ -18,44 +19,47 @@ public class Options public OptionTypeEnum Type { get; set; } = OptionTypeEnum.String; // 写一个字段,映射Value,判断是不是json字符串,是的话就解析成对象 - [NotMapped] - public object? ValueObject + // 写一个字段,映射Value,判断是不是json字符串,是的话就解析成对象 + public T? GetValueObject() { - get + if (string.IsNullOrEmpty(Value)) { - if (string.IsNullOrEmpty(Value)) - { - return Value; - } - - if (Type == OptionTypeEnum.JSON) - { - return JsonConvert.DeserializeObject(Value ?? "{}"); - } - - if (Type == OptionTypeEnum.Number) - { - return Convert.ToDouble(Value); - } - - return Value; + return default; } - set - { - if (value == null) - { - Value = string.Empty; - return; - } - if (Type == OptionTypeEnum.JSON) + if (Type == OptionTypeEnum.JSON) + { + return JsonConvert.DeserializeObject(Value ?? "{}"); + } + + if (Type == OptionTypeEnum.Number) + { + if (double.TryParse(Value, out double result)) { - Value = JsonConvert.SerializeObject(value); - } - else - { - Value = value.ToString(); + return (T)Convert.ChangeType(result, typeof(T)); } + return default; + } + + return (T)Convert.ChangeType(Value, typeof(T)); + } + + // 写一个方法,设置Value的值 + public void SetValueObject(T value) + { + if (value == null) + { + Value = string.Empty; + return; + } + + if (Type == OptionTypeEnum.JSON) + { + Value = JsonConvert.SerializeObject(value); + } + else + { + Value = value.ToString(); } } } diff --git a/LMS.Repository/DB/Prompt.cs b/LMS.Repository/DB/Prompt.cs index afaa291..4de484a 100644 --- a/LMS.Repository/DB/Prompt.cs +++ b/LMS.Repository/DB/Prompt.cs @@ -1,4 +1,4 @@ -namespace LMS.Repository.Models.DB +namespace LMS.Repository.DB { public class Prompt { @@ -45,7 +45,7 @@ /// /// 创建者 /// - public string CreateUserId { get; set; } + public long CreateUserId { get; set; } /// /// 创建时间 @@ -55,7 +55,7 @@ /// /// 更新者 /// - public string UpdateUserId { get; set; } + public long UpdateUserId { get; set; } /// /// 更新时间 diff --git a/LMS.Repository/DB/PromptType.cs b/LMS.Repository/DB/PromptType.cs index f204e63..15f1f22 100644 --- a/LMS.Repository/DB/PromptType.cs +++ b/LMS.Repository/DB/PromptType.cs @@ -1,35 +1,12 @@ -namespace LMS.Repository.Models.DB +using LMS.Repository.DTO.PromptTypeDto; + +namespace LMS.Repository.Models.DB { /// /// 提示词类型的库 /// - public class PromptType + public class PromptType : PromptTypeBasic { - /// - /// ID - /// - public string Id { get; set; } - - /// - /// 提示词类型编码 - /// - public string Code { get; set; } - - /// - /// 提示词类型名称 - /// - public string Name { get; set; } - - /// - /// 提示词类型描述 - /// - public string? Remark { get; set; } - - /// - /// 提示词类型状态 - /// - public string Status { get; set; } - /// /// 是否删除 /// @@ -38,7 +15,7 @@ /// /// 创建用户ID /// - public string CreateUserId { get; set; } + public long CreateUserId { get; set; } /// /// 创建时间 @@ -48,14 +25,11 @@ /// /// 更新者ID /// - public string UpdateUserId { get; set; } + public long UpdateUserId { get; set; } /// /// 更新时间 /// public DateTime UpdateTime { get; set; } - - - } } diff --git a/LMS.Repository/DB/Role.cs b/LMS.Repository/DB/Role.cs index b4b1f52..d4af099 100644 --- a/LMS.Repository/DB/Role.cs +++ b/LMS.Repository/DB/Role.cs @@ -1,5 +1,4 @@ -using LMS.Tools.Extensions; -using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity; namespace LMS.Repository.Models.DB { diff --git a/LMS.Repository/DTO/PromptDto/PromptDto.cs b/LMS.Repository/DTO/PromptDto/PromptDto.cs new file mode 100644 index 0000000..4a404c5 --- /dev/null +++ b/LMS.Repository/DTO/PromptDto/PromptDto.cs @@ -0,0 +1,15 @@ +using LMS.Repository.DB; +using LMS.Repository.DTO.PromptTypeDto; +using LMS.Repository.DTO.UserDto; + +namespace LMS.Repository.DTO.PromptDto; + +public class PromptDto : Prompt +{ + + public UserBaseDto CreatedUser { get; set; } + + public UserBaseDto UpdatedUser { get; set; } + + public PromptTypeBasic? PromptType { get; set; } +} diff --git a/LMS.Repository/DTO/PromptDto/PromptNameDto.cs b/LMS.Repository/DTO/PromptDto/PromptNameDto.cs new file mode 100644 index 0000000..857f958 --- /dev/null +++ b/LMS.Repository/DTO/PromptDto/PromptNameDto.cs @@ -0,0 +1,10 @@ +namespace LMS.Repository.DTO.PromptDto; + +public class PromptNameDto +{ + public string Id { get; set; } + + public string Name { get; set; } + + public string PromptTypeId { get; set; } +} diff --git a/LMS.Repository/DTO/PromptTypeDto/PrompTypeNameModel.cs b/LMS.Repository/DTO/PromptTypeDto/PrompTypeNameModel.cs new file mode 100644 index 0000000..8558096 --- /dev/null +++ b/LMS.Repository/DTO/PromptTypeDto/PrompTypeNameModel.cs @@ -0,0 +1,8 @@ +namespace LMS.Repository.DTO.PromptTypeDto; + +public class PrompTypeNameModel +{ + public string Name { get; set; } + + public string Id { get; set; } +} diff --git a/LMS.Repository/DTO/PromptTypeDto/PromptTypeBasic.cs b/LMS.Repository/DTO/PromptTypeDto/PromptTypeBasic.cs new file mode 100644 index 0000000..f5ec73e --- /dev/null +++ b/LMS.Repository/DTO/PromptTypeDto/PromptTypeBasic.cs @@ -0,0 +1,29 @@ +namespace LMS.Repository.DTO.PromptTypeDto; + +public class PromptTypeBasic +{ + /// + /// ID + /// + public string Id { get; set; } + + /// + /// 提示词类型编码 + /// + public string Code { get; set; } + + /// + /// 提示词类型名称 + /// + public string Name { get; set; } + + /// + /// 提示词类型描述 + /// + public string? Remark { get; set; } + + /// + /// 提示词类型状态 + /// + public string Status { get; set; } +} diff --git a/LMS.Repository/DTO/PromptTypeDto/PromptTypeDto.cs b/LMS.Repository/DTO/PromptTypeDto/PromptTypeDto.cs new file mode 100644 index 0000000..39c9ce1 --- /dev/null +++ b/LMS.Repository/DTO/PromptTypeDto/PromptTypeDto.cs @@ -0,0 +1,12 @@ +using LMS.Repository.DTO.UserDto; +using LMS.Repository.Models.DB; + +namespace LMS.Repository.DTO.PromptTypeDto +{ + public class PromptTypeDto : PromptType + { + public UserBaseDto? UpdatedUser { get; set; } + + public UserBaseDto? CreatedUser { get; set; } + } +} diff --git a/LMS.Repository/Forward/ForwardModel.cs b/LMS.Repository/Forward/ForwardModel.cs new file mode 100644 index 0000000..17a225f --- /dev/null +++ b/LMS.Repository/Forward/ForwardModel.cs @@ -0,0 +1,48 @@ +using System.ComponentModel.DataAnnotations; + +namespace LMS.Repository.Forward; + +public class ForwardModel +{ + /// + /// 提示词类型ID + /// + [Required] + public string PromptTypeId { get; set; } + + /// + /// 提示词ID + /// + [Required] + public string PromptId { get; set; } + + /// + /// GPT 请求网址 + /// + [Required] + public string GptUrl { get; set; } + + /// + /// 调用的模型 + /// + [Required] + public string Model { get; set; } + + /// + /// 机器码 + /// + [Required] + public string MachineId { get; set; } + + /// + /// API Key + /// + [Required] + public string ApiKey { get; set; } + + /// + /// 处理之前的文案,基础文案 + /// + [Required] + public string Word { get; set; } = string.Empty; +} diff --git a/LMS.Repository/LMS.Repository.csproj b/LMS.Repository/LMS.Repository.csproj index e389625..31743cd 100644 --- a/LMS.Repository/LMS.Repository.csproj +++ b/LMS.Repository/LMS.Repository.csproj @@ -6,10 +6,6 @@ enable - - - - diff --git a/LMS.Repository/PromptModel/ModifyPromptModel.cs b/LMS.Repository/PromptModel/ModifyPromptModel.cs new file mode 100644 index 0000000..822bb90 --- /dev/null +++ b/LMS.Repository/PromptModel/ModifyPromptModel.cs @@ -0,0 +1,45 @@ +using System.ComponentModel.DataAnnotations; + +namespace LMS.Repository.PromptModel; + +public class ModifyPromptModel +{ + /// + /// 名称 + /// + [Required] + public string Name { get; set; } + + /// + /// 提示词类型 + /// + [Required] + public string PromptTypeId { get; set; } + + /// + /// 提示词预设字符串 + /// + [Required] + public string PromptString { get; set; } + + /// + /// 描述 + /// + public string? Description { get; set; } + + /// + /// 备注 + /// + public string? Remark { get; set; } + + /// + /// 版本 + /// + public int Version { get; set; } + + [Required] + /// + /// 状态 + /// + public string Status { get; set; } +} diff --git a/LMS.Repository/PromptModel/ModifyPromptTypeModal.cs b/LMS.Repository/PromptModel/ModifyPromptTypeModal.cs new file mode 100644 index 0000000..1370cde --- /dev/null +++ b/LMS.Repository/PromptModel/ModifyPromptTypeModal.cs @@ -0,0 +1,29 @@ +using System.ComponentModel.DataAnnotations; + +namespace LMS.Repository.PromptModel; + +public class ModifyPromptTypeModal +{ + /// + /// 名称 + /// + [Required] + public string Name { get; set; } + + /// + /// 提示词类型编码 + /// + [Required] + public string Code { get; set; } + + /// + /// 状态 + /// + [Required] + public string Status { get; set; } + + /// + /// 备注 + /// + public string? Remark { get; set; } = string.Empty; +} diff --git a/LMS.service/Configuration/AutoMapperConfig.cs b/LMS.service/Configuration/AutoMapperConfig.cs index 0ce4bb7..b2755fd 100644 --- a/LMS.service/Configuration/AutoMapperConfig.cs +++ b/LMS.service/Configuration/AutoMapperConfig.cs @@ -1,10 +1,13 @@ using AutoMapper; using LMS.Repository.DB; using LMS.Repository.DTO; +using LMS.Repository.DTO.PromptDto; +using LMS.Repository.DTO.PromptTypeDto; using LMS.Repository.DTO.UserDto; using LMS.Repository.Models.DB; using LMS.Repository.Models.Machine; using LMS.Repository.Models.Promission; +using LMS.Repository.PromptModel; using LMS.Repository.RequestModel.Permission; using static LMS.Repository.DTO.MachineResponse.MachineDto; @@ -30,6 +33,14 @@ namespace Lai_server.Configuration CreateMap(); + CreateMap(); + + CreateMap(); + + CreateMap(); + + CreateMap(); + } } } diff --git a/LMS.service/Configuration/InitConfiguration/DatabaseConfiguration.cs b/LMS.service/Configuration/InitConfiguration/DatabaseConfiguration.cs index a22d12e..b03d0c8 100644 --- a/LMS.service/Configuration/InitConfiguration/DatabaseConfiguration.cs +++ b/LMS.service/Configuration/InitConfiguration/DatabaseConfiguration.cs @@ -102,6 +102,7 @@ public class DatabaseConfiguration(IServiceProvider serviceProvider) : IHostedSe new Options { Key = "LaitoolUpdateContent", Value = string.Empty, Type = OptionTypeEnum.String }, new Options { Key = "LaitoolNotice", Value = string.Empty, Type = OptionTypeEnum.String }, new Options { Key = "LaitoolVersion", Value = string.Empty, Type = OptionTypeEnum.String }, + new Options { Key = "LaiToolTrialDays", Value = "2" , Type = OptionTypeEnum.Number} ]; // 遍历所有的配置项,如果没有则添加 diff --git a/LMS.service/Configuration/ServiceConfiguration.cs b/LMS.service/Configuration/ServiceConfiguration.cs index 4393cb3..0b5e103 100644 --- a/LMS.service/Configuration/ServiceConfiguration.cs +++ b/LMS.service/Configuration/ServiceConfiguration.cs @@ -5,6 +5,7 @@ using LMS.DAO.UserDAO; using LMS.service.Configuration.InitConfiguration; using LMS.service.Service; using LMS.service.Service.PermissionService; +using LMS.service.Service.PromptService; using LMS.service.Service.RoleService; using LMS.service.Service.UserService; @@ -27,6 +28,10 @@ namespace Lai_server.Configuration services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + // 注入 DAO diff --git a/LMS.service/Controllers/ForwardController.cs b/LMS.service/Controllers/ForwardController.cs new file mode 100644 index 0000000..2894c48 --- /dev/null +++ b/LMS.service/Controllers/ForwardController.cs @@ -0,0 +1,73 @@ +using LMS.DAO; +using LMS.Repository.Forward; +using LMS.service.Service; +using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using static LMS.Common.Enums.ResponseCodeEnum; + +namespace LMS.service.Controllers; + +[Route("lms/[controller]/[action]")] +[ApiController] +public class ForwardController(ForwardWordService forwardWordService) : ControllerBase +{ + private readonly ForwardWordService _forwardWordService = forwardWordService; + + /// + /// 转发OpenAi格式的请求 + /// + /// + /// + [HttpPost] + public async Task>> ForwardWord([FromBody] ForwardModel request) + { + if (!ModelState.IsValid) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError); + } + return await _forwardWordService.ForwardWord(request); + } + + /// + /// 流式转发 + /// + /// + /// + [HttpPost] + public async Task ForwardWordStream([FromBody] ForwardModel req) + { + try + { + HttpContext.Response.ContentType = "text/event-stream"; + HttpContext.Response.Headers.Add("Cache-Control", "no-cache"); + HttpContext.Response.Headers.Add("Connection", "keep-alive"); + + var settings = new JsonSerializerSettings + { + ContractResolver = new LowercaseContractResolver(), + Formatting = Formatting.Indented + }; + + await foreach (var s in _forwardWordService.ForwardWordStream(req)) + { + // 确保遵循SSE的消息格式 + //var data = "data: " + JsonConvert.SerializeObject(s, settings) + "\n\n"; + await Response.WriteAsync(s); + await Response.Body.FlushAsync(); // 确保即时发送 + } + } + catch (Exception e) + { + return BadRequest(e.Message); + } + return new EmptyResult(); + } + public class LowercaseContractResolver : DefaultContractResolver + { + protected override string ResolvePropertyName(string propertyName) + { + return propertyName.ToLower(); + } + } +} diff --git a/LMS.service/Controllers/PromptController.cs b/LMS.service/Controllers/PromptController.cs new file mode 100644 index 0000000..aa8f556 --- /dev/null +++ b/LMS.service/Controllers/PromptController.cs @@ -0,0 +1,216 @@ +using LMS.DAO; +using LMS.Repository.DTO; +using LMS.Repository.DTO.PromptDto; +using LMS.Repository.DTO.PromptTypeDto; +using LMS.Repository.PromptModel; +using LMS.service.Service.PromptService; +using LMS.Tools.Extensions; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; +using static LMS.Common.Enums.PromptEnum; +using static LMS.Common.Enums.ResponseCodeEnum; + +namespace LMS.service.Controllers +{ + [Route("lms/[controller]/[action]")] + [ApiController] + public class PromptController : ControllerBase + { + private readonly ApplicationDbContext _context; + private readonly PromptTypeService _promptTypeService; + private readonly PromptService _promptService; + + + public PromptController(ApplicationDbContext context, PromptTypeService promptTypeService, PromptService promptService) + { + _context = context; + _promptTypeService = promptTypeService; + _promptService = promptService; + } + + #region 提示词类型相关 + + /// + /// 获取当前的所有的提示词类型(分页) + /// + /// 每页的数量 + /// 当前页 + /// + [HttpGet] + [Authorize] + public async Task>>> QueryPromptypeCollection([Required] int page, [Required] int pageSize, string? code, string? name, string? status, string? remark) + { + long reuqertUserId = ConvertExtension.ObjectToLong(HttpContext.Items["UserId"] ?? 0); + return await _promptTypeService.QueryPromptypeCollection(page, pageSize, code, name, status, remark, reuqertUserId); + } + + /// + /// 获取所有的提示词类型的选项,ID和Name + /// + /// + [HttpGet] + public async Task>>> GetPromptTypeOptions() + { + return await _promptTypeService.GetPromptTypeOptions(); + } + + /// + /// 通过ID获取详细的提示词类型信息 + /// + /// + /// + [HttpGet("{id}")] + [Authorize] + public async Task>> GetPromptTypeInfo(string id) + { + long reuqertUserId = ConvertExtension.ObjectToLong(HttpContext.Items["UserId"] ?? 0); + return await _promptTypeService.GetPromptTypeInfo(id, reuqertUserId); + } + + /// + /// 修改提示词数据 + /// + /// + /// + /// + [HttpPost("{id}")] + [Authorize] + public async Task>> ModityPromptType(string id, [FromBody] ModifyPromptTypeModal modal) + { + if (!ModelState.IsValid) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError); + } + long reuqertUserId = ConvertExtension.ObjectToLong(HttpContext.Items["UserId"] ?? 0); + return await _promptTypeService.ModityPromptType(id, modal, reuqertUserId); + } + + /// + /// 添加提示词类型数据 + /// + /// + /// + [HttpPost] + [Authorize] + public async Task>> AddPromptType([FromBody] ModifyPromptTypeModal modal) + { + if (!ModelState.IsValid) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError); + } + long reuqertUserId = ConvertExtension.ObjectToLong(HttpContext.Items["UserId"] ?? 0); + return await _promptTypeService.AddPromptType(modal, reuqertUserId); + } + + /// + /// 删除提示词类型数据 + /// + /// + /// + [HttpDelete("{id}/{deletePrompt}")] + [Authorize] + public async Task>> DeletePromptType(string id, bool deletePrompt) + { + long reuqertUserId = ConvertExtension.ObjectToLong(HttpContext.Items["UserId"] ?? 0); + return await _promptTypeService.DeletePromptType(id, reuqertUserId, deletePrompt); + } + + #endregion + + + #region 提示词相关 + + /// + /// 获取提示词数据的集合 + /// + /// + /// + /// + /// + /// + /// + /// + [HttpGet] + [Authorize] + public async Task>>> QueryPromptStringCollection([Required] int page, [Required] int pageSize, string? name, string? promptTypeId, string? status, string? remark) + { + long reuqertUserId = ConvertExtension.ObjectToLong(HttpContext.Items["UserId"] ?? 0); + return await _promptService.QueryPromptStringCollection(page, pageSize, name, promptTypeId, status, remark, reuqertUserId); + } + + /// + /// 获取指定提示词的详细信息 + /// + /// + /// + [HttpGet("{id}")] + [Authorize] + public async Task>> GetPromptInfo(string id) + { + long reuqertUserId = ConvertExtension.ObjectToLong(HttpContext.Items["UserId"] ?? 0); + return await _promptService.GetPromptInfo(id, reuqertUserId); + } + + /// + /// 修改提示词预设数据 + /// + /// + /// + /// + [HttpPost("{id}")] + [Authorize] + public async Task>> ModifyPrompt(string id, [FromBody] ModifyPromptModel model) + { + if (!ModelState.IsValid) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError); + } + long requertUserId = ConvertExtension.ObjectToLong(HttpContext.Items["UserId"] ?? 0); + return await _promptService.ModifyPrompt(id, model, requertUserId); + } + + /// + /// 添加提示词数据 + /// + /// + /// + [HttpPost] + [Authorize] + public async Task>> AddPrompt([FromBody] ModifyPromptModel model) + { + if (!ModelState.IsValid) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError); + } + long requertUserId = ConvertExtension.ObjectToLong(HttpContext.Items["UserId"] ?? 0); + return await _promptService.AddPrompt(model, requertUserId); + } + + /// + /// 删除提示词数据 + /// + /// + /// + [HttpDelete("{id}")] + [Authorize] + public async Task>> DeletePrompt(string id) + { + long requertUserId = ConvertExtension.ObjectToLong(HttpContext.Items["UserId"] ?? 0); + return await _promptService.DeletePrompt(id, requertUserId); + } + + /// + /// 获取所有的或者是指定的提示词预设数据 ID、Name + /// + /// + [HttpGet("{option}")] + public async Task>>> GetPromptOptions(string option) + { + return await _promptService.GetPromptOptions(option); + } + + #endregion + + } +} diff --git a/LMS.service/LMS.service.csproj b/LMS.service/LMS.service.csproj index 9b443d9..83a9e0e 100644 --- a/LMS.service/LMS.service.csproj +++ b/LMS.service/LMS.service.csproj @@ -12,6 +12,7 @@ + diff --git a/LMS.service/Service/ForwardWordService.cs b/LMS.service/Service/ForwardWordService.cs new file mode 100644 index 0000000..b67a376 --- /dev/null +++ b/LMS.service/Service/ForwardWordService.cs @@ -0,0 +1,147 @@ +using LMS.DAO; +using LMS.Repository.DB; +using LMS.Repository.Forward; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Newtonsoft.Json; +using static LMS.Common.Enums.ResponseCodeEnum; +using System.Net; +using System.Text; +using LMS.Repository.Model; +using LMS.Tools; +using Betalgo.Ranul.OpenAI.Managers; +using Betalgo.Ranul.OpenAI; +using Betalgo.Ranul.OpenAI.ObjectModels.RequestModels; + +namespace LMS.service.Service; + +public class ForwardWordService(ApplicationDbContext context) +{ + private readonly ApplicationDbContext _context = context; + /// + /// 转发OpenAi格式的请求 非流 + /// + /// + /// + /// + public async Task>> ForwardWord(ForwardModel request) + { + try + { + // 要校验机器码,但是目前不需要 + + if (request.Word == null || request.Word == "") + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError); + } + + // 获取提示词预设 + Prompt? prompt = await _context.Prompt.FirstOrDefaultAsync(x => x.PromptTypeId == request.PromptTypeId && x.Id == request.PromptId); + if (prompt == null) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.FindPromptStringFail); + } + + // 开始拼接请求体 + using HttpClient client = new HttpClient(); + client.DefaultRequestHeaders.Add("Authorization", "Bearer " + request.ApiKey); + string json = JsonConvert.SerializeObject(new + { + model = request.Model, + temperature = 0.3, + messages = new List + { + new OpenAI.RequestMessage + { + role = "system", + content = prompt.PromptString + + }, + new OpenAI.RequestMessage + { + role = "user", + content = request.Word + } + } + }); + + // 判断请求的url是不是满足条件 + if (string.IsNullOrEmpty(request.GptUrl)) + { + throw new Exception("请求的url为空"); + } + if (!request.GptUrl.StartsWith("https://ark.cn-beijing.volces.com") && !request.GptUrl.StartsWith("https://api.moonshot.cn") && !request.GptUrl.StartsWith("https://laitool.net") && !request.GptUrl.StartsWith("https://api.laitool.cc") && !request.GptUrl.StartsWith("https://laitool.cc")) + { + throw new Exception("请求的url不合法"); + } + client.Timeout = Timeout.InfiniteTimeSpan; + var response = await client.PostAsync(request.GptUrl, new StringContent(json, Encoding.UTF8, "application/json")); + + // 判断返回的状态码 + if (response.StatusCode != HttpStatusCode.OK) + { + // 读取响应体 + string responseContent = await response.Content.ReadAsStringAsync(); + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ForwardWordFail, responseContent, "请求失败"); + } + var content = await response.Content.ReadAsStringAsync(); + // 序列化一下 + return APIResponseModel.CreateSuccessResponseModel(content); + } + catch (Exception e) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.SystemError, e.Message); + } + } + + public async IAsyncEnumerable ForwardWordStream(ForwardModel request) + { + + // 要校验机器码,但是目前不需要 + + if (request.Word == null || request.Word == "") + { + throw new Exception("参数错误"); + } + + // 获取提示词预设 + Prompt? prompt = await _context.Prompt.FirstOrDefaultAsync(x => x.PromptTypeId == request.PromptTypeId && x.Id == request.PromptId); + if (prompt == null) + { + throw new Exception(ResponseCode.FindPromptStringFail.GetResult()); + } + var openAiService = new OpenAIService(new OpenAIOptions() + { + ApiKey = request.ApiKey, + BaseDomain = request.GptUrl, + }); + var completionResult = openAiService.ChatCompletion.CreateCompletionAsStream(new ChatCompletionCreateRequest + { + Messages = new List + { + ChatMessage.FromSystem(prompt.PromptString), + ChatMessage.FromUser(request.Word) + }, + Model = request.Model, + Stream = true + }); + + await foreach (var completion in completionResult) + { + if (completion.Successful) + { // 这边只返回数据,不返回全部的数据结构了 + yield return completion.Choices.First().Message.Content ?? ""; + } + else + { + if (completion.Error == null) + { + throw new Exception("Unknown Error"); + } + + throw new Exception($"{completion.Error.Code}: {completion.Error.Message}"); + } + } + + } +} diff --git a/LMS.service/Service/MachineService.cs b/LMS.service/Service/MachineService.cs index 0923553..074b1c6 100644 --- a/LMS.service/Service/MachineService.cs +++ b/LMS.service/Service/MachineService.cs @@ -109,7 +109,7 @@ namespace LMS.service.Service return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError); } // 判断OwnerUserId是不是还能添加 - User? ownerUser = await _userManager.FindByIdAsync(request.UserId.ToString()); + User? ownerUser = await _userManager.FindByIdAsync((request.UserId ?? reqId).ToString()); if (ownerUser == null) { return APIResponseModel.CreateErrorResponseModel(ResponseCode.FindUserByIdFail); @@ -142,7 +142,7 @@ namespace LMS.service.Service if (request.UseStatus == MachineUseStatus.Trial) { - var checkRes = await CanAddPermanentMachine(ownerUser, (long)request.UserId, null, false); + var checkRes = await CanAddPermanentMachine(ownerUser, (long)(request.UserId ?? reqId), null, false); if (checkRes.Code != 1) { return checkRes; @@ -160,11 +160,19 @@ namespace LMS.service.Service return APIResponseModel.CreateErrorResponseModel(ResponseCode.InvalidOptions, "到期时间不能小于当前时间"); } Console.WriteLine(BeijingTimeExtension.GetBeijingTime().ToString()); - int s = (request.DeactivationTime - BeijingTimeExtension.GetBeijingTime()).Value.Days; - // 判断当前时间和现在的时间差大于三天,报错 - if ((request.DeactivationTime - BeijingTimeExtension.GetBeijingTime()).Value.Days >= 3) + + int s = ((request.DeactivationTime ?? BeijingTimeExtension.GetBeijingTime().AddDays(1)) - BeijingTimeExtension.GetBeijingTime()).Days; + + var LaiToolTrialDays = await _context.Options.FirstOrDefaultAsync(x => x.Key == "LaiToolTrialDays"); + if (LaiToolTrialDays == null) { - return APIResponseModel.CreateErrorResponseModel(ResponseCode.InvalidOptions, "到期时间不能超过三天"); + return APIResponseModel.CreateErrorResponseModel(ResponseCode.SystemError, "系统错误,未设置最大试用天数"); + } + double maxTrialDays = LaiToolTrialDays.GetValueObject(); + // 判断当前时间和现在的时间差大于三天,报错 + if (s >= maxTrialDays) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.InvalidOptions, $"到期时间不能超过 {maxTrialDays}天"); } // 先修改用户的免费更换次数 ownerUser.FreeCount -= 1; @@ -172,7 +180,7 @@ namespace LMS.service.Service } else { - var checkRes = await CanAddPermanentMachine(ownerUser, (long)request.UserId, null, true); + var checkRes = await CanAddPermanentMachine(ownerUser, (long)(request.UserId ?? reqId), null, true); if (checkRes.Code != 1) { return checkRes; @@ -283,12 +291,6 @@ namespace LMS.service.Service using var transaction = _context.Database.BeginTransaction(); try { - // 修改 - // 判断当前用户是否有修改和管理机器码的权限 - //if (!await _context.Permission.AnyAsync(x => x.UserId == reqId && (x.PermissionCode == SubPermissionType.ManageMachine || x.PermissionCode == SubPermissionType.ModifyMachine))) - //{ - // return APIResponseModel.CreateErrorResponseModel(ResponseCode.NotPermissionAction); - //} // 判断传入的userId是否存在 User? user = await _userManager.FindByIdAsync(reqId.ToString()); if (user == null) @@ -398,7 +400,10 @@ namespace LMS.service.Service machine.DeactivationTime = null; } machine.UseStatus = request.UseStatus; - machine.MachineId = request.MachineId; + if (isAdminOrSuperAdmin) + { + machine.MachineId = request.MachineId; + } machine.Status = request.Status; machine.Remark = request.Remark; _context.Machine.Update(machine); diff --git a/LMS.service/Service/PromptService/PromptService.cs b/LMS.service/Service/PromptService/PromptService.cs new file mode 100644 index 0000000..7a1fb61 --- /dev/null +++ b/LMS.service/Service/PromptService/PromptService.cs @@ -0,0 +1,377 @@ +using AutoMapper; +using LMS.DAO; +using LMS.DAO.UserDAO; +using LMS.Repository.DB; +using LMS.Repository.DTO; +using LMS.Repository.DTO.PromptDto; +using LMS.Repository.DTO.PromptTypeDto; +using LMS.Repository.DTO.UserDto; +using LMS.Repository.Models.DB; +using LMS.Repository.PromptModel; +using LMS.Tools.Extensions; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; +using static LMS.Common.Enums.PromptEnum; +using static LMS.Common.Enums.ResponseCodeEnum; + +namespace LMS.service.Service.PromptService; + +public class PromptService(UserBasicDao userBasicDao, ApplicationDbContext context, IMapper mapper, UserManager userManager) +{ + private readonly UserBasicDao _userBasicDao = userBasicDao; + private readonly ApplicationDbContext _context = context; + private readonly IMapper _mapper = mapper; + private readonly UserManager _userManager = userManager; + + #region 查询数据集合 + + /// + /// 获取提示词数据的集合 + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public async Task>>> QueryPromptStringCollection(int page, int pageSize, string? name, string? promptTypeId, string? status, string? remark, long requertUserId) + { + try + { + bool isAdminAndSuperAdmin = await _userBasicDao.CheckUserIsAdminOrSuperAdmin(requertUserId); + if (!isAdminAndSuperAdmin) + { + return APIResponseModel>.CreateErrorResponseModel(ResponseCode.NotPermissionAction); + } + IQueryable? query = _context.Prompt; + + if (!string.IsNullOrEmpty(name)) + { + query = query.Where(x => x.Name.Contains(name)); + } + + if (!string.IsNullOrEmpty(promptTypeId)) + { + query = query.Where(x => x.PromptTypeId == promptTypeId); + } + + if (!string.IsNullOrEmpty(status)) + { + if (!PromptStatus.ValidStatuses.Contains(status)) + { + return APIResponseModel>.CreateErrorResponseModel(ResponseCode.ParameterError, "Status is invalid"); + } + query = query.Where(x => x.Status == status); + } + + if (!string.IsNullOrEmpty(remark)) + { + query = query.Where(x => x.Remark.Contains(remark)); + } + + // 开始返回数据 + // 通过ID降序 + query = query.OrderByDescending(x => x.CreateTime); + + // 查询总数 + int total = await query.CountAsync(); + + // 分页 + query = query.Skip((page - 1) * pageSize).Take(pageSize); + + + List? prompts = await query.ToListAsync(); + + List promptDtos = []; + + for (int i = 0; prompts != null && i < prompts.Count; i++) + { + Prompt prompt = prompts[i]; + User? createdUser = await _userManager.FindByIdAsync(prompt.CreateUserId.ToString()); + User? updatedUser = await _userManager.FindByIdAsync(prompt.UpdateUserId.ToString()); + PromptDto promptDto = _mapper.Map(prompt); + promptDto.CreatedUser = _mapper.Map(createdUser); + promptDto.UpdatedUser = _mapper.Map(updatedUser); + + PromptType? promptType = await _context.PromptType.FirstOrDefaultAsync(x => x.Id == prompt.PromptTypeId); + promptDto.PromptType = _mapper.Map(promptType); + promptDtos.Add(promptDto); + } + return APIResponseModel>.CreateSuccessResponseModel(new CollectionResponse + { + Total = total, + Collection = promptDtos, + Current = page + }); + } + catch (Exception e) + { + return APIResponseModel>.CreateErrorResponseModel(ResponseCode.SystemError, e.Message); + } + } + #endregion + + #region 获取指定提示词的详细信息 + /// + /// 获取指定提示词的详细信息 + /// + /// 提示词数据的ID + /// + /// + /// + public async Task>> GetPromptInfo(string id, long reuqertUserId) + { + try + { + bool isAdminAndSuperAdmin = await _userBasicDao.CheckUserIsAdminOrSuperAdmin(reuqertUserId); + if (!isAdminAndSuperAdmin) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.NotPermissionAction); + } + Prompt? prompt = await _context.Prompt.FirstOrDefaultAsync(x => x.Id == id); + if (prompt == null) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.FindPromptStringFail); + } + PromptDto promptDto = _mapper.Map(prompt); + User? createdUser = await _userManager.FindByIdAsync(prompt.CreateUserId.ToString()); + User? updatedUser = await _userManager.FindByIdAsync(prompt.UpdateUserId.ToString()); + promptDto.CreatedUser = _mapper.Map(createdUser); + promptDto.UpdatedUser = _mapper.Map(updatedUser); + PromptType? promptType = await _context.PromptType.FirstOrDefaultAsync(x => x.Id == prompt.PromptTypeId); + promptDto.PromptType = _mapper.Map(promptType); + return APIResponseModel.CreateSuccessResponseModel(promptDto); + } + catch (Exception e) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.SystemError, e.Message); + } + } + + #endregion + + #region 修改提示词预设数据 + /// + /// 修改提示词预设数据 + /// + /// + /// + /// + /// + /// + public async Task>> ModifyPrompt(string id, ModifyPromptModel model, long requertUserId) + { + try + { + bool isAdminAndSuperAdmin = await _userBasicDao.CheckUserIsAdminOrSuperAdmin(requertUserId); + if (!isAdminAndSuperAdmin) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.NotPermissionAction); + } + + Prompt? prompt = await _context.Prompt.FirstOrDefaultAsync(x => x.Id == id); + if (prompt == null) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.FindPromptStringFail); + } + + if (!PromptStatus.ValidStatuses.Contains(model.Status)) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError, "Status is invalid"); + } + + // 判断名字是不是存在 + if (await _context.Prompt.AnyAsync(x => x.Name == model.Name && x.Id != id)) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError, "名字已存在,新增失败"); + } + + if (!string.IsNullOrWhiteSpace(model.PromptTypeId)) + { + PromptType? promptType = await _context.PromptType.FirstOrDefaultAsync(x => x.Id == model.PromptTypeId); + if (promptType == null) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError, "指定的提示词ID不存在,请检查"); + } + prompt.PromptTypeCode = promptType.Code; + } + + if (string.IsNullOrEmpty(model.PromptString)) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError, "提示词预设不能为空,请检查"); + } + + prompt.Name = model.Name; + prompt.PromptTypeId = model.PromptTypeId; + prompt.PromptString = model.PromptString; + prompt.Description = model.Description; + prompt.Remark = model.Remark; + prompt.Status = model.Status; + prompt.Version = model.Version; + prompt.UpdateTime = BeijingTimeExtension.GetBeijingTime(); + prompt.UpdateUserId = requertUserId; + _context.Update(prompt); + await _context.SaveChangesAsync(); + return APIResponseModel.CreateSuccessResponseModel("修改成功"); + } + catch (Exception e) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.SystemError, e.Message); + } + } + + #endregion + + #region 添加提示词数据 + + /// + /// 添加提示词数据 + /// + /// + /// + /// + /// + public async Task>> AddPrompt(ModifyPromptModel model, long requertUserId) + { + try + { + Prompt prompt = _mapper.Map(model); + bool isAdminAndSuperAdmin = await _userBasicDao.CheckUserIsAdminOrSuperAdmin(requertUserId); + if (!isAdminAndSuperAdmin) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.NotPermissionAction); + } + + // 判断是不是有相同的名字的数存在 + if (await _context.Prompt.AnyAsync(x => x.Name == model.Name)) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.PromptStringExist); + } + // 判断提示词类型是不是存在 + if (string.IsNullOrWhiteSpace(model.PromptTypeId)) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError, "提示词类型不能为空,请检查"); + } + else + { + PromptType? promptType = await _context.PromptType.FirstOrDefaultAsync(x => x.Id == model.PromptTypeId); + if (promptType == null) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError, "指定的提示词类型ID不存在,请检查"); + } + prompt.PromptTypeCode = promptType.Code; + } + + // 判断状态 + if (!PromptStatus.ValidStatuses.Contains(model.Status)) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError, "Status is invalid"); + } + prompt.Id = Guid.NewGuid().ToString(); + prompt.CreateTime = BeijingTimeExtension.GetBeijingTime(); + prompt.UpdateTime = BeijingTimeExtension.GetBeijingTime(); + prompt.CreateUserId = requertUserId; + prompt.UpdateUserId = requertUserId; + prompt.Version = 1; + await _context.Prompt.AddAsync(prompt); + await _context.SaveChangesAsync(); + return APIResponseModel.CreateSuccessResponseModel(prompt.Id); + } + catch (Exception e) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.SystemError, e.Message); + } + } + + #endregion + + #region 删除提示词数据 + + /// + /// 删除提示词数据 + /// + /// + /// + /// + public async Task>> DeletePrompt(string id, long requertUserId) + { + try + { + bool isAdminAndSuperAdmin = await _userBasicDao.CheckUserIsAdminOrSuperAdmin(requertUserId); + if (!isAdminAndSuperAdmin) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.NotPermissionAction); + } + Prompt? prompt = await _context.Prompt.FirstOrDefaultAsync(x => x.Id == id); + if (prompt == null) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.FindPromptStringFail); + } + + _context.Prompt.Remove(prompt); + await _context.SaveChangesAsync(); + return APIResponseModel.CreateSuccessResponseModel("删除成功"); + } + catch (Exception e) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.SystemError, e.Message); + } + } + + #endregion + + #region 获取指定的或者是所有的提示词预设数据 ID、Name + + /// + /// 获取指定的或者是所有的提示词预设数据 ID、Name + /// + /// + /// + public async Task>>> GetPromptOptions(string option) + { + try + { + IQueryable query = _context.Prompt; + List promptList = []; + if (option.Equals("all", StringComparison.CurrentCultureIgnoreCase)) + { + // 全部 + promptList = await query.ToListAsync(); + } + else + { + PromptType? promptType = await _context.PromptType.FirstOrDefaultAsync(x => x.Id == option); + if (promptType == null) + { + return APIResponseModel>.CreateErrorResponseModel(ResponseCode.ParameterError, "指定的提示词类型不存在,请检查"); + } + query = query.Where(x => x.PromptTypeId == option); + promptList = await query.ToListAsync(); + } + List promptNames = []; + for (int i = 0; promptList != null && i < promptList.Count; i++) + { + Prompt prompt = promptList[i]; + PromptNameDto promptName = new() + { + Id = prompt.Id, + Name = prompt.Name, + PromptTypeId = prompt.PromptTypeId + }; + promptNames.Add(promptName); + } + return APIResponseModel>.CreateSuccessResponseModel(promptNames); + } + catch (Exception e) + { + return APIResponseModel>.CreateErrorResponseModel(ResponseCode.SystemError, e.Message); + } + } + + #endregion +} diff --git a/LMS.service/Service/PromptService/PromptTypeService.cs b/LMS.service/Service/PromptService/PromptTypeService.cs new file mode 100644 index 0000000..c734091 --- /dev/null +++ b/LMS.service/Service/PromptService/PromptTypeService.cs @@ -0,0 +1,358 @@ +using AutoMapper; +using LMS.DAO; +using LMS.DAO.UserDAO; +using LMS.Repository.DTO; +using LMS.Repository.DTO.PromptTypeDto; +using LMS.Repository.DTO.UserDto; +using LMS.Repository.Models.DB; +using LMS.Repository.PromptModel; +using LMS.Tools.Extensions; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using static LMS.Common.Enums.PromptEnum; +using static LMS.Common.Enums.ResponseCodeEnum; + +namespace LMS.service.Service.PromptService; + +public class PromptTypeService +{ + private readonly ApplicationDbContext _context; + private readonly IMapper _mapper; + private readonly UserBasicDao _userBaseDao; + private readonly UserManager _userManager; + public PromptTypeService(ApplicationDbContext context, IMapper mapper, UserBasicDao userBaseDao, UserManager userManager) + { + _context = context; + _mapper = mapper; + _userBaseDao = userBaseDao; + _userManager = userManager; + } + + #region 获取当前的所有的提示词类型数据(分页) + /// + /// 获取当前的所有的提示词类型数据(分页) + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public async Task>>> QueryPromptypeCollection(int page, int pageSize, string? code, string? name, string? status, string? remark, long reuqertUserId) + { + try + { + bool isAdminOrSuperAdmin = await _userBaseDao.CheckUserIsAdminOrSuperAdmin(reuqertUserId); + if (!isAdminOrSuperAdmin) + { + return APIResponseModel>.CreateErrorResponseModel(ResponseCode.NotPermissionAction); + } + + // 开始查询 + IQueryable? query = _context.PromptType; + + if (!string.IsNullOrWhiteSpace(code)) + { + query = query.Where(x => x.Code.Contains(code)); + } + + if (!string.IsNullOrWhiteSpace(name)) + { + query = query.Where(x => x.Name.Contains(name)); + } + + if (!string.IsNullOrWhiteSpace(status)) + { + if (!PromptTypeStatus.ValidStatuses.Contains(status)) + { + return APIResponseModel>.CreateErrorResponseModel(ResponseCode.ParameterError, "Status is invalid"); + } + query = query.Where(x => x.Status == status); + } + + if (!string.IsNullOrWhiteSpace(remark)) + { + query = query.Where(x => !string.IsNullOrWhiteSpace(x.Remark) && x.Remark.Contains(remark)); + } + + // 通过ID降序 + query = query.OrderByDescending(x => x.CreateTime); + + // 查询总数 + int total = await query.CountAsync(); + + // 分页 + query = query.Skip((page - 1) * pageSize).Take(pageSize); + + List? prompttypes = await query.ToListAsync(); + + List promptTypeDtos = []; + + for (int i = 0; prompttypes != null && i < prompttypes.Count; i++) + { + PromptType prompttype = prompttypes[i]; + User? createdUser = await _userManager.FindByIdAsync(prompttype.CreateUserId.ToString()); + User? updatedUser = await _userManager.FindByIdAsync(prompttype.UpdateUserId.ToString()); + PromptTypeDto promptTypeDto = _mapper.Map(prompttype); + promptTypeDto.CreatedUser = _mapper.Map(createdUser); + promptTypeDto.UpdatedUser = _mapper.Map(updatedUser); + promptTypeDtos.Add(promptTypeDto); + } + + return APIResponseModel>.CreateSuccessResponseModel(new CollectionResponse + { + Total = total, + Collection = promptTypeDtos, + Current = page, + }); + } + catch (Exception e) + { + return APIResponseModel>.CreateErrorResponseModel(ResponseCode.SystemError, e.Message); + } + } + + #endregion + + #region 通过ID获取详细的提示词类型信息 + /// + /// 通过ID获取详细的提示词类型信息 + /// + /// + /// + /// + /// + public async Task>> GetPromptTypeInfo(string id, long reuqertUserId) + { + try + { + bool isAdminOrSuperAdmin = await _userBaseDao.CheckUserIsAdminOrSuperAdmin(reuqertUserId); + if (!isAdminOrSuperAdmin) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.NotPermissionAction); + } + + PromptType? promptType = await _context.PromptType.FirstOrDefaultAsync(x => x.Id == id); + if (promptType == null) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.FindPromptTypeFail); + } + PromptTypeDto promptTypeDto = _mapper.Map(promptType); + User? createdUser = await _userManager.FindByIdAsync(promptType.CreateUserId.ToString()); + User? updatedUser = await _userManager.FindByIdAsync(promptType.UpdateUserId.ToString()); + promptTypeDto.CreatedUser = _mapper.Map(createdUser); + promptTypeDto.UpdatedUser = _mapper.Map(updatedUser); + return APIResponseModel.CreateSuccessResponseModel(promptTypeDto); + } + catch (Exception e) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.SystemError, e.Message); + } + } + + #endregion + + #region 修改提示词类型数据 + /// + /// 修改提示词类型数据 + /// + /// + /// + /// + /// + /// + public async Task>> ModityPromptType(string id, ModifyPromptTypeModal modal, long reuqertUserId) + { + using var transaction = _context.Database.BeginTransaction(); + try + { + bool isAdminOrSuperAdmin = await _userBaseDao.CheckUserIsAdminOrSuperAdmin(reuqertUserId); + if (!isAdminOrSuperAdmin) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.NotPermissionAction); + } + PromptType? promptType = await _context.PromptType.FirstOrDefaultAsync(x => x.Id == id); + if (promptType == null) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.FindPromptTypeFail); + } + + if (!PromptTypeStatus.ValidStatuses.Contains(modal.Status)) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError, "Status is invalid"); + } + + // 判断name是不是存在相同的 + if (await _context.PromptType.AnyAsync(x => x.Name == modal.Name && x.Id != id)) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError, "名称已存在"); + } + + if (await _context.PromptType.AnyAsync(x => x.Code == modal.Code && x.Id != id)) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError, "Code已存在"); + } + + promptType.Code = modal.Code; + promptType.Name = modal.Name; + promptType.Status = modal.Status; + promptType.Remark = modal.Remark; + promptType.UpdateTime = BeijingTimeExtension.GetBeijingTime(); + promptType.UpdateUserId = reuqertUserId; + + await _context.SaveChangesAsync(); + await transaction.CommitAsync(); + return APIResponseModel.CreateSuccessResponseModel("修改提示词类型数据成功"); + } + catch (Exception e) + { + await transaction.RollbackAsync(); + return APIResponseModel.CreateErrorResponseModel(ResponseCode.SystemError, e.Message); + } + } + + #endregion + + #region 添加提示词类型数据 + /// + /// 添加提示词类型数据 + /// + /// + /// + /// + /// + public async Task>> AddPromptType(ModifyPromptTypeModal modal, long reuqertUserId) + { + try + { + bool isAdminOrSuperAdmin = await _userBaseDao.CheckUserIsAdminOrSuperAdmin(reuqertUserId); + if (!isAdminOrSuperAdmin) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.NotPermissionAction); + } + + if (!PromptTypeStatus.ValidStatuses.Contains(modal.Status)) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError, "Status is invalid"); + } + + // 判断name是不是存在相同的 + if (await _context.PromptType.AnyAsync(x => x.Name == modal.Name)) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError, "名称已存在"); + } + + if (await _context.PromptType.AnyAsync(x => x.Code == modal.Code)) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.ParameterError, "Code已存在"); + } + + // 开始添加 + // 开始添加数据 + PromptType promptType = new() + { + Id = System.Guid.NewGuid().ToString(), + Code = modal.Code, + Name = modal.Name, + CreateTime = System.DateTime.Now, + UpdateTime = System.DateTime.Now, + CreateUserId = reuqertUserId, + UpdateUserId = reuqertUserId, + Remark = modal.Remark, + Status = modal.Status, + IsDeleted = false + }; + await _context.PromptType.AddAsync(promptType); + await _context.SaveChangesAsync(); + return APIResponseModel.CreateSuccessResponseModel("添加提示词类型数据成功"); + } + catch (Exception e) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.SystemError, e.Message); + } + } + + #endregion + + #region 删除提示词类型数据 + /// + /// 删除提示词类型数据 + /// + /// + /// + /// + /// + public async Task>> DeletePromptType(string id, long reuqertUserId, bool deletePrompt) + { + try + { + bool isAdminOrSuperAdmin = await _userBaseDao.CheckUserIsAdminOrSuperAdmin(reuqertUserId); + if (!isAdminOrSuperAdmin) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.NotPermissionAction); + } + + PromptType? promptType = await _context.PromptType.FirstOrDefaultAsync(x => x.Id == id); + if (promptType == null) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.FindPromptTypeFail); + } + + // 判断是不是删除所有的提示词类型相关的提示词数据 + bool hasPrompt = await _context.Prompt.AnyAsync(x => x.PromptTypeId == promptType.Id); + if (hasPrompt && !deletePrompt) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.PromptStringExist, "当前删除的提示词类型数据有关联的提示词数据"); + } + + if (hasPrompt && deletePrompt) + { + // 直接删除全部数据 + _context.Prompt.RemoveRange(_context.Prompt.Where(x => x.PromptTypeId == promptType.Id)); + await _context.SaveChangesAsync(); + } + _context.PromptType.Remove(promptType); + await _context.SaveChangesAsync(); + return APIResponseModel.CreateSuccessResponseModel("删除提示词类型数据成功以及所有的关联提示词数据成功"); + } + catch (Exception e) + { + return APIResponseModel.CreateErrorResponseModel(ResponseCode.SystemError, e.Message); + } + } + #endregion + + #region 获取所有的提示词类型的选项,ID和Name + /// + /// 获取所有的提示词类型的选项,ID和Name + /// + /// + /// + public async Task>>> GetPromptTypeOptions() + { + try + { + List promptTypes = await _context.PromptType.ToListAsync(); + List promptNameModels = []; + foreach (var item in promptTypes) + { + promptNameModels.Add(new PrompTypeNameModel + { + Id = item.Id, + Name = item.Name + }); + }; + return APIResponseModel>.CreateSuccessResponseModel(promptNameModels); + } + catch (Exception e) + { + return APIResponseModel>.CreateErrorResponseModel(ResponseCode.SystemError, e.Message); + } + } + + #endregion +}