mirror of
https://github.com/nsnail/NetAdmin.git
synced 2025-08-01 01:36:00 +08:00
@ -116,7 +116,7 @@ USDT
|
||||
登录名
|
||||
登录日志导出
|
||||
硕士
|
||||
示例导出
|
||||
代码模板导出
|
||||
离异
|
||||
空闲
|
||||
站内信导出
|
||||
|
@ -0,0 +1 @@
|
||||
示例导出
|
16
assets/seed-data/Sys_CodeTemplate.json
Normal file
16
assets/seed-data/Sys_CodeTemplate.json
Normal file
@ -0,0 +1,16 @@
|
||||
[
|
||||
{
|
||||
"Enabled": true,
|
||||
"Gender": 1,
|
||||
"Id": 694360665923594,
|
||||
"Name": "老王",
|
||||
"Sort": 100,
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Gender": 2,
|
||||
"Id": 694360665923595,
|
||||
"Name": "媳妇儿",
|
||||
"Sort": 100,
|
||||
}
|
||||
]
|
@ -278,13 +278,24 @@
|
||||
"Title": "代码生成",
|
||||
"Type": 1
|
||||
},
|
||||
{
|
||||
"Component": "sys/template",
|
||||
"Icon": "sc-icon-template",
|
||||
"Id": 694076641718288,
|
||||
"Name": "dev/template",
|
||||
"ParentId": 373838105399301,
|
||||
"Path": "/dev/template",
|
||||
"Sort": 99,
|
||||
"Title": "页面模板",
|
||||
"Type": 1
|
||||
},
|
||||
{
|
||||
"Id": 482777529417739,
|
||||
"ParentId": 373838105399301,
|
||||
"Icon": "el-icon-eleme-filled",
|
||||
"Name": "dev/element",
|
||||
"Path": "https://element-plus.org/zh-CN/component/overview.html",
|
||||
"Sort": 99,
|
||||
"Sort": 98,
|
||||
"Title": "Element",
|
||||
"Type": 3,
|
||||
},
|
||||
@ -294,7 +305,7 @@
|
||||
"Icon": "sc-icon-free-sql",
|
||||
"Name": "dev/freesql",
|
||||
"Path": "https://freesql.net/guide",
|
||||
"Sort": 99,
|
||||
"Sort": 97,
|
||||
"Title": "FreeSql",
|
||||
"Type": 3,
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Tpl.Example;
|
||||
|
||||
namespace NetAdmin.Application.Modules.Tpl;
|
||||
|
||||
/// <summary>
|
||||
/// 示例模块
|
||||
/// </summary>
|
||||
public interface IExampleModule : ICrudModule<CreateExampleReq, QueryExampleRsp // 创建类型
|
||||
, EditExampleReq // 编辑类型
|
||||
, QueryExampleReq, QueryExampleRsp // 查询类型
|
||||
, DelReq // 删除类型
|
||||
>;
|
@ -1,8 +0,0 @@
|
||||
using NetAdmin.Application.Modules.Tpl;
|
||||
|
||||
namespace NetAdmin.Application.Services.Tpl.Dependency;
|
||||
|
||||
/// <summary>
|
||||
/// 示例服务
|
||||
/// </summary>
|
||||
public interface IExampleService : IService, IExampleModule;
|
@ -1,9 +0,0 @@
|
||||
using NetAdmin.Application.Modules.Tpl;
|
||||
using NetAdmin.Application.Services.Tpl.Dependency;
|
||||
|
||||
namespace NetAdmin.Cache.Tpl.Dependency;
|
||||
|
||||
/// <summary>
|
||||
/// 示例缓存
|
||||
/// </summary>
|
||||
public interface IExampleCache : ICache<IDistributedCache, IExampleService>, IExampleModule;
|
@ -1,71 +0,0 @@
|
||||
using NetAdmin.Application.Services.Tpl.Dependency;
|
||||
using NetAdmin.Cache.Tpl.Dependency;
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Tpl.Example;
|
||||
|
||||
namespace NetAdmin.Cache.Tpl;
|
||||
|
||||
/// <inheritdoc cref="IExampleCache" />
|
||||
public sealed class ExampleCache(IDistributedCache cache, IExampleService service)
|
||||
: DistributedCache<IExampleService>(cache, service), IScoped, IExampleCache
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
|
||||
{
|
||||
return Service.BulkDeleteAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<long> CountAsync(QueryReq<QueryExampleReq> req)
|
||||
{
|
||||
return Service.CountAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<IOrderedEnumerable<KeyValuePair<IImmutableDictionary<string, string>, int>>> CountByAsync(QueryReq<QueryExampleReq> req)
|
||||
{
|
||||
return Service.CountByAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<QueryExampleRsp> CreateAsync(CreateExampleReq req)
|
||||
{
|
||||
return Service.CreateAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<int> DeleteAsync(DelReq req)
|
||||
{
|
||||
return Service.DeleteAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<QueryExampleRsp> EditAsync(EditExampleReq req)
|
||||
{
|
||||
return Service.EditAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<IActionResult> ExportAsync(QueryReq<QueryExampleReq> req)
|
||||
{
|
||||
return Service.ExportAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<QueryExampleRsp> GetAsync(QueryExampleReq req)
|
||||
{
|
||||
return Service.GetAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<PagedQueryRsp<QueryExampleRsp>> PagedQueryAsync(PagedQueryReq<QueryExampleReq> req)
|
||||
{
|
||||
return Service.PagedQueryAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<IEnumerable<QueryExampleRsp>> QueryAsync(QueryReq<QueryExampleReq> req)
|
||||
{
|
||||
return Service.QueryAsync(req);
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
namespace NetAdmin.Domain.DbMaps.Sys;
|
||||
|
||||
/// <summary>
|
||||
/// 代码模板表
|
||||
/// </summary>
|
||||
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_CodeTemplate))]
|
||||
public record Sys_CodeTemplate : VersionEntity, IFieldSort, IFieldSummary, IFieldEnabled, IFieldOwner
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否启用
|
||||
/// </summary>
|
||||
/// <example>true</example>
|
||||
[Column]
|
||||
[CsvIgnore]
|
||||
[JsonIgnore]
|
||||
public virtual bool Enabled { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 性别
|
||||
/// </summary>
|
||||
/// <example>Male</example>
|
||||
[Column]
|
||||
[CsvIgnore]
|
||||
[JsonIgnore]
|
||||
public virtual Genders? Gender { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 唯一编码
|
||||
/// </summary>
|
||||
/// <example>123456</example>
|
||||
[Column(IsIdentity = false, IsPrimary = true, Position = 1)]
|
||||
[CsvIgnore]
|
||||
[JsonIgnore]
|
||||
[Snowflake]
|
||||
public override long Id { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
/// <example>老王</example>
|
||||
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
|
||||
[CsvIgnore]
|
||||
[JsonIgnore]
|
||||
public virtual string Name { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 归属用户
|
||||
/// </summary>
|
||||
[CsvIgnore]
|
||||
[JsonIgnore]
|
||||
[Navigate(nameof(OwnerId))]
|
||||
public Sys_User Owner { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 归属部门编号
|
||||
/// </summary>
|
||||
/// <example>370942943322181</example>
|
||||
[Column]
|
||||
[CsvIgnore]
|
||||
[JsonIgnore]
|
||||
public virtual long? OwnerDeptId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 归属用户编号
|
||||
/// </summary>
|
||||
/// <example>370942943322181</example>
|
||||
[Column]
|
||||
[CsvIgnore]
|
||||
[JsonIgnore]
|
||||
public virtual long? OwnerId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序值,越大越前
|
||||
/// </summary>
|
||||
/// <example>100</example>
|
||||
[Column]
|
||||
[CsvIgnore]
|
||||
[JsonIgnore]
|
||||
public virtual long Sort { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
/// <example>备注文字</example>
|
||||
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
|
||||
[CsvIgnore]
|
||||
[JsonIgnore]
|
||||
public virtual string Summary { get; init; }
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
namespace NetAdmin.Domain.DbMaps.Tpl;
|
||||
|
||||
/// <summary>
|
||||
/// 示例表
|
||||
/// </summary>
|
||||
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Tpl_Example))]
|
||||
public record Tpl_Example : VersionEntity;
|
@ -0,0 +1,30 @@
|
||||
namespace NetAdmin.Domain.Dto.Sys.CodeTemplate;
|
||||
|
||||
/// <summary>
|
||||
/// 请求:创建代码模板
|
||||
/// </summary>
|
||||
public record CreateCodeTemplateReq : Sys_CodeTemplate
|
||||
{
|
||||
/// <inheritdoc cref="IFieldEnabled.Enabled" />
|
||||
public override bool Enabled { get; init; } = true;
|
||||
|
||||
/// <inheritdoc cref="Sys_CodeTemplate.Gender" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override Genders? Gender { get; init; }
|
||||
|
||||
/// <inheritdoc cref="Sys_CodeTemplate.Id" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override long Id { get; init; }
|
||||
|
||||
/// <inheritdoc cref="Sys_CodeTemplate.Name" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public override string Name { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldSort.Sort" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override long Sort { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldSummary.Summary" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public override string Summary { get; init; }
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
namespace NetAdmin.Domain.Dto.Sys.CodeTemplate;
|
||||
|
||||
/// <summary>
|
||||
/// 请求:编辑代码模板
|
||||
/// </summary>
|
||||
public sealed record EditCodeTemplateReq : CreateCodeTemplateReq
|
||||
{
|
||||
/// <inheritdoc cref="IFieldVersion.Version" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override long Version { get; init; }
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
namespace NetAdmin.Domain.Dto.Sys.CodeTemplate;
|
||||
|
||||
/// <summary>
|
||||
/// 请求:查询代码模板
|
||||
/// </summary>
|
||||
public sealed record QueryCodeTemplateReq : Sys_CodeTemplate
|
||||
{
|
||||
/// <inheritdoc cref="Sys_CodeTemplate.Id" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override long Id { get; init; }
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
using NetAdmin.Domain.Dto.Sys.User;
|
||||
|
||||
namespace NetAdmin.Domain.Dto.Sys.CodeTemplate;
|
||||
|
||||
/// <summary>
|
||||
/// 响应:查询代码模板
|
||||
/// </summary>
|
||||
public record QueryCodeTemplateRsp : Sys_CodeTemplate
|
||||
{
|
||||
/// <inheritdoc cref="IFieldCreatedTime.CreatedTime" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override DateTime CreatedTime { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldCreatedUser.CreatedUserId" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public override long? CreatedUserId { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldCreatedUser.CreatedUserName" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public override string CreatedUserName { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldEnabled.Enabled" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override bool Enabled { get; init; }
|
||||
|
||||
/// <inheritdoc cref="Sys_CodeTemplate.Gender" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override Genders? Gender { get; init; }
|
||||
|
||||
/// <inheritdoc cref="Sys_CodeTemplate.Id" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override long Id { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldModifiedTime.ModifiedTime" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public override DateTime? ModifiedTime { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldModifiedUser.ModifiedUserId" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public override long? ModifiedUserId { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldModifiedUser.ModifiedUserName" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public override string ModifiedUserName { get; init; }
|
||||
|
||||
/// <inheritdoc cref="Sys_CodeTemplate.Name" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public override string Name { get; init; }
|
||||
|
||||
/// <inheritdoc cref="Sys_CodeTemplate.Owner" />
|
||||
public new virtual QueryUserRsp Owner { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldOwner.OwnerDeptId" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public override long? OwnerDeptId { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldOwner.OwnerId" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public override long? OwnerId { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldSort.Sort" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override long Sort { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldSummary.Summary" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public override string Summary { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldVersion.Version" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override long Version { get; init; }
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
namespace NetAdmin.Domain.Dto.Sys.Dev;
|
||||
|
||||
/// <summary>
|
||||
/// 信息:字段项信息
|
||||
/// </summary>
|
||||
public sealed record FieldItemInfo : DataAbstraction
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据库字段类型
|
||||
/// </summary>
|
||||
public string DbType { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 代码模板
|
||||
/// </summary>
|
||||
public string Example { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 可空
|
||||
/// </summary>
|
||||
public bool IsNullable { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否主键
|
||||
/// </summary>
|
||||
public bool IsPrimary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 值类型
|
||||
/// </summary>
|
||||
public bool IsStruct { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Summary { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型
|
||||
/// </summary>
|
||||
public string Type { get; init; }
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
namespace NetAdmin.Domain.Dto.Sys.Dev;
|
||||
namespace NetAdmin.Domain.Dto.Sys.Dev;
|
||||
|
||||
/// <summary>
|
||||
/// 请求:生成后端代码
|
||||
@ -6,20 +6,32 @@ namespace NetAdmin.Domain.Dto.Sys.Dev;
|
||||
public sealed record GenerateCsCodeReq : DataAbstraction
|
||||
{
|
||||
/// <summary>
|
||||
/// 模块名称
|
||||
/// 基类
|
||||
/// </summary>
|
||||
[Required(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.模块名称不能为空))]
|
||||
public string ModuleName { get; init; }
|
||||
public string BaseClass { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 模块说明
|
||||
/// 实体名称
|
||||
/// </summary>
|
||||
[Required(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.模块说明不能为空))]
|
||||
public string ModuleRemark { get; init; }
|
||||
public string EntityName { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 模块类型
|
||||
/// 字段列表
|
||||
/// </summary>
|
||||
[Required(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.模块类型不能为空))]
|
||||
public string Type { get; init; }
|
||||
public IReadOnlyCollection<FieldItemInfo> FieldList { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 接口列表
|
||||
/// </summary>
|
||||
public string[] Interfaces { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 项目
|
||||
/// </summary>
|
||||
public string Project { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 描述
|
||||
/// </summary>
|
||||
public string Summary { get; init; }
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
namespace NetAdmin.Domain.Dto.Sys.Dev;
|
||||
|
||||
/// <summary>
|
||||
/// 请求:获取所有数据类型
|
||||
/// </summary>
|
||||
public sealed record GetDotnetDataTypesReq : DataAbstraction
|
||||
{
|
||||
/// <summary>
|
||||
/// 开始匹配
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string StartWith { get; init; }
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
using NetAdmin.Domain.DbMaps.Tpl;
|
||||
|
||||
namespace NetAdmin.Domain.Dto.Tpl.Example;
|
||||
|
||||
/// <summary>
|
||||
/// 请求:创建示例
|
||||
/// </summary>
|
||||
public record CreateExampleReq : Tpl_Example;
|
@ -1,15 +0,0 @@
|
||||
namespace NetAdmin.Domain.Dto.Tpl.Example;
|
||||
|
||||
/// <summary>
|
||||
/// 请求:编辑示例
|
||||
/// </summary>
|
||||
public record EditExampleReq : CreateExampleReq
|
||||
{
|
||||
/// <inheritdoc cref="EntityBase{T}.Id" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override long Id { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldVersion.Version" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override long Version { get; init; }
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
using NetAdmin.Domain.DbMaps.Tpl;
|
||||
|
||||
namespace NetAdmin.Domain.Dto.Tpl.Example;
|
||||
|
||||
/// <summary>
|
||||
/// 请求:查询示例
|
||||
/// </summary>
|
||||
public sealed record QueryExampleReq : Tpl_Example
|
||||
{
|
||||
/// <inheritdoc cref="EntityBase{T}.Id" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override long Id { get; init; }
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
using NetAdmin.Domain.DbMaps.Tpl;
|
||||
|
||||
namespace NetAdmin.Domain.Dto.Tpl.Example;
|
||||
|
||||
/// <summary>
|
||||
/// 响应:查询示例
|
||||
/// </summary>
|
||||
public sealed record QueryExampleRsp : Tpl_Example
|
||||
{
|
||||
/// <inheritdoc cref="EntityBase{T}.Id" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override long Id { get; init; }
|
||||
|
||||
/// <inheritdoc cref="IFieldVersion.Version" />
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public override long Version { get; init; }
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
<ProjectReference Include="../NetAdmin.Infrastructure/NetAdmin.Infrastructure.csproj"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CronExpressionDescriptor" Version="2.41.0"/>
|
||||
<PackageReference Include="CronExpressionDescriptor" Version="2.44.0"/>
|
||||
<PackageReference Include="Cronos" Version="0.11.0"/>
|
||||
<PackageReference Include="NetAdmin.CsvHelper" Version="1.0.0"/>
|
||||
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14"/>
|
||||
|
@ -1,102 +0,0 @@
|
||||
using NetAdmin.Application.Modules.Tpl;
|
||||
using NetAdmin.Application.Services.Tpl.Dependency;
|
||||
using NetAdmin.Cache.Tpl.Dependency;
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Tpl.Example;
|
||||
using NetAdmin.Host.Attributes;
|
||||
|
||||
namespace NetAdmin.Host.Controllers.Tpl;
|
||||
|
||||
/// <summary>
|
||||
/// 示例服务
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings(nameof(Tpl), Module = nameof(Tpl))]
|
||||
[Produces(Chars.FLG_HTTP_HEADER_VALUE_APPLICATION_JSON)]
|
||||
public sealed class ExampleController(IExampleCache cache) : ControllerBase<IExampleCache, IExampleService>(cache), IExampleModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 批量删除示例
|
||||
/// </summary>
|
||||
[Transaction]
|
||||
public Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
|
||||
{
|
||||
return Cache.BulkDeleteAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 示例计数
|
||||
/// </summary>
|
||||
public Task<long> CountAsync(QueryReq<QueryExampleReq> req)
|
||||
{
|
||||
return Cache.CountAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 示例分组计数
|
||||
/// </summary>
|
||||
public Task<IOrderedEnumerable<KeyValuePair<IImmutableDictionary<string, string>, int>>> CountByAsync(QueryReq<QueryExampleReq> req)
|
||||
{
|
||||
return Cache.CountByAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建示例
|
||||
/// </summary>
|
||||
[Transaction]
|
||||
public Task<QueryExampleRsp> CreateAsync(CreateExampleReq req)
|
||||
{
|
||||
return Cache.CreateAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除示例
|
||||
/// </summary>
|
||||
[Transaction]
|
||||
public Task<int> DeleteAsync(DelReq req)
|
||||
{
|
||||
return Cache.DeleteAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑示例
|
||||
/// </summary>
|
||||
[Transaction]
|
||||
public Task<QueryExampleRsp> EditAsync(EditExampleReq req)
|
||||
{
|
||||
return Cache.EditAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导出示例
|
||||
/// </summary>
|
||||
[NonAction]
|
||||
public Task<IActionResult> ExportAsync(QueryReq<QueryExampleReq> req)
|
||||
{
|
||||
return Cache.ExportAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取单个示例
|
||||
/// </summary>
|
||||
public Task<QueryExampleRsp> GetAsync(QueryExampleReq req)
|
||||
{
|
||||
return Cache.GetAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询示例
|
||||
/// </summary>
|
||||
public Task<PagedQueryRsp<QueryExampleRsp>> PagedQueryAsync(PagedQueryReq<QueryExampleReq> req)
|
||||
{
|
||||
return Cache.PagedQueryAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询示例
|
||||
/// </summary>
|
||||
[NonAction]
|
||||
public Task<IEnumerable<QueryExampleRsp>> QueryAsync(QueryReq<QueryExampleReq> req)
|
||||
{
|
||||
return Cache.QueryAsync(req);
|
||||
}
|
||||
}
|
@ -45,8 +45,7 @@ public abstract class ApiResultHandler<T>
|
||||
/// <summary>
|
||||
/// HTTP状态码处理
|
||||
/// </summary>
|
||||
#pragma warning disable ASA001, VSTHRD200
|
||||
public Task OnResponseStatusCodes( //
|
||||
public Task OnResponseStatusCodesAsync( //
|
||||
HttpContext context, int statusCode, UnifyResultSettingsOptions unifyResultSettings = null)
|
||||
{
|
||||
// 设置响应状态码
|
||||
@ -54,8 +53,6 @@ public abstract class ApiResultHandler<T>
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
#pragma warning restore ASA001, VSTHRD200
|
||||
|
||||
/// <summary>
|
||||
/// 请求成功
|
||||
/// </summary>
|
||||
|
@ -5,7 +5,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NetAdmin.ApiSkin" Condition="'$(Configuration)' == 'Debug'" Version="1.0.1"/>
|
||||
<PackageReference Include="NetAdmin.Spectre.Console.Cli" Version="1.0.1"/>
|
||||
<PackageReference Include="NetAdmin.Spectre.Console.Cli" Version="1.0.3"/>
|
||||
<PackageReference Include="prometheus-net.AspNetCore" Condition="'$(Configuration)' != 'Debug'" Version="8.2.1"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -5,7 +5,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NetAdmin.FreeSql.DbContext" Version="1.1.7" Label="refs"/>
|
||||
<PackageReference Include="NetAdmin.FreeSql.Provider.Sqlite" Version="1.1.7" Label="refs"/>
|
||||
<PackageReference Include="Gurion" Version="1.2.15" Label="refs"/>
|
||||
<PackageReference Include="Gurion" Version="1.2.16" Label="refs"/>
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.6"/>
|
||||
<PackageReference Include="Minio" Version="6.0.5"/>
|
||||
<PackageReference Include="NSExt" Version="2.3.7"/>
|
||||
|
@ -0,0 +1,12 @@
|
||||
using NetAdmin.Domain.Dto.Sys.CodeTemplate;
|
||||
|
||||
namespace NetAdmin.SysComponent.Application.Modules.Sys;
|
||||
|
||||
/// <summary>
|
||||
/// 代码模板模块
|
||||
/// </summary>
|
||||
public interface ICodeTemplateModule : ICrudModule<CreateCodeTemplateReq, QueryCodeTemplateRsp // 创建类型
|
||||
, EditCodeTemplateReq // 编辑类型
|
||||
, QueryCodeTemplateReq, QueryCodeTemplateRsp // 查询类型
|
||||
, DelReq // 删除类型
|
||||
>;
|
@ -21,4 +21,24 @@ public interface IDevModule
|
||||
/// 生成接口代码
|
||||
/// </summary>
|
||||
Task GenerateJsCodeAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 获取实体项目列表
|
||||
/// </summary>
|
||||
Task<IEnumerable<Tuple<string, string>>> GetDomainProjectsAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有数据类型
|
||||
/// </summary>
|
||||
IEnumerable<string> GetDotnetDataTypes(GetDotnetDataTypesReq req);
|
||||
|
||||
/// <summary>
|
||||
/// 获取实体基类列表
|
||||
/// </summary>
|
||||
IEnumerable<Tuple<string, string>> GetEntityBaseClasses();
|
||||
|
||||
/// <summary>
|
||||
/// 获取字段接口列表
|
||||
/// </summary>
|
||||
IEnumerable<Tuple<string, string>> GetFieldInterfaces();
|
||||
}
|
@ -1,15 +1,12 @@
|
||||
using NetAdmin.Application.Repositories;
|
||||
using NetAdmin.Application.Services.Tpl.Dependency;
|
||||
using NetAdmin.Domain.DbMaps.Tpl;
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Tpl.Example;
|
||||
using NetAdmin.Domain.DbMaps.Sys;
|
||||
using NetAdmin.Domain.Dto.Sys.CodeTemplate;
|
||||
using NetAdmin.Domain.Extensions;
|
||||
|
||||
namespace NetAdmin.Application.Services.Tpl;
|
||||
namespace NetAdmin.SysComponent.Application.Services.Sys;
|
||||
|
||||
/// <inheritdoc cref="IExampleService" />
|
||||
public sealed class ExampleService(BasicRepository<Tpl_Example, long> rpo) //
|
||||
: RepositoryService<Tpl_Example, long, IExampleService>(rpo), IExampleService
|
||||
/// <inheritdoc cref="ICodeTemplateService" />
|
||||
public sealed class CodeTemplateService(BasicRepository<Sys_CodeTemplate, long> rpo) //
|
||||
: RepositoryService<Sys_CodeTemplate, long, ICodeTemplateService>(rpo), ICodeTemplateService
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
|
||||
@ -26,34 +23,34 @@ public sealed class ExampleService(BasicRepository<Tpl_Example, long> rpo) //
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<long> CountAsync(QueryReq<QueryExampleReq> req)
|
||||
public Task<long> CountAsync(QueryReq<QueryCodeTemplateReq> req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
return QueryInternal(req).WithNoLockNoWait().CountAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IOrderedEnumerable<KeyValuePair<IImmutableDictionary<string, string>, int>>> CountByAsync(QueryReq<QueryExampleReq> req)
|
||||
public async Task<IOrderedEnumerable<KeyValuePair<IImmutableDictionary<string, string>, int>>> CountByAsync(QueryReq<QueryCodeTemplateReq> req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
var ret = await QueryInternal(req with { Order = Orders.None })
|
||||
.WithNoLockNoWait()
|
||||
.GroupBy(req.GetToListExp<Tpl_Example>())
|
||||
.GroupBy(req.GetToListExp<Sys_CodeTemplate>())
|
||||
.ToDictionaryAsync(a => a.Count())
|
||||
.ConfigureAwait(false);
|
||||
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
|
||||
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Tpl_Example).GetProperty(y)!.GetValue(x.Key)?.ToString())
|
||||
, x.Value))
|
||||
req.RequiredFields.ToImmutableDictionary(
|
||||
y => y, y => typeof(Sys_CodeTemplate).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value))
|
||||
.Where(x => x.Key.Any(y => !y.Value.NullOrEmpty()))
|
||||
.OrderByDescending(x => x.Value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<QueryExampleRsp> CreateAsync(CreateExampleReq req)
|
||||
public async Task<QueryCodeTemplateRsp> CreateAsync(CreateCodeTemplateReq req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
var ret = await Rpo.InsertAsync(req).ConfigureAwait(false);
|
||||
return ret.Adapt<QueryExampleRsp>();
|
||||
return ret.Adapt<QueryCodeTemplateRsp>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@ -64,33 +61,35 @@ public sealed class ExampleService(BasicRepository<Tpl_Example, long> rpo) //
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<QueryExampleRsp> EditAsync(EditExampleReq req)
|
||||
public async Task<QueryCodeTemplateRsp> EditAsync(EditCodeTemplateReq req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
#if DBTYPE_SQLSERVER
|
||||
return (await UpdateReturnListAsync(req).ConfigureAwait(false)).FirstOrDefault()?.Adapt<QueryExampleRsp>();
|
||||
#else
|
||||
return await UpdateAsync(req).ConfigureAwait(false) > 0 ? await GetAsync(new QueryExampleReq { Id = req.Id }).ConfigureAwait(false) : null;
|
||||
return await UpdateAsync(req).ConfigureAwait(false) > 0
|
||||
? await GetAsync(new QueryCodeTemplateReq { Id = req.Id }).ConfigureAwait(false)
|
||||
: null;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<IActionResult> ExportAsync(QueryReq<QueryExampleReq> req)
|
||||
public Task<IActionResult> ExportAsync(QueryReq<QueryCodeTemplateReq> req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
return ExportAsync<QueryExampleReq, QueryExampleRsp>(QueryInternal, req, Ln.示例导出);
|
||||
return ExportAsync<QueryCodeTemplateReq, QueryCodeTemplateRsp>(QueryInternal, req, Ln.代码模板导出);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<QueryExampleRsp> GetAsync(QueryExampleReq req)
|
||||
public async Task<QueryCodeTemplateRsp> GetAsync(QueryCodeTemplateReq req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
var ret = await QueryInternal(new QueryReq<QueryExampleReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
|
||||
return ret.Adapt<QueryExampleRsp>();
|
||||
var ret = await QueryInternal(new QueryReq<QueryCodeTemplateReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
|
||||
return ret.Adapt<QueryCodeTemplateRsp>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<PagedQueryRsp<QueryExampleRsp>> PagedQueryAsync(PagedQueryReq<QueryExampleReq> req)
|
||||
public async Task<PagedQueryRsp<QueryCodeTemplateRsp>> PagedQueryAsync(PagedQueryReq<QueryCodeTemplateReq> req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
var list = await QueryInternal(req)
|
||||
@ -100,18 +99,18 @@ public sealed class ExampleService(BasicRepository<Tpl_Example, long> rpo) //
|
||||
.ToListAsync(req)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return new PagedQueryRsp<QueryExampleRsp>(req.Page, req.PageSize, total, list.Adapt<IEnumerable<QueryExampleRsp>>());
|
||||
return new PagedQueryRsp<QueryCodeTemplateRsp>(req.Page, req.PageSize, total, list.Adapt<IEnumerable<QueryCodeTemplateRsp>>());
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IEnumerable<QueryExampleRsp>> QueryAsync(QueryReq<QueryExampleReq> req)
|
||||
public async Task<IEnumerable<QueryCodeTemplateRsp>> QueryAsync(QueryReq<QueryCodeTemplateReq> req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
var ret = await QueryInternal(req).WithNoLockNoWait().Take(req.Count).ToListAsync(req).ConfigureAwait(false);
|
||||
return ret.Adapt<IEnumerable<QueryExampleRsp>>();
|
||||
return ret.Adapt<IEnumerable<QueryCodeTemplateRsp>>();
|
||||
}
|
||||
|
||||
private ISelect<Tpl_Example> QueryInternal(QueryReq<QueryExampleReq> req)
|
||||
private ISelect<Sys_CodeTemplate> QueryInternal(QueryReq<QueryCodeTemplateReq> req)
|
||||
{
|
||||
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);
|
||||
|
@ -0,0 +1,6 @@
|
||||
namespace NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||
|
||||
/// <summary>
|
||||
/// 代码模板服务
|
||||
/// </summary>
|
||||
public interface ICodeTemplateService : IService, ICodeTemplateModule;
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,68 @@
|
||||
using NetAdmin.Domain.Dto.Sys.CodeTemplate;
|
||||
|
||||
namespace NetAdmin.SysComponent.Cache.Sys;
|
||||
|
||||
/// <inheritdoc cref="ICodeTemplateCache" />
|
||||
public sealed class CodeTemplateCache(IDistributedCache cache, ICodeTemplateService service)
|
||||
: DistributedCache<ICodeTemplateService>(cache, service), IScoped, ICodeTemplateCache
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
|
||||
{
|
||||
return Service.BulkDeleteAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<long> CountAsync(QueryReq<QueryCodeTemplateReq> req)
|
||||
{
|
||||
return Service.CountAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<IOrderedEnumerable<KeyValuePair<IImmutableDictionary<string, string>, int>>> CountByAsync(QueryReq<QueryCodeTemplateReq> req)
|
||||
{
|
||||
return Service.CountByAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<QueryCodeTemplateRsp> CreateAsync(CreateCodeTemplateReq req)
|
||||
{
|
||||
return Service.CreateAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<int> DeleteAsync(DelReq req)
|
||||
{
|
||||
return Service.DeleteAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<QueryCodeTemplateRsp> EditAsync(EditCodeTemplateReq req)
|
||||
{
|
||||
return Service.EditAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<IActionResult> ExportAsync(QueryReq<QueryCodeTemplateReq> req)
|
||||
{
|
||||
return Service.ExportAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<QueryCodeTemplateRsp> GetAsync(QueryCodeTemplateReq req)
|
||||
{
|
||||
return Service.GetAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<PagedQueryRsp<QueryCodeTemplateRsp>> PagedQueryAsync(PagedQueryReq<QueryCodeTemplateReq> req)
|
||||
{
|
||||
return Service.PagedQueryAsync(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<IEnumerable<QueryCodeTemplateRsp>> QueryAsync(QueryReq<QueryCodeTemplateReq> req)
|
||||
{
|
||||
return Service.QueryAsync(req);
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
namespace NetAdmin.SysComponent.Cache.Sys.Dependency;
|
||||
|
||||
/// <summary>
|
||||
/// 代码模板缓存
|
||||
/// </summary>
|
||||
public interface ICodeTemplateCache : ICache<IDistributedCache, ICodeTemplateService>, ICodeTemplateModule;
|
@ -23,4 +23,28 @@ public sealed class DevCache(IDistributedCache cache, IDevService service) //
|
||||
{
|
||||
return Service.GenerateJsCodeAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<IEnumerable<Tuple<string, string>>> GetDomainProjectsAsync()
|
||||
{
|
||||
return Service.GetDomainProjectsAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<string> GetDotnetDataTypes(GetDotnetDataTypesReq req)
|
||||
{
|
||||
return Service.GetDotnetDataTypes(req);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<Tuple<string, string>> GetEntityBaseClasses()
|
||||
{
|
||||
return Service.GetEntityBaseClasses();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<Tuple<string, string>> GetFieldInterfaces()
|
||||
{
|
||||
return Service.GetFieldInterfaces();
|
||||
}
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
using NetAdmin.Domain.Dto.Sys.CodeTemplate;
|
||||
|
||||
namespace NetAdmin.SysComponent.Host.Controllers.Sys;
|
||||
|
||||
/// <summary>
|
||||
/// 代码模板服务
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings(nameof(Sys), Module = nameof(Sys))]
|
||||
[Produces(Chars.FLG_HTTP_HEADER_VALUE_APPLICATION_JSON)]
|
||||
public sealed class CodeTemplateController(ICodeTemplateCache cache)
|
||||
: ControllerBase<ICodeTemplateCache, ICodeTemplateService>(cache), ICodeTemplateModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 批量删除代码模板
|
||||
/// </summary>
|
||||
[Transaction]
|
||||
public Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
|
||||
{
|
||||
return Cache.BulkDeleteAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 代码模板计数
|
||||
/// </summary>
|
||||
public Task<long> CountAsync(QueryReq<QueryCodeTemplateReq> req)
|
||||
{
|
||||
return Cache.CountAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 代码模板分组计数
|
||||
/// </summary>
|
||||
public Task<IOrderedEnumerable<KeyValuePair<IImmutableDictionary<string, string>, int>>> CountByAsync(QueryReq<QueryCodeTemplateReq> req)
|
||||
{
|
||||
return Cache.CountByAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建代码模板
|
||||
/// </summary>
|
||||
[Transaction]
|
||||
public Task<QueryCodeTemplateRsp> CreateAsync(CreateCodeTemplateReq req)
|
||||
{
|
||||
return Cache.CreateAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除代码模板
|
||||
/// </summary>
|
||||
[Transaction]
|
||||
public Task<int> DeleteAsync(DelReq req)
|
||||
{
|
||||
return Cache.DeleteAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑代码模板
|
||||
/// </summary>
|
||||
[Transaction]
|
||||
public Task<QueryCodeTemplateRsp> EditAsync(EditCodeTemplateReq req)
|
||||
{
|
||||
return Cache.EditAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导出代码模板
|
||||
/// </summary>
|
||||
[NonAction]
|
||||
public Task<IActionResult> ExportAsync(QueryReq<QueryCodeTemplateReq> req)
|
||||
{
|
||||
return Cache.ExportAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取单个代码模板
|
||||
/// </summary>
|
||||
public Task<QueryCodeTemplateRsp> GetAsync(QueryCodeTemplateReq req)
|
||||
{
|
||||
return Cache.GetAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询代码模板
|
||||
/// </summary>
|
||||
public Task<PagedQueryRsp<QueryCodeTemplateRsp>> PagedQueryAsync(PagedQueryReq<QueryCodeTemplateReq> req)
|
||||
{
|
||||
return Cache.PagedQueryAsync(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询代码模板
|
||||
/// </summary>
|
||||
[NonAction]
|
||||
public Task<IEnumerable<QueryCodeTemplateRsp>> QueryAsync(QueryReq<QueryCodeTemplateReq> req)
|
||||
{
|
||||
return Cache.QueryAsync(req);
|
||||
}
|
||||
}
|
@ -32,4 +32,36 @@ public sealed class DevController(IDevCache cache) : ControllerBase<IDevCache, I
|
||||
{
|
||||
return Cache.GenerateJsCodeAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取实体项目列表
|
||||
/// </summary>
|
||||
public Task<IEnumerable<Tuple<string, string>>> GetDomainProjectsAsync()
|
||||
{
|
||||
return Cache.GetDomainProjectsAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有数据类型
|
||||
/// </summary>
|
||||
public IEnumerable<string> GetDotnetDataTypes(GetDotnetDataTypesReq req)
|
||||
{
|
||||
return Cache.GetDotnetDataTypes(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取实体基类列表
|
||||
/// </summary>
|
||||
public IEnumerable<Tuple<string, string>> GetEntityBaseClasses()
|
||||
{
|
||||
return Cache.GetEntityBaseClasses();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取字段接口列表
|
||||
/// </summary>
|
||||
public IEnumerable<Tuple<string, string>> GetFieldInterfaces()
|
||||
{
|
||||
return Cache.GetFieldInterfaces();
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ public sealed class RequestAuditMiddleware(
|
||||
) {
|
||||
#pragma warning restore SA1009
|
||||
await next(context).ConfigureAwait(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -35,4 +35,45 @@ public class DevTests(WebTestApplicationFactory<Startup> factory, ITestOutputHel
|
||||
var rsp = await PostJsonAsync(typeof(DevController));
|
||||
Assert.True(rsp.IsSuccessStatusCode);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[Fact]
|
||||
public async Task<IEnumerable<Tuple<string, string>>> GetDomainProjectsAsync()
|
||||
{
|
||||
var rsp = await PostJsonAsync(typeof(DevController));
|
||||
Assert.True(rsp.IsSuccessStatusCode);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<string> GetDotnetDataTypes(GetDotnetDataTypesReq req)
|
||||
{
|
||||
#pragma warning disable xUnit1031
|
||||
var rsp = PostJsonAsync(typeof(DevController)).GetAwaiter().GetResult();
|
||||
#pragma warning restore xUnit1031
|
||||
Assert.True(rsp.IsSuccessStatusCode);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[Fact]
|
||||
public IEnumerable<Tuple<string, string>> GetEntityBaseClasses()
|
||||
{
|
||||
#pragma warning disable xUnit1031
|
||||
var rsp = PostJsonAsync(typeof(DevController)).GetAwaiter().GetResult();
|
||||
#pragma warning restore xUnit1031
|
||||
Assert.True(rsp.IsSuccessStatusCode);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[Fact]
|
||||
public IEnumerable<Tuple<string, string>> GetFieldInterfaces()
|
||||
{
|
||||
#pragma warning disable xUnit1031
|
||||
var rsp = PostJsonAsync(typeof(DevController)).GetAwaiter().GetResult();
|
||||
#pragma warning restore xUnit1031
|
||||
Assert.True(rsp.IsSuccessStatusCode);
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
global using CsvIgnore = CsvHelper.Configuration.Attributes.IgnoreAttribute;
|
@ -105,9 +105,13 @@ namespace YourSolution.AdmServer.Host
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
#pragma warning disable ASA001
|
||||
public async Task<int> Execute(CommandContext context, CommandLineArgs settings)
|
||||
#pragma warning restore ASA001
|
||||
public Task<int> ExecuteAsync(CommandContext context, CommandSettings settings)
|
||||
{
|
||||
return ExecuteAsync(context, (settings as CommandLineArgs)!);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<int> ExecuteAsync(CommandContext context, CommandLineArgs settings)
|
||||
{
|
||||
Args = settings;
|
||||
var webOpt = new WebApplicationOptions //
|
||||
@ -120,14 +124,6 @@ namespace YourSolution.AdmServer.Host
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
#pragma warning disable ASA001
|
||||
public Task<int> Execute(CommandContext context, CommandSettings settings)
|
||||
#pragma warning restore ASA001
|
||||
{
|
||||
return Execute(context, (settings as CommandLineArgs)!);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ValidationResult Validate(CommandContext context, CommandSettings settings)
|
||||
{
|
||||
|
@ -13,10 +13,6 @@
|
||||
"Group": "Adm",
|
||||
"Title": "管理服务",
|
||||
},
|
||||
{
|
||||
"Group": "Tpl",
|
||||
"Visible": false
|
||||
},
|
||||
{
|
||||
"Group": "Probe",
|
||||
"Visible": false
|
||||
|
@ -1,93 +1,93 @@
|
||||
/**
|
||||
* 示例服务
|
||||
* @module @/api/tpl/example
|
||||
* 代码模板服务
|
||||
* @module @/api/sys/code.template
|
||||
*/
|
||||
import config from '@/config'
|
||||
import http from '@/utils/request'
|
||||
export default {
|
||||
/**
|
||||
* 批量删除示例
|
||||
* 批量删除代码模板
|
||||
*/
|
||||
bulkDelete: {
|
||||
url: `${config.API_URL}/api/tpl/example/bulk.delete`,
|
||||
name: `批量删除示例`,
|
||||
url: `${config.API_URL}/api/sys/code.template/bulk.delete`,
|
||||
name: `批量删除代码模板`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 示例计数
|
||||
* 代码模板计数
|
||||
*/
|
||||
count: {
|
||||
url: `${config.API_URL}/api/tpl/example/count`,
|
||||
name: `示例计数`,
|
||||
url: `${config.API_URL}/api/sys/code.template/count`,
|
||||
name: `代码模板计数`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 示例分组计数
|
||||
* 代码模板分组计数
|
||||
*/
|
||||
countBy: {
|
||||
url: `${config.API_URL}/api/tpl/example/count.by`,
|
||||
name: `示例分组计数`,
|
||||
url: `${config.API_URL}/api/sys/code.template/count.by`,
|
||||
name: `代码模板分组计数`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建示例
|
||||
* 创建代码模板
|
||||
*/
|
||||
create: {
|
||||
url: `${config.API_URL}/api/tpl/example/create`,
|
||||
name: `创建示例`,
|
||||
url: `${config.API_URL}/api/sys/code.template/create`,
|
||||
name: `创建代码模板`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除示例
|
||||
* 删除代码模板
|
||||
*/
|
||||
delete: {
|
||||
url: `${config.API_URL}/api/tpl/example/delete`,
|
||||
name: `删除示例`,
|
||||
url: `${config.API_URL}/api/sys/code.template/delete`,
|
||||
name: `删除代码模板`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 编辑示例
|
||||
* 编辑代码模板
|
||||
*/
|
||||
edit: {
|
||||
url: `${config.API_URL}/api/tpl/example/edit`,
|
||||
name: `编辑示例`,
|
||||
url: `${config.API_URL}/api/sys/code.template/edit`,
|
||||
name: `编辑代码模板`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取单个示例
|
||||
* 获取单个代码模板
|
||||
*/
|
||||
get: {
|
||||
url: `${config.API_URL}/api/tpl/example/get`,
|
||||
name: `获取单个示例`,
|
||||
url: `${config.API_URL}/api/sys/code.template/get`,
|
||||
name: `获取单个代码模板`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 分页查询示例
|
||||
* 分页查询代码模板
|
||||
*/
|
||||
pagedQuery: {
|
||||
url: `${config.API_URL}/api/tpl/example/paged.query`,
|
||||
name: `分页查询示例`,
|
||||
url: `${config.API_URL}/api/sys/code.template/paged.query`,
|
||||
name: `分页查询代码模板`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
@ -37,4 +37,48 @@ export default {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取实体项目列表
|
||||
*/
|
||||
getDomainProjects: {
|
||||
url: `${config.API_URL}/api/sys/dev/get.domain.projects`,
|
||||
name: `获取实体项目列表`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取所有数据类型
|
||||
*/
|
||||
getDotnetDataTypes: {
|
||||
url: `${config.API_URL}/api/sys/dev/get.dotnet.data.types`,
|
||||
name: `获取所有数据类型`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取实体基类列表
|
||||
*/
|
||||
getEntityBaseClasses: {
|
||||
url: `${config.API_URL}/api/sys/dev/get.entity.base.classes`,
|
||||
name: `获取实体基类列表`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取字段接口列表
|
||||
*/
|
||||
getFieldInterfaces: {
|
||||
url: `${config.API_URL}/api/sys/dev/get.field.interfaces`,
|
||||
name: `获取字段接口列表`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
}
|
@ -75,4 +75,5 @@ export { default as archive } from './archive'
|
||||
export { default as 'device-log' } from './device-log'
|
||||
export { default as 'nick-name' } from './nick-name'
|
||||
export { default as telegram } from './telegram'
|
||||
export { default as country } from './country'
|
||||
export { default as country } from './country'
|
||||
export {default as template} from './template.vue'
|
1
src/frontend/admin/src/assets/icon/template.vue
Normal file
1
src/frontend/admin/src/assets/icon/template.vue
Normal file
@ -0,0 +1 @@
|
||||
<template><svg t="1751618283110" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5188" width="256" height="256"><path d="M533.333333 597.333333H106.666667c-12.8 0-21.333333-8.533333-21.333334-21.333333V106.666667c0-12.8 8.533333-21.333333 21.333334-21.333334h426.666666c12.8 0 21.333333 8.533333 21.333334 21.333334v469.333333c0 12.8-8.533333 21.333333-21.333334 21.333333zM128 554.666667h384V128H128v426.666667zM917.333333 938.666667H106.666667c-12.8 0-21.333333-8.533333-21.333334-21.333334V704c0-12.8 8.533333-21.333333 21.333334-21.333333h810.666666c12.8 0 21.333333 8.533333 21.333334 21.333333v213.333333c0 12.8-8.533333 21.333333-21.333334 21.333334zM128 896h768v-170.666667H128v170.666667zM917.333333 298.666667H661.333333c-12.8 0-21.333333-8.533333-21.333333-21.333334V106.666667c0-12.8 8.533333-21.333333 21.333333-21.333334h256c12.8 0 21.333333 8.533333 21.333334 21.333334v170.666666c0 12.8-8.533333 21.333333-21.333334 21.333334z m-234.666666-42.666667h213.333333V128H682.666667v128zM917.333333 597.333333H661.333333c-12.8 0-21.333333-8.533333-21.333333-21.333333v-170.666667c0-12.8 8.533333-21.333333 21.333333-21.333333h256c12.8 0 21.333333 8.533333 21.333334 21.333333v170.666667c0 12.8-8.533333 21.333333-21.333334 21.333333z m-234.666666-42.666666h213.333333v-128H682.666667v128z" fill="#333333" p-id="5189"></path></svg></template>
|
@ -443,7 +443,7 @@ export default {
|
||||
}
|
||||
this.aceEditorValue = this.vkbeautify.json(this.vue.query, 2)
|
||||
this.selectInputKey = this.controls.find((x) => x.type === 'select-input')?.field[1][0].key
|
||||
if (this.dateType === 'datetime-range') {
|
||||
if (this.dateType === 'datetimerange') {
|
||||
this.dateShortCuts.unshift(
|
||||
{
|
||||
text: this.$t('最近一时'),
|
||||
|
125
src/frontend/admin/src/components/na-table-page/detail.vue
Normal file
125
src/frontend/admin/src/components/na-table-page/detail.vue
Normal file
@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<sc-dialog v-model="visible" :full-screen="dialogFullScreen" :title="titleMap[mode]" @closed="$emit(`closed`)" destroy-on-close>
|
||||
<div v-loading="loading">
|
||||
<el-form
|
||||
:disabled="![`edit`, `add`].includes(mode)"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-position="right"
|
||||
label-width="12rem"
|
||||
ref="dialogForm">
|
||||
<template v-for="(item, i) in columns" :key="i">
|
||||
<el-form-item v-if="item.show?.includes(mode)" :label="item.label" :prop="i">
|
||||
<el-date-picker v-if="i.endsWith(`Time`)" v-model="form[i]" :disabled="item.disabled?.includes(mode)" type="datetime" />
|
||||
<el-select v-else-if="item.enum" v-model="form[i]" :disabled="item.disabled?.includes(mode)">
|
||||
<el-option
|
||||
v-for="e in Object.entries(this.$GLOBAL.enums[item.enum]).map((x) => {
|
||||
return { value: x[0], text: x[1][1] }
|
||||
})"
|
||||
:key="e.value"
|
||||
:label="e.text"
|
||||
:value="e.value" />
|
||||
</el-select>
|
||||
<el-switch
|
||||
v-else-if="typeof form[i] === `boolean` || item.isBoolean"
|
||||
v-model="form[i]"
|
||||
:disabled="item.disabled?.includes(mode)" />
|
||||
<component
|
||||
v-bind="item.detail?.props"
|
||||
v-else
|
||||
v-model="form[i]"
|
||||
:disabled="item.disabled?.includes(mode)"
|
||||
:is="item.detail?.is ?? `el-input`" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="visible = false">{{ $t(`取消`) }}</el-button>
|
||||
<el-button v-if="mode !== `view`" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t(`保存`) }}</el-button>
|
||||
</template>
|
||||
</sc-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
rules: {},
|
||||
visible: false,
|
||||
mode: `add`,
|
||||
loading: false,
|
||||
form: {},
|
||||
titleMap: {
|
||||
add: this.$t(`新建{summary}`, { summary: this.summary }),
|
||||
edit: this.$t(`编辑{summary}: {id}`, { summary: this.summary, id: `...` }),
|
||||
view: this.$t(`查看{summary}: {id}`, { summary: this.summary, id: `...` }),
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
emits: [`success`, `closed`, `mounted`],
|
||||
methods: {
|
||||
//显示
|
||||
async open(data) {
|
||||
this.visible = true
|
||||
this.loading = true
|
||||
this.mode = data.mode
|
||||
this.rules = Object.fromEntries(
|
||||
Object.entries(this.columns)
|
||||
.map((x) => {
|
||||
if (x[1].rule?.required) {
|
||||
return [
|
||||
x[0],
|
||||
[
|
||||
{ required: true, message: this.$t(`{field} 不能为空`, { field: x[1].label }) },
|
||||
{ validator: x[1].rule.validator, message: this.$t(`{field} 不正确`, { field: x[1].label }) },
|
||||
],
|
||||
]
|
||||
}
|
||||
return null
|
||||
})
|
||||
.filter((x) => x),
|
||||
)
|
||||
|
||||
if (data.row?.id) {
|
||||
const res = await this.$API[this.entityName].get.post({ id: data.row.id })
|
||||
Object.assign(this.form, res.data)
|
||||
this.titleMap.edit = this.$t(`编辑{summary}: {id}`, { summary: this.summary, id: this.form.id })
|
||||
this.titleMap.view = this.$t(`查看{summary}: {id}`, { summary: this.summary, id: this.form.id })
|
||||
}
|
||||
this.loading = false
|
||||
return this
|
||||
},
|
||||
|
||||
//表单提交方法
|
||||
async submit() {
|
||||
const valid = await this.$refs.dialogForm.validate().catch(() => {})
|
||||
if (!valid) {
|
||||
return false
|
||||
}
|
||||
this.loading = true
|
||||
const method = this.mode === `add` ? this.$API[this.entityName].create : this.$API[this.entityName].edit
|
||||
try {
|
||||
const res = await method.post(this.form)
|
||||
this.$emit(`success`, res.data, this.mode)
|
||||
this.visible = false
|
||||
this.$message.success(this.$t(`操作成功`))
|
||||
} catch {}
|
||||
this.loading = false
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$emit(`mounted`)
|
||||
},
|
||||
props: {
|
||||
entityName: { type: String },
|
||||
summary: { type: String },
|
||||
columns: { type: Array },
|
||||
dialogFullScreen: { type: Boolean },
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped />
|
344
src/frontend/admin/src/components/na-table-page/index.vue
Normal file
344
src/frontend/admin/src/components/na-table-page/index.vue
Normal file
@ -0,0 +1,344 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<!-- 仪表板-->
|
||||
<el-header v-loading="statistics.total === `...`" class="el-header-statistics">
|
||||
<el-row :gutter="15">
|
||||
<el-col :lg="24">
|
||||
<el-card shadow="never">
|
||||
<sc-statistic :title="$t(`总数`)" :value="statistics.total" group-separator />
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
|
||||
<!-- 过滤器-->
|
||||
<el-header v-if="selectFilterData.length > 0" class="el-header-select-filter">
|
||||
<sc-select-filter :data="selectFilterData" :label-width="10" @on-change="onFilterChange" ref="selectFilter" />
|
||||
</el-header>
|
||||
|
||||
<!-- 搜索栏-->
|
||||
<el-header>
|
||||
<div class="left-panel">
|
||||
<na-search
|
||||
:controls="searchControls"
|
||||
:vue="this"
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
<div class="right-panel">
|
||||
<el-button v-if="operations.includes('add')" @click="onAddClick" icon="el-icon-plus" type="primary" />
|
||||
<el-button
|
||||
:disabled="this.table.selection.length === 0 || this.loading"
|
||||
@click="onBulkDeleteClick"
|
||||
icon="el-icon-delete"
|
||||
plain
|
||||
type="danger" />
|
||||
</div>
|
||||
</el-header>
|
||||
|
||||
<!-- 表格主体-->
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
:context-extra="this.table.menu.extra"
|
||||
:context-menus="Object.keys(this.columns)"
|
||||
:context-opers="this.operations"
|
||||
:default-sort="{ prop: `id`, order: `descending` }"
|
||||
:export-api="$API[entityName].export"
|
||||
:params="query"
|
||||
:query-api="$API[entityName].pagedQuery"
|
||||
:vue="this"
|
||||
@data-change="onDataChange"
|
||||
@selection-change="onSelectionChange"
|
||||
ref="table"
|
||||
remote-filter
|
||||
remote-sort
|
||||
row-key="id"
|
||||
stripe>
|
||||
<el-table-column type="selection" width="50" />
|
||||
<template v-for="(item, i) in columns" :key="i">
|
||||
<component
|
||||
v-bind="item"
|
||||
v-if="item.show.includes('list')"
|
||||
:is="item.is ?? `el-table-column`"
|
||||
:options="
|
||||
item.options ??
|
||||
(item.enum
|
||||
? Object.entries(this.$GLOBAL.enums[item.enum]).map((x) => {
|
||||
return { value: x[0], text: x[1][1], type: x[1][2], pulse: x[1][3] === 'true' }
|
||||
})
|
||||
: null)
|
||||
"
|
||||
:prop="i"
|
||||
:sortable="item.sortable ?? `custom`">
|
||||
<template v-if="item.isBoolean" #default="{ row }">
|
||||
<el-switch v-model="row[i]" @change="onSwitchChange(row, i === `enabled` ? `setEnabled` : item.onChange)"></el-switch>
|
||||
</template>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<el-table-column :label="$t(`操作`)" align="right" fixed="right" width="150">
|
||||
<template #default="{ row }">
|
||||
<el-button-group size="small">
|
||||
<el-button @click="onViewClick(row)" icon="el-icon-view" />
|
||||
<el-button v-if="operations.includes(`edit`)" @click="onEditClick(row)" icon="el-icon-edit" />
|
||||
<el-button v-if="operations.includes(`del`)" @click="onDeleteClick(row)" icon="el-icon-delete" type="danger" />
|
||||
</el-button-group>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</sc-table>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
||||
<detail-dialog
|
||||
v-bind="$props"
|
||||
v-if="dialog.detail"
|
||||
@closed="dialog.detail = null"
|
||||
@mounted="$refs.detailDialog.open(dialog.detail)"
|
||||
@success="(data, mode) => tableConfig.handleUpdate($refs.table, data, mode)"
|
||||
ref="detailDialog" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { h } from 'vue'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
import tableConfig from '@/config/table'
|
||||
import naColOperation from '@/config/na-col-operation'
|
||||
const naColAvatar = defineAsyncComponent(() => import('@/components/na-col-avatar'))
|
||||
const detailDialog = defineAsyncComponent(() => import('./detail'))
|
||||
export default {
|
||||
components: {
|
||||
detailDialog,
|
||||
naColAvatar,
|
||||
},
|
||||
computed: {
|
||||
naColOperation() {
|
||||
return naColOperation
|
||||
},
|
||||
tableConfig() {
|
||||
return tableConfig
|
||||
},
|
||||
},
|
||||
created() {
|
||||
const searchFields = []
|
||||
for (const item in this.columns) {
|
||||
this.table.menu.extra[item] = this.columns[item].extra
|
||||
if (this.columns[item].searchable) {
|
||||
searchFields.push({ label: this.columns[item].label, key: item })
|
||||
}
|
||||
}
|
||||
if (searchFields.length > 0) {
|
||||
this.searchControls.push({
|
||||
type: 'select-input',
|
||||
field: ['dy', searchFields],
|
||||
placeholder: this.$t('匹配内容'),
|
||||
style: 'width:25rem',
|
||||
selectStyle: 'width:8rem',
|
||||
})
|
||||
}
|
||||
|
||||
for (const filter of this.selectFilters) {
|
||||
this.selectFilterData.push({
|
||||
title: filter.title,
|
||||
key: filter.key,
|
||||
options: [{ label: this.$t(`全部`), value: `` }].concat(
|
||||
filter.isBoolean
|
||||
? filter.isBoolean
|
||||
: Object.entries(this.$GLOBAL.enums[filter.enumName]).map((x) => {
|
||||
return {
|
||||
value: x[0],
|
||||
label: x[1][1],
|
||||
}
|
||||
}),
|
||||
),
|
||||
})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 过滤器数据
|
||||
selectFilterData: [],
|
||||
|
||||
// 搜索栏数据
|
||||
searchControls: [],
|
||||
|
||||
// 正在加载标记
|
||||
loading: false,
|
||||
|
||||
// 仪表盘统计数据
|
||||
statistics: {
|
||||
total: `...`,
|
||||
},
|
||||
|
||||
// 对话框
|
||||
dialog: {},
|
||||
|
||||
// 表格查询参数
|
||||
query: {
|
||||
dynamicFilter: {
|
||||
filters: [],
|
||||
},
|
||||
filter: {},
|
||||
keywords: this.keywords,
|
||||
},
|
||||
|
||||
// 表格配置
|
||||
table: {
|
||||
// 选中项
|
||||
selection: [],
|
||||
// 右键菜单
|
||||
menu: {
|
||||
extra: {},
|
||||
opers: [],
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
inject: [`reload`],
|
||||
methods: {
|
||||
// ---------------------------- ↓ 过滤器事件 ----------------------------
|
||||
onFilterChange(data) {
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
this.$refs.search.form.dy[key] = value === `true` ? true : value === `false` ? false : value
|
||||
})
|
||||
this.$refs.search.search()
|
||||
},
|
||||
// ---------------------------- 过滤器事件 ↑ ----------------------------
|
||||
|
||||
// ---------------------------- ↓ 搜索栏事件 ----------------------------
|
||||
async onReset() {
|
||||
Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = [``]))
|
||||
},
|
||||
async onSearch(form) {
|
||||
if (Array.isArray(form.dy.createdTime)) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: `createdTime`,
|
||||
operator: `dateRange`,
|
||||
value: form.dy.createdTime,
|
||||
})
|
||||
}
|
||||
for (const item in this.columns) {
|
||||
const field = form.dy[item] || form.dy[item[0].toUpperCase() + item.substring(1)]
|
||||
if (field === undefined || field === '' || typeof field === 'object') continue
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: item,
|
||||
operator: this.columns[item].searchable,
|
||||
value: field,
|
||||
})
|
||||
}
|
||||
|
||||
await this.$refs.table.upData()
|
||||
},
|
||||
// ---------------------------- 搜索栏事件 ↑ ----------------------------
|
||||
|
||||
// ---------------------------- ↓ 表格事件 ----------------------------
|
||||
async onViewClick(row) {
|
||||
this.dialog.detail = { mode: 'view', row }
|
||||
},
|
||||
async onEditClick(row) {
|
||||
this.dialog.detail = { mode: 'edit', row }
|
||||
},
|
||||
async onBulkDeleteClick() {
|
||||
let loading
|
||||
try {
|
||||
await this.$confirm(this.$t('确定删除选中的 {count} 项吗?', { count: this.table.selection.length }), this.$t('提示'), {
|
||||
type: 'warning',
|
||||
})
|
||||
loading = this.$loading()
|
||||
const res = await this.$API[this.entityName].bulkDelete.post({
|
||||
items: this.table.selection,
|
||||
})
|
||||
this.$refs.table.refresh()
|
||||
this.$message.success(this.$t('删除 {count} 项', { count: res.data }))
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
loading?.close()
|
||||
},
|
||||
async onDeleteClick(row) {
|
||||
try {
|
||||
await this.$confirm(h('div', [h('p', this.$t('是否确认删除?')), h('p', row.id)]), this.$t('提示'), {
|
||||
type: 'warning',
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
let loading = this.$loading()
|
||||
try {
|
||||
const res = await this.$API[this.entityName].delete.post({
|
||||
id: row.id,
|
||||
})
|
||||
this.$message.success(this.$t(`删除 {count} 项`, { count: res.data }))
|
||||
this.$refs.table.refresh()
|
||||
} catch {}
|
||||
loading?.close()
|
||||
},
|
||||
async onAddClick() {
|
||||
this.dialog.detail = { mode: 'add' }
|
||||
},
|
||||
async onSwitchChange(row, method) {
|
||||
try {
|
||||
await this.$API[this.entityName][method].post(row)
|
||||
this.$message.success(this.$t('操作成功'))
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
this.$refs.table.refresh()
|
||||
},
|
||||
async onDataChange(data) {
|
||||
this.statistics.total = this.$refs.table?.total
|
||||
|
||||
const calls = []
|
||||
for (const col in this.columns) {
|
||||
if (this.columns[col].countBy)
|
||||
calls.push(
|
||||
this.$API[this.entityName].countBy.post({
|
||||
dynamicFilter: { filters: this.query.dynamicFilter.filters },
|
||||
requiredFields: [col[0].toUpperCase() + col.substring(1)],
|
||||
}),
|
||||
)
|
||||
}
|
||||
const res = await Promise.all(calls)
|
||||
Object.assign(this.statistics, { res })
|
||||
for (const item of res) {
|
||||
for (const item2 of item.data) {
|
||||
const key = Object.entries(item2.key)[0]
|
||||
const filter = this.selectFilterData
|
||||
.find((x) => x.key.toString().toLowerCase() === key[0].toLowerCase())
|
||||
?.options.find((x) => x.value.toString().toLowerCase() === key[1].toLowerCase())
|
||||
if (filter) filter.badge = item2.value
|
||||
}
|
||||
}
|
||||
},
|
||||
onSelectionChange(data) {
|
||||
this.table.selection = data
|
||||
},
|
||||
// ---------------------------- 表格事件 ↑ ----------------------------
|
||||
},
|
||||
async mounted() {
|
||||
if (this.keywords) {
|
||||
this.$refs.search.form.root.keywords = this.keywords
|
||||
this.$refs.search.keeps.push({
|
||||
field: `keywords`,
|
||||
value: this.keywords,
|
||||
type: `root`,
|
||||
})
|
||||
}
|
||||
},
|
||||
props: {
|
||||
keywords: { type: String },
|
||||
entityName: { type: String },
|
||||
summary: { type: String },
|
||||
selectFilters: { type: Array },
|
||||
columns: { type: Object },
|
||||
operations: { type: Array, default: ['add', 'edit', 'del'] },
|
||||
dialogFullScreen: { type: Boolean },
|
||||
},
|
||||
watch: {},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped />
|
@ -117,9 +117,12 @@
|
||||
<sc-contextmenu-item
|
||||
v-for="(menu, index) in contextMenus.filter((x) => {
|
||||
if (current.column?.property === x) {
|
||||
this.showCopy = true
|
||||
return true
|
||||
}
|
||||
return this.contextMulti && !!this.contextMulti[current.column?.property]?.find((y) => y === x)
|
||||
const ret = this.contextExtra && !!this.contextExtra[current.column?.property]?.find((y) => y === x)
|
||||
if (ret) this.showCopy = true
|
||||
return ret
|
||||
})"
|
||||
:command="menu"
|
||||
:key="index"
|
||||
@ -151,9 +154,15 @@
|
||||
:command="`${menu}^|^order-descending^|^${tool.getNestedProperty(current.row, menu) ?? ''}`"
|
||||
:title="$t('倒序排序')" />
|
||||
</sc-contextmenu-item>
|
||||
<sc-contextmenu-item :title="$t('复制')" command="copy" divided icon="el-icon-copy-document" suffix="C" />
|
||||
<sc-contextmenu-item v-if="contextOpers.includes('add')" :title="$t('新建')" command="add" divided icon="el-icon-plus" suffix="A" />
|
||||
<sc-contextmenu-item v-if="contextOpers.includes('view')" :title="$t('查看')" command="view" icon="el-icon-view" suffix="V" />
|
||||
<sc-contextmenu-item v-if="showCopy" :title="$t('复制')" command="copy" divided icon="el-icon-copy-document" suffix="C" />
|
||||
<sc-contextmenu-item
|
||||
v-if="contextOpers.includes('add')"
|
||||
:divided="showCopy"
|
||||
:title="$t('新建')"
|
||||
command="add"
|
||||
icon="el-icon-plus"
|
||||
suffix="A" />
|
||||
<sc-contextmenu-item :title="$t('查看')" command="view" icon="el-icon-view" suffix="V" />
|
||||
<sc-contextmenu-item v-if="contextOpers.includes('edit')" :title="$t('编辑')" command="edit" icon="el-icon-edit" suffix="E" />
|
||||
<sc-contextmenu-item v-if="contextOpers.includes('del')" :title="$t('删除')" command="del" icon="el-icon-delete" suffix="D" />
|
||||
<sc-contextmenu-item
|
||||
@ -179,6 +188,7 @@ const fieldFilter = defineAsyncComponent(() => import('./field-filter'))
|
||||
|
||||
import { h } from 'vue'
|
||||
import tool from '@/utils/tool'
|
||||
import iframe from '@/store/modules/iframe'
|
||||
|
||||
export default {
|
||||
name: 'scTable',
|
||||
@ -192,9 +202,9 @@ export default {
|
||||
dblClickDisable: { type: Boolean, default: false },
|
||||
vue: { type: Object },
|
||||
contextMenus: { type: Array },
|
||||
contextOpers: { type: Array, default: ['copy', 'add', 'view', 'edit', 'del'] },
|
||||
contextOpers: { type: Array, default: [] },
|
||||
contextAdvs: { type: Array, default: [] },
|
||||
contextMulti: { type: Object },
|
||||
contextExtra: { type: Object },
|
||||
tableName: { type: String, default: '' },
|
||||
beforePost: {
|
||||
type: Function,
|
||||
@ -256,6 +266,9 @@ export default {
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
iframe() {
|
||||
return iframe
|
||||
},
|
||||
tool() {
|
||||
return tool
|
||||
},
|
||||
@ -268,6 +281,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showCopy: false,
|
||||
pagerCount: 11,
|
||||
current: {
|
||||
row: null,
|
||||
@ -326,7 +340,7 @@ export default {
|
||||
return
|
||||
}
|
||||
if (this.vue.dialog) {
|
||||
this.vue.dialog.save = { mode: 'view', row: { id: row.id } }
|
||||
this.vue.dialog.detail = { mode: 'view', row: { id: row.id } }
|
||||
}
|
||||
},
|
||||
async contextMenuCommand(command) {
|
||||
@ -357,7 +371,7 @@ export default {
|
||||
return
|
||||
}
|
||||
if (command === 'view') {
|
||||
this.vue.dialog.save = { mode: 'view', row: { id: this.current.row.id } }
|
||||
await this.vue.onViewClick(this.current.row)
|
||||
return
|
||||
}
|
||||
if (command === 'export') {
|
||||
@ -365,22 +379,15 @@ export default {
|
||||
return
|
||||
}
|
||||
if (command === 'add') {
|
||||
this.vue.dialog.save = { mode: 'add' }
|
||||
await this.vue.onAddClick()
|
||||
return
|
||||
}
|
||||
if (command === 'edit') {
|
||||
this.vue.dialog.save = { mode: 'edit', row: { id: this.current.row.id } }
|
||||
await this.vue.onEditClick(this.current.row)
|
||||
return
|
||||
}
|
||||
if (command === 'del') {
|
||||
try {
|
||||
await this.$confirm(h('div', [h('p', this.$t('是否确认删除?')), h('p', this.current.row.id)]), this.$t('提示'), {
|
||||
type: 'warning',
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
await this.vue.rowDel(this.current.row)
|
||||
await this.vue.onDeleteClick(this.current.row)
|
||||
return
|
||||
}
|
||||
const kv = command.split('^|^')
|
||||
@ -404,6 +411,7 @@ export default {
|
||||
}
|
||||
},
|
||||
contextMenuVisibleChange(visible) {
|
||||
this.showCopy = false
|
||||
if (!visible) {
|
||||
this.setCurrentRow()
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -2,7 +2,7 @@
|
||||
// 书写格式与动态路由格式一致,全部经由框架统一转换
|
||||
// 比较动态路由在meta中多加入了role角色权限,为数组类型。一个菜单是否有权限显示,取决于它以及后代菜单是否有权限。
|
||||
// routes 显示在左侧菜单中的路由(显示顺序在动态路由之前)
|
||||
// 示例如下
|
||||
// 代码模板如下
|
||||
|
||||
// const routes = [
|
||||
// {
|
||||
|
@ -31,6 +31,7 @@ import scSelectFilter from '@/components/sc-select-filter'
|
||||
import scStatistic from '@/components/sc-statistic'
|
||||
import scStatusIndicator from '@/components/sc-mini/sc-status-indicator'
|
||||
import scTable from '@/components/sc-table'
|
||||
import scSelect from '@/components/sc-select'
|
||||
|
||||
// net-admin组件
|
||||
import naButtonBulkDel from '@/components/na-button-bulk-del'
|
||||
@ -39,8 +40,9 @@ import naColIndicator from '@/components/na-col-indicator'
|
||||
import naColOperation from '@/components/na-col-operation'
|
||||
import naColUser from '@/components/na-col-user'
|
||||
import naIndicator from '@/components/na-indicator'
|
||||
import naSearch from '@/components/na-search'
|
||||
import naInfo from '@/components/na-info'
|
||||
import naSearch from '@/components/na-search'
|
||||
import naTablePage from '@/components/na-table-page'
|
||||
|
||||
export default {
|
||||
install(app) {
|
||||
@ -80,6 +82,7 @@ export default {
|
||||
app.component('naIndicator', naIndicator)
|
||||
app.component('naInfo', naInfo)
|
||||
app.component('naSearch', naSearch)
|
||||
app.component('naTablePage', naTablePage)
|
||||
|
||||
// sc组件
|
||||
app.component('scDialog', scDialog)
|
||||
@ -87,6 +90,7 @@ export default {
|
||||
app.component('scStatistic', scStatistic)
|
||||
app.component('scStatusIndicator', scStatusIndicator)
|
||||
app.component('scTable', scTable)
|
||||
app.component('scSelect', scSelect)
|
||||
|
||||
//注册全局指令
|
||||
app.directive('auth', auth)
|
||||
|
@ -625,4 +625,9 @@ export default {
|
||||
按钮: 'Button',
|
||||
倒序排序: 'Sort-Descending',
|
||||
顺序排序: 'Sort-Ascending',
|
||||
'查看{summary}: {id}': 'View {summary}: {id}',
|
||||
'新建{summary}': 'Add {summary}',
|
||||
'编辑{summary}: {id}': 'Edit {summary}: {id}',
|
||||
'{field} 不能为空': '{field} Must not be empty',
|
||||
'{field} Incorrect': '{field} Incorrect',
|
||||
}
|
@ -623,4 +623,9 @@ export default {
|
||||
按钮: '按钮',
|
||||
倒序排序: '倒序排序',
|
||||
顺序排序: '顺序排序',
|
||||
'查看{summary}: {id}': '查看{summary}: {id}',
|
||||
'新建{summary}': '新建{summary}',
|
||||
'编辑{summary}: {id}': '编辑{summary}: {id}',
|
||||
'{field} 不能为空': '{field} 不能为空',
|
||||
'{field} 不正确': '{field} 不正确',
|
||||
}
|
@ -1,70 +1,148 @@
|
||||
<template>
|
||||
<router-view />
|
||||
<el-main>
|
||||
<el-row :gutter="15">
|
||||
<el-col :lg="6" :md="8" :sm="12" :xl="6" :xs="24">
|
||||
<el-card :body-style="{ padding: '0' }" shadow="hover">
|
||||
<el-col>
|
||||
<el-card :body-style="{ padding: `0` }" shadow="hover">
|
||||
<div class="code-item">
|
||||
<div :style="{ background: 'blue' }" class="img">
|
||||
<el-icon>
|
||||
<component :is="`sc-icon-js`" />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="title">
|
||||
<h2>{{ $t('生成前端代码') }}</h2>
|
||||
<p>
|
||||
<el-button @click="generateJsCode()">{{ $t('生成') }}</el-button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="8" :sm="12" :xl="6" :xs="24">
|
||||
<el-card :body-style="{ padding: '0' }" shadow="hover">
|
||||
<div class="code-item">
|
||||
<div :style="{ background: 'orange' }" class="img">
|
||||
<div :style="{ background: `orange` }" class="img">
|
||||
<el-icon>
|
||||
<component :is="`sc-icon-csharp`" />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="title">
|
||||
<h2>{{ $t('生成后端代码') }}</h2>
|
||||
<el-form :model="form" :rules="rules" label-position="right" label-width="10rem" ref="form">
|
||||
<el-form-item :label="$t(`选择项目`)" prop="project">
|
||||
<sc-select
|
||||
v-model="form.project"
|
||||
:config="{ props: { label: `item1`, value: `item2` } }"
|
||||
:query-api="$API.sys_dev.getDomainProjects"
|
||||
class="w100p"
|
||||
clearable
|
||||
filterable />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t(`实体名称`)" prop="entityName">
|
||||
<el-input v-model="form.entityName" placeholder="Example"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t(`基类`)" prop="baseClass">
|
||||
<sc-select
|
||||
v-model="form.baseClass"
|
||||
:config="{ props: { label: `item1`, value: `item1` } }"
|
||||
:query-api="$API.sys_dev.getEntityBaseClasses"
|
||||
class="w100p"
|
||||
clearable
|
||||
filterable />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t(`实现接口`)" prop="interfaces">
|
||||
<sc-select
|
||||
v-model="form.interfaces"
|
||||
:config="{ props: { label: `item1`, value: `item1` } }"
|
||||
:query-api="$API.sys_dev.getFieldInterfaces"
|
||||
class="w100p"
|
||||
clearable
|
||||
filterable
|
||||
multiple />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t(`描述`)" prop="summary">
|
||||
<el-input v-model="form.summary" placeholder="example" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t(`字段列表`)" prop="fieldList">
|
||||
<sc-form-table v-model="form.fieldList" :addTemplate="{}" :placeholder="$t(`暂无数据`)" drag-sort ref="formTable">
|
||||
<el-table-column :label="$t(`字段名称`)" prop="name" width="150">
|
||||
<template #default="{ row }">
|
||||
<el-input v-model="row.name" placeholder="Username" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t(`字段说明`)" prop="summary" width="150">
|
||||
<template #default="{ row }">
|
||||
<el-input v-model="row.summary" :placeholder="$t(`用户名`)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t(`示例值`)" prop="example" width="150">
|
||||
<template #default="{ row }">
|
||||
<el-input v-model="row.example" :placeholder="$t(`root`)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t(`字段类型`)" prop="type" width="150">
|
||||
<template #default="{ row }">
|
||||
<el-select
|
||||
v-loading="loading"
|
||||
v-model="row.type"
|
||||
:remote-method="remoteMethod"
|
||||
filterable
|
||||
remote
|
||||
remote-show-suffix
|
||||
reserve-keyword>
|
||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t(`数据库字段类型`)" prop="dbType">
|
||||
<template #default="{ row }">
|
||||
<el-select v-model="row.dbType" clearable filterable>
|
||||
<el-option v-for="(item, i) in dbTypes" :key="i" :label="item[0]" :value="item[0]" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t(`可空`)" align="center" prop="isNullable" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-switch v-model="row.isNullable" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t(`主键`)" align="center" prop="isPrimary" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-switch v-model="row.isPrimary" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t(`值类型`)" align="center" prop="isStruct" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-switch v-model="row.isStruct" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</sc-form-table>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="submit" type="primary">{{ $t(`生成`) }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-card :body-style="{ padding: `0` }" shadow="hover">
|
||||
<div class="code-item">
|
||||
<div :style="{ background: `blue` }" class="img">
|
||||
<el-icon>
|
||||
<component :is="`sc-icon-js`" />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="title">
|
||||
<p>
|
||||
<el-input v-model="formCs.type" :placeholder="$t('模块类型')" />
|
||||
</p>
|
||||
<p>
|
||||
<el-input v-model="formCs.moduleName" :placeholder="$t('模块名称')" />
|
||||
</p>
|
||||
<p>
|
||||
<el-input v-model="formCs.moduleRemark" :placeholder="$t('模块说明')" />
|
||||
</p>
|
||||
<p>
|
||||
<el-button @click="generateCsCode()">{{ $t('生成') }}</el-button>
|
||||
<el-button @click="generateJsCode()">{{ $t(`生成`) }}</el-button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="8" :sm="12" :xl="6" :xs="24">
|
||||
<el-card :body-style="{ padding: '0' }" shadow="hover">
|
||||
<el-col>
|
||||
<el-card :body-style="{ padding: `0` }" shadow="hover">
|
||||
<div class="code-item">
|
||||
<div :style="{ background: 'green' }" class="img">
|
||||
<div :style="{ background: `green` }" class="img">
|
||||
<el-icon>
|
||||
<component :is="`el-icon-picture`" />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="title">
|
||||
<h2>{{ $t('生成图标代码') }}</h2>
|
||||
<p>
|
||||
<el-input v-model="form.iconName" :placeholder="$t('图标名称')" />
|
||||
<el-input v-model="iconForm.iconName" :placeholder="$t(`图标名称`)" />
|
||||
</p>
|
||||
<p>
|
||||
<el-input v-model="form.svgCode" :placeholder="$t('粘贴SVG代码')" />
|
||||
<el-input v-model="iconForm.svgCode" :placeholder="$t(`粘贴SVG代码`)" />
|
||||
</p>
|
||||
<p>
|
||||
<el-row align="middle">
|
||||
<el-col :span="12">
|
||||
<el-button @click="generateIconCode()">{{ $t('生成') }}</el-button>
|
||||
<el-button @click="generateIconCode()">{{ $t(`生成`) }}</el-button>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-link href="https://www.iconfont.cn/" target="_blank">Iconfont</el-link>
|
||||
@ -75,84 +153,138 @@
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="8" :sm="12" :xl="6" :xs="24">
|
||||
<el-card :body-style="{ padding: '0' }" shadow="hover">
|
||||
<div class="code-item">
|
||||
<div :style="{ background: 'gray' }" class="img">
|
||||
<el-icon>
|
||||
<component :is="`el-icon-picture`" />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="title">
|
||||
<h2>{{ $t('生成表格代码') }}</h2>
|
||||
<p>
|
||||
<el-input v-model="form.summaryInfo" :placeholder="$t('注释信息')" type="textarea" />
|
||||
</p>
|
||||
<p>
|
||||
<el-input v-model="form.tableCode" :placeholder="$t('表格代码')" type="textarea" />
|
||||
</p>
|
||||
<p>
|
||||
<el-input v-model="form.formCode" :placeholder="$t('表单代码')" type="textarea" />
|
||||
</p>
|
||||
<p>
|
||||
<el-button @click="generateTableCode()">{{ $t('生成') }}</el-button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
const scFormTable = defineAsyncComponent(() => import('@/components/sc-form-table'))
|
||||
|
||||
export default {
|
||||
components: {
|
||||
scFormTable,
|
||||
},
|
||||
created() {
|
||||
this.dbTypes = Object.entries(this.$GLOBAL.chars).filter((x) => x[0].indexOf(`FLG_DB_FIELD_TYPE`) === 0)
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
svgCode: '',
|
||||
iconName: '',
|
||||
loading: false,
|
||||
options: [],
|
||||
dbTypes: [],
|
||||
iconForm: {
|
||||
svgCode: ``,
|
||||
iconName: ``,
|
||||
},
|
||||
formCs: {
|
||||
moduleName: '',
|
||||
/// 模块说明
|
||||
moduleRemark: '',
|
||||
/// 模块类型
|
||||
type: 'YourSolution.AdmServer',
|
||||
form: {
|
||||
entityName: `Example`,
|
||||
interfaces: [`IFieldSummary`, `IFieldOwner`, `IFieldSort`, `IFieldEnabled`],
|
||||
summary: this.$t(`示例`),
|
||||
baseClass: `VersionEntity`,
|
||||
fieldList: [
|
||||
{
|
||||
name: `Id`,
|
||||
summary: this.$t(`示例编号`),
|
||||
example: `123456`,
|
||||
type: `long`,
|
||||
isPrimary: true,
|
||||
isStruct: true,
|
||||
},
|
||||
{
|
||||
name: `Name`,
|
||||
summary: this.$t(`名称`),
|
||||
example: this.$t(`老王`),
|
||||
type: `string`,
|
||||
dbType: `FLG_DB_FIELD_TYPE_VARCHAR_31`,
|
||||
},
|
||||
{
|
||||
name: `Gender`,
|
||||
summary: this.$t(`性别`),
|
||||
example: this.$t(`Male`),
|
||||
type: `Genders`,
|
||||
isNullable: true,
|
||||
isStruct: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
rules: {
|
||||
project: [{ required: true, message: this.$t(`请选择项目`) }],
|
||||
entityName: [{ required: true, message: this.$t(`请输入实体名称`) }],
|
||||
summary: [{ required: true, message: this.$t(`请输入描述`) }],
|
||||
baseClass: [{ required: true, message: this.$t(`请选择基类`) }],
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async generateIconCode() {
|
||||
try {
|
||||
await this.$API.sys_dev.generateIconCode.post(this.form)
|
||||
this.$message.success('生成完毕')
|
||||
await this.$API.sys_dev.generateIconCode.post(this.iconForm)
|
||||
this.$message.success($t(`生成完毕`))
|
||||
} catch {}
|
||||
},
|
||||
async generateTableCode() {
|
||||
for (const line of this.form.summaryInfo.split('\n')) {
|
||||
if (!line) continue
|
||||
let lineSplit = line.split(',')
|
||||
this.form.tableCode += `<el-table-column prop="${lineSplit[0].slice(0, 1).toLowerCase()}${lineSplit[0].slice(1)}" label="${
|
||||
lineSplit[1]
|
||||
}" />`
|
||||
|
||||
this.form.formCode += `<el-form-item prop="${lineSplit[0].slice(0, 1).toLowerCase()}${lineSplit[0].slice(1)}" label="${
|
||||
lineSplit[1]
|
||||
}"><el-input v-model="form.${lineSplit[0].slice(0, 1).toLowerCase()}${lineSplit[0].slice(1)}" clearable /></el-form-item>`
|
||||
}
|
||||
},
|
||||
async generateJsCode() {
|
||||
try {
|
||||
await this.$API.sys_dev.generateJsCode.post()
|
||||
this.$message.success('生成完毕')
|
||||
this.$message.success($t(`生成完毕`))
|
||||
} catch {}
|
||||
},
|
||||
async generateCsCode() {
|
||||
async remoteMethod(query) {
|
||||
if (query) {
|
||||
await new Promise((x) => setTimeout(x, 100))
|
||||
this.loading = true
|
||||
const res = await this.$API.sys_dev.getDotnetDataTypes.post({ startWith: query })
|
||||
this.options = res.data.map((x) => {
|
||||
return {
|
||||
label: x,
|
||||
value: x,
|
||||
}
|
||||
})
|
||||
this.loading = false
|
||||
} else {
|
||||
this.options = []
|
||||
}
|
||||
},
|
||||
async submit() {
|
||||
let primaryCount = 0
|
||||
for (const field of this.form.fieldList ?? []) {
|
||||
if (field.isPrimary) {
|
||||
primaryCount++
|
||||
}
|
||||
if (!field.name) {
|
||||
this.$message.error(this.$t(`缺少字段名`))
|
||||
return
|
||||
}
|
||||
if (!field.summary) {
|
||||
this.$message.error(this.$t(`缺少字段说明`))
|
||||
return
|
||||
}
|
||||
if (!field.example) {
|
||||
this.$message.error(this.$t(`缺少字段示例值`))
|
||||
return
|
||||
}
|
||||
if (!field.type) {
|
||||
this.$message.error(this.$t(`缺少字段类型`))
|
||||
return
|
||||
}
|
||||
}
|
||||
if (primaryCount !== 1) {
|
||||
this.$message.error(this.$t(`主键字段数量不为1`))
|
||||
return
|
||||
}
|
||||
|
||||
const valid = await this.$refs.form.validate().catch(() => {})
|
||||
if (!valid) {
|
||||
return false
|
||||
}
|
||||
this.loading = true
|
||||
try {
|
||||
await this.$API.sys_dev.generateCsCode.post(this.formCs)
|
||||
this.$message.success('生成完毕')
|
||||
const res = await this.$API.sys_dev.generateCsCode.post(this.form)
|
||||
this.$emit(`success`, res.data, this.mode)
|
||||
this.visible = false
|
||||
this.$message.success(this.$t(`操作成功`))
|
||||
} catch {}
|
||||
this.loading = false
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetime-range"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
@ -59,8 +59,8 @@
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
:context-extra="{ id: ['createdTime'] }"
|
||||
:context-menus="['id', 'userRegisterConfirm', 'userRegisterDept.name', 'userRegisterRole.name', 'enabled', 'createdTime']"
|
||||
:context-multi="{ id: ['createdTime'] }"
|
||||
:export-api="$API.sys_config.export"
|
||||
:params="query"
|
||||
:query-api="$API.sys_config.pagedQuery"
|
||||
|
@ -41,7 +41,7 @@
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetime-range"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
@ -66,8 +66,8 @@
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
:context-extra="{ id: ['createdTime'] }"
|
||||
:context-menus="['id', 'name', 'sort', 'enabled', 'createdTime', 'summary']"
|
||||
:context-multi="{ id: ['createdTime'] }"
|
||||
:default-sort="{ prop: 'sort', order: 'descending' }"
|
||||
:export-api="$API.sys_dept.export"
|
||||
:params="query"
|
||||
|
@ -41,7 +41,7 @@
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetime-range"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
@ -70,8 +70,8 @@
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
:before-post="(data) => data.dynamicFilter.filters.length > 0"
|
||||
:context-extra="{ id: ['createdTime'] }"
|
||||
:context-menus="['key', 'value', 'enabled', 'createdTime', 'id', 'summary']"
|
||||
:context-multi="{ id: ['createdTime'] }"
|
||||
:default-sort="{ prop: 'id', order: 'descending' }"
|
||||
:export-api="$API.sys_dic.exportContent"
|
||||
:params="query"
|
||||
|
@ -55,7 +55,7 @@
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetime-range"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
@ -81,8 +81,8 @@
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
:before-post="(data) => data.dynamicFilter.filters.length > 0"
|
||||
:context-extra="{ id: ['createdTime'] }"
|
||||
:context-menus="['title', 'enabled', 'createdTime', 'id', 'visibility']"
|
||||
:context-multi="{ id: ['createdTime'] }"
|
||||
:default-sort="{ prop: 'id', order: 'descending' }"
|
||||
:export-api="$API.sys_doc.exportContent"
|
||||
:params="query"
|
||||
|
@ -31,7 +31,7 @@
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetime-range"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
|
@ -78,7 +78,7 @@
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetime-range"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
@ -112,6 +112,7 @@
|
||||
}
|
||||
}
|
||||
"
|
||||
:context-extra="{ id: ['createdTime'] }"
|
||||
:context-menus="[
|
||||
'id',
|
||||
'jobName',
|
||||
@ -125,7 +126,6 @@
|
||||
'createdTime',
|
||||
'lastDuration',
|
||||
]"
|
||||
:context-multi="{ id: ['createdTime'] }"
|
||||
:default-sort="{ prop: 'lastExecTime', order: 'descending' }"
|
||||
:export-api="$API.sys_job.export"
|
||||
:page-size="100"
|
||||
|
@ -81,7 +81,7 @@
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetime-range"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
@ -98,8 +98,8 @@
|
||||
}
|
||||
}
|
||||
"
|
||||
:context-extra="{ id: ['createdTime'] }"
|
||||
:context-menus="['id', 'duration', 'httpMethod', 'requestUrl', 'httpStatusCode', 'createdTime', 'jobId', 'responseBody']"
|
||||
:context-multi="{ id: ['createdTime'] }"
|
||||
:default-sort="{ prop: 'id', order: 'descending' }"
|
||||
:export-api="$API.sys_job.exportRecord"
|
||||
:params="query"
|
||||
|
@ -93,7 +93,7 @@
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetime-range"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
@ -101,8 +101,8 @@
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
:context-extra="{ id: ['createdTime'] }"
|
||||
:context-menus="['id', 'httpStatusCode', 'loginUserName', 'createdClientIp', 'createdUserAgent', 'createdTime']"
|
||||
:context-multi="{ id: ['createdTime'] }"
|
||||
:context-opers="['view']"
|
||||
:default-sort="{ prop: 'id', order: 'descending' }"
|
||||
:export-api="$API.sys_loginlog.export"
|
||||
|
@ -110,7 +110,7 @@
|
||||
@reset="Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetime-range"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
@ -118,8 +118,8 @@
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
:context-extra="{ id: ['createdTime'] }"
|
||||
:context-menus="['id', 'httpStatusCode', 'apiPathCrc32', 'ownerId', 'httpMethod', 'duration', 'createdClientIp', 'createdTime']"
|
||||
:context-multi="{ id: ['createdTime'] }"
|
||||
:context-opers="[]"
|
||||
:default-sort="{ prop: 'createdTime', order: 'descending' }"
|
||||
:export-api="$API.sys_requestlog.export"
|
||||
|
@ -46,7 +46,7 @@
|
||||
@reset="Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetime-range"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
@ -57,8 +57,8 @@
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
:context-extra="{ id: ['createdTime'] }"
|
||||
:context-menus="['id', 'createdUserName', 'msgType', 'title', 'summary', 'createdTime']"
|
||||
:context-multi="{ id: ['createdTime'] }"
|
||||
:default-sort="{ prop: 'id', order: 'descending' }"
|
||||
:export-api="$API.sys_sitemsg.export"
|
||||
:params="query"
|
||||
|
@ -71,7 +71,7 @@
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetime-range"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
@ -81,6 +81,7 @@
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
:context-extra="{ id: ['createdTime'], ownerId: ['owner.userName'] }"
|
||||
:context-menus="[
|
||||
'id',
|
||||
'ownerId',
|
||||
@ -93,7 +94,6 @@
|
||||
'depositOrderStatus',
|
||||
'actualPayAmount',
|
||||
]"
|
||||
:context-multi="{ id: ['createdTime'], ownerId: ['owner.userName'] }"
|
||||
:context-opers="['view']"
|
||||
:default-sort="{ prop: 'id', order: 'descending' }"
|
||||
:export-api="$API.sys_depositorder.export"
|
||||
|
@ -89,7 +89,7 @@
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetime-range"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
@ -114,8 +114,8 @@
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
:context-extra="{ id: ['createdTime'] }"
|
||||
:context-menus="['id', 'name', 'sort', 'enabled', 'ignorePermissionControl', 'dataScope', 'displayDashboard', 'createdTime']"
|
||||
:context-multi="{ id: ['createdTime'] }"
|
||||
:default-sort="{ prop: 'sort', order: 'descending' }"
|
||||
:export-api="$API.sys_role.export"
|
||||
:params="query"
|
||||
|
108
src/frontend/admin/src/views/sys/template/index.vue
Normal file
108
src/frontend/admin/src/views/sys/template/index.vue
Normal file
@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<na-table-page
|
||||
:columns="{
|
||||
id: {
|
||||
label: $t(`唯一编码`),
|
||||
is: `na-col-id`,
|
||||
extra: [`createdTime`],
|
||||
width: 170,
|
||||
show: [`list`, `view`],
|
||||
searchable: `eq`,
|
||||
},
|
||||
name: {
|
||||
label: $t(`名字`),
|
||||
width: 150,
|
||||
show: [`list`, `view`, `add`, `edit`],
|
||||
rule: {
|
||||
required: true,
|
||||
},
|
||||
searchable: `eq`,
|
||||
},
|
||||
gender: {
|
||||
label: $t(`性别`),
|
||||
is: `na-col-indicator`,
|
||||
enum: `genders`,
|
||||
width: 100,
|
||||
align: `center`,
|
||||
countBy: true,
|
||||
show: [`list`, `view`, `add`, `edit`],
|
||||
},
|
||||
sort: {
|
||||
label: $t(`排序`),
|
||||
align: `right`,
|
||||
width: 100,
|
||||
show: [`list`, `view`, `add`, `edit`],
|
||||
rule: {
|
||||
required: true,
|
||||
validator: (rule, value, callback) => {
|
||||
if (/^-?\d+$/.test(value)) callback()
|
||||
else callback(new Error())
|
||||
},
|
||||
},
|
||||
},
|
||||
summary: {
|
||||
label: $t(`备注`),
|
||||
show: [`list`, `view`, `add`, `edit`],
|
||||
searchable: `contains`,
|
||||
},
|
||||
enabled: {
|
||||
label: $t(`启用`),
|
||||
width: 100,
|
||||
align: `center`,
|
||||
countBy: true,
|
||||
show: [`list`, `view`],
|
||||
isBoolean: true,
|
||||
},
|
||||
createdTime: {
|
||||
label: $t(`创建时间`),
|
||||
show: [`view`],
|
||||
},
|
||||
version: {
|
||||
label: $t(`数据版本`),
|
||||
show: [`view`],
|
||||
},
|
||||
}"
|
||||
:operations="[`add`, `del`, `edit`]"
|
||||
:search-controls="[
|
||||
{
|
||||
type: `input`,
|
||||
field: [`root`, `keywords`],
|
||||
placeholder: $t(`消息编号 / 消息主题 / 消息内容`),
|
||||
style: `width:25rem`,
|
||||
},
|
||||
]"
|
||||
:select-filters="[
|
||||
{
|
||||
title: $t(`是否启用`),
|
||||
key: `Enabled`,
|
||||
enumName: `Enabled`,
|
||||
isBoolean: [
|
||||
{ label: $t(`启用`), value: true },
|
||||
{ label: $t(`禁用`), value: false },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: $t(`性别`),
|
||||
key: `Gender`,
|
||||
enumName: `genders`,
|
||||
},
|
||||
]"
|
||||
:summary="$t(`代码模板`)"
|
||||
entity-name="sys_codetemplate" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
components: {},
|
||||
computed: {},
|
||||
created() {},
|
||||
data() {},
|
||||
inject: [`reload`],
|
||||
methods: {},
|
||||
mounted() {},
|
||||
props: [`keywords`],
|
||||
watch: {},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped />
|
@ -69,7 +69,7 @@
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetime-range"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
@ -77,6 +77,7 @@
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
:context-extra="{ id: ['createdTime'], ownerId: ['owner.userName'] }"
|
||||
:context-menus="[
|
||||
'id',
|
||||
'ownerId',
|
||||
@ -88,7 +89,6 @@
|
||||
'owner.userName',
|
||||
'tradeDirection',
|
||||
]"
|
||||
:context-multi="{ id: ['createdTime'], ownerId: ['owner.userName'] }"
|
||||
:context-opers="['view']"
|
||||
:default-sort="{ prop: 'id', order: 'descending' }"
|
||||
:export-api="$API.sys_wallettrade.export"
|
||||
|
@ -49,7 +49,7 @@
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetime-range"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
@ -92,8 +92,8 @@
|
||||
</el-col>
|
||||
<el-col :lg="20">
|
||||
<sc-table
|
||||
:context-extra="{ id: ['createdTime'] }"
|
||||
:context-menus="['id', 'userName', 'mobile', 'email', 'enabled', 'createdTime', 'lastLoginTime']"
|
||||
:context-multi="{ id: ['createdTime'] }"
|
||||
:context-opers="['view', 'edit']"
|
||||
:default-sort="{ prop: 'id', order: 'descending' }"
|
||||
:export-api="$API.sys_user.export"
|
||||
|
@ -51,7 +51,7 @@
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetime-range"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
@ -59,6 +59,7 @@
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
:context-extra="{ id: ['createdTime'], ownerId: ['owner.userName'] }"
|
||||
:context-menus="[
|
||||
'id',
|
||||
'ownerId',
|
||||
@ -71,7 +72,6 @@
|
||||
'totalExpenditure',
|
||||
'modifiedTime',
|
||||
]"
|
||||
:context-multi="{ id: ['createdTime'], ownerId: ['owner.userName'] }"
|
||||
:context-opers="['view']"
|
||||
:default-sort="{ prop: 'id', order: 'descending' }"
|
||||
:export-api="$API.sys_userwallet.export"
|
||||
|
Reference in New Issue
Block a user