構建ASP.NET MVC5+EF6+EasyUI 1.4.3+Unity4.x注入的后臺管理系統(53)-工作流設計-我的批閱
系列目錄
前言 :由于工作原因工作流一直沒時間更新,雖然沒有更新,但是批閱和申請差不多,改變一下數據的狀態字段就行,有幾個園友已經率先完成了
說句實話,一個工作流用文章表達很難,我起初以為這是一個很簡單的工作流程,但是要花很多時間考慮很多業務場景,這也是導致停滯不前的原因。
最近空出點時時間更新了皮膚,讓系統看起來奇葩一點, 順便也把工作流梳理了一遍,最后跑通了整個流程的多個場景完成從提交表單到審批駁回結束流程
事隔已久需要重新梳理流程,辣么開始吧(由于我自己更新了皮膚,截圖與之前有點不一樣,但是除UI層之外其他還是一樣的)
1.開始代碼之前需要更新個枚舉,這樣不容易出錯
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Apps.Models.Enum
{
public enum FlowStateEnum
{
/// <summary>
/// 駁回
/// </summary>
Reject =0,
/// <summary>
/// 通過
/// </summary>
Pass = 1,
/// <summary>
/// 進行中
/// </summary>
Progress =2,
/// <summary>
/// 關閉
/// </summary>
Closed = 3
}
public enum FlowRuleEnum
{
/// <summary>
/// 上級
/// </summary>
Lead =1,
/// <summary>
/// 人員
/// </summary>
Person = 2,
/// <summary>
/// 自選
/// </summary>
Customer = 3,
/// <summary>
/// 職位
/// </summary>
Position = 4,
/// <summary>
/// 部門
/// </summary>
Department =5,
}
public enum FlowFormLevelEnum
{
/// <summary>
/// 普通
/// </summary>
Ordinary = 1,
/// <summary>
/// 重要
/// </summary>
Major = 2,
/// <summary>
/// 緊急
/// </summary>
Urgent =3
}
}
FlowStateEnum.cs 有時間就要把那些123換成枚舉值
2.審批列表
通過起草新申請將獲得這個頁面的列表
[HttpPost]
public JsonResult GetListByUserId(GridPager pager, string queryStr)
{
List<Flow_FormContentModel> list = formContentBLL.GeExaminetListByUserId(ref pager, queryStr, GetUserId());
var json = new
{
total = pager.totalRows,
rows = (from r in list
select new Flow_FormContentModel()
{
Id = r.Id,
Title = r.Title,
UserId = r.UserId,
FormId = r.FormId,
FormLevel = r.FormLevel,
CreateTime = r.CreateTime,
TimeOut = r.TimeOut,
CurrentStep = formContentBLL.GetCurrentFormStep(r),
CurrentState = formContentBLL.GetCurrentFormState(r),
Action = "<a href='#' title='管理' onclick='ManageFlow(\"" + r.Title + "\",\"" + r.FormId + "\",\"" + r.Id + "\")'>管理</a> | <a href='#' title='圖例' onclick='LookFlow(\"" + r.FormId + "\")'>圖例</a>"
}).ToArray()
};
return Json(json);
}
Controller public List<Flow_FormContentModel> GeExaminetListByUserId(ref GridPager pager, string queryStr, string userId)
{
IQueryable<Flow_FormContent> queryData = null;
if (!string.IsNullOrWhiteSpace(queryStr))
{
queryData = m_Rep.GeExamineListByUserId(db, userId).Where(a => a.Title.Contains(queryStr));
}
else
{
queryData = m_Rep.GeExamineListByUserId(db, userId);
}
pager.totalRows = queryData.Count();
queryData = LinqHelper.SortingAndPaging(queryData, pager.sort, pager.order, pager.page, pager.rows);
return CreateModelList(ref queryData);
}
BLL public List<Flow_FormContentModel> GeExaminetListByUserId(ref GridPager pager, string queryStr, string userId)
{
IQueryable<Flow_FormContent> queryData = null;
if (!string.IsNullOrWhiteSpace(queryStr))
{
queryData = m_Rep.GeExamineListByUserId(db, userId).Where(a => a.Title.Contains(queryStr));
}
else
{
queryData = m_Rep.GeExamineListByUserId(db, userId);
}
pager.totalRows = queryData.Count();
queryData = LinqHelper.SortingAndPaging(queryData, pager.sort, pager.order, pager.page, pager.rows);
return CreateModelList(ref queryData);
}
private List<Flow_FormContentModel> CreateModelList(ref IQueryable<Flow_FormContent> queryData)
{
List<Flow_FormContentModel> modelList = (from r in queryData
select new Flow_FormContentModel
{
Id = r.Id,
Title = r.Title,
UserId = r.UserId,
FormId = r.FormId,
FormLevel = r.FormLevel,
CreateTime = r.CreateTime,
AttrA = r.AttrA,
AttrB = r.AttrB,
AttrC = r.AttrC,
AttrD = r.AttrD,
AttrE = r.AttrE,
AttrF = r.AttrF,
AttrG = r.AttrG,
AttrH = r.AttrH,
AttrI = r.AttrI,
AttrJ = r.AttrJ,
AttrK = r.AttrK,
AttrL = r.AttrL,
AttrM = r.AttrM,
AttrN = r.AttrN,
AttrO = r.AttrO,
AttrP = r.AttrP,
AttrQ = r.AttrQ,
AttrR = r.AttrR,
AttrS = r.AttrS,
AttrT = r.AttrT,
AttrU = r.AttrU,
AttrV = r.AttrV,
AttrW = r.AttrW,
AttrX = r.AttrX,
AttrY = r.AttrY,
AttrZ = r.AttrZ,
CustomMember = r.CustomMember,
TimeOut = r.TimeOut
}).ToList();
return modelList;
}
DAL @using Apps.Web.Core;
@using Apps.Common;
@using Apps.Models.Sys;
@using Apps.Models.Enum;
@using Apps.Locale;
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Index_Layout.cshtml";
List<permModel> perm = (List<permModel>)ViewBag.Perm;
if (perm == null)
{
perm = new List<permModel>();
}
}
<table id="List"></table>
<div id="modalwindow" class="easyui-window" data-options="modal:true,closed:true,minimizable:false,shadow:false"></div>
@Html.Partial("~/Views/Shared/_Partial_AutoGrid.cshtml")
<script type="text/javascript">
$(function () {
$('#List').datagrid({
url: '@Url.Action("GetListByUserId")',
width: SetGridWidthSub(10),
methord: 'post',
height: SetGridHeightSub(39),
fitColumns: true,
sortName: 'CreateTime',
sortOrder: 'desc',
idField: 'Id',
pageSize: 15,
pageList: [15, 20, 30, 40, 50],
pagination: true,
striped: true, //奇偶行是否區分
singleSelect: true,//單選模式
rownumbers: true,//行號
columns: [[
{ field: 'Id', title: '@BaseRes.TitleID', width: 80, hidden: true },
{ field: 'Title', title: '標題', width: 280, sortable: true },
{ field: 'UserId', title: '發起用戶', width: 80, sortable: true, hidden: true },
{ field: 'FormId', title: '對應表單', width: 80, sortable: true, hidden: true },
{ field: 'FormLevel', title: '公文級別', width: 80, sortable: true,align:'center',
formatter: function (value) {
if(value==@((int)FlowFormLevelEnum.Ordinary)){return "<span>普通</span>";}
if(value==@((int)FlowFormLevelEnum.Major)){return "<span class='color-yellow'>重要/span>";}
if(value==@((int)FlowFormLevelEnum.Urgent)){return "<span class='color-red'>緊急</span>";}
return "";
}
},
{ field: 'CreateTime', title: '@BaseRes.TitleCreateTime', width: 110, sortable: true},
{ field: 'TimeOut', title: '截至時間', width: 80, sortable: true, formatter: function (value) { return SubStrYMD(value) } },
{ field: 'CurrentStep', title: '當前環節', width: 80, sortable: true, align: 'center' },
{
field: 'CurrentState', title: '當前狀態', width: 80, sortable: true, align: 'center',
formatter: function (value, row, index) {
var _pass = "<span class='color-green fa fa-circle'></span>";
var _progress = "<span class='color-blue fa fa-circle'></span>";
var _reject = "<span class='color-red fa fa-circle'></span>";
var _close = "<span class='color-gray fa fa-circle'></span>";
if(value==@((int)FlowStateEnum.Pass)){ return _pass;}
if(value==@((int)FlowStateEnum.Progress)){ return _progress;}
if(value==@((int)FlowStateEnum.Reject)){ return _reject;}
return _close;
}
},
{ field: 'Action', title: '操作', width: 80, sortable: true, align: 'center' }
]]
});
});
//ifram 返回
function frameReturnByClose() {
$("#modalwindow").window('close');
}
function frameReturnByReload(flag) {
if (flag)
$("#List").datagrid('load');
else
$("#List").datagrid('reload');
}
function frameReturnByMes(mes) {
$.messageBox5s('@BaseRes.Tip', mes);
}
function LookFlow(formId) {
$("#modalwindow").html("<iframe width='100%' height='100%' scrolling='auto' frameborder='0' src='@Url.Action("Details")?id=" + formId + "&Ieguid=" + GetGuid() + "'></iframe>");
$("#modalwindow").window({ title: '圖例', width: 500, height: 380, iconCls: 'fa fa-list' }).window('open');
}
function ManageFlow(title, formId, id) {
var href = "@Url.Action("Edit")?formId=" + formId + "&id=" + id + "&Ieguid=" + GetGuid() + "";
if(isExitsFunction(window.parent.addTab))
{
window.parent.addTab(title, href, 'fa fa-pencil');
}else
{
window.open(href);
}
}
</script>
Index.cshtml 依次添加沒有難度
3.審批頁面
審批頁面基本和我的申請的編輯一致
4.先看看審批的代碼執行流程圖:
審批有點難度,需要覆蓋上面圖示流程。以下代碼
[HttpPost]
[SupportFilter]
public JsonResult Edit(string Remark, string TheSeal, string FormId, int Flag, string ContentId,string UserList)
{
string stepCheckId = formContentBLL.GetCurrentStepCheckId(FormId, ContentId);
if (stepCheckId == "")
{
return Json(JsonHandler.CreateMessage(0, BaseRes.EditFail));
}
Flow_FormContentStepCheckStateModel stepCheckStateModel = stepCheckStateBLL.GetByStepCheckId(stepCheckId);
if (stepCheckStateModel.UserId != GetUserId())
{
return Json(JsonHandler.CreateMessage(0, "越權操作!"));
}
stepCheckStateModel.Reamrk = Remark;
stepCheckStateModel.TheSeal = TheSeal;
stepCheckStateModel.CheckFlag = Flag;
if (stepCheckStateBLL.Edit(ref errors, stepCheckStateModel))
{
//獲取當前步驟
Flow_FormContentStepCheckModel stepCheckModel = stepCheckBLL.GetById(stepCheckStateModel.StepCheckId);
//獲得當前的步驟模板
Flow_StepModel currentStepModel = stepBLL.GetById(stepCheckModel.StepId);
//駁回直接終止審核
if(Flag==(int)FlowStateEnum.Reject)
{
stepCheckModel.State = Flag;
stepCheckModel.StateFlag = false;
stepCheckBLL.Edit(ref errors, stepCheckModel);
//重置所有步驟的狀態
stepCheckBLL.ResetCheckStateByFormCententId(ContentId, (int)FlowStateEnum.Progress, (int)FlowStateEnum.Progress);
LogHandler.WriteServiceLog(GetUserId(), "Id" + stepCheckStateModel.Id + ",StepCheckId" + stepCheckStateModel.Reamrk, "成功", "修改", "Flow_FormContentStepCheckState");
return Json(JsonHandler.CreateMessage(1, BaseRes.CheckSucceed));
}
else if (currentStepModel.IsAllCheck)
{
//啟用會簽
//獲得同步驟的同批審核人
List<Flow_FormContentStepCheckStateModel> stepCheckStateList = stepCheckStateBLL.GetListByStepCheckId(ref setNoPagerAscById, stepCheckStateModel.StepCheckId);
//查看自己是否是最后一個審核人
bool complete = stepCheckStateList.Where(a => a.CheckFlag == (int)FlowStateEnum.Progress).Count() == 1;
if (complete)
{
stepCheckModel.State = Flag;
stepCheckModel.StateFlag = true;
stepCheckBLL.Edit(ref errors, stepCheckModel);
}
else {
//讓審核人繼續執行這個步驟直到完成
LogHandler.WriteServiceLog(GetUserId(), "Id" + stepCheckStateModel.Id + ",StepCheckId" + stepCheckStateModel.Reamrk, "成功", "修改", "Flow_FormContentStepCheckState");
return Json(JsonHandler.CreateMessage(1, BaseRes.CheckSucceed));
}
}
else
{
//不是會簽,任何一個審批都通過
stepCheckModel.State = Flag;
stepCheckModel.StateFlag = true;
stepCheckBLL.Edit(ref errors, stepCheckModel);
}
if (!stepCheckModel.IsEnd)
{
List<Flow_FormContentStepCheckModel> stepCheckList = stepCheckBLL.GetListByFormId(FormId, ContentId);
int j = 0;
for (int i = stepCheckList.Count() - 1; i >= 0; i--)
{
if (stepCheckId == stepCheckList[i].Id)
{
j = i;
}
}
//查看是否還有下一步步驟
if(j-1<=stepCheckList.Count())
{
//查有第二步驟,查看是否是自選
Flow_StepModel stepModel = stepBLL.GetById(stepCheckList[j + 1].StepId);
if (stepModel.FlowRule==(int)FlowRuleEnum.Customer)
{
foreach (string userId in UserList.Split(','))
{
//批量建立步驟審核人表
CreateCheckState(stepCheckList[j + 1].Id, userId);
}
}
else {
//批量建立審核人員表
foreach (string userId in GetStepCheckMemberList(stepCheckList[j + 1].StepId))
{
//批量建立步驟審核人表
CreateCheckState(stepCheckList[j + 1].Id, userId);
}
}
}
}
LogHandler.WriteServiceLog(GetUserId(), "Id" + stepCheckStateModel.Id + ",StepCheckId" + stepCheckStateModel.Reamrk, "成功", "修改", "Flow_FormContentStepCheckState");
return Json(JsonHandler.CreateMessage(1, BaseRes.CheckSucceed));
}
else
{
string ErrorCol = errors.Error;
LogHandler.WriteServiceLog(GetUserId(), "Id" + stepCheckStateModel.Id + ",StepCheckId" + stepCheckStateModel.Reamrk + "," + ErrorCol, "失敗", "修改", "Flow_FormContentStepCheckState");
return Json(JsonHandler.CreateMessage(0, BaseRes.CheckFail + ErrorCol));
}
}
View Code USE [AppsDB]
GO
/****** Object: StoredProcedure [dbo].[P_Flow_ResetCheckStepState] Script Date: 2016/1/13 21:48:59 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
ALTER PROCEDURE [dbo].[P_Flow_ResetCheckStepState]
@ContentId varchar(50),
@CheckState int,
@CheckFlag int
AS
BEGIN
--重新設置當前表單步驟的狀態
update Flow_FormContentStepCheck set State=@CheckState where ContentId=@ContentId
--根據表單步驟設置其子下步驟分解的狀態
declare FormContentStepCheckState_Cursor cursor scroll for
select Id from Flow_FormContentStepCheckState where StepCheckId in
(
select Id from Flow_FormContentStepCheck where ContentId=@ContentId
)
open FormContentStepCheckState_Cursor
declare @tempId varchar(50)
fetch next from FormContentStepCheckState_Cursor into @tempId
while @@FETCH_STATUS=0
begin
update Flow_FormContentStepCheckState set CheckFlag=@CheckFlag where Id=@tempId
fetch next from FormContentStepCheckState_Cursor into @tempId
end
close FormContentStepCheckState_Cursor
deallocate FormContentStepCheckState_Cursor
END
P_Flow_ResetCheckStepState 涉及重置所有步驟的狀態存儲過程。
代碼分析:
1.獲取當前步驟
2.獲得當前的步驟模板
3.駁回直接終止審核(重置所有步驟的狀態)
4.會簽,獲得同步驟的同批審核人
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!