From 891442cd642c035ea7fbf65c3136509f97e24f0b Mon Sep 17 00:00:00 2001
From: 无关风月 <443237572@qq.com>
Date: 星期四, 29 一月 2026 16:01:11 +0800
Subject: [PATCH] bug修改
---
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ProjectController.java | 18 +-
ruoyi-system/src/main/java/com/ruoyi/system/query/ErrorListQuery.java | 5
ruoyi-system/src/main/java/com/ruoyi/system/service/DeviceUsageService.java | 3
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/DeviceUsageServiceImpl.java | 179 +++++++++++++++++++++++++++++++----
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/EntrustProjectController.java | 18 +++
ruoyi-system/src/main/java/com/ruoyi/system/query/EntrustListQuery.java | 6 +
ruoyi-system/src/main/java/com/ruoyi/system/query/EntrustDeviceListQuery.java | 8 +
ruoyi-system/src/main/resources/mapper/system/DeviceUsageMapper.xml | 37 +++++--
8 files changed, 226 insertions(+), 48 deletions(-)
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/EntrustProjectController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/EntrustProjectController.java
index 0206f69..6c39039 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/EntrustProjectController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/EntrustProjectController.java
@@ -17,6 +17,7 @@
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
+import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@@ -55,6 +56,21 @@
@Autowired
private UserFileService userFileService;
+ @ApiOperation(value = "项目不分页列表", response = Project.class)
+ @GetMapping("/projectListAll")
+ public R<List<Project>> projectListAll(Integer clientId,Integer category) {
+ LambdaQueryWrapper<Project> projectLambdaQueryWrapper = new LambdaQueryWrapper<>();
+ projectLambdaQueryWrapper.eq(Project::getClientId, clientId)
+ .eq(Project::getDeleted, false);
+ if (category==1){
+ projectLambdaQueryWrapper.eq(Project::getStatus, 1);
+ }
+ if (category==2){
+ projectLambdaQueryWrapper.eq(Project::getType,2);
+ }
+ List<Project> list = projectService.list(projectLambdaQueryWrapper);
+ return R.ok(list);
+ }
@ApiOperation(value = "项目列表", response = EntrustProjectVo.class)
@PostMapping("/projectList")
public R<Page<EntrustProjectVo>> projectList(@RequestBody EntrustListQuery query) {
@@ -105,7 +121,7 @@
@ApiOperation(value = "获取重大隐患列表", response = DeviceListVo.class)
@PostMapping("/errorList")
- public R<Page<ErrorListVo>> errorList(@RequestBody @Valid ErrorListQuery query) {
+ public R<Page<ErrorListVo>> errorList(@RequestBody @Valid ErrorListQuery query) throws ParseException {
Page<ErrorListVo> page = new Page<>(query.getPageNum(), query.getPageSize());
List<ErrorListVo> list = deviceUsageService.errorList(page, query);
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ProjectController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ProjectController.java
index 9174fd2..04299d0 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ProjectController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ProjectController.java
@@ -498,14 +498,14 @@
private String UPLOAD_DIR;
- @PostConstruct
- void init(){
- fileLocation = Path.of(UPLOAD_DIR).toAbsolutePath().normalize();
- try {
- Files.createDirectories(this.fileLocation);
- } catch (Exception ex) {
- throw new RuntimeException("Could not create the directory where the uploaded files will be stored.", ex);
- }
- }
+// @PostConstruct
+// void init(){
+// fileLocation = Path.of(UPLOAD_DIR).toAbsolutePath().normalize();
+// try {
+// Files.createDirectories(this.fileLocation);
+// } catch (Exception ex) {
+// throw new RuntimeException("Could not create the directory where the uploaded files will be stored.", ex);
+// }
+// }
}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/EntrustDeviceListQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/EntrustDeviceListQuery.java
index d392dee..af2696c 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/query/EntrustDeviceListQuery.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/EntrustDeviceListQuery.java
@@ -6,6 +6,7 @@
import lombok.Data;
import javax.validation.constraints.NotNull;
+import java.util.List;
@Data
@ApiModel("委托方端设备信息列表查询query")
@@ -13,11 +14,16 @@
@ApiModelProperty("项目id")
private Integer projectId;
+ @ApiModelProperty("项目ids")
+ private List<Integer> projectIds;
+ @ApiModelProperty("clientId")
+ private Integer clientId;
@ApiModelProperty("整改情况 true已整改 false未整改")
private Boolean reformed;
@ApiModelProperty("设备类型")
private Integer type;
-
+ @ApiModelProperty("类型 1在建 2固定资产")
+ private Integer category;
@ApiModelProperty("开始时间")
private String startTime;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/EntrustListQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/EntrustListQuery.java
index 7110070..54f3303 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/query/EntrustListQuery.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/EntrustListQuery.java
@@ -6,6 +6,7 @@
import lombok.Data;
import javax.validation.constraints.NotNull;
+import java.util.List;
@Data
@ApiModel("委托方端项目列表查询query")
@@ -13,9 +14,12 @@
@ApiModelProperty("项目id")
private Integer projectId;
-
+ @ApiModelProperty("项目ids")
+ private List< Integer> projectIds;
@ApiModelProperty("委托方id")
private Integer clientId;
+ @ApiModelProperty(value = "类型 1在建 2固定资产",required = true)
+ private Integer category;
@ApiModelProperty("项目类型:1-房建 2-市政 3-建筑工程等")
private Integer type;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/ErrorListQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/ErrorListQuery.java
index d4c0bf3..57e8ab5 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/query/ErrorListQuery.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/ErrorListQuery.java
@@ -11,8 +11,7 @@
@Data
@ApiModel("委托方端隐患列表查询query")
public class ErrorListQuery extends BasePage {
- @ApiModelProperty("clientId")
- private Integer clientId;
+
@ApiModelProperty("项目id")
private Integer projectId;
@ApiModelProperty("项目ids")
@@ -23,6 +22,8 @@
private Boolean reformed;
@ApiModelProperty("隐患类型 1安全 2设备")
private Integer type;
+ @ApiModelProperty("clientId")
+ private Integer clientId;
@ApiModelProperty("开始时间")
private String startTime;
@ApiModelProperty("结束时间")
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/DeviceUsageService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/DeviceUsageService.java
index d6f836d..a9fc33e 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/DeviceUsageService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/DeviceUsageService.java
@@ -11,6 +11,7 @@
import com.ruoyi.system.vo.DeviceListVo;
import javax.validation.Valid;
+import java.text.ParseException;
import java.util.List;
/**
@@ -33,7 +34,7 @@
List<EntrustDeviceListVo> deviceList(Page<EntrustDeviceListVo> page, EntrustDeviceListQuery query);
- List<ErrorListVo> errorList(Page<ErrorListVo> page, ErrorListQuery query);
+ List<ErrorListVo> errorList(Page<ErrorListVo> page, ErrorListQuery query) throws ParseException;
List<ErrorListVo> deviceErrorList(Page<ErrorListVo> page, ErrorListQuery query);
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/DeviceUsageServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/DeviceUsageServiceImpl.java
index 6b0fcf7..dfb028b 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/DeviceUsageServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/DeviceUsageServiceImpl.java
@@ -21,13 +21,12 @@
import org.springframework.util.StringUtils;
import java.math.BigDecimal;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.stream.Collectors;
/**
@@ -83,21 +82,86 @@
public List<EntrustProjectVo> projectList( Page<EntrustProjectVo> page,EntrustListQuery query) {
Integer pageNum = query.getPageNum();
Integer pageSize = query.getPageSize();
- LocalDateTime startTime = LocalDateTime.of(LocalDate.now().withDayOfMonth(1), LocalDateTime.MIN.toLocalTime());
- Map<Integer, List<EvalResult>> resultMap = evalResultMapper.selectList(new LambdaQueryWrapper<EvalResult>()
- .ge(EvalResult::getCreateTime, startTime)
- .le(EvalResult::getCreateTime, LocalDateTime.now())
- ).stream().collect(Collectors.groupingBy(EvalResult::getProjectId));
+ String startTime = query.getStartTime();
+ String endTime = query.getEndTime();
+
+ // 查询在建工程项目(usage_type 表示项目用途类型,假设 0 表示在建工程)
+ LambdaQueryWrapper<Project> projectWrapper = new LambdaQueryWrapper<>();
+ if (query.getClientId() != null) {
+ projectWrapper.eq(Project::getClientId, query.getClientId());
+ }
+ if (StringUtils.hasLength(query.getName())){
+ projectWrapper.like(Project::getName, query.getName());
+ }
+ switch (query.getCategory()){
+ case 1:
+ // 查询在建资产项目
+ projectWrapper.eq(Project::getDeleted, false)
+ .ne(Project::getType, 2) // 在建工程
+ .and(wrapper -> wrapper
+ .eq(Project::getStatus, 1) // 在建项目
+ .or(w -> w
+ .eq(Project::getStatus, 2) // 已完成项目
+ .ge(Project::getSuccessTime, startTime) // 完成时间 >= 开始日期// 完成时间 <= 结束日期
+ )
+ );
+ break;
+ case 2:
+ // 查询固定资产项目
+ projectWrapper.eq(Project::getDeleted, false)
+ .eq(Project::getType, 2) // 固定资产
+ .and(wrapper -> wrapper
+ .eq(Project::getStatus, 1) // 在建项目
+ .or(w -> w
+ .eq(Project::getStatus, 2) // 已完成项目
+ .ge(Project::getSuccessTime, startTime) // 完成时间 >= 开始日期
+ )
+ );
+ break;
+ }
+
+ List<Project> projects = projectMapper.selectList(projectWrapper);
+ List<Integer> projectIds = projects.stream().map(Project::getId).collect(Collectors.toList());
+ if (projectIds.isEmpty()){
+ projectIds.add(-1);
+ }
+ query.setProjectIds(projectIds);
+ // 查询检查任务
+ LambdaQueryWrapper<Task> taskWrapper = new LambdaQueryWrapper<>();
+ taskWrapper.in(Task::getProjectId, projectIds)
+ .eq(Task::getDeleted, false);
+ List<Task> taskList = taskMapper.selectList(taskWrapper);
+ List<Integer> checkTaskIds = taskList.stream().map(Task::getId).collect(Collectors.toList());
+ if (checkTaskIds.isEmpty()){
+ checkTaskIds.add(-1);
+ }
+ // 查询重大隐患记录(level 表示隐患等级,0 表示重大隐患)
+ LambdaQueryWrapper<Record> recordWrapper = new LambdaQueryWrapper<>();
+ recordWrapper.eq(Record::getDeleted, false)
+ .in(Record::getCheckTaskId, checkTaskIds)
+ .eq(Record::getLevel, 0); // 重大隐患等级
+ List<Integer> recordIds = recordMapper.selectList(recordWrapper).stream().map(Record::getId).toList();
+ if (recordIds.isEmpty()){
+ recordIds.add(-1);
+ }
+
Map<Integer, Integer> projectMap = projectMapper.selectList(new LambdaQueryWrapper<Project>()
.eq(Project::getDeleted, false)).stream().collect(Collectors.toMap(Project::getId, Project::getClientId));
Map<Integer, String> clientParamMap = clientParamMapper.selectList(new LambdaQueryWrapper<ClientParam>())
.stream().collect(Collectors.toMap(ClientParam::getClientId, ClientParam::getUnderConstructionProject));
- Map<Integer, List<Task>> taskMap = taskMapper.selectList(new LambdaQueryWrapper<Task>())
+ Map<Integer, List<Task>> taskMap = taskMapper.selectList(new LambdaQueryWrapper<Task>()
+ .ge(Task::getCreateTime, startTime)
+ .le(Task::getCreateTime, LocalDateTime.now())
+ .in(Task::getId, checkTaskIds)
+ .isNotNull(Task::getProjectId))
.stream().collect(Collectors.groupingBy(Task::getProjectId));
+ Map<Integer, List<EvalResult>> resultMap = evalResultMapper.selectList(new LambdaQueryWrapper<EvalResult>()
+ .in(EvalResult::getCheckTaskId, checkTaskIds)
+ ).stream().collect(Collectors.groupingBy(EvalResult::getProjectId));
List<Record> records = recordMapper.selectList(new LambdaQueryWrapper<Record>()
+ .in(Record::getId, recordIds)
.eq(Record::getDeleted, false));
- // 获取本月第一天凌晨
List<EntrustProjectVo> deviceList = this.baseMapper.projectList(page,query);
for (EntrustProjectVo deviceListVo : deviceList) {
List<EvalResult> evalResults = resultMap.get(deviceListVo.getId());
@@ -142,7 +206,7 @@
List<Task> tasks = taskMap.get(deviceListVo.getId());
if (tasks!=null&&!tasks.isEmpty()){
List<Integer> taskIds = tasks.stream().map(Task::getId).toList();
- List<Record> recordList = records.stream().filter(e -> taskIds.contains(e.getCheckTaskId())).collect(Collectors.toList());
+ List<Record> recordList = records.stream().filter(e -> taskIds.contains(e.getCheckTaskId())).toList();
Record record = recordList.stream().max(Comparator.comparing(Record::getCreateTime)).orElse(null);
if (record!=null){
deviceListVo.setCheckTime(record.getCreateTime());
@@ -237,23 +301,96 @@
@Override
public List<EntrustDeviceListVo> deviceList(Page<EntrustDeviceListVo> page, EntrustDeviceListQuery query) {
+ String startTime = query.getStartTime().replace("年","-").replace("月","-").replace("日","-");
+ String endTime = query.getEndTime();
+
+ // 查询在建工程项目(usage_type 表示项目用途类型,假设 0 表示在建工程)
+ LambdaQueryWrapper<Project> projectWrapper = new LambdaQueryWrapper<>();
+ if (query.getClientId() != null) {
+ projectWrapper.eq(Project::getClientId, query.getClientId());
+ }
+ switch (query.getCategory()){
+ case 1:
+ // 查询在建资产项目
+ projectWrapper.eq(Project::getDeleted, false)
+ .ne(Project::getType, 2) // 在建工程
+ .and(wrapper -> wrapper
+ .eq(Project::getStatus, 1) // 在建项目
+ .or(w -> w
+ .eq(Project::getStatus, 2) // 已完成项目
+ .ge(Project::getSuccessTime, startTime) // 完成时间 >= 开始日期// 完成时间 <= 结束日期
+ )
+ );
+ break;
+ case 2:
+ // 查询固定资产项目
+ projectWrapper.eq(Project::getDeleted, false)
+ .eq(Project::getType, 2) // 固定资产
+ .and(wrapper -> wrapper
+ .eq(Project::getStatus, 1) // 在建项目
+ .or(w -> w
+ .eq(Project::getStatus, 2) // 已完成项目
+ .ge(Project::getSuccessTime, startTime) // 完成时间 >= 开始日期
+ )
+ );
+ break;
+ }
+ List<Integer> projectIds = projectMapper.selectList(projectWrapper).stream().map(Project::getId).collect(Collectors.toList());
+ query.setProjectIds(projectIds);
List<EntrustDeviceListVo> deviceList = this.baseMapper.deviceList(page, query);
+ List<Integer> deviceIds = deviceList.stream().map(EntrustDeviceListVo::getId).collect(Collectors.toList());
+ if (deviceIds.isEmpty()){
+ deviceIds.add(-1);
+ }
+ LambdaQueryWrapper<Record> recordWrapper = new LambdaQueryWrapper<>();
+ recordWrapper.eq(Record::getRecordType, "error")
+ .isNotNull(Record::getDeviceId)
+ .in(Record::getDeviceId, deviceIds)
+ .eq(Record::getDeleted, false);
+ List<Record> records = recordMapper.selectList(recordWrapper);
+ List<Integer> deviceIdsRecord = records.stream().map(Record::getDeviceId).distinct().collect(Collectors.toList());
for (EntrustDeviceListVo deviceListVo : deviceList) {
- LocalDateTime checkTime = deviceListVo.getCheckTime();
- // 判断checkTime是否是本月的时间
- if (checkTime != null && YearMonth.from(checkTime).equals(YearMonth.now())) {
- deviceListVo.setCheckResult("已检查");
- }else {
+ if (deviceIdsRecord.contains(deviceListVo.getId())){
+ Record record = records.stream().filter(e -> e.getDeviceId().equals(deviceListVo.getId())).findFirst()
+ .orElse(null);
+ if (record!=null){
+ deviceListVo.setCheckResult("已检查");
+ deviceListVo.setCheckTime(record.getCreateTime());
+ }
+ }else{
deviceListVo.setCheckResult("未检查");
+ deviceListVo.setCheckTime(null);
+
}
+//
+// LocalDateTime checkTime = deviceListVo.getCheckTime();
+// // 判断checkTime是否是本月的时间
+// if (checkTime != null && YearMonth.from(checkTime).equals(YearMonth.now())) {
+// deviceListVo.setCheckResult("已检查");
+// }else {
+// deviceListVo.setCheckResult("未检查");
+// }
}
return deviceList;
}
@Override
- public List<ErrorListVo> errorList(Page<ErrorListVo> page, ErrorListQuery query) {
+ public List<ErrorListVo> errorList(Page<ErrorListVo> page, ErrorListQuery query) throws ParseException {
// 查询在建工程项目(usage_type 表示项目用途类型,假设 0 表示在建工程)
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ if (StringUtils.hasLength(query.getStartTime())){
+ Date startTime = simpleDateFormat.parse(query.getStartTime());
+ }
LambdaQueryWrapper<Project> projectWrapper = new LambdaQueryWrapper<>();
+ projectWrapper.eq(Project::getDeleted, false)
+ .ne(Project::getType, 2) // 在建工程
+ .and(wrapper -> wrapper
+ .eq(Project::getStatus, 1) // 在建项目
+ .or(w -> w
+ .eq(Project::getStatus, 2) // 已完成项目
+ .ge(Project::getSuccessTime, "2026-01-01 00:00:00") // 完成时间 >= 开始日期// 完成时间 <= 结束日期
+ )
+ );
if (query.getClientId() != null) {
projectWrapper.eq(Project::getClientId, query.getClientId());
}
@@ -302,8 +439,7 @@
// 查询重大隐患记录(level 表示隐患等级,0 表示重大隐患)
LambdaQueryWrapper<Record> recordWrapper = new LambdaQueryWrapper<>();
recordWrapper.eq(Record::getDeleted, false)
- .in(Record::getCheckTaskId, checkTaskIds)
- .eq(Record::getLevel, 0); // 重大隐患等级
+ .in(Record::getCheckTaskId, checkTaskIds);
List<Integer> recordIds = recordMapper.selectList(recordWrapper).stream().map(Record::getId).toList();
query.setRecordIds(recordIds);
List<ErrorListVo> errorList = this.baseMapper.deviceErrorList(page, query);
@@ -331,8 +467,7 @@
// 查询重大隐患记录(level 表示隐患等级,0 表示重大隐患)
LambdaQueryWrapper<Record> recordWrapper = new LambdaQueryWrapper<>();
recordWrapper.eq(Record::getDeleted, false)
- .in(Record::getCheckTaskId, checkTaskIds)
- .eq(Record::getLevel, 0); // 重大隐患等级
+ .in(Record::getCheckTaskId, checkTaskIds);
List<Integer> recordIds = recordMapper.selectList(recordWrapper).stream().map(Record::getId).toList();
query.setRecordIds(recordIds);
List<ErrorListVo> errorList = this.baseMapper.safetyErrorList(page, query);
diff --git a/ruoyi-system/src/main/resources/mapper/system/DeviceUsageMapper.xml b/ruoyi-system/src/main/resources/mapper/system/DeviceUsageMapper.xml
index 407ec7a..35a5a7b 100644
--- a/ruoyi-system/src/main/resources/mapper/system/DeviceUsageMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/DeviceUsageMapper.xml
@@ -52,12 +52,19 @@
left join (
select device_id, max(create_time) as record_time
from record
+ where device_id is not null and deleted = 0 and record_type ='error'
group by device_id
) latest on t2.id = latest.device_id
left join project t3 on t1.project_id = t3.id
- where t1.deleted = 0 and t1.disabled = 0 and t3.client_id =#{query.clientId}
+ where 1=1
<if test="query.projectId != null">
and t1.project_id = #{query.projectId}
+ </if>
+ <if test="query.projectIds != null">
+ and t1.project_id in
+ <foreach item="item" index="index" collection="query.projectIds" open="(" separator="," close=")">
+ #{item}
+ </foreach>
</if>
<if test="query.type != null">
and t2.type = #{query.type}
@@ -84,8 +91,22 @@
group by project_id
order by create_time desc
) result on t1.id = result.project_id
- where t1.deleted = 0 and t1.status =1 and t1.type!=2 and t1.client_id =#{query.clientId}
-
+ where t1.deleted = 0 and t1.status =1
+ <if test="query.category == 1">
+ and t1.status = #{query.category}
+ </if>
+ <if test="query.category == 2">
+ and t1.type = #{query.category}
+ </if>
+ <if test="query.clientId != null">
+ and t1.client_id = #{query.clientId}
+ </if>
+ <if test="query.projectIds != null">
+ and t1.id in
+ <foreach item="item" index="index" collection="query.projectIds" open="(" separator="," close=")">
+ #{item}
+ </foreach>
+ </if>
<if test="query.projectId != null">
and t1.id = #{query.projectId}
</if>
@@ -93,16 +114,10 @@
and t1.type = #{query.type}
</if>
<if test="query.riskLevel != null">
- and result.risk_level = #{query.riskLevel}
+ and `result`.risk_level = #{query.riskLevel}
</if>
<if test="query.name!= null and query.name!=''">
- and t1.name like CONCAT('%', #{query.content}, '%')
- </if>
- <if test="query.startTime != null and query.startTime != ''">
- and latest.record_time >= #{query.startTime}
- </if>
- <if test="query.endTime != null and query.endTime != ''">
- and #{query.endTime} >=latest.record_time
+ and t1.name like CONCAT('%', #{query.name}, '%')
</if>
GROUP BY t1.id
order by t1.create_time desc
--
Gitblit v1.7.1