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();
+
+		//&current=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