ws积分体系,充值体系等功能搭建

pull/520/head
dorion 2024-07-29 23:23:52 +08:00
parent 88f6bcad05
commit 1009db57be
61 changed files with 4932 additions and 180 deletions

17
pom.xml
View File

@ -30,6 +30,8 @@
<commons.io.version>2.13.0</commons.io.version>
<poi.version>4.1.2</poi.version>
<velocity.version>2.3</velocity.version>
<org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
<org.projectlombok.version>1.18.30</org.projectlombok.version>
</properties>
<!-- 依赖声明 -->
@ -193,6 +195,21 @@
<version>${ruoyi.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -79,6 +79,19 @@
<version>1.18.30</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,185 @@
package com.ruoyi.web.controller.sms;
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.MonitorAddressInfo;
import com.ruoyi.common.core.domain.entity.PointRechargeOrder;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.vo.MonitorAddressInfoVO;
import com.ruoyi.system.service.IMonitorAddressInfoService;
import com.ruoyi.system.service.IPointRechargeOrderService;
import com.ruoyi.system.service.ISysUserService;
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.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Controller
*
* @author dorion
* @date 2024-07-21
*/
@Controller
@RequestMapping("/sms/point")
public class PointRechargeOrderController extends BaseController
{
private String prefix = "sms/point";
@Autowired
private IMonitorAddressInfoService monitorAddressInfoService;
@Autowired
private IPointRechargeOrderService pointRechargeOrderService;
@Autowired
private ISysUserService sysUserService;
@RequiresPermissions("sms:point:view")
@GetMapping()
public String point(ModelMap mmap)
{
List<SysUser> sysUserList = sysUserService.selectUserList(new SysUser());
mmap.put("sysUserList",sysUserList);
return prefix + "/point";
}
/**
*
*/
@RequiresPermissions("sms:point:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(PointRechargeOrder pointRechargeOrder)
{
startPage();
List<PointRechargeOrder> list = pointRechargeOrderService.selectPointRechargeOrderList(pointRechargeOrder);
return getDataTable(list);
}
/**
*
*/
@RequiresPermissions("sms:point:export")
@Log(title = "群发充值管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(PointRechargeOrder pointRechargeOrder)
{
List<PointRechargeOrder> list = pointRechargeOrderService.selectPointRechargeOrderList(pointRechargeOrder);
ExcelUtil<PointRechargeOrder> util = new ExcelUtil<PointRechargeOrder>(PointRechargeOrder.class);
return util.exportExcel(list, "群发充值管理数据");
}
/**
*
*/
@GetMapping("/add")
public String add(ModelMap mmap)
{
List<SysUser> sysUserList = sysUserService.selectUserList(new SysUser());
mmap.put("sysUserList",sysUserList);
return prefix + "/add";
}
/**
*
*/
@RequiresPermissions("sms:point:recharge")
@GetMapping("/recharge")
public String rechage(ModelMap mmap)
{
/*List<SysUser> sysUserList = sysUserService.selectUserList(new SysUser());
mmap.put("sysUserList",sysUserList);*/
return prefix + "/recharge";
}
@RequiresPermissions("sms:point:recharge")
@GetMapping("/rechargeOrder/{idPointRechargeOrder}")
public String rechargeOrder(ModelMap mmap,@PathVariable("idPointRechargeOrder") Long idPointRechargeOrder)
{
PointRechargeOrder pointRechargeOrder = pointRechargeOrderService.selectPointRechargeOrderByIdPointRechargeOrder(idPointRechargeOrder);
BigDecimal amount = pointRechargeOrder.getAmount();
MonitorAddressInfo monitorAddressInfo = new MonitorAddressInfo();
monitorAddressInfo.setBusiType(DictUtils.getDictValue("sys_busi_type", "短信群发"));
List<MonitorAddressInfoVO> list = monitorAddressInfoService.selectMonitorAddressInfoList(monitorAddressInfo);
MonitorAddressInfoVO monitorAddressInfoVO = list.get(0);
String monitorAddress = monitorAddressInfoVO.getMonitorAddress();
String imageUrl = monitorAddressInfoVO.getImageUrl();
mmap.put("amount",amount);
mmap.put("monitorAddress",monitorAddress);
mmap.put("imageUrl",imageUrl);
return prefix + "/rechargeOrder";
}
/**
*
*/
@RequiresPermissions("sms:point:add")
@Log(title = "群发充值管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(PointRechargeOrder pointRechargeOrder)
{
return toAjax(pointRechargeOrderService.insertPointRechargeOrder(pointRechargeOrder));
}
@RequiresPermissions("ssms:point:recharge")
@Log(title = "群发充值管理", businessType = BusinessType.INSERT)
@PostMapping("/rechargeOrder")
@ResponseBody
public Map<String, Object> rechargeOrder(PointRechargeOrder pointRechargeOrder)
{
Map<String, Object> result = new HashMap<>();
Long idPointRechargeOrder = pointRechargeOrderService.rechargeOrder(pointRechargeOrder);
result.put("success", true);
result.put("newPageUrl", "/sms/point/rechargeOrder/"+idPointRechargeOrder); // 返回新的页面 URL
return result;
}
/**
*
*/
@RequiresPermissions("sms:point:edit")
@GetMapping("/edit/{idPointRechargeOrder}")
public String edit(@PathVariable("idPointRechargeOrder") Long idPointRechargeOrder, ModelMap mmap)
{
PointRechargeOrder pointRechargeOrder = pointRechargeOrderService.selectPointRechargeOrderByIdPointRechargeOrder(idPointRechargeOrder);
mmap.put("pointRechargeOrder", pointRechargeOrder);
List<SysUser> sysUserList = sysUserService.selectUserList(new SysUser());
mmap.put("sysUserList",sysUserList);
return prefix + "/edit";
}
/**
*
*/
@RequiresPermissions("sms:point:edit")
@Log(title = "群发充值管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(PointRechargeOrder pointRechargeOrder)
{
return toAjax(pointRechargeOrderService.updatePointRechargeOrder(pointRechargeOrder));
}
/**
*
*/
@RequiresPermissions("sms:point:remove")
@Log(title = "群发充值管理", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(pointRechargeOrderService.deletePointRechargeOrderByIdPointRechargeOrders(ids));
}
}

View File

@ -0,0 +1,122 @@
package com.ruoyi.web.controller.sms;
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.CountryTbl;
import com.ruoyi.common.core.domain.entity.SmsCountryPrice;
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.ISmsCountryPriceService;
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-21
*/
@Controller
@RequestMapping("/sms/country")
public class SmsCountryPriceController extends BaseController {
private String prefix = "sms/country";
@Autowired
private ISmsCountryPriceService smsCountryPriceService;
@RequiresPermissions("sms:country:view")
@GetMapping()
public String country(ModelMap mmp) {
List<CountryTbl> countries = smsCountryPriceService.selectAllCountries();
mmp.put("countries", countries);
return prefix + "/country";
}
/**
*
*/
@RequiresPermissions("sms:country:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SmsCountryPrice smsCountryPrice) {
startPage();
List<SmsCountryPrice> list = smsCountryPriceService.selectSmsCountryPriceList(smsCountryPrice);
return getDataTable(list);
}
/**
*
*/
@RequiresPermissions("sms:country:export")
@Log(title = "群发国家单价配置", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SmsCountryPrice smsCountryPrice) {
List<SmsCountryPrice> list = smsCountryPriceService.selectSmsCountryPriceList(smsCountryPrice);
ExcelUtil<SmsCountryPrice> util = new ExcelUtil<SmsCountryPrice>(SmsCountryPrice.class);
return util.exportExcel(list, "群发国家单价配置数据");
}
/**
*
*/
@GetMapping("/add")
public String add(ModelMap mmp) {
List<CountryTbl> countries = smsCountryPriceService.selectAllCountries();
mmp.put("countries", countries);
return prefix + "/add";
}
/**
*
*/
@RequiresPermissions("sms:country:add")
@Log(title = "群发国家单价配置", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(SmsCountryPrice smsCountryPrice) {
return toAjax(smsCountryPriceService.insertSmsCountryPrice(smsCountryPrice));
}
/**
*
*/
@RequiresPermissions("sms:country:edit")
@GetMapping("/edit/{idSmsCountryPrice}")
public String edit(@PathVariable("idSmsCountryPrice") Long idSmsCountryPrice, ModelMap mmap) {
SmsCountryPrice smsCountryPrice = smsCountryPriceService.selectSmsCountryPriceByIdSmsCountryPrice(idSmsCountryPrice);
mmap.put("smsCountryPrice", smsCountryPrice);
List<CountryTbl> countries = smsCountryPriceService.selectAllCountries();
mmap.put("countries", countries);
return prefix + "/edit";
}
/**
*
*/
@RequiresPermissions("sms:country:edit")
@Log(title = "群发国家单价配置", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SmsCountryPrice smsCountryPrice) {
return toAjax(smsCountryPriceService.updateSmsCountryPrice(smsCountryPrice));
}
/**
*
*/
@RequiresPermissions("sms:country:remove")
@Log(title = "群发国家单价配置", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids) {
return toAjax(smsCountryPriceService.deleteSmsCountryPriceByIdSmsCountryPrices(ids));
}
}

View File

@ -0,0 +1,157 @@
package com.ruoyi.web.controller.sms;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.config.ServerConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.MonitorAddressInfo;
import com.ruoyi.common.core.domain.entity.TgMessageInfo;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.vo.MonitorAddressInfoVO;
import com.ruoyi.system.service.IAccountAddressInfoService;
import com.ruoyi.system.service.IMonitorAddressInfoService;
import com.ruoyi.system.service.impl.TgMessageInfoServiceImpl;
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 org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
/**
* Controller
*
* @author dorion
* @date 2024-04-13
*/
@Controller
@RequestMapping("/sms/monitor")
public class SmsMonitorAddressInfoController extends BaseController
{
private String prefix = "sms/monitor";
@Autowired
private IMonitorAddressInfoService monitorAddressInfoService;
@Autowired
private IAccountAddressInfoService accountAddressInfoService;
@Autowired
private TgMessageInfoServiceImpl tgMessageInfoService;
@Autowired
private ServerConfig serverConfig;
@RequiresPermissions("sms:monitor:view")
@GetMapping()
public String monitor(ModelMap mmap)
{
TgMessageInfo tgMessageInfo = new TgMessageInfo();
tgMessageInfo.setMessageType(5L);
mmap.put("topicTgmessageInfoList", tgMessageInfoService.selectTgMessageInfoList(tgMessageInfo));
return prefix + "/monitor";
}
/**
*
*/
@RequiresPermissions("sms:monitor:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(MonitorAddressInfo monitorAddressInfo)
{
startPage();
monitorAddressInfo.setBusiType(DictUtils.getDictValue("sys_busi_type", "短信群发"));
List<MonitorAddressInfoVO> list = monitorAddressInfoService.selectMonitorAddressInfoList(monitorAddressInfo);
return getDataTable(list);
}
/**
*
*/
@RequiresPermissions("sms:monitor:export")
@Log(title = "监听账户入账", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(MonitorAddressInfo monitorAddressInfo)
{
monitorAddressInfo.setBusiType(DictUtils.getDictValue("sys_busi_type", "短信群发"));
List<MonitorAddressInfoVO> list = monitorAddressInfoService.selectMonitorAddressInfoList(monitorAddressInfo);
ExcelUtil<MonitorAddressInfoVO> util = new ExcelUtil<MonitorAddressInfoVO>(MonitorAddressInfoVO.class);
return util.exportExcel(list, "监听账户入账数据");
}
/**
*
*/
@GetMapping("/add")
public String add(ModelMap mmap)
{
TgMessageInfo tgMessageInfo = new TgMessageInfo();
tgMessageInfo.setMessageType(5L);
mmap.put("topicTgmessageInfoList", tgMessageInfoService.selectTgMessageInfoList(tgMessageInfo));
return prefix + "/add";
}
/**
*
*/
@RequiresPermissions("sms:monitor:add")
@Log(title = "监听账户入账", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@RequestParam("file") MultipartFile file, MonitorAddressInfo monitorAddressInfo) throws IOException { // 上传文件路径
String filePath = RuoYiConfig.getUploadPath();
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
monitorAddressInfo.setImageUrl(url);
monitorAddressInfo.setBusiType(DictUtils.getDictValue("sys_busi_type", "短信群发"));
return toAjax(monitorAddressInfoService.insertMonitorAddressInfo(monitorAddressInfo));
}
/**
*
*/
@RequiresPermissions("sms:monitor:edit")
@GetMapping("/edit/{idMonitorAddress}")
public String edit(@PathVariable("idMonitorAddress") Long idMonitorAddress, ModelMap mmap)
{
MonitorAddressInfo monitorAddressInfo = monitorAddressInfoService.selectMonitorAddressInfoByIdMonitorAddress(idMonitorAddress);
mmap.put("monitorAddressInfo", monitorAddressInfo);
TgMessageInfo tgMessageInfo = new TgMessageInfo();
tgMessageInfo.setMessageType(5L);
mmap.put("topicTgmessageInfoList", tgMessageInfoService.selectTgMessageInfoList(tgMessageInfo));
return prefix + "/edit";
}
/**
*
*/
@RequiresPermissions("sms:monitor:edit")
@Log(title = "监听账户入账", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(MonitorAddressInfo monitorAddressInfo)
{
return toAjax(monitorAddressInfoService.updateMonitorAddressInfo(monitorAddressInfo));
}
/**
*
*/
@RequiresPermissions("sms:monitor:remove")
@Log(title = "监听账户入账", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(monitorAddressInfoService.deleteMonitorAddressInfoByIdMonitorAddresss(ids));
}
}

View File

@ -0,0 +1,134 @@
package com.ruoyi.web.controller.sms;
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.SysUser;
import com.ruoyi.common.core.domain.entity.UserPoint;
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.ISysUserService;
import com.ruoyi.system.service.IUserPointService;
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-21
*/
@Controller
@RequestMapping("/sms/user")
public class UserPointController extends BaseController
{
private String prefix = "sms/user";
@Autowired
private IUserPointService userPointService;
@Autowired
private ISysUserService sysUserService;
@RequiresPermissions("sms:user:view")
@GetMapping()
public String user(ModelMap mmap)
{
List<SysUser> sysUserList = sysUserService.selectUserList(new SysUser());
mmap.put("sysUserList",sysUserList);
return prefix + "/user";
}
/**
*
*/
@RequiresPermissions("sms:user:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(UserPoint userPoint)
{
startPage();
List<UserPoint> list = userPointService.selectUserPointList(userPoint);
return getDataTable(list);
}
/**
*
*/
@RequiresPermissions("sms:user:export")
@Log(title = "用户积分", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(UserPoint userPoint)
{
List<UserPoint> list = userPointService.selectUserPointList(userPoint);
ExcelUtil<UserPoint> util = new ExcelUtil<UserPoint>(UserPoint.class);
return util.exportExcel(list, "用户积分数据");
}
/**
*
*/
@GetMapping("/add")
public String add(ModelMap mmap)
{
List<SysUser> sysUserList = sysUserService.selectUserList(new SysUser());
mmap.put("sysUserList",sysUserList);
return prefix + "/add";
}
/**
*
*/
@RequiresPermissions("sms:user:add")
@Log(title = "用户积分", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(UserPoint userPoint)
{
return toAjax(userPointService.insertUserPoint(userPoint));
}
/**
*
*/
@RequiresPermissions("sms:user:edit")
@GetMapping("/edit/{idUserPoint}")
public String edit(@PathVariable("idUserPoint") Long idUserPoint, ModelMap mmap)
{
UserPoint userPoint = userPointService.selectUserPointByIdUserPoint(idUserPoint);
mmap.put("userPoint", userPoint);
List<SysUser> sysUserList = sysUserService.selectUserList(new SysUser());
mmap.put("sysUserList",sysUserList);
return prefix + "/edit";
}
/**
*
*/
@RequiresPermissions("sms:user:edit")
@Log(title = "用户积分", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(UserPoint userPoint)
{
return toAjax(userPointService.updateUserPoint(userPoint));
}
/**
*
*/
@RequiresPermissions("sms:user:remove")
@Log(title = "用户积分", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(userPointService.deleteUserPointByIdUserPoints(ids));
}
}

View File

@ -1,15 +1,27 @@
package com.ruoyi.web.controller.sms;
import com.google.common.base.Preconditions;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.config.ServerConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SmsTaskTbl;
import com.ruoyi.common.core.domain.vo.BatchUpdateSmsVO;
import com.ruoyi.common.core.domain.vo.SmsTaskTblPreSummaryVO;
import com.ruoyi.common.core.domain.vo.SmsTaskTblSummaryVO;
import com.ruoyi.common.core.domain.vo.SmsTaskTblVO;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.file.InvalidExtensionException;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.service.ISmsTaskTblService;
import com.ruoyi.web.controller.sms.converter.SmsTaskTblConverter;
import com.ruoyi.web.controller.sms.converter.SmsTaskTblVOConverter;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
@ -19,39 +31,51 @@ import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
/**
* WSController
*
*
* @author dorion
* @date 2024-06-01
*/
@Controller
@RequestMapping("/sms/task/ws")
public class WSSmsTaskTblController extends BaseController
{
public class WSSmsTaskTblController extends BaseController {
private String prefix = "sms/task/ws";
@Autowired
private ISmsTaskTblService smsTaskTblService;
@Autowired
private ServerConfig serverConfig;
@RequiresPermissions("sms:task:ws:view")
@GetMapping()
public String task()
{
public String task() {
return prefix + "/task";
}
@RequiresPermissions("sms:task:ws:view")
@GetMapping("/summary")
public String taskSummary() {
return prefix + "/taskSummary";
}
/**
* WS
*/
@RequiresPermissions("sms:task:ws:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SmsTaskTbl smsTaskTbl)
{
public TableDataInfo list(SmsTaskTbl smsTaskTbl) {
startPage();
List<SmsTaskTbl> list = smsTaskTblService.selectSmsTaskTblList(smsTaskTbl);
return getDataTable(list);
@ -64,25 +88,31 @@ public class WSSmsTaskTblController extends BaseController
@Log(title = "WS短信任务配置", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SmsTaskTbl smsTaskTbl)
{
public AjaxResult export(SmsTaskTbl smsTaskTbl) {
List<SmsTaskTbl> list = smsTaskTblService.selectSmsTaskTblList(smsTaskTbl);
ExcelUtil<SmsTaskTbl> util = new ExcelUtil<SmsTaskTbl>(SmsTaskTbl.class);
return util.exportExcel(list, "WS短信任务配置数据");
List<SmsTaskTblPreSummaryVO> smsTaskTblPreSummaryVOList = SmsTaskTblConverter.INSTANCE.to(list);
ExcelUtil<SmsTaskTblPreSummaryVO> util = new ExcelUtil<SmsTaskTblPreSummaryVO>(SmsTaskTblPreSummaryVO.class);
return util.exportExcel(smsTaskTblPreSummaryVOList, "WS短信任务配置数据");
}
/**
* WS
*/
@GetMapping("/add")
public String add()
{
public String add() {
return prefix + "/add";
}
/**
* WS
*/
@GetMapping("/addBatch")
public String addBatch() {
return prefix + "/addBatch";
}
@GetMapping("/update/{ids}")
public String update(@PathVariable("ids") String ids, ModelMap mmap)
{
public String update(@PathVariable("ids") String ids, ModelMap mmap) {
mmap.put("ids", ids);
return prefix + "/update";
}
@ -91,8 +121,7 @@ public class WSSmsTaskTblController extends BaseController
@RequiresPermissions("sms:task:ws:edit")
@Log(title = "WS短信任务配置", businessType = BusinessType.UPDATE)
@ResponseBody
public AjaxResult update(BatchUpdateSmsVO batchUpdateSmsVO)
{
public AjaxResult update(BatchUpdateSmsVO batchUpdateSmsVO) {
smsTaskTblService.updateBatchUpdateSmsVO(batchUpdateSmsVO);
return toAjax(1);
}
@ -104,19 +133,191 @@ public class WSSmsTaskTblController extends BaseController
@Log(title = "WS短信任务配置", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(SmsTaskTbl smsTaskTbl)
{
smsTaskTbl.setSmsBusiType("WS");
return toAjax(smsTaskTblService.insertSmsTaskTbl(smsTaskTbl));
@RepeatSubmit
public AjaxResult addSave(@RequestParam("file") MultipartFile file, SmsTaskTbl smsTaskTbl) throws IOException {
String taskName = smsTaskTbl.getTaskName();
Preconditions.checkState(taskName.matches("^[a-zA-Z0-9_]+$"), "任务名称只能是数字,字母和下划线");
String originalFilename = file.getOriginalFilename();
checkFileExtendName(originalFilename);
// 上传文件路径
String filePath = RuoYiConfig.getUploadPath();
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
try (InputStream inputStream = file.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {
MessageDigest md = MessageDigest.getInstance("MD5");
long lineCount = 0;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
String line;
String phoneNumber = null;
while ((line = bufferedReader.readLine()) != null) {
if (StringUtils.isEmpty(phoneNumber)) {
phoneNumber = line;
}
lineCount++;
byte[] lineBytes = line.getBytes();
byteArrayOutputStream.write(lineBytes);
byteArrayOutputStream.write('\n'); // 添加换行符
md.update(lineBytes);
}
byte[] digest = md.digest();
String md5 = bytesToHex(digest);
// String base64 = Base64.getEncoder().encodeToString(smsTaskTbl.getContext().getBytes());
// 设置SmsTaskTbl对象的属性
smsTaskTbl.setSmsBusiType("WS");
smsTaskTbl.setFileMd5(md5);
// smsTaskTbl.setContext(base64);
smsTaskTbl.setFilePath(url);
smsTaskTbl.setFileName(originalFilename);
smsTaskTbl.setTotalCount(lineCount);
smsTaskTbl.setPhoneNumber(phoneNumber);
return toAjax(smsTaskTblService.insertSmsTaskTbl(smsTaskTbl));
} catch (IOException | NoSuchAlgorithmException e) {
throw new RuntimeException("Failed to process file", e);
}
}
private static void checkFileExtendName(String originalFilename) {
String[] split = originalFilename.split(".");
Preconditions.checkState("txt".equals(split[split.length - 1]), "文件格式错误,只支持txt文件上传");
}
private String bytesToHex(byte[] bytes) {
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
/**
* WS
*/
@RequiresPermissions("sms:task:ws:add")
@Log(title = "WS短信任务批量配置", businessType = BusinessType.INSERT)
@PostMapping("/addBatch")
@ResponseBody
@RepeatSubmit
public AjaxResult addBatchSave(@RequestParam("file") MultipartFile file, SmsTaskTblVO smsTaskTblVO) throws IOException, InvalidExtensionException, NoSuchAlgorithmException {
int splitNumber = 0;
splitNumber = smsTaskTblVO.getSplitNumber();
String[] allowedExtension = new String[]{"txt"};
// String baseDir = "/your/upload/directory"; // 上传文件的基础目录
String filePath = RuoYiConfig.getUploadPath();
// 拆分文件并上传
InputStream inputStream = file.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
String placeHolder = smsTaskTblVO.getPlaceHolder();
String context = smsTaskTblVO.getContext();
Preconditions.checkState(context.indexOf(placeHolder) != -1, "文本内容中不存在占位符");
String placeHolderFill = smsTaskTblVO.getPlaceHolderFill();
Preconditions.checkState(StringUtils.isNotEmpty(placeHolderFill), "占位符填充内容不能为空");
String[] split = placeHolderFill.split("\r\n");
Preconditions.checkState(splitNumber > 0, "物料切割数量必须大于0");
Preconditions.checkState(split.length == splitNumber, "占位填充符数量与物料切割数量不一致");
List<String> buffer = new ArrayList<>();
String line;
String phoneNumber = null;
long lineNumber = 0;
while ((line = reader.readLine()) != null) {
buffer.add(line);
if ( StringUtils.isEmpty(phoneNumber)) {
phoneNumber = line;
}
lineNumber++;
}
smsTaskTblVO.setLineCount(lineNumber);
reader.close();
smsTaskTblVO.setPhoneNumber(phoneNumber);
String originalFilename = file.getOriginalFilename();
int totalLines = buffer.size();
int linesPerFile = totalLines / splitNumber;
List<SmsTaskTbl> smsTaskTblList = new ArrayList<>();
for (int i = 0; i < splitNumber; i++) {
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos);
String outputFileName = originalFilename + "_" + (i + 1) + ".txt";
int startLine = i * linesPerFile;
// int endLine = Math.min(startLine + linesPerFile, totalLines);
int endLine = (i == splitNumber - 1) ? totalLines : startLine + linesPerFile;
MessageDigest md = MessageDigest.getInstance("MD5");
long lineCount = 0;
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(pos, StandardCharsets.UTF_8))) {
for (int j = startLine; j < endLine; j++) {
String writeLine = buffer.get(j);
writer.write(writeLine);
writer.newLine();
md.update(writeLine.getBytes());
lineCount++;
}
writer.flush();
} catch (IOException e) {
logger.error("Failed to write file", e);
} finally {
try {
pos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 调用上传方法
String fileName = FileUploadUtils.upload(filePath, outputFileName, pis, allowedExtension);
pis.close();
byte[] digest = md.digest();
String md5 = bytesToHex(digest);
SmsTaskTbl smsTaskTbl = SmsTaskTblVOConverter.INSTANCE.to(smsTaskTblVO);
smsTaskTbl.setFileName(outputFileName);
smsTaskTbl.setTaskName(smsTaskTblVO.getTaskName() + "_" + (i + 1) + "_" + placeHolder);
smsTaskTbl.setContext(smsTaskTblVO.getContext().replaceAll(placeHolder, split[i]));
smsTaskTbl.setFilePath(serverConfig.getUrl() + fileName);
smsTaskTbl.setFileMd5(md5);
smsTaskTbl.setSmsBusiType("WS");
smsTaskTbl.setTotalCount(lineCount);
smsTaskTblList.add(smsTaskTbl);
}
smsTaskTblVO.setSmsTaskTblList(smsTaskTblList);
smsTaskTblService.insertSmsTaskTblBatch(smsTaskTblVO);
return toAjax(split.length);
}
private int countLines(BufferedReader reader) throws IOException {
int lines = 0;
while (reader.readLine() != null) {
lines++;
}
return lines;
}
/**
* WS
*/
@RequiresPermissions("sms:task:ws:edit")
@GetMapping("/edit/{idSmsTask}")
public String edit(@PathVariable("idSmsTask") Long idSmsTask, ModelMap mmap)
{
public String edit(@PathVariable("idSmsTask") Long idSmsTask, ModelMap mmap) {
SmsTaskTbl smsTaskTbl = smsTaskTblService.selectSmsTaskTblByIdSmsTask(idSmsTask);
mmap.put("smsTaskTbl", smsTaskTbl);
return prefix + "/edit";
@ -125,8 +326,7 @@ public class WSSmsTaskTblController extends BaseController
@RequiresPermissions("sms:task:ws:export")
@GetMapping("/exportTaskDetail/{idSmsTask}")
public ResponseEntity<byte[]> exportTaskDetail(@PathVariable("idSmsTask") Long idSmsTask)
{
public ResponseEntity<byte[]> exportTaskDetail(@PathVariable("idSmsTask") Long idSmsTask) {
byte[] report = smsTaskTblService.getReport(idSmsTask);
HttpHeaders headers = new HttpHeaders();
@ -136,6 +336,16 @@ public class WSSmsTaskTblController extends BaseController
return new ResponseEntity<>(report, headers, HttpStatus.OK);
}
@RequiresPermissions("sms:task:ws:export")
@PostMapping("/exportSummaryTaskUrl")
@ResponseBody
public AjaxResult exportSummaryTaskUrl(SmsTaskTbl smsTaskTbl) {
List<SmsTaskTbl> list = smsTaskTblService.selectSmsTaskTblList(smsTaskTbl);
List<SmsTaskTblSummaryVO> smsTaskTblPreSummaryVOList = SmsTaskTblConverter.INSTANCE.toSmsTaskTblSummaryVOList(list);
ExcelUtil<SmsTaskTblSummaryVO> util = new ExcelUtil<SmsTaskTblSummaryVO>(SmsTaskTblSummaryVO.class);
return util.exportExcel(smsTaskTblPreSummaryVOList, "WS短信任务配置数据");
}
/**
* WS
*/
@ -143,8 +353,8 @@ public class WSSmsTaskTblController extends BaseController
@Log(title = "WS短信任务配置", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SmsTaskTbl smsTaskTbl)
{
@RepeatSubmit
public AjaxResult editSave(SmsTaskTbl smsTaskTbl) {
return toAjax(smsTaskTblService.updateSmsTaskTbl(smsTaskTbl));
}
@ -153,17 +363,16 @@ public class WSSmsTaskTblController extends BaseController
*/
@RequiresPermissions("sms:task:ws:remove")
@Log(title = "WS短信任务配置", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
public AjaxResult remove(String ids) {
return toAjax(smsTaskTblService.deleteSmsTaskTblByIdSmsTasks(ids));
}
@RequiresPermissions("sms:task:ws:edit")
@Log(title = "租户", businessType = BusinessType.ACTIVE_DATA)
@PostMapping( "/completeTask")
@PostMapping("/completeTask")
@ResponseBody
public AjaxResult completeTask(String ids) throws Exception {
return toAjax(smsTaskTblService.complete(ids));

View File

@ -0,0 +1,24 @@
package com.ruoyi.web.controller.sms.converter;
import com.ruoyi.common.core.domain.entity.SmsTaskTbl;
import com.ruoyi.common.core.domain.vo.SmsTaskTblPreSummaryVO;
import com.ruoyi.common.core.domain.vo.SmsTaskTblSummaryVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface SmsTaskTblConverter {
SmsTaskTblConverter INSTANCE = Mappers.getMapper(SmsTaskTblConverter.class);
SmsTaskTblPreSummaryVO to(SmsTaskTbl smsTaskTbl);
List<SmsTaskTblPreSummaryVO> to(List<SmsTaskTbl> smsTaskTblList);
SmsTaskTblSummaryVO toSmsTaskTblSummaryVO(SmsTaskTbl smsTaskTbl);
List<SmsTaskTblSummaryVO> toSmsTaskTblSummaryVOList(List<SmsTaskTbl> smsTaskTblList);
}

View File

@ -0,0 +1,19 @@
package com.ruoyi.web.controller.sms.converter;
import com.ruoyi.common.core.domain.entity.SmsTaskTbl;
import com.ruoyi.common.core.domain.vo.SmsTaskTblVO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper
public interface SmsTaskTblVOConverter {
SmsTaskTblVOConverter INSTANCE = Mappers.getMapper(SmsTaskTblVOConverter.class);
@Mapping(target = "fileName",ignore = true)
@Mapping(target = "taskName",ignore = true)
@Mapping(target = "context",ignore = true)
SmsTaskTbl to(SmsTaskTblVO smsTaskTblVO);
}

View File

@ -0,0 +1,18 @@
package com.ruoyi.web.core.config;
import com.ruoyi.common.utils.SnowFlakeUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DefaultConfiguration {
@Value("${snowflake.workerId}")
private long workerId;
@Value("${snowflake.dataCenterId}")
private long dataCenterId;
@Bean
public SnowFlakeUtil getSnowFlakeUtil(){
return new SnowFlakeUtil(dataCenterId,workerId);
}
}

View File

@ -9,7 +9,7 @@ ruoyi:
# 实例演示开关
demoEnabled: true
# 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath
profile: D:/ruoyi/uploadPath
profile: D:/ruoyi/uploadPathr
# 获取ip地址开关
addressEnabled: false
@ -170,4 +170,9 @@ tg:
bot:
name: CnRogerBot
token: 6559243612:AAFOZU6MFq_pX25w71PH874_lVIM2MIhuSE
chatid: -1002058165663
chatid: -1002058165663
snowflake:
dataCenterId: 1
workerId: 1

View File

@ -405,6 +405,28 @@ var table = {
window.location.href = url;
$.modal.closeLoading();
},exportSummaryTaskExcel: function(formId) {
table.set();
$.modal.confirm("确定导出所有" + table.options.modalName + "吗?", function() {
var currentId = $.common.isEmpty(formId) ? $('form').attr('id') : formId;
var params = $("#" + table.options.id).bootstrapTable('getOptions');
var dataParam = $("#" + currentId).serializeArray();
dataParam.push({ "name": "orderByColumn", "value": params.sortName });
dataParam.push({ "name": "isAsc", "value": params.sortOrder });
$.modal.loading("正在导出数据,请稍候...");
$.post(table.options.exportSummaryTaskUrl, dataParam, function(result) {
if (result.code == web_status.SUCCESS) {
window.location.href = ctx + "common/download?fileName=" + encodeURI(result.msg) + "&delete=" + true;
} else if (result.code == web_status.WARNING) {
$.modal.alertWarning(result.msg)
} else {
$.modal.alertError(result.msg);
}
$.modal.closeLoading();
});
});
},completeTask: function(formId) {
table.set();
@ -1200,6 +1222,10 @@ var table = {
table.set();
$.modal.openTab("添加" + table.options.modalName, $.operate.addUrl(id));
},
addBatchTab: function (id) {
table.set();
$.modal.openTab("添加" + table.options.modalName, $.operate.addBatchUrl(id));
},
// 添加信息 全屏
addFull: function(id) {
table.set();
@ -1210,6 +1236,10 @@ var table = {
var url = $.common.isEmpty(id) ? table.options.createUrl.replace("{id}", "") : table.options.createUrl.replace("{id}", id);
return url;
},
addBatchUrl: function(id) {
var url = $.common.isEmpty(id) ? table.options.createBatchUrl.replace("{id}", "") : table.options.createBatchUrl.replace("{id}", id);
return url;
},
// 修改信息
edit: function(id) {
table.set();

View File

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('新增群发国家单价配置')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-country-add">
<div class="form-group">
<label class="col-sm-3 control-label">国家:</label>
<!-- <div class="col-sm-8">
<input name="countryId" class="form-control" type="text">
</div>-->
<div class="col-sm-8">
<!-- <input name="accountAddress" class="form-control" type="text">-->
<select id="countryId" name="countryId" class="form-control " >
<option th:each="country:${countries}" th:value="${country.countryId}" th:text="${country.chineseName}" ></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">单价:</label>
<div class="col-sm-8">
<input name="price" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">备注信息:</label>
<div class="col-sm-8">
<textarea name="remark" class="form-control"></textarea>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "sms/country"
$("#form-country-add").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/add", $('#form-country-add').serialize());
}
}
</script>
</body>
</html>

View File

@ -0,0 +1,144 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('群发国家单价配置列表')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<li>
<label>国家:</label>
<input type="text" name="countryId"/>
</li>
<li class="select-time">
<label>创建时间:</label>
<input type="text" class="time-input" id="startTime" placeholder="开始时间" name="params[beginCreateTime]"/>
<span>-</span>
<input type="text" class="time-input" id="endTime" placeholder="结束时间" name="params[endCreateTime]"/>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="sms:country:add">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="sms:country:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="sms:country:remove">
<i class="fa fa-remove"></i> 删除
</a>
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="sms:country:export">
<i class="fa fa-download"></i> 导出
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('sms:country:edit')}]];
var removeFlag = [[${@permission.hasPermi('sms:country:remove')}]];
var countries = [[${countries}]];
var prefix = ctx + "sms/country";
$(function() {
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
modalName: "群发国家单价配置",
columns: [{
checkbox: true
},
{
field: 'idSmsCountryPrice',
title: '主键',
visible: false
},
{
field: 'countryId',
title: '国家',
formatter: function(value, row, index) {
if ($.common.isEmpty(countries) || $.common.isEmpty(value)) {
return '';
}
var actions = [];
$.each(countries, function(index, dict) {
if (dict.countryId == ('' + value)) {
var listClass = $.common.equals("default", dict.listClass) || $.common.isEmpty(dict.listClass) ? "" : "badge badge-" + dict.listClass;
var cssClass = $.common.isNotEmpty(dict.cssClass) ? dict.cssClass : listClass;
actions.push($.common.sprintf("<span class='%s'>%s</span>", cssClass, dict.chineseName));
return false;
}
});
if (actions.length === 0) {
actions.push($.common.sprintf("<span>%s</span>", value))
}
return actions.join('');
}
},
{
field: 'areaCode',
title: '国家代码',
visible: false
},
{
field: 'price',
title: '单价'
},
{
field: 'createBy',
title: '创建者',
visible: false
},
{
field: 'createTime',
title: '创建时间',
visible: false
},
{
field: 'updateBy',
title: '更新者',
visible: false
},
{
field: 'updateTime',
title: '更新时间',
visible: false
},
{
field: 'remark',
title: '备注信息'
},
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.idSmsCountryPrice + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.idSmsCountryPrice + '\')"><i class="fa fa-remove"></i>删除</a>');
return actions.join('');
}
}]
};
$.table.init(options);
});
</script>
</body>
</html>

View File

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('修改群发国家单价配置')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-country-edit" th:object="${smsCountryPrice}">
<input name="idSmsCountryPrice" th:field="*{idSmsCountryPrice}" type="hidden">
<div class="form-group">
<label class="col-sm-3 control-label">国家:</label>
<div class="col-sm-8">
<!-- <input name="countryId" th:field="*{countryId}" class="form-control" type="text">-->
<select id="countryId" name="countryId" class="form-control " >
<option th:each="country:${countries}" th:value="${country.countryId}" th:text="${country.chineseName}" th:field="*{countryId}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">单价:</label>
<div class="col-sm-8">
<input name="price" th:field="*{price}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">备注信息:</label>
<div class="col-sm-8">
<textarea name="remark" class="form-control">[[*{remark}]]</textarea>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "sms/country";
$("#form-country-edit").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-country-edit').serialize());
}
}
</script>
</body>
</html>

View File

@ -0,0 +1,104 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<th:block th:include="include :: header('新增监听账户入账')"/>
<th:block th:include="include :: jasny-bootstrap-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-monitor-add" enctype="multipart/form-data">
<div class="form-group">
<label class="col-sm-3 control-label">地址别名:</label>
<div class="col-sm-8">
<input name="monitorAddressName" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">监听地址:</label>
<div class="col-sm-8">
<input name="monitorAddress" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="font-noraml col-sm-3 control-label">收款二维码</label>
<div class="col-sm-8">
<div class="fileinput fileinput-new" data-provides="fileinput">
<span class="btn btn-white btn-file"><span class="fileinput-new">选择文件</span><span class="fileinput-exists">重新选择</span><input type="file" id="file" name="file" ></span>
<span class="fileinput-filename"></span>
<a href="javascript:;" class="close fileinput-exists" data-dismiss="fileinput" style="float: none">&times;</a>
</div>
</div>
</div>
<!--<div class="form-group">
<label class="col-sm-3 control-label">通知消息模版:</label>
<div class="col-sm-8">
<select id="idTgMessageInfo" name="idTgMessageInfo" class="form-control " >
<option th:each="topicTgmessageInfo:${topicTgmessageInfoList}" th:value="${topicTgmessageInfo.idTgMessageInfo}" th:text="${topicTgmessageInfo.messageAbbrName}" ></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">绑定群组:</label>
<div class="col-sm-8">
<select name="groupChatId" class="form-control m-b" th:with="type=${@dict.getType('sys_tg_chat_group_info')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</div>
</div>-->
<div class="form-group">
<label class="col-sm-3 control-label">备注:</label>
<div class="col-sm-8">
<input name="comment" class="form-control" type="text">
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer"/>
<th:block th:include="include :: jasny-bootstrap-js" />
<script th:inline="javascript">
var prefix = ctx + "sms/monitor"
$("#form-monitor-add").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
// $.operate.save(prefix + "/add", $('#form-monitor-add').serialize());
uploadFile();
}
}
function uploadFile() {
// var formData = new FormData();
if (!$('#file').val()) {
$.modal.alertWarning("请先选择文件路径");
return false;
}
// formData.append('fileName', $("input[name='fileName']").val());
// formData.append('file', $('#filePath')[0].files[0]);
const form = document.getElementById('form-monitor-add');
const formData = new FormData(form);
$.ajax({
url: prefix + "/add",
type: 'post',
cache: false,
data: formData,
processData: false,
contentType: false,
dataType: "json",
success: function(result) {
$.operate.successCallback(result);
}
});
}
</script>
</body>
</html>

View File

@ -0,0 +1,116 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('修改监听账户入账')" />
<th:block th:include="include :: datetimepicker-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-monitor-edit" th:object="${monitorAddressInfo}">
<input name="idMonitorAddress" th:field="*{idMonitorAddress}" type="hidden">
<div class="form-group">
<label class="col-sm-3 control-label">地址别名:</label>
<div class="col-sm-8">
<input name="monitorAddressName" th:field="*{monitorAddressName}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">监听地址:</label>
<div class="col-sm-8">
<input name="monitorAddress" th:field="*{monitorAddress}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">出账地址:</label>
<div class="col-sm-8">
<!-- <input name="accountAddress" th:field="*{accountAddress}" class="form-control" type="text">-->
<select id="accountAddress" name="accountAddress" class="form-control " >
<option th:each="accountAddressInfo:${accountAddressList}" th:value="${accountAddressInfo.address}" th:text="${accountAddressInfo.address}" th:field="*{accountAddress}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">TRX兑换单价/TRX</label>
<div class="col-sm-8">
<input name="trxPrice" th:field="*{trxPrice}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">USDT兑换单价/USDT</label>
<div class="col-sm-8">
<input name="usdtPrice" th:field="*{usdtPrice}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">是否有效:</label>
<div class="col-sm-8">
<select class="form-control" name="isValid" th:with="type=${@dict.getType('sys_yes_no')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{isValid}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">绑定时长:</label>
<div class="col-sm-8">
<select name="bindPeriod" class="form-control m-b" th:with="type=${@dict.getType('sys_lock_period')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{bindPeriod}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">通知消息模版:</label>
<div class="col-sm-8">
<select id="idTgMessageInfo" name="idTgMessageInfo" class="form-control " >
<option th:each="topicTgmessageInfo:${topicTgmessageInfoList}" th:value="${topicTgmessageInfo.idTgMessageInfo}" th:text="${topicTgmessageInfo.messageAbbrName}" th:field="*{idTgMessageInfo}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">绑定群组:</label>
<div class="col-sm-8">
<select name="groupChatId" class="form-control m-b" th:with="type=${@dict.getType('sys_tg_chat_group_info')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{groupChatId}"></option>
</select>
</div>
</div>
<!-- <div class="form-group">
<label class="col-sm-3 control-label">API_KEY</label>
<div class="col-sm-8">
<select name="apiKey" class="form-control m-b" th:with="type=${@dict.getType('sys_tron_api_key')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{apiKey}"></option>
</select>
</div>
</div>-->
<div class="form-group">
<label class="col-sm-3 control-label">备注:</label>
<div class="col-sm-8">
<input name="comment" th:field="*{comment}" class="form-control" type="text">
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<script th:inline="javascript">
var prefix = ctx + "trx2Energy/monitor";
$("#form-monitor-edit").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-monitor-edit').serialize());
}
}
</script>
</body>
</html>

View File

@ -0,0 +1,200 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('监听账户入账列表')"/>
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<li>
<label>监听地址:</label>
<input type="text" name="monitorAddress"/>
</li>
<li>
<label>是否有效:</label>
<select class="form-control" name="isValid" th:with="type=${@dict.getType('sys_yes_no')}">
<option value="">所有</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}"
th:value="${dict.dictValue}"></option>
</select>
</li>
<li class="select-time">
<label>创建时间:</label>
<input type="text" class="time-input" id="startTime" placeholder="开始时间"
name="params[beginFcd]"/>
<span>-</span>
<input type="text" class="time-input" id="endTime" placeholder="结束时间"
name="params[endFcd]"/>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i
class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i
class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="sms:monitor:add">
<i class="fa fa-plus"></i> 添加
</a>
<!-- <a class="btn btn-primary single disabled" onclick="$.operate.edit()"
shiro:hasPermission="sms:monitor:edit">
<i class="fa fa-edit"></i> 修改
</a>-->
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()"
shiro:hasPermission="sms:monitor:remove">
<i class="fa fa-remove"></i> 删除
</a>
<!--<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="sms:monitor:export">
<i class="fa fa-download"></i> 导出
</a>-->
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer"/>
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('sms:monitor:edit')}]];
var removeFlag = [[${@permission.hasPermi('sms:monitor:remove')}]];
var prefix = ctx + "sms/monitor";
var datas = [[${@dict.getType('sys_yes_no')}]];
var busiTypeDatas = [[${@dict.getType('sys_busi_type')}]];
var bindPeriodDatas = [[${@dict.getType('sys_lock_period')}]];
var groupChatIdDatas = [[${@dict.getType('sys_tg_chat_group_info')}]];
var topicTgmessageInfoList = [[${topicTgmessageInfoList}]];
$(function () {
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
modalName: "监听账户入账",
columns: [{
checkbox: true
},
{
field: 'idMonitorAddress',
title: '主键',
visible: false
},
{
field: 'monitorAddressName',
title: '地址别名'
},
{
field: 'monitorAddress',
title: '监听地址',
formatter: function (value, row, index) {
if (value == null) {
return value;
}
const maskedValue = value.replace(/^(.{6}).*(.{8})$/, '$1***$2');
return "<a href='https://www.oklink.com/zh-hans/trx/address/" + value + "' target='_blank'>" + maskedValue + "</a>";
}
},
{
field: 'trxBalance',
title: 'TRX余额',
formatter: function (value, row, index) {
// 确保值是一个数字
if (!isNaN(value)) {
// 保留两位小数
return parseFloat(value).toFixed(2);
} else {
// 如果值不是数字,直接返回原值
return value;
}
}
},
{
field: 'usdtBalance',
title: 'USDT余额',
formatter: function (value, row, index) {
// 确保值是一个数字
if (!isNaN(value)) {
// 保留两位小数
return parseFloat(value).toFixed(2);
} else {
// 如果值不是数字,直接返回原值
return value;
}
}
}, {
field: 'busiType',
title: '业务类型',
formatter: function (value, row, index) {
return $.table.selectDictLabel(busiTypeDatas, value);
},
visible: false
},
{
field: 'isValid',
title: '是否有效',
formatter: function (value, item, index) {
return $.table.selectDictLabel(datas, item.isValid);
}
}, {
field: 'imageUrl',
title: '收款二维码',
formatter: function(value, row, index) {
/* if (value) {
return '<img src="' + value + '" alt="收款二维码" style="width:300px;height:auto;" onclick=" $.modal.open( \'收款二维码\',this.src)"/>';
}
return '';*/
return $.table.imageView(value, '/profile/avatar');
}
},{
field: 'comment',
title: '备注'
},
{
field: 'fcd',
title: '创建时间',
visible: false
},
{
field: 'fcu',
title: '创建用户',
visible: false
},
{
field: 'lcd',
title: '更新时间',
visible: false
},
{
field: 'lcu',
title: '更新用户',
visible: false
},
{
title: '操作',
align: 'center',
formatter: function (value, row, index) {
var actions = [];
// actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.idMonitorAddress + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.idMonitorAddress + '\')"><i class="fa fa-remove"></i>删除</a>');
return actions.join('');
}
}]
};
$.table.init(options);
});
</script>
</body>
</html>

View File

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('新增群发充值管理')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-point-add">
<div class="form-group">
<label class="col-sm-3 control-label is-required">用户:</label>
<div class="col-sm-8">
<!--<input name="userId" class="form-control" type="text" required>-->
<select id="userId" name="userId" class="form-control " >
<option th:each="user:${sysUserList}" th:value="${user.userId}" th:text="${user.userName}" ></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">充值金额:</label>
<div class="col-sm-8">
<input name="amount" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">支付状态:</label>
<div class="col-sm-8">
<select name="status" class="form-control m-b" th:with="type=${@dict.getType('sys_is_paid')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "sms/point"
$("#form-point-add").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/add", $('#form-point-add').serialize());
}
}
</script>
</body>
</html>

View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('修改群发充值管理')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-point-edit" th:object="${pointRechargeOrder}">
<input name="idPointRechargeOrder" th:field="*{idPointRechargeOrder}" type="hidden">
<div class="form-group">
<label class="col-sm-3 control-label is-required">用户:</label>
<div class="col-sm-8">
<!-- <input name="userId" th:field="*{userId}" class="form-control" type="text" readonly>-->
<select id="userId" name="userId" class="form-control " disabled >
<option th:each="user:${sysUserList}" th:value="${user.userId}" th:text="${user.userName}" th:field="*{userId}" readonly></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">支付状态:</label>
<div class="col-sm-8">
<select name="status" class="form-control m-b" th:with="type=${@dict.getType('sys_is_paid')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{status}"></option>
</select>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "sms/point";
$("#form-point-edit").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-point-edit').serialize());
}
}
</script>
</body>
</html>

View File

@ -0,0 +1,150 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('群发充值管理列表')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<!-- <li>
<label>用户:</label>
<input type="text" name="userId"/>
</li>-->
<li>
<label>充值订单:</label>
<input type="text" name="orderNumber"/>
</li>
<li>
<label>充值金额:</label>
<input type="text" name="amount"/>
</li>
<li>
<label>支付状态:</label>
<select name="status" th:with="type=${@dict.getType('sys_is_paid')}">
<option value="">所有</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</li>
<li class="select-time">
<label>创建时间:</label>
<input type="text" class="time-input" id="startTime" placeholder="开始时间" name="params[beginCreateTime]"/>
<span>-</span>
<input type="text" class="time-input" id="endTime" placeholder="结束时间" name="params[endCreateTime]"/>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="sms:point:add">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="sms:point:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="sms:point:remove">
<i class="fa fa-remove"></i> 删除
</a>
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="sms:point:export">
<i class="fa fa-download"></i> 导出
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('sms:point:edit')}]];
var removeFlag = [[${@permission.hasPermi('sms:point:remove')}]];
var statusDatas = [[${@dict.getType('sys_is_paid')}]];
var sysUserList = [[${sysUserList}]];
var prefix = ctx + "sms/point";
$(function() {
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
modalName: "群发充值管理",
columns: [{
checkbox: true
},
{
field: 'idPointRechargeOrder',
title: '主键',
visible: false
},
{
field: 'userId',
title: '用户',
formatter: function(value, row, index) {
if ($.common.isEmpty(sysUserList) || $.common.isEmpty(value)) {
return '';
}
var actions = [];
$.each(sysUserList, function(index, dict) {
if (dict.userId == ('' + value)) {
var listClass = $.common.equals("default", dict.listClass) || $.common.isEmpty(dict.listClass) ? "" : "badge badge-" + dict.listClass;
var cssClass = $.common.isNotEmpty(dict.cssClass) ? dict.cssClass : listClass;
actions.push($.common.sprintf("<span class='%s'>%s</span>", cssClass, dict.userName));
return false;
}
});
if (actions.length === 0) {
actions.push($.common.sprintf("<span>%s</span>", value))
}
return actions.join('');
}
},
{
field: 'orderNumber',
title: '充值订单'
},
{
field: 'amount',
title: '充值金额'
},
{
field: 'exchangeRate',
title: '兑换汇率',
visible: false
},
{
field: 'points',
title: '兑换积分'
},
{
field: 'status',
title: '支付状态',
formatter: function(value, row, index) {
return $.table.selectDictLabel(statusDatas, value);
}
},
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.idPointRechargeOrder + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.idPointRechargeOrder + '\')"><i class="fa fa-remove"></i>删除</a>');
return actions.join('');
}
}]
};
$.table.init(options);
});
</script>
</body>
</html>

View File

@ -0,0 +1,117 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<th:block th:include="include :: header('新增群发充值管理')" />
<style>
.steps-container {
display: flex;
align-items: center;
justify-content: center;
}
.step {
display: flex;
align-items: center;
margin: 0 20px;
}
.step-number {
background-color: #1c84c6;
color: white;
border-radius: 50%;
width: 30px;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
margin-right: 10px;
}
.step-label {
font-size: 18px;
}
.step-line {
width: 300px;
height: 2px;
background-color: #1c84c6;
}
.step-2 .step-number {
background-color: #d3d3d3; /* 灰色 */
}
.step-2 .step-label {
color: #d3d3d3; /* 灰色 */
}
</style>
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<div class="steps-container">
<!-- 步骤1创建充值订单 -->
<div class="step step-1">
<div class="step-number">1</div>
<div class="step-label">创建充值订单</div>
</div>
<div class="step-line"></div>
<!-- 步骤2充值订单信息 -->
<div class="step step-2">
<div class="step-number">2</div>
<div class="step-label">充值订单信息</div>
</div>
</div>
<br>
<form class="form-horizontal m" id="form-point-add">
<div class="form-group">
<label class="col-sm-3 col-sm-offset-4 control-label">
<span style="font-size: 16px;"><b>💰1 USDT兑换 <span style="color: red ;font-size: 20px" th:text="${@config.getKey('sys.sms.exchange.rate')}">7.2</span> 积分:</b></span>
</label>
</div>
<!-- <div class="form-group">
<label class="col-sm-3 col-sm-offset-3 control-label">
<span style="font-size: 16px">创建充值订单后继续充值。</span>
</label>
</div>-->
<br>
<div class="form-group">
<label class="col-sm-3 control-label">充值金额:</label>
<div class="col-sm-6">
<input name="amount" type="number" class="form-control">
</div>
<div class="col-sm-1" style="padding-top: 7px"><span style="font-size: 16px"><b>USDT</b></span></div>
</div>
<div class="row">
<div class="col-sm-offset-5 col-sm-10">
<button type="button" class="btn btn-sm btn-primary" onclick="submitHandler()"><i class="fa fa-check"></i>保 存</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button type="button" class="btn btn-sm btn-danger" onclick="closeItem()"><i class="fa fa-reply-all"></i>关 闭 </button>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "sms/point"
$("#form-point-add").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.ajax({
type: 'POST',
url: prefix + "/rechargeOrder",
data: $('#form-point-add').serialize(),
success: function(response) {
if (response.success) {
window.location.href = response.newPageUrl; // 跳转到新的页面
} else {
alert(response.message);
}
},
error: function(xhr, status, error) {
// Handle errors here
console.error('Error:', status, error);
}
});
}
}
</script>
</body>
</html>

View File

@ -0,0 +1,142 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<th:block th:include="include :: header('新增群发充值管理')" />
<style>
.steps-container {
display: flex;
align-items: center;
justify-content: center;
}
.step {
display: flex;
align-items: center;
margin: 0 20px;
}
.step-number {
background-color: #1c84c6;
color: white;
border-radius: 50%;
width: 30px;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
margin-right: 10px;
}
.step-label {
font-size: 18px;
}
.step-line {
width: 300px;
height: 2px;
background-color: #1c84c6;
}
.step-2 .step-number {
background-color: #d3d3d3; /* 灰色 */
}
.step-2 .step-label {
color: #d3d3d3; /* 灰色 */
}
.form-group {
margin-bottom: 15px;
}
.info {
font-size: 18px; /* 放大字体 */
margin-bottom: 20px;
}
.amount {
color: red;
font-size: 24px; /* 放大字体 */
}
.highlight {
color: red;
}
.payment-address {
word-wrap: break-word;
font-size: 18px; /* 放大字体 */
}
form {
font-size: 18px; /* 统一放大表单内的字号 */
}
</style>
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<div class="steps-container">
<!-- 步骤1创建充值订单 -->
<div class="step step-1">
<div class="step-number">1</div>
<div class="step-label">创建充值订单</div>
</div>
<div class="step-line"></div>
<!-- 步骤2充值订单信息 -->
<div class="step step-1">
<div class="step-number">2</div>
<div class="step-label">充值订单信息</div>
</div>
</div>
<br>
<form class="form-horizontal m" id="form-point-add">
<div class="form-group">
<label class="col-sm-3 col-sm-offset-4 control-label">
<span style="font-size: 16px;"><b>转账时请仔细确认地址和金额是否跟页面一致!</b></span>
</label>
</div>
<!-- <div class="form-group">
<label class="col-sm-3 col-sm-offset-3 control-label">
<span style="font-size: 16px">创建充值订单后继续充值。</span>
</label>
</div>-->
<br>
<!-- <div class="form-group">
<label class="col-sm-3 control-label">充值金额:</label>
<div class="col-sm-6">
<input name="amount" type="number" class="form-control">
</div>
<div class="col-sm-1" style="padding-top: 7px"><span style="font-size: 16px"><b>USDT</b></span></div>
</div>-->
<div class="form-group">
<label class="col-sm-3 control-label"><b>充值类型:</b></label>
<label class="col-sm-9 " style="padding-top: 7px">
<span>USDT_TRC20</span>
</label>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><b>转账金额:</b></label>
<label class="col-sm-9 " style="padding-top: 7px">
<span class="amount" th:text="${amount}"></span>
</label>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><b>付款地址:</b></label>
<label class="col-sm-9 " style="padding-top: 7px">
<span th:text="${monitorAddress}"></span>
</label>
</div>
<div class="form-group">
<div class="col-sm-12 text-center">
<img th:src="${imageUrl}" width="250px" alt="QR Code">
</div>
</div>
<div class="form-group">
<div class="col-sm-6 col-sm-offset-2">
<ul>
<li>到账金额 <span class="highlight">必须确认为 <span class="amount" th:text="${amount}"></span> USDT</span>,否则充值不成功。</li>
<li>请在 <span class="highlight">60分钟</span> 内完成转账。</li>
<li>交易成功后会自动充值到账。</li>
<li>如因转账金额错误导致的充值失败,客服将在 14:00-15:00 时间段集中核对处理。</li>
</ul>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
</body>
</html>

View File

@ -8,42 +8,33 @@
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-task-add">
<form class="form-horizontal m" id="form-task-addBatch" enctype="multipart/form-data">
<div class="form-group">
<label class="col-sm-3 control-label is-required">任务名称:</label>
<div class="col-sm-8">
<input name="taskName" class="form-control" type="text" required>
</div>
</div>
<!-- <div class="form-group">
<label class="col-sm-3 control-label">单价:</label>
<div class="col-sm-8">
<input name="price" class="form-control" type="text">
</div>
</div>-->
<div class="form-group">
<label class="font-noraml col-sm-3 control-label">物料</label>
<!-- <div class="col-sm-8">
<div class="file-loading" >
<input id="singleFile" name="file" type="file">
</div>
<input type="hidden" name="fileName" id="fileName">
<input type="hidden" name="filePath" id="filePath">
<input type="hidden" name="fileMd5" id="fileMd5">
<input type="hidden" name="context" id="context">
</div>-->
<!-- <div class="col-sm-8">
<input id="filePath" name="filePath" class="form-control " type="file">
</div>-->
<div class="col-sm-8">
<div class="fileinput fileinput-new" data-provides="fileinput">
<span class="btn btn-white btn-file"><span class="fileinput-new">选择文件</span><span class="fileinput-exists">重新选择</span><input type="file" name="..."></span>
<span class="fileinput-filename"></span>
<a href="javascript:;" class="close fileinput-exists" data-dismiss="fileinput" style="float: none">&times;</a>
</div>
<div class="col-sm-8">
<div class="fileinput fileinput-new" data-provides="fileinput">
<span class="btn btn-white btn-file"><span class="fileinput-new">选择文件</span><span class="fileinput-exists">重新选择</span><input type="file" id="file" name="file" ></span>
<span class="fileinput-filename"></span>
<a href="javascript:;" class="close fileinput-exists" data-dismiss="fileinput" style="float: none">&times;</a>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">文本内容:</label>
<div class="col-sm-8">
<textarea name="context" class="form-control" style="height: 100px"></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">任务开始时间:</label>
<div class="col-sm-8">
@ -82,7 +73,6 @@
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<!-- <th:block th:include="include :: bootstrap-fileinput-js" />-->
<th:block th:include="include :: jasny-bootstrap-js" />
<script th:inline="javascript">
var prefix = ctx + "sms/task/ws"
@ -92,52 +82,42 @@
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/add", $('#form-task-add').serialize());
// $.operate.save(prefix + "/add", $('#form-task-add').serialize());
uploadFile();
}
}
function uploadFile() {
// var formData = new FormData();
if (!$('#file').val()) {
$.modal.alertWarning("请先选择文件路径");
return false;
}
// formData.append('fileName', $("input[name='fileName']").val());
// formData.append('file', $('#filePath')[0].files[0]);
const form = document.getElementById('form-task-addBatch');
const formData = new FormData(form);
$.ajax({
url: prefix + "/add",
type: 'post',
cache: false,
data: formData,
processData: false,
contentType: false,
dataType: "json",
success: function(result) {
$.operate.successCallback(result);
}
});
}
$("input[name='taskBeginTime']").datetimepicker({
format: "yyyy-mm-dd hh:ii:ss",
// minView: "second",
autoclose: true
});
$(document).ready(function () {
// 单图上传
$("#singleFile").fileinput({
uploadUrl: ctx + 'common/upload',
maxFileCount: 1,
autoReplace: true
}).on('fileuploaded', function (event, data, previewId, index) {
var rsp = data.response;
$("#filePath").val(rsp.url);
$("#fileName").val(rsp.originalFilename);
$("#fileMd5").val(rsp.fileMd5);
$("#context").val(rsp.context);
// log.info("return url" + rsp.url)
// log.info("reutrn fileName" + rsp.fileName)
// log.info("reutrn newFileName" + rsp.newFileName)
// log.info("return originalFilename" + rsp.originalFilename)
}).on('fileremoved', function (event, id, index) {
$("input[name='" + event.currentTarget.id + "']").val('')
$("#filePath").val('');
$("#fileName").val('');
$("#fileMd5").val('');
$("#context").val('');
}).on('filecleared', function (event, id, index) {
$("input[name='" + event.currentTarget.id + "']").val('')
$("#filePath").val('');
$("#fileName").val('');
$("#fileMd5").val('');
$("#context").val('');
}).on('filedeleted', function (event, vKey, jqXHR, extraData) {
$("input[name='" + event.currentTarget.id + "']").val('')
$("#filePath").val('');
$("#fileName").val('');
$("#fileMd5").val('');
$("#context").val('');
})
});
</script>
</body>
</html>

View File

@ -0,0 +1,143 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('新增WS短信任务配置')" />
<th:block th:include="include :: datetimepicker-css" />
<th:block th:include="include :: jasny-bootstrap-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-task-add" enctype="multipart/form-data">
<div class="form-group">
<label class="col-sm-3 control-label is-required">任务名称:</label>
<div class="col-sm-6">
<input name="taskName" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">占位符:</label>
<div class="col-sm-6">
<textarea name="placeHolder" class="form-control" type="text" required ></textarea>
</div>
</div>
<div class="form-group">
<label class="font-noraml col-sm-3 control-label is-required">物料</label>
<div class="col-sm-6">
<div class="fileinput fileinput-new" data-provides="fileinput">
<span class="btn btn-white btn-file"><span class="fileinput-new">选择文件</span><span class="fileinput-exists">重新选择</span><input type="file" id="file" name="file" ></span>
<span class="fileinput-filename"></span>
<a href="javascript:;" class="close fileinput-exists" data-dismiss="fileinput" style="float: none">&times;</a>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">物料切割数量:</label>
<div class="col-sm-6">
<input name="splitNumber" class="form-control" type="number" required />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">文本内容:</label>
<div class="col-sm-6">
<textarea name="context" class="form-control" style="height: 100px"></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">占位填充符:</label>
<div class="col-sm-6">
<textarea name="placeHolderFill" class="form-control" style="height: 100px" required></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">任务开始时间:</label>
<div class="col-sm-6">
<div class="input-group date">
<input name="taskBeginTime" class="form-control" placeholder="yyyy-MM-dd HH:mm:ss" type="text" required>
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">内容类型:</label>
<div class="col-sm-6">
<select name="smsContentType" class="form-control m-b" th:with="type=${@dict.getType('sys_sms_content_type')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">任务状态:</label>
<div class="col-sm-6">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_sms_task_status')}">
<input type="radio" th:id="${'taskStatus_' + dict.dictCode}" name="taskStatus" th:value="${dict.dictValue}" th:checked="${dict.default}">
<label th:for="${'taskStatus_' + dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
</div>
</form>
<div class="row">
<div class="col-sm-offset-5 col-sm-10">
<button type="button" class="btn btn-sm btn-primary" onclick="submitHandler()"><i class="fa fa-check"></i>保 存</button>&nbsp;
<button type="button" class="btn btn-sm btn-danger" onclick="closeItem()"><i class="fa fa-reply-all"></i>关 闭 </button>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<th:block th:include="include :: jasny-bootstrap-js" />
<script th:inline="javascript">
var prefix = ctx + "sms/task/ws"
$("#form-task-add").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
// $.operate.save(prefix + "/add", $('#form-task-add').serialize());
uploadFile();
}
}
function uploadFile() {
// var formData = new FormData();
if (!$('#file').val()) {
$.modal.alertWarning("请先选择文件路径");
return false;
}
// formData.append('fileName', $("input[name='fileName']").val());
// formData.append('file', $('#filePath')[0].files[0]);
const form = document.getElementById('form-task-add');
const formData = new FormData(form);
$.ajax({
url: prefix + "/addBatch",
type: 'post',
cache: false,
data: formData,
processData: false,
contentType: false,
dataType: "json",
success: function(result) {
$.operate.successCallback(result);
}
});
}
$("input[name='taskBeginTime']").datetimepicker({
format: "yyyy-mm-dd hh:ii:ss",
// minView: "second",
autoclose: true
});
</script>
</body>
</html>

View File

@ -14,18 +14,16 @@
<input name="taskName" th:field="*{taskName}" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">短信类型</label>
<div class="form-group">
<label class="col-sm-3 control-label">物料名称</label>
<div class="col-sm-8">
<select name="smsBusiType" class="form-control m-b" th:with="type=${@dict.getType('sys_sms_busi_type')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{smsBusiType}"></option>
</select>
<input name="fileName" th:field="*{fileName}" class="form-control" type="text" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">单价:</label>
<div class="form-group">
<label class="col-sm-3 control-label">文本内容</label>
<div class="col-sm-8">
<input name="price" th:field="*{price}" class="form-control" type="text">
<textarea name="context" class="form-control" style="height: 200px" >[[*{context}]]</textarea>
</div>
</div>
<div class="form-group">
@ -45,7 +43,7 @@
</select>
</div>
</div>
<div class="form-group">
<!-- <div class="form-group">
<label class="col-sm-3 control-label">任务状态:</label>
<div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_sms_task_status')}">
@ -53,19 +51,8 @@
<label th:for="${'taskStatus_' + dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">成功数:</label>
<div class="col-sm-8">
<input name="successRate" th:field="*{successRate}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">物料总数:</label>
<div class="col-sm-8">
<input name="issueCount" th:field="*{issueCount}" class="form-control" type="text">
</div>
</div>
</div>-->
</form>
</div>
<th:block th:include="include :: footer" />

View File

@ -40,6 +40,9 @@
<a class="btn btn-success" onclick="$.operate.addTab()" shiro:hasPermission="sms:task:ws:add">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-success" onclick="$.operate.addBatchTab()" shiro:hasPermission="sms:task:ws:add">
<i class="fa fa-plus"></i> 批量添加
</a>
<a class="btn btn-primary multiple disabled" onclick="$.operate.editStatus()" shiro:hasPermission="sms:task:ws:edit">
<i class="fa fa-edit"></i> 批量修改
</a>
@ -49,9 +52,9 @@
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="sms:task:ws:export">
<i class="fa fa-download"></i> 导出
</a>
<a class="btn btn-warning single disabled" onclick="$.table.exportExcelTaskDetail()" shiro:hasPermission="sms:task:ws:export">
<!-- <a class="btn btn-warning single disabled" onclick="$.table.exportExcelTaskDetail()" shiro:hasPermission="sms:task:ws:export">
<i class="fa fa-edit"></i> 下载任务明细
</a>
</a>-->
<a class="btn btn-danger multiple disabled" onclick="$.table.completeTask()" shiro:hasPermission="sms:task:ws:export">
<i class="fa fa-edit"></i> 强制完成
</a>
@ -74,6 +77,7 @@
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
createBatchUrl: prefix + "/addBatch",
updateUrl: prefix + "/edit/{id}",
updateStatusUrl: prefix + "/update/{ids}",
removeUrl: prefix + "/remove",
@ -96,15 +100,15 @@
{
field: 'totalCount',
title: '总量'
},{
},/*,{
field: 'successCount',
title: '成功个数'
},{
},*/{
field: 'preSummary',
title: '预估金额'
},
},/*,
{
field: 'smsBusiType',
title: '短信类型',
@ -112,7 +116,7 @@
return $.table.selectDictLabel(smsBusiTypeDatas, value);
},
visible: false
},
}*/
{
field: 'price',
title: '单价'
@ -130,11 +134,11 @@
title: '物料名称',
visible: false
},
{
/* {
field: 'filePath',
title: '物料文件下载地址',
visible: false
},
},*/
{
field: 'smsContentType',
title: '内容类型',
@ -150,16 +154,16 @@
return $.table.selectDictLabel(taskStatusDatas, value);
}
},
{
/*{
field: 'successRate',
title: '成功率',
visible: false
},
},*/
{
/* {
field: 'issueCount',
title: '物料总数'
},
},*/
{
field: 'createBy',
title: '创建者',

View File

@ -0,0 +1,208 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('WS短信任务配置列表')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<li>
<label>任务名称:</label>
<input type="text" name="taskName"/>
</li>
<li>
<label>任务状态:</label>
<select name="taskStatus" th:with="type=${@dict.getType('sys_sms_task_status')}">
<option value="">所有</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</li>
<li class="select-time">
<label>创建时间:</label>
<input type="text" class="time-input" id="startTime" placeholder="开始时间" name="params[beginCreateTime]"/>
<span>-</span>
<input type="text" class="time-input" id="endTime" placeholder="结束时间" name="params[endCreateTime]"/>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<!-- <a class="btn btn-success" onclick="$.operate.addTab()" shiro:hasPermission="sms:task:ws:add">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-success" onclick="$.operate.addBatchTab()" shiro:hasPermission="sms:task:ws:add">
<i class="fa fa-plus"></i> 批量添加
</a>
<a class="btn btn-primary multiple disabled" onclick="$.operate.editStatus()" shiro:hasPermission="sms:task:ws:edit">
<i class="fa fa-edit"></i> 批量修改
</a>-->
<!-- <a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="sms:task:ws:remove">
<i class="fa fa-remove"></i> 删除
</a>-->
<a class="btn btn-warning" onclick="$.table.exportSummaryTaskExcel()" shiro:hasPermission="sms:task:ws:export">
<i class="fa fa-download"></i> 导出
</a>
<a class="btn btn-warning single disabled" onclick="$.table.exportExcelTaskDetail()" shiro:hasPermission="sms:task:ws:export">
<i class="fa fa-edit"></i> 下载任务明细
</a>
<!-- <a class="btn btn-danger multiple disabled" onclick="$.table.completeTask()" shiro:hasPermission="sms:task:ws:export">
<i class="fa fa-edit"></i> 强制完成
</a>-->
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('sms:task:ws:edit')}]];
var removeFlag = [[${@permission.hasPermi('sms:task:ws:remove')}]];
var smsBusiTypeDatas = [[${@dict.getType('sys_sms_busi_type')}]];
var smsContentTypeDatas = [[${@dict.getType('sys_sms_content_type')}]];
var taskStatusDatas = [[${@dict.getType('sys_sms_task_status')}]];
var taskSettleStatusDatas = [[${@dict.getType('sys_sms_task_settle_status')}]];
var prefix = ctx + "sms/task/ws";
$(function() {
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
createBatchUrl: prefix + "/addBatch",
updateUrl: prefix + "/edit/{id}",
updateStatusUrl: prefix + "/update/{ids}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
exportTaskDetailUrl: prefix + "/exportTaskDetail/{id}",
exportSummaryTaskUrl: prefix + "/exportSummaryTaskUrl",
completeTaskUrl: prefix + "/completeTask",
modalName: "WS短信任务配置",
columns: [{
checkbox: true
},
{
field: 'idSmsTask',
title: '主键',
visible: false
},
{
field: 'taskName',
title: '任务名称'
}, {
field: 'country',
title: '所属国家'
},
{
field: 'totalCount',
title: '总量'
},{
field: 'successCount',
title: '成功个数'
},/*,
{
field: 'smsBusiType',
title: '短信类型',
formatter: function(value, row, index) {
return $.table.selectDictLabel(smsBusiTypeDatas, value);
},
visible: false
}*/
{
field: 'price',
title: '单价'
},
{
field: 'taskBeginTime',
title: '任务开始时间'
},
{
field: 'completeTime',
title: '任务完成时间'
},
{
field: 'fileName',
title: '物料名称',
visible: false
},
/* {
field: 'filePath',
title: '物料文件下载地址',
visible: false
},*/
{
field: 'smsContentType',
title: '内容类型',
formatter: function(value, row, index) {
return $.table.selectDictLabel(smsContentTypeDatas, value);
},
visible: false
},
{
field: 'taskStatus',
title: '任务状态',
formatter: function(value, row, index) {
return $.table.selectDictLabel(taskStatusDatas, value);
}
}, {
field: 'settleStatus',
title: '结算状态',
formatter: function(value, row, index) {
return $.table.selectDictLabel(taskSettleStatusDatas, value);
}
},
/*{
field: 'successRate',
title: '成功率',
visible: false
},*/
/* {
field: 'issueCount',
title: '物料总数'
},*/
{
field: 'createBy',
title: '创建者',
visible: false
},
{
field: 'createTime',
title: '创建时间'
},
{
field: 'updateBy',
title: '更新者',
visible: false
},
{
field: 'updateTime',
title: '更新时间',
visible: false
},
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.idSmsTask + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.idSmsTask + '\')"><i class="fa fa-remove"></i>删除</a>');
return actions.join('');
}
}]
};
$.table.init(options);
});
</script>
</body>
</html>

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('新增用户积分')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-user-add">
<div class="form-group">
<label class="col-sm-3 control-label">用户:</label>
<div class="col-sm-8">
<!-- <input name="userId" class="form-control" type="text">-->
<select id="userId" name="userId" class="form-control " >
<option th:each="user:${sysUserList}" th:value="${user.userId}" th:text="${user.userName}" ></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">剩余积分:</label>
<div class="col-sm-8">
<input name="pointBalance" class="form-control" type="text">
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "sms/user"
$("#form-user-add").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/add", $('#form-user-add').serialize());
}
}
</script>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('修改用户积分')" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-user-edit" th:object="${userPoint}">
<input name="idUserPoint" th:field="*{idUserPoint}" type="hidden">
<div class="form-group">
<label class="col-sm-3 control-label">用户:</label>
<div class="col-sm-8">
<!-- <input name="userId" th:field="*{userId}" class="form-control" type="text">-->
<select id="userId" name="userId" class="form-control " disabled >
<option th:each="user:${sysUserList}" th:value="${user.userId}" th:text="${user.userName}" th:field="*{userId}" readonly></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">剩余积分:</label>
<div class="col-sm-8">
<input name="pointBalance" th:field="*{pointBalance}" class="form-control" type="text">
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "sms/user";
$("#form-user-edit").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-user-edit').serialize());
}
}
</script>
</body>
</html>

View File

@ -0,0 +1,110 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('用户积分列表')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<li>
<label>用户:</label>
<input type="text" name="userId"/>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="sms:user:add">
<i class="fa fa-plus"></i> 添加
</a>
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="sms:user:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="sms:user:remove">
<i class="fa fa-remove"></i> 删除
</a>
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="sms:user:export">
<i class="fa fa-download"></i> 导出
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('sms:user:edit')}]];
var removeFlag = [[${@permission.hasPermi('sms:user:remove')}]];
var sysUserList = [[${sysUserList}]];
var prefix = ctx + "sms/user";
$(function() {
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
modalName: "用户积分",
columns: [{
checkbox: true
},
{
field: 'idUserPoint',
title: '主键',
visible: false
},
{
field: 'userId',
title: '用户',
formatter: function(value, row, index) {
if ($.common.isEmpty(sysUserList) || $.common.isEmpty(value)) {
return '';
}
var actions = [];
$.each(sysUserList, function(index, dict) {
if (dict.userId == ('' + value)) {
var listClass = $.common.equals("default", dict.listClass) || $.common.isEmpty(dict.listClass) ? "" : "badge badge-" + dict.listClass;
var cssClass = $.common.isNotEmpty(dict.cssClass) ? dict.cssClass : listClass;
actions.push($.common.sprintf("<span class='%s'>%s</span>", cssClass, dict.userName));
return false;
}
});
if (actions.length === 0) {
actions.push($.common.sprintf("<span>%s</span>", value))
}
return actions.join('');
}
},
{
field: 'pointBalance',
title: '剩余积分'
},
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.idUserPoint + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.idUserPoint + '\')"><i class="fa fa-remove"></i>删除</a>');
return actions.join('');
}
}]
};
$.table.init(options);
});
</script>
</body>
</html>

View File

@ -0,0 +1,40 @@
package com.ruoyi.common.core.domain.entity;
import lombok.Data;
import java.io.Serializable;
@Data
public class CountryTbl implements Serializable {
/**
*
*/
private Integer countryId;
/**
*
*/
private String englishName;
/**
*
*/
private String chineseName;
/**
*
*/
private String twoDigitAbbr;
/**
*
*/
private String threeDigitAbbr;
/**
*
*/
private Integer areaCode;
private static final long serialVersionUID = 1L;
}

View File

@ -75,6 +75,10 @@ public class MonitorAddressInfo extends BaseEntity
@Excel(name = "备注")
private String comment;
/** 二维码收款图片 */
@Excel(name = "二维码收款图片")
private String imageUrl;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")

View File

@ -0,0 +1,127 @@
package com.ruoyi.common.core.domain.entity;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.math.BigDecimal;
/**
* point_recharge_order
*
* @author dorion
* @date 2024-07-21
*/
public class PointRechargeOrder extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键 */
private Long idPointRechargeOrder;
/** 用户 */
@Excel(name = "用户")
private Long userId;
/** 充值订单 */
@Excel(name = "充值订单")
private String orderNumber;
/** 充值金额 */
@Excel(name = "充值金额")
private BigDecimal amount;
/** 兑换汇率 */
@Excel(name = "兑换汇率")
private BigDecimal exchangeRate;
/** 兑换积分 */
@Excel(name = "兑换积分")
private BigDecimal points;
/** 支付状态 */
@Excel(name = "支付状态")
private String status;
public void setIdPointRechargeOrder(Long idPointRechargeOrder)
{
this.idPointRechargeOrder = idPointRechargeOrder;
}
public Long getIdPointRechargeOrder()
{
return idPointRechargeOrder;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public Long getUserId()
{
return userId;
}
public void setOrderNumber(String orderNumber)
{
this.orderNumber = orderNumber;
}
public String getOrderNumber()
{
return orderNumber;
}
public void setAmount(BigDecimal amount)
{
this.amount = amount;
}
public BigDecimal getAmount()
{
return amount;
}
public void setExchangeRate(BigDecimal exchangeRate)
{
this.exchangeRate = exchangeRate;
}
public BigDecimal getExchangeRate()
{
return exchangeRate;
}
public void setPoints(BigDecimal points)
{
this.points = points;
}
public BigDecimal getPoints()
{
return points;
}
public void setStatus(String status)
{
this.status = status;
}
public String getStatus()
{
return status;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("idPointRechargeOrder", getIdPointRechargeOrder())
.append("userId", getUserId())
.append("orderNumber", getOrderNumber())
.append("amount", getAmount())
.append("exchangeRate", getExchangeRate())
.append("points", getPoints())
.append("status", getStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

View File

@ -0,0 +1,86 @@
package com.ruoyi.common.core.domain.entity;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.math.BigDecimal;
/**
* sms_country_price
*
* @author dorion
* @date 2024-07-21
*/
public class SmsCountryPrice extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键 */
private Long idSmsCountryPrice;
/** 国家 */
@Excel(name = "国家")
private Long countryId;
/** 国家代码 */
@Excel(name = "国家代码")
private String areaCode;
/** 单价 */
@Excel(name = "单价")
private BigDecimal price;
public void setIdSmsCountryPrice(Long idSmsCountryPrice)
{
this.idSmsCountryPrice = idSmsCountryPrice;
}
public Long getIdSmsCountryPrice()
{
return idSmsCountryPrice;
}
public void setCountryId(Long countryId)
{
this.countryId = countryId;
}
public Long getCountryId()
{
return countryId;
}
public void setAreaCode(String areaCode)
{
this.areaCode = areaCode;
}
public String getAreaCode()
{
return areaCode;
}
public void setPrice(BigDecimal price)
{
this.price = price;
}
public BigDecimal getPrice()
{
return price;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("idSmsCountryPrice", getIdSmsCountryPrice())
.append("countryId", getCountryId())
.append("areaCode", getAreaCode())
.append("price", getPrice())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

View File

@ -38,6 +38,10 @@ public class SmsTaskTbl extends BaseEntity
@Excel(name = "渠道id")
private String channelId;
/** 所属国家 */
@Excel(name = "所属国家")
private String country;
/** 单价 */
@Excel(name = "单价")
private BigDecimal price;
@ -45,6 +49,9 @@ public class SmsTaskTbl extends BaseEntity
/** 预估金额 */
@Excel(name = "预估金额")
private BigDecimal preSummary;
/** 实扣 */
@Excel(name = "实扣")
private BigDecimal actSummary;
/** 任务开始时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ -100,6 +107,46 @@ public class SmsTaskTbl extends BaseEntity
@Excel(name = "用户id")
private String userId;
/** 结算状态 */
@Excel(name = "结算状态")
private String settleStatus;
private String phoneNumber;
public BigDecimal getActSummary() {
return actSummary;
}
public void setActSummary(BigDecimal actSummary) {
this.actSummary = actSummary;
}
public String getSettleStatus() {
return settleStatus;
}
public void setSettleStatus(String settleStatus) {
this.settleStatus = settleStatus;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public void setIdSmsTask(Long idSmsTask)
{
this.idSmsTask = idSmsTask;

View File

@ -0,0 +1,71 @@
package com.ruoyi.common.core.domain.entity;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.math.BigDecimal;
/**
* user_point
*
* @author dorion
* @date 2024-07-21
*/
public class UserPoint extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键 */
private Long idUserPoint;
/** 用户 */
@Excel(name = "用户")
private Long userId;
/** 剩余积分 */
@Excel(name = "剩余积分")
private BigDecimal pointBalance;
public void setIdUserPoint(Long idUserPoint)
{
this.idUserPoint = idUserPoint;
}
public Long getIdUserPoint()
{
return idUserPoint;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public Long getUserId()
{
return userId;
}
public void setPointBalance(BigDecimal pointBalance)
{
this.pointBalance = pointBalance;
}
public BigDecimal getPointBalance()
{
return pointBalance;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("idUserPoint", getIdUserPoint())
.append("userId", getUserId())
.append("pointBalance", getPointBalance())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

View File

@ -0,0 +1,80 @@
package com.ruoyi.common.core.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* WS sms_task_tbl
*
* @author dorion
* @date 2024-07-04
*/
@Data
public class SmsTaskTblPreSummaryVO implements Serializable
{
private static final long serialVersionUID = 1L;
/** 主键 */
private Long idSmsTask;
/** 任务名称 */
@Excel(name = "任务名称")
private String taskName;
/** 所属国家 */
@Excel(name = "所属国家")
private String country;
/** 单价 */
@Excel(name = "单价")
private BigDecimal price;
/** 预估金额 */
@Excel(name = "预估金额")
private BigDecimal preSummary;
/** 任务开始时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "任务开始时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date taskBeginTime;
/** 任务完成时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "任务完成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date completeTime;
/** 物料名称 */
@Excel(name = "物料名称")
private String fileName;
/** 任务状态 */
@Excel(name = "任务状态",dictType = "sys_sms_task_status")
private String taskStatus;
/** 总数 */
@Excel(name = "总量")
private Long totalCount;
/** 创建者 */
private String createBy;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 更新者 */
private String updateBy;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}

View File

@ -0,0 +1,87 @@
package com.ruoyi.common.core.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* WS sms_task_tbl
*
* @author dorion
* @date 2024-07-04
*/
@Data
public class SmsTaskTblSummaryVO implements Serializable
{
private static final long serialVersionUID = 1L;
/** 主键 */
private Long idSmsTask;
/** 任务名称 */
@Excel(name = "任务名称")
private String taskName;
/** 所属国家 */
@Excel(name = "所属国家")
private String country;
/** 单价 */
@Excel(name = "单价")
private BigDecimal price;
/** 预估金额 */
@Excel(name = "实收金额")
private BigDecimal actSummary;
/** 任务开始时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "任务开始时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date taskBeginTime;
/** 任务完成时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "任务完成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date completeTime;
/** 物料名称 */
@Excel(name = "物料名称")
private String fileName;
/** 任务状态 */
@Excel(name = "任务状态",dictType = "sys_sms_task_status")
private String taskStatus;
/** 总数 */
@Excel(name = "总量")
private Long totalCount;
/** 成功数 */
@Excel(name = "成功数")
private Long successCount;
/** 结算状态 */
@Excel(name = "结算状态",dictType = "sys_sms_task_settle_status")
private String settleStatus;
/** 创建者 */
private String createBy;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 更新者 */
private String updateBy;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}

View File

@ -0,0 +1,84 @@
package com.ruoyi.common.core.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.core.domain.entity.SmsTaskTbl;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* WS sms_task_tbl
*
* @author dorion
* @date 2024-07-04
*/
@Data
public class SmsTaskTblVO implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
private String taskName;
/**
*
*/
private String placeHolder;
/**
*
*/
private Integer splitNumber;
/**
*
*/
private String context;
/**
*
*/
private String placeHolderFill;
/**
*
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date taskBeginTime;
/**
*
*/
private String smsContentType;
/**
*
*/
private String taskStatus;
/**
* ,
*/
private String phoneNumber;
/**
*
*/
private String fileName;
private List<SmsTaskTbl> smsTaskTblList;
private long lineCount ;
}

View File

@ -0,0 +1,200 @@
package com.ruoyi.common.utils;
import org.springframework.beans.factory.annotation.Value;
import java.util.Date;
/**
* @ClassName: SnowFlakeUtil
* @Author: jiaoxian
* @Date: 2022/4/24 16:34
* @Description:
*/
public class SnowFlakeUtil {
// private static SnowFlakeUtil snowFlakeUtil;
// static {
// snowFlakeUtil = new SnowFlakeUtil();
// }
// 初始时间戳(纪年),可用雪花算法服务上线时间戳的值
// 1691903735000L2023-08-13 13:15:35
private static final long INIT_EPOCH = 1691903735000L;
// 时间位取&
private static final long TIME_BIT = 0b1111111111111111111111111111111111111111110000000000000000000000L;
// 记录最后使用的毫秒时间戳,主要用于判断是否同一毫秒,以及用于服务器时钟回拨判断
private long lastTimeMillis = -1L;
// dataCenterId占用的位数
private static final long DATA_CENTER_ID_BITS = 5L;
// dataCenterId占用5个比特位最大值31
// 0000000000000000000000000000000000000000000000000000000000011111
private static final long MAX_DATA_CENTER_ID = ~(-1L << DATA_CENTER_ID_BITS);
// dataCenterId
private long dataCenterId;
// workId占用的位数
private static final long WORKER_ID_BITS = 5L;
// workId占用5个比特位最大值31
// 0000000000000000000000000000000000000000000000000000000000011111
private static final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS);
// workId
@Value("${snowflake.workerId}")
private long workerId;
// 最后12位代表每毫秒内可产生最大序列号即 2^12 - 1 = 4095
private static final long SEQUENCE_BITS = 12L;
// 掩码最低12位为1高位都为0主要用于与自增后的序列号进行位与如果值为0则代表自增后的序列号超过了4095
// 0000000000000000000000000000000000000000000000000000111111111111
private static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS);
// 同一毫秒内的最新序号,最大值可为 2^12 - 1 = 4095
private long sequence;
// workId位需要左移的位数 12
private static final long WORK_ID_SHIFT = SEQUENCE_BITS;
// dataCenterId位需要左移的位数 12+5
private static final long DATA_CENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
// 时间戳需要左移的位数 12+5+5
private static final long TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATA_CENTER_ID_BITS;
/**
*
*/
// public SnowFlakeUtil() {
// this(1, 1);
// }
/**
*
*
* @param dataCenterId
* @param workerId
*/
public SnowFlakeUtil(long dataCenterId, long workerId) {
// 检查dataCenterId的合法值
if (dataCenterId < 0 || dataCenterId > MAX_DATA_CENTER_ID) {
throw new IllegalArgumentException(
String.format("dataCenterId 值必须大于 0 并且小于 %d", MAX_DATA_CENTER_ID));
}
// 检查workId的合法值
if (workerId < 0 || workerId > MAX_WORKER_ID) {
throw new IllegalArgumentException(String.format("workId 值必须大于 0 并且小于 %d", MAX_WORKER_ID));
}
this.workerId = workerId;
this.dataCenterId = dataCenterId;
}
/**
* ID
*
* @return
*/
// public static Long getSnowFlakeId() {
// return nextId();
// }
/**
* id使synchronized
*
* @return id
*/
public synchronized long nextId() {
long currentTimeMillis = System.currentTimeMillis();
// System.out.println(currentTimeMillis);
// 当前时间小于上一次生成id使用的时间可能出现服务器时钟回拨问题
if (currentTimeMillis < lastTimeMillis) {
throw new RuntimeException(
String.format("可能出现服务器时钟回拨问题,请检查服务器时间。当前服务器时间戳:%d上一次使用时间戳%d", currentTimeMillis,
lastTimeMillis));
}
if (currentTimeMillis == lastTimeMillis) {
// 还是在同一毫秒内则将序列号递增1序列号最大值为4095
// 序列号的最大值是4095使用掩码最低12位为1高位都为0进行位与运行后如果值为0则自增后的序列号超过了4095
// 那么就使用新的时间戳
sequence = (sequence + 1) & SEQUENCE_MASK;
if (sequence == 0) {
currentTimeMillis = getNextMillis(lastTimeMillis);
}
} else { // 不在同一毫秒内则序列号重新从0开始序列号最大值为4095
sequence = 0;
}
// 记录最后一次使用的毫秒时间戳
lastTimeMillis = currentTimeMillis;
// 核心算法,将不同部分的数值移动到指定的位置,然后进行或运行
// <<:左移运算符, 1 << 2 即将二进制的 1 扩大 2^2 倍
// |:位或运算符, 是把某两个数中, 只要其中一个的某一位为1, 则结果的该位就为1
// 优先级:<< > |
return
// 时间戳部分
((currentTimeMillis - INIT_EPOCH) << TIMESTAMP_SHIFT)
// 数据中心部分
| (dataCenterId << DATA_CENTER_ID_SHIFT)
// 机器表示部分
| (workerId << WORK_ID_SHIFT)
// 序列号部分
| sequence;
}
/**
*
*
* @param lastTimeMillis
* @return
*/
private long getNextMillis(long lastTimeMillis) {
long currentTimeMillis = System.currentTimeMillis();
while (currentTimeMillis <= lastTimeMillis) {
currentTimeMillis = System.currentTimeMillis();
}
return currentTimeMillis;
}
/**
* ,length=13
*
* @return
*/
// public static String getRandomStr() {
// return Long.toString(getSnowFlakeId(), Character.MAX_RADIX);
// }
/**
* ID
*
* @param id ID
* @return
*/
public static Date getTimeBySnowFlakeId(long id) {
return new Date(((TIME_BIT & id) >> 22) + INIT_EPOCH);
}
// public static void main(String[] args) {
// SnowFlakeUtil snowFlakeUtil = new SnowFlakeUtil();
// long id = snowFlakeUtil.nextId();
// System.out.println("id:"+id);
// Date date = SnowFlakeUtil.getTimeBySnowFlakeId(id);
// System.out.println(date);
// long time = date.getTime();
// System.out.println(time);
// System.out.println(getRandomStr());
//
// }
}

View File

@ -1,11 +1,5 @@
package com.ruoyi.common.utils.file;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Objects;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.file.FileNameLengthLimitExceededException;
@ -14,6 +8,16 @@ import com.ruoyi.common.exception.file.InvalidExtensionException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.Seq;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Objects;
/**
*
@ -47,6 +51,9 @@ public class FileUploadUtils
return defaultBaseDir;
}
/**
*
*
@ -117,6 +124,32 @@ public class FileUploadUtils
return getPathFileName(baseDir, fileName);
}
// 上传文件方法
public static final String upload(String baseDir, String fileName, InputStream inputStream, String[] allowedExtension)
throws IOException, FileNameLengthLimitExceededException, InvalidExtensionException {
int fileNameLength = Objects.requireNonNull(fileName).length();
if (fileNameLength > DEFAULT_FILE_NAME_LENGTH) {
throw new FileNameLengthLimitExceededException(DEFAULT_FILE_NAME_LENGTH);
}
assertAllowed(fileName, allowedExtension);
fileName = extractFilename(fileName);
String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
try (OutputStream outputStream = Files.newOutputStream(Paths.get(absPath))) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
return getPathFileName(baseDir, fileName);
}
/**
*
*/
@ -125,6 +158,15 @@ public class FileUploadUtils
return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file));
}
/**
*
*/
public static final String extractFilename( String originalFilename)
{
return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
FilenameUtils.getBaseName(originalFilename), Seq.getId(Seq.uploadSeqType),FilenameUtils.getExtension(originalFilename));
}
public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
{
@ -147,6 +189,18 @@ public class FileUploadUtils
return Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
}
private static void assertAllowed(String fileName, String[] allowedExtension) throws InvalidExtensionException {
// 检查文件扩展名是否在允许的扩展名列表中
String fileExtension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
for (String ext : allowedExtension) {
if (fileExtension.equals(ext.toLowerCase())) {
return;
}
}
throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, fileExtension,
fileName);
}
/**
*
*

View File

@ -79,6 +79,9 @@ public class MonitorAddressInfoVO
@Excel(name = "备注")
private String comment;
@Excel(name = "二维码收款图片")
private String imageUrl;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")

View File

@ -1,6 +1,7 @@
package com.ruoyi.system.handler;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.ruoyi.common.core.domain.entity.ErrorLog;
@ -54,13 +55,14 @@ public class EnergyTenantTransferHandler {
if (tenantInfo.getEnergyBusiType().equals(eneryBusiTypeByDay)) {
Long period = tenantInfo.getPeriod();
long between = DateUtil.between(tenantInfo.getFcd(), new Date(), DateUnit.DAY);
Long delegatedDays = tenantInfo.getDelegatedDays();
// long between = DateUtil.between(tenantInfo.getFcd(), new Date(), DateUnit.DAY);
TrxExchangeInfo trxExchangeInfo = buildTrxExchangeInfo(tenantInfo, eneryBusiTypeByDay);
List<TrxExchangeMonitorAccountInfo> trxExchangeMonitorAccountInfoList = trxExchangeInfoMapper.selectTrxExchangeMonitorAccountInfo(trxExchangeInfo);
if (between + 1 > period) {
if (delegatedDays + 1 > period) {
String apiKey = DictUtils.getRandomDictValue("sys_tron_api_key");
@ -73,7 +75,7 @@ public class EnergyTenantTransferHandler {
}
//满期不继续处理
tenantInfo.setDelegatedDays(between);
// tenantInfo.setDelegatedDays(delegatedDays);
String delegateStatus = DictUtils.getDictValue("sys_delegate_status", "已满期");
tenantInfo.setStatus(delegateStatus);
tenantInfo.setLcu("system");
@ -137,6 +139,13 @@ public class EnergyTenantTransferHandler {
}
public static void main(String[] args) {
DateTime parse = DateUtil.parse("2024-06-20 01:59:31", "yyyy-MM-dd HH:mm:ss");
long between = DateUtil.between(parse, new Date(), DateUnit.DAY);
System.out.println(between);
}
private static TrxExchangeInfo buildTrxExchangeInfo(TenantInfo tenantInfo, String eneryBusiTypeByDay) {
String delegateStatus = DictUtils.getDictValue("sys_delegate_status", "已委托");

View File

@ -3,6 +3,7 @@ package com.ruoyi.system.handler;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.core.domain.entity.SmsTaskTbl;
import com.ruoyi.common.core.domain.entity.UserPoint;
import com.ruoyi.system.api.IU02cxApi;
import com.ruoyi.system.api.entity.U02cx.BatchTaskIdsRequest;
import com.ruoyi.system.api.entity.U02cx.GetTokenRequest;
@ -10,6 +11,7 @@ import com.ruoyi.system.api.entity.U02cx.TaskDetailResponse;
import com.ruoyi.system.domain.SmsChannelTbl;
import com.ruoyi.system.mapper.SmsChannelTblMapper;
import com.ruoyi.system.mapper.SmsTaskTblMapper;
import com.ruoyi.system.mapper.UserPointMapper;
import com.ruoyi.system.util.RsaUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
@ -32,6 +34,9 @@ public class GetSmsDetailTaskHandler {
@Autowired
private SmsTaskTblMapper smsTaskTblMapper;
@Autowired
private UserPointMapper userPointMapper;
public void doGetSmsDetailTask(List<SmsTaskTbl> smsTaskTblList) {
List<Long> taskIds = smsTaskTblList.stream().filter(smsTaskTbl -> {
return smsTaskTbl.getTaskId() != null;
@ -43,7 +48,6 @@ public class GetSmsDetailTaskHandler {
String token = iu02cxApi.getToken(getTokenRequest);
String jsonStr = JSONUtil.toJsonStr(taskIds);
log.debug("jsonStr:{}", jsonStr);
String encryptedData = RsaUtils.encryptData(jsonStr, smsChannelTbl.getPublicKey());
@ -59,24 +63,52 @@ public class GetSmsDetailTaskHandler {
.forEach(taskDetailResponse -> {
SmsTaskTbl smsTaskTbl = new SmsTaskTbl();
smsTaskTbl.setTaskId(taskDetailResponse.getTaskId());
if (taskDetailResponse.getCompleteTime()!=null ){
smsTaskTbl.setCompleteTime(DateUtil.parse(taskDetailResponse.getCompleteTime()));
String completeTime = taskDetailResponse.getCompleteTime();
if (completeTime == null) {
return;
}
SmsTaskTbl smsTaskTblResult = smsTaskTblMapper.selectSmsTaskTblList(smsTaskTbl).get(0);
smsTaskTblResult.setCompleteTime(DateUtil.parse(taskDetailResponse.getCompleteTime()));
String successRate = taskDetailResponse.getSuccessRate();
if (successRate != null){
if (successRate != null) {
smsTaskTbl.setSuccessRate(successRate);
String[] split = successRate.split("/");
smsTaskTbl.setSuccessCount(Long.parseLong(split[0]));
smsTaskTbl.setTotalCount(Long.parseLong(split[1]));
}
BigDecimal preSummary = taskDetailResponse.getPreSummary();
if (preSummary != null){
smsTaskTbl.setPreSummary(preSummary);
}
smsTaskTbl.setIssueCount(Long.valueOf(taskDetailResponse.getIssueCount()));
smsTaskTbl.setTaskStatus(taskDetailResponse.getTaskStatus());
smsTaskTbl.setUpdateBy("system");
BigDecimal price = smsTaskTblResult.getPrice();
BigDecimal actSummary = price.multiply(BigDecimal.valueOf(smsTaskTbl.getSuccessCount()));
smsTaskTblResult.setActSummary(actSummary);
BigDecimal preSummary = smsTaskTblResult.getPreSummary();
BigDecimal subtract = preSummary.subtract(actSummary);
UserPoint userPointParam = new UserPoint();
userPointParam.setUserId(Long.valueOf(smsTaskTblResult.getUserId()));
UserPoint userPoint = userPointMapper.selectUserPointList(userPointParam).get(0);
BigDecimal pointBalance = userPoint.getPointBalance();
BigDecimal pointBalanceNew = pointBalance.add(subtract);
userPoint.setPointBalance(pointBalanceNew);
userPointMapper.updateUserPoint(userPoint);
// smsTaskTbl.setCompleteTime(DateUtil.parse(taskDetailResponse.getCompleteTime()));
// String successRate = taskDetailResponse.getSuccessRate();
// if (successRate != null) {
// smsTaskTbl.setSuccessRate(successRate);
// String[] split = successRate.split("/");
// smsTaskTbl.setSuccessCount(Long.parseLong(split[0]));
//// smsTaskTbl.setTotalCount(Long.parseLong(split[1]));
// }
// /* BigDecimal preSummary = taskDetailResponse.getPreSummary();
// if (preSummary != null) {
// smsTaskTbl.setPreSummary(preSummary);
// }*/
//// smsTaskTbl.setIssueCount(Long.valueOf(taskDetailResponse.getIssueCount()));
// smsTaskTbl.setTaskStatus(taskDetailResponse.getTaskStatus());
// smsTaskTbl.setUpdateBy("system");
smsTaskTbl.setSettleStatus("1");
smsTaskTblMapper.updateSmsTaskTblByTaskId(smsTaskTbl);
});

View File

@ -0,0 +1,63 @@
package com.ruoyi.system.mapper;
import com.ruoyi.common.core.domain.entity.PointRechargeOrder;
import java.util.List;
/**
* Mapper
*
* @author dorion
* @date 2024-07-21
*/
public interface PointRechargeOrderMapper
{
/**
*
*
* @param idPointRechargeOrder
* @return
*/
public PointRechargeOrder selectPointRechargeOrderByIdPointRechargeOrder(Long idPointRechargeOrder);
/**
*
*
* @param pointRechargeOrder
* @return
*/
public List<PointRechargeOrder> selectPointRechargeOrderList(PointRechargeOrder pointRechargeOrder);
/**
*
*
* @param pointRechargeOrder
* @return
*/
public int insertPointRechargeOrder(PointRechargeOrder pointRechargeOrder);
/**
*
*
* @param pointRechargeOrder
* @return
*/
public int updatePointRechargeOrder(PointRechargeOrder pointRechargeOrder);
/**
*
*
* @param idPointRechargeOrder
* @return
*/
public int deletePointRechargeOrderByIdPointRechargeOrder(Long idPointRechargeOrder);
/**
*
*
* @param idPointRechargeOrders
* @return
*/
public int deletePointRechargeOrderByIdPointRechargeOrders(String[] idPointRechargeOrders);
}

View File

@ -0,0 +1,67 @@
package com.ruoyi.system.mapper;
import com.ruoyi.common.core.domain.entity.CountryTbl;
import com.ruoyi.common.core.domain.entity.SmsCountryPrice;
import java.util.List;
/**
* Mapper
*
* @author dorion
* @date 2024-07-21
*/
public interface SmsCountryPriceMapper {
/**
*
*
* @param idSmsCountryPrice
* @return
*/
public SmsCountryPrice selectSmsCountryPriceByIdSmsCountryPrice(Long idSmsCountryPrice);
/**
*
*
* @param smsCountryPrice
* @return
*/
public List<SmsCountryPrice> selectSmsCountryPriceList(SmsCountryPrice smsCountryPrice);
/**
*
*
* @param smsCountryPrice
* @return
*/
public int insertSmsCountryPrice(SmsCountryPrice smsCountryPrice);
/**
*
*
* @param smsCountryPrice
* @return
*/
public int updateSmsCountryPrice(SmsCountryPrice smsCountryPrice);
/**
*
*
* @param idSmsCountryPrice
* @return
*/
public int deleteSmsCountryPriceByIdSmsCountryPrice(Long idSmsCountryPrice);
/**
*
*
* @param idSmsCountryPrices
* @return
*/
public int deleteSmsCountryPriceByIdSmsCountryPrices(String[] idSmsCountryPrices);
List<CountryTbl> selectAllCountries();
CountryTbl selectCountryById(Long countryId);
}

View File

@ -0,0 +1,62 @@
package com.ruoyi.system.mapper;
import com.ruoyi.common.core.domain.entity.UserPoint;
import java.util.List;
/**
* Mapper
*
* @author dorion
* @date 2024-07-21
*/
public interface UserPointMapper
{
/**
*
*
* @param idUserPoint
* @return
*/
public UserPoint selectUserPointByIdUserPoint(Long idUserPoint);
/**
*
*
* @param userPoint
* @return
*/
public List<UserPoint> selectUserPointList(UserPoint userPoint);
/**
*
*
* @param userPoint
* @return
*/
public int insertUserPoint(UserPoint userPoint);
/**
*
*
* @param userPoint
* @return
*/
public int updateUserPoint(UserPoint userPoint);
/**
*
*
* @param idUserPoint
* @return
*/
public int deleteUserPointByIdUserPoint(Long idUserPoint);
/**
*
*
* @param idUserPoints
* @return
*/
public int deleteUserPointByIdUserPoints(String[] idUserPoints);
}

View File

@ -0,0 +1,65 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.entity.PointRechargeOrder;
import java.util.List;
/**
* Service
*
* @author dorion
* @date 2024-07-21
*/
public interface IPointRechargeOrderService
{
/**
*
*
* @param idPointRechargeOrder
* @return
*/
public PointRechargeOrder selectPointRechargeOrderByIdPointRechargeOrder(Long idPointRechargeOrder);
/**
*
*
* @param pointRechargeOrder
* @return
*/
public List<PointRechargeOrder> selectPointRechargeOrderList(PointRechargeOrder pointRechargeOrder);
/**
*
*
* @param pointRechargeOrder
* @return
*/
public int insertPointRechargeOrder(PointRechargeOrder pointRechargeOrder);
/**
*
*
* @param pointRechargeOrder
* @return
*/
public int updatePointRechargeOrder(PointRechargeOrder pointRechargeOrder);
/**
*
*
* @param idPointRechargeOrders
* @return
*/
public int deletePointRechargeOrderByIdPointRechargeOrders(String idPointRechargeOrders);
/**
*
*
* @param idPointRechargeOrder
* @return
*/
public int deletePointRechargeOrderByIdPointRechargeOrder(Long idPointRechargeOrder);
Long rechargeOrder(PointRechargeOrder pointRechargeOrder);
}

View File

@ -0,0 +1,67 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.entity.CountryTbl;
import com.ruoyi.common.core.domain.entity.SmsCountryPrice;
import java.util.List;
/**
* Service
*
* @author dorion
* @date 2024-07-21
*/
public interface ISmsCountryPriceService
{
/**
*
*
* @param idSmsCountryPrice
* @return
*/
public SmsCountryPrice selectSmsCountryPriceByIdSmsCountryPrice(Long idSmsCountryPrice);
/**
*
*
* @param smsCountryPrice
* @return
*/
public List<SmsCountryPrice> selectSmsCountryPriceList(SmsCountryPrice smsCountryPrice);
/**
*
*
* @param smsCountryPrice
* @return
*/
public int insertSmsCountryPrice(SmsCountryPrice smsCountryPrice);
/**
*
*
* @param smsCountryPrice
* @return
*/
public int updateSmsCountryPrice(SmsCountryPrice smsCountryPrice);
/**
*
*
* @param idSmsCountryPrices
* @return
*/
public int deleteSmsCountryPriceByIdSmsCountryPrices(String idSmsCountryPrices);
/**
*
*
* @param idSmsCountryPrice
* @return
*/
public int deleteSmsCountryPriceByIdSmsCountryPrice(Long idSmsCountryPrice);
List<CountryTbl> selectAllCountries();
}

View File

@ -2,6 +2,7 @@ package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.entity.SmsTaskTbl;
import com.ruoyi.common.core.domain.vo.BatchUpdateSmsVO;
import com.ruoyi.common.core.domain.vo.SmsTaskTblVO;
import java.util.List;
@ -67,4 +68,6 @@ public interface ISmsTaskTblService
byte[] getReport(Long idSmsTask);
int complete(String ids);
void insertSmsTaskTblBatch(SmsTaskTblVO smsTaskTblVO);
}

View File

@ -0,0 +1,63 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.entity.UserPoint;
import java.util.List;
/**
* Service
*
* @author dorion
* @date 2024-07-21
*/
public interface IUserPointService
{
/**
*
*
* @param idUserPoint
* @return
*/
public UserPoint selectUserPointByIdUserPoint(Long idUserPoint);
/**
*
*
* @param userPoint
* @return
*/
public List<UserPoint> selectUserPointList(UserPoint userPoint);
/**
*
*
* @param userPoint
* @return
*/
public int insertUserPoint(UserPoint userPoint);
/**
*
*
* @param userPoint
* @return
*/
public int updateUserPoint(UserPoint userPoint);
/**
*
*
* @param idUserPoints
* @return
*/
public int deleteUserPointByIdUserPoints(String idUserPoints);
/**
*
*
* @param idUserPoint
* @return
*/
public int deleteUserPointByIdUserPoint(Long idUserPoint);
}

View File

@ -0,0 +1,218 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import com.google.common.base.Preconditions;
import com.ruoyi.common.core.domain.entity.PointRechargeOrder;
import com.ruoyi.common.core.domain.entity.UserPoint;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.SnowFlakeUtil;
import com.ruoyi.system.mapper.PointRechargeOrderMapper;
import com.ruoyi.system.mapper.UserPointMapper;
import com.ruoyi.system.service.IPointRechargeOrderService;
import com.ruoyi.system.service.ISysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.Random;
/**
* Service
*
* @author dorion
* @date 2024-07-21
*/
@Service
public class PointRechargeOrderServiceImpl implements IPointRechargeOrderService {
@Autowired
private PointRechargeOrderMapper pointRechargeOrderMapper;
@Autowired
private UserPointMapper userPointMapper;
@Autowired
private ISysConfigService configService;
@Autowired
private SnowFlakeUtil snowFlakeUtil;
@Autowired
private RedisTemplate redisTemplate;
/**
*
*
* @param idPointRechargeOrder
* @return
*/
@Override
public PointRechargeOrder selectPointRechargeOrderByIdPointRechargeOrder(Long idPointRechargeOrder) {
return pointRechargeOrderMapper.selectPointRechargeOrderByIdPointRechargeOrder(idPointRechargeOrder);
}
/**
*
*
* @param pointRechargeOrder
* @return
*/
@Override
public List<PointRechargeOrder> selectPointRechargeOrderList(PointRechargeOrder pointRechargeOrder) {
return pointRechargeOrderMapper.selectPointRechargeOrderList(pointRechargeOrder);
}
/**
*
*
* @param pointRechargeOrder
* @return
*/
@Override
@Transactional
public int insertPointRechargeOrder(PointRechargeOrder pointRechargeOrder) {
setPointsAndExchangeRate(pointRechargeOrder);
setOrderNo(pointRechargeOrder);
String loginName = ShiroUtils.getLoginName();
pointRechargeOrder.setCreateBy(loginName);
pointRechargeOrder.setUpdateBy(loginName);
int i = pointRechargeOrderMapper.insertPointRechargeOrder(pointRechargeOrder);
String status = pointRechargeOrder.getStatus();
if (!"N".equals(status)) {
createOrUpdateUserPoints(pointRechargeOrder);
}
return i;
}
private void setOrderNo(PointRechargeOrder pointRechargeOrder) {
Long orderNumber = snowFlakeUtil.nextId();
pointRechargeOrder.setOrderNumber(orderNumber.toString());
}
private void setPointsAndExchangeRate(PointRechargeOrder pointRechargeOrder) {
String sysSmsExchangeRate = configService.selectConfigByKey("sys.sms.exchange.rate");
BigDecimal amount = pointRechargeOrder.getAmount();
BigInteger bigInteger = amount.toBigInteger();
BigDecimal calcAmount = new BigDecimal(bigInteger);
BigDecimal exchangeRate = new BigDecimal(sysSmsExchangeRate);
BigDecimal points = calcAmount.multiply(exchangeRate);
pointRechargeOrder.setPoints(points);
pointRechargeOrder.setExchangeRate(exchangeRate);
}
private void createOrUpdateUserPoints(PointRechargeOrder pointRechargeOrder) {
UserPoint userPoint = new UserPoint();
userPoint.setUserId(pointRechargeOrder.getUserId());
List<UserPoint> userPoints = userPointMapper.selectUserPointList(userPoint);
if (CollectionUtil.isNotEmpty(userPoints)) {
UserPoint userPointResult = userPoints.get(0);
BigDecimal pointBalance = userPointResult.getPointBalance();
BigDecimal add = pointBalance.add(pointRechargeOrder.getPoints());
userPointResult.setPointBalance(add);
userPointMapper.updateUserPoint(userPointResult);
} else {
userPoint.setPointBalance(pointRechargeOrder.getPoints());
userPointMapper.insertUserPoint(userPoint);
}
}
/**
*
*
* @param pointRechargeOrder
* @return
*/
@Override
public int updatePointRechargeOrder(PointRechargeOrder pointRechargeOrder) {
String loginName = ShiroUtils.getLoginName();
pointRechargeOrder.setUpdateBy(loginName);
String status = pointRechargeOrder.getStatus();
if (!"N".equals(status)) {
PointRechargeOrder pointRechargeOrderDetail = pointRechargeOrderMapper.selectPointRechargeOrderByIdPointRechargeOrder(pointRechargeOrder.getIdPointRechargeOrder());
if (!pointRechargeOrderDetail.getStatus().equals(pointRechargeOrder.getStatus())) {
//状态发生变化了再更新
createOrUpdateUserPoints(pointRechargeOrderDetail);
}
}
return pointRechargeOrderMapper.updatePointRechargeOrder(pointRechargeOrder);
}
/**
*
*
* @param idPointRechargeOrders
* @return
*/
@Override
public int deletePointRechargeOrderByIdPointRechargeOrders(String idPointRechargeOrders) {
return pointRechargeOrderMapper.deletePointRechargeOrderByIdPointRechargeOrders(Convert.toStrArray(idPointRechargeOrders));
}
/**
*
*
* @param idPointRechargeOrder
* @return
*/
@Override
public int deletePointRechargeOrderByIdPointRechargeOrder(Long idPointRechargeOrder) {
return pointRechargeOrderMapper.deletePointRechargeOrderByIdPointRechargeOrder(idPointRechargeOrder);
}
@Override
public Long rechargeOrder(PointRechargeOrder pointRechargeOrder) {
Long userId = ShiroUtils.getSysUser().getUserId();
PointRechargeOrder pointRechargeOrderParam = new PointRechargeOrder();
pointRechargeOrderParam.setUserId(userId);
pointRechargeOrderParam.setStatus("N");
List<PointRechargeOrder> pointRechargeOrders = pointRechargeOrderMapper.selectPointRechargeOrderList(pointRechargeOrderParam);
Preconditions.checkState(pointRechargeOrders.size() <=3, "每个用户1小时内最多只能创建3个充值订单");
PointRechargeOrder pointRechargeOrderExist = pointRechargeOrders.stream().filter(pointRechargeOrderTemp -> {
BigInteger amountOld = pointRechargeOrderTemp.getAmount().toBigInteger();
return amountOld.equals(pointRechargeOrder.getAmount().toBigInteger());
}).findFirst().orElse(null);
if (pointRechargeOrderExist != null){
return pointRechargeOrderExist.getIdPointRechargeOrder();
}
setPointsAndExchangeRate(pointRechargeOrder);
Boolean hasKey = true;
BigDecimal finalAmout;
do {
finalAmout = getFinalAmout(pointRechargeOrder);
hasKey = redisTemplate.hasKey("sms_recharge_amount_" + finalAmout);
} while (Boolean.TRUE.equals(hasKey));
pointRechargeOrder.setAmount(finalAmout);
setOrderNo(pointRechargeOrder);
// Long userId = ShiroUtils.getSysUser().getUserId();
pointRechargeOrder.setUserId(userId);
String loginName = ShiroUtils.getLoginName();
pointRechargeOrder.setCreateBy(loginName);
pointRechargeOrder.setUpdateBy(loginName);
pointRechargeOrder.setStatus("N");
pointRechargeOrderMapper.insertPointRechargeOrder(pointRechargeOrder);
return pointRechargeOrder.getIdPointRechargeOrder();
}
private static BigDecimal getFinalAmout(PointRechargeOrder pointRechargeOrder) {
BigDecimal amount = pointRechargeOrder.getAmount();
Random random = new Random();
int randomInt = random.nextInt(100);
BigDecimal finalAmout = BigDecimal.valueOf(randomInt).divide(BigDecimal.valueOf(100)).add(amount);
return finalAmout;
}
}

View File

@ -0,0 +1,114 @@
package com.ruoyi.system.service.impl;
import com.ruoyi.common.core.domain.entity.CountryTbl;
import com.ruoyi.common.core.domain.entity.SmsCountryPrice;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.system.mapper.SmsCountryPriceMapper;
import com.ruoyi.system.service.ISmsCountryPriceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Service
*
* @author dorion
* @date 2024-07-21
*/
@Service
public class SmsCountryPriceServiceImpl implements ISmsCountryPriceService
{
@Autowired
private SmsCountryPriceMapper smsCountryPriceMapper;
/**
*
*
* @param idSmsCountryPrice
* @return
*/
@Override
public SmsCountryPrice selectSmsCountryPriceByIdSmsCountryPrice(Long idSmsCountryPrice)
{
return smsCountryPriceMapper.selectSmsCountryPriceByIdSmsCountryPrice(idSmsCountryPrice);
}
/**
*
*
* @param smsCountryPrice
* @return
*/
@Override
public List<SmsCountryPrice> selectSmsCountryPriceList(SmsCountryPrice smsCountryPrice)
{
return smsCountryPriceMapper.selectSmsCountryPriceList(smsCountryPrice);
}
/**
*
*
* @param smsCountryPrice
* @return
*/
@Override
public int insertSmsCountryPrice(SmsCountryPrice smsCountryPrice)
{
CountryTbl countryTbl = smsCountryPriceMapper.selectCountryById(smsCountryPrice.getCountryId());
smsCountryPrice.setAreaCode(countryTbl.getAreaCode().toString());
String loginName = ShiroUtils.getLoginName();
smsCountryPrice.setCreateBy(loginName);
smsCountryPrice.setUpdateBy(loginName);
return smsCountryPriceMapper.insertSmsCountryPrice(smsCountryPrice);
}
/**
*
*
* @param smsCountryPrice
* @return
*/
@Override
public int updateSmsCountryPrice(SmsCountryPrice smsCountryPrice)
{
CountryTbl countryTbl = smsCountryPriceMapper.selectCountryById(smsCountryPrice.getCountryId());
smsCountryPrice.setAreaCode(countryTbl.getAreaCode().toString());
String loginName = ShiroUtils.getLoginName();
smsCountryPrice.setUpdateBy(loginName);
return smsCountryPriceMapper.updateSmsCountryPrice(smsCountryPrice);
}
/**
*
*
* @param idSmsCountryPrices
* @return
*/
@Override
public int deleteSmsCountryPriceByIdSmsCountryPrices(String idSmsCountryPrices)
{
return smsCountryPriceMapper.deleteSmsCountryPriceByIdSmsCountryPrices(Convert.toStrArray(idSmsCountryPrices));
}
/**
*
*
* @param idSmsCountryPrice
* @return
*/
@Override
public int deleteSmsCountryPriceByIdSmsCountryPrice(Long idSmsCountryPrice)
{
return smsCountryPriceMapper.deleteSmsCountryPriceByIdSmsCountryPrice(idSmsCountryPrice);
}
@Override
public List<CountryTbl> selectAllCountries() {
return smsCountryPriceMapper.selectAllCountries();
}
}

View File

@ -1,9 +1,15 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.google.common.base.Preconditions;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.domain.entity.CountryTbl;
import com.ruoyi.common.core.domain.entity.SmsCountryPrice;
import com.ruoyi.common.core.domain.entity.SmsTaskTbl;
import com.ruoyi.common.core.domain.entity.UserPoint;
import com.ruoyi.common.core.domain.vo.BatchUpdateSmsVO;
import com.ruoyi.common.core.domain.vo.SmsTaskTblVO;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
@ -12,7 +18,9 @@ import com.ruoyi.system.api.entity.U02cx.*;
import com.ruoyi.system.domain.SmsChannelTbl;
import com.ruoyi.system.handler.GetSmsDetailTaskHandler;
import com.ruoyi.system.mapper.SmsChannelTblMapper;
import com.ruoyi.system.mapper.SmsCountryPriceMapper;
import com.ruoyi.system.mapper.SmsTaskTblMapper;
import com.ruoyi.system.mapper.UserPointMapper;
import com.ruoyi.system.service.ISmsTaskTblService;
import com.ruoyi.system.util.RsaUtils;
import org.slf4j.Logger;
@ -21,7 +29,9 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.stream.Collectors;
@ -46,6 +56,12 @@ public class SmsTaskTblServiceImpl implements ISmsTaskTblService {
@Autowired
private GetSmsDetailTaskHandler smsDetailTaskHandler;
@Autowired
private SmsCountryPriceMapper smsCountryPriceMapper;
@Autowired
private UserPointMapper userPointMapper;
/**
* WS
*
@ -77,7 +93,52 @@ public class SmsTaskTblServiceImpl implements ISmsTaskTblService {
*/
@Override
public int insertSmsTaskTbl(SmsTaskTbl smsTaskTbl) {
log.info("insertSmsTaskTbl:{}", smsTaskTbl.toString());
String taskName = smsTaskTbl.getTaskName();
Preconditions.checkState(taskName.matches("^[a-zA-Z0-9_]+$"), "任务名称只能是数字,字母和下划线");
String phoneNumber = smsTaskTbl.getPhoneNumber();
List<SmsCountryPrice> smsCountryPrices = getSmsCountryPrices(phoneNumber);
SmsCountryPrice smsCountryPrice = smsCountryPrices.get(0);
BigDecimal price = smsCountryPrice.getPrice();
CountryTbl countryTbl = smsCountryPriceMapper.selectCountryById(smsCountryPrice.getCountryId());
String chineseName = countryTbl.getChineseName();
UserPoint userPoint = getUserPoint();
int i = doAddSmsTaskTblRequest(smsTaskTbl, price, chineseName,userPoint);
return i;
}
private UserPoint getUserPoint() {
Long userId = ShiroUtils.getUserId();
UserPoint userPointParam = new UserPoint();
userPointParam.setUserId(userId);
List<UserPoint> userPoints = userPointMapper.selectUserPointList(userPointParam);
Preconditions.checkState(CollectionUtil.isNotEmpty(userPoints), "未有积分,请先进行充值");
UserPoint userPoint = userPoints.get(0);
return userPoint;
}
private int doAddSmsTaskTblRequest(SmsTaskTbl smsTaskTbl, BigDecimal price, String chineseName,UserPoint userPoint) {
String taskName = smsTaskTbl.getTaskName();
smsTaskTbl.setPrice(price);
smsTaskTbl.setCountry(chineseName);
BigDecimal preSummary = price.multiply(new BigDecimal(smsTaskTbl.getTotalCount()));
smsTaskTbl.setPreSummary(preSummary);
Long userId = ShiroUtils.getUserId();
BigDecimal pointBalanceOld = userPoint.getPointBalance();
Preconditions.checkState(pointBalanceOld.compareTo(preSummary) >= 0, "积分不足本次消耗,请先进行充值");
BigDecimal pointBalance = pointBalanceOld.subtract(preSummary);
userPoint.setPointBalance(pointBalance);
SmsChannelTbl smsChannelTbl = smsChannelTblMapper.selectSmsChannelTblByIdSmsChannel(1L);
GetTokenRequest getTokenRequest = new GetTokenRequest();
@ -86,13 +147,13 @@ public class SmsTaskTblServiceImpl implements ISmsTaskTblService {
String token = u02cxApi.getToken(getTokenRequest);
log.debug("token:{}", token);
AddTaskRequest addTaskRequest = new AddTaskRequest();
addTaskRequest.setTaskName(smsTaskTbl.getTaskName())
addTaskRequest.setTaskName(taskName)
.setPrice(smsTaskTbl.getPrice())
.setTaskBeginTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", smsTaskTbl.getTaskBeginTime()))
.setFileName(smsTaskTbl.getFileName())
.setFilePath(smsTaskTbl.getFilePath())
.setFileMd5(smsTaskTbl.getFileMd5())
.setContext(smsTaskTbl.getContext())
.setContext( Base64.getEncoder().encodeToString(smsTaskTbl.getContext().getBytes()))
.setType(Integer.parseInt(smsTaskTbl.getSmsContentType()));
try {
// 将公钥字符串转换为 PublicKey 对象
@ -110,7 +171,7 @@ public class SmsTaskTblServiceImpl implements ISmsTaskTblService {
smsTaskTbl.setTaskId(taskId);
smsTaskTbl.setChannelId(smsChannelTbl.getChannelId());
Long userId = ShiroUtils.getUserId();
smsTaskTbl.setUserId(userId.toString());
String loginName = ShiroUtils.getLoginName();
smsTaskTbl.setCreateBy(loginName);
@ -121,6 +182,7 @@ public class SmsTaskTblServiceImpl implements ISmsTaskTblService {
}
int i = smsTaskTblMapper.insertSmsTaskTbl(smsTaskTbl);
userPointMapper.updateUserPoint(userPoint);
String taskStatus = smsTaskTbl.getTaskStatus();
if ("1".equals(taskStatus)) {
@ -140,6 +202,19 @@ public class SmsTaskTblServiceImpl implements ISmsTaskTblService {
return i;
}
private List<SmsCountryPrice> getSmsCountryPrices(String phoneNumber) {
Preconditions.checkState(phoneNumber.length() > 2, "首行号码位数不够");
String areaCode = phoneNumber.substring(0, 2);
SmsCountryPrice smsCountryPriceParam = new SmsCountryPrice();
smsCountryPriceParam.setAreaCode(areaCode);
List<SmsCountryPrice> smsCountryPrices = smsCountryPriceMapper.selectSmsCountryPriceList(smsCountryPriceParam);
if (CollectionUtil.isEmpty(smsCountryPrices)) {
smsCountryPriceParam.setAreaCode("99999");
smsCountryPrices = smsCountryPriceMapper.selectSmsCountryPriceList(smsCountryPriceParam);
}
return smsCountryPrices;
}
/**
* WS
@ -189,22 +264,22 @@ public class SmsTaskTblServiceImpl implements ISmsTaskTblService {
String token = u02cxApi.getToken(getTokenRequest);
List<String> idsList = Arrays.asList(ids.split(","));
List<SmsTaskTbl> smsTaskTblList = smsTaskTblMapper.selectSmsTaskTbl(idsList);
List<SmsTaskTbl> smsTaskTblList = smsTaskTblMapper.selectSmsTaskTbl(idsList);
List<String> editSmsTypeList = Arrays.asList(editSmsTypes.split(","));
if (editSmsTypeList.contains("task_status")){
if (editSmsTypeList.contains("task_status")) {
String taskStatus = batchUpdateSmsVO.getTaskStatus();
String taskStatusName = taskStatus.equals("0") ? "关闭" : "开启";
smsTaskTblList.stream().filter(smsTaskTbl -> smsTaskTbl.getTaskStatus().equals(taskStatus))
.forEach(smsTaskTbl -> {
throw new RuntimeException(smsTaskTbl.getTaskName()+"状态已经是:[ "+ taskStatusName+" ],不能修改,请重新选择");
});
.forEach(smsTaskTbl -> {
throw new RuntimeException(smsTaskTbl.getTaskName() + "状态已经是:[ " + taskStatusName + " ],不能修改,请重新选择");
});
}
for (SmsTaskTbl smsTaskTbl : smsTaskTblList) {
if (editSmsTypeList.contains("task_status")){
if (editSmsTypeList.contains("task_status")) {
UpdateTaskStatusRequest updateTaskStatusRequest = new UpdateTaskStatusRequest();
updateTaskStatusRequest.setTaskId(smsTaskTbl.getTaskId())
.setTaskStatus(Integer.parseInt(batchUpdateSmsVO.getTaskStatus()));
@ -220,7 +295,7 @@ public class SmsTaskTblServiceImpl implements ISmsTaskTblService {
smsTaskTbl.setTaskStatus(batchUpdateSmsVO.getTaskStatus());
}
if (editSmsTypeList.contains("begin_time")){
if (editSmsTypeList.contains("begin_time")) {
UpdateTaskRequest updateTaskRequest = new UpdateTaskRequest();
updateTaskRequest.setTaskId(smsTaskTbl.getTaskId())
.setTaskBeginTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", batchUpdateSmsVO.getTaskBeginTime()));
@ -240,9 +315,6 @@ public class SmsTaskTblServiceImpl implements ISmsTaskTblService {
}
// for (String id : idArray) {
// SmsTaskTbl smsTaskTbl = smsTaskTblMapper.selectSmsTaskTblByIdSmsTask(Long.valueOf(id));
//
@ -295,8 +367,8 @@ public class SmsTaskTblServiceImpl implements ISmsTaskTblService {
GetReportRequest getReportRequest = new GetReportRequest();
getReportRequest.setTaskId(smsTaskTbl.getTaskId())
.setToken(token)
.setAppId(smsChannelTbl.getAppId());
.setToken(token)
.setAppId(smsChannelTbl.getAppId());
byte[] report = u02cxApi.getReport(getReportRequest);
return report;
}
@ -305,7 +377,7 @@ public class SmsTaskTblServiceImpl implements ISmsTaskTblService {
public int complete(String ids) {
List<String> idsList = Arrays.asList(ids.split(","));
List<SmsTaskTbl> smsTaskTblList = smsTaskTblMapper.selectSmsTaskTbl(idsList);
List<SmsTaskTbl> smsTaskTblList = smsTaskTblMapper.selectSmsTaskTbl(idsList);
SmsChannelTbl smsChannelTbl = smsChannelTblMapper.selectSmsChannelTblByIdSmsChannel(1L);
@ -317,12 +389,32 @@ public class SmsTaskTblServiceImpl implements ISmsTaskTblService {
BatchTaskIdsRequest batchTaskIdsRequest = new BatchTaskIdsRequest();
batchTaskIdsRequest.setTaskIds(taskIds)
.setToken(token)
.setAppId(smsChannelTbl.getAppId());
.setToken(token)
.setAppId(smsChannelTbl.getAppId());
u02cxApi.completeByBatch(batchTaskIdsRequest);
smsDetailTaskHandler.doGetSmsDetailTask(smsTaskTblList);
return smsTaskTblList.size();
}
@Override
public void insertSmsTaskTblBatch(SmsTaskTblVO smsTaskTblVO) {
List<SmsCountryPrice> smsCountryPrices = getSmsCountryPrices(smsTaskTblVO.getPhoneNumber());
SmsCountryPrice smsCountryPrice = smsCountryPrices.get(0);
BigDecimal price = smsCountryPrice.getPrice();
CountryTbl countryTbl = smsCountryPriceMapper.selectCountryById(smsCountryPrice.getCountryId());
String chineseName = countryTbl.getChineseName();
List<SmsTaskTbl> smsTaskTblList = smsTaskTblVO.getSmsTaskTblList();
UserPoint userPoint = getUserPoint();
BigDecimal preSummary = price.multiply(new BigDecimal(smsTaskTblVO.getLineCount()));
BigDecimal pointBalanceOld = userPoint.getPointBalance();
Preconditions.checkState(pointBalanceOld.compareTo(preSummary) >= 0, "积分不足本次消耗,请先进行充值");
for (SmsTaskTbl smsTaskTbl : smsTaskTblList) {
doAddSmsTaskTblRequest(smsTaskTbl, price, chineseName,userPoint);
}
}
}

View File

@ -0,0 +1,100 @@
package com.ruoyi.system.service.impl;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.domain.entity.UserPoint;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.mapper.UserPointMapper;
import com.ruoyi.system.service.IUserPointService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Service
*
* @author dorion
* @date 2024-07-21
*/
@Service
public class UserPointServiceImpl implements IUserPointService
{
@Autowired
private UserPointMapper userPointMapper;
/**
*
*
* @param idUserPoint
* @return
*/
@Override
public UserPoint selectUserPointByIdUserPoint(Long idUserPoint)
{
return userPointMapper.selectUserPointByIdUserPoint(idUserPoint);
}
/**
*
*
* @param userPoint
* @return
*/
@Override
@DataScope(userAlias = "u")
public List<UserPoint> selectUserPointList(UserPoint userPoint)
{
return userPointMapper.selectUserPointList(userPoint);
}
/**
*
*
* @param userPoint
* @return
*/
@Override
public int insertUserPoint(UserPoint userPoint)
{
userPoint.setCreateTime(DateUtils.getNowDate());
return userPointMapper.insertUserPoint(userPoint);
}
/**
*
*
* @param userPoint
* @return
*/
@Override
public int updateUserPoint(UserPoint userPoint)
{
userPoint.setUpdateTime(DateUtils.getNowDate());
return userPointMapper.updateUserPoint(userPoint);
}
/**
*
*
* @param idUserPoints
* @return
*/
@Override
public int deleteUserPointByIdUserPoints(String idUserPoints)
{
return userPointMapper.deleteUserPointByIdUserPoints(Convert.toStrArray(idUserPoints));
}
/**
*
*
* @param idUserPoint
* @return
*/
@Override
public int deleteUserPointByIdUserPoint(Long idUserPoint)
{
return userPointMapper.deleteUserPointByIdUserPoint(idUserPoint);
}
}

View File

@ -18,6 +18,7 @@
<result property="bindPeriod" column="bind_period" />
<result property="isValid" column="is_valid" />
<result property="comment" column="comment" />
<result property="imageUrl" column="image_url" />
<result property="fcd" column="fcd" />
<result property="fcu" column="fcu" />
<result property="lcd" column="lcd" />
@ -25,7 +26,7 @@
</resultMap>
<sql id="selectMonitorAddressInfoVo">
select id_monitor_address, busi_type, monitor_address_name, monitor_address, account_address, trx_price, usdt_price, monitor_type, id_tg_message_info, group_chat_id, bind_period, is_valid, comment, fcd, fcu, lcd, lcu from monitor_address_info
select id_monitor_address, busi_type, monitor_address_name, monitor_address, account_address, trx_price, usdt_price, monitor_type, id_tg_message_info, group_chat_id, bind_period, is_valid, comment,image_url, fcd, fcu, lcd, lcu from monitor_address_info
</sql>
<select id="selectMonitorAddressInfoList" parameterType="MonitorAddressInfo" resultMap="MonitorAddressInfoResult">
@ -54,6 +55,7 @@
where id_monitor_address = #{idMonitorAddress}
</select>
<insert id="insertMonitorAddressInfo" parameterType="MonitorAddressInfo" useGeneratedKeys="true" keyProperty="idMonitorAddress">
insert into monitor_address_info
<trim prefix="(" suffix=")" suffixOverrides=",">
@ -64,12 +66,12 @@
<if test="trxPrice != null">trx_price,</if>
<if test="usdtPrice != null">usdt_price,</if>
<if test="monitorType != null">monitor_type,</if>
<!-- <if test="apiKey != null">api_key,</if>-->
<if test="bindPeriod != null">bind_period,</if>
<if test="isValid != null">is_valid,</if>
<if test="idTgMessageInfo != null">id_tg_message_info,</if>
<if test="groupChatId != null">group_chat_id,</if>
<if test="comment != null">comment,</if>
<if test="imageUrl != null">image_url,</if>
<if test="fcd != null">fcd,</if>
<if test="fcu != null">fcu,</if>
<if test="lcd != null">lcd,</if>
@ -83,12 +85,12 @@
<if test="trxPrice != null">#{trxPrice},</if>
<if test="usdtPrice != null">#{usdtPrice},</if>
<if test="monitorType != null">#{monitorType},</if>
<!-- <if test="apiKey != null">#{apiKey},</if>-->
<if test="bindPeriod != null">#{bindPeriod},</if>
<if test="isValid != null">#{isValid},</if>
<if test="idTgMessageInfo != null">#{idTgMessageInfo},</if>
<if test="groupChatId != null">#{groupChatId},</if>
<if test="comment != null">#{comment},</if>
<if test="imageUrl != null">#{imageUrl},</if>
<if test="fcd != null">#{fcd},</if>
<if test="fcu != null">#{fcu},</if>
<if test="lcd != null">#{lcd},</if>
@ -106,12 +108,12 @@
<if test="trxPrice != null">trx_price = #{trxPrice},</if>
<if test="usdtPrice != null">usdt_price = #{usdtPrice},</if>
<if test="monitorType != null">monitor_type = #{monitorType},</if>
<!-- <if test="apiKey != null">api_key = #{apiKey},</if>-->
<if test="bindPeriod != null">bind_period = #{bindPeriod},</if>
<if test="isValid != null">is_valid = #{isValid},</if>
<if test="idTgMessageInfo != null">id_tg_message_info = #{idTgMessageInfo},</if>
<if test="groupChatId != null">group_chat_id = #{groupChatId},</if>
<if test="comment != null">comment = #{comment},</if>
<if test="imageUrl != null">image_url = #{imageUrl},</if>
<if test="fcd != null">fcd = #{fcd},</if>
<if test="fcu != null">fcu = #{fcu},</if>
<if test="lcd != null">lcd = #{lcd},</if>

View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.PointRechargeOrderMapper">
<resultMap type="PointRechargeOrder" id="PointRechargeOrderResult">
<result property="idPointRechargeOrder" column="id_point_recharge_order" />
<result property="userId" column="user_id" />
<result property="orderNumber" column="order_number" />
<result property="amount" column="amount" />
<result property="exchangeRate" column="exchange_rate" />
<result property="points" column="points" />
<result property="status" column="status" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectPointRechargeOrderVo">
select id_point_recharge_order, user_id, order_number, amount, exchange_rate, points, status, create_by, create_time, update_by, update_time from point_recharge_order
</sql>
<select id="selectPointRechargeOrderList" parameterType="PointRechargeOrder" resultMap="PointRechargeOrderResult">
<include refid="selectPointRechargeOrderVo"/>
<where>
<if test="userId != null "> and user_id = #{userId}</if>
<if test="orderNumber != null and orderNumber != ''"> and order_number = #{orderNumber}</if>
<if test="amount != null "> and amount = #{amount}</if>
<if test="exchangeRate != null "> and exchange_rate = #{exchangeRate}</if>
<if test="points != null "> and points = #{points}</if>
<if test="status != null and status != ''"> and status = #{status}</if>
<if test="createBy != null and createBy != ''"> and create_by = #{createBy}</if>
<if test="params.beginCreateTime != null and params.beginCreateTime != '' and params.endCreateTime != null and params.endCreateTime != ''"> and create_time between #{params.beginCreateTime} and #{params.endCreateTime}</if>
<if test="updateBy != null and updateBy != ''"> and update_by = #{updateBy}</if>
<if test="updateTime != null "> and update_time = #{updateTime}</if>
</where>
</select>
<select id="selectPointRechargeOrderByIdPointRechargeOrder" parameterType="Long" resultMap="PointRechargeOrderResult">
<include refid="selectPointRechargeOrderVo"/>
where id_point_recharge_order = #{idPointRechargeOrder}
</select>
<insert id="insertPointRechargeOrder" parameterType="PointRechargeOrder" useGeneratedKeys="true" keyProperty="idPointRechargeOrder">
insert into point_recharge_order
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="userId != null">user_id,</if>
<if test="orderNumber != null">order_number,</if>
<if test="amount != null">amount,</if>
<if test="exchangeRate != null">exchange_rate,</if>
<if test="points != null">points,</if>
<if test="status != null">status,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="userId != null">#{userId},</if>
<if test="orderNumber != null">#{orderNumber},</if>
<if test="amount != null">#{amount},</if>
<if test="exchangeRate != null">#{exchangeRate},</if>
<if test="points != null">#{points},</if>
<if test="status != null">#{status},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
</trim>
</insert>
<update id="updatePointRechargeOrder" parameterType="PointRechargeOrder">
update point_recharge_order
<trim prefix="SET" suffixOverrides=",">
<if test="userId != null">user_id = #{userId},</if>
<if test="orderNumber != null">order_number = #{orderNumber},</if>
<if test="amount != null">amount = #{amount},</if>
<if test="exchangeRate != null">exchange_rate = #{exchangeRate},</if>
<if test="points != null">points = #{points},</if>
<if test="status != null">status = #{status},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
</trim>
where id_point_recharge_order = #{idPointRechargeOrder}
</update>
<delete id="deletePointRechargeOrderByIdPointRechargeOrder" parameterType="Long">
delete from point_recharge_order where id_point_recharge_order = #{idPointRechargeOrder}
</delete>
<delete id="deletePointRechargeOrderByIdPointRechargeOrders" parameterType="String">
delete from point_recharge_order where id_point_recharge_order in
<foreach item="idPointRechargeOrder" collection="array" open="(" separator="," close=")">
#{idPointRechargeOrder}
</foreach>
</delete>
</mapper>

View File

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SmsCountryPriceMapper">
<resultMap type="SmsCountryPrice" id="SmsCountryPriceResult">
<result property="idSmsCountryPrice" column="id_sms_country_price" />
<result property="countryId" column="country_id" />
<result property="areaCode" column="area_code" />
<result property="price" column="price" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectSmsCountryPriceVo">
select id_sms_country_price, country_id, area_code, price, create_by, create_time, update_by, update_time, remark from sms_country_price
</sql>
<select id="selectSmsCountryPriceList" parameterType="SmsCountryPrice" resultMap="SmsCountryPriceResult">
<include refid="selectSmsCountryPriceVo"/>
<where>
<if test="countryId != null "> and country_id = #{countryId}</if>
<if test="areaCode != null and areaCode != ''"> and area_code = #{areaCode}</if>
<if test="price != null "> and price = #{price}</if>
<if test="params.beginCreateTime != null and params.beginCreateTime != '' and params.endCreateTime != null and params.endCreateTime != ''"> and create_time between #{params.beginCreateTime} and #{params.endCreateTime}</if>
</where>
</select>
<select id="selectSmsCountryPriceByIdSmsCountryPrice" parameterType="Long" resultMap="SmsCountryPriceResult">
<include refid="selectSmsCountryPriceVo"/>
where id_sms_country_price = #{idSmsCountryPrice}
</select>
<insert id="insertSmsCountryPrice" parameterType="SmsCountryPrice">
insert into sms_country_price
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="idSmsCountryPrice != null">id_sms_country_price,</if>
<if test="countryId != null">country_id,</if>
<if test="areaCode != null">area_code,</if>
<if test="price != null">price,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="idSmsCountryPrice != null">#{idSmsCountryPrice},</if>
<if test="countryId != null">#{countryId},</if>
<if test="areaCode != null">#{areaCode},</if>
<if test="price != null">#{price},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateSmsCountryPrice" parameterType="SmsCountryPrice">
update sms_country_price
<trim prefix="SET" suffixOverrides=",">
<if test="countryId != null">country_id = #{countryId},</if>
<if test="areaCode != null">area_code = #{areaCode},</if>
<if test="price != null">price = #{price},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where id_sms_country_price = #{idSmsCountryPrice}
</update>
<delete id="deleteSmsCountryPriceByIdSmsCountryPrice" parameterType="Long">
delete from sms_country_price where id_sms_country_price = #{idSmsCountryPrice}
</delete>
<delete id="deleteSmsCountryPriceByIdSmsCountryPrices" parameterType="String">
delete from sms_country_price where id_sms_country_price in
<foreach item="idSmsCountryPrice" collection="array" open="(" separator="," close=")">
#{idSmsCountryPrice}
</foreach>
</delete>
<resultMap id="selectAllCountriesResultMap" type="com.ruoyi.common.core.domain.entity.CountryTbl">
<result column="country_id" property="countryId"/>
<result column="english_name" property="englishName"/>
<result column="chinese_name" property="chineseName"/>
<result column="two_digit_abbr" property="twoDigitAbbr"/>
<result column="three_digit_abbr" property="threeDigitAbbr"/>
<result column="area_code" property="areaCode"/>
</resultMap>
<select id="selectAllCountries" resultMap="selectAllCountriesResultMap">
select country_id, english_name, chinese_name, two_digit_abbr, three_digit_abbr, area_code
from country_tbl
</select>
<select id="selectCountryById" resultMap="selectAllCountriesResultMap">
select country_id, english_name, chinese_name, two_digit_abbr, three_digit_abbr, area_code
from country_tbl
where country_id = #{countryId}
</select>
</mapper>

View File

@ -11,13 +11,14 @@
<result property="smsBusiType" column="sms_busi_type" />
<result property="taskId" column="task_id" />
<result property="channelId" column="channel_id" />
<result property="country" column="country" />
<result property="price" column="price" />
<result property="preSummary" column="pre_summary" />
<result property="actSummary" column="act_summary" />
<result property="taskBeginTime" column="task_begin_time" />
<result property="completeTime" column="complete_time" />
<result property="fileName" column="file_name" />
<result property="filePath" column="file_path" />
<result property="fileMd5" column="file_md5" />
<result property="context" column="context" />
<result property="smsContentType" column="sms_content_type" />
<result property="taskStatus" column="task_status" />
@ -25,6 +26,7 @@
<result property="successCount" column="success_count" />
<result property="totalCount" column="total_count" />
<result property="issueCount" column="issue_count" />
<result property="settleStatus" column="settle_status" />
<result property="userId" column="user_id" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
@ -33,7 +35,7 @@
</resultMap>
<sql id="selectSmsTaskTblVo">
select id_sms_task, task_name, sms_busi_type, task_id, channel_id, price, pre_summary, task_begin_time, complete_time, file_name, file_path, file_md5, context, sms_content_type, task_status, success_rate, success_count, total_count, issue_count, s.user_id, s.create_by, s.create_time, s.update_by, s.update_time from sms_task_tbl s
select id_sms_task, task_name, sms_busi_type, task_id, channel_id,country, price, pre_summary,act_summary, task_begin_time, complete_time, file_name, file_path, context, sms_content_type, task_status, success_rate, success_count, total_count, issue_count,settle_status, s.user_id, s.create_by, s.create_time, s.update_by, s.update_time from sms_task_tbl s
</sql>
<select id="selectSmsTaskTblList" parameterType="SmsTaskTbl" resultMap="SmsTaskTblResult">
@ -62,13 +64,14 @@
<if test="smsBusiType != null">sms_busi_type,</if>
<if test="taskId != null">task_id,</if>
<if test="channelId != null">channel_id,</if>
<if test="country != null">country,</if>
<if test="price != null">price,</if>
<if test="preSummary != null">pre_summary,</if>
<if test="actSummary != null">act_summary,</if>
<if test="taskBeginTime != null">task_begin_time,</if>
<if test="completeTime != null">complete_time,</if>
<if test="fileName != null">file_name,</if>
<if test="filePath != null">file_path,</if>
<if test="fileMd5 != null">file_md5,</if>
<if test="context != null">context,</if>
<if test="smsContentType != null">sms_content_type,</if>
<if test="taskStatus != null">task_status,</if>
@ -77,6 +80,7 @@
<if test="totalCount != null">total_count,</if>
<if test="issueCount != null">issue_count,</if>
<if test="userId != null">user_id,</if>
<if test="settleStatus != null">settle_status,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
@ -87,13 +91,14 @@
<if test="smsBusiType != null">#{smsBusiType},</if>
<if test="taskId != null">#{taskId},</if>
<if test="channelId != null">#{channelId},</if>
<if test="country != null">#{country},</if>
<if test="price != null">#{price},</if>
<if test="preSummary != null">#{preSummary},</if>
<if test="actSummary != null">#{actSummary},</if>
<if test="taskBeginTime != null">#{taskBeginTime},</if>
<if test="completeTime != null">#{completeTime},</if>
<if test="fileName != null">#{fileName},</if>
<if test="filePath != null">#{filePath},</if>
<if test="fileMd5 != null">#{fileMd5},</if>
<if test="context != null">#{context},</if>
<if test="smsContentType != null">#{smsContentType},</if>
<if test="taskStatus != null">#{taskStatus},</if>
@ -102,6 +107,7 @@
<if test="totalCount != null">#{totalCount},</if>
<if test="issueCount != null">#{issueCount},</if>
<if test="userId != null">#{userId},</if>
<if test="settleStatus != null">#{settleStatus},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
@ -116,13 +122,14 @@
<if test="smsBusiType != null">sms_busi_type = #{smsBusiType},</if>
<if test="taskId != null">task_id = #{taskId},</if>
<if test="channelId != null">channel_id = #{channelId},</if>
<if test="country != null">country = #{country},</if>
<if test="price != null">price = #{price},</if>
<if test="preSummary != null">pre_summary = #{preSummary},</if>
<if test="actSummary != null">act_summary = #{actSummary},</if>
<if test="taskBeginTime != null">task_begin_time = #{taskBeginTime},</if>
<if test="completeTime != null">complete_time = #{completeTime},</if>
<if test="fileName != null">file_name = #{fileName},</if>
<if test="filePath != null">file_path = #{filePath},</if>
<if test="fileMd5 != null">file_md5 = #{fileMd5},</if>
<if test="context != null">context = #{context},</if>
<if test="smsContentType != null">sms_content_type = #{smsContentType},</if>
<if test="taskStatus != null">task_status = #{taskStatus},</if>
@ -131,6 +138,7 @@
<if test="totalCount != null">total_count = #{totalCount},</if>
<if test="issueCount != null">issue_count = #{issueCount},</if>
<if test="userId != null">user_id = #{userId},</if>
<if test="settleStatus != null">settle_status = #{settleStatus},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
@ -139,6 +147,7 @@
where id_sms_task = #{idSmsTask}
</update>
<delete id="deleteSmsTaskTblByIdSmsTask" parameterType="Long">
delete from sms_task_tbl where id_sms_task = #{idSmsTask}
</delete>
@ -163,11 +172,12 @@
<if test="channelId != null">channel_id = #{channelId},</if>
<if test="price != null">price = #{price},</if>
<if test="preSummary != null">pre_summary = #{preSummary},</if>
<if test="actSummary != null">act_summary = #{actSummary},</if>
<if test="taskBeginTime != null">task_begin_time = #{taskBeginTime},</if>
<if test="completeTime != null">complete_time = #{completeTime},</if>
<if test="fileName != null">file_name = #{fileName},</if>
<if test="filePath != null">file_path = #{filePath},</if>
<if test="fileMd5 != null">file_md5 = #{fileMd5},</if>
<if test="context != null">context = #{context},</if>
<if test="smsContentType != null">sms_content_type = #{smsContentType},</if>
<if test="taskStatus != null">task_status = #{taskStatus},</if>
@ -175,6 +185,7 @@
<if test="successCount != null">success_count = #{successCount},</if>
<if test="totalCount != null">total_count = #{totalCount},</if>
<if test="issueCount != null">issue_count = #{issueCount},</if>
<if test="settleStatus != null">settle_status = #{settleStatus},</if>
<if test="userId != null">user_id = #{userId},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.UserPointMapper">
<resultMap type="UserPoint" id="UserPointResult">
<result property="idUserPoint" column="id_user_point" />
<result property="userId" column="user_id" />
<result property="pointBalance" column="point_balance" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectUserPointVo">
select id_user_point, t.user_id, point_balance, t.create_by, t.create_time, t.update_by, t.update_time from user_point t
</sql>
<select id="selectUserPointList" parameterType="UserPoint" resultMap="UserPointResult">
<include refid="selectUserPointVo"/>
left join sys_user u on t.user_id = u.user_id
<where> 1 = 1
<if test="userId != null "> and t.user_id = #{userId}</if>
<if test="pointBalance != null "> and point_balance = #{pointBalance}</if>
</where>
<!-- 数据范围过滤 -->
${params.dataScope}
</select>
<select id="selectUserPointByIdUserPoint" parameterType="Long" resultMap="UserPointResult">
<include refid="selectUserPointVo"/>
where id_user_point = #{idUserPoint}
</select>
<insert id="insertUserPoint" parameterType="UserPoint" useGeneratedKeys="true" keyProperty="idUserPoint">
insert into user_point
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="userId != null">user_id,</if>
<if test="pointBalance != null">point_balance,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="userId != null">#{userId},</if>
<if test="pointBalance != null">#{pointBalance},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
</trim>
</insert>
<update id="updateUserPoint" parameterType="UserPoint">
update user_point
<trim prefix="SET" suffixOverrides=",">
<if test="userId != null">user_id = #{userId},</if>
<if test="pointBalance != null">point_balance = #{pointBalance},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
</trim>
where id_user_point = #{idUserPoint}
</update>
<delete id="deleteUserPointByIdUserPoint" parameterType="Long">
delete from user_point where id_user_point = #{idUserPoint}
</delete>
<delete id="deleteUserPointByIdUserPoints" parameterType="String">
delete from user_point where id_user_point in
<foreach item="idUserPoint" collection="array" open="(" separator="," close=")">
#{idUserPoint}
</foreach>
</delete>
</mapper>