2026-01-14 16:50:40 +08:00
|
|
|
|
using OpenAuth.App.BaseApp.Base;
|
|
|
|
|
|
using OpenAuth.Repository.Domain.FireManagement;
|
|
|
|
|
|
using OpenAuth.Repository;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using OpenAuth.Repository.Domain;
|
|
|
|
|
|
using Microsoft.Extensions.Options;
|
|
|
|
|
|
using OpenAuth.App.Common;
|
|
|
|
|
|
using OpenAuth.App.Interface;
|
|
|
|
|
|
using SqlSugar;
|
|
|
|
|
|
using System.Net.WebSockets;
|
|
|
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
|
|
using Infrastructure;
|
|
|
|
|
|
using OpenAuth.App.ServiceApp.FireManagement.Request;
|
|
|
|
|
|
using OpenAuth.App.ServiceApp.FmPreventionPlanManage.Request;
|
2026-01-15 11:38:11 +08:00
|
|
|
|
using Yitter.IdGenerator;
|
|
|
|
|
|
using OpenAuth.App.Const;
|
2026-01-29 11:13:58 +08:00
|
|
|
|
using NetTopologySuite.Geometries;
|
|
|
|
|
|
using NetTopologySuite.IO;
|
|
|
|
|
|
using System.IO.Compression;
|
|
|
|
|
|
using Org.BouncyCastle.Ocsp;
|
|
|
|
|
|
using DocumentFormat.OpenXml.EMMA;
|
|
|
|
|
|
using DocumentFormat.OpenXml.Office2010.Excel;
|
2026-01-30 11:11:39 +08:00
|
|
|
|
using DocumentFormat.OpenXml.Spreadsheet;
|
2026-01-14 16:50:40 +08:00
|
|
|
|
|
|
|
|
|
|
namespace OpenAuth.App.ServiceApp.FmPreventionPlanManage
|
|
|
|
|
|
{
|
|
|
|
|
|
public class FmPreventionPlanApp : SqlSugarBaseApp<FmPreventionplan, SugarDbContext>
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
private ClientWebSocket _socket;
|
|
|
|
|
|
private IConfiguration _configuration;
|
|
|
|
|
|
|
|
|
|
|
|
public FmPreventionPlanApp(IConfiguration configuration, ISugarUnitOfWork<SugarDbContext> unitWork,ISimpleClient<FmPreventionplan> repository, IAuth auth) : base(unitWork, repository, auth)
|
|
|
|
|
|
{
|
|
|
|
|
|
_auth = auth;
|
|
|
|
|
|
_configuration = configuration;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 分页查询预案列表
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public async Task<Response<PageInfo<List<FmPreventionplan>>>> GetPreventionplanPageList(FmPreventionplanReq req)
|
|
|
|
|
|
{
|
|
|
|
|
|
using (var db = base.UnitWork.CreateContext())
|
|
|
|
|
|
{
|
|
|
|
|
|
RefAsync<int> totalNumber = 0;
|
|
|
|
|
|
var infos = await db.FmPreventionplan.AsQueryable()
|
2026-01-15 11:38:11 +08:00
|
|
|
|
.Where(r=>r.IsDelete==false)
|
2026-01-14 16:50:40 +08:00
|
|
|
|
.WhereIF(req.state != null, r => r.Status == req.state)
|
|
|
|
|
|
.WhereIF(req.plancategory != null, r => r.PlanCategory == req.plancategory)
|
|
|
|
|
|
.WhereIF(req.createtimebegin != null && req.createtimeend != null, r => r.CreateTime >= req.createtimebegin && r.CreateTime <= req.createtimeend)
|
|
|
|
|
|
.WhereIF(!string.IsNullOrEmpty(req.name), r => r.PlanName.Contains(req.name))
|
|
|
|
|
|
.WhereIF(!string.IsNullOrEmpty(req.code), r => r.PlanCode.Contains(req.code))
|
|
|
|
|
|
.ToPageListAsync(req.page, req.limit, totalNumber);
|
|
|
|
|
|
return new Response<PageInfo<List<FmPreventionplan>>>
|
|
|
|
|
|
{
|
|
|
|
|
|
Result = new PageInfo<List<FmPreventionplan>> { Items = infos, Total = totalNumber }
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 查询应急预案详情
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public async Task<Response<FmPreventionplan>> LoadClueInfoById(string id)
|
|
|
|
|
|
{
|
|
|
|
|
|
using (var db = base.UnitWork.CreateContext())
|
|
|
|
|
|
{
|
|
|
|
|
|
var info = await db.FmPreventionplan.AsQueryable()
|
|
|
|
|
|
.FirstAsync(r => r.Id == id);
|
|
|
|
|
|
return new Response<FmPreventionplan> { Result = info };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-01-15 11:38:11 +08:00
|
|
|
|
//删除应急预案
|
|
|
|
|
|
public async Task<Response<bool>> DeletePreventionplan(string id)
|
|
|
|
|
|
{
|
|
|
|
|
|
using (var db = base.UnitWork.CreateContext())
|
|
|
|
|
|
{
|
|
|
|
|
|
var taskinfo = await db.FmPreventionplan.AsQueryable().FirstAsync(r => r.Id == id);
|
|
|
|
|
|
if (taskinfo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var flag=await db.FmPreventionplan.UpdateAsync(r => new FmPreventionplan
|
|
|
|
|
|
{
|
|
|
|
|
|
IsDelete = true
|
|
|
|
|
|
}, r => r.Id == id);
|
|
|
|
|
|
if (db.Commit()&&flag)
|
|
|
|
|
|
{
|
|
|
|
|
|
return new Response<bool> { Result = true, Message = "操作成功" };
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return new Response<bool> { Result = false, Message = "操作失败" };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return new Response<bool> { Result = false, Message = "预案不存在" };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//添加预案
|
2026-01-29 11:13:58 +08:00
|
|
|
|
public async Task<Response<bool>> AddPreventionplan(PrePlanAddReq req)
|
2026-01-15 11:38:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
using (var db = base.UnitWork.CreateContext())
|
|
|
|
|
|
{
|
2026-01-29 11:13:58 +08:00
|
|
|
|
FmPreventionplan info = req.MapTo<FmPreventionplan>();
|
2026-01-15 11:38:11 +08:00
|
|
|
|
var user = _auth.GetCurrentUser().User;
|
|
|
|
|
|
info.Id = Guid.NewGuid().ToString();
|
|
|
|
|
|
info.CreateTime = DateTime.Now;
|
|
|
|
|
|
info.CreateUser = user.Name;
|
|
|
|
|
|
info.IsDelete = false;
|
|
|
|
|
|
if (string.IsNullOrEmpty(info.PlanCode))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("请输入预案编号");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var exitinfo = db.FmPreventionplan
|
|
|
|
|
|
.AsQueryable()
|
|
|
|
|
|
.Count(a => a.PlanCode==info.PlanCode);
|
|
|
|
|
|
if (exitinfo > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("预案编号已存在,请重新输入");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-29 11:13:58 +08:00
|
|
|
|
FmPrePlanGeom geom = new FmPrePlanGeom();
|
2026-01-30 11:11:39 +08:00
|
|
|
|
geom.Id = Guid.NewGuid().ToString();
|
2026-01-29 11:13:58 +08:00
|
|
|
|
geom.PrePlanId = info.Id;
|
|
|
|
|
|
|
|
|
|
|
|
string _wktModel = req.geom;
|
|
|
|
|
|
|
|
|
|
|
|
geom.geom = null;
|
2026-01-30 11:11:39 +08:00
|
|
|
|
if (!string.IsNullOrEmpty(req.geom))
|
2026-01-15 11:38:11 +08:00
|
|
|
|
{
|
2026-01-30 11:11:39 +08:00
|
|
|
|
StringBuilder geomSql = new StringBuilder();
|
|
|
|
|
|
geomSql.AppendFormat(
|
|
|
|
|
|
$" update fm_preplangeom set \"geom\" = st_geomfromtext('{_wktModel}',4326) where \"Id\" = '{geom.Id}'");
|
|
|
|
|
|
var flag = await db.FmPreventionplan.InsertAsync(info);
|
|
|
|
|
|
var geomflag = await db.FmPrePlanGeom.InsertAsync(geom);
|
|
|
|
|
|
// 然后更新几何字段
|
|
|
|
|
|
if (flag && geomflag)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 等待异步操作完成
|
|
|
|
|
|
var affectedRows = await db.Db.Ado.ExecuteCommandAsync(geomSql.ToString());
|
|
|
|
|
|
|
|
|
|
|
|
if (affectedRows > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (db.Commit())
|
|
|
|
|
|
{
|
|
|
|
|
|
return new Response<bool> { Result = true, Message = "操作成功" };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-01-15 11:38:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2026-01-30 11:11:39 +08:00
|
|
|
|
// 如果没有几何数据,只插入主记录
|
|
|
|
|
|
var flag = await db.FmPreventionplan.InsertAsync(info);
|
|
|
|
|
|
var geomFlag = await db.FmPrePlanGeom.InsertAsync(geom);
|
|
|
|
|
|
|
|
|
|
|
|
if (flag && geomFlag && db.Commit())
|
|
|
|
|
|
{
|
|
|
|
|
|
return new Response<bool> { Result = true, Message = "操作成功" };
|
|
|
|
|
|
}
|
2026-01-15 11:38:11 +08:00
|
|
|
|
}
|
2026-01-30 11:11:39 +08:00
|
|
|
|
|
|
|
|
|
|
// 如果执行到这里,说明操作失败
|
|
|
|
|
|
return new Response<bool> { Result = false, Message = "操作失败" };
|
2026-01-15 11:38:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-01-29 11:13:58 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region 备用代码
|
|
|
|
|
|
//添加预案范围
|
|
|
|
|
|
private async Task<StringBuilder> ReadShapefile(string zipFilePath, string Id)
|
|
|
|
|
|
{
|
|
|
|
|
|
var extractPath = zipFilePath.Substring(0, zipFilePath.LastIndexOf(".")) + "extract";
|
|
|
|
|
|
//解压缩
|
|
|
|
|
|
await UnZip(zipFilePath, extractPath);
|
|
|
|
|
|
var searchPattern = "*.shp"; // 设置你想要遍历的文件后缀名
|
|
|
|
|
|
var fileName = Directory.GetFiles(extractPath, searchPattern, SearchOption.AllDirectories);
|
|
|
|
|
|
string shpFileName = fileName[0];
|
|
|
|
|
|
// 创建一个 ShapefileDataReader 对象
|
|
|
|
|
|
using (var reader = new ShapefileDataReader(shpFileName, GeometryFactory.Default))
|
|
|
|
|
|
{
|
|
|
|
|
|
StringBuilder geomSql = new StringBuilder();
|
|
|
|
|
|
while (reader.Read())
|
|
|
|
|
|
{
|
|
|
|
|
|
// 获取几何数据
|
|
|
|
|
|
Geometry geometry = reader.Geometry;
|
|
|
|
|
|
if (!geometry.IsValid)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("图斑未闭合,请重新整理数据");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果几何数据是一个多边形(Polygon),需要转换为 MultiPolygon
|
|
|
|
|
|
MultiPolygon multiPolygon;
|
|
|
|
|
|
if (geometry is Polygon polygon)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 单个Polygon转MultiPolygon
|
|
|
|
|
|
multiPolygon = new MultiPolygon(new[] { polygon });
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (geometry is MultiPolygon existingMultiPolygon)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 如果已经是MultiPolygon,直接使用
|
|
|
|
|
|
multiPolygon = existingMultiPolygon;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 如果是其他类型的几何图形,可以根据需求进行处理
|
|
|
|
|
|
throw new Exception("几何图形不是多边形或多重多边形类型");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 将几何数据转换为 WKT 格式,并用 SRID 4326
|
|
|
|
|
|
var geometryForWgs84 = multiPolygon.Copy();
|
|
|
|
|
|
geometryForWgs84.SRID = 4326;
|
|
|
|
|
|
//var geometryForWgs84 = GeometryFactory.Default.WithSRID(4326).CreateGeometry(geometry);
|
|
|
|
|
|
geomSql.AppendFormat(
|
|
|
|
|
|
$" update drone_shp_data set geom = '{geometryForWgs84.AsText()}' where \"relid\" = '{Id}';");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return geomSql;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static async Task UnZip(string zipFilePath, string extractPath)
|
|
|
|
|
|
{
|
|
|
|
|
|
await Task.Run(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
Directory.CreateDirectory(extractPath);
|
|
|
|
|
|
// 设置字符编码
|
|
|
|
|
|
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
|
|
|
|
|
var gbk = Encoding.GetEncoding("utf-8");
|
|
|
|
|
|
using (var archive = ZipFile.OpenRead(zipFilePath))
|
|
|
|
|
|
{
|
|
|
|
|
|
// 列举ZIP文件中的条目
|
|
|
|
|
|
foreach (var entry in archive.Entries)
|
|
|
|
|
|
{
|
|
|
|
|
|
var xxx = gbk.GetString(Encoding.Default.GetBytes(entry.FullName));
|
|
|
|
|
|
Console.WriteLine(xxx);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 提取ZIP文件中的所有文件到指定目录
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var entry in archive.Entries)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (entry.Name != string.Empty)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 确保完整路径存在 entry.FullName 是否可以编码
|
|
|
|
|
|
var fixedEntryName = entry.FullName.Replace("/", "");
|
|
|
|
|
|
var destinationPath =
|
|
|
|
|
|
System.IO.Path.GetFullPath(System.IO.Path.Combine(extractPath, fixedEntryName));
|
|
|
|
|
|
Console.WriteLine("解压文件路径:" + destinationPath);
|
|
|
|
|
|
if (!destinationPath.StartsWith(System.IO.Path.GetFullPath(extractPath) +
|
|
|
|
|
|
System.IO.Path.DirectorySeparatorChar))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new UnauthorizedAccessException("试图提取的文件超出了目标文件夹的路径边界。");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 提取条目到目标路径
|
|
|
|
|
|
entry.ExtractToFile(destinationPath, overwrite: true);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 遍历解压目录,是否有shp后缀的文件
|
|
|
|
|
|
if (!Directory.Exists(extractPath))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("文件解压失败");
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
2026-01-14 16:50:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|