ScheduleTaskHelper.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. using JLHHJSvr.BLL;
  2. using JLHHJSvr.Com.Model;
  3. using LJLib.SQLEX;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Data.SqlClient;
  7. using System.Diagnostics;
  8. using System.Text;
  9. namespace JLHHJSvr.Helper
  10. {
  11. internal sealed class ScheduleTaskHelper
  12. {
  13. public const string TaskTypeMattressRecalc = "mattress_recalc";
  14. public const string TaskTypeBatchModifyMattressInterfaceConfig = "batch_modify_mattress_interface_config";
  15. private readonly object _runLock = new object();
  16. private bool _running;
  17. public static string GetTaskTypeName(string taskType)
  18. {
  19. switch (taskType)
  20. {
  21. case TaskTypeMattressRecalc:
  22. return "重算报价";
  23. case TaskTypeBatchModifyMattressInterfaceConfig:
  24. return "批量批改配置";
  25. default:
  26. return taskType ?? string.Empty;
  27. }
  28. }
  29. public static int CreateTaskLog(SqlCommand cmd, u_task_log info)
  30. {
  31. var taskid = BllHelper.GetID(cmd, "u_task_log");
  32. cmd.CommandText = @"
  33. INSERT INTO u_task_log
  34. (taskid, task_type, run_mode, schedule_time, status, total_count, success_count, fail_count, skip_count, request_json, log_msg, create_emp, create_time, start_time)
  35. VALUES
  36. (@taskid, @task_type, @run_mode, @schedule_time, @status, @total_count, 0, 0, 0, @request_json, '', @create_emp, GETDATE(), " + (info.start_time.HasValue ? "GETDATE()" : "NULL") + ")";
  37. cmd.Parameters.Clear();
  38. cmd.Parameters.AddWithValue("@taskid", taskid);
  39. cmd.Parameters.AddWithValue("@task_type", info.task_type ?? string.Empty);
  40. cmd.Parameters.AddWithValue("@run_mode", info.run_mode);
  41. cmd.Parameters.AddWithValue("@schedule_time", (object)info.schedule_time ?? DBNull.Value);
  42. cmd.Parameters.AddWithValue("@status", info.status);
  43. cmd.Parameters.AddWithValue("@total_count", info.total_count);
  44. cmd.Parameters.AddWithValue("@request_json", info.request_json ?? string.Empty);
  45. cmd.Parameters.AddWithValue("@create_emp", info.create_emp ?? string.Empty);
  46. cmd.ExecuteNonQuery();
  47. return taskid;
  48. }
  49. public static void InsertTaskLogItems(SqlCommand cmd, int taskid, List<u_task_log_mx> items)
  50. {
  51. foreach (var item in items)
  52. {
  53. cmd.CommandText = @"
  54. INSERT INTO u_task_log_mx
  55. (taskid, printid, biz_id, biz_code, biz_name, status, result_json, err_msg, start_time)
  56. VALUES
  57. (@taskid, @printid, @biz_id, @biz_code, @biz_name, @status, '', '', " + (item.start_time.HasValue ? "GETDATE()" : "NULL") + ")";
  58. cmd.Parameters.Clear();
  59. cmd.Parameters.AddWithValue("@taskid", taskid);
  60. cmd.Parameters.AddWithValue("@printid", item.printid);
  61. cmd.Parameters.AddWithValue("@biz_id", item.biz_id);
  62. cmd.Parameters.AddWithValue("@biz_code", item.biz_code ?? string.Empty);
  63. cmd.Parameters.AddWithValue("@biz_name", item.biz_name ?? string.Empty);
  64. cmd.Parameters.AddWithValue("@status", item.status);
  65. cmd.ExecuteNonQuery();
  66. }
  67. }
  68. public static void UpdateTaskLogItemResults(SqlCommand cmd, int taskid, List<u_task_log_mx> items)
  69. {
  70. foreach (var item in items)
  71. {
  72. cmd.CommandText = @"
  73. UPDATE u_task_log_mx
  74. SET status = @status, result_json = @result_json, err_msg = @err_msg, start_time = ISNULL(start_time, GETDATE()), end_time = GETDATE()
  75. WHERE taskid = @taskid AND printid = @printid";
  76. cmd.Parameters.Clear();
  77. cmd.Parameters.AddWithValue("@status", item.status);
  78. cmd.Parameters.AddWithValue("@result_json", item.result_json ?? string.Empty);
  79. cmd.Parameters.AddWithValue("@err_msg", LimitValue(item.err_msg, 4000));
  80. cmd.Parameters.AddWithValue("@taskid", taskid);
  81. cmd.Parameters.AddWithValue("@printid", item.printid);
  82. cmd.ExecuteNonQuery();
  83. }
  84. }
  85. public static void FinishTaskLog(SqlCommand cmd, int taskid, int totalCount, int successCount, int failCount, int skipCount, string logMsg)
  86. {
  87. var status = failCount > 0 && (successCount > 0 || skipCount > 0) ? 4 : (failCount > 0 ? 3 : 2);
  88. cmd.CommandText = @"
  89. UPDATE u_task_log
  90. SET status = @status,
  91. total_count = @total_count,
  92. success_count = @success_count,
  93. fail_count = @fail_count,
  94. skip_count = @skip_count,
  95. log_msg = @log_msg,
  96. end_time = GETDATE()
  97. WHERE taskid = @taskid";
  98. cmd.Parameters.Clear();
  99. cmd.Parameters.AddWithValue("@status", status);
  100. cmd.Parameters.AddWithValue("@total_count", totalCount);
  101. cmd.Parameters.AddWithValue("@success_count", successCount);
  102. cmd.Parameters.AddWithValue("@fail_count", failCount);
  103. cmd.Parameters.AddWithValue("@skip_count", skipCount);
  104. cmd.Parameters.AddWithValue("@log_msg", LimitValue(logMsg, 8000));
  105. cmd.Parameters.AddWithValue("@taskid", taskid);
  106. cmd.ExecuteNonQuery();
  107. }
  108. public void ExecuteDueTasks()
  109. {
  110. lock (_runLock)
  111. {
  112. if (_running) return;
  113. _running = true;
  114. }
  115. try
  116. {
  117. var taskIds = GetDueTaskIds();
  118. foreach (var taskid in taskIds)
  119. {
  120. ExecuteTask(taskid);
  121. }
  122. }
  123. catch (Exception ex)
  124. {
  125. Trace.Write(ex);
  126. }
  127. finally
  128. {
  129. lock (_runLock)
  130. {
  131. _running = false;
  132. }
  133. }
  134. }
  135. private List<int> GetDueTaskIds()
  136. {
  137. var ids = new List<int>();
  138. using (var con = GlobalVar.ConnectionString.NewSqlConnection())
  139. using (var cmd = con.CreateCommand())
  140. {
  141. con.Open();
  142. cmd.CommandText = @"
  143. SELECT taskid
  144. FROM u_task_log WITH (NOLOCK)
  145. WHERE run_mode = 2 AND status = 0 AND schedule_time <= GETDATE()
  146. ORDER BY schedule_time, taskid";
  147. using (var reader = cmd.ExecuteReader())
  148. {
  149. while (reader.Read())
  150. {
  151. ids.Add(Convert.ToInt32(reader["taskid"]));
  152. }
  153. }
  154. }
  155. return ids;
  156. }
  157. private void ExecuteTask(int taskid)
  158. {
  159. var taskType = string.Empty;
  160. var createEmp = string.Empty;
  161. using (var con = GlobalVar.ConnectionString.NewSqlConnection())
  162. using (var cmd = con.CreateCommand())
  163. {
  164. con.Open();
  165. cmd.CommandText = @"
  166. UPDATE u_task_log
  167. SET status = 1, start_time = GETDATE()
  168. WHERE taskid = @taskid AND run_mode = 2 AND status = 0";
  169. cmd.Parameters.Clear();
  170. cmd.Parameters.AddWithValue("@taskid", taskid);
  171. if (cmd.ExecuteNonQuery() == 0) return;
  172. cmd.CommandText = "SELECT task_type, create_emp FROM u_task_log WHERE taskid = @taskid";
  173. cmd.Parameters.Clear();
  174. cmd.Parameters.AddWithValue("@taskid", taskid);
  175. using (var reader = cmd.ExecuteReader())
  176. {
  177. if (reader.Read())
  178. {
  179. taskType = Convert.ToString(reader["task_type"]);
  180. createEmp = Convert.ToString(reader["create_emp"]);
  181. }
  182. }
  183. }
  184. var success = 0;
  185. var fail = 0;
  186. var taskTypeName = GetTaskTypeName(taskType);
  187. var log = new StringBuilder();
  188. foreach (var item in GetPendingItems(taskid))
  189. {
  190. var errMsg = string.Empty;
  191. var isSuccess = false;
  192. using (var con = GlobalVar.ConnectionString.NewSqlConnection())
  193. using (var cmd = con.CreateCommand())
  194. {
  195. con.Open();
  196. using (cmd.Transaction = con.BeginTransaction())
  197. {
  198. try
  199. {
  200. UpdateItemRunning(cmd, taskid, item.printid);
  201. ExecuteOne(cmd, taskType, createEmp, item);
  202. UpdateItemResult(cmd, taskid, item.printid, 2, string.Empty);
  203. cmd.Transaction.Commit();
  204. isSuccess = true;
  205. }
  206. catch (Exception ex)
  207. {
  208. cmd.Transaction.Rollback();
  209. errMsg = ex.Message;
  210. Trace.Write(ex);
  211. }
  212. }
  213. }
  214. if (isSuccess)
  215. {
  216. success++;
  217. log.AppendLine($"任务类型:{taskTypeName} 单据:{item.biz_code} 执行成功");
  218. }
  219. else
  220. {
  221. fail++;
  222. SaveItemFail(taskid, item.printid, errMsg);
  223. log.AppendLine($"任务类型:{taskTypeName} 单据:{item.biz_code} 执行失败,错误:{errMsg}");
  224. }
  225. UpdateTaskProgress(taskid, success, fail);
  226. }
  227. FinishTask(taskid, success, fail, log.ToString());
  228. }
  229. private void ExecuteOne(SqlCommand cmd, string taskType, string createEmp, u_schedule_task_mx item)
  230. {
  231. if (taskType == TaskTypeMattressRecalc)
  232. {
  233. var helper = HelperBase.GetHelper<MattressHelper>(cmd, new HelperBase.Context
  234. {
  235. tokendata = new TokenData { username = createEmp },
  236. opdate = DateTime.Now
  237. });
  238. helper.RecalculateOne(new u_mattress { mattressid = item.biz_id });
  239. return;
  240. }
  241. throw new NotSupportedException("Unsupported task type:" + taskType);
  242. }
  243. private List<u_schedule_task_mx> GetPendingItems(int taskid)
  244. {
  245. var list = new List<u_schedule_task_mx>();
  246. using (var con = GlobalVar.ConnectionString.NewSqlConnection())
  247. using (var cmd = con.CreateCommand())
  248. {
  249. con.Open();
  250. cmd.CommandText = @"
  251. SELECT taskid, printid, biz_id, biz_code, biz_name, request_json
  252. FROM u_task_log_mx
  253. WHERE taskid = @taskid AND status = 0
  254. ORDER BY printid";
  255. cmd.Parameters.Clear();
  256. cmd.Parameters.AddWithValue("@taskid", taskid);
  257. using (var reader = cmd.ExecuteReader())
  258. {
  259. while (reader.Read())
  260. {
  261. list.Add(new u_schedule_task_mx
  262. {
  263. taskid = Convert.ToInt32(reader["taskid"]),
  264. printid = Convert.ToInt32(reader["printid"]),
  265. biz_id = Convert.ToInt32(reader["biz_id"]),
  266. biz_code = Convert.ToString(reader["biz_code"]),
  267. biz_name = Convert.ToString(reader["biz_name"]),
  268. request_json = Convert.ToString(reader["request_json"])
  269. });
  270. }
  271. }
  272. }
  273. return list;
  274. }
  275. private void UpdateItemRunning(SqlCommand cmd, int taskid, int printid)
  276. {
  277. cmd.CommandText = @"
  278. UPDATE u_task_log_mx
  279. SET status = 1, start_time = GETDATE(), err_msg = ''
  280. WHERE taskid = @taskid AND printid = @printid";
  281. cmd.Parameters.Clear();
  282. cmd.Parameters.AddWithValue("@taskid", taskid);
  283. cmd.Parameters.AddWithValue("@printid", printid);
  284. cmd.ExecuteNonQuery();
  285. }
  286. private void UpdateItemResult(SqlCommand cmd, int taskid, int printid, int status, string errMsg)
  287. {
  288. cmd.CommandText = @"
  289. UPDATE u_task_log_mx
  290. SET status = @status, err_msg = @err_msg, start_time = ISNULL(start_time, GETDATE()), end_time = GETDATE()
  291. WHERE taskid = @taskid AND printid = @printid";
  292. cmd.Parameters.Clear();
  293. cmd.Parameters.AddWithValue("@status", status);
  294. cmd.Parameters.AddWithValue("@err_msg", Limit(errMsg, 4000));
  295. cmd.Parameters.AddWithValue("@taskid", taskid);
  296. cmd.Parameters.AddWithValue("@printid", printid);
  297. cmd.ExecuteNonQuery();
  298. }
  299. private void SaveItemFail(int taskid, int printid, string errMsg)
  300. {
  301. using (var con = GlobalVar.ConnectionString.NewSqlConnection())
  302. using (var cmd = con.CreateCommand())
  303. {
  304. con.Open();
  305. UpdateItemResult(cmd, taskid, printid, 3, errMsg);
  306. }
  307. }
  308. private void UpdateTaskProgress(int taskid, int success, int fail)
  309. {
  310. using (var con = GlobalVar.ConnectionString.NewSqlConnection())
  311. using (var cmd = con.CreateCommand())
  312. {
  313. con.Open();
  314. cmd.CommandText = @"
  315. UPDATE u_task_log
  316. SET success_count = @success_count, fail_count = @fail_count
  317. WHERE taskid = @taskid";
  318. cmd.Parameters.Clear();
  319. cmd.Parameters.AddWithValue("@success_count", success);
  320. cmd.Parameters.AddWithValue("@fail_count", fail);
  321. cmd.Parameters.AddWithValue("@taskid", taskid);
  322. cmd.ExecuteNonQuery();
  323. }
  324. }
  325. private void FinishTask(int taskid, int success, int fail, string logMsg)
  326. {
  327. using (var con = GlobalVar.ConnectionString.NewSqlConnection())
  328. using (var cmd = con.CreateCommand())
  329. {
  330. con.Open();
  331. cmd.CommandText = @"
  332. UPDATE u_task_log
  333. SET status = @status, success_count = @success_count, fail_count = @fail_count,
  334. log_msg = @log_msg, end_time = GETDATE()
  335. WHERE taskid = @taskid";
  336. cmd.Parameters.Clear();
  337. cmd.Parameters.AddWithValue("@status", fail > 0 && success > 0 ? 4 : (fail > 0 ? 3 : 2));
  338. cmd.Parameters.AddWithValue("@success_count", success);
  339. cmd.Parameters.AddWithValue("@fail_count", fail);
  340. cmd.Parameters.AddWithValue("@log_msg", logMsg ?? string.Empty);
  341. cmd.Parameters.AddWithValue("@taskid", taskid);
  342. cmd.ExecuteNonQuery();
  343. }
  344. }
  345. private string Limit(string value, int maxLength)
  346. {
  347. return LimitValue(value, maxLength);
  348. }
  349. private static string LimitValue(string value, int maxLength)
  350. {
  351. if (string.IsNullOrEmpty(value)) return string.Empty;
  352. return value.Length <= maxLength ? value : value.Substring(0, maxLength);
  353. }
  354. }
  355. }