diff options
| author | shizhendong <[email protected]> | 2024-08-27 15:58:41 +0800 |
|---|---|---|
| committer | shizhendong <[email protected]> | 2024-08-27 15:58:41 +0800 |
| commit | 16fc3a4bc23cb9447bd0068b085635b3cc5c4ed6 (patch) | |
| tree | a02d499d06126c90b86ca837a2b8853812368e4d | |
| parent | 9051cd3fac60196223031ed9d0839fe13b547304 (diff) | |
feat: ASW-46 新增 device 接口
11 files changed, 465 insertions, 0 deletions
diff --git a/src/main/java/net/geedge/asw/module/device/controller/DeviceController.java b/src/main/java/net/geedge/asw/module/device/controller/DeviceController.java new file mode 100644 index 0000000..7942c05 --- /dev/null +++ b/src/main/java/net/geedge/asw/module/device/controller/DeviceController.java @@ -0,0 +1,90 @@ +package net.geedge.asw.module.device.controller; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.json.JSONObject; +import cn.hutool.log.Log; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.geedge.asw.common.util.R; +import net.geedge.asw.common.util.RCode; +import net.geedge.asw.common.util.T; +import net.geedge.asw.module.device.entity.DeviceEntity; +import net.geedge.asw.module.device.service.IDeviceService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +@RestController +@RequestMapping("/api/v1/device") +public class DeviceController { + + private static final Log log = Log.get(); + + + @Autowired + private IDeviceService deviceService; + + @GetMapping("/{id}") + public R detail(@PathVariable("id") String id) { + DeviceEntity entity = deviceService.queryInfo(id); + return R.ok().putData("record", entity); + } + + @GetMapping + public R list(@RequestParam Map<String, Object> params) { + T.VerifyUtil.is(params).notNull() + .and(T.MapUtil.getStr(params, "workspaceId")).notEmpty(RCode.WORKSPACE_ID_CANNOT_EMPTY); + Page page = deviceService.queryList(params); + return R.ok(page); + } + + @PostMapping + public R add(@RequestBody DeviceEntity entity) { + T.VerifyUtil.is(entity).notNull() + .and(entity.getName()).notEmpty(RCode.NAME_CANNOT_EMPTY) + .and(entity.getWorkspaceId()).notEmpty(RCode.WORKSPACE_ID_CANNOT_EMPTY); + + DeviceEntity deviceEntity = deviceService.saveDevice(entity); + return R.ok().putData("id", deviceEntity.getId()); + } + + @DeleteMapping + public R delete(String[] ids) { + T.VerifyUtil.is(ids).notEmpty(); + deviceService.removeDevice(T.ListUtil.of(ids)); + return R.ok(); + } + + @PostMapping("/test") + public R testConnect(@RequestBody DeviceEntity entity) { + T.VerifyUtil.is(entity).notNull() + .and(entity.getParam()).notEmpty(RCode.PARAM_CANNOT_EMPTY); + + JSONObject jsonObject = entity.getParamJSONObject(); + String host = jsonObject.getStr("host"); + String port = jsonObject.getStr("port"); + String token = jsonObject.getStr("token"); + if (T.StrUtil.hasEmpty(host, port, token)) { + return R.error(RCode.PARAM_CANNOT_EMPTY); + } + + try { + HttpRequest request = T.HttpUtil.createGet(String.format("http://%s:%s/api/v1/device/status", host, port)); + request.header("Authorization", token); + HttpResponse response = request.execute(); + log.info("[testConnect] [status: {}]", response.getStatus()); + if (response.getStatus() == 401) { + return R.error(401, "Unauthorized"); + } + if (response.isOk()) { + return R.ok(); + } + } catch (Exception e) { + log.error(e); + return R.error(RCode.ERROR); + } + return R.error(RCode.ERROR); + } + +}
\ No newline at end of file diff --git a/src/main/java/net/geedge/asw/module/device/dao/DeviceDao.java b/src/main/java/net/geedge/asw/module/device/dao/DeviceDao.java new file mode 100644 index 0000000..72897da --- /dev/null +++ b/src/main/java/net/geedge/asw/module/device/dao/DeviceDao.java @@ -0,0 +1,16 @@ +package net.geedge.asw.module.device.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.geedge.asw.module.device.entity.DeviceEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; +import java.util.Map; + +@Mapper +public interface DeviceDao extends BaseMapper<DeviceEntity> { + + List<DeviceEntity> queryList(Page page, Map<String, Object> params); + +} diff --git a/src/main/java/net/geedge/asw/module/device/dao/DeviceLogDao.java b/src/main/java/net/geedge/asw/module/device/dao/DeviceLogDao.java new file mode 100644 index 0000000..da9ab72 --- /dev/null +++ b/src/main/java/net/geedge/asw/module/device/dao/DeviceLogDao.java @@ -0,0 +1,10 @@ +package net.geedge.asw.module.device.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.geedge.asw.module.device.entity.DeviceLogEntity; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface DeviceLogDao extends BaseMapper<DeviceLogEntity> { + +} diff --git a/src/main/java/net/geedge/asw/module/device/entity/DeviceEntity.java b/src/main/java/net/geedge/asw/module/device/entity/DeviceEntity.java new file mode 100644 index 0000000..e2a9d2e --- /dev/null +++ b/src/main/java/net/geedge/asw/module/device/entity/DeviceEntity.java @@ -0,0 +1,53 @@ +package net.geedge.asw.module.device.entity; + +import cn.hutool.json.JSONObject; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; +import net.geedge.asw.common.util.T; +import net.geedge.asw.module.sys.entity.SysUserEntity; + +@Data +@TableName("device") +public class DeviceEntity { + + @TableId(type = IdType.ASSIGN_UUID) + private String id; + private String name; + private String location; + private String platform; + private Object param; + private String description; + private Integer status; + + private Long lastHealthCheck; + private Long createTimestamp; + private Long updateTimestamp; + private String createUserId; + private String updateUserId; + + private String workspaceId; + + @TableField(exist = false) + private SysUserEntity createUser; + + @TableField(exist = false) + private SysUserEntity updateUser; + + @TableField(exist = false) + private JSONObject useUser; + + @JsonIgnore + public String getParamStr() { + return null == this.param ? "{}" : T.JSONUtil.toJsonStr(this.param); + } + + @JsonIgnore + public JSONObject getParamJSONObject() { + return null == this.param ? new JSONObject() : T.JSONUtil.parseObj(this.getParamStr()); + } + +}
\ No newline at end of file diff --git a/src/main/java/net/geedge/asw/module/device/entity/DeviceLogEntity.java b/src/main/java/net/geedge/asw/module/device/entity/DeviceLogEntity.java new file mode 100644 index 0000000..2c9ec13 --- /dev/null +++ b/src/main/java/net/geedge/asw/module/device/entity/DeviceLogEntity.java @@ -0,0 +1,24 @@ +package net.geedge.asw.module.device.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@Data +@TableName("device_log") +public class DeviceLogEntity { + + @TableId(type = IdType.ASSIGN_UUID) + private String id; + private String deviceId; + private String userId; + private Integer status; + private String jobId; + + private Long startTimestamp; + private Long endTimestamp; + + private String workspaceId; + +}
\ No newline at end of file diff --git a/src/main/java/net/geedge/asw/module/device/service/IDeviceLogService.java b/src/main/java/net/geedge/asw/module/device/service/IDeviceLogService.java new file mode 100644 index 0000000..f910179 --- /dev/null +++ b/src/main/java/net/geedge/asw/module/device/service/IDeviceLogService.java @@ -0,0 +1,8 @@ +package net.geedge.asw.module.device.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import net.geedge.asw.module.device.entity.DeviceLogEntity; + +public interface IDeviceLogService extends IService<DeviceLogEntity>{ + +} diff --git a/src/main/java/net/geedge/asw/module/device/service/IDeviceService.java b/src/main/java/net/geedge/asw/module/device/service/IDeviceService.java new file mode 100644 index 0000000..4236b3e --- /dev/null +++ b/src/main/java/net/geedge/asw/module/device/service/IDeviceService.java @@ -0,0 +1,20 @@ +package net.geedge.asw.module.device.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import net.geedge.asw.module.device.entity.DeviceEntity; + +import java.util.List; +import java.util.Map; + +public interface IDeviceService extends IService<DeviceEntity>{ + + DeviceEntity queryInfo(String id); + + Page queryList(Map<String, Object> params); + + DeviceEntity saveDevice(DeviceEntity entity); + + void removeDevice(List<String> ids); + +} diff --git a/src/main/java/net/geedge/asw/module/device/service/impl/DeviceLogServiceImpl.java b/src/main/java/net/geedge/asw/module/device/service/impl/DeviceLogServiceImpl.java new file mode 100644 index 0000000..7fd1160 --- /dev/null +++ b/src/main/java/net/geedge/asw/module/device/service/impl/DeviceLogServiceImpl.java @@ -0,0 +1,15 @@ +package net.geedge.asw.module.device.service.impl; + +import cn.hutool.log.Log; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.geedge.asw.module.device.dao.DeviceLogDao; +import net.geedge.asw.module.device.entity.DeviceLogEntity; +import net.geedge.asw.module.device.service.IDeviceLogService; +import org.springframework.stereotype.Service; + +@Service +public class DeviceLogServiceImpl extends ServiceImpl<DeviceLogDao, DeviceLogEntity> implements IDeviceLogService { + + private static final Log log = Log.get(); + +} diff --git a/src/main/java/net/geedge/asw/module/device/service/impl/DeviceServiceImpl.java b/src/main/java/net/geedge/asw/module/device/service/impl/DeviceServiceImpl.java new file mode 100644 index 0000000..e35b1f4 --- /dev/null +++ b/src/main/java/net/geedge/asw/module/device/service/impl/DeviceServiceImpl.java @@ -0,0 +1,103 @@ +package net.geedge.asw.module.device.service.impl; + +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.log.Log; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.geedge.asw.common.util.RCode; +import net.geedge.asw.common.util.T; +import net.geedge.asw.module.device.dao.DeviceDao; +import net.geedge.asw.module.device.entity.DeviceEntity; +import net.geedge.asw.module.device.entity.DeviceLogEntity; +import net.geedge.asw.module.device.service.IDeviceLogService; +import net.geedge.asw.module.device.service.IDeviceService; +import net.geedge.asw.module.sys.entity.SysUserEntity; +import net.geedge.asw.module.sys.service.ISysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +@Service +public class DeviceServiceImpl extends ServiceImpl<DeviceDao, DeviceEntity> implements IDeviceService { + + private static final Log log = Log.get(); + + @Autowired + private ISysUserService sysUserService; + + @Autowired + private IDeviceLogService deviceLogService; + + @Override + public DeviceEntity queryInfo(String id) { + DeviceEntity device = this.getById(id); + T.VerifyUtil.is(device).notNull(RCode.SYS_RECORD_NOT_FOUND); + + // param + device.setParam(device.getParamJSONObject()); + + SysUserEntity createUser = sysUserService.getById(device.getCreateUserId()); + SysUserEntity updateUser = sysUserService.getById(device.getUpdateUserId()); + device.setCreateUser(createUser); + device.setUpdateUser(updateUser); + + DeviceLogEntity deviceLog = deviceLogService.getOne(new LambdaQueryWrapper<DeviceLogEntity>().eq(DeviceLogEntity::getDeviceId, device.getId())); + if (null != deviceLog) { + SysUserEntity useUser = sysUserService.getById(deviceLog.getUserId()); + + JSONObject jsonObject = new JSONObject(); + jsonObject.set("id", useUser.getId()); + jsonObject.set("name", useUser.getName()); + jsonObject.set("startTimestamp", deviceLog.getStartTimestamp()); + jsonObject.set("endTimestamp", deviceLog.getEndTimestamp()); + device.setUseUser(jsonObject); + } + return device; + } + + @Override + public Page queryList(Map<String, Object> params) { + Page page = T.PageUtil.getPage(params); + List<DeviceEntity> packageList = this.getBaseMapper().queryList(page, params); + + for (DeviceEntity entity : packageList) { + entity.setParam(entity.getParamJSONObject()); + } + page.setRecords(packageList); + return page; + } + + @Override + public DeviceEntity saveDevice(DeviceEntity entity) { + // param + entity.setParam(entity.getParamStr()); + + // default android + entity.setPlatform(T.StrUtil.emptyToDefault(entity.getPlatform(), "android")); + + entity.setCreateTimestamp(System.currentTimeMillis()); + entity.setUpdateTimestamp(System.currentTimeMillis()); + entity.setCreateUserId(StpUtil.getLoginIdAsString()); + entity.setUpdateUserId(StpUtil.getLoginIdAsString()); + + // save + this.save(entity); + return entity; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void removeDevice(List<String> ids) { + // remove + this.removeBatchByIds(ids); + + // log + deviceLogService.remove(new LambdaQueryWrapper<DeviceLogEntity>().in(DeviceLogEntity::getDeviceId, ids)); + } + +}
\ No newline at end of file diff --git a/src/main/resources/db/mapper/device/DeviceMapper.xml b/src/main/resources/db/mapper/device/DeviceMapper.xml new file mode 100644 index 0000000..a4aec0f --- /dev/null +++ b/src/main/resources/db/mapper/device/DeviceMapper.xml @@ -0,0 +1,79 @@ +<?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="net.geedge.asw.module.device.dao.DeviceDao"> + <resultMap id="deviceResult" type="net.geedge.asw.module.device.entity.DeviceEntity"> + <result property="id" column="id"/> + <result property="name" column="name"/> + <result property="platform" column="platform"/> + <result property="param" column="param"/> + <result property="description" column="description"/> + <result property="status" column="status"/> + <result property="lastHealthCheck" column="last_health_check"/> + <result property="createTimestamp" column="create_timestamp"/> + <result property="updateTimestamp" column="update_timestamp"/> + <result property="createUserId" column="create_user_id"/> + <result property="updateUserId" column="update_user_id"/> + <result property="workspaceId" column="workspace_id"/> + + <association property="createUser" columnPrefix="cu_" javaType="net.geedge.asw.module.sys.entity.SysUserEntity"> + <id property="id" column="id"/> + <result property="name" column="name"/> + </association> + + <association property="updateUser" columnPrefix="uu_" javaType="net.geedge.asw.module.sys.entity.SysUserEntity"> + <id property="id" column="id"/> + <result property="name" column="name"/> + </association> + + <association property="useUser" columnPrefix="u_" javaType="cn.hutool.json.JSONObject"> + <result property="id" column="id"/> + <result property="name" column="name"/> + <result property="startTimestamp" column="start_timestamp"/> + <result property="endTimestamp" column="end_timestamp"/> + </association> + </resultMap> + + <select id="queryList" resultMap="deviceResult"> + SELECT + d.*, + + cu.id AS cu_id, + cu.name AS cu_name, + + uu.id AS uu_id, + uu.name AS uu_name, + + log.user_id AS u_id, + u.name AS u_name, + log.start_timestamp AS u_start_timestamp, + log.end_timestamp AS u_end_timestamp + FROM device d + LEFT JOIN sys_user cu ON d.create_user_id = cu.id + LEFT JOIN sys_user uu ON d.update_user_id = uu.id + LEFT JOIN device_log log ON d.id = log.device_id + LEFT JOIN sys_user u ON log.user_id = u.id + + <where> + <if test="params.ids != null and params.ids != ''"> + d.id in + <foreach item="id" collection="params.ids.split(',')" separator="," open="(" close=")"> + #{id} + </foreach> + </if> + + <if test="params.q != null and params.q != ''"> + AND ( locate(#{params.q}, d.name) OR locate(#{params.q}, d.description) ) + </if> + + <if test="params.workspaceId != null and params.workspaceId != ''"> + AND d.workspace_id = #{params.workspaceId} + </if> + </where> + + <if test="params.orderBy == null or params.orderBy == ''"> + ORDER BY d.create_timestamp + </if> + </select> + +</mapper>
\ No newline at end of file diff --git a/src/main/resources/db/migration/V1.0.01__INIT_TABLES.sql b/src/main/resources/db/migration/V1.0.01__INIT_TABLES.sql index 4df4b10..1703503 100644 --- a/src/main/resources/db/migration/V1.0.01__INIT_TABLES.sql +++ b/src/main/resources/db/migration/V1.0.01__INIT_TABLES.sql @@ -456,3 +456,50 @@ CREATE TABLE `workspace_member` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; INSERT INTO `workspace_member` (`workspace_id`, `user_id`, `role_id`, `create_timestamp`, `create_user_id`) VALUES ('1', 'admin', 'admin', 1724291229000, 'admin'); + + +/** + * 新增 device 表 + */ +DROP TABLE IF EXISTS `device`; +CREATE TABLE `device` ( + `id` varchar(64) NOT NULL COMMENT '主键', + `name` varchar(256) NOT NULL DEFAULT '' COMMENT '名称', + `location` varchar(256) NOT NULL DEFAULT '' COMMENT '位置', + `platform` varchar(256) NOT NULL DEFAULT 'android' COMMENT '支持的平台,可选:android', + `param` varchar(1024) NOT NULL DEFAULT '' COMMENT '连接参数', + `description` text NOT NULL DEFAULT '' COMMENT '描述信息', + `status` int(1) NOT NULL DEFAULT 0 COMMENT '状态,0:离线;1:在线', + `last_health_check` bigint(20) NOT NULL DEFAULT -1 COMMENT '最后健康检查时间', + `create_timestamp` bigint(20) NOT NULL COMMENT '创建时间戳', + `update_timestamp` bigint(20) NOT NULL COMMENT '更新时间戳', + `create_user_id` varchar(64) NOT NULL COMMENT '创建人', + `update_user_id` varchar(64) NOT NULL COMMENT '更新人', + `workspace_id` varchar(64) NOT NULL DEFAULT '' COMMENT '工作空间ID', + PRIMARY KEY (`id`) USING BTREE, + KEY `idx_name` (`name`) USING BTREE, + KEY `idx_status` (`status`) USING BTREE, + KEY `idx_workspace_id` (`workspace_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + + +/** + * 新增 device_log 表 + */ +DROP TABLE IF EXISTS `device_log`; +CREATE TABLE `device_log` ( + `id` varchar(64) NOT NULL COMMENT '主键', + `device_id` varchar(64) NOT NULL DEFAULT '' COMMENT '设备id', + `user_id` varchar(64) NOT NULL DEFAULT '' COMMENT '用户id', + `start_timestamp` bigint(20) NOT NULL COMMENT '开始时间', + `end_timestamp` bigint(20) NOT NULL COMMENT '结束时间', + `status` int(1) NOT NULL DEFAULT 1 COMMENT '状态,1:使用中;2:已结束', + `job_id` varchar(64) NOT NULL DEFAULT '' COMMENT '任务id', + `workspace_id` varchar(64) NOT NULL DEFAULT '' COMMENT '工作空间ID', + PRIMARY KEY (`id`) USING BTREE, + KEY `idx_status` (`status`) USING BTREE, + KEY `idx_device_id` (`device_id`) USING BTREE, + KEY `idx_user_id` (`user_id`) USING BTREE, + KEY `idx_job_id` (`job_id`) USING BTREE, + KEY `idx_workspace_id` (`workspace_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; |
