Compare commits
64 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3747773685 | ||
|
|
7c0107f78e | ||
|
|
ce01dca5c3 | ||
|
|
f7bd7e22b4 | ||
|
|
985f898d88 | ||
|
|
e8b85fc05a | ||
|
|
a978fa7e22 | ||
|
|
576ff6e98a | ||
|
|
032f5551dc | ||
|
|
a28458347a | ||
|
|
3def1e6bfc | ||
|
|
a42b2dcb7c | ||
|
|
89fe623a72 | ||
|
|
107e297e01 | ||
|
|
8c129d6746 | ||
|
|
688caa324b | ||
|
|
a6fdf4e6ce | ||
|
|
b583b2adbf | ||
|
|
17e426c785 | ||
|
|
85497a544a | ||
|
|
aa7056bfb3 | ||
|
|
9653778c77 | ||
|
|
59a099b607 | ||
|
|
bf9be59a84 | ||
|
|
c7ff40615b | ||
|
|
61240b6f16 | ||
|
|
1750ff4c9e | ||
|
|
700bf8dea4 | ||
|
|
dd02328033 | ||
|
|
8ae512022e | ||
|
|
4a3d51b13d | ||
|
|
1926a3a09b | ||
|
|
ca8b2a82c4 | ||
|
|
1525a25aba | ||
|
|
2b0979dc88 | ||
|
|
918b6a53d4 | ||
|
|
1e2cfcb208 | ||
|
|
05922c77f3 | ||
|
|
346d0e9d5d | ||
|
|
df83cde075 | ||
|
|
390ab89dff | ||
|
|
757d86a765 | ||
|
|
8d6e1e5a65 | ||
|
|
3895a16942 | ||
|
|
8027c7b5bb | ||
|
|
263ff70f26 | ||
|
|
d5249d8cb3 | ||
|
|
3eb94d7f21 | ||
|
|
1b0a9193d1 | ||
|
|
b5bb518bd2 | ||
|
|
8359e21fdd | ||
|
|
831053aaf1 | ||
|
|
d32ef5b78d | ||
|
|
ac72a26313 | ||
|
|
daf7273537 | ||
|
|
9117e88e3e | ||
|
|
964ccb0d0b | ||
|
|
612f60f1b6 | ||
|
|
39f5b9790c | ||
|
|
3693a9dc44 | ||
|
|
77445b7197 | ||
|
|
24d383cdb0 | ||
|
|
9255a91669 | ||
|
|
33a5293ee1 |
29
.cursor/mcp.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"PostgreSQL": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"@modelcontextprotocol/server-postgres",
|
||||
"postgresql://postgres:AwxBRx1_5kljfy@172.30.144.46/openauthpro"
|
||||
],
|
||||
"env": {}
|
||||
},
|
||||
"mysql": {
|
||||
"type": "stdio",
|
||||
"command": "uvx",
|
||||
"args": [
|
||||
"--from",
|
||||
"mysql-mcp-server",
|
||||
"mysql_mcp_server"
|
||||
],
|
||||
"env": {
|
||||
"MYSQL_HOST": "localhost",
|
||||
"MYSQL_PORT": "3306",
|
||||
"MYSQL_USER": "root",
|
||||
"MYSQL_PASSWORD": "000000",
|
||||
"MYSQL_DATABASE": "openauthpro"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ Description="连接的数据库" %>
|
||||
<%@ Import Namespace="Util" %>
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
}
|
||||
<blockquote class="layui-elem-quote news_search toolList" id="menus">
|
||||
</blockquote>
|
||||
|
||||
@@ -5,47 +5,247 @@
|
||||
/// </summary>
|
||||
public static class Define
|
||||
{
|
||||
public static string USERROLE = "UserRole"; //用户角色关联KEY
|
||||
public const string ROLERESOURCE = "RoleResource"; //角色资源关联KEY
|
||||
public const string USERORG = "UserOrg"; //用户机构关联KEY
|
||||
public const string ROLEELEMENT = "RoleElement"; //角色菜单关联KEY
|
||||
public const string ROLEMODULE = "RoleModule"; //角色模块关联KEY
|
||||
public const string ROLEDATAPROPERTY = "RoleDataProperty"; //角色数据字段权限
|
||||
public const string MODULEPRINTERPLAN = "ModulePrinterPlan"; //模块配置打印方案
|
||||
public const string MODULE_FLOWSCHEME = "ModuleFlowScheme"; //模块挂载流程模板
|
||||
//Relevance关联KEY
|
||||
/// <summary>
|
||||
/// 用户角色关联KEY
|
||||
/// </summary>
|
||||
public static string USERROLE = "UserRole";
|
||||
|
||||
/// <summary>
|
||||
/// 角色资源关联KEY
|
||||
/// </summary>
|
||||
public const string ROLERESOURCE = "RoleResource";
|
||||
|
||||
/// <summary>
|
||||
/// 用户机构关联KEY
|
||||
/// </summary>
|
||||
public const string USERORG = "UserOrg";
|
||||
|
||||
/// <summary>
|
||||
/// 角色菜单关联KEY
|
||||
/// </summary>
|
||||
public const string ROLEELEMENT = "RoleElement";
|
||||
|
||||
/// <summary>
|
||||
/// 角色模块关联KEY
|
||||
/// </summary>
|
||||
public const string ROLEMODULE = "RoleModule";
|
||||
|
||||
/// <summary>
|
||||
/// 角色数据字段权限
|
||||
/// </summary>
|
||||
public const string ROLEDATAPROPERTY = "RoleDataProperty";
|
||||
|
||||
/// <summary>
|
||||
/// 模块配置打印方案
|
||||
/// </summary>
|
||||
public const string MODULEPRINTERPLAN = "ModulePrinterPlan";
|
||||
|
||||
/// <summary>
|
||||
/// 模块挂载流程模板
|
||||
/// </summary>
|
||||
public const string MODULE_FLOWSCHEME = "ModuleFlowScheme";
|
||||
|
||||
public const string DBTYPE_SQLSERVER = "SqlServer"; //sql server
|
||||
public const string DBTYPE_MYSQL = "MySql"; //mysql
|
||||
public const string DBTYPE_PostgreSQL = "PostgreSQL"; //PostgreSQL
|
||||
public const string DBTYPE_ORACLE = "Oracle"; //oracle
|
||||
//数据库类型
|
||||
/// <summary>
|
||||
/// 数据库类型:SQL Server
|
||||
/// </summary>
|
||||
public const string DBTYPE_SQLSERVER = "SqlServer";
|
||||
|
||||
/// <summary>
|
||||
/// 数据库类型:MySQL
|
||||
/// </summary>
|
||||
public const string DBTYPE_MYSQL = "MySql";
|
||||
|
||||
/// <summary>
|
||||
/// 数据库类型:PostgreSQL
|
||||
/// </summary>
|
||||
public const string DBTYPE_PostgreSQL = "PostgreSQL";
|
||||
|
||||
/// <summary>
|
||||
/// 数据库类型:Oracle
|
||||
/// </summary>
|
||||
public const string DBTYPE_ORACLE = "Oracle";
|
||||
|
||||
public const int INVALID_TOKEN = 50014; //token无效
|
||||
/// <summary>
|
||||
/// Token无效错误码:50014
|
||||
/// </summary>
|
||||
public const int INVALID_TOKEN = 50014;
|
||||
|
||||
/// <summary>
|
||||
/// Token名称,用于HTTP请求头
|
||||
/// </summary>
|
||||
public const string TOKEN_NAME = "X-Token";
|
||||
|
||||
/// <summary>
|
||||
/// 租户ID标识
|
||||
/// </summary>
|
||||
public const string TENANT_ID = "tenantId";
|
||||
|
||||
/// <summary>
|
||||
/// 系统用户名
|
||||
/// </summary>
|
||||
public const string SYSTEM_USERNAME = "System";
|
||||
|
||||
/// <summary>
|
||||
/// 系统用户默认密码
|
||||
/// </summary>
|
||||
public const string SYSTEM_USERPWD = "123456";
|
||||
|
||||
public const string DATAPRIVILEGE_LOGINUSER = "{loginUser}"; //数据权限配置中,当前登录用户的key
|
||||
public const string DATAPRIVILEGE_LOGINROLE = "{loginRole}"; //数据权限配置中,当前登录用户角色的key
|
||||
public const string DATAPRIVILEGE_LOGINORG = "{loginOrg}"; //数据权限配置中,当前登录用户部门的key
|
||||
/// <summary>
|
||||
/// 数据权限配置中,当前登录用户的key
|
||||
/// </summary>
|
||||
public const string DATAPRIVILEGE_LOGINUSER = "{loginUser}";
|
||||
|
||||
/// <summary>
|
||||
/// 数据权限配置中,当前登录用户角色的key
|
||||
/// </summary>
|
||||
public const string DATAPRIVILEGE_LOGINROLE = "{loginRole}";
|
||||
|
||||
/// <summary>
|
||||
/// 数据权限配置中,当前登录用户部门的key
|
||||
/// </summary>
|
||||
public const string DATAPRIVILEGE_LOGINORG = "{loginOrg}";
|
||||
|
||||
/// <summary>
|
||||
/// 任务调度映射键
|
||||
/// </summary>
|
||||
public const string JOBMAPKEY = "OpenJob";
|
||||
|
||||
/// <summary>
|
||||
/// 默认表单实例ID字段名
|
||||
/// </summary>
|
||||
public const string DEFAULT_FORM_INSTANCE_ID_NAME = "InstanceId";
|
||||
|
||||
//流程实例知会用户
|
||||
//表单类型
|
||||
/// <summary>
|
||||
/// 表单类型:动态表单(0)
|
||||
/// </summary>
|
||||
public const int FORM_TYPE_DYNAMIC = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 表单类型:自定义表单(1)
|
||||
/// </summary>
|
||||
public const int FORM_TYPE_DEVELOP = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 表单类型:vForm拖拽表单(2)
|
||||
/// </summary>
|
||||
public const int FORM_TYPE_DRAG = 2;
|
||||
|
||||
/// <summary>
|
||||
/// 表单类型:URL表单(3)
|
||||
/// </summary>
|
||||
public const int FORM_TYPE_URL = 3;
|
||||
|
||||
|
||||
//节点类型
|
||||
/// <summary>
|
||||
/// 节点类型:开始节点
|
||||
/// </summary>
|
||||
public const string NODE_TYPE_START = "start";
|
||||
|
||||
/// <summary>
|
||||
/// 节点类型:结束节点
|
||||
/// </summary>
|
||||
public const string NODE_TYPE_END = "end";
|
||||
|
||||
/// <summary>
|
||||
/// 节点类型:任务节点
|
||||
/// </summary>
|
||||
public const string NODE_TYPE_TASK = "node";
|
||||
|
||||
/// <summary>
|
||||
/// 节点类型:网关开始
|
||||
/// </summary>
|
||||
public const string NODE_TYPE_FORK = "fork";
|
||||
|
||||
/// <summary>
|
||||
/// 节点类型:网关结束
|
||||
/// </summary>
|
||||
public const string NODE_TYPE_JOIN = "join";
|
||||
|
||||
/// <summary>
|
||||
/// 节点类型:多实例、会签节点
|
||||
/// </summary>
|
||||
public const string NODE_TYPE_MULTI_INSTANCE = "multiInstance";
|
||||
|
||||
/// <summary>
|
||||
/// 流程实例知会用户
|
||||
/// </summary>
|
||||
public const string INSTANCE_NOTICE_USER = "INSTANCE_NOTICE_USER";
|
||||
//流程实例知会角色
|
||||
|
||||
/// <summary>
|
||||
/// 流程实例知会角色
|
||||
/// </summary>
|
||||
public const string INSTANCE_NOTICE_ROLE = "INSTANCE_NOTICE_ROLE";
|
||||
|
||||
//表单类型
|
||||
public const int FORM_TYPE_DYNAMIC = 0; //动态表单
|
||||
public const int FORM_TYPE_DEVELOP = 1; //自定义表单
|
||||
public const int FORM_TYPE_DRAG = 2; //vForm拖拽表单
|
||||
public const int FORM_TYPE_URL = 3; //URL表单
|
||||
//流程节点执行权限类型
|
||||
/// <summary>
|
||||
/// 流程节点执行权限类型:所有用户
|
||||
/// </summary>
|
||||
public const string ALL_USER = "ALL_USER";
|
||||
|
||||
/// <summary>
|
||||
/// 流程节点执行权限类型:指定角色
|
||||
/// </summary>
|
||||
public const string SPECIAL_ROLE = "SPECIAL_ROLE";
|
||||
|
||||
/// <summary>
|
||||
/// 流程节点执行权限类型:指定用户
|
||||
/// </summary>
|
||||
public const string SPECIAL_USER = "SPECIAL_USER";
|
||||
|
||||
/// <summary>
|
||||
/// 流程节点执行权限类型:指定SQL
|
||||
/// </summary>
|
||||
public const string SPECIAL_SQL = "SPECIAL_SQL";
|
||||
|
||||
/// <summary>
|
||||
/// 连续多级直属上级
|
||||
/// <para>不同于钉钉的各上级部门负责人审批,OpenAuth以用户的各级直属上级审批模式</para>
|
||||
/// </summary>
|
||||
public const string RUNTIME_MANY_PARENTS = "RUNTIME_MANY_PARENTS";
|
||||
|
||||
/// <summary>
|
||||
/// 部门负责人
|
||||
/// </summary>
|
||||
public const string RUNTIME_CHAIRMAN = "RUNTIME_CHAIRMAN";
|
||||
|
||||
/// <summary>
|
||||
/// 上一节点执行人的直属上级
|
||||
/// </summary>
|
||||
public const string RUNTIME_PARENT = "RUNTIME_PARENT";
|
||||
|
||||
/// <summary>
|
||||
/// 流程节点执行权限类型:运行时指定角色
|
||||
/// </summary>
|
||||
public const string RUNTIME_SPECIAL_ROLE = "RUNTIME_SPECIAL_ROLE";
|
||||
|
||||
/// <summary>
|
||||
/// 流程节点执行权限类型:运行时指定用户
|
||||
/// </summary>
|
||||
public const string RUNTIME_SPECIAL_USER = "RUNTIME_SPECIAL_USER";
|
||||
|
||||
//加签类型
|
||||
/// <summary>
|
||||
/// 加签类型:顺序审批
|
||||
/// </summary>
|
||||
public const string APPROVE_TYPE_SEQUENTIAL = "sequential";
|
||||
|
||||
/// <summary>
|
||||
/// 加签类型:并行且审批(所有人必须同意)
|
||||
/// </summary>
|
||||
public const string APPROVE_TYPE_ALL = "all";
|
||||
|
||||
/// <summary>
|
||||
/// 加签类型:并行或审批(一人同意即可)
|
||||
/// </summary>
|
||||
public const string APPROVE_TYPE_ONE = "one";
|
||||
|
||||
/// <summary>
|
||||
/// API资源标识
|
||||
/// </summary>
|
||||
public const string API = "API_RESOURCE";
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,11 @@
|
||||
|
||||
public string key { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义sql条件
|
||||
/// </summary>
|
||||
public string sqlWhere { get; set; }
|
||||
|
||||
public PageReq()
|
||||
{
|
||||
page = 1;
|
||||
|
||||
@@ -569,6 +569,9 @@ namespace OpenAuth.App
|
||||
{
|
||||
return "DateTime.Now";
|
||||
}
|
||||
else if (type == "bool"){
|
||||
return "false";
|
||||
}
|
||||
return Activator.CreateInstance(t).ToString();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,10 @@ namespace OpenAuth.App
|
||||
{
|
||||
objs = objs.Where(u => u.Name.Contains(request.key));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(request.sqlWhere))
|
||||
{
|
||||
objs = objs.Where(request.sqlWhere);
|
||||
}
|
||||
|
||||
result.data = objs.OrderBy(u => u.Name)
|
||||
.Skip((request.page - 1) * request.limit)
|
||||
|
||||
@@ -5,11 +5,6 @@
|
||||
/// </summary>
|
||||
public class FlowNode
|
||||
{
|
||||
public const string START = "start round mix";
|
||||
public const string END = "end round";
|
||||
public const string NODE = "node";
|
||||
public const string FORK = "fork"; //会签开始节点
|
||||
public const string JOIN = "join"; //会签结束节点
|
||||
|
||||
public string id { get; set; }
|
||||
|
||||
@@ -32,27 +27,7 @@
|
||||
|
||||
public class Setinfo
|
||||
{
|
||||
public const string ALL_USER = "ALL_USER"; //所有用户
|
||||
public const string SPECIAL_ROLE = "SPECIAL_ROLE"; //指定角色
|
||||
public const string SPECIAL_USER = "SPECIAL_USER"; //指定用户
|
||||
public const string SPECIAL_SQL = "SPECIAL_SQL"; //指定SQL
|
||||
/// <summary>
|
||||
/// 连续多级直属上级
|
||||
/// <para>不同于钉钉的各上级部门负责人审批,OpenAuth以用户的各级直属上级审批模式</para>
|
||||
/// </summary>
|
||||
public const string RUNTIME_MANY_PARENTS = "RUNTIME_MANY_PARENTS";
|
||||
/// <summary>
|
||||
/// 部门负责人
|
||||
/// </summary>
|
||||
public const string RUNTIME_CHAIRMAN = "RUNTIME_CHAIRMAN";
|
||||
/// <summary>
|
||||
/// 上一节点执行人的直属上级
|
||||
/// </summary>
|
||||
public const string RUNTIME_PARENT = "RUNTIME_PARENT";
|
||||
|
||||
public const string RUNTIME_SPECIAL_ROLE = "RUNTIME_SPECIAL_ROLE"; //运行时指定角色
|
||||
public const string RUNTIME_SPECIAL_USER = "RUNTIME_SPECIAL_USER"; //运行时指定用户
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 节点执行权限类型
|
||||
/// </summary>
|
||||
@@ -78,18 +53,18 @@
|
||||
public string Description { get; set; }
|
||||
public string TagedTime { get; set; }
|
||||
|
||||
//节点会签方式,
|
||||
//网关审批通过的方式,
|
||||
//all/空:默认为全部通过
|
||||
//one :至少有一个通过
|
||||
public string NodeConfluenceType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 会签通过的个数
|
||||
/// 网关通过的个数
|
||||
/// </summary>
|
||||
public int? ConfluenceOk { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 会签拒绝的个数
|
||||
/// 网关拒绝的个数
|
||||
/// </summary>
|
||||
public int? ConfluenceNo { get; set; }
|
||||
|
||||
|
||||
@@ -33,23 +33,21 @@ namespace OpenAuth.App.Flow
|
||||
InitNodes(schemeContentJson);
|
||||
|
||||
currentNodeId = instance.ActivityId == "" ? startNodeId : instance.ActivityId;
|
||||
currentNodeType = GetNodeType(currentNodeId);
|
||||
FrmData = instance.FrmData;
|
||||
title = schemeContentJson.title;
|
||||
initNum = schemeContentJson.initNum ?? 0;
|
||||
previousId = instance.PreviousId;
|
||||
flowInstanceId = instance.Id;
|
||||
|
||||
//会签开始节点和流程结束节点没有下一步
|
||||
if (currentNodeType == 0 || currentNodeType == 4)
|
||||
//网关开始节点和流程结束节点没有下一步
|
||||
if (GetCurrentNodeType() == Define.NODE_TYPE_FORK
|
||||
|| GetCurrentNodeType() == Define.NODE_TYPE_END)
|
||||
{
|
||||
nextNodeId = "-1";
|
||||
nextNodeType = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextNodeId = GetNextNodeId(); //下一个节点
|
||||
nextNodeType = GetNodeType(nextNodeId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +69,7 @@ namespace OpenAuth.App.Flow
|
||||
Nodes.Add(node.id, node);
|
||||
}
|
||||
|
||||
if (node.type == FlowNode.START)
|
||||
if (node.type == Define.NODE_TYPE_START)
|
||||
{
|
||||
this.startNodeId = node.id;
|
||||
}
|
||||
@@ -120,9 +118,9 @@ namespace OpenAuth.App.Flow
|
||||
{
|
||||
throw new Exception("无法寻找到下一个节点");
|
||||
}
|
||||
|
||||
|
||||
//URL表单暂时不支持URL表单
|
||||
if(flowInstance.FrmType == Define.FORM_TYPE_URL) return lines[0].to;
|
||||
if (flowInstance.FrmType == Define.FORM_TYPE_URL) return lines[0].to;
|
||||
|
||||
if (FrmData == "" || FrmData == "{}") return lines[0].to;
|
||||
|
||||
@@ -144,6 +142,14 @@ namespace OpenAuth.App.Flow
|
||||
|
||||
#region 共有方法
|
||||
|
||||
/// <summary>
|
||||
/// 判断流程是否完成
|
||||
/// </summary>
|
||||
public bool IsFinish()
|
||||
{
|
||||
return GetNextNodeType() == Define.NODE_TYPE_END;
|
||||
}
|
||||
|
||||
//获取下一个节点
|
||||
public FlowNode GetNextNode(string nodeId = null)
|
||||
{
|
||||
@@ -151,64 +157,54 @@ namespace OpenAuth.App.Flow
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取实例接下来运行的状态
|
||||
/// 获取实例接下来运行的节点类型
|
||||
/// </summary>
|
||||
/// <returns>-1无法运行,0会签开始,1会签结束,2一般节点,4流程运行结束</returns>
|
||||
public int GetNextNodeType()
|
||||
public string GetNextNodeType()
|
||||
{
|
||||
if (nextNodeId != "-1")
|
||||
{
|
||||
return GetNodeType(nextNodeId);
|
||||
}
|
||||
|
||||
return -1;
|
||||
return Define.NODE_TYPE_END;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取节点类型 0会签开始,1会签结束,2一般节点,开始节点,4流程运行结束
|
||||
/// 获取节点类型
|
||||
/// </summary>
|
||||
/// <param name="nodeId"></param>
|
||||
/// <returns></returns>
|
||||
public int GetNodeType(string nodeId)
|
||||
public string GetNodeType(string nodeId)
|
||||
{
|
||||
switch (Nodes[nodeId].type)
|
||||
{
|
||||
//会签开始节点
|
||||
case FlowNode.FORK:
|
||||
return 0;
|
||||
//会签结束节点
|
||||
case FlowNode.JOIN:
|
||||
return 1;
|
||||
//结束节点
|
||||
case FlowNode.END:
|
||||
return 4;
|
||||
//开始节点
|
||||
case FlowNode.START:
|
||||
return 3;
|
||||
|
||||
default:
|
||||
return 2;
|
||||
}
|
||||
return Nodes[nodeId].type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 节点会签审核
|
||||
/// 获取当前节点类型
|
||||
/// </summary>
|
||||
/// <param name="nodeId">会签时,currentNodeId是会签开始节点。这个表示当前正在处理的节点</param>
|
||||
/// <returns></returns>
|
||||
public string GetCurrentNodeType()
|
||||
{
|
||||
return GetNodeType(currentNodeId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 审批网关开始节点
|
||||
/// </summary>
|
||||
/// <param name="nodeId">currentNodeId是网关开始节点。这个表示当前正在处理的节点</param>
|
||||
/// <param name="tag"></param>
|
||||
/// <returns>-1不通过,1等待,其它通过</returns>
|
||||
public string NodeConfluence(HttpClient httpClient, Tag tag)
|
||||
public string VerifyGatewayStart(HttpClient httpClient, Tag tag)
|
||||
{
|
||||
var user = AutofacContainerModule.GetService<IAuth>().GetCurrentUser().User;
|
||||
//会签时的【当前节点】一直是会签开始节点
|
||||
//TODO: 标记会签节点的状态,这个地方感觉怪怪的
|
||||
//审批网关时的【当前节点】一直是网关开始节点
|
||||
//TODO: 标记网关节点的状态,这个地方感觉怪怪的
|
||||
MakeTagNode(currentNodeId, tag);
|
||||
|
||||
string canCheckId = ""; //寻找当前登录用户可审核的节点Id
|
||||
foreach (string fromForkStartNodeId in FromNodeLines[currentNodeId]
|
||||
.Select(u => u.to))
|
||||
{
|
||||
var fromForkStartNode = Nodes[fromForkStartNodeId]; //与会前开始节点直接连接的节点
|
||||
var fromForkStartNode = Nodes[fromForkStartNodeId]; //与网关开始节点直接连接的节点
|
||||
canCheckId = GetOneForkLineCanCheckNodeId(fromForkStartNode, tag);
|
||||
if (!string.IsNullOrEmpty(canCheckId)) break;
|
||||
}
|
||||
@@ -225,18 +221,18 @@ namespace OpenAuth.App.Flow
|
||||
|
||||
MakeTagNode(canCheckId, tag); //标记审核节点状态
|
||||
|
||||
var forkNode = Nodes[currentNodeId]; //会签开始节点
|
||||
var forkNode = Nodes[currentNodeId]; //网关开始节点
|
||||
FlowNode nextNode = GetNextNode(canCheckId); //获取当前处理的下一个节点
|
||||
|
||||
int forkNumber = FromNodeLines[currentNodeId].Count; //直接与会签节点连接的点,即会签分支数目
|
||||
string res = string.Empty; //记录会签的结果,默认正在会签
|
||||
int forkNumber = FromNodeLines[currentNodeId].Count; //直接与网关节点连接的点,即网关分支数目
|
||||
string gatewayResult = string.Empty; //记录网关审批的的结果,为空表示仍然在网关内部处理
|
||||
if (forkNode.setInfo.NodeConfluenceType == "one") //有一个步骤通过即可
|
||||
{
|
||||
if (tag.Taged == (int)TagState.Ok)
|
||||
{
|
||||
if (nextNode.type == FlowNode.JOIN) //下一个节点是会签结束,则该线路结束
|
||||
if (nextNode.type == Define.NODE_TYPE_JOIN) //下一个节点是网关结束,则该线路结束
|
||||
{
|
||||
res = GetNextNodeId(nextNode.id);
|
||||
gatewayResult = GetNextNodeId(nextNode.id);
|
||||
}
|
||||
}
|
||||
else if (tag.Taged == (int)TagState.No)
|
||||
@@ -247,13 +243,13 @@ namespace OpenAuth.App.Flow
|
||||
}
|
||||
else if (forkNode.setInfo.ConfluenceNo == (forkNumber - 1))
|
||||
{
|
||||
res = TagState.No.ToString("D");
|
||||
gatewayResult = TagState.No.ToString("D");
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isFirst = true; //是不是从会签开始到现在第一个
|
||||
bool isFirst = true; //是不是从网关开始到现在第一个
|
||||
var preNode = GetPreNode(canCheckId);
|
||||
while (preNode.id != forkNode.id) //反向一直到会签开始节点
|
||||
while (preNode.id != forkNode.id) //反向一直到网关开始节点
|
||||
{
|
||||
if (preNode.setInfo != null && preNode.setInfo.Taged == (int)TagState.No)
|
||||
{
|
||||
@@ -269,23 +265,23 @@ namespace OpenAuth.App.Flow
|
||||
}
|
||||
}
|
||||
}
|
||||
else //默认所有步骤通过
|
||||
else //所有步骤通过
|
||||
{
|
||||
if (tag.Taged == (int)TagState.No) //只要有一个不同意,那么流程就结束
|
||||
{
|
||||
res = TagState.No.ToString("D");
|
||||
gatewayResult = TagState.No.ToString("D");
|
||||
}
|
||||
else if (tag.Taged == (int)TagState.Ok)
|
||||
{
|
||||
if (nextNode.type == FlowNode.JOIN) //这种模式下只有坚持到【会签结束】节点之前才有意义,是否需要判定这条线所有的节点都通过,不然直接执行这个节点??
|
||||
if (nextNode.type == Define.NODE_TYPE_JOIN) //这种模式下只有坚持到【网关结束】节点之前才有意义,是否需要判定这条线所有的节点都通过,不然直接执行这个节点??
|
||||
{
|
||||
if (forkNode.setInfo.ConfluenceOk == null)
|
||||
{
|
||||
forkNode.setInfo.ConfluenceOk = 1;
|
||||
}
|
||||
else if (forkNode.setInfo.ConfluenceOk == (forkNumber - 1)) //会签成功
|
||||
else if (forkNode.setInfo.ConfluenceOk == (forkNumber - 1)) //网关成功
|
||||
{
|
||||
res = GetNextNodeId(nextNode.id);
|
||||
gatewayResult = GetNextNodeId(nextNode.id);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -295,30 +291,28 @@ namespace OpenAuth.App.Flow
|
||||
}
|
||||
}
|
||||
|
||||
if (res == TagState.No.ToString("D"))
|
||||
if (gatewayResult == TagState.No.ToString("D"))
|
||||
{
|
||||
tag.Taged = (int)TagState.No;
|
||||
MakeTagNode(nextNode.id, tag);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(res)) //会签结束,标记合流节点
|
||||
else if (!string.IsNullOrEmpty(gatewayResult)) //网关结束,标记合流节点
|
||||
{
|
||||
tag.Taged = (int)TagState.Ok;
|
||||
MakeTagNode(nextNode.id, tag);
|
||||
nextNodeId = res;
|
||||
nextNodeType = GetNodeType(res);
|
||||
nextNodeId = gatewayResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextNodeId = nextNode.id;
|
||||
nextNodeType = GetNodeType(nextNode.id);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(res)) //会签结束节点配置了回调,则发起通知
|
||||
if (!string.IsNullOrEmpty(gatewayResult)) //网关结束节点配置了回调,则发起通知
|
||||
{
|
||||
NotifyThirdParty(httpClient, nextNode, tag);
|
||||
}
|
||||
|
||||
return res;
|
||||
return gatewayResult;
|
||||
}
|
||||
|
||||
//获取上一个节点
|
||||
@@ -378,7 +372,6 @@ namespace OpenAuth.App.Flow
|
||||
{
|
||||
flowInstance.PreviousId = flowInstance.ActivityId;
|
||||
flowInstance.ActivityId = rejectNode;
|
||||
flowInstance.ActivityType = GetNodeType(rejectNode);
|
||||
flowInstance.ActivityName = Nodes[rejectNode].name;
|
||||
flowInstance.MakerList =
|
||||
GetNodeMarkers(Nodes[rejectNode], flowInstance.CreateUserId);
|
||||
@@ -386,7 +379,7 @@ namespace OpenAuth.App.Flow
|
||||
}
|
||||
|
||||
flowInstance.SchemeContent = JsonHelper.Instance.Serialize(ToSchemeObj());
|
||||
|
||||
|
||||
var sugarClient = AutofacContainerModule.GetService<ISqlSugarClient>();
|
||||
sugarClient.Updateable(flowInstance).ExecuteCommand();
|
||||
|
||||
@@ -405,11 +398,10 @@ namespace OpenAuth.App.Flow
|
||||
{
|
||||
item.Value.setInfo = null;
|
||||
}
|
||||
|
||||
|
||||
flowInstance.IsFinish = FlowInstanceStatus.Draft;
|
||||
flowInstance.PreviousId = flowInstance.ActivityId;
|
||||
flowInstance.ActivityId = startNodeId;
|
||||
flowInstance.ActivityType = GetNodeType(startNodeId);
|
||||
flowInstance.ActivityName = Nodes[startNodeId].name;
|
||||
flowInstance.MakerList = GetNodeMarkers(Nodes[startNodeId], flowInstance.CreateUserId);
|
||||
|
||||
@@ -417,9 +409,9 @@ namespace OpenAuth.App.Flow
|
||||
|
||||
var sugarClient = AutofacContainerModule.GetService<ISqlSugarClient>();
|
||||
sugarClient.Updateable(flowInstance).ExecuteCommand();
|
||||
|
||||
|
||||
SaveOperationHis($"【撤回】备注:{request.Description}");
|
||||
|
||||
|
||||
sugarClient.Ado.CommitTran();
|
||||
}
|
||||
|
||||
@@ -501,11 +493,11 @@ namespace OpenAuth.App.Flow
|
||||
CreateUserName = user.Name,
|
||||
FromNodeId = currentNodeId,
|
||||
FromNodeName = currentNode.name,
|
||||
FromNodeType = currentNodeType,
|
||||
FromNodeType = GetCurrentNodeType(),
|
||||
ToNodeId = nextNodeId,
|
||||
ToNodeName = nextNode?.name,
|
||||
ToNodeType = nextNodeType,
|
||||
IsFinish = nextNodeType == 4 ? FlowInstanceStatus.Finished : FlowInstanceStatus.Running,
|
||||
ToNodeType = GetNextNodeType(),
|
||||
IsFinish = IsFinish() ? FlowInstanceStatus.Finished : FlowInstanceStatus.Running,
|
||||
TransitionSate = 0
|
||||
};
|
||||
|
||||
@@ -533,7 +525,7 @@ namespace OpenAuth.App.Flow
|
||||
result = tag.Taged, //1:通过;2:不通过;3驳回
|
||||
description = tag.Description,
|
||||
execTime = tag.TagedTime,
|
||||
isFinish = node.type == FlowNode.END
|
||||
isFinish = node.type == Define.NODE_TYPE_END
|
||||
};
|
||||
|
||||
var url = node.setInfo.ThirdPartyUrl;
|
||||
@@ -561,14 +553,14 @@ namespace OpenAuth.App.Flow
|
||||
/// </summary>
|
||||
public void UndoVerification()
|
||||
{
|
||||
// 已结束的流程不能撤销
|
||||
if (flowInstance.IsFinish == FlowInstanceStatus.Finished
|
||||
// 已结束的流程不能撤销
|
||||
if (flowInstance.IsFinish == FlowInstanceStatus.Finished
|
||||
|| flowInstance.IsFinish == FlowInstanceStatus.Rejected)
|
||||
{
|
||||
throw new Exception("流程已结束,不能撤销");
|
||||
}
|
||||
|
||||
if(Nodes[previousId].type == FlowNode.START)
|
||||
if (Nodes[previousId].type == Define.NODE_TYPE_START)
|
||||
{
|
||||
throw new Exception("没有任何审批,不能撤销!你可以删除或召回这个流程");
|
||||
}
|
||||
@@ -576,12 +568,11 @@ namespace OpenAuth.App.Flow
|
||||
// 恢复到上一个节点
|
||||
currentNodeId = flowInstance.PreviousId;
|
||||
flowInstance.ActivityId = currentNodeId;
|
||||
flowInstance.ActivityType = GetNodeType(currentNodeId);
|
||||
flowInstance.ActivityName = Nodes[currentNodeId].name;
|
||||
//向前查找ActivityId的前一个结点,即连线指向ActivityId的节点
|
||||
flowInstance.PreviousId = GetPreNode().id;
|
||||
flowInstance.MakerList = GetNodeMarkers(Nodes[currentNodeId]);
|
||||
|
||||
|
||||
// 清除当前节点的审批状态
|
||||
currentNode.setInfo.Taged = null;
|
||||
currentNode.setInfo.UserId = "";
|
||||
@@ -624,11 +615,15 @@ namespace OpenAuth.App.Flow
|
||||
throw new Exception("无法寻找到下一个节点");
|
||||
}
|
||||
|
||||
if (nextNodeType == 0) //如果是会签节点
|
||||
if (GetNextNodeType() == Define.NODE_TYPE_FORK) //如果是网关节点
|
||||
{
|
||||
makerList = GetForkNodeMakers(nextNodeId);
|
||||
}
|
||||
else if (nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_ROLE)
|
||||
else if (GetNextNodeType() == Define.NODE_TYPE_MULTI_INSTANCE) //如果是多实例、会签节点
|
||||
{
|
||||
makerList = GetMultiInstanceNodeMakers(nextNodeId);
|
||||
}
|
||||
else if (nextNode.setInfo.NodeDesignate == Define.RUNTIME_SPECIAL_ROLE)
|
||||
{
|
||||
//如果是运行时指定角色
|
||||
if (nextNode.setInfo.NodeDesignate != request.NodeDesignateType)
|
||||
@@ -640,7 +635,7 @@ namespace OpenAuth.App.Flow
|
||||
var users = revelanceApp.Get(Define.USERROLE, false, request.NodeDesignates);
|
||||
makerList = GenericHelpers.ArrayToString(users, makerList);
|
||||
}
|
||||
else if (nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_USER)
|
||||
else if (nextNode.setInfo.NodeDesignate == Define.RUNTIME_SPECIAL_USER)
|
||||
{
|
||||
//如果是运行时指定用户
|
||||
if (nextNode.setInfo.NodeDesignate != request.NodeDesignateType)
|
||||
@@ -650,7 +645,7 @@ namespace OpenAuth.App.Flow
|
||||
|
||||
makerList = GenericHelpers.ArrayToString(request.NodeDesignates, makerList);
|
||||
}
|
||||
else if (nextNode.setInfo.NodeDesignate == Setinfo.SPECIAL_SQL)
|
||||
else if (nextNode.setInfo.NodeDesignate == Define.SPECIAL_SQL)
|
||||
{
|
||||
//如果是指定SQL
|
||||
if (nextNode.setInfo.NodeDesignate != request.NodeDesignateType)
|
||||
@@ -663,8 +658,8 @@ namespace OpenAuth.App.Flow
|
||||
var result = sugarClient.Ado.SqlQuery<string>(sql);
|
||||
makerList = GenericHelpers.ArrayToString(result, makerList);
|
||||
}
|
||||
else if (nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_PARENT
|
||||
|| nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_MANY_PARENTS)
|
||||
else if (nextNode.setInfo.NodeDesignate == Define.RUNTIME_PARENT
|
||||
|| nextNode.setInfo.NodeDesignate == Define.RUNTIME_MANY_PARENTS)
|
||||
{
|
||||
//如果是上一节点执行人的直属上级或连续多级直属上级
|
||||
if (nextNode.setInfo.NodeDesignate != request.NodeDesignateType)
|
||||
@@ -684,7 +679,7 @@ namespace OpenAuth.App.Flow
|
||||
|
||||
makerList = GenericHelpers.ArrayToString(new[] { parentId }, makerList);
|
||||
}
|
||||
else if (nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_CHAIRMAN)
|
||||
else if (nextNode.setInfo.NodeDesignate == Define.RUNTIME_CHAIRMAN)
|
||||
{
|
||||
//如果是发起人的部门负责人
|
||||
if (nextNode.setInfo.NodeDesignate != request.NodeDesignateType)
|
||||
@@ -708,36 +703,105 @@ namespace OpenAuth.App.Flow
|
||||
return makerList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算多实例、会签节点的执行人
|
||||
/// </summary>
|
||||
/// <param name="nodeId"></param>
|
||||
/// <returns></returns>
|
||||
private string GetMultiInstanceNodeMakers(string nodeId)
|
||||
{
|
||||
if (GetNodeType(nodeId) != Define.NODE_TYPE_MULTI_INSTANCE)
|
||||
{
|
||||
throw new Exception("当前节点不是会签节点,请联系管理员");
|
||||
}
|
||||
|
||||
var node = Nodes[nodeId];
|
||||
string[] makerList = Array.Empty<string>(); // 执行人列表
|
||||
var sugarClient = AutofacContainerModule.GetService<ISqlSugarClient>();
|
||||
|
||||
if (node.setInfo.NodeDesignate == Define.SPECIAL_USER) //指定用户
|
||||
{
|
||||
makerList = node.setInfo.NodeDesignateData.datas;
|
||||
}
|
||||
else if (node.setInfo.NodeDesignate == Define.SPECIAL_ROLE) //指定角色
|
||||
{
|
||||
var revelanceApp = AutofacContainerModule.GetService<RevelanceManagerApp>();
|
||||
makerList = revelanceApp.Get(Define.USERROLE, false, node.setInfo.NodeDesignateData.datas).ToArray();
|
||||
}
|
||||
else if (node.setInfo.NodeDesignate == Define.SPECIAL_SQL) //指定SQL
|
||||
{
|
||||
//如果是指定SQL,则需要执行SQL,并返回结果
|
||||
var sql = ReplaceSql(node.setInfo.NodeDesignateData.datas[0]);
|
||||
|
||||
makerList = sugarClient.Ado.SqlQuery<string>(sql).ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("会签节点,不支持该类型,请重新设计流程模板");
|
||||
}
|
||||
|
||||
//将所有的会签人员写入到FlowApprover,后续审批的时候,按加签的逻辑处理
|
||||
var users = sugarClient.Queryable<SysUser>()
|
||||
.Where(u => makerList.Contains(u.Id))
|
||||
.ToList()
|
||||
.OrderBy(u => Array.IndexOf(makerList, u.Id))
|
||||
.ToList();
|
||||
int order = 1;
|
||||
foreach (var user in users)
|
||||
{
|
||||
var flowApprover = new FlowApprover
|
||||
{
|
||||
InstanceId = flowInstanceId,
|
||||
ActivityId = nodeId,
|
||||
ApproverId = user.Id,
|
||||
ApproverName = user.Name,
|
||||
OrderNo = order++,
|
||||
ApproveType = node.setInfo.NodeConfluenceType,
|
||||
ReturnToSignNode = false,
|
||||
Reason = "",
|
||||
CreateDate = DateTime.Now
|
||||
};
|
||||
sugarClient.Insertable(flowApprover).ExecuteCommand();
|
||||
}
|
||||
//如果是顺序执行,取第一个人
|
||||
if (node.setInfo.NodeConfluenceType == Define.APPROVE_TYPE_SEQUENTIAL)
|
||||
{
|
||||
return makerList[0];
|
||||
}
|
||||
//否则并行且/并行或都是返回所有加签人
|
||||
return GenericHelpers.ArrayToString(makerList, "");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算节点执行人
|
||||
/// 这里专门处理由前端选择相关的节点执行人
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
/// <returns></returns>
|
||||
public string GetNodeMarkers(FlowNode node, string flowinstanceCreateUserId = "")
|
||||
{
|
||||
string makerList = "";
|
||||
if (node.type == FlowNode.START && (!string.IsNullOrEmpty(flowinstanceCreateUserId))) //如果是开始节点,通常情况下是驳回到开始了
|
||||
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 == Setinfo.ALL_USER) //所有成员
|
||||
node.setInfo.NodeDesignate == Define.ALL_USER) //所有成员
|
||||
{
|
||||
makerList = "1";
|
||||
}
|
||||
else if (node.setInfo.NodeDesignate == Setinfo.SPECIAL_USER) //指定成员
|
||||
else if (node.setInfo.NodeDesignate == Define.SPECIAL_USER) //指定成员
|
||||
{
|
||||
makerList = GenericHelpers.ArrayToString(node.setInfo.NodeDesignateData.datas, makerList);
|
||||
}
|
||||
else if (node.setInfo.NodeDesignate == Setinfo.SPECIAL_ROLE) //指定角色
|
||||
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 == Setinfo.SPECIAL_SQL) //指定SQL
|
||||
else if (node.setInfo.NodeDesignate == Define.SPECIAL_SQL) //指定SQL
|
||||
{
|
||||
//如果是指定SQL,则需要执行SQL,并返回结果
|
||||
var sql = ReplaceSql(node.setInfo.NodeDesignateData.datas[0]);
|
||||
@@ -745,8 +809,8 @@ namespace OpenAuth.App.Flow
|
||||
var result = sugarClient.Ado.SqlQuery<string>(sql);
|
||||
makerList = GenericHelpers.ArrayToString(result, makerList);
|
||||
}
|
||||
else if (node.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_ROLE
|
||||
|| node.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_USER)
|
||||
else if (node.setInfo.NodeDesignate == Define.RUNTIME_SPECIAL_ROLE
|
||||
|| node.setInfo.NodeDesignate == Define.RUNTIME_SPECIAL_USER)
|
||||
{
|
||||
//如果是运行时选定的用户,则暂不处理。由上个节点审批时选定
|
||||
}
|
||||
@@ -768,7 +832,8 @@ namespace OpenAuth.App.Flow
|
||||
/// </summary>
|
||||
/// <param name="sql"></param>
|
||||
/// <returns></returns>
|
||||
private string ReplaceSql(string sql){
|
||||
private string ReplaceSql(string sql)
|
||||
{
|
||||
var loginUser = AutofacContainerModule.GetService<IAuth>().GetCurrentUser();
|
||||
var res = sql.Replace(Define.DATAPRIVILEGE_LOGINUSER, $"'{loginUser.User.Id}'");
|
||||
res = res.Replace(Define.DATAPRIVILEGE_LOGINROLE, string.Join(',', loginUser.Roles.Select(u => $"'{u.Id}'")));
|
||||
@@ -777,7 +842,7 @@ namespace OpenAuth.App.Flow
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 会签时,获取一条会签分支上面是否有用户可审核的节点
|
||||
/// 网关时,获取一条网关分支上面是否有用户可审核的节点
|
||||
/// </summary>
|
||||
/// <param name="fromForkStartNode"></param>
|
||||
/// <param name="tag"></param>
|
||||
@@ -786,7 +851,7 @@ namespace OpenAuth.App.Flow
|
||||
{
|
||||
string canCheckId = "";
|
||||
var node = fromForkStartNode;
|
||||
do //沿一条分支线路执行,直到遇到会签结束节点
|
||||
do //沿一条分支线路执行,直到遇到网关结束节点
|
||||
{
|
||||
var makerList = GetNodeMarkers(node);
|
||||
|
||||
@@ -798,22 +863,22 @@ namespace OpenAuth.App.Flow
|
||||
}
|
||||
|
||||
node = GetNextNode(node.id);
|
||||
} while (node.type != FlowNode.JOIN);
|
||||
} while (node.type != Define.NODE_TYPE_JOIN);
|
||||
|
||||
return canCheckId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取会签开始节点的所有可执行者
|
||||
/// 获取网关开始节点的所有可执行者
|
||||
/// </summary>
|
||||
/// <param name="forkNodeId">会签开始节点</param>
|
||||
/// <param name="forkNodeId">网关开始节点</param>
|
||||
/// <returns></returns>
|
||||
public string GetForkNodeMakers(string forkNodeId)
|
||||
{
|
||||
string makerList = "";
|
||||
foreach (string fromForkStartNodeId in FromNodeLines[forkNodeId].Select(u => u.to))
|
||||
{
|
||||
var fromForkStartNode = Nodes[fromForkStartNodeId]; //与会签开始节点直接连接的节点
|
||||
var fromForkStartNode = Nodes[fromForkStartNodeId]; //与网关开始节点直接连接的节点
|
||||
if (makerList != "")
|
||||
{
|
||||
makerList += ",";
|
||||
@@ -826,9 +891,9 @@ namespace OpenAuth.App.Flow
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取会签一条线上的审核者,该审核者应该是已审核过的节点的下一个人
|
||||
/// 获取网关一条线上的审核者,该审核者应该是已审核过的节点的下一个人
|
||||
/// </summary>
|
||||
/// <param name="fromForkStartNode">与会签开始节点直接连接的节点</param>
|
||||
/// <param name="fromForkStartNode">与网关开始节点直接连接的节点</param>
|
||||
private string GetOneForkLineMakers(FlowNode fromForkStartNode)
|
||||
{
|
||||
string markers = "";
|
||||
@@ -837,7 +902,7 @@ namespace OpenAuth.App.Flow
|
||||
{
|
||||
if (node.setInfo != null && node.setInfo.Taged != null)
|
||||
{
|
||||
if (node.type != FlowNode.FORK && node.setInfo.Taged != (int)TagState.Ok) //如果节点是不同意或驳回,则不用再找了
|
||||
if (node.type != Define.NODE_TYPE_FORK && node.setInfo.Taged != (int)TagState.Ok) //如果节点是不同意或驳回,则不用再找了
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -854,7 +919,7 @@ namespace OpenAuth.App.Flow
|
||||
|
||||
if (marker == "1")
|
||||
{
|
||||
throw new Exception($"节点{node.name}是会签节点,不能用所有人,请检查!");
|
||||
throw new Exception($"节点{node.name}是网关节点,不能用所有人,请检查!");
|
||||
}
|
||||
|
||||
if (markers != "")
|
||||
@@ -864,7 +929,7 @@ namespace OpenAuth.App.Flow
|
||||
|
||||
markers += marker;
|
||||
break;
|
||||
} while (node.type != FlowNode.JOIN);
|
||||
} while (node.type != Define.NODE_TYPE_JOIN);
|
||||
|
||||
return markers;
|
||||
}
|
||||
@@ -888,7 +953,7 @@ namespace OpenAuth.App.Flow
|
||||
/// 上一个节点
|
||||
/// </summary>
|
||||
private string previousId { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 实例节点集合
|
||||
/// </summary>
|
||||
@@ -909,11 +974,6 @@ namespace OpenAuth.App.Flow
|
||||
/// </summary>
|
||||
private Dictionary<string, List<FlowLine>> ToNodeLines { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前节点类型 0会签开始,1会签结束,2一般节点,开始节点,4流程运行结束
|
||||
/// </summary>
|
||||
private int currentNodeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 表单数据
|
||||
/// </summary>
|
||||
@@ -939,12 +999,6 @@ namespace OpenAuth.App.Flow
|
||||
/// </summary>
|
||||
public string nextNodeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 下一个节点类型 -1无法运行,0会签开始,1会签结束,2一般节点,4流程运行结束
|
||||
/// </summary>
|
||||
/// <value>The type of the next node.</value>
|
||||
public int nextNodeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 下一个节点对象
|
||||
/// </summary>
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace OpenAuth.App
|
||||
}
|
||||
|
||||
//如果是顺序执行,取第一个人
|
||||
if (query.First().ApproveType == 0)
|
||||
if (query.First().ApproveType == Define.APPROVE_TYPE_SEQUENTIAL)
|
||||
{
|
||||
var result = query.OrderBy(u => u.OrderNo).First();
|
||||
return new[] { result };
|
||||
@@ -138,7 +138,7 @@ namespace OpenAuth.App
|
||||
VerifyDate = DateTime.Now
|
||||
}, u => u.Id == verifyApproverReq.Id);
|
||||
|
||||
if (approve.ApproveType == 2)
|
||||
if (approve.ApproveType == Define.APPROVE_TYPE_ONE)
|
||||
{
|
||||
//如果是并行或,只需要一个审批通过即可
|
||||
return Repository.IsAny(u => u.InstanceId == approve.InstanceId
|
||||
|
||||
@@ -28,9 +28,9 @@ namespace OpenAuth.App.Request
|
||||
|
||||
|
||||
/// <summary>
|
||||
///类型(0顺序,1并行且,2并行或)
|
||||
///类型(sequential顺序,all并行且,one并行或)
|
||||
/// </summary>
|
||||
public int ApproveType { get; set; }
|
||||
public string ApproveType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///父节点ID,应对多次加签
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: yubaolee <yubaolee@163.com> | ahfu~ <954478625@qq.com>
|
||||
* @Date: 2024-12-13 16:55:17
|
||||
* @Description: 工作流实例表操作
|
||||
* @LastEditTime: 2025-04-10 00:02:15
|
||||
* @LastEditTime: 2025-04-21 10:54:45
|
||||
* Copyright (c) 2024 by yubaolee | ahfu~ , All Rights Reserved.
|
||||
*/
|
||||
|
||||
@@ -112,7 +112,6 @@ namespace OpenAuth.App
|
||||
|
||||
#region 根据运行实例改变当前节点状态
|
||||
flowInstance.ActivityId = wfruntime.nextNodeId;
|
||||
flowInstance.ActivityType = wfruntime.GetNextNodeType();
|
||||
flowInstance.ActivityName = wfruntime.nextNode.name;
|
||||
flowInstance.PreviousId = wfruntime.currentNodeId;
|
||||
flowInstance.CreateUserId = user.User.Id;
|
||||
@@ -121,8 +120,8 @@ namespace OpenAuth.App
|
||||
addFlowInstanceReq.CreateUserName = user.User.Account;
|
||||
|
||||
flowInstance.MakerList =
|
||||
wfruntime.GetNextNodeType() != 4 ? wfruntime.GetNextMakers(addFlowInstanceReq) : "";
|
||||
flowInstance.IsFinish = wfruntime.GetNextNodeType() == 4
|
||||
(!wfruntime.IsFinish()) ? wfruntime.GetNextMakers(addFlowInstanceReq) : "";
|
||||
flowInstance.IsFinish = wfruntime.IsFinish()
|
||||
? FlowInstanceStatus.Finished
|
||||
: FlowInstanceStatus.Running;
|
||||
|
||||
@@ -329,9 +328,9 @@ namespace OpenAuth.App
|
||||
|
||||
FlowRuntime wfruntime = new FlowRuntime(flowInstance);
|
||||
|
||||
if (flowInstance.ActivityType == 0) //当前节点是会签节点
|
||||
if (wfruntime.GetCurrentNodeType() == Define.NODE_TYPE_FORK) //当前节点是网关开始节点
|
||||
{
|
||||
CounterSign(wfruntime, tag, flowInstance);
|
||||
VerifyGatewayStart(wfruntime, tag, flowInstance);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -389,33 +388,32 @@ namespace OpenAuth.App
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 会签
|
||||
/// 网关
|
||||
/// </summary>
|
||||
private void CounterSign(FlowRuntime wfruntime, Tag tag, FlowInstance flowInstance)
|
||||
private void VerifyGatewayStart(FlowRuntime wfruntime, Tag tag, FlowInstance flowInstance)
|
||||
{
|
||||
string res = wfruntime.NodeConfluence(_httpClientFactory.CreateClient(), tag);
|
||||
string res = wfruntime.VerifyGatewayStart(_httpClientFactory.CreateClient(), tag);
|
||||
|
||||
if (res == TagState.No.ToString("D"))
|
||||
{
|
||||
flowInstance.IsFinish = FlowInstanceStatus.Disagree;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(res)) //会签结束,当前活动节点变为会签结束节点的下一个节点
|
||||
else if (!string.IsNullOrEmpty(res)) //网关结束,当前活动节点变为网关结束节点的下一个节点
|
||||
{
|
||||
flowInstance.PreviousId = flowInstance.ActivityId;
|
||||
flowInstance.ActivityId = wfruntime.nextNodeId;
|
||||
flowInstance.ActivityType = wfruntime.nextNodeType;
|
||||
flowInstance.ActivityName = wfruntime.nextNode.name;
|
||||
flowInstance.IsFinish = wfruntime.nextNodeType == 4
|
||||
flowInstance.IsFinish = wfruntime.IsFinish()
|
||||
? FlowInstanceStatus.Finished
|
||||
: FlowInstanceStatus.Running;
|
||||
flowInstance.MakerList =
|
||||
wfruntime.nextNodeType == 4 ? "" : wfruntime.GetNextMakers();
|
||||
wfruntime.IsFinish() ? "" : wfruntime.GetNextMakers();
|
||||
|
||||
wfruntime.SaveTransitionHis();
|
||||
}
|
||||
else
|
||||
{
|
||||
//会签过程中,需要更新用户
|
||||
//网关过程中,需要更新用户
|
||||
flowInstance.MakerList = wfruntime.GetForkNodeMakers(wfruntime.currentNodeId);
|
||||
wfruntime.SaveTransitionHis();
|
||||
}
|
||||
@@ -462,6 +460,11 @@ namespace OpenAuth.App
|
||||
if (!isfinish) //如果没有完成,不能到下一步
|
||||
{
|
||||
canNext = false;
|
||||
flowInstance.MakerList = GenericHelpers.ArrayToString(_flowApproverApp.GetApproverIds(new QueryApproverReq()
|
||||
{
|
||||
FlowInstanceId = flowInstance.Id,
|
||||
ActivityId = flowInstance.ActivityId
|
||||
}), "");
|
||||
}
|
||||
else if (approverInfo.ReturnToSignNode == null || !approverInfo.ReturnToSignNode.Value)
|
||||
{
|
||||
@@ -477,7 +480,7 @@ namespace OpenAuth.App
|
||||
}
|
||||
}
|
||||
|
||||
if (wfruntime.currentNode.setInfo.NodeDesignate == Setinfo.RUNTIME_MANY_PARENTS)
|
||||
if (wfruntime.currentNode.setInfo.NodeDesignate == Define.RUNTIME_MANY_PARENTS)
|
||||
{
|
||||
List<string> roles;
|
||||
if (user.Id != tag.UserId)
|
||||
@@ -503,10 +506,9 @@ namespace OpenAuth.App
|
||||
{
|
||||
flowInstance.PreviousId = flowInstance.ActivityId;
|
||||
flowInstance.ActivityId = wfruntime.nextNodeId;
|
||||
flowInstance.ActivityType = wfruntime.nextNodeType;
|
||||
flowInstance.ActivityName = wfruntime.nextNode.name;
|
||||
flowInstance.MakerList = wfruntime.nextNodeType == 4 ? "" : wfruntime.GetNextMakers(request);
|
||||
flowInstance.IsFinish = wfruntime.nextNodeType == 4
|
||||
flowInstance.MakerList = wfruntime.IsFinish() ? "" : wfruntime.GetNextMakers(request);
|
||||
flowInstance.IsFinish = wfruntime.IsFinish()
|
||||
? FlowInstanceStatus.Finished
|
||||
: FlowInstanceStatus.Running;
|
||||
}
|
||||
@@ -515,7 +517,6 @@ namespace OpenAuth.App
|
||||
{
|
||||
flowInstance.IsFinish = FlowInstanceStatus.Disagree;
|
||||
wfruntime.nextNodeId = "-1";
|
||||
wfruntime.nextNodeType = 4;
|
||||
}
|
||||
|
||||
var content =
|
||||
@@ -619,8 +620,8 @@ namespace OpenAuth.App
|
||||
/// <exception cref="Exception"></exception>
|
||||
private void CheckNodeDesignate(NodeDesignateReq request)
|
||||
{
|
||||
if ((request.NodeDesignateType == Setinfo.RUNTIME_SPECIAL_ROLE
|
||||
|| request.NodeDesignateType == Setinfo.RUNTIME_SPECIAL_USER) && request.NodeDesignates.Length == 0)
|
||||
if ((request.NodeDesignateType == Define.RUNTIME_SPECIAL_ROLE
|
||||
|| request.NodeDesignateType == Define.RUNTIME_SPECIAL_USER) && request.NodeDesignates.Length == 0)
|
||||
{
|
||||
throw new Exception("下个节点需要选择执行人或执行角色");
|
||||
}
|
||||
@@ -641,7 +642,7 @@ namespace OpenAuth.App
|
||||
resp.CanWriteFormItemIds = runtime.currentNode.setInfo.CanWriteFormItemIds;
|
||||
}
|
||||
|
||||
if (runtime.nextNode != null && runtime.nextNode.setInfo != null && runtime.nextNodeType != 4)
|
||||
if (runtime.nextNode != null && runtime.nextNode.setInfo != null && runtime.GetNextNodeType() != Define.NODE_TYPE_END)
|
||||
{
|
||||
resp.NextNodeDesignateType = runtime.nextNode.setInfo.NodeDesignate;
|
||||
resp.CanWriteFormItemIds = runtime.currentNode.setInfo.CanWriteFormItemIds;
|
||||
@@ -695,22 +696,22 @@ namespace OpenAuth.App
|
||||
else if (SugarClient.CurrentConnectionConfig.DbType == DbType.Oracle)
|
||||
{
|
||||
groupConcatSql = $@" (select listagg(Account, ',') within group (order by Account)
|
||||
from SysUser
|
||||
where fi.MakerList like '%' || Id || '%') ";
|
||||
from SysUser
|
||||
where fi.MakerList like '%' || Id || '%') ";
|
||||
}
|
||||
else if (SugarClient.CurrentConnectionConfig.DbType == DbType.PostgreSQL)
|
||||
{
|
||||
groupConcatSql = $@" (select string_agg(Account, ',')
|
||||
from SysUser
|
||||
where fi.MakerList like '%' || Id || '%') ";
|
||||
from SysUser
|
||||
where fi.MakerList like '%' || Id || '%') ";
|
||||
}
|
||||
|
||||
string sql = String.Empty;
|
||||
|
||||
if (request.type == "wait") //待办事项(即需要我处理的流程)
|
||||
{
|
||||
sql = $@"
|
||||
SELECT fi.Id,
|
||||
sql =$@"
|
||||
SELECT fi.Id,
|
||||
fi.CreateUserName,
|
||||
fi.ActivityName,
|
||||
fi.CreateDate,
|
||||
@@ -721,24 +722,38 @@ namespace OpenAuth.App
|
||||
CASE
|
||||
WHEN fi.MakerList = '1' THEN '所有人'
|
||||
WHEN fi.MakerList = '00000000-0000-0000-0000-000000000000' THEN 'System'
|
||||
ELSE {groupConcatSql}
|
||||
ELSE {groupConcatSql}
|
||||
END AS MakerList
|
||||
FROM FlowInstance fi
|
||||
JOIN (SELECT fith.Id
|
||||
FROM FlowInstance fith
|
||||
WHERE (MakerList = '1' or MakerList LIKE '%{user.User.Id}%')
|
||||
and (fith.IsFinish = {FlowInstanceStatus.Running} or fith.IsFinish = {FlowInstanceStatus.Rejected})
|
||||
and not exists (select 1
|
||||
from flowapprover
|
||||
where fith.Id = InstanceId
|
||||
and fith.ActivityId = ActivityId
|
||||
and Status = 0)
|
||||
UNION
|
||||
SELECT fa.InstanceId
|
||||
FROM FlowApprover fa
|
||||
WHERE fa.Status = 0
|
||||
AND fa.ApproverId = '{user.User.Id}') UniqueInstanceIds
|
||||
ON fi.Id = UniqueInstanceIds.Id";
|
||||
FROM FlowInstance fith
|
||||
WHERE (MakerList = '1' or MakerList LIKE '%{user.User.Id}%')
|
||||
and (fith.IsFinish = {FlowInstanceStatus.Running} or fith.IsFinish = {FlowInstanceStatus.Rejected})
|
||||
and not exists (select 1
|
||||
from flowapprover
|
||||
where fith.Id = InstanceId
|
||||
and fith.ActivityId = ActivityId
|
||||
and Status = 0)
|
||||
union
|
||||
select fa.instanceid
|
||||
from flowapprover fa
|
||||
where fa.status = 0
|
||||
and fa.approverid = '{user.User.Id}'
|
||||
and fa.approvetype <> '{Define.APPROVE_TYPE_SEQUENTIAL}'
|
||||
union
|
||||
select fa.instanceid
|
||||
from flowapprover fa
|
||||
where not exists (select 1
|
||||
from flowapprover fa2
|
||||
where fa2.instanceid = fa.instanceid
|
||||
and fa2.orderno < fa.orderno
|
||||
and fa2.status = 0
|
||||
and fa2.approvetype = '{Define.APPROVE_TYPE_SEQUENTIAL}')
|
||||
and fa.status = 0
|
||||
and fa.approverid = '{user.User.Id}'
|
||||
and fa.approvetype = '{Define.APPROVE_TYPE_SEQUENTIAL}') UniqueInstanceIds
|
||||
ON fi.Id = UniqueInstanceIds.Id
|
||||
";
|
||||
}
|
||||
else if (request.type == "disposed") //已办事项(即我参与过的流程)
|
||||
{
|
||||
@@ -757,15 +772,15 @@ namespace OpenAuth.App
|
||||
ELSE {groupConcatSql}
|
||||
END AS MakerList
|
||||
FROM FlowInstance fi
|
||||
JOIN (SELECT fith.InstanceId
|
||||
FROM FlowInstanceOperationHistory fith
|
||||
WHERE fith.CreateUserId = '{user.User.Id}'
|
||||
UNION
|
||||
SELECT fa.InstanceId
|
||||
FROM FlowApprover fa
|
||||
WHERE fa.Status <> 0
|
||||
AND fa.ApproverId = '{user.User.Id}') UniqueInstanceIds
|
||||
ON fi.Id = UniqueInstanceIds.InstanceId
|
||||
JOIN (SELECT fith.InstanceId
|
||||
FROM FlowInstanceOperationHistory fith
|
||||
WHERE fith.CreateUserId = '{user.User.Id}'
|
||||
UNION
|
||||
SELECT fa.InstanceId
|
||||
FROM FlowApprover fa
|
||||
WHERE fa.Status <> 0
|
||||
AND fa.ApproverId = '{user.User.Id}') UniqueInstanceIds
|
||||
ON fi.Id = UniqueInstanceIds.InstanceId
|
||||
";
|
||||
}
|
||||
else //我的流程(我创建的及知会我的)
|
||||
@@ -785,25 +800,25 @@ namespace OpenAuth.App
|
||||
ELSE {groupConcatSql}
|
||||
END AS MakerList
|
||||
FROM FlowInstance fi
|
||||
JOIN (select Id as InstanceId
|
||||
JOIN (select Id as InstanceId
|
||||
from FlowInstance
|
||||
where CreateUserId = '{user.User.Id}'
|
||||
union
|
||||
select distinct FirstId as InstanceId
|
||||
from Relevance rel
|
||||
inner join FlowInstance flow on rel.FirstId = flow.Id and flow.IsFinish = 1
|
||||
inner join FlowInstance flow on rel.FirstId = flow.Id and flow.IsFinish = 1
|
||||
where RelKey = '{Define.INSTANCE_NOTICE_USER}'
|
||||
and SecondId = '{user.User.Id}'
|
||||
and SecondId = '{user.User.Id}'
|
||||
union
|
||||
select distinct a.FirstId as InstanceId
|
||||
from Relevance a
|
||||
inner join (select SecondId as RoleId
|
||||
from Relevance
|
||||
where RelKey = 'UserRole'
|
||||
and FirstId = '{user.User.Id}') b on a.SecondId = b.RoleId
|
||||
inner join FlowInstance flow on a.FirstId = flow.Id and flow.IsFinish = 1
|
||||
inner join (select SecondId as RoleId
|
||||
from Relevance
|
||||
where RelKey = 'UserRole'
|
||||
and FirstId = '{user.User.Id}') b on a.SecondId = b.RoleId
|
||||
inner join FlowInstance flow on a.FirstId = flow.Id and flow.IsFinish = 1
|
||||
where a.RelKey = '{Define.INSTANCE_NOTICE_ROLE}') UniqueInstanceIds
|
||||
ON fi.Id = UniqueInstanceIds.InstanceId
|
||||
ON fi.Id = UniqueInstanceIds.InstanceId
|
||||
";
|
||||
}
|
||||
|
||||
@@ -860,8 +875,8 @@ namespace OpenAuth.App
|
||||
var wfruntime = new FlowRuntime(flowInstance);
|
||||
var user = _auth.GetCurrentUser();
|
||||
|
||||
if (wfruntime.nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_USER
|
||||
|| wfruntime.nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_ROLE)
|
||||
if (wfruntime.nextNode.setInfo.NodeDesignate == Define.RUNTIME_SPECIAL_USER
|
||||
|| wfruntime.nextNode.setInfo.NodeDesignate == Define.RUNTIME_SPECIAL_ROLE)
|
||||
{
|
||||
throw new Exception("暂不支持【第二执行节点为运行时指定角色/账号执行】的流程恢复");
|
||||
}
|
||||
@@ -869,13 +884,12 @@ namespace OpenAuth.App
|
||||
#region 根据运行实例改变当前节点状态
|
||||
|
||||
flowInstance.ActivityId = wfruntime.nextNodeId;
|
||||
flowInstance.ActivityType = wfruntime.GetNextNodeType();
|
||||
flowInstance.ActivityName = wfruntime.nextNode.name;
|
||||
flowInstance.PreviousId = wfruntime.currentNodeId;
|
||||
flowInstance.CreateUserId = user.User.Id;
|
||||
flowInstance.CreateUserName = user.User.Account;
|
||||
flowInstance.MakerList = wfruntime.GetNextNodeType() != 4 ? wfruntime.GetNextMakers() : "";
|
||||
flowInstance.IsFinish = wfruntime.GetNextNodeType() == 4
|
||||
flowInstance.MakerList = (!wfruntime.IsFinish()) ? wfruntime.GetNextMakers() : "";
|
||||
flowInstance.IsFinish = wfruntime.IsFinish()
|
||||
? FlowInstanceStatus.Finished
|
||||
: FlowInstanceStatus.Running;
|
||||
|
||||
|
||||
@@ -2,22 +2,17 @@
|
||||
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 WmsInboundOrderDtblApp : BaseStringApp<WmsInboundOrderDtbl,OpenAuthDBContext>
|
||||
public class WmsInboundOrderDtblApp : SqlSugarBaseApp<WmsInboundOrderDtbl>
|
||||
{
|
||||
private RevelanceManagerApp _revelanceApp;
|
||||
private DbExtension _dbExtension;
|
||||
|
||||
/// <summary>
|
||||
/// 加载列表
|
||||
/// </summary>
|
||||
@@ -29,19 +24,19 @@ namespace OpenAuth.App
|
||||
{
|
||||
throw new CommonException("登录已过期", Define.INVALID_TOKEN);
|
||||
}
|
||||
|
||||
|
||||
var properties = loginContext.GetTableColumns("WmsInboundOrderDtbl");
|
||||
if (properties == null || properties.Count == 0)
|
||||
{
|
||||
throw new Exception("请在代码生成界面配置WmsInboundOrderDtbl表的字段属性");
|
||||
}
|
||||
var result = new TableData();
|
||||
var objs = UnitWork.Find<WmsInboundOrderDtbl>(null);
|
||||
var objs = SugarClient.Queryable<WmsInboundOrderDtbl>();
|
||||
if (!string.IsNullOrEmpty(request.InboundOrderId))
|
||||
{
|
||||
objs = objs.Where(u => u.OrderId == request.InboundOrderId);
|
||||
}
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(request.key))
|
||||
{
|
||||
objs = objs.Where(u => u.GoodsId.Contains(request.key));
|
||||
@@ -51,32 +46,34 @@ namespace OpenAuth.App
|
||||
result.columnFields = properties;
|
||||
result.data = objs.OrderBy(u => u.Id)
|
||||
.Skip((request.page - 1) * request.limit)
|
||||
.Take(request.limit).Select($"new ({propertyStr})");
|
||||
.Take(request.limit).Select($"{propertyStr}").ToList();
|
||||
result.count = await objs.CountAsync();
|
||||
return result;
|
||||
}
|
||||
|
||||
public void Add(AddOrUpdateWmsInboundOrderDtblReq req)
|
||||
{
|
||||
SugarClient.Ado.BeginTran();
|
||||
AddNoSave(req);
|
||||
UnitWork.Save();
|
||||
SugarClient.Ado.CommitTran();
|
||||
}
|
||||
|
||||
|
||||
public void AddNoSave(AddOrUpdateWmsInboundOrderDtblReq req)
|
||||
{
|
||||
var obj = req.MapTo<WmsInboundOrderDtbl>();
|
||||
//todo:补充或调整自己需要的字段
|
||||
obj.CreateTime = DateTime.Now;
|
||||
var user = _auth.GetCurrentUser().User;
|
||||
obj.GenerateDefaultKeyVal();
|
||||
obj.CreateUserId = user.Id;
|
||||
obj.CreateUserName = user.Name;
|
||||
UnitWork.Add(obj);
|
||||
SugarClient.Insertable(obj).ExecuteCommand();
|
||||
}
|
||||
|
||||
public void Update(AddOrUpdateWmsInboundOrderDtblReq obj)
|
||||
public void Update(AddOrUpdateWmsInboundOrderDtblReq obj)
|
||||
{
|
||||
var user = _auth.GetCurrentUser().User;
|
||||
UnitWork.Update<WmsInboundOrderDtbl>(u => u.Id == obj.Id, u => new WmsInboundOrderDtbl
|
||||
Repository.Update(u => new WmsInboundOrderDtbl
|
||||
{
|
||||
Price = obj.Price,
|
||||
PriceNoTax = obj.PriceNoTax,
|
||||
@@ -98,15 +95,12 @@ namespace OpenAuth.App
|
||||
UpdateUserId = user.Id,
|
||||
UpdateUserName = user.Name
|
||||
//todo:补充或调整自己需要的字段
|
||||
});
|
||||
}, u => u.Id == obj.Id);
|
||||
|
||||
}
|
||||
|
||||
public WmsInboundOrderDtblApp(IUnitWork<OpenAuthDBContext> unitWork, IRepository<WmsInboundOrderDtbl,OpenAuthDBContext> repository,
|
||||
RevelanceManagerApp app, IAuth auth, DbExtension dbExtension) : base(unitWork, repository,auth)
|
||||
public WmsInboundOrderDtblApp(ISqlSugarClient client, IAuth auth) : base(client, auth)
|
||||
{
|
||||
_dbExtension = dbExtension;
|
||||
_revelanceApp = app;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,20 +2,17 @@
|
||||
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 WmsInboundOrderTblApp : BaseStringApp<WmsInboundOrderTbl,OpenAuthDBContext>
|
||||
public class WmsInboundOrderTblApp : SqlSugarBaseApp<WmsInboundOrderTbl>
|
||||
{
|
||||
private RevelanceManagerApp _revelanceApp;
|
||||
private WmsInboundOrderDtblApp _wmsInboundOrderDtblApp;
|
||||
|
||||
/// <summary>
|
||||
@@ -29,26 +26,32 @@ namespace OpenAuth.App
|
||||
throw new CommonException("登录已过期", Define.INVALID_TOKEN);
|
||||
}
|
||||
|
||||
|
||||
|
||||
var columns = loginContext.GetTableColumns("WmsInboundOrderTbl");
|
||||
if (columns == null || columns.Count == 0)
|
||||
{
|
||||
throw new Exception("请在代码生成界面配置WmsInboundOrderTbl表的字段属性");
|
||||
}
|
||||
|
||||
|
||||
var result = new TableData();
|
||||
|
||||
|
||||
result.columnFields = columns;
|
||||
|
||||
|
||||
var objs = GetDataPrivilege("u");
|
||||
if (!string.IsNullOrEmpty(request.key))
|
||||
{
|
||||
objs = objs.Where(u => u.Id.Contains(request.key));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(request.sqlWhere))
|
||||
{
|
||||
objs = objs.Where(request.sqlWhere);
|
||||
}
|
||||
|
||||
var propertyStr = string.Join(',', columns.Select(u => u.ColumnName));
|
||||
result.data = objs.OrderBy(u => u.Id)
|
||||
.Skip((request.page - 1) * request.limit)
|
||||
.Take(request.limit).Select($"new ({propertyStr})");
|
||||
.Take(request.limit).Select($"{propertyStr}").ToList();
|
||||
result.count = await objs.CountAsync();
|
||||
return result;
|
||||
}
|
||||
@@ -61,7 +64,8 @@ namespace OpenAuth.App
|
||||
var user = _auth.GetCurrentUser().User;
|
||||
obj.CreateUserId = user.Id;
|
||||
obj.CreateUserName = user.Name;
|
||||
UnitWork.Add(obj);
|
||||
SugarClient.Ado.BeginTran();
|
||||
SugarClient.Insertable(obj).ExecuteCommand();
|
||||
if (req.WmsInboundOrderDtblReqs != null && req.WmsInboundOrderDtblReqs.Any())
|
||||
{
|
||||
foreach (var detail in req.WmsInboundOrderDtblReqs)
|
||||
@@ -71,72 +75,71 @@ namespace OpenAuth.App
|
||||
}
|
||||
}
|
||||
|
||||
UnitWork.Save();
|
||||
SugarClient.Ado.CommitTran();
|
||||
}
|
||||
|
||||
public void Update(AddOrUpdateWmsInboundOrderTblReq obj)
|
||||
{
|
||||
var user = _auth.GetCurrentUser().User;
|
||||
|
||||
UnitWork.ExecuteWithTransaction(() =>
|
||||
SugarClient.Ado.BeginTran();
|
||||
|
||||
|
||||
if (obj.WmsInboundOrderDtblReqs != null && obj.WmsInboundOrderDtblReqs.Any())
|
||||
{
|
||||
if (obj.WmsInboundOrderDtblReqs != null && obj.WmsInboundOrderDtblReqs.Any())
|
||||
//id为空的添加
|
||||
foreach (var detail in obj.WmsInboundOrderDtblReqs.Where(u => string.IsNullOrEmpty(u.Id)))
|
||||
{
|
||||
//id为空的添加
|
||||
foreach (var detail in obj.WmsInboundOrderDtblReqs.Where(u => string.IsNullOrEmpty(u.Id)))
|
||||
{
|
||||
detail.OrderId = obj.Id;
|
||||
_wmsInboundOrderDtblApp.AddNoSave(detail);
|
||||
}
|
||||
|
||||
//id比数据库少的,删除
|
||||
var containids = obj.WmsInboundOrderDtblReqs.Select(u => u.Id)
|
||||
.Where(u => !string.IsNullOrEmpty(u)).ToList();
|
||||
if (containids.Any())
|
||||
{
|
||||
UnitWork.Delete<WmsInboundOrderDtbl>(u => (!containids.Contains(u.Id)) && u.OrderId == obj.Id);
|
||||
}
|
||||
|
||||
//更新id相同的
|
||||
foreach (var detail in obj.WmsInboundOrderDtblReqs.Where(u => !string.IsNullOrEmpty(u.Id)))
|
||||
{
|
||||
_wmsInboundOrderDtblApp.Update(detail);
|
||||
}
|
||||
detail.OrderId = obj.Id;
|
||||
_wmsInboundOrderDtblApp.AddNoSave(detail);
|
||||
}
|
||||
|
||||
UnitWork.Update<WmsInboundOrderTbl>(u => u.Id == obj.Id, u => new WmsInboundOrderTbl
|
||||
//id比数据库少的,删除
|
||||
var containids = obj.WmsInboundOrderDtblReqs.Select(u => u.Id)
|
||||
.Where(u => !string.IsNullOrEmpty(u)).ToList();
|
||||
if (containids.Any())
|
||||
{
|
||||
ExternalNo = obj.ExternalNo,
|
||||
ExternalType = obj.ExternalType,
|
||||
Status = obj.Status,
|
||||
OrderType = obj.OrderType,
|
||||
GoodsType = obj.GoodsType,
|
||||
PurchaseNo = obj.PurchaseNo,
|
||||
StockId = obj.StockId,
|
||||
OwnerId = obj.OwnerId,
|
||||
ShipperId = obj.ShipperId,
|
||||
SupplierId = obj.SupplierId,
|
||||
ScheduledInboundTime = obj.ScheduledInboundTime,
|
||||
Remark = obj.Remark,
|
||||
Enable = obj.Enable,
|
||||
TransferType = obj.TransferType,
|
||||
InBondedArea = obj.InBondedArea,
|
||||
ReturnBoxNum = obj.ReturnBoxNum,
|
||||
UpdateTime = DateTime.Now,
|
||||
UpdateUserId = user.Id,
|
||||
UpdateUserName = user.Name
|
||||
//todo:补充或调整自己需要的字段
|
||||
});
|
||||
SugarClient.Deleteable<WmsInboundOrderDtbl>(u => (!containids.Contains(u.Id)) && u.OrderId == obj.Id).ExecuteCommand();
|
||||
}
|
||||
|
||||
//更新id相同的
|
||||
foreach (var detail in obj.WmsInboundOrderDtblReqs.Where(u => !string.IsNullOrEmpty(u.Id)))
|
||||
{
|
||||
_wmsInboundOrderDtblApp.Update(detail);
|
||||
}
|
||||
}
|
||||
|
||||
Repository.Update(u => new WmsInboundOrderTbl
|
||||
{
|
||||
ExternalNo = obj.ExternalNo,
|
||||
ExternalType = obj.ExternalType,
|
||||
Status = obj.Status,
|
||||
OrderType = obj.OrderType,
|
||||
GoodsType = obj.GoodsType,
|
||||
PurchaseNo = obj.PurchaseNo,
|
||||
StockId = obj.StockId,
|
||||
OwnerId = obj.OwnerId,
|
||||
ShipperId = obj.ShipperId,
|
||||
SupplierId = obj.SupplierId,
|
||||
ScheduledInboundTime = obj.ScheduledInboundTime,
|
||||
Remark = obj.Remark,
|
||||
Enable = obj.Enable,
|
||||
TransferType = obj.TransferType,
|
||||
InBondedArea = obj.InBondedArea,
|
||||
ReturnBoxNum = obj.ReturnBoxNum,
|
||||
UpdateTime = DateTime.Now,
|
||||
UpdateUserId = user.Id,
|
||||
UpdateUserName = user.Name
|
||||
//todo:补充或调整自己需要的字段
|
||||
}, u => u.Id == obj.Id);
|
||||
|
||||
SugarClient.Ado.CommitTran();
|
||||
|
||||
UnitWork.Save();
|
||||
});
|
||||
}
|
||||
|
||||
public WmsInboundOrderTblApp(IUnitWork<OpenAuthDBContext> unitWork, IRepository<WmsInboundOrderTbl,OpenAuthDBContext> repository,
|
||||
RevelanceManagerApp app, IAuth auth, WmsInboundOrderDtblApp wmsInboundOrderDtblApp) : base(unitWork,
|
||||
repository, auth)
|
||||
public WmsInboundOrderTblApp(ISqlSugarClient client, IAuth auth,
|
||||
WmsInboundOrderDtblApp wmsInboundOrderDtblApp) : base(client, auth)
|
||||
{
|
||||
_revelanceApp = app;
|
||||
_wmsInboundOrderDtblApp = wmsInboundOrderDtblApp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
},
|
||||
"AppSetting": {
|
||||
"DbTypes": {
|
||||
"OpenAuthDBContext":"MySql" //数据库类型:SqlServer、MySql、Oracle
|
||||
"OpenAuthDBContext":"MySql" //数据库类型:SqlServer、MySql、Oracle、PostgreSql
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,11 +7,10 @@
|
||||
"AllowedHosts": "*",
|
||||
"ConnectionStrings": {
|
||||
"OpenAuthDBContext": "Data Source=.;Encrypt=false;Initial Catalog=OpenAuthDB;User=sa;Password=000000"
|
||||
//"OpenAuthDBContext": "server=127.0.0.1;user id=root;database=openauthdb;password=000000" //my sql
|
||||
},
|
||||
"AppSetting": {
|
||||
"DbTypes": {
|
||||
"OpenAuthDBContext":"SqlServer" //数据库类型:SqlServer、MySql、Oracle
|
||||
"OpenAuthDBContext":"SqlServer" //数据库类型:SqlServer、MySql、Oracle、PostgreSql
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
<None Include="wwwroot\css\metroStyle\img\metro.gif" />
|
||||
<None Include="wwwroot\css\metroStyle\img\metro.png" />
|
||||
<None Include="wwwroot\css\metroStyle\metroStyle.css" />
|
||||
<None Include="wwwroot\css\treetable.css" />
|
||||
<None Include="wwwroot\images\alipay.jpg" />
|
||||
<None Include="wwwroot\images\code.jpg" />
|
||||
<None Include="wwwroot\images\face.jpg" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css"/>
|
||||
|
||||
}
|
||||
|
||||
<blockquote class="layui-elem-quote news_search toolList" id="menus">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
<link href="/js/flow/GooFlow.css" rel="stylesheet" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
<link href="/js/flow/GooFlow.css" rel="stylesheet" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
}
|
||||
|
||||
@@ -1,17 +1,52 @@
|
||||
|
||||
@section header
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
<link href="/js/flow/GooFlow.css" rel="stylesheet" />
|
||||
<link href="/css/formpreview.css" rel="stylesheet" />
|
||||
|
||||
<!-- 添加自定义样式覆盖main.css中的冲突样式 -->
|
||||
<style>
|
||||
.verification-flex-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 600px;
|
||||
}
|
||||
|
||||
.verification-left-panel {
|
||||
flex: 8;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.verification-right-panel {
|
||||
flex: 4;
|
||||
background-color: gainsboro;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
/* 覆盖main.css中的绝对定位样式 */
|
||||
.verification-tab .layui-tab-item {
|
||||
position: relative !important;
|
||||
top: auto !important;
|
||||
bottom: auto !important;
|
||||
left: auto !important;
|
||||
right: auto !important;
|
||||
min-height: 500px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.verification-tab .layui-tab-content {
|
||||
min-height: 500px;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
}
|
||||
|
||||
<form class="layui-form " action="" id="formEdit">
|
||||
<div class="layui-row ">
|
||||
<div class="layui-col-xs8">
|
||||
<div class="layui-tab layui-tab-brief" lay-filter="tab" style="margin: 0px">
|
||||
<div class="verification-flex-container">
|
||||
<div class="verification-left-panel">
|
||||
<div class="layui-tab layui-tab-brief verification-tab" lay-filter="tab" style="margin: 0px">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">流程信息</li>
|
||||
<li>表单信息</li>
|
||||
@@ -19,18 +54,22 @@
|
||||
|
||||
<div class="layui-tab-content">
|
||||
<div class="layui-tab-item layui-show">
|
||||
<div id="flowPanel"></div>
|
||||
<div id="flowPanel">
|
||||
<!-- 测试内容 -->
|
||||
<p>流程内容应该显示在这里</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-tab-item">
|
||||
<div id="frmPreview"></div>
|
||||
<div id="frmPreview">
|
||||
<!-- 测试内容 -->
|
||||
<p>表单内容应该显示在这里</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="layui-col-xs4" style="background-color: gainsboro; min-height: 600px">
|
||||
<div class="verification-right-panel">
|
||||
<input type="hidden" id="FlowInstanceId" name="FlowInstanceId"/>
|
||||
|
||||
<div class="layui-form-item">
|
||||
@@ -50,7 +89,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" lay-submit id="btnSubmit" lay-filter="formSubmit"/>
|
||||
</form>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
<link href="/js/flow/GooFlow.css" rel="stylesheet" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
<link href="/js/flow/GooFlow.css" rel="stylesheet" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
<style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
}
|
||||
|
||||
<div class="layui-row">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css"/>
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css"/>
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
}
|
||||
<blockquote class="layui-elem-quote news_search toolList" id="menus">
|
||||
</blockquote>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css"/>
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css"/>
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css"/>
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css"/>
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css"/>
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
}
|
||||
<blockquote class="layui-elem-quote news_search toolList" id="menus">
|
||||
</blockquote>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
}
|
||||
<blockquote class="layui-elem-quote news_search toolList" id="menus">
|
||||
</blockquote>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css" />
|
||||
|
||||
<link rel="stylesheet" href="/js/dtree/dtree.css" />
|
||||
<link rel="stylesheet" href="/js/dtree/font/dtreefont.css" />
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@section header
|
||||
{
|
||||
<link rel="stylesheet" href="/css/treetable.css"/>
|
||||
|
||||
}
|
||||
|
||||
<blockquote class="layui-elem-quote news_search toolList" id="menus">
|
||||
|
||||
@@ -5,6 +5,14 @@
|
||||
.layui-layer-tab .layui-layer-title span.layui-layer-tabnow{ height:42px !important; }
|
||||
.layui-layer-tab .layui-layer-title span{ min-width:45px !important; }
|
||||
.marg0{ margin:0; }
|
||||
/*统一按钮样式*/
|
||||
.layui-btn {
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
padding: 0 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/*模拟加载层图标样式*/
|
||||
.layui-layer-dialog .layui-layer-content .layui-layer-ico16{ background-size:100% 100% !important; }
|
||||
|
||||
@@ -26,6 +34,8 @@
|
||||
|
||||
.layui-elem-quote{
|
||||
border-left: 5px solid #f8f8f8 !important; /*blockquote的左侧边框*/
|
||||
padding:5px;
|
||||
margin-block-end: 2px;
|
||||
}
|
||||
|
||||
/*样式改变的过渡*/
|
||||
@@ -72,15 +82,13 @@
|
||||
.layui-nav-tree .layui-nav-child dd.layui-this a:hover{ background-color:#009688; }
|
||||
|
||||
/*右侧body*/
|
||||
#top_tabs_box{ padding-right:138px; height:40px; border-bottom:1px solid #e2e2e2; }
|
||||
#top_tabs_box{ padding-right:138px; height:35px; border-bottom:1px solid #e2e2e2; }
|
||||
#top_tabs{ position: absolute; border-bottom:none;}
|
||||
/*多窗口页面操作下拉*/
|
||||
.closeBox{ position:absolute; right:0; background-color:#fff !important; color:#000; border-left:1px solid #e2e2e2; border-bottom:1px solid #e2e2e2; }
|
||||
.closeBox .layui-nav-item{ line-height:40px; }
|
||||
.closeBox .layui-nav-item{ line-height:35px; }
|
||||
.closeBox .layui-nav-item a,.closeBox .layui-nav-item a:hover{ color:#000; }
|
||||
.closeBox .layui-nav-more{ top:17px; }
|
||||
.closeBox .layui-nav-mored{ top:11px; }
|
||||
.closeBox .layui-nav-child{ top:42px; left:-12px; }
|
||||
.closeBox .layui-nav-child{ top:37px; left:-12px; }
|
||||
.closeBox .layui-nav-bar{ display:none; }
|
||||
.closeBox .icon-caozuo{ font-size: 20px; position:absolute; top:1px; left:-2px; }
|
||||
|
||||
@@ -90,11 +98,18 @@
|
||||
}
|
||||
.layui-tab-content{ height:100%; padding:0; }
|
||||
.layui-tab-item{ position: absolute; top: 41px; bottom:27px; left: 0; right: 0; padding: 0; margin: 0; -webkit-overflow-scrolling:touch; overflow:auto;}
|
||||
.layui-tab-title .layui-this{ background-color:#18A093;}
|
||||
.layui-tab .layui-tab-title{
|
||||
height: 35px;
|
||||
}
|
||||
.layui-tab-title .layui-this:after{ border:none; }
|
||||
.layui-tab-title li cite{ font-style: normal; padding-left:5px; }
|
||||
.layui-tab-card .layui-tab-title{background-color: #ffffff}
|
||||
.layui-tab-card .layui-tab-title .layui-this{background-color: #f2f2f2}
|
||||
.layui-tab .layui-tab-title li {
|
||||
line-height: 35px;
|
||||
}
|
||||
|
||||
|
||||
.clildFrame.layui-tab-content{ padding-right: 0; }
|
||||
.clildFrame.layui-tab-content iframe{ width: 100%; height:100%; border:none; min-width: 320px; position:absolute; }
|
||||
/*main.html*/
|
||||
@@ -180,7 +195,11 @@
|
||||
.orange .top_menu.layui-nav-itemed .layui-nav-more,.orange .top_menu.layui-nav .layui-nav-mored,.blue .top_menu.layui-nav-itemed .layui-nav-more,.blue .top_menu.layui-nav .layui-nav-mored{border-color:transparent transparent #fff !important;}
|
||||
|
||||
/*底部*/
|
||||
.footer{ text-align: center; line-height:44px;border-left: 2px solid #1AA094;}
|
||||
.footer{ text-align: center; }
|
||||
.layui-layout-admin .layui-footer {
|
||||
line-height: 35px !important;
|
||||
height: 35px !important;
|
||||
}
|
||||
|
||||
|
||||
/*响应式*/
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
.layui-elem-quote {
|
||||
margin-bottom: 2px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.layui-table-view {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
ul.ztree {
|
||||
margin-top: 0!important;
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
haveHead: false,
|
||||
haveTool: true,
|
||||
headLabel: true,
|
||||
toolBtns: ["start round mix", "end round", "node", "join", "fork"],
|
||||
toolBtns: ["start", "end", "node", "join", "fork"],
|
||||
haveGroup: true,
|
||||
useOperStack: true
|
||||
};
|
||||
@@ -78,14 +78,14 @@
|
||||
var _node = data.nodes[j];
|
||||
var _flag = false;
|
||||
switch (_node.type) {
|
||||
case "start round mix":
|
||||
case "start":
|
||||
startroundFlag++;
|
||||
if (fromlines[_node.id] == undefined) {
|
||||
layer.msg("开始节点无法流转到下一个节点");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case "end round":
|
||||
case "end":
|
||||
endroundFlag++;
|
||||
if (tolines[_node.id] == undefined) {
|
||||
layer.msg("无法流转到结束节点");
|
||||
@@ -173,7 +173,7 @@
|
||||
$.each(options.nodeData,
|
||||
function (i, item) {
|
||||
$("#" + item.id).css("background", "#999");
|
||||
if (item.type == "start round mix") {
|
||||
if (item.type == "start") {
|
||||
$("#" + item.id).css("background", "#5cb85c");
|
||||
} else {
|
||||
if (item.id == options.activityId) {
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
});
|
||||
};
|
||||
mainList();
|
||||
clickTableRow(table,'mainList', 'list');
|
||||
|
||||
//添加(编辑)对话框
|
||||
var editDlg = function () {
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
OpenNode: function (object) {
|
||||
FlowDesignObject = object; //为NodeInfo窗口提供调用
|
||||
|
||||
if (object.type == 'start round mix' || object.type == 'end round') {
|
||||
if (object.type == 'start' || object.type == 'end') {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
OpenNode: function (object) {
|
||||
FlowDesignObject = object; //为NodeInfo窗口提供调用
|
||||
|
||||
if (object.type == 'start round mix' || object.type == 'end round') {
|
||||
if (object.type == 'start' || object.type == 'end') {
|
||||
layer.msg("开始节点与结束节点不能设置");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
OpenNode: function (object) {
|
||||
FlowDesignObject = object; //为NodeInfo窗口提供调用
|
||||
|
||||
if (object.type == 'start round mix' || object.type == 'end round') {
|
||||
if (object.type == 'start' || object.type == 'end') {
|
||||
layer.msg("开始节点与结束节点不能设置");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
layui.config({
|
||||
/*
|
||||
* @Author: yubaolee <yubaolee@163.com> | ahfu~ <954478625@qq.com>
|
||||
* @Date: 2023-12-25 14:43:53
|
||||
* @Description:
|
||||
* @LastEditTime: 2025-04-14 15:55:51
|
||||
* Copyright (c) 2025 by yubaolee | ahfu~ , All Rights Reserved.
|
||||
*/
|
||||
layui.config({
|
||||
base: "/js/"
|
||||
}).use(['form', 'vue', 'ztree', 'layer', 'jquery', 'table', 'droptree', 'openauth', 'utils'], function () {
|
||||
var form = layui.form,
|
||||
@@ -50,7 +57,7 @@
|
||||
});
|
||||
};
|
||||
mainList();
|
||||
|
||||
clickTableRow(table,'mainList', 'list');
|
||||
|
||||
|
||||
//监听表格内部按钮
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
});
|
||||
};
|
||||
mainList();
|
||||
clickTableRow(table,'mainList', 'list');
|
||||
|
||||
//添加(编辑)对话框
|
||||
var editDlg = function () {
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace OpenAuth.Repository.Domain
|
||||
this.VerifyComment = "";
|
||||
this.CascadeId = "";
|
||||
this.ApproverId = "";
|
||||
this.ApproveType = 0;
|
||||
this.ApproveType = "";
|
||||
this.CreateDate = DateTime.Now;
|
||||
this.CreateUserName = "";
|
||||
this.ParentId = "";
|
||||
@@ -70,10 +70,10 @@ namespace OpenAuth.Repository.Domain
|
||||
public string ApproverId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///类型(0顺序,1并行且,2并行或)
|
||||
///类型(sequential顺序,all并行且,one并行或)
|
||||
/// </summary>
|
||||
[Description("类型(0顺序,1并行且,2并行或)")]
|
||||
public int ApproveType { get; set; }
|
||||
[Description("类型(sequential顺序,all并行且,one并行或)")]
|
||||
public string ApproveType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///加签时间
|
||||
|
||||
@@ -70,11 +70,6 @@ namespace OpenAuth.Repository.Domain
|
||||
[Description("当前节点ID")]
|
||||
public string ActivityId { get; set; }
|
||||
/// <summary>
|
||||
/// 当前节点类型(0会签节点)
|
||||
/// </summary>
|
||||
[Description("当前节点类型(0会签节点)")]
|
||||
public int? ActivityType { get; set; }
|
||||
/// <summary>
|
||||
/// 当前节点名称
|
||||
/// </summary>
|
||||
[Description("当前节点名称")]
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace OpenAuth.Repository.Domain
|
||||
/// 开始节点类型
|
||||
/// </summary>
|
||||
[Description("开始节点类型")]
|
||||
public int? FromNodeType { get; set; }
|
||||
public string FromNodeType { get; set; }
|
||||
/// <summary>
|
||||
/// 开始节点名称
|
||||
/// </summary>
|
||||
@@ -65,7 +65,7 @@ namespace OpenAuth.Repository.Domain
|
||||
/// 结束节点类型
|
||||
/// </summary>
|
||||
[Description("结束节点类型")]
|
||||
public int? ToNodeType { get; set; }
|
||||
public string ToNodeType { get; set; }
|
||||
/// <summary>
|
||||
/// 结束节点名称
|
||||
/// </summary>
|
||||
|
||||
18
README.md
@@ -54,13 +54,18 @@
|
||||
|
||||
|
||||
## 📸效果预览
|
||||
|
||||
#### 后端启动效果
|
||||

|
||||
|
||||
#### vue版本效果
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
#### layui开源版本效果
|
||||

|
||||
|
||||
|
||||
## 📞官方QQ交流群
|
||||
|
||||
@@ -74,6 +79,7 @@
|
||||
|
||||
|
||||
## 💡核心功能
|
||||
项目深入参考《企业应用架构模式》《重构与模式》《ASP.NET设计模式》等巨著完成每一行代码编写。主要特性:
|
||||
|
||||
* 支持最新版.Net 9.0.100
|
||||
|
||||
@@ -111,15 +117,5 @@
|
||||
|
||||
* 设计工具 PowerDesigner +PDManer + Enterprise Architect
|
||||
|
||||
|
||||
## 💎秀外
|
||||
|
||||

|
||||

|
||||
|
||||
## 🧠慧中
|
||||
|
||||
教科书级的分层思想,哪怕苛刻的你阅读的是大神级精典大作(如:《企业应用架构模式》《重构与模式》《ASP.NET设计模式》等),你也可以参考本项目。
|
||||
|
||||
## 🔜后续
|
||||
生命不息,更新不止
|
||||
@@ -1,192 +0,0 @@
|
||||
/*
|
||||
* @Author: yubaolee <yubaolee@163.com> | ahfu~ <954478625@qq.com>
|
||||
* @Date: 2023-08-12 10:48:24
|
||||
* @LastEditTime: 2025-04-09 20:38:14
|
||||
* @Description:
|
||||
* @
|
||||
* @Copyright (c) 2023 by yubaolee | ahfu~ , All Rights Reserved.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
title: 'OpenAuth.Net',
|
||||
description: '最好用的.net权限工作流框架,最好用的.net vue前后分离框架',
|
||||
head: [
|
||||
['link', {
|
||||
rel: 'icon',
|
||||
href: '/logo.png'
|
||||
}],['script',{},
|
||||
`var _hmt = _hmt || [];
|
||||
(function () {
|
||||
var hm = document.createElement('script')
|
||||
hm.src = 'https://hm.baidu.com/hm.js?93a7b9a145222f9b7109d643a0c58f8d'
|
||||
var s = document.getElementsByTagName('script')[0]
|
||||
s.parentNode.insertBefore(hm, s)
|
||||
})();
|
||||
`]
|
||||
],
|
||||
extendMarkdown: (md) => {
|
||||
md.set({
|
||||
breaks: true
|
||||
})
|
||||
md.use(require('markdown-it-plantuml'))
|
||||
},
|
||||
themeConfig: {
|
||||
lastUpdated: '最后更新时间', // string | boolean
|
||||
nav: [{
|
||||
text: '首页',
|
||||
link: 'http://openauth.net.cn/',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
text: '在线文档',
|
||||
ariaLabel: 'Proj Menu',
|
||||
items: [{
|
||||
text: 'OpenAuth.Net开源后端',
|
||||
link: '/core/',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
text: 'OpenAuth.Pro(vue3版本)',
|
||||
link: '/pro/',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
text: 'OpenAuth.Pro(vue2版本)',
|
||||
link: '/vue2/',
|
||||
target: '_blank'
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
text: '项目地址',
|
||||
ariaLabel: 'Proj Menu',
|
||||
items: [{
|
||||
text: 'gitee',
|
||||
link: 'https://gitee.com/dotnetchina/OpenAuth.Net',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
text: 'github',
|
||||
link: 'https://github.com/yubaolee/OpenAuth.Core',
|
||||
target: '_blank'
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: '战略合作',
|
||||
ariaLabel: 'Proj Menu',
|
||||
items: [{
|
||||
text: 'Variant Form - 可视化低代码表单',
|
||||
link: 'https://www.vform666.com/',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
text: 'SqlSugar',
|
||||
link: 'https://www.donet5.com/',
|
||||
target: '_blank'
|
||||
}
|
||||
],
|
||||
},
|
||||
],
|
||||
sidebar: {
|
||||
'/core/': [
|
||||
['', '项目介绍'],
|
||||
{
|
||||
title: '后端开发', // 必要的
|
||||
path: 'start', // 可选的, 标题的跳转链接,应为绝对路径且必须存在
|
||||
sidebarDepth: 1, // 可选的, 默认值是 1
|
||||
collapsable: false,
|
||||
children: ['start', 'specialist', 'deploy', 'deployapi', 'devnew', 'multidbs', 'multitenant', 'unitwork','sqlsugar', 'entity','dynamicapi', 'datavalidation', 'log', 'identity', 'job', 'cache', 'unittest','changesdk'],
|
||||
},
|
||||
{
|
||||
title: '权限控制', // 必要的
|
||||
sidebarDepth: 1, // 可选的, 默认值是 1
|
||||
collapsable: false,
|
||||
children: ['moduleauth','apiauth', 'logininfo', 'dataprivilege', 'datapropertyrule'],
|
||||
},
|
||||
{
|
||||
title: '表单设计', // 必要的
|
||||
sidebarDepth: 1, // 可选的, 默认值是 1
|
||||
collapsable: false,
|
||||
children: ['form'],
|
||||
},
|
||||
{
|
||||
title: '工作流', // 必要的
|
||||
sidebarDepth: 1, // 可选的, 默认值是 1
|
||||
collapsable: false,
|
||||
children: ['flowinstance','flowinstanceconcept', 'flowinstancestatus', 'thirdparty'],
|
||||
},
|
||||
{
|
||||
title: '前端开发', // 必要的
|
||||
sidebarDepth: 1, // 可选的, 默认值是 1
|
||||
collapsable: false,
|
||||
children: ['wwwarchitect'],
|
||||
},
|
||||
{
|
||||
title: '更新日志', // 必要的
|
||||
sidebarDepth: 1, // 可选的, 默认值是 1
|
||||
collapsable: false,
|
||||
children: ['changelog', 'routineupdate'],
|
||||
},
|
||||
'faq',
|
||||
],
|
||||
|
||||
'/pro/': [
|
||||
['', '项目介绍'],
|
||||
'deploy',
|
||||
'structure',
|
||||
'devnew',
|
||||
{
|
||||
title: '基础开发', // 必要的
|
||||
sidebarDepth: 1, // 可选的, 默认值是 1
|
||||
collapsable: false,
|
||||
children: ['router','openurl','keepalive'],
|
||||
},
|
||||
'datapropertyrule',
|
||||
'printerplan',
|
||||
{
|
||||
title: '表单设计', // 必要的
|
||||
sidebarDepth: 1, // 可选的, 默认值是 1
|
||||
collapsable: false,
|
||||
children: ['startform','urlform','dragform','dragformdetail'],
|
||||
},
|
||||
{
|
||||
title: '工作流', // 必要的
|
||||
sidebarDepth: 1, // 可选的, 默认值是 1
|
||||
collapsable: false,
|
||||
children: ['startflow','form'],
|
||||
},
|
||||
'components',
|
||||
'faq',
|
||||
],
|
||||
'/vue2/': [
|
||||
['', '项目介绍'],
|
||||
'deploy',
|
||||
'structure',
|
||||
'devnew',
|
||||
{
|
||||
title: '基础开发', // 必要的
|
||||
sidebarDepth: 1, // 可选的, 默认值是 1
|
||||
collapsable: false,
|
||||
children: ['router','openurl','keepalive'],
|
||||
},
|
||||
'datapropertyrule',
|
||||
'printerplan',
|
||||
{
|
||||
title: '表单设计', // 必要的
|
||||
sidebarDepth: 1, // 可选的, 默认值是 1
|
||||
collapsable: false,
|
||||
children: ['startform','dragform','dragformdetail'],
|
||||
},
|
||||
{
|
||||
title: '工作流', // 必要的
|
||||
sidebarDepth: 1, // 可选的, 默认值是 1
|
||||
collapsable: false,
|
||||
children: ['startflow','form'],
|
||||
},
|
||||
'components',
|
||||
'faq',
|
||||
]
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* @Author: yubaolee <yubaolee@163.com> | ahfu~ <954478625@qq.com>
|
||||
* @Date: 2024-06-19 20:41:42
|
||||
* @LastEditTime: 2024-06-19 20:48:04
|
||||
* @Description:
|
||||
* @
|
||||
* @Copyright (c) 2024 by yubaolee | ahfu~ , All Rights Reserved.
|
||||
*/
|
||||
// .vuepress/enhanceApp.js
|
||||
export default ({ router }) => {
|
||||
if (process.env.NODE_ENV === 'production' && typeof window !== 'undefined') {
|
||||
// 百度统计代码
|
||||
var _hmt = _hmt || []
|
||||
;(function () {
|
||||
var hm = document.createElement('script')
|
||||
hm.src = 'https://hm.baidu.com/hm.js?93a7b9a145222f9b7109d643a0c58f8d'
|
||||
var s = document.getElementsByTagName('script')[0]
|
||||
s.parentNode.insertBefore(hm, s)
|
||||
})();
|
||||
|
||||
// 路由切换时触发百度统计
|
||||
router.afterEach(function (to) {
|
||||
if (window._hmt) {
|
||||
window._hmt.push(['_trackPageview', to.fullPath])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 170 KiB |
|
Before Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 31 KiB |
@@ -1,25 +0,0 @@
|
||||
---
|
||||
home: true
|
||||
heroImage: /logo.png
|
||||
heroText: OpenAuth.Net
|
||||
tagline: 最好用的.net权限工作流框架,最实用的.net/vue前后端分离方案
|
||||
actionText: 快速上手 →
|
||||
actionLink: /core/start/
|
||||
features:
|
||||
- title: 简洁至上
|
||||
details: 源于Martin Fowler企业级应用开发思想及最新技术组合。
|
||||
- title: 灵活控制
|
||||
details: 超强的自定义权限控制功能,可灵活配置用户、角色可访问的数据权限。
|
||||
- title: 超酷体验
|
||||
details: 可拖拽的表单设计,可视化流程设计。
|
||||
- title: 紧随潮流
|
||||
details: 最新的.net sdk,配合最炫的vue框架。
|
||||
- title: 功能强大
|
||||
details: 角色授权、代码生成、API鉴权、智能打印、数据权限、拖拽表单、工作流引擎、定时任务。
|
||||
- title: 主流技术
|
||||
details: IdentityServer、EF、SqlSugar、Quartz、AutoFac、WebAPI、Swagger、Mock、NUnit、VUE2、VUE3、Element-ui、Element-plus。
|
||||
footer: Copyright © 2025- yubaolee
|
||||
---
|
||||
|
||||
|
||||
|
||||
2
docs/core/.vscode/settings.json
vendored
@@ -1,2 +0,0 @@
|
||||
{
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
# 部署MVC
|
||||
|
||||
::: tip 提示
|
||||
因.net core内部有自托管的Web服务器,推荐使用控制台方式部署。本内容基于控制台命令的方式。如果部署到IIS请自行百度:cold_sweat:
|
||||
:::
|
||||
|
||||
## 生成发布文件
|
||||
|
||||
* 修改部署环境的连接字符串信息,特别注意是`appsettings.Production.json`文件:
|
||||

|
||||
|
||||
::: warning 注意
|
||||
决定系统部署后读取`appsettings.json`还是`appsettings.Production.json`是通过操作系统的环境变量`ASPNETCORE_ENVIRONMENT`来控制的。
|
||||
在centos切换成正式可以用
|
||||
```shell
|
||||
export ASPNETCORE_ENVIRONMENT=Production
|
||||
```
|
||||
|
||||
或者修改/etc/profile配置,在结尾添加:
|
||||
```shell
|
||||
ASPNETCORE_ENVIRONMENT=Production
|
||||
export ASPNETCORE_ENVIRONMENT
|
||||
```
|
||||
然后刷新:
|
||||
```shell
|
||||
source /etc/profile
|
||||
```
|
||||
|
||||
在Widows系统中增加对应环境变量即可
|
||||
|
||||
:::
|
||||
|
||||
* 直接在解决方案资源管理器中,选中OpenAuth.Mvc右键【发布】,出现下面的配置框,使用文件系统即可:
|
||||
|
||||

|
||||
|
||||
* 发布完成后可以在输出目录看到发布详情(红色框内即为发布的文件夹):
|
||||
|
||||

|
||||
|
||||
## 部署OpenAuth.Mvc
|
||||
|
||||
将发布后的文件拷贝到服务器文件夹。直接使用`dotnet openauth.mvc.dll` 命令启动。启动成功后使用浏览器打开http://localhost:1802 即可访问,如下图所示:
|
||||
|
||||

|
||||
|
||||
|
||||
## jenkins部署OpenAuth.Mvc
|
||||
|
||||
OpenAuth.Net采用的是gitee托管源码,只需使用Gitee WebHook构建触发器。配置如下:
|
||||
|
||||

|
||||
|
||||
做好上面的配置后,代码提交时就会触发jenkins工作。剩下的就是编写自己的构建脚本。增加构建步骤,选择执行Shell。并输入以下脚本:
|
||||
|
||||
```shell
|
||||
#!/bin/bash
|
||||
kill -9 $(ps -ef|grep OpenAuth.Mvc.dll|grep -v grep|awk '{print $2}')
|
||||
|
||||
#项目启动之后才不会被Jenkins杀掉。
|
||||
export BUILD_ID=dontKillMe
|
||||
pwd
|
||||
echo $PATH
|
||||
dotnet restore # 还原nuget包
|
||||
|
||||
cd ./OpenAuth.Mvc
|
||||
dotnet build # 编译
|
||||
|
||||
rm -rf /data/openauthmvc #最终站点路径
|
||||
mkdir /data/openauthmvc
|
||||
dotnet publish -c:Release -o /data/openauthmvc # 生成发布文件到/data/openauthmvc。如果服务器上有多个.NET版本,加上目标版本号,如:-f net6.0
|
||||
|
||||
nohup dotnet /data/openauthmvc/OpenAuth.Mvc.dll &
|
||||
|
||||
echo '============================end build======================================='
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
# 工作流介绍
|
||||
|
||||
OpenAuth.Net工作流基于国际标准的BPMN2.0规范,并在此基础上做了一些扩展,以满足国内各种需求。系统工作流分为两个大类:
|
||||
|
||||
1. 无业务关联流程,如请假、报销等。
|
||||
|
||||

|
||||
|
||||
2. 有业务关联流程,如采购、销售等。
|
||||
|
||||

|
||||
|
||||
这两种流程的差异有以下几点:
|
||||
|
||||
| 对比维度 | 无业务关联流程 | 有业务关联流程 |
|
||||
|---------|--------------|--------------|
|
||||
| 适用场景 | 请假、报销等日常办公 | 采购、销售、入库等业务操作 |
|
||||
| 发起方式 | 流程中心 -> 我的流程 -> 新的申请 | 直接在业务模块中发起(如:仓储中心 -> 入库订单 -> 送审) |
|
||||
| 表单类型 | 简单表单,适用拖拽表单设计器 | 复杂表单,需要自定义表单或URL表单 |
|
||||
| 审批结束处理 | 仅更新流程状态 | 需要修改业务数据状态 |
|
||||
|
||||
表中提到的表单类型差异可以查看:[表单设计](./form.md)
|
||||
|
||||
|
||||
# 基本操作
|
||||
|
||||
一个完整的工作流从设计到发起,到审批,需要经过:
|
||||
|
||||
1. 表单设计:【基础配置/表单设计】中添加一个用于流程的表单;
|
||||
|
||||
2. 流程设计:【基础配置/流程设计】中添加一个流程模版,流程模版选择刚刚建的表单;
|
||||
|
||||
3. 流程发起:【流程中心/我的流程】中【新的申请】创建一个流程实例,或在业务系统中直接【送审】发起;
|
||||
|
||||
4. 流程审批:【流程中心/待处理流程】中进行审批;
|
||||
|
||||
这里只介绍开源版本的操作流程,vue版本操作流程请参考:[操作手册](/pro/startflow.md)
|
||||
|
||||
# 流程审批逻辑
|
||||
|
||||
当最终用户在【待处理流程】中审批一个流程实例时,流程实例会经过下面步骤进行处理:
|
||||
|
||||
@startuml
|
||||
skinparam handwritten true
|
||||
skinparam backgroundColor #EEEBDC
|
||||
|
||||
start
|
||||
if (当前活动节点类型为会签) then (yes)
|
||||
:标识当前节点状态;
|
||||
:从所有的分支中找到一个用户可以审批的节点canCheckId;
|
||||
if (没找到?) then (yes)
|
||||
stop
|
||||
endif
|
||||
:标识canCheckId节点状态;
|
||||
#HotPink:进行会签,结果为res;
|
||||
if(res == TagState.No) then (yes)
|
||||
:修改流程最终状态为不同意;
|
||||
else if(res != string.Empty) then (yes)
|
||||
stop
|
||||
else (no)
|
||||
:修改流程最终状态,修改活动节点,修改可执行人;
|
||||
:添加扭转记录;
|
||||
endif
|
||||
|
||||
else (no)
|
||||
:标识当前节点状态;
|
||||
if (同意) then (yes)
|
||||
:修改流程最终状态,修改活动节点,修改可执行人;
|
||||
:添加扭转记录;
|
||||
else
|
||||
:修改流程最终状态为不同意;
|
||||
endif
|
||||
:操作记录;
|
||||
endif
|
||||
stop
|
||||
|
||||
@enduml
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
# 流程实例
|
||||
|
||||
流程实例指正在运行的一个流程。数据存放在FlowInstance表中,该表核心字段如下:
|
||||
|
||||
#### IsFinish:流程的当前状态
|
||||
|
||||
- -1 草稿/召回:流程发起人主动召回流程;
|
||||
|
||||
- 0 正在运行;
|
||||
|
||||
- 1 完成:流程结束,同时所有的审批都通过;
|
||||
|
||||
- 3 不同意:即流程结束,同时审批人员没有通过;
|
||||
|
||||
- 4 驳回:流程结束,可能发起的流程内容有问题,要求被驳回重新提交;
|
||||
|
||||
|
||||
#### ActivityId: 当前活动节点,即待审批的节点
|
||||
|
||||
#### ActivityType:当前节点的类型
|
||||
|
||||
- -1 无法运行,
|
||||
|
||||
- 0 会签开始,
|
||||
|
||||
- 1 会签结束,
|
||||
|
||||
- 2 一般节点,
|
||||
|
||||
- 3 开始节点,
|
||||
|
||||
- 4 流程运行结束
|
||||
|
||||
#### SchemeContent:流程实例的具体内容
|
||||
|
||||
该字段存储的是一个JSON对象,具体内容如下所示:
|
||||
|
||||
```javascript
|
||||
{
|
||||
|
||||
"title":"newFlow_1",
|
||||
"nodes":[
|
||||
{
|
||||
"name":"node_1",
|
||||
"left":75,
|
||||
"top":90,
|
||||
"type":"start round mix",
|
||||
"id":1521797877921,
|
||||
"width":26,
|
||||
"height":26,
|
||||
"alt":true
|
||||
},
|
||||
{
|
||||
"name":"审核",
|
||||
"left":235,
|
||||
"top":97,
|
||||
"type":"node",
|
||||
"id":1521797879744,
|
||||
"width":104,
|
||||
"height":26,
|
||||
"alt":true,
|
||||
"setInfo":{
|
||||
"NodeDesignateData":{
|
||||
"users":[
|
||||
"49df1602-f5f3-4d52-afb7-3802da619558",
|
||||
"6ba79766-faa0-4259-8139-a4a6d35784e0"
|
||||
],
|
||||
"role":{
|
||||
},
|
||||
"org":{
|
||||
}
|
||||
},
|
||||
"NodeCode":"FIRST",
|
||||
"NodeName":"审核"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name":"node_3",
|
||||
"left":268,
|
||||
"top":209,
|
||||
"type":"end round",
|
||||
"id":1521797881216,
|
||||
"width":26,
|
||||
"height":26,
|
||||
"alt":true
|
||||
}
|
||||
],
|
||||
"lines":[
|
||||
{
|
||||
"type":"sl",
|
||||
"from":"1521797877921",
|
||||
"to":"1521797879744",
|
||||
"id":1521797883552,
|
||||
"name":"",
|
||||
"dash":false
|
||||
},
|
||||
{
|
||||
"type":"sl",
|
||||
"from":"1521797879744",
|
||||
"to":"1521797881216",
|
||||
"id":1521797884536,
|
||||
"name":"",
|
||||
"dash":false
|
||||
}
|
||||
],
|
||||
"areas":{
|
||||
},
|
||||
"initNum":7
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
其中:nodes为流程实例的所有节点。lines为流程实例的所有连线。节点的type属性为节点的类型属性,对应上面提到的ActivityType:
|
||||
|
||||
- -1:无法运行;
|
||||
|
||||
- 0:会签开始,即type为:‘fork’;
|
||||
|
||||
- 1:会签结束,即type为:’join’;
|
||||
|
||||
- 2:一般节点,即type为:’node’;
|
||||
|
||||
- 3:开始节点,即type为:‘start’;
|
||||
|
||||
- 4:流程运行结束,即type为’end’;
|
||||
|
||||
与流程实例密切相关的还有两个表:流程实例的操作记录FlowInstanceOperationHistory及流转记录FlowInstanceTransitionHistory。它们有不同的作用:
|
||||
|
||||
### 操作记录FlowInstanceOperationHistory
|
||||
该表记录了流程实例的所有操作记录,包括流程的创建、撤回、驳回、同意、不同意等操作。
|
||||
|
||||
### 流转记录FlowInstanceTransitionHistory
|
||||
记录某个流程实例所有已审批的从一个活动节点到下一个活动节点的操作人、操作时间。
|
||||
@@ -1,26 +0,0 @@
|
||||
# 后端开发规范
|
||||
|
||||
## 数据库表及字段命名
|
||||
|
||||
SqlServer采用PascalCase命名,Oracle采用全大写命名,其他数据库采用camelCase命名。
|
||||
|
||||
::: tip 提示
|
||||
|
||||
开源版代码生成时,通过表结尾Dtbl来判断是否是生成明细表代码。因此建议数据库表命名时按:子系统名称+业务名称+表尾,其中表尾名称规则:
|
||||
- 基础主数据以Mst结尾;
|
||||
- 普通业务表以Tbl结尾;
|
||||
- 业务明细表以Dtbl结尾;
|
||||
如:WMS系统入库订单明细表:WmsInboundOrderDtbl
|
||||
:::
|
||||
|
||||
|
||||
## 数据库字段类型
|
||||
|
||||
主键id统一使用Domain:PrimaryKey(针对SqlServer数据库,非Sql Server根据需要定义)
|
||||
|
||||
状态类,标识类的字段,统一使用bit not null
|
||||
|
||||
表示分类的字段,统一使用PrimaryKey。数值从Category中获取。
|
||||
|
||||
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
# 前端结构
|
||||
|
||||
OpenAuth.Mvc前端采用典型的mvc结构部署,其中:
|
||||
|
||||
* Views: 为静态资源页面,最终会渲染成html(实在不懂,百度Asp.Net Mvc中的View);
|
||||
|
||||
* wwwroot/js: 通用的js组件;
|
||||
|
||||
* wwwroot/userJs: 业务相关的js代码。通常一个csthml页面对应一个userJs中的js文件。如`Categories\Index.cshtml`对应`userJs\categories.js`
|
||||
|
||||
```shell
|
||||
|-- OpenAuth.Mvc
|
||||
|-- Views
|
||||
| |-- _ViewStart.cshtml
|
||||
| |-- Categories
|
||||
| | |-- Index.cshtml
|
||||
| |-- DataPrivilegeRules
|
||||
| | |-- index.cshtml
|
||||
| |-- Error
|
||||
| | |-- Auth.cshtml
|
||||
| |-- FlowInstances
|
||||
| | |-- Detail.cshtml
|
||||
| | |-- Disposed.cshtml
|
||||
| | |-- Edit.cshtml
|
||||
| | |-- Index.cshtml
|
||||
| | |-- Verification.cshtml
|
||||
| | |-- Wait.cshtml
|
||||
| |-- FlowSchemes
|
||||
| | |-- Design.cshtml
|
||||
| | |-- Index.cshtml
|
||||
| | |-- NodeInfo.cshtml
|
||||
| | |-- Preview.cshtml
|
||||
| |-- Forms
|
||||
| | |-- Edit.cshtml
|
||||
| | |-- index.cshtml
|
||||
| | |-- Preview.cshtml
|
||||
| |-- Home
|
||||
| | |-- git.cshtml
|
||||
| | |-- Index.cshtml
|
||||
| | |-- Main.cshtml
|
||||
| |-- Login
|
||||
| | |-- Index.cshtml
|
||||
| |-- ModuleManager
|
||||
| | |-- Assign.cshtml
|
||||
| | |-- Index.cshtml
|
||||
| |-- OpenJobs
|
||||
| | |-- index.cshtml
|
||||
| |-- OrgManager
|
||||
| | |-- Index.cshtml
|
||||
| |-- Redirects
|
||||
| | |-- IdentityAuth.cshtml
|
||||
| |-- Resources
|
||||
| | |-- Assign.cshtml
|
||||
| | |-- Index.cshtml
|
||||
| |-- RoleManager
|
||||
| | |-- Assign.cshtml
|
||||
| | |-- Index.cshtml
|
||||
| |-- Shared
|
||||
| | |-- _Layout.cshtml
|
||||
| |-- SysLogs
|
||||
| | |-- index.cshtml
|
||||
| |-- SysMessages
|
||||
| | |-- index.cshtml
|
||||
| |-- UserManager
|
||||
| | |-- ChangePassword.cshtml
|
||||
| | |-- Index.cshtml
|
||||
| | |-- Profile.cshtml
|
||||
| |-- WmsInboundOrderTbls
|
||||
| |-- index.cshtml
|
||||
|-- wwwroot
|
||||
|-- css
|
||||
| |-- formpreview.css
|
||||
| |-- images.css
|
||||
| |-- login.css
|
||||
| |-- main.css
|
||||
| |-- treetable.css
|
||||
|-- js
|
||||
|-- bodyTab.js
|
||||
|-- bootstrap.js
|
||||
|-- cookie.js
|
||||
|-- droptree.js
|
||||
|-- dtree.js
|
||||
|-- flowlayout.js
|
||||
|-- iconPicker.js
|
||||
|-- index.js
|
||||
|-- leftNav.js
|
||||
|-- openauth.js
|
||||
|-- slimscroll.js
|
||||
|-- utils.js
|
||||
|-- vue.js
|
||||
|-- ztree.js
|
||||
|-- userJs
|
||||
|-- assignModule.js
|
||||
|-- assignResource.js
|
||||
|-- assignRole.js
|
||||
|-- categories.js
|
||||
|-- changePwd.js
|
||||
|-- dataprivilegerules.js
|
||||
|-- flowinstanceDetail.js
|
||||
|-- flowInstanceDisposed.js
|
||||
|-- flowInstanceEdit.js
|
||||
|-- flowInstances.js
|
||||
|-- flowInstanceWait.js
|
||||
|-- flowSchemeDesign.js
|
||||
|-- flowSchemePreview.js
|
||||
|-- flowSchemes.js
|
||||
|-- formEdit.js
|
||||
|-- forms.js
|
||||
|-- login.js
|
||||
|-- main.js
|
||||
|-- modules.js
|
||||
|-- nodeInfo.js
|
||||
|-- openjobs.js
|
||||
|-- orgs.js
|
||||
|-- preview.js
|
||||
|-- profile.js
|
||||
|-- resources.js
|
||||
|-- roles.js
|
||||
|-- syslogs.js
|
||||
|-- sysmessages.js
|
||||
|-- users.js
|
||||
|-- verification.js
|
||||
|-- wmsinboundordertbls.js
|
||||
```
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"scripts": {
|
||||
"dev": "vuepress dev .",
|
||||
"build": "vuepress build ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"vuepress": "^1.4.1"
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
# 常见问题处理
|
||||
|
||||
## vue运行的时候报错
|
||||
|
||||
在启动企业版的时候,如果提示下面错误:
|
||||
|
||||

|
||||
|
||||
请使用`npm run dev`命令来启动项目
|
||||
27
newdocs/README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# open-auth-net-官方文档
|
||||
|
||||
The Site is generated using [vuepress](https://vuepress.vuejs.org/) and [vuepress-theme-plume](https://github.com/pengzhanbo/vuepress-theme-plume)
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
npm i
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
# start dev server
|
||||
npm run docs:dev
|
||||
# build for production
|
||||
npm run docs:build
|
||||
# preview production build in local
|
||||
npm run docs:preview
|
||||
# update vuepress and theme
|
||||
npm run vp-update
|
||||
```
|
||||
|
||||
## Documents
|
||||
|
||||
- [vuepress](https://vuepress.vuejs.org/)
|
||||
- [vuepress-theme-plume](https://theme-plume.vuejs.press/)
|
||||
27
newdocs/README.zh-CN.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# open-auth-net-官方文档
|
||||
|
||||
网站使用 [vuepress](https://vuepress.vuejs.org/) 和 [vuepress-theme-plume](https://github.com/pengzhanbo/vuepress-theme-plume) 构建生成。
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
npm i
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
# 启动开发服务
|
||||
npm run docs:dev
|
||||
# 构建生产包
|
||||
npm run docs:build
|
||||
# 本地预览生产服务
|
||||
npm run docs:preview
|
||||
# 更新 vuepress 和主题
|
||||
npm run vp-update
|
||||
```
|
||||
|
||||
## 文档
|
||||
|
||||
- [vuepress](https://vuepress.vuejs.org/)
|
||||
- [vuepress-theme-plume](https://theme-plume.vuejs.press/)
|
||||
31
newdocs/docs/.vuepress/client.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* @Author: yubaolee <yubaolee@163.com> | ahfu~ <954478625@qq.com>
|
||||
* @Date: 2025-04-23 23:37:29
|
||||
* @LastEditTime: 2025-04-26 15:00:36
|
||||
* @Description:
|
||||
* Copyright (c) 2025 by yubaolee | ahfu~ , All Rights Reserved.
|
||||
*/
|
||||
import { defineClientConfig } from 'vuepress/client'
|
||||
import { h } from 'vue'
|
||||
import { Layout } from 'vuepress-theme-plume/client'
|
||||
// import RepoCard from 'vuepress-theme-plume/features/RepoCard.vue'
|
||||
// import NpmBadge from 'vuepress-theme-plume/features/NpmBadge.vue'
|
||||
// import NpmBadgeGroup from 'vuepress-theme-plume/features/NpmBadgeGroup.vue'
|
||||
// import Swiper from 'vuepress-theme-plume/features/Swiper.vue'
|
||||
|
||||
// import CustomComponent from './theme/components/Custom.vue'
|
||||
|
||||
// import './theme/styles/custom.css'
|
||||
import AsideNav from './theme/components/AsideNav.vue'
|
||||
|
||||
|
||||
export default defineClientConfig({
|
||||
setup() {
|
||||
// setupThemeColors()
|
||||
},
|
||||
layouts: {
|
||||
Layout: h(Layout, null, {
|
||||
'aside-outline-after': () => h(AsideNav),
|
||||
}),
|
||||
},
|
||||
})
|
||||
173
newdocs/docs/.vuepress/config.ts
Normal file
@@ -0,0 +1,173 @@
|
||||
import { viteBundler } from '@vuepress/bundler-vite'
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
import { plumeTheme } from 'vuepress-theme-plume'
|
||||
|
||||
export default defineUserConfig({
|
||||
base: '/',
|
||||
lang: 'zh-CN',
|
||||
title: 'OpenAuth.Net',
|
||||
description: '最好用的.net权限工作流框架,最实用的.net/vue前后端分离方案',
|
||||
|
||||
head: [
|
||||
// 配置站点图标
|
||||
['link', { rel: 'icon', type: 'image/png', href: 'http://img.openauth.net.cn/2025-04-24-00-50-24.png' }],
|
||||
],
|
||||
|
||||
bundler: viteBundler(),
|
||||
shouldPrefetch: false, // 站点较大,页面数量较多时,不建议启用
|
||||
|
||||
theme: plumeTheme({
|
||||
/* 添加您的部署域名, 有助于 SEO, 生成 sitemap */
|
||||
hostname: 'http://doc.openauth.net.cn',
|
||||
|
||||
/* 文档仓库配置,用于 editLink */
|
||||
// docsRepo: '',
|
||||
// docsDir: 'docs',
|
||||
// docsBranch: '',
|
||||
|
||||
/* 页内信息 */
|
||||
// editLink: true,
|
||||
// lastUpdated: true,
|
||||
// contributors: true,
|
||||
// changelog: false,
|
||||
|
||||
/**
|
||||
* 博客
|
||||
* @see https://theme-plume.vuejs.press/config/basic/#blog
|
||||
*/
|
||||
// blog: false, // 禁用博客
|
||||
// blog: {
|
||||
// postList: true, // 是否启用文章列表页
|
||||
// tags: true, // 是否启用标签页
|
||||
// archives: true, // 是否启用归档页
|
||||
// categories: true, // 是否启用分类页
|
||||
// postCover: 'right', // 文章封面位置
|
||||
// pagination: 15, // 每页显示文章数量
|
||||
// },
|
||||
|
||||
/* 博客文章页面链接前缀 */
|
||||
article: '/article/',
|
||||
|
||||
/**
|
||||
* 编译缓存,加快编译速度
|
||||
* @see https://theme-plume.vuejs.press/config/basic/#cache
|
||||
*/
|
||||
cache: 'filesystem',
|
||||
|
||||
/**
|
||||
* 为 markdown 文件自动添加 frontmatter 配置
|
||||
* @see https://theme-plume.vuejs.press/config/basic/#autofrontmatter
|
||||
*/
|
||||
// autoFrontmatter: {
|
||||
// permalink: true, // 是否生成永久链接
|
||||
// createTime: true, // 是否生成创建时间
|
||||
// title: true, // 是否生成标题
|
||||
// },
|
||||
|
||||
/* 本地搜索, 默认启用 */
|
||||
search: { provider: 'local' },
|
||||
|
||||
/**
|
||||
* Algolia DocSearch
|
||||
* 启用此搜索需要将 本地搜索 search 设置为 false
|
||||
* @see https://theme-plume.vuejs.press/config/plugins/search/#algolia-docsearch
|
||||
*/
|
||||
// search: {
|
||||
// provider: 'algolia',
|
||||
// appId: '',
|
||||
// apiKey: '',
|
||||
// indexName: '',
|
||||
// },
|
||||
|
||||
/**
|
||||
* Shiki 代码高亮
|
||||
* @see https://theme-plume.vuejs.press/config/plugins/code-highlight/
|
||||
*/
|
||||
// codeHighlighter: {
|
||||
// twoslash: true, // 启用 twoslash
|
||||
// whitespace: true, // 启用 空格/Tab 高亮
|
||||
// lineNumbers: true, // 启用行号
|
||||
// },
|
||||
|
||||
/* 文章字数统计、阅读时间,设置为 false 则禁用 */
|
||||
// readingTime: true,
|
||||
|
||||
/**
|
||||
* markdown
|
||||
* @see https://theme-plume.vuejs.press/config/markdown/
|
||||
*/
|
||||
markdown: {
|
||||
plantuml: true,
|
||||
// abbr: true, // 启用 abbr 语法 *[label]: content
|
||||
// annotation: true, // 启用 annotation 语法 [+label]: content
|
||||
// pdf: true, // 启用 PDF 嵌入 @[pdf](/xxx.pdf)
|
||||
// caniuse: true, // 启用 caniuse 语法 @[caniuse](feature_name)
|
||||
// plot: true, // 启用隐秘文本语法 !!xxxx!!
|
||||
bilibili: true, // 启用嵌入 bilibili视频 语法 @[bilibili](bid)
|
||||
// youtube: true, // 启用嵌入 youtube视频 语法 @[youtube](video_id)
|
||||
// artPlayer: true, // 启用嵌入 artPlayer 本地视频 语法 @[artPlayer](url)
|
||||
// audioReader: true, // 启用嵌入音频朗读功能 语法 @[audioReader](url)
|
||||
// icons: true, // 启用内置图标语法 :[icon-name]:
|
||||
// codepen: true, // 启用嵌入 codepen 语法 @[codepen](user/slash)
|
||||
// replit: true, // 启用嵌入 replit 语法 @[replit](user/repl-name)
|
||||
// codeSandbox: true, // 启用嵌入 codeSandbox 语法 @[codeSandbox](id)
|
||||
// jsfiddle: true, // 启用嵌入 jsfiddle 语法 @[jsfiddle](user/id)
|
||||
// npmTo: true, // 启用 npm-to 容器 ::: npm-to
|
||||
// demo: true, // 启用 demo 容器 ::: demo
|
||||
// repl: { // 启用 代码演示容器
|
||||
// go: true, // ::: go-repl
|
||||
// rust: true, // ::: rust-repl
|
||||
// kotlin: true, // ::: kotlin-repl
|
||||
// },
|
||||
// math: { // 启用数学公式
|
||||
// type: 'katex',
|
||||
// },
|
||||
// chartjs: true, // 启用 chart.js
|
||||
// echarts: true, // 启用 ECharts
|
||||
// mermaid: true, // 启用 mermaid
|
||||
// flowchart: true, // 启用 flowchart
|
||||
// image: {
|
||||
// figure: true, // 启用 figure
|
||||
// lazyload: true, // 启用图片懒加载
|
||||
// mark: true, // 启用图片标记
|
||||
// size: true, // 启用图片大小
|
||||
// },
|
||||
// include: true, // 在 Markdown 文件中导入其他 markdown 文件内容
|
||||
// imageSize: 'local', // 启用 自动填充 图片宽高属性,避免页面抖动
|
||||
},
|
||||
|
||||
/**
|
||||
* 水印
|
||||
* @see https://theme-plume.vuejs.press/guide/features/watermark/
|
||||
*/
|
||||
// watermark: true,
|
||||
|
||||
/**
|
||||
* 评论 comments
|
||||
* @see https://theme-plume.vuejs.press/guide/features/comments/
|
||||
*/
|
||||
// comment: {
|
||||
// provider: '', // "Artalk" | "Giscus" | "Twikoo" | "Waline"
|
||||
// comment: true,
|
||||
// repo: '',
|
||||
// repoId: '',
|
||||
// category: '',
|
||||
// categoryId: '',
|
||||
// mapping: 'pathname',
|
||||
// reactionsEnabled: true,
|
||||
// inputPosition: 'top',
|
||||
// },
|
||||
|
||||
/**
|
||||
* 资源链接替换
|
||||
* @see https://theme-plume.vuejs.press/guide/features/replace-assets/
|
||||
*/
|
||||
// replaceAssets: 'https://cdn.example.com',
|
||||
|
||||
/**
|
||||
* 加密功能
|
||||
* @see https://theme-plume.vuejs.press/guide/features/encryption/
|
||||
*/
|
||||
// encrypt: {},
|
||||
}),
|
||||
})
|
||||
16
newdocs/docs/.vuepress/navbar.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* @Author: yubaolee <yubaolee@163.com> | ahfu~ <954478625@qq.com>
|
||||
* @Date: 2025-04-23 20:26:48
|
||||
* @LastEditTime: 2025-04-26 10:31:59
|
||||
* @Description: 顶部超链接
|
||||
* Copyright (c) 2025 by yubaolee | ahfu~ , All Rights Reserved.
|
||||
*/
|
||||
import { defineNavbarConfig } from 'vuepress-theme-plume'
|
||||
|
||||
export const navbar = defineNavbarConfig([
|
||||
{ text: '首页', link: 'http://www.openauth.net.cn', icon: 'mdi:home' },
|
||||
{ text: '文档首页', link: '/', icon: 'mdi:book-open-page-variant' },
|
||||
{ text: '开源版文档', link: '/notes/core/README.md', icon: 'logos:opensource' },
|
||||
{ text: 'vue3版文档', link: '/notes/pro/README.md', icon: 'material-icon-theme:vue' },
|
||||
{ text: 'vue2版文档', link: '/notes/vue2/README.md', icon: 'material-icon-theme:vue' }
|
||||
])
|
||||
120
newdocs/docs/.vuepress/notes.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* @Author: yubaolee <yubaolee@163.com> | ahfu~ <954478625@qq.com>
|
||||
* @Date: 2025-04-23 20:26:48
|
||||
* @LastEditTime: 2025-05-07 20:49:08
|
||||
* @Description: 笔记配置
|
||||
* Copyright (c) 2025 by yubaolee | ahfu~ , All Rights Reserved.
|
||||
*/
|
||||
import { defineNoteConfig, defineNotesConfig } from 'vuepress-theme-plume'
|
||||
|
||||
//开源后端文档
|
||||
const coreNote = defineNoteConfig({
|
||||
dir: 'core',
|
||||
link: '/core',
|
||||
sidebar: [
|
||||
'',
|
||||
{
|
||||
text: '基础开发',
|
||||
collapsed: false,
|
||||
items: [
|
||||
'start', 'specialist', 'deploy', 'deployapi', 'devnew', 'multidbs', 'multitenant', 'unitwork','sqlsugar', 'entity','dynamicapi', 'datavalidation', 'log', 'identity', 'job', 'cache', 'unittest','changesdk'
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '权限控制',
|
||||
collapsed: true,
|
||||
items: [
|
||||
'moduleauth','apiauth', 'logininfo', 'dataprivilege', 'datapropertyrule'
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '工作流',
|
||||
collapsed: true,
|
||||
items: ['form','flowinstance','flowinstanceconcept','flowinstancedev', 'thirdparty' ]
|
||||
},
|
||||
{
|
||||
text: '前端开发',
|
||||
collapsed: true,
|
||||
items: ['wwwarchitect']
|
||||
},
|
||||
{
|
||||
text: '其他',
|
||||
collapsed: true,
|
||||
items: ['changelog', 'routineupdate','faq']
|
||||
}
|
||||
],
|
||||
})
|
||||
|
||||
// vue3版本
|
||||
const proNote = defineNoteConfig({
|
||||
dir: 'pro',
|
||||
link: '/pro',
|
||||
sidebar: [
|
||||
'',
|
||||
{
|
||||
text: '基础开发',
|
||||
collapsed: false,
|
||||
items: ['start','deploy','structure','devnew', 'router','openurl','keepalive','datapropertyrule']
|
||||
},
|
||||
{
|
||||
text: '内置组件',
|
||||
collapsed: false,
|
||||
items: ['table','querybuilder','columnsetting','components']
|
||||
},
|
||||
'printerplan',
|
||||
{
|
||||
text: '表单设计',
|
||||
collapsed: true,
|
||||
items: ['startform','urlform','dragform','dragformdetail']
|
||||
},
|
||||
{
|
||||
text: '工作流',
|
||||
collapsed: true,
|
||||
items: ['startflow','form']
|
||||
},
|
||||
{
|
||||
text: '其他',
|
||||
collapsed: true,
|
||||
items: ['faq']
|
||||
}
|
||||
|
||||
]
|
||||
})
|
||||
|
||||
// vue2版本
|
||||
const vue2Note = defineNoteConfig({
|
||||
dir: 'vue2',
|
||||
link: '/vue2',
|
||||
sidebar: [
|
||||
'',
|
||||
{
|
||||
text: '基础开发',
|
||||
collapsed: false,
|
||||
items: [ 'deploy', 'structure', 'devnew','router','openurl','keepalive']
|
||||
},
|
||||
'datapropertyrule',
|
||||
'printerplan',
|
||||
{
|
||||
text: '表单设计',
|
||||
collapsed: true,
|
||||
items: ['startform','dragform','dragformdetail']
|
||||
},
|
||||
{
|
||||
text: '工作流',
|
||||
collapsed: true,
|
||||
items: ['startflow','form']
|
||||
},
|
||||
{
|
||||
text: '其他',
|
||||
collapsed: true,
|
||||
items: ['components','faq']
|
||||
}
|
||||
|
||||
]
|
||||
})
|
||||
|
||||
export const notes = defineNotesConfig({
|
||||
dir: 'notes',
|
||||
link: '/',
|
||||
notes: [coreNote, proNote, vue2Note],
|
||||
})
|
||||
76
newdocs/docs/.vuepress/plume.config.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* @Author: yubaolee <yubaolee@163.com> | ahfu~ <954478625@qq.com>
|
||||
* @Date: 2025-04-23 20:26:48
|
||||
* @LastEditTime: 2025-04-24 01:27:38
|
||||
* @Description: 配置
|
||||
* Copyright (c) 2025 by yubaolee | ahfu~ , All Rights Reserved.
|
||||
*/
|
||||
import { defineThemeConfig } from 'vuepress-theme-plume'
|
||||
import { navbar } from './navbar'
|
||||
import { notes } from './notes'
|
||||
|
||||
/**
|
||||
* @see https://theme-plume.vuejs.press/config/basic/
|
||||
*/
|
||||
export default defineThemeConfig({
|
||||
logo: 'http://img.openauth.net.cn/2025-04-23-21-21-00.png',
|
||||
|
||||
appearance: true, // 配置 深色模式
|
||||
|
||||
social: [
|
||||
{ icon: 'github', link: 'https://gitee.com/dotnetchina/OpenAuth.Net' },
|
||||
],
|
||||
// navbarSocialInclude: ['github'], // 允许显示在导航栏的 social 社交链接
|
||||
// aside: true, // 页内侧边栏, 默认显示在右侧
|
||||
// outline: [2, 3], // 页内大纲, 默认显示 h2, h3
|
||||
|
||||
/**
|
||||
* 文章版权信息
|
||||
* @see https://theme-plume.vuejs.press/guide/features/copyright/
|
||||
*/
|
||||
// copyright: true,
|
||||
|
||||
// prevPage: true, // 是否启用上一页链接
|
||||
// nextPage: true, // 是否启用下一页链接
|
||||
// createTime: true, // 是否显示文章创建时间
|
||||
|
||||
/* 站点页脚 */
|
||||
footer: {
|
||||
message: 'Copyright © 2025 <a target="_blank" href="http://www.openauth.net.cn">OpenAuth.Net</a>',
|
||||
copyright: '',
|
||||
},
|
||||
|
||||
/**
|
||||
* @see https://theme-plume.vuejs.press/config/basic/#profile
|
||||
*/
|
||||
profile: {
|
||||
avatar: 'http://img.openauth.net.cn/2025-04-23-21-21-00.png',
|
||||
name: 'OpenAuth.Net官方文档',
|
||||
description: '最好用的权限工作流框架',
|
||||
// circle: true,
|
||||
// location: '',
|
||||
// organization: '',
|
||||
},
|
||||
|
||||
navbar,
|
||||
notes,
|
||||
|
||||
/**
|
||||
* 公告板
|
||||
* @see https://theme-plume.vuejs.press/guide/features/bulletin/
|
||||
*/
|
||||
// bulletin: {
|
||||
// layout: 'top-right',
|
||||
// contentType: 'markdown',
|
||||
// title: '公告板标题',
|
||||
// content: '公告板内容',
|
||||
// },
|
||||
|
||||
/* 过渡动画 @see https://theme-plume.vuejs.press/config/basic/#transition */
|
||||
// transition: {
|
||||
// page: true, // 启用 页面间跳转过渡动画
|
||||
// postList: true, // 启用 博客文章列表过渡动画
|
||||
// appearance: 'fade', // 启用 深色模式切换过渡动画, 或配置过渡动画类型
|
||||
// },
|
||||
|
||||
})
|
||||
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
86
newdocs/docs/.vuepress/theme/components/AsideNav.vue
Normal file
@@ -0,0 +1,86 @@
|
||||
<!--
|
||||
* @Author: yubaolee <yubaolee@163.com> | ahfu~ <954478625@qq.com>
|
||||
* @Date: 2025-04-26 14:59:00
|
||||
* @LastEditTime: 2025-04-26 15:02:32
|
||||
* @Description: 右下角导航
|
||||
* Copyright (c) 2025 by yubaolee | ahfu~ , All Rights Reserved.
|
||||
-->
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { VPLink } from 'vuepress-theme-plume/client'
|
||||
import { useRouteLocale } from 'vuepress/client'
|
||||
|
||||
interface Locale {
|
||||
star: string
|
||||
issue: string
|
||||
sponsor: string
|
||||
}
|
||||
|
||||
const locales: Record<string, Locale> = {
|
||||
'/': { star: '在 gitee 上 Star', issue: '遇到问题?', sponsor: '喝杯奶茶' },
|
||||
'/en/': { star: 'Star on GitHub', issue: 'Create Issues', sponsor: 'Buy me a Bubble Tea' },
|
||||
}
|
||||
|
||||
const lang = useRouteLocale()
|
||||
const locale = computed(() => locales[lang.value])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="aside-nav-wrapper">
|
||||
<VPLink class="link" no-icon href="https://gitee.com/dotnetchina/OpenAuth.Net">
|
||||
<span class="vpi-github-star" />
|
||||
<span class="link-text">{{ locale.star }}</span>
|
||||
<span class="vpi-arrow-right" />
|
||||
</VPLink>
|
||||
<VPLink class="link" no-icon href="https://gitee.com/dotnetchina/OpenAuth.Net/issues/new">
|
||||
<span class="vpi-github-issue" />
|
||||
<span class="link-text">{{ locale.issue }}</span>
|
||||
<span class="vpi-arrow-right" />
|
||||
</VPLink>
|
||||
<!-- <VPLink class="link" href="/sponsor/">
|
||||
<span class="vpi-bubble-tea" />
|
||||
<span class="link-text">{{ locale.sponsor }}</span>
|
||||
<span class="vpi-arrow-right" />
|
||||
</VPLink> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.aside-nav-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 8px 0;
|
||||
margin: 16px 16px 0;
|
||||
border-top: solid 1px var(--vp-c-divider);
|
||||
}
|
||||
|
||||
.aside-nav-wrapper .link {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
color: var(--vp-c-text-2);
|
||||
transition: color var(--vp-t-color);
|
||||
}
|
||||
|
||||
.aside-nav-wrapper .link:hover {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.aside-nav-wrapper .link .link-text {
|
||||
flex: 1 2;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.vpi-github-star {
|
||||
--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m12 1.5l3.1 6.3l6.9 1l-5 4.8l1.2 6.9l-6.2-3.2l-6.2 3.2L7 13.6L2 8.8l6.9-1z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.vpi-github-issue {
|
||||
--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath fill='%23000' d='M8 9.5a1.5 1.5 0 1 0 0-3a1.5 1.5 0 0 0 0 3'/%3E%3Cpath fill='%23000' d='M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0M1.5 8a6.5 6.5 0 1 0 13 0a6.5 6.5 0 0 0-13 0'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.vpi-bubble-tea {
|
||||
--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m17.95 9l-1.478 8.69c-.25 1.463-.374 2.195-.936 2.631c-1.2.931-6.039.88-7.172 0c-.562-.436-.687-1.168-.936-2.632L5.95 9M6 9l.514-1.286a5.908 5.908 0 0 1 10.972 0L18 9M5 9h14m-7 0l4-7m-5.99 12h.01m1 4h.01m1.99-2h.01'/%3E%3C/svg%3E");
|
||||
}
|
||||
</style>
|
||||
11
newdocs/docs/.vuepress/theme/components/Custom.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const message = ref('Hello World!')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="my-custom-content">
|
||||
{{ message }}
|
||||
</div>
|
||||
</template>
|
||||