添加项目文件。

This commit is contained in:
2023-03-13 15:00:34 +08:00
parent 42bf06ca3e
commit 1d73df3235
1205 changed files with 185078 additions and 0 deletions

View File

@@ -0,0 +1,128 @@
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Filter;
using JNPF.Common.Security;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.Extend.Entitys;
using JNPF.Extend.Entitys.Dto.BigData;
using JNPF.FriendlyException;
using JNPF.LinqBuilder;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
namespace JNPF.Extend;
/// <summary>
/// 大数据测试
/// 版 本V3.2
/// 版 权拓通智联科技有限公司http://www.tuotong-tech.com
/// 日 期2021-06-01 .
/// </summary>
[ApiDescriptionSettings(Tag = "Extend", Name = "BigData", Order = 600)]
[Route("api/extend/[controller]")]
public class BigDataService : IDynamicApiController, ITransient
{
private readonly ISqlSugarRepository<BigDataEntity> _repository;
/// <summary>
/// 初始化一个<see cref="BigDataService"/>类型的新实例.
/// </summary>
public BigDataService(ISqlSugarRepository<BigDataEntity> repository)
{
_repository = repository;
}
#region GET
/// <summary>
/// 列表
/// </summary>
/// <param name="input">请求参数</param>
/// <returns></returns>
[HttpGet("")]
public async Task<dynamic> GetList([FromQuery] PageInputBase input)
{
var queryWhere = LinqExpression.And<BigDataEntity>();
if (!string.IsNullOrEmpty(input.keyword))
queryWhere = queryWhere.And(m => m.FullName.Contains(input.keyword) || m.EnCode.Contains(input.keyword));
var list = await _repository.AsQueryable().Where(queryWhere).OrderBy(x => x.CreatorTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
var pageList = new SqlSugarPagedList<BigDataListOutput>()
{
list = list.list.Adapt<List<BigDataListOutput>>(),
pagination = list.pagination
};
return PageResult<BigDataListOutput>.SqlSugarPageResult(pageList);
}
#endregion
#region POST
/// <summary>
/// 新建
/// </summary>
/// <returns></returns>
[HttpPost("")]
public async Task Create()
{
var list = await _repository.GetListAsync();
var code = 0;
if (list.Count > 0)
{
code = list.Select(x => x.EnCode).ToList().Max().ParseToInt();
}
var index = code == 0 ? 10000001 : code;
if (index > 11500001)
throw Oops.Oh(ErrorCode.Ex0001);
List<BigDataEntity> entityList = new List<BigDataEntity>();
for (int i = 0; i < 10000; i++)
{
entityList.Add(new BigDataEntity
{
Id = SnowflakeIdHelper.NextId(),
EnCode = index.ToString(),
FullName = "测试大数据" + index,
CreatorTime = DateTime.Now,
});
index++;
}
Blukcopy(entityList);
}
#endregion
#region PrivateMethod
/// <summary>
/// 大数据批量插入.
/// </summary>
/// <param name="entityList"></param>
private void Blukcopy(List<BigDataEntity> entityList)
{
try
{
var storageable = _repository.AsSugarClient().Storageable(entityList).SplitInsert(x => true).ToStorage();
switch (_repository.AsSugarClient().CurrentConnectionConfig.DbType)
{
case DbType.Dm:
case DbType.Kdbndp:
storageable.AsInsertable.ExecuteCommand();
break;
case DbType.Oracle:
_repository.AsSugarClient().Storageable(entityList).ToStorage().BulkCopy();
break;
default:
_repository.AsSugarClient().Fastest<BigDataEntity>().BulkCopy(entityList);
break;
}
}
catch (Exception ex)
{
throw;
}
}
#endregion
}

View File

@@ -0,0 +1,117 @@
using System.Web;
using JNPF.Common.Configuration;
using JNPF.Common.Core.Manager.Files;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Filter;
using JNPF.Common.Options;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.Extend.Entitys.Dto.DocumentPreview;
using JNPF.FriendlyException;
using JNPF.Logging.Attributes;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
namespace JNPF.Extend;
/// <summary>
/// 文件预览
/// 版 本V3.2
/// 版 权拓通智联科技有限公司http://www.tuotong-tech.com
/// 日 期2021-06-01 .
/// </summary>
[ApiDescriptionSettings(Tag = "Extend", Name = "DocumentPreview", Order = 600)]
[Route("api/extend/[controller]")]
public class DocumentPreview : IDynamicApiController, ITransient
{
private readonly IFileManager _fileManager;
public DocumentPreview(IFileManager fileManager)
{
_fileManager = fileManager;
}
#region Get
/// <summary>
/// 获取文档列表.
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpGet("")]
public async Task<dynamic> GetList_Api([FromQuery] KeywordInput input)
{
var filePath = FileVariable.DocumentPreviewFilePath;
var list = await _fileManager.GetObjList(filePath);
list = list.FindAll(x => "xlsx".Equals(x.FileType) || "xls".Equals(x.FileType) || "docx".Equals(x.FileType) || "doc".Equals(x.FileType) || "pptx".Equals(x.FileType) || "ppt".Equals(x.FileType));
if (input.keyword.IsNotEmptyOrNull())
list = list.FindAll(x => x.FileName.Contains(input.keyword));
return list.OrderByDescending(x => x.FileTime).Adapt<List<DocumentPreviewListOutput>>();
}
/// <summary>
/// 文件在线预览.
/// </summary>
/// <param name="fileId"></param>
/// <param name="input"></param>
/// <returns></returns>
[HttpGet("{fileId}/Preview")]
public async Task<dynamic> DocumentPreview_Api(string fileId, [FromQuery] DocumentPreviewPreviewInput input)
{
var filePath = FileVariable.DocumentPreviewFilePath;
var files = await _fileManager.GetObjList(filePath);
var file = files.Find(x => x.FileId == fileId);
if (file.IsNotEmptyOrNull())
{
string domain = App.GetConfig<AppOptions>("JNPF_App", true).Domain;
string yozoUrl = App.GetConfig<AppOptions>("JNPF_App", true).YOZO.Domain;
string yozoKey = App.GetConfig<AppOptions>("JNPF_App", true).YOZO.domainKey;
var url = string.Format("{0}/api/Extend/DocumentPreview/down/{1}", domain, file.FileName);
if (!input.previewType.Equals("localPreview"))
{
url = string.Format("{0}?k={1}&url={2}", yozoUrl,
yozoKey, url, input.noCache, input.watermark, input.isCopy, input.pageStart, input.pageEnd, input.type);
}
return url;
}
else
{
throw Oops.Oh(ErrorCode.D8000);
}
}
/// <summary>
/// 下载.
/// </summary>
/// <param name="fileName"></param>
[HttpGet("down/{fileName}")]
[IgnoreLog]
[AllowAnonymous]
public async Task FileDown(string fileName)
{
var filePath = Path.Combine(FileVariable.DocumentPreviewFilePath, fileName);
var systemFilePath = Path.Combine(FileVariable.SystemFilePath, fileName);
FileStreamResult fileStreamResult = null;
if (await _fileManager.ExistsFile(filePath))
fileStreamResult = await _fileManager.DownloadFileByType(filePath, fileName);
else
fileStreamResult = await _fileManager.DownloadFileByType(systemFilePath, fileName);
byte[] bytes = new byte[fileStreamResult.FileStream.Length];
fileStreamResult.FileStream.Read(bytes, 0, bytes.Length);
fileStreamResult.FileStream.Close();
var httpContext = App.HttpContext;
httpContext.Response.ContentType = "application/octet-stream";
httpContext.Response.Headers.Add("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
httpContext.Response.Headers.Add("Content-Length", bytes.Length.ToString());
httpContext.Response.Body.WriteAsync(bytes);
httpContext.Response.Body.Flush();
httpContext.Response.Body.Close();
}
#endregion
}

View File

@@ -0,0 +1,438 @@
using JNPF.Common.Core.Manager;
using JNPF.Common.Core.Manager.Files;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Filter;
using JNPF.Common.Manager;
using JNPF.Common.Models;
using JNPF.Common.Options;
using JNPF.Common.Security;
using JNPF.DataEncryption;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.Extend.Entitys;
using JNPF.Extend.Entitys.Dto.Document;
using JNPF.FriendlyException;
using JNPF.Systems.Entitys.Permission;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using Yitter.IdGenerator;
namespace JNPF.Extend;
/// <summary>
/// 知识管理
/// 版 本V3.2
/// 版 权拓通智联科技有限公司http://www.tuotong-tech.com
/// 日 期2021-06-01 .
/// </summary>
[ApiDescriptionSettings(Tag = "Extend", Name = "Document", Order = 601)]
[Route("api/extend/[controller]")]
public class DocumentService : IDynamicApiController, ITransient
{
private readonly ISqlSugarRepository<DocumentEntity> _repository;
private readonly IFileManager _fileManager;
private readonly ITenant _db;
private readonly IUserManager _userManager;
private readonly ICacheManager _cacheManager;
public DocumentService(ISqlSugarRepository<DocumentEntity> repository, IFileManager fileManager, IUserManager userManager, ICacheManager cacheManager, ISqlSugarClient context)
{
_repository = repository;
_fileManager = fileManager;
_userManager = userManager;
_cacheManager = cacheManager;
_db = context.AsTenant();
}
#region Get
/// <summary>
/// 列表(文件夹树).
/// </summary>
/// <returns></returns>
[HttpGet("FolderTree/{id}")]
public async Task<dynamic> GetFolderTree(string id)
{
var data = (await _repository.AsQueryable().Where(x => x.CreatorUserId == _userManager.UserId && x.Type == 0 && x.DeleteMark == 0).ToListAsync()).Adapt<List<DocumentFolderTreeOutput>>();
data.Add(new DocumentFolderTreeOutput
{
id = "0",
fullName = "全部文档",
parentId = "-1",
icon = "fa fa-folder",
});
if (!id.Equals("0"))
{
data.RemoveAll(x => x.id == id);
}
var treeList = data.ToTree("-1");
return new { list = treeList };
}
/// <summary>
/// 列表(全部文档).
/// </summary>
/// <param name="input">请求参数.</param>
/// <param name="parentId">文档层级.</param>
/// <returns></returns>
[HttpGet("")]
public async Task<dynamic> GetAllList([FromQuery] KeywordInput input, string parentId)
{
var data = (await _repository.AsQueryable().Where(m => m.CreatorUserId == _userManager.UserId && m.ParentId == parentId && m.DeleteMark == 0)
.WhereIF(input.keyword.IsNotEmptyOrNull(), t => t.FullName.Contains(input.keyword))
.OrderBy(x => x.SortCode).OrderBy(x => x.CreatorTime, OrderByType.Desc)
.OrderByIF(!string.IsNullOrEmpty(input.keyword), t => t.LastModifyTime, OrderByType.Desc).ToListAsync()).Adapt<List<DocumentListOutput>>();
return new { list = data };
}
/// <summary>
/// 列表(我的分享).
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpGet("Share")]
public async Task<dynamic> GetShareOutList([FromQuery] KeywordInput input)
{
var data = (await _repository.AsQueryable()
.Where(m => m.CreatorUserId == _userManager.UserId && m.IsShare > 0 && m.DeleteMark == 0)
.WhereIF(input.keyword.IsNotEmptyOrNull(), t => t.FullName.Contains(input.keyword))
.OrderBy(x => x.SortCode).OrderBy(x => x.CreatorTime, OrderByType.Desc)
.OrderByIF(!string.IsNullOrEmpty(input.keyword), t => t.LastModifyTime, OrderByType.Desc).ToListAsync()).Adapt<List<DocumentShareOutput>>();
return new { list = data };
}
/// <summary>
/// 列表(共享给我).
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpGet("ShareTome")]
public async Task<dynamic> GetShareTomeList([FromQuery] KeywordInput input)
{
var output = await _repository.AsSugarClient().Queryable<DocumentEntity, DocumentShareEntity, UserEntity>((a, b, c) => new JoinQueryInfos(JoinType.Left, a.Id == b.DocumentId, JoinType.Left, a.CreatorUserId == c.Id)).Where((a, b, c) => a.DeleteMark == 0 && b.ShareUserId == _userManager.UserId).WhereIF(input.keyword.IsNotEmptyOrNull(), a => a.FullName.Contains(input.keyword)).Select((a, b, c) => new DocumentShareTomeOutput()
{
shareTime = a.ShareTime,
fileSize = a.FileSize,
fullName = a.FullName,
id = a.Id,
creatorUserId = SqlFunc.MergeString(c.RealName, "/", c.Account),
fileExtension = a.FileExtension
}).MergeTable().OrderBy(a => a.shareTime, OrderByType.Desc).ToListAsync();
return new { list = output };
}
/// <summary>
/// 列表(回收站).
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpGet("Trash")]
public async Task<dynamic> GetTrashList([FromQuery] KeywordInput input)
{
var data = (await _repository.AsQueryable()
.Where(m => m.CreatorUserId == _userManager.UserId && m.DeleteMark == 1)
.WhereIF(input.keyword.IsNotEmptyOrNull(), t => t.FullName.Contains(input.keyword))
.OrderBy(x => x.SortCode).OrderBy(x => x.CreatorTime, OrderByType.Desc)
.OrderByIF(!string.IsNullOrEmpty(input.keyword), t => t.LastModifyTime, OrderByType.Desc).ToListAsync()).Adapt<List<DocumentTrashOutput>>();
return new { list = data };
}
/// <summary>
/// 列表(共享人员).
/// </summary>
/// <param name="documentId">文档主键.</param>
/// <returns></returns>
[HttpGet("ShareUser/{documentId}")]
public async Task<dynamic> GetShareUserList(string documentId)
{
var data = (await _repository.AsSugarClient().Queryable<DocumentShareEntity>().Where(x => x.DocumentId == documentId).OrderBy(x => x.ShareTime, OrderByType.Desc).ToListAsync()).Adapt<List<DocumentShareUserOutput>>();
return new { list = data };
}
/// <summary>
/// 信息.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpGet("{id}")]
public async Task<dynamic> GetInfo(string id)
{
var data = (await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == 0)).Adapt<DocumentInfoOutput>();
if (data.type == 1)
{
data.fullName = data.fullName.Replace("." + data.fileExtension, string.Empty);
}
return data;
}
#endregion
#region Post
/// <summary>
/// 新建.
/// </summary>
/// <param name="input">实体对象.</param>
/// <returns></returns>
[HttpPost("")]
public async Task Create([FromBody] DocumentCrInput input)
{
if (await _repository.IsAnyAsync(x => x.FullName == input.fullName && x.CreatorUserId == _userManager.UserId && x.Type == 0 && x.DeleteMark != 1))
throw Oops.Oh(ErrorCode.COM1004);
var entity = input.Adapt<DocumentEntity>();
entity.DeleteMark = 0;
var isOk = await _repository.AsSugarClient().Insertable(entity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1000);
}
/// <summary>
/// 更新.
/// </summary>
/// <param name="id">主键值.</param>
/// <param name="input">实体对象.</param>
/// <returns></returns>
[HttpPut("{id}")]
public async Task Update(string id, [FromBody] DocumentUpInput input)
{
if (await _repository.IsAnyAsync(x => x.Id != id && x.Type == input.type && x.FullName == input.fullName && x.DeleteMark != 1))
throw Oops.Oh(ErrorCode.COM1004);
var entity = await _repository.GetFirstAsync(x => x.Id == id);
entity.FullName = string.Format("{0}.{1}", input.fullName, entity.FileExtension);
var isOk = await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1001);
}
/// <summary>
/// 删除.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task Delete(string id)
{
if (await _repository.IsAnyAsync(x => x.ParentId == id && x.DeleteMark != 1))
throw Oops.Oh(ErrorCode.Ex0006);
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark != 1);
if (entity == null)
throw Oops.Oh(ErrorCode.COM1005);
var isOk = await _repository.AsSugarClient().Updateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1002);
}
/// <summary>
/// 上传文件.
/// </summary>
/// <returns></returns>
[HttpPost("Uploader")]
public async Task Uploader([FromForm] DocumentUploaderInput input)
{
#region
if (await _repository.IsAnyAsync(x => x.FullName == input.file.FileName && x.Type == 1 && x.DeleteMark != 1))
throw Oops.Oh(ErrorCode.D8002);
var stream = input.file.OpenReadStream();
var _filePath = _fileManager.GetPathByType("document");
await _fileManager.UploadFileByType(stream, _filePath, input.file.FileName);
Thread.Sleep(1000);
#endregion
#region
var entity = new DocumentEntity();
entity.Type = 1;
entity.FullName = input.file.FileName;
entity.ParentId = input.parentId;
entity.FileExtension = Path.GetExtension(input.file.FileName).Replace(".", string.Empty);
entity.FilePath = Path.Combine(_filePath, input.file.FileName);
entity.FileSize = input.file.Length.ToString();
entity.DeleteMark = 0;
var isOk = await _repository.AsSugarClient().Insertable(entity).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.D8001);
#endregion
}
/// <summary>
/// 分片组装.
/// </summary>
/// <param name="input">请求参数.</param>
[HttpPost("merge")]
public async Task<dynamic> merge([FromForm] ChunkModel input)
{
if (await _repository.IsAnyAsync(x => x.FullName == input.fileName && x.Type == 1 && x.DeleteMark != 1))
{
string directoryPath = Path.Combine(App.GetConfig<AppOptions>("JNPF_App", true).SystemPath, "TemporaryFile", input.identifier);
FileHelper.DeleteDirectory(directoryPath);
throw Oops.Oh(ErrorCode.D8002);
}
input.isUpdateName = false;
input.type = "document";
var _filePath = _fileManager.GetPathByType(input.type);
var output = await _fileManager.Merge(input);
#region
var entity = new DocumentEntity();
entity.Type = 1;
entity.FullName = input.fileName;
entity.ParentId = input.parentId;
entity.FileExtension = Path.GetExtension(input.fileName).Replace(".", string.Empty);
entity.FilePath = output.name;
entity.FileSize = input.fileSize;
entity.DeleteMark = 0;
var isOk = await _repository.AsSugarClient().Insertable(entity).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.D8001);
#endregion
return output;
}
/// <summary>
/// 下载文件.
/// </summary>
/// <param name="id">主键值.</param>
[HttpPost("Download/{id}")]
public async Task<dynamic> Download(string id)
{
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == 0);
if (entity == null)
throw Oops.Oh(ErrorCode.D8000);
var fileName = _userManager.UserId + "|" + entity.FilePath + "|document";
_cacheManager.Set(entity.FilePath, string.Empty);
return new
{
name = entity.FullName,
url = "/api/File/Download?encryption=" + DESCEncryption.Encrypt(fileName, "JNPF")
};
}
/// <summary>
/// 回收站(彻底删除).
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpDelete("Trash/{id}")]
public async Task TrashDelete(string id)
{
var list = await _repository.AsQueryable().Where(m => m.ParentId == id && m.Type == 1 && m.CreatorUserId == _userManager.UserId && m.DeleteMark == 1).ToListAsync();
foreach (var item in list)
{
if (item.Type == 1)
{
await _fileManager.DeleteFile(item.FilePath);
}
await _repository.AsSugarClient().Deleteable<DocumentEntity>().Where(m => m.Id == item.Id && m.CreatorUserId == _userManager.UserId).ExecuteCommandHasChangeAsync();
}
var isOk = await _repository.AsSugarClient().Deleteable<DocumentEntity>().Where(m => m.Id == id && m.CreatorUserId == _userManager.UserId).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1002);
}
/// <summary>
/// 回收站(还原文件).
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpPost("Trash/{id}/Actions/Recovery")]
public async Task TrashRecovery(string id)
{
var entity = await _repository.GetFirstAsync(x => x.Id == id);
if (!await _repository.IsAnyAsync(x => x.Id == entity.ParentId && x.DeleteMark == 0) && entity.ParentId != "0") throw Oops.Oh(ErrorCode.Ex0007);
entity.DeleteMark = 0;
entity.DeleteTime = null;
entity.DeleteUserId = null;
var isOk = await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1001);
}
/// <summary>
/// 共享文件(创建).
/// </summary>
/// <param name="id">共享文件id.</param>
/// <param name="input">共享人.</param>
/// <returns></returns>
[HttpPost("{id}/Actions/Share")]
public async Task ShareCreate(string id, [FromBody] DocumentActionsShareInput input)
{
try
{
var userIds = input.userId.Split(",");
List<DocumentShareEntity> documentShareEntityList = new List<DocumentShareEntity>();
foreach (var item in userIds)
{
documentShareEntityList.Add(new DocumentShareEntity
{
Id = YitIdHelper.NextId().ToString(),
DocumentId = id,
ShareUserId = item,
ShareTime = DateTime.Now,
});
}
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == 0);
entity.IsShare = documentShareEntityList.Count;
entity.ShareTime = DateTime.Now;
_db.BeginTran();
_repository.AsSugarClient().Deleteable<DocumentShareEntity>().Where(x => x.DocumentId == id).ExecuteCommand();
_repository.AsSugarClient().Insertable(documentShareEntityList).ExecuteCommand();
var isOk = await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1001);
_db.CommitTran();
}
catch (Exception ex)
{
_db.RollbackTran();
}
}
/// <summary>
/// 共享文件(取消).
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpDelete("{id}/Actions/Share")]
public async Task ShareCancel(string id)
{
try
{
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == 0);
entity.IsShare = 0;
entity.ShareTime = DateTime.Now;
_db.BeginTran();
_repository.AsSugarClient().Deleteable<DocumentShareEntity>().Where(x => x.DocumentId == id).ExecuteCommand();
var isOk = await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1001);
_db.CommitTran();
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// 文件/夹移动到.
/// </summary>
/// <param name="id">主键值</param>
/// <param name="toId">将要移动到Id</param>
/// <returns></returns>
[HttpPut("{id}/Actions/MoveTo/{toId}")]
public async Task MoveTo(string id, string toId)
{
var entity = await _repository.GetFirstAsync(x => x.Id == id);
var entityTo = await _repository.GetFirstAsync(x => x.Id == toId);
if (id == toId && entity.Type == 0 && entityTo.Type == 0)
throw Oops.Oh(ErrorCode.Ex0002);
if (entityTo.IsNotEmptyOrNull() && id == entityTo.ParentId && entity.Type == 0 && entityTo.Type == 0)
throw Oops.Oh(ErrorCode.Ex0005);
entity.ParentId = toId;
var isOk = await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1001);
}
#endregion
}

View File

@@ -0,0 +1,583 @@
using System.Web;
using JNPF.Common.Configuration;
using JNPF.Common.Core.Manager;
using JNPF.Common.Core.Manager.Files;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Filter;
using JNPF.Common.Models;
using JNPF.Common.Options;
using JNPF.Common.Security;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.Extend.Entitys;
using JNPF.Extend.Entitys.Dto.Email;
using JNPF.Extras.Thirdparty.Email;
using JNPF.FriendlyException;
using JNPF.LinqBuilder;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using SqlSugar;
namespace JNPF.Extend;
/// <summary>
/// 邮件收发
/// 版 本V3.2
/// 版 权拓通智联科技有限公司http://www.tuotong-tech.com
/// 日 期2021-06-01 .
/// </summary>
[ApiDescriptionSettings(Tag = "Extend", Name = "Email", Order = 600)]
[Route("api/extend/[controller]")]
public class EmailService : IDynamicApiController, ITransient
{
private readonly ISqlSugarRepository<EmailReceiveEntity> _repository;
private readonly ITenant _db;
private readonly IUserManager _userManager;
private readonly IFileManager _fileManager;
public EmailService(ISqlSugarRepository<EmailReceiveEntity> repository, IUserManager userManager, ISqlSugarClient context, IFileManager fileManager)
{
_repository = repository;
_userManager = userManager;
_db = context.AsTenant();
_fileManager = fileManager;
}
#region Get
/// <summary>
/// (带分页)获取邮件列表(收件箱、标星件、草稿箱、已发送).
/// </summary>
/// <param name="input">请求参数</param>
/// <returns></returns>
[HttpGet("")]
public async Task<dynamic> GetList([FromQuery] EmailListQuery input)
{
switch (input.type)
{
case "inBox"://收件箱
return await GetReceiveList(input);
case "star"://标星件
return await GetStarredList(input);
case "draft"://草稿箱
return await GetDraftList(input);
case "sent"://已发送
return await GetSentList(input);
default:
return PageResult<EmailListOutput>.SqlSugarPageResult(new SqlSugarPagedList<EmailListOutput>());
}
}
/// <summary>
/// 信息(收件/发件).
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpGet("{id}")]
public async Task<dynamic> GetInfo_Api(string id)
{
var output = new EmailInfoOutput();
var data = await GetInfo(id);
var jobj = data.ToObject<JObject>();
if (jobj.ContainsKey("Read"))
{
var entity = data.Adapt<EmailReceiveEntity>();
output = entity.Adapt<EmailInfoOutput>();
output.bodyText = HttpUtility.HtmlDecode(entity.BodyText);
}
else
{
var entity = data.Adapt<EmailSendEntity>();
output = entity.Adapt<EmailInfoOutput>();
output.bodyText = HttpUtility.HtmlDecode(entity.BodyText);
}
return output;
}
/// <summary>
/// 信息(配置).
/// </summary>
/// <returns></returns>
[HttpGet("Config")]
public async Task<dynamic> GetConfigInfo_Api()
{
return (await GetConfigInfo()).Adapt<EmailConfigInfoOutput>();
}
#endregion
#region Post
/// <summary>
/// 删除.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task Delete(string id)
{
try
{
_db.BeginTran();
var entity = await GetInfo(id);
if (entity is EmailReceiveEntity)
{
//删除邮件
var mailConfig = await GetConfigInfo();
var mailReceiveEntity = entity as EmailReceiveEntity;
MailUtil.Delete(new MailParameterInfo { Account = mailConfig.Account, Password = mailConfig.Password, POP3Host = mailConfig.POP3Host, POP3Port = mailConfig.POP3Port.ParseToInt() }, mailReceiveEntity.MID);
}
//删除数据
var isOk = false;
if (entity is EmailReceiveEntity)
isOk = await _repository.AsSugarClient().Updateable((EmailReceiveEntity)entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandHasChangeAsync();
else
isOk = await _repository.AsSugarClient().Updateable((EmailSendEntity)entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1002);
_db.CommitTran();
}
catch (Exception ex)
{
_db.RollbackTran();
throw Oops.Oh(ErrorCode.COM1002);
}
}
/// <summary>
/// 设置已读邮件.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpPut("{id}/Actions/Read")]
public async Task ReceiveRead(string id)
{
var isOk = await _repository.AsSugarClient().Updateable<EmailReceiveEntity>().SetColumns(it => new EmailReceiveEntity()
{
Read = 1,
LastModifyUserId = _userManager.UserId,
LastModifyTime = SqlFunc.GetDate()
}).Where(it => it.Id.Equals(id)).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1008);
}
/// <summary>
/// 设置未读邮件.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpPut("{id}/Actions/Unread")]
public async Task ReceiveUnread(string id)
{
var isOk = await _repository.AsSugarClient().Updateable<EmailReceiveEntity>().SetColumns(it => new EmailReceiveEntity()
{
Read = 0,
LastModifyUserId = _userManager.UserId,
LastModifyTime = SqlFunc.GetDate()
}).Where(it => it.Id.Equals(id)).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1008);
}
/// <summary>
/// 设置星标邮件
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpPut("{id}/Actions/Star")]
public async Task ReceiveYesStarred(string id)
{
var isOk = await _repository.AsSugarClient().Updateable<EmailReceiveEntity>().SetColumns(it => new EmailReceiveEntity()
{
Starred = 1,
LastModifyUserId = _userManager.UserId,
LastModifyTime = SqlFunc.GetDate()
}).Where(it => it.Id.Equals(id)).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1008);
}
/// <summary>
/// 设置取消星标.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpPut("{id}/Actions/Unstar ")]
public async Task ReceiveNoStarred(string id)
{
var isOk = await _repository.AsSugarClient().Updateable<EmailReceiveEntity>().SetColumns(it => new EmailReceiveEntity()
{
Starred = 0,
LastModifyUserId = _userManager.UserId,
LastModifyTime = SqlFunc.GetDate()
}).Where(it => it.Id.Equals(id)).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1008);
}
/// <summary>
/// 收邮件.
/// </summary>
/// <returns></returns>
[HttpPost("Receive")]
public async Task<dynamic> Receive()
{
var mailConfig = await GetConfigInfo();
if (mailConfig != null)
{
var mailAccount = mailConfig.Adapt<MailParameterInfo>();
if (MailUtil.CheckConnected(mailAccount))
{
new List<EmailReceiveEntity>();
var startTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd") + " 00:00");
var endTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd") + " 23:59");
var receiveCount = await _repository.AsSugarClient().Queryable<EmailReceiveEntity>().CountAsync(x => x.MAccount == mailConfig.Account && SqlFunc.Between(x.CreatorTime, startTime, endTime));
List<EmailReceiveEntity> entitys = MailUtil.Get(mailAccount, receiveCount).Select(item => new EmailReceiveEntity
{
MAccount = mailConfig.Account,
MID = item.UID,
Sender = item.To,
SenderName = item.ToName,
Subject = item.Subject,
BodyText = HttpUtility.HtmlEncode(item.BodyText),
Attachment = item.Attachment.ToJsonString(),
Date = item.Date,
Read = 0
}).ToList();
if (entitys.Count > 0)
{
await _repository.AsSugarClient().Insertable(entitys).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
}
return entitys.Count;
}
else
{
throw Oops.Oh(ErrorCode.Ex0003);
}
}
else
{
throw Oops.Oh(ErrorCode.Ex0004);
}
}
/// <summary>
/// 存草稿.
/// </summary>
/// <param name="input">对象实体.</param>
/// <returns></returns>
[HttpPost("Actions/SaveDraft")]
public async Task SaveDraft([FromBody] EmailActionsSaveDraftInput input)
{
var entity = input.Adapt<EmailSendEntity>();
entity.BodyText = HttpUtility.HtmlEncode(entity.BodyText);
entity.To = input.recipient;
entity.Sender = App.GetConfig<AppOptions>("JNPF_App", true).ErrorReportTo;
var isOk = 0;
entity.State = -1;
if (entity.Id.IsEmpty())
{
isOk = await _repository.AsSugarClient().Insertable(entity).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
}
else
{
isOk = await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync();
}
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1008);
}
/// <summary>
/// 发邮件.
/// </summary>
/// <param name="input">对象实体.</param>
/// <returns></returns>
[HttpPost("")]
public async Task SaveSent([FromBody] EmailSendInput input)
{
var entity = input.Adapt<EmailSendEntity>();
var mailConfig = await GetConfigInfo();
foreach (var item in input.recipient.Split(","))
{
if (!item.IsEmail())
throw Oops.Oh(ErrorCode.Ex0003);
if (mailConfig != null)
{
entity.BodyText = HttpUtility.HtmlEncode(entity.BodyText);
entity.To = item;
entity.Sender = App.GetConfig<AppOptions>("JNPF_App", true).ErrorReportTo;
entity.State = 1;
var isOk = 0;
if (entity.Id.IsEmpty())
{
entity.Sender = mailConfig.Account;
isOk = await _repository.AsSugarClient().Insertable(entity).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
}
else
{
isOk = await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync();
}
//拷贝文件,注意:从临时文件夹拷贝到邮件文件夹
var attachmentList = entity.Attachment.ToList<MailFileParameterInfo>();
var temporaryFile = FileVariable.TemporaryFilePath;
var mailFilePath = FileVariable.EmailFilePath;
foreach (MailFileParameterInfo mailFile in attachmentList)
{
FileHelper.MoveFile(Path.Combine(temporaryFile , mailFile.fileId), Path.Combine(mailFilePath , mailFile.fileId));
mailFile.fileName = mailFile.name;
}
//发送邮件
var mailModel = new MailInfo();
mailModel.To = entity.To;
mailModel.CC = entity.CC;
mailModel.Bcc = entity.BCC;
mailModel.Subject = entity.Subject;
mailModel.BodyText = HttpUtility.HtmlDecode(entity.BodyText);
mailModel.Attachment = attachmentList;
MailUtil.Send(new MailParameterInfo { AccountName = mailConfig.SenderName, Account = mailConfig.Account, Password = mailConfig.Password, SMTPHost = mailConfig.SMTPHost, SMTPPort = mailConfig.SMTPPort.ParseToInt() }, mailModel);
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1008);
}
else
{
throw Oops.Oh(ErrorCode.Ex0004);
}
}
}
/// <summary>
/// 保存邮箱配置
/// </summary>
/// <param name="input">对象实体</param>
/// <returns></returns>
[HttpPut("Config")]
public async Task SaveConfig([FromBody] EmailConfigUpInput input)
{
var entity = input.Adapt<EmailConfigEntity>();
var data = await GetConfigInfo();
var isOk = 0;
if (data == null)
{
isOk = await _repository.AsSugarClient().Insertable(entity).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
}
else
{
entity.Id = data.Id;
isOk = await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
}
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1008);
}
/// <summary>
/// 邮箱账户密码验证.
/// </summary>
/// <param name="input">对象实体</param>
[HttpPost("Config/Actions/CheckMail")]
public void CheckLogin([FromBody] EmailConfigActionsCheckMailInput input)
{
var entity = input.Adapt<EmailConfigEntity>();
if (!MailUtil.CheckConnected(entity.Adapt<MailParameterInfo>()))
throw Oops.Oh(ErrorCode.Ex0003);
}
/// <summary>
/// 下载附件.
/// </summary>
/// <param name="fileModel">文件对象</param>
[HttpPost("Download")]
public async Task Download(AnnexModel fileModel)
{
var filePath = Path.Combine(FileVariable.EmailFilePath , fileModel.FileId);
if (await _fileManager.ExistsFile(filePath))
{
_fileManager.DownloadFileByType(filePath, fileModel.FileName);
}
}
#endregion
#region PrivateMethod
/// <summary>
/// 信息(配置).
/// </summary>
/// <returns></returns>
private async Task<EmailConfigEntity> GetConfigInfo()
{
return await _repository.AsSugarClient().Queryable<EmailConfigEntity>().FirstAsync(x => x.CreatorUserId == _userManager.UserId);
}
/// <summary>
/// 列表(收件箱).
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task<dynamic> GetReceiveList(EmailListQuery input)
{
var whereLambda = LinqExpression.And<EmailReceiveEntity>();
whereLambda = whereLambda.And(x => x.CreatorUserId == _userManager.UserId && x.DeleteMark == null);
if (input.endTime != null && input.startTime != null)
{
var start = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 00:00:00}", input.startTime?.TimeStampToDateTime()));
var end = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 23:59:59}", input.endTime?.TimeStampToDateTime()));
whereLambda = whereLambda.And(x => SqlFunc.Between(x.Date, start, end));
}
if (!string.IsNullOrEmpty(input.keyword))
{
whereLambda = whereLambda.And(m => m.Sender.Contains(input.keyword) || m.Subject.Contains(input.keyword));
}
var list = await _repository.AsSugarClient().Queryable<EmailReceiveEntity>().Where(whereLambda)
.OrderBy(x => x.Date, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
var pageList = new SqlSugarPagedList<EmailListOutput>()
{
list = list.list.Adapt<List<EmailListOutput>>(),
pagination = list.pagination
};
return PageResult<EmailListOutput>.SqlSugarPageResult(pageList);
}
/// <summary>
/// 列表(未读邮件).
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task<dynamic> GetUnreadList(EmailListQuery input)
{
var whereLambda = LinqExpression.And<EmailReceiveEntity>();
whereLambda = whereLambda.And(x => x.CreatorUserId == _userManager.UserId && x.Read == 0 && x.DeleteMark == null);
if (input.endTime != null && input.startTime != null)
{
var start = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 00:00:00}", input.startTime?.TimeStampToDateTime()));
var end = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 23:59:59}", input.endTime?.TimeStampToDateTime()));
whereLambda = whereLambda.And(x => SqlFunc.Between(x.CreatorTime, start, end));
}
if (!string.IsNullOrEmpty(input.keyword))
{
whereLambda = whereLambda.And(m => m.Sender.Contains(input.keyword) || m.Subject.Contains(input.keyword));
}
var list = await _repository.AsSugarClient().Queryable<EmailReceiveEntity>().Where(whereLambda).OrderBy(x => x.Date, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
var pageList = new SqlSugarPagedList<EmailListOutput>()
{
list = list.list.Adapt<List<EmailListOutput>>(),
pagination = list.pagination
};
return PageResult<EmailListOutput>.SqlSugarPageResult(pageList);
}
/// <summary>
/// 列表(星标件).
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task<dynamic> GetStarredList(EmailListQuery input)
{
var whereLambda = LinqExpression.And<EmailReceiveEntity>();
whereLambda = whereLambda.And(x => x.CreatorUserId == _userManager.UserId && x.Starred == 1 && x.DeleteMark == null);
if (input.endTime != null && input.startTime != null)
{
var start = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 00:00:00}", input.startTime?.TimeStampToDateTime()));
var end = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 23:59:59}", input.endTime?.TimeStampToDateTime()));
whereLambda = whereLambda.And(x => SqlFunc.Between(x.CreatorTime, start, end));
}
//关键字用户、IP地址、功能名称
if (!string.IsNullOrEmpty(input.keyword))
{
whereLambda = whereLambda.And(m => m.Sender.Contains(input.keyword) || m.Subject.Contains(input.keyword));
}
var list = await _repository.AsSugarClient().Queryable<EmailReceiveEntity>().Where(whereLambda).OrderBy(x => x.Date, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
var pageList = new SqlSugarPagedList<EmailListOutput>()
{
list = list.list.Adapt<List<EmailListOutput>>(),
pagination = list.pagination
};
return PageResult<EmailListOutput>.SqlSugarPageResult(pageList);
}
/// <summary>
/// 列表(草稿箱).
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task<dynamic> GetDraftList(EmailListQuery input)
{
var whereLambda = LinqExpression.And<EmailSendEntity>();
whereLambda = whereLambda.And(x => x.CreatorUserId == _userManager.UserId && x.State == -1 && x.DeleteMark == null);
if (input.endTime != null && input.startTime != null)
{
var start = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 00:00:00}", input.startTime?.TimeStampToDateTime()));
var end = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 23:59:59}", input.endTime?.TimeStampToDateTime()));
whereLambda = whereLambda.And(x => SqlFunc.Between(x.CreatorTime, start, end));
}
if (!string.IsNullOrEmpty(input.keyword))
{
whereLambda = whereLambda.And(m => m.Sender.Contains(input.keyword) || m.Subject.Contains(input.keyword));
}
var list = await _repository.AsSugarClient().Queryable<EmailSendEntity>().Where(whereLambda).OrderBy(x => x.CreatorTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
var pageList = new SqlSugarPagedList<EmailListOutput>()
{
list = list.list.Adapt<List<EmailListOutput>>(),
pagination = list.pagination
};
return PageResult<EmailListOutput>.SqlSugarPageResult(pageList);
}
/// <summary>
/// 列表(已发送).
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task<dynamic> GetSentList(EmailListQuery input)
{
var whereLambda = LinqExpression.And<EmailSendEntity>();
whereLambda = whereLambda.And(x => x.CreatorUserId == _userManager.UserId && x.State != -1 && x.DeleteMark == null);
if (input.endTime != null && input.startTime != null)
{
var start = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 00:00:00}", input.startTime?.TimeStampToDateTime()));
var end = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 23:59:59}", input.endTime?.TimeStampToDateTime()));
whereLambda = whereLambda.And(x => SqlFunc.Between(x.CreatorTime, start, end));
}
if (!string.IsNullOrEmpty(input.keyword))
{
whereLambda = whereLambda.And(m => m.Sender.Contains(input.keyword) || m.Subject.Contains(input.keyword));
}
var list = await _repository.AsSugarClient().Queryable<EmailSendEntity>().Where(whereLambda).OrderBy(x => x.CreatorTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
var pageList = new SqlSugarPagedList<EmailListOutput>()
{
list = list.list.Adapt<List<EmailListOutput>>(),
pagination = list.pagination
};
return PageResult<EmailListOutput>.SqlSugarPageResult(pageList);
}
/// <summary>
/// 信息.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
private async Task<object> GetInfo(string id)
{
var entity = new object();
if (await _repository.AsSugarClient().Queryable<EmailReceiveEntity>().AnyAsync(x => x.Id == id && x.DeleteMark == null))
{
var receiveInfo = await _repository.AsSugarClient().Queryable<EmailReceiveEntity>().FirstAsync(x => x.Id == id && x.DeleteMark == null);
receiveInfo.Read = 1;
await _repository.AsSugarClient().Updateable(receiveInfo).CallEntityMethod(m => m.LastModify()).UpdateColumns(x => new { x.LastModifyTime, x.LastModifyUserId, x.Read }).ExecuteCommandHasChangeAsync();
entity = receiveInfo;
}
else
{
entity = await _repository.AsSugarClient().Queryable<EmailSendEntity>().FirstAsync(x => x.Id == id && x.DeleteMark == null);
}
return entity;
}
#endregion
}

View File

@@ -0,0 +1,412 @@
using JNPF.Common.Configuration;
using JNPF.Common.Core.Manager;
using JNPF.Common.Core.Manager.Files;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Filter;
using JNPF.Common.Helper;
using JNPF.Common.Models.NPOI;
using JNPF.Common.Security;
using JNPF.DataEncryption;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.Extend.Entitys;
using JNPF.Extend.Entitys.Dto.Employee;
using JNPF.FriendlyException;
using JNPF.LinqBuilder;
using Mapster;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
namespace JNPF.Extend;
/// <summary>
/// 职员管理(导入导出)
/// 版 本V3.2
/// 版 权拓通智联科技有限公司http://www.tuotong-tech.com
/// 日 期2021-06-01 .
/// </summary>
[ApiDescriptionSettings(Tag = "Extend", Name = "Employee", Order = 600)]
[Route("api/extend/[controller]")]
public class EmployeeService : IDynamicApiController, ITransient
{
private readonly ISqlSugarRepository<EmployeeEntity> _repository;
private readonly IFileManager _fileManager;
private readonly IUserManager _userManager;
public EmployeeService(ISqlSugarRepository<EmployeeEntity> repository, IFileManager fileManager, IUserManager userManager)
{
_repository = repository;
_fileManager = fileManager;
_userManager = userManager;
}
#region GET
/// <summary>
/// 列表.
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpGet("")]
public async Task<dynamic> GetList([FromQuery] EmployeeListQuery input)
{
var whereLambda = LinqExpression.And<EmployeeEntity>();
whereLambda = whereLambda.And(x => x.DeleteMark == null);
if (input.condition.IsNotEmptyOrNull() && input.keyword.IsNotEmptyOrNull())
{
string propertyName = input.condition;
string propertyValue = input.keyword;
switch (propertyName)
{
case "EnCode": // 工号
whereLambda = whereLambda.And(t => t.EnCode.Contains(propertyValue));
break;
case "FullName": // 姓名
whereLambda = whereLambda.And(t => t.FullName.Contains(propertyValue));
break;
case "Telephone": // 电话
whereLambda = whereLambda.And(t => t.Telephone.Contains(propertyValue));
break;
case "DepartmentName": // 部门
whereLambda = whereLambda.And(t => t.DepartmentName.Contains(propertyValue));
break;
case "PositionName": // 职位
whereLambda = whereLambda.And(t => t.PositionName.Contains(propertyValue));
break;
}
}
var list = await _repository.AsQueryable().Where(whereLambda)
.OrderBy(x => x.SortCode).OrderBy(x => x.CreatorTime, OrderByType.Desc)
.OrderByIF(!string.IsNullOrEmpty(input.keyword), t => t.LastModifyTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
var pageList = new SqlSugarPagedList<EmployeeListOutput>()
{
list = list.list.Adapt<List<EmployeeListOutput>>(),
pagination = list.pagination
};
return PageResult<EmployeeListOutput>.SqlSugarPageResult(pageList);
}
/// <summary>
/// 信息
/// </summary>
/// <param name="id">主键值</param>
/// <returns></returns>
[HttpGet("{id}")]
public async Task<dynamic> GetInfo(string id)
{
return await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
}
/// <summary>
/// 导入预览.
/// </summary>
/// <returns></returns>
[HttpGet("ImportPreview")]
public async Task<dynamic> ImportPreview(string fileName)
{
try
{
var filePath = FileVariable.TemporaryFilePath;
var savePath = Path.Combine(filePath, fileName);
//得到数据
var sr = await _fileManager.GetFileStream(savePath);
var excelData = ExcelImportHelper.ToDataTable(savePath, sr);
foreach (var item in excelData.Columns)
{
excelData.Columns[item.ToString()].ColumnName = GetFiledEncode(item.ToString());
}
//删除文件
_fileManager.DeleteFile(savePath);
//返回结果
return new { dataRow = excelData };
}
catch (Exception ex)
{
throw Oops.Oh(ErrorCode.D1801);
}
}
#endregion
#region POST
/// <summary>
/// 新建.
/// </summary>
/// <param name="entity">实体对象</param>
/// <returns></returns>
[HttpPost("")]
public async Task Create(EmployeeEntity entity)
{
var isOk = await _repository.AsSugarClient().Insertable(entity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1000);
}
/// <summary>
/// 更新.
/// </summary>
/// <param name="id">主键值</param>
/// <param name="entity">实体对象</param>
/// <returns></returns>
[HttpPut("{id}")]
public async Task Update(string id, EmployeeEntity entity)
{
var isOk = await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1001);
}
/// <summary>
/// 删除
/// </summary>
/// <param name="id">主键值</param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task Delete(string id)
{
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
var isOk = await _repository.AsSugarClient().Updateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1002);
}
/// <summary>
/// 导出.
/// </summary>
[HttpGet("ExportExcelData")]
public async Task<dynamic> ExportExcelData([FromQuery] EmployeeListQuery input)
{
var dataList = new List<EmployeeEntity>();
if (input.dataType == "0")
{
dataList = await GetPageListData(input);
}
else
{
dataList = await GetListData();
}
ExcelConfig excelconfig = new ExcelConfig();
excelconfig.FileName = "职员信息.xls";
excelconfig.HeadFont = "微软雅黑";
excelconfig.HeadPoint = 10;
excelconfig.IsAllSizeColumn = true;
excelconfig.ColumnModel = new List<ExcelColumnModel>();
var filedList = input.selectKey.Split(",");
excelconfig.ColumnModel = input.selectKey.Split(",").Select(item => new ExcelColumnModel() { Column = item.ToUpperCase(), ExcelColumn = GetFiledName(item) }).ToList();
var addPath = Path.Combine(FileVariable.TemporaryFilePath, excelconfig.FileName);
var stream = ExcelExportHelper<EmployeeEntity>.ExportMemoryStream(dataList, excelconfig);
await _fileManager.UploadFileByType(stream, FileVariable.TemporaryFilePath, excelconfig.FileName);
return new { name = excelconfig.FileName, url = "/api/file/Download?encryption=" + DESCEncryption.Encrypt(_userManager.UserId + "|" + excelconfig.FileName + "|" + addPath, "JNPF") };
}
/// <summary>
/// 上传文件.
/// </summary>
/// <returns></returns>
[HttpPost("Uploader")]
public async Task<dynamic> Uploader(IFormFile file)
{
var _filePath = _fileManager.GetPathByType(string.Empty);
var _fileName = DateTime.Now.ToString("yyyyMMdd") + "_" + SnowflakeIdHelper.NextId() + Path.GetExtension(file.FileName);
var stream = file.OpenReadStream();
await _fileManager.UploadFileByType(stream, _filePath, _fileName);
return new { name = _fileName, url = string.Format("/api/File/Image/{0}/{1}", string.Empty, _fileName) };
}
/// <summary>
/// 导入数据.
/// </summary>
/// <param name="input">请求参数</param>
/// <returns></returns>
[HttpPost("ImportData")]
public async Task<dynamic> ImportData_Api([FromBody] ImportDataInput input)
{
var output = new ImportDataOutput();
foreach (var item in input.list)
{
try
{
var entity = item.Adapt<EmployeeEntity>();
var isOk = await _repository.AsSugarClient().Insertable(entity).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
if (isOk < 1)
{
output.failResult.Add(item);
output.fnum++;
}
else
{
output.snum++;
}
}
catch (Exception)
{
output.failResult.Add(item);
output.fnum++;
}
}
if (output.snum == input.list.Count)
{
output.resultType = 0;
}
return output;
}
/// <summary>
/// 模板下载.
/// </summary>
[HttpGet("TemplateDownload")]
public async Task<dynamic> TemplateDownload()
{
var filePath = Path.Combine(FileVariable.TemplateFilePath, "employee_import_template.xlsx"); //模板路径
var addFilePath = Path.Combine(FileVariable.TemplateFilePath, "职员信息.xlsx"); // 保存路径
if (!(await _fileManager.ExistsFile(addFilePath)))
{
var stream = await _fileManager.GetFileStream(filePath);
await _fileManager.UploadFileByType(stream, FileVariable.TemporaryFilePath, "职员信息.xlsx");
}
return new { name = "职员信息.xlsx", url = "/api/file/Download?encryption=" + DESCEncryption.Encrypt(_userManager.UserId + "|职员信息.xlsx", "JNPF") };
}
#endregion
#region PrivateMethod
/// <summary>
/// 列表.
/// </summary>
/// <returns></returns>
private async Task<List<EmployeeEntity>> GetListData()
{
return await _repository.AsQueryable().Where(x => x.DeleteMark == null).OrderBy(x => x.CreatorTime, OrderByType.Desc).ToListAsync();
}
/// <summary>
/// 分页列表.
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task<List<EmployeeEntity>> GetPageListData(EmployeeListQuery input)
{
var whereLambda = LinqExpression.And<EmployeeEntity>();
whereLambda = whereLambda.And(x => x.DeleteMark == null);
if (input.condition.IsNotEmptyOrNull() && input.keyword.IsNotEmptyOrNull())
{
string propertyName = input.condition;
string propertyValue = input.keyword;
switch (propertyName)
{
case "EnCode": //工号
whereLambda = whereLambda.And(t => t.EnCode.Contains(propertyValue));
break;
case "FullName": //姓名
whereLambda = whereLambda.And(t => t.FullName.Contains(propertyValue));
break;
case "Telephone": //电话
whereLambda = whereLambda.And(t => t.Telephone.Contains(propertyValue));
break;
case "DepartmentName": //部门
whereLambda = whereLambda.And(t => t.DepartmentName.Contains(propertyValue));
break;
case "PositionName": //职位
whereLambda = whereLambda.And(t => t.PositionName.Contains(propertyValue));
break;
default:
break;
}
}
var list = await _repository.AsQueryable().Where(whereLambda).OrderBy(x => x.CreatorTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
return list.list.Adapt<List<EmployeeEntity>>();
}
/// <summary>
/// 获取字段编码.
/// </summary>
/// <param name="filed"></param>
/// <returns></returns>
private string GetFiledEncode(string filed)
{
switch (filed)
{
case "工号":
return "enCode";
case "姓名":
return "fullName";
case "性别":
return "gender";
case "部门":
return "departmentName";
case "岗位":
return "positionName";
case "用工性质":
return "workingNature";
case "身份证号":
return "idNumber";
case "联系电话":
return "telephone";
case "出生年月":
return "birthday";
case "参加工作":
return "attendWorkTime";
case "最高学历":
return "education";
case "所学专业":
return "major";
case "毕业院校":
return "graduationAcademy";
case "毕业时间":
return "graduationTime";
case "创建时间":
return "creatorTime";
default:
return string.Empty;
}
}
/// <summary>
/// 获取字段名称.
/// </summary>
/// <param name="filed"></param>
/// <returns></returns>
private string GetFiledName(string filed)
{
switch (filed)
{
case "enCode":
return "工号";
case "fullName":
return "姓名";
case "gender":
return "性别";
case "departmentName":
return "部门";
case "positionName":
return "岗位";
case "workingNature":
return "用工性质";
case "idNumber":
return "身份证号";
case "telephone":
return "联系电话";
case "birthday":
return "出生年月";
case "attendWorkTime":
return "参加工作";
case "education":
return "最高学历";
case "major":
return "所学专业";
case "graduationAcademy":
return "毕业院校";
case "graduationTime":
return "毕业时间";
case "creatorTime":
return "创建时间";
default:
return string.Empty;
}
}
#endregion
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,117 @@
using JNPF.Common.Core.Manager;
using JNPF.Common.Enums;
using JNPF.Common.Security;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.Extend.Entitys;
using JNPF.Extend.Entitys.Dto.ProductClassify;
using JNPF.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
namespace JNPF.Extend;
/// <summary>
/// 产品分类.
/// </summary>
[ApiDescriptionSettings(Tag = "Extend", Name = "Classify", Order = 600)]
[Route("api/extend/saleOrder/[controller]")]
public class ProductClassifyService : IDynamicApiController, ITransient
{
/// <summary>
/// 服务基础仓储.
/// </summary>
private readonly ISqlSugarRepository<ProductClassifyEntity> _repository;
/// <summary>
/// 用户管理.
/// </summary>
private readonly IUserManager _userManager;
public ProductClassifyService(
ISqlSugarRepository<ProductClassifyEntity> extProductRepository,
IUserManager userManager)
{
_repository = extProductRepository;
_userManager = userManager;
}
#region GET
/// <summary>
/// 列表.
/// </summary>
/// <returns></returns>
[HttpGet("")]
public async Task<dynamic> GetList()
{
var data = await _repository.AsQueryable().Where(t => t.DeleteMark == null).OrderBy(a => a.CreatorTime, OrderByType.Desc).ToListAsync();
List<ProductClassifyTreeOutput>? treeList = data.Adapt<List<ProductClassifyTreeOutput>>();
return new { list = treeList.ToTree("-1") };
}
/// <summary>
/// 获取订单示例.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpGet("{id}")]
public async Task<dynamic> GetInfo(string id)
{
return (await _repository.AsQueryable().FirstAsync(a => a.Id.Equals(id))).Adapt<ProductClassifyInfoOutput>();
}
#endregion
#region POST
/// <summary>
/// 新建.
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpPost("")]
public async Task Create([FromBody] ProductClassifyCrInput input)
{
var entity = input.Adapt<ProductClassifyEntity>();
entity.Id = SnowflakeIdHelper.NextId();
var isOk = await _repository.AsInsertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1000);
}
/// <summary>
/// 更新订单示例.
/// </summary>
/// <param name="id">主键值.</param>
/// <param name="input">参数.</param>
/// <returns></returns>
[HttpPut("{id}")]
public async Task Update(string id, [FromBody] ProductClassifyUpInput input)
{
var entity = input.Adapt<ProductClassifyEntity>();
entity.LastModifyTime = DateTime.Now;
entity.LastModifyUserId = _userManager.UserId;
var isOk = await _repository.AsUpdateable(entity).UpdateColumns(it => new
{
it.ParentId,
it.FullName,
it.LastModifyTime,
it.LastModifyUserId
}).ExecuteCommandAsync();
if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1001);
}
/// <summary>
/// 删除订单示例.
/// </summary>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task Delete(string id)
{
var isOk = await _repository.AsDeleteable().Where(it => it.Id.Equals(id)).ExecuteCommandAsync();
if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1002);
}
#endregion
}

View File

@@ -0,0 +1,158 @@
using System.Collections.Generic;
using JNPF.Common.Core.Manager;
using JNPF.Common.Filter;
using JNPF.Common.Security;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.Extend.Entitys;
using JNPF.Extend.Entitys.Dto.Product;
using JNPF.Extend.Entitys.Dto.ProductEntry;
using JNPF.Extend.Entitys.Model;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
namespace JNPF.Extend;
/// <summary>
/// 业务实现:订单示例.
/// </summary>
[ApiDescriptionSettings(Tag = "Extend", Name = "Product", Order = 200)]
[Route("api/extend/saleOrder/[controller]")]
public class ProductService : IDynamicApiController, ITransient
{
/// <summary>
/// 服务基础仓储.
/// </summary>
private readonly ISqlSugarRepository<ProductEntity> _repository;
/// <summary>
/// 用户管理.
/// </summary>
private readonly IUserManager _userManager;
/// <summary>
/// 初始化一个<see cref="ProductService"/>类型的新实例.
/// </summary>
public ProductService(
ISqlSugarRepository<ProductEntity> extProductRepository,
IUserManager userManager)
{
_repository = extProductRepository;
_userManager = userManager;
}
/// <summary>
/// 获取订单示例.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpGet("{id}")]
public async Task<dynamic> GetInfo(string id)
{
return (await _repository.AsQueryable()
.Includes(x => x.productEntryList.Select(it => new ProductEntryEntity
{
ProductCode = it.ProductCode,
ProductName = it.ProductName,
ProductSpecification = it.ProductSpecification,
Qty = it.Qty,
Type = it.Type,
Money = it.Money,
Price = it.Price,
Amount = it.Amount,
Description = it.Description
}).ToList()).Where(a => a.Id.Equals(id))
.ToListAsync(it => new ProductInfoOutput
{
id = it.Id,
code = it.Code,
customerName = it.CustomerName,
customerId = it.CustomerId,
auditName = it.AuditName,
auditDate = it.AuditDate,
goodsWarehouse = it.GoodsWarehouse,
goodsDate = it.GoodsDate,
gatheringType = it.GatheringType,
business = it.Business,
address = it.Address,
contactTel = it.ContactTel,
harvestMsg = it.HarvestMsg,
harvestWarehouse = it.HarvestWarehouse,
issuingName = it.IssuingName,
partPrice = it.PartPrice,
reducedPrice = it.ReducedPrice,
discountPrice = it.DiscountPrice,
description = it.Description,
productEntryList = it.productEntryList.Adapt<List<ProductEntryInfoOutput>>()
}))?.FirstOrDefault();
}
/// <summary>
/// 获取订单示例列表.
/// </summary>
/// <param name="input">请求参数.</param>
/// <returns></returns>
[HttpGet("")]
public async Task<dynamic> GetList([FromQuery] ProductListQueryInput input)
{
var data = await _repository.AsQueryable()
.WhereIF(!string.IsNullOrEmpty(input.code), it => it.Code.Contains(input.code))
.WhereIF(!string.IsNullOrEmpty(input.customerName), it => it.Type.Contains(input.customerName))
.WhereIF(!string.IsNullOrEmpty(input.contactTel), it => it.CustomerId.Contains(input.contactTel))
.WhereIF(!string.IsNullOrEmpty(input.auditState), it => it.AuditState.Equals(input.auditState))
.WhereIF(!string.IsNullOrEmpty(input.closeState), it => it.CloseState.Equals(input.closeState))
.Select(it => new ProductListOutput
{
id = it.Id,
code = it.Code,
customerName = it.CustomerName,
business = it.Business,
address = it.Address,
contactTel = it.ContactTel,
salesmanName = it.SalesmanName,
auditState = it.AuditState,
goodsState = it.GoodsState,
closeState = it.CloseState,
closeDate = it.CloseDate,
contactName = it.ContactName
}).MergeTable().OrderByIF(string.IsNullOrEmpty(input.sidx), it => it.id).OrderByIF(!string.IsNullOrEmpty(input.sidx), input.sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult<ProductListOutput>.SqlSugarPageResult(data);
}
/// <summary>
/// 获取订单示例列表.
/// </summary>
/// <param name="id">请求参数.</param>
/// <returns></returns>
[HttpGet("ProductEntry/{id}")]
public async Task<dynamic> GetProductEntryList(string id)
{
string data = "[{\"id\":\"37c995b4044541009fb7e285bcf9845d\",\"productSpecification\":\"120ml\",\"qty\":16,\"money\":510,\"price\":120,\"commandType\":\"唯一码\",\"util\":\"盒\"},{\"id\":\"2dbb11d3cde04c299985ac944d130ba0\",\"productSpecification\":\"150ml\",\"qty\":15,\"money\":520,\"price\":310,\"commandType\":\"唯一码\",\"util\":\"盒\"},{\"id\":\"f8ec261ccdf045e5a2e1f0e5485cda76\",\"productSpecification\":\"40ml\",\"qty\":13,\"money\":530,\"price\":140,\"commandType\":\"唯一码\",\"util\":\"盒\"},{\"id\":\"6c110b57ae56445faa8ce9be501c8997\",\"productSpecification\":\"103ml\",\"qty\":2,\"money\":504,\"price\":150,\"commandType\":\"唯一码\",\"util\":\"盒\"},{\"id\":\"f2ee981aaf934147a4d090a0eed2203f\",\"productSpecification\":\"120ml\",\"qty\":21,\"money\":550,\"price\":160,\"commandType\":\"唯一码\",\"util\":\"盒\"}]";
List<ProductEntryMdoel> dataAll = data.ToObject<List<ProductEntryMdoel>>();
List<ProductEntryListOutput> productEntryList = await _repository.AsSugarClient().Queryable<ProductEntryEntity>().Where(it => it.ProductId.Equals(id)).Select(it => new ProductEntryListOutput
{
productCode = it.ProductCode,
productName = it.ProductName,
qty = it.Qty,
type = it.Type,
activity = it.Activity,
}).ToListAsync();
productEntryList.ForEach(item =>
{
item.dataList = new List<ProductEntryMdoel>();
List<ProductEntryMdoel> dataList = new List<ProductEntryMdoel>();
var randomData = new Random();
int num = randomData.Next(1, dataAll.Count);
for (int i = 0; i < num; i++)
{
dataList.Add(dataAll[i]);
}
item.dataList = dataList;
});
return new { list = productEntryList };
}
}

View File

@@ -0,0 +1,238 @@
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Filter;
using JNPF.Common.Security;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.Extend.Entitys;
using JNPF.Extend.Entitys.Dto.ProjectGantt;
using JNPF.FriendlyException;
using JNPF.Systems.Entitys.Permission;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
namespace JNPF.Extend;
/// <summary>
/// 项目计划
/// 版 本V3.2
/// 版 权拓通智联科技有限公司http://www.tuotong-tech.com
/// 日 期2021-06-01 .
/// </summary>
[ApiDescriptionSettings(Tag = "Extend", Name = "ProjectGantt", Order = 600)]
[Route("api/extend/[controller]")]
public class ProjectGanttService : IDynamicApiController, ITransient
{
private readonly ISqlSugarRepository<ProjectGanttEntity> _repository;
public ProjectGanttService(ISqlSugarRepository<ProjectGanttEntity> repository)
{
_repository = repository;
}
#region GET
/// <summary>
/// 项目列表.
/// </summary>
/// <param name="input">请求参数</param>
/// <returns></returns>
[HttpGet("")]
public async Task<dynamic> GetList([FromQuery] KeywordInput input)
{
var data = await _repository.AsQueryable().Where(x => x.Type == 1 && x.DeleteMark == null)
.WhereIF(input.keyword.IsNotEmptyOrNull(), x => x.FullName.Contains(input.keyword))
.OrderBy(x => x.SortCode).OrderBy(x => x.CreatorTime, OrderByType.Desc)
.OrderByIF(!string.IsNullOrEmpty(input.keyword), t => t.LastModifyTime, OrderByType.Desc).ToListAsync();
var output = data.Adapt<List<ProjectGanttListOutput>>();
await GetManagersInfo(output);
return new { list = output };
}
/// <summary>
/// 任务列表.
/// </summary>
/// <param name="input">请求参数.</param>
/// <param name="projectId">项目Id.</param>
/// <returns></returns>
[HttpGet("{projectId}/Task")]
public async Task<dynamic> GetTaskList([FromQuery] KeywordInput input, string projectId)
{
var data = await _repository.AsQueryable()
.Where(x => x.Type == 2 && x.ProjectId == projectId && x.DeleteMark == null)
.OrderBy(x => x.SortCode).OrderBy(x => x.CreatorTime, OrderByType.Desc)
.OrderByIF(!string.IsNullOrEmpty(input.keyword), t => t.LastModifyTime, OrderByType.Desc).ToListAsync();
data.Add(await _repository.GetFirstAsync(x => x.Id == projectId));
if (!string.IsNullOrEmpty(input.keyword))
{
data = data.TreeWhere(t => t.FullName.Contains(input.keyword), t => t.Id, t => t.ParentId);
}
var output = data.Adapt<List<ProjectGanttTaskListOutput>>();
return new { list = output.ToTree() };
}
/// <summary>
/// 任务树形.
/// </summary>
/// <param name="projectId">项目Id.</param>
/// <returns></returns>
[HttpGet("{projectId}/Task/Selector/{id}")]
public async Task<dynamic> GetTaskTreeView(string projectId, string id)
{
var data = (await _repository.AsQueryable().Where(x => x.Type == 2 && x.ProjectId == projectId && x.DeleteMark == null).OrderBy(x => x.CreatorTime, OrderByType.Desc).ToListAsync());
data.Add(await _repository.GetFirstAsync(x => x.Id == projectId));
if (!id.Equals("0"))
{
data.RemoveAll(x => x.Id == id);
}
var output = data.Adapt<List<ProjectGanttTaskTreeViewOutput>>();
return new { list = output.ToTree() };
}
/// <summary>
/// 信息.
/// </summary>
/// <param name="id">主键值.</param>
/// <returns></returns>
[HttpGet("{id}")]
public async Task<dynamic> GetInfo(string id)
{
var data = (await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null)).Adapt<ProjectGanttInfoOutput>();
return data;
}
/// <summary>
/// 项目任务信息.
/// </summary>
/// <param name="taskId">主键值.</param>
/// <returns></returns>
[HttpGet("Task/{taskId}")]
public async Task<dynamic> GetTaskInfo(string taskId)
{
return (await _repository.GetFirstAsync(x => x.Id == taskId && x.DeleteMark == null)).Adapt<ProjectGanttTaskInfoOutput>();
}
#endregion
#region POST
/// <summary>
/// 删除.
/// </summary>
/// <param name="id">主键值</param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task Delete(string id)
{
if (await _repository.IsAnyAsync(x => x.ParentId != id && x.DeleteMark == null))
{
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
if (entity != null)
{
int isOk = await _repository.AsSugarClient().Updateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1002);
}
else
{
throw Oops.Oh(ErrorCode.COM1005);
}
}
else
{
throw Oops.Oh(ErrorCode.D1007);
}
}
/// <summary>
/// 创建.
/// </summary>
/// <param name="input">实体对象.</param>
/// <returns></returns>
[HttpPost("")]
public async Task Create([FromBody] ProjectGanttCrInput input)
{
if (await _repository.IsAnyAsync(x => x.EnCode == input.enCode && x.DeleteMark == null) || await _repository.IsAnyAsync(x => x.FullName == input.fullName && x.DeleteMark == null))
throw Oops.Oh(ErrorCode.COM1004);
var entity = input.Adapt<ProjectGanttEntity>();
entity.Type = 1;
entity.ParentId = "0";
var isOk = await _repository.AsSugarClient().Insertable(entity).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1000);
}
/// <summary>
/// 编辑.
/// </summary>
/// <param name="id">主键值.</param>
/// <param name="input">实体对象.</param>
/// <returns></returns>
[HttpPut("{id}")]
public async Task Update(string id, [FromBody] ProjectGanttUpInput input)
{
if (await _repository.IsAnyAsync(x => x.Id != id && x.EnCode == input.enCode && x.DeleteMark == null) || await _repository.IsAnyAsync(x => x.Id != id && x.FullName == input.fullName && x.DeleteMark == null))
throw Oops.Oh(ErrorCode.COM1004);
var entity = input.Adapt<ProjectGanttEntity>();
var isOk = await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1001);
}
/// <summary>
/// 创建.
/// </summary>
/// <param name="input">实体对象.</param>
/// <returns></returns>
[HttpPost("Task")]
public async Task CreateTask([FromBody] ProjectGanttTaskCrInput input)
{
var entity = input.Adapt<ProjectGanttEntity>();
entity.Type = 2;
var isOk = await _repository.AsSugarClient().Insertable(entity).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1000);
}
/// <summary>
/// 编辑.
/// </summary>
/// <param name="id">主键值.</param>
/// <param name="input">实体对象.</param>
/// <returns></returns>
[HttpPut("Task/{id}")]
public async Task UpdateTask(string id, [FromBody] ProjectGanttTaskUpInput input)
{
var entity = input.Adapt<ProjectGanttEntity>();
var isOk = await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1001);
}
#endregion
#region PrivateMethod
/// <summary>
/// 项目参与人员.
/// </summary>
/// <param name="outputList"></param>
/// <returns></returns>
private async Task GetManagersInfo(List<ProjectGanttListOutput> outputList)
{
foreach (var output in outputList)
{
foreach (var id in output.managerIds.Split(","))
{
var managerInfo = new ManagersInfo();
var userInfo = await _repository.AsSugarClient().Queryable<UserEntity>().FirstAsync(x => x.Id == id && x.DeleteMark == null);
if (userInfo != null)
{
managerInfo.account = userInfo.RealName + "/" + userInfo.Account;
managerInfo.headIcon = string.IsNullOrEmpty(userInfo.HeadIcon) ? string.Empty : "/api/file/Image/userAvatar/" + userInfo.HeadIcon;
output.managersInfo.Add(managerInfo);
}
}
}
}
#endregion
}

View File

@@ -0,0 +1,163 @@
using JNPF.Common.Core.Manager;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.Extend.Entitys;
using JNPF.Extend.Entitys.Dto.Schedule;
using JNPF.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
namespace JNPF.Extend;
/// <summary>
/// 项目计划
/// 版 本V3.2
/// 版 权拓通智联科技有限公司http://www.tuotong-tech.com
/// 日 期2021-06-01 .
/// </summary>
[ApiDescriptionSettings(Tag = "Extend", Name = "Schedule", Order = 600)]
[Route("api/extend/[controller]")]
public class ScheduleService : IDynamicApiController, ITransient
{
private readonly ISqlSugarRepository<ScheduleEntity> _repository;
private readonly IUserManager _userManager;
public ScheduleService(
ISqlSugarRepository<ScheduleEntity> repository,
IUserManager userManager)
{
_repository = repository;
_userManager = userManager;
}
#region GET
/// <summary>
/// 列表.
/// </summary>
/// <param name="input">参数</param>
/// <returns></returns>
[HttpGet("")]
public async Task<dynamic> GetList([FromQuery] ScheduleListQuery input)
{
var data = await _repository.AsQueryable()
.Where(x => x.CreatorUserId == _userManager.UserId && x.StartTime >= input.startTime.ParseToDateTime() && x.EndTime <= input.endTime.ParseToDateTime() && x.DeleteMark == null).OrderBy(x => x.StartTime, OrderByType.Desc).ToListAsync();
var output = data.Adapt<List<ScheduleListOutput>>();
return new { list = output };
}
/// <summary>
/// 信息.
/// </summary>
/// <param name="id">主键值</param>
/// <returns></returns>
[HttpGet("{id}")]
public async Task<dynamic> GetInfo(string id)
{
return (await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null)).Adapt<ScheduleInfoOutput>();
}
/// <summary>
/// app.
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpGet("AppList")]
public async Task<dynamic> GetAppList([FromQuery] ScheduleListQuery input)
{
var days = new Dictionary<string, int>();
var data = await _repository.AsQueryable()
.Where(x => x.CreatorUserId == _userManager.UserId && x.StartTime >= input.startTime.ParseToDateTime() && x.EndTime <= input.endTime.ParseToDateTime() && x.DeleteMark == null)
.OrderBy(x => x.StartTime, OrderByType.Desc).ToListAsync();
var output = data.Adapt<List<ScheduleListOutput>>();
foreach (var item in GetAllDays(input.startTime.ParseToDateTime(), input.endTime.ParseToDateTime()))
{
var _startTime = item.ToString("yyyy-MM-dd") + " 23:59";
var _endTime = item.ToString("yyyy-MM-dd") + " 00:00";
var count = output.FindAll(m => m.startTime <= _startTime.ParseToDateTime() && m.endTime >= _endTime.ParseToDateTime()).Count;
days.Add(item.ToString("yyyyMMdd"), count);
}
var today_startTime = input.dateTime + " 23:59";
var today_endTime = input.dateTime + " 00:00";
return new
{
signList = days,
todayList = output.FindAll(m => m.startTime <= today_startTime.ParseToDateTime() && m.endTime >= today_endTime.ParseToDateTime())
};
}
#endregion
#region POST
/// <summary>
/// 新建.
/// </summary>
/// <param name="input">实体对象</param>
/// <returns></returns>
[HttpPost("")]
public async Task Create([FromBody] ScheduleCrInput input)
{
var entity = input.Adapt<ScheduleEntity>();
var isOk = await _repository.AsSugarClient().Insertable(entity).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1000);
}
/// <summary>
/// 更新
/// </summary>
/// <param name="id">主键值</param>
/// <param name="input">实体对象</param>
/// <returns></returns>
[HttpPut("{id}")]
public async Task Update(string id, [FromBody] ScheduleUpInput input)
{
var entity = input.Adapt<ScheduleEntity>();
var isOk = await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1001);
}
/// <summary>
/// 删除.
/// </summary>
/// <param name="id">主键值</param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task Delete(string id)
{
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
if (entity == null)
throw Oops.Oh(ErrorCode.COM1005);
var isOk = await _repository.AsSugarClient().Updateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1002);
}
#endregion
#region PrivateMethod
/// <summary>
/// 获取固定日期范围内的所有日期,以数组形式返回.
/// </summary>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
private DateTime[] GetAllDays(DateTime startTime, DateTime endTime)
{
var listDay = new List<DateTime>();
DateTime dtDay = new DateTime();
//循环比较,取出日期;
for (dtDay = startTime; dtDay.CompareTo(endTime) <= 0; dtDay = dtDay.AddDays(1))
{
listDay.Add(dtDay);
}
return listDay.ToArray();
}
#endregion
}

View File

@@ -0,0 +1,385 @@
using System.Reflection;
using JNPF.Common.Core.Manager;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Filter;
using JNPF.Common.Security;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.Extend.Entitys;
using JNPF.Extend.Entitys.Dto.TableExample;
using JNPF.Extend.Entitys.Model;
using JNPF.FriendlyException;
using JNPF.LinqBuilder;
using JNPF.Systems.Entitys.Permission;
using JNPF.Systems.Entitys.System;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using SqlSugar;
using Yitter.IdGenerator;
namespace JNPF.Extend;
/// <summary>
/// 表格示例数据
/// 版 本V3.2
/// 版 权拓通智联科技有限公司http://www.tuotong-tech.com
/// 日 期2021-06-01 .
/// </summary>
[ApiDescriptionSettings(Tag = "Extend", Name = "TableExample", Order = 600)]
[Route("api/extend/[controller]")]
public class TableExampleService : IDynamicApiController, ITransient
{
private readonly ISqlSugarRepository<TableExampleEntity> _repository;
private readonly IUserManager _userManager;
public TableExampleService(
ISqlSugarRepository<TableExampleEntity> repository,
IUserManager userManager)
{
_repository = repository;
_userManager = userManager;
}
#region GET
/// <summary>
 /// 获取表格数据列表.
 /// </summary>
/// <param name="input">请求参数</param>
/// <returns></returns>
[HttpGet("")]
public async Task<dynamic> GetList([FromQuery] PageInputBase input)
{
return await GetPageList(string.Empty, input);
}
/// <summary>
/// 列表(树形表格)
/// </summary>
/// <param name="typeId"></param>
/// <param name="input"></param>
/// <returns></returns>
[HttpGet("ControlSample/{typeId}")]
public async Task<dynamic> GetList(string typeId, [FromQuery] PageInputBase input)
{
return await GetPageList(typeId, input);
}
/// <summary>
/// 列表.
/// </summary>
/// <returns></returns>
[HttpGet("All")]
public async Task<dynamic> GetListAll([FromQuery] KeywordInput input)
{
var list = await _repository.AsSugarClient().Queryable<TableExampleEntity, UserEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.Registrant == b.Id))
.WhereIF(input.keyword.IsNotEmptyOrNull(), a => a.ProjectCode.Contains(input.keyword) || a.ProjectName.Contains(input.keyword) || a.CustomerName.Contains(input.keyword)).OrderBy(a => a.RegisterDate, OrderByType.Desc)
.Select((a, b) => new TableExampleAllOutput()
{
id = a.Id,
interactionDate = a.InteractionDate,
projectCode = a.ProjectCode,
projectName = a.ProjectName,
principal = a.Principal,
jackStands = a.JackStands,
projectType = a.ProjectType,
projectPhase = a.ProjectPhase,
customerName = a.CustomerName,
costAmount = a.CostAmount,
tunesAmount = a.TunesAmount,
projectedIncome = a.ProjectedIncome,
registerDate = a.RegisterDate,
registrant = SqlFunc.MergeString(b.RealName, "/", b.Account),
description = a.Description
}).ToListAsync();
return new { list = list };
}
/// <summary>
/// 获取延伸扩展列表(行政区划).
/// </summary>
/// <returns></returns>
[HttpGet("IndustryList")]
public async Task<dynamic> GetIndustryList([FromQuery] KeywordInput input)
{
var data = (await _repository.AsSugarClient().Queryable<ProvinceEntity>()
.WhereIF(input.keyword.IsNotEmptyOrNull(), x => x.EnCode.Contains(input.keyword) || x.FullName.Contains(input.keyword))
.Where(m => m.ParentId == "-1" && m.DeleteMark == null).ToListAsync()).Adapt<List<TableExampleIndustryListOutput>>();
return new { list = data };
}
/// <summary>
/// 获取城市信息列表(获取延伸扩展列表(行政区划))
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("CityList/{id}")]
public async Task<dynamic> GetCityList(string id)
{
var data = (await _repository.AsSugarClient().Queryable<ProvinceEntity>().Where(m => m.ParentId == id && m.DeleteMark == null).ToListAsync()).Adapt<List<TableExampleCityListOutput>>();
return new { list = data };
}
/// <summary>
/// 列表(表格树形).
/// </summary>
/// <returns></returns>
[HttpGet("ControlSample/TreeList")]
public async Task<dynamic> GetTreeList(string isTree)
{
var dicData = await _repository.AsSugarClient().Queryable<DictionaryDataEntity, DictionaryTypeEntity>((a, b) =>
new JoinQueryInfos(JoinType.Left, a.DictionaryTypeId == b.Id)).Where((a, b) => b.EnCode == "IndustryType" && a.DeleteMark == null
&& b.DeleteMark == null).Select(a => a).ToListAsync();
var data = dicData.FindAll(x => x.EnabledMark == 1);
var treeList = data.Select(x => new TableExampleTreeListOutput()
{
id = x.Id,
parentId = x.ParentId,
text = x.FullName,
loaded = true,
expanded = true,
ht = x.Adapt<Dictionary<string, object>>()
}).ToList();
var output = isTree.IsNotEmptyOrNull() && "1".Equals(isTree) ? treeList.ToTree() : treeList;
return new { list = output };
}
/// <summary>
/// 信息
/// </summary>
/// <param name="id">主键值</param>
/// <returns></returns>
[HttpGet, Route("{id}")]
public async Task<dynamic> GetInfo(string id)
{
var data = (await _repository.GetFirstAsync(x => x.Id == id)).Adapt<TableExampleInfoOutput>();
return data;
}
/// <summary>
/// 获取批注
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("{id}/Actions/Postil")]
public async Task<dynamic> GetPostil(string id)
{
var tableExampleEntity = await _repository.GetFirstAsync(x => x.Id == id);
if (tableExampleEntity == null)
throw Oops.Oh(ErrorCode.COM1007);
return new { postilJson = tableExampleEntity.PostilJson };
}
#endregion
#region POST
/// <summary>
/// 删除.
 /// </summary>
/// <param name="id">主键值</param>
 /// <returns></returns>
[HttpDelete("{id}")]
public async Task Delete(string id)
{
var entity = await _repository.GetFirstAsync(x => x.Id == id);
if (entity != null)
{
await _repository.DeleteAsync(entity);
}
}
/// <summary>
/// 创建.
/// </summary>
/// <param name="input">实体对象</param>
/// <returns></returns>
[HttpPost("")]
public async Task Create([FromBody] TableExampleCrInput input)
{
var entity = input.Adapt<TableExampleEntity>();
entity.Id = YitIdHelper.NextId().ToString();
entity.RegisterDate = DateTime.Now;
entity.Registrant = _userManager.UserId;
entity.CostAmount = entity.CostAmount == null ? 0 : entity.CostAmount;
entity.TunesAmount = entity.TunesAmount == null ? 0 : entity.TunesAmount;
entity.ProjectedIncome = entity.ProjectedIncome == null ? 0 : entity.ProjectedIncome;
entity.Sign = "0000000";
await _repository.InsertAsync(entity);
}
/// <summary>
/// 编辑.
/// </summary>
/// <param name="id">主键</param>
/// <param name="input">实体对象</param>
/// <returns></returns>
[HttpPut("{id}")]
public async Task Update(string id, [FromBody] TableExampleUpInput input)
{
var entity = input.Adapt<TableExampleEntity>();
entity.Id = id;
entity.LastModifyTime = DateTime.Now;
entity.LastModifyUserId = _userManager.UserId;
entity.CostAmount = entity.CostAmount == null ? 0 : entity.CostAmount;
entity.TunesAmount = entity.TunesAmount == null ? 0 : entity.TunesAmount;
entity.ProjectedIncome = entity.ProjectedIncome == null ? 0 : entity.ProjectedIncome;
await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
}
/// <summary>
/// 更新标签.
/// </summary>
/// <param name="id">主键</param>
/// <param name="input">实体对象</param>
/// <returns></returns>
[HttpPut("UpdateSign/{id}")]
public async Task UpdateSign(string id, [FromBody] TableExampleSignUpInput input)
{
var tableExampleEntity = await _repository.GetFirstAsync(x => x.Id == id);
tableExampleEntity.Sign = input.sign;
tableExampleEntity.Id = id;
tableExampleEntity.LastModifyTime = DateTime.Now;
tableExampleEntity.LastModifyUserId = _userManager.UserId;
await _repository.AsSugarClient().Updateable(tableExampleEntity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
}
/// <summary>
/// 行编辑
/// </summary>
/// <param name="id"></param>
/// <param name="input"></param>
/// <returns></returns>
[HttpPut("{id}/Actions/RowsEdit")]
public async Task RowEditing(string id, [FromBody] TableExampleRowUpInput input)
{
var entity = input.Adapt<TableExampleEntity>();
entity.Id = id;
entity.CostAmount = entity.CostAmount == null ? 0 : entity.CostAmount;
entity.TunesAmount = entity.TunesAmount == null ? 0 : entity.TunesAmount;
entity.ProjectedIncome = entity.ProjectedIncome == null ? 0 : entity.ProjectedIncome;
var tableExampleEntity = await _repository.GetFirstAsync(x => x.Id == id);
var exampleEntity = BindModelValue(tableExampleEntity, entity);
exampleEntity.LastModifyTime = DateTime.Now;
exampleEntity.LastModifyUserId = _userManager.UserId;
await _repository.AsSugarClient().Updateable(tableExampleEntity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
}
/// <summary>
/// 发送批注
/// </summary>
/// <param name="id"></param>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("{id}/Postil")]
public async Task SendPostil(string id, [FromBody] TableExamplePostilSendInput input)
{
var tableExampleEntity = await _repository.GetFirstAsync(x => x.Id == id);
if (tableExampleEntity == null)
throw Oops.Oh(ErrorCode.COM1005);
var model = new PostilModel()
{
userId = string.Format("{0}/{1}", _userManager.Account, _userManager.RealName),
text = input.text,
creatorTime = DateTime.Now
};
var list = new List<PostilModel>();
list.Add(model);
if (tableExampleEntity.PostilJson.IsNotEmptyOrNull())
{
list = list.Concat(tableExampleEntity.PostilJson.ToList<PostilModel>()).ToList();
}
tableExampleEntity.PostilJson = JsonConvert.SerializeObject(list, new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" });
tableExampleEntity.PostilCount = list.Count;
tableExampleEntity.Id = id;
tableExampleEntity.LastModifyTime = DateTime.Now;
tableExampleEntity.LastModifyUserId = _userManager.UserId;
await _repository.AsSugarClient().Updateable(tableExampleEntity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
}
/// <summary>
/// 删除批注
/// </summary>
/// <param name="id">主键值</param>
/// <param name="index">请求参数</param>
/// <returns></returns>
[HttpDelete("{id}/Postil/{index}")]
public async Task DeletePostil(string id, int index)
{
var tableExampleEntity = await _repository.GetFirstAsync(x => x.Id == id);
if (tableExampleEntity == null)
throw Oops.Oh(ErrorCode.COM1005);
var list = tableExampleEntity.PostilJson.ToList<PostilModel>();
list.Remove(list[index]);
tableExampleEntity.PostilJson = list.ToJsonString();
tableExampleEntity.PostilCount = list.Count;
tableExampleEntity.Id = id;
tableExampleEntity.LastModifyTime = DateTime.Now;
tableExampleEntity.LastModifyUserId = _userManager.UserId;
await _repository.AsSugarClient().Updateable(tableExampleEntity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
}
#endregion
#region PrivateMethod
/// <summary>
/// 分页列表.
/// </summary>
/// <param name="typeId"></param>
/// <param name="input"></param>
/// <returns></returns>
private async Task<dynamic> GetPageList(string typeId, PageInputBase input)
{
var list = await _repository.AsSugarClient().Queryable<TableExampleEntity, UserEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.Registrant == b.Id))
.WhereIF(typeId.IsNotEmptyOrNull(), a => a.ProjectType == typeId)
.WhereIF(input.keyword.IsNotEmptyOrNull(), a => a.ProjectCode.Contains(input.keyword) || a.ProjectName.Contains(input.keyword))
.OrderBy(a => a.RegisterDate, OrderByType.Desc)
.Select((a, b) => new TableExampleListOutput()
{
id = a.Id,
interactionDate = a.InteractionDate,
projectCode = a.ProjectCode,
projectName = a.ProjectName,
principal = a.Principal,
jackStands = a.JackStands,
projectType = a.ProjectType,
projectPhase = a.ProjectPhase,
customerName = a.CustomerName,
costAmount = a.CostAmount,
tunesAmount = a.TunesAmount,
projectedIncome = a.ProjectedIncome,
registerDate = a.RegisterDate,
registrant = SqlFunc.MergeString(b.RealName, "/", b.Account),
description = a.Description,
sign = a.Sign,
postilJson = a.Sign,
postilCount = a.PostilCount.ToString(),
}).ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult<TableExampleListOutput>.SqlSugarPageResult(list);
}
/// <summary>
/// 将实体2的值动态赋值给实体1(名称一样的属性进行赋值)
/// </summary>
/// <param name="entity1">实体1</param>
/// <param name="entity2">实体2</param>
/// <returns>赋值后的model1</returns>
private T1 BindModelValue<T1, T2>(T1 entity1, T2 entity2) where T1 : class where T2 : class
{
Type t1 = entity1.GetType();
Type t2 = entity2.GetType();
PropertyInfo[] property2 = t2.GetProperties();
//排除字段
List<string> exclude = new List<string>() { "F_Id", "F_Registrant", "F_RegisterDate", "F_SortCode", "F_Sign", "F_PostilJson", "F_PostilCount" };
foreach (PropertyInfo p in property2)
{
if (exclude.Contains(p.Name)) { continue; }
t1.GetProperty(p.Name)?.SetValue(entity1, p.GetValue(entity2, null));
}
return entity1;
}
#endregion
}

View File

@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)\common.props" />
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\common\Tnb.Common.Core\Tnb.Common.Core.csproj" />
<ProjectReference Include="..\..\system\Tnb.Systems.Interfaces\Tnb.Systems.Interfaces.csproj" />
<ProjectReference Include="..\..\workflow\Tnb.WorkFlow.Interfaces\Tnb.WorkFlow.Interfaces.csproj" />
<ProjectReference Include="..\Tnb.Extend.Interfaces\Tnb.Extend.Interfaces.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,205 @@
using JNPF.Common.Core.Manager;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Filter;
using JNPF.Common.Security;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.Extend.Entitys;
using JNPF.Extend.Entitys.Dto.WoekLog;
using JNPF.Extend.Entitys.Dto.WorkLog;
using JNPF.FriendlyException;
using JNPF.Systems.Interfaces.Permission;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using Yitter.IdGenerator;
namespace JNPF.Extend;
/// <summary>
/// 工作日志
/// 版 本V3.2
/// 版 权拓通智联科技有限公司http://www.tuotong-tech.com
/// 日 期2021-06-01 .
/// </summary>
[ApiDescriptionSettings(Tag = "Extend", Name = "WorkLog", Order = 600)]
[Route("api/extend/[controller]")]
public class WorkLogService : IDynamicApiController, ITransient
{
private readonly ISqlSugarRepository<WorkLogEntity> _repository;
private readonly IUsersService _usersService;
private readonly IUserManager _userManager;
private readonly ITenant _db;
public WorkLogService(ISqlSugarRepository<WorkLogEntity> repository, IUsersService usersService, IUserManager userManager, ISqlSugarClient context)
{
_repository = repository;
_usersService = usersService;
_userManager = userManager;
_db = context.AsTenant();
}
#region Get
/// <summary>
/// 列表(我发出的)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpGet("Send")]
public async Task<dynamic> GetSendList([FromQuery] PageInputBase input)
{
var list = await _repository.AsQueryable().Where(x => x.CreatorUserId == _userManager.UserId && x.DeleteMark == null)
.WhereIF(input.keyword.IsNotEmptyOrNull(), m => m.Title.Contains(input.keyword) || m.Description.Contains(input.keyword))
.OrderBy(x => x.SortCode).OrderBy(x => x.CreatorTime, OrderByType.Desc)
.OrderByIF(!string.IsNullOrEmpty(input.keyword), t => t.LastModifyTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
var pageList = new SqlSugarPagedList<WorkLogListOutput>()
{
list = list.list.Adapt<List<WorkLogListOutput>>(),
pagination = list.pagination
};
return PageResult<WorkLogListOutput>.SqlSugarPageResult(pageList);
}
/// <summary>
/// 列表(我收到的)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpGet("Receive")]
public async Task<dynamic> GetReceiveList([FromQuery] PageInputBase input)
{
var list = await _repository.AsSugarClient().Queryable<WorkLogEntity, WorkLogShareEntity>(
(a, b) => new JoinQueryInfos(JoinType.Left, a.Id == b.WorkLogId))
.Where((a, b) => a.DeleteMark == null && b.ShareUserId == _userManager.UserId)
.WhereIF(input.keyword.IsNotEmptyOrNull(), a => a.Title.Contains(input.keyword))
.Select(a => new WorkLogListOutput()
{
id = a.Id,
title = a.Title,
question = a.Question,
creatorTime = a.CreatorTime,
todayContent = a.TodayContent,
tomorrowContent = a.TomorrowContent,
toUserId = a.ToUserId,
sortCode = a.SortCode,
lastModifyTime = a.LastModifyTime
}).MergeTable()
.OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc)
.OrderByIF(!string.IsNullOrEmpty(input.keyword), t => t.lastModifyTime, OrderByType.Desc)
.ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult<WorkLogListOutput>.SqlSugarPageResult(list);
}
/// <summary>
/// 信息
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("{id}")]
public async Task<dynamic> GetInfo(string id)
{
var output = (await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null)).Adapt<WorkLogInfoOutput>();
output.userIds = output.toUserId;
output.toUserId = await _usersService.GetUserName(output.toUserId);
return output;
}
#endregion
#region Post
/// <summary>
/// 添加.
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("")]
public async Task Create([FromBody] WorkLogCrInput input)
{
try
{
var entity = input.Adapt<WorkLogEntity>();
entity.Id = SnowflakeIdHelper.NextId();
List<WorkLogShareEntity> workLogShareList = entity.ToUserId.Split(',').Select(x => new WorkLogShareEntity()
{
Id = YitIdHelper.NextId().ToString(),
ShareTime = DateTime.Now,
WorkLogId = entity.Id,
ShareUserId = x
}).ToList();
_db.BeginTran();
_repository.AsSugarClient().Insertable(workLogShareList).ExecuteCommand();
var isOk = await _repository.AsSugarClient().Insertable(entity).CallEntityMethod(m => m.Create()).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1000);
_db.CommitTran();
}
catch (Exception)
{
_db.RollbackTran();
throw Oops.Oh(ErrorCode.COM1000);
}
}
/// <summary>
/// 修改
/// </summary>
/// <param name="id"></param>
/// <param name="input"></param>
/// <returns></returns>
[HttpPut("{id}")]
public async Task Update(string id, [FromBody] WorkLogUpInput input)
{
try
{
var entity = input.Adapt<WorkLogEntity>();
List<WorkLogShareEntity> workLogShareList = entity.ToUserId.Split(',').Select(x => new WorkLogShareEntity()
{
Id = YitIdHelper.NextId().ToString(),
ShareTime = DateTime.Now,
WorkLogId = entity.Id,
ShareUserId = x
}).ToList();
_db.BeginTran();
_repository.AsSugarClient().Deleteable(workLogShareList).ExecuteCommand();
_repository.AsSugarClient().Insertable(workLogShareList).ExecuteCommand();
var isOk = await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1001);
_db.CommitTran();
}
catch (Exception)
{
_db.RollbackTran();
throw Oops.Oh(ErrorCode.COM1001);
}
}
/// <summary>
/// 删除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task Delete(string id)
{
try
{
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
if (entity == null)
throw Oops.Oh(ErrorCode.COM1005);
_db.BeginTran();
_repository.AsSugarClient().Deleteable<WorkLogShareEntity>(x => x.WorkLogId == id).ExecuteCommand();
var isOk = await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.Delete()).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1002);
_db.CommitTran();
}
catch (Exception)
{
_db.RollbackTran();
throw Oops.Oh(ErrorCode.COM1002);
}
}
#endregion
}