15 files modified
1 files added
| New file |
| | |
| | | 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(); |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | moneyLogService.save(moneylog); |
| | | |
| | | order.setState(ContractOrder.STATE_CREATED); |
| | | order.setVolume(0D); |
| | | order.setDeposit(0); |
| | | order.setClose_time(new Date()); |
| | | update(order); |
| | | |
| | | /** |
| | | * 合约产品平仓后添加当前流水 |
| | | */ |
| | |
| | | order.setState(ContractOrder.STATE_CREATED); |
| | | order.setClose_time(new Date()); |
| | | } |
| | | |
| | | update(order); |
| | | return profit; |
| | | |
| | | } |
| | |
| | | } 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()); |
| | |
| | | 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) { |
| | |
| | | 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; |
| | | |
| | |
| | | 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; |
| | |
| | | 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 { |
| | |
| | | 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"; |
| | |
| | | try { |
| | | ContractOrder order = contractOrderService.findByOrderNo(order_no); |
| | | if (order == null || !ContractOrder.STATE_SUBMITTED.equals(order.getState())) { |
| | | logger.info("-----------到这里来了吗"); |
| | | /** |
| | | * 状态已改变,退出处理 |
| | | */ |
| | |
| | | } |
| | | List<Realtime> list = this.dataService.realtime(order.getSymbol()); |
| | | if (list.size() == 0) { |
| | | logger.info("-----------去你妈退出了"); |
| | | return; |
| | | } |
| | | Realtime realtime = list.get(0); |
| | |
| | | } |
| | | |
| | | } |
| | | |
| | | private static final Lock lock = new ReentrantLock(); // 全局锁,避免重复执行 |
| | | private static final long SLEEP_TIME = 500; // 重试间隔 |
| | | |
| | | /** |
| | | * 盈亏计算 |
| | |
| | | }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())) { |
| | | synchronized (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); |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | //钱包归零 |
| | | 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("---------进入强平了----------------"); |
| | |
| | | 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; |
| | | } |
| | |
| | | @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; |
| | | } |
| | |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | |
| | | import db.util.QpUtil; |
| | | import org.apache.commons.lang3.ObjectUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | |
| | | package project.project.web.api; |
| | | package project.web.api; |
| | | |
| | | import java.io.IOException; |
| | | import java.text.DecimalFormat; |
| | |
| | | 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; |
| | |
| | | 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>(); |
| | |
| | | |
| | | // 币币交易 |
| | | money = money + this.getMoneyexchangeApplyOrders(partyId, realtime_all); |
| | | |
| | | 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())); |
| | | //冻结金额 |
| | |
| | | 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)); |
| | | // 计算合约金额 |
| | | 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)); |
| | |
| | | |
| | | return data; |
| | | } |
| | | |
| | | public double getMoneyCoin(Serializable partyId, List<Realtime> realtime_all, List<String> list_symbol) { |
| | | double money_coin = 0; |
| | | |
| | |
| | | // 确保余额不会为负数 |
| | | 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)); |
| | | } |
| | | 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()); |
| | |
| | | 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; |
| | |
| | | protected SecUserService secUserService; |
| | | @Autowired |
| | | protected PasswordEncoder passwordEncoder; |
| | | |
| | | |
| | | private final String action = "normal/adminItemAction!"; |
| | | |
| | |
| | | * 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)) { |
| | |
| | | |
| | | 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(); |
| | |
| | | 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(); |
| | |
| | | } |
| | | 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); |
| | |
| | | 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) { |
| | |
| | | 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>(); |
| | |
| | | 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 |
| | |
| | | <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> |
| | | <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}"/> |
| | | <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">代码</label> |
| | | <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}"/> |
| | | <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> |
| | | <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> |
| | | </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> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="form-group"> |
| | | <label class="col-sm-2 control-label form-label">交易对</label> |
| | | <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}"/> |
| | | <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> |
| | | <a href="javascript:chooseSymbol('${id}')" class="btn btn-light" style="margin-bottom: 10px">交易对选择</a> |
| | | </div> |
| | | |
| | | <div class="col-sm-1"> |
| | |
| | | <a href="javascript:submit()" class="btn btn-default">保存</a> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="message-container"> |
| | | <p class="message-text"> |
| | | 添加完币种,请在操作里面初始化一下对于币种的K线 |
| | | </p> |
| | | </div> |
| | | </form> |
| | | |
| | | </div> |
| | |
| | | $('#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% */ |
| | | } |
| | | |
| | | .message-text { |
| | | font-size: 16px; /* 小屏幕上文字稍微小一点 */ |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /* 样式定义 */ |
| | | .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; |
| | | } |
| | | |
| | | 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"); |
| | |
| | | $("#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> |