系列目录

前言:由于工作原因工作流一直没时间更新,虽然没有更新,但是批阅和申请差不多,改变一下数据的状态字段就行,有几个园友已经率先完成了

说句实话,一个工作流用文章表达很难,我起初以为这是一个很简单的工作流程,但是要花很多时间考虑很多业务场景,这也是导致停滞不前的原因。

最近空出点时时间更新了皮肤,让系统看起来奇葩一点,顺便也把工作流梳理了一遍,最后跑通了整个流程的多个场景完成从提交表单到审批驳回结束流程

事隔已久需要重新梳理流程,辣么开始吧(由于我自己更新了皮肤,截图与之前有点不一样,但是除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 =,
/// <summary>
/// 通过
/// </summary>
Pass = , /// <summary>
/// 进行中
/// </summary>
Progress =, /// <summary>
/// 关闭
/// </summary>
Closed =
} public enum FlowRuleEnum
{
/// <summary>
/// 上级
/// </summary>
Lead =,
/// <summary>
/// 人员
/// </summary>
Person = ,
/// <summary>
/// 自选
/// </summary>
Customer = ,
/// <summary>
/// 职位
/// </summary>
Position = ,
/// <summary>
/// 部门
/// </summary>
Department =,
}
public enum FlowFormLevelEnum
{
/// <summary>
/// 普通
/// </summary>
Ordinary = ,
/// <summary>
/// 重要
/// </summary>
Major = ,
/// <summary>
/// 紧急
/// </summary>
Urgent = } }

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(),
methord: 'post',
height: SetGridHeightSub(),
fitColumns: true,
sortName: 'CreateTime',
sortOrder: 'desc',
idField: 'Id',
pageSize: ,
pageList: [, , , , ],
pagination: true,
striped: true, //奇偶行是否区分
singleSelect: true,//单选模式
rownumbers: true,//行号
columns: [[
{ field: 'Id', title: '@BaseRes.TitleID', width: , hidden: true },
{ field: 'Title', title: '标题', width: , sortable: true },
{ field: 'UserId', title: '发起用户', width: , sortable: true, hidden: true },
{ field: 'FormId', title: '对应表单', width: , sortable: true, hidden: true },
{ field: 'FormLevel', title: '公文级别', width: , 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: , sortable: true},
{ field: 'TimeOut', title: '截至时间', width: , sortable: true, formatter: function (value) { return SubStrYMD(value) } },
{ field: 'CurrentStep', title: '当前环节', width: , sortable: true, align: 'center' },
{
field: 'CurrentState', title: '当前状态', width: , 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: , 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: , height: , 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(, BaseRes.EditFail));
}
Flow_FormContentStepCheckStateModel stepCheckStateModel = stepCheckStateBLL.GetByStepCheckId(stepCheckId);
if (stepCheckStateModel.UserId != GetUserId())
{
return Json(JsonHandler.CreateMessage(, "越权操作!"));
}
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(, 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() == ;
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(, 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 = ;
for (int i = stepCheckList.Count() - ; i >= ; i--)
{
if (stepCheckId == stepCheckList[i].Id)
{
j = i;
}
}
//查看是否还有下一步步骤
if(j-<=stepCheckList.Count())
{
//查有第二步骤,查看是否是自选
Flow_StepModel stepModel = stepBLL.GetById(stepCheckList[j + ].StepId);
if (stepModel.FlowRule==(int)FlowRuleEnum.Customer)
{
foreach (string userId in UserList.Split(','))
{
//批量建立步骤审核人表
CreateCheckState(stepCheckList[j + ].Id, userId);
}
}
else {
//批量建立审核人员表
foreach (string userId in GetStepCheckMemberList(stepCheckList[j + ].StepId))
{
//批量建立步骤审核人表
CreateCheckState(stepCheckList[j + ].Id, userId);
}
} } } LogHandler.WriteServiceLog(GetUserId(), "Id" + stepCheckStateModel.Id + ",StepCheckId" + stepCheckStateModel.Reamrk, "成功", "修改", "Flow_FormContentStepCheckState");
return Json(JsonHandler.CreateMessage(, BaseRes.CheckSucceed));
}
else
{
string ErrorCol = errors.Error;
LogHandler.WriteServiceLog(GetUserId(), "Id" + stepCheckStateModel.Id + ",StepCheckId" + stepCheckStateModel.Reamrk + "," + ErrorCol, "失败", "修改", "Flow_FormContentStepCheckState");
return Json(JsonHandler.CreateMessage(, 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(),
@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()
fetch next from FormContentStepCheckState_Cursor into @tempId
while @@FETCH_STATUS=
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.会签,获得同步骤的同批审核人

ASP.NET MVC5+EF6+EasyUI 后台管理系统(53)-工作流设计-我的批阅的更多相关文章

  1. ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(持续更新中...)

    开发工具:VS2015(2012以上)+SQL2008R2以上数据库  您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB  升级后界面效果如下: 任务调度系统界面 http: ...

  2. ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(转)

    开发工具:VS2015(2012以上)+SQL2008R2以上数据库 您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB 升级后界面效果如下: 日程管理   http://ww ...

  3. ASP.NET MVC5+EF6+EasyUI 后台管理系统(63)-Excel导入和导出-自定义表模导入

    系列目录 前言 上一节使用了LinqToExcel和CloseXML对Excel表进行导入和导出的简单操作,大家可以跳转到上一节查看: ASP.NET MVC5+EF6+EasyUI 后台管理系统(6 ...

  4. ASP.NET MVC5+EF6+EasyUI 后台管理系统-WebApi的用法与调试

    1:ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-WebApi与Unity注入 使用Unity是为了使用我们后台的BLL和DAL层 2:ASP.NET MVC5+EF6+Easy ...

  5. ASP.NET MVC5+EF6+EasyUI 后台管理系统(51)-系统升级

    系统很久没有更新内容了,期待已久的更新在今天发布了,最近花了2个月的时间每天一点点,从原有系统 MVC4+EF5+UNITY2.X+Quartz 2.0+easyui 1.3.4无缝接入 MVC5+E ...

  6. ASP.NET MVC5+EF6+EasyUI 后台管理系统(58)-DAL层重构

    系列目录 前言:这是对本文系统一次重要的革新,很久就想要重构数据访问层了,数据访问层重复代码太多.主要集中增删该查每个模块都有,所以本次是为封装相同接口方法 如果你想了解怎么重构普通的接口DAL层请查 ...

  7. ASP.NET MVC5+EF6+EasyUI 后台管理系统(34)-文章发布系统①-简要分析

    系列目录 最新比较闲,为了学习下Android的开发构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(1)-前言与,虽然有点没有目的的学习,但还是了解了Andro ...

  8. ASP.NET MVC5+EF6+EasyUI 后台管理系统(54)-工作流设计-所有流程监控

    系列目录 先补充一个平面化登陆页面代码,自己更换喜欢的颜色背景 @using Apps.Common; @{ Layout = null; } <!DOCTYPE html> <ht ...

  9. ASP.NET MVC5+EF6+EasyUI 后台管理系统(56)-插件---单文件上传与easyui使用fancybox

    系列目录 https://yunpan.cn/cZVeSJ33XSHKZ  访问密码 0fc2 今天整合lightbox插件Fancybox1.3.4,发现1.3.4版本太老了.而目前easyui 1 ...

  10. ASP.NET MVC5+EF6+EasyUI 后台管理系统(38)-Easyui-accordion+tree漂亮的菜单导航

    系列目录 本节主要知识点是easyui 的手风琴加树结构做菜单导航 有园友抱怨原来菜单非常难看,但是基于原有树形无限级别的设计,没有办法只能已树形展示 先来看原来的效果 改变后的效果,当然我已经做好了 ...

随机推荐

  1. 【.net 深呼吸】细说CodeDom(8):分支与循环

    有人会问,为啥 CodeDom 不会生成 switch 语句,为啥没生成 while 语句之类.要注意,CodeDom只关心代码逻辑,而不是语法,语法是给写代码的人用的.如果用.net的“反编译”工具 ...

  2. C语言 · 高精度加法

    问题描述 输入两个整数a和b,输出这两个整数的和.a和b都不超过100位. 算法描述 由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储.对于这种问题,一般使用数组来处理. 定义一个数组A ...

  3. Mono为何能跨平台?聊聊CIL(MSIL)

    前言: 其实小匹夫在U3D的开发中一直对U3D的跨平台能力很好奇.到底是什么原理使得U3D可以跨平台呢?后来发现了Mono的作用,并进一步了解到了CIL的存在.所以,作为一个对Unity3D跨平台能力 ...

  4. 在一个空ASP.NET Web项目上创建一个ASP.NET Web API 2.0应用

    由于ASP.NET Web API具有与ASP.NET MVC类似的编程方式,再加上目前市面上专门介绍ASP.NET Web API 的书籍少之又少(我们看到的相关内容往往是某本介绍ASP.NET M ...

  5. MVC Core 网站开发(Ninesky) 1、创建项目

    又要开一个新项目了!说来惭愧,以前的东西每次都没写完,不是不想写完,主要是我每次看到新技术出来我都想尝试一下,看到.Net Core 手又痒了,开始学MVC Core. MVC Core最吸引我的有三 ...

  6. 一个IT人的成长路

    毕业四年多了,来深圳三年多了,经历了刚毕业的懵懂少年,成长为现在的成熟稳重青年.职场上,从刚毕业的小白,成长为现在可以成熟应对各种事情的老司机.经历过从初级研发工程师,到中级研发工程师,到高级研发工程 ...

  7. "NHibernate.Exceptions.GenericADOException: could not load an entity" 解决方案

     今天,测试一个项目的时候,抛出了这个莫名其妙的异常,然后就开始了一天的调试之旅... 花了很长时间,没有从代码找出任何问题... 那么到底哪里出问题呢? 根据下面那段长长的错误日志: -- ::, ...

  8. thinkphp数据的查询和截取

    public function NewsList(){ $this->assign('title','news'); $p = I('page',1); $listRows = 6; $News ...

  9. ABAP单元测试最佳实践

    本文包含了我在开发项目中经历过的实用的ABAP单元测试指导方针.我把它们安排成为问答的风格,欢迎任何人添加更多的Q&A's,以完成这个列表. 在我的项目中,只使用传统的ABAP report. ...

  10. JDK安装与配置

    JDK安装与配置 一.下载 JDK是ORACLE提供免费下载使用的,官网地址:https://www.oracle.com/index.html 一般选择Java SE版本即可,企业版的选择Java ...