diff --git a/m2pool-common/common-security/src/main/java/com/m2pool/common/security/interceptor/AuthRequestWrapper.java b/m2pool-common/common-security/src/main/java/com/m2pool/common/security/interceptor/AuthRequestWrapper.java new file mode 100644 index 0000000..ca8d168 --- /dev/null +++ b/m2pool-common/common-security/src/main/java/com/m2pool/common/security/interceptor/AuthRequestWrapper.java @@ -0,0 +1,64 @@ +package com.m2pool.common.security.interceptor; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.InputStreamReader; +import java.util.stream.Collectors; + +public class AuthRequestWrapper extends HttpServletRequestWrapper { + + private String body; + + public AuthRequestWrapper(HttpServletRequest request) { + super(request); + try(BufferedReader reader = request.getReader()){ + body= reader.lines().collect(Collectors.joining()); + }catch (Exception e){ + System.out.println("!!-- read request from requestbody error"+e.getMessage()); + } + } + + @Override + public BufferedReader getReader() { + return new BufferedReader(new InputStreamReader(this.getInputStream())); + } + + @Override + public ServletInputStream getInputStream() { + final ByteArrayInputStream byteArrayIns = new ByteArrayInputStream(body.getBytes()); + ServletInputStream servletIns = new ServletInputStream() { + @Override + public boolean isFinished() { + return false; + } + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setReadListener(ReadListener readListener) { + + } + + @Override + public int read() { + return byteArrayIns.read(); + } + }; + return servletIns; + } + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body; + } +} diff --git a/m2pool-common/common-security/src/main/java/com/m2pool/common/security/interceptor/CoinInterceptor.java b/m2pool-common/common-security/src/main/java/com/m2pool/common/security/interceptor/CoinInterceptor.java new file mode 100644 index 0000000..6780ca7 --- /dev/null +++ b/m2pool-common/common-security/src/main/java/com/m2pool/common/security/interceptor/CoinInterceptor.java @@ -0,0 +1,66 @@ +package com.m2pool.common.security.interceptor; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedReader; +import java.io.IOException; + +@Component +public class CoinInterceptor implements HandlerInterceptor { + + private final ObjectMapper objectMapper = new ObjectMapper(); + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + System.out.println("调用Coin拦截器1:" + request); + + // 仅处理 POST、PUT 等有请求体的请求方法 + if ("POST".equalsIgnoreCase(request.getMethod()) || "PUT".equalsIgnoreCase(request.getMethod())) { + try { + // 读取请求体内容 + if (request instanceof AuthRequestWrapper){ + //BufferedReader reader = request.getReader(); + //System.out.println("调用Coin拦截器2:" + reader); + // + //if (!requestBody.isEmpty()) { + // // 反序列化请求体为 RequestObject 对象 + // RequestObject requestObject = objectMapper.readValue(requestBody, RequestObject.class); + // System.out.println("调用Coin拦截器3:" + requestObject.toString()); + // String coin = requestObject.getCoin(); + // System.out.println("调用Coin拦截器4:" + coin); + // if ("enx".equals(coin)) { + // response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + // response.getWriter().write("enx币种已下架"); + // return false; + // } + //} + } + + } catch (Exception e) { + // 处理反序列化异常 + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + response.getWriter().write("请求体解析失败"); + return false; + } + } + return true; + } + + /** + * 读取请求体内容 + */ + private String readRequestBody(HttpServletRequest request) throws IOException { + StringBuilder stringBuilder = new StringBuilder(); + try (BufferedReader reader = request.getReader()) { + String line; + while ((line = reader.readLine()) != null) { + stringBuilder.append(line); + } + } + return stringBuilder.toString(); + } +} diff --git a/m2pool-common/common-security/src/main/java/com/m2pool/common/security/interceptor/RequestBodyFilter.java b/m2pool-common/common-security/src/main/java/com/m2pool/common/security/interceptor/RequestBodyFilter.java new file mode 100644 index 0000000..81e0766 --- /dev/null +++ b/m2pool-common/common-security/src/main/java/com/m2pool/common/security/interceptor/RequestBodyFilter.java @@ -0,0 +1,27 @@ +package com.m2pool.common.security.interceptor; + +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; +import org.springframework.web.util.ContentCachingRequestWrapper; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +@Component +@WebFilter("/*") +public class RequestBodyFilter extends OncePerRequestFilter { + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + + request = new AuthRequestWrapper(request); + filterChain.doFilter(request,response); + } +} diff --git a/m2pool-common/common-security/src/main/java/com/m2pool/common/security/interceptor/RequestObject.java b/m2pool-common/common-security/src/main/java/com/m2pool/common/security/interceptor/RequestObject.java new file mode 100644 index 0000000..a342126 --- /dev/null +++ b/m2pool-common/common-security/src/main/java/com/m2pool/common/security/interceptor/RequestObject.java @@ -0,0 +1,16 @@ +package com.m2pool.common.security.interceptor; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class RequestObject { + private String coin; + + // 添加 getter 和 setter 方法 + public String getCoin() { + return coin; + } + + public void setCoin(String coin) { + this.coin = coin; + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/CoinCharge.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/CoinCharge.java index dc0c6f1..43cf75a 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/CoinCharge.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/CoinCharge.java @@ -14,6 +14,7 @@ import java.util.List; public enum CoinCharge { ETH_USDT("ETH","USDT", BigDecimal.valueOf(1)), + ETH_ETH("ETH","USDT", BigDecimal.valueOf(0.0001)), TRON_USDT("TRON","USDT", BigDecimal.valueOf(1)), TRON_NEXA("TRON","NEXA", BigDecimal.valueOf(1000)); diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/PowerUnit.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/PowerUnit.java index e388fa2..36c071b 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/PowerUnit.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/PowerUnit.java @@ -28,9 +28,9 @@ public class PowerUnit { HashMap map = new HashMap<>(); map.put(KH_UNIT, BigDecimal.valueOf(1000)); map.put(MH_UNIT, BigDecimal.valueOf(1000 * 1000)); - map.put(GH_UNIT, BigDecimal.valueOf(1000L * 1000 * 1000 * 1000)); - map.put(TH_UNIT, BigDecimal.valueOf(1000L * 1000 * 1000 * 1000 * 1000)); - map.put(PH_UNIT, BigDecimal.valueOf(1000L * 1000 * 1000 * 1000 * 1000 * 1000)); + map.put(GH_UNIT, BigDecimal.valueOf(1000L * 1000 * 1000)); + map.put(TH_UNIT, BigDecimal.valueOf(1000L * 1000 * 1000 * 1000 )); + map.put(PH_UNIT, BigDecimal.valueOf(1000L * 1000 * 1000 * 1000 * 1000)); UNIT_MAP = Collections.unmodifiableMap(map); } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductController.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductController.java index 44f4a2b..5c623dc 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductController.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductController.java @@ -4,10 +4,7 @@ package com.m2pool.lease.controller; import com.m2pool.lease.dto.*; import com.m2pool.lease.service.LeaseProductService; import com.m2pool.lease.service.LeaseUserOwnedProductService; -import com.m2pool.lease.vo.BaseVo; -import com.m2pool.lease.vo.ProductPageVo; -import com.m2pool.lease.vo.ProductURDVo; -import com.m2pool.lease.vo.UserOwnedProductVo; +import com.m2pool.lease.vo.*; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; @@ -17,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; +import java.util.List; /** *

@@ -56,8 +54,14 @@ public class LeaseProductController { @ApiOperation("查询单个商品详情(包含商品对应的售卖机器详情列表)") @PostMapping("/getMachineInfo") - public Result getProductMachineInfo(@RequestBody BaseVo BaseVo) { - return leaseProductService.getProductMachineInfo(BaseVo.getId()); + public PageResult getProductMachineInfo(@RequestBody ProductMachineVo productMachineVo) { + return leaseProductService.getProductMachineInfo(productMachineVo); + } + + @ApiOperation("单个商品矿机列表页面---获取支付方式") + @PostMapping("/getPayTypes") + public Result> getPayTypes() { + return leaseProductService.getPayTypes(); } @@ -96,5 +100,26 @@ public class LeaseProductController { public Result getOwnedById(@RequestBody BaseVo baseVo) { return leaseUserOwnedProductService.getOwnedById(baseVo); } + + + @ApiOperation("查询用户店铺支持的支付方式") + @PostMapping("/getSupportPayType") + @Deprecated + public Result> getSupportPayType() { + return leaseProductService.getSupportPayType(); + } + + + @ApiOperation("获取店铺商品列表用于新增绑定店铺钱包") + @PostMapping("/getProductListForShopWalletConfig") + public Result> getProductListForShopWalletConfig() { + return leaseProductService.getProductListForShopWalletConfig(); + } + + @ApiOperation("新增绑定店铺钱包并设置店铺下面每个矿机该钱包币种的售价 + 钱包绑定") + @PostMapping("/updateProductListForShopWalletConfig") + public Result updateProductListForShopWalletConfig(@RequestBody ProductMachineForWalletConfigVo productMachineForWalletConfigVo) { + return leaseProductService.updateProductListForShopWalletConfig(productMachineForWalletConfigVo); + } } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductMachineController.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductMachineController.java index 2ded01b..e63ada5 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductMachineController.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductMachineController.java @@ -1,8 +1,10 @@ package com.m2pool.lease.controller; -import com.m2pool.common.security.annotation.RequiresLogin; -import com.m2pool.lease.dto.*; +import com.m2pool.lease.dto.PageResult; +import com.m2pool.lease.dto.ProductUpdateMachineDto; +import com.m2pool.lease.dto.Result; +import com.m2pool.lease.dto.UserMinerDto; import com.m2pool.lease.service.LeaseProductMachineService; import com.m2pool.lease.vo.*; import io.swagger.annotations.Api; diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShopController.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShopController.java index b3cfbac..1a29d4d 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShopController.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShopController.java @@ -121,8 +121,9 @@ public class LeaseShopController { * @param shopConfigVo 商铺配置信息 * @return 操作结果 */ - @ApiOperation("钱包配置---新增商铺收款钱包绑定配置") + @ApiOperation("钱包配置---新增商铺收款钱包绑定配置(弃用,业务移到/product/updateProductListForShopWalletConfig 接口)") @PostMapping("/addShopConfig") + @Deprecated public Result addShopConfig(@RequestBody ShopConfigVo shopConfigVo) { return leaseShopService.addShopConfig(shopConfigVo); } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ChainAndCoinDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ChainAndCoinDto.java new file mode 100644 index 0000000..afa4007 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ChainAndCoinDto.java @@ -0,0 +1,58 @@ +package com.m2pool.lease.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.Objects; + +/** + *

+ * 余额提现请求对象 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ChainAndCoinDto { + + + private String coin; + private String chain; + private Long shopId; + + public ChainAndCoinDto( String coin,String chain) { + this.chain = chain; + this.coin = coin; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ChainAndCoinDto that = (ChainAndCoinDto) o; + return Objects.equals(coin, that.coin) && Objects.equals(chain, that.chain) && Objects.equals(shopId, that.shopId); + } + + @Override + public int hashCode() { + return Objects.hash(coin, chain,shopId); + } + + @Override + public String toString() { + return "ChainAndCoinDto{" + + "coin='" + coin + '\'' + + ", chain='" + chain + '\'' + + ", shopId='" + shopId + '\'' + + '}'; + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/MachinePayTypeDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/MachinePayTypeDto.java new file mode 100644 index 0000000..6801ffa --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/MachinePayTypeDto.java @@ -0,0 +1,41 @@ +package com.m2pool.lease.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + *

+ * 矿机售价配置返回对象 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "矿机售价配置返回对象",value = "MachinePayTypeDto" ) +public class MachinePayTypeDto { + @ApiModelProperty(value = "矿机币种售价配置id") + private Long payTypeId; + + @ApiModelProperty(value = "矿机id(忽略)") + private Long productMachineId; + + @ApiModelProperty(value = "售价") + private BigDecimal price; + + @ApiModelProperty(value = "链") + private String chain; + + @ApiModelProperty(value = "售价单位币种") + private String coin; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/MachineTotalPriceDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/MachineTotalPriceDto.java new file mode 100644 index 0000000..503b851 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/MachineTotalPriceDto.java @@ -0,0 +1,34 @@ +package com.m2pool.lease.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + *

+ * 矿机售价配置返回对象 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "购物车矿机总价返回对象",value = "MachineTotalPriceDto" ) +public class MachineTotalPriceDto { + @ApiModelProperty(value = "售价") + private BigDecimal price; + + @ApiModelProperty(value = "链") + private String chain; + + @ApiModelProperty(value = "售价单位币种") + private String coin; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/PayTypeDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/PayTypeDto.java new file mode 100644 index 0000000..01b5b64 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/PayTypeDto.java @@ -0,0 +1,37 @@ +package com.m2pool.lease.dto; + + +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; + +/** + * @Description 店铺支持的支付方式 + * @Date 2024/6/14 15:57 + * @Author dy + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@ApiModel(description = "店铺支持的支付方式",value = "PayTypeDto") +public class PayTypeDto { + + @ApiModelProperty(value = "店铺id(不展示)") + private Long shopId; + + @ApiModelProperty(value = "链") + private String chain; + + @ApiModelProperty(value = "支付币种") + private String coin; + + @ApiModelProperty(value = "支付币种图标") + private String image; + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductDto.java index d5efd63..bc30aa8 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductDto.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductDto.java @@ -27,14 +27,15 @@ public class ProductDto { @ApiModelProperty(value = "商品id") private Long id; - - /** * 店铺id */ @ApiModelProperty(value = "店铺id") private Long shopId; + @ApiModelProperty(value = "店铺名称") + private String shopName; + /** * 商品名称 */ @@ -59,19 +60,18 @@ public class ProductDto { @ApiModelProperty(value = "上下架状态,0 上架,1 下架") private Integer state; - /** - * 商品机器单机算力(卖方手动填写) - */ - //@ApiModelProperty(value = "商品机器单机理论算力(卖方手动填写)") - //private BigDecimal power; /** * 库存中机器价格范围 */ @ApiModelProperty(value = "价格范围") + @Deprecated private String priceRange; + @ApiModelProperty(value = "店铺支持的支付方式") + private List payTypes; + /** * 算法 */ @@ -83,34 +83,6 @@ public class ProductDto { */ @ApiModelProperty(value = "商品描述") private String description; - - - /** - * 功耗 单位kw/h - */ - //@ApiModelProperty(value = "功耗 单位kw/h") - //private BigDecimal powerDissipation; - - - /** - * 电费 单位 $/度 - */ - //@ApiModelProperty(value = "电费 单位 $/度") - //private BigDecimal electricityBill; - - /** - * 收益率 单位 % - */ - //@ApiModelProperty(value = "收益率 单位 %") - //private BigDecimal incomeRate; - - - /** - * 机器成本价格单位$ [ 功耗 * 电费 * 24 * (1 + 收益率) ] - */ - //@ApiModelProperty(value = "机器成本价格单位$ [ 功耗 * 电费 * 24 * (1 + 收益率) ]") - // private BigDecimal cost; - /** * 矿机挖矿币种 nexa rxd dgbo dgbq dgbs alph enx grs mona */ diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductForWalletConfigDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductForWalletConfigDto.java new file mode 100644 index 0000000..a2c331a --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductForWalletConfigDto.java @@ -0,0 +1,71 @@ +package com.m2pool.lease.dto; + +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; + +/** + *

+ * 钱包配置修改商品支付方式返回对象 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "钱包配置修改商品支付方式返回对象",value = "ProductForWalletConfigDto" ) +public class ProductForWalletConfigDto { + + @ApiModelProperty(value = "商品id") + private Long productId; + /** + * 商品名称 + */ + @ApiModelProperty(value = "商品名称") + private String name; + + /** + * 商品图片路径 + */ + @ApiModelProperty(value = "商品图片路径") + private String image; + + /** + * 上下架状态,0 上架,1 下架 + */ + @ApiModelProperty(value = "上下架状态,0 上架,1 下架") + private Integer state; + + /** + * 算法 + */ + @ApiModelProperty(value = "算法") + private String algorithm; + + /** + * 商品描述 + */ + @ApiModelProperty(value = "商品描述") + private String description; + /** + * 矿机挖矿币种 nexa rxd dgbo dgbq dgbs alph enx grs mona + */ + @ApiModelProperty(value = "矿机挖矿币种 nexa rxd dgbo dgbq dgbs alph enx grs mona") + private String coin; + /** + * 总矿机数 + */ + @ApiModelProperty(value = "总矿机数(已售 + 未售出矿机)") + private Integer totalMachineNumber; + + @ApiModelProperty(value = "矿机列表") + private List machineList; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductMachineDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductMachineDto.java index f4a3cea..9c17688 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductMachineDto.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductMachineDto.java @@ -9,6 +9,7 @@ import lombok.NoArgsConstructor; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.util.List; /** *

@@ -56,7 +57,6 @@ public class ProductMachineDto { @ApiModelProperty(value = "挖矿机器编号") private String miner; - /** * 单价 */ @@ -109,12 +109,6 @@ public class ProductMachineDto { @ApiModelProperty(value = "租赁天数") private Integer leaseTime; - /** - * 单机预估实际收入 - */ - //@ApiModelProperty(value = "单机预估实际收入(每日)") - //private BigDecimal actualIncome; - @ApiModelProperty(value = "算法") private String algorithm; @@ -124,7 +118,7 @@ public class ProductMachineDto { @ApiModelProperty(value = "最大可租借天数(默认七天)",example = "7") private Integer maxLeaseDays; - @ApiModelProperty(value = "币种") + @ApiModelProperty(value = "挖矿机器挖矿币种") private String coin; @ApiModelProperty(value = "商品名称") @@ -132,4 +126,11 @@ public class ProductMachineDto { @ApiModelProperty(value = "是否删除 0否 1是") private Integer del; + + @ApiModelProperty(value = "支付币种") + private String payCoin; + + + @ApiModelProperty(value = "售价集合") + private List priceList; } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductMachineForWalletConfigDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductMachineForWalletConfigDto.java new file mode 100644 index 0000000..4874c18 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductMachineForWalletConfigDto.java @@ -0,0 +1,105 @@ +package com.m2pool.lease.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + *

+ * 商品对应实际商品返回对象 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "钱包配置修改矿机支付方式返回对象",value = "ProductMachineForWalletConfigDto" ) +public class ProductMachineForWalletConfigDto { + + @ApiModelProperty(value = "矿机ID") + private Long productMachineId; + + @ApiModelProperty(value = "商品ID") + private Long productId; + + /** + * 挖矿机器 对应的矿工账号 + */ + @ApiModelProperty(value = "挖矿机器 对应的矿工账号") + private String user; + + /** + * 挖矿机器型号 + */ + @ApiModelProperty(value = "挖矿机器型号") + private String type; + + /** + * 挖矿机器编号 + */ + @ApiModelProperty(value = "挖矿机器编号") + private String miner; + + @ApiModelProperty(value = "挖矿币种") + private String coin; + + ///** + // * 实际算力(计算得到,商家不能够自己添加和修改) + // */ + //@ApiModelProperty(value = "3天算力平均大小---实际实时算力(计算得到,商家不能够自己添加和修改)") + //private BigDecimal computingPower; + + @ApiModelProperty(value = "算力单位") + private String unit; + + /** + * 上下架状态,0 上架,1 下架 + */ + @ApiModelProperty(value = "上下架状态,0 上架,1 下架") + private Integer state; + + /** + * 售出状态 0未售出 1已售出 2售出中 + */ + @ApiModelProperty(value = "售出状态 0未售出 1已售出 2售出中") + private Integer saleState; + + /** + * 理论算力 + */ + @ApiModelProperty(value = "理论算力(卖方手动填写)") + private BigDecimal theoryPower; + + @ApiModelProperty(value = "单机理论收入(每日) 单位币种") + private BigDecimal theoryIncome; + + @ApiModelProperty(value = "单机理论收入(每日) 单位USDT") + private BigDecimal theoryUsdtIncome; + + @ApiModelProperty(value = "功耗 单位kw/h",example = "10") + private BigDecimal powerDissipation; + + + + /** + * 单价 + */ + @ApiModelProperty(value = "单价") + private BigDecimal price; + + @ApiModelProperty(value = "支付链") + private BigDecimal chain; + + @ApiModelProperty(value = "支付币种") + private BigDecimal symbol; + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductMachineForWalletConfigVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductMachineForWalletConfigVo.java new file mode 100644 index 0000000..c3f5ae4 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductMachineForWalletConfigVo.java @@ -0,0 +1,50 @@ +package com.m2pool.lease.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.List; + +/** + *

+ * 商品对应实际商品返回对象 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "钱包配置修改矿机支付方式请求对象",value = "ProductMachineForWalletConfigVo" ) +public class ProductMachineForWalletConfigVo { + + @ApiModelProperty(value = "钱包地址") + private String payAddress; + + @ApiModelProperty(value = "支付链") + private String chain; + + @ApiModelProperty(value = "支付币种,可以多个以逗号隔开") + private String symbol; + + @ApiModelProperty(value = "价格列表") + private List productMachineForWalletConfigVoList; + + @Data + @ApiModel(description = "币(二级) 下拉列表返回对象",value = "PriceVo") + public static class PriceVo{ + @ApiModelProperty(value = "矿机ID") + private Long productMachineId; + @ApiModelProperty(value = "单价,可以多个以逗号隔开") + private String price; + } + + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductMachineInfoDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductMachineInfoDto.java index 885fdb9..74a3169 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductMachineInfoDto.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductMachineInfoDto.java @@ -31,4 +31,6 @@ public class ProductMachineInfoDto { @ApiModelProperty(value = "矿机范围及矿机详情返回对象") private List machineRangeInfoList; + + } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductUpdateMachineDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductUpdateMachineDto.java index 8d9072c..5067305 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductUpdateMachineDto.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ProductUpdateMachineDto.java @@ -9,6 +9,7 @@ import lombok.NoArgsConstructor; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.util.List; /** *

@@ -50,8 +51,8 @@ public class ProductUpdateMachineDto { /** * 单价 */ - @ApiModelProperty(value = "单价") - private BigDecimal price; + @ApiModelProperty(value = "售价集合") + private List priceList; /** * 实际算力(计算得到,商家不能够自己添加和修改) @@ -59,7 +60,6 @@ public class ProductUpdateMachineDto { @ApiModelProperty(value = "3天算力平均大小---实际实时算力(计算得到,商家不能够自己添加和修改)") private BigDecimal computingPower; - /** * 理论算力 */ diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ShopCartDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ShopCartDto.java index 9482dd5..53a3d21 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ShopCartDto.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ShopCartDto.java @@ -38,12 +38,12 @@ public class ShopCartDto { @ApiModelProperty(value = "店铺下机器总数") private Integer totalMachine; + @ApiModelProperty(value = "总价集合") + private List totalPriceList; + @ApiModelProperty(value = "商品支持的支付地址") private List payConfigList; - //@ApiModelProperty(value = "购物车二层商品列表返回对象") - //List shoppingCartInfoDtoList; - @ApiModelProperty(value = "商品机器列表") List productMachineDtoList; } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ShoppingCartInfoDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ShoppingCartInfoDto.java index 904fc67..478f9f4 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ShoppingCartInfoDto.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ShoppingCartInfoDto.java @@ -21,52 +21,20 @@ import java.util.List; @Data @NoArgsConstructor @AllArgsConstructor -@ApiModel(description = "购物车二层商品列表返回对象",value = "ShoppingCartInfoDto" ) +@ApiModel(description = "购物车二层商品列表返回对象(不再使用)",value = "ShoppingCartInfoDto" ) public class ShoppingCartInfoDto { - - /** - * ID - */ - //@ApiModelProperty(value = "购物车详情ID") - //private Long id; - - - @ApiModelProperty(value = "店铺ID",example = "8") - private Long shopId; - /** * 商品 ID */ - @ApiModelProperty(value = "商品 ID") private Long productId; /** * 商品机器ID */ - @ApiModelProperty(value = "商品机器ID") private Long productMachineId; - /** - * 商品名称 + * 租期 */ - @ApiModelProperty(value = "商品名称") - private String name; - - /** - * 商品上下架状态,0 上架,1 下架 - */ - @ApiModelProperty(value = "商品上下架状态,0 上架,1 下架") - private Integer productState; - - - @ApiModelProperty(value = "矿机挖矿币种 nexa rxd dgbo dgbq dgbs alph enx grs mona",example = "nexa") - private String coin; - - @ApiModelProperty(value = "商品图片路径") - private String image; - - - @ApiModelProperty(value = "商品机器列表") - List productMachineDtoList; + private Integer leaseTime; } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseOrderFee.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseOrderFee.java new file mode 100644 index 0000000..bfc8a6e --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseOrderFee.java @@ -0,0 +1,46 @@ +package com.m2pool.lease.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.*; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + *

+ * 订单手续费表 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class LeaseOrderFee implements Serializable { + + private static final long serialVersionUID=1L; + + /** + * 订单 ID + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + private Long orderId; + + private BigDecimal fee; + + private String toAddress; + + private Boolean status; + + + + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseOrderInfo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseOrderInfo.java index 0b658c7..546b55d 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseOrderInfo.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseOrderInfo.java @@ -1,6 +1,7 @@ package com.m2pool.lease.entity; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import lombok.*; @@ -65,5 +66,12 @@ public class LeaseOrderInfo implements Serializable { */ private Boolean del; + /** + * 手续费 + */ + private BigDecimal fee; + + @TableField(exist = false) + private String chainAndCoinKey; } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseOrderItem.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseOrderItem.java index 3da8efd..e157616 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseOrderItem.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseOrderItem.java @@ -153,6 +153,21 @@ public class LeaseOrderItem implements Serializable { */ private String image; + /** + * 已支付金额 + */ + private BigDecimal alreadyPayAmount; + + /** + * 已支付金额(真实) + */ + private BigDecimal alreadyPayRealAmount; + + /** + * 当日待支付确认金额 + */ + private BigDecimal settlePayRealAmount; + /** * 商品类型 0 矿机 1 算力 */ diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeasePayRechargeMessage.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeasePayRechargeMessage.java index cdb13b8..766bdf9 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeasePayRechargeMessage.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeasePayRechargeMessage.java @@ -92,4 +92,14 @@ public class LeasePayRechargeMessage implements Serializable { */ private Boolean del; + /** + * 区块高度 + */ + private Long blockHeight; + + /** + * 充值来源地址(用户自己的钱包 + */ + private String fromAddress; + } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeasePayRecordMessage.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeasePayRecordMessage.java index 47fbcb8..559fa37 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeasePayRecordMessage.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeasePayRecordMessage.java @@ -46,6 +46,12 @@ public class LeasePayRecordMessage implements Serializable { */ private String toAddress; + + /** + * 订单id + */ + private String orderId; + /** * 订单号 */ @@ -108,10 +114,6 @@ public class LeasePayRecordMessage implements Serializable { private Long blockHeight; - /** - * 订单id - */ - private String orderId; /** * 支付时间 diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeasePayWithdrawMessage.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeasePayWithdrawMessage.java index 30ac9ff..17cae9f 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeasePayWithdrawMessage.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeasePayWithdrawMessage.java @@ -102,4 +102,9 @@ public class LeasePayWithdrawMessage implements Serializable { */ private Boolean del; + /** + * 区块高度 + */ + private Long blockHeight; + } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseProductMachine.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseProductMachine.java index 064af81..503e2c2 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseProductMachine.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseProductMachine.java @@ -1,6 +1,7 @@ package com.m2pool.lease.entity; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import io.swagger.annotations.ApiModelProperty; import lombok.*; @@ -8,6 +9,7 @@ import lombok.*; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.util.concurrent.atomic.AtomicInteger; /** *

@@ -142,4 +144,7 @@ public class LeaseProductMachine implements Serializable { private BigDecimal incomeRate; private Integer maxLeaseDays; + + @TableField(exist = false) + private Integer updateCount; } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseProductMachinePrice.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseProductMachinePrice.java new file mode 100644 index 0000000..d89f9f8 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseProductMachinePrice.java @@ -0,0 +1,41 @@ +package com.m2pool.lease.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.*; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + *

+ * 商品表对应的物品机器表 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class LeaseProductMachinePrice implements Serializable { + + private static final long serialVersionUID=1L; + + /** + * 主键ID + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + private Long productMachineId; + + private BigDecimal price; + + private String coin; + + private String chain; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseShoppingCartInfo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseShoppingCartInfo.java index bddee81..94d7c72 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseShoppingCartInfo.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseShoppingCartInfo.java @@ -30,6 +30,7 @@ public class LeaseShoppingCartInfo implements Serializable { @TableId(value = "id", type = IdType.AUTO) private Long id; + /** * 购物车ID */ diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseOrderFeeMapper.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseOrderFeeMapper.java new file mode 100644 index 0000000..4e475af --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseOrderFeeMapper.java @@ -0,0 +1,26 @@ +package com.m2pool.lease.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.m2pool.lease.dto.OrderStatusDto; +import com.m2pool.lease.entity.LeaseOrderFee; +import com.m2pool.lease.entity.LeaseOrderItem; +import com.m2pool.lease.entity.LeasePaymentRecord; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Set; + +/** + *

+ * 订单明细表 Mapper 接口 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Mapper +public interface LeaseOrderFeeMapper extends BaseMapper { + + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseOrderItemMapper.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseOrderItemMapper.java index 34b6412..014ac44 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseOrderItemMapper.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseOrderItemMapper.java @@ -4,9 +4,11 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.m2pool.lease.dto.OrderStatusDto; import com.m2pool.lease.entity.LeaseOrderItem; import com.m2pool.lease.entity.LeasePaymentRecord; +import com.m2pool.lease.mq.message.RabbitmqPayAutoReturnInfoMessage; import org.apache.ibatis.annotations.MapKey; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.transaction.Transaction; import java.util.List; import java.util.Map; @@ -51,4 +53,22 @@ public interface LeaseOrderItemMapper extends BaseMapper { */ List selectOrderInfoIds(@Param("itemIds") Set itemIds); + + /** + * 获取需要更新已实际支付总金额的订单详情 + * @param address + * @param transaction + * @return + */ + List getNeedUpdateOrderItem(@Param("orderId") Long orderId); + + + + /** + * 通过订单id找到订单详情 + * @param orderIds + * @return + */ + List getOrderItemByOrderIds(@Param("orderIds") Set orderIds); + } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeasePayRecordMessageMapper.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeasePayRecordMessageMapper.java index 6972983..841c16a 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeasePayRecordMessageMapper.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeasePayRecordMessageMapper.java @@ -64,19 +64,19 @@ public interface LeasePayRecordMessageMapper extends BaseMapper getRecentlyTransaction(@Param("walletList") List walletList); - /** - * 根据订单id 查询当天支付状态 - * @param orderInfoIds - * @return - */ - @MapKey("orderId") - Map selectOrderInfoMap(@Param("orderInfoIds") Set orderInfoIds); - - /** * 保存或者更新根据txHash * @param leasePayRecordMessage * @return */ int updateByTxHash(@Param("leasePayRecordMessage") LeasePayRecordMessage leasePayRecordMessage,@Param("txHash") String txHash); + + /** + * 根据订单id获取队列id + * @param infoIds + * @return + */ + @MapKey("orderId") + Map getQueueIdByInfoIds(@Param("infoIds") List infoIds); + } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseProductMachineMapper.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseProductMachineMapper.java index 60b1edb..7f1104f 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseProductMachineMapper.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseProductMachineMapper.java @@ -3,10 +3,9 @@ package com.m2pool.lease.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.m2pool.common.datasource.annotation.HashRateDB; import com.m2pool.common.datasource.annotation.Pool2DB; -import com.m2pool.lease.dto.PriceDto; -import com.m2pool.lease.dto.ProductMachineDto; -import com.m2pool.lease.dto.UserMinerDto; +import com.m2pool.lease.dto.*; import com.m2pool.lease.entity.LeaseProductMachine; +import com.m2pool.lease.vo.ProductMachineVo; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -102,4 +101,47 @@ public interface LeaseProductMachineMapper extends BaseMapper getPriceList(@Param("list")List machineIds); + + + /** + * 查询绑定新钱包后,已存在的商品矿机 + * + * @param shopId 店铺id + * @return 商品列表 + */ + List getProductListForShopWalletConfig(@Param("shopId")Long shopId); + + + /** + * 获取商品对应的机器ID集合 + * + * @param productId 商品ID + * @return 机器ID集合 + */ + List getIdsForProductId(@Param("productId")Long productId); + + + /** + * 根据价格范围,功耗范围,算力范围 获取商品对应的机器 + * + * @param productMachineVo 商品参数 + * @return 机器列表 + */ + List getMachinesByPriceAndPowerAndDissipation(@Param("productMachineVo") ProductMachineVo productMachineVo,@Param("coin") String coin); + + + /** + * 批量插入机器算力数据 + * + * @param list 机器算力数据 + * @return 插入结果 + */ + int batchInsertPowers(@Param("coin")String coin,@Param("list")List list); } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseProductMachinePriceMapper.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseProductMachinePriceMapper.java new file mode 100644 index 0000000..1c557c6 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseProductMachinePriceMapper.java @@ -0,0 +1,46 @@ +package com.m2pool.lease.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.m2pool.common.datasource.annotation.Pool2DB; +import com.m2pool.lease.dto.*; +import com.m2pool.lease.entity.LeaseOrderItem; +import com.m2pool.lease.entity.LeaseProductMachine; +import com.m2pool.lease.entity.LeaseProductMachinePrice; +import com.m2pool.lease.vo.OrderInfoVo; +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; + +/** + *

+ * 商品表对应的物品机器表 Mapper 接口 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Mapper +public interface LeaseProductMachinePriceMapper extends BaseMapper { + + /** + * 获取订单总金额 按照chain 和 分组 coin + * @param orderInfoVoList + * @return + */ + @MapKey("productMachineId") + Map getOrderTotalPriceGroupByChainAndCoin(@Param("list") List orderInfoVoList); + + + /** + * 获取机器价格通过id + * @param machineIds + * @return + */ + List getMachinePriceByMachineIds(@Param("list") List machineIds); + + @MapKey("productMachineId") + Map getPriceByOrderItems(@Param("list") List orderInfoVoList); +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseProductMapper.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseProductMapper.java index c545eaa..5440586 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseProductMapper.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseProductMapper.java @@ -2,7 +2,10 @@ package com.m2pool.lease.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.m2pool.common.datasource.annotation.Pool2DB; +import com.m2pool.lease.dto.MachinePayTypeDto; +import com.m2pool.lease.dto.PayTypeDto; import com.m2pool.lease.dto.ProductDto; +import com.m2pool.lease.dto.ProductForWalletConfigDto; import com.m2pool.lease.entity.LeaseProduct; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -55,5 +58,20 @@ public interface LeaseProductMapper extends BaseMapper { * @param shopId 用于个人中心商品列表 * @return */ - List getProductListForShopAndUserCenter(@Param("coin") String coin , @Param("algorithm") String algorithm,@Param("shopId") Long shopId); + List getProductListForShopAndUserCenter(@Param("coin") String coin , @Param("algorithm") String algorithm,@Param("shopId") Long shopId); + + /** + * 获取支持的支付方式 + * @param shopId + * @return + */ + List getSupportPayType(@Param("shopId")Long shopId); + + + /** + * 获取商品列表(用于钱包配置) + * @param shopId + * @return + */ + List getProductListForShopWalletConfig(@Param("shopId")Long shopId); } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseShopConfigMapper.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseShopConfigMapper.java index 4b7d5fd..9cd4f97 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseShopConfigMapper.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseShopConfigMapper.java @@ -39,4 +39,11 @@ public interface LeaseShopConfigMapper extends BaseMapper { */ List selectShopConfigByShopIdAndSymbolAndChain(@Param("list") List list); + /** + * 获取店铺支持的支付方式 + * @param shopIds + * @return + */ + List getPayType(@Param("list") List shopIds); + } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseShopMapper.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseShopMapper.java index 71d232e..2f2d951 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseShopMapper.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseShopMapper.java @@ -1,17 +1,20 @@ package com.m2pool.lease.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.m2pool.lease.dto.ChainAndCoinDto; import com.m2pool.lease.dto.PayConfigDto; import com.m2pool.lease.entity.LeaseProductMachine; import com.m2pool.lease.entity.LeaseShop; import com.m2pool.lease.entity.LeaseShopConfig; import com.m2pool.lease.vo.OrderInfoVo; import com.m2pool.lease.vo.OrderItemVo; +import org.apache.ibatis.annotations.MapKey; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -27,12 +30,10 @@ public interface LeaseShopMapper extends BaseMapper { /** * 获取买家自定义的支付地址和支付币种和链 - * @param shopIds - * @param coin - * @param chain + * @param chainAndCoinSet * @return */ - List getPayAddressAndPayCoin(@Param("shopIds") Set shopIds,@Param("coin") String coin,@Param("chain") String chain); + List getPayAddressAndPayCoin(@Param("chainAndCoinSet") Set chainAndCoinSet); /** @@ -49,4 +50,20 @@ public interface LeaseShopMapper extends BaseMapper { * @return */ List getShopWalletInfoList(@Param("shopIds") List shopIds); + + + /** + * 根据商品id集合获取店铺id集合 + * @param productIds + * @return + */ + List getShopIdsByProductIds(@Param("productIds") List productIds); + + /** + * 根据店铺id集合获取店铺名称 + * @param shopIds + * @return + */ + @MapKey("id") + Map getShopNameMapByIds(@Param("shopIds") List shopIds); } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseShoppingCartInfoMapper.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseShoppingCartInfoMapper.java index ec7842e..9e95276 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseShoppingCartInfoMapper.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseShoppingCartInfoMapper.java @@ -24,7 +24,7 @@ public interface LeaseShoppingCartInfoMapper extends BaseMapper getCartInfoList(@Param("cartId") Long cartId); + List getProductAndMachineIds(@Param("cartId") Long cartId); diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseUserWalletDataMapper.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseUserWalletDataMapper.java index 8c02bc2..3bc4225 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseUserWalletDataMapper.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseUserWalletDataMapper.java @@ -1,6 +1,7 @@ package com.m2pool.lease.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.m2pool.lease.dto.ChainAndCoinDto; import com.m2pool.lease.dto.UserWalletDataDto; import com.m2pool.lease.entity.LeaseUserWalletData; import org.apache.ibatis.annotations.Mapper; @@ -8,6 +9,7 @@ import org.apache.ibatis.annotations.Param; import java.math.BigDecimal; import java.util.List; +import java.util.Set; @Mapper public interface LeaseUserWalletDataMapper extends BaseMapper { @@ -40,4 +42,11 @@ public interface LeaseUserWalletDataMapper extends BaseMapper getWalletForBalanceIsZero(@Param("list") List addressList); + + /** + * 根据链和币种查询钱包信息 + * @param chainAndCoinSet 链和币种 + * @return 钱包信息 + */ + List selectWalletByChainAndCoinAndUsername(@Param("list") Set chainAndCoinSet,@Param("username") String username); } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/MessageReceiver.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/MessageReceiver.java index 71ebddf..382dc5e 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/MessageReceiver.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/MessageReceiver.java @@ -9,6 +9,7 @@ import com.m2pool.lease.entity.*; import com.m2pool.lease.exception.PayRechargeException; import com.m2pool.lease.mapper.*; import com.m2pool.lease.mq.message.*; +import com.m2pool.lease.service.LeaseOrderItemService; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.messaging.handler.annotation.Payload; @@ -18,6 +19,8 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; @@ -36,6 +39,10 @@ public class MessageReceiver { private LeasePayRecordMessageMapper leasePayRecordMessageMapper; @Resource private LeaseAutoAddressMapper leaseAutoAddressMapper; + @Resource + private LeaseOrderItemMapper leaseOrderItemMapper; + @Resource + private LeaseOrderItemService leaseOrderItemService; @Resource private RabbitTemplate rabbitTemplate; @@ -85,53 +92,68 @@ public class MessageReceiver { @Transactional(rollbackFor = Exception.class) public void listenerPayBalanceStatusQueueMessage(@Payload RabbitmqPayAutoReturnMessage payAutoReturnMessage) { System.out.println("支付消费者"+JSONUtil.toJsonPrettyStr(payAutoReturnMessage)); - //查找到数据库对应的充值记录 - List leasePayRecordMessages = leasePayRecordMessageMapper. - selectList(new LambdaQueryWrapper() + //查找到数据库对应的支付记录 + List leasePayRecordMessages = leasePayRecordMessageMapper.selectList(new LambdaQueryWrapper() .eq(LeasePayRecordMessage::getQueueId, payAutoReturnMessage.getQueue_id())); - Map collect = leasePayRecordMessages.stream() - .collect(Collectors.toMap(LeasePayRecordMessage::getOrderId, Function.identity())); + Map> recordMap = leasePayRecordMessages.stream() + .collect(Collectors.groupingBy(item -> item.getToAddress() + "-" + item.getToChain())); //买家钱包 - List transactions = payAutoReturnMessage.getTransactions(); - RabbitmqPayAutoReturnInfoMessage rabbitmqPayAutoReturnInfoMessage = transactions.get(0); + Map transactions = payAutoReturnMessage.getTransactions(); + LeasePayRecordMessage leasePayRecordMessage1 = leasePayRecordMessages.get(0); LeaseUserWalletData buyer = leaseUserWalletDataMapper.selectOne(new LambdaQueryWrapper() - .eq(LeaseUserWalletData::getFromAddress,rabbitmqPayAutoReturnInfoMessage.getFrom_address()) - .eq(LeaseUserWalletData::getFromChain, rabbitmqPayAutoReturnInfoMessage.getChain()) - .eq(LeaseUserWalletData::getFromSymbol, rabbitmqPayAutoReturnInfoMessage.getSymbol()) + .eq(LeaseUserWalletData::getFromAddress,leasePayRecordMessage1.getFromAddress()) + .eq(LeaseUserWalletData::getFromChain, leasePayRecordMessage1.getFromChain()) + .eq(LeaseUserWalletData::getFromSymbol, leasePayRecordMessage1.getFromSymbol()) .eq(LeaseUserWalletData::getDel, false) ); //获取初始余额和冻结余额 BigDecimal initBalance = buyer.getBalance(); BigDecimal initBlockBalance = buyer.getBlockedBalance(); + //支付成功修改order_item表实际支付金额 + transactions.forEach((key,transaction) -> { + String key1 = transaction.getTo_address() + "-" + payAutoReturnMessage.getChain(); + List leasePayRecordMessageList = recordMap.get(key1); + if (leasePayRecordMessageList != null){ + for (LeasePayRecordMessage leasePayRecordMessage : leasePayRecordMessageList) { + BigDecimal balance = buyer.getBalance().subtract(transaction.getAmount()); + BigDecimal blockBalance = buyer.getBlockedBalance().subtract(leasePayRecordMessage.getBlockAmount()) + .subtract(leasePayRecordMessage.getNeedAmount()); - transactions.forEach(transaction -> { - LeasePayRecordMessage leasePayRecordMessage = collect.get(transaction.getOrder_id()); + leasePayRecordMessage.setUpdateTime(LocalDateTime.now()); + leasePayRecordMessage.setBlockHeight(transaction.getBlock_height()); + leasePayRecordMessage.setRealAmount(transaction.getAmount()); + //当天已存在支付的信息 + leasePayRecordMessage.setStatus(transaction.getStatus()); + leasePayRecordMessage.setTxHash(transaction.getTx_hash()); + List needUpdateOrderItem = leaseOrderItemMapper.getNeedUpdateOrderItem(Long.valueOf(leasePayRecordMessage.getOrderId())); + if(transaction.getStatus() == 1){ + //支付成功 买家 钱包总余额 + 冻结余额 减少 卖家 钱包总余额增加 + buyer.setBalance(balance); + buyer.setBlockedBalance(blockBalance); + needUpdateOrderItem = needUpdateOrderItem.stream().peek(item ->{ + item.setAlreadyPayRealAmount(item.getAlreadyPayRealAmount().add(item.getSettlePayRealAmount())); + item.setSettlePayRealAmount(BigDecimal.ZERO); + }).collect(Collectors.toList()); + } + if (transaction.getStatus() == 0){ + buyer.setBlockedBalance(blockBalance); + needUpdateOrderItem = needUpdateOrderItem.stream().peek(item ->{ + item.setSettlePayRealAmount(BigDecimal.ZERO); + }).collect(Collectors.toList()); + } + //修改支付记录状态 + System.out.println("支付成功1"+JSONUtil.toJsonPrettyStr(leasePayRecordMessage)); + int i = leasePayRecordMessageMapper.updateById(leasePayRecordMessage); + //支付成功修改order_item表实际支付金额 + System.out.println("支付成功2"+JSONUtil.toJsonPrettyStr(needUpdateOrderItem)); + boolean b = leaseOrderItemService.updateBatchById(needUpdateOrderItem); - if (leasePayRecordMessage != null){ - BigDecimal balance = buyer.getBalance().subtract(transaction.getAmount()); - BigDecimal blockBalance = buyer.getBlockedBalance().subtract(leasePayRecordMessage.getBlockAmount()); + System.out.println("支付成功修改order_item表实际支付金额"+ b +"----"+ i); + if (i < 1 || !b){ + throw new PayRechargeException("支付失败,该支付记录已修改,消息重试!!!"); + } + } - leasePayRecordMessage.setUpdateTime(LocalDateTime.now()); - leasePayRecordMessage.setBlockHeight(transaction.getBlock_height()); - leasePayRecordMessage.setRealAmount(transaction.getAmount()); - //当天已存在支付的信息 - leasePayRecordMessage.setStatus(transaction.getStatus()); - leasePayRecordMessage.setTxHash(transaction.getTx_hash()); - if(transaction.getStatus() == 1){ - //支付成功 买家 钱包总余额 + 冻结余额 减少 卖家 钱包总余额增加 - buyer.setBalance(balance); - buyer.setBlockedBalance(blockBalance); - } - if (transaction.getStatus() == 0){ - buyer.setBlockedBalance(blockBalance); - } - //修改支付记录状态 - //int i = leasePayRecordMessageMapper.updateByTxHash(leasePayRecordMessage,transaction.getTx_hash()); - System.out.println("支付成功"+JSONUtil.toJsonPrettyStr(leasePayRecordMessage) + transaction.getTx_hash()); - int i = leasePayRecordMessageMapper.updateById(leasePayRecordMessage); - if (i < 1){ - throw new PayRechargeException("支付失败,该支付记录已修改,消息重试!!!"); - } } }); @@ -156,7 +178,6 @@ public class MessageReceiver { @Transactional(rollbackFor = Exception.class) public void listenerPayRechargeStatusQueueMessage(@Payload RabbitmqPayRechargeReturnMessage payRechargeReturnMessage) { System.out.println("充值消费者---"+JSONUtil.toJsonPrettyStr(payRechargeReturnMessage)); - //获取到需要操作的钱包 List leaseUserWalletDataList = leaseUserWalletDataMapper.selectList(new LambdaQueryWrapper() .eq(LeaseUserWalletData::getFromAddress, payRechargeReturnMessage.getAddress()) @@ -195,6 +216,8 @@ public class MessageReceiver { LeasePayRechargeMessage build = LeasePayRechargeMessage.builder() .queueId(payRechargeReturnMessage.getQueue_id()) .chain(payRechargeReturnMessage.getChain()) + .blockHeight(payRechargeReturnMessage.getBlock_height()) + .fromAddress(payRechargeReturnMessage.getFromAddress()) .symbol(payRechargeReturnMessage.getSymbol()) .amount(payRechargeReturnMessage.getAmount()) .address(payRechargeReturnMessage.getAddress()) @@ -279,6 +302,7 @@ public class MessageReceiver { .id(leasePayWithdrawMessage.getId()) .amount(payWithdrawReturnMessage.getAmount().add(payWithdrawReturnMessage.getFee())) .status(payWithdrawReturnMessage.getStatus()) + .blockHeight(payWithdrawReturnMessage.getBlock_height()) .txHash(payWithdrawReturnMessage.getTx_hash()) .build()); } @@ -385,33 +409,34 @@ public class MessageReceiver { //测试 开发环境 支付回调测试 - //@RabbitListener(queues = RabbitmqConstant.PAY_AUTO_QUEUE,containerFactory ="rabbitListenerContainerFactory") - //@Transactional(rollbackFor = Exception.class) - //public void listenerPayBalanceStatusQueueMessage(@Payload RabbitmqPayAutoMessage payAutoReturnMessage) { - // //消费消息 - // System.out.println("自动支付功能queueId"+payAutoReturnMessage.getQueue_id()); - // List collect = payAutoReturnMessage.getTransactions().stream() - // .map(transaction -> RabbitmqPayAutoReturnInfoMessage.builder() - // .order_id(transaction.getOrder_id()) - // .from_address(payAutoReturnMessage.getFrom_address()) - // .to_address(transaction.getTo_address()) - // .chain(payAutoReturnMessage.getChain()) - // .symbol(payAutoReturnMessage.getSymbol()) - // .amount(transaction.getAmount()) - // .tx_hash(payAutoReturnMessage.getQueue_id()+"第一笔") - // .block_height(10000L) - // .status(1) - // .build()).collect(Collectors.toList()); - // - // RabbitmqPayAutoReturnMessage rabbitmqPayAutoReturnMessage = RabbitmqPayAutoReturnMessage.builder() - // .queue_id(payAutoReturnMessage.getQueue_id()) - // .pay_status(1) - // .fromAddress(payAutoReturnMessage.getFrom_address()) - // .transactions(collect) - // .build(); - // - // rabbitTemplate.convertAndSend(RabbitmqConstant.PAY_AUTO_RETURN_QUEUE,rabbitmqPayAutoReturnMessage); - //} + @RabbitListener(queues = RabbitmqConstant.PAY_AUTO_QUEUE,containerFactory ="rabbitListenerContainerFactory") + @Transactional(rollbackFor = Exception.class) + public void listenerPayBalanceStatusQueueMessage(@Payload RabbitmqPayAutoMessage payAutoReturnMessage) { + //消费消息 + System.out.println("自动支付功能queueId"+payAutoReturnMessage.getQueue_id()); + Map transactions = payAutoReturnMessage.getTransactions(); + Map collect = new HashMap<>(); + transactions.forEach((k, transaction) -> { + collect.put(k,RabbitmqPayAutoReturnInfoMessage.builder() + .to_address(transaction.getTo_address()) + .amount(transaction.getAmount()) + .tx_hash(payAutoReturnMessage.getQueue_id()+"第一笔") + .block_height(10000L) + .status(1) + .build()); + }); + + RabbitmqPayAutoReturnMessage rabbitmqPayAutoReturnMessage = RabbitmqPayAutoReturnMessage.builder() + .queue_id(payAutoReturnMessage.getQueue_id()) + .from_address(payAutoReturnMessage.getFrom_address()) + .pay_status(1) + .chain(payAutoReturnMessage.getChain()) + .symbol(payAutoReturnMessage.getSymbol()) + .transactions(collect) + .build(); + + rabbitTemplate.convertAndSend(RabbitmqConstant.PAY_AUTO_RETURN_QUEUE,rabbitmqPayAutoReturnMessage); + } ////测试 开发环境 充值测试 //@RabbitListener(queues = RabbitmqConstant.PAY_RECHARGE_QUEUE,containerFactory ="rabbitListenerContainerFactory") diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayAutoInfoMessage.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayAutoInfoMessage.java index 62ef07d..8b9e33e 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayAutoInfoMessage.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayAutoInfoMessage.java @@ -18,6 +18,11 @@ import java.math.BigDecimal; @AllArgsConstructor public class RabbitmqPayAutoInfoMessage { + /** + * 订单号(该字段不再传递 一个fromAddress 可以对应多个订单) + */ + private String order_id; + /** * 卖家充值地址 */ @@ -28,12 +33,21 @@ public class RabbitmqPayAutoInfoMessage { */ private BigDecimal amount; + /** - * 订单号 + * 手续费 */ - private String order_id; + private BigDecimal fee; + /** + * 交易ID + */ + private String tx_hash; + /** + * 块高 + */ + private Long block_height; //下面五个不需要传输,只存数据库 @@ -46,6 +60,7 @@ public class RabbitmqPayAutoInfoMessage { * 实际应支付金额 */ private BigDecimal needAmount; + /** * 店铺ID */ @@ -56,5 +71,4 @@ public class RabbitmqPayAutoInfoMessage { */ private String userId; - private BigDecimal fee; } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayAutoMessage.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayAutoMessage.java index 40ac0da..158f26c 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayAutoMessage.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayAutoMessage.java @@ -44,21 +44,24 @@ public class RabbitmqPayAutoMessage { */ private BigDecimal total_amount; + /** + * 订单总手续费 + */ + private BigDecimal total_fee; + /** * 时间戳 */ private Long timestamp; + /** * 签名 时间戳+m2pool */ private String sign; - - - private BigDecimal totalFee; /** * 收款方信息 */ - private List transactions; + private Map transactions; } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayAutoReturnInfoMessage.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayAutoReturnInfoMessage.java index f111027..60caf1e 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayAutoReturnInfoMessage.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayAutoReturnInfoMessage.java @@ -24,31 +24,22 @@ public class RabbitmqPayAutoReturnInfoMessage { private String order_id; - - /** - * 买家 - */ - private String from_address; - /** * 卖家 */ private String to_address; - /** - * 链名称 - */ - private String chain; - /** - * 币种 - */ - private String symbol; /** * 支付金额 */ private BigDecimal amount; + /** + * 手续费 + */ + private BigDecimal fee; + /** * 支付结果 */ @@ -59,8 +50,15 @@ public class RabbitmqPayAutoReturnInfoMessage { */ private String tx_hash; + + /** * 块高 */ private Long block_height; + + + + + } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayAutoReturnMessage.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayAutoReturnMessage.java index 1ce0df9..1ca1e36 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayAutoReturnMessage.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayAutoReturnMessage.java @@ -9,6 +9,7 @@ import lombok.NoArgsConstructor; import java.io.Serializable; import java.math.BigDecimal; import java.util.List; +import java.util.Map; /** * @Description rabbitmq 支付 消费者 @@ -34,10 +35,19 @@ public class RabbitmqPayAutoReturnMessage{ /** * 买家支付地址 */ - private String fromAddress; + private String from_address; + /** + * 链名称 + */ + private String chain; + + /** + * 币种 + */ + private String symbol; /** * 收款方信息 */ - private List transactions; + private Map transactions; } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayRechargeMessage.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayRechargeMessage.java index d8d45be..576f01b 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayRechargeMessage.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayRechargeMessage.java @@ -16,13 +16,14 @@ import lombok.NoArgsConstructor; @AllArgsConstructor public class RabbitmqPayRechargeMessage { + /** + * 交易id + */ + private String queue_id; /** * 链名称 */ private String chain; - - private String queue_id; - /** * 币种 */ diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayRechargeReturnMessage.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayRechargeReturnMessage.java index 995c1b6..da4899a 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayRechargeReturnMessage.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayRechargeReturnMessage.java @@ -23,11 +23,18 @@ public class RabbitmqPayRechargeReturnMessage { private String queue_id; + + /** * 充值地址 */ private String address; + /** + * 来源地址(用户自己的钱包) + */ + private String fromAddress; + /** * 充值是否成功 */ @@ -53,4 +60,9 @@ public class RabbitmqPayRechargeReturnMessage { */ private String tx_hash; + /** + * 区块高度 + */ + private Long block_height; + } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayWithdrawMessage.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayWithdrawMessage.java index 874b256..a09093f 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayWithdrawMessage.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayWithdrawMessage.java @@ -38,6 +38,11 @@ public class RabbitmqPayWithdrawMessage { */ private BigDecimal amount; + /** + * 手续费 + */ + private BigDecimal fee; + /** * 链名称 @@ -60,9 +65,6 @@ public class RabbitmqPayWithdrawMessage { */ private String sign; - /** - * 手续费 - */ - private BigDecimal fee; + } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayWithdrawReturnMessage.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayWithdrawReturnMessage.java index 8668c0b..44df073 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayWithdrawReturnMessage.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mq/message/RabbitmqPayWithdrawReturnMessage.java @@ -22,6 +22,16 @@ public class RabbitmqPayWithdrawReturnMessage { */ private String queue_id; + /** + * 链名称 + */ + private String chain; + + /** + * 币种 + */ + private String symbol; + /** * 提现结果 @@ -34,25 +44,29 @@ public class RabbitmqPayWithdrawReturnMessage { */ private BigDecimal amount; - - /** - * 链名称 - */ - private String chain; - - /** - * 币种 - */ - private String symbol; - - /** - * 交易ID - */ - private String tx_hash; - /** * 手续费 */ private BigDecimal fee; + + /** + * 交易hash + */ + private String tx_hash; + + /** + * 块高 + */ + private Long block_height; + + ///** + // * 来源地址 + // */ + //private String from_address; + // + ///** + // * 收款地址 + // */ + //private String to_address; } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseProductMachinePriceService.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseProductMachinePriceService.java new file mode 100644 index 0000000..581ec30 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseProductMachinePriceService.java @@ -0,0 +1,17 @@ +package com.m2pool.lease.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.m2pool.lease.entity.LeaseProductMachinePrice; + +/** + *

+ * 商品表对应的物品机器表 服务类 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +public interface LeaseProductMachinePriceService extends IService { + + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseProductService.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseProductService.java index 1152d66..56f7938 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseProductService.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseProductService.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.m2pool.lease.dto.*; import com.m2pool.lease.entity.LeaseProduct; import com.m2pool.lease.vo.BaseVo; +import com.m2pool.lease.vo.ProductMachineVo; import com.m2pool.lease.vo.ProductPageVo; import com.m2pool.lease.vo.ProductURDVo; import org.springframework.web.bind.annotation.RequestBody; @@ -41,8 +42,14 @@ public interface LeaseProductService extends IService { * @param productId 商品 ID * @return Result 封装后的商品 DTO */ - Result getProductMachineInfo(Long productId); + PageResult getProductMachineInfo(ProductMachineVo productMachineVo); + + /** + * 单个商品矿机列表页面---获取支付方式 + * @return + */ + Result> getPayTypes(); /** * 新增商品 * @@ -66,4 +73,24 @@ public interface LeaseProductService extends IService { * @return */ Result deleteProduct(Long id); + + /** + * 查询用户店铺支持的支付方式 + * @return + */ + Result> getSupportPayType(); + + + /** + * 获取商品列表用于店铺钱包配置 + * @return + */ + Result> getProductListForShopWalletConfig(); + + + /** + * 修改商品列表用于店铺钱包配置 + * @return + */ + Result updateProductListForShopWalletConfig(ProductMachineForWalletConfigVo productMachineForWalletConfigVo); } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseShoppingCartService.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseShoppingCartService.java index f0d5b35..54287fd 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseShoppingCartService.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseShoppingCartService.java @@ -1,10 +1,9 @@ package com.m2pool.lease.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.m2pool.lease.dto.ShopCartDto; -import com.m2pool.lease.dto.ShoppingCartInfoDto; import com.m2pool.lease.dto.PageResult; import com.m2pool.lease.dto.Result; +import com.m2pool.lease.dto.ShopCartDto; import com.m2pool.lease.entity.LeaseShoppingCart; import com.m2pool.lease.vo.BaseVo; import com.m2pool.lease.vo.PageVo; diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseOrderInfoServiceImpl.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseOrderInfoServiceImpl.java index 0b2e33c..00be5ae 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseOrderInfoServiceImpl.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseOrderInfoServiceImpl.java @@ -10,6 +10,7 @@ import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.m2pool.common.redis.service.RedisService; import com.m2pool.common.security.utils.SecurityUtils; +import com.m2pool.lease.constant.CoinCharge; import com.m2pool.lease.constant.RedisKey; import com.m2pool.lease.dto.*; import com.m2pool.lease.entity.*; @@ -71,15 +72,6 @@ public class LeaseOrderInfoServiceImpl extends ServiceImpl orderInfoVoList,List machinesList){ - Map machineListMap = machinesList.stream() - .collect(Collectors.toMap(LeaseProductMachine::getId, Function.identity())); - return orderInfoVoList.stream() - .map(orderInfoVo -> { - LeaseProductMachine machine = machineListMap.get(orderInfoVo.getMachineId()); - return (machine != null) ? - machine.getPrice().multiply(BigDecimal.valueOf(orderInfoVo.getLeaseTime())) : - BigDecimal.ZERO; - }) - .reduce(BigDecimal.ZERO, BigDecimal::add); - } + @Resource + private LeaseOrderFeeMapper leaseOrderFeeMapper; - /** - * 修改订单支付地址,目前测试环境适用于自营(后续可能删除) - * @param shopConfigMap - */ - public void updatePayAddressForSelf( Map shopConfigMap){ - List leaseShopAddressConfigs = leaseShopAddressConfigMapper.selectList( - new LambdaQueryWrapper() - .eq(LeaseShopAddressConfig::getUserId, SecurityUtils.getUsername())); - Map shopAddressConfigMap = leaseShopAddressConfigs.stream().collect(Collectors.toMap(LeaseShopAddressConfig::getShopId, Function.identity())); - for (Long shopId : shopConfigMap.keySet()) { - if (!shopAddressConfigMap.containsKey(shopId)) { - LeaseAutoAddress oneStatusIsNoUse = leaseAutoAddressMapper.getOneStatusIsNoUse(); - if (oneStatusIsNoUse == null) { - throw new OrderException("订单生成失败,该商家可用的地址已使用完"); - } - String address = oneStatusIsNoUse.getAddress(); - String qrcode = QrCodeUtils.creatRrCode(address,200,200); - LeaseShopAddressConfig build = LeaseShopAddressConfig.builder() - .address(address) - .userId(SecurityUtils.getUsername()) - .shopId(shopId) - .qrcode(qrcode) - .build(); - leaseShopAddressConfigMapper.insert(build); - LeaseShopConfig leaseShopConfig = shopConfigMap.get(shopId); - leaseShopConfig.setQrcode(qrcode); - leaseShopConfig.setPayAddress(address); - } else { - LeaseShopAddressConfig leaseShopAddressConfig = shopAddressConfigMap.get(shopId); - LeaseShopConfig leaseShopConfig = shopConfigMap.get(shopId); - leaseShopConfig.setQrcode(leaseShopAddressConfig.getQrcode()); - leaseShopConfig.setPayAddress(leaseShopAddressConfig.getAddress()); - } - } - } - - /** - * 获取本次订单需总支付金额 - * - * @param leaseOrderItems - * @return - */ - public BigDecimal createPaymentOrders(List leaseOrderItems,Map shopConfigMap,LocalDateTime now,LeaseOrderInfo build){ - //按店铺id分组 - Map> shopMap = leaseOrderItems.stream().collect(Collectors.groupingBy(LeaseOrderItem::getShopId)); - List paymentRecordDTOs = new ArrayList<>(); - List paymentRecords = shopMap.values().stream() - .map(items -> { - LeaseOrderItem firstItem = items.get(0); - LeaseShopConfig leaseShopConfig = shopConfigMap.get(firstItem.getShopId()); - BigDecimal totalAmount = BigDecimal.ZERO; - for (LeaseOrderItem item : items) { - totalAmount = totalAmount.add(item.getPrice().multiply(BigDecimal.valueOf(item.getLeaseTime()))); - } - Long orderId = build.getId(); - Long productId = firstItem.getProductId(); - String payCoin = firstItem.getPayCoin(); - String address = firstItem.getAddress(); - - - paymentRecordDTOs.add(PaymentRecordDto.builder() - .payCoin(payCoin) - .amount(totalAmount) - .payAddress(address) - .img(leaseShopConfig.getQrcode()) - .build()); - - return LeasePaymentRecord.builder() - .orderId(orderId) - .shopId(firstItem.getShopId()) - .productId(productId) - .payCoin(payCoin) - .amount(totalAmount) - .payAddress(address) - .qrcode(leaseShopConfig.getQrcode()) - .createTime(now) - .build(); - }) - .collect(Collectors.toList()); - - - //4.保存支付订单 - //boolean saved = leasePaymentRecordService.saveBatch(paymentRecords); - //List rabbitmqOrderMessageList = paymentRecords.stream() - // .map(paymentRecord -> RabbitmqOrderMessage.builder().orderId(paymentRecord.getOrderId()).shopId(paymentRecord.getShopId()).build()) - // .collect(Collectors.toList()); - // - ////5.发送订单mq超时消息 - //rabbitTemplate.convertAndSend( - // ORDER_OVERTIME_EXCHANGE_NAME, - // ORDER_OVERTIME_ROUTING_KEY, - // rabbitmqOrderMessageList); - - - - - //返回总支付金额 - return paymentRecordDTOs.stream().map(PaymentRecordDto::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add); - - //throw new PaymentException("添加支付订单失败"); - } @Override @DSTransactional public Result addOrders(OrderAndCodeVo orderAndCodeVo ) { - BigDecimal price = orderAndCodeVo.getPrice(); - if (price.compareTo(BigDecimal.ZERO) <= 0){ - return Result.fail("获取的支付币种币价失败"); - } - List orderInfoVoList = orderAndCodeVo.getOrderInfoVoList(); - GoogleInfo googleInfo = leaseUserMapper.getGoogleInfoByEmail(SecurityUtils.getUsername()); - //校验当前用户是否存在该币种的钱包 - LeaseUserWalletData walletData = leaseUserWalletDataMapper.selectOne(new LambdaQueryWrapper() - .eq(LeaseUserWalletData::getUserId, SecurityUtils.getUsername()) - .eq(LeaseUserWalletData::getFromChain, orderAndCodeVo.getChain()) - .eq(LeaseUserWalletData::getFromSymbol, orderAndCodeVo.getCoin()) - .eq(LeaseUserWalletData::getDel, false) - ); - if (walletData == null){ - return Result.fail("余额不足,无法下单!您还没有绑定该链和币种钱包!"); - } + String userEmail = SecurityUtils.getUsername(); + GoogleInfo googleInfo = leaseUserMapper.getGoogleInfoByEmail(userEmail); //TODO 开发环境 //if(googleInfo == null || StringUtils.isBlank(googleInfo.getSecret())){ // //未绑定定谷歌验证器 @@ -243,77 +104,138 @@ public class LeaseOrderInfoServiceImpl extends ServiceImpl orderInfoVoList = orderAndCodeVo.getOrderInfoVoList(); + //存储根据chain和coin去重后的set集合 + Set chainAndCoinSet = new HashSet<>(); + Set chainAndCoinAndShopIdSet = new HashSet<>(); + //存储相同链和币种的map集合 + Map>> chainAndCoinMap = new HashMap<>(); + Map orderTotalPriceGroupByChainAndCoin = leaseProductMachinePriceMapper.getOrderTotalPriceGroupByChainAndCoin(orderInfoVoList); + //chain + coin 钱包 对应的总价 + Map totalPriceMap = new HashMap<>(); + //其他 + Map machineMap = new HashMap<>(); LocalDateTime now = LocalDateTime.now(); List machineIds = new ArrayList<>(); - Set shopIds = new HashSet<>(); Set productIds = new HashSet<>(); - for (OrderInfoVo vo : orderInfoVoList) { + String chain = vo.getChain(); + String coin = vo.getCoin(); + String key = chain +"-"+ coin; + chainAndCoinSet.add(new ChainAndCoinDto(coin, chain)); + chainAndCoinAndShopIdSet.add(new ChainAndCoinDto(coin, chain,vo.getShopId())); + chainAndCoinMap.computeIfAbsent(chain, k -> new HashMap<>()); + Map> innerMap = chainAndCoinMap.get(chain); + innerMap.computeIfAbsent(coin, k -> new ArrayList<>()).add(vo); + // 获取对应买方本次链和币对应需要支付的总金额 + totalPriceMap.compute(key, (k, v) -> { + if (v == null) { + v = BigDecimal.ZERO; + } + LeaseProductMachinePrice priceInfo = orderTotalPriceGroupByChainAndCoin.get(vo.getMachineId()); + if (priceInfo != null) { + v = v.add(priceInfo.getPrice().multiply(BigDecimal.valueOf(vo.getLeaseTime()))); + } + return v; + }); + machineMap.put(vo.getMachineId(), vo); machineIds.add(vo.getMachineId()); - shopIds.add(vo.getShopId()); productIds.add(vo.getProductId()); } - //查询需要生成订单的矿机信息 + //获取买家需要进行支付的几个钱包 + List walletDataList = leaseUserWalletDataMapper.selectWalletByChainAndCoinAndUsername(chainAndCoinSet, userEmail); + if (walletDataList.size() != chainAndCoinSet.size()){ + return Result.fail("下单失败!订单选择的支付方式中对应钱包您还未绑定并充值!"); + } + + //删除购物车中矿机 LeaseShoppingCart leaseShoppingCart = leaseShoppingCartMapper.selectOne(new LambdaQueryWrapper() .eq(LeaseShoppingCart::getUserId, SecurityUtils.getUsername())); + int delete = leaseShoppingCartInfoMapper.delete(new LambdaUpdateWrapper() + .eq(LeaseShoppingCartInfo::getCartId, leaseShoppingCart.getId()) + .in(LeaseShoppingCartInfo::getProductMachineId, machineIds)); + if (delete < 1){ + throw new OrderException("生成订单失败,购物车中不存在矿机商品"); + } + //查找矿机详情信息 List machinesList = leaseProductMachineMapper.selectBatchIds(machineIds); for (LeaseProductMachine leaseProductMachine : machinesList) { if (leaseProductMachine.getState() == 1 || leaseProductMachine.getDel()){ throw new OrderException("生成订单失败,订单矿机中存在已下架矿机"); } } - //删除购物车中矿机 - int delete = leaseShoppingCartInfoMapper.delete(new LambdaUpdateWrapper() - .eq(LeaseShoppingCartInfo::getCartId, leaseShoppingCart.getId()).in(LeaseShoppingCartInfo::getProductMachineId, machineIds)); - if (delete < 1){ - throw new OrderException("生成订单失败,购物车中不存在该矿机商品"); + // 获取卖家店铺钱包配置 + List payAddressAndPayCoin = leaseShopMapper.getPayAddressAndPayCoin(chainAndCoinAndShopIdSet); + Map configMap = new HashMap<>(); + Map> feeMap = new HashMap<>(); + for (LeaseShopConfig leaseShopConfig : payAddressAndPayCoin) { + String key = leaseShopConfig.getChain() + "-" + leaseShopConfig.getPayCoin() +"-"+leaseShopConfig.getShopId(); + configMap.put(key, leaseShopConfig); + feeMap.computeIfAbsent(leaseShopConfig.getChain() + "-" + leaseShopConfig.getPayCoin(), k -> new HashSet<>()).add(leaseShopConfig.getPayAddress()); } - //获取本次生成订单中所有矿机的总价(单位固定usdt) - BigDecimal totalPrice = calculateOrderPrice(orderInfoVoList, machinesList); - // 获取卖家店铺钱包配置(注意:目前同时只能结算一个店铺的,这里多个防止后续改成可以结算多个) - List payAddressAndPayCoin = leaseShopMapper.getPayAddressAndPayCoin(shopIds,orderAndCodeVo.getCoin(),orderAndCodeVo.getChain()); - Map shopConfigMap = payAddressAndPayCoin.stream() - .collect(Collectors.toMap(LeaseShopConfig::getShopId, Function.identity())); - - //订单主信息新增 - String userEmail = SecurityUtils.getUsername(); - String orderNumber = UuidGeneratorUtil.generateUuidWithoutHyphen(); - LeaseOrderInfo build = LeaseOrderInfo.builder() - .orderNumber(orderNumber) - .userId(userEmail) - .totalPrice(totalPrice) - .createTime(now) - .build(); - boolean save = save(build); + //根据买方钱包的 chain和coin 设置要生成的订单个数 以及对应的订单总价 + List leaseOrderInfoList = new ArrayList<>(); + Map totalFeeMap = new HashMap<>(); + Map walletDataMap = new HashMap<>(); + for (LeaseUserWalletData leaseUserWalletData : walletDataList) { + String key = leaseUserWalletData.getFromChain() + "-" + leaseUserWalletData.getFromSymbol(); + BigDecimal totalAmount = totalPriceMap.get(key); + String orderNumber = UuidGeneratorUtil.generateUuidWithoutHyphen(); + Set toAddressList = feeMap.get(key); + int size = toAddressList.size(); + BigDecimal charge = CoinCharge.getChargeByChainAndCoin(leaseUserWalletData.getFromChain(), leaseUserWalletData.getFromSymbol()); + BigDecimal fee = charge.multiply(BigDecimal.valueOf(size)); + leaseOrderInfoList.add(LeaseOrderInfo.builder() + .chainAndCoinKey(key) + .orderNumber(orderNumber) + .userId(userEmail) + .fee(fee) + .totalPrice(totalAmount) + .createTime(now) + .build()); + totalFeeMap.put(key, fee); + walletDataMap.put(key, leaseUserWalletData); + } + boolean save = saveBatch(leaseOrderInfoList); if (!save){ - throw new OrderException("订单生成失败"); + return Result.fail("生成订单失败"); } - Map machineMap = orderInfoVoList.stream().collect(Collectors.toMap(OrderInfoVo::getMachineId, Function.identity())); + for (LeaseOrderInfo leaseOrderInfo : leaseOrderInfoList) { + + } + Map orderInfoMap = leaseOrderInfoList.stream() + .collect(Collectors.toMap(LeaseOrderInfo::getChainAndCoinKey, Function.identity())); + + //订单详情表业务 List leaseProducts = leaseProductMapper.selectBatchIds(productIds); Map productMap = leaseProducts.stream().collect(Collectors.toMap(LeaseProduct::getId, Function.identity())); List leaseOrderItems = new ArrayList<>(); - //创建订单明细 for (LeaseProductMachine leaseProductMachine : machinesList) { - LeaseShopConfig leaseShopConfig = shopConfigMap.get(leaseProductMachine.getShopId()); + Long machineId = leaseProductMachine.getId(); + OrderInfoVo orderInfoVo = machineMap.get(machineId); + String chain = orderInfoVo.getChain(); + String coin = orderInfoVo.getCoin(); + Long shopId = orderInfoVo.getShopId(); + LeaseProductMachinePrice leaseProductMachinePrice = orderTotalPriceGroupByChainAndCoin.get(machineId); + LeaseShopConfig leaseShopConfig = configMap.get(chain + "-" +coin +"-"+ shopId); + LeaseUserWalletData walletInfo = walletDataMap.get(chain + "-" + coin); if (leaseShopConfig == null){ - throw new OrderException("卖方未绑定钱包"); + throw new OrderException("选择的卖家收款钱包不存在,请重行选择支付方法"); } - OrderInfoVo orderInfoVo = machineMap.get(leaseProductMachine.getId()); + LeaseOrderInfo leaseOrderInfo = orderInfoMap.get(chain + "-" + coin); + //设置销售数量 LeaseProduct leaseProduct = productMap.get(leaseProductMachine.getProductId()); leaseProduct.setSaleNumber(leaseProduct.getSaleNumber() + 1); leaseOrderItems.add( LeaseOrderItem.builder() .userId(userEmail) - .orderId(build.getId()) + .orderId(leaseOrderInfo.getId()) .productId(leaseProductMachine.getProductId()) .productMachineId(leaseProductMachine.getId()) - //这里需要实时计算支付币种的个数 - .price(leaseProductMachine.getPrice().divide(orderAndCodeVo.getPrice(),6, RoundingMode.HALF_UP)) + .price(leaseProductMachinePrice.getPrice()) .user(leaseProductMachine.getUser()) .miner(leaseProductMachine.getMiner()) + //TODO 这里的理论收益是商家新增机器时通过实时算力计算得来 .theoryIncome(leaseProductMachine.getTheoryIncome().multiply(BigDecimal.valueOf(orderInfoVo.getLeaseTime()))) .coin(leaseProduct.getCoin()) .leaseTime(orderInfoVo.getLeaseTime()) @@ -324,9 +246,9 @@ public class LeaseOrderInfoServiceImpl extends ServiceImpl walletDataMap,Map totalPriceMap,Map feeMap){ + + totalPriceMap.forEach((chainAndCoinKey, totalAmount) -> { + LeaseUserWalletData walletData = walletDataMap.get(chainAndCoinKey); + BigDecimal fee = feeMap.get(chainAndCoinKey); + if (walletData == null){ + throw new OrderException("下单失败,买家不存在"+chainAndCoinKey+"类型钱包"); + } + if (walletData.getBalance().subtract(walletData.getBlockedBalance()).compareTo(totalAmount) < 0){ + throw new OrderException("下单失败,买家"+chainAndCoinKey+"钱包余额不足,缺少" + (totalAmount.subtract(walletData.getBalance().subtract(walletData.getBlockedBalance()))) +"满足支付需求"); + } + walletData.setBlockedBalance(walletData.getBlockedBalance().add(totalAmount).add(fee)); + leaseUserWalletDataMapper.updateById(walletData); + }); + + } + + ///** + // * 获取本次订单需总支付金额 + // * + // * @param leaseOrderItems + // * @return + // */ + //public BigDecimal createPaymentOrders(List leaseOrderItems,Map shopConfigMap,LocalDateTime now,LeaseOrderInfo build){ + // //按店铺id分组 + // Map> shopMap = leaseOrderItems.stream().collect(Collectors.groupingBy(LeaseOrderItem::getShopId)); + // List paymentRecordDTOs = new ArrayList<>(); + // List paymentRecords = shopMap.values().stream() + // .map(items -> { + // LeaseOrderItem firstItem = items.get(0); + // LeaseShopConfig leaseShopConfig = shopConfigMap.get(firstItem.getShopId()); + // BigDecimal totalAmount = BigDecimal.ZERO; + // for (LeaseOrderItem item : items) { + // totalAmount = totalAmount.add(item.getPrice().multiply(BigDecimal.valueOf(item.getLeaseTime()))); + // } + // Long orderId = build.getId(); + // Long productId = firstItem.getProductId(); + // String payCoin = firstItem.getPayCoin(); + // String address = firstItem.getAddress(); + // + // + // paymentRecordDTOs.add(PaymentRecordDto.builder() + // .payCoin(payCoin) + // .amount(totalAmount) + // .payAddress(address) + // .img(leaseShopConfig.getQrcode()) + // .build()); + // + // return LeasePaymentRecord.builder() + // .orderId(orderId) + // .shopId(firstItem.getShopId()) + // .productId(productId) + // .payCoin(payCoin) + // .amount(totalAmount) + // .payAddress(address) + // .qrcode(leaseShopConfig.getQrcode()) + // .createTime(now) + // .build(); + // }) + // .collect(Collectors.toList()); + // + // + // //4.保存支付订单 + // //boolean saved = leasePaymentRecordService.saveBatch(paymentRecords); + // //List rabbitmqOrderMessageList = paymentRecords.stream() + // // .map(paymentRecord -> RabbitmqOrderMessage.builder().orderId(paymentRecord.getOrderId()).shopId(paymentRecord.getShopId()).build()) + // // .collect(Collectors.toList()); + // // + // ////5.发送订单mq超时消息 + // //rabbitTemplate.convertAndSend( + // // ORDER_OVERTIME_EXCHANGE_NAME, + // // ORDER_OVERTIME_ROUTING_KEY, + // // rabbitmqOrderMessageList); + // + // + // + // + // //返回总支付金额 + // return paymentRecordDTOs.stream().map(PaymentRecordDto::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add); + // + // //throw new PaymentException("添加支付订单失败"); + //} + + @Override public Result> buyAgain(List orderInfoVoList) { //LocalDateTime now = LocalDateTime.now(); @@ -480,47 +484,42 @@ public class LeaseOrderInfoServiceImpl extends ServiceImpl leaseOrderItems,List ordersByStatus,List ids){ - Map> collect = leaseOrderItems.stream().map(leaseOrderItem -> - OrderItemDto.builder() - .shopId(leaseOrderItem.getShopId()) - .orderId(leaseOrderItem.getOrderId()) - .productId(leaseOrderItem.getProductId()) - .productMachineId(leaseOrderItem.getProductMachineId()) - .leaseTime(leaseOrderItem.getLeaseTime()) - .address(leaseOrderItem.getAddress()) - .payCoin(leaseOrderItem.getPayCoin()) - .name(leaseOrderItem.getName()) - .price(leaseOrderItem.getPrice()) - .image(leaseOrderItem.getImage()) - .build() - ).collect(Collectors.groupingBy(OrderItemDto::getOrderId)); + Map hasPayAmountMap = new HashMap<>(); + Map hasPayRealAmountMap = new HashMap<>(); + Map> orderItemDtoMap = new HashMap<>(); + for (LeaseOrderItem leaseOrderItem : leaseOrderItems) { + orderItemDtoMap.computeIfAbsent(leaseOrderItem.getOrderId(), k -> new ArrayList<>()).add( OrderItemDto.builder() + .shopId(leaseOrderItem.getShopId()) + .orderId(leaseOrderItem.getOrderId()) + .productId(leaseOrderItem.getProductId()) + .productMachineId(leaseOrderItem.getProductMachineId()) + .leaseTime(leaseOrderItem.getLeaseTime()) + .address(leaseOrderItem.getAddress()) + .payCoin(leaseOrderItem.getPayCoin()) + .name(leaseOrderItem.getName()) + .price(leaseOrderItem.getPrice()) + .image(leaseOrderItem.getImage()) + .build()); + // 累加支付金额 + hasPayAmountMap.merge(leaseOrderItem.getOrderId(), leaseOrderItem.getAlreadyPayAmount(), BigDecimal::add); + // 累加实际支付金额 + hasPayRealAmountMap.merge(leaseOrderItem.getOrderId(), leaseOrderItem.getAlreadyPayRealAmount(), BigDecimal::add); + } - //获取订单已支付 和待支付金额 - List leasePayRecordMessages = leasePayRecordMessageMapper.selectList(new LambdaQueryWrapper().in(LeasePayRecordMessage::getOrderId, ids)); - Map collect1 = new HashMap<>(); - leasePayRecordMessages.forEach(leasePayRecordMessage -> { - HasPayTotalDto hasPayTotalDto = collect1.get(leasePayRecordMessage.getOrderId()); - if (hasPayTotalDto == null){ - collect1.put(leasePayRecordMessage.getOrderId(),HasPayTotalDto.builder() - .totalAmount(leasePayRecordMessage.getAmount()) - .totalRealAmount(leasePayRecordMessage.getRealAmount()) - .build()); - }else{ - hasPayTotalDto.setTotalAmount(hasPayTotalDto.getTotalAmount().add(leasePayRecordMessage.getAmount())); - hasPayTotalDto.setTotalRealAmount(hasPayTotalDto.getTotalRealAmount().add(leasePayRecordMessage.getRealAmount())); - collect1.put(leasePayRecordMessage.getOrderId(),hasPayTotalDto); - } - }); ordersByStatus.forEach(orderInfoDto -> { - List orderItems = collect.get(orderInfoDto.getId()); - HasPayTotalDto hasPayTotalDto = collect1.get(orderInfoDto.getId().toString()); - BigDecimal hasPayAmount = hasPayTotalDto == null ? BigDecimal.ZERO: hasPayTotalDto.getTotalAmount(); - BigDecimal hasPayRealAmount = hasPayTotalDto == null ? BigDecimal.ZERO: hasPayTotalDto.getTotalRealAmount(); - OrderItemDto orderItemDto = orderItems.get(0); + List orderItems = orderItemDtoMap.get(orderInfoDto.getId()); + BigDecimal hasPayAmount = hasPayAmountMap.get(orderInfoDto.getId()); + BigDecimal hasPayRealAmount = hasPayRealAmountMap.get(orderInfoDto.getId()); orderInfoDto.setOrderItemDtoList(orderItems); - orderInfoDto.setShopId(orderItemDto.getShopId()); + //orderInfoDto.setShopId(orderItems.get(0).getShopId()); orderInfoDto.setNoPayAmount(orderInfoDto.getTotalPrice().subtract(hasPayAmount).doubleValue()); orderInfoDto.setPayAmount(hasPayRealAmount.doubleValue()+"/"+hasPayAmount.doubleValue()); }); diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseProductMachinePriceServiceImpl.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseProductMachinePriceServiceImpl.java new file mode 100644 index 0000000..e778d16 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseProductMachinePriceServiceImpl.java @@ -0,0 +1,21 @@ +package com.m2pool.lease.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.m2pool.lease.entity.LeaseProductMachinePrice; +import com.m2pool.lease.mapper.LeaseProductMachinePriceMapper; +import com.m2pool.lease.service.LeaseProductMachinePriceService; +import org.springframework.stereotype.Service; + +/** + *

+ * 商品表对应的物品机器表 服务实现类 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Service +public class LeaseProductMachinePriceServiceImpl extends ServiceImpl implements LeaseProductMachinePriceService { + + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseProductMachineServiceImpl.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseProductMachineServiceImpl.java index d68f31f..5dfd167 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseProductMachineServiceImpl.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseProductMachineServiceImpl.java @@ -1,7 +1,9 @@ package com.m2pool.lease.service.impl; +import cn.hutool.json.JSONUtil; import com.baomidou.dynamic.datasource.annotation.DSTransactional; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.github.pagehelper.PageHelper; @@ -13,10 +15,14 @@ import com.m2pool.lease.constant.RedisKey; import com.m2pool.lease.dto.*; import com.m2pool.lease.entity.LeaseProduct; import com.m2pool.lease.entity.LeaseProductMachine; +import com.m2pool.lease.entity.LeaseProductMachinePrice; import com.m2pool.lease.mapper.LeaseNexaMachinePowerMapper; import com.m2pool.lease.mapper.LeaseProductMachineMapper; +import com.m2pool.lease.mapper.LeaseProductMachinePriceMapper; import com.m2pool.lease.mapper.LeaseProductMapper; +import com.m2pool.lease.service.LeaseProductMachinePriceService; import com.m2pool.lease.service.LeaseProductMachineService; +import com.m2pool.lease.service.LeaseProductService; import com.m2pool.lease.utils.PowerUnitUtils; import com.m2pool.lease.vo.*; import org.springframework.beans.factory.annotation.Autowired; @@ -28,8 +34,10 @@ import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; /** @@ -45,22 +53,19 @@ public class LeaseProductMachineServiceImpl extends ServiceImpl> > getUserMinersList(UserMinerVo userMinerVo) { String userId = SecurityUtils.getUsername(); - //测试 挖矿账号 + //开发环境 //userId = "Eudora.law@outlook.com"; List userMinersList = leaseProductMachineMapper.getUserMinersList(userId,userMinerVo.getCoin()); Map> collect = userMinersList.stream().collect(Collectors.groupingBy(UserMinerDto::getCoin)); @@ -90,6 +95,13 @@ public class LeaseProductMachineServiceImpl extends ServiceImpl leaseProductMachines = leaseProductMachineMapper.selectList(new LambdaQueryWrapper() .eq(LeaseProductMachine::getProductId, productForUpdateMachineVo.getId()).eq(LeaseProductMachine::getDel,false)); PageInfo pageInfo = new PageInfo<>(leaseProductMachines); + if (leaseProductMachines.isEmpty()){ + return PageResult.fail(new ArrayList<>(), "不存在租售的矿机"); + } + //获取矿机对应的币价 + List machineIds = leaseProductMachines.stream().map(LeaseProductMachine::getId).collect(Collectors.toList()); + List priceList = leaseProductMachineMapper.getPriceList(machineIds); + Map> collect = priceList.stream().collect(Collectors.groupingBy(MachinePayTypeDto::getProductMachineId)); List productUpdateMachineDtos = leaseProductMachines.stream().map(leaseProductMachine -> ProductUpdateMachineDto.builder() @@ -97,7 +109,7 @@ public class LeaseProductMachineServiceImpl extends ServiceImpl leaseProductMachines = new ArrayList<>(); List productMachineURDVos = productMachineParamsVo.getProductMachineURDVos(); + Map> payTypeMap = new HashMap<>(); + AtomicInteger index = new AtomicInteger(1); productMachineURDVos.forEach(machine -> { - leaseProductMachines.add(LeaseProductMachine.builder() + int andIncrement = index.getAndIncrement(); + leaseProductMachines.add(LeaseProductMachine.builder() + .updateCount(andIncrement) .shopId(product.getShopId()) .productId(productMachineParamsVo.getProductId()) .type(machine.getType() == null ? productMachineParamsVo.getType() : machine.getType()) .theoryPower(machine.getTheoryPower() == null ? productMachineParamsVo.getTheoryPower() : machine.getTheoryPower()) .powerDissipation(productMachineParamsVo.getPowerDissipation()) .cost(productMachineParamsVo.getCost()) - .price(machine.getPrice() == null ? productMachineParamsVo.getCost() : machine.getPrice()) + .price(BigDecimal.ZERO) .incomeRate(BigDecimal.ZERO) .maxLeaseDays(machine.getMaxLeaseDays() == null ? productMachineParamsVo.getMaxLeaseDays() : machine.getMaxLeaseDays()) .unit(machine.getUnit() == null ? productMachineParamsVo.getUnit() : machine.getUnit()) @@ -147,7 +163,15 @@ public class LeaseProductMachineServiceImpl extends ServiceImpl LeaseProductMachinePrice.builder() + .price(payType.getPrice()) + .coin(payType.getCoin()) + .chain(payType.getChain()) + .build()) + .collect(Collectors.toList())); + + }); @@ -209,11 +233,24 @@ public class LeaseProductMachineServiceImpl extends ServiceImpl= 1){ + //新增矿机 索引改为普通联合索引 + LeaseProductMachineServiceImpl service = applicationContext.getBean(LeaseProductMachineServiceImpl.class); + //TODO 修改,还是得用唯一索引 + //leaseProductMachineMapper.saveOrUpdateBatchs(collect); + boolean b = service.saveBatch(collect); + if (b){ //修改商品的价格范围 及商品下机器库存数量 updatePriceRange(product.getId()); + List list = new ArrayList<>(); + for (LeaseProductMachine leaseProductMachine : collect) { + + List leaseProductMachinePrices = payTypeMap.get(leaseProductMachine.getUpdateCount()); + list.addAll(leaseProductMachinePrices.stream() + .peek(leaseProductMachinePrice -> leaseProductMachinePrice.setProductMachineId(leaseProductMachine.getId())) + .collect(Collectors.toList())); + } + //修改机器配置 + leaseProductMachinePriceService.saveBatch(list); return Result.success("添加成功,添加矿机数:"+collect.size()); } return Result.fail("添加失败"); @@ -225,6 +262,7 @@ public class LeaseProductMachineServiceImpl extends ServiceImpl ids = new ArrayList<>(); List leaseProductMachines = new ArrayList<>(); + List list = new ArrayList<>(); productUpdateMachineVoList.forEach(machine -> { leaseProductMachines.add( LeaseProductMachine.builder() .id(machine.getId()) @@ -240,13 +278,21 @@ public class LeaseProductMachineServiceImpl extends ServiceImpl LeaseProductMachinePrice.builder() + .id(payType.getPayTypeId()) + .price(payType.getPrice()) + .chain(payType.getChain()) + .build()) + .collect(Collectors.toList())); if (machine.getState() == 1){ ids.add(machine.getId()); } }); if (!ids.isEmpty()){ List leaseProductMachines1 = leaseProductMachineMapper.selectBatchIds(ids); - long count = leaseProductMachines1.stream().filter(leaseProductMachine -> leaseProductMachine.getSaleState() == 1).count(); + long count = leaseProductMachines1.stream() + .filter(leaseProductMachine -> leaseProductMachine.getSaleState() == 1).count(); if (count >= 1){ return Result.fail("商品修改失败,部分矿机租约已存在,不能下架"); } @@ -259,6 +305,7 @@ public class LeaseProductMachineServiceImpl extends ServiceImpl getProductList(ProductPageVo productPageVo) { - LambdaQueryWrapper wrapper = new LambdaQueryWrapper().eq(LeaseProduct::getDel, false); Long shopId = 0L; - System.out.println("用户邮箱参数:"+productPageVo.getUserEmail()); //1.用户邮箱参数不为空,则表示个人中心的商品列表。这个时候能看到下架的商品 - if (productPageVo.getUserEmail() != null && !productPageVo.getUserEmail().isEmpty()){ + if (!StringUtils.isEmpty(productPageVo.getUserEmail())){ LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper() .eq(LeaseShop::getUserEmail, productPageVo.getUserEmail())); if (leaseShop != null){ shopId = leaseShop.getId(); }else{ - throw new ProductSoldOutException("不存在出售商品"); + return PageResult.fail(new ArrayList<>(), "不存在出售商品"); } } PageHelper.startPage(productPageVo.getPageNum(), productPageVo.getPageSize()); - List leaseProducts = leaseProductMapper.getProductListForShopAndUserCenter(productPageVo.getCoin(), productPageVo.getAlgorithm(), shopId); - PageInfo pageInfo = new PageInfo<>(leaseProducts); + List leaseProducts = leaseProductMapper.getProductListForShopAndUserCenter(productPageVo.getCoin(), productPageVo.getAlgorithm(), shopId); + PageInfo pageInfo = new PageInfo<>(leaseProducts); if(leaseProducts.isEmpty()){ - throw new ProductSoldOutException("不存在出售商品"); + return PageResult.fail(new ArrayList<>(), "不存在出售商品"); } - //获取商品列表 - List collect = new ArrayList<>(); - Set shopIds = new HashSet<>(); - for (LeaseProduct product : leaseProducts) { - collect.add( ProductDto.builder() - .id(product.getId()) - .name(product.getName()) - .image(product.getImage()) - .type(product.getType()) - .state(product.getState()) - .priceRange(product.getMaxPrice().equals(product.getMinPrice()) ? - product.getMaxPrice().toString() : - (product.getMinPrice().toString() +"-"+product.getMaxPrice().toString())) - .description(product.getDescription()) - .algorithm(product.getAlgorithm()) - .shopId(product.getShopId()) - .coinFullName(product.getCoinFullName()) - .saleNumber(product.getSaleNumber()) - .totalMachineNumber(product.getTotalMachineNumber()) - .coin(product.getCoin()) - .build()); - shopIds.add(product.getShopId()); + //获取店铺对应的支付方式 + List shopIds = leaseProducts.stream().map(ProductDto::getShopId).distinct().collect(Collectors.toList()); + List payType = leaseShopConfigMapper.getPayType(shopIds); + Map> payTypeMap = payType.stream().collect(Collectors.groupingBy(PayTypeDto::getShopId)); + //配置支付列表 + for (ProductDto productDto : leaseProducts) { + productDto.setPayTypes(payTypeMap.get(productDto.getShopId())); } - List leaseShops = leaseShopMapper.selectList(new LambdaQueryWrapper().eq(LeaseShop::getState, 1).in(LeaseShop::getId, shopIds)); - Map> idMapShop = leaseShops.stream().collect(Collectors.groupingBy(LeaseShop::getId)); - List result = new ArrayList<>(); - for (ProductDto productDto : collect) { - if (idMapShop.containsKey(productDto.getShopId())){ - result.add(productDto); - } - } - PageResult success = PageResult.success(result); + PageResult success = PageResult.success(leaseProducts); success.setTotal(pageInfo.getTotal()); success.setTotalPage(pageInfo.getPages()); PageHelper.clearPage(); @@ -147,30 +134,22 @@ public class LeaseProductServiceImpl extends ServiceImpl getProductMachineInfo(Long productId) { + public PageResult getProductMachineInfo(ProductMachineVo productMachineVo) { + Long productId = productMachineVo.getId(); LeaseProduct product = getById(productId); - ProductMachineInfoDto productMachineInfoDto = new ProductMachineInfoDto(); - //0.查询商品对应的收款钱包配置 List shopWalletInfo = leaseShopMapper.getShopWalletInfo(product.getShopId()); - productMachineInfoDto.setPayConfigList(shopWalletInfo); - - //1.查询商品对应处于上架状态 以及未售出的 机器集合 - List leaseProductMachines = leaseProductMachineMapper.selectList( - new LambdaQueryWrapper().eq(LeaseProductMachine::getProductId, productId) - .eq(LeaseProductMachine::getDel,false) - //.eq(LeaseProductMachine::getSaleState, 0) - .eq(LeaseProductMachine::getState, 0) - .orderByDesc(LeaseProductMachine::getSaleState) - - ); - - if (leaseProductMachines.isEmpty()){ - return Result.fail("该商品暂时没有可出售矿机"); + PayConfigDto payConfigDto = shopWalletInfo.get(0); + PageHelper.startPage(productMachineVo.getPageNum(), productMachineVo.getPageSize()); + if (StringUtils.isEmpty(productMachineVo.getChain()) && StringUtils.isEmpty(productMachineVo.getCoin())){ + productMachineVo.setChain(payConfigDto.getPayChain()); + productMachineVo.setCoin(payConfigDto.getPayCoin()); } + List productMachineDtoList = leaseProductMachineMapper.getMachinesByPriceAndPowerAndDissipation(productMachineVo, product.getCoin()); + PageInfo pageInfo = new PageInfo<>(productMachineDtoList); - //2.理论收益 = 矿机算力/全网算力 * 24h 秒数 /出块间隔秒数 * 单块奖励(redis中nexa:reward) - //查询矿机一天范围内的实际平均算力 单位为MH/S - List nexaMinersv2 = leaseProductMachineMapper.getRecentlyFiveMinutesData(leaseProductMachines, product.getCoin()); + if (productMachineDtoList.isEmpty()){ + return PageResult.fail(new ArrayList<>(),"不存在矿机"); + } //币价 单位usdt BigDecimal price = redisService.getCacheBigDecimal(RedisKey.getPiceKey(product.getCoin())) == null ? BigDecimal.ZERO : redisService.getCacheBigDecimal(RedisKey.getPiceKey(product.getCoin())); //报块奖励 @@ -178,84 +157,73 @@ public class LeaseProductServiceImpl extends ServiceImpl machineDtoMap = nexaMinersv2.stream() - .collect(Collectors.toMap( - dto -> dto.getUser() + "-" + dto.getMiner(), - dto -> dto - )); - List productMachines = leaseProductMachines.stream() - .map(leaseProductMachine -> { - String key = leaseProductMachine.getUser() + "-" + leaseProductMachine.getMiner(); - ProductMachineDto productMachineDto = machineDtoMap.get(key); + List productMachines = productMachineDtoList.stream() + .peek(productMachineDto -> { //理论收益 BigDecimal singleTheoryMachineIncome = BigDecimal.ZERO; - BigDecimal computingPower = BigDecimal.ZERO; - if (productMachineDto != null) { - // 矿机算力单位转换 + 计算单矿机平均算力(ComputingPower coin_mhs30m 平均算力) - computingPower = PowerUnitUtils.getPower(leaseProductMachine.getUnit(), - productMachineDto.getComputingPower() - .multiply(BigDecimal.valueOf(1000 * 1000)) - .divide(BigDecimal.valueOf(24 * 60 * 60 ), 2, RoundingMode.HALF_UP)); - - if (mhs == null || reward == null || price == null){ - singleTheoryMachineIncome = leaseProductMachine.getTheoryIncome(); - }else{ - //全网算力单位转换 - BigDecimal power = PowerUnitUtils.getPower(leaseProductMachine.getUnit(), mhs.multiply(BigDecimal.valueOf(1000 * 1000))); - //(理论收益 = 矿机算力/全网算力 * 24h /出块间隔秒数 * 单块奖励(redis中nexa:reward)) - singleTheoryMachineIncome = computingPower.divide( power,6, RoundingMode.HALF_UP) - .multiply(BigDecimal.valueOf(24 * 60 * 60) + productMachineDto.setAlgorithm(product.getAlgorithm()); + // 矿机算力单位转换 + 计算单矿机平均算力(ComputingPower coin_real_power 24小时总算力) + BigDecimal computingPower = PowerUnitUtils.getPower(productMachineDto.getUnit(), productMachineDto.getComputingPower().multiply(BigDecimal.valueOf(1000 * 1000)) + .divide(BigDecimal.valueOf(24 * 60 * 60),2,RoundingMode.HALF_UP)); + //全网算力单位转换 + BigDecimal power = PowerUnitUtils.getPower(productMachineDto.getUnit(), mhs.multiply(BigDecimal.valueOf(1000 * 1000))); + //(理论收益 = 矿机算力/全网算力 * 24h /出块间隔秒数 * 单块奖励(redis中nexa:reward)) + singleTheoryMachineIncome = computingPower.divide( power,6, RoundingMode.HALF_UP) + .multiply(BigDecimal.valueOf(24 * 60 * 60) .divide(BlockInterval.getBlockCountByCoinName(product.getCoin()), 6, RoundingMode.HALF_UP)) - .multiply(reward); - } - } - return ProductMachineDto.builder() - .id(leaseProductMachine.getId()) - .user(leaseProductMachine.getUser()) - .miner(leaseProductMachine.getMiner()) - .price(leaseProductMachine.getPrice()) - .type(leaseProductMachine.getType()) - .algorithm(product.getAlgorithm()) - .theoryPower(leaseProductMachine.getTheoryPower()) - .computingPower(computingPower) - .maxLeaseDays(leaseProductMachine.getMaxLeaseDays()) - .unit(leaseProductMachine.getUnit()) - .saleState(leaseProductMachine.getSaleState()) - .state(leaseProductMachine.getState()) - .powerDissipation(leaseProductMachine.getPowerDissipation()) - .theoryIncome(singleTheoryMachineIncome) - .theoryUsdtIncome(singleTheoryMachineIncome.multiply( price)) - .coin(leaseProductMachine.getCoin()) - .build(); + .multiply(reward); + productMachineDto.setComputingPower(computingPower); + productMachineDto.setTheoryIncome(singleTheoryMachineIncome); + productMachineDto.setTheoryUsdtIncome(singleTheoryMachineIncome.multiply(price)); + }) - //.filter(Objects::nonNull) - //.sorted(Comparator.comparing(ProductMachineDto::getPrice)) .collect(Collectors.toList()); + //分页内排序 + productMachines = sorted(productMachines,productMachineVo); + PageResult success = PageResult.success(productMachines); + success.setTotal(pageInfo.getTotal()); + success.setTotalPage(pageInfo.getPages()); + PageHelper.clearPage(); + return success; + } - //所有机器按价格分组 - Map> productMachineDtoMap = productMachines.stream() - .sorted(Comparator.comparing(ProductMachineDto::getSaleState)) - .collect(Collectors.groupingBy(ProductMachineDto::getPrice)); + public List sorted(List productMachineDtoList,ProductMachineVo productMachineVo){ - //计算实际,理论算力功耗等范围值 - Map bigDecimalProductMachineRangeDtoMap = calculateRanges(productMachineDtoMap); + if (productMachineVo.getPriceSort() != null) { + Comparator priceComparator = productMachineVo.getPriceSort() ? + Comparator.comparing(ProductMachineDto::getPrice) : + Comparator.comparing(ProductMachineDto::getPrice).reversed(); + return productMachineDtoList.stream() + .sorted(priceComparator) + .collect(Collectors.toList()); + } else if (productMachineVo.getPowerSort() != null) { + Comparator powerComparator = productMachineVo.getPowerSort() ? + Comparator.comparing(ProductMachineDto::getComputingPower) : + Comparator.comparing(ProductMachineDto::getComputingPower).reversed(); + return productMachineDtoList.stream() + .sorted(powerComparator) + .collect(Collectors.toList()); + } else if (productMachineVo.getPowerDissipationSort() != null) { + Comparator powerDissipationComparator = productMachineVo.getPowerDissipationSort() ? + Comparator.comparing(ProductMachineDto::getPowerDissipation) : + Comparator.comparing(ProductMachineDto::getPowerDissipation).reversed(); + return productMachineDtoList.stream() + .sorted(powerDissipationComparator) + .collect(Collectors.toList()); + } else { + return productMachineDtoList; + } + } - List collect = bigDecimalProductMachineRangeDtoMap.entrySet().stream() - .map(entry -> { - BigDecimal key = entry.getKey(); - ProductMachineRangeGroupDto rangeDto = entry.getValue(); - List machines = productMachineDtoMap.get(key); - return ProductMachineRangeInfoDto.builder() - .productMachineRangeGroupDto(rangeDto) - .productMachines(machines) - .build(); - }) - // 按照 rangeDto 的 price 字段降序排序 - .sorted(Comparator.comparing(info -> info.getProductMachineRangeGroupDto().getPrice())) - .collect(Collectors.toList()); - productMachineInfoDto.setMachineRangeInfoList( collect); - return Result.success(productMachineInfoDto); + @Override + public Result> getPayTypes() { + LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper() + .select(LeaseShop::getId) + .eq(LeaseShop::getUserEmail, SecurityUtils.getUsername()) + .eq(LeaseShop::getDel, false)); + + List shopWalletInfo = leaseShopMapper.getShopWalletInfo(leaseShop.getId()); + return Result.success(shopWalletInfo); } /** @@ -296,7 +264,6 @@ public class LeaseProductServiceImpl extends ServiceImpl collect = new ArrayList<>(); - //if (!BigDecimal.ZERO.equals(productURDVo.getPower())){ - // //如果修改了算力power 就需要对应修改该商品下的算力 - // List leaseProductMachines = leaseProductMachineMapper.selectList( - // new LambdaQueryWrapper().eq(LeaseProductMachine::getProductId, productURDVo.getId()) - // .eq(LeaseProductMachine::getDel,false)); - // - // //计算对应user+miner 近3天算力总和 - // List nexaMinersv2 = leaseNexaMachinePowerMapper.getRecentlyFiveMinutesData(leaseProductMachines, productURDVo.getCoin()); - // // 创建一个 Map 用于存储 user 和 miner 组合对应的 ProductMachineDto 对象 - // Map machineDtoMap = nexaMinersv2.stream() - // .collect(Collectors.toMap( - // dto -> dto.getUser() + "-" + dto.getMiner(), - // dto -> dto - // )); - // - // BigDecimal price = redisService.getCacheObject(RedisKey.getPiceKey(product.getCoin())); - // BigDecimal reward = redisService.getCacheObject(RedisKey.getRewardKey(product.getCoin())); - // //全网算力单位是MH/s - // BigDecimal mhs = redisService.getCacheObject(RedisKey.getMhsKey(product.getCoin())); - // if (price == null){ - // return Result.fail("修改商品失败,未获取到"+product.getCoin()+"币的币价,请稍后重试"); - // } - // if (reward == null){ - // return Result.fail("修改商品失败,未获取到"+product.getCoin()+"币的报快奖励,请稍后重试"); - // } - // if (mhs == null){ - // return Result.fail("修改商品失败,未获取到"+product.getCoin()+"币的全网算力,请稍后重试"); - // } - // - // - // ////得到3天内的全网算力平均值 - // //BigDecimal netPower = leaseProductMapper.getCoinNetPower(productURDVo.getCoin()); - // // - // ////获取近三天全网实际报块数 - // //BigDecimal actualNetBlocks = leaseProductMapper.getNetBlocks(productURDVo.getCoin()); - // // - // ////获取全网理论报块 - // //BigDecimal theoryNetBlocks = DailyBlockOutputConstant.getBlockCountByCoinName(productURDVo.getCoin()); - // // - // ////计算单机理论收益(商品对应的同类型机器都是这个固定值) - // //BigDecimal singleTheoryMachineIncome = productURDVo.getPower() - // // .divide(netPower, 8, RoundingMode.HALF_UP) - // // .multiply(theoryNetBlocks); - // - // collect = leaseProductMachines.stream().peek(productMachine-> { - // //获取单机实际算力 - // String key = productMachine.getUser() + "-" + productMachine.getMiner(); - // ProductMachineDto productMachineDto = machineDtoMap.get(key); - // - // BigDecimal singleActualMachineIncome = BigDecimal.ZERO; - // BigDecimal singleTheoryMachineIncome = BigDecimal.ZERO; - // if (productMachineDto != null){ - // //// 将 LocalDateTime 转换为 Instant 并使用 Duration 计算毫秒差 - // //Instant startInstant = productMachineDto.getStartTime().atZone(ZoneId.systemDefault()).toInstant(); - // //Instant endInstant = productMachineDto.getEndTime().atZone(ZoneId.systemDefault()).toInstant(); - // //Duration duration = Duration.between(startInstant, endInstant); - // //long millis = duration.toMillis(); - // //// 计算单矿机3天内平均算力 - // //BigDecimal actualPower = productMachineDto.getComputingPower() - // // .multiply(BigDecimal.valueOf(Math.pow(2, 32))) - // // //这里计算的是3天内 - // // .divide(BigDecimal.valueOf(millis), 2, RoundingMode.HALF_UP); - // ////计算预估实际收益 - // //singleActualMachineIncome = actualPower - // // .divide(netPower, 8, RoundingMode.HALF_UP) - // // .multiply(actualNetBlocks); - // - // //理论收益 = 矿机算力/全网算力 * 24h /出块间隔秒数 * 单块奖励(redis中nexa:reward) - // singleTheoryMachineIncome = mhs.divide( productMachineDto.getComputingPower(),6, RoundingMode.HALF_UP) - // .multiply(BigDecimal.valueOf(24 * 60 * 60).divide(BlockInterval.getBlockCountByCoinName(product.getCoin()), 6, RoundingMode.HALF_UP)) - // .multiply(reward); - // - // } - // //productMachine.setActualIncome(singleActualMachineIncome); - // productMachine.setTheoryIncome(singleTheoryMachineIncome); - // }).collect(Collectors.toList()); - // - //} - //if (collect.isEmpty() && b1){ - // return Result.success("修改成功"); - //} - //boolean b = leaseProductMachineService.updateBatchById(collect); - //if (b && b1){ - // return Result.success("修改成功"); - //} - //return Result.fail("修改失败"); } @Override @@ -488,15 +366,137 @@ public class LeaseProductServiceImpl extends ServiceImpl= 1){ return Result.fail("删除失败,该商品存在租约中的机器"); } - boolean updateFather = updateById(LeaseProduct.builder().id(id).del(true).build()); - //int delete = leaseProductMachineMapper.delete(new LambdaQueryWrapper().eq(LeaseProductMachine::getProductId, id)); - int update = leaseProductMachineMapper.update(LeaseProductMachine.builder().del(true).build(), - new LambdaQueryWrapper().eq(LeaseProductMachine::getProductId, id)); + List machineIds = leaseProductMachineMapper.getIdsForProductId(id); + if (updateFather){ + if (!machineIds.isEmpty()){ + leaseProductMachineMapper.update(LeaseProductMachine.builder().del(true).build(), + new LambdaQueryWrapper().in(LeaseProductMachine::getId, machineIds)); + //删除矿机对应的售价 + leaseProductMachinePriceService.remove(new LambdaUpdateWrapper() + .in(LeaseProductMachinePrice::getProductMachineId, machineIds)); + } - if (updateFather || update > 0){ return Result.success("删除成功"); } return Result.fail("删除失败"); } + + @Override + public Result> getSupportPayType() { + Long shopId = getShopIdByProductId(); + List supportPayType = leaseProductMapper.getSupportPayType(shopId); + return Result.success(supportPayType); + } + + + + @Override + public Result> getProductListForShopWalletConfig() { + Long shopId = getShopIdByProductId(); + //1.获取商品列表 + List productForShopWalletConfigDtoList = leaseProductMapper.getProductListForShopWalletConfig(shopId); + if (productForShopWalletConfigDtoList.isEmpty()){ + return Result.success(productForShopWalletConfigDtoList); + } + //2.获取商品对应矿机 + List productMachineForWalletConfigDtoList = leaseProductMachineMapper.getProductListForShopWalletConfig(shopId); + BigDecimal usdtPrice = redisService.getCacheBigDecimal(RedisKey.getPiceKey(productForShopWalletConfigDtoList.get(0).getCoin())); + Map> collect = productMachineForWalletConfigDtoList.stream() + .peek(productMachineForWalletConfigDto -> { + productMachineForWalletConfigDto.setTheoryUsdtIncome(productMachineForWalletConfigDto.getTheoryIncome() + .multiply(usdtPrice)); + }) + .collect(Collectors.groupingBy(ProductMachineForWalletConfigDto::getProductId)); + for (ProductForWalletConfigDto productForWalletConfigDto : productForShopWalletConfigDtoList) { + List list = collect.get(productForWalletConfigDto.getProductId()); + if (list.isEmpty()){ + productForShopWalletConfigDtoList.remove(productForWalletConfigDto); + } + productForWalletConfigDto.setMachineList(list); + } + return Result.success(productForShopWalletConfigDtoList); + } + + public Long getShopIdByProductId(){ + LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper() + .select(LeaseShop::getId) + .eq(LeaseShop::getUserEmail, SecurityUtils.getUsername()) + .eq(LeaseShop::getDel, false)); + return leaseShop.getId(); + } + + + @Override + @Transactional + public Result updateProductListForShopWalletConfig(ProductMachineForWalletConfigVo productMachineForWalletConfigVo) { + List payCoinsList = new ArrayList<>(Arrays.asList(productMachineForWalletConfigVo.getSymbol().split(","))); + String chain = productMachineForWalletConfigVo.getChain(); + String address = productMachineForWalletConfigVo.getPayAddress(); + LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper() + .eq(LeaseShop::getUserEmail, SecurityUtils.getUsername())); + boolean check = checkHashWalletInfo(leaseShop.getId(),chain,address, payCoinsList); + if (!check){ + return Result.fail("绑定钱包失败,钱包格式不正确或该链和币种钱包已绑定过"); + } + String[] symbolList = productMachineForWalletConfigVo.getSymbol().split(","); + List priceAndIdList = productMachineForWalletConfigVo.getProductMachineForWalletConfigVoList(); + List leaseProductMachinePriceList = new ArrayList<>(); + for (ProductMachineForWalletConfigVo.PriceVo priceVo : priceAndIdList) { + String[] priceList = priceVo.getPrice().split(","); + if (priceList.length != symbolList.length){ + return Result.fail("绑定钱包失败,存在商品矿机未设置新钱包售价"); + } + for (int i = 0; i < priceList.length; i++) { + leaseProductMachinePriceList.add(LeaseProductMachinePrice.builder() + .productMachineId(priceVo.getProductMachineId()) + .price(new BigDecimal(priceList[i])) + .coin(symbolList[i]) + .chain(chain) + .build()); + } + } + boolean b = leaseProductMachinePriceService.saveBatch(leaseProductMachinePriceList); + if (b || leaseProductMachinePriceList.isEmpty()){ + //绑定钱包新钱包 + List shopConfigList = leaseShopConfigMapper.getCoinIconByChainAndCoin(chain, payCoinsList); + String qrCode = QrCodeUtils.creatRrCode(address, 200, 200); + for (LeaseShopConfig leaseShopConfig : shopConfigList) { + leaseShopConfig.setShopId(leaseShop.getId()); + leaseShopConfig.setChain(chain); + leaseShopConfig.setPayAddress(address); + leaseShopConfig.setQrcode(qrCode); + } + boolean insetWallet = leaseShopConfigService.saveBatch(shopConfigList); + if (insetWallet){ + return Result.success("绑定钱包成功"); + } + throw new ProductSoldOutException ("钱包绑定失败"); + } + throw new ProductSoldOutException ("新币种钱包商品售价新增失败"); + } + + + /** + * 钱包格式校验,以及判断该链和币种钱包是否已存在 + * @param chain + * @param address + * @param coinList + * @return + */ + public boolean checkHashWalletInfo(Long shopId,String chain,String address,List coinList){ + if (!WalletRuleCheckUtils.checkAddress(chain,address)){ + return false; + } + List configList = leaseShopConfigMapper.selectList(new LambdaQueryWrapper() + .eq(LeaseShopConfig::getShopId, shopId) + .eq(LeaseShopConfig::getChain, chain) + .in(LeaseShopConfig::getPayCoin, coinList) + .eq(LeaseShopConfig::getDel, false) + ); + if (!configList.isEmpty()){ + return false; + } + return true; + } } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseShopServiceImpl.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseShopServiceImpl.java index d9f2199..b7b6cb0 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseShopServiceImpl.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseShopServiceImpl.java @@ -241,7 +241,7 @@ public class LeaseShopServiceImpl extends ServiceImpl() .eq(LeaseShop::getUserEmail, SecurityUtils.getUsername())); diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseShoppingCartServiceImpl.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseShoppingCartServiceImpl.java index 516063e..845ddc0 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseShoppingCartServiceImpl.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseShoppingCartServiceImpl.java @@ -1,5 +1,6 @@ package com.m2pool.lease.service.impl; +import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -7,6 +8,7 @@ import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.m2pool.common.redis.service.RedisService; import com.m2pool.common.security.utils.SecurityUtils; +import com.m2pool.lease.constant.BlockInterval; import com.m2pool.lease.constant.PowerUnit; import com.m2pool.lease.constant.RedisKey; import com.m2pool.lease.dto.*; @@ -24,6 +26,7 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; +import java.math.RoundingMode; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.HashMap; @@ -59,10 +62,10 @@ public class LeaseShoppingCartServiceImpl extends ServiceImpl getGoodsList(PageVo pageVo) { - //1.获取用户购物车 String userId = SecurityUtils.getUsername(); + //检查购物车中是否存在商品 LeaseShoppingCart leaseShoppingCart = leaseShoppingCartMapper.selectOne(new LambdaQueryWrapper() .eq(LeaseShoppingCart::getUserId, userId)); if (leaseShoppingCart == null){ - return PageResult.fail(null,"购物车中不存在商品"); + return PageResult.success(new ArrayList<>()); } - //获取商品相关信息 - List cartInfoList = leaseShoppingCartInfoMapper.getCartInfoList(leaseShoppingCart.getId()); - PageInfo pageInfo = new PageInfo<>(cartInfoList); + List cartInfoList = leaseShoppingCartInfoMapper.getProductAndMachineIds(leaseShoppingCart.getId()); if (cartInfoList.isEmpty()){ - return PageResult.fail(null,"购物车中不存在商品"); + return PageResult.success(new ArrayList<>()); } + List productIds = new ArrayList<>(); + List machineIds = new ArrayList<>(); + Map machineMap = new HashMap<>(); + for (ShoppingCartInfoDto shoppingCartInfoDto : cartInfoList) { + productIds.add(shoppingCartInfoDto.getProductId()); + machineIds.add(shoppingCartInfoDto.getProductMachineId()); + machineMap.put(shoppingCartInfoDto.getProductMachineId(), shoppingCartInfoDto.getLeaseTime()); + } + List shopIds = leaseShopMapper.getShopIdsByProductIds(productIds); PageHelper.startPage(pageVo.getPageNum(), pageVo.getPageSize()); - //查询购物车中店铺信息 - Map> shopGroupMap = cartInfoList.stream().collect(Collectors.groupingBy(ShoppingCartInfoDto::getShopId)); - List leaseShops = leaseShopMapper.selectList(new LambdaQueryWrapper().in(LeaseShop::getId, shopGroupMap.keySet())); + //查询购物车中店铺信息(一层) + List leaseShops = leaseShopMapper.selectList(new LambdaQueryWrapper().in(LeaseShop::getId, shopIds)); - //获取商品下机器id集合 - List machineIds = cartInfoList.stream().map(ShoppingCartInfoDto::getProductMachineId).collect(Collectors.toList()); - //获取机器id 为key ,机器详情集合为value 的map - List leaseShoppingCartInfos = leaseShoppingCartInfoMapper.selectList(new LambdaQueryWrapper() - .eq(LeaseShoppingCartInfo::getCartId, leaseShoppingCart.getId())); - Map machineMap = leaseShoppingCartInfos.stream().collect(Collectors.toMap(LeaseShoppingCartInfo::getProductMachineId, Function.identity())); - - //查询商品中机器详情 + 按照币种分组 + //获取商品售价 + List machinePriceByMachineIds = leaseProductMachinePriceMapper.getMachinePriceByMachineIds(machineIds); + Map> machinePriceMap = machinePriceByMachineIds.stream().collect(Collectors.groupingBy(MachinePayTypeDto::getProductMachineId)); + //查询商品中机器详情 + 按照币种分组 (二层) List leaseProductMachines = leaseProductMachineMapper.getMachinesByIds(machineIds); - Map> userAndMinerList = leaseProductMachines.stream().map( + //获取实时币价 + List coins = leaseProductMachines.stream().map(ProductMachineDto::getCoin).distinct().collect(Collectors.toList()); + Map coinPriceMap = new HashMap<>(); + Map coinRewardMap = new HashMap<>(); + Map coinMhsMap = new HashMap<>(); + for (String coin : coins) { + BigDecimal price = redisService.getCacheBigDecimal(RedisKey.getPiceKey(coin)); + BigDecimal reward =redisService.getCacheBigDecimal(RedisKey.getRewardKey(coin)); + BigDecimal mhs = redisService.getCacheBigDecimal(RedisKey.getMhsKey(coin)); + coinMhsMap.put(coin, mhs); + coinRewardMap.put(coin, reward); + coinPriceMap.put(coin, price); + } + //按币种查询每个矿机的最近一次30分钟的实时算力(后续修改为24小时平均算力) + List userMinerPowerList = new ArrayList<>(); + Map> userAndMinerList = leaseProductMachines.stream().map( ProductMachineDto -> - UserMinerDto.builder() + LeaseProductMachine.builder() .user(ProductMachineDto.getUser()) .miner(ProductMachineDto.getMiner()) .coin(ProductMachineDto.getCoin()) .build() - ).collect(Collectors.groupingBy(UserMinerDto::getCoin)); + ).collect(Collectors.groupingBy(LeaseProductMachine::getCoin)); - //获取实时币价 - List coins = leaseProductMachines.stream().map(ProductMachineDto::getCoin).distinct().collect(Collectors.toList()); - Map coinPriceMap = new HashMap<>(); - for (String coin : coins) { - BigDecimal price = redisService.getCacheBigDecimal(RedisKey.getPiceKey(coin)); - if (price == null){ - price = BigDecimal.ZERO; - } - coinPriceMap.put(coin, price); - } - - //按币种查询每个矿机的最近一次30分钟的实时算力(后续修改为24小时平均算力) - List userMinerPowerList = new ArrayList<>(); userAndMinerList.forEach((coin, userMinerDtos) -> { - userMinerPowerList.addAll(leaseUserOwnedProductMapper.getUserMinerPower(userMinerDtos, coin)); + List recentlyFiveMinutesData = leaseProductMachineMapper.getRecentlyFiveMinutesData(userMinerDtos, coin); + List collect = recentlyFiveMinutesData.stream().peek(dto -> { + dto.setCoin(coin); + }).collect(Collectors.toList()); + userMinerPowerList.addAll(collect); }); - Map realPowerList = userMinerPowerList.stream() + + Map realPowerList = userMinerPowerList.stream() .collect(Collectors.toMap( dto -> dto.getUser() + "-" + dto.getMiner() + "-" + dto.getCoin(), dto -> dto )); //为每个矿机设置实时的算力 + 按店铺分组 Map> shopIdAndMachineInfoMap = leaseProductMachines.stream().peek(productMachineDto -> { - UserMinerPowerDto userMinerPowerDto = realPowerList.get(productMachineDto.getUser() + "-" + productMachineDto.getMiner() + "-" + productMachineDto.getCoin()); + ProductMachineDto userMinerPowerDto = realPowerList.get(productMachineDto.getUser() + "-" + productMachineDto.getMiner() + "-" + productMachineDto.getCoin()); + List machinePayTypeDtoList = machinePriceMap.get(productMachineDto.getId()); + productMachineDto.setPriceList(machinePayTypeDtoList); + //理论收益 + BigDecimal singleTheoryMachineIncome; + BigDecimal computingPower; + BigDecimal singleTheoryUSDTMachineIncome; if (userMinerPowerDto != null) { + // 矿机算力单位转换 + 计算单矿机平均算力(ComputingPower coin_mhs30m 平均算力) + computingPower = PowerUnitUtils.getPower(productMachineDto.getUnit(), + userMinerPowerDto.getComputingPower() + .multiply(BigDecimal.valueOf(1000 * 1000)) + .divide(BigDecimal.valueOf(24 * 60 * 60 ), 2, RoundingMode.HALF_UP)); + BigDecimal mhs = coinMhsMap.get(productMachineDto.getCoin()); + BigDecimal reward = coinRewardMap.get(productMachineDto.getCoin()); + BigDecimal price = coinPriceMap.get(productMachineDto.getCoin()); + if (mhs == null || reward == null || price == null){ + singleTheoryMachineIncome = productMachineDto.getTheoryIncome(); + singleTheoryUSDTMachineIncome = singleTheoryMachineIncome.multiply(price); + }else{ + //全网算力单位转换 + BigDecimal power = PowerUnitUtils.getPower(productMachineDto.getUnit(),mhs).multiply(BigDecimal.valueOf(1000 * 1000)); + //(理论收益 = 矿机算力/全网算力 * 24h /出块间隔秒数 * 单块奖励(redis中nexa:reward)) + singleTheoryMachineIncome = computingPower.divide( power,6, RoundingMode.HALF_UP) + .multiply(BigDecimal.valueOf(24 * 60 * 60) + .divide(BlockInterval.getBlockCountByCoinName(productMachineDto.getCoin()), 6, RoundingMode.HALF_UP)).multiply(reward); + singleTheoryUSDTMachineIncome = singleTheoryMachineIncome.multiply(price); + } //单位为MH/s 需要转换成 矿机设定的单位 - BigDecimal value = userMinerPowerDto.getPower().multiply(PowerUnit.getPower(MH_UNIT)); - productMachineDto.setComputingPower(PowerUnitUtils.getPower(productMachineDto.getUnit(),value)); - productMachineDto.setTheoryUsdtIncome(productMachineDto.getTheoryIncome().multiply(coinPriceMap.get(productMachineDto.getCoin()))); - productMachineDto.setStartTime(userMinerPowerDto.getStartTime()); - productMachineDto.setEndTime(LocalDateTime.now()); + productMachineDto.setComputingPower(computingPower); + productMachineDto.setTheoryIncome(singleTheoryMachineIncome); + productMachineDto.setTheoryUsdtIncome(singleTheoryUSDTMachineIncome); } }).collect(Collectors.groupingBy(ProductMachineDto::getShopId)); - - //获取商铺钱包配置信息 - List shopIds = leaseShops.stream().map(LeaseShop::getId).collect(Collectors.toList()); List shopWalletInfo = leaseShopMapper.getShopWalletInfoList(shopIds); Map> payConfigMap = shopWalletInfo.stream().collect(Collectors.groupingBy(PayConfigDto::getShopId)); - //组合返回对象 List shopCartList = leaseShops.stream().map(leaseShop -> { - List productMachineList = shopIdAndMachineInfoMap.get(leaseShop.getId()); return ShopCartDto.builder() .id(leaseShop.getId()) @@ -258,33 +290,39 @@ public class LeaseShoppingCartServiceImpl extends ServiceImpl productMachineDtoList = shopCartDto.getProductMachineDtoList(); - if ( productMachineDtoList!= null) { - for (ProductMachineDto productMachineDto : productMachineDtoList) { - LeaseShoppingCartInfo cartInfo = machineMap.get(productMachineDto.getId()); - if (cartInfo != null ) { - Integer leaseTime = cartInfo.getLeaseTime(); - productMachineDto.setLeaseTime(leaseTime); - // 处理空指针情况 - BigDecimal price = productMachineDto.getPrice(); - if (price != null && leaseTime != null) { - BigDecimal itemPrice = price.multiply(new BigDecimal(leaseTime)); - totalPrice = totalPrice.add(itemPrice); - } - } + Map totalPriceMap = new HashMap<>(); + Map totalPriceDtoMap = new HashMap<>(); + for (ProductMachineDto productMachineDto : productMachineDtoList) { + Integer leaseTime = machineMap.get(productMachineDto.getId()); + productMachineDto.setLeaseTime(leaseTime); + List priceList = productMachineDto.getPriceList(); + for (MachinePayTypeDto machinePayTypeDto : priceList) { + BigDecimal itemPrice = machinePayTypeDto.getPrice().multiply(new BigDecimal(leaseTime)); + String key = machinePayTypeDto.getCoin()+"-"+machinePayTypeDto.getChain(); + totalPriceMap.merge(key, itemPrice, BigDecimal::add); + totalPriceDtoMap.put(key,new MachineTotalPriceDto(BigDecimal.ZERO, machinePayTypeDto.getChain(), machinePayTypeDto.getCoin())); } } - shopCartDto.setTotalPrice(totalPrice); + ; + totalPriceDtoMap.forEach((key, value) -> { + value.setPrice(totalPriceMap.get(key)); + }); + + shopCartDto.setTotalPriceList(new ArrayList<>(totalPriceDtoMap.values())); } + PageInfo pageInfo = new PageInfo<>(shopCartList); PageResult success = PageResult.success(shopCartList); success.setTotal(pageInfo.getTotal()); success.setTotalPage(pageInfo.getPages()); PageHelper.clearPage(); return success; + } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/MachineTask.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/MachineTask.java deleted file mode 100644 index 609f853..0000000 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/MachineTask.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.m2pool.lease.task; - -import cn.hutool.core.date.DateTime; -import cn.hutool.core.date.DateUtil; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.m2pool.lease.dto.ProductMachineDto; -import com.m2pool.lease.entity.LeaseNexaMachineAvgPower; -import com.m2pool.lease.entity.LeaseNexaMachinePower; -import com.m2pool.lease.entity.LeaseProductMachine; -import com.m2pool.lease.mapper.LeaseNexaMachineAvgPowerMapper; -import com.m2pool.lease.mapper.LeaseNexaMachinePowerMapper; -import com.m2pool.lease.mapper.LeaseProductMachineMapper; -import com.m2pool.lease.mapper.LeaseUserOwnedProductMapper; -import com.m2pool.lease.service.LeaseNexaMachinePowerService; -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.time.Duration; -import java.time.Instant; -import java.time.ZoneId; -import java.util.Calendar; -import java.util.Date; -import java.util.List; -import java.util.stream.Collectors; - -/** - * @Description 后台管理系统 定时任务 (没有用到后续可能删除) - * @Date 2025/7/15 15:45 - * @Author yyb - */ -@Configuration -@EnableScheduling -@Deprecated -public class MachineTask { - - // - //@Resource - //private LeaseNexaMachinePowerMapper leaseNexaMachinePowerMapper; - // - //@Resource - //private LeaseUserOwnedProductMapper leaseUserOwnedProductMapper; - // - //@Resource - //private LeaseProductMachineMapper leaseProductMachineMapper; - // - // - //@Resource - //private LeaseNexaMachinePowerService leaseNexaMachinePowerService; - // - //@Resource - //private LeaseNexaMachineAvgPowerMapper leaseNexaMachineAvgPowerMapper; - // - ///** - // * 每五分钟更新一次已经出售的机器的算力(所有币种数据) - // */ - //@Scheduled(cron = "0 0/5 * * * ?") - //public void insertMachinePowerTask(){ - // // 获取五分钟前的时间 - // Calendar calendar = Calendar.getInstance(); - // calendar.set(Calendar.SECOND, 0); - // calendar.set(Calendar.MILLISECOND, 0); - // calendar.add(Calendar.MINUTE, -5); - // Date pointDate = calendar.getTime(); - // //获取当天零点时间 - // DateTime dateTime = DateUtil.beginOfDay(DateTime.now()); - // //1.查询已购生效机器ids集合 - // List productMachineIds = leaseUserOwnedProductMapper.getProductMachineIds(dateTime); - // if (productMachineIds.isEmpty()){ - // System.out.println("没有存在租赁期机器"); - // return; - // } - // // 2. 先查询已购表中的在有效期内的机器user 和 miner - // List leaseProductMachines = leaseProductMachineMapper.selectList(new LambdaQueryWrapper().in(LeaseProductMachine::getId, productMachineIds)); - // // 3.根据这个user 和 miner 从hashrate库中获取对应的实时算力 TODO 这里可能不需要记录实时算力 并且这个定时任务也不需要了。这个实时算力没多大用 后续用收益代替 - // List nexaMinersv2 = leaseNexaMachinePowerMapper.getMachinePowerInHashRateById(leaseProductMachines,pointDate, "nexa_minersv2"); - // //4.向数据库写入数据 - // boolean b = leaseNexaMachinePowerService.saveBatch(nexaMinersv2); - // System.out.println("矿工算力入库状态(true 成功 false 失败):" + b); - //} - // - ///** - // * 每半小时更新一次m2pool中nexa的所有机器的实时平均算力(3天平均算力) - // */ - //@Scheduled(cron = "0 0/30 * * * ?") - //public void insertNexaMachineAvgPowerTask(){ - // //每半小时更新一次 - // List nexaMinersv2 = leaseNexaMachinePowerMapper.getMachineThreePower(null, "nexa"); - // - // if (nexaMinersv2.isEmpty()) { - // return; - // } - // List collect = nexaMinersv2.stream().map(productMachineDto -> { - // // 将 LocalDateTime 转换为 Instant - // Instant startInstant = productMachineDto.getStartTime().atZone(ZoneId.systemDefault()).toInstant(); - // Instant endInstant = productMachineDto.getEndTime().atZone(ZoneId.systemDefault()).toInstant(); - // // 使用 Duration 计算毫秒差 - // Duration duration = Duration.between(startInstant, endInstant); - // long millis = duration.toMillis(); - // return LeaseNexaMachineAvgPower.builder() - // .user(productMachineDto.getUser()) - // .miner(productMachineDto.getMiner()) - // .startTime(productMachineDto.getStartTime()) - // .endTime(productMachineDto.getEndTime()) - // .realAvgPower(productMachineDto.getComputingPower() - // .multiply(BigDecimal.valueOf(Math.pow(2, 32))) - // .divide(BigDecimal.valueOf(millis), 2, RoundingMode.HALF_UP)) - // .build(); - // }).collect(Collectors.toList()); - // - // boolean b = leaseNexaMachineAvgPowerMapper.insertBatchDatas(collect); - //} -} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/OrderAndPayTask.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/OrderAndPayTask.java index 224cae3..4bc3db9 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/OrderAndPayTask.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/OrderAndPayTask.java @@ -2,6 +2,7 @@ package com.m2pool.lease.task; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; +import com.baomidou.dynamic.datasource.annotation.DSTransactional; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.m2pool.lease.constant.PowerUnit; @@ -25,6 +26,8 @@ import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -71,6 +74,8 @@ public class OrderAndPayTask { @Resource private LeaseOrderItemService leaseOrderItemService; + + /** * 检查钱包半年内是否有 支付,充值,提现操作 */ @@ -105,7 +110,7 @@ public class OrderAndPayTask { long l = System.currentTimeMillis()/1000L; RabbitmqDeleteWalletMessage build = RabbitmqDeleteWalletMessage.builder() .msg_type(0) - .queue_id(userWalletDataDto.getQueueId().toString()) + .queue_id(userWalletDataDto.getQueueId()) .chain(userWalletDataDto.getFromChain()) .symbol(userWalletDataDto.getFromSymbol()) .address(userWalletDataDto.getFromAddress()) @@ -123,8 +128,8 @@ public class OrderAndPayTask { * 支付 定时任务 */ //@Scheduled(cron = "0 5 0 * * ? ") - @Scheduled(cron = "0 0/5 * * * ? ") - @Transactional + @Scheduled(cron = "0 0/1 * * * ? ") + @DSTransactional public void paymentTask(){ // 获取当天 0 点的 时间 LocalDateTime now = LocalDateTime.now(); @@ -135,14 +140,20 @@ public class OrderAndPayTask { System.out.println("没有进行中的订单"); return; } - Map orderNumberMap = needPayOrderList.stream().collect(Collectors.toMap(LeaseOrderInfo::getId, LeaseOrderInfo::getOrderNumber)); - //2.根据订单号找到对应的订单详情(不包含租约到期) ,并根据这些订单详情找到每个矿机的信息 - List infoIds = needPayOrderList.stream().map(LeaseOrderInfo::getId).collect(Collectors.toList()); + List infoIds = new ArrayList<>(); + Map queueIdMap = new HashMap<>(); + for (LeaseOrderInfo leaseOrderInfo : needPayOrderList) { + queueIdMap.put(leaseOrderInfo.getId(), leaseOrderInfo); + infoIds.add(leaseOrderInfo.getId()); + } + + //2.根据订单号找到对应的订单详情(状态为1 租约生效中) ,并根据这些订单详情找到每个矿机的信息 List leaseOrderItems = leaseOrderItemMapper.selectList(new LambdaQueryWrapper() .eq(LeaseOrderItem::getStatus,1) .in(LeaseOrderItem::getOrderId, infoIds)); - //因卖方收款钱包修改后,改变订单收款地址 + //订单进行过程中,卖方可能修改收款地址。所以每天支付前,需要修改旧收款地址为新地址 leaseOrderItems = updateOrderItemSellerWalletAddress(leaseOrderItems); + List machineIdList = leaseOrderItems.stream().map(LeaseOrderItem::getProductMachineId).collect(Collectors.toList()); List leaseProductMachines = leaseProductMachineMapper.selectBatchIds(machineIdList); @@ -161,59 +172,58 @@ public class OrderAndPayTask { dto -> dto )); //2.2 订单详情集合 按照 买方地址 + 链名称分组 - Map> userMapItem = leaseOrderItems.stream() - .collect(Collectors.groupingBy( - item-> item.getAddress() + "-" + item.getChain() - )); - + Map> userMapItem = leaseOrderItems.stream() + .collect(Collectors.groupingBy(LeaseOrderItem::getOrderId)); + //.collect(Collectors.groupingBy( + // item-> item.getFromAddress() + "-" + item.getChain()+"-" + item.getSymbol() + //)); //3.筛选出租期到期的商品 List expireProductList = new ArrayList<>(); List rabbitmqPayAutoMessages = new ArrayList<>(); Map orderInfoIdAndIsComplete = new HashMap<>(); - userMapItem.forEach((addressAndChain, items) -> { + List saleIngList = new ArrayList<>(); + // 按照订单分组 + userMapItem.forEach((orderId, items) -> { LeaseOrderItem leaseOrderItem = items.get(0); - List expire = new ArrayList<>(); - - //因为生成订单时会冻结整个订单的金额,所以这里不用再去判断 - String queueId = UuidGeneratorUtil.generateUuidWithoutHyphen(); long timestamp = System.currentTimeMillis()/1000; - + //因为同一个订单的queueId相同,所以这里直接使用订单id + LeaseOrderInfo orderInfo = queueIdMap.get(leaseOrderItem.getOrderId()); + String queueId =orderInfo.getOrderNumber(); //买方信息 RabbitmqPayAutoMessage build = RabbitmqPayAutoMessage.builder() .queue_id(queueId) .chain(leaseOrderItem.getChain()) .symbol(leaseOrderItem.getSymbol()) - .total_amount(BigDecimal.ZERO) + .total_fee(orderInfo.getFee()) .from_address(leaseOrderItem.getFromAddress()) + .total_amount(BigDecimal.ZERO) .timestamp(timestamp) .sign(HashUtils.sha256(timestamp)) .build(); - //封装卖方收款信息 - List sellerPayInfoMessages = new ArrayList<>(); + Map sellerPayInfoMessages = new HashMap<>(); //买方收款信息 相同订单最后整合成一个卖方信息 - Map> orderIdMap = items.stream().collect(Collectors.groupingBy(LeaseOrderItem::getOrderId)); - orderIdMap.forEach((orderId, orderItemList) -> { - LeaseOrderItem orderInfo = orderItemList.get(0); + Map> orderIdsMap = items.stream().collect(Collectors.groupingBy(LeaseOrderItem::getAddress)); + orderIdsMap.forEach((toAddress, orderItemList) -> { + LeaseOrderItem orderItem = orderItemList.get(0); RabbitmqPayAutoInfoMessage sellInfo = RabbitmqPayAutoInfoMessage.builder() - .to_address(orderInfo.getAddress()) + .order_id(orderItem.getOrderId().toString()) + .to_address(toAddress) .amount(BigDecimal.ZERO) .blockAmount(BigDecimal.ZERO) .needAmount(BigDecimal.ZERO) - .order_id(orderInfo.getOrderId().toString()) - .shopId(orderInfo.getShopId()) - .userId(orderInfo.getUserId()) + .shopId(orderItem.getShopId()) + .userId(orderItem.getUserId()) .build(); for (LeaseOrderItem item : orderItemList) { orderInfoIdAndIsComplete.putIfAbsent(item.getOrderId(), true); LocalDateTime expireTime = item.getCreateTime().plusDays(1).toLocalDate().atStartOfDay().plusDays(item.getLeaseTime()); //开发环境 - List list = leasePayRecordMessageService.list(new LambdaQueryWrapper() - .eq(LeasePayRecordMessage::getOrderId, item.getOrderId())); + LocalDateTime a = item.getCreateTime().plusMinutes(item.getLeaseTime()); // 租期已过 - if (startOfDay.isAfter(expireTime) /**开发环境*/|| list.size() == item.getLeaseTime()) { + if (startOfDay.isAfter(expireTime) /**开发环境*/|| now.isAfter(a)) { item.setStatus(0); expire.add(item); }else{ @@ -225,38 +235,42 @@ public class OrderAndPayTask { sellInfo.setNeedAmount(sellInfo.getNeedAmount().add(item.getPrice())); sellInfo.setBlockAmount(sellInfo.getBlockAmount().add(item.getPrice())); if (productMachineDto != null){ - //理论算力 BigDecimal theoryPower = machine.getTheoryPower().multiply(PowerUnit.getPower(machine.getUnit())) .divide(BigDecimal.valueOf(1000 * 1000),2,RoundingMode.HALF_UP); //实际算力 BigDecimal realPower = productMachineDto.getComputingPower() - .divide(BigDecimal.valueOf(24 * 60 * 60), 2, RoundingMode.HALF_UP); + .divide(BigDecimal.valueOf(24 * 60 * 60), 6, RoundingMode.HALF_UP); //设置实际支付金额 BigDecimal divide = theoryPower.subtract(realPower).divide(theoryPower, 10, RoundingMode.HALF_UP); - //设置实际需要发送消息去支付的各订单金额和总金额 if (divide.compareTo(BigDecimal.valueOf(0.05)) > 0){ - sellInfo.setAmount(sellInfo.getAmount().add(item.getPrice().multiply(BigDecimal.ONE.subtract(divide)))); - build.setTotal_amount(build.getTotal_amount().add(item.getPrice().multiply(BigDecimal.ONE.subtract(divide)))); + BigDecimal add = item.getPrice().multiply(BigDecimal.ONE.subtract(divide)); + item.setSettlePayRealAmount(add); + sellInfo.setAmount(sellInfo.getAmount().add(add)); + build.setTotal_amount(build.getTotal_amount().add(add)); }else{ - build.setTotal_amount(build.getTotal_amount().add(item.getPrice())); - sellInfo.setAmount(sellInfo.getAmount().add(item.getPrice())); + BigDecimal add = item.getPrice(); + item.setSettlePayRealAmount(add); + build.setTotal_amount(build.getTotal_amount().add(add)); + sellInfo.setAmount(sellInfo.getAmount().add(add)); } } + item.setAlreadyPayAmount(item.getAlreadyPayAmount().add(item.getPrice())); + saleIngList.add(item); } } - sellerPayInfoMessages.add(sellInfo); + sellerPayInfoMessages.put(sellInfo.getTo_address(), sellInfo); }); build.setTransactions(sellerPayInfoMessages); - //if 开发环境 - if(build.getTotal_amount().compareTo(BigDecimal.ZERO) > 0){ + if (build.getTotal_amount().compareTo(BigDecimal.ZERO) > 0){ rabbitmqPayAutoMessages.add(build); } expireProductList.addAll(expire); }); + //4.租约到期相关信息修改 if (!expireProductList.isEmpty()){ List itemIds = new ArrayList<>(); @@ -284,30 +298,36 @@ public class OrderAndPayTask { }); leaseProductService.updateBatchById(leaseProducts); - //4.5 找到详情表所有状态为0 租约已过期 ,并且订单info表订单状态为7 进行中的订单 并改为状态8 订单已完成 + //4.5 找到详情表所有状态为0 租约已过期 ,并且订单info表订单状态为7 进行中的订单 并改为状态8 订单已完成 ; 并且发送支付消息 List orderIds = orderInfoIdAndIsComplete.entrySet().stream() .filter(entry -> Boolean.TRUE.equals(entry.getValue())) .map(Map.Entry::getKey) .collect(Collectors.toList()); if(!orderIds.isEmpty()){ - leaseOrderInfoMapper.update(LeaseOrderInfo.builder().status(8).build(), - new LambdaQueryWrapper().in(LeaseOrderInfo::getId, orderIds)); + //订单状态改为已完成 + leaseOrderInfoMapper.update(LeaseOrderInfo.builder().status(8).build(), new LambdaQueryWrapper().in(LeaseOrderInfo::getId, orderIds)); + // TODO 发送支付消息 + sendMessageToMq(orderIds); } } - //5.根据这些订单发送今天的支付消息到mq + //5.正在售出中矿机已支付金额 + leaseOrderItemService.updateBatchById(saleIngList); + + //6.根据这些订单发送今天的支付消息到mq if (!rabbitmqPayAutoMessages.isEmpty()){ List collect = new ArrayList<>(); for (RabbitmqPayAutoMessage rabbitmqPayAutoMessage : rabbitmqPayAutoMessages) { List list = new ArrayList<>(); - for (RabbitmqPayAutoInfoMessage transaction : rabbitmqPayAutoMessage.getTransactions()) { + for (RabbitmqPayAutoInfoMessage transaction : rabbitmqPayAutoMessage.getTransactions().values()) { list.add(LeasePayRecordMessage.builder() + .orderId(transaction.getOrder_id()) + .orderNumber(rabbitmqPayAutoMessage.getQueue_id()) .queueId(rabbitmqPayAutoMessage.getQueue_id()) .fromAddress(rabbitmqPayAutoMessage.getFrom_address()) - .orderId(transaction.getOrder_id()) - .orderNumber(orderNumberMap.get(Long.parseLong(transaction.getOrder_id()))) .toAddress(transaction.getTo_address()) .amount(transaction.getNeedAmount()) + .realAmount(transaction.getAmount()) .needAmount(transaction.getAmount()) .fromChain(rabbitmqPayAutoMessage.getChain()) .fromSymbol(rabbitmqPayAutoMessage.getSymbol()) @@ -318,16 +338,18 @@ public class OrderAndPayTask { .toSymbol(rabbitmqPayAutoMessage.getSymbol()) .build()); } - try{ - rabbitTemplate.convertAndSend(PAY_AUTO_QUEUE, rabbitmqPayAutoMessage); - System.out.println("支付消息发送成功:"+rabbitmqPayAutoMessage); - }catch (Exception e){ - //一般出现在rabbitmq服务出现故障时出现,状态改为三,状态为三后续消息重试 - list = list.stream().peek(item->item.setStatus(3)).collect(Collectors.toList()); - System.out.println("消息发送失败:"+e.getMessage()); - }finally { - collect.addAll(list); - } + collect.addAll(list); + //TODO 订单金额 + //try{ + // rabbitTemplate.convertAndSend(PAY_AUTO_QUEUE, rabbitmqPayAutoMessage); + // System.out.println("支付消息发送成功:"+rabbitmqPayAutoMessage); + //}catch (Exception e){ + // //一般出现在rabbitmq服务出现故障时出现,状态改为三,状态为三后续消息重试 + // list = list.stream().peek(item->item.setStatus(3)).collect(Collectors.toList()); + // System.out.println("消息发送失败:"+e.getMessage()); + //}finally { + // + //} } leasePayRecordMessageService.saveBatch(collect); } @@ -368,11 +390,61 @@ public class OrderAndPayTask { } + /** + * 订单完成后---发送支付消息到mq + * @param orderIds + */ + public void sendMessageToMq(List orderIds){ + List leasePayRecordMessages = leasePayRecordMessageMapper.selectList(new LambdaQueryWrapper() + .in(LeasePayRecordMessage::getOrderId, orderIds)); + Map>> collect = leasePayRecordMessages.stream() + .collect(Collectors.groupingBy(LeasePayRecordMessage::getOrderId, Collectors.groupingBy(LeasePayRecordMessage::getToAddress))); + //遍历按订单id分组后的map + collect.forEach((orderId, payRecordMessagesMap) -> { + + long timestamp = System.currentTimeMillis()/1000; + List orDefault = payRecordMessagesMap.getOrDefault(payRecordMessagesMap.keySet().iterator().next(), new ArrayList<>()); + LeasePayRecordMessage initForm = orDefault.get(0); + RabbitmqPayAutoMessage build = RabbitmqPayAutoMessage.builder() + .queue_id(initForm.getQueueId()) + .from_address(initForm.getFromAddress()) + .chain(initForm.getFromChain()) + .symbol(initForm.getFromSymbol()) + .total_amount(BigDecimal.ZERO) + .timestamp(timestamp) + .sign(HashUtils.sha256(timestamp)) + .build(); + + Map transactions = new HashMap<>(); + //遍历按toAddress 分组后的map + payRecordMessagesMap.forEach((toAddress,payRecordMessageList) -> { + LeasePayRecordMessage init = payRecordMessageList.get(0); + RabbitmqPayAutoInfoMessage sellInfo = RabbitmqPayAutoInfoMessage.builder() + .to_address(init.getToAddress()) + .amount(BigDecimal.ZERO) + .blockAmount(BigDecimal.ZERO) + .needAmount(BigDecimal.ZERO) + .shopId(init.getShopId()) + .userId(init.getUserId()) + .build(); + for (LeasePayRecordMessage leasePayRecordMessage : payRecordMessageList) { + sellInfo.setAmount(sellInfo.getAmount().add(leasePayRecordMessage.getRealAmount())); + sellInfo.setBlockAmount(sellInfo.getBlockAmount().add(leasePayRecordMessage.getBlockAmount())); + sellInfo.setNeedAmount(sellInfo.getNeedAmount().add(leasePayRecordMessage.getNeedAmount())); + } + build.setTotal_amount(build.getTotal_amount().add(sellInfo.getAmount())); + transactions.put(toAddress,sellInfo); + }); + build.setTransactions(transactions); + rabbitTemplate.convertAndSend(PAY_AUTO_QUEUE, build); + }); + } + /** * 一些校验失败的支付消息需要重新发送 */ - @Scheduled(cron = "0 0/5 * * * ? ") + @Scheduled(cron = "0 0 0/1 * * ? ") @Transactional public void checkPushFailPayMessage(){ //查找出状态为三 消息发送失败的订单 再次发送支付消息。直到成功为止 @@ -393,16 +465,16 @@ public class OrderAndPayTask { .sign(HashUtils.sha256(l)) .timestamp(l) .build(); - List transactions = itemList.stream() + Map payMap = itemList.stream() .map(orderInfo -> RabbitmqPayAutoInfoMessage.builder() - .order_id(orderInfo.getOrderId()) - .amount(orderInfo.getAmount()) - .blockAmount(orderInfo.getBlockAmount()) - .shopId(orderInfo.getShopId()) - .userId(orderInfo.getUserId()) - .build()) - .collect(Collectors.toList()); - build.setTransactions(transactions); + .to_address(orderInfo.getToAddress()) + .amount(orderInfo.getAmount()) + .blockAmount(orderInfo.getBlockAmount()) + .shopId(orderInfo.getShopId()) + .userId(orderInfo.getUserId()) + .build()) + .collect(Collectors.toMap(RabbitmqPayAutoInfoMessage::getTo_address, Function.identity())); + build.setTransactions(payMap); try { rabbitTemplate.convertAndSend(PAY_AUTO_QUEUE, build); List updates = itemList.stream().peek(record -> record.setStatus(2)).collect(Collectors.toList()); diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/OwnProductTask.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/OwnProductTask.java index a4cd8bd..d719056 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/OwnProductTask.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/OwnProductTask.java @@ -28,6 +28,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; import java.util.stream.Collectors; import static com.m2pool.lease.constant.RabbitmqConstant.POOL_PROXY_QUEUE_NAME; @@ -138,7 +139,7 @@ public class OwnProductTask { //@Scheduled(cron = "0 35 0/1 * * ? ") - @Scheduled(cron = "0 0/5 * * * ? ") + @Scheduled(cron = "30 0/5 * * * ? ") @DSTransactional public void updateNexaIncomeTask(){ List updateList = computeIncome("nexa"); @@ -148,7 +149,7 @@ public class OwnProductTask { } //@Scheduled(cron = "10 35 0/1 * * ? ") - @Scheduled(cron = "0 0/5 * * * ? ") + @Scheduled(cron = "30 0/5 * * * ? ") @DSTransactional public void updateGrsIncomeTask(){ List updateList = computeIncome("grs"); @@ -157,7 +158,7 @@ public class OwnProductTask { } //@Scheduled(cron = "20 35 0/1 * * ? ") - @Scheduled(cron = "0 0/5 * * * ? ") + @Scheduled(cron = "30 0/5 * * * ? ") @DSTransactional public void updateRxdIncomeTask(){ List updateList = computeIncome("rxd"); @@ -166,7 +167,7 @@ public class OwnProductTask { } //@Scheduled(cron = "30 35 0/1 * * ? ") - @Scheduled(cron = "0 0/5 * * * ? ") + @Scheduled(cron = "30 0/5 * * * ? ") @DSTransactional public void updateMonaIncomeTask(){ List updateList = computeIncome("mona"); @@ -189,30 +190,32 @@ public class OwnProductTask { //1. 查询在有效期内的已购机器 LambdaQueryWrapper wrapper = new LambdaQueryWrapper() .eq(LeaseUserOwnedProduct::getCoin, coin) - .le(LeaseUserOwnedProduct::getStartTime, startOfDay) - .gt(LeaseUserOwnedProduct::getEndTime, startOfDay); + .eq(LeaseUserOwnedProduct::getStatus, 0); List leaseUserOwnedProducts = leaseUserOwnedProductMapper.selectList(wrapper); - - - //2.获取近一个小时矿机的收益 +并计算实时收益 + System.out.println("个人收益--矿机: " + JSONUtil.toJsonPrettyStr(leaseUserOwnedProducts)); + //2.获取近一个小时矿机的收益 + 并计算实时收益 List updateList = new ArrayList<>(); if (!leaseUserOwnedProducts.isEmpty()){ Map collect = new HashMap<>(); Set orderInfoIds = new HashSet<>(); for (LeaseUserOwnedProduct item : leaseUserOwnedProducts) { - collect.put(item.getUser() + "_" + item.getMiner() + "-" + item.getCoin(), item); + collect.put(item.getUser() + "-" + item.getMiner() + "-" + item.getCoin(), item); orderInfoIds.add(item.getOrderId()); } //2.1 查询当天已支付订单 - Map recordStatus = leasePayRecordMessageMapper.selectOrderInfoMap(orderInfoIds); + //查询订单详情对应的信息formAddress + fromChain + fromSymbol + toAddress + toChain + toSymbol + List leaseOrderItems = leaseOrderItemMapper.getOrderItemByOrderIds(orderInfoIds); + Map collect1 = leaseOrderItems.stream().collect(Collectors.toMap(item -> item.getUser() + "-" + item.getMiner() + "-" + item.getCoin(), Function.identity())); List incomeDtos = leaseUserOwnedProductMapper.getHourIncomeList(leaseUserOwnedProducts,coin, start, end); - for (HourIncomeDto hourIncomeDto : incomeDtos) { - LeaseUserOwnedProduct leaseUserOwnedProduct = collect.get(hourIncomeDto.getUser() + "_" + hourIncomeDto.getMiner()+ "-" + coin) ; - LeasePayRecordMessage leasePayRecordMessage = recordStatus.get(leaseUserOwnedProduct.getOrderId()); - if (leasePayRecordMessage != null && leasePayRecordMessage.getStatus() == 1){ + String key = hourIncomeDto.getUser() + "-" + hourIncomeDto.getMiner()+ "-" + coin; + System.out.println("个人收益--矿机详情: " + key); + LeaseUserOwnedProduct leaseUserOwnedProduct = collect.get(key) ; + LeaseOrderItem leaseOrderItem = collect1.get(key); + System.out.println("个人收益--订单详情: " + JSONUtil.toJsonPrettyStr(leaseOrderItem)); + if (leaseOrderItem != null && leaseOrderItem.getStatus() == 1){ BigDecimal coinIncome = hourIncomeDto.getIncome().add(leaseUserOwnedProduct.getCurrentIncome()); BigDecimal usdtIncome = hourIncomeDto.getUsdtIncome().add(leaseUserOwnedProduct.getCurrentUsdtIncome()); //当日待结算收益不为0,把待结算收益加到当前收益中 @@ -229,6 +232,11 @@ public class OwnProductTask { leaseUserOwnedProduct.setSettleIncome(hourIncomeDto.getIncome().add(leaseUserOwnedProduct.getSettleIncome())); leaseUserOwnedProduct.setSettleUsdtIncome(hourIncomeDto.getUsdtIncome().add(leaseUserOwnedProduct.getSettleUsdtIncome())); } + if (now.equals(startOfDay)){ + leaseUserOwnedProduct.setSettleIncome(BigDecimal.ZERO); + leaseUserOwnedProduct.setSettleUsdtIncome(BigDecimal.ZERO) ; + } + updateList.add(leaseUserOwnedProduct); } } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/RealPowerInsetTask.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/RealPowerInsetTask.java new file mode 100644 index 0000000..cc7dcdd --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/RealPowerInsetTask.java @@ -0,0 +1,109 @@ +package com.m2pool.lease.task; + +import com.baomidou.dynamic.datasource.annotation.DSTransactional; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.m2pool.lease.dto.ProductMachineDto; +import com.m2pool.lease.entity.LeaseProductMachine; +import com.m2pool.lease.mapper.LeaseProductMachineMapper; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicReference; + +/** + * @Description TODO + * @Date 2025/11/7 14:16 + * @Author yyb + */ +@Configuration +@EnableScheduling +public class RealPowerInsetTask { + + @Resource + private LeaseProductMachineMapper leaseProductMachineMapper; + + private static final int BATCH_SIZE = 1000; + private static final int THREAD_POOL_SIZE = Runtime.getRuntime().availableProcessors(); + private final ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE); + public void batchInsert(String coin,List recentlyFiveMinutesData) { + // 用于记录执行过程中的异常 + AtomicReference exceptionRef = new AtomicReference<>(); + List> futures = new ArrayList<>(); + + for (int i = 0; i < recentlyFiveMinutesData.size(); i += BATCH_SIZE) { + int toIndex = Math.min(i + BATCH_SIZE, recentlyFiveMinutesData.size()); + List subList = recentlyFiveMinutesData.subList(i, toIndex); + + CompletableFuture future = CompletableFuture.runAsync(() -> { + try { + leaseProductMachineMapper.batchInsertPowers(coin, subList); + } catch (Exception e) { + exceptionRef.set(e); + throw new RuntimeException(e); + } + }, executorService); + + futures.add(future); + } + // 等待所有任务完成 + CompletableFuture allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + try { + allFutures.get(); + } catch (InterruptedException | ExecutionException e) { + // 如果有异常,将异常信息设置到 exceptionRef 中 + exceptionRef.set(e); + } + + // 如果有异常,抛出异常触发事务回滚 + if (exceptionRef.get() != null) { + System.out.println("批量插入数据实时算力数据出错"+exceptionRef.get()); + throw new RuntimeException("批量插入数据实时算力数据出错", exceptionRef.get()); + } + } + + public List getRealPower(String coin){ + List leaseProductMachines = leaseProductMachineMapper.selectList(new LambdaQueryWrapper() + .eq(LeaseProductMachine::getDel, false)); + return leaseProductMachineMapper.getRecentlyFiveMinutesData(leaseProductMachines, coin); + } + + + @Scheduled(cron = "0 0/5 * * * ? ") + @DSTransactional + public void nexaRealPowerInset(){ + List nexaPower = getRealPower("nexa"); + batchInsert("nexa",nexaPower); + + } + + @Scheduled(cron = "0 0/5 * * * ? ") + @DSTransactional + public void monaRealPowerInset(){ + List monaPower = getRealPower("mona"); + batchInsert("mona",monaPower); + } + + @Scheduled(cron = "0 0/5 * * * ? ") + @DSTransactional + public void rxdRealPowerInset(){ + List rxdPower = getRealPower("mona"); + batchInsert("rxd",rxdPower); + } + + @Scheduled(cron = "0 0/5 * * * ? ") + @DSTransactional + public void grsRealPowerInset(){ + List rxdPower = getRealPower("grs"); + batchInsert("grs",rxdPower); + } + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/QrCodeUtils.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/QrCodeUtils.java index 989452f..d1056ce 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/QrCodeUtils.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/QrCodeUtils.java @@ -13,6 +13,8 @@ import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.Hashtable; /** @@ -89,7 +91,7 @@ public class QrCodeUtils { } public static void main(String[] args) { - System.out.println(creatRrCode("0x1c3d5d2a0eeb78476bcefadb44fbf24d29eeb964", 200,200)); + //System.out.println(creatRrCode("0x1c3d5d2a0eeb78476bcefadb44fbf24d29eeb964", 200,200)); } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/OrderAndCodeVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/OrderAndCodeVo.java index 485624e..c0853a9 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/OrderAndCodeVo.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/OrderAndCodeVo.java @@ -20,14 +20,6 @@ import java.util.List; @ApiModel(description = "订单结算及谷歌验证码请求对象",value = "OrderAndCodeVo" ) public class OrderAndCodeVo { - @ApiModelProperty(value = "支付币种",required = true) - private String coin; - - @ApiModelProperty(value = "链名称",required = true) - private String chain; - - @ApiModelProperty(value = "币价",required = true) - private BigDecimal price; @ApiModelProperty(value = "谷歌验证码",required = true) private Long code; diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/OrderInfoVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/OrderInfoVo.java index b7d325e..9dce327 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/OrderInfoVo.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/OrderInfoVo.java @@ -37,4 +37,13 @@ public class OrderInfoVo extends BaseVo{ @ApiModelProperty(value = "租赁时长",example = "1") private Integer leaseTime; + @ApiModelProperty(value = "支付币种",required = true) + private String coin; + + @ApiModelProperty(value = "链名称",required = true) + private String chain; + + //@ApiModelProperty(value = "币价",required = true) + //private BigDecimal price; + } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductMachineParamsVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductMachineParamsVo.java index 556ef09..bd8e9ce 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductMachineParamsVo.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductMachineParamsVo.java @@ -43,11 +43,6 @@ public class ProductMachineParamsVo{ @ApiModelProperty(value = "机器成本价格单位$ [ 功耗 * 电费 * 24 * (1 + 收益率) ]",example = "0.01") private BigDecimal cost; - //@ApiModelProperty(value = "电费",example = "0.01") - //private BigDecimal electricityBill; - - //@ApiModelProperty(value = "收益率",example = "0.01") - //private BigDecimal incomeRate; @ApiModelProperty(value = "最大可租借天数(默认七天)",example = "7") private Integer maxLeaseDays; diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductMachineURDVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductMachineURDVo.java index a072613..bd561cc 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductMachineURDVo.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductMachineURDVo.java @@ -1,5 +1,6 @@ package com.m2pool.lease.vo; +import com.m2pool.lease.dto.MachinePayTypeDto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; @@ -8,6 +9,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import java.math.BigDecimal; +import java.util.List; /** *

@@ -63,4 +65,6 @@ public class ProductMachineURDVo extends BaseVo{ @ApiModelProperty(value = "功耗",example = "0.01") private BigDecimal powerDissipation; + @ApiModelProperty(value = "币种价格配置") + private List priceList; } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductMachineVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductMachineVo.java new file mode 100644 index 0000000..3a474a1 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductMachineVo.java @@ -0,0 +1,67 @@ +package com.m2pool.lease.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + *

+ * 首页商品详情页矿机列表请求对象 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "首页商品详情页矿机列表请求对象",value = "ProductMachineVo" ) +public class ProductMachineVo extends PageVo{ + + @ApiModelProperty(value = "商品 ID") + private Long id; + + + @ApiModelProperty(value = "最大实际算力") + private BigDecimal maxPower; + + @ApiModelProperty(value = "最小实际算力") + private BigDecimal minPower; + + @ApiModelProperty(value = "最大功耗 单位kw/h",example = "10") + private BigDecimal maxPowerDissipation; + + @ApiModelProperty(value = "最小功耗 单位kw/h",example = "10") + private BigDecimal minPowerDissipation; + + + @ApiModelProperty(value = "最大单价") + private BigDecimal maxPrice; + + @ApiModelProperty(value = "最小单价") + private BigDecimal minPrice; + + @ApiModelProperty(value = "币种") + private String coin; + + @ApiModelProperty(value = "链") + private String chain; + + @ApiModelProperty(value = "价格排序方式 true:降序 false:升序") + private Boolean priceSort; + + @ApiModelProperty(value = "实际算力排序方式 true:降序 false:升序") + private Boolean powerSort; + + @ApiModelProperty(value = "功耗排序方式 true:降序 false:升序") + private Boolean powerDissipationSort; + + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductUpdateMachineVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductUpdateMachineVo.java index 5d211d1..8f53aa7 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductUpdateMachineVo.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductUpdateMachineVo.java @@ -1,5 +1,6 @@ package com.m2pool.lease.vo; +import com.m2pool.lease.dto.MachinePayTypeDto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; @@ -64,6 +65,10 @@ public class ProductUpdateMachineVo { @ApiModelProperty(value = "实际价格(同一个商品下的矿机单价默认为商品表的cost字段值= 功耗 * 电费 $/度 * 24h * (1+收益率) 用户可以自定义该价格)",example = "2760.00") private BigDecimal price; + @ApiModelProperty(value = "币种价格配置") + private List priceList; + + /** * 上下架状态,0 上架,1 下架 */ diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseOrderFeeMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseOrderFeeMapper.xml new file mode 100644 index 0000000..7f53aa6 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseOrderFeeMapper.xml @@ -0,0 +1,4 @@ + + + + diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseOrderItemMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseOrderItemMapper.xml index 2e921f5..704f870 100644 --- a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseOrderItemMapper.xml +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseOrderItemMapper.xml @@ -67,6 +67,40 @@ GROUP BY order_id; + + diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeasePayRechargeMessageMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeasePayRechargeMessageMapper.xml index 03654da..f90c939 100644 --- a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeasePayRechargeMessageMapper.xml +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeasePayRechargeMessageMapper.xml @@ -39,7 +39,7 @@ from lease_pay_recharge_message FROM lease_pay_recharge_message WHERE address = #{fromAddress} AND create_time >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 6 MONTH) AND del = 0; - SELECT DISTINCT address as fromAddress,chain as fromChain,symbol as fromSymbol, true AS hasOperator FROM lease_pay_recharge_message WHERE diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeasePayRecordMessageMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeasePayRecordMessageMapper.xml index 01db70d..b4eebe3 100644 --- a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeasePayRecordMessageMapper.xml +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeasePayRecordMessageMapper.xml @@ -30,7 +30,7 @@ FROM lease_pay_record_message WHERE from_address = #{fromAddress} AND create_time >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 6 MONTH) AND del = 0; - SELECT DISTINCT from_address as fromAddress,from_chain as fromChain,from_symbol as fromSymbol, true AS hasOperator FROM lease_pay_record_message WHERE @@ -110,17 +110,15 @@ order by update_time desc limit 5 - + select + DISTINCT order_id as orderId, + queue_id as queueId + from lease_pay_record_message + where order_id in + + #{item} + diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeasePayWithdrawMessageMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeasePayWithdrawMessageMapper.xml index de70b33..8d13889 100644 --- a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeasePayWithdrawMessageMapper.xml +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeasePayWithdrawMessageMapper.xml @@ -55,7 +55,7 @@ FROM lease_pay_withdraw_message FROM lease_pay_withdraw_message WHERE from_address = #{fromAddress} AND create_time >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 6 MONTH) AND del = 0; - SELECT DISTINCT from_address as fromAddress,from_chain as fromChain,from_symbol as fromSymbol, true AS hasOperator FROM lease_pay_withdraw_message WHERE diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseProductMachineMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseProductMachineMapper.xml index a2b093f..71d027f 100644 --- a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseProductMachineMapper.xml +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseProductMachineMapper.xml @@ -53,7 +53,7 @@ lpm.del, lpm.max_lease_days as maxLeaseDays FROM - lease_product_machine lpm join lease_product lp on lp.id = lpm.product_id + lease_product_machine lpm join lease_product lp on lp.id = lpm.product_id WHERE lpm.id IN @@ -85,9 +85,7 @@ SELECT `user`, miner, - SUM(mhs * 30 * 60) as computingPower, - MAX(`date`) as endTime, - MIN(`date`) as startTime + SUM(mhs * 30 * 60) as computingPower FROM ${coin}_mhs30m WHERE @@ -106,7 +104,7 @@ - + INSERT INTO lease_product_machine ( shop_id, product_id, user, type, coin, miner, theory_power, computing_power, theory_income, unit, @@ -138,6 +136,21 @@ del = VALUES(del), max_lease_days = VALUES(max_lease_days) + + INSERT INTO ${coin}_real_power (user,miner,power,`date`) + VALUES + + ( + #{item.user}, + #{item.miner}, + #{item.computingPower}, + now() + ) + + ON DUPLICATE KEY UPDATE + power = VALUES(power), + `date` = VALUES(`date`) + + + + + diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseProductMachinePriceMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseProductMachinePriceMapper.xml new file mode 100644 index 0000000..cfd527e --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseProductMachinePriceMapper.xml @@ -0,0 +1,40 @@ + + + + + + + + + + diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseProductMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseProductMapper.xml index 60cafc1..dd6abd7 100644 --- a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseProductMapper.xml +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseProductMapper.xml @@ -74,37 +74,68 @@ - + SELECT + lp.id, + lp.shop_id AS shopId, + lp.name, + lp.image, + lp.type, + lp.state, + lp.description, + lp.algorithm, + lp.shop_id AS shopId, + lp.coin_full_name AS coinFullName, + lp.coin, + lp.sale_number AS saleNumber, + lp.total_machine_number AS totalMachineNumber, + ls.name AS shopName + FROM lease_product lp RIGHT JOIN lease_shop ls ON lp.shop_id = ls.id and ls.state = 1 + WHERE lp.del = false - AND shop_id = #{shopId} + AND lp.shop_id = #{shopId} - AND state = 0 AND total_machine_number != 0 + AND lp.state = 0 AND lp.total_machine_number != 0 AND ( ( - coin LIKE CONCAT('%', #{coin}, '%') - OR coin_full_name LIKE CONCAT('%', #{coin}, '%') + lp.coin LIKE CONCAT('%', #{coin}, '%') + OR lp.coin_full_name LIKE CONCAT('%', #{coin}, '%') ) - AND algorithm LIKE CONCAT('%', #{algorithm}, '%') + AND lp.algorithm LIKE CONCAT('%', #{algorithm}, '%') ) - AND algorithm LIKE CONCAT('%', #{algorithm}, '%') + AND lp.algorithm LIKE CONCAT('%', #{algorithm}, '%') - order by sale_number desc,create_time desc + order by lp.sale_number desc,lp.create_time desc + + + diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseShopConfigMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseShopConfigMapper.xml index fea04a5..6109f4c 100644 --- a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseShopConfigMapper.xml +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseShopConfigMapper.xml @@ -52,6 +52,14 @@ ) + diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseShopMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseShopMapper.xml index 0bedd45..f9b69ae 100644 --- a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseShopMapper.xml +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseShopMapper.xml @@ -20,8 +20,7 @@ + + + diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseShoppingCartInfoMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseShoppingCartInfoMapper.xml index d3e61ac..f56018e 100644 --- a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseShoppingCartInfoMapper.xml +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseShoppingCartInfoMapper.xml @@ -17,9 +17,11 @@ id, cart_id, product_id, product_machine_id, create_time, update_time - + select product_machine_id as productMachineId, + product_id as productId, + lease_time as leaseTime + from lease_shopping_cart_info where cart_id = #{cartId} diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseUserWalletDataMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseUserWalletDataMapper.xml index 9c52063..f601f5f 100644 --- a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseUserWalletDataMapper.xml +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseUserWalletDataMapper.xml @@ -89,6 +89,30 @@ (`from_address` = #{item.fromAddress} AND from_symbol = #{item.fromSymbol} AND from_chain = #{item.fromChain}) ) + diff --git a/m2pool-modules/m2pool-manage/src/main/java/com/m2pool/manage/utils/PayParams.java b/m2pool-modules/m2pool-manage/src/main/java/com/m2pool/manage/utils/PayParams.java new file mode 100644 index 0000000..3e183b1 --- /dev/null +++ b/m2pool-modules/m2pool-manage/src/main/java/com/m2pool/manage/utils/PayParams.java @@ -0,0 +1,40 @@ +package com.m2pool.manage.utils; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * @Description 支付接口请求参数 + * @Date 2025/8/8 13:44 + * @Author yyb + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PayParams { + /** + * 币种(USDC ,USDT) + */ + private String coin; + + /** + * 收款地址 + */ + private String address; + + /** + * 收款金额 + */ + private BigDecimal amount; + + /** + * 下单时间 + */ + private Long ts; +}