文章增加字段+任务分析
This commit is contained in:
parent
a1445e792d
commit
16fc1183b9
@ -27,7 +27,6 @@ import org.springframework.web.bind.annotation.*;
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/aircraft/device")
|
||||
|
||||
public class AircraftDeviceController {
|
||||
|
||||
|
||||
|
@ -2,7 +2,10 @@ package com.aircraft.modules.article.controller;
|
||||
|
||||
|
||||
import com.aircraft.modules.article.domain.CpArticle;
|
||||
import com.aircraft.modules.article.domain.CpLabel;
|
||||
import com.aircraft.modules.article.domain.CpModule;
|
||||
import com.aircraft.modules.article.domain.CpText;
|
||||
import com.aircraft.modules.article.domain.dto.CpArticleDTO;
|
||||
import com.aircraft.modules.article.domain.dto.CpArticleVo;
|
||||
import com.aircraft.modules.article.domain.dto.CpLabelVo;
|
||||
import com.aircraft.modules.article.mapper.CpArticleMapper;
|
||||
@ -17,6 +20,7 @@ import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@ -27,6 +31,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.net.URI;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
|
||||
@ -109,7 +114,7 @@ public class CpArticleController {
|
||||
|
||||
@ApiOperation(value = "添加文章")
|
||||
@RequestMapping(method = {RequestMethod.POST})
|
||||
public ResponseEntity<?> add(@Valid @RequestBody final CpArticleVo cpArticleVo, final BindingResult result) {
|
||||
public ResponseEntity<?> add(@Valid @RequestBody final CpArticleDTO cpArticleDTO, final BindingResult result) {
|
||||
try {
|
||||
// 处理参数校验错误
|
||||
if (result.hasErrors()) {
|
||||
@ -130,45 +135,48 @@ public class CpArticleController {
|
||||
}
|
||||
|
||||
// 查找标签信息
|
||||
CpLabelVo cpLabelVo = cpLabelMapper.findByName(cpArticleVo.getLabelName());
|
||||
if (cpLabelVo == null) {
|
||||
CpLabel cpLabel = cpLabelMapper.findById(cpArticleDTO.getLabelId());
|
||||
if (cpLabel == null) {
|
||||
// 标签不存在时返回明确错误信息
|
||||
Map<String, Object> error = new HashMap<>();
|
||||
error.put("code", 400);
|
||||
error.put("msg", "标签不存在:标签名=" + cpArticleVo.getLabelName());
|
||||
error.put("msg", "标签不存在:标签名=" + cpArticleDTO.getLabelId());
|
||||
return ResponseEntity.badRequest().body(error);
|
||||
}
|
||||
|
||||
// 关联标签与模块(关键步骤)
|
||||
cpLabel.setModuleId(cpArticleDTO.getModuleId());
|
||||
cpLabelMapper.updateById(cpLabel); // 更新标签的模块关联
|
||||
|
||||
CpArticle cpArticle = new CpArticle();
|
||||
BeanUtils.copyProperties(cpArticleDTO, cpArticle);
|
||||
// 设置文章基础信息
|
||||
cpArticleVo.setCreateTime(LocalDateTime.now());
|
||||
cpArticleVo.setCheckState("w");// 默认未审核
|
||||
cpArticleVo.setDelFlag(0);
|
||||
cpArticleVo.setCplabelId(cpLabelVo.getId());// 关联标签ID
|
||||
cpArticle.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
|
||||
cpArticle.setCheckState("t");// 默认已审核
|
||||
cpArticle.setDelFlag(0);
|
||||
cpArticle.setCplabelId(cpLabel.getId());// 关联标签ID
|
||||
|
||||
Long authorId = getCurrentUserId();
|
||||
|
||||
// 设置作者ID
|
||||
cpArticleVo.setAuthorId(authorId);
|
||||
entityService.save(cpArticleVo);
|
||||
// 保存文章主信息
|
||||
entityService.save(cpArticleVo);
|
||||
cpArticle.setAuthorId(authorId);
|
||||
entityService.save(cpArticle);
|
||||
|
||||
// 保存文章内容
|
||||
CpText cpText = new CpText();
|
||||
cpText.setText(cpArticleVo.getText());
|
||||
cpText.setText(cpArticleDTO.getText());
|
||||
cpTextService.save(cpText);
|
||||
|
||||
// 回填文章内容ID并更新
|
||||
cpArticleVo.setTextid(cpText.getId());
|
||||
entityService.updateById(cpArticleVo);
|
||||
cpArticle.setTextid(cpText.getId());
|
||||
entityService.updateById(cpArticle);
|
||||
|
||||
// 返回创建成功的响应
|
||||
Map<String, Object> success = new HashMap<>();
|
||||
success.put("code", 201);
|
||||
success.put("msg", "文章创建成功");
|
||||
success.put("data", cpArticleVo);
|
||||
success.put("data", cpArticle);
|
||||
return ResponseEntity
|
||||
.created(URI.create("/cpArticle/" + cpArticleVo.getId()))
|
||||
.created(URI.create("/cpArticle/" + cpArticle.getId()))
|
||||
.body(success);
|
||||
} catch (Exception e) {
|
||||
LOG.error("添加文章失败", e);
|
||||
|
@ -21,7 +21,7 @@ import java.time.LocalDateTime;
|
||||
*/
|
||||
@Data
|
||||
@TableName("cp_article")
|
||||
public class CpArticle {
|
||||
public class CpArticle extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ -47,16 +47,13 @@ public class CpArticle {
|
||||
@ApiModelProperty(value = "类型id,关联标签表id")
|
||||
private Integer cplabelId;
|
||||
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
@ApiModelProperty(value = "是否置顶:1-置顶,0-不置顶")
|
||||
private Integer top;
|
||||
|
||||
@ApiModelProperty(value = "发布者id(用户表或管理员表由发布者类型决定)")
|
||||
private Long authorId;
|
||||
|
||||
@ApiModelProperty(value = "审核状态:t-审核通过,f-不通过,w-未审核")
|
||||
private String checkState;
|
||||
|
||||
@ApiModelProperty(value = "删除标记:“1”已删除,“0”正常")
|
||||
private Integer delFlag;
|
||||
private String checkState = "t";
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
package com.aircraft.modules.article.domain.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
@Data
|
||||
public class CpArticleDTO {
|
||||
@NotBlank(message = "标题不能为空")
|
||||
@ApiModelProperty(value = "文章标题", required = true)
|
||||
private String title;
|
||||
|
||||
@ApiModelProperty(value = "封面图片URL")
|
||||
private String photo;
|
||||
|
||||
@ApiModelProperty(value = "文章类型:0-图文,1-外链", allowableValues = "0,1")
|
||||
private Integer articleType;
|
||||
|
||||
@ApiModelProperty(value = "文章外链")
|
||||
private String url;
|
||||
|
||||
@NotBlank(message = "标签id不能为空")
|
||||
@ApiModelProperty(value = "标签ID", required = true)
|
||||
private int labelId;
|
||||
|
||||
@ApiModelProperty(value = "模块ID", required = true)
|
||||
private int moduleId;
|
||||
|
||||
@NotBlank(message = "文章内容不能为空")
|
||||
@ApiModelProperty(value = "文章正文内容", required = true)
|
||||
private String text;
|
||||
|
||||
@ApiModelProperty(value = "是否置顶:1-置顶,0-不置顶")
|
||||
private Integer top;
|
||||
}
|
@ -24,4 +24,7 @@ public interface CpLabelMapper extends BaseMapper<CpLabel> {
|
||||
List<CpLabelVo> selectLabelTreeByModuleId(Integer moduleId);
|
||||
|
||||
void updateDelFlagById(Integer id, Integer delFlag);
|
||||
|
||||
@Select("SELECT * FROM cp_label WHERE id = #{labelId}")
|
||||
CpLabelVo findById(int labelId);
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package com.aircraft.modules.order.controller;
|
||||
|
||||
import com.aircraft.modules.order.domain.OrderMain;
|
||||
import com.aircraft.modules.order.domain.dto.*;
|
||||
import com.aircraft.modules.order.mapper.OrderMainMapper;
|
||||
import com.aircraft.modules.order.service.IOrderMainService;
|
||||
import com.aircraft.modules.order.service.OrderAnalysisService;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
@ -13,7 +12,6 @@ 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.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@ -22,7 +20,6 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@ -69,7 +66,7 @@ public class OrderAnalysisController {
|
||||
@ApiOperation("按日范围分析订单")
|
||||
@GetMapping("/day")
|
||||
//额外返回传入时间范围内的每日订单总量
|
||||
public ResponseEntity<OrderAnalysisResult<List<OrderDailyStat>>> analyzeByDayRange(
|
||||
public ResponseEntity<OrderAnalysisResult<List<DailyStat>>> analyzeByDayRange(
|
||||
@ApiParam(value = "开始日期(yyyy-MM-dd)", required = true, example = "2025-01-01")
|
||||
@RequestParam("startDate") String startDate,
|
||||
@ApiParam(value = "结束日期(yyyy-MM-dd)", required = true, example = "2025-01-31")
|
||||
@ -86,7 +83,7 @@ public class OrderAnalysisController {
|
||||
}
|
||||
|
||||
// 调用服务层
|
||||
OrderAnalysisResult<List<OrderDailyStat>> result = orderAnalysisService.analyzeByDayRange(start, end);
|
||||
OrderAnalysisResult<List<DailyStat>> result = orderAnalysisService.analyzeByDayRange(start, end);
|
||||
LOG.info("按日分析完成,时间范围:{}至{}", startDate, endDate);
|
||||
return ResponseEntity.ok(result);
|
||||
} catch (Exception e) {
|
||||
@ -98,7 +95,7 @@ public class OrderAnalysisController {
|
||||
@ApiOperation("按月范围分析订单")
|
||||
@GetMapping("/month")
|
||||
//传入的时间范围:某年的某月到某年的某月,额外返回时间范围内的每月总订单量
|
||||
public ResponseEntity<OrderAnalysisResult<List<OrderMonthlyStat>>> analyzeByMonthRange(
|
||||
public ResponseEntity<OrderAnalysisResult<List<MonthlyStat>>> analyzeByMonthRange(
|
||||
@ApiParam(value = "开始月份(yyyy-MM)", required = true, example = "2025-01")
|
||||
@RequestParam("startDate") String startDate,
|
||||
@ApiParam(value = "结束月份(yyyy-MM)", required = true, example = "2025-03")
|
||||
@ -117,7 +114,7 @@ public class OrderAnalysisController {
|
||||
}
|
||||
|
||||
// 调用服务层
|
||||
OrderAnalysisResult<List<OrderMonthlyStat>> result = orderAnalysisService.analyzeByMonthRange(start, end);
|
||||
OrderAnalysisResult<List<MonthlyStat>> result = orderAnalysisService.analyzeByMonthRange(start, end);
|
||||
LOG.info("按月分析完成,时间范围:{}至{}", startDate, endDate);
|
||||
return ResponseEntity.ok(result);
|
||||
} catch (Exception e) {
|
||||
@ -129,7 +126,7 @@ public class OrderAnalysisController {
|
||||
@ApiOperation("按季度范围分析订单")
|
||||
@GetMapping("/quarter")
|
||||
//传入的时间范围:某年的某季到某年的某季,yyyy-Qn (例: 2025-Q1),额外返回时间范围内的每季总订单量
|
||||
public ResponseEntity<OrderAnalysisResult<List<OrderQuarterlyStat>>> analyzeByQuarterRange(
|
||||
public ResponseEntity<OrderAnalysisResult<List<QuarterlyStat>>> analyzeByQuarterRange(
|
||||
@ApiParam(value = "开始季度(yyyy-Qn,例:2025-Q1)", required = true)
|
||||
@RequestParam("startDate") String startDate,
|
||||
@ApiParam(value = "结束季度(yyyy-Qn,例:2025-Q4)", required = true)
|
||||
@ -161,7 +158,7 @@ public class OrderAnalysisController {
|
||||
}
|
||||
|
||||
// 调用服务层
|
||||
OrderAnalysisResult<List<OrderQuarterlyStat>> result = orderAnalysisService.analyzeByQuarterRange(start, end);
|
||||
OrderAnalysisResult<List<QuarterlyStat>> result = orderAnalysisService.analyzeByQuarterRange(start, end);
|
||||
LOG.info("按季度分析完成,时间范围:{}至{}", startDate, endDate);
|
||||
return ResponseEntity.ok(result);
|
||||
} catch (Exception e) {
|
||||
@ -174,7 +171,7 @@ public class OrderAnalysisController {
|
||||
@ApiOperation("按年范围分析订单")
|
||||
@GetMapping("/year")
|
||||
//传入的时间范围;某年到某年,额外返回时间范围内的每年总订单量
|
||||
public ResponseEntity<OrderAnalysisResult<List<OrderYearlyStat>>> analyzeByYearRange(
|
||||
public ResponseEntity<OrderAnalysisResult<List<YearlyStat>>> analyzeByYearRange(
|
||||
@ApiParam(value = "开始年份(yyyy)", required = true, example = "2023")
|
||||
@RequestParam("startDate") String startDate,
|
||||
@ApiParam(value = "结束年份(yyyy)", required = true, example = "2025")
|
||||
@ -191,7 +188,7 @@ public class OrderAnalysisController {
|
||||
}
|
||||
|
||||
// 调用服务层
|
||||
OrderAnalysisResult<List<OrderYearlyStat>> result = orderAnalysisService.analyzeByYearRange(start, end);
|
||||
OrderAnalysisResult<List<YearlyStat>> result = orderAnalysisService.analyzeByYearRange(start, end);
|
||||
LOG.info("按年分析完成,时间范围:{}至{}", startDate, endDate);
|
||||
return ResponseEntity.ok(result);
|
||||
} catch (Exception e) {
|
||||
|
@ -0,0 +1,207 @@
|
||||
package com.aircraft.modules.order.controller;
|
||||
|
||||
import com.aircraft.modules.order.domain.OrderDetail;
|
||||
import com.aircraft.modules.order.domain.dto.*;
|
||||
import com.aircraft.modules.order.service.IOrderDetailService;
|
||||
import com.aircraft.modules.order.service.OrderDetailAnalysisService;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Api(tags = "系统:子单任务分析")
|
||||
@RestController
|
||||
@RequestMapping("/fmsOdOrderDetailAnalysis")
|
||||
//统一返回时间范围内任务总量,任务状态统计以及任务状态分布,景区路线任务分布
|
||||
public class OrderDetailAnalysisController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(OrderDetailAnalysisController.class);
|
||||
|
||||
@Autowired
|
||||
private OrderDetailAnalysisService orderDetailAnalysisService; // 子单分析服务层
|
||||
@Autowired
|
||||
private IOrderDetailService orderDetailService;
|
||||
|
||||
// 日期格式化器
|
||||
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
private static final Pattern QUARTER_PATTERN = Pattern.compile("^\\d{4}-Q[1-4]$");
|
||||
|
||||
|
||||
@ApiOperation("全部子单任务分析统计")
|
||||
@GetMapping
|
||||
public ResponseEntity<OrderDetailAnalysisResult<T>> analyzeAllOrderDetails() {
|
||||
try {
|
||||
// 1. 获取所有子单数据
|
||||
List<OrderDetail> allDetails = orderDetailService.list();
|
||||
|
||||
// 2. 校验数据
|
||||
if (CollectionUtils.isEmpty(allDetails)) {
|
||||
LOG.info("全部子单分析:未找到子单数据");
|
||||
return ResponseEntity.badRequest().body(null);
|
||||
}
|
||||
OrderDetailAnalysisResult<T> result = orderDetailAnalysisService.analyzeAllOrderDetails(allDetails);
|
||||
return ResponseEntity.ok(result);
|
||||
} catch (Exception e) {
|
||||
LOG.error("全部子单分析失败", e);
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("按日范围分析子单任务")
|
||||
@GetMapping("/day")
|
||||
// 额外返回:时间范围内任务列表
|
||||
public ResponseEntity<OrderDetailAnalysisResult<List<DailyStat>>> analyzeByDayRange(
|
||||
@ApiParam(value = "开始日期(yyyy-MM-dd)", required = true, example = "2025-01-01")
|
||||
@RequestParam("startDate") String startDate,
|
||||
@ApiParam(value = "结束日期(yyyy-MM-dd)", required = true, example = "2025-01-31")
|
||||
@RequestParam("endDate") String endDate) {
|
||||
try {
|
||||
// 解析并校验日期
|
||||
LocalDate start = LocalDate.parse(startDate, DATE_FORMATTER);
|
||||
LocalDate end = LocalDate.parse(endDate, DATE_FORMATTER);
|
||||
if (start.isAfter(end)) {
|
||||
LOG.warn("按日分析子单:开始日期[{}]晚于结束日期[{}]", startDate, endDate);
|
||||
return ResponseEntity.badRequest().body(null);
|
||||
}
|
||||
OrderDetailAnalysisResult<List<DailyStat>> result =
|
||||
orderDetailAnalysisService.analyzeByDayRange(start, end);
|
||||
LOG.info("子单按日分析完成,时间范围:{}至{}", startDate, endDate);
|
||||
return ResponseEntity.ok(result);
|
||||
} catch (Exception e) {
|
||||
LOG.error("子单按日分析失败,参数:startDate={}, endDate={}", startDate, endDate, e);
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("按月范围分析子单任务")
|
||||
@GetMapping("/month")
|
||||
// 额外返回:时间范围内任务列表
|
||||
public ResponseEntity<OrderDetailAnalysisResult<List<MonthlyStat>>> analyzeByMonthRange(
|
||||
@ApiParam(value = "开始月份(yyyy-MM)", required = true, example = "2025-01")
|
||||
@RequestParam("startDate") String startDate,
|
||||
@ApiParam(value = "结束月份(yyyy-MM)", required = true, example = "2025-03")
|
||||
@RequestParam("endDate") String endDate) {
|
||||
try {
|
||||
// 解析月份为当月第一天和最后一天
|
||||
LocalDate start = LocalDate.parse(startDate + "-01", DATE_FORMATTER);
|
||||
LocalDate end = LocalDate.parse(endDate + "-01", DATE_FORMATTER)
|
||||
.withDayOfMonth(LocalDate.parse(endDate + "-01", DATE_FORMATTER).lengthOfMonth());
|
||||
|
||||
if (start.isAfter(end)) {
|
||||
LOG.warn("子单按月分析:开始月份[{}]晚于结束月份[{}]", startDate, endDate);
|
||||
return ResponseEntity.badRequest().body(null);
|
||||
}
|
||||
|
||||
OrderDetailAnalysisResult<List<MonthlyStat>> result =
|
||||
orderDetailAnalysisService.analyzeByMonthRange(start, end);
|
||||
LOG.info("子单按月分析完成,时间范围:{}至{}", startDate, endDate);
|
||||
return ResponseEntity.ok(result);
|
||||
} catch (Exception e) {
|
||||
LOG.error("子单按月分析失败,参数:startDate={}, endDate={}", startDate, endDate, e);
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("按季度范围分析子单任务")
|
||||
@GetMapping("/quarter")
|
||||
// 额外返回:时间范围内任务列表
|
||||
public ResponseEntity<OrderDetailAnalysisResult<List<QuarterlyStat>>> analyzeByQuarterRange(
|
||||
@ApiParam(value = "开始季度(yyyy-Qn,例:2025-Q1)", required = true)
|
||||
@RequestParam("startDate") String startDate,
|
||||
@ApiParam(value = "结束季度(yyyy-Qn,例:2025-Q4)", required = true)
|
||||
@RequestParam("endDate") String endDate) {
|
||||
try {
|
||||
// 校验季度格式
|
||||
if (!QUARTER_PATTERN.matcher(startDate).matches() || !QUARTER_PATTERN.matcher(endDate).matches()) {
|
||||
LOG.warn("子单按季度分析:格式错误,正确格式:yyyy-Q1~Q4");
|
||||
return ResponseEntity.badRequest().body(null);
|
||||
}
|
||||
|
||||
// 解析季度为日期范围
|
||||
String[] startParts = startDate.split("-Q");
|
||||
int startYear = Integer.parseInt(startParts[0]);
|
||||
int startQuarter = Integer.parseInt(startParts[1]);
|
||||
|
||||
String[] endParts = endDate.split("-Q");
|
||||
int endYear = Integer.parseInt(endParts[0]);
|
||||
int endQuarter = Integer.parseInt(endParts[1]);
|
||||
|
||||
LocalDate start = getQuarterFirstDay(startYear, startQuarter);
|
||||
LocalDate end = getQuarterLastDay(endYear, endQuarter);
|
||||
|
||||
if (start.isAfter(end)) {
|
||||
LOG.warn("子单按季度分析:开始季度[{}]晚于结束季度[{}]", startDate, endDate);
|
||||
return ResponseEntity.badRequest().body(null);
|
||||
}
|
||||
|
||||
// 调用服务层:按季度统计子单量、路线热度、操作员效率
|
||||
OrderDetailAnalysisResult<List<QuarterlyStat>> result =
|
||||
orderDetailAnalysisService.analyzeByQuarterRange(start, end);
|
||||
LOG.info("子单按季度分析完成,时间范围:{}至{}", startDate, endDate);
|
||||
return ResponseEntity.ok(result);
|
||||
} catch (Exception e) {
|
||||
LOG.error("子单按季度分析失败,参数:startDate={}, endDate={}", startDate, endDate, e);
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("按年范围分析子单任务")
|
||||
@GetMapping("/year")
|
||||
// 额外返回:时间范围内任务列表
|
||||
public ResponseEntity<OrderDetailAnalysisResult<List<YearlyStat>>> analyzeByYearRange(
|
||||
@ApiParam(value = "开始年份(yyyy)", required = true, example = "2023")
|
||||
@RequestParam("startDate") String startDate,
|
||||
@ApiParam(value = "结束年份(yyyy)", required = true, example = "2025")
|
||||
@RequestParam("endDate") String endDate) {
|
||||
try {
|
||||
// 解析年份为当年第一天和最后一天
|
||||
LocalDate start = LocalDate.parse(startDate + "-01-01", DATE_FORMATTER);
|
||||
LocalDate end = LocalDate.parse(endDate + "-12-31", DATE_FORMATTER);
|
||||
|
||||
if (start.isAfter(end)) {
|
||||
LOG.warn("子单按年分析:开始年份[{}]晚于结束年份[{}]", startDate, endDate);
|
||||
return ResponseEntity.badRequest().body(null);
|
||||
}
|
||||
|
||||
// 调用服务层:按年统计子单总量、设备/路线年度表现、载人特征变化
|
||||
OrderDetailAnalysisResult<List<YearlyStat>> result =
|
||||
orderDetailAnalysisService.analyzeByYearRange(start, end);
|
||||
LOG.info("子单按年分析完成,时间范围:{}至{}", startDate, endDate);
|
||||
return ResponseEntity.ok(result);
|
||||
} catch (Exception e) {
|
||||
LOG.error("子单按年分析失败,参数:startDate={}, endDate={}", startDate, endDate, e);
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 工具方法:复用原有季度日期转换逻辑
|
||||
private LocalDate getQuarterFirstDay(int year, int quarter) {
|
||||
int month = (quarter - 1) * 3 + 1;
|
||||
return LocalDate.of(year, month, 1);
|
||||
}
|
||||
|
||||
private LocalDate getQuarterLastDay(int year, int quarter) {
|
||||
int month = quarter * 3;
|
||||
return LocalDate.of(year, month, 1).withDayOfMonth(LocalDate.of(year, month, 1).lengthOfMonth());
|
||||
}
|
||||
}
|
@ -2,9 +2,9 @@ package com.aircraft.modules.order.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
//每日的订单总量统计实体类
|
||||
//总量统计实体类
|
||||
@Data
|
||||
public class OrderDailyStat {
|
||||
public class DailyStat {
|
||||
private String date;
|
||||
private Long orderCount;
|
||||
private Long dailyCount;//每日数量
|
||||
}
|
@ -3,7 +3,7 @@ package com.aircraft.modules.order.domain.dto;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class OrderMonthlyStat {
|
||||
public class MonthlyStat {
|
||||
private String month;
|
||||
private Long orderCount;
|
||||
private Long monthlyCount;//每月数量
|
||||
}
|
@ -18,7 +18,8 @@ public class OrderAnalysisResult<T> {
|
||||
private PageInfo pageInfo; // 分页信息
|
||||
private List<?> orderList; // 订单列表
|
||||
private Map<String, Double> droneModelDistribution; // 无人机型号订单占比
|
||||
private Map<String, Long> routeOrderDistribution; // 不同区域的订单总量
|
||||
private List<RouteStat> routeDistribution;//景区-路线的订单分布
|
||||
// private Map<String, Long> routeOrderDistribution; // 不同区域的订单总量
|
||||
private T timeSeriesData; // 时间序列数据(日/月/年统计)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,25 @@
|
||||
package com.aircraft.modules.order.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class OrderDetailAnalysisResult<T> {
|
||||
private Long totalTaskCount; // 总子单(任务)量
|
||||
private Long notStartedTaskCount; //未进行任务量
|
||||
private Long processingTaskCount; // 进行中任务量
|
||||
private Long completedTaskCount; // 已完成任务量
|
||||
private Long failedTaskCount; // 任务执行失败量
|
||||
private BigDecimal notStartedRate; // 任务未进行率
|
||||
private BigDecimal processingRate; // 任务进行率
|
||||
private BigDecimal completionRate; // 任务完成率
|
||||
private BigDecimal failedRate; // 任务失败率
|
||||
|
||||
private List<RouteStat> routeDistribution; // 景区路线统计分布
|
||||
private PageInfo pageInfo; // 分页信息
|
||||
private List<?> orderDetailList; // 子单列表(分页)
|
||||
private T timeSeriesData; // 时间序列数据(日/月/年统计)
|
||||
}
|
@ -3,7 +3,7 @@ package com.aircraft.modules.order.domain.dto;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class OrderQuarterlyStat {
|
||||
public class QuarterlyStat {
|
||||
private String quarter; // 季度标识(如2025-Q1)
|
||||
private Long orderCount; // 本季度订单总量
|
||||
private Long QuarterlyCount; // 每季度数量
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.aircraft.modules.order.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class RouteStat {
|
||||
private String scenicName;//景区名称,通过路线id获得景区id
|
||||
private String routeName;//路线名称
|
||||
private Long routeId ;//路线id
|
||||
private Long count;//某路线的订单/任务数量
|
||||
}
|
@ -3,7 +3,7 @@ package com.aircraft.modules.order.domain.dto;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class OrderYearlyStat {
|
||||
public class YearlyStat {
|
||||
private String year;
|
||||
private Long orderCount;
|
||||
private Long yearlyCount;
|
||||
}
|
@ -3,7 +3,6 @@ package com.aircraft.modules.order.service;
|
||||
|
||||
import com.aircraft.modules.order.domain.OrderMain;
|
||||
import com.aircraft.modules.order.domain.dto.*;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDate;
|
||||
@ -11,13 +10,13 @@ import java.util.List;
|
||||
|
||||
@Service
|
||||
public interface OrderAnalysisService {
|
||||
OrderAnalysisResult<List<OrderDailyStat>> analyzeByDayRange(LocalDate start, LocalDate end);
|
||||
OrderAnalysisResult<List<DailyStat>> analyzeByDayRange(LocalDate start, LocalDate end);
|
||||
|
||||
OrderAnalysisResult<List<OrderMonthlyStat>> analyzeByMonthRange(LocalDate start, LocalDate end);
|
||||
OrderAnalysisResult<List<MonthlyStat>> analyzeByMonthRange(LocalDate start, LocalDate end);
|
||||
|
||||
OrderAnalysisResult<List<OrderQuarterlyStat>> analyzeByQuarterRange(LocalDate start, LocalDate end);
|
||||
OrderAnalysisResult<List<QuarterlyStat>> analyzeByQuarterRange(LocalDate start, LocalDate end);
|
||||
|
||||
OrderAnalysisResult<List<OrderYearlyStat>> analyzeByYearRange(LocalDate start, LocalDate end);
|
||||
OrderAnalysisResult<List<YearlyStat>> analyzeByYearRange(LocalDate start, LocalDate end);
|
||||
|
||||
<T> OrderAnalysisResult<T> analyzeAllOrders(List<OrderMain> allOrders);
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
package com.aircraft.modules.order.service;
|
||||
|
||||
import com.aircraft.modules.order.domain.OrderDetail;
|
||||
import com.aircraft.modules.order.domain.dto.*;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public interface OrderDetailAnalysisService {
|
||||
OrderDetailAnalysisResult<T> analyzeAllOrderDetails(List<OrderDetail> allDetails);
|
||||
|
||||
OrderDetailAnalysisResult<List<DailyStat>> analyzeByDayRange(LocalDate start, LocalDate end);
|
||||
|
||||
OrderDetailAnalysisResult<List<MonthlyStat>> analyzeByMonthRange(LocalDate start, LocalDate end);
|
||||
|
||||
OrderDetailAnalysisResult<List<QuarterlyStat>> analyzeByQuarterRange(LocalDate start, LocalDate end);
|
||||
|
||||
OrderDetailAnalysisResult<List<YearlyStat>> analyzeByYearRange(LocalDate start, LocalDate end);
|
||||
}
|
@ -2,15 +2,20 @@ package com.aircraft.modules.order.service.impl;
|
||||
|
||||
import com.aircraft.modules.aircraft.domain.AircraftDevice;
|
||||
import com.aircraft.modules.aircraft.mapper.AircraftDeviceMapper;
|
||||
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.mapper.OrderMainMapper;
|
||||
import com.aircraft.modules.order.service.OrderAnalysisService;
|
||||
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 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;
|
||||
@ -36,6 +41,9 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
|
||||
private OrderDetailMapper orderDetailMapper;
|
||||
@Autowired
|
||||
private CpRouteMapper cpRouteMapper;
|
||||
@Autowired
|
||||
private EmScenicMapper emScenicMapper;
|
||||
private static final Logger LOG = LoggerFactory.getLogger(OrderAnalysisController.class);
|
||||
|
||||
// 日期格式化器(用于按日/月/季度/年分组)
|
||||
private static final DateTimeFormatter DAY_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
@ -54,7 +62,7 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
|
||||
* 按日范围分析订单
|
||||
*/
|
||||
@Override
|
||||
public OrderAnalysisResult<List<OrderDailyStat>> analyzeByDayRange(LocalDate start, LocalDate end) {
|
||||
public OrderAnalysisResult<List<DailyStat>> analyzeByDayRange(LocalDate start, LocalDate end) {
|
||||
// 1. 查询时间范围内的所有订单
|
||||
List<OrderMain> orders = queryOrdersByDateRange(start, end);
|
||||
if (CollectionUtils.isEmpty(orders)) {
|
||||
@ -74,13 +82,13 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
|
||||
System.out.println(dailyCountMap);
|
||||
|
||||
// 3. 填充每日统计数据(确保日期连续性,即使某天无订单也显示0)
|
||||
List<OrderDailyStat> dailyStats = new ArrayList<>();
|
||||
List<DailyStat> dailyStats = new ArrayList<>();
|
||||
LocalDate current = start;
|
||||
while (!current.isAfter(end)) {
|
||||
String dateStr = current.format(DAY_FORMATTER);
|
||||
OrderDailyStat stat = new OrderDailyStat();
|
||||
DailyStat stat = new DailyStat();
|
||||
stat.setDate(dateStr);
|
||||
stat.setOrderCount(dailyCountMap.getOrDefault(dateStr, 0L));
|
||||
stat.setDailyCount(dailyCountMap.getOrDefault(dateStr, 0L));
|
||||
dailyStats.add(stat);
|
||||
current = current.plusDays(1); // 移至下一天
|
||||
}
|
||||
@ -94,7 +102,7 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
|
||||
* 按月范围分析订单
|
||||
*/
|
||||
@Override
|
||||
public OrderAnalysisResult<List<OrderMonthlyStat>> analyzeByMonthRange(LocalDate start, LocalDate end) {
|
||||
public OrderAnalysisResult<List<MonthlyStat>> analyzeByMonthRange(LocalDate start, LocalDate end) {
|
||||
// 1. 查询时间范围内的所有订单
|
||||
List<OrderMain> orders = queryOrdersByDateRange(start, end);
|
||||
if (CollectionUtils.isEmpty(orders)) {
|
||||
@ -112,15 +120,15 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
|
||||
));
|
||||
|
||||
// 3. 填充每月统计数据(确保月份连续性)
|
||||
List<OrderMonthlyStat> monthlyStats = new ArrayList<>();
|
||||
List<MonthlyStat> monthlyStats = new ArrayList<>();
|
||||
LocalDate current = start.withDayOfMonth(1); // 从当月第一天开始
|
||||
LocalDate endMonth = end.withDayOfMonth(1); // 结束月份第一天
|
||||
|
||||
while (!current.isAfter(endMonth)) {
|
||||
String monthStr = current.format(MONTH_FORMATTER);
|
||||
OrderMonthlyStat stat = new OrderMonthlyStat();
|
||||
MonthlyStat stat = new MonthlyStat();
|
||||
stat.setMonth(monthStr);
|
||||
stat.setOrderCount(monthlyCountMap.getOrDefault(monthStr, 0L));
|
||||
stat.setMonthlyCount(monthlyCountMap.getOrDefault(monthStr, 0L));
|
||||
monthlyStats.add(stat);
|
||||
current = current.plusMonths(1); // 移至下一月
|
||||
}
|
||||
@ -134,7 +142,7 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
|
||||
* 按季度范围分析订单
|
||||
*/
|
||||
@Override
|
||||
public OrderAnalysisResult<List<OrderQuarterlyStat>> analyzeByQuarterRange(LocalDate start, LocalDate end) {
|
||||
public OrderAnalysisResult<List<QuarterlyStat>> analyzeByQuarterRange(LocalDate start, LocalDate end) {
|
||||
// 1. 查询时间范围内的所有订单
|
||||
List<OrderMain> orders = queryOrdersByDateRange(start, end);
|
||||
if (CollectionUtils.isEmpty(orders)) {
|
||||
@ -154,7 +162,7 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
|
||||
));
|
||||
|
||||
// 3. 填充每季度统计数据(确保季度连续性)
|
||||
List<OrderQuarterlyStat> quarterlyStats = new ArrayList<>();
|
||||
List<QuarterlyStat> quarterlyStats = new ArrayList<>();
|
||||
LocalDate currentQuarterStart = start;
|
||||
// 调整至当前季度第一天(如2025-05-10 → 2025-04-01)
|
||||
currentQuarterStart = currentQuarterStart.minusMonths((currentQuarterStart.getMonthValue() - 1) % 3);
|
||||
@ -165,9 +173,9 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
|
||||
int quarter = (currentQuarterStart.getMonthValue() - 1) / 3 + 1;
|
||||
String quarterStr = currentQuarterStart.format(YEAR_FORMATTER) + "-Q" + quarter;
|
||||
|
||||
OrderQuarterlyStat stat = new OrderQuarterlyStat();
|
||||
QuarterlyStat stat = new QuarterlyStat();
|
||||
stat.setQuarter(quarterStr);
|
||||
stat.setOrderCount(quarterCountMap.getOrDefault(quarterStr, 0L));
|
||||
stat.setQuarterlyCount(quarterCountMap.getOrDefault(quarterStr, 0L));
|
||||
quarterlyStats.add(stat);
|
||||
|
||||
// 移至下一季度第一天
|
||||
@ -183,7 +191,7 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
|
||||
* 按年范围分析订单
|
||||
*/
|
||||
@Override
|
||||
public OrderAnalysisResult<List<OrderYearlyStat>> analyzeByYearRange(LocalDate start, LocalDate end) {
|
||||
public OrderAnalysisResult<List<YearlyStat>> analyzeByYearRange(LocalDate start, LocalDate end) {
|
||||
// 1. 查询时间范围内的所有订单
|
||||
List<OrderMain> orders = queryOrdersByDateRange(start, end);
|
||||
if (CollectionUtils.isEmpty(orders)) {
|
||||
@ -200,15 +208,15 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
|
||||
Collectors.counting()
|
||||
));
|
||||
// 3. 填充每年统计数据(确保年份连续性)
|
||||
List<OrderYearlyStat> yearlyStats = new ArrayList<>();
|
||||
List<YearlyStat> yearlyStats = new ArrayList<>();
|
||||
int startYear = start.getYear();
|
||||
int endYear = end.getYear();
|
||||
|
||||
for (int year = startYear; year <= endYear; year++) {
|
||||
String yearStr = String.valueOf(year);
|
||||
OrderYearlyStat stat = new OrderYearlyStat();
|
||||
YearlyStat stat = new YearlyStat();
|
||||
stat.setYear(yearStr);
|
||||
stat.setOrderCount(yearCountMap.getOrDefault(yearStr, 0L));
|
||||
stat.setYearlyCount(yearCountMap.getOrDefault(yearStr, 0L));
|
||||
yearlyStats.add(stat);
|
||||
}
|
||||
|
||||
@ -279,7 +287,7 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
|
||||
result.setDroneModelDistribution(calculateDroneModelDistribution(orders));
|
||||
|
||||
// 5. 景区路线订单分布
|
||||
result.setRouteOrderDistribution(calculateRouteDistribution(orders));
|
||||
result.setRouteDistribution(calculateRouteDistribution(orders));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -397,21 +405,78 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
|
||||
|
||||
/**
|
||||
* 计算景区内各路线的订单分布
|
||||
*
|
||||
* @param orders 订单列表
|
||||
* @return 路线订单分布映射,键为路线名称,值为对应订单数量
|
||||
*/
|
||||
private Map<String, Long> calculateRouteDistribution(List<OrderMain> orders) {
|
||||
Map<String, Long> routeDistribution = new HashMap<>();
|
||||
public List<RouteStat> calculateRouteDistribution(List<OrderMain> orders) {
|
||||
// 统计各路线的订单数量
|
||||
Map<Long, Long> routeCountMap = new HashMap<>();
|
||||
for (OrderMain order : Optional.ofNullable(orders).orElse(Collections.emptyList())) {
|
||||
if (order == null || order.getRouteIds() == null || order.getRouteIds().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 遍历所有订单,统计各路线的订单数量,1个订单会包含多个路线
|
||||
for (OrderMain order : orders) {
|
||||
Long routeId = 0L; // TODO 这里路线可能存在多个
|
||||
String routeName = cpRouteMapper.getNameById(routeId);
|
||||
if (routeName != null) {
|
||||
routeDistribution.put(routeName, routeDistribution.getOrDefault(routeName, 0L) + 1);
|
||||
String[] routeIdArray = order.getRouteIds().split(",");
|
||||
for (String routeIdStr : routeIdArray) {
|
||||
String trimmedRouteId = routeIdStr.trim();
|
||||
if (!trimmedRouteId.isEmpty()) {
|
||||
try {
|
||||
Long routeId = Long.parseLong(trimmedRouteId);
|
||||
routeCountMap.put(routeId, routeCountMap.getOrDefault(routeId, 0L) + 1);
|
||||
} catch (NumberFormatException e) {
|
||||
LOG.error("路线id格式错误: {}", trimmedRouteId, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 转换统计结果为RouteStat列表
|
||||
List<RouteStat> routeDistribution = new ArrayList<>();
|
||||
|
||||
if (!routeCountMap.isEmpty()) {
|
||||
// 提取所有路线ID
|
||||
Set<Long> routeIds = routeCountMap.keySet();
|
||||
|
||||
// 批量查询所有路线信息(仅需查询路线名称和景区ID)
|
||||
List<CpRoute> routes = cpRouteMapper.listRoutesByIds(new ArrayList<>(routeIds));
|
||||
Map<Long, CpRoute> routeMap = routes.stream()
|
||||
.collect(Collectors.toMap(CpRoute::getId, route -> route));
|
||||
|
||||
// 提取所有景区ID
|
||||
Set<Long> scenicIds = routes.stream()
|
||||
.map(CpRoute::getScenicId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 批量查询所有景区名称
|
||||
Map<Long, String> scenicNameMap = emScenicMapper.getScenicNameMap(new ArrayList<>(scenicIds));
|
||||
|
||||
// 组装结果
|
||||
for (Map.Entry<Long, Long> entry : routeCountMap.entrySet()) {
|
||||
Long routeId = entry.getKey();
|
||||
Long count = entry.getValue();
|
||||
|
||||
RouteStat stat = new RouteStat();
|
||||
stat.setRouteId(routeId);
|
||||
stat.setCount(count);
|
||||
|
||||
CpRoute route = routeMap.get(routeId);
|
||||
if (route != null) {
|
||||
stat.setRouteName(route.getName());
|
||||
|
||||
Long scenicId = route.getScenicId();
|
||||
if (scenicId != null) {
|
||||
stat.setScenicName(scenicNameMap.getOrDefault(scenicId, "未知景区"));
|
||||
} else {
|
||||
stat.setScenicName("未知景区");
|
||||
}
|
||||
} else {
|
||||
stat.setRouteName("未知路线");
|
||||
stat.setScenicName("未知景区");
|
||||
}
|
||||
|
||||
routeDistribution.add(stat);
|
||||
}
|
||||
}
|
||||
|
||||
return routeDistribution;
|
||||
}
|
||||
/**
|
||||
@ -465,7 +530,7 @@ public class OrderAnalysisServiceImpl implements OrderAnalysisService {
|
||||
result.setPageInfo(new PageInfo());
|
||||
result.setOrderList(Collections.emptyList());
|
||||
result.setDroneModelDistribution(Collections.emptyMap());
|
||||
result.setRouteOrderDistribution(Collections.emptyMap());
|
||||
result.setRouteDistribution(Collections.emptyList());
|
||||
result.setTimeSeriesData(null);
|
||||
return result;
|
||||
}
|
||||
|
@ -0,0 +1,435 @@
|
||||
package com.aircraft.modules.order.service.impl;
|
||||
|
||||
import com.aircraft.modules.aircraft.domain.AircraftDevice;
|
||||
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;
|
||||
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 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.time.LocalDate;
|
||||
import java.time.YearMonth;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
@Service
|
||||
public class OrderDetailAnalysisServiceImpl implements OrderDetailAnalysisService {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(OrderAnalysisController.class);
|
||||
|
||||
// 日期格式化器(用于按日/月/季度/年分组)
|
||||
private static final DateTimeFormatter DAY_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
private static final DateTimeFormatter MONTH_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM");
|
||||
private static final DateTimeFormatter QUARTER_FORMATTER = DateTimeFormatter.ofPattern("yyyy-Qq"); // 如2025-Q1
|
||||
private static final DateTimeFormatter YEAR_FORMATTER = DateTimeFormatter.ofPattern("yyyy");
|
||||
|
||||
// 订单状态
|
||||
private static final Integer STATUS_NOT_STARTED = 0;//未进行
|
||||
private static final Integer STATUS_PROCESSING = 1;//进行中
|
||||
private static final Integer STATUS_COMPLETED = 2;//已完成
|
||||
private static final Integer STATUS_FAILED = 3;//执行失败
|
||||
|
||||
@Autowired
|
||||
private OrderDetailMapper orderDetailMapper;
|
||||
@Autowired
|
||||
private CpRouteMapper cpRouteMapper;
|
||||
@Autowired
|
||||
private EmScenicMapper emScenicMapper;
|
||||
|
||||
@Override
|
||||
public OrderDetailAnalysisResult<T> analyzeAllOrderDetails(List<OrderDetail> allDetails) {
|
||||
return buildOrderDetailAnalysisResult(allDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderDetailAnalysisResult<List<DailyStat>> analyzeByDayRange(LocalDate start, LocalDate end) {
|
||||
// 1. 查询时间范围内的所有订单
|
||||
List<OrderDetail> orders = queryOrderDetailByDateRange(start, end);
|
||||
if (CollectionUtils.isEmpty(orders)) {
|
||||
return buildEmptyResult();
|
||||
}
|
||||
|
||||
// 2. 按日分组统计每日订单量
|
||||
Map<String, Long> dailyCountMap = orders.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
order -> {
|
||||
LocalDate localDate = order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
return localDate.format(DAY_FORMATTER); // 按日期字符串分组
|
||||
},
|
||||
Collectors.counting() // 统计每组数量
|
||||
));
|
||||
|
||||
System.out.println(dailyCountMap);
|
||||
|
||||
// 3. 填充每日统计数据(确保日期连续性,即使某天无订单也显示0)
|
||||
List<DailyStat> dailyStats = new ArrayList<>();
|
||||
LocalDate current = start;
|
||||
while (!current.isAfter(end)) {
|
||||
String dateStr = current.format(DAY_FORMATTER);
|
||||
DailyStat stat = new DailyStat();
|
||||
stat.setDate(dateStr);
|
||||
stat.setDailyCount(dailyCountMap.getOrDefault(dateStr, 0L));
|
||||
dailyStats.add(stat);
|
||||
current = current.plusDays(1); // 移至下一天
|
||||
}
|
||||
|
||||
// 4. 构建并返回完整结果
|
||||
return buildAnalysisResult(orders, dailyStats);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderDetailAnalysisResult<List<MonthlyStat>> analyzeByMonthRange(LocalDate start, LocalDate end) {
|
||||
// 1. 查询时间范围内的所有订单
|
||||
List<OrderDetail> orders = queryOrderDetailByDateRange(start, end);
|
||||
if (CollectionUtils.isEmpty(orders)) {
|
||||
return buildEmptyResult();
|
||||
}
|
||||
|
||||
// 2. 按月分组统计每月订单量
|
||||
Map<String, Long> monthlyCountMap = orders.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
order -> {
|
||||
LocalDate localDate = order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
return localDate.format(MONTH_FORMATTER);
|
||||
},
|
||||
Collectors.counting()
|
||||
));
|
||||
|
||||
// 3. 填充每月统计数据(确保月份连续性)
|
||||
List<MonthlyStat> monthlyStats = new ArrayList<>();
|
||||
LocalDate current = start.withDayOfMonth(1); // 从当月第一天开始
|
||||
LocalDate endMonth = end.withDayOfMonth(1); // 结束月份第一天
|
||||
|
||||
while (!current.isAfter(endMonth)) {
|
||||
String monthStr = current.format(MONTH_FORMATTER);
|
||||
MonthlyStat stat = new MonthlyStat();
|
||||
stat.setMonth(monthStr);
|
||||
stat.setMonthlyCount(monthlyCountMap.getOrDefault(monthStr, 0L));
|
||||
monthlyStats.add(stat);
|
||||
current = current.plusMonths(1); // 移至下一月
|
||||
}
|
||||
|
||||
// 4. 构建并返回完整结果
|
||||
return buildAnalysisResult(orders, monthlyStats);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderDetailAnalysisResult<List<QuarterlyStat>> analyzeByQuarterRange(LocalDate start, LocalDate end) {
|
||||
// 1. 查询时间范围内的所有订单
|
||||
List<OrderDetail> orders = queryOrderDetailByDateRange(start, end);
|
||||
if (CollectionUtils.isEmpty(orders)) {
|
||||
return buildEmptyResult();
|
||||
}
|
||||
|
||||
// 2. 按季度分组统计每季度订单量
|
||||
Map<String, Long> quarterCountMap = orders.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
order -> {
|
||||
// 将 java.util.Date 转换为 java.time.YearMonth
|
||||
YearMonth yearMonth = YearMonth.from(order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()));
|
||||
int quarter = (yearMonth.getMonthValue() - 1) / 3 + 1;
|
||||
return yearMonth.format(YEAR_FORMATTER) + "-Q" + quarter;
|
||||
},
|
||||
Collectors.counting()
|
||||
));
|
||||
|
||||
// 3. 填充每季度统计数据(确保季度连续性)
|
||||
List<QuarterlyStat> quarterlyStats = new ArrayList<>();
|
||||
LocalDate currentQuarterStart = start;
|
||||
// 调整至当前季度第一天(如2025-05-10 → 2025-04-01)
|
||||
currentQuarterStart = currentQuarterStart.minusMonths((currentQuarterStart.getMonthValue() - 1) % 3);
|
||||
currentQuarterStart = currentQuarterStart.withDayOfMonth(1);
|
||||
|
||||
while (!currentQuarterStart.isAfter(end)) {
|
||||
// 计算当前季度标识(如2025-Q2)
|
||||
int quarter = (currentQuarterStart.getMonthValue() - 1) / 3 + 1;
|
||||
String quarterStr = currentQuarterStart.format(YEAR_FORMATTER) + "-Q" + quarter;
|
||||
|
||||
QuarterlyStat stat = new QuarterlyStat();
|
||||
stat.setQuarter(quarterStr);
|
||||
stat.setQuarterlyCount(quarterCountMap.getOrDefault(quarterStr, 0L));
|
||||
quarterlyStats.add(stat);
|
||||
|
||||
// 移至下一季度第一天
|
||||
currentQuarterStart = currentQuarterStart.plusMonths(3);
|
||||
}
|
||||
|
||||
// 4. 构建并返回完整结果
|
||||
return buildAnalysisResult(orders, quarterlyStats);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderDetailAnalysisResult<List<YearlyStat>> analyzeByYearRange(LocalDate start, LocalDate end) {
|
||||
// 1. 查询时间范围内的所有订单
|
||||
List<OrderDetail> orders = queryOrderDetailByDateRange(start, end);
|
||||
if (CollectionUtils.isEmpty(orders)) {
|
||||
return buildEmptyResult();
|
||||
}
|
||||
|
||||
// 2. 按年分组统计每年订单量
|
||||
Map<String, Long> yearCountMap = orders.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
order -> {
|
||||
LocalDate localDate = order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
return localDate.format(YEAR_FORMATTER);
|
||||
},
|
||||
Collectors.counting()
|
||||
));
|
||||
// 3. 填充每年统计数据(确保年份连续性)
|
||||
List<YearlyStat> yearlyStats = new ArrayList<>();
|
||||
int startYear = start.getYear();
|
||||
int endYear = end.getYear();
|
||||
|
||||
for (int year = startYear; year <= endYear; year++) {
|
||||
String yearStr = String.valueOf(year);
|
||||
YearlyStat stat = new YearlyStat();
|
||||
stat.setYear(yearStr);
|
||||
stat.setYearlyCount(yearCountMap.getOrDefault(yearStr, 0L));
|
||||
yearlyStats.add(stat);
|
||||
}
|
||||
|
||||
// 4. 构建并返回完整结果
|
||||
return buildAnalysisResult(orders, yearlyStats);
|
||||
}
|
||||
|
||||
// ====================== 通用工具方法 ======================
|
||||
|
||||
/**
|
||||
* 根据日期范围查询订单
|
||||
*/
|
||||
private List<OrderDetail> queryOrderDetailByDateRange(LocalDate start, LocalDate end) {
|
||||
// MyBatis Plus 条件构造器:查询 create_time 在 [start, end] 范围内的订单
|
||||
LambdaQueryWrapper<OrderDetail> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.ge(OrderDetail::getCreateTime, start.atStartOfDay()) // 开始时间:当天00:00:00
|
||||
.le(OrderDetail::getCreateTime, end.atTime(23, 59, 59)); // 结束时间:当天23:59:59
|
||||
return orderDetailMapper.selectList(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建完整的订单分析结果
|
||||
*/
|
||||
private <T> OrderDetailAnalysisResult<T> buildAnalysisResult(List<OrderDetail> orderDetails, T timeSeriesData) {
|
||||
OrderDetailAnalysisResult<T> result = buildOrderDetailAnalysisResult(orderDetails);
|
||||
// 时间序列数据(日/月/季/年统计)
|
||||
result.setTimeSeriesData(timeSeriesData);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理任务分析结果
|
||||
*/
|
||||
private <T> OrderDetailAnalysisResult<T> buildOrderDetailAnalysisResult(List<OrderDetail> orderDetails) {
|
||||
OrderDetailAnalysisResult<T> result = new OrderDetailAnalysisResult<>();
|
||||
|
||||
// 1. 基础统计指标
|
||||
long totalTaskCount = orderDetails.size();
|
||||
result.setTotalTaskCount(totalTaskCount);
|
||||
|
||||
// 2. 按状态统计任务数量
|
||||
long notStartedCount = countTasksByStatus(orderDetails, STATUS_NOT_STARTED);
|
||||
long processingCount = countTasksByStatus(orderDetails, STATUS_PROCESSING);
|
||||
long completedCount = countTasksByStatus(orderDetails, STATUS_COMPLETED);
|
||||
long failedCount = countTasksByStatus(orderDetails, STATUS_FAILED);
|
||||
|
||||
// 3. 设置状态统计结果
|
||||
result.setNotStartedTaskCount(notStartedCount);
|
||||
result.setProcessingTaskCount(processingCount);
|
||||
result.setCompletedTaskCount(completedCount);
|
||||
result.setFailedTaskCount(failedCount);
|
||||
|
||||
// 4. 计算状态比率(保留两位小数)
|
||||
BigDecimal total = BigDecimal.valueOf(totalTaskCount);
|
||||
result.setNotStartedRate(calculateRate(notStartedCount, total));
|
||||
result.setProcessingRate(calculateRate(processingCount, total));
|
||||
result.setCompletionRate(calculateRate(completedCount, total));
|
||||
result.setFailedRate(calculateRate(failedCount, total));
|
||||
|
||||
// 5. 景区路线订单分布
|
||||
result.setRouteDistribution(calculateRouteDistribution(orderDetails));
|
||||
|
||||
// 6. 分页信息和订单列表(默认取第一页,每页10条)
|
||||
PageInfo pageInfo = buildTaskPageInfo(orderDetails, 1, 10);
|
||||
result.setPageInfo(pageInfo);
|
||||
result.setOrderDetailList(getPagedTasks(orderDetails, pageInfo));
|
||||
|
||||
// 7. 时间序列数据(在调用此方法的上层设置)
|
||||
result.setTimeSeriesData(null); // 由调用者设置具体时间序列数据
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按状态统计任务数量
|
||||
*/
|
||||
private long countTasksByStatus(List<OrderDetail> tasks, Integer status) {
|
||||
return tasks.stream()
|
||||
.filter(task -> status.equals(task.getOrderItemStatus()))
|
||||
.count();
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算比率(保留两位小数)
|
||||
*/
|
||||
private BigDecimal calculateRate(long count, BigDecimal total) {
|
||||
if (total.compareTo(BigDecimal.ZERO) == 0) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return BigDecimal.valueOf(count)
|
||||
.divide(total, 4, BigDecimal.ROUND_HALF_UP) // 中间计算保留4位小数
|
||||
.multiply(BigDecimal.valueOf(100)) // 转换为百分比
|
||||
.setScale(2, BigDecimal.ROUND_HALF_UP); // 最终结果保留两位小数
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建任务分页信息
|
||||
*/
|
||||
private PageInfo buildTaskPageInfo(List<OrderDetail> tasks, int pageNum, int pageSize) {
|
||||
PageInfo pageInfo = new PageInfo();
|
||||
pageInfo.setPageNum(pageNum);
|
||||
pageInfo.setPageSize(pageSize);
|
||||
pageInfo.setTotal((long) tasks.size());
|
||||
return pageInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分页后的任务列表
|
||||
*/
|
||||
private List<OrderDetail> getPagedTasks(List<OrderDetail> tasks, PageInfo pageInfo) {
|
||||
int start = (pageInfo.getPageNum() - 1) * pageInfo.getPageSize();
|
||||
int end = Math.min(start + pageInfo.getPageSize(), tasks.size());
|
||||
return tasks.subList(start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将列表按指定大小分割为多个子列表
|
||||
*
|
||||
* @param list 原始列表
|
||||
* @param batchSize 每个子列表的最大大小
|
||||
* @return 子列表集合
|
||||
*/
|
||||
private <T> List<List<T>> partitionList(List<T> list, int batchSize) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return IntStream.range(0, (list.size() + batchSize - 1) / batchSize)
|
||||
.mapToObj(i -> list.subList(i * batchSize, Math.min((i + 1) * batchSize, list.size())))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算景区内各路线的任务分布
|
||||
*/
|
||||
public List<RouteStat> calculateRouteDistribution(List<OrderDetail> orderDetails) {
|
||||
// 1. 校验输入
|
||||
if (CollectionUtils.isEmpty(orderDetails)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 2. 统计各路线的任务数量(基于子单的routeId字段)
|
||||
Map<Long, Long> routeCountMap = orderDetails.stream()
|
||||
.filter(detail -> detail.getRouteId() != null) // 过滤掉无路线ID的任务
|
||||
.collect(Collectors.groupingBy(
|
||||
OrderDetail::getRouteId, // 按路线ID分组
|
||||
Collectors.counting() // 统计每组数量
|
||||
));
|
||||
|
||||
// 3. 批量查询路线信息(名称、所属景区)
|
||||
List<RouteStat> result = new ArrayList<>();
|
||||
if (!routeCountMap.isEmpty()) {
|
||||
// 提取所有路线ID
|
||||
ArrayList<Long> routeIds = new ArrayList<>(routeCountMap.keySet());
|
||||
|
||||
// 批量查询路线信息(名称、景区ID)
|
||||
List<CpRoute> routes = cpRouteMapper.listRoutesByIds(routeIds);
|
||||
Map<Long, CpRoute> routeInfoMap = routes.stream()
|
||||
.collect(Collectors.toMap(CpRoute::getId, route -> route));
|
||||
|
||||
// 提取所有景区ID(用于批量查询景区名称)
|
||||
Set<Long> scenicIds = routes.stream()
|
||||
.map(CpRoute::getScenicId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 批量查询景区名称
|
||||
Map<Long, String> scenicNameMap = emScenicMapper.getScenicNameMap(new ArrayList<>(scenicIds));
|
||||
|
||||
// 4. 组装结果
|
||||
for (Map.Entry<Long, Long> entry : routeCountMap.entrySet()) {
|
||||
Long routeId = entry.getKey();
|
||||
Long taskCount = entry.getValue();
|
||||
|
||||
RouteStat stat = new RouteStat();
|
||||
stat.setRouteId(routeId);
|
||||
stat.setCount(taskCount);
|
||||
|
||||
// 设置路线名称和景区名称
|
||||
CpRoute route = routeInfoMap.get(routeId);
|
||||
if (route != null) {
|
||||
stat.setRouteName(route.getName());
|
||||
Long scenicId = route.getScenicId();
|
||||
if (scenicId != null) {
|
||||
stat.setScenicName(scenicNameMap.getOrDefault(scenicId, "未知景区"));
|
||||
} else {
|
||||
stat.setScenicName("未知景区");
|
||||
}
|
||||
} else {
|
||||
// 路线不存在的情况
|
||||
stat.setRouteName("未知路线");
|
||||
stat.setScenicName("未知景区");
|
||||
}
|
||||
|
||||
result.add(stat);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建空结果(无任务时)
|
||||
*/
|
||||
private <T> OrderDetailAnalysisResult<T> buildEmptyResult() {
|
||||
OrderDetailAnalysisResult<T> result = new OrderDetailAnalysisResult<>();
|
||||
|
||||
// 任务统计指标
|
||||
result.setTotalTaskCount(0L);
|
||||
|
||||
// 分项状态计数
|
||||
result.setNotStartedTaskCount(0L);
|
||||
result.setProcessingTaskCount(0L);
|
||||
result.setCompletedTaskCount(0L);
|
||||
result.setFailedTaskCount(0L);
|
||||
|
||||
// 状态比率
|
||||
result.setNotStartedRate(BigDecimal.ZERO);
|
||||
result.setProcessingRate(BigDecimal.ZERO);
|
||||
result.setCompletionRate(BigDecimal.ZERO);
|
||||
result.setFailedRate(BigDecimal.ZERO);
|
||||
|
||||
// 路线分布、分页和时间序列数据
|
||||
result.setRouteDistribution(Collections.emptyList());
|
||||
result.setPageInfo(new PageInfo());
|
||||
result.setOrderDetailList(Collections.emptyList());
|
||||
result.setTimeSeriesData(null);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -5,6 +5,7 @@ import com.aircraft.modules.route.domain.dto.CpRouteVo;
|
||||
import com.aircraft.modules.route.mapper.CpRouteMapper;
|
||||
import com.aircraft.modules.system.mapper.UserMapper;
|
||||
import com.aircraft.modules.route.service.CpRouteService;
|
||||
import com.aircraft.utils.StringUtils;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
@ -92,7 +93,7 @@ public class CpRouteController {
|
||||
@ApiOperation(value = "查询单个路线")
|
||||
@RequestMapping(value = "{id}", method = {RequestMethod.GET})
|
||||
@ApiImplicitParam(name = "id", value = "路线ID", required = true, paramType = "path") // 调整参数描述
|
||||
public ResponseEntity<CpRoute> one(@PathVariable final Integer id) {
|
||||
public ResponseEntity<CpRoute> one(@PathVariable final Long id) {
|
||||
try {
|
||||
CpRoute entity = cpRouteMapper.getRouteById(id);
|
||||
if (entity == null || entity.getDelFlag() == 1) {
|
||||
@ -239,4 +240,40 @@ public class CpRouteController {
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation(value = "根据景区名称模糊查询路线")
|
||||
@RequestMapping(value = "searchRoutesByName", method = RequestMethod.GET)
|
||||
public ResponseEntity<List<CpRoute>> searchRoutesByName(
|
||||
@ApiParam(value = "景区名称(支持模糊匹配)", required = true)
|
||||
@RequestParam("areaName") String areaName) {
|
||||
|
||||
try {
|
||||
// 1. 参数校验
|
||||
if (StringUtils.isBlank(areaName)) {
|
||||
LOG.warn("景区名称模糊查询失败:景区名称为空");
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
|
||||
// 2. 构建查询条件(仅针对景区名称进行模糊匹配)
|
||||
QueryWrapper<CpRoute> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.like("area_name", areaName)
|
||||
.eq("del_flag", 0);
|
||||
|
||||
// 3. 查询匹配的路线
|
||||
List<CpRoute> routes = entityService.list(queryWrapper);
|
||||
|
||||
// 4. 返回结果
|
||||
if (CollectionUtils.isEmpty(routes)) {
|
||||
LOG.info("未找到景区名称包含'{}'的路线数据", areaName);
|
||||
return ResponseEntity.ok(Collections.emptyList());
|
||||
}
|
||||
|
||||
LOG.info("景区名称模糊查询成功,关键词='{}',共找到{}条路线", areaName, routes.size());
|
||||
return ResponseEntity.ok(routes);
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.error("景区名称模糊查询失败,关键词={}", areaName, e);
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,9 @@ import com.aircraft.modules.route.domain.CpRoute;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 路线表 Mapper 接口
|
||||
@ -17,7 +20,9 @@ public interface CpRouteMapper extends BaseMapper<CpRoute> {
|
||||
|
||||
void updateDelFlagById(Long id, Integer delFlag);
|
||||
|
||||
CpRoute getRouteById(Integer id);
|
||||
CpRoute getRouteById(Long id);
|
||||
|
||||
String getNameById(Long routeId);
|
||||
|
||||
List<CpRoute> listRoutesByIds(ArrayList<Long> longs);
|
||||
}
|
||||
|
@ -6,7 +6,9 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import io.lettuce.core.dynamic.annotation.Param;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -32,4 +34,6 @@ public interface EmScenicMapper extends BaseMapper<EmScenic> {
|
||||
* @return
|
||||
*/
|
||||
List<AreaNumStatisVo> countByAreaId();
|
||||
|
||||
Map<Long, String> getScenicNameMap(ArrayList<Long> longs);
|
||||
}
|
||||
|
@ -26,4 +26,14 @@
|
||||
where valid = 't'
|
||||
group by area_id
|
||||
</select>
|
||||
<select id="getScenicNameMap" resultType="java.util.HashMap">
|
||||
SELECT
|
||||
id AS "key",
|
||||
name AS "value"
|
||||
FROM em_scenic
|
||||
WHERE id IN
|
||||
<foreach collection="scenicIds" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
</mapper>
|
||||
|
@ -6,6 +6,8 @@
|
||||
<id column="id" property="id" jdbcType="BIGINT"/>
|
||||
<result column="order_id" property="orderId" jdbcType="BIGINT"/>
|
||||
<result column="device_id" property="deviceId" jdbcType="BIGINT"/>
|
||||
<result column="routeId" property="routeId" jdbcType="BIGINT"/>
|
||||
<result column="cargo_weight" property="cargoWeight" jdbcType="DECIMAL"/>
|
||||
<result column="person_count" property="personCount" jdbcType="VARCHAR"/>
|
||||
<result column="operator_id" property="operatorId" jdbcType="BIGINT"/>
|
||||
<result column="order_item_status" property="orderItemStatus" jdbcType="INTEGER"/>
|
||||
@ -16,12 +18,13 @@
|
||||
<result column="del_flag" property="delFlag" jdbcType="INTEGER"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 通过订单ID列表查询订单详情列表 -->
|
||||
<select id="getOrderDetailsByOrderIds" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
<!-- 基础查询列 -->
|
||||
<sql id="Base_Column_List">
|
||||
id,
|
||||
order_id,
|
||||
device_id,
|
||||
routeId,
|
||||
cargo_weight,
|
||||
person_count,
|
||||
operator_id,
|
||||
order_item_status,
|
||||
@ -30,30 +33,28 @@
|
||||
update_by,
|
||||
update_time,
|
||||
del_flag
|
||||
</sql>
|
||||
|
||||
<!-- 通过订单ID列表查询订单详情列表 -->
|
||||
<select id="getOrderDetailsByOrderIds" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
<include refid="Base_Column_List"/>
|
||||
FROM fms_od_order_detail
|
||||
WHERE order_id IN
|
||||
<foreach collection="orderIds" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
AND del_flag = 0
|
||||
ORDER BY order_id ASC, id ASC
|
||||
</select>
|
||||
|
||||
<!-- 通过订单id获取单个订单详情-->
|
||||
<select id="getOrderDetailsByOrderId" resultMap="BaseResultMap">
|
||||
SELECT id,
|
||||
order_id,
|
||||
device_id,
|
||||
person_count,
|
||||
operator_id,
|
||||
order_item_status,
|
||||
create_by,
|
||||
create_time,
|
||||
update_by,
|
||||
update_time,
|
||||
del_flag
|
||||
SELECT
|
||||
<include refid="Base_Column_List"/>
|
||||
FROM fms_od_order_detail
|
||||
WHERE order_id = #{orderId}
|
||||
ORDER BY fms_od_order_detail.create_time ASC
|
||||
AND del_flag = 0
|
||||
ORDER BY create_time ASC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
</mapper>
|
@ -19,4 +19,15 @@
|
||||
FROM cp_route
|
||||
WHERE id = #{routeId}
|
||||
</select>
|
||||
<select id="listRoutesByIds" resultType="com.aircraft.modules.route.domain.CpRoute">
|
||||
SELECT
|
||||
id,
|
||||
name,
|
||||
scenic_id
|
||||
FROM cp_route
|
||||
WHERE id IN
|
||||
<foreach collection="routeIds" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
</mapper>
|
||||
|
Loading…
Reference in New Issue
Block a user