From e5e540305d0653dc1313666c1ce50b65e8170230 Mon Sep 17 00:00:00 2001 From: MichaelWin Date: Wed, 25 Feb 2026 18:52:34 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=AE=BE=E5=A4=87=E6=BF=80=E6=B4=BB=EF=BC=8C=E5=B7=A5?= =?UTF-8?q?=E5=8E=82=E8=AE=BE=E5=A4=87=E6=BF=80=E6=B4=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/dto/DeviceActivationRequest.java | 7 + .../app/dto/SubmitActivityRequest.java | 19 + .../com/corewing/app/entity/BizDevice.java | 4 + .../app/entity/BizDeviceCategory.java | 3 + .../app/modules/app/AppDeviceController.java | 7 + .../service/BizDeviceActivationService.java | 2 + .../impl/BizDeviceActivationServiceImpl.java | 28 + .../java/com/corewing/app/util/DateUtils.java | 513 +++++++++++++++++- 8 files changed, 579 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/corewing/app/dto/SubmitActivityRequest.java diff --git a/src/main/java/com/corewing/app/dto/DeviceActivationRequest.java b/src/main/java/com/corewing/app/dto/DeviceActivationRequest.java index 589b788..d83c206 100644 --- a/src/main/java/com/corewing/app/dto/DeviceActivationRequest.java +++ b/src/main/java/com/corewing/app/dto/DeviceActivationRequest.java @@ -12,4 +12,11 @@ public class DeviceActivationRequest { @NotBlank(message = "MAC地址不能为空") private String mac; + @ApiModelProperty(value = "设备型号", required = true) + @NotBlank(message = "设备型号不能为空") + private String modelId; + + @ApiModelProperty(value = "时间戳", required = true) + private String timestamp; + } diff --git a/src/main/java/com/corewing/app/dto/SubmitActivityRequest.java b/src/main/java/com/corewing/app/dto/SubmitActivityRequest.java new file mode 100644 index 0000000..5bb1aae --- /dev/null +++ b/src/main/java/com/corewing/app/dto/SubmitActivityRequest.java @@ -0,0 +1,19 @@ +package com.corewing.app.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class SubmitActivityRequest { + + @ApiModelProperty("活动id") + private String activityId; + + /* 创作平台 */ + @ApiModelProperty("创作平台") + private String creationPlatform; + + /* 提交内容 */ + @ApiModelProperty("提交内容") + private String content; +} diff --git a/src/main/java/com/corewing/app/entity/BizDevice.java b/src/main/java/com/corewing/app/entity/BizDevice.java index 31db7bd..7614841 100644 --- a/src/main/java/com/corewing/app/entity/BizDevice.java +++ b/src/main/java/com/corewing/app/entity/BizDevice.java @@ -11,6 +11,7 @@ import lombok.EqualsAndHashCode; * 设备表 */ @EqualsAndHashCode(callSuper = true) + @Data @TableName("biz_device") public class BizDevice extends CommonEntity { @@ -28,6 +29,9 @@ public class BizDevice extends CommonEntity { @ApiModelProperty("公布状态") private String publicStatus; + @ApiModelProperty("型号") + private String categoryId; + @ApiModelProperty("排序") private int sortCode; diff --git a/src/main/java/com/corewing/app/entity/BizDeviceCategory.java b/src/main/java/com/corewing/app/entity/BizDeviceCategory.java index b103ed0..84af614 100644 --- a/src/main/java/com/corewing/app/entity/BizDeviceCategory.java +++ b/src/main/java/com/corewing/app/entity/BizDeviceCategory.java @@ -22,6 +22,9 @@ public class BizDeviceCategory extends CommonEntity { @ApiModelProperty("设备型号缩略图") private String thumbnail; + @ApiModelProperty("型号id") + private Integer modelId; + @ApiModelProperty("设备型号名称") private String categoryName; diff --git a/src/main/java/com/corewing/app/modules/app/AppDeviceController.java b/src/main/java/com/corewing/app/modules/app/AppDeviceController.java index b794d72..b7e2b20 100644 --- a/src/main/java/com/corewing/app/modules/app/AppDeviceController.java +++ b/src/main/java/com/corewing/app/modules/app/AppDeviceController.java @@ -31,5 +31,12 @@ public class AppDeviceController { return Result.success(activationService.activation(deviceActivationRequest)); } + @CommonLog("工厂激活设备") + @ApiOperation("工厂激活设备") + @PostMapping("factoryActivation") + public Result factoryActivation(@RequestBody DeviceActivationRequest deviceActivationRequest) { + return Result.success(activationService.factoryActivation(deviceActivationRequest)); + } + } diff --git a/src/main/java/com/corewing/app/service/BizDeviceActivationService.java b/src/main/java/com/corewing/app/service/BizDeviceActivationService.java index b0c79e1..51cc526 100644 --- a/src/main/java/com/corewing/app/service/BizDeviceActivationService.java +++ b/src/main/java/com/corewing/app/service/BizDeviceActivationService.java @@ -6,4 +6,6 @@ import com.corewing.app.entity.BizDeviceActivation; public interface BizDeviceActivationService extends IService { Boolean activation(DeviceActivationRequest deviceActivationRequest); + + Boolean factoryActivation(DeviceActivationRequest deviceActivationRequest); } diff --git a/src/main/java/com/corewing/app/service/impl/BizDeviceActivationServiceImpl.java b/src/main/java/com/corewing/app/service/impl/BizDeviceActivationServiceImpl.java index 98a50f6..f928218 100644 --- a/src/main/java/com/corewing/app/service/impl/BizDeviceActivationServiceImpl.java +++ b/src/main/java/com/corewing/app/service/impl/BizDeviceActivationServiceImpl.java @@ -7,12 +7,15 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.corewing.app.dto.DeviceActivationRequest; import com.corewing.app.entity.BizDevice; import com.corewing.app.entity.BizDeviceActivation; +import com.corewing.app.entity.BizDeviceCategory; import com.corewing.app.mapper.BizDeviceActivationMapper; import com.corewing.app.service.BizDeviceActivationService; +import com.corewing.app.service.BizDeviceCategoryService; import com.corewing.app.service.BizDeviceService; import com.corewing.app.util.CommonServletUtil; import com.corewing.app.util.IpUtil; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.Date; @@ -24,6 +27,9 @@ public class BizDeviceActivationServiceImpl extends ServiceImpl wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(BizDeviceActivation::getDeviceMac, deviceActivationRequest.getMac()); + BizDeviceActivation checkDeviceActivation = getOne(wrapper); + if(checkDeviceActivation != null) { + return false; + } + + LambdaQueryWrapper findWrapper = new LambdaQueryWrapper<>(); + findWrapper.eq(BizDeviceCategory::getModelId, deviceActivationRequest.getModelId()); + BizDeviceCategory deviceCategory = categoryService.getOne(findWrapper); + + BizDevice device = new BizDevice(); + device.setDeviceMac(deviceActivationRequest.getMac()); + device.setStatus("0"); + device.setPublicStatus("1"); + device.setCategoryId(deviceCategory.getId()); + return deviceService.save(device); + } } diff --git a/src/main/java/com/corewing/app/util/DateUtils.java b/src/main/java/com/corewing/app/util/DateUtils.java index 570000e..b76220d 100644 --- a/src/main/java/com/corewing/app/util/DateUtils.java +++ b/src/main/java/com/corewing/app/util/DateUtils.java @@ -1,21 +1,526 @@ package com.corewing.app.util; import java.text.SimpleDateFormat; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Date; public class DateUtils { - // 格式化LocalDateTime为字符串 + public static void main(String[] args) { + //2026-02-24 08:40:90 + System.out.println(isAfter(parseToLocalDateTime("2026-02-22 08:40:30"))); + } + + //==================== 字符串格式化方法 ==================== + + /** + * 将字符串格式化为LocalDateTime + * @param dateTimeStr 日期时间字符串 + * @param pattern 格式模式,如:yyyy-MM-dd HH:mm:ss + * @return LocalDateTime对象 + */ + public static LocalDateTime parseToLocalDateTime(String dateTimeStr, String pattern) { + if (dateTimeStr == null || dateTimeStr.isEmpty() || pattern == null || pattern.isEmpty()) { + return null; + } + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); + return LocalDateTime.parse(dateTimeStr, formatter); + } + + /** + * 将字符串格式化为LocalDate + * @param dateStr 日期字符串 + * @param pattern 格式模式,如:yyyy-MM-dd + * @return LocalDate对象 + */ + public static LocalDate parseToLocalDate(String dateStr, String pattern) { + if (dateStr == null || dateStr.isEmpty() || pattern == null || pattern.isEmpty()) { + return null; + } + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); + return LocalDate.parse(dateStr, formatter); + } + + /** + * 将字符串格式化为LocalTime + * @param timeStr 时间字符串 + * @param pattern 格式模式,如:HH:mm:ss + * @return LocalTime对象 + */ + public static LocalTime parseToLocalTime(String timeStr, String pattern) { + if (timeStr == null || timeStr.isEmpty() || pattern == null || pattern.isEmpty()) { + return null; + } + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); + return LocalTime.parse(timeStr, formatter); + } + + /** + * 将字符串格式化为Date + * @param dateTimeStr 日期时间字符串 + * @param pattern 格式模式,如:yyyy-MM-dd HH:mm:ss + * @return Date对象 + */ + public static Date parseToDate(String dateTimeStr, String pattern) { + if (dateTimeStr == null || dateTimeStr.isEmpty() || pattern == null || pattern.isEmpty()) { + return null; + } + try { + SimpleDateFormat sdf = new SimpleDateFormat(pattern); + return sdf.parse(dateTimeStr); + } catch (Exception e) { + throw new IllegalArgumentException("日期解析失败: " + dateTimeStr, e); + } + } + + //==================== 常用格式的快捷方法 ==================== + + /** + * 将字符串格式化为LocalDateTime(默认格式:yyyy-MM-dd HH:mm:ss) + */ + public static LocalDateTime parseToLocalDateTime(String dateTimeStr) { + return parseToLocalDateTime(dateTimeStr, "yyyy-MM-dd HH:mm:ss"); + } + + /** + * 将字符串格式化为LocalDate(默认格式:yyyy-MM-dd) + */ + public static LocalDate parseToLocalDate(String dateStr) { + return parseToLocalDate(dateStr, "yyyy-MM-dd"); + } + + /** + * 将字符串格式化为LocalTime(默认格式:HH:mm:ss) + */ + public static LocalTime parseToLocalTime(String timeStr) { + return parseToLocalTime(timeStr, "HH:mm:ss"); + } + + /** + * 将字符串格式化为Date(默认格式:yyyy-MM-dd HH:mm:ss) + */ + public static Date parseToDate(String dateTimeStr) { + return parseToDate(dateTimeStr, "yyyy-MM-dd HH:mm:ss"); + } + + //==================== 智能解析方法 ==================== + + /** + * 智能解析字符串为LocalDateTime(自动识别常见格式) + * 支持格式: + * - yyyy-MM-dd HH:mm:ss + * - yyyy/MM/dd HH:mm:ss + * - yyyy-MM-dd'T'HH:mm:ss + * - yyyy-MM-dd HH:mm + * - yyyy-MM-dd + * - yyyy/MM/dd + */ + public static LocalDateTime smartParseToLocalDateTime(String dateTimeStr) { + if (dateTimeStr == null || dateTimeStr.isEmpty()) { + return null; + } + + String str = dateTimeStr.trim(); + + // 尝试各种格式 + try { + // 格式1: yyyy-MM-dd HH:mm:ss + return LocalDateTime.parse(str, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + } catch (Exception e1) { + try { + // 格式2: yyyy/MM/dd HH:mm:ss + return LocalDateTime.parse(str, DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss")); + } catch (Exception e2) { + try { + // 格式3: yyyy-MM-dd'T'HH:mm:ss + return LocalDateTime.parse(str, DateTimeFormatter.ISO_LOCAL_DATE_TIME); + } catch (Exception e3) { + try { + // 格式4: yyyy-MM-dd HH:mm + return LocalDateTime.parse(str, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")); + } catch (Exception e4) { + try { + // 格式5: yyyy-MM-dd (转为当天开始时间) + LocalDate date = LocalDate.parse(str, DateTimeFormatter.ofPattern("yyyy-MM-dd")); + return date.atStartOfDay(); + } catch (Exception e5) { + try { + // 格式6: yyyy/MM/dd + LocalDate date = LocalDate.parse(str, DateTimeFormatter.ofPattern("yyyy/MM/dd")); + return date.atStartOfDay(); + } catch (Exception e6) { + throw new IllegalArgumentException("无法解析的日期时间字符串: " + str); + } + } + } + } + } + } + } + + /** + * 智能解析字符串为LocalDate(自动识别常见格式) + * 支持格式: + * - yyyy-MM-dd + * - yyyy/MM/dd + * - yyyyMMdd + * - dd/MM/yyyy + */ + public static LocalDate smartParseToLocalDate(String dateStr) { + if (dateStr == null || dateStr.isEmpty()) { + return null; + } + + String str = dateStr.trim(); + + try { + return LocalDate.parse(str, DateTimeFormatter.ofPattern("yyyy-MM-dd")); + } catch (Exception e1) { + try { + return LocalDate.parse(str, DateTimeFormatter.ofPattern("yyyy/MM/dd")); + } catch (Exception e2) { + try { + return LocalDate.parse(str, DateTimeFormatter.ofPattern("yyyyMMdd")); + } catch (Exception e3) { + try { + return LocalDate.parse(str, DateTimeFormatter.ofPattern("dd/MM/yyyy")); + } catch (Exception e4) { + throw new IllegalArgumentException("无法解析的日期字符串: " + str); + } + } + } + } + } + + //==================== 格式化输出方法 ==================== + + /** + * 将LocalDateTime格式化为字符串 + * @param dateTime LocalDateTime对象 + * @param pattern 格式模式 + * @return 格式化后的字符串 + */ + public static String format(LocalDateTime dateTime, String pattern) { + if (dateTime == null || pattern == null || pattern.isEmpty()) { + return ""; + } + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); + return dateTime.format(formatter); + } + + /** + * 将LocalDate格式化为字符串 + */ + public static String format(LocalDate date, String pattern) { + if (date == null || pattern == null || pattern.isEmpty()) { + return ""; + } + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); + return date.format(formatter); + } + + /** + * 将LocalTime格式化为字符串 + */ + public static String format(LocalTime time, String pattern) { + if (time == null || pattern == null || pattern.isEmpty()) { + return ""; + } + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); + return time.format(formatter); + } + + /** + * 将Date格式化为字符串 + */ public static String format(Date time, String pattern) { if (time == null || pattern == null || pattern.isEmpty()) { return ""; } - // 创建SimpleDateFormat实例 SimpleDateFormat sdf = new SimpleDateFormat(pattern); - // 格式化日期为字符串 return sdf.format(time); } -} + /** + * 将LocalDateTime格式化为默认格式:yyyy-MM-dd HH:mm:ss + */ + public static String formatDateTime(LocalDateTime dateTime) { + return format(dateTime, "yyyy-MM-dd HH:mm:ss"); + } + + /** + * 将LocalDate格式化为默认格式:yyyy-MM-dd + */ + public static String formatDate(LocalDate date) { + return format(date, "yyyy-MM-dd"); + } + + /** + * 将LocalTime格式化为默认格式:HH:mm:ss + */ + public static String formatTime(LocalTime time) { + return format(time, "HH:mm:ss"); + } + + /** + * 将Date格式化为默认格式:yyyy-MM-dd HH:mm:ss + */ + public static String formatDateTime(Date date) { + return format(date, "yyyy-MM-dd HH:mm:ss"); + } + + //==================== 判断方法 ==================== + + /** + * 判断传入时间是否大于当前时间 + * @param time 支持:Date, LocalDateTime, LocalDate, String + */ + public static boolean isAfter(Object time) { + LocalDateTime dateTime = convertToLocalDateTime(time); + return dateTime.isAfter(LocalDateTime.now()); + } + + /** + * 判断传入时间是否小于当前时间 + * @param time 支持:Date, LocalDateTime, LocalDate, String + */ + public static boolean isBefore(Object time) { + LocalDateTime dateTime = convertToLocalDateTime(time); + return dateTime.isBefore(LocalDateTime.now()); + } + + /** + * 判断传入时间是否等于当前时间(近似到分钟) + * @param time 支持:Date, LocalDateTime, LocalDate, String + */ + public static boolean isEqual(Object time) { + LocalDateTime dateTime = convertToLocalDateTime(time); + LocalDateTime now = LocalDateTime.now().withSecond(0).withNano(0); + return dateTime.withSecond(0).withNano(0).isEqual(now); + } + + //==================== 日期时间专用判断 ==================== + + /** + * 判断传入时间是否大于等于当前时间 + */ + public static boolean isAfterOrEqual(Object time) { + LocalDateTime dateTime = convertToLocalDateTime(time); + return !dateTime.isBefore(LocalDateTime.now()); + } + + /** + * 判断传入时间是否小于等于当前时间 + */ + public static boolean isBeforeOrEqual(Object time) { + LocalDateTime dateTime = convertToLocalDateTime(time); + return !dateTime.isAfter(LocalDateTime.now()); + } + + /** + * 判断传入时间是否大于等于指定时间 + * @param time 要判断的时间 + * @param targetTime 目标时间 + */ + public static boolean isAfterOrEqual(Object time, Object targetTime) { + LocalDateTime dateTime = convertToLocalDateTime(time); + LocalDateTime target = convertToLocalDateTime(targetTime); + return !dateTime.isBefore(target); + } + + /** + * 判断传入时间是否小于等于指定时间 + * @param time 要判断的时间 + * @param targetTime 目标时间 + */ + public static boolean isBeforeOrEqual(Object time, Object targetTime) { + LocalDateTime dateTime = convertToLocalDateTime(time); + LocalDateTime target = convertToLocalDateTime(targetTime); + return !dateTime.isAfter(target); + } + + /** + * 判断传入时间是否在指定时间范围内(包含边界) + * @param time 要判断的时间 + * @param start 开始时间 + * @param end 结束时间 + */ + public static boolean isBetween(Object time, Object start, Object end) { + LocalDateTime dateTime = convertToLocalDateTime(time); + LocalDateTime startTime = convertToLocalDateTime(start); + LocalDateTime endTime = convertToLocalDateTime(end); + return !dateTime.isBefore(startTime) && !dateTime.isAfter(endTime); + } + + /** + * 判断传入时间是否在指定时间范围内(不包含边界) + * @param time 要判断的时间 + * @param start 开始时间 + * @param end 结束时间 + */ + public static boolean isBetweenExclusive(Object time, Object start, Object end) { + LocalDateTime dateTime = convertToLocalDateTime(time); + LocalDateTime startTime = convertToLocalDateTime(start); + LocalDateTime endTime = convertToLocalDateTime(end); + return dateTime.isAfter(startTime) && dateTime.isBefore(endTime); + } + + //==================== 两个时间比较 ==================== + + /** + * 判断time1是否大于time2 + */ + public static boolean isAfter(Object time1, Object time2) { + LocalDateTime dt1 = convertToLocalDateTime(time1); + LocalDateTime dt2 = convertToLocalDateTime(time2); + return dt1.isAfter(dt2); + } + + /** + * 判断time1是否小于time2 + */ + public static boolean isBefore(Object time1, Object time2) { + LocalDateTime dt1 = convertToLocalDateTime(time1); + LocalDateTime dt2 = convertToLocalDateTime(time2); + return dt1.isBefore(dt2); + } + + /** + * 判断两个时间是否相等 + */ + public static boolean isEqual(Object time1, Object time2) { + LocalDateTime dt1 = convertToLocalDateTime(time1); + LocalDateTime dt2 = convertToLocalDateTime(time2); + return dt1.isEqual(dt2); + } + + //==================== 日期专用判断 ==================== + + /** + * 判断传入日期是否大于今天(只比较年月日) + */ + public static boolean isAfterDate(Object date) { + LocalDate localDate = convertToLocalDate(date); + return localDate.isAfter(LocalDate.now()); + } + + /** + * 判断传入日期是否小于今天(只比较年月日) + */ + public static boolean isBeforeDate(Object date) { + LocalDate localDate = convertToLocalDate(date); + return localDate.isBefore(LocalDate.now()); + } + + /** + * 判断传入日期是否等于今天 + */ + public static boolean isToday(Object date) { + LocalDate localDate = convertToLocalDate(date); + return localDate.isEqual(LocalDate.now()); + } + + /** + * 判断传入日期是否大于等于今天(只比较年月日) + */ + public static boolean isAfterOrEqualDate(Object date) { + LocalDate localDate = convertToLocalDate(date); + return !localDate.isBefore(LocalDate.now()); + } + + /** + * 判断传入日期是否小于等于今天(只比较年月日) + */ + public static boolean isBeforeOrEqualDate(Object date) { + LocalDate localDate = convertToLocalDate(date); + return !localDate.isAfter(LocalDate.now()); + } + + //==================== 私有转换方法 ==================== + + /** + * 将各种类型转换为LocalDateTime + */ + private static LocalDateTime convertToLocalDateTime(Object time) { + if (time == null) { + throw new IllegalArgumentException("时间不能为null"); + } + + // 1. LocalDateTime + if (time instanceof LocalDateTime) { + return (LocalDateTime) time; + } + + // 2. LocalDate + if (time instanceof LocalDate) { + return ((LocalDate) time).atStartOfDay(); + } + + // 3. Date + if (time instanceof Date) { + return ((Date) time).toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDateTime(); + } + + // 4. String + if (time instanceof String) { + return smartParseToLocalDateTime((String) time); + } + + // 5. Long (时间戳) + if (time instanceof Long) { + return LocalDateTime.ofInstant( + java.time.Instant.ofEpochMilli((Long) time), + ZoneId.systemDefault() + ); + } + + throw new IllegalArgumentException("不支持的时间类型: " + time.getClass().getName()); + } + + /** + * 将各种类型转换为LocalDate + */ + private static LocalDate convertToLocalDate(Object date) { + if (date == null) { + throw new IllegalArgumentException("日期不能为null"); + } + + // 1. LocalDate + if (date instanceof LocalDate) { + return (LocalDate) date; + } + + // 2. LocalDateTime + if (date instanceof LocalDateTime) { + return ((LocalDateTime) date).toLocalDate(); + } + + // 3. Date + if (date instanceof Date) { + return ((Date) date).toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDate(); + } + + // 4. String + if (date instanceof String) { + return smartParseToLocalDate((String) date); + } + + // 5. Long (时间戳) + if (date instanceof Long) { + return LocalDateTime.ofInstant( + java.time.Instant.ofEpochMilli((Long) date), + ZoneId.systemDefault() + ).toLocalDate(); + } + + throw new IllegalArgumentException("不支持的日期类型: " + date.getClass().getName()); + } +} \ No newline at end of file