mirror of
https://gitee.com/dotnetchina/OpenAuth.Net.git
synced 2026-07-28 06:07:59 +08:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6410c9da6 | ||
|
|
4730ac7a36 | ||
|
|
33cc0b1e3b | ||
|
|
87866d08fb | ||
|
|
6b2c50252b | ||
|
|
c85793bb55 | ||
|
|
f980fc5afc | ||
|
|
d83a40e07e | ||
|
|
695f5af89f | ||
|
|
82bb5b8f3e | ||
|
|
1c6ab0348f |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -268,3 +268,4 @@ __pycache__/
|
||||
/OpenAuth.Mvc/Properties/PublishProfiles
|
||||
*.pubxml
|
||||
/OpenAuth.WebApi/temp-keys
|
||||
/newdocs/docs/.vuepress/.cache
|
||||
|
||||
@@ -28,7 +28,13 @@ namespace Infrastructure
|
||||
{
|
||||
if (obj == null) return default(T);
|
||||
|
||||
var config = new MapperConfiguration(cfg=>cfg.CreateMap(obj.GetType(),typeof(T)));
|
||||
// 当Id为空时,不进行映射
|
||||
var config = new MapperConfiguration(cfg => {
|
||||
cfg.CreateMap(obj.GetType(), typeof(T))
|
||||
.ForMember("Id", opt => opt.Condition((src, dest, srcValue) =>
|
||||
srcValue != null && !string.IsNullOrEmpty(srcValue.ToString())
|
||||
));
|
||||
});
|
||||
var mapper = config.CreateMapper();
|
||||
return mapper.Map<T>(obj);
|
||||
}
|
||||
|
||||
@@ -337,6 +337,7 @@ namespace OpenAuth.App
|
||||
.Replace("{ModuleCode}", sysTableInfo.ModuleCode)
|
||||
.Replace("{ModuleName}", sysTableInfo.ModuleName)
|
||||
.Replace("{ClassName}", sysTableInfo.ClassName)
|
||||
.Replace("{Namespace}", sysTableInfo.Namespace)
|
||||
.Replace("{UpdateColumns}", updateColumns)
|
||||
.Replace("{InsertColumns}", insertColumns)
|
||||
.Replace("{StartName}", StratName);
|
||||
@@ -370,6 +371,7 @@ namespace OpenAuth.App
|
||||
.Replace("{ModuleCode}", sysTableInfo.ModuleCode)
|
||||
.Replace("{ModuleName}", sysTableInfo.ModuleName)
|
||||
.Replace("{ClassName}", sysTableInfo.ClassName)
|
||||
.Replace("{Namespace}", sysTableInfo.Namespace)
|
||||
.Replace("{SubForeignKey}", subTable.ForeignKey)
|
||||
.Replace("{SubClassName}", subTable.ClassName)
|
||||
.Replace("{SubModuleCode}", subTable.ModuleCode)
|
||||
@@ -508,6 +510,7 @@ namespace OpenAuth.App
|
||||
domainContent = FileHelper.ReadFile(@"Template\\BuildControllerApi.html")
|
||||
.Replace("{TableName}", sysTableInfo.TableName)
|
||||
.Replace("{ModuleCode}", sysTableInfo.ModuleCode)
|
||||
.Replace("{Namespace}", sysTableInfo.Namespace)
|
||||
.Replace("{ModuleName}", sysTableInfo.ModuleName)
|
||||
.Replace("{ClassName}", sysTableInfo.ClassName)
|
||||
.Replace("{StartName}", StratName);
|
||||
@@ -607,6 +610,7 @@ namespace OpenAuth.App
|
||||
|
||||
domainContent = domainContent.Replace("{ClassName}", tableInfo.ClassName)
|
||||
.Replace("{AttributeList}", attributeBuilder.ToString())
|
||||
.Replace("{Namespace}", tableInfo.Namespace)
|
||||
.Replace("{Construction}", constructionBuilder.ToString());
|
||||
|
||||
|
||||
@@ -621,10 +625,29 @@ namespace OpenAuth.App
|
||||
tableAttr.Append(" [Table(\"" + tableInfo.TableName + "\")]");
|
||||
domainContent = domainContent.Replace("{AttributeManager}", tableAttr.ToString());
|
||||
|
||||
FileHelper.WriteFile(
|
||||
mapPath +
|
||||
$"\\OpenAuth.Repository\\Domain\\", tableInfo.ClassName + ".cs",
|
||||
domainContent);
|
||||
// 检查命名空间是否以OpenAuth.Repository开头
|
||||
if (!tableInfo.Namespace.StartsWith("OpenAuth.Repository"))
|
||||
{
|
||||
throw new Exception("命名空间必须以OpenAuth.Repository开头!");
|
||||
}
|
||||
// 获取OpenAuth.Repository后面的部分
|
||||
var subNamespace = tableInfo.Namespace.Substring("OpenAuth.Repository".Length).TrimStart('.');
|
||||
// 构建目录层级
|
||||
var domainPath = Path.Combine(mapPath, "OpenAuth.Repository");
|
||||
if (!string.IsNullOrEmpty(subNamespace))
|
||||
{
|
||||
foreach (var part in subNamespace.Split('.'))
|
||||
{
|
||||
domainPath = Path.Combine(domainPath, part);
|
||||
}
|
||||
}
|
||||
// 确保目录存在
|
||||
if (!Directory.Exists(domainPath))
|
||||
{
|
||||
Directory.CreateDirectory(domainPath);
|
||||
}
|
||||
|
||||
FileHelper.WriteFile(domainPath, tableInfo.ClassName + ".cs", domainContent);
|
||||
}
|
||||
|
||||
Dictionary<string, Type> PrimitiveTypes = new Dictionary<string, Type>()
|
||||
|
||||
@@ -590,6 +590,16 @@ namespace OpenAuth.App.Flow
|
||||
throw new Exception("无法寻找到下一个节点");
|
||||
}
|
||||
|
||||
//如果request为空,则应该是草稿状态变为启动,或为网关节点,使用nextNode的setInfo
|
||||
if (request == null)
|
||||
{
|
||||
request = new NodeDesignateReq
|
||||
{
|
||||
NodeDesignateType = nextNode.setInfo.NodeDesignate,
|
||||
NodeDesignates = nextNode.setInfo.NodeDesignateData.datas
|
||||
};
|
||||
}
|
||||
|
||||
if (GetNextNodeType() == Define.NODE_TYPE_FORK) //如果是网关节点
|
||||
{
|
||||
makerList = GetForkNodeMakers(nextNodeId);
|
||||
|
||||
@@ -68,6 +68,11 @@ namespace OpenAuth.App
|
||||
var elementIds = _revelanceApp.Get(Define.ROLERESOURCE, true, roleId);
|
||||
return SugarClient.Queryable<SysResource>().Where(u => elementIds.Contains(u.Id) && (appId == null || appId =="" || u.AppId == appId)).ToArray();
|
||||
}
|
||||
|
||||
public List<SysResource> LoadByIds(string[] ids)
|
||||
{
|
||||
return SugarClient.Queryable<SysResource>().Where(u => ids.Contains(u.Id)).ToList();
|
||||
}
|
||||
|
||||
public async Task<PagedDynamicDataResp> Load(QueryResourcesReq request)
|
||||
{
|
||||
|
||||
@@ -52,6 +52,16 @@ namespace OpenAuth.App
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据ID加载角色
|
||||
/// </summary>
|
||||
/// <param name="ids"></param>
|
||||
/// <returns></returns>
|
||||
public List<Role> LoadByIds(string[] ids)
|
||||
{
|
||||
return UnitWork.Find<Role>(u => ids.Contains(u.Id)).ToList();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 添加角色,如果当前登录用户不是System,则直接把新角色分配给当前登录用户
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Autofac.Extensions.DependencyInjection;
|
||||
@@ -60,44 +61,71 @@ namespace OpenAuth.App.Test
|
||||
|
||||
serviceCollection.AddDbContext<OpenAuthDBContext>();
|
||||
|
||||
var dbtypes = config.GetSection("AppSetting:DbTypes").GetChildren()
|
||||
.ToDictionary(x => x.Key, x => x.Value);
|
||||
|
||||
var connectionString = config.GetSection("ConnectionStrings")["OpenAuthDBContext"];
|
||||
|
||||
Console.WriteLine($"单元测试数据库信息:{dbtypes[httpContextAccessorMock.Object.GetTenantId()]}/{connectionString}");
|
||||
|
||||
var dbtypes = config.GetSection("AppSetting:DbTypes").GetChildren()
|
||||
.ToDictionary(x => x.Key, x => x.Value);;
|
||||
var sqlsugarTypes = UtilMethods.EnumToDictionary<SqlSugar.DbType>();
|
||||
var dbType = sqlsugarTypes.FirstOrDefault(it =>
|
||||
dbtypes.ToDictionary(u => u.Key, v => v.Value.ToLower()).ContainsValue(it.Key));
|
||||
|
||||
serviceCollection.AddScoped<ISqlSugarClient>(s =>
|
||||
{
|
||||
var sqlSugar = new SqlSugarClient(new ConnectionConfig()
|
||||
// 获取所有连接字符串配置
|
||||
var connectionStrings = config.GetSection("ConnectionStrings").GetChildren()
|
||||
.ToDictionary(x => x.Key, x => x.Value);
|
||||
|
||||
// 准备ConnectionConfig列表
|
||||
var connectionConfigs = new List<ConnectionConfig>();
|
||||
|
||||
// 遍历所有连接字符串
|
||||
foreach (var conn in connectionStrings)
|
||||
{
|
||||
DbType = dbType.Value,
|
||||
ConnectionString = connectionString,
|
||||
IsAutoCloseConnection = true
|
||||
});
|
||||
|
||||
if(dbType.Value != SqlSugar.DbType.PostgreSQL){
|
||||
return sqlSugar;
|
||||
}
|
||||
// 配置bool类型转换为smallint
|
||||
sqlSugar.Aop.OnExecutingChangeSql = (sql, parameters) =>
|
||||
{
|
||||
foreach (var param in parameters)
|
||||
// 获取对应的数据库类型
|
||||
var connDbType = dbtypes.ContainsKey(conn.Key) ?
|
||||
sqlsugarTypes.FirstOrDefault(it => dbtypes[conn.Key].ToLower().Contains(it.Key)).Value :
|
||||
DbType.SqlServer; // 如果没有定义DbType,使用默认类型
|
||||
|
||||
// 创建连接配置
|
||||
var config = new ConnectionConfig
|
||||
{
|
||||
if (param.Value is bool boolValue)
|
||||
{
|
||||
param.DbType = System.Data.DbType.Int16;
|
||||
// 将 bool 转换为 smallint
|
||||
param.Value = boolValue ? (short)1 : (short)0;
|
||||
}
|
||||
DbType = connDbType,
|
||||
ConnectionString = conn.Value,
|
||||
IsAutoCloseConnection = true,
|
||||
};
|
||||
|
||||
// 如果不是默认连接,设置ConfigId
|
||||
if (conn.Key != Define.DEFAULT_TENANT_ID)
|
||||
{
|
||||
config.ConfigId = conn.Key;
|
||||
}
|
||||
// 返回修改后的 SQL 和参数
|
||||
return new System.Collections.Generic.KeyValuePair<string, SugarParameter[]>(sql, parameters);
|
||||
};
|
||||
|
||||
connectionConfigs.Add(config);
|
||||
Console.WriteLine($"添加数据库连接: {conn.Key} / {(dbtypes.ContainsKey(conn.Key) ? dbtypes[conn.Key] : "未指定类型")},连接字符串:{conn.Value}");
|
||||
}
|
||||
|
||||
var sqlSugar = new SqlSugarClient(connectionConfigs);
|
||||
|
||||
// 配置PostgreSQL数据库处理
|
||||
foreach (var connConfig in connectionConfigs)
|
||||
{
|
||||
if(connConfig.DbType == SqlSugar.DbType.PostgreSQL)
|
||||
{
|
||||
// 配置bool类型转换为smallint
|
||||
sqlSugar.Aop.OnExecutingChangeSql = (sql, parameters) =>
|
||||
{
|
||||
foreach (var param in parameters)
|
||||
{
|
||||
if (param.Value is bool boolValue)
|
||||
{
|
||||
param.DbType = System.Data.DbType.Int16;
|
||||
// 将 bool 转换为 smallint
|
||||
param.Value = boolValue ? (short)1 : (short)0;
|
||||
}
|
||||
}
|
||||
// 返回修改后的 SQL 和参数
|
||||
return new System.Collections.Generic.KeyValuePair<string, SugarParameter[]>(sql, parameters);
|
||||
};
|
||||
break; // 找到一个PostgreSQL连接后就设置一次即可
|
||||
}
|
||||
}
|
||||
|
||||
return sqlSugar;
|
||||
});
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace OpenAuth.App.Test
|
||||
|
||||
//模拟路径
|
||||
var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
|
||||
.Replace("\\OpenAuth.App\\bin\\Debug\\netcoreapp3.1","");
|
||||
.Replace("\\OpenAuth.App\\bin\\Debug\\net9.0","");
|
||||
var mockPathProvider = new Mock<IPathProvider>();
|
||||
mockPathProvider.Setup(x => x.MapPath("",false)).Returns(path);
|
||||
services.AddScoped(x => mockHttpFac.Object);
|
||||
|
||||
@@ -340,5 +340,49 @@ namespace OpenAuth.App
|
||||
var users = UnitWork.FromSql<SysUser>(sql);
|
||||
return users.Select(u=>u.Id).ToList();
|
||||
}
|
||||
|
||||
public List<UserView> LoadByIds(string[] ids)
|
||||
{
|
||||
var users = Repository.Find(u => ids.Contains(u.Id));
|
||||
|
||||
//获取用户及用户关联的机构
|
||||
var userOrgs = from user in users
|
||||
join relevance in UnitWork.Find<Relevance>(u => u.RelKey == "UserOrg")
|
||||
on user.Id equals relevance.FirstId into temp
|
||||
from r in temp.DefaultIfEmpty()
|
||||
join org in UnitWork.Find<SysOrg>(null)
|
||||
on r.SecondId equals org.Id into orgtmp
|
||||
from o in orgtmp.DefaultIfEmpty()
|
||||
select new
|
||||
{
|
||||
user.Id,
|
||||
user.Account,
|
||||
user.Name,
|
||||
user.Sex,
|
||||
user.Status,
|
||||
user.CreateTime,
|
||||
user.CreateId,
|
||||
user.ParentId,
|
||||
OrgId = o.Id,
|
||||
OrgName = o.Name
|
||||
};
|
||||
|
||||
var userViews = userOrgs.GroupBy(b => b.Account).Select(u => new UserView
|
||||
{
|
||||
Id = u.First().Id,
|
||||
Account = u.Key,
|
||||
Name = u.First().Name,
|
||||
Sex = u.First().Sex,
|
||||
Status = u.First().Status,
|
||||
CreateTime = u.First().CreateTime,
|
||||
CreateUser = u.First().CreateId,
|
||||
ParentName = u.First().ParentId,
|
||||
ParentId = u.First().ParentId,
|
||||
OrganizationIds = string.Join(",", u.Select(x=>x.OrgId))
|
||||
,Organizations = string.Join(",", u.Select(x=>x.OrgName))
|
||||
});
|
||||
|
||||
return userViews.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -67,44 +68,70 @@ namespace OpenAuth.Repository.Test
|
||||
|
||||
serviceCollection.AddDbContext<OpenAuthDBContext>();
|
||||
|
||||
var dbtypes = config.GetSection("AppSetting:DbTypes").GetChildren()
|
||||
.ToDictionary(x => x.Key, x => x.Value);
|
||||
|
||||
var connectionString = config.GetSection("ConnectionStrings")["OpenAuthDBContext"];
|
||||
Console.WriteLine($"单元测试数据库信息:{dbtypes[httpContextAccessorMock.Object.GetTenantId()]}/{connectionString}");
|
||||
|
||||
var dbtypes = config.GetSection("AppSetting:DbTypes").GetChildren()
|
||||
.ToDictionary(x => x.Key, x => x.Value);;
|
||||
var sqlsugarTypes = UtilMethods.EnumToDictionary<SqlSugar.DbType>();
|
||||
var dbType = sqlsugarTypes.FirstOrDefault(it =>
|
||||
dbtypes.ToDictionary(u => u.Key, v => v.Value.ToLower()).ContainsValue(it.Key));
|
||||
|
||||
serviceCollection.AddScoped<ISqlSugarClient>(s =>
|
||||
{
|
||||
var sqlSugar = new SqlSugarClient(new ConnectionConfig()
|
||||
// 获取所有连接字符串配置
|
||||
var connectionStrings = config.GetSection("ConnectionStrings").GetChildren()
|
||||
.ToDictionary(x => x.Key, x => x.Value);
|
||||
|
||||
// 准备ConnectionConfig列表
|
||||
var connectionConfigs = new List<ConnectionConfig>();
|
||||
|
||||
// 遍历所有连接字符串
|
||||
foreach (var conn in connectionStrings)
|
||||
{
|
||||
DbType = dbType.Value,
|
||||
ConnectionString = connectionString,
|
||||
IsAutoCloseConnection = true
|
||||
});
|
||||
|
||||
if(dbType.Value != SqlSugar.DbType.PostgreSQL){
|
||||
return sqlSugar;
|
||||
// 获取对应的数据库类型
|
||||
var connDbType = dbtypes.ContainsKey(conn.Key) ?
|
||||
sqlsugarTypes.FirstOrDefault(it => dbtypes[conn.Key].ToLower().Contains(it.Key)).Value :
|
||||
DbType.SqlServer; // 如果没有定义DbType,使用默认类型
|
||||
|
||||
// 创建连接配置
|
||||
var config = new ConnectionConfig
|
||||
{
|
||||
DbType = connDbType,
|
||||
ConnectionString = conn.Value,
|
||||
IsAutoCloseConnection = true,
|
||||
};
|
||||
|
||||
// 如果不是默认连接,设置ConfigId
|
||||
if (conn.Key != Define.DEFAULT_TENANT_ID)
|
||||
{
|
||||
config.ConfigId = conn.Key;
|
||||
}
|
||||
|
||||
connectionConfigs.Add(config);
|
||||
Console.WriteLine($"添加数据库连接: {conn.Key} / {(dbtypes.ContainsKey(conn.Key) ? dbtypes[conn.Key] : "未指定类型")},连接字符串:{conn.Value}");
|
||||
}
|
||||
|
||||
// 配置bool类型转换为smallint
|
||||
sqlSugar.Aop.OnExecutingChangeSql = (sql, parameters) =>
|
||||
var sqlSugar = new SqlSugarClient(connectionConfigs);
|
||||
|
||||
// 配置PostgreSQL数据库处理
|
||||
foreach (var connConfig in connectionConfigs)
|
||||
{
|
||||
foreach (var param in parameters)
|
||||
if(connConfig.DbType == SqlSugar.DbType.PostgreSQL)
|
||||
{
|
||||
if (param.Value is bool boolValue)
|
||||
// 配置bool类型转换为smallint
|
||||
sqlSugar.Aop.OnExecutingChangeSql = (sql, parameters) =>
|
||||
{
|
||||
param.DbType = System.Data.DbType.Int16;
|
||||
// 将 bool 转换为 smallint
|
||||
param.Value = boolValue ? (short)1 : (short)0;
|
||||
}
|
||||
foreach (var param in parameters)
|
||||
{
|
||||
if (param.Value is bool boolValue)
|
||||
{
|
||||
param.DbType = System.Data.DbType.Int16;
|
||||
// 将 bool 转换为 smallint
|
||||
param.Value = boolValue ? (short)1 : (short)0;
|
||||
}
|
||||
}
|
||||
// 返回修改后的 SQL 和参数
|
||||
return new System.Collections.Generic.KeyValuePair<string, SugarParameter[]>(sql, parameters);
|
||||
};
|
||||
break; // 找到一个PostgreSQL连接后就设置一次即可
|
||||
}
|
||||
// 返回修改后的 SQL 和参数
|
||||
return new System.Collections.Generic.KeyValuePair<string, SugarParameter[]>(sql, parameters);
|
||||
};
|
||||
}
|
||||
|
||||
return sqlSugar;
|
||||
});
|
||||
|
||||
|
||||
@@ -70,6 +70,14 @@ namespace OpenAuth.WebApi.Controllers
|
||||
return resp;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public Response<List<SysResource>> LoadByIds([FromBody]string[] ids)
|
||||
{
|
||||
var result = new Response<List<SysResource>>();
|
||||
result.Data = _app.LoadByIds(ids);
|
||||
return result;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public Response<string> Add([FromBody] AddOrUpdateResReq obj)
|
||||
{
|
||||
|
||||
@@ -40,6 +40,24 @@ namespace OpenAuth.WebApi.Controllers
|
||||
result.Message = ex.InnerException?.Message ?? ex.Message;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public Response LoadByIds([FromBody]string[] ids)
|
||||
{
|
||||
var result = new Response<List<Role>>();
|
||||
try
|
||||
{
|
||||
result.Data = _app.LoadByIds(ids);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.Code = 500;
|
||||
result.Message = ex.InnerException?.Message ?? ex.Message;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -139,6 +140,24 @@ namespace OpenAuth.WebApi.Controllers
|
||||
return result;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public Response LoadByIds([FromBody]string[] ids)
|
||||
{
|
||||
var result = new Response<List<UserView>>();
|
||||
try
|
||||
{
|
||||
result.Data = _app.LoadByIds(ids);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.Code = 500;
|
||||
result.Message = ex.InnerException?.Message ?? ex.Message;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载指定角色的用户
|
||||
/// </summary>
|
||||
|
||||
@@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using OpenAuth.App;
|
||||
using OpenAuth.App.Request;
|
||||
using OpenAuth.App.Response;
|
||||
using OpenAuth.Repository.Domain;
|
||||
using {Namespace};
|
||||
|
||||
namespace OpenAuth.WebApi.Controllers
|
||||
{
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// This code was generated by a CodeSmith Template.
|
||||
//
|
||||
// DO NOT MODIFY contents of this file. Changes to this
|
||||
// file will be lost if the code is regenerated.
|
||||
// Author:Yubao Li
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
* @Author: yubaolee <yubaolee@163.com> | ahfu~ <954478625@qq.com>
|
||||
* @Description: 实体类
|
||||
* Copyright (c) 2025 by yubaolee | ahfu~ , All Rights Reserved.
|
||||
*/
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using OpenAuth.Repository.Core;
|
||||
|
||||
namespace OpenAuth.Repository.Domain
|
||||
namespace {Namespace}
|
||||
{
|
||||
{AttributeManager}
|
||||
public class {ClassName} : {BaseEntityName}
|
||||
|
||||
@@ -5,7 +5,7 @@ using Infrastructure;
|
||||
using OpenAuth.App.Interface;
|
||||
using OpenAuth.App.Request;
|
||||
using OpenAuth.App.Response;
|
||||
using OpenAuth.Repository.Domain;
|
||||
using {Namespace};
|
||||
using SqlSugar;
|
||||
namespace OpenAuth.App
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ using Infrastructure;
|
||||
using OpenAuth.App.Interface;
|
||||
using OpenAuth.App.Request;
|
||||
using OpenAuth.App.Response;
|
||||
using OpenAuth.Repository.Domain;
|
||||
using {Namespace};
|
||||
using SqlSugar;
|
||||
namespace OpenAuth.App
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@ using Infrastructure;
|
||||
using OpenAuth.App.Interface;
|
||||
using OpenAuth.App.Request;
|
||||
using OpenAuth.App.Response;
|
||||
using OpenAuth.Repository.Domain;
|
||||
using {Namespace};
|
||||
using SqlSugar;
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ using Infrastructure;
|
||||
using OpenAuth.App.Interface;
|
||||
using OpenAuth.App.Request;
|
||||
using OpenAuth.App.Response;
|
||||
using OpenAuth.Repository.Domain;
|
||||
using {Namespace};
|
||||
using SqlSugar;
|
||||
|
||||
|
||||
|
||||
56
README.md
56
README.md
@@ -1,4 +1,4 @@
|
||||
🔥.Net权限管理及快速开发框架、最好用的权限工作流系统。源于Martin Fowler企业级应用开发思想及最新技术组合(SqlSugar、EF、Quartz、AutoFac、WebAPI、Swagger、Mock、NUnit、Vue2/3、Element-ui/plus、IdentityServer等)。核心模块包括:角色授权、代码生成、API鉴权、智能打印、表单设计、工作流、定时任务等。架构易扩展,是中小企业的首选。
|
||||
🔥.Net权限管理及快速开发框架、最好用的权限工作流系统。源于Martin Fowler企业级应用开发思想及最新技术组合(SqlSugar、EF、Quartz、AutoFac、WebAPI、Swagger、Mock、NUnit、UniApp、Vue2/3、Element-ui/plus、IdentityServer等)。核心模块包括:角色授权、代码生成、API鉴权、智能打印、表单设计、工作流、定时任务等。架构易扩展,是中小企业的首选。
|
||||
|
||||
<p align="center">
|
||||
<img src="https://gitee.com/uploads/images/2018/0425/163228_7077c3fd_362401.png" alt="LOGO" width="300" />
|
||||
@@ -65,41 +65,25 @@
|
||||
## 💡核心功能
|
||||
项目深入参考《企业应用架构模式》《重构与模式》《ASP.NET设计模式》等巨著完成每一行代码编写。主要特性:
|
||||
|
||||
* 支持最新版.Net 9.0.100
|
||||
|
||||
* 同时支持EntityFramework、SqlSugar两款最流行的ORM框架
|
||||
|
||||
* 超强的自定义权限控制功能,请参考:[通用权限设计与实现](https://www.cnblogs.com/yubaolee/p/DataPrivilege.html)
|
||||
|
||||
* 完整API鉴权,可以控制角色可访问的API资源,及模块功能字段可见及是否返回,请参考:[按角色授权API资源](http://doc.openauth.net.cn/core/apiauth.html#%E6%8C%89%E8%A7%92%E8%89%B2%E6%8E%88%E6%9D%83api%E8%B5%84%E6%BA%90) 及 [字段权限](http://doc.openauth.net.cn/core/datapropertyrule/)
|
||||
|
||||
* 可拖拽的表单设计。详情:[可拖拽表单](http://doc.openauth.net.cn/pro/dragform/)
|
||||
|
||||
* 可视化流程设计。[可视化流程设计](http://doc.openauth.net.cn/pro/startflow/)
|
||||
|
||||
* 全网最好用的打印解决方案。详情:[智能打印](http://doc.openauth.net.cn/pro/printerplan/)
|
||||
|
||||
* 基于Quartz.Net的定时任务控制,可随时启/停,可视化配置Cron表达式功能,请参考:[定时任务](http://doc.openauth.net.cn/core/job/)
|
||||
|
||||
* 零代码动态API接口,详情:[动态API](http://doc.openauth.net.cn/core/dynamicapi/)
|
||||
|
||||
* 自带代码生成器,可快速生成带有头/明细结构的页面
|
||||
|
||||
* 支持sqlserver、mysql、Oracle、PostgreSql数据库,理论上支持所有数据库
|
||||
|
||||
* 支持同时访问多数据源
|
||||
|
||||
* 支持多租户
|
||||
|
||||
* 支持搭建自己的IdentityServer服务器,实现基于OAuth2的登录体系,请参考:[登录认证及OAuth集成](http://doc.openauth.net.cn/core/identity/)
|
||||
|
||||
* 建立三方对接规范,已有系统可以无缝对接流程引擎
|
||||
|
||||
* vue前端采用 vue + element-ui + vform + hiprinter
|
||||
|
||||
* 后端采用 .net +EF + sqlsugar + autofac + quartz +IdentityServer4 + nunit + swagger
|
||||
|
||||
* 设计工具 PowerDesigner +PDManer + Enterprise Architect
|
||||
* ✅支持最新版.Net 9
|
||||
* ✅同时支持EntityFramework、SqlSugar两款最流行的ORM框架
|
||||
* ✅超强的自定义权限控制,详情:[通用权限设计与实现](https://www.cnblogs.com/yubaolee/p/DataPrivilege.html)
|
||||
* ✅完整API鉴权,可以控制角色可访问的API资源,及模块功能字段可见及是否返回,详情:[按角色授权API资源](http://doc.openauth.net.cn/core/apiauth.html#%E6%8C%89%E8%A7%92%E8%89%B2%E6%8E%88%E6%9D%83api%E8%B5%84%E6%BA%90) 及 [字段权限](http://doc.openauth.net.cn/core/datapropertyrule/)
|
||||
* ✅可拖拽表单设计。详情:[可拖拽表单](http://doc.openauth.net.cn/pro/dragform/)
|
||||
* ✅可视化流程设计。详情:[可视化流程设计](http://doc.openauth.net.cn/pro/startflow/)
|
||||
* ✅全网最好用的打印解决方案,详情:[智能打印](http://doc.openauth.net.cn/pro/printerplan/)
|
||||
* ✅基于Quartz的定时任务控制,可随时启/停,可视化配置Cron表达式,详情:[定时任务](http://doc.openauth.net.cn/core/job/)
|
||||
* ✅零代码动态API接口,详情:[动态API](http://doc.openauth.net.cn/core/dynamicapi/)
|
||||
* ✅超好用代码生成器,可快速生成单表、主从表结构的界面
|
||||
* ✅支持sqlserver、mysql、Oracle、PostgreSql数据库,理论上支持所有数据库
|
||||
* ✅支持多数据源
|
||||
* ✅支持多租户
|
||||
* ✅支持多语言
|
||||
* ✅支持自建OAuth2登录体系,详情:[登录认证及OAuth集成](http://doc.openauth.net.cn/core/identity/)
|
||||
* ✅支持已有系统无缝对接本项目流程引擎
|
||||
* ✅vue前端采用 vue2/3 + element-ui/plus + vform + hiprint + pinia + axios + uniapp
|
||||
* ✅后端采用 .net +EF + sqlsugar + autofac + quartz +IdentityServer4 + nunit + swagger
|
||||
* ✅设计工具 PowerDesigner +PDManer + Enterprise Architect
|
||||
|
||||
## 🔜后续
|
||||
生命不息,更新不止
|
||||
@@ -4,7 +4,7 @@ createTime: 2025/04/23 21:03:10
|
||||
permalink: /core/changesdk/
|
||||
---
|
||||
|
||||
OpenAuth.Net最新版默认使用.Net SDK 9.0.100。如果你使用的是其他版本的sdk(如.net 6.0/7.0等)打开项目,需要调整csproj项目文件的TargetFramework。用记事本等工具,打开 `Infrastructure.csproj` `OpenAuth.Repository.csproj` `OpenAuth.App.csproj` `OpenAuth.Mvc.csproj` `OpenAuth.WebApi.csproj` `OpenAuth.IdentityServer.csproj`,将
|
||||
OpenAuth.Net最新版默认使用.Net SDK 9.0.100。如果你使用的是其他版本的sdk(如.net 6.0/7.0等)打开项目,需要调整csproj项目文件的TargetFramework。用记事本等工具,打开 `Infrastructure.csproj` `OpenAuth.Repository.csproj` `OpenAuth.App.csproj` `OpenAuth.WebApi.csproj` `OpenAuth.IdentityServer.csproj`,将
|
||||
```csharp
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
@@ -32,19 +32,11 @@ OpenAuth.Net支持两种登录认证方式:Token认证和==自己搭建=={.tip
|
||||
不同于其他项目的统一登录(如微信登录、支付宝登录等),OpenAuth.Net的统一登录指的是自己搭建一套OAuth登录服务,提供给其他项目使用。即OpenAuth.IdentityServer。启动后,直接访问[http://localhost:12796](http://localhost:12796),效果如下:
|
||||

|
||||
|
||||
这时我们修改OpenAuth.WebApi/Mvc的IdentityServerUrl配置:
|
||||
这时我们修改OpenAuth.WebApi的IdentityServerUrl配置:
|
||||
```json
|
||||
"IdentityServerUrl": "http://localhost:12796", //IdentityServer服务器地址。
|
||||
```
|
||||
|
||||
### OpenAuth.Mvc效果
|
||||
|
||||
当启用了Identity时,mvc启动后界面如下:
|
||||

|
||||
|
||||
这时点击登录超链接,会跳转到OpenAuth.Identity登录界面。效果如下:
|
||||

|
||||
|
||||
|
||||
### OpenAuth.WebApi效果
|
||||
|
||||
@@ -66,7 +58,8 @@ VITE_OIDC_AUTOMATICSILENTRENEW = true #自动续期
|
||||
如果服务端启用了Identity认证,则打开登录界面如下:
|
||||

|
||||
|
||||
这时点击登录超链接,操作同OpenAuth.Mvc一样。
|
||||
这时点击登录超链接,会跳转到OpenAuth.Identity登录界面。效果如下:
|
||||

|
||||
|
||||
|
||||
#### SwaggerUI
|
||||
|
||||
@@ -4,10 +4,25 @@ createTime: 2025/04/23 23:43:26
|
||||
permalink: /pro/
|
||||
---
|
||||
::: warning 注意
|
||||
如果你使用的是vue2版本,请参考:[OpenAuth.Net Vue2版本](/vue2/)
|
||||
如果你使用的是开源的vue2版本,请参考:[OpenAuth.Net Vue2版本](/vue2/)
|
||||
:::
|
||||
|
||||
OpenAuth.Net Vue3版本基于vue3 + element-plus。使用OpenAuth.Net的API接口(即:OpenAuth.WebApi)提供数据服务。系统架构如下:
|
||||
目前OpenAuth.Net开源版源码、文档全部免费向大家提供,为了使项目走的更远,我们特推出付费订阅的vue3版本,以便更好服务于企业用户。相对于vue2版本,主要有以下优势:
|
||||
|
||||
| 对比项 | Vue3版本 | Vue2版本 |
|
||||
|---------------------|--------------------------------------------|--------------------------------------------|
|
||||
| 技术栈 | Vue3 + Element Plus | Vue2 + Element UI |
|
||||
| 移动端支持 | 提供UniApp版本 | 不支持移动端 |
|
||||
| 组件写法 | 组合式API(setup语法糖) | 选项式API |
|
||||
| 性能优化 | 更优的响应式系统,支持Tree-shaking | 响应式系统较旧,Tree-shaking支持较弱 |
|
||||
| 代码可维护性 | 更高,逻辑复用性强,易于模块化 | 逻辑复用性一般,模块化难度较高 |
|
||||
| 最新功能 | 新特性新功能第一时间上(如:表格列设置、流程加签等) | 社区更新较慢 |
|
||||
| 问题响应 | 官方团队第一时间响应 | 社区响应较慢 |
|
||||
| 技术支持 | 官方团队007待岗响应 | 社区大群沟通 |
|
||||
| 商业授权 | 需商业授权获取源码 | 开源免费 |
|
||||
| 适用场景 | 企业生产环境使用 | 个人、团队研究学习使用 |
|
||||
|
||||
系统架构如下:
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -4,165 +4,181 @@ createTime: 2025/05/24 23:43:26
|
||||
permalink: /pro/selectusercom/
|
||||
---
|
||||
|
||||
SelectUsersCom是一个用于选择用户或角色的基础组件。如下图:
|
||||
SelectUsersCom是一个用于选择用户或角色的组件,提供了两种使用方式:
|
||||
1. 对话框模式 (index.vue)
|
||||
2. 输入框触发模式 (indexwithinput.vue)
|
||||
|
||||

|
||||

|
||||
|
||||
一般通过按钮触发弹框进行选择,如下:
|
||||
## 基础对话框组件 (index.vue)
|
||||
|
||||
```vue
|
||||
<el-button @click="selectDialog = true">选择用户</el-button>
|
||||
<el-dialog :destroy-on-close="true" width="850px" title="选择用户" v-model="selectDialog">
|
||||
<selectUsersCom v-if="selectDialog" :ignore-auth="ignoreAuth" v-model:show="selectDialog" :loginKey="'loginUser'"
|
||||
v-model:users="selectUsers" v-model:userNames="names"></selectUsersCom>
|
||||
</el-dialog>
|
||||
### 组件功能
|
||||
- 支持选择用户或角色
|
||||
- 支持组织树结构浏览
|
||||
- 支持搜索功能
|
||||
- 支持分页显示
|
||||
- 支持已选项目可视化管理
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import SelectUsersCom from '@/components/SelectUsersCom/index.vue'
|
||||
|
||||
const selectDialog = ref(false)
|
||||
const selectUsers = ref([])
|
||||
const names = ref('')
|
||||
const ignoreAuth = ref(false)
|
||||
|
||||
</script>
|
||||
```
|
||||
|
||||
还有一种通过输入框触发弹框进行选择,这时需要回填数据到文本框中。如下:
|
||||
|
||||

|
||||
|
||||
```vue
|
||||
<el-input @click="selectDialog = true" readonly v-model="names" :placeholder="placeholder"></el-input>
|
||||
<el-dialog :destroy-on-close="true" width="850px" title="选择用户" v-model="selectDialog">
|
||||
<selectUsersCom v-if="selectDialog" :ignore-auth="ignoreAuth" v-model:show="selectDialog" :loginKey="'loginUser'"
|
||||
v-model:users="selectUsers" v-model:userNames="names"></selectUsersCom>
|
||||
</el-dialog>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import SelectUsersCom from '@/components/SelectUsersCom/index.vue'
|
||||
|
||||
const selectDialog = ref(false)
|
||||
const selectUsers = ref([])
|
||||
const names = ref('')
|
||||
const ignoreAuth = ref(false)
|
||||
|
||||
</script>
|
||||
```
|
||||
|
||||
为了方便使用,我们在`SelectUsersCom`组件的基础上封装了`/components/SelectUsersCom/dialog.vue`组件用于带文本框的场景。使用如下:
|
||||
|
||||
```vue
|
||||
<select-users v-model:userNames="names" :users="users" :ignore-auth="true"></select-users>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import SelectUsersDialog from '@/components/SelectUsersCom/dialog.vue'
|
||||
|
||||
const names = ref('')
|
||||
const roles = ref([])
|
||||
</script>
|
||||
```
|
||||
|
||||
## 属性
|
||||
### 属性说明
|
||||
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| show | Boolean | false | 控制组件显示/隐藏 |
|
||||
| loginKey | String | - | 选择类型,'loginUser'表示选择用户,其他值表示选择角色 |
|
||||
| orgId | String | - | 组织ID,如果为空则显示左侧树状结构 |
|
||||
| ignoreAuth | Boolean | false | 是否忽略登录用户权限,直接获取全部数据,用于可以跨部门选择用户、角色的场景 |
|
||||
| hiddenFooter | Boolean | false | 是否隐藏底部的确定/取消按钮 |
|
||||
| userNames | String | - | 已选用户/角色名称,逗号分隔 |
|
||||
| users | Array | [] | 已选用户/角色ID列表 |
|
||||
| ignoreAuth | Boolean | false | 是否忽略登录用户权限,直接获取全部数据 |
|
||||
| selectType | String | 'User' | 选择类型,'User'表示选择用户,'Role'表示选择角色 |
|
||||
| orgId | String | - | 组织ID,如果为空则显示左边树状结构 |
|
||||
| userNames | String | - | 用户名称(逗号分隔) |
|
||||
| users | Object | - | 初始选中项ID列表或对象列表 |
|
||||
| inType | String | 'id' | 父级传入的是id列表还是对象列表,取值为'id'或'obj' |
|
||||
| modelValue | Boolean | false | 控制对话框显示 |
|
||||
|
||||
## 事件
|
||||
### 事件说明
|
||||
|
||||
| 事件名 | 说明 | 回调参数 |
|
||||
| --- | --- | --- |
|
||||
| update:show | 组件显示状态变化时触发 | (show: Boolean) |
|
||||
| update:userNames | 选择的用户/角色名称变化时触发 | (userNames: String) |
|
||||
| update:users | 选择的用户/角色ID变化时触发 | (users: Array) |
|
||||
| 事件名 | 说明 |
|
||||
| --- | --- |
|
||||
| update:userNames | 更新用户名称 |
|
||||
| update:users | 更新用户列表 |
|
||||
| save | 保存选择结果 |
|
||||
| update:modelValue | 更新对话框显示状态 |
|
||||
|
||||
## 方法
|
||||
|
||||
| 方法名 | 说明 | 参数 |
|
||||
| --- | --- | --- |
|
||||
| handleSaveUsers | 保存已选中的用户/角色,可通过ref调用 | - |
|
||||
|
||||
## 更多示例
|
||||
|
||||
### 选择角色
|
||||
### 使用示例
|
||||
|
||||
```vue
|
||||
<el-input @click="selectDialog = true" readonly v-model="names" :placeholder="placeholder"></el-input>
|
||||
<el-dialog :destroy-on-close="true" width="850px" title="选择角色" v-model="selectDialog">
|
||||
<selectUsersCom v-if="selectDialog" :ignore-auth="ignoreAuth" v-model:show="selectDialog" :loginKey="'loginRole'"
|
||||
v-model:users="selectRoles" v-model:userNames="names"></selectUsersCom>
|
||||
</el-dialog>
|
||||
<template>
|
||||
<el-button @click="showDialog = true">选择用户</el-button>
|
||||
|
||||
<SelectUsersCom
|
||||
v-model="showDialog"
|
||||
:ignore-auth="true"
|
||||
select-type="User"
|
||||
v-model:users="selectedUsers"
|
||||
v-model:userNames="selectedNames"
|
||||
@save="handleSave"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import SelectUsersCom from '@/components/SelectUsersCom/index.vue'
|
||||
|
||||
const selectDialog = ref(false)
|
||||
const selectRoles = ref([])
|
||||
const names = ref('')
|
||||
const ignoreAuth = ref(false)
|
||||
const showDialog = ref(false)
|
||||
const selectedUsers = ref([])
|
||||
const selectedNames = ref('')
|
||||
|
||||
const handleSave = () => {
|
||||
console.log('已选用户ID:', selectedUsers.value)
|
||||
console.log('已选用户名称:', selectedNames.value)
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
为了方便使用,我们在`SelectUsersCom`组件的基础上封装了`SelectRoles`组件用于选择角色。使用如下:
|
||||
## 输入框触发模式 (indexwithinput.vue)
|
||||
|
||||
### 组件功能
|
||||
- 默认显示为输入框
|
||||
- 点击输入框弹出选择对话框
|
||||
- 支持根据用户ID自动获取用户姓名
|
||||
- 支持选择用户并回显名称
|
||||
|
||||
### 属性说明
|
||||
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| users | Array/String | - | 用户ID列表或单个用户ID |
|
||||
| userNames | String | '' | 用户名称(逗号分隔) |
|
||||
| placeholder | String | '' | 输入框占位符 |
|
||||
| ignoreAuth | Boolean | false | 是否忽略权限限制 |
|
||||
|
||||
### 事件说明
|
||||
|
||||
| 事件名 | 说明 |
|
||||
| --- | --- |
|
||||
| users-change | 用户选择变更时触发,参数为('users', 选中的用户ID列表)或('Texts', 选中的用户名称) |
|
||||
|
||||
### 使用示例
|
||||
|
||||
```vue
|
||||
<select-roles v-model:userNames="names" :roles="roles" :ignore-auth="true"></select-roles>
|
||||
<template>
|
||||
<SelectUsersComInput
|
||||
:users="selectedUserIds"
|
||||
:user-names="selectedUserNames"
|
||||
placeholder="请选择用户"
|
||||
:ignore-auth="true"
|
||||
@users-change="handleUsersChange"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import SelectRoles from '@/components/SelectRoles/index.vue'
|
||||
import SelectUsersComInput from '@/components/SelectUsersCom/indexwithinput.vue'
|
||||
|
||||
const names = ref('')
|
||||
const roles = ref([])
|
||||
const selectedUserIds = ref(['user1', 'user2'])
|
||||
const selectedUserNames = ref('张三,李四')
|
||||
|
||||
const handleUsersChange = (type, value) => {
|
||||
if (type === 'users') {
|
||||
selectedUserIds.value = value
|
||||
} else if (type === 'Texts') {
|
||||
selectedUserNames.value = value
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
### 不显示底部按钮,通过ref调用方法
|
||||
## 角色选择输入框 (SelectRoles/indexwithinput.vue)
|
||||
|
||||
### 组件功能
|
||||
- 基于SelectUsersCom实现的角色选择器
|
||||
- 默认显示为输入框
|
||||
- 点击输入框弹出选择角色对话框
|
||||
|
||||
### 属性说明
|
||||
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| roles | Array | - | 角色ID列表 |
|
||||
| userNames | String | - | 角色名称(逗号分隔) |
|
||||
| placeholder | String | - | 输入框占位符 |
|
||||
| ignoreAuth | Boolean | false | 是否忽略权限限制 |
|
||||
|
||||
### 事件说明
|
||||
|
||||
| 事件名 | 说明 |
|
||||
| --- | --- |
|
||||
| roles-change | 角色选择变更时触发,参数为('roles', 选中的角色ID列表)或('Texts', 选中的角色名称) |
|
||||
|
||||
### 使用示例
|
||||
|
||||
```vue
|
||||
<el-dialog width="80%" draggable :title="'选择用户'" v-model="dialogSelectUser">
|
||||
<selectUsersCom ref="selectUserRef" v-if="dialogSelectUser" :hiddenFooter="true" :loginKey="'loginUser'"
|
||||
v-model:users="selectUsers"></selectUsersCom>
|
||||
<template v-slot:footer>
|
||||
<div style="text-align: right">
|
||||
<el-button size="small" type="info" @click="dialogSelectUser = false">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button size="small" type="primary" @click="handleSaveUsers">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<template>
|
||||
<SelectRolesInput
|
||||
:roles="selectedRoleIds"
|
||||
:user-names="selectedRoleNames"
|
||||
placeholder="请选择角色"
|
||||
:ignore-auth="true"
|
||||
@roles-change="handleRolesChange"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import SelectUsersCom from '@/components/SelectUsersCom/index.vue'
|
||||
import SelectRolesInput from '@/components/SelectRoles/indexwithinput.vue'
|
||||
|
||||
const selectUserRef = ref(null)
|
||||
const dialogSelectUser = ref(false)
|
||||
const selectUsers = ref([])
|
||||
const selectedRoleIds = ref(['role1', 'role2'])
|
||||
const selectedRoleNames = ref('管理员,操作员')
|
||||
|
||||
//确定添加的用户
|
||||
const handleSaveUsers = () => {
|
||||
selectUserRef.value.handleSaveUsers()
|
||||
dialogSelectUser.value = false
|
||||
const handleRolesChange = (type, value) => {
|
||||
if (type === 'roles') {
|
||||
selectedRoleIds.value = value
|
||||
} else if (type === 'Texts') {
|
||||
selectedRoleNames.value = value
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 当`ignoreAuth`为`true`时,将调用`loadAll`接口获取所有数据,否则调用`getList`接口获取有权限的数据
|
||||
1. 使用indexwithinput.vue时,如果在弹出框中使用,建议设置`:destroy-on-close="true"`,避免names记录上一次选中行的值
|
||||
2. 选择用户时可以通过组织树进行筛选,也可以直接搜索
|
||||
3. ignoreAuth属性可以控制是否忽略用户权限限制,直接获取全部数据
|
||||
4. 组件内部会自动处理用户ID和用户名称的映射关系
|
||||
@@ -578,8 +578,8 @@ COMMENT ON TABLE "EXTERNALDATASOURCE" IS '外部数据源管理';
|
||||
-- ----------------------------
|
||||
-- Records of EXTERNALDATASOURCE
|
||||
-- ----------------------------
|
||||
INSERT INTO "EXTERNALDATASOURCE" VALUES ('94279d93-cef3-46e0-83af-3b7dc48764fe', '本地SqlServer', '1', 'Data Source=localhost;Encrypt=false;Initial Catalog=openauthpro;User=sa;Password=000000;', 'localhost', NULL, 'openauthpro', 'sa', '000000', '1', TO_DATE('2025-03-15 20:09:35', 'SYYYY-MM-DD HH24:MI:SS'), TO_DATE('2025-03-18 11:42:08', 'SYYYY-MM-DD HH24:MI:SS'), '0', NULL, '00000000-0000-0000-0000-000000000000', '超级管理员', '00000000-0000-0000-0000-000000000000', '超级管理员');
|
||||
INSERT INTO "EXTERNALDATASOURCE" VALUES ('94279d93-cef3-46e0-83af-3b7dc48764ff', '本地mysql', '0', 'Server=127.0.0.1;Database=openauthpro;User=root;Password=000000;', '127.0.0.1', '3306', 'openauthpro', 'root', '000000', '1', TO_DATE('2025-03-15 00:02:11', 'SYYYY-MM-DD HH24:MI:SS'), TO_DATE('2025-03-15 20:12:30', 'SYYYY-MM-DD HH24:MI:SS'), '0', NULL, '00000000-0000-0000-0000-000000000000', '超级管理员', '00000000-0000-0000-0000-000000000000', '超级管理员');
|
||||
INSERT INTO "EXTERNALDATASOURCE" VALUES ('94279d93-cef3-46e0-83af-3b7dc48764fe', '非默认的SqlServer', '1', 'Data Source=localhost;Encrypt=false;Initial Catalog=openauthpro;User=sa;Password=000000;', 'localhost', NULL, 'openauthpro', 'sa', '000000', '1', TO_DATE('2025-03-15 20:09:35', 'SYYYY-MM-DD HH24:MI:SS'), TO_DATE('2025-03-18 11:42:08', 'SYYYY-MM-DD HH24:MI:SS'), '0', NULL, '00000000-0000-0000-0000-000000000000', '超级管理员', '00000000-0000-0000-0000-000000000000', '超级管理员');
|
||||
INSERT INTO "EXTERNALDATASOURCE" VALUES ('94279d93-cef3-46e0-83af-3b7dc48764ff', '非默认的mysql', '0', 'Server=127.0.0.1;Database=openauthpro;User=root;Password=000000;', '127.0.0.1', '3306', 'openauthpro', 'root', '000000', '1', TO_DATE('2025-03-15 00:02:11', 'SYYYY-MM-DD HH24:MI:SS'), TO_DATE('2025-03-15 20:12:30', 'SYYYY-MM-DD HH24:MI:SS'), '0', NULL, '00000000-0000-0000-0000-000000000000', '超级管理员', '00000000-0000-0000-0000-000000000000', '超级管理员');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for FLOWAPPROVER
|
||||
|
||||
@@ -480,8 +480,8 @@ COMMENT ON TABLE "public"."externaldatasource" IS '外部数据源管理';
|
||||
-- ----------------------------
|
||||
-- Records of externaldatasource
|
||||
-- ----------------------------
|
||||
INSERT INTO "public"."externaldatasource" VALUES ('94279d93-cef3-46e0-83af-3b7dc48764fe', '本地SqlServer', 1, 'Data Source=localhost;Encrypt=false;Initial Catalog=openauthpro;User=sa;Password=000000;', 'localhost', NULL, 'openauthpro', 'sa', '000000', 1, '2025-03-15 20:09:35', '2025-03-18 11:42:08', 0, '', '00000000-0000-0000-0000-000000000000', '超级管理员', '00000000-0000-0000-0000-000000000000', '超级管理员');
|
||||
INSERT INTO "public"."externaldatasource" VALUES ('94279d93-cef3-46e0-83af-3b7dc48764ff', '本地mysql', 0, 'Server=127.0.0.1;Database=openauthpro;User=root;Password=000000;', '127.0.0.1', 3306, 'openauthpro', 'root', '000000', 1, '2025-03-15 00:02:11', '2025-03-15 20:12:30', 0, '', '00000000-0000-0000-0000-000000000000', '超级管理员', '00000000-0000-0000-0000-000000000000', '超级管理员');
|
||||
INSERT INTO "public"."externaldatasource" VALUES ('94279d93-cef3-46e0-83af-3b7dc48764fe', '非默认的SqlServer', 1, 'Data Source=localhost;Encrypt=false;Initial Catalog=openauthpro;User=sa;Password=000000;', 'localhost', NULL, 'openauthpro', 'sa', '000000', 1, '2025-03-15 20:09:35', '2025-03-18 11:42:08', 0, '', '00000000-0000-0000-0000-000000000000', '超级管理员', '00000000-0000-0000-0000-000000000000', '超级管理员');
|
||||
INSERT INTO "public"."externaldatasource" VALUES ('94279d93-cef3-46e0-83af-3b7dc48764ff', '非默认的mysql', 0, 'Server=127.0.0.1;Database=openauthpro;User=root;Password=000000;', '127.0.0.1', 3306, 'openauthpro', 'root', '000000', 1, '2025-03-15 00:02:11', '2025-03-15 20:12:30', 0, '', '00000000-0000-0000-0000-000000000000', '超级管理员', '00000000-0000-0000-0000-000000000000', '超级管理员');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for flowapprover
|
||||
|
||||
@@ -1522,10 +1522,10 @@ GO
|
||||
-- ----------------------------
|
||||
-- Records of ExternalDataSource
|
||||
-- ----------------------------
|
||||
INSERT INTO [dbo].[ExternalDataSource] ([Id], [Name], [DbType], [ConnectionString], [Server], [Port], [DatabaseName], [UserName], [Password], [Enabled], [CreateTime], [UpdateTime], [TestSuccess], [Description], [CreateUserId], [CreateUserName], [UpdateUserId], [UpdateUserName]) VALUES (N'94279d93-cef3-46e0-83af-3b7dc48764fe', N'本地SqlServer', N'1', N'Data Source=localhost;Encrypt=false;Initial Catalog=openauthpro;User=sa;Password=000000;', N'localhost', NULL, N'openauthpro', N'sa', N'000000', N'1', N'2025-03-15', N'2025-03-18', N'0', N'', N'00000000-0000-0000-0000-000000000000', N'超级管理员', N'00000000-0000-0000-0000-000000000000', N'超级管理员')
|
||||
INSERT INTO [dbo].[ExternalDataSource] ([Id], [Name], [DbType], [ConnectionString], [Server], [Port], [DatabaseName], [UserName], [Password], [Enabled], [CreateTime], [UpdateTime], [TestSuccess], [Description], [CreateUserId], [CreateUserName], [UpdateUserId], [UpdateUserName]) VALUES (N'94279d93-cef3-46e0-83af-3b7dc48764fe', N'非默认的SqlServer', N'1', N'Data Source=localhost;Encrypt=false;Initial Catalog=openauthpro;User=sa;Password=000000;', N'localhost', NULL, N'openauthpro', N'sa', N'000000', N'1', N'2025-03-15', N'2025-03-18', N'0', N'', N'00000000-0000-0000-0000-000000000000', N'超级管理员', N'00000000-0000-0000-0000-000000000000', N'超级管理员')
|
||||
GO
|
||||
|
||||
INSERT INTO [dbo].[ExternalDataSource] ([Id], [Name], [DbType], [ConnectionString], [Server], [Port], [DatabaseName], [UserName], [Password], [Enabled], [CreateTime], [UpdateTime], [TestSuccess], [Description], [CreateUserId], [CreateUserName], [UpdateUserId], [UpdateUserName]) VALUES (N'94279d93-cef3-46e0-83af-3b7dc48764ff', N'本地mysql', N'0', N'Server=127.0.0.1;Database=openauthpro;User=root;Password=000000;', N'127.0.0.1', N'3306', N'openauthpro', N'root', N'000000', N'1', N'2025-03-15', N'2025-03-15', N'0', N'', N'00000000-0000-0000-0000-000000000000', N'超级管理员', N'00000000-0000-0000-0000-000000000000', N'超级管理员')
|
||||
INSERT INTO [dbo].[ExternalDataSource] ([Id], [Name], [DbType], [ConnectionString], [Server], [Port], [DatabaseName], [UserName], [Password], [Enabled], [CreateTime], [UpdateTime], [TestSuccess], [Description], [CreateUserId], [CreateUserName], [UpdateUserId], [UpdateUserName]) VALUES (N'94279d93-cef3-46e0-83af-3b7dc48764ff', N'非默认的mysql', N'0', N'Server=127.0.0.1;Database=openauthpro;User=root;Password=000000;', N'127.0.0.1', N'3306', N'openauthpro', N'root', N'000000', N'1', N'2025-03-15', N'2025-03-15', N'0', N'', N'00000000-0000-0000-0000-000000000000', N'超级管理员', N'00000000-0000-0000-0000-000000000000', N'超级管理员')
|
||||
GO
|
||||
|
||||
|
||||
|
||||
@@ -373,8 +373,8 @@ CREATE TABLE `externaldatasource` (
|
||||
-- ----------------------------
|
||||
-- Records of externaldatasource
|
||||
-- ----------------------------
|
||||
INSERT INTO `externaldatasource` VALUES ('94279d93-cef3-46e0-83af-3b7dc48764fe', '本地SqlServer', 1, 'Data Source=localhost;Encrypt=false;Initial Catalog=openauthpro;User=sa;Password=000000;', 'localhost', NULL, 'openauthpro', 'sa', '000000', 1, '2025-03-15 20:09:35', '2025-03-18 11:42:08', 0, '', '00000000-0000-0000-0000-000000000000', '超级管理员', '00000000-0000-0000-0000-000000000000', '超级管理员');
|
||||
INSERT INTO `externaldatasource` VALUES ('94279d93-cef3-46e0-83af-3b7dc48764ff', '本地mysql', 0, 'Server=127.0.0.1;Database=openauthpro;User=root;Password=000000;', '127.0.0.1', 3306, 'openauthpro', 'root', '000000', 1, '2025-03-15 00:02:11', '2025-03-15 20:12:30', 0, '', '00000000-0000-0000-0000-000000000000', '超级管理员', '00000000-0000-0000-0000-000000000000', '超级管理员');
|
||||
INSERT INTO `externaldatasource` VALUES ('94279d93-cef3-46e0-83af-3b7dc48764fe', '非默认的SqlServer', 1, 'Data Source=localhost;Encrypt=false;Initial Catalog=openauthpro;User=sa;Password=000000;', 'localhost', NULL, 'openauthpro', 'sa', '000000', 1, '2025-03-15 20:09:35', '2025-03-18 11:42:08', 0, '', '00000000-0000-0000-0000-000000000000', '超级管理员', '00000000-0000-0000-0000-000000000000', '超级管理员');
|
||||
INSERT INTO `externaldatasource` VALUES ('94279d93-cef3-46e0-83af-3b7dc48764ff', '非默认的mysql', 0, 'Server=127.0.0.1;Database=openauthpro;User=root;Password=000000;', '127.0.0.1', 3306, 'openauthpro', 'root', '000000', 1, '2025-03-15 00:02:11', '2025-03-15 20:12:30', 0, '', '00000000-0000-0000-0000-000000000000', '超级管理员', '00000000-0000-0000-0000-000000000000', '超级管理员');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for flowapprover
|
||||
|
||||
Reference in New Issue
Block a user