From 7ed30406c9f721a12f0b756ec8884a1882242b93 Mon Sep 17 00:00:00 2001 From: nsnail Date: Wed, 27 Nov 2024 15:52:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E2=9C=A8=20=E6=96=87=E6=A1=A3=E7=AE=A1?= =?UTF-8?q?=E7=90=86=20(#221)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: tk --- assets/res/NetAdmin.Fields.ln | 8 +- assets/res/NetAdmin.Statements.ln | 26 +- assets/seed-data/Sys_Menu.json | 25 +- package.json | 4 +- .../Extensions/UnitOfWorkManagerExtensions.cs | 7 +- .../DbMaps/Sys/Sys_DicCatalog.cs | 4 +- .../DbMaps/Sys/Sys_DocCatalog.cs | 73 +++++ .../DbMaps/Sys/Sys_DocContent.cs | 86 ++++++ .../Sys/Doc/Catalog/CreateDocCatalogReq.cs | 23 ++ .../Dto/Sys/Doc/Catalog/EditDocCatalogReq.cs | 11 + .../Dto/Sys/Doc/Catalog/QueryDocCatalogReq.cs | 8 + .../Dto/Sys/Doc/Catalog/QueryDocCatalogRsp.cs | 32 +++ .../Sys/Doc/Content/CreateDocContentReq.cs | 34 +++ .../Dto/Sys/Doc/Content/EditDocContentReq.cs | 11 + .../Sys/Doc/Content/ExportDocContentRsp.cs | 31 ++ .../Dto/Sys/Doc/Content/QueryDocContentReq.cs | 8 + .../Dto/Sys/Doc/Content/QueryDocContentRsp.cs | 38 +++ .../Doc/Content/SetDocContentEnabledReq.cs | 17 ++ .../Enums/Sys/ArchiveVisibilities.cs | 38 +++ .../NetAdmin.Host/Filters/ApiResultHandler.cs | 3 +- .../NetAdmin.Infrastructure/Constant/Chars.cs | 1 + .../Modules/Sys/IDocCatalogModule.cs | 11 + .../Modules/Sys/IDocContentModule.cs | 17 ++ .../Modules/Sys/IDocModule.cs | 95 +++++++ .../Sys/Dependency/IDocCatalogService.cs | 14 + .../Sys/Dependency/IDocContentService.cs | 19 ++ .../Services/Sys/Dependency/IDocService.cs | 6 + .../Services/Sys/DevService.cs | 9 +- .../Services/Sys/DicContentService.cs | 18 +- .../Services/Sys/DocCatalogService.cs | 150 ++++++++++ .../Services/Sys/DocContentService.cs | 202 +++++++++++++ .../Services/Sys/DocService.cs | 128 +++++++++ .../Sys/Dependency/IDocCache.cs | 6 + .../Sys/Dependency/IDocCatalogCache.cs | 6 + .../Sys/Dependency/IDocContentCache.cs | 6 + .../Sys/DocCache.cs | 111 ++++++++ .../Sys/DocCatalogCache.cs | 62 ++++ .../Sys/DocContentCache.cs | 68 +++++ .../Controllers/Sys/DocController.cs | 157 +++++++++++ src/frontend/admin/package.json | 8 +- src/frontend/admin/src/api/sys/doc.js | 194 +++++++++++++ src/frontend/admin/src/api/sys/doccatalog.js | 73 +++++ src/frontend/admin/src/api/sys/doccontent.js | 84 ++++++ .../admin/src/components/naColUser/index.vue | 2 +- .../admin/src/components/scCron/index.vue | 2 +- .../src/components/scIconSelect/index.vue | 2 +- .../src/components/scTable/fieldFilter.vue | 2 +- .../admin/src/components/scTable/index.vue | 4 +- .../admin/src/components/scUpload/index.vue | 2 +- src/frontend/admin/src/global.js | 2 - .../admin/src/layout/components/tasks.vue | 2 +- .../admin/src/layout/components/userbar.vue | 4 +- src/frontend/admin/src/locales/lang/en.js | 4 +- src/frontend/admin/src/locales/lang/zh-cn.js | 4 +- src/frontend/admin/src/router/systemRouter.js | 7 + .../admin/src/views/guest/register.vue | 4 +- .../admin/src/views/guest/view-doc.vue | 61 ++++ .../admin/src/views/home/widgets/index.vue | 4 +- .../src/views/home/work/components/myapp.vue | 2 +- .../admin/src/views/profile/account/index.vue | 6 +- .../src/views/profile/account/set-email.vue | 2 +- .../src/views/profile/account/set-mobile.vue | 2 +- .../views/profile/account/set-password.vue | 2 +- .../admin/src/views/sys/config/index.vue | 4 +- .../admin/src/views/sys/config/save.vue | 2 +- .../admin/src/views/sys/dept/index.vue | 4 +- .../admin/src/views/sys/dept/save.vue | 2 +- .../sys/dic/components/catalog-select.vue} | 0 .../admin/src/views/sys/dic/index.vue | 6 +- .../admin/src/views/sys/dic/list/index.vue | 36 +-- .../admin/src/views/sys/dic/list/save.vue | 12 +- .../src/views/sys/dic/list/savebatch.vue | 2 +- src/frontend/admin/src/views/sys/dic/save.vue | 23 +- .../sys/doc/components/catalog-select.vue | 52 ++++ .../admin/src/views/sys/doc/index.vue | 167 +++++++++++ .../admin/src/views/sys/doc/list/index.vue | 266 ++++++++++++++++++ .../admin/src/views/sys/doc/list/save.vue | 133 +++++++++ src/frontend/admin/src/views/sys/doc/save.vue | 84 ++++++ .../admin/src/views/sys/job/all/index.vue | 4 +- .../admin/src/views/sys/job/all/save.vue | 6 +- .../admin/src/views/sys/job/record/index.vue | 4 +- .../admin/src/views/sys/job/record/save.vue | 2 +- .../src/views/sys/log/operation/index.vue | 2 +- .../admin/src/views/sys/msg/index.vue | 4 +- src/frontend/admin/src/views/sys/msg/save.vue | 2 +- .../admin/src/views/sys/role/index.vue | 4 +- .../admin/src/views/sys/role/save.vue | 4 +- .../admin/src/views/sys/user/index.vue | 8 +- .../admin/src/views/sys/user/save.vue | 4 +- 89 files changed, 2748 insertions(+), 141 deletions(-) create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DocCatalog.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DocContent.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Catalog/CreateDocCatalogReq.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Catalog/EditDocCatalogReq.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Catalog/QueryDocCatalogReq.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Catalog/QueryDocCatalogRsp.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/CreateDocContentReq.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/EditDocContentReq.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/ExportDocContentRsp.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/QueryDocContentReq.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/QueryDocContentRsp.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/SetDocContentEnabledReq.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Enums/Sys/ArchiveVisibilities.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Application/Modules/Sys/IDocCatalogModule.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Application/Modules/Sys/IDocContentModule.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Application/Modules/Sys/IDocModule.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IDocCatalogService.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IDocContentService.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IDocService.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DocCatalogService.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DocContentService.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DocService.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/Dependency/IDocCache.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/Dependency/IDocCatalogCache.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/Dependency/IDocContentCache.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/DocCache.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/DocCatalogCache.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/DocContentCache.cs create mode 100644 src/backend/NetAdmin/NetAdmin.SysComponent.Host/Controllers/Sys/DocController.cs create mode 100644 src/frontend/admin/src/api/sys/doc.js create mode 100644 src/frontend/admin/src/api/sys/doccatalog.js create mode 100644 src/frontend/admin/src/api/sys/doccontent.js create mode 100644 src/frontend/admin/src/views/guest/view-doc.vue rename src/frontend/admin/src/{components/naDicCatalog/index.vue => views/sys/dic/components/catalog-select.vue} (100%) create mode 100644 src/frontend/admin/src/views/sys/doc/components/catalog-select.vue create mode 100644 src/frontend/admin/src/views/sys/doc/index.vue create mode 100644 src/frontend/admin/src/views/sys/doc/list/index.vue create mode 100644 src/frontend/admin/src/views/sys/doc/list/save.vue create mode 100644 src/frontend/admin/src/views/sys/doc/save.vue diff --git a/assets/res/NetAdmin.Fields.ln b/assets/res/NetAdmin.Fields.ln index c0eb7171..3bcbd345 100644 --- a/assets/res/NetAdmin.Fields.ln +++ b/assets/res/NetAdmin.Fields.ln @@ -18,7 +18,6 @@ 作业名称 作业状态 保密 -保密 信息 倒序排序 全部数据 @@ -43,7 +42,6 @@ 大于 大于等于 女 -女 字典内容导出 宕机 客户端IP @@ -74,6 +72,9 @@ 插入种子数据 操作系统 数据范围 +文档内容 +文档内容导出 +文档标题 无效操作 无效输入 无限权限 @@ -100,7 +101,6 @@ 用户导出 电子邮箱 男 -男 登录 登录名 登录日志导出 @@ -110,8 +110,6 @@ 空闲 站内信导出 等于 -等于 -等于 等待发送 管理模块 系统模块 diff --git a/assets/res/NetAdmin.Statements.ln b/assets/res/NetAdmin.Statements.ln index 05cb90f4..810dd086 100644 --- a/assets/res/NetAdmin.Statements.ln +++ b/assets/res/NetAdmin.Statements.ln @@ -19,15 +19,10 @@ XML注释文件不存在 字典名称不能为空 字典目录不存在 字典目录编号不能为空 -字典目录编号不能为空 字典编码不能为空 学历不正确 +完全公开 密码不能为空 -密码不能为空 -密码不能为空 -密码不能为空 -已处理完毕 -已处理完毕 已处理完毕 并发冲突_请稍后重试 开始事务 @@ -41,6 +36,12 @@ XML注释文件不存在 数据库服务器时钟偏移 数据库结构同步完成 文件不能为空 +文档内容不能为空 +文档分类不存在 +文档分类名称不能为空 +文档分类编号不能为空 +文档分类编码不能为空 +文档标题不能为空 新密码不能为空 新手机号码验证码不正确 无效端口号 @@ -53,28 +54,24 @@ XML注释文件不存在 时间计划不能为空 未指定部门 未获取到待执行任务 +档案可见性不正确 模块名称不能为空 模块类型不能为空 模块说明不能为空 此节点已下线 -此节点已下线 民族不正确 消息主题不能为空 消息内容不能为空 父节点不存在 用户不存在 用户名不能为空 -用户名不能为空 -用户名不能为空 用户名不能是手机号码 用户名或密码错误 用户名长度4位以上 用户头像不能为空 用户编号不存在 +登录用户 目标设备不能为空 -目标设备不能为空 -短信验证请求不能为空 -短信验证请求不能为空 短信验证请求不能为空 种子数据插入完成 站内信不存在 @@ -82,8 +79,7 @@ XML注释文件不存在 站内信类型不正确 缓存键不能为空 网络地址不正确 -网络地址不正确 -网络地址不正确 +自己可见 菜单名称不能为空 菜单标题不能为空 菜单类型不正确 @@ -109,11 +105,11 @@ XML注释文件不存在 邀请码不正确 邮箱验证码不正确 部门不存在 +部门可见 部门名称不能为空 配置文件初始化完毕 键值不能为空 键名称不能为空 -键名称不能为空 随机延时结束时间不正确 随机延时起始时间不正确 非JSON字符串 diff --git a/assets/seed-data/Sys_Menu.json b/assets/seed-data/Sys_Menu.json index fc614da3..2a212494 100644 --- a/assets/seed-data/Sys_Menu.json +++ b/assets/seed-data/Sys_Menu.json @@ -140,13 +140,34 @@ "Title": "缓存管理", "Type": 1 }, + // ------------------------------ 档案管理 ------------------------------ + { + "Icon": "sc-icon-App", + "Id": 616214756757512, + "Name": "archive", + "Path": "/archive", + "Sort": 98, + "Title": "档案管理", + "Type": 1 + }, + { + "Component": "sys/doc", + "Icon": "el-icon-set-up", + "Id": 616214756757516, + "Name": "archive/doc", + "ParentId": 616214756757512, + "Path": "/archive/doc", + "Sort": 100, + "Title": "文档管理", + "Type": 1 + }, // ------------------------------ 日志管理 ------------------------------ { "Icon": "el-icon-tickets", "Id": 374792687640581, "Name": "log", "Path": "/log", - "Sort": 98, + "Sort": 97, "Title": "日志管理", "Type": 1 }, @@ -178,7 +199,7 @@ "Id": 373838105399301, "Name": "dev", "Path": "/dev", - "Sort": 97, + "Sort": 96, "Title": "开发管理", "Type": 1 }, diff --git a/package.json b/package.json index 06aaa99d..7c38e43a 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "devDependencies": { "cz-git": "^1.11.0", "commitizen": "^4.3.1", - "prettier": "^3.3.3", + "prettier": "^3.4.0", "standard-version": "^9.5.0" }, "config": { @@ -11,4 +11,4 @@ "path": "node_modules/cz-git" } } -} +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Application/Extensions/UnitOfWorkManagerExtensions.cs b/src/backend/NetAdmin/NetAdmin.Application/Extensions/UnitOfWorkManagerExtensions.cs index 2d2285db..be782b30 100644 --- a/src/backend/NetAdmin/NetAdmin.Application/Extensions/UnitOfWorkManagerExtensions.cs +++ b/src/backend/NetAdmin/NetAdmin.Application/Extensions/UnitOfWorkManagerExtensions.cs @@ -8,7 +8,7 @@ public static class UnitOfWorkManagerExtensions /// /// 事务操作 /// - public static async Task AtomicOperateAsync(this UnitOfWorkManager me, Func handle) + public static async Task AtomicOperateAsync(this UnitOfWorkManager me, Func handle, Func onErrorHandle = null) { var logger = LogHelper.Get(); using var unitOfWork = me.Begin(); @@ -25,6 +25,11 @@ public static class UnitOfWorkManagerExtensions logger?.Warn(ex); unitOfWork.Rollback(); logger?.Warn($"{Ln.事务已回滚}: {hashCode}"); + + if (onErrorHandle != null) { + await onErrorHandle().ConfigureAwait(false); + } + throw; } } diff --git a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DicCatalog.cs b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DicCatalog.cs index 8f578b95..e6954aac 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DicCatalog.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DicCatalog.cs @@ -16,7 +16,7 @@ public record Sys_DicCatalog : VersionEntity public IEnumerable Children { get; init; } /// - /// 字典编码 + /// 字典目录编码 /// [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)] [CsvIgnore] @@ -32,7 +32,7 @@ public record Sys_DicCatalog : VersionEntity public ICollection Contents { get; init; } /// - /// 字典名称 + /// 字典目录名称 /// [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)] [CsvIgnore] diff --git a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DocCatalog.cs b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DocCatalog.cs new file mode 100644 index 00000000..8e8c4d8d --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DocCatalog.cs @@ -0,0 +1,73 @@ +namespace NetAdmin.Domain.DbMaps.Sys; + +/// +/// 文档分类表 +/// +[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(Code), nameof(Code), true)] +[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_DocCatalog))] +public record Sys_DocCatalog : VersionEntity, IFieldOwner +{ + /// + /// 子节点 + /// + [CsvIgnore] + [JsonIgnore] + [Navigate(nameof(ParentId))] + public IEnumerable Children { get; init; } + + /// + /// 文档分类编码 + /// + [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)] + [CsvIgnore] + [JsonIgnore] + public virtual string Code { get; init; } + + /// + /// 文档内容集合 + /// + [CsvIgnore] + [JsonIgnore] + [Navigate(nameof(Sys_DocContent.CatalogId))] + public ICollection Contents { get; init; } + + /// + /// 文档分类名称 + /// + [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)] + [CsvIgnore] + [JsonIgnore] + public virtual string Name { get; init; } + + /// + /// 拥有者 + /// + [CsvIgnore] + [JsonIgnore] + [Navigate(nameof(OwnerId))] + public Sys_User Owner { get; init; } + + /// + /// 拥有者部门编号 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual long? OwnerDeptId { get; init; } + + /// + /// 拥有者用户编号 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual long? OwnerId { get; init; } + + /// + /// 父编号 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual long ParentId { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DocContent.cs b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DocContent.cs new file mode 100644 index 00000000..45d72a72 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/DbMaps/Sys/Sys_DocContent.cs @@ -0,0 +1,86 @@ +using NetAdmin.Domain.Enums.Sys; + +namespace NetAdmin.Domain.DbMaps.Sys; + +/// +/// 文档内容表 +/// +[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_DocContent))] +public record Sys_DocContent : VersionEntity, IFieldEnabled, IFieldOwner +{ + /// + /// 文档正文 + /// + #if DBTYPE_SQLSERVER + [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_MAX)] + #else + [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)] + #endif + [CsvIgnore] + [JsonIgnore] + public virtual string Body { get; init; } + + /// + /// 文档分类 + /// + [CsvIgnore] + [JsonIgnore] + [Navigate(nameof(CatalogId))] + public Sys_DocCatalog Catalog { get; init; } + + /// + /// 文档分类编号 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual long CatalogId { get; init; } + + /// + /// 是否启用 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual bool Enabled { get; init; } + + /// + /// 拥有者 + /// + [CsvIgnore] + [JsonIgnore] + [Navigate(nameof(OwnerId))] + public Sys_User Owner { get; init; } + + /// + /// 拥有者部门编号 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual long? OwnerDeptId { get; init; } + + /// + /// 拥有者用户编号 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual long? OwnerId { get; init; } + + /// + /// 文档标题 + /// + [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)] + [CsvIgnore] + [JsonIgnore] + public virtual string Title { get; init; } + + /// + /// 可见性 + /// + [Column] + [CsvIgnore] + [JsonIgnore] + public virtual ArchiveVisibilities Visibility { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Catalog/CreateDocCatalogReq.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Catalog/CreateDocCatalogReq.cs new file mode 100644 index 00000000..7d6d3031 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Catalog/CreateDocCatalogReq.cs @@ -0,0 +1,23 @@ +using NetAdmin.Domain.DbMaps.Sys; + +namespace NetAdmin.Domain.Dto.Sys.Doc.Catalog; + +/// +/// 请求:创建文档分类 +/// +public record CreateDocCatalogReq : Sys_DocCatalog +{ + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + [Required(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.文档分类编码不能为空))] + public override string Code { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + [Required(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.文档分类名称不能为空))] + public override string Name { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override long ParentId { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Catalog/EditDocCatalogReq.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Catalog/EditDocCatalogReq.cs new file mode 100644 index 00000000..80979822 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Catalog/EditDocCatalogReq.cs @@ -0,0 +1,11 @@ +namespace NetAdmin.Domain.Dto.Sys.Doc.Catalog; + +/// +/// 请求:编辑文档分类 +/// +public sealed record EditDocCatalogReq : CreateDocCatalogReq +{ + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override long Version { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Catalog/QueryDocCatalogReq.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Catalog/QueryDocCatalogReq.cs new file mode 100644 index 00000000..40fe3ee8 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Catalog/QueryDocCatalogReq.cs @@ -0,0 +1,8 @@ +using NetAdmin.Domain.DbMaps.Sys; + +namespace NetAdmin.Domain.Dto.Sys.Doc.Catalog; + +/// +/// 请求:查询文档分类 +/// +public sealed record QueryDocCatalogReq : Sys_DocCatalog; \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Catalog/QueryDocCatalogRsp.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Catalog/QueryDocCatalogRsp.cs new file mode 100644 index 00000000..a51f2f3c --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Catalog/QueryDocCatalogRsp.cs @@ -0,0 +1,32 @@ +using NetAdmin.Domain.DbMaps.Sys; + +namespace NetAdmin.Domain.Dto.Sys.Doc.Catalog; + +/// +/// 响应:查询文档分类 +/// +public sealed record QueryDocCatalogRsp : Sys_DocCatalog +{ + /// + public new IEnumerable Children { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string Code { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override long Id { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string Name { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override long ParentId { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override long Version { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/CreateDocContentReq.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/CreateDocContentReq.cs new file mode 100644 index 00000000..9a2132be --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/CreateDocContentReq.cs @@ -0,0 +1,34 @@ +using NetAdmin.Domain.DbMaps.Sys; +using NetAdmin.Domain.Enums.Sys; + +namespace NetAdmin.Domain.Dto.Sys.Doc.Content; + +/// +/// 请求:创建文档内容 +/// +public record CreateDocContentReq : Sys_DocContent +{ + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [Required(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.文档内容不能为空))] + public override string Body { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + [Required(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.文档分类编号不能为空))] + public override long CatalogId { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override bool Enabled { get; init; } = true; + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [Required(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.文档标题不能为空))] + public override string Title { get; init; } + + /// + [EnumDataType(typeof(ArchiveVisibilities), ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.档案可见性不正确))] + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override ArchiveVisibilities Visibility { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/EditDocContentReq.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/EditDocContentReq.cs new file mode 100644 index 00000000..f4bcf768 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/EditDocContentReq.cs @@ -0,0 +1,11 @@ +namespace NetAdmin.Domain.Dto.Sys.Doc.Content; + +/// +/// 请求:编辑文档内容 +/// +public sealed record EditDocContentReq : CreateDocContentReq +{ + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override long Version { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/ExportDocContentRsp.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/ExportDocContentRsp.cs new file mode 100644 index 00000000..5874dfbd --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/ExportDocContentRsp.cs @@ -0,0 +1,31 @@ +namespace NetAdmin.Domain.Dto.Sys.Doc.Content; + +/// +/// 响应:导出文档内容 +/// +public sealed record ExportDocContentRsp : QueryDocContentRsp +{ + /// + [CsvIndex(1)] + [CsvIgnore(false)] + [CsvName(nameof(Ln.文档内容))] + public override string Body { get; init; } + + /// + [CsvIndex(2)] + [CsvIgnore(false)] + [CsvName(nameof(Ln.创建时间))] + public override DateTime CreatedTime { get; init; } + + /// + [CsvIndex(3)] + [CsvIgnore(false)] + [CsvName(nameof(Ln.是否启用))] + public override bool Enabled { get; init; } + + /// + [CsvIndex(0)] + [CsvIgnore(false)] + [CsvName(nameof(Ln.文档标题))] + public override string Title { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/QueryDocContentReq.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/QueryDocContentReq.cs new file mode 100644 index 00000000..1d8319bd --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/QueryDocContentReq.cs @@ -0,0 +1,8 @@ +using NetAdmin.Domain.DbMaps.Sys; + +namespace NetAdmin.Domain.Dto.Sys.Doc.Content; + +/// +/// 请求:查询文档内容 +/// +public sealed record QueryDocContentReq : Sys_DocContent; \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/QueryDocContentRsp.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/QueryDocContentRsp.cs new file mode 100644 index 00000000..378a01f0 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/QueryDocContentRsp.cs @@ -0,0 +1,38 @@ +using NetAdmin.Domain.DbMaps.Sys; +using NetAdmin.Domain.Enums.Sys; + +namespace NetAdmin.Domain.Dto.Sys.Doc.Content; + +/// +/// 响应:查询文档内容 +/// +public record QueryDocContentRsp : Sys_DocContent +{ + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string Body { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override long CatalogId { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override DateTime CreatedTime { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override bool Enabled { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string Title { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override long Version { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override ArchiveVisibilities Visibility { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/SetDocContentEnabledReq.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/SetDocContentEnabledReq.cs new file mode 100644 index 00000000..4ddfde06 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Doc/Content/SetDocContentEnabledReq.cs @@ -0,0 +1,17 @@ +using NetAdmin.Domain.DbMaps.Sys; + +namespace NetAdmin.Domain.Dto.Sys.Doc.Content; + +/// +/// 请求:设置文档内容启用状态 +/// +public sealed record SetDocContentEnabledReq : Sys_DocContent +{ + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override bool Enabled { get; init; } + + /// + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override long Version { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Enums/Sys/ArchiveVisibilities.cs b/src/backend/NetAdmin/NetAdmin.Domain/Enums/Sys/ArchiveVisibilities.cs new file mode 100644 index 00000000..33e3e1cd --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Enums/Sys/ArchiveVisibilities.cs @@ -0,0 +1,38 @@ +namespace NetAdmin.Domain.Enums.Sys; + +/// +/// 档案可见性 +/// +[Export] +public enum ArchiveVisibilities +{ + /// + /// 完全公开 + /// + [ResourceDescription(nameof(Ln.完全公开))] + Public = 1 + + , + + /// + /// 登录用户 + /// + [ResourceDescription(nameof(Ln.登录用户))] + LogonUser = 2 + + , + + /// + /// 部门可见 + /// + [ResourceDescription(nameof(Ln.部门可见))] + DeptUser = 3 + + , + + /// + /// 自己可见 + /// + [ResourceDescription(nameof(Ln.自己可见))] + Self = 4 +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Host/Filters/ApiResultHandler.cs b/src/backend/NetAdmin/NetAdmin.Host/Filters/ApiResultHandler.cs index edd7d494..819c40d9 100644 --- a/src/backend/NetAdmin/NetAdmin.Host/Filters/ApiResultHandler.cs +++ b/src/backend/NetAdmin/NetAdmin.Host/Filters/ApiResultHandler.cs @@ -25,7 +25,8 @@ public abstract class ApiResultHandler { var naException = context.Exception switch { NetAdminException ex => ex - , _ => context.Exception.Message.Contains(Chars.FLG_DB_EXCEPTION_PRIMARY_KEY_CONFLICT) + , _ => context.Exception.Message.Contains(Chars.FLG_DB_EXCEPTION_PRIMARY_KEY_CONFLICT) || + context.Exception.Message.Contains(Chars.FLG_DB_EXCEPTION_UNIQUE_CONSTRAINT_CONFLICT) ? new NetAdminInvalidOperationException(Ln.记录已存在) : null }; diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/Constant/Chars.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/Constant/Chars.cs index 98f6e559..3cb8c92d 100644 --- a/src/backend/NetAdmin/NetAdmin.Infrastructure/Constant/Chars.cs +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/Constant/Chars.cs @@ -16,6 +16,7 @@ public static class Chars public const string FLG_CONTEXT_USER_INFO = nameof(FLG_CONTEXT_USER_INFO); public const string FLG_CRON_PER_SECS = "* * * * * *"; public const string FLG_DB_EXCEPTION_PRIMARY_KEY_CONFLICT = "PRIMARY KEY"; + public const string FLG_DB_EXCEPTION_UNIQUE_CONSTRAINT_CONFLICT = "UNIQUE constraint"; public const string FLG_DB_FIELD_TYPE_NVARCHAR = "nvarchar"; public const string FLG_DB_FIELD_TYPE_NVARCHAR_1022 = "nvarchar(1022)"; public const string FLG_DB_FIELD_TYPE_NVARCHAR_127 = "nvarchar(127)"; diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Modules/Sys/IDocCatalogModule.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Modules/Sys/IDocCatalogModule.cs new file mode 100644 index 00000000..3d3415c8 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Modules/Sys/IDocCatalogModule.cs @@ -0,0 +1,11 @@ +using NetAdmin.Domain.Dto.Sys.Doc.Catalog; + +namespace NetAdmin.SysComponent.Application.Modules.Sys; + +/// +/// 文档分类模块 +/// +public interface IDocCatalogModule : ICrudModule; \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Modules/Sys/IDocContentModule.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Modules/Sys/IDocContentModule.cs new file mode 100644 index 00000000..7a163cd2 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Modules/Sys/IDocContentModule.cs @@ -0,0 +1,17 @@ +using NetAdmin.Domain.Dto.Sys.Doc.Content; + +namespace NetAdmin.SysComponent.Application.Modules.Sys; + +/// +/// 文档内容模块 +/// +public interface IDocContentModule : ICrudModule +{ + /// + /// 启用/禁用文档内容 + /// + Task SetEnabledAsync(SetDocContentEnabledReq req); +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Modules/Sys/IDocModule.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Modules/Sys/IDocModule.cs new file mode 100644 index 00000000..a878d1b6 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Modules/Sys/IDocModule.cs @@ -0,0 +1,95 @@ +using NetAdmin.Domain.Dto.Sys.Doc.Catalog; +using NetAdmin.Domain.Dto.Sys.Doc.Content; + +namespace NetAdmin.SysComponent.Application.Modules.Sys; + +/// +/// 文档模块 +/// +public interface IDocModule +{ + /// + /// 批量删除文档分类 + /// + Task BulkDeleteCatalogAsync(BulkReq req); + + /// + /// 批量删除文档内容 + /// + Task BulkDeleteContentAsync(BulkReq req); + + /// + /// 创建文档分类 + /// + Task CreateCatalogAsync(CreateDocCatalogReq req); + + /// + /// 创建文档内容 + /// + Task CreateContentAsync(CreateDocContentReq req); + + /// + /// 删除文档分类 + /// + Task DeleteCatalogAsync(DelReq req); + + /// + /// 删除文档内容 + /// + Task DeleteContentAsync(DelReq req); + + /// + /// 编辑文档分类 + /// + Task EditCatalogAsync(EditDocCatalogReq req); + + /// + /// 编辑文档内容 + /// + Task EditContentAsync(EditDocContentReq req); + + /// + /// 导出文档内容 + /// + Task ExportContentAsync(QueryReq req); + + /// + /// 获取单个文档分类 + /// + Task GetCatalogAsync(QueryDocCatalogReq req); + + /// + /// 获取单个文档内容 + /// + Task GetContentAsync(QueryDocContentReq req); + + /// + /// 分页查询文档分类 + /// + Task> PagedQueryCatalogAsync(PagedQueryReq req); + + /// + /// 分页查询文档内容 + /// + Task> PagedQueryContentAsync(PagedQueryReq req); + + /// + /// 查询文档分类 + /// + Task> QueryCatalogAsync(QueryReq req); + + /// + /// 查询文档内容 + /// + Task> QueryContentAsync(QueryReq req); + + /// + /// 启用/禁用文档内容 + /// + Task SetEnabledAsync(SetDocContentEnabledReq req); + + /// + /// 浏览文档内容 + /// + Task ViewContentAsync(QueryDocContentReq req); +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IDocCatalogService.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IDocCatalogService.cs new file mode 100644 index 00000000..97ad8ac7 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IDocCatalogService.cs @@ -0,0 +1,14 @@ +using NetAdmin.Domain.Dto.Sys.Doc.Catalog; + +namespace NetAdmin.SysComponent.Application.Services.Sys.Dependency; + +/// +/// 文档分类服务 +/// +public interface IDocCatalogService : IService, IDocCatalogModule +{ + /// + /// 编辑文档分类 + /// + Task EditAsync(EditDocCatalogReq req); +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IDocContentService.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IDocContentService.cs new file mode 100644 index 00000000..297cb9d9 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IDocContentService.cs @@ -0,0 +1,19 @@ +using NetAdmin.Domain.Dto.Sys.Doc.Content; + +namespace NetAdmin.SysComponent.Application.Services.Sys.Dependency; + +/// +/// 文档内容服务 +/// +public interface IDocContentService : IService, IDocContentModule +{ + /// + /// 编辑文档内容 + /// + Task EditAsync(EditDocContentReq req); + + /// + /// 浏览文档内容 + /// + Task ViewAsync(QueryDocContentReq req); +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IDocService.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IDocService.cs new file mode 100644 index 00000000..8c39fa0b --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IDocService.cs @@ -0,0 +1,6 @@ +namespace NetAdmin.SysComponent.Application.Services.Sys.Dependency; + +/// +/// 文档服务 +/// +public interface IDocService : IService, IDocModule; \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DevService.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DevService.cs index 019acb90..52555274 100644 --- a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DevService.cs +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DevService.cs @@ -46,7 +46,14 @@ public sealed class DevService(IApiService apiService) : ServiceBase var appServicesDependencyDir = Path.Combine(appServicesDir, "Dependency"); // 数据契约层目录 - var dataDir = GetDir($"{req.Type}.Domain"); + string dataDir; + try { + dataDir = GetDir($"{req.Type}.Domain"); + } + catch (InvalidOperationException) { + dataDir = tplDataDir; + } + var dtoDir = Path.Combine(dataDir, "Dto", typeAbbr, req.ModuleName); var entityDir = Path.Combine(dataDir, "DbMaps", typeAbbr); diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DicContentService.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DicContentService.cs index e06d26bc..8a89710e 100644 --- a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DicContentService.cs +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DicContentService.cs @@ -26,10 +26,10 @@ public sealed class DicContentService(BasicRepository rpo) { req.ThrowIfInvalid(); return QueryInternal(req) - #if DBTYPE_SQLSERVER + #if DBTYPE_SQLSERVER .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait) - #endif - .CountAsync(); + #endif + .CountAsync(); } /// @@ -87,10 +87,10 @@ public sealed class DicContentService(BasicRepository rpo) { req.ThrowIfInvalid(); return QueryInternal(req) - #if DBTYPE_SQLSERVER + #if DBTYPE_SQLSERVER .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait) - #endif - .AnyAsync(); + #endif + .AnyAsync(); } /// @@ -162,7 +162,11 @@ public sealed class DicContentService(BasicRepository rpo) private ISelect QueryInternal(QueryReq req) { - var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); + var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter) + .WhereDynamic(req.Filter) + .WhereIf( // + req.Keywords?.Length > 0 + , a => a.Key.Contains(req.Keywords) || a.Value.Contains(req.Keywords) || a.Summary.Contains(req.Keywords)); // ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault switch (req.Order) { diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DocCatalogService.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DocCatalogService.cs new file mode 100644 index 00000000..7384a44e --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DocCatalogService.cs @@ -0,0 +1,150 @@ +using NetAdmin.Domain.DbMaps.Sys; +using NetAdmin.Domain.Dto.Sys.Doc.Catalog; + +namespace NetAdmin.SysComponent.Application.Services.Sys; + +/// +public sealed class DocCatalogService(BasicRepository rpo) // + : RepositoryService(rpo), IDocCatalogService +{ + /// + public async Task BulkDeleteAsync(BulkReq req) + { + req.ThrowIfInvalid(); + var ret = 0; + + // ReSharper disable once LoopCanBeConvertedToQuery + foreach (var item in req.Items) { + ret += await DeleteAsync(item).ConfigureAwait(false); + } + + return ret; + } + + /// + public Task CountAsync(QueryReq req) + { + req.ThrowIfInvalid(); + return QueryInternal(req) + #if DBTYPE_SQLSERVER + .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait) + #endif + .CountAsync(); + } + + /// + /// The_parent_node_does_not_exist + public async Task CreateAsync(CreateDocCatalogReq req) + { + req.ThrowIfInvalid(); + if (req.ParentId != 0 && !await Rpo.Where(a => a.Id == req.ParentId) + #if DBTYPE_SQLSERVER + .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait) + #endif + .AnyAsync() + .ConfigureAwait(false)) { + throw new NetAdminInvalidOperationException(Ln.父节点不存在); + } + + var ret = await Rpo.InsertAsync(req).ConfigureAwait(false); + return ret.Adapt(); + } + + /// + public async Task DeleteAsync(DelReq req) + { + req.ThrowIfInvalid(); + var ret = await Rpo.DeleteCascadeByDatabaseAsync(a => a.Id == req.Id).ConfigureAwait(false); + return ret.Count; + } + + /// + /// The_parent_node_does_not_exist + public async Task EditAsync(EditDocCatalogReq req) + { + req.ThrowIfInvalid(); + return req.ParentId == 0 || await Rpo.Where(a => a.Id == req.ParentId) + #if DBTYPE_SQLSERVER + .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait) + #endif + .AnyAsync() + .ConfigureAwait(false) + ? await UpdateAsync(req, null).ConfigureAwait(false) + : throw new NetAdminInvalidOperationException(Ln.父节点不存在); + } + + /// + public Task ExistAsync(QueryReq req) + { + req.ThrowIfInvalid(); + return QueryInternal(req) + #if DBTYPE_SQLSERVER + .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait) + #endif + .AnyAsync(); + } + + /// + public Task ExportAsync(QueryReq req) + { + req.ThrowIfInvalid(); + throw new NotImplementedException(); + } + + /// + public async Task GetAsync(QueryDocCatalogReq req) + { + req.ThrowIfInvalid(); + var ret = await QueryInternal(new QueryReq { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false); + return ret.Adapt(); + } + + /// + public async Task> PagedQueryAsync(PagedQueryReq req) + { + req.ThrowIfInvalid(); + var list = await QueryInternal(req) + .Page(req.Page, req.PageSize) + #if DBTYPE_SQLSERVER + .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait) + #endif + .Count(out var total) + .ToListAsync() + .ConfigureAwait(false); + + return new PagedQueryRsp(req.Page, req.PageSize, total, list.Adapt>()); + } + + /// + public async Task> QueryAsync(QueryReq req) + { + req.ThrowIfInvalid(); + var ret = await QueryInternal(req) + #if DBTYPE_SQLSERVER + .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait) + #endif + .ToTreeListAsync() + .ConfigureAwait(false); + return ret.Adapt>(); + } + + private ISelect QueryInternal(QueryReq req) + { + var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); + + // ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); + } + + ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); + if (!req.Prop?.Equals(nameof(req.Filter.Id), StringComparison.OrdinalIgnoreCase) ?? true) { + ret = ret.OrderByDescending(a => a.Id); + } + + return ret; + } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DocContentService.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DocContentService.cs new file mode 100644 index 00000000..c5a37c9c --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DocContentService.cs @@ -0,0 +1,202 @@ +using NetAdmin.Domain.DbMaps.Dependency.Fields; +using NetAdmin.Domain.DbMaps.Sys; +using NetAdmin.Domain.Dto.Sys.Doc.Content; +using NetAdmin.Domain.Enums.Sys; + +namespace NetAdmin.SysComponent.Application.Services.Sys; + +/// +public sealed class DocContentService(BasicRepository rpo) // + : RepositoryService(rpo), IDocContentService +{ + /// + public async Task BulkDeleteAsync(BulkReq req) + { + req.ThrowIfInvalid(); + var ret = 0; + + // ReSharper disable once LoopCanBeConvertedToQuery + foreach (var item in req.Items) { + ret += await DeleteAsync(item).ConfigureAwait(false); + } + + return ret; + } + + /// + public Task CountAsync(QueryReq req) + { + req.ThrowIfInvalid(); + return QueryInternal(req) + #if DBTYPE_SQLSERVER + .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait) + #endif + .CountAsync(); + } + + /// + /// Doctionary_directory_does_not_exist + public async Task CreateAsync(CreateDocContentReq req) + { + req.ThrowIfInvalid(); + if (!await Rpo.Orm.Select() + .Where(a => a.Id == req.CatalogId) + #if DBTYPE_SQLSERVER + .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait) + #endif + .AnyAsync() + .ConfigureAwait(false)) { + throw new NetAdminInvalidOperationException(Ln.文档分类不存在); + } + + var ret = await Rpo.InsertAsync(req).ConfigureAwait(false); + return ret.Adapt(); + } + + /// + public Task DeleteAsync(DelReq req) + { + req.ThrowIfInvalid(); + return Rpo.DeleteAsync(a => a.Id == req.Id); + } + + /// + /// Doctionary_directory_does_not_exist + public async Task EditAsync(EditDocContentReq req) + { + req.ThrowIfInvalid(); + if (!await Rpo.Orm.Select() + .Where(a => a.Id == req.CatalogId) + #if DBTYPE_SQLSERVER + .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait) + #endif + .AnyAsync() + .ConfigureAwait(false)) { + throw new NetAdminInvalidOperationException(Ln.文档分类不存在); + } + + #if DBTYPE_SQLSERVER + return (await UpdateReturnListAsync(req, null).ConfigureAwait(false)).FirstOrDefault()?.Adapt(); + #else + return await UpdateAsync(req, null, [nameof(IFieldOwner.OwnerId), nameof(IFieldOwner.OwnerDeptId)]).ConfigureAwait(false) > 0 + ? await GetAsync(new QueryDocContentReq { Id = req.Id }).ConfigureAwait(false) + : null; + #endif + } + + /// + public Task ExistAsync(QueryReq req) + { + req.ThrowIfInvalid(); + return QueryInternal(req) + #if DBTYPE_SQLSERVER + .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait) + #endif + .AnyAsync(); + } + + /// + public Task ExportAsync(QueryReq req) + { + req.ThrowIfInvalid(); + return ExportAsync(QueryInternal, req, Ln.文档内容导出); + } + + /// + public async Task GetAsync(QueryDocContentReq req) + { + req.ThrowIfInvalid(); + var ret = await QueryInternal(new QueryReq { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false); + return ret.Adapt(); + } + + /// + public async Task> PagedQueryAsync(PagedQueryReq req) + { + req.ThrowIfInvalid(); + var list = await QueryInternal(req) + .Page(req.Page, req.PageSize) + #if DBTYPE_SQLSERVER + .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait) + #endif + .Count(out var total) + .ToListAsync() + .ConfigureAwait(false); + + return new PagedQueryRsp(req.Page, req.PageSize, total, list.Adapt>()); + } + + /// + public async Task> QueryAsync(QueryReq req) + { + req.ThrowIfInvalid(); + var ret = await QueryInternal(req) + #if DBTYPE_SQLSERVER + .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait) + #endif + .Take(req.Count) + .ToListAsync() + .ConfigureAwait(false); + return ret.Adapt>(); + } + + /// + public Task SetEnabledAsync(SetDocContentEnabledReq req) + { + req.ThrowIfInvalid(); + return UpdateAsync(req, [nameof(Sys_DocContent.Enabled)]); + } + + /// + public async Task ViewAsync(QueryDocContentReq req) + { + req.ThrowIfInvalid(); + var ret = await QueryInternal(new QueryReq { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false); + + switch (ret?.Visibility) { + case ArchiveVisibilities.LogonUser: + if (UserToken == null) { + return null; + } + + break; + case ArchiveVisibilities.DeptUser: + if (UserToken == null || UserToken.DeptId != ret.OwnerDeptId) { + return null; + } + + break; + case ArchiveVisibilities.Self: + if (UserToken == null || UserToken.Id != ret.OwnerId) { + return null; + } + + break; + } + + return ret?.Enabled == false ? null : ret?.Adapt(); + } + + private ISelect QueryInternal(QueryReq req) + { + var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter) + .WhereDynamic(req.Filter) + .WhereIf( // + req.Keywords?.Length > 0, a => a.Title.Contains(req.Keywords)); + + // ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); + } + + ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); + if (!req.Prop?.Equals(nameof(req.Filter.Id), StringComparison.OrdinalIgnoreCase) ?? true) { + ret = ret.OrderByDescending(a => a.Id); + } + + return ret; + } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DocService.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DocService.cs new file mode 100644 index 00000000..d10ef374 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/DocService.cs @@ -0,0 +1,128 @@ +using NetAdmin.Domain.Dto.Sys.Doc.Catalog; +using NetAdmin.Domain.Dto.Sys.Doc.Content; + +namespace NetAdmin.SysComponent.Application.Services.Sys; + +/// +public sealed class DocService(IDocCatalogService catalogService, IDocContentService contentService) // + : ServiceBase, IDocService +{ + /// + public Task BulkDeleteCatalogAsync(BulkReq req) + { + req.ThrowIfInvalid(); + return catalogService.BulkDeleteAsync(req); + } + + /// + public Task BulkDeleteContentAsync(BulkReq req) + { + req.ThrowIfInvalid(); + return contentService.BulkDeleteAsync(req); + } + + /// + public Task CreateCatalogAsync(CreateDocCatalogReq req) + { + req.ThrowIfInvalid(); + return catalogService.CreateAsync(req); + } + + /// + public Task CreateContentAsync(CreateDocContentReq req) + { + req.ThrowIfInvalid(); + return contentService.CreateAsync(req); + } + + /// + public Task DeleteCatalogAsync(DelReq req) + { + req.ThrowIfInvalid(); + return catalogService.DeleteAsync(req); + } + + /// + public Task DeleteContentAsync(DelReq req) + { + req.ThrowIfInvalid(); + return contentService.DeleteAsync(req); + } + + /// + public Task EditCatalogAsync(EditDocCatalogReq req) + { + req.ThrowIfInvalid(); + return catalogService.EditAsync(req); + } + + /// + public Task EditContentAsync(EditDocContentReq req) + { + req.ThrowIfInvalid(); + return contentService.EditAsync(req); + } + + /// + public Task ExportContentAsync(QueryReq req) + { + req.ThrowIfInvalid(); + return contentService.ExportAsync(req); + } + + /// + public Task GetCatalogAsync(QueryDocCatalogReq req) + { + req.ThrowIfInvalid(); + return catalogService.GetAsync(req); + } + + /// + public Task GetContentAsync(QueryDocContentReq req) + { + req.ThrowIfInvalid(); + return contentService.GetAsync(req); + } + + /// + public Task> PagedQueryCatalogAsync(PagedQueryReq req) + { + req.ThrowIfInvalid(); + return catalogService.PagedQueryAsync(req); + } + + /// + public Task> PagedQueryContentAsync(PagedQueryReq req) + { + req.ThrowIfInvalid(); + return contentService.PagedQueryAsync(req); + } + + /// + public Task> QueryCatalogAsync(QueryReq req) + { + req.ThrowIfInvalid(); + return catalogService.QueryAsync(req); + } + + /// + public Task> QueryContentAsync(QueryReq req) + { + req.ThrowIfInvalid(); + return contentService.QueryAsync(req); + } + + /// + public Task SetEnabledAsync(SetDocContentEnabledReq req) + { + req.ThrowIfInvalid(); + return contentService.SetEnabledAsync(req); + } + + /// + public Task ViewContentAsync(QueryDocContentReq req) + { + req.ThrowIfInvalid(); + return contentService.ViewAsync(req); + } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/Dependency/IDocCache.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/Dependency/IDocCache.cs new file mode 100644 index 00000000..660640c8 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/Dependency/IDocCache.cs @@ -0,0 +1,6 @@ +namespace NetAdmin.SysComponent.Cache.Sys.Dependency; + +/// +/// 文档缓存 +/// +public interface IDocCache : ICache, IDocModule; \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/Dependency/IDocCatalogCache.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/Dependency/IDocCatalogCache.cs new file mode 100644 index 00000000..f1b51717 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/Dependency/IDocCatalogCache.cs @@ -0,0 +1,6 @@ +namespace NetAdmin.SysComponent.Cache.Sys.Dependency; + +/// +/// 文档分类缓存 +/// +public interface IDocCatalogCache : ICache, IDocCatalogModule; \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/Dependency/IDocContentCache.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/Dependency/IDocContentCache.cs new file mode 100644 index 00000000..e5328226 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/Dependency/IDocContentCache.cs @@ -0,0 +1,6 @@ +namespace NetAdmin.SysComponent.Cache.Sys.Dependency; + +/// +/// 文档内容缓存 +/// +public interface IDocContentCache : ICache, IDocContentModule; \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/DocCache.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/DocCache.cs new file mode 100644 index 00000000..5ffa6dd1 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/DocCache.cs @@ -0,0 +1,111 @@ +using NetAdmin.Domain.Dto.Sys.Doc.Catalog; +using NetAdmin.Domain.Dto.Sys.Doc.Content; + +namespace NetAdmin.SysComponent.Cache.Sys; + +/// +public sealed class DocCache(IDistributedCache cache, IDocService service) // + : DistributedCache(cache, service), IScoped, IDocCache +{ + /// + public Task BulkDeleteCatalogAsync(BulkReq req) + { + return Service.BulkDeleteCatalogAsync(req); + } + + /// + public Task BulkDeleteContentAsync(BulkReq req) + { + return Service.BulkDeleteContentAsync(req); + } + + /// + public Task CreateCatalogAsync(CreateDocCatalogReq req) + { + return Service.CreateCatalogAsync(req); + } + + /// + public Task CreateContentAsync(CreateDocContentReq req) + { + return Service.CreateContentAsync(req); + } + + /// + public Task DeleteCatalogAsync(DelReq req) + { + return Service.DeleteCatalogAsync(req); + } + + /// + public Task DeleteContentAsync(DelReq req) + { + return Service.DeleteContentAsync(req); + } + + /// + public Task EditCatalogAsync(EditDocCatalogReq req) + { + return Service.EditCatalogAsync(req); + } + + /// + public Task EditContentAsync(EditDocContentReq req) + { + return Service.EditContentAsync(req); + } + + /// + public Task ExportContentAsync(QueryReq req) + { + return Service.ExportContentAsync(req); + } + + /// + public Task GetCatalogAsync(QueryDocCatalogReq req) + { + return Service.GetCatalogAsync(req); + } + + /// + public Task GetContentAsync(QueryDocContentReq req) + { + return Service.GetContentAsync(req); + } + + /// + public Task> PagedQueryCatalogAsync(PagedQueryReq req) + { + return Service.PagedQueryCatalogAsync(req); + } + + /// + public Task> PagedQueryContentAsync(PagedQueryReq req) + { + return Service.PagedQueryContentAsync(req); + } + + /// + public Task> QueryCatalogAsync(QueryReq req) + { + return Service.QueryCatalogAsync(req); + } + + /// + public Task> QueryContentAsync(QueryReq req) + { + return Service.QueryContentAsync(req); + } + + /// + public Task SetEnabledAsync(SetDocContentEnabledReq req) + { + return Service.SetEnabledAsync(req); + } + + /// + public Task ViewContentAsync(QueryDocContentReq req) + { + return Service.ViewContentAsync(req); + } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/DocCatalogCache.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/DocCatalogCache.cs new file mode 100644 index 00000000..d71d4ce4 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/DocCatalogCache.cs @@ -0,0 +1,62 @@ +using NetAdmin.Domain.Dto.Sys.Doc.Catalog; + +namespace NetAdmin.SysComponent.Cache.Sys; + +/// +public sealed class DocCatalogCache(IDistributedCache cache, IDocCatalogService service) + : DistributedCache(cache, service), IScoped, IDocCatalogCache +{ + /// + public Task BulkDeleteAsync(BulkReq req) + { + return Service.BulkDeleteAsync(req); + } + + /// + public Task CountAsync(QueryReq req) + { + return Service.CountAsync(req); + } + + /// + public Task CreateAsync(CreateDocCatalogReq req) + { + return Service.CreateAsync(req); + } + + /// + public Task DeleteAsync(DelReq req) + { + return Service.DeleteAsync(req); + } + + /// + public Task ExistAsync(QueryReq req) + { + return Service.ExistAsync(req); + } + + /// + public Task ExportAsync(QueryReq req) + { + return Service.ExportAsync(req); + } + + /// + public Task GetAsync(QueryDocCatalogReq req) + { + return Service.GetAsync(req); + } + + /// + public Task> PagedQueryAsync(PagedQueryReq req) + { + return Service.PagedQueryAsync(req); + } + + /// + public Task> QueryAsync(QueryReq req) + { + return Service.QueryAsync(req); + } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/DocContentCache.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/DocContentCache.cs new file mode 100644 index 00000000..f3c503e7 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/DocContentCache.cs @@ -0,0 +1,68 @@ +using NetAdmin.Domain.Dto.Sys.Doc.Content; + +namespace NetAdmin.SysComponent.Cache.Sys; + +/// +public sealed class DocContentCache(IDistributedCache cache, IDocContentService service) + : DistributedCache(cache, service), IScoped, IDocContentCache +{ + /// + public Task BulkDeleteAsync(BulkReq req) + { + return Service.BulkDeleteAsync(req); + } + + /// + public Task CountAsync(QueryReq req) + { + return Service.CountAsync(req); + } + + /// + public Task CreateAsync(CreateDocContentReq req) + { + return Service.CreateAsync(req); + } + + /// + public Task DeleteAsync(DelReq req) + { + return Service.DeleteAsync(req); + } + + /// + public Task ExistAsync(QueryReq req) + { + return Service.ExistAsync(req); + } + + /// + public Task ExportAsync(QueryReq req) + { + return Service.ExportAsync(req); + } + + /// + public Task GetAsync(QueryDocContentReq req) + { + return Service.GetAsync(req); + } + + /// + public Task> PagedQueryAsync(PagedQueryReq req) + { + return Service.PagedQueryAsync(req); + } + + /// + public Task> QueryAsync(QueryReq req) + { + return Service.QueryAsync(req); + } + + /// + public Task SetEnabledAsync(SetDocContentEnabledReq req) + { + return Service.SetEnabledAsync(req); + } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Controllers/Sys/DocController.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Controllers/Sys/DocController.cs new file mode 100644 index 00000000..fe72db29 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Controllers/Sys/DocController.cs @@ -0,0 +1,157 @@ +using NetAdmin.Domain.Dto.Sys.Doc.Catalog; +using NetAdmin.Domain.Dto.Sys.Doc.Content; + +namespace NetAdmin.SysComponent.Host.Controllers.Sys; + +/// +/// 文档服务 +/// +[ApiDescriptionSettings(nameof(Sys), Module = nameof(Sys))] +[Produces(Chars.FLG_HTTP_HEADER_VALUE_APPLICATION_JSON)] +public sealed class DocController(IDocCache cache) : ControllerBase(cache), IDocModule +{ + /// + /// 批量删除文档分类 + /// + [Transaction] + public Task BulkDeleteCatalogAsync(BulkReq req) + { + return Cache.BulkDeleteCatalogAsync(req); + } + + /// + /// 批量删除文档内容 + /// + [Transaction] + public Task BulkDeleteContentAsync(BulkReq req) + { + return Cache.BulkDeleteContentAsync(req); + } + + /// + /// 创建文档分类 + /// + [Transaction] + public Task CreateCatalogAsync(CreateDocCatalogReq req) + { + return Cache.CreateCatalogAsync(req); + } + + /// + /// 创建文档内容 + /// + [Transaction] + public Task CreateContentAsync(CreateDocContentReq req) + { + return Cache.CreateContentAsync(req); + } + + /// + /// 删除文档分类 + /// + [Transaction] + public Task DeleteCatalogAsync(DelReq req) + { + return Cache.DeleteCatalogAsync(req); + } + + /// + /// 删除文档内容 + /// + [Transaction] + public Task DeleteContentAsync(DelReq req) + { + return Cache.DeleteContentAsync(req); + } + + /// + /// 编辑文档分类 + /// + [Transaction] + public Task EditCatalogAsync(EditDocCatalogReq req) + { + return Cache.EditCatalogAsync(req); + } + + /// + /// 编辑文档内容 + /// + [Transaction] + public Task EditContentAsync(EditDocContentReq req) + { + return Cache.EditContentAsync(req); + } + + /// + /// 导出文档内容 + /// + public Task ExportContentAsync(QueryReq req) + { + return Cache.ExportContentAsync(req); + } + + /// + /// 获取单个文档分类 + /// + public Task GetCatalogAsync(QueryDocCatalogReq req) + { + return Cache.GetCatalogAsync(req); + } + + /// + /// 获取单个文档内容 + /// + public Task GetContentAsync(QueryDocContentReq req) + { + return Cache.GetContentAsync(req); + } + + /// + /// 分页查询文档分类 + /// + public Task> PagedQueryCatalogAsync(PagedQueryReq req) + { + return Cache.PagedQueryCatalogAsync(req); + } + + /// + /// 分页查询文档内容 + /// + public Task> PagedQueryContentAsync(PagedQueryReq req) + { + return Cache.PagedQueryContentAsync(req); + } + + /// + /// 查询文档分类 + /// + public Task> QueryCatalogAsync(QueryReq req) + { + return Cache.QueryCatalogAsync(req); + } + + /// + /// 查询文档内容 + /// + public Task> QueryContentAsync(QueryReq req) + { + return Cache.QueryContentAsync(req); + } + + /// + /// 启用/禁用文档内容 + /// + public Task SetEnabledAsync(SetDocContentEnabledReq req) + { + return Cache.SetEnabledAsync(req); + } + + /// + /// 浏览文档内容 + /// + [AllowAnonymous] + public Task ViewContentAsync(QueryDocContentReq req) + { + return Cache.ViewContentAsync(req); + } +} \ No newline at end of file diff --git a/src/frontend/admin/package.json b/src/frontend/admin/package.json index 18ea6aa3..2a92b482 100644 --- a/src/frontend/admin/package.json +++ b/src/frontend/admin/package.json @@ -12,7 +12,7 @@ "@element-plus/icons-vue": "2.3.1", "ace-builds": "1.36.5", "aieditor": "1.2.7", - "axios": "1.7.7", + "axios": "1.7.8", "crypto-js": "4.2.0", "echarts": "5.5.1", "element-plus": "2.8.8", @@ -20,11 +20,11 @@ "markdown-it": "14.1.0", "markdown-it-emoji": "3.0.0", "nprogress": "0.2.0", - "sortablejs": "1.15.3", + "sortablejs": "1.15.4", "vkbeautify": "0.99.3", "vue": "3.5.13", "vue-i18n": "10.0.4", - "vue-router": "4.4.5", + "vue-router": "4.5.0", "vue3-ace-editor": "2.2.4", "vue3-json-viewer": "2.2.2", "vuedraggable": "4.0.3", @@ -32,7 +32,7 @@ }, "devDependencies": { "@vitejs/plugin-vue": "5.2.0", - "prettier": "3.3.3", + "prettier": "3.4.0", "prettier-plugin-organize-attributes": "1.0.0", "sass": "1.81.0", "terser": "5.36.0", diff --git a/src/frontend/admin/src/api/sys/doc.js b/src/frontend/admin/src/api/sys/doc.js new file mode 100644 index 00000000..a63bc840 --- /dev/null +++ b/src/frontend/admin/src/api/sys/doc.js @@ -0,0 +1,194 @@ +/** + * 文档服务 + * @module @/api/sys/doc + */ +import config from '@/config' +import http from '@/utils/request' +export default { + /** + * 批量删除文档分类 + */ + bulkDeleteCatalog: { + url: `${config.API_URL}/api/sys/doc/bulk.delete.catalog`, + name: `批量删除文档分类`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 批量删除文档内容 + */ + bulkDeleteContent: { + url: `${config.API_URL}/api/sys/doc/bulk.delete.content`, + name: `批量删除文档内容`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 创建文档分类 + */ + createCatalog: { + url: `${config.API_URL}/api/sys/doc/create.catalog`, + name: `创建文档分类`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 创建文档内容 + */ + createContent: { + url: `${config.API_URL}/api/sys/doc/create.content`, + name: `创建文档内容`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 删除文档分类 + */ + deleteCatalog: { + url: `${config.API_URL}/api/sys/doc/delete.catalog`, + name: `删除文档分类`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 删除文档内容 + */ + deleteContent: { + url: `${config.API_URL}/api/sys/doc/delete.content`, + name: `删除文档内容`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 编辑文档分类 + */ + editCatalog: { + url: `${config.API_URL}/api/sys/doc/edit.catalog`, + name: `编辑文档分类`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 编辑文档内容 + */ + editContent: { + url: `${config.API_URL}/api/sys/doc/edit.content`, + name: `编辑文档内容`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 导出文档内容 + */ + exportContent: { + url: `${config.API_URL}/api/sys/doc/export.content`, + name: `导出文档内容`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 获取单个文档分类 + */ + getCatalog: { + url: `${config.API_URL}/api/sys/doc/get.catalog`, + name: `获取单个文档分类`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 获取单个文档内容 + */ + getContent: { + url: `${config.API_URL}/api/sys/doc/get.content`, + name: `获取单个文档内容`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 分页查询文档分类 + */ + pagedQueryCatalog: { + url: `${config.API_URL}/api/sys/doc/paged.query.catalog`, + name: `分页查询文档分类`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 分页查询文档内容 + */ + pagedQueryContent: { + url: `${config.API_URL}/api/sys/doc/paged.query.content`, + name: `分页查询文档内容`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 查询文档分类 + */ + queryCatalog: { + url: `${config.API_URL}/api/sys/doc/query.catalog`, + name: `查询文档分类`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 查询文档内容 + */ + queryContent: { + url: `${config.API_URL}/api/sys/doc/query.content`, + name: `查询文档内容`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 启用/禁用文档内容 + */ + setEnabled: { + url: `${config.API_URL}/api/sys/doc/set.enabled`, + name: `启用/禁用文档内容`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 浏览文档内容 + */ + viewContent: { + url: `${config.API_URL}/api/sys/doc/view.content`, + name: `浏览文档内容`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, +} \ No newline at end of file diff --git a/src/frontend/admin/src/api/sys/doccatalog.js b/src/frontend/admin/src/api/sys/doccatalog.js new file mode 100644 index 00000000..a048098b --- /dev/null +++ b/src/frontend/admin/src/api/sys/doccatalog.js @@ -0,0 +1,73 @@ +/** + * 文档分类服务 + * @module @/api/sys/doc.catalog + */ +import config from '@/config' +import http from '@/utils/request' +export default { + /** + * 批量删除文档分类 + */ + bulkDelete: { + url: `${config.API_URL}/api/sys/doc.catalog/bulk.delete`, + name: `批量删除文档分类`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 文档分类计数 + */ + count: { + url: `${config.API_URL}/api/sys/doc.catalog/count`, + name: `文档分类计数`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 创建文档分类 + */ + create: { + url: `${config.API_URL}/api/sys/doc.catalog/create`, + name: `创建文档分类`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 删除文档分类 + */ + delete: { + url: `${config.API_URL}/api/sys/doc.catalog/delete`, + name: `删除文档分类`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 获取单个文档分类 + */ + get: { + url: `${config.API_URL}/api/sys/doc.catalog/get`, + name: `获取单个文档分类`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 分页查询文档分类 + */ + pagedQuery: { + url: `${config.API_URL}/api/sys/doc.catalog/paged.query`, + name: `分页查询文档分类`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, +} \ No newline at end of file diff --git a/src/frontend/admin/src/api/sys/doccontent.js b/src/frontend/admin/src/api/sys/doccontent.js new file mode 100644 index 00000000..26f5ba9e --- /dev/null +++ b/src/frontend/admin/src/api/sys/doccontent.js @@ -0,0 +1,84 @@ +/** + * 文档内容服务 + * @module @/api/sys/doc.content + */ +import config from '@/config' +import http from '@/utils/request' +export default { + /** + * 批量删除文档内容 + */ + bulkDelete: { + url: `${config.API_URL}/api/sys/doc.content/bulk.delete`, + name: `批量删除文档内容`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 文档内容计数 + */ + count: { + url: `${config.API_URL}/api/sys/doc.content/count`, + name: `文档内容计数`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 创建文档内容 + */ + create: { + url: `${config.API_URL}/api/sys/doc.content/create`, + name: `创建文档内容`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 删除文档内容 + */ + delete: { + url: `${config.API_URL}/api/sys/doc.content/delete`, + name: `删除文档内容`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 获取单个文档内容 + */ + get: { + url: `${config.API_URL}/api/sys/doc.content/get`, + name: `获取单个文档内容`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 分页查询文档内容 + */ + pagedQuery: { + url: `${config.API_URL}/api/sys/doc.content/paged.query`, + name: `分页查询文档内容`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 启用/禁用文档内容 + */ + setEnabled: { + url: `${config.API_URL}/api/sys/doc.content/set.enabled`, + name: `启用/禁用文档内容`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, +} \ No newline at end of file diff --git a/src/frontend/admin/src/components/naColUser/index.vue b/src/frontend/admin/src/components/naColUser/index.vue index ccac418b..db8e15dd 100644 --- a/src/frontend/admin/src/components/naColUser/index.vue +++ b/src/frontend/admin/src/components/naColUser/index.vue @@ -11,7 +11,7 @@

{{ $TOOL.getNestedProperty(row, $attrs.nestProp2) }}

- + diff --git a/src/frontend/admin/src/components/scCron/index.vue b/src/frontend/admin/src/components/scCron/index.vue index bbe62b28..3b527449 100644 --- a/src/frontend/admin/src/components/scCron/index.vue +++ b/src/frontend/admin/src/components/scCron/index.vue @@ -293,7 +293,7 @@ diff --git a/src/frontend/admin/src/components/scIconSelect/index.vue b/src/frontend/admin/src/components/scIconSelect/index.vue index a487dfe3..ba111c17 100644 --- a/src/frontend/admin/src/components/scIconSelect/index.vue +++ b/src/frontend/admin/src/components/scIconSelect/index.vue @@ -49,7 +49,7 @@ diff --git a/src/frontend/admin/src/components/scTable/fieldFilter.vue b/src/frontend/admin/src/components/scTable/fieldFilter.vue index 18590055..455b29f9 100644 --- a/src/frontend/admin/src/components/scTable/fieldFilter.vue +++ b/src/frontend/admin/src/components/scTable/fieldFilter.vue @@ -13,7 +13,7 @@ diff --git a/src/frontend/admin/src/components/scTable/index.vue b/src/frontend/admin/src/components/scTable/index.vue index f373d50b..c04f30fc 100644 --- a/src/frontend/admin/src/components/scTable/index.vue +++ b/src/frontend/admin/src/components/scTable/index.vue @@ -90,8 +90,8 @@ :hide-after="0" :title="$t('列设置')" :width="500" - @after-leave="customColumnShow = false" - @show="customColumnShow = true" + @after-leave="(customColumnShow = false)" + @show="(customColumnShow = true)" placement="top" trigger="click"> + + \ No newline at end of file diff --git a/src/frontend/admin/src/views/home/widgets/index.vue b/src/frontend/admin/src/views/home/widgets/index.vue index 763008a2..571d044c 100644 --- a/src/frontend/admin/src/views/home/widgets/index.vue +++ b/src/frontend/admin/src/views/home/widgets/index.vue @@ -77,7 +77,7 @@ - 添加自定义布局 + 添加自定义布局
@@ -115,7 +115,7 @@ diff --git a/src/frontend/admin/src/views/home/work/components/myapp.vue b/src/frontend/admin/src/views/home/work/components/myapp.vue index 597c6ceb..a5a42c4b 100644 --- a/src/frontend/admin/src/views/home/work/components/myapp.vue +++ b/src/frontend/admin/src/views/home/work/components/myapp.vue @@ -52,7 +52,7 @@
diff --git a/src/frontend/admin/src/views/profile/account/index.vue b/src/frontend/admin/src/views/profile/account/index.vue index 0020fb34..1d420784 100644 --- a/src/frontend/admin/src/views/profile/account/index.vue +++ b/src/frontend/admin/src/views/profile/account/index.vue @@ -36,18 +36,18 @@ diff --git a/src/frontend/admin/src/views/profile/account/set-email.vue b/src/frontend/admin/src/views/profile/account/set-email.vue index 4f7000b1..0013c7d9 100644 --- a/src/frontend/admin/src/views/profile/account/set-email.vue +++ b/src/frontend/admin/src/views/profile/account/set-email.vue @@ -28,7 +28,7 @@ diff --git a/src/frontend/admin/src/views/profile/account/set-mobile.vue b/src/frontend/admin/src/views/profile/account/set-mobile.vue index 46d74da3..71fa4973 100644 --- a/src/frontend/admin/src/views/profile/account/set-mobile.vue +++ b/src/frontend/admin/src/views/profile/account/set-mobile.vue @@ -33,7 +33,7 @@ diff --git a/src/frontend/admin/src/views/profile/account/set-password.vue b/src/frontend/admin/src/views/profile/account/set-password.vue index fdaeb7e0..251086f2 100644 --- a/src/frontend/admin/src/views/profile/account/set-password.vue +++ b/src/frontend/admin/src/views/profile/account/set-password.vue @@ -34,7 +34,7 @@ diff --git a/src/frontend/admin/src/views/sys/config/index.vue b/src/frontend/admin/src/views/sys/config/index.vue index f768c009..0bb74859 100644 --- a/src/frontend/admin/src/views/sys/config/index.vue +++ b/src/frontend/admin/src/views/sys/config/index.vue @@ -39,7 +39,7 @@ ref="search" />
- + @@ -106,7 +106,7 @@ diff --git a/src/frontend/admin/src/views/sys/config/save.vue b/src/frontend/admin/src/views/sys/config/save.vue index c3e5dc1b..914c0790 100644 --- a/src/frontend/admin/src/views/sys/config/save.vue +++ b/src/frontend/admin/src/views/sys/config/save.vue @@ -44,7 +44,7 @@
diff --git a/src/frontend/admin/src/views/sys/dept/index.vue b/src/frontend/admin/src/views/sys/dept/index.vue index e8dedc63..b306a153 100644 --- a/src/frontend/admin/src/views/sys/dept/index.vue +++ b/src/frontend/admin/src/views/sys/dept/index.vue @@ -46,7 +46,7 @@ ref="search" />
- + @@ -113,7 +113,7 @@ diff --git a/src/frontend/admin/src/views/sys/dept/save.vue b/src/frontend/admin/src/views/sys/dept/save.vue index 5ac84f43..59928e6e 100644 --- a/src/frontend/admin/src/views/sys/dept/save.vue +++ b/src/frontend/admin/src/views/sys/dept/save.vue @@ -42,7 +42,7 @@
diff --git a/src/frontend/admin/src/components/naDicCatalog/index.vue b/src/frontend/admin/src/views/sys/dic/components/catalog-select.vue similarity index 100% rename from src/frontend/admin/src/components/naDicCatalog/index.vue rename to src/frontend/admin/src/views/sys/dic/components/catalog-select.vue diff --git a/src/frontend/admin/src/views/sys/dic/index.vue b/src/frontend/admin/src/views/sys/dic/index.vue index 53719edd..86589faf 100644 --- a/src/frontend/admin/src/views/sys/dic/index.vue +++ b/src/frontend/admin/src/views/sys/dic/index.vue @@ -38,7 +38,7 @@
{{ - $t('字典分类') + $t('字典目录') }} @@ -48,7 +48,7 @@ @@ -106,7 +106,7 @@ export default { }, //字典目录增加 async add(id, code) { - this.dialog.save = { mode: 'add', data: { catalogId: id, code: code + '>' } } + this.dialog.save = { mode: 'add', data: { catalogId: id, code: code ? code + '>' : '' } } }, //字典目录编辑 async edit(data) { diff --git a/src/frontend/admin/src/views/sys/dic/list/index.vue b/src/frontend/admin/src/views/sys/dic/list/index.vue index 17953555..819a3d53 100644 --- a/src/frontend/admin/src/views/sys/dic/list/index.vue +++ b/src/frontend/admin/src/views/sys/dic/list/index.vue @@ -23,8 +23,8 @@ :controls="[ { type: 'input', - field: ['dy', 'keywords'], - placeholder: $t('项名 / 项值'), + field: ['root', 'keywords'], + placeholder: $t('项名 / 项值 / 备注'), style: 'width:20rem', }, ]" @@ -38,7 +38,7 @@
@@ -53,7 +53,7 @@ {{ $t('启用') }} {{ $t('禁用') }} - {{ + {{ $t('设置项值') }} @@ -64,7 +64,7 @@ + @@ -88,7 +89,6 @@ - @@ -222,25 +222,7 @@ export default { this.query.dynamicFilter.filters.push({ field: 'createdTime', operator: 'dateRange', - value: form.dy.createdTime, - }) - } - - if (form.dy.keywords) { - this.query.dynamicFilter.filters.push({ - logic: 'or', - filters: [ - { - field: 'key', - operator: 'contains', - value: form.dy.keywords, - }, - { - field: 'value', - operator: 'contains', - value: form.dy.keywords, - }, - ], + value: form.dy.createdTime.map((x) => x.replace(/ 00:00:00$/, '')), }) } diff --git a/src/frontend/admin/src/views/sys/dic/list/save.vue b/src/frontend/admin/src/views/sys/dic/list/save.vue index 88ee9116..b92e4566 100644 --- a/src/frontend/admin/src/views/sys/dic/list/save.vue +++ b/src/frontend/admin/src/views/sys/dic/list/save.vue @@ -4,8 +4,8 @@ - - + + @@ -30,15 +30,17 @@
\ No newline at end of file diff --git a/src/frontend/admin/src/views/sys/doc/index.vue b/src/frontend/admin/src/views/sys/doc/index.vue new file mode 100644 index 00000000..8e99f0e0 --- /dev/null +++ b/src/frontend/admin/src/views/sys/doc/index.vue @@ -0,0 +1,167 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/admin/src/views/sys/doc/list/index.vue b/src/frontend/admin/src/views/sys/doc/list/index.vue new file mode 100644 index 00000000..afbf0e42 --- /dev/null +++ b/src/frontend/admin/src/views/sys/doc/list/index.vue @@ -0,0 +1,266 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/admin/src/views/sys/doc/list/save.vue b/src/frontend/admin/src/views/sys/doc/list/save.vue new file mode 100644 index 00000000..32b2a335 --- /dev/null +++ b/src/frontend/admin/src/views/sys/doc/list/save.vue @@ -0,0 +1,133 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/admin/src/views/sys/doc/save.vue b/src/frontend/admin/src/views/sys/doc/save.vue new file mode 100644 index 00000000..fd08823e --- /dev/null +++ b/src/frontend/admin/src/views/sys/doc/save.vue @@ -0,0 +1,84 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/admin/src/views/sys/job/all/index.vue b/src/frontend/admin/src/views/sys/job/all/index.vue index 9e2e37cd..b69852f3 100644 --- a/src/frontend/admin/src/views/sys/job/all/index.vue +++ b/src/frontend/admin/src/views/sys/job/all/index.vue @@ -70,7 +70,7 @@ ref="search" />
- + @@ -223,7 +223,7 @@ diff --git a/src/frontend/admin/src/views/sys/job/all/save.vue b/src/frontend/admin/src/views/sys/job/all/save.vue index eb2f73f5..6e67eeac 100644 --- a/src/frontend/admin/src/views/sys/job/all/save.vue +++ b/src/frontend/admin/src/views/sys/job/all/save.vue @@ -45,7 +45,7 @@ :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'github_dark' : 'github'" lang="json" style="height: 10rem; width: 100%" /> - {{ $t('JSON 格式化') }} + {{ $t('JSON 格式化') }} - {{ $t('JSON 格式化') }} + {{ $t('JSON 格式化') }} @@ -121,7 +121,7 @@ diff --git a/src/frontend/admin/src/views/sys/job/record/index.vue b/src/frontend/admin/src/views/sys/job/record/index.vue index 4f9058c4..151a68d5 100644 --- a/src/frontend/admin/src/views/sys/job/record/index.vue +++ b/src/frontend/admin/src/views/sys/job/record/index.vue @@ -135,14 +135,14 @@ diff --git a/src/frontend/admin/src/views/sys/job/record/save.vue b/src/frontend/admin/src/views/sys/job/record/save.vue index 26975764..4454619e 100644 --- a/src/frontend/admin/src/views/sys/job/record/save.vue +++ b/src/frontend/admin/src/views/sys/job/record/save.vue @@ -39,7 +39,7 @@ diff --git a/src/frontend/admin/src/views/sys/log/operation/index.vue b/src/frontend/admin/src/views/sys/log/operation/index.vue index d0c923d1..df323c2f 100644 --- a/src/frontend/admin/src/views/sys/log/operation/index.vue +++ b/src/frontend/admin/src/views/sys/log/operation/index.vue @@ -182,7 +182,7 @@ diff --git a/src/frontend/admin/src/views/sys/msg/index.vue b/src/frontend/admin/src/views/sys/msg/index.vue index 9df84043..2c340d84 100644 --- a/src/frontend/admin/src/views/sys/msg/index.vue +++ b/src/frontend/admin/src/views/sys/msg/index.vue @@ -47,7 +47,7 @@ ref="search" />
- +
@@ -105,7 +105,7 @@ diff --git a/src/frontend/admin/src/views/sys/msg/save.vue b/src/frontend/admin/src/views/sys/msg/save.vue index 8d1175a8..42a1c14a 100644 --- a/src/frontend/admin/src/views/sys/msg/save.vue +++ b/src/frontend/admin/src/views/sys/msg/save.vue @@ -65,7 +65,7 @@ diff --git a/src/frontend/admin/src/views/sys/role/index.vue b/src/frontend/admin/src/views/sys/role/index.vue index 5e2ab06a..42b40a91 100644 --- a/src/frontend/admin/src/views/sys/role/index.vue +++ b/src/frontend/admin/src/views/sys/role/index.vue @@ -64,7 +64,7 @@ ref="search" />
- + @@ -159,7 +159,7 @@ diff --git a/src/frontend/admin/src/views/sys/role/save.vue b/src/frontend/admin/src/views/sys/role/save.vue index 83daeaf8..07fac51e 100644 --- a/src/frontend/admin/src/views/sys/role/save.vue +++ b/src/frontend/admin/src/views/sys/role/save.vue @@ -80,7 +80,7 @@ :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'github_dark' : 'github'" lang="json" style="height: 30rem; width: 100%" /> - {{ + {{ $t('JSON 格式化') }} @@ -101,7 +101,7 @@
diff --git a/src/frontend/admin/src/views/sys/user/index.vue b/src/frontend/admin/src/views/sys/user/index.vue index 3bfe006a..7e74ad9b 100644 --- a/src/frontend/admin/src/views/sys/user/index.vue +++ b/src/frontend/admin/src/views/sys/user/index.vue @@ -62,7 +62,7 @@ ref="search" />
- + {{ $t('批量操作') }} @@ -132,18 +132,18 @@ diff --git a/src/frontend/admin/src/views/sys/user/save.vue b/src/frontend/admin/src/views/sys/user/save.vue index fd3b0bd5..62bdfeb3 100644 --- a/src/frontend/admin/src/views/sys/user/save.vue +++ b/src/frontend/admin/src/views/sys/user/save.vue @@ -46,7 +46,7 @@ maxlength="16" oninput="value=value.replace(/[^\w]/g,'')" placeholder="8位以上数字字母组合"> - {{ $t('初始密码') }} + {{ $t('初始密码') }}
@@ -249,7 +249,7 @@