AnalysisMapper.xml 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.qqflow.engine.domain.flow.mapper.AnalysisMapper">
  4. <resultMap id="ProcessEfficiencyResultMap" type="com.qqflow.engine.domain.flow.dto.analysis.ProcessEfficiencyDTO">
  5. <id column="process_definition_id" property="processDefinitionId"/>
  6. <result column="process_name" property="processName"/>
  7. <result column="instance_count" property="instanceCount"/>
  8. <result column="avg_duration_minutes" property="avgDurationMinutes"/>
  9. <result column="max_duration_minutes" property="maxDurationMinutes"/>
  10. <result column="min_duration_minutes" property="minDurationMinutes"/>
  11. </resultMap>
  12. <resultMap id="NodeStayStatResultMap" type="com.qqflow.engine.domain.flow.dto.analysis.NodeStayStatDTO">
  13. <id column="node_id" property="nodeId"/>
  14. <result column="node_name" property="nodeName"/>
  15. <result column="process_definition_id" property="processDefinitionId"/>
  16. <result column="process_name" property="processName"/>
  17. <result column="task_count" property="taskCount"/>
  18. <result column="avg_stay_minutes" property="avgStayMinutes"/>
  19. <result column="max_stay_minutes" property="maxStayMinutes"/>
  20. </resultMap>
  21. <resultMap id="StuckInstanceResultMap" type="com.qqflow.engine.domain.flow.dto.analysis.StuckInstanceDTO">
  22. <id column="instance_id" property="instanceId"/>
  23. <result column="instance_no" property="instanceNo"/>
  24. <result column="title" property="title"/>
  25. <result column="process_definition_id" property="processDefinitionId"/>
  26. <result column="process_name" property="processName"/>
  27. <result column="applicant_id" property="applicantId"/>
  28. <result column="applicant_name" property="applicantName"/>
  29. <result column="node_id" property="nodeId"/>
  30. <result column="node_name" property="nodeName"/>
  31. <result column="task_create_time" property="taskCreateTime"/>
  32. <result column="stay_minutes" property="stayMinutes"/>
  33. </resultMap>
  34. <!-- 已完成流程效率统计(H2 / MySQL 通用) -->
  35. <select id="selectCompletedEfficiency" resultMap="ProcessEfficiencyResultMap">
  36. SELECT
  37. pd.id AS process_definition_id,
  38. pd.process_name AS process_name,
  39. COUNT(pi.id) AS instance_count,
  40. ROUND(AVG(TIMESTAMPDIFF(MINUTE, pi.start_time, pi.end_time))) AS avg_duration_minutes,
  41. MAX(TIMESTAMPDIFF(MINUTE, pi.start_time, pi.end_time)) AS max_duration_minutes,
  42. MIN(TIMESTAMPDIFF(MINUTE, pi.start_time, pi.end_time)) AS min_duration_minutes
  43. FROM bpm_process_instance pi
  44. INNER JOIN bpm_process_definition pd ON pi.process_definition_id = pd.id
  45. WHERE pi.deleted = 0
  46. AND pi.status = 5
  47. AND pi.end_time IS NOT NULL
  48. <if test="processDefinitionId != null">
  49. AND pi.process_definition_id = #{processDefinitionId}
  50. </if>
  51. <if test="startTime != null">
  52. AND pi.end_time &gt;= #{startTime}
  53. </if>
  54. <if test="endTime != null">
  55. AND pi.end_time &lt;= #{endTime}
  56. </if>
  57. GROUP BY pd.id, pd.process_name
  58. ORDER BY avg_duration_minutes DESC
  59. LIMIT 20
  60. </select>
  61. <!-- 进行中流程节点停留统计 -->
  62. <select id="selectInProgressByNode" resultMap="NodeStayStatResultMap">
  63. SELECT
  64. t.node_id AS node_id,
  65. t.node_name AS node_name,
  66. pi.process_definition_id AS process_definition_id,
  67. pd.process_name AS process_name,
  68. COUNT(t.id) AS task_count,
  69. ROUND(AVG(TIMESTAMPDIFF(MINUTE, t.create_time, NOW()))) AS avg_stay_minutes,
  70. MAX(TIMESTAMPDIFF(MINUTE, t.create_time, NOW())) AS max_stay_minutes
  71. FROM bpm_approval_task t
  72. INNER JOIN bpm_process_instance pi ON t.instance_id = pi.id
  73. LEFT JOIN bpm_process_definition pd ON pi.process_definition_id = pd.id
  74. WHERE t.deleted = 0
  75. AND t.task_status = 0
  76. AND t.node_type != 'cc'
  77. AND pi.deleted = 0
  78. AND pi.status IN (0, 1, 4)
  79. <if test="processDefinitionId != null">
  80. AND pi.process_definition_id = #{processDefinitionId}
  81. </if>
  82. GROUP BY t.node_id, t.node_name, pi.process_definition_id, pd.process_name
  83. ORDER BY avg_stay_minutes DESC
  84. LIMIT 20
  85. </select>
  86. <!-- 卡住流程实例数量 -->
  87. <select id="countStuckInstances" resultType="java.lang.Long">
  88. SELECT COUNT(*)
  89. FROM bpm_approval_task t
  90. INNER JOIN bpm_process_instance pi ON t.instance_id = pi.id
  91. LEFT JOIN bpm_process_definition pd ON pi.process_definition_id = pd.id
  92. WHERE t.deleted = 0
  93. AND t.task_status = 0
  94. AND t.node_type != 'cc'
  95. AND pi.deleted = 0
  96. AND pi.status IN (0, 1, 4)
  97. <if test="nodeId != null and nodeId != ''">
  98. AND t.node_id = #{nodeId}
  99. </if>
  100. <if test="processDefinitionId != null">
  101. AND pi.process_definition_id = #{processDefinitionId}
  102. </if>
  103. <if test="minStayMinutes != null">
  104. AND TIMESTAMPDIFF(MINUTE, t.create_time, NOW()) &gt;= #{minStayMinutes}
  105. </if>
  106. </select>
  107. <!-- 卡住流程实例明细 -->
  108. <select id="selectStuckInstances" resultMap="StuckInstanceResultMap">
  109. SELECT
  110. pi.id AS instance_id,
  111. pi.instance_no AS instance_no,
  112. pi.title AS title,
  113. pi.process_definition_id AS process_definition_id,
  114. pd.process_name AS process_name,
  115. pi.applicant_id AS applicant_id,
  116. su.real_name AS applicant_name,
  117. t.node_id AS node_id,
  118. t.node_name AS node_name,
  119. t.create_time AS task_create_time,
  120. TIMESTAMPDIFF(MINUTE, t.create_time, NOW()) AS stay_minutes
  121. FROM bpm_approval_task t
  122. INNER JOIN bpm_process_instance pi ON t.instance_id = pi.id
  123. LEFT JOIN bpm_process_definition pd ON pi.process_definition_id = pd.id
  124. LEFT JOIN sys_user su ON pi.applicant_id = su.id
  125. WHERE t.deleted = 0
  126. AND t.task_status = 0
  127. AND t.node_type != 'cc'
  128. AND pi.deleted = 0
  129. AND pi.status IN (0, 1, 4)
  130. <if test="nodeId != null and nodeId != ''">
  131. AND t.node_id = #{nodeId}
  132. </if>
  133. <if test="processDefinitionId != null">
  134. AND pi.process_definition_id = #{processDefinitionId}
  135. </if>
  136. <if test="minStayMinutes != null">
  137. AND TIMESTAMPDIFF(MINUTE, t.create_time, NOW()) &gt;= #{minStayMinutes}
  138. </if>
  139. ORDER BY stay_minutes DESC
  140. LIMIT #{pageSize} OFFSET #{offset}
  141. </select>
  142. <!-- 流程实例概览统计 -->
  143. <select id="selectInstanceOverview" resultType="com.qqflow.engine.domain.flow.dto.analysis.AnalysisOverviewDTO">
  144. SELECT
  145. COUNT(id) AS total_instances,
  146. SUM(CASE WHEN status = 5 THEN 1 ELSE 0 END) AS completed_count,
  147. SUM(CASE WHEN status IN (0, 1, 4) THEN 1 ELSE 0 END) AS running_count,
  148. SUM(CASE WHEN status = 3 THEN 1 ELSE 0 END) AS rejected_count,
  149. SUM(CASE WHEN status = 6 THEN 1 ELSE 0 END) AS revoked_count,
  150. IFNULL(ROUND(AVG(CASE WHEN status = 5 THEN TIMESTAMPDIFF(MINUTE, start_time, end_time) END)), 0) AS avg_duration_minutes
  151. FROM bpm_process_instance
  152. WHERE deleted = 0
  153. <if test="startTime != null">
  154. AND start_time &gt;= #{startTime}
  155. </if>
  156. <if test="endTime != null">
  157. AND start_time &lt;= #{endTime}
  158. </if>
  159. <if test="processDefinitionId != null">
  160. AND process_definition_id = #{processDefinitionId}
  161. </if>
  162. </select>
  163. <!-- 超时任务数 -->
  164. <select id="countTimeoutTasks" resultType="java.lang.Long">
  165. SELECT COUNT(t.id)
  166. FROM bpm_approval_task t
  167. INNER JOIN bpm_process_instance pi ON t.instance_id = pi.id
  168. WHERE t.deleted = 0
  169. AND t.task_status = 0
  170. AND t.timeout_time IS NOT NULL
  171. AND t.timeout_time &lt; NOW()
  172. AND pi.deleted = 0
  173. AND pi.status IN (0, 1, 4)
  174. <if test="processDefinitionId != null">
  175. AND pi.process_definition_id = #{processDefinitionId}
  176. </if>
  177. </select>
  178. <!-- 流程状态分布 -->
  179. <select id="selectStatusDistribution" resultType="com.qqflow.engine.domain.flow.dto.analysis.StatusDistributionDTO">
  180. SELECT
  181. status,
  182. COUNT(*) AS count
  183. FROM bpm_process_instance
  184. WHERE deleted = 0
  185. <if test="startTime != null">
  186. AND start_time &gt;= #{startTime}
  187. </if>
  188. <if test="endTime != null">
  189. AND start_time &lt;= #{endTime}
  190. </if>
  191. <if test="processDefinitionId != null">
  192. AND process_definition_id = #{processDefinitionId}
  193. </if>
  194. GROUP BY status
  195. ORDER BY status
  196. </select>
  197. <!-- 近30天流程趋势 -->
  198. <select id="selectTrend" resultType="com.qqflow.engine.domain.flow.dto.analysis.TrendDTO">
  199. SELECT
  200. CAST(DATE(start_time) AS CHAR) AS date,
  201. COUNT(*) AS started_count,
  202. SUM(CASE WHEN status = 5 THEN 1 ELSE 0 END) AS completed_count,
  203. SUM(CASE WHEN status = 3 THEN 1 ELSE 0 END) AS rejected_count
  204. FROM bpm_process_instance
  205. WHERE deleted = 0
  206. AND DATE(start_time) BETWEEN #{startDate} AND #{endDate}
  207. <if test="processDefinitionId != null">
  208. AND process_definition_id = #{processDefinitionId}
  209. </if>
  210. GROUP BY CAST(DATE(start_time) AS CHAR)
  211. ORDER BY date
  212. </select>
  213. </mapper>