Browse Source

fix: 优化大屏

master
wxc 1 month ago
parent
commit
fdee6a2175
  1. 71
      src/main/java/com/biutag/supervision/controller/datav/DataVCaseVerifController.java
  2. 4
      src/main/java/com/biutag/supervision/controller/datav/DataVSupervisionNotifyController.java
  3. 44
      src/main/java/com/biutag/supervision/controller/datav/DataVVideoSuperviseController.java
  4. 116
      src/main/java/com/biutag/supervision/mapper/NegativeMapper.java
  5. 7
      src/main/java/com/biutag/supervision/pojo/vo/CaseVerificationCountVo.java
  6. 10
      src/main/java/com/biutag/supervision/pojo/vo/VideoSuperviseCountVo.java
  7. 20
      src/test/java/com/biutag/supervision/StrUtil.java

71
src/main/java/com/biutag/supervision/controller/datav/DataVCaseVerifController.java

@ -4,15 +4,19 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.biutag.supervision.constants.enums.BlameType;
import com.biutag.supervision.constants.enums.InspectCaseEnum;
import com.biutag.supervision.constants.enums.ProcessingStatusEnum;
import com.biutag.supervision.mapper.DataCaseVerifMapper;
import com.biutag.supervision.mapper.NegativeMapper;
import com.biutag.supervision.pojo.Result;
import com.biutag.supervision.pojo.entity.DataCaseVerif;
import com.biutag.supervision.pojo.entity.Negative;
import com.biutag.supervision.pojo.vo.CaseVerificationCountVo;
import com.biutag.supervision.pojo.vo.CaseVerificationMapVo;
import com.biutag.supervision.pojo.vo.EchartsVo;
import com.biutag.supervision.pojo.vo.OrganizeProblemRankVo;
import com.biutag.supervision.pojo.entity.NegativeBlame;
import com.biutag.supervision.pojo.entity.SupPolice;
import com.biutag.supervision.pojo.vo.*;
import com.biutag.supervision.service.NegativeBlameService;
import com.biutag.supervision.service.SupPoliceService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
@ -26,6 +30,8 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.biutag.supervision.constants.enums.ProblemSourcesEnum.*;
@ -42,6 +48,9 @@ public class DataVCaseVerifController {
private final DataCaseVerifMapper dataCaseVerifMapper;
private final NegativeMapper negativeMapper;
private final NegativeBlameService blameService;
private final SupPoliceService policeService;
// region 左边
@ -126,21 +135,52 @@ public class DataVCaseVerifController {
* @param endTime 结束时间
* @return Result<JSONObject>
*/
@Operation(summary = "中央数据总览")
@Operation(summary = "案件核查数据总览")
@GetMapping("/getCaseVerificationCount")
public Result<JSONObject> getAllCaseVerificationCount(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") Date beginTime,
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") Date endTime) {
endTime = DateUtil.endOfDay(endTime);
// "IFNULL( ROUND( COUNT( DISTINCT IF(ng.checkStatus IN (1, 2), ng.id, NULL) ) / count(DISTINCT ng.id)*100, 1 ), 0 ) AS rate "
CaseVerificationCountVo overview = negativeMapper.getAllCaseVerificationCount(beginTime, endTime);
List<String> list = Arrays.asList( A12389.getValue(),SLDJB.getValue(), ZDDJB.getValue(), SJJB.getValue());
long confirmed = negativeMapper.selectCount(new LambdaQueryWrapper<Negative>().in(Negative::getProblemSourcesCode,list).between(Negative::getCrtTime,beginTime,endTime));
long total = dataCaseVerifMapper.selectCount(new LambdaQueryWrapper<DataCaseVerif>().between(DataCaseVerif::getCreateTime,beginTime,endTime));
overview.setTotal((int) total);
overview.setConfirmed((int) confirmed);
// overview.setRate((double) ((overview.getConfirmed() / total * 100) ));
overview.setRate(NumberUtil.div((Number) (overview.getConfirmed() * 100),total ).doubleValue());
// CaseVerificationCountVo overview = negativeMapper.getAllCaseVerificationCount(beginTime, endTime);
// List<String> list = Arrays.asList( A12389.getValue(),SLDJB.getValue(), ZDDJB.getValue(), SJJB.getValue());
// overview.setConfirmed((int) confirmed);
//// overview.setRate((double) ((overview.getConfirmed() / total * 100) ));
// overview.setRate(NumberUtil.div((Number) (overview.getConfirmed() * 100),total ).doubleValue());
CaseVerificationCountVo overview = new CaseVerificationCountVo();
List<DataCaseVerif> dataCaseVerifs = dataCaseVerifMapper.selectList(new LambdaQueryWrapper<DataCaseVerif>().between(DataCaseVerif::getCreateTime, beginTime, endTime));
overview.setTotal(dataCaseVerifs.size());
List<Negative> negatives = negativeMapper.selectList(new LambdaQueryWrapper<Negative>()
.between(Negative::getCrtTime, beginTime, endTime)
.in(Negative::getProblemSourcesCode, List.of(A12389.getValue(), SLDJB.getValue(), ZDDJB.getValue(), SJJB.getValue())));
overview.setConfirmed(negatives.size());
List<String> trueValue = List.of(InspectCaseEnum.TRUE.getValue(), InspectCaseEnum.PARTIALLY_TRUE.getValue());
overview.setDealCasePro(negatives.stream().filter(item -> Objects.nonNull(item.getCheckStatus()) && trueValue.contains(item.getCheckStatus())).count());
double rate = overview.getTotal() == 0 ? 0 : NumberUtil.round((double) overview.getConfirmed() / overview.getTotal() * 100, 0).doubleValue();
overview.setRate(rate);
if (negatives.isEmpty()) {
overview.setPunishOrg(0L);
overview.setPunishPre(0L);
} else {
List<NegativeBlame> blames = blameService.list(new LambdaQueryWrapper<NegativeBlame>()
.in(NegativeBlame::getNegativeId, negatives.stream().map(Negative::getId).toList())
.isNotNull(NegativeBlame::getHandleResultCode)
.ne(NegativeBlame::getHandleResultCode, "")
.ne(NegativeBlame::getHandleResultName, "不予追责"));
List<NegativeBlame> departBlames = blames.stream().filter(item -> BlameType.department.name().equals(item.getType())).toList();
log.info("问责单位 数量:{}", departBlames.size());
if (departBlames.isEmpty()) {
overview.setPunishOrg(0L);
} else {
log.info("问责单位 领导警号集合:{}", departBlames.stream().map(NegativeBlame::getBlameEmpNo).collect(Collectors.toSet()));
long count = policeService.count(new LambdaQueryWrapper<SupPolice>().in(SupPolice::getEmpNo, departBlames.stream().map(NegativeBlame::getBlameEmpNo).collect(Collectors.toSet())));
overview.setPunishOrg(count);
}
overview.setPunishPre(blames.stream().filter(item -> BlameType.personal.name().equals(item.getType())).count());
}
JSONObject res = new JSONObject().fluentPut("overview", overview);
return Result.success(res);
}
@ -153,7 +193,7 @@ public class DataVCaseVerifController {
* @param endTime 结束时间
* @return Result<JSONObject>
*/
@Operation(summary = "地图Icon数据")
@Operation(summary = "案件核查大屏地图")
@GetMapping("/getCaseVerificationMap")
// @Cacheable(cacheNames = "Supervision:Screen:CaseVerificationMap", key = "#beginTime.getTime()+'_'+#endTime.getTime()")
public Result<JSONObject> getCaseVerificationMap(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") Date beginTime,
@ -161,7 +201,6 @@ public class DataVCaseVerifController {
Date finalEndTime = DateUtil.endOfDay(endTime);
List<CaseVerificationMapVo> caseVerificationMapList = negativeMapper.getCaseVerificationMap(beginTime, finalEndTime);
log.info("-------caseVerificationMapList-------");
log.info(caseVerificationMapList.toString());
JSONObject res = new JSONObject().fluentPut("caseVerificationMapList", caseVerificationMapList);
return Result.success(res);
}

4
src/main/java/com/biutag/supervision/controller/datav/DataVSupervisionNotifyController.java

@ -202,8 +202,8 @@ public class DataVSupervisionNotifyController {
String relationOrg =negativeMapper.getSupervisionMapStringData(beginTime, finalEndTime,"department",s.getDepartId()) ;
String personNum =negativeMapper.getSupervisionMapStringData(beginTime, finalEndTime,"personal",s.getDepartId()) ;;
// String completedRate = negativeMapper.getSupervisionMapCompletedRate(beginTime, finalEndTime,s.getDepartId());
double rate = s.getTotalPro() == 0 ? 0: NumberUtil.round((double) s.getCompletedNumber() / s.getTotalPro() * 100, 2).doubleValue();
s.setCompletedRate(String.valueOf(rate));
// double rate = s.getTotalPro() == 0 ? 0: NumberUtil.round((double) s.getCompletedNumber() / s.getTotalPro() * 100, 2).doubleValue();
// s.setCompletedRate(String.valueOf(rate));
s.setPersonNum(personNum);
s.setRelationOrg(relationOrg);
});

44
src/main/java/com/biutag/supervision/controller/datav/DataVVideoSuperviseController.java

@ -2,14 +2,24 @@ package com.biutag.supervision.controller.datav;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.biutag.supervision.constants.enums.BlameType;
import com.biutag.supervision.constants.enums.InspectCaseEnum;
import com.biutag.supervision.constants.enums.ProblemSourcesEnum;
import com.biutag.supervision.constants.enums.ProcessingStatusEnum;
import com.biutag.supervision.mapper.NegativeMapper;
import com.biutag.supervision.mapper.WvpDeviceChannelMapper;
import com.biutag.supervision.pojo.Result;
import com.biutag.supervision.pojo.entity.Negative;
import com.biutag.supervision.pojo.entity.NegativeBlame;
import com.biutag.supervision.pojo.entity.SupPolice;
import com.biutag.supervision.pojo.entity.WvpDeviceChannel;
import com.biutag.supervision.pojo.vo.EchartsVo;
import com.biutag.supervision.pojo.vo.OrganizeProblemRankVo;
import com.biutag.supervision.pojo.vo.VideoSuperviseCountVo;
import com.biutag.supervision.pojo.vo.VideoSuperviseMapIconVo;
import com.biutag.supervision.service.NegativeBlameService;
import com.biutag.supervision.service.SupPoliceService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
@ -20,6 +30,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
import java.util.stream.Collectors;
import static com.biutag.supervision.constants.enums.ProblemSourcesEnum.SPDC;
@ -35,8 +46,11 @@ import static com.biutag.supervision.constants.enums.ProblemSourcesEnum.SPDC;
public class DataVVideoSuperviseController {
private final NegativeMapper negativeMapper;
private final NegativeBlameService blameService;
private final WvpDeviceChannelMapper wvpDeviceChannelMapper;
private final SupPoliceService policeService;
//region 左边
@ -103,7 +117,33 @@ public class DataVVideoSuperviseController {
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") Date endTime) {
endTime = DateUtil.endOfDay(endTime);
// 获取视频督察中央数据
VideoSuperviseCountVo overview = negativeMapper.getAllVideoSuperviseCount(beginTime, endTime);
// VideoSuperviseCountVo overview = negativeMapper.getAllVideoSuperviseCount(beginTime, endTime);
VideoSuperviseCountVo overview = new VideoSuperviseCountVo();
List<Negative> negatives = negativeMapper.selectList(new LambdaQueryWrapper<Negative>().between(Negative::getCrtTime, beginTime, endTime)
.eq(Negative::getProblemSourcesCode, SPDC.getValue()));
overview.setTotal(negatives.size());
overview.setCompletionProblem(negatives.stream().filter(item -> ProcessingStatusEnum.completed.name().equals(item.getProcessingStatus())).count());
List<String> trueValue = List.of(InspectCaseEnum.TRUE.getValue(), InspectCaseEnum.PARTIALLY_TRUE.getValue());
overview.setDiscoverProblem(negatives.stream().filter(item -> Objects.nonNull(item.getCheckStatus()) && trueValue.contains(item.getCheckStatus())).count());
if (negatives.isEmpty()) {
overview.setRelativeOrg(0L);
overview.setRelativePer(0L);
} else {
List<NegativeBlame> blames = blameService.list(new LambdaQueryWrapper<NegativeBlame>()
.in(NegativeBlame::getNegativeId, negatives.stream().map(Negative::getId).toList())
.isNotNull(NegativeBlame::getHandleResultCode)
.ne(NegativeBlame::getHandleResultCode, "")
.ne(NegativeBlame::getHandleResultName, "不予追责"));
List<NegativeBlame> departBlames = blames.stream().filter(item -> BlameType.department.name().equals(item.getType())).toList();
if (departBlames.isEmpty()) {
overview.setRelativeOrg(0L);
} else {
long count = policeService.list(new LambdaQueryWrapper<SupPolice>().in(SupPolice::getEmpNo, departBlames.stream().map(NegativeBlame::getBlameEmpNo).collect(Collectors.toSet()))).stream().map(SupPolice::getOrgId).distinct().count();
overview.setRelativeOrg(count);
}
overview.setRelativePer(blames.stream().filter(item -> BlameType.personal.name().equals(item.getType())).count());
}
JSONObject data = new JSONObject().fluentPut("overview", overview);
return Result.success(data);
}
@ -132,7 +172,7 @@ public class DataVVideoSuperviseController {
List<VideoSuperviseMapIconVo> videoSuperviseMapIconVoList = Optional.ofNullable(negativeMapper.getVideoSuperviseMapIconInfo(beginTime, endTime)).
orElseGet(ArrayList::new);
List<EchartsVo> list =negativeMapper.selectRelativePer(beginTime,endTime);
List<EchartsVo> list = negativeMapper.selectRelativePer(beginTime,endTime);
videoSuperviseMapIconVoList.forEach(s->{
List<EchartsVo> echartsVoList= list.stream().filter(b->b.getName().contains(s.getDepartId())).toList();
if(!echartsVoList.isEmpty()){

116
src/main/java/com/biutag/supervision/mapper/NegativeMapper.java

@ -371,23 +371,35 @@ public interface NegativeMapper extends BaseMapper<Negative> {
"ORDER BY `value` DESC")
List<OrganizeProblemRankVo> getVideoSuperviseProblemRank(Date beginTime, Date endTime, Integer groupId);
@Select("SELECT " +
"sd.short_name AS `name`, " +
"sd.id AS departId, " +
"COUNT(DISTINCT ng.id) as total, "+
"COUNT(DISTINCT CASE WHEN ng.checkStatus <> 3 THEN ng.id END) AS discoverProblem, " +
"COUNT( DISTINCT IF(ng.processing_status='completed', ng.id, NULL) ) AS completionProblem, " +
"COUNT( DISTINCT ng.involveDepartId) AS relativeOrg, " +
"COUNT( DISTINCT nb.blameName ) AS relativePer, " +
"IFNULL(ROUND( COUNT( DISTINCT IF(ng.processing_status='completed', ng.id, NULL) )/COUNT( DISTINCT ng.id)*100, 1 ),0) AS completionRate " +
"FROM sup_depart sd " +
"LEFT JOIN negative ng ON sd.id=ng.second_involve_depart_id " +
"AND problemSourcesCode = 16 " +
"AND crtTime BETWEEN #{beginTime} AND #{endTime} " +
"and checkStatus in (1, 2) "+
"LEFT JOIN negative_blame nb ON ng.id=nb.negativeId " +
"WHERE sd.statistics_group_id=3 " +
"GROUP BY sd.short_name; ")
@Select("SELECT " +
" d.short_name name, " +
" d.id departId, " +
" t.discoverProblem, " +
" t.completionProblem, " +
" t.relativePer, " +
" t.relativeOrg " +
"FROM " +
" sup_depart d " +
" LEFT JOIN ( " +
" SELECT " +
" a.second_involve_depart_id, " +
" count( DISTINCT IF ( a.checkStatus IN ( '1', '2' ), a.id, NULL ) ) discoverProblem, " +
" count( DISTINCT IF ( a.processing_status = 'completed', a.id, NULL ) ) completionProblem, " +
" count( DISTINCT IF ( b.type = 'personal' and b.handleResultName != '不予追责' and b.handleResultCode is not null and b.handleResultCode != '', b.blameEmpNo, NULL ) ) relativePer, " +
" count( DISTINCT IF ( b.type = 'department' and b.handleResultName != '不予追责' and b.handleResultCode is not null and b.handleResultCode != '', b.blameEmpNo, NULL ) ) relativeOrg " +
" FROM " +
" negative a " +
" JOIN negative_blame b ON a.id = b.negativeId " +
" WHERE " +
" a.crtTime BETWEEN #{beginTime} AND #{endTime} AND a.problemSourcesCode = 16 " +
" GROUP BY " +
" a.second_involve_depart_id " +
" ) t ON d.id = t.second_involve_depart_id " +
"WHERE " +
" d.statistics_group_id = 3 " +
"GROUP BY " +
" d.short_name, " +
" d.id")
List<VideoSuperviseMapIconVo> getVideoSuperviseMapIconInfo(Date beginTime, Date endTime);
/**
@ -451,21 +463,61 @@ public interface NegativeMapper extends BaseMapper<Negative> {
@Select("SELECT " +
"sd.short_name AS `name`, " +
"sd.id AS departId, " +
"COUNT( DISTINCT ng.id ) AS total, " +
"COUNT( DISTINCT IF( ng.checkStatus<>3, ng.id, NULL ) ) AS confirmed, " +
"COUNT( DISTINCT IF( nb.handleResultCode!=14, nb.blameId, NULL ) ) AS dealCasePro, " +
"COUNT( DISTINCT nb.blameIdCode ) AS punishPre, " +
"COUNT( DISTINCT nb.blameDepartId ) AS punishOrg, " +
"IFNULL( ROUND( COUNT( DISTINCT IF( ng.isRectifyCode=1, ng.id, NULL ) )/COUNT( DISTINCT ng.id )*100, 1 ), 0) AS rate " +
"FROM sup_depart sd " +
"LEFT JOIN negative ng ON ng.second_involve_depart_id=sd.id " +
"AND ng.problemSourcesCode IN (17,18,19,20) " +
"AND ng.crtTime BETWEEN #{beginTime} AND #{endTime} " +
"LEFT JOIN negative_blame nb ON ng.id=nb.negativeId " +
"WHERE sd.statistics_group_id=3 " +
"GROUP BY sd.short_name;")
" d.short_name name, " +
" d.id departId, " +
" t1.total, " +
" t.confirmed, " +
" t.dealCasePro, " +
" t.punishPre, " +
" t.punishOrg, " +
"CASE WHEN t1.total = 0 THEN 0 ELSE ROUND(t.confirmed / t1.total * 100) END rate " +
"FROM " +
" sup_depart d " +
" LEFT JOIN ( " +
" SELECT " +
" a.second_involve_depart_id, " +
" count( DISTINCT a.id ) confirmed, " +
" count( DISTINCT IF ( a.checkStatus IN ( '1', '2' ), a.id, NULL ) ) dealCasePro, " +
" count( DISTINCT IF ( a.processing_status = 'completed', a.id, NULL ) ) completionProblem, " +
" count( " +
" DISTINCT " +
" IF " +
" ( " +
" b.type = 'personal' " +
" AND b.handleResultName != '不予追责' " +
" AND b.handleResultCode IS NOT NULL " +
" AND b.handleResultCode != '', " +
" b.blameId, " +
" NULL " +
" ) " +
" ) punishPre, " +
" count( " +
" DISTINCT " +
" IF " +
" ( " +
" b.type = 'department' " +
" AND b.handleResultName != '不予追责' " +
" AND b.handleResultCode IS NOT NULL " +
" AND b.handleResultCode != '', " +
" b.blameEmpNo, " +
" NULL " +
" ) " +
" ) punishOrg " +
" FROM " +
" negative a " +
" JOIN negative_blame b ON a.id = b.negativeId " +
" WHERE " +
" a.crtTime BETWEEN #{beginTime} AND #{endTime} " +
" AND a.problemSourcesCode IN ( 17, 18, 19, 20 ) " +
" GROUP BY " +
" a.second_involve_depart_id " +
" ) t ON d.id = t.second_involve_depart_id " +
" LEFT JOIN ( SELECT second_depart_id, count( 1 ) total FROM data_case_verif WHERE create_time BETWEEN #{beginTime} AND #{endTime} GROUP BY second_depart_id ) t1 ON d.id = t1.second_depart_id " +
"WHERE " +
" d.statistics_group_id = 3 " +
"GROUP BY " +
" d.short_name, " +
" d.id")
List<CaseVerificationMapVo> getCaseVerificationMap(Date beginTime, Date endTime);
@Select("SELECT nb.handleResultName as `name`, count(*) as `value` " +

7
src/main/java/com/biutag/supervision/pojo/vo/CaseVerificationCountVo.java

@ -12,11 +12,10 @@ public class CaseVerificationCountVo {
private Integer total; // 总案件数
private Integer confirmed; // 已查实案件数
private Integer dealCasePro; // 查处理案件数
private Integer punishPre; // 问责人数
private Integer punishOrg; // 问责单位数
private Long dealCasePro; // 查处理案件数
private Long punishPre; // 问责人数
private Long punishOrg; // 问责单位数
private Double rate; // 查实率
}

10
src/main/java/com/biutag/supervision/pojo/vo/VideoSuperviseCountVo.java

@ -14,11 +14,11 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
public class VideoSuperviseCountVo {
private Long total;
private Integer discoverProblem;
private Integer completionProblem;
private Integer relativeOrg;
private Integer relativePer;
private Integer total;
private Long discoverProblem;
private Long completionProblem;
private Long relativeOrg;
private Long relativePer;
private Double completionRate;
}

20
src/test/java/com/biutag/supervision/StrUtil.java

@ -5,6 +5,7 @@ import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.fastjson2.JSONObject;
import com.biutag.supervision.constants.enums.InspectCaseEnum;
import com.biutag.supervision.pojo.vo.RpcApplyVo;
import freemarker.template.Configuration;
import freemarker.template.Template;
@ -136,9 +137,22 @@ public class StrUtil {
@Test
public void template4() {
String s = "123";
System.out.println(String.format(" %s", s));
System.out.println("SELECT " +
"sd.short_name AS `name`, " +
"sd.id AS departId, " +
"COUNT( DISTINCT ng.id ) AS total, " +
"COUNT( DISTINCT IF( ng.checkStatus<>3, ng.id, NULL ) ) AS confirmed, " +
"COUNT( DISTINCT IF( nb.handleResultCode!=14, nb.blameId, NULL ) ) AS dealCasePro, " +
"COUNT( DISTINCT nb.blameIdCode ) AS punishPre, " +
"COUNT( DISTINCT nb.blameDepartId ) AS punishOrg, " +
"IFNULL( ROUND( COUNT( DISTINCT IF( ng.isRectifyCode=1, ng.id, NULL ) )/COUNT( DISTINCT ng.id )*100, 1 ), 0) AS rate " +
"FROM sup_depart sd " +
"LEFT JOIN negative ng ON ng.second_involve_depart_id=sd.id " +
"AND ng.problemSourcesCode IN (17,18,19,20) " +
"AND ng.crtTime BETWEEN #{beginTime} AND #{endTime} " +
"LEFT JOIN negative_blame nb ON ng.id=nb.negativeId " +
"WHERE sd.statistics_group_id=3 " +
"GROUP BY sd.short_name");
}
}

Loading…
Cancel
Save