summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshizhendong <[email protected]>2024-08-27 15:58:41 +0800
committershizhendong <[email protected]>2024-08-27 15:58:41 +0800
commit16fc3a4bc23cb9447bd0068b085635b3cc5c4ed6 (patch)
treea02d499d06126c90b86ca837a2b8853812368e4d
parent9051cd3fac60196223031ed9d0839fe13b547304 (diff)
feat: ASW-46 新增 device 接口
-rw-r--r--src/main/java/net/geedge/asw/module/device/controller/DeviceController.java90
-rw-r--r--src/main/java/net/geedge/asw/module/device/dao/DeviceDao.java16
-rw-r--r--src/main/java/net/geedge/asw/module/device/dao/DeviceLogDao.java10
-rw-r--r--src/main/java/net/geedge/asw/module/device/entity/DeviceEntity.java53
-rw-r--r--src/main/java/net/geedge/asw/module/device/entity/DeviceLogEntity.java24
-rw-r--r--src/main/java/net/geedge/asw/module/device/service/IDeviceLogService.java8
-rw-r--r--src/main/java/net/geedge/asw/module/device/service/IDeviceService.java20
-rw-r--r--src/main/java/net/geedge/asw/module/device/service/impl/DeviceLogServiceImpl.java15
-rw-r--r--src/main/java/net/geedge/asw/module/device/service/impl/DeviceServiceImpl.java103
-rw-r--r--src/main/resources/db/mapper/device/DeviceMapper.xml79
-rw-r--r--src/main/resources/db/migration/V1.0.01__INIT_TABLES.sql47
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;