///////////////////////////////////////////////////////////////////////////////// // 宁波拓通e智造平台 ToTong Next Builder // // https://git.tuotong-tech.com/tnb/tnb.server // ///////////////////////////////////////////////////////////////////////////////// using JNPF.Common.Core.Manager; using JNPF.Common.Extension; using Mapster; using Newtonsoft.Json.Linq; using SqlSugar; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Reflection; using Tnb.Core; using Yitter.IdGenerator; namespace Tnb.Vengine.Domain; /// /// 视图模型 /// [SugarTable("sys_vmodel")] public partial class Vmodel : Entity { #region Properties /// /// 主键标识 /// [SugarColumn(IsPrimaryKey = true)] public string id { get; set; } = YitIdHelper.NextId().ToString(); /// /// 模块代码 /// [SugarColumn(ColumnName = "area_code", Length = DbConsts.LengthS)] public string areaCode { get; set; } = "edp"; /// /// 视图代码 /// [SugarColumn(ColumnName = "vm_code", IsNullable = false, Length = DbConsts.LengthM)] public string vmCode { get; set; } = string.Empty; /// /// 视图名称 /// [SugarColumn(ColumnName = "vm_name", IsNullable = false, Length = DbConsts.LengthM)] public string vmName { get; set; } = string.Empty; /// /// 数据库连接 /// [SugarColumn(ColumnName = "db_code", Length = DbConsts.LengthS)] public string? dbCode { get; set; } /// /// 主表名称 /// [SugarColumn(ColumnName = "table_name", IsNullable = false, Length = DbConsts.LengthS)] public string tableName { get; set; } = string.Empty; /// /// 表字段属性 /// [SugarColumn(ColumnName = "db_props", IsNullable = false, IsJson = true)] public List dbProps { get; set; } = new List(); /// /// 导航属性 /// [SugarColumn(ColumnName = "nav_props", IsNullable = true, IsJson = true)] public List navProps { get; set; } = new List(); /// /// 计算属性 /// [SugarColumn(ColumnName = "cal_props", IsNullable = true, IsJson = true)] public List calProps { get; set; } = new List(); /// /// 排序 /// [SugarColumn(ColumnName = "ordinal", IsNullable = false)] public int ordinal { get; set; } /// /// 软删除 /// [SugarColumn(ColumnName = "soft_delete", IsNullable = false)] public short softDelete { get; set; } /// /// 是否激活 /// [SugarColumn(ColumnName = "enabled", IsNullable = false)] public short enabled { get; set; } = 1; /// /// 是否删除 /// [SugarColumn(ColumnName = "deleted", IsNullable = false)] public short deleted { get; set; } /// /// 描述 /// [SugarColumn(ColumnName = "descrip", Length = DbConsts.LengthL)] public string? descrip { get; set; } /// /// 创建时间 /// [SugarColumn(ColumnName = "create_time", IsNullable = false)] public DateTime createTime { get; set; } = DateTime.Now; /// /// 创建人 /// [SugarColumn(ColumnName = "create_id", Length = DbConsts.LengthS)] public string? createId { get; set; } /// /// 修改时间 /// [SugarColumn(ColumnName = "modify_time", Length = DbConsts.LengthS)] public DateTime? modifyTime { get; set; } /// /// 修改人 /// [SugarColumn(ColumnName = "modify_id", Length = DbConsts.LengthS)] public string? modifyId { get; set; } [SugarColumn(IsIgnore = true)] public string fullCode { get { return areaCode + "/" + vmCode; } } /// /// 主键 /// public override object[] GetKeys() { return new object[] { id }; } #endregion /// /// 通过实体创建模型 /// /// /// /// public static Vmodel CreateByEntity(Type tpEntity, string? dbCode = null) { Vmodel model = new() { dbCode = dbCode, vmCode = tpEntity.Name }; var sugarTableAttr = tpEntity.GetCustomAttribute(); if (sugarTableAttr != null) { model.tableName = sugarTableAttr.TableName; model.vmName = sugarTableAttr.TableDescription; } if (string.IsNullOrEmpty(model.tableName)) { model.tableName = tpEntity.GetCustomAttribute()?.Name ?? tpEntity.Name; } if (string.IsNullOrEmpty(model.vmName)) { model.vmName = tpEntity.GetCustomAttribute()?.Name ?? tpEntity.GetCustomAttribute()?.Description ?? model.vmCode; } var props = tpEntity.GetProperties(BindingFlags.Public); int n = 1; foreach (var p in props) { VmDbProp prop = new(); var sugarColumn = p.GetCustomAttribute(); if (sugarColumn != null) { prop = sugarColumn.Adapt(); } prop.code = p.Name; prop.ordinal = n++; model.dbProps.Add(prop); } return model; } /// /// 获取模型的主键字段属性 /// /// public VmDbProp GetPrimary() { return dbProps.First(a => a.pkey); } /// /// 根据属性名获取字段名 /// /// /// public string? PropCodeToFieldCode(string propCode) { return dbProps.Where(a => a.code == propCode).Select(a => a.field).FirstOrDefault(); } /// /// 根据字段名获取属性名 /// /// /// public string? FieldCodeToPropCode(string fieldCode) { return dbProps.Where(a => a.field == fieldCode).Select(a => a.code).FirstOrDefault(); } /// /// 属性代码转换为字段代码 /// /// /// /// public DObject PropToField(DObject input, bool ignoreNotMapped = true) { DObject ret = new(); foreach (var item in input) { var fcode = PropCodeToFieldCode(item.Key); if (!string.IsNullOrEmpty(fcode)) { ret.Add(fcode, item.Value); } else if (!ignoreNotMapped) { ret.Add(item.Key, item.Value); } } return ret; } /// /// 字段代码转换为属性代码 /// /// /// /// public DObject FieldToProp(DObject input, bool ignoreNotMapped = true) { DObject ret = new(); foreach (var item in input) { var pcode = FieldCodeToPropCode(item.Key); if (!string.IsNullOrEmpty(pcode)) { ret.Add(pcode, item.Value); } else if (!ignoreNotMapped) { ret.Add(item.Key, item.Value); } } return ret; } /// /// 获取查询字段的属性信息 /// /// /// public List GetVmSelectProps(string? outputProps) { if (string.IsNullOrEmpty(outputProps) || outputProps == "*") { return dbProps.Select(a => new VmSelectProp { code = a.code, field = a.field }).ToList(); } List selProps = new(); var outputs = outputProps.Split(',').Distinct().ToList(); foreach (var propCode in outputs) { if (!propCode.Contains(".")) { var fieldCode = PropCodeToFieldCode(propCode); if (!string.IsNullOrEmpty(fieldCode)) { selProps.Add(new VmSelectProp { code = propCode, field = fieldCode }); } continue; } var codes = propCode.Split('.'); if (codes.Length != 2) continue; if (codes[0] == VmSelectProp.MAIN_ALIES) { var fieldCode = PropCodeToFieldCode(propCode); if (!string.IsNullOrEmpty(fieldCode)) { selProps.Add(new VmSelectProp { code = propCode, field = fieldCode }); } continue; } var navProp = navProps.FirstOrDefault(a => a.code == codes[0]); if (navProp?.naviModel != null) { var fieldCode = navProp.naviModel.PropCodeToFieldCode(codes[1]); if (!string.IsNullOrEmpty(fieldCode)) { selProps.Add(new VmSelectProp { code = codes[1], field = fieldCode, navCode = codes[0], propType = ePropType.Navigate, navType = navProp.navType }); } } } return selProps; } /// /// 获取联表配置信息 /// /// /// public List GetJoinInfos(List selProps) { var navigates = selProps.Where(a => a.propType == ePropType.Navigate).Select(a => a.navCode).Distinct().ToList(); List joins = new(); foreach (var navCode in navigates) { if (navCode == VmSelectProp.MAIN_ALIES) continue; var navProp = navProps.First(a => a.code == navCode); if (navProp.naviModel == null || navProp.navType != eNavigateType.OneToOne) continue; JoinInfoParameter join = new JoinInfoParameter { TableName = navProp.naviModel.tableName, ShortName = navCode, Type = JoinType.Inner }; var fkField = navProp.naviModel.PropCodeToFieldCode(navProp.fkField); var refField = navProp.refField; if (navProp.refCode != VmSelectProp.MAIN_ALIES) { var refProp = navProps.First(a => a.code == navProp.refCode); refField = refProp.naviModel!.PropCodeToFieldCode(navProp.refField); } join.Models = ObjectFuncModel.Create("Equals", $"{navCode}.{fkField}", $"{navProp.refCode}.{refField}"); joins.Add(join); } return joins; } /// /// 转换为查询过滤条件 /// /// /// public List GetConditionalModels(DObject? filter) { List wheres = new List(); if (filter == null) return wheres; foreach (var item in filter) { // TODO 按子表条件查询 if (item.Key.Contains(".")) { } var prop = dbProps.FirstOrDefault(a => a.code == item.Key); if (prop == null) continue; if (item.Value is JArray val) { var op = val[0].ToString(); switch (op) { case "><": wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val[1].ToString(), ConditionalType = ConditionalType.GreaterThan, CSharpTypeName = prop.csType }); wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val[2].ToString(), ConditionalType = ConditionalType.LessThan, CSharpTypeName = prop.csType }); break; case ">=<": wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val[1].ToString(), ConditionalType = ConditionalType.GreaterThanOrEqual, CSharpTypeName = prop.csType }); wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val[2].ToString(), ConditionalType = ConditionalType.LessThan, CSharpTypeName = prop.csType }); break; case "><=": wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val[1].ToString(), ConditionalType = ConditionalType.GreaterThan, CSharpTypeName = prop.csType }); wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val[2].ToString(), ConditionalType = ConditionalType.LessThanOrEqual, CSharpTypeName = prop.csType }); break; case ">=<=": wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val[1].ToString(), ConditionalType = ConditionalType.GreaterThanOrEqual, CSharpTypeName = prop.csType }); wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val[2].ToString(), ConditionalType = ConditionalType.LessThanOrEqual, CSharpTypeName = prop.csType }); break; case "in": wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val.Skip(1).ToString(), ConditionalType = ConditionalType.In, CSharpTypeName = prop.csType }); break; default: op = string.Empty; break; } } else { //if (item.Value == null) continue; var conditionalType = ConditionalType.Equal; string? value = item.Value?.ToString(); if (string.IsNullOrEmpty(value)) continue; if (value.Length >= 2) { var op = value.Substring(0, 2); switch (op) { case "%%": conditionalType = ConditionalType.Like; break; case ">>": conditionalType = ConditionalType.GreaterThan; break; case "<<": conditionalType = ConditionalType.LessThan; break; case ">=": conditionalType = ConditionalType.GreaterThanOrEqual; break; case "<=": conditionalType = ConditionalType.LessThanOrEqual; break; case "==": conditionalType = ConditionalType.Equal; break; default: op = string.Empty; break; } if (!string.IsNullOrEmpty(op)) { value = value.RemovePreFix(op); if (value.ToLower() == "null") { value = null; } } } wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = value, ConditionalType = conditionalType, CSharpTypeName = prop.csType }); } } return wheres; } /// /// 转换为查询字段列表 /// /// /// public List GetSelectModels(List selProps) { return selProps.Where(a => a.navType != eNavigateType.OneToMany && a.navType != eNavigateType.ManyToMany).Select(a => new SelectModel { FiledName = (a.navCode == VmSelectProp.MAIN_ALIES ? "" : a.navCode + ".") + a.field, AsName = (a.navCode == VmSelectProp.MAIN_ALIES ? "" : a.navCode + "_") + a.code }).ToList(); } /// /// 获取默认对象 /// /// public DObject GetDefaultDObject() { DObject obj = new(); foreach (var p in dbProps) { obj.Add(p.code, p.GetDefaultValue()!); } return obj; } /// /// 转换为待新增的实体对象 /// /// public DObject ToCreateEntity(DObject input, IUserManager user) { DObject obj = new(); foreach (var p in dbProps) { if (input.ContainsKey(p.code)) { obj.Add(p.field, input[p.code]); } //当提交的数据与内置规则有重复时,采用内置规则,如果要优先采用提交的数据,这里要使用else if if ((p.pkey && p.code == "id") || p.defValue == "@snowid") { obj[p.field] = YitIdHelper.NextId().ToString(); } else if (p.csType == "DateTime" && (p.code == "createTime" || p.defValue == "@createTime")) { obj[p.field] = DateTime.Now; } else if (p.csType == "string" && (p.code == "createId" || p.defValue == "@createId")) { obj[p.field] = user.UserId; } else if (obj.GetOrDefault(p.field) == null && (p.required || !string.IsNullOrEmpty(p.defValue))) { obj[p.field] = p.GetDefaultValue()!; } } return obj; } /// /// 转换为待修改的实体对象 /// /// public DObject ToUpdateEntity(DObject input, IUserManager user) { DObject obj = new(); foreach (var p in dbProps) { if (input.ContainsKey(p.code)) { obj.Add(p.field, input[p.code]); } //当提交的数据与内置规则有重复时,采用内置规则,如果要优先采用提交的数据,这里要使用else if if (p.csType == "DateTime" && (p.code == "updateTime" || p.code == "modifyTime" || p.defValue == "@updateTime")) { obj[p.field] = DateTime.Now; } else if (p.csType == "string" && (p.code == "updateId" || p.code == "modifyId" || p.defValue == "@updateId")) { obj[p.field] = user.UserId; } } return obj; } }