update 租赁系统1.1.0 钱包地址参数加密,gpu矿机新增到订单流程测试修改等
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
package com.m2pool.lease.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 标记在方法上,表示需要对请求体进行解密
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Decrypt {
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.m2pool.lease.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 标记在字段上,表示该字段需要解密
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface EncryptedField {
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package com.m2pool.lease.aspect;
|
||||
|
||||
|
||||
import cn.hutool.crypto.asymmetric.RSA;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.m2pool.lease.annotation.EncryptedField;
|
||||
import com.m2pool.lease.exception.RSAException;
|
||||
import com.m2pool.lease.utils.RsaUtils;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class DecryptAspect {
|
||||
|
||||
// 定义切点,拦截所有带 @Decrypt 注解的方法
|
||||
@Pointcut("@annotation(com.m2pool.lease.annotation.Decrypt)")
|
||||
public void decryptPointcut() {}
|
||||
|
||||
@Around("decryptPointcut()")
|
||||
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
Object[] args = joinPoint.getArgs();
|
||||
Parameter[] parameters = ((MethodSignature) joinPoint.getSignature()).getMethod().getParameters();
|
||||
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
// 找到被 @RequestBody 标记的参数
|
||||
if (parameters[i].isAnnotationPresent(RequestBody.class)) {
|
||||
Object requestBody = args[i];
|
||||
// 递归解密对象中的加密字段
|
||||
decryptObjectFields(requestBody);
|
||||
}
|
||||
}
|
||||
// 继续执行原方法
|
||||
return joinPoint.proceed(args);
|
||||
}
|
||||
|
||||
private void decryptObjectFields(Object obj) {
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理集合或数组类型
|
||||
if (obj instanceof Collection) {
|
||||
for (Object item : (Collection<?>) obj) {
|
||||
decryptObjectFields(item);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理Map类型
|
||||
if (obj instanceof Map) {
|
||||
for (Object value : ((Map<?, ?>) obj).values()) {
|
||||
decryptObjectFields(value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理普通对象
|
||||
Field[] fields = obj.getClass().getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
if (field.isAnnotationPresent(EncryptedField.class)) {
|
||||
handleEncryptedField(obj, field);
|
||||
} else {
|
||||
//这里可能是普通对象或者集合或其他非EncryptedField标记的普通属性字段
|
||||
handleNestedField(obj, field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleEncryptedField(Object obj, Field field) {
|
||||
field.setAccessible(true);
|
||||
try {
|
||||
Object value = field.get(obj);
|
||||
if (value != null) {
|
||||
String encryptedValue = value.toString();
|
||||
System.out.println("加密前地址:"+value +"类型"+(value instanceof String));
|
||||
String decryptedValue = RsaUtils.decrypt(encryptedValue);
|
||||
System.out.println("解密后地址:"+decryptedValue);
|
||||
field.set(obj, decryptedValue);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RSAException("解密失败: " + e.getMessage());
|
||||
} finally {
|
||||
field.setAccessible(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleNestedField(Object obj, Field field) {
|
||||
field.setAccessible(true);
|
||||
try {
|
||||
Object fieldValue = field.get(obj);
|
||||
if (fieldValue != null && !isPrimitiveOrWrapper(fieldValue)) {
|
||||
decryptObjectFields(fieldValue);
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
// 忽略访问异常
|
||||
} finally {
|
||||
field.setAccessible(false);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPrimitiveOrWrapper(Object obj) {
|
||||
Class<?> clazz = obj.getClass();
|
||||
return clazz.isPrimitive() ||
|
||||
clazz == String.class ||
|
||||
clazz == Integer.class ||
|
||||
clazz == Long.class ||
|
||||
clazz == Double.class ||
|
||||
clazz == Float.class ||
|
||||
clazz == Boolean.class ||
|
||||
clazz == Character.class ||
|
||||
clazz == Byte.class ||
|
||||
clazz == Short.class ||
|
||||
clazz == BigDecimal.class;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
package com.m2pool.lease.controller;
|
||||
|
||||
|
||||
import com.m2pool.lease.annotation.Decrypt;
|
||||
import com.m2pool.lease.dto.PageResult;
|
||||
import com.m2pool.lease.dto.Result;
|
||||
import com.m2pool.lease.dto.v2.CoinAndAlgorithmListDto;
|
||||
import com.m2pool.lease.dto.v2.MiningInfoDto;
|
||||
import com.m2pool.lease.dto.v2.PurchasedMachineDto;
|
||||
import com.m2pool.lease.dto.v2.PurchasedMachineListDto;
|
||||
import com.m2pool.lease.dto.v2.*;
|
||||
import com.m2pool.lease.service.LeaseOrderInfoService;
|
||||
import com.m2pool.lease.vo.BaseVo;
|
||||
import com.m2pool.lease.vo.OrderAndCodeVo;
|
||||
@@ -52,6 +50,7 @@ public class LeaseOrderInfoV2Controller {
|
||||
|
||||
@ApiOperation("创建订单及订单详情 + 支付订单(返回二维码内容)")
|
||||
@PostMapping("/addOrdersV2")
|
||||
@Decrypt
|
||||
public Result<String> addOrdersV2(@RequestBody OrderAndCodeVo orderAndCodeVo) {
|
||||
return leaseOrderInfoService.addOrdersV2(orderAndCodeVo);
|
||||
}
|
||||
@@ -70,7 +69,7 @@ public class LeaseOrderInfoV2Controller {
|
||||
|
||||
@ApiOperation("买家:根据id查询已购矿机详情")
|
||||
@PostMapping("/getPurchasedInfo")
|
||||
public Result<PurchasedMachineDto> getPurchasedInfo(@RequestBody BaseVo baseVo) {
|
||||
public Result<MiningConfigInfoDto> getPurchasedInfo(@RequestBody BaseVo baseVo) {
|
||||
return leaseOrderInfoService.getPurchasedInfo(baseVo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.m2pool.lease.controller;
|
||||
|
||||
|
||||
import com.m2pool.lease.annotation.Decrypt;
|
||||
import com.m2pool.lease.dto.*;
|
||||
import com.m2pool.lease.service.LeaseProductService;
|
||||
import com.m2pool.lease.service.LeaseUserOwnedProductService;
|
||||
@@ -14,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -121,6 +123,7 @@ public class LeaseProductController {
|
||||
|
||||
@ApiOperation("新增绑定店铺钱包并设置店铺下面每个矿机该钱包币种的售价 + 钱包绑定")
|
||||
@PostMapping("/updateProductListForShopWalletConfig")
|
||||
@Decrypt
|
||||
public Result<String> updateProductListForShopWalletConfig(@RequestBody ProductMachineForWalletConfigVo productMachineForWalletConfigVo) {
|
||||
return leaseProductService.updateProductListForShopWalletConfig(productMachineForWalletConfigVo);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.m2pool.lease.dto;
|
||||
|
||||
import com.m2pool.lease.annotation.EncryptedField;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
@@ -7,7 +8,6 @@ import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -26,6 +26,7 @@ import java.util.List;
|
||||
public class ProductMachineForWalletConfigVo {
|
||||
|
||||
@ApiModelProperty(value = "钱包地址")
|
||||
@EncryptedField
|
||||
private String payAddress;
|
||||
|
||||
@ApiModelProperty(value = "支付链")
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
package com.m2pool.lease.dto.v2;
|
||||
|
||||
|
||||
import com.m2pool.lease.dto.PageResult;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@@ -37,4 +34,29 @@ public class CoinAndAlgorithmDto {
|
||||
*/
|
||||
private Boolean isEffect;
|
||||
|
||||
/**
|
||||
* gpu名称
|
||||
*/
|
||||
private String model;
|
||||
|
||||
/**
|
||||
* gpu 功耗
|
||||
*/
|
||||
private BigDecimal powerDissipation;
|
||||
|
||||
/**
|
||||
* gpu 理论算力
|
||||
*/
|
||||
private BigDecimal hashRate;
|
||||
|
||||
/**
|
||||
* 月收入
|
||||
*/
|
||||
private BigDecimal monthIncome;
|
||||
|
||||
/**
|
||||
* 是否新增 gpu 配置
|
||||
*/
|
||||
private Boolean isAdd;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.m2pool.lease.dto.v2;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 商品列表分页请求对象
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class MachineHashRateMapDto {
|
||||
private Long machineId;
|
||||
|
||||
private BigDecimal hashRate;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.m2pool.lease.dto.v2;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import scala.math.BigDecimal;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 挖矿中订单
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-12-02
|
||||
*/
|
||||
@Builder
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ApiModel(description = "已购商品挖矿配置详情返回对象",value = "MiningConfigInfoDto" )
|
||||
public class MiningConfigInfoDto {
|
||||
|
||||
@ApiModelProperty(value = "矿池所挖币种")
|
||||
private String coin;
|
||||
|
||||
@ApiModelProperty(value = "币种对应算法")
|
||||
private String algorithm;
|
||||
|
||||
|
||||
@ApiModelProperty(value = "矿池名称")
|
||||
private String pool;
|
||||
|
||||
|
||||
@ApiModelProperty(value = "矿池挖矿地址")
|
||||
private String poolUrl;
|
||||
|
||||
|
||||
@ApiModelProperty(value = "矿池挖矿账户")
|
||||
private String poolUser;
|
||||
|
||||
@ApiModelProperty(value = "收款钱包")
|
||||
private String walletAddress;
|
||||
|
||||
@ApiModelProperty(value = "挖矿信息页面地址")
|
||||
private String watchUrl;
|
||||
|
||||
@ApiModelProperty(value = "已购矿机信息")
|
||||
private List<PurchasedMachineDto> purchasedMachines;
|
||||
|
||||
}
|
||||
@@ -6,8 +6,8 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import scala.math.BigDecimal;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
|
||||
@@ -25,9 +25,12 @@ import java.time.LocalDateTime;
|
||||
@AllArgsConstructor
|
||||
@ApiModel(description = "矿机对应实时算力放回对象",value = "MiningHashrateInfoDto" )
|
||||
public class MiningHashrateInfoDto {
|
||||
@ApiModelProperty(value = "算力")
|
||||
@ApiModelProperty(value = "实时算力")
|
||||
private BigDecimal power;
|
||||
|
||||
@ApiModelProperty(value = "记录时间")
|
||||
@ApiModelProperty(value = "最近实时算力记录时间")
|
||||
private LocalDateTime recordTime;
|
||||
|
||||
@ApiModelProperty(value = "矿工号")
|
||||
private String miner;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
@@ -30,37 +31,12 @@ public class PurchasedMachineDto {
|
||||
//@ApiModelProperty(value = "订单编号")
|
||||
//private String orderNumbers;
|
||||
|
||||
@ApiModelProperty(value = "矿池所挖币种")
|
||||
private String coin;
|
||||
|
||||
@ApiModelProperty(value = "币种对应算法")
|
||||
private String algorithm;
|
||||
|
||||
|
||||
@ApiModelProperty(value = "矿池名称")
|
||||
private String pool;
|
||||
|
||||
|
||||
@ApiModelProperty(value = "矿池挖矿地址")
|
||||
private String poolUrl;
|
||||
|
||||
|
||||
@ApiModelProperty(value = "矿池挖矿账户")
|
||||
private String poolUser;
|
||||
|
||||
|
||||
@ApiModelProperty(value = "矿工号")
|
||||
private String workerId;
|
||||
|
||||
@ApiModelProperty(value = "收款钱包")
|
||||
private String walletAddress;
|
||||
|
||||
@ApiModelProperty(value = "挖矿信息页面地址")
|
||||
private String watchUrl;
|
||||
|
||||
|
||||
@ApiModelProperty(value = "0 租约已到期 1挖矿中 2卖家矿机启动中")
|
||||
private Boolean status;
|
||||
private Integer status;
|
||||
|
||||
|
||||
@ApiModelProperty(value = "挖矿开始时间")
|
||||
@@ -70,7 +46,11 @@ public class PurchasedMachineDto {
|
||||
@ApiModelProperty(value = "挖矿结束时间")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
@ApiModelProperty(value = "算力信息")
|
||||
private MiningHashrateInfoDto miningHashrateInfo;
|
||||
|
||||
@ApiModelProperty(value = "实时算力")
|
||||
private BigDecimal power;
|
||||
|
||||
@ApiModelProperty(value = "最近实时算力记录时间")
|
||||
private LocalDateTime recordTime;
|
||||
|
||||
}
|
||||
|
||||
@@ -50,6 +50,38 @@ public class LeaseGpuConfig implements Serializable {
|
||||
*/
|
||||
private Integer memory;
|
||||
|
||||
/**
|
||||
* 币种
|
||||
*/
|
||||
private String coin;
|
||||
|
||||
|
||||
/**
|
||||
* 算力 单位MH/s
|
||||
*/
|
||||
private BigDecimal hashrate;
|
||||
|
||||
|
||||
/**
|
||||
* 算法
|
||||
*/
|
||||
private String algorithm;
|
||||
|
||||
/**
|
||||
* 图标
|
||||
*/
|
||||
private String icon;
|
||||
|
||||
/**
|
||||
* 单位 默认MH/S
|
||||
*/
|
||||
private String unit;
|
||||
|
||||
/**
|
||||
* 月收入
|
||||
*/
|
||||
private BigDecimal monthIncome;
|
||||
|
||||
/**
|
||||
* 功耗 单位kw/h
|
||||
*/
|
||||
|
||||
@@ -41,6 +41,11 @@ public class GlobalExceptionHandler {
|
||||
return Result.fail(e.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(RSAException.class)
|
||||
public Result<String> handleRSAException(RSAException e) {
|
||||
return Result.fail(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理其他未明确捕获的异常,返回统一的错误结果。
|
||||
*
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.m2pool.lease.exception;
|
||||
|
||||
/**
|
||||
* 非对称加密异常
|
||||
*/
|
||||
public class RSAException extends RuntimeException {
|
||||
public RSAException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.m2pool.lease.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.m2pool.lease.dto.v2.CoinAndAlgorithmDto;
|
||||
import com.m2pool.lease.entity.LeaseGpuConfig;
|
||||
import com.m2pool.lease.netty.message.GpuMessage;
|
||||
import com.m2pool.lease.task.info.BlockInfo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@@ -24,5 +26,13 @@ public interface LeaseGpuConfigMapper extends BaseMapper<LeaseGpuConfig> {
|
||||
* @param gpuMessages
|
||||
* @return
|
||||
*/
|
||||
int insertOrUpdate(@Param("list") Collection<GpuMessage> gpuMessages);
|
||||
int insertOrUpdateBatchByGpuInfo(@Param("list") List<CoinAndAlgorithmDto> gpuMessages);
|
||||
|
||||
/**
|
||||
* 通过实体类批量插入或更新
|
||||
* @param leaseGpuConfigs
|
||||
* @return
|
||||
*/
|
||||
int insertOrUpdateBatchByEntity(@Param("list") List<LeaseGpuConfig> leaseGpuConfigs);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
package com.m2pool.lease.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.m2pool.lease.dto.v2.CoinAndAlgorithmDto;
|
||||
import com.m2pool.lease.dto.v2.CoinAndAlgorithmListDto;
|
||||
import com.m2pool.lease.dto.v2.MiningConfigSelectDto;
|
||||
import com.m2pool.lease.dto.v2.*;
|
||||
import com.m2pool.lease.entity.LeaseMachineConfig;
|
||||
import com.m2pool.lease.vo.BaseVo;
|
||||
import com.m2pool.lease.vo.v2.CoinAndAlgorithmVo;
|
||||
import org.apache.ibatis.annotations.MapKey;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -38,4 +38,10 @@ public interface LeaseMachineConfigMapper extends BaseMapper<LeaseMachineConfig>
|
||||
*/
|
||||
List<CoinAndAlgorithmDto> getMachineSupportCoinAndAlgorithm(@Param("machineIds") List<BaseVo> machineIds);
|
||||
|
||||
|
||||
/**
|
||||
* 获取理论算力
|
||||
* @return
|
||||
*/
|
||||
List<MachineHashRateMapDto> getTheoryHashRate(@Param("list") List<OrderMiningInfoDto> orderMiningInfoDtoList);
|
||||
}
|
||||
|
||||
@@ -23,5 +23,5 @@ public interface LeaseMiningSoftwareConfigMapper extends BaseMapper<LeaseMiningS
|
||||
* @param miningsofts
|
||||
* @return
|
||||
*/
|
||||
List<CoinAndAlgorithmDto> selectSupportAlgorithm(@Param("miningsofts") List<String> miningsofts);
|
||||
List<CoinAndAlgorithmDto> selectSupportAlgorithm(@Param("miningsofts") List<String> miningsofts,@Param("modelList") List<String> modelList);
|
||||
}
|
||||
|
||||
@@ -5,11 +5,13 @@ import com.m2pool.common.datasource.annotation.MiningDB;
|
||||
import com.m2pool.lease.dto.v2.*;
|
||||
import com.m2pool.lease.entity.LeaseOrderMining;
|
||||
import com.m2pool.lease.netty.message.ClientConfigurationMining;
|
||||
import org.apache.ibatis.annotations.MapKey;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -50,22 +52,17 @@ public interface LeaseOrderMiningMapper extends BaseMapper<LeaseOrderMining> {
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
PurchasedMachineDto getPurchasedInfo(@Param("id") Long id);
|
||||
MiningConfigInfoDto getPurchasedInfo(@Param("id") Long id);
|
||||
|
||||
|
||||
/**
|
||||
* 获取最近一次的算力
|
||||
* @param pool
|
||||
* @param wallet
|
||||
* @param coin
|
||||
* @param miner
|
||||
* @param list
|
||||
* @return
|
||||
*/
|
||||
@MiningDB
|
||||
MiningHashrateInfoDto getRecentlyHashrate(@Param("pool") String pool,
|
||||
@Param("wallet") String wallet,
|
||||
@Param("coin") String coin,
|
||||
@Param("miner") String miner);
|
||||
@MapKey("miner")
|
||||
Map<String,MiningHashrateInfoDto> getRecentlyHashrate(@Param("pool") String pool,@Param("wallet") String wallet,@Param("coin") String coin,@Param("list") List<PurchasedMachineDto> list);
|
||||
|
||||
|
||||
/**
|
||||
@@ -90,4 +87,12 @@ public interface LeaseOrderMiningMapper extends BaseMapper<LeaseOrderMining> {
|
||||
* @return
|
||||
*/
|
||||
List<OrderMiningInfoDto> checkMiningMinersExist(@Param("list") List<OrderMiningInfoDto> list);
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户购买的矿机信息
|
||||
* @param info
|
||||
* @return
|
||||
*/
|
||||
List<PurchasedMachineDto> getPurchasedMachineInfo(@Param("info") MiningConfigInfoDto info);
|
||||
}
|
||||
|
||||
@@ -87,59 +87,70 @@ public class ServerChannelHandler extends SimpleChannelInboundHandler<ClientMess
|
||||
*/
|
||||
private void handlerDownloadClientMessage(ChannelHandlerContext ctx,ClientMessage<Object> msg){
|
||||
String id = msg.getId();
|
||||
String[] split = id.split("::");
|
||||
System.out.println("客户端消息"+JSONUtil.toJsonPrettyStr( split) + "长度"+split.length);
|
||||
System.out.println("客户端消息 "+checkMessage(ctx,id,split[0]));
|
||||
if (split.length == 2 && checkMessage(ctx,id,split[0])){
|
||||
if (checkMessage(ctx,id)){
|
||||
String[] split = id.split("::");
|
||||
Object params = msg.getParams();
|
||||
GpuAndSoftMessage gpuAndSoftMessage = JSONUtil.toBean(params.toString(), GpuAndSoftMessage.class);
|
||||
Map<String, GpuMessage> gpus = gpuAndSoftMessage.getGpus();
|
||||
List<String> miningsofts = gpuAndSoftMessage.getMiningsofts();
|
||||
List<String> modelList = gpus.values().stream().map(GpuMessage::getModel).collect(Collectors.toList());
|
||||
|
||||
if (params instanceof GpuAndSoftMessage){
|
||||
System.out.println("客户端消息"+JSONUtil.toJsonPrettyStr(params));
|
||||
GpuAndSoftMessage gpuAndSoftMessage = (GpuAndSoftMessage) params;
|
||||
Map<String, GpuMessage> gpus = gpuAndSoftMessage.getGpus();
|
||||
List<String> miningsofts = gpuAndSoftMessage.getMiningsofts();
|
||||
Collection<GpuMessage> gpuMessagesList = gpus.values();
|
||||
//挖矿软件公共配置
|
||||
List<CoinAndAlgorithmDto> supportAlgorithmAndCoin = leaseMiningSoftwareConfigMapper.selectSupportAlgorithm(miningsofts,modelList);
|
||||
// 新增主机相关信息
|
||||
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
try {
|
||||
LeaseMachine leaseMachine = leaseMachineMapper.selectOne(new LambdaQueryWrapper<LeaseMachine>()
|
||||
.eq(LeaseMachine::getHostMac, id).eq(LeaseMachine::getDel, false));
|
||||
if (leaseMachine == null){
|
||||
LeaseShop shop = getShop(split[0]);
|
||||
leaseMachine = LeaseMachine.builder()
|
||||
.shopId(shop.getId())
|
||||
.hostMac(id)
|
||||
.type(true)
|
||||
.state(true)
|
||||
.saleNumbers(0).build();
|
||||
List<CoinAndAlgorithmDto> needAddAlgo = supportAlgorithmAndCoin.stream()
|
||||
.filter(CoinAndAlgorithmDto::getIsAdd).collect(Collectors.toList());
|
||||
|
||||
//挖矿软件公共配置
|
||||
List<CoinAndAlgorithmDto> supportAlgorithmAndCoin = leaseMiningSoftwareConfigMapper.selectSupportAlgorithm(miningsofts);
|
||||
// 新增主机相关信息
|
||||
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
try {
|
||||
LeaseMachine leaseMachine = leaseMachineMapper.selectOne(new LambdaQueryWrapper<LeaseMachine>()
|
||||
.eq(LeaseMachine::getHostMac, split[1]));
|
||||
if (leaseMachine == null){
|
||||
LeaseShop shop = getShop(split[0]);
|
||||
leaseMachine = LeaseMachine.builder()
|
||||
.shopId(shop.getId())
|
||||
.hostMac(split[1])
|
||||
.type(true)
|
||||
.state(true)
|
||||
.saleNumbers(0).build();
|
||||
if (!needAddAlgo.isEmpty()){
|
||||
List<CoinAndAlgorithmDto> needAdd = new ArrayList<>();
|
||||
for (String model : modelList) {
|
||||
for (CoinAndAlgorithmDto coinAndAlgorithmDto : needAddAlgo) {
|
||||
needAdd.add(CoinAndAlgorithmDto.builder()
|
||||
.isEffect(coinAndAlgorithmDto.getIsEffect())
|
||||
.coin(coinAndAlgorithmDto.getCoin())
|
||||
.algorithm(coinAndAlgorithmDto.getAlgorithm())
|
||||
.model(model)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
//GPU配置信息配置
|
||||
leaseGpuConfigMapper.insertOrUpdate(gpuMessagesList);
|
||||
List<LeaseMachineConfig> leaseMachineConfigs = packageInsert(leaseMachine.getId(),gpus, supportAlgorithmAndCoin);
|
||||
leaseMachineMapper.insert(leaseMachine);
|
||||
leaseMachineConfigService.saveBatch(leaseMachineConfigs);
|
||||
}else {
|
||||
leaseMachine.setOnlineStatus(true);
|
||||
leaseMachineMapper.updateById(leaseMachine);
|
||||
//检测对照表
|
||||
List<LeaseMachineConfig> needUpdateInfo = packageInsert(leaseMachine.getId(),gpus, supportAlgorithmAndCoin);
|
||||
//带检测矿机
|
||||
List<MachineConfigDto> needCheckInfo = leaseMachineMapper.getEffectMachineAndTempMachineList(leaseMachine.getId());
|
||||
Map<Boolean, List<MachineConfigDto>> collect = needCheckInfo.stream().collect(Collectors.groupingBy(MachineConfigDto::getIsTemp));
|
||||
checkMachineAndInsertOrUpdate(leaseMachine.getId(),needUpdateInfo, collect);
|
||||
leaseGpuConfigMapper.insertOrUpdateBatchByGpuInfo(needAdd);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 回滚事务
|
||||
status.setRollbackOnly();
|
||||
throw e;
|
||||
leaseMachineMapper.insert(leaseMachine);
|
||||
List<LeaseMachineConfig> leaseMachineConfigs = packageInsert(leaseMachine.getId(),gpus, supportAlgorithmAndCoin);
|
||||
leaseMachineConfigService.saveBatch(leaseMachineConfigs);
|
||||
}else {
|
||||
leaseMachine.setOnlineStatus(true);
|
||||
leaseMachineMapper.updateById(leaseMachine);
|
||||
//检测对照表
|
||||
List<LeaseMachineConfig> needUpdateInfo = packageInsert(leaseMachine.getId(),gpus, supportAlgorithmAndCoin);
|
||||
//带检测矿机
|
||||
List<MachineConfigDto> needCheckInfo = leaseMachineMapper.getEffectMachineAndTempMachineList(leaseMachine.getId());
|
||||
Map<Boolean, List<MachineConfigDto>> collect = needCheckInfo.stream().collect(Collectors.groupingBy(MachineConfigDto::getIsTemp));
|
||||
checkMachineAndInsertOrUpdate(leaseMachine.getId(),needUpdateInfo, collect);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 回滚事务
|
||||
status.setRollbackOnly();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,18 +162,25 @@ public class ServerChannelHandler extends SimpleChannelInboundHandler<ClientMess
|
||||
*/
|
||||
public List<LeaseMachineConfig> packageInsert(Long machineId,Map<String, GpuMessage> gpus,List<CoinAndAlgorithmDto> supportAlgorithmAndCoin){
|
||||
List<LeaseMachineConfig> list = new ArrayList<>();
|
||||
System.out.println("gpu信息"+ JSONUtil.toJsonStr(gpus.values()));
|
||||
for (GpuMessage value : gpus.values()) {
|
||||
list.addAll(supportAlgorithmAndCoin.stream().map(item-> LeaseMachineConfig.builder()
|
||||
.machineId(machineId)
|
||||
.coin(item.getCoin())
|
||||
.algorithm(item.getAlgorithm())
|
||||
.brand(value.getBrand())
|
||||
.name(value.getModel())
|
||||
.memory(value.getMem())
|
||||
.status(item.getIsEffect())
|
||||
.unit("MH/S")
|
||||
.del(false)
|
||||
.build()).collect(Collectors.toList()));
|
||||
for (CoinAndAlgorithmDto coinAndAlgorithmDto : supportAlgorithmAndCoin) {
|
||||
if (coinAndAlgorithmDto.getModel() != null && value.getModel().contains(coinAndAlgorithmDto.getModel())){
|
||||
list.add(LeaseMachineConfig.builder()
|
||||
.machineId(machineId)
|
||||
.brand(value.getBrand())
|
||||
.name(value.getModel())
|
||||
.memory(value.getMem())
|
||||
.coin(coinAndAlgorithmDto.getCoin())
|
||||
.algorithm(coinAndAlgorithmDto.getAlgorithm())
|
||||
.status(coinAndAlgorithmDto.getIsEffect())
|
||||
.powerDissipation(coinAndAlgorithmDto.getPowerDissipation())
|
||||
.hashrate(coinAndAlgorithmDto.getHashRate())
|
||||
.monthIncome(coinAndAlgorithmDto.getMonthIncome())
|
||||
.build());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
@@ -263,15 +281,12 @@ public class ServerChannelHandler extends SimpleChannelInboundHandler<ClientMess
|
||||
* @param msg
|
||||
*/
|
||||
private void handlerClientMiningMessage(ChannelHandlerContext ctx,ClientMessage<Object> msg){
|
||||
String id = msg.getId();
|
||||
String[] split = id.split("::");
|
||||
if (split.length == 2 && checkMessage(ctx,id,split[0])){
|
||||
if (checkMessage(ctx,msg.getId())){
|
||||
String[] split = msg.getId().split("::");
|
||||
Object params = msg.getParams();
|
||||
if (params instanceof ClientConfigurationMining){
|
||||
ClientConfigurationMining clientConfigurationMining = (ClientConfigurationMining) params;
|
||||
//修改 当前邮箱账户 对应的该矿池的 一些基本信息 TODO 这里可以设置真实开始时间 和 状态改为1
|
||||
leaseOrderMiningMapper.updateOrderMining(split[0],clientConfigurationMining);
|
||||
}
|
||||
ClientConfigurationMining clientConfigurationMining = JSONUtil.toBean(params.toString(), ClientConfigurationMining.class);
|
||||
//修改 当前邮箱账户 对应的该矿池的 一些基本信息 TODO 这里可以设置真实开始时间 和 状态改为1
|
||||
leaseOrderMiningMapper.updateOrderMining(split[0],clientConfigurationMining);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,11 +305,15 @@ public class ServerChannelHandler extends SimpleChannelInboundHandler<ClientMess
|
||||
* 检查消息的合法性
|
||||
* @return
|
||||
*/
|
||||
private boolean checkMessage(ChannelHandlerContext ctx,String id,String authCode){
|
||||
LeaseShop leaseShop = getShop(authCode);
|
||||
private boolean checkMessage(ChannelHandlerContext ctx,String id){
|
||||
System.out.println("客户端消息id"+ id);
|
||||
String[] split = id.split("::");
|
||||
if (split.length != 2){
|
||||
return false;
|
||||
}
|
||||
LeaseShop leaseShop = getShop(split[0]);
|
||||
Channel channel = ctx.channel();
|
||||
ChannelManager.idMap.put(channel,id);
|
||||
ChannelManager.macMap.put(channel,getIPString(ctx));
|
||||
//不存在对应身份码的店铺 发送消息给客户端
|
||||
if (leaseShop == null){
|
||||
sendErrorResp(ctx,id);
|
||||
@@ -341,10 +360,11 @@ public class ServerChannelHandler extends SimpleChannelInboundHandler<ClientMess
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) {
|
||||
System.out.println("ip:"+getIPString(ctx)+"断开连接");
|
||||
String mac = ChannelManager.macMap.get(ctx.channel());
|
||||
String id = ChannelManager.idMap.get(ctx.channel());
|
||||
//修改矿机离线状态为 离线
|
||||
if (mac != null){
|
||||
leaseMachineMapper.update(LeaseMachine.builder().onlineStatus(false).build(), new LambdaUpdateWrapper<LeaseMachine>().eq(LeaseMachine::getHostMac,mac));
|
||||
if (id != null){
|
||||
leaseMachineMapper.update(LeaseMachine.builder().onlineStatus(false).build(),
|
||||
new LambdaUpdateWrapper<LeaseMachine>().eq(LeaseMachine::getHostMac,id));
|
||||
}
|
||||
ChannelManager.removeChannel(getIPString(ctx));
|
||||
ctx.close();
|
||||
@@ -382,28 +402,28 @@ public class ServerChannelHandler extends SimpleChannelInboundHandler<ClientMess
|
||||
*/
|
||||
@Override
|
||||
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
|
||||
String socketString = ctx.channel().remoteAddress().toString();
|
||||
if (evt instanceof IdleStateEvent) {
|
||||
IdleStateEvent event = (IdleStateEvent) evt;
|
||||
String ip = getIPString(ctx);
|
||||
String id = ChannelManager.getIdByChannel(ip);
|
||||
if (event.state() == IdleState.READER_IDLE) {
|
||||
System.out.println("读超时,未收到任何客户端消息,断开连接");
|
||||
System.out.println(id+"用户写超时,接受pong"+System.currentTimeMillis());
|
||||
//System.out.println(id+"用户读超时,断开连接");
|
||||
ChannelManager.removeChannel(ip);
|
||||
ctx.disconnect();//断开
|
||||
} else if (event.state() == IdleState.WRITER_IDLE ) {
|
||||
System.out.println("写超时发送ping到客户端");
|
||||
String id = ChannelManager.getIdByChannel(ip);
|
||||
System.out.println(id+"用户写超时,发送ping"+System.currentTimeMillis());
|
||||
if (id != null){
|
||||
ClientMessage ping = new ClientMessage();
|
||||
ping.setMethod(PING);
|
||||
ping.setId(id);
|
||||
ctx.writeAndFlush(ping);
|
||||
}
|
||||
} else if (event.state() == IdleState.ALL_IDLE) {
|
||||
System.out.println("客户端 ALL_IDLE 总超时: " + socketString);
|
||||
ChannelManager.removeChannel(ip);
|
||||
ctx.disconnect();
|
||||
}
|
||||
//else if (event.state() == IdleState.ALL_IDLE) {
|
||||
// ChannelManager.removeChannel(ip);
|
||||
// ctx.disconnect();
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ public class ServerChannelInitializer extends ChannelInitializer<SocketChannel>
|
||||
ChannelPipeline pipeline = socketChannel.pipeline();
|
||||
//IdleStateHandler心跳机制,如果超时触发Handle中userEventTrigger()方法
|
||||
pipeline.addLast("idleStateHandler",
|
||||
new IdleStateHandler(PONG_TIME, PING_TIME, 0, TimeUnit.MINUTES));
|
||||
new IdleStateHandler(PONG_TIME, PING_TIME, 0, TimeUnit.SECONDS));
|
||||
pipeline.addLast(new LineBasedFrameDecoder(1024));
|
||||
//字符串编解码器
|
||||
pipeline.addLast(new MessageToJsonDecoder(),new MessageToJsonEncoder());
|
||||
|
||||
@@ -2,10 +2,7 @@ package com.m2pool.lease.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.lease.dto.*;
|
||||
import com.m2pool.lease.dto.v2.CoinAndAlgorithmListDto;
|
||||
import com.m2pool.lease.dto.v2.MiningInfoDto;
|
||||
import com.m2pool.lease.dto.v2.PurchasedMachineDto;
|
||||
import com.m2pool.lease.dto.v2.PurchasedMachineListDto;
|
||||
import com.m2pool.lease.dto.v2.*;
|
||||
import com.m2pool.lease.entity.LeaseOrderInfo;
|
||||
import com.m2pool.lease.vo.*;
|
||||
import com.m2pool.lease.vo.v2.CoinAndAlgorithmVo;
|
||||
@@ -106,5 +103,5 @@ public interface LeaseOrderInfoService extends IService<LeaseOrderInfo> {
|
||||
* @param baseVo
|
||||
* @return
|
||||
*/
|
||||
Result<PurchasedMachineDto> getPurchasedInfo(BaseVo baseVo);
|
||||
Result<MiningConfigInfoDto> getPurchasedInfo(BaseVo baseVo);
|
||||
}
|
||||
|
||||
@@ -821,12 +821,19 @@ public class LeaseOrderInfoServiceImpl extends ServiceImpl<LeaseOrderInfoMapper,
|
||||
List<LeaseShop> shopList = leaseShopMapper.selectBatchIds(shopIds);
|
||||
Map<Long, LeaseShop> shopMap = shopList.stream().collect(Collectors.toMap(LeaseShop::getId, Function.identity()));
|
||||
|
||||
//获取理论算力
|
||||
List<MachineHashRateMapDto> theoryHashRate1 = leaseMachineConfigMapper.getTheoryHashRate(orderMiningInfoDtoList);
|
||||
Map<Long, List<MachineHashRateMapDto>> theoryHashRateMap = theoryHashRate1.stream()
|
||||
.collect(Collectors.groupingBy(MachineHashRateMapDto::getMachineId));
|
||||
|
||||
Map<Long,Long> endMiningMap = new HashMap<>();
|
||||
Map<Long,Long> machineOrderIdMap = new HashMap<>();
|
||||
Map<Long,Long> machineOrderItemIdMap = new HashMap<>();
|
||||
for (LeaseMachine leaseMachine : machinesList) {
|
||||
Long machineId = leaseMachine.getId();
|
||||
OrderInfoVo orderInfoVo = machineMap.get(machineId);
|
||||
List<MachineHashRateMapDto> machineHashRateMapDtos = theoryHashRateMap.get(machineId);
|
||||
BigDecimal theoryHashRate = machineHashRateMapDtos.isEmpty() ? BigDecimal.ZERO : machineHashRateMapDtos.get(0).getHashRate();
|
||||
String chain = orderInfoVo.getChain();
|
||||
String coin = orderInfoVo.getCoin();
|
||||
Long shopId = orderInfoVo.getShopId();
|
||||
@@ -862,6 +869,7 @@ public class LeaseOrderInfoServiceImpl extends ServiceImpl<LeaseOrderInfoMapper,
|
||||
.fromSymbol(walletInfo.getFromSymbol())
|
||||
.numbers(orderInfoVo.getNumbers())
|
||||
.type(leaseMachine.getType())
|
||||
.theoryPower(theoryHashRate)
|
||||
.build();
|
||||
Long timestamp = startTime + orderInfoVo.getLeaseTime() * 24 * 60 * 60 * 1000L;
|
||||
endMiningMap.put(machineId,timestamp);
|
||||
@@ -903,7 +911,7 @@ public class LeaseOrderInfoServiceImpl extends ServiceImpl<LeaseOrderInfoMapper,
|
||||
*/
|
||||
private boolean checkGpuMachine(List<LeaseMachine> gpuMachines){
|
||||
for (LeaseMachine gpuMachine : gpuMachines) {
|
||||
if (ChannelManager.getChannelByMac(gpuMachine.getHostMac()) == null){
|
||||
if (ChannelManager.getChannelById(gpuMachine.getHostMac()) == null){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1003,7 +1011,7 @@ public class LeaseOrderInfoServiceImpl extends ServiceImpl<LeaseOrderInfoMapper,
|
||||
.pool_user(poolUser)
|
||||
.worker_id(poolWorkerId)
|
||||
.end_timestamp(endTime / 1000).build();
|
||||
message.setId(userEmail+"::"+ mac);
|
||||
message.setId(mac);
|
||||
message.setMethod(MINING_RAG);
|
||||
message.setParams( build);
|
||||
//TCP 消息
|
||||
@@ -1067,12 +1075,24 @@ public class LeaseOrderInfoServiceImpl extends ServiceImpl<LeaseOrderInfoMapper,
|
||||
|
||||
@Override
|
||||
@DSTransactional
|
||||
public Result<PurchasedMachineDto> getPurchasedInfo(BaseVo baseVo) {
|
||||
public Result<MiningConfigInfoDto> getPurchasedInfo(BaseVo baseVo) {
|
||||
//找到miner 和钱包 ,pool 矿池名
|
||||
PurchasedMachineDto info = leaseOrderMiningMapper.getPurchasedInfo(baseVo.getId());
|
||||
MiningConfigInfoDto info = leaseOrderMiningMapper.getPurchasedInfo(baseVo.getId());
|
||||
List<PurchasedMachineDto> list = leaseOrderMiningMapper.getPurchasedMachineInfo(info);
|
||||
|
||||
|
||||
//根据钱包 + 币种 + 矿工号 查询 pool 库 pool.kryptex 表 中对应 算力
|
||||
MiningHashrateInfoDto recentlyHashrate = leaseOrderMiningMapper.getRecentlyHashrate(info.getPool(), info.getWalletAddress(), info.getCoin(), info.getWorkerId());
|
||||
info.setMiningHashrateInfo(recentlyHashrate);
|
||||
Map<String, MiningHashrateInfoDto> recentlyHashRateMap = leaseOrderMiningMapper
|
||||
.getRecentlyHashrate(info.getPool(), info.getWalletAddress(), info.getCoin(), list);
|
||||
for (PurchasedMachineDto purchasedMachineDto : list) {
|
||||
MiningHashrateInfoDto miningHashrateInfoDto = recentlyHashRateMap.get(purchasedMachineDto.getWorkerId());
|
||||
if (miningHashrateInfoDto != null){
|
||||
purchasedMachineDto.setRecordTime(miningHashrateInfoDto.getRecordTime());
|
||||
purchasedMachineDto.setPower(miningHashrateInfoDto.getPower());
|
||||
}
|
||||
}
|
||||
|
||||
info.setPurchasedMachines(list);
|
||||
return Result.success(info);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.m2pool.lease.service.impl;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.druid.support.json.JSONUtils;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
@@ -251,7 +252,9 @@ public class LeaseProductServiceImpl extends ServiceImpl<LeaseProductMapper, Lea
|
||||
.select(LeaseShop::getId)
|
||||
.eq(LeaseShop::getUserEmail, SecurityUtils.getUsername())
|
||||
.eq(LeaseShop::getDel, false));
|
||||
|
||||
if (leaseShop == null){
|
||||
return Result.fail("店铺不存在");
|
||||
}
|
||||
List<PayConfigDto> shopWalletInfo = leaseShopMapper.getShopWalletInfo(leaseShop.getId());
|
||||
return Result.success(shopWalletInfo);
|
||||
}
|
||||
|
||||
@@ -7,10 +7,12 @@ import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.m2pool.common.core.utils.StringUtils;
|
||||
import com.m2pool.common.security.utils.SecurityUtils;
|
||||
import com.m2pool.lease.controller.LeaseShopController;
|
||||
import com.m2pool.lease.dto.*;
|
||||
import com.m2pool.lease.dto.v2.PayWithdrawSellerRecordDto;
|
||||
import com.m2pool.lease.dto.v2.ShopWalletInfoDto;
|
||||
import com.m2pool.lease.entity.*;
|
||||
import com.m2pool.lease.exception.MachineException;
|
||||
import com.m2pool.lease.exception.PaymentException;
|
||||
import com.m2pool.lease.mapper.*;
|
||||
import com.m2pool.lease.mq.message.RabbitmqPayWithdrawMessage;
|
||||
@@ -66,8 +68,9 @@ public class LeaseShopServiceImpl extends ServiceImpl<LeaseShopMapper, LeaseShop
|
||||
@Resource
|
||||
private LeaseProductMachineMapper leaseProductMachineMapper;
|
||||
|
||||
|
||||
@Resource
|
||||
private LeaseProductMachinePriceMapper leaseProductMachinePriceMapper;
|
||||
private LeaseMachinePriceMapper leaseMachinePriceMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseUserMapper leaseUserMapper;
|
||||
@@ -81,6 +84,12 @@ public class LeaseShopServiceImpl extends ServiceImpl<LeaseShopMapper, LeaseShop
|
||||
@Resource
|
||||
private LeaseAutoAddressMapper leaseAutoAddressMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseMachineMapper leaseMachineMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseMachineConfigMapper leaseMachineConfigMapper;
|
||||
|
||||
@Override
|
||||
public Result<String> addShop(ShopVo shopVo) {
|
||||
LeaseShop leaseShop1 = leaseShopMapper.selectOne(new LambdaQueryWrapper<LeaseShop>()
|
||||
@@ -143,9 +152,11 @@ public class LeaseShopServiceImpl extends ServiceImpl<LeaseShopMapper, LeaseShop
|
||||
return Result.fail("店铺不存在");
|
||||
}
|
||||
//校验是否存在已售出的矿机
|
||||
if (leaseProductMachineMapper.checkHasSaleMachineByShopId(baseVo.getId()) >= 1){
|
||||
if (leaseProductMachineMapper.checkHasSaleMachineByShopId(baseVo.getId()) >= 1 || leaseMachineMapper.checkHasSaleMachineByShopId(baseVo.getId()) >= 1){
|
||||
return Result.fail("关闭店铺失败,店铺存在租约中矿机");
|
||||
}
|
||||
|
||||
|
||||
if (leaseShop.getState() == 1){
|
||||
leaseShop.setState(2);
|
||||
boolean b = updateById(leaseShop);
|
||||
@@ -202,16 +213,8 @@ public class LeaseShopServiceImpl extends ServiceImpl<LeaseShopMapper, LeaseShop
|
||||
if (byId.getDel()){
|
||||
return Result.fail("删除店铺失败,店铺已删除,请刷新页面");
|
||||
}
|
||||
|
||||
//校验是否存在已售出的矿机
|
||||
if (leaseProductMachineMapper.checkHasSaleMachineByShopId(baseVo.getId()) >= 1){
|
||||
return Result.fail("删除店铺失败,店铺存在租约中矿机");
|
||||
}
|
||||
leaseProductMapper.update(LeaseProduct.builder().del(true).build(), new LambdaUpdateWrapper<LeaseProduct>()
|
||||
.eq(LeaseProduct::getShopId, baseVo.getId()));
|
||||
leaseProductMachineMapper.update(LeaseProductMachine.builder().del(true).build(), new LambdaUpdateWrapper<LeaseProductMachine>()
|
||||
.eq(LeaseProductMachine::getShopId, baseVo.getId()));
|
||||
|
||||
updateMachineInfoV1(baseVo.getId());
|
||||
updateMachineInfoV2(baseVo.getId());
|
||||
boolean b = updateById(LeaseShop.builder().id(baseVo.getId()).del(true).build());
|
||||
if (b){
|
||||
return Result.success("删除成功");
|
||||
@@ -220,6 +223,51 @@ public class LeaseShopServiceImpl extends ServiceImpl<LeaseShopMapper, LeaseShop
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除店铺时,将店铺下所有矿机和对应钱包删除 V1版本
|
||||
*
|
||||
* */
|
||||
public void updateMachineInfoV1(Long shopId){
|
||||
//校验是否存在已售出的矿机
|
||||
if (leaseProductMachineMapper.checkHasSaleMachineByShopId(shopId) >= 1){
|
||||
throw new MachineException("删除店铺失败,店铺存在租约中矿机");
|
||||
}
|
||||
leaseProductMapper.update(LeaseProduct.builder().del(true).build(), new LambdaUpdateWrapper<LeaseProduct>()
|
||||
.eq(LeaseProduct::getShopId, shopId));
|
||||
leaseProductMachineMapper.update(LeaseProductMachine.builder().del(true).build(), new LambdaUpdateWrapper<LeaseProductMachine>()
|
||||
.eq(LeaseProductMachine::getShopId, shopId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除店铺时,将店铺下所有矿机和对应钱包删除 V2版本
|
||||
*
|
||||
* */
|
||||
public void updateMachineInfoV2(Long shopId){
|
||||
//校验是否存在已售出的矿机
|
||||
if (leaseMachineMapper.checkHasSaleMachineByShopId(shopId) >= 1){
|
||||
throw new MachineException("删除店铺失败,店铺存在租约中矿机");
|
||||
}
|
||||
//校验是否存在余额不为0的钱包
|
||||
List<LeaseShopConfig> leaseShopConfigs = leaseShopConfigMapper.selectList(new LambdaQueryWrapper<LeaseShopConfig>()
|
||||
.select(LeaseShopConfig::getId,LeaseShopConfig::getBalance)
|
||||
.eq(LeaseShopConfig::getShopId, shopId).eq(LeaseShopConfig::getDel, false));
|
||||
if (leaseShopConfigs.stream().anyMatch(leaseShopConfig -> leaseShopConfig.getBalance().compareTo(BigDecimal.ZERO) > 0)){
|
||||
throw new MachineException("删除店铺失败,店铺存在余额不为0的钱包");
|
||||
}
|
||||
leaseMachineMapper.update(LeaseMachine.builder().del(true).build(), new LambdaUpdateWrapper<LeaseMachine>()
|
||||
.eq(LeaseMachine::getShopId, shopId));
|
||||
|
||||
List<Long> ids = leaseMachineMapper.selectList(new LambdaQueryWrapper<LeaseMachine>()
|
||||
.select(LeaseMachine::getId)
|
||||
.eq(LeaseMachine::getShopId, shopId))
|
||||
.stream().map(LeaseMachine::getId)
|
||||
.collect(Collectors.toList());
|
||||
leaseMachineConfigMapper.delete(new LambdaQueryWrapper<LeaseMachineConfig>().in(LeaseMachineConfig::getMachineId, ids));
|
||||
|
||||
leaseShopConfigMapper.update(LeaseShopConfig.builder().del(true).build(), new LambdaUpdateWrapper<LeaseShopConfig>()
|
||||
.eq(LeaseShopConfig::getShopId, shopId));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
@@ -444,10 +492,10 @@ public class LeaseShopServiceImpl extends ServiceImpl<LeaseShopMapper, LeaseShop
|
||||
List<LeaseShopConfig> collect = leaseShopConfigs.stream().peek(leaseShopConfig -> leaseShopConfig.setDel(true)).collect(Collectors.toList());
|
||||
boolean b = leaseShopConfigService.updateBatchById(collect);
|
||||
if (b){
|
||||
leaseProductMachinePriceMapper.update(LeaseProductMachinePrice.builder().del(true).build(),
|
||||
new LambdaQueryWrapper<LeaseProductMachinePrice>()
|
||||
.eq(LeaseProductMachinePrice::getChain, config.getChain())
|
||||
.in(LeaseProductMachinePrice::getProductMachineId,ids)
|
||||
leaseMachinePriceMapper.update(LeaseMachinePrice.builder().del(true).build(),
|
||||
new LambdaQueryWrapper<LeaseMachinePrice>()
|
||||
.eq(LeaseMachinePrice::getChain, config.getChain())
|
||||
.in(LeaseMachinePrice::getMachineId,ids)
|
||||
);
|
||||
return Result.success("删除成功");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
package com.m2pool.lease.task;
|
||||
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.m2pool.lease.constant.BlockInterval;
|
||||
import com.m2pool.lease.entity.LeaseGpuConfig;
|
||||
import com.m2pool.lease.entity.LeaseMiningSoftwareConfig;
|
||||
import com.m2pool.lease.mapper.LeaseGpuConfigMapper;
|
||||
import com.m2pool.lease.mapper.LeaseMiningSoftwareConfigMapper;
|
||||
import com.m2pool.lease.task.info.*;
|
||||
import io.lettuce.core.ScriptOutputType;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Description 获取gpu 信息三方api:whattomine.com 定时任务
|
||||
* @Date 2025/12/16 15:38
|
||||
* @Author yyb
|
||||
*/
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
public class GpuRequestApiTask {
|
||||
|
||||
@Resource
|
||||
private LeaseGpuConfigMapper leaseGpuConfigMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseMiningSoftwareConfigMapper leaseMiningSoftwareConfigMapper;
|
||||
|
||||
@Scheduled(cron = "0 0 0/6 * * ? ")
|
||||
//@Scheduled(cron = "0 0/5 * * * ? ")
|
||||
public void gpuInfoTask(){
|
||||
List<GpuInfo> gpuInfos = fetchGpuInfo();
|
||||
List<LeaseGpuConfig> leaseGpuConfigs = convertGpuInfoToLeaseConfig(gpuInfos);
|
||||
List<LeaseMiningSoftwareConfig> leaseMiningSoftwareConfigs = leaseMiningSoftwareConfigMapper.
|
||||
selectList(new LambdaQueryWrapper<>());
|
||||
//选出挖矿软件只支持的算法和币种
|
||||
List<LeaseGpuConfig> leaseGpuConfigs1 = new ArrayList<>();
|
||||
for (LeaseGpuConfig leaseGpuConfig : leaseGpuConfigs) {
|
||||
for (LeaseMiningSoftwareConfig leaseMiningSoftwareConfig : leaseMiningSoftwareConfigs) {
|
||||
if (leaseMiningSoftwareConfig.getAlgorithm().contains(leaseGpuConfig.getAlgorithm())){
|
||||
leaseGpuConfig.setCoin(leaseMiningSoftwareConfig.getCoin());
|
||||
leaseGpuConfigs1.add(leaseGpuConfig);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
List<AlgorithmInfo> coinNetPowers = fetchMiningPower();
|
||||
if (!coinNetPowers.isEmpty()){
|
||||
Map<String, AlgorithmInfo> coinPowerMap = coinNetPowers.stream()
|
||||
.collect(Collectors.toMap(AlgorithmInfo-> AlgorithmInfo.getCoin()+"-"+AlgorithmInfo.getName(), Function.identity()));
|
||||
for (LeaseGpuConfig leaseGpuConfig : leaseGpuConfigs1) {
|
||||
AlgorithmInfo coinPower = coinPowerMap.get(leaseGpuConfig.getCoin()+"-"+leaseGpuConfig.getAlgorithm());
|
||||
BigDecimal monthIncome = calculateMonthIncome(leaseGpuConfig, coinPower);
|
||||
leaseGpuConfig.setMonthIncome(monthIncome);
|
||||
}
|
||||
|
||||
}
|
||||
leaseGpuConfigMapper.insertOrUpdateBatchByEntity(leaseGpuConfigs1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算月收入
|
||||
* @param leaseGpuConfig
|
||||
* @param coinPower
|
||||
* @return
|
||||
*/
|
||||
private static BigDecimal calculateMonthIncome(LeaseGpuConfig leaseGpuConfig, AlgorithmInfo coinPower) {
|
||||
BigDecimal monthIncome = BigDecimal.ZERO;
|
||||
if (coinPower != null){
|
||||
monthIncome = leaseGpuConfig.getHashrate()
|
||||
.divide(coinPower.getHashrate().divide(BigDecimal.valueOf(1000 * 1000), 8, RoundingMode.HALF_UP), 8, RoundingMode.HALF_UP)
|
||||
.multiply(BigDecimal.valueOf(24 * 60 * 60)
|
||||
.divide(coinPower.getBlockInterval(), 8, RoundingMode.HALF_UP))
|
||||
.multiply(coinPower.getBlockReward()).multiply(BigDecimal.valueOf(30))
|
||||
.multiply(coinPower.getPrice())
|
||||
;
|
||||
}
|
||||
return monthIncome;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 三方api 获取gpu信息
|
||||
* @return
|
||||
*/
|
||||
public List<GpuInfo> fetchGpuInfo() {
|
||||
String url = "https://whattomine.com/api/v1/gpus?api_token=8ea12738081eaa70a37d62364ddfffecc0c96a6047f02b4cc728af7588fcdbd8";
|
||||
String response = HttpRequest.get(url).execute().body();
|
||||
|
||||
// 将JSONUtil.parseArray改为JSON.parseArray
|
||||
JSONArray gpusArray = JSON.parseArray(response);
|
||||
List<GpuInfo> gpuInfoList = new ArrayList<>();
|
||||
|
||||
for (Object obj : gpusArray) {
|
||||
// JSONObject转换方式
|
||||
JSONObject gpuJson = (JSONObject) obj;
|
||||
GpuInfo gpuInfo = new GpuInfo();
|
||||
|
||||
// 设置基本GPU信息
|
||||
gpuInfo.setId(gpuJson.getLong("id"));
|
||||
gpuInfo.setName(gpuJson.getString("name"));
|
||||
gpuInfo.setRelease_date(gpuJson.getString("release_date"));
|
||||
|
||||
// 处理算法信息
|
||||
JSONArray algorithmsArray = gpuJson.getJSONArray("algorithms");
|
||||
List<AlgorithmInfo> algorithmInfos = new ArrayList<>();
|
||||
|
||||
for (Object algoObj : algorithmsArray) {
|
||||
// JSONObject转换方式
|
||||
JSONObject algoJson = (JSONObject) algoObj;
|
||||
AlgorithmInfo algorithmInfo = new AlgorithmInfo();
|
||||
|
||||
algorithmInfo.setName(algoJson.getString("name"));
|
||||
algorithmInfo.setHashrate(algoJson.getBigDecimal("hashrate"));
|
||||
algorithmInfo.setPower(algoJson.getBigDecimal("power"));
|
||||
|
||||
algorithmInfos.add(algorithmInfo);
|
||||
}
|
||||
|
||||
gpuInfo.setAlgorithms(algorithmInfos);
|
||||
gpuInfoList.add(gpuInfo);
|
||||
}
|
||||
|
||||
return gpuInfoList;
|
||||
}
|
||||
|
||||
|
||||
public List<LeaseGpuConfig> convertGpuInfoToLeaseConfig(List<GpuInfo> gpuInfos) {
|
||||
List<LeaseGpuConfig> leaseGpuConfigs = new ArrayList<>();
|
||||
|
||||
for (GpuInfo gpuInfo : gpuInfos) {
|
||||
if (gpuInfo.getAlgorithms() != null) {
|
||||
for (AlgorithmInfo algorithm : gpuInfo.getAlgorithms()) {
|
||||
LeaseGpuConfig config = buildGpuConfig(gpuInfo, algorithm);
|
||||
leaseGpuConfigs.add(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return leaseGpuConfigs;
|
||||
}
|
||||
|
||||
private static LeaseGpuConfig buildGpuConfig(GpuInfo gpuInfo, AlgorithmInfo algorithm) {
|
||||
LeaseGpuConfig config = new LeaseGpuConfig();
|
||||
config.setName(gpuInfo.getName());
|
||||
config.setAlgorithm(algorithm.getName());
|
||||
config.setHashrate(algorithm.getHashrate().divide(BigDecimal.valueOf(1000 * 1000),2, RoundingMode.HALF_UP));
|
||||
config.setPowerDissipation(algorithm.getPower());
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 三方api 获取gpu 对应算法的收益信息
|
||||
* @return
|
||||
*/
|
||||
public static List<AlgorithmInfo> fetchMiningPower() {
|
||||
String url = "https://whattomine.com/api/v1/coins?api_token=8ea12738081eaa70a37d62364ddfffecc0c96a6047f02b4cc728af7588fcdbd8";
|
||||
String response = HttpRequest.get(url).execute().body();
|
||||
JSONArray gpusArray = JSON.parseArray(response);
|
||||
List<AlgorithmInfo> hashRateInfos = new ArrayList<>();
|
||||
for (int i = 0; i < gpusArray.size(); i++) {
|
||||
JSONObject item = gpusArray.getJSONObject(i);
|
||||
AlgorithmInfo info = new AlgorithmInfo();
|
||||
info.setCoin(item.getString("tag"));
|
||||
info.setName(item.getString("algorithm"));
|
||||
info.setHashrate(new BigDecimal(item.getLong("nethash")));
|
||||
info.setBlockReward(BigDecimal.valueOf(item.getDouble("block_reward")));
|
||||
info.setBlockInterval(BigDecimal.valueOf(item.getDouble("block_time")));
|
||||
// 解析exchanges数组并获取第一个对象的price值
|
||||
JSONArray exchanges = item.getJSONArray("exchanges");
|
||||
if (!exchanges.isEmpty()) {
|
||||
JSONObject firstExchange = exchanges.getJSONObject(0);
|
||||
//30日平均币价
|
||||
info.setPrice(BigDecimal.valueOf(firstExchange.getDouble("price30")).multiply(BigDecimal.valueOf(100000)));
|
||||
}
|
||||
hashRateInfos.add(info);
|
||||
}
|
||||
return hashRateInfos;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.m2pool.lease.task.info;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @Description 算法信息类
|
||||
* @Date 2025/12/16 15:43
|
||||
* @Author yyb
|
||||
*/
|
||||
@Data
|
||||
public class AlgorithmInfo {
|
||||
|
||||
/**
|
||||
* 币种名称
|
||||
*/
|
||||
private String coin;
|
||||
|
||||
/**
|
||||
* 算法名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 挖矿算力
|
||||
*/
|
||||
private BigDecimal hashrate;
|
||||
|
||||
/**
|
||||
* 功耗
|
||||
*/
|
||||
private BigDecimal power;
|
||||
|
||||
/**
|
||||
* 报块间隔
|
||||
*/
|
||||
private BigDecimal blockInterval;
|
||||
|
||||
/**
|
||||
* 报块奖励
|
||||
*/
|
||||
private BigDecimal blockReward;
|
||||
|
||||
private BigDecimal price;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.m2pool.lease.task.info;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description gpu 信息类
|
||||
* @Date 2025/12/16 15:42
|
||||
* @Author yyb
|
||||
*/
|
||||
@Data
|
||||
public class GpuInfo {
|
||||
/**
|
||||
* gpu id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* gpu 名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* gpu 发布日期
|
||||
*/
|
||||
private String release_date;
|
||||
|
||||
|
||||
/**
|
||||
* gpu 算法信息
|
||||
*/
|
||||
private List<AlgorithmInfo> algorithms;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.m2pool.lease.task.info;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class MiningRewardInfo {
|
||||
private int id;
|
||||
/**
|
||||
* 币种名
|
||||
*/
|
||||
private String tag;
|
||||
private String name;
|
||||
private String estimated_rewards;
|
||||
private String estimated_rewards24;
|
||||
private String btc_revenue;
|
||||
private String btc_revenue24;
|
||||
private double revenue;
|
||||
private double revenue24;
|
||||
private double profit;
|
||||
private double profit24;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.m2pool.lease.task.info;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @Description 月收益信息
|
||||
* @Date 2025/12/16 15:43
|
||||
* @Author yyb
|
||||
*/
|
||||
@Builder
|
||||
@Data
|
||||
public class MonthIncomeInfo {
|
||||
|
||||
/**
|
||||
* 算法名称
|
||||
*/
|
||||
private String algorithm;
|
||||
|
||||
/**
|
||||
* 功耗
|
||||
*/
|
||||
private BigDecimal power;
|
||||
|
||||
/**
|
||||
* 矿机算力 单位H/S
|
||||
*/
|
||||
private BigDecimal hashrate;
|
||||
}
|
||||
@@ -1,12 +1,7 @@
|
||||
package com.m2pool.lease.utils;
|
||||
|
||||
import com.m2pool.lease.entity.LeaseProduct;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
public class HashUtils {
|
||||
|
||||
@@ -58,25 +53,6 @@ public class HashUtils {
|
||||
return decimalValue.toString(16) + key;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws NoSuchAlgorithmException {
|
||||
//Long inputStr = 1758610297L;
|
||||
//System.out.println("加密结果" + sha256(inputStr));
|
||||
// 生成RSA密钥对
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||
keyPairGenerator.initialize(2048); // 密钥长度设置为2048位
|
||||
KeyPair keyPair = keyPairGenerator.generateKeyPair();
|
||||
PublicKey publicKey = keyPair.getPublic();
|
||||
PrivateKey privateKey = keyPair.getPrivate();
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
|
||||
// 将公钥转换为Base64字符串格式
|
||||
String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded());
|
||||
System.out.println("公钥 (Base64): " + publicKeyString);
|
||||
|
||||
// 将私钥转换为Base64字符串格式(注意安全!)
|
||||
String privateKeyString = Base64.getEncoder().encodeToString(privateKey.getEncoded());
|
||||
System.out.println("私钥 (Base64): " + privateKeyString);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.m2pool.lease.utils;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
|
||||
public class RsaUtils {
|
||||
public static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsQVIKYozXCfnXUw8+omYLdcdL1pTzmQh35YPsvn22wM4SQJKvMmXmcS6bI5Bu+5zCjL0F56DzfKz0BNZEwb46UshUOO+KFBUr8CxjYE8NOgIsoe5FUn57O6er9/KySaWlkpGZX49K+l3e90R+dFUEfRE/ijYpeZWkLRwcgWZ+2u6HGpl9h/eF6XD0aW9asDjdAbxUQ48TlaWgfP+OHC+Zy2GKGQG16EcDMczrN6a2HbFnwRIUKrFP67UqyRq11BTUziOhXLY8J0MFuwXUk2OY4VpqjrJjHHjlHYADjIL/5K4Io2AhRU9+QSsKFR2wGxi4e8vw2IXDzscrDuah/7YSwIDAQAB"; // 可公开
|
||||
private static final String PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCxBUgpijNcJ+ddTDz6iZgt1x0vWlPOZCHflg+y+fbbAzhJAkq8yZeZxLpsjkG77nMKMvQXnoPN8rPQE1kTBvjpSyFQ474oUFSvwLGNgTw06Aiyh7kVSfns7p6v38rJJpaWSkZlfj0r6Xd73RH50VQR9ET+KNil5laQtHByBZn7a7ocamX2H94XpcPRpb1qwON0BvFRDjxOVpaB8/44cL5nLYYoZAbXoRwMxzOs3prYdsWfBEhQqsU/rtSrJGrXUFNTOI6FctjwnQwW7BdSTY5jhWmqOsmMceOUdgAOMgv/krgijYCFFT35BKwoVHbAbGLh7y/DYhcPOxysO5qH/thLAgMBAAECggEAYE00TczuVfMrbdkcz1ttW3rMWMd2EjDtMJqNXduYjNs6kpVZnUy6WZ/pn0bgweFd2i2QFw1YPQENC2SLL8u6PAhwTnYnK/1PpPFaZlXpMAsPODiX2toMyfWihKFly3pfr9EmbO55TttK8ip5LgPQDZhqtC36dn5Rl5ViGtWrSFgQOJm4Mu7px/6DbAu5c3u9yBqwA5Z90XDGIOivjjquQA4upexCvtBPYm/krCwsZcYHRBeihi+s4mt2Mz+a3u8NkJGxE7+QpXkWC0XR2KKiG4kdD6Sn+d9fG7UZUUBrb1p9Z5n3NV2oh3EKnrV3Pf/J0WEzrDZKBF4I9PMNzEkd2QKBgQDx9uW2HOqGnGv993L57+Twon7BxJHd0WQzdskTNEU7+cdNBYPbailjEOByGBPuupwOc2qTU6j+kyqSH5SoWDpnp1BnmFaJF6X52DJCQ6+2z5MfPApZbMDNSG/MOgPpHRjVcMfdPR/48W0S/1jlPh3ZIQ6bvL/011HYKqNF+NBp5QKBgQC7SfzSgqftZmLiZ4q4DfYGiWjSPQ+G4LwT+ehRNQ1IuJL8yO2tnuOxEN+Egxm5PEY55syeQ41alKWSeoRSFaopdCZZvPnuAEH8rhCgi0ymHIk+24TREZZMJhimBas77JCkRnWfJmfIPCXlv0fS4etzczx+Prntd5B7CKDKYPZWbwKBgQDw6Yblv/yycmQDxbCwse4cuW3Dt9gUJzvBEfA6Mr0MbjHFukwC1rzGajNO5jJSa3Kd4MSoU4/biOPGAbOdudrNAYXI36CpduZG0L+ZwpLdTeeKHdmgF+wPeKP3j3v9Sn9DZLtayFVhI+AaHiuAdEx7t7I31cK6IPjYZfuS252HEQKBgB6WK7r5aZFkyjtta4M5jHdu03aaUEHXy/97LcytXFkHA8JS0jYrn8XYGpjajEXrKRDlt38VSy2C3zN33MpHDX4toOHA8hRDaINqrf56IW9zc5qXYS5/r8sJ4bajcF6d+NVLSIRQUlyqLgpCXel7yecV58g6WEUG5MqjExdaFIDzAoGBAIlhI+jGPRn7lJVTZxik6/Kvj2KKpmpF+WMKer7hLuKd8Tu6iAldNjce9Y9uvD5lvyn+eSGG4OgEKKlPZ4vbY2c3AsYlsJu3ltaz203c61SVYa6tc3xeas9fiLUF7IXd6+6/1nDubG7mDwnMhmGV0pxVJKMUVqx+2LFDFqHaaTAN"; // 这里替换为你的实际私钥
|
||||
|
||||
public static String decrypt(String encryptedData) throws Exception {
|
||||
// Base64解码加密数据
|
||||
byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
|
||||
|
||||
// 加载私钥
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(PRIVATE_KEY));
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
|
||||
|
||||
// 初始化Cipher进行解密
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
|
||||
// 执行解密
|
||||
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
|
||||
return new String(decryptedBytes, StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.m2pool.lease.vo;
|
||||
|
||||
import com.m2pool.common.core.decrpy.Decrypt;
|
||||
import com.m2pool.lease.annotation.EncryptedField;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
@@ -8,8 +8,6 @@ import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 店铺商品配置请求对象
|
||||
@@ -48,8 +46,8 @@ public class ShopConfigVo extends BaseVo {
|
||||
/**
|
||||
* 卖方对应收款钱包
|
||||
*/
|
||||
@Decrypt
|
||||
@ApiModelProperty(value = "卖方对应收款钱包",example = "nexa:nqtsq5g50jkkmklvjyaflg46c4nwuy46z9gzswqe3l0csc7g")
|
||||
|
||||
private String payAddress;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.m2pool.lease.vo.v2;
|
||||
|
||||
import com.m2pool.lease.annotation.EncryptedField;
|
||||
import com.m2pool.lease.vo.BaseVo;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
@@ -31,6 +32,7 @@ public class ShopWalletInfoVo {
|
||||
private String chain;
|
||||
|
||||
@ApiModelProperty(value = "卖方对应收款钱包",example = "nexa:nqtsq5g50jkkmklvjyaflg46c4nwuy46z9gzswqe3l0csc7g")
|
||||
@EncryptedField
|
||||
private String payAddress;
|
||||
|
||||
}
|
||||
|
||||
@@ -17,17 +17,30 @@
|
||||
<sql id="Base_Column_List">
|
||||
id, brand, name, status, memory, power_dissipation, del
|
||||
</sql>
|
||||
<insert id="insertOrUpdate">
|
||||
insert into lease_gpu_config (brand, name, memory)
|
||||
<insert id="insertOrUpdateBatchByGpuInfo">
|
||||
insert into lease_gpu_config ( name, algorithm,coin)
|
||||
values
|
||||
<foreach item="item" index="index" collection="list" separator=",">
|
||||
(#{item.brand}, #{item.name}, #{item.mem})
|
||||
(#{item.model}, #{item.algorithm},'')
|
||||
</foreach>
|
||||
ON DUPLICATE KEY UPDATE
|
||||
brand = VALUES(brand),
|
||||
`name` = VALUES(`name`),
|
||||
memory = VALUES(memory)
|
||||
|
||||
name = VALUES(`name`),
|
||||
`algorithm` = VALUES(`algorithm`),
|
||||
coin = VALUES(coin)
|
||||
</insert>
|
||||
<insert id="insertOrUpdateBatchByEntity">
|
||||
insert into lease_gpu_config ( name, algorithm, power_dissipation,hashrate,month_income)
|
||||
values
|
||||
<foreach item="item" index="index" collection="list" separator=",">
|
||||
(#{item.name}, #{item.algorithm}, #{item.powerDissipation},#{item.hashrate},#{item.monthIncome})
|
||||
</foreach>
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = VALUES(`name`),
|
||||
`algorithm` = VALUES(`algorithm`),
|
||||
power_dissipation = VALUES(power_dissipation),
|
||||
hashrate = VALUES(hashrate),
|
||||
month_income = VALUES(month_income)
|
||||
</insert>
|
||||
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -66,5 +66,13 @@
|
||||
GROUP BY
|
||||
lpc.coin, lpc.algorithm
|
||||
</select>
|
||||
<select id="getTheoryHashRate" resultType="com.m2pool.lease.dto.v2.MachineHashRateMapDto">
|
||||
SELECT machine_id as machineId,hashrate as hashRate FROM lease_machine_config
|
||||
-- TODO 这里最好加个算法,加算法后一一对应
|
||||
WHERE del = 0 AND (machine_id,coin) IN
|
||||
<foreach collection="list" item="item" open="(" separator="," close=")">
|
||||
(#{item.machineId},#{item.coin})
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -17,19 +17,40 @@
|
||||
id, name, coin, algorithm, icon, del
|
||||
</sql>
|
||||
<select id="selectSupportAlgorithm" resultType="com.m2pool.lease.dto.v2.CoinAndAlgorithmDto">
|
||||
SELECT DISTINCT
|
||||
SELECT
|
||||
sub.coin,
|
||||
sub.`algorithm`,
|
||||
sub.isEffect,
|
||||
lgc.`name` AS model,
|
||||
lgc.hashrate AS hashRate,
|
||||
lgc.power_dissipation AS powerDissipation,
|
||||
lgc.month_income as monthIncome,
|
||||
IF(lgc.id,FALSE,TRUE) AS isAdd
|
||||
FROM
|
||||
(
|
||||
SELECT DISTINCT
|
||||
sc.coin,
|
||||
sc.algorithm,
|
||||
IF(cc.id,true,false) as isEffect
|
||||
FROM
|
||||
lease_mining_software_config sc
|
||||
LEFT JOIN lease_pool_coin_config cc ON sc.coin = cc.coin AND cc.`algorithm` = sc.`algorithm` AND cc.status = 1
|
||||
WHERE
|
||||
sc.del = 0
|
||||
AND sc.name IN
|
||||
<foreach item="item" index="index" collection="miningsofts" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
IF( cc.id, TRUE, FALSE ) AS isEffect
|
||||
FROM
|
||||
lease_mining_software_config sc
|
||||
LEFT JOIN lease_pool_coin_config cc ON sc.coin = cc.coin AND cc.`algorithm` = sc.`algorithm` AND cc.status = 1
|
||||
WHERE
|
||||
sc.del = 0
|
||||
AND sc.name IN
|
||||
<foreach item="item" index="index" collection="miningsofts" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
) sub
|
||||
LEFT JOIN(
|
||||
SELECT gc.`name`,gc.hashrate,gc.power_dissipation,gc.algorithm,gc.id,gc.month_income FROM
|
||||
lease_gpu_config gc
|
||||
WHERE gc.`name` IN
|
||||
<foreach item="item" index="index" collection="modelList" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
) lgc ON sub.`algorithm` = lgc.algorithm
|
||||
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -68,22 +68,21 @@
|
||||
|
||||
<select id="getPurchasedItems" resultType="com.m2pool.lease.dto.v2.PurchasedMachineListDto">
|
||||
select
|
||||
id,
|
||||
coin,
|
||||
algorithm,
|
||||
pool,
|
||||
pool_url as poolUrl,
|
||||
pool_user as poolUser,
|
||||
worker_id as workerId,
|
||||
wallet_address as walletAddress,
|
||||
watch_url as watchUrl,
|
||||
status,
|
||||
start_time as startTime,
|
||||
end_time as endTime
|
||||
end_time
|
||||
FROM lease_order_mining
|
||||
WHERE user_id = #{userEmail}
|
||||
ORDER BY status DESC,end_time DESC
|
||||
GROUP BY wallet_address,pool_user,pool,pool_url,coin,`algorithm`
|
||||
ORDER BY `status` DESC,end_time DESC
|
||||
</select>
|
||||
<select id="getPurchasedInfo" resultType="com.m2pool.lease.dto.v2.PurchasedMachineDto">
|
||||
<select id="getPurchasedInfo" resultType="com.m2pool.lease.dto.v2.MiningConfigInfoDto">
|
||||
select
|
||||
id ,
|
||||
coin,
|
||||
@@ -91,12 +90,6 @@
|
||||
pool,
|
||||
pool_url as poolUrl,
|
||||
pool_user as poolUser,
|
||||
|
||||
-- worker_id as workerId,
|
||||
-- status,
|
||||
-- start_time as startTime,
|
||||
-- end_time as endTime,
|
||||
|
||||
wallet_address as walletAddress,
|
||||
watch_url as watchUrl
|
||||
FROM lease_order_mining
|
||||
@@ -104,12 +97,25 @@
|
||||
</select>
|
||||
<select id="getRecentlyHashrate" resultType="com.m2pool.lease.dto.v2.MiningHashrateInfoDto">
|
||||
SELECT
|
||||
date_time AS recordTime,
|
||||
hashrate AS power
|
||||
FROM
|
||||
$ {pool}
|
||||
WHERE
|
||||
wallet = #{wallet} and coin = #{coin} and miner = #{miner} order by date_time desc limit 1
|
||||
t.datetime AS recordTime,
|
||||
t.hashrate AS power,
|
||||
t.miner
|
||||
FROM (
|
||||
SELECT
|
||||
datetime,
|
||||
hashrate,
|
||||
miner,
|
||||
ROW_NUMBER() OVER(PARTITION BY miner ORDER BY datetime DESC) as rn
|
||||
FROM `${pool}`
|
||||
WHERE wallet = #{wallet}
|
||||
AND coin = #{coin}
|
||||
AND miner IN (
|
||||
<foreach collection="list" item="item" separator=",">
|
||||
#{item.workerId}
|
||||
</foreach>
|
||||
)
|
||||
) t
|
||||
WHERE t.rn = 1
|
||||
</select>
|
||||
<select id="getRecently24HourHashrate" resultType="com.m2pool.lease.dto.v2.RealHashrateInfoDto">
|
||||
SELECT
|
||||
@@ -160,6 +166,22 @@
|
||||
</foreach>
|
||||
)
|
||||
</select>
|
||||
<select id="getPurchasedMachineInfo" resultType="com.m2pool.lease.dto.v2.PurchasedMachineDto">
|
||||
select
|
||||
id ,
|
||||
worker_id as workerId,
|
||||
status,
|
||||
start_time as startTime,
|
||||
end_time as endTime
|
||||
FROM lease_order_mining
|
||||
WHERE
|
||||
wallet_address = #{info.walletAddress} AND
|
||||
pool_user = #{info.poolUser} AND
|
||||
pool = #{info.pool} AND
|
||||
pool_url = #{info.poolUrl} AND
|
||||
coin = #{info.coin} AND
|
||||
`algorithm` = #{info.algorithm}
|
||||
</select>
|
||||
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -295,7 +295,7 @@ WHERE
|
||||
SELECT
|
||||
id
|
||||
FROM
|
||||
lease_product_machine
|
||||
lease_machine
|
||||
WHERE
|
||||
shop_id = #{shopId}
|
||||
and `del` = 0
|
||||
|
||||
Reference in New Issue
Block a user