From 1210ab4b6cde9706f2de936fed3753773a1516f6 Mon Sep 17 00:00:00 2001
From: zyy <zyy@email.com>
Date: Fri, 22 May 2026 16:01:01 +0800
Subject: [PATCH] 矿机
---
trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/AdminMinerServiceImpl.java | 41
trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/MinerServiceImpl.java | 211 +
trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerRedisKeys.java | 36
trading-order-service/src/main/java/com/yami/trading/service/miner/loadcache/MinerLoadCacheService.java | 137 +
trading-order-service/src/main/java/com/yami/trading/service/miner/service/AdminMinerParaService.java | 8
trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/AdminMinerService.java | 12
trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/MinerOrderProfitServiceImpl.java | 546 ++++
trading-order-service/src/main/java/com/yami/trading/dao/miner/MinerMapper.java | 10
trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/AdminMinerOrderController.java | 328 ++
trading-order-service/src/main/java/com/yami/trading/service/miner/job/MinerOrderProfitJob.java | 246 ++
trading-order-service/src/main/resources/mapper/miner/MinerOrderMapper.xml | 104
trading-order-service/src/main/java/com/yami/trading/dao/miner/MinerParaMapper.java | 10
trading-order-service/src/main/java/com/yami/trading/service/miner/job/MinerOrderMessage.java | 69
trading-order-bean/src/main/java/com/yami/trading/bean/miner/MinerOrder.java | 209 +
trading-order-service/src/main/java/com/yami/trading/service/miner/service/AdminMinerOrderService.java | 17
trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/MinerRedisKeys.java | 36
trading-order-common/src/main/java/com/yami/trading/common/util/TimeZoneContext.java | 26
trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/MinerOrderController.java | 565 ++++
trading-order-service/src/main/java/com/yami/trading/service/miner/web/AdminMinerParaAction.java | 156 +
trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/AdminMinerOrderServiceImpl.java | 159 +
trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerParaService.java | 18
trading-order-service/src/main/java/com/yami/trading/service/miner/service/AdminMinerService.java | 12
trading-order-admin/src/main/java/com/yami/trading/admin/dao/MinerMapper.java | 4
trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerOrderService.java | 98
trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerService.java | 33
trading-order-bean/src/main/java/com/yami/trading/bean/miner/Miner.java | 361 +++
trading-order-service/src/main/resources/mapper/miner/MinerMapper.xml | 17
trading-order-service/src/main/java/com/yami/trading/dao/miner/MinerOrderMapper.java | 31
trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/MinerService.java | 24
/dev/null | 35
trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/MinerOrderServiceImpl.java | 1004 ++++++++
trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/AdminMinerParaServiceImpl.java | 39
trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/MinerController.java | 113
trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/impl/AdminMinerServiceImpl.java | 40
trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/impl/MinerServiceImpl.java | 213 +
trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/AdminMinerController.java | 561 ++++
trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerOrderProfitService.java | 43
trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/MinerParaServiceImpl.java | 40
trading-order-service/src/main/resources/mapper/miner/MinerParaMapper.xml | 18
trading-order-bean/src/main/java/com/yami/trading/bean/miner/MinerPara.java | 66
trading-order-common/src/main/java/com/yami/trading/common/util/DateTimeTools.java | 1143 ++++++++++
41 files changed, 6,728 insertions(+), 111 deletions(-)
diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/AdminMinerController.java b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/AdminMinerController.java
new file mode 100644
index 0000000..06b60f7
--- /dev/null
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/AdminMinerController.java
@@ -0,0 +1,561 @@
+package com.yami.trading.admin.controller.miner;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yami.trading.api.util.ServletUtil;
+import com.yami.trading.bean.miner.Miner;
+import com.yami.trading.bean.model.Log;
+import com.yami.trading.bean.model.User;
+import com.yami.trading.common.constants.Constants;
+import com.yami.trading.common.domain.Result;
+import com.yami.trading.common.exception.BusinessException;
+import com.yami.trading.common.util.StringUtils;
+import com.yami.trading.security.common.util.SecurityUtils;
+import com.yami.trading.service.miner.service.AdminMinerService;
+import com.yami.trading.service.miner.service.MinerService;
+import com.yami.trading.service.system.LogService;
+import com.yami.trading.service.user.UserService;
+import com.yami.trading.sys.service.SysUserService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 矿机配置
+ */
+@RestController
+@CrossOrigin
+public class AdminMinerController {
+
+ private Logger logger = LogManager.getLogger(AdminMinerController.class);
+
+ @Autowired
+ protected AdminMinerService adminMinerService;
+ @Autowired
+ protected MinerService minerService;
+ @Autowired
+ protected UserService partyService;
+ @Autowired
+ protected LogService logService;
+ @Autowired
+ protected SysUserService secUserService;
+ @Autowired
+ protected PasswordEncoder passwordEncoder;
+
+ private final String action = "normal/adminMinerAction!";
+
+ /**
+ * 获取 矿机配置 列表
+ */
+ @RequestMapping(action + "list.action")
+ public Result list(HttpServletRequest request) {
+// this.checkAndSetPageNo(request.getParameter("pageNo"));
+ String name_para = request.getParameter("name_para");
+ String message = request.getParameter("message");
+ String error = request.getParameter("error");
+ int pageNo = 0;
+ int pageSize = 300;
+ Page page = this.adminMinerService.pagedQuery(pageNo, 300, name_para);
+ for(Map<String,Object> data:(List<Map<String,Object>>) (page.getRecords())) {
+ if("N".equals(data.get("test"))) {
+ data.put("cycle", null);
+ }
+ }
+ Map<String,Object> map = new HashMap<>();
+ map.put("pageNo", pageNo);
+ map.put("pageSize", pageSize);
+ map.put("page", page);
+ map.put("name_para", name_para);
+ map.put("message", message);
+ map.put("error", error);
+
+ return Result.ok(map);
+ }
+
+ public String toAdd() {
+ return "add";
+ }
+
+ /**
+ * 验证基础信息
+ */
+ protected String verifBase(String algorithm, String computing_power, String power, String product_factory,
+ String product_size, String weight, String work_temperature_min, String work_temperature_max, String work_humidity_min,
+ String work_humidity_max, String internet) {
+ if (StringUtils.isEmptyString(algorithm)) {
+ return "请选择适用算法";
+ }
+
+ if (StringUtils.isNullOrEmpty(computing_power)
+ || !StringUtils.isDouble(computing_power)
+ || Double.valueOf(computing_power) < 0) {
+ return "额定算力不能小于0";
+ }
+
+ if (StringUtils.isNullOrEmpty(power)
+ || !StringUtils.isDouble(power)
+ || Double.valueOf(power) < 0) {
+ return "功耗不能小于0";
+ }
+
+ if (StringUtils.isNullOrEmpty(product_factory)) {
+ return "请输入生产厂家";
+ }
+
+ if (StringUtils.isNullOrEmpty(product_size)) {
+ return "请输入外箱尺寸";
+ }
+
+ if (StringUtils.isNullOrEmpty(weight)
+ || !StringUtils.isDouble(weight)
+ || Double.valueOf(weight) < 0) {
+ return "整机重量不能小于0";
+ }
+
+ if (StringUtils.isNullOrEmpty(work_temperature_min)
+ || !StringUtils.isDouble(work_temperature_min)) {
+ return "工作温度区间最小值错误";
+ }
+
+ if (StringUtils.isNullOrEmpty(work_temperature_max)
+ || !StringUtils.isDouble(work_temperature_max)
+ || Double.valueOf(work_temperature_max) == 0) {
+ return "工作温度区间最大值错误";
+ }
+
+ if (Double.valueOf(work_temperature_max) <= Double.valueOf(work_temperature_min)) {
+ return "工作温度区间错误";
+ }
+
+ if (StringUtils.isNullOrEmpty(work_humidity_min)
+ || !StringUtils.isDouble(work_humidity_min)
+ || Double.valueOf(work_humidity_min) < 0) {
+ return "工作湿度区间不能小于0";
+ }
+
+ if (StringUtils.isNullOrEmpty(work_humidity_max)
+ || !StringUtils.isDouble(work_humidity_max)
+ || Double.valueOf(work_humidity_max) == 0) {
+ return "工作温度区间最大值错误";
+ }
+
+ if (StringUtils.isNullOrEmpty(work_humidity_max)
+ || !StringUtils.isDouble(work_humidity_max)
+ || Double.valueOf(work_humidity_max) == 0) {
+ return "工作温度区间最大值错误";
+ }
+
+ if (Double.valueOf(work_humidity_max) <= Double.valueOf(work_humidity_min)) {
+ return "工作温度区间错误";
+ }
+
+ if (StringUtils.isEmptyString(internet)) {
+ return "请选择网络连接";
+ }
+
+ return null;
+ }
+ protected String verification(String name, String show_daily_rate, String daily_rate, String cycle_close, String investment_min, String investment_max,
+ String algorithm, String computing_power, String power, String product_factory,
+ String product_size, String weight, String work_temperature_min, String work_temperature_max, String work_humidity_min,
+ String work_humidity_max, String internet) {
+
+ String verifBase = verifBase(algorithm, computing_power, power, product_factory,
+ product_size, weight, work_temperature_min, work_temperature_max, work_humidity_min,
+ work_humidity_max, internet);
+
+ if(StringUtils.isNotEmpty(verifBase)) {
+ return verifBase;
+ }
+ if (StringUtils.isEmptyString(name)) {
+ return "请输入产品名称";
+ }
+
+// if (StringUtils.isEmptyString(this.img))
+// return "请上传产品图片";
+// if (this.cycle <= 0) {
+// return "周期不能小于等于0天";
+// }
+// if (this.daily_rate < 0.0D) {
+// return "日利率不能小于0";
+// }
+
+ if (StringUtils.isNullOrEmpty(show_daily_rate)
+ || !StringUtils.isDouble(show_daily_rate)
+ || Double.valueOf(show_daily_rate) < 0) {
+ return "日利率不能小于0";
+ }
+
+ if (StringUtils.isNullOrEmpty(daily_rate)
+ || !StringUtils.isDouble(daily_rate)
+ || Double.valueOf(daily_rate) < 0) {
+ return "今日利率不能小于0";
+ }
+
+ if (StringUtils.isNullOrEmpty(cycle_close)
+ || !StringUtils.isDouble(cycle_close)
+ || Double.valueOf(cycle_close) < 0) {
+ return "解锁周期不能小于0";
+ }
+
+ if (StringUtils.isNullOrEmpty(investment_min)
+ || !StringUtils.isDouble(investment_min)
+ || Double.valueOf(investment_min) < 0) {
+ return "投资金额区间最小值不能小于0";
+ }
+
+ if (StringUtils.isNullOrEmpty(investment_max)
+ || !StringUtils.isDouble(investment_max)
+ || Double.valueOf(investment_max) < 0) {
+ return "投资金额区间最大值不能小于0";
+ }
+
+ // max=0表示没有设置上限
+ if (Double.valueOf(investment_max) < Double.valueOf(investment_min)) {
+ return "投资金额区间错误";
+ }
+ return null;
+ }
+
+// public String add() {
+// try {
+// this.error = verification();
+// if (!StringUtils.isNullOrEmpty(this.error))
+// return toAdd();
+//// if (this.minerService.findByName(this.name) != null) {
+//// this.error ="产品名称已存在";
+//// return toAdd();
+//// }
+// Miner miner = new Miner();
+// miner.setName(this.name);
+// miner.setName_en(this.name_en);
+// miner.setName_cn(this.name_cn);
+//// miner.setImg(this.img);
+//// miner.setCycle(this.cycle);
+// miner.setCycle_close(this.cycle_close);
+// miner.setDaily_rate(this.daily_rate);
+// miner.setShow_daily_rate(this.show_daily_rate);
+// miner.setInvestment_min(this.investment_min);
+// miner.setInvestment_max(this.investment_max);
+// miner.setState("1");
+// miner.setTest(false);
+// miner.setOn_sale(this.on_sale);
+//
+// //基础参数
+// miner.setAlgorithm(algorithm);
+// miner.setComputing_power(computing_power);
+// miner.setComputing_power_unit(computing_power_unit);
+// miner.setPower(power);
+// miner.setProduct_factory(product_factory);
+// miner.setProduct_size(product_size);
+// miner.setWeight(weight);
+// miner.setWork_temperature_min(work_temperature_min);
+// miner.setWork_temperature_max(work_temperature_max);
+// miner.setWork_humidity_min(work_humidity_min);
+// miner.setWork_humidity_max(work_humidity_max);
+// miner.setInternet(internet);
+//
+// this.minerService.save(miner);
+// this.message = "操作成功";
+// } catch (BusinessException e) {
+// this.error = e.getMessage();
+// return toAdd();
+// } catch (Throwable t) {
+// logger.error("UserAction.register error ", t);
+// this.error = "[ERROR] " + t.getMessage();
+// return toAdd();
+// }
+// return list();
+// }
+
+ protected String verificationUpdate(String name, String show_daily_rate, String daily_rate, String cycle_close, String investment_min, String investment_max,
+ String algorithm, String computing_power, String power, String product_factory,
+ String product_size, String weight, String work_temperature_min, String work_temperature_max, String work_humidity_min,
+ String work_humidity_max, String internet) {
+ String verifBase = verifBase(algorithm, computing_power, power, product_factory,
+ product_size, weight, work_temperature_min, work_temperature_max, work_humidity_min,
+ work_humidity_max, internet);
+ if(StringUtils.isNotEmpty(verifBase)) {
+ return verifBase;
+ }
+ if (StringUtils.isEmptyString(name))
+ return "请输入产品名称";
+// if (StringUtils.isEmptyString(this.img))
+// return "请上传产品图片";
+// if (this.cycle <= 0) {
+// return "周期不能小于等于0天";
+// }
+ if (StringUtils.isNullOrEmpty(show_daily_rate)
+ || !StringUtils.isDouble(show_daily_rate)
+ || Double.valueOf(show_daily_rate) < 0) {
+ return "日利率不能小于0";
+ }
+
+ if (StringUtils.isNullOrEmpty(daily_rate)
+ || !StringUtils.isDouble(daily_rate)
+ || Double.valueOf(daily_rate) < 0) {
+ return "今日利率不能小于0";
+ }
+
+ if (StringUtils.isNullOrEmpty(cycle_close)
+ || !StringUtils.isDouble(cycle_close)
+ || Double.valueOf(cycle_close) < 0) {
+ return "解锁周期不能小于0";
+ }
+
+ if (StringUtils.isNullOrEmpty(investment_min)
+ || !StringUtils.isDouble(investment_min)
+ || Double.valueOf(investment_min) < 0) {
+ return "投资金额区间最小值不能小于0";
+ }
+
+ if (StringUtils.isNullOrEmpty(investment_max)
+ || !StringUtils.isDouble(investment_max)
+ || Double.valueOf(investment_max) < 0) {
+ return "投资金额区间最大值不能小于0";
+ }
+
+ // max=0表示没有设置上限
+ if (Double.valueOf(investment_max) < Double.valueOf(investment_min)) {
+ return "投资金额区间错误";
+ }
+
+ return null;
+ }
+
+ @RequestMapping(action + "toUpdate.action")
+ public Result toUpdate(HttpServletRequest request) {
+ String id = request.getParameter("id");
+ Miner miner = this.minerService.findById(id);
+ String name = miner.getName();
+ String name_en = miner.getName_en();
+ String name_cn = miner.getName_cn();
+// this.img = miner.getImg();
+// this.cycle = miner.getCycle();
+ int cycle_close = miner.getCycle_close();
+ double daily_rate = miner.getDaily_rate();
+ double investment_min = miner.getInvestment_min();
+ double investment_max = (miner.getTest() == "N") && miner.getInvestment_max() == 0 ? null : miner.getInvestment_max();
+ double show_daily_rate = miner.getShow_daily_rate();
+// this.state = miner.getState();
+ String test = miner.getTest();
+ String on_sale = miner.getOn_sale();
+
+ //基础参数
+ String algorithm = miner.getAlgorithm();
+ double computing_power = miner.getComputing_power();
+ String computing_power_unit = miner.getComputing_power_unit();
+ double power = miner.getPower();
+ String product_factory = miner.getProduct_factory();
+ String product_size = miner.getProduct_size();
+ double weight = miner.getWeight();
+ double work_temperature_min = miner.getWork_temperature_min();
+ double work_temperature_max = miner.getWork_temperature_max();
+ double work_humidity_min = miner.getWork_humidity_min();
+ double work_humidity_max = miner.getWork_humidity_max();
+ String internet = miner.getInternet();
+
+ Map<String,Object> map = new HashMap<>();
+ map.put("id", id);
+ map.put("name", name);
+ map.put("name_en", name_en);
+ map.put("name_cn", name_cn);
+ map.put("cycle_close", cycle_close);
+ map.put("daily_rate", daily_rate);
+ map.put("investment_min", investment_min);
+ map.put("investment_max", investment_max);
+ map.put("show_daily_rate", show_daily_rate);
+ map.put("test", test);
+ map.put("on_sale", on_sale);
+ map.put("algorithm", algorithm);
+ map.put("computing_power", computing_power);
+ map.put("computing_power_unit", computing_power_unit);
+ map.put("power", power);
+ map.put("product_factory", product_factory);
+ map.put("product_size", product_size);
+ map.put("weight", weight);
+ map.put("work_temperature_min", work_temperature_min);
+ map.put("work_temperature_max", work_temperature_max);
+ map.put("work_humidity_min", work_humidity_min);
+ map.put("work_humidity_max", work_humidity_max);
+ map.put("internet", internet);
+
+ return Result.ok(map);
+ }
+
+ @RequestMapping(action + "update.action")
+ public Result update(HttpServletRequest request) {
+
+ String error = "";
+ String id = request.getParameter("id");
+ String name = request.getParameter("name");
+ String show_daily_rate = request.getParameter("show_daily_rate");
+ String daily_rate = request.getParameter("daily_rate");
+ String cycle_close = request.getParameter("cycle_close");
+ String investment_min = request.getParameter("investment_min");
+ String investment_max = request.getParameter("investment_max");
+ String algorithm = request.getParameter("algorithm");
+ String computing_power = request.getParameter("computing_power");
+ String power = request.getParameter("power");
+ String product_factory = request.getParameter("product_factory");
+ String product_size = request.getParameter("product_size");
+ String weight = request.getParameter("weight");
+ String work_temperature_min = request.getParameter("work_temperature_min");
+ String work_temperature_max = request.getParameter("work_temperature_max");
+ String work_humidity_min = request.getParameter("work_humidity_min");
+ String work_humidity_max = request.getParameter("work_humidity_max");
+ String internet = request.getParameter("internet");
+ String buyCurrency = request.getParameter("buyCurrency");
+ String outputCurrency = request.getParameter("outputCurrency");
+
+ if(StringUtils.isNullOrEmpty(buyCurrency)){
+ buyCurrency = "usdt";
+ }
+
+ if(StringUtils.isNullOrEmpty(outputCurrency)){
+ outputCurrency = "usdt";
+ }
+
+ String name_en = request.getParameter("name_en");
+ String name_cn = request.getParameter("name_cn");
+ String test = request.getParameter("test");
+ String on_sale = request.getParameter("on_sale");
+ String login_safeword = request.getParameter("login_safeword");
+ String computing_power_unit = request.getParameter("computing_power_unit");
+
+// ModelAndView model = new ModelAndView();
+// model.addObject("id", id);
+// model.addObject("name", name);
+// model.addObject("name_en", name_en);
+// model.addObject("name_cn", name_cn);
+// model.addObject("cycle_close", cycle_close);
+// model.addObject("daily_rate", daily_rate);
+// model.addObject("investment_min", investment_min);
+// model.addObject("investment_max", investment_max);
+// model.addObject("show_daily_rate", show_daily_rate);
+// model.addObject("test", test);
+// model.addObject("on_sale", on_sale);
+// model.addObject("algorithm", algorithm);
+// model.addObject("computing_power", computing_power);
+// model.addObject("computing_power_unit", computing_power_unit);
+// model.addObject("power", power);
+// model.addObject("product_factory", product_factory);
+// model.addObject("product_size", product_size);
+// model.addObject("weight", weight);
+// model.addObject("work_temperature_min", work_temperature_min);
+// model.addObject("work_temperature_max", work_temperature_max);
+// model.addObject("work_humidity_min", work_humidity_min);
+// model.addObject("work_humidity_max", work_humidity_max);
+// model.addObject("internet", internet);
+
+ Miner miner = this.minerService.findById(id);
+ try {
+ error = verificationUpdate(name, show_daily_rate, daily_rate, cycle_close, investment_min, investment_max,
+ algorithm, computing_power, power, product_factory,
+ product_size, weight, work_temperature_min, work_temperature_max, work_humidity_min,
+ work_humidity_max, internet);
+ if (!StringUtils.isNullOrEmpty(error)) {
+// model.addObject("error", error);
+// model.setViewName("miner_update");
+ return Result.failed(error);
+ }
+ String username = SecurityUtils.getSysUser().getUsername();
+// SysUser sec = this.secUserService.getByUserName(username);
+// User sec = this.secUserService.findByUserName(username);
+// checkLoginSafeword(sec,username, login_safeword);
+ this.secUserService.checkSafeWord(login_safeword);
+
+ miner.setName(name);
+ miner.setName_en(name_en);
+ miner.setName_cn(name_cn);
+// miner.setCycle(this.cycle);
+ miner.setDaily_rate(Double.valueOf(daily_rate));
+ miner.setInvestment_min(Double.valueOf(investment_min));
+ miner.setInvestment_max(investment_max == null ? 0 : Double.valueOf(investment_max));
+ miner.setOn_sale(on_sale);
+ miner.setShow_daily_rate(Double.valueOf(show_daily_rate));
+// miner.setState(this.state);
+
+ //基础参数
+ miner.setAlgorithm(algorithm);
+ miner.setComputing_power(Double.valueOf(computing_power));
+ miner.setComputing_power_unit(computing_power_unit);
+ miner.setPower(Double.valueOf(power));
+ miner.setProduct_factory(product_factory);
+ miner.setProduct_size(product_size);
+ miner.setWeight(Double.valueOf(weight));
+ miner.setWork_temperature_min(Double.valueOf(work_temperature_min));
+ miner.setWork_temperature_max(Double.valueOf(work_temperature_max));
+ miner.setWork_humidity_min(Double.valueOf(work_humidity_min));
+ miner.setWork_humidity_max(Double.valueOf(work_humidity_max));
+ miner.setInternet(internet);
+ miner.setCycle_close(Integer.valueOf(cycle_close));
+ miner.setBuy_currency(buyCurrency.toLowerCase());
+ miner.setOutput_currency(outputCurrency.toLowerCase());
+
+ this.minerService.updateA(miner);
+
+ Log log = new Log();
+ log.setCategory(Constants.LOG_CATEGORY_OPERATION);
+
+ log.setUsername(username);
+ log.setOperator(username);
+ String ip = ServletUtil.getIp(request);
+ log.setLog("手动修改矿机配置,ip:["+ip+"]");
+ logService.save(log);
+
+// model.addObject("message", "操作成功");
+// model.setViewName("redirect:/" + action + "list.action");
+ return Result.ok(miner);
+ } catch (BusinessException e) {
+// model.addObject("error", e.getMessage());
+// model.setViewName("miner_update");
+ return Result.failed(e.getMessage());
+ } catch (Throwable t) {
+ logger.error("update error ", t);
+// model.addObject("error", "程序错误");
+// model.setViewName("miner_update");
+ return Result.failed("程序错误");
+// return model;
+ }
+ }
+
+ /**
+ * 验证登录人资金密码
+ * @param operatorUsername
+ * @param loginSafeword
+ */
+ protected void checkLoginSafeword(User secUser,String operatorUsername,String loginSafeword) {
+// SecUser sec = this.secUserService.findUserByLoginName(operatorUsername);
+ String sysSafeword = secUser.getSafePassword();
+
+ String safeword_md5 = passwordEncoder.encode(loginSafeword);
+ if (!safeword_md5.equals(sysSafeword)) {
+ throw new BusinessException("登录人资金密码错误");
+ }
+ }
+
+// public String toDelete() {
+// try {
+//
+// this.minerService.delete(this.id);
+// this.message = "操作成功";
+// return list();
+// } catch (BusinessException e) {
+// this.error = e.getMessage();
+// return list();
+// } catch (Throwable t) {
+// logger.error("update error ", t);
+// this.error = "程序错误";
+// return list();
+// }
+// }
+}
diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/AdminMinerOrderController.java b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/AdminMinerOrderController.java
new file mode 100644
index 0000000..f44a09b
--- /dev/null
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/AdminMinerOrderController.java
@@ -0,0 +1,328 @@
+package com.yami.trading.admin.controller.miner;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yami.trading.admin.facade.PermissionFacade;
+import com.yami.trading.bean.miner.Miner;
+import com.yami.trading.bean.miner.MinerOrder;
+import com.yami.trading.common.domain.Result;
+import com.yami.trading.common.exception.BusinessException;
+import com.yami.trading.common.util.*;
+import com.yami.trading.security.common.util.SecurityUtils;
+import com.yami.trading.service.miner.job.MinerOrderProfitJob;
+import com.yami.trading.service.miner.service.AdminMinerOrderService;
+import com.yami.trading.service.miner.service.MinerOrderService;
+import com.yami.trading.service.miner.service.MinerService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+
+/**
+ * 管理后台-矿机订单页面
+ *
+ */
+@RestController
+@CrossOrigin
+public class AdminMinerOrderController {
+
+ private Logger logger = LogManager.getLogger(AdminMinerOrderController.class);
+
+ @Autowired
+ protected AdminMinerOrderService adminMinerOrderService;
+ @Autowired
+ protected MinerOrderService minerOrderService;
+ @Autowired
+ protected MinerService minerService;
+ @Autowired
+ protected MinerOrderProfitJob minerOrderProfitJob;
+
+ @Autowired
+ private PermissionFacade permissionFacade;
+
+ protected Map<String, Object> session = new HashMap<>();
+
+ private final String action = "normal/adminMinerOrderAction!";
+
+ @RequestMapping(action + "list.action")
+ public Result list(HttpServletRequest request) {
+
+// this.checkAndSetPageNo(request.getParameter("pageNo"));
+ String name_para = request.getParameter("name_para");
+ String miner_para = request.getParameter("miner_para");
+ String status_para = request.getParameter("status_para");
+ String order_no_para = request.getParameter("order_no_para");
+ String rolename_para = request.getParameter("rolename_para");
+
+ int pageNo = Integer.parseInt(request.getParameter("current"));
+ int pageSize = Integer.parseInt(request.getParameter("size"));
+
+ List<String> children = permissionFacade.getOwnerUserIds();
+
+ //¤t=1&size=10
+
+// String partyId = getLoginPartyId();
+ String partyId = null;//SecurityUtils.getCurrentSysUserId();
+ List<Miner> findAll = this.minerService.findAll();
+ Map<String, String> miner_name_map = new LinkedHashMap<String, String>();
+ for (Miner miner : findAll) {
+ miner_name_map.put(miner.getUuid(), miner.getName());
+ }
+
+ Page page = this.adminMinerOrderService.pagedQuery(pageNo, pageSize, name_para, miner_para,
+ status_para, children, order_no_para, rolename_para);
+// ModelAndView model = new ModelAndView();
+// model.addObject("pageNo", pageNo);
+// model.addObject("pageSize", pageSize);
+// model.addObject("page", page);
+// model.addObject("name_para", name_para);
+// model.addObject("miner_para", miner_para);
+// model.addObject("status_para", status_para);
+// model.addObject("order_no_para", order_no_para);
+// model.addObject("rolename_para", rolename_para);
+//
+// model.addObject("miner_name_map", miner_name_map);
+// model.addObject("message", message);
+// model.addObject("error", error);
+// model.setViewName("miner_order_list");
+ return Result.ok(page);
+ }
+
+ /**
+ * 后台赎回
+ */
+ @RequestMapping(action + "close.action")
+ public Result closOrder(HttpServletRequest request) {
+ String message = "";
+ String error = "";
+ Map<String,Object> map = new HashMap<>();
+ try {
+ String order_no = request.getParameter("order_no");
+ System.out.println("order_no => "+order_no);
+ MinerOrder order = minerOrderService.findByOrder_no(order_no);
+ System.out.println("order.getMiner_id() => "+order.getMiner_id());
+ Miner miner = minerService.findById(order.getMiner_id());
+
+ CloseDelayThread lockDelayThread = new CloseDelayThread(order_no, minerOrderService);
+ Thread t = new Thread(lockDelayThread);
+ t.start();
+ message = "操作成功";
+ } catch (BusinessException e) {
+ error = e.getMessage();
+ return Result.failed(error);
+ } catch (Exception e) {
+ logger.error("error ", e);
+ error = "程序错误";
+ return Result.failed(error);
+ }
+// ModelAndView model = new ModelAndView();
+// model.addObject("message", message);
+// model.addObject("error", error);
+// model.setViewName("redirect:/" + action + "list.action");
+ return Result.succeed(map);
+ }
+
+ /**
+ * 新线程处理,直接拿到订单锁处理完成后退出
+ *
+ */
+ public class CloseDelayThread implements Runnable {
+ private String orderNo;
+ private MinerOrderService minerOrderService;
+
+ public void run() {
+ try {
+ while (true) {
+ /**
+ * 提前赎回理财产品需要支付违约金
+ */
+ MinerOrder order = minerOrderService.findByOrder_no(orderNo);
+
+ Miner miner = minerService.findById(order.getMiner_id());
+
+ Date date_now = new Date();// 取时间
+ double last_days = daysBetween(order.getCreate_time(), date_now);
+ if ("1".equals(order.getState()) && last_days >= miner.getCycle_close()) {
+ /**
+ * 扣除违约金
+ */
+ double default_money = 0d;// 不计违约金
+ order.setState("2");
+ order.setProfit(Arith.sub(order.getProfit(), default_money));
+ this.minerOrderService.saveClose(order);
+ }
+ /**
+ * 处理完退出
+ */
+ break;
+ }
+
+ } catch (Exception e) {
+ logger.error("error:", e);
+ }
+
+ }
+
+ public CloseDelayThread(String orderNo, MinerOrderService minerOrderService) {
+ this.orderNo = orderNo;
+ this.minerOrderService = minerOrderService;
+ }
+
+ }
+
+ @RequestMapping(action + "toAddOrder.action")
+ public Result toAddOrder(HttpServletRequest request) {
+ String session_token = UUID.randomUUID().toString();
+ this.session.put("session_token", session_token);
+
+ List<Miner> findAll = this.minerService.findAll();
+ Map<String, String> miner_name_map = new LinkedHashMap<String, String>();
+ List<Miner> miner_list = new LinkedList<Miner>();
+ for (Miner miner : findAll) {
+ miner_name_map.put(miner.getUuid(), miner.getName());
+ miner_list.add(miner);
+ }
+ Map<String,Object> map = new HashMap<>();
+ map.put("miner_name_map", miner_name_map);
+ map.put("miner_list", miner_list);
+ map.put("session_token", session_token);
+ return Result.ok(map);
+ }
+
+ @RequestMapping(action + "addOrder.action")
+ public Result addOrder(HttpServletRequest request) {
+
+ String error = "";
+ try {
+ String session_token = request.getParameter("session_token");
+ String para_uid = request.getParameter("para_uid");
+ // 购买金额
+ String para_amount = request.getParameter("para_amount");
+ // 矿机id
+ String para_minerid = request.getParameter("para_minerid");
+
+// Object object = this.session.get("session_token");
+// this.session.remove("session_token");
+// if ((object == null) || (StringUtils.isNullOrEmpty(session_token))
+// || (!session_token.equals((String) object))) {
+// return Result.failed("token");
+// }
+
+ error = verifyAddOrder(para_uid, para_amount, para_minerid);
+ if (!StringUtils.isNullOrEmpty(error)) {
+// model.addObject("error", error);
+// model.setViewName("miner_order_add");
+ return Result.failed(error);
+ }
+
+ Object object = new Object();
+ synchronized (object) {
+ String username = SecurityUtils.getSysUser().getUsername();
+ adminMinerOrderService.addOrder(para_uid, Double.valueOf(para_amount), para_minerid, username);
+ ThreadUtils.sleep(100);
+ }
+// model.addObject("message", "操作成功");
+// model.setViewName("redirect:/" + action + "list.action");
+ return Result.ok("操作成功");
+ } catch (BusinessException e) {
+// model.addObject("error", e.getMessage());
+ return Result.failed(e.getMessage());
+ } catch (Exception e) {
+ logger.error("error ", e);
+// model.addObject("error", "程序错误");
+// model.setViewName("miner_order_add");
+ return Result.failed("程序错误");
+ }
+ }
+
+ protected String verifyAddOrder(String para_uid, String para_amount, String para_minerid) {
+ if (StringUtils.isEmptyString(para_uid)) {
+ return "请输入用户uid";
+ }
+
+ if (StringUtils.isNullOrEmpty(para_amount)
+ || !StringUtils.isDouble(para_amount)
+ || Double.valueOf(para_amount)< 0) {
+ return "购买金额不能小于0";
+ }
+
+ if (StringUtils.isEmptyString(para_minerid)) {
+ return "请选择要购买的矿机";
+ }
+ return null;
+ }
+
+ @RequestMapping(action + "addProfit.action")
+ public Result addProfit(HttpServletRequest request) {
+ String message = "";
+ String error = "";
+ String system_time = request.getParameter("system_time");
+ try {
+ String username = SecurityUtils.getSysUser().getUsername();
+ if (!"root".equals(username) && !"admin".equals(username)) {
+ throw new BusinessException("权限不足");
+ }
+ if (StringUtils.isEmptyString(system_time)) {
+ throw new BusinessException("请填入系统时间");
+ }
+
+ Date newTime = DateTimeTools.readQueryTime(system_time, DateUtils.NORMAL_DATE_FORMAT, null);
+ //JobDelayThread thread = new JobDelayThread(DateUtils.toDate(system_time, DateUtils.NORMAL_DATE_FORMAT), minerOrderProfitJob);
+ JobDelayThread thread = new JobDelayThread(newTime, minerOrderProfitJob);
+ Thread t = new Thread(thread);
+ t.start();
+ message = "操作成功";
+ } catch (BusinessException e) {
+ error = e.getMessage();
+// System.out.println("error = " + error);
+ return Result.failed(e.getMessage());
+ } catch (Exception e) {
+ logger.error("error ", e);
+// System.out.println("error " + e);
+ error = "程序错误";
+ return Result.failed(e.getMessage());
+ }
+// ModelAndView model = new ModelAndView();
+ Map<String,Object> map = new HashMap<>();
+ map.put("message", message);
+ map.put("error", error);
+ return Result.ok(map);
+ }
+
+
+ public class JobDelayThread implements Runnable {
+ private MinerOrderProfitJob minerOrderProfitJob;
+ private Date systemTime;
+ public void run() {
+ minerOrderProfitJob.handleData(systemTime);
+ }
+
+ public JobDelayThread(Date systemTime, MinerOrderProfitJob minerOrderProfitJob) {
+ this.systemTime = systemTime;
+ this.minerOrderProfitJob = minerOrderProfitJob;
+ }
+
+ }
+
+ public static int daysBetween(Date smdate, Date bdate) throws ParseException {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ smdate = sdf.parse(sdf.format(smdate));
+ bdate = sdf.parse(sdf.format(bdate));
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(smdate);
+ long time1 = cal.getTimeInMillis();
+ cal.setTime(bdate);
+ long time2 = cal.getTimeInMillis();
+ long between_days = (time2 - time1) / (1000 * 3600 * 24);
+
+ return Integer.parseInt(String.valueOf(between_days));
+ }
+
+}
diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/MinerController.java b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/MinerController.java
index 458acd7..e9bc9e0 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/MinerController.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/MinerController.java
@@ -1,57 +1,88 @@
package com.yami.trading.admin.controller.miner;
-import com.yami.trading.admin.controller.service.MinerService;
-import com.yami.trading.bean.model.Miner;
-import io.swagger.annotations.Api;
-import lombok.extern.slf4j.Slf4j;
+import com.yami.trading.bean.miner.Miner;
+import com.yami.trading.common.exception.BusinessException;
+import com.yami.trading.common.web.ResultObject;
+import com.yami.trading.service.miner.service.MinerService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
/**
- * @program: trading-order-master
- * @description: 矿机
- * @create: 2025-01-22 17:10
- **/
+ * 矿机产品
+ *
+ */
@RestController
-@RequestMapping("miner")
-@Api(tags = "矿机")
-@Slf4j
+@CrossOrigin
public class MinerController {
- @Autowired
- private MinerService minerService;
+ private Logger logger = LogManager.getLogger(MinerController.class);
+
+ @Autowired
+ protected MinerService minerService;
+
+ private final String action = "api/miner!";
- // 添加矿机
- @PostMapping("/add")
- public boolean addMiner(@RequestBody Miner miner) {
- return minerService.addMiner(miner);
- }
+ /**
+ * 矿机产品列表
+ */
+ @RequestMapping(action + "list.action")
+ public Object list() throws IOException {
- // 删除矿机
- @DeleteMapping("/delete/{id}")
- public boolean deleteMiner(@PathVariable int id) {
- return minerService.deleteMiner(id);
- }
+ ResultObject resultObject = new ResultObject();
+ try {
+ List<Miner> data = minerService.findAllState_1();
+ List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
+ if (data != null) {
+ for (int i = 0; i < data.size(); i++) {
+ result.add(minerService.getBindOne(data.get(i)));
+ }
+ }
+ resultObject.setData(result);
+ resultObject.setCode("0");
+ } catch (BusinessException e) {
+ resultObject.setCode("1");
+ resultObject.setMsg(e.getMessage());
+ logger.error("BusinessException:", e);
+ } catch (Exception e) {
+ resultObject.setCode("1");
+ resultObject.setMsg("程序错误");
+ logger.error("error:", e);
+ }
+ return resultObject;
+ }
- // 更新矿机
- @PutMapping("/update")
- public boolean updateMiner(@RequestBody Miner miner) {
- return minerService.updateMiner(miner);
- }
+ /**
+ * 矿机产品详情
+ */
+ @RequestMapping(action + "get.action")
+ public Object get(HttpServletRequest request) {
- // 获取矿机详情
- @GetMapping("/get/{id}")
- public Miner getMiner(@PathVariable int id) {
- return minerService.getMiner(id);
- }
+ ResultObject resultObject = new ResultObject();
+ try {
+ String id = request.getParameter("id");
+ Miner data = minerService.findById(id);
+ resultObject.setData(minerService.getBindOne(data));
+ resultObject.setCode("0");
+ } catch (BusinessException e) {
+ resultObject.setCode("1");
+ resultObject.setMsg(e.getMessage());
+ logger.error("BusinessException:", e);
+ } catch (Exception e) {
+ resultObject.setCode("1");
+ resultObject.setMsg("程序错误");
+ logger.error("error:", e);
+ }
- // 获取所有矿机
- @GetMapping("/getAll")
- public List<Miner> getAllMiners() {
- return minerService.getAllMiners();
- }
-
-
+ return resultObject;
+ }
}
diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/MinerOrderController.java b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/MinerOrderController.java
new file mode 100644
index 0000000..cebd32a
--- /dev/null
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/MinerOrderController.java
@@ -0,0 +1,565 @@
+package com.yami.trading.admin.controller.miner;
+
+import com.alibaba.fastjson2.JSON;
+import com.yami.trading.bean.miner.Miner;
+import com.yami.trading.bean.miner.MinerOrder;
+import com.yami.trading.bean.model.User;
+import com.yami.trading.common.exception.BusinessException;
+import com.yami.trading.common.util.*;
+import com.yami.trading.common.web.ResultObject;
+import com.yami.trading.security.common.util.SecurityUtils;
+import com.yami.trading.service.SessionTokenService;
+import com.yami.trading.service.miner.service.MinerOrderService;
+import com.yami.trading.service.miner.service.MinerService;
+import com.yami.trading.service.syspara.SysparaService;
+import com.yami.trading.service.user.UserService;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.text.DecimalFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+
+/**
+ * 矿池订单
+ */
+@RestController
+@CrossOrigin
+public class MinerOrderController {
+
+ private Logger logger = LogManager.getLogger(MinerOrderController.class);
+ @Autowired
+ protected MinerOrderService minerOrderService;
+ @Autowired
+ protected MinerService minerService;
+ @Autowired
+ protected UserService partyService;
+ @Autowired
+ protected SessionTokenService sessionTokenService;
+ @Autowired
+ protected SysparaService sysparaService;
+
+ private final String action = "api/minerOrder!";
+
+ /**
+ * 矿池订单 列表
+ */
+ @RequestMapping(action + "list.action")
+ public ResultObject list(HttpServletRequest request) {
+
+ ResultObject resultObject = new ResultObject();
+// resultObject = readSecurityContextFromSession(resultObject);
+// if (!"0".equals(resultObject.getCode())) {
+// return resultObject;
+// }
+ try {
+ List<Map<String, Object>> datas = null;
+// String partyId = getLoginPartyId();
+ String partyId = SecurityUtils.getCurrentUserId();
+// DecimalFormat df = new DecimalFormat("#.##");
+ if (StringUtils.isNullOrEmpty(partyId)) {
+ resultObject.setData(datas);
+ resultObject.setCode("0");
+ return resultObject;
+ }
+
+ // 状态。0.正常赎回, 1 托管中 ,2提前赎回 (违约)3.取消
+ String state = request.getParameter("state");
+ String page_no = request.getParameter("page_no");
+ int pageNo = 1;
+ if (StringUtils.isNotEmpty(page_no)) {
+ pageNo = Integer.valueOf(page_no);
+ }
+
+ datas = minerOrderService.pagedQuery(pageNo, 40, partyId, state).getRecords();
+
+ for (Map<String, Object> data : datas) {
+ int intervalDaysByTwoDate = 0;
+ if (null == data.get("stop_time")) {
+ if ("0" != data.get("cycle_close")) {
+ String can_close_time = DateUtils
+ .format(DateUtils.addDay(DateUtils.toDate(data.get("create_time").toString()),
+ new Double(data.get("cycle_close").toString()).intValue()),
+ DateUtils.DF_yyyyMMdd);
+ intervalDaysByTwoDate = DateUtils.getIntervalDaysByTwoDate(DateUtils.toDate(can_close_time),
+ new Date());
+ }
+ } else {
+ intervalDaysByTwoDate = DateUtils.getIntervalDaysByTwoDate(
+ DateUtils.toDate(data.get("stop_time").toString()), new Date());
+ }
+ if (intervalDaysByTwoDate < 0) {
+ intervalDaysByTwoDate = 0;
+ }
+ data.put("days", intervalDaysByTwoDate);
+ DecimalFormat df = new DecimalFormat("#.##");
+ data.put("profit", df.format(data.get("profit")));
+ data.put("test", null != data.get("test") && "Y".equals(data.get("test").toString()));
+ data.put("can_close", intervalDaysByTwoDate <= 0);
+
+ data.put("buyCurrency", "usdt");
+ data.put("outputCurrency", "usdt");
+
+ if ((boolean) data.get("test")) {
+ Double minerTestProfit = sysparaService.find("miner_test_profit").getDouble();
+ data.put("daily_profit", minerTestProfit);
+ data.put("daily_rate", minerTestProfit);
+ data.put("cycle", data.get("cycle"));
+ data.put("all_rate", Arith.mul(minerTestProfit, Integer.valueOf(data.get("cycle").toString())));
+ } else {
+ double dailyProfitRate = Arith.mul(Double.valueOf(data.get("daily_rate").toString()), 0.01d);
+ double dailyProfitAmount = Arith.mul(dailyProfitRate, Double.valueOf(data.get("amount").toString()));
+ String dailyProfit = df.format(dailyProfitAmount);
+ // 当日收益
+ data.put("daily_profit", dailyProfit);
+ data.put("daily_rate", data.get("daily_rate"));
+ // 这里的周期,体验矿机是周期,其他矿机是解锁周期(到期后需手动解锁)
+ data.put("cycle", data.get("cycle_close"));
+ double all_rate = Arith.mul(30, Double.valueOf(data.get("daily_rate").toString()));
+ data.put("all_rate", df.format(all_rate));
+ }
+ }
+ resultObject.setData(datas);
+ } catch (BusinessException e) {
+ resultObject.setCode("1");
+ resultObject.setMsg(e.getMessage());
+ logger.error("BusinessException:", e);
+ } catch (Exception e) {
+ resultObject.setCode("1");
+ resultObject.setMsg("程序错误");
+ logger.error("error:", e);
+ }
+ return resultObject;
+ }
+
+ /**
+ * 矿机收益统计
+ */
+ @RequestMapping(action + "listSum.action")
+ public Object listSum() {
+ ResultObject resultObject = new ResultObject();
+ try {
+// String partyId = getLoginPartyId();
+ String partyId = SecurityUtils.getCurrentUserId();
+ List<Map<String, Object>> data = minerOrderService.findByState(partyId, null);
+ MinerOrder order;
+ Map<String, Object> one;
+ List<Miner> miners = minerService.findAll();
+ Miner miner = new Miner();
+ Map<String, Object> map = new HashMap<String, Object>();
+
+ // 金额总数
+ double amount_sum = 0;
+ // 预计今日盈利
+ double today_profit = 0;
+ // 已获收益
+ double aready_profit = 0;
+ // 订单数
+ double order_sum = 0;
+ // 金额总数 换算U
+ double amountSumValue = 0;
+ // 今日盈利 换算U
+ double todayProfitValue = 0;
+ // 已获收益 换算U
+ double areadyProfitValue = 0;
+
+ String buyCurrency = "";
+ String outputCurrency = "";
+
+ Double miner_test_profit = sysparaService.find("miner_test_profit").getDouble();
+
+ if (data != null) {
+ for (int i = 0; i < data.size(); i++) {
+ one = data.get(i);
+
+ order = JSON.parseObject(JSON.toJSONString(one), MinerOrder.class);
+
+ if ("1".equals(order.getState())) {
+ order_sum = Arith.add(order_sum, 1d);
+ amount_sum = Arith.add(amount_sum, (Double) order.getAmount());
+ }
+ aready_profit = Arith.add(aready_profit, (Double) order.getProfit());
+ for (int j = 0; j < miners.size(); j++) {
+ miner = miners.get(j);
+ if (miner.getUuid().equals(order.getMiner_id()) && "1".equals(order.getState())) {
+ if (miner.getTest().equals("Y")) {
+ today_profit = Arith.add(today_profit, miner_test_profit);
+ } else {
+ double miner_profit = Arith.mul(miner.getDaily_rate(), 0.01d);
+ double get_profit = Arith.mul(miner_profit, (Double) order.getAmount());
+ today_profit = Arith.add(today_profit, get_profit);
+ break;
+ }
+ }
+ }
+ }
+ }
+ DecimalFormat df = new DecimalFormat("#.##");
+ map.put("amount_sum", df.format(amount_sum));
+ map.put("amountSumValue", df.format(amountSumValue));
+ map.put("today_profit", df.format(today_profit));
+ map.put("aready_profit", df.format(aready_profit));
+ map.put("order_sum", order_sum);
+ map.put("buyCurrency", buyCurrency);
+ map.put("outputCurrency", outputCurrency);
+ map.put("areadyProfitValue", df.format(areadyProfitValue));
+ map.put("todayProfitValue", df.format(todayProfitValue));
+ resultObject.setData(map);
+ resultObject.setCode("0");
+ } catch (BusinessException e) {
+ resultObject.setCode("1");
+ resultObject.setMsg(e.getMessage());
+ } catch (Exception e) {
+ resultObject.setCode("1");
+ resultObject.setMsg("程序错误");
+ logger.error("error:", e);
+ }
+ return resultObject;
+ }
+
+ /**
+ * 矿池订单 详情
+ */
+ @RequestMapping(action + "get.action")
+ public Object get(HttpServletRequest request) {
+ ResultObject resultObject = new ResultObject();
+// resultObject = readSecurityContextFromSession(resultObject);
+// if (!"0".equals(resultObject.getCode())) {
+// return resultObject;
+// }
+ try {
+ String order_no = request.getParameter("order_no");
+ MinerOrder data = minerOrderService.findByOrder_no(order_no);
+
+ resultObject.setData(bulidData(data));
+ resultObject.setCode("0");
+ } catch (BusinessException e) {
+ resultObject.setCode("1");
+ resultObject.setMsg(e.getMessage());
+ logger.error("BusinessException:", e);
+ } catch (Exception e) {
+ resultObject.setCode("1");
+ resultObject.setMsg("程序错误");
+ logger.error("error:", e);
+ }
+ return resultObject;
+ }
+
+ /**
+ * 创建买入矿机订单
+ */
+ @RequestMapping(action + "open.action")
+ public Object open(HttpServletRequest request) {
+ ResultObject resultObject = new ResultObject();
+// resultObject = readSecurityContextFromSession(resultObject);
+// if (!"0".equals(resultObject.getCode())) {
+// return resultObject;
+// }
+// String partyId = this.getLoginPartyId();
+ String partyId = SecurityUtils.getCurrentUserId();
+ try {
+ String session_token = request.getParameter("session_token");
+ String minerId = request.getParameter("minerId");
+ String amount = request.getParameter("amount");
+
+ String object = this.sessionTokenService.cacheGet(session_token);
+ this.sessionTokenService.del(session_token);
+ if ((!partyId.equals(object))) {
+ resultObject.setCode("1");
+ resultObject.setMsg("请稍后再试");
+ return resultObject;
+ }
+
+ User party = this.partyService.cacheUserBy(partyId);
+// if (!party.getEnabled()) {
+// resultObject.setCode("506");
+// resultObject.setMsg(error);
+// return resultObject;
+// }
+
+ MinerOrder order = new MinerOrder();
+ order.setPartyId(partyId);
+ order.setMinerId(minerId);
+ order.setAmount(Double.valueOf(amount));
+ order.setOrder_no(DateUtil.getToday("yyMMddHHmmss") + RandomUtil.getRandomNum(8));
+ order.setState("1");
+
+ this.minerOrderService.saveCreateNew(order, false);
+
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("order_no", order.getOrder_no());
+ resultObject.setData(map);
+ resultObject.setCode("0");
+ } catch (BusinessException e) {
+ resultObject.setCode("1");
+ resultObject.setMsg(e.getMessage());
+ } catch (Exception e) {
+ resultObject.setCode("1");
+ resultObject.setMsg("程序错误");
+ logger.error("error:", e);
+ }
+ return resultObject;
+ }
+
+ /**
+ * 获取订单
+ */
+ @RequestMapping(action + "getOpen.action")
+ public Object getOpen(HttpServletRequest request) throws IOException {
+ ResultObject resultObject = new ResultObject();
+// resultObject = readSecurityContextFromSession(resultObject);
+// if (!"0".equals(resultObject.getCode())) {
+// return resultObject;
+// }
+ try {
+ String minerId = request.getParameter("minerId");
+ String amount_temp = request.getParameter("amount");
+ Miner miner = minerService.findById(minerId);
+ if (StringUtils.isNullOrEmpty(amount_temp)
+ || !StringUtils.isDouble(amount_temp)
+ || Double.valueOf(amount_temp) < 0) {
+ throw new BusinessException("金额错误");
+ }
+
+ DecimalFormat df = new DecimalFormat("#.##");
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("miner_test", miner.getTest());
+ map.put("miner_name", miner.getName());
+ map.put("miner_name_en", miner.getName_en());
+ map.put("miner_name_cn", miner.getName_cn());
+ map.put("buyCurrenc", miner.getBuy_currency());
+ map.put("outputCurrency", miner.getOutput_currency());
+// String partyId = getLoginPartyId();
+ String partyId = SecurityUtils.getCurrentUserId();
+ if (!StringUtils.isNullOrEmpty(partyId)) {
+ String session_token = sessionTokenService.savePut(partyId);
+ map.put("session_token", session_token);
+ }
+
+ Date date = new Date();
+ map.put("create_time", date);
+ Calendar calendar = new GregorianCalendar();
+ calendar.setTime(date);
+ // 把日期往后增加一天.整数往后推
+ calendar.add(calendar.DATE, 1);
+ date = calendar.getTime();
+
+ // 起息时间
+ // 根据对外展示时区设置,修改时间
+ Date showEarnTime = DateTimeTools.transferToShowTime(date);
+ map.put("earn_time", DateUtils.format(showEarnTime, DateUtils.DF_yyyyMMdd));
+
+ if (miner.getTest().equals("Y")) {
+ map.put("amount", 0);
+ calendar.add(calendar.DATE, miner.getCycle());
+ date = calendar.getTime();
+ // 系统时区时间
+ Date localStopTime = DateUtils.addDay(date, miner.getCycle());
+ // 根据对外展示时区设置,修改时间
+ Date showStopTime = DateTimeTools.transferToShowTime(localStopTime);
+ map.put("stop_time", DateUtils.format(showStopTime, DateUtils.DF_yyyyMMdd));
+ Double minerTestProfit = sysparaService.find("miner_test_profit").getDouble();
+ map.put("daily_rate", minerTestProfit);
+ map.put("profit_may", String.valueOf(Arith.mul(minerTestProfit, miner.getCycle())));
+ map.put("cycle", miner.getCycle());
+ map.put("all_rate", Arith.mul(minerTestProfit, miner.getCycle()));
+ } else {
+ double amount = Double.valueOf(amount_temp);
+ map.put("amount", amount);
+ map.put("stop_time", null);
+ map.put("daily_rate", miner.getDaily_rate());
+ double rate = Arith.mul(miner.getDaily_rate(), 0.01d);
+ map.put("profit_may", String.valueOf(df.format(Arith.mul(amount, Arith.mul(rate, 30d)))));
+ map.put("cycle", miner.getCycle_close());
+ double all_rate = Arith.mul(30d, miner.getDaily_rate());
+ map.put("all_rate", df.format(all_rate));
+ }
+ map.put("investment_min", miner.getInvestment_min());
+ map.put("minerId", minerId);
+ map.put("order_no", DateUtil.getToday("yyMMddHHmmss") + RandomUtil.getRandomNum(8));
+ map.put("test", miner.getTest());
+
+ resultObject.setData(map);
+ resultObject.setCode("0");
+ } catch (BusinessException e) {
+ resultObject.setCode("1");
+ resultObject.setMsg(e.getMessage());
+ logger.error("BusinessException:", e);
+ } catch (Exception e) {
+ resultObject.setCode("1");
+ resultObject.setMsg("程序错误");
+ logger.error("error:", e.fillInStackTrace());
+ }
+ return resultObject;
+ }
+
+
+ /**
+ * 赎回订单
+ */
+ @RequestMapping(action + "closOrder.action")
+ public Object closOrder(HttpServletRequest request) throws IOException {
+ ResultObject resultObject = new ResultObject();
+// resultObject = readSecurityContextFromSession(resultObject);
+// if (!"0".equals(resultObject.getCode())) {
+// return resultObject;
+// }
+ try {
+ String order_no = request.getParameter("order_no");
+ CloseDelayThread lockDelayThread = new CloseDelayThread(order_no, minerOrderService);
+ Thread t = new Thread(lockDelayThread);
+ t.start();
+
+ } catch (BusinessException e) {
+ resultObject.setCode("1");
+ resultObject.setMsg(e.getMessage());
+ } catch (Exception e) {
+ resultObject.setCode("1");
+ resultObject.setMsg("程序错误");
+ logger.error("error:", e.fillInStackTrace());
+ }
+ return resultObject;
+ }
+
+ /**
+ * 新线程处理,直接拿到订单锁处理完成后退出
+ */
+ public class CloseDelayThread implements Runnable {
+ private String orderNo;
+ private MinerOrderService minerOrderService;
+
+ public void run() {
+ try {
+ // 提前赎回理财产品需要支付违约金
+ MinerOrder order = minerOrderService.findByOrder_no(orderNo);
+
+ Miner miner = minerService.findById(order.getMiner_id());
+
+ // 取时间
+ Date date_now = new Date();
+ double last_days = daysBetween(order.getCreate_time(), date_now);
+ if ("1".equals(order.getState()) && last_days >= miner.getCycle_close()) {
+ // 解锁,不扣违约金
+ double default_money = 0;
+ order.setState("2");
+ order.setProfit(Arith.sub(order.getProfit(), default_money));
+ this.minerOrderService.saveClose(order);
+ }
+
+ } catch (Exception e) {
+ logger.error("error:", e);
+ }
+
+ }
+
+ public CloseDelayThread(String orderNo, MinerOrderService minerOrderService) {
+ this.orderNo = orderNo;
+ this.minerOrderService = minerOrderService;
+ }
+
+ }
+
+ protected Map<String, Object> bulidData(MinerOrder order) throws ParseException {
+ System.out.println("bulidData => " + order);
+ Miner miner = new Miner();
+ miner = minerService.findById(order.getMiner_id());
+ System.out.println("miner => " + miner);
+
+ DecimalFormat df = new DecimalFormat("#.##");
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("miner_name", miner.getName());
+ map.put("miner_name_en", miner.getName_en());
+ map.put("miner_name_cn", miner.getName_cn());
+ Double miner_test_profit = sysparaService.find("miner_test_profit").getDouble();
+
+ map.put("daily_rate", miner.getTest().equals("Y") ? miner_test_profit : miner.getDaily_rate());
+ Date create_time = order.getCreate_time();
+ map.put("create_timeStr", create_time);
+ map.put("close_timeStr", order.getClose_time());
+ if (miner.getTest().equals("Y")) {
+ // 根据对外展示时区设置,修改时间
+ Date showStopTime = DateTimeTools.transferToShowTime(order.getStop_time());
+ map.put("stop_timeStr", DateUtils.format(showStopTime, DateUtils.DF_yyyyMMdd));
+ } else {
+ map.put("stop_timeStr", null);
+ }
+
+ // 根据对外展示时区设置,修改时间
+ Date showEarnTime = DateTimeTools.transferToShowTime(order.getEarn_time());
+ map.put("earn_timeStr", DateUtils.format(showEarnTime, DateUtils.DF_yyyyMMdd));
+
+ //System.out.println("getTest => "+miner.getTest().equals("Y") );
+ //System.out.println("stop_timeStr => "+DateUtils.format(order.getStop_time(), DateUtils.DF_yyyyMMdd));
+
+ Date date_now = new Date();// 取时间
+ int daysBetween = order.getStop_time() == null ? 0 : daysBetween(date_now, order.getStop_time());
+ daysBetween = Math.max(daysBetween, 0);
+ map.put("days", daysBetween);
+ int last_days = daysBetween(create_time, date_now);
+ map.put("can_close", last_days >= miner.getCycle_close());
+ double rate = Arith.mul(miner.getDaily_rate(), 0.01d);
+ map.put("profit_may", miner.getTest().equals("Y") ? String.valueOf(Arith.mul(miner_test_profit, miner.getCycle()))
+ : String.valueOf(Arith.mul(order.getAmount(), Arith.mul(rate, 30d))));
+ map.put("order_no", order.getOrder_no());
+ map.put("amount", order.getAmount());
+ // map.put("cycle", miner.getCycle());
+ map.put("id", order.getOrder_no());
+
+ map.put("state", order.getState());
+ map.put("profit", order.getProfit());
+
+ int cycle = miner.getTest().equals("Y") ? miner.getCycle() : miner.getCycle_close();
+ map.put("cycle", cycle);
+ double all_rate = Arith.mul(30, miner.getDaily_rate());
+ map.put("all_rate", miner.getTest().equals("Y") ? Arith.mul(miner_test_profit, miner.getCycle()) : df.format(all_rate));
+
+ map.put("test", miner.getTest());
+ map.put("buyCurrency", miner.getBuy_currency());
+ map.put("outputCurrency", miner.getOutput_currency());
+
+ if ("1".equals(order.getState())) {
+
+ map.put("profit", order.getProfit());
+
+ map.put("default_amount", 0);
+ map.put("principal_amount", 0);
+ }
+ if ("2".equals(order.getState())) {
+ map.put("profit", 0);
+ map.put("default_amount", 0);
+ map.put("principal_amount", df.format(order.getAmount()));
+ }
+ if ("0".equals(order.getState())) {// 正常
+ map.put("profit", order.getProfit());
+ map.put("default_amount", 0);
+ map.put("principal_amount", df.format(order.getAmount()));
+ }
+
+ return map;
+
+ }
+
+ public static int daysBetween(Date smdate, Date bdate) throws ParseException {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ smdate = sdf.parse(sdf.format(smdate));
+ bdate = sdf.parse(sdf.format(bdate));
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(smdate);
+ long time1 = cal.getTimeInMillis();
+ cal.setTime(bdate);
+ long time2 = cal.getTimeInMillis();
+ long between_days = (time2 - time1) / (1000 * 3600 * 24);
+
+ return Integer.parseInt(String.valueOf(between_days));
+ }
+
+
+}
diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/AdminMinerService.java b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/AdminMinerService.java
new file mode 100644
index 0000000..9c33584
--- /dev/null
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/AdminMinerService.java
@@ -0,0 +1,12 @@
+package com.yami.trading.admin.controller.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+public interface AdminMinerService {
+
+ /**
+ * 代理分页查询
+ *
+ */
+ public Page pagedQuery(int pageNo, int pageSize, String name_para);
+}
diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/MinerRedisKeys.java b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/MinerRedisKeys.java
new file mode 100644
index 0000000..d4e1937
--- /dev/null
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/MinerRedisKeys.java
@@ -0,0 +1,36 @@
+package com.yami.trading.admin.controller.service;
+
+public class MinerRedisKeys {
+
+ /**
+ * 矿机,id做key
+ */
+ public final static String MINER_ID = "MINER_ID_";
+
+
+ /**
+ * 获取所有的矿机
+ */
+ public final static String MINER_MAP = "MINER_MAP_";
+
+ /**
+ * 矿机订单,订单号做key
+ */
+ public final static String MINER_ORDER_ORDERNO = "MINER_ORDER_ORDERNO_";
+
+ /**
+ * 矿机订单,查询partyid的map
+ */
+ public final static String MINER_ORDER_PARTY_ID = "MINER_ORDER_PARTY_ID_";
+
+ /**
+ * 矿机总资产,partyid做key
+ */
+ public final static String MINER_ASSETS_PARTY_ID = "MINER_ASSETS_PARTY_ID_";
+
+ /**
+ * 矿机订单异步提交
+ */
+ public final static String MINER_ORDER = "MINER_ORDER_";
+
+}
diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/MinerService.java b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/MinerService.java
index 4a9e893..6aafbc7 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/MinerService.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/MinerService.java
@@ -1,23 +1,23 @@
package com.yami.trading.admin.controller.service;
-import com.yami.trading.bean.model.Miner;
-
import java.util.List;
+import java.util.Map;
public interface MinerService {
- // 增加矿机
- boolean addMiner(Miner miner);
+ public boolean save(Miner miner);
- // 删除矿机
- boolean deleteMiner(int id);
+ public void updateA(Miner miner);
- // 更新矿机
- boolean updateMiner(Miner miner);
+ public Miner findById(String id);
- // 获取矿机详情
- Miner getMiner(int id);
+ public void delete(String id);
- // 获取所有矿机
- List<Miner> getAllMiners();
+ public List<Miner> findAll();
+
+ public List<Miner> findAllState_1();
+
+ public Miner cacheById(String id);
+
+ public Map<String,Object> getBindOne(Miner miner);
}
\ No newline at end of file
diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/impl/AdminMinerServiceImpl.java b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/impl/AdminMinerServiceImpl.java
new file mode 100644
index 0000000..f8c87fe
--- /dev/null
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/impl/AdminMinerServiceImpl.java
@@ -0,0 +1,40 @@
+package com.yami.trading.admin.controller.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yami.trading.admin.controller.service.AdminMinerService;
+import com.yami.trading.admin.dao.MinerMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@Transactional
+public class AdminMinerServiceImpl extends ServiceImpl<MinerMapper, Miner> implements AdminMinerService {
+// protected PagedQueryDao pagedQueryDao;
+
+ public Page pagedQuery(int pageNo, int pageSize, String name_para) {
+// StringBuffer queryString = new StringBuffer(
+// " SELECT miner.UUID id,miner.NAME name,miner.NAME_EN name_en,miner.NAME_CN name_cn,miner.IMG img,miner.CYCLE cycle,miner.CYCLE_CLOSE cycle_close, "
+// + " miner.SHOW_DAILY_RATE show_daily_rate ,miner.DAILY_RATE daily_rate ,miner.STATE state,miner.ON_SALE on_sale,miner.TEST test,"
+// + " miner.INVESTMENT_MIN investment_min,miner.INVESTMENT_MAX investment_max ");
+// queryString.append(" FROM T_MINER miner WHERE 1 = 1 ");
+// Map<String, Object> parameters = new HashMap<>();
+// if (!StringUtils.isNullOrEmpty(name_para)) {
+// queryString.append(" and miner.NAME like:name ");
+// parameters.put("name", "%" + name_para + "%");
+// }
+// queryString.append(" ORDER BY miner.INVESTMENT_MIN+0 ASC ");
+
+// Page page = this.pagedQueryDao.pagedQuerySQL(pageNo, pageSize, queryString.toString(), parameters);
+// return page;
+
+ Page page = new Page(pageNo,pageSize);
+ this.baseMapper.pagedQuery(page,name_para);
+
+ return page;
+ }
+
+// public void setPagedQueryDao(PagedQueryDao pagedQueryDao) {
+// this.pagedQueryDao = pagedQueryDao;
+// }
+}
diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/impl/MinerServiceImpl.java b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/impl/MinerServiceImpl.java
index 130051c..5f7f7a4 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/impl/MinerServiceImpl.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/service/impl/MinerServiceImpl.java
@@ -1,43 +1,212 @@
package com.yami.trading.admin.controller.service.impl;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yami.trading.admin.controller.service.MinerRedisKeys;
import com.yami.trading.admin.controller.service.MinerService;
import com.yami.trading.admin.dao.MinerMapper;
-import com.yami.trading.bean.model.Miner;
+import com.yami.trading.bean.data.domain.Realtime;
+import com.yami.trading.common.exception.BusinessException;
+import com.yami.trading.common.util.Arith;
+import com.yami.trading.service.data.DataService;
+import com.yami.trading.service.syspara.SysparaService;
+import org.apache.commons.lang3.StringUtils;
+
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
-import java.util.List;
-/**
- * @program: trading-order-master
- * @description:
- * @create: 2025-03-10 14:27
- **/
@Service
+@Transactional
public class MinerServiceImpl extends ServiceImpl<MinerMapper, Miner> implements MinerService {
- @Override
- public boolean addMiner(Miner miner) {
- return this.save(miner);
+ // protected RedisHandler redisHandler;
+ @Autowired
+ private RedisTemplate redisTemplate;
+ @Autowired
+ protected SysparaService sysparaService;
+ @Autowired
+ protected DataService dataService;
+
+ public Miner cacheById(String id) {
+ return (Miner) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_ID + id);
}
- @Override
- public boolean deleteMiner(int id) {
- return this.removeById(id);
+ public boolean save(Miner entity) {
+
+ this.save(entity);
+
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ID + entity.getUuid().toString(), entity);
+
+ Map<String, Miner> map = (Map<String, Miner>) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_MAP);
+ if (map == null) {
+ map = new ConcurrentHashMap<String, Miner>();
+ }
+ map.put(entity.getUuid().toString(), entity);
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_MAP, map);
+ return true;
}
- @Override
- public boolean updateMiner(Miner miner) {
- return this.updateById(miner);
+ public void updateA(Miner entity) {
+ if(entity == null){
+ System.out.println("entity is null");
+ }
+ this.updateById(entity);
+
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ID + entity.getUuid().toString(), entity);
+
+ Map<String, Miner> map = (Map<String, Miner>) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_MAP);
+ if (map == null) {
+ map = new ConcurrentHashMap<String, Miner>();
+ }
+ map.put(entity.getUuid().toString(), entity);
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_MAP, map);
}
- @Override
- public Miner getMiner(int id) {
- return this.getById(id);
+ public void delete(String id) {
+ Miner entity = findById(id);
+ this.delete(entity.getUuid());
+
+
+ redisTemplate.delete(MinerRedisKeys.MINER_ID + entity.getUuid().toString());
+ Map<String, Miner> map = (Map<String, Miner>) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_MAP);
+ if (map != null && !map.isEmpty()) {
+ map.remove(entity.getUuid().toString());
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_MAP, map);
+ }
}
- @Override
- public List<Miner> getAllMiners() {
- return this.list();
+ public Miner findById(String id) {
+ return (Miner) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_ID + id);
}
+
+ public List<Miner> findAll() {
+ Map<String, Miner> map = (Map<String, Miner>) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_MAP);
+ if (map != null) {
+ List<Miner> list = new ArrayList<>(map.values());
+ list.sort(new Miner());
+ return list;
+ }
+ return new ArrayList<>();
+ }
+
+ public List<Miner> findAllState_1() {
+ List<Miner> list = new ArrayList<Miner>();
+ for (Miner miner : findAll()) {
+ if ("1".equals(miner.getState())) {
+ list.add(miner);
+ }
+ }
+ return list;
+ }
+
+ public Map<String, Object> getBindOne(Miner miner) {
+ Map<String, Object> result = new HashMap<String, Object>();
+
+ result.put("id", miner.getUuid());
+ result.put("name", miner.getName());
+ result.put("name_en", miner.getName_en());
+ result.put("name_cn", miner.getName_cn());
+ result.put("daily_rate", miner.getDaily_rate());
+ result.put("investment_min", miner.getInvestment_min());
+ result.put("investment_max", miner.getInvestment_max());
+ result.put("state", miner.getState());
+ result.put("on_sale", miner.getOn_sale());
+ result.put("test", miner.getTest());
+ Double miner_test_profit = sysparaService.find("miner_test_profit").getDouble();
+ if (miner.getTest().equals("Y")) {
+ result.put("all_rate", Arith.mul(miner_test_profit, miner.getCycle()));
+ result.put("cycle", miner.getCycle());
+ result.put("daily_rate", miner_test_profit);
+ } else {
+ result.put("all_rate", Arith.mul(miner.getDaily_rate(), 30));
+ result.put("cycle", miner.getCycle_close());
+ }
+
+ // 根据产生的收益转化成指定的币种
+ String miner_profit_symbol = sysparaService.find("miner_profit_symbol").getSvalue();
+ // 矿机购买时使用的币种,则产生
+ String miner_buy_symbol = sysparaService.find("miner_buy_symbol").getSvalue();
+ double symbol_profit = miner.getTest().equals("Y") ? miner_test_profit
+ : Arith.div(Arith.mul(100, miner.getDaily_rate()), 100);// 100为单位的币种收益
+ // 收益转化成U
+ if (StringUtils.isNotEmpty(miner_buy_symbol) && !"usdt".equalsIgnoreCase(miner_buy_symbol)) {
+ List<Realtime> realtime_list = this.dataService.realtime(miner_buy_symbol);
+ Realtime realtime = null;
+ if (realtime_list.size() > 0) {
+ realtime = realtime_list.get(0);
+ } else {
+ throw new BusinessException("行情获取异常,稍后再试");
+ }
+ symbol_profit = Arith.mul(symbol_profit, realtime.getClose().doubleValue());
+ }
+
+ if (StringUtils.isNotEmpty(miner_profit_symbol) && !"usdt".equalsIgnoreCase(miner_profit_symbol)) {
+ List<Realtime> realtime_list = this.dataService.realtime(miner_profit_symbol);
+ Realtime realtime = null;
+ if (realtime_list.size() > 0) {
+ realtime = realtime_list.get(0);
+ } else {
+ throw new BusinessException("行情获取异常,稍后再试");
+ }
+ symbol_profit = Arith.div(symbol_profit, realtime.getClose().doubleValue());
+ result.put("symbol_profit", symbol_profit);
+ } else {
+ result.put("symbol_profit", symbol_profit);
+ }
+ result.put("miner_profit_symbol",
+ StringUtils.isEmpty(miner_profit_symbol) ? "USDT" : miner_profit_symbol.toUpperCase());
+ result.put("img", "https://trading-order-test.s3.amazonaws.com/common/2023-09-16/783a1a14-f6ad-48e3-adb4-6623cca57480IMG_1558.PNG");
+ // 基础信息
+ result.put("algorithm", miner.getAlgorithm());
+ result.put("computing_power", miner.getComputing_power());
+ result.put("computing_power_unit", miner.getComputing_power_unit());
+ result.put("power", miner.getPower());
+ result.put("product_factory", miner.getProduct_factory());
+ result.put("product_size", miner.getProduct_size());
+ result.put("weight", miner.getWeight());
+ result.put("work_temperature_min", miner.getWork_temperature_min());
+ result.put("work_temperature_max", miner.getWork_temperature_max());
+ result.put("work_humidity_min", miner.getWork_humidity_min());
+ result.put("work_humidity_max", miner.getWork_humidity_max());
+ result.put("internet", miner.getInternet());
+
+ result.put("buy_currency", miner.getBuy_currency());
+ result.put("output_currency", miner.getOutput_currency());
+
+ return result;
+ }
+
+// public void setRedisHandler(RedisHandler redisHandler) {
+// this.redisHandler = redisHandler;
+// }
+
+ public void setSysparaService(SysparaService sysparaService) {
+ this.sysparaService = sysparaService;
+ }
+
+ public void setDataService(DataService dataService) {
+ this.dataService = dataService;
+ }
+
+// public List<Finance> findAll_2() {
+//
+// LambdaQueryWrapper<Miner> queryWrapper = new LambdaQueryWrapper<Miner>()
+// .eq(Miner::getState,state).eq(FinanceOrder::getPartyId, partyId);
+// list = this.getBaseMapper().selectList(queryWrapper);
+//
+// Map<String, Finance> cacheMap = (Map<String, Finance>) redisTemplate.opsForValue().get(FinanceRedisKeys.FINANCE_MAP);
+// if (cacheMap != null && !cacheMap.isEmpty()) {
+// return new ArrayList<Finance>(cacheMap.values());
+// }
+// return new ArrayList<Finance>();
+// }
}
diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/dao/MinerMapper.java b/trading-order-admin/src/main/java/com/yami/trading/admin/dao/MinerMapper.java
index 1381114..abc91f8 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/admin/dao/MinerMapper.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/dao/MinerMapper.java
@@ -1,8 +1,9 @@
package com.yami.trading.admin.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.yami.trading.bean.model.Miner;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
/**
* @program: trading-order-master
@@ -11,4 +12,5 @@
**/
@Mapper
public interface MinerMapper extends BaseMapper<Miner> {
+ Page pagedQuery(Page page, @Param("name_para") String name_para);
}
\ No newline at end of file
diff --git a/trading-order-bean/src/main/java/com/yami/trading/bean/miner/Miner.java b/trading-order-bean/src/main/java/com/yami/trading/bean/miner/Miner.java
new file mode 100644
index 0000000..a697389
--- /dev/null
+++ b/trading-order-bean/src/main/java/com/yami/trading/bean/miner/Miner.java
@@ -0,0 +1,361 @@
+package com.yami.trading.bean.miner;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.yami.trading.common.domain.UUIDEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Comparator;
+
+/**
+ * 矿机
+ *
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("t_miner")
+public class Miner extends UUIDEntity implements Comparator<Miner> {
+
+ private static final long serialVersionUID = 1639941028310043811L;
+
+ /**
+ * 矿机名称(简体中文)
+ */
+ private String name;
+
+ /**
+ * 矿机名称(英文)
+ */
+ private String name_en;
+ /**
+ * 矿机名称(繁体)
+ */
+ private String name_cn;
+
+ /**
+ * 周期-天数(现做矿机等级判定)
+ */
+ private int cycle;
+ /**
+ * ----可解锁周期-- 截止后方可解锁 CYCLE_CLOSE
+ */
+ @TableField("CYCLE_CLOSE")
+ private int cycle_close;
+
+ /**
+ * 日利率(%)
+ */
+ private double daily_rate;
+ /**
+ * 展示日利率(%)
+ */
+ private double show_daily_rate;
+
+ /**
+ * 最低投资金额(USDT)
+ */
+ private double investment_min;
+ /**
+ * 最高投资金额(USDT)
+ */
+ private double investment_max;
+
+ /**
+ * 上下架。0 下架, 1 上架,
+ */
+ private String state = "0";
+ /**
+ * 是否自主购买 0需管理员手动增加,1可自行购买
+ */
+ private String on_sale = "0";
+ /**
+ * ---是否是体验产品
+ */
+ private String test = "N";
+
+ /**
+ * 适用算法
+ */
+ private String algorithm;
+ /**
+ * 算力
+ */
+ private double computing_power;
+ /**
+ * 算力单位
+ */
+ private String computing_power_unit;
+ /**
+ * 功耗
+ */
+ private double power;
+ /**
+ * 生产厂家
+ */
+ private String product_factory;
+ /**
+ * 外箱尺寸
+ */
+ private String product_size;
+ /**
+ * 整机重量
+ */
+ private double weight;
+ /**
+ * 工作温度区间(最小值)
+ */
+ private double work_temperature_min;
+ /**
+ * 工作温度区间(最大值)
+ */
+ private double work_temperature_max;
+ /**
+ * 工作湿度区间(最小值)
+ */
+ private double work_humidity_min;
+ /**
+ * 工作湿度区间(最大值)
+ */
+ private double work_humidity_max;
+ /**
+ * 网络连接
+ */
+ private String internet;
+ /**
+ * 基础计息金额
+ */
+ private double base_compute_amount;
+
+ @Getter
+ private String img;
+
+ @Getter
+ @Setter
+ private int unlock_user_need;
+
+ /**
+ * 矿机购买币种
+ */
+ @Getter
+ @Setter
+ private String buy_currency = "usdt";
+
+ /**
+ * 矿机购买币种
+ */
+ @Getter
+ @Setter
+ private String output_currency = "usdt";
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getCycle() {
+ return cycle;
+ }
+
+ public void setCycle(int cycle) {
+ this.cycle = cycle;
+ }
+
+ public double getDaily_rate() {
+ return daily_rate;
+ }
+
+ public void setDaily_rate(double daily_rate) {
+ this.daily_rate = daily_rate;
+ }
+
+ public double getInvestment_min() {
+ return investment_min;
+ }
+
+ public void setInvestment_min(double investment_min) {
+ this.investment_min = investment_min;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public String getName_en() {
+ return name_en;
+ }
+
+ public void setName_en(String name_en) {
+ this.name_en = name_en;
+ }
+
+ public String getName_cn() {
+ return name_cn;
+ }
+
+ public void setName_cn(String name_cn) {
+ this.name_cn = name_cn;
+ }
+
+ public String getTest() {
+ return test;
+ }
+
+ public void setTest(String test) {
+ this.test = test;
+ }
+
+ public String getOn_sale() {
+ return on_sale;
+ }
+
+ public void setOn_sale(String on_sale) {
+ this.on_sale = on_sale;
+ }
+
+ public double getInvestment_max() {
+ return investment_max;
+ }
+
+ public void setInvestment_max(double investment_max) {
+ this.investment_max = investment_max;
+ }
+
+ public double getShow_daily_rate() {
+ return show_daily_rate;
+ }
+
+ public void setShow_daily_rate(double show_daily_rate) {
+ this.show_daily_rate = show_daily_rate;
+ }
+
+ public int compare(Miner o1, Miner o2) {
+ return o1.getInvestment_min() < o2.getInvestment_min() ? -1 : 1;
+ }
+
+ public int getCycle_close() {
+ return cycle_close;
+ }
+
+ public void setCycle_close(int cycle_close) {
+ this.cycle_close = cycle_close;
+ }
+
+ public String getAlgorithm() {
+ return algorithm;
+ }
+
+ public double getPower() {
+ return power;
+ }
+
+ public String getProduct_factory() {
+ return product_factory;
+ }
+
+ public String getProduct_size() {
+ return product_size;
+ }
+
+ public double getWeight() {
+ return weight;
+ }
+
+ public String getInternet() {
+ return internet;
+ }
+
+ public void setAlgorithm(String algorithm) {
+ this.algorithm = algorithm;
+ }
+
+ public void setPower(double power) {
+ this.power = power;
+ }
+
+ public void setProduct_factory(String product_factory) {
+ this.product_factory = product_factory;
+ }
+
+ public void setProduct_size(String product_size) {
+ this.product_size = product_size;
+ }
+
+ public void setWeight(double weight) {
+ this.weight = weight;
+ }
+
+ public void setInternet(String internet) {
+ this.internet = internet;
+ }
+
+ public double getWork_temperature_min() {
+ return work_temperature_min;
+ }
+
+ public double getWork_temperature_max() {
+ return work_temperature_max;
+ }
+
+ public double getWork_humidity_min() {
+ return work_humidity_min;
+ }
+
+ public double getWork_humidity_max() {
+ return work_humidity_max;
+ }
+
+ public void setWork_temperature_min(double work_temperature_min) {
+ this.work_temperature_min = work_temperature_min;
+ }
+
+ public void setWork_temperature_max(double work_temperature_max) {
+ this.work_temperature_max = work_temperature_max;
+ }
+
+ public void setWork_humidity_min(double work_humidity_min) {
+ this.work_humidity_min = work_humidity_min;
+ }
+
+ public void setWork_humidity_max(double work_humidity_max) {
+ this.work_humidity_max = work_humidity_max;
+ }
+
+ public double getComputing_power() {
+ return computing_power;
+ }
+
+ public String getComputing_power_unit() {
+ return computing_power_unit;
+ }
+
+ public void setComputing_power(double computing_power) {
+ this.computing_power = computing_power;
+ }
+
+ public void setComputing_power_unit(String computing_power_unit) {
+ this.computing_power_unit = computing_power_unit;
+ }
+
+ public double getBase_compute_amount() {
+ return base_compute_amount;
+ }
+
+ public void setBase_compute_amount(double base_compute_amount) {
+ this.base_compute_amount = base_compute_amount;
+ }
+
+ public void setImg(String img) {
+ this.img = img;
+ }
+
+}
diff --git a/trading-order-bean/src/main/java/com/yami/trading/bean/miner/MinerOrder.java b/trading-order-bean/src/main/java/com/yami/trading/bean/miner/MinerOrder.java
new file mode 100644
index 0000000..2a43d21
--- /dev/null
+++ b/trading-order-bean/src/main/java/com/yami/trading/bean/miner/MinerOrder.java
@@ -0,0 +1,209 @@
+package com.yami.trading.bean.miner;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.yami.trading.common.domain.UUIDEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Comparator;
+import java.util.Date;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("t_miner_order")
+public class MinerOrder extends UUIDEntity implements Comparator<MinerOrder> {
+ private static final long serialVersionUID = -726057340004619294L;
+
+ @TableField("party_id")
+ private String party_id;
+ /**
+ * 订单 号
+ */
+ private String order_no;
+
+ /**
+ * 矿机产品Id
+ */
+ @Getter
+ private String miner_id;
+
+ /**
+ * 金额
+ */
+ private double amount;
+
+ /**
+ * 买入时间
+ */
+// @JsonSerialize(using = LocalDateTimeSerializer.class)
+// @JsonDeserialize(using = LocalDateTimeDeserializer.class)
+// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date create_time;
+
+ /**
+ * 起息时间 从买入时间第二天开始算
+ */
+// @JsonSerialize(using = LocalDateTimeSerializer.class)
+// @JsonDeserialize(using = LocalDateTimeDeserializer.class)
+// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date earn_time;
+
+ /**
+ * 截止时间
+ */
+// @JsonSerialize(using = LocalDateTimeSerializer.class)
+// @JsonDeserialize(using = LocalDateTimeDeserializer.class)
+// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date stop_time;
+
+ /**
+ * 累计收益
+ */
+ private double profit;
+
+ /**
+ * 状态。0.正常赎回, 1 托管中 ,2提前赎回 (违约)3.取消
+ */
+ private String state = "1";
+ /**
+ * 上次结息日期纪录,(如遇服务中途停止,可根据该字段判定是否需要重新计算)
+ */
+// @JsonSerialize(using = LocalDateTimeSerializer.class)
+// @JsonDeserialize(using = LocalDateTimeDeserializer.class)
+// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date compute_day;
+ /**
+ * 赎回时间
+ */
+// @JsonSerialize(using = LocalDateTimeSerializer.class)
+// @JsonDeserialize(using = LocalDateTimeDeserializer.class)
+// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date close_time;
+ /**
+ * 是否首次购买: 1:首次购买,0不是首次
+ */
+ private String first_buy;
+ /**
+ * 基础计息金额
+ */
+ private double base_compute_amount;
+
+ @Setter
+ @Getter
+ private double compute_profit;
+
+ @Setter
+ @Getter
+ private double default_money;
+
+ public String getPartyId() {
+ return party_id;
+ }
+
+ public void setPartyId(String partyId) {
+ this.party_id = partyId;
+ }
+
+ public String getOrder_no() {
+ return order_no;
+ }
+
+ public void setOrder_no(String order_no) {
+ this.order_no = order_no;
+ }
+
+ public double getAmount() {
+ return amount;
+ }
+
+ public void setAmount(double amount) {
+ this.amount = amount;
+ }
+
+ public Date getCreate_time() {
+ return create_time;
+ }
+
+ public void setCreate_time(Date create_time) {
+ this.create_time = create_time;
+ }
+
+ public double getProfit() {
+ return profit;
+ }
+
+ public void setProfit(double profit) {
+ this.profit = profit;
+ }
+
+ public Date getEarn_time() {
+ return earn_time;
+ }
+
+ public void setEarn_time(Date earn_time) {
+ this.earn_time = earn_time;
+ }
+
+ public Date getStop_time() {
+ return stop_time;
+ }
+
+ public void setStop_time(Date stop_time) {
+ this.stop_time = stop_time;
+ }
+
+ public void setMinerId(String minerId) {
+ this.miner_id = minerId;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public Date getCompute_day() {
+ return compute_day;
+ }
+
+ public void setCompute_day(Date compute_day) {
+ this.compute_day = compute_day;
+ }
+
+ public Date getClose_time() {
+ return close_time;
+ }
+
+ public void setClose_time(Date close_time) {
+ this.close_time = close_time;
+ }
+
+ public String getFirst_buy() {
+ return first_buy;
+ }
+
+ public void setFirst_buy(String first_buy) {
+ this.first_buy = first_buy;
+ }
+
+
+ public double getBase_compute_amount() {
+ return base_compute_amount;
+ }
+
+ public void setBase_compute_amount(double base_compute_amount) {
+ this.base_compute_amount = base_compute_amount;
+ }
+
+ @Override
+ public int compare(MinerOrder arg0, MinerOrder arg1) {
+ // TODO Auto-generated method stub
+ return -arg0.getCreate_time().compareTo(arg1.getCreate_time());
+ }
+
+}
diff --git a/trading-order-bean/src/main/java/com/yami/trading/bean/miner/MinerPara.java b/trading-order-bean/src/main/java/com/yami/trading/bean/miner/MinerPara.java
new file mode 100644
index 0000000..2c24174
--- /dev/null
+++ b/trading-order-bean/src/main/java/com/yami/trading/bean/miner/MinerPara.java
@@ -0,0 +1,66 @@
+package com.yami.trading.bean.miner;
+
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.yami.trading.common.domain.UUIDEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 矿机配置参数
+ *
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("t_miner_para")
+public class MinerPara extends UUIDEntity {
+
+ private static final long serialVersionUID = 1639941028310043811L;
+
+ /**
+ * 矿机id
+ */
+ private String miner_id;
+ /**
+ * 购买周期
+ */
+ private int cycle;
+
+ /**
+ * 购买价格
+ */
+ private double amount;
+
+ public int getCycle() {
+ return cycle;
+ }
+
+ public double getAmount() {
+ return amount;
+ }
+
+ public void setCycle(int cycle) {
+ this.cycle = cycle;
+ }
+
+ public void setAmount(double amount) {
+ this.amount = amount;
+ }
+
+ public String getMiner_id() {
+ return miner_id;
+ }
+
+ public void setMiner_id(String miner_id) {
+ this.miner_id = miner_id;
+ }
+
+
+
+
+
+
+
+
+}
diff --git a/trading-order-bean/src/main/java/com/yami/trading/bean/model/Miner.java b/trading-order-bean/src/main/java/com/yami/trading/bean/model/Miner.java
deleted file mode 100644
index eb987fb..0000000
--- a/trading-order-bean/src/main/java/com/yami/trading/bean/model/Miner.java
+++ /dev/null
@@ -1,155 +0,0 @@
-package com.yami.trading.bean.model;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-
-/**
- * 矿机
- */
-@EqualsAndHashCode(callSuper = false)
-@TableName("t_miner")
-@Data
-public class Miner {
-
- @TableId(type = IdType.AUTO,value = "id")
- private int id;
-
- /**
- * 矿机名称(简体中文)
- */
- private String name;
-
- /**
- * 矿机名称(英文)
- */
- private String name_en;
-
- /**
- * 矿机名称(繁体)
- */
- private String name_cn;
-
- /**
- * 周期-天数(现做矿机等级判定)
- */
- private int cycle;
-
- /**
- * ----可解锁周期-- 截止后方可解锁 CYCLE_CLOSE
- */
- private int cycle_close;
-
- /**
- * 日利率(%)
- */
- private double daily_rate;
-
- /**
- * 展示日利率(%)
- */
- private double show_daily_rate;
-
- /**
- * 最低投资金额(USDT)
- */
- private double investment_min;
-
- /**
- * 最高投资金额(USDT)
- */
- private double investment_max;
-
- /**
- * 上下架。0 下架, 1 上架,
- */
- private String state = "0";
-
- /**
- * 是否自主购买 0需管理员手动增加,1可自行购买
- */
- private String on_sale = "0";
-
- /**
- * 是否是体验产品
- */
- private boolean test = false;
-
- /**
- * 适用算法
- */
- private String algorithm;
-
- /**
- * 算力
- */
- private double computing_power;
-
- /**
- * 算力单位
- */
- private String computing_power_unit;
-
- /**
- * 功耗
- */
- private double power;
-
- /**
- * 生产厂家
- */
- private String product_factory;
-
- /**
- * 外箱尺寸
- */
- private String product_size;
-
- /**
- * 整机重量
- */
- private double weight;
-
- /**
- * 工作温度区间(最小值)
- */
- private double work_temperature_min;
-
- /**
- * 工作温度区间(最大值)
- */
- private double work_temperature_max;
-
- /**
- * 工作湿度区间(最小值)
- */
- private double work_humidity_min;
-
- /**
- * 工作湿度区间(最大值)
- */
- private double work_humidity_max;
-
- /**
- * 网络连接
- */
- private String internet;
-
- /**
- * 基础计息金额
- */
- private double base_compute_amount;
-
- /**
- * 矿机购买币种
- */
- private String buyCurrency;
-
- /**
- * 矿机购买币种
- */
- private String outputCurrency;
-}
diff --git a/trading-order-bean/src/main/java/com/yami/trading/bean/model/MinerOrder.java b/trading-order-bean/src/main/java/com/yami/trading/bean/model/MinerOrder.java
deleted file mode 100644
index c0a55f5..0000000
--- a/trading-order-bean/src/main/java/com/yami/trading/bean/model/MinerOrder.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package com.yami.trading.bean.model;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.io.Serializable;
-import java.util.Date;
-
-@EqualsAndHashCode(callSuper = false)
-@TableName("t_miner_order")
-@Data
-public class MinerOrder{
-
- @TableId(type = IdType.AUTO,value = "id")
- private int id;
-
- private Serializable partyId;
-
- /**
- * 订单 号
- */
- private String order_no;
-
- /**
- * 矿机产品Id
- */
- private String minerId;
-
- /**
- * 金额
- */
- private double amount;
-
- /**
- * 买入时间
- */
- private Date create_time;
-
- /**
- * 起息时间 从买入时间第二天开始算
- */
- private Date earn_time;
-
- /**
- * 截止时间
- */
- private Date stop_time;
-
- /**
- * 累计收益
- */
- private double profit;
-
- /**
- * 状态。0.正常赎回, 1 托管中 ,2提前赎回 (违约)3.取消
- */
- private String state = "1";
- /**
- * 上次结息日期纪录,(如遇服务中途停止,可根据该字段判定是否需要重新计算)
- */
- private Date compute_day;
- /**
- * 赎回时间
- */
- private Date close_time;
-
- /**
- * 是否首次购买: 1:首次购买,0不是首次
- */
- private String first_buy;
-
- /**
- * 基础计息金额
- */
- private double base_compute_amount;
-}
diff --git a/trading-order-bean/src/main/java/com/yami/trading/bean/model/MinerPara.java b/trading-order-bean/src/main/java/com/yami/trading/bean/model/MinerPara.java
deleted file mode 100644
index 40b6b3a..0000000
--- a/trading-order-bean/src/main/java/com/yami/trading/bean/model/MinerPara.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.yami.trading.bean.model;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-
-/**
- * 矿机配置参数
- */
-@EqualsAndHashCode(callSuper = false)
-@TableName("t_miner_para")
-@Data
-public class MinerPara{
-
- @TableId(type = IdType.AUTO,value = "id")
- private int id;
-
- /**
- * 矿机id
- */
- private String miner_id;
-
- /**
- * 购买周期
- */
- private int cycle;
-
- /**
- * 购买价格
- */
- private double amount;
-}
diff --git a/trading-order-common/src/main/java/com/yami/trading/common/util/DateTimeTools.java b/trading-order-common/src/main/java/com/yami/trading/common/util/DateTimeTools.java
new file mode 100644
index 0000000..c88868a
--- /dev/null
+++ b/trading-order-common/src/main/java/com/yami/trading/common/util/DateTimeTools.java
@@ -0,0 +1,1143 @@
+package com.yami.trading.common.util;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Timestamp;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.*;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.TimeZone;
+
+/**
+ * 日期工具类
+ *
+ * 参考资料:
+ * https://blog.csdn.net/shuair/article/details/126694562
+ * https://www.cnblogs.com/convict/p/16180509.html
+ *
+ * 时区对照表:
+ * http://t.zoukankan.com/kakaisgood-p-12523507.html
+ * https://blog.csdn.net/LordForce/article/details/132101076
+ */
+public class DateTimeTools {
+ private final static Logger logger = LoggerFactory.getLogger(DateTimeTools.class);
+
+ public static final String DEFAULT_DATA_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
+
+ // 处理类似格式:2022-07-08T04:02:43.85
+ public static final String DATA_TIME_FORMAT_2 = "yyyy-MM-dd'T'HH:mm:ss.SSS";
+
+ // 带时区格式
+ public static final String DATA_TIME_FORMAT_3 = "yyyy-MM-dd'T'HH:mm:ssZ";
+
+ public static final String DAY_FORMAT = "yyyy-MM-dd";
+
+ // 提前缓存各个时区的标记,以及各个时区和 UTC 时区的时差
+ public static TimeZone utcZone = TimeZone.getTimeZone("UTC");
+
+ /**
+ * 基于系统时区,将指定 date 类型对象转换为 LocalDateTime 对象
+ *
+ * @param date
+ * @return
+ */
+ public static LocalDateTime date2LocalDateTime(Date date) {
+ if (date == null) {
+ return null;
+ }
+
+ // 时区
+ ZoneId zoneId = ZoneId.systemDefault();
+
+ // 方式1
+ ZonedDateTime zonedDateTime = date.toInstant().atZone(zoneId);
+ return zonedDateTime.toLocalDateTime();
+
+// // 方式2
+// return LocalDateTime.ofInstant(date.toInstant(), zoneId);
+ }
+
+ public static LocalDate date2LocalDate(Date date) {
+ if (date == null) {
+ return null;
+ }
+
+ // 时区
+ ZoneId zoneId = ZoneId.systemDefault();
+
+ // 方式1
+ ZonedDateTime zonedDateTime = date.toInstant().atZone(zoneId);
+ return zonedDateTime.toLocalDate();
+
+// // 方式2
+// LocalDateTime localDateTime2 = LocalDateTime.ofInstant(date.toInstant(), zoneId);
+// return localDateTime2.toLocalDate();
+ }
+
+ public static LocalTime date2LocalTime(Date date) {
+ if (date == null) {
+ return null;
+ }
+
+ // 时区
+ ZoneId zoneId = ZoneId.systemDefault();
+
+ // 方式1
+ ZonedDateTime zonedDateTime = date.toInstant().atZone(zoneId);
+ return zonedDateTime.toLocalTime();
+
+ // 方式2
+// LocalDateTime localDateTime2 = LocalDateTime.ofInstant(date.toInstant(), zoneId);
+// return localDateTime2.toLocalTime();
+ }
+
+ /**
+ * 将当前系统时区的时间转换成 Date 类型对象;
+ * 注意:参数 time 关联的是当前系统时区的时间
+ *
+ * @param time
+ * @return
+ */
+ public static Date localDateTime2Date(LocalDateTime time) {
+ if (time == null) {
+ return null;
+ }
+
+ // 时区
+ ZoneId zoneId = ZoneId.systemDefault();
+
+ Instant instant = time.atZone(zoneId).toInstant();
+ return Date.from(instant);
+ }
+
+ public static Date localDate2Date(LocalDate time) {
+ if (time == null) {
+ return null;
+ }
+ // 由于`LocalDate`不带有时间信息,所以必须设置时间,才能转 Date
+
+ // 时区
+ ZoneId zoneId = ZoneId.systemDefault();
+ Instant instant;
+ Date date;
+
+ // 方式1:atStartOfDay,自动赋予午夜时间,返回 LocalDateTime,设置时区返回 ZonedDateTime,进而得到 Instant
+ instant = time.atStartOfDay().atZone(zoneId).toInstant();
+ date = Date.from(instant);
+ System.out.println(date);
+
+ return date;
+
+// // 方式2
+// instant = time.atStartOfDay(zoneId).toInstant();
+// date = Date.from(instant);
+// System.out.println(date);
+//
+// // 方式3:atStartOfDay 的底层实现
+// instant = time.atTime(LocalTime.MIDNIGHT).atZone(zoneId).toInstant();
+// date = Date.from(instant);
+// System.out.println(date);
+//
+// // 方式4
+// instant = LocalDateTime.of(time, LocalTime.MIDNIGHT).atZone(zoneId).toInstant();
+// date = Date.from(instant);
+// System.out.println(date);
+//
+// // 方式5:通过 Timestamp 得到 Instant
+// instant = Timestamp.valueOf(time.atTime(LocalTime.MIDNIGHT)).toInstant();
+// date = Date.from(instant);
+// System.out.println(date);
+//
+// // 方式6
+// instant = Timestamp.valueOf(LocalDateTime.of(time, LocalTime.MIDNIGHT)).toInstant();
+// date = Date.from(instant);
+// System.out.println(date);
+//
+// // 方式7:通过毫秒数初始化 Date 对象
+// Timestamp timestamp = Timestamp.valueOf(time.atTime(LocalTime.MIDNIGHT));
+// date = new Date(timestamp.getTime());
+// System.out.println(date);
+ }
+
+ public static Date localTime2Date(LocalTime time) {
+ if (time == null) {
+ return null;
+ }
+
+ // 由于 LocalTime 不带有日期信息,所以必须设置日期,才能转 Date
+ LocalDate nowDate = LocalDate.now();
+
+ // 时区
+ ZoneId zoneId = ZoneId.systemDefault();
+ Instant instant;
+ Date date;
+
+ instant = LocalDateTime.of(nowDate, time).atZone(zoneId).toInstant();
+ date = Date.from(instant);
+
+ instant = Timestamp.valueOf(LocalDateTime.of(nowDate, time)).toInstant();
+ date = Date.from(instant);
+
+ Timestamp timestamp = Timestamp.valueOf(LocalDateTime.of(nowDate, time));
+ date = new Date(timestamp.getTime());
+
+ return date;
+ }
+
+ public static Date getDateFromMs(long ms) {
+ return new Date(ms);
+ }
+
+ public static LocalDate getLocalDateFromMs(long ms) {
+ Date date = getDateFromMs(ms);
+ return date2LocalDate(date);
+ }
+
+ public static LocalTime getLocalTimeFromMs(long ms) {
+ Date date = getDateFromMs(ms);
+ return date2LocalTime(date);
+ }
+
+ public static LocalDateTime getLocalDateTimeFromMs(long ms) {
+ Date date = getDateFromMs(ms);
+ return date2LocalDateTime(date);
+ }
+
+ /**
+ * 获取当前天
+ *
+ * @return String
+ */
+ public static String getCurDayStr() {
+ return new SimpleDateFormat(DAY_FORMAT).format(new Date());
+ }
+
+ public static String getDayStr(Date time) {
+ if (time == null) {
+ return null;
+ }
+
+ return new SimpleDateFormat(DAY_FORMAT).format(time);
+ }
+
+ /**
+ * 获取前一天
+ * 注意时区的影响!!!
+ *
+ * @return Date
+ */
+ public static Date getPreviousDate() {
+ Calendar begin = Calendar.getInstance();
+ begin.set(Calendar.DAY_OF_MONTH, begin.get(Calendar.DAY_OF_MONTH) - 1);
+ begin.set(Calendar.HOUR_OF_DAY, 0);
+ begin.set(Calendar.MINUTE, 0);
+ begin.set(Calendar.SECOND, 0);
+ return begin.getTime();
+ }
+
+ /**
+ * 获取下N天
+ * 注意时区的影响!!!
+ *
+ * @param date
+ * 当前时间
+ * @param n
+ * 下N天
+ * @return Date 下N天日期
+ */
+ public static Date getNextDate(Date date, int n) {
+ if (date == null) {
+ return null;
+ }
+
+ Calendar begin = Calendar.getInstance();
+ begin.setTime(date);
+ begin.set(Calendar.DAY_OF_MONTH, begin.get(Calendar.DAY_OF_MONTH) + n);
+ begin.set(Calendar.HOUR_OF_DAY, 0);
+ begin.set(Calendar.MINUTE, 0);
+ begin.set(Calendar.SECOND, 0);
+ begin.set(Calendar.MILLISECOND, 0);
+ return begin.getTime();
+ }
+
+ /**
+ * 添加秒数
+ * 注意时区的影响!!!
+ *
+ * @return Date
+ */
+ public static Date addSecond(Long date, int second) {
+ if (date == null) {
+ return null;
+ }
+
+ Calendar cal = Calendar.getInstance();
+ cal.setTimeInMillis(date);
+ cal.add(Calendar.SECOND, second);
+ return cal.getTime();
+ }
+
+ /**
+ * 添加小时
+ * 注意时区的影响!!!
+ *
+ * @param date
+ * @param hour
+ * @return Date
+ */
+ public static Date addHour(Long date, int hour) {
+ if (date == null || date <= 0) {
+ return null;
+ }
+
+ Calendar cal = Calendar.getInstance();
+ cal.setTimeInMillis(date);
+ cal.add(Calendar.HOUR_OF_DAY, hour);
+ return cal.getTime();
+ }
+
+ /**
+ * 添加小时
+ * 注意时区的影响!!!
+ *
+ * @param date
+ * @param hour
+ * @return Date
+ */
+ public static Date addHour(Date date, int hour) {
+ if (date == null) {
+ return null;
+ }
+
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);;
+ cal.add(Calendar.HOUR_OF_DAY, hour);
+ return cal.getTime();
+ }
+
+ /**
+ * 注意时区的影响!!!
+ *
+ * @param date
+ * @param minutes
+ * @return
+ */
+ public static Date addMinutes(Date date, int minutes) {
+ if (date == null) {
+ return null;
+ }
+
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ cal.add(Calendar.MINUTE, minutes);
+ return cal.getTime();
+ }
+
+ /**
+ * 添加秒数
+ * 注意时区的影响!!!
+ *
+ * @return Date
+ */
+ public static Date addSecond(Date date, int second) {
+ if (date == null) {
+ return null;
+ }
+
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ cal.add(Calendar.SECOND, second);
+ return cal.getTime();
+ }
+
+ /**
+ * 添加天数
+ * 注意时区的影响!!!
+ *
+ * @param date
+ * @param day
+ * @return Date
+ */
+ public static Date addDay(Date date, int day) {
+ if (date == null) {
+ return null;
+ }
+
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ cal.add(Calendar.DAY_OF_YEAR, day);
+ return cal.getTime();
+ }
+
+ /**
+ * 两个时间之间相差距离多少天
+ *
+ * @param starttime 时间参数 1:
+ * @param endtime 时间参数 2:
+ * @return 相差天数
+ */
+ public static long getDistanceDays(String starttime, String endtime) {
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+ Date one;
+ Date two;
+ long days = 0;
+ try {
+ one = df.parse(starttime);
+ two = df.parse(endtime);
+ long time1 = one.getTime();
+ long time2 = two.getTime();
+ long diff ;
+ if (time1<time2) {
+ diff = time2 - time1;
+ } else {
+ diff = time1 - time2;
+ }
+ days = diff / (1000 * 60 * 60 * 24);
+ } catch (ParseException e) {
+ logger.error("计算两个时间:{} - {} 的天数差距报错", starttime, endtime, e);
+ }
+
+ return days;//返回相差多少天
+ }
+
+ /**
+ * 两个时间相差距离多少天多少小时多少分多少秒
+ * @param starttime 时间参数 1 格式:1990-01-01 12:00:00
+ * @param endtime 时间参数 2 格式:2009-01-01 12:00:00
+ * @return long[] 返回值为:{天, 时, 分, 秒}
+ */
+ public static long[] getDistanceTimes(String starttime, String endtime) {
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ Date one;
+ Date two;
+ long day = 0;
+ long hour = 0;
+ long min = 0;
+ long sec = 0;
+ try {
+ one = df.parse(starttime);
+ two = df.parse(endtime);
+ long time1 = one.getTime();
+ long time2 = two.getTime();
+ long diff ;
+ if (time1<time2) {
+ diff = time2 - time1;
+ } else {
+ diff = time1 - time2;
+ }
+ day = diff / (24 * 60 * 60 * 1000);
+ hour = (diff / (60 * 60 * 1000) - day * 24);
+ min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
+ sec = (diff/1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
+ } catch (ParseException e) {
+ logger.error("计算两个时间:{} - {} 的天数差距报错", starttime, endtime, e);
+ return null;
+ }
+
+ long[] times = {day, hour, min, sec};
+ return times;
+ }
+
+ /**
+ * 注意时区的影响!!!
+ *
+ * @param ms
+ * @return
+ */
+ public static Date fromMilliseconds(long ms) {
+ if (ms <= 0L) {
+ throw new RuntimeException("错误的参数");
+ }
+
+ return new Date(ms);
+ }
+
+ public static String formatDateTime(Date date) {
+ return DateUtil.formatDateTime(date);
+ }
+
+ public static String formatDateTime(LocalTime localTime) {
+ if (localTime == null) {
+ return null;
+ }
+
+ Date date = localTime2Date(localTime);
+ return DateUtil.formatDateTime(date);
+ }
+
+ public static String formatDateTime(LocalDateTime localDateTime) {
+ if (localDateTime == null) {
+ return null;
+ }
+
+ Date date = localDateTime2Date(localDateTime);
+ return DateUtil.formatDateTime(date);
+ }
+
+ public static String formatDateTime(LocalDate localDate) {
+ if (localDate == null) {
+ return null;
+ }
+
+ Date date = localDate2Date(localDate);
+ return DateUtil.formatDateTime(date);
+ }
+
+ public static TimeZone getLocalTimeZone() {
+ // 香港是上海时区,该时区和北京时区没有时差
+ // utc 标准时区比北京时区晚 8 个小时,就是说北京上午 8 点,UTC 0点
+ Calendar ca = Calendar.getInstance();
+ TimeZone tz = ca.getTimeZone();// 等效:TimeZone.getDefault();
+
+ logger.info("当前时区:{}", tz.getID());
+
+ return tz;
+ }
+
+ public static ZoneId getLocalZoneId() {
+ return TimeZone.getDefault().toZoneId();
+ }
+
+ /**
+ * 返回美东时区 zone 对象
+ *
+ * @return
+ */
+ public static ZoneId getMDZone() {
+ return ZoneId.of("Etc/GMT+4");
+ //return ZoneId.of("America/New_York");
+ }
+
+ /**
+ * 将参数 time 对应的时区时间认为是 fromZone 参数对应的时区时间,转成 toZone 时区对应的时间。
+ * 注意:如果原始时间 time 使用的时区和参数 fromZone 的不一致,则换算结果是不合预期的!!!!
+ * 例如:如果 time 是基于中欧标准时间(比北京时间晚 6 个小时)得到的值, fromZone 填写的是
+ * 北京时区, toZone 是美东时区,则得到的结果将比北京时间晚 18 个小时的时间,而非预期的
+ * 比中欧时间晚 6 个小时的时间(美东时区比北京时区晚 12 个小时)
+ *
+ * 常识:北京时区时间比 UTC 时间早 8 个小时,北京时区时间比中欧时区时间早 6 个小时,北京时区时间比美东时区时间早 12 个小时
+ *
+ * @param time
+ * @param fromZone
+ * @param toZone
+ * @return
+ */
+ public static LocalDateTime convertZoneTime(final LocalDateTime time, final ZoneId fromZone, final ZoneId toZone) {
+ final ZonedDateTime zonedtime = time.atZone(fromZone);
+ final ZonedDateTime converted = zonedtime.withZoneSameInstant(toZone);
+ return converted.toLocalDateTime();
+ }
+
+ /**
+ * 将当前时区的时间转换为指定时区的时间
+ *
+ * @param time
+ * @param toZone
+ * @return
+ */
+ public static LocalDateTime convertZoneTime(final LocalDateTime time, final ZoneId toZone) {
+ return convertZoneTime(time, ZoneId.systemDefault(), toZone);
+ }
+
+ /**
+ * 将指定时区的时间转换为 UTC 时间;
+ * 注意: time 对象对应的时区需要和参数 fromZone 的保持一致,否则结果会不如预期!!!!
+ *
+ * @param time
+ * @param fromZone
+ * @return
+ */
+ public static LocalDateTime toUtc(final LocalDateTime time, final ZoneId fromZone) {
+ return convertZoneTime(time, fromZone, ZoneOffset.UTC);
+ }
+
+ /**
+ * 将当前时区产生的时间转换为 UTC 时间
+ *
+ * @param time
+ * @return
+ */
+ public static LocalDateTime toUtc(final LocalDateTime time) {
+ return toUtc(time, ZoneId.systemDefault());
+ }
+
+ public static String standardTimeFormat(Date time) {
+ return standardTimeFormat(time, null);
+ }
+
+ /**
+ * 提取当前系统时区所在的时间 time,对应于指定时区 fromZone 的时间字符串
+ *
+ * @param time
+ * @param fromZone
+ * @return
+ */
+ public static String standardTimeFormat(Date time, ZoneId fromZone) {
+ if (time == null) {
+ return null;
+ }
+ if (fromZone == null) {
+ fromZone = ZoneId.systemDefault();
+ }
+
+ SimpleDateFormat formatter = new SimpleDateFormat(DEFAULT_DATA_TIME_FORMAT);
+ TimeZone formatTimeZone = TimeZone.getTimeZone(fromZone);
+ formatter.setTimeZone(formatTimeZone);
+ return formatter.format(time);
+ }
+
+ /**
+ * 基于指定时区,来解析传入的时间,返回的是当前系统时区的时间
+ *
+ * 注意:
+ * 本方法返回的是 --- 基于 fromZone 时区来解析字符串时间,返回基于同样的时间戳下,对应的当前系统时区时间;
+ * 务必清楚,此处返回的不是系统时区下减去时间偏移量后计算的 fromZone 时间值。
+ *
+ * 例如:如果传入的 timeStr = 2023-11-08 12:00:00,当前系统时区是 Etc/GMT-8,传入的 fromZone = Etc/GMT+4;
+ * 那么调用本方法返回的 date 对象使用当前系统时区的时间处理工具打印出来的值是: 2023-11-09 00:00:00
+ *
+ * @param timeStr
+ * @param fromZone
+ * @return
+ */
+ public static Date parseWithTimeZone(String timeStr, ZoneId fromZone) {
+ if (StrUtil.isBlank(timeStr)) {
+ return null;
+ }
+ if (fromZone == null) {
+ fromZone = ZoneId.systemDefault();
+ }
+
+ timeStr = normalize(timeStr);
+
+ SimpleDateFormat formatter = new SimpleDateFormat(DEFAULT_DATA_TIME_FORMAT);
+ TimeZone formatTimeZone = TimeZone.getTimeZone(fromZone);
+ formatter.setTimeZone(formatTimeZone);
+ try {
+ return formatter.parse(timeStr);
+ } catch (Exception e) {
+ throw new RuntimeException("日期转换报错");
+ }
+ }
+
+ /**
+ * 基于指定时区,来解析传入的时间,返回的是当前系统时区的时间
+ *
+ * @param time
+ * @param fromZone
+ * @return
+ */
+ public static Date parseWithTimeZone(Date time, ZoneId fromZone) {
+ LocalDateTime fromLocalTime = DateTimeTools.date2LocalDateTime(time);
+
+ Instant instant = fromLocalTime.atZone(fromZone).toInstant();
+ Date targetZoneDate = Date.from(instant);
+
+ return targetZoneDate;
+ }
+
+ public static String normalize(String dateStr) {
+ if (StrUtil.isBlank(dateStr)) {
+ return StrUtil.str(dateStr);
+ }
+
+ // 日期时间分开处理
+ final List<String> dateAndTime = StrUtil.splitTrim(dateStr, ' ');
+ final int size = dateAndTime.size();
+ if (size < 1 || size > 2) {
+ // 非可被标准处理的格式
+ return StrUtil.str(dateStr);
+ }
+
+ dateStr = dateStr.replace("T", " ");
+ final StringBuilder builder = StrUtil.builder();
+
+ // 日期部分("\"、"/"、"."、"年"、"月"都替换为"-")
+ String datePart = dateAndTime.get(0).replaceAll("[/.年月]", "-");
+ datePart = StrUtil.removeSuffix(datePart, "日");
+ builder.append(datePart);
+
+ // 时间部分
+ if (size == 2) {
+ builder.append(' ');
+ String timePart = dateAndTime.get(1).replaceAll("[时分秒]", ":");
+ timePart = StrUtil.removeSuffix(timePart, ":");
+ //将ISO8601中的逗号替换为.
+ timePart = timePart.replace(',', '.');
+ builder.append(timePart);
+ }
+
+ return builder.toString();
+ }
+
+// /**
+// * 将当前时区时间转换成 UTC 时区时间
+// * 注意:此处 Date 对象对应的时区都是系统默认时区
+// *
+// * @param time
+// * @return
+// */
+// public static Date toUtc(Date time) {
+// if (time == null) {
+// return null;
+// }
+//
+// String localTimeZoneId = TimeZone.getDefault().getID();
+// long timeDiff = timeZoneDiffMap.get(localTimeZoneId);
+// return (new Date(time.getTime() - timeDiff * 1000L));
+// }
+//
+// public static Date toUtc(Date time, ZoneId fromZone) {
+// if (time == null) {
+// return null;
+// }
+// if (fromZone == null) {
+// fromZone = ZoneId.systemDefault();
+// }
+//
+// // 提取指定时区和 UTC 的时差
+// long timeDiff = timeZoneDiffMap.get(fromZone.getId());
+// // 对应时区的时间毫秒值减去时差,就是 UTC 时间
+// return (new Date(time.getTime() - timeDiff * 1000L));
+// }
+//
+// /**
+// *
+// * @Description: 基于零时区位置的展示时间,计算本地时间;
+// * 注意:基于返回值算出的时间毫秒值,算是标准时间毫秒值
+// *
+// * @time 2020年7月31日 下午9:38:08
+// * @author daydayup
+// * @param utcTime
+// * @return
+// * Date
+// * @throws
+// */
+// public static Date fromUtc(Date utcTime) {
+// if (utcTime == null) {
+// return null;
+// }
+//
+// String localTimeZoneId = TimeZone.getDefault().getID();
+// long timeDiff = timeZoneDiffMap.get(localTimeZoneId);
+// return (new Date(utcTime.getTime() + timeDiff * 1000L));
+// }
+//
+// public static Date fromUtc(Date utcTime, ZoneId toZone) {
+// if (utcTime == null) {
+// return null;
+// }
+// if (toZone == null) {
+// toZone = ZoneId.systemDefault();
+// }
+//
+// long timeDiff = timeZoneDiffMap.get(toZone.getId());
+// return (new Date(utcTime.getTime() + timeDiff * 1000L));
+// }
+
+ /**
+ * 基于当前系统时区指定的时间,计算目标时区的时间
+ *
+ * @param fromTime : 系统时区的时间
+ * @param targetZone : 转换成目标时区
+ * @return
+ */
+ public static Date convertZoneTime(Date fromTime, ZoneId targetZone) {
+ return convertZoneTime(fromTime, ZoneId.systemDefault(), targetZone);
+ }
+
+ public static Date convertZoneTime(long fromTime, ZoneId targetZone) {
+ if (fromTime <= 0) {
+ return null;
+ }
+ String checkTimeStr = String.valueOf(fromTime);
+ if (checkTimeStr.startsWith("1")) {
+ if (checkTimeStr.length() == 10) {
+ // 1000000000(秒) 对应 2001-09-09 09:46:40,识别为基于秒的时间戳
+ checkTimeStr = checkTimeStr + "000";
+ }
+ } else {
+ // 首位数大于 1,要么是 9几年的秒时间,要么是 9 几年的毫秒时间,基于秒的有 9 位数
+ if (checkTimeStr.length() <= 9) {
+ // 基于秒的时间戳
+ checkTimeStr = checkTimeStr + "000";
+ }
+ }
+
+ fromTime = Long.parseLong(checkTimeStr);
+ Date dateTime = new Date(fromTime);
+
+ return convertZoneTime(dateTime, targetZone);
+ }
+
+ /**
+ * 基于时区 fromZone 的时间 timeStr 解析成时区 toZone 的时间
+ * 注意:返回的是基于 toZone 时区的字面时间,不是系统时区的时间
+ *
+ * @param timeStr
+ * @param fromZone
+ * @param toZone
+ * @return
+ */
+ public static Date convertZoneTime(String timeStr, ZoneId fromZone, ZoneId toZone) {
+ // 注意:返回的 oriTime 是系统时区的时间值
+ Date oriTime = parseWithTimeZone(timeStr, fromZone);
+
+ // 注意写法!
+ return convertZoneTime(oriTime, ZoneId.systemDefault(), toZone);
+ }
+
+ /**
+ * 基于时区 fromZone 的时间 time 解析成时区 toZone 的时间
+ *
+ * @param time
+ * @param fromZone
+ * @param toZone
+ * @return
+ */
+ public static Date convertZoneTime(Date time, ZoneId fromZone, ZoneId toZone) {
+ if (time == null) {
+ return null;
+ }
+
+ // toZone 时区相对于 fromZone 时区的时间偏移
+ long timeDiff = getTimeOffset(fromZone, toZone);
+ return (new Date(time.getTime() + timeDiff));
+ }
+
+ /**
+ * 将系统时区时间转换为对外展示配置的时区时间
+ *
+ * @param localZoneTime
+ * @return
+ */
+ public static Date transferToShowTime(Date localZoneTime) {
+ if (localZoneTime == null) {
+ return null;
+ }
+
+ String outPutTimeZoneId = TimeZoneContext.showTimeZoneId.get();
+ if (StrUtil.isBlank(outPutTimeZoneId)) {
+ throw new RuntimeException("错误的使用方式");
+ }
+
+ Date retDate = convertZoneTime(localZoneTime, ZoneId.of(outPutTimeZoneId));
+ return retDate;
+ }
+
+ /**
+ * 具体业务中使用的方法
+ *
+ * @param fromTime
+ * @return
+ */
+ public static Date transferToShowTime(Long fromTime) {
+ if (fromTime == null || fromTime <= 0) {
+ return null;
+ }
+ String checkTimeStr = String.valueOf(fromTime);
+ if (checkTimeStr.startsWith("1")) {
+ if (checkTimeStr.length() == 10) {
+ // 1000000000(秒) 对应 2001-09-09 09:46:40,识别为基于秒的时间戳
+ checkTimeStr = checkTimeStr + "000";
+ }
+ } else {
+ // 首位数大于 1,要么是 9几年的秒时间,要么是 9 几年的毫秒时间,基于秒的有 9 位数
+ if (checkTimeStr.length() <= 9) {
+ // 基于秒的时间戳
+ checkTimeStr = checkTimeStr + "000";
+ }
+ }
+
+ fromTime = Long.parseLong(checkTimeStr);
+ Date dateTime = new Date(fromTime);
+
+ return transferToShowTime(dateTime);
+ }
+
+ /**
+ * 注意:本方法用于将当前系统时区时间戳,参考预期的展示时间,转换为客户端时区能正确解析的时间戳。
+ * 此处涉及多个时区偏移换算问题,其他业务在不清楚本方法功能时不要随意使用!!!
+ * 本方法目前专用于将业务 API 返回给前端的时间戳值做加工,返回给前端解析时间。
+ *
+ * @param localTimestamp
+ * @return
+ */
+ public static long transferShowTimeToClientTime(Long localTimestamp) {
+ if (localTimestamp == null || localTimestamp <= 0) {
+ return 0L;
+ }
+
+ // 时间戳类型: 1-毫秒时间戳, 2-秒时间戳
+ int timestampType = 1;
+ String checkTimeStr = String.valueOf(localTimestamp);
+ if (checkTimeStr.startsWith("1")) {
+ if (checkTimeStr.length() == 10) {
+ // 1000000000(秒) 对应 2001-09-09 09:46:40,识别为基于秒的时间戳
+ checkTimeStr = checkTimeStr + "000";
+ timestampType = 2;
+ }
+ } else {
+ // 首位数大于 1,要么是 9几年的秒时间,要么是 9 几年的毫秒时间,基于秒的有 9 位数
+ if (checkTimeStr.length() <= 9) {
+ // 基于秒的时间戳
+ checkTimeStr = checkTimeStr + "000";
+ timestampType = 2;
+ }
+ }
+
+ localTimestamp = Long.parseLong(checkTimeStr);
+
+ String showTimeZoneId = TimeZoneContext.showTimeZoneId.get();
+ if (StrUtil.isBlank(showTimeZoneId)) {
+ throw new RuntimeException("错误的使用方式");
+ }
+ String clientTimeZoneId = TimeZoneContext.clientTimeZoneId.get();
+ if (StrUtil.isBlank(clientTimeZoneId)) {
+ throw new RuntimeException("错误的使用方式");
+ }
+
+ long timeOffset = getTimeOffset(ZoneId.of(clientTimeZoneId), ZoneId.of(showTimeZoneId));
+ //logger.info("----------------> DateTimeTools.transferShowTimeToClientTime 传入时间戳:{}, showTimeZoneId:{}, clientTimeZoneId:{}, timeOffset:{}",
+ // localTimestamp, showTimeZoneId, clientTimeZoneId, timeOffset);
+
+ long retTimestamp = localTimestamp + timeOffset;
+ if (timestampType == 1) {
+ // 以毫秒入,以毫秒出
+ return retTimestamp;
+ } else if (timestampType == 2) {
+ // 以秒入,以秒出
+ return retTimestamp / 1000L;
+ }
+
+ // TODO
+ return retTimestamp;
+ }
+
+ /**
+ * 将基于 fromZone 时区的时间值 inputTime,转换为对应的系统时间
+ *
+ * @param inputTime : 请求参数传入的字符串时间值
+ * @param timeFormat : 时间格式
+ * @param inputTimeZone : 参数时间使用的时区,如果未指定时区,则从当前线程上下文中自动提取时区
+ * @return
+ */
+ public static Date readQueryTime(String inputTime, String timeFormat, ZoneId inputTimeZone) {
+ if (StrUtil.isBlank(inputTime)) {
+ return null;
+ }
+
+ if (inputTimeZone == null) {
+ String inPutTimeZoneId = TimeZoneContext.showTimeZoneId.get();
+ if (StrUtil.isBlank(inPutTimeZoneId)) {
+ throw new RuntimeException("不能识别当前时间所属的时区,无法解析");
+ }
+
+ inputTimeZone = ZoneId.of(inPutTimeZoneId);
+ }
+
+ return convertZoneTime(inputTime, inputTimeZone, ZoneId.systemDefault());
+ }
+
+ /**
+ * 计算指定时区当前时间到 UTC 时间的时差,返回单位为毫秒
+ * 当值大于 0,代表当前时区更早,例如当前时区已经 12 点了,utc 时区才 11 点。
+ *
+ * 参考资料:
+ * https://qa.1r1g.com/sf/ask/1105223941/
+ *
+ * @return
+ */
+ public static long getTimeOffset(ZoneId zoneId) {
+ LocalDateTime refNow = LocalDateTime.now();
+ ZoneId refZoneId = ZoneId.of("Z");
+ ZonedDateTime refTime = refNow.atZone(refZoneId);
+
+ ZonedDateTime curZoneTime = refNow.atZone(zoneId);
+ Duration diff = Duration.between(curZoneTime, refTime);
+ return diff.toMillis();
+ }
+
+ /**
+ * 计算 targetZone 时区时间偏移量比 sourceZone 时区时间偏移量大的值
+ *
+ * @param sourceZone
+ * @param targetZone
+ * @return
+ */
+ public static long getTimeOffset(ZoneId sourceZone, ZoneId targetZone) {
+ LocalDateTime refNow = LocalDateTime.now();
+ ZonedDateTime refTime = refNow.atZone(sourceZone);
+
+ ZonedDateTime targetZoneTime = refNow.atZone(targetZone);
+ Duration diff = Duration.between(targetZoneTime, refTime);
+ return diff.toMillis();
+ }
+
+ public static void main(String[] args) {
+ TimeZone.setDefault(TimeZone.getTimeZone(ZoneId.of("GMT-4")));
+ long now = System.currentTimeMillis();
+ TimeZoneContext.showTimeZoneId.set("GMT+4");
+ TimeZoneContext.clientTimeZoneId.set("GMT+3");
+
+ long retNow = transferShowTimeToClientTime(now / 1000L);
+ System.out.println("----> now:" + now + ", retNow:" + retNow);
+ }
+
+ /**
+ * 时区资料:
+ * https://zhuanlan.zhihu.com/p/538934548
+ * https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
+ *
+ * @param args
+ */
+ public static void main2(String[] args) {
+// for (String oneZone : TimeZone.getAvailableIDs()) {
+// System.out.println("-----> oneZone:" + oneZone);
+// }
+ //TimeZone.setDefault(TimeZone.getTimeZone(ZoneId.of("GMT+4")));
+ System.out.println("-----> defaultTimeZone:" + ZoneId.systemDefault());
+
+ Date now = new Date();
+ // 展示 GMT-4 时区当前时间
+ TimeZoneContext.showTimeZoneId.set("GMT-4");
+ Date showTime = transferToShowTime(now);
+
+ Date innerTime = readQueryTime("2023-11-08 12:00:00", "yyyy-MM-dd HH:mm:ss", ZoneId.of("GMT-3"));
+ System.out.println("-----> now:" + DateUtil.formatDateTime(now) + ", showTime:" + DateUtil.formatDateTime(showTime) + ", innerTime:" + DateUtil.formatDateTime(innerTime));
+
+ // 注意: atZone 的用途是,将系统时区所在的时刻,应用到目标时区来解释,同时返回的时间是系统时区的时间。
+ // 而不是误以为的:将系统时区对应的时间,换算成目标时区的时间,并将这个目标时区的时间换算成系统时区的时间
+ LocalDateTime localNow = LocalDateTime.now();
+ Instant convertInstant = localNow.atZone(ZoneId.of("GMT-4")).toInstant();
+ Date convertDateTime = Date.from(convertInstant);
+ System.out.println("-----> convertDateTime:" + DateUtil.formatDateTime(convertDateTime));
+
+ String timeStr = "2023-11-08 12:00:00";
+ Date strTime1 = parseWithTimeZone(timeStr, ZoneId.of("Etc/GMT+4")); // 返回: 2023-11-09 00:00:00
+ Date strTime2 = parseWithTimeZone(timeStr, ZoneId.of("Etc/GMT-8")); // 返回: 2023-11-08 12:00:00
+ System.out.println("-----> strTime1:" + DateUtil.formatDateTime(strTime1) + ", strTime2:" + DateUtil.formatDateTime(strTime2));
+
+ // 符合预期
+ Date convertTime1 = convertZoneTime(timeStr, ZoneId.of("Etc/GMT+4"), ZoneId.of("Etc/GMT+5"));
+ System.out.println("-------> convertTime1: " + DateUtil.formatDateTime(convertTime1));
+
+ // 符合预期
+ long offset1 = getTimeOffset(ZoneId.of("GMT+0800"));
+ long offset2 = getTimeOffset(ZoneId.of("Z"));
+ long offset3 = getTimeOffset(ZoneId.of("GMT+0800"), ZoneId.of("GMT+7"));
+ System.out.println("------> offset1:" + offset1 + ", offset2:" + offset2 + ", offset3:" + offset3);
+
+ Date localNowTime = new Date();
+ TimeZone tz1 = TimeZone.getTimeZone("GMT+0500");// Etc/GMT+4 America/New_York (北京时间比纽约时间早 13 个小时)
+ SimpleDateFormat timeZoneDateFormat1 = new SimpleDateFormat(DEFAULT_DATA_TIME_FORMAT);
+ timeZoneDateFormat1.setTimeZone(tz1);
+
+ TimeZone tz2 = TimeZone.getTimeZone("GMT+4:00");// Etc/GMT+4 America/New_York (北京时间比纽约时间早 13 个小时)
+ SimpleDateFormat timeZoneDateFormat2 = new SimpleDateFormat(DEFAULT_DATA_TIME_FORMAT);
+ timeZoneDateFormat2.setTimeZone(tz2);
+ // 符合预期
+ System.out.println("------> tz1.time:" + timeZoneDateFormat1.format(localNowTime) + ", tz2.time:" + timeZoneDateFormat2.format(localNowTime));
+
+// try {
+// Date time = timeZoneDateFormat1.parse(normalize(timeStr));
+// String targetTime = timeZoneDateFormat1.format(localNowTime);
+// System.out.println("-----> localTime1:" + DateUtil.formatDateTime(time) +
+// ", localTime2:" + timeZoneDateFormat1.format(time) + ", targetTime:" + targetTime);
+// } catch (Exception e) {
+// throw new RuntimeException("日期转换报错");
+// }
+
+ // now1 是北京时区的时间值
+ LocalDateTime now1 = LocalDateTime.now();
+ long now1time = System.currentTimeMillis();
+ // 现在是北京时间 2023-11-06 22:00:00, 已经是 Etc/GMT 时区上偏离 0 时区的 -8 得到的时间,下面将获取此时 +4 时区的时间(相对于当前时区的时间),
+ // 这代表 +4 时区上此时已经是当前北京时间 12 个小时后的时间了,这既是目标时区的当时时间(例如北京地方 12点,目标地方已经夜里 24点),也可理解为当前
+ // 时区的一个未来时间
+ ZoneId zoneId = ZoneId.of("Etc/GMT+4"); // 北京时区是: Etc/GMT-8
+
+ // 计算当前在 ETC/GMT+4 时区的时间
+ Instant instant = now1.atZone(zoneId).toInstant();
+ Date date1 = Date.from(instant);
+ long now2time = date1.getTime();
+ // 以下显示:无论是从时间字符串打印来看,还是时间戳差值来看,都是 12 个小时后的时间
+ System.out.println("-----> now1 at Etc/GMT+4 : " + DateUtil.formatDateTime(date1) + ", offset: " + (now2time - now1time));
+
+ // 符合预期
+ Date now2 = new Date();
+ Date date2 = convertZoneTime(now2, ZoneId.of("Etc/GMT-8"), ZoneId.of("Etc/GMT+4"));
+ System.out.println("-----> now2 at Etc/GMT+4 : " + DateUtil.formatDateTime(date2) + ", offset: " + (date2.getTime() - now2.getTime()));
+
+ // 符合预期
+ Date now22 = new Date();
+ Date date22 = convertZoneTime(now22, ZoneId.of("GMT+3"), ZoneId.of("GMT+4"));
+ System.out.println("-----> now22 at GMT+4 : " + DateUtil.formatDateTime(date22));
+
+ // 符合预期
+ long timeoffset1 = getTimeOffset(ZoneId.of("Etc/GMT-8"));
+ long timeoffset2 = getTimeOffset(ZoneId.of("Etc/GMT+4"));
+ System.out.println("------> timeoffset1:" + timeoffset1 + ", timeoffset2:" + timeoffset2);
+
+ // 符合预期
+ Date now3 = new Date();
+ Date date3 = convertZoneTime(now3, ZoneId.of("Etc/GMT+4"));
+ System.out.println("-----> now3 at Etc/GMT+4 : " + DateUtil.formatDateTime(date3) + ", offset: " + (date3.getTime() - now3.getTime()));
+
+ // Etc/GMT+4 地方所在的 date3 时刻,也是当前时区 Etc/GMT-8 的一个未来时间(但是是一个虚拟的 Etc/GMT+4 地方的时间)
+ // Etc/GMT+4 时区的当前时间,转换为 Etc/GMT-8 时区的时间,是要在此基础上加 12 个小时,符合预期
+ Date now4 = new Date();
+ Date date4 = convertZoneTime(now3, ZoneId.of("Etc/GMT+4"), ZoneId.of("Etc/GMT-8"));
+ System.out.println("-----> date4 at Etc/GMT-8 : " + DateUtil.formatDateTime(date4) + ", offset: " + (now4.getTime() - date4.getTime()));
+
+ // 符合预期
+ Date date5 = convertZoneTime("2023-11-08 12:00:00", ZoneId.of("GMT+8"), ZoneId.of("GMT-4"));
+ System.out.println("-----> date5 at GMT-4 : " + DateUtil.formatDateTime(date5));
+
+ // 符合预期
+ Date localNowTime2 = new Date();
+ String date61 = standardTimeFormat(localNowTime2, ZoneId.of("GMT+8"));
+ String date62 = standardTimeFormat(localNowTime2, ZoneId.of("GMT-4"));
+ System.out.println("-----> date61 : " + date61 + ", date62:" + date62);
+
+
+// for (int i = 0; i < 200; i++) {
+// Date now = new Date();
+// LocalDateTime locatTime = date2LocalDateTime (now);
+// if (now.getTime() != DateTimeTools.localDateTime2Date(locatTime).getTime()) {
+// System.out.println("----------------> 时间转换有差距, now:" + DateUtil.formatDateTime(now));
+// }
+//
+// try {
+// Thread.sleep(500L);
+// } catch (Exception e) {
+// e.printStackTrace();
+// }
+// }
+ }
+
+ private static void testTimeZoneOffset() {
+ // 问题:随着时间的不同,通过以下方式计算时差不是一个固定值,目前看来有时是 4 个小时,有时是 5 个小时!!!!
+// String refTimeStr = "2022-09-15 01:38:01"; // 字面时间
+ String refTimeStr = "2000-01-02 01:00:00"; // 字面时间
+ SimpleDateFormat refSDF1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ SimpleDateFormat refSDF2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ refSDF1.setTimeZone(utcZone);
+ refSDF2.setTimeZone(TimeZone.getTimeZone("America/New_York"));
+
+ try {
+ Date utcTime = refSDF1.parse(refTimeStr);
+ Date mdTime = refSDF2.parse(refTimeStr);
+ logger.info("utcTime时分秒:{}-{}-{} {}:{}, mdTime时分秒:{}-{}-{} {}:{}", utcTime.getYear(), utcTime.getMonth(), utcTime.getDay(), utcTime.getHours(), utcTime.getMinutes(), mdTime.getYear(), mdTime.getMonth(), mdTime.getDay(), mdTime.getHours(), mdTime.getMinutes());
+ logger.info("utcTime:{}, mdTime:{}, 时差:{} 个小时", DateUtil.formatDateTime(utcTime), DateUtil.formatDateTime(mdTime), (mdTime.getTime() - utcTime.getTime())/3600000L);
+ } catch (ParseException e) {
+ logger.error("[DateTimeUtils static] 初始化时区信息报错:", e);
+ }
+ }
+}
diff --git a/trading-order-common/src/main/java/com/yami/trading/common/util/TimeZoneContext.java b/trading-order-common/src/main/java/com/yami/trading/common/util/TimeZoneContext.java
new file mode 100644
index 0000000..94c75fc
--- /dev/null
+++ b/trading-order-common/src/main/java/com/yami/trading/common/util/TimeZoneContext.java
@@ -0,0 +1,26 @@
+package com.yami.trading.common.util;
+
+import com.alibaba.ttl.TransmittableThreadLocal;
+
+import java.time.ZoneId;
+
+public class TimeZoneContext {
+ /**
+ * 对外展示时间使用的该时区对应的时间,主要用于处理 Date 类型,或者 String 类型的时间展示
+ */
+ public static ThreadLocal<String> showTimeZoneId = new TransmittableThreadLocal<String>() {
+ protected synchronized String initialValue() {
+ return ZoneId.systemDefault().getId();
+ }
+ };
+
+ /**
+ * 客户端当前的系统时区,主要用于处理时间戳类型的时间转换,以迎合/方便客户端解析时间戳
+ */
+ public static ThreadLocal<String> clientTimeZoneId = new TransmittableThreadLocal<String>() {
+ protected synchronized String initialValue() {
+ return ZoneId.systemDefault().getId();
+ }
+ };
+
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/dao/miner/MinerMapper.java b/trading-order-service/src/main/java/com/yami/trading/dao/miner/MinerMapper.java
new file mode 100644
index 0000000..182c0db
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/dao/miner/MinerMapper.java
@@ -0,0 +1,10 @@
+package com.yami.trading.dao.miner;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yami.trading.bean.miner.Miner;
+import org.apache.ibatis.annotations.Param;
+
+public interface MinerMapper extends BaseMapper<Miner> {
+ Page pagedQuery(Page page, @Param("name_para") String name_para);
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/dao/miner/MinerOrderMapper.java b/trading-order-service/src/main/java/com/yami/trading/dao/miner/MinerOrderMapper.java
new file mode 100644
index 0000000..deffcfa
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/dao/miner/MinerOrderMapper.java
@@ -0,0 +1,31 @@
+package com.yami.trading.dao.miner;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yami.trading.bean.miner.MinerOrder;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface MinerOrderMapper extends BaseMapper<MinerOrder> {
+ Page pagedQuery(Page page, @Param("name_para") String name_para);
+
+ Page pagedQuery1(Page page, @Param("partyId") String partyId,@Param("state") String state);
+
+ Page pagedQueryComputeOrder(Page page);
+
+
+ Page pagedQueryAdmin(Page page, @Param("children") List children,
+ @Param("miner_para") String miner_para,
+ @Param("status_para") String status_para,
+ @Param("orderNo") String orderNo,
+ @Param("rolename_para") String rolename_para,
+ @Param("name_para") String name_para);
+
+
+
+
+
+
+
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/dao/miner/MinerParaMapper.java b/trading-order-service/src/main/java/com/yami/trading/dao/miner/MinerParaMapper.java
new file mode 100644
index 0000000..c8cad1d
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/dao/miner/MinerParaMapper.java
@@ -0,0 +1,10 @@
+package com.yami.trading.dao.miner;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yami.trading.bean.miner.MinerPara;
+import org.apache.ibatis.annotations.Param;
+
+public interface MinerParaMapper extends BaseMapper<MinerPara> {
+ Page pagedQuery(Page page, @Param("name_para") String name_para);
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/job/MinerOrderMessage.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/job/MinerOrderMessage.java
new file mode 100644
index 0000000..8d306d4
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/job/MinerOrderMessage.java
@@ -0,0 +1,69 @@
+package com.yami.trading.service.miner.job;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@ApiModel
+public class MinerOrderMessage implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2239789461218349202L;
+
+ /**
+ * 无参构造函数
+ */
+ public MinerOrderMessage() {
+ }
+
+ /**
+ * 订单号
+ */
+ private String orderNo;
+ /**
+ * 收益
+ */
+ private double profit = 0.0D;
+ /**
+ * 计息时间
+ */
+ private Date computeDay;
+
+ public String getOrderNo() {
+ return orderNo;
+ }
+
+ public double getProfit() {
+ return profit;
+ }
+
+ public Date getComputeDay() {
+ return computeDay;
+ }
+
+ public void setOrderNo(String orderNo) {
+ this.orderNo = orderNo;
+ }
+
+ public void setProfit(double profit) {
+ this.profit = profit;
+ }
+
+ public void setComputeDay(Date computeDay) {
+ this.computeDay = computeDay;
+ }
+
+
+ public MinerOrderMessage(String orderNo, double profit, Date computeDay) {
+ this.orderNo = orderNo;
+ this.profit = profit;
+ this.computeDay = computeDay;
+ }
+
+
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/job/MinerOrderProfitJob.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/job/MinerOrderProfitJob.java
new file mode 100644
index 0000000..0ecf664
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/job/MinerOrderProfitJob.java
@@ -0,0 +1,246 @@
+package com.yami.trading.service.miner.job;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yami.trading.bean.data.domain.Realtime;
+import com.yami.trading.bean.model.Log;
+import com.yami.trading.bean.syspara.domain.Syspara;
+import com.yami.trading.common.util.StringUtils;
+import com.yami.trading.service.data.DataService;
+import com.yami.trading.service.miner.service.MinerOrderProfitService;
+import com.yami.trading.service.syspara.SysparaService;
+import com.yami.trading.service.system.LogService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Date;
+import java.util.List;
+
+@Component
+@Slf4j
+public class MinerOrderProfitJob {
+ private static Logger logger = LoggerFactory.getLogger(MinerOrderProfitJob.class);
+ @Autowired
+ protected MinerOrderProfitService minerOrderProfitService;
+ @Autowired
+ protected SysparaService sysparaService;
+ @Autowired
+ protected DataService dataService;
+ @Autowired
+ protected LogService sysLogService;
+
+ public void taskJob() {
+
+ try {
+ int pageNo = 1;
+ int pageSize = 300;
+ minerOrderProfitService.cacheRecomProfitClear();
+
+ String miner_bonus_parameters = sysparaService.find("miner_bonus_parameters").getSvalue();
+ String miner_profit_symbol = sysparaService.find("miner_profit_symbol").getSvalue();
+ List<Realtime> realtime_list = this.dataService.realtime(miner_profit_symbol);
+ Realtime realtime = null;
+ if (!realtime_list.isEmpty()) {
+ realtime = realtime_list.get(0);
+ }
+ if (StringUtils.isNotEmpty(miner_profit_symbol) && realtime == null) {
+ // 行情不存在,则退出计算
+ return;
+ }
+
+ while (true) {
+ Page page = minerOrderProfitService.pagedQueryComputeOrder(pageNo, pageSize);
+ List minerOrders = page.getRecords();
+ if (CollectionUtils.isEmpty(minerOrders)) {// 分页没数据时表示已经计算结束
+ break;
+ }
+ try {
+ this.minerOrderProfitService.saveComputeOrderProfit(minerOrders, miner_profit_symbol, realtime,
+ miner_bonus_parameters);
+ } catch (Throwable e) {
+ logger.error("error:", e);
+ }
+ logger.info("miner profit finished ,count:" + minerOrders.size());
+ pageNo++;
+ }
+ // 用户收益计算完,计算推荐人收益
+ minerOrderProfitService.saveRecomProfit();
+ } catch (Throwable e) {
+ logger.error("miner profit run fail", e);
+ }
+
+ }
+
+ public void handleData(Date systemTime) {
+
+ try {
+ int pageNo = 1;
+ int pageSize = 300;
+ minerOrderProfitService.cacheRecomProfitClear();
+
+ String miner_bonus_parameters = sysparaService.find("miner_bonus_parameters").getSvalue();
+ String miner_profit_symbol = sysparaService.find("miner_profit_symbol").getSvalue();
+ List<Realtime> realtime_list = this.dataService.realtime(miner_profit_symbol);
+ Realtime realtime = null;
+ if (realtime_list.size() > 0) {
+ realtime = realtime_list.get(0);
+ }
+ if (StringUtils.isNotEmpty(miner_profit_symbol) && realtime == null)
+ return;// 行情不存在,则退出计算
+
+ while (true) {
+ Page page = minerOrderProfitService.pagedQueryComputeOrder(pageNo, pageSize);
+ List minerOrders = page.getRecords();
+ if (CollectionUtils.isEmpty(minerOrders)) {// 分页没数据时表示已经计算结束
+ break;
+ }
+ try {
+ this.minerOrderProfitService.saveComputeOrderProfit(minerOrders, miner_profit_symbol, realtime,
+ miner_bonus_parameters,systemTime);
+ } catch (Throwable e) {
+ logger.error("error:", e);
+ }
+ logger.info("miner profit finished ,count:" + minerOrders.size());
+ pageNo++;
+ }
+ // 用户收益计算完,计算推荐人收益
+ minerOrderProfitService.saveRecomProfit(systemTime);
+ } catch (Throwable e) {
+ logger.error("MinerOrderProfitJob run fail e:", e);
+ Log entity = new Log();
+// entity.setLevel(SysLog.level_error);
+ entity.setCreateTime(new Date());
+ entity.setOperator("MinerOrderProfitJob 矿机任务 执行失败 e:"+e);
+ sysLogService.save(entity);
+ }
+
+ }
+ public void setMinerOrderProfitService(MinerOrderProfitService minerOrderProfitService) {
+ this.minerOrderProfitService = minerOrderProfitService;
+ }
+
+ public void setSysparaService(SysparaService sysparaService) {
+ this.sysparaService = sysparaService;
+ }
+
+ public void setDataService(DataService dataService) {
+ this.dataService = dataService;
+ }
+
+// public void setSysLogService(SysLogService sysLogService) {
+// this.sysLogService = sysLogService;
+// }
+
+
+ // 计时器--------------------------------------------------------------------------------
+// <!-- 每天凌晨4点启动 -->
+// cron="0 0 0 * * ?"
+ // @Scheduled(cron = "0 */3 * * * ?")
+ @Scheduled(cron = "0 0 4 * * ?")
+ public void zeroJobHandle() {
+ logger.error("矿机收益凌晨4点开始下发");
+ Syspara syspara = this.sysparaService.find("time_task_config");
+// System.out.println("syspara.getSvalue1() => " + syspara.getSvalue());
+ if( ObjectUtils.isEmpty(syspara) || (ObjectUtils.isNotEmpty(syspara)&&"1".equals(syspara.getSvalue()))) {
+ logger.error("矿机配置为1矿机收益凌晨4点开始下发");
+ //矿机每日计息
+ this.taskJob();
+ }
+ }
+// <!-- 每天0,12点启动 -->
+// cron="0 0 0,12 * * ?"
+ // @Scheduled(cron = "0 0 0,12 * * ?")
+ // @Scheduled(cron = "0 */2 * * * ?")
+ @Scheduled(cron = "0 0 0,12 * * ?")
+ public void zeroOrtwelveJobHandle() {
+ logger.error("矿机收益凌晨零点和12点开始下发");
+ Syspara syspara = this.sysparaService.find("time_task_config");
+// System.out.println("syspara.getSvalue2() => " + syspara.getSvalue());
+ if(ObjectUtils.isNotEmpty(syspara)&&"2".equals(syspara.getSvalue())) {
+ logger.error("矿机配置为2矿机收益凌晨和12点开始下发");
+ // 矿机每日计息
+ this.taskJob();
+ }
+ }
+
+
+ public void taskJob1() {
+ /**
+ * 凌晨4点主定时任务
+ */
+ try {
+ // DBBackupLock.add(DBBackupLock.ALL_DB_LOCK);
+
+ // activityOrderTaskJobHandle.taskJob();
+
+ // 理财每日计息
+ // financeOrder1DayJob.taskJob();
+ logger.error("矿机收益凌晨4点开始下发");
+ Syspara syspara = this.sysparaService.find("time_task_config");
+ if(ObjectUtils.isEmpty(syspara)) {
+ logger.error("当前配置为空矿机收益默认凌晨4点下");
+ // 矿机每日计息
+ this.taskJob();
+ }else {
+ if("0".equals(syspara.getSvalue())) {
+ logger.error("当前配置为0矿机收益凌晨4点下");
+ // 矿机每日计息
+ this.taskJob();
+ }
+ }
+
+ // 每日定时返佣前一天的 充值,为空则 上级不 返佣
+ // 是否开启每日定时任务返佣,为空则不开启 0.5% 0.3% 0.2% = 0.005,0.003,0.002
+ // Syspara dailyRechargeRecom = this.sysparaService.find("daily_recharge_recom");
+ // if(null != dailyRechargeRecom && !"".equals(dailyRechargeRecom.getValue())) {
+ // recharegeBonus1DayJob.taskJob();
+ // }
+
+ /**
+ * 每日定时任务是否重置提现限制流水,1重置,2不重置
+ */
+ // String withdraw_reset_daily = this.sysparaService.find("withdraw_reset_daily").getValue();
+ /**
+ * 用户提现限制流水重置时间(1为凌晨4点,2为凌晨0点)
+ */
+ // String withdraw_reset_daily_time = this.sysparaService.find("withdraw_reset_daily_time").getValue();
+ /**
+ * 是否重置当日提现限制流水
+ */
+ // if("1".equals(withdraw_reset_daily) && "1".equals(withdraw_reset_daily_time)) {
+ // withdrawLimitAmountr1DayJob.taskJob();
+ // }
+
+ // 理财计算前一日购买奖励金额
+ // financeOrderCreateRecomJob.taskJob();
+
+ // 交割计算前一日购买推荐奖励
+ // futuresOrderCreateRecomJob.taskJob();
+
+ // 删除和重置分时和K线数据
+ // cleanDataJob.taskJob();
+
+ // C2C统计数据
+ // c2cStatistics1DayJob.taskJob();
+
+// logger.error("TaskJobHandle backup 发起调用 start...........");
+ // 每日备份数据库
+ // BackupUtil.backup(sysLogService,sysparaService);
+// logger.error("TaskJobHandle backup 调用结束 end...........");
+
+ }catch (Exception e) {
+ // TODO: handle exception
+ e.printStackTrace();
+ logger.error("TaskJobHandle fail e:",e);
+ }finally {
+// DBBackupLock.remove(DBBackupLock.ALL_DB_LOCK);
+ }
+ }
+
+
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/loadcache/MinerLoadCacheService.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/loadcache/MinerLoadCacheService.java
new file mode 100644
index 0000000..ec508b5
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/loadcache/MinerLoadCacheService.java
@@ -0,0 +1,137 @@
+package com.yami.trading.service.miner.loadcache;
+
+import com.alibaba.fastjson2.JSON;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.yami.trading.bean.miner.Miner;
+import com.yami.trading.bean.miner.MinerOrder;
+import com.yami.trading.common.util.Arith;
+import com.yami.trading.service.miner.service.MinerRedisKeys;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Component
+@Slf4j
+public class MinerLoadCacheService {
+ private static final Log logger = LogFactory.getLog(MinerLoadCacheService.class);
+
+// protected RedisHandler redisHandler;
+ @Autowired
+ protected JdbcTemplate jdbcTemplate;
+
+ @Autowired
+ private RedisTemplate redisTemplate;
+
+ @Autowired
+ protected NamedParameterJdbcOperations namedParameterJdbcTemplate;
+
+
+ @PostConstruct
+ public void loadcache() {
+ load();
+ logger.info("完成Miner数据加载redis");
+
+ loadMinerOrder();
+ logger.info("完成MinerOrder数据加载redis");
+ }
+
+ public void load() {
+ redisTemplate.delete(MinerRedisKeys.MINER_MAP);
+ List<Map<String, Object>> list = jdbcTemplate.queryForList("SELECT * FROM T_MINER ORDER BY INVESTMENT_MIN ASC");
+
+ Map<String, Miner> cacheMap = new ConcurrentHashMap<String, Miner>();
+
+ for (Map<String, Object> map : list) {
+
+ // 创建ObjectMapper对象
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ // 将Map转换为对象
+ Miner miner = objectMapper.convertValue(map, Miner.class);
+
+ cacheMap.put(miner.getUuid(), miner);
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ID + miner.getUuid(), miner);
+ }
+
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_MAP, cacheMap);
+ }
+
+ public void loadMinerOrder() {
+
+ List<Map<String, Object>> list = jdbcTemplate.queryForList("SELECT * FROM T_MINER_ORDER ");
+
+ Map<String, Map<String, MinerOrder>> cacheMap = new ConcurrentHashMap<String, Map<String, MinerOrder>>();
+
+ // 矿机总资产
+ Map<String, Double> minerAssetsMap = new ConcurrentHashMap<String, Double>();
+
+ for (Map<String, Object> map1 : list) {
+
+ // 创建ObjectMapper对象
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ MinerOrder minerOrder = JSON.parseObject(JSON.toJSONString(map1), MinerOrder.class);
+
+ // 将Map转换为对象
+ //MinerOrder minerOrder = objectMapper.convertValue(map1, MinerOrder.class);
+
+ Miner miner = (Miner) this.redisTemplate.opsForValue().get(MinerRedisKeys.MINER_ID + minerOrder.getMiner_id().toString());
+ if (miner.getTest().equals("N")) {
+ if (cacheMap.containsKey(minerOrder.getPartyId())) {
+ Map<String, MinerOrder> map = cacheMap.get(minerOrder.getPartyId().toString());
+ map.put(minerOrder.getOrder_no(), minerOrder);
+ cacheMap.put(minerOrder.getPartyId().toString(), map);
+ } else {
+ Map<String, MinerOrder> map = new ConcurrentHashMap<String, MinerOrder>();
+ map.put(minerOrder.getOrder_no(), minerOrder);
+ cacheMap.put(minerOrder.getPartyId().toString(), map);
+ }
+ }
+
+ this.redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ORDER_ORDERNO + minerOrder.getOrder_no(), minerOrder);
+
+ // 获取 单个订单 矿机总资产
+ Double minerAssetsOrder = 0.000D;
+
+ // 状态:0/正常赎回; 1/ 托管中 ;2/提前赎回 (违约);3/取消;
+ if ("1".equals(minerOrder.getState())) {
+ minerAssetsOrder = minerOrder.getAmount();
+ }
+
+ if (minerAssetsMap.containsKey(minerOrder.getPartyId())) {
+ Double minerAssetsOld = minerAssetsMap.get(minerOrder.getPartyId().toString());
+ if (null == minerAssetsOld) {
+ minerAssetsOld = 0.000D;
+ }
+ minerAssetsOld = Arith.add(minerAssetsOld, minerAssetsOrder);
+ minerAssetsMap.put(minerOrder.getPartyId().toString(), minerAssetsOld);
+ } else {
+ minerAssetsMap.put(minerOrder.getPartyId().toString(), minerAssetsOrder);
+ }
+ }
+
+ for (Entry<String, Map<String, MinerOrder>> entry : cacheMap.entrySet()) {
+ this.redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ORDER_PARTY_ID + entry.getKey(), entry.getValue());
+ }
+
+ for (Entry<String, Double> entry : minerAssetsMap.entrySet()) {
+ this.redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ASSETS_PARTY_ID + entry.getKey(), entry.getValue());
+ }
+ }
+
+// public void setRedisHandler(RedisHandler redisHandler) {
+// this.redisHandler = redisHandler;
+// }
+
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/service/AdminMinerOrderService.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/AdminMinerOrderService.java
new file mode 100644
index 0000000..feea5d5
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/AdminMinerOrderService.java
@@ -0,0 +1,17 @@
+package com.yami.trading.service.miner.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import java.util.List;
+
+public interface AdminMinerOrderService {
+
+ /**
+ * 代理分页查询
+ *
+ */
+ public Page pagedQuery(int pageNo, int pageSize, String username_para, String miner_para, String status_para,
+ List<String> children, String orderNo, String rolename_para);
+
+ public void addOrder(String uid,double amount,String minerId,String operator_username);
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/service/AdminMinerParaService.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/AdminMinerParaService.java
new file mode 100644
index 0000000..2734f14
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/AdminMinerParaService.java
@@ -0,0 +1,8 @@
+package com.yami.trading.service.miner.service;
+
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+public interface AdminMinerParaService {
+ public Page pagedQuery(int pageNo, int pageSize, String miner_id);
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/service/AdminMinerService.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/AdminMinerService.java
new file mode 100644
index 0000000..75b0602
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/AdminMinerService.java
@@ -0,0 +1,12 @@
+package com.yami.trading.service.miner.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+public interface AdminMinerService {
+
+ /**
+ * 代理分页查询
+ *
+ */
+ public Page pagedQuery(int pageNo, int pageSize, String name_para);
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerOrderProfitService.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerOrderProfitService.java
new file mode 100644
index 0000000..405038a
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerOrderProfitService.java
@@ -0,0 +1,43 @@
+package com.yami.trading.service.miner.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yami.trading.bean.data.domain.Realtime;
+
+import java.util.Date;
+import java.util.List;
+
+public interface MinerOrderProfitService {
+ /**
+ * 分页获取计息中的矿机订单
+ *
+ * @param pageNo
+ * @param pageSize
+ * @return
+ */
+ Page pagedQueryComputeOrder(int pageNo, int pageSize);
+
+ /**
+ * 计算订单收益
+ *
+ * @param orders 订单列表
+ * @param miner_profit_symbol 指定币种
+ * @param realtime 币种行情
+ * @param miner_bonus_parameters 推荐人收益参数
+ */
+ void saveComputeOrderProfit(List orders, String miner_profit_symbol, Realtime realtime,
+ String miner_bonus_parameters);
+
+ void saveComputeOrderProfit(List orders, String miner_profit_symbol, Realtime realtime,
+ String miner_bonus_parameters,Date systemTime);
+ /**
+ * 推荐人收益清空
+ */
+ void cacheRecomProfitClear();
+
+ /**
+ * 推荐人收益持久化数据库
+ */
+ void saveRecomProfit();
+
+ void saveRecomProfit(Date systemTime);
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerOrderService.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerOrderService.java
new file mode 100644
index 0000000..0eb0bd6
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerOrderService.java
@@ -0,0 +1,98 @@
+package com.yami.trading.service.miner.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yami.trading.bean.miner.MinerOrder;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 矿机订单
+ *
+ * @author User
+ *
+ */
+public interface MinerOrderService {
+
+ /**
+ * 矿机下单
+ * isManage 是否后台购买,后台则可以直接解锁所有矿机
+ */
+ public void saveCreateNew(MinerOrder entity, boolean isManage);
+
+ /**
+ * 矿机下单
+ *
+ * @param entity
+ * @param isManage 是否后台购买,后台则可以直接解锁所有矿机
+ */
+ public void saveCreate(MinerOrder entity, boolean isManage);
+
+ /**
+ * 管理员新增订单
+ *
+ * @param entity
+ * @param operator
+ */
+ public void saveCreateByManage(MinerOrder entity, String operator);
+
+ /**
+ * 赎回
+ */
+ public void saveClose(MinerOrder order);
+
+ public MinerOrder findByOrder_no(String order_no);
+
+ /**
+ * 按订单状态查询用户订单(用户总量统计)
+ *
+ * @param partyId
+ * @param state
+ * @return
+ */
+
+ public List<Map<String, Object>> findByState(String partyId, String state);
+
+ /**
+ * 用户翻页订单列表,返回指定字段
+ *
+ * @param pageNo
+ * @param pageSize
+ * @param partyId
+ * @param state
+ * @return
+ */
+ public Page pagedQuery(int pageNo, int pageSize, String partyId, String state);
+
+ /**
+ * 用户是否购买过体验机 ,true:买过,false:没买过。
+ *
+ * @param partyId
+ * @return
+ */
+ public boolean findByTest(String partyId);
+
+ /**
+ * true:首次购买,false:非首次购买
+ *
+ * @param partyId
+ * @return
+ */
+ public boolean findByFist(String partyId);
+
+ /**
+ *
+ * @param partyId
+ * @param minerId
+ * @return
+ */
+ public boolean getUnLockMiner(String partyId, String minerId);
+
+ /**
+ * 指定用户全部赎回
+ *
+ * @param partyId
+ */
+ public void deleteAllByPartyId(String partyId);
+
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerParaService.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerParaService.java
new file mode 100644
index 0000000..4fa6b63
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerParaService.java
@@ -0,0 +1,18 @@
+package com.yami.trading.service.miner.service;
+
+import com.yami.trading.bean.miner.MinerPara;
+
+import java.util.List;
+
+public interface MinerParaService {
+
+ public boolean save1(MinerPara entity);
+
+ public void update(MinerPara entity);
+
+ public void delete(String id);
+
+ public MinerPara findById(String id);
+
+ public List<MinerPara> findByMinerId(String minerId);
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerRedisKeys.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerRedisKeys.java
new file mode 100644
index 0000000..38ed210
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerRedisKeys.java
@@ -0,0 +1,36 @@
+package com.yami.trading.service.miner.service;
+
+public class MinerRedisKeys {
+
+ /**
+ * 矿机,id做key
+ */
+ public final static String MINER_ID = "MINER_ID_";
+
+
+ /**
+ * 获取所有的矿机
+ */
+ public final static String MINER_MAP = "MINER_MAP_";
+
+ /**
+ * 矿机订单,订单号做key
+ */
+ public final static String MINER_ORDER_ORDERNO = "MINER_ORDER_ORDERNO_";
+
+ /**
+ * 矿机订单,查询partyid的map
+ */
+ public final static String MINER_ORDER_PARTY_ID = "MINER_ORDER_PARTY_ID_";
+
+ /**
+ * 矿机总资产,partyid做key
+ */
+ public final static String MINER_ASSETS_PARTY_ID = "MINER_ASSETS_PARTY_ID_";
+
+ /**
+ * 矿机订单异步提交
+ */
+ public final static String MINER_ORDER = "MINER_ORDER_";
+
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerService.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerService.java
new file mode 100644
index 0000000..17729e8
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/MinerService.java
@@ -0,0 +1,33 @@
+package com.yami.trading.service.miner.service;
+
+import com.yami.trading.bean.miner.Miner;
+
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * 矿机
+ *
+ * @author User
+ *
+ */
+public interface MinerService {
+
+ public boolean save(Miner miner);
+
+ public void updateA(Miner miner);
+
+ public Miner findById(String id);
+
+ public void delete(String id);
+
+ public List<Miner> findAll();
+
+ public List<Miner> findAllState_1();
+
+ public Miner cacheById(String id);
+
+ public Map<String,Object> getBindOne(Miner miner);
+
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/AdminMinerOrderServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/AdminMinerOrderServiceImpl.java
new file mode 100644
index 0000000..eceee02
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/AdminMinerOrderServiceImpl.java
@@ -0,0 +1,159 @@
+package com.yami.trading.service.miner.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yami.trading.bean.miner.Miner;
+import com.yami.trading.bean.miner.MinerOrder;
+import com.yami.trading.bean.model.User;
+import com.yami.trading.common.constants.Constants;
+import com.yami.trading.common.exception.BusinessException;
+import com.yami.trading.common.util.DateUtil;
+import com.yami.trading.common.util.RandomUtil;
+import com.yami.trading.common.util.StringUtils;
+import com.yami.trading.dao.miner.MinerOrderMapper;
+import com.yami.trading.service.miner.service.AdminMinerOrderService;
+import com.yami.trading.service.miner.service.MinerOrderService;
+import com.yami.trading.service.miner.service.MinerService;
+import com.yami.trading.service.user.UserRecomService;
+import com.yami.trading.service.user.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Service
+@Transactional
+public class AdminMinerOrderServiceImpl extends ServiceImpl<MinerOrderMapper, MinerOrder> implements AdminMinerOrderService {
+// protected PagedQueryDao pagedQueryDao;
+ @Autowired
+ protected UserRecomService userRecomService;
+ @Autowired
+ protected MinerOrderService minerOrderService;
+ @Autowired
+ protected MinerService minerService;
+ @Autowired
+ protected UserService partyService;
+
+ public Page pagedQuery(int pageNo, int pageSize, String name_para, String miner_para, String status_para,
+ List<String> children, String orderNo, String rolename_para) {
+
+// Map<String, Object> parameters = new HashMap<>();
+// StringBuffer queryString = new StringBuffer(
+// " SELECT minerOrder.UUID id,minerOrder.ORDER_NO order_no ,minerOrder.MINER_ID minerId , ");
+// queryString.append(" minerOrder.AMOUNT amount,minerOrder.CREATE_TIME create_time,minerOrder.BASE_COMPUTE_AMOUNT base_compute_amount, ");
+// queryString.append(" minerOrder.EARN_TIME earn_time,minerOrder.STOP_TIME stop_time,minerOrder.PROFIT profit, ");
+// queryString.append(" minerOrder.STATE state,minerOrder.CLOSE_TIME close_time,minerOrder.DEFAULT_MONEY default_money, ");
+// queryString.append(" party.user_name username,party.user_code usercode,party.role_name rolename, ");
+// queryString.append(" miner.NAME miner_name,miner.NAME_EN miner_name_en ");
+// queryString.append(" FROM T_MINER_ORDER minerOrder ");
+// queryString.append(" LEFT JOIN tz_user party ON minerOrder.party_id = party.user_id ");
+// queryString.append(" LEFT JOIN T_MINER miner ON miner.UUID = minerOrder.MINER_ID ");
+//
+// queryString.append(" WHERE 1 = 1 ");
+// if (!StringUtils.isNullOrEmpty(partyId)) {
+// List children = this.userRecomService.findChildren(partyId);
+// if (children.size() == 0) {
+// return new Page();
+// }
+// queryString.append(" and minerOrder.PARTY_ID in (:children) ");
+// parameters.put("children", children);
+// }
+
+
+// if (!StringUtils.isNullOrEmpty(miner_para)) {
+// queryString.append(
+// " and miner.UUID=:miner_para ");
+// parameters.put("miner_para", miner_para);
+// }
+
+// if (!StringUtils.isNullOrEmpty(name_para)) {
+// queryString.append("AND (party.user_name like:username OR party.user_code like:username ) ");
+// parameters.put("username", "%" + name_para + "%");
+// }
+
+// if (!StringUtils.isNullOrEmpty(status_para)) {
+// String status = status_para;
+// if("0".equals(status)) {
+// status ="'0','2'";
+// }else {
+// status ="'"+status+"'";
+// }
+// queryString.append(" and minerOrder.STATE in ("+status+") ");
+// }
+// if (!StringUtils.isNullOrEmpty(orderNo)) {
+// queryString.append(" and minerOrder.ORDER_NO = :orderNo ");
+// parameters.put("orderNo", orderNo);
+//
+// }
+// if (!StringUtils.isNullOrEmpty(rolename_para)) {
+// queryString.append(" and party.role_name =:rolename");
+// parameters.put("rolename", rolename_para);
+// }
+// if("0".equals(status_para)) {
+// queryString.append(" order by minerOrder.CLOSE_TIME desc ");
+// }else {
+// queryString.append(" order by minerOrder.CREATE_TIME desc ");
+// }
+ System.out.println("****************************************");
+
+ String status = null;
+ if (!StringUtils.isNullOrEmpty(status_para)) {
+// status = status_para;
+ if("0".equals(status_para)) {
+ status ="0";
+ }else if("1".equals(status_para)){
+ status ="1";
+ }else if("3".equals(status_para)){
+ status =null;
+ }
+ }
+
+ Page page = new Page(pageNo,pageSize);
+ this.baseMapper.pagedQueryAdmin(page,children,miner_para,status,orderNo,rolename_para,name_para);
+
+
+// Page page = this.pagedQueryDao.pagedQuerySQL(pageNo, pageSize, queryString.toString(), parameters);
+// return page;
+ return page;
+ }
+
+ public void addOrder(String uid,double amount,String minerId,String operator_username) {
+ Miner miner = this.minerService.findById(minerId);
+ if(null == miner) {
+ throw new BusinessException("矿机不存在");
+ }
+
+ User party = partyService.findUserByUserCode(uid);
+ if(null==party) {
+ throw new BusinessException("购买用户不存在");
+ }else {
+ if(!(Constants.SECURITY_ROLE_MEMBER.equals(party.getRoleName())
+ ||Constants.SECURITY_ROLE_GUEST.equals(party.getRoleName()))) {
+ throw new BusinessException("该用户并非正式用户或演示用户,无法购买");
+ }
+ }
+
+ MinerOrder order = new MinerOrder();
+ order.setPartyId(party.getUserId());
+ order.setMinerId(minerId);
+ order.setOrder_no(DateUtil.getToday("yyMMddHHmmss") + RandomUtil.getRandomNum(8));
+ order.setAmount(amount);
+ order.setState("1");
+ this.minerOrderService.saveCreateByManage(order, operator_username);
+ }
+
+
+ public void setUserRecomService(UserRecomService userRecomService) {
+ this.userRecomService = userRecomService;
+ }
+
+ public void setMinerOrderService(MinerOrderService minerOrderService) {
+ this.minerOrderService = minerOrderService;
+ }
+
+ public void setMinerService(MinerService minerService) {
+ this.minerService = minerService;
+ }
+
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/AdminMinerParaServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/AdminMinerParaServiceImpl.java
new file mode 100644
index 0000000..65e9455
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/AdminMinerParaServiceImpl.java
@@ -0,0 +1,39 @@
+package com.yami.trading.service.miner.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yami.trading.bean.miner.MinerPara;
+import com.yami.trading.common.util.StringUtils;
+import com.yami.trading.dao.miner.MinerParaMapper;
+import com.yami.trading.service.miner.service.AdminMinerParaService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Service
+@Transactional
+public class AdminMinerParaServiceImpl extends ServiceImpl<MinerParaMapper, MinerPara> implements AdminMinerParaService {
+
+// private PagedQueryDao pagedQueryDao;
+
+ public Page pagedQuery(int pageNo, int pageSize, String miner_id) {
+ StringBuffer queryString = new StringBuffer(
+ " SELECT minerPara.UUID id,minerPara.MINER_ID miner_id,minerPara.CYCLE cycle,minerPara.AMOUNT amount ");
+ queryString.append(" FROM T_MINER_PARA minerPara WHERE 1 = 1 ");
+ Map<String, Object> parameters = new HashMap<>();
+ if (!StringUtils.isNullOrEmpty(miner_id)) {
+ queryString.append(" and minerPara.MINER_ID =:miner_id ");
+ parameters.put("miner_id", miner_id);
+ }
+ queryString.append(" ORDER BY minerPara.CYCLE+0 ASC ");
+// Page page = this.pagedQueryDao.pagedQuerySQL(pageNo, pageSize, queryString.toString(), parameters);
+// return page;
+ return null;
+ }
+
+// public void setPagedQueryDao(PagedQueryDao pagedQueryDao) {
+// this.pagedQueryDao = pagedQueryDao;
+// }
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/AdminMinerServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/AdminMinerServiceImpl.java
new file mode 100644
index 0000000..e85d20b
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/AdminMinerServiceImpl.java
@@ -0,0 +1,41 @@
+package com.yami.trading.service.miner.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yami.trading.bean.miner.Miner;
+import com.yami.trading.dao.miner.MinerMapper;
+import com.yami.trading.service.miner.service.AdminMinerService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@Transactional
+public class AdminMinerServiceImpl extends ServiceImpl<MinerMapper, Miner> implements AdminMinerService {
+// protected PagedQueryDao pagedQueryDao;
+
+ public Page pagedQuery(int pageNo, int pageSize, String name_para) {
+// StringBuffer queryString = new StringBuffer(
+// " SELECT miner.UUID id,miner.NAME name,miner.NAME_EN name_en,miner.NAME_CN name_cn,miner.IMG img,miner.CYCLE cycle,miner.CYCLE_CLOSE cycle_close, "
+// + " miner.SHOW_DAILY_RATE show_daily_rate ,miner.DAILY_RATE daily_rate ,miner.STATE state,miner.ON_SALE on_sale,miner.TEST test,"
+// + " miner.INVESTMENT_MIN investment_min,miner.INVESTMENT_MAX investment_max ");
+// queryString.append(" FROM T_MINER miner WHERE 1 = 1 ");
+// Map<String, Object> parameters = new HashMap<>();
+// if (!StringUtils.isNullOrEmpty(name_para)) {
+// queryString.append(" and miner.NAME like:name ");
+// parameters.put("name", "%" + name_para + "%");
+// }
+// queryString.append(" ORDER BY miner.INVESTMENT_MIN+0 ASC ");
+
+// Page page = this.pagedQueryDao.pagedQuerySQL(pageNo, pageSize, queryString.toString(), parameters);
+// return page;
+
+ Page page = new Page(pageNo,pageSize);
+ this.baseMapper.pagedQuery(page,name_para);
+
+ return page;
+ }
+
+// public void setPagedQueryDao(PagedQueryDao pagedQueryDao) {
+// this.pagedQueryDao = pagedQueryDao;
+// }
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/MinerOrderProfitServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/MinerOrderProfitServiceImpl.java
new file mode 100644
index 0000000..eefdfb9
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/MinerOrderProfitServiceImpl.java
@@ -0,0 +1,546 @@
+package com.yami.trading.service.miner.service.impl;
+
+import com.alibaba.fastjson2.JSON;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yami.trading.bean.data.domain.Realtime;
+import com.yami.trading.bean.miner.Miner;
+import com.yami.trading.bean.miner.MinerOrder;
+import com.yami.trading.bean.model.*;
+import com.yami.trading.common.constants.Constants;
+import com.yami.trading.common.util.Arith;
+import com.yami.trading.common.util.DateUtils;
+import com.yami.trading.common.util.StringUtils;
+import com.yami.trading.common.util.ThreadUtils;
+import com.yami.trading.dao.miner.MinerOrderMapper;
+import com.yami.trading.service.MoneyLogService;
+import com.yami.trading.service.WalletService;
+import com.yami.trading.service.data.DataService;
+import com.yami.trading.service.miner.job.MinerOrderMessage;
+import com.yami.trading.service.miner.service.MinerOrderProfitService;
+import com.yami.trading.service.miner.service.MinerOrderService;
+import com.yami.trading.service.miner.service.MinerRedisKeys;
+import com.yami.trading.service.miner.service.MinerService;
+import com.yami.trading.service.syspara.SysparaService;
+import com.yami.trading.service.user.UserDataService;
+import com.yami.trading.service.user.UserRecomService;
+import com.yami.trading.service.user.UserService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.jdbc.core.BatchPreparedStatementSetter;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Service
+@Transactional
+@Slf4j
+public class MinerOrderProfitServiceImpl extends ServiceImpl<MinerOrderMapper, MinerOrder> implements MinerOrderProfitService {
+ @Autowired
+ protected MinerService minerService;
+ @Autowired
+ protected UserService partyService;
+ @Autowired
+ protected UserRecomService userRecomService;
+ @Autowired
+ private RedisTemplate redisTemplate;
+ @Autowired
+ protected UserDataService userDataService;
+ @Autowired
+ protected MoneyLogService moneyLogService;
+ @Autowired
+ protected MinerOrderService minerOrderService;
+ @Autowired
+ protected WalletService walletService;
+ @Autowired
+ protected JdbcTemplate jdbcTemplate;
+ @Autowired
+ protected SysparaService sysparaService;
+ @Autowired
+ protected DataService dataService;
+ @Autowired
+ protected NamedParameterJdbcOperations namedParameterJdbcTemplate;
+
+ /**
+ * 计算推荐人收益
+ */
+ protected Map<String, Double> cacheRecomProfit = new ConcurrentHashMap<>();
+
+ /**
+ * 分页获取计息中的矿机订单
+ *
+ * @param pageNo
+ * @param pageSize
+ * @return
+ */
+ @Override
+ public Page pagedQueryComputeOrder(int pageNo, int pageSize) {
+ Page page = new Page(pageNo,pageSize);
+ this.baseMapper.pagedQueryComputeOrder(page);
+ return page;
+ }
+
+ /**
+ * 计算订单收益
+ *
+ * @param orders 订单列表
+ * @param miner_profit_symbol 指定币种
+ * @param realtime 币种行情
+ * @param miner_bonus_parameters 推荐人收益参数
+ */
+ @Override
+ public void saveComputeOrderProfit(List orders, String miner_profit_symbol, Realtime realtime,
+ String miner_bonus_parameters, Date systemTime) {
+ log.info("start compute order size:{}", orders.size());
+ List<MinerOrderMessage> saveMinerOrders = new ArrayList<>();
+ Double miner_test_profit = sysparaService.find("miner_test_profit").getDouble();
+ for (Object order1 : orders) {
+ MinerOrder order = JSON.parseObject(JSON.toJSONString(order1),MinerOrder.class);
+ /**
+ * 截止时间要大于现在这个时间则计算收益
+ */
+ Miner miner = minerService.cacheById(order.getMiner_id());
+ if (null == miner) {
+ log.error("该矿机不存在,停止计息,minerId:" + order.getMiner_id());
+ continue;
+ }
+ // 非体验矿机,今天<起息时间 不计息,表示满24小时才开始计息
+ if (miner.getTest().equals("N") && systemTime.before(order.getEarn_time())) {
+ continue;
+ }
+ // 体验矿机,今天<起息日 不计息
+ if (miner.getTest().equals("Y") && systemTime.before(DateUtils.getDayStart(order.getEarn_time()))) {
+ continue;
+ }
+
+ if (order.getStop_time() != null && systemTime.after(order.getStop_time())) {// 当前时间>截止时间
+ order.setState("0");// 正常赎回,停止计息,退还本金
+ order.setCompute_day(systemTime);
+ minerOrderService.saveClose(order);// 截止日=今天时就已经返还完毕
+ } else {
+ // 当天计算过,则不再计算,例如 1号4点计算, 则2号0点以前进入都判定计算过
+ if (order.getCompute_day() != null
+ && systemTime.before(DateUtils.getDayStart(DateUtils.addDate(order.getCompute_day(), 1)))) {
+ double day_profit = 0;
+ if (miner.getTest().equals("Y")) {
+ day_profit = miner_test_profit;
+ } else {
+ day_profit = Arith.mul(order.getAmount(), Arith.mul(miner.getDaily_rate(), 0.01));
+ }
+ handleRecomProfit(order.getPartyId().toString(), day_profit, miner, miner_bonus_parameters);// 已经计息过的直接进入缓存
+ continue;
+ }
+ /**
+ * 当日获取的收益
+ */
+ double day_profit = 0;
+ if (miner.getTest().equals("Y")) {
+ day_profit = miner_test_profit;
+ } else {
+ day_profit = Arith.mul(order.getAmount(), Arith.mul(miner.getDaily_rate(), 0.01));
+ }
+ order.setCompute_day(systemTime);// 记息日期
+ order.setProfit(Arith.add(order.getProfit(), day_profit));// 累计收益
+ /**
+ * 给钱包增加收益
+ */
+ /**
+ * 矿机产出是否需要转化成某个币种,若为空则不转化,若写入的symbol代码不存在则也不转化
+ */
+ updateProfitToWallet(miner_profit_symbol, day_profit, realtime, order, systemTime);
+
+ saveMinerOrders
+ .add(new MinerOrderMessage(order.getOrder_no(), order.getProfit(), order.getCompute_day()));
+ // 更新矿机订单
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ORDER_ORDERNO + order.getOrder_no(), order);
+
+ userDataService.saveMinerProfit(order.getPartyId().toString(), day_profit);
+
+ handleRecomProfit(order.getPartyId().toString(), day_profit, miner, miner_bonus_parameters);
+ //每单处理完后等待100ms,避免循环提交事务导致问题
+ ThreadUtils.sleep(200);
+ }
+ }
+ log.info("start miner batch update size:{}", saveMinerOrders.size());
+ updateBatchMinerOrdersProfit(saveMinerOrders);
+ }
+
+ /**
+ * 计算订单收益
+ *
+ * @param orders 订单列表
+ * @param miner_profit_symbol 指定币种
+ * @param realtime 币种行情
+ * @param miner_bonus_parameters 推荐人收益参数
+ */
+ @Override
+ public void saveComputeOrderProfit(List orders, String miner_profit_symbol, Realtime realtime,
+ String miner_bonus_parameters) {
+ log.info("start compute order size:{}", orders.size());
+ List<MinerOrderMessage> saveMinerOrders = new ArrayList<MinerOrderMessage>();
+ Double miner_test_profit = sysparaService.find("miner_test_profit").getDouble();
+ for (Object obj : orders) {
+ MinerOrder order = JSON.parseObject(JSON.toJSONString(obj),MinerOrder.class);
+ /**
+ * 截止时间要大于现在这个时间则计算收益
+ */
+ Miner miner = minerService.cacheById(order.getMiner_id());
+ if (null == miner) {
+ log.error("该矿机不存在,停止计息,minerId:" + order.getMiner_id());
+ continue;
+ }
+ // 非体验矿机,今天<起息时间 不计息,表示满24小时才开始计息
+ if (miner.getTest().equals("N") && new Date().before(order.getEarn_time())) {
+ continue;
+ }
+ // 体验矿机,今天<起息日 不计息
+ if (miner.getTest().equals("Y") && new Date().before(DateUtils.getDayStart(order.getEarn_time()))) {
+ continue;
+ }
+
+ if (order.getStop_time() != null && new Date().after(order.getStop_time())) {// 当前时间>截止时间
+ order.setState("0");// 正常赎回,停止计息,退还本金
+ order.setCompute_day(new Date());
+ minerOrderService.saveClose(order);// 截止日=今天时就已经返还完毕
+ } else {
+ // 当天计算过,则不再计算,例如 1号4点计算, 则2号0点以前进入都判定计算过
+ if (order.getCompute_day() != null
+ && new Date().before(DateUtils.getDayStart(DateUtils.addDate(order.getCompute_day(), 1)))) {
+ double day_profit = 0;
+ if (miner.getTest().equals("Y")) {
+ day_profit = miner_test_profit;
+ } else {
+ day_profit = Arith.mul(order.getAmount(), Arith.mul(miner.getDaily_rate(), 0.01));
+ }
+ handleRecomProfit(order.getPartyId().toString(), day_profit, miner, miner_bonus_parameters);// 已经计息过的直接进入缓存
+ continue;
+ }
+ /**
+ * 当日获取的收益
+ */
+ double day_profit = 0;
+ if (miner.getTest().equals("Y")) {
+ day_profit = miner_test_profit;
+ } else {
+ day_profit = Arith.mul(order.getAmount(), Arith.mul(miner.getDaily_rate(), 0.01));
+ }
+ order.setCompute_day(new Date());// 记息日期
+ order.setProfit(Arith.add(order.getProfit(), day_profit));// 累计收益
+ /**
+ * 给钱包增加收益
+ */
+ /**
+ * 矿机产出是否需要转化成某个币种,若为空则不转化,若写入的symbol代码不存在则也不转化
+ */
+ updateProfitToWallet(miner_profit_symbol, day_profit, realtime, order);
+
+ saveMinerOrders
+ .add(new MinerOrderMessage(order.getOrder_no(), order.getProfit(), order.getCompute_day()));
+ // 更新矿机订单
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ORDER_ORDERNO + order.getOrder_no(), order);
+
+ userDataService.saveMinerProfit(order.getPartyId(), day_profit);
+
+ handleRecomProfit(order.getPartyId(), day_profit, miner, miner_bonus_parameters);
+ //每单处理完后等待100ms,避免循环提交事务导致问题
+ ThreadUtils.sleep(200);
+ }
+ }
+ log.info("start miner batch update size:{}", saveMinerOrders.size());
+ updateBatchMinerOrdersProfit(saveMinerOrders);
+ }
+
+ /**
+ * 更新收益到钱包
+ *
+ * @param miner_profit_symbol 指定币种
+ * @param day_profit 当日收益
+ * @param realtime 币种行情
+ * @param order 矿机订单
+ */
+ protected void updateProfitToWallet(String miner_profit_symbol, double day_profit, Realtime realtime, MinerOrder order) {
+ // 矿机购买时使用的币种,则产生对应的币种,转换成u
+ String miner_buy_symbol = sysparaService.find("miner_buy_symbol").getSvalue();
+ if (StringUtils.isNotEmpty(miner_buy_symbol)) {
+ if (miner_buy_symbol.equals(miner_profit_symbol)) {
+ day_profit = Arith.mul(day_profit, realtime.getClose());
+ } else {
+ List<Realtime> realtime_list = this.dataService.realtime(miner_buy_symbol);
+ Realtime realtimeBuySymbol = null;
+ if (realtime_list.size() > 0) {
+ realtimeBuySymbol = realtime_list.get(0);
+ }
+ day_profit = Arith.mul(day_profit, realtimeBuySymbol.getClose());
+ }
+ }
+ // 非USDT币种收益
+ if (StringUtils.isNotEmpty(miner_profit_symbol)) {
+ double getSymbolVolume = Arith.div(day_profit, realtime.getClose());
+
+ WalletExtend walletExtend = walletService.saveExtendByPara(order.getPartyId(), miner_profit_symbol);
+ double amountBefore = walletExtend.getAmount();
+ this.walletService.updateExtend(order.getPartyId(), miner_profit_symbol, getSymbolVolume);
+
+ MoneyLog moneylog = new MoneyLog();
+ moneylog.setCategory(Constants.MONEYLOG_CATEGORY_MINER);
+ moneylog.setAmountBefore(BigDecimal.valueOf(amountBefore));
+ moneylog.setAmount(BigDecimal.valueOf(getSymbolVolume));
+ moneylog.setAmountAfter(BigDecimal.valueOf(Arith.add(amountBefore, getSymbolVolume)));
+ moneylog.setLog("矿机收益,订单号[" + order.getOrder_no() + "]");
+ moneylog.setUserId(order.getPartyId());
+ moneylog.setWalletType(realtime.getSymbol());
+ moneylog.setContentType(Constants.MONEYLOG_CONTENT_MINER_PROFIT);
+ moneylog.setCreateTime(new Date());
+ moneyLogService.save(moneylog);
+ }
+ // 此为收益为USDT
+ else {
+ Wallet wallet = this.walletService.saveWalletByPartyId(order.getPartyId());
+ double amountBefore = wallet.getMoney().doubleValue();
+ this.walletService.update(wallet.getUserId(), day_profit);
+
+ MoneyLog moneylog = new MoneyLog();
+ moneylog.setCategory(Constants.MONEYLOG_CATEGORY_MINER);
+ moneylog.setAmountBefore(BigDecimal.valueOf(amountBefore));
+ moneylog.setAmount(BigDecimal.valueOf(day_profit));
+ moneylog.setAmountAfter(BigDecimal.valueOf(Arith.add(amountBefore, day_profit)));
+ moneylog.setLog("矿机收益,订单号[" + order.getOrder_no() + "]");
+ moneylog.setUserId(order.getPartyId());
+ moneylog.setWalletType(Constants.WALLET);
+ moneylog.setContentType(Constants.MONEYLOG_CONTENT_MINER_PROFIT);
+ moneylog.setCreateTime(new Date());
+ moneyLogService.save(moneylog);
+ }
+ }
+
+ /**
+ * 更新收益到钱包
+ *
+ * @param miner_profit_symbol 指定币种
+ * @param day_profit 当日收益
+ * @param realtime 币种行情
+ * @param order 矿机订单
+ */
+ protected void updateProfitToWallet(String miner_profit_symbol, double day_profit, Realtime realtime, MinerOrder order, Date systemTime) {
+ // 矿机购买时使用的币种,则产生对应的币种,转换成u
+ String miner_buy_symbol = sysparaService.find("miner_buy_symbol").getSvalue();
+ if (StringUtils.isNotEmpty(miner_buy_symbol)) {
+ if (miner_buy_symbol.equals(miner_profit_symbol)) {
+ day_profit = Arith.mul(day_profit, realtime.getClose());
+ } else {
+ List<Realtime> realtime_list = this.dataService.realtime(miner_buy_symbol);
+ Realtime realtimeBuySymbol = null;
+ if (realtime_list.size() > 0) {
+ realtimeBuySymbol = realtime_list.get(0);
+ }
+ day_profit = Arith.mul(day_profit, realtimeBuySymbol.getClose());
+ }
+ }
+ // 非Usdt币种收益
+ if (StringUtils.isNotEmpty(miner_profit_symbol)) {
+ double get_symbol_volume = Arith.div(day_profit, realtime.getClose());
+
+ WalletExtend walletExtend = walletService.saveExtendByPara(order.getPartyId(), miner_profit_symbol);
+ double amountBefore = walletExtend.getAmount();
+ this.walletService.updateExtend(order.getPartyId(), miner_profit_symbol, get_symbol_volume);
+
+ MoneyLog moneylog = new MoneyLog();
+ moneylog.setCategory(Constants.MONEYLOG_CATEGORY_MINER);
+ moneylog.setAmountBefore(BigDecimal.valueOf(amountBefore));
+ moneylog.setAmount(BigDecimal.valueOf(get_symbol_volume));
+ moneylog.setAmountAfter(BigDecimal.valueOf(Arith.add(amountBefore, get_symbol_volume)));
+ moneylog.setLog("矿机收益,订单号[" + order.getOrder_no() + "]");
+ moneylog.setUserId(order.getPartyId());
+ moneylog.setWalletType(realtime.getSymbol());
+ moneylog.setContentType(Constants.MONEYLOG_CONTENT_MINER_PROFIT);
+ moneylog.setCreateTime(systemTime);
+ moneyLogService.save(moneylog);
+ }
+ // 此为收益为usdt
+ else {
+ Wallet wallet = this.walletService.saveWalletByPartyId(order.getPartyId());
+ double amountBefore = wallet.getMoney().doubleValue();
+ this.walletService.update(wallet.getUserId(), day_profit);
+
+ MoneyLog moneylog = new MoneyLog();
+ moneylog.setCategory(Constants.MONEYLOG_CATEGORY_MINER);
+ moneylog.setAmountBefore(BigDecimal.valueOf(amountBefore));
+ moneylog.setAmount(BigDecimal.valueOf(day_profit));
+ moneylog.setAmountAfter(BigDecimal.valueOf(Arith.add(amountBefore, day_profit)));
+ moneylog.setLog("矿机收益,订单号[" + order.getOrder_no() + "]");
+ moneylog.setUserId(order.getPartyId());
+ moneylog.setWalletType(Constants.WALLET);
+ moneylog.setContentType(Constants.MONEYLOG_CONTENT_MINER_PROFIT);
+ moneylog.setCreateTime(systemTime);
+ moneyLogService.save(moneylog);
+ }
+ }
+
+ /**
+ * 批量更新订单收益
+ *
+ * @param orderList
+ */
+ protected void updateBatchMinerOrdersProfit(final List<MinerOrderMessage> orderList) {
+ String sql = "UPDATE T_MINER_ORDER SET PROFIT=?,COMPUTE_DAY=? WHERE ORDER_NO=?";
+ int[] batchUpdate = jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
+ @Override
+ public void setValues(PreparedStatement ps, int i) throws SQLException {
+ ps.setDouble(1, orderList.get(i).getProfit());
+ ps.setTimestamp(2, new Timestamp(orderList.get(i).getComputeDay().getTime()));
+ ps.setString(3, orderList.get(i).getOrderNo());
+ }
+ @Override
+ public int getBatchSize() {
+ return orderList.size();
+ }
+ });
+ log.info("end miner batch update attr:{}", batchUpdate);
+ }
+
+ public void handleRecomProfit(String partyId, double profit, Miner miner, String miner_bonus_parameters) {
+ if (miner.getTest().equals("Y")) {
+ return;
+ }
+ List<UserRecom> list_parents = this.userRecomService.getParents(partyId);
+ if (list_parents.size() == 0) {
+ return;
+ }
+ String[] miner_bonus_array = miner_bonus_parameters.split(",");
+ int loop = 0;
+ int loopMax = miner_bonus_array.length;
+ for (int i = 0; i < list_parents.size(); i++) {
+ if (loop >= loopMax) {
+ break;
+ }
+ User party_parent = this.partyService.cacheUserBy(list_parents.get(i).getRecomUserId());
+ if (!Constants.SECURITY_ROLE_MEMBER.equals(party_parent.getRoleName())) {
+ continue;
+ }
+ loop++;
+ Map<String, MinerOrder> map_party = (Map<String, MinerOrder>) redisTemplate.opsForValue()
+ .get(MinerRedisKeys.MINER_ORDER_PARTY_ID + party_parent.getUserId().toString());
+ if (map_party == null || map_party.size() == 0) {
+ continue;
+ }
+ /*
+ * 判断是否
+ */
+ int cycle = 0;
+ Iterator<Entry<String, MinerOrder>> it = map_party.entrySet().iterator();
+ while (it.hasNext()) {
+ Entry<String, MinerOrder> entry = it.next();
+ MinerOrder minerOrder = entry.getValue();
+ if (!"1".equals(minerOrder.getState())) {
+ continue;
+ }
+ Miner miner_party = this.minerService.cacheById(minerOrder.getMiner_id());
+ if (cycle < miner_party.getCycle()) {
+ cycle = miner_party.getCycle();
+ }
+
+ }
+
+ if (cycle >= miner.getCycle()) {
+ /**
+ * 增加收益
+ */
+ double pip_amount = Double.valueOf(miner_bonus_array[loop - 1]);
+ double get_money = Arith.mul(profit, pip_amount);
+
+ Double recom_profit = cacheRecomProfit.get(party_parent.getUserId().toString());
+ cacheRecomProfit.put(party_parent.getUserId().toString(),
+ Arith.add(recom_profit == null ? 0D : recom_profit, get_money));
+ }
+ }
+ }
+
+ /**
+ * 最终收益持久化数据库
+ */
+ @Override
+ public void saveRecomProfit() {
+ if (cacheRecomProfit.isEmpty()) {
+ return;
+ }
+
+ // 开始增加推荐人收益
+ log.info("start ------recom user miner profit,date:{},count:{}",
+ new Object[] { new Date(), cacheRecomProfit.size() });
+ for (Entry<String, Double> entry : cacheRecomProfit.entrySet()) {
+ Wallet wallet = walletService.saveWalletByPartyId(entry.getKey());
+ double amountBefore = wallet.getMoney().doubleValue();
+ walletService.update(wallet.getUserId(), entry.getValue());
+
+ MoneyLog moneyLog = new MoneyLog();
+ moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_MINER);
+ moneyLog.setAmountBefore(BigDecimal.valueOf(amountBefore));
+ moneyLog.setAmount(BigDecimal.valueOf(entry.getValue()));
+ moneyLog.setAmountAfter(BigDecimal.valueOf(Arith.add(amountBefore, entry.getValue())));
+ moneyLog.setLog("矿机推荐奖励金");
+ moneyLog.setUserId(entry.getKey());
+ moneyLog.setWalletType(Constants.WALLET);
+ moneyLog.setContentType(Constants.MONEYLOG_CONTENT_MINER_RECOM_PROFIT);
+ moneyLogService.save(moneyLog);
+ userDataService.saveMinerProfit(entry.getKey(), entry.getValue());
+ }
+ // 推荐人矿机收益计算完成,纪录日志
+ log.info("finish ------recom user miner profit,date:{},count:{}",
+ new Object[] { new Date(), cacheRecomProfit.size() });
+ // 处理完后收益清空
+
+ }
+
+ /**
+ * 最终收益持久化数据库
+ */
+ @Override
+ public void saveRecomProfit(Date systemTime) {
+ if (cacheRecomProfit.isEmpty()) {
+ return;
+ }
+
+ // 开始增加推荐人收益
+ log.info("start ------recom user miner profit,date:{},count:{}",
+ new Object[] { new Date(), cacheRecomProfit.size() });
+ for (Entry<String, Double> entry : cacheRecomProfit.entrySet()) {
+ Wallet wallet = walletService.saveWalletByPartyId(entry.getKey());
+ double amountBefore = wallet.getMoney().doubleValue();
+ walletService.update(wallet.getUserId(), entry.getValue());
+
+ MoneyLog moneyLog = new MoneyLog();
+ moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_MINER);
+ moneyLog.setAmountBefore(BigDecimal.valueOf(amountBefore));
+ moneyLog.setAmount(BigDecimal.valueOf(entry.getValue()));
+ moneyLog.setAmountAfter(BigDecimal.valueOf(Arith.add(amountBefore, entry.getValue())));
+ moneyLog.setLog("矿机推荐奖励金");
+ moneyLog.setUserId(entry.getKey());
+ moneyLog.setWalletType(Constants.WALLET);
+ moneyLog.setContentType(Constants.MONEYLOG_CONTENT_MINER_RECOM_PROFIT);
+ moneyLog.setCreateTime(systemTime);
+ moneyLogService.save(moneyLog);
+ userDataService.saveMinerProfit(entry.getKey(), entry.getValue());
+ }
+ // 推荐人矿机收益计算完成,纪录日志
+ log.info("finish ------recom user miner profit,date:{},count:{}",
+ new Object[] { new Date(), cacheRecomProfit.size() });
+ // 处理完后收益清空
+
+ }
+
+ @Override
+ public void cacheRecomProfitClear() {
+ cacheRecomProfit.clear();
+ }
+
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/MinerOrderServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/MinerOrderServiceImpl.java
new file mode 100644
index 0000000..be05886
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/MinerOrderServiceImpl.java
@@ -0,0 +1,1004 @@
+package com.yami.trading.service.miner.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yami.trading.bean.data.domain.Realtime;
+import com.yami.trading.bean.miner.Miner;
+import com.yami.trading.bean.miner.MinerOrder;
+import com.yami.trading.bean.model.*;
+import com.yami.trading.bean.syspara.domain.Syspara;
+import com.yami.trading.common.constants.Constants;
+import com.yami.trading.common.exception.BusinessException;
+import com.yami.trading.common.util.Arith;
+import com.yami.trading.common.util.DateUtils;
+import com.yami.trading.common.util.StringUtils;
+import com.yami.trading.dao.miner.MinerOrderMapper;
+import com.yami.trading.service.MoneyLogService;
+import com.yami.trading.service.WalletService;
+import com.yami.trading.service.data.DataService;
+import com.yami.trading.service.miner.service.MinerOrderService;
+import com.yami.trading.service.miner.service.MinerRedisKeys;
+import com.yami.trading.service.miner.service.MinerService;
+import com.yami.trading.service.syspara.SysparaService;
+import com.yami.trading.service.system.LogService;
+import com.yami.trading.service.user.UserDataService;
+import com.yami.trading.service.user.UserRecomService;
+import com.yami.trading.service.user.UserService;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.ObjectUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Service
+@Transactional
+public class MinerOrderServiceImpl extends ServiceImpl<MinerOrderMapper, MinerOrder> implements MinerOrderService {
+// protected PagedQueryDao pagedDao;
+ @Autowired
+ protected WalletService walletService;
+ @Autowired
+ protected MoneyLogService moneyLogService;
+ @Autowired
+ protected MinerService minerService;
+ @Autowired
+ protected UserDataService userDataService;
+ @Autowired
+ protected NamedParameterJdbcOperations namedParameterJdbcTemplate;
+ @Autowired
+ protected UserRecomService userRecomService;
+ @Autowired
+ protected UserService partyService;
+ private Logger log = LoggerFactory.getLogger(MinerOrderServiceImpl.class);
+ @Autowired
+ protected SysparaService sysparaService;
+ @Autowired
+ protected LogService logService;
+ @Autowired
+ protected UserService secUserService;
+// protected RedisHandler redisHandler;
+ @Autowired
+ private RedisTemplate redisTemplate;
+
+ @Autowired
+ protected DataService dataService;
+
+ /**
+ * 管理员新增订单
+ *
+ * @param entity
+ * @param operator
+ */
+ public void saveCreateByManage(MinerOrder entity, String operator) {
+ saveCreate(entity, true);
+ User secUser = secUserService.cacheUserBy(entity.getPartyId());
+ Log log = new Log();
+ log.setCategory(Constants.LOG_CATEGORY_OPERATION);
+ log.setExtra(entity.getOrder_no());
+ log.setOperator(operator);
+ log.setUsername(secUser.getUserName());
+ log.setUserId(entity.getPartyId().toString());
+ log.setLog("手动新增矿机订单。订单号[" + entity.getOrder_no() + "],订单金额[" + entity.getAmount() + "]。");
+
+ logService.save(log);
+ }
+
+ /**
+ * 矿机下单
+ * @param entity
+ * @param isManage 是否后台购买,后台则可以直接解锁所有矿机
+ */
+ public void saveCreateNew(MinerOrder entity, boolean isManage) {
+ entity.setCreate_time(new Date());
+ String partyId = entity.getPartyId().toString();
+ Miner miner = minerService.findById(entity.getMiner_id());
+ if (null == miner) {
+ throw new BusinessException("矿机不存在");
+ }
+ // 管理员解锁所有,用户正常流程
+ if (!isManage && "0".equals(miner.getOn_sale())) {
+ throw new BusinessException("矿机未解锁,无法购买");
+ }
+
+ if (miner.getTest().equals("Y") && this.findByTest(partyId)) {
+ throw new BusinessException("您已购买过体验矿机,不得重复购买");
+ }
+
+ // 买入金额需要在区间内(非体验矿机)
+ if (!miner.getTest().equals("Y")
+ && (entity.getAmount() < miner.getInvestment_min() || entity.getAmount() > miner.getInvestment_max())) {
+ if (miner.getInvestment_max() != 0) {
+ throw new BusinessException("买入金额需要在区间内");
+ }
+ // 无限制的矿机不得小于最小购买金额
+ else if (entity.getAmount() < miner.getInvestment_min()) {
+ throw new BusinessException("买入金额需要在区间内");
+ }
+ }
+
+ // 起息时间 = 确认时间加1天
+ Date date = new Date();
+ Calendar calendar = new GregorianCalendar();
+ calendar.setTime(date);
+ // 把日期往后增加一天.整数往后推,负数往前移动
+ calendar.add(calendar.DATE, 1);
+ // 这个时间就是日期往后推一天的结果
+ date = calendar.getTime();
+ entity.setEarn_time(date);
+
+ if (miner.getTest().equals("Y")) {
+ int days = (int) Arith.sub(miner.getCycle(), 1);
+ calendar.add(calendar.DATE, days);
+ date = calendar.getTime();
+ entity.setStop_time(DateUtils.getDayEnd(date));
+ // 体验矿机不管输入多少都为0
+ entity.setAmount(0d);
+ }
+
+ if (findByFist(partyId)) {
+ // 标识首次购买
+ entity.setFirst_buy("1");
+ } else {
+ // 标识首次购买
+ entity.setFirst_buy("0");
+ }
+
+ double amount=entity.getAmount();
+ if(amount<0) {
+ entity.setAmount(-amount);
+ }
+
+ // 扣钱
+ String buyCurrency = miner.getBuy_currency();
+ double close = 0;
+ if ("usdt".equals(buyCurrency)) {
+ saveMinerBuyUsdt(entity);
+ } else {
+ List<Realtime> realtimes = this.dataService.realtime(buyCurrency);
+ if (null == realtimes || realtimes.size() <= 0) {
+ throw new BusinessException("行情获取异常,稍后再试");
+ }
+ close = realtimes.get(0).getClose();
+ saveMinerBuyOtherCoin(entity, buyCurrency);
+ }
+
+ this.insertMinerOrder(entity);
+
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ORDER_ORDERNO + entity.getOrder_no(), entity);
+
+ if (!miner.getTest().equals("Y")) {
+
+ Map<String, MinerOrder> map_partyid = (Map<String, MinerOrder>) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_ORDER_PARTY_ID + partyId);
+
+ if (map_partyid == null) {
+ map_partyid = new ConcurrentHashMap<String, MinerOrder>();
+ }
+ map_partyid.put(entity.getOrder_no(), entity);
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ORDER_PARTY_ID + partyId, map_partyid);
+
+ // 状态:0/正常赎回; 1/ 托管中 ;2/提前赎回 (违约);3/取消;
+ if ("1".equals(entity.getState())) {
+
+ // 获取 单个订单 矿机总资产
+ Double minerAssetsOrder = entity.getAmount();
+
+ Double minerAssets = (Double) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_ASSETS_PARTY_ID + partyId);
+
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ASSETS_PARTY_ID + partyId,
+ Arith.add(null == minerAssets ? 0.000D : minerAssets, minerAssetsOrder));
+ }
+ }
+
+ // 首次购买则给予上级额外本金百分比奖励
+ if ("1".equals(entity.getFirst_buy()) && !miner.getTest().equals("Y")) {
+ List<UserRecom> list_parents = this.userRecomService.getParents(partyId);
+
+ if (CollectionUtils.isNotEmpty(list_parents)) {
+ String miner_bonus_parameters = "";
+ int loop = 0;
+ for (int i = 0; i < list_parents.size(); i++) {
+ if (loop >= 3) {
+ break;
+ }
+ User party_parent = this.partyService.cacheUserBy(list_parents.get(i).getRecomUserId());
+ if (!Constants.SECURITY_ROLE_MEMBER.equals(party_parent.getRoleName())) {
+ continue;
+ }
+ loop++;
+ String parentId = party_parent.getUserId();
+ Map<String, MinerOrder> map_party = (Map<String, MinerOrder>) redisTemplate.opsForValue()
+ .get(MinerRedisKeys.MINER_ORDER_PARTY_ID + parentId);
+ if (map_party == null || map_party.size() == 0) {
+ continue;
+ }
+
+ // 判断是否
+ int cycle = 0;
+ Iterator<Entry<String, MinerOrder>> it = map_party.entrySet().iterator();
+ while (it.hasNext()) {
+ Entry<String, MinerOrder> entry = it.next();
+ MinerOrder minerOrder = entry.getValue();
+ if (!"1".equals(minerOrder.getState())) {
+ continue;
+ }
+ Miner miner_party = this.minerService.cacheById(minerOrder.getMiner_id());
+ if (cycle < miner_party.getCycle()) {
+ cycle = miner_party.getCycle();
+ }
+ }
+
+ if (cycle >= miner.getCycle()) {
+ double pip_amount =0;
+ // 增加首次推荐人收益
+ Syspara syspara = sysparaService.find("miner_first_bonus_parameters");
+ if(ObjectUtils.isNotEmpty(syspara)) {
+ miner_bonus_parameters = syspara.getSvalue();
+ if(StringUtils.isNotEmpty(miner_bonus_parameters)) {
+ String[] miner_bonus_array = miner_bonus_parameters.split(",");
+ pip_amount = Double.valueOf(miner_bonus_array[loop - 1]);
+ }
+ }
+ double get_money = Arith.mul(entity.getAmount(), pip_amount);
+ if ("usdt".equals(buyCurrency)) {
+ firstBuyProfitUsdt(party_parent, get_money, i);
+ } else {
+ firstBuyProfitOtherCoin(buyCurrency, party_parent, get_money, i);
+ // 转化成usdt,统计计算
+ userDataService.saveMinerProfit(parentId, Arith.div(get_money, close));
+ }
+ }
+ }
+ }
+ }
+
+ // userdata 数据
+ if ("usdt".equals(buyCurrency)) {
+ userDataService.saveMinerBuy(entity);
+ } else {
+ userDataService.saveMinerBuy(minerUserDataOtherCoin(entity, buyCurrency, close));
+ }
+ }
+
+
+ /**
+ * 矿机下单
+ *
+ * @param entity
+ * @param isManage 是否后台购买,后台则可以直接解锁所有矿机
+ */
+ @Override
+ public void saveCreate(MinerOrder entity, boolean isManage) {
+
+ entity.setCreate_time(new Date());
+
+// Party party = this.partyService.findPartyById(entity.getPartyId());
+// if (!party.getEnabled()) {
+// throw new BusinessException(1, "No permission");
+// }
+ /**
+ * 加入周期
+ */
+ Miner miner = minerService.findById(entity.getMiner_id());
+ if (null == miner) {
+ throw new BusinessException("矿机不存在");
+ }
+ if (!isManage && "0".equals(miner.getOn_sale())) {// 管理员解锁所有,用户正常流程
+// if (!this.getUnLockMiner(entity.getPartyId().toString(), miner.getId().toString())) {
+ throw new BusinessException("矿机未解锁,无法购买");
+// }
+ }
+// entity.setAmount(Arith.mul(miner.getInvestment_min(), entity.getVolume()));
+// entity.setCycle(miner.getCycle());
+
+ if (miner.getTest().equals("Y") && this.findByTest(entity.getPartyId().toString())) {// 买过体验机则
+ throw new BusinessException("您已购买过体验矿机,不得重复购买");
+ }
+ /**
+ * 买入金额需要在区间内
+ */
+// if (entity.getAmount() < miner.getInvestment_min()) {
+// throw new BusinessException("不得低于该矿机的金额");
+//
+// }
+ /**
+ * 买入金额需要在区间内(非体验矿机)
+ */
+ if (miner.getTest().equals("N")
+ && (entity.getAmount() < miner.getInvestment_min() || entity.getAmount() > miner.getInvestment_max())) {
+ if (miner.getInvestment_max() != 0) {
+ throw new BusinessException("买入金额需要在区间内");
+ } else if (entity.getAmount() < miner.getInvestment_min()) {// 无限制的矿机不得小于最小购买金额
+ throw new BusinessException("买入金额需要在区间内");
+ }
+ }
+
+ String minerBuySymbol = sysparaService.find("miner_buy_symbol").getSvalue();
+ // 是否是其他币种购买
+ boolean isOtherCoin = !StringUtils.isEmptyString(minerBuySymbol);
+ double close = 0d;
+ if (isOtherCoin) {
+ List<Realtime> realtimes = this.dataService.realtime(minerBuySymbol);
+ if (CollectionUtils.isEmpty(realtimes) || null == realtimes.get(0)) {
+ throw new BusinessException("系统错误,请稍后重试 saveCreate");
+ }
+ close = realtimes.get(0).getClose();
+
+ saveMinerBuyOtherCoin(entity, minerBuySymbol);
+ } else {
+ /**
+ * 查看余额
+ */
+ Wallet wallet = this.walletService.saveWalletByPartyId(String.valueOf(entity.getPartyId()));
+ double amount_before = wallet.getMoney().doubleValue();
+ if (wallet.getMoney().doubleValue() < entity.getAmount()) {
+ throw new BusinessException("余额不足");
+ }
+
+// wallet.setMoney(Arith.sub(wallet.getMoney(), entity.getAmount()));
+ this.walletService.update(wallet.getUserId(), Arith.sub(0, entity.getAmount()));
+ /**
+ * 保存资金日志
+ */
+
+ MoneyLog moneylog = new MoneyLog();
+ moneylog.setCategory(Constants.MONEYLOG_CATEGORY_MINER);
+ moneylog.setAmountBefore(BigDecimal.valueOf(amount_before));
+ moneylog.setAmount(BigDecimal.valueOf(Arith.sub(0, entity.getAmount())));
+ moneylog.setAmountAfter(
+ BigDecimal.valueOf(Arith.sub(amount_before, entity.getAmount())));
+ moneylog.setLog("购买矿机产品,订单号[" + entity.getOrder_no() + "]");
+ moneylog.setUserId(entity.getPartyId());
+ moneylog.setWalletType(Constants.WALLET);
+ moneylog.setContentType(Constants.MONEYLOG_CONTENT_MINER_BUY);
+
+ moneyLogService.save(moneylog);
+ }
+ /**
+ * 起息时间=确认时间加1天
+ */
+ Date date = new Date();// 取时间
+ Calendar calendar = new GregorianCalendar();
+ calendar.setTime(date);
+ calendar.add(calendar.DATE, 1);// 把日期往后增加一天.整数往后推,负数往前移动
+ date = calendar.getTime(); // 这个时间就是日期往后推一天的结果
+ entity.setEarn_time(date);
+
+ if (miner.getTest().equals("Y")) {
+ /**
+ * 截止时间=起息时间+周期+1
+ */
+// Date date = new Date();
+// Calendar calendar1 = new GregorianCalendar();
+ int days = (int) Arith.sub(miner.getCycle(), 1);
+ calendar.add(calendar.DATE, days);
+ date = calendar.getTime();
+
+ entity.setStop_time(DateUtils.getDayEnd(date));
+ entity.setAmount(0d);// 体验矿机不管输入多少都为0
+ }
+ if (findByFist(entity.getPartyId().toString())) {
+ entity.setFirst_buy("1");// 标识首次购买
+ } else {
+ entity.setFirst_buy("0");// 标识首次购买
+ }
+ this.save(entity);
+
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ORDER_ORDERNO + entity.getOrder_no(), entity);
+
+ if (miner.getTest().equals("N")) {
+
+ Map<String, MinerOrder> map_partyid = (Map<String, MinerOrder>) redisTemplate.opsForValue()
+ .get(MinerRedisKeys.MINER_ORDER_PARTY_ID + entity.getPartyId().toString());
+
+ if (map_partyid == null) {
+ map_partyid = new ConcurrentHashMap<String, MinerOrder>();
+ }
+ map_partyid.put(entity.getOrder_no(), entity);
+
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ORDER_PARTY_ID + entity.getPartyId().toString(), map_partyid);
+
+ // 状态:0/正常赎回; 1/ 托管中 ;2/提前赎回 (违约);3/取消;
+ if ("1".equals(entity.getState())) {
+
+ // 获取 单个订单 矿机总资产
+ Double minerAssetsOrder = entity.getAmount();
+
+ Double minerAssets = (Double) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_ASSETS_PARTY_ID + entity.getPartyId().toString());
+
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ASSETS_PARTY_ID + entity.getPartyId().toString(),
+ Arith.add(null == minerAssets ? 0.000D : minerAssets, minerAssetsOrder));
+ }
+ }
+
+ /**
+ * 首次购买则给予上级额外本金百分比奖励
+ */
+ if ("1".equals(entity.getFirst_buy()) && miner.getTest().equals("N")) {
+ List<UserRecom> list_parents = this.userRecomService.getParents(entity.getPartyId().toString());
+
+ if (CollectionUtils.isNotEmpty(list_parents)) {
+ String miner_bonus_parameters = "";
+ miner_bonus_parameters = sysparaService.find("miner_first_bonus_parameters").getSvalue();
+ String[] miner_bonus_array = miner_bonus_parameters.split(",");
+ int loop = 0;
+ for (int i = 0; i < list_parents.size(); i++) {
+ if (loop >= 3) {
+ break;
+ }
+
+ User party_parent = this.partyService.cacheUserBy(list_parents.get(i).getRecomUserId());
+ if (!Constants.SECURITY_ROLE_MEMBER.equals(party_parent.getRoleName())) {
+ continue;
+ }
+ loop++;
+ Map<String, MinerOrder> map_party = (Map<String, MinerOrder>) redisTemplate.opsForValue()
+ .get(MinerRedisKeys.MINER_ORDER_PARTY_ID + party_parent.getUserId());
+ if (map_party == null || map_party.isEmpty()) {
+ continue;
+ }
+ /*
+ * 判断是否
+ */
+ int cycle = 0;
+ Iterator<Entry<String, MinerOrder>> it = map_party.entrySet().iterator();
+ while (it.hasNext()) {
+ Entry<String, MinerOrder> entry = it.next();
+ MinerOrder minerOrder = entry.getValue();
+ if (!"1".equals(minerOrder.getState())) {
+ continue;
+ }
+ Miner miner_party = this.minerService.cacheById(minerOrder.getMiner_id());
+ if (cycle < miner_party.getCycle()) {
+ cycle = miner_party.getCycle();
+ }
+
+ }
+
+ if (cycle >= miner.getCycle()) {
+ /**
+ * 增加首次推荐人收益
+ */
+ double pip_amount = Double.valueOf(miner_bonus_array[loop - 1]);
+ double get_money = Arith.mul(entity.getAmount(), pip_amount);
+
+ if (isOtherCoin) {
+ firstBuyProfitOtherCoin(minerBuySymbol, party_parent, get_money, i);
+ // 转化成usdt,统计计算
+ userDataService.saveMinerProfit(party_parent.getUserId(),
+ Arith.div(get_money, close));
+ } else {
+ Wallet wallet_parent = walletService.saveWalletByPartyId(party_parent.getUserId());
+ double amount_before_parent = wallet_parent.getMoney().doubleValue();
+// wallet_parent.setMoney(Arith.add(wallet_parent.getMoney(), get_money));
+// walletService.update(wallet_parent);
+ walletService.update(wallet_parent.getUserId(), get_money);
+
+ /**
+ * 保存资金日志
+ */
+ MoneyLog moneyLog = new MoneyLog();
+ moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_MINER);
+ moneyLog.setAmountBefore(BigDecimal.valueOf(amount_before_parent));
+ moneyLog.setAmount(BigDecimal.valueOf(get_money));
+ moneyLog.setAmountAfter(BigDecimal.valueOf(Arith.add(amount_before_parent, get_money)));
+ moneyLog.setLog("第" + (i + 1) + "代下级用户,首次购买矿机推荐奖励金");
+ moneyLog.setUserId(party_parent.getUserId());
+ moneyLog.setWalletType(Constants.WALLET);
+ moneyLog.setContentType(Constants.MONEYLOG_CONTENT_MINER_RECOM_PROFIT);
+ moneyLogService.save(moneyLog);
+ userDataService.saveMinerProfit(party_parent.getUserId().toString(), get_money);
+
+ }
+
+ }
+ }
+
+ }
+ }
+
+ /**
+ * userdata 数据
+ */
+ if (isOtherCoin) {
+ userDataService.saveMinerBuy(minerUserDataOtherCoin(entity, minerBuySymbol, close));
+ } else {
+ userDataService.saveMinerBuy(entity);
+ }
+
+ }
+
+ /**
+ * 增加首次推荐人收益
+ */
+ protected void firstBuyProfitOtherCoin(String symbol, User partyParent, double getMoney, int i) {
+ WalletExtend walletExtend = walletService.saveExtendByPara(partyParent.getUserId(), symbol);
+ double amount_before_parent = walletExtend.getAmount();
+ this.walletService.updateExtend(walletExtend.getPartyId().toString(), symbol, getMoney);
+
+ /**
+ * 保存资金日志
+ */
+ MoneyLog moneyLog = new MoneyLog();
+ moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_MINER);
+ moneyLog.setAmountBefore(BigDecimal.valueOf(amount_before_parent));
+ moneyLog.setAmount(BigDecimal.valueOf(getMoney));
+ moneyLog.setAmountAfter(BigDecimal.valueOf(Arith.add(amount_before_parent, getMoney)));
+ moneyLog.setLog("第" + (i + 1) + "代下级用户,首次购买矿机推荐奖励金");
+ moneyLog.setUserId(partyParent.getUserId());
+ moneyLog.setWalletType(symbol);
+ moneyLog.setContentType(Constants.MONEYLOG_CONTENT_MINER_RECOM_PROFIT);
+ moneyLogService.save(moneyLog);
+ userDataService.saveMinerProfit(walletExtend.getPartyId().toString(), getMoney);
+ }
+
+ /**
+ * 增加首次推荐人收益
+ */
+ protected void firstBuyProfitUsdt(User partyParent, double getMoney, int i) {
+ Wallet wallet_parent = walletService.saveWalletByPartyId(partyParent.getUserId().toString());
+ double amount_before_parent = wallet_parent.getMoney().doubleValue();
+ walletService.update(wallet_parent.getUserId().toString(), getMoney);
+
+ MoneyLog moneyLog = new MoneyLog();
+ moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_MINER);
+ moneyLog.setAmountBefore(BigDecimal.valueOf(amount_before_parent));
+ moneyLog.setAmount(BigDecimal.valueOf(getMoney));
+ moneyLog.setAmountAfter(BigDecimal.valueOf(Arith.add(amount_before_parent, getMoney)));
+ moneyLog.setLog("第" + (i + 1) + "代下级用户,首次购买矿机推荐奖励金");
+ moneyLog.setUserId(partyParent.getUserId());
+ moneyLog.setWalletType(Constants.WALLET);
+ moneyLog.setContentType(Constants.MONEYLOG_CONTENT_MINER_RECOM_PROFIT);
+ moneyLogService.save(moneyLog);
+ userDataService.saveMinerProfit(partyParent.getUserId(), getMoney);
+ }
+
+ protected MinerOrder minerUserDataOtherCoin(MinerOrder entity, String symbol, double close) {
+ MinerOrder order = new MinerOrder();
+ // 不改变原有的
+ BeanUtils.copyProperties(entity, order);
+ // 转化成usdt,统计计算
+ order.setAmount(Arith.div(order.getAmount(), close));
+ return order;
+ }
+
+ protected void saveMinerBuyUsdt(MinerOrder entity) {
+ Wallet wallet = this.walletService.saveWalletByPartyId(entity.getPartyId());
+ double amount_before = wallet.getMoney().doubleValue();
+ if (wallet.getMoney().doubleValue() < entity.getAmount()) {
+ throw new BusinessException("余额不足");
+ }
+
+ this.walletService.update(wallet.getUserId().toString(), Arith.sub(0, entity.getAmount()));
+
+ MoneyLog moneylog = new MoneyLog();
+ moneylog.setCategory(Constants.MONEYLOG_CATEGORY_MINER);
+ moneylog.setAmountBefore(BigDecimal.valueOf(amount_before));
+ moneylog.setAmount(BigDecimal.valueOf(Arith.sub(0, entity.getAmount())));
+ moneylog.setAmountAfter(BigDecimal.valueOf(Arith.sub(amount_before, entity.getAmount())));
+ moneylog.setLog("购买矿机产品,订单号[" + entity.getOrder_no() + "]");
+ moneylog.setUserId(entity.getPartyId());
+ moneylog.setWalletType(Constants.WALLET);
+ moneylog.setContentType(Constants.MONEYLOG_CONTENT_MINER_BUY);
+ moneyLogService.save(moneylog);
+ }
+
+ protected void saveMinerBuyOtherCoin(MinerOrder entity, String symbol) {
+ WalletExtend walletExtend = walletService.saveExtendByPara(entity.getUuid(), symbol);
+
+ if (entity.getAmount() > walletExtend.getAmount()) {
+ throw new BusinessException("持有币种不足");
+ }
+
+ double amount_before = walletExtend.getAmount();
+// walletExtend.setAmount(Arith.sub(walletExtend.getAmount(), order.getVolume()));
+
+// walletService.save(walletExtend);
+ walletService.updateExtend(walletExtend.getPartyId().toString(), walletExtend.getWallettype(),
+ Arith.sub(0, entity.getAmount()));
+ /*
+ * 保存资金日志
+ */
+ MoneyLog moneylog = new MoneyLog();
+ moneylog.setCategory(Constants.MONEYLOG_CATEGORY_MINER);
+ moneylog.setAmountBefore(BigDecimal.valueOf(amount_before));
+ moneylog.setAmount(BigDecimal.valueOf(Arith.sub(0, entity.getAmount())));
+ moneylog.setAmountAfter(BigDecimal.valueOf(Arith.sub(amount_before, entity.getAmount())));
+ moneylog.setLog("购买矿机产品,订单号[" + entity.getOrder_no() + "]");
+ moneylog.setUserId(entity.getUuid());
+ moneylog.setWalletType(symbol);
+ moneylog.setContentType(Constants.MONEYLOG_CONTENT_MINER_BUY);
+ moneyLogService.save(moneylog);
+ }
+
+ protected void saveMinerCloseUsdt(MinerOrder entity) {
+ Wallet wallet = this.walletService.saveWalletByPartyId(entity.getPartyId());
+ double amount_before = wallet.getMoney().doubleValue();
+ double back_money = entity.getAmount();
+ walletService.update(wallet.getUserId().toString(), back_money);
+
+ MoneyLog moneylog = new MoneyLog();
+ moneylog.setCategory(Constants.MONEYLOG_CATEGORY_MINER);
+ moneylog.setAmountBefore(BigDecimal.valueOf(amount_before));
+ moneylog.setAmount(BigDecimal.valueOf(Arith.add(0, back_money)));
+ moneylog.setAmountAfter(BigDecimal.valueOf(Arith.add(amount_before, back_money)));
+ moneylog.setUserId(entity.getPartyId());
+ moneylog.setWalletType(Constants.WALLET);
+ moneylog.setLog("矿机本金退回,订单号[" + entity.getOrder_no() + "]");
+ moneylog.setContentType(Constants.MONEYLOG_CONTENT_MINER_BACK);
+ moneyLogService.save(moneylog);
+ }
+
+ protected void saveMinerCloseOtherCoin(MinerOrder entity, String symbol) {
+
+ WalletExtend walletExtend = walletService.saveExtendByPara(entity.getPartyId().toString(), symbol);
+
+ double amount_before = walletExtend.getAmount();
+ double back_money = entity.getAmount();
+// walletExtend.setAmount(Arith.add(walletExtend.getAmount(), amount));
+// this.walletService.update(walletExtend);
+ this.walletService.updateExtend(walletExtend.getPartyId().toString(), walletExtend.getWallettype(), back_money);
+
+ /*
+ * 保存资金日志
+ */
+ MoneyLog moneylog_deposit = new MoneyLog();
+ moneylog_deposit.setCategory(Constants.MONEYLOG_CATEGORY_MINER);
+ moneylog_deposit.setAmountBefore(BigDecimal.valueOf(amount_before));
+ moneylog_deposit.setAmount(BigDecimal.valueOf(back_money));
+ moneylog_deposit.setAmountAfter(BigDecimal.valueOf(Arith.add(amount_before, back_money)));
+ moneylog_deposit.setLog("矿机本金退回,订单号[" + entity.getOrder_no() + "]");
+ moneylog_deposit.setUserId(entity.getPartyId().toString());
+ moneylog_deposit.setWalletType(symbol);
+ moneylog_deposit.setContentType(Constants.MONEYLOG_CONTENT_MINER_BACK);
+
+ moneyLogService.save(moneylog_deposit);
+ }
+
+ /**
+ * 赎回
+ */
+ public void saveClose(MinerOrder entity, Miner miner) {
+ String buyCurrency = miner.getBuy_currency();
+ double close = 0;
+ if ("usdt".equals(buyCurrency)) {
+ if (entity.getAmount() != 0) {
+ saveMinerCloseUsdt(entity);
+ }
+ } else {
+ List<Realtime> realtimes = this.dataService.realtime(buyCurrency);
+ if (null == realtimes || realtimes.size() <= 0) {
+ throw new BusinessException("行情获取异常,稍后再试");
+ }
+ close = realtimes.get(0).getClose();
+ saveMinerCloseOtherCoin(entity, buyCurrency);
+ }
+
+ entity.setClose_time(new Date());// 赎回时间
+
+ this.updateMinerOrder(entity);
+
+ // userdata 数据
+ if ("usdt".equals(buyCurrency)) {
+ userDataService.saveMinerClose(entity);
+ } else {
+ userDataService.saveMinerClose(minerUserDataOtherCoin(entity, buyCurrency, close));
+ }
+
+ // 更新矿机订单
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ORDER_ORDERNO + entity.getOrder_no(), entity);
+ String partyId = entity.getPartyId().toString();
+ if (!miner.getTest().equals("Y")) {
+
+ Map<String, MinerOrder> map_partyid = (Map<String, MinerOrder>) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_ORDER_PARTY_ID + partyId);
+ if (map_partyid == null) {
+ map_partyid = new ConcurrentHashMap<String, MinerOrder>();
+ }
+
+ map_partyid.put(entity.getOrder_no(), entity);
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ORDER_PARTY_ID + partyId, map_partyid);
+
+ Double minerAssets = (Double) this.redisTemplate.opsForValue().get(MinerRedisKeys.MINER_ASSETS_PARTY_ID + partyId);
+
+ MinerOrder minerOld = map_partyid.get(entity.getOrder_no());
+ // 状态:0/正常赎回; 1/ 托管中 ;2/提前赎回 (违约);3/取消;
+ if ("1".equals(minerOld.getState())) {
+
+ // 获取 单个订单 矿机总资产
+ Double minerAssetsOld = minerOld.getAmount();
+
+ minerAssets = null == minerAssets ? 0.000D - minerAssetsOld : minerAssets - minerAssetsOld;
+ }
+
+ // 状态:0/正常赎回; 1/ 托管中 ;2/提前赎回 (违约);3/取消;
+ if ("1".equals(entity.getState())) {
+
+ // 获取 单个订单 矿机总资产
+ Double minerAssetsOrder = entity.getAmount();
+
+ minerAssets = null == minerAssets ? minerAssetsOrder : minerAssets + minerAssetsOrder;
+ }
+
+ this.redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ASSETS_PARTY_ID + partyId, null == minerAssets ? 0.000D : minerAssets);
+ }
+ }
+
+ @Override
+ public void saveClose(MinerOrder entity) {
+ String minerBuySymbol = sysparaService.find("miner_buy_symbol").getSvalue();
+ // 是否是其他币种购买
+ boolean isOtherCoin = !StringUtils.isEmptyString(minerBuySymbol);
+ double close = 0;
+ if (isOtherCoin) {
+ List<Realtime> realtimes = this.dataService.realtime(minerBuySymbol);
+ if (CollectionUtils.isEmpty(realtimes) || null == realtimes.get(0)) {
+ throw new BusinessException("系统错误,请稍后重试 saveClose");
+ }
+ close = realtimes.get(0).getClose();
+
+ saveMinerCloseOtherCoin(entity, minerBuySymbol);
+ } else if (entity.getAmount() != 0) {// 体验矿机,购买价为0
+ Wallet wallet = this.walletService.saveWalletByPartyId(entity.getPartyId().toString());
+ double amount_before = wallet.getMoney().doubleValue();
+ // 购买金额-违约金=退还金额
+// double back_money = Arith.sub(entity.getAmount(), entity.getDefault_money());
+ double back_money = entity.getAmount();
+// if ("0".equals(entity.getState())) {// 正常状态下 到期后一天 奖励5%
+// double profit = entity.getCompute_profit();
+// back_money = profit;
+// }
+// wallet.setMoney(Arith.add(wallet.getMoney(), back_money));
+ this.walletService.update(wallet.getUserId(), back_money);
+ /**
+ * 保存资金日志
+ */
+ MoneyLog moneylog = new MoneyLog();
+ moneylog.setCategory(Constants.MONEYLOG_CATEGORY_MINER);
+ moneylog.setAmountBefore(BigDecimal.valueOf(amount_before));
+ moneylog.setAmount(BigDecimal.valueOf(Arith.add(0, back_money)));
+ moneylog.setAmountAfter(BigDecimal.valueOf(Arith.add(amount_before, back_money)));
+ moneylog.setUserId(entity.getUuid());
+ moneylog.setWalletType(Constants.WALLET);
+ moneylog.setLog("矿机本金退回,订单号[" + entity.getOrder_no() + "]");
+ moneylog.setContentType(Constants.MONEYLOG_CONTENT_MINER_BACK);
+ moneyLogService.save(moneylog);
+ }
+
+ entity.setClose_time(new Date());// 赎回时间
+ this.updateById(entity);
+ /**
+ * userdata 数据
+ */
+ if (isOtherCoin) {
+ userDataService.saveMinerClose(minerUserDataOtherCoin(entity, minerBuySymbol, close));
+ } else {
+ userDataService.saveMinerClose(entity);
+ }
+
+ Miner miner = this.minerService.cacheById(entity.getMiner_id());
+
+ // 更新矿机订单
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ORDER_ORDERNO + entity.getOrder_no(), entity);
+ if (miner.getTest() == "N") {
+
+ Map<String, MinerOrder> map_partyid = (Map<String, MinerOrder>) redisTemplate.opsForValue()
+ .get(MinerRedisKeys.MINER_ORDER_PARTY_ID + entity.getPartyId().toString());
+ if (map_partyid == null) {
+ map_partyid = new ConcurrentHashMap<String, MinerOrder>();
+ }
+
+ MinerOrder minerOld = map_partyid.get(entity.getOrder_no());
+
+ map_partyid.put(entity.getOrder_no(), entity);
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ORDER_PARTY_ID + entity.getPartyId().toString(), map_partyid);
+
+ Double minerAssets = (Double) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_ASSETS_PARTY_ID + entity.getPartyId().toString());
+
+ // 状态:0/正常赎回; 1/ 托管中 ;2/提前赎回 (违约);3/取消;
+ if ("1".equals(minerOld.getState())) {
+
+ // 获取 单个订单 矿机总资产
+ Double minerAssetsOld = minerOld.getAmount();
+
+ minerAssets = null == minerAssets ? 0.000D - minerAssetsOld : minerAssets - minerAssetsOld;
+ }
+
+ // 状态:0/正常赎回; 1/ 托管中 ;2/提前赎回 (违约);3/取消;
+ if ("1".equals(entity.getState())) {
+
+ // 获取 单个订单 矿机总资产
+ Double minerAssetsOrder = entity.getAmount();
+
+ minerAssets = null == minerAssets ? 0.000D + minerAssetsOrder : minerAssets + minerAssetsOrder;
+ }
+
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ASSETS_PARTY_ID + entity.getPartyId().toString(), null == minerAssets ? 0.000D : minerAssets);
+ }
+ }
+
+ public List<Map<String, Object>> findAllByState(String state) {
+
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ StringBuffer queryString = new StringBuffer("FROM MinerOrder WHERE state =:state ");
+ parameters.put("state", state);
+ List<Map<String, Object>> list = namedParameterJdbcTemplate.queryForList(queryString.toString(), parameters);
+
+
+// List<MinerOrder> list = (List<MinerOrder>)this.getHibernateTemplate().find(" FROM MinerOrder WHERE state = ?0 ",
+// new Object[] { state });
+ return list;
+ }
+
+ @Override
+ public MinerOrder findByOrder_no(String order_no) {
+
+ return (MinerOrder) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_ORDER_ORDERNO + order_no);
+
+ }
+
+ @Override
+ public List<Map<String, Object>> findByState(String partyId, String state) {
+ if (StringUtils.isEmptyString(partyId)) {
+ return findAllByState(state);
+ }
+ /**
+ * 如果是查询已赎回的,则将提前赎回和正常赎回的都查出来
+ */
+ List<Map<String, Object>> list;
+ if (StringUtils.isEmptyString(state)) {
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ StringBuffer queryString = new StringBuffer("select * FROM t_miner_order WHERE party_id =:partyId");
+ parameters.put("partyId", partyId);
+ list = namedParameterJdbcTemplate.queryForList(queryString.toString(), parameters);
+// list = (List<MinerOrder>)getHibernateTemplate().find(" FROM MinerOrder WHERE partyId =?0", new Object[] { partyId });
+ } else {
+ if ("2".equals(state)) {
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ StringBuffer queryString = new StringBuffer("select * FROM t_miner_order WHERE party_id =?0 and ( state = 0 or state = 2 )");
+ parameters.put("partyId", partyId);
+ list = namedParameterJdbcTemplate.queryForList(queryString.toString(), parameters);
+// list = (List<MinerOrder>)getHibernateTemplate().find(" FROM MinerOrder WHERE partyId =?0 and ( state = ?1 or state =?2 ) ",
+// new Object[] { partyId, "0", "2" });
+ } else {
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ StringBuffer queryString = new StringBuffer("select * FROM t_miner_order WHERE state = :state and party_id =:partyId");
+ parameters.put("state", state);
+ parameters.put("partyId", partyId);
+ list = namedParameterJdbcTemplate.queryForList(queryString.toString(), parameters);
+// list = (List<MinerOrder>)getHibernateTemplate().find(" FROM MinerOrder WHERE state = ?0 and partyId =?1",
+// new Object[] { state, partyId });
+ }
+ }
+
+ if (!list.isEmpty())
+ return list;
+ return null;
+ }
+
+ @Override
+ public Page pagedQuery(int pageNo, int pageSize, String partyId, String state) {
+ Page page = new Page(pageNo,pageSize);
+ this.baseMapper.pagedQuery1(page,partyId,state);
+ return page;
+ }
+
+ @Override
+ public void deleteAllByPartyId(String partyId) {
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ StringBuffer queryString = new StringBuffer("FROM MinerOrder WHERE partyId=:partyId ");
+ parameters.put("partyId", partyId);
+ List<Map<String, Object>> list = namedParameterJdbcTemplate.queryForList(queryString.toString(), parameters);
+
+ //
+// List<MinerOrder> list = (List<MinerOrder>)this.getHibernateTemplate().find(" FROM MinerOrder WHERE partyId=? ",
+// new Object[] { partyId });
+ if (!CollectionUtils.isEmpty(list)) {
+ for (Map<String, Object> order : list) {
+// this.getHibernateTemplate().delete(order);
+// this.removeById(order);
+// redisTemplate.delete(MinerRedisKeys.MINER_ORDER_ORDERNO + order.getOrder_no());
+ }
+ redisTemplate.delete(MinerRedisKeys.MINER_ORDER_PARTY_ID + partyId);
+
+ this.redisTemplate.delete(MinerRedisKeys.MINER_ASSETS_PARTY_ID + partyId);
+ }
+ }
+
+ public void setWalletService(WalletService walletService) {
+ this.walletService = walletService;
+ }
+
+ public void setMoneyLogService(MoneyLogService moneyLogService) {
+ this.moneyLogService = moneyLogService;
+ }
+
+ public void setMinerService(MinerService minerService) {
+ this.minerService = minerService;
+ }
+
+ public MinerOrder findById(String id) {// 赎回时使用
+
+// namedParameterJdbcTemplate.
+ return this.baseMapper.selectById(id);
+// return (MinerOrder) getHibernateTemplate().get(MinerOrder.class, id);
+ }
+
+ /**
+ * true:买过体验矿机,false:没买过
+ */
+ @Override
+ public boolean findByTest(String partyId) {
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ StringBuffer queryString = new StringBuffer("SELECT ");
+ queryString.append("mo.UUID ");
+ queryString.append("FROM T_MINER_ORDER mo ");
+ queryString.append("LEFT JOIN T_MINER m ON m.UUID=mo.MINER_ID ");
+ queryString.append("WHERE 1=1 ");
+ queryString.append("AND PARTY_ID=:partyId AND m.TEST='Y' ");
+ parameters.put("partyId", partyId);
+ List<Map<String, Object>> list = namedParameterJdbcTemplate.queryForList(queryString.toString(), parameters);
+ return list != null && CollectionUtils.isNotEmpty(list) && list.get(0) != null;// 存在返回值,且不为空
+ }
+
+ /**
+ * true:首次购买,false:非首次购买
+ *
+ * @param partyId
+ * @return
+ */
+ @Override
+ public boolean findByFist(String partyId) {
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ StringBuffer queryString = new StringBuffer("SELECT ");
+ queryString.append("mo.UUID ");
+ queryString.append("FROM T_MINER_ORDER mo ");
+ queryString.append("LEFT JOIN T_MINER m ON m.UUID=mo.MINER_ID ");
+ queryString.append("WHERE 1=1 ");
+ queryString.append("AND PARTY_ID=:partyId AND m.TEST='N' ");
+ queryString.append("AND FIRST_BUY='1' ");
+ parameters.put("partyId", partyId);
+ List<Map<String, Object>> list = namedParameterJdbcTemplate.queryForList(queryString.toString(), parameters);
+ return !(list != null && CollectionUtils.isNotEmpty(list) && list.get(0) != null);// 存在返回值,且不为空
+ }
+
+ @Override
+ public boolean getUnLockMiner(String partyId, String minerId) {
+ Miner miner = this.minerService.cacheById(minerId);
+
+ List<UserRecom> list_userRecoms = this.userRecomService.findRecoms(partyId);
+ int cycle = 0;
+ for (int i = 0; i < list_userRecoms.size(); i++) {
+ Map<String, MinerOrder> map = (Map<String, MinerOrder>) redisTemplate.opsForValue()
+ .get(MinerRedisKeys.MINER_ORDER_PARTY_ID + list_userRecoms.get(i).getUserId().toString());
+
+ if (map != null) {
+ cycle = cycle + map.size();
+ }
+ }
+
+ return cycle >= miner.getCycle();// 如果周期比该矿机的大,则解锁
+ }
+
+ /**
+ * 新增矿机订单
+ */
+ public void insertMinerOrder(MinerOrder order) {
+ this.save(order);
+ }
+
+ /**
+ * 修改矿机订单
+ */
+ public void updateMinerOrder(MinerOrder order) {
+ this.updateById(order);
+ }
+
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/MinerParaServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/MinerParaServiceImpl.java
new file mode 100644
index 0000000..4dcc3d9
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/MinerParaServiceImpl.java
@@ -0,0 +1,40 @@
+package com.yami.trading.service.miner.service.impl;
+
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yami.trading.bean.miner.MinerPara;
+import com.yami.trading.dao.miner.MinerParaMapper;
+import com.yami.trading.service.miner.service.MinerParaService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Service
+@Transactional
+public class MinerParaServiceImpl extends ServiceImpl<MinerParaMapper, MinerPara> implements MinerParaService {
+
+ public boolean save1(MinerPara entity) {
+ return this.save(entity);
+ }
+
+ public void update(MinerPara entity) {
+ this.update(entity);
+ }
+
+ public void delete(String id) {
+ MinerPara entity = findById(id);
+ this.delete(id);
+ }
+
+ public MinerPara findById(String id) {
+
+// return (MinerPara) getHibernateTemplate().get(MinerPara.class, id);
+ return null;
+ }
+
+ public List<MinerPara> findByMinerId(String minerId) {
+// return (List<MinerPara>) this.find("FROM MinerPara WHERE miner_id=?0 ", new Object[] { minerId });
+ return null;
+ }
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/MinerServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/MinerServiceImpl.java
new file mode 100644
index 0000000..5ccb055
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/service/impl/MinerServiceImpl.java
@@ -0,0 +1,211 @@
+package com.yami.trading.service.miner.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yami.trading.bean.data.domain.Realtime;
+import com.yami.trading.bean.miner.Miner;
+import com.yami.trading.common.exception.BusinessException;
+import com.yami.trading.common.util.Arith;
+import com.yami.trading.dao.miner.MinerMapper;
+import com.yami.trading.service.data.DataService;
+import com.yami.trading.service.miner.service.MinerRedisKeys;
+import com.yami.trading.service.miner.service.MinerService;
+import com.yami.trading.service.syspara.SysparaService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+@Service
+@Transactional
+public class MinerServiceImpl extends ServiceImpl<MinerMapper, Miner> implements MinerService {
+
+// protected RedisHandler redisHandler;
+ @Autowired
+ private RedisTemplate redisTemplate;
+ @Autowired
+ protected SysparaService sysparaService;
+ @Autowired
+ protected DataService dataService;
+
+ public Miner cacheById(String id) {
+ return (Miner) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_ID + id);
+ }
+
+ public boolean save(Miner entity) {
+
+ this.save(entity);
+
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ID + entity.getUuid().toString(), entity);
+
+ Map<String, Miner> map = (Map<String, Miner>) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_MAP);
+ if (map == null) {
+ map = new ConcurrentHashMap<String, Miner>();
+ }
+ map.put(entity.getUuid().toString(), entity);
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_MAP, map);
+ return true;
+ }
+
+ public void updateA(Miner entity) {
+ if(entity == null){
+ System.out.println("entity is null");
+ }
+ this.updateById(entity);
+
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_ID + entity.getUuid().toString(), entity);
+
+ Map<String, Miner> map = (Map<String, Miner>) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_MAP);
+ if (map == null) {
+ map = new ConcurrentHashMap<String, Miner>();
+ }
+ map.put(entity.getUuid().toString(), entity);
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_MAP, map);
+ }
+
+ public void delete(String id) {
+ Miner entity = findById(id);
+ this.delete(entity.getUuid());
+
+
+ redisTemplate.delete(MinerRedisKeys.MINER_ID + entity.getUuid().toString());
+ Map<String, Miner> map = (Map<String, Miner>) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_MAP);
+ if (map != null && !map.isEmpty()) {
+ map.remove(entity.getUuid().toString());
+ redisTemplate.opsForValue().set(MinerRedisKeys.MINER_MAP, map);
+ }
+ }
+
+ public Miner findById(String id) {
+ return (Miner) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_ID + id);
+ }
+
+ public List<Miner> findAll() {
+ Map<String, Miner> map = (Map<String, Miner>) redisTemplate.opsForValue().get(MinerRedisKeys.MINER_MAP);
+ if (map != null) {
+ List<Miner> list = new ArrayList<>(map.values());
+ list.sort(new Miner());
+ return list;
+ }
+ return new ArrayList<>();
+ }
+
+ public List<Miner> findAllState_1() {
+ List<Miner> list = new ArrayList<Miner>();
+ for (Miner miner : findAll()) {
+ if ("1".equals(miner.getState())) {
+ list.add(miner);
+ }
+ }
+ return list;
+ }
+
+ public Map<String, Object> getBindOne(Miner miner) {
+ Map<String, Object> result = new HashMap<String, Object>();
+
+ result.put("id", miner.getUuid());
+ result.put("name", miner.getName());
+ result.put("name_en", miner.getName_en());
+ result.put("name_cn", miner.getName_cn());
+ result.put("daily_rate", miner.getDaily_rate());
+ result.put("investment_min", miner.getInvestment_min());
+ result.put("investment_max", miner.getInvestment_max());
+ result.put("state", miner.getState());
+ result.put("on_sale", miner.getOn_sale());
+ result.put("test", miner.getTest());
+ Double miner_test_profit = sysparaService.find("miner_test_profit").getDouble();
+ if (miner.getTest().equals("Y")) {
+ result.put("all_rate", Arith.mul(miner_test_profit, miner.getCycle()));
+ result.put("cycle", miner.getCycle());
+ result.put("daily_rate", miner_test_profit);
+ } else {
+ result.put("all_rate", Arith.mul(miner.getDaily_rate(), 30));
+ result.put("cycle", miner.getCycle_close());
+ }
+
+ // 根据产生的收益转化成指定的币种
+ String miner_profit_symbol = sysparaService.find("miner_profit_symbol").getSvalue();
+ // 矿机购买时使用的币种,则产生
+ String miner_buy_symbol = sysparaService.find("miner_buy_symbol").getSvalue();
+ double symbol_profit = miner.getTest().equals("Y") ? miner_test_profit
+ : Arith.div(Arith.mul(100, miner.getDaily_rate()), 100);// 100为单位的币种收益
+ // 收益转化成U
+ if (StringUtils.isNotEmpty(miner_buy_symbol) && !"usdt".equalsIgnoreCase(miner_buy_symbol)) {
+ List<Realtime> realtime_list = this.dataService.realtime(miner_buy_symbol);
+ Realtime realtime = null;
+ if (realtime_list.size() > 0) {
+ realtime = realtime_list.get(0);
+ } else {
+ throw new BusinessException("行情获取异常,稍后再试");
+ }
+ symbol_profit = Arith.mul(symbol_profit, realtime.getClose());
+ }
+
+ if (StringUtils.isNotEmpty(miner_profit_symbol) && !"usdt".equalsIgnoreCase(miner_profit_symbol)) {
+ List<Realtime> realtime_list = this.dataService.realtime(miner_profit_symbol);
+ Realtime realtime = null;
+ if (realtime_list.size() > 0) {
+ realtime = realtime_list.get(0);
+ } else {
+ throw new BusinessException("行情获取异常,稍后再试");
+ }
+ symbol_profit = Arith.div(symbol_profit, realtime.getClose());
+ result.put("symbol_profit", symbol_profit);
+ } else {
+ result.put("symbol_profit", symbol_profit);
+ }
+ result.put("miner_profit_symbol",
+ StringUtils.isEmpty(miner_profit_symbol) ? "USDT" : miner_profit_symbol.toUpperCase());
+ result.put("img", "https://trading-order-test.s3.amazonaws.com/common/2023-09-16/783a1a14-f6ad-48e3-adb4-6623cca57480IMG_1558.PNG");
+ // 基础信息
+ result.put("algorithm", miner.getAlgorithm());
+ result.put("computing_power", miner.getComputing_power());
+ result.put("computing_power_unit", miner.getComputing_power_unit());
+ result.put("power", miner.getPower());
+ result.put("product_factory", miner.getProduct_factory());
+ result.put("product_size", miner.getProduct_size());
+ result.put("weight", miner.getWeight());
+ result.put("work_temperature_min", miner.getWork_temperature_min());
+ result.put("work_temperature_max", miner.getWork_temperature_max());
+ result.put("work_humidity_min", miner.getWork_humidity_min());
+ result.put("work_humidity_max", miner.getWork_humidity_max());
+ result.put("internet", miner.getInternet());
+
+ result.put("buy_currency", miner.getBuy_currency());
+ result.put("output_currency", miner.getOutput_currency());
+
+ return result;
+ }
+
+// public void setRedisHandler(RedisHandler redisHandler) {
+// this.redisHandler = redisHandler;
+// }
+
+ public void setSysparaService(SysparaService sysparaService) {
+ this.sysparaService = sysparaService;
+ }
+
+ public void setDataService(DataService dataService) {
+ this.dataService = dataService;
+ }
+
+// public List<Finance> findAll_2() {
+//
+// LambdaQueryWrapper<Miner> queryWrapper = new LambdaQueryWrapper<Miner>()
+// .eq(Miner::getState,state).eq(FinanceOrder::getPartyId, partyId);
+// list = this.getBaseMapper().selectList(queryWrapper);
+//
+// Map<String, Finance> cacheMap = (Map<String, Finance>) redisTemplate.opsForValue().get(FinanceRedisKeys.FINANCE_MAP);
+// if (cacheMap != null && !cacheMap.isEmpty()) {
+// return new ArrayList<Finance>(cacheMap.values());
+// }
+// return new ArrayList<Finance>();
+// }
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/miner/web/AdminMinerParaAction.java b/trading-order-service/src/main/java/com/yami/trading/service/miner/web/AdminMinerParaAction.java
new file mode 100644
index 0000000..45c8456
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/miner/web/AdminMinerParaAction.java
@@ -0,0 +1,156 @@
+package com.yami.trading.service.miner.web;
+
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yami.trading.bean.miner.Miner;
+import com.yami.trading.bean.miner.MinerPara;
+import com.yami.trading.common.exception.BusinessException;
+import com.yami.trading.service.miner.service.AdminMinerParaService;
+import com.yami.trading.service.miner.service.MinerParaService;
+import com.yami.trading.service.miner.service.MinerService;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+public class AdminMinerParaAction {
+
+ private static Log logger = LogFactory.getLog(AdminMinerParaAction.class);
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2606134812043922161L;
+
+ private AdminMinerParaService adminMinerParaService;
+ private MinerParaService minerParaService;
+ private MinerService minerService;
+
+ /**
+ * id
+ */
+ private String id;
+ /**
+ * 矿机id
+ */
+ private String miner_id;
+ /**
+ * 购买周期
+ */
+ private int cycle;
+
+ /**
+ * 购买价格
+ */
+ private double amount;
+
+ private String miner_name;
+
+ public String list() {
+ int pageNo = 1;
+ int pageSize = 30;
+ Miner miner = minerService.findById(miner_id);
+ miner_name = miner.getName();
+ Page page = adminMinerParaService.pagedQuery(pageNo, pageSize, miner_id);
+ return "list";
+ }
+ public String toAdd() {
+ return "add";
+ }
+ public String toUpdate() {
+ MinerPara minerPara = minerParaService.findById(id);
+ try {
+ if(minerPara==null) {
+ throw new BusinessException("参数不存在,刷新重试");
+ }
+ miner_id = minerPara.getMiner_id();
+ cycle = minerPara.getCycle();
+ amount = minerPara.getAmount();
+ return "update";
+ } catch (BusinessException e) {
+// this.error = e.getMessage();
+ return list();
+ } catch (Throwable t) {
+ logger.error("update error ", t);
+// this.error = "程序错误";
+ return list();
+ }
+ }
+
+ public String update() {
+ MinerPara minerPara = minerParaService.findById(id);
+ try {
+ minerPara.setCycle(cycle);
+ minerPara.setAmount(amount);
+ minerParaService.update(minerPara);
+// this.message = "操作成功";
+ return list();
+ } catch (BusinessException e) {
+// this.error = e.getMessage();
+ return toUpdate();
+ } catch (Throwable t) {
+ logger.error("update error ", t);
+// this.error = "程序错误";
+ return toUpdate();
+ }
+ }
+ public String add() {
+ try {
+ MinerPara minerPara = new MinerPara();
+ minerPara.setCycle(cycle);
+ minerPara.setAmount(amount);
+ minerPara.setMiner_id(miner_id);
+// minerParaService.save(minerPara);
+// this.message = "操作成功";
+ return list();
+ } catch (BusinessException e) {
+// this.error = e.getMessage();
+ return toAdd();
+ } catch (Throwable t) {
+ logger.error("update error ", t);
+// this.error = "程序错误";
+ return toAdd();
+ }
+ }
+
+ public String getMiner_id() {
+ return miner_id;
+ }
+ public int getCycle() {
+ return cycle;
+ }
+ public double getAmount() {
+ return amount;
+ }
+ public void setMiner_id(String miner_id) {
+ this.miner_id = miner_id;
+ }
+ public void setCycle(int cycle) {
+ this.cycle = cycle;
+ }
+ public void setAmount(double amount) {
+ this.amount = amount;
+ }
+ public void setAdminMinerParaService(AdminMinerParaService adminMinerParaService) {
+ this.adminMinerParaService = adminMinerParaService;
+ }
+ public void setMinerParaService(MinerParaService minerParaService) {
+ this.minerParaService = minerParaService;
+ }
+ public String getId() {
+ return id;
+ }
+ public void setId(String id) {
+ this.id = id;
+ }
+ public void setMinerService(MinerService minerService) {
+ this.minerService = minerService;
+ }
+ public String getMiner_name() {
+ return miner_name;
+ }
+ public void setMiner_name(String miner_name) {
+ this.miner_name = miner_name;
+ }
+
+
+
+}
diff --git a/trading-order-service/src/main/resources/mapper/miner/MinerMapper.xml b/trading-order-service/src/main/resources/mapper/miner/MinerMapper.xml
new file mode 100644
index 0000000..e15f596
--- /dev/null
+++ b/trading-order-service/src/main/resources/mapper/miner/MinerMapper.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.yami.trading.dao.miner.MinerMapper">
+
+ <select id="pagedQuery" resultType="java.util.HashMap">
+ SELECT miner.uuid id,miner.name name,miner.name_en name_en,miner.name_cn name_cn,
+ miner.img img,miner.cycle cycle,miner.cycle_close cycle_close,miner.show_daily_rate show_daily_rate ,
+ miner.daily_rate daily_rate ,miner.state state,miner.on_sale on_sale,miner.test test,miner.investment_min investment_min,
+ miner.investment_max investment_max, miner.buy_currency, miner.output_currency FROM t_miner miner WHERE 1 = 1
+ <if test="name_para!=null and name_para!=''">
+ and miner.name like CONCAT('%', #{name_para}, '%')
+ </if>
+
+ ORDER BY miner.investment_min+0 ASC
+ </select>
+
+</mapper>
diff --git a/trading-order-service/src/main/resources/mapper/miner/MinerOrderMapper.xml b/trading-order-service/src/main/resources/mapper/miner/MinerOrderMapper.xml
new file mode 100644
index 0000000..876cd93
--- /dev/null
+++ b/trading-order-service/src/main/resources/mapper/miner/MinerOrderMapper.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.yami.trading.dao.miner.MinerOrderMapper">
+
+ <select id="pagedQuery" resultType="java.util.HashMap">
+ select finance.uuid id,finance.name name,finance.name_en name_en,finance.name_cn name_cn,
+ finance.name_kn name_kn,finance.name_jn name_jn,finance.img img,finance.cycle cycle,
+ finance.daily_rate daily_rate ,finance.daily_rate_max daily_rate_max ,finance.today_rate today_rate ,finance.state state,
+ finance.default_ratio default_ratio ,finance.investment_min investment_min,finance.investment_max investment_max
+ from t_finance finance where 1=1
+ <if test="name_para!=null and name_para!=''">
+ and finance.name like CONCAT('%', #{name_para}, '%')
+ </if>
+
+ order by finance.create_time desc
+ </select>
+
+ <select id="pagedQuery1" resultType="java.util.HashMap">
+ select minerOrder.uuid id,minerOrder.order_no order_no ,minerOrder.miner_id minerId ,
+ minerOrder.amount amount,DATE_FORMAT(minerOrder.create_time,'%Y-%m-%d %H:%i:%S') create_time,
+ DATE(minerOrder.earn_time) earn_time,DATE(minerOrder.stop_time) stop_time,minerOrder.profit profit,
+ minerOrder.state state,minerOrder.base_compute_amount base_compute_amount,
+ miner.cycle cycle,miner.cycle_close cycle_close,miner.daily_rate daily_rate,miner.test test,
+ miner.name miner_name,miner.name_en miner_name_en,miner.name_cn miner_name_cn
+ FROM t_miner_order minerOrder
+ LEFT JOIN t_miner miner ON miner.uuid= minerOrder.miner_id where 1=1
+ <if test="partyId!=null and partyId!=''">
+ AND minerOrder.party_id=#{partyId}
+ </if>
+
+ <if test="state!=null and state==2">
+ AND minerOrder.state in('0','2')
+ </if>
+
+ <if test="state!=null and state==1">
+ AND minerOrder.state=#{state}
+ </if>
+
+ order by minerOrder.create_time desc
+ </select>
+
+
+ <select id="pagedQueryComputeOrder" resultType="java.util.HashMap">
+ select * FROM t_miner_order WHERE state =1
+ </select>
+
+ <select id="pagedQueryAdmin" resultType="java.util.HashMap">
+ SELECT minerOrder.uuid id,minerOrder.order_no order_no ,minerOrder.miner_id minerId , minerOrder.amount amount,minerOrder.create_time create_time,minerOrder.base_compute_amount base_compute_amount,
+ minerOrder.earn_time earn_time,minerOrder.stop_time stop_time,minerOrder.profit profit,
+ minerOrder.state state,minerOrder.close_time close_time,minerOrder.default_money default_money,
+ party.user_name username,party.user_code usercode,party.role_name rolename,
+ miner.name miner_name,miner.name_en miner_name_en
+ FROM t_miner_order minerOrder
+ LEFT JOIN tz_user party ON minerOrder.party_id = party.user_id
+ LEFT JOIN t_miner miner ON miner.uuid = minerOrder.miner_id
+ WHERE 1 = 1
+
+ <if test="children != null and children.size() >0">
+ and minerOrder.party_id in
+ <foreach collection="children" item="item" index="index" open="(" close=")" separator=",">
+ #{item}
+ </foreach>
+ </if>
+
+ <if test="miner_para!=null and miner_para!=''">
+ and miner.name=#{miner_para}
+ </if>
+
+ <if test="name_para!=null and name_para!=''">
+ AND (party.user_name like CONCAT('%', #{name_para}, '%') OR party.user_code like CONCAT('%', #{name_para}, '%'))
+ </if>
+
+ <if test="status_para!=null and status_para!='' and status_para!=0 ">
+ and minerOrder.STATE = #{status_para}
+ </if>
+
+ <if test="status_para!=null and status_para==0 ">
+ and (minerOrder.STATE ='0' OR minerOrder.STATE ='2' )
+ </if>
+
+ <if test="orderNo!=null and orderNo!=''">
+ and minerOrder.order_no =#{orderNo}
+ </if>
+
+ <if test="rolename_para!=null and rolename_para!=''">
+ and party.role_name =#{rolename_para}
+ </if>
+
+
+ <if test="status_para!=null and status_para!='' and status_para == '0'">
+ order by minerOrder.close_time desc
+ </if>
+
+ <if test="status_para!=null and status_para!='' and status_para != '0'">
+ order by minerOrder.create_time desc
+ </if>
+
+ <if test="status_para==null or status_para==''">
+ order by minerOrder.create_time desc
+ </if>
+
+ </select>
+
+</mapper>
diff --git a/trading-order-service/src/main/resources/mapper/miner/MinerParaMapper.xml b/trading-order-service/src/main/resources/mapper/miner/MinerParaMapper.xml
new file mode 100644
index 0000000..8b14873
--- /dev/null
+++ b/trading-order-service/src/main/resources/mapper/miner/MinerParaMapper.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.yami.trading.dao.miner.MinerParaMapper">
+
+ <select id="pagedQuery" resultType="java.util.HashMap">
+ select finance.uuid id,finance.name name,finance.name_en name_en,finance.name_cn name_cn,
+ finance.name_kn name_kn,finance.name_jn name_jn,finance.img img,finance.cycle cycle,
+ finance.daily_rate daily_rate ,finance.daily_rate_max daily_rate_max ,finance.today_rate today_rate ,finance.state state,
+ finance.default_ratio default_ratio ,finance.investment_min investment_min,finance.investment_max investment_max
+ from t_finance finance where 1=1
+ <if test="name_para!=null and name_para!=''">
+ and finance.name like CONCAT('%', #{name_para}, '%')
+ </if>
+
+ order by finance.create_time desc
+ </select>
+
+</mapper>
--
Gitblit v1.9.3