Compare commits

...

20 Commits

Author SHA1 Message Date
zpc
8081be4f2d 32321 2025-09-12 20:22:39 +08:00
zpc
830732aeeb 333 2025-09-10 19:27:25 +08:00
zpc
b0d2592ddb 333 2025-08-26 13:18:36 +08:00
zpc
be90a309dd 3333 2025-08-21 19:48:25 +08:00
zpc
d5018a36ba 333 2025-08-21 16:27:30 +08:00
zpc
913ce41ca5 33 2025-08-21 13:08:05 +08:00
zpc
5c282a5fef 33 2025-08-21 13:08:02 +08:00
zpc
87897f5126 333 2025-08-20 00:59:04 +08:00
zpc
82a7d3e6aa 333 2025-08-20 00:31:01 +08:00
zpc
113989577d 提交 2025-08-19 23:49:57 +08:00
zpc
7a20e2f53e 333 2025-08-18 23:37:08 +08:00
zpc
7f0cd141a5 333 2025-08-18 22:36:31 +08:00
zpc
6df1269fcd 333 2025-08-18 22:34:48 +08:00
zpc
2aae829a16 333 2025-08-18 22:32:56 +08:00
zpc
34d377bb65 测试 2025-08-18 19:25:41 +08:00
zpc
eaa5f3f610 333 2025-08-18 16:04:03 +08:00
zpc
0d094db7d3 提交 2025-08-18 15:43:05 +08:00
zpc
7e88d4620e 333 2025-08-18 15:37:30 +08:00
zpc
15469c5164 新增腾讯地图 2025-08-18 12:58:01 +08:00
zpc
eed70324fd 初始项目 2025-08-18 12:02:43 +08:00
45 changed files with 2307 additions and 1443 deletions

1
.gitignore vendored
View File

@ -272,3 +272,4 @@ __pycache__/
/Quartz.NET.WindowsService
/ZRAdmin-vue
/ZR.Admin.WebApi/ZRModel.xml
/ZR.Admin.WebApi/wwwroot/workfiles

View File

@ -0,0 +1,78 @@
using Microsoft.AspNetCore.Hosting;
using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ZR.Infrastructure.Helper
{
/// <summary>
/// Excel 导出帮助类EPPlus
/// </summary>
public class ExcelHelper
{
private readonly IWebHostEnvironment _webHostEnvironment;
/// <summary>
/// 构造函数,需要注入 IWebHostEnvironment 获取 web 根目录
/// </summary>
/// <param name="webHostEnvironment"></param>
public ExcelHelper(IWebHostEnvironment webHostEnvironment)
{
_webHostEnvironment = webHostEnvironment;
ExcelPackage.License.SetNonCommercialPersonal("pnaa");
}
/// <summary>
/// 导出 Excel 文件
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="list">数据列表</param>
/// <param name="sheetName">Sheet 名</param>
/// <param name="fileName">文件名,不含时间戳和后缀</param>
/// <returns>返回文件名和完整路径</returns>
public (string, string) ExportExcel<T>(List<T> list, string sheetName, string fileName)
{
// 生成带时间戳的文件名
string sFileName = $"{fileName}_{DateTime.Now:MMdd_HHmmss}.xlsx";
string fullPath = Path.Combine(_webHostEnvironment.WebRootPath, "export", sFileName);
// 创建目录
Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
using (var package = new ExcelPackage())
{
// 添加 Sheet
var worksheet = package.Workbook.Worksheets.Add(sheetName ?? "Sheet1");
// 将 List<T> 导入到 Sheet
worksheet.Cells["A2"].LoadFromCollection(list, false); // true 表示包含表头
// 插入图片
var pic = worksheet.Drawings.AddPicture("Logo", new FileInfo("D:\\CodeManage\\Zr.Admin.NET\\ZR.Admin.WebApi\\wwwroot\\workfiles\\2025\\20250818\\当日照片\\1755531044_7059.jpg"));
// 设置图片位置
pic.SetPosition(4, 0, 4, 0); // 行, 行偏移, 列, 列偏移
pic.SetSize(100, 50); // 宽高像素
// 自动调整列宽
worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();
// 保存文件
package.SaveAs(new FileInfo(fullPath));
}
return (sFileName, fullPath);
}
}
}

View File

@ -12,6 +12,7 @@
<ItemGroup>
<PackageReference Include="AspectCore.Abstractions" Version="2.4.0" />
<PackageReference Include="EPPlus" Version="8.1.0" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="8.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="UAParser" Version="3.1.47" />

View File

@ -0,0 +1,100 @@
using Microsoft.AspNetCore.Mvc;
using ZR.Model.Business.Dto;
using ZR.Model.Business;
using ZR.Service.Business.IBusinessService;
//创建时间2025-08-18
namespace ZR.Admin.WebApi.Controllers.Business
{
/// <summary>
/// 工作人员记录
/// </summary>
[Route("business/CamWorker")]
public class CamWorkerController : BaseController
{
/// <summary>
/// 工作人员记录接口
/// </summary>
private readonly ICamWorkerService _CamWorkerService;
public CamWorkerController(ICamWorkerService CamWorkerService)
{
_CamWorkerService = CamWorkerService;
}
/// <summary>
/// 查询工作人员记录列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
[HttpGet("list")]
[ActionPermissionFilter(Permission = "camworker:list")]
public IActionResult QueryCamWorker([FromQuery] CamWorkerQueryDto parm)
{
var response = _CamWorkerService.GetList(parm);
return SUCCESS(response);
}
/// <summary>
/// 查询工作人员记录详情
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
[HttpGet("{Id}")]
[ActionPermissionFilter(Permission = "camworker:query")]
public IActionResult GetCamWorker(long Id)
{
var response = _CamWorkerService.GetInfo(Id);
var info = response.Adapt<CamWorkerDto>();
return SUCCESS(info);
}
/// <summary>
/// 添加工作人员记录
/// </summary>
/// <returns></returns>
[HttpPost]
[ActionPermissionFilter(Permission = "camworker:add")]
[Log(Title = "工作人员记录", BusinessType = BusinessType.INSERT)]
public IActionResult AddCamWorker([FromBody] CamWorkerDto parm)
{
var modal = parm.Adapt<CamWorker>().ToCreate(HttpContext);
var response = _CamWorkerService.AddCamWorker(modal);
return SUCCESS(response);
}
/// <summary>
/// 更新工作人员记录
/// </summary>
/// <returns></returns>
[HttpPut]
[ActionPermissionFilter(Permission = "camworker:edit")]
[Log(Title = "工作人员记录", BusinessType = BusinessType.UPDATE)]
public IActionResult UpdateCamWorker([FromBody] CamWorkerDto parm)
{
var modal = parm.Adapt<CamWorker>().ToUpdate(HttpContext);
var response = _CamWorkerService.UpdateCamWorker(modal);
return ToResponse(response);
}
/// <summary>
/// 删除工作人员记录
/// </summary>
/// <returns></returns>
[HttpPost("delete/{ids}")]
[ActionPermissionFilter(Permission = "camworker:delete")]
[Log(Title = "工作人员记录", BusinessType = BusinessType.DELETE)]
public IActionResult DeleteCamWorker([FromRoute]string ids)
{
var idArr = Tools.SplitAndConvert<long>(ids);
return ToResponse(_CamWorkerService.Delete(idArr));
}
}
}

View File

@ -0,0 +1,73 @@
using Microsoft.AspNetCore.Mvc;
using ZR.Model.Business.Dto;
using ZR.Model.Business;
using ZR.Service.Business.IBusinessService;
//创建时间2025-08-19
namespace ZR.Admin.WebApi.Controllers.Business
{
/// <summary>
/// 月报表
/// </summary>
[Route("business/CamWorkers")]
public class CamWorkersController : BaseController
{
/// <summary>
/// 月报表接口
/// </summary>
private readonly ICamWorkersService _CamWorkersService;
public CamWorkersController(ICamWorkersService CamWorkersService)
{
_CamWorkersService = CamWorkersService;
}
/// <summary>
/// 查询月报表列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
[HttpGet("list")]
[ActionPermissionFilter(Permission = "camworkers:list")]
public IActionResult QueryCamWorkers([FromQuery] CamWorkersQueryDto parm)
{
var response = _CamWorkersService.GetList(parm);
return SUCCESS(response);
}
/// <summary>
/// 查询月报表详情
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
[HttpGet("{Id}")]
[ActionPermissionFilter(Permission = "camworkers:query")]
public IActionResult GetCamWorkers(long Id)
{
var response = _CamWorkersService.GetInfo(Id);
var info = response.Adapt<CamWorkersDto>();
return SUCCESS(info);
}
/// <summary>
/// 导出月报表
/// </summary>
/// <returns></returns>
[Log(Title = "月报表", BusinessType = BusinessType.EXPORT, IsSaveResponseData = false)]
[HttpGet("export")]
[ActionPermissionFilter(Permission = "camworkers:export")]
public IActionResult Export([FromQuery] CamWorkersQueryDto parm)
{
var list = _CamWorkersService.ExportList(parm);
if (list == null || list.Count <= 0)
{
return ToResponse(ResultCode.FAIL, "没有要导出的数据");
}
var result = ExportExcelMini(list, "月报表", "月报表");
return ExportExcel(result.Item2, result.Item1);
}
}
}

View File

@ -0,0 +1,272 @@
using Microsoft.AspNetCore.Mvc;
using ZR.Model.Business.Dto;
using ZR.Model.Business;
using ZR.Service.Business.IBusinessService;
using MiniExcelLibs.Picture;
using SKIT.FlurlHttpClient.Wechat.Api.Models;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Hosting;
using MiniExcelLibs;
using System.IO;
using IOFile = System.IO.File;
using Org.BouncyCastle.Utilities;
using Microsoft.Extensions.Configuration.UserSecrets;
using MiniExcelLibs.OpenXml;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg;
using ZR.Infrastructure.Helper;
using OfficeOpenXml;
using OfficeOpenXml.Drawing;
//创建时间2025-08-18
namespace ZR.Admin.WebApi.Controllers.Business
{
/// <summary>
/// 工作记录
/// </summary>
[Route("business/CamWorkrecord")]
public class CamWorkrecordController : BaseController
{
/// <summary>
/// 工作记录接口
/// </summary>
private readonly ICamWorkrecordService _CamWorkrecordService;
private OptionsSetting OptionsSetting;
private IWebHostEnvironment WebHostEnvironment;
private readonly ICamWorkerService _CamWorkerService;
public CamWorkrecordController(ICamWorkrecordService CamWorkrecordService, IOptions<OptionsSetting> options, IWebHostEnvironment webHostEnvironment,
ICamWorkerService camWorkerService)
{
_CamWorkrecordService = CamWorkrecordService;
OptionsSetting = options.Value;
WebHostEnvironment = webHostEnvironment;
_CamWorkerService = camWorkerService;
}
/// <summary>
/// 查询工作记录列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
[HttpGet("list")]
[ActionPermissionFilter(Permission = "camworkrecord:list")]
public IActionResult QueryCamWorkrecord([FromQuery] CamWorkrecordQueryDto parm)
{
var response = _CamWorkrecordService.GetList(parm);
return SUCCESS(response);
}
/// <summary>
/// 查询工作记录详情
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
[HttpGet("{Id}")]
[ActionPermissionFilter(Permission = "camworkrecord:query")]
public IActionResult GetCamWorkrecord(int Id)
{
var response = _CamWorkrecordService.GetInfo(Id);
var info = response.Adapt<CamWorkrecordDto>();
if (info != null)
{
var names = _CamWorkerService.AsQueryable().Where(it => it.WorkrecordId == info.Id).Select(it => it.WorkerName).ToList();
info.Worker = names != null && names.Count > 0 ? string.Join(",", names) : "";
}
return SUCCESS(info);
}
/// <summary>
/// 添加工作记录
/// </summary>
/// <returns></returns>
[HttpPost]
[ActionPermissionFilter(Permission = "camworkrecord:add")]
[Log(Title = "工作记录", BusinessType = BusinessType.INSERT)]
public IActionResult AddCamWorkrecord([FromBody] CamWorkrecordDto parm)
{
var modal = parm.Adapt<CamWorkrecord>().ToCreate(HttpContext);
modal.CreateTime = DateTime.Now;
modal.UpdateTime = DateTime.Now;
var response = _CamWorkrecordService.AddCamWorkrecord(modal);
return SUCCESS(response);
}
/// <summary>
/// 更新工作记录
/// </summary>
/// <returns></returns>
[HttpPut]
[ActionPermissionFilter(Permission = "camworkrecord:edit")]
[Log(Title = "工作记录", BusinessType = BusinessType.UPDATE)]
public IActionResult UpdateCamWorkrecord([FromBody] CamWorkrecordDto parm)
{
var modal = parm.Adapt<CamWorkrecord>().ToUpdate(HttpContext);
modal.UpdateTime = DateTime.Now;
var response = _CamWorkrecordService.UpdateCamWorkrecord(modal);
return ToResponse(response);
}
/// <summary>
/// 删除工作记录
/// </summary>
/// <returns></returns>
[HttpPost("delete/{ids}")]
[ActionPermissionFilter(Permission = "camworkrecord:delete")]
[Log(Title = "工作记录", BusinessType = BusinessType.DELETE)]
public IActionResult DeleteCamWorkrecord([FromRoute] string ids)
{
var idArr = Tools.SplitAndConvert<int>(ids);
return ToResponse(_CamWorkrecordService.Delete(idArr, "删除工作记录"));
}
/// <summary>
/// 导出工作记录
/// </summary>
/// <returns></returns>
[Log(Title = "工作记录", BusinessType = BusinessType.EXPORT, IsSaveResponseData = false)]
[HttpGet("export")]
[ActionPermissionFilter(Permission = "camworkrecord:export")]
public IActionResult Export([FromQuery] CamWorkrecordQueryDto parm)
{
var list = _CamWorkrecordService.ExportList(parm).Result;
if (list == null || list.Count <= 0)
{
return ToResponse(ResultCode.FAIL, "没有要导出的数据");
}
var url = OptionsSetting.Upload.UploadUrl;
string savePath = Path.Combine(WebHostEnvironment.WebRootPath);
int i = 1;
list.ForEach(it =>
{
var temp = string.IsNullOrEmpty(it.ImageUrl) ? "" : it.ImageUrl;
if (temp.IndexOf("http") > -1)
{
var image = temp.Replace(url, "");
temp = savePath + image;
}
it.Index = i;
it.ImageUrl = temp;
//it.Image = CompressImage(temp, 50);
i++;
});
ExcelHelper excelHelper = new ExcelHelper(WebHostEnvironment);
ExcelPackage.License.SetNonCommercialPersonal("pnaa");
var result = ExportWorkRecordExcel(list, "工作记录", 200, 70, 60);
//ExportExcelMini(list, "工作记录", "工作记录");
//ExportExcelWithImagesInBatches(result.Item2, "工作记录", urlList, 10);
//loadExcel();
return ExportExcel(result.Item2, result.Item1);
}
/// <summary>
public (string fileName, string fullPath) ExportWorkRecordExcel(List<CamWorkrecordExcelDto> list, string fileName, int imageWidth = 100, int imageHeight = 60, int imageQuality = 50)
{
IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment));
string sFileName = $"{fileName}_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx";
string fullPath = Path.Combine(webHostEnvironment.WebRootPath, "export", sFileName);
Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
using var package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("工作记录");
// 写表头
var headers = new[]
{
"序号","部门名称","拍照时间","经度","纬度","位置","工作内容","施工人员","状态","施工图片","创建时间","更新时间"
};
for (int i = 0; i < headers.Length; i++)
{
ws.Cells[1, i + 1].Value = headers[i];
ws.Cells[1, i + 1].Style.Font.Bold = true;
//ws.Column(i).Width = 120;
}
//ws.Column(10).Width = 40;
int row = 2;
foreach (var item in list)
{
ws.Cells[row, 1].Value = item.Index;
ws.Cells[row, 2].Value = item.DeptName;
ws.Cells[row, 3].Value = item.RecordTime?.ToString("yyyy-MM-dd HH:mm:ss");
ws.Cells[row, 4].Value = item.Longitude;
ws.Cells[row, 5].Value = item.Latitude;
ws.Cells[row, 6].Value = item.Address;
ws.Cells[row, 7].Value = item.Content;
ws.Cells[row, 8].Value = item.Worker;
ws.Cells[row, 9].Value = item.StatusName;
ws.Cells[row, 11].Value = item.CreateTime?.ToString("yyyy-MM-dd HH:mm:ss");
ws.Cells[row, 12].Value = item.UpdateTime?.ToString("yyyy-MM-dd HH:mm:ss");
// 如果 ImageUrl 有值,则压缩后插入 Excel
if (!string.IsNullOrEmpty(item.ImageUrl) && IOFile.Exists(item.ImageUrl))
{
using var image = SixLabors.ImageSharp.Image.Load(item.ImageUrl);
var encoder = new JpegEncoder { Quality = imageQuality };
using var ms = new MemoryStream();
image.Save(ms, encoder);
ms.Position = 0;
var pic = ws.Drawings.AddPicture($"Pic_{row}_10", ms);
pic.SetPosition(row - 1, 5, 9, 5); // 第10列
pic.SetSize(imageWidth, imageHeight);
}
ws.Row(row).Height = imageHeight;
row++;
}
ws.Cells[ws.Dimension.Address].AutoFitColumns();
ws.Cells[ws.Dimension.Address].Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
ws.Column(10).Width = 40;
package.SaveAs(new FileInfo(fullPath));
return (sFileName, fullPath);
}
public byte[] CompressImage(string imagePath, int quality)
{
// 使用 using 语句确保资源被释放
using (var image = Image.Load(imagePath))
{
var encoder = new JpegEncoder { Quality = quality };
using (var outputStream = new MemoryStream())
{
image.Save(outputStream, encoder);
return outputStream.ToArray();
}
}
}
/// <summary>
/// 根据图片文件扩展名映射为 ContentType避免类型不匹配导致 Excel 修复。
/// </summary>
private static string GetContentTypeByExtension(string filePath)
{
var ext = Path.GetExtension(filePath)?.ToLowerInvariant();
return ext switch
{
".png" => "image/png",
".jpg" => "image/jpeg",
".jpeg" => "image/jpeg",
".gif" => "image/gif",
".bmp" => "image/bmp",
".webp" => "image/webp", // 只有新版本 Excel 兼容,谨慎使用
_ => "image/png" // 默认按 png 处理
};
}
}
}

View File

@ -1,154 +0,0 @@
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
{
/// <summary>
/// 礼品申领表
/// </summary>
[Route("business/GiftClaim")]
public class GiftClaimController : BaseController
{
/// <summary>
/// 礼品申领表接口
/// </summary>
private readonly IGiftClaimService _GiftClaimService;
public GiftClaimController(IGiftClaimService GiftClaimService)
{
_GiftClaimService = GiftClaimService;
}
/// <summary>
/// 查询礼品申领表列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
[HttpGet("list")]
[ActionPermissionFilter(Permission = "giftclaim:list")]
public IActionResult QueryGiftClaim([FromQuery] GiftClaimQueryDto parm)
{
var response = _GiftClaimService.GetList(parm);
return SUCCESS(response);
}
/// <summary>
/// 查询礼品申领表列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
[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 });
}
/// <summary>
/// 查询礼品申领表详情
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
[HttpGet("{Id}")]
[ActionPermissionFilter(Permission = "giftclaim:query")]
public IActionResult GetGiftClaim(int Id)
{
var response = _GiftClaimService.GetInfo(Id);
var info = response.Adapt<GiftClaimDto>();
return SUCCESS(info);
}
/// <summary>
/// 添加礼品申领表
/// </summary>
/// <returns></returns>
[HttpPost]
[ActionPermissionFilter(Permission = "giftclaim:add")]
[Log(Title = "礼品申领记录", BusinessType = BusinessType.INSERT)]
public IActionResult AddGiftClaim([FromBody] GiftClaimDto parm)
{
var modal = parm.Adapt<GiftClaim>().ToCreate(HttpContext);
var response = _GiftClaimService.AddGiftClaim(modal);
return SUCCESS(response);
}
/// <summary>
/// 更新礼品申领表
/// </summary>
/// <returns></returns>
[HttpPut]
[ActionPermissionFilter(Permission = "giftclaim:edit")]
[Log(Title = "礼品申领记录", BusinessType = BusinessType.UPDATE)]
public IActionResult UpdateGiftClaim([FromBody] GiftClaimDto parm)
{
var modal = parm.Adapt<GiftClaim>().ToUpdate(HttpContext);
var response = _GiftClaimService.UpdateGiftClaim(modal);
return ToResponse(response);
}
/// <summary>
/// 更新礼品申领表
/// </summary>
/// <returns></returns>
[HttpPost("editStatus")]
[ActionPermissionFilter(Permission = "giftclaim:editStatus")]
[Log(Title = "礼品申领记录", BusinessType = BusinessType.UPDATE, MessageKey = "giftclaim:status")]
public async Task<IActionResult> 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, ""));
}
/// <summary>
/// 删除礼品申领表
/// </summary>
/// <returns></returns>
[HttpPost("delete/{ids}")]
[ActionPermissionFilter(Permission = "giftclaim:delete")]
[Log(Title = "礼品申领表", BusinessType = BusinessType.DELETE)]
public IActionResult DeleteGiftClaim([FromRoute] string ids)
{
var idArr = Tools.SplitAndConvert<int>(ids);
return ToResponse(_GiftClaimService.Delete(idArr));
}
/// <summary>
/// 导出礼品申领表
/// </summary>
/// <returns></returns>
[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);
}
}
}

View File

@ -1,116 +0,0 @@
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
{
/// <summary>
/// 礼品小程序
/// </summary>
[Route("business/GiftConfig")]
public class GiftConfigController : BaseController
{
/// <summary>
/// 礼品小程序接口
/// </summary>
private readonly IGiftConfigService _GiftConfigService;
public GiftConfigController(IGiftConfigService GiftConfigService)
{
_GiftConfigService = GiftConfigService;
}
/// <summary>
/// 查询礼品小程序列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
[HttpGet("list")]
[ActionPermissionFilter(Permission = "giftconfig:list")]
public IActionResult QueryGiftConfig([FromQuery] GiftConfigQueryDto parm)
{
var response = _GiftConfigService.GetList(parm);
return SUCCESS(response);
}
/// <summary>
/// 查询礼品小程序详情
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
[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<GiftConfigDto>();
}
else
{
var tt = _GiftConfigService.AddGiftConfig(new GiftConfig()
{
HomeImage = "",
Extend = "",
Extend1 = "",
});
info = tt.Adapt<GiftConfigDto>();
}
return SUCCESS(info);
}
/// <summary>
/// 添加礼品小程序
/// </summary>
/// <returns></returns>
[HttpPost]
[ActionPermissionFilter(Permission = "giftconfig:add")]
[Log(Title = "礼品小程序", BusinessType = BusinessType.INSERT)]
public IActionResult AddGiftConfig([FromBody] GiftConfigDto parm)
{
var modal = parm.Adapt<GiftConfig>().ToCreate(HttpContext);
var response = _GiftConfigService.AddGiftConfig(modal);
return SUCCESS(response);
}
/// <summary>
/// 更新礼品小程序
/// </summary>
/// <returns></returns>
[HttpPut]
[ActionPermissionFilter(Permission = "giftconfig:edit")]
[Log(Title = "礼品小程序", BusinessType = BusinessType.UPDATE)]
public IActionResult UpdateGiftConfig([FromBody] GiftConfigDto parm)
{
var modal = parm.Adapt<GiftConfig>().ToUpdate(HttpContext);
var response = _GiftConfigService.UpdateGiftConfig(modal);
return ToResponse(response);
}
/// <summary>
/// 删除礼品小程序
/// </summary>
/// <returns></returns>
[HttpPost("delete/{ids}")]
[ActionPermissionFilter(Permission = "giftconfig:delete")]
[Log(Title = "礼品小程序", BusinessType = BusinessType.DELETE)]
public IActionResult DeleteGiftConfig([FromRoute] string ids)
{
var idArr = Tools.SplitAndConvert<int>(ids);
return ToResponse(_GiftConfigService.Delete(idArr, "删除礼品小程序"));
}
}
}

View File

@ -1,121 +0,0 @@
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
{
/// <summary>
/// 微信用户表
/// </summary>
[Route("business/GiftUser")]
public class GiftUserController : BaseController
{
/// <summary>
/// 微信用户表接口
/// </summary>
private readonly IGiftUserService _GiftUserService;
public GiftUserController(IGiftUserService GiftUserService)
{
_GiftUserService = GiftUserService;
}
/// <summary>
/// 查询微信用户表列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
[HttpGet("list")]
[ActionPermissionFilter(Permission = "giftuser:list")]
public IActionResult QueryGiftUser([FromQuery] GiftUserQueryDto parm)
{
var response = _GiftUserService.GetList(parm);
return SUCCESS(response);
}
/// <summary>
/// 查询微信用户表详情
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
[HttpGet("{Id}")]
[ActionPermissionFilter(Permission = "giftuser:query")]
public IActionResult GetGiftUser(int Id)
{
var response = _GiftUserService.GetInfo(Id);
var info = response.Adapt<GiftUserDto>();
return SUCCESS(info);
}
/// <summary>
/// 添加微信用户表
/// </summary>
/// <returns></returns>
[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<GiftUser>().ToCreate(HttpContext);
var response = _GiftUserService.AddGiftUser(modal);
return SUCCESS(response);
}
/// <summary>
/// 更新微信用户表
/// </summary>
/// <returns></returns>
[HttpPut]
[ActionPermissionFilter(Permission = "giftuser:edit")]
[Log(Title = "微信用户表", BusinessType = BusinessType.UPDATE)]
public IActionResult UpdateGiftUser([FromBody] GiftUserDto parm)
{
parm.UpdateTime = DateTime.Now;
var modal = parm.Adapt<GiftUser>().ToUpdate(HttpContext);
var response = _GiftUserService.UpdateGiftUser(modal);
return ToResponse(response);
}
/// <summary>
/// 删除微信用户表
/// </summary>
/// <returns></returns>
[HttpPost("delete/{ids}")]
[ActionPermissionFilter(Permission = "giftuser:delete")]
[Log(Title = "微信用户表", BusinessType = BusinessType.DELETE)]
public IActionResult DeleteGiftUser([FromRoute]string ids)
{
var idArr = Tools.SplitAndConvert<int>(ids);
return ToResponse(_GiftUserService.Delete(idArr));
}
/// <summary>
/// 导出微信用户表
/// </summary>
/// <returns></returns>
[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);
}
}
}

View File

@ -5,11 +5,21 @@ using Microsoft.Extensions.Options;
using MiniExcelLibs;
using ZR.Infrastructure.IPTools;
using ZR.Model.Business.Dto;
using ZR.Model.Business;
using ZR.Model.Dto;
using ZR.Model.System;
using ZR.Service.Business.IBusinessService;
using ZR.ServiceCore.Resources;
using ZR.ServiceCore.Resources;
using ZR.Service.Business.IBusinessService;
using ZR.Service.Business;
using System.Threading.Tasks;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.CgibinExpressIntracityUpdateStoreRequest.Types;
using Aliyun.OSS.Model;
using System.IO.Compression;
using IOFile = System.IO.File;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp;
namespace ZR.Admin.WebApi.Controllers
{
/// <summary>
@ -25,29 +35,44 @@ namespace ZR.Admin.WebApi.Controllers
private IWebHostEnvironment WebHostEnvironment;
private ISysFileService SysFileService;
private readonly IStringLocalizer<SharedResource> _localizer;
public readonly ISysDeptService _deptService;
public readonly ISysDictDataService sysDictDataService;
/// <summary>
/// 礼品小程序接口
/// 工作记录接口
/// </summary>
private readonly IGiftConfigService _GiftConfigService;
private readonly ICamWorkrecordService _CamWorkrecordService;
/// <summary>
///
/// 工作人员记录接口
/// </summary>
private readonly ICamWorkerService _CamWorkerService;
/// <summary>
/// CommonController 构造函数
/// </summary>
/// <param name="stringLocalizer"></param>
/// <param name="options"></param>
/// <param name="webHostEnvironment"></param>
/// <param name="fileService"></param>
/// <param name="deptService"></param>
public CommonController(
IStringLocalizer<SharedResource> stringLocalizer,
IOptions<OptionsSetting> options,
IWebHostEnvironment webHostEnvironment,
ISysFileService fileService,
IGiftConfigService GiftConfigService)
ISysDeptService deptService,
ISysDictDataService sysDictDataService,
ICamWorkrecordService _CamWorkrecordService,
ICamWorkerService camWorkerService)
{
WebHostEnvironment = webHostEnvironment;
SysFileService = fileService;
OptionsSetting = options.Value;
_localizer = stringLocalizer;
_GiftConfigService = GiftConfigService;
_deptService = deptService;
this.sysDictDataService = sysDictDataService;
this._CamWorkrecordService = _CamWorkrecordService;
_CamWorkerService = camWorkerService;
}
/// <summary>
@ -60,21 +85,10 @@ namespace ZR.Admin.WebApi.Controllers
public IActionResult Index()
{
var hello = _localizer["hello"].Value;
return Ok($"请求成功!=>" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
return Ok($"请求成功!=>" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")+"==>camera");
}
/// <summary>
/// home
/// </summary>
/// <returns></returns>
[Route("/config")]
[HttpGet]
[AllowAnonymous]
public async Task<object> GetConfig()
{
var response = _GiftConfigService.GetFirst(it => true);
return new { home = (response?.HomeImage ?? ""), response.Extend, response.Extend1 };
}
/// <summary>
/// 查询IP信息
@ -118,7 +132,7 @@ namespace ZR.Admin.WebApi.Controllers
/// <returns></returns>
[HttpPost]
[ActionPermissionFilter(Permission = "common")]
public async Task<IActionResult> UploadFile([FromForm] UploadDto uploadDto, IFormFile file, StoreType storeType = StoreType.ALIYUN)
public async Task<IActionResult> UploadFile([FromForm] UploadDto uploadDto, IFormFile file, StoreType storeType = StoreType.LOCAL)
{
if (file == null) throw new CustomException(ResultCode.PARAM_ERROR, "上传文件不能为空");
SysFile sysfile = new();
@ -216,5 +230,516 @@ namespace ZR.Admin.WebApi.Controllers
string fileName = Path.GetFileName(fullPath);
return DownFile(fullPath, fileName);
}
/// <summary>
/// home
/// </summary>
/// <returns></returns>
[Route("/config")]
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> GetConfig()
{
var file = await SysFileService.AsQueryable().Where(x => x.ClassifyType == "watermark").FirstAsync();
var topDept = await _deptService.AsQueryable().Where(it => it.ParentId == 0 && it.DelFlag == 0 && it.Status == 0).FirstAsync();
List<string> deptList = new List<string>();
if (topDept != null)
{
var children = await _deptService.AsQueryable().Where(it => it.ParentId == topDept.DeptId && it.DelFlag == 0 && it.Status == 0).Select(it => it.DeptName).ToListAsync();
deptList = children;
}
var list = await sysDictDataService.AsQueryable().Where(it => it.DictType == "sys_construction_status" && it.Status == "0").Select(it => it.DictValue).ToListAsync();
return SUCCESS(new { logo = file?.AccessUrl ?? "", deptList, construction = list });
}
/// <summary>
/// 添加工作记录
/// </summary>
/// <returns></returns>
[HttpPost]
[Route("/addworkrecord")]
[AllowAnonymous]
public async Task<IActionResult> AddCamWorkRecord([FromBody] CamRecordWorkDto parm)
{
if (parm.Workers == null || parm.Workers.Count == 0)
{
return ToResponse(ResultCode.PARAM_ERROR, "请选择工作人员");
}
if (string.IsNullOrEmpty(parm.Image) && !string.IsNullOrEmpty(parm.ImageUrl))
{
return ToResponse(ResultCode.PARAM_ERROR, "请上传图片");
}
//-当日所有照片
//- 当日根据【人名】分类的照片
//- 当日根据【工作内容】分类的照片
//- 当日根据【部门】分类的照片
var imageprx = ImageConverter.GetFileExtensionFromBase64(parm.Image);
var filePath = "/workfiles/" + parm.RecordTime?.ToString("yyyyMM/yyyyMMdd");
string savePath = Path.Combine(WebHostEnvironment.WebRootPath);
var path = savePath + filePath;
var images = ImageConverter.Base64ToImageBytes(parm.Image);
if (images.Length == 0)
{
return ToResponse(ResultCode.CUSTOM_ERROR, "图片上传失败");
}
if (parm.Id != null && parm.Id > 0)
{
if (parm.ImageUrl.IndexOf("http") == -1)
{
//删除之前的人员照片
var m = await _CamWorkrecordService.AsQueryable().Where(it => it.Id == parm.Id).FirstAsync();
var m_workers = await _CamWorkerService.AsQueryable().Where(it => it.WorkrecordId == parm.Id).ToListAsync();
if (m == null)
{
return ToResponse(ResultCode.PARAM_ERROR, "未找到该记录");
}
if (!string.IsNullOrEmpty(m.ImageUrl))
{
//m.ImageUrl http://localhost:8888/workfiles/202508/20250819/当日照片/1755617080_7078.jpg
var imagePath = m.ImageUrl.Substring(m.ImageUrl.IndexOf("workfiles"));
var fullImagePath = Path.Combine(WebHostEnvironment.WebRootPath, imagePath);
// 获取文件名
var fileName = Path.GetFileName(fullImagePath);
var directoryPath = Path.GetDirectoryName(fullImagePath);
// 删除当日照片
if (IOFile.Exists(fullImagePath))
{
IOFile.Delete(fullImagePath);
}
// 删除参与人员照片
var participantsPath = Path.Combine(WebHostEnvironment.WebRootPath, "workfiles", m.RecordTime?.ToString("yyyyMM/yyyyMMdd"), "参与人员");
if (Directory.Exists(participantsPath))
{
foreach (var workerDir in m_workers)
{
var workerImagePath = Path.Combine(participantsPath, workerDir.WorkerName, fileName);
if (IOFile.Exists(workerImagePath))
{
IOFile.Delete(workerImagePath);
}
}
}
// 删除工作内容照片
var jobContentPath = Path.Combine(WebHostEnvironment.WebRootPath, "workfiles", m.RecordTime?.ToString("yyyyMM/yyyyMMdd"), "工作内容", m.Content);
var jobContentImagePath = Path.Combine(jobContentPath, fileName);
if (IOFile.Exists(jobContentImagePath))
{
IOFile.Delete(jobContentImagePath);
}
// 删除部门照片
var departmentPath = Path.Combine(WebHostEnvironment.WebRootPath, "workfiles", m.RecordTime?.ToString("yyyyMM/yyyyMMdd"), "部门", m.DeptName);
var departmentImagePath = Path.Combine(departmentPath, fileName);
if (IOFile.Exists(departmentImagePath))
{
IOFile.Delete(departmentImagePath);
}
}
//删除施工人员数据
await _CamWorkerService.DeleteAsync(it => it.WorkrecordId == parm.Id);
}
}
int MaxSize = 300 * 1024; // 300KB = 307200 字节
// 如果图片大于300KB才压缩
if (images.Length > MaxSize)
{
images = CompressImage(images, 50); // 压缩质量 70
imageprx = ".jpg";
}
var imageName = ImageConverter.GenerateImageFileName(imageprx);
var participantsUrl = $"{path}/参与人员/";
var photosDay = $"{path}/当日照片/";
var jobContent = $"{path}/工作内容/";
var department = $"{path}/部门/";
//添加当日照片
if (!Directory.Exists(photosDay))
{
Directory.CreateDirectory(photosDay);
}
var photosDayFileName = $"{photosDay}/{imageName}";
using (var stream = new FileStream(photosDayFileName, FileMode.Create))
{
await stream.WriteAsync(images, 0, images.Length);
}
//添加当日根据【人名】分类的照片
foreach (var work in parm.Workers)
{
var participantsUrlFIleName = $"{participantsUrl}/{work}/";
if (!Directory.Exists(participantsUrlFIleName))
{
Directory.CreateDirectory(participantsUrlFIleName);
}
participantsUrlFIleName += imageName;
using (var stream = new FileStream(participantsUrlFIleName, FileMode.Create))
{
await stream.WriteAsync(images, 0, images.Length);
}
}
//添加当日根据【工作内容】分类的照片
var jobContentUrl = $"{jobContent}/{parm.Content}/";
if (!Directory.Exists(jobContentUrl))
{
Directory.CreateDirectory(jobContentUrl);
}
jobContentUrl += imageName;
using (var stream = new FileStream(jobContentUrl, FileMode.Create))
{
await stream.WriteAsync(images, 0, images.Length);
}
//添加当日根据【部门】分类的照片
var departmentUrl = $"{department}{parm.DeptName}/";
if (!Directory.Exists(departmentUrl))
{
Directory.CreateDirectory(departmentUrl);
}
departmentUrl += imageName;
using (var stream = new FileStream(departmentUrl, FileMode.Create))
{
await stream.WriteAsync(images, 0, images.Length);
}
var domainUrl = $"{OptionsSetting.Upload.UploadUrl}";
//备份一下本地
var modal = parm.Adapt<CamWorkrecord>().ToCreate(HttpContext);
modal.CreateTime = DateTime.Now;
modal.UpdateTime = DateTime.Now;
modal.ImageUrl = $"{domainUrl}{filePath}/当日照片/{imageName}";
if (parm.Id != null && parm.Id > 0)
{
//修改实体类
await _CamWorkrecordService.UpdateAsync(modal);
}
else
{
modal = await _CamWorkrecordService.Insertable(modal).ExecuteReturnEntityAsync();
}
var workid = modal.Id;
var workers = new List<CamWorker>();
foreach (var item in parm.Workers)
{
var worker = new CamWorker()
{
WorkrecordId = workid,
WorkerName = item,
CreateTime = DateTime.Now,
UpdateTime = DateTime.Now
};
workers.Add(worker);
}
_CamWorkerService.AsInsertable(workers).ExecuteCommand();
return SUCCESS(1);
}
/// <summary>
/// 删除工作记录
/// </summary>
/// <param name="id">工作记录ID</param>
/// <returns></returns>
[HttpPost]
[Route("/deleteworkrecord/{id}")]
[ActionPermissionFilter(Permission = "camworkrecord:delete")]
public async Task<IActionResult> DeleteCamWorkRecord(long id)
{
// 查询工作记录
var workRecord = await _CamWorkrecordService.AsQueryable().Where(it => it.Id == id).FirstAsync();
if (workRecord == null)
{
return ToResponse(ResultCode.PARAM_ERROR, "未找到该记录");
}
// 查询相关的工作人员
var workers = await _CamWorkerService.AsQueryable().Where(it => it.WorkrecordId == id).ToListAsync();
try
{
// 删除图片文件
if (!string.IsNullOrEmpty(workRecord.ImageUrl))
{
// 从URL中提取文件路径
var imagePath = workRecord.ImageUrl.Substring(workRecord.ImageUrl.IndexOf("workfiles"));
var fullImagePath = Path.Combine(WebHostEnvironment.WebRootPath, imagePath);
// 获取文件名
var fileName = Path.GetFileName(fullImagePath);
var directoryPath = Path.GetDirectoryName(fullImagePath);
// 删除当日照片
if (IOFile.Exists(fullImagePath))
{
IOFile.Delete(fullImagePath);
}
// 删除参与人员照片
var participantsPath = Path.Combine(WebHostEnvironment.WebRootPath, "workfiles", workRecord.RecordTime?.ToString("yyyyMM/yyyyMMdd"), "参与人员");
if (Directory.Exists(participantsPath))
{
foreach (var worker in workers)
{
var workerImagePath = Path.Combine(participantsPath, worker.WorkerName, fileName);
if (IOFile.Exists(workerImagePath))
{
IOFile.Delete(workerImagePath);
}
// 如果该工作人员的文件夹为空,则删除文件夹
var workerDir = Path.GetDirectoryName(workerImagePath);
if (Directory.Exists(workerDir) && !Directory.EnumerateFiles(workerDir).Any())
{
Directory.Delete(workerDir);
}
}
}
// 删除工作内容照片
var jobContentPath = Path.Combine(WebHostEnvironment.WebRootPath, "workfiles", workRecord.RecordTime?.ToString("yyyyMM/yyyyMMdd"), "工作内容", workRecord.Content);
var jobContentImagePath = Path.Combine(jobContentPath, fileName);
if (IOFile.Exists(jobContentImagePath))
{
IOFile.Delete(jobContentImagePath);
}
// 如果工作内容文件夹为空,则删除文件夹
if (Directory.Exists(jobContentPath) && !Directory.EnumerateFiles(jobContentPath).Any())
{
Directory.Delete(jobContentPath);
}
// 删除部门照片
var departmentPath = Path.Combine(WebHostEnvironment.WebRootPath, "workfiles", workRecord.RecordTime?.ToString("yyyyMM/yyyyMMdd"), "部门", workRecord.DeptName);
var departmentImagePath = Path.Combine(departmentPath, fileName);
if (IOFile.Exists(departmentImagePath))
{
IOFile.Delete(departmentImagePath);
}
// 如果部门文件夹为空,则删除文件夹
if (Directory.Exists(departmentPath) && !Directory.EnumerateFiles(departmentPath).Any())
{
Directory.Delete(departmentPath);
}
// 清理空文件夹
CleanEmptyDirectories(Path.Combine(WebHostEnvironment.WebRootPath, "workfiles", workRecord.RecordTime?.ToString("yyyyMM/yyyyMMdd")));
}
}
catch (Exception ex)
{
logger.Error($"删除文件失败,错误: {ex.Message}");
}
// 删除工作人员记录
await _CamWorkerService.DeleteAsync(it => it.WorkrecordId == id);
// 删除工作记录
await _CamWorkrecordService.DeleteAsync(it => it.Id == id);
return SUCCESS(1);
}
/// <summary>
/// 清理空文件夹
/// </summary>
/// <param name="directoryPath">目录路径</param>
private void CleanEmptyDirectories(string directoryPath)
{
if (!Directory.Exists(directoryPath))
return;
try
{
// 递归清理子目录
foreach (var subDir in Directory.GetDirectories(directoryPath))
{
CleanEmptyDirectories(subDir);
}
// 如果当前目录为空,则删除
if (!Directory.EnumerateFiles(directoryPath).Any() && !Directory.EnumerateDirectories(directoryPath).Any())
{
Directory.Delete(directoryPath);
}
}
catch (Exception ex)
{
// 记录日志但不抛出异常,避免影响主流程
logger.Error($"清理空文件夹失败: {directoryPath}, 错误: {ex.Message}");
}
}
[HttpGet]
[Route("/getDownloadZip")]
[AllowAnonymous]
public async Task<IActionResult> DownloadZip([FromQuery] string? yearMoney)
{
if (string.IsNullOrEmpty(yearMoney) || yearMoney == "null")
{
yearMoney = DateTime.Now.ToString("yyyyMM");
}
if (yearMoney.IndexOf("-") > -1)
{
yearMoney = yearMoney.Replace("-", "");
}
var filePath = "/workfiles/" + yearMoney;
string savePath = Path.Combine(WebHostEnvironment.WebRootPath);
var path = savePath + filePath;
if (!Directory.Exists(path))
{
return ToResponse(ResultCode.FAIL, "无数据");
}
var outputPath = WebHostEnvironment.WebRootPath + "/workfiles/temp/";
if (!Directory.Exists(outputPath))
{
Directory.CreateDirectory(outputPath);
}
var zipReturnFileName = $"{outputPath}{yearMoney}.zip";
if (IOFile.Exists(zipReturnFileName))
{
IOFile.Delete(zipReturnFileName);
}
ZipFile.CreateFromDirectory(path, zipReturnFileName);
return DownFile(zipReturnFileName, $"{yearMoney}.zip");
}
public byte[] CompressImage(byte[] imageBytes, int quality)
{
using (var inputStream = new MemoryStream(imageBytes))
using (var image = Image.Load(inputStream))
{
var encoder = new JpegEncoder { Quality = quality };
using (var outputStream = new MemoryStream())
{
image.Save(outputStream, encoder);
return outputStream.ToArray();
}
}
}
/// <summary>
/// 获取workfiles文件夹大小信息
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("/getWorkfilesSize")]
[AllowAnonymous]
public IActionResult GetWorkfilesSize()
{
try
{
var workfilesPath = Path.Combine(WebHostEnvironment.WebRootPath, "workfiles");
if (!Directory.Exists(workfilesPath))
{
return ToResponse(ResultCode.FAIL, "workfiles文件夹不存在");
}
var result = new
{
TotalSize = GetDirectorySize(workfilesPath),
TotalSizeFormatted = FormatFileSize(GetDirectorySize(workfilesPath)),
DailyFolders = GetDailyFoldersSize(workfilesPath)
};
return SUCCESS(result);
}
catch (Exception ex)
{
logger.Error(ex, "获取workfiles文件夹大小信息失败");
return ToResponse(ResultCode.FAIL, "获取文件夹大小信息失败");
}
}
/// <summary>
/// 计算目录大小
/// </summary>
/// <param name="directoryPath">目录路径</param>
/// <returns>目录大小(字节)</returns>
private long GetDirectorySize(string directoryPath)
{
long size = 0;
try
{
var directory = new DirectoryInfo(directoryPath);
var files = directory.GetFiles("*", SearchOption.AllDirectories);
size = files.Sum(file => file.Length);
}
catch (Exception ex)
{
logger.Error(ex, $"计算目录大小失败: {directoryPath}");
}
return size;
}
/// <summary>
/// 格式化文件大小
/// </summary>
/// <param name="bytes">字节数</param>
/// <returns>格式化后的大小字符串</returns>
private string FormatFileSize(long bytes)
{
string[] sizes = { "B", "KB", "MB", "GB", "TB" };
double len = bytes;
int order = 0;
while (len >= 1024 && order < sizes.Length - 1)
{
order++;
len = len / 1024;
}
return $"{len:0.##} {sizes[order]}";
}
/// <summary>
/// 获取每日文件夹大小信息
/// </summary>
/// <param name="workfilesPath">workfiles路径</param>
/// <returns>每日文件夹大小信息列表</returns>
private List<object> GetDailyFoldersSize(string workfilesPath)
{
var dailyFolders = new List<object>();
try
{
var directory = new DirectoryInfo(workfilesPath);
var subDirectories = directory.GetDirectories();
foreach (var subDir in subDirectories)
{
var folderSize = GetDirectorySize(subDir.FullName);
var folderInfo = new
{
FolderName = subDir.Name,
Size = folderSize,
SizeFormatted = FormatFileSize(folderSize),
FileCount = subDir.GetFiles("*", SearchOption.AllDirectories).Length,
LastModified = subDir.LastWriteTime
};
dailyFolders.Add(folderInfo);
}
// 按文件夹名称排序(通常是日期格式)
dailyFolders = dailyFolders.OrderByDescending(x => ((dynamic)x).FolderName).ToList();
}
catch (Exception ex)
{
logger.Error(ex, "获取每日文件夹大小信息失败");
}
return dailyFolders;
}
}
}

View File

@ -4,11 +4,14 @@ 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;
using ZR.Common;
using ZR.Model.Dto;
using Infrastructure.Model;
using System.Threading.Tasks;
using ZR.Common.Model;
namespace ZR.Admin.WebApi.Controllers
{
@ -20,200 +23,143 @@ namespace ZR.Admin.WebApi.Controllers
[ApiExplorerSettings(GroupName = "webapi")]
public class WebApiController : BaseController
{
private readonly WechatApiClient _client;
/// <summary>
/// 礼品申领表接口
/// </summary>
private readonly IGiftClaimService _GiftClaimService;
/// <summary>
/// 微信用户表接口
/// </summary>
private readonly IGiftUserService _GiftUserService;
private ISysFileService SysFileService;
public WebApiController(WechatApiClient client, IGiftUserService GiftUserService, IGiftClaimService giftClaimService, ISysFileService sysFileService)
private readonly TencentMapService _tencentMapService;
public WebApiController(TencentMapService tencentMapService)
{
_client = client;
_GiftUserService = GiftUserService;
_GiftClaimService = giftClaimService;
SysFileService = sysFileService;
_tencentMapService = tencentMapService;
}
/// <summary>
///
/// 转换 GPS 经纬度到腾讯地图坐标
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
[HttpPost()]
[Route("/userLogin")]
[AllowAnonymous]
public async Task<IActionResult> GetOpenId([FromQuery] string code)
/// <param name="request">坐标转换请求参数</param>
/// <returns>转换后的坐标</returns>
[HttpPost]
[Route("GetLocationTranslate")]
public async Task<IActionResult> GetLocationTranslate([FromBody] CoordinateTranslateRequest request)
{
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<IActionResult> 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<object> list1 = new List<object>();
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<IActionResult> 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))
if (request == null || string.IsNullOrWhiteSpace(request.Locations))
{
Directory.CreateDirectory(path);
}
using (var stream = new FileStream(finalPath, FileMode.Create))
{
await stream.WriteAsync(images, 0, images.Length);
return ToResponse(ResultCode.CUSTOM_ERROR, "坐标点不能为空");
}
var result = await _tencentMapService.GetLocationTranslateAsync(request.Locations, request.Type);
return SUCCESS(result);
}
catch (Exception ex)
{
return ToResponse(ResultCode.CUSTOM_ERROR, ex.Message);
}
if (!string.IsNullOrEmpty(domainUrl))
{
finalPath = domainUrl + "/" + finalPath;
}
var ip = HttpContextExtension.GetClientUserIp(HttpContext);
GeoCodeService geoCodeService = new GeoCodeService(new HttpClient());
var resultTuple = await geoCodeService.GetReGeoCodeAsync(giftClaim.Longitude + "," + giftClaim.Latitude);
string regeo = "";
string geocodedAddress = "";
if (resultTuple.HasValue)
{
var (result, message) = resultTuple.Value;
if (result != null)
{
geocodedAddress = result;
}
regeo = message ?? "";
}
//if(t.)
var ipAddress = HttpContextExtension.GetIpInfo(ip);
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,
Longitude = giftClaim.Longitude,
Latitude = giftClaim.Latitude,
GeocodedAddress = geocodedAddress,
IP = ip,
Regeo= regeo,
IPAddress = ipAddress,
};
_GiftClaimService.AddGiftClaim(giftClaim1);
return SUCCESS(new { giftClaim1.Id });
}
/// <summary>
///
/// 根据坐标获取地址信息
/// </summary>
/// <returns></returns>
[HttpGet()]
[Route("/getBannerList")]
[AllowAnonymous]
public async Task<IActionResult> GetBannerList()
/// <param name="request">地理编码请求参数</param>
/// <returns>地址信息</returns>
[HttpPost]
[Route("GetLocationGeocoder")]
public async Task<IActionResult> GetLocationGeocoder([FromBody] GeocoderRequest request)
{
var list = await SysFileService.AsQueryable().Where(it => it.ClassifyType == "banner").Select(it =>
new { it.AccessUrl, it.RealName }).ToListAsync();
return SUCCESS(list);
try
{
if (request == null || string.IsNullOrWhiteSpace(request.Location))
{
return ToResponse(ResultCode.CUSTOM_ERROR, "坐标点不能为空");
}
var result = await _tencentMapService.GetLocationGeocoderAsync(request.Location);
return SUCCESS(result);
}
catch (Exception ex)
{
return ToResponse(ResultCode.CUSTOM_ERROR, ex.Message);
}
}
/// <summary>
/// 批量转换GPS坐标并获取地址
/// </summary>
/// <param name="request">坐标转换请求参数</param>
/// <returns>转换后的坐标和地址信息</returns>
[HttpPost]
[Route("GetLocationTranslateAndGeocoder")]
public async Task<IActionResult> GetLocationTranslateAndGeocoder([FromBody] CoordinateTranslateRequest request)
{
try
{
if (request == null || string.IsNullOrWhiteSpace(request.Locations))
{
return ToResponse(ResultCode.CUSTOM_ERROR, "坐标点不能为空");
}
var result = await _tencentMapService.GetLocationTranslateAndGeocoderAsync(request.Locations);
return SUCCESS(new
{
Location = result.Location,
Address = result.Address
});
}
catch (Exception ex)
{
return ToResponse(ResultCode.CUSTOM_ERROR, ex.Message);
}
}
/// <summary>
/// 转换 GPS 经纬度到腾讯地图坐标 (GET方式)
/// </summary>
/// <param name="locations">坐标点格式lat,lng;lat,lng</param>
/// <param name="type">转换类型默认1表示GPS坐标转腾讯坐标</param>
/// <returns>转换后的坐标</returns>
[HttpGet]
[Route("/webapi/GetLocationTranslate")]
[AllowAnonymous]
public async Task<IActionResult> GetLocationTranslateGet([FromQuery] string locations, [FromQuery] int type = 1)
{
try
{
if (string.IsNullOrWhiteSpace(locations))
{
return ToResponse(ResultCode.CUSTOM_ERROR, "坐标点不能为空");
}
var result = await _tencentMapService.GetLocationTranslateAsync(locations, type);
return SUCCESS(result);
}
catch (Exception ex)
{
return ToResponse(ResultCode.CUSTOM_ERROR, ex.Message);
}
}
/// <summary>
/// 根据坐标获取地址信息 (GET方式)
/// </summary>
/// <param name="location">坐标点格式lat,lng</param>
/// <returns>地址信息</returns>
[HttpGet]
[Route("/webapi/GetLocationGeocoder")]
[AllowAnonymous]
public async Task<IActionResult> GetLocationGeocoderGet([FromQuery] string location)
{
try
{
if (string.IsNullOrWhiteSpace(location))
{
return ToResponse(ResultCode.CUSTOM_ERROR, "坐标点不能为空");
}
var result = await _tencentMapService.GetLocationGeocoderAsync(location);
return SUCCESS(result);
}
catch (Exception ex)
{
return ToResponse(ResultCode.CUSTOM_ERROR, ex.Message);
}
}
}
}

View File

@ -5,9 +5,6 @@ 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
{
@ -19,19 +16,11 @@ namespace ZR.Admin.WebApi.Controllers
public class WxOpenController : BaseController
{
private readonly WechatApiClient _client;
/// <summary>
/// 礼品申领表接口
/// </summary>
private readonly IGiftClaimService _GiftClaimService;
/// <summary>
/// 微信用户表接口
/// </summary>
private readonly IGiftUserService _GiftUserService;
public WxOpenController(WechatApiClient client, IGiftUserService GiftUserService, IGiftClaimService giftClaimService)
public WxOpenController(WechatApiClient client)
{
_client = client;
_GiftUserService = GiftUserService;
_GiftClaimService = giftClaimService;
}
@ -60,69 +49,5 @@ namespace ZR.Admin.WebApi.Controllers
return SUCCESS(new { appId, signature, noncestr, timestamp, url });
}
[HttpGet("login")]
[AllowAnonymous]
public async Task<IActionResult> 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<IActionResult> 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<object> list1 = new List<object>();
list?.ForEach(it =>
{
list1.Add(new
{
it.Status,
it.Name,
it.Address,
it.Phone
});
});
return SUCCESS(list1);
}
}
}

View File

@ -1,7 +1,9 @@
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;
using Swashbuckle.AspNetCore.SwaggerUI;
using System.Reflection;
namespace ZR.Admin.WebApi.Extensions
@ -55,9 +57,9 @@ namespace ZR.Admin.WebApi.Extensions
Title = "ZrAdmin.NET Api",
Version = "v1",
Description = "系统管理",
Contact = new OpenApiContact { Name = "Admin doc", Url = new Uri("") }
Contact = new OpenApiContact { Name = "Admin doc" }
});
try
{
//var tempPath = hostEnvironment.ContentRootPath;

View File

@ -84,6 +84,10 @@ if (!string.IsNullOrEmpty(GaoDeKey))
{
GeoCodeService.ApiKey = GaoDeKey;
}
// 注册腾讯地图服务
builder.Services.AddHttpClient();
builder.Services.AddSingleton<TencentMapService>();
builder.Services.AddMvc(options =>
{
options.Filters.Add(typeof(GlobalActionMonitor));//全局注册

View File

@ -13,12 +13,16 @@
<ItemGroup>
<Compile Remove="gift\**" />
<Compile Remove="wwwroot\2025\**" />
<Compile Remove="wwwroot\file\**" />
<Content Remove="gift\**" />
<Content Remove="wwwroot\2025\**" />
<Content Remove="wwwroot\file\**" />
<EmbeddedResource Remove="gift\**" />
<EmbeddedResource Remove="wwwroot\2025\**" />
<EmbeddedResource Remove="wwwroot\file\**" />
<None Remove="gift\**" />
<None Remove="wwwroot\2025\**" />
<None Remove="wwwroot\file\**" />
</ItemGroup>
<ItemGroup>
@ -38,8 +42,10 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Controllers\Business\" />
<Folder Include="Controllers\WebApi\" />
<Folder Include="Properties\PublishProfiles\" />
<Folder Include="wwwroot\Generatecode\" />
</ItemGroup>
<ItemGroup>

View File

@ -8,7 +8,7 @@
},
"dbConfigs": [
{
"Conn": "Data Source=192.168.195.8;User ID=sa;Password=Dbt@com@123;Initial Catalog=GiftAdmin;Encrypt=True;TrustServerCertificate=True;",
"Conn": "Data Source=192.168.195.8;User ID=sa;Password=Dbt@com@123;Initial Catalog=WatermarkCamera;Encrypt=True;TrustServerCertificate=True;",
"DbType": 1, // MySql = 0, SqlServer = 1, Oracle = 3PgSql = 4
"ConfigId": "0", //
"IsAutoCloseConnection": true
@ -28,7 +28,7 @@
"Conn": "Data Source=192.168.195.8;User ID=sa;Password=Dbt@com@123;Encrypt=True;TrustServerCertificate=True;Initial Catalog={dbName};",
"DbType": 1,
"IsAutoCloseConnection": true,
"DbName": "GiftAdmin" //,Oracle
"DbName": "WatermarkCamera" //,Oracle
},
"urls": "http://*:8888", //urldevServer
"corsUrls": [ "http://localhost:8887", "http://localhost:8886" ], //","
@ -48,10 +48,10 @@
"DemoMode": false, //
"SingleLogin": false, ///
"workId": 1, //id
"sqlExecutionTime": 5, //Sql
"sqlExecutionTime": 5, //Sql
"Upload": {
"uploadUrl": "http://localhost:8888", //访
"localSavePath": "", // wwwroot
"localSavePath": "file", // wwwroot
"maxSize": 15, // 15M
"notAllowedExt": [ ".bat", ".exe", ".jar", ".js" ],
"requestLimitSize": 50 //body
@ -125,5 +125,8 @@
"tablePrefix": "sys_", //"表前缀(生成类名不会包含表前缀,多个用逗号分隔)",
"vuePath": "", //egD:\Work\ZRAdmin-Vue3
"uniappPath": "D:\\Work" //h5
},
"TencentMap": {
"Key": "2DYBZ-V4N3W-VQ4RA-Y22V5-BXA2E-53FYV" //key
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

View File

@ -88,7 +88,24 @@ public static class ImageConverter
// 拼接文件名
return $"{timestamp}_{randomNumber}{extension}";
}
/// <summary>
/// 生成图片名称:时间戳(秒)+4位随机数字
/// 示例16907832451234.png
/// </summary>
/// <param name="extension">文件扩展名(例如 .png、.jpg可选默认值为 .png</param>
/// <returns>生成的图片文件名</returns>
public static string GenerateImageFileNameTime(string extension = ".png")
{
// 获取当前时间戳(秒)
string now = DateTime.Now.ToString("yyyyMMddHHmmssfff");
// 生成 4 位随机数1000 - 9999
Random random = new Random();
int randomNumber = random.Next(1000, 10000);
// 拼接文件名
return $"{now}_{randomNumber}{extension}";
}
}

View File

@ -0,0 +1,135 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace ZR.Common.Model
{
/// <summary>
/// 腾讯地图坐标对象
/// </summary>
public class MapLocation
{
/// <summary>
/// 纬度
/// </summary>
[JsonPropertyName("lat")]
public double Lat { get; set; }
/// <summary>
/// 经度
/// </summary>
[JsonPropertyName("lng")]
public double Lng { get; set; }
}
/// <summary>
/// 腾讯地图API响应对象
/// </summary>
public class MapApiResponse
{
/// <summary>
/// 状态码
/// </summary>
[JsonPropertyName("status")]
public int Status { get; set; }
/// <summary>
/// 状态信息
/// </summary>
[JsonPropertyName("message")]
public string Message { get; set; }
/// <summary>
/// 请求ID
/// </summary>
[JsonPropertyName("request_id")]
public string RequestId { get; set; }
/// <summary>
/// 坐标列表
/// </summary>
[JsonPropertyName("locations")]
public List<MapLocation> Locations { get; set; }
}
/// <summary>
/// 腾讯地图地理编码结果
/// </summary>
public class MapGeocoderResult
{
/// <summary>
/// 地址
/// </summary>
[JsonPropertyName("address")]
public string Address { get; set; }
[JsonPropertyName("formatted_addresses")]
public FormattedAddresses formattedAddresses { get; set; }
}
public class FormattedAddresses
{
public string recommend { get; set; }
public string rough { get; set; }
public string standard_address { get; set; }
}
/// <summary>
/// 腾讯地图地理编码API响应
/// </summary>
public class MapGeocoderApiResponse
{
/// <summary>
/// 状态码
/// </summary>
[JsonPropertyName("status")]
public int Status { get; set; }
/// <summary>
/// 状态信息
/// </summary>
[JsonPropertyName("message")]
public string Message { get; set; }
/// <summary>
/// 请求ID
/// </summary>
[JsonPropertyName("request_id")]
public string RequestId { get; set; }
/// <summary>
/// 地理编码结果
/// </summary>
[JsonPropertyName("result")]
public MapGeocoderResult Result { get; set; }
}
/// <summary>
/// 坐标转换请求参数
/// </summary>
public class CoordinateTranslateRequest
{
/// <summary>
/// 坐标点格式lat,lng;lat,lng
/// </summary>
public string Locations { get; set; }
/// <summary>
/// 转换类型1-GPS坐标转腾讯坐标
/// </summary>
public int Type { get; set; } = 1;
}
/// <summary>
/// 地理编码请求参数
/// </summary>
public class GeocoderRequest
{
/// <summary>
/// 坐标点格式lat,lng
/// </summary>
public string Location { get; set; }
}
}

View File

@ -0,0 +1,130 @@
using Infrastructure;
using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
using ZR.Common.Model;
namespace ZR.Common
{
/// <summary>
/// 腾讯地图服务
/// </summary>
public class TencentMapService
{
private readonly HttpClient _httpClient;
private readonly string _apiKey = AppSettings.GetConfig("TencentMap:KEY");
private const string BaseUrl = "https://apis.map.qq.com/";
public TencentMapService(HttpClient httpClient)
{
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
}
/// <summary>
/// 转换 GPS 经纬度到腾讯地图坐标
/// </summary>
/// <param name="locations">坐标点格式lat,lng;lat,lng</param>
/// <param name="type">转换类型默认1表示GPS坐标转腾讯坐标</param>
/// <returns>转换后的坐标</returns>
public async Task<MapLocation> GetLocationTranslateAsync(string locations, int type = 1)
{
if (string.IsNullOrWhiteSpace(locations))
{
throw new ArgumentException("坐标点不能为空", nameof(locations));
}
var url = $"{BaseUrl}ws/coord/v1/translate?locations={locations}&type={type}&key={_apiKey}";
try
{
var response = await _httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
var mapResponse = JsonSerializer.Deserialize<MapApiResponse>(content, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
if (mapResponse?.Status == 0 && mapResponse.Locations?.Count > 0)
{
return mapResponse.Locations[0];
}
else
{
throw new Exception($"坐标转换失败: {mapResponse?.Message}");
}
}
catch (HttpRequestException ex)
{
throw new Exception("请求腾讯地图API失败", ex);
}
catch (JsonException ex)
{
throw new Exception("解析腾讯地图API响应失败", ex);
}
}
/// <summary>
/// 根据转换后的经纬度获取地址
/// </summary>
/// <param name="location">坐标点格式lat,lng</param>
/// <returns>地址信息</returns>
public async Task<string> GetLocationGeocoderAsync(string location)
{
if (string.IsNullOrWhiteSpace(location))
{
throw new ArgumentException("坐标点不能为空", nameof(location));
}
var url = $"{BaseUrl}ws/geocoder/v1/?location={location}&key={_apiKey}";
try
{
var response = await _httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
var geocoderResponse = JsonSerializer.Deserialize<MapGeocoderApiResponse>(content, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
if (geocoderResponse?.Status == 0 && geocoderResponse.Result != null)
{
return geocoderResponse.Result.formattedAddresses?.standard_address ?? geocoderResponse.Result.Address;
}
else
{
throw new Exception($"地理编码失败: {geocoderResponse?.Message}");
}
}
catch (HttpRequestException ex)
{
throw new Exception("请求腾讯地图API失败", ex);
}
catch (JsonException ex)
{
throw new Exception("解析腾讯地图API响应失败", ex);
}
}
/// <summary>
/// 批量转换GPS坐标并获取地址
/// </summary>
/// <param name="locations">坐标点格式lat,lng;lat,lng</param>
/// <returns>转换后的坐标和地址信息</returns>
public async Task<(MapLocation Location, string Address)> GetLocationTranslateAndGeocoderAsync(string locations)
{
var translatedLocation = await GetLocationTranslateAsync(locations);
var locationString = $"{translatedLocation.Lat},{translatedLocation.Lng}";
var address = await GetLocationGeocoderAsync(locationString);
return (translatedLocation, address);
}
}
}

View File

@ -0,0 +1,37 @@
namespace ZR.Model.Business
{
/// <summary>
/// 工作人员记录
/// </summary>
[SugarTable("cam_worker")]
public class CamWorker
{
/// <summary>
/// 主键
/// </summary>
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public long Id { get; set; }
/// <summary>
/// 施工记录Id
/// </summary>
public int WorkrecordId { get; set; }
/// <summary>
/// 人员
/// </summary>
public string WorkerName { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime? CreateTime { get; set; }
/// <summary>
/// 更新时间
/// </summary>
public DateTime? UpdateTime { get; set; }
}
}

View File

@ -0,0 +1,37 @@
namespace ZR.Model.Business
{
/// <summary>
/// 月报表
/// </summary>
[SugarTable("cam_workers")]
public class CamWorkers
{
/// <summary>
/// Id
/// </summary>
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public long Id { get; set; }
/// <summary>
/// WorkrecordId
/// </summary>
public int WorkrecordId { get; set; }
/// <summary>
/// WorkerName
/// </summary>
public string WorkerName { get; set; }
/// <summary>
/// WorkerDay
/// </summary>
public int WorkerDay { get; set; }
/// <summary>
/// CreateTime
/// </summary>
public DateTime? CreateTime { get; set; }
}
}

View File

@ -2,69 +2,70 @@
namespace ZR.Model.Business
{
/// <summary>
/// 微信用户表
/// 工作记录
/// </summary>
[SugarTable("gift_user")]
public class GiftUser
[SugarTable("cam_workrecord")]
public class CamWorkrecord
{
/// <summary>
/// 主键ID
/// 主键
/// </summary>
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
/// <summary>
/// 微信openid
/// 部门名称
/// </summary>
public string Openid { get; set; }
public string DeptName { get; set; }
/// <summary>
/// 微信unionid
/// 图片
/// </summary>
public string Unionid { get; set; }
public string ImageUrl { get; set; }
/// <summary>
/// 昵称
/// 拍照时间
/// </summary>
public string Nickname { get; set; }
public DateTime? RecordTime { get; set; }
/// <summary>
/// 头像URL
/// 经度
/// </summary>
[SugarColumn(ColumnName = "avatar_url")]
public string AvatarUrl { get; set; }
public string Longitude { get; set; }
/// <summary>
/// 性别
/// 纬度
/// </summary>
public string Gender { get; set; }
public string Latitude { get; set; }
/// <summary>
/// 手机号
/// 拍照地址
/// </summary>
public string Phone { get; set; }
public string Address { get; set; }
/// <summary>
/// 工作内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 状态
/// </summary>
public string Status { get; set; }
public string StatusName { get; set; }
/// <summary>
/// 最后登录时间
/// 备注
/// </summary>
[SugarColumn(ColumnName = "last_login_time")]
public DateTime? LastLoginTime { get; set; }
public string Remarks { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[SugarColumn(ColumnName = "create_time")]
public DateTime? CreateTime { get; set; }
/// <summary>
/// 更新时间
/// </summary>
[SugarColumn(ColumnName = "update_time")]
public DateTime? UpdateTime { get; set; }
}

View File

@ -0,0 +1,49 @@
namespace ZR.Model.Business.Dto
{
/// <summary>
/// 工作人员记录查询对象
/// </summary>
public class CamWorkerQueryDto : PagerInfo
{
}
/// <summary>
/// 工作人员记录输入输出对象
/// </summary>
public class CamWorkerDto
{
[Required(ErrorMessage = "主键不能为空")]
public long Id { get; set; }
[Required(ErrorMessage = "施工记录Id不能为空")]
public int WorkrecordId { get; set; }
[Required(ErrorMessage = "人员不能为空")]
public string WorkerName { get; set; }
public DateTime? CreateTime { get; set; }
public DateTime? UpdateTime { get; set; }
}
/// <summary>
/// 工作人员记录输入输出对象
/// </summary>
public class CamWorkersDto
{
[Required(ErrorMessage = "主键不能为空")]
public long Id { get; set; }
[Required(ErrorMessage = "人员不能为空")]
public string WorkerName { get; set; }
}
}

View File

@ -0,0 +1,81 @@
namespace ZR.Model.Business.Dto
{
/// <summary>
/// 月报表查询对象
/// </summary>
public class CamWorkersQueryDto
{
public string WorkerName { get; set; }
public string YearMonth { get; set; }
}
/// <summary>
/// 月报表输入输出对象
/// </summary>
public class CamWorkersfDto
{
[Required(ErrorMessage = "Id不能为空")]
[ExcelColumn(Name = "Id")]
[ExcelColumnName("Id")]
public long Id { get; set; }
[Required(ErrorMessage = "WorkrecordId不能为空")]
[ExcelColumn(Name = "WorkrecordId")]
[ExcelColumnName("WorkrecordId")]
public int WorkrecordId { get; set; }
[Required(ErrorMessage = "WorkerName不能为空")]
[ExcelColumn(Name = "WorkerName")]
[ExcelColumnName("WorkerName")]
public string WorkerName { get; set; }
[Required(ErrorMessage = "WorkerDay不能为空")]
[ExcelColumn(Name = "WorkerDay")]
[ExcelColumnName("WorkerDay")]
public int WorkerDay { get; set; }
[Required(ErrorMessage = "CreateTime不能为空")]
[ExcelColumn(Name = "CreateTime", Format = "yyyy-MM-dd HH:mm:ss", Width = 20)]
[ExcelColumnName("CreateTime")]
public DateTime? CreateTime { get; set; }
}
/// <summary>
/// 每月员工工作天数统计结果
/// </summary>
public class WorkerMonthlyWorkDays
{
/// <summary>
/// 年月格式yyyy-MM
/// </summary>
[ExcelColumn(Name = "月份")]
[ExcelColumnName("月份")]
public string YearMonth { get; set; }
/// <summary>
/// 部门名称
/// </summary>
[ExcelColumn(Name = "部门名称")]
[ExcelColumnName("部门名称")]
public string DeptName { get; set; }
/// <summary>
/// 员工姓名
/// </summary>
[ExcelColumn(Name = "员工姓名")]
[ExcelColumnName("员工姓名")]
public string WorkerName { get; set; }
/// <summary>
/// 当月工作天数
/// </summary>
[ExcelColumn(Name = "当月工作天数")]
[ExcelColumnName("当月工作天数")]
public int WorkDays { get; set; }
}
}

View File

@ -0,0 +1,204 @@
namespace ZR.Model.Business.Dto
{
/// <summary>
/// 工作记录查询对象
/// </summary>
public class CamWorkrecordQueryDto : PagerInfo
{
public string DeptName { get; set; }
public string Address { get; set; }
public string Content { get; set; }
public string StatusName { get; set; }
/// <summary>
///
/// </summary>
public string Workrecord { get; set; }
public DateTime? BeginRecordTime { get; set; }
public DateTime? EndRecordTime { get; set; }
}
/// <summary>
/// 工作记录输入输出对象
/// </summary>
public class CamWorkrecordDto
{
[Required(ErrorMessage = "主键不能为空")]
public int Id { get; set; }
public string DeptName { get; set; }
public string ImageUrl { get; set; }
public DateTime? RecordTime { get; set; }
public string Longitude { get; set; }
public string Latitude { get; set; }
public string Address { get; set; }
public string Content { get; set; }
public string StatusName { get; set; }
public string Remarks { get; set; }
public DateTime? CreateTime { get; set; }
public DateTime? UpdateTime { get; set; }
public Dictionary<string, object> RemarksDic { get; set; }
/// <summary>
/// 施工人员
/// </summary>
public List<CamWorkersDto> Workers { get; set; }
/// <summary>
/// 施工人员
/// </summary>
public string Worker { get; set; }
[ExcelColumn(Name = "状态")]
public string StatusNameLabel { get; set; }
}
/// <summary>
///
/// </summary>
public class CamRecordWorkDto
{
public int? Id { get; set; }
/// <summary>
/// 部门名称
/// </summary>
public string DeptName { get; set; }
public string ImageUrl { get; set; }
/// <summary>
/// 图片地址
/// </summary>
public string Image { get; set; }
/// <summary>
/// 工作记录时间
/// </summary>
public DateTime? RecordTime { get; set; }
/// <summary>
/// 经度
/// </summary>
public string Longitude { get; set; }
/// <summary>
/// 纬度
/// </summary>
public string Latitude { get; set; }
/// <summary>
/// 工作地点
/// </summary>
public string Address { get; set; }
/// <summary>
/// 工作内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 状态
/// </summary>
public string StatusName { get; set; }
/// <summary>
///备注
/// </summary>
public string Remarks { get; set; }
/// <summary>
///
/// </summary>
public List<string> Workers { get; set; }
}
/// <summary>
/// 工作记录输入输出对象
/// </summary>
public class CamWorkrecordExcelDto
{
[ExcelIgnore]
public int Id { get; set; }
[ExcelColumn(Name = "序号")]
[ExcelColumnName("序号")]
public int Index { get; set; }
[ExcelColumn(Name = "部门名称")]
[ExcelColumnName("部门名称")]
public string DeptName { get; set; }
[ExcelColumn(Name = "拍照时间", Format = "yyyy-MM-dd HH:mm:ss", Width = 20)]
[ExcelColumnName("拍照时间")]
public DateTime? RecordTime { get; set; }
[ExcelColumn(Name = "经度")]
[ExcelColumnName("经度")]
public string Longitude { get; set; }
[ExcelColumn(Name = "纬度")]
[ExcelColumnName("纬度")]
public string Latitude { get; set; }
[ExcelColumn(Name = "位置")]
[ExcelColumnName("位置")]
public string Address { get; set; }
[ExcelColumn(Name = "工作内容")]
[ExcelColumnName("工作内容")]
public string Content { get; set; }
/// <summary>
///
/// </summary>
[ExcelIgnore]
public List<string> Workers { get; set; }
[ExcelColumn(Name = "施工人员")]
[ExcelColumnName("施工人员")]
public string Worker
{
get
{
return Workers != null ? string.Join(",", Workers) : string.Empty;
}
}
[ExcelColumn(Name = "状态")]
[ExcelColumnName("状态")]
public string StatusName { get; set; }
[ExcelIgnore]
public string Remarks { get; set; }
[ExcelColumn(Name = "施工图片", Width = 100)]
[ExcelColumnName("施工图片")]
public byte[] Image { get; set; }
[ExcelColumn(Name = "创建时间", Format = "yyyy-MM-dd HH:mm:ss", Width = 20)]
[ExcelColumnName("创建时间")]
public DateTime? CreateTime { get; set; }
[ExcelColumn(Name = "更新时间", Format = "yyyy-MM-dd HH:mm:ss", Width = 20)]
[ExcelColumnName("更新时间")]
public DateTime? UpdateTime { get; set; }
[ExcelIgnore]
public string ImageUrl { get; set; }
}
}

View File

@ -1,202 +0,0 @@
namespace ZR.Model.Business.Dto
{
/// <summary>
/// 礼品申领表查询对象
/// </summary>
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; }
}
/// <summary>
/// 礼品申领表输入输出对象
/// </summary>
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; }
/// <summary>
/// 审核时间
/// </summary>
[ExcelColumn(Name = "审核时间")]
[ExcelColumnName("审核时间")]
public DateTime? ReviewAt { get; set; }
/// <summary>
/// 微信用户id
/// </summary>
[ExcelColumn(Name = "微信用户id")]
[ExcelColumnName("微信用户id")]
public string UserWxOpenId { get; set; }
/// <summary>
/// 经度
/// </summary>
[ExcelColumn(Name = "经度")]
[ExcelColumnName("经度")]
public string Latitude { get; set; }
/// <summary>
/// 纬度
/// </summary>
[ExcelColumn(Name = "纬度")]
[ExcelColumnName("纬度")]
public string Longitude { get; set; }
/// <summary>
/// 经纬度地址
/// </summary>
[ExcelColumn(Name = "经纬度地址")]
[ExcelColumnName("经纬度地址")]
public string GeocodedAddress { get; set; }
/// <summary>
/// ip地址
/// </summary>
[ExcelColumn(Name = "ip")]
[ExcelColumnName("ip")]
public string IP { get; set; }
/// <summary>
/// ip地址
/// </summary>
[ExcelColumn(Name = "ip地址")]
[ExcelColumnName("ip地址")]
public string IPAddress { get; set; }
}
/// <summary>
/// 礼品申领表输入输出对象
/// </summary>
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; }
/// <summary>
/// 纬度
/// </summary>
public string Latitude { get; set; }
/// <summary>
/// 经度
/// </summary>
public string Longitude { get; set; }
}
}

View File

@ -1,28 +0,0 @@
namespace ZR.Model.Business.Dto
{
/// <summary>
/// 礼品小程序查询对象
/// </summary>
public class GiftConfigQueryDto : PagerInfo
{
}
/// <summary>
/// 礼品小程序输入输出对象
/// </summary>
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; }
}
}

View File

@ -1,73 +0,0 @@
namespace ZR.Model.Business.Dto
{
/// <summary>
/// 微信用户表查询对象
/// </summary>
public class GiftUserQueryDto : PagerInfo
{
public string Nickname { get; set; }
}
/// <summary>
/// 微信用户表输入输出对象
/// </summary>
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; }
}
}

View File

@ -1,111 +0,0 @@
namespace ZR.Model.Business
{
/// <summary>
/// 礼品申领表
/// </summary>
[SugarTable("gift_claim")]
public class GiftClaim
{
/// <summary>
/// 主键
/// </summary>
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
/// <summary>
/// 用户ID
/// </summary>
[SugarColumn(ColumnName = "user_id")]
public int UserId { get; set; }
/// <summary>
/// 姓名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 联系方式
/// </summary>
public string Phone { get; set; }
/// <summary>
/// 工作单位
/// </summary>
public string Company { get; set; }
/// <summary>
/// 收货地址
/// </summary>
public string Address { get; set; }
/// <summary>
/// 产品型号
/// </summary>
public string ProductModel { get; set; }
/// <summary>
/// 出品编号
/// </summary>
public string ProductSerialNumber { get; set; }
/// <summary>
/// 出品年月
/// </summary>
public string ProductDate { get; set; }
/// <summary>
/// 出品图片
/// </summary>
public string ProductImage { get; set; }
/// <summary>
/// 提交时间
/// </summary>
public DateTime? CreatedAt { get; set; }
/// <summary>
/// 审核状态
/// </summary>
public int Status { get; set; }
/// <summary>
/// 审核时间
/// </summary>
public DateTime? ReviewAt { get; set; }
/// <summary>
/// 微信用户id
/// </summary>
public string UserWxOpenId { get; set; }
/// <summary>
/// 经度
/// </summary>
public string Latitude { get; set; }
/// <summary>
/// 纬度
/// </summary>
public string Longitude { get; set; }
/// <summary>
/// ip地址
/// </summary>
public string IP { get; set; }
/// <summary>
/// 经纬度地址
/// </summary>
public string GeocodedAddress { get; set; }
/// <summary>
/// ip地址
/// </summary>
public string IPAddress { get; set; }
/// <summary>
///
/// </summary>
public string Regeo { get; set; }
}
}

View File

@ -1,32 +0,0 @@
namespace ZR.Model.Business
{
/// <summary>
/// 礼品小程序
/// </summary>
[SugarTable("gift_config")]
public class GiftConfig
{
/// <summary>
/// Id
/// </summary>
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
/// <summary>
/// 首页图片
/// </summary>
public string HomeImage { get; set; }
/// <summary>
/// 扩展1
/// </summary>
public string Extend { get; set; }
/// <summary>
/// 扩展2
/// </summary>
public string Extend1 { get; set; }
}
}

View File

@ -14,6 +14,7 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Business\" />
<Folder Include="Social\Dto\" />
</ItemGroup>
</Project>

View File

@ -8,23 +8,24 @@ using ZR.Service.Business.IBusinessService;
namespace ZR.Service.Business
{
/// <summary>
/// 礼品小程序Service业务层处理
/// 工作人员记录Service业务层处理
/// </summary>
[AppService(ServiceType = typeof(IGiftConfigService), ServiceLifetime = LifeTime.Transient)]
public class GiftConfigService : BaseService<GiftConfig>, IGiftConfigService
[AppService(ServiceType = typeof(ICamWorkerService), ServiceLifetime = LifeTime.Transient)]
public class CamWorkerService : BaseService<CamWorker>, ICamWorkerService
{
/// <summary>
/// 查询礼品小程序列表
/// 查询工作人员记录列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public PagedInfo<GiftConfigDto> GetList(GiftConfigQueryDto parm)
public PagedInfo<CamWorkerDto> GetList(CamWorkerQueryDto parm)
{
var predicate = QueryExp(parm);
var response = Queryable()
//.OrderBy("Id desc")
.Where(predicate.ToExpression())
.ToPage<GiftConfig, GiftConfigDto>(parm);
.ToPage<CamWorker, CamWorkerDto>(parm);
return response;
}
@ -35,7 +36,7 @@ namespace ZR.Service.Business
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
public GiftConfig GetInfo(int Id)
public CamWorker GetInfo(long Id)
{
var response = Queryable()
.Where(x => x.Id == Id)
@ -45,23 +46,23 @@ namespace ZR.Service.Business
}
/// <summary>
/// 添加礼品小程序
/// 添加工作人员记录
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public GiftConfig AddGiftConfig(GiftConfig model)
public CamWorker AddCamWorker(CamWorker model)
{
return Insertable(model).ExecuteReturnEntity();
}
/// <summary>
/// 修改礼品小程序
/// 修改工作人员记录
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int UpdateGiftConfig(GiftConfig model)
public int UpdateCamWorker(CamWorker model)
{
return Update(model, true, "修改礼品小程序");
return Update(model, true);
}
/// <summary>
@ -69,9 +70,9 @@ namespace ZR.Service.Business
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
private static Expressionable<GiftConfig> QueryExp(GiftConfigQueryDto parm)
private static Expressionable<CamWorker> QueryExp(CamWorkerQueryDto parm)
{
var predicate = Expressionable.Create<GiftConfig>();
var predicate = Expressionable.Create<CamWorker>();
return predicate;
}

View File

@ -0,0 +1,115 @@
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
{
/// <summary>
/// 月报表Service业务层处理
/// </summary>
[AppService(ServiceType = typeof(ICamWorkersService), ServiceLifetime = LifeTime.Transient)]
public class CamWorkersService : BaseService<CamWorkers>, ICamWorkersService
{
private readonly ICamWorkrecordService _camWorkrecordService;
private readonly ICamWorkerService _camWorkerService;
public CamWorkersService(ICamWorkrecordService camWorkrecordService, ICamWorkerService camWorkerService)
{
_camWorkrecordService = camWorkrecordService;
_camWorkerService = camWorkerService;
}
/// <summary>
/// 查询月报表列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public List<WorkerMonthlyWorkDays> GetList(CamWorkersQueryDto parm)
{
string where = "";
if (!string.IsNullOrEmpty(parm.WorkerName))
{
where += $" and w.WorkerName like '%{parm.WorkerName}%'";
}
if (parm.YearMonth != null)
{
where += $" and CONVERT(varchar(7), CAST(r.RecordTime AS date), 120) = '{parm.YearMonth}'";
}
var predicate = QueryExp(parm);
var list = Context.Ado.SqlQuery<WorkerMonthlyWorkDays>($@"
SELECT
r.DeptName,
w.WorkerName,
CONVERT(varchar(7), CAST(r.RecordTime AS date), 120) AS YearMonth,
COUNT(DISTINCT CAST(r.RecordTime AS date)) AS WorkDays
FROM cam_worker w
LEFT JOIN cam_workrecord r ON w.workrecordId = r.Id where r.RecordTime is not null {where}
GROUP BY
r.DeptName,
w.WorkerName,
CONVERT(varchar(7), CAST(r.RecordTime AS date), 120)
ORDER BY
r.DeptName,
w.WorkerName,
YearMonth
");
//.Where(predicate.ToExpression())
//var response = Queryable()
// //.OrderBy("WorkerName asc")
// .Where(predicate.ToExpression())
// .ToPage<CamWorkers, CamWorkersDto>(parm);
return list;
}
/// <summary>
/// 获取详情
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
public CamWorkers GetInfo(long Id)
{
var response = Queryable()
.Where(x => x.Id == Id)
.First();
return response;
}
/// <summary>
/// 添加月报表
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public CamWorkers AddCamWorkers(CamWorkers model)
{
return Insertable(model).ExecuteReturnEntity();
}
/// <summary>
/// 导出月报表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public List<WorkerMonthlyWorkDays> ExportList(CamWorkersQueryDto parm)
{
return GetList(parm);
}
/// <summary>
/// 查询导出表达式
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
private static Expressionable<CamWorkrecord> QueryExp(CamWorkersQueryDto parm)
{
var predicate = Expressionable.Create<CamWorkrecord>();
return predicate;
}
}
}

View File

@ -0,0 +1,179 @@
using Infrastructure.Attribute;
using Infrastructure.Extensions;
using ZR.Model.Business.Dto;
using ZR.Model.Business;
using ZR.Repository;
using ZR.Service.Business.IBusinessService;
using ZR.ServiceCore.Services;
namespace ZR.Service.Business
{
/// <summary>
/// 工作记录Service业务层处理
/// </summary>
[AppService(ServiceType = typeof(ICamWorkrecordService), ServiceLifetime = LifeTime.Transient)]
public class CamWorkrecordService : BaseService<CamWorkrecord>, ICamWorkrecordService
{
private ICamWorkerService camWorkerService;
public CamWorkrecordService(ICamWorkerService camWorkerService)
{
this.camWorkerService = camWorkerService;
}
/// <summary>
/// 查询工作记录列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public PagedInfo<CamWorkrecordDto> GetList(CamWorkrecordQueryDto parm)
{
var predicate = QueryExp(parm);
var response = Queryable()
.OrderBy("Id desc")
.Where(predicate.ToExpression())
.ToPage<CamWorkrecord, CamWorkrecordDto>(parm);
var ids = response.Result.Select(it => it.Id).ToList();
if (ids != null && ids.Count > 0)
{
var works = camWorkerService.AsQueryable().Where(it => ids.Contains(it.WorkrecordId)).ToList();
response.Result.ForEach(item =>
{
var w = works.Where(it => it.WorkrecordId == item.Id).Select(it => new CamWorkersDto { WorkerName = it.WorkerName, Id = it.Id }).ToList();
item.Workers = w;
if (w.Count > 0)
{
item.Worker = string.Join(",", w.Select(it => it.WorkerName).ToList());
}
else
{
item.Worker = "";
}
if (!string.IsNullOrEmpty(item.Remarks))
{
try
{
item.RemarksDic = JsonConvert.DeserializeObject<Dictionary<string, object>>(item.Remarks);
}
catch (Exception ex)
{
}
}
});
}
return response;
}
/// <summary>
/// 获取详情
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
public CamWorkrecord GetInfo(int Id)
{
var response = Queryable()
.Where(x => x.Id == Id)
.First();
return response;
}
/// <summary>
/// 添加工作记录
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public CamWorkrecord AddCamWorkrecord(CamWorkrecord model)
{
return Insertable(model).ExecuteReturnEntity();
}
/// <summary>
/// 修改工作记录
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int UpdateCamWorkrecord(CamWorkrecord model)
{
return Update(model, true, "修改工作记录");
}
/// <summary>
/// 导出工作记录
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public PagedInfo<CamWorkrecordExcelDto> ExportList(CamWorkrecordQueryDto parm)
{
parm.PageNum = 1;
parm.PageSize = 100000;
var predicate = QueryExp(parm);
var response = Queryable()
.Where(predicate.ToExpression())
.Select((it) => new CamWorkrecordExcelDto()
{
}, true)
.ToPage(parm);
var ids = response.Result.Select(it => it.Id).ToList();
if (ids != null && ids.Count > 0)
{
var works = camWorkerService.AsQueryable().Where(it => ids.Contains(it.WorkrecordId)).ToList();
response.Result.ForEach(item =>
{
var w = works.Where(it => it.WorkrecordId == item.Id).Select(it => it.WorkerName).ToList();
item.Workers = w;
if (!string.IsNullOrEmpty(item.Remarks))
{
try
{
//item.RemarksDic = JsonConvert.DeserializeObject<Dictionary<string, object>>(item.Remarks);
}
catch (Exception ex)
{
}
}
});
}
return response;
}
/// <summary>
/// 查询导出表达式
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
private static Expressionable<CamWorkrecord> QueryExp(CamWorkrecordQueryDto parm)
{
var predicate = Expressionable.Create<CamWorkrecord>();
//predicate = predicate.AndIF(parm.BeginRecordTime == null, it => it.RecordTime >= DateTime.Now.ToShortDateString().ParseToDateTime());
predicate = predicate.AndIF(parm.BeginRecordTime != null, it => it.RecordTime >= parm.BeginRecordTime);
predicate = predicate.AndIF(parm.EndRecordTime != null, it => it.RecordTime <= parm.EndRecordTime);
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.DeptName), it => it.DeptName == parm.DeptName);
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.Address), it => it.Address.Contains(parm.Address));
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.Content), it => it.Content.Contains(parm.Content));
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.StatusName), it => it.StatusName == parm.StatusName);
//camWorkerService.AsQueryable().Where(it => it.WorkerName.Contains(parm.Workrecord));
// 关键:根据子表 CamWorker 过滤
if (!string.IsNullOrEmpty(parm.Workrecord))
{
predicate = predicate.And(it =>
SqlFunc.Subqueryable<CamWorker>()
.Where(w => w.WorkrecordId == it.Id && w.WorkerName.Contains(parm.Workrecord))
.Any()
);
}
return predicate;
}
}
}

View File

@ -1,117 +0,0 @@
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
{
/// <summary>
/// 礼品申领表Service业务层处理
/// </summary>
[AppService(ServiceType = typeof(IGiftClaimService), ServiceLifetime = LifeTime.Transient)]
public class GiftClaimService : BaseService<GiftClaim>, IGiftClaimService
{
/// <summary>
/// 查询礼品申领表列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public PagedInfo<GiftClaimDto> GetList(GiftClaimQueryDto parm)
{
var predicate = QueryExp(parm);
var response = Queryable()
//.OrderBy("Id desc")
.Where(predicate.ToExpression())
.ToPage<GiftClaim, GiftClaimDto>(parm);
//response.Result.ForEach(item =>
//{
// if (item.ProductImage.IndexOf("http") == -1)
// {
// item.ProductImage = "" +
// }
//});
return response;
}
/// <summary>
/// 获取详情
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
public GiftClaim GetInfo(int Id)
{
var response = Queryable()
.Where(x => x.Id == Id)
.First();
return response;
}
/// <summary>
/// 添加礼品申领表
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public GiftClaim AddGiftClaim(GiftClaim model)
{
return Insertable(model).ExecuteReturnEntity();
}
/// <summary>
/// 修改礼品申领表
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int UpdateGiftClaim(GiftClaim model)
{
return Update(model, true);
}
/// <summary>
/// 导出礼品申领表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public PagedInfo<GiftClaimDto> 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<Model.System.SysDictData>("gift_request_claim"),
}, true)
.ToPage(parm);
return response;
}
/// <summary>
/// 查询导出表达式
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
private static Expressionable<GiftClaim> QueryExp(GiftClaimQueryDto parm)
{
var predicate = Expressionable.Create<GiftClaim>();
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;
}
}
}

View File

@ -1,104 +0,0 @@
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
{
/// <summary>
/// 微信用户表Service业务层处理
/// </summary>
[AppService(ServiceType = typeof(IGiftUserService), ServiceLifetime = LifeTime.Transient)]
public class GiftUserService : BaseService<GiftUser>, IGiftUserService
{
/// <summary>
/// 查询微信用户表列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public PagedInfo<GiftUserDto> GetList(GiftUserQueryDto parm)
{
var predicate = QueryExp(parm);
var response = Queryable()
//.OrderBy("Id desc")
.Where(predicate.ToExpression())
.ToPage<GiftUser, GiftUserDto>(parm);
return response;
}
/// <summary>
/// 获取详情
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
public GiftUser GetInfo(int Id)
{
var response = Queryable()
.Where(x => x.Id == Id)
.First();
return response;
}
/// <summary>
/// 添加微信用户表
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public GiftUser AddGiftUser(GiftUser model)
{
return Insertable(model).ExecuteReturnEntity();
}
/// <summary>
/// 修改微信用户表
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int UpdateGiftUser(GiftUser model)
{
return Update(model, true);
}
/// <summary>
/// 导出微信用户表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public PagedInfo<GiftUserDto> 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<Model.System.SysDictData>("sys_user_sex"),
StatusLabel = it.Status.GetConfigValue<Model.System.SysDictData>("sys_common_status"),
}, true)
.ToPage(parm);
return response;
}
/// <summary>
/// 查询导出表达式
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
private static Expressionable<GiftUser> QueryExp(GiftUserQueryDto parm)
{
var predicate = Expressionable.Create<GiftUser>();
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.Nickname), it => it.Nickname.Contains(parm.Nickname));
return predicate;
}
}
}

View File

@ -0,0 +1,21 @@
using ZR.Model.Business.Dto;
using ZR.Model.Business;
namespace ZR.Service.Business.IBusinessService
{
/// <summary>
/// 工作人员记录service接口
/// </summary>
public interface ICamWorkerService : IBaseService<CamWorker>
{
PagedInfo<CamWorkerDto> GetList(CamWorkerQueryDto parm);
CamWorker GetInfo(long Id);
CamWorker AddCamWorker(CamWorker parm);
int UpdateCamWorker(CamWorker parm);
}
}

View File

@ -0,0 +1,21 @@
using ZR.Model.Business.Dto;
using ZR.Model.Business;
namespace ZR.Service.Business.IBusinessService
{
/// <summary>
/// 月报表service接口
/// </summary>
public interface ICamWorkersService : IBaseService<CamWorkers>
{
List<WorkerMonthlyWorkDays> GetList(CamWorkersQueryDto parm);
CamWorkers GetInfo(long Id);
CamWorkers AddCamWorkers(CamWorkers parm);
List<WorkerMonthlyWorkDays> ExportList(CamWorkersQueryDto parm);
}
}

View File

@ -0,0 +1,21 @@
using ZR.Model.Business.Dto;
using ZR.Model.Business;
namespace ZR.Service.Business.IBusinessService
{
/// <summary>
/// 工作记录service接口
/// </summary>
public interface ICamWorkrecordService : IBaseService<CamWorkrecord>
{
PagedInfo<CamWorkrecordDto> GetList(CamWorkrecordQueryDto parm);
CamWorkrecord GetInfo(int Id);
CamWorkrecord AddCamWorkrecord(CamWorkrecord parm);
int UpdateCamWorkrecord(CamWorkrecord parm);
PagedInfo<CamWorkrecordExcelDto> ExportList(CamWorkrecordQueryDto parm);
}
}

View File

@ -1,22 +0,0 @@
using ZR.Model.Business.Dto;
using ZR.Model.Business;
namespace ZR.Service.Business.IBusinessService
{
/// <summary>
/// 礼品申领表service接口
/// </summary>
public interface IGiftClaimService : IBaseService<GiftClaim>
{
PagedInfo<GiftClaimDto> GetList(GiftClaimQueryDto parm);
GiftClaim GetInfo(int Id);
GiftClaim AddGiftClaim(GiftClaim parm);
int UpdateGiftClaim(GiftClaim parm);
PagedInfo<GiftClaimDto> ExportList(GiftClaimQueryDto parm);
}
}

View File

@ -1,21 +0,0 @@
using ZR.Model.Business.Dto;
using ZR.Model.Business;
namespace ZR.Service.Business.IBusinessService
{
/// <summary>
/// 礼品小程序service接口
/// </summary>
public interface IGiftConfigService : IBaseService<GiftConfig>
{
PagedInfo<GiftConfigDto> GetList(GiftConfigQueryDto parm);
GiftConfig GetInfo(int Id);
GiftConfig AddGiftConfig(GiftConfig parm);
int UpdateGiftConfig(GiftConfig parm);
}
}

View File

@ -1,22 +0,0 @@
using ZR.Model.Business.Dto;
using ZR.Model.Business;
namespace ZR.Service.Business.IBusinessService
{
/// <summary>
/// 微信用户表service接口
/// </summary>
public interface IGiftUserService : IBaseService<GiftUser>
{
PagedInfo<GiftUserDto> GetList(GiftUserQueryDto parm);
GiftUser GetInfo(int Id);
GiftUser AddGiftUser(GiftUser parm);
int UpdateGiftUser(GiftUser parm);
PagedInfo<GiftUserDto> ExportList(GiftUserQueryDto parm);
}
}

View File

@ -12,6 +12,7 @@
<ProjectReference Include="..\ZR.ServiceCore\ZR.ServiceCore.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Business\" />
<Folder Include="IService\" />
</ItemGroup>