package com.itmuch.contentcenter.service.content;
import com.itmuch.contentcenter.dao.content.RocketmqTransactionLogMapper;
import com.itmuch.contentcenter.dao.content.ShareMapper;
import com.itmuch.contentcenter.domain.dto.content.ShareAuditDTO;
import com.itmuch.contentcenter.domain.dto.content.ShareDTO;
import com.itmuch.contentcenter.domain.dto.message.UserAddBonusMsgDTO;
import com.itmuch.contentcenter.domain.dto.user.UserDTO;
import com.itmuch.contentcenter.domain.entity.content.RocketmqTransactionLog;
import com.itmuch.contentcenter.domain.entity.content.Share;
import com.itmuch.contentcenter.domain.enums.AuditStatusEnum;
import com.itmuch.contentcenter.feignclient.UserCenterFeignClient;
import com.sun.xml.internal.txw2.IllegalSignatureException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.ResponseEntity;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class ShareService {
private final RocketmqTransactionLogMapper rocketmqTransactionLogMapper;
private final RocketMQTemplate rocketMQTemplate;
private final ShareMapper shareMapper;
//private final RestTemplate restTemplate;
private final UserCenterFeignClient userCenterFeignClient;
//private final DiscoveryClient discoveryClient;
public ShareDTO findById(Integer id){
//获取分享人详情
Share share = this.shareMapper.selectByPrimaryKey(id);
//发布人id
Integer userId = share.getUserId();
//怎么调用用户微服务的/user/{userId}??
//用户中心所有实例的信息
//List<ServiceInstance> instances = discoveryClient.getInstances("user-center");
//所有用户中心实例的请求地址
/*List<String> targetURLS = instances.stream()
.map(instance -> instance.getUri().toString() + "/users/{id}")
.collect(Collectors.toList());
//.findFirst()
//当instances是空的列表时会抛出异常
//.orElseThrow(() -> new IllegalArgumentException("当前没有实例"));*/
//int i = ThreadLocalRandom.current().nextInt(targetURLS.size());
//log.info("请求的目标地址:{} " + targetURLS.get(i));
/*UserDTO userDTO = this.restTemplate.getForObject(
"http://user-center/users/{userId}",
UserDTO.class,userId
);*/
UserDTO userDTO = this.userCenterFeignClient.findById(userId);
ShareDTO shareDTO = new ShareDTO();
BeanUtils.copyProperties(share,shareDTO);
shareDTO.setWxNickname(userDTO.getWxNickname());
return shareDTO;
}
public static void main(String[] args) {
RestTemplate restTemplate = new RestTemplate();
//用Http的get方法去请求,并且返回一个对象
String forObject = restTemplate.getForObject(
"http://localhost:8080/users/1",
String.class
);
System.out.println(forObject);
}
public Share auditById(Integer id, ShareAuditDTO auditDTO) {
//1.查询share是否存在,不存在或者当前的audit_status == NOT_YET,那么抛出异常
Share share = this.shareMapper.selectByPrimaryKey(id);
if(share == null){
throw new IllegalSignatureException("参数非法!该分享不存在!");
}
if(!Objects.equals("NOT_YET",share.getAuditStatus())){
throw new IllegalArgumentException("参数非法!该分享已审核通过或审核不通过!");
}
//
if(AuditStatusEnum.PASS.equals(auditDTO.getAuditStatusEnum())){
//发送半消息
String transactionId = UUID.randomUUID().toString();
this.rocketMQTemplate.sendMessageInTransaction(
"tx-add-bonus-group",
"add-bonus",
MessageBuilder
.withPayload(
UserAddBonusMsgDTO.builder()
.userId(share.getUserId())
.bonus(50)
.build()
)
//header也有妙用
.setHeader(RocketMQHeaders.TRANSACTION_ID, transactionId)
.setHeader("share-id",id)
.build(),
auditDTO
);
}else{
this.auditByIdInDB(id,auditDTO);
}
//2.审核资源,将状态设为PASS/REJECT
/*share.setAuditStatus(auditDTO.getAuditStatusEnum().toString());
this.shareMapper.updateByPrimaryKey(share);*/
//3.如果是PASS,那么发消息给rocketmq,让用户中心去消费,并为发布人添加积分
//异步执行 缩短整个接口的相应耗时,提升用户体验
/*this.rocketMQTemplate.convertAndSend(
"add-bonus",
UserAddBonusMsgDTO.builder()
.userId(share.getUserId())
.bonus(50)
.build()
);*/
//4. 把share写到缓存里面
return share;
}
@Transactional(rollbackFor = Exception.class)
public void auditByIdInDB(Integer id,ShareAuditDTO auditDTO){
Share share = Share.builder()
.id(id)
.auditStatus(auditDTO.getAuditStatusEnum().toString())
.reason(auditDTO.getReason())
.build();
this.shareMapper.updateByPrimaryKeySelective(share);
//4. 把share写到缓存里面
}
@Transactional(rollbackFor = Exception.class)
public void auditByIdWithRocketMqLog(Integer id,ShareAuditDTO auditDTO,String transactionId){
this.auditByIdInDB(id,auditDTO);
this.rocketmqTransactionLogMapper.insertSelective(
RocketmqTransactionLog.builder()
.transactionId(transactionId)
.log("审核分享...")
.build()
);
}
}
面向未来微服务:熟练掌握Spring Cloud Alibaba
了解课程