系列目錄javascript
前言:因爲工做緣由工做流一直沒時間更新,雖然沒有更新,可是批閱和申請差很少,改變一下數據的狀態字段就行,有幾個園友已經率先完成了html
說句實話,一個工做流用文章表達很難,我起初覺得這是一個很簡單的工做流程,可是要花不少時間考慮不少業務場景,這也是致使停滯不前的緣由。java
最近空出點時時間更新了皮膚,讓系統看起來奇葩一點,順便也把工做流梳理了一遍,最後跑通了整個流程的多個場景完成從提交表單到審批駁回結束流程json
事隔已久須要從新梳理流程,辣麼開始吧(因爲我本身更新了皮膚,截圖與以前有點不同,可是除UI層以外其餘仍是同樣的)ide
1.開始代碼以前須要更新個枚舉,這樣不容易出錯post
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 } }
有時間就要把那些123換成枚舉值fetch
2.審批列表ui
經過 起草新申請 將得到這個頁面的列表url
[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); }
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); }
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; }
@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>
依次添加沒有難度spa
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)); } }
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
涉及重置全部步驟的狀態存儲過程。
代碼分析:
1.獲取當前步驟
2.得到當前的步驟模板
3.駁回直接終止審覈(重置全部步驟的狀態)
4.會籤,得到同步驟的同批審覈人