mirror of
https://gitee.com/dotnetchina/OpenAuth.Net.git
synced 2026-07-28 06:07:59 +08:00
Compare commits
11 Commits
d2c8f783e1
...
7a34fa7c51
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a34fa7c51 | ||
|
|
62babb205c | ||
|
|
a222959efe | ||
|
|
0340fb224f | ||
|
|
1a43adb9a6 | ||
|
|
cbb43f0011 | ||
|
|
9aac53b3eb | ||
|
|
bfe9bf2481 | ||
|
|
ab41783e9f | ||
|
|
fd4a328a72 | ||
|
|
17f0e402ac |
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: dev
|
||||
description: OpenAuth.Net开发规范
|
||||
description: OpenAuth.Net后端开发规范
|
||||
---
|
||||
|
||||
## 编码规范
|
||||
|
||||
25
CheckAndKillPort52789.bat
Normal file
25
CheckAndKillPort52789.bat
Normal file
@@ -0,0 +1,25 @@
|
||||
@echo off
|
||||
chcp 936
|
||||
setlocal enabledelayedexpansion
|
||||
echo <20><><EFBFBD>ڼ<EFBFBD><DABC><EFBFBD>52789<38>˿<EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
||||
|
||||
rem <20><><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC>52789<38>˿ڵĽ<DAB5><C4BD><EFBFBD>
|
||||
FOR /F "tokens=5" %%i IN ('netstat -ano ^| findstr :52789 ^| findstr LISTENING') DO (
|
||||
SET pid=%%i
|
||||
echo <20><><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC>52789<38>˿ڵĽ<DAB5><C4BD>̣<EFBFBD>PID: %%i
|
||||
echo <20><><EFBFBD>ڲ<EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ...
|
||||
tasklist | findstr %%i
|
||||
|
||||
echo <20><><EFBFBD>ڽ<EFBFBD><DABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %%i...
|
||||
taskkill /F /PID %%i
|
||||
|
||||
echo <20><>֤<EFBFBD>˿<EFBFBD><CBBF>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ͷ<EFBFBD>...
|
||||
netstat -ano | findstr :52789
|
||||
goto :END
|
||||
)
|
||||
|
||||
echo δ<><CEB4><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC>52789<38>˿ڵĽ<DAB5><C4BD>̡<EFBFBD>
|
||||
|
||||
:END
|
||||
echo <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɡ<EFBFBD>
|
||||
pause
|
||||
@@ -6,7 +6,7 @@
|
||||
public struct FlowInstanceStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// 撤销、召回
|
||||
/// 召回
|
||||
/// </summary>
|
||||
public const int Draft = -1;
|
||||
/// <summary>
|
||||
|
||||
@@ -10,6 +10,16 @@
|
||||
|
||||
public string name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 节点类型
|
||||
/// <para>
|
||||
/// start:开始节点
|
||||
/// end:结束节点
|
||||
/// node:普通节点
|
||||
/// fork:网关开始
|
||||
/// join:网关结束
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public string type { get; set; }
|
||||
|
||||
public int left { get; set; }
|
||||
@@ -47,10 +57,29 @@
|
||||
/// </summary>
|
||||
public string NodeRejectType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 审批标记:1通过,2不通过,3驳回
|
||||
/// </summary>
|
||||
public int? Taged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 审批人名称
|
||||
/// </summary>
|
||||
public string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 审批人ID
|
||||
/// </summary>
|
||||
public string UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 审批意见
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 审批时间
|
||||
/// </summary>
|
||||
public string TagedTime { get; set; }
|
||||
|
||||
//网关审批通过的方式,
|
||||
|
||||
@@ -267,6 +267,8 @@ namespace OpenAuth.App.Flow
|
||||
isFirst = false;
|
||||
break;
|
||||
}
|
||||
|
||||
preNode = GetPreNode(preNode.id);
|
||||
}
|
||||
|
||||
if (isFirst)
|
||||
@@ -400,13 +402,22 @@ namespace OpenAuth.App.Flow
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 撤销流程,清空所有节点
|
||||
/// 召回流程,清空所有节点,返回开始节点并修改为草稿状态
|
||||
/// </summary>
|
||||
public void ReCall(RecallFlowInstanceReq request)
|
||||
{
|
||||
foreach (var item in Nodes)
|
||||
{
|
||||
item.Value.setInfo = null;
|
||||
if (item.Value.setInfo != null)
|
||||
{
|
||||
item.Value.setInfo.Taged = null;
|
||||
item.Value.setInfo.UserName = null;
|
||||
item.Value.setInfo.UserId = null;
|
||||
item.Value.setInfo.Description = null;
|
||||
item.Value.setInfo.TagedTime = null;
|
||||
item.Value.setInfo.ConfluenceOk = null;
|
||||
item.Value.setInfo.ConfluenceNo = null;
|
||||
}
|
||||
}
|
||||
|
||||
flowInstance.IsFinish = FlowInstanceStatus.Draft;
|
||||
@@ -414,17 +425,18 @@ namespace OpenAuth.App.Flow
|
||||
flowInstance.ActivityId = startNodeId;
|
||||
flowInstance.ActivityName = Nodes[startNodeId].name;
|
||||
flowInstance.MakerList = GetNodeMarkers(Nodes[startNodeId], flowInstance.CreateUserId);
|
||||
flowInstance.SchemeContent = JsonHelper.Instance.Serialize(ToSchemeObj());
|
||||
|
||||
var sugarClient = AutofacContainerModule.GetService<ISqlSugarClient>();
|
||||
sugarClient.Updateable(flowInstance).ExecuteCommand();
|
||||
|
||||
SaveOperationHis($"【撤回】备注:{request.Description}");
|
||||
SaveOperationHis($"【召回】备注:{request.Description}");
|
||||
|
||||
sugarClient.Ado.CommitTran();
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// 标记节点1通过,-1不通过,0驳回
|
||||
/// 标记节点1通过,2不通过,3驳回
|
||||
/// </summary>
|
||||
/// <param name="nodeId"></param>
|
||||
public void MakeTagNode(string nodeId, Tag tag)
|
||||
@@ -448,6 +460,9 @@ namespace OpenAuth.App.Flow
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为流程方案对象
|
||||
/// </summary>
|
||||
public object ToSchemeObj()
|
||||
{
|
||||
return new
|
||||
@@ -583,8 +598,11 @@ namespace OpenAuth.App.Flow
|
||||
#region 获取节点审批人
|
||||
|
||||
/// <summary>
|
||||
/// 寻找下一步的执行人
|
||||
/// 一般用于本节点审核完成后,修改流程实例的当前执行人,可以做到通知等功能
|
||||
/// 计算流程推进到下一步时的执行人
|
||||
/// <para>创建流程实例(Add):新建流程后计算第一个审批人</para>
|
||||
/// <para>网关审批完成(VerifyGatewayStart):网关结束后推进到下一节点</para>
|
||||
/// <para>普通节点审批通过(VerifyNode):审批同意后推进到下一节点</para>
|
||||
/// <para>启动草稿流程(Start):草稿变为运行状态,计算下一执行人</para>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetNextMakers(NodeDesignateReq request = null)
|
||||
@@ -598,11 +616,13 @@ namespace OpenAuth.App.Flow
|
||||
//如果request为空,则应该是草稿状态变为启动,或为网关节点,使用nextNode的setInfo
|
||||
if (request == null)
|
||||
{
|
||||
request = new NodeDesignateReq
|
||||
{
|
||||
NodeDesignateType = nextNode.setInfo.NodeDesignate,
|
||||
NodeDesignates = nextNode.setInfo.NodeDesignateData.datas
|
||||
};
|
||||
request = new NodeDesignateReq();
|
||||
}
|
||||
|
||||
//从url审批过来的,request不为空,但是这两个属性是空的
|
||||
if(request.NodeDesignateType == null || request.NodeDesignates == null){
|
||||
request.NodeDesignateType = nextNode.setInfo.NodeDesignate;
|
||||
request.NodeDesignates = nextNode.setInfo.NodeDesignateData.datas;
|
||||
}
|
||||
|
||||
if (GetNextNodeType() == Define.NODE_TYPE_FORK) //如果是网关节点
|
||||
@@ -621,9 +641,7 @@ namespace OpenAuth.App.Flow
|
||||
throw new Exception("前端提交的节点权限类型异常,请检查流程");
|
||||
}
|
||||
|
||||
var revelanceApp = AutofacContainerModule.GetService<RevelanceManagerApp>();
|
||||
var users = revelanceApp.Get(Define.USERROLE, false, request.NodeDesignates);
|
||||
makerList = GenericHelpers.ArrayToString(users, makerList);
|
||||
makerList = ResolveDesignateUsers(Define.SPECIAL_ROLE, request.NodeDesignates);
|
||||
}
|
||||
else if (nextNode.setInfo.NodeDesignate == Define.RUNTIME_SPECIAL_USER)
|
||||
{
|
||||
@@ -633,7 +651,7 @@ namespace OpenAuth.App.Flow
|
||||
throw new Exception("前端提交的节点权限类型异常,请检查流程");
|
||||
}
|
||||
|
||||
makerList = GenericHelpers.ArrayToString(request.NodeDesignates, makerList);
|
||||
makerList = ResolveDesignateUsers(Define.SPECIAL_USER, request.NodeDesignates);
|
||||
}
|
||||
else if (nextNode.setInfo.NodeDesignate == Define.SPECIAL_SQL)
|
||||
{
|
||||
@@ -643,10 +661,7 @@ namespace OpenAuth.App.Flow
|
||||
throw new Exception("前端提交的节点权限类型异常,请检查流程");
|
||||
}
|
||||
|
||||
var sql = ReplaceSql(nextNode.setInfo.NodeDesignateData.datas[0]);
|
||||
var sugarClient = AutofacContainerModule.GetService<ISqlSugarClient>();
|
||||
var result = sugarClient.Ado.SqlQuery<string>(sql);
|
||||
makerList = GenericHelpers.ArrayToString(result, makerList);
|
||||
makerList = ResolveDesignateUsers(Define.SPECIAL_SQL, nextNode.setInfo.NodeDesignateData.datas);
|
||||
}
|
||||
else if (nextNode.setInfo.NodeDesignate == Define.RUNTIME_PARENT
|
||||
|| nextNode.setInfo.NodeDesignate == Define.RUNTIME_MANY_PARENTS)
|
||||
@@ -693,6 +708,99 @@ namespace OpenAuth.App.Flow
|
||||
return makerList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取节点审批人
|
||||
/// <para>回退/查询"场景,回答"这个节点设计时配了谁来审"</para>
|
||||
/// <para>驳回到指定节点(RejectNode):流程被驳回时,需要重新计算目标节点的审批人</para>
|
||||
/// <para>召回流程(ReCall):将流程撤回到开始节点,用创建人ID算出审批人</para>
|
||||
/// <para>撤销审批(UndoVerification):恢复上一个节点的审批人</para>
|
||||
/// <para>网关分支中查找可审核节点(GetOneForkLineCanCheckNodeId):遍历分支判断当前用户是否有权审核</para>
|
||||
/// <para>网关分支获取审核者(GetOneForkLineMakers):找到分支线上下一个待审人</para>
|
||||
/// </summary>
|
||||
public string GetNodeMarkers(FlowNode node, string flowinstanceCreateUserId = "")
|
||||
{
|
||||
string makerList = "";
|
||||
if (node.type == Define.NODE_TYPE_START && (!string.IsNullOrEmpty(flowinstanceCreateUserId))) //如果是开始节点,通常情况下是驳回到开始了
|
||||
{
|
||||
makerList = flowinstanceCreateUserId;
|
||||
}
|
||||
else if (node.setInfo != null)
|
||||
{
|
||||
if (node.setInfo.NodeDesignate == Define.RUNTIME_SPECIAL_ROLE
|
||||
|| node.setInfo.NodeDesignate == Define.RUNTIME_SPECIAL_USER)
|
||||
{
|
||||
//如果是运行时选定的用户,则暂不处理。由上个节点审批时选定
|
||||
}
|
||||
else if (node.setInfo.NodeDesignate == Define.RUNTIME_PARENT
|
||||
|| node.setInfo.NodeDesignate == Define.RUNTIME_MANY_PARENTS)
|
||||
{
|
||||
//驳回/撤销场景:找到目标节点的前一个节点的执行人,以其为基准计算直属上级
|
||||
var preNode = GetPreNode(node.id);
|
||||
var preNodeUserId = preNode.setInfo?.UserId;
|
||||
if (!string.IsNullOrEmpty(preNodeUserId))
|
||||
{
|
||||
var userManagerApp = AutofacContainerModule.GetService<UserManagerApp>();
|
||||
var parentId = userManagerApp.GetParent(preNodeUserId);
|
||||
if (!StringExtension.IsNullOrEmpty(parentId))
|
||||
{
|
||||
makerList = GenericHelpers.ArrayToString(new[] { parentId }, makerList);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (node.setInfo.NodeDesignate == Define.RUNTIME_CHAIRMAN)
|
||||
{
|
||||
//驳回/撤销场景:获取发起人的部门负责人
|
||||
var orgManagerApp = AutofacContainerModule.GetService<OrgManagerApp>();
|
||||
var chairmanIds = orgManagerApp.GetChairmanId(node.setInfo.NodeDesignateData?.datas);
|
||||
makerList = GenericHelpers.ArrayToString(chairmanIds, makerList);
|
||||
}
|
||||
else
|
||||
{
|
||||
makerList = ResolveDesignateUsers(node.setInfo.NodeDesignate, node.setInfo.NodeDesignateData?.datas);
|
||||
}
|
||||
}
|
||||
else //如果没有设置节点信息,属于流程设计异常
|
||||
{
|
||||
throw new Exception($"节点【{node.name}】未设置审批人信息,请检查流程设计!");
|
||||
}
|
||||
|
||||
return makerList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据指定类型和指定数据解析审批人列表(公共辅助方法)
|
||||
/// </summary>
|
||||
/// <param name="designateType">节点指定类型</param>
|
||||
/// <param name="designateData">节点指定数据</param>
|
||||
/// <returns>审批人列表字符串</returns>
|
||||
private string ResolveDesignateUsers(string designateType, string[] designateData)
|
||||
{
|
||||
string makerList = "";
|
||||
if (string.IsNullOrEmpty(designateType) || designateType == Define.ALL_USER) //所有成员
|
||||
{
|
||||
makerList = "1";
|
||||
}
|
||||
else if (designateType == Define.SPECIAL_USER) //指定成员
|
||||
{
|
||||
makerList = GenericHelpers.ArrayToString(designateData, makerList);
|
||||
}
|
||||
else if (designateType == Define.SPECIAL_ROLE) //指定角色
|
||||
{
|
||||
var revelanceApp = AutofacContainerModule.GetService<RevelanceManagerApp>();
|
||||
var users = revelanceApp.Get(Define.USERROLE, false, designateData);
|
||||
makerList = GenericHelpers.ArrayToString(users, makerList);
|
||||
}
|
||||
else if (designateType == Define.SPECIAL_SQL) //指定SQL
|
||||
{
|
||||
var sql = ReplaceSql(designateData[0]);
|
||||
var sugarClient = AutofacContainerModule.GetService<ISqlSugarClient>();
|
||||
var result = sugarClient.Ado.SqlQuery<string>(sql);
|
||||
makerList = GenericHelpers.ArrayToString(result, makerList);
|
||||
}
|
||||
|
||||
return makerList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算多实例、会签节点的执行人
|
||||
/// </summary>
|
||||
@@ -762,57 +870,6 @@ namespace OpenAuth.App.Flow
|
||||
return GenericHelpers.ArrayToString(makerList, "");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 这里专门处理由前端选择相关的节点执行人
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
/// <returns></returns>
|
||||
public string GetNodeMarkers(FlowNode node, string flowinstanceCreateUserId = "")
|
||||
{
|
||||
string makerList = "";
|
||||
if (node.type == Define.NODE_TYPE_START && (!string.IsNullOrEmpty(flowinstanceCreateUserId))) //如果是开始节点,通常情况下是驳回到开始了
|
||||
{
|
||||
makerList = flowinstanceCreateUserId;
|
||||
}
|
||||
else if (node.setInfo != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(node.setInfo.NodeDesignate) ||
|
||||
node.setInfo.NodeDesignate == Define.ALL_USER) //所有成员
|
||||
{
|
||||
makerList = "1";
|
||||
}
|
||||
else if (node.setInfo.NodeDesignate == Define.SPECIAL_USER) //指定成员
|
||||
{
|
||||
makerList = GenericHelpers.ArrayToString(node.setInfo.NodeDesignateData.datas, makerList);
|
||||
}
|
||||
else if (node.setInfo.NodeDesignate == Define.SPECIAL_ROLE) //指定角色
|
||||
{
|
||||
var revelanceApp = AutofacContainerModule.GetService<RevelanceManagerApp>();
|
||||
var users = revelanceApp.Get(Define.USERROLE, false, node.setInfo.NodeDesignateData.datas);
|
||||
makerList = GenericHelpers.ArrayToString(users, makerList);
|
||||
}
|
||||
else if (node.setInfo.NodeDesignate == Define.SPECIAL_SQL) //指定SQL
|
||||
{
|
||||
//如果是指定SQL,则需要执行SQL,并返回结果
|
||||
var sql = ReplaceSql(node.setInfo.NodeDesignateData.datas[0]);
|
||||
var sugarClient = AutofacContainerModule.GetService<ISqlSugarClient>();
|
||||
var result = sugarClient.Ado.SqlQuery<string>(sql);
|
||||
makerList = GenericHelpers.ArrayToString(result, makerList);
|
||||
}
|
||||
else if (node.setInfo.NodeDesignate == Define.RUNTIME_SPECIAL_ROLE
|
||||
|| node.setInfo.NodeDesignate == Define.RUNTIME_SPECIAL_USER)
|
||||
{
|
||||
//如果是运行时选定的用户,则暂不处理。由上个节点审批时选定
|
||||
}
|
||||
}
|
||||
else //如果没有设置节点信息,默认所有人都可以审核
|
||||
{
|
||||
makerList = "1";
|
||||
}
|
||||
|
||||
return makerList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 替换SQL中的权限占位符
|
||||
/// <para>如当前用户的全部下属:select id from sysuser where parentId = {loginUser}</para>
|
||||
|
||||
@@ -103,22 +103,23 @@ namespace OpenAuth.App
|
||||
/// </summary>
|
||||
public FlowApprover[] GetApprovers(QueryApproverReq req)
|
||||
{
|
||||
var query= Repository.AsQueryable()
|
||||
// 一次查询,内存中处理,避免 ISugarQueryable 状态污染
|
||||
var all = Repository.AsQueryable()
|
||||
.Where(u => u.InstanceId == req.FlowInstanceId
|
||||
&& u.ActivityId == req.ActivityId && u.Status == 0); //本节点待审批的加签人
|
||||
if (query.Count() == 0)
|
||||
&& u.ActivityId == req.ActivityId && u.Status == 0)
|
||||
.OrderBy(u => u.OrderNo)
|
||||
.ToArray();
|
||||
|
||||
if (all.Length == 0) return null;
|
||||
|
||||
// 顺序执行:只返回第一个
|
||||
if (all[0].ApproveType == Define.APPROVE_TYPE_SEQUENTIAL)
|
||||
{
|
||||
return null;
|
||||
return new[] { all[0] };
|
||||
}
|
||||
|
||||
//如果是顺序执行,取第一个人
|
||||
if (query.First().ApproveType == Define.APPROVE_TYPE_SEQUENTIAL)
|
||||
{
|
||||
var result = query.OrderBy(u => u.OrderNo).First();
|
||||
return new[] { result };
|
||||
}
|
||||
//否则并行且/并行或都是返回所有加签人
|
||||
return query.ToArray();
|
||||
|
||||
// 并行且/并行或:返回全部
|
||||
return all;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: yubaolee <yubaolee@163.com> | ahfu~ <954478625@qq.com>
|
||||
* @Date: 2024-12-13 16:55:17
|
||||
* @Description: 工作流实例表操作
|
||||
* @LastEditTime: 2025-10-18 14:35:01
|
||||
* @LastEditTime: 2026-06-11 22:35:03
|
||||
* Copyright (c) 2024 by yubaolee | ahfu~ , All Rights Reserved.
|
||||
*/
|
||||
|
||||
@@ -512,6 +512,7 @@ namespace OpenAuth.App
|
||||
else //审批结果为不同意
|
||||
{
|
||||
flowInstance.IsFinish = FlowInstanceStatus.Disagree;
|
||||
flowInstance.MakerList = "";
|
||||
wfruntime.nextNodeId = "-1";
|
||||
}
|
||||
|
||||
@@ -520,7 +521,7 @@ namespace OpenAuth.App
|
||||
$"结果:{(tag.Taged == 1 ? "同意" : "不同意")},备注:{tag.Description}";
|
||||
wfruntime.SaveOperationHis(tag.UserId, tag.UserName, content);
|
||||
|
||||
if (flowInstance.IsFinish == 1)
|
||||
if (flowInstance.IsFinish == FlowInstanceStatus.Finished)
|
||||
{
|
||||
//给知会人员发送通知信息
|
||||
var userids = _userManagerApp.GetNoticeUsers(flowInstance.Id);
|
||||
@@ -592,20 +593,20 @@ namespace OpenAuth.App
|
||||
/// </summary>
|
||||
public void Verification(VerificationReq request)
|
||||
{
|
||||
TagState tagState = (TagState)Int32.Parse(request.VerificationFinally);
|
||||
//如果是同意,需要判断是否为运行时选定下一步执行角色/执行人
|
||||
if (request.VerificationFinally == "1")
|
||||
if (tagState == TagState.Ok)
|
||||
{
|
||||
CheckNodeDesignate(request);
|
||||
}
|
||||
|
||||
bool isReject = TagState.Reject.Equals((TagState)Int32.Parse(request.VerificationFinally));
|
||||
if (isReject) //驳回
|
||||
|
||||
if (tagState == TagState.Reject)
|
||||
{
|
||||
RejectNode(request);
|
||||
RejectNode(request); // 驳回
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeVerification(request);
|
||||
NodeVerification(request); // 审核(同意/不同意)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -660,7 +661,13 @@ namespace OpenAuth.App
|
||||
ActivityId = flowinstance.ActivityId
|
||||
});
|
||||
|
||||
if (flowinstance.MakerList != "1" && !flowinstance.MakerList.Contains(user.User.Id) &&
|
||||
//流程已终止(完成/不同意/撤销等),不允许继续审批
|
||||
if (flowinstance.IsFinish != FlowInstanceStatus.Running && flowinstance.IsFinish != FlowInstanceStatus.Rejected)
|
||||
{
|
||||
resp.CanVerify = false;
|
||||
}
|
||||
//当前用户不是当前节点的审批人,不允许继续审批
|
||||
else if (flowinstance.MakerList != "1" && !flowinstance.MakerList.Contains(user.User.Id) &&
|
||||
!approvers.Contains(user.User.Id))
|
||||
{
|
||||
resp.CanVerify = false;
|
||||
|
||||
@@ -48,6 +48,8 @@ namespace OpenAuth.App
|
||||
FrmUrlTemplate = flowScheme.FrmUrlTemplate,
|
||||
Disabled = flowScheme.Disabled,
|
||||
Description = flowScheme.Description,
|
||||
CreateDate = flowScheme.CreateDate,
|
||||
SchemeCode = flowScheme.SchemeCode,
|
||||
OrgId = flowScheme.OrgId
|
||||
},u => u.Id == flowScheme.Id);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!--
|
||||
* @Author: yubaolee <yubaolee@163.com> | ahfu~ <954478625@qq.com>
|
||||
* @Date: 2024-01-08 17:08:56
|
||||
* @LastEditTime: 2024-06-21 10:16:05
|
||||
* @LastEditTime: 2026-06-14 22:50:56
|
||||
* @Description:
|
||||
* @
|
||||
* @Copyright (c) 2024 by yubaolee | ahfu~ , All Rights Reserved.
|
||||
@@ -304,9 +304,20 @@ export default {
|
||||
const to = info.targetId
|
||||
|
||||
if (from === to) return false
|
||||
const filter = that.flowData.lines.filter(link => (link.from === from && link.to === to))
|
||||
const filter = that.flowData.lines.filter(link => (link.from === from && link.to === to)
|
||||
|| (link.from === to && link.to === from))
|
||||
if (filter.length > 0) {
|
||||
that.$message.error('同方向的两节点连线只能有一条!')
|
||||
that.$message.error('两节点连线只能有一条!')
|
||||
return false
|
||||
}
|
||||
|
||||
if(from.includes("end")){
|
||||
that.$message.error('结束节点不能作为起点!')
|
||||
return false
|
||||
}
|
||||
|
||||
if(to.includes("start")){
|
||||
that.$message.error('开始节点不能作为终点!')
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
||||
@@ -122,9 +122,13 @@ OpenAuth.Net工作流分为两个大类:
|
||||
|
||||
* 同意:流程审批通过,流程结束;
|
||||
|
||||
* 不同意:流程审批不通过,流程结束;
|
||||
* **不同意(拒绝 / 反对)**:审批人明确不批准本次申请,属于终结性意见。
|
||||
|
||||
* 驳回:可以驳回到指定的步骤,该步骤的人可以重新审批提交;
|
||||
* 结果:本次申请失败,流程结束,如果重新发起新流程。
|
||||
|
||||
* **驳回(退回 / 打回)**:审批人认为资料不全 / 有误,需要修改后重提,属于回退 + 重走动作。
|
||||
|
||||
* 结果:流程未终结,可修复后继续。
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ SelectUsersCom是一个用于选择用户或角色的组件,提供了两种使
|
||||
| users | Object | - | 初始选中项ID列表或对象列表 |
|
||||
| inType | String | 'id' | 父级传入的是id列表还是对象列表,取值为'id'或'obj' |
|
||||
| modelValue | Boolean | false | 控制对话框显示 |
|
||||
| single | Boolean | false | 是否单选,true时只能选择一个用户/角色 |
|
||||
|
||||
### 事件说明
|
||||
|
||||
@@ -87,6 +88,7 @@ const handleSave = () => {
|
||||
| userNames | String | '' | 用户名称(逗号分隔) |
|
||||
| placeholder | String | '' | 输入框占位符 |
|
||||
| ignoreAuth | Boolean | false | 是否忽略权限限制 |
|
||||
| single | Boolean | false | 是否单选,true时只能选择一个用户/角色 |
|
||||
|
||||
### 事件说明
|
||||
|
||||
|
||||
@@ -4,27 +4,47 @@ createTime: 2025/04/23 23:43:26
|
||||
permalink: /pro/start/
|
||||
---
|
||||
## 工具准备
|
||||
|
||||
#### NodeJs
|
||||
|
||||
前端环境为NodeJs,下载地址:[http://nodejs.cn/download/current/](http://nodejs.cn/download/current/)
|
||||
|
||||
#### visual studio code
|
||||
|
||||
下载最新版的vs code,或Cursor、Windsurf、Trae等工具用来作为OpenAuth.Net Vue3版的开发工具。
|
||||
|
||||
## 源码下载
|
||||
|
||||
根据授权文件的下载指示,下载Vue3源码。注意:一定要使用下图中的数据库脚本:
|
||||

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

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

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