Commit 1faa50c7 authored by tangtuo's avatar tangtuo

收费管理

parent 83c576d0
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>fzm-joying</artifactId> <artifactId>fzm-joying</artifactId>
<groupId>com.fzm</groupId> <groupId>com.fzm</groupId>
<version>1.0.0</version> <version>1.1.0</version>
</parent> </parent>
<artifactId>joying-admin</artifactId> <artifactId>joying-admin</artifactId>
......
package com.fzm.admin.controller;
import com.fzm.common.annotation.Authentication;
import com.fzm.common.entity.Charge;
import com.fzm.common.model.ResponseModel;
import com.fzm.common.service.ChargeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* @author tangtuo
* @date 2022/1/25 10:13
*/
@Authentication
@RestController
@RequestMapping(value = "/charge")
@Api(tags = "收费管理")
public class ChargeController {
@Resource
private ChargeService chargeService;
@PostMapping("/update")
@ApiOperation("编辑")
public ResponseModel<String> update(@RequestBody Charge charge) {
chargeService.updateById(charge);
return ResponseModel.success("编辑成功");
}
@GetMapping("/detail/{type}")
@ApiOperation("根据收费类型获取详情")
public ResponseModel<Charge> getByType(@ApiParam("收费类型 1-nft发行 2-版权申请") @PathVariable Integer type) {
Charge charge = chargeService.getByType(type);
return ResponseModel.success(charge);
}
}
package com.fzm.common.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author tangtuo
* @date 2022/1/25 10:07
*/
@Data
@TableName("tb_charge")
public class Charge {
@TableId(type = IdType.AUTO)
private Integer id;
@ApiModelProperty("收费金额")
private Long fee;
@ApiModelProperty("收费类型 1-nft发行 2-版权申请")
private Integer type;
}
...@@ -73,6 +73,9 @@ public class Nft extends BaseEntity { ...@@ -73,6 +73,9 @@ public class Nft extends BaseEntity {
@ApiModelProperty("nft发行时间") @ApiModelProperty("nft发行时间")
private Date publishTime; private Date publishTime;
@ApiModelProperty("发行状态 0-待支付 1-发行中 2-发行成功 3-发行失败")
private Integer publishStatus;
@ApiModelProperty("交易转让hash") @ApiModelProperty("交易转让hash")
private String transferHash; private String transferHash;
......
...@@ -24,12 +24,12 @@ public class Payment { ...@@ -24,12 +24,12 @@ public class Payment {
@ApiModelProperty("交易类型") @ApiModelProperty("交易类型")
private String tradeType; private String tradeType;
@ApiModelProperty("交易状态")
private String tradeState;
@ApiModelProperty("支付金额(分)") @ApiModelProperty("支付金额(分)")
private Integer totalFee; private Integer totalFee;
@ApiModelProperty("是否有退款, 0-否 1-是")
private Integer isRefund;
@ApiModelProperty("商品订单编号") @ApiModelProperty("商品订单编号")
private String successTime; private String successTime;
......
package com.fzm.common.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@Data
@TableName("tb_refund")
public class Refund {
private Long id;
@ApiModelProperty("商品订单编号")
private Long orderId;
@ApiModelProperty("支付系统交易编号")
private String transactionId;
@ApiModelProperty("状态")
private String refundId;
@ApiModelProperty("退款状态 1- 退款中 2-退款成功 3-退款失败")
private Integer refundStatus;
@ApiModelProperty("当前退款单的退款入账方")
private String userReceivedAccount;
@ApiModelProperty("支付金额(分)")
private Long fee;
@ApiModelProperty("商品订单编号")
private String successTime;
@ApiModelProperty("通知参数")
private String content;
private Date createDate;
private Date updateDate;
}
\ No newline at end of file
...@@ -13,6 +13,8 @@ import lombok.NoArgsConstructor; ...@@ -13,6 +13,8 @@ import lombok.NoArgsConstructor;
@AllArgsConstructor @AllArgsConstructor
public class OrderProcessMsg { public class OrderProcessMsg {
private Long orderId;
private Integer productId; private Integer productId;
private Integer payScene; private Integer payScene;
......
package com.fzm.common.entity.vo;
/**
* @author tangtuo
* @date 2022/1/24 16:44
*/
public class OrderVo {
private Long id;
}
package com.fzm.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author tangtuo
* @date 2022/1/24 17:19
*
* <p>
* nft发行状态
* </p>
*/
@Getter
@AllArgsConstructor
public enum PublishStatus {
TO_BE_PAY(0, "待支付"),
PUBLISHING(1, "发行中"),
SUSSED(2, "发行成功"),
FAILED(3, "发行失败");
private Integer code;
private String type;
}
package com.fzm.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author tangtuo
* @date 2022/1/24 15:02
*/
@Getter
@AllArgsConstructor
public enum RefundStatus {
REFUNDING(1),
SUCCESS(2),
FAINED(3),
;
private Integer status;
}
package com.fzm.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author tangtuo
* @date 2022/1/24 11:03
*/
@AllArgsConstructor
@Getter
public enum WxPayStatus {
SUCCESS("SUCCESS", "支付成功"),
REFUND("REFUND", "转入退款"),
NOTPAY("NOTPAY", "未支付"),
CLOSED("CLOSED", "已关闭"),
REVOKED("REVOKED", "已撤销(仅付款码支付会返回)"),
USERPAYING("USERPAYING", "用户支付中(仅付款码支付会返回)"),
PAYERROR("PAYERROR", "支付失败(仅付款码支付会返回)");
private String status;
private String desc;
}
package com.fzm.common.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fzm.common.entity.Charge;
import org.apache.ibatis.annotations.Mapper;
/**
* @author tangtuo
* @date 2022/1/25 10:10
*/
@Mapper
public interface ChargeMapper extends BaseMapper<Charge> {
}
package com.fzm.common.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fzm.common.entity.Refund;
import org.apache.ibatis.annotations.Mapper;
/**
* @author tangtuo
* @date 2022/1/24 14:27
*/
@Mapper
public interface RefundMapper extends BaseMapper<Refund> {
}
package com.fzm.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.fzm.common.entity.Charge;
/**
* @author tangtuo
* @date 2022/1/25 10:10
*/
public interface ChargeService extends IService<Charge> {
/**
* 根据收费类型获取详情
*
* @param type
* @return
*/
Charge getByType(Integer type);
}
...@@ -64,7 +64,7 @@ public interface CopyrightApplyService extends IService<CopyrightApply> { ...@@ -64,7 +64,7 @@ public interface CopyrightApplyService extends IService<CopyrightApply> {
* *
* @param copyrightDTO * @param copyrightDTO
*/ */
Boolean update(CopyrightDTO copyrightDTO); Integer update(CopyrightDTO copyrightDTO);
/** /**
* 分页查询 * 分页查询
......
...@@ -176,4 +176,10 @@ public interface NftService extends IService<Nft> { ...@@ -176,4 +176,10 @@ public interface NftService extends IService<Nft> {
* @param isEntrust * @param isEntrust
*/ */
void updateEntrust(String nftHash, Integer isEntrust); void updateEntrust(String nftHash, Integer isEntrust);
/**
* 删除
* @param id
*/
void delete(Integer id);
} }
...@@ -5,6 +5,8 @@ import com.fzm.common.entity.Order; ...@@ -5,6 +5,8 @@ import com.fzm.common.entity.Order;
import com.fzm.common.entity.dto.OrderDto; import com.fzm.common.entity.dto.OrderDto;
import com.fzm.common.enums.OrderStatus; import com.fzm.common.enums.OrderStatus;
import java.util.List;
/** /**
* @author tangtuo * @author tangtuo
* @date 2022/1/19 15:41 * @date 2022/1/19 15:41
...@@ -18,7 +20,7 @@ public interface OrderService extends IService<Order> { ...@@ -18,7 +20,7 @@ public interface OrderService extends IService<Order> {
* @param productId * @param productId
* @return * @return
*/ */
Order getByPaySceneAndProductId(Integer payScene, Integer productId); Order getByPaySceneAndProductId(Integer payScene, Integer productId, Integer orderStatus);
/** /**
* 更新订单状态 * 更新订单状态
...@@ -30,15 +32,34 @@ public interface OrderService extends IService<Order> { ...@@ -30,15 +32,34 @@ public interface OrderService extends IService<Order> {
/** /**
* 下单 * 下单
*
* @param orderDto * @param orderDto
* @return * @return
*/ */
Long createOrder(OrderDto orderDto); Long createOrder(OrderDto orderDto);
/** /**
*
* @param orderId * @param orderId
* @param payType * @param payType
*/ */
Boolean updatePayType(Long orderId, Integer payType); Boolean updatePayType(Long orderId, Integer payType);
/**
* 取消订单
*
* @param orderId
* @param orderStatus
* @return
*/
Boolean cancel(Long orderId, OrderStatus orderStatus);
/**
* 获取我的订单
*
* @param payScene
* @return
*/
List<Order> listOrder(Integer payScene);
void processOrder(Long orderId, Integer productId, Integer payScene);
} }
...@@ -8,4 +8,6 @@ import com.fzm.common.entity.Payment; ...@@ -8,4 +8,6 @@ import com.fzm.common.entity.Payment;
* @date 2022/1/20 16:40 * @date 2022/1/20 16:40
*/ */
public interface PaymentService extends IService<Payment> { public interface PaymentService extends IService<Payment> {
Payment getByOrderId(Long orderId);
} }
package com.fzm.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.fzm.common.entity.Refund;
/**
* @author tangtuo
* @date 2022/1/24 14:26
*/
public interface RefundService extends IService<Refund> {
}
...@@ -33,9 +33,9 @@ public interface WxPayService { ...@@ -33,9 +33,9 @@ public interface WxPayService {
* *
* @param jsonObject * @param jsonObject
*/ */
void processOrder(JSONObject jsonObject) throws GeneralSecurityException; void processOrder(JSONObject jsonObject) throws GeneralSecurityException, InterruptedException;
String queryOrder(Long orderId); String queryOrder(Long orderId) throws IOException;
/** /**
* 退款 * 退款
...@@ -57,5 +57,5 @@ public interface WxPayService { ...@@ -57,5 +57,5 @@ public interface WxPayService {
* *
* @param jsonObject * @param jsonObject
*/ */
void processRefund(JSONObject jsonObject); void processRefund(JSONObject jsonObject) throws InterruptedException;
} }
package com.fzm.common.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzm.common.entity.Charge;
import com.fzm.common.mapper.ChargeMapper;
import com.fzm.common.service.ChargeService;
import org.springframework.stereotype.Service;
/**
* @author tangtuo
* @date 2022/1/25 10:11
*/
@Service
public class ChargeServiceImpl extends ServiceImpl<ChargeMapper, Charge> implements ChargeService {
@Override
public Charge getByType(Integer type) {
QueryWrapper<Charge> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("type", type);
return getOne(queryWrapper);
}
}
...@@ -249,7 +249,7 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper, ...@@ -249,7 +249,7 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper,
} }
@Override @Override
public Boolean update(CopyrightDTO copyrightDTO) { public Integer update(CopyrightDTO copyrightDTO) {
// 只有撤回 驳回和登记失败的才能编辑 // 只有撤回 驳回和登记失败的才能编辑
CopyrightApply copyright = this.getById(copyrightDTO.getId()); CopyrightApply copyright = this.getById(copyrightDTO.getId());
if (CopyrightApplyState.REJECTED.getCode() != copyright.getRegisterState() && if (CopyrightApplyState.REJECTED.getCode() != copyright.getRegisterState() &&
...@@ -304,7 +304,8 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper, ...@@ -304,7 +304,8 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper,
} }
copyrightApply.setApplyTime(new Date()); copyrightApply.setApplyTime(new Date());
copyrightApply.setRegisterState(CopyrightApplyState.TO_BE_PAY.getCode()); copyrightApply.setRegisterState(CopyrightApplyState.TO_BE_PAY.getCode());
return updateById(copyrightApply); this.updateById(copyrightApply);
return copyrightDTO.getId();
} }
@Override @Override
......
...@@ -20,6 +20,7 @@ import com.fzm.common.entity.vo.CopyrightVo; ...@@ -20,6 +20,7 @@ import com.fzm.common.entity.vo.CopyrightVo;
import com.fzm.common.entity.vo.NftListVo; import com.fzm.common.entity.vo.NftListVo;
import com.fzm.common.entity.vo.NftVo; import com.fzm.common.entity.vo.NftVo;
import com.fzm.common.enums.AuthStatus; import com.fzm.common.enums.AuthStatus;
import com.fzm.common.enums.PublishStatus;
import com.fzm.common.enums.ResultCode; import com.fzm.common.enums.ResultCode;
import com.fzm.common.exception.GlobalException; import com.fzm.common.exception.GlobalException;
import com.fzm.common.mapper.NftMapper; import com.fzm.common.mapper.NftMapper;
...@@ -96,12 +97,18 @@ public class NftServiceImpl extends ServiceImpl<NftMapper, Nft> implements NftSe ...@@ -96,12 +97,18 @@ public class NftServiceImpl extends ServiceImpl<NftMapper, Nft> implements NftSe
@Resource @Resource
private CopyrightApplyService copyrightApplyService; private CopyrightApplyService copyrightApplyService;
@Resource
private ObsUtil obsUtil;
//private static String abi = "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"}],\"name\":\"TransferBatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"TransferSingle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"URI\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"}],\"name\":\"balanceOfBatch\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"name\":\"burnTokenBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getTokenInfo\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"getUserTokens\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mintToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"name\":\"mintTokenBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeBatchTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"tokenInfo\",\"type\":\"string\"}],\"name\":\"setTokenInfo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"uri\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]"; //private static String abi = "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"}],\"name\":\"TransferBatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"TransferSingle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"URI\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"}],\"name\":\"balanceOfBatch\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"name\":\"burnTokenBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getTokenInfo\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"getUserTokens\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mintToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"name\":\"mintTokenBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeBatchTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"tokenInfo\",\"type\":\"string\"}],\"name\":\"setTokenInfo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"uri\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]";
private static String abi = "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"}],\"name\":\"TransferBatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"TransferSingle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"URI\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"}],\"name\":\"balanceOfBatch\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"name\":\"burnTokenBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getTokenInfo\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"getUserTokens\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mintToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"name\":\"mintTokenBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeBatchTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"tokenInfo\",\"type\":\"string\"}],\"name\":\"setTokenInfo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"uri\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]"; private static String abi = "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"}],\"name\":\"TransferBatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"TransferSingle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"URI\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"}],\"name\":\"balanceOfBatch\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"name\":\"burnTokenBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getTokenInfo\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"getUserTokens\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mintToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"name\":\"mintTokenBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeBatchTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"tokenInfo\",\"type\":\"string\"}],\"name\":\"setTokenInfo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"uri\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]";
@Override @Override
public Integer saveNft(Nft nft) { public Integer saveNft(Nft nft) {
User user = userService.getUserByToken(); User user = userService.getUserByToken();
if (!AuthStatus.SUCCESS.getStatus().equals(user.getAuthStatus())) {
throw GlobalException.newException(ResultCode.PUBLISH_ERROR, "您还未实名认证,请先实名认证");
}
nft.setUserId(user.getId()); nft.setUserId(user.getId());
nft.setPublishAddress(user.getWallet()); nft.setPublishAddress(user.getWallet());
save(nft); save(nft);
...@@ -112,9 +119,6 @@ public class NftServiceImpl extends ServiceImpl<NftMapper, Nft> implements NftSe ...@@ -112,9 +119,6 @@ public class NftServiceImpl extends ServiceImpl<NftMapper, Nft> implements NftSe
public Integer publish(Integer id) { public Integer publish(Integer id) {
Nft nft = getById(id); Nft nft = getById(id);
User user = userService.getUserByWallet(nft.getPublishAddress()); User user = userService.getUserByWallet(nft.getPublishAddress());
if (!AuthStatus.SUCCESS.getStatus().equals(user.getAuthStatus())) {
throw GlobalException.newException(ResultCode.PUBLISH_ERROR, "您还未实名认证,请先实名认证");
}
String wallet = user.getWallet(); String wallet = user.getWallet();
// 获取用户的私钥 // 获取用户的私钥
String privkey = paraChainClient.walletDumpPrivkey(wallet); String privkey = paraChainClient.walletDumpPrivkey(wallet);
...@@ -139,7 +143,10 @@ public class NftServiceImpl extends ServiceImpl<NftMapper, Nft> implements NftSe ...@@ -139,7 +143,10 @@ public class NftServiceImpl extends ServiceImpl<NftMapper, Nft> implements NftSe
if (StringUtils.isBlank(tradeHash)) { if (StringUtils.isBlank(tradeHash)) {
throw GlobalException.newException(ResultCode.PUBLISH_ERROR, "nft发行失败"); throw GlobalException.newException(ResultCode.PUBLISH_ERROR, "nft发行失败");
} }
// 给mq发送一条消息,异步确认交易结果 // 修改nft的发行状态为发行中
nft.setPublishStatus(PublishStatus.PUBLISHING.getCode());
this.updateById(nft);
// 给mq发送一条消息,异步确认发行结果
NftPublishMsg nftPublishMsg = new NftPublishMsg(hash, id, tokenId); NftPublishMsg nftPublishMsg = new NftPublishMsg(hash, id, tokenId);
rabbitTemplate.convertAndSend("nft-exchange", "nft.publish", nftPublishMsg); rabbitTemplate.convertAndSend("nft-exchange", "nft.publish", nftPublishMsg);
return nft.getId(); return nft.getId();
...@@ -242,6 +249,15 @@ public class NftServiceImpl extends ServiceImpl<NftMapper, Nft> implements NftSe ...@@ -242,6 +249,15 @@ public class NftServiceImpl extends ServiceImpl<NftMapper, Nft> implements NftSe
this.update(nft, wrapper); this.update(nft, wrapper);
} }
@Override
public void delete(Integer id) {
Nft nft = this.getById(id);
if (nft != null && StringUtils.isNotBlank(nft.getCover())) {
obsUtil.delete(nft.getCover());
}
this.removeById(id);
}
private String getCodeType(String type) { private String getCodeType(String type) {
switch (type) { switch (type) {
case "sms": case "sms":
......
...@@ -4,20 +4,22 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; ...@@ -4,20 +4,22 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzm.common.entity.Order; import com.fzm.common.entity.Order;
import com.fzm.common.entity.dto.OrderDto; import com.fzm.common.entity.dto.OrderDto;
import com.fzm.common.entity.dto.OrderProcessMsg;
import com.fzm.common.enums.OrderStatus; import com.fzm.common.enums.OrderStatus;
import com.fzm.common.enums.PayScene; import com.fzm.common.enums.PayScene;
import com.fzm.common.enums.PayType;
import com.fzm.common.mapper.OrderMapper; import com.fzm.common.mapper.OrderMapper;
import com.fzm.common.service.CopyrightApplyService; import com.fzm.common.service.CopyrightApplyService;
import com.fzm.common.service.NftService; import com.fzm.common.service.NftService;
import com.fzm.common.service.OrderService; import com.fzm.common.service.OrderService;
import com.fzm.common.utils.JwtUtil; import com.fzm.common.utils.JwtUtil;
import com.fzm.common.utils.SnowflakeUtil; import com.fzm.common.utils.SnowflakeUtil;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.List;
/** /**
* @author tangtuo * @author tangtuo
...@@ -39,11 +41,15 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements ...@@ -39,11 +41,15 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
@Resource @Resource
private HttpServletRequest request; private HttpServletRequest request;
@Resource
private RabbitTemplate rabbitTemplate;
@Override @Override
public Order getByPaySceneAndProductId(Integer payScene, Integer productId) { public Order getByPaySceneAndProductId(Integer payScene, Integer productId, Integer orderStatus) {
QueryWrapper<Order> queryWrapper = new QueryWrapper<>(); QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("pay_scene", payScene) queryWrapper.eq("pay_scene", payScene)
.eq("product_id", productId); .eq("product_id", productId)
.eq("order_status", orderStatus);
return this.getOne(queryWrapper); return this.getOne(queryWrapper);
} }
...@@ -61,19 +67,28 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements ...@@ -61,19 +67,28 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
long id = snowflakeUtil.snowflakeId(); long id = snowflakeUtil.snowflakeId();
Integer productId = orderDto.getProductId(); Integer productId = orderDto.getProductId();
String orderName; String orderName;
if (PayScene.NFT.getCode().equals(orderDto.getPayScene())) { Integer payScene = orderDto.getPayScene();
if (PayScene.NFT.getCode().equals(payScene)) {
orderName = nftService.getById(productId).getName(); orderName = nftService.getById(productId).getName();
} else { } else {
orderName = copyrightApplyService.getById(productId).getOpusName(); orderName = copyrightApplyService.getById(productId).getOpusName();
} }
order.setId(id); order.setId(id);
order.setOrderName(orderName); order.setOrderName(orderName);
order.setPayScene(orderDto.getPayScene()); order.setPayScene(payScene);
order.setOrderName(orderName); order.setOrderName(orderName);
order.setFee(orderDto.getFee()); order.setFee(orderDto.getFee());
order.setProductId(productId); order.setProductId(productId);
order.setUserId(JwtUtil.getUserIdFromToken(request.getHeader("Authorization"))); order.setUserId(JwtUtil.getUserIdFromToken(request.getHeader("Authorization")));
order.setOrderStatus(OrderStatus.PAYING.getStatus()); Integer orderStatus;
if (orderDto.getFee() > 0) {
orderStatus = OrderStatus.PAYING.getStatus();
} else {
// 订单金额为0的话,创建订单时,状态为支付成功
orderStatus = OrderStatus.PAYED.getStatus();
processOrder(id, productId, payScene);
}
order.setOrderStatus(orderStatus);
this.save(order); this.save(order);
return id; return id;
} }
...@@ -85,4 +100,37 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements ...@@ -85,4 +100,37 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
o.setPayType(payType); o.setPayType(payType);
return updateById(o); return updateById(o);
} }
@Override
public Boolean cancel(Long orderId, OrderStatus orderStatus) {
Order order = this.getById(orderId);
Integer productId = order.getProductId();
// 判断订单的类型
if (PayScene.NFT.getCode().equals(order.getPayScene())) {
// 删除nft的相关信息
nftService.delete(productId);
} else {
// 删除版权申请的相关信息
copyrightApplyService.delete(productId);
}
// 修改订单状态为取消
this.updateOrderStatus(orderId, orderStatus);
return true;
}
@Override
public List<Order> listOrder(Integer payScene) {
Integer userId = JwtUtil.getUserIdFromToken(request.getHeader("Authorization"));
QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("pay_scene", payScene);
queryWrapper.eq("user_id", userId);
return this.list(queryWrapper);
}
@Override
public void processOrder(Long orderId, Integer productId, Integer payScene) {
// 订单支付成功后,给mq发送一条消息,处理nft发行或版权申请的状态
OrderProcessMsg orderProcessMsg = new OrderProcessMsg(orderId, productId, payScene);
rabbitTemplate.convertAndSend("order-exchange", "order.process", orderProcessMsg);
}
} }
package com.fzm.common.service.impl; package com.fzm.common.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzm.common.entity.Payment; import com.fzm.common.entity.Payment;
import com.fzm.common.mapper.PaymentMapper; import com.fzm.common.mapper.PaymentMapper;
...@@ -14,4 +15,11 @@ import org.springframework.transaction.annotation.Transactional; ...@@ -14,4 +15,11 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
@Transactional(rollbackFor = RuntimeException.class) @Transactional(rollbackFor = RuntimeException.class)
public class PaymentServiceImpl extends ServiceImpl<PaymentMapper, Payment> implements PaymentService { public class PaymentServiceImpl extends ServiceImpl<PaymentMapper, Payment> implements PaymentService {
@Override
public Payment getByOrderId(Long orderId) {
QueryWrapper<Payment> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("order_id", orderId);
return getOne(queryWrapper);
}
} }
package com.fzm.common.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzm.common.entity.Refund;
import com.fzm.common.mapper.RefundMapper;
import com.fzm.common.service.RefundService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @author tangtuo
* @date 2022/1/24 14:27
*/
@Service
@Transactional(rollbackFor = RuntimeException.class)
public class RefundServiceImpl extends ServiceImpl<RefundMapper, Refund> implements RefundService {
}
...@@ -5,8 +5,10 @@ import cn.hutool.json.JSONObject; ...@@ -5,8 +5,10 @@ import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fzm.common.constant.SystemConstant;
import com.fzm.common.entity.Order; import com.fzm.common.entity.Order;
import com.fzm.common.entity.Payment; import com.fzm.common.entity.Payment;
import com.fzm.common.entity.Refund;
import com.fzm.common.entity.dto.JsapiPayDto; import com.fzm.common.entity.dto.JsapiPayDto;
import com.fzm.common.entity.dto.OrderProcessMsg; import com.fzm.common.entity.dto.OrderProcessMsg;
import com.fzm.common.enums.*; import com.fzm.common.enums.*;
...@@ -18,6 +20,7 @@ import com.wechat.pay.contrib.apache.httpclient.util.AesUtil; ...@@ -18,6 +20,7 @@ import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
...@@ -77,6 +80,9 @@ public class WxPayServiceImpl implements WxPayService { ...@@ -77,6 +80,9 @@ public class WxPayServiceImpl implements WxPayService {
@Resource @Resource
private SnowflakeUtil snowflakeUtil; private SnowflakeUtil snowflakeUtil;
@Resource
private RefundService refundService;
public Map<String, Object> payJsapi(JsapiPayDto jsapiPayDto) throws Exception { public Map<String, Object> payJsapi(JsapiPayDto jsapiPayDto) throws Exception {
RLock lock = redisson.getLock("pay-" + jsapiPayDto.getOrderId()); RLock lock = redisson.getLock("pay-" + jsapiPayDto.getOrderId());
if (!lock.tryLock(10, TimeUnit.SECONDS)) { if (!lock.tryLock(10, TimeUnit.SECONDS)) {
...@@ -177,14 +183,14 @@ public class WxPayServiceImpl implements WxPayService { ...@@ -177,14 +183,14 @@ public class WxPayServiceImpl implements WxPayService {
@Override @Override
public void processOrder(JSONObject jsonObject) { public void processOrder(JSONObject jsonObject) throws InterruptedException {
// 获取订单号 // 获取订单号
Long out_trade_no = jsonObject.getLong("out_trade_no"); Long out_trade_no = jsonObject.getLong("out_trade_no");
// 加锁,避免接口幂等性问题 // 加锁,避免接口幂等性问题
RLock lock = redisson.getLock("pay-notify-" + out_trade_no); RLock lock = redisson.getLock("pay-notify-" + out_trade_no);
lock.lock(10, TimeUnit.SECONDS);
// 修改订单状态 // 修改订单状态
try { try {
if (lock.tryLock(10, TimeUnit.SECONDS)) {
Order order = orderService.getById(out_trade_no); Order order = orderService.getById(out_trade_no);
// 如果订单状态不是待支付,直接返回 // 如果订单状态不是待支付,直接返回
if (!OrderStatus.PAYING.getStatus().equals(order.getOrderStatus())) { if (!OrderStatus.PAYING.getStatus().equals(order.getOrderStatus())) {
...@@ -193,7 +199,7 @@ public class WxPayServiceImpl implements WxPayService { ...@@ -193,7 +199,7 @@ public class WxPayServiceImpl implements WxPayService {
} }
Integer productId = order.getProductId(); Integer productId = order.getProductId();
// 订单支付成功后,给mq发送一条消息,处理nft发行或版权申请的状态 // 订单支付成功后,给mq发送一条消息,处理nft发行或版权申请的状态
OrderProcessMsg orderProcessMsg = new OrderProcessMsg(productId, order.getPayScene()); OrderProcessMsg orderProcessMsg = new OrderProcessMsg(out_trade_no, productId, order.getPayScene());
rabbitTemplate.convertAndSend("order-exchange", "order.process", orderProcessMsg); rabbitTemplate.convertAndSend("order-exchange", "order.process", orderProcessMsg);
// 修改订单状态 // 修改订单状态
orderService.updateOrderStatus(out_trade_no, OrderStatus.PAYED); orderService.updateOrderStatus(out_trade_no, OrderStatus.PAYED);
...@@ -204,9 +210,9 @@ public class WxPayServiceImpl implements WxPayService { ...@@ -204,9 +210,9 @@ public class WxPayServiceImpl implements WxPayService {
payment.setTotalFee(jsonObject.getJSONObject("amount").getInt("payer_total")); payment.setTotalFee(jsonObject.getJSONObject("amount").getInt("payer_total"));
payment.setTransactionId(jsonObject.getStr("transaction_id")); payment.setTransactionId(jsonObject.getStr("transaction_id"));
payment.setSuccessTime(jsonObject.getStr("success_time")); payment.setSuccessTime(jsonObject.getStr("success_time"));
payment.setTradeState(jsonObject.getStr("trade_state"));
payment.setContent(JSONUtil.toJsonStr(jsonObject)); payment.setContent(JSONUtil.toJsonStr(jsonObject));
paymentService.save(payment); paymentService.save(payment);
}
} finally { } finally {
lock.unlock(); lock.unlock();
} }
...@@ -214,9 +220,16 @@ public class WxPayServiceImpl implements WxPayService { ...@@ -214,9 +220,16 @@ public class WxPayServiceImpl implements WxPayService {
@Override @Override
public String queryOrder(Long orderId) { public String queryOrder(Long orderId) throws IOException {
String url = String.format("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/%s?mchid=%s", orderId, wxPayProperties.getMchId());
return null; HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("Accept", "application/json");
//完成签名并执行请求
CloseableHttpResponse response = httpClient.execute(httpGet);
String result = EntityUtils.toString(response.getEntity());
log.info("查询微信支付订单状态, 当前订单号: {}, 返回结果:{}", orderId, result);
JSONObject jsonObject = JSONUtil.parseObj(result);
return jsonObject.getStr("trade_state");
} }
@Override @Override
...@@ -225,7 +238,7 @@ public class WxPayServiceImpl implements WxPayService { ...@@ -225,7 +238,7 @@ public class WxPayServiceImpl implements WxPayService {
if (order == null || !order.getOrderStatus().equals(OrderStatus.PAYED.getStatus())) { if (order == null || !order.getOrderStatus().equals(OrderStatus.PAYED.getStatus())) {
throw GlobalException.newException(ResultCode.REFUND_FAILED, "当前订单未支付成功"); throw GlobalException.newException(ResultCode.REFUND_FAILED, "当前订单未支付成功");
} }
String out_refund_no = "refund-" + snowflakeUtil.snowflakeId(); Long out_refund_no = snowflakeUtil.snowflakeId();
String url = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds"; String url = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";
HttpPost httpPost = new HttpPost(url); HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Accept", "application/json"); httpPost.addHeader("Accept", "application/json");
...@@ -233,9 +246,7 @@ public class WxPayServiceImpl implements WxPayService { ...@@ -233,9 +246,7 @@ public class WxPayServiceImpl implements WxPayService {
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
ObjectNode rootNode = objectMapper.createObjectNode(); ObjectNode rootNode = objectMapper.createObjectNode();
rootNode.put("mchid", wxPayProperties.getMchId()) rootNode.put("out_refund_no", String.valueOf(out_refund_no))
.put("appid", wxPayProperties.getAppId())
.put("out_refund_no", out_refund_no)
.put("notify_url", wxPayProperties.getRefundNotifyUrl()) .put("notify_url", wxPayProperties.getRefundNotifyUrl())
.put("out_trade_no", String.valueOf(orderId)); .put("out_trade_no", String.valueOf(orderId));
rootNode.putObject("amount") rootNode.putObject("amount")
...@@ -248,10 +259,19 @@ public class WxPayServiceImpl implements WxPayService { ...@@ -248,10 +259,19 @@ public class WxPayServiceImpl implements WxPayService {
httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8")); httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
CloseableHttpResponse response = httpClient.execute(httpPost); CloseableHttpResponse response = httpClient.execute(httpPost);
String bodyAsString = EntityUtils.toString(response.getEntity()); String bodyAsString = EntityUtils.toString(response.getEntity());
log.info("退款接口返回参数: {}", bodyAsString);
JSONObject jsonObject = JSONUtil.parseObj(bodyAsString); JSONObject jsonObject = JSONUtil.parseObj(bodyAsString);
// 修改订单状态为退款中 // 修改订单状态为退款中
orderService.updateOrderStatus(orderId, OrderStatus.REFUNDING); orderService.updateOrderStatus(orderId, OrderStatus.REFUNDING);
// 插入退款信息
Refund refund = new Refund();
refund.setId(out_refund_no);
refund.setFee(order.getFee());
refund.setOrderId(orderId);
refund.setRefundId(jsonObject.getStr("refund_id"));
refund.setTransactionId(jsonObject.getStr("transaction_id"));
refund.setUserReceivedAccount(jsonObject.getStr("user_received_account"));
refundService.save(refund);
} }
@Override @Override
...@@ -264,23 +284,37 @@ public class WxPayServiceImpl implements WxPayService { ...@@ -264,23 +284,37 @@ public class WxPayServiceImpl implements WxPayService {
String plainText = this.decrypt(resource); String plainText = this.decrypt(resource);
log.info("解密后的明文信息为: {}", plainText); log.info("解密后的明文信息为: {}", plainText);
JSONObject obj = JSONUtil.parseObj(plainText); JSONObject obj = JSONUtil.parseObj(plainText);
processRefund(jsonObject); processRefund(obj);
return null; return true;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); log.error(e.getMessage(), e);
return false; return false;
} }
} }
@Override @Override
public void processRefund(JSONObject jsonObject) { public void processRefund(JSONObject obj) throws InterruptedException {
Long out_trade_no = jsonObject.getLong("out_trade_no"); Long out_trade_no = obj.getLong("out_trade_no");
Long out_refund_no = obj.getLong("out_refund_no");
RLock lock = redisson.getLock("refund-" + out_trade_no); RLock lock = redisson.getLock("refund-" + out_trade_no);
lock.lock(10, TimeUnit.SECONDS);
try { try {
// 修改订单未退款成功 if (lock.tryLock(10, TimeUnit.SECONDS)) {
Refund refund = refundService.getById(out_refund_no);
if (RefundStatus.SUCCESS.getStatus().equals(refund.getRefundStatus())) {
return;
}
// 更新退款信息
refund.setRefundStatus(RefundStatus.SUCCESS.getStatus());
refund.setSuccessTime(obj.getStr("success_time"));
refund.setContent(JSONUtil.toJsonStr(obj));
refundService.updateById(refund);
// 更新流水的退款状态
Payment payment = paymentService.getByOrderId(out_trade_no);
payment.setIsRefund(SystemConstant.BOOLEAN_DATA_TRUE);
paymentService.updateById(payment);
// 修改订单状态为退款成功
orderService.updateOrderStatus(out_trade_no, OrderStatus.REFUNDED); orderService.updateOrderStatus(out_trade_no, OrderStatus.REFUNDED);
// 保存流水信息 }
} finally { } finally {
lock.unlock(); lock.unlock();
} }
......
package com.fzm.portal;
import com.fzm.common.entity.dto.OrderProcessMsg;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.scheduling.support.SimpleTriggerContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @author tangtuo
* @date 2022/1/21 16:28
*/
@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
@Resource
private RabbitTemplate rabbitTemplate;
@GetMapping("/send")
public String send(){
log.info("发送消息: {}",123);
rabbitTemplate.convertAndSend("nft-exchange", "nft.publish", 123);
return "SUCCESS";
}
}
package com.fzm.portal.controller;
import com.fzm.common.annotation.Authentication;
import com.fzm.common.entity.Charge;
import com.fzm.common.model.ResponseModel;
import com.fzm.common.service.ChargeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* @author tangtuo
* @date 2022/1/25 10:13
*/
@Authentication
@RestController
@RequestMapping(value = "/charge")
@Api(tags = "收费管理")
public class ChargeController {
@Resource
private ChargeService chargeService;
@GetMapping("/fee/{type}")
@ApiOperation("根据收费类型查询收费")
public ResponseModel<Long> getByType(@ApiParam("收费类型 1-nft发行 2-版权申请") @PathVariable Integer type) {
Charge charge = chargeService.getByType(type);
return ResponseModel.success(charge.getFee());
}
}
...@@ -78,7 +78,7 @@ public class CopyrightApplyController { ...@@ -78,7 +78,7 @@ public class CopyrightApplyController {
@Authentication @Authentication
@PostMapping(value = "/update") @PostMapping(value = "/update")
@ApiOperation(value = "编辑") @ApiOperation(value = "编辑")
public ResponseModel<Boolean> update(@RequestBody CopyrightDTO copyrightDTO) { public ResponseModel<Integer> update(@RequestBody CopyrightDTO copyrightDTO) {
return ResponseModel.success(copyrightApplyService.update(copyrightDTO)); return ResponseModel.success(copyrightApplyService.update(copyrightDTO));
} }
......
package com.fzm.portal.controller; package com.fzm.portal.controller;
import com.fzm.common.annotation.Authentication; import com.fzm.common.annotation.Authentication;
import com.fzm.common.entity.Order;
import com.fzm.common.entity.dto.OrderDto; import com.fzm.common.entity.dto.OrderDto;
import com.fzm.common.enums.OrderStatus;
import com.fzm.common.model.ResponseModel; import com.fzm.common.model.ResponseModel;
import com.fzm.common.service.OrderService; import com.fzm.common.service.OrderService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
...@@ -9,8 +11,7 @@ import io.swagger.annotations.ApiOperation; ...@@ -9,8 +11,7 @@ import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.HashMap; import java.util.List;
import java.util.Map;
/** /**
* @author tangtuo * @author tangtuo
...@@ -39,4 +40,22 @@ public class OrderController { ...@@ -39,4 +40,22 @@ public class OrderController {
public ResponseModel<Integer> queryOrderStatus(@PathVariable Long orderId) { public ResponseModel<Integer> queryOrderStatus(@PathVariable Long orderId) {
return ResponseModel.success(orderService.getById(orderId).getOrderStatus()); return ResponseModel.success(orderService.getById(orderId).getOrderStatus());
} }
@PostMapping("/cancel")
@ApiOperation("取消订单")
public ResponseModel<Boolean> cancelOrder(@RequestParam Long orderId) {
Boolean result = orderService.cancel(orderId, OrderStatus.CANCEL);
return ResponseModel.success(result);
}
@GetMapping("/list/{payScene}")
@ApiOperation(value = "获取我的订单列表")
public ResponseModel<List<Order>> listOrder(@PathVariable Integer payScene) {
List<Order> orders = orderService.listOrder(payScene);
return ResponseModel.success(orders);
}
} }
...@@ -71,5 +71,11 @@ public class WxPayController { ...@@ -71,5 +71,11 @@ public class WxPayController {
} }
@GetMapping("/refund/{orderId}")
public ResponseModel<String> refund(@PathVariable Long orderId) throws IOException {
wxPayService.refund(orderId);
return ResponseModel.success("退款成功");
}
} }
...@@ -5,18 +5,26 @@ import cn.fzm.chain.simplesdk.constant.TxStatusEnum; ...@@ -5,18 +5,26 @@ import cn.fzm.chain.simplesdk.constant.TxStatusEnum;
import cn.fzm.chain.simplesdk.model.TxResult; import cn.fzm.chain.simplesdk.model.TxResult;
import com.fzm.common.constant.SystemConstant; import com.fzm.common.constant.SystemConstant;
import com.fzm.common.entity.Nft; import com.fzm.common.entity.Nft;
import com.fzm.common.entity.Order;
import com.fzm.common.entity.User; import com.fzm.common.entity.User;
import com.fzm.common.entity.dto.NftPublishMsg; import com.fzm.common.entity.dto.NftPublishMsg;
import com.fzm.common.enums.OrderStatus;
import com.fzm.common.enums.PayScene;
import com.fzm.common.enums.PublishStatus;
import com.fzm.common.enums.ResultCode; import com.fzm.common.enums.ResultCode;
import com.fzm.common.exception.GlobalException; import com.fzm.common.exception.GlobalException;
import com.fzm.common.service.NftService; import com.fzm.common.service.NftService;
import com.fzm.common.service.OrderService;
import com.fzm.common.service.UserService; import com.fzm.common.service.UserService;
import com.fzm.common.service.WxPayService;
import com.fzm.common.utils.RedisUtil; import com.fzm.common.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date; import java.util.Date;
/** /**
...@@ -39,15 +47,22 @@ public class NftListener { ...@@ -39,15 +47,22 @@ public class NftListener {
@Resource @Resource
private RedisUtil redisUtil; private RedisUtil redisUtil;
@Resource
private OrderService orderService;
@Resource
private WxPayService wxPayService;
/** /**
* 监听nft发行结果 * 监听nft发行结果
* *
* @param msg * @param msg
*/ */
@RabbitListener(queues = "nft.publish.queue") @RabbitListener(queues = "nft.publish.queue")
public void listenNftPublish(NftPublishMsg msg) { public void listenNftPublish(NftPublishMsg msg) throws IOException {
log.info("收到处理确认nft发行结果的消息: {}", msg); log.info("收到处理确认nft发行结果的消息: {}", msg);
Nft nft = nftService.getById(msg.getId()); Nft nft = nftService.getById(msg.getId());
try {
User user = userService.getUserByWallet(nft.getPublishAddress()); User user = userService.getUserByWallet(nft.getPublishAddress());
String hash = msg.getHash(); String hash = msg.getHash();
// 确认交易结果 // 确认交易结果
...@@ -56,13 +71,13 @@ public class NftListener { ...@@ -56,13 +71,13 @@ public class NftListener {
throw GlobalException.newException(ResultCode.PUBLISH_ERROR, txResult.getErrMsg().getValue()); throw GlobalException.newException(ResultCode.PUBLISH_ERROR, txResult.getErrMsg().getValue());
} }
String realHash = paraChainClient.getRealTxHashFromGrp(hash); String realHash = paraChainClient.getRealTxHashFromGrp(hash);
/*TxResult txResult = paraChainClient.cycleConfirmTxWithHash(realHash, false, 1000); if (StringUtils.isBlank(realHash)) {
if (!TxStatusEnum.SUCCESS.equals(txResult.getStatus())) { throw GlobalException.newException(ResultCode.PUBLISH_ERROR);
throw GlobalException.newException(ResultCode.PUBLISH_ERROR, txResult.getErrMsg().getValue()); }
}*/
nft.setNftHash(realHash); nft.setNftHash(realHash);
nft.setTokenId(msg.getTokenId()); nft.setTokenId(msg.getTokenId());
nft.setPublishTime(new Date()); nft.setPublishTime(new Date());
nft.setPublishStatus(PublishStatus.SUSSED.getCode());
nftService.updateById(nft); nftService.updateById(nft);
// 如果用户是第一次发行作品,把用户的isPublish修改成1,并清空用户统计的缓存信息 // 如果用户是第一次发行作品,把用户的isPublish修改成1,并清空用户统计的缓存信息
if (SystemConstant.BOOLEAN_DATA_FALSE.equals(user.getIsPublish())) { if (SystemConstant.BOOLEAN_DATA_FALSE.equals(user.getIsPublish())) {
...@@ -70,5 +85,15 @@ public class NftListener { ...@@ -70,5 +85,15 @@ public class NftListener {
userService.updateById(u); userService.updateById(u);
redisUtil.delete("user::statistic"); redisUtil.delete("user::statistic");
} }
} catch (Exception e) {
log.error(e.getMessage(), e);
// nft发行失败,需要把nft的发行状态改成failed,然后主动发起退款
nft.setPublishStatus(PublishStatus.FAILED.getCode());
nftService.updateById(nft);
Order order = orderService.getByPaySceneAndProductId(PayScene.NFT.getCode(), nft.getId(), OrderStatus.PAYED.getStatus());
if (order != null) {
wxPayService.refund(order.getId());
}
}
} }
} }
...@@ -5,11 +5,13 @@ import com.fzm.common.enums.CopyrightApplyState; ...@@ -5,11 +5,13 @@ import com.fzm.common.enums.CopyrightApplyState;
import com.fzm.common.enums.PayScene; import com.fzm.common.enums.PayScene;
import com.fzm.common.service.CopyrightApplyService; import com.fzm.common.service.CopyrightApplyService;
import com.fzm.common.service.NftService; import com.fzm.common.service.NftService;
import com.fzm.common.service.WxPayService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException;
/** /**
* @author tangtuo * @author tangtuo
...@@ -25,9 +27,13 @@ public class OrderListener { ...@@ -25,9 +27,13 @@ public class OrderListener {
@Resource @Resource
private CopyrightApplyService copyrightApplyService; private CopyrightApplyService copyrightApplyService;
@Resource
private WxPayService wxPayService;
@RabbitListener(queues = "order.process.queue") @RabbitListener(queues = "order.process.queue")
public void listenProcessOrder(OrderProcessMsg msg) { public void listenProcessOrder(OrderProcessMsg msg) throws IOException {
log.info("收到处理订单的消息: {}", msg); log.info("收到处理订单的消息: {}", msg);
try {
if (PayScene.NFT.getCode().equals(msg.getPayScene())) { if (PayScene.NFT.getCode().equals(msg.getPayScene())) {
// 如果支付场景是发行nft的话,需要把此订单的nft发行 // 如果支付场景是发行nft的话,需要把此订单的nft发行
nftService.publish(msg.getProductId()); nftService.publish(msg.getProductId());
...@@ -35,6 +41,10 @@ public class OrderListener { ...@@ -35,6 +41,10 @@ public class OrderListener {
// 如果支付场景是版权申请的话,需要把当前订单对应的版权状态改为待核验 // 如果支付场景是版权申请的话,需要把当前订单对应的版权状态改为待核验
copyrightApplyService.updateRegisterState(msg.getProductId(), CopyrightApplyState.TO_BE_REVIEWED.getCode()); copyrightApplyService.updateRegisterState(msg.getProductId(), CopyrightApplyState.TO_BE_REVIEWED.getCode());
} }
} catch (Exception e) {
// 处理失败,需要主动发起退款
wxPayService.refund(msg.getOrderId());
}
} }
} }
...@@ -126,5 +126,5 @@ wx-pay: ...@@ -126,5 +126,5 @@ wx-pay:
api-v3-key: D864DA53FEF8ACD41519064967DC10D2 api-v3-key: D864DA53FEF8ACD41519064967DC10D2
mch-serial-num: 72A62544B0A08A214FAEC780108692EDC6E7D5FA mch-serial-num: 72A62544B0A08A214FAEC780108692EDC6E7D5FA
private-key-path: apiclient_key.pem private-key-path: apiclient_key.pem
pay-notify-url: https://test.inmvo.com:8985/proxyApi/wx-pay/notify/jsapi pay-notify-url: https://test.inmvo.com/proxyApi/wx-pay/notify/jsapi
refund-notify-url: https://test.inmvo.com:8985/proxyApi/wx-pay/notify/refund refund-notify-url: https://test.inmvo.com/proxyApi/wx-pay/notify/refund
...@@ -53,8 +53,8 @@ public class WxPayTest { ...@@ -53,8 +53,8 @@ public class WxPayTest {
@Test @Test
public void testH5Pay() throws IOException { public void testH5Pay() throws IOException {
OrderProcessMsg orderProcessMsg = new OrderProcessMsg(1, 1); // OrderProcessMsg orderProcessMsg = new OrderProcessMsg(1, 1);
rabbitTemplate.convertAndSend("order-exchange", "order.process", orderProcessMsg); // rabbitTemplate.convertAndSend("order-exchange", "order.process", orderProcessMsg);
// for (int i = 0; i < 10; i++) { // for (int i = 0; i < 10; i++) {
// log.info(String.valueOf(snowflakeUtil.snowflakeId()));// } // log.info(String.valueOf(snowflakeUtil.snowflakeId()));// }
// String url = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi"; // String url = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -611,3 +611,8 @@ CREATE TABLE `tb_order` ( ...@@ -611,3 +611,8 @@ CREATE TABLE `tb_order` (
`update_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `update_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- v2.3.0
alter table tb_nft add column publish_status TINYINT(1) not null default 1 comment '发行状态 1-待支付 2-发行成功 3-发行失败' after publish_time;
update tb_nft set publish_status =2 where nft_hash !='';
\ No newline at end of file
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