11 Commits
8.2 ... 8.3.1

Author SHA1 Message Date
yubaolee
e6410c9da6 Merge branch 'main' of https://gitee.com/dotnetchina/OpenAuth.Net into main 2025-07-24 00:08:29 +08:00
yubaolee
4730ac7a36 📃docs: 文档更新 2025-07-24 00:07:50 +08:00
yubaolee
33cc0b1e3b ⚠️feat: 为前端穿梭框提供接口 2025-07-23 17:50:55 +08:00
yubaolee
87866d08fb 📃docs: 文档更新 2025-07-21 23:14:38 +08:00
yubaolee
6b2c50252b ⚠️feat: 为前端穿梭框提供接口 2025-07-21 00:42:35 +08:00
yubaolee
c85793bb55 🐛fix: #ICMS86 创建新的任务保存时提示job name不能为null 2025-07-16 21:18:29 +08:00
yubaolee
f980fc5afc 🐛fix: #ICL05Q 代码生成命名空间设置无效 2025-07-10 21:24:26 +08:00
yubaolee
d83a40e07e ⚠️feat: 完善测试访问多数据库 2025-07-06 23:40:10 +08:00
yubaolee
695f5af89f 📃docs: 文档更新 2025-07-04 00:07:59 +08:00
yubaolee
82bb5b8f3e 🔧chore: 调整.gitignore 2025-07-03 23:38:56 +08:00
yubaolee
1c6ab0348f 🐛fix: #ICJH8Z 启动已召回流程报错 2025-07-02 21:55:18 +08:00
28 changed files with 459 additions and 254 deletions

1
.gitignore vendored
View File

@@ -268,3 +268,4 @@ __pycache__/
/OpenAuth.Mvc/Properties/PublishProfiles
*.pubxml
/OpenAuth.WebApi/temp-keys
/newdocs/docs/.vuepress/.cache

View File

@@ -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);
}

View File

@@ -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>()

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -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则直接把新角色分配给当前登录用户

View File

@@ -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;
});

View File

@@ -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);

View File

@@ -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();
}
}
}

View File

@@ -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;
});

View File

@@ -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)
{

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -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
{

View File

@@ -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}

View File

@@ -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
{

View File

@@ -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
{

View File

@@ -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;

View File

@@ -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;

View File

@@ -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
## 🔜后续
生命不息,更新不止

View File

@@ -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>

View File

@@ -32,19 +32,11 @@ OpenAuth.Net支持两种登录认证方式Token认证和==自己搭建=={.tip
不同于其他项目的统一登录(如微信登录、支付宝登录等),OpenAuth.Net的统一登录指的是自己搭建一套OAuth登录服务提供给其他项目使用。即OpenAuth.IdentityServer。启动后直接访问[http://localhost:12796](http://localhost:12796),效果如下:
![2025-03-18-23-12-18](http://img.openauth.net.cn/2025-03-18-23-12-18.png)
这时我们修改OpenAuth.WebApi/Mvc的IdentityServerUrl配置
这时我们修改OpenAuth.WebApi的IdentityServerUrl配置
```json
"IdentityServerUrl": "http://localhost:12796", //IdentityServer服务器地址。
```
### OpenAuth.Mvc效果
当启用了Identity时mvc启动后界面如下
![2025-04-24-00-24-28](http://img.openauth.net.cn/2025-04-24-00-24-28.png)
这时点击登录超链接会跳转到OpenAuth.Identity登录界面。效果如下
![2025-04-24-00-24-40](http://img.openauth.net.cn/2025-04-24-00-24-40.png)
### OpenAuth.WebApi效果
@@ -66,7 +58,8 @@ VITE_OIDC_AUTOMATICSILENTRENEW = true #自动续期
如果服务端启用了Identity认证则打开登录界面如下
![2025-03-10-14-46-47](http://img.openauth.net.cn/2025-03-10-14-46-47.png)
这时点击登录超链接,操作同OpenAuth.Mvc一样。
这时点击登录超链接,会跳转到OpenAuth.Identity登录界面。效果如下
![2025-04-24-00-24-40](http://img.openauth.net.cn/2025-04-24-00-24-40.png)
#### SwaggerUI

View File

@@ -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版本 | 不支持移动端 |
| 组件写法 | 组合式APIsetup语法糖 | 选项式API |
| 性能优化 | 更优的响应式系统支持Tree-shaking | 响应式系统较旧Tree-shaking支持较弱 |
| 代码可维护性 | 更高,逻辑复用性强,易于模块化 | 逻辑复用性一般,模块化难度较高 |
| 最新功能 | 新特性新功能第一时间上(如:表格列设置、流程加签等) | 社区更新较慢 |
| 问题响应 | 官方团队第一时间响应 | 社区响应较慢 |
| 技术支持 | 官方团队007待岗响应 | 社区大群沟通 |
| 商业授权 | 需商业授权获取源码 | 开源免费 |
| 适用场景 | 企业生产环境使用 | 个人、团队研究学习使用 |
系统架构如下:
![系统架构](http://img.openauth.net.cn/系统架构.png)

View File

@@ -4,165 +4,181 @@ createTime: 2025/05/24 23:43:26
permalink: /pro/selectusercom/
---
SelectUsersCom是一个用于选择用户或角色的基础组件。如下图
SelectUsersCom是一个用于选择用户或角色的组件,提供了两种使用方式
1. 对话框模式 (index.vue)
2. 输入框触发模式 (indexwithinput.vue)
![2025-05-24-12-15-46](http://img.openauth.net.cn/2025-05-24-12-15-46.png)
![2025-07-24-00-07-13](http://img.openauth.net.cn/2025-07-24-00-07-13.png)
一般通过按钮触发弹框进行选择,如下:
## 基础对话框组件 (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>
```
还有一种通过输入框触发弹框进行选择,这时需要回填数据到文本框中。如下:
![2025-05-24-11-44-26](http://img.openauth.net.cn/2025-05-24-11-44-26.png)
```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和用户名称的映射关系

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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