Apply.cshtml 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. @using VberAdmin.Web.Models.Table
  2. @using Microsoft.AspNetCore.Mvc.Rendering
  3. @using VberAdmin.Web.Models.Search
  4. @using VberZero
  5. @{
  6. //ViewBag.Title = L("StateTitle");
  7. ViewBag.Title = "我的工作流程申请";
  8. string activeMenu = PermissionNames.VberMyWorkflowApplyMg; //The menu item will be active for this page.
  9. ViewBag.ActiveMenu = activeMenu;
  10. var table = new VmTable(VzConsts.ApiAppUrl + "Workflow/GetMyWorkflow", activeMenu, new VmSearch(new List<VmSearchItem>()
  11. {
  12. //new SearchItem("dd", L("stateName")).SetSearchIcon("q_u","ddd"),
  13. //new SearchItem("ff", L("stateName")).SetSelectItem("<option value=\"\">000</option><option value=\"S10001\">111</option><option value=\"S10002\">222</option>").SetSearchIcon("q_u","fff"),
  14. //new SearchItem("name1", L("stateName"),FieldType.D),
  15. //new VmSearchItem("id", "流程编号"),
  16. new VmSearchItem("title", "流程名称")
  17. })).AddItems(new List<VmTableItem>()
  18. {
  19. //new("id", "流程编号"),
  20. new("title", "流程名称"),
  21. //new("userName", "提交人"),
  22. new VmTableItem("creationTime", "提交时间","DateTimeFormatter").WithSort(),
  23. new("status", "审核状态","WorkflowStatusFormatter"),
  24. new("completeTime", "完成时间","DateTimeFormatter"),
  25. new("currentStepTitle", "当前阶段",""),
  26. new("", "操作","ActionsFormatter"),
  27. });
  28. //var modalBody = new VmModalBody()
  29. // .AddInputs(new List<VmInputBase>()
  30. // {
  31. // new VmInputHidden("id"),
  32. // })
  33. // .AddInput(new VmInput("displayValue", L("displayValue")))
  34. // .AddGroup(new List<VmInputBase>()
  35. // {
  36. // new VmInput("name", L("stateName")).WithDisabled(),
  37. // new VmInput("codeKey", L("codeKey")).WithDisabled(),
  38. // new VmInput("codeValue", L("codeValue")).WithDisabled(),
  39. // }, 3);
  40. //var modal = new VmModal().WithHeaderAndFooter(L("state"), "").WithBody(modalBody);
  41. }
  42. @await Html.PartialAsync("_Table", table)
  43. <div class="bg-white"
  44. id="audit_flow_detail"
  45. data-kt-drawer="true"
  46. data-kt-drawer-activate="true"
  47. @*data-kt-drawer-toggle="#"*@
  48. data-kt-drawer-close="#detail_close"
  49. data-kt-drawer-name="audit_flow_detail"
  50. data-kt-drawer-overlay="true"
  51. data-kt-drawer-width="{default:'300px', 'md': '600px'}"
  52. data-kt-drawer-direction="end">
  53. <div class="card rounded-0 w-100">
  54. <div class="card-header pe-5">
  55. <div class="card-title">
  56. <div class="d-flex justify-content-center flex-column me-3">
  57. <a href="#" class="fs-4 me-1 text-gray-800 lh-1"><span class="px-2 fw-bolder text-primary " id="flow-title"></span> <span id="flow-status"></span></a>
  58. </div>
  59. </div>
  60. <div class="card-toolbar">
  61. <div class="btn btn-sm btn-icon btn-active-light-primary" id="detail_close">
  62. <span class="svg-icon svg-icon-2">
  63. <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
  64. <rect opacity="0.5" x="6" y="17.3137" width="16" height="2" rx="1" transform="rotate(-45 6 17.3137)" fill="currentColor"></rect>
  65. <rect x="7.41422" y="6" width="16" height="2" rx="1" transform="rotate(45 7.41422 6)" fill="currentColor"></rect>
  66. </svg>
  67. </span>
  68. </div>
  69. </div>
  70. </div>
  71. <div class="card-body hover-scroll-overlay-y pt-5">
  72. <div class="fs-4 me-1 lh-1 mb-3 fw-bolder">申请详情:</div>
  73. <div class="px-5"><dl class="d-flex dl-line"><dt class="pe-2 fw-bolder">申请人:</dt><dd class="px-2 text-primary" id="flow-user-name"></dd></dl></div>
  74. <div id="flow-detail" class="px-5"></div>
  75. <div class="separator mb-3"></div>
  76. <div class="fs-4 me-1 lh-1 mb-3 fw-bolder">审批详情:</div>
  77. <div class="timeline-box" id="audit-records">
  78. <div>
  79. </div>
  80. </div>
  81. </div>
  82. </div>
  83. </div>
  84. @section scripts
  85. {
  86. <script src="~/js/workflowHelper.js" asp-append-version="false"></script>
  87. <script type="text/javascript">
  88. let $table = $('#table'), curWorkflowId = '', curExecutionRecord = [];
  89. $(function() {
  90. var funs = window.LoadTable();
  91. funs["btnCreate"] = function() {
  92. };
  93. funs["btnUpdate"] = function() {
  94. let row = $table.VbTable("getSelection");
  95. if (row) {
  96. }
  97. };
  98. });
  99. function Detail(id) {
  100. const flow_detail_drawer = KTDrawer.getInstance($('#audit_flow_detail')[0]);
  101. curWorkflowId = id;
  102. $.vbAjax4({
  103. url: abp.appUrl + "workflow/getDetails?id=" + id,
  104. success: (res) => {
  105. curExecutionRecord = res.executionRecords;
  106. $('#flow-user-name').html(res.userName);
  107. $('#flow-title').html(res.title);
  108. $('#flow-status').html(WorkflowStatusFormatter(res.status));
  109. ApplyDetail(res.data, res.inputs);
  110. RecordDetail(id, res.executionRecords);
  111. flow_detail_drawer.show();
  112. }
  113. });
  114. function ApplyDetail(data, inputs) {
  115. if (inputs && inputs.length) {
  116. let str = '';
  117. inputs.forEach(v => {
  118. const col = v.length ? 12 / v.length : 0;
  119. str += `<div class="row">`;
  120. v.forEach(vv => {
  121. str += `<dl class="col-${col} d-flex dl-line"><dt class="pe-2 fw-bolder">${vv.label}:</dt><dd >${GetInputValueText(vv)}</dd></dl>`;
  122. });
  123. str += `</div>`;
  124. });
  125. $('#flow-detail').html(str);
  126. }
  127. function GetInputValueText(input) {
  128. if (input.type == "uploadImages") {
  129. return `<img class="w-50 h-50" src="${data[input.name]}"/>`;
  130. } else if (input.type == "uploadFiles") {
  131. return `<a href="${data[input.name]}">查看附件</a>`;
  132. } else if (input.items && input.items.length) {
  133. const val = data[input.name];
  134. if (typeof val == 'string') {
  135. const item = input.items.find(v => v.value == val);
  136. return item ? item.label : "";
  137. } else if (val && val.length) {
  138. let valueStr = '';
  139. val.forEach(v => {
  140. const item = input.items.find(vv => vv.value == v);
  141. valueStr += item ? `${valueStr ? "," : ""}${item.label}` : "";
  142. });
  143. return valueStr;
  144. }
  145. }
  146. return data[input.name] || "";
  147. }
  148. }
  149. }
  150. function RecordDetail(id, executionRecords) {
  151. $.vbAjax4({
  152. url: abp.appUrl + "WorkflowAudit/GetAuditRecords",
  153. data: { id: id },
  154. success: r => { AuditRecordsFormatter(executionRecords, r) }
  155. });
  156. function AuditRecordsFormatter(data, auditData) {
  157. $('#audit-records').html('');
  158. if (data && data.length) {
  159. let i = 0;
  160. data.forEach(v => {
  161. i++;
  162. let records = auditData.auditRecords[v.executionPointerId];
  163. if (records && records.length) {
  164. let str = ``, styleStr = "bg-primary";
  165. str += `<div class="timeline-label"><span class="{0} text-white px-3">${v.stepTitle}</span></div>`;
  166. str += `<div>`;
  167. records.forEach(vv => {
  168. str += `<div class="timeline-item">`;
  169. if (vv.status == 0 && i==data.length) {
  170. str += `<div class="timeline-header">`;
  171. str += HeadFormatter(vv);
  172. str += `</div>`;
  173. } else if (vv.status !== 0 && vv.remark) {
  174. styleStr = vv.status == 1 ? "bg-success" : "bg-danger";
  175. str += `<div class="timeline-header">`;
  176. str += HeadFormatter(vv);
  177. str += `<div class="my-2"><span class="ps-5 fw-bolder"> 备注:</span>${vv.remark || ""}</div>`;
  178. str += `</div>`;
  179. }
  180. str += `</div>`;
  181. });
  182. str += `</div>`;
  183. $('#audit-records').append(str.format(styleStr));
  184. }
  185. });
  186. }
  187. }
  188. function HeadFormatter(data) {
  189. var str = `<div class="d-flex flex-stack align-items-cente mx-3">
  190. <div>
  191. <div class="symbol symbol-25px"><img class="" src="${data.userHeadPhoto}" /></div>
  192. <span class="mx-2 fw-bolder">${data.userIdentityName}</span>
  193. <span class="">${AuditStatusFormatter(data.status)}</span>
  194. </div>
  195. <div class="fs-6"><span class="text-muted">${DateTimeFormatter(data.auditTime) || ""}</span></div>
  196. </div>`;
  197. return str;
  198. }
  199. }
  200. </script>
  201. <script id="formatter" type="text/javascript">
  202. function AuditStatusFormatter(v) {
  203. var name = $('#hid-auditStatus option[value="' + v + '"]').text();
  204. if (v === 0) {
  205. return '<span class="badge badge-light-primary">' + name + '</span>';
  206. } else if (v === 1) {
  207. return '<span class="badge badge-light-success">' + name + '</span>';
  208. } else if (v === 2) {
  209. return '<span class="badge badge-light-danger">' + name + '</span>';
  210. } else if (v === 3) {
  211. return '<span class="badge badge-light-warning">' + name + '</span>';
  212. }
  213. return v;
  214. }
  215. function WorkflowStatusFormatter(v) {
  216. var name = $('#hid-wfStatus option[value="' + v + '"]').text();
  217. if (v === 0) {
  218. return '<span class="badge badge-primary">' + name + '</span>';
  219. } else if (v === 1) {
  220. return '<span class="badge badge-success">' + name + '</span>';
  221. } else if (v === 2) {
  222. return '<span class="badge badge-danger">' + name + '</span>';
  223. } else if (v === 3) {
  224. return '<span class="badge badge-warning">' + name + '</span>';
  225. }
  226. return v;
  227. }
  228. function ActionsFormatter(v, r) {
  229. let str = '';
  230. str += `<span class="table-action" onclick="Detail('${r.id}')">流程详情${icon}</span>`;
  231. return str;
  232. }
  233. </script>
  234. }
  235. <section style="display: none">
  236. <select id="hid-auditStatus">
  237. @Html.Raw(ViewBag.AuditStatus)
  238. </select>
  239. <select id="hid-wfStatus">
  240. @Html.Raw(ViewBag.WfStatus)
  241. </select>
  242. </section>