ASP.NET MVC5+EF6+EasyUI 后台管理系统(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 =,
/// <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)-工作流设计-我的批阅的更多相关文章
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(持续更新中...)
开发工具:VS2015(2012以上)+SQL2008R2以上数据库 您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB 升级后界面效果如下: 任务调度系统界面 http: ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(转)
开发工具:VS2015(2012以上)+SQL2008R2以上数据库 您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB 升级后界面效果如下: 日程管理 http://ww ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(63)-Excel导入和导出-自定义表模导入
系列目录 前言 上一节使用了LinqToExcel和CloseXML对Excel表进行导入和导出的简单操作,大家可以跳转到上一节查看: ASP.NET MVC5+EF6+EasyUI 后台管理系统(6 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统-WebApi的用法与调试
1:ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-WebApi与Unity注入 使用Unity是为了使用我们后台的BLL和DAL层 2:ASP.NET MVC5+EF6+Easy ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(51)-系统升级
系统很久没有更新内容了,期待已久的更新在今天发布了,最近花了2个月的时间每天一点点,从原有系统 MVC4+EF5+UNITY2.X+Quartz 2.0+easyui 1.3.4无缝接入 MVC5+E ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(58)-DAL层重构
系列目录 前言:这是对本文系统一次重要的革新,很久就想要重构数据访问层了,数据访问层重复代码太多.主要集中增删该查每个模块都有,所以本次是为封装相同接口方法 如果你想了解怎么重构普通的接口DAL层请查 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(34)-文章发布系统①-简要分析
系列目录 最新比较闲,为了学习下Android的开发构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(1)-前言与,虽然有点没有目的的学习,但还是了解了Andro ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(54)-工作流设计-所有流程监控
系列目录 先补充一个平面化登陆页面代码,自己更换喜欢的颜色背景 @using Apps.Common; @{ Layout = null; } <!DOCTYPE html> <ht ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(56)-插件---单文件上传与easyui使用fancybox
系列目录 https://yunpan.cn/cZVeSJ33XSHKZ 访问密码 0fc2 今天整合lightbox插件Fancybox1.3.4,发现1.3.4版本太老了.而目前easyui 1 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(38)-Easyui-accordion+tree漂亮的菜单导航
系列目录 本节主要知识点是easyui 的手风琴加树结构做菜单导航 有园友抱怨原来菜单非常难看,但是基于原有树形无限级别的设计,没有办法只能已树形展示 先来看原来的效果 改变后的效果,当然我已经做好了 ...
随机推荐
- CSS3 border-radius边框圆角
在CSS3中提供了对边框进行圆角设定的支持,可对边框1~4个角进行圆角样式设置. 目录 1. 介绍 2. value值的格式和类型 3. border-radius 1~4个参数说明 4. 在线示例 ...
- Docker 第一篇--初识docker
已经多年不写博客, 看完<晓松奇谈>最后一期猛然觉醒, 决定仔细梳理下自己这几年的知识脉络. 既然决定写, 那么首先就从最近2年热门的开源项目Docker开始.Docker 这两年在国内很 ...
- Android Ormlite 学习笔记1 -- 基础
Ormlite 是一个开源Java数据实体映射框架.其中依赖2个核心类库: 1.ormlite-android-4.48.jar 2.ormlite-core-4.48.jar 新建项目,引用上面2个 ...
- 运用php做投票题,例题
要求大概是这样的,有一个题目,题目下面是复选框,要求点完复选框提交后会变成进度条,各选项的进度条百分比,和投票数量 首先还是要在数据库建两张表,如下: 要完成这个题目,需要建两个页面 <!DOC ...
- Hawk 5.1 数据导入和导出
除了一般的数据库导入导出,Hawk还支持从文件导入和导出,支持的文件类型包括: Excel CSV(逗号分割文本文件) TXT (制表符分割文本文件) Json xml Excel 目前来看,Exce ...
- UWP开发必备:常用数据列表控件汇总比较
今天是想通过实例将UWP开发常用的数据列表做汇总比较,作为以后项目开发参考.UWP开发必备知识点总结请参照[UWP开发必备以及常用知识点总结]. 本次主要讨论以下控件: GridView:用于显示数据 ...
- 第一个移动前端开源项目-dailog
你还在为手机上没有忙碌光标而发愁吗?你还在抱怨弹出框组件要依赖zepto/jqery吗?你还在纠结是否要自己写一套还是去网上寻找成现成的UI组件吗?YouA为你轻松解决所有烦恼.YouA是我为移动前端 ...
- 读书笔记汇总 - SQL必知必会(第4版)
本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...
- Java中常用集合操作
一.Map 名值对存储的. 常用派生类HashMap类 添加: put(key,value)往集合里添加数据 删除: clear()删除所有 remove(key)清除单个,根据k来找 获取: siz ...
- 微信公众号开发(一)--验证服务器地址的Java实现
现在主流上都用php写微信公众号后台,其实作为后端语言之一的java也可以实现. 这篇文章将对验证服务器地址这一步做出实现. 参考资料:1.慕课网-<初识java微信公众号开发>,2.微信 ...