PageRenderTime 98ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/Components/BP.WFV4/WF/WorkNode.cs

#
C# | 5164 lines | 4430 code | 307 blank | 427 comment | 468 complexity | 20be7b5137a2280d3840c699df9572c0 MD5 | raw file
Possible License(s): AGPL-3.0
  1. using System;
  2. using BP.En;
  3. using BP.DA;
  4. using System.Collections;
  5. using System.Data;
  6. using BP.Port;
  7. using BP.Web;
  8. using BP.Sys;
  9. namespace BP.WF
  10. {
  11. /// <summary>
  12. /// WF 的摘要说明。
  13. /// 工作流.
  14. /// 这里包含了两个方面
  15. /// 工作的信息.
  16. /// 流程的信息.
  17. /// </summary>
  18. public class WorkNode
  19. {
  20. #region ToE
  21. public string ToE(string s, string chName)
  22. {
  23. return BP.Sys.Language.GetValByUserLang(s, chName);
  24. }
  25. public string ToEP1(string s, string chName, string v)
  26. {
  27. return string.Format(BP.Sys.Language.GetValByUserLang(s, chName), v);
  28. }
  29. public string ToEP2(string s, string chName, string v, string v1)
  30. {
  31. return string.Format(BP.Sys.Language.GetValByUserLang(s, chName), v, v1);
  32. }
  33. public string ToEP3(string s, string chName, string v, string v1, string v2)
  34. {
  35. return string.Format(BP.Sys.Language.GetValByUserLang(s, chName), v, v1, v2);
  36. }
  37. #endregion
  38. #region 权限判断
  39. /// <summary>
  40. /// 判断一个人能不能对这个工作节点进行操作。
  41. /// </summary>
  42. /// <param name="empId"></param>
  43. /// <returns></returns>
  44. private bool IsCanOpenCurrentWorkNode(string empId)
  45. {
  46. NodeState stat = this.HisWork.NodeState;
  47. if (stat == NodeState.Init)
  48. {
  49. if (this.HisNode.IsStartNode)
  50. {
  51. /*如果是开始工作节点,从工作岗位判断他有没有工作的权限。*/
  52. return WorkFlow.IsCanDoWorkCheckByEmpStation(this.HisNode.NodeID, empId);
  53. }
  54. else
  55. {
  56. /* 如果是初始化阶段,判断他的初始化节点 */
  57. WorkerList wl = new WorkerList();
  58. wl.WorkID = this.HisWork.OID;
  59. wl.FK_Emp = empId;
  60. Emp myEmp = new Emp(empId);
  61. wl.FK_EmpText = myEmp.Name;
  62. wl.FK_Node = this.HisNode.NodeID;
  63. wl.FK_NodeText = this.HisNode.Name;
  64. return wl.IsExits;
  65. }
  66. }
  67. else
  68. {
  69. /* 如果是初始化阶段 */
  70. return false;
  71. }
  72. }
  73. #endregion
  74. //查询出每个节点表里的接收人集合(Emps)。
  75. public string GenerEmps(Node nd)
  76. {
  77. string str = "";
  78. foreach (WorkerList wl in this.HisWorkerLists)
  79. str = wl.FK_Emp + ",";
  80. return str;
  81. }
  82. private string _VirPath = null;
  83. /// <summary>
  84. /// 虚拟目录的路径
  85. /// </summary>
  86. public string VirPath
  87. {
  88. get
  89. {
  90. if (_VirPath == null && BP.SystemConfig.IsBSsystem)
  91. _VirPath = System.Web.HttpContext.Current.Request.ApplicationPath ;
  92. return _VirPath;
  93. }
  94. }
  95. private string _AppType = null;
  96. /// <summary>
  97. /// 虚拟目录的路径
  98. /// </summary>
  99. public string AppType
  100. {
  101. get
  102. {
  103. if (_AppType == null)
  104. {
  105. if (BP.Web.WebUser.IsWap)
  106. _AppType = "/WF/WAP";
  107. else
  108. _AppType = "/WF";
  109. }
  110. return _AppType;
  111. }
  112. }
  113. private string nextStationName = "";
  114. /// <summary>
  115. /// 产生下一步的工作者
  116. /// </summary>
  117. /// <param name="town">WorkNode</param>
  118. /// <returns></returns>
  119. public WorkerLists InitWorkerLists_QingHai(WorkNode town)
  120. {
  121. DataTable dt = new DataTable();
  122. // dt = DBAccess.RunSQLReturnTable("SELECT NO,NAME FROM PUB_EMP WHERE 1=2 ");
  123. dt.Columns.Add("No", typeof(string));
  124. string sql;
  125. string fk_emp;
  126. // 如果执行了两次发送,那前一次的轨迹就需要被删除。这里是为了避免错误。
  127. DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE WorkID=" + this.HisWork.OID + " AND FK_Node =" + town.HisNode.NodeID);
  128. // 判断当前节点是否采集了目标人员.(分配责任区)
  129. if (this.HisWork.EnMap.Attrs.Contains("FK_Emp"))
  130. {
  131. //sql="SELECT No,Name FROM PUB_EMP WHERE NO='"+this.HisWork.GetValStringByKey("FK_Emp")+"'";
  132. fk_emp = this.HisWork.GetValStringByKey("FK_Emp");
  133. DataRow dr = dt.NewRow();
  134. dr[0] = fk_emp;
  135. dt.Rows.Add(dr);
  136. //dt=DBAccess.RunSQLReturnTable(sql);
  137. return WorkerListWayOfDept(town, dt);
  138. }
  139. //分配分局(所)长
  140. if (this.HisWork.EnMap.Attrs.Contains("FK_FJZ"))
  141. {
  142. fk_emp = this.HisWork.GetValStringByKey("FK_FJZ");
  143. DataRow dr = dt.NewRow();
  144. dr[0] = fk_emp;
  145. dt.Rows.Add(dr);
  146. //sql = "SELECT No,Name FROM PUB_EMP WHERE NO='" + this.HisWork.GetValStringByKey("FK_FJZ") + "'";
  147. //dt = DBAccess.RunSQLReturnTable(sql);
  148. return WorkerListWayOfDept(town, dt);
  149. }
  150. //从轨迹里面查询.
  151. sql = "SELECT DISTINCT FK_Emp FROM Port_EmpStation WHERE FK_Station IN "
  152. + "(SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") "
  153. + "AND FK_Emp IN (SELECT FK_Emp FROM WF_GenerWorkerlist WHERE WorkID=" + this.HisWork.OID + ")";
  154. dt = DBAccess.RunSQLReturnTable(sql);
  155. // 如果能够找到.
  156. if (dt.Rows.Count >= 1)
  157. {
  158. return WorkerListWayOfDept(town, dt);
  159. }
  160. // 没有查询到的情况下。
  161. Stations nextStations = town.HisNode.HisStations;
  162. // 找不到, 就要判断流向问题。
  163. Station fromSt = this.HisStationOfUse;
  164. string DeptofUse = this.HisDeptOfUse.No;
  165. if (nextStations.Count == 0)
  166. throw new Exception(this.ToEP1("WF2", "@工作流程{0}已经完成。", town.HisNode.Name)); //管理员维护错误,您没有给节点["+town.HisNode.Name+"]设置工作岗位。
  167. Station toSt = (Station)nextStations[0];
  168. if (fromSt.No == toSt.No)
  169. {
  170. #warning edit 2008 - 05-28 .
  171. // sql = "SELECT No,Name FROM Port_Emp WHERE NO IN (SELECT FK_Dept FROM Port_EmpDept WHERE FK_EMP='" + WebUser.No + "') AND NO IN (SELECT FK_Emp FROM Port_EmpSTATION WHERE FK_Station='" + toSt.No + "')";
  172. sql = "SELECT No,Name FROM Port_Emp WHERE NO='" + WebUser.No + "'"; // IN (SELECT FK_Dept FROM Port_EmpDept WHERE FK_EMP='" + WebUser.No + "') AND NO IN (SELECT FK_Emp FROM Port_EmpSTATION WHERE FK_Station='" + toSt.No + "')";
  173. dt = DBAccess.RunSQLReturnTable(sql);
  174. if (dt.Rows.Count == 0)
  175. {
  176. fk_emp = this.HisWork.GetValStringByKey("FK_FJZ");
  177. DataRow dr = dt.NewRow();
  178. dr[0] = fk_emp;
  179. dt.Rows.Add(dr);
  180. return WorkerListWayOfDept(town, dt);
  181. }
  182. else
  183. {
  184. return WorkerListWayOfDept(town, dt);
  185. }
  186. }
  187. if (fromSt.Grade < toSt.Grade)
  188. {
  189. }
  190. else if (fromSt.Grade == toSt.Grade)
  191. {
  192. }
  193. else
  194. {
  195. }
  196. return WorkerListWayOfDept(town, dt);
  197. }
  198. private WorkNode town = null;
  199. public WorkerLists GenerWorkerLists_WidthFID(WorkNode town)
  200. {
  201. this.town = town;
  202. DataTable dt = new DataTable();
  203. dt.Columns.Add("No", typeof(string));
  204. string sql;
  205. string fk_emp;
  206. // 如果执行了两次发送,那前一次的轨迹就需要被删除。这里是为了避免错误。
  207. DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE WorkID=" + this.HisWork.FID + " AND FK_Node=" + town.HisNode.NodeID);
  208. #region 首先判断是否配置了获取下一步接受人员的sql.
  209. if (town.HisNode.HisDeliveryWay == DeliveryWay.BySQL)
  210. {
  211. if (town.HisNode.RecipientSQL.Length < 4)
  212. throw new Exception("@您设置的当前节点按照sql,决定下一步的接受人员,但是你没有设置sql.");
  213. Attrs attrs = this.HisWork.EnMap.Attrs;
  214. sql = this.HisNode.RecipientSQL;
  215. foreach (Attr attr in attrs)
  216. {
  217. if (attr.MyDataType == DataType.AppString)
  218. sql = sql.Replace("@" + attr.Key, "'" + this.HisWork.GetValStrByKey(attr.Key) + "'");
  219. else
  220. sql = sql.Replace("@" + attr.Key, this.HisWork.GetValStrByKey(attr.Key));
  221. }
  222. sql = sql.Replace("~", "'");
  223. dt = DBAccess.RunSQLReturnTable(sql);
  224. if (dt.Rows.Count == 0)
  225. throw new Exception("@没有找到可接受的工作人员。@技术信息:执行的sql没有发现人员:" + sql);
  226. return WorkerListWayOfDept(town, dt);
  227. }
  228. #endregion
  229. // 按上一节点发送人处理。
  230. if (town.HisNode.HisDeliveryWay == DeliveryWay.ByPreviousOper
  231. || town.HisNode.HisDeliveryWay == DeliveryWay.ByPreviousOperSkip)
  232. {
  233. DataRow dr = dt.NewRow();
  234. dr[0] = Web.WebUser.No;
  235. dt.Rows.Add(dr);
  236. return WorkerListWayOfDept(town, dt);
  237. }
  238. // 按照选择的人员处理。
  239. if (town.HisNode.HisDeliveryWay == DeliveryWay.BySelected)
  240. {
  241. sql = "SELECT FK_Emp FROM WF_SelectAccper WHERE FK_Node=" + this.HisNode.NodeID + " AND WorkID=" + this.WorkID;
  242. dt = DBAccess.RunSQLReturnTable(sql);
  243. return WorkerListWayOfDept(town, dt);
  244. }
  245. // 按照节点指定的人员处理。
  246. if (town.HisNode.HisDeliveryWay == DeliveryWay.BySpcEmp)
  247. {
  248. dt = DBAccess.RunSQLReturnTable("SELECT FK_Emp FROM WF_NodeEmp WHERE FK_Node=" + town.HisNode.NodeID);
  249. if (dt.Rows.Count == 0)
  250. throw new Exception("@您设置的当前节点按照节点绑定人员,但是你没有为(" + town.HisNode.NodeID + "," + town.HisNode.Name + ")节点绑定人员。");
  251. return WorkerListWayOfDept(town, dt);
  252. }
  253. // 按照表单字段人员处理。
  254. if (town.HisNode.HisDeliveryWay == DeliveryWay.ByEmp)
  255. {
  256. if (this.HisWork.EnMap.Attrs.Contains("FK_Emp") == false)
  257. throw new Exception("@您设置的当前节点按照指定节点表单字段人员,决定下一步的接受人员,但是你没有在节点(" + town.HisNode.NodeID + "," + town.HisNode.Name + ")表单中设置该表单FK_Emp字段。");
  258. fk_emp = this.HisWork.GetValStringByKey("FK_Emp");
  259. DataRow dr = dt.NewRow();
  260. dr[0] = fk_emp;
  261. dt.Rows.Add(dr);
  262. return WorkerListWayOfDept(town, dt);
  263. }
  264. //// 判断 节点人员里是否有设置? 如果有就不考虑岗位设置了。从节点人员设置里面查询。
  265. //if (town.HisNode.HisEmps.Length > 2)
  266. //{
  267. // string[] emps = town.HisNode.HisEmps.Split('@');
  268. // foreach (string emp in emps)
  269. // {
  270. // if (emp == null || emp == "")
  271. // continue;
  272. // DataRow dr = dt.NewRow();
  273. // dr[0] = emp;
  274. // dt.Rows.Add(dr);
  275. // }
  276. // return WorkerListWayOfDept(town, dt);
  277. //}
  278. // 判断节点部门里面是否设置了部门,如果设置了,就按照它的部门处理。
  279. if (town.HisNode.HisDeliveryWay == DeliveryWay.ByDept)
  280. {
  281. sql = "SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept IN ( SELECT FK_Dept FROM WF_NodeDept WHERE FK_Node=" + town.HisNode.NodeID + ")";
  282. dt = DBAccess.RunSQLReturnTable(sql);
  283. if (dt.Rows.Count > 0)
  284. return WorkerListWayOfDept(town, dt);
  285. else
  286. throw new Exception("流程设计错误或组织结构维护不完整:没有找到按部门计算访问的节点人员。");
  287. }
  288. if (town.HisNode.HisDeliveryWay == DeliveryWay.ByDeptAndStation)
  289. {
  290. /* 如果还设置了岗位的集合的话,就按两个的交集计算。 */
  291. sql = "SELECT NO FROM Port_Emp WHERE NO IN ";
  292. sql += "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept IN ";
  293. sql += "( SELECT FK_Dept FROM WF_NodeDept WHERE FK_Node=" + town.HisNode.NodeID + ")";
  294. sql += ")";
  295. sql += "AND NO IN ";
  296. sql += "(";
  297. sql += "SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN ";
  298. sql += "( SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ")";
  299. sql += ")";
  300. dt = DBAccess.RunSQLReturnTable(sql);
  301. if (dt.Rows.Count > 0)
  302. return WorkerListWayOfDept(town, dt);
  303. else
  304. throw new Exception("流程设计错误或组织结构维护不完整:没有找到“按部门与岗位的交集计算”的节点人员。");
  305. }
  306. #region 按指定的节点人员做为下一步骤的流程接受人
  307. string empNo = WebUser.No;
  308. string empDept = WebUser.FK_Dept;
  309. if (town.HisNode.HisDeliveryWay == DeliveryWay.BySpecNodeStation)
  310. {
  311. /* 按指定节点岗位上的人员计算 */
  312. string fk_node = town.HisNode.RecipientSQL;
  313. if (DataType.IsNumStr(fk_node) == false)
  314. throw new Exception("流程设计错误:您设置的节点(" + town.HisNode.Name + ")的接收方式为按指定的节点岗位投递,但是您没有在访问规则设置中设置节点编号。");
  315. dt = DBAccess.RunSQLReturnTable("SELECT Rec FROM ND" + fk_node + " WHERE OID=" + this.WorkID);
  316. if (dt.Rows.Count == 1)
  317. return WorkerListWayOfDept(town, dt);
  318. throw new Exception("@流程设计错误,到达的节点(" + town.HisNode.Name + ")在指定的节点中没有数据,无法找到工作的人员。");
  319. }
  320. #endregion 按指定的节点人员做为下一步骤的流程接受人
  321. #region 最后一定是按照岗位来执行
  322. if (this.HisNode.IsStartNode == false)
  323. {
  324. // 如果当前的节点不是开始节点, 从轨迹里面查询。
  325. sql = "SELECT DISTINCT FK_Emp FROM Port_EmpStation WHERE FK_Station IN "
  326. + "(SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") "
  327. + "AND FK_Emp IN (SELECT FK_Emp FROM WF_GenerWorkerlist WHERE WorkID=" + this.HisWork.FID + " AND FK_Node IN (" + DataType.PraseAtToInSql(town.HisNode.GroupStaNDs, true) + ") )";
  328. dt = DBAccess.RunSQLReturnTable(sql);
  329. // 如果能够找到.
  330. if (dt.Rows.Count >= 1)
  331. {
  332. if (dt.Rows.Count == 1)
  333. {
  334. /* 如果人员只有一个的情况,说明他可能要 */
  335. }
  336. return WorkerListWayOfDept(town, dt);
  337. }
  338. }
  339. /* 如果执行节点 与 接受节点岗位集合一致 */
  340. if (this.HisNode.GroupStaNDs == town.HisNode.GroupStaNDs)
  341. {
  342. /* 说明,就把当前人员做为下一个节点处理人。*/
  343. DataRow dr = dt.NewRow();
  344. dr[0] = empNo;
  345. dt.Rows.Add(dr);
  346. return WorkerListWayOfDept(town, dt);
  347. }
  348. /* 如果执行节点 与 接受节点岗位集合不一致 */
  349. if (this.HisNode.GroupStaNDs != town.HisNode.GroupStaNDs)
  350. {
  351. /* 没有查询到的情况下, 先按照本部门计算。*/
  352. sql = "SELECT No FROM Port_Emp WHERE NO IN "
  353. + "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") )"
  354. + " AND NO IN "
  355. + "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept = '" + empDept + "')";
  356. dt = DBAccess.RunSQLReturnTable(sql);
  357. if (dt.Rows.Count == 0)
  358. {
  359. Stations nextStations = town.HisNode.HisStations;
  360. if (nextStations.Count == 0)
  361. throw new Exception(this.ToE("WN19", "节点没有岗位:") + town.HisNode.NodeID + " " + town.HisNode.Name);
  362. }
  363. else
  364. {
  365. bool isInit = false;
  366. foreach (DataRow dr in dt.Rows)
  367. {
  368. if (dr[0].ToString() == empNo)
  369. {
  370. /* 如果岗位分组不一样,并且结果集合里还有当前的人员,就说明了出现了当前操作员,拥有本节点上的岗位也拥有下一个节点的工作岗位
  371. 导致:节点的分组不同,传递到同一个人身上。 */
  372. isInit = true;
  373. }
  374. }
  375. if (isInit == false)
  376. return WorkerListWayOfDept(town, dt);
  377. }
  378. }
  379. // 没有查询到的情况下, 执行查询隶属本部门的下级部门人员。
  380. sql = "SELECT NO FROM Port_Emp WHERE NO IN "
  381. + "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") )"
  382. + " AND NO IN "
  383. + "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept LIKE '" + empDept + "%')"
  384. + " AND No!='" + empNo + "'";
  385. dt = DBAccess.RunSQLReturnTable(sql);
  386. if (dt.Rows.Count == 0)
  387. {
  388. Stations nextStations = town.HisNode.HisStations;
  389. if (nextStations.Count == 0)
  390. throw new Exception(this.ToE("WN19", "节点没有岗位:") + town.HisNode.NodeID + " " + town.HisNode.Name);
  391. }
  392. else
  393. {
  394. return WorkerListWayOfDept(town, dt);
  395. }
  396. // 没有查询到的情况下, 按照最大匹配数 提高一个级别 计算,递归算法未完成,不过现在已经满足大部分需要。
  397. int lengthStep = 0; //增长步骤。
  398. while (true)
  399. {
  400. lengthStep += 2;
  401. int toLen = empDept.Length - lengthStep;
  402. if (toLen <= 0)
  403. throw new Exception("@已经列举到最高部门,仍然没有找到接受人员。");
  404. sql = "SELECT NO FROM Port_Emp WHERE No IN "
  405. + "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") )"
  406. + " AND NO IN "
  407. + "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept LIKE '" + empDept.Substring(0, empDept.Length - lengthStep) + "%')"
  408. + " AND No!='" + empNo+ "'";
  409. dt = DBAccess.RunSQLReturnTable(sql);
  410. if (dt.Rows.Count == 0)
  411. {
  412. Stations nextStations = town.HisNode.HisStations;
  413. if (nextStations.Count == 0)
  414. throw new Exception(this.ToE("WN19", "节点没有岗位:") + town.HisNode.NodeID + " " + town.HisNode.Name);
  415. sql = "SELECT No FROM Port_Emp WHERE NO IN ";
  416. sql += "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + " ) )";
  417. sql += " AND No IN ";
  418. if (empDept.Length == 2)
  419. sql += "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Emp!='" + empNo + "') ";
  420. else
  421. sql += "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Emp!='" + empNo + "' AND FK_Dept LIKE '" + empDept.Substring(0, empDept.Length - 4) + "%')";
  422. dt = DBAccess.RunSQLReturnTable(sql);
  423. if (dt.Rows.Count == 0)
  424. {
  425. sql = "SELECT No FROM Port_Emp WHERE No!='" + empNo + "' AND No IN ";
  426. sql += "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + " ) )";
  427. dt = DBAccess.RunSQLReturnTable(sql);
  428. if (dt.Rows.Count == 0)
  429. {
  430. string msg = town.HisNode.HisStationsStr;
  431. throw new Exception(this.ToE("WF3", "岗位(" + msg + ")下没有人员,对应节点:") + town.HisNode.Name);
  432. //"维护错误,请检查[" + town.HisNode.Name + "]维护的岗位中是否有人员?"
  433. }
  434. }
  435. return WorkerListWayOfDept(town, dt);
  436. }
  437. else
  438. {
  439. return WorkerListWayOfDept(town, dt);
  440. }
  441. }
  442. #endregion 按照岗位来执行
  443. }
  444. public WorkerLists GenerWorkerLists(WorkNode town)
  445. {
  446. this.town = town;
  447. DataTable dt = new DataTable();
  448. dt.Columns.Add("No", typeof(string));
  449. string sql;
  450. string fk_emp;
  451. // 如果执行了两次发送,那前一次的轨迹就需要被删除。这里是为了避免错误。
  452. DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE WorkID=" + this.HisWork.OID + " AND FK_Node =" + town.HisNode.NodeID);
  453. // 如果指定特定的人员处理。
  454. if (JumpToEmp != null)
  455. {
  456. DataRow dr = dt.NewRow();
  457. dr[0] = JumpToEmp;
  458. dt.Rows.Add(dr);
  459. return WorkerListWayOfDept(town, dt);
  460. }
  461. // 按上一节点发送人处理。
  462. if (town.HisNode.HisDeliveryWay == DeliveryWay.ByPreviousOper
  463. || town.HisNode.HisDeliveryWay == DeliveryWay.ByPreviousOperSkip)
  464. {
  465. DataRow dr = dt.NewRow();
  466. dr[0] = Web.WebUser.No;
  467. dt.Rows.Add(dr);
  468. return WorkerListWayOfDept(town, dt);
  469. }
  470. //首先判断是否配置了获取下一步接受人员的sql.
  471. if (town.HisNode.HisDeliveryWay == DeliveryWay.BySQL)
  472. {
  473. if (town.HisNode.RecipientSQL.Length < 4)
  474. throw new Exception("@您设置的当前节点按照sql,决定下一步的接受人员,但是你没有设置sql.");
  475. Attrs attrs = this.HisWork.EnMap.Attrs;
  476. sql = town.HisNode.RecipientSQL;
  477. foreach (Attr attr in attrs)
  478. {
  479. if (attr.MyDataType == DataType.AppString)
  480. sql = sql.Replace("@" + attr.Key, "'" + this.HisWork.GetValStrByKey(attr.Key) + "'");
  481. else
  482. sql = sql.Replace("@" + attr.Key, this.HisWork.GetValStrByKey(attr.Key));
  483. }
  484. sql = sql.Replace("~", "'");
  485. sql = sql.Replace("@WebUser.No", "'" + WebUser.No + "'");
  486. sql = sql.Replace("@WebUser.Name", "'" + WebUser.Name + "'");
  487. sql = sql.Replace("@WebUser.FK_Dept", "'" + WebUser.FK_Dept + "'");
  488. dt = DBAccess.RunSQLReturnTable(sql);
  489. if (dt.Rows.Count == 0)
  490. throw new Exception("@没有找到可接受的工作人员。@技术信息:执行的sql没有发现人员:" + sql);
  491. return WorkerListWayOfDept(town, dt);
  492. }
  493. // 按照选择的人员处理。
  494. if (town.HisNode.HisDeliveryWay == DeliveryWay.BySelected)
  495. {
  496. sql = "SELECT FK_Emp FROM WF_SelectAccper WHERE FK_Node=" + this.HisNode.NodeID + " AND WorkID=" + this.WorkID;
  497. dt = DBAccess.RunSQLReturnTable(sql);
  498. if (dt.Rows.Count == 0)
  499. throw new Exception("请选择下一步骤工作(" + town.HisNode.Name + ")接受人员。");
  500. return WorkerListWayOfDept(town, dt);
  501. }
  502. // 按照节点指定的人员处理。
  503. if (town.HisNode.HisDeliveryWay == DeliveryWay.BySpcEmp)
  504. {
  505. dt = DBAccess.RunSQLReturnTable("SELECT FK_Emp FROM WF_NodeEmp WHERE FK_Node=" + town.HisNode.NodeID);
  506. if (dt.Rows.Count == 0)
  507. throw new Exception("@您设置的当前节点按照节点绑定人员,但是你没有为(" + town.HisNode.NodeID + "," + town.HisNode.Name + ")节点绑定人员。");
  508. //fk_emp = this.HisWork.GetValStringByKey("FK_Emp");
  509. //DataRow dr = dt.NewRow();
  510. //dr[0] = fk_emp;
  511. //dt.Rows.Add(dr);
  512. return WorkerListWayOfDept(town, dt);
  513. }
  514. // 按照节点指定的人员处理。
  515. if (town.HisNode.HisDeliveryWay == DeliveryWay.ByEmp)
  516. {
  517. if (this.HisWork.EnMap.Attrs.Contains("FK_Emp") == false)
  518. throw new Exception("@您设置的当前节点按照指定的人员,决定下一步的接受人员,但是你没有在节点表单中设置该表单FK_Emp字段。");
  519. fk_emp = this.HisWork.GetValStringByKey("FK_Emp");
  520. DataRow dr = dt.NewRow();
  521. dr[0] = fk_emp;
  522. dt.Rows.Add(dr);
  523. return WorkerListWayOfDept(town, dt);
  524. }
  525. string prjNo = "";
  526. FlowAppType flowAppType = this.HisNode.HisFlow.HisFlowAppType;
  527. sql = "";
  528. if (this.HisNode.HisFlow.HisFlowAppType == FlowAppType.PRJ)
  529. {
  530. prjNo = "";
  531. try
  532. {
  533. prjNo = this.HisWork.GetValStrByKey("PrjNo");
  534. }
  535. catch (Exception ex)
  536. {
  537. throw new Exception("@当前流程是工程类流程,但是在节点表单中没有PrjNo字段(注意区分大小写),请确认。@异常信息:" + ex.Message);
  538. }
  539. }
  540. #region 按部门与岗位的交集计算.
  541. if (town.HisNode.HisDeliveryWay == DeliveryWay.ByDeptAndStation)
  542. {
  543. sql = "SELECT No FROM Port_Emp WHERE No IN ";
  544. sql += "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept IN ";
  545. sql += "( SELECT FK_Dept FROM WF_NodeDept WHERE FK_Node=" + town.HisNode.NodeID + ")";
  546. sql += ")";
  547. sql += "AND No IN ";
  548. sql += "(";
  549. sql += "SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN ";
  550. sql += "( SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ")";
  551. sql += ")";
  552. dt = DBAccess.RunSQLReturnTable(sql);
  553. if (dt.Rows.Count > 0)
  554. return WorkerListWayOfDept(town, dt);
  555. else
  556. throw new Exception("@节点访问规则错误:节点(" + town.HisNode.NodeID + "," + town.HisNode.Name + "), 按照岗位与部门的交集确定接受人的范围错误,没有找到人员:SQL=" + sql);
  557. }
  558. #endregion 按部门与岗位的交集计算.
  559. #region 判断节点部门里面是否设置了部门如果设置了就按照它的部门处理
  560. if (town.HisNode.HisDeliveryWay == DeliveryWay.ByDept)
  561. {
  562. if (flowAppType == FlowAppType.Normal)
  563. {
  564. sql = "SELECT DISTINCT FK_Emp FROM Port_EmpDept WHERE FK_Dept IN ( SELECT FK_Dept FROM WF_NodeDept WHERE FK_Node=" + town.HisNode.NodeID + ")";
  565. dt = DBAccess.RunSQLReturnTable(sql);
  566. if (dt.Rows.Count > 0)
  567. return WorkerListWayOfDept(town, dt);
  568. }
  569. if (flowAppType == FlowAppType.PRJ)
  570. {
  571. sql = "SELECT No FROM Port_Emp WHERE No IN ";
  572. sql += "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept IN ";
  573. sql += "( SELECT FK_Dept FROM WF_NodeDept WHERE FK_Node=" + town.HisNode.NodeID + ")";
  574. sql += ")";
  575. sql += "AND NO IN ";
  576. sql += "(";
  577. sql += "SELECT FK_Emp FROM Prj_EmpPrjStation WHERE FK_Station IN ";
  578. sql += "( SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") AND FK_Prj='" + prjNo + "'";
  579. sql += ")";
  580. dt = DBAccess.RunSQLReturnTable(sql);
  581. if (dt.Rows.Count == 0)
  582. {
  583. /* 如果项目组里没有工作人员就提交到公共部门里去找。*/
  584. sql = "SELECT NO FROM Port_Emp WHERE NO IN ";
  585. sql += "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept IN ";
  586. sql += "( SELECT FK_Dept FROM WF_NodeDept WHERE FK_Node=" + town.HisNode.NodeID + ")";
  587. sql += ")";
  588. sql += "AND NO IN ";
  589. sql += "(";
  590. sql += "SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN ";
  591. sql += "( SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ")";
  592. sql += ")";
  593. }
  594. else
  595. {
  596. return WorkerListWayOfDept(town, dt);
  597. }
  598. dt = DBAccess.RunSQLReturnTable(sql);
  599. if (dt.Rows.Count > 0)
  600. return WorkerListWayOfDept(town, dt);
  601. }
  602. }
  603. #endregion 判断节点部门里面是否设置了部门如果设置了就按照它的部门处理
  604. #region 按指定的节点人员做为下一步骤的流程接受人
  605. string empNo = WebUser.No;
  606. string empDept = WebUser.FK_Dept;
  607. if (town.HisNode.HisDeliveryWay == DeliveryWay.BySpecNodeStation)
  608. {
  609. /* 按指定节点岗位上的人员计算 */
  610. string fk_node = town.HisNode.RecipientSQL;
  611. if (DataType.IsNumStr(fk_node) == false)
  612. throw new Exception("流程设计错误:您设置的节点(" + town.HisNode.Name + ")的接收方式为按指定的节点岗位投递,但是您没有在访问规则设置中设置节点编号。");
  613. dt = DBAccess.RunSQLReturnTable("SELECT Rec FROM ND" + fk_node + " WHERE OID=" + this.WorkID);
  614. if (dt.Rows.Count == 1)
  615. return WorkerListWayOfDept(town, dt);
  616. throw new Exception("@流程设计错误,到达的节点(" + town.HisNode.Name + ")在指定的节点中没有数据,无法找到工作的人员。");
  617. }
  618. #endregion 按指定的节点人员做为下一步骤的流程接受人
  619. #region 按节点岗位与人员部门集合两个纬度计算.
  620. if (town.HisNode.HisDeliveryWay == DeliveryWay.ByStationAndEmpDept)
  621. {
  622. sql = "SELECT No FROM Port_Emp WHERE NO IN "
  623. + "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") )"
  624. + " AND FK_Dept IN "
  625. + "(SELECT FK_Dept FROM Port_EmpDept WHERE FK_Emp = '" + WebUser.No + "')";
  626. //2012.7.16李健修改
  627. //+" AND NO IN "
  628. //+ "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Emp = '" + WebUser.No + "')";
  629. dt = DBAccess.RunSQLReturnTable(sql);
  630. if (dt.Rows.Count > 0)
  631. return WorkerListWayOfDept(town, dt);
  632. else
  633. throw new Exception("@节点访问规则错误:节点(" + town.HisNode.NodeID + "," + town.HisNode.Name + "), 按节点岗位与人员部门集合两个纬度计算,没有找到人员:SQL=" + sql);
  634. }
  635. #endregion
  636. if (town.HisNode.HisDeliveryWay != DeliveryWay.ByStation)
  637. throw new Exception("@没有判断的执行规则:" + town.HisNode.HisDeliveryWay);
  638. #region 最后判断 - 按照岗位来执行
  639. if (this.HisNode.IsStartNode == false)
  640. {
  641. if (flowAppType == FlowAppType.Normal)
  642. {
  643. // 如果当前的节点不是开始节点, 从轨迹里面查询。
  644. sql = "SELECT DISTINCT FK_Emp FROM Port_EmpStation WHERE FK_Station IN "
  645. + "(SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") "
  646. + "AND FK_Emp IN (SELECT FK_Emp FROM WF_GenerWorkerlist WHERE WorkID=" + this.HisWork.OID + " AND FK_Node IN (" + DataType.PraseAtToInSql(town.HisNode.GroupStaNDs, true) + ") )";
  647. }
  648. if (flowAppType == FlowAppType.PRJ)
  649. {
  650. // 如果当前的节点不是开始节点, 从轨迹里面查询。
  651. sql = "SELECT DISTINCT FK_Emp FROM Prj_EmpPrjStation WHERE FK_Station IN "
  652. + "(SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") AND FK_Prj='" + prjNo + "' "
  653. + "AND FK_Emp IN (SELECT FK_Emp FROM WF_GenerWorkerlist WHERE WorkID=" + this.HisWork.OID + " AND FK_Node IN (" + DataType.PraseAtToInSql(town.HisNode.GroupStaNDs, true) + ") )";
  654. dt = DBAccess.RunSQLReturnTable(sql);
  655. if (dt.Rows.Count == 0)
  656. {
  657. /* 如果项目组里没有工作人员就提交到公共部门里去找。*/
  658. sql = "SELECT DISTINCT FK_Emp FROM Port_EmpStation WHERE FK_Station IN "
  659. + "(SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") "
  660. + "AND FK_Emp IN (SELECT FK_Emp FROM WF_GenerWorkerlist WHERE WorkID=" + this.HisWork.OID + " AND FK_Node IN (" + DataType.PraseAtToInSql(town.HisNode.GroupStaNDs, true) + ") )";
  661. }
  662. else
  663. {
  664. return WorkerListWayOfDept(town, dt);
  665. }
  666. }
  667. dt = DBAccess.RunSQLReturnTable(sql);
  668. // 如果能够找到.
  669. if (dt.Rows.Count >= 1)
  670. {
  671. if (dt.Rows.Count == 1)
  672. {
  673. /*如果人员只有一个的情况,说明他可能要 */
  674. }
  675. return WorkerListWayOfDept(town, dt);
  676. }
  677. }
  678. /* 如果执行节点 与 接受节点岗位集合一致 */
  679. if (this.HisNode.GroupStaNDs == town.HisNode.GroupStaNDs)
  680. {
  681. /* 说明,就把当前人员做为下一个节点处理人。*/
  682. DataRow dr = dt.NewRow();
  683. dr[0] = WebUser.No;
  684. dt.Rows.Add(dr);
  685. return WorkerListWayOfDept(town, dt);
  686. }
  687. /* 如果执行节点 与 接受节点岗位集合不一致 */
  688. if (this.HisNode.GroupStaNDs != town.HisNode.GroupStaNDs)
  689. {
  690. /* 没有查询到的情况下, 先按照本部门计算。*/
  691. if (flowAppType == FlowAppType.Normal)
  692. {
  693. sql = "SELECT NO FROM Port_Emp WHERE NO IN "
  694. + "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") )"
  695. + " AND NO IN "
  696. + "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept = '" + empDept + "')";
  697. }
  698. if (flowAppType == FlowAppType.PRJ)
  699. {
  700. sql = "SELECT FK_Emp FROM Prj_EmpPrjStation WHERE FK_Prj='" + prjNo + "' AND FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ")"
  701. + " AND FK_Prj='" + prjNo + "' ";
  702. dt = DBAccess.RunSQLReturnTable(sql);
  703. if (dt.Rows.Count == 0)
  704. {
  705. /* 如果项目组里没有工作人员就提交到公共部门里去找。 */
  706. sql = "SELECT NO FROM Port_Emp WHERE NO IN "
  707. + "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") )"
  708. + " AND NO IN "
  709. + "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept = '" + empDept + "')";
  710. }
  711. else
  712. {
  713. return WorkerListWayOfDept(town, dt);
  714. }
  715. }
  716. dt = DBAccess.RunSQLReturnTable(sql);
  717. if (dt.Rows.Count == 0)
  718. {
  719. Stations nextStations = town.HisNode.HisStations;
  720. if (nextStations.Count == 0)
  721. throw new Exception(this.ToE("WN19", "节点没有岗位:") + town.HisNode.NodeID + " " + town.HisNode.Name);
  722. }
  723. else
  724. {
  725. bool isInit = false;
  726. foreach (DataRow dr in dt.Rows)
  727. {
  728. if (dr[0].ToString() == Web.WebUser.No)
  729. {
  730. /* 如果岗位分组不一样,并且结果集合里还有当前的人员,就说明了出现了当前操作员,拥有本节点上的岗位也拥有下一个节点的工作岗位
  731. 导致:节点的分组不同,传递到同一个人身上。 */
  732. isInit = true;
  733. }
  734. }
  735. #warning edit by peng, 用来确定不同岗位集合的传递包含同一个人的处理方式
  736. if (isInit == false || isInit == true)
  737. return WorkerListWayOfDept(town, dt);
  738. }
  739. }
  740. // 没有查询到的情况下, 执行查询隶属本部门的下级部门人员。
  741. if (flowAppType == FlowAppType.Normal)
  742. {
  743. sql = "SELECT NO FROM Port_Emp WHERE NO IN "
  744. + "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") )"
  745. + " AND NO IN "
  746. + "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept LIKE '" + empDept + "%')"
  747. + " AND No!='" + empNo + "'";
  748. }
  749. if (flowAppType == FlowAppType.PRJ)
  750. {
  751. sql = "SELECT FK_Emp FROM Prj_EmpPrjStation WHERE FK_Prj='" + prjNo + "' AND FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ")"
  752. + " AND FK_Prj='" + prjNo + "' ";
  753. dt = DBAccess.RunSQLReturnTable(sql);
  754. if (dt.Rows.Count == 0)
  755. {
  756. /* 如果项目组里没有工作人员就提交到公共部门里去找。*/
  757. sql = "SELECT NO FROM Port_Emp WHERE NO IN "
  758. + "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") )"
  759. + " AND NO IN "
  760. + "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept LIKE '" + empDept + "%')"
  761. + " AND No!='" + empNo + "'";
  762. }
  763. else
  764. {
  765. return WorkerListWayOfDept(town, dt);
  766. }
  767. }
  768. dt = DBAccess.RunSQLReturnTable(sql);
  769. if (dt.Rows.Count == 0)
  770. {
  771. Stations nextStations = town.HisNode.HisStations;
  772. if (nextStations.Count == 0)
  773. throw new Exception(this.ToE("WN19", "节点没有岗位:") + town.HisNode.NodeID + " " + town.HisNode.Name);
  774. }
  775. else
  776. {
  777. return WorkerListWayOfDept(town, dt);
  778. }
  779. /* 没有查询到的情况下, 按照最大匹配数 提高一个级别 计算,递归算法未完成,不过现在已经满足大部分需要。
  780. *
  781. * 因为:以上已经做的岗位的判断,就没有必要在判断其它类型的流程处理了。
  782. *
  783. * */
  784. int lengthStep = 0; //增长步骤。
  785. while (true)
  786. {
  787. lengthStep += 2;
  788. sql = "SELECT NO FROM Port_Emp WHERE No IN "
  789. + "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") )"
  790. + " AND NO IN "
  791. + "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept LIKE '" + empDept.Substring(0, empDept.Length - lengthStep) + "%')"
  792. + " AND No!='" + empNo + "'";
  793. dt = DBAccess.RunSQLReturnTable(sql);
  794. if (dt.Rows.Count == 0)
  795. {
  796. Stations nextStations = town.HisNode.HisStations;
  797. if (nextStations.Count == 0)
  798. throw new Exception(this.ToE("WN19", "节点没有岗位:") + town.HisNode.NodeID + " " + town.HisNode.Name);
  799. sql = "SELECT No FROM Port_Emp WHERE NO IN ";
  800. sql += "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + " ) )";
  801. sql += " AND No IN ";
  802. if (empDept.Length == 2)
  803. sql += "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Emp!='" + empNo + "') ";
  804. else
  805. sql += "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Emp!='" + empNo + "' AND FK_Dept LIKE '" + empDept.Substring(0, empDept.Length - 4) + "%')";
  806. dt = DBAccess.RunSQLReturnTable(sql);
  807. if (dt.Rows.Count == 0)
  808. {
  809. sql = "SELECT No FROM Port_Emp WHERE No!='" + empNo + "' AND No IN ";
  810. sql += "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + " ) )";
  811. dt = DBAccess.RunSQLReturnTable(sql);
  812. if (dt.Rows.Count == 0)
  813. {
  814. string msg = town.HisNode.HisStationsStr;
  815. throw new Exception(this.ToE("WF3", "岗位(" + msg + ")下没有人员,对应节点:") + town.HisNode.Name);
  816. //"维护错误,请检查[" + town.HisNode.Name + "]维护的岗位中是否有人员?"
  817. }
  818. }
  819. return WorkerListWayOfDept(town, dt);
  820. }
  821. else
  822. {
  823. return WorkerListWayOfDept(town, dt);
  824. }
  825. }
  826. #endregion 按照岗位来执行
  827. }
  828. public WorkerLists GenerWorkerListsV2_del(WorkNode town)
  829. {
  830. DataTable dt = new DataTable();
  831. dt.Columns.Add("No", typeof(string));
  832. string sql;
  833. string fk_emp;
  834. // 如果执行了两次发送,那前一次的轨迹就需要被删除。这里是为了避免错误。
  835. DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE WorkID=" + this.HisWork.OID + " AND FK_Node =" + town.HisNode.NodeID);
  836. //首先判断是否配置了获取下一步接受人员的sql.
  837. if (this.HisNode.RecipientSQL.Length > 4)
  838. {
  839. Attrs attrs = this.HisWork.EnMap.Attrs;
  840. sql = this.HisNode.RecipientSQL;
  841. foreach (Attr attr in attrs)
  842. {
  843. if (attr.MyDataType == DataType.AppString)
  844. sql = sql.Replace("@" + attr.Key, "'" + this.HisWork.GetValStrByKey(attr.Key) + "'");
  845. else
  846. sql = sql.Replace("@" + attr.Key, this.HisWork.GetValStrByKey(attr.Key));
  847. }
  848. dt = DBAccess.RunSQLReturnTable(sql);
  849. if (dt.Rows.Count == 0)
  850. {
  851. if (SystemConfig.IsDebug)
  852. throw new Exception("@没有找到可接受的工作人员。@技术信息:执行的sql没有发现人员:" + sql);
  853. else
  854. throw new Exception("@没有找到可接受的工作人员。");
  855. }
  856. return WorkerListWayOfDept(town, dt);
  857. }
  858. if (this.HisNode.HisDeliveryWay == DeliveryWay.BySelected)
  859. {
  860. sql = "SELECT FK_Emp FROM WF_SelectAccper WHERE FK_Node=" + this.HisNode.NodeID + " AND WorkID=" + this.WorkID;
  861. dt = DBAccess.RunSQLReturnTable(sql);
  862. return WorkerListWayOfDept(town, dt);
  863. }
  864. // 判断当前节点是否采集了目标人员
  865. if (this.HisWork.EnMap.Attrs.Contains("FK_Emp"))
  866. {
  867. fk_emp = this.HisWork.GetValStringByKey("FK_Emp");
  868. DataRow dr = dt.NewRow();
  869. dr[0] = fk_emp;
  870. dt.Rows.Add(dr);
  871. return WorkerListWayOfDept(town, dt);
  872. }
  873. // 判断 节点人员里是否有设置? 如果有就不考虑岗位设置了。从节点人员设置里面查询。
  874. if (town.HisNode.HisEmps.Length > 2)
  875. {
  876. string[] emps = town.HisNode.HisEmps.Split('@');
  877. foreach (string emp in emps)
  878. {
  879. if (emp == null || emp == "")
  880. continue;
  881. DataRow dr = dt.NewRow();
  882. dr[0] = emp;
  883. dt.Rows.Add(dr);
  884. }
  885. return WorkerListWayOfDept(town, dt);
  886. }
  887. // 判断节点部门里面是否设置了部门,如果设置了,就按照它的部门处理。
  888. if (town.HisNode.HisDeliveryWay == DeliveryWay.ByDept)
  889. {
  890. if (town.HisNode.HisStations.Count == 0)
  891. {
  892. sql = "SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept IN ( SELECT FK_Dept FROM WF_NodeDept WHERE FK_Node=" + town.HisNode.NodeID + ")";
  893. dt = DBAccess.RunSQLReturnTable(sql);
  894. if (dt.Rows.Count > 0)
  895. return WorkerListWayOfDept(town, dt);
  896. }
  897. else
  898. {
  899. sql = "SELECT NO FROM Port_Emp WHERE NO IN ";
  900. sql += "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept IN ";
  901. sql += "( SELECT FK_Dept FROM WF_NodeDept WHERE FK_Node=" + town.HisNode.NodeID + ")";
  902. sql += ")";
  903. sql += "AND NO IN ";
  904. sql += "(";
  905. sql += "SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN ";
  906. sql += "( SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ")";
  907. sql += ")";
  908. dt = DBAccess.RunSQLReturnTable(sql);
  909. if (dt.Rows.Count > 0)
  910. return WorkerListWayOfDept(town, dt);
  911. }
  912. }
  913. if (this.HisNode.IsStartNode == false)
  914. {
  915. // 如果当前的节点不是开始节点, 从轨迹里面查询。
  916. sql = "SELECT DISTINCT FK_Emp FROM Port_EmpStation WHERE FK_Station IN "
  917. + "(SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") "
  918. + "AND FK_Emp IN (SELECT FK_Emp FROM WF_GenerWorkerlist WHERE WorkID=" + this.HisWork.OID + " AND FK_Node IN (" + DataType.PraseAtToInSql(town.HisNode.GroupStaNDs, true) + ") )";
  919. dt = DBAccess.RunSQLReturnTable(sql);
  920. // 如果能够找到.
  921. if (dt.Rows.Count >= 1)
  922. {
  923. if (dt.Rows.Count == 1)
  924. {
  925. /*如果人员只有一个的情况,说明他可能要 */
  926. }
  927. return WorkerListWayOfDept(town, dt);
  928. }
  929. }
  930. // 没有查询到的情况下, 先按照本部门计算。
  931. sql = "SELECT NO FROM Port_Emp WHERE NO IN "
  932. + "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") )"
  933. + " AND NO IN "
  934. + "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept = '" + WebUser.FK_Dept + "')";
  935. dt = DBAccess.RunSQLReturnTable(sql);
  936. if (dt.Rows.Count == 0)
  937. {
  938. Stations nextStations = town.HisNode.HisStations;
  939. if (nextStations.Count == 0)
  940. throw new Exception(this.ToE("WN19", "节点没有岗位:") + town.HisNode.NodeID + " " + town.HisNode.Name);
  941. // throw new Exception(this.ToEP1("WN2", "@工作流程{0}已经完成。", town.HisNode.Name));
  942. }
  943. else
  944. {
  945. return WorkerListWayOfDept(town, dt);
  946. }
  947. // 没有查询到的情况下, 按照最大匹配数计算。
  948. sql = "SELECT NO FROM Port_Emp WHERE NO IN "
  949. + "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") )"
  950. + " AND NO IN "
  951. + "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept LIKE '" + WebUser.FK_Dept + "%')";
  952. dt = DBAccess.RunSQLReturnTable(sql);
  953. if (dt.Rows.Count == 0)
  954. {
  955. Stations nextStations = town.HisNode.HisStations;
  956. if (nextStations.Count == 0)
  957. throw new Exception(this.ToE("WN19", "节点没有岗位:") + town.HisNode.NodeID + " " + town.HisNode.Name);
  958. // throw new Exception(this.ToEP1("WN2", "@工作流程{0}已经完成。", town.HisNode.Name));
  959. }
  960. else
  961. {
  962. return WorkerListWayOfDept(town, dt);
  963. }
  964. // 没有查询到的情况下, 按照最大匹配数 提高一个级别 计算。
  965. sql = "SELECT NO FROM Port_Emp WHERE NO IN "
  966. + "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + ") )"
  967. + " AND NO IN "
  968. + "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept LIKE '" + WebUser.FK_Dept.Substring(0, WebUser.FK_Dept.Length - 2) + "%')";
  969. dt = DBAccess.RunSQLReturnTable(sql);
  970. if (dt.Rows.Count == 0)
  971. {
  972. Stations nextStations = town.HisNode.HisStations;
  973. if (nextStations.Count == 0)
  974. throw new Exception(this.ToE("WN19", "节点没有岗位:") + town.HisNode.NodeID + " " + town.HisNode.Name);
  975. //throw new Exception(this.ToEP1("WF2", "@工作流程{0}已经完成。", town.HisNode.Name));
  976. else
  977. {
  978. sql = "SELECT No FROM Port_Emp WHERE NO IN ";
  979. sql += "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + " ) )";
  980. sql += " AND No IN ";
  981. if (WebUser.FK_Dept.Length == 2)
  982. sql += "(SELECT FK_Emp FROM Port_EmpDept )";
  983. else
  984. sql += "(SELECT FK_Emp FROM Port_EmpDept WHERE FK_Dept LIKE '" + WebUser.FK_Dept.Substring(0, WebUser.FK_Dept.Length - 4) + "%')";
  985. dt = DBAccess.RunSQLReturnTable(sql);
  986. if (dt.Rows.Count == 0)
  987. {
  988. sql = "SELECT No FROM Port_Emp WHERE No IN ";
  989. sql += "(SELECT FK_Emp FROM Port_EmpStation WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + town.HisNode.NodeID + " ) )";
  990. dt = DBAccess.RunSQLReturnTable(sql);
  991. if (dt.Rows.Count == 0)
  992. {
  993. string msg = town.HisNode.HisStationsStr;
  994. throw new Exception(this.ToE("WF3", "岗位(" + msg + ")下没有人员,对应节点:") + town.HisNode.Name);
  995. //"维护错误,请检查[" + town.HisNode.Name + "]维护的岗位中是否有人员?"
  996. }
  997. }
  998. return WorkerListWayOfDept(town, dt);
  999. }
  1000. }
  1001. else
  1002. {
  1003. return WorkerListWayOfDept(town, dt);
  1004. }
  1005. }
  1006. public bool IsSubFlowWorkNode
  1007. {
  1008. get
  1009. {
  1010. if (this.HisWork.FID == 0)
  1011. return false;
  1012. else
  1013. return true;
  1014. }
  1015. }
  1016. /// <summary>
  1017. /// 生成一个word
  1018. /// </summary>
  1019. public void DoPrint()
  1020. {
  1021. string tempFile = SystemConfig.PathOfTemp + "\\" + this.WorkID + ".doc";
  1022. Work wk = this.HisNode.HisWork;
  1023. wk.OID = this.WorkID;
  1024. wk.Retrieve();
  1025. Glo.GenerWord(tempFile, wk);
  1026. PubClass.OpenWordDocV2(tempFile, this.HisNode.Name + ".doc");
  1027. }
  1028. public WorkNode DoReturnWork(int backtoNodeID, string msg)
  1029. {
  1030. return DoReturnWork(backtoNodeID, msg, false);
  1031. }
  1032. private WorkNode DoReturnSubFlow(int backtoNodeID, string msg, bool isHiden)
  1033. {
  1034. Node nd = new Node(backtoNodeID);
  1035. // 删除可能存在的数据.
  1036. string sql = "DELETE FROM WF_GenerWorkerList WHERE FK_Node=" + backtoNodeID + " AND WorkID=" + this.HisWork.OID + " AND FID=" + this.HisWork.FID;
  1037. BP.DA.DBAccess.RunSQL(sql);
  1038. // 找出分合流点处理的人员.
  1039. sql = "SELECT FK_Emp FROM WF_GenerWorkerList WHERE FK_Node=" + backtoNodeID + " AND WorkID=" + this.HisWork.FID;
  1040. DataTable dt = DBAccess.RunSQLReturnTable(sql);
  1041. if (dt.Rows.Count != 1)
  1042. throw new Exception("@ system error , this values must be =1");
  1043. string fk_emp = dt.Rows[0][0].ToString();
  1044. // 获取当前工作的信息.
  1045. WorkerList wl = new WorkerList(this.HisWork.FID, this.HisNode.NodeID, fk_emp);
  1046. Emp emp = new Emp(fk_emp);
  1047. // 改变部分属性让它适应新的数据,并显示一条新的待办工作让用户看到。
  1048. wl.IsPass = false;
  1049. wl.WorkID = this.HisWork.OID;
  1050. wl.FID = this.HisWork.FID;
  1051. wl.RDT = DataType.CurrentDataTime;
  1052. wl.FK_Emp = fk_emp;
  1053. wl.FK_EmpText = emp.Name;
  1054. wl.FK_Node = backtoNodeID;
  1055. wl.FK_NodeText = nd.Name;
  1056. wl.WarningDays = nd.WarningDays;
  1057. wl.FK_Dept = emp.FK_Dept;
  1058. DateTime dtNew = DateTime.Now;
  1059. dtNew = dtNew.AddDays(nd.WarningDays);
  1060. wl.SDT = dtNew.ToString(DataType.SysDataFormat); // DataType.CurrentDataTime;
  1061. wl.FK_Flow = this.HisNode.FK_Flow;
  1062. wl.Insert();
  1063. GenerWorkFlow gwf = new GenerWorkFlow(this.HisWork.OID);
  1064. gwf.FK_Node = backtoNodeID;
  1065. gwf.NodeName = nd.Name;
  1066. gwf.DirectUpdate();
  1067. BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=3 WHERE FK_Node=" + this.HisNode.NodeID + " AND WorkID=" + this.WorkID);
  1068. /* 如果是隐性退回。*/
  1069. BP.WF.ReturnWork rw = new ReturnWork();
  1070. rw.WorkID = wl.WorkID;
  1071. rw.ReturnToNode = wl.FK_Node;
  1072. rw.ReturnNode = this.HisNode.NodeID;
  1073. rw.ReturnNodeName = this.HisNode.Name;
  1074. rw.ReturnToEmp = fk_emp;
  1075. rw.Note = msg;
  1076. rw.MyPK = rw.ReturnToNode + "_" + rw.WorkID + "_" + DateTime.Now.ToString("yyyyMMddhhmmss");
  1077. rw.Insert();
  1078. // 加入track.
  1079. this.AddToTrack(ActionType.Return, fk_emp, emp.Name, backtoNodeID, nd.Name, msg);
  1080. WorkNode wn = new WorkNode(this.HisWork.FID, backtoNodeID);
  1081. if (Glo.IsEnableSysMessage)
  1082. {
  1083. WF.Port.WFEmp wfemp = new Port.WFEmp(wn.HisWork.Rec);
  1084. BP.TA.SMS.AddMsg(wl.WorkID + "_" + wl.FK_Node + "_" + wfemp.No, wfemp.No,
  1085. wfemp.HisAlertWay, wfemp.Tel,
  1086. this.ToEP3("WN27", "工作退回:流程:{0}.工作:{1},退回人:{2},需您处理",
  1087. wn.HisNode.FlowName, wn.HisNode.Name, WebUser.Name),
  1088. wfemp.Email, null, msg);
  1089. }
  1090. return wn;
  1091. throw new Exception("分流子线程退回到分流点或者分合流点功能,没有实现。");
  1092. }
  1093. /// <summary>
  1094. /// 工作退回
  1095. /// </summary>
  1096. /// <param name="backtoNodeID">退回到节点</param>
  1097. /// <param name="msg">退回信息</param>
  1098. /// <param name="IsBackTracking">退回后是否原路返回?</param>
  1099. /// <returns></returns>
  1100. public WorkNode DoReturnWork(int backtoNodeID, string msg, bool isBackTracking)
  1101. {
  1102. //退回前事件
  1103. this.HisNode.HisNDEvents.DoEventNode(EventListOfNode.ReturnBefore, this.HisWork);
  1104. if (this.HisNode.FocusField != "")
  1105. {
  1106. // 把数据更新它。
  1107. this.HisWork.Update(this.HisNode.FocusField, "");
  1108. }
  1109. Node backToNode = new Node(backtoNodeID);
  1110. switch (this.HisNode.HisNodeWorkType)
  1111. {
  1112. case NodeWorkType.WorkHL: /*如果当前是合流点 */
  1113. /* 杀掉进程*/
  1114. WorkerLists wlsSubs = new WorkerLists();
  1115. wlsSubs.Retrieve(WorkerListAttr.FID, this.HisWork.OID);
  1116. foreach (WorkerList sub in wlsSubs)
  1117. {
  1118. GenerWorkFlow gw1f = new GenerWorkFlow();
  1119. gw1f.WorkID = sub.WorkID;
  1120. gw1f.DirectDelete();
  1121. Node subNode = new Node(sub.FK_Node);
  1122. Work wk = subNode.GetWork(sub.WorkID);
  1123. wk.Delete();
  1124. sub.Delete();
  1125. }
  1126. GenerFH fh = new GenerFH();
  1127. fh.FID = this.WorkID;
  1128. fh.Delete();
  1129. break;
  1130. default:
  1131. switch (backToNode.HisNodeWorkType)
  1132. {
  1133. case NodeWorkType.StartWorkFL:
  1134. case NodeWorkType.WorkFL:
  1135. case NodeWorkType.WorkFHL:
  1136. if (this.IsSubFlowWorkNode)
  1137. {
  1138. /* 如果是支流,并且向分流或者分合流节点上退回. */
  1139. return DoReturnSubFlow(backtoNodeID, msg, isBackTracking);
  1140. }
  1141. // return DoReturnSubFlow(backtoNodeID, msg, isHiden);
  1142. break;
  1143. default:
  1144. break;
  1145. }
  1146. break;
  1147. }
  1148. // 改变当前的工作节点.
  1149. WorkNode wnOfBackTo = new WorkNode(this.WorkID, backtoNodeID);
  1150. wnOfBackTo.HisWork.NodeState = NodeState.Back; // 更新 return work 状态.
  1151. wnOfBackTo.HisWork.DirectUpdate();
  1152. // 改变当前待办工作节点。
  1153. DBAccess.RunSQL("UPDATE WF_GenerWorkFlow SET FK_Node='" + backtoNodeID + "',NodeName='" + backToNode.Name+ "' WHERE WorkID=" + this.WorkID);
  1154. DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=0 WHERE FK_Node=" + backtoNodeID + " AND WorkID=" + this.WorkID);
  1155. // 记录退回轨迹。
  1156. ReturnWork rw = new ReturnWork();
  1157. rw.WorkID = wnOfBackTo.HisWork.OID;
  1158. rw.ReturnToNode = wnOfBackTo.HisNode.NodeID;
  1159. rw.ReturnNodeName = this.HisNode.Name;
  1160. rw.ReturnNode = this.HisNode.NodeID; // 当前退回节点.
  1161. rw.ReturnToEmp = wnOfBackTo.HisWork.Rec; //退回给。
  1162. rw.MyPK = rw.ReturnToNode + "_" + rw.WorkID + "_" + DateTime.Now.ToString("yyyyMMddhhmmss");
  1163. rw.Note = msg;
  1164. rw.IsBackTracking = isBackTracking;
  1165. rw.Insert();
  1166. // 加入track.
  1167. this.AddToTrack(ActionType.Return, wnOfBackTo.HisWork.Rec, wnOfBackTo.HisWork.RecText,
  1168. backtoNodeID, wnOfBackTo.HisNode.Name, msg);
  1169. try
  1170. {
  1171. // 记录退回日志.
  1172. ReorderLog(backToNode, this.HisNode, rw);
  1173. }
  1174. catch(Exception ex)
  1175. {
  1176. Log.DebugWriteWarning(ex.Message);
  1177. }
  1178. // 以退回到的节点向前数据用递归删除它。
  1179. if (isBackTracking == false)
  1180. {
  1181. /*如果退回不需要原路返回,就删除中间点的数据。*/
  1182. DeleteToNodesData(backToNode.HisToNodes);
  1183. }
  1184. //删除正常的垃圾数据。
  1185. DBAccess.RunSQL("DELETE WF_GenerWorkFlow WHERE WorkID NOT IN (SELECT WorkID FROM WF_GenerWorkerList )");
  1186. DBAccess.RunSQL("DELETE WF_GenerFH WHERE FID NOT IN (SELECT FID FROM WF_GenerWorkerList)");
  1187. //向他发送消息。
  1188. WorkNode backWN = new WorkNode(this.WorkID, backtoNodeID);
  1189. if (Glo.IsEnableSysMessage ==true)
  1190. {
  1191. WF.Port.WFEmp wfemp = new Port.WFEmp(wnOfBackTo.HisWork.Rec);
  1192. BP.TA.SMS.AddMsg(rw.MyPK, wfemp.No,
  1193. wfemp.HisAlertWay, wfemp.Tel,
  1194. this.ToEP3("WN27", "工作退回:流程:{0}.工作:{1},退回人:{2},需您处理",
  1195. backToNode.FlowName, backToNode.Name, WebUser.Name),
  1196. wfemp.Email, null, msg);
  1197. }
  1198. //退回后事件
  1199. this.HisNode.HisNDEvents.DoEventNode(EventListOfNode.ReturnAfter, this.HisWork);
  1200. return wnOfBackTo;
  1201. }
  1202. private string infoLog = "";
  1203. public void ReorderLog(Node fromND, Node toND, ReturnWork rw)
  1204. {
  1205. string filePath = BP.SystemConfig.PathOfDataUser + "\\ReturnLog\\" + this.HisNode.FK_Flow + "\\";
  1206. if (System.IO.Directory.Exists(filePath) == false)
  1207. System.IO.Directory.CreateDirectory(filePath);
  1208. string file = filePath + "\\" + rw.MyPK;
  1209. infoLog = "\r\n退回人:" + WebUser.No+","+WebUser.Name + " \r\n退回节点:" + fromND.Name + " \r\n退回到:" + toND.Name;
  1210. infoLog += "\r\n退回时间:" + DataType.CurrentDataTime;
  1211. infoLog += "\r\n原因:" + rw.Note;
  1212. ReorderLog(fromND, toND);
  1213. DataType.WriteFile(file+".txt", infoLog);
  1214. DataType.WriteFile(file + ".htm", infoLog.Replace("\r\n","<br>"));
  1215. this.HisWork.Delete();
  1216. }
  1217. public void ReorderLog(Node fromND, Node toND)
  1218. {
  1219. /*开始遍历到达的节点集合*/
  1220. foreach (Node nd in fromND.HisToNodes)
  1221. {
  1222. Work wk = nd.HisWork;
  1223. wk.OID = this.WorkID;
  1224. if (wk.RetrieveFromDBSources() == 0)
  1225. {
  1226. wk.FID = this.WorkID;
  1227. if (wk.Retrieve(WorkAttr.FID, this.WorkID) == 0)
  1228. continue;
  1229. }
  1230. if (nd.IsFL)
  1231. {
  1232. /* 如果是分流 */
  1233. WorkerLists wls = new WorkerLists();
  1234. QueryObject qo = new QueryObject(wls);
  1235. qo.AddWhere(WorkerListAttr.FID, this.WorkID);
  1236. qo.addAnd();
  1237. string[] ndsStrs = nd.HisToNDs.Split('@');
  1238. string inStr = "";
  1239. foreach (string s in ndsStrs)
  1240. {
  1241. if (s == "" || s == null)
  1242. continue;
  1243. inStr += "'" + s + "',";
  1244. }
  1245. inStr = inStr.Substring(0, inStr.Length - 1);
  1246. if (inStr.Contains(",") == true)
  1247. qo.AddWhere(WorkerListAttr.FK_Node, int.Parse(inStr));
  1248. else
  1249. qo.AddWhereIn(WorkerListAttr.FK_Node, "(" + inStr + ")");
  1250. qo.DoQuery();
  1251. foreach (WorkerList wl in wls)
  1252. {
  1253. Node subNd = new Node(wl.FK_Node);
  1254. Work subWK = subNd.GetWork(wl.WorkID);
  1255. infoLog += "\r\n*****************************************************************************************";
  1256. infoLog += "\r\n节点ID:" + subNd.NodeID + " 工作名称:" + subWK.EnDesc;
  1257. infoLog += "\r\n处理人:" + subWK.Rec + " , " + wk.RecOfEmp.Name;
  1258. infoLog += "\r\n接收时间:" + subWK.RDT + " 处理时间:" + subWK.CDT;
  1259. infoLog += "\r\n ------------------------------------------------- ";
  1260. foreach (Attr attr in wk.EnMap.Attrs)
  1261. {
  1262. if (attr.UIVisible == false)
  1263. continue;
  1264. infoLog += "\r\n " + attr.Desc + ":" + subWK.GetValStrByKey(attr.Key);
  1265. }
  1266. //递归调用。
  1267. ReorderLog(subNd, toND);
  1268. }
  1269. }
  1270. else
  1271. {
  1272. infoLog += "\r\n*****************************************************************************************";
  1273. infoLog += "\r\n节点ID:" + wk.NodeID + " 工作名称:" + wk.EnDesc;
  1274. infoLog += "\r\n处理人:" + wk.Rec +" , "+wk.RecOfEmp.Name;
  1275. infoLog += "\r\n接收时间:" + wk.RDT + " 处理时间:" + wk.CDT;
  1276. infoLog += "\r\n ------------------------------------------------- ";
  1277. foreach (Attr attr in wk.EnMap.Attrs)
  1278. {
  1279. if (attr.UIVisible == false)
  1280. continue;
  1281. infoLog += "\r\n" + attr.Desc + " : " + wk.GetValStrByKey(attr.Key);
  1282. }
  1283. }
  1284. /* 如果到了当前的节点 */
  1285. if (nd.NodeID == toND.NodeID)
  1286. break;
  1287. //递归调用。
  1288. ReorderLog(nd, toND);
  1289. }
  1290. }
  1291. /// <summary>
  1292. /// 递归删除两个节点之间的数据
  1293. /// </summary>
  1294. /// <param name="nds">到达的节点集合</param>
  1295. public void DeleteToNodesData(Nodes nds)
  1296. {
  1297. /*开始遍历到达的节点集合*/
  1298. foreach (Node nd in nds)
  1299. {
  1300. Work wk = nd.HisWork;
  1301. wk.OID = this.WorkID;
  1302. if (wk.Delete() == 0)
  1303. {
  1304. wk.FID = this.WorkID;
  1305. if (wk.Delete(WorkAttr.FID, this.WorkID) == 0)
  1306. continue;
  1307. }
  1308. #region 删除当前节点数据删除附件信息
  1309. // 删除明细表信息。
  1310. MapDtls dtls = new MapDtls("ND" + nd.NodeID);
  1311. foreach (MapDtl dtl in dtls)
  1312. {
  1313. BP.DA.DBAccess.RunSQL("DELETE " + dtl.PTable + " WHERE RefPK='" + this.WorkID + "'");
  1314. }
  1315. // 删除表单附件信息。
  1316. BP.DA.DBAccess.RunSQL("DELETE FROM Sys_FrmAttachmentDB WHERE RefPKVal='" + this.WorkID + "' AND FK_MapData='ND" + nd.NodeID + "'");
  1317. // 删除签名信息。
  1318. BP.DA.DBAccess.RunSQL("DELETE FROM Sys_FrmEleDB WHERE RefPKVal='" + this.WorkID + "' AND FK_MapData='ND" + nd.NodeID + "'");
  1319. #endregion 删除当前节点数据
  1320. /*说明:已经删除该节点数据。*/
  1321. DBAccess.RunSQL("DELETE WF_GenerWorkerList WHERE (WorkID=" + this.WorkID + " OR FID=" + this.WorkID + ") AND FK_Node=" + nd.NodeID);
  1322. if (nd.IsFL)
  1323. {
  1324. /* 如果是分流 */
  1325. WorkerLists wls = new WorkerLists();
  1326. QueryObject qo = new QueryObject(wls);
  1327. qo.AddWhere(WorkerListAttr.FID, this.WorkID);
  1328. qo.addAnd();
  1329. string[] ndsStrs = nd.HisToNDs.Split('@');
  1330. string inStr = "";
  1331. foreach (string s in ndsStrs)
  1332. {
  1333. if (s == "" || s == null)
  1334. continue;
  1335. inStr += "'" + s + "',";
  1336. }
  1337. inStr = inStr.Substring(0, inStr.Length - 1);
  1338. if (inStr.Contains(",") == true)
  1339. qo.AddWhere(WorkerListAttr.FK_Node, int.Parse(inStr));
  1340. else
  1341. qo.AddWhereIn(WorkerListAttr.FK_Node, "(" + inStr + ")");
  1342. qo.DoQuery();
  1343. foreach (WorkerList wl in wls)
  1344. {
  1345. Node subNd = new Node(wl.FK_Node);
  1346. Work subWK = subNd.GetWork(wl.WorkID);
  1347. subWK.Delete();
  1348. //删除分流下步骤的节点信息.
  1349. DeleteToNodesData(subNd.HisToNodes);
  1350. }
  1351. DBAccess.RunSQL("DELETE WF_GenerWorkFlow WHERE FID=" + this.WorkID);
  1352. DBAccess.RunSQL("DELETE WF_GenerWorkerList WHERE FID=" + this.WorkID);
  1353. DBAccess.RunSQL("DELETE WF_GenerFH WHERE FID=" + this.WorkID);
  1354. }
  1355. DeleteToNodesData(nd.HisToNodes);
  1356. }
  1357. }
  1358. /// <summary>
  1359. /// 执行退回
  1360. /// </summary>
  1361. /// <param name="msg">退回工作的原因</param>
  1362. /// <returns></returns>
  1363. public WorkNode DoReturnWork(string msg)
  1364. {
  1365. // 改变当前的工作节点.
  1366. WorkNode wn = this.GetPreviousWorkNode();
  1367. GenerWorkFlow gwf = new GenerWorkFlow(this.HisWork.OID);
  1368. gwf.FK_Node = wn.HisNode.NodeID;
  1369. gwf.NodeName = wn.HisNode.Name;
  1370. gwf.DirectUpdate();
  1371. // 更新 return work 状态.
  1372. wn.HisWork.NodeState = NodeState.Back;
  1373. wn.HisWork.DirectUpdate();
  1374. // 删除工作者.
  1375. WorkerLists wkls = new WorkerLists(this.HisWork.OID, this.HisNode.NodeID);
  1376. wkls.Delete();
  1377. // 写入日志.
  1378. BP.WF.ReturnWork rw = new ReturnWork();
  1379. rw.WorkID = wn.HisWork.OID;
  1380. rw.ReturnToNode = wn.HisNode.NodeID;
  1381. rw.ReturnToEmp = wn.HisWork.Rec;
  1382. rw.ReturnNode = this.HisNode.NodeID;
  1383. rw.ReturnNodeName = this.HisNode.Name;
  1384. rw.Note = msg;
  1385. rw.MyPK = rw.ReturnToNode + "_" + rw.WorkID + "_" + DateTime.Now.ToString("yyyyMMddhhmmss");
  1386. rw.Insert();
  1387. //WorkFlow wf = this.HisWorkFlow;
  1388. //wf.WritLog(msg);
  1389. // 消息通知上一步工作人员处理.
  1390. WorkerLists wls = new WorkerLists(wn.HisWork.OID, wn.HisNode.NodeID);
  1391. BP.WF.MsgsManager.AddMsgs(wls, "退回的工作", wn.HisNode.Name, "退回的工作");
  1392. // 删除退回时当前节点的工作信息。
  1393. this.HisWork.Delete();
  1394. return wn;
  1395. }
  1396. /// <summary>
  1397. /// 执行退回(在合流节点上执行退回到上一个步骤)
  1398. /// </summary>
  1399. /// <param name="workid">线程ID</param>
  1400. /// <param name="msg">退回工作的原因</param>
  1401. /// <returns></returns>
  1402. public WorkNode DoReturnWorkHL(Int64 workid, string msg)
  1403. {
  1404. // 改变当前的工作节点.
  1405. WorkNode wn = this.GetPreviousWorkNode_FHL(workid);
  1406. GenerWorkFlow gwf = new GenerWorkFlow(workid);
  1407. gwf.FK_Node = wn.HisNode.NodeID;
  1408. gwf.NodeName = wn.HisNode.Name;
  1409. gwf.DirectUpdate();
  1410. // 更新 return work 状态.
  1411. wn.HisWork.NodeState = NodeState.Back;
  1412. wn.HisWork.DirectUpdate();
  1413. // 删除工作者.
  1414. WorkerLists wkls = new WorkerLists(workid, this.HisNode.NodeID);
  1415. wkls.Delete();
  1416. // 写入日志.
  1417. BP.WF.ReturnWork rw = new ReturnWork();
  1418. rw.WorkID = workid;
  1419. rw.ReturnToNode = wn.HisNode.NodeID;
  1420. rw.ReturnToEmp = wn.HisWork.Rec;
  1421. rw.ReturnNode = this.HisNode.NodeID;
  1422. rw.Note = msg;
  1423. rw.MyPK = rw.ReturnToNode + "_" + rw.WorkID + "_" + DateTime.Now.ToString("yyyyMMddhhmmss");
  1424. rw.Insert();
  1425. BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=0 WHERE FK_Node='" + wn.HisNode.NodeID + "' and workid=" + workid);
  1426. //WorkFlow wf = this.HisWorkFlow;
  1427. //wf.WritLog(msg);
  1428. // 消息通知上一步工作人员处理.
  1429. WorkerLists wls = new WorkerLists(workid, wn.HisNode.NodeID);
  1430. BP.WF.MsgsManager.AddMsgs(wls, "退回的工作", wn.HisNode.Name, "退回的工作");
  1431. // 删除退回时当前节点的工作信息。
  1432. // this.HisWork.Delete();
  1433. return wn;
  1434. }
  1435. /// <summary>
  1436. /// 执行工作完成
  1437. /// </summary>
  1438. public string DoSetThisWorkOver()
  1439. {
  1440. this.HisWork.AfterWorkNodeComplete();
  1441. // 更新状态。
  1442. this.HisWork.NodeState = NodeState.Complete;
  1443. this.HisWork.SetValByKey("CDT", DataType.CurrentDataTime);
  1444. this.HisWork.Rec = Web.WebUser.No;
  1445. //判断是不是MD5流程?
  1446. if (this.HisFlow.IsMD5)
  1447. this.HisWork.SetValByKey("MD5", Glo.GenerMD5(this.HisWork));
  1448. this.HisWork.DirectUpdate();
  1449. // 清除其他的工作者.
  1450. string sql = "";
  1451. sql = "DELETE FROM WF_GenerWorkerlist WHERE FK_Node=" + this.HisNode.NodeID + " AND WorkID=" + this.HisWork.OID + " AND FK_Emp <> '" + this.HisWork.Rec.ToString() + "'";
  1452. DBAccess.RunSQL(sql);
  1453. return "";
  1454. }
  1455. /// <summary>
  1456. /// 按照 "职务" 得到的能够执行这项工作的集合
  1457. /// </summary>
  1458. /// <returns></returns>
  1459. private DataTable GetCanDoWorkEmpsByDuty(int nodeId)
  1460. {
  1461. string sql = "SELECT b.FK_Emp FROM WF_NodeDuty a, Port_EmpDuty b WHERE (a.FK_Duty=b.FK_Duty ) AND a.FK_Node=" + nodeId;
  1462. return DBAccess.RunSQLReturnTable(sql);
  1463. }
  1464. /// <summary>
  1465. /// 按照 "部门" 得到的能够执行这项工作的集合
  1466. /// </summary>
  1467. /// <returns></returns>
  1468. private DataTable GetCanDoWorkEmpsByDept(int nodeId)
  1469. {
  1470. string sql = "SELECT b.FK_Emp FROM WF_NodeDept a, Port_EmpDept b WHERE (a.FK_Dept=b.FK_Dept) AND a.FK_Node=" + nodeId;
  1471. return DBAccess.RunSQLReturnTable(sql);
  1472. }
  1473. #region 根据工作岗位生成工作者
  1474. private WorkerLists WorkerListWayOfDept(WorkNode town, DataTable dt)
  1475. {
  1476. return WorkerListWayOfDept(town,dt,0);
  1477. }
  1478. private WorkerLists WorkerListWayOfDept(WorkNode town, DataTable dt, Int64 fid)
  1479. {
  1480. if (dt.Rows.Count == 0)
  1481. {
  1482. //string msg = "接受人员列表为空: 流程设计或者组织结构维护错误,节点的访问规则是("+town.HisNode.RecipientSQL+")";
  1483. throw new Exception(this.ToE("WN4", "接受人员列表为空.")); // 接受人员列表为空
  1484. }
  1485. Int64 workID = fid;
  1486. if (workID == 0)
  1487. workID = this.HisWork.OID;
  1488. int toNodeId = town.HisNode.NodeID;
  1489. this.HisWorkerLists = new WorkerLists();
  1490. this.HisWorkerLists.Clear();
  1491. #warning 限期时间 town.HisNode.DeductDays-1
  1492. // 2008-01-22 之前的东西。
  1493. //int i = town.HisNode.DeductDays;
  1494. //dtOfShould = DataType.AddDays(dtOfShould, i);
  1495. //if (town.HisNode.WarningDays > 0)
  1496. // dtOfWarning = DataType.AddDays(dtOfWarning, i - town.HisNode.WarningDays);
  1497. // edit at 2008-01-22 , 处理预警日期的问题。
  1498. DateTime dtOfShould;
  1499. int day = 0;
  1500. int hh = 0;
  1501. if (town.HisNode.DeductDays < 1)
  1502. day = 0;
  1503. else
  1504. day =int.Parse( town.HisNode.DeductDays.ToString());
  1505. dtOfShould = DataType.AddDays(DateTime.Now, day);
  1506. DateTime dtOfWarning = DateTime.Now;
  1507. if (town.HisNode.WarningDays > 0)
  1508. dtOfWarning = DataType.AddDays(dtOfShould, - int.Parse(town.HisNode.WarningDays.ToString())); // dtOfShould.AddDays(-town.HisNode.WarningDays);
  1509. switch (this.HisNode.HisNodeWorkType)
  1510. {
  1511. case NodeWorkType.StartWorkFL:
  1512. case NodeWorkType.WorkFHL:
  1513. case NodeWorkType.WorkFL:
  1514. case NodeWorkType.WorkHL:
  1515. break;
  1516. default:
  1517. this.HisGenerWorkFlow.Update(GenerWorkFlowAttr.FK_Node,
  1518. town.HisNode.NodeID,
  1519. "SDT", dtOfShould.ToString("yyyy-MM-dd"));
  1520. break;
  1521. }
  1522. if (dt.Rows.Count == 1)
  1523. {
  1524. /* 如果只有一个人员 */
  1525. WorkerList wl = new WorkerList();
  1526. wl.WorkID = workID;
  1527. wl.FK_Node = toNodeId;
  1528. wl.FK_NodeText = town.HisNode.Name;
  1529. wl.FK_Emp = dt.Rows[0][0].ToString();
  1530. Emp emp = new Emp(wl.FK_Emp);
  1531. wl.FK_EmpText = emp.Name;
  1532. wl.FK_Dept = emp.FK_Dept;
  1533. wl.WarningDays = town.HisNode.WarningDays;
  1534. wl.SDT = dtOfShould.ToString(DataType.SysDataFormat);
  1535. wl.DTOfWarning = dtOfWarning.ToString(DataType.SysDataFormat);
  1536. wl.RDT = DateTime.Now.ToString(DataType.SysDataTimeFormat);
  1537. wl.FK_Flow = town.HisNode.FK_Flow;
  1538. wl.FID = town.HisWork.FID;
  1539. wl.Sender = WebUser.No;
  1540. //if (wl.FID == 0)
  1541. // wl.FID = this.WorkID;
  1542. wl.DirectInsert();
  1543. this.HisWorkerLists.AddEntity(wl);
  1544. RememberMe rm = new RememberMe(); // this.GetHisRememberMe(town.HisNode);
  1545. rm.Objs = "@" + wl.FK_Emp + "@";
  1546. rm.ObjsExt = wl.FK_Emp + "<" + wl.FK_EmpText + ">";
  1547. rm.Emps = "@" + wl.FK_Emp + "@";
  1548. rm.EmpsExt = wl.FK_Emp + "<" + wl.FK_EmpText + ">";
  1549. this._RememberMe = rm;
  1550. }
  1551. else
  1552. {
  1553. /* 如果有多个人员 */
  1554. RememberMe rm = this.GetHisRememberMe(town.HisNode);
  1555. // 如果按照选择的人员处理,就设置它的记忆为空。2011-11-06处理电厂需求 .
  1556. if (this.town.HisNode.HisDeliveryWay == DeliveryWay.BySelected
  1557. || town.HisNode.IsRememberMe == false)
  1558. {
  1559. if (rm != null)
  1560. rm.Objs = "";
  1561. }
  1562. if (this.HisNode.IsFL)
  1563. {
  1564. if (rm != null)
  1565. rm.Objs = "";
  1566. }
  1567. // 记忆中是否存在当前的人员。
  1568. bool isHaveIt = false;
  1569. string emps = "@";
  1570. foreach (DataRow dr in dt.Rows)
  1571. {
  1572. string fk_emp = dr[0].ToString();
  1573. if (rm.Objs.IndexOf("@" + fk_emp) != -1)
  1574. isHaveIt = true;
  1575. emps += fk_emp + "@";
  1576. }
  1577. if (isHaveIt == false)
  1578. {
  1579. /* 记忆里面没有当前生成的操作人员 */
  1580. /* 已经保证了没有重复的人员。*/
  1581. string myemps = "";
  1582. Emp emp = null;
  1583. foreach (DataRow dr in dt.Rows)
  1584. {
  1585. if (myemps.IndexOf(dr[0].ToString()) != -1)
  1586. continue;
  1587. myemps += "@" + dr[0].ToString();
  1588. WorkerList wl = new WorkerList();
  1589. wl.IsEnable = true;
  1590. wl.WorkID = workID;
  1591. wl.FK_Node = toNodeId;
  1592. wl.FK_NodeText = town.HisNode.Name;
  1593. wl.FK_Emp = dr[0].ToString();
  1594. try
  1595. {
  1596. emp = new Emp(wl.FK_Emp);
  1597. }
  1598. catch
  1599. {
  1600. continue;
  1601. }
  1602. wl.FK_EmpText = emp.Name;
  1603. wl.FK_Dept = emp.FK_Dept;
  1604. wl.WarningDays = town.HisNode.WarningDays;
  1605. wl.SDT = dtOfShould.ToString(DataType.SysDataFormat);
  1606. wl.DTOfWarning = dtOfWarning.ToString(DataType.SysDataFormat);
  1607. wl.RDT = DateTime.Now.ToString(DataType.SysDataTimeFormat);
  1608. wl.FK_Flow = town.HisNode.FK_Flow;
  1609. wl.FID = town.HisWork.FID;
  1610. wl.Sender = WebUser.No;
  1611. //if (wl.FID == 0)
  1612. // wl.FID = this.WorkID;
  1613. try
  1614. {
  1615. wl.DirectInsert();
  1616. this.HisWorkerLists.AddEntity(wl);
  1617. }
  1618. catch (Exception ex)
  1619. {
  1620. Log.DefaultLogWriteLineError("不应该出现的异常信息:" + ex.Message);
  1621. }
  1622. }
  1623. }
  1624. else
  1625. {
  1626. string[] strs = rm.Objs.Split('@');
  1627. string myemps = "";
  1628. foreach (string s in strs)
  1629. {
  1630. if (s.Length < 1)
  1631. continue;
  1632. if (myemps.IndexOf(s) != -1)
  1633. continue;
  1634. myemps += "@" + s;
  1635. WorkerList wl = new WorkerList();
  1636. wl.IsEnable = true;
  1637. wl.WorkID = workID;
  1638. wl.FK_Node = toNodeId;
  1639. wl.FK_NodeText = town.HisNode.Name;
  1640. wl.FK_Emp = s;
  1641. Emp emp = null;
  1642. try
  1643. {
  1644. emp = new Emp(s);
  1645. }
  1646. catch
  1647. {
  1648. continue;
  1649. }
  1650. wl.FK_EmpText = emp.Name;
  1651. wl.FK_Dept = emp.FK_Dept;
  1652. wl.WarningDays = town.HisNode.WarningDays;
  1653. wl.SDT = dtOfShould.ToString(DataType.SysDataFormat);
  1654. wl.DTOfWarning = dtOfWarning.ToString(DataType.SysDataFormat);
  1655. wl.RDT = DateTime.Now.ToString(DataType.SysDataTimeFormat);
  1656. wl.FK_Flow = town.HisNode.FK_Flow;
  1657. wl.FID = town.HisWork.FID;
  1658. wl.Sender = WebUser.No;
  1659. try
  1660. {
  1661. if (town.HisNode.IsFLHL == false)
  1662. {
  1663. wl.DirectInsert();
  1664. this.HisWorkerLists.AddEntity(wl);
  1665. }
  1666. }
  1667. catch
  1668. {
  1669. continue;
  1670. }
  1671. }
  1672. }
  1673. string objsmy = "@";
  1674. foreach (WorkerList wl in this.HisWorkerLists)
  1675. {
  1676. objsmy += wl.FK_Emp + "@";
  1677. }
  1678. if (rm.Emps != emps || rm.Objs != objsmy)
  1679. {
  1680. /* 工作人员列表发生了变化 */
  1681. rm.Emps = emps;
  1682. rm.Objs = objsmy;
  1683. string objExts = "";
  1684. foreach (WorkerList wl in this.HisWorkerLists)
  1685. {
  1686. if (Glo.IsShowUserNoOnly)
  1687. objExts += wl.FK_Emp + "、";
  1688. else
  1689. objExts += wl.FK_Emp + "<" + wl.FK_EmpText + ">、";
  1690. }
  1691. rm.ObjsExt = objExts;
  1692. string empExts = "";
  1693. foreach (DataRow dr in dt.Rows)
  1694. {
  1695. Emp emp = new Emp(dr[0].ToString());
  1696. if (rm.Objs.IndexOf(emp.No) != -1)
  1697. {
  1698. if (Glo.IsShowUserNoOnly)
  1699. empExts += emp.No + "、";
  1700. else
  1701. empExts += emp.No + "<" + emp.Name + ">、";
  1702. }
  1703. else
  1704. {
  1705. if (Glo.IsShowUserNoOnly)
  1706. empExts += "<strike><font color=red>" + emp.No + "</font></strike>、";
  1707. else
  1708. empExts += "<strike><font color=red>" + emp.No + "<" + emp.Name + "></font></strike>、";
  1709. }
  1710. }
  1711. rm.EmpsExt = empExts;
  1712. rm.Save();
  1713. }
  1714. }
  1715. if (this.HisWorkerLists.Count == 0)
  1716. throw new Exception("@根据部门产生工作人员出现错误,流程[" + this.HisWorkFlow.HisFlow.Name + "],中节点[" + town.HisNode.Name + "]定义错误,没有找到接受此工作的工作人员.");
  1717. // 求出日志类型。
  1718. ActionType at = ActionType.Forward;
  1719. switch (town.HisNode.HisNodeWorkType)
  1720. {
  1721. case NodeWorkType.StartWork:
  1722. case NodeWorkType.StartWorkFL:
  1723. at = ActionType.Start;
  1724. break;
  1725. case NodeWorkType.Work:
  1726. if (this.HisNode.HisNodeWorkType == NodeWorkType.WorkFL
  1727. || this.HisNode.HisNodeWorkType == NodeWorkType.WorkFHL)
  1728. at = ActionType.ForwardFL;
  1729. else
  1730. at = ActionType.Forward;
  1731. break;
  1732. case NodeWorkType.WorkHL:
  1733. at = ActionType.ForwardHL;
  1734. break;
  1735. case NodeWorkType.SubThreadWork:
  1736. at = ActionType.SubFlowForward;
  1737. break;
  1738. default:
  1739. break;
  1740. }
  1741. if (this.HisWorkerLists.Count == 1)
  1742. {
  1743. WorkerList wl = this.HisWorkerLists[0] as WorkerList;
  1744. this.AddToTrack(at, wl.FK_Emp, wl.FK_EmpText, wl.FK_Node, wl.FK_NodeText, null);
  1745. }
  1746. else
  1747. {
  1748. string info = "共(" + this.HisWorkerLists.Count+ ")人接收\t\n";
  1749. foreach (WorkerList wl in this.HisWorkerLists)
  1750. {
  1751. info += wl.FK_Emp + "," + wl.FK_EmpText + "\t\n";
  1752. }
  1753. this.AddToTrack(at, WebUser.No, WebUser.Name, town.HisNode.NodeID, town.HisNode.Name, info);
  1754. }
  1755. return this.HisWorkerLists;
  1756. }
  1757. #endregion
  1758. #region 属性
  1759. #region 工作岗位
  1760. private Station _HisStationOfUse = null;
  1761. /// <summary>
  1762. /// 取出当前工作用的岗位.
  1763. /// 这对与多个工作岗位的节点来说的.
  1764. ///
  1765. /// </summary>
  1766. /// <returns></returns>
  1767. public Station HisStationOfUse
  1768. {
  1769. get
  1770. {
  1771. if (_HisStationOfUse == null)
  1772. {
  1773. Stations sts = this.HisNode.HisStations;
  1774. if (sts.Count == 0)
  1775. throw new Exception(this.ToE("WN18", this.HisNode.Name));
  1776. _HisStationOfUse = (Station)this.HisNode.HisStations[0];
  1777. return _HisStationOfUse;
  1778. if (this.HisStations.Count == 1)
  1779. {
  1780. /* 如果这个工作节点只允许一个工作岗位访问,那末这个工作节点就是这个工作节点用的节点。*/
  1781. _HisStationOfUse = (Station)HisStations[0];
  1782. return _HisStationOfUse;
  1783. }
  1784. // 如果当前节点允许多个工作岗位访问。 找出工作人员的工作岗位集合
  1785. Stations mySts = this.HisWork.RecOfEmp.HisStations;
  1786. if (mySts.Count == 1)
  1787. {
  1788. _HisStationOfUse = (Station)mySts[0];
  1789. return _HisStationOfUse;
  1790. }
  1791. // 取出,节点的工作岗位与工作人员工作岗位的交集合
  1792. Stations gainSts = (Stations)mySts.GainIntersection(this.HisStations);
  1793. if (gainSts.Count == 0)
  1794. {
  1795. if (this.HisStations.Count == 0)
  1796. throw new Exception("@您没有为节点[" + this.HisNode.Name + "],设置工作岗位.");
  1797. _HisStationOfUse = (Station)mySts[0];
  1798. return _HisStationOfUse;
  1799. ///// //throw new Exception("@获取使用工作岗位出现错误,工作人员["+this.HisWork.RecOfEmp.Name+"]的工作没有处理完成,您改变了他的工作岗位.导致工作不能正常的流转下去.");
  1800. }
  1801. /* 判断他的主要工作岗位,主要工作岗位优先. */
  1802. string mainStatNo = this.HisWork.HisRec.No;
  1803. foreach (Station myst in gainSts)
  1804. {
  1805. if (myst.No == mainStatNo)
  1806. {
  1807. _HisStationOfUse = myst;
  1808. return _HisStationOfUse;
  1809. }
  1810. }
  1811. /*扫描交集,外勤优先. */
  1812. foreach (Station myst in gainSts)
  1813. {
  1814. }
  1815. /* 没有扫描到就, 返回第一个station.*/
  1816. if (_HisStationOfUse == null)
  1817. _HisStationOfUse = (Station)gainSts[0];
  1818. }
  1819. return _HisStationOfUse;
  1820. }
  1821. }
  1822. /// <summary>
  1823. /// 工作岗位
  1824. /// </summary>
  1825. public Stations HisStations
  1826. {
  1827. get
  1828. {
  1829. return this.HisNode.HisStations;
  1830. }
  1831. }
  1832. /// <summary>
  1833. /// 返回第一个工作节点
  1834. /// </summary>
  1835. public Station HisStationOfFirst
  1836. {
  1837. get
  1838. {
  1839. return (Station)this.HisNode.HisStations[0];
  1840. }
  1841. }
  1842. #endregion
  1843. #region 判断一人多部门的情况
  1844. /// <summary>
  1845. /// HisDeptOfUse
  1846. /// </summary>
  1847. private Dept _HisDeptOfUse = null;
  1848. /// <summary>
  1849. /// HisDeptOfUse
  1850. /// </summary>
  1851. public Dept HisDeptOfUse
  1852. {
  1853. get
  1854. {
  1855. if (_HisDeptOfUse == null)
  1856. {
  1857. //找到全部的部门。
  1858. Depts depts;
  1859. if (this.HisWork.Rec == WebUser.No)
  1860. depts = WebUser.HisDepts;
  1861. else
  1862. depts = this.HisWork.RecOfEmp.HisDepts;
  1863. if (depts.Count == 0)
  1864. {
  1865. throw new Exception("您没有给[" + this.HisWork.Rec + "]设置部门。");
  1866. }
  1867. if (depts.Count == 1) /* 如果全部的部门只有一个,就返回它。*/
  1868. {
  1869. _HisDeptOfUse = (Dept)depts[0];
  1870. return _HisDeptOfUse;
  1871. }
  1872. if (_HisDeptOfUse == null)
  1873. {
  1874. /* 如果还没找到,就返回第一个部门。 */
  1875. _HisDeptOfUse = depts[0] as Dept;
  1876. }
  1877. }
  1878. return _HisDeptOfUse;
  1879. }
  1880. }
  1881. #endregion
  1882. #endregion
  1883. #region 条件
  1884. private Conds _HisNodeCompleteConditions = null;
  1885. /// <summary>
  1886. /// 节点完成任务的条件
  1887. /// 条件与条件之间是or 的关系, 就是说,如果任何一个条件满足,这个工作人员在这个节点上的任务就完成了.
  1888. /// </summary>
  1889. public Conds HisNodeCompleteConditions
  1890. {
  1891. get
  1892. {
  1893. if (this._HisNodeCompleteConditions == null)
  1894. {
  1895. _HisNodeCompleteConditions = new Conds(CondType.Node, this.HisNode.NodeID, this.WorkID);
  1896. return _HisNodeCompleteConditions;
  1897. }
  1898. return _HisNodeCompleteConditions;
  1899. }
  1900. }
  1901. private Conds _HisFlowCompleteConditions = null;
  1902. /// <summary>
  1903. /// 他的完成任务的条件,此节点是完成任务的条件集合
  1904. /// 条件与条件之间是or 的关系, 就是说,如果任何一个条件满足,这个任务就完成了.
  1905. /// </summary>
  1906. public Conds HisFlowCompleteConditions
  1907. {
  1908. get
  1909. {
  1910. if (this._HisFlowCompleteConditions == null)
  1911. {
  1912. _HisFlowCompleteConditions = new Conds(CondType.Flow, this.HisNode.NodeID, this.WorkID);
  1913. }
  1914. return _HisFlowCompleteConditions;
  1915. }
  1916. }
  1917. #endregion
  1918. #region 关于质量考核
  1919. ///// <summary>
  1920. ///// 得到以前的已经完成的工作节点.
  1921. ///// </summary>
  1922. ///// <returns></returns>
  1923. //public WorkNodes GetHadCompleteWorkNodes()
  1924. //{
  1925. // WorkNodes mywns = new WorkNodes();
  1926. // WorkNodes wns = new WorkNodes(this.HisNode.HisFlow, this.HisWork.OID);
  1927. // foreach (WorkNode wn in wns)
  1928. // {
  1929. // if (wn.IsComplete)
  1930. // mywns.Add(wn);
  1931. // }
  1932. // return mywns;
  1933. //}
  1934. #endregion
  1935. #region 流程公共方法
  1936. /// <summary>
  1937. /// 检查全局的工作流程是不是完成任务
  1938. /// 如果完成了,就返回不做任何处理。
  1939. /// 如果符合流程完成的条件,就返回相应的信息。
  1940. /// 如果不符合流程的完成条件,return null;
  1941. /// </summary>
  1942. public string CheckGlobalCompleteCondition()
  1943. {
  1944. if (this.HisWorkFlow.IsComplete) // 如果全局的工作已经完成.
  1945. return this.ToE("FlowOver", "当前的任务已经完成"); //当前的任务已经完成
  1946. #region 检查全局的完成条件,由于不经常用到,所以就暂时删除.
  1947. /*
  1948. GlobalCompleteConditions gcc = new GlobalCompleteConditions(this.HisNode.FK_Flow,this.HisWork.OID);
  1949. if (gcc.IsOneOfConditionPassed)
  1950. {
  1951. this.HisWorkFlow.DoFlowOver();
  1952. return "@工作流程["+this.HisNode.HisFlow.Name+"]执行过程中,在节点["+this.HisNode.Name+"]符合流程完成条件,"+gcc.GetOneOfConditionPassed.ConditionDesc+",工作正常结束!";
  1953. }
  1954. */
  1955. #endregion
  1956. return null;
  1957. }
  1958. private Flow _HisFlow = null;
  1959. public Flow HisFlow
  1960. {
  1961. get
  1962. {
  1963. if (_HisFlow == null)
  1964. _HisFlow = this.HisNode.HisFlow;
  1965. return _HisFlow;
  1966. }
  1967. }
  1968. public Node JumpToNode = null;
  1969. public string JumpToEmp = null;
  1970. /// <summary>
  1971. /// 保存后处理
  1972. /// </summary>
  1973. /// <returns></returns>
  1974. public string AfterNodeSave()
  1975. {
  1976. return AfterNodeSave(null, null);
  1977. }
  1978. /// <summary>
  1979. /// 解决流程回滚的问题
  1980. /// </summary>
  1981. /// <param name="TransferPC"></param>
  1982. /// <param name="ByTransfered"></param>
  1983. /// <returns></returns>
  1984. public string AfterNodeSave(Node jumpToNode, string jumpToEmp)
  1985. {
  1986. this.JumpToNode = jumpToNode;
  1987. this.JumpToEmp = jumpToEmp;
  1988. // 检查是否是当前节点,如果不是就可能存在sdk用户刷新的可能,导致数据重复提交。
  1989. //if (this.HisGenerWorkFlow.FK_Node != this.HisNode.NodeID)
  1990. // throw new Exception("@您不能重复提交,或者刷新界面。");
  1991. DBAccess.DoTransactionBegin();
  1992. DateTime dt = DateTime.Now;
  1993. this.HisWork.Rec = Web.WebUser.No;
  1994. this.WorkID = this.HisWork.OID;
  1995. string msg = this.HisNode.HisNDEvents.DoEventNode(EventListOfNode.SendWhen, this.HisWork);
  1996. // 调用发送前的接口。
  1997. try
  1998. {
  1999. #region 处理调用日志.
  2000. if (this.HisNode.IsStartNode)
  2001. {
  2002. /*如果是开始流程判断是不是被吊起的流程,如果是就要向父流程写日志。*/
  2003. if (SystemConfig.IsBSsystem)
  2004. {
  2005. string fk_nodeFrom = System.Web.HttpContext.Current.Request.QueryString["FromNode"];
  2006. if (string.IsNullOrEmpty(fk_nodeFrom) == false)
  2007. {
  2008. Node ndFrom = new Node(int.Parse(fk_nodeFrom));
  2009. string fromWorkID = System.Web.HttpContext.Current.Request.QueryString["FromWorkID"];
  2010. string pTitle = DBAccess.RunSQLReturnString("SELECT Title FROM ND" + int.Parse(ndFrom.FK_Flow) + "01 WHERE OID=" + fromWorkID);
  2011. //记录当前流程被调起。
  2012. this.AddToTrack(ActionType.StartSubFlow, WebUser.No,
  2013. WebUser.Name, ndFrom.NodeID, ndFrom.FlowName + "\t\n" + ndFrom.FlowName, "被父流程(" + ndFrom.FlowName + ":" + pTitle + ")唤起.");
  2014. //记录父流程被调起。
  2015. Track tkParent = new Track();
  2016. tkParent.WorkID = Int64.Parse(fromWorkID);
  2017. tkParent.RDT = DataType.CurrentDataTimess;
  2018. tkParent.HisActionType = ActionType.CallSubFlow;
  2019. tkParent.EmpFrom = WebUser.No;
  2020. tkParent.EmpFromT = WebUser.Name;
  2021. tkParent.NDTo = this.HisNode.NodeID;
  2022. tkParent.NDToT = this.HisNode.FlowName + " \t\n " + this.HisNode.Name;
  2023. tkParent.FK_Flow = ndFrom.FK_Flow;
  2024. tkParent.NDFrom = ndFrom.NodeID;
  2025. tkParent.NDFromT = ndFrom.Name;
  2026. tkParent.EmpTo = WebUser.No;
  2027. tkParent.EmpToT = WebUser.Name;
  2028. tkParent.Msg = "<a href='Track.aspx?FK_Flow=" + this.HisNode.FK_Flow + "&WorkID=" + this.HisWork.OID + "' target=_b >调起子流程(" + this.HisNode.FlowName + ")</a>";
  2029. tkParent.MyPK = tkParent.WorkID + "_" + tkParent.FID + "_" + (int)tkParent.HisActionType + "_" + tkParent.NDFrom + "_" + DateTime.Now.ToString("yyMMddhhmmss");
  2030. tkParent.Insert();
  2031. }
  2032. }
  2033. }
  2034. #endregion 处理调用日志.
  2035. msg += AfterNodeSave_Do();
  2036. DBAccess.DoTransactionCommit(); //提交事务.
  2037. try
  2038. {
  2039. // 调起发送成功后的事务。
  2040. msg += this.HisNode.HisNDEvents.DoEventNode(EventListOfNode.SendSuccess, this.HisWork);
  2041. }
  2042. catch (Exception ex)
  2043. {
  2044. msg += ex.Message;
  2045. }
  2046. string msgOfSend = this.HisNode.TurnToDealDoc;
  2047. if (msgOfSend.Length > 3)
  2048. {
  2049. if (msgOfSend.Contains("@"))
  2050. {
  2051. Attrs attrs = this.HisWork.EnMap.Attrs;
  2052. foreach (Attr attr in attrs)
  2053. {
  2054. msgOfSend = msgOfSend.Replace("@" + attr.Key, this.HisWork.GetValStrByKey(attr.Key));
  2055. }
  2056. }
  2057. return msgOfSend;
  2058. }
  2059. // 如果需要跳转.
  2060. if (town != null)
  2061. {
  2062. if (town.HisNode.HisDeliveryWay == DeliveryWay.ByPreviousOperSkip)
  2063. return town.AfterNodeSave();
  2064. }
  2065. return msg;
  2066. }
  2067. catch (Exception ex)
  2068. {
  2069. this.WhenTranscactionRollbackError(ex);
  2070. DBAccess.DoTransactionRollback();
  2071. throw ex;
  2072. }
  2073. }
  2074. private void WhenTranscactionRollbackError(Exception ex)
  2075. {
  2076. /*在提交错误的情况下,回滚数据。*/
  2077. try
  2078. {
  2079. // 把工作的状态设置回来。
  2080. this.HisWork.Update(WorkAttr.NodeState, (int)NodeState.Init);
  2081. // 把流程的状态设置回来。
  2082. GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID);
  2083. if (gwf.WFState != 0 || gwf.FK_Node != this.HisNode.NodeID)
  2084. {
  2085. /* 如果这两项其中有一项有变化。*/
  2086. gwf.FK_Node = this.HisNode.NodeID;
  2087. gwf.NodeName = this.HisNode.Name;
  2088. gwf.WFState = 0;
  2089. gwf.Update();
  2090. }
  2091. //执行数据.
  2092. DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0 WHERE FK_Emp='"+WebUser.No+"' AND WorkID="+this.WorkID+" AND FK_Node="+this.HisNode.NodeID);
  2093. Node startND = this.HisNode.HisFlow.HisStartNode;
  2094. StartWork wk = startND.HisWork as StartWork;
  2095. switch (startND.HisNodeWorkType)
  2096. {
  2097. case NodeWorkType.StartWorkFL:
  2098. case NodeWorkType.WorkFL:
  2099. break;
  2100. default:
  2101. /*
  2102. 要考虑删除WFState 节点字段的问题。
  2103. */
  2104. //// 把开始节点的装态设置回来。
  2105. //DBAccess.RunSQL("UPDATE " + wk.EnMap.PhysicsTable + " SET WFState=0 WHERE OID="+this.WorkID+" OR OID="+this);
  2106. //wk.OID = this.WorkID;
  2107. //int i =wk.RetrieveFromDBSources();
  2108. //if (wk.WFState == WFState.Complete)
  2109. //{
  2110. // wk.Update("WFState", (int)WFState.Runing);
  2111. //}
  2112. break;
  2113. }
  2114. Nodes nds = this.HisNode.HisToNodes;
  2115. foreach (Node nd in nds)
  2116. {
  2117. Work mwk = nd.HisWork;
  2118. mwk.OID = this.WorkID;
  2119. mwk.DirectDelete();
  2120. }
  2121. this.HisNode.HisNDEvents.DoEventNode(EventListOfNode.SendError, this.HisWork);
  2122. }
  2123. catch (Exception ex1)
  2124. {
  2125. if (this.rptGe != null)
  2126. this.rptGe.CheckPhysicsTable();
  2127. throw new Exception(ex.Message + "@回滚发送失败数据出现错误:" + ex1.Message + "@有可能系统已经自动修复错误,请您在重新执行一次。");
  2128. }
  2129. }
  2130. #region 用户到的变量
  2131. public WorkerLists HisWorkerLists = null;
  2132. public GenerWorkFlow _HisGenerWorkFlow;
  2133. public GenerWorkFlow HisGenerWorkFlow
  2134. {
  2135. get
  2136. {
  2137. if (_HisGenerWorkFlow == null)
  2138. _HisGenerWorkFlow = new GenerWorkFlow(this.WorkID);
  2139. return _HisGenerWorkFlow;
  2140. }
  2141. set
  2142. {
  2143. _HisGenerWorkFlow = value;
  2144. }
  2145. }
  2146. private Int64 _WorkID = 0;
  2147. public Int64 WorkID
  2148. {
  2149. get
  2150. {
  2151. return _WorkID;
  2152. }
  2153. set
  2154. {
  2155. _WorkID = value;
  2156. }
  2157. }
  2158. #endregion
  2159. /// <summary>
  2160. /// 启动分流
  2161. /// </summary>
  2162. /// <param name="toNode"></param>
  2163. /// <returns></returns>
  2164. public string FeiLiuStartUp(Node toNode)
  2165. {
  2166. // 发起.
  2167. Work wk = toNode.HisWork;
  2168. WorkNode town = new WorkNode(wk, toNode);
  2169. // 产生下一步骤要执行的人员.
  2170. WorkerLists gwls = this.GenerWorkerLists(town);
  2171. this.AddIntoWacthDog(gwls); //@加入消息集合里。
  2172. //清除以前的数据,比如两次发送。
  2173. wk.Delete(WorkAttr.FID, this.HisWork.OID);
  2174. // 判断分流的次数.是不是历史记录里面有分流。
  2175. bool IsHaveFH = false;
  2176. if (DBAccess.RunSQLReturnValInt("SELECT COUNT(*) FROM WF_GenerWorkerlist WHERE FID=" + this.HisWork.OID) != 0)
  2177. IsHaveFH = true;
  2178. string msg = "";
  2179. FrmAttachmentDBs athDBs = new FrmAttachmentDBs("ND" + this.HisNode.NodeID,
  2180. this.WorkID.ToString());
  2181. FrmEleDBs eleDBs = new FrmEleDBs("ND" + this.HisNode.NodeID,
  2182. this.WorkID.ToString());
  2183. MapDtls dtlsFrom = new MapDtls("ND" + this.HisNode.NodeID);
  2184. if (dtlsFrom.Count > 1)
  2185. {
  2186. foreach (MapDtl d in dtlsFrom)
  2187. {
  2188. d.HisGEDtls_temp = null;
  2189. }
  2190. }
  2191. MapDtls dtlsTo = null;
  2192. if (dtlsFrom.Count >= 1)
  2193. dtlsTo = new MapDtls("ND" + toNode.NodeID);
  2194. // 按照部门分组,分别启动流程。
  2195. switch (this.HisNode.HisFLRole)
  2196. {
  2197. case FLRole.ByStation:
  2198. case FLRole.ByDept:
  2199. case FLRole.ByEmp:
  2200. foreach (WorkerList wl in gwls)
  2201. {
  2202. Work mywk = toNode.HisWork;
  2203. mywk.Copy(this.rptGe);
  2204. mywk.Copy(this.HisWork); //复制过来信息。
  2205. bool isHaveEmp = false;
  2206. if (IsHaveFH)
  2207. {
  2208. /* 如果曾经走过分流合流,就找到同一个人员同一个FID下的OID ,做这当前线程的ID。*/
  2209. DataTable dt = DBAccess.RunSQLReturnTable("SELECT WorkID,FK_Node FROM WF_GenerWorkerlist WHERE FID=" + this.WorkID + " AND FK_Emp='" + wl.FK_Emp + "' ORDER BY RDT DESC");
  2210. if (dt.Rows.Count == 0)
  2211. {
  2212. /*没有发现,就说明以前分流节点中没有这个人的分流信息 */
  2213. mywk.OID = DBAccess.GenerOID();
  2214. }
  2215. else
  2216. {
  2217. int workid_old = (int)dt.Rows[0][0];
  2218. int fk_Node_nearly = (int)dt.Rows[0][1];
  2219. Node nd_nearly = new Node(fk_Node_nearly);
  2220. Work nd_nearly_work = nd_nearly.HisWork;
  2221. nd_nearly_work.OID = workid_old;
  2222. if (nd_nearly_work.RetrieveFromDBSources() != 0)
  2223. {
  2224. mywk.Copy(nd_nearly_work);
  2225. mywk.OID = workid_old;
  2226. }
  2227. else
  2228. {
  2229. mywk.OID = DBAccess.GenerOID();
  2230. }
  2231. isHaveEmp = true;
  2232. }
  2233. }
  2234. else
  2235. {
  2236. mywk.OID = DBAccess.GenerOID(); //BP.DA.DBAccess.GenerOID();
  2237. }
  2238. mywk.FID = this.HisWork.FID;
  2239. mywk.Rec = wl.FK_Emp;
  2240. mywk.Emps = wl.FK_Emp;
  2241. mywk.BeforeSave();
  2242. //判断是不是MD5流程?
  2243. if (this.HisFlow.IsMD5)
  2244. mywk.SetValByKey("MD5", Glo.GenerMD5(mywk));
  2245. mywk.InsertAsOID(mywk.OID);
  2246. #region 复制附件信息
  2247. if (athDBs.Count > 0)
  2248. {
  2249. /* 说明当前节点有附件数据 */
  2250. athDBs.Delete(FrmAttachmentDBAttr.FK_MapData, "ND" + toNode.NodeID,
  2251. FrmAttachmentDBAttr.RefPKVal, mywk.OID);
  2252. int i = 0;
  2253. foreach (FrmAttachmentDB athDB in athDBs)
  2254. {
  2255. i++;
  2256. FrmAttachmentDB athDB_N = new FrmAttachmentDB();
  2257. athDB_N.Copy(athDB);
  2258. athDB_N.FK_MapData = "ND" + toNode.NodeID;
  2259. athDB_N.MyPK = mywk.OID + "_" + mywk.FID + "_" + toNode.NodeID + "_" + i.ToString();
  2260. athDB_N.FK_FrmAttachment = athDB_N.FK_FrmAttachment.Replace("ND" + this.HisNode.NodeID,
  2261. "ND" + toNode.NodeID);
  2262. athDB_N.RefPKVal = mywk.OID.ToString();
  2263. athDB_N.DirectInsert();
  2264. }
  2265. }
  2266. #endregion 复制附件信息
  2267. #region 复制签名信息
  2268. if (eleDBs.Count > 0)
  2269. {
  2270. /* 说明当前节点有附件数据 */
  2271. eleDBs.Delete(FrmEleDBAttr.FK_MapData, "ND" + toNode.NodeID,
  2272. FrmEleDBAttr.RefPKVal, mywk.OID);
  2273. int i = 0;
  2274. foreach (FrmEleDB eleDB in eleDBs)
  2275. {
  2276. i++;
  2277. FrmEleDB athDB_N = new FrmEleDB();
  2278. athDB_N.Copy(eleDB);
  2279. athDB_N.FK_MapData = "ND" + toNode.NodeID;
  2280. athDB_N.RefPKVal = mywk.OID.ToString();
  2281. athDB_N.GenerPKVal();
  2282. athDB_N.DirectInsert();
  2283. }
  2284. }
  2285. #endregion 复制附件信息
  2286. #region 复制明细表信息.
  2287. if (dtlsFrom.Count > 0)
  2288. {
  2289. int i = -1;
  2290. foreach (Sys.MapDtl dtl in dtlsFrom)
  2291. {
  2292. i++;
  2293. if (dtlsTo.Count <= i)
  2294. continue;
  2295. Sys.MapDtl toDtl = (Sys.MapDtl)dtlsTo[i];
  2296. if (toDtl.IsCopyNDData == false)
  2297. continue;
  2298. //获取明细数据。
  2299. GEDtls gedtls = null;
  2300. if (dtl.HisGEDtls_temp == null)
  2301. {
  2302. gedtls = new GEDtls(dtl.No);
  2303. QueryObject qo = null;
  2304. qo = new QueryObject(gedtls);
  2305. switch (dtl.DtlOpenType)
  2306. {
  2307. case DtlOpenType.ForEmp:
  2308. qo.AddWhere(GEDtlAttr.RefPK, this.WorkID);
  2309. break;
  2310. case DtlOpenType.ForWorkID:
  2311. qo.AddWhere(GEDtlAttr.RefPK, this.WorkID);
  2312. break;
  2313. case DtlOpenType.ForFID:
  2314. qo.AddWhere(GEDtlAttr.FID, this.WorkID);
  2315. break;
  2316. }
  2317. qo.DoQuery();
  2318. dtl.HisGEDtls_temp = gedtls;
  2319. }
  2320. gedtls = dtl.HisGEDtls_temp;
  2321. int unPass = 0;
  2322. DBAccess.RunSQL("DELETE " + toDtl.PTable + " WHERE RefPK=" + mywk.OID);
  2323. foreach (GEDtl gedtl in gedtls)
  2324. {
  2325. BP.Sys.GEDtl dtCopy = new GEDtl(toDtl.No);
  2326. dtCopy.Copy(gedtl);
  2327. dtCopy.FK_MapDtl = toDtl.No;
  2328. dtCopy.RefPK = mywk.OID.ToString();
  2329. dtCopy.OID = 0;
  2330. dtCopy.Insert();
  2331. //dtCopy.InsertAsOID(gedtl.OID);
  2332. //dtCopy.InsertAsOID(gedtl.OID);
  2333. #region 复制明细表单条 - 附件信息 - M2M- M2MM
  2334. if (toDtl.IsEnableAthM)
  2335. {
  2336. /*如果启用了多附件,就复制这条明细数据的附件信息。*/
  2337. athDBs = new FrmAttachmentDBs(dtl.No, gedtl.OID.ToString());
  2338. if (athDBs.Count > 0)
  2339. {
  2340. i = 0;
  2341. foreach (FrmAttachmentDB athDB in athDBs)
  2342. {
  2343. i++;
  2344. FrmAttachmentDB athDB_N = new FrmAttachmentDB();
  2345. athDB_N.Copy(athDB);
  2346. athDB_N.FK_MapData = toDtl.No;
  2347. athDB_N.MyPK = toDtl.No + "_" + dtCopy.OID + "_" + i.ToString();
  2348. athDB_N.FK_FrmAttachment = athDB_N.FK_FrmAttachment.Replace("ND" + this.HisNode.NodeID,
  2349. "ND" + toNode.NodeID);
  2350. athDB_N.RefPKVal = dtCopy.OID.ToString();
  2351. athDB_N.DirectInsert();
  2352. }
  2353. }
  2354. }
  2355. if (toDtl.IsEnableM2M || toDtl.IsEnableM2MM)
  2356. {
  2357. /*如果启用了m2m */
  2358. M2Ms m2ms = new M2Ms(dtl.No, gedtl.OID);
  2359. if (m2ms.Count > 0)
  2360. {
  2361. i = 0;
  2362. foreach (M2M m2m in m2ms)
  2363. {
  2364. i++;
  2365. M2M m2m_N = new M2M();
  2366. m2m_N.Copy(m2m);
  2367. m2m_N.FK_MapData = toDtl.No;
  2368. m2m_N.MyPK = toDtl.No + "_" + m2m.M2MNo + "_" + gedtl.ToString() + "_" + m2m.DtlObj;
  2369. m2m_N.EnOID = gedtl.OID;
  2370. m2m_N.InitMyPK();
  2371. m2m_N.DirectInsert();
  2372. }
  2373. }
  2374. }
  2375. #endregion 复制明细表单条 - 附件信息
  2376. }
  2377. }
  2378. }
  2379. #endregion 复制附件信息
  2380. // 产生工作的信息。
  2381. GenerWorkFlow gwf = new GenerWorkFlow();
  2382. gwf.FID = this.WorkID;
  2383. gwf.WorkID = mywk.OID;
  2384. gwf.Title = this.GenerTitle(this.HisWork);
  2385. //if (BP.WF.Glo.IsShowUserNoOnly == false)
  2386. // gwf.Title = WebUser.No + "," + WebUser.Name + " 发起:" + toNode.Name + "(分流节点)";
  2387. //else
  2388. // gwf.Title = WebUser.No + " 发起:" + toNode.Name + "(分流节点)";
  2389. gwf.WFState = 0;
  2390. gwf.RDT = DataType.CurrentDataTime;
  2391. gwf.Rec = Web.WebUser.No;
  2392. gwf.RecName = Web.WebUser.Name;
  2393. gwf.FK_Flow = toNode.FK_Flow;
  2394. gwf.FlowName = toNode.FlowName;
  2395. gwf.FID = this.WorkID;
  2396. gwf.FK_FlowSort = toNode.HisFlow.FK_FlowSort;
  2397. gwf.FK_Node = toNode.NodeID;
  2398. gwf.NodeName = toNode.Name;
  2399. gwf.FK_Dept = wl.FK_Dept;
  2400. gwf.DeptName = wl.FK_DeptT;
  2401. try
  2402. {
  2403. gwf.DirectInsert();
  2404. }
  2405. catch
  2406. {
  2407. gwf.DirectUpdate();
  2408. }
  2409. DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET WorkID=" + mywk.OID + ",FID=" + this.WorkID + " WHERE FK_Emp='" + wl.FK_Emp + "' AND WorkID=" + this.WorkID + " AND FK_Node=" + toNode.NodeID);
  2410. }
  2411. break;
  2412. default:
  2413. throw new Exception("没有处理的类型:" + this.HisNode.HisFLRole.ToString());
  2414. }
  2415. // return 。系统自动下达给如下几位同事。";
  2416. string info = this.ToE("WN28", "@分流节点:{0}已经发起。@任务自动下达给{1}如下{2}位同事,{3}.");
  2417. msg += string.Format(info, toNode.Name,
  2418. this.nextStationName,
  2419. this._RememberMe.NumOfObjs.ToString(),
  2420. this._RememberMe.EmpsExt);
  2421. // 如果是开始节点,就可以允许选择接受人。
  2422. if (this.HisNode.IsStartNode)
  2423. {
  2424. if (gwls.Count >= 2)
  2425. msg += "@<img src='" + this.VirPath + "/WF/Img/AllotTask.gif' border=0 /><a href=\"javascript:WinOpen('" + this.VirPath + "/WF/AllotTask.aspx?WorkID=" + this.WorkID + "&FID=" + this.WorkID + "&NodeID=" + toNode.NodeID + "')\" >" + this.ToE("W29", "修改接受对象") + "</a>.";
  2426. }
  2427. if (this.HisNode.IsStartNode)
  2428. {
  2429. msg += "@<a href='" + this.VirPath + this.AppType + "/MyFlowInfo" + Glo.FromPageType + ".aspx?DoType=UnSend&WorkID=" + this.WorkID + "&FK_Flow=" + toNode.FK_Flow + "'><img src='" + this.VirPath + "/WF/Img/UnDo.gif' border=0/>" + this.ToE("WN22", "撤销本次发送") + "</a>, <a href='" + this.VirPath + "/" + this.AppType + "/MyFlow" + Glo.FromPageType + ".aspx?FK_Flow=" + toNode.FK_Flow + "&FK_Node="+toNode.FK_Flow+"01' ><img src=./Img/New.gif border=0/>" + this.ToE("NewFlow", "新建流程") + "</a>。";
  2430. }
  2431. else
  2432. {
  2433. msg += "@<a href='" + this.VirPath + this.AppType + "/MyFlowInfo" + Glo.FromPageType + ".aspx?DoType=UnSend&WorkID=" + this.WorkID + "&FK_Flow=" + toNode.FK_Flow + "'><img src='" + this.VirPath + "/WF/Img/UnDo.gif' border=0/>" + this.ToE("WN22", "撤销本次发送") + "</a>。";
  2434. // msg += "@<a href=\"javascript:WinOpen('" + this.VirPath + "/" + this.AppType + "/" + Glo.FromPageType + ".aspx?DoType=UnSend&WorkID=" + this.WorkID + "&FK_Flow=" + toNode.FK_Flow + "'><img src='" + this.VirPath + "/WF/Img/UnDo.gif' border=0/>" + this.ToE("WN22", "撤销本次发送") + "</a>。";
  2435. }
  2436. msg += this.GenerWhySendToThem(this.HisNode.NodeID, toNode.NodeID);
  2437. //更新节点状态。
  2438. this.HisWork.Update(WorkAttr.NodeState, (int)NodeState.Complete);
  2439. msg += "@<a href='" + this.VirPath + "/WF/WFRpt.aspx?WorkID=" + this.WorkID + "&FID=" + wk.FID + "&FK_Flow=" + this.HisNode.FK_Flow + "'target='_blank' >工作报告</a>";
  2440. return msg;
  2441. // +" <font color=blue><b>" + this.nextStationName + "</b></font> " + this._RememberMe.NumOfObjs + " :@" + this._RememberMe.EmpsExt;
  2442. // return this.ToEP3("TaskAutoSendTo", "@任务自动下达给{0}如下{1}位同事,{2}.", this._RememberMe.NumOfObjs.ToString(), this._RememberMe.EmpsExt); // +" <font color=blue><b>" + this.nextStationName + "</b></font> " + this._RememberMe.NumOfObjs + " :@" + this._RememberMe.EmpsExt;
  2443. }
  2444. /// <summary>
  2445. /// 分流发起
  2446. /// </summary>
  2447. /// <returns></returns>
  2448. public string FeiLiuStartUp()
  2449. {
  2450. #region GenerFH
  2451. GenerFH fh = new GenerFH();
  2452. fh.FID = this.WorkID;
  2453. if (this.HisNode.IsStartNode || fh.IsExits == false)
  2454. {
  2455. try
  2456. {
  2457. fh.Title = this.HisWork.GetValStringByKey(StartWorkAttr.Title);
  2458. }
  2459. catch (Exception ex)
  2460. {
  2461. BP.Sys.MapAttr attr = new BP.Sys.MapAttr();
  2462. attr.FK_MapData = "ND" + this.HisNode.NodeID;
  2463. attr.HisEditType = BP.En.EditType.UnDel;
  2464. attr.KeyOfEn = "Title";
  2465. int i = attr.Retrieve(MapAttrAttr.FK_MapData, attr.FK_MapData, MapAttrAttr.KeyOfEn, attr.KeyOfEn);
  2466. if (i == 0)
  2467. {
  2468. attr.KeyOfEn = "Title";
  2469. attr.Name = BP.Sys.Language.GetValByUserLang("Title", "标题"); // "流程标题";
  2470. attr.MyDataType = BP.DA.DataType.AppString;
  2471. attr.UIContralType = UIContralType.TB;
  2472. attr.LGType = FieldTypeS.Normal;
  2473. attr.UIVisible = true;
  2474. attr.UIIsEnable = true;
  2475. attr.UIIsLine = true;
  2476. attr.MinLen = 0;
  2477. attr.MaxLen = 200;
  2478. attr.IDX = -100;
  2479. attr.Insert();
  2480. }
  2481. fh.Title = WebUser.No + "-" + WebUser.Name + " @ " + DataType.CurrentDataTime + " ";
  2482. }
  2483. fh.RDT = DataType.CurrentData;
  2484. fh.FID = this.WorkID;
  2485. fh.FK_Flow = this.HisNode.FK_Flow;
  2486. fh.FK_Node = this.HisNode.NodeID;
  2487. fh.GroupKey = WebUser.No;
  2488. fh.WFState = 0;
  2489. try
  2490. {
  2491. fh.DirectInsert();
  2492. }
  2493. catch
  2494. {
  2495. fh.DirectUpdate();
  2496. }
  2497. }
  2498. #endregion GenerFH
  2499. string msg = "";
  2500. Nodes toNodes = this.HisNode.HisToNodes;
  2501. // 如果只有一个转向节点, 就不用判断条件了,直接转向他.
  2502. if (toNodes.Count == 1)
  2503. return FeiLiuStartUp((Node)toNodes[0]);
  2504. Conds dcsAll = new Conds();
  2505. dcsAll.Retrieve(CondAttr.NodeID, this.HisNode.NodeID, CondAttr.PRI);
  2506. if (dcsAll.Count == 0)
  2507. {
  2508. /*如果没有设置方向条件就全部通过*/
  2509. return msg + StartNextNode(toNodes);
  2510. }
  2511. #region 获取能够通过的节点集合如果没有设置方向条件就默认通过.
  2512. Nodes myNodes = new Nodes();
  2513. int toNodeId = 0;
  2514. int numOfWay = 0;
  2515. foreach (Node nd in toNodes)
  2516. {
  2517. Conds dcs = new Conds();
  2518. foreach (Cond dc in dcsAll)
  2519. {
  2520. if (dc.ToNodeID != nd.NodeID)
  2521. continue;
  2522. dc.WorkID = this.HisWork.OID;
  2523. dcs.AddEntity(dc);
  2524. }
  2525. if (dcs.Count == 0)
  2526. {
  2527. // 如果没有设置方向条件,就默认通过的.
  2528. myNodes.AddEntity(nd);
  2529. continue;
  2530. // throw new Exception(string.Format(this.ToE("WN10", "@定义节点的方向条件错误:没有给从{0}节点到{1},定义转向条件."), this.HisNode.NodeID + this.HisNode.Name, nd.NodeID + nd.Name));
  2531. }
  2532. if (dcs.IsPass) // 如果多个转向条件中有一个成立.
  2533. {
  2534. myNodes.AddEntity(nd);
  2535. continue;
  2536. //numOfWay++;
  2537. //toNodeId = nd.NodeID;
  2538. //msg = FeiLiuStartUp(nd);
  2539. }
  2540. }
  2541. #endregion 获取能够通过的节点集合如果没有设置方向条件就默认通过.
  2542. if (myNodes.Count == 0)
  2543. {
  2544. throw new Exception(string.Format(this.ToE("WN10_1",
  2545. "@定义节点的方向条件错误:没有给从{0}节点到其它节点,定义转向条件."), this.HisNode.NodeID + this.HisNode.Name));
  2546. }
  2547. else
  2548. {
  2549. return msg + StartNextNode(myNodes);
  2550. }
  2551. }
  2552. #endregion
  2553. public string GenerTitle(Work wk)
  2554. {
  2555. // 生成标题.
  2556. Attr myattr = wk.EnMap.Attrs.GetAttrByKey("Title");
  2557. if (myattr == null)
  2558. myattr = wk.EnMap.Attrs.GetAttrByKey("Title");
  2559. string titleRole = "";
  2560. if (myattr != null)
  2561. titleRole = myattr.DefaultVal.ToString();
  2562. if (string.IsNullOrEmpty(titleRole) || titleRole.Contains("@") == false)
  2563. titleRole = "@WebUser.FK_DeptName-@WebUser.No,@WebUser.Name在@RDT发起.";
  2564. titleRole = titleRole.Replace("@WebUser.No", wk.Rec);
  2565. titleRole = titleRole.Replace("@WebUser.Name", wk.RecText);
  2566. titleRole = titleRole.Replace("@WebUser.FK_DeptName", wk.RecOfEmp.FK_DeptText);
  2567. titleRole = titleRole.Replace("@RDT", wk.RDT);
  2568. if (titleRole.Contains("@"))
  2569. {
  2570. foreach (Attr attr in wk.EnMap.Attrs)
  2571. {
  2572. if (titleRole.Contains("@") == false)
  2573. break;
  2574. if (attr.IsFKorEnum)
  2575. continue;
  2576. titleRole = titleRole.Replace("@" + attr.Key, wk.GetValStrByKey(attr.Key));
  2577. }
  2578. }
  2579. wk.SetValByKey("Title", titleRole);
  2580. return titleRole;
  2581. }
  2582. public GEEntity rptGe = null;
  2583. private void InitStartWorkData()
  2584. {
  2585. /* 产生开始工作流程记录. */
  2586. GenerWorkFlow gwf = new GenerWorkFlow();
  2587. gwf.WorkID = this.HisWork.OID;
  2588. gwf.Title = this.GenerTitle(this.HisWork);
  2589. gwf.WFState = 0;
  2590. gwf.RDT = this.HisWork.RDT;
  2591. gwf.Rec = Web.WebUser.No;
  2592. gwf.RecName = Web.WebUser.Name;
  2593. gwf.FK_Flow = this.HisNode.FK_Flow;
  2594. gwf.FlowName = this.HisNode.FlowName;
  2595. gwf.FK_FlowSort = this.HisNode.HisFlow.FK_FlowSort;
  2596. gwf.FK_Node = this.HisNode.NodeID;
  2597. gwf.NodeName = this.HisNode.Name;
  2598. gwf.FK_Dept = this.HisWork.RecOfEmp.FK_Dept;
  2599. gwf.DeptName = this.HisWork.RecOfEmp.FK_DeptText;
  2600. if (Glo.IsEnablePRI)
  2601. {
  2602. try
  2603. {
  2604. gwf.PRI = this.HisWork.GetValIntByKey("PRI");
  2605. }
  2606. catch (Exception ex)
  2607. {
  2608. this.HisNode.RepareMap();
  2609. }
  2610. }
  2611. try
  2612. {
  2613. gwf.DirectInsert();
  2614. }
  2615. catch
  2616. {
  2617. gwf.DirectUpdate();
  2618. }
  2619. StartWork sw = (StartWork)this.HisWork;
  2620. #region 设置 HisGenerWorkFlow
  2621. this.HisGenerWorkFlow = gwf;
  2622. //#warning 去掉这个工作没有想到如何去写?
  2623. // 记录到流程统计分析中去。
  2624. //this.HisCHOfFlow = new CHOfFlow();
  2625. //this.HisCHOfFlow.Copy(gwf);
  2626. //this.HisCHOfFlow.WorkID = this.HisWork.OID;
  2627. //this.HisCHOfFlow.WFState = (int)WFState.Runing;
  2628. ///* 说明没有这个记录 */
  2629. //this.HisCHOfFlow.FK_Flow = this.HisNode.FK_Flow;
  2630. //this.HisCHOfFlow.WFState = 0;
  2631. //this.HisCHOfFlow.Title = gwf.Title;
  2632. //this.HisCHOfFlow.FK_Emp = this.HisWork.Rec.ToString();
  2633. //this.HisCHOfFlow.RDT = this.HisWork.RDT;
  2634. //this.HisCHOfFlow.CDT = DataType.CurrentDataTime;
  2635. //this.HisCHOfFlow.SpanDays = 0;
  2636. //this.HisCHOfFlow.FK_Dept = this.HisDeptOfUse.No;
  2637. //this.HisCHOfFlow.FK_NY = DataType.CurrentYearMonth;
  2638. //try
  2639. //{
  2640. // this.HisCHOfFlow.Insert();
  2641. //}
  2642. //catch
  2643. //{
  2644. // this.HisCHOfFlow.Update();
  2645. //}
  2646. #endregion HisCHOfFlow
  2647. #region 产生开始工作者,能够执行他们的人员.
  2648. WorkerList wl = new WorkerList();
  2649. wl.WorkID = this.HisWork.OID;
  2650. wl.FK_Node = this.HisNode.NodeID;
  2651. wl.FK_NodeText = this.HisNode.Name;
  2652. wl.FK_Emp = WebUser.No;
  2653. wl.FK_EmpText = WebUser.Name;
  2654. wl.FK_Flow = this.HisNode.FK_Flow;
  2655. wl.FK_Dept = WebUser.FK_Dept;
  2656. wl.WarningDays = this.HisNode.WarningDays;
  2657. wl.SDT = DataType.CurrentData;
  2658. wl.DTOfWarning = DataType.CurrentData;
  2659. wl.RDT = DataType.CurrentDataTime;
  2660. try
  2661. {
  2662. wl.Insert(); // 先插入,后更新。
  2663. }
  2664. catch
  2665. {
  2666. wl.Update();
  2667. }
  2668. #endregion
  2669. }
  2670. /// <summary>
  2671. /// 执行数据copy.
  2672. /// </summary>
  2673. /// <param name="fromWK"></param>
  2674. private void DoCopyRptWork(Work fromWK)
  2675. {
  2676. foreach (Attr attr in fromWK.EnMap.Attrs)
  2677. {
  2678. switch (attr.Key)
  2679. {
  2680. case BP.WF.GERptAttr.FK_NY:
  2681. case BP.WF.GERptAttr.FK_Dept:
  2682. case BP.WF.GERptAttr.FlowDaySpan:
  2683. case BP.WF.GERptAttr.FlowEmps:
  2684. case BP.WF.GERptAttr.FlowEnder:
  2685. case BP.WF.GERptAttr.FlowEnderRDT:
  2686. case BP.WF.GERptAttr.FlowStarter:
  2687. case BP.WF.GERptAttr.Title:
  2688. continue;
  2689. default:
  2690. break;
  2691. }
  2692. object obj = fromWK.GetValByKey(attr.Key);
  2693. if (obj == null)
  2694. continue;
  2695. this.rptGe.SetValByKey(attr.Key, obj);
  2696. }
  2697. if (this.HisNode.IsStartNode)
  2698. this.rptGe.SetValByKey("Title", fromWK.GetValByKey("Title"));
  2699. }
  2700. /// <summary>
  2701. /// 在流程节点保存后的操作.
  2702. /// 1, 判断节点的任务是不是完成,如果完成,就设置节点的完成状态.
  2703. /// 2, 判断是不是符合工作流完成任务任务的条件, 如果完成,就设置,工作流程任务完成. return ;
  2704. /// 3, 判断节点的方向.
  2705. /// 1, 一个一个的判断此节点的方向, 满足就启动节点工作.
  2706. /// 2, 如果没有任何一个节点的工作.那末就抛出异常, 流程的节点方向条件定义错误. .
  2707. /// </summary>
  2708. /// <param name="TransferPC">是否要执行获取外部信息工组</param>
  2709. /// <param name="ByTransfered">是不是被调用的,只用在开始节点,并且是外部调用的自动启动的流程,如果设置为true, 流程在当前的节点完成之后就不做下一步骤的工作,如果设置为false, 就做下一步工作.</param>
  2710. /// <returns>执行后的内容</returns>
  2711. private string AfterNodeSave_Do()
  2712. {
  2713. #region 把数据放到报表表里面.
  2714. if (this.HisNode.IsStartNode)
  2715. this.InitStartWorkData();
  2716. this.rptGe = this.HisNode.HisFlow.HisFlowData;
  2717. this.rptGe.SetValByKey("OID", this.WorkID);
  2718. if (rptGe.RetrieveFromDBSources() == 0)
  2719. {
  2720. rptGe.SetValByKey("OID", this.WorkID);
  2721. this.DoCopyRptWork(this.HisWork);
  2722. rptGe.SetValByKey(GERptAttr.FlowEmps, "@" + WebUser.No + "," + WebUser.Name);
  2723. rptGe.SetValByKey(GERptAttr.FlowStarter, WebUser.No);
  2724. rptGe.SetValByKey(GERptAttr.FlowStartRDT, DataType.CurrentDataTime);
  2725. rptGe.SetValByKey(GERptAttr.WFState, 0);
  2726. rptGe.SetValByKey(GERptAttr.FK_NY, DataType.CurrentYearMonth);
  2727. rptGe.SetValByKey(GERptAttr.FK_Dept, WebUser.FK_Dept);
  2728. rptGe.Insert();
  2729. }
  2730. else
  2731. {
  2732. foreach (Attr attr in this.HisWork.EnMap.Attrs)
  2733. {
  2734. switch (attr.Key)
  2735. {
  2736. case StartWorkAttr.FK_Dept:
  2737. case StartWorkAttr.FID:
  2738. case StartWorkAttr.CDT:
  2739. case StartWorkAttr.RDT:
  2740. case StartWorkAttr.Rec:
  2741. case StartWorkAttr.Sender:
  2742. case StartWorkAttr.NodeState:
  2743. case StartWorkAttr.OID:
  2744. case StartWorkAttr.Title:
  2745. continue;
  2746. default:
  2747. break;
  2748. }
  2749. object obj = this.HisWork.GetValByKey(attr.Key);
  2750. if (obj == null)
  2751. continue;
  2752. rptGe.SetValByKey(attr.Key, obj);
  2753. }
  2754. try
  2755. {
  2756. string str = rptGe.GetValStrByKey(GERptAttr.FlowEmps);
  2757. if (str.Contains("@" + WebUser.No + "," + WebUser.Name) == false)
  2758. rptGe.SetValByKey(GERptAttr.FlowEmps, str + "@" + WebUser.No + "," + WebUser.Name);
  2759. }
  2760. catch
  2761. {
  2762. this.HisNode.HisFlow.DoCheck();
  2763. }
  2764. if (this.HisNode.IsEndNode)
  2765. {
  2766. rptGe.SetValByKey(GERptAttr.WFState, 1); // 更新状态。
  2767. rptGe.SetValByKey(GERptAttr.FlowEnder, WebUser.No);
  2768. rptGe.SetValByKey(GERptAttr.FlowEnderRDT, DataType.CurrentDataTime);
  2769. rptGe.SetValByKey(GERptAttr.FlowDaySpan, DataType.GetSpanDays(this.rptGe.GetValStringByKey(GERptAttr.FlowStartRDT), DataType.CurrentDataTime));
  2770. }
  2771. rptGe.DirectUpdate();
  2772. /* 查看一下本路径是否是原路退回的可能?*/
  2773. //string retoNode = DBAccess.RunSQLReturnString("SELECT ReturnNode FROM WF_ReturnWork WHERE ReturnToNode=" + this.HisNode.NodeID + " AND WorkID=" + this.WorkID + " AND IsBackTracking=1", null);
  2774. //if (retoNode != null)
  2775. //{
  2776. // /*说明有原路退回的问题。*/
  2777. // this.JumpToEmp = DBAccess.RunSQLReturnString("SELECT Returner FROM WF_ReturnWork WHERE ReturnToNode=" + this.HisNode.NodeID + " AND WorkID=" + this.WorkID + " AND IsBackTracking=1", null);
  2778. // this.JumpToNode = new Node(int.Parse(retoNode));
  2779. //}
  2780. }
  2781. #endregion
  2782. #region 根据当前节点类型不同处理不同的模式
  2783. string msg = "";
  2784. switch (this.HisNode.HisNodeWorkType)
  2785. {
  2786. case NodeWorkType.StartWorkFL:
  2787. case NodeWorkType.WorkFL: /* 启动分流 */
  2788. this.HisWork.FID = this.HisWork.OID;
  2789. msg = this.FeiLiuStartUp();
  2790. break;
  2791. case NodeWorkType.WorkFHL: /* 启动分流 */
  2792. this.HisWork.FID = this.HisWork.OID;
  2793. msg = this.FeiLiuStartUp();
  2794. break;
  2795. case NodeWorkType.WorkHL: /* 当前工作节点是合流 */
  2796. msg = this.StartupNewNodeWork();
  2797. msg += this.DoSetThisWorkOver(); // 执行此工作结束。
  2798. break;
  2799. default: /* 其他的点的逻辑 */
  2800. msg = this.StartupNewNodeWork();
  2801. msg += this.DoSetThisWorkOver();
  2802. break;
  2803. }
  2804. #endregion 根据当前节点类型不同处理不同的模式
  2805. #region 处理收听
  2806. if (Glo.IsEnableSysMessage)
  2807. {
  2808. Listens lts = new Listens();
  2809. lts.RetrieveByLike(ListenAttr.Nodes, "%" + this.HisNode.NodeID + "%");
  2810. foreach (Listen lt in lts)
  2811. {
  2812. string sql = "SELECT FK_Emp FROM WF_GenerWorkerList WHERE IsEnable=1 AND IsPass=1 AND FK_Node=" + lt.FK_Node + " AND WorkID=" + this.WorkID;
  2813. DataTable dtRem = BP.DA.DBAccess.RunSQLReturnTable(sql);
  2814. foreach (DataRow dr in dtRem.Rows)
  2815. {
  2816. string fk_emp = dr["FK_Emp"] as string;
  2817. Port.WFEmp emp = new BP.WF.Port.WFEmp(fk_emp);
  2818. if (emp.HisAlertWay == BP.WF.Port.AlertWay.None)
  2819. {
  2820. // msg += "@<font color=red>此信息无法发送给:" + emp.Name + ",因为他关闭了信息提醒,给他打电话:"+emp.Tel+"</font>";
  2821. msg += "@<font color=red>" + this.ToEP2("WN25", "此信息无法发送给:{0},因为他关闭了信息提醒,给他打电话:{1}。", emp.Name, emp.Tel) + "</font>";
  2822. continue;
  2823. }
  2824. else
  2825. {
  2826. // msg += "@您的操作已经通过(<font color=green><b>" + emp.HisAlertWayT + "</b></font>)的方式发送给:" + emp.Name;
  2827. msg += this.ToEP2("WN26", "@您的操作已经通过(<font color=green><b>{0}</b></font>)的方式发送给:{1}", emp.HisAlertWayT, emp.Name);
  2828. }
  2829. string title = lt.Title.Clone() as string;
  2830. title = title.Replace("@WebUser.No", WebUser.No);
  2831. title = title.Replace("@WebUser.Name", WebUser.Name);
  2832. title = title.Replace("@WebUser.FK_Dept", WebUser.FK_Dept);
  2833. title = title.Replace("@WebUser.FK_DeptName", WebUser.FK_DeptName);
  2834. string doc = lt.Doc.Clone() as string;
  2835. doc = doc.Replace("@WebUser.No", WebUser.No);
  2836. doc = doc.Replace("@WebUser.Name", WebUser.Name);
  2837. doc = doc.Replace("@WebUser.FK_Dept", WebUser.FK_Dept);
  2838. doc = doc.Replace("@WebUser.FK_DeptName", WebUser.FK_DeptName);
  2839. Attrs attrs = this.rptGe.EnMap.Attrs;
  2840. foreach (Attr attr in attrs)
  2841. {
  2842. title = title.Replace("@" + attr.Key, this.rptGe.GetValStrByKey(attr.Key));
  2843. doc = doc.Replace("@" + attr.Key, this.rptGe.GetValStrByKey(attr.Key));
  2844. }
  2845. BP.TA.SMS.AddMsg(lt.OID + "_" + this.WorkID, fk_emp, emp.HisAlertWay, emp.Tel, title, emp.Email, title, doc);
  2846. }
  2847. }
  2848. }
  2849. #endregion
  2850. #region 生成单据
  2851. BillTemplates reffunc = this.HisNode.HisBillTemplates;
  2852. if (reffunc.Count > 0)
  2853. {
  2854. #region 生成单据信息
  2855. Int64 workid = this.HisWork.OID;
  2856. int nodeId = this.HisNode.NodeID;
  2857. string flowNo = this.HisNode.FK_Flow;
  2858. #endregion
  2859. DateTime dt = DateTime.Now;
  2860. Flow fl = new Flow(this.HisNode.FK_Flow);
  2861. string year = dt.Year.ToString();
  2862. string billInfo = "";
  2863. foreach (BillTemplate func in reffunc)
  2864. {
  2865. string file = year + "_" + WebUser.FK_Dept + "_" + func.No + "_" + workid + ".doc";
  2866. BP.Rpt.RTF.RTFEngine rtf = new BP.Rpt.RTF.RTFEngine();
  2867. Works works;
  2868. string[] paths;
  2869. string path;
  2870. try
  2871. {
  2872. #region 生成单据
  2873. rtf.HisEns.Clear();
  2874. rtf.EnsDataDtls.Clear();
  2875. if (func.NodeID == 0)
  2876. {
  2877. // 判断是否是受理回执
  2878. //if (fl.DateLit == 0)
  2879. // continue;
  2880. //HisCHOfFlow.DateLitFrom = DateTime.Now.AddDays(fl.DateLit).ToString(DataType.SysDataFormat);
  2881. //HisCHOfFlow.DateLitTo = DateTime.Now.AddDays(fl.DateLit + 10).ToString(DataType.SysDataFormat);
  2882. //HisCHOfFlow.Update();
  2883. // rtf.AddEn(HisCHOfFlow);
  2884. }
  2885. else
  2886. {
  2887. WorkNodes wns = new WorkNodes();
  2888. if (this.HisNode.HisFNType == FNType.River)
  2889. wns.GenerByFID(this.HisNode.HisFlow, this.WorkID);
  2890. else
  2891. wns.GenerByWorkID(this.HisNode.HisFlow, this.WorkID);
  2892. rtf.HisGEEntity = rptGe;
  2893. works = wns.GetWorks;
  2894. foreach (Work wk in works)
  2895. {
  2896. if (wk.OID == 0)
  2897. continue;
  2898. rtf.AddEn(wk);
  2899. rtf.ensStrs += ".ND" + wk.NodeID;
  2900. ArrayList al = wk.GetDtlsDatasOfArrayList();
  2901. foreach (Entities ens in al)
  2902. rtf.AddDtlEns(ens);
  2903. }
  2904. // w = new BP.Port.WordNo(WebUser.FK_DeptOfXJ);
  2905. // rtf.AddEn(w);
  2906. }
  2907. paths = file.Split('_');
  2908. path = paths[0] + "/" + paths[1] + "/" + paths[2] + "/";
  2909. string billUrl = this.VirPath + "/DataUser/Bill/" + path + file;
  2910. if (func.HisBillFileType == BillFileType.PDF)
  2911. {
  2912. billUrl = billUrl.Replace(".doc", ".pdf");
  2913. billInfo += "<img src='" + this.VirPath + "/Images/FileType/PDF.gif' /><a href='" + billUrl + "' target=_blank >" + func.Name + "</a>";
  2914. }
  2915. else
  2916. {
  2917. billInfo += "<img src='" + this.VirPath + "/Images/FileType/doc.gif' /><a href='" + billUrl + "' target=_blank >" + func.Name + "</a>";
  2918. }
  2919. // string = BP.SystemConfig.GetConfig("FtpPath") + file;
  2920. path = BP.WF.Glo.FlowFileBill + year + "\\" + WebUser.FK_Dept + "\\" + func.No + "\\";
  2921. if (System.IO.Directory.Exists(path) == false)
  2922. System.IO.Directory.CreateDirectory(path);
  2923. rtf.MakeDoc(func.Url + ".rtf",
  2924. path, file, func.ReplaceVal, false);
  2925. #endregion
  2926. #region 转化成pdf.
  2927. if (func.HisBillFileType == BillFileType.PDF)
  2928. {
  2929. string rtfPath = path + file;
  2930. string pdfPath = rtfPath.Replace(".doc", ".pdf");
  2931. // string pdfPath = path + func.Url + ".pdf";
  2932. try
  2933. {
  2934. Glo.Rtf2PDF(rtfPath, pdfPath);
  2935. }
  2936. catch (Exception ex)
  2937. {
  2938. msg += ex.Message;
  2939. }
  2940. }
  2941. #endregion
  2942. #region 保存单据
  2943. Bill bill = new Bill();
  2944. bill.MyPK = this.HisWork.FID + "_" + this.HisWork.OID + "_" + this.HisNode.NodeID + "_" + func.No;
  2945. bill.FID = this.HisWork.FID;
  2946. bill.WorkID = this.HisWork.OID;
  2947. bill.FK_Node = this.HisNode.NodeID;
  2948. // bill.FK_Bill = func.No;
  2949. bill.FK_Dept = WebUser.FK_Dept;
  2950. bill.FK_Emp = WebUser.No;
  2951. bill.Url = billUrl;
  2952. bill.RDT = DataType.CurrentDataTime;
  2953. bill.FullPath = path + file;
  2954. bill.FK_NY = DataType.CurrentYearMonth;
  2955. bill.FK_Flow = this.HisNode.FK_Flow;
  2956. bill.FK_BillType = func.FK_BillType;
  2957. bill.FK_Flow = this.HisNode.FK_Flow;
  2958. bill.Emps = this.rptGe.GetValStrByKey("Emps");
  2959. bill.FK_Starter = this.rptGe.GetValStrByKey("Rec");
  2960. bill.StartDT = this.rptGe.GetValStrByKey("RDT");
  2961. bill.Title = this.rptGe.GetValStrByKey("Title");
  2962. bill.FK_Dept = this.rptGe.GetValStrByKey("FK_Dept");
  2963. try
  2964. {
  2965. bill.Insert();
  2966. }
  2967. catch
  2968. {
  2969. bill.Update();
  2970. }
  2971. #endregion
  2972. }
  2973. catch (Exception ex)
  2974. {
  2975. BP.WF.DTS.InitBillDir dir = new BP.WF.DTS.InitBillDir();
  2976. dir.Do();
  2977. path = BP.WF.Glo.FlowFileBill + year + "\\" + WebUser.FK_Dept + "\\" + func.No + "\\";
  2978. string msgErr = "@" + this.ToE("WN5", "生成单据失败,请让管理员检查目录设置") + "[" + BP.WF.Glo.FlowFileBill + "]。@Err:" + ex.Message + " @File=" + file + " @Path:" + path;
  2979. billInfo += "@<font color=red>" + msgErr + "</font>";
  2980. throw new Exception(msgErr + "@其它信息:" + ex.Message);
  2981. }
  2982. } // end 生成循环单据。
  2983. if (billInfo != "")
  2984. billInfo = "@" + billInfo;
  2985. msg += billInfo;
  2986. }
  2987. #endregion
  2988. // this.HisWork.DoCopy(); // copy 本地的数据到指定的系统.
  2989. DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=1 WHERE FK_Node=" + this.HisNode.NodeID + " AND WorkID=" + this.WorkID);
  2990. #region 执行抄送.
  2991. if (this.HisNode.HisCCRole == CCRole.AutoCC || this.HisNode.HisCCRole == CCRole.HandAndAuto)
  2992. {
  2993. /*如果是自动抄送*/
  2994. CC cc = new CC();
  2995. cc.NodeID = this.HisNode.NodeID;
  2996. cc.Retrieve();
  2997. string ccTitle = cc.CCTitle.Clone() as string;
  2998. ccTitle = ccTitle.Replace("@WebUser.No", WebUser.No);
  2999. ccTitle = ccTitle.Replace("@WebUser.Name", WebUser.Name);
  3000. ccTitle = ccTitle.Replace("@WebUser.FK_Dept", WebUser.FK_Dept);
  3001. ccTitle = ccTitle.Replace("@WebUser.FK_DeptName", WebUser.FK_DeptName);
  3002. ccTitle = ccTitle.Replace("@RDT", DataType.CurrentData);
  3003. string ccDoc = cc.CCDoc.Clone() as string;
  3004. ccDoc = ccDoc.Replace("@WebUser.No", WebUser.No);
  3005. ccDoc = ccDoc.Replace("@WebUser.Name", WebUser.Name);
  3006. ccDoc = ccDoc.Replace("@RDT", DataType.CurrentData);
  3007. ccDoc = ccDoc.Replace("@WebUser.FK_Dept", WebUser.FK_Dept);
  3008. ccDoc = ccDoc.Replace("@WebUser.FK_DeptName", WebUser.FK_DeptName);
  3009. foreach (Attr item in this.rptGe.EnMap.Attrs)
  3010. {
  3011. if (ccDoc.Contains("@" + item.Key) == true)
  3012. ccDoc = ccDoc.Replace("@" + item.Key, this.rptGe.GetValStrByKey(item.Key));
  3013. if (ccTitle.Contains("@" + item.Key) == true)
  3014. ccTitle = ccTitle.Replace("@" + item.Key, this.rptGe.GetValStrByKey(item.Key));
  3015. }
  3016. // ccDoc += "\t\n ------------------- ";
  3017. // string msgPK = "SELECT MyPK FROM WF_Track WHERE WorkID="+this.WorkID+" AND NDFrom="+this.HisNode.NodeID+" ORDER BY RDT";
  3018. DataTable ccers = cc.GenerCCers(this.rptGe);
  3019. if (ccers.Rows.Count > 0)
  3020. {
  3021. msg += "@消息自动抄送给";
  3022. string basePath = "http://" + System.Web.HttpContext.Current.Request.Url.Host;
  3023. basePath += "/" + System.Web.HttpContext.Current.Request.ApplicationPath;
  3024. string mailTemp = BP.DA.DataType.ReadTextFile2Html(BP.SystemConfig.PathOfDataUser + "\\EmailTemplete\\CC_" + WebUser.SysLang + ".txt");
  3025. foreach (DataRow dr in ccers.Rows)
  3026. {
  3027. ccDoc = ccDoc.Replace("@Accepter", dr[1].ToString());
  3028. ccTitle = ccTitle.Replace("@Accepter", dr[1].ToString());
  3029. CCList list = new CCList();
  3030. list.MyPK = this.WorkID + "_" + this.HisNode.NodeID + "_" + dr[0].ToString();
  3031. list.FK_Flow = this.HisNode.FK_Flow;
  3032. list.FlowName = this.HisNode.FlowName;
  3033. list.FK_Node = this.HisNode.NodeID;
  3034. list.NodeName = this.HisNode.Name;
  3035. list.Title = ccTitle;
  3036. list.Doc = ccDoc;
  3037. list.CCTo = dr[0].ToString();
  3038. list.RDT = DataType.CurrentDataTime;
  3039. list.Rec = WebUser.No;
  3040. list.RefWorkID = this.WorkID;
  3041. list.FID = this.HisWork.FID;
  3042. try
  3043. {
  3044. list.Insert();
  3045. }
  3046. catch
  3047. {
  3048. list.CheckPhysicsTable();
  3049. list.Update();
  3050. }
  3051. msg += list.CCTo + "(" + dr[1].ToString() + ");";
  3052. BP.WF.Port.WFEmp wfemp = new Port.WFEmp(list.CCTo);
  3053. string sid = list.CCTo + "_" + list.RefWorkID + "_" + list.FK_Node + "_" + list.RDT;
  3054. string url = basePath + "/WF/Do.aspx?DoType=OF&SID=" + sid;
  3055. string urlWap = basePath + "/WF/Do.aspx?DoType=OF&SID=" + sid + "&IsWap=1";
  3056. string mytemp = mailTemp.Clone() as string;
  3057. mytemp = string.Format(mytemp, wfemp.Name, WebUser.Name, url, urlWap);
  3058. BP.TA.SMS.AddMsg(list.RefWorkID + "_" + list.FK_Node + "_" + wfemp.No, wfemp.No, wfemp.HisAlertWay, wfemp.Tel,
  3059. this.ToEP3("WN27", "工作抄送:{0}.工作:{1},发送人:{2},需您查阅",
  3060. this.HisNode.FlowName, this.HisNode.Name, WebUser.Name), wfemp.Email, null, mytemp);
  3061. }
  3062. }
  3063. // BP.TA.SMS.AddMsg(
  3064. // this.WorkerListWayOfDept
  3065. }
  3066. #endregion 执行抄送.
  3067. return msg;
  3068. }
  3069. /// <summary>
  3070. /// 增加日志
  3071. /// </summary>
  3072. /// <param name="at">类型</param>
  3073. /// <param name="toEmp">到人员</param>
  3074. /// <param name="toEmpName">到人员名称</param>
  3075. /// <param name="toNDid">到节点</param>
  3076. /// <param name="toNDName">到节点名称</param>
  3077. /// <param name="msg">消息</param>
  3078. public void AddToTrack(ActionType at, string toEmp, string toEmpName, int toNDid, string toNDName, string msg)
  3079. {
  3080. Track t = new Track();
  3081. t.WorkID = this.HisWork.OID;
  3082. t.FID = this.HisWork.FID;
  3083. t.RDT = DataType.CurrentDataTimess;
  3084. t.HisActionType = at;
  3085. t.NDFrom = this.HisNode.NodeID;
  3086. t.NDFromT = this.HisNode.Name;
  3087. t.EmpFrom = WebUser.No;
  3088. t.EmpFromT = WebUser.Name;
  3089. t.FK_Flow = this.HisNode.FK_Flow;
  3090. t.NDTo = toNDid;
  3091. t.NDToT = toNDName;
  3092. t.EmpTo = toEmp;
  3093. t.EmpToT = toEmpName;
  3094. t.Msg = msg;
  3095. if (string.IsNullOrEmpty(msg))
  3096. {
  3097. switch (at)
  3098. {
  3099. case ActionType.Forward:
  3100. case ActionType.Start:
  3101. case ActionType.Undo:
  3102. case ActionType.ForwardFL:
  3103. case ActionType.ForwardHL:
  3104. //判断是否有焦点字段,如果有就把它记录到日志里。
  3105. if (this.HisNode.FocusField.Length > 1)
  3106. {
  3107. try
  3108. {
  3109. t.Msg = this.HisWork.GetValStrByKey(this.HisNode.FocusField);
  3110. }
  3111. catch (Exception ex)
  3112. {
  3113. Log.DebugWriteError("@焦点字段被删除了" + ex.Message + "@" + this.HisNode.FocusField);
  3114. }
  3115. }
  3116. break;
  3117. default:
  3118. break;
  3119. }
  3120. }
  3121. if (at == ActionType.Forward)
  3122. {
  3123. if (this.HisNode.IsFL)
  3124. at = ActionType.ForwardFL;
  3125. }
  3126. try
  3127. {
  3128. t.MyPK = t.WorkID + "_" + t.FID + "_" + t.NDFrom + "_" + t.NDTo +"_"+t.EmpFrom+"_"+t.EmpTo+"_"+ DateTime.Now.ToString("yyMMddhhmmss");
  3129. t.Insert();
  3130. }
  3131. catch
  3132. {
  3133. t.CheckPhysicsTable();
  3134. }
  3135. }
  3136. /// <summary>
  3137. /// 加入工作记录
  3138. /// </summary>
  3139. /// <param name="gwls"></param>
  3140. public void AddIntoWacthDog(WorkerLists gwls)
  3141. {
  3142. if (BP.SystemConfig.IsBSsystem == false)
  3143. return;
  3144. if (BP.WF.Glo.IsEnableSysMessage == false)
  3145. return;
  3146. string basePath = "http://" + System.Web.HttpContext.Current.Request.Url.Host;
  3147. basePath += "/" + System.Web.HttpContext.Current.Request.ApplicationPath;
  3148. string mailTemp = BP.DA.DataType.ReadTextFile2Html(BP.SystemConfig.PathOfDataUser + "\\EmailTemplete\\" + WebUser.SysLang + ".txt");
  3149. foreach (WorkerList wl in gwls)
  3150. {
  3151. if (wl.IsEnable == false)
  3152. continue;
  3153. string sid = wl.FK_Emp + "_" + wl.WorkID + "_" + wl.FK_Node + "_" + wl.RDT;
  3154. string url = basePath + "/WF/Do.aspx?DoType=OF&SID=" + sid;
  3155. string urlWap = basePath + "/WF/Do.aspx?DoType=OF&SID=" + sid + "&IsWap=1";
  3156. //string mytemp ="您好" + wl.FK_EmpText + ": <br><br>&nbsp;&nbsp; "+WebUser.Name+"发来的工作需要您处理,点这里<a href='" + url + "'>打开工作</a>。 \t\n <br>&nbsp;&nbsp;如果打不开请复制到浏览器地址栏里。<br>&nbsp;&nbsp;" + url + " <br><br>&nbsp;&nbsp;此邮件由iWF工作流程引擎自动发出,请不要回复。<br>*^_^* 谢谢 ";
  3157. string mytemp = mailTemp.Clone() as string;
  3158. mytemp = string.Format(mytemp, wl.FK_EmpText, WebUser.Name, url, urlWap);
  3159. //执行消息发送。
  3160. BP.WF.Port.WFEmp wfemp = new BP.WF.Port.WFEmp(wl.FK_Emp);
  3161. // wfemp.No = wl.FK_Emp;
  3162. BP.TA.SMS.AddMsg(wl.WorkID + "_" + wl.FK_Node + "_" + wfemp.No, wfemp.No, wfemp.HisAlertWay, wfemp.Tel,
  3163. this.ToEP3("WN27", "流程:{0}.工作:{1},发送人:{2},需您处理",
  3164. this.HisNode.FlowName, wl.FK_NodeText, WebUser.Name),
  3165. wfemp.Email, null, mytemp);
  3166. }
  3167. /*
  3168. string workers="";
  3169. // 工作者
  3170. foreach(WorkerList wl in gwls)
  3171. {
  3172. workers+=","+wl.FK_Emp;
  3173. }
  3174. Watchdog wd =new Watchdog();
  3175. wd.InitDateTime=DataType.CurrentDataTime ;
  3176. wd.WorkID=this.HisWork.OID;
  3177. wd.NodeId =this.HisNode.OID;
  3178. wd.Workers = workers+",";
  3179. wd.FK_Dept =this.HisDeptOfUse.No ;
  3180. wd.FK_Station=this.HisStationOfUse.No;
  3181. wd.Save();
  3182. */
  3183. }
  3184. /// <summary>
  3185. /// 会签节点是否全部完成?
  3186. /// </summary>
  3187. private bool IsOverMGECheckStand = false;
  3188. private bool IsStopFlow = false;
  3189. /// <summary>
  3190. /// 检查流程、节点的完成条件
  3191. /// </summary>
  3192. /// <returns></returns>
  3193. private string CheckCompleteCondition()
  3194. {
  3195. this.IsStopFlow = false;
  3196. // 调用检查全局的工作.
  3197. string msg = this.CheckGlobalCompleteCondition();
  3198. if (msg != null)
  3199. return msg;
  3200. #region 判断节点完成条件
  3201. try
  3202. {
  3203. // 如果没有条件,就说明了,保存为完成节点任务的条件.
  3204. if (this.HisNode.IsCCNode == false)
  3205. {
  3206. msg = string.Format(this.ToE("WN6", "当前工作[{0}]已经完成"), this.HisNode.Name);
  3207. }
  3208. else
  3209. {
  3210. int i = this.HisNodeCompleteConditions.Count;
  3211. if (i == 0)
  3212. {
  3213. this.HisNode.IsCCNode = false;
  3214. this.HisNode.Update();
  3215. }
  3216. if (this.HisNodeCompleteConditions.IsPass)
  3217. {
  3218. if (SystemConfig.IsDebug)
  3219. msg = "@当前工作[" + this.HisNode.Name + "]符合完成条件[" + this.HisNodeCompleteConditions.ConditionDesc + "],已经完成.";
  3220. else
  3221. msg = string.Format(this.ToE("WN6", "当前工作{0}已经完成"), this.HisNode.Name); //"@"; //当前工作[" + this.HisNode.Name + "],已经完成.
  3222. }
  3223. else
  3224. {
  3225. // "@当前工作[" + this.HisNode.Name + "]没有完成,下一步工作不能启动."
  3226. throw new Exception(string.Format(this.ToE("WN7", "@当前工作{0}没有完成,下一步工作不能启动."), this.HisNode.Name));
  3227. }
  3228. }
  3229. }
  3230. catch (Exception ex)
  3231. {
  3232. throw new Exception(string.Format(this.ToE("WN8", "@判断节点{0}完成条件出现错误.") + ex.Message, this.HisNode.Name)); //"@判断节点[" + this.HisNode.Name + "]完成条件出现错误:" + ex.Message;
  3233. }
  3234. #endregion
  3235. #region 判断流程条件.
  3236. try
  3237. {
  3238. if (this.HisNode.HisToNodes.Count == 0 && this.HisNode.IsStartNode)
  3239. {
  3240. /* 如果流程完成 */
  3241. string overMsg = this.HisWorkFlow.DoFlowOver("");
  3242. this.IsStopFlow = true;
  3243. this.AddToTrack(ActionType.FlowOver, WebUser.No, WebUser.Name,
  3244. this.HisNode.NodeID, this.HisNode.Name, "流程结束");
  3245. return "工作已经成功处理(一个流程的工作)。 @查看<img src='./../Images/Btn/PrintWorkRpt.gif' ><a href='WFRpt.aspx?WorkID=" + this.HisWork.OID + "&FID=" + this.HisWork.FID + "&FK_Flow=" + this.HisNode.FK_Flow + "'target='_blank' >工作报告</a>";
  3246. // string path = System.Web.HttpContext.Current.Request.ApplicationPath;
  3247. // return msg + "@符合工作流程完成条件" + this.HisFlowCompleteConditions.ConditionDesc + "" + overMsg + " @查看<img src='./../Images/Btn/PrintWorkRpt.gif' ><a href='WFRpt.aspx?WorkID=" + this.HisWork.OID + "&FID=" + this.HisWork.FID + "&FK_Flow=" + this.HisNode.FK_Flow + "'target='_blank' >工作报告</a>";
  3248. }
  3249. if ((this.HisNode.IsCCFlow && this.HisFlowCompleteConditions.IsPass))
  3250. {
  3251. /* 如果流程完成 */
  3252. string overMsg = this.HisWorkFlow.DoFlowOver("");
  3253. this.IsStopFlow = true;
  3254. this.AddToTrack(ActionType.FlowOver, WebUser.No, WebUser.Name,
  3255. this.HisNode.NodeID, this.HisNode.Name, "流程结束");
  3256. // string path = System.Web.HttpContext.Current.Request.ApplicationPath;
  3257. return msg + "@符合工作流程完成条件" + this.HisFlowCompleteConditions.ConditionDesc + "" + overMsg + " @查看<img src='./../Images/Btn/PrintWorkRpt.gif' ><a href='WFRpt.aspx?WorkID=" + this.HisWork.OID + "&FID=" + this.HisWork.FID + "&FK_Flow=" + this.HisNode.FK_Flow + "'target='_blank' >工作报告</a>";
  3258. }
  3259. }
  3260. catch (Exception ex)
  3261. {
  3262. throw new Exception(string.Format(this.ToE("WN9", "@判断流程{0}完成条件出现错误.") + ex.Message, this.HisNode.Name));
  3263. }
  3264. #endregion
  3265. return msg;
  3266. }
  3267. /// <summary>
  3268. /// 启动新的节点
  3269. /// </summary>
  3270. /// <returns></returns>
  3271. public string StartupNewNodeWork()
  3272. {
  3273. #region 启动下一个节点之前进行必要的判断
  3274. string msg = this.CheckCompleteCondition();
  3275. if (this.IsStopFlow == true)
  3276. {
  3277. /*在检查完后,流程已经停止了。*/
  3278. return msg;
  3279. }
  3280. switch (this.HisNode.HisNodeWorkType)
  3281. {
  3282. case NodeWorkType.WorkHL:
  3283. case NodeWorkType.WorkFHL:
  3284. if (this.HisNode.IsForceKill)
  3285. {
  3286. // 检查是否还有没有完成的进程。
  3287. WorkerLists wls = new WorkerLists();
  3288. wls.Retrieve(WorkerListAttr.FID, this.HisWork.OID,
  3289. WorkerListAttr.IsPass, 0);
  3290. if (wls.Count > 0)
  3291. {
  3292. msg += "@开始进行对没有完成分流工作的同事强制删除。";
  3293. foreach (WorkerList wl in wls)
  3294. {
  3295. WorkFlow wf = new WorkFlow(wl.FK_Flow, wl.WorkID, wl.FID);
  3296. wf.DoDeleteWorkFlowByReal();
  3297. msg += "@已经把(" + wl.FK_Emp + " , " + wl.FK_EmpText + ")的工作删除。";
  3298. }
  3299. }
  3300. }
  3301. else
  3302. {
  3303. DataTable dt = DBAccess.RunSQLReturnTable("SELECT b.No,b.Name FROM WF_GenerWorkerList a,Port_Emp b WHERE a.FK_Emp=b.No AND IsPass=0 AND FID=" + this.HisWork.OID);
  3304. if (dt.Rows.Count != 0)
  3305. {
  3306. int i = BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET FID=0 WHERE FID=WorkID AND WorkID=" + this.WorkID);
  3307. if (i == 1)
  3308. {
  3309. // this.HisWorkFlow.FID = 0;
  3310. }
  3311. dt = DBAccess.RunSQLReturnTable("SELECT b.No,b.Name FROM WF_GenerWorkerList a,Port_Emp b WHERE a.FK_Emp=b.No AND a.IsPass=0 AND a.IsEnable=1 AND FID=" + this.HisWork.OID);
  3312. if (dt.Rows.Count != 0)
  3313. {
  3314. msg = "@执行完成错误,有如下人员没有完成工作。";
  3315. foreach (DataRow dr in dt.Rows)
  3316. {
  3317. msg += "@" + dr[0].ToString() + " - " + dr[1].ToString();
  3318. }
  3319. msg += "@以上每个成员都完成后,才可以执行此操作。";
  3320. throw new Exception(msg);
  3321. }
  3322. }
  3323. }
  3324. break;
  3325. case NodeWorkType.Work:
  3326. case NodeWorkType.StartWork:
  3327. // 合理的结束。
  3328. break;
  3329. case NodeWorkType.SubThreadWork:
  3330. break;
  3331. default:
  3332. break;
  3333. //throw new Exception("@流程设计错误,结束节点的类型不能为:(" + this.HisNode.HisNodeWorkTypeT + ") 类型.");
  3334. }
  3335. #endregion
  3336. // 取当前节点Nodes.
  3337. Nodes toNodes = this.HisNode.HisToNodes;
  3338. if (toNodes.Count == 0)
  3339. {
  3340. /* 如果是最后一个节点,就设置流程结束。*/
  3341. string ovrMsg = this.HisWorkFlow.DoFlowOver("无");
  3342. this.AddToTrack(ActionType.FlowOver, WebUser.No, WebUser.Name,
  3343. this.HisNode.NodeID, this.HisNode.Name, "流程结束");
  3344. if (this.HisNode.HisFormType == FormType.SDKForm)
  3345. return ovrMsg + this.ToE("WN0", "@此工作流程运行到最后一个环节,工作成功结束!");
  3346. else
  3347. return ovrMsg + this.ToE("WN0", "@此工作流程运行到最后一个环节,工作成功结束!") + "<img src='" + this.VirPath + "/Images/Btn/PrintWorkRpt.gif' ><a href='" + this.VirPath + "/WF/WFRpt.aspx?WorkID=" + this.HisWork.OID + "&FID=" + this.HisWork.FID + "&FK_Flow=" + this.HisNode.FK_Flow + "&FK_Node=" + this.HisNode.NodeID + "'target='_blank' >" + this.ToE("WorkRpt", "工作报告") + "</a>";
  3348. }
  3349. // 如果有跳转的节点.
  3350. if (this.JumpToNode != null)
  3351. {
  3352. return msg + StartNextNode(this.JumpToNode);
  3353. }
  3354. // 如果只有一个转向节点, 就不用判断条件了,直接转向他.
  3355. if (toNodes.Count == 1)
  3356. return msg + StartNextNode((Node)toNodes[0]);
  3357. Node toNode = null;
  3358. int numOfWay = 0;
  3359. string condMsg = "";
  3360. Conds dcs = new Conds();
  3361. QueryObject qo = new QueryObject(dcs);
  3362. qo.AddWhere(CondAttr.NodeID, this.HisNode.NodeID);
  3363. qo.addOrderBy(CondAttr.PRI);
  3364. qo.DoQuery();
  3365. foreach (Cond cd in dcs)
  3366. {
  3367. cd.WorkID = this.WorkID;
  3368. foreach (Node nd in toNodes)
  3369. {
  3370. if (cd.ToNodeID != nd.NodeID)
  3371. continue;
  3372. if (cd.IsPassed) // 如果多个转向条件中有一个成立.
  3373. {
  3374. numOfWay++;
  3375. toNode = nd;
  3376. break;
  3377. }
  3378. condMsg += "<b>@检查方向条件:到节点:" + nd.Name + "</b>";
  3379. condMsg += dcs.MsgOfDesc;
  3380. }
  3381. if (toNode != null)
  3382. break;
  3383. }
  3384. if (toNode == null)
  3385. throw new Exception(string.Format(this.ToE("WN11", "@转向条件设置错误,节点名称:{0}, 系统无法投递。"),
  3386. this.HisNode.Name));
  3387. /* 删除曾经在这个步骤上的流程运行数据。
  3388. * 比如说:方向条件,发生了变化后可能产生两个工作上的数据。是为了工作报告上面体现了两个步骤。 */
  3389. foreach (Node nd in toNodes)
  3390. {
  3391. if (nd.NodeID == toNode.NodeID)
  3392. continue;
  3393. // 删除这个工作,因为这个工作的数据不在有用了。
  3394. Work wk = nd.HisWork;
  3395. wk.OID = this.HisWork.OID;
  3396. if (wk.Delete() != 0)
  3397. {
  3398. /* 删除其它附件信息,明细表信息。 */
  3399. #warning 没处理
  3400. }
  3401. }
  3402. msg += StartNextNode(toNode);
  3403. return msg;
  3404. }
  3405. #region 启动审核节点
  3406. /// <summary>
  3407. /// 启动多个节点.
  3408. /// </summary>
  3409. /// <param name="nds"></param>
  3410. /// <returns></returns>
  3411. public string StartNextNode(Nodes nds)
  3412. {
  3413. /* 分流点 */
  3414. foreach (Node nd in nds)
  3415. {
  3416. if (nd.IsHL == true)
  3417. {
  3418. /* 如果其中的一个点到达了合流点,就让它发起合流点。*/
  3419. if (nds.Count != 1)
  3420. {
  3421. throw new Exception("@在遇到混合流程节点发送时错误,你不能同时启动分流与干流。");
  3422. }
  3423. else
  3424. {
  3425. return StartNextNode(nd);
  3426. }
  3427. }
  3428. }
  3429. /*分别启动每个节点的信息.*/
  3430. string msg = "";
  3431. //查询出来上一个节点的附件信息来。
  3432. FrmAttachmentDBs athDBs = new FrmAttachmentDBs("ND" + this.HisNode.NodeID,
  3433. this.WorkID.ToString());
  3434. //查询出来上一个Ele信息来。
  3435. FrmEleDBs eleDBs = new FrmEleDBs("ND" + this.HisNode.NodeID,
  3436. this.WorkID.ToString());
  3437. foreach (Node nd in nds)
  3438. {
  3439. msg += "@"+nd.Name+"工作已经启动,处理工作者:";
  3440. //产生一个工作信息。
  3441. Work wk = nd.HisWork;
  3442. wk.Copy(this.HisWork);
  3443. wk.FID = this.HisWork.OID;
  3444. wk.OID = BP.DA.DBAccess.GenerOID();
  3445. wk.NodeState = NodeState.Init;
  3446. wk.BeforeSave();
  3447. wk.DirectInsert();
  3448. if (athDBs.Count > 0)
  3449. {
  3450. /*说明当前节点有附件数据*/
  3451. int idx = 0;
  3452. foreach (FrmAttachmentDB athDB in athDBs)
  3453. {
  3454. idx++;
  3455. FrmAttachmentDB athDB_N = new FrmAttachmentDB();
  3456. athDB_N.Copy(athDB);
  3457. athDB_N.FK_MapData = "ND" + nd.NodeID;
  3458. athDB_N.MyPK = athDB_N.MyPK.Replace("ND" + this.HisNode.NodeID, "ND" + nd.NodeID);
  3459. athDB_N.FK_FrmAttachment = athDB_N.FK_FrmAttachment.Replace("ND" + this.HisNode.NodeID,
  3460. "ND" + nd.NodeID) + "_" + idx;
  3461. athDB_N.RefPKVal = wk.OID.ToString();
  3462. athDB_N.Insert();
  3463. }
  3464. }
  3465. if (eleDBs.Count > 0)
  3466. {
  3467. /*说明当前节点有附件数据*/
  3468. int idx = 0;
  3469. foreach (FrmEleDB eleDB in eleDBs)
  3470. {
  3471. idx++;
  3472. FrmEleDB eleDB_N = new FrmEleDB();
  3473. eleDB_N.Copy(eleDB);
  3474. eleDB_N.FK_MapData = "ND" + nd.NodeID;
  3475. eleDB_N.Insert();
  3476. }
  3477. }
  3478. //获得它的工作者。
  3479. WorkNode town = new WorkNode(wk, nd);
  3480. WorkerLists gwls = this.GenerWorkerLists(town);
  3481. foreach (WorkerList wl in gwls)
  3482. {
  3483. msg += wl.FK_Emp + "," + wl.FK_EmpText + "、";
  3484. // 产生工作的信息。
  3485. GenerWorkFlow gwf = new GenerWorkFlow();
  3486. gwf.WorkID = wk.OID;
  3487. if (gwf.IsExits)
  3488. continue;
  3489. gwf.FID = this.WorkID;
  3490. #warning 需要修改成标题生成规则
  3491. gwf.Title = this.GenerTitle(this.HisWork);
  3492. gwf.WFState = 0;
  3493. gwf.RDT = DataType.CurrentDataTime;
  3494. gwf.Rec = Web.WebUser.No;
  3495. gwf.RecName = Web.WebUser.Name;
  3496. gwf.FK_Flow = nd.FK_Flow;
  3497. gwf.FlowName = nd.FlowName;
  3498. gwf.FK_FlowSort = this.HisNode.HisFlow.FK_FlowSort;
  3499. gwf.FK_Node = nd.NodeID;
  3500. gwf.NodeName = nd.Name;
  3501. gwf.FK_Dept = wl.FK_Dept;
  3502. gwf.DeptName = wl.FK_DeptT;
  3503. gwf.DirectInsert();
  3504. DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET WorkID=" + wk.OID + ",FID=" + this.WorkID + " WHERE FK_Emp='" + wl.FK_Emp + "' AND WorkID=" + this.WorkID + " AND FK_Node=" + nd.NodeID);
  3505. }
  3506. }
  3507. this.HisWork.NodeState = NodeState.Complete;
  3508. this.HisWork.Update(WorkAttr.NodeState, (int)NodeState.Complete);
  3509. return msg;
  3510. }
  3511. /// <summary>
  3512. /// 启动指定的下一个节点 .
  3513. /// </summary>
  3514. /// <param name="nd">要启动的节点</param>
  3515. public string StartNextNode(Node nd)
  3516. {
  3517. /*如果当前节点是分流,下一个节点是合流,就按普通节点启动它。*/
  3518. if (this.HisNode.IsFL && nd.IsHL)
  3519. return StartNextWorkNodeOrdinary(nd); /* 普通节点 */
  3520. string msg = "";
  3521. try
  3522. {
  3523. switch (nd.HisNodeWorkType)
  3524. {
  3525. case NodeWorkType.WorkHL:
  3526. case NodeWorkType.WorkFHL: // 如果下一个节点是合流节点,或者是分合流节点。
  3527. // 判断当前节点的类型是什么.
  3528. switch (this.HisNode.HisNodeWorkType)
  3529. {
  3530. case NodeWorkType.Work:
  3531. case NodeWorkType.SubThreadWork:
  3532. case NodeWorkType.StartWork: /* 如果当前点是以上类型 */
  3533. if (this.HisWork.FID == 0)
  3534. msg = StartNextWorkNodeHeLiu_WithOutFID(nd); /* 没有流程ID,比如: */
  3535. else
  3536. msg = StartNextWorkNodeHeLiu_WithFID(nd); /* 合流节点, 开始节点是分流节点 */
  3537. break;
  3538. default:
  3539. throw new Exception("@没有判断的情况。");
  3540. }
  3541. msg += "@<a href='" + this.VirPath + this.AppType+"/MyFlowInfo" + Glo.FromPageType + ".aspx?DoType=UnSend&FID=" + this.HisWork.FID + "&WorkID=" + this.WorkID + "&FK_Flow=" + nd.FK_Flow + "'><img src='" + this.VirPath + "/WF/Img/UnDo.gif' border=0/>" + this.ToE("WN22", "撤销本次发送") + "</a>。";
  3542. return msg;
  3543. case NodeWorkType.StartWork:
  3544. case NodeWorkType.StartWorkFL:
  3545. throw new Exception("System Error ");
  3546. break;
  3547. case NodeWorkType.SubThreadWork: // 如果是下一个节点是子线程.
  3548. default:
  3549. return StartNextWorkNodeOrdinary(nd); /* 普通节点 */
  3550. }
  3551. // this.InitEmps(nd);
  3552. }
  3553. catch (Exception ex)
  3554. {
  3555. throw new Exception("@" + this.ToE("StartNextNodeErr", "@启动下一个节点出现错误") + ":" + ex.Message); //启动下一个节点出现错误
  3556. }
  3557. }
  3558. /// <summary>
  3559. /// 在启动下个工作要做的工作。
  3560. /// </summary>
  3561. /// <param name="wk">要启动的工作</param>
  3562. /// <param name="nd">要启动的节点。</param>
  3563. /// <returns>启动的信息</returns>
  3564. private string beforeStartNode(Work wk, Node nd)
  3565. {
  3566. // town.
  3567. WorkNode town = new WorkNode(wk, nd);
  3568. // 初试化他们的工作人员.
  3569. WorkerLists gwls = this.GenerWorkerLists(town);
  3570. //@加入消息集合里。
  3571. this.AddIntoWacthDog(gwls);
  3572. string msg = "";
  3573. msg = this.ToEP3("TaskAutoSendTo", "@任务自动下达给{0}如下{1}位同事,{2}.", this.nextStationName,
  3574. this._RememberMe.NumOfObjs.ToString(), this._RememberMe.EmpsExt); // +" <font color=blue><b>" + this.nextStationName + "</b></font> " + this._RememberMe.NumOfObjs + " :@" + this._RememberMe.EmpsExt;
  3575. if (this._RememberMe.NumOfEmps >= 2)
  3576. {
  3577. if (WebUser.IsWap)
  3578. msg += "<a href=\"" + this.VirPath + "/WF/AllotTask.aspx?WorkID=" + this.WorkID + "&NodeID=" + nd.NodeID + "&FK_Flow=" + nd.FK_Flow + "')\"><img src='./Img/AllotTask.gif' border=0/>" + this.ToE("WN24", "指定特定的同事处理") + "</a>。";
  3579. else
  3580. msg += "<a href=\"javascript:WinOpen('" + this.VirPath + "/WF/AllotTask.aspx?WorkID=" + this.WorkID + "&NodeID=" + nd.NodeID + "&FK_Flow=" + nd.FK_Flow + "')\"><img src='./Img/AllotTask.gif' border=0/>" + this.ToE("WN24", "指定特定的同事处理") + "</a>。";
  3581. }
  3582. msg += this.GenerWhySendToThem(this.HisNode.NodeID, nd.NodeID);
  3583. if (WebUser.IsWap == false)
  3584. msg += "@<a href=\"javascript:WinOpen('" + this.VirPath + "/WF/Msg/SMS.aspx?WorkID=" + this.WorkID + "&FK_Node=" + nd.NodeID + "');\" ><img src='" + this.VirPath + "/WF/Img/SMS.gif' border=0 />" + this.ToE("WN21", "发手机短信提醒他(们)") + "</a>";
  3585. if (this.HisNode.HisFormType != FormType.SDKForm)
  3586. {
  3587. if (this.HisNode.IsStartNode)
  3588. msg += "@<a href='" + this.VirPath + this.AppType + "/MyFlowInfo" + Glo.FromPageType + ".aspx?DoType=UnSend&WorkID=" + wk.OID + "&FK_Flow=" + nd.FK_Flow + "'><img src='" + this.VirPath + "/WF/Img/UnDo.gif' border=0/>" + this.ToE("WN22", "撤销本次发送") + "</a>, <a href='" + this.VirPath + "/" + this.AppType + "/MyFlow" + Glo.FromPageType + ".aspx?FK_Flow=" + nd.FK_Flow + "&FK_Node="+nd.FK_Flow+"01'><img src=" + this.VirPath + "/WF/Img/New.gif border=0/>" + this.ToE("NewFlow", "新建流程") + "</a>。";
  3589. else
  3590. msg += "@<a href='" + this.VirPath + "/" + this.AppType + "/MyFlowInfo" + Glo.FromPageType + ".aspx?DoType=UnSend&WorkID=" + wk.OID + "&FK_Flow=" + nd.FK_Flow + "'><img src='" + this.VirPath + "/WF/Img/UnDo.gif' border=0/>" + this.ToE("WN22", "撤销本次发送") + "</a>。";
  3591. }
  3592. string str = "";
  3593. DBAccess.RunSQL("UPDATE WF_GenerWorkFlow SET FK_Node=" + nd.NodeID + ", NodeName='" + nd.Name + "' WHERE WorkID=" + this.HisWork.OID);
  3594. if (this.HisNode.HisFormType == FormType.SDKForm)
  3595. return msg;
  3596. else
  3597. return msg + "@" + str + " <img src='" + this.VirPath + "/Images/Btn/PrintWorkRpt.gif' ><a href='" + this.VirPath + "/WF/WFRpt.aspx?WorkID=" + wk.OID + "&FID=" + wk.FID + "&FK_Flow=" + nd.FK_Flow + "'target='_blank' >" + this.ToE("WorkRpt", "工作报告") + "</a>。";
  3598. }
  3599. /// <summary>
  3600. /// 生成为什么发送给他们
  3601. /// </summary>
  3602. /// <param name="fNodeID"></param>
  3603. /// <param name="toNodeID"></param>
  3604. /// <returns></returns>
  3605. public string GenerWhySendToThem(int fNodeID, int toNodeID)
  3606. {
  3607. return "";
  3608. //return "@<a href='WhySendToThem.aspx?NodeID=" + fNodeID + "&ToNodeID=" + toNodeID + "&WorkID=" + this.WorkID + "' target=_blank >" + this.ToE("WN20", "为什么要发送给他们?") + "</a>";
  3609. }
  3610. /// <summary>
  3611. /// 工作流程ID
  3612. /// </summary>
  3613. public static Int64 FID = 0;
  3614. /// <summary>
  3615. /// 没有FID
  3616. /// </summary>
  3617. /// <param name="nd"></param>
  3618. /// <returns></returns>
  3619. private string StartNextWorkNodeHeLiu_WithOutFID(Node nd)
  3620. {
  3621. throw new Exception("未完成:StartNextWorkNodeHeLiu_WithOutFID");
  3622. }
  3623. private string StartNextWorkNodeHeLiu_WithFID_YiBu(Node nd)
  3624. {
  3625. GenerFH myfh = new GenerFH(this.HisWork.FID);
  3626. if (myfh.FK_Node == nd.NodeID)
  3627. {
  3628. /* 说明不是第一次到这个节点上来了,
  3629. * 比如:一条流程:
  3630. * A分流-> B普通-> C合流
  3631. * 从B 到C 中, B中有N 个线程,在之前已经有一个线程到达过C.
  3632. */
  3633. /*
  3634. * 首先:更新它的节点 worklist 信息, 说明当前节点已经完成了.
  3635. * 不让当前的操作员能看到自己的工作。
  3636. */
  3637. DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=1 WHERE WorkID=" + this.WorkID + " AND FID=" + this.HisWork.FID + " AND FK_Node=" + this.HisNode.NodeID);
  3638. DBAccess.RunSQL("UPDATE WF_GenerWorkFlow SET FK_Node=" + nd.NodeID + ",NodeName='" + nd.Name + "' WHERE WorkID=" + this.HisWork.OID);
  3639. /*
  3640. * 其次更新当前节点的状态与完成时间.
  3641. */
  3642. this.HisWork.Update(WorkAttr.NodeState, (int)NodeState.Complete,
  3643. WorkAttr.CDT, BP.DA.DataType.CurrentDataTime);
  3644. // 产生合流汇总明细表数据.
  3645. this.GenerHieLiuHuiZhongDtlData(nd);
  3646. #region 处理完成率
  3647. Nodes fromNds = nd.HisFromNodes;
  3648. string nearHLNodes = "";
  3649. foreach (Node mynd in fromNds)
  3650. {
  3651. if (mynd.HisNodeWorkType == NodeWorkType.SubThreadWork)
  3652. nearHLNodes += "," + mynd.NodeID;
  3653. }
  3654. nearHLNodes = nearHLNodes.Substring(1);
  3655. string sqlOK = "SELECT FK_Emp,FK_EmpText FROM WF_GenerWorkerList WHERE FK_Node IN (" + nearHLNodes + ") AND FID=" + this.HisWork.FID + " AND IsPass=1";
  3656. DataTable dt_worker = BP.DA.DBAccess.RunSQLReturnTable(sqlOK);
  3657. string numStr = "@如下分流人员已执行完成:";
  3658. foreach (DataRow dr in dt_worker.Rows)
  3659. numStr += "@" + dr[0] + "," + dr[1];
  3660. decimal ok = (decimal)dt_worker.Rows.Count;
  3661. string sqlAll = "SELECT COUNT(distinct WorkID) AS Num FROM WF_GenerWorkerList WHERE IsEnable=1 AND FID=" + this.HisWork.FID + " AND FK_Node IN (" + this.SpanSubTheadNodes(nd) + ")";
  3662. decimal all = (decimal)DBAccess.RunSQLReturnValInt(sqlAll);
  3663. decimal passRate = ok / all * 100;
  3664. numStr += "@您是第(" + ok + ")到达此节点上的同事,共启动了(" + all + ")个子流程。";
  3665. if (nd.PassRate <= passRate)
  3666. {
  3667. /*说明全部的人员都完成了,就让合流点显示它。*/
  3668. DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=0 WHERE FK_Node=" + nd.NodeID + " AND WorkID=" + this.HisWork.FID);
  3669. numStr += "@下一步工作(" + nd.Name + ")已经启动。";
  3670. }
  3671. #endregion 处理完成率
  3672. string fk_emp1 = myfh.ToEmpsMsg.Substring(0, myfh.ToEmpsMsg.LastIndexOf('<'));
  3673. this.AddToTrack(ActionType.ForwardHL, fk_emp1, myfh.ToEmpsMsg, nd.NodeID, nd.Name, null);
  3674. return "@流程已经运行到合流节点[" + nd.Name + "],当前工作已经完成.@您的工作已经发送给如下人员[" + myfh.ToEmpsMsg + "],<a href=\"javascript:WinOpen('./Msg/SMS.aspx?WorkID=" + this.WorkID + "&FK_Node=" + nd.NodeID + "')\" >短信通知他们</a>。" + this.GenerWhySendToThem(this.HisNode.NodeID, nd.NodeID) + numStr;
  3675. }
  3676. /* 已经有FID,说明:以前已经有分流或者合流节点。*/
  3677. /*
  3678. * 以下处理的是没有流程到达此位置
  3679. * 说明是第一次到这个节点上来了.
  3680. * 比如:一条流程:
  3681. * A分流-> B普通-> C合流
  3682. * 从B 到C 中, B中有N 个线程,在之前他是第一个到达C.
  3683. */
  3684. // 首先找到此节点的接受人员的集合。做为 FID 合流分流的FID。
  3685. WorkNode town = new WorkNode(nd.HisWork, nd);
  3686. // 初试化他们的工作人员.
  3687. WorkerLists gwls = this.GenerWorkerLists_WidthFID(town);
  3688. string fk_emp = "";
  3689. string toEmpsStr = "";
  3690. string emps = "";
  3691. foreach (WorkerList wl in gwls)
  3692. {
  3693. fk_emp = wl.FK_Emp;
  3694. if (Glo.IsShowUserNoOnly)
  3695. toEmpsStr += wl.FK_Emp + "、";
  3696. else
  3697. toEmpsStr += wl.FK_Emp + "<" + wl.FK_EmpText + ">、";
  3698. if (gwls.Count == 1)
  3699. emps = fk_emp;
  3700. else
  3701. emps += "@" + fk_emp;
  3702. }
  3703. /*
  3704. * 更新它的节点 worklist 信息, 说明当前节点已经完成了.
  3705. * 不让当前的操作员能看到自己的工作。
  3706. */
  3707. // 设置父流程状态 设置当前的节点为:
  3708. myfh.Update(GenerFHAttr.FK_Node, nd.NodeID,
  3709. GenerFHAttr.ToEmpsMsg, toEmpsStr);
  3710. #region 处理合流节点表单数据
  3711. Work mainWK = town.HisWork;
  3712. mainWK.OID = this.HisWork.FID;
  3713. if (mainWK.RetrieveFromDBSources() == 1)
  3714. mainWK.Delete();
  3715. #region 复制报表上面的数据到合流点上去
  3716. DataTable dt = DBAccess.RunSQLReturnTable("SELECT * FROM ND" + int.Parse(nd.FK_Flow) + "Rpt WHERE OID=" + this.HisWork.FID);
  3717. foreach (DataColumn dc in dt.Columns)
  3718. mainWK.SetValByKey(dc.ColumnName, dt.Rows[0][dc.ColumnName]);
  3719. mainWK.NodeState = NodeState.Init;
  3720. mainWK.Rec = fk_emp;
  3721. mainWK.Emps = emps;
  3722. mainWK.OID = this.HisWork.FID;
  3723. mainWK.Insert();
  3724. #endregion 复制报表上面的数据到合流点上去
  3725. #region 复制附件
  3726. FrmAttachmentDBs athDBs = new FrmAttachmentDBs("ND" + this.HisNode.NodeID,
  3727. this.WorkID.ToString());
  3728. if (athDBs.Count > 0)
  3729. {
  3730. /*说明当前节点有附件数据*/
  3731. int idx = 0;
  3732. foreach (FrmAttachmentDB athDB in athDBs)
  3733. {
  3734. idx++;
  3735. FrmAttachmentDB athDB_N = new FrmAttachmentDB();
  3736. athDB_N.Copy(athDB);
  3737. athDB_N.FK_MapData = "ND" + nd.NodeID;
  3738. athDB_N.MyPK = athDB_N.MyPK.Replace("ND" + this.HisNode.NodeID, "ND" + nd.NodeID) + "_" + idx;
  3739. athDB_N.FK_FrmAttachment = athDB_N.FK_FrmAttachment.Replace("ND" + this.HisNode.NodeID,
  3740. "ND" + nd.NodeID);
  3741. athDB_N.RefPKVal = this.HisWork.FID.ToString();
  3742. athDB_N.Save();
  3743. }
  3744. }
  3745. #endregion 复制附件
  3746. #region 复制EleDB
  3747. FrmEleDBs eleDBs = new FrmEleDBs("ND" + this.HisNode.NodeID,
  3748. this.WorkID.ToString());
  3749. if (eleDBs.Count > 0)
  3750. {
  3751. /*说明当前节点有附件数据*/
  3752. int idx = 0;
  3753. foreach (FrmEleDB eleDB in eleDBs)
  3754. {
  3755. idx++;
  3756. FrmEleDB eleDB_N = new FrmEleDB();
  3757. eleDB_N.Copy(eleDB);
  3758. eleDB_N.FK_MapData = "ND" + nd.NodeID;
  3759. eleDB_N.MyPK = eleDB_N.MyPK.Replace("ND" + this.HisNode.NodeID, "ND" + nd.NodeID);
  3760. eleDB_N.RefPKVal = this.HisWork.FID.ToString();
  3761. eleDB_N.Save();
  3762. }
  3763. }
  3764. #endregion 复制EleDB
  3765. // 产生合流汇总明细表数据.
  3766. this.GenerHieLiuHuiZhongDtlData(nd);
  3767. #endregion 处理合流节点表单数据
  3768. /* 合流点需要等待各个分流点全部处理完后才能看到它。*/
  3769. string info = "";
  3770. string sql1 = "";
  3771. #warning 对于多个分合流点可能会有问题
  3772. sql1 = "SELECT COUNT(distinct WorkID) AS Num FROM WF_GenerWorkerList WHERE FID=" + this.HisWork.FID + " AND FK_Node IN (" + this.SpanSubTheadNodes(nd) + ")";
  3773. decimal numAll1 = (decimal)DBAccess.RunSQLReturnValInt(sql1);
  3774. decimal passRate1 = 1 / numAll1 * 100;
  3775. if (nd.PassRate <= passRate1)
  3776. {
  3777. DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=0,WorkID=" + this.HisWork.FID + ",FID=0 WHERE FK_Node=" + nd.NodeID + " AND WorkID=" + this.HisWork.OID);
  3778. info = "@下一步合流点("+nd.Name+")已经启动。";
  3779. }
  3780. else
  3781. {
  3782. #warning 为了不让其显示在途的工作需要 =3 不是正常的处理模式
  3783. DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=3,WorkID=" + this.HisWork.FID + ",FID=0 WHERE FK_Node=" + nd.NodeID + " AND WorkID=" + this.HisWork.OID);
  3784. }
  3785. DBAccess.RunSQL("UPDATE WF_GenerWorkFlow SET FK_Node=" + nd.NodeID + ",NodeName='" + nd.Name + "' WHERE WorkID=" + this.HisWork.FID);
  3786. return "@当前工作已经完成,流程已经运行到合流节点[" + nd.Name + "]。@您的工作已经发送给如下人员[" + toEmpsStr + "],<a href=\"javascript:WinOpen('" + this.VirPath + "/WF/Msg/SMS.aspx?WorkID=" + this.WorkID + "&FK_Node=" + nd.NodeID + "')\" >短信通知他们</a>。" + "@您是第一个到达此节点的同事."+info;
  3787. }
  3788. /// <summary>
  3789. /// 产生合流汇总数据
  3790. /// </summary>
  3791. /// <param name="nd"></param>
  3792. private void GenerHieLiuHuiZhongDtlData(Node ndOfHeLiu)
  3793. {
  3794. MapDtls mydtls = ndOfHeLiu.HisWork.HisMapDtls;
  3795. foreach (MapDtl dtl in mydtls)
  3796. {
  3797. if (dtl.IsHLDtl == false)
  3798. continue;
  3799. GEDtl geDtl = dtl.HisGEDtl;
  3800. geDtl.Copy(this.HisWork);
  3801. geDtl.RefPK = this.HisWork.FID.ToString();
  3802. geDtl.Rec = WebUser.No;
  3803. geDtl.RDT = DataType.CurrentDataTime;
  3804. try
  3805. {
  3806. geDtl.InsertAsOID(geDtl.OID);
  3807. }
  3808. catch
  3809. {
  3810. geDtl.Update();
  3811. }
  3812. break;
  3813. }
  3814. }
  3815. /// <summary>
  3816. /// 子线程节点
  3817. /// </summary>
  3818. private string _SpanSubTheadNodes = null;
  3819. /// <summary>
  3820. /// 获取分流与合流之间的子线程节点集合.
  3821. /// </summary>
  3822. /// <param name="toNode"></param>
  3823. /// <returns></returns>
  3824. private string SpanSubTheadNodes(Node toHLNode)
  3825. {
  3826. _SpanSubTheadNodes = "";
  3827. SpanSubTheadNodes_DG(toHLNode.HisFromNodes);
  3828. if (_SpanSubTheadNodes == "")
  3829. throw new Exception("获取分合流之间的子线程节点集合出现错。");
  3830. _SpanSubTheadNodes = _SpanSubTheadNodes.Substring(1);
  3831. return _SpanSubTheadNodes;
  3832. //DataTable dt = DBAccess.RunSQLReturnTable("SELECT * FROM WF_GenerWorkerlist WHERE FID=" + this.HisWork.FID + " AND FK_Node IN (" + _SpanSubTheadNodes + ") ");
  3833. //_SpanSubTheadNodes = "";
  3834. //foreach (DataRow dr in dt.Rows)
  3835. //{
  3836. // _SpanSubTheadNodes += "," + dr["FK_Node"].ToString();
  3837. //}
  3838. //_SpanSubTheadNodes = _SpanSubTheadNodes.Substring(1);
  3839. //return _SpanSubTheadNodes;
  3840. }
  3841. private void SpanSubTheadNodes_DG(Nodes subNDs)
  3842. {
  3843. foreach (Node nd in subNDs)
  3844. {
  3845. if (nd.IsFL == true)
  3846. continue;
  3847. if (nd.HisNodeWorkType == NodeWorkType.SubThreadWork)
  3848. _SpanSubTheadNodes += "," + nd.NodeID;
  3849. SpanSubTheadNodes_DG(nd.HisFromNodes);
  3850. }
  3851. }
  3852. /// <summary>
  3853. /// 有FID
  3854. /// </summary>
  3855. /// <param name="nd"></param>
  3856. /// <returns></returns>
  3857. private string StartNextWorkNodeHeLiu_WithFID(Node nd)
  3858. {
  3859. //设置已经通过.
  3860. DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=1 WHERE WorkID=" + this.WorkID + " AND FID=" + this.HisWork.FID );
  3861. string spanNodes = this.SpanSubTheadNodes(nd);
  3862. if (nd.HisFromNodes.Count != 1)
  3863. {
  3864. return StartNextWorkNodeHeLiu_WithFID_YiBu(nd);
  3865. }
  3866. GenerFH myfh = new GenerFH(this.HisWork.FID);
  3867. if (myfh.FK_Node == nd.NodeID)
  3868. {
  3869. /* 说明不是第一次到这个节点上来了,
  3870. * 比如:一条流程:
  3871. * A分流-> B普通-> C合流
  3872. * 从B 到C 中, B中有N 个线程,在之前已经有一个线程到达过C.
  3873. */
  3874. /*
  3875. * 首先:更新它的节点 worklist 信息, 说明当前节点已经完成了.
  3876. * 不让当前的操作员能看到自己的工作。
  3877. */
  3878. DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=1 WHERE WorkID=" + this.WorkID + " AND FID=" + this.HisWork.FID + " AND FK_Node=" + this.HisNode.NodeID);
  3879. DBAccess.RunSQL("UPDATE WF_GenerWorkFlow SET FK_Node=" + nd.NodeID + ",NodeName='" + nd.Name + "' WHERE WorkID=" + this.HisWork.OID);
  3880. /*
  3881. * 其次更新当前节点的状态与完成时间.
  3882. */
  3883. this.HisWork.Update(WorkAttr.NodeState, (int)NodeState.Complete,
  3884. WorkAttr.CDT, BP.DA.DataType.CurrentDataTime);
  3885. #region 处理完成率
  3886. string sqlOK = "SELECT FK_Emp,FK_EmpText FROM WF_GenerWorkerList WHERE FK_Node=" + this.HisNode.NodeID + " AND FID=" + this.HisWork.FID + " AND IsPass=1";
  3887. DataTable dt_worker = BP.DA.DBAccess.RunSQLReturnTable(sqlOK);
  3888. string numStr = "@如下分流人员已执行完成:";
  3889. foreach (DataRow dr in dt_worker.Rows)
  3890. numStr += "@" + dr[0] + "," + dr[1];
  3891. decimal ok = (decimal)dt_worker.Rows.Count;
  3892. string sql = "SELECT COUNT(distinct WorkID) AS Num FROM WF_GenerWorkerList WHERE IsEnable=1 AND FID=" + this.HisWork.FID + " AND FK_Node IN (" + spanNodes + ")";
  3893. decimal all = (decimal)DBAccess.RunSQLReturnValInt(sql);
  3894. decimal passRate = ok / all * 100;
  3895. numStr = "@您是第(" + ok + ")到达此节点上的同事,共启动了(" + all + ")个子流程。";
  3896. if (nd.PassRate <= passRate)
  3897. {
  3898. /*说明全部的人员都完成了,就让合流点显示它。*/
  3899. DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=0 WHERE FK_Node=" + nd.NodeID + " AND WorkID=" + this.HisWork.FID);
  3900. numStr += "@下一步工作(" + nd.Name + ")已经启动。";
  3901. }
  3902. #endregion 处理完成率
  3903. // 产生合流汇总明细表数据.
  3904. this.GenerHieLiuHuiZhongDtlData(nd);
  3905. string fk_emp1 = myfh.ToEmpsMsg.Substring(0, myfh.ToEmpsMsg.LastIndexOf('<'));
  3906. this.AddToTrack(ActionType.ForwardHL, fk_emp1, myfh.ToEmpsMsg, nd.NodeID, nd.Name, null);
  3907. return "@流程已经运行到合流节点[" + nd.Name + "],当前工作已经完成.@您的工作已经发送给如下人员[" + myfh.ToEmpsMsg + "],<a href=\"javascript:WinOpen('./Msg/SMS.aspx?WorkID=" + this.WorkID + "&FK_Node=" + nd.NodeID + "')\" >短信通知他们</a>。" + this.GenerWhySendToThem(this.HisNode.NodeID, nd.NodeID) + numStr;
  3908. }
  3909. /* 已经有FID,说明:以前已经有分流或者合流节点。*/
  3910. /*
  3911. * 以下处理的是没有流程到达此位置
  3912. * 说明是第一次到这个节点上来了.
  3913. * 比如:一条流程:
  3914. * A分流-> B普通-> C合流
  3915. * 从B 到C 中, B中有N 个线程,在之前他是第一个到达C.
  3916. */
  3917. // 首先找到此节点的接受人员的集合。做为 FID 合流分流的FID。
  3918. WorkNode town = new WorkNode(nd.HisWork, nd);
  3919. // 初试化他们的工作人员.
  3920. WorkerLists gwls = this.GenerWorkerLists_WidthFID(town);
  3921. string fk_emp = "";
  3922. string toEmpsStr = "";
  3923. string emps = "";
  3924. foreach (WorkerList wl in gwls)
  3925. {
  3926. fk_emp = wl.FK_Emp;
  3927. if (Glo.IsShowUserNoOnly)
  3928. toEmpsStr += wl.FK_Emp + "、";
  3929. else
  3930. toEmpsStr += wl.FK_Emp + "<" + wl.FK_EmpText + ">、";
  3931. if (gwls.Count == 1)
  3932. emps = fk_emp;
  3933. else
  3934. emps += "@" + fk_emp;
  3935. }
  3936. /*
  3937. * 更新它的节点 worklist 信息, 说明当前节点已经完成了.
  3938. * 不让当前的操作员能看到自己的工作。
  3939. */
  3940. #region 设置父流程状态 设置当前的节点为:
  3941. myfh.Update(GenerFHAttr.FK_Node, nd.NodeID,
  3942. GenerFHAttr.ToEmpsMsg, toEmpsStr);
  3943. Work mainWK = town.HisWork;
  3944. mainWK.OID = this.HisWork.FID;
  3945. if (mainWK.RetrieveFromDBSources() == 1)
  3946. mainWK.Delete();
  3947. // 复制报表上面的数据到合流点上去。
  3948. DataTable dt = DBAccess.RunSQLReturnTable("SELECT * FROM ND" + int.Parse(nd.FK_Flow) + "Rpt WHERE OID=" + this.HisWork.FID);
  3949. foreach (DataColumn dc in dt.Columns)
  3950. mainWK.SetValByKey(dc.ColumnName, dt.Rows[0][dc.ColumnName]);
  3951. mainWK.NodeState = NodeState.Init;
  3952. mainWK.Rec = fk_emp;
  3953. mainWK.Emps = emps;
  3954. mainWK.OID = this.HisWork.FID;
  3955. mainWK.Insert();
  3956. // 产生合流汇总明细表数据.
  3957. this.GenerHieLiuHuiZhongDtlData(nd);
  3958. /*处理表单数据的复制。*/
  3959. #region 复制附件
  3960. FrmAttachmentDBs athDBs = new FrmAttachmentDBs("ND" + this.HisNode.NodeID,
  3961. this.WorkID.ToString());
  3962. if (athDBs.Count > 0)
  3963. {
  3964. /*说明当前节点有附件数据*/
  3965. int idx = 0;
  3966. foreach (FrmAttachmentDB athDB in athDBs)
  3967. {
  3968. idx++;
  3969. FrmAttachmentDB athDB_N = new FrmAttachmentDB();
  3970. athDB_N.Copy(athDB);
  3971. athDB_N.FK_MapData = "ND" + nd.NodeID;
  3972. athDB_N.MyPK = athDB_N.MyPK.Replace("ND" + this.HisNode.NodeID, "ND" + nd.NodeID) + "_" + idx;
  3973. athDB_N.FK_FrmAttachment = athDB_N.FK_FrmAttachment.Replace("ND" + this.HisNode.NodeID,
  3974. "ND" + nd.NodeID);
  3975. athDB_N.RefPKVal = this.HisWork.FID.ToString();
  3976. athDB_N.Save();
  3977. }
  3978. }
  3979. #endregion 复制附件
  3980. #region 复制Ele
  3981. FrmEleDBs eleDBs = new FrmEleDBs("ND" + this.HisNode.NodeID,
  3982. this.WorkID.ToString());
  3983. if (eleDBs.Count > 0)
  3984. {
  3985. /*说明当前节点有附件数据*/
  3986. int idx = 0;
  3987. foreach (FrmEleDB eleDB in eleDBs)
  3988. {
  3989. idx++;
  3990. FrmEleDB eleDB_N = new FrmEleDB();
  3991. eleDB_N.Copy(eleDB);
  3992. eleDB_N.FK_MapData = "ND" + nd.NodeID;
  3993. eleDB_N.MyPK = eleDB_N.MyPK.Replace("ND" + this.HisNode.NodeID, "ND" + nd.NodeID);
  3994. eleDB_N.RefPKVal = this.HisWork.FID.ToString();
  3995. eleDB_N.Save();
  3996. }
  3997. }
  3998. #endregion 复制附件
  3999. /* 合流点需要等待各个分流点全部处理完后才能看到它。*/
  4000. string sql1 = "";
  4001. // "SELECT COUNT(*) AS Num FROM WF_GenerWorkerList WHERE FK_Node=" + this.HisNode.NodeID + " AND FID=" + this.HisWork.FID;
  4002. // string sql1 = "SELECT COUNT(*) AS Num FROM WF_GenerWorkerList WHERE IsPass=0 AND FID=" + this.HisWork.FID;
  4003. #warning 对于多个分合流点可能会有问题
  4004. sql1 = "SELECT COUNT(distinct WorkID) AS Num FROM WF_GenerWorkerList WHERE FID=" + this.HisWork.FID + " AND FK_Node IN (" + spanNodes + ")";
  4005. decimal numAll1 = (decimal)DBAccess.RunSQLReturnValInt(sql1);
  4006. decimal passRate1 = 1 / numAll1 * 100;
  4007. if (nd.PassRate <= passRate1)
  4008. {
  4009. DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=0,WorkID=" + this.HisWork.FID + ",FID=0 WHERE FK_Node=" + nd.NodeID + " AND WorkID=" + this.HisWork.OID);
  4010. }
  4011. else
  4012. {
  4013. #warning 为了不让其显示在途的工作需要 =3 不是正常的处理模式
  4014. DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=3,WorkID=" + this.HisWork.FID + ",FID=0 WHERE FK_Node=" + nd.NodeID + " AND WorkID=" + this.HisWork.OID);
  4015. }
  4016. DBAccess.RunSQL("UPDATE WF_GenerWorkFlow SET FK_Node=" + nd.NodeID + ",NodeName='" + nd.Name + "' WHERE WorkID=" + this.HisWork.FID);
  4017. #endregion 设置父流程状态
  4018. return "@当前工作已经完成,流程已经运行到合流节点[" + nd.Name + "]。@您的工作已经发送给如下人员[" + toEmpsStr + "],<a href=\"javascript:WinOpen('" + this.VirPath + "/WF/Msg/SMS.aspx?WorkID=" + this.WorkID + "&FK_Node=" + nd.NodeID + "')\" >短信通知他们</a>。" + "@您是第一个到达此节点的同事.";
  4019. }
  4020. /// <summary>
  4021. /// 启动下一个工作节点
  4022. /// </summary>
  4023. /// <param name="nd">节点</param>
  4024. /// <returns></returns>
  4025. private string StartNextWorkNodeOrdinary(Node nd)
  4026. {
  4027. string sql = "";
  4028. try
  4029. {
  4030. #region 初始化发起的工作节点
  4031. Work wk = nd.HisWork;
  4032. wk.SetValByKey("OID", this.HisWork.OID); //设定它的ID.
  4033. if (this.HisNode.IsStartNode == false)
  4034. wk.Copy(this.rptGe);
  4035. wk.FID = 0;
  4036. wk.Copy(this.HisWork); // 执行 copy 上一个节点的数据。
  4037. wk.NodeState = NodeState.Init; //节点状态。
  4038. wk.Rec = BP.Web.WebUser.No;
  4039. try
  4040. {
  4041. //判断是不是MD5流程?
  4042. if (this.HisFlow.IsMD5)
  4043. wk.SetValByKey("MD5", Glo.GenerMD5(wk));
  4044. wk.Insert();
  4045. }
  4046. catch (Exception ex)
  4047. {
  4048. wk.CheckPhysicsTable();
  4049. try
  4050. {
  4051. wk.Update();
  4052. }
  4053. catch (Exception ex11)
  4054. {
  4055. throw new Exception(ex.Message + " == " + ex11.Message);
  4056. }
  4057. }
  4058. #region 复制附件
  4059. FrmAttachmentDBs athDBs = new FrmAttachmentDBs("ND" + this.HisNode.NodeID,
  4060. this.WorkID.ToString());
  4061. int idx = 0;
  4062. if (athDBs.Count > 0)
  4063. {
  4064. athDBs.Delete(FrmAttachmentDBAttr.FK_MapData, "ND" + nd.NodeID,
  4065. FrmAttachmentDBAttr.RefPKVal, this.WorkID);
  4066. /*说明当前节点有附件数据*/
  4067. foreach (FrmAttachmentDB athDB in athDBs)
  4068. {
  4069. idx++;
  4070. FrmAttachmentDB athDB_N = new FrmAttachmentDB();
  4071. athDB_N.Copy(athDB);
  4072. athDB_N.FK_MapData = "ND" + nd.NodeID;
  4073. athDB_N.RefPKVal = this.WorkID.ToString();
  4074. athDB_N.MyPK = this.WorkID + "_" + idx + "_" + athDB_N.FK_MapData;
  4075. athDB_N.FK_FrmAttachment = athDB_N.FK_FrmAttachment.Replace("ND" + this.HisNode.NodeID,
  4076. "ND" + nd.NodeID);
  4077. athDB_N.Save();
  4078. }
  4079. }
  4080. #endregion 复制附件
  4081. #region 复制Ele
  4082. FrmEleDBs eleDBs = new FrmEleDBs("ND" + this.HisNode.NodeID,
  4083. this.WorkID.ToString());
  4084. if (eleDBs.Count > 0)
  4085. {
  4086. eleDBs.Delete(FrmEleDBAttr.FK_MapData, "ND" + nd.NodeID,
  4087. FrmEleDBAttr.RefPKVal, this.WorkID);
  4088. /*说明当前节点有附件数据*/
  4089. foreach (FrmEleDB eleDB in eleDBs)
  4090. {
  4091. idx++;
  4092. FrmEleDB eleDB_N = new FrmEleDB();
  4093. eleDB_N.Copy(eleDB);
  4094. eleDB_N.FK_MapData = "ND" + nd.NodeID;
  4095. eleDB_N.GenerPKVal();
  4096. eleDB_N.Save();
  4097. }
  4098. }
  4099. #endregion 复制Ele
  4100. #region 复制多选数据
  4101. M2Ms m2ms = new M2Ms("ND"+this.HisNode.NodeID, this.WorkID);
  4102. if (m2ms.Count >= 1)
  4103. {
  4104. foreach (M2M item in m2ms)
  4105. {
  4106. M2M m2 = new M2M();
  4107. m2.Copy(item);
  4108. m2.EnOID = this.WorkID;
  4109. m2.FK_MapData = m2.FK_MapData.Replace("ND" + this.HisNode.NodeID, "ND" + nd.NodeID);
  4110. m2.InitMyPK();
  4111. try
  4112. {
  4113. m2.DirectInsert();
  4114. }
  4115. catch
  4116. {
  4117. m2.DirectUpdate();
  4118. }
  4119. }
  4120. }
  4121. #endregion
  4122. #region 复制明细数据
  4123. Sys.MapDtls dtls = new BP.Sys.MapDtls("ND" + this.HisNode.NodeID);
  4124. if (dtls.Count >= 1)
  4125. {
  4126. Sys.MapDtls toDtls = new BP.Sys.MapDtls("ND" + nd.NodeID);
  4127. Sys.MapDtls startDtls = null;
  4128. bool isEnablePass = false;
  4129. foreach (MapDtl dtl in dtls)
  4130. {
  4131. if (dtl.IsEnablePass)
  4132. isEnablePass = true;
  4133. }
  4134. if (isEnablePass)
  4135. startDtls = new BP.Sys.MapDtls("ND" + int.Parse(nd.FK_Flow) + "01");
  4136. int i = -1;
  4137. foreach (Sys.MapDtl dtl in dtls)
  4138. {
  4139. i++;
  4140. if (toDtls.Count <= i)
  4141. continue;
  4142. Sys.MapDtl toDtl = (Sys.MapDtl)toDtls[i];
  4143. if (dtl.IsEnablePass == true)
  4144. {
  4145. /*如果启用了是否明细表的审核通过机制,就允许copy节点数据。*/
  4146. toDtl.IsCopyNDData = true;
  4147. }
  4148. if (toDtl.IsCopyNDData == false)
  4149. continue;
  4150. //获取明细数据。
  4151. GEDtls gedtls = new GEDtls(dtl.No);
  4152. QueryObject qo = null;
  4153. qo = new QueryObject(gedtls);
  4154. switch (dtl.DtlOpenType)
  4155. {
  4156. case DtlOpenType.ForEmp:
  4157. qo.AddWhere(GEDtlAttr.RefPK, this.WorkID);
  4158. //qo.addAnd();
  4159. //qo.AddWhere(GEDtlAttr.Rec, WebUser.No);
  4160. break;
  4161. case DtlOpenType.ForWorkID:
  4162. qo.AddWhere(GEDtlAttr.RefPK, this.WorkID);
  4163. break;
  4164. case DtlOpenType.ForFID:
  4165. qo.AddWhere(GEDtlAttr.FID, this.WorkID);
  4166. break;
  4167. }
  4168. qo.DoQuery();
  4169. int unPass = 0;
  4170. // 是否起用审核机制。
  4171. isEnablePass = dtl.IsEnablePass;
  4172. if (isEnablePass && this.HisNode.IsStartNode == false)
  4173. isEnablePass = true;
  4174. else
  4175. isEnablePass = false;
  4176. if (isEnablePass == true)
  4177. {
  4178. /*判断当前节点该明细表上是否有,isPass 审核字段,如果没有抛出异常信息。*/
  4179. if (gedtls.Count != 0)
  4180. {
  4181. GEDtl dtl1 = gedtls[0] as GEDtl;
  4182. if (dtl1.EnMap.Attrs.Contains("IsPass") == false)
  4183. isEnablePass = false;
  4184. }
  4185. }
  4186. DBAccess.RunSQL("DELETE " + toDtl.PTable + " WHERE RefPK=" + this.WorkID);
  4187. foreach (GEDtl gedtl in gedtls)
  4188. {
  4189. if (isEnablePass)
  4190. {
  4191. if (gedtl.GetValBooleanByKey("IsPass") == false)
  4192. {
  4193. /*没有审核通过的就 continue 它们,仅复制已经审批通过的.*/
  4194. continue;
  4195. }
  4196. }
  4197. BP.Sys.GEDtl dtCopy = new GEDtl(toDtl.No);
  4198. dtCopy.Copy(gedtl);
  4199. dtCopy.FK_MapDtl = toDtl.No;
  4200. dtCopy.RefPK = this.WorkID.ToString();
  4201. dtCopy.InsertAsOID(dtCopy.OID);
  4202. #region 复制明细表单条 - 附件信息
  4203. if (toDtl.IsEnableAthM)
  4204. {
  4205. /*如果启用了多附件,就复制这条明细数据的附件信息。*/
  4206. athDBs = new FrmAttachmentDBs(dtl.No, gedtl.OID.ToString());
  4207. if (athDBs.Count > 0)
  4208. {
  4209. i = 0;
  4210. foreach (FrmAttachmentDB athDB in athDBs)
  4211. {
  4212. i++;
  4213. FrmAttachmentDB athDB_N = new FrmAttachmentDB();
  4214. athDB_N.Copy(athDB);
  4215. athDB_N.FK_MapData = toDtl.No;
  4216. athDB_N.MyPK = toDtl.No + "_" + dtCopy.OID + "_" + i.ToString();
  4217. athDB_N.FK_FrmAttachment = athDB_N.FK_FrmAttachment.Replace("ND" + this.HisNode.NodeID,
  4218. "ND" + nd.NodeID);
  4219. athDB_N.RefPKVal = dtCopy.OID.ToString();
  4220. athDB_N.DirectInsert();
  4221. }
  4222. }
  4223. }
  4224. if (toDtl.IsEnableM2M || toDtl.IsEnableM2MM)
  4225. {
  4226. /*如果启用了m2m */
  4227. m2ms = new M2Ms(dtl.No, gedtl.OID);
  4228. if (m2ms.Count > 0)
  4229. {
  4230. i = 0;
  4231. foreach (M2M m2m in m2ms)
  4232. {
  4233. i++;
  4234. M2M m2m_N = new M2M();
  4235. m2m_N.Copy(m2m);
  4236. m2m_N.FK_MapData = toDtl.No;
  4237. m2m_N.MyPK = toDtl.No + "_" + m2m.M2MNo + "_" + gedtl.ToString() + "_" + m2m.DtlObj;
  4238. m2m_N.EnOID = gedtl.OID;
  4239. m2m.InitMyPK();
  4240. m2m_N.DirectInsert();
  4241. }
  4242. }
  4243. }
  4244. #endregion 复制明细表单条 - 附件信息
  4245. }
  4246. if (isEnablePass)
  4247. {
  4248. /* 如果启用了审核通过机制,就把未审核的数据copy到第一个节点上去
  4249. * 1, 找到对应的明细点.
  4250. * 2, 把未审核通过的数据复制到开始明细表里.
  4251. */
  4252. string startTable = "ND" + int.Parse(nd.FK_Flow) + "01";
  4253. string startUser = "SELECT Rec FROM " + startTable + " WHERE OID=" + this.WorkID;
  4254. startUser = DBAccess.RunSQLReturnString(startUser);
  4255. MapDtl startDtl = (MapDtl)startDtls[i];
  4256. foreach (GEDtl gedtl in gedtls)
  4257. {
  4258. if (gedtl.GetValBooleanByKey("IsPass"))
  4259. continue; /* 排除审核通过的 */
  4260. BP.Sys.GEDtl dtCopy = new GEDtl(startDtl.No);
  4261. dtCopy.Copy(gedtl);
  4262. dtCopy.OID = 0;
  4263. dtCopy.FK_MapDtl = startDtl.No;
  4264. dtCopy.RefPK = gedtl.OID.ToString(); //this.WorkID.ToString();
  4265. dtCopy.SetValByKey("BatchID", this.WorkID);
  4266. dtCopy.SetValByKey("IsPass", 0);
  4267. dtCopy.SetValByKey("Rec", startUser);
  4268. dtCopy.SetValByKey("Checker", BP.Web.WebUser.Name);
  4269. dtCopy.SaveAsOID(gedtl.OID);
  4270. }
  4271. DBAccess.RunSQL("UPDATE " + startDtl.PTable + " SET Rec='" + startUser + "',Checker='" + WebUser.No + "' WHERE BatchID=" + this.WorkID + " AND Rec='" + WebUser.No + "'");
  4272. }
  4273. }
  4274. }
  4275. #endregion 复制明细数据
  4276. // wk.CopyCellsData("ND" + this.HisNode.NodeID + "_" + this.HisWork.OID);
  4277. #endregion
  4278. try
  4279. {
  4280. wk.BeforeSave();
  4281. }
  4282. catch
  4283. {
  4284. }
  4285. try
  4286. {
  4287. wk.DirectSave();
  4288. }
  4289. catch
  4290. {
  4291. #region 解决工作节点字段修复问题
  4292. try
  4293. {
  4294. wk.CheckPhysicsTable();
  4295. wk.DirectSave();
  4296. }
  4297. catch (Exception ex)
  4298. {
  4299. Log.DebugWriteInfo(this.ToE("SaveWorkErr", "保存工作错误") + ":" + ex.Message);
  4300. throw new Exception(this.ToE("SaveWorkErr", "保存工作错误 ") + wk.EnDesc + ex.Message);
  4301. }
  4302. #endregion 解决字段修复问题
  4303. }
  4304. // 启动一个工作节点.
  4305. string msg = this.beforeStartNode(wk, nd);
  4306. return "@" + string.Format(this.ToE("NStep", "@第{0}步"), nd.Step.ToString()) + "<font color=blue>" + nd.Name + "</font>" + this.ToE("WorkStartOK", "工作成功启动") + "." + msg;
  4307. }
  4308. catch (Exception ex)
  4309. {
  4310. nd.HisWorks.DoDBCheck(DBLevel.Middle);
  4311. throw new Exception(string.Format("StartGEWorkErr", nd.Name) + "@" + ex.Message + sql);
  4312. }
  4313. }
  4314. #endregion
  4315. #region 基本属性
  4316. /// <summary>
  4317. /// 工作
  4318. /// </summary>
  4319. private Work _HisWork = null;
  4320. /// <summary>
  4321. /// 工作
  4322. /// </summary>
  4323. public Work HisWork
  4324. {
  4325. get
  4326. {
  4327. return this._HisWork;
  4328. }
  4329. }
  4330. /// <summary>
  4331. /// 节点
  4332. /// </summary>
  4333. private Node _HisNode = null;
  4334. /// <summary>
  4335. /// 节点
  4336. /// </summary>
  4337. public Node HisNode
  4338. {
  4339. get
  4340. {
  4341. return this._HisNode;
  4342. }
  4343. }
  4344. private RememberMe _RememberMe = null;
  4345. public RememberMe GetHisRememberMe(Node nd)
  4346. {
  4347. if (_RememberMe == null || _RememberMe.FK_Node != nd.NodeID)
  4348. {
  4349. _RememberMe = new RememberMe();
  4350. _RememberMe.FK_Emp = Web.WebUser.No;
  4351. _RememberMe.FK_Node = nd.NodeID;
  4352. _RememberMe.RetrieveFromDBSources();
  4353. }
  4354. return this._RememberMe;
  4355. }
  4356. private WorkFlow _HisWorkFlow = null;
  4357. /// <summary>
  4358. /// 工作流程
  4359. /// </summary>
  4360. public WorkFlow HisWorkFlow
  4361. {
  4362. get
  4363. {
  4364. if (_HisWorkFlow == null)
  4365. _HisWorkFlow = new WorkFlow(this.HisNode.HisFlow, this.HisWork.OID, this.HisWork.FID);
  4366. return _HisWorkFlow;
  4367. }
  4368. }
  4369. /// <summary>
  4370. /// 当前节点的工作是不是完成。
  4371. /// </summary>
  4372. public bool IsComplete
  4373. {
  4374. get
  4375. {
  4376. if (this.HisWork.NodeState == NodeState.Complete)
  4377. return true;
  4378. else
  4379. return false;
  4380. }
  4381. }
  4382. #endregion
  4383. #region 构造方法
  4384. /// <summary>
  4385. /// 建立一个工作节点事例.
  4386. /// </summary>
  4387. /// <param name="workId">工作ID</param>
  4388. /// <param name="nodeId">节点ID</param>
  4389. public WorkNode(Int64 workId, int nodeId)
  4390. {
  4391. this.WorkID = workId;
  4392. Node nd = new Node(nodeId);
  4393. Work wk = nd.HisWork;
  4394. wk.OID = workId;
  4395. wk.Retrieve();
  4396. this._HisWork = wk;
  4397. this._HisNode = nd;
  4398. }
  4399. /// <summary>
  4400. /// 建立一个工作节点事例
  4401. /// </summary>
  4402. /// <param name="nd">节点ID</param>
  4403. /// <param name="wk">工作</param>
  4404. public WorkNode(Work wk, Node nd)
  4405. {
  4406. this.WorkID = wk.OID;
  4407. //Node nd = new Node(ndId);
  4408. // if (nd.HisWorks.GetNewEntity.ToString() != wk.ToString())
  4409. // throw new Exception("@创建工作接点失败:定义节点[" + nd.Name + "]采集信息存放的实体[" + nd.WorksEnsName + "],与数据实体[" + wk.ToString() + "]不一致.");
  4410. this._HisWork = wk;
  4411. this._HisNode = nd;
  4412. }
  4413. #endregion
  4414. #region 运算属性
  4415. private void Repair()
  4416. {
  4417. }
  4418. public WorkNode GetPreviousWorkNode_FHL(Int64 workid)
  4419. {
  4420. WorkNodes wns = this.GetPreviousWorkNodes_FHL();
  4421. foreach (WorkNode wn in wns)
  4422. {
  4423. if (wn.HisWork.OID == workid)
  4424. return wn;
  4425. }
  4426. return null;
  4427. }
  4428. public WorkNodes GetPreviousWorkNodes_FHL()
  4429. {
  4430. // 如果没有找到转向他的节点,就返回,当前的工作.
  4431. if (this.HisNode.IsStartNode)
  4432. throw new Exception("@" + this.ToE("WN14", "此节点是开始节点,没有上一步工作")); //此节点是开始节点,没有上一步工作.
  4433. if (this.HisNode.HisNodeWorkType == NodeWorkType.WorkHL
  4434. || this.HisNode.HisNodeWorkType == NodeWorkType.WorkFHL)
  4435. {
  4436. }
  4437. else
  4438. {
  4439. throw new Exception("@当前工作节 - 非是分合流节点。");
  4440. }
  4441. WorkNodes wns = new WorkNodes();
  4442. Nodes nds = this.HisNode.HisFromNodes;
  4443. foreach (Node nd in nds)
  4444. {
  4445. Works wks = (Works)nd.HisWorks;
  4446. wks.Retrieve(WorkAttr.FID, this.HisWork.OID);
  4447. if (wks.Count == 0)
  4448. continue;
  4449. foreach (Work wk in wks)
  4450. {
  4451. WorkNode wn = new WorkNode(wk, nd);
  4452. wns.Add(wn);
  4453. }
  4454. }
  4455. return wns;
  4456. }
  4457. /// <summary>
  4458. /// 得当他的上一步工作
  4459. /// 1, 从当前的找到他的上一步工作的节点集合.
  4460. /// 如果没有找到转向他的节点,就返回,当前的工作.
  4461. ///
  4462. /// </summary>
  4463. /// <returns>得当他的上一步工作</returns>
  4464. public WorkNode GetPreviousWorkNode()
  4465. {
  4466. // 如果没有找到转向他的节点,就返回,当前的工作.
  4467. if (this.HisNode.IsStartNode)
  4468. throw new Exception("@" + this.ToE("WN14", "此节点是开始节点,没有上一步工作")); //此节点是开始节点,没有上一步工作.
  4469. WorkNodes wns = new WorkNodes();
  4470. Nodes nds = this.HisNode.HisFromNodes;
  4471. foreach (Node nd in nds)
  4472. {
  4473. switch (this.HisNode.HisNodeWorkType)
  4474. {
  4475. case NodeWorkType.WorkHL: /* 如果是合流 */
  4476. if (this.IsSubFlowWorkNode == false)
  4477. {
  4478. /* 如果不是线程 */
  4479. Node pnd = nd.HisPriFLNode;
  4480. if (pnd == null)
  4481. throw new Exception("@没有取道它的上一步骤的分流节点,请确认设计是否错误?");
  4482. Work wk1 = (Work)pnd.HisWorks.GetNewEntity;
  4483. wk1.OID = this.HisWork.OID;
  4484. if (wk1.RetrieveFromDBSources() == 0)
  4485. continue;
  4486. WorkNode wn11 = new WorkNode(wk1, pnd);
  4487. return wn11;
  4488. break;
  4489. }
  4490. break;
  4491. default:
  4492. break;
  4493. }
  4494. Work wk = (Work)nd.HisWorks.GetNewEntity;
  4495. wk.OID = this.HisWork.OID;
  4496. if (wk.RetrieveFromDBSources() == 0)
  4497. continue;
  4498. WorkNode wn = new WorkNode(wk, nd);
  4499. wns.Add(wn);
  4500. }
  4501. switch (wns.Count)
  4502. {
  4503. case 0:
  4504. throw new Exception(this.ToE("WN15", "没有找到他的上一步工作,系统错误。请通知管理员来处理,请上让上一步同事撤消发送、或者用本区县管理员用户登陆=》待办工作=》流程查询=》在关键字中输入Workid其它条件选择全部,查询到该流程删除它。") + "@WorkID=" + this.WorkID);
  4505. case 1:
  4506. return (WorkNode)wns[0];
  4507. default:
  4508. break;
  4509. }
  4510. Node nd1 = wns[0].HisNode;
  4511. Node nd2 = wns[1].HisNode;
  4512. if (nd1.HisFromNodes.Contains(NodeAttr.NodeID, nd2.NodeID))
  4513. {
  4514. return wns[0];
  4515. }
  4516. else
  4517. {
  4518. return wns[1];
  4519. }
  4520. }
  4521. /// <summary>
  4522. /// 得当他的下一步工作.
  4523. /// 如果当前工作在没有处理完毕状态,就返回当前的工作.
  4524. /// </summary>
  4525. /// <returns>得当他的下一步工作</returns>
  4526. private WorkNode GetNextWorkNode()
  4527. {
  4528. // 如果当前工作在没有处理完毕状态,就返回当前的工作.
  4529. if (this.HisWork.NodeState != NodeState.Complete)
  4530. throw new Exception(this.ToE("WN16", "@此节点的工作任务还没有完成,没有下一步工作.")); //"@此节点的工作任务还没有完成,没有下一步工作."
  4531. // 如果他是一个结束节点
  4532. if (this.HisNode.IsEndNode)
  4533. throw new Exception(this.ToE("ND17", "@此节点是结束节点,没有下一步工作.")); // "@此节点是结束节点,没有下一步工作."
  4534. // throw new Exception("@当前的工作没有完成任务,这是最");
  4535. Nodes nds = this.HisNode.HisToNodes;
  4536. if (nds.Count == 0)
  4537. throw new Exception("@没有找到从当前节点【" + this.HisNode.Name + "】的转向节点,可能这是一个最后节点,不能取道下一个工作节点。");
  4538. foreach (Node nd in nds)
  4539. {
  4540. Work wk = (Work)nd.HisWorks.GetNewEntity;
  4541. wk.OID = this.HisWork.OID;
  4542. if (wk.IsExits == false)
  4543. continue;
  4544. wk.Retrieve();
  4545. WorkNode wn = new WorkNode(wk, nd);
  4546. return wn;
  4547. }
  4548. if (nds.Count == 1)
  4549. {
  4550. /* 这一中情况是,工作表的记录被非法删除.
  4551. * 补救办法是:
  4552. * 1,把当前的流程的当前工作节点设置为当前的节点.,
  4553. * 2,节设置为工作人员.
  4554. * */
  4555. // 判断是不是用下一步的工作人员列表.
  4556. Node nd = (Node)nds[0];
  4557. WorkerLists wls = new WorkerLists(this.HisWork.OID, nd.NodeID);
  4558. if (wls.Count == 0)
  4559. {
  4560. /*说名没有产生工作者列表.*/
  4561. this.HisWork.NodeState = NodeState.Init;
  4562. this.HisWork.DirectUpdate();
  4563. GenerWorkFlow wgf = new GenerWorkFlow(this.HisWork.OID);
  4564. throw new Exception("@当前的工作没有正确的处理, 没有下一步骤工作节点.也可能是你非法删除了工作表中的记录,造成的没有找到,下一步工作内容,但是系统已经恢复当前节点为为完成状态,此流程可以正常的运行下去.");
  4565. }
  4566. else
  4567. {
  4568. /*说名已经产生工作者列表.*/
  4569. DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE WorkID=" + this.HisWork.OID + " AND FK_Node=" + nd.NodeID);
  4570. }
  4571. }
  4572. throw new Exception("@没有找到下一步骤工作节点[" + this.HisNode.Name + "]的下一步工作,流程错误.请把此问题发送给管理人员.");
  4573. }
  4574. #endregion
  4575. }
  4576. /// <summary>
  4577. /// 工作节点集合.
  4578. /// </summary>
  4579. public class WorkNodes : CollectionBase
  4580. {
  4581. #region 构造
  4582. /// <summary>
  4583. /// 他的工作s
  4584. /// </summary>
  4585. public Works GetWorks
  4586. {
  4587. get
  4588. {
  4589. if (this.Count == 0)
  4590. throw new Exception("@初始化失败,没有找到任何节点。");
  4591. Works ens = this[0].HisNode.HisWorks;
  4592. ens.Clear();
  4593. foreach (WorkNode wn in this)
  4594. {
  4595. ens.AddEntity(wn.HisWork);
  4596. }
  4597. return ens;
  4598. }
  4599. }
  4600. /// <summary>
  4601. /// 工作节点集合
  4602. /// </summary>
  4603. public WorkNodes()
  4604. {
  4605. }
  4606. public int GenerByFID(Flow flow, Int64 fid)
  4607. {
  4608. this.Clear();
  4609. Nodes nds = flow.HisNodes;
  4610. foreach (Node nd in nds)
  4611. {
  4612. if (nd.HisFNType != FNType.River)
  4613. continue;
  4614. Work wk = nd.GetWork(fid);
  4615. if (wk == null)
  4616. continue;
  4617. this.Add(new WorkNode(wk, nd));
  4618. }
  4619. return this.Count;
  4620. }
  4621. public int GenerByWorkID(Flow flow, Int64 oid)
  4622. {
  4623. Nodes nds = flow.HisNodes;
  4624. foreach (Node nd in nds)
  4625. {
  4626. //if (nd.HisFNType == FNType.River)
  4627. // continue;
  4628. Work wk = nd.GetWork(oid);
  4629. if (wk == null)
  4630. continue;
  4631. this.Add(new WorkNode(wk, nd));
  4632. }
  4633. return this.Count;
  4634. }
  4635. /// <summary>
  4636. /// 删除工作流程
  4637. /// </summary>
  4638. public void DeleteWorks()
  4639. {
  4640. foreach (WorkNode wn in this)
  4641. {
  4642. wn.HisWork.Delete();
  4643. }
  4644. }
  4645. #endregion
  4646. #region 方法
  4647. /// <summary>
  4648. /// 增加一个WorkNode
  4649. /// </summary>
  4650. /// <param name="wn">工作 节点</param>
  4651. public void Add(WorkNode wn)
  4652. {
  4653. this.InnerList.Add(wn);
  4654. }
  4655. /// <summary>
  4656. /// 根据位置取得数据
  4657. /// </summary>
  4658. public WorkNode this[int index]
  4659. {
  4660. get
  4661. {
  4662. return (WorkNode)this.InnerList[index];
  4663. }
  4664. }
  4665. #endregion
  4666. }
  4667. }