diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/M2poolLeaseApplication.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/M2poolLeaseApplication.java index 3e27c64..6799051 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/M2poolLeaseApplication.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/M2poolLeaseApplication.java @@ -3,19 +3,36 @@ package com.m2pool.lease; import com.m2pool.common.security.annotation.EnableCustomConfig; import com.m2pool.common.security.annotation.EnableM2PoolFeignClients; import com.m2pool.common.swagger.annotation.EnableCustomSwagger2; +import com.m2pool.lease.netty.server.NettyTcpServer; +import io.netty.channel.ChannelFuture; import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import javax.annotation.Resource; + @EnableCustomConfig @EnableCustomSwagger2 @EnableM2PoolFeignClients @SpringBootApplication @MapperScan({"com.m2pool.lease.mapper"}) -public class M2poolLeaseApplication { +public class M2poolLeaseApplication implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(M2poolLeaseApplication.class, args); } + @Resource + NettyTcpServer nettyTcpServer; + + + @Override + public void run(String... args) { + //启动服务端 + ChannelFuture start = nettyTcpServer.start(); + //服务端管道关闭的监听器并同步阻塞,直到channel关闭,线程才会往下执行,结束进程 + start.channel().closeFuture().syncUninterruptibly(); + } } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseOrderInfoV2Controller.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseOrderInfoV2Controller.java new file mode 100644 index 0000000..c2f003a --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseOrderInfoV2Controller.java @@ -0,0 +1,80 @@ +package com.m2pool.lease.controller; + + +import com.m2pool.lease.dto.PageResult; +import com.m2pool.lease.dto.Result; +import com.m2pool.lease.dto.UserOwnedProductDto; +import com.m2pool.lease.dto.v2.CoinAndAlgorithmListDto; +import com.m2pool.lease.dto.v2.MiningInfoDto; +import com.m2pool.lease.service.LeaseOrderInfoService; +import com.m2pool.lease.vo.BaseVo; +import com.m2pool.lease.vo.OrderAndCodeVo; +import com.m2pool.lease.vo.UserOwnedProductVo; +import com.m2pool.lease.vo.v2.CoinAndAlgorithmVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +/** + *

+ * 订单表 前端控制器 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Api(tags = "v2版本--订单控制器") +@RestController +@RequestMapping("/v2/order/info") +public class LeaseOrderInfoV2Controller { + + + @Resource + private LeaseOrderInfoService leaseOrderInfoService; + + @ApiOperation("算法币种选择框:购物车结算获取选中矿机支持的算法和币种列表") + @PostMapping("/getMachineSupportCoinAndAlgorithm") + public Result> getMachineSupportCoinAndAlgorithm(@RequestBody List machineIds) { + return leaseOrderInfoService.getMachineSupportCoinAndAlgorithm(machineIds); + } + + @ApiOperation("矿池选择框:根据矿机id 获取当前矿机支持的矿池币种信息") + @PostMapping("/getMachineSupportPool") + public Result> getMachineSupportPool(@RequestBody CoinAndAlgorithmVo coinAndAlgorithmVo) { + return leaseOrderInfoService.getMachineSupportPool(coinAndAlgorithmVo); + } + + @ApiOperation("创建订单及订单详情 + 支付订单(返回二维码内容)") + @PostMapping("/addOrdersV2") + public Result addOrdersV2(@RequestBody OrderAndCodeVo orderAndCodeVo) { + return leaseOrderInfoService.addOrdersV2(orderAndCodeVo); + } + + + @ApiOperation("用户查询当前自身已购商品列表") + @PostMapping("/getOwnedList") + public PageResult getOwnedList(@RequestBody(required = false) UserOwnedProductVo userOwnedProductVo) { + if (userOwnedProductVo == null){ + userOwnedProductVo = new UserOwnedProductVo(); + } + //return leaseOrderInfoService.getOwnedList(userOwnedProductVo); + return null; + + } + + + + @ApiOperation("根据id查询当前自身已购商品详情") + @PostMapping("/getOwnedById") + public Result getOwnedById(@RequestBody BaseVo baseVo) { + //return leaseOrderInfoService.getOwnedById(baseVo); + return null; + } +} + 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 5c623dc..d359e5c 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 @@ -104,18 +104,21 @@ public class LeaseProductController { @ApiOperation("查询用户店铺支持的支付方式") @PostMapping("/getSupportPayType") - @Deprecated public Result> getSupportPayType() { return leaseProductService.getSupportPayType(); } + //TODO 2025-11-21 查询店铺的矿机列表,不存在商品了 + @ApiOperation("获取店铺商品列表用于新增绑定店铺钱包") @PostMapping("/getProductListForShopWalletConfig") public Result> getProductListForShopWalletConfig() { return leaseProductService.getProductListForShopWalletConfig(); } + //TODO 2025-11-21 修改这些矿机的价格,并且绑定新钱包 + @ApiOperation("新增绑定店铺钱包并设置店铺下面每个矿机该钱包币种的售价 + 钱包绑定") @PostMapping("/updateProductListForShopWalletConfig") public Result updateProductListForShopWalletConfig(@RequestBody ProductMachineForWalletConfigVo 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 e63ada5..09ac4e6 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 @@ -35,6 +35,7 @@ public class LeaseProductMachineController { @Resource private LeaseProductMachineService leaseProductMachineService; + @ApiOperation("根据 登录账户 获取挖矿账户及挖矿币种集合----用于用户为商品添加实际出售机器库存") @PostMapping("/getUserMinersList") public Result>> getUserMinersList(@RequestBody UserMinerVo userMinerVo) { diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductMachineV2Controller.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductMachineV2Controller.java new file mode 100644 index 0000000..9586cb3 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductMachineV2Controller.java @@ -0,0 +1,96 @@ +package com.m2pool.lease.controller; + + +import com.m2pool.lease.dto.*; +import com.m2pool.lease.dto.v2.MachineInfoDto; +import com.m2pool.lease.dto.v2.SellerMachineInfoDto; +import com.m2pool.lease.dto.v2.ShopInfoDto; +import com.m2pool.lease.service.LeaseMachineService; +import com.m2pool.lease.vo.*; +import com.m2pool.lease.vo.v2.*; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + *

+ * 商品表对应的物品机器表 前端控制器 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Api(tags = "v2版本--矿机控制器类") +@RestController +@RequestMapping("/v2/product/machine") +public class LeaseProductMachineV2Controller { + + + @Resource + private LeaseMachineService leaseMachineService; + + @ApiOperation("商城首页---店铺列表") + @PostMapping("/getShopList") + public PageResult getShopList(@RequestBody(required = false) ProductPageVo productPageVo) { + if(productPageVo == null){ + productPageVo = new ProductPageVo(); + } + return leaseMachineService.getShopList(productPageVo); + } + + + @ApiOperation("商城首页---店铺对应矿机详情列表") + @PostMapping("/getShopMachineList") + public PageResult getShopMachineList(@RequestBody ShopMachineVo shopMachineVo) { + return leaseMachineService.getShopMachineList(shopMachineVo); + } + + @ApiOperation("卖家页面---矿机列表") + @PostMapping("/getShopMachineListForSeller") + public PageResult getShopMachineListForSeller(@RequestBody(required = false) SellerMachineVo sellerMachineVo) { + if (sellerMachineVo == null) { + sellerMachineVo = new SellerMachineVo(); + } + return leaseMachineService.getShopMachineListForSeller(sellerMachineVo); + } + + @ApiOperation("卖家页面---新增ASIC矿机") + @PostMapping("/addAsicMachine") + public Result addAsicMachine(@RequestBody AsicMachineParamsVo asicMachineParamsVo) { + return leaseMachineService.addAsicMachine(asicMachineParamsVo); + } + + @ApiOperation("卖家页面---修改ASIC矿机") + @PostMapping("/updateAsicMachine") + public Result updateAsicMachine(@RequestBody AsicMachineParamsVo asicMachineParamsVo) { + return leaseMachineService.updateAsicMachine(asicMachineParamsVo); + } + + @ApiOperation("卖家页面--- 批量修改GPU矿机 和 批量上下架") + @PostMapping("/updateGpuMachine") + public Result updateGpuMachine(@RequestBody List gpuMachineParamsVoList) { + return leaseMachineService.updateGpuMachine(gpuMachineParamsVoList); + } + + @ApiOperation("卖家页面---GPU/ASIC矿机上下架") + @PostMapping("/updateMachineState") + public Result updateMachineState(@RequestBody MachineStateVo machineStateVo) { + return leaseMachineService.updateMachineState(machineStateVo); + } + + + @ApiOperation("卖家页面---根据矿机id删除GPU/ASIC矿机") + @PostMapping("/deleteMachine") + public Result deleteMachine(@RequestBody BaseVo baseVo) { + return leaseMachineService.deleteMachine(baseVo); + } + + + + + +} + diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShopV2Controller.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShopV2Controller.java new file mode 100644 index 0000000..58096fd --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShopV2Controller.java @@ -0,0 +1,69 @@ +package com.m2pool.lease.controller; + + +import com.m2pool.lease.dto.*; +import com.m2pool.lease.dto.v2.PayWithdrawSellerRecordDto; +import com.m2pool.lease.dto.v2.ShopWalletInfoDto; +import com.m2pool.lease.service.LeaseShopService; +import com.m2pool.lease.vo.BalancePageVo; +import com.m2pool.lease.vo.BalanceVo; +import com.m2pool.lease.vo.BaseVo; +import com.m2pool.lease.vo.PageVo; +import com.m2pool.lease.vo.v2.ShopWalletInfoVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + *

+ * 店铺表 前端控制器 + *

+ * + * @author yyb + * @since 2025-08-05 + */ +@Api(tags = "v2版本--店铺控制器") +@RestController +@RequestMapping("/v2/shop") +public class LeaseShopV2Controller { + + @Resource + private LeaseShopService leaseShopService; + + /** + * 根据店铺id 查询配置信息列表 + * @param baseVo + * @return 操作结果 + */ + @ApiOperation("钱包配置----根据店铺id查询收款钱包绑定信息列表") + @PostMapping("/getShopConfigV2") + public Result> getShopConfigV2(@RequestBody BaseVo baseVo) { + return leaseShopService.getShopConfigV2(baseVo); + } + + @PostMapping("/withdrawBalanceForSeller") + @ApiOperation(value = "卖家店铺钱包余额提现") + public Result withdrawBalanceForSeller(@RequestBody BalanceVo balanceVo){ + return leaseShopService.withdrawBalanceForSeller(balanceVo); + } + + @ApiOperation("钱包配置----根据配置id 修改商铺收款钱包配置") + @PostMapping("/updateShopConfigV2") + public Result updateShopConfigV2(@RequestBody ShopWalletInfoVo shopWalletInfoVo) { + return leaseShopService.updateShopConfigV2(shopWalletInfoVo); + } + + + @PostMapping("/balanceWithdrawList") + @ApiOperation(value = "卖家:余额提现记录列表") + public PageResult balanceWithdrawList(@RequestBody PageVo pageVo){ + return leaseShopService.balanceWithdrawList(pageVo); + } + + + +} + diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShoppingCartController.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShoppingCartController.java index 0a3ff3e..c8e8488 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShoppingCartController.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShoppingCartController.java @@ -51,6 +51,12 @@ public class LeaseShoppingCartController { return leaseShoppingCartService.getGoodsList(pageVo); } + @ApiOperation("批量删除购物车中商品") + @PostMapping("/deleteBatchGoods") + public Result deleteBatchGoods(@RequestBody List baseVoList) { + return leaseShoppingCartService.deleteBatchGoods(baseVoList); + } + @ApiOperation("删除购物车中商品") @PostMapping("/deleteGoods") @Deprecated @@ -58,11 +64,6 @@ public class LeaseShoppingCartController { return leaseShoppingCartService.deleteGoods(baseVo); } - @ApiOperation("批量删除购物车中商品") - @PostMapping("/deleteBatchGoods") - public Result deleteBatchGoods(@RequestBody List baseVoList) { - return leaseShoppingCartService.deleteBatchGoods(baseVoList); - } @ApiOperation("批量删除购物车中已下架商品") @PostMapping("/deleteBatchGoodsForIsDelete") diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShoppingCartV2Controller.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShoppingCartV2Controller.java new file mode 100644 index 0000000..21c1bf9 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShoppingCartV2Controller.java @@ -0,0 +1,73 @@ +package com.m2pool.lease.controller; + + +import com.m2pool.lease.dto.PageResult; +import com.m2pool.lease.dto.Result; +import com.m2pool.lease.dto.ShopCartDto; +import com.m2pool.lease.dto.v2.ShopCartV2Dto; +import com.m2pool.lease.service.LeaseShoppingCartService; +import com.m2pool.lease.vo.BaseVo; +import com.m2pool.lease.vo.PageVo; +import com.m2pool.lease.vo.ProductAndMachineVo; +import com.m2pool.lease.vo.ShoppingCartInfoURDVo; +import com.m2pool.lease.vo.v2.AddGoodsVo; +import com.m2pool.lease.vo.v2.CartInfoVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +/** + *

+ * 购物车表 前端控制器 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Api(tags = "v2版本---购物车表控制器") +@RestController +@RequestMapping("/v2/shopping/cart") +public class LeaseShoppingCartV2Controller { + + @Resource + private LeaseShoppingCartService leaseShoppingCartService; + + @ApiOperation("添加商品到购物车(批量+单个)") + @PostMapping("/addGoodsV2") + public Result addGoodsV2(@RequestBody List addGoodsVoList) { + return leaseShoppingCartService.addGoodsV2(addGoodsVoList); + } + + @ApiOperation("查询购物车中商品列表") + @PostMapping("/getGoodsListV2") + public PageResult getGoodsListV2(@RequestBody(required = false) PageVo pageVo) { + if (pageVo == null){ + pageVo = new PageVo(); + } + return leaseShoppingCartService.getGoodsListV2(pageVo); + } + + + @ApiOperation("批量删除购物车中商品") + @PostMapping("/deleteBatchGoodsV2") + public Result deleteBatchGoodsV2(@RequestBody List baseVoList) { + return leaseShoppingCartService.deleteBatchGoodsV2(baseVoList); + } + + + @ApiOperation("批量删除购物车中已下架商品") + @PostMapping("/deleteBatchGoodsForIsDeleteV2") + public Result deleteBatchGoodsForIsDeleteV2() { + return leaseShoppingCartService.deleteBatchGoodsForIsDeleteV2(); + } + + + +} + diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseUserController.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseUserController.java index 8a8fbf1..2f32dc4 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseUserController.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseUserController.java @@ -7,12 +7,11 @@ import com.m2pool.lease.service.LeaseUserService; import com.m2pool.lease.vo.*; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import java.util.List; /** @@ -98,5 +97,18 @@ public class LeaseUserController { public Result> getCharge(){ return leaseUserService.getCharge(); } + + @GetMapping("/downloadClient") + @ApiOperation(value = "卖家:下载客户端") + public void downloadClient(@RequestParam String userEmail,HttpServletRequest request, HttpServletResponse response){ + leaseUserService.downloadClient(userEmail,request, response); + } + + @GetMapping("/getClientVersion") + @ApiOperation(value = "获取客户端版本号") + public String getClientVersion(){ + return leaseUserService.getClientVersion(); + } + } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/OrderInfoDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/OrderInfoDto.java index e7f2f78..7832b19 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/OrderInfoDto.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/OrderInfoDto.java @@ -71,6 +71,10 @@ public class OrderInfoDto { private LocalDateTime createTime; + @ApiModelProperty(value = "订单完成时间") + private LocalDateTime endTime; + + // ---------------------------------------------- 一个普通订单对应一个支付订单(多个封装下面四个字段为一个对象,并返回list)---------------------------------------------------------------------- diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/OrderItemDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/OrderItemDto.java index 92d792c..e213d67 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/OrderItemDto.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/OrderItemDto.java @@ -81,5 +81,9 @@ public class OrderItemDto { private String payCoin; + @ApiModelProperty(value = "租赁矿机数量") + private Integer numbers; + + } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/PageResult.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/PageResult.java index 2abd229..d46b4fb 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/PageResult.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/PageResult.java @@ -8,6 +8,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; +import java.util.ArrayList; import java.util.List; /** @@ -49,11 +50,18 @@ public class PageResult implements Serializable @ApiModelProperty(value = "查询结果描述", example = "成功") private String msg; + @ApiModelProperty(value = "表头信息") + private List columns; + public static PageResult success(List data) { return setPageResult(data, SUCCESS, "成功"); } + public static PageResult successColumns(List data) { + return setPageResultAndHeader(data, SUCCESS, "成功"); + } + public static PageResult fail(List data, String msg) { return setPageResult(data, FAIL, msg); @@ -67,4 +75,43 @@ public class PageResult implements Serializable rspData.setMsg("查询成功"); return rspData; } + private static PageResult setPageResultAndHeader(List data, int code, String msg) { + List columns = new ArrayList<>(); + columns.add(TableHeadersDto.builder() + .key("model") + .label("型号") + .type("text") + .fixed("left") + .width(100) + .build()); + columns.add(TableHeadersDto.builder() + .key("price") + .label("价格") + .type("amount") + .width(100) + .build()); + + columns.add(TableHeadersDto.builder() + .key("monthIncome") + .label("最大月收益") + .type("amount") + .currency("USDT") + .period("MONTH") + .width(110) + .build()); + + columns.add(TableHeadersDto.builder() + .key("maxLeaseDays") + .label("最大租赁天数") + .type("days") + .width(80) + .build()); + + PageResult rspData = new PageResult(); + rspData.setColumns(columns); + rspData.setCode(SUCCESS); + rspData.setRows(data); + rspData.setMsg("查询成功"); + return rspData; + } } 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 9c17688..75ac525 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 @@ -29,65 +29,44 @@ public class ProductMachineDto { @ApiModelProperty(value = "矿机ID") private Long id; + @ApiModelProperty(value = "购物车详情id") + private Long cartInfoId; @ApiModelProperty(value = "店铺id") private Long shopId; - /** - * 商品 ID - */ @ApiModelProperty(value = "商品 ID") private Long productId; - /** - * 挖矿机器 对应的矿工账号 - */ @ApiModelProperty(value = "挖矿机器 对应的矿工账号") private String user; - /** - * 挖矿机器型号 - */ + @ApiModelProperty(value = "挖矿机器型号") private String type; - /** - * 挖矿机器编号 - */ @ApiModelProperty(value = "挖矿机器编号") private String miner; - /** - * 单价 - */ + @ApiModelProperty(value = "单价") private BigDecimal price; - /** - * 实际算力(计算得到,商家不能够自己添加和修改) - */ + @ApiModelProperty(value = "3天算力平均大小---实际实时算力(计算得到,商家不能够自己添加和修改)") private BigDecimal computingPower; - /** - * 理论算力 - */ + @ApiModelProperty(value = "理论算力(卖方手动填写)") private BigDecimal theoryPower; @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; @@ -97,9 +76,7 @@ public class ProductMachineDto { @ApiModelProperty(value = "机器算力最近记录的一次时间") private LocalDateTime endTime; - /** - * 单机理论收入 - */ + @ApiModelProperty(value = "单机理论收入(每日) 单位币种") private BigDecimal theoryIncome; diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ShopDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ShopDto.java index b44f49c..b445851 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ShopDto.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/ShopDto.java @@ -8,6 +8,8 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import java.math.BigDecimal; + /** *

* 店铺表 @@ -54,4 +56,8 @@ public class ShopDto { */ @ApiModelProperty(value = "逻辑删除字段") private Boolean del; + + + @ApiModelProperty(value = "店铺手续费比例 范围0.01-0.1",example = "0.01") + private BigDecimal feeRate; } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/TableHeadersDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/TableHeadersDto.java new file mode 100644 index 0000000..9409807 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/TableHeadersDto.java @@ -0,0 +1,66 @@ +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; + +/** + * @Description 表头信息 + * @Date 2025/11/28 13:31 + * @Author yyb + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "表头信息",value = "TableHeadersDto" ) +public class TableHeadersDto { + + /** + * 动态列第几列 + */ + @ApiModelProperty(value = "动态列第几列") + private String key; + + /** + * 列名 + */ + @ApiModelProperty(value = "列名") + private String label; + + /** + * 类型 text/amount/hashrate/days + */ + @ApiModelProperty(value = "类型 text/amount/hashrate/days") + private String type; + + /** + * 固定列 left/right/不传 + */ + @ApiModelProperty(value = "固定列 left/right/不传") + private String fixed; + + @ApiModelProperty(value = "价格单位") + private String currency; + + @ApiModelProperty(value = "时间间隔") + private String period; + + /** + * 算力单位 + */ + @ApiModelProperty(value = "算力单位") + private String unit; + + @ApiModelProperty(value = "图标") + private String icon; + + /** + * 宽度 + */ + @ApiModelProperty(value = "宽度") + private Integer width; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/AlgorithmShopIdMapDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/AlgorithmShopIdMapDto.java new file mode 100644 index 0000000..8f134c6 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/AlgorithmShopIdMapDto.java @@ -0,0 +1,30 @@ +package com.m2pool.lease.dto.v2; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * 商品列表分页请求对象 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "商品对应算法",value = "AlgorithmShopIdMapDto" ) +public class AlgorithmShopIdMapDto { + + + @ApiModelProperty(value = "店铺id",example = "1") + private Long shopId; + + @ApiModelProperty(value = "算法") + private String algorithm; + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/AsicCoinAndAlgoDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/AsicCoinAndAlgoDto.java new file mode 100644 index 0000000..2204246 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/AsicCoinAndAlgoDto.java @@ -0,0 +1,44 @@ +package com.m2pool.lease.dto.v2; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + *

+ * 机器参数请求对象 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "asic 矿机新增 算力,币种返回对象",value = "AsicCoinAndAlgoDto" ) +public class AsicCoinAndAlgoDto { + + @ApiModelProperty(value = "币种算力配置id") + private Long coinAndPowerId; + + @ApiModelProperty(value = "矿机id(忽略)") + private Long productMachineId; + + @ApiModelProperty(value = "币种(多个逗号隔开)") + private String coin; + + @ApiModelProperty(value = "算法(多个逗号隔开)") + private String algorithm; + + @ApiModelProperty(value = "理论算力)",example = "0.01") + private BigDecimal theoryPower; + + @ApiModelProperty(value = "商品机器单机算力单位",example = "TH/S") + private String unit; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/CartMachineInfoDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/CartMachineInfoDto.java new file mode 100644 index 0000000..3b7d1f2 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/CartMachineInfoDto.java @@ -0,0 +1,108 @@ +package com.m2pool.lease.dto.v2; + +import com.m2pool.lease.dto.MachinePayTypeDto; +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 = "CartMachineInfoDto" ) +public class CartMachineInfoDto{ + + @ApiModelProperty(value = "矿机ID") + private Long id; + + @ApiModelProperty(value = "购物车详情id") + private Long cartInfoId; + + @ApiModelProperty(value = "店铺id") + private Long shopId; + + @ApiModelProperty(value = " gpu名称型号 或asic 名称型号") + private String name; + + @ApiModelProperty(value = "矿工账号 (gpu)") + private String user; + + @ApiModelProperty(value = "矿机型号 0 ASIC 1 GPU") + private Integer type; + + @ApiModelProperty(value = "矿机编号(gpu)") + private String miner; + + + @ApiModelProperty(value = "上下架状态,0 上架,1 下架") + private Integer state; + + @ApiModelProperty(value = "售出状态 0未售出 1已售出") + private Integer saleState; + + + @ApiModelProperty(value = "最大可租借天数(默认七天)",example = "7") + private Integer maxLeaseDays; + + @ApiModelProperty(value = "是否删除 0否 1是") + private Integer del; + + + @ApiModelProperty(value = "最大月收益 usdt") + private BigDecimal monthIncome; + + @ApiModelProperty(value = "最大收益币种功耗 单位kw/h",example = "10") + private BigDecimal powerDissipation; + + @ApiModelProperty(value = "理论算力(卖方手动填写)") + private BigDecimal theoryPower; + + @ApiModelProperty(value = "最大收益币种算力单位") + private String unit; + + @ApiModelProperty(value = "最大收益币种算法") + private String algorithm; + + @ApiModelProperty(value = "售价") + private BigDecimal price; + + @ApiModelProperty(value = "最大收益对应币种") + private String coin; + + @ApiModelProperty(value = "租赁天数") + private Integer leaseTime; + + private Long configId; + + @ApiModelProperty(value = "支付币种") + private String payCoin; + + @ApiModelProperty(value = "asic 租赁数量") + private Integer numbers; + + @ApiModelProperty(value = "矿机客户端在离线情况 0 离线 1 在线") + private Boolean onlineStatus; + + @ApiModelProperty(value = "可售数量") + private Integer canSaleNumbers; + + @ApiModelProperty(value = "gpu和asic对应币种算力和月收益信息") + private List powerIncomeInfoList; + + @ApiModelProperty(value = "店铺售价集合") + private List priceList; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/CoinAndAlgorithmDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/CoinAndAlgorithmDto.java new file mode 100644 index 0000000..a33aa68 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/CoinAndAlgorithmDto.java @@ -0,0 +1,35 @@ +package com.m2pool.lease.dto.v2; + + +import com.m2pool.lease.dto.PageResult; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class CoinAndAlgorithmDto { + + /** + * 币种名称 + */ + private String coin; + + /** + * 算法名称 + */ + private String algorithm; + + /** + * 矿机id,多个已逗号隔开 + */ + private String machineIds; + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/CoinAndAlgorithmListDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/CoinAndAlgorithmListDto.java new file mode 100644 index 0000000..c961d8f --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/CoinAndAlgorithmListDto.java @@ -0,0 +1,39 @@ +package com.m2pool.lease.dto.v2; + + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@ApiModel(description = "币种算法返回对象",value = "CoinAndAlgorithmListDto") +public class CoinAndAlgorithmListDto { + + + @ApiModelProperty(value = "币种") + private String coin; + + @ApiModelProperty(value = "币种对应算法返回对象") + private List algorithmList; + + @Data + @ApiModel(description = "币种对应算法返回对象",value = "AlgorithmListDto") + public static class AlgorithmListDto{ + @ApiModelProperty(value = "算法") + private String algorithm; + + @ApiModelProperty(value = "支持该算法的矿机id集合") + private List machineIds; + } + + + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/GpuConfigDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/GpuConfigDto.java new file mode 100644 index 0000000..937b39b --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/GpuConfigDto.java @@ -0,0 +1,39 @@ +package com.m2pool.lease.dto.v2; + +import com.m2pool.lease.dto.MachinePayTypeDto; +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 = "gpu公共配置返回对象",value = "GpuConfigDto" ) +public class GpuConfigDto { + + + + @ApiModelProperty(value = "gpu名称/型号") + private String name; + + @ApiModelProperty(value = "gpu品牌") + private String brand; + + private Integer memory; + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MachineInfoDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MachineInfoDto.java new file mode 100644 index 0000000..1391d5f --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MachineInfoDto.java @@ -0,0 +1,101 @@ +package com.m2pool.lease.dto.v2; + +import com.m2pool.lease.dto.MachinePayTypeDto; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +import java.math.BigDecimal; +import java.util.List; + +/** + *

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

+ * + * @author yyb + * @since 2025-07-23 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "矿机返回对象",value = "MachineInfoDto" ) +public class MachineInfoDto { + + + private Integer type; + + private BigDecimal theoryPower; + + + @ApiModelProperty(value = "矿机ID") + private Long id; + + @ApiModelProperty(value = "gpu名称 或asic 名称") + private String model; + + @ApiModelProperty(value = "矿机mac地址") + private String hostMac; + + @ApiModelProperty(value = "上下架状态,0 上架,1 下架") + private Integer state; + + @ApiModelProperty(value = "售出状态 0未售出 1已售出") + private Integer saleState; + + + @ApiModelProperty(value = "最大可租借天数(默认七天)",example = "7") + private Integer maxLeaseDays; + + @ApiModelProperty(value = "最大月收益 usdt") + private BigDecimal monthIncome; + + + @ApiModelProperty(value = "最大收益币种算法") + private String algorithm; + + @ApiModelProperty(value = "售价") + private BigDecimal price; + + @ApiModelProperty(value = "最大收益对应币种") + private String coin; + + @ApiModelProperty(value = "矿机客户端在离线情况 0 离线 1 在线") + private Boolean onlineStatus; + + @ApiModelProperty(value = "可出售机器数量") + private Integer saleNumbers; + + @ApiModelProperty(value = "已售出数量") + private Integer saleOutNumbers; + + //动态列名(方便前端显示) + private BigDecimal c1; + + private BigDecimal c2; + + private BigDecimal c3; + + private BigDecimal c4; + + private BigDecimal c5; + + private BigDecimal c6; + + private BigDecimal c7; + + private BigDecimal c8; + + private BigDecimal c9; + + private BigDecimal c10; + + + + //@ApiModelProperty(value = "币种动态列集合") + //private List powerIncomeInfoList; + + @ApiModelProperty(value = "店铺售价集合") + private List priceList; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MachineInfoInterface.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MachineInfoInterface.java new file mode 100644 index 0000000..fe3ea23 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MachineInfoInterface.java @@ -0,0 +1,14 @@ +package com.m2pool.lease.dto.v2; + +import java.math.BigDecimal; +import java.util.List; + +public interface MachineInfoInterface { + Integer getType(); + Long getId(); + String getCoin(); + String getAlgorithm(); + BigDecimal getTheoryPower(); + BigDecimal getMonthIncome(); + void setPowerIncomeInfoList(List powerIncomeInfoList); +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MiningCoinInfoDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MiningCoinInfoDto.java new file mode 100644 index 0000000..7ab99f3 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MiningCoinInfoDto.java @@ -0,0 +1,43 @@ +package com.m2pool.lease.dto.v2; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + * @Description 矿机对应的矿池配置信息 + * @Date 2025/11/26 14:19 + * @Author yyb + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "矿池对应币种返回对象",value = "MiningCoinInfoDto" ) +public class MiningCoinInfoDto { + @ApiModelProperty(value = "矿池配置id") + private Long coinConfigId; + + @ApiModelProperty(value = "挖矿币种") + private String coin; + + @ApiModelProperty(value = "挖矿算法") + private String algorithm; + + @ApiModelProperty(value = "挖矿地址 TCP GPU") + private String miningTcpGpuUrl; + + @ApiModelProperty(value = "分配模式名") + private String modelName; + + @ApiModelProperty(value = "分配模式手续费") + private BigDecimal modelFee; + + @ApiModelProperty(value = "是否支持钱包支付0 不支持 1 支持") + private Boolean walletMining; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MiningConfigDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MiningConfigDto.java new file mode 100644 index 0000000..cfdd008 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MiningConfigDto.java @@ -0,0 +1,46 @@ +package com.m2pool.lease.dto.v2; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @Description 矿机对应的矿池配置信息 + * @Date 2025/11/26 14:19 + * @Author yyb + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class MiningConfigDto { + + @ApiModelProperty(value = "挖矿币种") + private String coin; + + @ApiModelProperty(value = "挖矿算法") + private String algo; + + @ApiModelProperty(value = "矿池名称") + private String pool; + + @ApiModelProperty(value = "是否支持钱包挖矿 0 不支持 1支持") + private Boolean wallet_mining; + + @ApiModelProperty(value = "挖矿地址") + private String pool_url; + + @ApiModelProperty(value = "收款钱包") + private String wallet_address; + + @ApiModelProperty(value = "挖矿账户") + private String pool_user; + + @ApiModelProperty(value = "矿工号") + private String worker_id; + + @ApiModelProperty(value = "挖矿结束时间") + private Long end_timestamp; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MiningConfigSelectDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MiningConfigSelectDto.java new file mode 100644 index 0000000..fcb17a0 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MiningConfigSelectDto.java @@ -0,0 +1,49 @@ +package com.m2pool.lease.dto.v2; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + * @Description 矿机对应的矿池配置信息 + * @Date 2025/11/26 14:19 + * @Author yyb + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class MiningConfigSelectDto { + + + @ApiModelProperty(value = "矿池配置id") + private Long coinConfigId; + + @ApiModelProperty(value = "矿池id") + private Long poolId; + + @ApiModelProperty(value = "挖矿币种") + private String coin; + + @ApiModelProperty(value = "挖矿算法") + private String algorithm; + + @ApiModelProperty(value = "矿池名称") + private String poolName; + + @ApiModelProperty(value = "是否支持钱包支付0 不支持 1 支持") + private Boolean walletMining; + + @ApiModelProperty(value = "挖矿地址 TCP GPU") + private String miningTcpGpuUrl; + + @ApiModelProperty(value = "分配模式名") + private String modelName; + + @ApiModelProperty(value = "分配模式手续费") + private BigDecimal modelFee; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MiningInfoDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MiningInfoDto.java new file mode 100644 index 0000000..7b2ca45 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/MiningInfoDto.java @@ -0,0 +1,31 @@ +package com.m2pool.lease.dto.v2; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @Description 矿机对应的矿池配置信息 + * @Date 2025/11/26 14:19 + * @Author yyb + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "矿池列表返回对象",value = "MiningInfoDto" ) +public class MiningInfoDto { + @ApiModelProperty(value = "矿池id") + private Long poolId; + + @ApiModelProperty(value = "矿池名称") + private String poolName; + + @ApiModelProperty(value = "矿池支持对应币种信息") + private List miningCoinInfoList; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/OrderMiningInfoDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/OrderMiningInfoDto.java new file mode 100644 index 0000000..ce62121 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/OrderMiningInfoDto.java @@ -0,0 +1,43 @@ +package com.m2pool.lease.dto.v2; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @Description 矿机对应的矿池配置信息 + * @Date 2025/11/26 14:19 + * @Author yyb + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "矿池列表返回对象",value = "OrderMiningInfoDto" ) +public class OrderMiningInfoDto { + @ApiModelProperty(value = "矿池名称") + private String poolName; + + @ApiModelProperty(value = "矿池配置id") + private Long coinConfigId; + + @ApiModelProperty(value = "是否钱包挖矿 0 不支持 1 支持") + private Boolean walletMining; + + @ApiModelProperty(value = "矿机id列表") + private List machineIds; + + @ApiModelProperty(value = "挖矿钱包(用户自己输入)") + private String walletAddress; + + @ApiModelProperty(value = "挖矿账号(用户自己输入)") + private String poolUser; + + @ApiModelProperty(value = "矿工号(用户自己输入)") + private String workerId; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/PayWithdrawSellerRecordDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/PayWithdrawSellerRecordDto.java new file mode 100644 index 0000000..a4abac5 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/PayWithdrawSellerRecordDto.java @@ -0,0 +1,77 @@ +package com.m2pool.lease.dto.v2; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + *

+ * 余额提现返回对象 + *

+ * + * @author yyb + * @since 2025-09-10 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "店铺钱包提现记录返回信息",value = "PayWithdrawSellerRecordDto" ) +public class PayWithdrawSellerRecordDto { + + private Long id; + + + + @ApiModelProperty(value = "用户充值地址") + private String fromAddress; + + @ApiModelProperty(value = "提现地址(用户自定义)") + private String toAddress; + + + @ApiModelProperty(value = "提现金额") + private BigDecimal amount; + + /** + * 币种 + */ + @ApiModelProperty(value = "币种") + private String symbol; + + /** + * 链名称 + */ + @ApiModelProperty(value = "链名称") + private String chain; + + /** + * 充值时间 + */ + @ApiModelProperty(value = "提现时间") + private LocalDateTime createTime; + + /** + * 更新时间 + */ + @ApiModelProperty(value = "提现完成时间") + private LocalDateTime updateTime; + + /** + * 0 支付失败 1 支付成功 2 支付中 + */ + @ApiModelProperty(value = "记录状态 提现业务: 0 提现失败 1 提现成功 2 提现中 3 校验失败") + private Integer status; + + /** + * 交易hash + */ + @ApiModelProperty(value = "交易hash") + private String txHash; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/PowerIncomeInfoDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/PowerIncomeInfoDto.java new file mode 100644 index 0000000..d7758fb --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/PowerIncomeInfoDto.java @@ -0,0 +1,50 @@ +package com.m2pool.lease.dto.v2; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + *

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

+ * + * @author yyb + * @since 2025-07-23 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "gpu配置信息返回对象",value = "PowerIncomeInfoDto" ) +public class PowerIncomeInfoDto { + + @ApiModelProperty(value = "币种") + private String coin; + + //@ApiModelProperty(value = "算法") + //private String algorithm; + + @ApiModelProperty(value = "算力") + private BigDecimal power; + + @ApiModelProperty(value = "月收益") + private BigDecimal monthIncome; + + //@ApiModelProperty(value = "功耗") + //private BigDecimal powerDissipation; + + private Long machineId; + + @ApiModelProperty(value = "算力单位") + private String unit; + + @ApiModelProperty(value = "图标") + private String icon; + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/SellerMachineInfoDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/SellerMachineInfoDto.java new file mode 100644 index 0000000..c875879 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/SellerMachineInfoDto.java @@ -0,0 +1,96 @@ +package com.m2pool.lease.dto.v2; + +import com.m2pool.lease.dto.MachinePayTypeDto; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.*; + +import java.math.BigDecimal; +import java.util.List; + +/** + *

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

+ * + * @author yyb + * @since 2025-07-23 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "卖家矿机列表返回对象",value = "SellerMachineInfoDto" ) +public class SellerMachineInfoDto { + + @ApiModelProperty(value = "矿机ID") + private Long id; + + @ApiModelProperty(value = "店铺id") + private Long shopId; + + @ApiModelProperty(value = "gpu名称 或asic 名称") + private String name; + + @ApiModelProperty(value = "矿机型号 0 ASIC 1 GPU") + private Integer type; + + @ApiModelProperty(value = "矿工账号 (gpu)") + private String user; + + @ApiModelProperty(value = "矿机编号(gpu)") + private String miner; + + @ApiModelProperty(value = "上下架状态,0 上架,1 下架") + private Integer state; + + @ApiModelProperty(value = "售出状态 0未售出 1已售出") + private Integer saleState; + + + @ApiModelProperty(value = "最大可租借天数(默认七天)",example = "7") + private Integer maxLeaseDays; + + @ApiModelProperty(value = "是否删除 0否 1是") + private Integer del; + + + @ApiModelProperty(value = "最大月收益 usdt") + private BigDecimal monthIncome; + + @ApiModelProperty(value = "最大收益币种功耗 单位kw/h",example = "10") + private BigDecimal powerDissipation; + + @ApiModelProperty(value = "最大收益币种算力(单机理论算力)") + private BigDecimal theoryPower; + + @ApiModelProperty(value = "最大收益币种算力单位") + private String unit; + + @ApiModelProperty(value = "最大收益币种算法") + private String algorithm; + + @ApiModelProperty(value = "售价") + private BigDecimal price; + + @ApiModelProperty(value = "最大收益对应币种") + private String coin; + + @ApiModelProperty(value = "可出售机器数量") + private Integer saleNumbers; + + @ApiModelProperty(value = "已售出数量") + private Integer saleOutNumbers; + + @ApiModelProperty(value = "矿机客户端在离线情况 0 离线 1 在线") + private Boolean onlineStatus; + + //@ApiModelProperty(value = "gpu和asic对应币种算力和月收益信息") + //private List powerIncomeInfoList; + + @ApiModelProperty(value = "币种算法算力信息") + private List coinAndAlgoList; + + @ApiModelProperty(value = "店铺售价集合") + private List priceList; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/ShopCartV2Dto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/ShopCartV2Dto.java new file mode 100644 index 0000000..88901b5 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/ShopCartV2Dto.java @@ -0,0 +1,48 @@ +package com.m2pool.lease.dto.v2; + +import com.m2pool.lease.dto.MachineTotalPriceDto; +import com.m2pool.lease.dto.PayConfigDto; +import com.m2pool.lease.dto.ProductMachineDto; +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-08-05 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "购物车一层商铺列表返回对象V2",value = "ShopCartV2Dto") +public class ShopCartV2Dto { + + @ApiModelProperty(value = "店铺id") + private Long id; + @ApiModelProperty(value = "店铺名称") + private String name; + @ApiModelProperty(value = "店铺下机器总价") + private BigDecimal totalPrice; + @ApiModelProperty(value = "店铺下机器总数") + private Integer totalMachine; + + @ApiModelProperty(value = "总价集合") + private List totalPriceList; + + @ApiModelProperty(value = "商品支持的支付地址") + private List payConfigList; + + @ApiModelProperty(value = "商品机器列表") + List cartMachineInfoDtoList; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/ShopInfoDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/ShopInfoDto.java new file mode 100644 index 0000000..06ef8f8 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/ShopInfoDto.java @@ -0,0 +1,58 @@ +package com.m2pool.lease.dto.v2; + +import com.m2pool.lease.dto.PayTypeDto; +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 = "ShopInfoDto" ) +public class ShopInfoDto { + + @ApiModelProperty(value = "店铺id") + private Long shopId; + + @ApiModelProperty(value = "店铺名称") + private String shopName; + + + @ApiModelProperty(value = "店铺图片") + private String image; + + @ApiModelProperty(value = "店铺描述") + private String description; + + @ApiModelProperty(value = "已售矿机数") + private Integer saleNumber; + + + @ApiModelProperty(value = "店铺售出矿机包含的类型 多个以逗号隔开",example = "gpu,asci") + private String type; + + @ApiModelProperty(value = "支持的挖矿币种",example = "NEXA,RXD") + private String coin; + + @ApiModelProperty(value = "算法 (多个算法已逗号隔开)",example = "sha256,sha512") + private String algorithm; + + @ApiModelProperty(value = "店铺支持的支付方式") + private List payTypes; + + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/ShopWalletInfoDto.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/ShopWalletInfoDto.java new file mode 100644 index 0000000..0e05974 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/dto/v2/ShopWalletInfoDto.java @@ -0,0 +1,50 @@ +package com.m2pool.lease.dto.v2; + +import com.m2pool.lease.vo.BaseVo; +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-08-05 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "店铺钱包配置返回对象",value = "ShopWalletInfoDto") +public class ShopWalletInfoDto extends BaseVo { + + + @ApiModelProperty(value = "商铺ID") + private Long shopId; + + @ApiModelProperty(value = "卖方对应收款钱包") + private String payAddress; + + @ApiModelProperty(value = "链") + private String chain; + + @ApiModelProperty(value = "商品支付方式及价格单位 取值 虚拟币( nexa rxd dgbo dgbq dgbs alph enx grs mona) 稳定币(usdt usdc busd)") + private String payCoin; + + @ApiModelProperty(value = "币种图片") + private String image; + + @ApiModelProperty(value = "余额") + private BigDecimal balance; + + @ApiModelProperty(value = "手续费") + private BigDecimal serviceCharge; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseGpuConfig.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseGpuConfig.java new file mode 100644 index 0000000..40988f0 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseGpuConfig.java @@ -0,0 +1,64 @@ +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; + +/** + *

+ * GPU对应币种挖矿算力(只要gpu类型相同那么就使用这个配置) + *

+ * + * @author yyb + * @since 2025-11-27 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class LeaseGpuConfig implements Serializable { + + private static final long serialVersionUID=1L; + + /** + * id + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * gpu品牌 + */ + private String brand; + + /** + * gpu 名称/型号 + */ + private String name; + + /** + * 0 禁用 1 启用 + */ + private Boolean status; + + /** + * 内存单位M + */ + private Integer memory; + + /** + * 功耗 单位kw/h + */ + private BigDecimal powerDissipation; + + /** + * 逻辑删除字段 + */ + private Boolean del; + + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseMachine.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseMachine.java new file mode 100644 index 0000000..76ac1e9 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseMachine.java @@ -0,0 +1,120 @@ +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; + +/** + *

+ * gpu类型出售矿机表 + *

+ * + * @author yyb + * @since 2025-11-21 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class LeaseMachine implements Serializable { + + private static final long serialVersionUID=1L; + + /** + * 主键ID + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 商铺ID + */ + private Long shopId; + + /** + * gpu 挖矿主机mac矿机编号 + */ + private String hostMac; + + /** + * 0 ASIC 1 GPU + */ + private Boolean type; + + + + /** + * 矿机最大租售天数 + */ + private Integer maxLeaseDays; + + + + /** + * 售出状态 0未售出 1已售出 + */ + private Boolean saleState; + + /** + * 上下架状态,0 上架,1 下架 + */ + private Boolean state; + + /** + * 逻辑删除字段 + */ + private Boolean del; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 矿机客户端在离线情况 0 离线 1 在线 + */ + private Boolean onlineStatus; + + /** + * 挖矿机器 对应的矿工账号(mac地址代替) + */ + private String user; + + /** + * 挖矿机器编号(gpu编号) + */ + private String miner; + + /** + * asci 类型矿机租售的台数 + */ + private Integer saleNumbers; + + /** + * asci 类型矿机已租售的台数 + */ + private Integer saleOutNumbers; + + /** + * asci 类型矿机可租售的台数 + */ + private Integer canSaleNumbers; + + /** + * asci 类型矿机已锁定的台数 乐观锁 + */ + @TableField(exist = false) + private Integer lockNumbers; + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseMachineConfig.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseMachineConfig.java new file mode 100644 index 0000000..099db1b --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseMachineConfig.java @@ -0,0 +1,99 @@ +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; + +/** + *

+ * GPU对应币种挖矿算力(只要gpu类型相同那么就使用这个配置) + *

+ * + * @author yyb + * @since 2025-11-27 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class LeaseMachineConfig implements Serializable { + + private static final long serialVersionUID=1L; + + /** + * id + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 机器id + */ + private Long machineId; + + /** + * gpu/asic品牌 + */ + private String brand; + + /** + * gpu 名称/型号 + */ + private String name; + + /** + * 内存单位M + */ + private Integer memory; + + /** + * 0 禁用 1 启用 + */ + private Boolean status; + + /** + * 支持的币种 + */ + private String coin; + + /** + * 算力 + */ + private BigDecimal hashrate; + + /** + * 算法 + */ + private String algorithm; + + /** + * 币种图片 + */ + private String icon; + + /** + * 算力单位 GH/s TH/s PH/s等 + */ + private String unit; + + /** + * 月收益usdt + */ + private BigDecimal monthIncome; + + /** + * 功耗 单位kw/h + */ + private BigDecimal powerDissipation; + + /** + * 逻辑删除字段 + */ + private Boolean del; + + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseMachinePrice.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseMachinePrice.java new file mode 100644 index 0000000..9df1eb8 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseMachinePrice.java @@ -0,0 +1,59 @@ +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; + +/** + *

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

+ * + * @author yyb + * @since 2025-11-25 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class LeaseMachinePrice implements Serializable { + + private static final long serialVersionUID=1L; + + /** + * 主键ID + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 矿机id + */ + private Long machineId; + + /** + * 实际单价 + */ + private BigDecimal price; + + /** + * 价值单位 + */ + private String coin; + + /** + * 链 + */ + private String chain; + + /** + * 逻辑删除字段 + */ + private Boolean del; + + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseMiningSoftwareConfig.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseMiningSoftwareConfig.java new file mode 100644 index 0000000..1a0642f --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseMiningSoftwareConfig.java @@ -0,0 +1,58 @@ +package com.m2pool.lease.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.*; + +import java.io.Serializable; + +/** + *

+ * 挖矿软件公共配置表 + *

+ * + * @author yyb + * @since 2025-11-27 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class LeaseMiningSoftwareConfig implements Serializable { + + private static final long serialVersionUID=1L; + + /** + * id + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 挖矿软件名 + */ + private String name; + + /** + * 挖矿软件支持的币种 + */ + private String coin; + + /** + * 算法 + */ + private String algorithm; + + /** + * 币种图片 + */ + private String icon; + + /** + * 逻辑删除字段 + */ + private Boolean del; + + +} 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 e157616..2a97d25 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 @@ -168,6 +168,8 @@ public class LeaseOrderItem implements Serializable { */ private BigDecimal settlePayRealAmount; + private Integer numbers; + /** * 商品类型 0 矿机 1 算力 */ diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseOrderMining.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseOrderMining.java new file mode 100644 index 0000000..c37f6cf --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseOrderMining.java @@ -0,0 +1,94 @@ +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.time.LocalDateTime; + +/** + *

+ * 挖矿中订单 + *

+ * + * @author yyb + * @since 2025-12-02 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class LeaseOrderMining implements Serializable { + + private static final long serialVersionUID=1L; + + /** + * id + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 订单 ID + */ + private Long orderId; + + /** + * 币种 + */ + private String coin; + + /** + * 算法 + */ + private String algorithm; + + /** + * 矿池 + */ + private String pool; + + /** + * 挖矿地址 + */ + private String poolUrl; + + /** + * 矿工号 + */ + private String workerId; + + /** + * 收款钱包 + */ + private String walletAddress; + + /** + * 挖矿信息页面 + */ + private String watchUrl; + + /** + * 0 租约已到期 1挖矿中 2等待卖家矿机启动中 + */ + private Boolean status; + + /** + * 挖矿开始时间 + */ + private LocalDateTime startTime; + + /** + * 挖矿结束时间 + */ + private LocalDateTime endTime; + + /** + * 逻辑删除字段 + */ + private Boolean del; + + +} 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 17cae9f..9f848b3 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 @@ -31,6 +31,11 @@ public class LeasePayWithdrawMessage implements Serializable { @TableId(value = "id", type = IdType.AUTO) private Long id; + /** + * 店铺ID + */ + private Long shopId; + /** * 消息ID */ diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseProduct.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseProduct.java index aa90cee..36a0c16 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseProduct.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseProduct.java @@ -52,12 +52,6 @@ public class LeaseProduct implements Serializable { */ private Integer type; - /** - * 商品矿池类型 0 自营矿池 1 非自营矿池 - */ - private Integer poolType; - - /** * 上下架状态,0 上架,1 下架 */ 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 index 77bee0e..ce17305 100644 --- 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 @@ -33,6 +33,11 @@ public class LeaseProductMachinePrice implements Serializable { private Long productMachineId; + /** + * 0 自营矿池 1 非自营矿池(gpu 和asic) + */ + private Boolean type; + private BigDecimal price; private String coin; diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseShop.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseShop.java index ae53b46..304a4e6 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseShop.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseShop.java @@ -2,9 +2,11 @@ package com.m2pool.lease.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModelProperty; import lombok.*; import java.io.Serializable; +import java.math.BigDecimal; import java.time.LocalDateTime; /** @@ -30,6 +32,11 @@ public class LeaseShop implements Serializable { @TableId(value = "id", type = IdType.AUTO) private Long id; + /** + * 店铺唯一标识码 + */ + private String identityCode; + /** * 店铺拥有者邮箱 */ @@ -70,5 +77,11 @@ public class LeaseShop implements Serializable { */ private Boolean del; + private BigDecimal feeRate; + + /** + * 售出矿机数 + */ + private Integer saleNumber; } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseShopConfig.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseShopConfig.java index eaa6d95..e7964d6 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseShopConfig.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseShopConfig.java @@ -72,6 +72,11 @@ public class LeaseShopConfig implements Serializable { */ private String qrcode; + /** + * 余额(这个余额是租赁系统的收款余额,而不是卖家钱包真实余额,该余额只能用于提现) + */ + private BigDecimal balance; + /** * 创建时间 */ 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 94d7c72..0a51d10 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,11 +30,15 @@ public class LeaseShoppingCartInfo implements Serializable { @TableId(value = "id", type = IdType.AUTO) private Long id; + /** + * 用户ID + */ + private String userId; /** - * 购物车ID + * 商店ID */ - private Long cartId; + private Long shopId; /** * 商品 ID @@ -51,6 +55,11 @@ public class LeaseShoppingCartInfo implements Serializable { */ private Integer leaseTime; + /** + * ASIC 租售台数 + */ + private Integer numbers; + /** * 创建时间 */ @@ -61,5 +70,10 @@ public class LeaseShoppingCartInfo implements Serializable { */ private LocalDateTime updateTime; + /** + * 版本 0 旧版本 1 新版本 + */ + private Integer version; + } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/exception/GlobalExceptionHandler.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/exception/GlobalExceptionHandler.java index c0d046f..8519630 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/exception/GlobalExceptionHandler.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/exception/GlobalExceptionHandler.java @@ -21,6 +21,11 @@ public class GlobalExceptionHandler { return Result.fail(e.getMessage()); } + @ExceptionHandler(MachineException.class) + public Result handleMachineException(MachineException e) { + return Result.fail(e.getMessage()); + } + @ExceptionHandler(PaymentException.class) public Result handlePaymentException(PaymentException e) { return Result.fail(e.getMessage()); diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/exception/MachineException.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/exception/MachineException.java new file mode 100644 index 0000000..bb868ac --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/exception/MachineException.java @@ -0,0 +1,10 @@ +package com.m2pool.lease.exception; + +/** + * 商品已出售异常类,用于表示在添加订单时商品已被出售的异常情况。 + */ +public class MachineException extends RuntimeException { + public MachineException(String message) { + super(message); + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseGpuConfigMapper.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseGpuConfigMapper.java new file mode 100644 index 0000000..6aa335b --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseGpuConfigMapper.java @@ -0,0 +1,27 @@ +package com.m2pool.lease.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.m2pool.lease.entity.LeaseGpuConfig; +import com.m2pool.lease.netty.message.GpuMessage; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * GPU对应币种挖矿算力(只要gpu类型相同那么就使用这个配置) Mapper 接口 + *

+ * + * @author yyb + * @since 2025-11-27 + */ +@Mapper +public interface LeaseGpuConfigMapper extends BaseMapper { + /** + * 批量插入或更新 + * @param gpuMessages + * @return + */ + int insertOrUpdate(@Param("list") List gpuMessages); +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseMachineConfigMapper.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseMachineConfigMapper.java new file mode 100644 index 0000000..f1f3261 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseMachineConfigMapper.java @@ -0,0 +1,41 @@ +package com.m2pool.lease.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.m2pool.lease.dto.v2.CoinAndAlgorithmDto; +import com.m2pool.lease.dto.v2.CoinAndAlgorithmListDto; +import com.m2pool.lease.dto.v2.MiningConfigSelectDto; +import com.m2pool.lease.entity.LeaseMachineConfig; +import com.m2pool.lease.vo.BaseVo; +import com.m2pool.lease.vo.v2.CoinAndAlgorithmVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * GPU对应币种挖矿算力(只要gpu类型相同那么就使用这个配置) Mapper 接口 + *

+ * + * @author yyb + * @since 2025-11-27 + */ +@Mapper +public interface LeaseMachineConfigMapper extends BaseMapper { + /** + * 获取配置列表 + * @param coin + * @param algorithm + * @return + */ + List getConfigList(@Param("coin") String coin,@Param("algorithm") String algorithm); + + + + /** + * 获取矿机支持的币种和算法 + * @return + */ + List getMachineSupportCoinAndAlgorithm(@Param("machineIds") List machineIds); + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseMachineMapper.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseMachineMapper.java new file mode 100644 index 0000000..26cef69 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseMachineMapper.java @@ -0,0 +1,119 @@ +package com.m2pool.lease.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.m2pool.lease.dto.MachinePayTypeDto; +import com.m2pool.lease.dto.v2.*; +import com.m2pool.lease.entity.LeaseMachine; +import com.m2pool.lease.vo.v2.SellerMachineVo; +import com.m2pool.lease.vo.v2.ShopMachineVo; +import org.apache.ibatis.annotations.MapKey; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + *

+ * gpu类型出售矿机表 Mapper 接口 + *

+ * + * @author yyb + * @since 2025-11-21 + */ +public interface LeaseMachineMapper extends BaseMapper { + + /** + * 获取店铺ids + * @return + */ + Set getShopIds(); + + /** + * 根据id集合查询店铺信息 + * @return + */ + List getExistsMachineShop(@Param("ids") Set ids, @Param("coin") String coin , @Param("algorithm") String algorithm); + + + /** + * 获取店铺对应GPU或ASIC矿机信息 + * @param shopMachineVo + * @return + */ + List getShopMachineList(@Param("shopMachineVo") ShopMachineVo shopMachineVo); + + + /** + * 根据id集合获取gpu配置信息 + * @param ids + * @return + */ + List getGpuConfigList(@Param("ids") List ids); + + + /** + * 获取店铺Gpu或Asic对应矿机信息 + * @param sellerMachineVo + * @return + */ + List getShopMachineListForSeller(@Param("sellerMachineVo") SellerMachineVo sellerMachineVo, @Param("shopId") Long shopId); + + /** + * 根据矿机id获取对应的矿机价格列表 + * @param ids + * @return + */ + List getMachinePriceList(@Param("list") List ids); + + + /** + * 根据矿机id获取对应的矿机价格列表 + * @param machineIds + * @return + */ + List getShopIdsByMachineIds(@Param("machineIds") List machineIds); + + + /** + * 获取购物车对应矿机信息 + * @param machineIds + * @return + */ + List getMachinesByIds(@Param("machineIds") List machineIds); + + + /** + * 获取购物车对应矿机信息 + * @param ids + * @return + */ + List getCoinAndAlgoList(@Param("list") List ids); + + + /** + * 修改gpu矿机售出状态 + * @param asicMachines + * @return + */ + int updateLockState(@Param("list") List asicMachines); + + + /** + * 修改asic 矿机售出数量 + * @param gpuMachines + * @return + */ + int updateLockNumbers(@Param("list") List gpuMachines); + + + + /** + * 根据id 获取配置算法和币种 + * @param ids + * @return + */ + @MapKey("id") + Map getCoinAndAlgoById(@Param("ids") List ids); + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseMachinePriceMapper.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseMachinePriceMapper.java new file mode 100644 index 0000000..dc38f5e --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseMachinePriceMapper.java @@ -0,0 +1,41 @@ +package com.m2pool.lease.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.m2pool.lease.dto.MachinePayTypeDto; +import com.m2pool.lease.entity.LeaseMachinePrice; +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-11-25 + */ +@Mapper +public interface LeaseMachinePriceMapper extends BaseMapper { + /** + * 获取机器价格通过id + * @param machineIds + * @return + */ + List getMachinePriceByMachineIds(@Param("list") List machineIds); + + + /** + * 获取订单总金额 按照chain 和 分组 coin -v2 + * @param orderInfoVoList + * @return + */ + @MapKey("productMachineId") + Map getOrderTotalPriceGroupByChainAndCoin(@Param("list") List orderInfoVoList); + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseMiningSoftwareConfigMapper.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseMiningSoftwareConfigMapper.java new file mode 100644 index 0000000..dcc556c --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseMiningSoftwareConfigMapper.java @@ -0,0 +1,16 @@ +package com.m2pool.lease.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.m2pool.lease.entity.LeaseMiningSoftwareConfig; + +/** + *

+ * 挖矿软件公共配置表 Mapper 接口 + *

+ * + * @author yyb + * @since 2025-11-27 + */ +public interface LeaseMiningSoftwareConfigMapper extends BaseMapper { + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseOrderMiningMapper.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseOrderMiningMapper.java new file mode 100644 index 0000000..a285b8e --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeaseOrderMiningMapper.java @@ -0,0 +1,16 @@ +package com.m2pool.lease.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.m2pool.lease.entity.LeaseOrderMining; + +/** + *

+ * 挖矿中订单 Mapper 接口 + *

+ * + * @author yyb + * @since 2025-12-02 + */ +public interface LeaseOrderMiningMapper extends BaseMapper { + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeasePayWithdrawMessageMapper.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeasePayWithdrawMessageMapper.java index 07da8d4..ff39f0b 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeasePayWithdrawMessageMapper.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/mapper/LeasePayWithdrawMessageMapper.java @@ -2,6 +2,7 @@ package com.m2pool.lease.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.m2pool.lease.dto.*; +import com.m2pool.lease.dto.v2.PayWithdrawSellerRecordDto; import com.m2pool.lease.entity.LeasePayWithdrawMessage; import com.m2pool.lease.entity.LeaseUserWalletData; import org.apache.ibatis.annotations.MapKey; @@ -74,4 +75,13 @@ public interface LeasePayWithdrawMessageMapper extends BaseMapper getSellerWithdrawRecord(@Param("shopId") Long shopId); } 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 eff17a3..bdea754 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 @@ -152,4 +152,5 @@ public interface LeaseProductMachineMapper extends BaseMapper list); + } 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 9cd4f97..241ab5d 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 @@ -2,6 +2,7 @@ package com.m2pool.lease.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.m2pool.lease.dto.*; +import com.m2pool.lease.dto.v2.ShopWalletInfoDto; import com.m2pool.lease.entity.LeaseShopConfig; import org.apache.ibatis.annotations.Param; @@ -46,4 +47,18 @@ public interface LeaseShopConfigMapper extends BaseMapper { */ List getPayType(@Param("list") List shopIds); + /** + * 获取店铺钱包信息 + * @param shopId + * @return + */ + List getShopWalletInfoList(@Param("shopId") Long shopId); + + + /** + * 获取店铺钱包信息 + * @param shopId + * @return + */ + ShopWalletInfoDto getShopWalletInfo(@Param("shopId") Long shopId,@Param("address") String address,@Param("chain") String chain,@Param("coin") String coin); } 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 2f2d951..cc129c6 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 @@ -3,16 +3,12 @@ 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; @@ -54,10 +50,10 @@ public interface LeaseShopMapper extends BaseMapper { /** * 根据商品id集合获取店铺id集合 - * @param productIds + * @param machineIds * @return */ - List getShopIdsByProductIds(@Param("productIds") List productIds); + List getShopIdsByMachineIds(@Param("machineIds") List machineIds); /** * 根据店铺id集合获取店铺名称 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 9e95276..604c4ba 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,15 +24,14 @@ public interface LeaseShoppingCartInfoMapper extends BaseMapper getProductAndMachineIds(@Param("cartId") Long cartId); + List getProductAndMachineIds(@Param("userId") String userId, @Param("version") Integer version); /** * 批量删除购物车详情数据 - * @param cartId - * @param productAndMachineVos + * @param ids * @return */ - int deleteBatchData(@Param("cartId") Long cartId,@Param("productAndMachineVos") List productAndMachineVos); + int deleteBatchData(@Param("ids") List ids); } 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 4c564b4..9c329e1 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 @@ -44,6 +44,8 @@ public class MessageReceiver { private LeaseOrderItemMapper leaseOrderItemMapper; @Resource private LeaseOrderItemService leaseOrderItemService; + @Resource + private LeaseShopConfigMapper leaseShopConfigMapper; @Resource private RabbitTemplate rabbitTemplate; @@ -335,6 +337,34 @@ public class MessageReceiver { if (leasePayWithdrawMessageList.isEmpty()){ return ; } + LeasePayWithdrawMessage leasePayWithdrawMessage = handlerBuyerWithdraw(payWithdrawReturnMessage, leasePayWithdrawMessageList); + if (leasePayWithdrawMessage != null){ + LeaseShopConfig leaseShopConfig = leaseShopConfigMapper.selectOne(new LambdaQueryWrapper() + .eq(LeaseShopConfig::getPayAddress, leasePayWithdrawMessage.getFromAddress()) + .eq(LeaseShopConfig::getChain, leasePayWithdrawMessage.getFromChain()) + .eq(LeaseShopConfig::getPayCoin, leasePayWithdrawMessage.getFromSymbol())); + if (leaseShopConfig != null){ + //要修改的钱包状态为1 且提现的状态为1 则不处理 + if (leasePayWithdrawMessage.getStatus() == 1 && payWithdrawReturnMessage.getStatus() == 1){ + return; + } + if (payWithdrawReturnMessage.getStatus() == 1){ + leaseShopConfig.setBalance(leaseShopConfig.getBalance() + .add(leasePayWithdrawMessage.getAmount()) + .add(leasePayWithdrawMessage.getServiceCharge())); + leaseShopConfigMapper.updateById(leaseShopConfig); + } + leasePayWithdrawMessageMapper.updateById(LeasePayWithdrawMessage.builder() + .id(leasePayWithdrawMessage.getId()) + .status(payWithdrawReturnMessage.getStatus()) + .build()); + //TODO 修改leaseShopConfig 金额(暂时不修改,提现申请的时候就修改了) + } + } + + } + + public LeasePayWithdrawMessage handlerBuyerWithdraw(RabbitmqPayWithdrawReturnMessage payWithdrawReturnMessage,List leasePayWithdrawMessageList){ LeasePayWithdrawMessage leasePayWithdrawMessage = leasePayWithdrawMessageList.get(0); //获取对应的提现钱包 LeaseUserWalletData leaseUserWalletData = leaseUserWalletDataMapper.selectOne(new LambdaQueryWrapper() @@ -342,7 +372,9 @@ public class MessageReceiver { .eq(LeaseUserWalletData::getFromChain, leasePayWithdrawMessage.getFromChain()) .eq(LeaseUserWalletData::getFromSymbol, leasePayWithdrawMessage.getFromSymbol()) .eq(LeaseUserWalletData::getDel,false)); - + if (leaseUserWalletData == null){ + return leasePayWithdrawMessage; + } BigDecimal balance = leaseUserWalletData.getBalance() .subtract(payWithdrawReturnMessage.getAmount()) .subtract(leasePayWithdrawMessage.getServiceCharge()); @@ -370,7 +402,7 @@ public class MessageReceiver { }else{ //要修改的钱包状态为1 且提现的状态为1 则不处理 if (leasePayWithdrawMessage.getStatus() == 1 && payWithdrawReturnMessage.getStatus() == 1){ - return; + return null; } leasePayWithdrawMessageMapper.updateById(LeasePayWithdrawMessage.builder() .id(leasePayWithdrawMessage.getId()) @@ -415,13 +447,12 @@ public class MessageReceiver { updateWalletInfo(payWithdrawReturnMessage.getStatus(), leaseUserWalletData, balance, blockBalance); } } - - } - + return null; } + /** * 更新钱包余额信息 * @param status diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/handler/ChannelManager.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/handler/ChannelManager.java new file mode 100644 index 0000000..75985b7 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/handler/ChannelManager.java @@ -0,0 +1,83 @@ +package com.m2pool.lease.netty.handler; + +import io.netty.channel.Channel; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + + +/** + * @Description 频道管理类 + * @Date 2025/11/25 15:07 + * @Author yyb + */ +public class ChannelManager { + + /** + * key ip value channel + */ + private static final Map channelMap = new ConcurrentHashMap<>(); + + /** + * key mac value ip + */ + private static final Map macMap = new ConcurrentHashMap<>(); + + /** + * 添加Channel + * @param ip + * @param channel + */ + public static void addChannel(String ip, Channel channel) { + Channel prev = channelMap.put(ip, channel); + if (prev != null && prev.isActive()) { + prev.close(); + } + } + + /** + * 移除Channel + * @param ip + */ + public static void removeChannel(String ip) { + // 需要先移除MAC映射 + macMap.values().removeIf(value -> value.equals(ip)); + channelMap.remove(ip); + } + + + + /** + * 根据ip获取Channel + * @param ip + * @return + */ + public static Channel getChannelByIp(String ip) { + return channelMap.get(ip); + } + + + /** + * 根据mac地址获取Channel + * @param mac + * @return + */ + public static Channel getChannelByMac(String mac) { + String ip = macMap.get(mac); + if (ip != null) { + return channelMap.get(ip); + } + return null; + } + + public static boolean sendToClient(String mac, Object message) { + Channel channel = getChannelByMac(mac); + if (channel != null && channel.isActive()) { + channel.writeAndFlush(message).syncUninterruptibly(); + return false; + }else{ + return true; + } + } + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/handler/MessageToJsonDecoder.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/handler/MessageToJsonDecoder.java new file mode 100644 index 0000000..dfa3e87 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/handler/MessageToJsonDecoder.java @@ -0,0 +1,43 @@ +package com.m2pool.lease.netty.handler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.m2pool.lease.netty.parser.*; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; + +import java.util.ArrayList; +import java.util.List; + +public class MessageToJsonDecoder extends ByteToMessageDecoder { + private final ObjectMapper objectMapper = new ObjectMapper(); + + private final List> parsers = new ArrayList<>(); + + public MessageToJsonDecoder() { + // 初始化解析器列表 + parsers.add(new StringParser()); + parsers.add(new ClientConfigMiningParser()); + parsers.add(new GpuMessageMapParser()); + parsers.add(new ServerConfigMiningParser()); + } + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + if (in.readableBytes() > 0) { + byte[] bytes = new byte[in.readableBytes()]; + in.readBytes(bytes); + String jsonStr = new String(bytes); + + for (MessageParser parser : parsers) { + try { + Object message = parser.parse(objectMapper, jsonStr); + out.add(message); + return; + } catch (Exception e) { + // 继续尝试下一个解析器 + } + } + } + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/handler/MessageToJsonEncoder.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/handler/MessageToJsonEncoder.java new file mode 100644 index 0000000..1e0128f --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/handler/MessageToJsonEncoder.java @@ -0,0 +1,31 @@ +package com.m2pool.lease.netty.handler; + + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; + +public class MessageToJsonEncoder extends MessageToByteEncoder { + private final ObjectMapper objectMapper = new ObjectMapper(); + + @Override + protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception { + // 使用 ObjectMapper 将 msg 对象序列化为 JSON 字符串 + String jsonStr = objectMapper.writeValueAsString(msg); + // 如果 msg 是 String 类型,则直接使用 msg 的值 + if (msg instanceof String){ + jsonStr = (String) msg; + } + // 明确使用 UTF-8 编码创建 ByteBuf + ByteBuf buffer = Unpooled.copiedBuffer(jsonStr, java.nio.charset.StandardCharsets.UTF_8); + try { + // 将生成的 ByteBuf 内容写入输出的 ByteBuf + out.writeBytes(buffer); + } finally { + // 释放临时创建的 ByteBuf,避免内存泄漏 + buffer.release(); + } + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/handler/ServerChannelHandler.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/handler/ServerChannelHandler.java new file mode 100644 index 0000000..d2d7778 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/handler/ServerChannelHandler.java @@ -0,0 +1,301 @@ +package com.m2pool.lease.netty.handler; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.m2pool.common.core.utils.ip.IpUtils; +import com.m2pool.lease.entity.LeaseShop; +import com.m2pool.lease.mapper.*; +import com.m2pool.lease.netty.message.*; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +@Component +@ChannelHandler.Sharable +public class ServerChannelHandler extends SimpleChannelInboundHandler> { + + + /** + * 心跳检测 + */ + public static Map heartbeatMap = new ConcurrentHashMap(); + + @Resource + private LeaseShopMapper leaseShopMapper; + + @Resource + private LeaseMachineConfigMapper leaseMachineConfigMapper; + + @Resource + private LeaseMachineMapper leaseMachineMapper; + + @Resource + private LeaseGpuConfigMapper leaseGpuConfigMapper; + + @Resource + private LeaseMiningSoftwareConfigMapper leaseMiningSoftwareConfigMapper; + + /** + * 接收到客户端的信息 + * + * @param ctx + * @param msg + * @throws Exception + */ + @Override + protected void channelRead0(ChannelHandlerContext ctx, ClientMessage msg) throws Exception { + + //处理 + if (MethodConstant.AUTH_MACHINE_CODE.equals(msg.getMethod())){ + System.out.println("Netty tcp 服务端收到客户端下载初始化GPU消息"); + handlerDownloadClientMessage(ctx,msg); + }else if (MethodConstant.MINING_REP.equals(msg.getMethod())){ + System.out.println("Netty tcp 服务端收到客户端开始挖矿信息"); + handlerClientMiningMessage(ctx,msg); + }else{ + System.out.println("未知消息方法"); + } + } + + + + /** + * 处理客户端发送主机gpu信息消息业务 + * @param msg + */ + private void handlerDownloadClientMessage(ChannelHandlerContext ctx,ClientMessage msg){ + boolean b = checkMessage( ctx,msg); + if (b){ + Object params = msg.getParams(); + //if(params instanceof Map){ + // //map key value类型校验 + // Map rawMap = (Map) params; + // Map gpuMessageMap = new HashMap<>(); + // boolean b1 = mapCheck(rawMap, gpuMessageMap); + // if (b1){ + // List gpuMessagesList = new ArrayList<>(gpuMessageMap.values()); + // //GPU配置信息配置 + // int insertOrUpdate = leaseGpuConfigMapper.insertOrUpdate(gpuMessagesList); + // //TODO 挖矿软件公共配置 + // //leaseMiningSoftwareConfigMapper.insertOrUpdate(); + // //TODO 新增主机信息 + // } + //} + + if (params instanceof GpuAndSoftMessage){ + GpuAndSoftMessage gpuAndSoftMessage = (GpuAndSoftMessage) params; + Map gpus = gpuAndSoftMessage.getGpus(); + List miningsofts = gpuAndSoftMessage.getMiningsofts(); + + + //GPU配置信息配置 + //int insertOrUpdate = leaseGpuConfigMapper.insertOrUpdate(gpuMessagesList); + //TODO 挖矿软件公共配置 + //leaseMiningSoftwareConfigMapper.insertOrUpdate(); + //TODO 新增主机信息 + + } + } + + } + + /** + * 处理客户端发送的挖矿开始信息 + * @param msg + */ + private void handlerClientMiningMessage(ChannelHandlerContext ctx,ClientMessage msg){ + Object params = msg.getParams(); + boolean b = checkMessage(ctx,msg); + if (b){ + if (params instanceof ClientConfigurationMining){ + ClientConfigurationMining clientConfigurationMining = (ClientConfigurationMining) params; + + }else{ + //挖矿开始失败 + } + } + } + + + + /** + * 检查消息的合法性 + * @param msg + * @return + */ + private boolean checkMessage(ChannelHandlerContext ctx,ClientMessage msg){ + String id = msg.getId(); + String[] split = id.split("."); + if (split.length != 0){ + LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper().eq(LeaseShop::getIdentityCode, split[0])); + //不存在对应身份码的店铺 发送消息给客户端 + if (leaseShop == null){ + sendErrorResp(ctx,id); + return false; + } + } + return true; + } + + /** + * 身份码校验失败 + * @param ctx + * @param id + */ + public void sendErrorResp(ChannelHandlerContext ctx,String id){ + ServerMessage errorMsg = new ServerMessage<>(); + errorMsg.setId(id); + errorMsg.setResult(false); + ctx.channel().writeAndFlush(errorMsg).syncUninterruptibly(); + } + + + /** + * Map 类型校验 + * @param rawMap + * @param gpuMessageMap + */ + public boolean mapCheck(Map rawMap,Map gpuMessageMap){ + for (Map.Entry entry : rawMap.entrySet()) { + // 校验键是否为String + if (!(entry.getKey() instanceof String)) { + return false; + } + // 校验值是否为GpuMessage + if (!(entry.getValue() instanceof GpuMessage)) { + return false; + } + String key = (String) entry.getKey(); + GpuMessage value = (GpuMessage) entry.getValue(); + // 校验通过,放入目标Map + gpuMessageMap.put(key, value); + } + return true; + } + + + /** + * 活跃的、有效的通道 + * 第一次连接成功后进入的方法 + * + * @param ctx + * @throws Exception + */ + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + super.channelActive(ctx); + String ip = getIPString(ctx); + System.out.println("ip:"+ip+"连接客户端"); + ChannelManager.addChannel(ip, ctx.channel()); + } + + /** + * 不活动的通道 + * 连接丢失后执行的方法(client端可据此实现断线重连) + * + * @param ctx + * @throws Exception + */ + @Override + public void channelInactive(ChannelHandlerContext ctx) { + ChannelManager.removeChannel(getIPString(ctx)); + ctx.close(); + } + + /** + * 异常处理 + * + * @param ctx + * @param cause + * @throws Exception + */ + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + super.exceptionCaught(ctx, cause); + //发生异常,关闭连接 + System.out.println("引擎 {} 的通道发生异常,即将断开连接"+ getRemoteAddress(ctx)); + ctx.close();//再次建议close + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + if ("PONG".equals(msg.toString())) { + //收到客户端心跳 + heartbeatMap.put(ctx.channel(), true); + } else { + // 处理其他消息 + super.channelRead(ctx, msg); + } + } + /** + * 心跳机制,超时处理 + * + * @param ctx + * @param evt + * @throws Exception + */ + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + String socketString = ctx.channel().remoteAddress().toString(); + if (evt instanceof IdleStateEvent) { + IdleStateEvent event = (IdleStateEvent) evt; + String ip = getIPString(ctx); + if (event.state() == IdleState.READER_IDLE) { + Boolean isActive = heartbeatMap.put(ctx.channel(), false); + //服务端发送心跳信息 + if (isActive != null && !isActive){ + heartbeatMap.remove(ctx.channel()); + ChannelManager.removeChannel(ip); + ctx.disconnect();//断开 + }else{ + ctx.writeAndFlush("PING"); + System.out.println("读超时发送ping到客户端"); + } + } else if (event.state() == IdleState.WRITER_IDLE) { + System.out.println("客户端WRITER_IDLE 读超时: " + socketString + " "); + ChannelManager.removeChannel(ip); + ctx.disconnect();//断开 + } else if (event.state() == IdleState.ALL_IDLE) { + System.out.println("客户端 ALL_IDLE 总超时: " + socketString); + ChannelManager.removeChannel(ip); + ctx.disconnect(); + } + } + } + + /** + * 获取client对象:ip+port + * + * @param ctx + * @return + */ + public String getRemoteAddress(ChannelHandlerContext ctx) { + String socketString = ""; + socketString = ctx.channel().remoteAddress().toString(); + return socketString; + } + + /** + * 获取client的ip + * + * @param ctx + * @return + */ + public String getIPString(ChannelHandlerContext ctx) { + String ipString = ""; + String socketString = ctx.channel().remoteAddress().toString(); + int colonAt = socketString.indexOf(":"); + ipString = socketString.substring(1, colonAt); + return ipString; + } + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/ClientConfigurationMining.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/ClientConfigurationMining.java new file mode 100644 index 0000000..a61daba --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/ClientConfigurationMining.java @@ -0,0 +1,52 @@ +package com.m2pool.lease.netty.message; + +import lombok.Data; + +/** + * @Description 客户端响应给服务器的消息 + * @Date 2025/11/26 14:19 + * @Author yyb + */ +@Data +public class ClientConfigurationMining { + + /** + * 币种 + */ + private String coin; + + /** + * 算法 + */ + private String algo; + + + /** + * 矿池名称 + */ + private String pool; + + /** + * 挖矿地址 + */ + private String pool_url; + + /** + * 矿池挖矿号 仅支持不支持钱包挖矿的矿池 如 f2pool,m2pool + */ + private String worker_id; + + + /** + * 收款钱包 + */ + private String wallet_address; + + + /** + * 挖矿信息页面 只有支持钱包挖矿的矿池才有这个字段 + */ + private String watch_url; + + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/ClientMessage.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/ClientMessage.java new file mode 100644 index 0000000..8d4bd13 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/ClientMessage.java @@ -0,0 +1,30 @@ +package com.m2pool.lease.netty.message; + +import lombok.Data; + +/** + * @Description 客户端消息 + * @Date 2025/11/26 11:13 + * @Author yyb + */ +@Data +public class ClientMessage { + /** + * 身份码.主机码 + */ + private String id; + + /** + * 方法名 auth.machineCode + */ + private String method; + + /** + * 消息体 + */ + private T params; + + + + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/GpuAndSoftMessage.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/GpuAndSoftMessage.java new file mode 100644 index 0000000..bfe227c --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/GpuAndSoftMessage.java @@ -0,0 +1,24 @@ +package com.m2pool.lease.netty.message; + +import lombok.Builder; +import lombok.Data; + +import java.util.List; +import java.util.Map; + + +@Data +@Builder +public class GpuAndSoftMessage { + + /** + * 挖矿软件集合 + */ + private List miningsofts; + + /** + * gpu集合 + */ + private Map gpus; + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/GpuMessage.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/GpuMessage.java new file mode 100644 index 0000000..307f622 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/GpuMessage.java @@ -0,0 +1,48 @@ +package com.m2pool.lease.netty.message; + +import lombok.Data; + +/** + * @Description 客户端GPU消息 + * @Date 2025/11/26 16:42 + * @Author yyb + */ +@Data +public class GpuMessage { + /** + * 显卡品牌 + */ + private String brand; + /** + * 显卡型号 + */ + private String model; + /** + * 显存大小 + */ + private String mem; + + public String getBrand() { + return brand; + } + + public void setBrand(String brand) { + this.brand = brand; + } + + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + public String getMem() { + return mem; + } + + public void setMem(String mem) { + this.mem = mem; + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/MethodConstant.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/MethodConstant.java new file mode 100644 index 0000000..bd1163e --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/MethodConstant.java @@ -0,0 +1,28 @@ +package com.m2pool.lease.netty.message; + +import lombok.Data; + +/** + * @Description 消息 类型常量类 + * @Date 2025/11/26 15:31 + * @Author yyb + */ +@Data +public class MethodConstant { + /** + * 买家下单后,需要发送一个消息给卖家客户端 (客户端消息) + */ + public static final String MINING_RAG = "mining.req"; + + /** + * 客户端开始挖矿成功后,给服务端一个响应 (服务端消息) + */ + public static final String MINING_REP = "mining.resp"; + + + /** + * 用户下载客户端后,客户端主动发送一个消息到服务端 (服务段消息) + */ + public static final String AUTH_MACHINE_CODE = "auth.machineCode"; + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/ServerConfigurationMining.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/ServerConfigurationMining.java new file mode 100644 index 0000000..15a04a1 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/ServerConfigurationMining.java @@ -0,0 +1,58 @@ +package com.m2pool.lease.netty.message; + +import lombok.Data; + +/** + * @Description 客户端响应给服务端的客户端主机的gpu信息 + * @Date 2025/11/26 14:13 + * @Author yyb + */ +@Data +public class ServerConfigurationMining { + /** + * 币种 + */ + private String coin; + + /** + * 算法 + */ + private String algo; + + + /** + * 矿池名称 + */ + private String pool; + + /** + * 是否支持钱包挖矿 0 不支持 1 支持 + */ + private Boolean wallet_mining; + + /** + * 挖矿地址 + */ + private String pool_url; + + + /** + * 收款钱包 + */ + private String wallet_address; + + /** + * 矿池挖矿账号 仅支持不支持钱包挖矿的矿池 如 f2pool,m2pool + */ + private String pool_user; + /** + * 矿池挖矿号 仅支持不支持钱包挖矿的矿池 如 f2pool,m2pool + */ + private String worker_id; + + /** + * 合约结束时间 + */ + private Long end_timestamp; + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/ServerMessage.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/ServerMessage.java new file mode 100644 index 0000000..052b5fc --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/message/ServerMessage.java @@ -0,0 +1,31 @@ +package com.m2pool.lease.netty.message; + +import lombok.Data; + +/** + * @Description 服务端响应给客户端的信息 + * @Date 2025/11/26 14:11 + * @Author yyb + */ +@Data +public class ServerMessage { + /** + * 身份码.主机码 + */ + private String id; + + /** + * 方法名 0 false 1 true + */ + private Boolean result; + + /** + * 方法名 auth.machineCode 详情见 + */ + private String method; + + /** + * 消息体 + */ + private T data; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/parser/ClientConfigMiningParser.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/parser/ClientConfigMiningParser.java new file mode 100644 index 0000000..47bb87d --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/parser/ClientConfigMiningParser.java @@ -0,0 +1,19 @@ +package com.m2pool.lease.netty.parser; + + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.m2pool.lease.netty.message.ClientConfigurationMining; +import com.m2pool.lease.netty.message.ClientMessage; + +public class ClientConfigMiningParser implements MessageParser> { + @Override + public ClientMessage parse(ObjectMapper objectMapper, String jsonStr) throws Exception { + return objectMapper.readValue(jsonStr, getTypeReference()); + } + + @Override + public TypeReference> getTypeReference() { + return new TypeReference>() {}; + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/parser/GpuMessageMapParser.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/parser/GpuMessageMapParser.java new file mode 100644 index 0000000..a567535 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/parser/GpuMessageMapParser.java @@ -0,0 +1,21 @@ +package com.m2pool.lease.netty.parser; + + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.m2pool.lease.netty.message.ClientMessage; +import com.m2pool.lease.netty.message.GpuMessage; + +import java.util.HashMap; + +public class GpuMessageMapParser implements MessageParser>> { + @Override + public ClientMessage> parse(ObjectMapper objectMapper, String jsonStr) throws Exception { + return objectMapper.readValue(jsonStr, getTypeReference()); + } + + @Override + public TypeReference>> getTypeReference() { + return new TypeReference>>() {}; + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/parser/MessageParser.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/parser/MessageParser.java new file mode 100644 index 0000000..64bd63c --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/parser/MessageParser.java @@ -0,0 +1,21 @@ +package com.m2pool.lease.netty.parser; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +public interface MessageParser { + /** + * 解析 JSON 字符串为指定类型的消息对象 + * @param objectMapper Jackson 的 ObjectMapper 实例 + * @param jsonStr 待解析的 JSON 字符串 + * @return 解析后的消息对象 + * @throws Exception 解析过程中可能抛出的异常 + */ + T parse(ObjectMapper objectMapper, String jsonStr) throws Exception; + + /** + * 获取该解析器对应的类型引用 + * @return 类型引用 + */ + TypeReference getTypeReference(); +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/parser/ServerConfigMiningParser.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/parser/ServerConfigMiningParser.java new file mode 100644 index 0000000..10b6ff8 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/parser/ServerConfigMiningParser.java @@ -0,0 +1,19 @@ +package com.m2pool.lease.netty.parser; + + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.m2pool.lease.netty.message.ServerConfigurationMining; +import com.m2pool.lease.netty.message.ServerMessage; + +public class ServerConfigMiningParser implements MessageParser> { + @Override + public ServerMessage parse(ObjectMapper objectMapper, String jsonStr) throws Exception { + return objectMapper.readValue(jsonStr, getTypeReference()); + } + + @Override + public TypeReference> getTypeReference() { + return new TypeReference>() {}; + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/parser/StringParser.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/parser/StringParser.java new file mode 100644 index 0000000..1fd380a --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/parser/StringParser.java @@ -0,0 +1,19 @@ +package com.m2pool.lease.netty.parser; + + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.m2pool.lease.netty.message.ClientConfigurationMining; +import com.m2pool.lease.netty.message.ClientMessage; + +public class StringParser implements MessageParser { + @Override + public String parse(ObjectMapper objectMapper, String jsonStr) throws Exception { + return jsonStr; + } + + @Override + public TypeReference getTypeReference() { + return new TypeReference() {}; + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/server/NettyTcpServer.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/server/NettyTcpServer.java new file mode 100644 index 0000000..432239e --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/server/NettyTcpServer.java @@ -0,0 +1,90 @@ +package com.m2pool.lease.netty.server; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.util.concurrent.Future; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.annotation.PreDestroy; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Component +public class NettyTcpServer { + + private static final Logger log = LoggerFactory.getLogger(NettyTcpServer.class); + //boss事件轮询线程组 + //处理Accept连接事件的线程,这里线程数设置为1即可,netty处理链接事件默认为单线程,过度设置反而浪费cpu资源 + private EventLoopGroup boss = new NioEventLoopGroup(1); + //worker事件轮询线程组 + //处理hadnler的工作线程,其实也就是处理IO读写 。线程数据默认为 CPU 核心数乘以2 + private EventLoopGroup worker = new NioEventLoopGroup(); + + @Autowired + ServerChannelInitializer serverChannelInitializer; + + @Value("${netty.tcp.client.port}") + private Integer port; + + //与客户端建立连接后得到的通道对象 + private Channel channel; + + + + /** + * 开启Netty tcp server服务 + * + * @return + */ + public ChannelFuture start() { + //启动类 + ServerBootstrap serverBootstrap = new ServerBootstrap(); + serverBootstrap.group(boss, worker)//组配置,初始化ServerBootstrap的线程组 + .channel(NioServerSocketChannel.class)///构造channel通道工厂//bossGroup的通道,只是负责连接 + .childHandler(serverChannelInitializer)//设置通道处理者ChannelHandler////workerGroup的处理器 + .option(ChannelOption.SO_BACKLOG, 1024)//socket参数,当服务器请求处理程全满时,用于临时存放已完成三次握手请求的队列的最大长度。如果未设置或所设置的值小于1,Java将使用默认值50。 + .childOption(ChannelOption.SO_KEEPALIVE, true);//启用心跳保活机制,tcp,默认2小时发一次心跳 + //Future:异步任务的生命周期,可用来获取任务结果 + ChannelFuture channelFuture1 = serverBootstrap.bind(port).syncUninterruptibly();//绑定端口,开启监听,同步等待 + if (channelFuture1 != null && channelFuture1.isSuccess()) { + channel = channelFuture1.channel();//获取通道 + log.info("Netty tcp 服务端启动成功, 端口号 = {}", port); + } else { + log.error("Netty tcp 服务端启动失败"); + } + return channelFuture1; + } + + /** + * 停止Netty tcp server服务 + */ + @PreDestroy + public void destroy() { + if (channel != null) { + channel.close(); + } + try { + Future future = worker.shutdownGracefully().await(); + if (!future.isSuccess()) { + log.error("netty tcp workerGroup shutdown fail, {}", future.cause()); + } + Future future1 = boss.shutdownGracefully().await(); + if (!future1.isSuccess()) { + log.error("netty tcp bossGroup shutdown fail, {}", future1.cause()); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + log.info("Netty tcp server shutdown success"); + } + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/server/ServerChannelInitializer.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/server/ServerChannelInitializer.java new file mode 100644 index 0000000..e9e7c4f --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/server/ServerChannelInitializer.java @@ -0,0 +1,38 @@ +package com.m2pool.lease.netty.server; + + +import com.m2pool.lease.netty.handler.MessageToJsonDecoder; +import com.m2pool.lease.netty.handler.MessageToJsonEncoder; +import com.m2pool.lease.netty.handler.ServerChannelHandler; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.SocketChannel; +import io.netty.handler.timeout.IdleStateHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.concurrent.TimeUnit; + + +@Component +public class ServerChannelInitializer extends ChannelInitializer { + + @Autowired + ServerChannelHandler serverChannelHandler; + + @Override + protected void initChannel(SocketChannel socketChannel) throws Exception { + ChannelPipeline pipeline = socketChannel.pipeline(); + //IdleStateHandler心跳机制,如果超时触发Handle中userEventTrigger()方法 + pipeline.addLast("idleStateHandler", + new IdleStateHandler(10, 0, 0, TimeUnit.MINUTES)); + //字符串编解码器 + pipeline.addLast(new MessageToJsonDecoder(),new MessageToJsonEncoder()); + //pipeline.addLast( + // new StringDecoder(), + // new StringEncoder() + //); + //自定义Handler + pipeline.addLast("serverChannelHandler", serverChannelHandler); + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseMachineConfigService.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseMachineConfigService.java new file mode 100644 index 0000000..562169c --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseMachineConfigService.java @@ -0,0 +1,16 @@ +package com.m2pool.lease.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.m2pool.lease.entity.LeaseMachineConfig; + +/** + *

+ * GPU对应币种挖矿算力(只要gpu类型相同那么就使用这个配置) 服务类 + *

+ * + * @author yyb + * @since 2025-11-27 + */ +public interface LeaseMachineConfigService extends IService { + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseMachinePriceService.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseMachinePriceService.java new file mode 100644 index 0000000..fdc5670 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseMachinePriceService.java @@ -0,0 +1,16 @@ +package com.m2pool.lease.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.m2pool.lease.entity.LeaseMachinePrice; + +/** + *

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

+ * + * @author yyb + * @since 2025-11-25 + */ +public interface LeaseMachinePriceService extends IService { + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseMachineService.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseMachineService.java new file mode 100644 index 0000000..d38a40e --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseMachineService.java @@ -0,0 +1,80 @@ +package com.m2pool.lease.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.m2pool.lease.dto.PageResult; +import com.m2pool.lease.dto.Result; +import com.m2pool.lease.dto.v2.MachineInfoDto; +import com.m2pool.lease.dto.v2.SellerMachineInfoDto; +import com.m2pool.lease.dto.v2.ShopInfoDto; +import com.m2pool.lease.entity.LeaseMachine; +import com.m2pool.lease.vo.BaseVo; +import com.m2pool.lease.vo.ProductPageVo; +import com.m2pool.lease.vo.v2.*; +import org.springframework.web.bind.annotation.RequestBody; + +import java.util.List; + +/** + *

+ * gpu类型出售矿机表 服务类 + *

+ * + * @author yyb + * @since 2025-11-21 + */ +public interface LeaseMachineService extends IService { + + /** + * 获取商品对应的实际商品列表 + * @return + */ + PageResult getShopList(ProductPageVo productPageVo); + + + /** + * 获取店铺矿机详情 + * @return + */ + PageResult getShopMachineList(ShopMachineVo shopMachineVo); + + + /** + * 获取卖家页面矿机列表 + * @return + */ + PageResult getShopMachineListForSeller(SellerMachineVo sellerMachineVo); + + + /** + * 添加ASIC矿机 + * @return + */ + Result addAsicMachine( AsicMachineParamsVo asicMachineParamsVo); + + + /** + * 修改ASIC矿机 + * @return + */ + Result updateAsicMachine( AsicMachineParamsVo asicMachineParamsVo); + + + /** + * 修改GPU矿机 + * @return + */ + Result updateGpuMachine(List gpuMachineParamsVoList); + + /** + * 矿机上下架 + * @return + */ + Result updateMachineState(MachineStateVo machineStateVo); + + + /** + * 删除矿机 + * @return + */ + Result deleteMachine(BaseVo baseVo); +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseOrderInfoService.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseOrderInfoService.java index bb90748..bfab99a 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseOrderInfoService.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseOrderInfoService.java @@ -5,9 +5,11 @@ import com.m2pool.lease.dto.OrderInfoDto; import com.m2pool.lease.dto.PageResult; import com.m2pool.lease.dto.PaymentRecordDto; import com.m2pool.lease.dto.Result; +import com.m2pool.lease.dto.v2.CoinAndAlgorithmListDto; +import com.m2pool.lease.dto.v2.MiningInfoDto; import com.m2pool.lease.entity.LeaseOrderInfo; import com.m2pool.lease.vo.*; -import org.springframework.web.bind.annotation.RequestBody; +import com.m2pool.lease.vo.v2.CoinAndAlgorithmVo; import java.math.BigDecimal; import java.util.List; @@ -69,4 +71,54 @@ public interface LeaseOrderInfoService extends IService { * @return */ Result getCoinPrice(CoinVo coinVo); + + + /** + * 获取矿机对应的支持币种和算法 + * @return + */ + Result> getMachineSupportCoinAndAlgorithm(List machineIds); + + /** + * 获取当前矿机支持的矿池币种信息 + * @param machineIds + * @return + */ + Result> getMachineSupportPool(CoinAndAlgorithmVo coinAndAlgorithmVo); + + /** + * 添加订单-V2 + * @param orderAndCodeVo + * @return + */ + Result addOrdersV2( OrderAndCodeVo orderAndCodeVo); + + /** + * 根据订单状态查询订单列表-V2(买家) + * @param orderInfoStateVo + * @return + */ + PageResult getOrdersByStatusV2(OrderInfoStateVo orderInfoStateVo); + + + /** + * 根据订单状态查询订单列表-V2(卖家) + * @param orderInfoStateVo + * @return + */ + PageResult getOrdersByStatusForSellerV2(OrderInfoStateVo orderInfoStateVo); + + /** + * 根据订单id查询订单-V2 + * @param orderVo + * @return + */ + Result getOrdersByIdsV2(OrderVo orderVo); + + /** + * 获取用户选择的支付币种 获取实时币价-V2 + * @param coinVo + * @return + */ + Result getCoinPriceV2(CoinVo coinVo); } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseShopService.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseShopService.java index f59866a..e492909 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseShopService.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseShopService.java @@ -2,14 +2,13 @@ package com.m2pool.lease.service; import com.baomidou.mybatisplus.extension.service.IService; import com.m2pool.lease.dto.*; +import com.m2pool.lease.dto.v2.PayWithdrawSellerRecordDto; +import com.m2pool.lease.dto.v2.ShopWalletInfoDto; import com.m2pool.lease.entity.LeaseShop; -import com.m2pool.lease.vo.BaseVo; -import com.m2pool.lease.vo.ShopConfigVo; -import com.m2pool.lease.vo.ShopVo; -import org.springframework.web.bind.annotation.RequestBody; +import com.m2pool.lease.vo.*; +import com.m2pool.lease.vo.v2.ShopWalletInfoVo; import java.util.List; -import java.util.Map; /** *

@@ -114,4 +113,34 @@ public interface LeaseShopService extends IService { Result getChainAndCoin(BaseVo baseVo); + + + /** + * 根据店铺id 获取店铺配置信息列表--v2 新增手续费和钱包余额 + * @param baseVo + * @return + */ + Result> getShopConfigV2(BaseVo baseVo); + + + /** + * 卖家余额提现 + * @param balanceVo + * @return + */ + Result withdrawBalanceForSeller(BalanceVo balanceVo); + + + /** + * 修改商铺配置--v2 新增手续费和钱包余额 + */ + Result updateShopConfigV2(ShopWalletInfoVo shopWalletInfoVo); + + + + /** + * 获取店铺内所有钱包(包含历史钱包)提现列表 + * @return + */ + PageResult balanceWithdrawList(PageVo pageVo); } 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 54287fd..6f58288 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 @@ -4,11 +4,15 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.m2pool.lease.dto.PageResult; import com.m2pool.lease.dto.Result; import com.m2pool.lease.dto.ShopCartDto; +import com.m2pool.lease.dto.v2.ShopCartV2Dto; import com.m2pool.lease.entity.LeaseShoppingCart; import com.m2pool.lease.vo.BaseVo; import com.m2pool.lease.vo.PageVo; import com.m2pool.lease.vo.ProductAndMachineVo; import com.m2pool.lease.vo.ShoppingCartInfoURDVo; +import com.m2pool.lease.vo.v2.AddGoodsVo; +import com.m2pool.lease.vo.v2.CartInfoVo; +import org.springframework.web.bind.annotation.RequestBody; import java.util.List; @@ -55,4 +59,32 @@ public interface LeaseShoppingCartService extends IService { * @return */ Result deleteBatchGoodsForIsDelete(); + + + /** + * 批量添加购物车 + * @param addGoodsVoList + * @return + */ + Result addGoodsV2(List addGoodsVoList); + + + /** + * 查询购物车中商品列表 + * @param pageVo + * @return + */ + PageResult getGoodsListV2(PageVo pageVo); + /** + * 批量删除购物车中商品 + * @param baseVoList + * @return + */ + Result deleteBatchGoodsV2(List baseVoList); + + /** + * 批量删除购物车中已下架商品 + * @return + */ + Result deleteBatchGoodsForIsDeleteV2(); } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseUserService.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseUserService.java index 0295ed7..a406291 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseUserService.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseUserService.java @@ -5,7 +5,10 @@ import com.m2pool.lease.dto.*; import com.m2pool.lease.entity.LeaseUser; import com.m2pool.lease.vo.*; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import java.util.List; /** @@ -90,4 +93,17 @@ public interface LeaseUserService extends IService { Result> getCharge(); + /** + * 下载客户端 + * @param response + * @return + */ + void downloadClient(String userEmail,HttpServletRequest request, HttpServletResponse response); + + + /** + * 获取用户信息 + * @return + */ + String getClientVersion(); } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseMachineConfigServiceImpl.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseMachineConfigServiceImpl.java new file mode 100644 index 0000000..ee81e7c --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseMachineConfigServiceImpl.java @@ -0,0 +1,20 @@ +package com.m2pool.lease.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.m2pool.lease.entity.LeaseMachineConfig; +import com.m2pool.lease.mapper.LeaseMachineConfigMapper; +import com.m2pool.lease.service.LeaseMachineConfigService; +import org.springframework.stereotype.Service; + +/** + *

+ * GPU对应币种挖矿算力(只要gpu类型相同那么就使用这个配置) 服务实现类 + *

+ * + * @author yyb + * @since 2025-11-27 + */ +@Service +public class LeaseMachineConfigServiceImpl extends ServiceImpl implements LeaseMachineConfigService { + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseMachinePriceServiceImpl.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseMachinePriceServiceImpl.java new file mode 100644 index 0000000..9742b81 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseMachinePriceServiceImpl.java @@ -0,0 +1,20 @@ +package com.m2pool.lease.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.m2pool.lease.entity.LeaseMachinePrice; +import com.m2pool.lease.mapper.LeaseMachinePriceMapper; +import com.m2pool.lease.service.LeaseMachinePriceService; +import org.springframework.stereotype.Service; + +/** + *

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

+ * + * @author yyb + * @since 2025-11-25 + */ +@Service +public class LeaseMachinePriceServiceImpl extends ServiceImpl implements LeaseMachinePriceService { + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseMachineServiceImpl.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseMachineServiceImpl.java new file mode 100644 index 0000000..aa88426 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseMachineServiceImpl.java @@ -0,0 +1,444 @@ +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; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.m2pool.common.core.utils.StringUtils; +import com.m2pool.common.security.utils.SecurityUtils; +import com.m2pool.lease.dto.*; +import com.m2pool.lease.dto.v2.*; +import com.m2pool.lease.entity.LeaseMachine; +import com.m2pool.lease.entity.LeaseMachineConfig; +import com.m2pool.lease.entity.LeaseMachinePrice; +import com.m2pool.lease.entity.LeaseShop; +import com.m2pool.lease.exception.MachineException; +import com.m2pool.lease.exception.ProductSoldOutException; +import com.m2pool.lease.mapper.*; +import com.m2pool.lease.service.LeaseMachineConfigService; +import com.m2pool.lease.service.LeaseMachinePriceService; +import com.m2pool.lease.service.LeaseMachineService; +import com.m2pool.lease.utils.UuidGeneratorUtil; +import com.m2pool.lease.vo.BaseVo; +import com.m2pool.lease.vo.ProductPageVo; +import com.m2pool.lease.vo.v2.*; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; + +/** + *

+ * gpu类型出售矿机表 服务实现类 + *

+ * + * @author yyb + * @since 2025-11-21 + */ +@Service +public class LeaseMachineServiceImpl extends ServiceImpl implements LeaseMachineService { + + + @Resource + private LeaseShopConfigMapper leaseShopConfigMapper; + + @Resource + private LeaseMachineMapper leaseMachineMapper; + + @Resource + private LeaseShopMapper leaseShopMapper; + + @Resource + private LeaseMachineConfigMapper leaseMachineConfigMapper; + + @Resource + private LeaseMachinePriceMapper leaseMachinePriceMapper; + + @Resource + private LeaseMachineConfigService leaseMachineConfigService; + + @Resource + private LeaseMachinePriceService leaseMachinePriceService; + + public LeaseShop getShopById() { + return leaseShopMapper.selectOne(new LambdaQueryWrapper().eq(LeaseShop::getUserEmail, SecurityUtils.getUsername()) + .eq(LeaseShop::getDel, false)); + } + @Override + public PageResult getShopList(ProductPageVo productPageVo) { + //获取到矿机 + Set shopIds = leaseMachineMapper.getShopIds(); + if (shopIds.isEmpty()){ + return PageResult.fail(new ArrayList<>(), "暂无商品"); + } + PageHelper.startPage(productPageVo.getPageNum(), productPageVo.getPageSize()); + List existsMachineShop = leaseMachineMapper.getExistsMachineShop(shopIds, productPageVo.getCoin(), productPageVo.getAlgorithm()); + PageInfo pageInfo = new PageInfo<>(existsMachineShop); + //店铺支付方式 + List payType = leaseShopConfigMapper.getPayType(new ArrayList<>(shopIds)); + Map> payTypeMap = payType.stream().collect(Collectors.groupingBy(PayTypeDto::getShopId)); + + PageResult success = PageResult.success(existsMachineShop); + for (ShopInfoDto shopInfoDto : success.getRows()) { + shopInfoDto.setPayTypes(payTypeMap.get(shopInfoDto.getShopId())); + } + success.setTotal(pageInfo.getTotal()); + success.setTotalPage(pageInfo.getPages()); + PageHelper.clearPage(); + return success; + } + + @Override + public PageResult getShopMachineList(ShopMachineVo shopMachineVo) { + //获取店铺钱包信息 + List shopWalletInfo = leaseShopMapper.getShopWalletInfo(shopMachineVo.getShopId()); + //分页查询矿机基础信息 + PageHelper.startPage(shopMachineVo.getPageNum(), shopMachineVo.getPageSize()); + shopMachineVo = buildQuery(shopMachineVo,shopWalletInfo.get(0)); + List machineInfoDtoList = leaseMachineMapper.getShopMachineList(shopMachineVo); + PageInfo pageInfo = new PageInfo<>(machineInfoDtoList); + //获取gpu和asic对应币种算力和月收益信息 + PageResult success = setGpuAndAsicInfo(PageResult.successColumns(machineInfoDtoList),shopMachineVo); + success.setTotal(pageInfo.getTotal()); + success.setTotalPage(pageInfo.getPages()); + PageHelper.clearPage(); + return success; + } + + /** + * 设置gpu和asic 对应的收益列表信息 + * @param + */ + public PageResult setGpuAndAsicInfo(PageResult success,ShopMachineVo shopMachineVo) { + List machineInfoDtoList = success.getRows(); + List columns = success.getColumns(); + if (!machineInfoDtoList.isEmpty()){ + List machineIds = machineInfoDtoList.stream() + .map(MachineInfoDto::getId).collect(Collectors.toList()); + //获取价格列表(价格列表只与主表有关,与machine_config 表无关) + List machinePriceByMachineIds = leaseMachinePriceMapper.getMachinePriceByMachineIds(machineIds); + Map> machinePriceMap = machinePriceByMachineIds.stream() + .collect(Collectors.groupingBy(MachinePayTypeDto::getProductMachineId)); + + //动态列:获取每个矿机前十个币种算法的配置 + List gpuConfigList = leaseMachineMapper.getGpuConfigList(machineIds); + Map> collect = gpuConfigList.stream() + .collect(Collectors.groupingBy(PowerIncomeInfoDto::getMachineId)); + for (MachineInfoDto machineInfo : machineInfoDtoList) { + machineInfo.setPriceList(machinePriceMap.get(machineInfo.getId())); + List powerIncomeInfoDtoList = collect.get(machineInfo.getId()); + for (int i = 0; i < powerIncomeInfoDtoList.size(); i++) { + PowerIncomeInfoDto powerIncomeInfoDto = powerIncomeInfoDtoList.get(i); + setDynamicColumn(columns,powerIncomeInfoDto,machineInfo); + } + } + //排序分页后对象 + List sorted = sorted(machineInfoDtoList, shopMachineVo); + success.setRows(sorted); + success.setColumns(columns); + + } + return success; + } + + /** + * 设置算力动态列 + * @param columns + */ + public void setDynamicColumn(List columns,PowerIncomeInfoDto powerIncomeInfoDto,MachineInfoDto machineInfo){ + TableHeadersDto column = TableHeadersDto.builder() + .label(powerIncomeInfoDto.getCoin()) + .type("hashrate") + .unit(powerIncomeInfoDto.getUnit()) + .icon(powerIncomeInfoDto.getIcon()) + .width(100).build(); + int index = 1; + + for (TableHeadersDto tableHeadersDto : columns) { + if (index < 10 && "hashrate".equals(tableHeadersDto.getType())){ + if (column.getLabel().equals(tableHeadersDto.getLabel())){ + setDynamicPower(index,machineInfo,powerIncomeInfoDto); + return; + }else{ + index++; + } + } + } + if (index <= 10){ + setDynamicPower(index,machineInfo,powerIncomeInfoDto); + column.setKey("c"+index); + columns.add(column); + } + } + + private void setDynamicPower(int index,MachineInfoDto machineInfo,PowerIncomeInfoDto powerIncomeInfoDto){ + switch (index){ + case 1: + machineInfo.setC1(powerIncomeInfoDto.getPower()); + break; + case 2: + machineInfo.setC2(powerIncomeInfoDto.getPower()); + break; + case 3: + machineInfo.setC3(powerIncomeInfoDto.getPower()); + break; + case 4: + machineInfo.setC4(powerIncomeInfoDto.getPower()); + break; + case 5: + machineInfo.setC5(powerIncomeInfoDto.getPower()); + break; + case 6: + machineInfo.setC6(powerIncomeInfoDto.getPower()); + break; + case 7: + machineInfo.setC7(powerIncomeInfoDto.getPower()); + break; + case 8: + machineInfo.setC8(powerIncomeInfoDto.getPower()); + break; + case 9: + machineInfo.setC9(powerIncomeInfoDto.getPower()); + break; + case 10: + machineInfo.setC10(powerIncomeInfoDto.getPower()); + break; + } + } + + @Override + public PageResult getShopMachineListForSeller(SellerMachineVo sellerMachineVo) { + LeaseShop leaseShop = getShopById(); + PageHelper.startPage(sellerMachineVo.getPageNum(), sellerMachineVo.getPageSize()); + List machineInfoDtoList = leaseMachineMapper.getShopMachineListForSeller(sellerMachineVo,leaseShop.getId()); + PageInfo pageInfo = new PageInfo<>(machineInfoDtoList); + if (machineInfoDtoList.isEmpty()){ + return PageResult.fail(new ArrayList<>(), "暂无矿机"); + } + PageResult success = PageResult.success(machineInfoDtoList); + //获取矿机配置信息 + List coinAndAlgoList = leaseMachineMapper.getCoinAndAlgoList(success.getRows()); + Map> collect1 = coinAndAlgoList.stream().collect(Collectors.groupingBy(AsicCoinAndAlgoDto::getProductMachineId)); + //价格配置信息 + List machinePriceList = leaseMachineMapper.getMachinePriceList(success.getRows()); + Map> collect = machinePriceList.stream().collect(Collectors.groupingBy(MachinePayTypeDto::getProductMachineId)); + for (SellerMachineInfoDto row : success.getRows()) { + row.setPriceList(collect.get(row.getId())); + row.setCoinAndAlgoList(collect1.get(row.getId())); + } + success.setTotal(pageInfo.getTotal()); + success.setTotalPage(pageInfo.getPages()); + PageHelper.clearPage(); + return success; + } + + + /** + * 分页内排序 + * @param shopMachineVo 查询条件 + * @param machineInfoDtoList 钱包信息 + * @return 查询条件 + */ + public List sorted(List machineInfoDtoList, ShopMachineVo shopMachineVo){ + + if (shopMachineVo.getPriceSort() != null) { + Comparator priceComparator = shopMachineVo.getPriceSort() ? + Comparator.comparing(MachineInfoDto::getPrice) : + Comparator.comparing(MachineInfoDto::getPrice).reversed(); + return machineInfoDtoList.stream() + .sorted(priceComparator) + .collect(Collectors.toList()); + } else if (shopMachineVo.getPowerSort() != null) { + Comparator powerComparator = shopMachineVo.getPowerSort() ? + Comparator.comparing(MachineInfoDto::getTheoryPower) : + Comparator.comparing(MachineInfoDto::getTheoryPower).reversed(); + return machineInfoDtoList.stream() + .sorted(powerComparator) + .collect(Collectors.toList()); + }else { + return machineInfoDtoList; + } + } + + public ShopMachineVo buildQuery(ShopMachineVo shopMachineVo,PayConfigDto payConfigDto){ + if (StringUtils.isEmpty(shopMachineVo.getChain()) && StringUtils.isEmpty(shopMachineVo.getCoin())){ + shopMachineVo.setChain(payConfigDto.getPayChain()); + shopMachineVo.setCoin(payConfigDto.getPayCoin()); + } + //BigDecimal power = PowerUnit.getPower(shopMachineVo.getUnit()).divide(BigDecimal.valueOf(1000 * 1000),2, RoundingMode.HALF_UP); + //shopMachineVo.setMaxPower(shopMachineVo.getMaxPower().multiply(power)); + //shopMachineVo.setMinPower(shopMachineVo.getMinPower().multiply(power)); + ////算力设置 + //if (shopMachineVo.getMaxPower().compareTo(shopMachineVo.getMinPower()) < 0){ + // shopMachineVo.setMaxPower(shopMachineVo.getMinPower()); + // shopMachineVo.setMinPower(shopMachineVo.getMaxPower()); + //} + ////功耗设置 + //if (shopMachineVo.getMaxPowerDissipation().compareTo(shopMachineVo.getMinPowerDissipation()) < 0){ + // shopMachineVo.setMaxPowerDissipation(shopMachineVo.getMinPowerDissipation()); + // shopMachineVo.setMinPowerDissipation(shopMachineVo.getMaxPowerDissipation()); + //} + //价格设置 + if (shopMachineVo.getMaxPrice().compareTo(shopMachineVo.getMinPrice()) < 0){ + + shopMachineVo.setMaxPrice(shopMachineVo.getMinPrice()); + shopMachineVo.setMinPrice(shopMachineVo.getMaxPrice()); + } + return shopMachineVo; + } + + + @Override + @Transactional + public Result addAsicMachine(AsicMachineParamsVo asicMachineParamsVo) { + LeaseShop leaseShop = getShopById(); + if (leaseShop == null){ + return Result.fail("添加ASIC矿机失败,未找到商铺,请重试"); + } + //新增lease_machine主表信息 + LeaseMachine machine = LeaseMachine.builder() + .hostMac(UuidGeneratorUtil.generateUuidWithoutHyphen()) + .shopId(leaseShop.getId()) + .type(false) + .maxLeaseDays(asicMachineParamsVo.getMaxLeaseDays()) + .saleNumbers(asicMachineParamsVo.getSaleNumbers()) + .build(); + int machineInsert = leaseMachineMapper.insert(machine); + + //新增lease_asic_coin_power_config 配置信息表信息 + lease_machine_price 矿机价格表信息 + if (machineInsert > 0){ + List collect = asicMachineParamsVo.getCoinAndAlgoList().stream().map( + coinAndAlgo -> LeaseMachineConfig.builder() + .machineId(machine.getId()) + .name(asicMachineParamsVo.getName()) + .powerDissipation(asicMachineParamsVo.getPowerDissipation()) + .coin(coinAndAlgo.getCoin()) + .algorithm(coinAndAlgo.getAlgorithm()) + .hashrate(coinAndAlgo.getTheoryPower()) + .unit(coinAndAlgo.getUnit()) + .build() + ).collect(Collectors.toList()); + + List collect1 = asicMachineParamsVo.getPriceList().stream() + .map(machinePayTypeVo -> + LeaseMachinePrice.builder() + .machineId(machine.getId()) + .price(machinePayTypeVo.getPrice()) + .coin(machinePayTypeVo.getCoin()) + .chain(machinePayTypeVo.getChain()) + .build() + ).collect(Collectors.toList()); + boolean b1 = leaseMachinePriceService.saveBatch(collect1); + boolean b = leaseMachineConfigService.saveBatch(collect); + if (!b && !b1){ + throw new MachineException("添加asic矿机币价及算力信息失败"); + } + return Result.success("添加asic矿机成功"); + } + return Result.fail("添加ASIC矿机失败,请重试"); + } + + @Override + @Transactional + public Result updateAsicMachine(AsicMachineParamsVo asicMachineParamsVo) { + //修改lease_machine主表信息 + LeaseMachine machine = LeaseMachine.builder() + .id(asicMachineParamsVo.getId()) + .maxLeaseDays(asicMachineParamsVo.getMaxLeaseDays()) + .saleNumbers(asicMachineParamsVo.getSaleNumbers()) + .state(asicMachineParamsVo.getState()) + .build(); + int machineUpdate = leaseMachineMapper.updateById(machine); + //修改lease_machine_price 矿机价格表信息 + 修改lease_asic_coin_power_config 配置信息表信息 + if (machineUpdate > 0){ + + List collect = asicMachineParamsVo.getPriceList().stream().map( + machinePayTypeVo -> + LeaseMachinePrice.builder() + .id(machinePayTypeVo.getPayTypeId()) + .price(machinePayTypeVo.getPrice()) + .build() + ).collect(Collectors.toList()); + boolean b = leaseMachinePriceService.updateBatchById(collect); + List collect1 = asicMachineParamsVo.getCoinAndAlgoList().stream().map(coinAndAlgo -> + LeaseMachineConfig.builder() + .id(coinAndAlgo.getCoinAndPowerId()) + .machineId(machine.getId()) + .name(asicMachineParamsVo.getName()) + .coin(coinAndAlgo.getCoin()) + .hashrate(coinAndAlgo.getTheoryPower()) + .algorithm(coinAndAlgo.getAlgorithm()) + .unit(coinAndAlgo.getUnit()) + .powerDissipation(asicMachineParamsVo.getPowerDissipation()) + .build() + ).collect(Collectors.toList()); + boolean b1 = leaseMachineConfigService.saveOrUpdateBatch(collect1); + if (!b && !b1){ + throw new MachineException("修改asic矿机币价及算力信息失败"); + } + + return Result.success("修改ASIC矿机成功"); + } + return Result.fail("修改ASIC矿机失败,请重试"); + } + + @Override + @Transactional + public Result updateGpuMachine(List gpuMachineParamsVoList) { + for (GpuMachineParamsVo gpuMachineParamsVo : gpuMachineParamsVoList) { + //修改lease_machine主表信息 + LeaseMachine machine = LeaseMachine.builder() + .id(gpuMachineParamsVo.getId()) + .maxLeaseDays(gpuMachineParamsVo.getMaxLeaseDays()) + .state(gpuMachineParamsVo.getState()) + .build(); + int machineUpdate = leaseMachineMapper.updateById(machine); + //修改lease_machine_price 矿机价格表信息 + gpu的配置信息是固定的不能修改 + if (machineUpdate > 0){ + List priceList = gpuMachineParamsVo.getPriceList(); + for (MachinePayTypeVo machinePayTypeVo : priceList) { + LeaseMachinePrice build = LeaseMachinePrice.builder() + .id(machinePayTypeVo.getPayTypeId()) + .price(machinePayTypeVo.getPrice()) + .chain(machinePayTypeVo.getChain()) + .coin(machinePayTypeVo.getCoin()) + .machineId(machine.getId()) + .build(); + if (build.getId() == null || build.getId() == 0){ + leaseMachinePriceMapper.insert(build); + }else{ + leaseMachinePriceMapper.updateById(build); + } + } + } + } + return Result.success("修改GPU矿机成功") ; + } + + + @Override + @Transactional + public Result updateMachineState(MachineStateVo machineStateVo) { + leaseMachineMapper.updateById(LeaseMachine.builder().id(machineStateVo.getId()).state(machineStateVo.getState()).build()); + return machineStateVo.getState() ? Result.success("下架成功") : Result.success("上架成功"); + } + + @Override + public Result deleteMachine(BaseVo baseVo) { + //TODO 删除之前需要判断是否存在订单 + leaseMachineMapper.updateById(LeaseMachine.builder().id(baseVo.getId()).del(true).build()); + //删除售价 + leaseMachinePriceMapper.update(LeaseMachinePrice.builder().del(true).build(),new LambdaQueryWrapper() + .eq(LeaseMachinePrice::getMachineId,baseVo.getId())); + //ASIC/GPU 矿机删除配置信息 + leaseMachineConfigMapper.update(LeaseMachineConfig.builder().del(true).build(), + new LambdaQueryWrapper().eq(LeaseMachineConfig::getMachineId,baseVo.getId())); + + return Result.success("删除成功"); + } +} 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 f59b8d6..210723b 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 @@ -13,19 +13,25 @@ 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.dto.v2.*; import com.m2pool.lease.entity.*; import com.m2pool.lease.exception.OrderException; import com.m2pool.lease.mapper.*; +import com.m2pool.lease.netty.handler.ChannelManager; +import com.m2pool.lease.netty.handler.ServerChannelHandler; import com.m2pool.lease.service.LeaseOrderInfoService; import com.m2pool.lease.service.LeaseOrderItemService; import com.m2pool.lease.service.LeaseProductService; import com.m2pool.lease.service.LeaseUserOwnedProductService; import com.m2pool.lease.utils.UuidGeneratorUtil; import com.m2pool.lease.vo.*; +import com.m2pool.lease.vo.v2.CoinAndAlgorithmVo; +import io.netty.channel.Channel; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; +import java.time.Instant; import java.time.LocalDateTime; import java.util.*; import java.util.function.Function; @@ -61,9 +67,6 @@ public class LeaseOrderInfoServiceImpl extends ServiceImpl() - .eq(LeaseShoppingCart::getUserId, SecurityUtils.getUsername())); int delete = leaseShoppingCartInfoMapper.delete(new LambdaUpdateWrapper() - .eq(LeaseShoppingCartInfo::getCartId, leaseShoppingCart.getId()) + .eq(LeaseShoppingCartInfo::getUserId, SecurityUtils.getUsername()) .in(LeaseShoppingCartInfo::getProductMachineId, machineIds)); if (delete < 1){ throw new OrderException("生成订单失败,购物车中不存在矿机商品"); @@ -229,7 +232,6 @@ public class LeaseOrderInfoServiceImpl extends ServiceImpl getCoinPrice(CoinVo coinVo) { BigDecimal coinPrice = getCoinPrice(coinVo.getCoin()); return Result.success(coinPrice); } - public BigDecimal getCoinPrice(String coin) { coin = coin.toLowerCase(); String priceKey = RedisKey.getPiceKey(coin); @@ -594,4 +593,360 @@ public class LeaseOrderInfoServiceImpl extends ServiceImpl> getMachineSupportCoinAndAlgorithm(List machineIds) { + //lease_pool_coin_config 中获取本系统支持的币种和算法 + List machineSupportCoinAndAlgorithm = leaseMachineConfigMapper.getMachineSupportCoinAndAlgorithm(machineIds); + // 按币种分组 + Map> coinGroup = machineSupportCoinAndAlgorithm.stream() + .collect(Collectors.groupingBy(CoinAndAlgorithmDto::getCoin)); + List result = new ArrayList<>(); + // 遍历每个币种 + coinGroup.forEach((coin, dtos) -> { + CoinAndAlgorithmListDto item = new CoinAndAlgorithmListDto(); + item.setCoin(coin); + // 转换算法列表 + List algorithmList = dtos.stream() + .map(dto -> { + CoinAndAlgorithmListDto.AlgorithmListDto algoDto = new CoinAndAlgorithmListDto.AlgorithmListDto(); + algoDto.setAlgorithm(dto.getAlgorithm()); + + // 转换机器ID列表 + List ids = Arrays.stream(dto.getMachineIds().split(",")) + .map(Long::valueOf) + .collect(Collectors.toList()); + algoDto.setMachineIds(ids); + + return algoDto; + }) + .collect(Collectors.toList()); + + item.setAlgorithmList(algorithmList); + result.add(item); + }); + return Result.success(result); + } + + + @Override + public Result> getMachineSupportPool(CoinAndAlgorithmVo coinAndAlgorithmVo) { + List coinConfigList = leaseMachineConfigMapper.getConfigList(coinAndAlgorithmVo.getCoin(), coinAndAlgorithmVo.getAlgorithm()); + // 将查询结果按poolId分组并转换为MiningInfoDto列表 + List miningInfoList = coinConfigList.stream() + .collect(Collectors.groupingBy(MiningConfigSelectDto::getPoolId)) + .entrySet().stream() + .map(entry -> { + MiningConfigSelectDto firstConfig = entry.getValue().get(0); + + List coinInfoList = entry.getValue().stream() + .map(config -> MiningCoinInfoDto.builder() + .coinConfigId(config.getCoinConfigId()) + .coin(config.getCoin()) + .algorithm(config.getAlgorithm()) + .miningTcpGpuUrl(config.getMiningTcpGpuUrl()) + .modelName(config.getModelName()) + .modelFee(config.getModelFee()) + .walletMining(config.getWalletMining()) + .build()) + .collect(Collectors.toList()); + + return MiningInfoDto.builder() + .poolId(entry.getKey()) + .poolName(firstConfig.getPoolName()) + .miningCoinInfoList(coinInfoList) + .build(); + }) + .collect(Collectors.toList()); + return Result.success(miningInfoList); + } + + @Override + @DSTransactional + public Result addOrdersV2(OrderAndCodeVo orderAndCodeVo) { + String userEmail = SecurityUtils.getUsername(); + List orderInfoVoList = orderAndCodeVo.getOrderInfoVoList(); + + GoogleInfo googleInfo = leaseUserMapper.getGoogleInfoByEmail(userEmail); + //TODO 开发环境 + //if(googleInfo == null || StringUtils.isBlank(googleInfo.getSecret())){ + // //未绑定定谷歌验证器 + // return Result.fail("您的账号未开启双重验证,请先开启验证!"); + //} + //if(!GoogleAuthenticator.checkCode(googleInfo.getSecret(), orderAndCodeVo.getCode(), System.currentTimeMillis())){ + // return Result.fail("谷歌验证码错误"); + //} + Map collect1 = orderInfoVoList.stream() + .collect(Collectors.toMap(OrderInfoVo::getMachineId,Function.identity())); + List machineList = leaseMachineMapper.selectBatchIds(collect1.keySet()); + Map> machineTypeMap = machineList.stream().collect(Collectors.groupingBy(LeaseMachine::getType)); + List gpuMachines = machineTypeMap.get(true) == null ? new ArrayList<>() : machineTypeMap.get(true); + List asicMachines = machineTypeMap.get(false) == null ? new ArrayList<>() : machineTypeMap.get(false); + //校验asic 可售数量是否充足 + gpu 机器对应客户端是否在线 + boolean isAsicPass = checkAsicMachine(asicMachines,collect1); + if (!isAsicPass){ + return Result.fail("购买的ASIC商品中,存在可售数量不足的商品!"); + } + boolean isGpuPass = checkGpuMachine(gpuMachines); + if (!isGpuPass){ + return Result.fail("购买的GPU商品中,存在客户端不在线的矿机!"); + } + //存储相同链和币种的map集合 + Map>> chainAndCoinMap = new HashMap<>(); + Map orderTotalPriceGroupByChainAndCoin = leaseMachinePriceMapper.getOrderTotalPriceGroupByChainAndCoin(orderInfoVoList); + //chain + coin 钱包 对应的总价 + Map totalPriceMap = new HashMap<>(); + //存储根据chain和coin去重后的set集合 + Set chainAndCoinSet = new HashSet<>(); + Set chainAndCoinAndShopIdSet = new HashSet<>(); + //其他 + Map machineMap = new HashMap<>(); + LocalDateTime now = LocalDateTime.now(); + Long startTime = System.currentTimeMillis(); + List machineIds = new ArrayList<>(); + Set shopIds = new HashSet<>(); + for (OrderInfoVo vo : orderInfoVoList) { + String chain = vo.getChain(); + String coin = vo.getCoin(); + Long shopId = vo.getShopId(); + String key = chain +"-"+ coin+"-"+shopId; + 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; + } + LeaseMachinePrice 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()); + + } + //获取买家需要进行支付的几个钱包 + List walletDataList = leaseUserWalletDataMapper.selectWalletByChainAndCoinAndUsername(chainAndCoinSet, userEmail); + if (walletDataList.size() != chainAndCoinSet.size()){ + return Result.fail("下单失败!订单选择的支付方式中对应钱包您还未绑定并充值!"); + } + + Map fromAddressMap = walletDataList.stream().collect(Collectors.toMap(item -> item.getFromChain() + "-" + item.getFromSymbol(), Function.identity())); + //封装订单主表信息 + List leaseOrderInfoList = new ArrayList<>(); + totalPriceMap.forEach((key, totalPrice)->{ + String[] split = key.split("-"); + String coin = split[1]; + String chain = split[0]; + BigDecimal fee = CoinCharge.getFee(chain, coin, totalPrice); + leaseOrderInfoList.add(LeaseOrderInfo.builder() + .chainAndCoinAndShopIdKey(key) + .chainAndCoinKey(chain+"-"+coin) + .orderNumber(UuidGeneratorUtil.generateUuidWithoutHyphen()) + .userId(userEmail) + .fee(fee) + .totalPrice(totalPrice) + .createTime(now) + .build()); + }); + + //删除购物车中矿机 + int delete = leaseShoppingCartInfoMapper.delete(new LambdaUpdateWrapper() + .eq(LeaseShoppingCartInfo::getUserId, SecurityUtils.getUsername()) + .eq(LeaseShoppingCartInfo::getVersion, 1) + .in(LeaseShoppingCartInfo::getProductMachineId, machineIds)); + if (delete < 1){ + throw new OrderException("生成订单失败,购物车中不存在矿机商品"); + } + //查找矿机详情信息 + List machinesList = leaseMachineMapper.selectBatchIds(machineIds); + List collect = machinesList.stream().filter(leaseMachine -> leaseMachine.getState() || leaseMachine.getDel()).collect(Collectors.toList()); + if (!collect.isEmpty()){ + 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()); + } + boolean save = saveBatch(leaseOrderInfoList); + if (!save){ + return Result.fail("生成订单失败"); + } + Map orderInfoMap = leaseOrderInfoList.stream() + .collect(Collectors.toMap(LeaseOrderInfo::getChainAndCoinAndShopIdKey, Function.identity())); + + //订单详情表业务 + List shopList = leaseShopMapper.selectBatchIds(shopIds); + Map shopMap = shopList.stream().collect(Collectors.toMap(LeaseShop::getId, Function.identity())); + List leaseOrderItems = new ArrayList<>(); + + //挖矿结束时间 + Map endMiningMap = new HashMap<>(); + + for (LeaseMachine leaseMachine : machinesList) { + Long machineId = leaseMachine.getId(); + OrderInfoVo orderInfoVo = machineMap.get(machineId); + String chain = orderInfoVo.getChain(); + String coin = orderInfoVo.getCoin(); + Long shopId = orderInfoVo.getShopId(); + String key = chain + "-" + coin + "-" + shopId; + LeaseMachinePrice leaseMachinePrice = orderTotalPriceGroupByChainAndCoin.get(machineId); + LeaseShopConfig leaseShopConfig = configMap.get(key); + LeaseUserWalletData walletInfo = fromAddressMap.get(chain + "-" + coin); + if (leaseShopConfig == null){ + throw new OrderException("选择的卖家收款钱包不存在,请重行选择支付方法"); + } + LeaseOrderInfo leaseOrderInfo = orderInfoMap.get(key); + //设置销售数量 + LeaseShop leaseShop = shopMap.get(leaseMachine.getShopId()); + leaseShop.setSaleNumber(leaseShop.getSaleNumber() + orderInfoVo.getNumbers()); + + leaseOrderItems.add( LeaseOrderItem.builder() + .userId(userEmail) + .orderId(leaseOrderInfo.getId()) + .productMachineId(machineId) + .price(leaseMachinePrice.getPrice()) + .user(leaseMachine.getUser()) + .miner(leaseMachine.getMiner()) + //.theoryIncome(leaseMachine.getTheoryIncome().multiply(BigDecimal.valueOf(orderInfoVo.getLeaseTime()))) + .leaseTime(orderInfoVo.getLeaseTime()) + .payCoin(leaseShopConfig.getPayCoin()) + .address(leaseShopConfig.getPayAddress()) + .name(leaseMachine.getHostMac()) + .chain(leaseShopConfig.getChain()) + .symbol(leaseShopConfig.getPayCoin()) + .shopId(leaseMachine.getShopId()) + .fromAddress(walletInfo.getFromAddress()) + .fromChain(walletInfo.getFromChain()) + .fromSymbol(walletInfo.getFromSymbol()) + .numbers(orderInfoVo.getNumbers()) + .build()); + Long timestamp =startTime + orderInfoVo.getLeaseTime() * orderInfoVo.getNumbers() * 24 * 60 * 60 * 1000L; + endMiningMap.put(machineId,timestamp); + + } + boolean b = leaseOrderItemService.saveBatch(leaseOrderItems); + //开始生成支付订单并返回 + if (b){ + checkBalanceAndSetBlockBalance(fromAddressMap,leaseOrderInfoList); + //修改GPU 矿机售出状态为 1 已售出 + int gpuUpdate = leaseMachineMapper.updateLockState(asicMachines); + //修改ASIC 矿机出售数量 + int asicUpdate = leaseMachineMapper.updateLockNumbers(gpuMachines); + int i = gpuUpdate + asicUpdate; + if (i != machineIds.size()){ + throw new OrderException("订单中已有商品售出,请刷新购物车删除已售出商品,重新结算生成订单"); + } + //发送消息 + sendGpuTcpMessageToClient(gpuMachines,orderAndCodeVo.getOrderMiningInfoDtoList(),endMiningMap); + return Result.success("订单生成成功"); + } + throw new OrderException("订单生成失败"); + } + + /** + * 检测 gpu客户端是否在线 + * @param gpuMachines 购买的GPU矿机信息 + */ + private boolean checkGpuMachine(List gpuMachines){ + for (LeaseMachine gpuMachine : gpuMachines) { + if (ChannelManager.getChannelByMac(gpuMachine.getHostMac()) == null){ + return false; + } + } + return true; + } + + /** + * 校验 ASIC 矿机可售数量是否充足 + * @param asicMachines 购买的ASIC矿机信息 + */ + private boolean checkAsicMachine(List asicMachines,Map numbers){ + for (LeaseMachine leaseMachine : asicMachines) { + Integer number = numbers.get(leaseMachine.getId()).getNumbers(); + Integer lockNumbers = leaseMachine.getSaleOutNumbers(); + leaseMachine.setLockNumbers(lockNumbers); + leaseMachine.setSaleOutNumbers(lockNumbers + number); + if (leaseMachine.getSaleNumbers() - leaseMachine.getSaleOutNumbers() < number){ + return false; + } + } + return true; + } + + /** + * GPU矿机的通过mac发送给相应的客户端 + */ + public void sendGpuTcpMessageToClient(List gpuMachines, List orderMiningInfo,Map endMiningMap){ + //TODO 不添加 + //if(!checkGpuMachine(gpuMachines)){ + // throw new OrderException("购买的GPU商品中,存在客户端不在线的矿机!"); + //} + + Map coinAndAlgoMap = leaseMachineMapper.getCoinAndAlgoById(orderMiningInfo.stream().map(OrderMiningInfoDto::getCoinConfigId).collect(Collectors.toList())); + Map idAndMacMap = gpuMachines.stream().collect(Collectors.toMap(LeaseMachine::getId, Function.identity())); + + for (OrderMiningInfoDto orderMiningInfoDto : orderMiningInfo) { + MiningConfigDto miningConfigDto = coinAndAlgoMap.get(orderMiningInfoDto.getCoinConfigId()); + for (Long machineId : orderMiningInfoDto.getMachineIds()) { + String mac = idAndMacMap.get(machineId).getHostMac(); + Long endTime = endMiningMap.get(machineId); + ChannelManager.sendToClient(mac,MiningConfigDto.builder() + .algo(miningConfigDto.getAlgo()) + .coin(miningConfigDto.getCoin()) + .pool(miningConfigDto.getPool()) + .wallet_mining(orderMiningInfoDto.getWalletMining()) + .pool_url(miningConfigDto.getPool_url()) + .wallet_address(orderMiningInfoDto.getWalletAddress()) + .pool_user(orderMiningInfoDto.getPoolUser()) + .worker_id(orderMiningInfoDto.getWorkerId()) + .end_timestamp(endTime).build()); + } + } + } + + //TODO ASIC 不是发送给客户端是通过其他方式,不过发送消息的结构和gpu相同 + + @Override + public PageResult getOrdersByStatusV2(OrderInfoStateVo orderInfoStateVo) { + return null; + } + + @Override + public PageResult getOrdersByStatusForSellerV2(OrderInfoStateVo orderInfoStateVo) { + return null; + } + + @Override + public Result getOrdersByIdsV2(OrderVo orderVo) { + return null; + } + + @Override + public Result getCoinPriceV2(CoinVo coinVo) { + return null; + } + + } 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 8f4193d..0ce65d0 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 @@ -3,27 +3,40 @@ package com.m2pool.lease.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.m2pool.common.core.utils.StringUtils; import com.m2pool.common.security.utils.SecurityUtils; import com.m2pool.lease.dto.*; +import com.m2pool.lease.dto.v2.PayWithdrawSellerRecordDto; +import com.m2pool.lease.dto.v2.ShopWalletInfoDto; import com.m2pool.lease.entity.*; +import com.m2pool.lease.exception.PaymentException; import com.m2pool.lease.mapper.*; +import com.m2pool.lease.mq.message.RabbitmqPayWithdrawMessage; import com.m2pool.lease.service.LeaseShopConfigService; import com.m2pool.lease.service.LeaseShopService; +import com.m2pool.lease.utils.HashUtils; import com.m2pool.lease.utils.QrCodeUtils; +import com.m2pool.lease.utils.UuidGeneratorUtil; import com.m2pool.lease.utils.WalletRuleCheckUtils; -import com.m2pool.lease.vo.BaseVo; -import com.m2pool.lease.vo.ShopConfigVo; -import com.m2pool.lease.vo.ShopVo; +import com.m2pool.lease.vo.*; +import com.m2pool.lease.vo.v2.ShopWalletInfoVo; +import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import static com.m2pool.lease.constant.CoinCharge.getChargeByChainAndCoin; +import static com.m2pool.lease.constant.RabbitmqConstant.PAY_WITHDRAW_QUEUE; + /** *

* 店铺表 服务实现类 @@ -56,6 +69,18 @@ public class LeaseShopServiceImpl extends ServiceImpl addShop(ShopVo shopVo) { LeaseShop leaseShop1 = leaseShopMapper.selectOne(new LambdaQueryWrapper() @@ -67,6 +92,7 @@ public class LeaseShopServiceImpl extends ServiceImpl addShopConfig(ShopConfigVo shopConfigVo) { - + if (checkSystemctlAddress(shopConfigVo.getPayAddress(), shopConfigVo.getChain())){ + return Result.fail("收款钱包不能使用系统钱包"); + } //钱包地址校验 if (!WalletRuleCheckUtils.checkAddress(shopConfigVo.getChain(),shopConfigVo.getPayAddress())){ return Result.fail("钱包地址格式错误"); @@ -282,6 +315,9 @@ public class LeaseShopServiceImpl extends ServiceImpl updateShopConfig(ShopConfigVo shopConfigVo) { + if (checkSystemctlAddress(shopConfigVo.getPayAddress(), shopConfigVo.getChain())){ + return Result.fail("收款钱包不能使用系统钱包"); + } if ( !WalletRuleCheckUtils.checkAddress(shopConfigVo.getChain(),shopConfigVo.getPayAddress())){ return Result.fail("提现地址格式不符合"+shopConfigVo.getChain()+"节点"); } @@ -364,6 +400,22 @@ public class LeaseShopServiceImpl extends ServiceImpl() + .eq(LeaseAutoAddress::getAddress, address) + .eq(LeaseAutoAddress::getFromChain, chain)); + if (leaseAutoAddress != null){ + return true; + } + return false; + } + @Override public Result deleteShopConfig(BaseVo baseVo) { LeaseShopConfig config = leaseShopConfigMapper.selectById(baseVo.getId()); @@ -490,5 +542,125 @@ public class LeaseShopServiceImpl extends ServiceImpl> getShopConfigV2(BaseVo baseVo) { + List list = leaseShopConfigMapper.getShopWalletInfoList(baseVo.getId()); + for (ShopWalletInfoDto shopWalletInfoDto : list) { + BigDecimal chargeByChainAndCoin = getChargeByChainAndCoin(shopWalletInfoDto.getChain(), shopWalletInfoDto.getPayCoin()); + shopWalletInfoDto.setServiceCharge(chargeByChainAndCoin); + } + return Result.success(list); + } + @Override + public Result withdrawBalanceForSeller(BalanceVo balanceVo) { + //校验地址 + if (StringUtils.isEmpty(balanceVo.getToAddress()) || StringUtils.isEmpty(balanceVo.getToChain()) || StringUtils.isEmpty(balanceVo.getToSymbol()) ){ + return Result.fail("提现地址,链,币种 不能为空"); + } + if (!WalletRuleCheckUtils.checkAddress(balanceVo.getToChain(),balanceVo.getToAddress())){ + return Result.fail("提现收款地址格式不正确"); + } + LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper() + .select(LeaseShop::getId).eq(LeaseShop::getUserEmail, SecurityUtils.getUsername()).eq(LeaseShop::getDel, false)); + ShopWalletInfoDto shopWalletInfo = leaseShopConfigMapper.getShopWalletInfo(leaseShop.getId(), balanceVo.getFromAddress(), balanceVo.getToChain(), balanceVo.getToSymbol()); + if (StringUtils.isNull(shopWalletInfo) || StringUtils.isEmpty(shopWalletInfo.getPayAddress())){ + return Result.fail("提现地址不属于您,请登录正确的账号"); + } + GoogleInfo googleInfo = leaseUserMapper.getGoogleInfoByEmail(SecurityUtils.getUsername()); + //开发环境 + //if(googleInfo == null || StringUtils.isBlank(googleInfo.getSecret())){ + // //未绑定定谷歌验证器 + // return Result.fail("您的账号未开启双重验证,请先开启验证!"); + //} + //if(!GoogleAuthenticator.checkCode(googleInfo.getSecret(), balanceVo.getCode(), System.currentTimeMillis())){ + // return Result.fail("谷歌验证码错误"); + //} + + //同一个from只能存在一笔提现中的订单 + Integer recentlyOneData = leasePayWithdrawMessageMapper.getRecentlyOneData(balanceVo.getFromAddress(), balanceVo.getToChain()); + if (recentlyOneData != null && recentlyOneData == 2){ + return Result.fail("提现申请失败,已存在一笔金额正在提现中..."); + } + BigDecimal serviceCharge = getChargeByChainAndCoin(balanceVo.getToChain(), balanceVo.getToSymbol()); + String queueId = UuidGeneratorUtil.generateUuidWithoutHyphen(); + Long timestamp = System.currentTimeMillis()/1000; + //验证通过存储提现记录 + int insert = leasePayWithdrawMessageMapper.insert(LeasePayWithdrawMessage.builder() + .queueId(queueId) + .shopId(leaseShop.getId()) + .toChain(balanceVo.getToChain()) + .toSymbol(balanceVo.getToSymbol()) + .fromChain(shopWalletInfo.getChain()) + .fromSymbol(shopWalletInfo.getPayCoin()) + .fromAddress(shopWalletInfo.getPayAddress()) + .serviceCharge(serviceCharge) + .toAddress(balanceVo.getToAddress()) + .amount(balanceVo.getAmount()) + .build()); + LeaseShopConfig build = LeaseShopConfig.builder() + .id(shopWalletInfo.getId()) + .balance(shopWalletInfo.getBalance().subtract(balanceVo.getAmount())) + .build(); + int update = leaseShopConfigMapper.update(build,new LambdaUpdateWrapper() + .eq(LeaseShopConfig::getBalance, shopWalletInfo.getBalance())); + + if (insert > 0 && update > 0){ + //发送mq消息到队列 + RabbitmqPayWithdrawMessage message = RabbitmqPayWithdrawMessage.builder() + .queue_id(queueId) + .from_address(shopWalletInfo.getPayAddress()) + .to_address(balanceVo.getToAddress()) + .amount(balanceVo.getAmount().subtract(serviceCharge)) + .chain(balanceVo.getToChain()) + .symbol(balanceVo.getToSymbol()) + .fee(serviceCharge) + .timestamp(timestamp) + .sign(HashUtils.sha256(timestamp)) + .build(); + try { + //发送提现消息 + rabbitTemplate.convertAndSend(PAY_WITHDRAW_QUEUE,message); + return Result.success("提现申请成功"); + } catch (Exception e) { + throw new PaymentException(("提现失败,失败原因"+e.getMessage())); + } + } + throw new PaymentException("提现失败,余额已变化,请重新提现!"); + + } + + @Override + public Result updateShopConfigV2(ShopWalletInfoVo shopWalletInfoVo) { + if ( !WalletRuleCheckUtils.checkAddress(shopWalletInfoVo.getChain(),shopWalletInfoVo.getPayAddress())){ + return Result.fail("提现地址格式不符合"+shopWalletInfoVo.getChain()+"节点"); + } + //LeaseShopConfig byId = leaseShopConfigService.getById(shopWalletInfoVo.getId()); + //if (byId.getBalance().compareTo(BigDecimal.ZERO) > 0){ + // return Result.fail("钱包地址余额不为0,请先提现,否则会造成财产丢失"); + //} + boolean b = leaseShopConfigService.updateById(LeaseShopConfig.builder() + .id(shopWalletInfoVo.getId()) + .payAddress(shopWalletInfoVo.getPayAddress()) + .build()); + if (b){ + return Result.success("修改成功"); + } + return Result.fail("修改失败"); + } + + + @Override + public PageResult balanceWithdrawList(PageVo pageVo) { + String userEmail = SecurityUtils.getUsername(); + LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper().eq(LeaseShop::getUserEmail, userEmail)); + PageHelper.startPage(pageVo.getPageNum(), pageVo.getPageSize()); + List payWithdrawMessageDtoList = leasePayWithdrawMessageMapper.getSellerWithdrawRecord(leaseShop.getId()); + PageInfo pageInfo = new PageInfo<>(payWithdrawMessageDtoList); + PageResult success = PageResult.success(payWithdrawMessageDtoList); + 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/service/impl/LeaseShoppingCartServiceImpl.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseShoppingCartServiceImpl.java index e46b8f5..720657a 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 @@ -10,9 +10,10 @@ 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.CoinCharge; -import com.m2pool.lease.constant.PowerUnit; import com.m2pool.lease.constant.RedisKey; import com.m2pool.lease.dto.*; +import com.m2pool.lease.dto.v2.CartMachineInfoDto; +import com.m2pool.lease.dto.v2.ShopCartV2Dto; import com.m2pool.lease.entity.*; import com.m2pool.lease.mapper.*; import com.m2pool.lease.service.LeaseShoppingCartInfoService; @@ -22,23 +23,20 @@ import com.m2pool.lease.vo.BaseVo; import com.m2pool.lease.vo.PageVo; import com.m2pool.lease.vo.ProductAndMachineVo; import com.m2pool.lease.vo.ShoppingCartInfoURDVo; +import com.m2pool.lease.vo.v2.AddGoodsVo; +import com.m2pool.lease.vo.v2.CartInfoVo; import org.springframework.stereotype.Service; 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; import java.util.List; import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; import java.util.stream.Collectors; -import static com.m2pool.lease.constant.PowerUnit.MH_UNIT; - /** *

* 购物车表 服务实现类 @@ -50,8 +48,6 @@ import static com.m2pool.lease.constant.PowerUnit.MH_UNIT; @Service public class LeaseShoppingCartServiceImpl extends ServiceImpl implements LeaseShoppingCartService { - @Resource - private LeaseShoppingCartMapper leaseShoppingCartMapper; @Resource private LeaseShoppingCartInfoMapper leaseShoppingCartInfoMapper; @@ -70,68 +66,40 @@ public class LeaseShoppingCartServiceImpl extends ServiceImpl addGoods(List shoppingCartInfoURDVoList) { - //String userId = SecurityUtils.getUsername(); - //if (shoppingCartInfoURDVoList.isEmpty()){ - // return Result.fail("请选择商品"); - //} - //LeaseShoppingCart leaseShoppingCart = leaseShoppingCartMapper - // .selectOne(new LambdaQueryWrapper().eq(LeaseShoppingCart::getUserId, userId)); - //if (leaseShoppingCart == null){ - // leaseShoppingCart = LeaseShoppingCart.builder().userId(userId).build(); - // int insert = leaseShoppingCartMapper.insert(leaseShoppingCart); - // if (insert <= 0){ - // return Result.fail("添加购物车失败"); - // } - //} - //Long cartId = leaseShoppingCart.getId(); - //List productMachineIds = shoppingCartInfoURDVoList.stream().map(ShoppingCartInfoURDVo::getProductMachineId).collect(Collectors.toList()); - //List leaseShoppingCartInfos = leaseShoppingCartInfoMapper.selectList(new LambdaQueryWrapper() - // .eq(LeaseShoppingCartInfo::getCartId, cartId).in(LeaseShoppingCartInfo::getProductMachineId, productMachineIds)); - // - //if (!leaseShoppingCartInfos.isEmpty()){ - // return Result.fail("购物车中已存在该机器,不能重复添加"); - //} - //List collect = shoppingCartInfoURDVoList.stream().map(shoppingCartInfoURDVo -> - // LeaseShoppingCartInfo.builder() - // .leaseTime(shoppingCartInfoURDVo.getLeaseTime()) - // .cartId(cartId) - // .productId(shoppingCartInfoURDVo.getProductId()) - // .productMachineId(shoppingCartInfoURDVo.getProductMachineId()) - // .build() - //).collect(Collectors.toList()); - //boolean b = leaseShoppingCartInfoService.saveBatch(collect); - //if (b){ - // return Result.success("添加购物车成功"); - //} - //return Result.fail("添加购物车失败"); String userId = SecurityUtils.getUsername(); if (shoppingCartInfoURDVoList.isEmpty()) { return Result.fail("请选择商品"); } - LeaseShoppingCart leaseShoppingCart = leaseShoppingCartMapper - .selectOne(new LambdaQueryWrapper().eq(LeaseShoppingCart::getUserId, userId)); - if (leaseShoppingCart == null) { - leaseShoppingCart = LeaseShoppingCart.builder().userId(userId).build(); - int insert = leaseShoppingCartMapper.insert(leaseShoppingCart); - if (insert <= 0) { - return Result.fail("添加购物车失败"); - } - } - Long cartId = leaseShoppingCart.getId(); - List productMachineIds = shoppingCartInfoURDVoList.stream().map(ShoppingCartInfoURDVo::getProductMachineId).collect(Collectors.toList()); - List leaseShoppingCartInfos = leaseShoppingCartInfoMapper.selectList(new LambdaQueryWrapper() - .eq(LeaseShoppingCartInfo::getCartId, cartId).in(LeaseShoppingCartInfo::getProductMachineId, productMachineIds)); + + List machineIds = shoppingCartInfoURDVoList.stream().map(ShoppingCartInfoURDVo::getProductMachineId).collect(Collectors.toList()); + List leaseProductMachines = leaseProductMachineMapper.selectList(new LambdaQueryWrapper() + .select(LeaseProductMachine::getId, LeaseProductMachine::getShopId) + .in(LeaseProductMachine::getId, machineIds)); + Map collect = leaseProductMachines.stream().collect(Collectors.toMap(LeaseProductMachine::getId, LeaseProductMachine::getShopId)); + //获取用户购物车中所有矿机 + List leaseShoppingCartInfos = leaseShoppingCartInfoMapper + .selectList(new LambdaQueryWrapper() + .eq(LeaseShoppingCartInfo::getUserId, userId)); // 存储需要新增的记录 List newRecords = shoppingCartInfoURDVoList.stream() - .filter(vo -> leaseShoppingCartInfos.stream().noneMatch(info -> info.getProductMachineId().equals(vo.getProductMachineId()))) + .filter(vo -> leaseShoppingCartInfos.stream() + .noneMatch(info -> info.getProductMachineId().equals(vo.getProductMachineId()))) .map(shoppingCartInfoURDVo -> LeaseShoppingCartInfo.builder() + .userId(userId) + .shopId(collect.get(shoppingCartInfoURDVo.getProductMachineId())) .leaseTime(shoppingCartInfoURDVo.getLeaseTime()) - .cartId(cartId) .productId(shoppingCartInfoURDVo.getProductId()) .productMachineId(shoppingCartInfoURDVo.getProductMachineId()) .build() @@ -175,28 +143,20 @@ public class LeaseShoppingCartServiceImpl extends ServiceImpl getGoodsList(PageVo pageVo) { String userId = SecurityUtils.getUsername(); //检查购物车中是否存在商品 - LeaseShoppingCart leaseShoppingCart = leaseShoppingCartMapper.selectOne(new LambdaQueryWrapper() - .eq(LeaseShoppingCart::getUserId, userId)); - if (leaseShoppingCart == null){ - return PageResult.success(new ArrayList<>()); - } - List cartInfoList = leaseShoppingCartInfoMapper.getProductAndMachineIds(leaseShoppingCart.getId()); + List cartInfoList = leaseShoppingCartInfoMapper.getProductAndMachineIds(userId,0); if (cartInfoList.isEmpty()){ 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); + List shopIds = leaseShopMapper.getShopIdsByMachineIds(machineIds); PageHelper.startPage(pageVo.getPageNum(), pageVo.getPageSize()); //查询购物车中店铺信息(一层) List leaseShops = leaseShopMapper.selectList(new LambdaQueryWrapper().in(LeaseShop::getId, shopIds)); - //获取商品售价 List machinePriceByMachineIds = leaseProductMachinePriceMapper.getMachinePriceByMachineIds(machineIds); Map> machinePriceMap = machinePriceByMachineIds.stream().collect(Collectors.groupingBy(MachinePayTypeDto::getProductMachineId)); @@ -336,19 +296,25 @@ public class LeaseShoppingCartServiceImpl extends ServiceImpl deleteBatchGoods(List baseVoList) { - LeaseShoppingCart leaseShoppingCart = leaseShoppingCartMapper.selectOne(new LambdaQueryWrapper().eq(LeaseShoppingCart::getUserId, SecurityUtils.getUsername())); - - if (leaseShoppingCart == null){ - return Result.fail("删除购物车商品失败,购物车未获取到"); + List leaseShoppingCartInfos = leaseShoppingCartInfoMapper.selectList(new LambdaQueryWrapper() + .eq(LeaseShoppingCartInfo::getUserId, SecurityUtils.getUsername()) + .eq(LeaseShoppingCartInfo::getVersion, 0)); + if (leaseShoppingCartInfos.isEmpty()){ + return Result.fail("删除购物车商品失败,购物车中不存在商品"); } - - // 执行删除操作 - int i = leaseShoppingCartInfoMapper.deleteBatchData(leaseShoppingCart.getId(), baseVoList); - - if (i > 0){ - return Result.success("删除购物车商品成功"); + List ids = new ArrayList<>(); + for (LeaseShoppingCartInfo leaseShoppingCartInfo : leaseShoppingCartInfos) { + for (ProductAndMachineVo baseVo : baseVoList){ + if (leaseShoppingCartInfo.getProductMachineId().equals(baseVo.getMachineId())){ + ids.add(leaseShoppingCartInfo.getId()); + } + } } - return Result.fail("删除购物车商品失败"); + if (ids.isEmpty()){ + return Result.fail("删除购物车商品失败,购物车中不存在该商品"); + } + leaseShoppingCartInfoMapper.deleteBatchData(ids); + return Result.success("删除购物车商品成功"); } @Override @@ -364,14 +330,11 @@ public class LeaseShoppingCartServiceImpl extends ServiceImpl deleteBatchGoodsForIsDelete() { - - LeaseShoppingCart leaseShoppingCart = leaseShoppingCartMapper.selectOne(new LambdaQueryWrapper() - .eq(LeaseShoppingCart::getUserId, SecurityUtils.getUsername())); - List leaseShoppingCartInfos = leaseShoppingCartInfoMapper.selectList(new LambdaQueryWrapper() - .eq(LeaseShoppingCartInfo::getCartId, leaseShoppingCart.getId())); + .eq(LeaseShoppingCartInfo::getUserId, SecurityUtils.getUsername())); - List machineIds = leaseShoppingCartInfos.stream().map(LeaseShoppingCartInfo::getProductMachineId).collect(Collectors.toList()); + List machineIds = leaseShoppingCartInfos.stream().map(LeaseShoppingCartInfo::getProductMachineId) + .collect(Collectors.toList()); List leaseProductMachines = leaseProductMachineMapper.selectList(new LambdaQueryWrapper() .in(LeaseProductMachine::getId, machineIds)); List delMachineIds = leaseProductMachines.stream().filter(productMachine -> productMachine.getDel() || productMachine.getState() == 1) @@ -383,10 +346,212 @@ public class LeaseShoppingCartServiceImpl extends ServiceImpl() .in(LeaseShoppingCartInfo::getProductMachineId, delMachineIds)); - if (delete > 0){ return Result.success("删除购物车已下架商品成功"); } return Result.fail("删除失败,不存在已下架商品"); } + + @Override + public Result addGoodsV2(List addGoodsVoList) { + + String userId = SecurityUtils.getUsername(); + if (addGoodsVoList.isEmpty()) { + return Result.fail("请选择商品"); + } + + List machineIds = addGoodsVoList.stream().map(AddGoodsVo::getId).collect(Collectors.toList()); + List leaseProductMachines = leaseMachineMapper.selectList(new LambdaQueryWrapper() + .select(LeaseMachine::getId, LeaseMachine::getShopId) + .in(LeaseMachine::getId, machineIds)); + Map collect = leaseProductMachines.stream() + .collect(Collectors.toMap(LeaseMachine::getId, LeaseMachine::getShopId)); + //获取用户购物车中所有矿机 + List leaseShoppingCartInfos = leaseShoppingCartInfoMapper + .selectList(new LambdaQueryWrapper() + .eq(LeaseShoppingCartInfo::getUserId, userId)); + + // 存储需要新增的记录 + List newRecords = addGoodsVoList.stream() + .filter(vo -> leaseShoppingCartInfos.stream() + .noneMatch(info -> info.getProductMachineId().equals(vo.getId()))) + .map(shoppingCartInfoURDVo -> + LeaseShoppingCartInfo.builder() + .userId(userId) + .shopId(collect.get(shoppingCartInfoURDVo.getId())) + .leaseTime(shoppingCartInfoURDVo.getLeaseTime()) + .numbers(shoppingCartInfoURDVo.getNumbers()) + .productMachineId(shoppingCartInfoURDVo.getId()) + .version(1) + .build() + ).collect(Collectors.toList()); + + // 存储需要更新的记录 + Map voMap = addGoodsVoList.stream() + .collect(Collectors.toMap(AddGoodsVo::getId, vo -> vo)); + List updateList = leaseShoppingCartInfos.stream() + .peek(info -> { + AddGoodsVo vo = voMap.get(info.getProductMachineId()); + if (vo != null && vo.getNumbers() != null) { + info.setNumbers(info.getNumbers()+vo.getNumbers()); + info.setLeaseTime(info.getLeaseTime() + vo.getLeaseTime()); + info.setId(info.getId()); + } + }) + .collect(Collectors.toList()); + + System.out.println("updateList"+ JSONUtil.toJsonPrettyStr(updateList)); + System.out.println("newRecords"+ JSONUtil.toJsonPrettyStr(newRecords)); + // 执行更新操作 + if (!updateList.isEmpty()) { + boolean updateResult = leaseShoppingCartInfoService.updateBatchById(updateList); + if (!updateResult) { + return Result.fail("更新购物车租赁时间失败"); + } + } + + // 执行新增操作 + if (!newRecords.isEmpty()) { + boolean saveResult = leaseShoppingCartInfoService.saveBatch(newRecords); + if (!saveResult) { + return Result.fail("添加新购物车记录失败"); + } + } + + return Result.success("添加购物车成功"); + } + + @Override + public PageResult getGoodsListV2(PageVo pageVo) { + String userId = SecurityUtils.getUsername(); + //检查购物车中是否存在商品 + List cartInfoList = leaseShoppingCartInfoMapper.getProductAndMachineIds(userId,1); + if (cartInfoList.isEmpty()){ + return PageResult.success(new ArrayList<>()); + } + List machineIds = new ArrayList<>(); + Map machineMap = new HashMap<>(); + for (ShoppingCartInfoDto shoppingCartInfoDto : cartInfoList) { + machineIds.add(shoppingCartInfoDto.getProductMachineId()); + machineMap.put(shoppingCartInfoDto.getProductMachineId(), shoppingCartInfoDto.getLeaseTime()); + } + + List shopIds = leaseMachineMapper.getShopIdsByMachineIds(machineIds); + PageHelper.startPage(pageVo.getPageNum(), pageVo.getPageSize()); + //查询购物车中店铺信息(一层) + List leaseShops = leaseShopMapper.selectList(new LambdaQueryWrapper() + .in(LeaseShop::getId, shopIds)); + + //获取商品售价 + List machinePriceByMachineIds = leaseMachinePriceMapper.getMachinePriceByMachineIds(machineIds); + Map> machinePriceMap = machinePriceByMachineIds.stream() + .collect(Collectors.groupingBy(MachinePayTypeDto::getProductMachineId)); + + //查询店铺中机器详情 + List leaseProductMachines = leaseMachineMapper.getMachinesByIds(machineIds); + //获取实时币价 TODO 这里需要新加入一些币种的全网实时算力以及实时币价和报块奖励 + //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); + //} + + //设置每个矿机的售价,并按店铺分组 + Map> shopIdAndMachineInfoMap = leaseProductMachines.stream() + .peek(productMachineDto -> { + productMachineDto.setPriceList(machinePriceMap.get(productMachineDto.getId())); + }) + .collect(Collectors.groupingBy(CartMachineInfoDto::getShopId)); + //获取商铺钱包配置信息 + List shopWalletInfo = leaseShopMapper.getShopWalletInfoList(shopIds); + Map> payConfigMap = shopWalletInfo.stream() + .map(payConfigDto->{ + payConfigDto.setDeductibleAmount(CoinCharge.getDeductibleAmountByChainAndCoin(payConfigDto.getPayChain(), payConfigDto.getPayCoin())); + payConfigDto.setFee(CoinCharge.getChargeByChainAndCoin(payConfigDto.getPayChain(), payConfigDto.getPayCoin())); + return payConfigDto; + }) + .collect(Collectors.groupingBy(PayConfigDto::getShopId)); + //组合返回对象 + List shopCartList = leaseShops.stream().map(leaseShop -> { + List productMachineList = shopIdAndMachineInfoMap.get(leaseShop.getId()); + return ShopCartV2Dto.builder() + .id(leaseShop.getId()) + .name(leaseShop.getName()) + .totalMachine(productMachineList != null ? productMachineList.size() : 0) + .payConfigList(payConfigMap.get(leaseShop.getId())) + .cartMachineInfoDtoList(productMachineList) + .build(); + }).collect(Collectors.toList()); + + + + //计算不同链和币种对应的总售价 + for (ShopCartV2Dto shopCartDto : shopCartList) { + //遍历每个商铺下的矿机 + List productMachineDtoList = shopCartDto.getCartMachineInfoDtoList(); + Map totalPriceMap = new HashMap<>(); + Map totalPriceDtoMap = new HashMap<>(); + for (CartMachineInfoDto 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())); + } + } + 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; + } + + @Override + public Result deleteBatchGoodsV2(List baseVoList) { + List ids = baseVoList.stream().map(CartInfoVo::getCartInfoId).collect(Collectors.toList()); + leaseShoppingCartInfoMapper.deleteBatchData(ids); + return Result.success("删除购物车商品成功"); + } + + @Override + public Result deleteBatchGoodsForIsDeleteV2() { + List leaseShoppingCartInfos = leaseShoppingCartInfoMapper.selectList(new LambdaQueryWrapper() + .eq(LeaseShoppingCartInfo::getUserId, SecurityUtils.getUsername())); + + List machineIds = leaseShoppingCartInfos.stream().map(LeaseShoppingCartInfo::getProductMachineId).collect(Collectors.toList()); + List leaseMachines = leaseMachineMapper.selectList(new LambdaQueryWrapper() + .in(LeaseMachine::getId, machineIds)); + + List delMachineIds = leaseMachines.stream().filter(machine -> machine.getDel() || machine.getState()) + .map(LeaseMachine::getId).collect(Collectors.toList()); + + if (delMachineIds.isEmpty()){ + return Result.success("删除购物车已下架商品成功"); + } + + int delete = leaseShoppingCartInfoMapper.delete(new LambdaUpdateWrapper() + .in(LeaseShoppingCartInfo::getProductMachineId, delMachineIds)); + if (delete > 0){ + return Result.success("删除购物车已下架商品成功"); + } + return Result.fail("删除失败,不存在已下架商品"); + + } } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseUserServiceImpl.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseUserServiceImpl.java index ce0b7e9..076316b 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseUserServiceImpl.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseUserServiceImpl.java @@ -1,13 +1,12 @@ 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.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; -import com.m2pool.common.core.utils.GoogleAuthenticator; +import com.m2pool.common.core.utils.DateUtils; import com.m2pool.common.core.utils.StringUtils; import com.m2pool.common.security.utils.SecurityUtils; import com.m2pool.lease.dto.*; @@ -19,15 +18,30 @@ import com.m2pool.lease.mq.message.RabbitmqPayWithdrawMessage; import com.m2pool.lease.service.LeaseUserService; import com.m2pool.lease.utils.*; import com.m2pool.lease.vo.*; +import org.apache.commons.io.FileUtils; import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; +import java.net.URLEncoder; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.*; import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; import static com.m2pool.lease.constant.CoinCharge.getAllChargesAsDtoList; import static com.m2pool.lease.constant.CoinCharge.getChargeByChainAndCoin; @@ -73,6 +87,20 @@ public class LeaseUserServiceImpl extends ServiceImpl login(UserURDVo userURDVo) { LeaseUser leaseUser = leaseUserMapper.selectOne(new LambdaQueryWrapper() @@ -364,7 +392,7 @@ public class LeaseUserServiceImpl extends ServiceImpl pageInfo = new PageInfo<>(payWithdrawMessageDtos); - System.out.println(userEmail + "用户提现"+ payWithdrawMessageDtos); + System.out.println(userEmail + "用户提现" + payWithdrawMessageDtos); PageResult success = PageResult.success(payWithdrawMessageDtos); success.setTotal(pageInfo.getTotal()); success.setTotalPage(pageInfo.getPages()); @@ -466,4 +494,150 @@ public class LeaseUserServiceImpl extends ServiceImpl allChargesAsDtoList = getAllChargesAsDtoList(); return Result.success(allChargesAsDtoList); } + + public String getAuthCode(String userEmail){ + + System.out.println("获取下载权限码"+userEmail); + LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper() + .select(LeaseShop::getIdentityCode) + .eq(LeaseShop::getUserEmail, userEmail)); + + if (leaseShop == null){ + throw new RuntimeException("下载失败,下载客户端权限,请重新登录并创建店铺"); + } + if (StringUtils.isEmpty(leaseShop.getIdentityCode())) { + leaseShop.setIdentityCode(UuidGeneratorUtil.generateUuidWithoutHyphen()); + leaseShopMapper.updateById(leaseShop); + } + return leaseShop.getIdentityCode(); + } + + + @Override + public void downloadClient(String userEmail,HttpServletRequest request, HttpServletResponse response) { + String auth = getAuthCode(userEmail); + //设置响应头信息 + response.reset(); + response.setCharacterEncoding("utf-8"); + response.setContentType("multipart/form-data"); + //设置压缩包的名字,date为时间戳 + String downloadName = "gpu.zip"; + String agent = request.getHeader("USER-AGENT"); + try { + //针对IE或者以IE为内核的浏览器: + if (agent.contains("MSIE") || agent.contains("Trident")) { + downloadName = URLEncoder.encode(downloadName, "UTF-8"); + } else { + //非IE浏览器的处理: + downloadName = new String(downloadName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1); + } + + // 创建临时目录 + Path tempDir = Files.createTempDirectory("client-download"); + + + // 创建auth.txt文件 + Path authFile = tempDir.resolve("auth"); + Files.write(authFile, auth.getBytes(StandardCharsets.UTF_8)); + + //读取/home/ubuntu/web/client/bin 下所有文件和 auth文件一起压缩 + Path sourceDir = Paths.get(downloadClient); + try { + Files.walk(sourceDir) + .filter(path -> !Files.isDirectory(path)) + .forEach(path -> { + try { + Path dest = tempDir.resolve(sourceDir.relativize(path)); + Files.createDirectories(dest.getParent()); + Files.copy(path, dest); + } catch (IOException e) { + log.error("复制客户端文件失败", e); + } + }); + } catch (IOException e) { + log.error("遍历客户端文件失败", e); + } + + // 创建新的zip文件 + Path zipFile = Files.createTempFile("client", ".zip"); + try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(zipFile.toFile().toPath()))) { + // 添加解压后的文件和auth.txt到新zip + Files.walk(tempDir) + .filter(path -> !Files.isDirectory(path)) + .forEach(path -> { + try { + // 修改这里,确保文件名编码正确 + String entryName = tempDir.relativize(path).toString().replace('\\', '/'); + ZipEntry zipEntry = new ZipEntry(entryName); + zos.putNextEntry(zipEntry); + Files.copy(path, zos); + zos.closeEntry(); + } catch (IOException e) { + log.error("添加文件到zip失败", e); + } + }); + } + + // 设置响应头 + response.setHeader("Content-Disposition", "attachment;fileName=" + downloadName); + response.setContentLength((int) Files.size(zipFile)); + + // 发送文件 + Files.copy(zipFile, response.getOutputStream()); + response.flushBuffer(); + + // 清理临时文件 + Files.walk(tempDir) + .sorted(Comparator.reverseOrder()) + .forEach(path -> { + try { + Files.deleteIfExists(path); + } catch (IOException e) { + System.out.println("清理临时文件失败"); + } + }); + Files.deleteIfExists(zipFile); + + } catch (Exception e) { + log.error("系统异常", e); + throw new RuntimeException("下载客户端失败", e); + } + + } + + + + @Override + public String getClientVersion() { + try { + return readTxtFromDir(downloadClient, configName); + }catch (Exception e){ + return "获取配置信息失败"+e; + } + + } + + + /** + * 读取ZIP压缩文件中指定txt文件的内容 + * @param filePath 文件目录 + * @param targetTxtName 目标txt文件名(含扩展名,如"config.txt") + * @return txt文件内容字符串 + * @throws IOException 文件操作异常 + */ + public String readTxtFromDir(String filePath, String targetTxtName) throws IOException { + //遍历 zipFilePath 然后找到文件名未targetTxtName(带后缀) 的文件 + File dir = new File(filePath); + if (!dir.isDirectory()) { + throw new IllegalArgumentException("提供的路径不是一个目录"); + } + + File[] files = dir.listFiles((dir1, name) -> name.equals(targetTxtName)); + if (files == null || files.length == 0) { + throw new FileNotFoundException("未找到目标文件: " + targetTxtName); + } + + return new String(Files.readAllBytes(files[0].toPath()), StandardCharsets.UTF_8); + } + } 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 c0853a9..97dd420 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 @@ -1,12 +1,12 @@ package com.m2pool.lease.vo; +import com.m2pool.lease.dto.v2.OrderMiningInfoDto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import java.math.BigDecimal; import java.util.List; /** @@ -26,4 +26,7 @@ public class OrderAndCodeVo { @ApiModelProperty(value = "订单信息列表",required = true) private List orderInfoVoList; + + @ApiModelProperty(value = "挖矿配置",required = true) + private List orderMiningInfoDtoList; } 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 9dce327..a31f17b 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,13 +37,16 @@ public class OrderInfoVo extends BaseVo{ @ApiModelProperty(value = "租赁时长",example = "1") private Integer leaseTime; + @ApiModelProperty(value = "租赁数量",example = "1") + private Integer numbers = 1; + + @ApiModelProperty(value = "矿机型号 0 ASIC 1 GPU") + private Integer type; + @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/ProductMachineVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductMachineVo.java index 3067d90..78408b4 100644 --- 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 @@ -28,10 +28,10 @@ public class ProductMachineVo extends PageVo{ private Long id; - @ApiModelProperty(value = "最大实际算力") + @ApiModelProperty(value = "最大算力") private BigDecimal maxPower = BigDecimal.ZERO; - @ApiModelProperty(value = "最小实际算力") + @ApiModelProperty(value = "最小算力") private BigDecimal minPower = BigDecimal.ZERO; @ApiModelProperty(value = "最大功耗 单位kw/h",example = "10") diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductPageVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductPageVo.java index 82c7046..b33ec81 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductPageVo.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ProductPageVo.java @@ -27,7 +27,6 @@ public class ProductPageVo extends PageVo{ */ @ApiModelProperty(value = "矿机挖矿币种 nexa rxd dgbo dgbq dgbs alph enx grs mona",example = "nexa") private String coin; - /** * 算法 */ diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ShopVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ShopVo.java index aa18f95..26a21db 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ShopVo.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/ShopVo.java @@ -8,6 +8,7 @@ import io.swagger.annotations.ApiOperation; import lombok.*; import java.io.Serializable; +import java.math.BigDecimal; import java.time.LocalDateTime; /** @@ -48,6 +49,9 @@ public class ShopVo extends BaseVo{ */ @ApiModelProperty(value = "商铺状态 0 待审核 1 审核通过(店铺开启) 2 店铺关闭",example = "1") private Integer state; + + @ApiModelProperty(value = "店铺手续费比例 范围0.01-0.1",example = "0.01") + private BigDecimal feeRate; /** * 逻辑删除字段 */ diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/AddGoodsVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/AddGoodsVo.java new file mode 100644 index 0000000..747edca --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/AddGoodsVo.java @@ -0,0 +1,35 @@ +package com.m2pool.lease.vo.v2; + +import com.m2pool.lease.vo.BaseVo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * 购物车详情请求对象 + *

+ * + * @author yyb + * @since 2025-07-24 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "购物车详情请求对象V2",value = "AddGoodsVo") +public class AddGoodsVo extends BaseVo { + + @ApiModelProperty(value = "矿机ID", example = "1") + private Long id; + + @ApiModelProperty(value = "租赁天数", example = "1") + private Integer leaseTime; + + @ApiModelProperty(value = "购买数量(ASIC类型)", example = "1") + private Integer numbers; + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/AsicCoinAndAlgoVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/AsicCoinAndAlgoVo.java new file mode 100644 index 0000000..41c7a4f --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/AsicCoinAndAlgoVo.java @@ -0,0 +1,44 @@ +package com.m2pool.lease.vo.v2; + +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 = "asic 矿机新增 算力,币种请求对象",value = "AsicCoinAndAlgoVo" ) +public class AsicCoinAndAlgoVo { + + @ApiModelProperty(value = "币种算力配置id") + private Long coinAndPowerId; + + + + @ApiModelProperty(value = "币种(多个逗号隔开)") + private String coin; + + @ApiModelProperty(value = "算法(多个逗号隔开)") + private String algorithm; + + @ApiModelProperty(value = "理论算力)",example = "0.01") + private BigDecimal theoryPower; + + @ApiModelProperty(value = "商品机器单机算力单位",example = "TH/S") + private String unit; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/AsicMachineParamsVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/AsicMachineParamsVo.java new file mode 100644 index 0000000..1ec2cf5 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/AsicMachineParamsVo.java @@ -0,0 +1,54 @@ +package com.m2pool.lease.vo.v2; + +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 = "AsicMachineParamsVo" ) +public class AsicMachineParamsVo { + + @ApiModelProperty(value = "矿机id(修改接口)") + private Long id; + + @ApiModelProperty(value = "矿机型号/名称",example = "龍珠") + private String name; + + @ApiModelProperty(value = "最大可租借天数(默认七天)",example = "7") + private Integer maxLeaseDays; + + @ApiModelProperty(value = "可出售数量",example = "1") + private Integer saleNumbers; + + + @ApiModelProperty(value = "功耗",example = "0.01") + private BigDecimal powerDissipation; + + @ApiModelProperty(value = "状态0上架 1下架",example = "上架") + private Boolean state; + + @ApiModelProperty(value = "币种和算力配置") + private List coinAndAlgoList; + + @ApiModelProperty(value = "币种价格配置") + private List priceList; + + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/CartInfoVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/CartInfoVo.java new file mode 100644 index 0000000..564a4ff --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/CartInfoVo.java @@ -0,0 +1,23 @@ +package com.m2pool.lease.vo.v2; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @Description 购物车商品机器删除请求对象 + * @Date 2025/7/25 11:15 + * @Author yyb + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "购物车商品机器删除请求对象",value = "CartInfoVo" ) +public class CartInfoVo { + + @ApiModelProperty(value = "购物车详情id") + private Long cartInfoId; + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/CoinAndAlgorithmVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/CoinAndAlgorithmVo.java new file mode 100644 index 0000000..eb41e6b --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/CoinAndAlgorithmVo.java @@ -0,0 +1,26 @@ +package com.m2pool.lease.vo.v2; + + +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; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@ApiModel(description = "币种算法请求对象",value = "CoinAndAlgorithmVo") +public class CoinAndAlgorithmVo { + + + @ApiModelProperty(value = "币种") + private String coin; + + @ApiModelProperty(value = "算法") + private String algorithm; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/GpuMachineParamsVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/GpuMachineParamsVo.java new file mode 100644 index 0000000..b9dc309 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/GpuMachineParamsVo.java @@ -0,0 +1,39 @@ +package com.m2pool.lease.vo.v2; + +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 = "GpuMachineParamsVo" ) +public class GpuMachineParamsVo { + + @ApiModelProperty(value = "矿机id(修改接口)") + private Long id; + + @ApiModelProperty(value = "最大可租借天数(默认七天)",example = "7") + private Integer maxLeaseDays; + + @ApiModelProperty(value = "0 上架 1 下架",example = "1") + private Boolean state; + + @ApiModelProperty(value = "币种价格配置") + private List priceList; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/MachinePayTypeVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/MachinePayTypeVo.java new file mode 100644 index 0000000..ce5a26a --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/MachinePayTypeVo.java @@ -0,0 +1,40 @@ +package com.m2pool.lease.vo.v2; + +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 = "MachinePayTypeVo" ) +public class MachinePayTypeVo { + @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/vo/v2/MachineStateVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/MachineStateVo.java new file mode 100644 index 0000000..9297711 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/MachineStateVo.java @@ -0,0 +1,34 @@ +package com.m2pool.lease.vo.v2; + +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 = "MachineStateVo" ) +public class MachineStateVo { + + @ApiModelProperty(value = "矿机id(修改接口)") + private Long id; + + @ApiModelProperty(value = "上下架状态: 0 上架,1 下架") + private Boolean state; + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/SellerMachineVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/SellerMachineVo.java new file mode 100644 index 0000000..79a8f5c --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/SellerMachineVo.java @@ -0,0 +1,34 @@ +package com.m2pool.lease.vo.v2; + +import com.m2pool.lease.vo.PageVo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + *

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

+ * + * @author yyb + * @since 2025-07-23 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "卖家详情页矿机列表请求对象",value = "SellerMachineVo" ) +public class SellerMachineVo extends PageVo { + @ApiModelProperty(value = "型号(gpu名称 或asic 名称)",example = "4090") + private String name; + + @ApiModelProperty(value = "搜索关键词",example = "4090") + private String keyword; + + @ApiModelProperty(value = "类型 0:ASIC 1:GPU") + private Boolean type; + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/ShopMachineVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/ShopMachineVo.java new file mode 100644 index 0000000..2f4f66e --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/ShopMachineVo.java @@ -0,0 +1,73 @@ +package com.m2pool.lease.vo.v2; + +import com.m2pool.lease.vo.PageVo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + *

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

+ * + * @author yyb + * @since 2025-07-23 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "首页店铺详情页矿机列表请求对象",value = "ShopMachineVo" ) +public class ShopMachineVo extends PageVo { + + @ApiModelProperty(value = "店铺id") + private Long shopId; + + //@ApiModelProperty(value = "最大算力") + //private BigDecimal maxPower = BigDecimal.ZERO; + // + //@ApiModelProperty(value = "最小算力") + //private BigDecimal minPower = BigDecimal.ZERO; + // + //@ApiModelProperty(value = "最大功耗 单位kw/h",example = "10") + //private BigDecimal maxPowerDissipation = BigDecimal.ZERO; + // + //@ApiModelProperty(value = "最小功耗 单位kw/h",example = "10") + //private BigDecimal minPowerDissipation = BigDecimal.ZERO; + + + @ApiModelProperty(value = "最大单价") + private BigDecimal maxPrice = BigDecimal.ZERO; + + @ApiModelProperty(value = "最小单价") + private BigDecimal minPrice = BigDecimal.ZERO; + + @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; + + @ApiModelProperty(value = "币种单位",example = "MH/S") + private String unit; + + @ApiModelProperty(value = "类型 0:ASIC 1:GPU") + private Boolean type; + + @ApiModelProperty(value = "币种算法关键字") + private String keyword; + + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/ShopWalletInfoVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/ShopWalletInfoVo.java new file mode 100644 index 0000000..823ef7f --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/v2/ShopWalletInfoVo.java @@ -0,0 +1,36 @@ +package com.m2pool.lease.vo.v2; + +import com.m2pool.lease.vo.BaseVo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * 店铺商品配置请求对象 + *

+ * + * @author yyb + * @since 2025-08-05 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "店铺钱包配置请求对象",value = "ShopWalletInfoVo") +public class ShopWalletInfoVo { + + + @ApiModelProperty(value = "id",example = "1") + private Long id; + + @ApiModelProperty(value = "链名称",example = "tron") + private String chain; + + @ApiModelProperty(value = "卖方对应收款钱包",example = "nexa:nqtsq5g50jkkmklvjyaflg46c4nwuy46z9gzswqe3l0csc7g") + private String payAddress; + +} diff --git a/m2pool-modules/m2pool-lease/src/main/resources/bootstrap-dev.yml b/m2pool-modules/m2pool-lease/src/main/resources/bootstrap-dev.yml index 01c95d6..7620643 100644 --- a/m2pool-modules/m2pool-lease/src/main/resources/bootstrap-dev.yml +++ b/m2pool-modules/m2pool-lease/src/main/resources/bootstrap-dev.yml @@ -37,3 +37,13 @@ spring: multipart: max-file-size: 2MB max-request-size: 8MB + +client: + download: + path: https://test.m2pool.com/client + config: version + +netty: + tcp: + client: + port: 2345 diff --git a/m2pool-modules/m2pool-lease/src/main/resources/bootstrap-test.yml b/m2pool-modules/m2pool-lease/src/main/resources/bootstrap-test.yml index 0719136..0806049 100644 --- a/m2pool-modules/m2pool-lease/src/main/resources/bootstrap-test.yml +++ b/m2pool-modules/m2pool-lease/src/main/resources/bootstrap-test.yml @@ -37,3 +37,22 @@ spring: multipart: max-file-size: 2MB max-request-size: 8MB +file: + domain: https://test.m2pool.com + path: /var/www/html/web_test + # img: /img + filepath: /home/ubuntu/web + prefix: /statics + +client: + # 客户端安装包 + download: + path: /home/ubuntu/web/client + client: /home/ubuntu/web/client/bin + # 客户端版本号文件名 + config: version + +netty: + tcp: + client: + port: 2345 diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseGpuConfigMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseGpuConfigMapper.xml new file mode 100644 index 0000000..430c637 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseGpuConfigMapper.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + id, brand, name, status, memory, power_dissipation, del + + + insert into lease_gpu_config (brand, name, memory) + values + + (#{item.brand}, #{item.name}, #{item.mem}) + + ON DUPLICATE KEY UPDATE + brand = VALUES(brand), + `name` = VALUES(`name`), + memory = VALUES(memory) + + + + diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseMachineConfigMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseMachineConfigMapper.xml new file mode 100644 index 0000000..f700fca --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseMachineConfigMapper.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + id, machine_id, brand, name, status, coin, hashrate, algorithm, icon, unit, month_income, power_dissipation, del + + + + + diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseMachineMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseMachineMapper.xml new file mode 100644 index 0000000..4d2a88b --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseMachineMapper.xml @@ -0,0 +1,410 @@ + + + + + + + + + + + + + + + + + + + + + + + + id, shop_id, type, single_power, total_power, unit, max_lease_days, price, power_dissipation, sale_state, state, del, create_time, update_time, coin, algorithm, gpu_config_id, user, miner, sale_numbers, sale_out_numbers + + + + + + + + + + + + + + + + + + + + + + + + UPDATE lease_machine + SET + sale_state = 1 + WHERE + id IN + + #{item.id} + + and sale_state = 0 + + + + UPDATE lease_machine + SET + sale_out_numbers = #{item.saleOutNumbers} + sale_state = CASE WHEN #{item.saleOutNumbers} = sale_numbers THEN 1 ELSE sale_state END + WHERE + id = #{item.id} + AND sale_out_numbers = #{item.lockNumbers} + + + + + + + + diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseMachinePriceMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseMachinePriceMapper.xml new file mode 100644 index 0000000..adba03e --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseMachinePriceMapper.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + id, machine_id, price, coin, chain, del + + + + + diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseMiningSoftwareConfigMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseMiningSoftwareConfigMapper.xml new file mode 100644 index 0000000..c7ad372 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseMiningSoftwareConfigMapper.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + id, name, coin, algorithm, icon, del + + + diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseOrderInfoMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseOrderInfoMapper.xml index ba053b1..1a3b4dd 100644 --- a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseOrderInfoMapper.xml +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseOrderInfoMapper.xml @@ -26,7 +26,8 @@ loo.user_id as userId, loo.total_price as totalPrice, loo.status, - loo.create_time as createTime + loo.create_time as createTime, + loo.update_time as endTime from lease_order_info loo del = 0 and user_id = #{userId} diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseOrderMiningMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseOrderMiningMapper.xml new file mode 100644 index 0000000..3f31b26 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseOrderMiningMapper.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + id, order_id, coin, algorithm, pool, pool_url, worker_id, wallet_address, watch_url, status, start_time, end_time, del + + + 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 ef182b7..e44742e 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 @@ -107,5 +107,21 @@ FROM lease_pay_withdraw_message + 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 dd6abd7..6e2d4e3 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 @@ -121,7 +121,7 @@ order by lp.sale_number desc,lp.create_time desc + + 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 4f44746..8188d89 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 @@ -58,15 +58,15 @@ and del = 0 - SELECT DISTINCT shop_id as shopId FROM - lease_product + lease_product_machine WHERE id IN - - #{productId} + + #{machineId} 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 f56018e..87f8f79 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 @@ -5,7 +5,6 @@ - @@ -22,19 +21,16 @@ product_id as productId, lease_time as leaseTime from lease_shopping_cart_info - where cart_id = #{cartId} + where user_id = #{userId} and version = #{version} DELETE FROM lease_shopping_cart_info - WHERE cart_id = #{cartId} - - AND ( - - (product_id = #{item.productId} AND product_machine_id = #{item.machineId}) - - ) - + WHERE id IN + + #{id} +