package com.yami.trading.api.controller.exchange;
|
|
import cn.hutool.core.lang.Console;
|
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.http.HttpStatus;
|
import cn.hutool.json.JSONUtil;
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONObject;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.yami.trading.bean.vo.RechargeAddressVo;
|
import com.yami.trading.common.util.RedisUtil;
|
import com.yami.trading.security.common.enums.CryptoCurrencyEnum;
|
import com.yami.trading.security.common.util.LocalKeyStorageAESUtil;
|
import com.yami.trading.api.UD.*;
|
import com.yami.trading.api.UD.Address;
|
import com.yami.trading.bean.exchange.PartyBlockchain;
|
import com.yami.trading.bean.model.ChannelBlockchain;
|
import com.yami.trading.bean.model.RechargeBlockchainOrder;
|
import com.yami.trading.bean.model.User;
|
import com.yami.trading.common.constants.Constants;
|
import com.yami.trading.common.domain.Result;
|
import com.yami.trading.common.exception.YamiShopBindException;
|
import com.yami.trading.common.util.MD5;
|
import com.yami.trading.common.util.StringUtils;
|
import com.yami.trading.security.common.util.SecurityUtils;
|
import com.yami.trading.service.ChannelBlockchainService;
|
import com.yami.trading.service.RechargeBlockchainOrderService;
|
import com.yami.trading.service.exchange.PartyBlockchainService;
|
import com.yami.trading.service.syspara.SysparaService;
|
import com.yami.trading.service.user.UserService;
|
import com.yami.trading.sys.model.SysUser;
|
import com.yami.trading.sys.service.SysUserService;
|
import io.swagger.annotations.Api;
|
import lombok.extern.slf4j.Slf4j;
|
import okhttp3.*;
|
import org.jetbrains.annotations.NotNull;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RestController;
|
|
import javax.servlet.http.HttpServletRequest;
|
import java.io.File;
|
import java.io.FileInputStream;
|
import java.io.IOException;
|
import java.io.ObjectInputStream;
|
import java.math.BigDecimal;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
@RestController
|
@Slf4j
|
@Api(tags = "区块链 -api")
|
public class ApiChannelBlockchainController {
|
@Autowired
|
private SysparaService sysparaService;
|
private final String action = "/api/channelBlockchain!";
|
@Autowired
|
private ChannelBlockchainService channelBlockchainService;
|
private OkHttpClient okHttpClient = new OkHttpClient();
|
private final String threedUrl = "https://api.star-pay.vip/api/gateway/pay";
|
@Autowired
|
UserService userService;
|
@Autowired
|
PartyBlockchainService partyBlockchainService;
|
@Autowired
|
RedisTemplate redisTemplate;
|
@Autowired
|
private SysUserService sysUserService;
|
@Autowired
|
RechargeBlockchainOrderService rechargeBlockchainOrderService;
|
@Autowired
|
protected UserService partyService;
|
|
private final String gateway = "https://sig11.udun.io";
|
private final String merchantKey = "7fd79e4ed59e7c31e1fa2e13d64f7e6c";
|
private final String merchantId = "319563";
|
private final String defaultCallBackUrl = "https://openapi.yanshiz.com/api/channelBlockchain!rechargeCallback.action";
|
|
|
|
/**
|
* 获取所有链地址
|
*/
|
@RequestMapping(action + "list.action")
|
public Object list() throws IOException {
|
List<ChannelBlockchain> data = new ArrayList<ChannelBlockchain>();
|
String partyId = SecurityUtils.getUser().getUserId();
|
User party = userService.getById(partyId);
|
List<PartyBlockchain> list = partyBlockchainService.findByUserName(party.getUserName());
|
if (null != list && !list.isEmpty()) {
|
data = list.stream().map(dict -> {
|
String qrImage = dict.getQrImage();
|
String chainAddress = dict.getAddress();
|
String chainName = dict.getChainName();
|
String coinSymbol = dict.getCoinSymbol();
|
String autoStr = dict.getAuto();
|
boolean auto = autoStr.equals("Y") ? true : false;
|
ChannelBlockchain cbc = new ChannelBlockchain();
|
cbc.setBlockchainName(chainName);
|
cbc.setBlockchain_name(chainName);
|
cbc.setAddress(chainAddress);
|
cbc.setCoin(coinSymbol);
|
cbc.setAuto(auto);
|
cbc.setImg(qrImage);
|
return cbc;
|
}).collect(Collectors.toList());
|
}
|
if (data.isEmpty()) data = channelBlockchainService.list();
|
for (int i = 0; i < data.size(); i++) {
|
data.get(i).setBlockchain_name(data.get(i).getBlockchainName());
|
if (1 == this.sysparaService.find("can_recharge").getInteger()) {
|
// 允许在线充值,展示二维码
|
if (!StringUtils.isNullOrEmpty(data.get(i).getImg())) {
|
String path = Constants.WEB_URL + "/public/showimg!showImg.action?imagePath=" + data.get(i).getImg();
|
data.get(i).setImg(path);
|
}
|
} else {
|
data.get(i).setImg(null);
|
data.get(i).setAddress(null);
|
}
|
}
|
return Result.succeed(data);
|
}
|
|
/**
|
* 根据币种获取链地址
|
*/
|
@GetMapping(action + "getBlockchainName.action")
|
public Object getBlockchainName(HttpServletRequest request) throws Exception {
|
String coin = request.getParameter("coin");
|
String partyId = SecurityUtils.getUser().getUserId();
|
return Result.succeed(getStringListMap(coin.toUpperCase(),partyId));
|
}
|
|
@NotNull
|
private List<ChannelBlockchain> getStringListMap(String coin,String partyId ) {
|
|
//获取商户支持币种
|
List<Coin> coinList = listSupportCoin(merchantId,false);
|
List<ChannelBlockchain> blockchainList = new ArrayList<>();
|
List<Coin> filteredCoins = coinList.stream()
|
.filter(c -> coin.equals(c.getSymbol()))
|
.collect(Collectors.toList());
|
//创建地址
|
filteredCoins.forEach(f->{
|
if(f.getName().equals("BTC")){
|
String partyBTC = Optional.ofNullable(RedisUtil.get(partyId + "_BTC"))
|
.map(Object::toString)
|
.orElse("");
|
if(!StringUtils.isNotEmpty(partyBTC)){
|
Address address3 = createAddress(f.getMainCoinType(),null,null,null);
|
blockchainList.add(createElement("2c948a8280828d5f018084ff569b0002", "btc", "/qr/1be19b34fbb9406c8044c1a9b08a87ca.png", address3.getAddress(),"BTC"));
|
RedisUtil.set(partyId+ "_BTC",address3.getAddress());
|
}else{
|
blockchainList.add(createElement("2c948a8280828d5f018084ff569b0002", "btc", "/qr/1be19b34fbb9406c8044c1a9b08a87ca.png", partyBTC,"BTC"));
|
}
|
}else if(f.getName().equals("ETH")){
|
String partyETH = Optional.ofNullable(RedisUtil.get(partyId + "_ETH"))
|
.map(Object::toString)
|
.orElse("");
|
if(!StringUtils.isNotEmpty(partyETH)){
|
Address address3 = createAddress(f.getMainCoinType(),null,null,null);
|
blockchainList.add(createElement("2c948a8280828d5f018084ff569b0002", "eth", "/qr/1be19b34fbb9406c8044c1a9b08a87ca.png", address3.getAddress(),"ETH"));
|
RedisUtil.set(partyId + "_ETH",address3.getAddress());
|
}else{
|
blockchainList.add(createElement("2c948a8280828d5f018084ff569b0002", "eth", "/qr/1be19b34fbb9406c8044c1a9b08a87ca.png", partyETH,"ETH"));
|
}
|
}else if(f.getName().equals("USDT-ERC20")){
|
String partyUSDT = Optional.ofNullable(RedisUtil.get(partyId + "_USDT-ERC20"))
|
.map(Object::toString)
|
.orElse("");
|
if(!StringUtils.isNotEmpty(partyUSDT)){
|
Address address3 = createAddress(f.getMainCoinType(),null,null,null);
|
blockchainList.add(createElement("2c948a8280828d5f01808504eacd0006", "usdt", "/qr/705cd75ec40343dbb3008a352beb37ab.png", address3.getAddress(),"ERC20"));
|
RedisUtil.set(partyId + "_USDT-ERC20",address3.getAddress());
|
}else{
|
blockchainList.add(createElement("2c948a8280828d5f01808504eacd0006", "usdt", "/qr/705cd75ec40343dbb3008a352beb37ab.png", partyUSDT,"ERC20"));
|
}
|
}else if(f.getName().equals("USDC")){
|
String partyUSDC = Optional.ofNullable(RedisUtil.get(partyId + "USDC"))
|
.map(Object::toString)
|
.orElse("");
|
if(!StringUtils.isNotEmpty(partyUSDC)){
|
Address address3 = createAddress(f.getMainCoinType(),null,null,null);
|
blockchainList.add(createElement("2c948a8280828d5f01808504eacd0004", "usdc", "/qr/975f4666ed044efa9f0ee2fa81fa8f4a.png", address3.getAddress(),"ERC20"));
|
RedisUtil.set(partyId + "USDC",address3.getAddress());
|
}else{
|
blockchainList.add(createElement("2c948a8280828d5f01808504eacd0004", "usdc", "/qr/975f4666ed044efa9f0ee2fa81fa8f4a.png", partyUSDC,"ERC20"));
|
}
|
}
|
});
|
return blockchainList;
|
}
|
|
public List<Coin> listSupportCoin(String merchantId , boolean showBalance) {
|
Map<String, Object> params = new HashMap<>();
|
params.put("merchantId", merchantId);
|
params.put("showBalance", showBalance);
|
ResultMsg result = JSONUtil.toBean(UdunUtils.post(gateway, merchantKey, ApiPath.SUPPORT_COIN, JSONUtil.toJsonStr(params)), ResultMsg.class);
|
if (result.getCode() != HttpStatus.HTTP_OK) {
|
Console.error(JSONUtil.toJsonStr(result));
|
return null;
|
}
|
return JSONUtil.toList(JSONUtil.parseArray(result.getData()), Coin.class);
|
}
|
|
public Address createAddress(String mainCoinType, String alias, String walletId, String callUrl) throws UdunException{
|
Map<String, String> params = new HashMap<>();
|
params.put("merchantId", merchantId);
|
params.put("coinType", mainCoinType);
|
params.put("callUrl", defaultCallBackUrl);
|
params.put("walletId", walletId);
|
params.put("alias", alias);
|
|
ResultMsg result = JSONUtil.toBean(UdunUtils.post(gateway, merchantKey, ApiPath.CREATE_ADDRESS, StrUtil.format("[{}]", JSONUtil.toJsonStr(params))), ResultMsg.class);
|
if (result.getCode() != HttpStatus.HTTP_OK) {
|
throw new UdunException(result.getCode(), result.getMessage());
|
}
|
return JSONUtil.toBean(result.getData(), Address.class);
|
}
|
|
private static ChannelBlockchain createElement(String id, String coin, String img, String address,String blockchain_name) {
|
ChannelBlockchain channelBlockchain = new ChannelBlockchain();
|
channelBlockchain.setCoin(coin);
|
channelBlockchain.setAddress(address);
|
channelBlockchain.setBlockchain_name(blockchain_name);
|
return channelBlockchain;
|
}
|
//回调地址关闭
|
// @RequestMapping(action +"rechargeCallback.action")
|
// public ResultMsg rechargeCallback(HttpServletRequest request){
|
// String timestamp = request.getParameter("timestamp");
|
// String nonce = request.getParameter("nonce");
|
// String sign = request.getParameter("sign");
|
// String body = request.getParameter("body");
|
// try{
|
// ObjectMapper objectMapper = new ObjectMapper();
|
// Map<String, Object> map = objectMapper.readValue(body, HashMap.class);
|
// double amounts = Double.parseDouble(map.get("amount").toString()); // 假设 amount 的值为 1000
|
// double decimals = Double.parseDouble(map.get("decimals").toString());
|
// double success_amount = amounts / Math.pow(10, decimals);
|
// String address = map.get("address").toString();
|
//
|
//
|
// RechargeBlockchainOrder blockchainOrder = rechargeBlockchainOrderService.getOne(new LambdaQueryWrapper<>(RechargeBlockchainOrder.class)
|
// .eq(RechargeBlockchainOrder::getSucceeded, 0)
|
// .eq(RechargeBlockchainOrder::getChannelAddress, address).last(" limit 1 "));
|
// if(ObjectUtil.isEmpty(blockchainOrder)){
|
// ResultMsg resultMsg = new ResultMsg();
|
// resultMsg.setCode(200);
|
// return resultMsg;
|
// }
|
// SysUser user = sysUserService.getSysUserById( Long.getLong(blockchainOrder.getPartyId()));
|
// rechargeBlockchainOrderService.manualReceipt(1,blockchainOrder.getPartyId(), BigDecimal.valueOf(success_amount),user.getUsername());
|
// ResultMsg resultMsg = new ResultMsg();
|
// resultMsg.setCode(200);
|
// return resultMsg;
|
// }catch (Exception e){
|
// ResultMsg resultMsg = new ResultMsg();
|
// resultMsg.setCode(500);
|
// resultMsg.setMessage("回调处理失败");
|
// return resultMsg;
|
// }
|
// }
|
|
/**
|
* 根据第三方充值链接
|
*/
|
@RequestMapping(action + "getThirdUrl.action")
|
public Result getThirdUrl(HttpServletRequest request) throws IOException {
|
|
String key = this.sysparaService.find("third_key").getSvalue();
|
String merchant_no = this.sysparaService.find("third_id").getSvalue();
|
int i = (int) (Math.random() * 900) + 100;
|
//商户号
|
//10位时间戳
|
String timestamp = "" + System.currentTimeMillis() / 1000;
|
String amount = request.getParameter("amount");
|
//法币名称
|
String fiat_currency = request.getParameter("fiat_currency");
|
//订单号
|
String merchant_ref = System.currentTimeMillis() + "" + i;
|
//产品名称
|
String product = "ERC20Buy";
|
String sign_type = "MD5";
|
Map<String, String> requestparam = new HashMap<>();
|
JSONObject params = new JSONObject(new LinkedHashMap<>());
|
JSONObject extra = new JSONObject(new LinkedHashMap<>());
|
extra.put("fiat_currency", fiat_currency);
|
params.put("merchant_ref", merchant_ref);
|
params.put("product", product);
|
params.put("amount", amount);
|
params.put("extra", extra);
|
String waitsign = merchant_no + params + sign_type + timestamp + key;
|
String sign = MD5.sign(waitsign);
|
requestparam.put("merchant_no", merchant_no);
|
requestparam.put("params", params.toJSONString());
|
requestparam.put("sign", sign);
|
requestparam.put("sign_type", sign_type);
|
requestparam.put("timestamp", params.toJSONString());
|
String result = "";
|
RequestBody body = new FormBody.Builder()
|
.add("merchant_no", merchant_no)
|
.add("timestamp", timestamp)
|
.add("sign_type", sign_type)
|
.add("params", params.toString())
|
.add("sign", sign)
|
.build();
|
Request requestParm = new Request.Builder()
|
.url(threedUrl)
|
.method("POST", body)
|
.addHeader("Content-Type", "application/x-www-form-urlencoded")
|
.build();
|
try {
|
Response response = okHttpClient.newCall(requestParm).execute();
|
result = response.body().string();
|
} catch (Exception e) {
|
throw new YamiShopBindException("请求第三方失败");
|
}
|
JSONObject resultJson = JSON.parseObject(result);
|
Integer code = resultJson.getInteger("code");
|
if (code == 200) {
|
JSONObject resultParams = resultJson.getJSONObject("params");
|
return Result.succeed(resultParams.getString("payurl"));
|
} else {
|
return Result.failed(resultJson.getString("message"));
|
|
}
|
}
|
}
|