mirror of
https://gitee.com/dotnetchina/OpenAuth.Net.git
synced 2026-07-28 22:27:59 +08:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62babb205c | ||
|
|
a222959efe | ||
|
|
0340fb224f | ||
|
|
1a43adb9a6 | ||
|
|
cbb43f0011 | ||
|
|
9aac53b3eb | ||
|
|
bfe9bf2481 | ||
|
|
ab41783e9f | ||
|
|
fd4a328a72 | ||
|
|
17f0e402ac | ||
|
|
d2c8f783e1 | ||
|
|
237fc49f2f | ||
|
|
684b6e0fea | ||
|
|
ea658e3cba | ||
|
|
92eda330e5 | ||
|
|
aac40f9e67 | ||
|
|
ad18885596 | ||
|
|
6302ad4bca | ||
|
|
f30fe5e11d | ||
|
|
ac49f0e80f | ||
|
|
7d94137b44 | ||
|
|
fb7c1392a1 | ||
|
|
7cd738e7a7 |
@@ -1,33 +1,7 @@
|
||||
---
|
||||
alwaysApply: false
|
||||
name: dev
|
||||
description: OpenAuth.Net后端开发规范
|
||||
---
|
||||
# OpenAuth.Net Cursor Rules
|
||||
|
||||
## 项目概述
|
||||
OpenAuth.Net是一个基于.NET 9的企业级权限管理和快速开发框架,采用Martin Fowler企业级应用开发思想,集成了最新的技术栈。
|
||||
|
||||
## 技术栈
|
||||
- **后端**: .NET 9, ASP.NET Core WebAPI
|
||||
- **ORM**: SqlSugar (主要) + Entity Framework Core (兼容)
|
||||
- **依赖注入**: Autofac
|
||||
- **数据库**: 支持SqlServer、MySQL、Oracle、PostgreSQL
|
||||
- **定时任务**: Quartz.NET
|
||||
- **缓存**: Redis, MemoryCache
|
||||
- **前端**: Vue2 + Element-UI
|
||||
- **测试**: NUnit
|
||||
- **文档**: Swagger
|
||||
|
||||
## 项目架构
|
||||
```
|
||||
📦OpenAuth.Net
|
||||
┣ 📂Infrastructure # 基础设施层 - 工具类、扩展方法、帮助类
|
||||
┣ 📂OpenAuth.Repository # 数据访问层 - 实体定义、数据访问
|
||||
┣ 📂OpenAuth.App # 应用服务层 - 业务逻辑
|
||||
┣ 📂OpenAuth.WebApi # 表示层 - WebAPI控制器
|
||||
┣ 📂OpenAuth.Identity # 身份认证服务 - IdentityServer4
|
||||
┣ 📂Vue2 # 前端项目
|
||||
┗ 📂数据库脚本 # 数据库初始化脚本
|
||||
```
|
||||
|
||||
## 编码规范
|
||||
|
||||
@@ -54,7 +28,33 @@ OpenAuth.Net是一个基于.NET 9的企业级权限管理和快速开发框架
|
||||
- 复杂业务逻辑必须添加行内注释
|
||||
- 使用/// <summary>标记方法说明
|
||||
- 参数使用/// <param name="参数名">说明</param>
|
||||
- 返回值使用/// <returns>说明</returns>
|
||||
- 返回值使用/// <returns>说明</returns>
|
||||
|
||||
## 项目概述
|
||||
OpenAuth.Net是一个基于.NET 9的企业级权限管理和快速开发框架,采用Martin Fowler企业级应用开发思想,集成了最新的技术栈。
|
||||
|
||||
## 技术栈
|
||||
- **后端**: .NET 9, ASP.NET Core WebAPI
|
||||
- **ORM**: SqlSugar (主要) + Entity Framework Core (兼容)
|
||||
- **依赖注入**: Autofac
|
||||
- **数据库**: 支持SqlServer、MySQL、Oracle、PostgreSQL
|
||||
- **定时任务**: Quartz.NET
|
||||
- **缓存**: Redis, MemoryCache
|
||||
- **前端**: Vue2 + Element-UI
|
||||
- **测试**: NUnit
|
||||
- **文档**: Swagger
|
||||
|
||||
## 项目架构
|
||||
```
|
||||
📦OpenAuth.Net
|
||||
┣ 📂Infrastructure # 基础设施层 - 工具类、扩展方法、帮助类
|
||||
┣ 📂OpenAuth.Repository # 数据访问层 - 实体定义、数据访问
|
||||
┣ 📂OpenAuth.App # 应用服务层 - 业务逻辑
|
||||
┣ 📂OpenAuth.WebApi # 表示层 - WebAPI控制器
|
||||
┣ 📂OpenAuth.Identity # 身份认证服务 - IdentityServer4
|
||||
┣ 📂Vue2 # 前端项目
|
||||
┗ 📂数据库脚本 # 数据库初始化脚本
|
||||
```
|
||||
|
||||
## 分层架构规则
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"PostgreSQL": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@modelcontextprotocol/server-postgres",
|
||||
"postgresql://postgres:AwxBRx1_5kljfy@172.30.144.46/openauthpro"
|
||||
],
|
||||
"env": {}
|
||||
},
|
||||
"openauthpro": {
|
||||
"command": "powershell",
|
||||
"args": [
|
||||
"-Command",
|
||||
"npx -y @f4ww4z/mcp-mysql-server"
|
||||
],
|
||||
"env": {
|
||||
"MYSQL_HOST": "localhost",
|
||||
"MYSQL_PORT": "3306",
|
||||
"MYSQL_USER": "root",
|
||||
"MYSQL_PASSWORD": "000000",
|
||||
"MYSQL_DATABASE": "openauthpro"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
25
CheckAndKillPort52789.bat
Normal file
25
CheckAndKillPort52789.bat
Normal file
@@ -0,0 +1,25 @@
|
||||
@echo off
|
||||
chcp 936
|
||||
setlocal enabledelayedexpansion
|
||||
echo <20><><EFBFBD>ڼ<EFBFBD><DABC><EFBFBD>52789<38>˿<EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
||||
|
||||
rem <20><><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC>52789<38>˿ڵĽ<DAB5><C4BD><EFBFBD>
|
||||
FOR /F "tokens=5" %%i IN ('netstat -ano ^| findstr :52789 ^| findstr LISTENING') DO (
|
||||
SET pid=%%i
|
||||
echo <20><><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC>52789<38>˿ڵĽ<DAB5><C4BD>̣<EFBFBD>PID: %%i
|
||||
echo <20><><EFBFBD>ڲ<EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ...
|
||||
tasklist | findstr %%i
|
||||
|
||||
echo <20><><EFBFBD>ڽ<EFBFBD><DABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %%i...
|
||||
taskkill /F /PID %%i
|
||||
|
||||
echo <20><>֤<EFBFBD>˿<EFBFBD><CBBF>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ͷ<EFBFBD>...
|
||||
netstat -ano | findstr :52789
|
||||
goto :END
|
||||
)
|
||||
|
||||
echo δ<><CEB4><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC>52789<38>˿ڵĽ<DAB5><C4BD>̡<EFBFBD>
|
||||
|
||||
:END
|
||||
echo <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɡ<EFBFBD>
|
||||
pause
|
||||
@@ -6,7 +6,7 @@
|
||||
public struct FlowInstanceStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// 撤销、召回
|
||||
/// 召回
|
||||
/// </summary>
|
||||
public const int Draft = -1;
|
||||
/// <summary>
|
||||
|
||||
@@ -65,7 +65,8 @@ namespace Infrastructure.Middleware
|
||||
// 启用倒带功能,就可以让 Request.Body 可以再次读取
|
||||
request.EnableBuffering();
|
||||
// 文件上传 记录文件信息
|
||||
if (path.Contains("/upload"))
|
||||
var contentType = request.ContentType?? "";
|
||||
if (path.Contains("/upload") || contentType.Contains("multipart/form-data"))
|
||||
{
|
||||
var content = string.Join(",", request.Form.Files.Select(item => item.FileName));
|
||||
logData.Add("request.body", $"收到上传文件:{content}");
|
||||
@@ -73,7 +74,6 @@ namespace Infrastructure.Middleware
|
||||
else
|
||||
{
|
||||
var sr = new StreamReader(request.Body, Encoding.UTF8);
|
||||
//string content = sr.ReadToEnd(); //.Net Core 3.0 默认不再支持
|
||||
var content = sr.ReadToEndAsync().Result;
|
||||
logData.Add("request.body", content);
|
||||
request.Body.Position = 0;
|
||||
|
||||
@@ -11,6 +11,7 @@ using OpenAuth.Repository.Domain;
|
||||
using SqlSugar;
|
||||
using Autofac;
|
||||
using Infrastructure.Extensions.AutofacManager;
|
||||
using MySql.Data.MySqlClient.Memcached;
|
||||
|
||||
namespace OpenAuth.App
|
||||
{
|
||||
@@ -69,7 +70,15 @@ namespace OpenAuth.App
|
||||
if (loginUser.User.Account == Define.SYSTEM_USERNAME) return SugarClient.Queryable<T>(); //超级管理员特权
|
||||
|
||||
var moduleName = typeof(T).Name;
|
||||
var rule = SugarClient.Queryable<DataPrivilegeRule>().First(u => u.SourceCode == moduleName);
|
||||
|
||||
//数据权限永远只用默认连接字符串,避免租户隔离
|
||||
ISqlSugarClient defualtClient = SugarClient;
|
||||
var currentConfigId = SugarClient.CurrentConnectionConfig.ConfigId;
|
||||
if(currentConfigId != null && currentConfigId.ToString() !=""){
|
||||
defualtClient = SugarClient.AsTenant().GetConnection("");
|
||||
}
|
||||
var rule = defualtClient.Queryable<DataPrivilegeRule>().First(u => u.SourceCode == moduleName);
|
||||
|
||||
if (rule == null) return SugarClient.Queryable<T>(); //没有设置数据规则,那么视为该资源允许被任何主体查看
|
||||
if (rule.PrivilegeRules.Contains(Define.DATAPRIVILEGE_LOGINUSER) ||
|
||||
rule.PrivilegeRules.Contains(Define.DATAPRIVILEGE_LOGINROLE)||
|
||||
|
||||
@@ -11,7 +11,6 @@ using Infrastructure;
|
||||
using Infrastructure.Extensions;
|
||||
using Infrastructure.Helpers;
|
||||
using Infrastructure.Utilities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyModel;
|
||||
using Microsoft.Extensions.Options;
|
||||
using OpenAuth.App.Interface;
|
||||
@@ -20,12 +19,12 @@ using OpenAuth.App.Response;
|
||||
using OpenAuth.Repository;
|
||||
using OpenAuth.Repository.Core;
|
||||
using OpenAuth.Repository.Domain;
|
||||
using OpenAuth.Repository.Interface;
|
||||
using SqlSugar;
|
||||
|
||||
|
||||
namespace OpenAuth.App
|
||||
{
|
||||
public class BuilderTableApp : BaseStringApp<BuilderTable, OpenAuthDBContext>
|
||||
public class BuilderTableApp : SqlSugarBaseApp<BuilderTable>
|
||||
{
|
||||
private BuilderTableColumnApp _builderTableColumnApp;
|
||||
private CategoryApp _categoryApp;
|
||||
@@ -34,9 +33,9 @@ namespace OpenAuth.App
|
||||
private string _startName = "";
|
||||
private IOptions<AppSetting> _appConfiguration;
|
||||
|
||||
public BuilderTableApp(IUnitWork<OpenAuthDBContext> unitWork, IRepository<BuilderTable, OpenAuthDBContext> repository,
|
||||
public BuilderTableApp(ISqlSugarClient client,
|
||||
RevelanceManagerApp app, IAuth auth, DbExtension dbExtension, BuilderTableColumnApp builderTableColumnApp,
|
||||
IOptions<AppSetting> appConfiguration, CategoryApp categoryApp) : base(unitWork, repository, auth)
|
||||
IOptions<AppSetting> appConfiguration, CategoryApp categoryApp) : base(client, auth)
|
||||
{
|
||||
_dbExtension = dbExtension;
|
||||
_builderTableColumnApp = builderTableColumnApp;
|
||||
@@ -87,7 +86,7 @@ namespace OpenAuth.App
|
||||
}
|
||||
|
||||
var result = new PagedListDataResp<BuilderTable>();
|
||||
var objs = UnitWork.Find<BuilderTable>(null);
|
||||
var objs = SugarClient.Queryable<BuilderTable>();
|
||||
if (!string.IsNullOrEmpty(request.key))
|
||||
{
|
||||
objs = objs.Where(u => u.Id.Contains(request.key));
|
||||
@@ -126,7 +125,6 @@ namespace OpenAuth.App
|
||||
Check(req);
|
||||
var obj = AddTableAndColumns(req.MapTo<BuilderTable>());
|
||||
|
||||
UnitWork.Save();
|
||||
return obj.Id;
|
||||
}
|
||||
|
||||
@@ -143,8 +141,7 @@ namespace OpenAuth.App
|
||||
var user = _auth.GetCurrentUser().User;
|
||||
obj.CreateUserId = user.Id;
|
||||
obj.CreateUserName = user.Name;
|
||||
UnitWork.Add(obj);
|
||||
UnitWork.Save(); //需要先保存表结构,后面才能正常判定
|
||||
Repository.Insert(obj);
|
||||
|
||||
_dbExtension.ProcessExternalDb(obj.Id); //先处理外部数据库连接
|
||||
var columns = _dbExtension.GetDbTableStructure(obj.TableName);
|
||||
@@ -175,7 +172,7 @@ namespace OpenAuth.App
|
||||
CreateUserName = user.Name,
|
||||
CreateTime = DateTime.Now
|
||||
};
|
||||
UnitWork.Add(builderColumn);
|
||||
SugarClient.Insertable(builderColumn).ExecuteCommand();
|
||||
}
|
||||
|
||||
return obj;
|
||||
@@ -185,7 +182,7 @@ namespace OpenAuth.App
|
||||
{
|
||||
Check(obj);
|
||||
var user = _auth.GetCurrentUser().User;
|
||||
UnitWork.Update<BuilderTable>(u => u.Id == obj.Id, u => new BuilderTable
|
||||
Repository.Update(u => new BuilderTable
|
||||
{
|
||||
TableName = obj.TableName,
|
||||
Remark = obj.Remark,
|
||||
@@ -204,7 +201,7 @@ namespace OpenAuth.App
|
||||
UpdateUserId = user.Id,
|
||||
UpdateUserName = user.Name,
|
||||
ExternalDataSourceId = obj.ExternalDataSourceId //外部数据源ID
|
||||
});
|
||||
}, u => u.Id == obj.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -213,12 +210,10 @@ namespace OpenAuth.App
|
||||
/// <param name="ids"></param>
|
||||
public void DelTableAndcolumns(string[] ids)
|
||||
{
|
||||
UnitWork.ExecuteWithTransaction(() =>
|
||||
{
|
||||
UnitWork.Delete<BuilderTable>(u => ids.Contains(u.Id));
|
||||
UnitWork.Delete<BuilderTableColumn>(u => ids.Contains(u.TableId));
|
||||
UnitWork.Save();
|
||||
});
|
||||
SugarClient.Ado.BeginTran();
|
||||
SugarClient.Deleteable<BuilderTable>().Where(u => ids.Contains(u.Id)).ExecuteCommand();
|
||||
SugarClient.Deleteable<BuilderTableColumn>().Where(u => ids.Contains(u.TableId)).ExecuteCommand();
|
||||
SugarClient.Ado.CommitTran();
|
||||
}
|
||||
|
||||
|
||||
@@ -228,7 +223,7 @@ namespace OpenAuth.App
|
||||
/// <returns></returns>
|
||||
public void CreateEntity(CreateEntityReq req)
|
||||
{
|
||||
var sysTableInfo = Repository.FirstOrDefault(u => u.Id == req.Id);
|
||||
var sysTableInfo = SugarClient.Queryable<BuilderTable>().First(u => u.Id == req.Id);
|
||||
var tableColumns = _builderTableColumnApp.Find(req.Id);
|
||||
if (sysTableInfo == null
|
||||
|| tableColumns == null
|
||||
@@ -247,7 +242,7 @@ namespace OpenAuth.App
|
||||
/// <returns></returns>
|
||||
public void CreateBusiness(CreateBusiReq req)
|
||||
{
|
||||
var sysTableInfo = Repository.FirstOrDefault(u => u.Id == req.Id);
|
||||
var sysTableInfo = SugarClient.Queryable<BuilderTable>().First(u => u.Id == req.Id);
|
||||
var mainColumns = _builderTableColumnApp.Find(req.Id);
|
||||
if (sysTableInfo == null
|
||||
|| mainColumns == null
|
||||
@@ -319,7 +314,7 @@ namespace OpenAuth.App
|
||||
|
||||
string domainContent = string.Empty;
|
||||
//查找是否存在子表的情况
|
||||
var subTable = Repository.FirstOrDefault(u => u.ParentTableId == sysTableInfo.Id);
|
||||
var subTable = SugarClient.Queryable<BuilderTable>().First(u => u.ParentTableId == sysTableInfo.Id);
|
||||
|
||||
if (subTable == null) //如果子表不存在,则用单模版生成
|
||||
{
|
||||
@@ -386,21 +381,7 @@ namespace OpenAuth.App
|
||||
{
|
||||
throw new Exception($"未能找到表{sysTableInfo.TableName}的主键字段");
|
||||
}
|
||||
if (primarykey.ColumnType == "decimal" || primarykey.ColumnType == "numeric") //是否为数字
|
||||
{
|
||||
if (primarykey.IsIncrement) //是否自增
|
||||
{
|
||||
domainContent = domainContent.Replace("{BaseAppName}", "BaseIntAutoGenApp");
|
||||
}
|
||||
else //普通的雪花算法生成id
|
||||
{
|
||||
domainContent = domainContent.Replace("{BaseAppName}", "BaseLongApp");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
domainContent = domainContent.Replace("{BaseAppName}", "BaseStringApp");
|
||||
}
|
||||
domainContent = domainContent.Replace("{BaseAppName}", "SqlSugarBaseApp");
|
||||
FileHelper.WriteFile($"{appRootPath}\\{sysTableInfo.ModuleCode}", $"{sysTableInfo.ModuleCode}.cs", domainContent);
|
||||
}
|
||||
|
||||
@@ -465,7 +446,7 @@ namespace OpenAuth.App
|
||||
}
|
||||
|
||||
//查找是否存在子表的情况
|
||||
var subTable = Repository.FirstOrDefault(u => u.ParentTableId == sysTableInfo.Id);
|
||||
var subTable = SugarClient.Queryable<BuilderTable>().First(u => u.ParentTableId == sysTableInfo.Id);
|
||||
|
||||
if (subTable != null) //如果子表存在,需要加子表的请求参数
|
||||
{
|
||||
@@ -705,7 +686,7 @@ namespace OpenAuth.App
|
||||
{
|
||||
var types = AssemblyLoadContext.Default
|
||||
.LoadFromAssemblyName(new AssemblyName(compilation.Name))
|
||||
.GetTypes().Where(x => x.GetTypeInfo().BaseType != null
|
||||
.GetTypes().Where(x => System.Reflection.IntrospectionExtensions.GetTypeInfo(x).BaseType != null
|
||||
&& x.BaseType == typeof(StringEntity));
|
||||
foreach (var entity in types)
|
||||
{
|
||||
@@ -736,7 +717,7 @@ namespace OpenAuth.App
|
||||
{
|
||||
throw new Exception("请提供vue项目的根目录,如:C:\\OpenAuth.Pro\\Client");
|
||||
}
|
||||
var sysTableInfo = Repository.FirstOrDefault(u => u.Id == req.Id);
|
||||
var sysTableInfo = SugarClient.Queryable<BuilderTable>().First(u => u.Id == req.Id);
|
||||
|
||||
if (!string.IsNullOrEmpty(sysTableInfo.ParentTableId))
|
||||
{
|
||||
@@ -753,7 +734,7 @@ namespace OpenAuth.App
|
||||
string domainContent = string.Empty;
|
||||
|
||||
//查找是否存在子表额情况
|
||||
var subTable = Repository.FirstOrDefault(u => u.ParentTableId == req.Id);
|
||||
var subTable = SugarClient.Queryable<BuilderTable>().First(u => u.ParentTableId == req.Id);
|
||||
|
||||
if (subTable == null) //如果子表不存在,则用单模版生成
|
||||
{
|
||||
@@ -868,7 +849,7 @@ namespace OpenAuth.App
|
||||
{
|
||||
throw new Exception("请提供vue项目的根目录,如:C:\\OpenAuth.Pro\\Client");
|
||||
}
|
||||
var sysTableInfo = Repository.FirstOrDefault(u => u.Id == req.Id);
|
||||
var sysTableInfo = SugarClient.Queryable<BuilderTable>().First(u => u.Id == req.Id);
|
||||
var tableColumns = _builderTableColumnApp.Find(req.Id);
|
||||
if (sysTableInfo == null
|
||||
|| tableColumns == null
|
||||
@@ -890,7 +871,7 @@ namespace OpenAuth.App
|
||||
public async Task<PagedDynamicDataResp> AllMain()
|
||||
{
|
||||
var result = new PagedDynamicDataResp();
|
||||
var objs = UnitWork.Find<BuilderTable>(u => string.IsNullOrEmpty(u.ParentTableId)).Select(u => new
|
||||
var objs = SugarClient.Queryable<BuilderTable>().Where(u => string.IsNullOrEmpty(u.ParentTableId)).Select(u => new
|
||||
{
|
||||
Id = u.Id,
|
||||
Name = u.TableName
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace OpenAuth.App
|
||||
|
||||
var propertyStr = string.Join(',', columnFields.Select(u =>u.ColumnName));
|
||||
result.ColumnFields = columnFields;
|
||||
result.Data = objs.OrderBy(u => u.DtCode)
|
||||
result.Data = objs.OrderBy(u => u.SortNo).OrderBy(u => u.DtCode)
|
||||
.Skip((request.page - 1) * request.limit)
|
||||
.Take(request.limit).Select($"{propertyStr}").ToList();
|
||||
result.Count = await objs.CountAsync();
|
||||
|
||||
@@ -3,18 +3,16 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OpenAuth.App.Interface;
|
||||
using OpenAuth.App.Request;
|
||||
using OpenAuth.App.Response;
|
||||
using OpenAuth.Repository;
|
||||
using OpenAuth.Repository.Domain;
|
||||
using OpenAuth.Repository.Interface;
|
||||
using SqlSugar;
|
||||
|
||||
|
||||
namespace OpenAuth.App
|
||||
{
|
||||
public class CategoryTypeApp : BaseStringApp<CategoryType,OpenAuthDBContext>
|
||||
public class CategoryTypeApp : SqlSugarBaseApp<CategoryType>
|
||||
{
|
||||
private RevelanceManagerApp _revelanceApp;
|
||||
|
||||
@@ -24,7 +22,7 @@ namespace OpenAuth.App
|
||||
public async Task<PagedDynamicDataResp> Load(QueryCategoryTypeListReq request)
|
||||
{
|
||||
var result = new PagedDynamicDataResp();
|
||||
var objs = UnitWork.Find<CategoryType>(null);
|
||||
var objs = SugarClient.Queryable<CategoryType>();
|
||||
if (!string.IsNullOrEmpty(request.key))
|
||||
{
|
||||
objs = objs.Where(u => u.Id.Contains(request.key) || u.Name.Contains(request.key));
|
||||
@@ -42,39 +40,37 @@ namespace OpenAuth.App
|
||||
var obj = req.MapTo<CategoryType>();
|
||||
//todo:补充或调整自己需要的字段
|
||||
obj.CreateTime = DateTime.Now;
|
||||
Repository.Add(obj);
|
||||
Repository.Insert(obj);
|
||||
}
|
||||
|
||||
public void Update(AddOrUpdateCategoryTypeReq obj)
|
||||
{
|
||||
var user = _auth.GetCurrentUser().User;
|
||||
UnitWork.Update<CategoryType>(u => u.Id == obj.Id, u => new CategoryType
|
||||
Repository.Update(u => new CategoryType
|
||||
{
|
||||
Name = obj.Name,
|
||||
CreateTime = DateTime.Now
|
||||
//todo:补充或调整自己需要的字段
|
||||
});
|
||||
}, u => u.Id == obj.Id);
|
||||
|
||||
}
|
||||
|
||||
public new void Delete(string[] ids)
|
||||
{
|
||||
UnitWork.ExecuteWithTransaction(() =>
|
||||
{
|
||||
UnitWork.Delete<CategoryType>(u=>ids.Contains(u.Id));
|
||||
UnitWork.Delete<Category>(u=>ids.Contains(u.TypeId));
|
||||
UnitWork.Save();
|
||||
});
|
||||
SugarClient.Ado.BeginTran();
|
||||
SugarClient.Deleteable<CategoryType>().Where(u=>ids.Contains(u.Id)).ExecuteCommand();
|
||||
SugarClient.Deleteable<Category>().Where(u=>ids.Contains(u.TypeId)).ExecuteCommand();
|
||||
SugarClient.Ado.CommitTran();
|
||||
|
||||
}
|
||||
|
||||
public List<CategoryType> AllTypes()
|
||||
{
|
||||
return UnitWork.Find<CategoryType>(null).ToList();
|
||||
return SugarClient.Queryable<CategoryType>().ToList();
|
||||
}
|
||||
|
||||
public CategoryTypeApp(IUnitWork<OpenAuthDBContext> unitWork, IRepository<CategoryType,OpenAuthDBContext> repository,
|
||||
RevelanceManagerApp app, IAuth auth) : base(unitWork, repository,auth)
|
||||
public CategoryTypeApp(ISqlSugarClient client,
|
||||
RevelanceManagerApp app, IAuth auth) : base(client, auth)
|
||||
{
|
||||
_revelanceApp = app;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,59 @@ namespace OpenAuth.App
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
#region 辅助方法 - 大小写不敏感的字典操作
|
||||
|
||||
/// <summary>
|
||||
/// 将普通字典转换为大小写不敏感的字典
|
||||
/// </summary>
|
||||
private Dictionary<string, object> ToIgnoreCaseDict(Dictionary<string, object> source)
|
||||
{
|
||||
var result = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
||||
if (source != null)
|
||||
{
|
||||
foreach (var kvp in source)
|
||||
{
|
||||
result[kvp.Key] = kvp.Value;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查字典中是否包含指定键(大小写不敏感)
|
||||
/// </summary>
|
||||
private bool ContainsKeyIgnoreCase(Dictionary<string, object> dict, string key)
|
||||
{
|
||||
return dict.Keys.Any(k => string.Equals(k, key, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取字典中指定键的值(大小写不敏感)
|
||||
/// </summary>
|
||||
private object GetValueIgnoreCase(Dictionary<string, object> dict, string key)
|
||||
{
|
||||
var kvp = dict.FirstOrDefault(x => string.Equals(x.Key, key, StringComparison.OrdinalIgnoreCase));
|
||||
return kvp.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置字典中指定键的值(保留原始键名,大小写不敏感查找)
|
||||
/// </summary>
|
||||
private void SetValueIgnoreCase(Dictionary<string, object> dict, string key, object value)
|
||||
{
|
||||
var existingKey = dict.Keys.FirstOrDefault(k => string.Equals(k, key, StringComparison.OrdinalIgnoreCase));
|
||||
if (existingKey != null)
|
||||
{
|
||||
dict[existingKey] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
dict[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 获取表数据列表
|
||||
/// </summary>
|
||||
@@ -154,37 +207,42 @@ namespace OpenAuth.App
|
||||
return result;
|
||||
}
|
||||
|
||||
// 将对象转换为字典
|
||||
var dict = JsonHelper.Instance.Deserialize<Dictionary<string, Object>>(req.Obj);
|
||||
// 将对象转换为字典(使用大小写不敏感的反序列化)
|
||||
var rawDict = JsonHelper.Instance.Deserialize<Dictionary<string, object>>(req.Obj);
|
||||
var dict = ToIgnoreCaseDict(rawDict);
|
||||
|
||||
// 设置ID
|
||||
if (!dict.ContainsKey("Id"))
|
||||
{
|
||||
dict["Id"] = Guid.NewGuid().ToString();
|
||||
}
|
||||
else if (string.IsNullOrEmpty(dict["Id"]?.ToString()))
|
||||
// 设置ID(大小写不敏感检查)
|
||||
if (!ContainsKeyIgnoreCase(dict, "Id"))
|
||||
{
|
||||
dict["Id"] = Guid.NewGuid().ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
//如果Id不为空,需要判断Id是否存在
|
||||
var entity = await _client.Queryable<dynamic>()
|
||||
.AS(req.TableName)
|
||||
.Where("Id = @id", new { id = dict["Id"] })
|
||||
.FirstAsync();
|
||||
if (entity != null)
|
||||
var idValue = GetValueIgnoreCase(dict, "Id");
|
||||
if (string.IsNullOrEmpty(idValue?.ToString()))
|
||||
{
|
||||
result.Code = 500;
|
||||
result.Message = "Id已存在";
|
||||
return result;
|
||||
SetValueIgnoreCase(dict, "Id", Guid.NewGuid().ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
//如果Id不为空,需要判断Id是否存在
|
||||
var entity = await _client.Queryable<dynamic>()
|
||||
.AS(req.TableName)
|
||||
.Where("Id = @id", new { id = idValue })
|
||||
.FirstAsync();
|
||||
if (entity != null)
|
||||
{
|
||||
result.Code = 500;
|
||||
result.Message = "Id已存在";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//如果有CreateTime字段,自动设置
|
||||
if (dict.ContainsKey("CreateTime"))
|
||||
//如果有CreateTime字段,自动设置(大小写不敏感)
|
||||
if (ContainsKeyIgnoreCase(dict, "CreateTime"))
|
||||
{
|
||||
dict["CreateTime"] = DateTime.Now.ToString();
|
||||
SetValueIgnoreCase(dict, "CreateTime", DateTime.Now.ToString());
|
||||
}
|
||||
|
||||
// 添加数据
|
||||
@@ -222,30 +280,44 @@ namespace OpenAuth.App
|
||||
return result;
|
||||
}
|
||||
|
||||
// 将对象转换为字典
|
||||
var dict = JsonHelper.Instance.Deserialize<Dictionary<string, Object>>(req.Obj);
|
||||
// 将对象转换为字典(使用大小写不敏感的反序列化)
|
||||
var rawDict = JsonHelper.Instance.Deserialize<Dictionary<string, object>>(req.Obj);
|
||||
var dict = ToIgnoreCaseDict(rawDict);
|
||||
|
||||
// 检查ID是否存在
|
||||
if (!dict.ContainsKey("Id"))
|
||||
// 检查ID是否存在(大小写不敏感)
|
||||
if (!ContainsKeyIgnoreCase(dict, "Id"))
|
||||
{
|
||||
result.Code = 500;
|
||||
result.Message = "更新数据必须包含Id字段";
|
||||
return result;
|
||||
}
|
||||
|
||||
// 如果有UpdateTime字段,自动设置
|
||||
if (dict.ContainsKey("UpdateTime"))
|
||||
// 确保字典中有 "Id" 键(用于 SqlSugar 的 WhereColumns)
|
||||
if (!dict.ContainsKey("Id"))
|
||||
{
|
||||
dict["UpdateTime"] = DateTime.Now.ToString();
|
||||
var idValue = GetValueIgnoreCase(dict, "Id");
|
||||
// 移除原始的小写 id 键
|
||||
var originalKey = dict.Keys.FirstOrDefault(k => string.Equals(k, "Id", StringComparison.OrdinalIgnoreCase));
|
||||
if (originalKey != null && originalKey != "Id")
|
||||
{
|
||||
dict.Remove(originalKey);
|
||||
dict["Id"] = idValue;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果有用户信息,设置更新用户
|
||||
// 如果有UpdateTime字段,自动设置(大小写不敏感)
|
||||
if (ContainsKeyIgnoreCase(dict, "UpdateTime"))
|
||||
{
|
||||
SetValueIgnoreCase(dict, "UpdateTime", DateTime.Now.ToString());
|
||||
}
|
||||
|
||||
// 如果有用户信息,设置更新用户(大小写不敏感)
|
||||
var currentUser = _auth.GetCurrentUser();
|
||||
if (dict.ContainsKey("UpdateUserId") && currentUser != null)
|
||||
if (ContainsKeyIgnoreCase(dict, "UpdateUserId") && currentUser != null)
|
||||
{
|
||||
// 设置更新用户信息
|
||||
dict["UpdateUserId"] = currentUser.User.Id;
|
||||
dict["UpdateUserName"] = currentUser.User.Name;
|
||||
SetValueIgnoreCase(dict, "UpdateUserId", currentUser.User.Id);
|
||||
SetValueIgnoreCase(dict, "UpdateUserName", currentUser.User.Name);
|
||||
}
|
||||
|
||||
// 更新数据
|
||||
@@ -387,27 +459,21 @@ namespace OpenAuth.App
|
||||
try
|
||||
{
|
||||
var json = request.Parameters;
|
||||
// 检查参数名是否存在于JSON中
|
||||
if (json.Contains($"\"{param.Name}\""))
|
||||
|
||||
// 解析完整的JSON对象(使用大小写不敏感的字典)
|
||||
var jsonObj = JsonHelper.Instance.Deserialize<Dictionary<string, object>>(json);
|
||||
var ignoreCaseDict = ToIgnoreCaseDict(jsonObj);
|
||||
|
||||
// 从JSON对象中获取参数值(大小写不敏感查找)
|
||||
if (ContainsKeyIgnoreCase(ignoreCaseDict, param.Name))
|
||||
{
|
||||
// 解析完整的JSON对象
|
||||
var jsonObj = JsonHelper.Instance.Deserialize<Dictionary<string, object>>(json);
|
||||
// 获取参数对应的JSON值并序列化为字符串
|
||||
var rawValue = GetValueIgnoreCase(ignoreCaseDict, param.Name);
|
||||
var paramValue = JsonHelper.Instance.Serialize(rawValue);
|
||||
|
||||
// 从JSON对象中获取参数值
|
||||
if (jsonObj.ContainsKey(param.Name))
|
||||
{
|
||||
// 获取参数对应的JSON值并序列化为字符串
|
||||
var paramValue = JsonHelper.Instance.Serialize(jsonObj[param.Name]);
|
||||
|
||||
// 将JSON字符串反序列化为目标类型
|
||||
var deserializeMethod = typeof(JsonHelper).GetMethod("Deserialize").MakeGenericMethod(param.ParameterType);
|
||||
paramValues[i] = deserializeMethod.Invoke(JsonHelper.Instance, new object[] { paramValue });
|
||||
}
|
||||
else
|
||||
{
|
||||
// 参数名存在但获取不到,使用默认值
|
||||
paramValues[i] = param.HasDefaultValue ? param.DefaultValue : null;
|
||||
}
|
||||
// 将JSON字符串反序列化为目标类型
|
||||
var deserializeMethod = typeof(JsonHelper).GetMethod("Deserialize").MakeGenericMethod(param.ParameterType);
|
||||
paramValues[i] = deserializeMethod.Invoke(JsonHelper.Instance, new object[] { paramValue });
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -7,31 +7,29 @@ using Infrastructure;
|
||||
using Infrastructure.Extensions;
|
||||
using Infrastructure.Helpers;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using OpenAuth.App.Interface;
|
||||
using OpenAuth.App.Request;
|
||||
using OpenAuth.App.Response;
|
||||
using OpenAuth.Repository;
|
||||
using OpenAuth.Repository.Domain;
|
||||
using OpenAuth.Repository.Interface;
|
||||
using SqlSugar;
|
||||
|
||||
namespace OpenAuth.App
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件管理
|
||||
/// </summary>
|
||||
public class FileApp : BaseStringApp<UploadFile,OpenAuthDBContext>
|
||||
public class FileApp : SqlSugarBaseApp<UploadFile>
|
||||
{
|
||||
private ILogger<FileApp> _logger;
|
||||
private string _filePath;
|
||||
private string _dbFilePath; //数据库中的文件路径
|
||||
private string _dbThumbnail; //数据库中的缩略图路径
|
||||
|
||||
public FileApp(IOptions<AppSetting> setOptions, IUnitWork<OpenAuthDBContext> unitWork, IRepository<UploadFile,OpenAuthDBContext> repository,
|
||||
public FileApp(IOptions<AppSetting> setOptions, ISqlSugarClient client,
|
||||
ILogger<FileApp> logger, IAuth auth)
|
||||
: base(unitWork, repository, auth)
|
||||
: base(client, auth)
|
||||
{
|
||||
_logger = logger;
|
||||
_filePath = setOptions.Value.UploadPath;
|
||||
@@ -47,7 +45,7 @@ namespace OpenAuth.App
|
||||
public async Task<PagedDynamicDataResp> Load(QueryFileListReq request)
|
||||
{
|
||||
var result = new PagedDynamicDataResp();
|
||||
var objs = UnitWork.Find<UploadFile>(null);
|
||||
var objs = SugarClient.Queryable<UploadFile>();
|
||||
if (!string.IsNullOrEmpty(request.key))
|
||||
{
|
||||
objs = objs.Where(u => u.FileName.Contains(request.key) || u.FilePath.Contains(request.key));
|
||||
@@ -112,7 +110,7 @@ namespace OpenAuth.App
|
||||
FileType = Path.GetExtension(fileName),
|
||||
Extension = Path.GetExtension(fileName)
|
||||
};
|
||||
Repository.Add(filedb);
|
||||
Repository.Insert(filedb);
|
||||
return filedb;
|
||||
}
|
||||
}
|
||||
@@ -126,9 +124,9 @@ namespace OpenAuth.App
|
||||
/// 删除附件
|
||||
/// </summary>
|
||||
/// <param name="ids"></param>
|
||||
public override void Delete(string[] ids)
|
||||
public new void Delete(string[] ids)
|
||||
{
|
||||
var files = base.Repository.Find(u => ids.Contains(u.Id)).ToList();
|
||||
var files = SugarClient.Queryable<UploadFile>().Where(u => ids.Contains(u.Id)).ToList();
|
||||
for (int i = 0; i < files.Count(); i++)
|
||||
{
|
||||
var uploadPath = Path.Combine(_filePath, files[i].FilePath);
|
||||
@@ -137,7 +135,7 @@ namespace OpenAuth.App
|
||||
{
|
||||
FileHelper.FileDel(Path.Combine(_filePath, files[i].Thumbnail));
|
||||
}
|
||||
Repository.Delete(u =>u.Id == files[i].Id);
|
||||
SugarClient.Deleteable<UploadFile>().Where(u =>u.Id == files[i].Id).ExecuteCommand();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,16 @@
|
||||
|
||||
public string name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 节点类型
|
||||
/// <para>
|
||||
/// start:开始节点
|
||||
/// end:结束节点
|
||||
/// node:普通节点
|
||||
/// fork:网关开始
|
||||
/// join:网关结束
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public string type { get; set; }
|
||||
|
||||
public int left { get; set; }
|
||||
@@ -47,10 +57,29 @@
|
||||
/// </summary>
|
||||
public string NodeRejectType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 审批标记:1通过,2不通过,3驳回
|
||||
/// </summary>
|
||||
public int? Taged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 审批人名称
|
||||
/// </summary>
|
||||
public string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 审批人ID
|
||||
/// </summary>
|
||||
public string UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 审批意见
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 审批时间
|
||||
/// </summary>
|
||||
public string TagedTime { get; set; }
|
||||
|
||||
//网关审批通过的方式,
|
||||
|
||||
@@ -400,13 +400,22 @@ namespace OpenAuth.App.Flow
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 撤销流程,清空所有节点
|
||||
/// 召回流程,清空所有节点,返回开始节点并修改为草稿状态
|
||||
/// </summary>
|
||||
public void ReCall(RecallFlowInstanceReq request)
|
||||
{
|
||||
foreach (var item in Nodes)
|
||||
{
|
||||
item.Value.setInfo = null;
|
||||
if (item.Value.setInfo != null)
|
||||
{
|
||||
item.Value.setInfo.Taged = null;
|
||||
item.Value.setInfo.UserName = null;
|
||||
item.Value.setInfo.UserId = null;
|
||||
item.Value.setInfo.Description = null;
|
||||
item.Value.setInfo.TagedTime = null;
|
||||
item.Value.setInfo.ConfluenceOk = null;
|
||||
item.Value.setInfo.ConfluenceNo = null;
|
||||
}
|
||||
}
|
||||
|
||||
flowInstance.IsFinish = FlowInstanceStatus.Draft;
|
||||
@@ -414,17 +423,18 @@ namespace OpenAuth.App.Flow
|
||||
flowInstance.ActivityId = startNodeId;
|
||||
flowInstance.ActivityName = Nodes[startNodeId].name;
|
||||
flowInstance.MakerList = GetNodeMarkers(Nodes[startNodeId], flowInstance.CreateUserId);
|
||||
flowInstance.SchemeContent = JsonHelper.Instance.Serialize(ToSchemeObj());
|
||||
|
||||
var sugarClient = AutofacContainerModule.GetService<ISqlSugarClient>();
|
||||
sugarClient.Updateable(flowInstance).ExecuteCommand();
|
||||
|
||||
SaveOperationHis($"【撤回】备注:{request.Description}");
|
||||
SaveOperationHis($"【召回】备注:{request.Description}");
|
||||
|
||||
sugarClient.Ado.CommitTran();
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// 标记节点1通过,-1不通过,0驳回
|
||||
/// 标记节点1通过,2不通过,3驳回
|
||||
/// </summary>
|
||||
/// <param name="nodeId"></param>
|
||||
public void MakeTagNode(string nodeId, Tag tag)
|
||||
@@ -448,6 +458,9 @@ namespace OpenAuth.App.Flow
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为流程方案对象
|
||||
/// </summary>
|
||||
public object ToSchemeObj()
|
||||
{
|
||||
return new
|
||||
@@ -583,8 +596,11 @@ namespace OpenAuth.App.Flow
|
||||
#region 获取节点审批人
|
||||
|
||||
/// <summary>
|
||||
/// 寻找下一步的执行人
|
||||
/// 一般用于本节点审核完成后,修改流程实例的当前执行人,可以做到通知等功能
|
||||
/// 计算流程推进到下一步时的执行人
|
||||
/// <para>创建流程实例(Add):新建流程后计算第一个审批人</para>
|
||||
/// <para>网关审批完成(VerifyGatewayStart):网关结束后推进到下一节点</para>
|
||||
/// <para>普通节点审批通过(VerifyNode):审批同意后推进到下一节点</para>
|
||||
/// <para>启动草稿流程(Start):草稿变为运行状态,计算下一执行人</para>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetNextMakers(NodeDesignateReq request = null)
|
||||
@@ -598,11 +614,13 @@ namespace OpenAuth.App.Flow
|
||||
//如果request为空,则应该是草稿状态变为启动,或为网关节点,使用nextNode的setInfo
|
||||
if (request == null)
|
||||
{
|
||||
request = new NodeDesignateReq
|
||||
{
|
||||
NodeDesignateType = nextNode.setInfo.NodeDesignate,
|
||||
NodeDesignates = nextNode.setInfo.NodeDesignateData.datas
|
||||
};
|
||||
request = new NodeDesignateReq();
|
||||
}
|
||||
|
||||
//从url审批过来的,request不为空,但是这两个属性是空的
|
||||
if(request.NodeDesignateType == null || request.NodeDesignates == null){
|
||||
request.NodeDesignateType = nextNode.setInfo.NodeDesignate;
|
||||
request.NodeDesignates = nextNode.setInfo.NodeDesignateData.datas;
|
||||
}
|
||||
|
||||
if (GetNextNodeType() == Define.NODE_TYPE_FORK) //如果是网关节点
|
||||
@@ -621,9 +639,7 @@ namespace OpenAuth.App.Flow
|
||||
throw new Exception("前端提交的节点权限类型异常,请检查流程");
|
||||
}
|
||||
|
||||
var revelanceApp = AutofacContainerModule.GetService<RevelanceManagerApp>();
|
||||
var users = revelanceApp.Get(Define.USERROLE, false, request.NodeDesignates);
|
||||
makerList = GenericHelpers.ArrayToString(users, makerList);
|
||||
makerList = ResolveDesignateUsers(Define.SPECIAL_ROLE, request.NodeDesignates);
|
||||
}
|
||||
else if (nextNode.setInfo.NodeDesignate == Define.RUNTIME_SPECIAL_USER)
|
||||
{
|
||||
@@ -633,7 +649,7 @@ namespace OpenAuth.App.Flow
|
||||
throw new Exception("前端提交的节点权限类型异常,请检查流程");
|
||||
}
|
||||
|
||||
makerList = GenericHelpers.ArrayToString(request.NodeDesignates, makerList);
|
||||
makerList = ResolveDesignateUsers(Define.SPECIAL_USER, request.NodeDesignates);
|
||||
}
|
||||
else if (nextNode.setInfo.NodeDesignate == Define.SPECIAL_SQL)
|
||||
{
|
||||
@@ -643,10 +659,7 @@ namespace OpenAuth.App.Flow
|
||||
throw new Exception("前端提交的节点权限类型异常,请检查流程");
|
||||
}
|
||||
|
||||
var sql = ReplaceSql(nextNode.setInfo.NodeDesignateData.datas[0]);
|
||||
var sugarClient = AutofacContainerModule.GetService<ISqlSugarClient>();
|
||||
var result = sugarClient.Ado.SqlQuery<string>(sql);
|
||||
makerList = GenericHelpers.ArrayToString(result, makerList);
|
||||
makerList = ResolveDesignateUsers(Define.SPECIAL_SQL, nextNode.setInfo.NodeDesignateData.datas);
|
||||
}
|
||||
else if (nextNode.setInfo.NodeDesignate == Define.RUNTIME_PARENT
|
||||
|| nextNode.setInfo.NodeDesignate == Define.RUNTIME_MANY_PARENTS)
|
||||
@@ -693,6 +706,99 @@ namespace OpenAuth.App.Flow
|
||||
return makerList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取节点审批人
|
||||
/// <para>回退/查询"场景,回答"这个节点设计时配了谁来审"</para>
|
||||
/// <para>驳回到指定节点(RejectNode):流程被驳回时,需要重新计算目标节点的审批人</para>
|
||||
/// <para>召回流程(ReCall):将流程撤回到开始节点,用创建人ID算出审批人</para>
|
||||
/// <para>撤销审批(UndoVerification):恢复上一个节点的审批人</para>
|
||||
/// <para>网关分支中查找可审核节点(GetOneForkLineCanCheckNodeId):遍历分支判断当前用户是否有权审核</para>
|
||||
/// <para>网关分支获取审核者(GetOneForkLineMakers):找到分支线上下一个待审人</para>
|
||||
/// </summary>
|
||||
public string GetNodeMarkers(FlowNode node, string flowinstanceCreateUserId = "")
|
||||
{
|
||||
string makerList = "";
|
||||
if (node.type == Define.NODE_TYPE_START && (!string.IsNullOrEmpty(flowinstanceCreateUserId))) //如果是开始节点,通常情况下是驳回到开始了
|
||||
{
|
||||
makerList = flowinstanceCreateUserId;
|
||||
}
|
||||
else if (node.setInfo != null)
|
||||
{
|
||||
if (node.setInfo.NodeDesignate == Define.RUNTIME_SPECIAL_ROLE
|
||||
|| node.setInfo.NodeDesignate == Define.RUNTIME_SPECIAL_USER)
|
||||
{
|
||||
//如果是运行时选定的用户,则暂不处理。由上个节点审批时选定
|
||||
}
|
||||
else if (node.setInfo.NodeDesignate == Define.RUNTIME_PARENT
|
||||
|| node.setInfo.NodeDesignate == Define.RUNTIME_MANY_PARENTS)
|
||||
{
|
||||
//驳回/撤销场景:找到目标节点的前一个节点的执行人,以其为基准计算直属上级
|
||||
var preNode = GetPreNode(node.id);
|
||||
var preNodeUserId = preNode.setInfo?.UserId;
|
||||
if (!string.IsNullOrEmpty(preNodeUserId))
|
||||
{
|
||||
var userManagerApp = AutofacContainerModule.GetService<UserManagerApp>();
|
||||
var parentId = userManagerApp.GetParent(preNodeUserId);
|
||||
if (!StringExtension.IsNullOrEmpty(parentId))
|
||||
{
|
||||
makerList = GenericHelpers.ArrayToString(new[] { parentId }, makerList);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (node.setInfo.NodeDesignate == Define.RUNTIME_CHAIRMAN)
|
||||
{
|
||||
//驳回/撤销场景:获取发起人的部门负责人
|
||||
var orgManagerApp = AutofacContainerModule.GetService<OrgManagerApp>();
|
||||
var chairmanIds = orgManagerApp.GetChairmanId(node.setInfo.NodeDesignateData?.datas);
|
||||
makerList = GenericHelpers.ArrayToString(chairmanIds, makerList);
|
||||
}
|
||||
else
|
||||
{
|
||||
makerList = ResolveDesignateUsers(node.setInfo.NodeDesignate, node.setInfo.NodeDesignateData?.datas);
|
||||
}
|
||||
}
|
||||
else //如果没有设置节点信息,属于流程设计异常
|
||||
{
|
||||
throw new Exception($"节点【{node.name}】未设置审批人信息,请检查流程设计!");
|
||||
}
|
||||
|
||||
return makerList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据指定类型和指定数据解析审批人列表(公共辅助方法)
|
||||
/// </summary>
|
||||
/// <param name="designateType">节点指定类型</param>
|
||||
/// <param name="designateData">节点指定数据</param>
|
||||
/// <returns>审批人列表字符串</returns>
|
||||
private string ResolveDesignateUsers(string designateType, string[] designateData)
|
||||
{
|
||||
string makerList = "";
|
||||
if (string.IsNullOrEmpty(designateType) || designateType == Define.ALL_USER) //所有成员
|
||||
{
|
||||
makerList = "1";
|
||||
}
|
||||
else if (designateType == Define.SPECIAL_USER) //指定成员
|
||||
{
|
||||
makerList = GenericHelpers.ArrayToString(designateData, makerList);
|
||||
}
|
||||
else if (designateType == Define.SPECIAL_ROLE) //指定角色
|
||||
{
|
||||
var revelanceApp = AutofacContainerModule.GetService<RevelanceManagerApp>();
|
||||
var users = revelanceApp.Get(Define.USERROLE, false, designateData);
|
||||
makerList = GenericHelpers.ArrayToString(users, makerList);
|
||||
}
|
||||
else if (designateType == Define.SPECIAL_SQL) //指定SQL
|
||||
{
|
||||
var sql = ReplaceSql(designateData[0]);
|
||||
var sugarClient = AutofacContainerModule.GetService<ISqlSugarClient>();
|
||||
var result = sugarClient.Ado.SqlQuery<string>(sql);
|
||||
makerList = GenericHelpers.ArrayToString(result, makerList);
|
||||
}
|
||||
|
||||
return makerList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算多实例、会签节点的执行人
|
||||
/// </summary>
|
||||
@@ -762,57 +868,6 @@ namespace OpenAuth.App.Flow
|
||||
return GenericHelpers.ArrayToString(makerList, "");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 这里专门处理由前端选择相关的节点执行人
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
/// <returns></returns>
|
||||
public string GetNodeMarkers(FlowNode node, string flowinstanceCreateUserId = "")
|
||||
{
|
||||
string makerList = "";
|
||||
if (node.type == Define.NODE_TYPE_START && (!string.IsNullOrEmpty(flowinstanceCreateUserId))) //如果是开始节点,通常情况下是驳回到开始了
|
||||
{
|
||||
makerList = flowinstanceCreateUserId;
|
||||
}
|
||||
else if (node.setInfo != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(node.setInfo.NodeDesignate) ||
|
||||
node.setInfo.NodeDesignate == Define.ALL_USER) //所有成员
|
||||
{
|
||||
makerList = "1";
|
||||
}
|
||||
else if (node.setInfo.NodeDesignate == Define.SPECIAL_USER) //指定成员
|
||||
{
|
||||
makerList = GenericHelpers.ArrayToString(node.setInfo.NodeDesignateData.datas, makerList);
|
||||
}
|
||||
else if (node.setInfo.NodeDesignate == Define.SPECIAL_ROLE) //指定角色
|
||||
{
|
||||
var revelanceApp = AutofacContainerModule.GetService<RevelanceManagerApp>();
|
||||
var users = revelanceApp.Get(Define.USERROLE, false, node.setInfo.NodeDesignateData.datas);
|
||||
makerList = GenericHelpers.ArrayToString(users, makerList);
|
||||
}
|
||||
else if (node.setInfo.NodeDesignate == Define.SPECIAL_SQL) //指定SQL
|
||||
{
|
||||
//如果是指定SQL,则需要执行SQL,并返回结果
|
||||
var sql = ReplaceSql(node.setInfo.NodeDesignateData.datas[0]);
|
||||
var sugarClient = AutofacContainerModule.GetService<ISqlSugarClient>();
|
||||
var result = sugarClient.Ado.SqlQuery<string>(sql);
|
||||
makerList = GenericHelpers.ArrayToString(result, makerList);
|
||||
}
|
||||
else if (node.setInfo.NodeDesignate == Define.RUNTIME_SPECIAL_ROLE
|
||||
|| node.setInfo.NodeDesignate == Define.RUNTIME_SPECIAL_USER)
|
||||
{
|
||||
//如果是运行时选定的用户,则暂不处理。由上个节点审批时选定
|
||||
}
|
||||
}
|
||||
else //如果没有设置节点信息,默认所有人都可以审核
|
||||
{
|
||||
makerList = "1";
|
||||
}
|
||||
|
||||
return makerList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 替换SQL中的权限占位符
|
||||
/// <para>如当前用户的全部下属:select id from sysuser where parentId = {loginUser}</para>
|
||||
|
||||
@@ -103,22 +103,23 @@ namespace OpenAuth.App
|
||||
/// </summary>
|
||||
public FlowApprover[] GetApprovers(QueryApproverReq req)
|
||||
{
|
||||
var query= Repository.AsQueryable()
|
||||
// 一次查询,内存中处理,避免 ISugarQueryable 状态污染
|
||||
var all = Repository.AsQueryable()
|
||||
.Where(u => u.InstanceId == req.FlowInstanceId
|
||||
&& u.ActivityId == req.ActivityId && u.Status == 0); //本节点待审批的加签人
|
||||
if (query.Count() == 0)
|
||||
&& u.ActivityId == req.ActivityId && u.Status == 0)
|
||||
.OrderBy(u => u.OrderNo)
|
||||
.ToArray();
|
||||
|
||||
if (all.Length == 0) return null;
|
||||
|
||||
// 顺序执行:只返回第一个
|
||||
if (all[0].ApproveType == Define.APPROVE_TYPE_SEQUENTIAL)
|
||||
{
|
||||
return null;
|
||||
return new[] { all[0] };
|
||||
}
|
||||
|
||||
//如果是顺序执行,取第一个人
|
||||
if (query.First().ApproveType == Define.APPROVE_TYPE_SEQUENTIAL)
|
||||
{
|
||||
var result = query.OrderBy(u => u.OrderNo).First();
|
||||
return new[] { result };
|
||||
}
|
||||
//否则并行且/并行或都是返回所有加签人
|
||||
return query.ToArray();
|
||||
|
||||
// 并行且/并行或:返回全部
|
||||
return all;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: yubaolee <yubaolee@163.com> | ahfu~ <954478625@qq.com>
|
||||
* @Date: 2024-12-13 16:55:17
|
||||
* @Description: 工作流实例表操作
|
||||
* @LastEditTime: 2025-10-18 14:35:01
|
||||
* @LastEditTime: 2026-06-11 22:35:03
|
||||
* Copyright (c) 2024 by yubaolee | ahfu~ , All Rights Reserved.
|
||||
*/
|
||||
|
||||
@@ -512,6 +512,7 @@ namespace OpenAuth.App
|
||||
else //审批结果为不同意
|
||||
{
|
||||
flowInstance.IsFinish = FlowInstanceStatus.Disagree;
|
||||
flowInstance.MakerList = "";
|
||||
wfruntime.nextNodeId = "-1";
|
||||
}
|
||||
|
||||
@@ -520,7 +521,7 @@ namespace OpenAuth.App
|
||||
$"结果:{(tag.Taged == 1 ? "同意" : "不同意")},备注:{tag.Description}";
|
||||
wfruntime.SaveOperationHis(tag.UserId, tag.UserName, content);
|
||||
|
||||
if (flowInstance.IsFinish == 1)
|
||||
if (flowInstance.IsFinish == FlowInstanceStatus.Finished)
|
||||
{
|
||||
//给知会人员发送通知信息
|
||||
var userids = _userManagerApp.GetNoticeUsers(flowInstance.Id);
|
||||
@@ -592,20 +593,20 @@ namespace OpenAuth.App
|
||||
/// </summary>
|
||||
public void Verification(VerificationReq request)
|
||||
{
|
||||
TagState tagState = (TagState)Int32.Parse(request.VerificationFinally);
|
||||
//如果是同意,需要判断是否为运行时选定下一步执行角色/执行人
|
||||
if (request.VerificationFinally == "1")
|
||||
if (tagState == TagState.Ok)
|
||||
{
|
||||
CheckNodeDesignate(request);
|
||||
}
|
||||
|
||||
bool isReject = TagState.Reject.Equals((TagState)Int32.Parse(request.VerificationFinally));
|
||||
if (isReject) //驳回
|
||||
|
||||
if (tagState == TagState.Reject)
|
||||
{
|
||||
RejectNode(request);
|
||||
RejectNode(request); // 驳回
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeVerification(request);
|
||||
NodeVerification(request); // 审核(同意/不同意)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -660,7 +661,13 @@ namespace OpenAuth.App
|
||||
ActivityId = flowinstance.ActivityId
|
||||
});
|
||||
|
||||
if (flowinstance.MakerList != "1" && !flowinstance.MakerList.Contains(user.User.Id) &&
|
||||
//流程已终止(完成/不同意/撤销等),不允许继续审批
|
||||
if (flowinstance.IsFinish != FlowInstanceStatus.Running && flowinstance.IsFinish != FlowInstanceStatus.Rejected)
|
||||
{
|
||||
resp.CanVerify = false;
|
||||
}
|
||||
//当前用户不是当前节点的审批人,不允许继续审批
|
||||
else if (flowinstance.MakerList != "1" && !flowinstance.MakerList.Contains(user.User.Id) &&
|
||||
!approvers.Contains(user.User.Id))
|
||||
{
|
||||
resp.CanVerify = false;
|
||||
|
||||
@@ -48,6 +48,8 @@ namespace OpenAuth.App
|
||||
FrmUrlTemplate = flowScheme.FrmUrlTemplate,
|
||||
Disabled = flowScheme.Disabled,
|
||||
Description = flowScheme.Description,
|
||||
CreateDate = flowScheme.CreateDate,
|
||||
SchemeCode = flowScheme.SchemeCode,
|
||||
OrgId = flowScheme.OrgId
|
||||
},u => u.Id == flowScheme.Id);
|
||||
}
|
||||
|
||||
@@ -3,9 +3,8 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using Infrastructure;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OpenAuth.Repository;
|
||||
using OpenAuth.Repository.Interface;
|
||||
using OpenAuth.Repository.QueryObj;
|
||||
using SqlSugar;
|
||||
namespace OpenAuth.App
|
||||
{
|
||||
/// <summary>
|
||||
@@ -13,10 +12,10 @@ namespace OpenAuth.App
|
||||
/// </summary>
|
||||
public class DragForm: IForm
|
||||
{
|
||||
private IUnitWork<OpenAuthDBContext> _unitWork;
|
||||
public DragForm(IUnitWork<OpenAuthDBContext> unitWork)
|
||||
private ISqlSugarClient _sugarClient;
|
||||
public DragForm(ISqlSugarClient sugarClient)
|
||||
{
|
||||
_unitWork = unitWork;
|
||||
_sugarClient = sugarClient;
|
||||
}
|
||||
/**
|
||||
* 功能: 创建表单数据表格(基于sql server)
|
||||
@@ -29,7 +28,7 @@ namespace OpenAuth.App
|
||||
var jsonArray = JsonHelper.Instance.Deserialize<JObject>(form.ContentData)["widgetList"];
|
||||
string tableName = form.DbName;
|
||||
//如果数据库已经存在该表,则不用创建
|
||||
var exist = _unitWork.FromSql<QueryStringObj>($"select '1' as value from sysobjects where name = '{tableName}' and type = 'U'").SingleOrDefault();
|
||||
var exist = _sugarClient.Ado.SqlQuery<QueryStringObj>($"select '1' as value from sysobjects where name = '{tableName}' and type = 'U'").SingleOrDefault();
|
||||
if (exist != null) return string.Empty;
|
||||
// 如果数据库没有指定的表,则创建表
|
||||
StringBuilder sql = new StringBuilder($"CREATE TABLE {tableName} ( [Id] varchar(50) COLLATE Chinese_PRC_CI_AS NOT NULL,"); //主键
|
||||
@@ -62,7 +61,7 @@ namespace OpenAuth.App
|
||||
var jsonArray = JsonHelper.Instance.Deserialize<JObject>(form.ContentData)["widgetList"];
|
||||
string tableName = form.DbName;
|
||||
//如果数据库已经存在该表,则不用创建
|
||||
var exist = _unitWork.FromSql<QueryStringObj>($"select distinct table_name as value from information_schema.tables where table_name ='{tableName}'").SingleOrDefault();
|
||||
var exist = _sugarClient.Ado.SqlQuery<QueryStringObj>($"select distinct table_name as value from information_schema.tables where table_name ='{tableName}'").SingleOrDefault();
|
||||
if (exist != null) return string.Empty;
|
||||
// 如果数据库没有指定的表,则创建表
|
||||
StringBuilder sql = new StringBuilder($"create table if not exists `{tableName}` ( Id varchar(50) not null primary key,"); //主键
|
||||
|
||||
@@ -4,19 +4,17 @@ using System.Threading.Tasks;
|
||||
using Infrastructure;
|
||||
using Infrastructure.Utilities;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Options;
|
||||
using OpenAuth.App.Interface;
|
||||
using OpenAuth.App.Request;
|
||||
using OpenAuth.App.Response;
|
||||
using OpenAuth.Repository;
|
||||
using OpenAuth.Repository.Domain;
|
||||
using OpenAuth.Repository.Interface;
|
||||
using SqlSugar;
|
||||
|
||||
|
||||
namespace OpenAuth.App
|
||||
{
|
||||
public class FormApp : BaseStringApp<Form,OpenAuthDBContext>
|
||||
public class FormApp : SqlSugarBaseApp<Form>
|
||||
{
|
||||
private IOptions<AppSetting> _appConfiguration;
|
||||
private IHttpContextAccessor _httpContextAccessor;
|
||||
@@ -44,19 +42,21 @@ namespace OpenAuth.App
|
||||
var user = _auth.GetCurrentUser().User;
|
||||
obj.CreateUserId = user.Id;
|
||||
obj.CreateUserName = user.Name;
|
||||
UnitWork.Add(obj);
|
||||
Repository.Insert(obj);
|
||||
if (!string.IsNullOrEmpty(obj.DbName))
|
||||
{
|
||||
var dbtype = _appConfiguration.Value.DbTypes[_httpContextAccessor.GetTenantId()];
|
||||
|
||||
UnitWork.ExecuteSql(FormFactory.CreateForm(obj, this.UnitWork).GetSql(obj, dbtype));
|
||||
var sql = FormFactory.CreateForm(obj, SugarClient).GetSql(obj, dbtype);
|
||||
if (!string.IsNullOrEmpty(sql))
|
||||
{
|
||||
SugarClient.Ado.ExecuteCommand(sql);
|
||||
}
|
||||
}
|
||||
UnitWork.Save();
|
||||
}
|
||||
|
||||
public void Update(Form obj)
|
||||
{
|
||||
Repository.Update(u => u.Id == obj.Id, u => new Form
|
||||
Repository.Update(u => new Form
|
||||
{
|
||||
FrmType = obj.FrmType,
|
||||
ContentData = obj.ContentData,
|
||||
@@ -69,12 +69,16 @@ namespace OpenAuth.App
|
||||
Description = obj.Description,
|
||||
OrgId = obj.OrgId,
|
||||
ModifyDate = DateTime.Now
|
||||
});
|
||||
}, u => u.Id == obj.Id);
|
||||
|
||||
if (!string.IsNullOrEmpty(obj.DbName))
|
||||
{
|
||||
var dbtype = _appConfiguration.Value.DbTypes[_httpContextAccessor.GetTenantId()];
|
||||
UnitWork.ExecuteSql(FormFactory.CreateForm(obj,this.UnitWork).GetSql(obj, dbtype));
|
||||
var sql = FormFactory.CreateForm(obj, SugarClient).GetSql(obj, dbtype);
|
||||
if (!string.IsNullOrEmpty(sql))
|
||||
{
|
||||
SugarClient.Ado.ExecuteCommand(sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,8 +88,8 @@ namespace OpenAuth.App
|
||||
return form.MapTo<FormResp>();
|
||||
}
|
||||
|
||||
public FormApp(IUnitWork<OpenAuthDBContext> unitWork, IRepository<Form,OpenAuthDBContext> repository,
|
||||
IAuth auth, IOptions<AppSetting> appConfiguration, IHttpContextAccessor httpContextAccessor) : base(unitWork, repository, auth)
|
||||
public FormApp(ISqlSugarClient client,
|
||||
IAuth auth, IOptions<AppSetting> appConfiguration, IHttpContextAccessor httpContextAccessor) : base(client, auth)
|
||||
{
|
||||
_auth = auth;
|
||||
_appConfiguration = appConfiguration;
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
using System;
|
||||
using OpenAuth.Repository;
|
||||
using OpenAuth.Repository.Domain;
|
||||
using OpenAuth.Repository.Interface;
|
||||
using Infrastructure;
|
||||
using SqlSugar;
|
||||
|
||||
namespace OpenAuth.App
|
||||
{
|
||||
public class FormFactory
|
||||
{
|
||||
public static IForm CreateForm(Form form, IUnitWork<OpenAuthDBContext> unitWork)
|
||||
public static IForm CreateForm(Form form, ISqlSugarClient sugarClient)
|
||||
{
|
||||
if (form.FrmType == Define.FORM_TYPE_DYNAMIC)
|
||||
{
|
||||
return new LeipiForm(unitWork);
|
||||
return new LeipiForm(sugarClient);
|
||||
}else if (form.FrmType == Define.FORM_TYPE_DEVELOP)
|
||||
{
|
||||
throw new Exception("自定义表单不需要创建数据库表");
|
||||
}
|
||||
else
|
||||
{
|
||||
return new DragForm(unitWork);
|
||||
return new DragForm(sugarClient);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,16 @@
|
||||
using System.Text;
|
||||
using Infrastructure;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OpenAuth.Repository;
|
||||
using OpenAuth.Repository.Interface;
|
||||
using OpenAuth.Repository.QueryObj;
|
||||
using SqlSugar;
|
||||
namespace OpenAuth.App
|
||||
{
|
||||
public class LeipiForm : IForm
|
||||
{
|
||||
private IUnitWork<OpenAuthDBContext> _unitWork;
|
||||
public LeipiForm(IUnitWork<OpenAuthDBContext> unitWork)
|
||||
private ISqlSugarClient _sugarClient;
|
||||
public LeipiForm(ISqlSugarClient sugarClient)
|
||||
{
|
||||
_unitWork = unitWork;
|
||||
_sugarClient = sugarClient;
|
||||
}
|
||||
/**
|
||||
* 功能: 创建表单数据表格(基于sql server)
|
||||
@@ -25,7 +24,7 @@ namespace OpenAuth.App
|
||||
var jsonArray = JArray.Parse(form.ContentData);
|
||||
// 数据库名称
|
||||
string tableName = form.DbName;
|
||||
var exist = _unitWork.FromSql<QueryStringObj>($"select '1' as value from sysobjects where name = '{tableName}' and type = 'U'").SingleOrDefault();
|
||||
var exist = _sugarClient.Ado.SqlQuery<QueryStringObj>($"select '1' as value from sysobjects where name = '{tableName}' and type = 'U'").SingleOrDefault();
|
||||
if (exist != null) return string.Empty;
|
||||
// 创建数据表
|
||||
StringBuilder sql = new StringBuilder($"CREATE TABLE {tableName} ( [Id] varchar(50) COLLATE Chinese_PRC_CI_AS NOT NULL,"); //主键
|
||||
@@ -61,7 +60,7 @@ namespace OpenAuth.App
|
||||
var jsonArray = JArray.Parse(form.ContentData);
|
||||
// 数据库名称
|
||||
string tableName = form.DbName;
|
||||
var exist = _unitWork.FromSql<QueryStringObj>($"select distinct table_name as value from information_schema.tables where table_name ='{tableName}'").SingleOrDefault();
|
||||
var exist = _sugarClient.Ado.SqlQuery<QueryStringObj>($"select distinct table_name as value from information_schema.tables where table_name ='{tableName}'").SingleOrDefault();
|
||||
if (exist != null) return string.Empty;
|
||||
// 创建数据表
|
||||
StringBuilder sql = new StringBuilder($"create table if not exists `{tableName}` ( Id varchar(50) not null primary key,"); //主键
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
using System.Threading.Tasks;
|
||||
using Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OpenAuth.App.Interface;
|
||||
using OpenAuth.App.Request;
|
||||
using OpenAuth.App.Response;
|
||||
using OpenAuth.Repository;
|
||||
using OpenAuth.Repository.Domain;
|
||||
using OpenAuth.Repository.Interface;
|
||||
using SqlSugar;
|
||||
|
||||
|
||||
namespace OpenAuth.App
|
||||
{
|
||||
public class FrmLeaveReqApp : BaseStringApp<FrmLeaveReq,OpenAuthDBContext>, ICustomerForm
|
||||
public class FrmLeaveReqApp : SqlSugarBaseApp<FrmLeaveReq>, ICustomerForm
|
||||
{
|
||||
private RevelanceManagerApp _revelanceApp;
|
||||
|
||||
@@ -22,18 +20,20 @@ namespace OpenAuth.App
|
||||
{
|
||||
return new PagedDynamicDataResp
|
||||
{
|
||||
Count = await Repository.CountAsync(null),
|
||||
Data = await Repository.Find(request.page, request.limit, "Id desc").ToListAsync()
|
||||
Count = await SugarClient.Queryable<FrmLeaveReq>().CountAsync(),
|
||||
Data = await SugarClient.Queryable<FrmLeaveReq>().OrderByDescending(u => u.Id)
|
||||
.Skip((request.page - 1) * request.limit)
|
||||
.Take(request.limit).ToListAsync()
|
||||
};
|
||||
}
|
||||
|
||||
public void Add(FrmLeaveReq obj)
|
||||
{
|
||||
Repository.Add(obj);
|
||||
Repository.Insert(obj);
|
||||
}
|
||||
|
||||
public FrmLeaveReqApp(IUnitWork<OpenAuthDBContext> unitWork, IRepository<FrmLeaveReq,OpenAuthDBContext> repository,
|
||||
RevelanceManagerApp app,IAuth auth) : base(unitWork, repository, auth)
|
||||
public FrmLeaveReqApp(ISqlSugarClient client,
|
||||
RevelanceManagerApp app,IAuth auth) : base(client, auth)
|
||||
{
|
||||
_revelanceApp = app;
|
||||
}
|
||||
@@ -48,13 +48,13 @@ namespace OpenAuth.App
|
||||
public void Update(string flowInstanceId, string frmData)
|
||||
{
|
||||
var req = JsonHelper.Instance.Deserialize<FrmLeaveReq>(frmData);
|
||||
UnitWork.Update<FrmLeaveReq>(u => u.FlowInstanceId == flowInstanceId, u => new FrmLeaveReq
|
||||
Repository.Update(u => new FrmLeaveReq
|
||||
{
|
||||
UserName = req.UserName,
|
||||
RequestComment = req.RequestComment,
|
||||
RequestType = req.RequestType
|
||||
//补充其他需要更新的字段
|
||||
});
|
||||
}, u => u.FlowInstanceId == flowInstanceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,12 @@ using System.Linq;
|
||||
using Infrastructure;
|
||||
using OpenAuth.App.Interface;
|
||||
using OpenAuth.App.Request;
|
||||
using OpenAuth.Repository;
|
||||
using OpenAuth.Repository.Domain;
|
||||
using OpenAuth.Repository.Interface;
|
||||
using SqlSugar;
|
||||
|
||||
namespace OpenAuth.App
|
||||
{
|
||||
public class ModuleManagerApp : BaseTreeApp<Module,OpenAuthDBContext>
|
||||
public class ModuleManagerApp : SqlSugarBaseTreeApp<Module>
|
||||
{
|
||||
private RevelanceManagerApp _revelanceApp;
|
||||
|
||||
@@ -23,7 +22,7 @@ namespace OpenAuth.App
|
||||
|
||||
CaculateCascade(model);
|
||||
|
||||
Repository.Add(model);
|
||||
Repository.Insert(model);
|
||||
|
||||
AddDefaultMenus(model);
|
||||
//当前登录用户的所有角色自动分配模块
|
||||
@@ -52,9 +51,9 @@ namespace OpenAuth.App
|
||||
/// <param name="roleId">The role unique identifier.</param>
|
||||
public IEnumerable<Module> LoadForRole(string roleId)
|
||||
{
|
||||
var moduleIds = UnitWork.Find<Relevance>(u => u.FirstId == roleId && u.RelKey == Define.ROLEMODULE)
|
||||
.Select(u => u.SecondId);
|
||||
return UnitWork.Find<Module>(u => moduleIds.Contains(u.Id)).OrderBy(u => u.SortNo);
|
||||
var moduleIds = SugarClient.Queryable<Relevance>().Where(u => u.FirstId == roleId && u.RelKey == Define.ROLEMODULE)
|
||||
.Select(u => u.SecondId).ToArray();
|
||||
return SugarClient.Queryable<Module>().Where(u => moduleIds.Contains(u.Id)).OrderBy(u => u.SortNo).ToList();
|
||||
}
|
||||
|
||||
//获取角色可访问的模块字段
|
||||
@@ -68,14 +67,14 @@ namespace OpenAuth.App
|
||||
/// </summary>
|
||||
public IEnumerable<ModuleElement> LoadMenusForRole(string moduleId, string roleId)
|
||||
{
|
||||
var elementIds = _revelanceApp.Get(Define.ROLEELEMENT, true, roleId);
|
||||
var query = UnitWork.Find<ModuleElement>(u => elementIds.Contains(u.Id));
|
||||
var elementIds = _revelanceApp.Get(Define.ROLEELEMENT, true, roleId).ToArray();
|
||||
var query = SugarClient.Queryable<ModuleElement>().Where(u => elementIds.Contains(u.Id));
|
||||
if (!string.IsNullOrEmpty(moduleId))
|
||||
{
|
||||
query = query.Where(u => u.ModuleId == moduleId);
|
||||
}
|
||||
|
||||
return query;
|
||||
return query.ToList();
|
||||
}
|
||||
|
||||
#endregion 用户/角色分配模块
|
||||
@@ -87,9 +86,9 @@ namespace OpenAuth.App
|
||||
/// <returns></returns>
|
||||
public IEnumerable<SysPrinterPlan> LoadPrinterPlans(string moduleId)
|
||||
{
|
||||
var planids = _revelanceApp.Get(Define.MODULEPRINTERPLAN, true, moduleId);
|
||||
var query = UnitWork.Find<SysPrinterPlan>(u => planids.Contains(u.Id));
|
||||
return query;
|
||||
var planids = _revelanceApp.Get(Define.MODULEPRINTERPLAN, true, moduleId).ToArray();
|
||||
var query = SugarClient.Queryable<SysPrinterPlan>().Where(u => planids.Contains(u.Id));
|
||||
return query.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -99,9 +98,9 @@ namespace OpenAuth.App
|
||||
/// <returns></returns>
|
||||
public IEnumerable<FlowScheme> LoadFlowSchemes(string moduleId)
|
||||
{
|
||||
var planids = _revelanceApp.Get(Define.MODULE_FLOWSCHEME, true, moduleId);
|
||||
var query = UnitWork.Find<FlowScheme>(u => planids.Contains(u.Id));
|
||||
return query;
|
||||
var planids = _revelanceApp.Get(Define.MODULE_FLOWSCHEME, true, moduleId).ToArray();
|
||||
var query = SugarClient.Queryable<FlowScheme>().Where(u => planids.Contains(u.Id));
|
||||
return query.ToList();
|
||||
}
|
||||
|
||||
|
||||
@@ -113,8 +112,7 @@ namespace OpenAuth.App
|
||||
/// <param name="ids"></param>
|
||||
public void DelMenu(string[] ids)
|
||||
{
|
||||
UnitWork.Delete<ModuleElement>(u => ids.Contains(u.Id));
|
||||
UnitWork.Save();
|
||||
SugarClient.Deleteable<ModuleElement>().Where(u => ids.Contains(u.Id)).ExecuteCommand();
|
||||
}
|
||||
|
||||
|
||||
@@ -130,28 +128,29 @@ namespace OpenAuth.App
|
||||
throw new CommonException("登录已过期", Define.INVALID_TOKEN);
|
||||
}
|
||||
|
||||
UnitWork.ExecuteWithTransaction(() =>
|
||||
SugarClient.Ado.BeginTran();
|
||||
if (model.KeyIsNull())
|
||||
{
|
||||
UnitWork.Add(model);
|
||||
model.GenerateDefaultKeyVal();
|
||||
}
|
||||
SugarClient.Insertable(model).ExecuteCommand();
|
||||
|
||||
//当前登录用户的所有角色自动分配菜单
|
||||
loginContext.Roles.ForEach(u =>
|
||||
//当前登录用户的所有角色自动分配菜单
|
||||
loginContext.Roles.ForEach(u =>
|
||||
{
|
||||
_revelanceApp.Assign(new AssignReq
|
||||
{
|
||||
_revelanceApp.Assign(new AssignReq
|
||||
{
|
||||
type = Define.ROLEELEMENT,
|
||||
firstId = u.Id,
|
||||
secIds = new[] {model.Id}
|
||||
});
|
||||
type = Define.ROLEELEMENT,
|
||||
firstId = u.Id,
|
||||
secIds = new[] {model.Id}
|
||||
});
|
||||
UnitWork.Save();
|
||||
});
|
||||
SugarClient.Ado.CommitTran();
|
||||
}
|
||||
|
||||
public void UpdateMenu(ModuleElement model)
|
||||
{
|
||||
UnitWork.Update<ModuleElement>(model);
|
||||
UnitWork.Save();
|
||||
SugarClient.Updateable(model).ExecuteCommand();
|
||||
}
|
||||
|
||||
//添加默认按钮
|
||||
@@ -197,8 +196,8 @@ namespace OpenAuth.App
|
||||
#endregion
|
||||
|
||||
|
||||
public ModuleManagerApp(IUnitWork<OpenAuthDBContext> unitWork, IRepository<Module,OpenAuthDBContext> repository
|
||||
, RevelanceManagerApp app, IAuth auth) : base(unitWork, repository, auth)
|
||||
public ModuleManagerApp(ISqlSugarClient client
|
||||
, RevelanceManagerApp app, IAuth auth) : base(client, auth)
|
||||
{
|
||||
_revelanceApp = app;
|
||||
}
|
||||
|
||||
@@ -6,17 +6,15 @@ using Infrastructure.Helpers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using OpenAuth.App.Interface;
|
||||
using OpenAuth.App.Request;
|
||||
using OpenAuth.Repository;
|
||||
using OpenAuth.Repository.Domain;
|
||||
using OpenAuth.Repository.Interface;
|
||||
using SqlSugar;
|
||||
|
||||
namespace OpenAuth.App
|
||||
{
|
||||
public class RevelanceManagerApp : BaseStringApp<Relevance,OpenAuthDBContext>
|
||||
public class RevelanceManagerApp : SqlSugarBaseApp<Relevance>
|
||||
{
|
||||
private readonly ILogger<RevelanceManagerApp> _logger;
|
||||
public RevelanceManagerApp(IUnitWork<OpenAuthDBContext> unitWork, IRepository<Relevance,OpenAuthDBContext> repository, IAuth auth, ILogger<RevelanceManagerApp> logger) : base(unitWork,
|
||||
repository, auth)
|
||||
public RevelanceManagerApp(ISqlSugarClient client, IAuth auth, ILogger<RevelanceManagerApp> logger) : base(client, auth)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
@@ -38,7 +36,7 @@ namespace OpenAuth.App
|
||||
/// <param name="idMaps"></param>
|
||||
public void Assign(string key, ILookup<string, string> idMaps)
|
||||
{
|
||||
UnitWork.BatchAdd((from sameVals in idMaps
|
||||
SugarClient.Insertable((from sameVals in idMaps
|
||||
from value in sameVals
|
||||
select new Relevance
|
||||
{
|
||||
@@ -46,8 +44,7 @@ namespace OpenAuth.App
|
||||
FirstId = sameVals.Key,
|
||||
SecondId = value,
|
||||
OperateTime = TimeHelper.Now
|
||||
}).ToArray());
|
||||
UnitWork.Save();
|
||||
}).ToArray()).ExecuteCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -82,7 +79,7 @@ namespace OpenAuth.App
|
||||
_logger.LogInformation($"start=> delete {key} {sameVals.Key} {value}");
|
||||
try
|
||||
{
|
||||
UnitWork.Delete<Relevance>(u => u.RelKey == key && u.FirstId == sameVals.Key && u.SecondId == value);
|
||||
SugarClient.Deleteable<Relevance>().Where(u => u.RelKey == key && u.FirstId == sameVals.Key && u.SecondId == value).ExecuteCommand();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -95,7 +92,7 @@ namespace OpenAuth.App
|
||||
|
||||
public void DeleteBy(string key, params string[] firstIds)
|
||||
{
|
||||
UnitWork.Delete<Relevance>(u => firstIds.Contains(u.FirstId) && u.RelKey == key);
|
||||
SugarClient.Deleteable<Relevance>().Where(u => firstIds.Contains(u.FirstId) && u.RelKey == key).ExecuteCommand();
|
||||
}
|
||||
|
||||
|
||||
@@ -110,12 +107,12 @@ namespace OpenAuth.App
|
||||
{
|
||||
if (returnSecondIds)
|
||||
{
|
||||
return Repository.Find(u => u.RelKey == key
|
||||
return SugarClient.Queryable<Relevance>().Where(u => u.RelKey == key
|
||||
&& ids.Contains(u.FirstId)).Select(u => u.SecondId).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Repository.Find(u => u.RelKey == key
|
||||
return SugarClient.Queryable<Relevance>().Where(u => u.RelKey == key
|
||||
&& ids.Contains(u.SecondId)).Select(u => u.FirstId).ToList();
|
||||
}
|
||||
}
|
||||
@@ -129,7 +126,7 @@ namespace OpenAuth.App
|
||||
/// <returns></returns>
|
||||
public List<string> Get(string key, string firstId, string secondId)
|
||||
{
|
||||
return Repository.Find(u => u.RelKey == key && u.FirstId == firstId && u.SecondId == secondId)
|
||||
return SugarClient.Queryable<Relevance>().Where(u => u.RelKey == key && u.FirstId == firstId && u.SecondId == secondId)
|
||||
.Select(u => u.ThirdId).ToList();
|
||||
}
|
||||
|
||||
@@ -157,8 +154,7 @@ namespace OpenAuth.App
|
||||
});
|
||||
}
|
||||
|
||||
UnitWork.BatchAdd(relevances.ToArray());
|
||||
UnitWork.Save();
|
||||
SugarClient.Insertable(relevances).ExecuteCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -182,10 +178,10 @@ namespace OpenAuth.App
|
||||
{
|
||||
foreach (var property in request.Properties)
|
||||
{
|
||||
UnitWork.Delete<Relevance>(u => u.RelKey == Define.ROLEDATAPROPERTY
|
||||
SugarClient.Deleteable<Relevance>().Where(u => u.RelKey == Define.ROLEDATAPROPERTY
|
||||
&& u.FirstId == request.RoleId
|
||||
&& u.SecondId == request.ModuleCode
|
||||
&& u.ThirdId == property);
|
||||
&& u.ThirdId == property).ExecuteCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,21 +192,19 @@ namespace OpenAuth.App
|
||||
/// <param name="request"></param>
|
||||
public void AssignRoleUsers(AssignRoleUsers request)
|
||||
{
|
||||
UnitWork.ExecuteWithTransaction(() =>
|
||||
{
|
||||
//删除以前的所有用户
|
||||
UnitWork.Delete<Relevance>(u => u.SecondId == request.RoleId && u.RelKey == Define.USERROLE);
|
||||
//批量分配用户角色
|
||||
UnitWork.BatchAdd((from firstId in request.UserIds
|
||||
SugarClient.Ado.BeginTran();
|
||||
//删除以前的所有用户
|
||||
SugarClient.Deleteable<Relevance>().Where(u => u.SecondId == request.RoleId && u.RelKey == Define.USERROLE).ExecuteCommand();
|
||||
//批量分配用户角色
|
||||
SugarClient.Insertable((from firstId in request.UserIds
|
||||
select new Relevance
|
||||
{
|
||||
RelKey = Define.USERROLE,
|
||||
FirstId = firstId,
|
||||
SecondId = request.RoleId,
|
||||
OperateTime = TimeHelper.Now
|
||||
}).ToArray());
|
||||
UnitWork.Save();
|
||||
});
|
||||
}).ToArray()).ExecuteCommand();
|
||||
SugarClient.Ado.CommitTran();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -219,21 +213,19 @@ namespace OpenAuth.App
|
||||
/// <param name="request"></param>
|
||||
public void AssignOrgUsers(AssignOrgUsers request)
|
||||
{
|
||||
UnitWork.ExecuteWithTransaction(() =>
|
||||
{
|
||||
//删除以前的所有用户
|
||||
UnitWork.Delete<Relevance>(u => u.SecondId == request.OrgId && u.RelKey == Define.USERORG);
|
||||
//批量分配用户角色
|
||||
UnitWork.BatchAdd((from firstId in request.UserIds
|
||||
SugarClient.Ado.BeginTran();
|
||||
//删除以前的所有用户
|
||||
SugarClient.Deleteable<Relevance>().Where(u => u.SecondId == request.OrgId && u.RelKey == Define.USERORG).ExecuteCommand();
|
||||
//批量分配用户角色
|
||||
SugarClient.Insertable((from firstId in request.UserIds
|
||||
select new Relevance
|
||||
{
|
||||
RelKey = Define.USERORG,
|
||||
FirstId = firstId,
|
||||
SecondId = request.OrgId,
|
||||
OperateTime = TimeHelper.Now
|
||||
}).ToArray());
|
||||
UnitWork.Save();
|
||||
});
|
||||
}).ToArray()).ExecuteCommand();
|
||||
SugarClient.Ado.CommitTran();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -242,21 +234,19 @@ namespace OpenAuth.App
|
||||
/// <param name="request"></param>
|
||||
public void AssignRoleResources(AssignRoleResources request)
|
||||
{
|
||||
UnitWork.ExecuteWithTransaction(() =>
|
||||
{
|
||||
//删除以前的所有资源
|
||||
UnitWork.Delete<Relevance>(u => u.FirstId == request.RoleId && u.RelKey == Define.ROLERESOURCE);
|
||||
//批量分配角色资源
|
||||
UnitWork.BatchAdd((from firstId in request.ResourceIds
|
||||
SugarClient.Ado.BeginTran();
|
||||
//删除以前的所有资源
|
||||
SugarClient.Deleteable<Relevance>().Where(u => u.FirstId == request.RoleId && u.RelKey == Define.ROLERESOURCE).ExecuteCommand();
|
||||
//批量分配角色资源
|
||||
SugarClient.Insertable((from firstId in request.ResourceIds
|
||||
select new Relevance
|
||||
{
|
||||
RelKey = Define.ROLERESOURCE,
|
||||
FirstId = request.RoleId,
|
||||
SecondId = firstId,
|
||||
OperateTime = TimeHelper.Now
|
||||
}).ToArray());
|
||||
UnitWork.Save();
|
||||
});
|
||||
}).ToArray()).ExecuteCommand();
|
||||
SugarClient.Ado.CommitTran();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,15 @@
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OpenAuth.App.Request;
|
||||
using OpenAuth.App.Response;
|
||||
using OpenAuth.Repository;
|
||||
using OpenAuth.Repository.Domain;
|
||||
using OpenAuth.Repository.Interface;
|
||||
using SqlSugar;
|
||||
|
||||
|
||||
namespace OpenAuth.App
|
||||
{
|
||||
public class SysLogApp : BaseStringApp<SysLog,OpenAuthDBContext>
|
||||
public class SysLogApp : SqlSugarBaseApp<SysLog>
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
@@ -20,7 +18,7 @@ namespace OpenAuth.App
|
||||
public async Task<PagedDynamicDataResp> Load(QuerySysLogListReq request)
|
||||
{
|
||||
var result = new PagedDynamicDataResp();
|
||||
var objs = UnitWork.Find<SysLog>(null);
|
||||
var objs = SugarClient.Queryable<SysLog>();
|
||||
if (!string.IsNullOrEmpty(request.key))
|
||||
{
|
||||
objs = objs.Where(u => u.Content.Contains(request.key) || u.Id.Contains(request.key));
|
||||
@@ -37,19 +35,19 @@ namespace OpenAuth.App
|
||||
{
|
||||
//程序类型取入口应用的名称,可以根据自己需要调整
|
||||
obj.Application = Assembly.GetEntryAssembly().FullName.Split(',')[0];
|
||||
Repository.Add(obj);
|
||||
Repository.Insert(obj);
|
||||
}
|
||||
|
||||
public void Update(SysLog obj)
|
||||
{
|
||||
UnitWork.Update<SysLog>(u => u.Id == obj.Id, u => new SysLog
|
||||
Repository.Update(u => new SysLog
|
||||
{
|
||||
//todo:要修改的字段赋值
|
||||
});
|
||||
}, u => u.Id == obj.Id);
|
||||
|
||||
}
|
||||
|
||||
public SysLogApp(IUnitWork<OpenAuthDBContext> unitWork, IRepository<SysLog,OpenAuthDBContext> repository) : base(unitWork, repository, null)
|
||||
public SysLogApp(ISqlSugarClient client) : base(client, null)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,20 +2,18 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using OpenAuth.App.Interface;
|
||||
using OpenAuth.App.Request;
|
||||
using OpenAuth.App.Response;
|
||||
using OpenAuth.Repository;
|
||||
using OpenAuth.Repository.Domain;
|
||||
using OpenAuth.Repository.Interface;
|
||||
using Infrastructure.Helpers;
|
||||
using SqlSugar;
|
||||
|
||||
|
||||
namespace OpenAuth.App
|
||||
{
|
||||
public class SysMessageApp : BaseStringApp<SysMessage,OpenAuthDBContext>
|
||||
public class SysMessageApp : SqlSugarBaseApp<SysMessage>
|
||||
{
|
||||
private RevelanceManagerApp _revelanceApp;
|
||||
private readonly ILogger<SysMessageApp> _logger;
|
||||
@@ -32,7 +30,7 @@ namespace OpenAuth.App
|
||||
}
|
||||
|
||||
var result = new PagedDynamicDataResp();
|
||||
var objs = UnitWork.Find<SysMessage>(u =>u.ToId == loginContext.User.Id && u.ToStatus != -1);
|
||||
var objs = SugarClient.Queryable<SysMessage>().Where(u =>u.ToId == loginContext.User.Id && u.ToStatus != -1);
|
||||
|
||||
if (!string.IsNullOrEmpty(request.key))
|
||||
{
|
||||
@@ -54,7 +52,7 @@ namespace OpenAuth.App
|
||||
|
||||
public void Add(SysMessage obj)
|
||||
{
|
||||
Repository.Add(obj);
|
||||
Repository.Insert(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -75,14 +73,14 @@ namespace OpenAuth.App
|
||||
}
|
||||
else
|
||||
{
|
||||
sysUser = UnitWork.FirstOrDefault<SysUser>(u => u.Id == userId);
|
||||
sysUser = SugarClient.Queryable<SysUser>().First(u => u.Id == userId);
|
||||
}
|
||||
if (sysUser == null)
|
||||
{
|
||||
_logger.LogError($"未能找到用户{userId},不能给该用户发送消息");
|
||||
return;
|
||||
}
|
||||
Repository.Add(new SysMessage
|
||||
Repository.Insert(new SysMessage
|
||||
{
|
||||
ToId = sysUser.Id,
|
||||
ToName = sysUser.Name,
|
||||
@@ -101,10 +99,10 @@ namespace OpenAuth.App
|
||||
/// <param name="msgid"></param>
|
||||
public void Read(ReadMsgReq req)
|
||||
{
|
||||
UnitWork.Update<SysMessage>(u => u.Id == req.Id, u => new SysMessage
|
||||
Repository.Update(u => new SysMessage
|
||||
{
|
||||
ToStatus = 1
|
||||
});
|
||||
}, u => u.Id == req.Id);
|
||||
}
|
||||
/// <summary>
|
||||
/// 消息采用逻辑删除
|
||||
@@ -112,15 +110,15 @@ namespace OpenAuth.App
|
||||
/// <param name="ids"></param>
|
||||
public void Del(string[] ids)
|
||||
{
|
||||
UnitWork.Update<SysMessage>(u => ids.Contains(u.Id), u => new SysMessage
|
||||
Repository.Update(u => new SysMessage
|
||||
{
|
||||
ToStatus = -1 //逻辑删除
|
||||
});
|
||||
}, u => ids.Contains(u.Id));
|
||||
|
||||
}
|
||||
|
||||
public SysMessageApp(IUnitWork<OpenAuthDBContext> unitWork, IRepository<SysMessage,OpenAuthDBContext> repository,
|
||||
RevelanceManagerApp app,IAuth auth, ILogger<SysMessageApp> logger) : base(unitWork, repository, auth)
|
||||
public SysMessageApp(ISqlSugarClient client,
|
||||
RevelanceManagerApp app,IAuth auth, ILogger<SysMessageApp> logger) : base(client, auth)
|
||||
{
|
||||
_revelanceApp = app;
|
||||
_logger = logger;
|
||||
|
||||
@@ -11,8 +11,17 @@ using OpenAuth.App.SSO;
|
||||
|
||||
namespace OpenAuth.App.Test
|
||||
{
|
||||
class TestDynamicApiApp :TestBase
|
||||
/// <summary>
|
||||
/// DynamicApiApp 单元测试
|
||||
/// 测试表:noentity (id varchar(50), name varchar(255), age int)
|
||||
/// 支持 MySQL 和 SqlServer 数据库
|
||||
/// 测试大小写混合属性命名
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TestDynamicApiApp : TestBase
|
||||
{
|
||||
private const string TEST_TABLE = "noentity";
|
||||
|
||||
public override ServiceCollection GetService()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
@@ -28,55 +37,628 @@ namespace OpenAuth.App.Test
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region 基础 CRUD 测试
|
||||
|
||||
/// <summary>
|
||||
/// 测试添加数据 - 标准属性名(PascalCase)
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestAdd()
|
||||
public async Task TestAdd_PascalCase()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
var obj = await app.Add(new AddOrUpdateDynamicEntityReq { TableName = "noentity", Obj = "{\"P1\":\"测试\",\"Id\":\"12\"}" });
|
||||
Console.WriteLine(JsonHelper.Instance.Serialize(obj));
|
||||
var id = Guid.NewGuid().ToString();
|
||||
|
||||
var result = await app.Add(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"测试PascalCase\",\"Age\":25}}"
|
||||
});
|
||||
|
||||
Console.WriteLine($"添加结果(PascalCase): {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(200), $"添加失败: {result.Message}");
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试添加数据 - 小写属性名(camelCase)
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestAdd_CamelCase()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
var id = Guid.NewGuid().ToString();
|
||||
|
||||
var result = await app.Add(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"id\":\"{id}\",\"name\":\"测试camelCase\",\"age\":30}}"
|
||||
});
|
||||
|
||||
Console.WriteLine($"添加结果(camelCase): {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(200), $"添加失败: {result.Message}");
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试添加数据 - 大写属性名(UPPERCASE)
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestAdd_UpperCase()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
var id = Guid.NewGuid().ToString();
|
||||
|
||||
var result = await app.Add(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"ID\":\"{id}\",\"NAME\":\"测试UPPERCASE\",\"AGE\":35}}"
|
||||
});
|
||||
|
||||
Console.WriteLine($"添加结果(UPPERCASE): {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(200), $"添加失败: {result.Message}");
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试添加数据 - 混合大小写属性名(MixedCase)
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestAdd_MixedCase()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
var id = Guid.NewGuid().ToString();
|
||||
|
||||
// 混合使用不同大小写:Id(PascalCase), name(camelCase), AGE(UPPERCASE)
|
||||
var result = await app.Add(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"Id\":\"{id}\",\"name\":\"测试MixedCase\",\"AGE\":40}}"
|
||||
});
|
||||
|
||||
Console.WriteLine($"添加结果(MixedCase): {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(200), $"添加失败: {result.Message}");
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试获取单条数据
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestGet()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
var id = Guid.NewGuid().ToString();
|
||||
|
||||
// 先添加数据
|
||||
await app.Add(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"测试获取\",\"Age\":28}}"
|
||||
});
|
||||
|
||||
// 获取数据
|
||||
var result = await app.Get(new QueryDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Id = id
|
||||
});
|
||||
|
||||
Console.WriteLine($"获取结果: {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(200), $"获取失败: {result.Message}");
|
||||
Assert.That(result.Data, Is.Not.Null, "未找到数据");
|
||||
|
||||
|
||||
var obj = await app.Get(new QueryDynamicEntityReq { TableName = "noentity", Id = "1" });
|
||||
Console.WriteLine(JsonHelper.Instance.Serialize(obj));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试获取列表
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestGetList()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
|
||||
var obj = await app.GetList(new QueryDynamicListReq { TableName = "noentity", page = 1, limit = 10, key = "" });
|
||||
Console.WriteLine(JsonHelper.Instance.Serialize(obj));
|
||||
var result = await app.GetList(new QueryDynamicListReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
page = 1,
|
||||
limit = 10,
|
||||
key = ""
|
||||
});
|
||||
|
||||
Console.WriteLine($"列表查询结果: 总数={result.Count}, 数据条数={result.Data?.Count ?? 0}");
|
||||
Console.WriteLine($"详细结果: {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(200), $"查询失败: {result.Message}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试带关键字搜索的列表查询
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestInvoke()
|
||||
public async Task TestGetList_WithKey()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
var id = Guid.NewGuid().ToString();
|
||||
var searchKey = "搜索测试_" + DateTime.Now.Ticks;
|
||||
|
||||
// 先添加测试数据
|
||||
await app.Add(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"{searchKey}\",\"Age\":22}}"
|
||||
});
|
||||
|
||||
// 查询
|
||||
var result = await app.GetList(new QueryDynamicListReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
page = 1,
|
||||
limit = 10,
|
||||
key = searchKey
|
||||
});
|
||||
|
||||
Console.WriteLine($"带关键字搜索结果: {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(200), $"查询失败: {result.Message}");
|
||||
Assert.That(result.Count, Is.GreaterThanOrEqualTo(1), "应该至少找到一条数据");
|
||||
|
||||
// 清理测试数据
|
||||
await CleanupTestData(app, id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试更新数据 - 标准属性名(PascalCase)
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestUpdate_PascalCase()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
var id = Guid.NewGuid().ToString();
|
||||
|
||||
// 先添加数据
|
||||
await app.Add(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"原始名称\",\"Age\":20}}"
|
||||
});
|
||||
|
||||
// 更新数据
|
||||
var result = await app.Update(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"更新后PascalCase\",\"Age\":21}}"
|
||||
});
|
||||
|
||||
Console.WriteLine($"更新结果(PascalCase): {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(200), $"更新失败: {result.Message}");
|
||||
|
||||
// 验证更新结果
|
||||
var getResult = await app.Get(new QueryDynamicEntityReq { TableName = TEST_TABLE, Id = id });
|
||||
Console.WriteLine($"更新后数据: {JsonHelper.Instance.Serialize(getResult)}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试更新数据 - 小写属性名(camelCase)
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestUpdate_CamelCase()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
var id = Guid.NewGuid().ToString();
|
||||
|
||||
// 先添加数据
|
||||
await app.Add(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"id\":\"{id}\",\"name\":\"原始名称\",\"age\":20}}"
|
||||
});
|
||||
|
||||
// 更新数据
|
||||
var result = await app.Update(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"id\":\"{id}\",\"name\":\"更新后camelCase\",\"age\":22}}"
|
||||
});
|
||||
|
||||
Console.WriteLine($"更新结果(camelCase): {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(200), $"更新失败: {result.Message}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试更新数据 - 混合大小写属性名
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestUpdate_MixedCase()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
var id = Guid.NewGuid().ToString();
|
||||
|
||||
// 先添加数据(使用PascalCase)
|
||||
await app.Add(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"原始名称\",\"Age\":20}}"
|
||||
});
|
||||
|
||||
// 更新数据(使用混合大小写)
|
||||
var result = await app.Update(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"Id\":\"{id}\",\"name\":\"更新后MixedCase\",\"AGE\":23}}"
|
||||
});
|
||||
|
||||
Console.WriteLine($"更新结果(MixedCase): {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(200), $"更新失败: {result.Message}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试删除单条数据
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestDelete_Single()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
var id = Guid.NewGuid().ToString();
|
||||
|
||||
// 先添加数据
|
||||
await app.Add(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"待删除\",\"Age\":99}}"
|
||||
});
|
||||
|
||||
// 删除数据
|
||||
var result = await app.Delete(new DelDynamicReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Ids = new[] { id }
|
||||
});
|
||||
|
||||
Console.WriteLine($"删除结果: {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(200), $"删除失败: {result.Message}");
|
||||
|
||||
// 验证删除结果
|
||||
var getResult = await app.Get(new QueryDynamicEntityReq { TableName = TEST_TABLE, Id = id });
|
||||
Assert.That(getResult.Data, Is.Null, "数据应该已被删除");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试批量删除
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestDelete_Batch()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
var ids = new[] { Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString() };
|
||||
|
||||
// 添加多条测试数据
|
||||
foreach (var id in ids)
|
||||
{
|
||||
await app.Add(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"批量删除测试_{id.Substring(0, 8)}\",\"Age\":50}}"
|
||||
});
|
||||
}
|
||||
|
||||
// 批量删除
|
||||
var result = await app.Delete(new DelDynamicReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Ids = ids
|
||||
});
|
||||
|
||||
Console.WriteLine($"批量删除结果: {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(200), $"批量删除失败: {result.Message}");
|
||||
|
||||
// 验证删除结果
|
||||
foreach (var id in ids)
|
||||
{
|
||||
var getResult = await app.Get(new QueryDynamicEntityReq { TableName = TEST_TABLE, Id = id });
|
||||
Assert.That(getResult.Data, Is.Null, $"数据 {id} 应该已被删除");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 完整 CRUD 流程测试
|
||||
|
||||
/// <summary>
|
||||
/// 测试完整的 CRUD 流程
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestCRUD_FullFlow()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
var id = Guid.NewGuid().ToString();
|
||||
|
||||
Console.WriteLine("=== 开始完整 CRUD 流程测试 ===");
|
||||
|
||||
// 1. Create - 创建数据
|
||||
Console.WriteLine("\n1. 创建数据...");
|
||||
var addResult = await app.Add(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"CRUD测试\",\"Age\":18}}"
|
||||
});
|
||||
Console.WriteLine($"创建结果: {JsonHelper.Instance.Serialize(addResult)}");
|
||||
Assert.That(addResult.Code, Is.EqualTo(200), $"创建失败: {addResult.Message}");
|
||||
|
||||
// 2. Read - 读取数据
|
||||
Console.WriteLine("\n2. 读取数据...");
|
||||
var getResult = await app.Get(new QueryDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Id = id
|
||||
});
|
||||
Console.WriteLine($"读取结果: {JsonHelper.Instance.Serialize(getResult)}");
|
||||
Assert.That(getResult.Code, Is.EqualTo(200), $"读取失败: {getResult.Message}");
|
||||
Assert.That(getResult.Data, Is.Not.Null, "数据不应为空");
|
||||
|
||||
// 3. Update - 更新数据
|
||||
Console.WriteLine("\n3. 更新数据...");
|
||||
var updateResult = await app.Update(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"CRUD测试_已更新\",\"Age\":19}}"
|
||||
});
|
||||
Console.WriteLine($"更新结果: {JsonHelper.Instance.Serialize(updateResult)}");
|
||||
Assert.That(updateResult.Code, Is.EqualTo(200), $"更新失败: {updateResult.Message}");
|
||||
|
||||
// 验证更新
|
||||
var getResult2 = await app.Get(new QueryDynamicEntityReq { TableName = TEST_TABLE, Id = id });
|
||||
Console.WriteLine($"更新后数据: {JsonHelper.Instance.Serialize(getResult2)}");
|
||||
|
||||
// 4. Delete - 删除数据
|
||||
Console.WriteLine("\n4. 删除数据...");
|
||||
var deleteResult = await app.Delete(new DelDynamicReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Ids = new[] { id }
|
||||
});
|
||||
Console.WriteLine($"删除结果: {JsonHelper.Instance.Serialize(deleteResult)}");
|
||||
Assert.That(deleteResult.Code, Is.EqualTo(200), $"删除失败: {deleteResult.Message}");
|
||||
|
||||
// 验证删除
|
||||
var getResult3 = await app.Get(new QueryDynamicEntityReq { TableName = TEST_TABLE, Id = id });
|
||||
Assert.That(getResult3.Data, Is.Null, "数据应该已被删除");
|
||||
|
||||
Console.WriteLine("\n=== 完整 CRUD 流程测试完成 ===");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Invoke 方法测试
|
||||
|
||||
/// <summary>
|
||||
/// 测试 Invoke 调用 - 获取父级用户
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestInvoke_GetParent()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
|
||||
var obj = await app.Invoke(new InvokeDynamicReq { ServiceName = "UserManagerApp", MethodName = "GetParent",
|
||||
Parameters = "{\"userid\":\"0ceff0f8-f848-440c-bc26-d8605ac858cd\"}" });
|
||||
Console.WriteLine(JsonHelper.Instance.Serialize(obj));
|
||||
var result = await app.Invoke(new InvokeDynamicReq
|
||||
{
|
||||
ServiceName = "UserManagerApp",
|
||||
MethodName = "GetParent",
|
||||
Parameters = "{\"userid\":\"0ceff0f8-f848-440c-bc26-d8605ac858cd\"}"
|
||||
});
|
||||
|
||||
Console.WriteLine($"Invoke GetParent 结果: {JsonHelper.Instance.Serialize(result)}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试 Invoke 调用 - 加载用户列表
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestInvoke2()
|
||||
public async Task TestInvoke_Load()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
|
||||
var obj = await app.Invoke(new InvokeDynamicReq {
|
||||
ServiceName = "UserManagerApp",
|
||||
MethodName = "Load",
|
||||
Parameters = "{\"request\":{\"page\":1,\"limit\":10,\"key\":\"dddd\"}}"
|
||||
});
|
||||
Console.WriteLine(JsonHelper.Instance.Serialize(obj));
|
||||
|
||||
}
|
||||
|
||||
var result = await app.Invoke(new InvokeDynamicReq
|
||||
{
|
||||
ServiceName = "UserManagerApp",
|
||||
MethodName = "Load",
|
||||
Parameters = "{\"request\":{\"page\":1,\"limit\":10,\"key\":\"\"}}"
|
||||
});
|
||||
|
||||
Console.WriteLine($"Invoke Load 结果: {JsonHelper.Instance.Serialize(result)}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试 Invoke 调用 - 参数大小写混合
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestInvoke_MixedCaseParameters()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
|
||||
// 使用混合大小写的参数
|
||||
var result = await app.Invoke(new InvokeDynamicReq
|
||||
{
|
||||
ServiceName = "UserManagerApp",
|
||||
MethodName = "Load",
|
||||
Parameters = "{\"Request\":{\"Page\":1,\"Limit\":10,\"Key\":\"\"}}"
|
||||
});
|
||||
|
||||
Console.WriteLine($"Invoke MixedCase 结果: {JsonHelper.Instance.Serialize(result)}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 异常场景测试
|
||||
|
||||
/// <summary>
|
||||
/// 测试不存在的表
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestNonExistentTable()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
|
||||
var result = await app.GetList(new QueryDynamicListReq
|
||||
{
|
||||
TableName = "non_existent_table_12345",
|
||||
page = 1,
|
||||
limit = 10
|
||||
});
|
||||
|
||||
Console.WriteLine($"查询不存在的表结果: {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(500), "应该返回错误");
|
||||
Assert.That(result.Message, Does.Contain("表不存在"), "错误信息应包含'表不存在'");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试更新不包含Id的数据
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestUpdate_WithoutId()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
|
||||
var result = await app.Update(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = "{\"Name\":\"没有Id的更新\",\"Age\":99}"
|
||||
});
|
||||
|
||||
Console.WriteLine($"无Id更新结果: {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(500), "应该返回错误");
|
||||
Assert.That(result.Message, Does.Contain("Id"), "错误信息应包含'Id'");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试添加重复Id的数据
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestAdd_DuplicateId()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
var id = Guid.NewGuid().ToString();
|
||||
|
||||
// 第一次添加
|
||||
await app.Add(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"第一次添加\",\"Age\":1}}"
|
||||
});
|
||||
|
||||
// 第二次添加相同Id
|
||||
var result = await app.Add(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"第二次添加\",\"Age\":2}}"
|
||||
});
|
||||
|
||||
Console.WriteLine($"重复Id添加结果: {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(500), "应该返回错误");
|
||||
Assert.That(result.Message, Does.Contain("Id已存在"), "错误信息应包含'Id已存在'");
|
||||
|
||||
// 清理测试数据
|
||||
await CleanupTestData(app, id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试获取不存在的记录
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestGet_NonExistent()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
|
||||
var result = await app.Get(new QueryDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Id = "non_existent_id_12345"
|
||||
});
|
||||
|
||||
Console.WriteLine($"获取不存在记录结果: {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(500), "应该返回错误");
|
||||
Assert.That(result.Message, Does.Contain("未找到"), "错误信息应包含'未找到'");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 自动生成ID测试
|
||||
|
||||
/// <summary>
|
||||
/// 测试添加数据时自动生成Id
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestAdd_AutoGenerateId()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
|
||||
// 不传Id
|
||||
var result = await app.Add(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = "{\"Name\":\"自动生成Id测试\",\"Age\":33}"
|
||||
});
|
||||
|
||||
Console.WriteLine($"自动生成Id结果: {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(200), $"添加失败: {result.Message}");
|
||||
|
||||
// 查询并验证确实有数据被添加
|
||||
var listResult = await app.GetList(new QueryDynamicListReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
page = 1,
|
||||
limit = 100,
|
||||
key = "自动生成Id测试"
|
||||
});
|
||||
|
||||
Console.WriteLine($"查询结果: {JsonHelper.Instance.Serialize(listResult)}");
|
||||
Assert.That(listResult.Count, Is.GreaterThan(0), "应该能查到数据");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试添加数据时Id为空字符串,应自动生成
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestAdd_EmptyId()
|
||||
{
|
||||
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
|
||||
|
||||
// 传空Id
|
||||
var result = await app.Add(new AddOrUpdateDynamicEntityReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Obj = "{\"Id\":\"\",\"Name\":\"空Id测试\",\"Age\":34}"
|
||||
});
|
||||
|
||||
Console.WriteLine($"空Id测试结果: {JsonHelper.Instance.Serialize(result)}");
|
||||
Assert.That(result.Code, Is.EqualTo(200), $"添加失败: {result.Message}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 辅助方法
|
||||
|
||||
/// <summary>
|
||||
/// 清理测试数据
|
||||
/// </summary>
|
||||
private async Task CleanupTestData(DynamicApiApp app, string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
await app.Delete(new DelDynamicReq
|
||||
{
|
||||
TableName = TEST_TABLE,
|
||||
Ids = new[] { id }
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"清理测试数据失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,8 +189,8 @@ namespace OpenAuth.WebApi.Controllers
|
||||
{
|
||||
return new PagedDynamicDataResp
|
||||
{
|
||||
Message = "未找到指定的节点",
|
||||
Code = 500,
|
||||
Data = new List<OrgView>(),
|
||||
Count = 0
|
||||
};
|
||||
}
|
||||
cascadeId = org.CascadeId;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!--
|
||||
* @Author: yubaolee <yubaolee@163.com> | ahfu~ <954478625@qq.com>
|
||||
* @Date: 2021-06-01 14:10:29
|
||||
* @LastEditTime: 2024-02-23 11:36:24
|
||||
* @LastEditTime: 2025-12-21 17:39:13
|
||||
* @Description: 处于草稿和驳回状态的流程,可以进行编辑
|
||||
* 可以编辑流程的基本信息和提交的表单内容
|
||||
* @
|
||||
@@ -171,7 +171,7 @@ export default {
|
||||
.then((response) => {
|
||||
this.postObj = response.data
|
||||
this.formData = JSON.parse(response.data.frmData)
|
||||
this.formJson = JSON.parse(response.data.frmContentData)
|
||||
|
||||
|
||||
if (this.postObj.frmType === 1) {
|
||||
// 用户自定义的页面,即Vue组件
|
||||
@@ -179,6 +179,8 @@ export default {
|
||||
loadComp().then(res => {
|
||||
this.userDefineComp = res.default
|
||||
})
|
||||
}else{
|
||||
this.formJson = JSON.parse(response.data.frmContentData)
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
|
||||
@@ -122,9 +122,13 @@ OpenAuth.Net工作流分为两个大类:
|
||||
|
||||
* 同意:流程审批通过,流程结束;
|
||||
|
||||
* 不同意:流程审批不通过,流程结束;
|
||||
* **不同意(拒绝 / 反对)**:审批人明确不批准本次申请,属于终结性意见。
|
||||
|
||||
* 驳回:可以驳回到指定的步骤,该步骤的人可以重新审批提交;
|
||||
* 结果:本次申请失败,流程结束,如果重新发起新流程。
|
||||
|
||||
* **驳回(退回 / 打回)**:审批人认为资料不全 / 有误,需要修改后重提,属于回退 + 重走动作。
|
||||
|
||||
* 结果:流程未终结,可修复后继续。
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,25 +4,29 @@ createTime: 2025/04/23 23:43:26
|
||||
permalink: /pro/dragformdetail/
|
||||
---
|
||||
|
||||
企业版可拖拽表单使用的是VForm Pro版本,详细的配置可参考:[https://www.vform666.com/](https://www.vform666.com/) 本节只做常用的配置说明。
|
||||
企业版可拖拽表单使用的是 VForm Pro 版本,详细的配置可参考:[https://www.vform666.com/](https://www.vform666.com/) 本节只做常用的配置说明。
|
||||
|
||||
## 后端加载下拉列表值
|
||||
|
||||
官网推荐通过数据源的方式给下拉列表赋值,简单点的方式是使用组件的`onCreated`事件。新建一个下拉先选框,唯一名称改为:`SelectVals`,在组件的`onCreated`事件中添加以下代码:
|
||||
|
||||
```javascript
|
||||
var selectVals = this.getWidgetRef('SelectVals');
|
||||
var addressAPI= 'http://localhost:52789/api/SelectVals/'
|
||||
axios.get(addressAPI).then(function(res) {
|
||||
if (res.data.code==200) {
|
||||
selectVals.loadOptions(res.data.result);
|
||||
}
|
||||
}).catch(function(error) {
|
||||
console.error(error)
|
||||
})
|
||||
var selectVals = this.getWidgetRef("SelectVals");
|
||||
var addressAPI = "http://localhost:52789/api/SelectVals/";
|
||||
axios
|
||||
.get(addressAPI)
|
||||
.then(function (res) {
|
||||
if (res.data.code == 200) {
|
||||
selectVals.loadOptions(res.data.result);
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.error(error);
|
||||
});
|
||||
```
|
||||
|
||||
基于OpenAuth.WebApi返回的数据格式:
|
||||
基于 OpenAuth.WebApi 返回的数据格式:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"result": [{
|
||||
@@ -35,4 +39,19 @@ axios.get(addressAPI).then(function(res) {
|
||||
"message": "操作成功",
|
||||
"code": 200
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
## 多字段校验
|
||||
|
||||
使用场景:拖动表单中有多个表单组件需要联动校验,比如两个日期组件校验开始日期小于等于结束日期。
|
||||
具体做法:在表单设计的【全局设置】里面配置`onFormValidate`事件:
|
||||
|
||||
```javascript
|
||||
if (formModel.startDate > formModel.endDate) {
|
||||
this.$message.error("开始日期必须小于结束日期");
|
||||
return false;
|
||||
}
|
||||
```
|
||||
|
||||
如下图:
|
||||

|
||||
|
||||
@@ -30,6 +30,7 @@ SelectUsersCom是一个用于选择用户或角色的组件,提供了两种使
|
||||
| users | Object | - | 初始选中项ID列表或对象列表 |
|
||||
| inType | String | 'id' | 父级传入的是id列表还是对象列表,取值为'id'或'obj' |
|
||||
| modelValue | Boolean | false | 控制对话框显示 |
|
||||
| single | Boolean | false | 是否单选,true时只能选择一个用户/角色 |
|
||||
|
||||
### 事件说明
|
||||
|
||||
@@ -87,6 +88,7 @@ const handleSave = () => {
|
||||
| userNames | String | '' | 用户名称(逗号分隔) |
|
||||
| placeholder | String | '' | 输入框占位符 |
|
||||
| ignoreAuth | Boolean | false | 是否忽略权限限制 |
|
||||
| single | Boolean | false | 是否单选,true时只能选择一个用户/角色 |
|
||||
|
||||
### 事件说明
|
||||
|
||||
|
||||
@@ -4,27 +4,47 @@ createTime: 2025/04/23 23:43:26
|
||||
permalink: /pro/start/
|
||||
---
|
||||
## 工具准备
|
||||
|
||||
#### NodeJs
|
||||
|
||||
前端环境为NodeJs,下载地址:[http://nodejs.cn/download/current/](http://nodejs.cn/download/current/)
|
||||
|
||||
#### visual studio code
|
||||
|
||||
下载最新版的vs code,或Cursor、Windsurf、Trae等工具用来作为OpenAuth.Net Vue3版的开发工具。
|
||||
|
||||
## 源码下载
|
||||
|
||||
根据授权文件的下载指示,下载Vue3源码。注意:一定要使用下图中的数据库脚本:
|
||||

|
||||
|
||||
## 创建数据库
|
||||
* 新建一个空数据库:OpenAuthPro。使用上一步下载的【sql脚本】文件夹,根据你的数据库类型,选择运行你需要的脚本:`Sql Server脚本.sql`或`mysql脚本.sql`
|
||||
|
||||
* 新建一个空数据库:OpenAuthPro。使用上一步下载的【sql脚本】文件夹,根据你的数据库类型,选择运行你需要的脚本:`Sql Server脚本.sql`或 `mysql脚本.sql`
|
||||
|
||||
## 启动后端
|
||||
|
||||
启动后端请参考:[快速开始](/core/start/)
|
||||
|
||||
## 启动前端
|
||||
使用Vs Code(或个人喜欢的工具)打开openauthvue3文件夹,修改配置文件`.env.dev`对应的后端接口地址,调整为自己的接口地址:
|
||||
|
||||
使用Vs Code(或个人喜欢的工具)打开openauthvue3文件夹,修改配置文件 `.env.dev`对应的后端接口地址,调整为自己的接口地址:
|
||||
|
||||
```javascript
|
||||
VITE_BASE_API = http://localhost:52789/api
|
||||
VITE_BASE_IMG_URL = http://localhost:52789
|
||||
```
|
||||
|
||||
::: warning 注意
|
||||
如果是发布打包,调整的文件为`.env.production`
|
||||
如果是发布打包,调整的文件为 `.env.production`
|
||||
:::
|
||||
使用`npm install`命令安装程序运行所需的第三方包。再用`npm run dev`命令运行。如下图:
|
||||

|
||||
启动成功后,使用浏览器访问[http://localhost:1803/](http://localhost:1803/) 即可打开vue3版界面:
|
||||
使用 `npm install`命令安装程序运行所需的第三方包。在安装的过程中如果遇到卡住的情况,可能是ssl证书问题,可以使用以下命令进行配置:
|
||||
|
||||
```
|
||||
npm config set strict-ssl false; npm config set registry https://registry.npmmirror.com
|
||||
```
|
||||
|
||||
再用 `npm run dev`命令运行。如下图:
|
||||
启动成功后,使用浏览器访问[http://localhost:1803/](http://localhost:1803/) 即可打开vue3版界面:
|
||||
|
||||

|
||||
|
||||
@@ -145,9 +145,13 @@ OpenAuth.Net工作流分为两个大类:
|
||||
|
||||
* 同意:流程审批通过,流程结束;
|
||||
|
||||
* 不同意:流程审批不通过,流程结束;
|
||||
* **不同意(拒绝 / 反对)**:审批人明确不批准本次申请,属于终结性意见。
|
||||
|
||||
* 驳回:可以驳回到指定的步骤,该步骤的人可以重新审批提交;
|
||||
* 结果:本次申请失败,流程结束,如果重新发起新流程。
|
||||
|
||||
* **驳回(退回 / 打回)**:审批人认为资料不全 / 有误,需要修改后重提,属于回退 + 重走动作。
|
||||
|
||||
* 结果:流程未终结,可修复后继续。
|
||||
|
||||
* 加签:在已有审批流程上临时添加审批人,协助自己审批;
|
||||
|
||||
|
||||
@@ -1273,7 +1273,7 @@ INSERT INTO "MODULEELEMENT" VALUES ('4fba8ea0-6b0d-426f-8687-b654575ca780', 'btn
|
||||
INSERT INTO "MODULEELEMENT" VALUES ('4fba8ea0-7c5c-426f-8687-b654575ca780', 'btnExport', '导出', NULL, 'export()', 'bianji-copy', 'info', '导出订单', '10', '98a949e8-8704-40a7-b9a1-c0e8801e4057', NULL, NULL);
|
||||
INSERT INTO "MODULEELEMENT" VALUES ('4fe5d402-4314-4673-8723-eeed4bfaa2e1', 'btnEdit', '编辑', NULL, NULL, 'xiugai', 'primary', '编辑流程', '1', '9486ff22-b696-4d7f-8093-8a3e53c45453', NULL, NULL);
|
||||
INSERT INTO "MODULEELEMENT" VALUES ('50c9df24-b233-42cb-9a0d-4ce158c75f86', 'btnAdd', '添加', NULL, 'add()', 'xinzeng', 'success', '添加用戶', '0', 'ef386d5d-cd58-43c0-a4ab-80afd0dbcd6c', NULL, NULL);
|
||||
INSERT INTO "MODULEELEMENT" VALUES ('52be6f7a-0b32-481e-b8a2-929437eafb2a', 'btnRecall', '撤销', NULL, NULL, 'chexiao_', 'danger', NULL, '5', '9486ff22-b696-4d7f-8093-8a3e53c45453', NULL, NULL);
|
||||
INSERT INTO "MODULEELEMENT" VALUES ('52be6f7a-0b32-481e-b8a2-929437eafb2a', 'btnRecall', '召回', NULL, NULL, 'chexiao_', 'danger', NULL, '5', '9486ff22-b696-4d7f-8093-8a3e53c45453', NULL, NULL);
|
||||
INSERT INTO "MODULEELEMENT" VALUES ('57dfb830-6b65-41e0-848e-88aa604f9ad8', 'btnEdit', '编辑', NULL, 'edit()', 'bianji-copy', 'primary', '修改外部数据源管理', '2', 'e11b4ece-b4c6-44f5-b1c1-8f1dadbf037c', NULL, NULL);
|
||||
INSERT INTO "MODULEELEMENT" VALUES ('584c7a3b-d28a-47b4-8648-7797d05d83d1', 'btnDel', '删除', NULL, 'del()', 'shanchu', 'danger', NULL, '3', '9486ff22-b696-4d7f-8093-8a3e53c45453', NULL, NULL);
|
||||
INSERT INTO "MODULEELEMENT" VALUES ('44075557-496e-4dde-bb75-7b69f51ab4fe', 'btnEdit', '编辑', NULL, 'edit()', 'bianji-copy', 'primary', '编辑模块', '2', 'bc80478d-0547-4437-9cff-be4b40144bdf', NULL, NULL);
|
||||
|
||||
@@ -1055,7 +1055,7 @@ INSERT INTO "public"."moduleelement" VALUES ('4fba8ea0-6b0d-426f-8687-b654575ca7
|
||||
INSERT INTO "public"."moduleelement" VALUES ('4fba8ea0-7c5c-426f-8687-b654575ca780', 'btnExport', '导出', '', 'export()', 'bianji-copy', 'info', '导出订单', 10, '98a949e8-8704-40a7-b9a1-c0e8801e4057', NULL, NULL);
|
||||
INSERT INTO "public"."moduleelement" VALUES ('4fe5d402-4314-4673-8723-eeed4bfaa2e1', 'btnEdit', '编辑', '', '', 'xiugai', 'primary', '编辑流程', 1, '9486ff22-b696-4d7f-8093-8a3e53c45453', '', '');
|
||||
INSERT INTO "public"."moduleelement" VALUES ('50c9df24-b233-42cb-9a0d-4ce158c75f86', 'btnAdd', '添加', '', 'add()', 'xinzeng', 'success', '添加用戶', 0, 'ef386d5d-cd58-43c0-a4ab-80afd0dbcd6c', NULL, NULL);
|
||||
INSERT INTO "public"."moduleelement" VALUES ('52be6f7a-0b32-481e-b8a2-929437eafb2a', 'btnRecall', '撤销', '', '', 'chexiao_', 'danger', '', 5, '9486ff22-b696-4d7f-8093-8a3e53c45453', '', '');
|
||||
INSERT INTO "public"."moduleelement" VALUES ('52be6f7a-0b32-481e-b8a2-929437eafb2a', 'btnRecall', '召回', '', '', 'chexiao_', 'danger', '', 5, '9486ff22-b696-4d7f-8093-8a3e53c45453', '', '');
|
||||
INSERT INTO "public"."moduleelement" VALUES ('57dfb830-6b65-41e0-848e-88aa604f9ad8', 'btnEdit', '编辑', '', 'edit()', 'bianji-copy', 'primary', '修改外部数据源管理', 2, 'e11b4ece-b4c6-44f5-b1c1-8f1dadbf037c', '', '');
|
||||
INSERT INTO "public"."moduleelement" VALUES ('584c7a3b-d28a-47b4-8648-7797d05d83d1', 'btnDel', '删除', '', 'del()', 'shanchu', 'danger', '', 3, '9486ff22-b696-4d7f-8093-8a3e53c45453', NULL, NULL);
|
||||
INSERT INTO "public"."moduleelement" VALUES ('5ed1681c-13d2-4c87-8675-a8d95c0b40ae', 'btnAddMenu', '添加菜单', '', 'assignButton()', 'xinzeng', 'success', '为模块分配按钮', 4, 'bc80478d-0547-4437-9cff-be4b40144bdf', NULL, NULL);
|
||||
|
||||
@@ -3413,7 +3413,7 @@ GO
|
||||
INSERT INTO [dbo].[ModuleElement] ([Id], [DomId], [Name], [Attr], [Script], [Icon], [Class], [Remark], [Sort], [ModuleId], [TypeName], [TypeId]) VALUES (N'50c9df24-b233-42cb-9a0d-4ce158c75f86', N'btnAdd', N'添加', N'', N'add()', N'xinzeng', N'success', N'添加用戶', N'0', N'ef386d5d-cd58-43c0-a4ab-80afd0dbcd6c', NULL, NULL)
|
||||
GO
|
||||
|
||||
INSERT INTO [dbo].[ModuleElement] ([Id], [DomId], [Name], [Attr], [Script], [Icon], [Class], [Remark], [Sort], [ModuleId], [TypeName], [TypeId]) VALUES (N'52be6f7a-0b32-481e-b8a2-929437eafb2a', N'btnRecall', N'撤销', N'', N'', N'chexiao_', N'danger', N'', N'5', N'9486ff22-b696-4d7f-8093-8a3e53c45453', N'', N'')
|
||||
INSERT INTO [dbo].[ModuleElement] ([Id], [DomId], [Name], [Attr], [Script], [Icon], [Class], [Remark], [Sort], [ModuleId], [TypeName], [TypeId]) VALUES (N'52be6f7a-0b32-481e-b8a2-929437eafb2a', N'btnRecall', N'召回', N'', N'', N'chexiao_', N'danger', N'', N'5', N'9486ff22-b696-4d7f-8093-8a3e53c45453', N'', N'')
|
||||
GO
|
||||
|
||||
INSERT INTO [dbo].[ModuleElement] ([Id], [DomId], [Name], [Attr], [Script], [Icon], [Class], [Remark], [Sort], [ModuleId], [TypeName], [TypeId]) VALUES (N'57dfb830-6b65-41e0-848e-88aa604f9ad8', N'btnEdit', N'编辑', N'', N'edit()', N'bianji-copy', N'primary', N'修改外部数据源管理', N'2', N'e11b4ece-b4c6-44f5-b1c1-8f1dadbf037c', N'', N'')
|
||||
|
||||
@@ -792,7 +792,7 @@ INSERT INTO `moduleelement` VALUES ('4fba8ea0-6b0d-426f-8687-b654575ca780', 'btn
|
||||
INSERT INTO `moduleelement` VALUES ('4fba8ea0-7c5c-426f-8687-b654575ca780', 'btnExport', '导出', '', 'export()', 'bianji-copy', 'info', '导出订单', 10, '98a949e8-8704-40a7-b9a1-c0e8801e4057', NULL, NULL);
|
||||
INSERT INTO `moduleelement` VALUES ('4fe5d402-4314-4673-8723-eeed4bfaa2e1', 'btnEdit', '编辑', '', '', 'xiugai', 'primary', '编辑流程', 1, '9486ff22-b696-4d7f-8093-8a3e53c45453', '', '');
|
||||
INSERT INTO `moduleelement` VALUES ('50c9df24-b233-42cb-9a0d-4ce158c75f86', 'btnAdd', '添加', '', 'add()', 'xinzeng', 'success', '添加用戶', 0, 'ef386d5d-cd58-43c0-a4ab-80afd0dbcd6c', NULL, NULL);
|
||||
INSERT INTO `moduleelement` VALUES ('52be6f7a-0b32-481e-b8a2-929437eafb2a', 'btnRecall', '撤销', '', '', 'chexiao_', 'danger', '', 5, '9486ff22-b696-4d7f-8093-8a3e53c45453', '', '');
|
||||
INSERT INTO `moduleelement` VALUES ('52be6f7a-0b32-481e-b8a2-929437eafb2a', 'btnRecall', '召回', '', '', 'chexiao_', 'danger', '', 5, '9486ff22-b696-4d7f-8093-8a3e53c45453', '', '');
|
||||
INSERT INTO `moduleelement` VALUES ('57dfb830-6b65-41e0-848e-88aa604f9ad8', 'btnEdit', '编辑', '', 'edit()', 'bianji-copy', 'primary', '修改外部数据源管理', 2, 'e11b4ece-b4c6-44f5-b1c1-8f1dadbf037c', '', '');
|
||||
INSERT INTO `moduleelement` VALUES ('584c7a3b-d28a-47b4-8648-7797d05d83d1', 'btnDel', '删除', '', 'del()', 'shanchu', 'danger', '', 3, '9486ff22-b696-4d7f-8093-8a3e53c45453', NULL, NULL);
|
||||
INSERT INTO `moduleelement` VALUES ('5ed1681c-13d2-4c87-8675-a8d95c0b40ae', 'btnAddMenu', '添加菜单', '', 'assignButton()', 'xinzeng', 'success', '为模块分配按钮', 4, 'bc80478d-0547-4437-9cff-be4b40144bdf', NULL, NULL);
|
||||
|
||||
Reference in New Issue
Block a user