Ver código fonte

一卡通短信平台对接,学员充值限制

xiari 2 meses atrás
pai
commit
0dd3a9f8ac

+ 91 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sms/AesEncryptUtil.java

@@ -0,0 +1,91 @@
+package org.dromara.common.core.utils.sms;
+
+import cn.hutool.core.codec.Base64;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.SecureRandom;
+
+/**
+ * AES 加密工具类
+ *
+ * @author system
+ */
+@Slf4j
+public class AesEncryptUtil {
+
+    private static final String ALGORITHM = "AES";
+    private static final String DEFAULT_KEY = "unicom-swdx-aes-key"; // 默认密钥,建议从配置文件读取
+
+    /**
+     * AES 加密
+     *
+     * @param content 需要加密的内容
+     * @param password 加密密码
+     * @return 加密后的字符串
+     */
+    public static String encrypt(String content, String password) {
+        try {
+            KeyGenerator kgen = KeyGenerator.getInstance(ALGORITHM);
+            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
+            secureRandom.setSeed(password.getBytes());
+            kgen.init(128, secureRandom);
+            SecretKey secretKey = kgen.generateKey();
+            byte[] enCodeFormat = secretKey.getEncoded();
+            SecretKeySpec key = new SecretKeySpec(enCodeFormat, ALGORITHM);
+            Cipher cipher = Cipher.getInstance(ALGORITHM);
+            byte[] byteContent = content.getBytes("utf-8");
+            cipher.init(Cipher.ENCRYPT_MODE, key);
+            byte[] result = cipher.doFinal(byteContent);
+            return Base64.encode(result);
+        } catch (Exception e) {
+            log.error("AES加密失败", e);
+            throw new RuntimeException("AES加密失败", e);
+        }
+    }
+
+    /**
+     * AES 解密
+     *
+     * @param content 待解密内容
+     * @param password 解密密码
+     * @return 解密后的字符串
+     */
+    public static String decrypt(String content, String password) {
+        try {
+            KeyGenerator kgen = KeyGenerator.getInstance(ALGORITHM);
+            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
+            secureRandom.setSeed(password.getBytes());
+            kgen.init(128, secureRandom);
+            SecretKey secretKey = kgen.generateKey();
+            byte[] enCodeFormat = secretKey.getEncoded();
+            SecretKeySpec key = new SecretKeySpec(enCodeFormat, ALGORITHM);
+            Cipher cipher = Cipher.getInstance(ALGORITHM);
+            cipher.init(Cipher.DECRYPT_MODE, key);
+            byte[] result = cipher.doFinal(Base64.decode(content));
+            return new String(result, "utf-8");
+        } catch (Exception e) {
+            log.error("AES解密失败", e);
+            throw new RuntimeException("AES解密失败", e);
+        }
+    }
+
+    /**
+     * 使用默认密钥加密
+     */
+    public static String encrypt(String content) {
+        return encrypt(content, DEFAULT_KEY);
+    }
+
+    /**
+     * 使用默认密钥解密
+     */
+    public static String decrypt(String content) {
+        return decrypt(content, DEFAULT_KEY);
+    }
+
+
+}

+ 93 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sms/SmsUtil.java

@@ -0,0 +1,93 @@
+package org.dromara.common.core.utils.sms;
+
+import cn.hutool.http.HttpRequest;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.domain.model.ErrorInfo;
+
+@Slf4j
+public class SmsUtil {
+
+//    @Value("${sms.gateway.systemCode:SYS004}")
+//    private String systemCode;
+//
+//    @Value("${sms.gateway.secret:afcd53c8cfdcfb2b150238a783a04d355697d84857dacbd931522fa8ade94b2d}")
+//    private String secret;
+//
+//    @Value("${sms.gateway.url:http://172.16.137.140:48088/system/sms-gateway/send}") // http://59.231.239.52:48088/system/sms-gateway/send
+//    private String url;
+
+
+    public static boolean send(String smsUrl, String systemCode, String secret, String desMobile, String content) {
+        try {
+            String systemKey = generateSystemKey(systemCode, secret);
+
+            JSONObject body = new JSONObject();
+            body.put("systemKey", systemKey);
+            body.put("desMobile", desMobile);
+            body.put("content", content);
+            body.put("CpPassword", "220324");
+            body.put("CpName", "fzgj");
+            body.put("userId", "test_user_001");
+            body.put("ExtCode", "10010");
+
+
+            String response = HttpRequest.post(smsUrl)
+                .header("Content-Type", "application/json")
+                .body(body.toJSONString())
+                .execute().body();
+
+            JSONObject result = JSONObject.parseObject(response);
+            JSONObject data = result.getJSONObject("data");
+            if (result.getInteger("code") != null && result.getInteger("code") == 0
+                && data != null && "0".equals(data.getString("code"))) {
+                log.info("短信发送成功: mobile={}, content={}, smsid={}", desMobile, content, data.getString("smsid"));
+                return true;
+            } else {
+                log.error("短信发送失败: mobile={}, response={}", desMobile, response);
+                return false;
+            }
+        } catch (Exception e) {
+            log.error("短信发送异常: mobile={}", desMobile, e);
+            return false;
+        }
+    }
+
+    public static String generateSystemKey(String systemCode, String secret) {
+        long timestamp = System.currentTimeMillis();
+        String data = systemCode + ":" + timestamp;
+        String signature = AesEncryptUtil.encrypt(data, secret);
+        return systemCode + ":" + timestamp + ":" + signature;
+    }
+
+    public static void main(String[] args) {
+        String systemCode = "SYS004";
+        String secret = "afcd53c8cfdcfb2b150238a783a04d355697d84857dacbd931522fa8ade94b2d";
+        String url = "http://172.16.137.140:48088/system/sms-gateway/send";
+
+
+        String message = "【湖南省委党校】" + " 您好:\n" +
+            "欢迎您参加【普通培训班】培训!"+ System.currentTimeMillis();
+
+        String message2 = "【湖南省委党校】您的登录验证码是:111,有效期3分钟,请勿泄露给他人。";
+
+        String message3 = String.format("【湖南省委党校】\n尊敬的【%s】:\n  欢迎您参加【%s】培训!\n  请去前台办理入住手续。" , "小王", "普通班");
+
+        String message4 = "【湖南省委党校】您好:\n" +
+            "    本次操作的验证码为:406899,您正在使用短信办理自助业务,有效期1分钟";
+
+        String message5 = "【湖南省委党校】{\"code\":400,\"type\":\"CONSUME_CHECK_FAIL\",\"message\":\"消费记录已上传\",\"detils\":\"消费记录已上传:3c9ca4eafa00090000475500000b4000\"}";
+
+        ErrorInfo errorInfo = new ErrorInfo();
+        errorInfo.setCode(400);
+        errorInfo.setMessage("消费记录已上传");
+        errorInfo.setType("CONSUME_CHECK_FAIL");
+        errorInfo.setDetils("消费记录已上传:3c9ca4eafa00090000475500000b4000");
+
+        String message6 = "【湖南省委党校】"+JSONObject.toJSONString(errorInfo);
+
+        send(url,systemCode, secret, "15674973790",message2);
+
+    }
+
+}

+ 2 - 2
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/business/self/SelfBusiness.java

@@ -113,9 +113,9 @@ public class SelfBusiness {
      * @param message 发送内容
      */
     public void sendSms(String phone, String message) {
-        if (!RedisUtils.hasKey("yktSmsToken")) {
+        /*if (!RedisUtils.hasKey("yktSmsToken")) {
             loginSms();
-        }
+        }*/
         asyncTaskService.asyncSendSms(phone, message);
     }
 

+ 33 - 4
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/cardCenter/controller/PtSubsidyitemController.java

@@ -32,14 +32,13 @@ import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
+import java.util.*;
 
 /**
  * 补助明细
@@ -205,4 +204,34 @@ public class PtSubsidyitemController extends BaseController {
     public R<List<PtSubsidyitemVo>> importExcel(@RequestPart("file") MultipartFile file) {
         return ptSubsidyitemService.importSubsidyDetail(file);
     }
+
+    //手动设置数据,生产PDF
+    public static void main(String[] args)  throws FileNotFoundException {
+        List<PtSubsidyReportVo> list = new ArrayList<>();
+        PtSubsidyReportVo ptSubsidyReportVo = new PtSubsidyReportVo();
+        ptSubsidyReportVo.setFillDate("2025-08");
+        ptSubsidyReportVo.setSubsidyType("所有");
+        ptSubsidyReportVo.setFillMoney(new BigDecimal("537000"));
+        ptSubsidyReportVo.setCountNumber(1074L);
+        ptSubsidyReportVo.setReceiveMoney(new BigDecimal("537000"));
+        ptSubsidyReportVo.setReceiveNumber(1074L);
+        ptSubsidyReportVo.setNotReceiveMoney(new BigDecimal("0"));
+        ptSubsidyReportVo.setNotReceiveNumber(0L);
+        ptSubsidyReportVo.setCreateByName("所有");
+        list.add(ptSubsidyReportVo);
+        Map<String,Object> hashMap = new HashMap<>();
+        hashMap.put("currentDate", "dsfsadfsddasfd");
+        hashMap.put("useUint", "中共湖南省委党校湖南行政学院");
+        hashMap.put("makeMan", "admin");
+        hashMap.put("makeTime", DateUtils.getTime());
+        hashMap.put("queryTime", "2025-08-01至2025-08-31");
+        hashMap.put("itemList", list);
+        // 合计金额
+        hashMap.put("totalAmount", list.stream().map(PtSubsidyReportVo::getReceiveMoney).reduce(BigDecimal::add).orElse(BigDecimal.ZERO));
+        // 合计笔数
+        hashMap.put("totalCount", list.stream().map(PtSubsidyReportVo::getReceiveNumber).reduce(Long::sum).orElse(0L));
+        PdfUtil.renderPdf("PtSubsidyReport.html",hashMap, new FileOutputStream("D:/temp1.pdf"),PageSize.A4.rotate());
+        System.err.println("ok");
+    }
+
 }

+ 2 - 1
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/dubbo/RemoteXfExceptionServiceImpl.java

@@ -29,7 +29,8 @@ public class RemoteXfExceptionServiceImpl implements RemoteXfExceptionService {
 
     @Override
     public void sendExceptionSms(String mobile, String message) {
-        selfBusiness.sendSms(mobile, message);
+        String errMsg = "【湖南省委党校】" + message;
+        selfBusiness.sendSms(mobile, errMsg);
     }
 
     @Override

+ 1 - 1
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/controller/self/SelfController.java

@@ -46,7 +46,7 @@ public class SelfController {
     @PostMapping(value = "/api/v1/sendSms")
     public void sendSms(@RequestBody Map<String, String> mapSendInfo) {
         String mobile = mapSendInfo.get("mobile");
-        String message = mapSendInfo.get("content");
+        String message = "【湖南省委党校】"+ mapSendInfo.get("content");
 
         selfBusiness.sendSms(mobile, message);
     }

+ 32 - 21
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/task/AsyncTaskService.java

@@ -6,6 +6,7 @@ import cn.hutool.json.JSONUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.core.api.ReturnResult;
+import org.dromara.common.core.utils.sms.SmsUtil;
 import org.dromara.common.redis.utils.RedisUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
@@ -25,30 +26,40 @@ import java.util.Map;
 @Service
 @RequiredArgsConstructor
 public class AsyncTaskService {
-    @Value("${third-api.sms-api}")
-    String smsApi;
+//    @Value("${third-api.sms-api}")
+//    String smsApi;
+
+    @Value("${sms.gateway.systemCode:SYS004}")
+    private String systemCode;
+
+    @Value("${sms.gateway.secret:afcd53c8cfdcfb2b150238a783a04d355697d84857dacbd931522fa8ade94b2d}")
+    private String secret;
+
+    @Value("${sms.gateway.url:http://172.16.137.140:48088/system/sms-gateway/send}") // http://59.231.239.52:48088/system/sms-gateway/send
+    private String url;
 
 
     public void asyncSendSms(String mobile, String message) {
-        String keyToken = "yktSmsToken";
-        String sendUrl = smsApi + "sms/api/v1/send";
-        String tokens = RedisUtils.getCacheObject(keyToken);
-        Map<String, String> mapHeaders = new HashMap<>(2);
-        mapHeaders.put("businessName","ykt");
-        mapHeaders.put("token", tokens);
-
-
-        Map<String, String> mapMessages = new HashMap<>(2);
-        mapMessages.put("mobile", mobile);
-        mapMessages.put("message", message);
-        try {
-            HttpRequest req = HttpUtil.createPost(sendUrl);
-            req.headerMap(mapHeaders,false);
-            ReturnResult sendResult = JSONUtil.toBean(req.body(JSONUtil.toJsonStr(mapMessages)).execute().body(), ReturnResult.class);
-            log.info("[短信发送]-{\"内容\":\"{}\",\"结果\":\"{}\"", message, sendResult.getMessage());
-        } catch (Exception ex) {
-            log.info("[短信发送]-{\"内容\":\"{}\",\"发送异常\":\"{}\"", message, ex.getMessage());
-        }
+//        String keyToken = "yktSmsToken";
+//        String sendUrl = smsApi + "sms/api/v1/send";
+//        String tokens = RedisUtils.getCacheObject(keyToken);
+//        Map<String, String> mapHeaders = new HashMap<>(2);
+//        mapHeaders.put("businessName","ykt");
+//        mapHeaders.put("token", tokens);
+//
+//
+//        Map<String, String> mapMessages = new HashMap<>(2);
+//        mapMessages.put("mobile", mobile);
+//        mapMessages.put("message", message);
+//        try {
+//            HttpRequest req = HttpUtil.createPost(sendUrl);
+//            req.headerMap(mapHeaders,false);
+//            ReturnResult sendResult = JSONUtil.toBean(req.body(JSONUtil.toJsonStr(mapMessages)).execute().body(), ReturnResult.class);
+//            log.info("[短信发送]-{\"内容\":\"{}\",\"结果\":\"{}\"", message, sendResult.getMessage());
+//        } catch (Exception ex) {
+//            log.info("[短信发送]-{\"内容\":\"{}\",\"发送异常\":\"{}\"", message, ex.getMessage());
+//        }
+        SmsUtil.send(url, systemCode, secret, mobile, message);
     }
 
 }

+ 9 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/wx/contorller/WxController.java

@@ -9,6 +9,7 @@ import org.dromara.backstage.payment.domain.vo.PtUserAccountVo;
 import org.dromara.backstage.wx.domain.vo.WxCreditAccountVo;
 import org.dromara.backstage.wx.service.IWxService;
 import org.dromara.common.core.domain.R;
+import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.satoken.utils.LoginHelper;
@@ -18,6 +19,7 @@ import org.springframework.web.bind.annotation.*;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Optional;
 
 /**
  * 微信
@@ -98,6 +100,13 @@ public class WxController extends BaseController {
         mapParams.put("dealValue", transValue);
         mapParams.put("userAgent", userAgent);
 
+        Long l = Long.valueOf(userId);
+        String category = Optional.ofNullable(wxService.obtainUserInfoByUserId(l)).map(PtUserAccountVo::getCategory).orElse("");
+        if("2".equals(category)){
+            throw new ServiceException("学员身份,无需充值!");
+        }
+
+
         R<String> strReturn = thirdPayBusiness.createDirectPayment(mapParams);
         log.info("[微信支付请求返回]-[{}]", strReturn.getData());
         return strReturn.getData();

+ 2 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/wx/service/IWxService.java

@@ -13,6 +13,8 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
 public interface IWxService {
 
     PtUserAccountVo getUserInfoByUserId(Long userId);
+    PtUserAccountVo obtainUserInfoByUserId(Long userId);
+
 
     TableDataInfo<WxCreditAccountVo> findCreditAccount(String type, Long userId, String startTime, String endTime,
                                                        PageQuery pageQuery);

+ 5 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/wx/service/impl/WxServiceImpl.java

@@ -139,6 +139,11 @@ public class WxServiceImpl implements IWxService {
         return vo;
     }
 
+    @Override
+    public PtUserAccountVo obtainUserInfoByUserId(Long userId) {
+        return accountMapper.selectVoById(userId);
+    }
+
     @Override
     public TableDataInfo<WxCreditAccountVo> findCreditAccount(String type, Long userId, String startTime,
                                                               String endTime,

+ 2 - 2
ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/controller/SysSmsController.java

@@ -71,14 +71,14 @@ public class SysSmsController extends BaseController {
     @RateLimiter(key = "#phone", time = 60, count = 1)
     @GetMapping("/sendPhoneCode")
     public R<Object> sendPhoneCode(String phone)  {
-        String key = "PhoneCode_" + phone;
+        /*String key = "PhoneCode_" + phone;
         String code = RandomUtil.randomNumbers(4);
         RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
         String content = "您的验证码为:" + code + ",有效性为" + Constants.CAPTCHA_EXPIRATION + "分钟,请尽快填写。";
         boolean flag = SmsUtils.send(phone, content, url, user, pwd);
         if (!flag) {
             return R.fail("验证码短信发送异常,请稍后重试!");
-        }
+        }*/
         return R.ok();
     }
 }

+ 17 - 4
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysSmsController.java

@@ -5,6 +5,7 @@ import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.constant.Constants;
 import org.dromara.common.core.domain.R;
 import org.dromara.common.core.utils.SmsUtils;
+import org.dromara.common.core.utils.sms.SmsUtil;
 import org.dromara.common.ratelimiter.annotation.RateLimiter;
 import org.dromara.common.redis.utils.RedisUtils;
 import org.springframework.beans.factory.annotation.Value;
@@ -25,12 +26,21 @@ import java.time.Duration;
 @RequestMapping("/sms")
 public class SysSmsController {
 
-    @Value("${sms.swdx.url}")
+    /*@Value("${sms.swdx.url}")
     private String url;
     @Value("${sms.swdx.user}")
     private  String user;
     @Value("${sms.swdx.pwd}")
-    private  String pwd;
+    private  String pwd;*/
+
+    @Value("${sms.gateway.systemCode:SYS004}")
+    private String systemCode;
+
+    @Value("${sms.gateway.secret:afcd53c8cfdcfb2b150238a783a04d355697d84857dacbd931522fa8ade94b2d}")
+    private String secret;
+
+    @Value("${sms.gateway.url:http://172.16.137.140:48088/system/sms-gateway/send}") // http://59.231.239.52:48088/system/sms-gateway/send
+    private String url;
 
     /** 调用省委党校短信平台发送短信验证码*/
     @RateLimiter(key = "#phone", time = 60, count = 1)
@@ -39,8 +49,11 @@ public class SysSmsController {
         String key = SmsUtils.PHONE_CODE_PREFIX + phone;
         String code = RandomUtil.randomNumbers(4);
         RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
-        String content = "您的验证码为:" + code + ",有效性为" + Constants.CAPTCHA_EXPIRATION + "分钟,请尽快填写。";
-        boolean flag = SmsUtils.send(phone, content, url, user, pwd);
+        //【湖南省委党校】您的验证码为:{code},有效期{expire}分钟,请勿泄露给他人。
+        String content = String.format("【湖南省委党校】您的验证码为:%s,有效期%s分钟,请勿泄露给他人。", code, Constants.CAPTCHA_EXPIRATION);
+//        String content = "您的验证码为:" + code + ",有效期" + Constants.CAPTCHA_EXPIRATION + "分钟,请尽快填写。";
+//        boolean flag = SmsUtils.send(phone, content, url, user, pwd);
+        boolean flag = SmsUtil.send(url, systemCode, secret, phone, content);
         if (!flag) {
             return R.fail("验证码短信发送异常,请稍后重试!");
         }