Compare commits

...

19 Commits

Author SHA1 Message Date
furongxin
8345840129 Merge branch 'cbs' of http://git.znkjfw.com/ak/zn-cloud-wcs into dev
# Conflicts:
#	pom.xml
#	yudao-module-grpc/yudao-module-grpc-biz/src/main/java/cn/iocoder/yudao/module/grpc/service/geometry/GeometryServiceImpl.java
2025-01-13 10:03:31 +08:00
cbs
491250852b 搬运任务回传 2025-01-13 09:10:19 +08:00
cbs
89fa21411d 搬运任务校验 2025-01-09 13:59:39 +08:00
cbs
9fe8245ed5 下发搬运任务 2025-01-08 10:46:50 +08:00
cbs
84980c31f7 机器人任务 2025-01-07 10:39:14 +08:00
cbs
101be5a8ad 巷道、库区、库位、车辆、设备 2025-01-04 17:34:56 +08:00
aikai
9aac8442f1 调整grpc和protobuf版本 2025-01-03 17:55:11 +08:00
cbs
0017ab3778 GRPC注册nacos 2025-01-03 16:59:48 +08:00
aikai
ed3e68278b Merge branch 'cbs' of http://git.znkjfw.com/ak/zn-cloud-wcs into aikai
# Conflicts:
#	yudao-module-grpc/yudao-module-grpc-biz/src/main/java/cn/iocoder/yudao/module/grpc/service/geometry/GeometryServiceImpl.java
2025-01-03 15:56:02 +08:00
cbs
bb03dd010f wcs设备注册 2025-01-03 15:54:13 +08:00
aikai
a780ac5139 调整grpc和protobuf版本 2025-01-03 15:52:43 +08:00
cbs
1a0881f0ad GRPC集成skywalking 2024-12-31 15:57:42 +08:00
cbs
4945cf542e MQTT服务添加日志和策略 2024-12-31 15:46:37 +08:00
cbs
363fa30fef MQTT服务发送 2024-12-31 14:47:29 +08:00
cbs
0c4ca50b3f 服务注册 2024-12-28 10:26:00 +08:00
cbs
37f93355df 调整pom文件依赖 2024-12-27 15:12:43 +08:00
cbs
3fe31b65b4 grpc客户端调通 2024-12-27 14:34:00 +08:00
cbs
9889059f53 grpc模块调试 2024-12-26 17:50:50 +08:00
cbs
48a222ee31 创建grpc模块 2024-12-25 17:56:15 +08:00
158 changed files with 10157 additions and 1 deletions

25
pom.xml
View File

@ -14,7 +14,9 @@
<!-- 各种 module 拓展 -->
<module>yudao-module-system</module>
<module>yudao-module-infra</module>
<!-- <module>yudao-module-member</module>-->
<module>yudao-module-grpc</module>
<module>yudao-module-mqtt</module>
<!-- <module>yudao-module-member</module>-->
<!-- <module>yudao-module-bpm</module>-->
<!-- <module>yudao-module-pay</module>-->
<!-- <module>yudao-module-report</module>-->
@ -32,6 +34,8 @@
<revision>2.3.0-jdk8-SNAPSHOT</revision>
<!-- Maven 相关 -->
<java.version>1.8</java.version>
<swagger.version>2.2.9</swagger.version>
<grpc.version>2.12.0.RELEASE</grpc.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version>
@ -42,6 +46,7 @@
<spring.boot.version>2.7.18</spring.boot.version>
<mapstruct.version>1.6.2</mapstruct.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mqtt.version>1.2.5</mqtt.version>
</properties>
<dependencyManagement>
@ -53,6 +58,24 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-client-spring-boot-starter</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>${mqtt.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -0,0 +1,425 @@
<?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=".dao.WareHouseLocationDao">
<resultMap id="BaseResultMap" type=".entity.WareHouseLocation">
<!--@Table ware_house_location-->
<result property="id" column="id" jdbcType="INTEGER"/>
<result property="laneId" column="lane_id" jdbcType="INTEGER"/>
<result property="laneName" column="lane_name" jdbcType="VARCHAR"/>
<result property="areaId" column="area_id" jdbcType="INTEGER"/>
<result property="areaName" column="area_name" jdbcType="VARCHAR"/>
<result property="locationNo" column="location_no" jdbcType="VARCHAR"/>
<result property="locationYaw" column="location_yaw" jdbcType="VARCHAR"/>
<result property="groupName" column="group_name" jdbcType="VARCHAR"/>
<result property="skuInfo" column="sku_info" jdbcType="VARCHAR"/>
<result property="skuBatch" column="sku_batch" jdbcType="VARCHAR"/>
<result property="skuNumber" column="sku_number" jdbcType="INTEGER"/>
<result property="trayInfo" column="tray_info" jdbcType="VARCHAR"/>
<result property="locationEnable" column="location_enable" jdbcType="INTEGER"/>
<result property="locationLock" column="location_lock" jdbcType="INTEGER"/>
<result property="locationUseStatus" column="location_use_status" jdbcType="INTEGER"/>
<result property="locationX" column="location_x" jdbcType="VARCHAR"/>
<result property="locationY" column="location_y" jdbcType="VARCHAR"/>
<result property="locationWide" column="location_wide" jdbcType="NUMERIC"/>
<result property="locationDeep" column="location_deep" jdbcType="NUMERIC"/>
<result property="locationHeight" column="location_height" jdbcType="NUMERIC"/>
<result property="locationDefaultHeight" column="location_default_height" jdbcType="NUMERIC"/>
<result property="locationTotalHeight" column="location_total_height" jdbcType="NUMERIC"/>
<result property="locationTrayHeight" column="location_tray_height" jdbcType="NUMERIC"/>
<result property="locationStorey" column="location_storey" jdbcType="INTEGER"/>
<result property="locationType" column="location_type" jdbcType="INTEGER"/>
<result property="locationNumber" column="location_number" jdbcType="INTEGER"/>
<result property="creator" column="creator" jdbcType="VARCHAR"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
<result property="updater" column="updater" jdbcType="VARCHAR"/>
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
<result property="deleted" column="deleted" jdbcType="INTEGER"/>
<result property="tenantId" column="tenant_id" jdbcType="INTEGER"/>
</resultMap>
<!--查询单个-->
<select id="queryById" resultMap="BaseResultMap">
select
id, lane_id, lane_name, area_id, area_name, location_no, location_yaw, group_name, sku_info, sku_batch, sku_number, tray_info, location_enable, location_lock, location_use_status, location_x, location_y, location_wide, location_deep, location_height, location_default_height, location_total_height, location_tray_height, location_storey, location_type, location_number, creator, create_time, updater, update_time, deleted, tenant_id
from ware_house_location
where id = #{id}
</select>
<!--查询指定行数据-->
<select id="queryAllByLimit" resultMap="BaseResultMap">
select
id, lane_id, lane_name, area_id, area_name, location_no, location_yaw, group_name, sku_info, sku_batch, sku_number, tray_info, location_enable, location_lock, location_use_status, location_x, location_y, location_wide, location_deep, location_height, location_default_height, location_total_height, location_tray_height, location_storey, location_type, location_number, creator, create_time, updater, update_time, deleted, tenant_id
from ware_house_location
<where>
<if test="id != null">
and id = #{id}
</if>
<if test="laneId != null">
and lane_id = #{laneId}
</if>
<if test="laneName != null and laneName != ''">
and lane_name = #{laneName}
</if>
<if test="areaId != null">
and area_id = #{areaId}
</if>
<if test="areaName != null and areaName != ''">
and area_name = #{areaName}
</if>
<if test="locationNo != null and locationNo != ''">
and location_no = #{locationNo}
</if>
<if test="locationYaw != null and locationYaw != ''">
and location_yaw = #{locationYaw}
</if>
<if test="groupName != null and groupName != ''">
and group_name = #{groupName}
</if>
<if test="skuInfo != null and skuInfo != ''">
and sku_info = #{skuInfo}
</if>
<if test="skuBatch != null and skuBatch != ''">
and sku_batch = #{skuBatch}
</if>
<if test="skuNumber != null">
and sku_number = #{skuNumber}
</if>
<if test="trayInfo != null and trayInfo != ''">
and tray_info = #{trayInfo}
</if>
<if test="locationEnable != null">
and location_enable = #{locationEnable}
</if>
<if test="locationLock != null">
and location_lock = #{locationLock}
</if>
<if test="locationUseStatus != null">
and location_use_status = #{locationUseStatus}
</if>
<if test="locationX != null and locationX != ''">
and location_x = #{locationX}
</if>
<if test="locationY != null and locationY != ''">
and location_y = #{locationY}
</if>
<if test="locationWide != null">
and location_wide = #{locationWide}
</if>
<if test="locationDeep != null">
and location_deep = #{locationDeep}
</if>
<if test="locationHeight != null">
and location_height = #{locationHeight}
</if>
<if test="locationDefaultHeight != null">
and location_default_height = #{locationDefaultHeight}
</if>
<if test="locationTotalHeight != null">
and location_total_height = #{locationTotalHeight}
</if>
<if test="locationTrayHeight != null">
and location_tray_height = #{locationTrayHeight}
</if>
<if test="locationStorey != null">
and location_storey = #{locationStorey}
</if>
<if test="locationType != null">
and location_type = #{locationType}
</if>
<if test="locationNumber != null">
and location_number = #{locationNumber}
</if>
<if test="creator != null and creator != ''">
and creator = #{creator}
</if>
<if test="createTime != null">
and create_time = #{createTime}
</if>
<if test="updater != null and updater != ''">
and updater = #{updater}
</if>
<if test="updateTime != null">
and update_time = #{updateTime}
</if>
<if test="deleted != null">
and deleted = #{deleted}
</if>
<if test="tenantId != null">
and tenant_id = #{tenantId}
</if>
</where>
limit #{pageable.offset}, #{pageable.pageSize}
</select>
<!--通过实体作为筛选条件查询-->
<select id="queryAll" resultMap="BaseResultMap">
select
id, lane_id, lane_name, area_id, area_name, location_no, location_yaw, group_name, sku_info, sku_batch, sku_number, tray_info, location_enable, location_lock, location_use_status, location_x, location_y, location_wide, location_deep, location_height, location_default_height, location_total_height, location_tray_height, location_storey, location_type, location_number, creator, create_time, updater, update_time, deleted, tenant_id
from zn_wcs.ware_house_location
<!--统计总行数-->
<select id="count" resultType="java.lang.Long">
select count(1)
from ware_house_location
<where>
<if test="id != null">
and id = #{id}
</if>
<if test="laneId != null">
and lane_id = #{laneId}
</if>
<if test="laneName != null and laneName != ''">
and lane_name = #{laneName}
</if>
<if test="areaId != null">
and area_id = #{areaId}
</if>
<if test="areaName != null and areaName != ''">
and area_name = #{areaName}
</if>
<if test="locationNo != null and locationNo != ''">
and location_no = #{locationNo}
</if>
<if test="locationYaw != null and locationYaw != ''">
and location_yaw = #{locationYaw}
</if>
<if test="groupName != null and groupName != ''">
and group_name = #{groupName}
</if>
<if test="skuInfo != null and skuInfo != ''">
and sku_info = #{skuInfo}
</if>
<if test="skuBatch != null and skuBatch != ''">
and sku_batch = #{skuBatch}
</if>
<if test="skuNumber != null">
and sku_number = #{skuNumber}
</if>
<if test="trayInfo != null and trayInfo != ''">
and tray_info = #{trayInfo}
</if>
<if test="locationEnable != null">
and location_enable = #{locationEnable}
</if>
<if test="locationLock != null">
and location_lock = #{locationLock}
</if>
<if test="locationUseStatus != null">
and location_use_status = #{locationUseStatus}
</if>
<if test="locationX != null and locationX != ''">
and location_x = #{locationX}
</if>
<if test="locationY != null and locationY != ''">
and location_y = #{locationY}
</if>
<if test="locationWide != null">
and location_wide = #{locationWide}
</if>
<if test="locationDeep != null">
and location_deep = #{locationDeep}
</if>
<if test="locationHeight != null">
and location_height = #{locationHeight}
</if>
<if test="locationDefaultHeight != null">
and location_default_height = #{locationDefaultHeight}
</if>
<if test="locationTotalHeight != null">
and location_total_height = #{locationTotalHeight}
</if>
<if test="locationTrayHeight != null">
and location_tray_height = #{locationTrayHeight}
</if>
<if test="locationStorey != null">
and location_storey = #{locationStorey}
</if>
<if test="locationType != null">
and location_type = #{locationType}
</if>
<if test="locationNumber != null">
and location_number = #{locationNumber}
</if>
<if test="creator != null and creator != ''">
and creator = #{creator}
</if>
<if test="createTime != null">
and create_time = #{createTime}
</if>
<if test="updater != null and updater != ''">
and updater = #{updater}
</if>
<if test="updateTime != null">
and update_time = #{updateTime}
</if>
<if test="deleted != null">
and deleted = #{deleted}
</if>
<if test="tenantId != null">
and tenant_id = #{tenantId}
</if>
</where>
</select>
<!--新增所有列-->
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
insert into ware_house_location(lane_id, lane_name, area_id, area_name, location_no, location_yaw, group_name, sku_info, sku_batch, sku_number, tray_info, location_enable, location_lock, location_use_status, location_x, location_y, location_wide, location_deep, location_height, location_default_height, location_total_height, location_tray_height, location_storey, location_type, location_number, creator, create_time, updater, update_time, deleted, tenant_id)
values (#{laneId}, #{laneName}, #{areaId}, #{areaName}, #{locationNo}, #{locationYaw}, #{groupName}, #{skuInfo}, #{skuBatch}, #{skuNumber}, #{trayInfo}, #{locationEnable}, #{locationLock}, #{locationUseStatus}, #{locationX}, #{locationY}, #{locationWide}, #{locationDeep}, #{locationHeight}, #{locationDefaultHeight}, #{locationTotalHeight}, #{locationTrayHeight}, #{locationStorey}, #{locationType}, #{locationNumber}, #{creator}, #{createTime}, #{updater}, #{updateTime}, #{deleted}, #{tenantId})
</insert>
<insert id="insertBatch" keyProperty="id" useGeneratedKeys="true">
insert into ware_house_location(lane_id, lane_name, area_id, area_name, location_no, location_yaw, group_name, sku_info, sku_batch, sku_number, tray_info, location_enable, location_lock, location_use_status, location_x, location_y, location_wide, location_deep, location_height, location_default_height, location_total_height, location_tray_height, location_storey, location_type, location_number, creator, create_time, updater, update_time, deleted, tenant_id)
values
<foreach collection="entities" item="entity" separator=",">
(#{entity.laneId}, #{entity.laneName}, #{entity.areaId}, #{entity.areaName}, #{entity.locationNo}, #{entity.locationYaw}, #{entity.groupName}, #{entity.skuInfo}, #{entity.skuBatch}, #{entity.skuNumber}, #{entity.trayInfo}, #{entity.locationEnable}, #{entity.locationLock}, #{entity.locationUseStatus}, #{entity.locationX}, #{entity.locationY}, #{entity.locationWide}, #{entity.locationDeep}, #{entity.locationHeight}, #{entity.locationDefaultHeight}, #{entity.locationTotalHeight}, #{entity.locationTrayHeight}, #{entity.locationStorey}, #{entity.locationType}, #{entity.locationNumber}, #{entity.creator}, #{entity.createTime}, #{entity.updater}, #{entity.updateTime}, #{entity.deleted}, #{entity.tenantId})
</foreach>
</insert>
<insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true">
insert into ware_house_location(lane_id, lane_name, area_id, area_name, location_no, location_yaw, group_name, sku_info, sku_batch, sku_number, tray_info, location_enable, location_lock, location_use_status, location_x, location_y, location_wide, location_deep, location_height, location_default_height, location_total_height, location_tray_height, location_storey, location_type, location_number, creator, create_time, updater, update_time, deleted, tenant_id)
values
<foreach collection="entities" item="entity" separator=",">
(#{entity.laneId}, #{entity.laneName}, #{entity.areaId}, #{entity.areaName}, #{entity.locationNo}, #{entity.locationYaw}, #{entity.groupName}, #{entity.skuInfo}, #{entity.skuBatch}, #{entity.skuNumber}, #{entity.trayInfo}, #{entity.locationEnable}, #{entity.locationLock}, #{entity.locationUseStatus}, #{entity.locationX}, #{entity.locationY}, #{entity.locationWide}, #{entity.locationDeep}, #{entity.locationHeight}, #{entity.locationDefaultHeight}, #{entity.locationTotalHeight}, #{entity.locationTrayHeight}, #{entity.locationStorey}, #{entity.locationType}, #{entity.locationNumber}, #{entity.creator}, #{entity.createTime}, #{entity.updater}, #{entity.updateTime}, #{entity.deleted}, #{entity.tenantId})
</foreach>
on duplicate key update
lane_id = values(lane_id),
lane_name = values(lane_name),
area_id = values(area_id),
area_name = values(area_name),
location_no = values(location_no),
location_yaw = values(location_yaw),
group_name = values(group_name),
sku_info = values(sku_info),
sku_batch = values(sku_batch),
sku_number = values(sku_number),
tray_info = values(tray_info),
location_enable = values(location_enable),
location_lock = values(location_lock),
location_use_status = values(location_use_status),
location_x = values(location_x),
location_y = values(location_y),
location_wide = values(location_wide),
location_deep = values(location_deep),
location_height = values(location_height),
location_default_height = values(location_default_height),
location_total_height = values(location_total_height),
location_tray_height = values(location_tray_height),
location_storey = values(location_storey),
location_type = values(location_type),
location_number = values(location_number),
creator = values(creator),
create_time = values(create_time),
updater = values(updater),
update_time = values(update_time),
deleted = values(deleted),
tenant_id = values(tenant_id)
</insert>
<!--通过主键修改数据-->
<update id="update">
update ware_house_location
<set>
<if test="laneId != null">
lane_id = #{laneId},
</if>
<if test="laneName != null and laneName != ''">
lane_name = #{laneName},
</if>
<if test="areaId != null">
area_id = #{areaId},
</if>
<if test="areaName != null and areaName != ''">
area_name = #{areaName},
</if>
<if test="locationNo != null and locationNo != ''">
location_no = #{locationNo},
</if>
<if test="locationYaw != null and locationYaw != ''">
location_yaw = #{locationYaw},
</if>
<if test="groupName != null and groupName != ''">
group_name = #{groupName},
</if>
<if test="skuInfo != null and skuInfo != ''">
sku_info = #{skuInfo},
</if>
<if test="skuBatch != null and skuBatch != ''">
sku_batch = #{skuBatch},
</if>
<if test="skuNumber != null">
sku_number = #{skuNumber},
</if>
<if test="trayInfo != null and trayInfo != ''">
tray_info = #{trayInfo},
</if>
<if test="locationEnable != null">
location_enable = #{locationEnable},
</if>
<if test="locationLock != null">
location_lock = #{locationLock},
</if>
<if test="locationUseStatus != null">
location_use_status = #{locationUseStatus},
</if>
<if test="locationX != null and locationX != ''">
location_x = #{locationX},
</if>
<if test="locationY != null and locationY != ''">
location_y = #{locationY},
</if>
<if test="locationWide != null">
location_wide = #{locationWide},
</if>
<if test="locationDeep != null">
location_deep = #{locationDeep},
</if>
<if test="locationHeight != null">
location_height = #{locationHeight},
</if>
<if test="locationDefaultHeight != null">
location_default_height = #{locationDefaultHeight},
</if>
<if test="locationTotalHeight != null">
location_total_height = #{locationTotalHeight},
</if>
<if test="locationTrayHeight != null">
location_tray_height = #{locationTrayHeight},
</if>
<if test="locationStorey != null">
location_storey = #{locationStorey},
</if>
<if test="locationType != null">
location_type = #{locationType},
</if>
<if test="locationNumber != null">
location_number = #{locationNumber},
</if>
<if test="creator != null and creator != ''">
creator = #{creator},
</if>
<if test="createTime != null">
create_time = #{createTime},
</if>
<if test="updater != null and updater != ''">
updater = #{updater},
</if>
<if test="updateTime != null">
update_time = #{updateTime},
</if>
<if test="deleted != null">
deleted = #{deleted},
</if>
<if test="tenantId != null">
tenant_id = #{tenantId},
</if>
</set>
where id = #{id}
</update>
<!--通过主键删除-->
<delete id="deleteById">
delete from ware_house_location where id = #{id}
</delete>
</mapper>

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.common.util.date;
import cn.hutool.core.date.LocalDateTimeUtil;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
@ -27,6 +28,11 @@ public class DateUtils {
public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss";
public static String getYearMonthDay() {
LocalDate currentDate = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
return currentDate.format(formatter);
}
/**
* LocalDateTime 转换成 Date
*

25
yudao-module-grpc/pom.xml Normal file
View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<modules>
<module>yudao-module-grpc-api</module>
<module>yudao-module-grpc-biz</module>
<module>yudao-module-grpc-lib</module>
</modules>
<artifactId>yudao-module-grpc</artifactId>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<description>
grpc 模块下,与机器人接口调用。
</description>
</project>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-grpc</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-grpc-api</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
grpc 模块 API暴露给其它模块调用
</description>
<dependencies>
<!--<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-common</artifactId>
</dependency>-->
<!-- Web 相关 -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<scope>provided</scope> <!-- 设置为 provided主要是 PageParam 使用到 -->
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<optional>true</optional>
</dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,17 @@
package cn.iocoder.yudao.module.grpc.api;
import cn.iocoder.yudao.module.grpc.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "GRPC 服务 - 调用机器人")
public interface GrpcServiceApi {
@PostMapping("/grpc/robot/onVehiclePoseUpdatedG")
@Operation(summary = "订阅车体位姿更新")
String onVehiclePoseUpdated();
}

View File

@ -0,0 +1,17 @@
package cn.iocoder.yudao.module.grpc.enums;
public class ApiConstants {
/**
* 服务名
*
* 注意需要保证和 spring.application.name 保持一致
*/
public static final String NAME = "grpc-server";
public static final String PREFIX = "/rpc-api/grpc";
public static final String VERSION = "1.0.0";
}

View File

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-grpc</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-grpc-biz</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
grpc 模块下,与机器人通信。
</description>
<dependencies>
<!-- Spring Cloud 基础 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!-- 依赖服务 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-system-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-grpc-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-grpc-lib</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>0.2.12</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
</dependency>
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-client-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<!-- 设置构建的 jar 包名 -->
<finalName>${project.artifactId}</finalName>
<plugins>
<!-- 打包 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
</goals>
</execution>
</executions>
</plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>8</source><target>8</target></configuration></plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,13 @@
package cn.iocoder.yudao.module.grpc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class GrpcServerApplication {
public static void main(String[] args) {
SpringApplication.run(GrpcServerApplication.class, args);
}
}

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.grpc.api;
import cn.iocoder.yudao.module.grpc.service.geometry.GeometryService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController // 提供 RESTful API 接口 Feign 调用
@Validated
public class GrpcServiceImpl implements GrpcServiceApi {
@Resource
private GeometryService geometryService;
@Override
public String onVehiclePoseUpdated() {
return geometryService.onVehiclePoseUpdated();
}
}

View File

@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.grpc.controller;
import cn.iocoder.yudao.module.grpc.service.geometry.GeometryService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
@Tag(name = "测试demo")
@RestController
@RequestMapping("/grpc/robot")
//@Validated
public class GeometryController {
@Resource
private GeometryService geometryService;
@PostMapping("/onVehiclePoseUpdated")
@Operation(summary = "测试GRPC调用")
@PermitAll
public String onVehiclePoseUpdated() {
return geometryService.onVehiclePoseUpdated();
}
}

View File

@ -0,0 +1,5 @@
package cn.iocoder.yudao.module.grpc.service.geometry;
public interface GeometryService {
String onVehiclePoseUpdated();
}

View File

@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.grpc.service.geometry;
import com.google.protobuf.DoubleValue;
import device.proto.robotics.nav.ChassisNavigationControlService;
import device.proto.robotics.nav.ChassisNavigationServiceGrpc;
import io.grpc.Channel;
import lombok.extern.slf4j.Slf4j;
//import net.devh.springboot.autoconfigure.grpc.client.GrpcClient;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.stereotype.Service;
import java.util.Iterator;
@Slf4j
@Service
public class GeometryServiceImpl implements GeometryService{
@GrpcClient("ChassisNavigationService")
private Channel serverChannel;
@Override
public String onVehiclePoseUpdated() {
log.info("测试GRPC连接");
ChassisNavigationServiceGrpc.ChassisNavigationServiceBlockingStub myServiceStub
= ChassisNavigationServiceGrpc.newBlockingStub(this.serverChannel);
Iterator<ChassisNavigationControlService.Response> responseIterator = myServiceStub.onVehiclePoseUpdated(null);
while (responseIterator.hasNext()) {
log.info("机车推送的消息 :{}",responseIterator.next());
}
DoubleValue build = DoubleValue.newBuilder().build();
ChassisNavigationControlService.Response response = myServiceStub.forkControl(build);
return response.toString();
}
}

View File

@ -0,0 +1,57 @@
# grpc配置
grpc:
# grpc clienT相关配置
client:
# 是服务端配置的名字GrpcClient注解会用到
ChassisNavigationService:
address: 'static://192.168.10.78:6914'
# gRPC服务端地址
# host: 192.168.10.78
# port: 6914
# 是否开启保持连接(长连接)
enableKeepAlive: true
# 保持连接时长默认20s
keepAliveTimeout: 100
# 没有RPC调用时是否保持连接默认false可禁用避免额外消耗CPU
keepAliveWithoutCalls: false
# 客户端负载均衡策略(round_robin默认, pick_first)
defaultLoadBalancingPolicy: round_robin
# 通信类型
# plaintext | plaintext_upgrade | tls
# 明文通信且http/2 | 明文通信且升级http/1.1为http/2 | 使用TLSALPN/NPN通信
negotiationType: plaintext
spring:
cloud:
nacos:
server-addr: localhost:8848 # Nacos 服务器地址
username: # Nacos 账号
password: # Nacos 密码
discovery: # 【配置中心】配置项
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
metadata:
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
config: # 【注册中心】配置项
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
# Lock4j 配置项
lock4j:
acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒
--- #################### 监控相关配置 ####################
# Actuator 监控端点的配置项
management:
endpoints:
web:
base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
exposure:
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。

View File

@ -0,0 +1,30 @@
spring:
application:
name: grpc-server
main:
allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。
allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务
profiles:
active: local
mvc:
pathmatch:
matching-strategy: ANT_PATH_MATCHER # 解决 SpringFox 与 SpringBoot 2.6.x 不兼容的问题,参见 SpringFoxHandlerProviderBeanPostProcessor 类
# Jackson 配置项
jackson:
serialization:
write-dates-as-timestamps: true # 设置 LocalDateTime 的格式,使用时间戳
write-date-timestamps-as-nanoseconds: false # 设置不使用 nanoseconds 的格式。例如说 1611460870.401,而是直接 1611460870401
write-durations-as-timestamps: true # 设置 Duration 的格式,使用时间戳
fail-on-empty-beans: false # 允许序列化无属性的 Bean
server:
port: 48084
debug: false

View File

@ -0,0 +1,23 @@
--- #################### 注册中心相关配置 ####################
spring:
cloud:
nacos:
server-addr: 127.0.0.1:8848
discovery:
namespace: dev # 命名空间。这里使用 dev 开发环境
metadata:
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
--- #################### 配置中心相关配置 ####################
spring:
cloud:
nacos:
# Nacos Config 配置项,对应 NacosConfigProperties 配置属性类
config:
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
namespace: dev # 命名空间 dev 的ID不能直接使用 dev 名称。创建命名空间的时候需要指定ID为 dev这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
name: ${spring.application.name} # 使用的 Nacos 配置集的 dataId默认为 spring.application.name
file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties

View File

@ -0,0 +1,23 @@
--- #################### 注册中心相关配置 ####################
spring:
cloud:
nacos:
server-addr: 127.0.0.1:8848
discovery:
namespace: dev # 命名空间。这里使用 dev 开发环境
metadata:
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
--- #################### 配置中心相关配置 ####################
spring:
cloud:
nacos:
# Nacos Config 配置项,对应 NacosConfigProperties 配置属性类
config:
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
namespace: dev # 命名空间 dev 的ID不能直接使用 dev 名称。创建命名空间的时候需要指定ID为 dev这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
name: ${spring.application.name} # 使用的 Nacos 配置集的 dataId默认为 spring.application.name
file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties

View File

@ -0,0 +1,23 @@
--- #################### 注册中心相关配置 ####################
spring:
cloud:
nacos:
server-addr: 127.0.0.1:8848
discovery:
namespace: prod # 命名空间。这里使用 dev 开发环境
metadata:
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
--- #################### 配置中心相关配置 ####################
spring:
cloud:
nacos:
# Nacos Config 配置项,对应 NacosConfigProperties 配置属性类
config:
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
namespace: prod # 命名空间 dev 的ID不能直接使用 dev 名称。创建命名空间的时候需要指定ID为 dev这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
name: ${spring.application.name} # 使用的 Nacos 配置集的 dataId默认为 spring.application.name
file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties

View File

@ -0,0 +1,15 @@
spring:
application:
name: grpc-server
profiles:
active: local #local
# active: prod
server:
port: 48084
# 日志文件配置。注意,如果 logging.file.name 不放在 bootstrap.yaml 配置文件,而是放在 application.yaml 中,会导致出现 LOG_FILE_IS_UNDEFINED 文件
logging:
file:
name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径

View File

@ -0,0 +1,76 @@
<configuration>
<!-- 引用 Spring Boot 的 logback 基础配置 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<!-- 变量 yudao.info.base-package基础业务包 -->
<springProperty scope="context" name="yudao.info.base-package" source="yudao.info.base-package"/>
<!-- 格式化输出:%d 表示日期,%X{tid} SkWalking 链路追踪编号,%thread 表示线程名,%-5level级别从左显示 5 个字符宽度,%msg日志消息%n是换行符 -->
<property name="PATTERN_DEFAULT" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} | %highlight(${LOG_LEVEL_PATTERN:-%5p} ${PID:- }) | %boldYellow(%thread [%tid]) %boldGreen(%-40.40logger{39}) | %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
<!-- 控制台 Appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">     
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
</appender>
<!-- 文件 Appender -->
<!-- 参考 Spring Boot 的 file-appender.xml 编写 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
<!-- 日志文件名 -->
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 滚动后的日志文件名 -->
<fileNamePattern>${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz}</fileNamePattern>
<!-- 启动服务时,是否清理历史日志,一般不建议清理 -->
<cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
<!-- 日志文件,到达多少容量,进行滚动 -->
<maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
<!-- 日志文件的总大小0 表示不限制 -->
<totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
<!-- 日志文件的保留天数 -->
<maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-30}</maxHistory>
</rollingPolicy>
</appender>
<!-- 异步写入日志,提升性能 -->
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志。默认的,如果队列的 80% 已满,则会丢弃 TRACT、DEBUG、INFO 级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能。默认值为 256 -->
<queueSize>256</queueSize>
<appender-ref ref="FILE"/>
</appender>
<!-- SkyWalking GRPC 日志收集实现日志中心。注意SkyWalking 8.4.0 版本开始支持 -->
<appender name="GRPC" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
</appender>
<!-- 本地环境 -->
<springProfile name="local">
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="GRPC"/> <!-- 本地环境下,如果不想接入 SkyWalking 日志服务,可以注释掉本行 -->
<appender-ref ref="ASYNC"/> <!-- 本地环境下,如果不想打印日志,可以注释掉本行 -->
</root>
</springProfile>
<!-- 其它环境 -->
<springProfile name="dev,test,stage,prod,default">
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="ASYNC"/>
<appender-ref ref="GRPC"/>
</root>
</springProfile>
</configuration>

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-grpc</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-grpc-lib</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
grpc 模块 LIB生成GRPC的proto文件
</description>
<properties>
<!--grpc版本号-->
<grpc.version>1.64.0</grpc.version>
<!--protobuf 版本号-->
<protobuf.version>3.25.3</protobuf.version>
</properties>
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-core</artifactId>
<version>1.64.0</version> <!-- 确保版本一致 -->
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.64.0</version> <!-- 确保版本一致 -->
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.5.0.Final</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}
</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,67 @@
syntax = "proto3";
package device.proto.model.common;
option csharp_namespace = "Al.Proto.Model.Common";
//import "google/protobuf/struct.proto";
//2d点
message Point2d {
double x = 1;
double y = 2;
}
//2d位姿
message Pose2d {
double x = 1;//x
double y = 2;//y
double yaw = 3;//
}
//2d直线
message Line2d {
repeated Point2d points = 1;
}
//
message Polygon2d {
repeated Point2d vertex = 1;
}
message Quaternion {
double x = 1;
double y = 2;
double z = 3;
double w = 4;
}
message Rotation {
double roll = 1;
double pitch = 2;
double yaw = 3;
}
message EulerPose {
option deprecated = true;
double x = 1;
double y = 2;
double z = 3;
double roll = 4;
double pitch = 5;
double yaw = 6;
}
message Vector3d {
double x = 1;
double y = 2;
double z = 3;
}
message Pose {
double x = 1;
double y = 2;
double z = 3;
double roll = 4;
double pitch = 5;
double yaw = 6;
}

View File

@ -0,0 +1,138 @@
syntax = "proto3";
package device.proto.model.common.schema;
option csharp_namespace = "Al.Proto.Model.Common.Schema";
//
message EnumValue {
//
int64 value = 1;
//
string text = 2;
//
string remark = 3;
}
//
message TypeAttribute {
//
enum Category {
//
UNKNOWN = 0;
//
BOOLEAN = 1;
//8
INT8 = 2;
//8
UINT8 = 3;
//16
INT16 = 4;
//16
UINT16 = 5;
//32
INT32 = 6;
//32
UINT32 = 7;
//64
INT64 = 8;
//64
UINT64 = 9;
//
FLOAT = 10;
//
STRING = 15;
//
ENUM = 20;
///
ARRAY = 25;
//
MAP = 26;
//
VARIANT = 29;
//
OBJECT = 30;
}
//
message InitialValue {
oneof kind_of_initial {
//
double floating = 1;
//
uint64 integer = 2;
//
string text = 3;
//
EnumValue enum_value = 4;
//
bool boolean = 5;
}
}
//
message OptionValue {
oneof kind_of_value {
//
double floating = 1;
//
uint64 integer = 2;
//
string text = 3;
//
EnumValue enum_value = 4;
}
}
//
string definition = 1;
//
Category category = 2;
//
string remark = 3;
//
InitialValue initial = 4;
//
repeated string dependencies = 5;
//
string note = 6;
///
bool necessary = 11;
//
bool readonly = 13;
//
string pattern = 15;
oneof kind_of_range_min {
//
int64 min_integer_value = 17;
//
double min_float_value = 18;
}
oneof kind_of_range_max {
//
uint64 max_integer_value = 19;
//
double max_float_value = 20;
}
//
bool extendable = 21;
//
repeated OptionValue options = 22;
//
map<string, string> decorators = 23;
}
//
message TypeSchema {
//
TypeAttribute attr = 1;
//
map<string, TypeAttribute> fields = 4;
}

View File

@ -0,0 +1,45 @@
syntax = "proto3";
package device.proto.model.common;
option csharp_namespace = "Al.Proto.Model.Common";
//import "google/protobuf/struct.proto";
import "model/common/geometry.proto";
//
message Exception {
//
string rtti = 1;
//
string message = 2;
//
int32 code = 3;
//
string category = 4;
}
message Nothing {
}
//
message Strings {
repeated string values = 1;
}
//
message Indexes {
repeated int32 values = 1;
}
//
message Number {
oneof variant {
int32 i32 = 1;
uint32 u32 = 2;
int64 i64 = 3;
int64 u64 = 4;
double floating = 5;
}
}

View File

@ -0,0 +1,71 @@
syntax = "proto3";
package device.proto.robotics.nav;
option csharp_namespace = "Al.Proto.Api.Robotics.Nav";
import "google/protobuf/empty.proto";
import "google/protobuf/wrappers.proto";
import "google/protobuf/struct.proto";
//2d位姿
message Pose2d {
double x = 1; //x
double y = 2; //y
double yaw = 3; //
}
message NavigateThroughPosesRequest {
repeated Pose2d pose2ds = 1;
}
//
message JoyAgvRequest {
//x方向的速度
double vx = 1;
//y方向的速度
double vy = 2;
//
double angle = 3;
}
message Response {
//
string status_code = 1;
//
string message = 2;
//
google.protobuf.Struct data = 3;
}
service ChassisNavigationService {
//姿
rpc OnVehiclePoseUpdated(google.protobuf.Empty) returns (stream Response) {}
//姿
rpc OnTrackingPoseUpdated(google.protobuf.Empty) returns (stream Response) {}
//姿
rpc NavigateToPose(Pose2d) returns (Response) {}
//
rpc NavigateThroughPoses(NavigateThroughPosesRequest) returns (Response) {}
//
rpc ForkControl(google.protobuf.DoubleValue) returns (Response) {}
//
rpc OnRobotStateUpdated(google.protobuf.Empty) returns (stream Response) {}
//IMU数据的更新
rpc OnChassesMainImuDataUpdated(google.protobuf.Empty) returns (stream Response) {}
//
rpc OnChassesOdometryUpdated(google.protobuf.Empty) returns (stream Response) {}
//
rpc OnPerceptionLaserOdometryUpdated(google.protobuf.Empty) returns (stream Response) {}
//
rpc OnWheelOdometryUpdated(google.protobuf.Empty) returns (stream Response) {}
//
rpc OnRobotFaultStatusUpdated(google.protobuf.Empty) returns (stream Response) {}
//
rpc JoyAgvControl(JoyAgvRequest) returns (Response) {}
//
rpc JoyForkControl(google.protobuf.Struct) returns (Response) {}
}

24
yudao-module-mqtt/pom.xml Normal file
View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<modules>
<module>yudao-module-mqtt-api</module>
<module>yudao-module-mqtt-biz</module>
</modules>
<artifactId>yudao-module-mqtt</artifactId>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<description>
mqtt 模块,主要提供能力:
1. 与设备通信
</description>
</project>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-mqtt</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-mqtt-api</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
mqtt 模块 API暴露给其它模块调用
</description>
<dependencies>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-common</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<scope>provided</scope>
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<optional>true</optional>
</dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.mqtt.api.task;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAcceptTaskDTO;
import cn.iocoder.yudao.module.mqtt.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import javax.validation.Valid;
import java.util.List;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "MQTT 服务 - 参数配置")
public interface RobotTaskApi {
String PREFIX = ApiConstants.PREFIX + "/config";
@PostMapping(PREFIX + "/distribute/tasks")
@Operation(summary = "下发任务给车机")
CommonResult<String> sendTaskToRobot(@Valid @RequestBody List<RobotAcceptTaskDTO> robotTaskDOS );
}

View File

@ -0,0 +1,10 @@
package cn.iocoder.yudao.module.mqtt.api.task.dto;
import lombok.Data;
@Data
public class Pose2ds {
private String x;
private String y;
private String yaw;
}

View File

@ -0,0 +1,17 @@
package cn.iocoder.yudao.module.mqtt.api.task.dto;
import lombok.Data;
import java.util.List;
@Data
public class RobotAcceptTaskDTO {
/**
* 订单id
*/
private String order_id;
private String order_type = "";
private String topic;
private List<RobotAcceptTaskData> data;
}

View File

@ -0,0 +1,15 @@
package cn.iocoder.yudao.module.mqtt.api.task.dto;
import lombok.Data;
import java.util.List;
@Data
public class RobotAcceptTaskData {
private String serial;
private String command_id;
private String command_type;
private List<Pose2ds> pose2ds;
private String target_height;
private String parm;
}

View File

@ -0,0 +1,16 @@
package cn.iocoder.yudao.module.mqtt.enums;
import cn.iocoder.yudao.framework.common.enums.RpcConstants;
public class ApiConstants {
/**
* 服务名
*
* 注意需要保证和 spring.application.name 保持一致
*/
public static final String NAME = "mqtt-server";
public static final String PREFIX = RpcConstants.RPC_API_PREFIX + "/mqtt";
public static final String VERSION = "1.0.0";
}

View File

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-mqtt</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-mqtt-biz</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
mqtt 模块,主要提供能力:
1. 与设备通信
</description>
<dependencies>
<!-- Spring Cloud 基础 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-env</artifactId>
</dependency>
<!-- 依赖服务 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-system-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-mqtt-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-mqtt</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<!-- 设置构建的 jar 包名 -->
<finalName>${project.artifactId}</finalName>
<plugins>
<!-- 打包 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,14 @@
package cn.iododer.yudao.module.mqtt;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MqttServerApplication {
public static void main(String[] args) {
SpringApplication.run(MqttServerApplication.class, args);
// 1在DefineSubTopicEnum添加自己的topic
// 2MqttFactory的getMqttFactory对应topic编写实现的策略实现类
// 3编写对应的impl实现类
}
}

View File

@ -0,0 +1,41 @@
package cn.iododer.yudao.module.mqtt.api.task;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.mqtt.api.task.RobotTaskApi;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAcceptTaskDTO;
import cn.iododer.yudao.module.mqtt.util.MqttUtils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@RestController // 提供 RESTful API 接口 Feign 调用
@Validated
@Slf4j
public class RobotTaskApiImpl implements RobotTaskApi {
@Autowired
private MqttUtils mqttUtils;
@Override
public CommonResult<String> sendTaskToRobot(List<RobotAcceptTaskDTO> robotTaskDOS) {
String str ="SUCCESS";
for (RobotAcceptTaskDTO robotTaskDO : robotTaskDOS) {
log.info("发送MQTT消息 :{}",JSON.toJSONString(robotTaskDO));
try {
mqttUtils.pub( robotTaskDO.getTopic(), JSON.toJSONString(robotTaskDO));
} catch (Exception e) {
log.info("消息发送异常 :{}",e.getMessage());
str ="FAIL";
}
}
return success(str);
}
}

View File

@ -0,0 +1,30 @@
package cn.iododer.yudao.module.mqtt.config;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 初始化执行
*/
@Slf4j
@Order(1)
@Component
public class MqttBeforePoint implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
// 初始化Mqtt连接
try {
MqttFactory.getInstance();
log.info("[MQTT]初始化成功");
} catch (MqttException e) {
log.info("[MQTT]初始化失败。考虑是否服务端掉线");
MqttFactory.reconnect();
}
}
}

View File

@ -0,0 +1,56 @@
package cn.iododer.yudao.module.mqtt.config;
import cn.iododer.yudao.module.mqtt.service.MqttService;
import cn.iododer.yudao.module.mqtt.service.RobotTaskStatusServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttAsyncClient;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
/**
* MQTT回调
*/
@Slf4j
@Configuration
public class MqttCallBack implements MqttCallback {
/**
* 与服务器断开的回调
*/
@Override
public void connectionLost(Throwable throwable) {
log.info("[MQTT]断开了与服务端的连接。考虑是否服务端掉线 or 回调参数解析报错 or 无默认sub");
// 执行自动重连
MqttFactory.reconnect();
}
/**
* 消息到达的回调
*
* @param topic 话题
* @param mqttMessage 消息内容
*/
@Override
public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
String msg = new String(mqttMessage.getPayload());
log.info("[MQTT]接收当前消息为 :{}", msg);
MqttService mqttService = MqttFactory.getMqttFactory(topic);
mqttService.analysisMessage(msg);
}
/**
* 消息发布成功的回调
*
* @param token token
*/
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
IMqttAsyncClient client = token.getClient();
// log.info("[MQTT]{}:消息发布成功!", client.getClientId());
}
}

View File

@ -0,0 +1,147 @@
package cn.iododer.yudao.module.mqtt.config;
//import cn.iododer.yudao.module.mqtt.customer.MqttMessageListener;
import cn.iododer.yudao.module.mqtt.enums.DefineSubTopicEnum;
import cn.iododer.yudao.module.mqtt.service.MqttService;
import cn.iododer.yudao.module.mqtt.service.RobotGenericsStatusServiceImpl;
import cn.iododer.yudao.module.mqtt.service.RobotTaskStatusServiceImpl;
import cn.iododer.yudao.module.mqtt.service.RobotStatusServiceImpl;
import cn.iododer.yudao.module.mqtt.util.BeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;
/**
* Mqtt 工厂类
*/
@Slf4j
@Component
public class MqttFactory {
@Autowired
private MqttProperties config;
private static MqttFactory factory;
private static MqttClient client;
@PostConstruct
public void init() {
factory = this;
factory.config = this.config;
}
/**
* 获取客户端实例
* 单例模式存在即返回不存在则初始化
*
* @return client
* @throws MqttException 此处刻意抛出异常否则无法执行断线重连
*/
public static MqttClient getInstance() throws MqttException {
if (client == null) {
connect();
}
return client;
}
/**
* 清空客户端实例
* mqtt 断开连接时需清空 clientId再执行断线重连
*/
public static void clear() {
client = null;
}
/**
* 断线重连方法
*/
public static void reconnect() {
int count = 0;
while (true) {
clear();
++ count;
try {
log.info("----------------[MQTT]即将执行自动重连----------------");
getInstance();
log.info("----------------[MQTT]自动重连成功----------------");
break;
} catch (MqttException e) {
log.error("----------------[MQTT]自动重连失败,当前为第 {} 次尝试----------------", count);
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException ex) {
log.error("----------------[MQTT]自动重连,休眠失败!----------------", e);
}
}
}
}
/**
* 客户端连接服务端
*
* @throws MqttException 此处刻意抛出异常否则无法执行断线重连
*/
private static void connect() throws MqttException {
// 创建MQTT客户端对象
client = new MqttClient(factory.config.getHostUrl(), factory.config.getClientId(), new MemoryPersistence());
// 连接设置
MqttConnectOptions options = new MqttConnectOptions();
// 是否清空session设置false表示服务器会保留客户端的连接记录订阅主题qos,客户端重连之后能获取到服务器在客户端断开连接期间推送的消息
// 设置为true表示每次连接服务器都是以新的身份
options.setCleanSession(true);
// 设置连接用户名
options.setUserName(factory.config.getUsername());
// 设置连接密码
options.setPassword(factory.config.getPassword().toCharArray());
// 设置超时时间单位为秒
options.setConnectionTimeout(100);
// 设置心跳时间 单位为秒表示服务器每隔 20 秒的时间向客户端发送心跳判断客户端是否在线
options.setKeepAliveInterval(20);
// 设置遗嘱消息的话题若客户端和服务器之间的连接意外断开服务器将发布客户端的遗嘱信息
options.setWill("willTopic", (factory.config.getClientId() + "MQTT客户端与服务器断开连接").getBytes(), 0, false);
// 设置回调
client.setCallback(new MqttCallBack());
client.connect(options);
// 设置默认订阅主题
// 消息等级与主题数组一一对应
int[] qos = DefineSubTopicEnum.queryAllQos();
// 主题
String[] topics = DefineSubTopicEnum.queryAllTopic();
// 订阅主题
client.subscribe(topics, qos);
}
/**
* 根据topic去实现自己的业务
* @param topic
* @return
*/
public static MqttService getMqttFactory(String topic){
DefineSubTopicEnum defineSubTopicEnum = DefineSubTopicEnum.getDefineSubTopicEnumByTopic(topic);
switch (defineSubTopicEnum){
case ROBOT_GENERICS_STATUS:
return BeanUtils.getBean(RobotGenericsStatusServiceImpl.class);
case ROBOT_STATUS:
return BeanUtils.getBean(RobotStatusServiceImpl.class);
default :
// case ROBOT_TASK_STATUS:
return BeanUtils.getBean(RobotTaskStatusServiceImpl.class);
}
}
}

View File

@ -0,0 +1,40 @@
package cn.iododer.yudao.module.mqtt.config;
import cn.hutool.core.util.IdUtil;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* Mqtt Config
* * 备注以下刻意将 defaultClientIdclientId 区分使用
* * 防止断线重连的时候clientId 被重复拼接时间戳
*/
@Getter
@Configuration
public class MqttProperties {
@Value("${mqtt.host}")
private String hostUrl;
@Value("${mqtt.username}")
private String username;
@Value("${mqtt.password}")
private String password;
@Value("${mqtt.clientId}")
private String clientId;
@Value("${mqtt.qos}")
private int qos;
private String clientUUId;
public String getClientId() {
if (clientUUId == null) {
clientUUId = clientId + IdUtil.fastSimpleUUID();
}
return clientUUId;
}
}

View File

@ -0,0 +1,33 @@
package cn.iododer.yudao.module.mqtt.controller;
import cn.iododer.yudao.module.mqtt.util.MqttUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Tag(name = "MQTT通讯")
@RestController
@RequestMapping("/mqtt")
@Validated
@Slf4j
public class MqttController {
@Autowired
private MqttUtils mqttUtils;
@PostMapping("/pub")
public String pub(String topic, String msg) {
try {
mqttUtils.pub( topic, msg);
return "发送成功!";
} catch (Exception e) {
log.error("消息发送失败!", e);
}
return "发送成功!";
}
}

View File

@ -0,0 +1,71 @@
package cn.iododer.yudao.module.mqtt.enums;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import java.util.ArrayList;
import java.util.List;
/**
* 默认订阅的话题 -- 枚举类
*/
@Getter
@AllArgsConstructor
public enum DefineSubTopicEnum {
//qos 0-至多1次1-至少1次2-正好一次
ROBOT_STATUS("ROBOT_STATUS", 0,"点位"),
ROBOT_TASK_STATUS("ROBOT_TASK_STATUS", 0,"机器人任务完成上报"),
ROBOT_GENERICS_STATUS("ROBOT_GENERICS_STATUS", 0,"机器人异常");
private final String topic;
private final int qos;
private final String msg;
/**
* 获取所有话题名
*
* @return topicArr
*/
public static String[] queryAllTopic() {
List<String> topicList = new ArrayList<>();
for (DefineSubTopicEnum item : DefineSubTopicEnum.values()) {
topicList.add(item.getTopic());
}
String[] topicArr = new String[topicList.size()];
topicArr = topicList.toArray(topicArr);
return topicArr;
}
/**
* 获取所有qos
*
* @return qosArr
*/
public static int[] queryAllQos() {
List<Integer> qosList = new ArrayList<>();
for (DefineSubTopicEnum item : DefineSubTopicEnum.values()) {
qosList.add(item.getQos());
}
int[] qosArr = new int[qosList.size()];
qosArr = qosList.stream().mapToInt(Integer::intValue).toArray();
return qosArr;
}
public static DefineSubTopicEnum getDefineSubTopicEnumByTopic(String topic) {
for (DefineSubTopicEnum item : DefineSubTopicEnum.values()) {
if (item.getTopic().equals(topic)) {
return item;
}
}
return null;
}
}

View File

@ -0,0 +1,12 @@
package cn.iododer.yudao.module.mqtt.framework.system;
import cn.iocoder.yudao.module.system.api.robot.RobotGenericsStatusApi;
import cn.iocoder.yudao.module.system.api.robot.RobotStatusApi;
import cn.iocoder.yudao.module.system.api.robot.RobotTaskStatusApi;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
@EnableFeignClients(clients = {RobotGenericsStatusApi.class, RobotTaskStatusApi.class, RobotStatusApi.class})
public class SystemConfiguration {
}

View File

@ -0,0 +1,5 @@
package cn.iododer.yudao.module.mqtt.service;
public interface MqttService {
void analysisMessage(String message);
}

View File

@ -0,0 +1,15 @@
package cn.iododer.yudao.module.mqtt.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class RobotGenericsStatusServiceImpl implements MqttService{
@Override
public void analysisMessage(String message) {
log.info("处理RobotGenericsStatusServiceImpl的消息 :{}",message);
}
}

View File

@ -0,0 +1,23 @@
package cn.iododer.yudao.module.mqtt.service;
import cn.iocoder.yudao.module.system.api.robot.RobotStatusApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Slf4j
@Service
public class RobotStatusServiceImpl implements MqttService{
@Resource
private RobotStatusApi robotStatusApi;
/**
* 机器人点位
* @param message
*/
@Override
public void analysisMessage(String message) {
log.info("处理RobotStatusServiceImpl的消息 :{}",message);
}
}

View File

@ -0,0 +1,23 @@
package cn.iododer.yudao.module.mqtt.service;
import cn.iocoder.yudao.module.system.api.robot.RobotTaskStatusApi;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotCompleteTaskDTO;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class RobotTaskStatusServiceImpl implements MqttService {
@Autowired
private RobotTaskStatusApi robotTaskStatusApi;
@Override
public void analysisMessage(String message) {
log.info("处理RobotTaskStatusServiceImpl的消息 :{}",message);
RobotCompleteTaskDTO robotCompleteTask = JSON.parseObject(message , RobotCompleteTaskDTO.class);
robotTaskStatusApi.robotDoneTask(robotCompleteTask);
}
}

View File

@ -0,0 +1,31 @@
package cn.iododer.yudao.module.mqtt.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class BeanUtils implements ApplicationContextAware {
protected static ApplicationContext applicationContext ;
@Override
public void setApplicationContext(ApplicationContext arg0) throws BeansException {
if (applicationContext == null) {
applicationContext = arg0;
}
}
public static Object getBean(String name) {
//name表示其他要注入的注解name名
return applicationContext.getBean(name);
}
/**
* 拿到ApplicationContext对象实例后就可以手动获取Bean的注入实例对象
*/
public static <T> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
}

View File

@ -0,0 +1,61 @@
package cn.iododer.yudao.module.mqtt.util;
import cn.iododer.yudao.module.mqtt.config.MqttFactory;
import cn.iododer.yudao.module.mqtt.config.MqttProperties;
import org.eclipse.paho.client.mqttv3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
@Component
public class MqttUtils {
@Autowired
private MqttProperties config;
/**
* 发布消息
*
* @param qos 0-至多1次1-至少1次2-一次
* @param retained 是否保留true-sub重新连接mqtt服务端时总能拿到该主题的最新消息false-sub重新连接mqtt服务端时只能拿到连接后发布的消息
* @param topic 话题
* @param message 消息内容
*/
public void pub(String topic, String message) throws MqttException {
// 获取客户端实例
MqttClient client = MqttFactory.getInstance();
MqttMessage mqttMessage = new MqttMessage();
mqttMessage.setQos(config.getQos());
mqttMessage.setRetained(false);
// 此处必须指明编码方式否则会出现订阅端中文乱码的情况
mqttMessage.setPayload(message.getBytes(StandardCharsets.UTF_8));
// 主题的目的地用于发布/订阅信息
MqttTopic mqttTopic = client.getTopic(topic);
// 提供一种机制来跟踪消息的传递进度
// 用于在以非阻塞方式在后台运行执行发布是跟踪消息的传递进度
MqttDeliveryToken token;
try {
// 将指定消息发布到主题但不等待消息传递完成返回的token可用于跟踪消息的传递状态
// 一旦此方法干净地返回消息就已被客户端接受发布当连接可用将在后台完成消息传递
token = mqttTopic.publish(mqttMessage);
token.waitForCompletion();
} catch (MqttException e) {
e.printStackTrace();
}
}
/**
* 断开连接
*/
public static void disConnect() {
try {
// 获取客户端实例
MqttClient client = MqttFactory.getInstance();
client.disconnect();
} catch (MqttException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,42 @@
spring:
cloud:
nacos:
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
username: # Nacos 账号
password: # Nacos 密码
discovery: # 【配置中心】配置项
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
metadata:
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
config: # 【注册中心】配置项
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
# Lock4j 配置项
lock4j:
acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒
--- #################### 监控相关配置 ####################
# Actuator 监控端点的配置项
management:
endpoints:
web:
base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
exposure:
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
# MQTT
mqtt:
host: tcp://127.0.0.1:1883
username: adminuser
password: adminuser
qos: 1
clientId: mqttx_b82345a52
timeout: 10
keepalive: 20

View File

@ -0,0 +1,30 @@
spring:
application:
name: mqtt-server
main:
allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。
allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务
profiles:
active: local
mvc:
pathmatch:
matching-strategy: ANT_PATH_MATCHER # 解决 SpringFox 与 SpringBoot 2.6.x 不兼容的问题,参见 SpringFoxHandlerProviderBeanPostProcessor 类
# Jackson 配置项
jackson:
serialization:
write-dates-as-timestamps: true # 设置 LocalDateTime 的格式,使用时间戳
write-date-timestamps-as-nanoseconds: false # 设置不使用 nanoseconds 的格式。例如说 1611460870.401,而是直接 1611460870401
write-durations-as-timestamps: true # 设置 Duration 的格式,使用时间戳
fail-on-empty-beans: false # 允许序列化无属性的 Bean
server:
port: 48083
debug: false

View File

@ -0,0 +1,23 @@
--- #################### 注册中心相关配置 ####################
spring:
cloud:
nacos:
server-addr: 127.0.0.1:8848
discovery:
namespace: dev # 命名空间。这里使用 dev 开发环境
metadata:
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
--- #################### 配置中心相关配置 ####################
spring:
cloud:
nacos:
# Nacos Config 配置项,对应 NacosConfigProperties 配置属性类
config:
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
namespace: dev # 命名空间 dev 的ID不能直接使用 dev 名称。创建命名空间的时候需要指定ID为 dev这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
name: ${spring.application.name} # 使用的 Nacos 配置集的 dataId默认为 spring.application.name
file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties

View File

@ -0,0 +1,23 @@
--- #################### 注册中心相关配置 ####################
spring:
cloud:
nacos:
server-addr: 127.0.0.1:8848
discovery:
namespace: dev # 命名空间。这里使用 dev 开发环境
metadata:
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
--- #################### 配置中心相关配置 ####################
spring:
cloud:
nacos:
# Nacos Config 配置项,对应 NacosConfigProperties 配置属性类
config:
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
namespace: dev # 命名空间 dev 的ID不能直接使用 dev 名称。创建命名空间的时候需要指定ID为 dev这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
name: ${spring.application.name} # 使用的 Nacos 配置集的 dataId默认为 spring.application.name
file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties

View File

@ -0,0 +1,23 @@
--- #################### 注册中心相关配置 ####################
spring:
cloud:
nacos:
server-addr: 127.0.0.1:8848
discovery:
namespace: prod # 命名空间。这里使用 dev 开发环境
metadata:
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
--- #################### 配置中心相关配置 ####################
spring:
cloud:
nacos:
# Nacos Config 配置项,对应 NacosConfigProperties 配置属性类
config:
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
namespace: prod # 命名空间 dev 的ID不能直接使用 dev 名称。创建命名空间的时候需要指定ID为 dev这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
name: ${spring.application.name} # 使用的 Nacos 配置集的 dataId默认为 spring.application.name
file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties

View File

@ -0,0 +1,15 @@
spring:
application:
name: mqtt-server
profiles:
active: local #local
# active: prod
server:
port: 48083
# 日志文件配置。注意,如果 logging.file.name 不放在 bootstrap.yaml 配置文件,而是放在 application.yaml 中,会导致出现 LOG_FILE_IS_UNDEFINED 文件
logging:
file:
name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径

View File

@ -0,0 +1,76 @@
<configuration>
<!-- 引用 Spring Boot 的 logback 基础配置 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<!-- 变量 yudao.info.base-package基础业务包 -->
<springProperty scope="context" name="yudao.info.base-package" source="yudao.info.base-package"/>
<!-- 格式化输出:%d 表示日期,%X{tid} SkWalking 链路追踪编号,%thread 表示线程名,%-5level级别从左显示 5 个字符宽度,%msg日志消息%n是换行符 -->
<property name="PATTERN_DEFAULT" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} | %highlight(${LOG_LEVEL_PATTERN:-%5p} ${PID:- }) | %boldYellow(%thread [%tid]) %boldGreen(%-40.40logger{39}) | %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
<!-- 控制台 Appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">     
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
</appender>
<!-- 文件 Appender -->
<!-- 参考 Spring Boot 的 file-appender.xml 编写 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
<!-- 日志文件名 -->
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 滚动后的日志文件名 -->
<fileNamePattern>${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz}</fileNamePattern>
<!-- 启动服务时,是否清理历史日志,一般不建议清理 -->
<cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
<!-- 日志文件,到达多少容量,进行滚动 -->
<maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
<!-- 日志文件的总大小0 表示不限制 -->
<totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
<!-- 日志文件的保留天数 -->
<maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-30}</maxHistory>
</rollingPolicy>
</appender>
<!-- 异步写入日志,提升性能 -->
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志。默认的,如果队列的 80% 已满,则会丢弃 TRACT、DEBUG、INFO 级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能。默认值为 256 -->
<queueSize>256</queueSize>
<appender-ref ref="FILE"/>
</appender>
<!-- SkyWalking GRPC 日志收集实现日志中心。注意SkyWalking 8.4.0 版本开始支持 -->
<appender name="GRPC" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
</appender>
<!-- 本地环境 -->
<springProfile name="local">
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="GRPC"/> <!-- 本地环境下,如果不想接入 SkyWalking 日志服务,可以注释掉本行 -->
<appender-ref ref="ASYNC"/> <!-- 本地环境下,如果不想打印日志,可以注释掉本行 -->
</root>
</springProfile>
<!-- 其它环境 -->
<springProfile name="dev,test,stage,prod,default">
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="ASYNC"/>
<appender-ref ref="GRPC"/>
</root>
</springProfile>
</configuration>

View File

@ -0,0 +1,11 @@
package cn.iocoder.yudao.module.system.api.robot;
import cn.iocoder.yudao.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 机器人异常上报")
public interface RobotGenericsStatusApi {
}

View File

@ -0,0 +1,11 @@
package cn.iocoder.yudao.module.system.api.robot;
import cn.iocoder.yudao.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 机器人点位上报")
public interface RobotStatusApi {
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.system.api.robot;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotCompleteTaskDTO;
import cn.iocoder.yudao.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 机器人完成任务状态上报")
public interface RobotTaskStatusApi {
String PREFIX = ApiConstants.PREFIX + "/task";
@PostMapping(PREFIX + "/updateStatus")
@Operation(summary = "机器人完成任务上报")
CommonResult<Boolean> robotDoneTask(@RequestBody RobotCompleteTaskDTO robotCompleteTaskDTO);
}

View File

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.system.api.robot.dto;
import lombok.Data;
@Data
public class RobotCommandStateDTO {
/**
* 命令id
*/
private String command_id;
/**
* 命令类型
*/
private String command_type;
/**
* 执行状态
*/
private String execution_state;
/**
* 响应的状态码
*/
private String status_code;
/**
* 失败时的错误原因
*/
private String message;
/**
* 解决方法
*/
private String solution;
}

View File

@ -0,0 +1,41 @@
package cn.iocoder.yudao.module.system.api.robot.dto;
import lombok.Data;
import java.util.List;
@Data
public class RobotCompleteTaskDTO {
/**
* mac地址
*/
private String mac;
/**
* robot_task_detail 表id
*/
private Long order_id;
/**
* 任务类型暂时未定义
*/
private String order_type;
/**
* 执行状态
*/
private Integer execution_state;
/**
* 响应的状态码
*/
private String status_code;
/**
* 失败时的错误原因
*/
private String message;
/**
* 解决方法
*/
private String solution;
/**
* 子任务
*/
private List<RobotCommandStateDTO> command_state;
}

View File

@ -163,4 +163,36 @@ public interface ErrorCodeConstants {
// ========== 站内信发送 1-002-028-000 ==========
ErrorCode NOTIFY_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1_002_028_000, "模板参数({})缺失");
// ========== 设备信息 1-002-029-000 ==========
ErrorCode INFORMATION_NOT_EXISTS = new ErrorCode(1_002_029_001, "设备信息不存在");
ErrorCode INFORMATION_MAC_EXIST = new ErrorCode(1_002_029_002, "此Mac地址已经存在");
ErrorCode INFORMATION_MAC_INPUT = new ErrorCode(1_002_029_003, "请输入Mac地址");
// ========== 线库/巷道 1-002-030-000 ==========
ErrorCode HOUSE_LANE_NOT_EXISTS = new ErrorCode(1-002-030-001, "线库不存在");
// ========== 库区 1-002-031-000 ==========
ErrorCode HOUSE_AREA_NOT_EXISTS = new ErrorCode(1-002-031-001, "库区不存在");
// ========== 库位 1-002-032-000 ==========
ErrorCode HOUSE_LOCATION_NOT_EXISTS = new ErrorCode(1-002-032-001, "库位不存在");
// ========== 车辆类型 1-002-033-000==========
ErrorCode MODEL_NOT_EXISTS = new ErrorCode(1-002-033-001, "车辆类型不存在");
// ========== 车辆信息 1-002-034-000 ==========
ErrorCode ROBOT_INFORMATION_NOT_EXISTS = new ErrorCode(1-002-034-001, "车辆信息不存在");
// ========== 机器人任务主表 1-002-035-000 ==========
ErrorCode TASK_NOT_EXISTS = new ErrorCode(1-002-035-001, "机器人任务主表不存在");
ErrorCode TASK_DATA_NOT_FULL = new ErrorCode(1-002-035-002, "任务数据不完整");
ErrorCode TASK_CYCLE_NOT_OPEN = new ErrorCode(1-002-035-003, "循环任务的配置未开启!");
ErrorCode TASK_ONLY_CHOOSE_LOCATION = new ErrorCode(1-002-035-004, "搬空任务只能选择线库或者区域");
ErrorCode TASK_CHECK_EXCEPTION = new ErrorCode(1-002-035-005, "任务下发失败");
// ========== 机器人任务明细 1-002-036-000 ==========
ErrorCode TASK_DETAIL_NOT_EXISTS = new ErrorCode(1-002-036-001, "机器人任务明细不存在");
// ========== 机器人任务明细 1-002-037-000 ==========
ErrorCode REDISSON_NOT_OBTAIN_LOCK = new ErrorCode(1-002-037-001, "有正在下发中的任务请稍后重试!");
}

View File

@ -35,6 +35,16 @@
<artifactId>yudao-module-infra-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-grpc-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-mqtt-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- 业务组件 -->
<dependency>

View File

@ -0,0 +1,53 @@
package cn.iocoder.yudao.module.system.api.robot;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotCompleteTaskDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskMapper;
import cn.iocoder.yudao.module.system.enums.robot.RobotTaskDetailStatusEnum;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Slf4j
@RestController // 提供 RESTful API 接口 Feign 调用
@Validated
public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
@Autowired
private RobotTaskDetailMapper robotTaskDetailMapper;
@Autowired
private RobotTaskMapper robotTaskMapper;
/**
* 机器人完成任务上报
* @param robotCompleteTaskDTO
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public CommonResult<Boolean> robotDoneTask(RobotCompleteTaskDTO robotCompleteTaskDTO) {
log.info("机器人完成任务上报 :{}", JSON.toJSONString(robotCompleteTaskDTO));
TenantContextHolder.setTenantId(1L);
robotTaskDetailMapper.updateRobotDetailStatus(robotCompleteTaskDTO.getOrder_id(),
robotCompleteTaskDTO.getExecution_state());
RobotTaskDetailDO robotTaskDetailDO = robotTaskDetailMapper.selectById(robotCompleteTaskDTO.getOrder_id());
List<RobotTaskDetailDO> taskDetails = robotTaskDetailMapper.queryByTaskId(robotTaskDetailDO.getRobotTaskId());
boolean b =
taskDetails.stream().allMatch(v -> (v.getTaskStatus().equals(RobotTaskDetailStatusEnum.DONE.getType())
|| v.getTaskStatus().equals(RobotTaskDetailStatusEnum.CLOSE.getType()) ));
if(b) {
robotTaskMapper.updateRobotStatus(taskDetails.get(0).getRobotTaskId(), RobotTaskDetailStatusEnum.DONE.getType());
}
return CommonResult.success(true);
}
}

View File

@ -0,0 +1,65 @@
package cn.iocoder.yudao.module.system.config;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @ClassName XxlJobConfig
* @Description: xxl-job依赖配置
* @author
* @date 2022年12月07日 08:37
* @version 1.0
*/
@Configuration //是否开启xxl-job定时任务注释掉 //@Configuration 则不开启定时任务
@Data
@Slf4j
public class XxlJobConfig {
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${xxl.job.accessToken}")
private String accessToken;
@Value("${xxl.job.executor.appname}")
private String appname;
@Value("${xxl.job.executor.address}")
private String address;
@Value("${xxl.job.executor.ip}")
private String ip;
@Value("${xxl.job.executor.port}")
private int port;
@Value("${xxl.job.executor.logpath}")
private String logPath;
@Value("${xxl.job.executor.logretentiondays}")
private int logRetentionDays;
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
XxlJobHelper.log(">>>>>>>>>>> xxl-job config init.>>>>>>>>>>>");
System.out.println("=============== xxl-job config init.===============");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setAddress(address);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
}

View File

@ -0,0 +1,97 @@
package cn.iocoder.yudao.module.system.controller.admin.housearea;
import cn.iocoder.yudao.module.system.controller.admin.housearea.vo.HouseAreaPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.housearea.vo.HouseAreaRespVO;
import cn.iocoder.yudao.module.system.controller.admin.housearea.vo.HouseAreaSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.housearea.HouseAreaDO;
import cn.iocoder.yudao.module.system.service.housearea.HouseAreaService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 库区")
@RestController
@RequestMapping("/system/ware/house-area")
@Validated
public class HouseAreaController {
@Resource
private HouseAreaService houseAreaService;
@PostMapping("/create")
@Operation(summary = "创建库区")
@PreAuthorize("@ss.hasPermission('ware:house-area:create')")
public CommonResult<Long> createHouseArea(@Valid @RequestBody HouseAreaSaveReqVO createReqVO) {
return success(houseAreaService.createHouseArea(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新库区")
@PreAuthorize("@ss.hasPermission('ware:house-area:update')")
public CommonResult<Boolean> updateHouseArea(@Valid @RequestBody HouseAreaSaveReqVO updateReqVO) {
houseAreaService.updateHouseArea(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除库区")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('ware:house-area:delete')")
public CommonResult<Boolean> deleteHouseArea(@RequestParam("id") Long id) {
houseAreaService.deleteHouseArea(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得库区")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('ware:house-area:query')")
public CommonResult<HouseAreaRespVO> getHouseArea(@RequestParam("id") Long id) {
HouseAreaDO houseArea = houseAreaService.getHouseArea(id);
return success(BeanUtils.toBean(houseArea, HouseAreaRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得库区分页")
@PreAuthorize("@ss.hasPermission('ware:house-area:query')")
public CommonResult<PageResult<HouseAreaRespVO>> getHouseAreaPage(@Valid HouseAreaPageReqVO pageReqVO) {
PageResult<HouseAreaDO> pageResult = houseAreaService.getHouseAreaPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, HouseAreaRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出库区 Excel")
@PreAuthorize("@ss.hasPermission('ware:house-area:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportHouseAreaExcel(@Valid HouseAreaPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<HouseAreaDO> list = houseAreaService.getHouseAreaPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "库区.xls", "数据", HouseAreaRespVO.class,
BeanUtils.toBean(list, HouseAreaRespVO.class));
}
}

View File

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.system.controller.admin.housearea.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 库区分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class HouseAreaPageReqVO extends PageParam {
@Schema(description = "库区id(自定义)", example = "24710")
private Long areaId;
@Schema(description = "库区名称", example = "李四")
private String areaName;
@Schema(description = "库区说明")
private String areaMsg;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,35 @@
package cn.iocoder.yudao.module.system.controller.admin.housearea.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 库区 Response VO")
@Data
@ExcelIgnoreUnannotated
public class HouseAreaRespVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2922")
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "库区id(自定义)", requiredMode = Schema.RequiredMode.REQUIRED, example = "24710")
@ExcelProperty("库区id(自定义)")
private Long areaId;
@Schema(description = "库区名称", example = "李四")
@ExcelProperty("库区名称")
private String areaName;
@Schema(description = "库区说明")
@ExcelProperty("库区说明")
private String areaMsg;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.system.controller.admin.housearea.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 库区新增/修改 Request VO")
@Data
public class HouseAreaSaveReqVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2922")
private Long id;
@Schema(description = "库区id(自定义)", requiredMode = Schema.RequiredMode.REQUIRED, example = "24710")
@NotNull(message = "库区id(自定义)不能为空")
private Long areaId;
@Schema(description = "库区名称", example = "李四")
private String areaName;
@Schema(description = "库区说明")
private String areaMsg;
}

View File

@ -0,0 +1,97 @@
package cn.iocoder.yudao.module.system.controller.admin.houselane;
import cn.iocoder.yudao.module.system.controller.admin.houselane.vo.WareHouseLanePageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.houselane.vo.WareHouseLaneRespVO;
import cn.iocoder.yudao.module.system.controller.admin.houselane.vo.WareHouseLaneSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselane.WareHouseLaneDO;
import cn.iocoder.yudao.module.system.service.houselane.WareHouseLaneService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 线库/巷道")
@RestController
@RequestMapping("/system/ware/house-lane")
@Validated
public class WareHouseLaneController {
@Resource
private WareHouseLaneService houseLaneService;
@PostMapping("/create")
@Operation(summary = "创建线库/巷道")
@PreAuthorize("@ss.hasPermission('ware:house-lane:create')")
public CommonResult<Long> createHouseLane(@Valid @RequestBody WareHouseLaneSaveReqVO createReqVO) {
return success(houseLaneService.createHouseLane(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新线库/巷道")
@PreAuthorize("@ss.hasPermission('ware:house-lane:update')")
public CommonResult<Boolean> updateHouseLane(@Valid @RequestBody WareHouseLaneSaveReqVO updateReqVO) {
houseLaneService.updateHouseLane(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除线库/巷道")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('ware:house-lane:delete')")
public CommonResult<Boolean> deleteHouseLane(@RequestParam("id") Long id) {
houseLaneService.deleteHouseLane(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得线库/巷道")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('ware:house-lane:query')")
public CommonResult<WareHouseLaneRespVO> getHouseLane(@RequestParam("id") Long id) {
WareHouseLaneDO houseLane = houseLaneService.getHouseLane(id);
return success(BeanUtils.toBean(houseLane, WareHouseLaneRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得线库/巷道分页")
@PreAuthorize("@ss.hasPermission('ware:house-lane:query')")
public CommonResult<PageResult<WareHouseLaneRespVO>> getHouseLanePage(@Valid WareHouseLanePageReqVO pageReqVO) {
PageResult<WareHouseLaneDO> pageResult = houseLaneService.getHouseLanePage(pageReqVO);
return success(BeanUtils.toBean(pageResult, WareHouseLaneRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出线库/巷道 Excel")
@PreAuthorize("@ss.hasPermission('ware:house-lane:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportHouseLaneExcel(@Valid WareHouseLanePageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<WareHouseLaneDO> list = houseLaneService.getHouseLanePage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "线库/巷道.xls", "数据", WareHouseLaneRespVO.class,
BeanUtils.toBean(list, WareHouseLaneRespVO.class));
}
}

View File

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.system.controller.admin.houselane.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 线库/巷道分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class WareHouseLanePageReqVO extends PageParam {
@Schema(description = "巷道id(自定义)", example = "276")
private Long laneId;
@Schema(description = "巷道名称", example = "芋艿")
private String laneName;
@Schema(description = "巷道说明(可以拓展为区域说明)")
private String laneMsg;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,35 @@
package cn.iocoder.yudao.module.system.controller.admin.houselane.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 线库/巷道 Response VO")
@Data
@ExcelIgnoreUnannotated
public class WareHouseLaneRespVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "4293")
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "巷道id(自定义)", requiredMode = Schema.RequiredMode.REQUIRED, example = "276")
@ExcelProperty("巷道id(自定义)")
private Long laneId;
@Schema(description = "巷道名称", example = "芋艿")
@ExcelProperty("巷道名称")
private String laneName;
@Schema(description = "巷道说明(可以拓展为区域说明)")
@ExcelProperty("巷道说明(可以拓展为区域说明)")
private String laneMsg;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.system.controller.admin.houselane.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 线库/巷道新增/修改 Request VO")
@Data
public class WareHouseLaneSaveReqVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "4293")
private Long id;
@Schema(description = "巷道id(自定义)", requiredMode = Schema.RequiredMode.REQUIRED, example = "276")
@NotNull(message = "巷道id(自定义)不能为空")
private Long laneId;
@Schema(description = "巷道名称", example = "芋艿")
private String laneName;
@Schema(description = "巷道说明(可以拓展为区域说明)")
private String laneMsg;
}

View File

@ -0,0 +1,96 @@
package cn.iocoder.yudao.module.system.controller.admin.houselocation;
import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationRespVO;
import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
import cn.iocoder.yudao.module.system.service.houselocation.HouseLocationService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 库位")
@RestController
@RequestMapping("/system/ware/house-location")
@Validated
public class WareHouseLocationController {
@Resource
private HouseLocationService houseLocationService;
@PostMapping("/create")
@Operation(summary = "创建库位")
@PreAuthorize("@ss.hasPermission('ware:house-location:create')")
public CommonResult<Long> createHouseLocation(@Valid @RequestBody WareHouseLocationSaveReqVO createReqVO) {
return success(houseLocationService.createHouseLocation(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新库位")
@PreAuthorize("@ss.hasPermission('ware:house-location:update')")
public CommonResult<Boolean> updateHouseLocation(@Valid @RequestBody WareHouseLocationSaveReqVO updateReqVO) {
houseLocationService.updateHouseLocation(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除库位")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('ware:house-location:delete')")
public CommonResult<Boolean> deleteHouseLocation(@RequestParam("id") Long id) {
houseLocationService.deleteHouseLocation(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得库位")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('ware:house-location:query')")
public CommonResult<WareHouseLocationRespVO> getHouseLocation(@RequestParam("id") Long id) {
WareHouseLocationDO houseLocation = houseLocationService.getHouseLocation(id);
return success(BeanUtils.toBean(houseLocation, WareHouseLocationRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得库位分页")
@PreAuthorize("@ss.hasPermission('ware:house-location:query')")
public CommonResult<PageResult<WareHouseLocationRespVO>> getHouseLocationPage(@Valid WareHouseLocationPageReqVO pageReqVO) {
PageResult<WareHouseLocationDO> pageResult = houseLocationService.getHouseLocationPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, WareHouseLocationRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出库位 Excel")
@PreAuthorize("@ss.hasPermission('ware:house-location:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportHouseLocationExcel(@Valid WareHouseLocationPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<WareHouseLocationDO> list = houseLocationService.getHouseLocationPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "库位.xls", "数据", WareHouseLocationRespVO.class,
BeanUtils.toBean(list, WareHouseLocationRespVO.class));
}
}

View File

@ -0,0 +1,102 @@
package cn.iocoder.yudao.module.system.controller.admin.houselocation.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import java.math.BigDecimal;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 库位分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class WareHouseLocationPageReqVO extends PageParam {
@Schema(description = "巷道/线库id", example = "24770")
private Long laneId;
@Schema(description = "巷道/线库名称", example = "赵六")
private String laneName;
@Schema(description = "库区id(自定义)", example = "11770")
private Long areaId;
@Schema(description = "库区名称", example = "张三")
private String areaName;
@Schema(description = "库位编号")
private String locationNo;
@Schema(description = "分组名称", example = "李四")
private String groupName;
@Schema(description = "弧度")
private String locationYaw;
@Schema(description = "物料信息")
private String skuInfo;
@Schema(description = "物料批次号")
private String skuBatch;
@Schema(description = "物料数量")
private Long skuNumber;
@Schema(description = "托盘消息")
private String trayInfo;
@Schema(description = "启用/禁用0禁用、1启用")
private Integer locationEnable;
@Schema(description = "锁定/正常0锁定、1正常")
private Integer locationLock;
@Schema(description = "状态0空闲、1占用", example = "2")
private Integer locationUseStatus;
@Schema(description = "库位坐标x轴")
private String locationX;
@Schema(description = "库位坐标y轴")
private String locationY;
@Schema(description = "宽(库位上目前所放物品的宽)")
private BigDecimal locationWide;
@Schema(description = "深(库位上目前所放物品的深)")
private BigDecimal locationDeep;
@Schema(description = "高(库位上目前所放物品的高)")
private BigDecimal locationHeight;
@Schema(description = "库位默认高度(现场有水泥高出地面的高度)")
private BigDecimal locationDefaultHeight;
@Schema(description = "机车上报的高度/总高(如果两个箱子叠加,就是叠加后的总高度)")
private BigDecimal locationTotalHeight;
@Schema(description = "机车上报的托盘高度")
private BigDecimal locationTrayHeight;
@Schema(description = "层数")
private Integer locationStorey;
@Schema(description = "点位类型0库位、1等待点、2输送线取托盘点、3出库放托盘点", example = "1")
private Integer locationType;
@Schema(description = "排序的位置,越大越优先堆放")
private Long locationNumber;
@Schema(description = "最后一次执行任务robot_task的id", example = "23816")
private Long taskId;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,128 @@
package cn.iocoder.yudao.module.system.controller.admin.houselocation.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.math.BigDecimal;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 库位 Response VO")
@Data
@ExcelIgnoreUnannotated
public class WareHouseLocationRespVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "31866")
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "巷道/线库id", example = "24770")
@ExcelProperty("巷道/线库id")
private Long laneId;
@Schema(description = "巷道/线库名称", example = "赵六")
@ExcelProperty("巷道/线库名称")
private String laneName;
@Schema(description = "库区id(自定义)", example = "11770")
@ExcelProperty("库区id(自定义)")
private Long areaId;
@Schema(description = "库区名称", example = "张三")
@ExcelProperty("库区名称")
private String areaName;
@Schema(description = "库位编号")
@ExcelProperty("库位编号")
private String locationNo;
@Schema(description = "分组名称", example = "李四")
@ExcelProperty("分组名称")
private String groupName;
@Schema(description = "弧度")
@ExcelProperty("弧度")
private String locationYaw;
@Schema(description = "物料信息")
@ExcelProperty("物料信息")
private String skuInfo;
@Schema(description = "物料批次号")
@ExcelProperty("物料批次号")
private String skuBatch;
@Schema(description = "物料数量")
@ExcelProperty("物料数量")
private Long skuNumber;
@Schema(description = "托盘消息")
@ExcelProperty("托盘消息")
private String trayInfo;
@Schema(description = "启用/禁用0禁用、1启用")
@ExcelProperty("启用/禁用0禁用、1启用")
private Integer locationEnable;
@Schema(description = "锁定/正常0锁定、1正常")
@ExcelProperty("锁定/正常0锁定、1正常")
private Integer locationLock;
@Schema(description = "状态0空闲、1占用", example = "2")
@ExcelProperty("状态0空闲、1占用")
private Integer locationUseStatus;
@Schema(description = "库位坐标x轴")
@ExcelProperty("库位坐标x轴")
private String locationX;
@Schema(description = "库位坐标y轴")
@ExcelProperty("库位坐标y轴")
private String locationY;
@Schema(description = "宽(库位上目前所放物品的宽)")
@ExcelProperty("宽(库位上目前所放物品的宽)")
private BigDecimal locationWide;
@Schema(description = "深(库位上目前所放物品的深)")
@ExcelProperty("深(库位上目前所放物品的深)")
private BigDecimal locationDeep;
@Schema(description = "高(库位上目前所放物品的高)")
@ExcelProperty("高(库位上目前所放物品的高)")
private BigDecimal locationHeight;
@Schema(description = "库位默认高度(现场有水泥高出地面的高度)")
@ExcelProperty("库位默认高度(现场有水泥高出地面的高度)")
private BigDecimal locationDefaultHeight;
@Schema(description = "机车上报的高度/总高(如果两个箱子叠加,就是叠加后的总高度)")
@ExcelProperty("机车上报的高度/总高(如果两个箱子叠加,就是叠加后的总高度)")
private BigDecimal locationTotalHeight;
@Schema(description = "机车上报的托盘高度")
@ExcelProperty("机车上报的托盘高度")
private BigDecimal locationTrayHeight;
@Schema(description = "层数")
@ExcelProperty("层数")
private Integer locationStorey;
@Schema(description = "点位类型0库位、1等待点、2输送线取托盘点、3出库放托盘点", example = "1")
@ExcelProperty("点位类型0库位、1等待点、2输送线取托盘点、3出库放托盘点")
private Integer locationType;
@Schema(description = "排序的位置,越大越优先堆放")
@ExcelProperty("排序的位置,越大越优先堆放")
private Long locationNumber;
@Schema(description = "最后一次执行任务robot_task的id", example = "23816")
@ExcelProperty("最后一次执行任务robot_task的id")
private Long taskId;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,94 @@
package cn.iocoder.yudao.module.system.controller.admin.houselocation.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
import java.math.BigDecimal;
@Schema(description = "管理后台 - 库位新增/修改 Request VO")
@Data
public class WareHouseLocationSaveReqVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "31866")
private Long id;
@Schema(description = "巷道/线库id", example = "24770")
private Long laneId;
@Schema(description = "巷道/线库名称", example = "赵六")
private String laneName;
@Schema(description = "库区id(自定义)", example = "11770")
private Long areaId;
@Schema(description = "库区名称", example = "张三")
private String areaName;
@Schema(description = "库位编号")
private String locationNo;
@Schema(description = "分组名称", example = "李四")
private String groupName;
@Schema(description = "弧度")
private String locationYaw;
@Schema(description = "物料信息")
private String skuInfo;
@Schema(description = "物料批次号")
private String skuBatch;
@Schema(description = "物料数量")
private Long skuNumber;
@Schema(description = "托盘消息")
private String trayInfo;
@Schema(description = "启用/禁用0禁用、1启用")
private Integer locationEnable;
@Schema(description = "锁定/正常0锁定、1正常")
private Integer locationLock;
@Schema(description = "状态0空闲、1占用", example = "2")
private Integer locationUseStatus;
@Schema(description = "库位坐标x轴")
private String locationX;
@Schema(description = "库位坐标y轴")
private String locationY;
@Schema(description = "宽(库位上目前所放物品的宽)")
private BigDecimal locationWide;
@Schema(description = "深(库位上目前所放物品的深)")
private BigDecimal locationDeep;
@Schema(description = "高(库位上目前所放物品的高)")
private BigDecimal locationHeight;
@Schema(description = "库位默认高度(现场有水泥高出地面的高度)")
private BigDecimal locationDefaultHeight;
@Schema(description = "机车上报的高度/总高(如果两个箱子叠加,就是叠加后的总高度)")
private BigDecimal locationTotalHeight;
@Schema(description = "机车上报的托盘高度")
private BigDecimal locationTrayHeight;
@Schema(description = "层数")
private Integer locationStorey;
@Schema(description = "点位类型0库位、1等待点、2输送线取托盘点、3出库放托盘点", example = "1")
private Integer locationType;
@Schema(description = "排序的位置,越大越优先堆放")
private Long locationNumber;
@Schema(description = "最后一次执行任务robot_task的id", example = "23816")
private Long taskId;
}

View File

@ -0,0 +1,96 @@
package cn.iocoder.yudao.module.system.controller.admin.information;
import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationRespVO;
import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.information.DeviceInformationDO;
import cn.iocoder.yudao.module.system.service.information.DeviceInformationService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 设备信息")
@RestController
@RequestMapping("/system/device/information")
@Validated
public class DeviceInformationController {
@Resource
private DeviceInformationService informationService;
@PostMapping("/create")
@Operation(summary = "创建设备信息")
@PreAuthorize("@ss.hasPermission('device:information:create')")
public CommonResult<Long> createInformation(@Valid @RequestBody DeviceInformationSaveReqVO createReqVO) {
return success(informationService.createInformation(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新设备信息")
@PreAuthorize("@ss.hasPermission('device:information:update')")
public CommonResult<Boolean> updateInformation(@Valid @RequestBody DeviceInformationSaveReqVO updateReqVO) {
informationService.updateInformation(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除设备信息")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('device:information:delete')")
public CommonResult<Boolean> deleteInformation(@RequestParam("id") Long id) {
informationService.deleteInformation(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得设备信息")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('device:information:query')")
public CommonResult<DeviceInformationRespVO> getInformation(@RequestParam("id") Long id) {
DeviceInformationDO information = informationService.getInformation(id);
return success(BeanUtils.toBean(information, DeviceInformationRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得设备信息分页")
@PreAuthorize("@ss.hasPermission('device:information:query')")
public CommonResult<PageResult<DeviceInformationRespVO>> getInformationPage(@Valid DeviceInformationPageReqVO pageReqVO) {
PageResult<DeviceInformationDO> pageResult = informationService.getInformationPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, DeviceInformationRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出设备信息 Excel")
@PreAuthorize("@ss.hasPermission('device:information:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportInformationExcel(@Valid DeviceInformationPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<DeviceInformationDO> list = informationService.getInformationPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "设备信息.xls", "数据", DeviceInformationRespVO.class,
BeanUtils.toBean(list, DeviceInformationRespVO.class));
}
}

View File

@ -0,0 +1,50 @@
package cn.iocoder.yudao.module.system.controller.admin.information.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 设备信息分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DeviceInformationPageReqVO extends PageParam {
@Schema(description = "设备类型1充电桩、2输送线、 3码垛机、4拆垛机、5自动门、6提升机、7信号灯、8按钮盒", example = "2")
private Integer deviceType;
@Schema(description = "设备编号")
private String deviceNo;
@Schema(description = "mac地址")
private String macAddress;
@Schema(description = "上传图片附件", example = "https://www.iocoder.cn")
private String url;
@Schema(description = "图片设置1默认图片、2上传图片、 3不显示图片")
private Integer pictureConfig;
@Schema(description = "设备状态1在线、2离线、 3异常", example = "1")
private Integer deviceStatus;
@Schema(description = "设备启用禁用0禁用、1启用")
private Integer deviceEnable;
@Schema(description = "设备协议")
private String deviceAgreement;
@Schema(description = "设备最后通讯时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] deviceLastTime;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,59 @@
package cn.iocoder.yudao.module.system.controller.admin.information.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 设备信息 Response VO")
@Data
@ExcelIgnoreUnannotated
public class DeviceInformationRespVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "14335")
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "设备类型1充电桩、2输送线、 3码垛机、4拆垛机、5自动门、6提升机、7信号灯、8按钮盒", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty("设备类型1充电桩、2输送线、 3码垛机、4拆垛机、5自动门、6提升机、7信号灯、8按钮盒")
private Integer deviceType;
@Schema(description = "设备编号")
@ExcelProperty("设备编号")
private String deviceNo;
@Schema(description = "mac地址")
@ExcelProperty("mac地址")
private String macAddress;
@Schema(description = "上传图片附件", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
@ExcelProperty("上传图片附件")
private String url;
@Schema(description = "图片设置1默认图片、2上传图片、 3不显示图片")
@ExcelProperty("图片设置1默认图片、2上传图片、 3不显示图片")
private Integer pictureConfig;
@Schema(description = "设备状态1在线、2离线、 3异常", example = "1")
@ExcelProperty("设备状态1在线、2离线、 3异常")
private Integer deviceStatus;
@Schema(description = "设备启用禁用0禁用、1启用")
@ExcelProperty("设备启用禁用0禁用、1启用")
private Integer deviceEnable;
@Schema(description = "设备协议")
@ExcelProperty("设备协议")
private String deviceAgreement;
@Schema(description = "设备最后通讯时间")
@ExcelProperty("设备最后通讯时间")
private LocalDateTime deviceLastTime;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,45 @@
package cn.iocoder.yudao.module.system.controller.admin.information.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 设备信息新增/修改 Request VO")
@Data
public class DeviceInformationSaveReqVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "14335")
private Long id;
@Schema(description = "设备类型1充电桩、2输送线、 3码垛机、4拆垛机、5自动门、6提升机、7信号灯、8按钮盒", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "设备类型不能为空")
private Integer deviceType;
@Schema(description = "设备编号")
private String deviceNo;
@Schema(description = "mac地址")
private String macAddress;
@Schema(description = "上传图片附件", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
private String url;
@Schema(description = "图片设置1默认图片、2上传图片、 3不显示图片")
private Integer pictureConfig;
@Schema(description = "设备状态1在线、2离线、 3异常", example = "1")
private Integer deviceStatus;
@Schema(description = "设备启用禁用0禁用、1启用")
private Integer deviceEnable;
@Schema(description = "设备协议")
private String deviceAgreement;
@Schema(description = "设备最后通讯时间")
private LocalDateTime deviceLastTime;
}

View File

@ -0,0 +1,96 @@
package cn.iocoder.yudao.module.system.controller.admin.robot;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationRespVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
import cn.iocoder.yudao.module.system.service.robot.RobotInformationService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 车辆信息")
@RestController
@RequestMapping("/system/robot/information")
@Validated
public class RobotInformationController {
@Resource
private RobotInformationService informationService;
@PostMapping("/create")
@Operation(summary = "创建车辆信息")
@PreAuthorize("@ss.hasPermission('robot:information:create')")
public CommonResult<Long> createInformation(@Valid @RequestBody RobotInformationSaveReqVO createReqVO) {
return success(informationService.createInformation(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新车辆信息")
@PreAuthorize("@ss.hasPermission('robot:information:update')")
public CommonResult<Boolean> updateInformation(@Valid @RequestBody RobotInformationSaveReqVO updateReqVO) {
informationService.updateInformation(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除车辆信息")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('robot:information:delete')")
public CommonResult<Boolean> deleteInformation(@RequestParam("id") Long id) {
informationService.deleteInformation(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得车辆信息")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('robot:information:query')")
public CommonResult<RobotInformationRespVO> getInformation(@RequestParam("id") Long id) {
RobotInformationDO information = informationService.getInformation(id);
return success(BeanUtils.toBean(information, RobotInformationRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得车辆信息分页")
@PreAuthorize("@ss.hasPermission('robot:information:query')")
public CommonResult<PageResult<RobotInformationRespVO>> getInformationPage(@Valid RobotInformationPageReqVO pageReqVO) {
PageResult<RobotInformationDO> pageResult = informationService.getInformationPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, RobotInformationRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出车辆信息 Excel")
@PreAuthorize("@ss.hasPermission('robot:information:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportInformationExcel(@Valid RobotInformationPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<RobotInformationDO> list = informationService.getInformationPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "车辆信息.xls", "数据", RobotInformationRespVO.class,
BeanUtils.toBean(list, RobotInformationRespVO.class));
}
}

View File

@ -0,0 +1,94 @@
package cn.iocoder.yudao.module.system.controller.admin.robot;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotModelPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotModelRespVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotModelSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotModelDO;
import cn.iocoder.yudao.module.system.service.robot.RobotModelService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 车辆类型")
@RestController
@RequestMapping("/system/robot/model")
@Validated
public class RobotModelController {
@Resource
private RobotModelService modelService;
@PostMapping("/create")
@Operation(summary = "创建车辆类型")
@PreAuthorize("@ss.hasPermission('robot:model:create')")
public CommonResult<Long> createModel(@Valid @RequestBody RobotModelSaveReqVO createReqVO) {
return success(modelService.createModel(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新车辆类型")
@PreAuthorize("@ss.hasPermission('robot:model:update')")
public CommonResult<Boolean> updateModel(@Valid @RequestBody RobotModelSaveReqVO updateReqVO) {
modelService.updateModel(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除车辆类型")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('robot:model:delete')")
public CommonResult<Boolean> deleteModel(@RequestParam("id") Long id) {
modelService.deleteModel(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得车辆类型")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('robot:model:query')")
public CommonResult<RobotModelRespVO> getModel(@RequestParam("id") Long id) {
RobotModelDO model = modelService.getModel(id);
return success(BeanUtils.toBean(model, RobotModelRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得车辆类型分页")
@PreAuthorize("@ss.hasPermission('robot:model:query')")
public CommonResult<PageResult<RobotModelRespVO>> getModelPage(@Valid RobotModelPageReqVO pageReqVO) {
PageResult<RobotModelDO> pageResult = modelService.getModelPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, RobotModelRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出车辆类型 Excel")
@PreAuthorize("@ss.hasPermission('robot:model:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportModelExcel(@Valid RobotModelPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<RobotModelDO> list = modelService.getModelPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "车辆类型.xls", "数据", RobotModelRespVO.class,
BeanUtils.toBean(list, RobotModelRespVO.class));
}
}

View File

@ -0,0 +1,98 @@
package cn.iocoder.yudao.module.system.controller.admin.robot;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskRespVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO;
import cn.iocoder.yudao.module.system.service.robot.RobotTaskService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 机器人任务主表")
@RestController
@RequestMapping("/system/robot/task")
@Validated
public class RobotTaskController {
@Resource
private RobotTaskService taskService;
@PostMapping("/create")
@Operation(summary = "创建机器人任务主表")
@PreAuthorize("@ss.hasPermission('robot:task:create')")
public CommonResult<Long> createTask(@Valid @RequestBody RobotTaskSaveReqVO createReqVO) throws InterruptedException {
return success(taskService.createTask(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新机器人任务主表")
@PreAuthorize("@ss.hasPermission('robot:task:update')")
public CommonResult<Boolean> updateTask(@Valid @RequestBody RobotTaskSaveReqVO updateReqVO) {
taskService.updateTask(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除机器人任务主表")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('robot:task:delete')")
public CommonResult<Boolean> deleteTask(@RequestParam("id") Long id) {
taskService.deleteTask(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得机器人任务主表")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('robot:task:query')")
public CommonResult<RobotTaskRespVO> getTask(@RequestParam("id") Long id) {
RobotTaskDO task = taskService.getTask(id);
return success(BeanUtils.toBean(task, RobotTaskRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得机器人任务主表分页")
@PreAuthorize("@ss.hasPermission('robot:task:query')")
public CommonResult<PageResult<RobotTaskRespVO>> getTaskPage(@Valid RobotTaskPageReqVO pageReqVO) {
PageResult<RobotTaskDO> pageResult = taskService.getTaskPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, RobotTaskRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出机器人任务主表 Excel")
@PreAuthorize("@ss.hasPermission('robot:task:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportTaskExcel(@Valid RobotTaskPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<RobotTaskDO> list = taskService.getTaskPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "机器人任务主表.xls", "数据", RobotTaskRespVO.class,
BeanUtils.toBean(list, RobotTaskRespVO.class));
}
}

View File

@ -0,0 +1,95 @@
package cn.iocoder.yudao.module.system.controller.admin.robot;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailRespVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO;
import cn.iocoder.yudao.module.system.service.robot.RobotTaskDetailService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 机器人任务明细")
@RestController
@RequestMapping("/system/robot/task-detail")
@Validated
public class RobotTaskDetailController {
@Resource
private RobotTaskDetailService taskDetailService;
@PostMapping("/create")
@Operation(summary = "创建机器人任务明细")
@PreAuthorize("@ss.hasPermission('robot:task-detail:create')")
public CommonResult<Long> createTaskDetail(@Valid @RequestBody RobotTaskDetailSaveReqVO createReqVO) {
return success(taskDetailService.createTaskDetail(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新机器人任务明细")
@PreAuthorize("@ss.hasPermission('robot:task-detail:update')")
public CommonResult<Boolean> updateTaskDetail(@Valid @RequestBody RobotTaskDetailSaveReqVO updateReqVO) {
taskDetailService.updateTaskDetail(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除机器人任务明细")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('robot:task-detail:delete')")
public CommonResult<Boolean> deleteTaskDetail(@RequestParam("id") Long id) {
taskDetailService.deleteTaskDetail(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得机器人任务明细")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('robot:task-detail:query')")
public CommonResult<RobotTaskDetailRespVO> getTaskDetail(@RequestParam("id") Long id) {
RobotTaskDetailDO taskDetail = taskDetailService.getTaskDetail(id);
return success(BeanUtils.toBean(taskDetail, RobotTaskDetailRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得机器人任务明细分页")
@PreAuthorize("@ss.hasPermission('robot:task-detail:query')")
public CommonResult<PageResult<RobotTaskDetailRespVO>> getTaskDetailPage(@Valid RobotTaskDetailPageReqVO pageReqVO) {
PageResult<RobotTaskDetailDO> pageResult = taskDetailService.getTaskDetailPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, RobotTaskDetailRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出机器人任务明细 Excel")
@PreAuthorize("@ss.hasPermission('robot:task-detail:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportTaskDetailExcel(@Valid RobotTaskDetailPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<RobotTaskDetailDO> list = taskDetailService.getTaskDetailPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "机器人任务明细.xls", "数据", RobotTaskDetailRespVO.class,
BeanUtils.toBean(list, RobotTaskDetailRespVO.class));
}
}

View File

@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.vo;
import lombok.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 车辆信息分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class RobotInformationPageReqVO extends PageParam {
@Schema(description = "车辆类型表id", example = "26319")
private Long robotModelId;
@Schema(description = "车辆类型")
private String robotModelNumber;
@Schema(description = "AGV编号")
private String robotNo;
@Schema(description = "任务模式0拒收任务、1正常")
private Integer robotTaskModel;
@Schema(description = "mac地址")
private String macAddress;
@Schema(description = "上传图片附件", example = "https://www.iocoder.cn")
private String url;
@Schema(description = "AGV状态0暂停且无任务、1暂停(有处理中的任务)、2任务中、3待命", example = "1")
private Integer robotStatus;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,50 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 车辆信息 Response VO")
@Data
@ExcelIgnoreUnannotated
public class RobotInformationRespVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "24068")
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "车辆类型表id", example = "26319")
@ExcelProperty("车辆类型表id")
private Long robotModelId;
@Schema(description = "车辆类型")
@ExcelProperty("车辆类型")
private String robotModelNumber;
@Schema(description = "AGV编号")
@ExcelProperty("AGV编号")
private String robotNo;
@Schema(description = "任务模式0拒收任务、1正常", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("任务模式0拒收任务、1正常")
private Integer robotTaskModel;
@Schema(description = "mac地址")
@ExcelProperty("mac地址")
private String macAddress;
@Schema(description = "上传图片附件", example = "https://www.iocoder.cn")
@ExcelProperty("上传图片附件")
private String url;
@Schema(description = "AGV状态0暂停且无任务、1暂停(有处理中的任务)、2任务中、3待命", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("AGV状态0暂停且无任务、1暂停(有处理中的任务)、2任务中、3待命")
private Integer robotStatus;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,36 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 车辆信息新增/修改 Request VO")
@Data
public class RobotInformationSaveReqVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "24068")
private Long id;
@Schema(description = "车辆类型表id", example = "26319")
private Long robotModelId;
@Schema(description = "车辆类型")
private String robotModelNumber;
@Schema(description = "AGV编号")
private String robotNo;
@Schema(description = "任务模式0拒收任务、1正常", requiredMode = Schema.RequiredMode.REQUIRED)
private Integer robotTaskModel;
@Schema(description = "mac地址")
private String macAddress;
@Schema(description = "上传图片附件", example = "https://www.iocoder.cn")
private String url;
@Schema(description = "AGV状态0暂停且无任务、1暂停(有处理中的任务)、2任务中、3待命", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer robotStatus;
}

View File

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 车辆类型分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class RobotModelPageReqVO extends PageParam {
@Schema(description = "车辆类型")
private String robotModelNumber;
@Schema(description = "偏移量")
private String robotOffset;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 车辆类型 Response VO")
@Data
@ExcelIgnoreUnannotated
public class RobotModelRespVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "15571")
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "车辆类型", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("车辆类型")
private String robotModelNumber;
@Schema(description = "偏移量")
@ExcelProperty("偏移量")
private String robotOffset;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
@Schema(description = "管理后台 - 车辆类型新增/修改 Request VO")
@Data
public class RobotModelSaveReqVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "15571")
private Long id;
@Schema(description = "车辆类型", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "车辆类型不能为空")
private String robotModelNumber;
@Schema(description = "偏移量")
private String robotOffset;
}

View File

@ -0,0 +1,57 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.vo;
import cn.hutool.core.util.ObjectUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class RobotTaskDetailAddVo {
@Schema(description = "任务类型1取放货、2停车、 3充电、4移动、5仅取货、6仅放货、7扫描码、8检测托盘类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "任务类型1取放货、2停车、 3充电、4移动、5仅取货、6仅放货、7扫描码、8检测托盘类型不能为空")
private Integer taskType;
@Schema(description = "放货类型1库位、2线库、 3区域", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "放货类型1库位、2线库、 3区域不能为空")
private Integer releaseType;
@Schema(description = "取货类型1库位、2线库、 3区域", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "取货类型1库位、2线库、 3区域不能为空")
private Integer takeType;
@Schema(description = "放货库位/线库/区域", requiredMode = Schema.RequiredMode.REQUIRED, example = "6223")
@NotNull(message = "放货库位/线库/区域不能为空")
private Long releaseId;
@Schema(description = "取货库位/线库/区域", requiredMode = Schema.RequiredMode.REQUIRED, example = "24801")
@NotNull(message = "取货库位/线库/区域不能为空")
private Long takeId;
@Schema(description = "AGV编号")
private String robotNo;
@Schema(description = "计算后的来源库位编号(前端不用传此字段)")
private String fromLocationNo;
@Schema(description = "计算后的来源库位id(前端不用传此字段)")
private Long fromLocationId;
@Schema(description = "计算后的目标库位编号(前端不用传此字段)")
private String toLocationNo;
@Schema(description = "计算后的目标库位id(前端不用传此字段)")
private Long toLocationId;
@Schema(description = "机器人任务主表id(前端不用传此字段)")
private Long robotTaskId;
@Schema(description = "取货层数(前端不用传此字段)")
private Integer fromLocationStorey;
@Schema(description = "放货层数(前端不用传此字段)")
private Integer toLocationStorey;
@Schema(description = "优先级(前端不用传此字段)")
private Long priority;
public Long getPriority() {
if (ObjectUtil.isEmpty(priority)) {
priority = 0l;
}
return priority;
}
}

View File

@ -0,0 +1,74 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.vo;
import lombok.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 机器人任务明细分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class RobotTaskDetailPageReqVO extends PageParam {
@Schema(description = "机器人任务主表id", example = "9241")
private Long robotTaskId;
@Schema(description = "任务类型1取放货、2停车、 3充电、4移动、5仅取货、6仅放货、7扫描码、8检测托盘类型", example = "2")
private Integer taskType;
@Schema(description = "放货类型1库位、2线库、 3区域", example = "2")
private Integer releaseType;
@Schema(description = "取货类型1库位、2线库、 3区域", example = "1")
private Integer takeType;
@Schema(description = "放货库位/线库/区域", example = "6223")
private Long releaseId;
@Schema(description = "取货库位/线库/区域", example = "24801")
private Long takeId;
@Schema(description = "计算后的来源库位编号")
private String fromLocationNo;
@Schema(description = "计算后的来源库位id")
private Long fromLocationId;
@Schema(description = "计算后的目标库位编号")
private String toLocationNo;
@Schema(description = "计算后的目标库位id")
private Long toLocationId;
@Schema(description = "AGV编号")
private String robotNo;
@Schema(description = "AGV动作")
private String robotAction;
@Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消)", example = "1")
private Integer taskStatus;
@Schema(description = "任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)")
private Long taskStage;
@Schema(description = "开始时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] startTime;
@Schema(description = "结束时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] endTime;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@Schema(description = "取货层数")
private Integer fromLocationStorey;
@Schema(description = "放货层数")
private Integer toLocationStorey;
@Schema(description = "优先级")
private Long priority;
}

View File

@ -0,0 +1,91 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 机器人任务明细 Response VO")
@Data
@ExcelIgnoreUnannotated
public class RobotTaskDetailRespVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "26224")
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "机器人任务主表id", requiredMode = Schema.RequiredMode.REQUIRED, example = "9241")
@ExcelProperty("机器人任务主表id")
private Long robotTaskId;
@Schema(description = "任务类型1取放货、2停车、 3充电、4移动、5仅取货、6仅放货、7扫描码、8检测托盘类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty("任务类型1取放货、2停车、 3充电、4移动、5仅取货、6仅放货、7扫描码、8检测托盘类型")
private Integer taskType;
@Schema(description = "放货类型1库位、2线库、 3区域", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty("放货类型1库位、2线库、 3区域")
private Integer releaseType;
@Schema(description = "取货类型1库位、2线库、 3区域", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("取货类型1库位、2线库、 3区域")
private Integer takeType;
@Schema(description = "放货库位/线库/区域", requiredMode = Schema.RequiredMode.REQUIRED, example = "6223")
@ExcelProperty("放货库位/线库/区域")
private Long releaseId;
@Schema(description = "取货库位/线库/区域", requiredMode = Schema.RequiredMode.REQUIRED, example = "24801")
@ExcelProperty("取货库位/线库/区域")
private Long takeId;
@Schema(description = "计算后的来源库位编号")
@ExcelProperty("计算后的来源库位编号")
private String fromLocationNo;
@Schema(description = "计算后的来源库位id")
private Long fromLocationId;
@Schema(description = "计算后的目标库位编号")
@ExcelProperty("计算后的目标库位编号")
private String toLocationNo;
@Schema(description = "计算后的目标库位id")
private Long toLocationId;
@Schema(description = "AGV编号")
@ExcelProperty("AGV编号")
private String robotNo;
@Schema(description = "AGV动作")
@ExcelProperty("AGV动作")
private String robotAction;
@Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消)", example = "1")
@ExcelProperty("任务状态(0:未开始、1执行中、2已完成、3已取消)")
private Integer taskStatus;
@Schema(description = "任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)")
@ExcelProperty("任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)")
private Long taskStage;
@Schema(description = "开始时间")
@ExcelProperty("开始时间")
private LocalDateTime startTime;
@Schema(description = "结束时间")
@ExcelProperty("结束时间")
private LocalDateTime endTime;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
@Schema(description = "取货层数")
@ExcelProperty("取货层数")
private Integer fromLocationStorey;
@Schema(description = "放货层数")
@ExcelProperty("放货层数")
private Integer toLocationStorey;
@Schema(description = "优先级")
@ExcelProperty("优先级")
private Long priority;
}

View File

@ -0,0 +1,75 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import javax.validation.constraints.*;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 机器人任务明细新增/修改 Request VO")
@Data
public class RobotTaskDetailSaveReqVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "26224")
private Long id;
@Schema(description = "机器人任务主表id", requiredMode = Schema.RequiredMode.REQUIRED, example = "9241")
@NotNull(message = "机器人任务主表id不能为空")
private Long robotTaskId;
@Schema(description = "任务类型1取放货、2停车、 3充电、4移动、5仅取货、6仅放货、7扫描码、8检测托盘类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "任务类型1取放货、2停车、 3充电、4移动、5仅取货、6仅放货、7扫描码、8检测托盘类型不能为空")
private Integer taskType;
@Schema(description = "放货类型1库位、2线库、 3区域", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "放货类型1库位、2线库、 3区域不能为空")
private Integer releaseType;
@Schema(description = "取货类型1库位、2线库、 3区域", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "取货类型1库位、2线库、 3区域不能为空")
private Integer takeType;
@Schema(description = "放货库位/线库/区域", requiredMode = Schema.RequiredMode.REQUIRED, example = "6223")
@NotNull(message = "放货库位/线库/区域不能为空")
private Long releaseId;
@Schema(description = "取货库位/线库/区域", requiredMode = Schema.RequiredMode.REQUIRED, example = "24801")
@NotNull(message = "取货库位/线库/区域不能为空")
private Long takeId;
@Schema(description = "计算后的来源库位编号")
private String fromLocationNo;
@Schema(description = "计算后的来源库位id")
private Long fromLocationId;
@Schema(description = "计算后的目标库位编号")
private String toLocationNo;
@Schema(description = "计算后的目标库位id")
private Long toLocationId;
@Schema(description = "AGV编号")
private String robotNo;
@Schema(description = "AGV动作")
private String robotAction;
@Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消)", example = "1")
private Integer taskStatus;
@Schema(description = "任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)")
private Long taskStage;
@Schema(description = "开始时间")
private LocalDateTime startTime;
@Schema(description = "结束时间")
private LocalDateTime endTime;
@Schema(description = "取货层数")
private Integer fromLocationStorey;
@Schema(description = "放货层数")
private Integer toLocationStorey;
@Schema(description = "优先级")
private Long priority;
}

View File

@ -0,0 +1,72 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 机器人任务主表分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class RobotTaskPageReqVO extends PageParam {
@Schema(description = "是否拼接任务0不拼接、1拼接")
private Integer montageTask;
@Schema(description = "拼接任务数量")
private Integer montageNumber;
@Schema(description = "物料信息")
private String skuInfo;
@Schema(description = "物料批次号")
private String skuBatch;
@Schema(description = "物料数量")
private Long skuNumber;
@Schema(description = "优先级")
private Long priority;
@Schema(description = "其他信息")
private String otherMsg;
@Schema(description = "循环(0:不循环、1循环)")
private Long doCycle;
@Schema(description = "是否搬空所选线库/区域(0:不搬空、1搬空)")
private Long doMoveAll;
@Schema(description = "循环次数")
private Long cycleNumber;
@Schema(description = "剩余循环次数默认1")
private Long remainingCycleNumber;
@Schema(description = "任务号")
private String taskNo;
@Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消)", example = "2")
private Long taskStatus;
@Schema(description = "任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)")
private Long taskStage;
@Schema(description = "开始时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] startTime;
@Schema(description = "结束时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] endTime;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,87 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 机器人任务主表 Response VO")
@Data
@ExcelIgnoreUnannotated
public class RobotTaskRespVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "15306")
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "是否拼接任务0不拼接、1拼接", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("是否拼接任务0不拼接、1拼接")
private Integer montageTask;
@Schema(description = "拼接任务数量", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("拼接任务数量")
private Integer montageNumber;
@Schema(description = "物料信息")
@ExcelProperty("物料信息")
private String skuInfo;
@Schema(description = "物料批次号")
@ExcelProperty("物料批次号")
private String skuBatch;
@Schema(description = "物料数量")
@ExcelProperty("物料数量")
private Long skuNumber;
@Schema(description = "优先级")
@ExcelProperty("优先级")
private Long priority;
@Schema(description = "其他信息")
@ExcelProperty("其他信息")
private String otherMsg;
@Schema(description = "循环(0:不循环、1循环)")
@ExcelProperty("循环(0:不循环、1循环)")
private Long doCycle;
@Schema(description = "是否搬空所选线库/区域(0:不搬空、1搬空)")
@ExcelProperty("是否搬空所选线库/区域(0:不搬空、1搬空)")
private Long doMoveAll;
@Schema(description = "循环次数")
@ExcelProperty("循环次数")
private Long cycleNumber;
@Schema(description = "剩余循环次数默认1")
@ExcelProperty("剩余循环次数默认1")
private Long remainingCycleNumber;
@Schema(description = "任务号")
@ExcelProperty("任务号")
private String taskNo;
@Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消)", example = "2")
@ExcelProperty("任务状态(0:未开始、1执行中、2已完成、3已取消)")
private Long taskStatus;
@Schema(description = "任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)")
@ExcelProperty("任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)")
private Long taskStage;
@Schema(description = "开始时间")
@ExcelProperty("开始时间")
private LocalDateTime startTime;
@Schema(description = "结束时间")
@ExcelProperty("结束时间")
private LocalDateTime endTime;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,71 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 机器人任务主表新增/修改 Request VO")
@Data
public class RobotTaskSaveReqVO {
@Schema(description = "是否拼接任务0不拼接、1拼接", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "是否拼接任务0不拼接、1拼接不能为空")
private Integer montageTask;
@Schema(description = "拼接任务数量", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "拼接任务数量不能为空")
private Integer montageNumber;
@Schema(description = "任务")
private List<RobotTaskDetailAddVo> taskDetailList;
@Schema(description = "物料信息")
private String skuInfo;
@Schema(description = "物料批次号")
private String skuBatch;
@Schema(description = "物料数量")
private Long skuNumber;
@Schema(description = "优先级")
private Long priority;
@Schema(description = "其他信息")
private String otherMsg;
@Schema(description = "循环(0:不循环、1循环)")
private Long doCycle;
@Schema(description = "是否搬空所选线库/区域(0:不搬空、1搬空)")
private Long doMoveAll;
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "15306")
private Long id;
@Schema(description = "循环次数")
private Long cycleNumber;
@Schema(description = "剩余循环次数默认1")
private Long remainingCycleNumber;
@Schema(description = "任务号")
private String taskNo;
@Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消)", example = "2")
private Long taskStatus;
@Schema(description = "任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)")
private Long taskStage;
@Schema(description = "开始时间")
private LocalDateTime startTime;
@Schema(description = "结束时间")
private LocalDateTime endTime;
}

View File

@ -0,0 +1,40 @@
package cn.iocoder.yudao.module.system.dal.dataobject.housearea;
import lombok.*;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 库区 DO
*
* @author 陈宾顺
*/
@TableName("ware_house_area")
@KeySequence("ware_house_area_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class HouseAreaDO extends BaseDO {
/**
* 主键ID
*/
@TableId
private Long id;
/**
* 库区id(自定义)
*/
private Long areaId;
/**
* 库区名称
*/
private String areaName;
/**
* 库区说明
*/
private String areaMsg;
}

View File

@ -0,0 +1,43 @@
package cn.iocoder.yudao.module.system.dal.dataobject.houselane;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 线库/巷道 DO
*
* @author 陈宾顺
*/
@TableName("ware_house_lane")
@KeySequence("ware_house_lane_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WareHouseLaneDO extends BaseDO {
/**
* 主键ID
*/
@TableId
private Long id;
/**
* 巷道id(自定义)
*/
private Long laneId;
/**
* 巷道名称
*/
private String laneName;
/**
* 巷道说明(可以拓展为区域说明)
*/
private String laneMsg;
}

View File

@ -0,0 +1,141 @@
package cn.iocoder.yudao.module.system.dal.dataobject.houselocation;
import lombok.*;
import java.util.*;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 库位 DO
*
* @author 陈宾顺
*/
@TableName("ware_house_location")
@KeySequence("ware_house_location_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WareHouseLocationDO extends BaseDO {
/**
* 主键ID
*/
@TableId
private Long id;
/**
* 巷道/线库id
*/
private Long laneId;
/**
* 巷道/线库名称
*/
private String laneName;
/**
* 库区id(自定义)
*/
private Long areaId;
/**
* 库区名称
*/
private String areaName;
/**
* 库位编号
*/
private String locationNo;
/**
* 分组名称
*/
private String groupName;
/**
* 弧度
*/
private String locationYaw;
/**
* 物料信息
*/
private String skuInfo;
/**
* 物料批次号
*/
private String skuBatch;
/**
* 物料数量
*/
private Long skuNumber;
/**
* 托盘消息
*/
private String trayInfo;
/**
* 启用/禁用0禁用1启用
*/
private Integer locationEnable;
/**
* 锁定/正常0锁定1正常
*/
private Integer locationLock;
/**
* 状态0空闲1占用
*/
private Integer locationUseStatus;
/**
* 库位坐标x轴
*/
private String locationX;
/**
* 库位坐标y轴
*/
private String locationY;
/**
* (库位上目前所放物品的宽)
*/
private BigDecimal locationWide;
/**
* (库位上目前所放物品的深)
*/
private BigDecimal locationDeep;
/**
* (库位上目前所放物品的高)
*/
private BigDecimal locationHeight;
/**
* 库位默认高度(现场有水泥高出地面的高度)
*/
private BigDecimal locationDefaultHeight;
/**
* 机车上报的高度/总高(如果两个箱子叠加就是叠加后的总高度)
*/
private BigDecimal locationTotalHeight;
/**
* 机车上报的托盘高度
*/
private BigDecimal locationTrayHeight;
/**
* 层数
*/
private Integer locationStorey;
/**
* 点位类型0库位1等待点2输送线取托盘点3出库放托盘点
*/
private Integer locationType;
/**
* 排序的位置,越大越优先堆放
*/
private Long locationNumber;
/**
* 最后一次执行任务robot_task的id
*/
private Long taskId;
}

Some files were not shown because too many files have changed in this diff Show More