Commit 4819f7b0 authored by tangtuo's avatar tangtuo

微信支付

parent 96d5d17e
...@@ -34,7 +34,8 @@ public class WxPayConfig { ...@@ -34,7 +34,8 @@ public class WxPayConfig {
private WxPayProperties wxPayProperties; private WxPayProperties wxPayProperties;
private PrivateKey getPrivateKey() { @Bean
public PrivateKey wxPrivateKey() {
// 加载商户私钥(privateKey:私钥字符串地址) // 加载商户私钥(privateKey:私钥字符串地址)
try { try {
ClassPathResource resource = new ClassPathResource(wxPayProperties.getPrivateKeyPath()); ClassPathResource resource = new ClassPathResource(wxPayProperties.getPrivateKeyPath());
...@@ -44,23 +45,20 @@ public class WxPayConfig { ...@@ -44,23 +45,20 @@ public class WxPayConfig {
} }
} }
@Bean @Bean
public CloseableHttpClient client() throws NotFoundException, HttpCodeException, GeneralSecurityException, IOException { public CloseableHttpClient client(PrivateKey wxPrivateKey) throws NotFoundException, HttpCodeException, GeneralSecurityException, IOException {
// 获取证书管理器实例 // 获取证书管理器实例
CertificatesManager certificatesManager = CertificatesManager.getInstance(); CertificatesManager certificatesManager = CertificatesManager.getInstance();
// 向证书管理器增加需要自动更新平台证书的商户信息 // 向证书管理器增加需要自动更新平台证书的商户信息
PrivateKey merchantPrivateKey = getPrivateKey();
String mchId = wxPayProperties.getMchId(); String mchId = wxPayProperties.getMchId();
String apiV3Key = wxPayProperties.getApiV3Key(); String apiV3Key = wxPayProperties.getApiV3Key();
String mchSerialNum = wxPayProperties.getMchSerialNum(); String mchSerialNum = wxPayProperties.getMchSerialNum();
certificatesManager.putMerchant(mchId, new WechatPay2Credentials(mchId, certificatesManager.putMerchant(mchId, new WechatPay2Credentials(mchId,
new PrivateKeySigner(mchSerialNum, merchantPrivateKey)), apiV3Key.getBytes(StandardCharsets.UTF_8)); new PrivateKeySigner(mchSerialNum, wxPrivateKey)), apiV3Key.getBytes(StandardCharsets.UTF_8));
// 从证书管理器中获取verifier // 从证书管理器中获取verifier
Verifier verifier = certificatesManager.getVerifier(mchId); Verifier verifier = certificatesManager.getVerifier(mchId);
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create() WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, mchSerialNum, merchantPrivateKey) .withMerchant(mchId, mchSerialNum, wxPrivateKey)
.withValidator(new WechatPay2Validator(verifier)); .withValidator(new WechatPay2Validator(verifier));
// ... 接下来,你仍然可以通过builder设置各种参数,来配置你的HttpClient // ... 接下来,你仍然可以通过builder设置各种参数,来配置你的HttpClient
// 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新 // 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新
......
...@@ -56,16 +56,11 @@ public class Nft extends BaseEntity { ...@@ -56,16 +56,11 @@ public class Nft extends BaseEntity {
@ApiModelProperty("简介") @ApiModelProperty("简介")
private String synopsis; private String synopsis;
@ApiModelProperty("文件名")
private String fileName;
@ApiModelProperty("文件地址--用户选择不存档的情况下为空")
private String fileUrl;
@NotBlank(message = "作品哈希不能为空") @NotBlank(message = "作品哈希不能为空")
@ApiModelProperty("文件hash") @ApiModelProperty("文件hash")
private String fileHash; private String fileHash;
@NotBlank(message = "nft编号不能为空")
@ApiModelProperty("nft编号") @ApiModelProperty("nft编号")
private String nftId; private String nftId;
......
package com.fzm.common.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import java.util.Date;
/**
* @author tangtuo
* @date 2022/1/19 15:33
*/
@Data
@TableName("tb_order")
public class Order {
@ApiModelProperty("主键")
private Long id;
@ApiModelProperty("订单名")
private String orderName;
@ApiModelProperty("支付场景 1-nft发行 2-版权申请")
private Integer payScene;
@ApiModelProperty("产品id nft主键或者版权主键")
private Integer productId;
@ApiModelProperty("用户id")
private Integer userId;
@ApiModelProperty("订单价格-单位(分)")
private Long fee;
@ApiModelProperty("0-支付中 1-支付成功 2-订单已关闭 3-已退款")
private Integer orderStatus;
@ApiModelProperty("支付类型 1-微信支付 2-支付宝支付")
private Integer payType;
@ApiModelProperty("创建时间")
private Date createDate;
@ApiModelProperty("最后一次修改时间")
private Date updateDate;
}
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;
import java.util.Date;
@Data
@TableName("tb_payment")
public class Payment {
@TableId(type = IdType.AUTO)
private Integer id;
@ApiModelProperty("商品订单编号")
private Long orderId;
@ApiModelProperty("支付系统交易编号")
private String transactionId;
@ApiModelProperty("交易类型")
private String tradeType;
@ApiModelProperty("交易状态")
private String tradeState;
@ApiModelProperty("支付金额(分)")
private Integer totalFee;
@ApiModelProperty("商品订单编号")
private String successTime;
@ApiModelProperty("通知参数")
private String content;
private Date createDate;
private Date updateDate;
}
\ No newline at end of file
package com.fzm.common.entity.dto;
import lombok.Data;
/**
* @author tangtuo
* @date 2022/1/20 18:45
*/
@Data
public class JsapiPayDto {
private String openid;
private Long orderId;
}
package com.fzm.common.entity.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author tangtuo
* @date 2022/1/19 15:09
*/
@Data
public class OrderDto {
@ApiModelProperty("订单价格")
private Long fee;
@ApiModelProperty("支付场景 1-nft发行 2-版权申请")
private Integer payScene;
@ApiModelProperty("产品id nft的id或者copyright的id")
private Integer productId;
}
package com.fzm.common.entity.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author tangtuo
* @date 2022/1/21 13:08
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OrderProcessMsg {
private Integer productId;
private Integer payScene;
}
...@@ -12,7 +12,7 @@ import lombok.ToString; ...@@ -12,7 +12,7 @@ import lombok.ToString;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
public enum CopyrightApplyState { public enum CopyrightApplyState {
TO_BE_PAY(-2, "待支付", ""),
WITHDRAW(-1, "已撤回", ""), WITHDRAW(-1, "已撤回", ""),
TO_BE_REVIEWED(0, "待核验", ""), TO_BE_REVIEWED(0, "待核验", ""),
SUBMITTED(2, "提交审核", "请耐心等待湖北版权局审核受理,受理成功后将在15个工作日内完成登记"), SUBMITTED(2, "提交审核", "请耐心等待湖北版权局审核受理,受理成功后将在15个工作日内完成登记"),
......
package com.fzm.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author tangtuo
* @date 2022/1/19 15:53
*/
@AllArgsConstructor
@Getter
public enum OrderStatus {
// 支付中
PAYING(0),
// 支付成功
PAYED(1),
// 已关单
CLOSED(2),
// 退款中
REFUNDING(3),
// 退款成功
REFUNDED(4),
// 订单已取消(已关闭)
CANCEL(5),
;
private Integer status;
}
package com.fzm.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author tangtuo
* @date 2022/1/18 17:49
*/
@Getter
@AllArgsConstructor
public enum PayScene {
NFT(1, "NFT发行"),
COPYRIGHT(2, "版权申请");
private Integer code;
private String type;
public static String getTypeByCode(Integer code) {
for (PayScene value : PayScene.values()) {
if (value.getCode().equals(code)) {
return value.getType();
}
}
return NFT.getType();
}
}
package com.fzm.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum PayType {
/**
* 微信
*/
WXPAY(1, "微信支付"),
/**
* 支付宝
*/
ALIPAY(2, "支付宝支付");
/**
* 类型
*/
private Integer code;
private final String type;
}
...@@ -20,6 +20,7 @@ public enum ResultCode implements IErrorCode { ...@@ -20,6 +20,7 @@ public enum ResultCode implements IErrorCode {
OPERATION_FAILED(418, "操作失败"), OPERATION_FAILED(418, "操作失败"),
COPYRIGHT_FAILED(420, "版权申请失败"), COPYRIGHT_FAILED(420, "版权申请失败"),
SELECT_FAILED(421, "查询失败"), SELECT_FAILED(421, "查询失败"),
PAY_FAILED(422, "支付失败"),
; ;
......
package com.fzm.common.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fzm.common.entity.Order;
import org.apache.ibatis.annotations.Mapper;
/**
* @author tangtuo
* @date 2022/1/19 15:41
*/
@Mapper
public interface OrderMapper extends BaseMapper<Order> {
}
package com.fzm.common.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fzm.common.entity.Payment;
import org.apache.ibatis.annotations.Mapper;
/**
* @author tangtuo
* @date 2022/1/20 16:39
*/
@Mapper
public interface PaymentMapper extends BaseMapper<Payment> {
}
package com.fzm.common.properties; package com.fzm.common.properties;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.Data; import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
...@@ -17,6 +18,9 @@ public class WxPayProperties { ...@@ -17,6 +18,9 @@ public class WxPayProperties {
@ApiModelProperty("微信公众号appId") @ApiModelProperty("微信公众号appId")
private String appId; private String appId;
@ApiModelProperty("微信公众号APPSecret")
private String appSecret;
@ApiModelProperty("商户号") @ApiModelProperty("商户号")
private String mchId; private String mchId;
...@@ -29,4 +33,10 @@ public class WxPayProperties { ...@@ -29,4 +33,10 @@ public class WxPayProperties {
@ApiModelProperty("商户私钥文件路径") @ApiModelProperty("商户私钥文件路径")
private String privateKeyPath; private String privateKeyPath;
@ApiModelProperty("h5支付回调地址")
private String h5PayNotifyUrl;
@ApiModelProperty("h5退款回调地址")
private String h5RefundNotifyUrl;
} }
...@@ -143,4 +143,12 @@ public interface CopyrightApplyService extends IService<CopyrightApply> { ...@@ -143,4 +143,12 @@ public interface CopyrightApplyService extends IService<CopyrightApply> {
*/ */
List<String> getSerialCodes(); List<String> getSerialCodes();
/**
* 修改状态
*
* @param copyrightId
* @param state
* @return
*/
boolean updateRegisterState(Integer copyrightId, int state);
} }
...@@ -23,7 +23,7 @@ public interface NftService extends IService<Nft> { ...@@ -23,7 +23,7 @@ public interface NftService extends IService<Nft> {
* @param nft * @param nft
* @return * @return
*/ */
NftDto saveNft(Nft nft); Integer saveNft(Nft nft);
/** /**
* 查看nft列表 * 查看nft列表
...@@ -124,10 +124,10 @@ public interface NftService extends IService<Nft> { ...@@ -124,10 +124,10 @@ public interface NftService extends IService<Nft> {
/** /**
* 发行nft * 发行nft
* *
* @param nftDto * @param id
* @return * @return
*/ */
Integer publish(NftDto nftDto); Integer publish(Integer id);
/** /**
* nft转让 * nft转让
......
package com.fzm.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.fzm.common.entity.Order;
import com.fzm.common.entity.dto.OrderDto;
import com.fzm.common.enums.OrderStatus;
/**
* @author tangtuo
* @date 2022/1/19 15:41
*/
public interface OrderService extends IService<Order> {
/**
* 根据支付场景和产品id查询订单
*
* @param payScene
* @param productId
* @return
*/
Order getByPaySceneAndProductId(Integer payScene, Integer productId);
/**
* 更新订单状态
*
* @param out_trade_no
* @param orderStatus
*/
void updateOrderStatus(Long out_trade_no, OrderStatus orderStatus);
/**
* 下单
* @param orderDto
* @return
*/
Long createOrder(OrderDto orderDto);
/**
*
* @param orderId
* @param payType
*/
Boolean updatePayType(Long orderId, Integer payType);
}
package com.fzm.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.fzm.common.entity.Payment;
/**
* @author tangtuo
* @date 2022/1/20 16:40
*/
public interface PaymentService extends IService<Payment> {
}
package com.fzm.common.service; package com.fzm.common.service;
import cn.hutool.json.JSONObject;
import com.fzm.common.entity.dto.JsapiPayDto;
import javax.servlet.http.HttpServletRequest;
import java.security.GeneralSecurityException;
import java.util.Map;
/** /**
* @author tangtuo * @author tangtuo
* @date 2022/1/13 10:13 * @date 2022/1/13 10:13
*/ */
public interface WxPayService { public interface WxPayService {
/**
* h5支付下单并生成签名
*
* @param jsapiPayDto
* @return
* @throws Exception
*/
Map<String, Object> payJsapi(JsapiPayDto jsapiPayDto) throws Exception;
String encryptByPrivateKey(String data) throws Exception;
Boolean notifyH5(HttpServletRequest request);
/**
* 支付成功后处理订单
*
* @param jsonObject
*/
void processOrder(JSONObject jsonObject) throws GeneralSecurityException;
String queryOrder(Long orderId);
} }
...@@ -114,8 +114,8 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper, ...@@ -114,8 +114,8 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper,
throw GlobalException.newException(ResultCode.VALIDATE_FAILED); throw GlobalException.newException(ResultCode.VALIDATE_FAILED);
} }
CopyrightApply copyrightApply = new CopyrightApply(copyrightDTO); CopyrightApply copyrightApply = new CopyrightApply(copyrightDTO);
// 首次提交,登记状态为待提交 // 首次提交,登记状态为待支付
copyrightApply.setRegisterState(CopyrightApplyState.TO_BE_REVIEWED.getCode()); copyrightApply.setRegisterState(CopyrightApplyState.TO_BE_PAY.getCode());
copyrightApply.setUserId(user.getId()); copyrightApply.setUserId(user.getId());
copyrightApply.setApplyTime(new Date()); copyrightApply.setApplyTime(new Date());
try { try {
...@@ -303,7 +303,7 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper, ...@@ -303,7 +303,7 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper,
copyrightApplyOwnerRelationService.saveBatch(owners); copyrightApplyOwnerRelationService.saveBatch(owners);
} }
copyrightApply.setApplyTime(new Date()); copyrightApply.setApplyTime(new Date());
copyrightApply.setRegisterState(CopyrightApplyState.TO_BE_REVIEWED.getCode()); copyrightApply.setRegisterState(CopyrightApplyState.TO_BE_PAY.getCode());
return updateById(copyrightApply); return updateById(copyrightApply);
} }
...@@ -444,4 +444,12 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper, ...@@ -444,4 +444,12 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper,
return copyrightApplyMapper.getSerialCodes(); return copyrightApplyMapper.getSerialCodes();
} }
@Override
public boolean updateRegisterState(Integer copyrightId, int state) {
CopyrightApply copyrightApply = new CopyrightApply();
copyrightApply.setId(copyrightId);
copyrightApply.setRegisterState(state);
return updateById(copyrightApply);
}
} }
...@@ -14,7 +14,6 @@ import com.fzm.common.utils.JwtUtil; ...@@ -14,7 +14,6 @@ import com.fzm.common.utils.JwtUtil;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -38,16 +37,19 @@ public class EntrustShelfServiceImpl extends ServiceImpl<EntrustShelfMapper, Ent ...@@ -38,16 +37,19 @@ public class EntrustShelfServiceImpl extends ServiceImpl<EntrustShelfMapper, Ent
@Override @Override
public Boolean submit(EntrustShelf entrustShelf) { public Boolean submit(EntrustShelf entrustShelf) {
// 查询当前nft是否已提交过申请
QueryWrapper<EntrustShelf> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("nft_hash", entrustShelf.getNftHash());
queryWrapper.eq("status", SystemConstant.BOOLEAN_DATA_FALSE);
if (this.count(queryWrapper) > 0) {
throw GlobalException.newException(ResultCode.FAILED, "此nft已提交过上架申请,请勿重复提交");
}
// 修改当前nft的是否已申请的状态为是 // 修改当前nft的是否已申请的状态为是
nftService.updateEntrust(entrustShelf.getNftHash(), SystemConstant.BOOLEAN_DATA_TRUE); nftService.updateEntrust(entrustShelf.getNftHash(), SystemConstant.BOOLEAN_DATA_TRUE);
String authorization = request.getHeader("Authorization"); String authorization = request.getHeader("Authorization");
Integer userId = JwtUtil.getUserIdFromToken(authorization); Integer userId = JwtUtil.getUserIdFromToken(authorization);
entrustShelf.setUserId(userId); entrustShelf.setUserId(userId);
try {
return this.save(entrustShelf); return this.save(entrustShelf);
} catch (DuplicateKeyException e) {
throw GlobalException.newException(ResultCode.FAILED, "此nft已提交过上架申请,请勿重复提交");
}
} }
@Override @Override
...@@ -91,6 +93,7 @@ public class EntrustShelfServiceImpl extends ServiceImpl<EntrustShelfMapper, Ent ...@@ -91,6 +93,7 @@ public class EntrustShelfServiceImpl extends ServiceImpl<EntrustShelfMapper, Ent
public EntrustShelf getByNftHash(String nftHash) { public EntrustShelf getByNftHash(String nftHash) {
QueryWrapper<EntrustShelf> queryWrapper = new QueryWrapper<>(); QueryWrapper<EntrustShelf> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("nft_hash", nftHash); queryWrapper.eq("nft_hash", nftHash);
queryWrapper.eq("status", SystemConstant.BOOLEAN_DATA_FALSE);
return this.getOne(queryWrapper); return this.getOne(queryWrapper);
} }
} }
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.Order;
import com.fzm.common.entity.dto.OrderDto;
import com.fzm.common.enums.OrderStatus;
import com.fzm.common.enums.PayScene;
import com.fzm.common.enums.PayType;
import com.fzm.common.mapper.OrderMapper;
import com.fzm.common.service.CopyrightApplyService;
import com.fzm.common.service.NftService;
import com.fzm.common.service.OrderService;
import com.fzm.common.utils.JwtUtil;
import com.fzm.common.utils.SnowflakeUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
/**
* @author tangtuo
* @date 2022/1/19 15:42
*/
@Service
@Transactional(rollbackFor = RuntimeException.class)
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
@Resource
private NftService nftService;
@Resource
private CopyrightApplyService copyrightApplyService;
@Resource
private SnowflakeUtil snowflakeUtil;
@Resource
private HttpServletRequest request;
@Override
public Order getByPaySceneAndProductId(Integer payScene, Integer productId) {
QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("pay_scene", payScene)
.eq("product_id", productId);
return this.getOne(queryWrapper);
}
@Override
public void updateOrderStatus(Long out_trade_no, OrderStatus orderStatus) {
Order order = new Order();
order.setId(out_trade_no);
order.setOrderStatus(orderStatus.getStatus());
this.updateById(order);
}
@Override
public Long createOrder(OrderDto orderDto) {
Order order = new Order();
long id = snowflakeUtil.snowflakeId();
Integer productId = orderDto.getProductId();
String orderName;
if (PayScene.NFT.getCode().equals(orderDto.getPayScene())) {
orderName = nftService.getById(productId).getName();
} else {
orderName = copyrightApplyService.getById(productId).getOpusName();
}
order.setId(id);
order.setOrderName(orderName);
order.setPayScene(orderDto.getPayScene());
order.setOrderName(orderName);
order.setFee(orderDto.getFee());
order.setProductId(productId);
order.setUserId(JwtUtil.getUserIdFromToken(request.getHeader("Authorization")));
order.setOrderStatus(OrderStatus.PAYING.getStatus());
this.save(order);
return id;
}
@Override
public Boolean updatePayType(Long orderId, Integer payType) {
Order o = new Order();
o.setId(orderId);
o.setPayType(payType);
return updateById(o);
}
}
package com.fzm.common.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzm.common.entity.Payment;
import com.fzm.common.mapper.PaymentMapper;
import com.fzm.common.service.PaymentService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @author tangtuo
* @date 2022/1/20 16:40
*/
@Service
@Transactional(rollbackFor = RuntimeException.class)
public class PaymentServiceImpl extends ServiceImpl<PaymentMapper, Payment> implements PaymentService {
}
package com.fzm.common.utils;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.IdUtil;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
@Slf4j
public class SnowflakeUtil {
@JsonFormat(shape = JsonFormat.Shape.STRING)
private long workerId = 0;//为终端ID
private long datacenterId = 1;//数据中心ID
private Snowflake snowflake = IdUtil.createSnowflake(workerId, datacenterId);
@PostConstruct
public void init() {
workerId = NetUtil.ipv4ToLong(NetUtil.getLocalhostStr());
log.info("当前机器的workId:{}", workerId);
}
public long snowflakeId() {
return snowflake.nextId();
}
public long snowflakeId(long workerId, long datacenterId) {
Snowflake snowflake = IdUtil.createSnowflake(workerId, datacenterId);
return snowflake.nextId();
}
}
2022-01-18 17:04:13.739 [background-preinit] INFO org.hibernate.validator.internal.util.Version-HV000001: Hibernate Validator 6.1.7.Final
2022-01-18 17:04:13.756 [main] INFO com.fzm.portal.WxPayTest-Starting WxPayTest on LAPTOP-AT8CNAMK with PID 117992 (started by tangtuo in D:\workspace\fzm-joying\joying-portal)
2022-01-18 17:04:13.757 [main] INFO com.fzm.portal.WxPayTest-The following profiles are active: nj
2022-01-18 17:04:14.838 [main] INFO o.s.d.r.config.RepositoryConfigurationDelegate-Multiple Spring Data modules found, entering strict repository configuration mode!
2022-01-18 17:04:14.841 [main] INFO o.s.d.r.config.RepositoryConfigurationDelegate-Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2022-01-18 17:04:14.894 [main] INFO o.s.d.r.config.RepositoryConfigurationDelegate-Finished Spring Data repository scanning in 13ms. Found 0 Redis repository interfaces.
2022-01-18 17:04:16.143 [main] INFO c.a.d.s.b.a.DruidDataSourceAutoConfigure-Init DruidDataSource
2022-01-18 17:04:18.251 [main] INFO com.alibaba.druid.pool.DruidDataSource-{dataSource-1} inited
2022-01-18 17:04:21.406 [main] INFO com.obs.services.ObsClient-Storage|1|HTTP+XML|ObsClient||||2022-01-18 17:04:20|2022-01-18 17:04:21|||0|
2022-01-18 17:04:21.408 [main] WARN com.obs.services.ObsClient-[OBS SDK Version=3.20.6.1];[Endpoint=https://obs.cn-east-3.myhuaweicloud.com:443/];[Access Mode=Virtul Hosting]
2022-01-18 17:04:21.741 [main] INFO org.redisson.Version-Redisson 3.16.0
2022-01-18 17:04:22.734 [redisson-netty-4-20] INFO o.r.connection.pool.MasterPubSubConnectionPool-1 connections initialized for 146.56.218.121/146.56.218.121:6379
2022-01-18 17:04:22.872 [redisson-netty-4-19] INFO org.redisson.connection.pool.MasterConnectionPool-24 connections initialized for 146.56.218.121/146.56.218.121:6379
2022-01-18 17:04:23.032 [main] WARN c.b.mybatisplus.core.metadata.TableInfoHelper-Warn: Could not find @TableId in Class: com.fzm.common.entity.CopyrightApplyOwnerRelation.
2022-01-18 17:04:23.170 [main] WARN c.b.mybatisplus.core.metadata.TableInfoHelper-Warn: Could not find @TableId in Class: com.fzm.common.entity.CopyrightAuthorityRelation.
2022-01-18 17:04:23.313 [main] INFO o.s.scheduling.concurrent.ThreadPoolTaskExecutor-Initializing ExecutorService 'threadPoolTaskExecutor'
2022-01-18 17:04:25.206 [scheduled_update_cert_thread] INFO c.w.p.c.apache.httpclient.cert.CertificatesManager-Begin update Certificates.Date:2022-01-18T09:04:25.206Z
2022-01-18 17:04:25.251 [main] INFO s.d.s.w.PropertySourcedRequestMappingHandlerMapping-Mapped URL path [/v2/api-docs] onto method [springfox.documentation.swagger2.web.Swagger2Controller#getDocumentation(String, HttpServletRequest)]
2022-01-18 17:04:25.446 [scheduled_update_cert_thread] INFO c.w.p.c.apache.httpclient.cert.CertificatesManager-Finish update Certificates.Date:2022-01-18T09:04:25.445Z
2022-01-18 17:04:26.989 [main] INFO s.d.s.web.plugins.DocumentationPluginsBootstrapper-Context refreshed
2022-01-18 17:04:27.034 [main] INFO s.d.s.web.plugins.DocumentationPluginsBootstrapper-Found 1 custom documentation plugin(s)
2022-01-18 17:04:27.085 [main] INFO s.d.spring.web.scanners.ApiListingReferenceScanner-Scanning for api listing references
2022-01-18 17:04:27.271 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: listUsingGET_1
2022-01-18 17:04:27.278 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: listUsingGET_2
2022-01-18 17:04:27.292 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: listUsingGET_3
2022-01-18 17:04:27.317 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: listUsingGET_4
2022-01-18 17:04:27.357 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: getByIdUsingGET_1
2022-01-18 17:04:27.381 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: listUsingGET_5
2022-01-18 17:04:27.409 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: addUsingPOST_1
2022-01-18 17:04:27.410 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: deleteUsingPOST_1
2022-01-18 17:04:27.416 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: listUsingGET_6
2022-01-18 17:04:27.417 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: updateUsingPOST_1
2022-01-18 17:04:27.419 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: deleteUsingPOST_2
2022-01-18 17:04:27.423 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: listUsingGET_7
2022-01-18 17:04:27.431 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: getByIdUsingGET_2
2022-01-18 17:04:27.433 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: submitUsingPOST_1
2022-01-18 17:04:27.474 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: listUsingGET_8
2022-01-18 17:04:27.483 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: publishUsingPOST_1
2022-01-18 17:04:27.504 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: saveUsingPOST_1
2022-01-18 17:04:27.513 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: getDetailUsingGET_1
2022-01-18 17:04:27.516 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: listUsingGET_9
2022-01-18 17:04:27.519 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: listUsingGET_10
2022-01-18 17:04:27.521 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: deleteUsingPOST_3
2022-01-18 17:04:27.522 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: downloadUsingPOST_1
2022-01-18 17:04:27.524 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: uploadUsingPOST_1
2022-01-18 17:04:27.564 [main] INFO s.d.s.w.r.operation.CachingOperationNameGenerator-Generating unique operation named: updateUsingPOST_2
2022-01-18 17:04:27.598 [main] INFO com.fzm.portal.WxPayTest-Started WxPayTest in 14.245 seconds (JVM running for 15.64)
2022-01-18 17:04:28.366 [SpringContextShutdownHook] INFO o.s.scheduling.concurrent.ThreadPoolTaskExecutor-Shutting down ExecutorService 'threadPoolTaskExecutor'
2022-01-18 17:04:28.565 [SpringContextShutdownHook] INFO com.alibaba.druid.pool.DruidDataSource-{dataSource-1} closing ...
2022-01-18 17:04:28.574 [SpringContextShutdownHook] INFO com.alibaba.druid.pool.DruidDataSource-{dataSource-1} closed
This diff is collapsed.
...@@ -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-portal</artifactId> <artifactId>joying-portal</artifactId>
...@@ -36,6 +36,11 @@ ...@@ -36,6 +36,11 @@
<artifactId>joying-common</artifactId> <artifactId>joying-common</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
package com.fzm.portal.config;
import org.springframework.amqp.core.*;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author tangtuo
* @date 2022/1/21 11:28
*/
@Configuration
public class RabbitConfig {
/**
* 处理订单的交换机
*/
@Bean
public DirectExchange orderExchange() {
return new DirectExchange("order-exchange", true, false);
}
/**
* 处理订单的队列
*
* @return
*/
@Bean
public Queue orderQueue() {
return new Queue("order.process.queue", true);
}
/**
* 处理订单的队列和交换机之间的绑定
*
* @return
*/
@Bean
public Binding orderBinding() {
return BindingBuilder.bind(orderQueue()).to(orderExchange()).with("order.process");
}
/**
* 发行nft的交换机
*
* @return
*/
@Bean
public DirectExchange nftExchange() {
return new DirectExchange("nft-exchange", true, false);
}
/**
* 死信交换机,死信到期后将会被转发到这个交换机,然后再路由到相应的队列
*/
@Bean
public DirectExchange dlNftExchange() {
return new DirectExchange("dl-nft-exchange", true, false);
}
/**
* 死信队列,用户把nft的交易hash发到此队列,
*
* @return
*/
@Bean
public Queue dlNftQueue() {
return QueueBuilder.durable("dl.nft.queue")
.ttl(1000 * 10)
.deadLetterExchange("dl-nft-exchange")
.deadLetterRoutingKey("nft")
.build();
}
/**
* 接收死信的列队,用户监听这个队列
*
* @return
*/
@Bean
public Queue nftPublishQueue() {
return new Queue("nft.publish.queue", true);
}
/**
* 死信队列和nft交换机的绑定
*
* @return
*/
@Bean
public Binding dlNftBinding() {
return BindingBuilder.bind(dlNftQueue()).to(nftExchange()).with("nft.publish");
}
@Bean
public Binding nftBinding() {
return BindingBuilder.bind(nftPublishQueue()).to(dlNftExchange()).with("nft");
}
@Bean
public MessageConverter messageConverter() {
return new Jackson2JsonMessageConverter();
}
}
...@@ -58,19 +58,19 @@ public class NftController { ...@@ -58,19 +58,19 @@ public class NftController {
@Authentication @Authentication
@PostMapping("/save") @PostMapping("/save")
@ApiOperation(value = "nft基本信息保存(基本信息和加密上链两个步骤)") @ApiOperation(value = "nft基本信息保存(基本信息和加密上链两个步骤)")
public ResponseModel<NftDto> save(@Validated @ModelAttribute Nft nft) { public ResponseModel<Integer> save(@Validated @ModelAttribute Nft nft) {
return ResponseModel.success(nftService.saveNft(nft)); return ResponseModel.success(nftService.saveNft(nft));
} }
@Authentication // @Authentication
@PostMapping("/publish") // @PostMapping("/publish")
@ApiOperation("发行nft") // @ApiOperation("发行nft")
public ResponseModel<Integer> publish(@Validated @RequestBody NftDto nftDto) { // public ResponseModel<Integer> publish(@Validated @RequestBody NftDto nftDto) {
Integer id = nftService.publish(nftDto); // Integer id = nftService.publish(nftDto);
//
return ResponseModel.success(id); // return ResponseModel.success(id);
} // }
@GetMapping("/list") @GetMapping("/list")
@ApiOperation(value = "获取nft列表") @ApiOperation(value = "获取nft列表")
......
package com.fzm.portal.controller;
import com.fzm.common.annotation.Authentication;
import com.fzm.common.entity.Order;
import com.fzm.common.entity.dto.OrderDto;
import com.fzm.common.enums.PayScene;
import com.fzm.common.model.ResponseModel;
import com.fzm.common.service.CopyrightApplyService;
import com.fzm.common.service.NftService;
import com.fzm.common.service.OrderService;
import com.fzm.common.utils.SnowflakeUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* @author tangtuo
* @date 2022/1/20 18:22
*/
@Authentication
@Api(tags = "作品类别")
@RestController
@RequestMapping("/opus/category")
public class OrderController {
@Resource
private OrderService orderService;
@PostMapping("/create")
@ApiOperation("下单")
public ResponseModel<Long> createOrder(@RequestBody OrderDto orderDto) {
Long orderId = orderService.createOrder(orderDto);
return ResponseModel.success(orderId);
}
@GetMapping("/query-order-status")
@ApiOperation(value = "查询订单状态")
public ResponseModel<Integer> queryOrderStatus(@PathVariable Long orderId) {
return ResponseModel.success(orderService.getById(orderId).getOrderStatus());
}
}
package com.fzm.portal.controller; package com.fzm.portal.controller;
import cn.hutool.http.HttpStatus;
import com.fzm.common.annotation.Authentication; import com.fzm.common.annotation.Authentication;
import com.fzm.common.entity.dto.JsapiPayDto;
import com.fzm.common.entity.dto.OrderDto;
import com.fzm.common.model.ResponseModel; import com.fzm.common.model.ResponseModel;
import com.fzm.common.service.WxPayService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
/** /**
* @author tangtuo * @author tangtuo
* @date 2022/1/13 9:55 * @date 2022/1/13 9:55
*/ */
@Authentication
@Api(tags = "微信支付") @Api(tags = "微信支付")
@RestController @RestController
@RequestMapping("/wx-pay") @RequestMapping("/wx-pay")
public class WxPayController { public class WxPayController {
@PostMapping("/pay/h5") @Resource
@ApiOperation(value = "发起h5支付") private WxPayService wxPayService;
public ResponseModel<String> payH5() {
@Authentication
@PostMapping("/pay/jsapi")
@ApiOperation(value = "发起jsapi支付")
public ResponseModel<Map<String, Object>> payH5(@RequestBody JsapiPayDto jsapiPayDto) throws Exception {
return ResponseModel.success(wxPayService.payJsapi(jsapiPayDto));
}
return ResponseModel.success(); @ApiOperation("jsapi支付回调通知")
@PostMapping("/notify/jsapi")
public Map<String, String> notifyJsapi(HttpServletRequest request, HttpServletResponse response) {
Map<String, String> result = new HashMap<>();
Boolean notify = wxPayService.notifyH5(request);
if (notify) {
result.put("code", "SUCCESS");
result.put("message", "成功");
response.setStatus(HttpStatus.HTTP_OK);
} else {
result.put("code", "FAILED");
result.put("message", "系统异常");
response.setStatus(HttpStatus.HTTP_INTERNAL_ERROR);
}
return result;
} }
} }
package com.fzm.portal.listener;
import com.fzm.common.entity.dto.OrderProcessMsg;
import com.fzm.common.enums.CopyrightApplyState;
import com.fzm.common.enums.PayScene;
import com.fzm.common.service.CopyrightApplyService;
import com.fzm.common.service.NftService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* @author tangtuo
* @date 2022/1/21 11:44
*/
@Slf4j
@Component
public class OrderListener {
@Resource
private NftService nftService;
@Resource
private CopyrightApplyService copyrightApplyService;
@RabbitListener(queues = "order.process.queue")
public void listenProcessOrder(OrderProcessMsg msg) {
log.info("收到处理订单的消息: {}", msg);
if (PayScene.NFT.getCode().equals(msg.getPayScene())) {
// 如果支付场景是发行nft的话,需要把此订单的nft发行
nftService.publish(msg.getProductId());
} else {
// 如果支付场景是版权申请的话,需要把当前订单对应的版权状态改为待核验
copyrightApplyService.updateRegisterState(msg.getProductId(), CopyrightApplyState.TO_BE_REVIEWED.getCode());
}
}
@RabbitListener(queues = "nft.publish.queue")
public void listenProcessOrder(Long id) {
log.info("接收到信息: {}", id);
}
}
...@@ -45,7 +45,19 @@ spring: ...@@ -45,7 +45,19 @@ spring:
type: redis type: redis
redis: redis:
time-to-live: 86400000 time-to-live: 86400000
rabbitmq:
host: 172.16.101.135
port: 5672
username: admin
password: admin
listener:
simple:
retry:
enabled: true
max-attempts: 5 # 最大重试次数
initial-interval: 1000 # 初始的失败等待时长为1秒
multiplier: 2 # 下次失败的等待时长倍数,下次等待时长 = multiplier * last-interval
stateless: true # true无状态;false有状态。如果业务中包含事务,这里改为false
swagger: swagger:
title: 乐映影视门户系统 title: 乐映影视门户系统
description: 乐映影视门户系统RESTFUL API description: 乐映影视门户系统RESTFUL API
...@@ -96,7 +108,10 @@ huaweiyun: ...@@ -96,7 +108,10 @@ huaweiyun:
wx-pay: wx-pay:
app-id: wxbdddd81913c795e9 app-id: wxbdddd81913c795e9
app-secret: aa201717c46a0e07c4c143b1ee73229a
mch-id: 1604477044 mch-id: 1604477044
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
h5-pay-notify-url: https://146.56.218.121:12100/wx-pay/notify/h5
h5-refund-notify-url:
...@@ -54,10 +54,10 @@ spring: ...@@ -54,10 +54,10 @@ spring:
simple: simple:
retry: retry:
enabled: true enabled: true
max-attempts: 5 max-attempts: 5 # 最大重试次数
initial-interval: 1000 initial-interval: 1000 # 初始的失败等待时长为1秒
multiplier: 2 multiplier: 2 # 下次失败的等待时长倍数,下次等待时长 = multiplier * last-interval
stateless: true stateless: true # true无状态;false有状态。如果业务中包含事务,这里改为false
swagger: swagger:
title: 乐映影视门户系统 title: 乐映影视门户系统
description: 乐映影视门户系统RESTFUL API description: 乐映影视门户系统RESTFUL API
...@@ -108,7 +108,10 @@ huaweiyun: ...@@ -108,7 +108,10 @@ huaweiyun:
wx-pay: wx-pay:
app-id: wxbdddd81913c795e9 app-id: wxbdddd81913c795e9
app-secret: aa201717c46a0e07c4c143b1ee73229a
mch-id: 1604477044 mch-id: 1604477044
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
h5-pay-notify-url: https://146.56.218.121:12100/wx-pay/notify/h5
h5-refund-notify-url:
\ No newline at end of file
...@@ -46,7 +46,19 @@ spring: ...@@ -46,7 +46,19 @@ spring:
type: redis type: redis
redis: redis:
time-to-live: 86400000 time-to-live: 86400000
rabbitmq:
host: 129.211.166.223
port: 5672
username: guest
password: guest
listener:
simple:
retry:
enabled: true
max-attempts: 5 # 最大重试次数
initial-interval: 1000 # 初始的失败等待时长为1秒
multiplier: 2 # 下次失败的等待时长倍数,下次等待时长 = multiplier * last-interval
stateless: true # true无状态;false有状态。如果业务中包含事务,这里改为false
swagger: swagger:
title: 乐映影视门户系统 title: 乐映影视门户系统
description: 乐映影视门户系统RESTFUL API description: 乐映影视门户系统RESTFUL API
...@@ -109,7 +121,10 @@ huaweiyun: ...@@ -109,7 +121,10 @@ huaweiyun:
wx-pay: wx-pay:
app-id: wxbdddd81913c795e9 app-id: wxbdddd81913c795e9
app-secret: aa201717c46a0e07c4c143b1ee73229a
mch-id: 1604477044 mch-id: 1604477044
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
h5-pay-notify-url: https://test.inmvo.com:8985/proxyApi/wx-pay/notify/h5
h5-refund-notify-url:
...@@ -46,6 +46,19 @@ spring: ...@@ -46,6 +46,19 @@ spring:
type: redis type: redis
redis: redis:
time-to-live: 86400000 time-to-live: 86400000
rabbitmq:
host: 192.168.0.11
port: 5672
username: admin
password: admin
listener:
simple:
retry:
enabled: true
max-attempts: 5 # 最大重试次数
initial-interval: 1000 # 初始的失败等待时长为1秒
multiplier: 2 # 下次失败的等待时长倍数,下次等待时长 = multiplier * last-interval
stateless: true # true无状态;false有状态。如果业务中包含事务,这里改为false
swagger: swagger:
title: 乐映影视门户系统 title: 乐映影视门户系统
...@@ -97,7 +110,10 @@ huaweiyun: ...@@ -97,7 +110,10 @@ huaweiyun:
wx-pay: wx-pay:
app-id: wxbdddd81913c795e9 app-id: wxbdddd81913c795e9
app-secret: aa201717c46a0e07c4c143b1ee73229a
mch-id: 1604477044 mch-id: 1604477044
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
h5-pay-notify-url: https://nft.inmvo.com/proxyApi/wx-pay/notify/h5
h5-refund-notify-url:
\ No newline at end of file
spring: spring:
profiles: profiles:
active: nj active: local
application: application:
name: joying-portal name: joying-portal
servlet: servlet:
......
...@@ -86,7 +86,7 @@ class LyPortalApplicationTests { ...@@ -86,7 +86,7 @@ class LyPortalApplicationTests {
} }
@Test @Test
void contextLoads() { public void contextLoads() {
System.out.println("redisson = " + redisson); System.out.println("redisson = " + redisson);
RSemaphore semaphore = redisson.getSemaphore("banner09"); RSemaphore semaphore = redisson.getSemaphore("banner09");
boolean b = semaphore.trySetPermits(10); boolean b = semaphore.trySetPermits(10);
......
package com.fzm.portal;
import com.fzm.common.utils.SnowflakeUtil;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
/**
* @author tangtuo
* @date 2022/1/19 14:04
*/
@SpringBootTest
public class SnawFlakeTest {
@Resource
private SnowflakeUtil snowflakeUtil;
@Test
public void test1() {
System.out.println(snowflakeUtil.snowflakeId());
}
}
...@@ -3,6 +3,9 @@ package com.fzm.portal; ...@@ -3,6 +3,9 @@ package com.fzm.portal;
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.properties.WxPayProperties; import com.fzm.common.properties.WxPayProperties;
import com.fzm.common.service.WxPayService;
import com.fzm.common.utils.SnowflakeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
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;
...@@ -19,6 +22,7 @@ import java.io.IOException; ...@@ -19,6 +22,7 @@ import java.io.IOException;
* @author tangtuo * @author tangtuo
* @date 2022/1/13 15:30 * @date 2022/1/13 15:30
*/ */
@Slf4j
@SpringBootTest @SpringBootTest
public class WxPayTest { public class WxPayTest {
...@@ -29,34 +33,79 @@ public class WxPayTest { ...@@ -29,34 +33,79 @@ public class WxPayTest {
@Resource @Resource
private WxPayProperties wxPayProperties; private WxPayProperties wxPayProperties;
@Resource
private WxPayService wxPayService;
@Resource
private SnowflakeUtil snowflakeUtil;
@Test
public void testSnowFlake() {
for (int i = 0; i < 10; i++) {
log.info(String.valueOf(snowflakeUtil.snowflakeId()));
}
}
@Test @Test
public void testH5Pay() throws IOException { public void testH5Pay() throws IOException {
for (int i = 0; i < 10; i++) {
log.info(String.valueOf(snowflakeUtil.snowflakeId()));
}
// String url = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
// HttpPost httpPost = new HttpPost(url);
// httpPost.addHeader("Accept", "application/json");
// httpPost.addHeader("Content-type", "application/json; charset=utf-8");
// ByteArrayOutputStream bos = new ByteArrayOutputStream();
// ObjectMapper objectMapper = new ObjectMapper();
//
// ObjectNode rootNode = objectMapper.createObjectNode();
// rootNode.put("mchid", wxPayProperties.getMchId())
// .put("appid", wxPayProperties.getAppId())
// .put("description", "Image形象店-深圳腾大-QQ公仔")
// .put("notify_url", "http://www.baidu.com")
// .put("out_trade_no", "nft-123");
// rootNode.putObject("amount")
// .put("total", 1);
// rootNode.putObject("payer")
// .put("openid", "oRpMVw3OiOuVDZPrJTzMwTJALf70");
// String json = objectMapper.writeValueAsString(rootNode);
// System.out.println("json = " + json);
// objectMapper.writeValue(bos, rootNode);
//
// httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
// CloseableHttpResponse response = httpClient.execute(httpPost);
//
// String bodyAsString = EntityUtils.toString(response.getEntity());
// System.out.println(bodyAsString);
//
// String data = "wx8888888888888888\n1414561699\n5K8264ILTKCH16CQ2502SI8ZNMTM67VS\nprepay_id=wx201410272009395522657a690389285100";
// try {
// System.out.println(wxPayService.encryptByPrivateKey(data));
// } catch (Exception e) {
// e.printStackTrace();
// }
}
@Test
void test() {
String prepay_id = "wx181704295362907bc91140bfb2a71b0000";
String url = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi"; String url = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
HttpPost httpPost = new HttpPost(url); HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Accept", "application/json"); httpPost.addHeader("Accept", "application/json");
httpPost.addHeader("Content-type","application/json; charset=utf-8"); httpPost.addHeader("Content-type", "application/json; charset=utf-8");
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("mchid", wxPayProperties.getMchId())
.put("appid", wxPayProperties.getAppId()) .put("appid", wxPayProperties.getAppId())
.put("description", "Image形象店-深圳腾大-QQ公仔") .put("description", "Image形象店-深圳腾大-QQ公仔")
.put("notify_url", "http://www.baidu.com") .put("notify_url", "http://www.baidu.com")
.put("out_trade_no", "nft-123"); .put("out_trade_no", "nft-123");
rootNode.putObject("amount") }
.put("total", 1);
rootNode.putObject("payer")
.put("openid", "oRG0ZxPPF0fbH1KCmMV5goJ69W8I");
String json = objectMapper.writeValueAsString(rootNode);
System.out.println("json = " + json);
objectMapper.writeValue(bos, rootNode);
httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
CloseableHttpResponse response = httpClient.execute(httpPost);
String bodyAsString = EntityUtils.toString(response.getEntity());
System.out.println(bodyAsString);
}
} }
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<groupId>com.fzm</groupId> <groupId>com.fzm</groupId>
<artifactId>fzm-joying</artifactId> <artifactId>fzm-joying</artifactId>
<version>1.0.0</version> <version>1.1.0</version>
<modules> <modules>
<module>joying-common</module> <module>joying-common</module>
<module>joying-portal</module> <module>joying-portal</module>
......
...@@ -574,5 +574,40 @@ UPDATE `tb_opus_category` SET `value` = '其他作品' WHERE `id` = 18; ...@@ -574,5 +574,40 @@ UPDATE `tb_opus_category` SET `value` = '其他作品' WHERE `id` = 18;
alter table tb_copyright_apply modify column evidence_date datetime DEFAULT NULL COMMENT '存证时间'; alter table tb_copyright_apply modify column evidence_date datetime DEFAULT NULL COMMENT '存证时间';
-- v2.1.0 -- v2.1.0
CREATE UNIQUE INDEX idx_nfthash ON tb_entrust_shelf ( nft_hash );
alter table tb_nft add column is_entrust tinyint(1) not null default 0 comment '是否已委托上架 0-否 1-是' after status; alter table tb_nft add column is_entrust tinyint(1) not null default 0 comment '是否已委托上架 0-否 1-是' after status;
CREATE TABLE `tb_entrust_shelf` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL COMMENT '用户id',
`nft_hash` varchar(255) NOT NULL COMMENT 'nft哈希',
`name` varchar(12) NOT NULL DEFAULT '' COMMENT '姓名',
`telephone` varchar(16) NOT NULL DEFAULT '' COMMENT '电话号码',
`wechat_num` varchar(128) DEFAULT NULL COMMENT '微信号',
`status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0-委托中 1-已取消',
`create_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='委托上架';
CREATE TABLE `tb_banner` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL DEFAULT '' COMMENT '名称',
`poster` varchar(255) NOT NULL DEFAULT '' COMMENT '海报',
`jump_url` varchar(255) NOT NULL DEFAULT '' COMMENT '跳转地址',
`sort` int(2) NOT NULL DEFAULT '0' COMMENT '排序',
`create_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
CREATE TABLE `tb_order` (
`id` bigint(20) NOT NULL,
`pay_scene` tinyint(1) NOT NULL COMMENT '支付场景 1-nft发行 2-版权申请',
`product_id` int(11) NOT NULL COMMENT '产品id nft主键或者版权主键',
`user_id` int(11) NOT NULL COMMENT '用户id',
`fee` bigint(20) NOT NULL COMMENT '订单价格-单位(分)',
`order_status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0-支付中 1-支付成功 2-订单已关闭 3-已退款',
`prepay_id` varchar(128) NOT NULL COMMENT '微信预支付交易会话标识',
`create_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
\ 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