diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/trx2Energy/TrxExchangeFailController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/trx2Energy/TrxExchangeFailController.java new file mode 100644 index 000000000..7fda7609f --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/trx2Energy/TrxExchangeFailController.java @@ -0,0 +1,134 @@ +package com.ruoyi.web.controller.trx2Energy; + + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.TrxExchangeFail; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.service.ITrxExchangeFailService; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 发送失败记录Controller + * + * @author dorion + * @date 2024-07-07 + */ +@Controller +@RequestMapping("/trx2Energy/fail") +public class TrxExchangeFailController extends BaseController +{ + private String prefix = "trx2Energy/fail"; + + @Autowired + private ITrxExchangeFailService trxExchangeFailService; + + @RequiresPermissions("trx2Energy:fail:view") + @GetMapping() + public String fail() + { + return prefix + "/fail"; + } + + /** + * 查询发送失败记录列表 + */ + @RequiresPermissions("trx2Energy:fail:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(TrxExchangeFail trxExchangeFail) + { + startPage(); + List list = trxExchangeFailService.selectTrxExchangeFailList(trxExchangeFail); + return getDataTable(list); + } + + /** + * 导出发送失败记录列表 + */ + @RequiresPermissions("trx2Energy:fail:export") + @Log(title = "发送失败记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + @ResponseBody + public AjaxResult export(TrxExchangeFail trxExchangeFail) + { + List list = trxExchangeFailService.selectTrxExchangeFailList(trxExchangeFail); + ExcelUtil util = new ExcelUtil(TrxExchangeFail.class); + return util.exportExcel(list, "发送失败记录数据"); + } + + /** + * 新增发送失败记录 + */ + @GetMapping("/add") + public String add() + { + return prefix + "/add"; + } + + /** + * 新增保存发送失败记录 + */ + @RequiresPermissions("trx2Energy:fail:add") + @Log(title = "发送失败记录", businessType = BusinessType.INSERT) + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(TrxExchangeFail trxExchangeFail) + { + return toAjax(trxExchangeFailService.insertTrxExchangeFail(trxExchangeFail)); + } + + /** + * 修改发送失败记录 + */ + @RequiresPermissions("trx2Energy:fail:edit") + @GetMapping("/edit/{idTrxExchangeFail}") + public String edit(@PathVariable("idTrxExchangeFail") Long idTrxExchangeFail, ModelMap mmap) + { + TrxExchangeFail trxExchangeFail = trxExchangeFailService.selectTrxExchangeFailByIdTrxExchangeFail(idTrxExchangeFail); + mmap.put("trxExchangeFail", trxExchangeFail); + return prefix + "/edit"; + } + + /** + * 修改保存发送失败记录 + */ + @RequiresPermissions("trx2Energy:fail:edit") + @Log(title = "发送失败记录", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(TrxExchangeFail trxExchangeFail) + { + return toAjax(trxExchangeFailService.updateTrxExchangeFail(trxExchangeFail)); + } + + /** + * 删除发送失败记录 + */ + @RequiresPermissions("trx2Energy:fail:remove") + @Log(title = "发送失败记录", businessType = BusinessType.DELETE) + @PostMapping( "/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + return toAjax(trxExchangeFailService.deleteTrxExchangeFailByIdTrxExchangeFails(ids)); + } + + + @RequiresPermissions("trx2Energy:fail:edit") + @Log(title = "批量补偿", businessType = BusinessType.ACTIVE_DATA) + @PostMapping( "/completeTask") + @ResponseBody + public AjaxResult completeTask(String ids) throws Exception { + return toAjax(trxExchangeFailService.complete(ids)); + } +} diff --git a/ruoyi-admin/src/main/resources/templates/trx2Energy/fail/add.html b/ruoyi-admin/src/main/resources/templates/trx2Energy/fail/add.html new file mode 100644 index 000000000..a705ddce7 --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/trx2Energy/fail/add.html @@ -0,0 +1,123 @@ + + + + + + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/trx2Energy/fail/edit.html b/ruoyi-admin/src/main/resources/templates/trx2Energy/fail/edit.html new file mode 100644 index 000000000..31a160806 --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/trx2Energy/fail/edit.html @@ -0,0 +1,124 @@ + + + + + + +
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/trx2Energy/fail/fail.html b/ruoyi-admin/src/main/resources/templates/trx2Energy/fail/fail.html new file mode 100644 index 000000000..a2a8e1214 --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/trx2Energy/fail/fail.html @@ -0,0 +1,191 @@ + + + + + + +
+
+
+
+
+
    +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + + + - + +
  • +
  • +  搜索 +  重置 +
  • +
+
+
+
+ + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/TrxExchangeFail.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/TrxExchangeFail.java new file mode 100644 index 000000000..d3a2a72a9 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/TrxExchangeFail.java @@ -0,0 +1,225 @@ +package com.ruoyi.common.core.domain.entity; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 发送失败记录对象 trx_exchange_fail + * + * @author dorion + * @date 2024-07-07 + */ +public class TrxExchangeFail extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键id */ + private Long idTrxExchangeFail; + + /** 转出账户 */ + @Excel(name = "转出账户") + private String fromAddress; + + /** 转入账户 */ + @Excel(name = "转入账户") + private String toAddress; + + /** 实际出账账户 */ + @Excel(name = "实际出账账户") + private String accountAddress; + + /** 单价 */ + @Excel(name = "单价") + private Long price; + + /** 订单hash */ + @Excel(name = "订单hash") + private String trxTxId; + + /** 笔数 */ + @Excel(name = "笔数") + private Long tranferCount; + + /** 业务类型 */ + @Excel(name = "业务类型") + private String energyBusiType; + + /** 转入金额 */ + @Excel(name = "转入金额") + private Long trxAmount; + + /** 转入单位 */ + @Excel(name = "转入单位") + private String trxAmountUnit; + + + /** 资源类型 */ + @Excel(name = "资源类型") + private String resourceCode; + + /** 锁定周期 */ + @Excel(name = "锁定周期") + private Long lockPeriod; + + /** 补偿状态 */ + @Excel(name = "补偿状态") + private String delegateStatus; + + /** 笔数计算规则 */ + @Excel(name = "笔数计算规则") + private String calcRule; + + public void setIdTrxExchangeFail(Long idTrxExchangeFail) + { + this.idTrxExchangeFail = idTrxExchangeFail; + } + + public Long getIdTrxExchangeFail() + { + return idTrxExchangeFail; + } + public void setFromAddress(String fromAddress) + { + this.fromAddress = fromAddress; + } + + public String getFromAddress() + { + return fromAddress; + } + public void setToAddress(String toAddress) + { + this.toAddress = toAddress; + } + + public String getToAddress() + { + return toAddress; + } + public void setAccountAddress(String accountAddress) + { + this.accountAddress = accountAddress; + } + + public String getAccountAddress() + { + return accountAddress; + } + public void setPrice(Long price) + { + this.price = price; + } + + public Long getPrice() + { + return price; + } + public void setTrxTxId(String trxTxId) + { + this.trxTxId = trxTxId; + } + + public String getTrxTxId() + { + return trxTxId; + } + public void setTranferCount(Long tranferCount) + { + this.tranferCount = tranferCount; + } + + public Long getTranferCount() + { + return tranferCount; + } + public void setEnergyBusiType(String energyBusiType) + { + this.energyBusiType = energyBusiType; + } + + public String getEnergyBusiType() + { + return energyBusiType; + } + public void setTrxAmount(Long trxAmount) + { + this.trxAmount = trxAmount; + } + + public Long getTrxAmount() + { + return trxAmount; + } + public void setTrxAmountUnit(String trxAmountUnit) + { + this.trxAmountUnit = trxAmountUnit; + } + + public String getTrxAmountUnit() + { + return trxAmountUnit; + } + + public void setResourceCode(String resourceCode) + { + this.resourceCode = resourceCode; + } + + public String getResourceCode() + { + return resourceCode; + } + public void setLockPeriod(Long lockPeriod) + { + this.lockPeriod = lockPeriod; + } + + public Long getLockPeriod() + { + return lockPeriod; + } + public void setDelegateStatus(String delegateStatus) + { + this.delegateStatus = delegateStatus; + } + + public String getDelegateStatus() + { + return delegateStatus; + } + public void setCalcRule(String calcRule) + { + this.calcRule = calcRule; + } + + public String getCalcRule() + { + return calcRule; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("idTrxExchangeFail", getIdTrxExchangeFail()) + .append("fromAddress", getFromAddress()) + .append("toAddress", getToAddress()) + .append("accountAddress", getAccountAddress()) + .append("price", getPrice()) + .append("trxTxId", getTrxTxId()) + .append("tranferCount", getTranferCount()) + .append("energyBusiType", getEnergyBusiType()) + .append("trxAmount", getTrxAmount()) + .append("trxAmountUnit", getTrxAmountUnit()) + .append("resourceCode", getResourceCode()) + .append("lockPeriod", getLockPeriod()) + .append("delegateStatus", getDelegateStatus()) + .append("calcRule", getCalcRule()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java index af95dbe58..098e90343 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java @@ -4,8 +4,8 @@ import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.entity.SysDictData; import org.springframework.stereotype.Component; -import java.util.Collections; import java.util.List; +import java.util.Random; /** * 字典工具类 @@ -77,8 +77,10 @@ public class DictUtils if (StringUtils.isNotNull(cacheObj)) { List sysDictDataList = StringUtils.cast(cacheObj); - Collections.shuffle(sysDictDataList); - return sysDictDataList.get(0).getDictValue(); + Random random = new Random(); + int i = random.nextInt(sysDictDataList.size()); +// Collections.shuffle(sysDictDataList); + return sysDictDataList.get(i).getDictValue(); } return null; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/handler/TRX2EneryTransferHandler.java b/ruoyi-system/src/main/java/com/ruoyi/system/handler/TRX2EneryTransferHandler.java index 64ef3ed7c..30829b0be 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/handler/TRX2EneryTransferHandler.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/handler/TRX2EneryTransferHandler.java @@ -7,6 +7,7 @@ import cn.hutool.json.JSONUtil; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.domain.entity.ErrorLog; import com.ruoyi.common.core.domain.entity.TenantInfo; +import com.ruoyi.common.core.domain.entity.TrxExchangeFail; import com.ruoyi.common.core.domain.entity.TrxExchangeInfo; import com.ruoyi.common.utils.DictUtils; import com.ruoyi.common.utils.ForwardCounter; @@ -22,6 +23,7 @@ import com.ruoyi.system.dto.Data; import com.ruoyi.system.dto.TronGridResponse; import com.ruoyi.system.dto.Value; import com.ruoyi.system.mapper.TenantInfoMapper; +import com.ruoyi.system.mapper.TrxExchangeFailMapper; import com.ruoyi.system.mapper.TrxExchangeInfoMapper; import com.ruoyi.system.service.IErrorLogService; import com.ruoyi.system.service.ISysConfigService; @@ -75,6 +77,8 @@ public class TRX2EneryTransferHandler { @Autowired private IErrorLogService errorLogService; + @Autowired + private TrxExchangeFailMapper trxExchangeFailMapper; public void doMonitorTrxTransferByMonitorAddressInfo(MonitorAddressAccount monitorAddressAccount) { @@ -146,9 +150,10 @@ public class TRX2EneryTransferHandler { .errorMsg(exceptionString.length() > 2000 ? exceptionString.substring(0, 2000) : exceptionString) .fcu("system") .lcu("system").build(); - errorLogService.insertErrorLog(errorLog); -// throw new RuntimeException("doDelegateResource业务处理异常", e); + + + } finally { if (lock.isLocked()) { if (lock.isHeldByCurrentThread()) { @@ -366,7 +371,30 @@ public class TRX2EneryTransferHandler { /* lock_period: 锁定周期,以区块时间(3s)为单位,表示锁定多少个区块的时间,当lock为true时,该字段有效。如果代理锁定期为1天,则lock_period为:28800*/ - delegateResourceTxid = getDelegateResourceTxid(apiWrapper, accountAddress, balance, ownerAddress, resourceCode); + try { + delegateResourceTxid = getDelegateResourceTxid(apiWrapper, accountAddress, balance, ownerAddress, resourceCode); + } catch (Exception e) { + Object cacheidTrxExchangeFail = redisTemplate.opsForValue().get("transfer_trx_fail_" + txID); + if (cacheidTrxExchangeFail == null){ + TrxExchangeFail trxExchangeFail = new TrxExchangeFail(); + trxExchangeFail.setFromAddress(ownerAddress); + trxExchangeFail.setToAddress(toAddress); + trxExchangeFail.setAccountAddress(accountAddress); + trxExchangeFail.setPrice(price); + trxExchangeFail.setTrxTxId(txID); + trxExchangeFail.setTranferCount(transferCount); + trxExchangeFail.setEnergyBusiType(sysEnergyBusiType); + trxExchangeFail.setTrxAmount(amount); + trxExchangeFail.setTrxAmountUnit(trxAmountUnit); + trxExchangeFail.setResourceCode(resourceCode); + trxExchangeFail.setLockPeriod(lockPeriod); + trxExchangeFail.setDelegateStatus("2"); + trxExchangeFail.setCalcRule(calcRule); + trxExchangeFailMapper.insertTrxExchangeFail(trxExchangeFail); + redisTemplate.opsForValue().set("transfer_trx_fail_" + txID, trxExchangeFail.getIdTrxExchangeFail(), 1, TimeUnit.HOURS); + } + throw new RuntimeException(e); + } } String fromAddress = AddressUtil.hexToBase58(ownerAddress); @@ -393,6 +421,16 @@ public class TRX2EneryTransferHandler { .build(); trxExchangeInfoMapper.insertTrxExchangeInfo(trxExchangeInfo); + Object cacheidTrxExchangeFail = redisTemplate.opsForValue().get("transfer_trx_fail_" + txID); + if (cacheidTrxExchangeFail != null){ + + TrxExchangeFail trxExchangeFail = new TrxExchangeFail(); + trxExchangeFail.setIdTrxExchangeFail(Long.valueOf(cacheidTrxExchangeFail.toString())); + trxExchangeFail.setDelegateStatus("1"); + trxExchangeFailMapper.updateTrxExchangeFail(trxExchangeFail); + redisTemplate.delete("transfer_trx_fail_" + txID); + } + String sysenTrxTransferNotice = configService.selectConfigByKey("sys.energy.transaction.notice"); String sysTgGroupChatId = configService.selectConfigByKey("sys.tg.group.chat.id"); if (longPollingBot != null && StringUtils.isNotEmpty(sysenTrxTransferNotice) && StringUtils.isNotEmpty(sysTgGroupChatId)) { @@ -443,11 +481,13 @@ public class TRX2EneryTransferHandler { } private String getDelegateResourceTxid(ApiWrapper apiWrapper, String accountAddress, long balance, String ownerAddress, String resourceCode) throws IllegalException { + Response.TransactionExtention transactionExtention = apiWrapper.delegateResourceV2(accountAddress, balance * 1000000, Common.ResourceCode.valueOf(resourceCode).getNumber(), ownerAddress, false, 0); Chain.Transaction transaction = apiWrapper.signTransaction(transactionExtention); String delegateResourceTxid = apiWrapper.broadcastTransaction(transaction); + return delegateResourceTxid; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/handler/UndelegateEnergyHandler.java b/ruoyi-system/src/main/java/com/ruoyi/system/handler/UndelegateEnergyHandler.java index 9bf5f276c..6c0bd1cb6 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/handler/UndelegateEnergyHandler.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/handler/UndelegateEnergyHandler.java @@ -246,6 +246,7 @@ public class UndelegateEnergyHandler { tenantInfo.setLcu("system"); + tenantInfo.setLcd(new Date()); tenantInfoMapper.updateTenantInfo(tenantInfo); } @@ -261,7 +262,6 @@ public class UndelegateEnergyHandler { .fcu("system") .lcu("system").build(); errorLogService.insertErrorLog(errorLog); -// throw new RuntimeException("回收能量业务处理异常", e); } finally { if (lock.isLocked()) { if (lock.isHeldByCurrentThread()) { diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TrxExchangeFailMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TrxExchangeFailMapper.java new file mode 100644 index 000000000..bf4d14c4c --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TrxExchangeFailMapper.java @@ -0,0 +1,67 @@ +package com.ruoyi.system.mapper; + +import com.ruoyi.common.core.domain.entity.TrxExchangeFail; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 发送失败记录Mapper接口 + * + * @author dorion + * @date 2024-07-07 + */ +public interface TrxExchangeFailMapper +{ + /** + * 查询发送失败记录 + * + * @param idTrxExchangeFail 发送失败记录主键 + * @return 发送失败记录 + */ + public TrxExchangeFail selectTrxExchangeFailByIdTrxExchangeFail(Long idTrxExchangeFail); + + /** + * 查询发送失败记录列表 + * + * @param trxExchangeFail 发送失败记录 + * @return 发送失败记录集合 + */ + public List selectTrxExchangeFailList(TrxExchangeFail trxExchangeFail); + + /** + * 新增发送失败记录 + * + * @param trxExchangeFail 发送失败记录 + * @return 结果 + */ + public int insertTrxExchangeFail(TrxExchangeFail trxExchangeFail); + + /** + * 修改发送失败记录 + * + * @param trxExchangeFail 发送失败记录 + * @return 结果 + */ + public int updateTrxExchangeFail(TrxExchangeFail trxExchangeFail); + + /** + * 删除发送失败记录 + * + * @param idTrxExchangeFail 发送失败记录主键 + * @return 结果 + */ + public int deleteTrxExchangeFailByIdTrxExchangeFail(Long idTrxExchangeFail); + + /** + * 批量删除发送失败记录 + * + * @param idTrxExchangeFails 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteTrxExchangeFailByIdTrxExchangeFails(String[] idTrxExchangeFails); + + public List selectTrxExchangeFailListByIdList(@Param("idsList") List idsList); + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ITrxExchangeFailService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ITrxExchangeFailService.java new file mode 100644 index 000000000..44a2f78f4 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ITrxExchangeFailService.java @@ -0,0 +1,65 @@ +package com.ruoyi.system.service; + + +import com.ruoyi.common.core.domain.entity.TrxExchangeFail; + +import java.util.List; + +/** + * 发送失败记录Service接口 + * + * @author dorion + * @date 2024-07-07 + */ +public interface ITrxExchangeFailService +{ + /** + * 查询发送失败记录 + * + * @param idTrxExchangeFail 发送失败记录主键 + * @return 发送失败记录 + */ + public TrxExchangeFail selectTrxExchangeFailByIdTrxExchangeFail(Long idTrxExchangeFail); + + /** + * 查询发送失败记录列表 + * + * @param trxExchangeFail 发送失败记录 + * @return 发送失败记录集合 + */ + public List selectTrxExchangeFailList(TrxExchangeFail trxExchangeFail); + + /** + * 新增发送失败记录 + * + * @param trxExchangeFail 发送失败记录 + * @return 结果 + */ + public int insertTrxExchangeFail(TrxExchangeFail trxExchangeFail); + + /** + * 修改发送失败记录 + * + * @param trxExchangeFail 发送失败记录 + * @return 结果 + */ + public int updateTrxExchangeFail(TrxExchangeFail trxExchangeFail); + + /** + * 批量删除发送失败记录 + * + * @param idTrxExchangeFails 需要删除的发送失败记录主键集合 + * @return 结果 + */ + public int deleteTrxExchangeFailByIdTrxExchangeFails(String idTrxExchangeFails); + + /** + * 删除发送失败记录信息 + * + * @param idTrxExchangeFail 发送失败记录主键 + * @return 结果 + */ + public int deleteTrxExchangeFailByIdTrxExchangeFail(Long idTrxExchangeFail); + + int complete(String ids) throws Exception; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TrxExchangeFailServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TrxExchangeFailServiceImpl.java new file mode 100644 index 000000000..0718fc005 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TrxExchangeFailServiceImpl.java @@ -0,0 +1,179 @@ +package com.ruoyi.system.service.impl; + + +import com.ruoyi.common.core.domain.entity.TrxExchangeFail; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.utils.*; +import com.ruoyi.system.handler.TRX2EneryTransferHandler; +import com.ruoyi.system.mapper.TrxExchangeFailMapper; +import com.ruoyi.system.service.IAccountAddressInfoService; +import com.ruoyi.system.service.ITrxExchangeFailService; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; +import org.tron.trident.core.ApiWrapper; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * 发送失败记录Service业务层处理 + * + * @author dorion + * @date 2024-07-07 + */ +@Service +public class TrxExchangeFailServiceImpl implements ITrxExchangeFailService +{ + private static final Logger log = LoggerFactory.getLogger(TrxExchangeFailServiceImpl.class); + @Autowired + private TrxExchangeFailMapper trxExchangeFailMapper; + + @Autowired + private TRX2EneryTransferHandler trx2EneryTransferHandler; + + @Autowired + private IAccountAddressInfoService accountAddressInfoService; + + @Autowired + private RedisTemplate redisTemplate; + @Autowired + private RedissonClient redissonClient; + + /** + * 查询发送失败记录 + * + * @param idTrxExchangeFail 发送失败记录主键 + * @return 发送失败记录 + */ + @Override + public TrxExchangeFail selectTrxExchangeFailByIdTrxExchangeFail(Long idTrxExchangeFail) + { + return trxExchangeFailMapper.selectTrxExchangeFailByIdTrxExchangeFail(idTrxExchangeFail); + } + + /** + * 查询发送失败记录列表 + * + * @param trxExchangeFail 发送失败记录 + * @return 发送失败记录 + */ + @Override + public List selectTrxExchangeFailList(TrxExchangeFail trxExchangeFail) + { + return trxExchangeFailMapper.selectTrxExchangeFailList(trxExchangeFail); + } + + /** + * 新增发送失败记录 + * + * @param trxExchangeFail 发送失败记录 + * @return 结果 + */ + @Override + public int insertTrxExchangeFail(TrxExchangeFail trxExchangeFail) + { + trxExchangeFail.setCreateTime(DateUtils.getNowDate()); + return trxExchangeFailMapper.insertTrxExchangeFail(trxExchangeFail); + } + + /** + * 修改发送失败记录 + * + * @param trxExchangeFail 发送失败记录 + * @return 结果 + */ + @Override + public int updateTrxExchangeFail(TrxExchangeFail trxExchangeFail) + { + trxExchangeFail.setUpdateTime(DateUtils.getNowDate()); + return trxExchangeFailMapper.updateTrxExchangeFail(trxExchangeFail); + } + + /** + * 批量删除发送失败记录 + * + * @param idTrxExchangeFails 需要删除的发送失败记录主键 + * @return 结果 + */ + @Override + public int deleteTrxExchangeFailByIdTrxExchangeFails(String idTrxExchangeFails) + { + return trxExchangeFailMapper.deleteTrxExchangeFailByIdTrxExchangeFails(Convert.toStrArray(idTrxExchangeFails)); + } + + /** + * 删除发送失败记录信息 + * + * @param idTrxExchangeFail 发送失败记录主键 + * @return 结果 + */ + @Override + public int deleteTrxExchangeFailByIdTrxExchangeFail(Long idTrxExchangeFail) + { + return trxExchangeFailMapper.deleteTrxExchangeFailByIdTrxExchangeFail(idTrxExchangeFail); + } + + @Override + public int complete(String ids) throws Exception { + List idsList = Arrays.asList(ids.split(",")); + + List trxExchangeFails = trxExchangeFailMapper.selectTrxExchangeFailListByIdList(idsList); + + String apiKey = DictUtils.getRandomDictValue("sys_tron_api_key"); + + + for (TrxExchangeFail trxExchangeFail : trxExchangeFails) { + String decryptPrivateKey = accountAddressInfoService.getDecryptPrivateKey(trxExchangeFail.getAccountAddress()); + + ApiWrapper apiWrapper = ApiWrapper.ofMainnet( decryptPrivateKey,apiKey); + String txID = trxExchangeFail.getTrxTxId(); + Boolean hasKey = redisTemplate.hasKey("transfer_trx_" + txID); + if (hasKey) { + continue; + } + + + RLock lock = redissonClient.getLock("lock_" + txID); + try { + boolean res = lock.tryLock(3, 50, TimeUnit.SECONDS); + if (!res) { + //有其他程序正在处理则不需要再处理 + continue; + } + + trx2EneryTransferHandler.calcBalanceAndDelegate(txID, + apiWrapper, + trxExchangeFail.getAccountAddress(), + trxExchangeFail.getTranferCount(), + trxExchangeFail.getFromAddress(), + trxExchangeFail.getLockPeriod(), + trxExchangeFail.getToAddress(), + trxExchangeFail.getPrice(), + trxExchangeFail.getEnergyBusiType(), + trxExchangeFail.getTrxAmount(), + trxExchangeFail.getTrxAmountUnit(), + ShiroUtils.getLoginName(), + trxExchangeFail.getResourceCode(), trxExchangeFail.getCalcRule()); + + + }catch (Exception e){ + log.error("doDelegateResource业务处理异常{},txid:{},exception:", trxExchangeFail.getFromAddress(), txID, e); + throw new RuntimeException("补偿失败"); + }finally { + if (lock.isLocked()) { + if (lock.isHeldByCurrentThread()) { + lock.unlock(); + } + } + } + } + + return idsList.size(); + } +} diff --git a/ruoyi-system/src/main/resources/mapper/exchange/TrxExchangeFailMapper.xml b/ruoyi-system/src/main/resources/mapper/exchange/TrxExchangeFailMapper.xml new file mode 100644 index 000000000..2e6774d38 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/exchange/TrxExchangeFailMapper.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + select id_trx_exchange_fail, from_address, to_address, account_address, price, trx_tx_id, tranfer_count, energy_busi_type, trx_amount, trx_amount_unit, resource_code, lock_period, delegate_status, calc_rule, create_by, create_time, update_by, update_time from trx_exchange_fail + + + + + + + + insert into trx_exchange_fail + + from_address, + to_address, + account_address, + price, + trx_tx_id, + tranfer_count, + energy_busi_type, + trx_amount, + trx_amount_unit, + resource_code, + lock_period, + delegate_status, + calc_rule, + create_by, + create_time, + update_by, + update_time, + + + #{fromAddress}, + #{toAddress}, + #{accountAddress}, + #{price}, + #{trxTxId}, + #{tranferCount}, + #{energyBusiType}, + #{trxAmount}, + #{trxAmountUnit}, + #{resourceCode}, + #{lockPeriod}, + #{delegateStatus}, + #{calcRule}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update trx_exchange_fail + + from_address = #{fromAddress}, + to_address = #{toAddress}, + account_address = #{accountAddress}, + price = #{price}, + trx_tx_id = #{trxTxId}, + tranfer_count = #{tranferCount}, + energy_busi_type = #{energyBusiType}, + trx_amount = #{trxAmount}, + trx_amount_unit = #{trxAmountUnit}, + resource_code = #{resourceCode}, + lock_period = #{lockPeriod}, + delegate_status = #{delegateStatus}, + calc_rule = #{calcRule}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id_trx_exchange_fail = #{idTrxExchangeFail} + + + + delete from trx_exchange_fail where id_trx_exchange_fail = #{idTrxExchangeFail} + + + + delete from trx_exchange_fail where id_trx_exchange_fail in + + #{idTrxExchangeFail} + + + + + \ No newline at end of file