You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DSWMS/Vue.Net/VOL.Core/BaseProvider/ServiceBase.cs

3146 lines
132 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Logical;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using VOL.Core.CacheManager;
using VOL.Core.Configuration;
using VOL.Core.Const;
using VOL.Core.Enums;
using VOL.Core.Extensions;
using VOL.Core.Extensions.AutofacManager;
using VOL.Core.Filters;
using VOL.Core.ManageUser;
using VOL.Core.Services;
using VOL.Core.Utilities;
using VOL.Entity;
using VOL.Entity.DomainModels;
using VOL.Entity.SystemModels;
using System.Drawing.Text;
//using System.Data.SqlClient;
using Microsoft.Data.SqlClient;
using AutoMapper;
using VOL.Core.DBManager;
using VOL.Core.Infrastructure;
using System.Collections.ObjectModel;
using System.Data;
using ConvertHelper;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
namespace VOL.Core.BaseProvider
{
public abstract class ServiceBase<T, TRepository> : ServiceFunFilter<T>
where T : BaseEntity
where TRepository : IRepository<T>
{
public ICacheService CacheContext
{
get
{
return AutofacContainerModule.GetService<ICacheService>();
}
}
public Microsoft.AspNetCore.Http.HttpContext Context
{
get
{
return HttpContext.Current;
}
}
private WebResponseContent Response { get; set; }
protected IRepository<T> repository;
private PropertyInfo[] _propertyInfo { get; set; } = null;
private PropertyInfo[] TProperties
{
get
{
if (_propertyInfo != null)
{
return _propertyInfo;
}
_propertyInfo = typeof(T).GetProperties();
return _propertyInfo;
}
}
//用于标记正在执行的业务 防止重复执行
private static List<string> LockKeyList;
public class LockKeyHelper
{
private static readonly Lazy<LockKeyHelper> lazy = new Lazy<LockKeyHelper>(() => new LockKeyHelper());
public static LockKeyHelper Instance { get { return lazy.Value; } }
private LockKeyHelper() { }
public static int newno { get; set; } = 0;
public bool addLockKey(object key)
{
try
{
//logger.Debug("获取编号");
if (LockKeyList == null)
LockKeyList = new List<string>();
if (LockKeyList.Contains(key.ToString())) return false;
LockKeyList.Add(key.ToString());
return true;
}
catch (Exception ex)
{
//logger.Debug("获取编号错误");
return false;
}
finally
{
}
}
}
/// <summary>
/// 原锁定key方法 由于线程不安全 改为调用lazy单例的模式
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool addLockKey(object key) {
//if (LockKeyList == null)
// LockKeyList = new List<string>();
//if (LockKeyList.Contains(key.ToString())) return false;
//LockKeyList.Add(key.ToString());
//return true;
return LockKeyHelper.Instance.addLockKey(key);
}
public void delLockKey(object key) {
if (LockKeyList == null)
LockKeyList = new List<string>();
if (LockKeyList.Contains(key.ToString())) {
for (var _i = LockKeyList.Count - 1; _i >= 0; _i--) {
if (LockKeyList[_i] == key.ToString()) {
LockKeyList.RemoveAt(_i);
}
}
}
}
public ServiceBase()
{
}
public ServiceBase(TRepository repository)
{
Response = new WebResponseContent(true);
this.repository = repository;
}
protected virtual void Init(IRepository<T> repository)
{
}
/// <summary>
/// 2020.08.15添加自定义原生查询sql或多租户(查询、导出)
/// </summary>
/// <returns></returns>
private IQueryable<T> GetSearchQueryable()
{
//UserContext.Current.IsSuperAdmin超级管理员不限制数据
//自定sql,没有使用多租户直接执行自定义sql
if (QuerySql != null && (!IsMultiTenancy || UserContext.Current.IsSuperAdmin))
{
//将
return repository.DbContext.Set<T>().FromSqlRaw(QuerySql);
}
//没有自定sql与多租户执行默认查询
if ((QuerySql == null && !IsMultiTenancy) )
{
return repository.DbContext.Set<T>();
}
string multiTenancyString;
//多租户
if (QuerySql != null && IsMultiTenancy)
{
//自定sql+多租户
multiTenancyString = $"select * from ({QuerySql}) as mt ";
}
else
{
//如果是pgsql数据库请修改select * from 为pgsql的语法
multiTenancyString = $"select * from {typeof(T).GetEntityTableName()} ";
}
//多租户请继续完善下面sql,
//例如sql只显示自己创建的数据:
//multiTenancyString = multiTenancyString + " where createid=" + UserContext.Current.UserId;
return repository.DbContext.Set<T>().FromSqlRaw(multiTenancyString);
}
protected void SetQuerySqlCondition(PageDataOptions options, Dictionary<string, string> SearchName)
{
options = options ?? new PageDataOptions();
List<SearchParameters> searchParametersList = new List<SearchParameters>();
if (!string.IsNullOrEmpty(options.Wheres))
{
try
{
searchParametersList = options.Wheres.DeserializeObject<List<SearchParameters>>();
}
catch { }
}
QueryRelativeList?.Invoke(searchParametersList);
foreach (var item in searchParametersList)
{
if (!string.IsNullOrEmpty(item.Name))
{
var searchname = item.Name;
try
{
searchname = (SearchName == null || string.IsNullOrWhiteSpace(SearchName[item.Name])) ? item.Name : SearchName[item.Name];
}
catch (Exception e) { }
var searchparam = item.DisplayType.GetDBCondition();
if (searchparam == HtmlElementType.like)
{
item.Value = $"%{item.Value}%";
QuerySql += $" and {searchname} {searchparam} '{item.Value}' ";
}
else
if (searchparam == HtmlElementType.StartWith)
{
searchparam = HtmlElementType.like;
item.Value = $"{item.Value}%";
QuerySql += $" and {searchname} {searchparam} '{item.Value}' ";
}
else
if (searchparam == "in")
{
//searchparam = HtmlElementType.like;
//item.Value = $"{item.Value}%";
var _str = item.Value.Replace(",", "','");
QuerySql += $" and {searchname} in ('{_str}') ";
}
else
QuerySql += $" and {searchname} {searchparam} '{item.Value}' ";
}
else {
var searchparam = item.DisplayType.GetDBCondition();
if (searchparam == HtmlElementType.Exists)
{
QuerySql += $" and {item.Value} ";
}
}
}
}
/// <summary>
/// 2020.08.15添加获取多租户数据过滤sql删除、编辑
/// </summary>
/// <returns></returns>
private string GetMultiTenancySql(string ids, string tableKey)
{
string sql = $"select count(*) FROM {typeof(T).GetEntityTableName() } where {tableKey} in ({ids}) ";
if (DBType.Name == DbCurrentType.PgSql.ToString())
{
sql = $"select count(*) FROM \"public\".\"{typeof(T).GetEntityTableName()}\" where \"{tableKey}\" in ({ids}) ";
}
return sql;
}
/// <summary>
/// 2020.08.15添加多租户数据过滤(编辑)
/// </summary>
private void CheckUpdateMultiTenancy(string ids, string tableKey)
{
string sql = GetMultiTenancySql(ids, tableKey);
//请接着过滤条件
//例如sql只能(编辑)自己创建的数据:判断数据是不是当前用户创建的
//sql = $" {sql} and createid!={UserContext.Current.UserId}";
object obj = repository.DapperContext.ExecuteScalar(sql, null);
if (obj == null || obj.GetInt() > 0)
{
Response.Error("不能编辑此数据");
}
}
/// <summary>
/// 2020.08.15添加多租户数据过滤(删除)
/// </summary>
private void CheckDelMultiTenancy(string ids, string tableKey)
{
string sql = GetMultiTenancySql(ids, tableKey);
//请接着过滤条件
//例如sql只能(删除)自己创建的数据:找出不是自己创建的数据
//sql = $" {sql} and createid!={UserContext.Current.UserId}";
object obj = repository.DapperContext.ExecuteScalar(sql, null);
if (obj == null || obj.GetInt() > 0)
{
Response.Error("不能删除此数据");
}
}
//private const string _desc = "desc";
private const string _asc = "asc";
/// <summary>
/// 生成排序字段
/// </summary>
/// <param name="pageData"></param>
/// <param name="propertyInfo"></param>
private Dictionary<string, QueryOrderBy> GetPageDataSort(PageDataOptions pageData, PropertyInfo[] propertyInfo)
{
if (base.OrderByExpression != null)
{
return base.OrderByExpression.GetExpressionToDic();
}
//排序字段不存在直接移除
if (!string.IsNullOrEmpty(pageData.Sort) && !propertyInfo.Any(x => x.Name.ToLower() == pageData.Sort.ToLower()))
{
pageData.Sort = null;
}
//如果没有排序字段,则使用主键作为排序字段
if (string.IsNullOrEmpty(pageData.Sort))
{
PropertyInfo property = propertyInfo.GetKeyProperty();
//如果主键不是自增类型则使用appsettings.json中CreateMember->DateField配置的创建时间作为排序
if (property.PropertyType == typeof(int) || property.PropertyType == typeof(long))
{
if (!propertyInfo.Any(x => x.Name.ToLower() == pageData.Sort))
{
pageData.Sort = propertyInfo.GetKeyName();
}
}
else
{
if (!string.IsNullOrEmpty(AppSetting.CreateMember.DateField)
&& propertyInfo.Any(x => x.Name == AppSetting.CreateMember.DateField))
{
pageData.Sort = AppSetting.CreateMember.DateField;
}
else
{
pageData.Sort = propertyInfo.GetKeyName();
}
}
}
var result = new Dictionary<string, QueryOrderBy>();
return new Dictionary<string, QueryOrderBy>() { {
pageData.Sort, pageData.Order?.ToLower() == _asc? QueryOrderBy.Asc: QueryOrderBy.Desc
} };
}
/// <summary>
/// 验证排序与查询字段合法性
/// </summary>
/// <param name="options"></param>
/// <param name="queryable"></param>
/// <returns></returns>
public PageDataOptions ValidatePageOptions(PageDataOptions options, out IQueryable<T> queryable)
{
options = options ?? new PageDataOptions();
List<SearchParameters> searchParametersList = new List<SearchParameters>();
if (!string.IsNullOrEmpty(options.Wheres))
{
try
{
searchParametersList = options.Wheres.DeserializeObject<List<SearchParameters>>();
}
catch { }
}
QueryRelativeList?.Invoke(searchParametersList);
// Connection
// queryable = repository.DbContext.Set<T>();
//2020.08.15添加自定义原生查询sql或多租户
queryable = GetSearchQueryable();
//判断列的数据类型数字,日期的需要判断值的格式是否正确
for (int i = 0; i < searchParametersList.Count; i++)
{
SearchParameters x = searchParametersList[i];
if(string.IsNullOrWhiteSpace(x.SearchType))
x.SearchType = x.DisplayType.GetDBCondition();
//else
//x.DisplayType = x.DisplayType.GetDBCondition();
if (string.IsNullOrEmpty(x.Value) )
{
continue;
}
PropertyInfo property = TProperties.Where(c => c.Name.ToUpper() == x.Name.ToUpper()).FirstOrDefault();
//2020.06.25增加字段null处理
if (property == null)
continue;
// property
//移除查询的值与数据库类型不匹配的数据
object[] values = property.ValidationValueForDbType(x.Value.Split(',')).Where(q => q.Item1).Select(s => s.Item3).ToArray();
if (values == null || values.Length == 0)
{
continue;
}
if (x.SearchType == HtmlElementType.Contains)
x.Value = string.Join(",", values);
LinqExpressionType expressionType = x.SearchType.GetLinqCondition();
queryable = LinqExpressionType.In == expressionType
? queryable.Where(x.Name.CreateExpression<T>(values, expressionType))
: queryable.Where(x.Name.CreateExpression<T>(x.Value, expressionType));
}
options.TableName = base.TableName ?? typeof(T).Name;
return options;
}
/// <summary>
/// 加载页面数据 通用查询 基类
/// </summary>
/// <param name="loadSingleParameters"></param>
/// <returns></returns>
public virtual PageGridData<T> GetPageData(PageDataOptions options)
{
options = ValidatePageOptions(options, out IQueryable<T> queryable);
//获取排序字段
//Dictionary<string, QueryOrderBy> orderbyDic = GetPageDataSort(options, TProperties);
//PageGridData<T> pageGridData = new PageGridData<T>();
//if (QueryRelativeExpression != null)
//{
// queryable = QueryRelativeExpression.Invoke(queryable);
//}
//if (options.Export)
//{
// pageGridData.rows = queryable.GetIQueryableOrderBy(orderbyDic).Take(Limit).ToList();
//}
//else
//{
// pageGridData.rows = repository.IQueryablePage(queryable,
// options.Page,
// options.Rows,
// out int rowCount,
// orderbyDic).ToList();
// pageGridData.total = rowCount;
// //查询界面统计求等字段
// if (SummaryExpress != null)
// {
// pageGridData.summary = SummaryExpress.Invoke(queryable);
// //Func<T, T> groupExpress = x =>x;
// //pageGridData.summary = queryable.GroupBy(groupExpress).Select(SummaryExpress).FirstOrDefault();
// }
//}
//GetPageDataOnExecuted?.Invoke(pageGridData);
//return pageGridData;
return Do_GetPageData(options, queryable);
}
public PageGridData<T> Do_GetPageData(PageDataOptions options, IQueryable<T> queryable)
{
Dictionary<string, QueryOrderBy> orderbyDic = GetPageDataSort(options, TProperties);
PageGridData<T> pageGridData = new PageGridData<T>();
if (QueryRelativeExpression != null)
{
queryable = QueryRelativeExpression.Invoke(queryable);
}
if (options.Export)
{
pageGridData.rows = queryable.GetIQueryableOrderBy(orderbyDic).Take(Limit).ToList();
}
else
{
pageGridData.rows = repository.IQueryablePage(queryable,
options.Page,
options.Rows,
out int rowCount,
orderbyDic).ToList();
pageGridData.total = rowCount;
//查询界面统计求等字段
if (SummaryExpress != null)
{
pageGridData.summary = SummaryExpress.Invoke(queryable);
//Func<T, T> groupExpress = x =>x;
//pageGridData.summary = queryable.GroupBy(groupExpress).Select(SummaryExpress).FirstOrDefault();
}
}
GetPageDataOnExecuted?.Invoke(pageGridData);
return pageGridData;
}
public virtual object GetDetailPage(PageDataOptions pageData)
{
Type detailType = typeof(T).GetCustomAttribute<EntityAttribute>()?.DetailTable?[0];
if (detailType == null)
{
return null;
}
object obj = typeof(ServiceBase<T, TRepository>)
.GetMethod("GetDetailPage", BindingFlags.Instance | BindingFlags.NonPublic)
.MakeGenericMethod(new Type[] { detailType }).Invoke(this, new object[] { pageData });
return obj;
}
protected override object GetDetailSummary<Detail>(IQueryable<Detail> queryeable)
{
return null;
}
private PageGridData<Detail> GetDetailPage<Detail>(PageDataOptions options) where Detail : class
{
//校验查询值,排序字段,分页大小规则待完
PageGridData<Detail> gridData = new PageGridData<Detail>();
if (options.Value == null) return gridData;
//主表主键字段
string keyName = typeof(T).GetKeyName();
//生成查询条件
Expression<Func<Detail, bool>> whereExpression = keyName.CreateExpression<Detail>(options.Value, LinqExpressionType.Equal);
var queryeable = repository.DbContext.Set<Detail>().Where(whereExpression);
gridData.total = queryeable.Count();
string sortName = options.Sort ?? typeof(Detail).GetKeyName();
Dictionary<string, QueryOrderBy> orderBy = new Dictionary<string, QueryOrderBy>() { {
sortName,
options.Order == "asc" ?
QueryOrderBy.Asc :
QueryOrderBy.Desc } };
gridData.rows = queryeable
.GetIQueryableOrderBy(orderBy)
.Skip((options.Page - 1) * options.Rows)
.Take(options.Rows)
.ToList();
gridData.summary = GetDetailSummary<Detail>(queryeable);
return gridData;
}
/// <summary>
/// 上传文件
/// </summary>
/// <param name="files"></param>
/// <returns></returns>
public virtual WebResponseContent Upload(List<Microsoft.AspNetCore.Http.IFormFile> files)
{
if (files == null || files.Count == 0) return Response.Error("请上传文件");
var limitFiles = files.Where(x => x.Length > LimitUpFileSizee * 1024 * 1024).Select(s => s.FileName);
if (limitFiles.Count() > 0)
{
return Response.Error($"文件大小不能超过:{ LimitUpFileSizee}M,{string.Join(",", limitFiles)}");
}
string filePath = $"Upload/Tables/{typeof(T).GetEntityTableName()}/{DateTime.Now.ToString("yyyMMddHHmmsss") + new Random().Next(1000, 9999)}/";
string fullPath = filePath.MapPath(true);
int i = 0;
// List<string> fileNames = new List<string>();
try
{
if (!Directory.Exists(fullPath)) Directory.CreateDirectory(fullPath);
for (i = 0; i < files.Count; i++)
{
string fileName = files[i].FileName;
//20230830 增加处理 如果文件名称中带有+ - % & < > / # 则将其替换为_
fileName = BasicDALRef.FileNameDeal(fileName);
//if (fileNames.Contains(fileName))
//{
// fileName += $"({i}){fileName}";
//}
//fileNames.Add(fileName);
using (var stream = new FileStream(fullPath + fileName, FileMode.Create))
{
files[i].CopyTo(stream);
}
}
}
catch (Exception ex)
{
Logger.Error($"上传文件失败:{typeof(T).GetEntityTableCnName()},路径:{filePath},失败文件:{files[i]},{ex.Message + ex.StackTrace}");
return Response.Error("文件上传失败");
}
return Response.OK("文件上传成功", filePath);
}
/// <summary>
/// 上传文件-董家镇
/// </summary>
/// <param name="files"></param>
/// <returns></returns>
public virtual WebResponseContent UploadDJZ(List<Microsoft.AspNetCore.Http.IFormFile> files)
{
if (files == null || files.Count == 0) return Response.Error("请上传文件");
var limitFiles = files.Where(x => x.Length > LimitUpFileSizee * 1024 * 1024).Select(s => s.FileName);
if (limitFiles.Count() > 0)
{
return Response.Error($"文件大小不能超过:{ LimitUpFileSizee}M,{string.Join(",", limitFiles)}");
}
string filePath = $"Upload/Tables/{typeof(T).GetEntityTableName()}/{DateTime.Now.ToString("yyyMMddHHmmsss") + new Random().Next(1000, 9999)}/";
string fullPath = filePath.MapPath(true);
int i = 0;
// List<string> fileNames = new List<string>();
try
{
if (!Directory.Exists(fullPath)) Directory.CreateDirectory(fullPath);
for (i = 0; i < files.Count; i++)
{
string fileName = files[i].FileName;
//if (fileNames.Contains(fileName))
//{
// fileName += $"({i}){fileName}";
//}
//fileNames.Add(fileName);
using (var stream = new FileStream(fullPath + fileName, FileMode.Create))
{
files[i].CopyTo(stream);
}
}
return Response.OK("文件上传成功", filePath);
}
catch (Exception ex)
{
Logger.Error($"上传文件失败:{typeof(T).GetEntityTableCnName()},路径:{filePath},失败文件:{files[i]},{ex.Message + ex.StackTrace}");
return Response.Error("文件上传失败");
}
}
private List<string> GetIgnoreTemplate()
{
//忽略创建人、修改人、审核等字段
List<string> ignoreTemplate = UserIgnoreFields.ToList();
ignoreTemplate.AddRange(auditFields.ToList());
return ignoreTemplate;
}
public virtual WebResponseContent DownLoadTemplate()
{
string tableName = typeof(T).GetEntityTableCnName();
string dicPath = $"Download/{DateTime.Now.ToString("yyyMMdd")}/Template/".MapPath();
if (!Directory.Exists(dicPath)) Directory.CreateDirectory(dicPath);
string fileName = tableName + DateTime.Now.ToString("yyyyMMddHHssmm") + ".xlsx";
//DownLoadTemplateColumns 2020.05.07增加扩展指定导出模板的列
EPPlusHelper.ExportTemplate<T>(DownLoadTemplateColumns, GetIgnoreTemplate(), dicPath, fileName);
return Response.OK(null, dicPath + fileName);
}
/// <summary>
/// 导入表数据Excel文件夹
/// </summary>
/// <param name="files"></param>
/// <returns></returns>
public virtual WebResponseContent Import(List<Microsoft.AspNetCore.Http.IFormFile> files)
{
if (files == null || files.Count == 0)
return new WebResponseContent { Status = true, Message = "请选择上传的文件" };
Microsoft.AspNetCore.Http.IFormFile formFile = files[0];
string dicPath = $"Upload/{DateTime.Now.ToString("yyyMMdd")}/{typeof(T).Name}/".MapPath();
if (!Directory.Exists(dicPath)) Directory.CreateDirectory(dicPath);
dicPath = $"{dicPath}{Guid.NewGuid().ToString()}_{formFile.FileName}";
using (var stream = new FileStream(dicPath, FileMode.Create))
{
formFile.CopyTo(stream);
}
try
{
Response = EPPlusHelper.ReadToDataTable<T>(dicPath, DownLoadTemplateColumns, GetIgnoreTemplate());
}
catch (Exception ex)
{
Response.Error("未能处理导入的文件,请检查导入的文件是否正确");
Logger.Error($"表{typeof(T).GetEntityTableCnName()}导入失败{ex.Message + ex.InnerException?.Message}");
}
if (!Response.Status) return Response;
List<T> list = Response.Data as List<T>;
if (ImportOnExecuting != null)
{
Response = ImportOnExecuting.Invoke(list);
if (!Response.Status) return Response;
}
repository.AddRange(list, true);
if (ImportOnExecuted != null)
{
Response = ImportOnExecuted.Invoke(list);
if (!Response.Status) return Response;
}
return new WebResponseContent { Status = true, Message = "文件上传成功" };
}
public virtual List<T> GetListByExcel(List<Microsoft.AspNetCore.Http.IFormFile> files,out WebResponseContent _webResponseContent)
{
if (files == null || files.Count == 0)
{
_webResponseContent = new WebResponseContent().Error("没有找到文件");
return new List<T>();
}
Microsoft.AspNetCore.Http.IFormFile formFile = files[0];
string dicPath = $"Upload/{DateTime.Now.ToString("yyyMMdd")}/{typeof(T).Name}/".MapPath();
if (!Directory.Exists(dicPath)) Directory.CreateDirectory(dicPath);
dicPath = $"{dicPath}{Guid.NewGuid().ToString()}_{formFile.FileName}";
using (var stream = new FileStream(dicPath, FileMode.Create))
{
formFile.CopyTo(stream);
}
try
{
Response = EPPlusHelper.ReadToDataTable<T>(dicPath, DownLoadTemplateColumns, GetIgnoreTemplate());
_webResponseContent = Response;
}
catch (Exception ex)
{
Response.Error("未能处理导入的文件,请检查导入的文件是否正确");
Logger.Error($"表{typeof(T).GetEntityTableCnName()}导入失败{ex.Message + ex.InnerException?.Message}");
_webResponseContent = Response;
}
if (!Response.Status) return new List<T>();
List<T> list = Response.Data as List<T>;
File.Delete(dicPath);
return list;
}
/// <summary>
/// 导出
/// </summary>
/// <param name="pageData"></param>
/// <returns></returns>
public virtual WebResponseContent Export(PageDataOptions pageData)
{
pageData.Export = true;
List<T> list = GetPageData(pageData).rows;
string tableName = typeof(T).GetEntityTableCnName();
string fileName = tableName + DateTime.Now.ToString("yyyyMMddHHssmm") + ".xlsx";
string folder = DateTime.Now.ToString("yyyyMMdd");
string savePath = $"Download/ExcelExport/{folder}/".MapPath();
List<string> ignoreColumn = new List<string>();
if (ExportOnExecuting != null)
{
Response = ExportOnExecuting(list, ignoreColumn);
if (!Response.Status) return Response;
}
//ExportColumns 2020.05.07增加扩展指定导出模板的列
if (ExportColumns != null)
{
EPPlusHelper.Export(list, ExportColumns?.GetExpressionToArray(), ignoreColumn, savePath, fileName);
}
else
if (ExportColumnsList != null && ExportColumnsList.Count > 0)
{
EPPlusHelper.Export(list, ExportColumnsList.ToArray(), ignoreColumn, savePath, fileName);
}
else {
EPPlusHelper.Export(list, ExportColumns?.GetExpressionToArray(), ignoreColumn, savePath, fileName);
}
return Response.OK(null, (savePath + "/" + fileName).EncryptDES(AppSetting.Secret.ExportFile));
}
/// <summary>
/// 新建 新建方法
/// </summary>
/// <param name="saveDataModel"></param>
/// <returns></returns>
public virtual WebResponseContent Add(SaveModel saveDataModel)
{
if (AddOnExecute != null)
{
Response = AddOnExecute(saveDataModel);
if (!Response.Status) return Response;
}
if (saveDataModel == null
|| saveDataModel.MainData == null
|| saveDataModel.MainData.Count == 0)
return Response.Set(ResponseType.ParametersLack, false);
saveDataModel.DetailData = saveDataModel.DetailData?.Where(x => x.Count > 0).ToList();
Type type = typeof(T);
string validReslut = type.ValidateDicInEntity(saveDataModel.MainData, true, UserIgnoreFields);
if (!string.IsNullOrEmpty(validReslut)) return Response.Error(validReslut);
if (saveDataModel.MainData.Count == 0)
return Response.Error("保存的数据为空请检查model是否配置正确!");
UserInfo userInfo = UserContext.Current.UserInfo;
saveDataModel.SetDefaultVal(AppSetting.CreateMember, userInfo);
PropertyInfo keyPro = type.GetKeyProperty();
if (keyPro.PropertyType == typeof(Guid))
{
saveDataModel.MainData.Add(keyPro.Name, Guid.NewGuid());
}
else if (keyPro.PropertyType.Name == "String") {
//string型的主键也使用guid填充
//如果需要使用命名规则 需要在这里实现
saveDataModel.MainData.Add(keyPro.Name, Guid.NewGuid().ToString());
}
else
{
saveDataModel.MainData.Remove(keyPro.Name);
}
//没有明细直接保存返回
if (saveDataModel.DetailData == null || saveDataModel.DetailData.Count == 0)
{
//20200922 首先把editable=false的都去掉
//var editfalse = type.GetEditableFalse();
//foreach (var editfalsefield in editfalse) {
// saveDataModel.MainData.Remove(editfalsefield.Name);
//}
T mainEntity = saveDataModel.MainData.DicToEntity<T>();
if (base.AddOnExecuting != null)
{
Response = base.AddOnExecuting(mainEntity, null);
if (!Response.Status) return Response;
}
Response = repository.DbContextBeginTransaction(() =>
{
repository.Add(mainEntity,true);
saveDataModel.MainData[keyPro.Name] = keyPro.GetValue(mainEntity);
Response.OK(ResponseType.SaveSuccess);
if (base.AddOnExecuted != null)
{
Response = base.AddOnExecuted(mainEntity, null);
}
return Response;
});
if (Response.Status)
{
Response.Data = new { data = saveDataModel.MainData, message = "保存成功" };
}
if (Response.Status && string.IsNullOrEmpty(Response.Message))
Response.OK(ResponseType.SaveSuccess);
return Response;
}
Type detailType = typeof(T).GetCustomAttribute<EntityAttribute>().DetailTable[0];
return typeof(ServiceBase<T, TRepository>)
.GetMethod("Add", BindingFlags.Instance | BindingFlags.NonPublic)
.MakeGenericMethod(new Type[] { detailType })
.Invoke(this, new object[] { saveDataModel })
as WebResponseContent;
}
public virtual WebResponseContent AddEntity(T entity, bool validationEntity = true)
{
return Add<T>(entity, null, validationEntity);
}
/// <summary>
/// 保存主、明细数据
/// </summary>
/// <typeparam name="TDetail"></typeparam>
/// <param name="entity"></param>
/// <param name="list"></param>
/// <param name="validationEntity">是否进行实体验证</param>
/// <returns></returns>
public WebResponseContent Add<TDetail>(T entity, List<TDetail> list = null, bool validationEntity = true) where TDetail : class
{
//设置用户默认值
entity.SetCreateDefaultVal();
if (validationEntity)
{
Response = entity.ValidationEntity();
if (!Response.Status) return Response;
if (list != null && list.Count > 0)
{
Response = list.ValidationEntity();
if (!Response.Status) return Response;
}
}
if (this.AddOnExecuting != null)
{
Response = AddOnExecuting(entity, list);
if (!Response.Status) return Response;
}
Response = repository.DbContextBeginTransaction(() =>
{
repository.Add(entity);
repository.DbContext.SaveChanges();
//保存明细
if (list != null && list.Count > 0)
{
//获取保存后的主键值
PropertyInfo mainKey = typeof(T).GetKeyProperty();
PropertyInfo detailMainKey = typeof(TDetail).GetProperties()
.Where(q => q.Name.ToLower() == mainKey.Name.ToLower()).FirstOrDefault();
object keyValue = mainKey.GetValue(entity);
list.ForEach(x =>
{
//设置用户默认值
x.SetCreateDefaultVal();
detailMainKey.SetValue(x, keyValue);
repository.DbContext.Entry<TDetail>(x).State = EntityState.Added;
});
repository.DbContext.SaveChanges();
}
Response.OK(ResponseType.SaveSuccess);
if (AddOnExecuted != null)
Response = AddOnExecuted(entity, list);
return Response;
});
if (Response.Status && string.IsNullOrEmpty(Response.Message))
Response.OK(ResponseType.SaveSuccess);
return Response;
}
public WebResponseContent Add<TDetail>(T entity, List<TDetail> list1=null, List<TDetail> list2=null, List<TDetail> list3 = null, List<TDetail> list4 = null, List<TDetail> list5 = null, List<TDetail> list6 = null,bool validationEntity = true) where TDetail : class
{
//设置用户默认值
entity.SetCreateDefaultVal();
if (validationEntity)
{
Response = entity.ValidationEntity();
if (!Response.Status) return Response;
if (BodyListValidation(list1)) {
return Response;
}
if (BodyListValidation(list2))
{
return Response;
}
if (BodyListValidation(list3))
{
return Response;
}
if (BodyListValidation(list4))
{
return Response;
}
if (BodyListValidation(list5))
{
return Response;
}
if (BodyListValidation(list6))
{
return Response;
}
}
if (this.AddOnExecuting != null)
{
if (!list1.isNullorEmpty())
Response = AddOnExecuting(entity, list1);
if (!list2.isNullorEmpty())
Response = AddOnExecuting(entity, list2);
if (!list3.isNullorEmpty())
Response = AddOnExecuting(entity, list3);
if (!list4.isNullorEmpty())
Response = AddOnExecuting(entity, list4);
if (!list5.isNullorEmpty())
Response = AddOnExecuting(entity, list5);
if (!list6.isNullorEmpty())
Response = AddOnExecuting(entity, list6);
if (!Response.Status) return Response;
}
Response = repository.DbContextBeginTransaction(() =>
{
repository.Add(entity);
repository.DbContext.SaveChanges();
//获取保存后的主键值
PropertyInfo mainKey = typeof(T).GetKeyProperty();
object keyValue = mainKey.GetValue(entity);
//保存明细
if (!list1.isNullorEmpty())
{
PropertyInfo detailMainKey = typeof(TDetail).GetParentIdProperty(typeof(T).GetEntityTableName());
PropertyInfo BodyPK = typeof(TDetail).GetKeyProperty();
list1.ForEach(x =>
{
//设置用户默认值
x.SetCreateDefaultVal();
detailMainKey.SetValue(x, keyValue);
if (BodyPK.PropertyType == typeof(Guid))
{
BodyPK.SetValue(x, Guid.NewGuid());
}
repository.DbContext.Entry<TDetail>(x).State = EntityState.Added;
});
repository.DbContext.SaveChanges();
}
if (!list2.isNullorEmpty())
{
PropertyInfo detailMainKey = typeof(TDetail).GetParentIdProperty(typeof(T).GetEntityTableName());
PropertyInfo BodyPK = typeof(TDetail).GetKeyProperty();
list2.ForEach(x =>
{
//设置用户默认值
x.SetCreateDefaultVal();
detailMainKey.SetValue(x, keyValue);
if (BodyPK.PropertyType == typeof(Guid))
{
BodyPK.SetValue(x, Guid.NewGuid());
}
repository.DbContext.Entry<TDetail>(x).State = EntityState.Added;
});
repository.DbContext.SaveChanges();
}
if (!list3.isNullorEmpty())
{
PropertyInfo detailMainKey = typeof(TDetail).GetParentIdProperty(typeof(T).GetEntityTableName());
PropertyInfo BodyPK = typeof(TDetail).GetKeyProperty();
list3.ForEach(x =>
{
//设置用户默认值
x.SetCreateDefaultVal();
detailMainKey.SetValue(x, keyValue);
if (BodyPK.PropertyType == typeof(Guid))
{
BodyPK.SetValue(x, Guid.NewGuid());
}
repository.DbContext.Entry<TDetail>(x).State = EntityState.Added;
});
repository.DbContext.SaveChanges();
}
if (!list4.isNullorEmpty())
{
PropertyInfo detailMainKey = typeof(TDetail).GetParentIdProperty(typeof(T).GetEntityTableName());
PropertyInfo BodyPK = typeof(TDetail).GetKeyProperty();
list4.ForEach(x =>
{
//设置用户默认值
x.SetCreateDefaultVal();
detailMainKey.SetValue(x, keyValue);
if (BodyPK.PropertyType == typeof(Guid))
{
BodyPK.SetValue(x, Guid.NewGuid());
}
repository.DbContext.Entry<TDetail>(x).State = EntityState.Added;
});
repository.DbContext.SaveChanges();
}
if (!list5.isNullorEmpty())
{
PropertyInfo detailMainKey = typeof(TDetail).GetParentIdProperty(typeof(T).GetEntityTableName());
PropertyInfo BodyPK = typeof(TDetail).GetKeyProperty();
list5.ForEach(x =>
{
//设置用户默认值
x.SetCreateDefaultVal();
detailMainKey.SetValue(x, keyValue);
if (BodyPK.PropertyType == typeof(Guid))
{
BodyPK.SetValue(x, Guid.NewGuid());
}
repository.DbContext.Entry<TDetail>(x).State = EntityState.Added;
});
repository.DbContext.SaveChanges();
}
if (!list6.isNullorEmpty())
{
PropertyInfo detailMainKey = typeof(TDetail).GetParentIdProperty(typeof(T).GetEntityTableName());
PropertyInfo BodyPK = typeof(TDetail).GetKeyProperty();
list6.ForEach(x =>
{
//设置用户默认值
x.SetCreateDefaultVal();
detailMainKey.SetValue(x, keyValue);
if (BodyPK.PropertyType == typeof(Guid))
{
BodyPK.SetValue(x, Guid.NewGuid());
}
repository.DbContext.Entry<TDetail>(x).State = EntityState.Added;
});
repository.DbContext.SaveChanges();
}
Response.OK(ResponseType.SaveSuccess);
if (AddOnExecuted != null)
{
if (!list1.isNullorEmpty())
Response = AddOnExecuted(entity, list1);
if (!list2.isNullorEmpty())
Response = AddOnExecuted(entity, list2);
if (!list3.isNullorEmpty())
Response = AddOnExecuted(entity, list3);
if (!list4.isNullorEmpty())
Response = AddOnExecuted(entity, list4);
if (!list5.isNullorEmpty())
Response = AddOnExecuted(entity, list5);
if (!list6.isNullorEmpty())
Response = AddOnExecuted(entity, list6);
}
return Response;
});
if (Response.Status && string.IsNullOrEmpty(Response.Message))
Response.OK(ResponseType.SaveSuccess);
return Response;
}
private Boolean BodyListValidation<TDetail>(List<TDetail> list) {
if (list != null && list.Count > 0)
{
Response = list.ValidationEntity();
return (!Response.Status) ;
}
return false;
}
public void AddDetailToDBSet<TDetail>() where TDetail : class
{
List<PropertyInfo> listChilds = TProperties.Where(x => x.PropertyType.Name == "List`1").ToList();
// repository.DbContext.Set<TDetail>().AddRange();
}
private WebResponseContent Add<TDetail>(SaveModel saveDataModel) where TDetail : class
{
T mainEntity = saveDataModel.MainData.DicToEntity<T>();
//验证明细
string reslut = typeof(TDetail).ValidateDicInEntity(saveDataModel.DetailData, true, false, new string[] { TProperties.GetKeyName() });
if (reslut != string.Empty)
return Response.Error(reslut);
List<TDetail> list = saveDataModel.DetailData.DicToList<TDetail>();
Response = Add<TDetail>(mainEntity, list, false);
//保存失败
if (!Response.Status)
{
Logger.Error(LoggerType.Add, saveDataModel.Serialize() + Response.Message);
return Response;
}
PropertyInfo propertyKey = typeof(T).GetKeyProperty();
saveDataModel.MainData[propertyKey.Name] = propertyKey.GetValue(mainEntity);
Response.Data = new { data = saveDataModel.MainData, list };
return Response.Set(ResponseType.SaveSuccess);
}
#region 编辑
/// <summary>
/// 获取编辑明细主键
/// </summary>
/// <typeparam name="DetailT"></typeparam>
/// <typeparam name="Tkey"></typeparam>
/// <param name="detailKeyName"></param>
/// <param name="mainKeyName"></param>
/// <param name="mainKeyValue"></param>
/// <returns></returns>
public List<Tkey> GetUpdateDetailSelectKeys<DetailT, Tkey>(string detailKeyName, string mainKeyName, string mainKeyValue) where DetailT : class
{
IQueryable<DetailT> queryable = repository.DbContext.Set<DetailT>();
Expression<Func<DetailT, Tkey>> selectExpression = detailKeyName.GetExpression<DetailT, Tkey>();
Expression<Func<DetailT, bool>> whereExpression = mainKeyName.CreateExpression<DetailT>(mainKeyValue, LinqExpressionType.Equal);
List<Tkey> detailKeys = queryable.Where(whereExpression).Select(selectExpression).ToList();
return detailKeys;
}
/// <summary>
/// 将数据转换成对象后最终保存
/// </summary>
/// <typeparam name="DetailT"></typeparam>
/// <param name="saveModel"></param>
/// <param name="mainKeyProperty"></param>
/// <param name="detailKeyInfo"></param>
/// <param name="keyDefaultVal"></param>
/// <returns></returns>
public WebResponseContent UpdateToEntity<DetailT>(SaveModel saveModel, PropertyInfo mainKeyProperty, PropertyInfo detailKeyInfo, object keyDefaultVal) where DetailT : class
{
T mainEnity = saveModel.MainData.DicToEntity<T>();
List<DetailT> detailList = saveModel.DetailData.DicToList<DetailT>();
//删除的主键
//查出所有明细表数据的ID
System.Collections.IList detailKeys = this.GetType().GetMethod("GetUpdateDetailSelectKeys")
.MakeGenericMethod(new Type[] { typeof(DetailT), detailKeyInfo.PropertyType })
.Invoke(this, new object[] {
detailKeyInfo.Name, mainKeyProperty.Name,
saveModel.MainData[mainKeyProperty.Name].ToString()
}) as System.Collections.IList;
//新增对象
List<DetailT> addList = new List<DetailT>();
// List<object> containsKeys = new List<object>();
//编辑对象
List<DetailT> editList = new List<DetailT>();
//删除的主键
List<object> delKeys = new List<object>();
mainKeyProperty = typeof(DetailT).GetProperties().Where(x => x.Name == mainKeyProperty.Name).FirstOrDefault();
//获取新增与修改的对象
foreach (DetailT item in detailList)
{
object value = detailKeyInfo.GetValue(item);
if (keyDefaultVal.Equals(value))//主键为默认值的,新增数据
{
//设置新增的主表的值
mainKeyProperty.SetValue(item,
saveModel.MainData[mainKeyProperty.Name]
.ChangeType(mainKeyProperty.PropertyType));
if (detailKeyInfo.PropertyType == typeof(Guid))
{
detailKeyInfo.SetValue(item, Guid.NewGuid());
}
addList.Add(item);
}
else if (detailKeys.Contains(value))
{
//containsKeys.Add(value);
editList.Add(item);
}
}
//获取需要删除的对象的主键
if (saveModel.DelKeys != null && saveModel.DelKeys.Count > 0)
{
delKeys = saveModel.DelKeys
.Where(x => detailKeys.Contains(x.ChangeType(detailKeyInfo.PropertyType)))
.Select(q => q.ChangeType(detailKeyInfo.PropertyType)).ToList();
}
if (UpdateOnExecuting != null)
{
Response = UpdateOnExecuting(mainEnity, addList, editList, delKeys);
if (!Response.Status)
return Response;
}
mainEnity.SetModifyDefaultVal();
//主表修改
//不修改!CreateFields.Contains创建人信息
repository.Update(mainEnity, typeof(T).GetEditField()
.Where(c => saveModel.MainData.Keys.Contains(c) && !CreateFields.Contains(c))
.ToArray());
foreach (var item in saveModel.DetailData)
{
item.SetModifyDefaultVal();
}
//明细修改
editList.ForEach(x =>
{
//获取编辑的字段
string[] updateField = saveModel.DetailData
.Where(c => c[detailKeyInfo.Name].ChangeType(detailKeyInfo.PropertyType)
.Equal(detailKeyInfo.GetValue(x)))
.FirstOrDefault()
.Keys.Where(k => k != detailKeyInfo.Name)
.Where(r => !CreateFields.Contains(r))
.ToArray();
//設置默認值
x.SetModifyDefaultVal();
//添加修改字段
repository.Update<DetailT>(x, updateField);
});
//明细新增
addList.ForEach(x =>
{
x.SetCreateDefaultVal();
repository.DbContext.Entry<DetailT>(x).State = EntityState.Added;
});
//明细删除
delKeys.ForEach(x =>
{
DetailT delT = Activator.CreateInstance<DetailT>();
detailKeyInfo.SetValue(delT, x);
repository.DbContext.Entry<DetailT>(delT).State = EntityState.Deleted;
});
if (UpdateOnExecuted == null)
{
repository.DbContext.SaveChanges();
Response.OK(ResponseType.SaveSuccess);
}
else
{
Response = repository.DbContextBeginTransaction(() =>
{
repository.DbContext.SaveChanges();
Response = UpdateOnExecuted(mainEnity, addList, editList, delKeys);
return Response;
});
}
if (Response.Status)
{
addList.AddRange(editList);
Response.Data = new { data = mainEnity, list = addList };
if (string.IsNullOrEmpty(Response.Message))
Response.OK(ResponseType.SaveSuccess);
}
return Response;
}
/// <summary>
/// 获取配置的创建人ID创建时间创建人,修改人ID修改时间、修改人与数据相同的字段
/// </summary>
private static string[] _userIgnoreFields { get; set; }
private static string[] UserIgnoreFields
{
get
{
if (_userIgnoreFields != null) return _userIgnoreFields;
List<string> fields = new List<string>();
fields.AddRange(CreateFields);
fields.AddRange(ModifyFields);
_userIgnoreFields = fields.ToArray();
return _userIgnoreFields;
}
}
private static string[] _createFields { get; set; }
private static string[] CreateFields
{
get
{
if (_createFields != null) return _createFields;
_createFields = AppSetting.CreateMember.GetType().GetProperties()
.Select(x => x.GetValue(AppSetting.CreateMember)?.ToString())
.Where(w => !string.IsNullOrEmpty(w)).ToArray();
return _createFields;
}
}
private static string[] _modifyFields { get; set; }
private static string[] ModifyFields
{
get
{
if (_modifyFields != null) return _modifyFields;
_modifyFields = AppSetting.ModifyMember.GetType().GetProperties()
.Select(x => x.GetValue(AppSetting.ModifyMember)?.ToString())
.Where(w => !string.IsNullOrEmpty(w)).ToArray();
return _modifyFields;
}
}
/// <summary>
/// 编辑
/// 1、明细表必须把主表的主键字段也设置为可编辑
/// 2、修改、增加只会操作设置为编辑列的数据
/// </summary>
/// <param name="saveModel"></param>
/// <returns></returns>
public virtual WebResponseContent Update(SaveModel saveModel)
{
if (UpdateOnExecute != null)
{
Response = UpdateOnExecute(saveModel);
if (!Response.Status) return Response;
}
if (saveModel == null)
return Response.Error(ResponseType.ParametersLack);
Type type = typeof(T);
//设置修改时间,修改人的默认值
UserInfo userInfo = UserContext.Current.UserInfo;
saveModel.SetDefaultVal(AppSetting.ModifyMember, userInfo);
//判断提交的数据与实体格式是否一致
string result = type.ValidateDicInEntity(saveModel.MainData, true, false, UserIgnoreFields);
if (result != string.Empty)
return Response.Error(result);
PropertyInfo mainKeyProperty = type.GetKeyProperty();
//验证明细
Type detailType = null;
if (saveModel.DetailData != null || saveModel.DelKeys != null)
{
saveModel.DetailData = saveModel.DetailData == null
? new List<Dictionary<string, object>>()
: saveModel.DetailData.Where(x => x.Count > 0).ToList();
detailType = typeof(T).GetCustomAttribute<EntityAttribute>().DetailTable[0];
result = detailType.ValidateDicInEntity(saveModel.DetailData, true, false, new string[] { mainKeyProperty.Name });
if (result != string.Empty) return Response.Error(result);
//主从关系指定外键,即从表的外键可以不是主键的主表,还需要改下代码生成器设置属性外键,功能预留后面再开发(2020.04.25)
//string foreignKey = type.GetTypeCustomValue<System.ComponentModel.DataAnnotations.Schema.ForeignKeyAttribute>(x => new { x.Name });
//if (!string.IsNullOrEmpty(foreignKey))
//{
// var _mainKeyProperty = detailType.GetProperties().Where(x => x.Name.ToLower() == foreignKey.ToLower()).FirstOrDefault();
// if (_mainKeyProperty != null)
// {
// mainKeyProperty = _mainKeyProperty;
// }
//}
}
//获取主建类型的默认值用于判断后面数据是否正确,int long默认值为0,guid :0000-000....
object keyDefaultVal = mainKeyProperty.PropertyType.Assembly.CreateInstance("System.Int32");
if (mainKeyProperty.PropertyType.FullName == "System.String") keyDefaultVal = mainKeyProperty.PropertyType.Assembly.CreateInstance("System.Guid");
else
keyDefaultVal = mainKeyProperty.PropertyType.Assembly.CreateInstance(mainKeyProperty.PropertyType.FullName);//.ToString();
//判断是否包含主键
if (mainKeyProperty == null
|| !saveModel.MainData.ContainsKey(mainKeyProperty.Name)
|| saveModel.MainData[mainKeyProperty.Name] == null
)
{
return Response.Error(ResponseType.NoKey);
}
object mainKeyVal = saveModel.MainData[mainKeyProperty.Name];
if (!addLockKey(mainKeyVal)){
return Response.Error("该业务正在进行操作 请稍后");
}
try
{
//判断主键类型是否正确
(bool, string, object) validation = mainKeyProperty.ValidationValueForDbType(mainKeyVal).FirstOrDefault();
if (!validation.Item1)
return Response.Error(ResponseType.KeyError);
object valueType = mainKeyVal.ToString().ChangeType(mainKeyProperty.PropertyType);
//判断主键值是不是当前类型的默认值
if (valueType == null ||
(!valueType.GetType().Equals(mainKeyProperty.PropertyType)
|| valueType.ToString() == keyDefaultVal.ToString()
))
return Response.Error(ResponseType.KeyError);
if (saveModel.MainData.Count <= 1) return Response.Error("系统没有配置好编辑的数据请检查model!");
// 2020.08.15添加多租户数据过滤(编辑)
if (IsMultiTenancy && !UserContext.Current.IsSuperAdmin)
{
CheckUpdateMultiTenancy(mainKeyProperty.PropertyType == typeof(Guid) ? "'" + mainKeyVal.ToString() + "'" : mainKeyVal.ToString(), mainKeyProperty.Name);
if (!Response.Status)
{
return Response;
}
}
Expression<Func<T, bool>> expression = mainKeyProperty.Name.CreateExpression<T>(mainKeyVal.ToString(), LinqExpressionType.Equal);
if (!repository.Exists(expression)) return Response.Error("保存的数据不存在!");
//没有明细的直接保存主表数据
if (detailType == null)
{
saveModel.SetDefaultVal(AppSetting.ModifyMember, userInfo);
T mainEntity = saveModel.MainData.DicToEntity<T>();
if (UpdateOnExecuting != null)
{
Response = UpdateOnExecuting(mainEntity, null, null, null);
if (!Response.Status) return Response;
}
//不修改!CreateFields.Contains创建人信息
repository.Update(mainEntity, type.GetEditField().Where(c => saveModel.MainData.Keys.Contains(c) && !CreateFields.Contains(c)).ToArray());
if (base.UpdateOnExecuted == null)
{
repository.SaveChanges();
Response.OK(ResponseType.SaveSuccess);
}
else
{
Response = repository.DbContextBeginTransaction(() =>
{
repository.SaveChanges();
Response = UpdateOnExecuted(mainEntity, null, null, null);
return Response;
});
}
if (Response.Status) Response.Data = new SaveResult( mainEntity);
if (Response.Status && string.IsNullOrEmpty(Response.Message))
Response.OK(ResponseType.SaveSuccess);
return Response;
}
saveModel.DetailData = saveModel.DetailData.Where(x => x.Count > 0).ToList();
//明细操作
PropertyInfo detailKeyInfo = detailType.GetKeyProperty();
//主键类型
// string detailKeyType = mainKeyProperty.GetTypeCustomValue<ColumnAttribute>(c => new { c.TypeName });
//判断明细是否包含了主表的主键
string deatilDefaultVal = detailKeyInfo.PropertyType.Assembly.CreateInstance(detailKeyInfo.PropertyType.FullName).ToString();
foreach (Dictionary<string, object> dic in saveModel.DetailData)
{
//不包含主键的默认添加主键默认值,用于后面判断是否为新增数据
if (!dic.ContainsKey(detailKeyInfo.Name))
{
dic.Add(detailKeyInfo.Name, keyDefaultVal);
if (dic.ContainsKey(mainKeyProperty.Name))
{
dic[mainKeyProperty.Name] = keyDefaultVal;
}
else
{
dic.Add(mainKeyProperty.Name, keyDefaultVal);
}
continue;
}
if (dic[detailKeyInfo.Name] == null)
return Response.Error(ResponseType.NoKey);
//主键值是否正确
string detailKeyVal = dic[detailKeyInfo.Name].ToString();
if (!mainKeyProperty.ValidationValueForDbType(detailKeyVal).FirstOrDefault().Item1
|| deatilDefaultVal == detailKeyVal)
return Response.Error(ResponseType.KeyError);
//判断主表的值是否正确
if (detailKeyVal != keyDefaultVal.ToString() && (!dic.ContainsKey(mainKeyProperty.Name) || dic[mainKeyProperty.Name] == null || dic[mainKeyProperty.Name].ToString() == keyDefaultVal.ToString()))
{
return Response.Error(mainKeyProperty.Name + "是必填项!");
}
}
if (saveModel.DetailData.Exists(c => c.Count <= 2))
return Response.Error("系统没有配置好明细编辑的数据请检查model!");
return this.GetType().GetMethod("UpdateToEntity")
.MakeGenericMethod(new Type[] { detailType })
.Invoke(this, new object[] { saveModel, mainKeyProperty, detailKeyInfo, keyDefaultVal })
as WebResponseContent;
}
catch (Exception e)
{
return Response.Error(e.Message);
}
finally {
delLockKey(mainKeyVal);
}
}
#endregion
/// <summary>
/// 删除明细数据
/// 前台使用时调用该表自己的URL/DelDetail 参数delKey
/// </summary>
/// <typeparam name="TDetail"></typeparam>
/// <param name="list"></param>
/// <param name="Delkeys"></param>
/// <returns></returns>
public virtual WebResponseContent DelDetail(SaveModel saveDataModel)
{
Type DetailType = typeof(T);
var keys = saveDataModel.DelKeys.ToArray();
FieldType fieldType = DetailType.GetFieldType();
for (var _i= 0; _i < keys.Length;_i++) {
if (keys[_i]==null ) {
if (fieldType == FieldType.Int || fieldType == FieldType.BigInt)
{
keys[_i] = 0;
}
else {
keys[_i] = Guid.Empty.ToString();
}
}
}
var DetailkeyProperty = DetailType.GetKeyProperty();
if (DetailkeyProperty == null || keys == null || keys.Length == 0) return Response.Error(ResponseType.NoKeyDel);
string tKey = DetailkeyProperty.Name;
if (string.IsNullOrEmpty(tKey))
return Response.Error("没有主键不能删除");
if (DelOnExecuting != null)
{
Response = DelOnExecuting(keys);
if (!Response.Status) return Response;
}
string joinKeys = (fieldType == FieldType.Int || fieldType == FieldType.BigInt)
? string.Join(",", keys)
: $"'{string.Join("','", keys)}'";
// 2020.08.15添加判断多租户数据(删除)
if (IsMultiTenancy && !UserContext.Current.IsSuperAdmin)
{
CheckDelMultiTenancy(joinKeys, tKey);
if (!Response.Status)
{
return Response;
}
}
string sql = $"DELETE FROM {DetailType.GetEntityTableName() } where {tKey} in ({joinKeys});";
//repository.DapperContext.ExcuteNonQuery(sql, CommandType.Text, null, true);
//可能在删除后还要做一些其它数据库新增或删除操作,这样就可能需要与删除保持在同一个事务中处理
//采用此方法 repository.DbContextBeginTransaction(()=>{//do delete......and other});
//做的其他操作在DelOnExecuted中加入委托实现
Response = repository.DbContextBeginTransaction(() =>
{
repository.ExecuteSqlCommand(sql);
if (DelOnExecuted != null)
{
Response = DelOnExecuted(keys);
}
return Response;
});
if (Response.Status && string.IsNullOrEmpty(Response.Message)) Response.OK(ResponseType.DelSuccess);
return Response;
}
public virtual string GetKeysStr(SaveModel saveDataModel) {
try
{
Type DetailType = typeof(T);
var keys = saveDataModel.DelKeys.ToArray();
FieldType fieldType = DetailType.GetFieldType();
string joinKeys = (fieldType == FieldType.Int || fieldType == FieldType.BigInt)
? string.Join(",", keys)
: $"'{string.Join("','", keys)}'";
return joinKeys;
}
catch { return ""; }
}
/// <summary>
/// 查找前台传回数据结构中的 WorkKeys 数组
/// 通常用来放置需要处理的业务编号组
/// </summary>
/// <param name="saveDataModel"></param>
/// <returns></returns>
public virtual string GetWorkKeysStr(SaveModel saveDataModel)
{
try
{
Type DetailType = typeof(T);
var keys = saveDataModel.WorkKeys.ToArray();
FieldType fieldType = DetailType.GetFieldType();
string joinKeys = (fieldType == FieldType.Int || fieldType == FieldType.BigInt)
? string.Join(",", keys)
: $"'{string.Join("','", keys)}'";
return joinKeys;
}
catch { return ""; }
}
/// <summary>
///
/// </summary>
/// <param name="keys"></param>
/// <param name="delList">是否删除明细数据(默认会删除明细)</param>
/// <returns></returns>
public virtual WebResponseContent Del(object[] keys, bool delList = true)
{
Type entityType = typeof(T);
var keyProperty = entityType.GetKeyProperty();
if (keyProperty == null || keys == null || keys.Length == 0) return Response.Error(ResponseType.NoKeyDel);
IEnumerable<(bool, string, object)> validation = keyProperty.ValidationValueForDbType(keys);
if (validation.Any(x => !x.Item1))
{
return Response.Error(validation.Where(x => !x.Item1).Select(s => s.Item2 + "</br>").Serialize());
}
string tKey = keyProperty.Name;
if (string.IsNullOrEmpty(tKey))
return Response.Error("没有主键不能删除");
if (DelOnExecuting != null)
{
Response = DelOnExecuting(keys);
if (!Response.Status) return Response;
}
FieldType fieldType = entityType.GetFieldType();
string joinKeys = (fieldType == FieldType.Int || fieldType == FieldType.BigInt)
? string.Join(",", keys)
: $"'{string.Join("','", keys)}'";
string sql = $"DELETE FROM {entityType.GetEntityTableName() } where {tKey} in ({joinKeys});";
// 2020.08.06增加pgsql删除功能
if (DBType.Name == DbCurrentType.PgSql.ToString())
{
sql = $"DELETE FROM \"public\".\"{entityType.GetEntityTableName() }\" where \"{tKey}\" in ({joinKeys});";
}
if (delList)
{
Type detailType = entityType.GetCustomAttribute<EntityAttribute>()?.DetailTable?[0];
if (detailType != null)
{
if (DBType.Name == DbCurrentType.PgSql.ToString())
{
sql += $"DELETE FROM \"public\".\"{detailType.GetEntityTableName()}\" where \"{tKey}\" in ({joinKeys});";
}
else
{
sql += $"DELETE FROM {detailType.GetEntityTableName()} where {tKey} in ({joinKeys});";
}
}
}
//repository.DapperContext.ExcuteNonQuery(sql, CommandType.Text, null, true);
//可能在删除后还要做一些其它数据库新增或删除操作,这样就可能需要与删除保持在同一个事务中处理
//采用此方法 repository.DbContextBeginTransaction(()=>{//do delete......and other});
//做的其他操作在DelOnExecuted中加入委托实现
Response = repository.DbContextBeginTransaction(() =>
{
repository.ExecuteSqlCommand(sql);
if (DelOnExecuted != null)
{
Response = DelOnExecuted(keys);
}
return Response;
});
if (Response.Status && string.IsNullOrEmpty(Response.Message)) Response.OK(ResponseType.DelSuccess);
return Response;
}
private static string[] auditFields = new string[] { "auditid", "auditstatus", "auditor", "auditdate", "auditreason" };
/// <summary>
/// 审核默认对应数据库字段为AuditId审核人ID ,AuditStatus审核状态,Auditor审核人,Auditdate审核时间,Auditreason审核原因
/// </summary>
/// <param name="keys"></param>
/// <param name="auditStatus"></param>
/// <param name="auditReason"></param>
/// <returns></returns>
public virtual WebResponseContent Audit(object[] keys, int? auditStatus, string auditReason)
{
if (keys == null || keys.Length == 0)
return Response.Error("未获取到参数!");
if (auditStatus != 1 && auditStatus != 2)
return Response.Error("请提求正确的审核结果!");
//获取主键
PropertyInfo property = TProperties.GetKeyProperty();
if (property == null)
return Response.Error("没有配置好主键!");
UserInfo userInfo = UserContext.Current.UserInfo;
//表如果有审核相关字段,设置默认审核
PropertyInfo[] updateFields = TProperties.Where(x => auditFields.Contains(x.Name.ToLower())).ToArray();
List<T> auditList = new List<T>();
foreach (var value in keys)
{
object convertVal = value.ToString().ChangeType(property.PropertyType);
if (convertVal == null) continue;
T entity = Activator.CreateInstance<T>();
property.SetValue(entity, convertVal);
foreach (var item in updateFields)
{
switch (item.Name.ToLower())
{
case "auditid":
item.SetValue(entity, userInfo.User_Id);
break;
case "auditstatus":
item.SetValue(entity, auditStatus);
break;
case "auditor":
item.SetValue(entity, userInfo.UserTrueName);
break;
case "auditdate":
item.SetValue(entity, DateTime.Now);
break;
case "auditreason":
item.SetValue(entity, auditReason);
break;
}
}
auditList.Add(entity);
}
if (base.AuditOnExecuting != null)
{
Response = AuditOnExecuting(auditList);
if (!Response.Status) return Response;
}
repository.UpdateRange(auditList, updateFields.Select(x => x.Name).ToArray(), true);
if (base.AuditOnExecuted != null)
{
Response = AuditOnExecuted(auditList);
if (!Response.Status) return Response;
}
return Response.OK(ResponseType.AuditSuccess);
}
public virtual WebResponseContent PushStatus(object[] keys, int execution, string reason) {
return Response.Error("未指定的执行参数【"+ execution + "】!");
}
public virtual WebResponseContent SaveAndPushStatus(SaveModel saveDataModel)
{
return Response.Error("未指定的执行参数【" + saveDataModel.GetExection() + "】!");
}
public virtual (string, T, bool) ApiValidate(string bizContent, Expression<Func<T, object>> expression = null)
{
return ApiValidateInput<T>(bizContent, expression);
}
/// <summary>
/// 对指定类与api的参数进行验证
/// </summary>
/// <typeparam name="TInput"></typeparam>
/// <param name="bizContent"></param>
/// <param name="input"></param>
/// <param name="expression">对指属性验证</param>
/// <returns>(string,TInput, bool) string:返回验证消息,TInputbizContent序列化后的对象,bool:验证是否通过</returns>
public virtual (string, TInput, bool) ApiValidateInput<TInput>(string bizContent, Expression<Func<TInput, object>> expression)
{
return ApiValidateInput(bizContent, expression, null);
}
/// <summary>
///
/// </summary>
/// <typeparam name="TInput"></typeparam>
/// <param name="bizContent"></param>
/// <param name="expression">对指属性验证格式如x=>new { x.UserName,x.Value }</param>
/// <param name="validateExpression">对指定的字段只做合法性判断比如长度是是否超长</param>
/// <returns>(string,TInput, bool) string:返回验证消息,TInputbizContent序列化后的对象,bool:验证是否通过</returns>
public virtual (string, TInput, bool) ApiValidateInput<TInput>(string bizContent, Expression<Func<TInput, object>> expression, Expression<Func<TInput, object>> validateExpression)
{
try
{
TInput input = JsonConvert.DeserializeObject<TInput>(bizContent);
if (!(input is System.Collections.IList))
{
Response = input.ValidationEntity(expression, validateExpression);
return (Response.Message, input, Response.Status);
}
System.Collections.IList list = input as System.Collections.IList;
for (int i = 0; i < list.Count; i++)
{
Response = list[i].ValidationEntity(expression?.GetExpressionProperty(),
validateExpression?.GetExpressionProperty());
if (!Response.Status)
return (Response.Message, default(TInput), false);
}
return ("", input, true);
}
catch (Exception ex)
{
Response.Status = false;
Response.Message = ApiMessage.ParameterError;
Logger.Error(LoggerType.HandleError, bizContent, null, ex.Message);
}
return (Response.Message, default(TInput), Response.Status);
}
/// <summary>
/// 将数据源映射到新的数据中,目前只支持List<TSource>映射到List<TResult>或TSource映射到TResult
/// 目前只支持Dictionary或实体类型
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="resultExpression">只映射返回对象的指定字段</param>
/// <param name="sourceExpression">只映射数据源对象的指定字段</param>
/// 过滤条件表达式调用方式List表达式x => new { x[0].MenuName, x[0].Menu_Id}表示指定映射MenuName,Menu_Id字段
/// List<Sys_Menu> list = new List<Sys_Menu>();
/// list.MapToObject<List<Sys_Menu>, List<Sys_Menu>>(x => new { x[0].MenuName, x[0].Menu_Id}, null);
///
///过滤条件表达式调用方式实体表达式x => new { x.MenuName, x.Menu_Id}表示指定映射MenuName,Menu_Id字段
/// Sys_Menu sysMenu = new Sys_Menu();
/// sysMenu.MapToObject<Sys_Menu, Sys_Menu>(x => new { x.MenuName, x.Menu_Id}, null);
/// <returns></returns>
public virtual TResult MapToEntity<TSource, TResult>(TSource source, Expression<Func<TResult, object>> resultExpression,
Expression<Func<TSource, object>> sourceExpression = null) where TResult : class
{
return source.MapToObject<TSource, TResult>(resultExpression, sourceExpression);
}
/// <summary>
/// 将一个实体的赋到另一个实体上,应用场景:
/// 两个实体a a1= new a();b b1= new b(); a1.P=b1.P; a1.Name=b1.Name;
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="result"></param>
/// <param name="expression">指定对需要的字段赋值,格式x=>new {x.Name,x.P},返回的结果只会对Name与P赋值</param>
public virtual void MapValueToEntity<TSource, TResult>(TSource source, TResult result, Expression<Func<TResult, object>> expression = null) where TResult : class
{
source.MapValueToEntity<TSource, TResult>(result, expression);
}
/// <summary>
/// 处理扩展的子列表数据 返回addList和updateList
/// 子表当中与父表连接的字段需增加 【ParentId属性】
/// 如一个子表关联多个子表,需要在属性中添加父表名字;如只关联一个父表,可以传空字符串进去
/// 在调用时如不传表名将会取得子表中第一个包含【ParentId属性】的字段
/// </summary>
/// <typeparam name="TDetail"></typeparam>
/// <param name="BodyList"></param>
/// <returns></returns>
public static List<List<TDetail>> DealBodyList<TDetail>(object MainKeyValue, List<TDetail> BodyList, string HeadTableName="")
{
PropertyInfo BodyPK = typeof(TDetail).GetKeyProperty();
PropertyInfo detailMainKey = typeof(TDetail).GetParentIdProperty(HeadTableName);
//id=0的默认为新增的数据
List<TDetail> addList = new List<TDetail>();
List<TDetail> updateList = new List<TDetail>();
bool pidisnull(object obj) {
if (obj == null || obj.ToString() == "" || obj.ToString() == "0" || obj.ToString() == "00000000-0000-0000-0000-000000000000")
{
return true;
}
else {
return false;
}
}
BodyList.ForEach(x =>
{
if (BodyPK.PropertyType == typeof(Guid) || BodyPK.PropertyType == typeof(Guid?))
{
var pkvalue = (Guid)BodyPK.GetValue(x);
if (pkvalue == Guid.Empty)
{
x.SetCreateDefaultVal();
x.SetModifyDefaultVal();
var mk = new Guid(MainKeyValue.ToString());
try
{
if(pidisnull( detailMainKey.GetValue(x)))
detailMainKey.SetValue(x, mk);
}
catch
{
if (pidisnull(detailMainKey.GetValue(x)))
detailMainKey.SetValue(x, MainKeyValue);
}
BodyPK.SetValue(x, Guid.NewGuid());
addList.Add(x);
}
else
{
updateList.Add(x);
}
}
else if (BodyPK.PropertyType == typeof(string)|| BodyPK.PropertyType == typeof(String))
{
if ((string)BodyPK.GetValue(x) == string.Empty || (string)BodyPK.GetValue(x) == "" || (string)BodyPK.GetValue(x) == null
|| (string)BodyPK.GetValue(x) == "00000000-0000-0000-0000-000000000000"
)
{
x.SetCreateDefaultVal();
x.SetModifyDefaultVal();
var mk = new Guid(MainKeyValue.ToString());
try
{
if (pidisnull(detailMainKey.GetValue(x)))
detailMainKey.SetValue(x, mk);
}
catch
{
if (pidisnull(detailMainKey.GetValue(x)))
detailMainKey.SetValue(x, MainKeyValue);
}
BodyPK.SetValue(x, Guid.NewGuid().ToString());
addList.Add(x);
}
else
{
updateList.Add(x);
}
}
else if (BodyPK.PropertyType == typeof(string))
{
if (string.IsNullOrWhiteSpace((string)BodyPK.GetValue(x)))
{
x.SetCreateDefaultVal();
x.SetModifyDefaultVal();
if (pidisnull(detailMainKey.GetValue(x)))
detailMainKey.SetValue(x, MainKeyValue.ToString());
BodyPK.SetValue(x, Guid.NewGuid().ToString());
addList.Add(x);
}
else
{
updateList.Add(x);
}
}
else if (BodyPK.PropertyType == typeof(Int32))
{
if ((Int32)BodyPK.GetValue(x) == 0)
{
x.SetCreateDefaultVal();
x.SetModifyDefaultVal();
if (pidisnull(detailMainKey.GetValue(x)))
detailMainKey.SetValue(x, MainKeyValue);
addList.Add(x);
}
else
{
updateList.Add(x);
}
}
else
{
if ((Int64)BodyPK.GetValue(x) == 0)
{
x.SetCreateDefaultVal();
x.SetModifyDefaultVal();
if (pidisnull(detailMainKey.GetValue(x)))
detailMainKey.SetValue(x, MainKeyValue);
addList.Add(x);
}
else
{
updateList.Add(x);
}
}
});
var result = new List<List<TDetail>>();
result.Add(addList);
result.Add(updateList);
return result;
}
////当前用户只能操作自己(与下级角色)创建的数据,如:查询、删除、修改等操作(待完)
//private Expression<Func<T, bool>> GetCurrentUserCondition(Type type)
//{
// var userContext = UserContext.Current;
// if (userContext.IsSuperAdmin)
// {
// return null;
// }
// //LimitCurrentUserPermission开启用户权限与代码生成器同时开起了用户权限才会生效
// if (!LimitCurrentUserPermission || !type.GetCustomAttribute<EntityAttribute>().CurrentUserPermission) { return null; }
// //表的创建人字段必须与配置文件appsettings.json中的创建人字段相同(大小写也必须相同)
// string createId = AppSetting.CreateMember.UserIdField;
// if (type.GetProperty(createId) == null)
// {
// return null;
// }
// Expression<Func<T, bool>> whereExpression = createId.CreateExpression<T>(userContext.UserId, LinqExpressionType.Equal);
// List<int> roles = RoleContext.GetAllChildrenIds(userContext.RoleId);
// //没有下级角色的直看当前用户的数据
// if (roles == null || roles.Count == 0)
// {
// return whereExpression;
// }
// // type.GetProperty();
// return null;
//}
public virtual String GetBillNo(string OPLBNAME,string RULEBLNO="委托编号",string ACCDATE="")
{
var result = "";
UserInfo userInfo = UserContext.Current.UserInfo;
SqlParameter[] Param =
{ new SqlParameter("@OPLBNAME", System.Data.SqlDbType.VarChar),
new SqlParameter("@RULEBLNO", System.Data.SqlDbType.VarChar),
new SqlParameter("@companyid", System.Data.SqlDbType.VarChar), //输出一定要定义字符类型长度 以免报错
};
Param[0].Value = OPLBNAME;
Param[1].Value = RULEBLNO;
Param[2].Value = userInfo.CompanyId.ToString();
List<Dictionary<string,object>> billnoset =
repository.Exec($"SELECT GID,OPLBNAME,RULEBLNO,RULEDATETYPE,BILLTYPE,COMPANYID,ISEDIT,ISAUTO,CUSTOMHEAD ,(select BillName from tSysBillType where BillCode=sys_billno_set.BILLTYPE) BILLTYPEREF from sys_billno_set where oplbname=@OPLBNAME and ruleblno=@RULEBLNO and companyid=@companyid ", Param);
if (billnoset.Count > 0)
{
if (string.IsNullOrWhiteSpace(billnoset[0]["BILLTYPE"].ToString())) return "";
var today = DateTime.Now.AddDays(0).ToString("yyyy-MM-dd");
result = DoGetBillNo(billnoset[0], today, ACCDATE, userInfo);
return result;
}
else {
SqlParameter[] Param2 =
{ new SqlParameter("@OPLBNAME", System.Data.SqlDbType.VarChar),
new SqlParameter("@RULEBLNO", System.Data.SqlDbType.VarChar),
};
Param2[0].Value = OPLBNAME;
Param2[1].Value = RULEBLNO;
billnoset = repository.Exec($"SELECT GID,OPLBNAME,RULEBLNO,RULEDATETYPE,BILLTYPE,COMPANYID,ISEDIT,ISAUTO,CUSTOMHEAD ,(select BillName from tSysBillType where BillCode=sys_billno_set.BILLTYPE) BILLTYPEREF from sys_billno_set where oplbname=@OPLBNAME and ruleblno=@RULEBLNO ", Param2);
if (string.IsNullOrWhiteSpace(billnoset[0]["BILLTYPE"].ToString())) return "";
var today = DateTime.Now.AddDays(0).ToString("yyyy-MM-dd");
result = DoGetBillNo(billnoset[0], today, ACCDATE, userInfo);
return result;
}
}
#region 董家镇项目串口服务获取单据编号 修改
public virtual String GetDJZBillNo(string OPLBNAME, string RULEBLNO = "委托编号", string ACCDATE = "")
{
var result = "";
SqlParameter[] Param =
{ new SqlParameter("@OPLBNAME", System.Data.SqlDbType.VarChar),
new SqlParameter("@RULEBLNO", System.Data.SqlDbType.VarChar),
new SqlParameter("@companyid", System.Data.SqlDbType.VarChar), //输出一定要定义字符类型长度 以免报错
};
Param[0].Value = OPLBNAME;
Param[1].Value = RULEBLNO;
Param[2].Value = "Comcab2d43f60454327af30a131fc1d3abd";
List<Dictionary<string, object>> billnoset =
repository.Exec($"SELECT GID,OPLBNAME,RULEBLNO,RULEDATETYPE,BILLTYPE,COMPANYID,ISEDIT,ISAUTO,CUSTOMHEAD ,(select BillName from tSysBillType where BillCode=sys_billno_set.BILLTYPE) BILLTYPEREF from sys_billno_set where oplbname=@OPLBNAME and ruleblno=@RULEBLNO and companyid=@companyid ", Param);
if (billnoset.Count > 0)
{
if (string.IsNullOrWhiteSpace(billnoset[0]["BILLTYPE"].ToString())) return "";
var today = DateTime.Now.AddDays(0).ToString("yyyy-MM-dd");
result = DoGetBillNoDJZ(billnoset[0], today, ACCDATE);
return result;
}
else
{
SqlParameter[] Param2 =
{ new SqlParameter("@OPLBNAME", System.Data.SqlDbType.VarChar),
new SqlParameter("@RULEBLNO", System.Data.SqlDbType.VarChar),
};
Param2[0].Value = OPLBNAME;
Param2[1].Value = RULEBLNO;
billnoset = repository.Exec($"SELECT GID,OPLBNAME,RULEBLNO,RULEDATETYPE,BILLTYPE,COMPANYID,ISEDIT,ISAUTO,CUSTOMHEAD ,(select BillName from tSysBillType where BillCode=sys_billno_set.BILLTYPE) BILLTYPEREF from sys_billno_set where oplbname=@OPLBNAME and ruleblno=@RULEBLNO ", Param2);
if (string.IsNullOrWhiteSpace(billnoset[0]["BILLTYPE"].ToString())) return "";
var today = DateTime.Now.AddDays(0).ToString("yyyy-MM-dd");
result = DoGetBillNoDJZ(billnoset[0], today, ACCDATE);
return result;
}
}
private string DoGetBillNoDJZ(Dictionary<string, object> billType, string bsdate, string accdate)
{
var orgCode = "Comcab2d43f60454327af30a131fc1d3abd";
var UserCode = "EC269890-F167-454D-AD00-5424BE1C6D06";
var _paramdata = "";
if (billType["RULEDATETYPE"].ToString() == "业务日期")
{
_paramdata = bsdate;
}
if (billType["RULEDATETYPE"].ToString() == "会计期间")
{
_paramdata = accdate;
}
SqlParameter[] Param =
{
//new SqlParameter("@ps_BillType", $"'{billType["BILLTYPE"].ToString()}'"),
//new SqlParameter("@ps_OrgCode", $"'{orgCode}'"),
//new SqlParameter("@ps_EmpCode", $"'{UserCode}'"),
//new SqlParameter("@ps_Date", $"'{_paramdata}'"),
new SqlParameter("@ps_BillType", System.Data.SqlDbType.VarChar),
new SqlParameter("@ps_OrgCode", System.Data.SqlDbType.VarChar),
new SqlParameter("@ps_EmpCode", System.Data.SqlDbType.VarChar),
new SqlParameter("@ps_Date", System.Data.SqlDbType.VarChar),
new SqlParameter("@ps_bshead", System.Data.SqlDbType.VarChar),
new SqlParameter("@ps_BillNo", System.Data.SqlDbType.VarChar),
new SqlParameter("@ps_RefBillNo", System.Data.SqlDbType.VarChar),
};
Param[0].Value = billType["BILLTYPE"].ToString();
Param[1].Value = orgCode;
Param[2].Value = UserCode;
Param[3].Value = _paramdata;
Param[4].Value = "";
Param[5].Value = "";
Param[6].Value = "";
var resultdic = repository.ExecSp("sSysGetBillNo_new", Param);
var result = resultdic[0]["BillNo"].ToString();
return result;
}
#endregion
private string DoGetBillNo(Dictionary<string, object> billType, string bsdate, string accdate, UserInfo userInfo)
{
var orgCode = userInfo.CompanyId.ToString();
var UserCode = userInfo.User_Id.ToString();
var _paramdata = "";
if (billType["RULEDATETYPE"].ToString() == "业务日期") {
_paramdata = bsdate;
}
if (billType["RULEDATETYPE"].ToString() == "会计期间")
{
_paramdata = accdate;
}
SqlParameter[] Param =
{
//new SqlParameter("@ps_BillType", $"'{billType["BILLTYPE"].ToString()}'"),
//new SqlParameter("@ps_OrgCode", $"'{orgCode}'"),
//new SqlParameter("@ps_EmpCode", $"'{UserCode}'"),
//new SqlParameter("@ps_Date", $"'{_paramdata}'"),
new SqlParameter("@ps_BillType", System.Data.SqlDbType.VarChar),
new SqlParameter("@ps_OrgCode", System.Data.SqlDbType.VarChar),
new SqlParameter("@ps_EmpCode", System.Data.SqlDbType.VarChar),
new SqlParameter("@ps_Date", System.Data.SqlDbType.VarChar),
new SqlParameter("@ps_bshead", System.Data.SqlDbType.VarChar),
new SqlParameter("@ps_BillNo", System.Data.SqlDbType.VarChar),
new SqlParameter("@ps_RefBillNo", System.Data.SqlDbType.VarChar),
};
Param[0].Value = billType["BILLTYPE"].ToString();
Param[1].Value = orgCode;
Param[2].Value = UserCode;
Param[3].Value = _paramdata;
Param[4].Value = "";
Param[5].Value = "";
Param[6].Value = "";
var resultdic = repository.ExecSp("sSysGetBillNo_new", Param);
var result = resultdic[0]["BillNo"].ToString();
return result;
}
private object GetPropertyValue(T entity, string propertyName)
{
object result = null;
Type entityType = typeof(T);
try
{
PropertyInfo proInfo = entityType.GetProperty(propertyName);
result = proInfo.GetValue(entity);
}
catch (Exception)
{
}
return result;
}
public void wms_add<toT,fromT>(ref toT tot, fromT fromt)
where fromT:class , new()
where toT:class
{
fieldadd(ref tot, fromt, "KGS");
fieldadd(ref tot, fromt, "NETWEIGHT");
fieldadd(ref tot, fromt, "CBM");
fieldadd(ref tot, fromt, "PKGS");
fieldadd(ref tot, fromt, "STORAGEUNITCOUNT");
fieldadd(ref tot, fromt, "RULEUNITCOUNT");
fieldadd(ref tot, fromt, "SMALLPKGS");
fieldadd(ref tot, fromt, "MINPKGS");
}
public void wms_cut<toT, fromT>(ref toT tot, fromT fromt)
where fromT : class, new()
where toT : class
{
fieldcut(ref tot, fromt, "KGS");
fieldcut(ref tot, fromt, "NETWEIGHT");
fieldcut(ref tot, fromt, "CBM");
fieldcut(ref tot, fromt, "PKGS");
fieldcut(ref tot, fromt, "STORAGEUNITCOUNT");
fieldcut(ref tot, fromt, "RULEUNITCOUNT");
fieldcut(ref tot, fromt, "SMALLPKGS");
fieldcut(ref tot, fromt, "MINPKGS");
}
/// <summary>
/// 将与数量相关的6个字段从后赋值到前
/// (KGS PKGS CBM NETWEIGHT STORAGEUNITCOUNT RULEUNITCOUNT)
/// </summary>
/// <typeparam name="toT"></typeparam>
/// <typeparam name="fromT"></typeparam>
/// <param name="tot"></param>
/// <param name="fromt"></param>
public void wms_copy<toT, fromT>(ref toT tot, fromT fromt)
where fromT : class, new()
where toT : class
{
fieldcopy(ref tot, fromt, "KGS");
fieldcopy(ref tot, fromt, "NETWEIGHT");
fieldcopy(ref tot, fromt, "CBM");
fieldcopy(ref tot, fromt, "PKGS");
fieldcopy(ref tot, fromt, "STORAGEUNITCOUNT");
fieldcopy(ref tot, fromt, "RULEUNITCOUNT");
fieldcopy(ref tot, fromt, "SMALLPKGS");
fieldcopy(ref tot, fromt, "MINPKGS");
}
public void wms_getPkgs<toT, fromT>(ref toT tot, fromT fromt,decimal NEWPKGS =1m)
where fromT : class, new()
where toT : class
{
var OLDPKGS = fieldGetValue(fromt, "PKGS");
var bili = NEWPKGS / OLDPKGS;
//fieldcopy(ref tot, fromt, "KGS");
//fieldcopy(ref tot, fromt, "NETWEIGHT");
//fieldcopy(ref tot, fromt, "CBM");
//fieldcopy(ref tot, fromt, "PKGS");
//fieldcopy(ref tot, fromt, "STORAGEUNITCOUNT");
//fieldcopy(ref tot, fromt, "RULEUNITCOUNT");
var NewKGS = fieldGetValue(fromt, "KGS") * bili;
var NewNETWEIGHT = fieldGetValue(fromt, "NETWEIGHT") * bili;
var NewCBM = fieldGetValue(fromt, "CBM") * bili;
var NewSTORAGEUNITCOUNT = fieldGetValue(fromt, "STORAGEUNITCOUNT") * bili;
var NewRULEUNITCOUNT = fieldGetValue(fromt, "RULEUNITCOUNT") * bili;
var NewSMALLPKGS = fieldGetValue(fromt, "SMALLPKGS") * bili;
var NewMINPKGS = fieldGetValue(fromt, "MINPKGS") * bili;
fieldSetValue(tot, "KGS", NewKGS);
fieldSetValue(tot, "NETWEIGHT", NewNETWEIGHT);
fieldSetValue(tot, "CBM", NewCBM);
//fieldSetValue(tot, "PKGS");
fieldSetValue(tot, "STORAGEUNITCOUNT", NewSTORAGEUNITCOUNT);
fieldSetValue(tot, "RULEUNITCOUNT", NewRULEUNITCOUNT);
fieldSetValue(tot, "SMALLPKGS", NewSMALLPKGS);
fieldSetValue(tot, "MINPKGS", NewMINPKGS);
}
public void wms_getStorageunitcount<toT, fromT>(ref toT tot, fromT fromt, decimal NEWSTORAGEUNITCOUNT = 1m)
where fromT : class, new()
where toT : class
{
var OLDSTORAGEUNITCOUNT = fieldGetValue(fromt, "STORAGEUNITCOUNT");
var bili = NEWSTORAGEUNITCOUNT / OLDSTORAGEUNITCOUNT;
//fieldcopy(ref tot, fromt, "KGS");
//fieldcopy(ref tot, fromt, "NETWEIGHT");
//fieldcopy(ref tot, fromt, "CBM");
//fieldcopy(ref tot, fromt, "PKGS");
//fieldcopy(ref tot, fromt, "STORAGEUNITCOUNT");
//fieldcopy(ref tot, fromt, "RULEUNITCOUNT");
var NewKGS = fieldGetValue(fromt, "KGS") * bili;
var NewNETWEIGHT = fieldGetValue(fromt, "NETWEIGHT") * bili;
var NewCBM = fieldGetValue(fromt, "CBM") * bili;
//var NewSTORAGEUNITCOUNT = fieldGetValue(fromt, "STORAGEUNITCOUNT") * bili;
var NewPKGS = Math.Floor( fieldGetValue(fromt, "PKGS") * bili);
var NewRULEUNITCOUNT = fieldGetValue(fromt, "RULEUNITCOUNT") * bili;
var NewSMALLPKGS = fieldGetValue(fromt, "SMALLPKGS") * bili;
var NewMINPKGS = fieldGetValue(fromt, "MINPKGS") * bili;
fieldSetValue(tot, "KGS", NewKGS);
fieldSetValue(tot, "NETWEIGHT", NewNETWEIGHT);
fieldSetValue(tot, "CBM", NewCBM);
fieldSetValue(tot, "PKGS", NewPKGS);
fieldSetValue(tot, "STORAGEUNITCOUNT", NEWSTORAGEUNITCOUNT);
fieldSetValue(tot, "RULEUNITCOUNT", NewRULEUNITCOUNT);
fieldSetValue(tot, "SMALLPKGS", NewSMALLPKGS);
fieldSetValue(tot, "MINPKGS", NewMINPKGS);
}
public void wms_new<toT>(ref toT tot)
where toT : class
{
fieldSetValue(tot, "KGS");
fieldSetValue(tot, "NETWEIGHT");
fieldSetValue(tot, "CBM");
fieldSetValue(tot, "PKGS");
fieldSetValue(tot, "STORAGEUNITCOUNT");
fieldSetValue(tot, "RULEUNITCOUNT");
fieldSetValue(tot, "SMALLPKGS");
fieldSetValue(tot, "MINPKGS");
}
public bool wms_isequal<toT, fromT>(toT tot, fromT fromt)
where fromT : class, new()
where toT : class
{
return fieldisequal(tot, fromt, "KGS")&& fieldisequal(tot, fromt, "NETWEIGHT") && fieldisequal(tot, fromt, "CBM") && fieldisequal(tot, fromt, "PKGS")&& fieldisequal(tot, fromt, "STORAGEUNITCOUNT") && fieldisequal(tot, fromt, "RULEUNITCOUNT");
}
/// <summary>
/// 前方tot大于后面的fromt
/// </summary>
/// <typeparam name="toT"></typeparam>
/// <typeparam name="fromT"></typeparam>
/// <param name="tot"></param>
/// <param name="fromt"></param>
/// <returns></returns>
public bool wms_isBig<toT, fromT>(toT tot, fromT fromt)
where fromT : class, new()
where toT : class
{
return fieldisBig(tot, fromt, "KGS") || fieldisBig(tot, fromt, "NETWEIGHT") || fieldisBig(tot, fromt, "CBM") || fieldisBig(tot, fromt, "PKGS") || fieldisBig(tot, fromt, "STORAGEUNITCOUNT") || fieldisBig(tot, fromt, "RULEUNITCOUNT");
}
/// <summary>
/// 两个对象的指定字段相加,后者加入到前者内。
/// </summary>
/// <typeparam name="fromT"></typeparam>
/// <param name="tot"></param>
/// <param name="fromt"></param>
/// <param name="fieldname"></param>
public void fieldadd<toT,fromT>(ref toT tot, fromT fromt,string fieldname)
where fromT : class, new()
where toT : class
{
Type entityType = typeof(toT);
PropertyInfo to_proInfo = entityType.GetProperty(fieldname);
var tofield = to_proInfo.GetValue(tot) == null ? 0 : (decimal)to_proInfo.GetValue(tot);//(decimal)to_proInfo.GetValue(tot);
Type fromType = typeof(fromT);
PropertyInfo profrom = fromType.GetProperty(fieldname);
var fromfield = profrom.GetValue(fromt) == null ? 0 : (decimal)profrom.GetValue(fromt);//(decimal)profrom.GetValue(fromt);
to_proInfo.SetValue(tot, tofield + fromfield);
}
/// <summary>
/// 两个对象的指定字段相减,从前者内去掉后者。
/// </summary>
/// <typeparam name="fromT"></typeparam>
/// <param name="tot"></param>
/// <param name="fromt"></param>
/// <param name="fieldname"></param>
public void fieldcut<toT, fromT>(ref toT tot, fromT fromt, string fieldname)
where fromT : class, new()
where toT : class
{
Type entityType = typeof(toT);
PropertyInfo to_proInfo = entityType.GetProperty(fieldname);
var tofield = to_proInfo.GetValue(tot) == null ? 0 : (decimal)to_proInfo.GetValue(tot);//(decimal)to_proInfo.GetValue(tot);
Type fromType = typeof(fromT);
PropertyInfo profrom = fromType.GetProperty(fieldname);
var fromfield = profrom.GetValue(fromt) == null ? 0 : (decimal)profrom.GetValue(fromt);//(decimal)profrom.GetValue(fromt);
to_proInfo.SetValue(tot, tofield - fromfield);
}
public void fieldcopy<toT, fromT>(ref toT tot, fromT fromt, string fieldname)
where fromT : class, new()
where toT : class
{
Type entityType = typeof(toT);
PropertyInfo to_proInfo = entityType.GetProperty(fieldname);
//var tofield = (decimal)to_proInfo.GetValue(tot);
Type fromType = typeof(fromT);
PropertyInfo profrom = fromType.GetProperty(fieldname);
var fromfield = profrom.GetValue(fromt)==null?0: (decimal)profrom.GetValue(fromt);
to_proInfo.SetValue(tot, fromfield);
}
/// <summary>
/// 相同
/// </summary>
/// <typeparam name="toT"></typeparam>
/// <typeparam name="fromT"></typeparam>
/// <param name="tot"></param>
/// <param name="fromt"></param>
/// <param name="fieldname"></param>
/// <returns></returns>
public bool fieldisequal<toT, fromT>(toT tot, fromT fromt, string fieldname)
where fromT : class, new()
where toT : class
{
Type entityType = typeof(toT);
PropertyInfo to_proInfo = entityType.GetProperty(fieldname);
var tofield = to_proInfo.GetValue(tot) == null ? 0 : (decimal)to_proInfo.GetValue(tot);//(decimal)to_proInfo.GetValue(tot);
Type fromType = typeof(fromT);
PropertyInfo profrom = fromType.GetProperty(fieldname);
var fromfield = profrom.GetValue(fromt) == null ? 0 : (decimal)profrom.GetValue(fromt);//(decimal)profrom.GetValue(fromt);
return (tofield == fromfield);
}
/// <summary>
/// 较大
/// </summary>
/// <typeparam name="toT"></typeparam>
/// <typeparam name="fromT"></typeparam>
/// <param name="tot"></param>
/// <param name="fromt"></param>
/// <param name="fieldname"></param>
/// <returns></returns>
public bool fieldisBig<toT, fromT>(toT tot, fromT fromt, string fieldname)
where fromT : class, new()
where toT : class
{
Type entityType = typeof(toT);
PropertyInfo to_proInfo = entityType.GetProperty(fieldname);
var tofield = to_proInfo.GetValue(tot) == null ? 0 : (decimal)to_proInfo.GetValue(tot);// (decimal)to_proInfo.GetValue(tot);
Type fromType = typeof(fromT);
PropertyInfo profrom = fromType.GetProperty(fieldname);
var fromfield = profrom.GetValue(fromt) == null ? 0 : (decimal)profrom.GetValue(fromt);//(decimal)profrom.GetValue(fromt);
return (tofield > fromfield);
}
public void fieldSetValue<toT>(toT tot, string fieldname,decimal value=0)
where toT : class
{
Type entityType = typeof(toT);
PropertyInfo to_proInfo = entityType.GetProperty(fieldname);
to_proInfo.SetValue(tot, value);
}
public decimal fieldGetValue<fromT>(fromT fromt, string fieldname, decimal value = 0)
where fromT : class
{
Type entityType = typeof(fromT);
PropertyInfo to_proInfo = entityType.GetProperty(fieldname);
return to_proInfo.GetValue(fromt) == null ? 0 : (decimal)to_proInfo.GetValue(fromt);
}
public void RemoveSearchParam(ref List<SearchParameters> parameters,string FieldName) {
for (var _i = parameters.Count - 1; _i >= 0; _i--)
{
if (parameters[_i].Name == FieldName)
parameters.Remove(parameters[_i]);
}
}
public Expression<Func<T, bool>> GetOrExpression(string FieldName, string paramStr) {
Expression<Func<T, bool>> _true = x => 1 == 1;
if (!string.IsNullOrWhiteSpace(paramStr))
{
var _paramlist = paramStr.Split(",");
var paramlist = new List<string>();
foreach (var item in _paramlist) {
if (!string.IsNullOrWhiteSpace(item.Trim())) {
paramlist.Add(item);
}
}
if (paramlist == null || paramlist.Count == 0) {
return _true;
}
//if (paramlist.Count() == 1)
//{
// Expression<Func<T, bool>> _oneParam = FieldName.CreateExpression<T>(paramlist[0].ToString(), LinqExpressionType.Contains);
// return _oneParam;
//}
//else
//{
//PropertyInfo property = TProperties.Where(c => c.Name.ToUpper() == x.Name.ToUpper()).FirstOrDefault();
Expression<Func<T, bool>> expre = FieldName.CreateExpression<T>(paramlist[0].ToString(), LinqExpressionType.Contains);
foreach (var param in paramlist)
{
if (param == paramlist[0]) continue;
expre = ExpressionFuncExtender.Or(expre, FieldName.CreateExpression<T>(param.ToString(), LinqExpressionType.Contains));
}
return expre;
//}
}
else {
return _true;
}
}
/// <summary>
/// 将查询条件中的指定字段 改为指定形式
/// 默认改为startwith的形式
/// </summary>
/// <param name="options"></param>
/// <param name="FieldName"></param>
public void SetFieldSearchType(ref PageDataOptions options, string FieldName,string newtype="StartWith") {
try
{
var searchParametersList = options.Wheres.DeserializeObject<List<SearchParameters>>();
if (searchParametersList.Exists(x => x.Name == FieldName))
{
searchParametersList.First(x => x.Name == FieldName).SearchType = newtype;
}
options.Wheres = Newtonsoft.Json.JsonConvert.SerializeObject(searchParametersList);
}
catch { }
}
}
public class SaveResult:object {
public object data { get; set; }
public object message { get; set; }
public bool status { get; set; }
public SaveResult(object Data, string Message="",bool Status= true) {
data = Data;
message = Message;
status = Status;
}
}
/// <summary>
/// 基础工具类
/// 通用工具类
/// </summary>
public static class BasicDataRef {
/// <summary>
/// 返回两个时间的间隔天数之差+1
/// 如
/// </summary>
/// <param name="dt1"></param>
/// <param name="dt2"></param>
/// <returns></returns>
public static decimal days(DateTime dt1, DateTime dt2)
{
TimeSpan ts = dt2.Subtract(dt1);
if (ts.TotalDays < 0) ts = dt1.Subtract(dt2);
return decimal.Parse(Math.Floor(ts.TotalDays + 1).ToString());
}
/// <summary>
/// 通过公司ID获取公司名称
/// </summary>
/// <param name="companyid"></param>
/// <returns></returns>
public static string getCompanyFullName(string companyid) {
var companydiclist = DBServerProvider.SqlDapper.QueryList<SourceKeyVaule>("select GID [key],fullname [value] from company ", null)
.Where(x => (x.Key).ToString() == companyid)
.Select(s => new Sys_DictionaryList()
{
DicName = s.Value,
DicValue = s.Key.ToString()
}).ToList();
var companydic = companydiclist[0];
return companydic.DicName;
}
public static CompanyField getCompany(string companyid)
{
try
{
var companydiclist = DBServerProvider.SqlDapper.QueryList<CompanyField>("select [GID],[CODENAME],[NAME],[FULLNAME],[ENNAME],[ADDRESS],[ENADDRESS],[POSTCODE],[OFFICEPHONE],[FAX],[EMAIL],[WEBSITEURL],[LICENSECODE],[TAXCODE],[LOGO],[CREATEUSER],[CREATETIME],[MODIFIEDUSER],[MODIFIEDTIME],[ISDELETED],[ISDISABLE],[PARENTID],[BILLRISES],[CHEQUEPAYABLE],[PRTHEADXML1],[PRTHEADXML2],[PRTHEADXML3],[PRTHEADXML4],[PRTHEADXML5],[BANKSHEAD],[GPSUser],[GPSPassWord],[ORGANIZATIONCODE],[DBNAME],[LOCALCURR],[WORKFLOWMSG],[openCustom],[allowOpenMark2],[TRADE_CODE],[UNIT],[VGMCODE],[bxid],[CLOSEETDDAY],MANAGER from company ", null)
.Where(x => (x.GID).ToString() == companyid)
.ToList();
var company = companydiclist[0];
return company;
}
catch (Exception e) {
return new CompanyField();
}
}
/// <summary>
/// 消息实体
/// </summary>
public class NoticeInput
{
/// <summary>
/// 标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 公司Id
/// </summary>
public string CompanyId { get; set; }
/// <summary>
/// 内容
/// </summary>
public string Content { get; set; }
}
/// <summary>
/// 发送系统消息
/// </summary>
/// <param name="notice"></param>
public static void SendSysNotice(NoticeInput input)
{
var Gid = Guid.NewGuid();
var notice = new Sys_Announcement
{
Gid = Gid,
Title = input.Title,
AnnouncementType = 2,//系统消息
ReceiveType = 2,//指定用户
Abstract = input.Content,
Content = input.Content,
SendStatus = 1,
EndTime = DateTime.Now.AddMonths(1),
SendTime = DateTime.Now,
Status = 0,
CreateDate = DateTime.Now,
CreateID = Guid.Parse("1BEC90E1-9780-472F-90C2-0C6390C044A4"),
Creator = "系统管理员",
};
DBServerProvider.SqlDapper.Add(notice);
var relation = new Sys_AnnouncementCompany
{
AnnouncementId = Gid,
CompanyId = input.CompanyId,
IsRead = false,
};
DBServerProvider.SqlDapper.Add(relation);
}
/// <summary>
/// 获取某一字符串第N到第N+1空格的字符
/// </summary>
/// <returns></returns>
public static Func<int, int, string, string, string> GetStrOfStringInBlankIndex()
{
return (x, y, z, f) =>
{
int start = GetBlankIndexOfString()(x, z, f);
int end = GetBlankIndexOfString()(y, z, f);
string str = f.Substring(start, end - start);
return str;
};
}
/// <summary>
/// 获取第N个空格所在
/// </summary>
/// <returns></returns>
public static Func<int, string, string, int> GetBlankIndexOfString()
{
return (x, y, z) =>
{
int result = 0, index = 0;
string str = z;
for (int i = 0; i < x; i++)
{
index = str.IndexOf(y);
str = str.Substring(index, str.Length - index).TrimStart();
result = z.LastIndexOf(str);
}
return result;
};
}
public static string GetSqlIDList(List<string> strlist) {
var result = "'" + string.Join("','", strlist.ToArray()) + "'" ;
return result;
}
public static long ConvertDateTimeToInt(DateTime time)
{
DateTimeOffset dto = new DateTimeOffset(time);
return dto.ToUnixTimeMilliseconds();
}
}
/// <summary>
/// AutoMapper的帮助类
/// </summary>
public static class AutoMapperHelper
{
/// <summary>
/// 来源,目标
/// 单条实体类型映射,默认字段名字一一对应
///
/// </summary>
/// <typeparam name="TSource">Dto类型</typeparam>
/// <typeparam name="TDestination">要被转化的数据</typeparam>
/// <param name="source">转化之后的实体</param>
/// <returns></returns>
public static TDestination MapTo<TSource, TDestination>(this TSource source)
where TDestination : class, new()
where TSource : class
{
if (source == null) return new TDestination();
var config = new MapperConfiguration(cfg => cfg.CreateMap<TSource, TDestination>());
var mapper = config.CreateMapper();
return mapper.Map<TDestination>(source);
}
/// <summary>
/// 实体列表类型映射,默认字段名字一一对应
/// </summary>
/// <typeparam name="TDestination">Dto类型</typeparam>
/// <typeparam name="TSource">要被转化的数据</typeparam>
/// <param name="source">可以使用这个扩展方法的类型,任何引用类型</param>
/// <returns>转化之后的实体列表</returns>
public static List<TDestination> MapToList<TSource, TDestination>(this IEnumerable<TSource> source)
where TDestination : class
where TSource : class
{
if (source == null) return new List<TDestination>();
var config = new MapperConfiguration(cfg => cfg.CreateMap<TSource, TDestination>());
var mapper = config.CreateMapper();
return mapper.Map<List<TDestination>>(source);
}
}
public class Query
{
public enum Operators
{
None = 0,
Equal = 1,
GreaterThan = 2,
GreaterThanOrEqual = 3,
LessThan = 4,
LessThanOrEqual = 5,
Contains = 6,
StartWith = 7,
EndWidth = 8,
Range = 9,
NotEqual=10
}
public enum Condition
{
OrElse = 1,
AndAlso = 2
}
public string Name { get; set; }
public Operators Operator { get; set; }
public object Value { get; set; }
public object ValueMin { get; set; }
public object ValueMax { get; set; }
}
public class QueryCollection : Collection<Query>
{
public Expression<Func<T, bool>> AsExpression<T>(Query.Condition? condition = Query.Condition.OrElse) where T : class
{
Type targetType = typeof(T);
TypeInfo typeInfo = targetType.GetTypeInfo();
var parameter = Expression.Parameter(targetType, "m");
Expression expression = null;
Func<Expression, Expression, Expression> Append = (exp1, exp2) =>
{
if (exp1 == null)
{
return exp2;
}
return (condition ?? Query.Condition.OrElse) == Query.Condition.OrElse ? Expression.OrElse(exp1, exp2) : Expression.AndAlso(exp1, exp2);
};
foreach (var item in this)
{
var property = typeInfo.GetProperty(item.Name);
if (property == null ||
!property.CanRead ||
(item.Operator != Query.Operators.Range && item.Value == null) ||
(item.Operator == Query.Operators.Range && item.ValueMin == null && item.ValueMax == null))
{
continue;
}
Type realType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
if (item.Value != null)
{
item.Value = Convert.ChangeType(item.Value, realType);
}
Expression<Func<object>> valueLamba = () => item.Value;
switch (item.Operator)
{
case Query.Operators.Equal:
{
expression = Append(expression, Expression.Equal(Expression.Property(parameter, item.Name),
Expression.Convert(valueLamba.Body, property.PropertyType)));
break;
}
case Query.Operators.GreaterThan:
{
expression = Append(expression, Expression.GreaterThan(Expression.Property(parameter, item.Name),
Expression.Convert(valueLamba.Body, property.PropertyType)));
break;
}
case Query.Operators.GreaterThanOrEqual:
{
expression = Append(expression, Expression.GreaterThanOrEqual(Expression.Property(parameter, item.Name),
Expression.Convert(valueLamba.Body, property.PropertyType)));
break;
}
case Query.Operators.LessThan:
{
expression = Append(expression, Expression.LessThan(Expression.Property(parameter, item.Name),
Expression.Convert(valueLamba.Body, property.PropertyType)));
break;
}
case Query.Operators.LessThanOrEqual:
{
expression = Append(expression, Expression.LessThanOrEqual(Expression.Property(parameter, item.Name),
Expression.Convert(valueLamba.Body, property.PropertyType)));
break;
}
case Query.Operators.Contains:
{
var nullCheck = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, Expression.Property(parameter, item.Name)));
var contains = Expression.Call(Expression.Property(parameter, item.Name), "Contains", null,
Expression.Convert(valueLamba.Body, property.PropertyType));
expression = Append(expression, Expression.AndAlso(nullCheck, contains));
break;
}
case Query.Operators.StartWith:
{
var nullCheck = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, Expression.Property(parameter, item.Name)));
var startsWith = Expression.Call(Expression.Property(parameter, item.Name), "StartsWith", null,
Expression.Convert(valueLamba.Body, property.PropertyType));
expression = Append(expression, Expression.AndAlso(nullCheck, startsWith));
break;
}
case Query.Operators.EndWidth:
{
var nullCheck = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, Expression.Property(parameter, item.Name)));
var endsWith = Expression.Call(Expression.Property(parameter, item.Name), "EndsWith", null,
Expression.Convert(valueLamba.Body, property.PropertyType));
expression = Append(expression, Expression.AndAlso(nullCheck, endsWith));
break;
}
case Query.Operators.Range:
{
Expression minExp = null, maxExp = null;
if (item.ValueMin != null)
{
var minValue = Convert.ChangeType(item.ValueMin, realType);
Expression<Func<object>> minValueLamda = () => minValue;
minExp = Expression.GreaterThanOrEqual(Expression.Property(parameter, item.Name), Expression.Convert(minValueLamda.Body, property.PropertyType));
}
if (item.ValueMax != null)
{
var maxValue = Convert.ChangeType(item.ValueMax, realType);
Expression<Func<object>> maxValueLamda = () => maxValue;
maxExp = Expression.LessThanOrEqual(Expression.Property(parameter, item.Name), Expression.Convert(maxValueLamda.Body, property.PropertyType));
}
if (minExp != null && maxExp != null)
{
expression = Append(expression, Expression.AndAlso(minExp, maxExp));
}
else if (minExp != null)
{
expression = Append(expression, minExp);
}
else if (maxExp != null)
{
expression = Append(expression, maxExp);
}
break;
}
case Query.Operators.NotEqual:
{
expression = Append(expression, Expression.NotEqual(Expression.Property(parameter, item.Name),
Expression.Convert(valueLamba.Body, property.PropertyType)));
break;
}
}
}
if (expression == null)
{
return null;
}
return ((Expression<Func<T, bool>>)Expression.Lambda(expression, parameter));
}
}
public static class ExpressionFuncExtender
{
/// <summary>
/// 以特定的条件运行组合两个Expression表达式
/// </summary>
/// <typeparam name="T">表达式的主实体类型</typeparam>
/// <param name="first">第一个Expression表达式</param>
/// <param name="second">要组合的Expression表达式</param>
/// <param name="merge">组合条件运算方式</param>
/// <returns>组合后的表达式</returns>
public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second,
Func<Expression, Expression, Expression> merge)
{
var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
}
/// <summary>
/// 以 Expression.AndAlso 组合两个Expression表达式
/// </summary>
/// <typeparam name="T">表达式的主实体类型</typeparam>
/// <param name="first">第一个Expression表达式</param>
/// <param name="second">要组合的Expression表达式</param>
/// <returns>组合后的表达式</returns>
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first,
Expression<Func<T, bool>> second)
{
return first.Compose(second, Expression.AndAlso);
}
/// <summary>
/// 以 Expression.OrElse 组合两个Expression表达式
/// </summary>
/// <typeparam name="T">表达式的主实体类型</typeparam>
/// <param name="first">第一个Expression表达式</param>
/// <param name="second">要组合的Expression表达式</param>
/// <returns>组合后的表达式</returns>
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first,
Expression<Func<T, bool>> second)
{
return first.Compose(second, Expression.OrElse);
}
private class ParameterRebinder : ExpressionVisitor
{
private readonly Dictionary<ParameterExpression, ParameterExpression> _map;
private ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
{
_map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
}
public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map,
Expression exp)
{
return new ParameterRebinder(map).Visit(exp);
}
protected override Expression VisitParameter(ParameterExpression node)
{
ParameterExpression replacement;
if (_map.TryGetValue(node, out replacement))
node = replacement;
return base.VisitParameter(node);
}
}
}
/// <summary>
/// 工具类 用于处理【用逗号隔开的文本字段】的内容
/// </summary>
public class STRLISTField {
private List<string> strlist { get; set; }
public string getStr() {
var result = "";
foreach (var item in strlist) {
if (result != "") result += ",";
result += item;
}
return result;
}
private static List<string> getstrlist(string fieldvalue) {
var _strlist = new List<string>();
if (!string.IsNullOrWhiteSpace(fieldvalue))
{
_strlist = fieldvalue.Split(",").ToList();
}
return _strlist;
}
public STRLISTField() { }
public STRLISTField(string fieldvalue) {
strlist = getstrlist(fieldvalue);
}
public STRLISTField(string fieldvalue,string addfield)
{
strlist = getstrlist(fieldvalue);
add(addfield);
}
public void add(string fieldvalue) {
var addlist = getstrlist(fieldvalue);
foreach (var additem in addlist) {
if (!strlist.Exists(x => x == additem)) {
strlist.Add(additem);
}
}
}
public void del(string fieldvalue)
{
var dellist = getstrlist(fieldvalue);
foreach (var delitem in dellist)
{
if (strlist.Exists(x => x == delitem))
{
strlist.Remove(delitem);
}
}
}
}
}