diff --git a/Infrastructure/Attribute/LogAttribute.cs b/Infrastructure/Attribute/LogAttribute.cs index 20df620..0e764c5 100644 --- a/Infrastructure/Attribute/LogAttribute.cs +++ b/Infrastructure/Attribute/LogAttribute.cs @@ -18,6 +18,10 @@ namespace Infrastructure.Attribute /// public bool IsSaveResponseData { get; set; } = true; + /// + /// 内容 + /// + public string MessageKey { get; set; } public LogAttribute() { } public LogAttribute(string name) diff --git a/Infrastructure/Helper/LogMessageRegistry.cs b/Infrastructure/Helper/LogMessageRegistry.cs new file mode 100644 index 0000000..8b0b544 --- /dev/null +++ b/Infrastructure/Helper/LogMessageRegistry.cs @@ -0,0 +1,47 @@ +using Microsoft.AspNetCore.Mvc.Filters; + +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNetCore.Mvc; +using System.Text; +using System.Threading.Tasks; + +namespace ZR.Infrastructure.Helper; + +public static class LogMessageRegistry +{ + public static readonly Dictionary> Templates + = new Dictionary> + { + ["giftclaim:status"] = ctx => + { + if (ctx.HttpContext.Request.Query.TryGetValue("id", out var idStr) && + ctx.HttpContext.Request.Query.TryGetValue("status", out var statusStr)) + { + var id = int.Parse(idStr); + int status = int.Parse(statusStr); + if (id > 0) + { + return $"礼品审核状态修改,礼品兑换ID:{id},修改时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},修改状态为:{(status == 1 ? "通过" : "未通过")}"; + } + } + return ""; + } + }; + + /// + /// 获取日志消息模板 + /// + /// + /// + /// + public static string GetMessage(string key, ResultExecutedContext client) + { + if (!Templates.TryGetValue(key, out var func)) + { + return ""; + } + return func(client); + } +} diff --git a/Infrastructure/WebExtensions/LogoExtension.cs b/Infrastructure/WebExtensions/LogoExtension.cs index 20fd26d..22dc791 100644 --- a/Infrastructure/WebExtensions/LogoExtension.cs +++ b/Infrastructure/WebExtensions/LogoExtension.cs @@ -16,11 +16,11 @@ namespace Infrastructure Console.WriteLine(content); Console.ForegroundColor = ConsoleColor.Blue; //Console.WriteLine("🎉源码地址: https://gitee.com/izory/ZrAdminNetCore"); - Console.WriteLine("📖官方文档:http://www.izhaorui.cn"); - Console.WriteLine("💰打赏作者:http://www.izhaorui.cn/vip"); - Console.WriteLine("📱移动端体验:http://demo.izhaorui.cn/h5"); - Console.WriteLine($"Swagger地址:{url}/swagger/index.html"); - Console.WriteLine($"初始化种子数据地址:{url}/common/InitSeedData"); + //Console.WriteLine("📖官方文档:http://www.izhaorui.cn"); + //Console.WriteLine("💰打赏作者:http://www.izhaorui.cn/vip"); + //Console.WriteLine("📱移动端体验:http://demo.izhaorui.cn/h5"); + //Console.WriteLine($"Swagger地址:{url}/swagger/index.html"); + //Console.WriteLine($"初始化种子数据地址:{url}/common/InitSeedData"); } } } diff --git a/ZR.Admin.WebApi/Controllers/Business/GiftClaimController.cs b/ZR.Admin.WebApi/Controllers/Business/GiftClaimController.cs new file mode 100644 index 0000000..89d72ea --- /dev/null +++ b/ZR.Admin.WebApi/Controllers/Business/GiftClaimController.cs @@ -0,0 +1,154 @@ +using Microsoft.AspNetCore.Mvc; +using ZR.Model.Business.Dto; +using ZR.Model.Business; +using ZR.Service.Business.IBusinessService; +using System.Threading.Tasks; + +//创建时间:2025-07-30 +namespace ZR.Admin.WebApi.Controllers.Business +{ + /// + /// 礼品申领表 + /// + [Route("business/GiftClaim")] + public class GiftClaimController : BaseController + { + /// + /// 礼品申领表接口 + /// + private readonly IGiftClaimService _GiftClaimService; + + public GiftClaimController(IGiftClaimService GiftClaimService) + { + _GiftClaimService = GiftClaimService; + } + + /// + /// 查询礼品申领表列表 + /// + /// + /// + [HttpGet("list")] + [ActionPermissionFilter(Permission = "giftclaim:list")] + public IActionResult QueryGiftClaim([FromQuery] GiftClaimQueryDto parm) + { + var response = _GiftClaimService.GetList(parm); + return SUCCESS(response); + } + + /// + /// 查询礼品申领表列表 + /// + /// + /// + [HttpGet("statistics")] + public IActionResult getGiftClaimStatistics() + { + var nowDate = DateTime.Now.Date; + var nowCount = _GiftClaimService.AsQueryable().Count(); + var shenheCount = _GiftClaimService.AsQueryable().Where(it => it.Status == 0).Count(); + var shenheCount1 = _GiftClaimService.AsQueryable().Where(it => it.Status == 1).Count(); + var shenheCount2 = _GiftClaimService.AsQueryable().Where(it => it.Status == 2).Count(); + return SUCCESS(new { nowCount, shenheCount, shenheCount1, shenheCount2 }); + } + /// + /// 查询礼品申领表详情 + /// + /// + /// + [HttpGet("{Id}")] + [ActionPermissionFilter(Permission = "giftclaim:query")] + public IActionResult GetGiftClaim(int Id) + { + var response = _GiftClaimService.GetInfo(Id); + + var info = response.Adapt(); + return SUCCESS(info); + } + + /// + /// 添加礼品申领表 + /// + /// + [HttpPost] + [ActionPermissionFilter(Permission = "giftclaim:add")] + [Log(Title = "礼品申领记录", BusinessType = BusinessType.INSERT)] + public IActionResult AddGiftClaim([FromBody] GiftClaimDto parm) + { + var modal = parm.Adapt().ToCreate(HttpContext); + + var response = _GiftClaimService.AddGiftClaim(modal); + + return SUCCESS(response); + } + + /// + /// 更新礼品申领表 + /// + /// + [HttpPut] + [ActionPermissionFilter(Permission = "giftclaim:edit")] + [Log(Title = "礼品申领记录", BusinessType = BusinessType.UPDATE)] + public IActionResult UpdateGiftClaim([FromBody] GiftClaimDto parm) + { + var modal = parm.Adapt().ToUpdate(HttpContext); + var response = _GiftClaimService.UpdateGiftClaim(modal); + + return ToResponse(response); + } + + /// + /// 更新礼品申领表 + /// + /// + [HttpPost("editStatus")] + [ActionPermissionFilter(Permission = "giftclaim:editStatus")] + [Log(Title = "礼品申领记录", BusinessType = BusinessType.UPDATE, MessageKey = "giftclaim:status")] + public async Task UpdateGiftClaimStatus([FromQuery] int id, [FromQuery] int status) + { + var model = await _GiftClaimService.AsQueryable().FirstAsync(it => it.Id == id); + if (model == null) + { + return ToResponse(ResultCode.FAIL, "礼品申领数据不存在"); + } + model.Status = status; + model.ReviewAt = DateTime.Now; + var response = await _GiftClaimService.UpdateAsync(model); + return ToResponse(new ApiResult(response ? 200 : 500, "")); + } + + + /// + /// 删除礼品申领表 + /// + /// + [HttpPost("delete/{ids}")] + [ActionPermissionFilter(Permission = "giftclaim:delete")] + [Log(Title = "礼品申领表", BusinessType = BusinessType.DELETE)] + public IActionResult DeleteGiftClaim([FromRoute] string ids) + { + var idArr = Tools.SplitAndConvert(ids); + + return ToResponse(_GiftClaimService.Delete(idArr)); + } + + /// + /// 导出礼品申领表 + /// + /// + [Log(Title = "礼品申领记录", BusinessType = BusinessType.EXPORT, IsSaveResponseData = false)] + [HttpGet("export")] + [ActionPermissionFilter(Permission = "giftclaim:export")] + public IActionResult Export([FromQuery] GiftClaimQueryDto parm) + { + var list = _GiftClaimService.ExportList(parm).Result; + if (list == null || list.Count <= 0) + { + return ToResponse(ResultCode.FAIL, "没有要导出的数据"); + } + var result = ExportExcelMini(list, "礼品申领记录", "礼品申领记录"); + return ExportExcel(result.Item2, result.Item1); + } + + } +} \ No newline at end of file diff --git a/ZR.Admin.WebApi/Controllers/Business/GiftConfigController.cs b/ZR.Admin.WebApi/Controllers/Business/GiftConfigController.cs new file mode 100644 index 0000000..883c1fc --- /dev/null +++ b/ZR.Admin.WebApi/Controllers/Business/GiftConfigController.cs @@ -0,0 +1,116 @@ +using Microsoft.AspNetCore.Mvc; +using ZR.Model.Business.Dto; +using ZR.Model.Business; +using ZR.Service.Business.IBusinessService; +using ZR.Service.Business; + +//创建时间:2025-07-30 +namespace ZR.Admin.WebApi.Controllers.Business +{ + /// + /// 礼品小程序 + /// + [Route("business/GiftConfig")] + public class GiftConfigController : BaseController + { + /// + /// 礼品小程序接口 + /// + private readonly IGiftConfigService _GiftConfigService; + + public GiftConfigController(IGiftConfigService GiftConfigService) + { + _GiftConfigService = GiftConfigService; + } + + /// + /// 查询礼品小程序列表 + /// + /// + /// + [HttpGet("list")] + [ActionPermissionFilter(Permission = "giftconfig:list")] + public IActionResult QueryGiftConfig([FromQuery] GiftConfigQueryDto parm) + { + var response = _GiftConfigService.GetList(parm); + return SUCCESS(response); + } + + + /// + /// 查询礼品小程序详情 + /// + /// + /// + [HttpGet("{Id}")] + [ActionPermissionFilter(Permission = "giftconfig:query")] + public IActionResult GetGiftConfig(int? Id) + { + var t = _GiftConfigService.Count(it => true); + GiftConfigDto info = new GiftConfigDto(); + if (t > 0) + { + var response = _GiftConfigService.GetFirst(it => true); + info = response.Adapt(); + + } + else + { + var tt = _GiftConfigService.AddGiftConfig(new GiftConfig() + { + HomeImage = "", + Extend = "", + Extend1 = "", + }); + info = tt.Adapt(); + } + return SUCCESS(info); + } + + /// + /// 添加礼品小程序 + /// + /// + [HttpPost] + [ActionPermissionFilter(Permission = "giftconfig:add")] + [Log(Title = "礼品小程序", BusinessType = BusinessType.INSERT)] + public IActionResult AddGiftConfig([FromBody] GiftConfigDto parm) + { + var modal = parm.Adapt().ToCreate(HttpContext); + + var response = _GiftConfigService.AddGiftConfig(modal); + + return SUCCESS(response); + } + + /// + /// 更新礼品小程序 + /// + /// + [HttpPut] + [ActionPermissionFilter(Permission = "giftconfig:edit")] + [Log(Title = "礼品小程序", BusinessType = BusinessType.UPDATE)] + public IActionResult UpdateGiftConfig([FromBody] GiftConfigDto parm) + { + var modal = parm.Adapt().ToUpdate(HttpContext); + var response = _GiftConfigService.UpdateGiftConfig(modal); + + return ToResponse(response); + } + + /// + /// 删除礼品小程序 + /// + /// + [HttpPost("delete/{ids}")] + [ActionPermissionFilter(Permission = "giftconfig:delete")] + [Log(Title = "礼品小程序", BusinessType = BusinessType.DELETE)] + public IActionResult DeleteGiftConfig([FromRoute] string ids) + { + var idArr = Tools.SplitAndConvert(ids); + + return ToResponse(_GiftConfigService.Delete(idArr, "删除礼品小程序")); + } + + } +} \ No newline at end of file diff --git a/ZR.Admin.WebApi/Controllers/Business/GiftUserController.cs b/ZR.Admin.WebApi/Controllers/Business/GiftUserController.cs new file mode 100644 index 0000000..9736011 --- /dev/null +++ b/ZR.Admin.WebApi/Controllers/Business/GiftUserController.cs @@ -0,0 +1,121 @@ +using Microsoft.AspNetCore.Mvc; +using ZR.Model.Business.Dto; +using ZR.Model.Business; +using ZR.Service.Business.IBusinessService; + +//创建时间:2025-07-30 +namespace ZR.Admin.WebApi.Controllers.Business +{ + /// + /// 微信用户表 + /// + [Route("business/GiftUser")] + public class GiftUserController : BaseController + { + /// + /// 微信用户表接口 + /// + private readonly IGiftUserService _GiftUserService; + + public GiftUserController(IGiftUserService GiftUserService) + { + _GiftUserService = GiftUserService; + } + + /// + /// 查询微信用户表列表 + /// + /// + /// + [HttpGet("list")] + [ActionPermissionFilter(Permission = "giftuser:list")] + public IActionResult QueryGiftUser([FromQuery] GiftUserQueryDto parm) + { + var response = _GiftUserService.GetList(parm); + return SUCCESS(response); + } + + + /// + /// 查询微信用户表详情 + /// + /// + /// + [HttpGet("{Id}")] + [ActionPermissionFilter(Permission = "giftuser:query")] + public IActionResult GetGiftUser(int Id) + { + var response = _GiftUserService.GetInfo(Id); + + var info = response.Adapt(); + return SUCCESS(info); + } + + /// + /// 添加微信用户表 + /// + /// + [HttpPost] + [ActionPermissionFilter(Permission = "giftuser:add")] + [Log(Title = "微信用户表", BusinessType = BusinessType.INSERT)] + public IActionResult AddGiftUser([FromBody] GiftUserDto parm) + { + parm.CreateTime= DateTime.Now; + parm.UpdateTime= DateTime.Now; + var modal = parm.Adapt().ToCreate(HttpContext); + + var response = _GiftUserService.AddGiftUser(modal); + + return SUCCESS(response); + } + + /// + /// 更新微信用户表 + /// + /// + [HttpPut] + [ActionPermissionFilter(Permission = "giftuser:edit")] + [Log(Title = "微信用户表", BusinessType = BusinessType.UPDATE)] + public IActionResult UpdateGiftUser([FromBody] GiftUserDto parm) + { + parm.UpdateTime = DateTime.Now; + var modal = parm.Adapt().ToUpdate(HttpContext); + var response = _GiftUserService.UpdateGiftUser(modal); + + return ToResponse(response); + } + + /// + /// 删除微信用户表 + /// + /// + [HttpPost("delete/{ids}")] + [ActionPermissionFilter(Permission = "giftuser:delete")] + [Log(Title = "微信用户表", BusinessType = BusinessType.DELETE)] + public IActionResult DeleteGiftUser([FromRoute]string ids) + { + var idArr = Tools.SplitAndConvert(ids); + + return ToResponse(_GiftUserService.Delete(idArr)); + } + + /// + /// 导出微信用户表 + /// + /// + [Log(Title = "微信用户表", BusinessType = BusinessType.EXPORT, IsSaveResponseData = false)] + [HttpGet("export")] + [ActionPermissionFilter(Permission = "giftuser:export")] + public IActionResult Export([FromQuery] GiftUserQueryDto parm) + { + var list = _GiftUserService.ExportList(parm).Result; + if (list == null || list.Count <= 0) + { + return ToResponse(ResultCode.FAIL, "没有要导出的数据"); + } + var result = ExportExcelMini(list, "微信用户表", "微信用户表"); + return ExportExcel(result.Item2, result.Item1); + } + + } +} \ No newline at end of file diff --git a/ZR.Admin.WebApi/Controllers/CommonController.cs b/ZR.Admin.WebApi/Controllers/CommonController.cs index 0f2ecd3..88e6d40 100644 --- a/ZR.Admin.WebApi/Controllers/CommonController.cs +++ b/ZR.Admin.WebApi/Controllers/CommonController.cs @@ -1,10 +1,13 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Options; + using MiniExcelLibs; + using ZR.Infrastructure.IPTools; using ZR.Model.Dto; using ZR.Model.System; +using ZR.Service.Business.IBusinessService; using ZR.ServiceCore.Resources; namespace ZR.Admin.WebApi.Controllers @@ -22,7 +25,10 @@ namespace ZR.Admin.WebApi.Controllers private IWebHostEnvironment WebHostEnvironment; private ISysFileService SysFileService; private readonly IStringLocalizer _localizer; - + /// + /// 礼品小程序接口 + /// + private readonly IGiftConfigService _GiftConfigService; /// /// /// @@ -34,12 +40,14 @@ namespace ZR.Admin.WebApi.Controllers IStringLocalizer stringLocalizer, IOptions options, IWebHostEnvironment webHostEnvironment, - ISysFileService fileService) + ISysFileService fileService, + IGiftConfigService GiftConfigService) { WebHostEnvironment = webHostEnvironment; SysFileService = fileService; OptionsSetting = options.Value; _localizer = stringLocalizer; + _GiftConfigService = GiftConfigService; } /// @@ -56,6 +64,19 @@ namespace ZR.Admin.WebApi.Controllers "如果觉得项目有用,打赏作者喝杯咖啡作为奖励\n☛☛http://www.izhaorui.cn/vip\n"); } + /// + /// home + /// + /// + [Route("/config")] + [HttpGet] + [AllowAnonymous] + public async Task GetConfig() + { + var response = _GiftConfigService.GetFirst(it => true); + return new { home = (response?.HomeImage ?? "") }; + } + /// /// 查询IP信息 /// @@ -98,7 +119,7 @@ namespace ZR.Admin.WebApi.Controllers /// [HttpPost] [ActionPermissionFilter(Permission = "common")] - public async Task UploadFile([FromForm] UploadDto uploadDto, IFormFile file, StoreType storeType = StoreType.LOCAL) + public async Task UploadFile([FromForm] UploadDto uploadDto, IFormFile file, StoreType storeType = StoreType.ALIYUN) { if (file == null) throw new CustomException(ResultCode.PARAM_ERROR, "上传文件不能为空"); SysFile sysfile = new(); diff --git a/ZR.Admin.WebApi/Controllers/WebApiController.cs b/ZR.Admin.WebApi/Controllers/WebApiController.cs new file mode 100644 index 0000000..112e77a --- /dev/null +++ b/ZR.Admin.WebApi/Controllers/WebApiController.cs @@ -0,0 +1,178 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +using SKIT.FlurlHttpClient.Wechat.Api.Models; +using SKIT.FlurlHttpClient.Wechat.Api; +using System.Web; +using ZR.Model.Business; +using ZR.Service.Business.IBusinessService; +using ZR.Model.Business.Dto; +using Org.BouncyCastle.Utilities; +using System.Net; + +namespace ZR.Admin.WebApi.Controllers +{ + /// + /// webApi + /// + [Route("[controller]/[action]")] + [AllowAnonymous] + [ApiExplorerSettings(GroupName = "webapi")] + public class WebApiController : BaseController + { + private readonly WechatApiClient _client; + /// + /// 礼品申领表接口 + /// + private readonly IGiftClaimService _GiftClaimService; + /// + /// 微信用户表接口 + /// + private readonly IGiftUserService _GiftUserService; + public WebApiController(WechatApiClient client, IGiftUserService GiftUserService, IGiftClaimService giftClaimService) + { + _client = client; + _GiftUserService = GiftUserService; + _GiftClaimService = giftClaimService; + } + + + + /// + /// 1 + /// + /// + /// + /// + [HttpPost()] + [Route("/userLogin")] + [AllowAnonymous] + public async Task GetOpenId([FromQuery] string code) + { + var response = await _client.ExecuteSnsJsCode2SessionAsync(new SnsJsCode2SessionRequest + { + JsCode = code, + GrantType = "authorization_code" + }); + if (!response.IsSuccessful()) + { + throw new Exception($"获取OpenId失败: {response.ErrorMessage}"); // 可以根据需要处理异常 + } + var openId = response.OpenId; + var user = await _GiftUserService.AsQueryable().Where(it => it.Openid == openId).FirstAsync(); + if (user == null) + { + user = new GiftUser() + { + AvatarUrl = "", + CreateTime = DateTime.Now, + Nickname = "微信用户", + Openid = openId, + UpdateTime = DateTime.Now, + LastLoginTime = DateTime.Now, + Phone = "", + Status = "0", + Unionid = "" + }; + _GiftUserService.AddGiftUser(user); + } + return SUCCESS(new { user_id = user.Id }); + + } + [HttpGet("/getRecord")] + [AllowAnonymous] + public async Task GetRecord([FromQuery] int userId) + { + if (userId == 0) + { + return ToResponse(ResultCode.CUSTOM_ERROR, "用户不存在"); + } + var user = await _GiftUserService.AsQueryable().Where(it => it.Id == userId).FirstAsync(); + if (user == null) + { + return ToResponse(ResultCode.CUSTOM_ERROR, "用户不存在"); + } + var list = await _GiftClaimService.AsQueryable().Where(it => it.UserId == userId).OrderByDescending(it => it.Id).ToListAsync(); + List list1 = new List(); + list?.ForEach(it => + { + list1.Add(new + { + it.Status, + it.Name, + it.Address, + it.Phone, + time = it.CreatedAt?.ToString("yyyy-MM-dd") + }); + }); + return SUCCESS(list1); + } + public static string domainUrl = AppSettings.GetConfig("ALIYUN_OSS:domainUrl"); + [HttpPost()] + [Route("/addRecord")] + [AllowAnonymous] + public async Task AddRecord([FromBody] AddGiftClaimDto giftClaim) + { + if (giftClaim.UserId == 0) + { + return ToResponse(ResultCode.CUSTOM_ERROR, "用户不存在"); + } + var user = await _GiftUserService.AsQueryable().Where(it => it.Id == giftClaim.UserId).FirstAsync(); + if (user == null) + { + return ToResponse(ResultCode.CUSTOM_ERROR, "用户不存在"); + } + var images = ImageConverter.Base64ToImageBytes(giftClaim.ProductImage); + if (images.Length == 0) + { + return ToResponse(ResultCode.CUSTOM_ERROR, "图片上传失败"); + } + var imageprx = ImageConverter.GetFileExtensionFromBase64(giftClaim.ProductImage); + var imageName = ImageConverter.GenerateImageFileName(imageprx); + var filePath = "gift/" + DateTime.Now.ToString("yyyy/MMdd/"); + //备份一下本地 + var finalPath = filePath + imageName; + if (!string.IsNullOrEmpty(domainUrl)) + { + var statusCode = AliyunOssHelper.PutObjectFromFile(new MemoryStream(images), finalPath, ""); + } + + try + { + var path = Path.GetFullPath(filePath); + if (!Directory.Exists(path)) + { + Directory.CreateDirectory(path); + } + using (var stream = new FileStream(finalPath, FileMode.Create)) + { + await stream.WriteAsync(images, 0, images.Length); + } + } + catch (Exception ex) + { + } + if (!string.IsNullOrEmpty(domainUrl)) + { + finalPath = domainUrl + "/" + finalPath; + } + GiftClaim giftClaim1 = new GiftClaim() + { + Address = giftClaim.Address, + Name = giftClaim.Name, + Phone = giftClaim.Phone, + UserId = giftClaim.UserId, + Status = 0, + Company = giftClaim.Company, + ProductModel = giftClaim.ProductModel, + ProductDate = giftClaim.ProductDate, + ProductSerialNumber = giftClaim.ProductSerialNumber, + CreatedAt = DateTime.Now, + ProductImage = finalPath, + UserWxOpenId= user.Openid + }; + _GiftClaimService.AddGiftClaim(giftClaim1); + return SUCCESS(new { giftClaim1.Id }); + } + } +} diff --git a/ZR.Admin.WebApi/Controllers/WxOpenController.cs b/ZR.Admin.WebApi/Controllers/WxOpenController.cs index 53bbc10..24ce5df 100644 --- a/ZR.Admin.WebApi/Controllers/WxOpenController.cs +++ b/ZR.Admin.WebApi/Controllers/WxOpenController.cs @@ -1,6 +1,14 @@ using Microsoft.AspNetCore.Mvc; + +using SKIT.FlurlHttpClient.Wechat.Api; +using SKIT.FlurlHttpClient.Wechat.Api.Models; + using System.Web; +using ZR.Model.Business.Dto; +using ZR.Model.Business; +using ZR.Service.Business.IBusinessService; + namespace ZR.Admin.WebApi.Controllers { /// @@ -10,6 +18,23 @@ namespace ZR.Admin.WebApi.Controllers [AllowAnonymous] public class WxOpenController : BaseController { + private readonly WechatApiClient _client; + /// + /// 礼品申领表接口 + /// + private readonly IGiftClaimService _GiftClaimService; + /// + /// 微信用户表接口 + /// + private readonly IGiftUserService _GiftUserService; + public WxOpenController(WechatApiClient client, IGiftUserService GiftUserService, IGiftClaimService giftClaimService) + { + _client = client; + _GiftUserService = GiftUserService; + _GiftClaimService = giftClaimService; + } + + /// /// 获取签名 /// @@ -35,5 +60,69 @@ namespace ZR.Admin.WebApi.Controllers return SUCCESS(new { appId, signature, noncestr, timestamp, url }); } + [HttpGet("login")] + [AllowAnonymous] + public async Task GetOpenId([FromQuery] string code) + { + var response = await _client.ExecuteSnsJsCode2SessionAsync(new SnsJsCode2SessionRequest + { + JsCode = code, + GrantType = "authorization_code" + }); + if (!response.IsSuccessful()) + { + throw new Exception($"获取OpenId失败: {response.ErrorMessage}"); // 可以根据需要处理异常 + } + var openId = response.OpenId; + var user = await _GiftUserService.AsQueryable().Where(it => it.Openid == openId).FirstAsync(); + if (user == null) + { + //response. + user = new GiftUser() + { + AvatarUrl = "", + CreateTime = DateTime.Now, + Nickname = "微信用户", + Openid = openId, + UpdateTime = DateTime.Now, + LastLoginTime = DateTime.Now, + Phone = "", + Status = "0", + Unionid = "" + }; + _GiftUserService.AddGiftUser(user); + } + return SUCCESS(new { user_id = user.Id }); + + } + [HttpGet("getRecord")] + [AllowAnonymous] + public async Task GetRecord([FromQuery] int user_id) + { + if (user_id == 0) + { + return ToResponse(ResultCode.CUSTOM_ERROR, "用户不存在"); + } + var user = await _GiftUserService.AsQueryable().Where(it => it.Id == user_id).FirstAsync(); + if (user == null) + { + return ToResponse(ResultCode.CUSTOM_ERROR, "用户不存在"); + } + var list = await _GiftClaimService.AsQueryable().Where(it => it.UserId == user_id).ToListAsync(); + List list1 = new List(); + list?.ForEach(it => + { + list1.Add(new + { + it.Status, + it.Name, + it.Address, + it.Phone + }); + }); + return SUCCESS(list1); + } + + } } diff --git a/ZR.Admin.WebApi/Program.cs b/ZR.Admin.WebApi/Program.cs index 8c61fe5..2d360f6 100644 --- a/ZR.Admin.WebApi/Program.cs +++ b/ZR.Admin.WebApi/Program.cs @@ -13,6 +13,7 @@ using ZR.Infrastructure.WebExtensions; using ZR.ServiceCore.Signalr; using ZR.ServiceCore.SqlSugar; using ZR.Mall; +using SKIT.FlurlHttpClient.Wechat.Api; //using SQLitePCL; var builder = WebApplication.CreateBuilder(args); @@ -50,6 +51,19 @@ builder.Services.AddJwt(); builder.Services.AddSingleton(new AppSettings(builder.Configuration)); //app服务注册 builder.Services.AddAppService(); +var wxMp = builder.Configuration.GetSection("WxMp"); +var mp_appid = wxMp.GetSection("AppID").Value ?? "";//默认值 +var mp_appSecret = wxMp.GetSection("AppSecret").Value ?? "";//默认值 + +builder.Services.AddSingleton(sp => +{ + return new WechatApiClient(new WechatApiClientOptions + { + AppId = mp_appid, + AppSecret = mp_appSecret + }); +}); + //开启计划任务 builder.Services.AddTaskSchedulers(); //请求大小限制 diff --git a/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj b/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj index e1e5949..4fb9a8d 100644 --- a/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj +++ b/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj @@ -20,6 +20,7 @@ + @@ -27,6 +28,7 @@ + diff --git a/ZR.Admin.WebApi/appsettings.json b/ZR.Admin.WebApi/appsettings.json index 7c760ab..671c93d 100644 --- a/ZR.Admin.WebApi/appsettings.json +++ b/ZR.Admin.WebApi/appsettings.json @@ -25,7 +25,7 @@ //代码生成数据库配置 初始化数据:http://localhost:8888/common/initseedData "CodeGenDbConfig": { //代码生成连接字符串,注意{dbName}为固定格式,不要填写数据库名 - "Conn": "Data Source=192.168.1.41;User ID=sa;Password=Dbt@com@123;Initial Catalog={dbName};", + "Conn": "Data Source=192.168.1.41;User ID=sa;Password=Dbt@com@123;Encrypt=True;TrustServerCertificate=True;Initial Catalog={dbName};", "DbType": 1, "IsAutoCloseConnection": true, "DbName": "ZrAdmin" //代码生成默认连接数据库,Oracle库是实例的名称 @@ -43,8 +43,8 @@ "MainDb": "0", // 多租户主库配置ID "UseTenant": 0, //是否启用多租户 0:不启用 1:启用 "InjectClass": [ "ZR.Repository", "ZR.Service", "ZR.Tasks", "ZR.ServiceCore", "ZR.Mall" ], //自动注入类 - "ShowDbLog": true, //是否打印db日志 - "InitDb": true, //是否初始化db + "ShowDbLog": false, //是否打印db日志 + "InitDb": false, //是否初始化db "DemoMode": false, //是否演示模式 "SingleLogin": false, //是否允许多设备/浏览器登录 "workId": 1, //雪花id唯一数字 @@ -58,11 +58,11 @@ }, //阿里云存储配置 "ALIYUN_OSS": { - "REGIONID": "", //eg:cn-hangzhou - "KEY": "XX", - "SECRET": "XX", - "bucketName": "bucketName", - "domainUrl": "http://xxx.xxx.com", //访问资源域名 + "REGIONID": "https://oss-cn-shanghai.aliyuncs.com", //eg:cn-hangzhou + "KEY": "LTAI5tAm5ZZf2HWXDSbpa2qZ", + "SECRET": "daMgmpVpxVC9R0u88O3gbHjHmytyCM", + "bucketName": "zpc-gift", + "domainUrl": "https://zpc-gift.oss-cn-shanghai.aliyuncs.com", //访问资源域名 "maxSize": 100 //上传文件大小限制 100M }, //企业微信通知配置 @@ -77,6 +77,10 @@ "AppID": "", "AppSecret": "" }, + "WxMp": { + "AppId": "wx595ec949c6efd72b", //公众号AppId" + "AppSecret": "81202b95746795f429fda6a448548b60" //公众号AppSecret + }, //邮箱配置信息 "MailOptions": [ { diff --git a/ZR.Admin.WebApi/gift/2025/0731/1753959570_3841.jpg b/ZR.Admin.WebApi/gift/2025/0731/1753959570_3841.jpg new file mode 100644 index 0000000..6036a9f Binary files /dev/null and b/ZR.Admin.WebApi/gift/2025/0731/1753959570_3841.jpg differ diff --git a/ZR.Admin.WebApi/gift/2025/0731/1753960453_1554.jpg b/ZR.Admin.WebApi/gift/2025/0731/1753960453_1554.jpg new file mode 100644 index 0000000..d023d6c Binary files /dev/null and b/ZR.Admin.WebApi/gift/2025/0731/1753960453_1554.jpg differ diff --git a/ZR.Admin.WebApi/gift/2025/0731/1753960582_6224.jpg b/ZR.Admin.WebApi/gift/2025/0731/1753960582_6224.jpg new file mode 100644 index 0000000..d023d6c Binary files /dev/null and b/ZR.Admin.WebApi/gift/2025/0731/1753960582_6224.jpg differ diff --git a/ZR.Admin.WebApi/gift/2025/0731/1753961346_7203.jpg b/ZR.Admin.WebApi/gift/2025/0731/1753961346_7203.jpg new file mode 100644 index 0000000..d023d6c Binary files /dev/null and b/ZR.Admin.WebApi/gift/2025/0731/1753961346_7203.jpg differ diff --git a/ZR.Admin.WebApi/gift/2025/0731/1753963521_6271.jpg b/ZR.Admin.WebApi/gift/2025/0731/1753963521_6271.jpg new file mode 100644 index 0000000..6036a9f Binary files /dev/null and b/ZR.Admin.WebApi/gift/2025/0731/1753963521_6271.jpg differ diff --git a/ZR.Admin.WebApi/gift/2025/0801/1754025667_6541.jpg b/ZR.Admin.WebApi/gift/2025/0801/1754025667_6541.jpg new file mode 100644 index 0000000..6036a9f Binary files /dev/null and b/ZR.Admin.WebApi/gift/2025/0801/1754025667_6541.jpg differ diff --git a/ZR.Admin.WebApi/gift/2025/0801/1754025801_3379.jpg b/ZR.Admin.WebApi/gift/2025/0801/1754025801_3379.jpg new file mode 100644 index 0000000..6036a9f Binary files /dev/null and b/ZR.Admin.WebApi/gift/2025/0801/1754025801_3379.jpg differ diff --git a/ZR.Admin.WebApi/wwwroot/2025/0730/0d11f20ad2eea600.png b/ZR.Admin.WebApi/wwwroot/2025/0730/0d11f20ad2eea600.png new file mode 100644 index 0000000..e74cf84 Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/2025/0730/0d11f20ad2eea600.png differ diff --git a/ZR.Admin.WebApi/wwwroot/2025/0730/2462dc9bc2549207.jpg b/ZR.Admin.WebApi/wwwroot/2025/0730/2462dc9bc2549207.jpg new file mode 100644 index 0000000..39d717e Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/2025/0730/2462dc9bc2549207.jpg differ diff --git a/ZR.Admin.WebApi/wwwroot/2025/0730/434da46405a347d2.png b/ZR.Admin.WebApi/wwwroot/2025/0730/434da46405a347d2.png new file mode 100644 index 0000000..e74cf84 Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/2025/0730/434da46405a347d2.png differ diff --git a/ZR.Admin.WebApi/wwwroot/2025/0730/eff3068dd43bdef6.png b/ZR.Admin.WebApi/wwwroot/2025/0730/eff3068dd43bdef6.png new file mode 100644 index 0000000..e74cf84 Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/2025/0730/eff3068dd43bdef6.png differ diff --git a/ZR.Admin.WebApi/wwwroot/2025/0731/68ce26d1f3ab7887.png b/ZR.Admin.WebApi/wwwroot/2025/0731/68ce26d1f3ab7887.png new file mode 100644 index 0000000..e74cf84 Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/2025/0731/68ce26d1f3ab7887.png differ diff --git a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt index 97a52ea..4f590a0 100644 --- a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt +++ b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt @@ -747,6 +747,7 @@ $if(replaceDto.ShowBtnEdit) // 修改按钮操作 function handleUpdate(row) { reset() + state.submitLoading = false const id = row.${replaceDto.FistLowerPk} || ids.value get${genTable.BusinessName}(id).then((res) => { const { code, data } = res diff --git a/ZR.Admin.WebApi/wwwroot/logo.txt b/ZR.Admin.WebApi/wwwroot/logo.txt index 8b06c93..8bd1990 100644 --- a/ZR.Admin.WebApi/wwwroot/logo.txt +++ b/ZR.Admin.WebApi/wwwroot/logo.txt @@ -1,7 +1,7 @@ - ___________ _ _ _ _ ______ _______ - |___ / __ \ /\ | | (_) | \ | | ____|__ __| - / /| |__) | / \ __| |_ __ ___ _ _ __ | \| | |__ | | - / / | _ / / /\ \ / _` | '_ ` _ \| | '_ \ | . ` | __| | | - / /__| | \ \ / ____ \ (_| | | | | | | | | | |_| |\ | |____ | | - /_____|_| \_\/_/ \_\__,_|_| |_| |_|_|_| |_(_)_| \_|______| |_| + _ _ _ _ ______ _______ + /\ | | (_) | \ | | ____|__ __| + / \ __| |_ __ ___ _ _ __ | \| | |__ | | + / /\ \ / _` | '_ ` _ \| | '_ \ | . ` | __| | | + / ____ \ (_| | | | | | | | | | |_| |\ | |____ | | +/_/ \_\__,_|_| |_| |_|_|_| |_(_)_| \_|______| |_| \ No newline at end of file diff --git a/ZR.Common/ImageConverter.cs b/ZR.Common/ImageConverter.cs new file mode 100644 index 0000000..0e82bf6 --- /dev/null +++ b/ZR.Common/ImageConverter.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace ZR.Common; + +public static class ImageConverter +{ + + /// + /// 将 Base64 编码的字符串转换为图片的二进制数据(byte[])。 + /// + /// Base64 编码的字符串,格式可以包含前缀(如 data:image/png;base64,)或不包含 + /// 图片的字节数组 + public static byte[] Base64ToImageBytes(string base64String) + { + // 如果包含 data:image/...base64, 的前缀,去除它 + var base64Data = base64String; + + if (base64String.Contains(",")) + { + base64Data = base64String.Substring(base64String.IndexOf(",") + 1); + } + + // 将 base64 字符串转换为字节数组 + return Convert.FromBase64String(base64Data); + } + + /// + /// 将 Base64 转换成图片文件并保存到指定路径 + /// + /// Base64 字符串 + /// 输出文件完整路径(包含文件名和扩展名) + public static void SaveBase64AsImage(string base64String, string outputPath) + { + byte[] imageBytes = Base64ToImageBytes(base64String); + File.WriteAllBytes(outputPath, imageBytes); + } + + + /// + /// 从 Base64 字符串中提取文件扩展名。 + /// + /// + /// + public static string GetFileExtensionFromBase64(string base64) + { + // 正则匹配 MIME 类型 + var match = Regex.Match(base64, @"^data:image/(?[a-zA-Z+]+);base64,"); + if (!match.Success) return null; + + string mimeType = match.Groups["format"].Value.ToLower(); + + // MIME 类型转文件扩展名 + return mimeType switch + { + "png" => ".png", + "jpeg" or "jpg" => ".jpg", + "gif" => ".gif", + "webp" => ".webp", + "bmp" => ".bmp", + "svg+xml" => ".svg", + "tiff" => ".tiff", + "x-icon" => ".ico", + _ => null // 未知类型 + }; + } + + /// + /// 生成图片名称:时间戳(秒)+4位随机数字 + /// 示例:16907832451234.png + /// + /// 文件扩展名(例如 .png、.jpg),可选,默认值为 .png + /// 生成的图片文件名 + public static string GenerateImageFileName(string extension = ".png") + { + // 获取当前时间戳(秒) + long timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); + + // 生成 4 位随机数(1000 - 9999) + Random random = new Random(); + int randomNumber = random.Next(1000, 10000); + + // 拼接文件名 + return $"{timestamp}_{randomNumber}{extension}"; + } + +} + + diff --git a/ZR.Common/ZR.Common.csproj b/ZR.Common/ZR.Common.csproj index bbef2da..d99c603 100644 --- a/ZR.Common/ZR.Common.csproj +++ b/ZR.Common/ZR.Common.csproj @@ -8,6 +8,7 @@ + diff --git a/ZR.Model/Business/Dto/GiftClaimDto.cs b/ZR.Model/Business/Dto/GiftClaimDto.cs new file mode 100644 index 0000000..bc29cdd --- /dev/null +++ b/ZR.Model/Business/Dto/GiftClaimDto.cs @@ -0,0 +1,156 @@ + +namespace ZR.Model.Business.Dto +{ + /// + /// 礼品申领表查询对象 + /// + public class GiftClaimQueryDto : PagerInfo + { + public string Name { get; set; } + public string Phone { get; set; } + public string Company { get; set; } + public string Address { get; set; } + public string ProductModel { get; set; } + public string ProductSerialNumber { get; set; } + public int? Status { get; set; } + + public string UserWxOpenId { get; set; } + } + + /// + /// 礼品申领表输入输出对象 + /// + public class GiftClaimDto + { + [Required(ErrorMessage = "主键不能为空")] + [ExcelColumn(Name = "主键")] + [ExcelColumnName("主键")] + public int Id { get; set; } + + [Required(ErrorMessage = "用户ID不能为空")] + [ExcelColumn(Name = "用户ID")] + [ExcelColumnName("用户ID")] + public int UserId { get; set; } + + [Required(ErrorMessage = "姓名不能为空")] + [ExcelColumn(Name = "姓名")] + [ExcelColumnName("姓名")] + public string Name { get; set; } + + [Required(ErrorMessage = "联系方式不能为空")] + [ExcelColumn(Name = "联系方式")] + [ExcelColumnName("联系方式")] + public string Phone { get; set; } + + [ExcelColumn(Name = "工作单位")] + [ExcelColumnName("工作单位")] + public string Company { get; set; } + + [Required(ErrorMessage = "收货地址不能为空")] + [ExcelColumn(Name = "收货地址")] + [ExcelColumnName("收货地址")] + public string Address { get; set; } + + [Required(ErrorMessage = "产品型号不能为空")] + [ExcelColumn(Name = "产品型号")] + [ExcelColumnName("产品型号")] + public string ProductModel { get; set; } + + [Required(ErrorMessage = "出品编号不能为空")] + [ExcelColumn(Name = "出品编号")] + [ExcelColumnName("出品编号")] + public string ProductSerialNumber { get; set; } + + [Required(ErrorMessage = "出品年月不能为空")] + [ExcelColumn(Name = "出品年月")] + [ExcelColumnName("出品年月")] + public string ProductDate { get; set; } + + [ExcelColumn(Name = "出品图片")] + [ExcelColumnName("出品图片")] + public string ProductImage { get; set; } + + [ExcelColumn(Name = "提交时间", Format = "yyyy-MM-dd HH:mm:ss", Width = 20)] + [ExcelColumnName("提交时间")] + public DateTime? CreatedAt { get; set; } + + [Required(ErrorMessage = "审核状态不能为空")] + [ExcelColumn(Name = "审核状态")] + [ExcelColumnName("审核状态")] + public int Status { get; set; } + + + + [ExcelColumn(Name = "审核状态")] + public string StatusLabel { get; set; } + + /// + /// 审核时间 + /// + [ExcelColumn(Name = "审核时间")] + [ExcelColumnName("审核时间")] + public DateTime? ReviewAt { get; set; } + + /// + /// 微信用户id + /// + [ExcelColumn(Name = "微信用户id")] + [ExcelColumnName("微信用户id")] + public string UserWxOpenId { get; set; } + } + /// + /// 礼品申领表输入输出对象 + /// + public class AddGiftClaimDto + { + + [Required(ErrorMessage = "用户ID不能为空")] + [ExcelColumn(Name = "用户ID")] + [ExcelColumnName("用户ID")] + public int UserId { get; set; } + + [Required(ErrorMessage = "姓名不能为空")] + [ExcelColumn(Name = "姓名")] + [ExcelColumnName("姓名")] + public string Name { get; set; } + + [Required(ErrorMessage = "联系方式不能为空")] + [ExcelColumn(Name = "联系方式")] + [ExcelColumnName("联系方式")] + public string Phone { get; set; } + + [ExcelColumn(Name = "工作单位")] + [ExcelColumnName("工作单位")] + public string Company { get; set; } + + [Required(ErrorMessage = "收货地址不能为空")] + [ExcelColumn(Name = "收货地址")] + [ExcelColumnName("收货地址")] + public string Address { get; set; } + + [Required(ErrorMessage = "产品型号不能为空")] + [ExcelColumn(Name = "产品型号")] + [ExcelColumnName("产品型号")] + public string ProductModel { get; set; } + + [Required(ErrorMessage = "出品编号不能为空")] + [ExcelColumn(Name = "出品编号")] + [ExcelColumnName("出品编号")] + public string ProductSerialNumber { get; set; } + + [Required(ErrorMessage = "出品年月不能为空")] + [ExcelColumn(Name = "出品年月")] + [ExcelColumnName("出品年月")] + public string ProductDate { get; set; } + [Required(ErrorMessage = "出品图片不能为空")] + [ExcelColumn(Name = "出品图片")] + [ExcelColumnName("出品图片")] + public string ProductImage { get; set; } + + + + } + + + +} \ No newline at end of file diff --git a/ZR.Model/Business/Dto/GiftConfigDto.cs b/ZR.Model/Business/Dto/GiftConfigDto.cs new file mode 100644 index 0000000..e162c6a --- /dev/null +++ b/ZR.Model/Business/Dto/GiftConfigDto.cs @@ -0,0 +1,28 @@ + +namespace ZR.Model.Business.Dto +{ + /// + /// 礼品小程序查询对象 + /// + public class GiftConfigQueryDto : PagerInfo + { + } + + /// + /// 礼品小程序输入输出对象 + /// + public class GiftConfigDto + { + [Required(ErrorMessage = "Id不能为空")] + public int Id { get; set; } + + public string HomeImage { get; set; } + + public string Extend { get; set; } + + public string Extend1 { get; set; } + + + + } +} \ No newline at end of file diff --git a/ZR.Model/Business/Dto/GiftUserDto.cs b/ZR.Model/Business/Dto/GiftUserDto.cs new file mode 100644 index 0000000..628b2e6 --- /dev/null +++ b/ZR.Model/Business/Dto/GiftUserDto.cs @@ -0,0 +1,73 @@ + +namespace ZR.Model.Business.Dto +{ + /// + /// 微信用户表查询对象 + /// + public class GiftUserQueryDto : PagerInfo + { + public string Nickname { get; set; } + } + + /// + /// 微信用户表输入输出对象 + /// + public class GiftUserDto + { + [Required(ErrorMessage = "主键ID不能为空")] + [ExcelColumn(Name = "主键ID")] + [ExcelColumnName("主键ID")] + public int Id { get; set; } + + [Required(ErrorMessage = "微信openid不能为空")] + [ExcelColumn(Name = "微信openid")] + [ExcelColumnName("微信openid")] + public string Openid { get; set; } + + [ExcelColumn(Name = "微信unionid")] + [ExcelColumnName("微信unionid")] + public string Unionid { get; set; } + + [ExcelColumn(Name = "昵称")] + [ExcelColumnName("昵称")] + public string Nickname { get; set; } + + [ExcelColumn(Name = "头像URL")] + [ExcelColumnName("头像URL")] + public string AvatarUrl { get; set; } + + [ExcelColumn(Name = "性别")] + [ExcelColumnName("性别")] + public string Gender { get; set; } + + [ExcelColumn(Name = "手机号")] + [ExcelColumnName("手机号")] + public string Phone { get; set; } + + [Required(ErrorMessage = "状态不能为空")] + [ExcelColumn(Name = "状态")] + [ExcelColumnName("状态")] + public string Status { get; set; } + + [ExcelColumn(Name = "最后登录时间", Format = "yyyy-MM-dd HH:mm:ss", Width = 20)] + [ExcelColumnName("最后登录时间")] + public DateTime? LastLoginTime { get; set; } + + //[Required(ErrorMessage = "创建时间不能为空")] + [ExcelColumn(Name = "创建时间", Format = "yyyy-MM-dd HH:mm:ss", Width = 20)] + [ExcelColumnName("创建时间")] + public DateTime? CreateTime { get; set; } + + //[Required(ErrorMessage = "更新时间不能为空")] + [ExcelColumn(Name = "更新时间", Format = "yyyy-MM-dd HH:mm:ss", Width = 20)] + [ExcelColumnName("更新时间")] + public DateTime? UpdateTime { get; set; } + + + + [ExcelColumn(Name = "性别")] + public string GenderLabel { get; set; } + [ExcelColumn(Name = "状态")] + public string StatusLabel { get; set; } + } +} \ No newline at end of file diff --git a/ZR.Model/Business/GiftClaim.cs b/ZR.Model/Business/GiftClaim.cs new file mode 100644 index 0000000..4cdf7e3 --- /dev/null +++ b/ZR.Model/Business/GiftClaim.cs @@ -0,0 +1,83 @@ + +namespace ZR.Model.Business +{ + /// + /// 礼品申领表 + /// + [SugarTable("gift_claim")] + public class GiftClaim + { + /// + /// 主键 + /// + [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + public int Id { get; set; } + + /// + /// 用户ID + /// + [SugarColumn(ColumnName = "user_id")] + public int UserId { get; set; } + + /// + /// 姓名 + /// + public string Name { get; set; } + + /// + /// 联系方式 + /// + public string Phone { get; set; } + + /// + /// 工作单位 + /// + public string Company { get; set; } + + /// + /// 收货地址 + /// + public string Address { get; set; } + + /// + /// 产品型号 + /// + public string ProductModel { get; set; } + + /// + /// 出品编号 + /// + public string ProductSerialNumber { get; set; } + + /// + /// 出品年月 + /// + public string ProductDate { get; set; } + + /// + /// 出品图片 + /// + public string ProductImage { get; set; } + + /// + /// 提交时间 + /// + public DateTime? CreatedAt { get; set; } + + /// + /// 审核状态 + /// + public int Status { get; set; } + + /// + /// 审核时间 + /// + public DateTime? ReviewAt { get; set; } + + /// + /// 微信用户id + /// + public string UserWxOpenId { get; set; } + + } +} \ No newline at end of file diff --git a/ZR.Model/Business/GiftConfig.cs b/ZR.Model/Business/GiftConfig.cs new file mode 100644 index 0000000..81a117d --- /dev/null +++ b/ZR.Model/Business/GiftConfig.cs @@ -0,0 +1,32 @@ + +namespace ZR.Model.Business +{ + /// + /// 礼品小程序 + /// + [SugarTable("gift_config")] + public class GiftConfig + { + /// + /// Id + /// + [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + public int Id { get; set; } + + /// + /// 首页图片 + /// + public string HomeImage { get; set; } + + /// + /// 扩展1 + /// + public string Extend { get; set; } + + /// + /// 扩展2 + /// + public string Extend1 { get; set; } + + } +} \ No newline at end of file diff --git a/ZR.Model/Business/GiftUser.cs b/ZR.Model/Business/GiftUser.cs new file mode 100644 index 0000000..ef915f1 --- /dev/null +++ b/ZR.Model/Business/GiftUser.cs @@ -0,0 +1,71 @@ + +namespace ZR.Model.Business +{ + /// + /// 微信用户表 + /// + [SugarTable("gift_user")] + public class GiftUser + { + /// + /// 主键ID + /// + [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + public int Id { get; set; } + + /// + /// 微信openid + /// + public string Openid { get; set; } + + /// + /// 微信unionid + /// + public string Unionid { get; set; } + + /// + /// 昵称 + /// + public string Nickname { get; set; } + + /// + /// 头像URL + /// + [SugarColumn(ColumnName = "avatar_url")] + public string AvatarUrl { get; set; } + + /// + /// 性别 + /// + public string Gender { get; set; } + + /// + /// 手机号 + /// + public string Phone { get; set; } + + /// + /// 状态 + /// + public string Status { get; set; } + + /// + /// 最后登录时间 + /// + [SugarColumn(ColumnName = "last_login_time")] + public DateTime? LastLoginTime { get; set; } + + /// + /// 创建时间 + /// + [SugarColumn(ColumnName = "create_time")] + public DateTime? CreateTime { get; set; } + + /// + /// 更新时间 + /// + [SugarColumn(ColumnName = "update_time")] + public DateTime? UpdateTime { get; set; } + + } +} \ No newline at end of file diff --git a/ZR.Service/Business/GiftClaimService.cs b/ZR.Service/Business/GiftClaimService.cs new file mode 100644 index 0000000..dcf3cd1 --- /dev/null +++ b/ZR.Service/Business/GiftClaimService.cs @@ -0,0 +1,117 @@ +using Infrastructure.Attribute; +using Infrastructure.Extensions; +using ZR.Model.Business.Dto; +using ZR.Model.Business; +using ZR.Repository; +using ZR.Service.Business.IBusinessService; + +namespace ZR.Service.Business +{ + /// + /// 礼品申领表Service业务层处理 + /// + [AppService(ServiceType = typeof(IGiftClaimService), ServiceLifetime = LifeTime.Transient)] + public class GiftClaimService : BaseService, IGiftClaimService + { + /// + /// 查询礼品申领表列表 + /// + /// + /// + public PagedInfo GetList(GiftClaimQueryDto parm) + { + var predicate = QueryExp(parm); + + var response = Queryable() + //.OrderBy("Id desc") + .Where(predicate.ToExpression()) + .ToPage(parm); + //response.Result.ForEach(item => + //{ + // if (item.ProductImage.IndexOf("http") == -1) + // { + // item.ProductImage = "" + + // } + + //}); + return response; + } + + + /// + /// 获取详情 + /// + /// + /// + public GiftClaim GetInfo(int Id) + { + var response = Queryable() + .Where(x => x.Id == Id) + .First(); + + return response; + } + + /// + /// 添加礼品申领表 + /// + /// + /// + public GiftClaim AddGiftClaim(GiftClaim model) + { + return Insertable(model).ExecuteReturnEntity(); + } + + /// + /// 修改礼品申领表 + /// + /// + /// + public int UpdateGiftClaim(GiftClaim model) + { + return Update(model, true); + } + + /// + /// 导出礼品申领表 + /// + /// + /// + public PagedInfo ExportList(GiftClaimQueryDto parm) + { + parm.PageNum = 1; + parm.PageSize = 100000; + var predicate = QueryExp(parm); + + var response = Queryable() + .Where(predicate.ToExpression()) + .Select((it) => new GiftClaimDto() + { + StatusLabel = it.Status.GetConfigValue("gift_request_claim"), + }, true) + .ToPage(parm); + + return response; + } + + /// + /// 查询导出表达式 + /// + /// + /// + private static Expressionable QueryExp(GiftClaimQueryDto parm) + { + var predicate = Expressionable.Create(); + + predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.Name), it => it.Name.Contains(parm.Name)); + predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.Phone), it => it.Phone.Contains(parm.Phone)); + predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.Company), it => it.Company.Contains(parm.Company)); + predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.Address), it => it.Address.Contains(parm.Address)); + predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.ProductModel), it => it.ProductModel.Contains(parm.ProductModel)); + predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.ProductSerialNumber), it => it.ProductSerialNumber.Contains(parm.ProductSerialNumber)); + predicate = predicate.AndIF(parm.Status != null, it => it.Status == parm.Status); + predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.UserWxOpenId), it => it.UserWxOpenId.Contains(parm.UserWxOpenId)); + return predicate; + } + } +} \ No newline at end of file diff --git a/ZR.Service/Business/GiftConfigService.cs b/ZR.Service/Business/GiftConfigService.cs new file mode 100644 index 0000000..b660a60 --- /dev/null +++ b/ZR.Service/Business/GiftConfigService.cs @@ -0,0 +1,79 @@ +using Infrastructure.Attribute; +using Infrastructure.Extensions; +using ZR.Model.Business.Dto; +using ZR.Model.Business; +using ZR.Repository; +using ZR.Service.Business.IBusinessService; + +namespace ZR.Service.Business +{ + /// + /// 礼品小程序Service业务层处理 + /// + [AppService(ServiceType = typeof(IGiftConfigService), ServiceLifetime = LifeTime.Transient)] + public class GiftConfigService : BaseService, IGiftConfigService + { + /// + /// 查询礼品小程序列表 + /// + /// + /// + public PagedInfo GetList(GiftConfigQueryDto parm) + { + var predicate = QueryExp(parm); + + var response = Queryable() + .Where(predicate.ToExpression()) + .ToPage(parm); + + return response; + } + + + /// + /// 获取详情 + /// + /// + /// + public GiftConfig GetInfo(int Id) + { + var response = Queryable() + .Where(x => x.Id == Id) + .First(); + + return response; + } + + /// + /// 添加礼品小程序 + /// + /// + /// + public GiftConfig AddGiftConfig(GiftConfig model) + { + return Insertable(model).ExecuteReturnEntity(); + } + + /// + /// 修改礼品小程序 + /// + /// + /// + public int UpdateGiftConfig(GiftConfig model) + { + return Update(model, true, "修改礼品小程序"); + } + + /// + /// 查询导出表达式 + /// + /// + /// + private static Expressionable QueryExp(GiftConfigQueryDto parm) + { + var predicate = Expressionable.Create(); + + return predicate; + } + } +} \ No newline at end of file diff --git a/ZR.Service/Business/GiftUserService.cs b/ZR.Service/Business/GiftUserService.cs new file mode 100644 index 0000000..e510496 --- /dev/null +++ b/ZR.Service/Business/GiftUserService.cs @@ -0,0 +1,104 @@ +using Infrastructure.Attribute; +using Infrastructure.Extensions; +using ZR.Model.Business.Dto; +using ZR.Model.Business; +using ZR.Repository; +using ZR.Service.Business.IBusinessService; + +namespace ZR.Service.Business +{ + /// + /// 微信用户表Service业务层处理 + /// + [AppService(ServiceType = typeof(IGiftUserService), ServiceLifetime = LifeTime.Transient)] + public class GiftUserService : BaseService, IGiftUserService + { + /// + /// 查询微信用户表列表 + /// + /// + /// + public PagedInfo GetList(GiftUserQueryDto parm) + { + var predicate = QueryExp(parm); + + var response = Queryable() + //.OrderBy("Id desc") + .Where(predicate.ToExpression()) + .ToPage(parm); + + return response; + } + + + /// + /// 获取详情 + /// + /// + /// + public GiftUser GetInfo(int Id) + { + var response = Queryable() + .Where(x => x.Id == Id) + .First(); + + return response; + } + + /// + /// 添加微信用户表 + /// + /// + /// + public GiftUser AddGiftUser(GiftUser model) + { + return Insertable(model).ExecuteReturnEntity(); + } + + /// + /// 修改微信用户表 + /// + /// + /// + public int UpdateGiftUser(GiftUser model) + { + return Update(model, true); + } + + /// + /// 导出微信用户表 + /// + /// + /// + public PagedInfo ExportList(GiftUserQueryDto parm) + { + parm.PageNum = 1; + parm.PageSize = 100000; + var predicate = QueryExp(parm); + + var response = Queryable() + .Where(predicate.ToExpression()) + .Select((it) => new GiftUserDto() + { + GenderLabel = it.Gender.GetConfigValue("sys_user_sex"), + StatusLabel = it.Status.GetConfigValue("sys_common_status"), + }, true) + .ToPage(parm); + + return response; + } + + /// + /// 查询导出表达式 + /// + /// + /// + private static Expressionable QueryExp(GiftUserQueryDto parm) + { + var predicate = Expressionable.Create(); + + predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.Nickname), it => it.Nickname.Contains(parm.Nickname)); + return predicate; + } + } +} \ No newline at end of file diff --git a/ZR.Service/Business/IBusinessService/IGiftClaimService.cs b/ZR.Service/Business/IBusinessService/IGiftClaimService.cs new file mode 100644 index 0000000..109ade5 --- /dev/null +++ b/ZR.Service/Business/IBusinessService/IGiftClaimService.cs @@ -0,0 +1,22 @@ +using ZR.Model.Business.Dto; +using ZR.Model.Business; + +namespace ZR.Service.Business.IBusinessService +{ + /// + /// 礼品申领表service接口 + /// + public interface IGiftClaimService : IBaseService + { + PagedInfo GetList(GiftClaimQueryDto parm); + + GiftClaim GetInfo(int Id); + + + GiftClaim AddGiftClaim(GiftClaim parm); + int UpdateGiftClaim(GiftClaim parm); + + + PagedInfo ExportList(GiftClaimQueryDto parm); + } +} diff --git a/ZR.Service/Business/IBusinessService/IGiftConfigService.cs b/ZR.Service/Business/IBusinessService/IGiftConfigService.cs new file mode 100644 index 0000000..21b2164 --- /dev/null +++ b/ZR.Service/Business/IBusinessService/IGiftConfigService.cs @@ -0,0 +1,21 @@ +using ZR.Model.Business.Dto; +using ZR.Model.Business; + +namespace ZR.Service.Business.IBusinessService +{ + /// + /// 礼品小程序service接口 + /// + public interface IGiftConfigService : IBaseService + { + PagedInfo GetList(GiftConfigQueryDto parm); + + GiftConfig GetInfo(int Id); + + + GiftConfig AddGiftConfig(GiftConfig parm); + int UpdateGiftConfig(GiftConfig parm); + + + } +} diff --git a/ZR.Service/Business/IBusinessService/IGiftUserService.cs b/ZR.Service/Business/IBusinessService/IGiftUserService.cs new file mode 100644 index 0000000..293243c --- /dev/null +++ b/ZR.Service/Business/IBusinessService/IGiftUserService.cs @@ -0,0 +1,22 @@ +using ZR.Model.Business.Dto; +using ZR.Model.Business; + +namespace ZR.Service.Business.IBusinessService +{ + /// + /// 微信用户表service接口 + /// + public interface IGiftUserService : IBaseService + { + PagedInfo GetList(GiftUserQueryDto parm); + + GiftUser GetInfo(int Id); + + + GiftUser AddGiftUser(GiftUser parm); + int UpdateGiftUser(GiftUser parm); + + + PagedInfo ExportList(GiftUserQueryDto parm); + } +} diff --git a/ZR.ServiceCore/Filters/GlobalActionMonitor.cs b/ZR.ServiceCore/Filters/GlobalActionMonitor.cs index aae4137..328bb9b 100644 --- a/ZR.ServiceCore/Filters/GlobalActionMonitor.cs +++ b/ZR.ServiceCore/Filters/GlobalActionMonitor.cs @@ -1,11 +1,15 @@ using Infrastructure; using Infrastructure.Attribute; using Infrastructure.Model; + using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Filters; + using NLog; + +using ZR.Infrastructure.Helper; using ZR.Infrastructure.IPTools; using ZR.Model.System; using ZR.ServiceCore.Services; @@ -111,11 +115,20 @@ namespace ZR.ServiceCore.Middleware sysOperLog.OperParam = logAttribute.IsSaveRequestData ? sysOperLog.OperParam : ""; sysOperLog.JsonResult = logAttribute.IsSaveResponseData ? sysOperLog.JsonResult : ""; } + if (statusCode == 403) { sysOperLog.Status = 1; sysOperLog.ErrorMsg = "无权限访问"; } + else + { + if (!string.IsNullOrEmpty(logAttribute.MessageKey)) + { + + sysOperLog.ErrorMsg = LogMessageRegistry.GetMessage(logAttribute.MessageKey, context); + } + } LogEventInfo ei = new(NLog.LogLevel.Info, "GlobalActionMonitor", ""); ei.Properties["jsonResult"] = !HttpMethods.IsGet(method) ? jsonResult : ""; diff --git a/ZR.ServiceCore/Middleware/GlobalExceptionMiddleware.cs b/ZR.ServiceCore/Middleware/GlobalExceptionMiddleware.cs index 5cf0d9a..8d9f4aa 100644 --- a/ZR.ServiceCore/Middleware/GlobalExceptionMiddleware.cs +++ b/ZR.ServiceCore/Middleware/GlobalExceptionMiddleware.cs @@ -79,7 +79,7 @@ namespace ZR.ServiceCore.Middleware var an1 = string.Empty; if (ex.Message.Contains(q1)) { - an1 = $"====请查看issue:https://gitee.com/izory/ZrAdminNetCore/issues/I6S4DZ"; + //an1 = $"====请查看issue:https://gitee.com/izory/ZrAdminNetCore/issues/I6S4DZ"; } msg = "服务器好像出了点问题,请联系系统管理员..."; error = $"异常原因:{ex.Message}{an1}"; diff --git a/ZR.ServiceCore/Middleware/JwtAuthMiddleware.cs b/ZR.ServiceCore/Middleware/JwtAuthMiddleware.cs index c89682f..79aeea4 100644 --- a/ZR.ServiceCore/Middleware/JwtAuthMiddleware.cs +++ b/ZR.ServiceCore/Middleware/JwtAuthMiddleware.cs @@ -37,6 +37,7 @@ namespace ZR.ServiceCore.Middleware await _next(context); return; } + if (_whitelistPaths.Any(p => path.StartsWith(p, StringComparison.OrdinalIgnoreCase))) { await _next(context); diff --git a/ZR.ServiceCore/Services/IService/ISysFileService.cs b/ZR.ServiceCore/Services/IService/ISysFileService.cs index 8d75128..5f37c99 100644 --- a/ZR.ServiceCore/Services/IService/ISysFileService.cs +++ b/ZR.ServiceCore/Services/IService/ISysFileService.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Http; + using ZR.Model.Dto; using ZR.Model.System; @@ -17,7 +18,18 @@ namespace ZR.ServiceCore.Services /// /// 文件对象 Task SaveFileToLocal(string rootPath, UploadDto dto, string userName, IFormFile formFile); - + + /// + /// + /// + /// + /// + /// + /// + /// + /// + Task SaveFileToLocal(string rootPath, UploadDto dto, string userName, string fileName, byte[] fileByte); + /// /// 上传文件到阿里云 /// @@ -26,7 +38,16 @@ namespace ZR.ServiceCore.Services /// /// Task SaveFileToAliyun(SysFile file, UploadDto dto, IFormFile formFile); - + + /// + /// 上传文件到阿里云 + /// + /// + /// + /// + /// + Task SaveFileToAliyun(SysFile sysFile, UploadDto dto, byte[] file); + /// /// 按时间来创建文件夹 /// diff --git a/ZR.ServiceCore/Services/SysFileService.cs b/ZR.ServiceCore/Services/SysFileService.cs index d0965fb..727a419 100644 --- a/ZR.ServiceCore/Services/SysFileService.cs +++ b/ZR.ServiceCore/Services/SysFileService.cs @@ -2,13 +2,17 @@ using Infrastructure.Attribute; using Infrastructure.Enums; using Infrastructure.Model; + using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; + using SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats.Jpeg; + using System.Net; using System.Security.Cryptography; using System.Text; + using ZR.Common; using ZR.Model.Dto; using ZR.Model.System; @@ -210,5 +214,50 @@ namespace ZR.ServiceCore.Services // 保存压缩后的图片到输出流 await image.SaveAsync(outputStream, encoder); } + + public async Task SaveFileToLocal(string rootPath, UploadDto dto, string userName, string fileName, byte[] fileByte) + { + var fileDir = dto.FileDir; + string fileExt = Path.GetExtension(fileName); + fileName = (fileName.IsEmpty() ? HashFileName() : fileName) + fileExt; + + string filePath = GetdirPath(fileDir); + string finalFilePath = Path.Combine(rootPath, filePath, fileName); + double fileSize = Math.Round(fileByte.Length / 1024.0, 2); + + if (!Directory.Exists(Path.GetDirectoryName(finalFilePath))) + { + Directory.CreateDirectory(Path.GetDirectoryName(finalFilePath)); + } + // 常见的图片扩展名 + //var imageExtensions = new[] { ".jpg", ".jpeg", ".png", ".gif", ".bmp" }; + + // 检查扩展名是否在图片扩展名列表中 + //bool isImageByExtension = imageExtensions.Contains(fileExt); + using (var stream = new FileStream(finalFilePath, FileMode.Create)) + { + await stream.WriteAsync(fileByte, 0, fileByte.Length); + } + string uploadUrl = OptionsSetting.Upload.UploadUrl; + string accessPath = string.Concat(filePath.Replace("\\", "/"), "/", fileName); + Uri baseUri = new(uploadUrl); + Uri fullUrl = new(baseUri, accessPath); + SysFile file = new(fileName, fileName, fileExt, fileSize + "kb", filePath, userName) + { + StoreType = (int)StoreType.LOCAL, + FileType = fileExt, + FileUrl = finalFilePath.Replace("\\", "/"), + AccessUrl = fullUrl.AbsoluteUri, + ClassifyType = "", + CategoryId = dto.CategoryId, + }; + file.Id = await InsertFile(file); + return file; + } + + public async Task SaveFileToAliyun(SysFile sysFile, UploadDto dto, byte[] file) + { + throw new NotImplementedException(); + } } }