using System.Collections; using System.Data; using System.Text; using JNPF.Common.Configuration; using JNPF.Common.Core.Manager; using JNPF.Common.Core.Manager.Files; using JNPF.Common.Dtos.DataBase; using JNPF.Common.Enums; using JNPF.Common.Extension; using JNPF.Common.Filter; using JNPF.Common.Security; using JNPF.DatabaseAccessor; using JNPF.DependencyInjection; using JNPF.DynamicApiController; using JNPF.FriendlyException; using JNPF.Systems.Entitys.Dto.Database; using JNPF.Systems.Entitys.Model.DataBase; using JNPF.Systems.Entitys.System; using JNPF.Systems.Interfaces.System; using Mapster; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using SqlSugar; namespace JNPF.Systems; /// /// 数据管理 /// 版 本:V3.2 /// 版 权:拓通智联科技有限公司(http://www.tuotong-tech.com) /// 日 期:2021-06-01. /// [ApiDescriptionSettings(Tag = "System", Name = "DataModel", Order = 208)] [Route("api/system/[controller]")] public class DataBaseService : IDynamicApiController, ITransient { /// /// 服务基础仓储. /// public readonly ISqlSugarRepository _repository; /// /// 数据连接服务. /// private readonly IDbLinkService _dbLinkService; /// /// 文件服务. /// private readonly IFileManager _fileManager; /// /// 数据库管理. /// private readonly IDataBaseManager _dataBaseManager; /// /// 用户管理. /// private readonly IUserManager _userManager; /// /// 初始化一个类型的新实例. /// public DataBaseService( ISqlSugarRepository repository, IDbLinkService dbLinkService, IFileManager fileManager, IDataBaseManager dataBaseManager, IUserManager userManager) { _repository = repository; _dbLinkService = dbLinkService; _fileManager = fileManager; _dataBaseManager = dataBaseManager; _userManager = userManager; } #region GET /// /// 表名列表. /// /// 连接Id. /// 过滤条件. /// [HttpGet("{id}/Tables")] public async Task GetList(string id, [FromQuery] KeywordInput input) { var link = await _dbLinkService.GetInfo(id); var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName); var tables = _dataBaseManager.GetDBTableList(tenantLink); //tables = tables.Where((x, i) => tables.FindIndex(z => z.Name == x.Name) == i).ToList(); //var output = tables.Adapt>(); if (!string.IsNullOrEmpty(input.keyword)) tables = tables.FindAll(d => d.table.ToLower().Contains(input.keyword.ToLower()) || (d.tableName.IsNotEmptyOrNull() && d.tableName.ToLower().Contains(input.keyword.ToLower()))); if (tenantLink.DbType.ToLower().Equals("dm")) { GetTableCount(tables, tenantLink); } return new { list = tables.OrderBy(x => x.table).ToList() }; //try //{ //} //catch (Exception ex) //{ // return new { list = new List() }; //} } /// /// 预览数据. /// /// 请求参数. /// 连接Id. /// 表名. /// [HttpGet("{linkId}/Table/{tableName}/Preview")] public async Task GetData([FromQuery] DatabaseTablePreviewQuery input, string linkId, string tableName) { var link = await _dbLinkService.GetInfo(linkId); if (string.IsNullOrEmpty(tableName)) return new PageResult(); var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName); StringBuilder dbSql = new StringBuilder(); dbSql.AppendFormat("SELECT * FROM {0} WHERE 1=1", tableName); if (!string.IsNullOrEmpty(input.field) && !string.IsNullOrEmpty(input.keyword)) dbSql.AppendFormat(" AND {0} like '%{1}%'", input.field, input.keyword); return await _dataBaseManager.GetDataTablePage(tenantLink, dbSql.ToString(), input.currentPage, input.pageSize); } /// /// 字段列表. /// /// 连接Id. /// 表名. /// 字段类型. /// [HttpGet("{linkId}/Tables/{tableName}/Fields")] public async Task GetFieldList(string linkId, string tableName, [FromQuery] string type) { var link = await _dbLinkService.GetInfo(linkId); if (string.IsNullOrEmpty(tableName)) return new PageResult(); var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName); var data = _dataBaseManager.GetFieldList(tenantLink, tableName).Adapt>(); if (type.Equals("1")) { data.ForEach(item => { item.field = item.field.ReplaceRegex("^f_", string.Empty).ParseToPascalCase().ToLowerCase(); }); } return new { list = data }; } /// /// 信息. /// /// 连接Id. /// 主键值. /// [HttpGet("{linkId}/Table/{tableName}")] public async Task GetInfo(string linkId, string tableName) { var link = await _dbLinkService.GetInfo(linkId); if (string.IsNullOrEmpty(tableName)) return new PageResult(); var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName); var output = _dataBaseManager.GetDataBaseTableInfo(tenantLink, tableName); var data = _dataBaseManager.GetData(tenantLink, tableName); output.hasTableData = data.Rows.Count > 0; return output; } /// /// 获取数据库表字段下拉框列表(弃用). /// /// 连接Id. /// 表名. /// [HttpGet("{linkId}/Tables/{tableName}/Fields/Selector")] public async Task SelectorData(string linkId, string tableName) { var link = await _dbLinkService.GetInfo(linkId); if (string.IsNullOrEmpty(tableName)) return new PageResult(); var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName); var data = _dataBaseManager.GetDBTableList(tenantLink).FindAll(m => m.table == tableName).Adapt>(); return new { list = data }; } /// /// 导出. /// /// 连接ID. /// 表名称. /// [HttpGet("{linkId}/Table/{tableName}/Action/Export")] public async Task ActionsExport(string linkId, string tableName) { var link = await _dbLinkService.GetInfo(linkId); var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName); var data = _dataBaseManager.GetDataBaseTableInfo(tenantLink, tableName); var jsonStr = data.ToJsonString(); return await _fileManager.Export(jsonStr, data.tableInfo.table, ExportFileType.bdb); } #endregion #region POST /// /// 删除. /// /// 连接Id. /// 表名. /// [HttpDelete("{linkId}/Table/{tableName}")] [UnitOfWork] public async Task Delete(string linkId, string tableName) { if (IsSysTable(tableName)) throw Oops.Oh(ErrorCode.D1504); var link = await _dbLinkService.GetInfo(linkId); var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName); var data = _dataBaseManager.GetData(tenantLink, tableName); if (data.Rows.Count > 0) throw Oops.Oh(ErrorCode.D1508); if (!_dataBaseManager.Delete(tenantLink, tableName)) throw Oops.Oh(ErrorCode.D1500); } /// /// 新建. /// /// 连接Id. /// 请求参数. /// [HttpPost("{linkId}/Table")] [UnitOfWork] public async Task Create(string linkId, [FromBody] DatabaseTableInfoOutput input) { var link = await _dbLinkService.GetInfo(linkId); var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName); if (_dataBaseManager.IsAnyTable(tenantLink, input.tableInfo.newTable)) throw Oops.Oh(ErrorCode.D1503); var tableInfo = input.tableInfo.Adapt(); tableInfo.table = input.tableInfo.newTable; var tableFieldList = input.tableFieldList.Adapt>(); if (!await _dataBaseManager.Create(tenantLink, tableInfo, tableFieldList)) throw Oops.Oh(ErrorCode.D1501); } /// /// 更新. /// /// 连接Id. /// 请求参数. /// [HttpPut("{linkId}/Table")] [UnitOfWork] public async Task Update(string linkId, [FromBody] DatabaseTableUpInput input) { var link = await _dbLinkService.GetInfo(linkId); var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName); var oldFieldList = _dataBaseManager.GetFieldList(tenantLink, input.tableInfo.table).Adapt>(); oldFieldList = _dataBaseManager.ViewDataTypeConversion(oldFieldList, _dataBaseManager.ToDbType(tenantLink.DbType)); var oldTableInfo = _dataBaseManager.GetDBTableList(tenantLink).Find(m => m.table == input.tableInfo.table).Adapt(); var data = _dataBaseManager.GetData(tenantLink, input.tableInfo.table); if (data.Rows.Count > 0) throw Oops.Oh(ErrorCode.D1508); var tableInfo = input.tableInfo.Adapt(); tableInfo.table = input.tableInfo.newTable; if (IsSysTable(tableInfo.table)) throw Oops.Oh(ErrorCode.D1504); var tableFieldList = input.tableFieldList.Adapt>(); if (!input.tableInfo.table.Equals(input.tableInfo.newTable) && _dataBaseManager.IsAnyTable(tenantLink, input.tableInfo.newTable)) throw Oops.Oh(ErrorCode.D1503); if (!await _dataBaseManager.Update(tenantLink, input.tableInfo.table, tableInfo, tableFieldList)) { await _dataBaseManager.Create(tenantLink, oldTableInfo, oldFieldList.Adapt>()); throw Oops.Oh(ErrorCode.D1502); } } /// /// 更新. /// /// 连接Id. /// 请求参数. /// [HttpPut("{linkId}/addFields")] [UnitOfWork] public async Task AddFields(string linkId, [FromBody] DatabaseTableUpInput input) { try { var link = await _dbLinkService.GetInfo(linkId); var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName); _dataBaseManager.AddTableColumn(tenantLink, input.tableInfo.table, input.tableFieldList.Adapt>()); } catch (Exception ex) { throw Oops.Oh(ErrorCode.D1510); } } /// /// 导入. /// /// /// /// [HttpPost("{linkid}/Action/Import")] public async Task ActionsImport(string linkid, IFormFile file) { var fileType = Path.GetExtension(file.FileName).Replace(".", string.Empty); if (!fileType.ToLower().Equals(ExportFileType.bdb.ToString())) throw Oops.Oh(ErrorCode.D3006); var josn = _fileManager.Import(file); var data = josn.ToObject(); if (data == null || data.tableFieldList == null || data.tableInfo == null) throw Oops.Oh(ErrorCode.D3006); data.tableInfo.newTable = data.tableInfo.table; await Create(linkid, data); } /// /// 清除表数据 /// /// 数据库配置主键 /// /// [HttpPost("{linkId}/clean-data")] public async Task CleanTableData(string linkId, DatabaseTableDataCleanInput input) { SqlSugarScope sugarClient = null!; if (linkId == "0") { ConnectionStringsOptions options = App.GetConfig("ConnectionStrings", true); var connCfg = options.Adapt(); sugarClient = new SqlSugarScope(connCfg); } else { var link = await _dbLinkService.GetInfo(linkId); sugarClient = _dataBaseManager.ChangeDataBase(link); } return await sugarClient.Deleteable().AS(input.TableName).ExecuteCommandAsync(); } /// /// 生成代码 /// /// 数据库配置表主键 /// post输入参数 /// /// /// [HttpPost("{linkId}/gen-code")] public async Task GenerateCode(string linkId,DatabaseTableDataCleanInput input) { if (input.TableName.IsNullOrWhiteSpace()) { throw new ArgumentNullException(nameof(input.TableName)); } if (!input.TableName.Contains("_")) { throw new ArgumentException($"表【{input.TableName}】,表名之间必须包含_"); } var dir = Path.Combine(FileVariable.GenerateCodePath, "DbModel"); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } SqlSugarScope sugarClient = null!; if (linkId == "0") //默认时,使用当前默认数据库配置 { ConnectionStringsOptions options = App.GetConfig("ConnectionStrings", true); var connCfg = options.Adapt(); sugarClient = new SqlSugarScope(connCfg); } else { var link = await _dbLinkService.GetInfo(linkId); sugarClient = _dataBaseManager.ChangeDataBase(link); } string CustomFormatName(string s) { var pos = 0; if ((pos = s.IndexOf("_", StringComparison.Ordinal)) > -1) { var first = s.AsSpan().Slice(0, pos).ToString().ToUpperCase(); var second = s.AsSpan().Slice(pos + 1).ToString().ToUpperCase(); return $"{first}{second}"; } else { return s.ToUpperCase(); } } foreach (var item in sugarClient.DbMaintenance.GetTableInfoList().Where(t => t.Name == input.TableName)) { string entityName = CustomFormatName(item.Name);/*实体名首字母大写*/ sugarClient.MappingTables.Add(entityName, item.Name); foreach (var col in sugarClient.DbMaintenance.GetColumnInfosByTableName(item.Name)) { var colName = CustomFormatName(col.DbColumnName); sugarClient.MappingColumns.Add(colName /*类的属性首字母大写*/, col.DbColumnName, entityName); } } var newFileName = ""; var pos = input.TableName.IndexOf("_", StringComparison.Ordinal); var first = input.TableName.AsSpan().Slice(0, pos).ToString().ToUpperCase(); var second = input.TableName.AsSpan().Slice(pos + 1).ToString().ToUpperCase(); newFileName = $"{first}{second}"; sugarClient.DbFirst.Where(input.TableName) .FormatFileName(CustomFormatName) .IsCreateAttribute() .CreateClassFile(dir, "DbModels"); var previewContent = ""; var codeFile = Path.Combine(dir, $"{CustomFormatName(input.TableName)}.cs"); if (File.Exists(codeFile)) { using (var sr = File.OpenText(codeFile)) { previewContent = await sr.ReadToEndAsync(); } } return previewContent; } #endregion #region PrivateMethod /// /// 是否系统表. /// /// /// private bool IsSysTable(string table) { string[] byoTable = { "base_appdata", "base_authorize", "base_billrule", "base_columnspurview", "base_comfields", "base_datainterface", "base_datainterfacelog", "base_dbbackup", "base_dblink", "base_dictionarydata", "base_dictionarytype", "base_group", "base_imcontent", "base_imreply", "base_message", "base_message_template", "base_messagereceive", "base_module", "base_modulebutton", "base_modulecolumn", "base_moduledataauthorize", "base_moduledataauthorizescheme", "base_moduleform", "base_organize", "base_organize_relation", "base_organizeadministrator", "base_portal", "base_position", "base_printdev", "base_province", "base_role", "base_sms_template", "base_synthirdinfo", "base_sysconfig", "base_syslog", "base_timetask", "base_timetasklog", "base_user", "base_userrelation", "base_visualdev", "base_visualdev_modeldata", "blade_visual", "blade_visual_category", "blade_visual_config", "blade_visual_db", "blade_visual_map", "crm_busines", "crm_businesproduct", "crm_clue", "crm_contract", "crm_contractinvoice", "crm_contractmoney", "crm_contractproduct", "crm_customer", "crm_customercontacts", "crm_followlog", "crm_invoice", "crm_product", "crm_receivable", "ext_bigdata", "ext_document", "ext_documentshare", "ext_emailconfig", "ext_emailreceive", "ext_emailsend", "ext_employee", "ext_order", "ext_orderentry", "ext_orderreceivable", "ext_projectgantt", "ext_schedule", "ext_tableexample", "ext_worklog", "ext_worklogshare", "flow_delegate", "flow_engine", "flow_engineform", "flow_enginevisible", "flow_task", "flow_taskcirculate", "flow_tasknode", "flow_taskoperator", "flow_taskoperatorrecord", "wechat_mpeventcontent", "wechat_mpmaterial", "wechat_mpmessage", "wechat_qydepartment", "wechat_qymessage", "wechat_qyuser", "wform_applybanquet", "wform_applydelivergoods", "wform_applydelivergoodsentry", "wform_applymeeting", "wform_archivalborrow", "wform_articleswarehous", "wform_batchpack", "wform_batchtable", "wform_conbilling", "wform_contractapproval", "wform_contractapprovalsheet", "wform_debitbill", "wform_documentapproval", "wform_documentsigning", "wform_expenseexpenditure", "wform_finishedproduct", "wform_finishedproductentry", "wform_incomerecognition", "wform_leaveapply", "wform_letterservice", "wform_materialrequisition", "wform_materialrequisitionentry", "wform_monthlyreport", "wform_officesupplies", "wform_outboundorder", "wform_outboundorderentry", "wform_outgoingapply", "wform_paydistribution", "wform_paymentapply", "wform_postbatchtab", "wform_procurementmaterial", "wform_procurementmaterialentry", "wform_purchaselist", "wform_purchaselistentry", "wform_quotationapproval", "wform_receiptprocessing", "wform_receiptsign", "wform_rewardpunishment", "wform_salesorder", "wform_salesorderentry", "wform_salessupport", "wform_staffovertime", "wform_supplementcard", "wform_travelapply", "wform_travelreimbursement", "wform_vehicleapply", "wform_violationhandling", "wform_warehousereceipt", "wform_warehousereceiptentry", "wform_workcontactsheet" }; return ((IList)byoTable).Contains(table.ToLower()); } /// /// 获取表条数. /// /// private void GetTableCount(List tableList, DbLinkEntity link) { var _sqlSugarClient = _dataBaseManager.ChangeDataBase(link); foreach (var item in tableList) { try { item.sum = _sqlSugarClient.Queryable().AS(item.table).Count(); } catch (Exception ex) { item.sum = 0; } } } #endregion }