This commit is contained in:
owenchen committed 2026-08-19 14:11:17 +08:00
commit f05d2d215f
678 files changed
+73865

No files matched your search

@@ -0,0 +1,125 @@
using CloudBuilder.Core.Extensions;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudBuilder.Core.Service
{
public class AbstractSearchCriteria
{
public int limit { get; set; } = 20;
public int page { get; set; }
public int clear { get; set; }
public string? orderby { get; set; } = string.Empty;
public string? orderbytag { get; set; } = string.Empty;
public SearchFilter[]? Filter { get; set; }
public bool IsModal { get; set; } = false;
public string? ReportName { get; set; }
public GridColumnInfo[]? GridColumns { get; set; }
public SelectOption[]? SelectOptions { get; set; }
public List<string> PackSearchCriteriaDisplay(ref List<TemplateHeader> headers, ref string sqlWhere)
{
return PackSearchCriteriaDisplay(ref headers, ref sqlWhere, null);
}
public List<string> PackSearchCriteriaDisplay(ref List<TemplateHeader> headers, ref string sqlWhere, Dictionary<string, Dictionary<string, object>> mappings)
{
List<string> l = new List<string>();
if (this.GridColumns != null && this.GridColumns.Length > 0)
{
foreach (var column in this.GridColumns)
{
if (!string.IsNullOrEmpty(column.title))
{
if (column.hidden != "N") continue;
if (string.IsNullOrEmpty(column.dataIndex) || string.IsNullOrEmpty(column.title) || column.dataIndex == "index") continue;
headers.Add(new TemplateHeader()
{
DisplayName = column.title,
BindingName = column.dataIndex!,
Format = column.format!,
Width = TemplateHeader.WidthAutoFit
});
}
}
}
if (this.Filter != null && this.Filter.Length > 0)
{
sqlWhere = SearchFilter.ComposeWhereClause(this.Filter);
foreach (SearchFilter filter in this.Filter)
{
if (!string.IsNullOrEmpty(filter.Column) && headers.Where(x => filter.Column.StringToProerty() == x.BindingName).Count() > 0)
{
TemplateHeader h = headers.Where(x => filter.Column.StringToProerty() == x.BindingName).FirstOrDefault();
string v = filter.Value;
switch (filter.Operator)
{
case SearchFilterOperatorPolicy.BETWEEN:
case SearchFilterOperatorPolicy.DATE_BETWEEN:
case SearchFilterOperatorPolicy.DATETIME_BETWEEN:
if (!string.IsNullOrEmpty(filter.Value) && string.IsNullOrEmpty(filter.Value1))
v = string.Format("[ {0} ~ ]", filter.Value);
break;
}
if (!string.IsNullOrEmpty(filter.Value) && !string.IsNullOrEmpty(filter.Value1)) v = string.Format("[ {0} ~ {1} ]", filter.Value, filter.Value1);
if (string.IsNullOrEmpty(filter.Value) && !string.IsNullOrEmpty(filter.Value1)) v = string.Format("[ ~ {0}]", filter.Value1);
if (filter.Values != null && filter.Values.Length > 0)
{
v = QuotedString.ToDelimiteredList(filter.Values);
if (mappings != null && mappings.Count() > 0)
{
List<string> m = new List<string>();
foreach (string mv in filter.Values)
{
m.Add(mappings[h.BindingName][mv].ToString());
}
v = QuotedString.ToDelimiteredList(m.ToArray());
}
}
l.Add(string.Format("{0}: {1}", h.DisplayName, v));
}
}
}
return l;
}
}
public class TemplateHeader
{
public const string DateFormat1 = "yyyy-MM-dd";
public const string DateTimeFormat1 = "yyyy-MM-dd HH:mm:ss";
public const string IntFormat1 = "#,##0;(#,##0)";
public const string DecimalFormat1 = "#,##0.00;(#,##0.00)";
public const string PercentageFormat1 = "0.0%";
public const double WidthAutoFit = -1;
public TemplateHeader()
{
Width = WidthAutoFit;
}
public string Format { get; set; }
public string DisplayName { get; set; }
public string BindingName { get; set; }
public string CellTypeFormatName { get; set; }
public string DataValueFormatName { get; set; }
public double Width { get; set; }
public int? DisplayIndex { get; set; }
}
}
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudBuilder.Core.Service
{
public class ExceptionData
{
public string StatusCode { get; set; }
public string ErrMsg { get; set; }
}
}
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudBuilder.Core.Service
{
public interface IService
{
}
}
@@ -0,0 +1,18 @@
using CloudBuilder.Core.DatabaseAccessor;
namespace CloudBuilder.Core.Service
{
public interface IServiceBase<Tdata, Tkey, Tc> : IService
{
Tdata FindByKey(Tkey tc);
[UnitOfWork]
Tdata Insert(Tdata tdata);
[UnitOfWork]
Tdata Update(Tdata tdata);
[UnitOfWork]
void Delete(Tkey tkey);
}
}
@@ -0,0 +1,307 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudBuilder.Core.Service
{
public class SearchCriteria
{
public const string KEY_FILTER_COLUMN = "filter_column";
public const string KEY_FILTER_OPERATOR = "filter_operator";
public const string KEY_FILTER_TYPE = "filter_type";
public SearchCriteria()
{
Add(KEY_FILTER_OPERATOR, SearchFilterOperatorPolicy.GetInstance().GetBindOptions());
Add(KEY_FILTER_TYPE, SearchFilterTypePolicy.GetInstance().GetBindOptions());
}
public SearchCriteria(Selection[] selections)
{
Selections = selections;
Add(KEY_FILTER_OPERATOR, SearchFilterOperatorPolicy.GetInstance().GetBindOptions());
Add(KEY_FILTER_TYPE, SearchFilterTypePolicy.GetInstance().GetBindOptions());
}
public Selection[] Selections { get; set; }
public void Add(string key, BindOption[] bindOptions)
{
if (bindOptions == null || bindOptions.Length == 0) return;
List<Selection> selections = new List<Selection>();
if (Selections != null)
{
selections.AddRange(Selections);
}
selections.Add(new Selection() { Key = key, BindOptions = bindOptions });
Selections = selections.ToArray();
}
}
public class Selection
{
public Selection() { }
public Selection(string key, BindOption[] bindOptions)
{
Key = key;
BindOptions = bindOptions;
}
public string Key { get; set; }
public BindOption[] BindOptions { get; set; }
}
public class BindOption
{
public BindOption() { }
public BindOption(string value, string name, SelectOption[] selectOptions)
{
BindValue = value;
DisplayName = name;
SelectOptions = selectOptions;
}
public BindOption(string value, string name, string type, string opt)
{
BindValue = value;
DisplayName = name;
Type = type;
Operator = opt;
}
public BindOption(string value, string name, string type, string opt, SelectOption[] selectOptions)
{
BindValue = value;
DisplayName = name;
Type = type;
Operator = opt;
Values = new string[] { };
SelectOptions = selectOptions;
}
public BindOption(string value, string name, string type, string opt, string defaultValue, string defaultValue1, string[] defaultValues, SelectOption[] selectOptions)
{
BindValue = value;
DisplayName = name;
Type = type;
Operator = opt;
Values = new string[] { };
Value1 = defaultValue1;
Value = defaultValue;
Values = defaultValues;
SelectOptions = selectOptions;
}
public BindOption(string value, string name, string type, string opt, string defaultValue, string defaultValue1, SelectOption[] selectOptions)
{
BindValue = value;
DisplayName = name;
Type = type;
Operator = opt;
Values = new string[] { };
Value1 = defaultValue1;
Value = defaultValue;
SelectOptions = selectOptions;
}
public BindOption(string value, string name, string type, string opt, string[] defaultValues, SelectOption[] selectOptions)
{
BindValue = value;
DisplayName = name;
Type = type;
Operator = opt;
Values = new string[] { };
Values = defaultValues;
SelectOptions = selectOptions;
}
public string DisplayName { get; set; }
public string BindValue { get; set; }
public string Type { get; set; }
public string Operator { get; set; }
public string[] Values { get; set; }
public string Value { get; set; }
public string Value1 { get; set; }
public SelectOption[] SelectOptions { get; set; }
}
public class SelectOption
{
public string DisplayName { get; set; }
public string BindValue { get; set; }
}
public class SearchFilter
{
public SearchFilter() { }
public SearchFilter(string column, string opt, string value)
{
Column = column;
Operator = opt;
Value = value;
}
public string? Column { get; set; }
public string? Type { get; set; }
public string? Operator { get; set; }
public string? Value { get; set; }
public string? Value1 { get; set; }
public string[]? Values { get; set; }
public static string ComposeWhereClause(SearchFilter[] searchFilters)
{
StringBuilder sb = new StringBuilder();
if (searchFilters == null || searchFilters.Length == 0) return null;
foreach (SearchFilter f in searchFilters)
{
if (string.IsNullOrEmpty(f.Value) && !(f.Operator == SearchFilterOperatorPolicy.DATE_BETWEEN || f.Operator == SearchFilterOperatorPolicy.BETWEEN || f.Operator == SearchFilterOperatorPolicy.DATETIME_BETWEEN)) continue;
switch (f.Operator)
{
case SearchFilterOperatorPolicy.EQUAL_TO:
case SearchFilterOperatorPolicy.SINGLE:
sb.Append(string.Format(" and {0} = '{1}' ", f.Column, QuoteString(f.Value)));
break;
case SearchFilterOperatorPolicy.CONTAIN:
sb.Append(string.Format(" and {0} like '%{1}%' ", f.Column, QuoteString(f.Value)));
break;
case SearchFilterOperatorPolicy.START_CONTAIN:
sb.Append(string.Format(" and {0} like '{1}%' ", f.Column, QuoteString(f.Value)));
break;
case SearchFilterOperatorPolicy.END_CONTAIN:
sb.Append(string.Format(" and {0} like '%{1}' ", f.Column, QuoteString(f.Value)));
break;
case SearchFilterOperatorPolicy.CN_CONTAIN:
sb.Append(string.Format(" and {0} like N'%{1}%' ", f.Column, QuoteString(f.Value)));
break;
case SearchFilterOperatorPolicy.CN_START_CONTAIN:
sb.Append(string.Format(" and {0} like N'{1}%' ", f.Column, QuoteString(f.Value)));
break;
case SearchFilterOperatorPolicy.CN_END_CONTAIN:
sb.Append(string.Format(" and {0} like N'%{1}' ", f.Column, QuoteString(f.Value)));
break;
case SearchFilterOperatorPolicy.CN_MULTIPLE:
case SearchFilterOperatorPolicy.CN_IN_RANGE:
sb.Append(string.Format(" and {0} in ({1}) ", f.Column, QuoteStringCNInRange(f.Values)));
break;
case SearchFilterOperatorPolicy.MULTIPLE:
case SearchFilterOperatorPolicy.IN_RANGE:
sb.Append(string.Format(" and {0} in ({1}) ", f.Column, QuoteStringInRange(f.Values)));
break;
case SearchFilterOperatorPolicy.NOT_IN_RANGE:
sb.Append(string.Format(" and {0} not in ({1}) ", f.Column, QuoteStringInRange(f.Values)));
break;
case SearchFilterOperatorPolicy.NUMBER_GREATER_THAN:
sb.Append(string.Format(" and {0} > {1} ", f.Column, QuoteNumber(f.Value)));
break;
case SearchFilterOperatorPolicy.NUMBER_GREATER_THAN_OR_EQUAL_TO:
sb.Append(string.Format(" and {0} >= {1} ", f.Column, QuoteNumber(f.Value)));
break;
case SearchFilterOperatorPolicy.NUMBER_LESS_THAN:
sb.Append(string.Format(" and {0} < {1} ", f.Column, QuoteNumber(f.Value)));
break;
case SearchFilterOperatorPolicy.NUMBER_LESS_THAN_OR_EQUAL_TO:
sb.Append(string.Format(" and {0} <= {1} ", f.Column, QuoteNumber(f.Value)));
break;
case SearchFilterOperatorPolicy.NUMBER_EQUAL_TO:
sb.Append(string.Format(" and {0} = {1} ", f.Column, QuoteNumber(f.Value)));
break;
case SearchFilterOperatorPolicy.BETWEEN:
if (!string.IsNullOrEmpty(f.Value) && !string.IsNullOrEmpty(f.Value1))
sb.Append(string.Format(" and {0} between {1} and {2} ", f.Column, QuoteNumber(f.Value), QuoteNumber(f.Value1)));
if (!string.IsNullOrEmpty(f.Value) && string.IsNullOrEmpty(f.Value1))
sb.Append(string.Format(" and {0} >= {1} ", f.Column, QuoteNumber(f.Value)));
if (string.IsNullOrEmpty(f.Value) && !string.IsNullOrEmpty(f.Value1))
sb.Append(string.Format(" and {0} <= {1} ", f.Column, QuoteNumber(f.Value1)));
break;
case SearchFilterOperatorPolicy.DATE_BETWEEN:
if (!string.IsNullOrEmpty(f.Value) && !string.IsNullOrEmpty(f.Value1))
sb.Append(string.Format(" and {0} between '{1}' and '{2}' ", f.Column, QuoteString(f.Value), Convert.ToDateTime(QuoteString(f.Value1)).AddDays(1).ToString("yyyy-MM-dd")));
if (!string.IsNullOrEmpty(f.Value) && string.IsNullOrEmpty(f.Value1))
sb.Append(string.Format(" and {0} >= '{1}' ", f.Column, QuoteString(f.Value)));
if (string.IsNullOrEmpty(f.Value) && !string.IsNullOrEmpty(f.Value1))
sb.Append(string.Format(" and {0} <= '{1}' ", f.Column, Convert.ToDateTime(QuoteString(f.Value1)).AddDays(1).ToString("yyyy-MM-dd")));
break;
case SearchFilterOperatorPolicy.DATETIME_BETWEEN:
if (!string.IsNullOrEmpty(f.Value) && !string.IsNullOrEmpty(f.Value1))
sb.Append(string.Format(" and {0} between '{1}' and '{2}' ", f.Column, QuoteString(f.Value), Convert.ToDateTime(QuoteString(f.Value1)).AddSeconds(1).ToString("yyyy-MM-dd HH:mm:ss")));
if (!string.IsNullOrEmpty(f.Value) && string.IsNullOrEmpty(f.Value1))
sb.Append(string.Format(" and {0} >= '{1}' ", f.Column, QuoteString(f.Value)));
if (string.IsNullOrEmpty(f.Value) && !string.IsNullOrEmpty(f.Value1))
sb.Append(string.Format(" and {0} <= '{1}' ", f.Column, Convert.ToDateTime(QuoteString(f.Value1)).AddSeconds(1).ToString("yyyy-MM-dd HH:mm:ss")));
break;
case SearchFilterOperatorPolicy.DATE_GREATER_THAN:
sb.Append(string.Format(" and {0} > '{1}' ", f.Column, QuoteString(f.Value)));
break;
case SearchFilterOperatorPolicy.DATE_GREATER_THAN_OR_EQUAL_TO:
sb.Append(string.Format(" and {0} >= '{1}' ", f.Column, QuoteString(f.Value)));
break;
case SearchFilterOperatorPolicy.DATE_LESS_THAN:
sb.Append(string.Format(" and {0} < '{1}' ", f.Column, Convert.ToDateTime(QuoteString(f.Value)).AddDays(1).ToString("yyyy-MM-dd")));
break;
case SearchFilterOperatorPolicy.DATE_LESS_THAN_OR_EQUAL_TO:
sb.Append(string.Format(" and {0} <= '{1}' ", f.Column, QuoteString(f.Value)));
break;
case SearchFilterOperatorPolicy.DATE_EQUAL_TO:
sb.Append(string.Format(" and {0} = '{1}' ", f.Column, QuoteString(f.Value)));
break;
}
}
return sb.ToString();
}
public static string QuoteStringCNInRange(string[] values)
{
if (values == null || values.Length == 0) return string.Empty;
StringBuilder sb = new StringBuilder();
foreach (string v in values)
{
sb.Append(string.Format(" N'{0}', ", QuoteString(v)));
}
return sb.ToString().Substring(0, sb.Length - 2);
}
public static string QuoteStringInRange(string[] values)
{
if (values == null || values.Length == 0) return string.Empty;
StringBuilder sb = new StringBuilder();
foreach (string v in values)
{
sb.Append(string.Format(" '{0}', ", QuoteString(v)));
}
return sb.ToString().Substring(0, sb.Length - 2);
}
public static string QuoteNumber(string s)
{
int i = 0;
if (!int.TryParse(s, out i)) return "0";
return s;
}
public static string QuoteString(string s)
{
if (s == null) s = string.Empty;
return s.Replace("'", "''");// "'" + s.Replace("'", "''") + "'";
}
}
public class GridColumnInfo
{
public string? title { get; set; }
public string? dataIndex { get; set; }
public int sequence { get; set; }
public string? align { get; set; }
public string? hidden { get; set; }
public string? format { get; set; }
}
}
@@ -0,0 +1,19 @@
using CloudBuilder.Core.Authorization;
namespace CloudBuilder.Core.Service
{
[TypeScript]
public class SearchCriteriaResultData
{
public int Limit { get; set; }
public int Page { get; set; }
public int Total { get; set; }
public string? Sql { get; set; }
public string? ErrorMessage { get; set; }
}
}
@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace CloudBuilder.Core.Service
{
public class ServiceErrorException : Exception
{
public string SourceCode { get; set; } = "CloudBuilder.Core.ServiceErrorException";
public new string Message { get; set; } = string.Empty;
/// <summary>
/// 初始化<see cref="CloudBuilder.CoreException"/>类的新实例
/// </summary>
public ServiceErrorException()
{ }
public ServiceErrorException(Exception ex)
: base(ex.Message, ex)
{
Message = ex.Message;
}
/// <summary>
/// 使用指定错误消息初始化<see cref="CloudBuilder.CoreException"/>类的新实例。
/// </summary>
/// <param name="message">描述错误的消息</param>
public ServiceErrorException(string message)
: base(message)
{
Message = message;
}
/// <summary>
/// 使用异常消息与一个内部异常实例化一个<see cref="CloudBuilder.CoreException"/>类的新实例
/// </summary>
/// <param name="message">异常消息</param>
/// <param name="inner">用于封装在<see cref="CloudBuilder.CoreException"/>内部的异常实例</param>
public ServiceErrorException(string message, Exception inner)
: base(message, inner)
{ Message = message; }
/// <summary>
/// 使用可序列化数据实例化一个<see cref="CloudBuilder.CoreException"/>类的新实例
/// </summary>
/// <param name="info">保存序列化对象数据的对象。</param>
/// <param name="context">有关源或目标的上下文信息。</param>
protected ServiceErrorException(SerializationInfo info, StreamingContext context)
: base(info, context)
{ }
}
}
@@ -0,0 +1,53 @@
using CloudBuilder.Core.DependencyInjection.Form;
using Microsoft.Extensions.DependencyInjection;
namespace CloudBuilder
{
public class ServiceHelper
{
//services.TryAddSingleton<ApplicationServiceContext>();
/// <summary>
/// 通过单例获取指定类型的服务
/// </summary>
public static R GetService<R>()
{
return ApplicationServiceContext.ServiceProvider.GetService<R>()!;
}
//services.TryAddSingleton<IContext, LoginContext>();
/// <summary>
/// 通过接口获取指定类型的服务
/// </summary>
public static R GetInterfaceService<R>()
{
return ApplicationServiceContext.ServiceProvider.GetService<R>()!;
}
//services.TryAddKeyedScoped(implementType, implementType.Name);
/// <summary>
/// 通过名称获取指定类型的服务
/// </summary>
public static R GetTypeService<R>()
{
return ApplicationServiceContext.ServiceProvider.GetRequiredKeyedService<R>(typeof(R).Name);
}
//services.TryAddKeyedScoped(implementType.BaseType, implementType.Name, implementType);
/// <summary>
/// 通过名称获取指定类型(被继承的类)的服务
/// </summary>
public static R GetBaseTypeService<R>(string name)
{
return ApplicationServiceContext.ServiceProvider.GetRequiredKeyedService<R>(name);
}
public static R GetBaseTypeScopeService<R>(string name)
{
using (var scope = ApplicationServiceContext.ServiceProvider.CreateScope())
{
return scope.ServiceProvider.GetRequiredKeyedService<R>(name);
}
}
}
}
@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace CloudBuilder.Core.Service
{
public class ValidatedException : Exception
{
public string SourceCode { get; set; } = "CloudBuilder.Core.ValidatedException";
public new string Message { get; set; } = string.Empty;
/// <summary>
/// 初始化<see cref="CloudBuilder.CoreException"/>类的新实例
/// </summary>
public ValidatedException()
{ }
/// <summary>
/// 使用指定错误消息初始化<see cref="CloudBuilder.CoreException"/>类的新实例。
/// </summary>
/// <param name="message">描述错误的消息</param>
public ValidatedException(string message)
: base(message)
{
Message = message;
}
/// <summary>
/// 使用异常消息与一个内部异常实例化一个<see cref="CloudBuilder.CoreException"/>类的新实例
/// </summary>
/// <param name="message">异常消息</param>
/// <param name="inner">用于封装在<see cref="CloudBuilder.CoreException"/>内部的异常实例</param>
public ValidatedException(string message, Exception inner)
: base(message, inner)
{
Message = message;
}
/// <summary>
/// 使用可序列化数据实例化一个<see cref="CloudBuilder.CoreException"/>类的新实例
/// </summary>
/// <param name="info">保存序列化对象数据的对象。</param>
/// <param name="context">有关源或目标的上下文信息。</param>
protected ValidatedException(SerializationInfo info, StreamingContext context)
: base(info, context)
{ }
}
}