一个简易流程审批实现

审批代码 -> 审批环节 -> 审批岗位 ->在数据库中创建各个节点保存审核记录

一个审批代码表示一个业务需要审批,通过审批代码得到审批中需要流转的环节,每个环节对应着一个或是多个审批岗位

    #region 各个审核步骤定义并实现,每个审核步骤均对应一个代码,通过代码得到审核所需的环节,从而得到审批岗位
    public class ProgressHelper
    {
        #region 流程流转顺序(一个流程顺序包含多个流转(Progress))定义(一个流转(Progress)可以有多个审核节点(Step))
        public static List<OrderAudiProgressTemplate> GFanDanOrderAudiProgressTest
        {
            get
            {
                var progress1 = new OrderAudiProgressTemplate
                       {

                           ProgressName = "翻单订单导SAP审核过程1",
                           PreviousProgress = null,
                           Steps = new List<OrderAudiStepTemplate>
                           {
                                //三个并行审核过程
                                new OrderAudiStepTemplate{ UserSpecial = "财务-不合理欠款" , Remark = "1查询客户是否有不合理欠款"},
                                new OrderAudiStepTemplate{ UserSpecial = "财务-库存是否过剩" , Remark = "2查询客户该机型是否有不合理库存"},
                                new OrderAudiStepTemplate{ UserSpecial = "财务-订金是否到" , Remark = "3查询客户订金是否到帐"}
                           }

                       };
                var progress2 = new OrderAudiProgressTemplate
                       {
                           ProgressName = "翻单订单导SAP审核过程2",
                           PreviousProgress = progress1,
                           Steps = new List<OrderAudiStepTemplate>
                           {
                                //三个并行审核过程
                                new OrderAudiStepTemplate{ UserSpecial = "财务-不合理欠款" , Remark = "4查询客户是否有不合理欠款"},
                                new OrderAudiStepTemplate{ UserSpecial = "财务-库存是否过剩" , Remark = "5查询客户该机型是否有不合理库存"},
                                new OrderAudiStepTemplate{ UserSpecial = "财务-订金是否到" , Remark = "6查询客户订金是否到帐"}
                           }

                       };

                var progress3 = new OrderAudiProgressTemplate
                {
                    ProgressName = "翻单订单导SAP审核过程3",
                    PreviousProgress = progress2,
                    Steps = new List<OrderAudiStepTemplate>
                           {
                                //三个并行审核过程
                                new OrderAudiStepTemplate{ UserSpecial = "财务-不合理欠款" , Remark = "7查询客户是否有不合理欠款"},
                                new OrderAudiStepTemplate{ UserSpecial = "财务-库存是否过剩" , Remark = "8查询客户该机型是否有不合理库存"},
                                new OrderAudiStepTemplate{ UserSpecial = "财务-订金是否到" , Remark = "9查询客户订金是否到帐"}
                           }

                };
                return new List<OrderAudiProgressTemplate>
                {
                      progress2,progress1,progress3
                };
            }
        }

        public static List<OrderAudiProgressTemplate> FanDanOrderAudiProgress
        {
            get
            {

                var progress1 = new OrderAudiProgressTemplate
                {
                    ProgressName = "翻单订单导SAP前审核过程",
                    ProgressCode = PendingCode.FandanAudiProgressCode,
                    PreviousProgress = null,
                    Steps = new List<OrderAudiStepTemplate>
                           {
                                //三个并行审核过程
                                new OrderAudiStepTemplate{ UserSpecial = "财务-不合理欠款" , Remark = "查询客户是否有不合理欠款" ,StepCode = "Ac1"},
                                new OrderAudiStepTemplate{ UserSpecial = "财务-库存是否过剩" , Remark = "查询客户该机型是否有不合理库存",StepCode = "Ac2"},
                                new OrderAudiStepTemplate{ UserSpecial = "财务-订金是否到" , Remark = "查询客户订金是否到帐",StepCode = "Ac3"}
                           }

                };
                return new List<OrderAudiProgressTemplate>
                {
                      progress1
                };
            }
        }
        #endregion
        private static List<OrderAudiProgressTemplate> GetAudiProgressByCode(string code)
        {
            var codeTitles = new Dictionary<string, List<OrderAudiProgressTemplate>>();
            codeTitles.Add(PendingCode.TestAudiProgressCode, GFanDanOrderAudiProgressTest);
            codeTitles.Add(PendingCode.FandanAudiProgressCode, FanDanOrderAudiProgress);
            if (codeTitles.ContainsKey(code))
            {
                return codeTitles[code];
            }
            return null;
        }

        public static void SetAllOrderProgresMoved(int orderId, string progressCode)
        {

            using (var db = new DataContext.OverSeaOrderEntities())
            {
                foreach (var item in db.OrderPendingState.Where(p => p.OrderID == orderId && p.ProgressCode == progressCode))
                {
                    item.ProgressCode = item.ProgressCode + "_";
                }
                db.SaveChanges();
            }
        }

        public static void CreateProgressForOrder(int orderId,string progressCode)
        {
            var template = GetAudiProgressByCode(progressCode);
            if (template == null) return;
            var currentgress = template.FirstOrDefault(p => p.PreviousProgress == null);
            if (currentgress == null) return;
            var stateId = 0;

            using (var db = new DataContext.OverSeaOrderEntities())
            {
                if (db.OrderPendingState.Any(p => p.OrderID == orderId && p.ProgressCode == progressCode))
                {
                    return;
                }
                var state = new OrderPendingState
                {
                    CreateDate = System.DateTime.Now,
                    LastUpdateDate = null,
                    OrderID = orderId,
                    PendingResult = (int)OrderPendingResult.Pending,
                    ProgressCode = progressCode
                };
                db.OrderPendingState.Add(state);
                db.SaveChanges();
                stateId = state.ID;
            }
            OrderAudiProgress predbgress = null;
            do
            {
                //创建新的Progress项目
                var curdb = CreateSaveingProgress(currentgress, orderId, predbgress, stateId);
                //查找下一个
                predbgress = curdb;
                currentgress = template.FirstOrDefault(p => p.PreviousProgress == currentgress);
            }
            while (currentgress != null);
            //为所有的流转创建一个状态项

        }
        /// <summary>
        /// 保存用户保存结果
        /// </summary>
        public static void SetStepPendingResult(int userId,int progressStepId, bool result)
        {
            using (var db = new DataContext.OverSeaOrderEntities())
            {
                var step = db.ProgressStep.FirstOrDefault(p => p.ID == progressStepId);
                if (step == null) return;
                step.Passed = result;
                //判断每个步骤是否都已经执行
                var allsteps = db.ProgressStep.Where(p => p.ProgressID == step.ProgressID && p.ID != progressStepId).ToList();
                //此处需等所有人【步骤】都审核完成才执行,是否结果为false时就直接判断结束
                if (allsteps.All(p => p.Passed.HasValue))
                {
                    //所有人已经填写,总结下是否都通过
                    var progressResult = false;
                    if (result && allsteps.All(p => p.Passed == true))
                    {
                        progressResult = true;
                    }
                    //按总结情况更新主状态,是下一步,还是退回
                    var progress = db.OrderAudiProgress.FirstOrDefault(p => p.ID == step.ProgressID);
                    if (progress == null) return;
                    var orderstat = db.OrderPendingState.FirstOrDefault(p => progress.OrderID  == p.OrderID && p.ProgressCode == progress.ProgerssCode);
                    if (orderstat == null) return;
                    progress.IsPassed = progressResult;
                    progress.PassedDate = System.DateTime.Now;
                    if (progressResult) //下一步或是完成
                    {
                        progress.IsRuning = false;
                        //查找下一步progress
                        var nextProgress = db.OrderAudiProgress.FirstOrDefault(p => p.PreviousProgressID == progress.ID);
                        if (nextProgress == null)
                        {
                            //流程已走完
                            orderstat.PendingResult = (int)OrderPendingResult.Successed;
                            orderstat.LastUpdateDate = System.DateTime.Now;
                        }
                        else
                        {
                            //更新下一个progress开始进行
                            nextProgress.IsRuning = true;
                        }
                    }
                    else
                    {
                        //有审核人员意见不通过
                        orderstat.PendingResult = (int)OrderPendingResult.Backed;
                        orderstat.LastUpdateDate = System.DateTime.Now;
                    }
                }
                db.SaveChanges();
            }
        }

        /// <summary>
        /// 为每一个流程顺序创建一个数据库对应项并指定流转顺序
        /// </summary>
        /// <param name="gressTemplate"></param>
        /// <param name="orderId"></param>
        /// <param name="predbgress"></param>
        /// <returns></returns>
        static OrderAudiProgress CreateSaveingProgress(OrderAudiProgressTemplate gressTemplate, int orderId, OrderAudiProgress predbgress,int stateId)
        {
            using (var db = new DataContext.OverSeaOrderEntities())
            {
                OrderAudiProgress item = new OrderAudiProgress
                {
                    CreateDate = System.DateTime.Now,
                    IsPassed = null,
                    OrderID = orderId,
                    PassedDate = null,
                    ProgressName = gressTemplate.ProgressName,
                    ProgressStep = new List<ProgressStep>(),
                    ProgerssCode = gressTemplate.ProgressCode,
                    PendingStateID = stateId
                };
                if (predbgress == null)
                {
                    item.PreviousProgressID = null;
                    item.IsRuning = true; //如果没有前续表明该流转为第一个开始的
                }
                else
                {
                    item.PreviousProgressID = predbgress.ID;
                    item.IsRuning = false;
                }
                db.OrderAudiProgress.Add(item);
                foreach (var step in gressTemplate.Steps)
                {
                    var dbstep = new ProgressStep
                    {
                        AudiorID = 0,
                        CreateDate = System.DateTime.Now,
                        StepTitle = step.Remark,
                        StepCode = step.StepCode
                    };
                    /****  审核员查找代码  ***/
                    var audio = db.User.OrderByDescending(p => p.ID).FirstOrDefault(p => p.AudiSpecial == step.UserSpecial);
                    if (audio != null)
                    {
                        dbstep.AudiorID = audio.ID;
                    }
                    /****-完毕-*/
                    item.ProgressStep.Add(dbstep);
                    db.ProgressStep.Add(dbstep);
                }
                db.SaveChanges();
                return item;
            }
        }

        /// <summary>
        /// 获取用户的审核列表
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public static List<ProgressStep> GetUserPendingList(int userId)
        {
            using (var db = new DataContext.OverSeaOrderEntities())
            {
                return db.ProgressStep.Where(p => p.AudiorID == userId && p.OrderAudiProgress.IsRuning == true && p.Passed == null).ToList();
            }
        }
    }
    #endregion

    #region 定义审核及审核结果枚举[前提:每个订单对应几个审核情况,如,在导入ERP前有前置审批,在导入后的出货有出货相关流种审批,每个审批对应几个环节,每个环节对应几个岗位]
    public enum OrderPendingResult
    {
         Pending = 0 ,Backed = 4 ,Successed = 8
    }

    public class PendingCode
    {
        public const string TestAudiProgressCode = "FDTest";
        public const string FandanAudiProgressCode = "FD001";
        public static string GetPendingCodeTitle(string code)
        {
            var codeTitles = new Dictionary<string, string>();
            codeTitles.Add(PendingCode.TestAudiProgressCode, "测试时使用流程");
            codeTitles.Add(PendingCode.FandanAudiProgressCode, "翻单导SAP流程");
            if (codeTitles.ContainsKey(code))
            {
                return codeTitles[code];
            }
            return string.Empty;
        }
    }
    #endregion

    #region 定义审核过程及每个过程包含的审核步骤类
    //订单审核过程 (1个过程(progress)中包含多个步骤(step) 过程是有先后顺序,步骤则没有但需全部完成)
    public class OrderAudiProgressTemplate
    {
        public string ProgressName { get; set; }
        public string ProgressCode { get; set; }
        public List<OrderAudiStepTemplate> Steps { get; set; }
        public OrderAudiProgressTemplate PreviousProgress { get; set; }
    }

    //订单审核
    public class OrderAudiStepTemplate
    {
        //public User Audior { get; set; }
        public string UserSpecial { get; set; }  //用户岗位 [通过用户岗位描述来查找审核员]
        public string Remark { get; set; }

        public string StepCode { get; set; }
    }
    #endregion

    #region 各种情况判定帮助类
    public class OrderAudiStateHelper
    {

        public static bool IsOrderProgressCreated(int orderId, string progressCode)
        {
            return PendingSateAny(p => p.OrderID == orderId && p.ProgressCode == progressCode);
        }

        public static bool IsOrderProgressSuccess(int orderId, string progressCode)
        {
            var resutl = (int)OrderPendingResult.Successed;
            return PendingSateAny(p => p.OrderID == orderId && p.ProgressCode == progressCode && p.PendingResult == resutl);
        }
        public static bool IsOrderProgressBacked(int orderId, string progressCode)
        {
            var resutl = (int)OrderPendingResult.Successed;
            return PendingSateAny(p => p.OrderID == orderId && p.ProgressCode == progressCode && p.PendingResult == resutl);
        }

        private static bool PendingSateAny(Expression<Func<OrderPendingState, bool>> func)
        {
            using (var db = new DataContext.OverSeaOrderEntities())
            {
                return db.OrderPendingState.Any(func);
            }
        }

    }
    #endregion
时间: 2024-07-31 18:44:51

一个简易流程审批实现的相关文章

基于SSM框架下的JAVA企业流程审批系统

每天记录学习,每天会有好心情.*^_^* 今天将为大家分析一个企业流程审批系统(现代企业对资金流的控制十分严格,但是绝大部分企业的费用审批还停滞在手动填单.逐级递交.逐级审批的现状,既没有效率也不利于与国际接轨.文中采用基于JAVA技术和mysql数据库开发了一个改变原始审批流程操作的自动审批流程系统,缩短了审批时间,提高了企业的工作效率,真正实现了无纸办公,为电子商务时代企业的发展提供了崭新的模式.),该项目使用框架为SSM(MYECLIPSE),选用开发工具为MYECLIPSE.企业流程审批

jQuery+jsPlumb简易流程设计

jsPlumb是一个比较强大的绘图组件,它提供了一种方法,主要用于连接网页上的元素. 1.主要三个JS组件:jQuery.jQuery UI.jsPlumb 2.结果展示: 3.源码地址: 源码下载 4.注意 源码中test.jsp中JS和CSS的引入根据自己项目的实际位置引入. String contextPath = request.getContextPath();       if ("/".equals(contextPath))        {            co

重装linux服务器简易流程

项目开发软件开发非常重要的一个环节,而能够拥有一个安全健康的服务器来使System正常高效的运行也是非常有必要的.由于是搭建在外网上的服务器,时不时会受到各种病毒的侵袭,这篇博客不写如何进行防御各种病毒,而是讲一下,如果发生了这种情况.如何通过最笨的一种方法,重装服务器来解决这个问题,这里把流程注意事项讲述一下. 一个项目已经上线了,发生了这种情况,一般情况下会让我们晚上在有限的时间内重装完毕,回复原样,我们需要提前做好准备,确保能够完成.好这里看一下,在重装服务器前后我们需要考虑的各项事宜,及

一个简易JVM的实现

 http://catpad.net/michael/jvm/是一个开源的简易的JVM实现.它实现了大多数的JVM功能,实现简单,适合广大技术爱好者了解JVM的内部工作原理.可以参考<Inside the Java Virtual Machine>by Bill Venners,本书对jvm结构,Java class的定义有详细的讲解. 本文介绍下其中的一些关键实现点: 类加载,class loading 线程和同步, thead,synchronization 代码解释 GC JNI 1

实现无人值守流程审批管理

实现无人值守流程审批管理 你想实现,不登陆网站就能审批文件?你想实现不用去公司就可以 解决自己的审批任务?我可以给你一个 很好的思路.我们可以很好的利用手机短信的业务来实现事件通过Ws回调,只需要一个短信 就能实现你的审批 或者拒绝 大家可以举一反三 我只是告诉大家可以这样做 如图:下面这个列子就是现实一个 无人值守的审批 代码实现如下: 上面是我的截图下面是代码 using System;using System.Collections;using System.Collections.Gen

ENode 2.0 第一个真实案例剖析-一个简易论坛(Forum)

前言 经过不断的坚持和努力,ENode 2.0的第一个真实案例终于出来了.这个案例是一个简易的论坛,开发这个论坛的初衷是为了验证用ENode框架来开发一个真实项目的可行性.关于ENode是什么,本文就不多介绍了,可以参考这篇文章的介绍.本文重点介绍一下ENode是如何帮助我们开发一个基于DDD+CQRS+Event Sourcing架构的应用程序的.这个论坛使用到了ENode, EQueue两个框架,EQueue是一个分布式的消息队列组件,该组件的主体思想是参考阿里的RocketMQ.当我们使用

C 基于UDP实现一个简易的聊天室

引言 本文是围绕Linux udp api 构建一个简易的多人聊天室.重点看思路,帮助我们加深 对udp开发中一些api了解.相对而言udp socket开发相比tcp socket开发注意的细节要少很多. 但是水也很深. 本文就当是一个demo整合帮助开发者回顾和继续了解 linux udp开发的基本流程. 首先我们来看看 linux udp 和 tcp的异同. /* 这里简单比较一下TCP和UDP在编程实现上的一些区别: TCP流程 建立一个TCP连接需要三次握手,而断开一个TCP则需要四个

npm 发包的简易流程

 发包的简易流程: https://www.jianshu.com/p/ea64fd01679c 错误集锦: npm publish error: 403. You do not have permission to publish 'project name':包同名 使用方法指南: 1. 注册一个账号 你有两种方式注册一个账号: 去npm 网站注册或者使用npm adduser命令 2. 输入npm init 初始化一个项目,准备好自己的包文件 name: 包名 version: 包版本号

编写Python爬虫的简易流程描述

python网络爬虫,其实就是模拟人类浏览网页的行为,并将这种行为自动化的工具. 从技术上来说,就是利用python代码发送特定的request请求到Web页面,最后获得response,并将response解析,提取其中的数据并存储起来. 开发一个爬虫程序,首先要确定目标.例如爬取拉勾网的python相关职位信息是我们的目标.根据这个目标,我们可以先使用手工的方式,访问拉勾网,搜索python相关职位,从而对如何从页面获取所需信息有一个直观的理解. 其次,可以使用浏览器自带的开发者工具.抓包工