1、部署Redis 首先搜寻并拉取Redis
随后输入如下代码运行Redis
1 docker run -p 6379 :6379 -d redis:latest redis-server
随后在下面的页面配置密码
通过输入
1 2 3 redis-cli config set requirepass [mypassword] config get requirepass
设定、查看密码
2、部署Minio 首先拉取Minio
随后输入
1 docker run -d -p 9000 :9000 -p 9090 :9090 --name minio --restart=always -e "MINIO_BROWSER_REDIRECT_URL=http://localhost:9000 " -e "MINIO_ROOT_USER=minioadmin" -e "MINIO_ROOT_PASSWORD=minioadmin" minio/minio:RELEASE.2024 -09 -13 T20-26 -02 Z server /data --console-address ":9000 " -address ":9090 "
以启动运行Minio
3、系统配置 1、appsettings.json 在appsettings.json中设定需要使用的详细信息,如路由、密码等内容。
ProgramBackEnd\appsettings.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 { "Logging" : { "LogLevel" : { "Default" : "Information" , "Microsoft.AspNetCore" : "Warning" } , "Console" : { "FormatterName" : "simple" , "FormatterOptions" : { "TimestampFormat" : "yyyy-MM-dd HH:mm:ss " , "UseUtcTimestamp" : false , "SingleLine" : true , "IncludeScopes" : false } } } , "ConnectionStrings" : { "DefaultConnection" : "server=localhost;port=33061;database=sky_take_out;uid=root;pwd=mysql;" , "Redis" : "localhost:6379,password=redis,ssl=false,abortConnect=false" } , "Kestrel" : { "Endpoints" : { "Http" : { "Url" : "http://localhost:8080" } } } , "MinioSettings" : { "Endpoint" : "localhost:9090" , "AccessKey" : "minioadmin" , "SecretKey" : "minioadmin" , "BucketName" : "test" , "UseSSL" : false } , "JwtConfig" : { "AdminSecretKey" : "AdminSecretKey_sky1234567890123456789012" , "AdminTtl" : 7200000 , "AdminTokenName" : "token" , "UserSecretKey" : "UserSecretKey_sky12345678901234567890123" , "UserTtl" : 7200000 } , "AllowedHosts" : "*" }
2、Program.cs ProgramBackEnd\Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 using Microsoft.EntityFrameworkCore; using ProgramBackEnd.SkyCommon.properties; using ProgramBackEnd.SkyServer.config; using ProgramBackEnd.SkyServer.Handler; using ProgramBackEnd.SkyServer.Middlewares; using StackExchange.Redis; var builder = WebApplication.CreateBuilder(args );builder.Services.AddDbContext<SkyDbContext>(options => options.UseMySql( builder.Configuration.GetConnectionString("DefaultConnection" ), new MySqlServerVersion(new Version(9 , 3 , 0 )) ) ); builder.Services.AddStackExchangeRedisCache(options => { options.Configuration = builder.Configuration.GetConnectionString("Redis" ); }); builder.Services.AddSingleton<IConnectionMultiplexer>(sp => { var configuration = ConfigurationOptions.Parse( builder.Configuration.GetConnectionString("Redis" )); return ConnectionMultiplexer.Connect(configuration); }); builder.Services.Configure<JwtProperties>(builder.Configuration.GetSection("JwtConfig" )); builder.Services.Configure<MinioProperties>(builder.Configuration.GetSection("MinioSettings" )); builder.Services.AddSingleton(sp => { var minioSettings = builder.Configuration.GetSection("MinioSettings" ).Get<MinioProperties>(); return minioSettings ?? new MinioProperties(); }); builder.Services.AddControllers() .AddGlobalExceptionHandler(); builder.Services.RegisterAllServices(); var app = builder.Build();if (app.Environment.IsDevelopment()){ } app.UseRouting(); app.UseMiddleware<JsonFormatterMiddleware>(); app.UseMiddleware<JwtTokenValidationMiddleware>(); app.MapControllers(); app.Run();
3、Redis配置 由于会在此处和以后使用Redis,因此需要设定Redis使用的相关内容,均在“ProgramBackEnd\SkyCommon\redisCache”文件夹下
1、ISerializer 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 namespace ProgramBackEnd.SkyCommon.redisCache { public interface ISerializer { string Serialize <T >(T obj ) ; T Deserialize <T >(string value ) ; } }
2、JsonSerializer 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 using System;using System.Text.Json;namespace ProgramBackEnd.SkyCommon.redisCache { public class JsonSerializer : ISerializer { private readonly JsonSerializerOptions _serializerOptions; public JsonSerializer () { _serializerOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull, ReadCommentHandling = JsonCommentHandling.Skip, Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping }; } public string Serialize <T >(T obj ) { try { if (obj == null && default (T) != null ) { throw new ArgumentNullException(nameof (obj), "序列化的对象不能为null" ); } return System.Text.Json.JsonSerializer.Serialize(obj, _serializerOptions); } catch (JsonException ex) { throw new JsonException($"序列化类型'{typeof (T).Name} '的对象到JSON时失败: {ex.Message} " , ex); } catch (Exception ex) when (ex is not ArgumentNullException && ex is not JsonException) { throw new InvalidOperationException($"执行JSON序列化时发生意外错误: {ex.Message} " , ex); } } public T Deserialize <T >(string value ) { if (string .IsNullOrEmpty(value )) { throw new ArgumentNullException(nameof (value ), "要反序列化的JSON字符串不能为null或空" ); } try { return System.Text.Json.JsonSerializer.Deserialize<T>(value , _serializerOptions); } catch (JsonException ex) { throw new JsonException($"将JSON反序列化为类型'{typeof (T).Name} '时失败: {ex.Message} " , ex); } catch (Exception ex) when (ex is not ArgumentNullException && ex is not JsonException) { throw new InvalidOperationException($"执行JSON反序列化时发生意外错误: {ex.Message} " , ex); } } } }
3、IRedisCache 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 namespace ProgramBackEnd.SkyCommon.redisCache { public interface IRedisCache { Task<T?> GetAsync<T>(string key); Task SetAsync <T >(string key, T value , TimeSpan? expiry = null ) ; Task<bool > RemoveAsync (string key ) ; Task<bool > ExistsAsync (string key ) ; } }
4、RedisCacheImpl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 using System;using System.Threading.Tasks;using StackExchange.Redis;namespace ProgramBackEnd.SkyCommon.redisCache { public class RedisCacheImpl : IRedisCache { private readonly IDatabase _db; private readonly ISerializer _serializer; public RedisCacheImpl (IConnectionMultiplexer redis, ISerializer serializer ) { if (redis == null ) throw new ArgumentNullException(nameof (redis)); if (serializer == null ) throw new ArgumentNullException(nameof (serializer)); _db = redis.GetDatabase(); _serializer = serializer; } public async Task <T ?> GetAsync <T >(string key ) { if (string .IsNullOrEmpty(key)) throw new ArgumentNullException(nameof (key), "缓存键不能为null或空字符串" ); try { var value = await _db.StringGetAsync(key); if (value .IsNull) return default ; return _serializer.Deserialize<T>(value ); } catch (RedisException ex) { throw new InvalidOperationException($"从Redis获取键'{key} '时发生错误: {ex.Message} " , ex); } catch (Exception ex) when (ex is not ArgumentNullException) { throw new InvalidOperationException($"处理缓存键'{key} '时发生错误: {ex.Message} " , ex); } } public async Task SetAsync <T >(string key, T value , TimeSpan? expiry = null ) { if (string .IsNullOrEmpty(key)) throw new ArgumentNullException(nameof (key), "缓存键不能为null或空字符串" ); if (value == null ) throw new ArgumentNullException(nameof (value ), "缓存值不能为null" ); try { var serializedValue = _serializer.Serialize(value ); await _db.StringSetAsync(key, serializedValue, expiry); } catch (RedisException ex) { throw new InvalidOperationException($"向Redis设置键'{key} '时发生错误: {ex.Message} " , ex); } catch (Exception ex) when (ex is not ArgumentNullException) { throw new InvalidOperationException($"序列化或缓存数据时发生错误: {ex.Message} " , ex); } } public async Task<bool > RemoveAsync (string key ) { if (string .IsNullOrEmpty(key)) throw new ArgumentNullException(nameof (key), "缓存键不能为null或空字符串" ); try { return await _db.KeyDeleteAsync(key); } catch (RedisException ex) { throw new InvalidOperationException($"从Redis删除键'{key} '时发生错误: {ex.Message} " , ex); } } public async Task<bool > ExistsAsync (string key ) { if (string .IsNullOrEmpty(key)) throw new ArgumentNullException(nameof (key), "缓存键不能为null或空字符串" ); try { return await _db.KeyExistsAsync(key); } catch (RedisException ex) { throw new InvalidOperationException($"检查Redis键'{key} '存在性时发生错误: {ex.Message} " , ex); } } } }
4、MinioProperties MinioProperties用来承接设置中Minio的必要参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 using System;namespace ProgramBackEnd.SkyCommon.properties { public class MinioProperties { public string ? Endpoint { get ; set ; } public string ? AccessKey { get ; set ; } public string ? SecretKey { get ; set ; } public string ? BucketName { get ; set ; } public bool UseSSL { get ; set ; } } }
4、CommonController 文件上传控制器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 using Microsoft.AspNetCore.Mvc;using ProgramBackEnd.SkyCommon.result;using ProgramBackEnd.SkyServer.service;namespace ProgramBackEnd.SkyServer.controller.admin { [ApiController ] [Route("/admin/common/upload" ) ] public class CommonController : ControllerBase { private readonly IFileUploadService _fileUploadService; public CommonController (IFileUploadService fileUploadService ) { _fileUploadService = fileUploadService ?? throw new ArgumentNullException(nameof (fileUploadService)); } [HttpPost ] public async Task<Result<string >> Upload(IFormFile file ) { string url = await _fileUploadService.UploadFileAsync(file ); return Result<string >.Success(url); } } }
5、FileUploadService 文件上传服务相关代码
1、IFileUploadService 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 using Microsoft.AspNetCore.Http;using System.Threading.Tasks;namespace ProgramBackEnd.SkyServer.service { public interface IFileUploadService { Task<string > UploadFileAsync (IFormFile file ) ; } }
2、FileUploadServiceImpl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 using Microsoft.AspNetCore.Http;using Microsoft.Extensions.Logging;using Minio;using Minio.DataModel.Args;using ProgramBackEnd.SkyCommon.exception;using ProgramBackEnd.SkyCommon.properties;using System;using System.IO;using System.Threading.Tasks;namespace ProgramBackEnd.SkyServer.service.Impl { public class FileUploadServiceImpl : IFileUploadService { private readonly MinioProperties _minioProperties; public FileUploadServiceImpl (MinioProperties minioProperties ) { _minioProperties = minioProperties ?? throw new ArgumentNullException(nameof (minioProperties)); } public async Task<string > UploadFileAsync (IFormFile file ) { if (file == null || file .Length == 0 ) throw new ArgumentException("文件不能为空或大小为零" , nameof (file )); try { var minioClient = new MinioClient() .WithEndpoint(_minioProperties.Endpoint) .WithCredentials(_minioProperties.AccessKey, _minioProperties.SecretKey) .WithSSL(_minioProperties.UseSSL) .Build(); var bucketName = _minioProperties.BucketName; var bucketExistsArgs = new BucketExistsArgs().WithBucket(bucketName); bool bucketExists = await minioClient.BucketExistsAsync(bucketExistsArgs); if (!bucketExists) { var makeBucketArgs = new MakeBucketArgs().WithBucket(bucketName); await minioClient.MakeBucketAsync(makeBucketArgs); } string dateDir = DateTime.Now.ToString("yyyyMMdd" ); string uuid = Guid.NewGuid().ToString("N" ); string extension = Path.GetExtension(file .FileName); string objectName = $"{dateDir} /{uuid} {extension} " ; using var stream = file .OpenReadStream(); var putObjectArgs = new PutObjectArgs() .WithBucket(bucketName) .WithObject(objectName) .WithStreamData(stream) .WithObjectSize(file .Length) .WithContentType(file .ContentType); await minioClient.PutObjectAsync(putObjectArgs); string ? endpointUrl = _minioProperties.Endpoint; if (string .IsNullOrEmpty(endpointUrl)) { throw new BaseException("MinIO端点配置无效" ); } if (!endpointUrl.StartsWith("http" )) { endpointUrl = (_minioProperties.UseSSL ? "https://" : "http://" ) + endpointUrl; } string url = $"{endpointUrl} /{bucketName} /{objectName} " ; Console.WriteLine($"文件上传成功: {url} " ); return url; } catch (Exception ex) when (ex is not ArgumentException && ex is not BaseException) { Console.WriteLine($"上传文件时发生错误: {ex.Message} " ); throw new BaseException($"文件上传失败: {ex.Message} " ); } } } }
6、Dish相关代码 1、DishController ProgramBackEnd\SkyServer\controller\admin\DishController.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 using Microsoft.AspNetCore.Mvc;using Microsoft.Extensions.Logging;using ProgramBackEnd.SkyCommon.result;using ProgramBackEnd.SkyPojo.dto;using ProgramBackEnd.SkyPojo.entity;using ProgramBackEnd.SkyPojo.vo;using ProgramBackEnd.SkyServer.service;using StackExchange.Redis;using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;namespace ProgramBackEnd.SkyServer.controller.admin { [ApiController ] [Route("/admin/dish" ) ] public class DishController : ControllerBase { private readonly IConnectionMultiplexer _redis; private readonly ILogger<DishController> _logger; private readonly IDishService _dishService; public DishController (IDishService dishService, IConnectionMultiplexer redis, ILogger<DishController> logger ) { _dishService = dishService ?? throw new ArgumentNullException(nameof (dishService)); _redis = redis ?? throw new ArgumentNullException(nameof (redis)); _logger = logger ?? throw new ArgumentNullException(nameof (logger)); } [HttpPost ] public async Task<Result<string >> Save([FromBody] DishDTO dishDTO) { await _dishService.SaveWithFlavor(dishDTO); string key = $"dish_{dishDTO.CategoryId} " ; CleanCache(key); return Result<string >.Success("保存成功" ); } [HttpGet("page" ) ] public async Task<Result<PageResult>> Page([FromQuery] DishPageQueryDTO dishPageQueryDTO) { _logger.LogInformation("菜品分页查询:{@DishPageQueryDTO}" , dishPageQueryDTO); var pageResult = await _dishService.PageQuery(dishPageQueryDTO); return Result<PageResult>.Success(pageResult); } [HttpDelete ] public async Task<Result<string >> Delete([FromQuery] string ids) { var idList = !string .IsNullOrEmpty(ids) ? ids.Split(',' ).Select(long .Parse).ToList() : new List<long >(); _logger.LogInformation("菜品批量删除:{@Ids}" , idList); await _dishService.DeleteBatch(idList); CleanCache("dish_*" ); return Result<string >.Success("删除成功" ); } [HttpGet("{id}" ) ] public async Task<Result<DishVO>> GetById([FromRoute] long id) { _logger.LogInformation("根据ID查询菜品:{Id}" , id); DishVO dishVO = await _dishService.GetByIdWithFlavor(id); return Result<DishVO>.Success(dishVO); } [HttpPut ] public async Task<Result<string >> Update([FromBody] DishDTO dishDTO) { _logger.LogInformation("修改菜品:ID={Id}, Name={Name}" , dishDTO.Id, dishDTO.Name); await _dishService.UpdateWithFlavor(dishDTO); CleanCache("dish_*" ); return Result<string >.Success("修改成功" ); } [HttpPost("status/{status}" ) ] public async Task<Result<string >> StartOrStop([FromRoute] int status, [FromQuery] long id) { _logger.LogInformation("修改菜品状态:status={Status}, id={Id}" , status, id); await _dishService.StartOrStop(status, id); CleanCache("dish_*" ); string message = status == 1 ? "菜品已起售" : "菜品已停售" ; return Result<string >.Success(message); } [HttpGet("list" ) ] public async Task<Result<List<Dish>>> List([FromQuery] long categoryId) { _logger.LogInformation("根据分类ID查询菜品:{CategoryId}" , categoryId); List<Dish> list = await _dishService.List(categoryId); return Result<List<Dish>>.Success(list); } private void CleanCache (string pattern ) { try { var db = _redis.GetDatabase(); var endpoint = _redis.GetEndPoints().FirstOrDefault(); if (endpoint == null ) { _logger.LogWarning("无法获取Redis服务器端点,缓存清理操作已跳过" ); return ; } var server = _redis.GetServer(endpoint); var keys = server.Keys(pattern: pattern).ToArray(); if (keys.Length > 0 ) { db.KeyDelete(keys); _logger.LogInformation("已清理{Count}个匹配'{Pattern}'的缓存键" , keys.Length, pattern); } else { _logger.LogDebug("未找到匹配'{Pattern}'的缓存键" , pattern); } } catch (Exception ex) { _logger.LogError(ex, "清理缓存时发生错误,模式:{Pattern}" , pattern); } } } }
2、IDishService ProgramBackEnd\SkyServer\service\IDishService.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 using ProgramBackEnd.SkyCommon.result;using ProgramBackEnd.SkyPojo.dto;using ProgramBackEnd.SkyPojo.entity;using ProgramBackEnd.SkyPojo.vo;using System.Collections.Generic;using System.Threading.Tasks;namespace ProgramBackEnd.SkyServer.service { public interface IDishService { Task SaveWithFlavor (DishDTO dishDTO ) ; Task<PageResult> PageQuery (DishPageQueryDTO dishPageQueryDTO ) ; Task<DishVO> GetByIdWithFlavor (long id ) ; Task UpdateWithFlavor (DishDTO dishDTO ) ; Task DeleteBatch (List<long > ids ) ; Task StartOrStop (int status, long id ) ; Task<List<Dish>> List(long categoryId); } }
3、DishServiceImpl ProgramBackEnd\SkyServer\service\Impl\DishServiceImpl.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 using Microsoft.EntityFrameworkCore;using ProgramBackEnd.SkyCommon.context;using ProgramBackEnd.SkyCommon.exception;using ProgramBackEnd.SkyCommon.result;using ProgramBackEnd.SkyCommon.utils;using ProgramBackEnd.SkyPojo.dto;using ProgramBackEnd.SkyPojo.entity;using ProgramBackEnd.SkyPojo.vo;using ProgramBackEnd.SkyServer.config;using ProgramBackEnd.SkyServer.mapper;using System;using System.Collections;using System.Collections.Generic;using System.Threading.Tasks;namespace ProgramBackEnd.SkyServer.service.Impl { public class DishServiceImpl : IDishService { private readonly IDishMapper _dishMapper; private readonly IDishFlavorMapper _dishFlavorMapper; private readonly ISetmealDishMapper _setmealDishMapper; private readonly ISetmealMapper _setmealMapper; private readonly SkyDbContext _skyDbContext; public DishServiceImpl ( IDishMapper dishMapper, IDishFlavorMapper dishFlavorMapper, ISetmealDishMapper setmealDishMapper, ISetmealMapper setmealMapper, SkyDbContext skyDbContext ) { _dishMapper = dishMapper ?? throw new ArgumentNullException(nameof (dishMapper)); _dishFlavorMapper = dishFlavorMapper ?? throw new ArgumentNullException(nameof (dishFlavorMapper)); _setmealDishMapper = setmealDishMapper ?? throw new ArgumentNullException(nameof (setmealDishMapper)); _setmealMapper = setmealMapper ?? throw new ArgumentNullException(nameof (setmealMapper)); _skyDbContext = skyDbContext ?? throw new ArgumentNullException(nameof (skyDbContext)); } public async Task DeleteBatch (List<long > ids ) { if (ids == null || ids.Count == 0 ) { return ; } using var transaction = await _skyDbContext.Database.BeginTransactionAsync(); try { foreach (var id in ids) { Dish dish = await _dishMapper.GetById(id); if (dish == null ) { continue ; } if (dish.Status == 1 ) { throw new BaseException("起售中的菜品不能删除,请先停售再删除" ); } } List<long > setmealIds = await _setmealDishMapper.GetSetmealIdsByDishIds(ids); if (setmealIds != null && setmealIds.Count > 0 ) { throw new BaseException("菜品已被套餐关联,请先解除关联再删除" ); } foreach (var id in ids) { await _dishMapper.DeleteById(id); await _dishFlavorMapper.DeleteByDishId(id); } await transaction.CommitAsync(); } catch (Exception ex) { await transaction.RollbackAsync(); if (ex is BaseException) { throw ; } else { throw new Exception($"删除菜品失败: {ex.Message} " , ex); } } } public async Task<DishVO> GetByIdWithFlavor (long id ) { Dish dish = await _dishMapper.GetById(id) ?? throw new BaseException($"未找到ID为{id} 的菜品" ); List<DishFlavor> dishFlavors = await _dishFlavorMapper.GetByDishId(id); DishVO dishVO = new (); PropertyUtil.CopyProperties(dish, dishVO); dishVO.Flavors = dishFlavors ?? new List<DishFlavor>(); return dishVO; } public async Task<List<Dish>> List(long categoryId) { Dish queryDish = new () { CategoryId = categoryId, Status = 1 }; return await _dishMapper.List(queryDish); } public async Task<PageResult> PageQuery (DishPageQueryDTO dishPageQueryDTO ) { if (dishPageQueryDTO == null ) { throw new ArgumentNullException(nameof (dishPageQueryDTO)); } (long total, IList dishList) = await _dishMapper.PageQuery(dishPageQueryDTO); return new PageResult(total, dishList); } public async Task SaveWithFlavor (DishDTO dishDTO ) { if (dishDTO == null ) { throw new ArgumentNullException(nameof (dishDTO), "菜品数据不能为空" ); } Dish dish = new (); PropertyUtil.CopyProperties(dishDTO, dish); long currentUserId = BaseContext.GetCurrentId() ?? 0 ; DateTime now = DateTime.Now; dish.CreateTime = now; dish.UpdateTime = now; dish.CreateUser = currentUserId; dish.UpdateUser = currentUserId; await _dishMapper.Insert(dish); long dishId = dish.Id; List<DishFlavor> flavors = dishDTO.Flavors; if (flavors != null && flavors.Count > 0 ) { foreach (var flavor in flavors) { flavor.DishId = dishId; } await _dishFlavorMapper.InsertBatch(flavors); } } public async Task StartOrStop (int status, long id ) { if (status != 0 && status != 1 ) { throw new ArgumentException("无效的状态值,只能为0(停售)或1(起售)" , nameof (status)); } using var transaction = await _skyDbContext.Database.BeginTransactionAsync(); try { Dish dish = new () { Id = id, Status = status, UpdateTime = DateTime.Now, UpdateUser = BaseContext.GetCurrentId() ?? 0 }; await _dishMapper.Update(dish); if (status == 0 ) { List<long > dishIds = new () { id }; List<long > setmealIds = await _setmealDishMapper.GetSetmealIdsByDishIds(dishIds); if (setmealIds != null && setmealIds.Count > 0 ) { long currentUserId = BaseContext.GetCurrentId() ?? 0 ; DateTime now = DateTime.Now; foreach (long setmealId in setmealIds) { Setmeal setmeal = new () { Id = setmealId, Status = 0 , UpdateTime = now, UpdateUser = currentUserId }; await _setmealMapper.Update(setmeal); } } } await transaction.CommitAsync(); } catch (Exception ex) { await transaction.RollbackAsync(); string action = status == 1 ? "起售" : "停售" ; throw new Exception($"菜品{action} 操作失败: {ex.Message} " , ex); } } public async Task UpdateWithFlavor (DishDTO dishDTO ) { if (dishDTO == null ) { throw new ArgumentNullException(nameof (dishDTO), "菜品更新数据不能为空" ); } if (dishDTO.Id <= 0 ) { throw new ArgumentException("无效的菜品ID" , nameof (dishDTO)); } Dish dish = new (); PropertyUtil.CopyProperties(dishDTO, dish); dish.UpdateTime = DateTime.Now; dish.UpdateUser = BaseContext.GetCurrentId() ?? 0 ; try { await _dishMapper.Update(dish); await _dishFlavorMapper.DeleteByDishId(dishDTO.Id); List<DishFlavor> flavors = dishDTO.Flavors; if (flavors != null && flavors.Count > 0 ) { foreach (var flavor in flavors) { flavor.DishId = dishDTO.Id; } await _dishFlavorMapper.InsertBatch(flavors); } } catch (Exception ex) { throw new Exception($"更新菜品信息失败: {ex.Message} " , ex); } } } }
4、IDishMapper ProgramBackEnd\SkyServer\mapper\IDishMapper.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 using ProgramBackEnd.SkyPojo.dto;using ProgramBackEnd.SkyPojo.entity;using System;using System.Collections;using System.Collections.Generic;using System.Threading.Tasks;namespace ProgramBackEnd.SkyServer.mapper { public interface IDishMapper { Task<int > CountByCategoryId (long id ) ; Task DeleteById (long id ) ; Task<Dish> GetById (long id ) ; Task Insert (Dish dish ) ; Task<List<Dish>> List(Dish dish); Task<(long total, IList dishList)> PageQuery(DishPageQueryDTO dishPageQueryDTO); Task Update (Dish dish ) ; } }
5、DishMapperImpl ProgramBackEnd\SkyServer\controller\admin\DishController.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 using Microsoft.EntityFrameworkCore;using ProgramBackEnd.SkyPojo.dto;using ProgramBackEnd.SkyPojo.entity;using ProgramBackEnd.SkyPojo.vo;using ProgramBackEnd.SkyServer.config;using System;using System.Collections;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;namespace ProgramBackEnd.SkyServer.mapper.Impl { public class DishMapperImpl : IDishMapper { private readonly SkyDbContext _skyDbContext; public DishMapperImpl (SkyDbContext skyDbContext ) { _skyDbContext = skyDbContext ?? throw new ArgumentNullException(nameof (skyDbContext)); } public async Task<int > CountByCategoryId (long id ) { int total = await _skyDbContext.Dishes .Where(d => d.CategoryId == id) .CountAsync(); return total; } public async Task DeleteById (long id ) { try { var dish = await _skyDbContext.Dishes.FindAsync(id); if (dish != null ) { _skyDbContext.Dishes.Remove(dish); await _skyDbContext.SaveChangesAsync(); } } catch (Exception ex) { throw new InvalidOperationException($"删除菜品(ID:{id} )时发生错误: {ex.Message} " , ex); } } public async Task<Dish> GetById (long id ) { try { var dish = await _skyDbContext.Dishes .FirstOrDefaultAsync(d => d.Id == id); if (dish == null ) { throw new Exception($"未找到ID为{id} 的菜品" ); } return dish; } catch (Exception ex) when (ex.Message != $"未找到ID为{id} 的菜品" ) { throw new InvalidOperationException($"查询菜品(ID:{id} )时发生错误: {ex.Message} " , ex); } } public async Task Insert (Dish dish ) { await _skyDbContext.Dishes.AddAsync(dish); await _skyDbContext.SaveChangesAsync(); } public async Task<List<Dish>> List(Dish dish) { try { IQueryable<Dish> query = _skyDbContext.Dishes.AsQueryable(); if (!string .IsNullOrEmpty(dish.Name)) { query = query.Where(d => d.Name != null && d.Name.Contains(dish.Name)); } if (dish.CategoryId > 0 ) { query = query.Where(d => d.CategoryId == dish.CategoryId); } if (dish.Status.HasValue) { query = query.Where(d => d.Status == dish.Status); } query = query.OrderByDescending(d => d.CreateTime); return await query.ToListAsync(); } catch (Exception ex) { throw new InvalidOperationException($"查询菜品列表时发生错误: {ex.Message} " , ex); } } public async Task<(long total, IList dishList)> PageQuery(DishPageQueryDTO dishPageQueryDTO) { if (dishPageQueryDTO == null ) { throw new ArgumentNullException(nameof (dishPageQueryDTO), "查询参数不能为空" ); } int page = Math.Max(1 , dishPageQueryDTO.Page); int pageSize = Math.Max(1 , dishPageQueryDTO.PageSize); try { var query = from d in _skyDbContext.Dishes join c in _skyDbContext.Categories on d.CategoryId equals c.Id into categoryGroup from c in categoryGroup.DefaultIfEmpty() select new { d.Id, d.Name, d.CategoryId, d.Price, d.Image, d.Description, d.Status, d.CreateTime, d.UpdateTime, d.CreateUser, d.UpdateUser, CategoryName = c.Name }; if (!string .IsNullOrEmpty(dishPageQueryDTO.Name)) { string name = dishPageQueryDTO.Name.Trim(); query = query.Where(d => d.Name != null && d.Name.Contains(name)); } if (dishPageQueryDTO.CategoryId.HasValue && dishPageQueryDTO.CategoryId > 0 ) { query = query.Where(d => d.CategoryId == dishPageQueryDTO.CategoryId); } if (dishPageQueryDTO.Status.HasValue) { query = query.Where(d => d.Status == dishPageQueryDTO.Status); } long total = await query.LongCountAsync(); var dishDataList = await query .OrderByDescending(d => d.CreateTime) .ThenBy(d => d.Id) .Skip((page - 1 ) * pageSize) .Take(pageSize) .ToListAsync(); var dishList = dishDataList.Select(d => new DishVO( d.Id, d.Name, d.CategoryId, d.Price, d.Image, d.Description, d.Status, d.UpdateTime, d.CategoryName, new List<DishFlavor>() )).ToList(); return (total, dishList); } catch (Exception ex) when (ex is not ArgumentNullException) { throw new InvalidOperationException($"执行菜品分页查询时发生错误: {ex.Message} " , ex); } } public async Task Update (Dish dish ) { try { var existingDish = await _skyDbContext.Dishes.FindAsync(dish.Id); if (existingDish == null ) { throw new InvalidOperationException($"未找到ID为{dish.Id} 的菜品" ); } if (dish.Name != null ) existingDish.Name = dish.Name; if (dish.CategoryId != 0 ) existingDish.CategoryId = dish.CategoryId; if (dish.Price != 0 ) existingDish.Price = dish.Price; if (dish.Image != null ) existingDish.Image = dish.Image; if (dish.Description != null ) existingDish.Description = dish.Description; if (dish.Status.HasValue) existingDish.Status = dish.Status; existingDish.UpdateTime = dish.UpdateTime; if (dish.UpdateUser != 0 ) existingDish.UpdateUser = dish.UpdateUser; await _skyDbContext.SaveChangesAsync(); } catch (Exception ex) when (!(ex is InvalidOperationException && ex.Message.StartsWith("未找到ID" ))) { throw new InvalidOperationException($"更新菜品(ID:{dish.Id} )时发生错误: {ex.Message} " , ex); } } } }
6、IDishFlavorMapper ProgramBackEnd\SkyServer\mapper\IDishFlavorMapper.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 using ProgramBackEnd.SkyPojo.entity;using System.Collections.Generic;using System.Threading.Tasks;namespace ProgramBackEnd.SkyServer.mapper { public interface IDishFlavorMapper { Task DeleteByDishId (long id ) ; Task<List<DishFlavor>> GetByDishId(long id); Task InsertBatch (List<DishFlavor> flavors ) ; } }
7、DishFlavorMapperImpl ProgramBackEnd\SkyServer\mapper\Impl\DishFlavorMapperImpl.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 using Microsoft.EntityFrameworkCore;using ProgramBackEnd.SkyPojo.entity;using ProgramBackEnd.SkyServer.config;using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;namespace ProgramBackEnd.SkyServer.mapper.Impl { public class DishFlavorMapperImpl : IDishFlavorMapper { private readonly SkyDbContext _skyDbContext; public DishFlavorMapperImpl (SkyDbContext skyDbContext ) { _skyDbContext = skyDbContext ?? throw new ArgumentNullException(nameof (skyDbContext)); } public async Task DeleteByDishId (long dishId ) { try { var flavorsToDelete = await _skyDbContext.DishFlavors .Where(df => df.DishId == dishId) .ToListAsync(); if (flavorsToDelete.Any()) { _skyDbContext.DishFlavors.RemoveRange(flavorsToDelete); await _skyDbContext.SaveChangesAsync(); } } catch (Exception ex) { throw new InvalidOperationException( $"删除菜品口味数据时发生错误(菜品ID:{dishId} ): {ex.Message} " , ex); } } public async Task<List<DishFlavor>> GetByDishId(long id) { try { return await _skyDbContext.DishFlavors .Where(df => df.DishId == id) .ToListAsync(); } catch (Exception ex) { throw new InvalidOperationException( $"查询菜品口味数据时发生错误(菜品ID:{id} ): {ex.Message} " , ex); } } public async Task InsertBatch (List<DishFlavor> flavors ) { if (flavors == null || flavors.Count == 0 ) { return ; } try { await _skyDbContext.DishFlavors.AddRangeAsync(flavors); await _skyDbContext.SaveChangesAsync(); } catch (Exception ex) { throw new InvalidOperationException( $"批量插入菜品口味数据时发生错误: {ex.Message} " , ex); } } } }
8、ISetmealMapper ProgramBackEnd\SkyServer\mapper\ISetmealMapper.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 using ProgramBackEnd.SkyPojo.entity;using System.Threading.Tasks;namespace ProgramBackEnd.SkyServer.mapper { public interface ISetmealMapper { Task<int > CountByCategoryId (long id ) ; Task Update (Setmeal setmeal ) ; } }
9、SetmealMapperImpl ProgramBackEnd\SkyServer\mapper\Impl\SetmealMapperImpl.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 using Microsoft.EntityFrameworkCore;using ProgramBackEnd.SkyPojo.entity;using ProgramBackEnd.SkyServer.config;using System;using System.Linq;using System.Threading.Tasks;namespace ProgramBackEnd.SkyServer.mapper.Impl { public class SetmealMapperImpl : ISetmealMapper { private readonly SkyDbContext _skyDbContext; public SetmealMapperImpl (SkyDbContext skyDbContext ) { _skyDbContext = skyDbContext ?? throw new ArgumentNullException(nameof (skyDbContext)); } public async Task<int > CountByCategoryId (long id ) { try { int total = await _skyDbContext.Setmeals .Where(s => s.CategoryId == id) .CountAsync(); return total; } catch (Exception ex) { throw new InvalidOperationException( $"统计分类ID为{id} 的套餐数量时发生错误: {ex.Message} " , ex); } } public async Task Update (Setmeal setmeal ) { if (setmeal == null ) { throw new ArgumentNullException(nameof (setmeal), "套餐对象不能为null" ); } try { var existingSetmeal = await _skyDbContext.Setmeals.FindAsync(setmeal.Id); if (existingSetmeal == null ) { throw new InvalidOperationException($"未找到ID为{setmeal.Id} 的套餐" ); } if (setmeal.Name != null ) existingSetmeal.Name = setmeal.Name; if (setmeal.CategoryId != 0 ) existingSetmeal.CategoryId = setmeal.CategoryId; if (setmeal.Price != 0 ) existingSetmeal.Price = setmeal.Price; if (setmeal.Status.HasValue) existingSetmeal.Status = setmeal.Status; if (setmeal.Description != null ) existingSetmeal.Description = setmeal.Description; if (setmeal.Image != null ) existingSetmeal.Image = setmeal.Image; if (setmeal.UpdateTime != default ) existingSetmeal.UpdateTime = setmeal.UpdateTime; if (setmeal.UpdateUser != 0 ) existingSetmeal.UpdateUser = setmeal.UpdateUser; await _skyDbContext.SaveChangesAsync(); } catch (Exception ex) when (!(ex is InvalidOperationException && ex.Message.StartsWith("未找到ID" ))) { throw new InvalidOperationException( $"更新套餐(ID:{setmeal.Id} )时发生错误: {ex.Message} " , ex); } } } }
10、ISetmealDishMapper ProgramBackEnd\SkyServer\mapper\ISetmealDishMapper.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 using System.Collections.Generic;using System.Threading.Tasks;namespace ProgramBackEnd.SkyServer.mapper { public interface ISetmealDishMapper { Task<List<long >> GetSetmealIdsByDishIds(List<long > ids); } }
11、SetmealDishMapperImpl ProgramBackEnd\SkyServer\mapper\Impl\SetmealDishMapperImpl.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 using Microsoft.EntityFrameworkCore;using ProgramBackEnd.SkyServer.config;using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;namespace ProgramBackEnd.SkyServer.mapper.Impl { public class SetmealDishMapperImpl : ISetmealDishMapper { private readonly SkyDbContext _skyDbContext; public SetmealDishMapperImpl (SkyDbContext skyDbContext ) { _skyDbContext = skyDbContext ?? throw new ArgumentNullException(nameof (skyDbContext)); } public async Task<List<long >> GetSetmealIdsByDishIds(List<long > ids) { if (ids == null || ids.Count == 0 ) { return new List<long >(); } try { var setmealIds = await _skyDbContext.SetmealDishes .Where(sd => ids.Contains(sd.DishId)) .Select(sd => sd.SetmealId) .Distinct() .ToListAsync(); return setmealIds; } catch (Exception ex) { throw new InvalidOperationException( $"查询包含指定菜品的套餐时发生错误: {ex.Message} " , ex); } } } }
7、结果展示 1、查
2、增
3、改
4、删