添加项目文件。
This commit is contained in:
128
extend/Tnb.Extend/BigDataService.cs
Normal file
128
extend/Tnb.Extend/BigDataService.cs
Normal 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
|
||||
}
|
||||
117
extend/Tnb.Extend/DocumentPreview.cs
Normal file
117
extend/Tnb.Extend/DocumentPreview.cs
Normal 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
|
||||
}
|
||||
438
extend/Tnb.Extend/DocumentService.cs
Normal file
438
extend/Tnb.Extend/DocumentService.cs
Normal 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
|
||||
}
|
||||
583
extend/Tnb.Extend/EmailService.cs
Normal file
583
extend/Tnb.Extend/EmailService.cs
Normal 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
|
||||
}
|
||||
412
extend/Tnb.Extend/EmployeeService.cs
Normal file
412
extend/Tnb.Extend/EmployeeService.cs
Normal 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
|
||||
}
|
||||
321
extend/Tnb.Extend/OrderService.cs
Normal file
321
extend/Tnb.Extend/OrderService.cs
Normal file
File diff suppressed because one or more lines are too long
117
extend/Tnb.Extend/ProductClassifyService.cs
Normal file
117
extend/Tnb.Extend/ProductClassifyService.cs
Normal 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
|
||||
}
|
||||
158
extend/Tnb.Extend/ProductService.cs
Normal file
158
extend/Tnb.Extend/ProductService.cs
Normal 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 };
|
||||
}
|
||||
}
|
||||
238
extend/Tnb.Extend/ProjectGanttService.cs
Normal file
238
extend/Tnb.Extend/ProjectGanttService.cs
Normal 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
|
||||
}
|
||||
163
extend/Tnb.Extend/ScheduleService.cs
Normal file
163
extend/Tnb.Extend/ScheduleService.cs
Normal 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
|
||||
}
|
||||
385
extend/Tnb.Extend/TableExampleService.cs
Normal file
385
extend/Tnb.Extend/TableExampleService.cs
Normal 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
|
||||
}
|
||||
18
extend/Tnb.Extend/Tnb.Extend.csproj
Normal file
18
extend/Tnb.Extend/Tnb.Extend.csproj
Normal 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>
|
||||
205
extend/Tnb.Extend/WorkLogService.cs
Normal file
205
extend/Tnb.Extend/WorkLogService.cs
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user