Parcourir la source

Merge branch 'release' of gitadmin/tuoheng_lc into master

tags/v1.1.0
wanghaoran il y a 1 an
Parent
révision
488fee503d
54 fichiers modifiés avec 2236 ajouts et 386 suppressions
  1. +97
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/controller/AliyunOssController.java
  2. +61
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/controller/IndexGisController.java
  3. +2
    -1
      tuoheng-admin/src/main/java/com/tuoheng/admin/controller/InspectionController.java
  4. +3
    -1
      tuoheng-admin/src/main/java/com/tuoheng/admin/controller/QuestionController.java
  5. +2
    -2
      tuoheng-admin/src/main/java/com/tuoheng/admin/controller/QuestionTypeController.java
  6. +11
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/controller/ReportController.java
  7. +90
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/controller/WorkOrderController.java
  8. +67
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/domain/QuestionHandle.java
  9. +14
    -9
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/domain/Tenant.java
  10. +81
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/domain/WorkOrder.java
  11. +42
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/domain/WorkOrderQuestion.java
  12. +54
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/dto/index/AirportDetailDto.java
  13. +72
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/dto/index/QuestionListDto.java
  14. +5
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/request/MissionStatusRequest.java
  15. +28
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/request/WorkOrderHandleRequest.java
  16. +24
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/request/WorkOrderQuestionRequest.java
  17. +49
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/request/WorkOrderRequest.java
  18. +21
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/request/index/GetAirportDetailDto.java
  19. +24
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/request/index/GetQuestionListDto.java
  20. +13
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/vo/QuestionDetailVO.java
  21. +45
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/vo/QuestionHandleVO.java
  22. +4
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/vo/QuestionReportVO.java
  23. +147
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/vo/QuestionVO.java
  24. +67
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/vo/WorkOrderInfoVO.java
  25. +86
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/vo/WorkOrderQuestionVO.java
  26. +19
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/entity/vo/index/IndexMissionVO.java
  27. +23
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/enums/WorkOrderStatusEnum.java
  28. +12
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/mapper/QuestionHandleMapper.java
  29. +5
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/mapper/QuestionMapper.java
  30. +13
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/mapper/WorkOrderMapper.java
  31. +7
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/mapper/WorkOrderQuestionMapper.java
  32. +3
    -1
      tuoheng-admin/src/main/java/com/tuoheng/admin/service/IQuestionService.java
  33. +8
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/service/IReportService.java
  34. +3
    -2
      tuoheng-admin/src/main/java/com/tuoheng/admin/service/IThInspectionService.java
  35. +23
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/service/IWorkOrderService.java
  36. +26
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/service/IndexService.java
  37. +148
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/service/impl/IndexServiceImpl.java
  38. +1
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/service/impl/MissionServiceImpl.java
  39. +63
    -31
      tuoheng-admin/src/main/java/com/tuoheng/admin/service/impl/QuestionServiceImpl.java
  40. +366
    -11
      tuoheng-admin/src/main/java/com/tuoheng/admin/service/impl/ReportServiceImpl.java
  41. +1
    -1
      tuoheng-admin/src/main/java/com/tuoheng/admin/service/impl/TenantServiceImpl.java
  42. +54
    -34
      tuoheng-admin/src/main/java/com/tuoheng/admin/service/impl/ThInspectionServiceImpl.java
  43. +251
    -0
      tuoheng-admin/src/main/java/com/tuoheng/admin/service/impl/WorkOrderServiceImpl.java
  44. +9
    -11
      tuoheng-admin/src/main/java/com/tuoheng/admin/task/ScheduledTask.java
  45. +0
    -220
      tuoheng-admin/src/main/resources/application-airport.yml
  46. +4
    -12
      tuoheng-admin/src/main/resources/application-dev.yml
  47. +3
    -11
      tuoheng-admin/src/main/resources/application-local.yml
  48. +2
    -3
      tuoheng-admin/src/main/resources/application-prod.yml
  49. +10
    -19
      tuoheng-admin/src/main/resources/application-test.yml
  50. +17
    -0
      tuoheng-admin/src/main/resources/mapper/QuestionHandleMapper.xml
  51. +17
    -0
      tuoheng-admin/src/main/resources/mapper/QuestionMapper.xml
  52. +38
    -0
      tuoheng-admin/src/main/resources/mapper/WorkOrderMapper.xml
  53. +0
    -16
      tuoheng-common/src/main/java/com/tuoheng/common/config/CommonConfig.java
  54. +1
    -1
      tuoheng-common/src/main/java/com/tuoheng/common/utils/HttpUtils.java

+ 97
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/controller/AliyunOssController.java Voir le fichier

@@ -0,0 +1,97 @@
package com.tuoheng.admin.controller;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.tuoheng.admin.config.AliyuncsVodConfig;
import com.tuoheng.common.utils.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


/**
* 阿里云对象存储OSS 前端控制器
*
* @author WangHaoran
* @since 2022-03-15
*/
@Slf4j
@RestController
@RequestMapping("/aliyunOss")
public class AliyunOssController {

/**
* 获取securityToken
*
* @return
*/
@GetMapping("/getSecurityToken")
public JsonResult getSecurityToken() {
// STS接入地址,例如sts.cn-shanghai.aliyuncs.com。
String endpoint = "sts.cn-shanghai.aliyuncs.com";
// 填写步骤1生成的访问密钥AccessKey ID和AccessKey Secret。
String AccessKeyId = AliyuncsVodConfig.accessKeyId;
String accessKeySecret = AliyuncsVodConfig.accessKeySecret;
// 填写步骤3获取的角色ARN。
String roleArn = AliyuncsVodConfig.roleArn;
// 自定义角色会话名称,用来区分不同的令牌,例如可填写为SessionTest。
// String roleSessionName = "<yourRoleSessionName>";
// 以下Policy用于限制仅允许使用临时访问凭证向目标存储空间examplebucket上传文件。
// 临时访问凭证最后获得的权限是步骤4设置的角色权限和该Policy设置权限的交集,即仅允许将文件上传至目标存储空间examplebucket下的exampledir目录。
String policy = "{\n" +
" \"Version\": \"1\", \n" +
" \"Statement\": [\n" +
" {\n" +
" \"Action\": [\n" +
" \"oss:PutObject\"\n" +
" ], \n" +
" \"Resource\": [\n" +
" \"acs:oss:*:*:ta-tech-image/imagedir/*\" \n" +
" ], \n" +
" \"Effect\": \"Allow\"\n" +
" }\n" +
" ]\n" +
"}";
try {
// regionId表示RAM的地域ID。以华东1(杭州)地域为例,regionID填写为cn-hangzhou。也可以保留默认值,默认值为空字符串("")。
String regionId = "";
// 添加endpoint。适用于Java SDK 3.12.0及以上版本。
DefaultProfile.addEndpoint(regionId, "Sts", endpoint);
// 添加endpoint。适用于Java SDK 3.12.0以下版本。
// DefaultProfile.addEndpoint("",regionId, "Sts", endpoint);
// 构造default profile。
IClientProfile profile = DefaultProfile.getProfile(regionId, AccessKeyId, accessKeySecret);
// 构造client。
DefaultAcsClient client = new DefaultAcsClient(profile);
final AssumeRoleRequest request = new AssumeRoleRequest();
// 适用于Java SDK 3.12.0及以上版本。
request.setSysMethod(MethodType.POST);
// 适用于Java SDK 3.12.0以下版本。
//request.setMethod(MethodType.POST);
request.setRoleArn(roleArn);
request.setRoleSessionName("SessionTest");
request.setPolicy(policy); // 如果policy为空,则用户将获得该角色下所有权限。
request.setDurationSeconds(3600L); // 设置临时访问凭证的有效时间为3600秒。
final AssumeRoleResponse response = client.getAcsResponse(request);
log.info("Expiration: " + response.getCredentials().getExpiration());
log.info("Access Key Id: " + response.getCredentials().getAccessKeyId());
log.info("Access Key Secret: " + response.getCredentials().getAccessKeySecret());
log.info("Security Token: " + response.getCredentials().getSecurityToken());
log.info("RequestId: " + response.getRequestId());
return JsonResult.success(response.getCredentials());
} catch (ClientException e) {
log.error("Error code: " + e.getErrCode());
log.error("Error message: " + e.getErrMsg());
log.error("RequestId: " + e.getRequestId());
}
return JsonResult.error();
}


}

+ 61
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/controller/IndexGisController.java Voir le fichier

@@ -0,0 +1,61 @@
package com.tuoheng.admin.controller;

import com.tuoheng.admin.entity.request.index.GetAirportDetailDto;
import com.tuoheng.admin.entity.request.index.GetQuestionListDto;
import com.tuoheng.admin.service.IndexService;
import com.tuoheng.common.common.BaseQuery;
import com.tuoheng.common.utils.JsonResult;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
* @author chenjiandong
* @description: TODO
* @date 2022/12/26 10:10
*/
@RestController
@RequestMapping("/index")
@ApiOperation(value = "首页")
@Slf4j
public class IndexGisController {

@Autowired
private IndexService indexService;

/**
* 获取任务列表
* @param baseQuery
* @return
*/
@PostMapping("/getMissionList")
public JsonResult getMissionList(@RequestBody BaseQuery baseQuery) {
log.info("Index getMissionList start...");
return JsonResult.success(indexService.getMissionList(baseQuery));
}

/**
* 获取机场详细信息
* @param getAirportDetailDto
* @return
*/
@PostMapping("/getAirportDetail")
public JsonResult getAirportDetail(@RequestBody GetAirportDetailDto getAirportDetailDto) {
log.info("Index getAirportDetail start... param:{}", getAirportDetailDto.toString());
return indexService.getAirportDetail(getAirportDetailDto);
}

/**
* 获取问题列表
* @param getQuestionListDto
* @return
*/
@PostMapping("/getQuestionList")
public JsonResult getQuestionList(@RequestBody @Validated GetQuestionListDto getQuestionListDto) {
log.info("Index getQuestionList start... param:{}", getQuestionListDto.toString());
return JsonResult.success(indexService.getQuestionList(getQuestionListDto));
}

}

+ 2
- 1
tuoheng-admin/src/main/java/com/tuoheng/admin/controller/InspectionController.java Voir le fichier

@@ -21,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.util.List;

/**
@@ -46,7 +47,7 @@ public class InspectionController {
*/
@GetMapping("/airport")
@ApiOperation(value = "获取巡检机场", notes = "获取巡检机场")
public JsonResult airport(BaseQuery baseQuery) {
public JsonResult airport(BaseQuery baseQuery) throws UnsupportedEncodingException {
return JsonResult.success(inspectionService.airport());
}


+ 3
- 1
tuoheng-admin/src/main/java/com/tuoheng/admin/controller/QuestionController.java Voir le fichier

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.tuoheng.admin.entity.domain.Question;
import com.tuoheng.admin.entity.request.*;
import com.tuoheng.admin.entity.vo.QuestionTypeCountVO;
import com.tuoheng.admin.entity.vo.QuestionVO;
import com.tuoheng.admin.service.IQuestionService;
import com.tuoheng.common.utils.JsonResult;
import lombok.extern.slf4j.Slf4j;
@@ -14,6 +15,7 @@ import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import java.text.ParseException;
import java.util.List;
import java.util.Map;

@@ -38,7 +40,7 @@ public class QuestionController {
* @return
*/
@GetMapping("/page")
public JsonResult<IPage<Question>> page(QuestionQuery questionQuery) {
public JsonResult<IPage<QuestionVO>> page(QuestionQuery questionQuery) throws ParseException {
return JsonResult.success(questionService.queryPage(questionQuery));
}


+ 2
- 2
tuoheng-admin/src/main/java/com/tuoheng/admin/controller/QuestionTypeController.java Voir le fichier

@@ -22,7 +22,7 @@ import java.util.Map;
* @since 2021-09-02
*/
@RestController
@RequestMapping("/question/type")
@RequestMapping("/question")
public class QuestionTypeController {

@Autowired
@@ -31,7 +31,7 @@ public class QuestionTypeController {
/**
* 获取巡检问题列表
*/
@GetMapping("")
@GetMapping("/type")
public JsonResult getQuestionType() {
return JsonResult.success(questionTypeService.list());
}

+ 11
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/controller/ReportController.java Voir le fichier

@@ -73,4 +73,15 @@ public class ReportController {
return JsonResult.success(reportService.exportReportWord(reportId, request, response));
}

/**
* 导出处理报告word并下载
*
* @param reportId 报告ID
* @return
*/
@GetMapping(value = "{reportId}/handleWord")
public JsonResult<String> exportReportHandleWord(@PathVariable("reportId") Integer reportId, HttpServletRequest request, HttpServletResponse response) throws Exception{
return JsonResult.success(reportService.exportReportHandleWord(reportId, request, response));
}

}

+ 90
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/controller/WorkOrderController.java Voir le fichier

@@ -0,0 +1,90 @@
package com.tuoheng.admin.controller;

import com.tuoheng.admin.entity.request.QuestionStatusRequest;
import com.tuoheng.admin.entity.request.WorkOrderHandleRequest;
import com.tuoheng.admin.entity.request.WorkOrderQuestionRequest;
import com.tuoheng.admin.entity.request.WorkOrderRequest;
import com.tuoheng.admin.service.IWorkOrderService;
import com.tuoheng.common.utils.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


/**
* 工单表 前端控制器
*
* @author Wanghaoran
* @since 2022-12-27
*/
@RestController
@RequestMapping("/workOrder")
public class WorkOrderController {

@Autowired
private IWorkOrderService workOrderService;

/**
* 获取工单列表(分页)
*
* @param request 查询条件
* @return
*/
@GetMapping("/page")
public JsonResult queryPage(WorkOrderRequest request) {
return workOrderService.queryPage(request);
}

/**
* 生成工单
*
* @return
*/
@PostMapping("/generate/{ids}")
public JsonResult generate(@PathVariable("ids") Integer[] ids) {
return workOrderService.generate(ids);
}

/**
* 分配处理人员
*
* @return
*/
@PostMapping("/assign")
public JsonResult assign(@RequestBody WorkOrderRequest request) {
return workOrderService.assign(request);
}

/**
* 处理人员处理
*
* @return
*/
@PostMapping("/handle")
public JsonResult handle(@RequestBody WorkOrderHandleRequest request) {
return workOrderService.handle(request);
}

/**
* 工单问题列表
*
* @param
* @return
*/
@GetMapping("/question/page")
public JsonResult questionPage(WorkOrderQuestionRequest request) {
return workOrderService.questionPage(request);
}


/**
* 工单问题详情
*
* @param
* @return
*/
@GetMapping("/question/detail")
public JsonResult questionDetail(@RequestParam("questionId") Integer questionId) {
return workOrderService.questionDetail(questionId);
}

}

+ 67
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/domain/QuestionHandle.java Voir le fichier

@@ -0,0 +1,67 @@
package com.tuoheng.admin.entity.domain;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.tuoheng.common.common.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serializable;
import java.util.Date;

/**
* 巡检问题处理结果映射实体
*
* @author WangHaoran
* @date 2022/12/27
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("th_question_handle")
public class QuestionHandle extends BaseEntity implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 巡检问题文件ID
*/
private Integer questionId;

/**
* 处理人
*/
private Integer handlerUser;

/**
* 处理后图片(多个图片逗号“,”分隔)
*/
private String handlerImage;

/**
* 处理结果
*/
private String handlerResult;

/**
* 处理时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date handlerTime;

/**
* 处理状态:0待处理 1已处理
*/
@TableField(exist = false)
private Integer status;

/**
* 处理人名称
*/
@TableField(exist = false)
private String handlerUserName;
}

+ 14
- 9
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/domain/Tenant.java Voir le fichier

@@ -30,15 +30,15 @@ public class Tenant extends BaseEntity implements Serializable {

private static final long serialVersionUID = 1L;

public Tenant(int type){
if(type== UpdateOrCreateEnum.CREATE.getCode()){
setCreateUser(ShiroUtils.getUserId());
setCreateTime(new Date());
setMark(MarkTypeEnum.VALID.getCode());
}
setUpdateUser(ShiroUtils.getUserId());
setUpdateTime(new Date());
}
// public Tenant(int type){
// if(type== UpdateOrCreateEnum.CREATE.getCode()){
// setCreateUser(ShiroUtils.getUserId());
// setCreateTime(new Date());
// setMark(MarkTypeEnum.VALID.getCode());
// }
// setUpdateUser(ShiroUtils.getUserId());
// setUpdateTime(new Date());
// }

/**
* 租户名称
@@ -75,6 +75,11 @@ public class Tenant extends BaseEntity implements Serializable {
*/
private String email;

/**
* 机场调用邮箱
*/
private String airportUrl;

/**
* 省份编号
*/

+ 81
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/domain/WorkOrder.java Voir le fichier

@@ -0,0 +1,81 @@
package com.tuoheng.admin.entity.domain;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.tuoheng.common.common.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serializable;
import java.util.Date;

/**
* 巡检问题工单映射实体
*
* @author WangHaoran
* @date 2022/12/27
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("th_work_order")
public class WorkOrder extends BaseEntity implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 问题工单号
*/
private String code;

/**
* 工单状态:5待分配 10处理中(已分配) 15已完成
*/
private Integer status;

/**
* 指派负责人,多个用,隔开
*/
private String assignUser;

/**
* 指派备注
*/
private String assignNote;

/**
* 指派时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date assignTime;

/**
* 完成时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date finishTime;

/**
* 问题总数
*/
@TableField(exist = false)
private Integer questionTotal;

/**
* 未处理问题数
*/
@TableField(exist = false)
private Integer unhandledTotal;

/**
* 指派负责人名称
*/
@TableField(exist = false)
private String assignUserName;

}

+ 42
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/domain/WorkOrderQuestion.java Voir le fichier

@@ -0,0 +1,42 @@
package com.tuoheng.admin.entity.domain;

import com.baomidou.mybatisplus.annotation.TableName;
import com.tuoheng.common.common.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
* 巡检问题工单子表映射实体
*
* @author WangHaoran
* @date 2022/12/27
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("th_work_order_question")
public class WorkOrderQuestion extends BaseEntity implements Serializable {

private static final long serialVersionUID = 1L;

private Integer tenantId;

/**
* 巡检问题工单ID
*/
private Integer workOrderId;

/**
* 巡检问题文件ID
*/
private Integer questionId;

/**
* 处理状态:0待处理 1已处理
*/
private Integer status;

}

+ 54
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/dto/index/AirportDetailDto.java Voir le fichier

@@ -0,0 +1,54 @@
package com.tuoheng.admin.entity.dto.index;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
* @author chenjiandong
* @description: TODO
* @date 2022/12/28 14:53
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class AirportDetailDto {

/**
* 风速
*/
private String wspd;

/**
* 风向
*/
private String wdir;

/**
* 大气压力
*/
private String hpa;

/**
* 空气湿度
*/
private String hum;

/**
* 空气温度
*/
private String tmp;

/**
* 机场状态
*/
private String status;

/**
* 可选挂载
*/
private String mountName;

}

+ 72
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/dto/index/QuestionListDto.java Voir le fichier

@@ -0,0 +1,72 @@
package com.tuoheng.admin.entity.dto.index;

import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
* @author chenjiandong
* @description: TODO
* @date 2022/12/27 17:55
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class QuestionListDto {

private Integer questionId;

private String missionId;

/**
* 任务名称
*/
private String missionName;

/**
* 经度
*/
private String lng;

/**
* 纬度
*/
private String lat;

private String type;

/**
* 问题类型
*/
private String typeName;

/**
* 巡检时间
*/
private String inspectionTime;

/**
* 问题图片
*/
private String fileMarkerUrl;

/**
* 处理结果
*/
private String handlerResult;

/**
* 多张处理图片,","相隔
*/
private String handlerImage;

private Integer handlerUserId;

private String handlerUserName;

private String handlerTime;

}

+ 5
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/request/MissionStatusRequest.java Voir le fichier

@@ -37,4 +37,9 @@ public class MissionStatusRequest implements Serializable {
@ApiModelProperty(value = "任务里程")
private String mileage;

@ApiModelProperty(value = "直播原视频外网地址")
private String playUrl;

@ApiModelProperty(value = "请求ID")
private String requestId;
}

+ 28
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/request/WorkOrderHandleRequest.java Voir le fichier

@@ -0,0 +1,28 @@
package com.tuoheng.admin.entity.request;

import lombok.Data;

@Data
public class WorkOrderHandleRequest {

/**
* 巡检问题工单ID
*/
private Integer workOrderId;

/**
* 巡检问题文件ID
*/
private Integer questionId;

/**
* 处理后图片(多个图片逗号“,”分隔)
*/
private String handlerImage;

/**
* 处理结果
*/
private String handlerResult;

}

+ 24
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/request/WorkOrderQuestionRequest.java Voir le fichier

@@ -0,0 +1,24 @@
package com.tuoheng.admin.entity.request;

import com.tuoheng.common.common.BaseQuery;
import lombok.Data;

@Data
public class WorkOrderQuestionRequest extends BaseQuery {

/**
* 工单ID
*/
private Integer workOrderId;

/**
* 问题编码
*/
private String questionType;

/**
* 问题状态:0待处理 1已处理
*/
private Integer status;

}

+ 49
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/request/WorkOrderRequest.java Voir le fichier

@@ -0,0 +1,49 @@
package com.tuoheng.admin.entity.request;

import com.tuoheng.common.common.BaseQuery;
import lombok.Data;

import java.io.Serializable;
import java.util.List;

@Data
public class WorkOrderRequest extends BaseQuery implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 工单ID
*/
private Integer id;

/**
* 问题工单号
*/
private String code;

/**
* 工单状态:5待分配 10处理中(已分配) 15已完成
*/
private Integer status;

/**
* 开始时间
*/
private String createStartTime;

/**
* 结束时间
*/
private String createEndTime;

/**
* 处理人员
*/
private List<Integer> handleUserList;

/**
* 处理标识,为1时,查询分配给当前登录人的数据
*/
private Integer handleFlag;

}

+ 21
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/request/index/GetAirportDetailDto.java Voir le fichier

@@ -0,0 +1,21 @@
package com.tuoheng.admin.entity.request.index;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
* @author chenjiandong
* @description: TODO
* @date 2022/12/27 17:09
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class GetAirportDetailDto {

private Integer airportId;

}

+ 24
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/request/index/GetQuestionListDto.java Voir le fichier

@@ -0,0 +1,24 @@
package com.tuoheng.admin.entity.request.index;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotEmpty;

/**
* @author chenjiandong
* @description: TODO
* @date 2022/12/27 17:09
*/
@Data
public class GetQuestionListDto {

@NotEmpty(message = "startTime can not be empty!")
private String startTime;

@NotEmpty(message = "endTime can not be empty!")
private String endTime;

}

+ 13
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/vo/QuestionDetailVO.java Voir le fichier

@@ -0,0 +1,13 @@
package com.tuoheng.admin.entity.vo;

import com.tuoheng.admin.entity.domain.Question;
import com.tuoheng.admin.entity.domain.QuestionHandle;
import lombok.Data;

@Data
public class QuestionDetailVO {

private Question question;

private QuestionHandle questionHandle;
}

+ 45
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/vo/QuestionHandleVO.java Voir le fichier

@@ -0,0 +1,45 @@
package com.tuoheng.admin.entity.vo;

import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

@Data
public class QuestionHandleVO {

/**
* 处理人
*/
private Integer handlerUser;

/**
* 处理人
*/
private String handlerUserName;

/**
* 处理后图片(多个图片逗号“,”分隔)
*/
private String handlerImage;

/**
* 处理结果
*/
private String handlerResult;

/**
* 处理时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date handlerTime;

/**
* 处理状态:0待处理 1已处理
*/
@TableField(exist = false)
private Integer status;
}

+ 4
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/vo/QuestionReportVO.java Voir le fichier

@@ -4,6 +4,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;
import java.util.List;

@Data
public class QuestionReportVO implements Serializable {
@@ -24,4 +25,7 @@ public class QuestionReportVO implements Serializable {

@ApiModelProperty(value = "经度")
private String lng;

@ApiModelProperty(value = "问题处理清单")
private List<QuestionHandleVO> questionHandleList;
}

+ 147
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/vo/QuestionVO.java Voir le fichier

@@ -0,0 +1,147 @@
package com.tuoheng.admin.entity.vo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.tuoheng.admin.entity.domain.Question;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

/**
* 巡检任务 新增或修改请求参数 2022/7/27
* @author : qiujinyang
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class QuestionVO {

private static final long serialVersionUID = 1L;

/**
* 工单生成状态
*/
private Integer wordOrderStatus;

/**
* 工单处理状态
*/
private Integer handleStatus;

/**
* 任务ID
*/
private Integer missionId;

/**
* 任务名称
*/
private String missionName;

/**
* 问题类型:病死树、林斑
*/
private String type;

/**
* 问题类型名称
*/
private String questionName;

/**
* 问题描述
*/
private String questionDesc;

/**
* 图片分析时间,可以通过这个时间来计算出坐标位置
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date analyseTime;

/**
* 文件编码
*/
private String fileCode;

/**
* 文件名称
*/
private String fileName;

/**
* 原图片位置
*/
private String fileOriginalUrl;

/**
* 分析后的图片位置
*/
private String fileMarkerUrl;

/**
* 经度
*/
private String lng;

/**
* 纬度
*/
private String lat;

/**
* 备注
*/
private String note;

/**
* 问题状态:1:确认,2:忽略,3:待确认
*/
private Integer status;


/**
* 租户id
*/
private Integer tenantId;

/**
* 主键ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;

/**
* 添加人
*/
private Integer createUser;

/**
* 创建时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;

/**
* 更新人
*/
private Integer updateUser;

/**
* 更新时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime;

/**
* 有效标识
*/
private Integer mark;
}

+ 67
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/vo/WorkOrderInfoVO.java Voir le fichier

@@ -0,0 +1,67 @@
package com.tuoheng.admin.entity.vo;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

@Data
public class WorkOrderInfoVO {

/**
* 问题工单号
*/
private String code;

/**
* 工单状态:5待分配 10处理中(已分配) 15已完成
*/
private Integer status;

/**
* 指派负责人,多个用,隔开
*/
private String assignUser;

/**
* 指派备注
*/
private String assignNote;

/**
* 指派时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date assignTime;

/**
* 完成时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date finishTime;

/**
* 问题总数
*/
private Integer questionTotal;

/**
* 未处理问题数
*/
private Integer unhandledTotal;

/**
* 指派负责人名称
*/
private String assignUserName;

/**
* 创建时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
}

+ 86
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/vo/WorkOrderQuestionVO.java Voir le fichier

@@ -0,0 +1,86 @@
package com.tuoheng.admin.entity.vo;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

@Data
public class WorkOrderQuestionVO {

/**
* 问题ID
*/
private Integer questionId;

/**
* 问题类型
*/
private String type;

/**
* 问题描述
*/
private String questionDesc;

/**
* 问题类型名称
*/
private String questionName;
/**
* 原图片地址
*/
private String fileOriginalUrl;
/**
* 分析后的图片地址
*/
private String fileMarkerUrl;
/**
* 经度
*/
private String lng;
/**
* 纬度
*/
private String lat;
/**
* 处理状态:0待处理 1已处理
*/
private Integer status;

/**
* 发现时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;

/**
* 处理人员
*/
private Integer handlerUser;

/**
* 处理后图片(多个图片逗号“,”分隔)
*/
private String handlerImage;

/**
* 处理后图片(多个图片逗号“,”分隔)
*/
private String handlerResult;

/**
* 处理完成时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date handlerTime;

/**
* 处理人员名称
*/
private String handlerUserName;

}

+ 19
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/entity/vo/index/IndexMissionVO.java Voir le fichier

@@ -0,0 +1,19 @@
package com.tuoheng.admin.entity.vo.index;

import lombok.Data;

/**
* @author chenjiandong
* @description: TODO
* @date 2022/12/26 10:29
*/
@Data
public class IndexMissionVO {

private Integer missionId;

private String missionName;

private Integer status;

}

+ 23
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/enums/WorkOrderStatusEnum.java Voir le fichier

@@ -0,0 +1,23 @@
package com.tuoheng.admin.enums;

import lombok.Getter;

public enum WorkOrderStatusEnum {

//工单状态:5待分配 10处理中(已分配) 15已完成
TO_BE_ALLOCATED(5,"待分配"),
ALLOCATED(10,"已分配"),
COMPLETED(15,"已完成");

WorkOrderStatusEnum(int code, String description){
this.code = code;
this.description = description;
}

@Getter
private int code;

@Getter
private String description;

}

+ 12
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/mapper/QuestionHandleMapper.java Voir le fichier

@@ -0,0 +1,12 @@
package com.tuoheng.admin.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tuoheng.admin.entity.domain.QuestionHandle;
import com.tuoheng.admin.entity.vo.QuestionHandleVO;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface QuestionHandleMapper extends BaseMapper<QuestionHandle> {
List<QuestionHandleVO> getList(@Param("questionId") Integer questionId);
}

+ 5
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/mapper/QuestionMapper.java Voir le fichier

@@ -2,6 +2,8 @@ package com.tuoheng.admin.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tuoheng.admin.entity.domain.Question;
import com.tuoheng.admin.entity.dto.index.QuestionListDto;
import com.tuoheng.admin.entity.request.index.GetQuestionListDto;
import com.tuoheng.admin.entity.vo.QuestionCountVO;
import com.tuoheng.admin.entity.vo.QuestionTypeCountVO;

@@ -18,4 +20,7 @@ public interface QuestionMapper extends BaseMapper<Question> {
List<QuestionCountVO> analyze(Integer missionId);

List<QuestionTypeCountVO> analyzeType(Integer missionId, Integer tenantId);

List<QuestionListDto> getIndexQuestion(GetQuestionListDto getQuestionListDto);

}

+ 13
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/mapper/WorkOrderMapper.java Voir le fichier

@@ -0,0 +1,13 @@
package com.tuoheng.admin.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.tuoheng.admin.entity.domain.WorkOrder;
import com.tuoheng.admin.entity.request.WorkOrderQuestionRequest;
import com.tuoheng.admin.entity.vo.WorkOrderQuestionVO;
import org.apache.ibatis.annotations.Param;


public interface WorkOrderMapper extends BaseMapper<WorkOrder> {
IPage<WorkOrderQuestionVO> questionPage(@Param("page") IPage page, @Param("request") WorkOrderQuestionRequest request);
}

+ 7
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/mapper/WorkOrderQuestionMapper.java Voir le fichier

@@ -0,0 +1,7 @@
package com.tuoheng.admin.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tuoheng.admin.entity.domain.WorkOrderQuestion;

public interface WorkOrderQuestionMapper extends BaseMapper<WorkOrderQuestion> {
}

+ 3
- 1
tuoheng-admin/src/main/java/com/tuoheng/admin/service/IQuestionService.java Voir le fichier

@@ -5,10 +5,12 @@ import com.tuoheng.admin.entity.domain.Question;
import com.tuoheng.admin.entity.request.*;
import com.tuoheng.admin.entity.vo.QuestionCountVO;
import com.tuoheng.admin.entity.vo.QuestionTypeCountVO;
import com.tuoheng.admin.entity.vo.QuestionVO;
import com.tuoheng.common.common.IBaseService;
import com.tuoheng.common.exception.ServiceException;
import com.tuoheng.common.utils.JsonResult;

import java.text.ParseException;
import java.util.List;
import java.util.Map;

@@ -26,7 +28,7 @@ public interface IQuestionService extends IBaseService<Question> {
* @param query
* @return
*/
IPage<Question> queryPage(QuestionQuery query);
IPage<QuestionVO> queryPage(QuestionQuery query) throws ParseException;

List<Question> distributed(QuestionQuery query);


+ 8
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/service/IReportService.java Voir le fichier

@@ -52,4 +52,12 @@ public interface IReportService extends IBaseService<Report> {
* @return
*/
String exportReportWord(Integer reportId, HttpServletRequest request, HttpServletResponse response) throws Exception;

/**
* 导出处理报告word并下载
*
* @param reportId 报告ID
* @return
*/
String exportReportHandleWord(Integer reportId, HttpServletRequest request, HttpServletResponse response) throws Exception;
}

+ 3
- 2
tuoheng-admin/src/main/java/com/tuoheng/admin/service/IThInspectionService.java Voir le fichier

@@ -9,6 +9,7 @@ import com.tuoheng.common.common.IBaseService;
import com.tuoheng.common.exception.ServiceException;
import com.tuoheng.common.utils.JsonResult;

import java.io.UnsupportedEncodingException;
import java.util.List;

/**
@@ -23,13 +24,13 @@ public interface IThInspectionService extends IBaseService<ThInspection> {

Integer track(InspectionRequest inspectionRequest) throws ServiceException;

List<AirPortVO> airport() throws ServiceException;
List<AirPortVO> airport() throws ServiceException, UnsupportedEncodingException;

List<AirLineVO> airLine(Integer droneId) throws ServiceException;

AirWeatherVO getWeather(Integer airportId);

JsonResult executeTask(String taskId,PushAndPullURLRequest pushAndPull) throws ServiceException;
JsonResult executeTask(String missionId,PushAndPullURLRequest pushAndPull) throws ServiceException;

JsonResult lineTrack(Integer missionId);
}

+ 23
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/service/IWorkOrderService.java Voir le fichier

@@ -0,0 +1,23 @@
package com.tuoheng.admin.service;

import com.tuoheng.admin.entity.domain.WorkOrder;
import com.tuoheng.admin.entity.request.WorkOrderHandleRequest;
import com.tuoheng.admin.entity.request.WorkOrderQuestionRequest;
import com.tuoheng.admin.entity.request.WorkOrderRequest;
import com.tuoheng.common.common.IBaseService;
import com.tuoheng.common.utils.JsonResult;


public interface IWorkOrderService extends IBaseService<WorkOrder> {
JsonResult queryPage(WorkOrderRequest request);

JsonResult generate(Integer[] ids);

JsonResult assign(WorkOrderRequest request);

JsonResult handle(WorkOrderHandleRequest request);

JsonResult questionPage(WorkOrderQuestionRequest request);

JsonResult questionDetail(Integer questionId);
}

+ 26
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/service/IndexService.java Voir le fichier

@@ -0,0 +1,26 @@
package com.tuoheng.admin.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.tuoheng.admin.entity.dto.index.QuestionListDto;
import com.tuoheng.admin.entity.request.index.GetAirportDetailDto;
import com.tuoheng.admin.entity.request.index.GetQuestionListDto;
import com.tuoheng.admin.entity.vo.MissionVO;
import com.tuoheng.common.common.BaseQuery;
import com.tuoheng.common.utils.JsonResult;

import java.util.List;

/**
* @author chenjiandong
* @description: TODO
* @date 2022/12/26 10:24
*/
public interface IndexService {

IPage<MissionVO> getMissionList(BaseQuery baseQuery);

JsonResult getAirportDetail(GetAirportDetailDto getAirportDetailDto);

List<QuestionListDto> getQuestionList(GetQuestionListDto getQuestionListDto);

}

+ 148
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/service/impl/IndexServiceImpl.java Voir le fichier

@@ -0,0 +1,148 @@
package com.tuoheng.admin.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tuoheng.admin.entity.domain.Question;
import com.tuoheng.admin.entity.domain.Tenant;
import com.tuoheng.admin.entity.domain.ThMission;
import com.tuoheng.admin.entity.dto.index.AirportDetailDto;
import com.tuoheng.admin.entity.dto.index.QuestionListDto;
import com.tuoheng.admin.entity.request.index.GetAirportDetailDto;
import com.tuoheng.admin.entity.request.index.GetQuestionListDto;
import com.tuoheng.admin.entity.vo.MissionVO;
import com.tuoheng.admin.enums.MarkTypeEnum;
import com.tuoheng.admin.enums.TaskStatusEnum;
import com.tuoheng.admin.mapper.QuestionMapper;
import com.tuoheng.admin.mapper.TenantMapper;
import com.tuoheng.admin.mapper.ThMissionMapper;
import com.tuoheng.admin.service.IndexService;
import com.tuoheng.common.common.BaseQuery;
import com.tuoheng.common.config.CommonConfig;
import com.tuoheng.common.utils.HttpUtils;
import com.tuoheng.common.utils.JacksonUtil;
import com.tuoheng.common.utils.JsonResult;
import com.tuoheng.common.utils.StringUtils;
import com.tuoheng.system.utils.ShiroUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
* @author chenjiandong
* @description: TODO
* @date 2022/12/26 10:24
*/
@Service
@Slf4j
public class IndexServiceImpl implements IndexService {

@Autowired
private ThMissionMapper thMissionMapper;

@Autowired
private QuestionMapper questionMapper;

@Autowired
private TenantMapper tenantMapper;

@Override
@Transactional(readOnly = true)
public IPage<MissionVO> getMissionList(BaseQuery baseQuery){
Page<ThMission> page = new Page<>();
page.setSize(baseQuery.getLimit() != null ? baseQuery.getLimit() : 10);
page.setCurrent(baseQuery.getPage() != null ? baseQuery.getPage() : 0);
LambdaQueryWrapper<ThMission> queryMission=new LambdaQueryWrapper<>();
queryMission.eq(ThMission::getMark,MarkTypeEnum.VALID.getCode()).orderByDesc(ThMission::getCreateTime);
queryMission.in(ThMission::getStatus, Arrays.asList(TaskStatusEnum.FLIGHT.getCode(),TaskStatusEnum.WAIT.getCode()));
IPage<ThMission> thMissionIPage = thMissionMapper.selectPage(page, queryMission);
List<ThMission> records = thMissionIPage.getRecords();
List<MissionVO> result=new ArrayList<>();
records.forEach(mission->{
MissionVO missionVO=new MissionVO();
BeanUtils.copyProperties(mission,missionVO);
//获取最后一次的飞行时间
result.add(missionVO);
});

IPage<MissionVO> resultPage=new Page<>();
resultPage.setCurrent(thMissionIPage.getCurrent());
resultPage.setPages(thMissionIPage.getPages());
resultPage.setSize(thMissionIPage.getSize());
resultPage.setTotal(thMissionIPage.getTotal());
resultPage.setRecords(result);
return resultPage;
}

@Override
public JsonResult getAirportDetail(GetAirportDetailDto getAirportDetailDto){
Tenant tenant = tenantMapper.selectById(ShiroUtils.getTenantId());
String url = tenant.getAirportUrl() +"/api/airportInterface/getAirportStatus";
String param = "airportId=" + getAirportDetailDto.getAirportId();
String result = HttpUtils.sendGet(url, param);
JsonResult jsonResult = JacksonUtil.json2pojo(result, JsonResult.class);
AirportDetailDto airportDetailDto = new AirportDetailDto();
JSONObject dataObject = (JSONObject) JSONObject.toJSON(jsonResult.getData());
JSONObject wthJson = dataObject.getJSONObject("WTH");
if(Objects.nonNull(wthJson)){
JSONObject parmJson = wthJson.getJSONObject("parm");
airportDetailDto.setWspd(parmJson.getString("WSPD") + "m/s")
.setWdir(parmJson.getString("WDIR") + "度");
//用角度表示风向,是把圆周分成360度,北风(N)是0度(即360度),东风(E)是90度,南风(S)是180度,西风(W)是270度
BigDecimal hpa = parmJson.getBigDecimal("Hpa");
if(hpa != null){
BigDecimal mpa = hpa.divide(new BigDecimal(100000), 1, BigDecimal.ROUND_HALF_UP);
airportDetailDto.setHpa(mpa + "Mpa");
}
}
JSONObject tahJson = dataObject.getJSONObject("TAH");
if(Objects.nonNull(tahJson)){
JSONObject parmJson = wthJson.getJSONObject("parm");
BigDecimal hum = parmJson.getBigDecimal("Hum").divide(new BigDecimal(10), 1, BigDecimal.ROUND_HALF_UP);
airportDetailDto.setHum(hum + "rh");
BigDecimal tmp = parmJson.getBigDecimal("Tmp").divide(new BigDecimal(10), 1, BigDecimal.ROUND_HALF_UP);
airportDetailDto.setTmp(tmp + "℃");
}
JSONObject mountJson = dataObject.getJSONObject("mount");
if(Objects.nonNull(mountJson)){
airportDetailDto.setMountName(mountJson.getString("cameraName") + "、" +
mountJson.getString("megaphoneName") + "、" +
mountJson.getString("searchlightName")
);
}
airportDetailDto.setStatus(dataObject.getString("status"));
return JsonResult.success(airportDetailDto);
}

@Override
@Transactional(readOnly = true)
public List<QuestionListDto> getQuestionList(GetQuestionListDto getQuestionListDto){
if(ObjectUtil.isNotEmpty(getQuestionListDto.getStartTime()) && ObjectUtil.isNotEmpty(getQuestionListDto.getEndTime())){
getQuestionListDto.setStartTime(getQuestionListDto.getStartTime() + " 00:00:00");
getQuestionListDto.setEndTime(getQuestionListDto.getEndTime() + " 23:59:59");
}
List<QuestionListDto> questionListDtoList = questionMapper.getIndexQuestion(getQuestionListDto);
for(QuestionListDto questionListDto : questionListDtoList){
if(questionListDto.getHandlerImage() != null){
String[] imgHanders = questionListDto.getHandlerImage().split(",");
for (int i = 0; i < imgHanders.length; i++) {
imgHanders[i] = CommonConfig.imageURL + imgHanders[i];
}
String handerImg = StringUtils.join(imgHanders, ",");
questionListDto.setHandlerImage(handerImg);
}
}
return questionListDtoList;
}
}

+ 1
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/service/impl/MissionServiceImpl.java Voir le fichier

@@ -248,6 +248,7 @@ public class MissionServiceImpl extends BaseServiceImpl<ThMissionMapper, ThMissi
LambdaQueryWrapper<ThMission> lambdaQueryWrapper=new LambdaQueryWrapper<>();
lambdaQueryWrapper.orderByAsc(ThMission::getExecutionStartTime);
lambdaQueryWrapper.eq(ThMission::getInspectionLine, missionStatusRequest.getId());
lambdaQueryWrapper.eq(ThMission::getId,missionStatusRequest.getRequestId());
lambdaQueryWrapper.eq(ThMission::getStatus,status);
//lambdaQueryWrapper.eq(ThMission::getTenantId,ShiroUtils.getTenantId());
List<ThMission> thMissions = thMissionMapper.selectList(lambdaQueryWrapper);

+ 63
- 31
tuoheng-admin/src/main/java/com/tuoheng/admin/service/impl/QuestionServiceImpl.java Voir le fichier

@@ -6,20 +6,17 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tuoheng.admin.common.ServiceExceptionEnum;
import com.tuoheng.admin.entity.domain.Question;
import com.tuoheng.admin.entity.domain.QuestionType;
import com.tuoheng.admin.entity.domain.ThInspection;
import com.tuoheng.admin.entity.domain.ThMission;
import com.tuoheng.admin.entity.domain.*;
import com.tuoheng.admin.entity.request.*;
import com.tuoheng.admin.entity.vo.MissionVO;
import com.tuoheng.admin.entity.vo.QuestionCountVO;
import com.tuoheng.admin.entity.vo.QuestionTypeCountVO;
import com.tuoheng.admin.entity.vo.QuestionVO;
import com.tuoheng.admin.enums.*;
import com.tuoheng.admin.mapper.QuestionMapper;
import com.tuoheng.admin.mapper.QuestionTypeMapper;
import com.tuoheng.admin.mapper.ThInspectionMapper;
import com.tuoheng.admin.mapper.ThMissionMapper;
import com.tuoheng.admin.mapper.*;
import com.tuoheng.admin.service.IQuestionService;
import com.tuoheng.admin.service.IQuestionTypeService;
import com.tuoheng.admin.utils.TimeUtil;
import com.tuoheng.common.common.BaseServiceImpl;
import com.tuoheng.common.exception.ServiceException;
import com.tuoheng.common.utils.JsonResult;
@@ -29,8 +26,10 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@@ -55,39 +54,61 @@ public class QuestionServiceImpl extends BaseServiceImpl<QuestionMapper, Questio
@Autowired
private ThInspectionMapper inspectionMapper;

@Autowired
private WorkOrderQuestionMapper workOrderQuestionMapper;

@Autowired
private IQuestionTypeService questionTypeService;

private final static SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

@Override
public IPage<Question> queryPage(QuestionQuery query) {
@Transactional(readOnly = true)
public IPage<QuestionVO> queryPage(QuestionQuery query) throws ParseException {
if(null == query.getPage() || null == query.getLimit()){
throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
}
IPage<Question> pageData=null;
try {
// 获取分页数据
IPage<Question> page = new Page<>(query.getPage(), query.getLimit());

LambdaQueryWrapper<Question> questionLambdaQueryWrapper = new LambdaQueryWrapper<Question>()
.eq(ObjectUtil.isNotEmpty(query.getMissionId()), Question::getMissionId, query.getMissionId())
.like(ObjectUtil.isNotEmpty(query.getName()), Question::getMissionName, query.getName())
.eq(ObjectUtil.isNotEmpty(query.getType()), Question::getType, query.getType())
.eq(ObjectUtil.isNotEmpty(query.getStatus()), Question::getStatus, query.getStatus())
//.eq(Question::getTenantId, ShiroUtils.getTenantId())
.eq(Question::getMark, MarkTypeEnum.VALID.getCode()).orderByDesc(Question::getCreateTime);
if(ObjectUtil.isNotEmpty(query.getStartTime()) && ObjectUtil.isNotEmpty(query.getEndTime())){
query.setStartTime(query.getStartTime()+" 00:00:00");
query.setEndTime(query.getEndTime()+" 23:59:59");
questionLambdaQueryWrapper.between(Question::getCreateTime, dateformat.parse(query.getStartTime()), dateformat.parse(query.getEndTime()));
}
pageData = questionMapper.selectPage(page, questionLambdaQueryWrapper);
}catch (Exception e){
e.printStackTrace();
log.error("查询出错!");
// 获取分页数据
IPage<Question> page = new Page<>(query.getPage(), query.getLimit());

LambdaQueryWrapper<Question> questionLambdaQueryWrapper = new LambdaQueryWrapper<Question>()
.eq(ObjectUtil.isNotEmpty(query.getMissionId()), Question::getMissionId, query.getMissionId())
.like(ObjectUtil.isNotEmpty(query.getName()), Question::getMissionName, query.getName())
.eq(ObjectUtil.isNotEmpty(query.getType()), Question::getType, query.getType())
.eq(ObjectUtil.isNotEmpty(query.getStatus()), Question::getStatus, query.getStatus())
//.eq(Question::getTenantId, ShiroUtils.getTenantId())
.eq(Question::getMark, MarkTypeEnum.VALID.getCode()).orderByDesc(Question::getCreateTime);
if(ObjectUtil.isNotEmpty(query.getStartTime()) && ObjectUtil.isNotEmpty(query.getEndTime())){
query.setStartTime(query.getStartTime()+" 00:00:00");
query.setEndTime(query.getEndTime()+" 23:59:59");
questionLambdaQueryWrapper.between(Question::getCreateTime, dateformat.parse(query.getStartTime()), dateformat.parse(query.getEndTime()));
}
return pageData;
IPage<Question> pageData = questionMapper.selectPage(page, questionLambdaQueryWrapper);
List<Question> questions = pageData.getRecords();
List<QuestionVO> questionVOList = new ArrayList<>();
questions.forEach(question->{
QuestionVO questionVO = new QuestionVO();
BeanUtils.copyProperties(question,questionVO);
LambdaQueryWrapper<WorkOrderQuestion> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(WorkOrderQuestion::getQuestionId, question.getId());
WorkOrderQuestion workOrderQuestion = workOrderQuestionMapper.selectOne(lambdaQueryWrapper);
if(workOrderQuestion != null){
questionVO.setWordOrderStatus(1);
questionVO.setHandleStatus(workOrderQuestion.getStatus());
}else {
questionVO.setWordOrderStatus(0);
questionVO.setHandleStatus(0);
}
questionVOList.add(questionVO);
});
IPage<QuestionVO> resultPage=new Page<>();
resultPage.setCurrent(pageData.getCurrent());
resultPage.setPages(pageData.getPages());
resultPage.setSize(pageData.getSize());
resultPage.setTotal(pageData.getTotal());
resultPage.setRecords(questionVOList);
return resultPage;

}

@Override
@@ -133,6 +154,16 @@ public class QuestionServiceImpl extends BaseServiceImpl<QuestionMapper, Questio

@Override
public JsonResult<Boolean> check(QuestionStatusRequest entity) {
//已经生成工单的问题无法修改
for (Integer id : entity.getId()) {
List<WorkOrderQuestion> workOrderQuestions = workOrderQuestionMapper.selectList(new LambdaQueryWrapper<WorkOrderQuestion>()
.eq(WorkOrderQuestion::getQuestionId, id));
if(StringUtils.isNotEmpty(workOrderQuestions)){
return JsonResult.error("问题已生成工单,无法修改!");
}
}


//根据ID的数量来判断是否是批量确认和忽略
Question question=new Question(UpdateOrCreateEnum.UPDATE.getCode());
question.setStatus(entity.getStatus());
@@ -373,4 +404,5 @@ public class QuestionServiceImpl extends BaseServiceImpl<QuestionMapper, Questio
}
return inspectionData.get(0);
}

}

+ 366
- 11
tuoheng-admin/src/main/java/com/tuoheng/admin/service/impl/ReportServiceImpl.java Voir le fichier

@@ -8,19 +8,17 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lowagie.text.*;
import com.tuoheng.admin.common.ServiceExceptionEnum;
import com.tuoheng.admin.entity.domain.Question;
import com.tuoheng.admin.entity.domain.QuestionHandle;
import com.tuoheng.admin.entity.domain.Report;
import com.tuoheng.admin.entity.domain.ThMission;
import com.tuoheng.admin.entity.request.ReportRequest;
import com.tuoheng.admin.entity.vo.*;
import com.tuoheng.admin.enums.*;
import com.tuoheng.admin.mapper.ReportMapper;
import com.tuoheng.admin.mapper.ThInspectionMapper;
import com.tuoheng.admin.mapper.ThMissionMapper;
import com.tuoheng.admin.mapper.*;
import com.tuoheng.admin.service.IQuestionService;
import com.tuoheng.admin.service.IReportService;
import com.tuoheng.admin.service.IThInspectionService;
import com.tuoheng.admin.utils.ImgTypeConvert;
import com.tuoheng.admin.utils.WeatherUtil;
import com.tuoheng.admin.utils.WordUtilsOld;
import com.tuoheng.common.common.BaseServiceImpl;
import com.tuoheng.common.config.CommonConfig;
@@ -30,8 +28,6 @@ import com.tuoheng.common.utils.DateUtils;
import com.tuoheng.common.utils.JsonResult;
import com.tuoheng.common.utils.StringUtils;
import com.tuoheng.system.service.impl.UserServiceImpl;
import com.tuoheng.system.utils.ShiroUtils;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -41,15 +37,11 @@ import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

/**
* 巡检报告表 服务实现类
@@ -79,6 +71,9 @@ public class ReportServiceImpl extends BaseServiceImpl<ReportMapper, Report> imp
@Autowired
private UserServiceImpl userService;

@Autowired
private QuestionHandleMapper questionHandleMapper;


@Override
public JsonResult generateReport(Integer missionId) {
@@ -218,6 +213,20 @@ public class ReportServiceImpl extends BaseServiceImpl<ReportMapper, Report> imp
for (Question question : questionList) {
QuestionReportVO questionReportVO=new QuestionReportVO();
BeanUtils.copyProperties(question,questionReportVO);
List<QuestionHandleVO> questionHandleList = questionHandleMapper.getList(question.getId());
for (QuestionHandleVO questionHandleVO : questionHandleList) {
//拼接图片域名
if(null != questionHandleVO && StringUtils.isNotEmpty(questionHandleVO.getHandlerImage())){
String[] imgHanders = questionHandleVO.getHandlerImage().split(",");
for (int i = 0; i < imgHanders.length; i++) {
imgHanders[i] = CommonConfig.imageURL + imgHanders[i];
}
String handerImg = StringUtils.join(imgHanders, ",");
questionHandleVO.setHandlerImage(handerImg);
}
}
questionReportVO.setQuestionHandleList(questionHandleList);

questionReportVOList.add(questionReportVO);
}
//问题列表
@@ -559,6 +568,352 @@ public class ReportServiceImpl extends BaseServiceImpl<ReportMapper, Report> imp
return UploadFileConfig.docDownLoad+"/lc/doc/"+fileName;
}

@Override
public String exportReportHandleWord(Integer reportId, HttpServletRequest request, HttpServletResponse response) throws Exception {
ReportInfoVO reportInfoVO = detail(reportId);
//创建word
String fileName = "汤山林场无人机处理报告【"+ reportInfoVO.getReportNo() + "】.doc";
String filePath = UploadFileConfig.uploadFolder+"doc/"+fileName;
File fd = new File(UploadFileConfig.uploadFolder+"doc");
File f = new File(filePath);
if(!fd.exists()){
fd.mkdirs();
}
WordUtilsOld wordUtils = new WordUtilsOld();

SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
if(f.exists()){
f.delete();
f.createNewFile();
}
log.info("开始编写word文件,文件为:{}",filePath);
wordUtils.openDocument(filePath);
wordUtils.getDocument().setPageSize(PageSize.A4);
wordUtils.getDocument().setMargins(71f, 71f, 72f, 72f);
//标题
wordUtils.insertTitlePattern("汤山林场无人机处理报告", WordUtilsOld.rtfGsBt1);
wordUtils.insertContext("报告编号:"+reportInfoVO.getReportNo(),10, Font.NORMAL, Element.ALIGN_RIGHT,20,0,0);
wordUtils.insertTitlePatternThird("一:林场信息", WordUtilsOld.rtfGsBt3);
Table table = new Table(2);//生成一表格
table.setOffset(1f);
int[] width = {1, 1};
table.setWidths(width);//设置系列所占比例
table.setWidth(100);
table.setAutoFillEmptyCells(true);
table.setAlignment(Element.ALIGN_LEFT);//居中显示
for (int i = 0; i < 6; i++) {
Cell cell = new Cell();
String str;
cell.setVerticalAlignment(Element.ALIGN_RIGHT);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
Font font = new Font();
font.setSize(10.5f);
font.setStyle(Font.BOLD);
if (i == 0) {
str = "责任单位";
font.setStyle(Font.NORMAL);
} else if (i == 1) {
str = reportInfoVO.getCompany();
} else if (i == 2) {
str = "林场名称";
font.setStyle(Font.NORMAL);
} else if (i == 3) {
str = reportInfoVO.getLcName();
} else if (i == 4) {
str = "巡查里程";
font.setStyle(Font.NORMAL);
} else {
if(StringUtils.isNotEmpty(reportInfoVO.getMission().getMileage())){
try{
BigDecimal mileageBd = new BigDecimal(reportInfoVO.getMission().getMileage()).divide(new BigDecimal(1000));
str = mileageBd + "公里";
}catch (Exception e){
log.info("转换里程出错:{}",e.getMessage());
str="";
}
}else{
str = "";
}

}
Paragraph p = new Paragraph(str, font);
cell.add(p);
table.addCell(cell);
}
wordUtils.getDocument().add(table);
log.info("林场信息写入完成");

wordUtils.insertTitlePatternThird("二:巡检信息", WordUtilsOld.rtfGsBt3);
Table table2 = new Table(2);//生成一表格
table2.setOffset(1f);
int[] width2 = {1, 1};
table2.setWidths(width2);//设置系列所占比例
table2.setWidth(100);
table2.setAutoFillEmptyCells(true);
table2.setAlignment(Element.ALIGN_CENTER);//居中显示
table2.setAlignment(Element.ALIGN_MIDDLE);//垂直居中显示

for (int i = 0; i < 12; i++) {
Cell cell = new Cell();
String str;
cell.setVerticalAlignment(Element.ALIGN_LEFT);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
Font font = new Font();
font.setSize(10.5f);
font.setStyle(Font.BOLD);
if (i == 0) {
str = "气象信息";
} else if (i == 1) {
str = reportInfoVO.getAirWeather();
font.setStyle(Font.NORMAL);
} else if (i == 2) {
str = "巡检方式";
} else if (i == 3) {
//巡检方式 1 机场服务,2 人工巡检
str = reportInfoVO.getMission().getInspectionType().equals(1) ? "机场服务" :"人工巡检";
font.setStyle(Font.NORMAL);
} else if (i == 4) {
str = "巡检设备";
} else if (i == 5) {
str = reportInfoVO.getMission().getDroneName();
font.setStyle(Font.NORMAL);
} else if (i == 6) {
str = "巡检开始时间";
} else if (i == 7) {
str = simpleDateFormat.format(reportInfoVO.getMission().getExecutionStartTime());
font.setStyle(Font.NORMAL);
} else if (i == 8) {
str = "巡检结束时间";
}else if (i == 9) {
str = simpleDateFormat.format(reportInfoVO.getMission().getExecutionEndTime());
font.setStyle(Font.NORMAL);
} else if (i == 10) {
str = "问题数量";
} else {
Integer questionCount = reportInfoVO.getQuestionCount();
str = ObjectUtil.isNotEmpty(questionCount)?questionCount.toString():"0";
font.setStyle(Font.NORMAL);
}

Paragraph p = new Paragraph(str, font);
cell.add(p);
table2.addCell(cell);
}
wordUtils.getDocument().add(table2);
log.info("巡检信息写入完成");

List<QuestionTypeCountVO> questionTypeInfo = reportInfoVO.getQuestionTypeInfo();
Map<String, Integer> questionCount=new HashMap<>();
for (QuestionTypeCountVO questionTypeCountVO : questionTypeInfo) {
questionCount.put(questionTypeCountVO.getType(),questionTypeCountVO.getQuantity());
}

if(questionTypeInfo.size()>0) {
wordUtils.insertTitlePatternThird("三:巡检结果", WordUtilsOld.rtfGsBt3);
Table table3 = new Table(2);//生成一表格
table3.setOffset(1f);
int[] width3 = {1, 1};
table3.setWidths(width3);//设置系列所占比例
table3.setWidth(100);
table3.setAutoFillEmptyCells(true);
table3.setAlignment(Element.ALIGN_CENTER);//居中显示
table3.setAlignment(Element.ALIGN_MIDDLE);//垂直居中显示

for (int i = 0; i < 10; i++) {
Cell cell = new Cell();
String str;
cell.setVerticalAlignment(Element.ALIGN_CENTER);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
Font font = new Font();
font.setSize(10.5f);
font.setStyle(Font.BOLD);
if (i == 0) {
str = "巡检内容";
} else if (i == 1) {
str = "巡检检查结果";
} else if (i == 2) {
str = "林场问题图斑";
} else if (i == 3) {
if(questionCount.containsKey("002000")){
str = questionCount.get("002000").toString().trim();
font.setStyle(Font.NORMAL);
}else{
str = "0";
font.setStyle(Font.NORMAL);
}
} else if (i == 4) {
str = "病死树";
} else if (i == 5) {
if(questionCount.containsKey("002001")){
str = questionCount.get("002001").toString().trim();
font.setStyle(Font.NORMAL);
}else{
str = "0";
font.setStyle(Font.NORMAL);
}
} else if (i == 6) {
str = "人员活动";
} else if (i == 7) {
if(questionCount.containsKey("002003")){
str = questionCount.get("002003").toString().trim();
font.setStyle(Font.NORMAL);
}else{
str = "0";
font.setStyle(Font.NORMAL);
}
} else if (i == 8) {
str = "火灾隐患";
} else{
if(questionCount.containsKey("002004")){
str = questionCount.get("002004").toString().trim();
font.setStyle(Font.NORMAL);
}else{
str = "0";
font.setStyle(Font.NORMAL);
}
}
Paragraph p = new Paragraph(str, font);
cell.add(p);
table3.addCell(cell);
}
wordUtils.getDocument().add(table3);
}

log.info("巡检结果写入完成");
if (reportInfoVO.getQuestionReportList().size() > 0) {
wordUtils.insertTitlePatternThird("四:问题清单", WordUtilsOld.rtfGsBt3);
log.info("报告标题四成功");
for (int i = 0; i < reportInfoVO.getQuestionReportList().size(); i++) {
Table table4 = new Table(2);//生成一表格
table4.setOffset(1f);
int[] width4 = {1, 2};
table4.setWidths(width4);//设置系列所占比例
table4.setWidth(100);
table4.setAutoFillEmptyCells(true);
table4.setAlignment(Element.ALIGN_LEFT);//居中显示
table4.setAlignment(Element.ALIGN_MIDDLE);//垂直居中显示
//查询处理数据
List<QuestionHandleVO> questionHandleList = questionHandleMapper.getList(reportInfoVO.getQuestionReportList().get(i).getId());
for (int j = 0; j < 15; j++) {
Cell cell = new Cell();
String str = "";
Font font = new Font();
font.setSize(10.5f);
cell.setVerticalAlignment(Element.ALIGN_CENTER);
if (j == 0) {
font.setSize(12);
str = " 问题" + (i + 1);
cell.add(new Paragraph(str, font));
cell.setColspan(2);
font.setStyle(Font.BOLD);
} else if (j == 1) {
str = " 坐标";
cell.add(new Paragraph(str, font));
} else if (j == 2) {
str = reportInfoVO.getQuestionReportList().get(i).getLng() + "," + reportInfoVO.getQuestionReportList().get(i).getLat();
cell.add(new Paragraph(str, font));
} else if (j == 3) {
str = " 问题描述";
cell.add(new Paragraph(str, font));
} else if (j == 4) {
str = reportInfoVO.getQuestionReportList().get(i).getQuestionDesc();
cell.add(new Paragraph(str, font));
} else if (j == 5) {
str = " 问题图片";
cell.add(new Paragraph(str, font));
} else if (j == 6) {
Image image = null;
String url = reportInfoVO.getQuestionReportList().get(i).getFileMarkerUrl();
if (new UrlResource(url).exists()) {
try {
image = Image.getInstance(Base64.getDecoder().decode(ImgTypeConvert.requestUrlToBase64(url)));
image.setAlignment(Image.ALIGN_CENTER);
image.scalePercent(100); //依照比例缩放
image.setAbsolutePosition(0, 0);
image.scaleToFit(300, 300);//自定义大
cell.add(image);
}catch (Exception e){
log.info("图片获取失败!");
e.printStackTrace();
cell.add(new Paragraph(""));
}
} else {
log.error("图片不存在!" + url);
}
}else if (j == 7) {
str = " 处理人员";
cell.add(new Paragraph(str, font));
}else if (j == 8) {
if(StringUtils.isNotEmpty(questionHandleList)){
str = questionHandleList.get(0).getHandlerUserName();
}
cell.add(new Paragraph(str, font));
}else if (j == 9) {
str = " 处理时间";
cell.add(new Paragraph(str, font));
}else if (j == 10) {
if(StringUtils.isNotEmpty(questionHandleList)){
String handlerTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, questionHandleList.get(0).getHandlerTime());
str = handlerTime;
}
cell.add(new Paragraph(str, font));
}else if (j == 11) {
str = " 处理描述";
cell.add(new Paragraph(str, font));
}else if (j == 12) {
if(StringUtils.isNotEmpty(questionHandleList)){
str = questionHandleList.get(0).getHandlerResult();
}
cell.add(new Paragraph(str, font));
}else if (j == 13) {
str = " 处理图片";
cell.add(new Paragraph(str, font));
}else if (j == 14) {
Image image = null;
String handlerImage = questionHandleList.get(0).getHandlerImage();

//拼接图片域名
String[] imgHanders = new String[0];
if(StringUtils.isNotEmpty(handlerImage)){
imgHanders = handlerImage.split(",");
for (int h = 0; h < imgHanders.length; h++) {
imgHanders[h] = CommonConfig.imageURL + imgHanders[h];
}
}
if (new UrlResource(imgHanders[0]).exists()) {
try {
image = Image.getInstance(Base64.getDecoder().decode(ImgTypeConvert.requestUrlToBase64(imgHanders[0])));
image.setAlignment(Image.ALIGN_CENTER);
image.scalePercent(100); //依照比例缩放
image.setAbsolutePosition(0, 0);
image.scaleToFit(300, 300);//自定义大
cell.add(image);
}catch (Exception e){
log.info("图片获取失败!");
e.printStackTrace();
cell.add(new Paragraph(""));
}
} else {
log.error("图片不存在!" + imgHanders[0]);
}
}
table4.addCell(cell);
}
wordUtils.getDocument().add(table4);
}
}

wordUtils.closeDocument();
log.info("问题清单写入完成");
}catch (Exception e){
log.info("异常信息:{}",e.getMessage());
e.printStackTrace();
}finally {
wordUtils.closeDocument();
}
return UploadFileConfig.docDownLoad+"/lc/doc/"+fileName;
}


/**

+ 1
- 1
tuoheng-admin/src/main/java/com/tuoheng/admin/service/impl/TenantServiceImpl.java Voir le fichier

@@ -87,7 +87,7 @@ public class TenantServiceImpl extends BaseServiceImpl<TenantMapper, Tenant> imp
throw new ServiceException(0, "系统中已经存在相同的账号信息");
}
// 参数转换
Tenant tenant = new Tenant(UpdateOrCreateEnum.CREATE.getCode());
Tenant tenant = new Tenant();
BeanUtils.copyProperties(tenantDto, tenant);
// 租户头像
if (StringUtils.isNotNull(tenantDto.getLogo()) && tenantDto.getLogo().contains(CommonConfig.imageURL)) {

+ 54
- 34
tuoheng-admin/src/main/java/com/tuoheng/admin/service/impl/ThInspectionServiceImpl.java Voir le fichier

@@ -5,32 +5,33 @@ import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tuoheng.admin.entity.domain.Tenant;
import com.tuoheng.admin.entity.domain.ThInspection;
import com.tuoheng.admin.entity.domain.ThMission;
import com.tuoheng.admin.entity.request.InspectionRequest;
import com.tuoheng.admin.entity.request.MissionStatusRequest;
import com.tuoheng.admin.entity.request.PushAndPullURLRequest;
import com.tuoheng.admin.entity.vo.*;
import com.tuoheng.admin.enums.MarkTypeEnum;
import com.tuoheng.admin.enums.TaskStatusEnum;
import com.tuoheng.admin.enums.UpdateOrCreateEnum;
import com.tuoheng.admin.mapper.TenantMapper;
import com.tuoheng.admin.mapper.ThInspectionMapper;
import com.tuoheng.admin.mapper.ThMissionMapper;
import com.tuoheng.admin.service.IMissionService;
import com.tuoheng.admin.service.IThInspectionService;
import com.tuoheng.common.common.BaseServiceImpl;
import com.tuoheng.common.config.CommonConfig;
import com.tuoheng.common.exception.ServiceException;
import com.tuoheng.common.utils.*;
import com.tuoheng.system.entity.User;
import com.tuoheng.system.mapper.UserMapper;
import com.tuoheng.system.utils.ShiroUtils;
import groovy.util.logging.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -52,6 +53,12 @@ public class ThInspectionServiceImpl extends BaseServiceImpl<ThInspectionMapper,
@Autowired
private ThMissionMapper missionMapper;

@Autowired
private TenantMapper tenantMapper;

@Autowired
private UserMapper userMapper;

@Autowired
private RedisUtils redisUtils;

@@ -96,10 +103,12 @@ public class ThInspectionServiceImpl extends BaseServiceImpl<ThInspectionMapper,
}

@Override
public List<AirPortVO> airport() throws ServiceException {
public List<AirPortVO> airport() throws ServiceException, UnsupportedEncodingException {
//这边需要配置到yml文件里面
String url = CommonConfig.airportUrl +"/api/airportInterface/airportList";
String param="page=1&limit=10";
Tenant tenant = tenantMapper.selectById(ShiroUtils.getTenantId());
String url = tenant.getAirportUrl() +"/api/airportInterface/airportList";
String param = "page=1&limit=1000&tenantCode=" + tenant.getCode();
log.info("****** airportList param tenantCode:{}", tenant.getCode());
String airPortStr = HttpUtils.sendGet(url, param);
JsonResult jsonResult = JacksonUtil.json2pojo(airPortStr, JsonResult.class);
if(ObjectUtil.isEmpty(jsonResult) || (!ObjectUtil.isEmpty(jsonResult.getData()) &&jsonResult.getCode() != 0)) {
@@ -110,9 +119,9 @@ public class ThInspectionServiceImpl extends BaseServiceImpl<ThInspectionMapper,

@Override
public List<AirLineVO> airLine(Integer droneId) throws ServiceException {
Tenant tenant = tenantMapper.selectById(ShiroUtils.getTenantId());
//这边需要配置到yml文件里面
String url = CommonConfig.airportUrl +"/api/airportInterface/taskByDroneId";
String url = tenant.getAirportUrl() +"/api/airportInterface/taskByDroneId";
String param="page=1&limit=100&droneId="+droneId;
String airPortStr = HttpUtils.sendGet(url, param);
JsonResult<AirLineVO> jsonResult = JacksonUtil.json2pojo(airPortStr, JsonResult.class);
@@ -123,42 +132,53 @@ public class ThInspectionServiceImpl extends BaseServiceImpl<ThInspectionMapper,
}

@Override
public JsonResult executeTask(String taskId,PushAndPullURLRequest pushAndPull) throws ServiceException{

ThMission thMission = missionMapper.selectById(taskId);
Assert.notNull(thMission,"任务不能为空!");
taskId=thMission.getInspectionLine().toString();
public JsonResult executeTask(String missionId,PushAndPullURLRequest pushAndPull) throws ServiceException{
log.info("executeTask准备就绪");
ThMission thMission = missionMapper.selectById(Integer.parseInt(missionId));
log.info("mission查询完成");
User user = userMapper.selectById(thMission.getCreateUser());
log.info("user查询完成");
Tenant tenant = tenantMapper.selectById(user.getTenantId());
log.info("tenant查询完成");

//这边需要配置到yml文件里面
String url = CommonConfig.airportUrl + "/api/airportInterface/executeTask";
log.info("executeTask准备入参");
String url = tenant.getAirportUrl() + "/api/airportInterface/executeTask";
JSONObject jsonObject = new JSONObject();
jsonObject.put("taskId", taskId);

String airPortStr = HttpUtils.doSend(url, jsonObject, null, "POST");
jsonObject.put("code", "lc");
jsonObject.put("tenantCode", tenant.getCode());
jsonObject.put("taskId", thMission.getInspectionLine());
jsonObject.put("requestId", missionId);
log.info("***** executeTask url:{};param:{}", url, jsonObject.toJSONString());
String airPortStr = null;
try {
airPortStr = HttpUtils.doSend(url, jsonObject, null, "POST");
} catch (Exception e) {
log.error("调用机场executeTask接口异常:",e);
return JsonResult.error("调用机场executeTask接口异常");
}
if(StringUtils.isEmpty(airPortStr)){
return JsonResult.error("机场接口返回数据为空");
}
JsonResult jsonResult = JacksonUtil.json2pojo(airPortStr, JsonResult.class);
if (ObjectUtil.isEmpty(jsonResult) || (!ObjectUtil.isEmpty(Objects.requireNonNull(jsonResult).getData()) && jsonResult.getCode() != 0)) {
assert jsonResult != null;
return JsonResult.error(JSONObject.parseArray(JSONObject.parseObject(JSONObject.toJSONString(jsonResult.getData())).get("data").toString(), AirExecuteTaskVO.class), "执行任务失败!");
} else if (ObjectUtil.isEmpty(jsonResult.getData()) && jsonResult.getCode() != 0) {
if (jsonResult.getCode() != 0) {
return JsonResult.error(jsonResult.getMsg());
} else {
ThMission thMissionUpdate=new ThMission(UpdateOrCreateEnum.UPDATE.getCode());
thMissionUpdate.setId(thMission.getId());
//修改执行时间为当前
thMissionUpdate.setExecutionStartTime(new Date());
missionMapper.updateById(thMissionUpdate);
//返回执行结果
return JsonResult.success(jsonResult.getMsg());
}

//将任务执行状态修改为已执行
ThMission thMissionUpdate = new ThMission(UpdateOrCreateEnum.UPDATE.getCode());
thMissionUpdate.setId(thMission.getId());
thMissionUpdate.setExecutionStatus(2);
missionMapper.updateById(thMissionUpdate);

return JsonResult.success();
}

@Override
public AirWeatherVO getWeather(Integer airportId) throws ServiceException{
Tenant tenant = tenantMapper.selectById(ShiroUtils.getTenantId());
//这边需要配置到yml文件里面
String url = CommonConfig.airportUrl + "/api/airportInterface/getWeather";
String url = tenant.getAirportUrl() + "/api/airportInterface/getWeather";
String param="airportId="+airportId;
String weatherStr = HttpUtils.sendGet(url, param);
JsonResult jsonResult;
@@ -178,12 +198,12 @@ public class ThInspectionServiceImpl extends BaseServiceImpl<ThInspectionMapper,

@Override
public JsonResult lineTrack(Integer missionId) {
Tenant tenant = tenantMapper.selectById(ShiroUtils.getTenantId());
ThMission thMission = missionMapper.selectById(missionId);
Assert.notNull(thMission,"任务不能为空!");
Integer taskId= thMission.getInspectionLine();
//解析标准srt文件里面的坐标,调用硬件接口,返回数据
String url = CommonConfig.airportUrl + "/api/airportInterface/getLocationById";
String url = tenant.getAirportUrl() + "/api/airportInterface/getLocationById";
String param="id="+taskId;
String airportLine = HttpUtils.sendGet(url, param);
JsonResult jsonResult = JacksonUtil.json2pojo(airportLine, JsonResult.class);

+ 251
- 0
tuoheng-admin/src/main/java/com/tuoheng/admin/service/impl/WorkOrderServiceImpl.java Voir le fichier

@@ -0,0 +1,251 @@
package com.tuoheng.admin.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tuoheng.admin.common.ServiceExceptionEnum;
import com.tuoheng.admin.entity.domain.Question;
import com.tuoheng.admin.entity.domain.QuestionHandle;
import com.tuoheng.admin.entity.domain.WorkOrder;
import com.tuoheng.admin.entity.domain.WorkOrderQuestion;
import com.tuoheng.admin.entity.request.WorkOrderHandleRequest;
import com.tuoheng.admin.entity.request.WorkOrderQuestionRequest;
import com.tuoheng.admin.entity.request.WorkOrderRequest;
import com.tuoheng.admin.entity.vo.QuestionDetailVO;
import com.tuoheng.admin.entity.vo.WorkOrderQuestionVO;
import com.tuoheng.admin.enums.MarkTypeEnum;
import com.tuoheng.admin.enums.WorkOrderStatusEnum;
import com.tuoheng.admin.mapper.QuestionHandleMapper;
import com.tuoheng.admin.mapper.QuestionMapper;
import com.tuoheng.admin.mapper.WorkOrderMapper;
import com.tuoheng.admin.mapper.WorkOrderQuestionMapper;
import com.tuoheng.admin.service.IWorkOrderService;
import com.tuoheng.common.common.BaseServiceImpl;
import com.tuoheng.common.config.CommonConfig;
import com.tuoheng.common.exception.ServiceException;
import com.tuoheng.common.utils.DateUtils;
import com.tuoheng.common.utils.JsonResult;
import com.tuoheng.common.utils.StringUtils;
import com.tuoheng.system.entity.User;
import com.tuoheng.system.mapper.UserMapper;
import com.tuoheng.system.utils.ShiroUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkOrder> implements IWorkOrderService {

@Autowired
private WorkOrderMapper workOrderMapper;

@Autowired
private WorkOrderQuestionMapper workOrderQuestionMapper;

@Autowired
private QuestionHandleMapper questionHandleMapper;

@Autowired
private QuestionMapper questionMapper;

@Autowired
private UserMapper userMapper;

@Override
public JsonResult queryPage(WorkOrderRequest request) {
if(null == request.getPage() || null == request.getLimit()){
throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
}

Date startDate = null;
Date endDate = null;
if(StringUtils.isNotEmpty(request.getCreateStartTime()) && StringUtils.isNotEmpty(request.getCreateEndTime())){
String startTime = request.getCreateStartTime() + " 00:00:00";
String endTime = request.getCreateEndTime() + " 23:59:59";
startDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime);
endDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime);
}
// 获取分页数据
IPage<WorkOrder> page = new Page<>(request.getPage(), request.getLimit());
IPage<WorkOrder> pageData = workOrderMapper.selectPage(page, new LambdaQueryWrapper<WorkOrder>()
.like(StringUtils.isNotEmpty(request.getCode()), WorkOrder::getCode, request.getCode())
.eq(ObjectUtil.isNotEmpty(request.getStatus()), WorkOrder::getStatus, request.getStatus())
.between(ObjectUtil.isNotNull(startDate),WorkOrder::getCreateTime, startDate, endDate)
.apply((null != request.getHandleFlag() && 1 == request.getHandleFlag()),"FIND_IN_SET(" + ShiroUtils.getUserId()+",assign_user)")
.eq(WorkOrder::getMark, MarkTypeEnum.VALID.getCode())
.orderByDesc(WorkOrder::getCreateTime));

pageData.getRecords().stream().map(vo -> {

//查询问题总数
Integer questionTotal = workOrderQuestionMapper.selectCount(new LambdaQueryWrapper<WorkOrderQuestion>()
.eq(WorkOrderQuestion::getWorkOrderId, vo.getId()));
vo.setQuestionTotal(questionTotal);

//查询未处理问题数
Integer unhandledTotal = workOrderQuestionMapper.selectCount(new LambdaQueryWrapper<WorkOrderQuestion>()
.eq(WorkOrderQuestion::getWorkOrderId, vo.getId())
.eq(WorkOrderQuestion::getStatus, 0));
vo.setUnhandledTotal(unhandledTotal);

//处理人员名称
if (StringUtils.isNotEmpty(vo.getAssignUser())) {
List<String> assignUser = Arrays.asList(vo.getAssignUser().split(","));
List<Integer> assignUserInteger = assignUser.stream().map(Integer::parseInt).collect(Collectors.toList());
List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().in(User::getId, assignUserInteger));
List<String> assignUserNameList = userList.stream().map(User::getRealname).collect(Collectors.toList());
vo.setAssignUserName(String.join(",", assignUserNameList));
}

return vo;
}).collect(Collectors.toList());
return JsonResult.success(pageData);

}

@Override
@Transactional
public JsonResult generate(Integer[] ids) {
//校验,已生成工单的问题,无法生成工单
Integer count = workOrderQuestionMapper.selectCount(new LambdaQueryWrapper<WorkOrderQuestion>()
.in(WorkOrderQuestion::getQuestionId, ids));
if(count > 0){
return JsonResult.error("有问题已生成工单");
}

String code = DateUtils.generateCode("XJGD");

WorkOrder workOrder = new WorkOrder();
workOrder.setCode(code);
workOrderMapper.insert(workOrder);

for (Integer id : ids) {

WorkOrderQuestion workOrderQuestion = new WorkOrderQuestion();
workOrderQuestion.setWorkOrderId(workOrder.getId());
workOrderQuestion.setQuestionId(id);
workOrderQuestionMapper.insert(workOrderQuestion);
}
return JsonResult.success();
}

@Override
public JsonResult assign(WorkOrderRequest request) {
WorkOrder workOrder = new WorkOrder();
workOrder.setId(request.getId());
workOrder.setStatus(WorkOrderStatusEnum.ALLOCATED.getCode());
workOrder.setAssignUser(StringUtils.join(request.getHandleUserList(), ","));
workOrder.setAssignTime(new Date());
workOrderMapper.updateById(workOrder);
return JsonResult.success();
}

@Override
@Transactional
public JsonResult handle(WorkOrderHandleRequest request) {
//校验,已处理的问题,无法再处理
Integer handleCount = workOrderQuestionMapper.selectCount(new LambdaQueryWrapper<WorkOrderQuestion>()
.eq(WorkOrderQuestion::getQuestionId, request.getQuestionId())
.eq(WorkOrderQuestion::getStatus, 1)
.eq(WorkOrderQuestion::getMark, MarkTypeEnum.VALID.getCode()));
if(handleCount > 0){
return JsonResult.error("问题已经处理,无法再处理");
}

//将工单子表状态修改为已处理
WorkOrderQuestion workOrderQuestion = new WorkOrderQuestion();
BeanUtils.copyProperties(request, workOrderQuestion);
workOrderQuestion.setStatus(1);
workOrderQuestionMapper.update(workOrderQuestion, new LambdaQueryWrapper<WorkOrderQuestion>()
.eq(WorkOrderQuestion::getWorkOrderId, request.getWorkOrderId())
.eq(WorkOrderQuestion::getQuestionId, request.getQuestionId()));

//问题处理结果表新增
QuestionHandle questionHandle = new QuestionHandle();
BeanUtils.copyProperties(request, questionHandle);
questionHandle.setHandlerUser(ShiroUtils.getUserId());
questionHandle.setHandlerTime(new Date());
questionHandleMapper.insert(questionHandle);

//查询工单下待处理的问题,如全部处理完,将工单状态修改为已完成
Integer count = workOrderQuestionMapper.selectCount(new LambdaQueryWrapper<WorkOrderQuestion>()
.eq(WorkOrderQuestion::getWorkOrderId, request.getWorkOrderId())
.eq(WorkOrderQuestion::getStatus, 0));
if(count == 0){
WorkOrder workOrder = new WorkOrder();
workOrder.setId(request.getWorkOrderId());
workOrder.setStatus(WorkOrderStatusEnum.COMPLETED.getCode());
workOrder.setFinishTime(new Date());
workOrderMapper.updateById(workOrder);
}
return JsonResult.success();
}

@Override
public JsonResult questionPage(WorkOrderQuestionRequest request) {

// 设置分页参数
IPage<WorkOrderQuestionVO> page = new Page<>(request.getPage(), request.getLimit());
// 查询结果
IPage<WorkOrderQuestionVO> pageInfo = workOrderMapper.questionPage(page, request);
for (WorkOrderQuestionVO record : pageInfo.getRecords()) {
if(StringUtils.isNotEmpty(record.getHandlerImage())){
String[] imgHanders = record.getHandlerImage().split(",");
for (int i = 0; i < imgHanders.length; i++) {
imgHanders[i] = CommonConfig.imageURL + imgHanders[i];
}
String handerImg = StringUtils.join(imgHanders, ",");
record.setHandlerImage(handerImg);
}
}
return JsonResult.success(pageInfo);
}

@Override
public JsonResult questionDetail(Integer questionId) {
QuestionDetailVO questionDetailVO = new QuestionDetailVO();
//查询问题详情
Question question = questionMapper.selectById(questionId);
questionDetailVO.setQuestion(question);

//查询问题处理详情
QuestionHandle questionHandle = questionHandleMapper.selectOne(new LambdaQueryWrapper<QuestionHandle>()
.eq(QuestionHandle::getQuestionId, questionId)
.eq(QuestionHandle::getMark, MarkTypeEnum.VALID.getCode()));
//拼接图片域名
if(null != questionHandle && StringUtils.isNotEmpty(questionHandle.getHandlerImage())){
String[] imgHanders = questionHandle.getHandlerImage().split(",");
for (int i = 0; i < imgHanders.length; i++) {
imgHanders[i] = CommonConfig.imageURL + imgHanders[i];
}
String handerImg = StringUtils.join(imgHanders, ",");
questionHandle.setHandlerImage(handerImg);
}

//查询处理人名称
User user = userMapper.selectById(questionHandle.getHandlerUser());
if(ObjectUtil.isNotNull(user)){
questionHandle.setHandlerUserName(user.getRealname());
}

//查询问题处理状态
WorkOrderQuestion workOrderQuestion = workOrderQuestionMapper.selectOne(new LambdaQueryWrapper<WorkOrderQuestion>()
.eq(WorkOrderQuestion::getQuestionId, questionId));
questionDetailVO.setQuestionHandle(questionHandle);
questionHandle.setStatus(workOrderQuestion.getStatus());

questionDetailVO.setQuestionHandle(questionHandle);
return JsonResult.success(questionDetailVO);
}


}

+ 9
- 11
tuoheng-admin/src/main/java/com/tuoheng/admin/task/ScheduledTask.java Voir le fichier

@@ -1,19 +1,17 @@
package com.tuoheng.admin.task;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tuoheng.admin.entity.domain.ThMission;
import com.tuoheng.admin.enums.MarkTypeEnum;
import com.tuoheng.admin.enums.TaskStatusEnum;
import com.tuoheng.admin.enums.UpdateOrCreateEnum;
import com.tuoheng.admin.mapper.ThMissionMapper;
import com.tuoheng.admin.service.IMissionService;
import com.tuoheng.admin.service.IThInspectionService;
import com.tuoheng.common.utils.JsonResult;
import com.tuoheng.common.utils.StringUtils;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
@@ -35,7 +33,8 @@ public class ScheduledTask {
private final static SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


@Scheduled(fixedRate = 1000)
// @Scheduled(fixedRate = 1000)
@XxlJob("lcAirportTaskHandler")
public void scheduledTask() {

log.info("执行定时执行飞行任务:" + LocalDateTime.now());
@@ -54,15 +53,14 @@ public class ScheduledTask {
log.info("执行定时执行飞行任务:" + thMission.getId());
JsonResult jsonResult = inspectionService.executeTask(String.valueOf(thMission.getId()), null);
log.info("执行定时执行飞行任务result:" + jsonResult);
thMission.setExecutionStatus(2);

ThMission thMissionUpdate = new ThMission(UpdateOrCreateEnum.UPDATE.getCode());
thMissionUpdate.setId(thMission.getId());
thMissionUpdate.setExecutionStatus(2);
if(jsonResult.getCode()!=0 && ObjectUtil.isEmpty(jsonResult.getData())){
thMission.setStatus(TaskStatusEnum.FAIL.getCode());
if(jsonResult.getCode() != 0){
ThMission thMissionUpdate = new ThMission(UpdateOrCreateEnum.UPDATE.getCode());
thMissionUpdate.setId(thMission.getId());
log.error("执行定时执行机场起飞失败" + thMission.getId());
thMissionUpdate.setStatus(TaskStatusEnum.FAIL.getCode());
missionMapper.updateById(thMissionUpdate);
}
missionMapper.updateById(thMissionUpdate);
}
}


+ 0
- 220
tuoheng-admin/src/main/resources/application-airport.yml Voir le fichier

@@ -1,220 +0,0 @@
# 端口配置
server:
port: 9099
servlet:
# 项目的前缀名
context-path: /api
tomcat:
basedir: /data/java/tuoheng_lc/uploads/doc
# 自定义配置
tuoheng:
# 图片域名
image-url: https://image.t-aaron.com/
# OSS域名
oss-url: https://ta-tech-image.oss-cn-shanghai.aliyuncs.com
# 机场域名
airport-url: https://airport.t-aaron.com/
# 视频域名
video-url: https://vod.play.t-aaron.com/
# 高德Key
gaodeKey: 8eb26a06684d34501e5a56dcc2f5af15
# 通道地址
live-channel-domain-url: https://streaming.t-aaron.com/
# DSP服务域名
#dsp-domain-url: http://192.168.11.241:1011/
dsp-domain-url: https://dsp-portal.t-aaron.com/
# DSP回调地址
dsp-callback-url: https://lcxj.t-aaron.com/api/question/{requestId}/callback
#阿里云
aliyuncsVod:
accessKeyId: LTAI5tE7KWN9fsuGU7DyfYF4
accessKeySecret: yPPCyfsqWgrTuoz5H4sisY0COclx8E
roleArn: acs:ram::1399733914954856:role/ramosstest
bucketName: ta-tech-image

spring:
# 配置数据源
datasource:
# 使用阿里的Druid连接池
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
# 填写你数据库的url、登录名、密码和数据库名
url: jdbc:mysql://localhost:3306/tuoheng_lc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8&useSSL=true&tinyInt1isBit=false
username: root
password: TH144#2022
druid:
# 连接池的配置信息
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 5
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,log4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
# 配置DruidStatFilter
webStatFilter:
enabled: true
url-pattern: "/*"
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
# 配置DruidStatViewServlet
statViewServlet:
url-pattern: "/druid/*"
# IP白名单(没有配置或者为空,则允许所有访问)
allow: 127.0.0.1,192.168.163.1
# IP黑名单 (存在共同时,deny优先于allow)
deny: 192.168.1.73
# 禁用HTML页面上的“Reset All”功能
reset-enable: false
# 登录名
login-username: admin
# 登录密码
login-password: 123456

# Redis数据源
redis:
# 缓存库默认索引0
database: 0
# Redis服务器地址
host: 127.0.0.1
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码(默认为空)
password:
# 连接超时时间(毫秒)
timeout: 6000
# 默认的数据过期时间,主要用于shiro权限管理
expire: 2592000
jedis:
pool:
max-active: 1000 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 1 # 连接池中的最小空闲连接

servlet:
multipart:
# 过滤springmvc的文件上传
enabled: false
# 单个文件最大值
max-file-size: 50MB
# 上传文件总的最大值
max-request-size: 100MB

#邮件配置
mail:
# 设置邮箱主机
host: smtp.qq.com
# 开启邮箱POP3/SMTP服务,获取客户端授权码(注意并不是邮箱密码,而是授权码)
password:
# 邮箱的用户名
username:
properties:
mail:
smtp:
# 设置是否需要认证,如果为true,那么用户名和密码就必须的。如果设置false,可以不设置用户名和密码,当然也得看你的对接的平台是否支持无密码进行访问的。
auth: true
starttls:
# STARTTLS[1] 是对纯文本通信协议的扩展。它提供一种方式将纯文本连接升级为加密连接(TLS或SSL),而不是另外使用一个端口作加密通信。
enable: true
require: true

alisms:
accessKeyId:
accessKeySecret:
regionId: cn-hangzhou
signName: 拓恒
templateCode:
kafka:
common:
enable: false
bootstrap-servers: 101.132.127.1:19092
alg-online-results-topic: alg-task-results
alg-online-results-group-id: alg-task-group-prod
alg-offline-tasks-topic: alg-offline-tasks
alg-online-tasks-topic: alg-online-tasks
file:
#上传的服务器上的映射文件夹
accessPath: /uploads/
#静态资源对外暴露的访问路径
staticAccessPath: /**
#静态资源实际存储路径
uploadFolder: /data/java/tuoheng_lc/tuoheng_lc_web/dist/lc/
docDownLoad: http://139.196.193.144:8088

# Shiro
shiro:
cipher-key: f/SX5TIve5WWzT4aQlABJA==
cookie-name: shiro-cookie2
user:
# 登录地址
loginUrl: /login
# 权限认证失败地址
unauthorizedUrl: /unauth
# 首页地址
indexUrl: /index
# 验证码开关
captchaEnabled: true
# 验证码类型 math 数组计算 char 字符
captchaType: math
cookie:
# 设置Cookie的域名 默认空,即当前访问的域名
domain:
# 设置cookie的有效访问路径
path: /
# 设置HttpOnly属性
httpOnly: true
# 设置Cookie的过期时间,天为单位
maxAge: 30
session:
# Session超时时间(默认30分钟)
expireTime: 300
# 同步session到数据库的周期(默认1分钟)
dbSyncPeriod: 1
# 相隔多久检查一次session的有效性,默认就是10分钟
validationInterval: 10

# 代码生成
generate:
# 作者
author: 拓恒
# 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool
packageName: com.tuoheng.system
# 模块名
moduleName: tuoheng-system
# 自动去除表前缀,默认是true
autoRemovePre: true
# 表前缀(生成类名不会包含表前缀,多个用逗号分隔)
tablePrefix: sys_
xxl:
enable: false
job:
admin:
addresses: http://172.16.1.31:8110/xxl-job-admin
accessToken: tuoheng
executor:
appname: xxl-job-executor-lc
address:
ip:
# 多个后台,端口号不能相同
port: 9999
logpath: /data/java/logs/xxl-job/jobhandler
logretentiondays: 15

+ 4
- 12
tuoheng-admin/src/main/resources/application-dev.yml Voir le fichier

@@ -13,7 +13,7 @@ tuoheng:
# OSS域名
oss-url: https://ta-tech-image.oss-cn-shanghai.aliyuncs.com
# 机场域名
airport-url: https://airport.t-aaron.com/
airport-url: http://192.168.11.22:9060/
# 视频域名
video-url: https://vod.play.t-aaron.com/
# 高德Key
@@ -142,14 +142,6 @@ spring:
regionId: cn-hangzhou
signName: 拓恒
templateCode:
kafka:
common:
enable: false
bootstrap-servers: 192.168.11.13:9092
alg-online-results-topic: alg-task-results
alg-online-results-group-id: alg-task-group-dev
alg-offline-tasks-topic: alg-offline-tasks
alg-online-tasks-topic: alg-online-tasks
file:
#上传的服务器上的映射文件夹
accessPath: /uploads/
@@ -157,7 +149,7 @@ file:
staticAccessPath: /**
#静态资源实际存储路径
uploadFolder: /data/java/tuoheng_lc/tuoheng_lc_web/dist/lc/
docDownLoad: http://192.168.11.11:8088
docDownLoad: http://192.168.11.22:8088

# Shiro
shiro:
@@ -210,7 +202,7 @@ logging:
config: classpath:logback.xml

xxl:
enable: false
enable: true
job:
admin:
addresses: http://192.168.11.11:8110/xxl-job-admin
@@ -220,6 +212,6 @@ xxl:
address:
ip:
# 多个后台,端口号不能相同
port: 9999
port: 9998
logpath: /data/java/logs/xxl-job/jobhandler
logretentiondays: 15

+ 3
- 11
tuoheng-admin/src/main/resources/application-local.yml Voir le fichier

@@ -13,7 +13,7 @@ tuoheng:
# OSS域名
oss-url: https://ta-tech-image.oss-cn-shanghai.aliyuncs.com
# 机场域名
airport-url: https://airport.t-aaron.com/
airport-url: http://192.168.11.22:9060/
# 视频域名
video-url: http://vod.play.t-aaron.com/
# 高德Key
@@ -142,14 +142,6 @@ spring:
regionId: cn-hangzhou
signName: 拓恒
templateCode:
kafka:
common:
enable: false
bootstrap-servers: 192.168.11.13:9092
alg-online-results-topic: alg-task-results
alg-online-results-group-id: alg-task-group-local
alg-offline-tasks-topic: alg-offline-tasks
alg-online-tasks-topic: alg-online-tasks
file:
#上传的服务器上的映射文件夹
accessPath: /uploads/
@@ -204,7 +196,7 @@ generate:
# 表前缀(生成类名不会包含表前缀,多个用逗号分隔)
tablePrefix: sys_
xxl:
enable: false
enable: true
job:
admin:
addresses: http://192.168.11.11:8110/xxl-job-admin
@@ -214,6 +206,6 @@ xxl:
address:
ip:
# 多个后台,端口号不能相同
port: 9999
port: 9998
logpath: /data/java/logs/xxl-job/jobhandler
logretentiondays: 15

+ 2
- 3
tuoheng-admin/src/main/resources/application-prod.yml Voir le fichier

@@ -143,7 +143,6 @@ spring:
regionId: cn-hangzhou
signName: 拓恒
templateCode:

file:
#上传的服务器上的映射文件夹
accessPath: /uploads/
@@ -198,7 +197,7 @@ generate:
# 表前缀(生成类名不会包含表前缀,多个用逗号分隔)
tablePrefix: sys_
xxl:
enable: false
enable: true
job:
admin:
addresses: https://xxl-job.t-aaron.com/xxl-job-admin/
@@ -208,6 +207,6 @@ xxl:
address:
ip:
# 多个后台,端口号不能相同
port: 9999
port: 9998
logpath: /data/java/logs/xxl-job/jobhandler
logretentiondays: 15

+ 10
- 19
tuoheng-admin/src/main/resources/application-test.yml Voir le fichier

@@ -13,7 +13,7 @@ tuoheng:
# OSS域名
oss-url: https://ta-tech-image.oss-cn-shanghai.aliyuncs.com
# 机场域名
airport-url: https://airport.t-aaron.com/
airport-url: https://airport-test.t-aaron.com/
# 视频域名
video-url: https://vod.play.t-aaron.com/
# 高德Key
@@ -21,10 +21,9 @@ tuoheng:
# 通道地址
live-channel-domain-url: https://streaming.t-aaron.com/
# DSP服务域名
#dsp-domain-url: http://192.168.11.241:1011/
dsp-domain-url: http://139.196.193.144:47821/
dsp-domain-url: http://172.15.1.11:7011/
# DSP回调地址
dsp-callback-url: http://139.196.193.144:9099/api/question/{requestId}/callback
dsp-callback-url: http://106.15.120.154:9099/api/question/{requestId}/callback
#阿里云
aliyuncsVod:
accessKeyId: LTAI5tE7KWN9fsuGU7DyfYF4
@@ -39,9 +38,9 @@ spring:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
# 填写你数据库的url、登录名、密码和数据库名
url: jdbc:mysql://192.168.11.242:3306/tuoheng_lc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8&useSSL=true&tinyInt1isBit=false
url: jdbc:mysql://rm-uf6z740323e8053pj.mysql.rds.aliyuncs.com:3306/tuoheng_lc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8&useSSL=true&tinyInt1isBit=false
username: root
password: idontcare
password: TH22#2022
druid:
# 连接池的配置信息
# 初始连接数
@@ -94,7 +93,7 @@ spring:
# 缓存库默认索引0
database: 0
# Redis服务器地址
host: 192.168.11.242
host: r-uf6cdzjifj20jszykr.redis.rds.aliyuncs.com
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码(默认为空)
@@ -142,14 +141,6 @@ spring:
regionId: cn-hangzhou
signName: 拓恒
templateCode:
kafka:
common:
enable: false
bootstrap-servers: 192.168.11.242:9092
alg-online-results-topic: alg-task-results
alg-online-results-group-id: hhz-test
alg-offline-tasks-topic: alg-offline-tasks
alg-online-tasks-topic: alg-online-tasks
file:
#上传的服务器上的映射文件夹
accessPath: /uploads/
@@ -157,7 +148,7 @@ file:
staticAccessPath: /**
#静态资源实际存储路径
uploadFolder: /data/java/tuoheng_lc/tuoheng_lc_web/dist/lc/
docDownLoad: http://192.168.11.241:8088
docDownLoad: https://lcxj-test.t-aaron.com

# Shiro
shiro:
@@ -204,16 +195,16 @@ generate:
# 表前缀(生成类名不会包含表前缀,多个用逗号分隔)
tablePrefix: sys_
xxl:
enable: false
enable: true
job:
admin:
addresses: http://192.168.11.241:8110/xxl-job-admin
addresses: http://172.15.1.11:8110/xxl-job-admin
accessToken: tuoheng
executor:
appname: xxl-job-executor-lc
address:
ip:
# 多个后台,端口号不能相同
port: 9999
port: 9998
logpath: /data/java/logs/xxl-job/jobhandler
logretentiondays: 15

+ 17
- 0
tuoheng-admin/src/main/resources/mapper/QuestionHandleMapper.xml Voir le fichier

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tuoheng.admin.mapper.QuestionHandleMapper">

<select id="getList" resultType="com.tuoheng.admin.entity.vo.QuestionHandleVO">
SELECT
qh.handler_user AS handlerUser,
qh.handler_image AS handlerImage,
qh.handler_result AS handlerResult,
qh.handler_time AS handlerTime,
u.realname AS handlerUserName
FROM th_question_handle qh
LEFT JOIN sys_user u ON qh.handler_user = u.id
WHERE qh.question_id = #{questionId}
</select>

</mapper>

+ 17
- 0
tuoheng-admin/src/main/resources/mapper/QuestionMapper.xml Voir le fichier

@@ -7,10 +7,27 @@
where q.mission_id=#{missionId}
group by q.status;
</select>

<select id="analyzeType" resultType="com.tuoheng.admin.entity.vo.QuestionTypeCountVO">
select q.type,count(q.id) as quantity
from th_question q
where q.mission_id=#{missionId} and q.status=1
group by q.type;
</select>

<select id="getIndexQuestion" parameterType="com.tuoheng.admin.entity.request.index.GetQuestionListDto" resultType="com.tuoheng.admin.entity.dto.index.QuestionListDto">
select a.create_time,a.id as questionId, a.mission_id as missionId, a.type, b.content as typeName,
a.mission_name as missionName, c.execution_start_time as inspectionTime,
a.file_marker_url as fileMarkerUrl, d.handler_result as handlerResult,
d.handler_image as handlerImage, d.handler_user as handlerUserId, e.realname as handlerUserName,
d.handler_time as handlerTime, a.lng, a.lat
from th_question a
inner join th_question_type b on b.code = a.type and b.mark = 1
inner join th_mission c on c.id = a.mission_id and c.mark = 1
left join th_question_handle d on d.question_id = a.id
left join sys_user e on e.id = d.handler_user
where a.mark = 1 and a.status = 1 and a.create_time BETWEEN #{startTime} AND #{endTime}
order by a.create_time desc limit 200
</select>

</mapper>

+ 38
- 0
tuoheng-admin/src/main/resources/mapper/WorkOrderMapper.xml Voir le fichier

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tuoheng.admin.mapper.WorkOrderMapper">

<select id="questionPage" resultType="com.tuoheng.admin.entity.vo.WorkOrderQuestionVO">
SELECT
q.type,
q.id AS questionId,
q.question_name AS questionName,
q.question_desc AS questionDesc,
q.file_original_url AS fileOriginalUrl,
q.file_marker_url AS fileMarkerUrl,
q.lng AS lng,
q.lat AS lat,
woq.`status` AS status,
q.create_time AS createTime,
qh.handler_user AS handlerUser,
qh.handler_image AS handlerImage,
qh.handler_result AS handlerResult,
qh.handler_time AS handlerTime,
u.realname AS handlerUserName
FROM th_work_order wo
LEFT JOIN th_work_order_question woq on wo.id = woq.work_order_id
LEFT JOIN th_question q on woq.question_id = q.id
LEFT JOIN th_question_handle qh on q.id = qh.question_id
LEFT JOIN sys_user u on qh.handler_user = u.id
WHERE
wo.mark = 1
AND wo.id = #{request.workOrderId}
<if test="request.questionType != '' and request.questionType != null">
AND q.type = #{request.questionType}
</if>
<if test="request.status != null">
AND woq.`status` = #{request.status}
</if>
</select>

</mapper>

+ 0
- 16
tuoheng-common/src/main/java/com/tuoheng/common/config/CommonConfig.java Voir le fichier

@@ -28,11 +28,6 @@ public class CommonConfig {
*/
public static String gaodeKey;

/**
* 机场域名
*/
public static String airportUrl;

/**
* 图片域名赋值
*
@@ -73,15 +68,4 @@ public class CommonConfig {
gaodeKey = key;
}

/**
* 机场域名赋值
*
* @param url 域名地址
*/
@Value("${tuoheng.airport-url}")
public void setAirportURL(String url) {
airportUrl = url;
}


}

+ 1
- 1
tuoheng-common/src/main/java/com/tuoheng/common/utils/HttpUtils.java Voir le fichier

@@ -83,7 +83,7 @@ public class HttpUtils {
connection.setDoOutput(true); // 设置该连接是可以输出的
//设置连接超时时间和读取超时时间
connection.setConnectTimeout(15000);
connection.setReadTimeout(60000 * 2);
connection.setReadTimeout(60000 * 5);
//设置请求方式
connection.setRequestMethod(method);
connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");

Chargement…
Annuler
Enregistrer