fix: 项目状态
This commit is contained in:
parent
25fcc34b68
commit
f20630786a
@ -3,6 +3,7 @@ package com.cmvr.web.controller.evaluation;
|
|||||||
import com.cmvr.common.core.controller.BaseController;
|
import com.cmvr.common.core.controller.BaseController;
|
||||||
import com.cmvr.common.core.domain.AjaxResult;
|
import com.cmvr.common.core.domain.AjaxResult;
|
||||||
import com.cmvr.evaluation.model.domain.AeEvaluation;
|
import com.cmvr.evaluation.model.domain.AeEvaluation;
|
||||||
|
import com.cmvr.evaluation.service.AeCallbackService;
|
||||||
import com.cmvr.evaluation.service.IAeEvaluationService;
|
import com.cmvr.evaluation.service.IAeEvaluationService;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
@ -18,13 +19,13 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class AeEvaluationController extends BaseController {
|
public class AeEvaluationController extends BaseController {
|
||||||
|
|
||||||
|
|
||||||
private final IAeEvaluationService aeEvaluationService;
|
private final IAeEvaluationService aeEvaluationService;
|
||||||
|
private final AeCallbackService aeCallbackService;
|
||||||
|
|
||||||
@ApiOperation("回调AI评估")
|
@ApiOperation("回调AI评估")
|
||||||
@PostMapping("/callback")
|
@PostMapping("/callback")
|
||||||
public AjaxResult list(@RequestBody AeEvaluation aeEvaluation) {
|
public AjaxResult list(@RequestBody AeEvaluation aeEvaluation) {
|
||||||
aeEvaluationService.callback(aeEvaluation);
|
aeCallbackService.callback(aeEvaluation);
|
||||||
return AjaxResult.ok();
|
return AjaxResult.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,9 @@ public class AeEvaluation implements Serializable {
|
|||||||
@ApiModelProperty("流程实例ID")
|
@ApiModelProperty("流程实例ID")
|
||||||
private String instId;
|
private String instId;
|
||||||
|
|
||||||
|
@ApiModelProperty("项目ID")
|
||||||
|
private String taskId;
|
||||||
|
|
||||||
@ApiModelProperty("检测项ID")
|
@ApiModelProperty("检测项ID")
|
||||||
private String itemId;
|
private String itemId;
|
||||||
|
|
||||||
@ -37,7 +40,7 @@ public class AeEvaluation implements Serializable {
|
|||||||
@ApiModelProperty("视频地址")
|
@ApiModelProperty("视频地址")
|
||||||
private String videoPath;
|
private String videoPath;
|
||||||
|
|
||||||
@ApiModelProperty("评估状态,0:待评估,1:评估中,3:评估成功,4:评估失败")
|
@ApiModelProperty("评估状态,0:待评估,1:评估中,2:评估成功,3:评估失败")
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
@ApiModelProperty("评估最终结果(JSON)")
|
@ApiModelProperty("评估最终结果(JSON)")
|
||||||
|
|||||||
@ -0,0 +1,11 @@
|
|||||||
|
package com.cmvr.evaluation.service;
|
||||||
|
|
||||||
|
import com.cmvr.evaluation.model.domain.AeEvaluation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 评估回写服务(防止依赖循环)
|
||||||
|
*/
|
||||||
|
public interface AeCallbackService {
|
||||||
|
|
||||||
|
public void callback(AeEvaluation aeEvaluation);
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
package com.cmvr.evaluation.service;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
|
||||||
|
public interface ExViProjectService {
|
||||||
|
|
||||||
|
public JSONObject queryById(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 评估完成回写项目状态
|
||||||
|
*/
|
||||||
|
public boolean updateStatus(String id);
|
||||||
|
|
||||||
|
}
|
||||||
@ -12,10 +12,12 @@ public interface IAeEvaluationService extends IService<AeEvaluation> {
|
|||||||
*/
|
*/
|
||||||
public void executeEvaluation(AeEvaluation evaluation);
|
public void executeEvaluation(AeEvaluation evaluation);
|
||||||
|
|
||||||
/**
|
public void runEvaluation(AeEvaluation evaluation);
|
||||||
* 评估回调
|
|
||||||
*/
|
|
||||||
void callback(AeEvaluation aeEvaluation);
|
|
||||||
|
|
||||||
List<AeEvaluation> queryEvaluation(String instId);
|
List<AeEvaluation> queryEvaluation(String instId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断当前项目是否已完成全部评估
|
||||||
|
*/
|
||||||
|
public boolean isAllEvaluationsFinished(String instId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,78 @@
|
|||||||
|
package com.cmvr.evaluation.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.cmvr.common.exception.GlobalException;
|
||||||
|
import com.cmvr.evaluation.model.domain.AeEvaluation;
|
||||||
|
import com.cmvr.evaluation.service.AeCallbackService;
|
||||||
|
import com.cmvr.evaluation.service.ExViProjectService;
|
||||||
|
import com.cmvr.evaluation.service.IAeEvaluationService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class AeCallbackServiceImpl implements AeCallbackService {
|
||||||
|
|
||||||
|
private final IAeEvaluationService aeEvaluationService;
|
||||||
|
private final ExViProjectService exViProjectService;
|
||||||
|
private final StringRedisTemplate redisTemplate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void callback(AeEvaluation aeEvaluation) {
|
||||||
|
String aeId = aeEvaluation.getAeId();
|
||||||
|
if (StrUtil.isEmpty(aeId)) {
|
||||||
|
throw new GlobalException("AI评估ID不能为空!");
|
||||||
|
}
|
||||||
|
String result = aeEvaluation.getResult();
|
||||||
|
if (StrUtil.isEmpty(result)) {
|
||||||
|
throw new GlobalException("AI评估结果不能为空!");
|
||||||
|
}
|
||||||
|
AeEvaluation byId = aeEvaluationService.getById(aeId);
|
||||||
|
if (Objects.isNull(byId)) {
|
||||||
|
log.error("ID为 {} 的评估对象不存在!", aeId);
|
||||||
|
}
|
||||||
|
JSONObject jsonObject = JSON.parseObject(result);
|
||||||
|
String overallResult = jsonObject.getString("overall_result");
|
||||||
|
int status;
|
||||||
|
if (StrUtil.isNotEmpty(overallResult) && overallResult.equals("成功")) {
|
||||||
|
status = 3;
|
||||||
|
} else {
|
||||||
|
status = 4;
|
||||||
|
}
|
||||||
|
LambdaUpdateWrapper<AeEvaluation> wrapper = Wrappers.lambdaUpdate();
|
||||||
|
wrapper.eq(AeEvaluation::getAeId, aeId)
|
||||||
|
.set(AeEvaluation::getResult, result)
|
||||||
|
.set(AeEvaluation::getStatus, status); // 评估完成/失败
|
||||||
|
|
||||||
|
aeEvaluationService.update(wrapper);
|
||||||
|
|
||||||
|
// 判断是否是最后一次评估 更改项目状态
|
||||||
|
boolean finished = aeEvaluationService.isAllEvaluationsFinished(byId.getInstId());
|
||||||
|
if (finished) {
|
||||||
|
exViProjectService.updateStatus(byId.getTaskId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 继续下一个评估
|
||||||
|
String str = redisTemplate.opsForList().leftPop("ae:evaluation:queue");
|
||||||
|
if (StrUtil.isEmpty(str)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AeEvaluation evaluation = JSON.parseObject(str, AeEvaluation.class);
|
||||||
|
try {
|
||||||
|
Thread.sleep(2000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
aeEvaluationService.runEvaluation(evaluation);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,7 +8,6 @@ import com.alibaba.fastjson2.JSON;
|
|||||||
import com.alibaba.fastjson2.JSONArray;
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.cmvr.common.exception.GlobalException;
|
import com.cmvr.common.exception.GlobalException;
|
||||||
@ -27,7 +26,6 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@ -43,6 +41,7 @@ import java.util.stream.Collectors;
|
|||||||
public class AeEvaluationServiceImpl extends ServiceImpl<AeEvaluationMapper, AeEvaluation> implements IAeEvaluationService {
|
public class AeEvaluationServiceImpl extends ServiceImpl<AeEvaluationMapper, AeEvaluation> implements IAeEvaluationService {
|
||||||
|
|
||||||
private final ITeNodeInstService teNodeInstService;
|
private final ITeNodeInstService teNodeInstService;
|
||||||
|
|
||||||
private final APIProperties apiProperties;
|
private final APIProperties apiProperties;
|
||||||
private final StringRedisTemplate redisTemplate;
|
private final StringRedisTemplate redisTemplate;
|
||||||
|
|
||||||
@ -205,57 +204,20 @@ public class AeEvaluationServiceImpl extends ServiceImpl<AeEvaluationMapper, AeE
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runEvaluation(AeEvaluation first) {
|
public void runEvaluation(AeEvaluation evaluation) {
|
||||||
// 构建评估请求
|
// 构建评估请求
|
||||||
Map<String, String> body = new HashMap<>();
|
Map<String, String> body = new HashMap<>();
|
||||||
body.put("aeId", first.getAeId());
|
body.put("aeId", evaluation.getAeId());
|
||||||
body.put("audioPath", first.getAudioPath());
|
body.put("audioPath", evaluation.getAudioPath());
|
||||||
body.put("videoPath", first.getVideoPath());
|
body.put("videoPath", evaluation.getVideoPath());
|
||||||
body.put("content", first.getAvContent());
|
body.put("content", evaluation.getAvContent());
|
||||||
body.put("aeType", first.getAeType());
|
body.put("aeType", evaluation.getAeType());
|
||||||
CallAPIUtil.doPostJson(apiProperties.getEvaluation(), null, body);
|
CallAPIUtil.doPostJson(apiProperties.getEvaluation(), null, body);
|
||||||
|
|
||||||
first.setStatus(1);
|
evaluation.setStatus(1);
|
||||||
this.updateById(first);
|
this.updateById(evaluation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void callback(AeEvaluation aeEvaluation) {
|
|
||||||
String aeId = aeEvaluation.getAeId();
|
|
||||||
if (StrUtil.isEmpty(aeId)) {
|
|
||||||
throw new GlobalException("AI评估ID不能为空!");
|
|
||||||
}
|
|
||||||
String result = aeEvaluation.getResult();
|
|
||||||
if (StrUtil.isEmpty(result)) {
|
|
||||||
throw new GlobalException("AI评估结果不能为空!");
|
|
||||||
}
|
|
||||||
AeEvaluation byId = this.getById(aeId);
|
|
||||||
if (Objects.isNull(byId)) {
|
|
||||||
log.error("ID为 {} 的评估对象不存在!",aeId);
|
|
||||||
}
|
|
||||||
JSONObject jsonObject = JSON.parseObject(result);
|
|
||||||
String overallResult = jsonObject.getString("overall_result");
|
|
||||||
int status;
|
|
||||||
if (StrUtil.isNotEmpty(overallResult) && overallResult.equals("成功")) {
|
|
||||||
status = 3;
|
|
||||||
} else {
|
|
||||||
status = 4;
|
|
||||||
}
|
|
||||||
LambdaUpdateWrapper<AeEvaluation> wrapper = Wrappers.lambdaUpdate();
|
|
||||||
wrapper.eq(AeEvaluation::getAeId, aeId)
|
|
||||||
.set(AeEvaluation::getResult, result)
|
|
||||||
.set(AeEvaluation::getStatus, status); // 评估完成/失败
|
|
||||||
|
|
||||||
this.update(wrapper);
|
|
||||||
|
|
||||||
// 继续下一个评估
|
|
||||||
String str = redisTemplate.opsForList().leftPop("ae:evaluation:queue");
|
|
||||||
if (StrUtil.isEmpty(str)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
AeEvaluation evaluation = JSON.parseObject(str, AeEvaluation.class);
|
|
||||||
runEvaluation(evaluation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AeEvaluation> queryEvaluation(String instId) {
|
public List<AeEvaluation> queryEvaluation(String instId) {
|
||||||
@ -264,6 +226,26 @@ public class AeEvaluationServiceImpl extends ServiceImpl<AeEvaluationMapper, AeE
|
|||||||
return this.list(wrapper);
|
return this.list(wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAllEvaluationsFinished(String instId) {
|
||||||
|
long total = this.count(
|
||||||
|
Wrappers.lambdaQuery(AeEvaluation.class)
|
||||||
|
.eq(AeEvaluation::getInstId, instId)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (total == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
long unfinished = this.count(
|
||||||
|
Wrappers.lambdaQuery(AeEvaluation.class)
|
||||||
|
.eq(AeEvaluation::getInstId, instId)
|
||||||
|
.ne(AeEvaluation::getStatus, 2)
|
||||||
|
);
|
||||||
|
|
||||||
|
return unfinished == 0;
|
||||||
|
}
|
||||||
|
|
||||||
private Map<String, List<TeNodeInst>> buildSingleIterationMap(List<TeNodeInst> view) {
|
private Map<String, List<TeNodeInst>> buildSingleIterationMap(List<TeNodeInst> view) {
|
||||||
return view.stream()
|
return view.stream()
|
||||||
.filter(e -> StrUtil.isNotEmpty(e.getIteration()))
|
.filter(e -> StrUtil.isNotEmpty(e.getIteration()))
|
||||||
|
|||||||
@ -29,6 +29,7 @@ public class FlowEndNodeHandler implements FlowNodeTypeHandler {
|
|||||||
public TaskNodeExecuteResult handle(TaskNodeExecuteMessage message) {
|
public TaskNodeExecuteResult handle(TaskNodeExecuteMessage message) {
|
||||||
String instId = message.getInstId();
|
String instId = message.getInstId();
|
||||||
String itemId = message.getItemId();
|
String itemId = message.getItemId();
|
||||||
|
String taskId = message.getTaskId();
|
||||||
TaskContext context = taskInstHolder.getContext(instId);
|
TaskContext context = taskInstHolder.getContext(instId);
|
||||||
RunModeEnum runMode = context.getRunMode();
|
RunModeEnum runMode = context.getRunMode();
|
||||||
// if (runMode.equals(RunModeEnum.NORMAL) || runMode.equals(RunModeEnum.TRIAL)) {
|
// if (runMode.equals(RunModeEnum.NORMAL) || runMode.equals(RunModeEnum.TRIAL)) {
|
||||||
@ -38,6 +39,7 @@ public class FlowEndNodeHandler implements FlowNodeTypeHandler {
|
|||||||
|
|
||||||
JSONObject jsonObject = new JSONObject();
|
JSONObject jsonObject = new JSONObject();
|
||||||
jsonObject.put("instId", instId);
|
jsonObject.put("instId", instId);
|
||||||
|
jsonObject.put("taskId", taskId);
|
||||||
jsonObject.put("itemId", itemId);
|
jsonObject.put("itemId", itemId);
|
||||||
jsonObject.put("aeType", RunModeEnum.VI_PROJECT.name());
|
jsonObject.put("aeType", RunModeEnum.VI_PROJECT.name());
|
||||||
|
|
||||||
|
|||||||
@ -78,6 +78,6 @@ public class ViProject extends BaseEntity {
|
|||||||
@ApiModelProperty("送样日期")
|
@ApiModelProperty("送样日期")
|
||||||
private Date sampleDate;
|
private Date sampleDate;
|
||||||
|
|
||||||
@ApiModelProperty(value = "状态", notes = "状态(0已执行 1未执行)")
|
@ApiModelProperty(value = "状态", notes = "状态(0未执行 1执行中 2执行完成(评估))")
|
||||||
private String status;
|
private String status;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,32 @@
|
|||||||
|
package com.cmvr.vi.service.ex;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.cmvr.evaluation.service.ExViProjectService;
|
||||||
|
import com.cmvr.vi.model.domain.ViProject;
|
||||||
|
import com.cmvr.vi.service.IViProjectService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class ExViProjectServiceImpl implements ExViProjectService {
|
||||||
|
|
||||||
|
private final IViProjectService viProjectService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject queryById(String id) {
|
||||||
|
ViProject project = viProjectService.getById(id);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateStatus(String id) {
|
||||||
|
LambdaUpdateWrapper<ViProject> wrapper = Wrappers.lambdaUpdate();
|
||||||
|
wrapper.eq(ViProject::getProjectId, id)
|
||||||
|
.eq(ViProject::getStatus, 1) // 运行中
|
||||||
|
.set(ViProject::getStatus, 2); // 完成
|
||||||
|
return viProjectService.update(null, wrapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjUtil;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.cmvr.common.exception.GlobalException;
|
import com.cmvr.common.exception.GlobalException;
|
||||||
@ -73,6 +74,7 @@ public class ViProjectServiceImpl extends ServiceImpl<ViProjectMapper, ViProject
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int insertViProject(ViProject viProject) {
|
public int insertViProject(ViProject viProject) {
|
||||||
|
viProject.setStatus("0");
|
||||||
int insert = this.baseMapper.insert(viProject);
|
int insert = this.baseMapper.insert(viProject);
|
||||||
TeTaskConfigInfo taskConfigInfo = new TeTaskConfigInfo();
|
TeTaskConfigInfo taskConfigInfo = new TeTaskConfigInfo();
|
||||||
taskConfigInfo.setRunMode(RunModeEnum.VI_PROJECT.name());
|
taskConfigInfo.setRunMode(RunModeEnum.VI_PROJECT.name());
|
||||||
@ -135,11 +137,11 @@ public class ViProjectServiceImpl extends ServiceImpl<ViProjectMapper, ViProject
|
|||||||
normalVO.setRunParams(taskExecuteProjectVO.getRunParams());
|
normalVO.setRunParams(taskExecuteProjectVO.getRunParams());
|
||||||
normalVO.setTerminalId(taskExecuteProjectVO.getTerminalId());
|
normalVO.setTerminalId(taskExecuteProjectVO.getTerminalId());
|
||||||
String instId = flowTaskRuntimeService.executeProjectTask(normalVO);
|
String instId = flowTaskRuntimeService.executeProjectTask(normalVO);
|
||||||
// this.update(
|
this.update(
|
||||||
// new LambdaUpdateWrapper<ViProject>()
|
new LambdaUpdateWrapper<ViProject>()
|
||||||
// .eq(ViProject::getProjectId, taskExecuteProjectVO.getProjectId())
|
.eq(ViProject::getProjectId, taskExecuteProjectVO.getProjectId())
|
||||||
// .set(ViProject::getStatus, "0")
|
.set(ViProject::getStatus, "1") //执行中
|
||||||
// );
|
);
|
||||||
return instId;
|
return instId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user