using DocumentFormat.OpenXml.Bibliography; using DocumentFormat.OpenXml.Office2016.Excel; using DocumentFormat.OpenXml.Spreadsheet; using DocumentFormat.OpenXml.Wordprocessing; using Infrastructure; using Infrastructure.Utils; using NetTopologySuite; using NetTopologySuite.Features; using NetTopologySuite.Geometries; using NetTopologySuite.IO; using Newtonsoft.Json.Linq; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using OpenAuth.App.Base.Tree; using OpenAuth.App.BaseApp.Base; using OpenAuth.App.FormModule; using OpenAuth.App.Interface; using OpenAuth.App.Request; using OpenAuth.App.ServiceApp.DataMaintenance.Request; using OpenAuth.Repository; using OpenAuth.Repository.Core; using OpenAuth.Repository.Domain.DataMaintenance; using Org.BouncyCastle.Asn1.Cms; using Org.BouncyCastle.Ocsp; using SqlSugar; using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Dynamic; using System.IO.Compression; using System.Linq; using System.Reflection.PortableExecutable; using System.Text; using System.Threading.Tasks; using Yitter.IdGenerator; using static NPOI.HSSF.UserModel.HeaderFooter; namespace OpenAuth.App.ServiceApp.DataMaintenance { /// /// 应用管理 /// public class ApplicationManagementApp : SqlSugarBaseApp { public ApplicationManagementApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) : base(unitWork, repository, auth) { _auth = auth; } /// /// 获取应用列表 /// /// /// public async Task>> GetApplicationList(string name, int isCatalogue) { using (var db = UnitWork.CreateContext()) { var user = _auth.GetCurrentUser().User; var result = new Response>(); // 使用参数化 var level = await db.Db.Ado.GetIntAsync("select min(\"Level\") from sys_userorg where \"UserId\" = @userId", new { userId = user.Id }); // 构建基础查询 var baseQuery = db.ApplicationData.AsQueryable(); // 根据用户级别过滤数据 if (level > 0) { var orgs = await db.SysUserOrg.AsQueryable() .Where(a => a.UserId == user.Id) .Select(a => a.OrgId) .ToListAsync(); var userIds = await db.SysUserOrg.AsQueryable() .Where(a => orgs.Contains(a.OrgId)) .Select(a => a.UserId) .ToListAsync(); baseQuery = baseQuery.Where(r => userIds.Contains(r.CreateUserId)); } // 应用名称过滤 if (!string.IsNullOrEmpty(name)) { baseQuery = baseQuery.Where(a => a.ApplicationName.Contains(name)); } //服务过滤 if (isCatalogue != 0) { baseQuery = baseQuery.Where(a => a.IsServer == 0); } // 执行查询并构建树形结构 var query = await baseQuery.Select().ToListAsync(); result.Result = UtilMethods.BuildTree(db.Db, query, "Id", "Pid", "Child", 0).ToList(); return result; } } //添加应用 public async Task> Add(ApplicationData app) { using (var db = UnitWork.CreateContext()) { app.Id = YitIdHelper.NextId(); app.CreateUserId = _auth.GetCurrentUser().User.Id; app.CreateTime = DateTime.Now; if (await db.ApplicationData.AsInsertable(app).ExecuteCommandAsync() > 0) { if (app.IsServer == 1) { //先插入一条数据 var geography = NtsGeometryServices.Instance.CreateGeometryFactory(4326); var point = geography.CreatePoint(new Coordinate(0, 0)); await db.Db.InsertableByDynamic(new { Id = 0, geom = point.AsText() }).AS(app.TableName).ExecuteCommandAsync(); var response = await GeoUtil.CreateStoreAndLayer("", "EPSG:4326", app.TableName, ""); if (response) { //删除数据 await db.Db.Deleteable().AS(app.TableName).Where("\"Id\"=@Id", new { Id = 0 }).ExecuteCommandAsync(); } } if (db.Commit()) { return new Response { Result = true }; } else { return new Response { Result = false, Message = "添加失败" }; } } else return new Response { Result = false, Message = "添加失败" }; } } //编辑应用 public async Task> Update(ApplicationData app) { if (await Repository.AsUpdateable(app).UpdateColumns(r => new ApplicationData { ApplicationName = app.ApplicationName, ServerId = app.ServerId, ServerName = app.ServerName, Sort = app.Sort, Pid = app.Pid, TableName = app.TableName, IsServer = app.IsServer, ServerType = app.ServerType, }).ExecuteCommandAsync() > 0) return new Response { Result = true }; else return new Response { Result = false, Message = "编辑失败" }; } //删除应用 public async Task> Delete(long id) { if (await Repository.AsDeleteable().Where(a => a.Id == id).ExecuteCommandAsync() > 0) return new Response { Result = true }; else return new Response { Result = false, Message = "删除失败" }; } //获取应用详情 public async Task> Get(long id) { var result = new Response(); result.Result = await Repository.AsQueryable().FirstAsync(a => a.Id == id); return result; } //获取应用列表 public async Task>>> GetList(PageReq req) { var result = new Response>>(); var totalCount = 0; var objs = Repository.AsQueryable(); objs.WhereIF(!string.IsNullOrEmpty(req.key), u => u.ApplicationName.Contains(req.key)); var data = await objs.OrderByDescending(u => u.CreateTime).ToPageListAsync(req.page, req.limit, totalCount); result.Result = new PageInfo> { Items = data, Total = totalCount }; return result; } //获取数据库表名及注释 public async Task> GetGeomTableList(PageReq req) { using (var db = UnitWork.CreateContext()) { var query = await db.Db.Ado.GetDataTableAsync(@" SELECT t.""table_name"", pg_catalog.obj_description(c.oid) AS table_comment FROM information_schema.tables t JOIN pg_catalog.pg_class c ON c.relname = t.""table_name"" WHERE t.table_schema = 'public' AND EXISTS ( SELECT 1 FROM information_schema.columns col WHERE col.""table_name"" = t.""table_name"" AND col.table_schema = t.table_schema AND col.data_type = 'USER-DEFINED' AND col.udt_name = 'geometry');"); return new Response() { Result = query, }; } } //查询一张表里的所有数据 public async Task>>> GetDataList(TableDataReq tableDataReq) { using (var db = UnitWork.CreateContext()) { StringBuilder stringBuilder = new StringBuilder(); RefAsync totalNumber = 0; var query = db.Db.Queryable().AS(tableDataReq.TableName); List fieldType = new List { "smallint", "integer", "bigint", "real", "double precision", "numeric", "money", "char", }; foreach (var filter in tableDataReq.Filter) { // 判断字段类型 if (fieldType.Contains(filter.Type)) { query.Where(BuildIntCondition(filter.Field, filter.Operator, filter.Value)); } else { query.Where(BuildStringCondition(filter.Field, filter.Operator, filter.Value)); } } var fields = string.Join(",", tableDataReq.Field.Select(f => $"\"{f}\"")); var dataList = await query.Select(fields).ToPageListAsync(tableDataReq.page, tableDataReq.limit, totalNumber); return new Response>> { Result = new PageInfo> { Items = dataList, Total = totalNumber } }; } } //拼接int类型的条件 private static string BuildIntCondition(string column, string operators, string value) { if (operators == "大于") { return $"\"{column}\" > {value}"; } else if (operators == "小于") { return $"\"{column}\" < {value}"; } else if (operators == "大于等于") { return $"\"{column}\" > {value}"; } else if (operators == "小于等于") { return $"\"{column}\" > {value}"; } else if (operators == "介于") { var range = value.Split(','); if (int.TryParse(range[0], out int lower) && int.TryParse(range[1], out int upper)) { return $"\"{column}\" BETWEEN {lower} AND {upper}"; } else { throw new ArgumentException("无效的范围值"); } } else { return $"\"{column}\" = {value}"; } } //拼接string类型的条件 private static string BuildStringCondition(string column, string operators, string value) { if (operators.StartsWith("包含")) { return $"\"{column}\" LIKE '%{value}%'"; } else if (operators.StartsWith("不包含")) { return $"\"{column}\" NOT LIKE '%{value}%'"; } else if (operators.StartsWith("以开头")) { return $"\"{column}\" LIKE '{value}%'"; } else if (operators.StartsWith("以结尾")) { return $"\"{column}\" LIKE '%{value}'"; } else { return $"\"{column}\" = '{value}'"; } } #region 导出数据 public List GetTableAndViewColumnList(string tableName) { using (var db = UnitWork.CreateContext()) { string query = $@" SELECT c.column_name, c.data_type, d.description FROM information_schema.columns c LEFT JOIN pg_catalog.pg_class t ON t.relname = c.table_name LEFT JOIN pg_catalog.pg_attribute a ON a.attnum > 0 AND a.attrelid = t.oid AND a.attname = c.column_name LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.relnamespace LEFT JOIN pg_catalog.pg_description d ON d.objoid = a.attrelid AND d.objsubid = a.attnum WHERE c.table_name = @tableName AND c.table_schema = 'public';"; // 执行查询并获取结果 var viewColumns = db.Db.Ado.SqlQuery(query, new { tableName = tableName }); return viewColumns; } } //查询所有数据 public async Task> GetDataAllList(TableDataReq tableDataReq) { using (var db = UnitWork.CreateContext()) { StringBuilder stringBuilder = new StringBuilder(); var query = db.Db.Queryable().AS(tableDataReq.TableName); List fieldType = new List { "smallint", "integer", "bigint", "real", "double precision", "numeric", "money", "char", }; foreach (var filter in tableDataReq.Filter) { // 判断字段类型 if (fieldType.Contains(filter.Type)) { query.Where(BuildIntCondition(filter.Field, filter.Operator, filter.Value)); } else { query.Where(BuildStringCondition(filter.Field, filter.Operator, filter.Value)); } } var fields = string.Join(",", tableDataReq.Field.Select(f => $"\"{f}\"")); var dataList = await query.Select(fields).ToListAsync(); return dataList; } } //导出Excel public async Task> ListToExcel(TableDataReq tableDataReq, List headers) { Response response = new Response(); try { var list = await GetDataAllList(tableDataReq); HSSFWorkbook workbook = new HSSFWorkbook(); #region 内容样式 IFont font1 = workbook.CreateFont(); //创建一个字体样式对象 font1.FontName = "Microsoft YaHei"; //和excel里面的字体对应 //font1.Boldweight = short.MaxValue;//字体加粗 font1.FontHeightInPoints = 12; //字体大小 ICellStyle style = workbook.CreateCellStyle(); //创建样式对象 style.BorderBottom = BorderStyle.Thin; style.BorderLeft = BorderStyle.Thin; style.BorderRight = BorderStyle.Thin; style.BorderTop = BorderStyle.Thin; style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center; style.VerticalAlignment = VerticalAlignment.Center; style.SetFont(font1); //将字体样式赋给样式对象 style.WrapText = true; #endregion #region 标题样式 IFont font = workbook.CreateFont(); //创建一个字体样式对象 font.FontName = "Microsoft YaHei"; //和excel里面的字体对应 font.Boldweight = (short)FontBoldWeight.Bold; //字体加粗 font.FontHeightInPoints = 12; //字体大小 ICellStyle style1 = workbook.CreateCellStyle(); //创建样式对象 style1.BorderBottom = BorderStyle.Thin; style1.BorderLeft = BorderStyle.Thin; style1.BorderRight = BorderStyle.Thin; style1.BorderTop = BorderStyle.Thin; style1.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center; style1.VerticalAlignment = VerticalAlignment.Center; style1.SetFont(font); //将字体样式赋给样式对象 #endregion #region 创建表头 int m = list.Count / 60000 + 1; for (int k = 0; k < m; k++) { ISheet sheet = workbook.CreateSheet("Sheet" + k.ToString()); IRow rowHeader = sheet.CreateRow(0); rowHeader.Height = 20 * 30; for (int i = 0; i < tableDataReq.Field.Count; i++) { rowHeader.CreateCell(i); rowHeader.Cells[i].CellStyle = style1; var va = headers.Where(r => r.key == tableDataReq.Field[i].ToString()).FirstOrDefault().value; rowHeader.Cells[i].SetCellValue(va); sheet.SetColumnWidth(i, 20 * 350); } #endregion #region 填充数据 var val = (k + 1) * 60000; var num = 60000; if (val > list.Count()) { num = list.Count - k * 60000; } for (int i = 0; i < num; i++) //循环数据 { var item = list[k * 60000 + i]; //获取数据 IRow dataRow = sheet.CreateRow(i + 1); //创建行 for (int j = 0; j < tableDataReq.Field.Count; j++) //循环表头 { //数据处理 var objValue = ""; var fieldKey = tableDataReq.Field[j].ToString(); if (item is ExpandoObject expandoItem) { var dictItem = (IDictionary)expandoItem; if (dictItem.ContainsKey(fieldKey)) { objValue = dictItem[fieldKey]?.ToString(); } } //创建单元格 dataRow.CreateCell(j); dataRow.Cells[j].CellStyle = style; //添加单元格样式 if (objValue != null && !string.IsNullOrEmpty(objValue.ToString())) { dataRow.Cells[j].SetCellValue(objValue.ToString()); //填充Excel单元格 } else { dataRow.Cells[j].SetCellValue(""); //填充Excel单元格 } } } } #endregion response.Result = new MemoryStream(); workbook.Write(response.Result); workbook = null; response.Result.Close(); response.Result.Dispose(); response.Code = 200; response.Message = "获取成功"; } catch (Exception ex) { response.Code = 500; response.Message = ex.Message; } return response; } /// /// 导出shp文件 /// /// /// /// /// public async Task ExportShapefile(TableDataReq tableDataReq, string shpFilePath, string shpFilePathzip, List headers) { var data = await GetDataAllList(tableDataReq); if (data == null || data.Count == 0) { throw new Exception("暂无数据"); } List features = new List(); foreach (var row in data) { var geometry = ParseGeometry(row.geom.ToString()); if (geometry == null) { throw new Exception("数据不可用"); } AttributesTable attributes = new AttributesTable(); IFeature feature = null; for (int i = 0; i < tableDataReq.Field.Count; i++) { var va = headers.Where(r => r.key == tableDataReq.Field[i].ToString()).FirstOrDefault().value; // 访问动态属性 var fieldName = tableDataReq.Field[i].ToString(); //var fieldValue = row.GetType().GetProperty(fieldName)?.GetValue(row, null); if (row is ExpandoObject expandoItem) { var dictItem = (IDictionary)expandoItem; if (dictItem.ContainsKey(fieldName)) { attributes.Add(va, dictItem[fieldName] == null ? "" : dictItem[fieldName].ToString()); } } } feature = new Feature(geometry, attributes); features.Add(feature); } if (features.Count == 0) { throw new Exception("数据不可用"); } // 导出 SHP 文件及其关联文件 ExportToShapefileFour(shpFilePath, features); // 将文件打包成 ZIP CreateZipFromShapefiles(shpFilePath, shpFilePathzip); } public Geometry ParseGeometry(string wkt) { if (string.IsNullOrEmpty(wkt)) { return null; } var reader = new WKTReader(); return reader.Read(wkt); } public void ExportToShapefileFour(string shpPath, List features) { string prjStr = @"GEOGCS[""GCS_China_Geodetic_Coordinate_System_2000"",DATUM[""D_China_2000"",SPHEROID[""CGCS2000"",6378137.0,298.257222101]],PRIMEM[""Greenwich"",0.0],UNIT[""Degree"",0.0174532925199433]]"; var cpgPath = System.IO.Path.ChangeExtension(shpPath, "prj"); System.IO.File.WriteAllText(cpgPath, prjStr, Encoding.UTF8); NetTopologySuite.IO.Esri.Shapefile.WriteAllFeatures(features, shpPath, encoding: Encoding.UTF8); } public void CreateZipFromShapefiles(string shpPath, string zipPath) { var files = new List { System.IO.Path.ChangeExtension(shpPath, "cpg"), shpPath, System.IO.Path.ChangeExtension(shpPath, "shx"), System.IO.Path.ChangeExtension(shpPath, "dbf"), System.IO.Path.ChangeExtension(shpPath, "prj") }; using (var zipArchive = ZipFile.Open(zipPath, ZipArchiveMode.Create)) { foreach (var file in files) { if (System.IO.File.Exists(file)) { zipArchive.CreateEntryFromFile(file, System.IO.Path.GetFileName(file)); } } } } #endregion //批量修改 public async Task> UpdateBatch(UpdateBatchDataReq updateBatchDataReq) { var result = new Response(); using (var db = UnitWork.CreateContext()) { if (updateBatchDataReq.OldValue == "") { if (updateBatchDataReq.Ids != null && updateBatchDataReq.Ids.Count > 0) { var flag = await db.Db.Updateable() .AS(updateBatchDataReq.TableName) .SetColumns(updateBatchDataReq.SingleField, updateBatchDataReq.NewValue) .Where($"\"{updateBatchDataReq.SingleField}\" = @OldValue OR \"{updateBatchDataReq.SingleField}\" IS NULL", new { OldValue = updateBatchDataReq.OldValue }) .Where($"\"Id\" IN ({string.Join(",", updateBatchDataReq.Ids)})") .ExecuteCommandAsync(); } else { var flag = await db.Db.Updateable() .AS(updateBatchDataReq.TableName) .SetColumns(updateBatchDataReq.SingleField, updateBatchDataReq.NewValue) .Where($"\"{updateBatchDataReq.SingleField}\" = @OldValue OR \"{updateBatchDataReq.SingleField}\" IS NULL", new { OldValue = updateBatchDataReq.OldValue }) .ExecuteCommandAsync(); } } else { if (updateBatchDataReq.Ids != null && updateBatchDataReq.Ids.Count > 0) { var flag = await db.Db.Updateable() .AS(updateBatchDataReq.TableName) .SetColumns(updateBatchDataReq.SingleField, updateBatchDataReq.NewValue) .Where($"\"{updateBatchDataReq.SingleField}\" = @OldValue", new { OldValue = updateBatchDataReq.OldValue }) .Where($"\"Id\" IN ({string.Join(",", updateBatchDataReq.Ids)})") .ExecuteCommandAsync(); } else { var flag = await db.Db.Updateable() .AS(updateBatchDataReq.TableName) .SetColumns(updateBatchDataReq.SingleField, updateBatchDataReq.NewValue) .Where($"\"{updateBatchDataReq.SingleField}\" = @OldValue", new { OldValue = updateBatchDataReq.OldValue }) .ExecuteCommandAsync(); } } if (db.Commit()) { result.Result = true; return result; } else { result.Result = false; result.Message = "修改失败"; return result; } } } } }