package com.ichaoj.ams.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.math.MathUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ichaoj.ams.constant.AmsConstant;
import com.ichaoj.ams.entity.AmsAirdropProject;
import com.ichaoj.ams.entity.AmsAirdropTask;
import com.ichaoj.ams.entity.AmsExecuteRecord;
import com.ichaoj.ams.entity.AmsTradeRecord;
import com.ichaoj.ams.mapper.AmsAirdropProjectMapper;
import com.ichaoj.ams.request.airdrop.CreateAirdropProject;
import com.ichaoj.ams.request.airdrop.PageProjectRequest;
import com.ichaoj.ams.request.airdrop.UpdateAirdropProject;
import com.ichaoj.ams.response.airdrop.AirdropProjectResponse;
import com.ichaoj.ams.response.record.TradeRecordResponse;
import com.ichaoj.ams.response.statistics.PredictCostResponse;
import com.ichaoj.ams.service.IAmsAirdropProjectService;
import com.ichaoj.ams.service.IAmsAirdropTaskService;
import com.ichaoj.ams.service.IAmsExecuteRecordService;
import com.ichaoj.ams.service.IAmsTradeRecordService;
import com.ichaoj.common.model.PublicPage;
import com.ichaoj.common.model.PublicUserInfo;
import com.ichaoj.mybatis.service.SuperWhaleServiceImpl;
import com.ichaoj.web.context.SuperWhaleContext;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
/**
*
* 空投项目 服务实现类
*
*
* @author cjwen
* @since 2023-05-10
*/
@Service
public class AmsAirdropProjectServiceImpl extends SuperWhaleServiceImpl implements IAmsAirdropProjectService {
@Resource
private IAmsAirdropTaskService taskService;
@Resource
@Lazy
private IAmsExecuteRecordService executeRecordService;
@Resource
@Lazy
private IAmsTradeRecordService tradeRecordService;
@Override
public PublicPage pageAirdropProject(PageProjectRequest projectRequest) {
LambdaQueryWrapper wrapper = Wrappers.lambdaQuery();
wrapper
.eq(StrUtil.isNotBlank(projectRequest.getQueryValue()), AmsAirdropProject::getProjectUrl, projectRequest.getQueryValue())
.or().like(StrUtil.isNotBlank(projectRequest.getQueryValue()), AmsAirdropProject::getProjectName, projectRequest.getQueryValue())
.orderByDesc(AmsAirdropProject::getCreateTime);
Page result = this.page(this.buildPageObj(projectRequest), wrapper);
return this.convertPublicPage(result, project -> {
AirdropProjectResponse response = BeanUtil.copyProperties(project, AirdropProjectResponse.class);
List list = executeRecordService.list(
new LambdaQueryWrapper()
.eq(AmsExecuteRecord::getExecuteStatus, 1)
.eq(AmsExecuteRecord::getProjectId, project.getAmsProjectId())
.eq(AmsExecuteRecord::getUserId, SuperWhaleContext.getContext(PublicUserInfo.class).getUserId())
);
if (CollectionUtil.isNotEmpty(list)) {
List records = tradeRecordService.listByIds(list.stream().map(AmsExecuteRecord::getExecuteId).collect(Collectors.toList()));
double totalGas = records.stream().mapToDouble(t -> Double.parseDouble(t.getGas())).sum();
response.setTotalGas(BigDecimal.valueOf(totalGas));
} else {
response.setTotalGas(BigDecimal.ZERO);
}
List tasks = taskService.list(new LambdaQueryWrapper()
.eq(AmsAirdropTask::getAirdropProjectId, project.getAmsProjectId()));
if (CollectionUtil.isNotEmpty(tasks)) {
long sum = tasks.stream().mapToLong(AmsAirdropTask::getPlanTimes).sum();
response.setTaskTotalCount(sum);
long finishCount = executeRecordService.count(
new LambdaQueryWrapper()
.eq(AmsExecuteRecord::getExecuteStatus, 1)
.in(AmsExecuteRecord::getTaskId, tasks.stream()
.map(AmsAirdropTask::getAmsTaskId)
.collect(Collectors.toList()))
);
response.setTaskFinishCount(finishCount);
} else {
response.setTaskTotalCount(0);
response.setTaskFinishCount(0);
}
return response;
});
}
@Override
public void createAirdropProject(CreateAirdropProject createAirdropProject) {
AmsAirdropProject project = BeanUtil.copyProperties(createAirdropProject, AmsAirdropProject.class);
project.setCreateTime(LocalDateTime.now());
project.setStatus(AmsConstant.AirdropStatus.NOT_STARTED);
this.save(project);
// List taskIds = createAirdropProject.getTaskIds();
// if (CollectionUtil.isNotEmpty(taskIds)) {
// List tasks = taskService.listByIds(taskIds)
// .stream()
// .peek(t -> t.setAirdropProjectId(project.getAmsProjectId()))
// .collect(Collectors.toList());
// taskService.updateBatchById(tasks);
// }
}
@Override
public void updateAirdropProject(UpdateAirdropProject updateAirdropProject) {
AmsAirdropProject project = BeanUtil.copyProperties(updateAirdropProject, AmsAirdropProject.class);
project.setUpdateTime(LocalDateTime.now());
this.updateById(project);
List taskList = updateAirdropProject.getTasks();
if (CollectionUtil.isEmpty(taskList)) {
return;
}
List tasks = taskService.listByIds(taskList.stream().map(UpdateAirdropProject.Task::getTaskId).collect(Collectors.toList()));
if (CollectionUtil.isNotEmpty(tasks)) {
for (AmsAirdropTask task : tasks) {
for (UpdateAirdropProject.Task t : taskList) {
if (task.getAmsTaskId().equals(t.getTaskId())) {
task.setTaskName(t.getTaskName());
taskService.updateById(task);
}
}
}
}
}
@Override
public PredictCostResponse predictCostStatistics() {
List list = this.list();
PredictCostResponse response = new PredictCostResponse();
response.setTotalCount(list.size());
response.setTotalCost(BigDecimal.valueOf(list.stream().mapToDouble(p -> Double.parseDouble(p.getEstimatedCost())).sum()));
List predicts = BeanUtil.copyToList(list, PredictCostResponse.Predict.class);
response.setPredicts(predicts.stream().sorted((p1, p2) -> CompareUtil.compare(p2.getEstimatedCost(), p1.getEstimatedCost())).collect(Collectors.toList()));
List tradeList = tradeRecordService.listByUserId(SuperWhaleContext.getContext(PublicUserInfo.class).getUserId());
response.setActualCost(BigDecimal.valueOf(tradeList.stream().mapToDouble(t -> Double.sum(Double.parseDouble(t.getGas()), Double.parseDouble(t.getAmount()))).sum()));
return response;
}
}