Commit 84788a56 authored by tangtuo's avatar tangtuo

新增转让nft功能的接口

parent d32e3b4d
......@@ -41,6 +41,9 @@ public class CommemorateNft {
@ApiModelProperty("名称")
private String name;
@ApiModelProperty("封面")
private String cover;
@NotBlank(message = "简介不能为空")
@Length(max = 500, message = "简介最大长度为500")
@ApiModelProperty("简介")
......
......@@ -19,9 +19,15 @@ public class CommemorateNftVo {
@ApiModelProperty("主键")
private Integer id;
@ApiModelProperty("类目")
private String category;
@ApiModelProperty("名称")
private String name;
@ApiModelProperty("封面")
private String cover;
@ApiModelProperty("发行人")
private String publisher;
......@@ -59,6 +65,7 @@ public class CommemorateNftVo {
this.nftHash = nft.getNftHash();
this.publishTime = nft.getPublishTime();
this.synopsis = nft.getSynopsis();
this.cover = nft.getCover();
}
}
package com.fzm.common.entity.vo;
import cn.hutool.core.date.DateUtil;
import com.fzm.common.entity.Nft;
import com.fzm.common.entity.User;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author tangtuo
* @date 2021/7/1 10:35
*/
@Data
public class NftTransferVo {
@ApiModelProperty("nft主键")
private Integer id;
@ApiModelProperty("nft名称")
private String name;
@ApiModelProperty("转出人的用户id")
private Integer userId;
@ApiModelProperty("转出人的头像")
private String avatar;
@ApiModelProperty("转出人的昵称")
private String nickname;
@ApiModelProperty("转出人的钱包地址")
private String wallet;
@ApiModelProperty("nft编号")
private String nftId;
public NftTransferVo(Nft nft, User user) {
this.id = nft.getId();
this.name = nft.getName();
this.userId = user.getId();
this.avatar = user.getAvatar();
this.wallet = user.getWallet();
this.nickname = user.getNickname();
this.nftId=nft.getNftId();
}
}
package com.fzm.common.params;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* @author tangtuo
* @date 2021/7/21 17:45
*/
@Data
public class NftTransferParam {
@ApiModelProperty("nft主键")
@NotNull(message = "nft主键不能为空")
private Integer id;
@ApiModelProperty("验证码")
@NotBlank(message = "验证码不能为空")
private String code;
@ApiModelProperty("短信验证码类型 sms-短信 email-邮箱 voice-语音")
@NotNull(message = "短信验证码类型不能为空")
private String codeType;
@ApiModelProperty("接收人地址")
@NotBlank(message = "接收人地址不能为空")
private String receiveWallet;
@ApiModelProperty("接收人")
@NotBlank(message = "接收人不能为空")
private String receiveNickname;
@ApiModelProperty("数量")
@NotNull(message = "数量不能为空")
private Integer count;
}
......@@ -5,6 +5,7 @@ import com.fzm.common.entity.Nft;
import com.fzm.common.entity.NftDto;
import com.fzm.common.entity.vo.CollectionNftVo;
import com.fzm.common.entity.vo.NftListVo;
import com.fzm.common.params.NftTransferParam;
import com.github.pagehelper.PageInfo;
import java.util.List;
......@@ -126,4 +127,12 @@ public interface NftService extends IService<Nft> {
* @return
*/
Boolean publish(NftDto nftDto);
/**
* nft转让
*
* @param param
* @return
*/
Boolean transfer(NftTransferParam param);
}
......@@ -17,14 +17,13 @@ import com.fzm.common.entity.vo.NftListVo;
import com.fzm.common.enums.ResultCode;
import com.fzm.common.exception.GlobalException;
import com.fzm.common.mapper.NftMapper;
import com.fzm.common.params.NftTransferParam;
import com.fzm.common.properties.SmsProperties;
import com.fzm.common.service.CategoryService;
import com.fzm.common.service.CollectionService;
import com.fzm.common.service.NftService;
import com.fzm.common.service.UserService;
import com.fzm.common.utils.JsonUtil;
import com.fzm.common.utils.JwtUtil;
import com.fzm.common.utils.OssUtil;
import com.fzm.common.utils.RedisUtil;
import com.fzm.common.utils.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
......@@ -71,6 +70,11 @@ public class NftServiceImpl extends ServiceImpl<NftMapper, Nft> implements NftSe
private OssUtil ossUtil;
@Resource
private SmsUtil smsUtil;
private SmsProperties smsProperties;
@Resource
private HttpServletRequest request;
@Value("${chain.para.contract-name}")
......@@ -138,6 +142,46 @@ public class NftServiceImpl extends ServiceImpl<NftMapper, Nft> implements NftSe
return true;
}
@Override
public Boolean transfer(NftTransferParam param) {
Nft nft = getById(param.getId());
if (nft == null) {
throw GlobalException.newException(ResultCode.DATA_ERROR, "没找到此nft详情");
}
// 转出人的个人信息
User user = userService.getUserByToken();
if (!nft.getUserId().equals(user.getId())) {
throw GlobalException.newException(ResultCode.FORBIDDEN, "您无权转让他人的nft");
}
// 校验短信验证码
// todo 现在用的是登录验证码模板,后续需要修改短信模板
if (!smsUtil.validateCode(smsProperties.getMessageLoginCodetype(), user.getTelephone(), param.getCode(), param.getCodeType())) {
throw GlobalException.newException(ResultCode.FAILED, "短信验证码校验失败");
}
// 校验接收人的个人信息
User receiveUser = userService.getUserByWallet(param.getReceiveWallet());
if (receiveUser == null) {
throw GlobalException.newException(ResultCode.FAILED, "接手人非本系统注册用户,暂不支持转让");
}
// 转让nft
String hash = paraChainClient.evmTransferNFT1155(contractName, user.getWallet(), null, param.getReceiveWallet(), nft.getTokenId(), param.getCount(), true);
if (StringUtils.isBlank(hash)) {
throw GlobalException.newException(ResultCode.FAILED, "nft领取失败");
}
// 确认转让结果
TxResult txResult = paraChainClient.cycleConfirmTxWithHash(hash, true, 1000);
if (!TxStatusEnum.SUCCESS.equals(txResult.getStatus())) {
throw GlobalException.newException(ResultCode.PUBLISH_ERROR, txResult.getErrMsg().getValue());
}
// 修改nft的拥有者用户id
Nft transferNft = new Nft().
setUserId(receiveUser.getId()).
setTransferHash(hash);
transferNft.setId(nft.getId());
updateById(transferNft);
return true;
}
public Boolean checkResult(String nftHash) {
TxResult txResult = paraChainClient.confirmTxWithGrpTxHash(nftHash);
if (TxStatusEnum.RUNNING.equals(txResult.getStatus())) {
......
......@@ -10,6 +10,7 @@ import com.fzm.common.entity.vo.CommemorateNftVo;
import com.fzm.common.enums.ResultCode;
import com.fzm.common.exception.GlobalException;
import com.fzm.common.model.ResponseModel;
import com.fzm.common.service.CategoryService;
import com.fzm.common.service.CommemorateNftService;
import com.fzm.common.service.LabelService;
import com.fzm.common.service.UserService;
......@@ -27,6 +28,7 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
/**
* @author tangtuo
......@@ -47,6 +49,9 @@ public class CommemorateNftController {
private UserService userService;
@Resource
private CategoryService categoryService;
@Resource
private RedissonClient redisson;
@Resource
......@@ -59,17 +64,24 @@ public class CommemorateNftController {
@ApiParam(value = "作品简介", required = true) String synopsis,
@ApiParam(value = "类目id", required = true) Integer categoryId,
@ApiParam(value = "文件", required = true) MultipartFile file,
@ApiParam(value = "封面", required = true) MultipartFile cover,
@ApiParam(value = "发行数量", required = true) Integer count) throws IOException {
if (file == null) {
if (file == null || cover == null) {
throw GlobalException.newException(ResultCode.VALIDATE_FAILED, "文件不能为空");
}
String url = ossUtil.putSimpleObject(file);
String coverName = cover.getOriginalFilename().toLowerCase();
if (!coverName.endsWith(".png") && !coverName.endsWith(".jpg")) {
throw GlobalException.newException(ResultCode.FILE_UPLOAD_ERROR, "封面类型有误");
}
String fileUrl = ossUtil.putSimpleObject(file);
String coverUrl = ossUtil.putSimpleObject(cover);
CommemorateNft commemorateNft = new CommemorateNft().
setName(name).
setCover(coverUrl).
setCount(count).
setSynopsis(synopsis).
setFileName(file.getOriginalFilename()).
setFileUrl(url).
setFileUrl(fileUrl).
setCategoryId(categoryId).
setFileHash(SecureUtil.md5(file.getInputStream()));
Integer id = commemorateNftService.publish(commemorateNft);
......@@ -94,6 +106,7 @@ public class CommemorateNftController {
}
User user = userService.getById(nft.getUserId());
CommemorateNftVo commemorateNftVo = new CommemorateNftVo(nft, user);
commemorateNftVo.setCategory(categoryService.getById(nft.getCategoryId()).getCategoryName());
RSemaphore semaphore = redisson.getSemaphore(RedisConstant.COMMEMORATE_NFT_PREFIX + id);
int permits = semaphore.availablePermits();
commemorateNftVo.setReceiveCount(nft.getCount() - permits);
......
......@@ -10,10 +10,12 @@ import com.fzm.common.entity.NftDto;
import com.fzm.common.entity.User;
import com.fzm.common.entity.vo.CollectionNftVo;
import com.fzm.common.entity.vo.NftCertificateVo;
import com.fzm.common.entity.vo.NftTransferVo;
import com.fzm.common.entity.vo.NftVo;
import com.fzm.common.enums.ResultCode;
import com.fzm.common.exception.GlobalException;
import com.fzm.common.model.ResponseModel;
import com.fzm.common.params.NftTransferParam;
import com.fzm.common.service.CategoryService;
import com.fzm.common.service.NftService;
import com.fzm.common.service.UserService;
......@@ -46,9 +48,6 @@ import java.util.stream.Collectors;
public class NftController {
@Resource
private OssUtil ossUtil;
@Resource
private NftService nftService;
@Resource
......@@ -190,4 +189,26 @@ public class NftController {
public void download(@ApiParam(value = "nft主键") @PathVariable Integer id) {
nftService.download(id);
}
@Authentication
@ApiOperation(value = "查询nft转出人的个人信息")
@GetMapping("/transfer/user")
public ResponseModel<NftTransferVo> getTransferUserInfo(@RequestParam Integer id) {
Nft nft = nftService.getById(id);
if (nft == null) {
throw GlobalException.newException(ResultCode.DATA_ERROR, "没有找到此nft的详情信息,请稍后再试");
}
User user = userService.getById(nft.getUserId());
return ResponseModel.success(new NftTransferVo(nft, user));
}
@Authentication
@ApiOperation(value = "转让nft")
@PostMapping("/transfer")
public ResponseModel<Boolean> transfer(@RequestBody @Validated NftTransferParam param) {
Boolean result = nftService.transfer(param);
return ResponseModel.success(result);
}
}
......@@ -137,4 +137,11 @@ public class UserController {
return ResponseModel.success();
}
@Authentication
@ApiOperation("根据钱包地址获取用户详情")
@GetMapping("/getUserByWallet")
public ResponseModel<User> getUserByWallet(@RequestParam String wallet) {
User user = userService.getUserByWallet(wallet);
return ResponseModel.success(user);
}
}
package com.fzm.portal.controller;
import com.fzm.common.annotation.Authentication;
import com.fzm.common.entity.User;
import com.fzm.common.enums.ResultCode;
import com.fzm.common.exception.GlobalException;
import com.fzm.common.model.ResponseModel;
import com.fzm.common.properties.SmsProperties;
import com.fzm.common.service.UserService;
import com.fzm.common.utils.SmsUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
......@@ -26,12 +30,14 @@ import javax.annotation.Resource;
public class VerificationCodeController {
@Resource
private UserService userService;
@Resource
private SmsProperties smsProperties;
@Resource
private SmsUtil sendSms;
private SmsUtil smsUtil;
@PostMapping(value = "/send/sms")
......@@ -41,7 +47,19 @@ public class VerificationCodeController {
@ApiImplicitParam(name = "codetype", value = "短信模板, 1:登录短信 2:修改密码 3:修改手机号"),
})
public ResponseModel<Boolean> sendSms(@RequestParam String telephone, @RequestParam Integer codetype) {
return ResponseModel.success(sendSms.sendSms(getCodeType(codetype), telephone));
return ResponseModel.success(smsUtil.sendSms(getCodeType(codetype), telephone));
}
@Authentication
@ApiOperation("发送转让nft的短信")
@PostMapping("/send/Sms/transferNft")
public ResponseModel<Boolean> sendTransferNftSms() {
User user = userService.getUserByToken();
if (user == null || StringUtils.isBlank(user.getTelephone())) {
throw GlobalException.newException(ResultCode.UNAUTHORIZED, "当前用户的手机号为空");
}
Boolean result = smsUtil.sendSms(smsProperties.getMessageLoginCodetype(), user.getTelephone());
return ResponseModel.success(result);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment