src/main/java/db/util/QpUtil.java
New file @@ -0,0 +1,80 @@ package db.util; import java.math.BigDecimal; import java.math.RoundingMode; /** * @program: xinbi-new * @description: * @create: 2025-04-10 15:25 **/ public class QpUtil { public static double faceValue = 0.01; // 合约面值(固定面值不能调整) public static double maintenanceMarginRate = 0.004; // 维持保证金率(固定不变) /** * 多仓强平价格计算 多仓预估强平价 =(保证金余额-面值 *|张数|*开仓均价)/(面值*张数|*(维持保证金率+手续费率 -1)); * @param marginBalance 保证金余额 * @param contractQuantity 合约张数 * @param openingPrice 开仓均价 * @param feeRate 手续费率 * @return */ public static double calculateLiquidationPrice(double marginBalance, double contractQuantity, double openingPrice, double feeRate){ // 计算分子部分 double numerator = marginBalance - (faceValue * contractQuantity * openingPrice); // 计算分母部分 double denominator = faceValue * contractQuantity * (maintenanceMarginRate + feeRate - 1); // 计算强平价 double result = numerator / denominator; if (result < 0) { return 0; } return new BigDecimal(result).setScale(2, RoundingMode.HALF_UP).doubleValue(); } /** * 空仓强平价格计算 空仓预估强平价 =(保证金余额+面值 *|张数|*开仓均价)/(面值*|张数|*(维持金率+王续费率 +1)) * @param marginBalance 保证金余额 * @param contractQuantity 合约张数 * @param openingPrice 开仓均价 * @param feeRate 手续费率 * @return */ public static double calculateEmptyLiquidationPrice (double marginBalance, double contractQuantity, double openingPrice, double feeRate){ // 计算分子部分 double numerator = marginBalance + (faceValue * contractQuantity * openingPrice); // 计算分母部分 double denominator = faceValue * contractQuantity * (maintenanceMarginRate + feeRate + 1); // 计算空仓预估强平价 double result = numerator / denominator; if (result < 0) { return 0; } return new BigDecimal(result).setScale(2, RoundingMode.HALF_UP).doubleValue(); } /** * * @param earnestMoney 保证金 * @param level 杠杆 * @param recentQuotation 最新价格 * @return 合约张数 张数=可用保证金*杠杆倍数/(面值*最新成交价) */ public static double countSheets(double earnestMoney, int level, double recentQuotation){ double result = earnestMoney * level / (faceValue * recentQuotation); BigDecimal bd = new BigDecimal(result).setScale(2, RoundingMode.DOWN); return bd.doubleValue(); } } src/main/java/project/contract/internal/ContractOrderServiceImpl.java
@@ -240,12 +240,6 @@ moneyLogService.save(moneylog); order.setState(ContractOrder.STATE_CREATED); order.setVolume(0D); order.setDeposit(0); order.setClose_time(new Date()); update(order); /** * 合约产品平仓后添加当前流水 */ @@ -343,7 +337,7 @@ order.setState(ContractOrder.STATE_CREATED); order.setClose_time(new Date()); } update(order); return profit; } @@ -522,21 +516,6 @@ } else { map.put("profit", df.format(order.getProfit())); } // double currentPrice = Double.parseDouble(map.get("trade_avg_price").toString()); // // double leve = Double.parseDouble(map.get("lever_rate").toString()); // //得到强平价格 // if(null != map.get("direction")){ // double liquidationPrice; // if(map.get("direction").equals("sell")){ // liquidationPrice = currentPrice * (1 + (1 / leve)); // }else{ // liquidationPrice = currentPrice * (1 - 1 / leve); // } // DecimalFormat dfs = new DecimalFormat("#.#####"); // String formattedPrice = dfs.format(liquidationPrice); // map.put("qiangPing",formattedPrice); // } double depositOpen = Double.parseDouble(map.get("deposit_open").toString()); double leverRate = Double.parseDouble(map.get("lever_rate").toString()); src/main/java/project/contract/job/ContractOrderCalculationJob.java
@@ -20,18 +20,22 @@ while (true) { try { List<ContractOrder> list = this.contractOrderService.findSubmitted(); logger.info("ccccccccccccccc:"+list.size()); for (int i = 0; i < list.size(); i++) { ContractOrder order = list.get(i); logger.info("ccccccccccccccc"); boolean lock = false; try { if (!ContractLock.add(order.getOrder_no())) { logger.info("-----------???????????????????"); continue; } lock = true; logger.info("-----------````````````````````````:"+order.getOrder_no()); this.contractOrderCalculationService.saveCalculation(order.getOrder_no()); } catch (Throwable e) { logger.info("-----------errorerrorerrorerrorerrorerrorerrorerrorerrorerror"); logger.error("error:", e); } finally { if (lock) { src/main/java/project/contract/job/ContractOrderCalculationServiceImpl.java
@@ -1,10 +1,15 @@ package project.contract.job; import java.sql.PreparedStatement; import java.sql.SQLException; import java.text.DecimalFormat; import java.util.List; import java.util.Map; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import kernel.util.StringUtils; import kernel.web.ApplicationUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,6 +19,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.util.ObjectUtils; import project.contract.ContractLock; import project.contract.ContractOrder; @@ -27,6 +37,7 @@ import project.wallet.Wallet; import project.wallet.WalletRedisKeys; import project.wallet.WalletService; import project.wallet.consumer.WalletDao; import project.wallet.consumer.WalletMessage; public class ContractOrderCalculationServiceImpl implements ContractOrderCalculationService, ApplicationContextAware { @@ -36,6 +47,7 @@ private ContractOrderService contractOrderService; private DataService dataService; private WalletService walletService; private WalletDao walletDao; // private RedisHandler redisHandler; private AssetService assetService; public final static String STATE_SUBMITTED = "submitted"; @@ -55,6 +67,7 @@ try { ContractOrder order = contractOrderService.findByOrderNo(order_no); if (order == null || !ContractOrder.STATE_SUBMITTED.equals(order.getState())) { logger.info("-----------到这里来了吗"); /** * 状态已改变,退出处理 */ @@ -62,6 +75,7 @@ } List<Realtime> list = this.dataService.realtime(order.getSymbol()); if (list.size() == 0) { logger.info("-----------去你妈退出了"); return; } Realtime realtime = list.get(0); @@ -97,6 +111,9 @@ } } private static final Lock lock = new ReentrantLock(); // 全局锁,避免重复执行 private static final long SLEEP_TIME = 500; // 重试间隔 /** * 盈亏计算 @@ -242,47 +259,26 @@ }else{ totleMoney = Double.parseDouble(money.toString()); } logger.info("---------全仓强平任务----------------"); logger.info("-------------------------:"+Arith.add(profit,totleMoney)); if (Arith.add(profit,totleMoney) <= 0) { redisHandler.setSync("MONEY_CONTRACT_PROFIT_"+order.getPartyId().toString(), 0); /** * 触发全仓强平 */ this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrder_no()); ThreadUtils.sleep(100); for (int i = 0; i < list.size(); i++) { ContractOrder close_line = list.get(i); if (!order.getOrder_no().equals(close_line.getOrder_no())) { try { while (true) { if (ContractLock.add(close_line.getOrder_no())) { this.contractOrderService.saveClose(close_line.getPartyId().toString(), close_line.getOrder_no()); /** * 处理完退出 */ break; } ThreadUtils.sleep(500); } } catch (Exception e) { logger.error("error:", e); } finally { ContractLock.remove(close_line.getOrder_no()); ThreadUtils.sleep(100); } synchronized (close_line.getOrder_no()){ this.contractOrderService.saveClose(close_line.getPartyId().toString(), close_line.getOrder_no()); } } //钱包归零 extracted(order, wallet, redisHandler); } } else { logger.info("---------进入单个持仓----------------"); logger.info("---------order.getProfit()----------------"+order.getProfit()); logger.info("---------order.getDeposit()----------------"+order.getDeposit()); logger.info("---------order_close_line----------------"+order_close_line); if (order.getProfit() < 0 && (Arith.div(order.getDeposit(), Math.abs(order.getProfit())) <= Arith .div(order_close_line, 100))) { logger.info("---------进入强平了----------------"); @@ -293,8 +289,46 @@ return; } } } private void extracted(ContractOrder order, Wallet wallet, RedisHandler redisHandler) { DataSourceTransactionManager transactionManager = ApplicationUtil.getBean(DataSourceTransactionManager.class); JdbcTemplate jdbcTemplate = ApplicationUtil.getBean(JdbcTemplate.class); TransactionStatus status = null; try { // 开启事务 status = transactionManager.getTransaction(new DefaultTransactionDefinition()); logger.info("----------我来更新钱包了"); wallet.setMoney(0); redisHandler.setSync(WalletRedisKeys.WALLET_PARTY_ID + wallet.getPartyId().toString(), wallet); logger.info("-------wallet:" + wallet.getPartyId()); // 更新数据库 int update = jdbcTemplate.update("UPDATE T_WALLET SET MONEY=ROUND(?,8) WHERE PARTY_ID=?", 0, wallet.getPartyId().toString()); logger.info("--------cnm跟新了几条:" + update); // 保存钱包信息 Wallet ww = this.walletService.saveWalletByPartyId(order.getPartyId().toString()); logger.info("-----------到底他妈是什么值:" + ww.getMoney()); // 更新 redis redisHandler.setSync("PARTY_ID_MONEY_" + wallet.getPartyId().toString(), wallet.getMoney()); // 提交事务 transactionManager.commit(status); logger.info("----------更新完了"); } catch (Exception e) { // 回滚事务 if (status != null) { transactionManager.rollback(status); } logger.error("更新钱包时发生错误:", e); throw e; } } public void setDataService(DataService dataService) { this.dataService = dataService; } src/main/java/project/item/model/Item.java
@@ -103,6 +103,21 @@ @Column(name="SYMBOL_FULL_NAME") private String symbolFullName; /** * 展示名字 */ @Column(name="SHOW_NAME") private String showName; public String getShowName() { return showName; } public void setShowName(String showName) { this.showName = showName; } public String getSymbolFullName() { return symbolFullName; } src/main/java/project/project/web/admin/AdminContractOrderController.java
@@ -11,6 +11,7 @@ import javax.servlet.http.HttpServletRequest; import db.util.QpUtil; import org.apache.commons.lang3.ObjectUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; src/main/java/project/project/web/api/ContractOrderController.java
@@ -1,4 +1,4 @@ package project.project.web.api; package project.web.api; import java.io.IOException; import java.text.DecimalFormat; src/main/java/project/wallet/internal/AssetServiceImpl.java
@@ -10,11 +10,14 @@ import kernel.exception.BusinessException; import kernel.util.Arith; import kernel.util.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import project.contract.ContractApplyOrder; import project.contract.ContractApplyOrderService; import project.contract.ContractOrder; import project.contract.ContractOrderService; import project.contract.ContractRedisKeys; import project.contract.job.ContractOrderCalculationServiceImpl; import project.data.DataService; import project.data.model.Realtime; import project.exchange.ExchangeApplyOrder; @@ -59,7 +62,8 @@ private ContractApplyOrderService contractApplyOrderService; private ExchangeApplyOrderService exchangeApplyOrderService; private static final Logger logger = LoggerFactory.getLogger(AssetServiceImpl.class); public Map<String, Object> getMoneyAll(Serializable partyId) { Map<String, Object> data = new HashMap<String, Object>(); DecimalFormat df2 = new DecimalFormat("#.##"); @@ -160,8 +164,11 @@ // 币币交易 money = money + this.getMoneyexchangeApplyOrders(partyId, realtime_all); data.put("total", df2.format(money)); if(df2.format(money).equals("-0")){ data.put("total", df2.format(0)); }else{ data.put("total", df2.format(money)); } //锁定金额 data.put("lock_money", df2.format(wallet.getLock_money())); //冻结金额 @@ -171,7 +178,15 @@ data.put("money_all_coin", df2.format(money_all_coin)); data.put("money_miner", df2.format(money_miner)); data.put("money_finance", df2.format(money_finance)); data.put("money_contract", df2.format(Arith.add(money_contract, money_contractApply))); // 计算合约金额 double result = Arith.add(money_contract, money_contractApply); logger.info("-----------合约余额"+result); double epsilon = 1.0E-10; // 定义一个很小的误差范围 if (Math.abs(result) < epsilon) { data.put("money_contract", df2.format(0.0)); }else{ data.put("money_contract", df2.format(Arith.add(money_contract, money_contractApply))); } data.put("money_contract_deposit", df2.format(money_contract_deposit)); data.put("money_contract_profit", df2.format(money_contract_profit)); data.put("money_futures", df2.format(money_futures)); @@ -180,7 +195,6 @@ return data; } public double getMoneyCoin(Serializable partyId, List<Realtime> realtime_all, List<String> list_symbol) { double money_coin = 0; src/main/java/project/wallet/internal/WalletServiceImpl.java
@@ -93,11 +93,13 @@ // 确保余额不会为负数 double newBalance = Arith.add(wallet.getMoney(), amount); if (newBalance < 0) { amount = -wallet.getMoney(); // 如果会负余额,调整 amount 使余额为0 wallet.setMoney(0); }else{ wallet.setMoney(Arith.add(wallet.getMoney(), amount)); } wallet.setMoney(Arith.add(wallet.getMoney(), amount)); logger.info("----------------tmd钱包的钱为什么不对"+wallet.getMoney()); redisHandler.setSync(WalletRedisKeys.WALLET_PARTY_ID + wallet.getPartyId().toString(), wallet); redisHandler.pushAsyn(WalletRedisKeys.WALLET_QUEUE_UPDATE, new WalletMessage(partyId, amount)); redisHandler.pushAsyn(WalletRedisKeys.WALLET_QUEUE_UPDATE, new WalletMessage(partyId, wallet.getMoney())); //用于计算合约亏损 redisHandler.setSync("PARTY_ID_MONEY_"+partyId, wallet.getMoney()); src/main/java/project/web/admin/AdminItemController.java
@@ -20,7 +20,11 @@ import kernel.web.Page; import kernel.web.PageActionSupport; import project.Constants; import project.data.AdjustmentValueCache; import project.data.DataCache; import project.data.DataDBService; import project.data.internal.KlineInitService; import project.data.model.Realtime; import project.item.AdminItemService; import project.item.ItemService; import project.item.model.Item; @@ -53,6 +57,7 @@ protected SecUserService secUserService; @Autowired protected PasswordEncoder passwordEncoder; private final String action = "normal/adminItemAction!"; @@ -412,19 +417,21 @@ * multiple 交易量放大倍数,如果为0或者空不进行操作,否则乘以倍数 * login_safeword 登录人资金密码 * borrowing_rate 借贷利率 * showName 火币的币名 */ @RequestMapping(value = action + "addConfig.action") public ModelAndView addConfig(HttpServletRequest request) { String name = request.getParameter("name"); String symbol = request.getParameter("symbol"); String symbol_data = request.getParameter("symbol_data"); String decimals = request.getParameter("decimals"); String multiple = request.getParameter("multiple"); String borrowing_rate = request.getParameter("borrowing_rate"); String login_safeword = request.getParameter("login_safeword"); String showName = request.getParameter("showName"); String pips = request.getParameter("pips"); ModelAndView modelAndView = new ModelAndView(); String symbol_data = symbol.toLowerCase()+"usdt"; try { if (StringUtils.isEmptyString(multiple)) { @@ -447,13 +454,19 @@ Item item = new Item(); item.setName(name); item.setSymbolFullName(name); item.setMarket("FOREVER"); item.setShowName(showName); item.setSymbol(symbol); item.setSymbol_data(symbol_data); item.setPips(Double.parseDouble(pips)); item.setPips_amount(Double.parseDouble(pips)); item.setAdjustment_value(0.0); item.setUnit_amount(10); item.setUnit_fee(0.001); item.setMarket("FOREVER"); item.setDecimals(decimals_int); item.setMultiple(multiple_double); item.setBorrowing_rate(Arith.div(borrowing_rate_double, 100)); item.setSymbolFullName(showName.toUpperCase()+"/USDT"); this.adminItemService.save(item); project.log.Log log = new project.log.Log(); src/main/java/project/web/admin/controller/upload/UploadImgController.java
@@ -105,7 +105,73 @@ return resultObject; } @RequestMapping(value = "normal/uploadimg!publishExecute.action") public Object publishExecute(HttpServletRequest request) { ResultObject resultObject = new ResultObject(); try { MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext()); File file = null; if(resolver.isMultipart(request)) { MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; MultipartFile multipartFile = multipartRequest.getFile("file"); file = multipartFileToFile(multipartFile); }else { throw new BusinessException("文件上传失败"); } String fileFileName = request.getParameter("fileName");; HashMap extMap = new HashMap(); extMap.put("image", "jpg,png"); if (file.length() / 1024L > 30720L) { resultObject.setCode("1"); resultObject.setMsg("图片大小不能超过30M"); return resultObject; } String fileDir = properties.getProperty("currencyImages.dir"); File f = new File(fileDir); if ((!f.exists()) && (!f.mkdirs())) { resultObject.setCode("1"); resultObject.setMsg("服务器错误"); logger.warn("文件:" + fileDir + "创建失败!"); return resultObject; } String imagePath = ""; String imageDir = fileFileName + "." + "png"; imagePath = fileDir + imageDir.toLowerCase().trim(); FileInputStream in = new FileInputStream(file); FileOutputStream outputStream = new FileOutputStream(imagePath); BufferedInputStream inputStream = new BufferedInputStream(in); byte[] buf = new byte[1024]; int length = 0; while ((length = inputStream.read(buf)) != -1) { outputStream.write(buf, 0, length); } resultObject.setData(imageDir); } catch (FileNotFoundException e) { resultObject.setCode("1"); resultObject.setMsg("服务器错误"); logger.error("文件上传失败", e); return resultObject; } catch (Exception e) { resultObject.setCode("1"); resultObject.setMsg("服务器错误"); logger.error("文件上传失败", e); return resultObject; } return resultObject; } public static File multipartFileToFile(MultipartFile multiFile) { // 获取文件名 String fileName = multiFile.getOriginalFilename(); src/main/java/project/web/api/ItemController.java
@@ -73,7 +73,7 @@ } Map<String, String> map = new HashMap<>(); map.put("symbol", item.getSymbol()); map.put("symbolFullName", item.getSymbolFullName()); map.put("symbolFullName", item.getName()); map.put("isTop", isTop); data.add(map); src/main/java/project/web/api/RealtimeController.java
@@ -90,13 +90,15 @@ Map<String, Object> map = new HashMap<String, Object>(); map.put("symbol", realtime.getSymbol()); map.put("ts", realtime.getTs()); String currentTime = realtime.getCurrent_time(); // 设置时区为纽约的冬令时(Eastern Standard Time, EST) long currentTime = 1744341503535L; // 确保 currentTime 是 long 类型 TimeZone timeZone = TimeZone.getTimeZone("America/New_York"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); sdf.setTimeZone(timeZone); map.put("current_time",sdf.format(currentTime)); map.put("name", realtime.getName()); Date date = new Date(currentTime); String formattedTime = sdf.format(date); map.put("current_time", formattedTime); Item item1 = this.itemService.cacheBySymbol(realtime.getSymbol(), false); map.put("name", item1.getName()); map.put("change_ratio", realtime.getChange_ratio()); Item item = this.itemService.cacheBySymbol(realtime.getSymbol(), true); if (item.getDecimals() == null || item.getDecimals() < 0) { src/main/java/project/web/api/WalletController.java
@@ -106,10 +106,10 @@ Map<String, Object> mapRetDefault = new LinkedHashMap<String, Object>(); mapRetDefault.put("usdt", 0.0D); mapRetDefault.put("no_zero", new ArrayList<Map<String, Object>>()); Item item = itemService.cacheBySymbol(symbol1, true); Map<String, Object> mapDefault1 = new HashMap<String, Object>(); mapDefault1.put("symbol", symbol1); mapDefault1.put("full_name", StringUtils.isEmptyString(itemMap.get(symbol1)) ? symbol1.toUpperCase() : itemMap.get(symbol1)); mapDefault1.put("full_name", item.getName()); mapDefault1.put("volume", 0.0D); mapDefault1.put("usdt", 0.0D); Map<String, Object> mapDefault2 = new HashMap<String, Object>(); src/main/resources/config/system.properties
@@ -1,5 +1,6 @@ http.server.host=https://app.usdtone.com/images/ images.dir=/root/project/images/ currencyImages.dir=/www/wwwroot/web/api/img/ web_url=https://app.usdtone.com/wap/ encryption.key=d78585e683ed11eaa13f0242ac110003 #version.number=1.1 src/main/webapp/item_config_add.jsp
@@ -7,234 +7,365 @@ <html> <head> <%@ include file="include/head.jsp"%> <%@ include file="include/head.jsp"%> </head> <body> <%@ include file="include/loading.jsp"%> <%@ include file="include/loading.jsp"%> <!-- START CONTENT --> <div class="ifr-dody"> <!-- START CONTAINER --> <div class="ifr-con"> <h3>行情品种管理</h3> <%@ include file="include/alert.jsp"%> <!-- //////////////////////////////////////////////////////////////////////////// --> <!-- START queryForm --> <form action="<%=basePath%>normal/adminItemAction!listConfig.action" method="post" id="queryForm"> <input type="hidden" name="pageNo" id="pageNo" value="${pageNo}"> </form> <!-- END queryForm --> <!-- //////////////////////////////////////////////////////////////////////////// --> <div class="row"> <div class="col-md-12 col-lg-12"> <div class="panel panel-default"> <!-- START CONTENT --> <div class="ifr-dody"> <!-- START CONTAINER --> <div class="ifr-con"> <h3>行情品种管理</h3> <div class="panel-title"> 添加行情品种 <ul class="panel-tools"> <li><a class="icon minimise-tool"><i class="fa fa-minus"></i></a></li> <li><a class="icon expand-tool"><i class="fa fa-expand"></i></a></li> </ul> </div> <%@ include file="include/alert.jsp"%> <div class="panel-body"> <form class="form-horizontal" action="<%=basePath%>normal/adminItemAction!addConfig.action" method="post" name="mainForm" id="mainForm"> <div class="form-group"> <label class="col-sm-2 control-label form-label">名称</label> <div class="col-sm-3"> <input id="name" name="name" class="form-control " value="${name}"/> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label form-label">代码</label> <div class="col-sm-3"> <input id="symbol" name="symbol" class="form-control " value="${symbol}"/> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label form-label">保留精度</label> <div class="col-sm-2"> <div class="input-group"> <input id="decimals" name="decimals" class="form-control " value="${decimals}"/> <div class="input-group-addon">位</div> </div> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label form-label">交易量倍数</label> <div class="col-sm-2"> <div class="input-group"> <input id="multiple" name="multiple" class="form-control " value="${multiple}"/> <div class="input-group-addon">倍</div> </div> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label form-label">借贷利率</label> <div class="col-sm-2"> <div class="input-group"> <input id="borrowing_rate" name="borrowing_rate" class="form-control " value="${borrowing_rate}"/> <div class="input-group-addon">%</div> </div> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label form-label">交易对</label> <div class="col-sm-3"> <input id="symbol_data" name="symbol_data" class="form-control " readonly="readonly" value="${symbol_data}"/> </div> <a href="javascript:chooseSymbol('${id}')" class="btn btn-light" style="margin-bottom: 10px">交易对选择</a> </div> <div class="col-sm-1"> <!-- 模态框(Modal) --> <div class="modal fade" id="modal_succeeded" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content" style="width: 350px;"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h4 class="modal-title" id="myModalLabel">登录人资金密码</h4> </div> <div class="modal-body"> <div class="" > <input id="login_safeword" type="password" name="login_safeword" class="login_safeword" placeholder="请输入登录人资金密码" style="width: 250px;"> </div> </div> <div class="modal-footer" style="margin-top: 0;"> <button type="button" class="btn " data-dismiss="modal">关闭</button> <button id="sub" type="submit" class="btn btn-default" >确认</button> </div> </div> <!-- /.modal-content --> </div> <!-- /.modal --> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <a href="javascript:goUrl(${pageNo})" class="btn">取消</a> <a href="javascript:submit()" class="btn btn-default">保存</a> </div> </div> </form> </div> </div> </div> </div> </div> <!-- END CONTAINER --> <!-- //////////////////////////////////////////////////////////////////////////// --> <!-- START queryForm --> <form action="<%=basePath%>normal/adminItemAction!listConfig.action" method="post" id="queryForm"> <input type="hidden" name="pageNo" id="pageNo" value="${pageNo}"> </form> <!-- END queryForm --> <!-- //////////////////////////////////////////////////////////////////////////// --> <%@ include file="include/footer.jsp"%> <div class="row"> <div class="col-md-12 col-lg-12"> <div class="panel panel-default"> </div> <!-- End Content --> <!-- //////////////////////////////////////////////////////////////////////////// --> <!-- 模态框 --> <div class="form-group"> <input type="hidden" name="quote_currency" id="quote_currency" value="${quote_currency}"> <div class="col-sm-2"> <!-- 模态框(Modal) --> <div class="modal fade" id="modal_set" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content" style="height:500px;"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h4 class="modal-title" id="myModalLabel">交易对</h4> </div> <div class="modal-body" id="symbols_get" style="height:380px;"> <%@ include file="contract_manage_add_symbols_list.jsp"%> </div> <div class="modal-footer" style="margin-top: 0;"> <button type="button" class="btn " data-dismiss="modal" >关闭</button> <button id="sub" type="submit" class="btn btn-default" onclick="modalConfirm(this)">确认</button> </div> <div class="panel-title"> 添加行情品种 <ul class="panel-tools"> <li><a class="icon minimise-tool"><i class="fa fa-minus"></i></a></li> <li><a class="icon expand-tool"><i class="fa fa-expand"></i></a></li> </ul> </div> <!-- /.modal-content --> <div class="panel-body"> <form class="form-horizontal" action="<%=basePath%>normal/adminItemAction!addConfig.action" method="post" name="mainForm" id="mainForm"> <div class="form-group"> <label class="col-sm-2 control-label form-label">名称(币种/USDT)</label> <div class="col-sm-3"> <input id="name" name="name" class="form-control" value="${name}" oninput="this.value = this.value.toUpperCase()"/> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label form-label">官网名称(火币对应的)</label> <div class="col-sm-3"> <input id="showName" name="showName" class="form-control" value="${showName}" oninput="this.value = this.value.toLowerCase().replace(/\s+/g, '')"/> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label form-label">币种名称(比如BTC)</label> <div class="col-sm-3"> <input id="symbol" name="symbol" class="form-control" value="${symbol}" oninput="this.value = this.value.toLowerCase().replace(/\s+/g, '')"/> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label form-label">保留精度(几位小数点就写几位)</label> <div class="col-sm-2"> <div class="input-group"> <input id="decimals" name="decimals" class="form-control " value="${decimals}"/> <div class="input-group-addon">位</div> </div> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label form-label">交易量倍数</label> <div class="col-sm-2"> <div class="input-group"> <input id="multiple" name="multiple" class="form-control " value="${multiple}"/> <div class="input-group-addon">倍</div> </div> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label form-label">最小浮动(参考火币对应币种的小数点比如100.254,填写0.001)</label> <div class="col-sm-2"> <div class="input-group"> <input id="pips" name="pips" class="form-control " value="${pips}"/> </div> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label form-label">借贷利率</label> <div class="col-sm-2"> <div class="input-group"> <input id="borrowing_rate" name="borrowing_rate" class="form-control " value="${borrowing_rate}"/> <div class="input-group-addon">%</div> </div> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label form-label">产品图片</label> <div class="col-sm-3"> <input type="file" id="fileName" name="fileName" value="${fileName}" onchange="upload();" style="position:absolute;opacity:0;" data-showname="${showName}"> <label for="fileName"> <img width="90px" height="90px" id="show_img" src="<%=base%>/image/add.png" alt="点击上传图片" /> </label> </div> </div> <div class="col-sm-1"> <!-- 模态框(Modal) --> <div class="modal fade" id="modal_succeeded" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content" style="width: 350px;"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h4 class="modal-title" id="myModalLabel">登录人资金密码</h4> </div> <div class="modal-body"> <div class="" > <input id="login_safeword" type="password" name="login_safeword" class="login_safeword" placeholder="请输入登录人资金密码" style="width: 250px;"> </div> </div> <div class="modal-footer" style="margin-top: 0;"> <button type="button" class="btn " data-dismiss="modal">关闭</button> <button id="sub" type="submit" class="btn btn-default" >确认</button> </div> </div> <!-- /.modal-content --> </div> <!-- /.modal --> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <a href="javascript:goUrl(${pageNo})" class="btn">取消</a> <a href="javascript:submit()" class="btn btn-default">保存</a> </div> </div> <div class="message-container"> <p class="message-text"> 添加完币种,请在操作里面初始化一下对于币种的K线 </p> </div> </form> </div> </div> <!-- /.modal --> </div> </div> <!-- </form> --> </div> <!-- END CONTAINER --> <!-- //////////////////////////////////////////////////////////////////////////// --> <%@ include file="include/footer.jsp"%> </div> <!-- End Content --> <!-- //////////////////////////////////////////////////////////////////////////// --> <!-- 模态框 --> <div class="form-group"> <input type="hidden" name="quote_currency" id="quote_currency" value="${quote_currency}"> <div class="col-sm-2"> <!-- 模态框(Modal) --> <div class="modal fade" id="modal_set" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content" style="height:500px;"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h4 class="modal-title" id="myModalLabel">交易对</h4> </div> <div class="modal-body" id="symbols_get" style="height:380px;"> <%@ include file="contract_manage_add_symbols_list.jsp"%> </div> <div class="modal-footer" style="margin-top: 0;"> <button type="button" class="btn " data-dismiss="modal" >关闭</button> <button id="sub" type="submit" class="btn btn-default" onclick="modalConfirm(this)">确认</button> </div> </div> <!-- /.modal-content --> </div> <!-- /.modal --> </div> </div> <%@ include file="include/js.jsp"%> <!-- </form> --> </div> <script type="text/javascript"> function submit() { $('#modal_succeeded').modal("show"); <%@ include file="include/js.jsp"%> <script type="text/javascript"> function submit() { $('#modal_succeeded').modal("show"); } </script> <style> /* 整个消息容器的样式 */ .message-container { background-color: #f8f9fa; /* 浅灰色背景 */ padding: 20px; border-radius: 8px; /* 圆角效果 */ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 阴影效果 */ width: 80%; /* 宽度80% */ margin: 20px auto; /* 上下留空,居中显示 */ } /* 文本的样式 */ .message-text { font-family: 'Arial', sans-serif; font-size: 18px; color: #333; /* 深灰色文字 */ line-height: 1.6; text-align: center; /* 居中显示 */ font-weight: 600; /* 加粗字体 */ } /* 增加一些响应式设计,让它在手机上也显示良好 */ @media (max-width: 600px) { .message-container { width: 95%; /* 小屏幕时宽度设置为95% */ } </script> <script type="text/javascript"> function chooseSymbol(id) { csPage(1); $('#modal_set').modal("show"); .message-text { font-size: 16px; /* 小屏幕上文字稍微小一点 */ } function csPage(pageNo,quoteCurrency,baseCurrency){ var url = $("#csUrl").val(); quoteCurrency = null==quoteCurrency||''==quoteCurrency||typeof(quoteCurrency) == "undefined"?$('#quote_currency').val():quoteCurrency; baseCurrency = null==baseCurrency||''==baseCurrency||typeof(baseCurrency) == "undefined"?$('#base_currency').val():baseCurrency; pageNo = Number(pageNo)<=0?1:pageNo; var data = {"pageNo":pageNo,"quote_currency":quoteCurrency,"base_currency":baseCurrency}; goAjaxUrl(url,data); } /* 样式定义 */ .upload-btn { display: inline-block; padding: 10px 20px; background-color: #4CAF50; /* 绿色背景 */ color: white; font-size: 16px; border-radius: 5px; /* 圆角 */ cursor: pointer; transition: background-color 0.3s ease; } .upload-btn:hover { background-color: #45a049; /* 鼠标悬停时的颜色 */ } .upload-btn:active { background-color: #397d3b; /* 按下时的颜色 */ } input[type="file"] { display: none; /* 隐藏默认的上传按钮 */ } </style> <script type="text/javascript"> function upload() { var formData = new FormData(); var fileName = document.getElementById('showName').value; var file = document.getElementById('fileName').files[0]; if (!fileName) { alert('请先输入币种官网名称(小写),否则导致图片不显示'); return; } function goAjaxUrl(targetUrl,data){ $.ajax({ url:targetUrl, data:data, type:'get', success: function (res) { $("#symbols_get").html(res); $('#quote_currency').val(data.quote_currency); $('#base_currency').val(data.base_currency); if(null==data.quote_currency||''==data.quote_currency||typeof(data.quote_currency) == "undefined"){ $('.tr_quote:first').attr('style','background:#39ffff;'); }else{ $('#tr_'+data.quote_currency).attr('style','background:#39ffff;'); } } }); } function modalConfirm(e){ $("#symbol_data").val($(".symbolCheck:checked").val()); $(e).prev().click(); } </script> formData.append("file", file); formData.append("fileName", fileName); $.ajax({ type: "POST", url: "<%=basePath%>normal/uploadimg!publishExecute.action?random=" + Math.random(), data: formData, dataType: "json", contentType: false, processData: false, success: function(data) { console.log(data); // 更新隐藏输入框的值 $("#title_img").val(data.data); // 强制刷新图片:给图片路径加上随机参数避免浏览器缓存 var show_img = document.getElementById('show_img'); show_img.src = "<%=base%>/wap/symbol/" + data.data + "?random=" + Math.random(); }, error: function(XMLHttpRequest, textStatus, errorThrown) { console.log("请求错误"); } }); } function chooseSymbol(id) { csPage(1); $('#modal_set').modal("show"); } function csPage(pageNo,quoteCurrency,baseCurrency){ var url = $("#csUrl").val(); quoteCurrency = null==quoteCurrency||''==quoteCurrency||typeof(quoteCurrency) == "undefined"?$('#quote_currency').val():quoteCurrency; baseCurrency = null==baseCurrency||''==baseCurrency||typeof(baseCurrency) == "undefined"?$('#base_currency').val():baseCurrency; pageNo = Number(pageNo)<=0?1:pageNo; var data = {"pageNo":pageNo,"quote_currency":quoteCurrency,"base_currency":baseCurrency}; goAjaxUrl(url,data); } function goAjaxUrl(targetUrl,data){ $.ajax({ url:targetUrl, data:data, type:'get', success: function (res) { $("#symbols_get").html(res); $('#quote_currency').val(data.quote_currency); $('#base_currency').val(data.base_currency); if(null==data.quote_currency||''==data.quote_currency||typeof(data.quote_currency) == "undefined"){ $('.tr_quote:first').attr('style','background:#39ffff;'); }else{ $('#tr_'+data.quote_currency).attr('style','background:#39ffff;'); } } }); } function modalConfirm(e){ $("#symbol_data").val($(".symbolCheck:checked").val()); $(e).prev().click(); } $(document).ready(function(){ // 点击上传区域,触发文件选择框 $('#upload-div').click(function(){ $('#image-upload').click(); }); // 当选择文件后,显示图片预览 $('#image-upload').change(function(event){ var file = event.target.files[0]; if (file && file.type.startsWith('image/')) { var reader = new FileReader(); reader.onload = function(e) { $('#image-preview').attr('src', e.target.result); $('.upload-preview').show(); }; reader.readAsDataURL(file); } }); }); </script> </body> </html>