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 =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换成枚举值

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);
        }
 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>

依次添加没有难度

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.会签,获得同步骤的同批审核人

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏ios 技术积累

MJRefresh 封装

MJRefresh是很好用的一个刷新控件,但是如果在每个ViewController中都加入如下代码

2162
来自专栏ascii0x03的安全笔记

IE的BHO通过IHTMLDocument2接口获得网页源代码

参考了凤之焚的专栏:http://blog.csdn.net/lion_wing/article/details/769742 但是他的源码有些问题,即IHTM...

3405
来自专栏JadePeng的技术博客

使用websocket-sharp来创建c#版本的websocket服务

当前有一个需求,需要网页端调用扫描仪,javascript不具备调用能力,因此需要在机器上提供一个ws服务给前端网页调用扫描仪。而扫描仪有一个c#版本的API,...

7155
来自专栏菩提树下的杨过

打印机设置(PrintDialog)、页面设置(PageSetupDialog) 及 RDLC报表如何选择指定打印机

如果一台电脑同时连接多个打印机,而且每个打印机使用的纸张大小各不相同(比如:票据打印钱用的小票专用张,办公打印机用的是A4标准纸),在处理打印类的需求时,如果不...

2977
来自专栏Java成神之路

Java微信公众平台开发_04_自定义菜单

自定义菜单中请求包的数据是Json字符串格式的,请参见:  Java_数据交换_fastJSON_01_用法入门

1323
来自专栏菩提树下的杨过

Flash在线拍摄用户头象

很多网站在上传用户头象时,除了传统方式上传外,都支持在线摄像头拍照并做简单编辑,完成之后再将图象数据提交到服务端(比如ASP.Net),这几天正好需要这个功能,...

3128
来自专栏PPV课数据科学社区

【学习】七天搞定SAS(一):数据的导入、数据结构

SAS的数据类型 ? 首先,sas的编程大概就两块:Data和PROC,这个倒是蛮清晰的划分。然后目前关注data部分。 SAS的数据类型还真的只有两种:数字和...

38212
来自专栏叁金大数据

WPF播放器

最近由于工作需要,需要做一个播放软件,在网上参考了很多例子,园子里有很多代码。其中最多的就是wpf自带的MediaElement控件,或者VLC视频播放器。

2932
来自专栏偏前端工程师的驿站

.Net魔法堂:史上最全的ActiveX开发教程——ActiveX与JS间交互篇

一、前言                             经过上几篇的学习,现在我们已经掌握了ActiveX的整个开发过程,但要发挥ActiveX的真正...

23010
来自专栏菩提树下的杨过

Silverlight:利用异步加载Xap实现自定义loading效果

关键点: 1.利用WebClient的DownloadProgressChanged事件更新下载进度 2.下载完成后,分析Xap包的程序集Assembly信息 ...

20110

扫码关注云+社区