添加设备管理功能以及任务分发功能

This commit is contained in:
fenghp
2026-05-10 21:06:57 +08:00
parent 487fc274fc
commit 95bde29804
26 changed files with 2903 additions and 0 deletions
@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.af.AfDeviceMapper">
<resultMap id="AfDeviceResult" type="com.ruoyi.system.domain.af.AfDevice">
<id property="id" column="id"/>
<result property="userName" column="user_name"/>
<result property="deviceCode" column="device_code"/>
<result property="onlineStatus" column="online_status"/>
<result property="taskStatus" column="task_status"/>
<result property="currentTaskId" column="current_task_id"/>
<result property="lastHeartbeatTime" column="last_heartbeat_time"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
</resultMap>
<sql id="selectAfDeviceVo">
select id, user_name, device_code, online_status, task_status, current_task_id,
last_heartbeat_time, create_by, create_time, update_by, update_time, remark
from af_device
</sql>
<select id="selectAfDeviceList" parameterType="com.ruoyi.system.domain.af.AfDevice" resultMap="AfDeviceResult">
<include refid="selectAfDeviceVo"/>
<where>
<if test="userName != null and userName != ''">
and user_name like concat('%', #{userName}, '%')
</if>
<if test="deviceCode != null and deviceCode != ''">
and device_code like concat('%', #{deviceCode}, '%')
</if>
<if test="onlineStatus != null and onlineStatus != ''">
and online_status = #{onlineStatus}
</if>
<if test="taskStatus != null and taskStatus != ''">
and task_status = #{taskStatus}
</if>
</where>
order by id desc
</select>
<select id="selectAfDeviceById" parameterType="Long" resultMap="AfDeviceResult">
<include refid="selectAfDeviceVo"/>
where id = #{id}
</select>
<select id="selectAfDeviceByIdForUpdate" parameterType="Long" resultMap="AfDeviceResult">
<include refid="selectAfDeviceVo"/>
where id = #{id}
for update
</select>
<select id="selectByUserNameAndDeviceCode" resultMap="AfDeviceResult">
<include refid="selectAfDeviceVo"/>
where user_name = #{userName}
and device_code = #{deviceCode}
</select>
<select id="selectByUserNameAndDeviceCodeForUpdate" resultMap="AfDeviceResult">
<include refid="selectAfDeviceVo"/>
where user_name = #{userName}
and device_code = #{deviceCode}
for update
</select>
<select id="selectOneDispatchableForUpdate" resultMap="AfDeviceResult">
<include refid="selectAfDeviceVo"/>
where online_status = 'ONLINE'
and task_status = 'IDLE'
order by last_heartbeat_time desc, id asc
limit 1
for update
</select>
<insert id="insertAfDevice" parameterType="com.ruoyi.system.domain.af.AfDevice">
insert into af_device (
user_name, device_code, online_status, task_status, current_task_id,
last_heartbeat_time, create_by, create_time, update_by, update_time, remark
) values (
#{userName}, #{deviceCode}, #{onlineStatus}, #{taskStatus}, #{currentTaskId},
#{lastHeartbeatTime}, #{createBy}, sysdate(), #{updateBy}, sysdate(), #{remark}
)
</insert>
<update id="updateAfDevice" parameterType="com.ruoyi.system.domain.af.AfDevice">
update af_device
<set>
<if test="onlineStatus != null and onlineStatus != ''">online_status = #{onlineStatus},</if>
<if test="taskStatus != null and taskStatus != ''">task_status = #{taskStatus},</if>
<if test="currentTaskId != null">current_task_id = #{currentTaskId},</if>
<if test="currentTaskId == null">current_task_id = null,</if>
<if test="lastHeartbeatTime != null">last_heartbeat_time = #{lastHeartbeatTime},</if>
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
<if test="remark != null">remark = #{remark},</if>
update_time = sysdate()
</set>
where id = #{id}
</update>
<update id="updateDeviceAfterDispatch">
update af_device
set task_status = 'HAS_TASK',
current_task_id = #{currentTaskId},
update_by = #{updateBy},
update_time = sysdate()
where id = #{id}
and online_status = 'ONLINE'
and task_status = 'IDLE'
</update>
<update id="updateDeviceToIdle">
update af_device
set task_status = 'IDLE',
current_task_id = null,
update_by = #{updateBy},
update_time = sysdate()
where id = #{id}
and current_task_id = #{currentTaskId}
</update>
<update id="refreshOfflineStatus">
update af_device
set online_status = 'OFFLINE',
update_time = sysdate()
where online_status = 'ONLINE'
and last_heartbeat_time is not null
and last_heartbeat_time &lt; date_sub(now(), interval #{timeoutMinutes} minute)
</update>
</mapper>
@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.af.AfDispatchTaskMapper">
<resultMap id="AfDispatchTaskResult" type="com.ruoyi.system.domain.af.AfDispatchTask">
<id property="id" column="id"/>
<result property="taskNo" column="task_no"/>
<result property="orderId" column="order_id"/>
<result property="orderNo" column="order_no"/>
<result property="userName" column="user_name"/>
<result property="deviceId" column="device_id"/>
<result property="deviceCode" column="device_code"/>
<result property="status" column="status"/>
<result property="pushTime" column="push_time"/>
<result property="receiveTime" column="receive_time"/>
<result property="startTime" column="start_time"/>
<result property="finishTime" column="finish_time"/>
<result property="timeoutAt" column="timeout_at"/>
<result property="retryCount" column="retry_count"/>
<result property="failReason" column="fail_reason"/>
<result property="resultJson" column="result_json"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
</resultMap>
<sql id="selectAfDispatchTaskVo">
select id, task_no, order_id, order_no, user_name, device_id, device_code, status,
push_time, receive_time, start_time, finish_time, timeout_at, retry_count,
fail_reason, result_json, create_by, create_time, update_by, update_time, remark
from af_dispatch_task
</sql>
<select id="selectAfDispatchTaskById" parameterType="Long" resultMap="AfDispatchTaskResult">
<include refid="selectAfDispatchTaskVo"/>
where id = #{id}
</select>
<select id="selectAfDispatchTaskByIdForUpdate" parameterType="Long" resultMap="AfDispatchTaskResult">
<include refid="selectAfDispatchTaskVo"/>
where id = #{id}
for update
</select>
<select id="selectAfDispatchTaskList" parameterType="com.ruoyi.system.domain.af.AfDispatchTask" resultMap="AfDispatchTaskResult">
<include refid="selectAfDispatchTaskVo"/>
<where>
<if test="taskNo != null and taskNo != ''">
and task_no like concat('%', #{taskNo}, '%')
</if>
<if test="orderNo != null and orderNo != ''">
and order_no like concat('%', #{orderNo}, '%')
</if>
<if test="userName != null and userName != ''">
and user_name like concat('%', #{userName}, '%')
</if>
<if test="deviceCode != null and deviceCode != ''">
and device_code like concat('%', #{deviceCode}, '%')
</if>
<if test="status != null and status != ''">
and status = #{status}
</if>
<if test="params.beginTime != null and params.beginTime != ''">
and create_time &gt;= #{params.beginTime}
</if>
<if test="params.endTime != null and params.endTime != ''">
and create_time &lt;= #{params.endTime}
</if>
</where>
order by id desc
</select>
<insert id="insertAfDispatchTask" parameterType="com.ruoyi.system.domain.af.AfDispatchTask" useGeneratedKeys="true" keyProperty="id">
insert into af_dispatch_task (
task_no, order_id, order_no, user_name, device_id, device_code, status,
push_time, receive_time, start_time, finish_time, timeout_at, retry_count,
fail_reason, result_json, create_by, create_time, update_by, update_time, remark
) values (
#{taskNo}, #{orderId}, #{orderNo}, #{userName}, #{deviceId}, #{deviceCode}, #{status},
#{pushTime}, #{receiveTime}, #{startTime}, #{finishTime}, #{timeoutAt}, #{retryCount},
#{failReason}, #{resultJson}, #{createBy}, sysdate(), #{updateBy}, sysdate(), #{remark}
)
</insert>
<update id="updateTaskStatusByExpect">
update af_dispatch_task
set status = #{status},
fail_reason = #{failReason},
update_by = #{updateBy},
update_time = sysdate()
<if test="status == 'RECEIVED'">
, receive_time = sysdate()
</if>
<if test="status == 'CANCELLED' or status == 'FAILED' or status == 'SUCCESS' or status == 'TIMEOUT'">
, finish_time = sysdate()
</if>
where id = #{id}
and status = #{expectStatus}
</update>
<update id="updateTaskStatusById">
update af_dispatch_task
set status = #{status},
fail_reason = #{failReason},
update_by = #{updateBy},
update_time = sysdate()
<if test="status == 'RECEIVED'">
, receive_time = sysdate()
</if>
<if test="status == 'CANCELLED' or status == 'FAILED' or status == 'SUCCESS' or status == 'TIMEOUT'">
, finish_time = sysdate()
</if>
where id = #{id}
</update>
<select id="selectPullTaskPayload" resultType="java.util.Map">
select
t.id as taskId,
t.task_no as taskNo,
t.order_id as orderId,
t.order_no as orderNo,
t.user_name as userName,
t.device_id as deviceId,
t.device_code as deviceCode,
t.status as taskStatus,
o.amount as amount,
o.recharge_account as rechargeAccount,
o.ext_json as ext,
o.status as orderStatus
from af_dispatch_task t
inner join af_order o on o.id = t.order_id
where t.user_name = #{userName}
and t.device_code = #{deviceCode}
and t.status in ('CREATED', 'PUSHED')
order by t.create_time asc, t.id asc
limit 1
</select>
</mapper>
@@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.af.AfOrderMapper">
<resultMap id="AfOrderResult" type="com.ruoyi.system.domain.af.AfOrder">
<id property="id" column="id"/>
<result property="source" column="source"/>
<result property="sourceOrderNo" column="source_order_no"/>
<result property="orderNo" column="order_no"/>
<result property="rechargeAccount" column="recharge_account"/>
<result property="userName" column="user_name"/>
<result property="amount" column="amount"/>
<result property="status" column="status"/>
<result property="dispatchMode" column="dispatch_mode"/>
<result property="deviceCode" column="device_code"/>
<result property="currentTaskId" column="current_task_id"/>
<result property="failReason" column="fail_reason"/>
<result property="extJson" column="ext_json"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
</resultMap>
<sql id="selectAfOrderVo">
select id, source, source_order_no, order_no, recharge_account, user_name, amount, status,
dispatch_mode, device_code, current_task_id, fail_reason, ext_json,
create_by, create_time, update_by, update_time, remark
from af_order
</sql>
<select id="selectAfOrderById" parameterType="Long" resultMap="AfOrderResult">
<include refid="selectAfOrderVo"/>
where id = #{id}
</select>
<select id="selectAfOrderByIdForUpdate" parameterType="Long" resultMap="AfOrderResult">
<include refid="selectAfOrderVo"/>
where id = #{id}
for update
</select>
<select id="selectAfOrderList" parameterType="com.ruoyi.system.domain.af.AfOrder" resultMap="AfOrderResult">
<include refid="selectAfOrderVo"/>
<where>
<if test="orderNo != null and orderNo != ''">
and order_no like concat('%', #{orderNo}, '%')
</if>
<if test="status != null and status != ''">
and status = #{status}
</if>
<if test="source != null and source != ''">
and source = #{source}
</if>
<if test="rechargeAccount != null and rechargeAccount != ''">
and recharge_account like concat('%', #{rechargeAccount}, '%')
</if>
<if test="userName != null and userName != ''">
and user_name like concat('%', #{userName}, '%')
</if>
<if test="deviceCode != null and deviceCode != ''">
and device_code like concat('%', #{deviceCode}, '%')
</if>
<if test="dispatchMode != null and dispatchMode != ''">
and dispatch_mode = #{dispatchMode}
</if>
<if test="params.beginTime != null and params.beginTime != ''">
and create_time &gt;= #{params.beginTime}
</if>
<if test="params.endTime != null and params.endTime != ''">
and create_time &lt;= #{params.endTime}
</if>
</where>
order by id desc
</select>
<select id="selectPendingOrderList" resultMap="AfOrderResult">
<include refid="selectAfOrderVo"/>
where status = 'PENDING'
order by create_time asc, id asc
limit #{limit}
</select>
<update id="updateOrderAfterDispatch">
update af_order
set status = #{status},
dispatch_mode = #{dispatchMode},
user_name = #{userName},
device_code = #{deviceCode},
current_task_id = #{currentTaskId},
update_by = #{updateBy},
update_time = sysdate()
where id = #{id}
and status = #{expectStatus}
</update>
<update id="updateOrderStatusByExpect">
update af_order
set status = #{status},
fail_reason = #{failReason},
update_by = #{updateBy},
update_time = sysdate()
where id = #{id}
and status = #{expectStatus}
</update>
<update id="updateOrderStatusById">
update af_order
set status = #{status},
fail_reason = #{failReason},
update_by = #{updateBy},
update_time = sysdate()
where id = #{id}
</update>
<update id="resetOrderToPending">
update af_order
set status = 'PENDING',
dispatch_mode = null,
user_name = null,
device_code = null,
current_task_id = null,
fail_reason = null,
update_by = #{updateBy},
update_time = sysdate()
where id = #{id}
</update>
</mapper>
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.af.AfTaskStepLogMapper">
<resultMap id="AfTaskStepLogResult" type="com.ruoyi.system.domain.af.AfTaskStepLog">
<id property="id" column="id"/>
<result property="taskId" column="task_id"/>
<result property="stepCode" column="step_code"/>
<result property="stepName" column="step_name"/>
<result property="stepStatus" column="step_status"/>
<result property="message" column="message"/>
<result property="payloadJson" column="payload_json"/>
<result property="createTime" column="create_time"/>
</resultMap>
<select id="selectByTaskId" parameterType="Long" resultMap="AfTaskStepLogResult">
select id, task_id, step_code, step_name, step_status, message, payload_json, create_time
from af_task_step_log
where task_id = #{taskId}
order by id asc
</select>
</mapper>