diff --git a/pom.xml b/pom.xml index 377320203..b160bf485 100644 --- a/pom.xml +++ b/pom.xml @@ -30,6 +30,8 @@ 2.13.0 4.1.2 2.3 + 1.5.5.Final + 1.18.30 @@ -193,6 +195,21 @@ ${ruoyi.version} + + org.mapstruct + mapstruct + ${org.mapstruct.version} + + + org.mapstruct + mapstruct-processor + ${org.mapstruct.version} + + + org.projectlombok + lombok-mapstruct-binding + 0.2.0 + diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index 99efa6b2b..1ec03bf13 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -79,6 +79,19 @@ 1.18.30 + + org.mapstruct + mapstruct + + + org.mapstruct + mapstruct-processor + + + org.projectlombok + lombok-mapstruct-binding + + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/PointRechargeOrderController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/PointRechargeOrderController.java new file mode 100644 index 000000000..9ac659d14 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/PointRechargeOrderController.java @@ -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 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 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 list = pointRechargeOrderService.selectPointRechargeOrderList(pointRechargeOrder); + ExcelUtil util = new ExcelUtil(PointRechargeOrder.class); + return util.exportExcel(list, "群发充值管理数据"); + } + + /** + * 新增群发充值管理 + */ + @GetMapping("/add") + public String add(ModelMap mmap) + { + List sysUserList = sysUserService.selectUserList(new SysUser()); + mmap.put("sysUserList",sysUserList); + return prefix + "/add"; + } + /** + * 新增群发充值管理 + */ + @RequiresPermissions("sms:point:recharge") + @GetMapping("/recharge") + public String rechage(ModelMap mmap) + { + /*List 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 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 rechargeOrder(PointRechargeOrder pointRechargeOrder) + { + Map 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 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)); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/SmsCountryPriceController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/SmsCountryPriceController.java new file mode 100644 index 000000000..fbb976bd2 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/SmsCountryPriceController.java @@ -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 countries = smsCountryPriceService.selectAllCountries(); + mmp.put("countries", countries); + return prefix + "/country"; + } + + /** + * 查询群发国家单价配置列表 + */ + @RequiresPermissions("sms:country:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(SmsCountryPrice smsCountryPrice) { + startPage(); + List 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 list = smsCountryPriceService.selectSmsCountryPriceList(smsCountryPrice); + ExcelUtil util = new ExcelUtil(SmsCountryPrice.class); + return util.exportExcel(list, "群发国家单价配置数据"); + } + + /** + * 新增群发国家单价配置 + */ + @GetMapping("/add") + public String add(ModelMap mmp) { + List 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 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)); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/SmsMonitorAddressInfoController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/SmsMonitorAddressInfoController.java new file mode 100644 index 000000000..be68b1849 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/SmsMonitorAddressInfoController.java @@ -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 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 list = monitorAddressInfoService.selectMonitorAddressInfoList(monitorAddressInfo); + ExcelUtil util = new ExcelUtil(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)); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/UserPointController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/UserPointController.java new file mode 100644 index 000000000..27a34b388 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/UserPointController.java @@ -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 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 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 list = userPointService.selectUserPointList(userPoint); + ExcelUtil util = new ExcelUtil(UserPoint.class); + return util.exportExcel(list, "用户积分数据"); + } + + /** + * 新增用户积分 + */ + @GetMapping("/add") + public String add(ModelMap mmap) + { + List 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 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)); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/WSSmsTaskTblController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/WSSmsTaskTblController.java index 0ad5c572d..b561834dc 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/WSSmsTaskTblController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/WSSmsTaskTblController.java @@ -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; /** * WS短信任务配置Controller - * + * * @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 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 list = smsTaskTblService.selectSmsTaskTblList(smsTaskTbl); - ExcelUtil util = new ExcelUtil(SmsTaskTbl.class); - return util.exportExcel(list, "WS短信任务配置数据"); + List smsTaskTblPreSummaryVOList = SmsTaskTblConverter.INSTANCE.to(list); + ExcelUtil util = new ExcelUtil(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 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 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 exportTaskDetail(@PathVariable("idSmsTask") Long idSmsTask) - { + public ResponseEntity 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 list = smsTaskTblService.selectSmsTaskTblList(smsTaskTbl); + List smsTaskTblPreSummaryVOList = SmsTaskTblConverter.INSTANCE.toSmsTaskTblSummaryVOList(list); + ExcelUtil util = new ExcelUtil(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)); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/converter/SmsTaskTblConverter.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/converter/SmsTaskTblConverter.java new file mode 100644 index 000000000..45796779f --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/converter/SmsTaskTblConverter.java @@ -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 to(List smsTaskTblList); + + SmsTaskTblSummaryVO toSmsTaskTblSummaryVO(SmsTaskTbl smsTaskTbl); + List toSmsTaskTblSummaryVOList(List smsTaskTblList); +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/converter/SmsTaskTblVOConverter.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/converter/SmsTaskTblVOConverter.java new file mode 100644 index 000000000..1969d6e02 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/sms/converter/SmsTaskTblVOConverter.java @@ -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); +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/DefaultConfiguration.java b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/DefaultConfiguration.java new file mode 100644 index 000000000..154524a6a --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/DefaultConfiguration.java @@ -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); + } +} diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 3f7281aea..d77eb7e02 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -9,7 +9,7 @@ ruoyi: # 实例演示开关 demoEnabled: true # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /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 \ No newline at end of file + chatid: -1002058165663 + + +snowflake: + dataCenterId: 1 + workerId: 1 \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js b/ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js index f77d5cf41..6a6170e77 100644 --- a/ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js +++ b/ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js @@ -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(); diff --git a/ruoyi-admin/src/main/resources/templates/sms/country/add.html b/ruoyi-admin/src/main/resources/templates/sms/country/add.html new file mode 100644 index 000000000..ae57e62f4 --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/sms/country/add.html @@ -0,0 +1,50 @@ + + + + + + +
+
+
+ + +
+ + +
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/sms/country/country.html b/ruoyi-admin/src/main/resources/templates/sms/country/country.html new file mode 100644 index 000000000..04561065a --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/sms/country/country.html @@ -0,0 +1,144 @@ + + + + + + +
+
+
+
+
+ +
+
+
+ + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/sms/country/edit.html b/ruoyi-admin/src/main/resources/templates/sms/country/edit.html new file mode 100644 index 000000000..58b60781e --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/sms/country/edit.html @@ -0,0 +1,47 @@ + + + + + + +
+
+ +
+ +
+ + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/sms/monitor/add.html b/ruoyi-admin/src/main/resources/templates/sms/monitor/add.html new file mode 100644 index 000000000..39591cd9e --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/sms/monitor/add.html @@ -0,0 +1,104 @@ + + + + + + + +
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+ +
+ + +
+
+ 选择文件重新选择 + + × +
+
+
+ + + + + +
+ +
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/sms/monitor/edit.html b/ruoyi-admin/src/main/resources/templates/sms/monitor/edit.html new file mode 100644 index 000000000..b47d6122f --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/sms/monitor/edit.html @@ -0,0 +1,116 @@ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + + + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+
+ + + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/sms/monitor/monitor.html b/ruoyi-admin/src/main/resources/templates/sms/monitor/monitor.html new file mode 100644 index 000000000..627eb330c --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/sms/monitor/monitor.html @@ -0,0 +1,200 @@ + + + + + + +
+
+
+
+
+
    +
  • + + +
  • + +
  • + + +
  • + +
  • + + + - + +
  • +
  • +  搜索 +  重置 +
  • +
+
+
+
+ + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/sms/point/add.html b/ruoyi-admin/src/main/resources/templates/sms/point/add.html new file mode 100644 index 000000000..f11011a46 --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/sms/point/add.html @@ -0,0 +1,49 @@ + + + + + + +
+
+
+ +
+ + +
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/sms/point/edit.html b/ruoyi-admin/src/main/resources/templates/sms/point/edit.html new file mode 100644 index 000000000..8043cb264 --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/sms/point/edit.html @@ -0,0 +1,44 @@ + + + + + + +
+
+ +
+ +
+ + +
+
+ +
+ +
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/sms/point/point.html b/ruoyi-admin/src/main/resources/templates/sms/point/point.html new file mode 100644 index 000000000..5330cbb47 --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/sms/point/point.html @@ -0,0 +1,150 @@ + + + + + + +
+
+
+
+
+
    + +
  • + + +
  • +
  • + + +
  • + +
  • + + +
  • + +
  • + + + - + +
  • + +
+
+
+
+ + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/sms/point/recharge.html b/ruoyi-admin/src/main/resources/templates/sms/point/recharge.html new file mode 100644 index 000000000..e49ab116b --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/sms/point/recharge.html @@ -0,0 +1,117 @@ + + + + + + + +
+
+ +
+
1
+
创建充值订单
+
+
+ +
+
2
+
充值订单信息
+
+
+
+
+
+ +
+ +
+
+ +
+ +
+
USDT
+
+ +
+
+       + +
+
+
+
+ + + + diff --git a/ruoyi-admin/src/main/resources/templates/sms/point/rechargeOrder.html b/ruoyi-admin/src/main/resources/templates/sms/point/rechargeOrder.html new file mode 100644 index 000000000..7349007ff --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/sms/point/rechargeOrder.html @@ -0,0 +1,142 @@ + + + + + + + +
+
+ +
+
1
+
创建充值订单
+
+
+ +
+
2
+
充值订单信息
+
+
+
+
+
+ +
+ +
+ + +
+ + +
+
+ + +
+ +
+ + +
+
+
+ QR Code +
+
+
+
+
    +
  • 到账金额 必须确认为 USDT,否则充值不成功。
  • +
  • 请在 60分钟 内完成转账。
  • +
  • 交易成功后会自动充值到账。
  • +
  • 如因转账金额错误导致的充值失败,客服将在 14:00-15:00 时间段集中核对处理。
  • +
+
+
+ + +
+
+ + + + diff --git a/ruoyi-admin/src/main/resources/templates/sms/task/ws/add.html b/ruoyi-admin/src/main/resources/templates/sms/task/ws/add.html index bda9fdf2d..6f08e1475 100644 --- a/ruoyi-admin/src/main/resources/templates/sms/task/ws/add.html +++ b/ruoyi-admin/src/main/resources/templates/sms/task/ws/add.html @@ -8,42 +8,33 @@
-
+
- +
- - -
-
- 选择文件重新选择 - - × -
+
+
+ 选择文件重新选择 + + × +
+ +
+ +
+ +
+
+
@@ -82,7 +73,6 @@ - \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/sms/task/ws/addBatch.html b/ruoyi-admin/src/main/resources/templates/sms/task/ws/addBatch.html new file mode 100644 index 000000000..017444871 --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/sms/task/ws/addBatch.html @@ -0,0 +1,143 @@ + + + + + + + + + +
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ + +
+
+ 选择文件重新选择 + + × +
+
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+ +
+ +
+
+ + +
+
+
+
+ +
+ +
+
+
+ +
+
+ + +
+
+
+ + +
+
+   + +
+
+
+ + + + + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/sms/task/ws/edit.html b/ruoyi-admin/src/main/resources/templates/sms/task/ws/edit.html index 1d43c9ee5..0f1a6395b 100644 --- a/ruoyi-admin/src/main/resources/templates/sms/task/ws/edit.html +++ b/ruoyi-admin/src/main/resources/templates/sms/task/ws/edit.html @@ -14,18 +14,16 @@
-
- +
+
- +
-
- +
+
- +
@@ -45,7 +43,7 @@
-
+ +
diff --git a/ruoyi-admin/src/main/resources/templates/sms/task/ws/task.html b/ruoyi-admin/src/main/resources/templates/sms/task/ws/task.html index 5ae10cd5f..20085334a 100644 --- a/ruoyi-admin/src/main/resources/templates/sms/task/ws/task.html +++ b/ruoyi-admin/src/main/resources/templates/sms/task/ws/task.html @@ -40,6 +40,9 @@ 添加 + + 批量添加 + 批量修改 @@ -49,9 +52,9 @@ 导出 - + 强制完成 @@ -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: '创建者', diff --git a/ruoyi-admin/src/main/resources/templates/sms/task/ws/taskSummary.html b/ruoyi-admin/src/main/resources/templates/sms/task/ws/taskSummary.html new file mode 100644 index 000000000..b8b2775e4 --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/sms/task/ws/taskSummary.html @@ -0,0 +1,208 @@ + + + + + + +
+
+
+
+
+
    +
  • + + +
  • +
  • + + +
  • +
  • + + + - + +
  • +
  • +  搜索 +  重置 +
  • +
+
+
+
+ + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/sms/user/add.html b/ruoyi-admin/src/main/resources/templates/sms/user/add.html new file mode 100644 index 000000000..81c5f4440 --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/sms/user/add.html @@ -0,0 +1,40 @@ + + + + + + +
+
+
+ +
+ + +
+
+
+ +
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/sms/user/edit.html b/ruoyi-admin/src/main/resources/templates/sms/user/edit.html new file mode 100644 index 000000000..c6583a007 --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/sms/user/edit.html @@ -0,0 +1,41 @@ + + + + + + +
+
+ +
+ +
+ + +
+
+
+ +
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/templates/sms/user/user.html b/ruoyi-admin/src/main/resources/templates/sms/user/user.html new file mode 100644 index 000000000..3a534d523 --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/sms/user/user.html @@ -0,0 +1,110 @@ + + + + + + +
+
+
+
+
+ +
+
+
+ + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/CountryTbl.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/CountryTbl.java new file mode 100644 index 000000000..36957dfc3 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/CountryTbl.java @@ -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; +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/MonitorAddressInfo.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/MonitorAddressInfo.java index 8dcaec545..12be49eb7 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/MonitorAddressInfo.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/MonitorAddressInfo.java @@ -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") diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/PointRechargeOrder.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/PointRechargeOrder.java new file mode 100644 index 000000000..19449fdb0 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/PointRechargeOrder.java @@ -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(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SmsCountryPrice.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SmsCountryPrice.java new file mode 100644 index 000000000..a760922e1 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SmsCountryPrice.java @@ -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(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SmsTaskTbl.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SmsTaskTbl.java index fb7a6eec1..77d8ee658 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SmsTaskTbl.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SmsTaskTbl.java @@ -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; diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/UserPoint.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/UserPoint.java new file mode 100644 index 000000000..0f07f9458 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/UserPoint.java @@ -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(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/SmsTaskTblPreSummaryVO.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/SmsTaskTblPreSummaryVO.java new file mode 100644 index 000000000..e0ee2626f --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/SmsTaskTblPreSummaryVO.java @@ -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; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/SmsTaskTblSummaryVO.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/SmsTaskTblSummaryVO.java new file mode 100644 index 000000000..e3c8e928c --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/SmsTaskTblSummaryVO.java @@ -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; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/SmsTaskTblVO.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/SmsTaskTblVO.java new file mode 100644 index 000000000..b5584a1ab --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/vo/SmsTaskTblVO.java @@ -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 smsTaskTblList; + + + private long lineCount ; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/SnowFlakeUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/SnowFlakeUtil.java new file mode 100644 index 000000000..98737a73d --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/SnowFlakeUtil.java @@ -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(); +// } + + + + + // 初始时间戳(纪年),可用雪花算法服务上线时间戳的值 + // 1691903735000L:2023-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()); +// +// } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java index 51fa59c84..278670d94 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java @@ -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); + } + /** * 文件大小校验 * diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MonitorAddressInfoVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MonitorAddressInfoVO.java index 7afc02e68..3ffec31ea 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MonitorAddressInfoVO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/MonitorAddressInfoVO.java @@ -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") diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/handler/EnergyTenantTransferHandler.java b/ruoyi-system/src/main/java/com/ruoyi/system/handler/EnergyTenantTransferHandler.java index c3d2ccbca..fe39abbac 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/handler/EnergyTenantTransferHandler.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/handler/EnergyTenantTransferHandler.java @@ -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 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", "已委托"); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/handler/GetSmsDetailTaskHandler.java b/ruoyi-system/src/main/java/com/ruoyi/system/handler/GetSmsDetailTaskHandler.java index c3c2a50ad..bf92c03d0 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/handler/GetSmsDetailTaskHandler.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/handler/GetSmsDetailTaskHandler.java @@ -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 smsTaskTblList) { List 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); }); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/PointRechargeOrderMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/PointRechargeOrderMapper.java new file mode 100644 index 000000000..c62369ad8 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/PointRechargeOrderMapper.java @@ -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 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); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SmsCountryPriceMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SmsCountryPriceMapper.java new file mode 100644 index 000000000..80c802357 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SmsCountryPriceMapper.java @@ -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 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 selectAllCountries(); + + CountryTbl selectCountryById(Long countryId); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserPointMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserPointMapper.java new file mode 100644 index 000000000..e5f15689c --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserPointMapper.java @@ -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 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); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IPointRechargeOrderService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IPointRechargeOrderService.java new file mode 100644 index 000000000..70d7a2b7d --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IPointRechargeOrderService.java @@ -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 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); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISmsCountryPriceService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISmsCountryPriceService.java new file mode 100644 index 000000000..675a13802 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISmsCountryPriceService.java @@ -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 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 selectAllCountries(); + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISmsTaskTblService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISmsTaskTblService.java index 89c9e7f07..0d9892af6 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISmsTaskTblService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISmsTaskTblService.java @@ -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); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IUserPointService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IUserPointService.java new file mode 100644 index 000000000..ec49a4877 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IUserPointService.java @@ -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 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); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/PointRechargeOrderServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/PointRechargeOrderServiceImpl.java new file mode 100644 index 000000000..824b82577 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/PointRechargeOrderServiceImpl.java @@ -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 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 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 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; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SmsCountryPriceServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SmsCountryPriceServiceImpl.java new file mode 100644 index 000000000..1810816f6 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SmsCountryPriceServiceImpl.java @@ -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 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 selectAllCountries() { + return smsCountryPriceMapper.selectAllCountries(); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SmsTaskTblServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SmsTaskTblServiceImpl.java index 4197a3aa4..56547a8e5 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SmsTaskTblServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SmsTaskTblServiceImpl.java @@ -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 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 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 getSmsCountryPrices(String phoneNumber) { + Preconditions.checkState(phoneNumber.length() > 2, "首行号码位数不够"); + String areaCode = phoneNumber.substring(0, 2); + SmsCountryPrice smsCountryPriceParam = new SmsCountryPrice(); + smsCountryPriceParam.setAreaCode(areaCode); + List 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 idsList = Arrays.asList(ids.split(",")); - List smsTaskTblList = smsTaskTblMapper.selectSmsTaskTbl(idsList); + List smsTaskTblList = smsTaskTblMapper.selectSmsTaskTbl(idsList); List 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 idsList = Arrays.asList(ids.split(",")); - List smsTaskTblList = smsTaskTblMapper.selectSmsTaskTbl(idsList); + List 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 smsCountryPrices = getSmsCountryPrices(smsTaskTblVO.getPhoneNumber()); + + SmsCountryPrice smsCountryPrice = smsCountryPrices.get(0); + BigDecimal price = smsCountryPrice.getPrice(); + CountryTbl countryTbl = smsCountryPriceMapper.selectCountryById(smsCountryPrice.getCountryId()); + String chineseName = countryTbl.getChineseName(); + List 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); + } + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserPointServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserPointServiceImpl.java new file mode 100644 index 000000000..172a37ed4 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserPointServiceImpl.java @@ -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 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); + } +} diff --git a/ruoyi-system/src/main/resources/mapper/account/MonitorAddressInfoMapper.xml b/ruoyi-system/src/main/resources/mapper/account/MonitorAddressInfoMapper.xml index 98cb8204d..a075d809b 100644 --- a/ruoyi-system/src/main/resources/mapper/account/MonitorAddressInfoMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/account/MonitorAddressInfoMapper.xml @@ -18,6 +18,7 @@ + @@ -25,7 +26,7 @@ - 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 + insert into monitor_address_info @@ -64,12 +66,12 @@ trx_price, usdt_price, monitor_type, - bind_period, is_valid, id_tg_message_info, group_chat_id, comment, + image_url, fcd, fcu, lcd, @@ -83,12 +85,12 @@ #{trxPrice}, #{usdtPrice}, #{monitorType}, - #{bindPeriod}, #{isValid}, #{idTgMessageInfo}, #{groupChatId}, #{comment}, + #{imageUrl}, #{fcd}, #{fcu}, #{lcd}, @@ -106,12 +108,12 @@ trx_price = #{trxPrice}, usdt_price = #{usdtPrice}, monitor_type = #{monitorType}, - bind_period = #{bindPeriod}, is_valid = #{isValid}, id_tg_message_info = #{idTgMessageInfo}, group_chat_id = #{groupChatId}, comment = #{comment}, + image_url = #{imageUrl}, fcd = #{fcd}, fcu = #{fcu}, lcd = #{lcd}, diff --git a/ruoyi-system/src/main/resources/mapper/sms/PointRechargeOrderMapper.xml b/ruoyi-system/src/main/resources/mapper/sms/PointRechargeOrderMapper.xml new file mode 100644 index 000000000..30adc8f5d --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/sms/PointRechargeOrderMapper.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + 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 + + + + + + + + insert into point_recharge_order + + user_id, + order_number, + amount, + exchange_rate, + points, + status, + create_by, + create_time, + update_by, + update_time, + + + #{userId}, + #{orderNumber}, + #{amount}, + #{exchangeRate}, + #{points}, + #{status}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update point_recharge_order + + user_id = #{userId}, + order_number = #{orderNumber}, + amount = #{amount}, + exchange_rate = #{exchangeRate}, + points = #{points}, + status = #{status}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id_point_recharge_order = #{idPointRechargeOrder} + + + + delete from point_recharge_order where id_point_recharge_order = #{idPointRechargeOrder} + + + + delete from point_recharge_order where id_point_recharge_order in + + #{idPointRechargeOrder} + + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/sms/SmsCountryPriceMapper.xml b/ruoyi-system/src/main/resources/mapper/sms/SmsCountryPriceMapper.xml new file mode 100644 index 000000000..11c31faf8 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/sms/SmsCountryPriceMapper.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + select id_sms_country_price, country_id, area_code, price, create_by, create_time, update_by, update_time, remark from sms_country_price + + + + + + + + insert into sms_country_price + + id_sms_country_price, + country_id, + area_code, + price, + create_by, + create_time, + update_by, + update_time, + remark, + + + #{idSmsCountryPrice}, + #{countryId}, + #{areaCode}, + #{price}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{remark}, + + + + + update sms_country_price + + country_id = #{countryId}, + area_code = #{areaCode}, + price = #{price}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + remark = #{remark}, + + where id_sms_country_price = #{idSmsCountryPrice} + + + + delete from sms_country_price where id_sms_country_price = #{idSmsCountryPrice} + + + + delete from sms_country_price where id_sms_country_price in + + #{idSmsCountryPrice} + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-system/src/main/resources/mapper/sms/SmsTaskTblMapper.xml b/ruoyi-system/src/main/resources/mapper/sms/SmsTaskTblMapper.xml index 6efdd4b52..fcbf4e11e 100644 --- a/ruoyi-system/src/main/resources/mapper/sms/SmsTaskTblMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/sms/SmsTaskTblMapper.xml @@ -11,13 +11,14 @@ + + - @@ -25,6 +26,7 @@ + @@ -33,7 +35,7 @@ - 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 + + left join sys_user u on t.user_id = u.user_id + 1 = 1 + and t.user_id = #{userId} + and point_balance = #{pointBalance} + + + ${params.dataScope} + + + + + + insert into user_point + + user_id, + point_balance, + create_by, + create_time, + update_by, + update_time, + + + #{userId}, + #{pointBalance}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + + + + + update user_point + + user_id = #{userId}, + point_balance = #{pointBalance}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where id_user_point = #{idUserPoint} + + + + delete from user_point where id_user_point = #{idUserPoint} + + + + delete from user_point where id_user_point in + + #{idUserPoint} + + + + \ No newline at end of file