diff --git a/aircraft-common/src/main/java/com/aircraft/annotation/rest/AnonymousAccess.java b/aircraft-common/src/main/java/com/aircraft/annotation/rest/AnonymousAccess.java
index eaf34e0..0f6867e 100644
--- a/aircraft-common/src/main/java/com/aircraft/annotation/rest/AnonymousAccess.java
+++ b/aircraft-common/src/main/java/com/aircraft/annotation/rest/AnonymousAccess.java
@@ -21,7 +21,7 @@ import java.lang.annotation.*;
* @author jacky
* 用于标记匿名访问方法
*/
-@Inherited
+//@Inherited
@Documented
@Target({ElementType.METHOD,ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/aircraft/mapper/AircraftDeviceMapper.java b/aircraft-system/src/main/java/com/aircraft/modules/aircraft/mapper/AircraftDeviceMapper.java
index 47f55a3..e2ba17a 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/aircraft/mapper/AircraftDeviceMapper.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/aircraft/mapper/AircraftDeviceMapper.java
@@ -9,7 +9,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import java.util.List;
-import java.util.Map;
/**
*
@@ -21,11 +20,11 @@ import java.util.Map;
*/
public interface AircraftDeviceMapper extends BaseMapper {
- Map getAircraftDeviceById(List deviceIds);
+ List getAircraftDeviceById(List deviceIds);
/**
* 分页查询 飞行器设备
*/
- IPage page(@Param("search")AircraftDevicePageDTO search, Page page);
+ IPage page(@Param("search") AircraftDevicePageDTO search, Page page);
}
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/article/controller/CpArticleController.java b/aircraft-system/src/main/java/com/aircraft/modules/article/controller/CpArticleController.java
index 1b6dd02..6166051 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/article/controller/CpArticleController.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/article/controller/CpArticleController.java
@@ -107,8 +107,8 @@ public class CpArticleController {
errorResponse.put("message", "不存在该文章");
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse);
}
- cpArticleMapper.updateViewCountById(id);
- entity.setViewCount(entity.getViewCount()+1);
+// cpArticleMapper.updateViewCountById(id);
+// entity.setViewCount(entity.getViewCount()+1);
return ResponseEntity.ok(entity);
} catch (Exception e) {
LOG.error("查询单个文章失败", e);
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/article/controller/CpMaterialController.java b/aircraft-system/src/main/java/com/aircraft/modules/article/controller/CpMaterialController.java
index 4a76312..3f8e20d 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/article/controller/CpMaterialController.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/article/controller/CpMaterialController.java
@@ -63,15 +63,12 @@ public class CpMaterialController {
@RequestParam(required = false) String keyword) {
try {
QueryWrapper wrapper = new QueryWrapper<>();
-
// 仅对素材名称进行模糊查询
if (keyword != null && !keyword.isEmpty()) {
wrapper.like("name", keyword);
}
-
- // 只查询未删除的素材
- wrapper.eq("del_flag", 0);
-
+ wrapper.eq("del_flag", 0); // 只查询未删除的素材
+ wrapper.orderByDesc("create_time");//按时间倒序排序
IPage records = materialService.page(page, wrapper);
return new ResponseEntity<>(records, HttpStatus.OK);
} catch (Exception e) {
@@ -102,7 +99,7 @@ public class CpMaterialController {
@PostMapping
public ResponseEntity add(@Valid @RequestBody CpMaterialDTO material) {
try {
- CpMaterial cpMaterial=new CpMaterial();
+ CpMaterial cpMaterial = new CpMaterial();
BeanUtils.copyProperties(material, cpMaterial);
// 填充默认值
cpMaterial.setCreateTime(LocalDateTime.now());
@@ -152,6 +149,7 @@ public class CpMaterialController {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
+
@ApiOperation(value = "删除素材", notes = "逻辑删除:将cp_material表中的del_flag设为1")
@ApiImplicitParam(name = "id", value = "素材ID", required = true, paramType = "path", dataType = "int")
@DeleteMapping("/{id}")
@@ -165,7 +163,7 @@ public class CpMaterialController {
// 逻辑删除:更新del_flag=1
material.setDelFlag(1);
- materialService.updateDelFlagById(material.getId(),material.getDelFlag());
+ materialService.updateDelFlagById(material.getId(), material.getDelFlag());
// 3. 删除成功,返回成功信息
Map success = new HashMap<>();
success.put("code", 200);
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/article/controller/CpTextController.java b/aircraft-system/src/main/java/com/aircraft/modules/article/controller/CpTextController.java
index f30eba9..0bc5d73 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/article/controller/CpTextController.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/article/controller/CpTextController.java
@@ -1,7 +1,11 @@
package com.aircraft.modules.article.controller;
+
+import com.aircraft.annotation.rest.AnonymousAccess;
+import com.aircraft.annotation.rest.AnonymousGetMapping;
import com.aircraft.modules.article.domain.CpArticle;
import com.aircraft.modules.article.domain.CpText;
import com.aircraft.modules.article.mapper.CpLabelMapper;
+import com.aircraft.modules.article.mapper.CpTextMapper;
import com.aircraft.modules.article.service.CpArticleService;
import com.aircraft.modules.article.service.CpTextService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -44,13 +48,12 @@ public class CpTextController {
@Autowired
private CpTextService cpTextService;
-
@Autowired
private CpArticleService cpArticleService;
-
@Autowired
- private CpLabelMapper cpLabelMapper;
+ private CpTextMapper cpTextMapper;
+// @AnonymousAccess
@ApiOperation(value = "分页查询文本内容", notes = "分页查询文本内容")
@RequestMapping(method = RequestMethod.GET)
@ApiImplicitParams({
@@ -101,6 +104,8 @@ public class CpTextController {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
+
+// @AnonymousAccess
@ApiOperation(value = "查询单个文本内容")
@RequestMapping(value = "{id}", method = {RequestMethod.GET})
@ApiImplicitParam(name = "id", value = "文本内容ID", required = true, paramType = "path")
@@ -110,7 +115,8 @@ public class CpTextController {
if (entity == null) {
return ResponseEntity.notFound().build();
}
-
+ cpTextMapper.updateViewCountById(id);
+ entity.setViewCount(entity.getViewCount() + 1);
return ResponseEntity.ok(entity);
} catch (Exception e) {
LOG.error("查询单个文本内容失败", e);
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/article/domain/CpText.java b/aircraft-system/src/main/java/com/aircraft/modules/article/domain/CpText.java
index b3c3d90..d253e3d 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/article/domain/CpText.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/article/domain/CpText.java
@@ -30,6 +30,9 @@ public class CpText {
@ApiModelProperty(value = "文章正文")
private String text;
+ @ApiModelProperty(value = "浏览量")
+ private Long viewCount;
+
@ApiModelProperty(value = "逻辑删除:1删除,0正常")
private Integer del_flag;
}
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/article/mapper/CpTextMapper.java b/aircraft-system/src/main/java/com/aircraft/modules/article/mapper/CpTextMapper.java
index a2fa359..62e3a8c 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/article/mapper/CpTextMapper.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/article/mapper/CpTextMapper.java
@@ -18,4 +18,6 @@ import org.apache.ibatis.annotations.Mapper;
public interface CpTextMapper extends BaseMapper {
IPage findByPage(Page page, String keyWord);
+
+ void updateViewCountById(Integer id);
}
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/OrderDetailAnalysisResult.java b/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/OrderDetailAnalysisResult.java
index 9207e60..2e5f584 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/OrderDetailAnalysisResult.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/order/domain/dto/OrderDetailAnalysisResult.java
@@ -18,6 +18,9 @@ public class OrderDetailAnalysisResult {
private BigDecimal completionRate; // 任务完成率
private BigDecimal failedRate; // 任务失败率
+ private Double averageTaskCycle; // 平均任务周期
+ private BigDecimal droneUsageRate; // 无人机使用率
+
private List routeDistribution; // 景区路线统计分布
private PageInfo pageInfo; // 分页信息
private List> orderDetailList; // 子单列表(分页)
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderAnalysisServiceImpl.java b/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderAnalysisServiceImpl.java
index 08c106a..3c89502 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderAnalysisServiceImpl.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderAnalysisServiceImpl.java
@@ -341,7 +341,13 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
.collect(Collectors.toList());
// 获取飞行设备 ID 对应的 AircraftDevice 对象的映射
- Map deviceMap = aircraftDeviceMapper.getAircraftDeviceById(deviceIds);
+ List deviceList = aircraftDeviceMapper.getAircraftDeviceById(deviceIds);
+ Map deviceMap = deviceList.stream()
+ .collect(Collectors.toMap(
+ AircraftDevice::getId, // 提取 ID 作为 key
+ device -> device, // 设备对象作为 value
+ (existing, replacement) -> existing // 处理 ID 重复(保留第一个)
+ ));
// 按型号分组统计数量(处理设备不存在的情况)
Map modelCountMap = orderDetails.stream()
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderDetailAnalysisServiceImpl.java b/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderDetailAnalysisServiceImpl.java
index 468643c..df30fba 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderDetailAnalysisServiceImpl.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/order/service/impl/OrderDetailAnalysisServiceImpl.java
@@ -1,9 +1,9 @@
package com.aircraft.modules.order.service.impl;
import com.aircraft.modules.aircraft.domain.AircraftDevice;
+import com.aircraft.modules.aircraft.service.AircraftDeviceService;
import com.aircraft.modules.order.controller.OrderAnalysisController;
import com.aircraft.modules.order.domain.OrderDetail;
-import com.aircraft.modules.order.domain.OrderMain;
import com.aircraft.modules.order.domain.dto.*;
import com.aircraft.modules.order.mapper.OrderDetailMapper;
import com.aircraft.modules.order.service.OrderDetailAnalysisService;
@@ -11,20 +11,22 @@ import com.aircraft.modules.route.domain.CpRoute;
import com.aircraft.modules.route.mapper.CpRouteMapper;
import com.aircraft.modules.system.mapper.EmScenicMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.poi.ss.formula.functions.T;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.Duration;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
+import java.time.temporal.Temporal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -51,10 +53,12 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
private CpRouteMapper cpRouteMapper;
@Autowired
private EmScenicMapper emScenicMapper;
+ @Autowired
+ private AircraftDeviceService aircraftDeviceService;
@Override
public OrderDetailAnalysisResult analyzeAllOrderDetails(List allDetails) {
- return buildOrderDetailAnalysisResult(allDetails);
+ return buildOrderDetailAnalysisResult(allDetails);
}
@Override
@@ -260,6 +264,14 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
result.setCompletionRate(calculateRate(completedCount, total));
result.setFailedRate(calculateRate(failedCount, total));
+ // 新增: 计算平均任务周期(单位:分钟)
+ double averageTaskCycle = calculateAverageTaskCycle(orderDetails);
+ result.setAverageTaskCycle(averageTaskCycle);
+
+ // 新增: 计算无人机使用率
+ BigDecimal droneUsageRate = calculateDroneUsageRate(orderDetails);
+ result.setDroneUsageRate(droneUsageRate);
+
// 5. 景区路线订单分布
result.setRouteDistribution(calculateRouteDistribution(orderDetails));
@@ -269,11 +281,53 @@ public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisServic
result.setOrderDetailList(getPagedTasks(orderDetails, pageInfo));
// 7. 时间序列数据(在调用此方法的上层设置)
- result.setTimeSeriesData(null); // 由调用者设置具体时间序列数据
+ result.setTimeSeriesData(null);
return result;
}
+ //计算平均任务周期
+ private double calculateAverageTaskCycle(List orderDetails) {
+ //获取任务数
+ List completedTasks = orderDetails.stream()
+ .filter(task -> task.getOrderItemStatus() == STATUS_COMPLETED)
+ .collect(Collectors.toList());
+ int completedTaskCount = completedTasks.size();
+ if (completedTasks.isEmpty()) {
+ return 0.0;
+ }
+ //获取时间范围内任务的执行总时间:更新时间-创建时间
+ long totalSeconds = completedTasks.stream()
+ .mapToLong(task ->
+ Duration.between(task.getCreateTime().toInstant(), task.getUpdateTime().toInstant()).getSeconds()
+ )
+ .sum();
+
+ //平均执行任务时间=总执行任务时间÷总任务数
+ return (double) totalSeconds / (60.0 * completedTaskCount);
+ }
+
+ //计算无人机使用率
+ private BigDecimal calculateDroneUsageRate(List orderDetails) {
+ // 1. 获取时间范围内订单中出现的无人机数量(去重)
+ Set usedDroneIds = orderDetails.stream()
+ .filter(task -> task.getDeviceId() != null) // 过滤使用了无人机的任务
+ .map(OrderDetail::getDeviceId)
+ .collect(Collectors.toSet());
+ int usedDroneCount = usedDroneIds.size();
+
+ // 2. 获取无人机总量
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ int totalDroneCount = aircraftDeviceService.count(queryWrapper);
+
+ // 3. 计算使用率(保留两位小数)
+ if (totalDroneCount == 0) {
+ return BigDecimal.ZERO;
+ }
+ return BigDecimal.valueOf((double) usedDroneCount / totalDroneCount)
+ .setScale(2, RoundingMode.HALF_UP);
+ }
+
/**
* 按状态统计任务数量
*/
diff --git a/aircraft-system/src/main/java/com/aircraft/modules/security/config/SpringSecurityConfig.java b/aircraft-system/src/main/java/com/aircraft/modules/security/config/SpringSecurityConfig.java
index 3d48625..caddeeb 100644
--- a/aircraft-system/src/main/java/com/aircraft/modules/security/config/SpringSecurityConfig.java
+++ b/aircraft-system/src/main/java/com/aircraft/modules/security/config/SpringSecurityConfig.java
@@ -66,6 +66,14 @@ public class SpringSecurityConfig {
protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
// 获取匿名标记
Map> anonymousUrls = AnonTagUtils.getAnonymousUrl(applicationContext);
+ // 手动添加需要匿名访问的接口路径(核心修改)
+ // 1. 分页查询接口:GET /cpText
+ anonymousUrls.computeIfAbsent(RequestMethodEnum.GET.getType(), k -> new HashSet<>())
+ .add("/cpText");
+ // 2. 通过 ID 查询接口:GET /cpText/{id}(支持任意 ID)
+ anonymousUrls.computeIfAbsent(RequestMethodEnum.GET.getType(), k -> new HashSet<>())
+ .add("/cpText/**");
+
return httpSecurity
// 禁用 CSRF
.csrf().disable()
@@ -88,6 +96,10 @@ public class SpringSecurityConfig {
// 静态资源等等
.antMatchers(
HttpMethod.GET,
+// "/swagger-ui.html",
+// "/swagger-resources/**",
+// "/*/api-docs", // Swagger API 文档接口
+// "/doc.html" , // Knife4j 文档页面
"/*.html",
"/**/*.html",
"/**/*.css",
diff --git a/aircraft-system/src/main/resources/mapper/aircraft/AircraftDeviceMapper.xml b/aircraft-system/src/main/resources/mapper/aircraft/AircraftDeviceMapper.xml
index 9b0b078..acf7666 100644
--- a/aircraft-system/src/main/resources/mapper/aircraft/AircraftDeviceMapper.xml
+++ b/aircraft-system/src/main/resources/mapper/aircraft/AircraftDeviceMapper.xml
@@ -3,22 +3,21 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
diff --git a/aircraft-system/src/main/resources/mapper/article/CpTextMapper.xml b/aircraft-system/src/main/resources/mapper/article/CpTextMapper.xml
index 0bd2cb3..a8f24bc 100644
--- a/aircraft-system/src/main/resources/mapper/article/CpTextMapper.xml
+++ b/aircraft-system/src/main/resources/mapper/article/CpTextMapper.xml
@@ -10,4 +10,11 @@
ORDER BY id DESC
+
+
+ UPDATE cp_text
+ SET view_count = view_count + 1 -- 自增1
+ WHERE id = #{id}
+ AND del_flag = 0 -- 确保只更新未删除的文章
+