diff --git a/docs/demo/src/WTA.Application/Identity/Data/IdentityDbSeed.cs b/docs/demo/src/WTA.Application/Identity/Data/IdentityDbSeed.cs index 53d36ea6..484ffe8a 100644 --- a/docs/demo/src/WTA.Application/Identity/Data/IdentityDbSeed.cs +++ b/docs/demo/src/WTA.Application/Identity/Data/IdentityDbSeed.cs @@ -104,6 +104,7 @@ public class IdentityDbSeed : IDbSeed // 用户初始化 var superUser = new User { + DepartmentId = context.Set().FirstOrDefault()?.Id, IsReadonly = true, UserName = "super", NormalizedUserName = "super".Normalize(), @@ -140,18 +141,18 @@ public class IdentityDbSeed : IDbSeed Order = -3, }.UpdateId().UpdatePath()); - //context.Set().Add(new Permission - //{ - // IsExternal = true, - // IsReadonly = true, - // Type = PermissionType.Resource, - // Name = "帮助", - // Number = "help", - // Path = "https://element-plus.org/", - // Method = "GET", - // Icon = "ep-link", - // Order = 1000, - //}.UpdateId().UpdatePath()); + context.Set().Add(new Permission + { + IsExternal = true, + IsReadonly = true, + Type = PermissionType.Resource, + Name = "帮助", + Number = "help", + Path = "https://element-plus.org/", + Method = "GET", + Icon = "ep-link", + Order = 1000, + }.UpdateId().UpdatePath()); WebApp.Current.Assemblies.SelectMany(o => o.GetTypes()).Where(o => o.IsClass && !o.IsAbstract && o.IsAssignableTo(typeof(IResource))).ForEach(resourceType => { @@ -196,7 +197,7 @@ public class IdentityDbSeed : IDbSeed Path = $"{operation.TrimEnd("Async").ToSlugify()}", IsHidden = methodInfo.GetCustomAttributes().Any(), Method = method, - Icon = methodInfo.GetCustomAttribute()?.Icon ?? $"{operation.TrimEnd("Async").ToSlugify()}", + Icon = methodInfo.GetCustomAttribute()?.Icon ?? IconAttribute.File, Order = methodInfo.GetCustomAttribute()?.Order ?? OrderAttribute.Default, HtmlClass = methodInfo.GetCustomAttribute()?.Class ?? HtmlClassAttribute.Default, IsTop = methodInfo.GetCustomAttribute() != null diff --git a/docs/demo/src/WTA.Application/Identity/Entities/SystemManagement/User.cs b/docs/demo/src/WTA.Application/Identity/Entities/SystemManagement/User.cs index 46121d6b..f06a9930 100644 --- a/docs/demo/src/WTA.Application/Identity/Entities/SystemManagement/User.cs +++ b/docs/demo/src/WTA.Application/Identity/Entities/SystemManagement/User.cs @@ -27,6 +27,7 @@ public class User : BaseEntity [Navigation] public Guid? DepartmentId { get; set; } + [Navigation] public Guid? PostId { get; set; } public Department? Department { get; set; } diff --git a/docs/demo/src/WTA.Infrastructure/Resources/zh.json b/docs/demo/src/WTA.Infrastructure/Resources/zh.json index 38e894dc..3712a743 100644 --- a/docs/demo/src/WTA.Infrastructure/Resources/zh.json +++ b/docs/demo/src/WTA.Infrastructure/Resources/zh.json @@ -126,5 +126,6 @@ "ConnectionId": "连接Id", "IsOnline": "在线", "Heartbeat": "心跳", - "UserAgent": "用户代理" + "UserAgent": "用户代理", + "PostId": "岗位" } diff --git a/docs/demo/src/WTA.Shared/Application/PaginationModel.cs b/docs/demo/src/WTA.Shared/Application/PaginationModel.cs index 6a4a0565..f250645f 100644 --- a/docs/demo/src/WTA.Shared/Application/PaginationModel.cs +++ b/docs/demo/src/WTA.Shared/Application/PaginationModel.cs @@ -15,8 +15,10 @@ public class PaginationModel [DefaultValue(20)] public int PageSize { get; set; } = 20; - public string? OrderBy { get; set; } = $"{nameof(BaseEntity.Order)},{nameof(BaseEntity.CreatedOn)}"; public int TotalCount { get; set; } + public string? OrderBy { get; set; } = $"{nameof(BaseEntity.Order)},{nameof(BaseEntity.CreatedOn)}"; + public List Items { get; set; } = new List(); + public bool QueryAll { get; set; } public TSearchModel Query { get; set; } = Activator.CreateInstance(); } diff --git a/docs/demo/src/WTA.Shared/Attributes/NavigationAttribute.cs b/docs/demo/src/WTA.Shared/Attributes/NavigationAttribute.cs index 5ebae6b0..4adbac40 100644 --- a/docs/demo/src/WTA.Shared/Attributes/NavigationAttribute.cs +++ b/docs/demo/src/WTA.Shared/Attributes/NavigationAttribute.cs @@ -3,10 +3,10 @@ namespace WTA.Shared.Attributes; [AttributeUsage(AttributeTargets.Property)] public class NavigationAttribute : Attribute { - public NavigationAttribute(string? path = null) + public NavigationAttribute(string? property = null) { - this.Path = path; + this.Property = property; } - public string? Path { get; } + public string? Property { get; } } diff --git a/docs/demo/src/WTA.Shared/Controllers/GenericController.cs b/docs/demo/src/WTA.Shared/Controllers/GenericController.cs index 774c53c8..3b87ed33 100644 --- a/docs/demo/src/WTA.Shared/Controllers/GenericController.cs +++ b/docs/demo/src/WTA.Shared/Controllers/GenericController.cs @@ -1,3 +1,4 @@ +using DocumentFormat.OpenXml.Bibliography; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; @@ -44,7 +45,14 @@ public class GenericController o.ToObject()) diff --git a/docs/demo/src/WTA.Shared/Controllers/GenericControllerRouteConvention.cs b/docs/demo/src/WTA.Shared/Controllers/GenericControllerRouteConvention.cs index c9dac766..d9b19ad6 100644 --- a/docs/demo/src/WTA.Shared/Controllers/GenericControllerRouteConvention.cs +++ b/docs/demo/src/WTA.Shared/Controllers/GenericControllerRouteConvention.cs @@ -16,19 +16,19 @@ public class GenericControllerRouteConvention : IControllerModelConvention if (baseControllerType != null) { var routeTemplate = $"api/{{culture=zh}}/"; - var genericType = baseControllerType.GenericTypeArguments[0]; - var groupAttribute = genericType.GetCustomAttributes().FirstOrDefault(o => o.GetType().IsAssignableTo(typeof(GroupAttribute))); - var moduleAttribute = groupAttribute?.GetType().GetCustomAttributes() - .Where(o => o.GetType().IsGenericType && o.GetType().GetGenericTypeDefinition() == typeof(ModuleAttribute<>)) - .Select(o => o as ITypeAttribute).Select(o => o?.Type).FirstOrDefault(); - if (moduleAttribute != null) - { - routeTemplate += $"{moduleAttribute.Name.TrimEnd("Module").ToSlugify()}/"; - } - if (groupAttribute != null) - { - routeTemplate += $"{groupAttribute.GetType().Name.TrimEnd("Attribute").ToSlugify()}/"; - } + //var genericType = baseControllerType.GenericTypeArguments[0]; + //var groupAttribute = genericType.GetCustomAttributes().FirstOrDefault(o => o.GetType().IsAssignableTo(typeof(GroupAttribute))); + //var moduleAttribute = groupAttribute?.GetType().GetCustomAttributes() + // .Where(o => o.GetType().IsGenericType && o.GetType().GetGenericTypeDefinition() == typeof(ModuleAttribute<>)) + // .Select(o => o as ITypeAttribute).Select(o => o?.Type).FirstOrDefault(); + //if (moduleAttribute != null) + //{ + // routeTemplate += $"{moduleAttribute.Name.TrimEnd("Module").ToSlugify()}/"; + //} + //if (groupAttribute != null) + //{ + // routeTemplate += $"{groupAttribute.GetType().Name.TrimEnd("Attribute").ToSlugify()}/"; + //} routeTemplate += "[controller]/[action]"; controller.Selectors.Add(new SelectorModel { diff --git a/docs/demo/src/WTA.Shared/Extensions/JsonSchemaExtensions.cs b/docs/demo/src/WTA.Shared/Extensions/JsonSchemaExtensions.cs index 7e712780..4c08a696 100644 --- a/docs/demo/src/WTA.Shared/Extensions/JsonSchemaExtensions.cs +++ b/docs/demo/src/WTA.Shared/Extensions/JsonSchemaExtensions.cs @@ -67,7 +67,6 @@ public static class JsonSchemaExtensions { schema.Add("type", "array"); schema.TryAdd("multiple", true); - schema.TryAdd("url", "url"); schema.Add("items", meta.ElementMetadata.GetSchema(serviceProvider, meta)); } } @@ -132,6 +131,10 @@ public static class JsonSchemaExtensions schema.AddNotNull("description", meta.Description); schema.AddNotNull("format", meta.DataTypeName?.ToLowerCamelCase()); schema.AddNotNull("input", meta.TemplateHint?.ToLowerCamelCase()); + if(meta.TemplateHint=="select"&&meta.IsEnumerableType&& modelType.IsGenericType) + { + schema.TryAdd("url", modelType.GetGenericArguments().First().Name.ToSlugify()); + } if (meta is DefaultModelMetadata defaultModelMetadata) { @@ -144,9 +147,11 @@ public static class JsonSchemaExtensions } if (defaultModelMetadata.Attributes.Attributes.FirstOrDefault(o => o.GetType() == typeof(NavigationAttribute)) is NavigationAttribute navigationAttribute) { - var path = navigationAttribute.Path ?? $"{propertyName[..^2]}.Name"; + var path = navigationAttribute.Property ?? $"{propertyName[..^2]}.Name"; path = string.Join('.', path.Split('.').Select(o => o.ToLowerCamelCase())); schema.Add("navigation", path); + schema.Add("input", "select"); + schema.Add("url", propertyName[..^2].ToSlugify()); } if (defaultModelMetadata.Attributes.Attributes.FirstOrDefault(o => o.GetType() == typeof(ScaffoldColumnAttribute)) is ScaffoldColumnAttribute scaffoldColumnAttribute && !scaffoldColumnAttribute.Scaffold) diff --git a/docs/demo/src/WTA.Shared/SignalR/PageHub.cs b/docs/demo/src/WTA.Shared/SignalR/PageHub.cs index efb96e51..e509ab90 100644 --- a/docs/demo/src/WTA.Shared/SignalR/PageHub.cs +++ b/docs/demo/src/WTA.Shared/SignalR/PageHub.cs @@ -43,14 +43,14 @@ public class PageHub : Hub Login = DateTime.UtcNow, UserAgent = httpContext?.Request.Headers["User-Agent"] }); - this.Context.Features.Get()?.OnHeartbeat(o => - { - if (DateTime.Now.Second % 15 == 0) - { - using var scope = WebApp.Current.Services.CreateScope(); - scope.ServiceProvider.GetService()?.Publish(new SignalRHeartbeatEvent { ConnectionId = o?.ToString()! }); - } - }, this.Context.ConnectionId); + //this.Context.Features.Get()?.OnHeartbeat(o => + //{ + // if (DateTime.Now.Second % 15 == 0) + // { + // using var scope = WebApp.Current.Services.CreateScope(); + // scope.ServiceProvider.GetService()?.Publish(new SignalRHeartbeatEvent { ConnectionId = o?.ToString()! }); + // } + //}, this.Context.ConnectionId); } return base.OnConnectedAsync(); } diff --git a/docs/demo/src/WTA.Shared/WebApp.cs b/docs/demo/src/WTA.Shared/WebApp.cs index 9df23e6b..91abc803 100644 --- a/docs/demo/src/WTA.Shared/WebApp.cs +++ b/docs/demo/src/WTA.Shared/WebApp.cs @@ -182,7 +182,7 @@ public class WebApp { if (scope.ServiceProvider.GetService(serviceType) is IJobService jobService) { - scheduler.Schedule(() => jobService.Invoke()).Cron(cron); + //scheduler.Schedule(() => jobService.Invoke()).Cron(cron); } } } diff --git a/docs/demo/src/WTA/wwwroot/api/user.js b/docs/demo/src/WTA/wwwroot/api/user.js index 075c9d73..3fbce5ac 100644 --- a/docs/demo/src/WTA/wwwroot/api/user.js +++ b/docs/demo/src/WTA/wwwroot/api/user.js @@ -64,7 +64,7 @@ const logout = () => { }; const getUser = async () => { - const result = await post("system-management/user/info"); + const result = await post("user/info"); const user = result.data; user.roles = Enumerable.from(user.userRoles) .select((o) => o.role) diff --git a/docs/demo/src/WTA/wwwroot/components/form/form-input.js b/docs/demo/src/WTA/wwwroot/components/form/form-input.js index 02911edf..dd4bf61f 100644 --- a/docs/demo/src/WTA/wwwroot/components/form/form-input.js +++ b/docs/demo/src/WTA/wwwroot/components/form/form-input.js @@ -1,6 +1,7 @@ import html from "html"; import { ref, reactive, watch } from "vue"; import { dayjs } from "element-plus"; +import { post } from "../../request/index.js"; export default { template: html` @@ -20,8 +21,9 @@ export default { :multiple="!!schema.multiple" clearable style="width:100%" + :title="JSON.stringify(options)" > - + - + + `, props: ["modelValue", "mode", "parentSchema", "schema", "prop", "errors"], diff --git a/docs/demo/src/WTA/wwwroot/components/list/index.js b/docs/demo/src/WTA/wwwroot/components/list/index.js index b0ff184b..83a79e12 100644 --- a/docs/demo/src/WTA/wwwroot/components/list/index.js +++ b/docs/demo/src/WTA/wwwroot/components/list/index.js @@ -2,7 +2,7 @@ import html, { getProp } from "html"; import AppForm from "../form/index.js"; import { get, post } from "../../request/index.js"; import { ref, reactive } from "vue"; -import { useRoute } from "vue-router"; +import { useRoute, useRouter } from "vue-router"; import { useI18n } from "vue-i18n"; import SvgIcon from "../../components/icon/index.js"; import { schemaToModel } from "../../utils/index.js"; @@ -196,7 +196,7 @@ export default { const dialogVisible = ref(false); const route = useRoute(); const { t } = useI18n(); - const baseUrl = `${route.meta.path}`.substring(1); + const baseUrl = `${route.meta.controller}`; const indexUrl = `${baseUrl}/index`; const vm = (await get(indexUrl)).data; const schema = vm.schema; diff --git a/docs/demo/src/WTA/wwwroot/router/index.js b/docs/demo/src/WTA/wwwroot/router/index.js index 04217e44..b42427dc 100644 --- a/docs/demo/src/WTA/wwwroot/router/index.js +++ b/docs/demo/src/WTA/wwwroot/router/index.js @@ -95,6 +95,7 @@ const reset = (list, parent = null) => { if (o.type === "Resource") { item.component = import(`../views/${o.component ? o.component : "list"}.js`); } + item.meta.controller = item.path; item.meta.path = `${parent === null ? "/" : parent.meta.path + "/"}${item.path}`; item.meta.fullName = `${parent === null ? "" : parent.meta.title + " > "}${item.meta.title}`; if (o.type === "Resource") {