租赁系统
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
package com.m2pool.lease.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.lease.entity.LeaseMachineConfig;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* GPU对应币种挖矿算力(只要gpu类型相同那么就使用这个配置) 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-11-27
|
||||
*/
|
||||
public interface LeaseMachineConfigService extends IService<LeaseMachineConfig> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.m2pool.lease.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.lease.entity.LeaseMachinePrice;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 商品表对应的物品机器表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-11-25
|
||||
*/
|
||||
public interface LeaseMachinePriceService extends IService<LeaseMachinePrice> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
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 org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* gpu类型出售矿机表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-11-21
|
||||
*/
|
||||
public interface LeaseMachineService extends IService<LeaseMachine> {
|
||||
|
||||
/**
|
||||
* 获取商品对应的实际商品列表
|
||||
* @return
|
||||
*/
|
||||
PageResult<ShopInfoDto> getShopList(ProductPageVo productPageVo);
|
||||
|
||||
|
||||
/**
|
||||
* 获取店铺矿机详情
|
||||
* @return
|
||||
*/
|
||||
PageResult<MachineInfoDto> getShopMachineList(ShopMachineVo shopMachineVo);
|
||||
|
||||
|
||||
/**
|
||||
* 获取卖家页面矿机列表
|
||||
* @return
|
||||
*/
|
||||
PageResult<SellerMachineInfoDto> getShopMachineListForSeller(SellerMachineVo sellerMachineVo);
|
||||
|
||||
|
||||
/**
|
||||
* 添加ASIC矿机
|
||||
* @return
|
||||
*/
|
||||
Result<String> addAsicMachine( AsicMachineParamsVo asicMachineParamsVo);
|
||||
|
||||
|
||||
/**
|
||||
* 修改ASIC矿机
|
||||
* @return
|
||||
*/
|
||||
Result<String> updateAsicMachine( AsicMachineParamsVo asicMachineParamsVo);
|
||||
|
||||
|
||||
/**
|
||||
* 修改GPU矿机
|
||||
* @return
|
||||
*/
|
||||
Result<String> updateGpuMachine(List<GpuMachineParamsVo> gpuMachineParamsVoList);
|
||||
|
||||
/**
|
||||
* 矿机上下架
|
||||
* @return
|
||||
*/
|
||||
Result<String> updateMachineState(MachineStateVo machineStateVo);
|
||||
|
||||
|
||||
/**
|
||||
* 删除矿机
|
||||
* @return
|
||||
*/
|
||||
Result<String> deleteMachine(BaseVo baseVo);
|
||||
|
||||
|
||||
/**
|
||||
* 获取支持的币种
|
||||
* @return
|
||||
*/
|
||||
Result<List<String>> getSupportCoin();
|
||||
|
||||
|
||||
/**
|
||||
* 获取支持的算法
|
||||
* @return
|
||||
*/
|
||||
Result<List<String>> getSupportAlgo( String coin);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.m2pool.lease.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.lease.entity.LeaseNexaMachineAvgPower;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 矿池nexa机器实时平均算力 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-29
|
||||
*/
|
||||
public interface LeaseNexaMachineAvgPowerService extends IService<LeaseNexaMachineAvgPower> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.m2pool.lease.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.lease.entity.LeaseNexaMachinePower;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 已售商品矿工实时算力表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-25
|
||||
*/
|
||||
public interface LeaseNexaMachinePowerService extends IService<LeaseNexaMachinePower> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.m2pool.lease.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.lease.dto.*;
|
||||
import com.m2pool.lease.dto.v2.*;
|
||||
import com.m2pool.lease.entity.LeaseOrderInfo;
|
||||
import com.m2pool.lease.vo.*;
|
||||
import com.m2pool.lease.vo.v2.CoinAndAlgorithmVo;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 订单表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
public interface LeaseOrderInfoService extends IService<LeaseOrderInfo> {
|
||||
/**
|
||||
* 添加订单
|
||||
* @param orderAndCodeVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> addOrders(OrderAndCodeVo orderAndCodeVo);
|
||||
|
||||
|
||||
/**
|
||||
* 再次购买
|
||||
* @param orderInfoVoList
|
||||
* @return
|
||||
*/
|
||||
Result<List<PaymentRecordDto>> buyAgain(List<OrderInfoVo> orderInfoVoList);
|
||||
/**
|
||||
* 根据订单状态查询订单列表(买家)
|
||||
* @param orderInfoStateVo
|
||||
* @return
|
||||
*/
|
||||
PageResult<OrderInfoDto> getOrdersByStatus(OrderInfoStateVo orderInfoStateVo);
|
||||
|
||||
/**
|
||||
* 根据订单状态查询订单列表(卖家)
|
||||
* @param orderInfoStateVo
|
||||
* @return
|
||||
*/
|
||||
PageResult<OrderInfoDto> getOrdersByStatusForSeller(OrderInfoStateVo orderInfoStateVo);
|
||||
|
||||
/**
|
||||
* 根据订单id查询订单
|
||||
* @param orderVo
|
||||
* @return
|
||||
*/
|
||||
Result<OrderInfoDto> getOrdersByIds( OrderVo orderVo);
|
||||
|
||||
/**
|
||||
* 取消订单
|
||||
* @param orderVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> cancelOrder(OrderVo orderVo);
|
||||
|
||||
/**
|
||||
* 获取用户选择的支付币种 获取实时币价
|
||||
* @param coinVo
|
||||
* @return
|
||||
*/
|
||||
Result<BigDecimal> getCoinPrice(CoinVo coinVo);
|
||||
|
||||
|
||||
/**
|
||||
* 获取矿机对应的支持币种和算法
|
||||
* @return
|
||||
*/
|
||||
Result<List<CoinAndAlgorithmListDto>> getMachineSupportCoinAndAlgorithm(List<BaseVo> machineIds);
|
||||
|
||||
/**
|
||||
* 获取当前矿机支持的矿池币种信息
|
||||
* @param machineIds
|
||||
* @return
|
||||
*/
|
||||
Result<List<MiningInfoDto>> getMachineSupportPool(CoinAndAlgorithmVo coinAndAlgorithmVo);
|
||||
|
||||
/**
|
||||
* 添加订单-V2
|
||||
* @param orderAndCodeVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> addOrdersV2( OrderAndCodeVo orderAndCodeVo);
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户已购商品列表-V2
|
||||
* @param pageVo
|
||||
* @return
|
||||
*/
|
||||
PageResult<PurchasedMachineListDto> getPurchasedItems(PageVo pageVo);
|
||||
|
||||
|
||||
/**
|
||||
* 根据id查询用户已购商品详情-V2
|
||||
* @param baseVo
|
||||
* @return
|
||||
*/
|
||||
Result<MiningConfigInfoDto> getPurchasedInfo(BaseVo baseVo);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.m2pool.lease.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.lease.entity.LeaseOrderItem;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 订单明细表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
public interface LeaseOrderItemService extends IService<LeaseOrderItem> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.m2pool.lease.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.lease.entity.LeasePayRecordMessage;
|
||||
import com.m2pool.lease.entity.LeasePayRecordMessageInfo;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* service层支付
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-09-10
|
||||
*/
|
||||
public interface LeasePayRecordMessageInfoService extends IService<LeasePayRecordMessageInfo> {
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.m2pool.lease.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.lease.entity.LeasePayRecordMessage;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* service层支付
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-09-10
|
||||
*/
|
||||
public interface LeasePayRecordMessageService extends IService<LeasePayRecordMessage> {
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.m2pool.lease.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.lease.dto.PaymentCallbackDto;
|
||||
import com.m2pool.lease.dto.PaymentRecordDto;
|
||||
import com.m2pool.lease.dto.Result;
|
||||
import com.m2pool.lease.entity.LeasePaymentRecord;
|
||||
import com.m2pool.lease.vo.BaseVo;
|
||||
import com.m2pool.lease.vo.CheckPayStatusVo;
|
||||
import com.m2pool.lease.vo.OrderVo;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 支付记录表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
public interface LeasePaymentRecordService extends IService<LeasePaymentRecord> {
|
||||
|
||||
|
||||
/**
|
||||
* 创建支付订单
|
||||
*
|
||||
* @param orderVo
|
||||
* @return
|
||||
*/
|
||||
Result<List<PaymentRecordDto>> addPayOrder(OrderVo orderVo);
|
||||
|
||||
/**
|
||||
* 根据订单id查询支付订单
|
||||
*
|
||||
* @param orderVo
|
||||
* @return
|
||||
*/
|
||||
Result<List<PaymentRecordDto>> getPayOrderByOrderId( OrderVo orderVo);
|
||||
/**
|
||||
* 支付回调结果---校验支付是否成功(批量校验)
|
||||
*
|
||||
* @param checkPayStatusVoList
|
||||
* @return
|
||||
*/
|
||||
Result<List<PaymentCallbackDto>> paymentCallbackBatch(List<CheckPayStatusVo> checkPayStatusVoList);
|
||||
|
||||
|
||||
/**
|
||||
* 支付回调结果----根据支付订单id校验支付是否成功(单个校验)
|
||||
* @param checkPayStatusVo
|
||||
* @return
|
||||
*/
|
||||
Result<PaymentCallbackDto> paymentCallbackByPayId(CheckPayStatusVo checkPayStatusVo);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 支付回调结果-----用于定时任务
|
||||
* @param leasePaymentRecordList
|
||||
* @return
|
||||
*/
|
||||
void paymentCallbackTask(List<LeasePaymentRecord> leasePaymentRecordList);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.m2pool.lease.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.lease.entity.LeaseProductIncome;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 商品收益表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
public interface LeaseProductIncomeService extends IService<LeaseProductIncome> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.m2pool.lease.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.lease.entity.LeaseProductMachinePrice;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 商品表对应的物品机器表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
public interface LeaseProductMachinePriceService extends IService<LeaseProductMachinePrice> {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.m2pool.lease.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.lease.dto.PageResult;
|
||||
import com.m2pool.lease.dto.ProductUpdateMachineDto;
|
||||
import com.m2pool.lease.dto.Result;
|
||||
import com.m2pool.lease.dto.UserMinerDto;
|
||||
import com.m2pool.lease.entity.LeaseProductMachine;
|
||||
import com.m2pool.lease.vo.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 商品表对应的物品机器表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
public interface LeaseProductMachineService extends IService<LeaseProductMachine> {
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前账户对应的挖矿账户
|
||||
* @return
|
||||
*/
|
||||
Result<Map<String, List<UserMinerDto>>> getUserMinersList(UserMinerVo userMinerVo);
|
||||
|
||||
/**
|
||||
* 获取当前账户对应的挖矿账户的机器矿工集合
|
||||
* @param userMinerVo
|
||||
* @return
|
||||
*/
|
||||
Result<List<UserMinerDto>> getUserMachineList(UserMinerVo userMinerVo);
|
||||
|
||||
|
||||
/**
|
||||
* 根据商品id查询商品矿机列表---用于卖方修改矿机信息
|
||||
* @param productForUpdateMachineVo
|
||||
* @return
|
||||
*/
|
||||
PageResult<ProductUpdateMachineDto> getMachineListForUpdate(ProductForUpdateMachineVo productForUpdateMachineVo);
|
||||
|
||||
/**
|
||||
* 新增商品库存---实际需出售机器
|
||||
* @param productMachineParamsVoList
|
||||
* @return
|
||||
*/
|
||||
Result<String> addSingleOrBatchMachine(ProductMachineParamsVo productMachineParamsVoList);
|
||||
|
||||
|
||||
/**
|
||||
* 编辑商品 + 商品上下架---实际需出售机器
|
||||
* @param productUpdateMachineVoList
|
||||
* @return
|
||||
*/
|
||||
Result<String> updateMachine(List<ProductUpdateMachineVo> productUpdateMachineVoList);
|
||||
|
||||
|
||||
/**
|
||||
* 删除商品---实际需出售机器
|
||||
* @param baseVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> deleteMachine(BaseVo baseVo);
|
||||
|
||||
|
||||
/**
|
||||
* 计算价格
|
||||
* @param priceCalculateVo
|
||||
* @return
|
||||
*/
|
||||
Result<BigDecimal> calculatePrice(PriceCalculateVo priceCalculateVo);
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.m2pool.lease.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.lease.dto.*;
|
||||
import com.m2pool.lease.entity.LeaseProduct;
|
||||
import com.m2pool.lease.vo.*;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 商品表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
public interface LeaseProductService extends IService<LeaseProduct> {
|
||||
/**
|
||||
* 查询商品列表
|
||||
*
|
||||
* @return Result<List<ProductDto>> 封装后的商品 DTO 列表
|
||||
*/
|
||||
PageResult<ProductDto> getProductList(ProductPageVo productPageVo);
|
||||
|
||||
|
||||
/**
|
||||
* 根据商品 ID 查询商品详情
|
||||
*
|
||||
* @param BaseVo 商品 ID
|
||||
* @return Result<ProductDto> 封装后的商品 DTO
|
||||
*/
|
||||
Result<ProductDto> getMachineInfoById( BaseVo baseVo);
|
||||
|
||||
/**
|
||||
* 根据商品 ID 查询商品详情
|
||||
*
|
||||
* @param productId 商品 ID
|
||||
* @return Result<ProductDto> 封装后的商品 DTO
|
||||
*/
|
||||
PageResult<ProductMachineDto> getProductMachineInfo(ProductMachineVo productMachineVo);
|
||||
|
||||
|
||||
/**
|
||||
* 单个商品矿机列表页面---获取支付方式
|
||||
* @return
|
||||
*/
|
||||
Result<List<PayConfigDto>> getPayTypes(ShopPayTypeVo shopPayTypeVo);
|
||||
/**
|
||||
* 新增商品
|
||||
*
|
||||
* @param productURDVo 商品 DTO
|
||||
* @return Result<Boolean> 操作结果
|
||||
*/
|
||||
Result<String> addProduct(ProductURDVo productURDVo);
|
||||
|
||||
/**
|
||||
* 编辑商品
|
||||
*
|
||||
* @param productURDVo 商品 DTO
|
||||
* @return Result<Boolean> 操作结果
|
||||
*/
|
||||
Result<String> updateProduct(ProductURDVo productURDVo);
|
||||
|
||||
|
||||
/**
|
||||
* 删除商品
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
Result<String> deleteProduct(Long id);
|
||||
|
||||
/**
|
||||
* 查询用户店铺支持的支付方式
|
||||
* @return
|
||||
*/
|
||||
Result<List<PayTypeDto>> getSupportPayType();
|
||||
|
||||
|
||||
/**
|
||||
* 获取商品列表用于店铺钱包配置
|
||||
* @return
|
||||
*/
|
||||
Result<List<ProductForWalletConfigDto>> getProductListForShopWalletConfig();
|
||||
|
||||
|
||||
/**
|
||||
* 修改商品列表用于店铺钱包配置
|
||||
* @return
|
||||
*/
|
||||
Result<String> updateProductListForShopWalletConfig(ProductMachineForWalletConfigVo productMachineForWalletConfigVo);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.m2pool.lease.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.lease.entity.LeaseShopConfig;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 店铺商品配置表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-08-05
|
||||
*/
|
||||
public interface LeaseShopConfigService extends IService<LeaseShopConfig> {
|
||||
|
||||
}
|
||||
146
src/main/java/com/m2pool/lease/service/LeaseShopService.java
Normal file
146
src/main/java/com/m2pool/lease/service/LeaseShopService.java
Normal file
@@ -0,0 +1,146 @@
|
||||
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.*;
|
||||
import com.m2pool.lease.vo.v2.ShopWalletInfoVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 店铺表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-08-05
|
||||
*/
|
||||
public interface LeaseShopService extends IService<LeaseShop> {
|
||||
|
||||
|
||||
/**
|
||||
* 新增店铺
|
||||
* @param shopVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> addShop(ShopVo shopVo);
|
||||
|
||||
|
||||
/**
|
||||
* 修改店铺
|
||||
* @param shopVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> updateShop( ShopVo shopVo);
|
||||
|
||||
/**
|
||||
* 关闭店铺
|
||||
* @param baseVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> closeShop( BaseVo baseVo);
|
||||
|
||||
|
||||
/**
|
||||
* 根据用户邮箱查询店铺
|
||||
* @return
|
||||
*/
|
||||
Result<ShopDto> getShopByUserEmail();
|
||||
|
||||
/**
|
||||
* 根据店铺id查询店铺
|
||||
* @param baseVo
|
||||
* @return
|
||||
*/
|
||||
Result<ShopDto> getShopById(BaseVo baseVo);
|
||||
|
||||
|
||||
/**
|
||||
* 删除店铺
|
||||
* @param baseVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> deleteShop(BaseVo baseVo);
|
||||
|
||||
|
||||
/**
|
||||
* 根据店铺id 获取店铺配置信息列表
|
||||
* @param baseVo
|
||||
* @return
|
||||
*/
|
||||
Result<List<ShopConfigDto>> getShopConfig(BaseVo baseVo);
|
||||
|
||||
/**
|
||||
* 根据 店铺id 获取店铺商品列表
|
||||
* @param baseVo
|
||||
* @return
|
||||
*/
|
||||
Result<List<ShopNameDto>> getProductListById(BaseVo baseVo);
|
||||
|
||||
/**
|
||||
* 新增商铺配置
|
||||
* @param shopConfigVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> addShopConfig( ShopConfigVo shopConfigVo);
|
||||
|
||||
|
||||
/**
|
||||
* 修改商铺配置
|
||||
* @param shopConfigVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> updateShopConfig( ShopConfigVo shopConfigVo);
|
||||
|
||||
/**
|
||||
* 删除商铺配置
|
||||
* @param baseVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> deleteShopConfig(BaseVo baseVo);
|
||||
|
||||
/**
|
||||
* 获取链和链列表
|
||||
* @return
|
||||
*/
|
||||
Result<List<ChainListDto>> getChainAndList();
|
||||
|
||||
|
||||
Result<List<ChainListDto>> getChainAndListForSeller( BaseVo baseVo);
|
||||
|
||||
|
||||
Result<ChainListDto> getChainAndCoin(BaseVo baseVo);
|
||||
|
||||
|
||||
/**
|
||||
* 根据店铺id 获取店铺配置信息列表--v2 新增手续费和钱包余额
|
||||
* @param baseVo
|
||||
* @return
|
||||
*/
|
||||
Result<List<ShopWalletInfoDto>> getShopConfigV2(BaseVo baseVo);
|
||||
|
||||
|
||||
/**
|
||||
* 卖家余额提现
|
||||
* @param balanceVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> withdrawBalanceForSeller(BalanceVo balanceVo);
|
||||
|
||||
|
||||
/**
|
||||
* 修改商铺配置--v2 新增手续费和钱包余额
|
||||
*/
|
||||
Result<String> updateShopConfigV2(ShopWalletInfoVo shopWalletInfoVo);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取店铺内所有钱包(包含历史钱包)提现列表
|
||||
* @return
|
||||
*/
|
||||
PageResult<PayWithdrawSellerRecordDto> balanceWithdrawList(PageVo pageVo);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.m2pool.lease.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.lease.entity.LeaseShoppingCartInfo;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 购物车详情表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-24
|
||||
*/
|
||||
public interface LeaseShoppingCartInfoService extends IService<LeaseShoppingCartInfo> {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 购物车表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
public interface LeaseShoppingCartService extends IService<LeaseShoppingCart> {
|
||||
/**
|
||||
* 添加购物车
|
||||
* @param shoppingCartInfoURDVoList
|
||||
* @return
|
||||
*/
|
||||
Result<String> addGoods(List<ShoppingCartInfoURDVo> shoppingCartInfoURDVoList);
|
||||
|
||||
|
||||
/**
|
||||
* 获取购物车列表
|
||||
* @param pageVo
|
||||
* @return
|
||||
*/
|
||||
PageResult<ShopCartDto> getGoodsList(PageVo pageVo);
|
||||
|
||||
/**
|
||||
* 批量删除购物车
|
||||
* @param baseVoList
|
||||
* @return
|
||||
*/
|
||||
Result<String> deleteBatchGoods(List<ProductAndMachineVo> baseVoList);
|
||||
/**
|
||||
* 删除购物车
|
||||
* @param baseVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> deleteGoods(BaseVo baseVo);
|
||||
|
||||
|
||||
/**
|
||||
* 批量删除购物车中已下架商品
|
||||
* @return
|
||||
*/
|
||||
Result<String> deleteBatchGoodsForIsDelete();
|
||||
|
||||
|
||||
/**
|
||||
* 批量添加购物车
|
||||
* @param addGoodsVoList
|
||||
* @return
|
||||
*/
|
||||
Result<String> addGoodsV2(List<AddGoodsVo> addGoodsVoList);
|
||||
|
||||
|
||||
/**
|
||||
* 查询购物车中商品列表
|
||||
* @param pageVo
|
||||
* @return
|
||||
*/
|
||||
PageResult<ShopCartV2Dto> getGoodsListV2(PageVo pageVo);
|
||||
/**
|
||||
* 批量删除购物车中商品
|
||||
* @param baseVoList
|
||||
* @return
|
||||
*/
|
||||
Result<String> deleteBatchGoodsV2(List<CartInfoVo> baseVoList);
|
||||
|
||||
/**
|
||||
* 批量删除购物车中已下架商品
|
||||
* @return
|
||||
*/
|
||||
Result<String> deleteBatchGoodsForIsDeleteV2();
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
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.UserOwnedProductDto;
|
||||
import com.m2pool.lease.entity.LeaseOrderItem;
|
||||
import com.m2pool.lease.entity.LeasePaymentRecord;
|
||||
import com.m2pool.lease.entity.LeaseUserOwnedProduct;
|
||||
import com.m2pool.lease.vo.BaseVo;
|
||||
import com.m2pool.lease.vo.UserOwnedProductVo;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户拥有商品详情表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
public interface LeaseUserOwnedProductService extends IService<LeaseUserOwnedProduct> {
|
||||
|
||||
/**
|
||||
* 用户查询当前自身已购商品列表
|
||||
*
|
||||
* @param userOwnedProductVo
|
||||
* @return
|
||||
*/
|
||||
PageResult<UserOwnedProductDto> getOwnedList(UserOwnedProductVo userOwnedProductVo);
|
||||
|
||||
|
||||
/**
|
||||
* 根据id查询当前自身已购商品详情
|
||||
*
|
||||
* @param baseVo
|
||||
* @return
|
||||
*/
|
||||
Result<UserOwnedProductDto> getOwnedById(BaseVo baseVo);
|
||||
|
||||
/**
|
||||
* 支付验证成功后去修改订单等信息
|
||||
* @param leaseOrderItems
|
||||
* @return
|
||||
*/
|
||||
boolean afterPaySuccessTodoSomeEvent(List<LeaseOrderItem> leaseOrderItems);
|
||||
}
|
||||
245
src/main/java/com/m2pool/lease/service/LeaseUserService.java
Normal file
245
src/main/java/com/m2pool/lease/service/LeaseUserService.java
Normal file
@@ -0,0 +1,245 @@
|
||||
package com.m2pool.lease.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.lease.dto.*;
|
||||
import com.m2pool.lease.dto.v2.GoogleInfoDto;
|
||||
import com.m2pool.lease.entity.LeaseUser;
|
||||
import com.m2pool.lease.vo.*;
|
||||
import com.m2pool.lease.vo.v2.CloseAccountVo;
|
||||
import com.m2pool.lease.vo.v2.GoogleBindVo;
|
||||
import com.m2pool.lease.vo.v2.GoogleCloseVo;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
public interface LeaseUserService extends IService<LeaseUser> {
|
||||
|
||||
/*---------------用户权限-----------------------*/
|
||||
|
||||
/**
|
||||
* 用户登录/注册
|
||||
* @param userLoginVo
|
||||
* @return
|
||||
*/
|
||||
Result<Map<String, Object>> login(UserLoginVo userLoginVo);
|
||||
|
||||
|
||||
/**
|
||||
* 用户注册
|
||||
* @param userRegisterVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> register( UserRegisterVo userRegisterVo);
|
||||
|
||||
|
||||
/**
|
||||
* 登录页面----忘记密码:重置密码
|
||||
* @param userLoginVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> updatePassword(UserLoginVo userLoginVo);
|
||||
|
||||
|
||||
/**
|
||||
* 个人中心--修改密码
|
||||
* @param restPwdVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> updatePasswordInCenter(RestPwdVo restPwdVo);
|
||||
|
||||
/**
|
||||
* 发送用户登录邮箱验证码
|
||||
* @param emailCodeVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> sendLoginCode( EmailCodeVo emailCodeVo);
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户注册邮箱验证码
|
||||
* @param emailCodeVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> sendRegisterCode(EmailCodeVo emailCodeVo);
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户修改密码邮箱验证码
|
||||
* @param emailCodeVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> sendUpdatePwdCode(EmailCodeVo emailCodeVo);
|
||||
|
||||
|
||||
/**
|
||||
* 登出
|
||||
* @return
|
||||
*/
|
||||
Result<String> logout();
|
||||
|
||||
|
||||
/**
|
||||
* 用户注销
|
||||
* @param closeAccountVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> closeAccount(CloseAccountVo closeAccountVo);
|
||||
|
||||
|
||||
/**
|
||||
* 发送用户注销邮箱验证码
|
||||
* @param emailCodeVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> sendCloseAccount( EmailCodeVo emailCodeVo);
|
||||
/*---------------用户权限-----------------------*/
|
||||
|
||||
|
||||
/*---------------谷歌双重验证-----------------------*/
|
||||
|
||||
/**
|
||||
* 绑定谷歌验证码
|
||||
* @param googleBindVo
|
||||
* @return
|
||||
*/
|
||||
Result<String> bindGoogle( GoogleBindVo googleBindVo);
|
||||
|
||||
/**
|
||||
* 获取谷歌验证器安全码和验证码
|
||||
* @return
|
||||
*/
|
||||
Result<GoogleInfoDto> getBindInfo();
|
||||
|
||||
/**
|
||||
* 发送谷歌验证器邮箱验证码
|
||||
* @return
|
||||
*/
|
||||
Result<String> sendOpenGoogleCode();
|
||||
|
||||
|
||||
/**
|
||||
* 发送关闭谷歌验证 邮箱验证码
|
||||
* @return
|
||||
*/
|
||||
Result<String> sendCloseGoogleCode();
|
||||
|
||||
/**
|
||||
* 关闭双重验证
|
||||
* @param vo
|
||||
* @return
|
||||
*/
|
||||
Result<String> closeStepTwo(GoogleCloseVo vo);
|
||||
|
||||
|
||||
/**
|
||||
* 获取谷歌验证器状态
|
||||
* @return
|
||||
*/
|
||||
Result<Integer> getGoogleStatus();
|
||||
|
||||
|
||||
/**
|
||||
* 开启双重验证
|
||||
* @param vo
|
||||
* @return
|
||||
*/
|
||||
Result<String> openStepTwo(GoogleCloseVo vo);
|
||||
|
||||
/*---------------谷歌双重验证-----------------------*/
|
||||
|
||||
|
||||
/*---------------用户信息-----------------------*/
|
||||
|
||||
/**
|
||||
* 绑定钱包
|
||||
* @param chainAndCoinVo
|
||||
* @return
|
||||
*/
|
||||
Result<UserWalletDataDto> bindWallet( ChainAndCoinVo chainAndCoinVo);
|
||||
|
||||
/**
|
||||
* 获取用户相关钱包信息
|
||||
* @return
|
||||
*/
|
||||
Result<List<UserWalletDataDto>> getWalletInfo();
|
||||
|
||||
|
||||
/**
|
||||
* 余额提现
|
||||
* @return
|
||||
*/
|
||||
Result<String> withdrawBalance(BalanceVo balanceVo);
|
||||
|
||||
|
||||
/**
|
||||
* 获取余额提现记录列表
|
||||
* @param balancePageVo
|
||||
* @return
|
||||
*/
|
||||
PageResult<PayWithdrawMessageDto> balanceWithdrawList(BalancePageVo balancePageVo);
|
||||
|
||||
/**
|
||||
* 获取余额充值记录列表
|
||||
* @param balancePageVo
|
||||
* @return
|
||||
*/
|
||||
PageResult<PayRechargeMessageDto> balanceRechargeList(BalancePageVo balancePageVo);
|
||||
|
||||
|
||||
/**
|
||||
* 卖家:获取钱包交易(收款)记录表
|
||||
* @param balancePageVo
|
||||
* @return
|
||||
*/
|
||||
PageResult<PayRecordMessageDto> balancePayList(BalancePageVo balancePageVo);
|
||||
|
||||
/**
|
||||
* 卖家:获取钱包交易(收款)记录表
|
||||
* @param recordTypePageVo
|
||||
* @return
|
||||
*/
|
||||
PageResult<TransactionRecordDto> transactionRecord( RecordTypePageVo recordTypePageVo);
|
||||
|
||||
/**
|
||||
* 最近5条交易
|
||||
* @return
|
||||
*/
|
||||
Result<List<RecentlyTransactionDto>> getRecentlyTransaction();
|
||||
|
||||
|
||||
/**
|
||||
* 获取手续费
|
||||
* @return
|
||||
*/
|
||||
Result<List<ChargeDto>> getCharge();
|
||||
|
||||
|
||||
/**
|
||||
* 下载客户端
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
void downloadClient(String userEmail,String type,HttpServletRequest request, HttpServletResponse response);
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @return
|
||||
*/
|
||||
String getClientVersion();
|
||||
|
||||
|
||||
/*---------------用户信息-----------------------*/
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* GPU对应币种挖矿算力(只要gpu类型相同那么就使用这个配置) 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-11-27
|
||||
*/
|
||||
@Service
|
||||
public class LeaseMachineConfigServiceImpl extends ServiceImpl<LeaseMachineConfigMapper, LeaseMachineConfig> implements LeaseMachineConfigService {
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 商品表对应的物品机器表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-11-25
|
||||
*/
|
||||
@Service
|
||||
public class LeaseMachinePriceServiceImpl extends ServiceImpl<LeaseMachinePriceMapper, LeaseMachinePrice> implements LeaseMachinePriceService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,470 @@
|
||||
package com.m2pool.lease.service.impl;
|
||||
|
||||
import com.alibaba.cloud.commons.lang.StringUtils;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
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.mapper.*;
|
||||
import com.m2pool.lease.service.LeaseMachineConfigService;
|
||||
import com.m2pool.lease.service.LeaseMachinePriceService;
|
||||
import com.m2pool.lease.service.LeaseMachineService;
|
||||
import com.m2pool.lease.utils.SecurityUtils;
|
||||
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.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* gpu类型出售矿机表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-11-21
|
||||
*/
|
||||
@Service
|
||||
public class LeaseMachineServiceImpl extends ServiceImpl<LeaseMachineMapper, LeaseMachine> 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<LeaseShop>().eq(LeaseShop::getUserEmail, SecurityUtils.getUsername())
|
||||
.eq(LeaseShop::getDel, false));
|
||||
}
|
||||
@Override
|
||||
public PageResult<ShopInfoDto> getShopList(ProductPageVo productPageVo) {
|
||||
//获取到矿机
|
||||
Set<Long> shopIds = leaseMachineMapper.getShopIds();
|
||||
if (shopIds.isEmpty()){
|
||||
//未查询到店铺
|
||||
return PageResult.success(new ArrayList<>());
|
||||
}
|
||||
PageHelper.startPage(productPageVo.getPageNum(), productPageVo.getPageSize());
|
||||
List<ShopInfoDto> existsMachineShop = leaseMachineMapper.getExistsMachineShop(shopIds, productPageVo.getCoin(), productPageVo.getAlgorithm());
|
||||
PageInfo<ShopInfoDto> pageInfo = new PageInfo<>(existsMachineShop);
|
||||
//店铺支付方式
|
||||
List<PayTypeDto> payType = leaseShopConfigMapper.getPayType(new ArrayList<>(shopIds));
|
||||
Map<Long, List<PayTypeDto>> payTypeMap = payType.stream().collect(Collectors.groupingBy(PayTypeDto::getShopId));
|
||||
|
||||
PageResult<ShopInfoDto> 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<MachineInfoDto> getShopMachineList(ShopMachineVo shopMachineVo) {
|
||||
//获取店铺钱包信息
|
||||
List<PayConfigDto> shopWalletInfo = leaseShopMapper.getShopWalletInfo(shopMachineVo.getShopId());
|
||||
//分页查询矿机基础信息
|
||||
PageHelper.startPage(shopMachineVo.getPageNum(), shopMachineVo.getPageSize());
|
||||
shopMachineVo = buildQuery(shopMachineVo,shopWalletInfo.get(0));
|
||||
List<MachineInfoDto> machineInfoDtoList = leaseMachineMapper.getShopMachineList(shopMachineVo);
|
||||
PageInfo<MachineInfoDto> pageInfo = new PageInfo<>(machineInfoDtoList);
|
||||
//获取gpu和asic对应币种算力和月收益信息
|
||||
PageResult<MachineInfoDto> success = setGpuAndAsicInfo(PageResult.successColumns(machineInfoDtoList),shopMachineVo);
|
||||
success.setTotal(pageInfo.getTotal());
|
||||
success.setTotalPage(pageInfo.getPages());
|
||||
PageHelper.clearPage();
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置gpu和asic 对应的收益列表信息
|
||||
* @param
|
||||
*/
|
||||
public PageResult<MachineInfoDto> setGpuAndAsicInfo(PageResult<MachineInfoDto> success,ShopMachineVo shopMachineVo) {
|
||||
List<MachineInfoDto> machineInfoDtoList = success.getRows();
|
||||
List<TableHeadersDto> columns = success.getColumns();
|
||||
if (!machineInfoDtoList.isEmpty()){
|
||||
List<Long> machineIds = machineInfoDtoList.stream()
|
||||
.map(MachineInfoDto::getId).collect(Collectors.toList());
|
||||
//获取价格列表(价格列表只与主表有关,与machine_config 表无关)
|
||||
List<MachinePayTypeDto> machinePriceByMachineIds = leaseMachinePriceMapper.getMachinePriceByMachineIds(machineIds);
|
||||
Map<Long, List<MachinePayTypeDto>> machinePriceMap = machinePriceByMachineIds.stream()
|
||||
.collect(Collectors.groupingBy(MachinePayTypeDto::getProductMachineId));
|
||||
|
||||
//动态列:获取每个矿机前十个币种算法的配置
|
||||
List<PowerIncomeInfoDto> gpuConfigList = leaseMachineMapper.getGpuConfigList(machineIds);
|
||||
Map<Long, List<PowerIncomeInfoDto>> collect = gpuConfigList.stream()
|
||||
.collect(Collectors.groupingBy(PowerIncomeInfoDto::getMachineId));
|
||||
for (MachineInfoDto machineInfo : machineInfoDtoList) {
|
||||
machineInfo.setPriceList(machinePriceMap.get(machineInfo.getId()));
|
||||
List<PowerIncomeInfoDto> powerIncomeInfoDtoList = collect.get(machineInfo.getId());
|
||||
for (int i = 0; i < powerIncomeInfoDtoList.size(); i++) {
|
||||
PowerIncomeInfoDto powerIncomeInfoDto = powerIncomeInfoDtoList.get(i);
|
||||
setDynamicColumn(columns,powerIncomeInfoDto,machineInfo);
|
||||
}
|
||||
}
|
||||
//排序分页后对象
|
||||
List<MachineInfoDto> sorted = sorted(machineInfoDtoList, shopMachineVo);
|
||||
success.setRows(sorted);
|
||||
success.setColumns(columns);
|
||||
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置算力动态列
|
||||
* @param columns
|
||||
*/
|
||||
public void setDynamicColumn(List<TableHeadersDto> 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() + powerIncomeInfoDto.getUnit());
|
||||
break;
|
||||
case 2:
|
||||
machineInfo.setC2(powerIncomeInfoDto.getPower() + powerIncomeInfoDto.getUnit());
|
||||
break;
|
||||
case 3:
|
||||
machineInfo.setC3(powerIncomeInfoDto.getPower() + powerIncomeInfoDto.getUnit());
|
||||
break;
|
||||
case 4:
|
||||
machineInfo.setC4(powerIncomeInfoDto.getPower() + powerIncomeInfoDto.getUnit());
|
||||
break;
|
||||
case 5:
|
||||
machineInfo.setC5(powerIncomeInfoDto.getPower() + powerIncomeInfoDto.getUnit());
|
||||
break;
|
||||
case 6:
|
||||
machineInfo.setC6(powerIncomeInfoDto.getPower() + powerIncomeInfoDto.getUnit());
|
||||
break;
|
||||
case 7:
|
||||
machineInfo.setC7(powerIncomeInfoDto.getPower() + powerIncomeInfoDto.getUnit());
|
||||
break;
|
||||
case 8:
|
||||
machineInfo.setC8(powerIncomeInfoDto.getPower() + powerIncomeInfoDto.getUnit());
|
||||
break;
|
||||
case 9:
|
||||
machineInfo.setC9(powerIncomeInfoDto.getPower() + powerIncomeInfoDto.getUnit());
|
||||
break;
|
||||
case 10:
|
||||
machineInfo.setC10(powerIncomeInfoDto.getPower() + powerIncomeInfoDto.getUnit());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<SellerMachineInfoDto> getShopMachineListForSeller(SellerMachineVo sellerMachineVo) {
|
||||
LeaseShop leaseShop = getShopById();
|
||||
if (leaseShop == null){
|
||||
//不存在店铺
|
||||
return PageResult.success(new ArrayList<>());
|
||||
}
|
||||
PageHelper.startPage(sellerMachineVo.getPageNum(), sellerMachineVo.getPageSize());
|
||||
List<SellerMachineInfoDto> machineInfoDtoList = leaseMachineMapper.getShopMachineListForSeller(sellerMachineVo,leaseShop.getId());
|
||||
PageInfo<SellerMachineInfoDto> pageInfo = new PageInfo<>(machineInfoDtoList);
|
||||
if (machineInfoDtoList.isEmpty()){
|
||||
//没有矿机
|
||||
return PageResult.success(new ArrayList<>());
|
||||
}
|
||||
PageResult<SellerMachineInfoDto> success = PageResult.success(machineInfoDtoList);
|
||||
//获取矿机配置信息
|
||||
List<AsicCoinAndAlgoDto> coinAndAlgoList = leaseMachineMapper.getCoinAndAlgoList(success.getRows());
|
||||
Map<Long, List<AsicCoinAndAlgoDto>> collect1 = coinAndAlgoList.stream().collect(Collectors.groupingBy(AsicCoinAndAlgoDto::getProductMachineId));
|
||||
//价格配置信息
|
||||
List<MachinePayTypeDto> machinePriceList = leaseMachineMapper.getMachinePriceList(success.getRows());
|
||||
Map<Long, List<MachinePayTypeDto>> collect = machinePriceList.stream().collect(Collectors.groupingBy(MachinePayTypeDto::getProductMachineId));
|
||||
//能否上架
|
||||
Map<Long, MachineEffectDto> longMachineEffectDtoMap = leaseMachineMapper.checkIsEffect(success.getRows());
|
||||
|
||||
for (SellerMachineInfoDto row : success.getRows()) {
|
||||
MachineEffectDto machineEffectDto = longMachineEffectDtoMap.get(row.getId());
|
||||
row.setEffect(machineEffectDto != null ? machineEffectDto.getEffect() : 0);
|
||||
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<MachineInfoDto> sorted(List<MachineInfoDto> machineInfoDtoList, ShopMachineVo shopMachineVo){
|
||||
|
||||
if (shopMachineVo.getPriceSort() != null) {
|
||||
Comparator<MachineInfoDto> 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<MachineInfoDto> 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<String> addAsicMachine(AsicMachineParamsVo asicMachineParamsVo) {
|
||||
if(asicMachineParamsVo.getPriceList().isEmpty()){
|
||||
return Result.fail("添加ASIC矿机失败,请先绑定收款钱包");
|
||||
}
|
||||
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())
|
||||
.canSaleNumbers(asicMachineParamsVo.getSaleNumbers())
|
||||
.build();
|
||||
int machineInsert = leaseMachineMapper.insert(machine);
|
||||
|
||||
//新增lease_asic_coin_power_config 配置信息表信息 + lease_machine_price 矿机价格表信息
|
||||
if (machineInsert > 0){
|
||||
List<LeaseMachineConfig> 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<LeaseMachinePrice> 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<String> 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<LeaseMachinePrice> collect = asicMachineParamsVo.getPriceList().stream().map(
|
||||
machinePayTypeVo ->
|
||||
LeaseMachinePrice.builder()
|
||||
.id(machinePayTypeVo.getPayTypeId())
|
||||
.price(machinePayTypeVo.getPrice())
|
||||
.build()
|
||||
).collect(Collectors.toList());
|
||||
boolean b = leaseMachinePriceService.updateBatchById(collect);
|
||||
List<LeaseMachineConfig> 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<String> updateGpuMachine(List<GpuMachineParamsVo> 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 矿机价格表信息
|
||||
if (machineUpdate > 0){
|
||||
List<MachinePayTypeVo> 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<String> updateMachineState(MachineStateVo machineStateVo) {
|
||||
leaseMachineMapper.updateById(LeaseMachine.builder().id(machineStateVo.getId()).state(machineStateVo.getState()).build());
|
||||
return machineStateVo.getState() ? Result.success("下架成功") : Result.success("上架成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<String> deleteMachine(BaseVo baseVo) {
|
||||
//TODO 删除之前需要判断是否存在订单
|
||||
leaseMachineMapper.updateById(LeaseMachine.builder().id(baseVo.getId()).del(true).build());
|
||||
//删除售价
|
||||
leaseMachinePriceMapper.update(LeaseMachinePrice.builder().del(true).build(),new LambdaQueryWrapper<LeaseMachinePrice>()
|
||||
.eq(LeaseMachinePrice::getMachineId,baseVo.getId()));
|
||||
//ASIC/GPU 矿机删除配置信息
|
||||
leaseMachineConfigMapper.update(LeaseMachineConfig.builder().del(true).build(),
|
||||
new LambdaQueryWrapper<LeaseMachineConfig>().eq(LeaseMachineConfig::getMachineId,baseVo.getId()));
|
||||
|
||||
return Result.success("删除成功");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Result<List<String>> getSupportCoin() {
|
||||
List<String> supportCoin = leaseMachineMapper.getSupportCoin();
|
||||
return Result.success(supportCoin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<String>> getSupportAlgo(String coin) {
|
||||
List<String> supportAlgo = leaseMachineMapper.getSupportAlgo(coin);
|
||||
return Result.success(supportAlgo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.m2pool.lease.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.m2pool.lease.entity.LeaseNexaMachineAvgPower;
|
||||
import com.m2pool.lease.mapper.LeaseNexaMachineAvgPowerMapper;
|
||||
import com.m2pool.lease.service.LeaseNexaMachineAvgPowerService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 矿池nexa机器实时平均算力 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-29
|
||||
*/
|
||||
@Service
|
||||
public class LeaseNexaMachineAvgPowerServiceImpl extends ServiceImpl<LeaseNexaMachineAvgPowerMapper, LeaseNexaMachineAvgPower> implements LeaseNexaMachineAvgPowerService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.m2pool.lease.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.m2pool.lease.entity.LeaseNexaMachinePower;
|
||||
import com.m2pool.lease.mapper.LeaseNexaMachinePowerMapper;
|
||||
import com.m2pool.lease.service.LeaseNexaMachinePowerService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 已售商品矿工实时算力表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-25
|
||||
*/
|
||||
@Service
|
||||
public class LeaseNexaMachinePowerServiceImpl extends ServiceImpl<LeaseNexaMachinePowerMapper, LeaseNexaMachinePower> implements LeaseNexaMachinePowerService {
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
||||
package com.m2pool.lease.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.m2pool.lease.entity.LeaseOrderItem;
|
||||
import com.m2pool.lease.mapper.LeaseOrderItemMapper;
|
||||
import com.m2pool.lease.service.LeaseOrderItemService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 订单明细表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
@Service
|
||||
public class LeaseOrderItemServiceImpl extends ServiceImpl<LeaseOrderItemMapper, LeaseOrderItem> implements LeaseOrderItemService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.m2pool.lease.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.m2pool.lease.entity.LeasePayRecordMessage;
|
||||
import com.m2pool.lease.entity.LeasePayRecordMessageInfo;
|
||||
import com.m2pool.lease.mapper.LeasePayRecordMessageInfoMapper;
|
||||
import com.m2pool.lease.mapper.LeasePayRecordMessageMapper;
|
||||
import com.m2pool.lease.service.LeasePayRecordMessageInfoService;
|
||||
import com.m2pool.lease.service.LeasePayRecordMessageService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* service层支付
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-09-10
|
||||
*/
|
||||
@Service
|
||||
public class LeasePayRecordMessageInfoServiceImpl extends ServiceImpl<LeasePayRecordMessageInfoMapper, LeasePayRecordMessageInfo> implements LeasePayRecordMessageInfoService {
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.m2pool.lease.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.m2pool.lease.entity.LeasePayRecordMessage;
|
||||
import com.m2pool.lease.mapper.LeasePayRecordMessageMapper;
|
||||
import com.m2pool.lease.service.LeasePayRecordMessageService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* service层支付
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-09-10
|
||||
*/
|
||||
@Service
|
||||
public class LeasePayRecordMessageServiceImpl extends ServiceImpl<LeasePayRecordMessageMapper, LeasePayRecordMessage> implements LeasePayRecordMessageService {
|
||||
}
|
||||
@@ -0,0 +1,497 @@
|
||||
package com.m2pool.lease.service.impl;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.m2pool.lease.constant.PaymentStatus;
|
||||
import com.m2pool.lease.dto.PaymentCallbackDto;
|
||||
import com.m2pool.lease.dto.PaymentRecordDto;
|
||||
import com.m2pool.lease.mq.message.RabbitmqPoolProxyMessage;
|
||||
import com.m2pool.lease.dto.Result;
|
||||
import com.m2pool.lease.entity.LeaseOrderInfo;
|
||||
import com.m2pool.lease.entity.LeaseOrderItem;
|
||||
import com.m2pool.lease.entity.LeasePaymentRecord;
|
||||
import com.m2pool.lease.exception.PaymentException;
|
||||
import com.m2pool.lease.mapper.LeaseOrderInfoMapper;
|
||||
import com.m2pool.lease.mapper.LeaseOrderItemMapper;
|
||||
import com.m2pool.lease.mapper.LeasePaymentRecordMapper;
|
||||
import com.m2pool.lease.service.LeasePaymentRecordService;
|
||||
import com.m2pool.lease.service.LeaseUserOwnedProductService;
|
||||
import com.m2pool.lease.utils.HttpPayUtils;
|
||||
import com.m2pool.lease.vo.CheckPayStatusVo;
|
||||
import com.m2pool.lease.vo.OrderVo;
|
||||
import com.m2pool.lease.vo.PayVo;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
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.ZoneId;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.m2pool.lease.constant.OrderStatus.FULLY_PAID;
|
||||
import static com.m2pool.lease.constant.OrderStatus.PARTIALLY_PAID;
|
||||
import static com.m2pool.lease.constant.PaymentStatus.*;
|
||||
import static com.m2pool.lease.constant.RabbitmqConstant.POOL_PROXY_QUEUE_NAME;
|
||||
import static com.m2pool.lease.utils.HttpPayUtils.PAY_ETH;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 支付记录表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
@Service
|
||||
public class LeasePaymentRecordServiceImpl extends ServiceImpl<LeasePaymentRecordMapper, LeasePaymentRecord> implements LeasePaymentRecordService {
|
||||
|
||||
|
||||
|
||||
@Resource
|
||||
private RabbitTemplate rabbitTemplate;
|
||||
|
||||
@Resource
|
||||
private LeaseOrderItemMapper leaseOrderItemMapper;
|
||||
|
||||
@Resource
|
||||
private LeasePaymentRecordMapper leasePaymentRecordMapper;
|
||||
|
||||
@Resource
|
||||
private ThreadPoolTaskExecutor customThreadPool;
|
||||
|
||||
@Resource
|
||||
private LeaseOrderInfoMapper leaseOrderInfoMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseUserOwnedProductService leaseUserOwnedProductService;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<List<PaymentRecordDto>> addPayOrder(OrderVo orderVo) {
|
||||
//1.根据订单id查询订单详情信息
|
||||
List<LeaseOrderItem> leaseOrderItems = leaseOrderItemMapper.selectList(new LambdaQueryWrapper<LeaseOrderItem>()
|
||||
.eq(LeaseOrderItem::getOrderId, orderVo.getOrderId()));
|
||||
|
||||
//2.按商品ID分组,并生成支付订单列表
|
||||
Map<Long, List<LeaseOrderItem>> productItemsMap = leaseOrderItems.stream()
|
||||
.collect(Collectors.groupingBy(LeaseOrderItem::getProductId));
|
||||
//3.生成支付订单列表 + 封装返回对象
|
||||
List<PaymentRecordDto> paymentRecordDTOs = new ArrayList<>();
|
||||
|
||||
List<LeasePaymentRecord> paymentRecords = productItemsMap.values().stream()
|
||||
.map(items -> {
|
||||
LeaseOrderItem firstItem = items.get(0);
|
||||
BigDecimal totalAmount = items.stream()
|
||||
.map(LeaseOrderItem::getPrice)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
Long orderId = orderVo.getOrderId();
|
||||
Long productId = firstItem.getProductId();
|
||||
String payCoin = firstItem.getPayCoin();
|
||||
String address = firstItem.getAddress();
|
||||
paymentRecordDTOs.add(PaymentRecordDto.builder()
|
||||
.payCoin(payCoin)
|
||||
.amount(totalAmount)
|
||||
.payAddress(address)
|
||||
.build());
|
||||
|
||||
return LeasePaymentRecord.builder()
|
||||
.orderId(orderId)
|
||||
.productId(productId)
|
||||
.payCoin(payCoin)
|
||||
.amount(totalAmount)
|
||||
.payAddress(address)
|
||||
.build();
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
//4.保存支付订单
|
||||
boolean saved = saveBatch(paymentRecords);
|
||||
if (saved) {
|
||||
return Result.success(paymentRecordDTOs);
|
||||
} else {
|
||||
return Result.fail("生成支付订单失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<PaymentRecordDto>> getPayOrderByOrderId(OrderVo orderVo) {
|
||||
List<LeasePaymentRecord> leasePaymentRecords = leasePaymentRecordMapper.selectList(new LambdaQueryWrapper<LeasePaymentRecord>()
|
||||
.eq(LeasePaymentRecord::getOrderId, orderVo.getOrderId())
|
||||
.eq(LeasePaymentRecord::getDel, false));
|
||||
List<PaymentRecordDto> collect = leasePaymentRecords.stream()
|
||||
.map(record -> PaymentRecordDto.builder()
|
||||
.id(record.getId())
|
||||
.payCoin(record.getPayCoin())
|
||||
.amount(record.getAmount())
|
||||
.payAddress(record.getPayAddress())
|
||||
.status(record.getStatus())
|
||||
.img(record.getQrcode())
|
||||
.build()).collect(Collectors.toList());
|
||||
return Result.success(collect);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<List<PaymentCallbackDto>> paymentCallbackBatch(List<CheckPayStatusVo> checkPayStatusVoList) {
|
||||
List<PaymentCallbackDto> paymentCallbackDTOs = new ArrayList<>();
|
||||
//1.查询处于待支付中状态(2)的订单
|
||||
List<Long> payIds = checkPayStatusVoList.stream().map(CheckPayStatusVo::getId).collect(Collectors.toList());
|
||||
List<LeasePaymentRecord> leasePaymentRecords = leasePaymentRecordMapper.selectList(new LambdaQueryWrapper<LeasePaymentRecord>()
|
||||
.in(LeasePaymentRecord::getId, payIds)
|
||||
.eq(LeasePaymentRecord::getDel, true)
|
||||
.nested(wrapper -> wrapper
|
||||
.eq(LeasePaymentRecord::getStatus, 2)
|
||||
.or()
|
||||
.eq(LeasePaymentRecord::getStatus, 10)));
|
||||
|
||||
List<Long> orderIds = leasePaymentRecords.stream().map(LeasePaymentRecord::getOrderId).collect(Collectors.toList());
|
||||
//2.根据订单id查询订单详情信息
|
||||
List<LeaseOrderItem> leaseOrderItems = leaseOrderItemMapper.selectList(new LambdaQueryWrapper<LeaseOrderItem>()
|
||||
.in(LeaseOrderItem::getOrderId, orderIds));
|
||||
//3.按商店id分组
|
||||
Map<Long, List<LeaseOrderItem>> productItemsMap = leaseOrderItems.stream()
|
||||
.collect(Collectors.groupingBy(LeaseOrderItem::getShopId));
|
||||
|
||||
//记录是否所有都支付成功
|
||||
int isAll = 0;
|
||||
//4.按店铺分组---->合并店铺下所有支付订单----> 按所有总交易金额 去填充这些订单---->填充慢则表示这一笔订单支付成功----> 发货
|
||||
for (LeasePaymentRecord record : leasePaymentRecords) {
|
||||
//4.1 调用三方api校验支付是否成功
|
||||
PaymentCallbackDto paymentCallbackDto = paymentCallback(record);
|
||||
|
||||
if (paymentCallbackDto.getIsPayAll() == 1){
|
||||
//4.2 修改商品售出状态 + 新增机器到已购表中 (为了保证成功需要通过消息中间件达成最终一致性 demo暂时不修改)
|
||||
List<LeaseOrderItem> leaseOrderItemList = productItemsMap.get(record.getShopId());
|
||||
boolean isSuccess = leaseUserOwnedProductService.afterPaySuccessTodoSomeEvent(leaseOrderItemList);
|
||||
if (!isSuccess){
|
||||
return Result.fail("支付校验成功√-->货款已付清√-->发货失败×。请提交工单发送订单给客服或者通过聊天系统联系客服解决");
|
||||
}
|
||||
record.setStatus(1);
|
||||
int i = leasePaymentRecordMapper.updateById(record);
|
||||
isAll += i;
|
||||
//4.3 发送rabbitmq消息给矿池代理
|
||||
sendRabbitmqMessage(leaseOrderItemList);
|
||||
}else if (paymentCallbackDto.getIsPayAll() == 10){
|
||||
//支付了部分货款改状态---但是不发货
|
||||
leasePaymentRecordMapper.updateById(LeasePaymentRecord.builder().id(record.getId()).status(10).build());
|
||||
}
|
||||
paymentCallbackDto.setTotalAmount(record.getAmount());
|
||||
paymentCallbackDTOs.add(paymentCallbackDto);
|
||||
}
|
||||
//5.修改订单状态为 1全部已支付 10部分已支付
|
||||
int status = isAll == leasePaymentRecords.size() ? 1 : 10;
|
||||
Long orderId = leasePaymentRecords.get(0).getOrderId();
|
||||
int i = leaseOrderInfoMapper.updateById(LeaseOrderInfo.builder().id(orderId).status(status).build());
|
||||
if (i > 0){
|
||||
return Result.success(paymentCallbackDTOs);
|
||||
}else {
|
||||
return Result.fail("校验失败");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<PaymentCallbackDto> paymentCallbackByPayId(CheckPayStatusVo baseVo) {
|
||||
LeasePaymentRecord record = leasePaymentRecordMapper.selectById(baseVo.getId());
|
||||
record.setFrom(baseVo.getForm());
|
||||
record.setHash(baseVo.getHash());
|
||||
//支付状态为2 待支付 或者 10 支付成功--已支付部分货款 两种状态可校验
|
||||
if (record.getStatus() == 10 || record.getStatus() == 2){
|
||||
//1.根据订单id + 店铺id 查询订单详情信息 (支付订单按shop分的,不再按商品分)
|
||||
List<LeaseOrderItem> leaseOrderItems = leaseOrderItemMapper.selectList(new LambdaQueryWrapper<LeaseOrderItem>()
|
||||
.eq(LeaseOrderItem::getOrderId, record.getOrderId()).eq(LeaseOrderItem::getShopId, record.getShopId()));
|
||||
|
||||
//2.调用三方api校验支付是否成功
|
||||
PaymentCallbackDto paymentCallbackDto = paymentCallback(record);
|
||||
if (paymentCallbackDto.getIsPayAll() == 1){
|
||||
boolean isSuccess = leaseUserOwnedProductService.afterPaySuccessTodoSomeEvent(leaseOrderItems);
|
||||
if (!isSuccess){
|
||||
return Result.fail("支付校验成功√-->货款已付清√-->发货失败×。请提交工单发送订单给客服或者通过聊天系统联系客服解决");
|
||||
}
|
||||
record.setStatus(1);
|
||||
leasePaymentRecordMapper.updateById(record);
|
||||
//2.1 发送rabbitmq消息给矿池代理
|
||||
sendRabbitmqMessage(leaseOrderItems);
|
||||
} else if (paymentCallbackDto.getIsPayAll() == 10){
|
||||
//2.2 支付了部分货款改状态---但是不发货
|
||||
leasePaymentRecordMapper.updateById(LeasePaymentRecord.builder().id(record.getId()).status(10).build());
|
||||
}
|
||||
//3.查询订单是否下所有支付订单都已支付完成
|
||||
Long l = leasePaymentRecordMapper.selectCount(new LambdaQueryWrapper<LeasePaymentRecord>()
|
||||
.eq(LeasePaymentRecord::getOrderId, record.getOrderId())
|
||||
.eq(LeasePaymentRecord::getDel, true)
|
||||
.ne(LeasePaymentRecord::getStatus,1));
|
||||
//4.修改订单为全部已支付
|
||||
if (l == 0){
|
||||
leaseOrderInfoMapper.updateById(LeaseOrderInfo.builder().id(record.getOrderId()).status(1).build());
|
||||
}
|
||||
return Result.success(paymentCallbackDto);
|
||||
}
|
||||
return Result.fail("验证失败,该订单状态不为支付成功未验证状态");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void paymentCallbackTask(List<LeasePaymentRecord> leasePaymentRecordList) {
|
||||
List<Long> orderIds = leasePaymentRecordList.stream().map(LeasePaymentRecord::getOrderId).distinct().collect(Collectors.toList());
|
||||
//1---根据订单id查询订单详情信息
|
||||
List<LeaseOrderItem> leaseOrderItems = leaseOrderItemMapper.selectList(new LambdaQueryWrapper<LeaseOrderItem>()
|
||||
.in(LeaseOrderItem::getOrderId, orderIds));
|
||||
//2---按商店id - 订单id 分组
|
||||
Map<String, List<LeaseOrderItem>> productItemsMap = leaseOrderItems.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
item -> item.getShopId() + "-" + item.getOrderId()
|
||||
));
|
||||
//3---支付订单按支付地址分组 校验
|
||||
Map<String, List<LeasePaymentRecord>> shopMaps = leasePaymentRecordList.stream().collect(Collectors.groupingBy(LeasePaymentRecord::getPayAddress));
|
||||
|
||||
List<LeasePaymentRecord> afterCheckPaymentList = shopMaps.entrySet().stream()
|
||||
.map(entry -> {
|
||||
String key = entry.getKey();
|
||||
List<LeasePaymentRecord> values = entry.getValue();
|
||||
// 查找已经支付的金额
|
||||
BigDecimal paySuccessAmount = values.stream().map(LeasePaymentRecord::getPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
BigDecimal alreadyPayAmount = getAlreadyPayAmount(key, values).subtract(paySuccessAmount);
|
||||
|
||||
// 在迭代过程中修改列表,使用 fori 循环避免 ConcurrentModificationException
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
LeasePaymentRecord leasePaymentRecord = values.get(i);
|
||||
BigDecimal needPayAmount = leasePaymentRecord.getAmount();
|
||||
BigDecimal payAmount = leasePaymentRecord.getPayAmount();
|
||||
// 如果该支付订单已支付了部分金额 剩下需支付需减去该值
|
||||
if (payAmount.compareTo(BigDecimal.ZERO) != 0) {
|
||||
needPayAmount = needPayAmount.subtract(payAmount);
|
||||
}
|
||||
// 已支付金额 不等于 需支付总金额
|
||||
if (payAmount.compareTo(needPayAmount) != 0) {
|
||||
if (needPayAmount.compareTo(alreadyPayAmount) < 0) {
|
||||
// 条件1: 交易记录金额大于需要支付的金额------> 该订单状态可改为 1全部已支付
|
||||
alreadyPayAmount = alreadyPayAmount.subtract(needPayAmount);
|
||||
leasePaymentRecord.setStatus(PAYMENT_SUCCESS_FULL.getCode());
|
||||
leasePaymentRecord.setPayAmount(leasePaymentRecord.getAmount());
|
||||
} else if (needPayAmount.compareTo(alreadyPayAmount) > 0 && alreadyPayAmount.compareTo(BigDecimal.ZERO) != 0) {
|
||||
// 条件2: 交易记录金额小于需要支付的金额 ,但是交易记录金额不为0 ------> 该订单可改为状态 10部分已支付
|
||||
alreadyPayAmount = BigDecimal.ZERO;
|
||||
leasePaymentRecord.setStatus(PAYMENT_SUCCESS_PARTIAL.getCode());
|
||||
leasePaymentRecord.setPayAmount(alreadyPayAmount);
|
||||
} else if (PAYMENT_SUCCESS_PARTIAL.getCode() == leasePaymentRecord.getStatus()) {
|
||||
// 条件3: 走到这里说明,交易金额已经分配完毕。 如果本身为部分已支付,直接去除
|
||||
values.remove(i);
|
||||
i--;
|
||||
}
|
||||
} else {
|
||||
// 已支付金额 等于 需支付总金额 直接剔除
|
||||
values.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return values;
|
||||
})
|
||||
.flatMap(List::stream) // 展开嵌套的列表
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
||||
List<LeaseOrderItem> rabbitmqMessages = new ArrayList<>();
|
||||
//4---更新支付状态变化的支付订单 + 支付订单为完成支付的 订单开始 发货
|
||||
for (LeasePaymentRecord record : afterCheckPaymentList) {
|
||||
//4.1全部支付成功的才能发货
|
||||
if (PaymentStatus.PAYMENT_SUCCESS_FULL.getCode() == record.getStatus()){
|
||||
String key = record.getShopId() + "-" + record.getOrderId();
|
||||
List<LeaseOrderItem> leaseOrderItemList = productItemsMap.get(key);
|
||||
leaseUserOwnedProductService.afterPaySuccessTodoSomeEvent(leaseOrderItemList);
|
||||
rabbitmqMessages.addAll(leaseOrderItemList);
|
||||
}
|
||||
//4.2 修改支付订单的状态
|
||||
leasePaymentRecordMapper.updateById(record);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//5---发送rabbitmq消息给矿池代理
|
||||
sendRabbitmqMessage(rabbitmqMessages);
|
||||
|
||||
//6---修改普通订单状态
|
||||
//统计每个普通订单对应的支付订单数量
|
||||
Map<Long, Long> orderIdCountMap = leasePaymentRecordList.stream()
|
||||
.collect(Collectors.groupingBy(LeasePaymentRecord::getOrderId, Collectors.counting()));
|
||||
// 统计每个订单对应的支付已全部完成的数量
|
||||
Map<Long, Long> fullPaidCountMap = leasePaymentRecordList.stream()
|
||||
.filter(record -> record.getStatus() == PAYMENT_SUCCESS_FULL.getCode())
|
||||
.collect(Collectors.groupingBy(LeasePaymentRecord::getOrderId, Collectors.counting()));
|
||||
// 统计每个订单对应的部分已完成的数量
|
||||
Map<Long, Long> partialPaidCountMap = leasePaymentRecordList.stream()
|
||||
.filter(record -> record.getStatus() == PAYMENT_SUCCESS_PARTIAL.getCode())
|
||||
.collect(Collectors.groupingBy(LeasePaymentRecord::getOrderId, Collectors.counting()));
|
||||
|
||||
// 遍历 orderIdCountMap,更新订单状态
|
||||
for (Map.Entry<Long, Long> entry : orderIdCountMap.entrySet()) {
|
||||
Long orderId = entry.getKey();
|
||||
Long totalCount = entry.getValue();
|
||||
Long fullPaidCount = fullPaidCountMap.getOrDefault(orderId, 0L);
|
||||
Long partialPaidCount = partialPaidCountMap.getOrDefault(orderId, 0L);
|
||||
if (Objects.equals(fullPaidCount, totalCount)) {
|
||||
// 全部已完成
|
||||
leaseOrderInfoMapper.updateById(LeaseOrderInfo.builder().id(orderId).status(FULLY_PAID.getCode()).build());
|
||||
//TODO 长连接联系前端支付已完成
|
||||
} else if (partialPaidCount > 0) {
|
||||
// 部分已完成
|
||||
leaseOrderInfoMapper.updateById(LeaseOrderInfo.builder().id(orderId).status(PARTIALLY_PAID.getCode()).build());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前用户已支付的金额
|
||||
* @param leasePaymentRecordList
|
||||
* @return
|
||||
*/
|
||||
private BigDecimal getAlreadyPayAmount(String payAddress,List<LeasePaymentRecord> leasePaymentRecordList) {
|
||||
LeasePaymentRecord leasePaymentRecord = leasePaymentRecordList.get(0);
|
||||
PayVo build = PayVo.builder()
|
||||
.ts(leasePaymentRecord.getCreateTime().atZone(ZoneId.systemDefault()).toInstant().getEpochSecond())
|
||||
.address(payAddress)
|
||||
.build();
|
||||
HttpPayUtils.PaymentDto paymentDto = HttpPayUtils.doPost(PAY_ETH, JSONUtil.toJsonStr(build));
|
||||
|
||||
BigDecimal totalAmount = BigDecimal.ZERO;
|
||||
List<HttpPayUtils.PaymentData> paymentData = handlerResponse(paymentDto);
|
||||
for (HttpPayUtils.PaymentData result : paymentData){
|
||||
String valueStr = result.getValue();
|
||||
BigDecimal divisor = BigDecimal.TEN.pow(6);
|
||||
BigDecimal resultAmount = new BigDecimal(valueStr).divide(divisor,6, RoundingMode.HALF_UP);
|
||||
totalAmount = totalAmount.add(resultAmount);
|
||||
}
|
||||
|
||||
return totalAmount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 调用三方api 进行支付校验
|
||||
* @param record
|
||||
* @return
|
||||
*/
|
||||
private PaymentCallbackDto paymentCallback(LeasePaymentRecord record) {
|
||||
PayVo build = PayVo.builder()
|
||||
.ts(record.getCreateTime().atZone(ZoneId.systemDefault()).toInstant().getEpochSecond())
|
||||
.coin(record.getPayCoin())
|
||||
.amount(record.getAmount())
|
||||
.address(record.getPayAddress())
|
||||
.build();
|
||||
HttpPayUtils.PaymentDto paymentDto = HttpPayUtils.doPost(PAY_ETH, JSONUtil.toJsonStr(build));
|
||||
|
||||
List<HttpPayUtils.PaymentData> paymentData = handlerResponse(paymentDto);
|
||||
if (paymentData != null && !paymentData.isEmpty()){
|
||||
return payIsSuccess(record, paymentData);
|
||||
}else{
|
||||
throw new PaymentException("验证失败,卖方不存在转账记录");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验代码
|
||||
* @param record
|
||||
* @param paymentData
|
||||
* @return
|
||||
*/
|
||||
private PaymentCallbackDto payIsSuccess(LeasePaymentRecord record,List<HttpPayUtils.PaymentData> paymentData){
|
||||
//待支付状态为2
|
||||
int isPayAll = 2;
|
||||
BigDecimal noPayAmount = record.getAmount();
|
||||
for (HttpPayUtils.PaymentData result : paymentData){
|
||||
String valueStr = result.getValue();
|
||||
BigDecimal divisor = BigDecimal.TEN.pow(6);
|
||||
BigDecimal resultAmount = new BigDecimal(valueStr).divide(divisor,6, RoundingMode.HALF_UP);
|
||||
long timeStamp = Long.parseLong(result.getTimeStamp());
|
||||
long ts = record.getCreateTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
||||
//交易hash 和 买家钱包地址 有一个校验通过即可(只适用于自营校验)
|
||||
if (timeStamp >= ts && (result.getFrom().equals(record.getFrom()) || result.getHash().equals(record.getHash()))){
|
||||
noPayAmount = noPayAmount.subtract(resultAmount);
|
||||
//全部货款已支付
|
||||
if (noPayAmount.compareTo(BigDecimal.ZERO) == 0){
|
||||
isPayAll = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//已支付部分货款
|
||||
if (noPayAmount.compareTo(record.getAmount()) != 0 && noPayAmount.compareTo(BigDecimal.ZERO) != 0){
|
||||
isPayAll = 10;
|
||||
}
|
||||
|
||||
return PaymentCallbackDto.builder().isPayAll(isPayAll).noPayAmount(noPayAmount).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 三方api调用异常
|
||||
* @param paymentDto
|
||||
* @return
|
||||
*/
|
||||
private List<HttpPayUtils.PaymentData> handlerResponse(HttpPayUtils.PaymentDto paymentDto){
|
||||
if (paymentDto != null){
|
||||
if (paymentDto.isResult() && paymentDto.getCode() == 0) {
|
||||
// 支付成功,处理返回的交易数据
|
||||
List<HttpPayUtils.PaymentData> transactions = paymentDto.getData();
|
||||
return transactions;
|
||||
} else {
|
||||
// 支付失败,根据 code 处理不同错误
|
||||
switch (paymentDto.getCode()) {
|
||||
case -1:
|
||||
throw new PaymentException("未转账");
|
||||
case -2:
|
||||
throw new PaymentException("coin参数不支持");
|
||||
default:
|
||||
throw new PaymentException("支付未知错误");
|
||||
}
|
||||
}
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送rabbitmq消息给矿机代理
|
||||
* @param leaseOrderItems
|
||||
*/
|
||||
public void sendRabbitmqMessage( List<LeaseOrderItem> leaseOrderItems) {
|
||||
leaseOrderItems.forEach(item -> {
|
||||
customThreadPool.execute(()->{
|
||||
RabbitmqPoolProxyMessage rabbitmqPoolProxyMessage = RabbitmqPoolProxyMessage.builder()
|
||||
.MethodID(0)
|
||||
.Msg("")
|
||||
.ID(item.getUser() + "-" + item.getMiner())
|
||||
.Address(item.getAddress())
|
||||
.build();
|
||||
try {
|
||||
rabbitTemplate.convertAndSend(POOL_PROXY_QUEUE_NAME, rabbitmqPoolProxyMessage);
|
||||
} catch (Exception e) {
|
||||
System.err.println("发送失败: " + e.getMessage());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.m2pool.lease.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.m2pool.lease.entity.LeaseProductIncome;
|
||||
import com.m2pool.lease.mapper.LeaseProductIncomeMapper;
|
||||
import com.m2pool.lease.service.LeaseProductIncomeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 商品收益表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
@Service
|
||||
public class LeaseProductIncomeServiceImpl extends ServiceImpl<LeaseProductIncomeMapper, LeaseProductIncome> implements LeaseProductIncomeService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.m2pool.lease.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.m2pool.lease.entity.LeaseProductMachinePrice;
|
||||
import com.m2pool.lease.mapper.LeaseProductMachinePriceMapper;
|
||||
import com.m2pool.lease.service.LeaseProductMachinePriceService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 商品表对应的物品机器表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
@Service
|
||||
public class LeaseProductMachinePriceServiceImpl extends ServiceImpl<LeaseProductMachinePriceMapper, LeaseProductMachinePrice> implements LeaseProductMachinePriceService {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,360 @@
|
||||
package com.m2pool.lease.service.impl;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.m2pool.lease.constant.BlockInterval;
|
||||
import com.m2pool.lease.redis.RedisCoinInfoKey;
|
||||
import com.m2pool.lease.dto.*;
|
||||
import com.m2pool.lease.entity.LeaseProduct;
|
||||
import com.m2pool.lease.entity.LeaseProductMachine;
|
||||
import com.m2pool.lease.entity.LeaseProductMachinePrice;
|
||||
import com.m2pool.lease.mapper.LeaseProductMachineMapper;
|
||||
import com.m2pool.lease.mapper.LeaseProductMapper;
|
||||
import com.m2pool.lease.redis.service.RedisService;
|
||||
import com.m2pool.lease.service.LeaseProductMachinePriceService;
|
||||
import com.m2pool.lease.service.LeaseProductMachineService;
|
||||
import com.m2pool.lease.utils.PowerUnitUtils;
|
||||
import com.m2pool.lease.utils.SecurityUtils;
|
||||
import com.m2pool.lease.vo.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
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.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 商品表对应的物品机器表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
@Service
|
||||
public class LeaseProductMachineServiceImpl extends ServiceImpl<LeaseProductMachineMapper, LeaseProductMachine> implements LeaseProductMachineService {
|
||||
|
||||
@Resource
|
||||
private LeaseProductMachineMapper leaseProductMachineMapper;
|
||||
@Resource
|
||||
private LeaseProductMapper leaseProductMapper;
|
||||
@Resource
|
||||
private RedisService redisService;
|
||||
@Resource
|
||||
private LeaseProductMachinePriceService leaseProductMachinePriceService;
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
@Override
|
||||
public Result<Map<String, List<UserMinerDto>> > getUserMinersList(UserMinerVo userMinerVo) {
|
||||
String userId = SecurityUtils.getUsername();
|
||||
|
||||
//开发环境
|
||||
//userId = "Eudora.law@outlook.com";
|
||||
List<UserMinerDto> userMinersList = leaseProductMachineMapper.getUserMinersList(userId,userMinerVo.getCoin());
|
||||
Map<String, List<UserMinerDto>> collect = userMinersList.stream().collect(Collectors.groupingBy(UserMinerDto::getCoin));
|
||||
return Result.success(collect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<UserMinerDto>> getUserMachineList(UserMinerVo userMinerVo) {
|
||||
//获取1天内的存在算力的机器(这里user 和coin 组成了表的唯一键,不用担心查询到其他用户相同的user和coin的矿机)
|
||||
List<UserMinerDto> minerMachines = leaseProductMachineMapper.getMinerMachines(userMinerVo.getUser(), userMinerVo.getCoin());
|
||||
//根据矿工账号查询已经新增到商品机器表中的机器
|
||||
List<String> minerMachinesIsSale = leaseProductMachineMapper.getMinerMachinesIsSale(userMinerVo.getUser(), userMinerVo.getCoin());
|
||||
// 过滤 minerMachines 集合,只保留 miner 字段值不在 existingMiners 中的元素
|
||||
minerMachines = minerMachines.stream()
|
||||
.filter(dto -> !minerMachinesIsSale.contains(dto.getMiner()))
|
||||
.peek(dto -> {
|
||||
dto.setRealPower(dto.getRealPower().divide(BigDecimal.valueOf(24 * 60 * 60),2, RoundingMode.HALF_UP));
|
||||
dto.setRealPower(dto.getRealPower().setScale(2, RoundingMode.HALF_UP));
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
return Result.success(minerMachines);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<ProductUpdateMachineDto> getMachineListForUpdate(ProductForUpdateMachineVo productForUpdateMachineVo) {
|
||||
PageHelper.startPage(productForUpdateMachineVo.getPageNum(), productForUpdateMachineVo.getPageSize());
|
||||
List<LeaseProductMachine> leaseProductMachines = leaseProductMachineMapper.selectList(new LambdaQueryWrapper<LeaseProductMachine>()
|
||||
.eq(LeaseProductMachine::getProductId, productForUpdateMachineVo.getId()).eq(LeaseProductMachine::getDel,false));
|
||||
PageInfo<LeaseProductMachine> pageInfo = new PageInfo<>(leaseProductMachines);
|
||||
if (leaseProductMachines.isEmpty()){
|
||||
//不存在租售的矿机
|
||||
return PageResult.success(new ArrayList<>());
|
||||
}
|
||||
//获取矿机对应的币价
|
||||
List<Long> machineIds = leaseProductMachines.stream().map(LeaseProductMachine::getId).collect(Collectors.toList());
|
||||
List<MachinePayTypeDto> priceList = leaseProductMachineMapper.getPriceList(machineIds);
|
||||
Map<Long, List<MachinePayTypeDto>> collect = priceList.stream().collect(Collectors.groupingBy(MachinePayTypeDto::getProductMachineId));
|
||||
|
||||
List<ProductUpdateMachineDto> productUpdateMachineDtos = leaseProductMachines.stream().map(leaseProductMachine ->
|
||||
ProductUpdateMachineDto.builder()
|
||||
.id(leaseProductMachine.getId())
|
||||
.user(leaseProductMachine.getUser())
|
||||
.type(leaseProductMachine.getType())
|
||||
.miner(leaseProductMachine.getMiner())
|
||||
.priceList(collect.get(leaseProductMachine.getId()))
|
||||
.computingPower(leaseProductMachine.getComputingPower().setScale(2, RoundingMode.HALF_UP))
|
||||
.theoryPower(leaseProductMachine.getTheoryPower())
|
||||
.unit(leaseProductMachine.getUnit())
|
||||
.maxLeaseDays(leaseProductMachine.getMaxLeaseDays())
|
||||
.state(leaseProductMachine.getState())
|
||||
.saleState(leaseProductMachine.getSaleState())
|
||||
.powerDissipation(leaseProductMachine.getPowerDissipation())
|
||||
.build()
|
||||
).collect(Collectors.toList());
|
||||
PageResult<ProductUpdateMachineDto> success = PageResult.success(productUpdateMachineDtos);
|
||||
success.setTotal(pageInfo.getTotal());
|
||||
success.setTotalPage(pageInfo.getPages());
|
||||
PageHelper.clearPage();
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DSTransactional
|
||||
public Result<String> addSingleOrBatchMachine(ProductMachineParamsVo productMachineParamsVo) {
|
||||
LeaseProduct product = leaseProductMapper.selectById(productMachineParamsVo.getProductId());
|
||||
|
||||
String coin = product.getCoin();
|
||||
if (coin == null){
|
||||
return Result.fail("商品币种不能为空");
|
||||
}
|
||||
//封装需要添加的商品的机器
|
||||
List<LeaseProductMachine> leaseProductMachines = new ArrayList<>();
|
||||
List<ProductMachineURDVo> productMachineURDVos = productMachineParamsVo.getProductMachineURDVos();
|
||||
|
||||
Map<Integer,List<LeaseProductMachinePrice>> payTypeMap = new HashMap<>();
|
||||
AtomicInteger index = new AtomicInteger(1);
|
||||
productMachineURDVos.forEach(machine -> {
|
||||
int andIncrement = index.getAndIncrement();
|
||||
leaseProductMachines.add(LeaseProductMachine.builder()
|
||||
.updateCount(andIncrement)
|
||||
.shopId(product.getShopId())
|
||||
.productId(productMachineParamsVo.getProductId())
|
||||
.type(machine.getType() == null ? productMachineParamsVo.getType() : machine.getType())
|
||||
.theoryPower(machine.getTheoryPower() == null ? productMachineParamsVo.getTheoryPower() : machine.getTheoryPower())
|
||||
.powerDissipation(productMachineParamsVo.getPowerDissipation())
|
||||
.cost(productMachineParamsVo.getCost())
|
||||
.price(BigDecimal.ZERO)
|
||||
.incomeRate(BigDecimal.ZERO)
|
||||
.maxLeaseDays(machine.getMaxLeaseDays() == null ? productMachineParamsVo.getMaxLeaseDays() : machine.getMaxLeaseDays())
|
||||
.unit(machine.getUnit() == null ? productMachineParamsVo.getUnit() : machine.getUnit())
|
||||
.powerDissipation(machine.getPowerDissipation() == null ? productMachineParamsVo.getPowerDissipation() : machine.getPowerDissipation())
|
||||
.user(machine.getUser())
|
||||
.miner(machine.getMiner())
|
||||
.coin(coin)
|
||||
.state(machine.getState())
|
||||
.del( false)
|
||||
.saleState(0)
|
||||
.build());
|
||||
payTypeMap.put(andIncrement,machine.getPriceList().stream()
|
||||
.map(payType -> LeaseProductMachinePrice.builder()
|
||||
.price(payType.getPrice())
|
||||
.coin(payType.getCoin())
|
||||
.chain(payType.getChain())
|
||||
.build())
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
//计算对应user+miner 一天的总算力
|
||||
List<ProductMachineDto> nexaMinersv2 = leaseProductMachineMapper.getRecentlyFiveMinutesData(leaseProductMachines, product.getCoin());
|
||||
// 创建一个 Map 用于存储 user 和 miner 组合对应的 ProductMachineDto 对象
|
||||
Map<String, ProductMachineDto> machineDtoMap = nexaMinersv2.stream()
|
||||
.collect(Collectors.toMap(
|
||||
dto -> dto.getUser() + "-" + dto.getMiner(),
|
||||
dto -> dto
|
||||
));
|
||||
String priceKey = RedisCoinInfoKey.getPiceKey(product.getCoin());
|
||||
String rewardKey = RedisCoinInfoKey.getRewardKey(product.getCoin());
|
||||
String mhsKey = RedisCoinInfoKey.getMhsKey(product.getCoin());
|
||||
|
||||
if (priceKey == null || rewardKey == null || mhsKey == null){
|
||||
return Result.fail("添加商品失败,该币种挖矿机器暂时不支持");
|
||||
}
|
||||
|
||||
BigDecimal price = redisService.getCacheBigDecimal(priceKey) == null ? BigDecimal.ZERO : redisService.getCacheBigDecimal(priceKey);
|
||||
BigDecimal reward = redisService.getCacheBigDecimal(rewardKey) == null ? BigDecimal.ZERO : redisService.getCacheBigDecimal(rewardKey);
|
||||
//全网算力单位是MH/s
|
||||
BigDecimal netPower = redisService.getCacheBigDecimal(mhsKey) == null ? BigDecimal.ZERO : redisService.getCacheBigDecimal(mhsKey);
|
||||
|
||||
if (price == null){
|
||||
return Result.fail("添加商品失败,未获取到"+product.getCoin()+"币的币价,请稍后重试");
|
||||
}
|
||||
if (reward == null){
|
||||
return Result.fail("添加商品失败,未获取到"+product.getCoin()+"币的报快奖励,请稍后重试");
|
||||
}
|
||||
if (netPower == null){
|
||||
return Result.fail("添加商品失败,未获取到"+product.getCoin()+"币的全网算力,请稍后重试");
|
||||
}
|
||||
|
||||
|
||||
|
||||
List<LeaseProductMachine> collect = leaseProductMachines.stream().peek(productMachineURDVo -> {
|
||||
//获取单机实际算力
|
||||
String key = productMachineURDVo.getUser() + "-" + productMachineURDVo.getMiner();
|
||||
ProductMachineDto productMachineDto = machineDtoMap.get(key);
|
||||
BigDecimal singleTheoryMachineIncome = BigDecimal.ZERO;
|
||||
BigDecimal computingPower = BigDecimal.ZERO;
|
||||
|
||||
if (productMachineDto != null && productMachineDto.getComputingPower() != null){
|
||||
//计算矿机一天内实际每秒平均算力
|
||||
computingPower = PowerUnitUtils.getPower(productMachineURDVo.getUnit(), productMachineDto.getComputingPower()
|
||||
.multiply(BigDecimal.valueOf(1000 * 1000))
|
||||
.divide(BigDecimal.valueOf(24 * 60 * 60), 2, RoundingMode.HALF_UP));
|
||||
BigDecimal power = PowerUnitUtils.getPower(productMachineURDVo.getUnit(), netPower.multiply(BigDecimal.valueOf(1000 * 1000)));
|
||||
//理论收益 = 矿机算力/全网算力 * 24h /出块间隔秒数 * 单块奖励(redis中nexa:reward)
|
||||
singleTheoryMachineIncome = computingPower.divide( power,6, RoundingMode.HALF_UP)
|
||||
.multiply(BigDecimal.valueOf(24 * 60 * 60)
|
||||
.divide(BlockInterval.getBlockCountByCoinName(product.getCoin()), 6, RoundingMode.HALF_UP))
|
||||
.multiply(reward)
|
||||
;
|
||||
|
||||
}
|
||||
productMachineURDVo.setShopId(product.getShopId());
|
||||
productMachineURDVo.setComputingPower(computingPower);
|
||||
productMachineURDVo.setTheoryIncome(singleTheoryMachineIncome);
|
||||
}).collect(Collectors.toList());
|
||||
//新增矿机 索引改为普通联合索引
|
||||
LeaseProductMachineServiceImpl service = applicationContext.getBean(LeaseProductMachineServiceImpl.class);
|
||||
//TODO 修改,还是得用唯一索引
|
||||
//leaseProductMachineMapper.saveOrUpdateBatchs(collect);
|
||||
boolean b = service.saveBatch(collect);
|
||||
if (b){
|
||||
//修改商品的价格范围 及商品下机器库存数量
|
||||
updatePriceRange(product.getId());
|
||||
List<LeaseProductMachinePrice> list = new ArrayList<>();
|
||||
for (LeaseProductMachine leaseProductMachine : collect) {
|
||||
|
||||
List<LeaseProductMachinePrice> leaseProductMachinePrices = payTypeMap.get(leaseProductMachine.getUpdateCount());
|
||||
list.addAll(leaseProductMachinePrices.stream()
|
||||
.peek(leaseProductMachinePrice -> leaseProductMachinePrice.setProductMachineId(leaseProductMachine.getId()))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
//修改机器配置
|
||||
leaseProductMachinePriceService.saveBatch(list);
|
||||
return Result.success("添加成功,添加矿机数:"+collect.size());
|
||||
}
|
||||
return Result.fail("添加失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<String> updateMachine(List<ProductUpdateMachineVo> productUpdateMachineVoList) {
|
||||
|
||||
List<Long> ids = new ArrayList<>();
|
||||
List<LeaseProductMachine> leaseProductMachines = new ArrayList<>();
|
||||
List<LeaseProductMachinePrice> list = new ArrayList<>();
|
||||
productUpdateMachineVoList.forEach(machine -> {
|
||||
leaseProductMachines.add( LeaseProductMachine.builder()
|
||||
.id(machine.getId())
|
||||
.type(machine.getType())
|
||||
.theoryPower(machine.getTheoryPower())
|
||||
.unit(machine.getUnit())
|
||||
.powerDissipation(machine.getPowerDissipation())
|
||||
//.electricityBill(machine.getElectricityBill())
|
||||
.incomeRate(machine.getIncomeRate())
|
||||
.price(machine.getPrice())
|
||||
.maxLeaseDays(machine.getMaxLeaseDays())
|
||||
.user(machine.getUser())
|
||||
.miner(machine.getMiner())
|
||||
.state(machine.getState())
|
||||
.build());
|
||||
list.addAll(machine.getPriceList().stream()
|
||||
.map(payType -> LeaseProductMachinePrice.builder()
|
||||
.id(payType.getPayTypeId())
|
||||
.price(payType.getPrice())
|
||||
.chain(payType.getChain())
|
||||
.build())
|
||||
.collect(Collectors.toList()));
|
||||
if (machine.getState() == 1){
|
||||
ids.add(machine.getId());
|
||||
}
|
||||
});
|
||||
if (!ids.isEmpty()){
|
||||
List<LeaseProductMachine> leaseProductMachines1 = leaseProductMachineMapper.selectBatchIds(ids);
|
||||
long count = leaseProductMachines1.stream()
|
||||
.filter(leaseProductMachine -> leaseProductMachine.getSaleState() == 1).count();
|
||||
if (count >= 1){
|
||||
return Result.fail("商品修改失败,部分矿机租约已存在,不能下架");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
boolean b = updateBatchById(leaseProductMachines);
|
||||
if (b){
|
||||
LeaseProductMachine leaseProductMachine = leaseProductMachineMapper.selectById(productUpdateMachineVoList.get(0).getId());
|
||||
//修改商品的价格范围
|
||||
updatePriceRange(leaseProductMachine.getProductId());
|
||||
leaseProductMachinePriceService.updateBatchById(list);
|
||||
return Result.success("修改成功");
|
||||
}
|
||||
return Result.fail("修改失败");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<String> deleteMachine(BaseVo baseVo) {
|
||||
LeaseProductMachine leaseProductMachine = leaseProductMachineMapper.selectById(baseVo.getId());
|
||||
if (leaseProductMachine.getSaleState() != 0){
|
||||
return Result.fail("该商品已售出,暂时不能删除");
|
||||
}
|
||||
//修改商品的价格范围 及商品下机器库存数量
|
||||
|
||||
boolean b = updateById(LeaseProductMachine.builder().id(baseVo.getId()).del(true).build());
|
||||
if (b){
|
||||
updatePriceRange(leaseProductMachine.getProductId());
|
||||
//删除售价
|
||||
leaseProductMachinePriceService.updateById(LeaseProductMachinePrice.builder().id(baseVo.getId()).del(true).build());
|
||||
return Result.success("删除成功");
|
||||
}
|
||||
return Result.fail("删除失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改商品价格范围
|
||||
* @param productId
|
||||
*/
|
||||
public void updatePriceRange(Long productId){
|
||||
|
||||
//修改商品的价格范围
|
||||
PriceDto priceDto = leaseProductMachineMapper.getPriceRange(productId);
|
||||
BigDecimal maxPrice = BigDecimal.ZERO;
|
||||
BigDecimal minPrice = BigDecimal.ZERO;
|
||||
Integer totalMachineNumber = 0;
|
||||
if (priceDto != null){
|
||||
totalMachineNumber = priceDto.getTotalMachineNumber();
|
||||
maxPrice = priceDto.getPriceMax();
|
||||
minPrice = priceDto.getPriceMin();
|
||||
}
|
||||
LeaseProduct build = LeaseProduct.builder().id(productId)
|
||||
.minPrice(minPrice)
|
||||
.maxPrice(maxPrice)
|
||||
.totalMachineNumber(totalMachineNumber )
|
||||
.build();
|
||||
leaseProductMapper.updateById(build);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<BigDecimal> calculatePrice(PriceCalculateVo priceCalculateVo) {
|
||||
//TODO 第三方计算器
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,539 @@
|
||||
package com.m2pool.lease.service.impl;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.cloud.commons.lang.StringUtils;
|
||||
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.lease.constant.Algorithm;
|
||||
import com.m2pool.lease.constant.BlockInterval;
|
||||
import com.m2pool.lease.constant.PowerUnit;
|
||||
import com.m2pool.lease.redis.RedisCoinInfoKey;
|
||||
import com.m2pool.lease.dto.*;
|
||||
import com.m2pool.lease.entity.*;
|
||||
import com.m2pool.lease.exception.ProductSoldOutException;
|
||||
import com.m2pool.lease.mapper.*;
|
||||
import com.m2pool.lease.redis.service.RedisService;
|
||||
import com.m2pool.lease.service.LeaseProductMachinePriceService;
|
||||
import com.m2pool.lease.service.LeaseProductService;
|
||||
import com.m2pool.lease.service.LeaseShopConfigService;
|
||||
import com.m2pool.lease.utils.PowerUnitUtils;
|
||||
import com.m2pool.lease.utils.QrCodeUtils;
|
||||
import com.m2pool.lease.utils.SecurityUtils;
|
||||
import com.m2pool.lease.utils.WalletRuleCheckUtils;
|
||||
import com.m2pool.lease.vo.*;
|
||||
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.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 商品表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
@Service
|
||||
public class LeaseProductServiceImpl extends ServiceImpl<LeaseProductMapper, LeaseProduct> implements LeaseProductService {
|
||||
|
||||
|
||||
@Resource
|
||||
private LeaseProductMachineMapper leaseProductMachineMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseProductMapper leaseProductMapper;
|
||||
|
||||
@Resource
|
||||
private RedisService redisService;
|
||||
|
||||
@Resource
|
||||
private LeaseShopMapper leaseShopMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseShopConfigMapper leaseShopConfigMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseProductMachinePriceService leaseProductMachinePriceService;
|
||||
@Resource
|
||||
private LeaseShopConfigService leaseShopConfigService;
|
||||
|
||||
@Resource
|
||||
private LeaseProductMachinePriceMapper leaseProductMachinePriceMapper;
|
||||
|
||||
|
||||
@Override
|
||||
public PageResult<ProductDto> getProductList(ProductPageVo productPageVo) {
|
||||
Long shopId = 0L;
|
||||
System.out.println("用户邮箱参数:"+productPageVo.getUserEmail());
|
||||
//1.用户邮箱参数不为空,则表示个人中心的商品列表。这个时候能看到下架的商品
|
||||
if (!StringUtils.isEmpty(productPageVo.getUserEmail())){
|
||||
LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper<LeaseShop>()
|
||||
.eq(LeaseShop::getUserEmail, productPageVo.getUserEmail()));
|
||||
if (leaseShop != null){
|
||||
shopId = leaseShop.getId();
|
||||
}else{
|
||||
//不存在出售商品
|
||||
return PageResult.success(new ArrayList<>());
|
||||
}
|
||||
}
|
||||
PageHelper.startPage(productPageVo.getPageNum(), productPageVo.getPageSize());
|
||||
List<ProductDto> leaseProducts = leaseProductMapper.getProductListForShopAndUserCenter(productPageVo.getCoin(), productPageVo.getAlgorithm(), shopId);
|
||||
PageInfo<ProductDto> pageInfo = new PageInfo<>(leaseProducts);
|
||||
if(leaseProducts.isEmpty()){
|
||||
//, "不存在出售商品"
|
||||
return PageResult.success(new ArrayList<>());
|
||||
}
|
||||
//获取店铺对应的支付方式
|
||||
List<Long> shopIds = leaseProducts.stream().map(ProductDto::getShopId).distinct().collect(Collectors.toList());
|
||||
List<PayTypeDto> payType = leaseShopConfigMapper.getPayType(shopIds);
|
||||
Map<Long, List<PayTypeDto>> payTypeMap = payType.stream().collect(Collectors.groupingBy(PayTypeDto::getShopId));
|
||||
//配置支付列表
|
||||
for (ProductDto productDto : leaseProducts) {
|
||||
productDto.setPayTypes(payTypeMap.get(productDto.getShopId()));
|
||||
}
|
||||
|
||||
PageResult<ProductDto> success = PageResult.success(leaseProducts);
|
||||
success.setTotal(pageInfo.getTotal());
|
||||
success.setTotalPage(pageInfo.getPages());
|
||||
PageHelper.clearPage();
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Result<ProductDto> getMachineInfoById(BaseVo baseVo) {
|
||||
LeaseProduct leaseProduct = leaseProductMapper.selectById(baseVo.getId());
|
||||
if (leaseProduct == null) {
|
||||
//"商品不存在"
|
||||
return Result.success(null);
|
||||
}
|
||||
|
||||
String priceRange = leaseProduct.getMinPrice().equals(leaseProduct.getMaxPrice()) ? leaseProduct.getMinPrice().toString(): leaseProduct.getMinPrice() +"-"+leaseProduct.getMaxPrice();
|
||||
ProductDto productDto = ProductDto.builder()
|
||||
.id(leaseProduct.getId())
|
||||
.shopId(leaseProduct.getShopId())
|
||||
.name(leaseProduct.getName())
|
||||
.image(leaseProduct.getImage())
|
||||
.type(leaseProduct.getType())
|
||||
.state(leaseProduct.getState())
|
||||
.priceRange(priceRange)
|
||||
.description(leaseProduct.getDescription())
|
||||
.coin(leaseProduct.getCoin())
|
||||
.algorithm(leaseProduct.getAlgorithm())
|
||||
.build();
|
||||
return Result.success(productDto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<ProductMachineDto> getProductMachineInfo(ProductMachineVo productMachineVo) {
|
||||
Long productId = productMachineVo.getId();
|
||||
LeaseProduct product = getById(productId);
|
||||
List<PayConfigDto> shopWalletInfo = leaseShopMapper.getShopWalletInfo(product.getShopId());
|
||||
PageHelper.startPage(productMachineVo.getPageNum(), productMachineVo.getPageSize());
|
||||
productMachineVo = buildQuery(productMachineVo,shopWalletInfo.get(0));
|
||||
List<ProductMachineDto> productMachineDtoList = leaseProductMachineMapper.getMachinesByPriceAndPowerAndDissipation(productMachineVo, product.getCoin());
|
||||
PageInfo<ProductMachineDto> pageInfo = new PageInfo<>(productMachineDtoList);
|
||||
|
||||
if (productMachineDtoList.isEmpty()){
|
||||
//,"不存在矿机"
|
||||
return PageResult.success(new ArrayList<>());
|
||||
}
|
||||
//币价 单位usdt
|
||||
BigDecimal price = redisService.getCacheBigDecimal(RedisCoinInfoKey.getPiceKey(product.getCoin())) == null ? BigDecimal.ZERO : redisService.getCacheBigDecimal(RedisCoinInfoKey.getPiceKey(product.getCoin()));
|
||||
//报块奖励
|
||||
BigDecimal reward =redisService.getCacheBigDecimal(RedisCoinInfoKey.getRewardKey(product.getCoin())) == null ? BigDecimal.ZERO : redisService.getCacheBigDecimal(RedisCoinInfoKey.getRewardKey(product.getCoin())) ;
|
||||
//全网算力单位是MH/s
|
||||
BigDecimal mhs = redisService.getCacheBigDecimal(RedisCoinInfoKey.getMhsKey(product.getCoin())) == null ? BigDecimal.ZERO : redisService.getCacheBigDecimal(RedisCoinInfoKey.getMhsKey(product.getCoin()));
|
||||
|
||||
List<ProductMachineDto> productMachines = productMachineDtoList.stream()
|
||||
.peek(productMachineDto -> {
|
||||
//理论收益
|
||||
BigDecimal singleTheoryMachineIncome = BigDecimal.ZERO;
|
||||
productMachineDto.setAlgorithm(product.getAlgorithm());
|
||||
// 矿机算力单位转换 + 计算单矿机平均算力(ComputingPower coin_real_power 24小时总算力)
|
||||
BigDecimal computingPower = PowerUnitUtils.getPower(productMachineDto.getUnit(), productMachineDto.getComputingPower()
|
||||
.multiply(BigDecimal.valueOf(1000 * 1000)));
|
||||
//全网算力单位转换
|
||||
BigDecimal power = PowerUnitUtils.getPower(productMachineDto.getUnit(), mhs.multiply(BigDecimal.valueOf(1000 * 1000)));
|
||||
//(理论收益 = 矿机算力/全网算力 * 24h /出块间隔秒数 * 单块奖励(redis中nexa:reward))
|
||||
singleTheoryMachineIncome = computingPower.divide( power,6, RoundingMode.HALF_UP)
|
||||
.multiply(BigDecimal.valueOf(24 * 60 * 60)
|
||||
.divide(BlockInterval.getBlockCountByCoinName(product.getCoin()), 6, RoundingMode.HALF_UP))
|
||||
.multiply(reward);
|
||||
productMachineDto.setComputingPower(computingPower);
|
||||
productMachineDto.setTheoryIncome(singleTheoryMachineIncome);
|
||||
productMachineDto.setTheoryUsdtIncome(singleTheoryMachineIncome.multiply(price));
|
||||
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
//分页内排序
|
||||
productMachines = sorted(productMachines,productMachineVo);
|
||||
PageResult<ProductMachineDto> success = PageResult.success(productMachines);
|
||||
success.setTotal(pageInfo.getTotal());
|
||||
success.setTotalPage(pageInfo.getPages());
|
||||
PageHelper.clearPage();
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建查询条件
|
||||
* @param productMachineVo
|
||||
* @param payConfigDto
|
||||
* @return
|
||||
*/
|
||||
public ProductMachineVo buildQuery(ProductMachineVo productMachineVo,PayConfigDto payConfigDto){
|
||||
if (StringUtils.isEmpty(productMachineVo.getChain()) && StringUtils.isEmpty(productMachineVo.getCoin())){
|
||||
productMachineVo.setChain(payConfigDto.getPayChain());
|
||||
productMachineVo.setCoin(payConfigDto.getPayCoin());
|
||||
}
|
||||
BigDecimal power = PowerUnit.getPower(productMachineVo.getUnit()).divide(BigDecimal.valueOf(1000 * 1000),2,RoundingMode.HALF_UP);
|
||||
productMachineVo.setMaxPower(productMachineVo.getMaxPower().multiply(power));
|
||||
productMachineVo.setMinPower(productMachineVo.getMinPower().multiply(power));
|
||||
//算力设置
|
||||
if (productMachineVo.getMaxPower().compareTo(productMachineVo.getMinPower()) < 0){
|
||||
productMachineVo.setMaxPower(productMachineVo.getMinPower());
|
||||
productMachineVo.setMinPower(productMachineVo.getMaxPower());
|
||||
}
|
||||
//功耗设置
|
||||
if (productMachineVo.getMaxPowerDissipation().compareTo(productMachineVo.getMinPowerDissipation()) < 0){
|
||||
productMachineVo.setMaxPowerDissipation(productMachineVo.getMinPowerDissipation());
|
||||
productMachineVo.setMinPowerDissipation(productMachineVo.getMaxPowerDissipation());
|
||||
}
|
||||
//价格设置
|
||||
if (productMachineVo.getMaxPrice().compareTo(productMachineVo.getMinPrice()) < 0){
|
||||
|
||||
productMachineVo.setMaxPrice(productMachineVo.getMinPrice());
|
||||
productMachineVo.setMinPrice(productMachineVo.getMaxPrice());
|
||||
}
|
||||
System.out.println("请求参数"+ JSONUtil.toJsonPrettyStr(productMachineVo));
|
||||
return productMachineVo;
|
||||
}
|
||||
|
||||
public List<ProductMachineDto> sorted(List<ProductMachineDto> productMachineDtoList,ProductMachineVo productMachineVo){
|
||||
|
||||
if (productMachineVo.getPriceSort() != null) {
|
||||
Comparator<ProductMachineDto> priceComparator = productMachineVo.getPriceSort() ?
|
||||
Comparator.comparing(ProductMachineDto::getPrice) :
|
||||
Comparator.comparing(ProductMachineDto::getPrice).reversed();
|
||||
return productMachineDtoList.stream()
|
||||
.sorted(priceComparator)
|
||||
.collect(Collectors.toList());
|
||||
} else if (productMachineVo.getPowerSort() != null) {
|
||||
Comparator<ProductMachineDto> powerComparator = productMachineVo.getPowerSort() ?
|
||||
Comparator.comparing(ProductMachineDto::getComputingPower) :
|
||||
Comparator.comparing(ProductMachineDto::getComputingPower).reversed();
|
||||
return productMachineDtoList.stream()
|
||||
.sorted(powerComparator)
|
||||
.collect(Collectors.toList());
|
||||
} else if (productMachineVo.getPowerDissipationSort() != null) {
|
||||
Comparator<ProductMachineDto> powerDissipationComparator = productMachineVo.getPowerDissipationSort() ?
|
||||
Comparator.comparing(ProductMachineDto::getPowerDissipation) :
|
||||
Comparator.comparing(ProductMachineDto::getPowerDissipation).reversed();
|
||||
return productMachineDtoList.stream()
|
||||
.sorted(powerDissipationComparator)
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
return productMachineDtoList;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<PayConfigDto>> getPayTypes(ShopPayTypeVo shopPayTypeVo) {
|
||||
Long shopId ;
|
||||
if (shopPayTypeVo == null){
|
||||
LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper<LeaseShop>()
|
||||
.select(LeaseShop::getId)
|
||||
.eq(LeaseShop::getUserEmail, SecurityUtils.getUsername())
|
||||
.eq(LeaseShop::getDel, false));
|
||||
if (leaseShop == null){
|
||||
//"店铺不存在"
|
||||
return Result.success(null);
|
||||
}
|
||||
shopId = leaseShop.getId();
|
||||
}else{
|
||||
shopId = shopPayTypeVo.getShopId();
|
||||
}
|
||||
List<PayConfigDto> shopWalletInfo = leaseShopMapper.getShopWalletInfo(shopId);
|
||||
return Result.success(shopWalletInfo);
|
||||
}
|
||||
|
||||
///**
|
||||
// * 计算每个价格分组中商品机器的功耗、理论算力、实际算力范围,并返回对应的范围信息对象
|
||||
// * @param productMachineDtoMap 按价格分组的商品机器列表
|
||||
// * @return 每个价格对应的商品机器范围信息
|
||||
// */
|
||||
//public static Map<BigDecimal, ProductMachineRangeGroupDto> calculateRanges(Map<BigDecimal, List<ProductMachineDto>> productMachineDtoMap) {
|
||||
// // 使用 AtomicInteger 来实现 onlyKey 递增
|
||||
// AtomicInteger onlyKey = new AtomicInteger(0);
|
||||
// return productMachineDtoMap.entrySet().stream()
|
||||
// .collect(Collectors.toMap(
|
||||
// Map.Entry::getKey,
|
||||
// entry -> {
|
||||
// List<ProductMachineDto> productMachines = entry.getValue();
|
||||
// int number = productMachines.size();
|
||||
// BigDecimal price = entry.getKey();
|
||||
//
|
||||
// // 计算功耗范围
|
||||
// BigDecimal minPower = productMachines.stream()
|
||||
// .map(ProductMachineDto::getPowerDissipation)
|
||||
// .min(BigDecimal::compareTo)
|
||||
// .orElse(BigDecimal.ZERO);
|
||||
// BigDecimal maxPower = productMachines.stream()
|
||||
// .map(ProductMachineDto::getPowerDissipation)
|
||||
// .max(BigDecimal::compareTo)
|
||||
// .orElse(BigDecimal.ZERO);
|
||||
// String powerRange = minPower.equals(maxPower) ? String.valueOf(minPower) : minPower + " - " + maxPower;
|
||||
//
|
||||
// // 计算理论算力范围
|
||||
// BigDecimal minTheoryPower = productMachines.stream()
|
||||
// .map(ProductMachineDto::getTheoryPower)
|
||||
// .min(BigDecimal::compareTo)
|
||||
// .orElse(BigDecimal.ZERO);
|
||||
// BigDecimal maxTheoryPower = productMachines.stream()
|
||||
// .map(ProductMachineDto::getTheoryPower)
|
||||
// .max(BigDecimal::compareTo)
|
||||
// .orElse(BigDecimal.ZERO);
|
||||
// String theoryPowerRange = minTheoryPower.equals(maxTheoryPower) ? String.valueOf(minTheoryPower) : minTheoryPower + " - " + maxTheoryPower;
|
||||
//
|
||||
// // 计算实际算力范围
|
||||
// BigDecimal minComputingPower = productMachines.stream()
|
||||
// .map(ProductMachineDto::getComputingPower)
|
||||
// .min(BigDecimal::compareTo)
|
||||
// .orElse(BigDecimal.ZERO);
|
||||
// BigDecimal maxComputingPower = productMachines.stream()
|
||||
// .map(ProductMachineDto::getComputingPower)
|
||||
// .max(BigDecimal::compareTo)
|
||||
// .orElse(BigDecimal.ZERO);
|
||||
// String computingPowerRange = minComputingPower.equals(maxComputingPower) ? String.valueOf(minComputingPower) : minComputingPower + " - " + maxComputingPower;
|
||||
// String unit = productMachines.get(0).getUnit();
|
||||
// int onlyKey1 = onlyKey.incrementAndGet();
|
||||
// return ProductMachineRangeGroupDto.builder()
|
||||
// .onlyKey(onlyKey1)
|
||||
// .powerRange(powerRange)
|
||||
// .theoryPowerRange(theoryPowerRange)
|
||||
// .computingPowerRange(computingPowerRange)
|
||||
// .number(number)
|
||||
// .price(price)
|
||||
// .unit(unit)
|
||||
// .build();
|
||||
// }
|
||||
// ));
|
||||
//}
|
||||
|
||||
|
||||
@Override
|
||||
public Result<String> addProduct(ProductURDVo productURDVo) {
|
||||
//校验是否存在收款钱包,不存在无法创建商品
|
||||
|
||||
List<LeaseShopConfig> leaseShopConfig = leaseShopConfigMapper.selectList(new LambdaQueryWrapper<LeaseShopConfig>()
|
||||
.eq(LeaseShopConfig::getShopId, productURDVo.getShopId()).eq(LeaseShopConfig::getDel, 0));
|
||||
if (leaseShopConfig.isEmpty()){
|
||||
return Result.fail("添加商品失败,请先绑定收款钱包");
|
||||
}
|
||||
String algorithm = Algorithm.getAlgorithm(productURDVo.getCoin());
|
||||
String coinFullName = Algorithm.getCoinFullName(productURDVo.getCoin());
|
||||
LeaseProduct product = LeaseProduct.builder()
|
||||
.image(productURDVo.getImage())
|
||||
.name(productURDVo.getName())
|
||||
.algorithm(algorithm)
|
||||
.description(productURDVo.getDescription())
|
||||
.state(productURDVo.getState())
|
||||
.type(productURDVo.getType())
|
||||
.coin(productURDVo.getCoin())
|
||||
.shopId(productURDVo.getShopId())
|
||||
.coinFullName(coinFullName)
|
||||
.build();
|
||||
boolean save = save(product);
|
||||
if (!save){
|
||||
return Result.fail("新增商品失败");
|
||||
}
|
||||
return Result.success("新增商品成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<String> updateProduct(ProductURDVo productURDVo) {;
|
||||
PriceDto priceDto = leaseProductMachineMapper.getPriceRange(productURDVo.getId());
|
||||
BigDecimal maxPrice = BigDecimal.ZERO;
|
||||
BigDecimal minPrice = BigDecimal.ZERO;
|
||||
if (priceDto != null){
|
||||
maxPrice = priceDto.getPriceMax();
|
||||
minPrice = priceDto.getPriceMin();
|
||||
}
|
||||
|
||||
//校验商品是否能够上下架
|
||||
if (productURDVo.getState() == 1 && leaseProductMachineMapper.checkHasSaleMachineByProductId(productURDVo.getId()) >= 1){
|
||||
return Result.fail("商品下架失败,商品存在租约中矿机");
|
||||
}
|
||||
|
||||
//修改商品主表
|
||||
String algorithm = Algorithm.getAlgorithm(productURDVo.getCoin());
|
||||
String coinFullName = Algorithm.getCoinFullName(productURDVo.getCoin());
|
||||
LeaseProduct product = LeaseProduct.builder()
|
||||
.id(productURDVo.getId())
|
||||
.image(productURDVo.getImage())
|
||||
.name(productURDVo.getName())
|
||||
.description(productURDVo.getDescription())
|
||||
.state(productURDVo.getState())
|
||||
.algorithm(algorithm)
|
||||
.maxPrice(maxPrice)
|
||||
.minPrice(minPrice)
|
||||
.type(productURDVo.getType())
|
||||
.coinFullName(coinFullName)
|
||||
.build();
|
||||
|
||||
boolean b1 = updateById(product);
|
||||
if (b1){
|
||||
return Result.success("修改商品成功");
|
||||
}
|
||||
return Result.fail("修改商品失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<String> deleteProduct(Long id) {
|
||||
int i = leaseProductMachineMapper.checkHasSaleMachineByProductId(id);
|
||||
if(i >= 1){
|
||||
return Result.fail("删除失败,该商品存在租约中的机器");
|
||||
}
|
||||
boolean updateFather = updateById(LeaseProduct.builder().id(id).del(true).build());
|
||||
List<Long> machineIds = leaseProductMachineMapper.getIdsForProductId(id);
|
||||
if (updateFather){
|
||||
if (!machineIds.isEmpty()){
|
||||
leaseProductMachineMapper.update(LeaseProductMachine.builder().del(true).build(),
|
||||
new LambdaQueryWrapper<LeaseProductMachine>().in(LeaseProductMachine::getId, machineIds));
|
||||
//删除矿机对应的售价
|
||||
leaseProductMachinePriceService.update(LeaseProductMachinePrice.builder().del(true).build(),new LambdaUpdateWrapper<LeaseProductMachinePrice>().in(LeaseProductMachinePrice::getProductMachineId, machineIds));
|
||||
}
|
||||
|
||||
return Result.success("删除成功");
|
||||
}
|
||||
return Result.fail("删除失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<PayTypeDto>> getSupportPayType() {
|
||||
Long shopId = getShopIdByProductId();
|
||||
List<PayTypeDto> supportPayType = leaseProductMapper.getSupportPayType(shopId);
|
||||
return Result.success(supportPayType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Result<List<ProductForWalletConfigDto>> getProductListForShopWalletConfig() {
|
||||
Long shopId = getShopIdByProductId();
|
||||
//1.获取商品列表
|
||||
List<ProductForWalletConfigDto> productForShopWalletConfigDtoList = leaseProductMapper.getProductListForShopWalletConfig(shopId);
|
||||
if (productForShopWalletConfigDtoList.isEmpty()){
|
||||
return Result.success(productForShopWalletConfigDtoList);
|
||||
}
|
||||
//2.获取商品对应矿机
|
||||
List<ProductMachineForWalletConfigDto> productMachineForWalletConfigDtoList = leaseProductMachineMapper.getProductListForShopWalletConfig(shopId);
|
||||
BigDecimal usdtPrice = redisService.getCacheBigDecimal(RedisCoinInfoKey.getPiceKey(productForShopWalletConfigDtoList.get(0).getCoin()));
|
||||
Map<Long, List<ProductMachineForWalletConfigDto>> collect = productMachineForWalletConfigDtoList.stream()
|
||||
.peek(productMachineForWalletConfigDto -> {
|
||||
productMachineForWalletConfigDto.setTheoryUsdtIncome(productMachineForWalletConfigDto.getTheoryIncome()
|
||||
.multiply(usdtPrice));
|
||||
})
|
||||
.collect(Collectors.groupingBy(ProductMachineForWalletConfigDto::getProductId));
|
||||
for (ProductForWalletConfigDto productForWalletConfigDto : productForShopWalletConfigDtoList) {
|
||||
List<ProductMachineForWalletConfigDto> list = collect.get(productForWalletConfigDto.getProductId());
|
||||
if (list.isEmpty()){
|
||||
productForShopWalletConfigDtoList.remove(productForWalletConfigDto);
|
||||
}
|
||||
productForWalletConfigDto.setMachineList(list);
|
||||
}
|
||||
return Result.success(productForShopWalletConfigDtoList);
|
||||
}
|
||||
|
||||
public Long getShopIdByProductId(){
|
||||
LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper<LeaseShop>()
|
||||
.select(LeaseShop::getId)
|
||||
.eq(LeaseShop::getUserEmail, SecurityUtils.getUsername())
|
||||
.eq(LeaseShop::getDel, false));
|
||||
return leaseShop.getId();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<String> updateProductListForShopWalletConfig(ProductMachineForWalletConfigVo productMachineForWalletConfigVo) {
|
||||
List<String> payCoinsList = new ArrayList<>(Arrays.asList(productMachineForWalletConfigVo.getSymbol().split(",")));
|
||||
String chain = productMachineForWalletConfigVo.getChain();
|
||||
String address = productMachineForWalletConfigVo.getPayAddress();
|
||||
LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper<LeaseShop>()
|
||||
.eq(LeaseShop::getAuthId, SecurityUtils.getUserId()));
|
||||
boolean check = checkHashWalletInfo(leaseShop.getId(),chain,address, payCoinsList);
|
||||
if (!check){
|
||||
return Result.fail("绑定钱包失败,钱包格式不正确或该链和币种钱包已绑定过");
|
||||
}
|
||||
String[] symbolList = productMachineForWalletConfigVo.getSymbol().split(",");
|
||||
List<ProductMachineForWalletConfigVo.PriceVo> priceAndIdList = productMachineForWalletConfigVo.getProductMachineForWalletConfigVoList();
|
||||
List<LeaseProductMachinePrice> leaseProductMachinePriceList = new ArrayList<>();
|
||||
for (ProductMachineForWalletConfigVo.PriceVo priceVo : priceAndIdList) {
|
||||
String[] priceList = priceVo.getPrice().split(",");
|
||||
if (priceList.length != symbolList.length){
|
||||
return Result.fail("绑定钱包失败,存在商品矿机未设置新钱包售价");
|
||||
}
|
||||
for (int i = 0; i < priceList.length; i++) {
|
||||
leaseProductMachinePriceList.add(LeaseProductMachinePrice.builder()
|
||||
.productMachineId(priceVo.getProductMachineId())
|
||||
.price(new BigDecimal(priceList[i]))
|
||||
.coin(symbolList[i])
|
||||
.chain(chain)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
boolean b = leaseProductMachinePriceService.saveBatch(leaseProductMachinePriceList);
|
||||
if (b || leaseProductMachinePriceList.isEmpty()){
|
||||
//绑定钱包新钱包
|
||||
List<LeaseShopConfig> shopConfigList = leaseShopConfigMapper.getCoinIconByChainAndCoin(chain, payCoinsList);
|
||||
String qrCode = QrCodeUtils.creatRrCode(address, 200, 200);
|
||||
for (LeaseShopConfig leaseShopConfig : shopConfigList) {
|
||||
leaseShopConfig.setShopId(leaseShop.getId());
|
||||
leaseShopConfig.setChain(chain);
|
||||
leaseShopConfig.setPayAddress(address);
|
||||
leaseShopConfig.setQrcode(qrCode);
|
||||
}
|
||||
boolean insetWallet = leaseShopConfigService.saveBatch(shopConfigList);
|
||||
if (insetWallet){
|
||||
return Result.success("绑定钱包成功");
|
||||
}
|
||||
throw new ProductSoldOutException ("钱包绑定失败");
|
||||
}
|
||||
throw new ProductSoldOutException ("新币种钱包商品售价新增失败");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 钱包格式校验,以及判断该链和币种钱包是否已存在
|
||||
* @param chain
|
||||
* @param address
|
||||
* @param coinList
|
||||
* @return
|
||||
*/
|
||||
public boolean checkHashWalletInfo(Long shopId,String chain,String address,List<String> coinList){
|
||||
if (!WalletRuleCheckUtils.checkAddress(chain,address)){
|
||||
return false;
|
||||
}
|
||||
List<LeaseShopConfig> configList = leaseShopConfigMapper.selectList(new LambdaQueryWrapper<LeaseShopConfig>()
|
||||
.eq(LeaseShopConfig::getShopId, shopId)
|
||||
.eq(LeaseShopConfig::getChain, chain)
|
||||
.in(LeaseShopConfig::getPayCoin, coinList)
|
||||
.eq(LeaseShopConfig::getDel, false)
|
||||
);
|
||||
if (!configList.isEmpty()){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.m2pool.lease.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.m2pool.lease.entity.LeaseShopConfig;
|
||||
import com.m2pool.lease.mapper.LeaseShopConfigMapper;
|
||||
import com.m2pool.lease.service.LeaseShopConfigService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 店铺商品配置表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-08-05
|
||||
*/
|
||||
@Service
|
||||
public class LeaseShopConfigServiceImpl extends ServiceImpl<LeaseShopConfigMapper, LeaseShopConfig> implements LeaseShopConfigService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,758 @@
|
||||
package com.m2pool.lease.service.impl;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
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.lease.aspect.OperationLogAspect;
|
||||
import com.m2pool.lease.dto.*;
|
||||
import com.m2pool.lease.dto.v2.PayWithdrawSellerRecordDto;
|
||||
import com.m2pool.lease.dto.v2.ShopWalletInfoDto;
|
||||
import com.m2pool.lease.entity.*;
|
||||
import com.m2pool.lease.exception.MachineException;
|
||||
import com.m2pool.lease.exception.PaymentException;
|
||||
import com.m2pool.lease.mapper.*;
|
||||
import com.m2pool.lease.mq.message.RabbitmqPayWithdrawMessage;
|
||||
import com.m2pool.lease.service.LeaseShopConfigService;
|
||||
import com.m2pool.lease.service.LeaseShopService;
|
||||
import com.m2pool.lease.utils.*;
|
||||
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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 店铺表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-08-05
|
||||
*/
|
||||
@Service
|
||||
public class LeaseShopServiceImpl extends ServiceImpl<LeaseShopMapper, LeaseShop> implements LeaseShopService {
|
||||
|
||||
@Resource
|
||||
private LeaseShopMapper leaseShopMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseShopConfigMapper leaseShopConfigMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseOrderItemMapper leaseOrderItemMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseShopConfigService leaseShopConfigService;
|
||||
|
||||
@Resource
|
||||
private LeaseProductMapper leaseProductMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseProductMachineMapper leaseProductMachineMapper;
|
||||
|
||||
|
||||
@Resource
|
||||
private LeaseMachinePriceMapper leaseMachinePriceMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseUserMapper leaseUserMapper;
|
||||
|
||||
@Resource
|
||||
private LeasePayWithdrawMessageMapper leasePayWithdrawMessageMapper;
|
||||
|
||||
@Resource
|
||||
private RabbitTemplate rabbitTemplate;
|
||||
|
||||
@Resource
|
||||
private LeaseAutoAddressMapper leaseAutoAddressMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseMachineMapper leaseMachineMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseMachineConfigMapper leaseMachineConfigMapper;
|
||||
|
||||
@Override
|
||||
public Result<String> addShop(ShopVo shopVo) {
|
||||
LeaseShop leaseShop1 = leaseShopMapper.selectOne(new LambdaQueryWrapper<LeaseShop>()
|
||||
.eq(LeaseShop::getUserEmail, SecurityUtils.getUsername()).eq(LeaseShop::getDel, false));
|
||||
|
||||
LeaseShop leaseShop = LeaseShop.builder()
|
||||
.userEmail(SecurityUtils.getUsername())
|
||||
.name(shopVo.getName())
|
||||
.image(shopVo.getImage())
|
||||
.description(shopVo.getDescription())
|
||||
.state(shopVo.getState())
|
||||
.feeRate(shopVo.getFeeRate())
|
||||
.authId(SecurityUtils.getUserId())
|
||||
.build();
|
||||
|
||||
if(leaseShop1 != null){
|
||||
return Result.fail("当前已存在店铺,请勿重复添加");
|
||||
}
|
||||
boolean save = save(leaseShop);
|
||||
return save ? Result.success("新增店铺成功") : Result.fail("新增店铺失败");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<String> updateShop(ShopVo shopVo) {
|
||||
|
||||
if (shopVo.getId() == null || shopVo.getId() == 0){
|
||||
return Result.fail("id不能为空或0");
|
||||
}
|
||||
|
||||
LeaseShop leaseShop = LeaseShop.builder()
|
||||
.id(shopVo.getId())
|
||||
.userEmail(SecurityUtils.getUsername())
|
||||
.name(shopVo.getName())
|
||||
.image(shopVo.getImage())
|
||||
.description(shopVo.getDescription())
|
||||
.state(shopVo.getState())
|
||||
.feeRate(shopVo.getFeeRate())
|
||||
.authId(SecurityUtils.getUserId())
|
||||
.build();
|
||||
LeaseShop byId = getById(shopVo.getId());
|
||||
if (byId.getDel()){
|
||||
return Result.fail("修改失败,店铺已被删除");
|
||||
}
|
||||
boolean save = updateById(leaseShop);
|
||||
if (save) {
|
||||
return Result.success("修改店铺成功");
|
||||
}
|
||||
return Result.fail("修改店铺失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<String> closeShop(BaseVo baseVo) {
|
||||
LeaseShop leaseShop = getById(baseVo.getId());
|
||||
if (leaseShop == null) {
|
||||
return Result.fail("店铺不存在");
|
||||
}
|
||||
//校验是否存在已售出的矿机
|
||||
if (leaseProductMachineMapper.checkHasSaleMachineByShopId(baseVo.getId()) >= 1 || leaseMachineMapper.checkHasSaleMachineByShopId(baseVo.getId()) >= 1){
|
||||
return Result.fail("关闭店铺失败,店铺存在租约中矿机");
|
||||
}
|
||||
|
||||
|
||||
if (leaseShop.getState() == 1){
|
||||
leaseShop.setState(2);
|
||||
boolean b = updateById(leaseShop);
|
||||
return b ? Result.success("关闭店铺成功") : Result.fail("关闭店铺失败");
|
||||
}
|
||||
if (leaseShop.getState() == 2){
|
||||
leaseShop.setState(1);
|
||||
boolean b = updateById(leaseShop);
|
||||
return b ? Result.success("开启店铺成功") : Result.fail("开启店铺失败");
|
||||
}
|
||||
return Result.fail("店铺正在审核中不能开启和关闭店铺");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<ShopDto> getShopByUserEmail() {
|
||||
LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper<LeaseShop>()
|
||||
.eq(LeaseShop::getUserEmail, SecurityUtils.getUsername())
|
||||
.eq(LeaseShop::getDel, false));
|
||||
ShopDto build = null;
|
||||
if (leaseShop != null){
|
||||
build = ShopDto.builder()
|
||||
.id(leaseShop.getId())
|
||||
.name(leaseShop.getName())
|
||||
.image(leaseShop.getImage())
|
||||
.feeRate(leaseShop.getFeeRate())
|
||||
.description(leaseShop.getDescription())
|
||||
.state(leaseShop.getState())
|
||||
.del(leaseShop.getDel())
|
||||
.build();
|
||||
|
||||
}
|
||||
return Result.success(build);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<ShopDto> getShopById(BaseVo baseVo) {
|
||||
LeaseShop leaseShop = leaseShopMapper.selectById(baseVo.getId());
|
||||
ShopDto build = null;
|
||||
if (leaseShop != null && !leaseShop.getDel()){
|
||||
build = ShopDto.builder()
|
||||
.id(leaseShop.getId())
|
||||
.name(leaseShop.getName())
|
||||
.image(leaseShop.getImage())
|
||||
.description(leaseShop.getDescription())
|
||||
.state(leaseShop.getState())
|
||||
.feeRate(leaseShop.getFeeRate())
|
||||
.del(leaseShop.getDel())
|
||||
.build();
|
||||
|
||||
}
|
||||
return Result.success(build);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<String> deleteShop(BaseVo baseVo) {
|
||||
LeaseShop byId = getById(baseVo.getId());
|
||||
if (byId.getDel()){
|
||||
return Result.fail("删除店铺失败,店铺已删除,请刷新页面");
|
||||
}
|
||||
updateMachineInfoV1(baseVo.getId());
|
||||
updateMachineInfoV2(baseVo.getId());
|
||||
boolean b = updateById(LeaseShop.builder().id(baseVo.getId()).del(true).build());
|
||||
if (b){
|
||||
return Result.success("删除成功");
|
||||
}
|
||||
return Result.fail("删除失败");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除店铺时,将店铺下所有矿机和对应钱包删除 V1版本
|
||||
*
|
||||
* */
|
||||
public void updateMachineInfoV1(Long shopId){
|
||||
//校验是否存在已售出的矿机
|
||||
if (leaseProductMachineMapper.checkHasSaleMachineByShopId(shopId) >= 1){
|
||||
throw new MachineException("注销失败,店铺存在租约中矿机");
|
||||
}
|
||||
leaseProductMapper.update(LeaseProduct.builder().del(true).build(), new LambdaUpdateWrapper<LeaseProduct>()
|
||||
.eq(LeaseProduct::getShopId, shopId));
|
||||
leaseProductMachineMapper.update(LeaseProductMachine.builder().del(true).build(), new LambdaUpdateWrapper<LeaseProductMachine>()
|
||||
.eq(LeaseProductMachine::getShopId, shopId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除店铺时,将店铺下所有矿机和对应钱包删除 V2版本
|
||||
*
|
||||
* */
|
||||
public void updateMachineInfoV2(Long shopId){
|
||||
//校验是否存在已售出的矿机
|
||||
if (leaseMachineMapper.checkHasSaleMachineByShopId(shopId) >= 1){
|
||||
throw new MachineException("注销失败,店铺存在租约中矿机");
|
||||
}
|
||||
//校验是否存在余额不为0的钱包
|
||||
List<LeaseShopConfig> leaseShopConfigs = leaseShopConfigMapper.selectList(new LambdaQueryWrapper<LeaseShopConfig>()
|
||||
.select(LeaseShopConfig::getId,LeaseShopConfig::getBalance)
|
||||
.eq(LeaseShopConfig::getShopId, shopId).eq(LeaseShopConfig::getDel, false));
|
||||
if (leaseShopConfigs.stream().anyMatch(leaseShopConfig -> leaseShopConfig.getBalance().compareTo(BigDecimal.ZERO) > 0)){
|
||||
throw new MachineException("注销失败,店铺存在余额不为0的钱包");
|
||||
}
|
||||
leaseMachineMapper.update(LeaseMachine.builder().del(true).build(), new LambdaUpdateWrapper<LeaseMachine>()
|
||||
.eq(LeaseMachine::getShopId, shopId));
|
||||
|
||||
List<Long> ids = leaseMachineMapper.selectList(new LambdaQueryWrapper<LeaseMachine>()
|
||||
.select(LeaseMachine::getId)
|
||||
.eq(LeaseMachine::getShopId, shopId))
|
||||
.stream().map(LeaseMachine::getId)
|
||||
.collect(Collectors.toList());
|
||||
if (!ids.isEmpty()){
|
||||
leaseMachineConfigMapper.delete(new LambdaQueryWrapper<LeaseMachineConfig>().in(LeaseMachineConfig::getMachineId, ids));
|
||||
}
|
||||
leaseShopConfigMapper.update(LeaseShopConfig.builder().del(true).build(), new LambdaUpdateWrapper<LeaseShopConfig>()
|
||||
.eq(LeaseShopConfig::getShopId, shopId));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Result<List<ShopNameDto>> getProductListById(BaseVo baseVo) {
|
||||
List<LeaseProduct> leaseProducts = leaseProductMapper.selectList(new LambdaQueryWrapper<LeaseProduct>().eq(LeaseProduct::getShopId, baseVo.getId()).eq(LeaseProduct::getDel, false));
|
||||
List<ShopNameDto> collect = leaseProducts.stream().map(leaseProduct ->
|
||||
ShopNameDto.builder()
|
||||
.id(leaseProduct.getId())
|
||||
.name(leaseProduct.getName()).build()
|
||||
).collect(Collectors.toList());
|
||||
return Result.success(collect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<ShopConfigDto>> getShopConfig(BaseVo baseVo) {
|
||||
List<LeaseShopConfig> leaseShopConfigs = leaseShopConfigMapper.selectList(new LambdaQueryWrapper<LeaseShopConfig>()
|
||||
.eq(LeaseShopConfig::getShopId, baseVo.getId())
|
||||
.eq(LeaseShopConfig::getDel, false));
|
||||
if (leaseShopConfigs.isEmpty()){
|
||||
//店铺还未设置钱包
|
||||
return Result.success(null);
|
||||
}
|
||||
Map<String, List<LeaseShopConfig>> collect = leaseShopConfigs.stream().collect(Collectors.groupingBy(LeaseShopConfig::getChain));
|
||||
List<ShopConfigDto> shopConfigDtos = new ArrayList<>();
|
||||
collect.forEach((chain, list) -> {
|
||||
LeaseShopConfig leaseShopConfig = list.get(0);
|
||||
|
||||
List<ShopConfigDto.CoinDto> coinDtoList = list.stream().map(shopConfig -> {
|
||||
ShopConfigDto.CoinDto coinDto = new ShopConfigDto.CoinDto();
|
||||
coinDto.setPayCoin(shopConfig.getPayCoin());
|
||||
coinDto.setImage(shopConfig.getPayCoinImage());
|
||||
return coinDto;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
ShopConfigDto build = ShopConfigDto.builder()
|
||||
.shopId(leaseShopConfig.getShopId())
|
||||
.chain(leaseShopConfig.getChain())
|
||||
.payType(leaseShopConfig.getPayType())
|
||||
.payAddress(leaseShopConfig.getPayAddress())
|
||||
.children(coinDtoList)
|
||||
.build();
|
||||
build.setId(leaseShopConfig.getId());
|
||||
shopConfigDtos.add( build);
|
||||
|
||||
});
|
||||
|
||||
return Result.success(shopConfigDtos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Result<String> addShopConfig(ShopConfigVo shopConfigVo) {
|
||||
if (checkSystemctlAddress(shopConfigVo.getPayAddress(), shopConfigVo.getChain())){
|
||||
return Result.fail("收款钱包不能使用系统钱包");
|
||||
}
|
||||
//钱包地址校验
|
||||
if (!WalletRuleCheckUtils.checkAddress(shopConfigVo.getChain(),shopConfigVo.getPayAddress())){
|
||||
return Result.fail("钱包地址格式错误");
|
||||
}
|
||||
LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper<LeaseShop>()
|
||||
.eq(LeaseShop::getUserEmail, SecurityUtils.getUsername()));
|
||||
|
||||
List<String> payCoinsList = new ArrayList<>(Arrays.asList(shopConfigVo.getPayCoin().split(",")));
|
||||
|
||||
LeaseShopConfig configList = leaseShopConfigMapper.selectOne(new LambdaQueryWrapper<LeaseShopConfig>()
|
||||
.eq(LeaseShopConfig::getPayAddress, shopConfigVo.getPayAddress())
|
||||
.eq(LeaseShopConfig::getPayCoin, shopConfigVo.getPayCoin())
|
||||
.eq(LeaseShopConfig::getChain, shopConfigVo.getChain())
|
||||
.eq(LeaseShopConfig::getDel, false)
|
||||
);
|
||||
if (configList != null){
|
||||
return Result.fail("绑定"+shopConfigVo.getPayAddress()+"钱包失败!" + shopConfigVo.getChain()+"链"+ shopConfigVo.getPayCoin()+ "币种钱包,已被绑定");
|
||||
}
|
||||
|
||||
//获取币种图标
|
||||
List<LeaseShopConfig> shopConfigList = leaseShopConfigMapper.getCoinIconByChainAndCoin(shopConfigVo.getChain(), payCoinsList);
|
||||
|
||||
String payAddress = shopConfigVo.getPayAddress();
|
||||
String qrCode = QrCodeUtils.creatRrCode(payAddress, 200, 200);
|
||||
for (LeaseShopConfig leaseShopConfig : shopConfigList) {
|
||||
leaseShopConfig.setShopId(leaseShop.getId());
|
||||
leaseShopConfig.setPayType(shopConfigVo.getPayType());
|
||||
leaseShopConfig.setChain(shopConfigVo.getChain());
|
||||
leaseShopConfig.setPayAddress(payAddress);
|
||||
leaseShopConfig.setQrcode(qrCode);
|
||||
}
|
||||
boolean b = leaseShopConfigService.saveBatch(shopConfigList);
|
||||
if (b){
|
||||
return Result.success("添加成功");
|
||||
}
|
||||
return Result.fail("添加失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<String> updateShopConfig(ShopConfigVo shopConfigVo) {
|
||||
if (checkSystemctlAddress(shopConfigVo.getPayAddress(), shopConfigVo.getChain())){
|
||||
return Result.fail("收款钱包不能使用系统钱包");
|
||||
}
|
||||
if ( !WalletRuleCheckUtils.checkAddress(shopConfigVo.getChain(),shopConfigVo.getPayAddress())){
|
||||
return Result.fail("提现地址格式不符合"+shopConfigVo.getChain()+"节点");
|
||||
}
|
||||
LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper<LeaseShop>().eq(LeaseShop::getUserEmail, SecurityUtils.getUsername()));
|
||||
List<String> payCoinsList = new ArrayList<>(Arrays.asList(shopConfigVo.getPayCoin().split(",")));
|
||||
String payAddress = shopConfigVo.getPayAddress();
|
||||
String qrCode = QrCodeUtils.creatRrCode(payAddress, 200, 200);
|
||||
List<LeaseShopConfig> configList = leaseShopConfigMapper.selectList(new LambdaQueryWrapper<LeaseShopConfig>()
|
||||
.eq(LeaseShopConfig::getShopId, leaseShop.getId())
|
||||
.eq(LeaseShopConfig::getChain, shopConfigVo.getChain())
|
||||
.eq(LeaseShopConfig::getDel, false)
|
||||
);
|
||||
//比较已绑定币种 和 本次修改币种的差异
|
||||
List<LeaseShopConfig> insertOrUpdateList = new ArrayList<>();
|
||||
List<LeaseShopConfig> deleteList = new ArrayList<>();
|
||||
|
||||
for (LeaseShopConfig leaseShopConfig : configList) {
|
||||
if(!payCoinsList.contains(leaseShopConfig.getPayCoin())){
|
||||
leaseShopConfig.setDel( true);
|
||||
deleteList.add(leaseShopConfig);
|
||||
}else if (shopConfigVo.getPayAddress().equalsIgnoreCase(leaseShopConfig.getPayAddress())){
|
||||
insertOrUpdateList.add(LeaseShopConfig.builder()
|
||||
.id(leaseShopConfig.getId())
|
||||
.shopId(leaseShop.getId())
|
||||
.payType(shopConfigVo.getPayType())
|
||||
.chain(shopConfigVo.getChain())
|
||||
.qrcode(qrCode)
|
||||
.payCoin(leaseShopConfig.getPayCoin())
|
||||
.payAddress(payAddress)
|
||||
.build());
|
||||
}else{
|
||||
//如果修改了地址 那么就是新增一个 旧的删除
|
||||
insertOrUpdateList.add(LeaseShopConfig.builder()
|
||||
.shopId(leaseShop.getId())
|
||||
.payType(shopConfigVo.getPayType())
|
||||
.chain(shopConfigVo.getChain())
|
||||
.qrcode(qrCode)
|
||||
.payCoin(leaseShopConfig.getPayCoin())
|
||||
.payAddress(payAddress)
|
||||
.build());
|
||||
leaseShopConfig.setDel( true);
|
||||
deleteList.add(leaseShopConfig);
|
||||
}
|
||||
}
|
||||
List<String> alreadyExistCoinList = configList.stream().map(LeaseShopConfig::getPayCoin).collect(Collectors.toList());
|
||||
for (String coin : payCoinsList) {
|
||||
//不存在新增
|
||||
if (!alreadyExistCoinList.contains(coin)){
|
||||
insertOrUpdateList.add(LeaseShopConfig.builder()
|
||||
.shopId(leaseShop.getId())
|
||||
.payCoin(coin)
|
||||
.payType(shopConfigVo.getPayType())
|
||||
.chain(shopConfigVo.getChain())
|
||||
.qrcode(qrCode)
|
||||
.payAddress(payAddress)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
if (!deleteList.isEmpty()){
|
||||
boolean delete = leaseShopConfigService.updateBatchById(deleteList);
|
||||
}
|
||||
List<String> coinList = insertOrUpdateList.stream().map(LeaseShopConfig::getPayCoin).collect(Collectors.toList());
|
||||
//获取币种对应的图片
|
||||
List<LeaseShopConfig> coinIconByChainAndCoin = leaseShopConfigMapper.getCoinIconByChainAndCoin(shopConfigVo.getChain(), coinList);
|
||||
|
||||
for (LeaseShopConfig leaseShopConfig : insertOrUpdateList) {
|
||||
for (LeaseShopConfig configImage : coinIconByChainAndCoin) {
|
||||
if (leaseShopConfig.getPayCoin().equals(configImage.getPayCoin())){
|
||||
leaseShopConfig.setPayCoinImage(configImage.getPayCoinImage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
boolean save = leaseShopConfigService.saveOrUpdateBatch(insertOrUpdateList);
|
||||
if (save){
|
||||
return Result.success("修改成功");
|
||||
}
|
||||
return Result.fail("修改失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验卖家收款钱包是否为本系统钱包
|
||||
* @param address
|
||||
* @param chain
|
||||
* @return
|
||||
*/
|
||||
public boolean checkSystemctlAddress(String address, String chain){
|
||||
LeaseAutoAddress leaseAutoAddress = leaseAutoAddressMapper.selectOne(new LambdaQueryWrapper<LeaseAutoAddress>()
|
||||
.eq(LeaseAutoAddress::getAddress, address)
|
||||
.eq(LeaseAutoAddress::getFromChain, chain));
|
||||
if (leaseAutoAddress != null){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<String> deleteShopConfig(BaseVo baseVo) {
|
||||
//1.根据id找到要删除的钱包配置
|
||||
LeaseShopConfig config = leaseShopConfigMapper.selectById(baseVo.getId());
|
||||
if (config.getBalance().compareTo(BigDecimal.ZERO) > 0){
|
||||
return Result.fail("删除失败,钱包余额不为0");
|
||||
}
|
||||
|
||||
//2.校验当前用户还有几个卖家钱包
|
||||
Long configNums = leaseShopConfigMapper.selectCount(new LambdaQueryWrapper<LeaseShopConfig>()
|
||||
.eq(LeaseShopConfig::getShopId, config.getShopId()).eq(LeaseShopConfig::getDel, false));
|
||||
|
||||
//3.获取当前用户店铺是否存在商品
|
||||
//List<Long> ids = leaseProductMachineMapper.getIdsForShopId(config.getShopId());
|
||||
//Long productNums = leaseProductMapper.selectCount(new LambdaQueryWrapper<LeaseProduct>()
|
||||
// .eq(LeaseProduct::getShopId, config.getShopId())
|
||||
// .eq(LeaseProduct::getDel, false));
|
||||
List<LeaseMachine> leaseMachines = leaseMachineMapper.selectList(new LambdaQueryWrapper<LeaseMachine>()
|
||||
.eq(LeaseMachine::getShopId, config.getShopId())
|
||||
.eq(LeaseMachine::getDel, false)
|
||||
);
|
||||
List<Long> ids = leaseMachines.stream().map(LeaseMachine::getId).collect(Collectors.toList());
|
||||
// 拥有的钱包数小于等于1 且 商品数不为0 不能删除
|
||||
if (configNums <= 1 && !leaseMachines.isEmpty()){
|
||||
return Result.fail("删除失败,店铺若存在商品,至少需要一个收款钱包");
|
||||
}
|
||||
//4.查询店铺中是否存在要删除链的钱包 的订单,存在订单不能删除
|
||||
Long l = leaseOrderItemMapper.selectCount(new LambdaQueryWrapper<LeaseOrderItem>()
|
||||
.eq(LeaseOrderItem::getChain, config.getChain())
|
||||
.ne(LeaseOrderItem::getStatus, 0)
|
||||
);
|
||||
if (l > 0){
|
||||
return Result.fail("删除钱包失败,该钱包存在交易中的订单");
|
||||
}
|
||||
config.setDel(true);
|
||||
//5.删除配置
|
||||
boolean b = leaseShopConfigService.updateById(config);
|
||||
if (b ){
|
||||
//6.删除所有矿机对应的价格配置
|
||||
if (!ids.isEmpty()){
|
||||
leaseMachinePriceMapper.update(LeaseMachinePrice.builder().del(true).build(),
|
||||
new LambdaQueryWrapper<LeaseMachinePrice>()
|
||||
.eq(LeaseMachinePrice::getChain, config.getChain())
|
||||
.in(LeaseMachinePrice::getMachineId,ids)
|
||||
);
|
||||
}
|
||||
return Result.success("删除成功");
|
||||
}
|
||||
return Result.fail("删除失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<ChainListDto>> getChainAndList() {
|
||||
//LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper<LeaseShop>().eq(LeaseShop::getUserEmail, SecurityUtils.getUsername())
|
||||
// .eq(LeaseShop::getDel, false));
|
||||
//获取本系统支持的所有链和币种
|
||||
List<CoinFullDto> chainAndList = leaseShopConfigMapper.getChainAndList(null);
|
||||
//获取卖家已绑定的币种
|
||||
//List<LeaseShopConfig> leaseShopConfigs = leaseShopConfigMapper.selectList(new LambdaQueryWrapper<LeaseShopConfig>()
|
||||
// .eq(LeaseShopConfig::getShopId, leaseShop.getId())
|
||||
//);
|
||||
//for (CoinFullDto coinFullDto : chainAndList) {
|
||||
// for (LeaseShopConfig leaseShopConfig : leaseShopConfigs) {
|
||||
// if (coinFullDto.getChainValue().equals(leaseShopConfig.getChain()) && coinFullDto.getCoinValue().equals(leaseShopConfig.getPayCoin())){
|
||||
// coinFullDto.setHasBind(1);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
return Result.success(buildChainList(chainAndList));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Result<List<ChainListDto>> getChainAndListForSeller(BaseVo baseVo) {
|
||||
//LeaseShop leaseShop = leaseShopMapper.selectById(baseVo.getId());
|
||||
if (baseVo.getId() == null){
|
||||
return Result.fail("未检测到该店铺");
|
||||
}
|
||||
List<CoinFullDto> chainAndListForSeller = leaseShopConfigMapper.getChainAndListForSeller(baseVo.getId());
|
||||
return Result.success(buildChainList(chainAndListForSeller));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Result<ChainListDto> getChainAndCoin(BaseVo baseVo) {
|
||||
LeaseShopConfig config = leaseShopConfigMapper.selectOne(new LambdaQueryWrapper<LeaseShopConfig>().eq(LeaseShopConfig::getId, baseVo.getId()));
|
||||
if (config == null){
|
||||
return Result.fail("未检测到该币种");
|
||||
}
|
||||
//商家链已绑定的币种
|
||||
List<LeaseShopConfig> leaseShopConfigs = leaseShopConfigMapper.selectList(new LambdaQueryWrapper<LeaseShopConfig>()
|
||||
.eq(LeaseShopConfig::getChain, config.getChain())
|
||||
.eq(LeaseShopConfig::getShopId, config.getShopId())
|
||||
);
|
||||
//获取本系统该链支持的所有币种
|
||||
List<CoinFullDto> chainAndList = leaseShopConfigMapper.getChainAndList(config.getChain());
|
||||
for (CoinFullDto coinFullDto : chainAndList) {
|
||||
for (LeaseShopConfig leaseShopConfig : leaseShopConfigs) {
|
||||
if (coinFullDto.getChainValue().equals(leaseShopConfig.getChain()) && coinFullDto.getCoinValue().equals(leaseShopConfig.getPayCoin())){
|
||||
coinFullDto.setHasBind(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
ChainListDto chainListDto = buildChainList(chainAndList).get(0);
|
||||
chainListDto.setAddress(config.getPayAddress());
|
||||
return Result.success(chainListDto);
|
||||
}
|
||||
|
||||
private List<ChainListDto> buildChainList(List<CoinFullDto> chainAndList){
|
||||
Map<String, List<CoinFullDto>> chainGroup = chainAndList.stream()
|
||||
.collect(Collectors.groupingBy(CoinFullDto::getChainValue));
|
||||
|
||||
List<ChainListDto> result = new ArrayList<>();
|
||||
for (Map.Entry<String, List<CoinFullDto>> entry : chainGroup.entrySet()) {
|
||||
String chainValue = entry.getKey();
|
||||
List<CoinFullDto> group = entry.getValue();
|
||||
// 取第一个元素获取链标签
|
||||
String chainLabel = group.get(0).getChainLabel();
|
||||
|
||||
List<ChainListDto.CoinListDto> coinList = group.stream()
|
||||
.map(coinFullDto -> {
|
||||
ChainListDto.CoinListDto coinDto = new ChainListDto.CoinListDto();
|
||||
coinDto.setValue(coinFullDto.getCoinValue());
|
||||
coinDto.setLabel(coinFullDto.getCoinLabel());
|
||||
coinDto.setHasBind(coinFullDto.getHasBind());
|
||||
return coinDto;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
ChainListDto chainListDto = ChainListDto.builder()
|
||||
.value(chainValue)
|
||||
.label(chainLabel)
|
||||
.children(coinList)
|
||||
.build();
|
||||
result.add(chainListDto);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<ShopWalletInfoDto>> getShopConfigV2(BaseVo baseVo) {
|
||||
List<ShopWalletInfoDto> 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<String> withdrawBalanceForSeller(BalanceVo balanceVo) {
|
||||
String username = SecurityUtils.getUsername();
|
||||
Long authId = SecurityUtils.getUserId();
|
||||
//校验地址
|
||||
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<LeaseShop>()
|
||||
.select(LeaseShop::getId).eq(LeaseShop::getUserEmail, username).eq(LeaseShop::getDel, false));
|
||||
ShopWalletInfoDto shopWalletInfo = leaseShopConfigMapper.getShopWalletInfo(leaseShop.getId(), balanceVo.getFromAddress(), balanceVo.getToChain(), balanceVo.getToSymbol());
|
||||
if (shopWalletInfo == null || StringUtils.isEmpty(shopWalletInfo.getPayAddress())){
|
||||
return Result.fail("提现地址不属于您,请登录正确的账号");
|
||||
}
|
||||
GoogleInfo googleInfo = leaseUserMapper.getGoogleInfoByEmail(username);
|
||||
//开发环境
|
||||
//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())
|
||||
.authId(authId)
|
||||
.build());
|
||||
LeaseShopConfig build = LeaseShopConfig.builder()
|
||||
.id(shopWalletInfo.getId())
|
||||
.balance(shopWalletInfo.getBalance())
|
||||
.build();
|
||||
int update = leaseShopConfigMapper.update(build,new LambdaUpdateWrapper<LeaseShopConfig>()
|
||||
.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))
|
||||
.user_email(username+"--"+authId)
|
||||
.build();
|
||||
try {
|
||||
//发送提现消息
|
||||
rabbitTemplate.convertAndSend(PAY_WITHDRAW_QUEUE,message);
|
||||
OperationLogAspect.addExtraLogParam("手续费", serviceCharge.toString());
|
||||
OperationLogAspect.addExtraLogParam("消息ID", queueId);
|
||||
return Result.success("提现申请成功");
|
||||
} catch (Exception e) {
|
||||
throw new PaymentException("提现失败,失败原因"+e.getMessage());
|
||||
}
|
||||
}
|
||||
throw new PaymentException("提现失败,余额已变化,请重新提现!");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<String> updateShopConfigV2(ShopWalletInfoVo shopWalletInfoVo) {
|
||||
|
||||
String username = SecurityUtils.getUsername();
|
||||
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,请先提现,否则会造成财产丢失");
|
||||
}
|
||||
|
||||
//谷歌验证
|
||||
GoogleInfo googleInfo = leaseUserMapper.getGoogleInfoByEmail(username);
|
||||
//开发环境
|
||||
//if(googleInfo == null || StringUtils.isBlank(googleInfo.getSecret())){
|
||||
// //未绑定定谷歌验证器
|
||||
// return Result.fail("您的账号未开启双重验证,请先开启验证!");
|
||||
//}
|
||||
//if(!GoogleAuthenticator.checkCode(googleInfo.getSecret(), balanceVo.getCode(), System.currentTimeMillis())){
|
||||
// return Result.fail("谷歌验证码错误");
|
||||
//}
|
||||
|
||||
LeaseShopConfig leaseShopConfig = leaseShopConfigMapper.selectOne(new LambdaQueryWrapper<LeaseShopConfig>()
|
||||
.eq(LeaseShopConfig::getPayAddress, shopWalletInfoVo.getPayAddress())
|
||||
.eq(LeaseShopConfig::getChain, shopWalletInfoVo.getChain())
|
||||
.eq(LeaseShopConfig::getPayCoin, byId.getPayCoin())
|
||||
.eq(LeaseShopConfig::getDel, false)
|
||||
);
|
||||
if (leaseShopConfig != null){
|
||||
return Result.fail("修改失败,该钱包地址下链和币种已被绑定,请重新输入地址或先解绑后重新绑定");
|
||||
}
|
||||
boolean b = leaseShopConfigService.updateById(LeaseShopConfig.builder()
|
||||
.id(shopWalletInfoVo.getId())
|
||||
.payAddress(shopWalletInfoVo.getPayAddress())
|
||||
.build());
|
||||
if (b){
|
||||
return Result.success("修改成功");
|
||||
}
|
||||
return Result.fail("修改失败");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PageResult<PayWithdrawSellerRecordDto> balanceWithdrawList(PageVo pageVo) {
|
||||
String userEmail = SecurityUtils.getUsername();
|
||||
LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper<LeaseShop>()
|
||||
.eq(LeaseShop::getUserEmail, userEmail).eq(LeaseShop::getDel, false));
|
||||
if (leaseShop == null){
|
||||
return PageResult.success(new ArrayList<>());
|
||||
}
|
||||
PageHelper.startPage(pageVo.getPageNum(), pageVo.getPageSize());
|
||||
List<PayWithdrawSellerRecordDto> payWithdrawMessageDtoList = leasePayWithdrawMessageMapper.getSellerWithdrawRecord(leaseShop.getId());
|
||||
PageInfo<PayWithdrawSellerRecordDto> pageInfo = new PageInfo<>(payWithdrawMessageDtoList);
|
||||
PageResult<PayWithdrawSellerRecordDto> success = PageResult.success(payWithdrawMessageDtoList);
|
||||
success.setTotal(pageInfo.getTotal());
|
||||
success.setTotalPage(pageInfo.getPages());
|
||||
PageHelper.clearPage();
|
||||
return success;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,542 @@
|
||||
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.lease.constant.BlockInterval;
|
||||
import com.m2pool.lease.constant.CoinCharge;
|
||||
import com.m2pool.lease.redis.RedisCoinInfoKey;
|
||||
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.redis.service.RedisService;
|
||||
import com.m2pool.lease.service.LeaseShoppingCartInfoService;
|
||||
import com.m2pool.lease.service.LeaseShoppingCartService;
|
||||
import com.m2pool.lease.utils.PowerUnitUtils;
|
||||
import com.m2pool.lease.utils.SecurityUtils;
|
||||
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.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 购物车表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
@Service
|
||||
public class LeaseShoppingCartServiceImpl extends ServiceImpl<LeaseShoppingCartMapper, LeaseShoppingCart> implements LeaseShoppingCartService {
|
||||
|
||||
|
||||
@Resource
|
||||
private LeaseShoppingCartInfoMapper leaseShoppingCartInfoMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseShoppingCartInfoService leaseShoppingCartInfoService;
|
||||
|
||||
@Resource
|
||||
private LeaseProductMachineMapper leaseProductMachineMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseShopMapper leaseShopMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseProductMachinePriceMapper leaseProductMachinePriceMapper;
|
||||
|
||||
@Resource
|
||||
private RedisService redisService;
|
||||
|
||||
@Resource
|
||||
private LeaseMachineMapper leaseMachineMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseMachinePriceMapper leaseMachinePriceMapper;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<String> addGoods(List<ShoppingCartInfoURDVo> shoppingCartInfoURDVoList) {
|
||||
String userId = SecurityUtils.getUsername();
|
||||
if (shoppingCartInfoURDVoList.isEmpty()) {
|
||||
return Result.fail("请选择商品");
|
||||
}
|
||||
|
||||
List<Long> machineIds = shoppingCartInfoURDVoList.stream().map(ShoppingCartInfoURDVo::getProductMachineId).collect(Collectors.toList());
|
||||
List<LeaseProductMachine> leaseProductMachines = leaseProductMachineMapper.selectList(new LambdaQueryWrapper<LeaseProductMachine>()
|
||||
.select(LeaseProductMachine::getId, LeaseProductMachine::getShopId)
|
||||
.in(LeaseProductMachine::getId, machineIds));
|
||||
Map<Long, Long> collect = leaseProductMachines.stream().collect(Collectors.toMap(LeaseProductMachine::getId, LeaseProductMachine::getShopId));
|
||||
//获取用户购物车中所有矿机
|
||||
List<LeaseShoppingCartInfo> leaseShoppingCartInfos = leaseShoppingCartInfoMapper
|
||||
.selectList(new LambdaQueryWrapper<LeaseShoppingCartInfo>()
|
||||
.eq(LeaseShoppingCartInfo::getUserId, userId));
|
||||
|
||||
// 存储需要新增的记录
|
||||
List<LeaseShoppingCartInfo> newRecords = shoppingCartInfoURDVoList.stream()
|
||||
.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())
|
||||
.productId(shoppingCartInfoURDVo.getProductId())
|
||||
.productMachineId(shoppingCartInfoURDVo.getProductMachineId())
|
||||
.build()
|
||||
).collect(Collectors.toList());
|
||||
|
||||
// 存储需要更新的记录
|
||||
Map<Long, ShoppingCartInfoURDVo> voMap = shoppingCartInfoURDVoList.stream()
|
||||
.collect(Collectors.toMap(ShoppingCartInfoURDVo::getProductMachineId, vo -> vo));
|
||||
List<LeaseShoppingCartInfo> updateList = leaseShoppingCartInfos.stream()
|
||||
.peek(info -> {
|
||||
ShoppingCartInfoURDVo vo = voMap.get(info.getProductMachineId());
|
||||
if (vo != null) {
|
||||
info.setLeaseTime(info.getLeaseTime() + vo.getLeaseTime());
|
||||
info.setId(info.getId());
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 执行更新操作
|
||||
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<ShopCartDto> getGoodsList(PageVo pageVo) {
|
||||
String userId = SecurityUtils.getUsername();
|
||||
//检查购物车中是否存在商品
|
||||
List<ShoppingCartInfoDto> cartInfoList = leaseShoppingCartInfoMapper.getProductAndMachineIds(userId,0);
|
||||
if (cartInfoList.isEmpty()){
|
||||
return PageResult.success(new ArrayList<>());
|
||||
}
|
||||
List<Long> machineIds = new ArrayList<>();
|
||||
Map<Long, Integer> machineMap = new HashMap<>();
|
||||
for (ShoppingCartInfoDto shoppingCartInfoDto : cartInfoList) {
|
||||
machineIds.add(shoppingCartInfoDto.getProductMachineId());
|
||||
machineMap.put(shoppingCartInfoDto.getProductMachineId(), shoppingCartInfoDto.getLeaseTime());
|
||||
}
|
||||
List<Long> shopIds = leaseShopMapper.getShopIdsByMachineIds(machineIds);
|
||||
PageHelper.startPage(pageVo.getPageNum(), pageVo.getPageSize());
|
||||
//查询购物车中店铺信息(一层)
|
||||
List<LeaseShop> leaseShops = leaseShopMapper.selectList(new LambdaQueryWrapper<LeaseShop>().in(LeaseShop::getId, shopIds));
|
||||
//获取商品售价
|
||||
List<MachinePayTypeDto> machinePriceByMachineIds = leaseProductMachinePriceMapper.getMachinePriceByMachineIds(machineIds);
|
||||
Map<Long, List<MachinePayTypeDto>> machinePriceMap = machinePriceByMachineIds.stream().collect(Collectors.groupingBy(MachinePayTypeDto::getProductMachineId));
|
||||
//查询商品中机器详情 + 按照币种分组 (二层)
|
||||
List<ProductMachineDto> leaseProductMachines = leaseProductMachineMapper.getMachinesByIds(machineIds);
|
||||
//获取实时币价
|
||||
List<String> coins = leaseProductMachines.stream().map(ProductMachineDto::getCoin).distinct().collect(Collectors.toList());
|
||||
Map<String, BigDecimal> coinPriceMap = new HashMap<>();
|
||||
Map<String, BigDecimal> coinRewardMap = new HashMap<>();
|
||||
Map<String, BigDecimal> coinMhsMap = new HashMap<>();
|
||||
for (String coin : coins) {
|
||||
BigDecimal price = redisService.getCacheBigDecimal(RedisCoinInfoKey.getPiceKey(coin));
|
||||
BigDecimal reward =redisService.getCacheBigDecimal(RedisCoinInfoKey.getRewardKey(coin));
|
||||
BigDecimal mhs = redisService.getCacheBigDecimal(RedisCoinInfoKey.getMhsKey(coin));
|
||||
coinMhsMap.put(coin, mhs);
|
||||
coinRewardMap.put(coin, reward);
|
||||
coinPriceMap.put(coin, price);
|
||||
}
|
||||
//按币种查询每个矿机的最近一次30分钟的实时算力(后续修改为24小时平均算力)
|
||||
List<ProductMachineDto> userMinerPowerList = new ArrayList<>();
|
||||
Map<String, List<LeaseProductMachine>> userAndMinerList = leaseProductMachines.stream().map(
|
||||
ProductMachineDto ->
|
||||
LeaseProductMachine.builder()
|
||||
.user(ProductMachineDto.getUser())
|
||||
.miner(ProductMachineDto.getMiner())
|
||||
.coin(ProductMachineDto.getCoin())
|
||||
.build()
|
||||
).collect(Collectors.groupingBy(LeaseProductMachine::getCoin));
|
||||
|
||||
userAndMinerList.forEach((coin, userMinerDtos) -> {
|
||||
List<ProductMachineDto> recentlyFiveMinutesData = leaseProductMachineMapper.getRecentlyFiveMinutesData(userMinerDtos, coin);
|
||||
List<ProductMachineDto> collect = recentlyFiveMinutesData.stream().peek(dto -> {
|
||||
dto.setCoin(coin);
|
||||
}).collect(Collectors.toList());
|
||||
userMinerPowerList.addAll(collect);
|
||||
});
|
||||
|
||||
Map<String, ProductMachineDto> realPowerList = userMinerPowerList.stream()
|
||||
.collect(Collectors.toMap(
|
||||
dto -> dto.getUser() + "-" + dto.getMiner() + "-" + dto.getCoin(),
|
||||
dto -> dto
|
||||
));
|
||||
//为每个矿机设置实时的算力 + 按店铺分组
|
||||
Map<Long, List<ProductMachineDto>> shopIdAndMachineInfoMap = leaseProductMachines.stream().peek(productMachineDto -> {
|
||||
ProductMachineDto userMinerPowerDto = realPowerList.get(productMachineDto.getUser() + "-" + productMachineDto.getMiner() + "-" + productMachineDto.getCoin());
|
||||
List<MachinePayTypeDto> machinePayTypeDtoList = machinePriceMap.get(productMachineDto.getId());
|
||||
productMachineDto.setPriceList(machinePayTypeDtoList);
|
||||
//理论收益
|
||||
BigDecimal singleTheoryMachineIncome;
|
||||
BigDecimal computingPower;
|
||||
BigDecimal singleTheoryUSDTMachineIncome;
|
||||
if (userMinerPowerDto != null) {
|
||||
// 矿机算力单位转换 + 计算单矿机平均算力(ComputingPower coin_mhs30m 平均算力)
|
||||
computingPower = PowerUnitUtils.getPower(productMachineDto.getUnit(),
|
||||
userMinerPowerDto.getComputingPower()
|
||||
.multiply(BigDecimal.valueOf(1000 * 1000))
|
||||
.divide(BigDecimal.valueOf(24 * 60 * 60 ), 2, RoundingMode.HALF_UP));
|
||||
BigDecimal mhs = coinMhsMap.get(productMachineDto.getCoin());
|
||||
BigDecimal reward = coinRewardMap.get(productMachineDto.getCoin());
|
||||
BigDecimal price = coinPriceMap.get(productMachineDto.getCoin());
|
||||
if (mhs == null || reward == null || price == null){
|
||||
singleTheoryMachineIncome = productMachineDto.getTheoryIncome();
|
||||
singleTheoryUSDTMachineIncome = singleTheoryMachineIncome.multiply(price);
|
||||
}else{
|
||||
//全网算力单位转换
|
||||
BigDecimal power = PowerUnitUtils.getPower(productMachineDto.getUnit(),mhs).multiply(BigDecimal.valueOf(1000 * 1000));
|
||||
//(理论收益 = 矿机算力/全网算力 * 24h /出块间隔秒数 * 单块奖励(redis中nexa:reward))
|
||||
singleTheoryMachineIncome = computingPower.divide( power,6, RoundingMode.HALF_UP)
|
||||
.multiply(BigDecimal.valueOf(24 * 60 * 60)
|
||||
.divide(BlockInterval.getBlockCountByCoinName(productMachineDto.getCoin()), 6, RoundingMode.HALF_UP)).multiply(reward);
|
||||
singleTheoryUSDTMachineIncome = singleTheoryMachineIncome.multiply(price);
|
||||
}
|
||||
//单位为MH/s 需要转换成 矿机设定的单位
|
||||
productMachineDto.setComputingPower(computingPower);
|
||||
productMachineDto.setTheoryIncome(singleTheoryMachineIncome);
|
||||
productMachineDto.setTheoryUsdtIncome(singleTheoryUSDTMachineIncome);
|
||||
}
|
||||
}).collect(Collectors.groupingBy(ProductMachineDto::getShopId));
|
||||
|
||||
//获取商铺钱包配置信息
|
||||
List<PayConfigDto> shopWalletInfo = leaseShopMapper.getShopWalletInfoList(shopIds);
|
||||
|
||||
Map<Long, List<PayConfigDto>> 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<ShopCartDto> shopCartList = leaseShops.stream().map(leaseShop -> {
|
||||
List<ProductMachineDto> productMachineList = shopIdAndMachineInfoMap.get(leaseShop.getId());
|
||||
return ShopCartDto.builder()
|
||||
.id(leaseShop.getId())
|
||||
.name(leaseShop.getName())
|
||||
.totalMachine(productMachineList != null ? productMachineList.size() : 0)
|
||||
.payConfigList(payConfigMap.get(leaseShop.getId()))
|
||||
.productMachineDtoList(productMachineList)
|
||||
.build();
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
|
||||
|
||||
//计算不同链和币种对应的总售价
|
||||
for (ShopCartDto shopCartDto : shopCartList) {
|
||||
//遍历每个商铺下的矿机
|
||||
List<ProductMachineDto> productMachineDtoList = shopCartDto.getProductMachineDtoList();
|
||||
Map<String, BigDecimal> totalPriceMap = new HashMap<>();
|
||||
Map<String, MachineTotalPriceDto> totalPriceDtoMap = new HashMap<>();
|
||||
for (ProductMachineDto productMachineDto : productMachineDtoList) {
|
||||
Integer leaseTime = machineMap.get(productMachineDto.getId());
|
||||
productMachineDto.setLeaseTime(leaseTime);
|
||||
List<MachinePayTypeDto> 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<ShopCartDto> pageInfo = new PageInfo<>(shopCartList);
|
||||
PageResult<ShopCartDto> success = PageResult.success(shopCartList);
|
||||
success.setTotal(pageInfo.getTotal());
|
||||
success.setTotalPage(pageInfo.getPages());
|
||||
PageHelper.clearPage();
|
||||
return success;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<String> deleteBatchGoods(List<ProductAndMachineVo> baseVoList) {
|
||||
List<LeaseShoppingCartInfo> leaseShoppingCartInfos = leaseShoppingCartInfoMapper.selectList(new LambdaQueryWrapper<LeaseShoppingCartInfo>()
|
||||
.eq(LeaseShoppingCartInfo::getUserId, SecurityUtils.getUsername())
|
||||
.eq(LeaseShoppingCartInfo::getVersion, 0));
|
||||
if (leaseShoppingCartInfos.isEmpty()){
|
||||
return Result.fail("删除购物车商品失败,购物车中不存在商品");
|
||||
}
|
||||
List<Long> ids = new ArrayList<>();
|
||||
for (LeaseShoppingCartInfo leaseShoppingCartInfo : leaseShoppingCartInfos) {
|
||||
for (ProductAndMachineVo baseVo : baseVoList){
|
||||
if (leaseShoppingCartInfo.getProductMachineId().equals(baseVo.getMachineId())){
|
||||
ids.add(leaseShoppingCartInfo.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ids.isEmpty()){
|
||||
return Result.fail("删除购物车商品失败,购物车中不存在该商品");
|
||||
}
|
||||
leaseShoppingCartInfoMapper.deleteBatchData(ids);
|
||||
return Result.success("删除购物车商品成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<String> deleteGoods(BaseVo baseVo) {
|
||||
int delete = leaseShoppingCartInfoMapper.deleteById(baseVo.getId());
|
||||
if (delete > 0){
|
||||
return Result.success("删除购物车商品成功");
|
||||
}
|
||||
return Result.fail("删除购物车商品失败");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Result<String> deleteBatchGoodsForIsDelete() {
|
||||
List<LeaseShoppingCartInfo> leaseShoppingCartInfos = leaseShoppingCartInfoMapper.selectList(new LambdaQueryWrapper<LeaseShoppingCartInfo>()
|
||||
.eq(LeaseShoppingCartInfo::getUserId, SecurityUtils.getUsername()));
|
||||
|
||||
List<Long> machineIds = leaseShoppingCartInfos.stream().map(LeaseShoppingCartInfo::getProductMachineId)
|
||||
.collect(Collectors.toList());
|
||||
List<LeaseProductMachine> leaseProductMachines = leaseProductMachineMapper.selectList(new LambdaQueryWrapper<LeaseProductMachine>()
|
||||
.in(LeaseProductMachine::getId, machineIds));
|
||||
List<Long> delMachineIds = leaseProductMachines.stream().filter(productMachine -> productMachine.getDel() || productMachine.getState() == 1)
|
||||
.map(LeaseProductMachine::getId).collect(Collectors.toList());
|
||||
|
||||
if (delMachineIds.isEmpty()){
|
||||
return Result.success("删除购物车已下架商品成功");
|
||||
}
|
||||
|
||||
int delete = leaseShoppingCartInfoMapper.delete(new LambdaUpdateWrapper<LeaseShoppingCartInfo>()
|
||||
.in(LeaseShoppingCartInfo::getProductMachineId, delMachineIds));
|
||||
if (delete > 0){
|
||||
return Result.success("删除购物车已下架商品成功");
|
||||
}
|
||||
return Result.fail("删除失败,不存在已下架商品");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<String> addGoodsV2(List<AddGoodsVo> addGoodsVoList) {
|
||||
|
||||
String userId = SecurityUtils.getUsername();
|
||||
if (addGoodsVoList.isEmpty()) {
|
||||
return Result.fail("请选择商品");
|
||||
}
|
||||
|
||||
List<Long> machineIds = addGoodsVoList.stream().map(AddGoodsVo::getId).collect(Collectors.toList());
|
||||
List<LeaseMachine> leaseProductMachines = leaseMachineMapper.selectList(new LambdaQueryWrapper<LeaseMachine>()
|
||||
.select(LeaseMachine::getId, LeaseMachine::getShopId)
|
||||
.in(LeaseMachine::getId, machineIds));
|
||||
Map<Long, Long> collect = leaseProductMachines.stream()
|
||||
.collect(Collectors.toMap(LeaseMachine::getId, LeaseMachine::getShopId));
|
||||
//获取用户购物车中所有矿机
|
||||
List<LeaseShoppingCartInfo> leaseShoppingCartInfos = leaseShoppingCartInfoMapper
|
||||
.selectList(new LambdaQueryWrapper<LeaseShoppingCartInfo>()
|
||||
.eq(LeaseShoppingCartInfo::getUserId, userId));
|
||||
|
||||
// 存储需要新增的记录
|
||||
List<LeaseShoppingCartInfo> 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<Long, AddGoodsVo> voMap = addGoodsVoList.stream()
|
||||
.collect(Collectors.toMap(AddGoodsVo::getId, vo -> vo));
|
||||
List<LeaseShoppingCartInfo> 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());
|
||||
|
||||
// 执行更新操作
|
||||
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<ShopCartV2Dto> getGoodsListV2(PageVo pageVo) {
|
||||
String userId = SecurityUtils.getUsername();
|
||||
//检查购物车中是否存在商品
|
||||
List<ShoppingCartInfoDto> cartInfoList = leaseShoppingCartInfoMapper.getProductAndMachineIds(userId,1);
|
||||
if (cartInfoList.isEmpty()){
|
||||
return PageResult.success(new ArrayList<>());
|
||||
}
|
||||
List<Long> machineIds = new ArrayList<>();
|
||||
Map<Long, Integer> machineMap = new HashMap<>();
|
||||
for (ShoppingCartInfoDto shoppingCartInfoDto : cartInfoList) {
|
||||
machineIds.add(shoppingCartInfoDto.getProductMachineId());
|
||||
machineMap.put(shoppingCartInfoDto.getProductMachineId(), shoppingCartInfoDto.getLeaseTime());
|
||||
}
|
||||
|
||||
List<Long> shopIds = leaseMachineMapper.getShopIdsByMachineIds(machineIds);
|
||||
PageHelper.startPage(pageVo.getPageNum(), pageVo.getPageSize());
|
||||
//查询购物车中店铺信息(一层)
|
||||
List<LeaseShop> leaseShops = leaseShopMapper.selectList(new LambdaQueryWrapper<LeaseShop>()
|
||||
.in(LeaseShop::getId, shopIds));
|
||||
|
||||
//获取商品售价
|
||||
List<MachinePayTypeDto> machinePriceByMachineIds = leaseMachinePriceMapper.getMachinePriceByMachineIds(machineIds);
|
||||
Map<Long, List<MachinePayTypeDto>> machinePriceMap = machinePriceByMachineIds.stream()
|
||||
.collect(Collectors.groupingBy(MachinePayTypeDto::getProductMachineId));
|
||||
|
||||
//查询店铺中机器详情
|
||||
List<CartMachineInfoDto> leaseProductMachines = leaseMachineMapper.getMachinesByIds(machineIds);
|
||||
|
||||
//设置每个矿机的售价,并按店铺分组
|
||||
Map<Long, List<CartMachineInfoDto>> shopIdAndMachineInfoMap = leaseProductMachines.stream()
|
||||
.peek(productMachineDto -> {
|
||||
productMachineDto.setPriceList(machinePriceMap.get(productMachineDto.getId()));
|
||||
})
|
||||
.collect(Collectors.groupingBy(CartMachineInfoDto::getShopId));
|
||||
//获取商铺钱包配置信息
|
||||
List<PayConfigDto> shopWalletInfo = leaseShopMapper.getShopWalletInfoList(shopIds);
|
||||
Map<Long, List<PayConfigDto>> 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<ShopCartV2Dto> shopCartList = leaseShops.stream().map(leaseShop -> {
|
||||
List<CartMachineInfoDto> 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<CartMachineInfoDto> productMachineDtoList = shopCartDto.getCartMachineInfoDtoList();
|
||||
Map<String, BigDecimal> totalPriceMap = new HashMap<>();
|
||||
Map<String, MachineTotalPriceDto> totalPriceDtoMap = new HashMap<>();
|
||||
for (CartMachineInfoDto productMachineDto : productMachineDtoList) {
|
||||
Integer leaseTime = machineMap.get(productMachineDto.getId());
|
||||
productMachineDto.setLeaseTime(leaseTime);
|
||||
List<MachinePayTypeDto> priceList = productMachineDto.getPriceList();
|
||||
for (MachinePayTypeDto machinePayTypeDto : priceList) {
|
||||
BigDecimal itemPrice = machinePayTypeDto.getPrice().multiply(new BigDecimal(leaseTime))
|
||||
.multiply(BigDecimal.valueOf(productMachineDto.getNumbers()));
|
||||
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<ShopCartV2Dto> pageInfo = new PageInfo<>(shopCartList);
|
||||
PageResult<ShopCartV2Dto> success = PageResult.success(shopCartList);
|
||||
success.setTotal(pageInfo.getTotal());
|
||||
success.setTotalPage(pageInfo.getPages());
|
||||
PageHelper.clearPage();
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<String> deleteBatchGoodsV2(List<CartInfoVo> baseVoList) {
|
||||
List<Long> ids = baseVoList.stream().map(CartInfoVo::getCartInfoId).collect(Collectors.toList());
|
||||
leaseShoppingCartInfoMapper.deleteBatchData(ids);
|
||||
return Result.success("删除购物车商品成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<String> deleteBatchGoodsForIsDeleteV2() {
|
||||
List<LeaseShoppingCartInfo> leaseShoppingCartInfos = leaseShoppingCartInfoMapper.selectList(new LambdaQueryWrapper<LeaseShoppingCartInfo>()
|
||||
.eq(LeaseShoppingCartInfo::getUserId, SecurityUtils.getUsername()));
|
||||
|
||||
List<Long> machineIds = leaseShoppingCartInfos.stream().map(LeaseShoppingCartInfo::getProductMachineId).collect(Collectors.toList());
|
||||
List<LeaseMachine> leaseMachines = leaseMachineMapper.selectList(new LambdaQueryWrapper<LeaseMachine>()
|
||||
.in(LeaseMachine::getId, machineIds));
|
||||
|
||||
List<Long> 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<LeaseShoppingCartInfo>()
|
||||
.in(LeaseShoppingCartInfo::getProductMachineId, delMachineIds));
|
||||
if (delete > 0){
|
||||
return Result.success("删除购物车已下架商品成功");
|
||||
}
|
||||
return Result.fail("删除失败,不存在已下架商品");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.m2pool.lease.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.m2pool.lease.entity.LeaseShoppingCartInfo;
|
||||
import com.m2pool.lease.mapper.LeaseShoppingCartInfoMapper;
|
||||
import com.m2pool.lease.service.LeaseShoppingCartInfoService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 购物车详情表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-24
|
||||
*/
|
||||
@Service
|
||||
public class LeaseShoppingCatInfoServiceImpl extends ServiceImpl<LeaseShoppingCartInfoMapper, LeaseShoppingCartInfo> implements LeaseShoppingCartInfoService {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
package com.m2pool.lease.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.m2pool.lease.redis.RedisCoinInfoKey;
|
||||
import com.m2pool.lease.dto.*;
|
||||
import com.m2pool.lease.entity.*;
|
||||
import com.m2pool.lease.mapper.*;
|
||||
import com.m2pool.lease.redis.service.RedisService;
|
||||
import com.m2pool.lease.service.LeaseUserOwnedProductService;
|
||||
import com.m2pool.lease.utils.SecurityUtils;
|
||||
import com.m2pool.lease.vo.BaseVo;
|
||||
import com.m2pool.lease.vo.UserOwnedProductVo;
|
||||
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.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户拥有商品详情表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author yyb
|
||||
* @since 2025-07-23
|
||||
*/
|
||||
@Service
|
||||
public class LeaseUserOwnedProductServiceImpl extends ServiceImpl<LeaseUserOwnedProductMapper, LeaseUserOwnedProduct> implements LeaseUserOwnedProductService {
|
||||
|
||||
@Resource
|
||||
private LeaseUserOwnedProductMapper leaseUserOwnedProductMapper;
|
||||
|
||||
@Resource
|
||||
private LeaseProductMachineMapper leaseProductMachineMapper;
|
||||
|
||||
@Resource
|
||||
private RedisService redisService;
|
||||
|
||||
@Override
|
||||
public PageResult<UserOwnedProductDto> getOwnedList(UserOwnedProductVo userOwnedProductVo) {
|
||||
PageHelper.startPage(userOwnedProductVo.getPageNum(), userOwnedProductVo.getPageSize());
|
||||
//查询已购买的商品集合 按租约状态 未过期在前 + 结束时间 最先结束的在前排序
|
||||
List<LeaseUserOwnedProduct> leaseUserOwnedProducts = leaseUserOwnedProductMapper.selectList(new LambdaQueryWrapper<LeaseUserOwnedProduct>()
|
||||
.eq(LeaseUserOwnedProduct::getUserId, SecurityUtils.getUsername())
|
||||
.eq(LeaseUserOwnedProduct::getDel, false)
|
||||
.orderByAsc(LeaseUserOwnedProduct::getStatus)
|
||||
.orderByDesc(LeaseUserOwnedProduct::getEndTime));
|
||||
PageInfo<LeaseUserOwnedProduct> pageInfo = new PageInfo<>(leaseUserOwnedProducts);
|
||||
if (leaseUserOwnedProducts.isEmpty()){
|
||||
//不存在已购商品
|
||||
PageResult<UserOwnedProductDto> fail = PageResult.success(null);
|
||||
PageHelper.clearPage();
|
||||
return fail;
|
||||
}
|
||||
Map<String, List<UserMinerDto>> userAndMinerList = leaseUserOwnedProducts.stream().map(
|
||||
leaseUserOwnedProduct ->
|
||||
UserMinerDto.builder()
|
||||
.user(leaseUserOwnedProduct.getUser())
|
||||
.miner(leaseUserOwnedProduct.getMiner())
|
||||
.coin(leaseUserOwnedProduct.getCoin())
|
||||
.build()
|
||||
).collect(Collectors.groupingBy(UserMinerDto::getCoin));
|
||||
List<UserMinerPowerDto> userMinerPowerList = new ArrayList<>();
|
||||
userAndMinerList.forEach((coin, userMinerDtos) -> {
|
||||
userMinerPowerList.addAll( leaseUserOwnedProductMapper.getUserMinerPower(userMinerDtos, coin));
|
||||
});
|
||||
|
||||
//根据user+miner+coin 获取到实时的算力
|
||||
Map<String, UserMinerPowerDto> collect = userMinerPowerList.stream()
|
||||
.collect(Collectors.toMap(
|
||||
dto -> dto.getUser() + "-" + dto.getMiner() + "-" + dto.getCoin(),
|
||||
dto -> dto
|
||||
));
|
||||
|
||||
//获取币价
|
||||
Map<String, BigDecimal> coinPrice = new HashMap<>();
|
||||
//封装返回对象
|
||||
List<UserOwnedProductDto> userOwnedProducts = leaseUserOwnedProducts.stream().map(leaseUserOwnedProduct ->{
|
||||
String coin = leaseUserOwnedProduct.getCoin();
|
||||
BigDecimal bigDecimal = coinPrice.putIfAbsent(coin, redisService.getCacheBigDecimal(RedisCoinInfoKey.getPiceKey(coin)));
|
||||
|
||||
UserOwnedProductDto build = UserOwnedProductDto.builder()
|
||||
.id(leaseUserOwnedProduct.getId())
|
||||
.userId(leaseUserOwnedProduct.getUserId())
|
||||
.productMachineId(leaseUserOwnedProduct.getProductMachineId())
|
||||
.orderItemId(leaseUserOwnedProduct.getOrderItemId())
|
||||
.startTime(leaseUserOwnedProduct.getStartTime())
|
||||
.productMachineId(leaseUserOwnedProduct.getProductMachineId())
|
||||
.endTime(leaseUserOwnedProduct.getEndTime())
|
||||
.currentIncome(leaseUserOwnedProduct.getCurrentIncome())
|
||||
.estimatedEndIncome(leaseUserOwnedProduct.getEstimatedEndIncome())
|
||||
.currentUsdtIncome(bigDecimal == null ? leaseUserOwnedProduct.getCurrentUsdtIncome() : bigDecimal.multiply(leaseUserOwnedProduct.getCurrentIncome()))
|
||||
.estimatedEndUsdtIncome(leaseUserOwnedProduct.getEstimatedEndUsdtIncome())
|
||||
.purchasedComputingPower(leaseUserOwnedProduct.getPurchasedComputingPower())
|
||||
.status(leaseUserOwnedProduct.getStatus())
|
||||
.type(leaseUserOwnedProduct.getType())
|
||||
.createTime(leaseUserOwnedProduct.getCreateTime())
|
||||
.build();
|
||||
UserMinerPowerDto userMinerPowerDto = collect.get(leaseUserOwnedProduct.getUser() + "-" + leaseUserOwnedProduct.getMiner() + "-"+ leaseUserOwnedProduct.getCoin());
|
||||
if (userMinerPowerDto != null){
|
||||
//已购机器30分算力
|
||||
build.setCurrentComputingPower(userMinerPowerDto.getPower());
|
||||
}
|
||||
return build;
|
||||
}).collect(Collectors.toList());
|
||||
PageResult<UserOwnedProductDto> success = PageResult.success(userOwnedProducts);
|
||||
success.setTotal(pageInfo.getTotal());
|
||||
success.setTotalPage(pageInfo.getPages());
|
||||
PageHelper.clearPage();
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Result<UserOwnedProductDto> getOwnedById(BaseVo baseVo) {
|
||||
LeaseUserOwnedProduct leaseUserOwnedProduct = leaseUserOwnedProductMapper.selectById(baseVo.getId());
|
||||
List<LeaseProductMachine> leaseProductMachines = new ArrayList<>();
|
||||
leaseProductMachines.add(LeaseProductMachine.builder()
|
||||
.user(leaseUserOwnedProduct.getUser())
|
||||
.miner(leaseUserOwnedProduct.getMiner())
|
||||
.build());
|
||||
BigDecimal price = redisService.getCacheBigDecimal(RedisCoinInfoKey.getPiceKey(leaseUserOwnedProduct.getCoin()));
|
||||
//获取实时算力
|
||||
List<ProductMachineDto> recentlyFiveMinutesData = leaseProductMachineMapper.getRecentlyFiveMinutesData(leaseProductMachines, leaseUserOwnedProduct.getCoin());
|
||||
Integer status = leaseUserOwnedProduct.getStatus();
|
||||
BigDecimal currentIncome = status == 0 ? leaseUserOwnedProduct.getSettleIncome() : leaseUserOwnedProduct.getCurrentIncome();
|
||||
BigDecimal currentUsdtIncome = currentIncome.multiply(price);
|
||||
UserOwnedProductDto build = UserOwnedProductDto.builder()
|
||||
.id(leaseUserOwnedProduct.getId())
|
||||
.userId(leaseUserOwnedProduct.getUserId())
|
||||
.productMachineId(leaseUserOwnedProduct.getProductMachineId())
|
||||
.orderItemId(leaseUserOwnedProduct.getOrderItemId())
|
||||
.startTime(leaseUserOwnedProduct.getStartTime())
|
||||
.productMachineId(leaseUserOwnedProduct.getProductMachineId())
|
||||
.endTime(leaseUserOwnedProduct.getEndTime())
|
||||
.estimatedEndIncome(leaseUserOwnedProduct.getEstimatedEndIncome())
|
||||
.estimatedEndUsdtIncome(leaseUserOwnedProduct.getEstimatedEndUsdtIncome())
|
||||
.purchasedComputingPower(leaseUserOwnedProduct.getPurchasedComputingPower())
|
||||
.currentIncome(currentIncome)
|
||||
.currentUsdtIncome(currentUsdtIncome)
|
||||
.status(status)
|
||||
.type(leaseUserOwnedProduct.getType())
|
||||
.createTime(leaseUserOwnedProduct.getCreateTime())
|
||||
.build();
|
||||
if (!recentlyFiveMinutesData.isEmpty()){
|
||||
build.setCurrentComputingPower(recentlyFiveMinutesData.get(0).getComputingPower().divide(BigDecimal.valueOf(24 * 60 * 60), 2, RoundingMode.HALF_UP));
|
||||
}
|
||||
return Result.success(build);
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付验证成功后去修改订单等信息(迁移到这里让事务生效)
|
||||
* @param leaseOrderItems
|
||||
* @return 支付订单验证成功的个数
|
||||
*/
|
||||
@Transactional
|
||||
@Override
|
||||
public boolean afterPaySuccessTodoSomeEvent(List<LeaseOrderItem> leaseOrderItems){
|
||||
//回调才需要
|
||||
// 修改商品售出状态
|
||||
//List<Long> ids = leaseOrderItems.stream().map(LeaseOrderItem::getProductMachineId).collect(Collectors.toList());
|
||||
//int update = leaseProductMachineMapper.update(LeaseProductMachine.builder().saleState(1).build(),
|
||||
// new LambdaQueryWrapper<LeaseProductMachine>().eq(LeaseProductMachine::getDel, false).in(LeaseProductMachine::getId, ids));
|
||||
// 添加购买记录
|
||||
//List<LeaseOrderItem> leaseOrderItems2 = leaseOrderItemMapper.selectList(new LambdaQueryWrapper<LeaseOrderItem>()
|
||||
// .in(LeaseOrderItem::getProductMachineId, ids));
|
||||
|
||||
//获取卖方收款币种币价
|
||||
BigDecimal price = redisService.getCacheBigDecimal(RedisCoinInfoKey.getPiceKey(leaseOrderItems.get(0).getCoin()));
|
||||
List<LeaseUserOwnedProduct> collect = leaseOrderItems.stream()
|
||||
.map(item -> {
|
||||
// 获取当前的 LocalDateTime
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
// 获取当天 0 点的 LocalDateTime
|
||||
LocalDateTime startOfDay = now.toLocalDate().atStartOfDay().plusDays(1);
|
||||
return LeaseUserOwnedProduct.builder()
|
||||
.miner(item.getMiner())
|
||||
.userId(SecurityUtils.getUsername())
|
||||
.user(item.getUser())
|
||||
.address(item.getAddress())
|
||||
.productMachineId(item.getProductMachineId())
|
||||
.orderItemId(item.getId())
|
||||
.orderId(item.getOrderId())
|
||||
//预估收益由订单创建时固定 实际收益通过定时任务实时计算
|
||||
.estimatedEndIncome(item.getTheoryIncome())
|
||||
.estimatedEndUsdtIncome(price == null ? BigDecimal.ZERO : item.getTheoryIncome().multiply(price))
|
||||
.coin(item.getCoin())
|
||||
.startTime(startOfDay)
|
||||
.type(item.getType() ? 1 : 0)
|
||||
.endTime(startOfDay.plusDays(item.getLeaseTime()))
|
||||
.build();
|
||||
}).collect(Collectors.toList());
|
||||
boolean b1 = saveBatch(collect);
|
||||
|
||||
return b1;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user