diff --git a/Infrastructure/Helper/ExcelHelper.cs b/Infrastructure/Helper/ExcelHelper.cs
new file mode 100644
index 0000000..6e17d32
--- /dev/null
+++ b/Infrastructure/Helper/ExcelHelper.cs
@@ -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
+{
+ ///
+ /// Excel 导出帮助类(EPPlus)
+ ///
+ public class ExcelHelper
+ {
+ private readonly IWebHostEnvironment _webHostEnvironment;
+
+ ///
+ /// 构造函数,需要注入 IWebHostEnvironment 获取 web 根目录
+ ///
+ ///
+ public ExcelHelper(IWebHostEnvironment webHostEnvironment)
+ {
+ _webHostEnvironment = webHostEnvironment;
+ ExcelPackage.License.SetNonCommercialPersonal("pnaa");
+
+ }
+
+ ///
+ /// 导出 Excel 文件
+ ///
+ /// 数据类型
+ /// 数据列表
+ /// Sheet 名
+ /// 文件名,不含时间戳和后缀
+ /// 返回文件名和完整路径
+ public (string, string) ExportExcel(List 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 导入到 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);
+ }
+
+
+
+
+
+ }
+}
diff --git a/Infrastructure/ZR.Infrastructure.csproj b/Infrastructure/ZR.Infrastructure.csproj
index 998f38e..4d9e0a9 100644
--- a/Infrastructure/ZR.Infrastructure.csproj
+++ b/Infrastructure/ZR.Infrastructure.csproj
@@ -12,6 +12,7 @@
+
diff --git a/ZR.Admin.WebApi/Controllers/Business/CamWorkersController.cs b/ZR.Admin.WebApi/Controllers/Business/CamWorkersController.cs
new file mode 100644
index 0000000..ba80909
--- /dev/null
+++ b/ZR.Admin.WebApi/Controllers/Business/CamWorkersController.cs
@@ -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
+{
+ ///
+ /// 月报表
+ ///
+ [Route("business/CamWorkers")]
+ public class CamWorkersController : BaseController
+ {
+ ///
+ /// 月报表接口
+ ///
+ private readonly ICamWorkersService _CamWorkersService;
+
+ public CamWorkersController(ICamWorkersService CamWorkersService)
+ {
+ _CamWorkersService = CamWorkersService;
+ }
+
+ ///
+ /// 查询月报表列表
+ ///
+ ///
+ ///
+ [HttpGet("list")]
+ [ActionPermissionFilter(Permission = "camworkers:list")]
+ public IActionResult QueryCamWorkers([FromQuery] CamWorkersQueryDto parm)
+ {
+ var response = _CamWorkersService.GetList(parm);
+ return SUCCESS(response);
+ }
+
+
+ ///
+ /// 查询月报表详情
+ ///
+ ///
+ ///
+ [HttpGet("{Id}")]
+ [ActionPermissionFilter(Permission = "camworkers:query")]
+ public IActionResult GetCamWorkers(long Id)
+ {
+ var response = _CamWorkersService.GetInfo(Id);
+
+ var info = response.Adapt();
+ return SUCCESS(info);
+ }
+
+ ///
+ /// 导出月报表
+ ///
+ ///
+ [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);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/ZR.Admin.WebApi/Controllers/Business/CamWorkrecordController.cs b/ZR.Admin.WebApi/Controllers/Business/CamWorkrecordController.cs
index 165e25a..88e3dff 100644
--- a/ZR.Admin.WebApi/Controllers/Business/CamWorkrecordController.cs
+++ b/ZR.Admin.WebApi/Controllers/Business/CamWorkrecordController.cs
@@ -2,7 +2,21 @@ 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
{
@@ -17,9 +31,15 @@ namespace ZR.Admin.WebApi.Controllers.Business
///
private readonly ICamWorkrecordService _CamWorkrecordService;
- public CamWorkrecordController(ICamWorkrecordService CamWorkrecordService)
+ private OptionsSetting OptionsSetting;
+ private IWebHostEnvironment WebHostEnvironment;
+
+
+ public CamWorkrecordController(ICamWorkrecordService CamWorkrecordService, IOptions options, IWebHostEnvironment webHostEnvironment)
{
_CamWorkrecordService = CamWorkrecordService;
+ OptionsSetting = options.Value;
+ WebHostEnvironment = webHostEnvironment;
}
///
@@ -46,7 +66,7 @@ namespace ZR.Admin.WebApi.Controllers.Business
public IActionResult GetCamWorkrecord(int Id)
{
var response = _CamWorkrecordService.GetInfo(Id);
-
+
var info = response.Adapt();
return SUCCESS(info);
}
@@ -89,12 +109,155 @@ namespace ZR.Admin.WebApi.Controllers.Business
[HttpPost("delete/{ids}")]
[ActionPermissionFilter(Permission = "camworkrecord:delete")]
[Log(Title = "工作记录", BusinessType = BusinessType.DELETE)]
- public IActionResult DeleteCamWorkrecord([FromRoute]string ids)
+ public IActionResult DeleteCamWorkrecord([FromRoute] string ids)
{
var idArr = Tools.SplitAndConvert(ids);
return ToResponse(_CamWorkrecordService.Delete(idArr, "删除工作记录"));
}
+ ///
+ /// 导出工作记录
+ ///
+ ///
+ [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);
+ }
+
+ ///
+ public (string fileName, string fullPath) ExportWorkRecordExcel(List 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();
+ }
+ }
+ }
+
+
+ ///
+ /// 根据图片文件扩展名映射为 ContentType,避免类型不匹配导致 Excel 修复。
+ ///
+ 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 处理
+ };
+ }
}
}
\ No newline at end of file
diff --git a/ZR.Admin.WebApi/Controllers/CommonController.cs b/ZR.Admin.WebApi/Controllers/CommonController.cs
index 1d8be58..1efb907 100644
--- a/ZR.Admin.WebApi/Controllers/CommonController.cs
+++ b/ZR.Admin.WebApi/Controllers/CommonController.cs
@@ -15,7 +15,11 @@ 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
{
///
@@ -34,7 +38,6 @@ namespace ZR.Admin.WebApi.Controllers
public readonly ISysDeptService _deptService;
public readonly ISysDictDataService sysDictDataService;
- private string domainUrl = AppSettings.GetConfig("Upload:uploadUrl");
///
/// 工作记录接口
///
@@ -272,8 +275,8 @@ namespace ZR.Admin.WebApi.Controllers
//- 当日根据【工作内容】分类的照片
//- 当日根据【部门】分类的照片
var imageprx = ImageConverter.GetFileExtensionFromBase64(parm.Image);
- var imageName = ImageConverter.GenerateImageFileName(imageprx);
- var filePath = "/workfiles/" + DateTime.Now.ToString("yyyy/yyyyMMdd");
+
+ var filePath = "/workfiles/" + DateTime.Now.ToString("yyyyMM/yyyyMMdd");
string savePath = Path.Combine(WebHostEnvironment.WebRootPath);
var path = savePath + filePath;
var images = ImageConverter.Base64ToImageBytes(parm.Image);
@@ -281,6 +284,14 @@ namespace ZR.Admin.WebApi.Controllers
{
return ToResponse(ResultCode.CUSTOM_ERROR, "图片上传失败");
}
+ int MaxSize = 300 * 1024; // 300KB = 307200 字节
+ // 如果图片大于300KB才压缩
+ if (images.Length > MaxSize)
+ {
+ images = CompressImage(images, 70); // 压缩质量 70
+ imageprx = ".jpg";
+ }
+ var imageName = ImageConverter.GenerateImageFileName(imageprx);
var participantsUrl = $"{path}/参与人员/";
var photosDay = $"{path}/当日照片/";
var jobContent = $"{path}/工作内容/";
@@ -331,6 +342,7 @@ namespace ZR.Admin.WebApi.Controllers
{
await stream.WriteAsync(images, 0, images.Length);
}
+ var domainUrl = $"{OptionsSetting.Upload.UploadUrl}";
//备份一下本地
var modal = parm.Adapt().ToCreate(HttpContext);
modal.CreateTime = DateTime.Now;
@@ -353,5 +365,54 @@ namespace ZR.Admin.WebApi.Controllers
_CamWorkerService.AsInsertable(workers).ExecuteCommand();
return SUCCESS(1);
}
+
+ [HttpGet]
+ [Route("/getDownloadZip")]
+ [AllowAnonymous]
+ public async Task DownloadZip([FromQuery] string? yearMoney)
+ {
+ if (string.IsNullOrEmpty(yearMoney))
+ {
+ 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();
+ }
+ }
+ }
}
}
diff --git a/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj b/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj
index 140ad7d..02a1cf9 100644
--- a/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj
+++ b/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj
@@ -45,6 +45,7 @@
+
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/参与人员/张三/1755531373_7849.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/参与人员/张三/1755531373_7849.jpg
deleted file mode 100644
index 9a41ca5..0000000
Binary files a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/参与人员/张三/1755531373_7849.jpg and /dev/null differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/参与人员/李四/1755531373_7849.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/参与人员/李四/1755531373_7849.jpg
deleted file mode 100644
index 9a41ca5..0000000
Binary files a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/参与人员/李四/1755531373_7849.jpg and /dev/null differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/参与人员/脾气/1755531044_7059.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/参与人员/脾气/1755531044_7059.jpg
deleted file mode 100644
index 63f2785..0000000
Binary files a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/参与人员/脾气/1755531044_7059.jpg and /dev/null differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/工作内容/泡三/1755531044_7059.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/工作内容/泡三/1755531044_7059.jpg
deleted file mode 100644
index 63f2785..0000000
Binary files a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/工作内容/泡三/1755531044_7059.jpg and /dev/null differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/工作内容/测试1/1755531373_7849.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/工作内容/测试1/1755531373_7849.jpg
deleted file mode 100644
index 9a41ca5..0000000
Binary files a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/工作内容/测试1/1755531373_7849.jpg and /dev/null differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/当日照片/1755531044_7059.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/当日照片/1755531044_7059.jpg
deleted file mode 100644
index 63f2785..0000000
Binary files a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/当日照片/1755531044_7059.jpg and /dev/null differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/当日照片/1755531373_7849.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/当日照片/1755531373_7849.jpg
deleted file mode 100644
index 9a41ca5..0000000
Binary files a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/当日照片/1755531373_7849.jpg and /dev/null differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/部门/研发部门/1755531044_7059.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/部门/研发部门/1755531044_7059.jpg
deleted file mode 100644
index 63f2785..0000000
Binary files a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/部门/研发部门/1755531044_7059.jpg and /dev/null differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/部门/研发部门/1755531373_7849.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/部门/研发部门/1755531373_7849.jpg
deleted file mode 100644
index 9a41ca5..0000000
Binary files a/ZR.Admin.WebApi/wwwroot/workfiles/2025/20250818/部门/研发部门/1755531373_7849.jpg and /dev/null differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/张三/1755617080_7078.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/张三/1755617080_7078.jpg
new file mode 100644
index 0000000..593533f
Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/张三/1755617080_7078.jpg differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/张三/1755617093_1631.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/张三/1755617093_1631.jpg
new file mode 100644
index 0000000..e4a74ed
Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/张三/1755617093_1631.jpg differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/李四/1755617080_7078.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/李四/1755617080_7078.jpg
new file mode 100644
index 0000000..593533f
Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/李四/1755617080_7078.jpg differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/李四/1755617093_1631.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/李四/1755617093_1631.jpg
new file mode 100644
index 0000000..e4a74ed
Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/李四/1755617093_1631.jpg differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/王五/1755617080_7078.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/王五/1755617080_7078.jpg
new file mode 100644
index 0000000..593533f
Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/王五/1755617080_7078.jpg differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/王五/1755617093_1631.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/王五/1755617093_1631.jpg
new file mode 100644
index 0000000..e4a74ed
Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/参与人员/王五/1755617093_1631.jpg differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/工作内容/测试/1755617080_7078.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/工作内容/测试/1755617080_7078.jpg
new file mode 100644
index 0000000..593533f
Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/工作内容/测试/1755617080_7078.jpg differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/工作内容/测试/1755617093_1631.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/工作内容/测试/1755617093_1631.jpg
new file mode 100644
index 0000000..e4a74ed
Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/工作内容/测试/1755617093_1631.jpg differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/当日照片/1755617080_7078.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/当日照片/1755617080_7078.jpg
new file mode 100644
index 0000000..593533f
Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/当日照片/1755617080_7078.jpg differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/当日照片/1755617093_1631.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/当日照片/1755617093_1631.jpg
new file mode 100644
index 0000000..e4a74ed
Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/当日照片/1755617093_1631.jpg differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/部门/研发部门/1755617080_7078.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/部门/研发部门/1755617080_7078.jpg
new file mode 100644
index 0000000..593533f
Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/部门/研发部门/1755617080_7078.jpg differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/部门/研发部门/1755617093_1631.jpg b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/部门/研发部门/1755617093_1631.jpg
new file mode 100644
index 0000000..e4a74ed
Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/workfiles/202508/20250819/部门/研发部门/1755617093_1631.jpg differ
diff --git a/ZR.Admin.WebApi/wwwroot/workfiles/temp/202508.zip b/ZR.Admin.WebApi/wwwroot/workfiles/temp/202508.zip
new file mode 100644
index 0000000..ec6e891
Binary files /dev/null and b/ZR.Admin.WebApi/wwwroot/workfiles/temp/202508.zip differ
diff --git a/ZR.Model/Business/CamWorkers.cs b/ZR.Model/Business/CamWorkers.cs
new file mode 100644
index 0000000..b170b3c
--- /dev/null
+++ b/ZR.Model/Business/CamWorkers.cs
@@ -0,0 +1,37 @@
+
+namespace ZR.Model.Business
+{
+ ///
+ /// 月报表
+ ///
+ [SugarTable("cam_workers")]
+ public class CamWorkers
+ {
+ ///
+ /// Id
+ ///
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
+ public long Id { get; set; }
+
+ ///
+ /// WorkrecordId
+ ///
+ public int WorkrecordId { get; set; }
+
+ ///
+ /// WorkerName
+ ///
+ public string WorkerName { get; set; }
+
+ ///
+ /// WorkerDay
+ ///
+ public int WorkerDay { get; set; }
+
+ ///
+ /// CreateTime
+ ///
+ public DateTime? CreateTime { get; set; }
+
+ }
+}
\ No newline at end of file
diff --git a/ZR.Model/Business/Dto/CamWorkerDto.cs b/ZR.Model/Business/Dto/CamWorkerDto.cs
index 31cde2c..bf995c0 100644
--- a/ZR.Model/Business/Dto/CamWorkerDto.cs
+++ b/ZR.Model/Business/Dto/CamWorkerDto.cs
@@ -4,7 +4,7 @@ namespace ZR.Model.Business.Dto
///
/// 工作人员记录查询对象
///
- public class CamWorkerQueryDto : PagerInfo
+ public class CamWorkerQueryDto : PagerInfo
{
}
@@ -28,5 +28,22 @@ namespace ZR.Model.Business.Dto
+ }
+
+
+ ///
+ /// 工作人员记录输入输出对象
+ ///
+ public class CamWorkersDto
+ {
+ [Required(ErrorMessage = "主键不能为空")]
+ public long Id { get; set; }
+
+
+
+ [Required(ErrorMessage = "人员不能为空")]
+ public string WorkerName { get; set; }
+
+
}
}
\ No newline at end of file
diff --git a/ZR.Model/Business/Dto/CamWorkersDto.cs b/ZR.Model/Business/Dto/CamWorkersDto.cs
new file mode 100644
index 0000000..7c20ba8
--- /dev/null
+++ b/ZR.Model/Business/Dto/CamWorkersDto.cs
@@ -0,0 +1,81 @@
+
+namespace ZR.Model.Business.Dto
+{
+ ///
+ /// 月报表查询对象
+ ///
+ public class CamWorkersQueryDto
+ {
+ public string WorkerName { get; set; }
+ public string YearMonth { get; set; }
+ }
+
+ ///
+ /// 月报表输入输出对象
+ ///
+ 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; }
+
+
+
+ }
+
+ ///
+ /// 每月员工工作天数统计结果
+ ///
+ public class WorkerMonthlyWorkDays
+ {
+ ///
+ /// 年月(格式:yyyy-MM)
+ ///
+ [ExcelColumn(Name = "月份")]
+ [ExcelColumnName("月份")]
+ public string YearMonth { get; set; }
+
+ ///
+ /// 部门名称
+ ///
+ [ExcelColumn(Name = "部门名称")]
+ [ExcelColumnName("部门名称")]
+ public string DeptName { get; set; }
+
+ ///
+ /// 员工姓名
+ ///
+ [ExcelColumn(Name = "员工姓名")]
+ [ExcelColumnName("员工姓名")]
+ public string WorkerName { get; set; }
+
+ ///
+ /// 当月工作天数
+ ///
+ [ExcelColumn(Name = "当月工作天数")]
+ [ExcelColumnName("当月工作天数")]
+ public int WorkDays { get; set; }
+ }
+
+}
\ No newline at end of file
diff --git a/ZR.Model/Business/Dto/CamWorkrecordDto.cs b/ZR.Model/Business/Dto/CamWorkrecordDto.cs
index fefca1c..6821cf4 100644
--- a/ZR.Model/Business/Dto/CamWorkrecordDto.cs
+++ b/ZR.Model/Business/Dto/CamWorkrecordDto.cs
@@ -10,6 +10,8 @@ namespace ZR.Model.Business.Dto
public string Address { get; set; }
public string Content { get; set; }
public string StatusName { get; set; }
+ public DateTime? BeginRecordTime { get; set; }
+ public DateTime? EndRecordTime { get; set; }
}
///
@@ -42,7 +44,17 @@ namespace ZR.Model.Business.Dto
public DateTime? UpdateTime { get; set; }
+ public Dictionary RemarksDic { get; set; }
+ ///
+ /// 施工人员
+ ///
+ public List Workers { get; set; }
+
+ ///
+ /// 施工人员
+ ///
+ public string Worker { get; set; }
[ExcelColumn(Name = "状态")]
public string StatusNameLabel { get; set; }
@@ -103,4 +115,82 @@ namespace ZR.Model.Business.Dto
///
public List Workers { get; set; }
}
+
+ ///
+ /// 工作记录输入输出对象
+ ///
+ 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; }
+
+ ///
+ ///
+ ///
+ [ExcelIgnore]
+ public List 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; }
+
+
+ }
+
}
\ No newline at end of file
diff --git a/ZR.Service/Business/CamWorkersService.cs b/ZR.Service/Business/CamWorkersService.cs
new file mode 100644
index 0000000..ade35e0
--- /dev/null
+++ b/ZR.Service/Business/CamWorkersService.cs
@@ -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
+{
+ ///
+ /// 月报表Service业务层处理
+ ///
+ [AppService(ServiceType = typeof(ICamWorkersService), ServiceLifetime = LifeTime.Transient)]
+ public class CamWorkersService : BaseService, ICamWorkersService
+ {
+ private readonly ICamWorkrecordService _camWorkrecordService;
+ private readonly ICamWorkerService _camWorkerService;
+ public CamWorkersService(ICamWorkrecordService camWorkrecordService, ICamWorkerService camWorkerService)
+ {
+
+
+ _camWorkrecordService = camWorkrecordService;
+ _camWorkerService = camWorkerService;
+ }
+ ///
+ /// 查询月报表列表
+ ///
+ ///
+ ///
+ public List 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($@"
+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 1=1 {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(parm);
+
+ return list;
+ }
+
+
+ ///
+ /// 获取详情
+ ///
+ ///
+ ///
+ public CamWorkers GetInfo(long Id)
+ {
+ var response = Queryable()
+ .Where(x => x.Id == Id)
+ .First();
+
+ return response;
+ }
+
+ ///
+ /// 添加月报表
+ ///
+ ///
+ ///
+ public CamWorkers AddCamWorkers(CamWorkers model)
+ {
+ return Insertable(model).ExecuteReturnEntity();
+ }
+
+ ///
+ /// 导出月报表
+ ///
+ ///
+ ///
+ public List ExportList(CamWorkersQueryDto parm)
+ {
+ return GetList(parm);
+ }
+
+ ///
+ /// 查询导出表达式
+ ///
+ ///
+ ///
+ private static Expressionable QueryExp(CamWorkersQueryDto parm)
+ {
+ var predicate = Expressionable.Create();
+
+ return predicate;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ZR.Service/Business/CamWorkrecordService.cs b/ZR.Service/Business/CamWorkrecordService.cs
index f0e26ca..e1a2b5c 100644
--- a/ZR.Service/Business/CamWorkrecordService.cs
+++ b/ZR.Service/Business/CamWorkrecordService.cs
@@ -4,6 +4,7 @@ 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
{
@@ -13,6 +14,13 @@ namespace ZR.Service.Business
[AppService(ServiceType = typeof(ICamWorkrecordService), ServiceLifetime = LifeTime.Transient)]
public class CamWorkrecordService : BaseService, ICamWorkrecordService
{
+
+ private ICamWorkerService camWorkerService;
+ public CamWorkrecordService(ICamWorkerService camWorkerService)
+ {
+ this.camWorkerService = camWorkerService;
+ }
+
///
/// 查询工作记录列表
///
@@ -23,10 +31,39 @@ namespace ZR.Service.Business
var predicate = QueryExp(parm);
var response = Queryable()
- //.OrderBy("Id desc")
+ .OrderBy("Id desc")
.Where(predicate.ToExpression())
.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 => 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>(item.Remarks);
+ }
+ catch (Exception ex)
+ {
+ }
+ }
+ });
+
+ }
return response;
}
@@ -65,6 +102,50 @@ namespace ZR.Service.Business
return Update(model, true, "修改工作记录");
}
+ ///
+ /// 导出工作记录
+ ///
+ ///
+ ///
+ public PagedInfo 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>(item.Remarks);
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }
+ });
+
+ }
+ return response;
+ }
+
///
/// 查询导出表达式
///
@@ -74,6 +155,9 @@ namespace ZR.Service.Business
{
var predicate = Expressionable.Create();
+ //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));
diff --git a/ZR.Service/Business/IBusinessService/ICamWorkersService.cs b/ZR.Service/Business/IBusinessService/ICamWorkersService.cs
new file mode 100644
index 0000000..51f4854
--- /dev/null
+++ b/ZR.Service/Business/IBusinessService/ICamWorkersService.cs
@@ -0,0 +1,21 @@
+using ZR.Model.Business.Dto;
+using ZR.Model.Business;
+
+namespace ZR.Service.Business.IBusinessService
+{
+ ///
+ /// 月报表service接口
+ ///
+ public interface ICamWorkersService : IBaseService
+ {
+ List GetList(CamWorkersQueryDto parm);
+
+ CamWorkers GetInfo(long Id);
+
+
+ CamWorkers AddCamWorkers(CamWorkers parm);
+
+
+ List ExportList(CamWorkersQueryDto parm);
+ }
+}
diff --git a/ZR.Service/Business/IBusinessService/ICamWorkrecordService.cs b/ZR.Service/Business/IBusinessService/ICamWorkrecordService.cs
index 96d33ac..a0f3e6c 100644
--- a/ZR.Service/Business/IBusinessService/ICamWorkrecordService.cs
+++ b/ZR.Service/Business/IBusinessService/ICamWorkrecordService.cs
@@ -16,6 +16,6 @@ namespace ZR.Service.Business.IBusinessService
CamWorkrecord AddCamWorkrecord(CamWorkrecord parm);
int UpdateCamWorkrecord(CamWorkrecord parm);
-
+ PagedInfo ExportList(CamWorkrecordQueryDto parm);
}
}