创建新表单之后,我们就可以起草申请了,申请按照严格的表单步骤和分支执行。
起草的同时,我们分解流转的规则中的审批人并保存,具体流程如下
接下来创建DrafContoller控制器,此控制器只有2个页面,一个Create(起草页面)Index(表单列表)
表单列表显示个人想法,我是根据分类直接获取其下表单,即Flow_Type下的Flow_Form


上面的表单列表简单完成之后,进入最复杂的一步,获取字段组成表单
获取字段组成表单可以做得很漂亮,即在设计表单的时候设计布局,直接读取布局,否则按照表单的控件顺序读取布局。
具体对比如下:
VS
明显前者更利于打印和阅读。我们先布局第二种形式
根据表Flow_FormContent设置Create页面的固定头尾
@model App.Models.Flow.Flow_FormContentModel @using App.Common; @using App.Models.Flow; @using App.Admin; @using App.Models.Sys; @{ ViewBag.Title = "创建"; Layout = "~/Views/Shared/_Index_Layout.cshtml"; List<permModel> perm = (List<permModel>)ViewBag.Perm; if (perm == null) { perm = new List<permModel>(); } } <script src="~/Scripts/My97DatePicker/WdatePicker.js"></script> <script type="text/javascript"> $(function () { $("#btnSave").click(function () { if ($("#Title").val() == "") { $.messageBox5s("提示", "表单标题必须填写!"); return false; } if (CheckForm()) { $.ajax({ url: "@Url.Action("Create")", type: "Post", data: $("form").serialize(), dataType: "json", success: function (data) { if (data.type == 1) { $.messageBox5s("添加成功!", data.message); $("#btnSave").hide(); } else { window.parent.frameReturnByMes(data.message); } } }); } return false; }); $("#btnReturn").click(function () { if ($("#btnSave").is(":hidden")) { window.parent.CloseCurrentWin(); } else { $.messager.confirm('提示', '没有保存的数据将会丢失,你确定要返回吗?', function (r) { if (r) { window.parent.CloseCurrentWin(); } }); } }); }); </script> @Html.Raw(ViewBag.HtmlJS) <div class="mvctool "> @Html.ToolButton("btnSave", "icon-save", "保存", perm, "Create", true) @Html.ToolButton("btnReturn", "icon-return", "返回",false) </div> @using (Html.BeginForm()) { <table class="fromEditTable setTextWidth300"> <tbody> @Html.HiddenFor(model => model.Id) @Html.HiddenFor(model => model.FormId) @Html.HiddenFor(model => model.UserId) <input id="CreateTime" type="hidden" name="CreateTime" value="2000-1-1" /> <input id="TimeOut" type="hidden" name="TimeOut" value="2111-1-1" /> <tr> <td style="width:100px; text-align:right;"> @Html.LabelFor(model => model.Title): </td> <td style="width:310px"> @Html.EditorFor(model => model.Title) </td> <td>@Html.ValidationMessageFor(model => model.Title)</td> </tr> @Html.Raw(ViewBag.Html) <tr><td style='width:100px; text-align:right;'>紧急程度 :</td><td><select name="FormLevel" id="FormLevel"><option value="普通">普通</option><option value="重要">重要</option><option value="紧急">紧急</option></select></td></tr> </tbody> </table> }
代码
@Html.Raw(ViewBag.Html)就是我们的表单核心部分。所以Create必须返回ViewBag.Html内容为设计表单的JS和字段
这里代码有点别扭,因为有26个字段,所以要循环26个字段去判断是否有关联来读取。很麻烦。可以用反射来做可以省很多代码
先创建一个类,这个类是辅助工作流的通用类

[SupportFilter] public ActionResult Create(string id) { ViewBag.Perm = GetPermission(); ViewBag.Html = ExceHtmlJs(id); Flow_FormContentModel model = new Flow_FormContentModel(); model.FormId = id; return View(model); } //根据设定公文,生成表单及控制条件 private string ExceHtmlJs(string id) { //定义一个sb为生成HTML表单 StringBuilder sbHtml = new StringBuilder(); StringBuilder sbJS = new StringBuilder(); sbJS.Append("<script type='text/javascript'>function CheckForm(){"); Flow_FormModel model = formBLL.GetById(id); #region 判断流程是否有字段,有就生成HTML表单 //获得对象的类型,model Type formType = model.GetType(); //查找名称为"A-Z"的属性 string[] arrStr = { "AttrA", "AttrB", "AttrC", "AttrD", "AttrE", "AttrF", "AttrG", "AttrH", "AttrI", "AttrJ", "AttrK" , "AttrL", "AttrM", "AttrN", "AttrO", "AttrP", "AttrQ", "AttrR", "AttrS", "AttrT", "AttrU" , "AttrV", "AttrW", "AttrX", "AttrY", "AttrZ"}; foreach (string str in arrStr) { object o = formType.GetProperty(str).GetValue(model, null); if (o != null) { sbHtml.Append(JuageExc(o.ToString(), str, ref sbJS)); } } #endregion sbJS.Append("return true}</script>"); ViewBag.HtmlJS = sbJS.ToString(); return sbHtml.ToString(); } private string JuageExc(string attr, string no,ref StringBuilder sbJS) { if (!string.IsNullOrEmpty(attr)) { return GetHtml(attr, no, ref sbJS); } return ""; } //获取指定名称的HTML表单 private string GetHtml(string id, string no, ref StringBuilder sbJS) { StringBuilder sb = new StringBuilder(); Flow_FormAttrModel attrModel = formAttrBLL.GetById(id); sb.AppendFormat("<tr><td style='width:100px; text-align:right;'>{0} :</td>", attrModel.Title); //获取指定类型的HTML表单 sb.AppendFormat("<td>{0}</td></tr>", new FlowHelper().GetInput(attrModel.AttrType, attrModel.Name, no)); sbJS.Append(attrModel.CheckJS); return sb.ToString(); }
引入命名空间using System;
代码结构:上面没有什么特殊算法。主要是26个字段用反射来读取。自己细细消化一下就行
应该可以用了,点击请假申请看看!
完成。可以起草新的申请了。接下来就是保存申请...
保存是最复杂的一步要取得表单,分解步骤,分解分支,最后指定审核人
看Create方法




代码分析:
1.填充表单内容Flow_FormContent
2.获得表单步骤Flow_Step
3.根据步骤获得Flow_StepRule
4.取得判断流程方向的标示(是否结束)
5.插入审批人
需要慢慢消化,分解过程比较复杂
本文转自ymnets博客园博客,原文链接:http://www.cnblogs.com/ymnets/p/4474755.html,如需转载请自行联系原作者