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;
}
}
}
}
}