Преглед изворни кода

Merge branch 'dev-1.2.0-wwlong' into dev-1.2.0

# Conflicts:
#	leromro-core/src/main/java/com/leromro/core/service/impl/VolunteerInfoServiceImpl.java
wangwl пре 3 месеци
родитељ
комит
168bf4200f
22 измењених фајлова са 503 додато и 40 уклоњено
  1. 2 2
      leromro-admin/src/main/resources/application-dev.yml
  2. 7 0
      leromro-common/src/main/java/com/leromro/common/exception/WebSocketAuthenticationException.java
  3. 1 2
      leromro-core/src/main/java/com/leromro/core/controller/ConversationRecordController.java
  4. 9 3
      leromro-core/src/main/java/com/leromro/core/controller/SmsController.java
  5. 62 0
      leromro-core/src/main/java/com/leromro/core/domain/SmsSendRecord.java
  6. 22 11
      leromro-core/src/main/java/com/leromro/core/facade/ConversationRecordFacade.java
  7. 5 1
      leromro-core/src/main/java/com/leromro/core/facade/OrdersFacade.java
  8. 62 0
      leromro-core/src/main/java/com/leromro/core/mapper/SmsSendRecordMapper.java
  9. 17 0
      leromro-core/src/main/java/com/leromro/core/service/ISmsSendRecordService.java
  10. 1 1
      leromro-core/src/main/java/com/leromro/core/service/impl/ConversationMsgRecordServiceImpl.java
  11. 1 1
      leromro-core/src/main/java/com/leromro/core/service/impl/ConversationRecordServiceImpl.java
  12. 8 4
      leromro-core/src/main/java/com/leromro/core/service/impl/MainOrderServiceImpl.java
  13. 4 1
      leromro-core/src/main/java/com/leromro/core/service/impl/OrderRefundServiceImpl.java
  14. 47 0
      leromro-core/src/main/java/com/leromro/core/service/impl/SmsSendRecordServiceImpl.java
  15. 6 1
      leromro-core/src/main/java/com/leromro/core/service/impl/VolunteerInfoServiceImpl.java
  16. 5 1
      leromro-core/src/main/java/com/leromro/core/service/impl/VolunteerPaymentRecordsServiceImpl.java
  17. 26 2
      leromro-core/src/main/java/com/leromro/core/socket/WebSocketService.java
  18. 23 7
      leromro-core/src/main/java/com/leromro/core/utils/SendSmsUtil.java
  19. 91 0
      leromro-core/src/main/resources/mapper/core/SmsSendRecordMapper.xml
  20. 15 3
      leromro-framework/src/main/java/com/leromro/framework/config/ConstantsConfig.java
  21. 6 0
      leromro-framework/src/main/java/com/leromro/framework/config/WebSocketConfig.java
  22. 83 0
      leromro-framework/src/main/java/com/leromro/framework/config/WebsocketEndpointConfig.java

+ 2 - 2
leromro-admin/src/main/resources/application-dev.yml

@@ -172,9 +172,9 @@ wx:
     #商户证书,用于退款
     key-path: classpath:apiclient_cert.p12
     #支付回调通知地址。必填项 这里真是域名地址即可
-    notify-url: https://goldshulin.com/prod-api/core/users/orders/payNotify
+    notify-url: https://yongc.top/prod-api/core/users/orders/payNotify
     #退款回调通知地址
-    refundNotifyUrl: https://goldshulin.com/prod-api/core/users/orders/refundNotify
+    refundNotifyUrl: https://yongc.top/prod-api/core/users/orders/refundNotify
 
 aliyun:
   admpay:

+ 7 - 0
leromro-common/src/main/java/com/leromro/common/exception/WebSocketAuthenticationException.java

@@ -0,0 +1,7 @@
+package com.leromro.common.exception;
+
+public class WebSocketAuthenticationException extends RuntimeException {
+    public WebSocketAuthenticationException(String message) {
+        super(message);
+    }
+}

+ 1 - 2
leromro-core/src/main/java/com/leromro/core/controller/ConversationRecordController.java

@@ -95,8 +95,7 @@ public class ConversationRecordController extends BaseController
     @PostMapping("/sendMsg")
     public R<String> sendMsg(@Validated @RequestBody ConversationMsgDTO dto)
     {
-        conversationRecordFacade.sendMsg(dto);
-        return R.ok();
+        return conversationRecordFacade.sendMsg(dto);
     }
 
     /**

+ 9 - 3
leromro-core/src/main/java/com/leromro/core/controller/SmsController.java

@@ -3,9 +3,11 @@ package com.leromro.core.controller;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONObject;
+import com.leromro.common.core.controller.BaseController;
 import com.leromro.common.core.domain.AjaxResult;
 import com.leromro.common.core.redis.RedisCache;
 import com.leromro.common.enums.ConstantsKey;
+import com.leromro.core.service.ISmsSendRecordService;
 import com.leromro.core.utils.SendSmsUtil;
 import com.leromro.framework.config.ConstantsConfig;
 import io.swagger.annotations.Api;
@@ -23,11 +25,14 @@ import java.util.concurrent.TimeUnit;
 @RestController
 @Api(tags = "短信")
 @RequestMapping({"/sms"})
-public class SmsController {
+public class SmsController extends BaseController {
 
     @Autowired
     private RedisCache redisCache;
 
+    @Autowired
+    private SendSmsUtil sendSmsUtil;
+
     /**
      * 发送验证码
      * @param phone
@@ -43,8 +48,9 @@ public class SmsController {
         String code = (Math.random() + "").substring(2, 6);
         JSONObject jsonObject = new JSONObject();
         jsonObject.putOnce("code", code);
-        String send = SendSmsUtil.send(phone, jsonObject.toString(), ConstantsConfig.SMS_TEMPLATE_TYPE_PHONE_CODE.getValue());
-        if (StrUtil.isBlank(send)) {
+        String sendStatus = sendSmsUtil.send(getUserId(),phone, jsonObject.toString(),
+                ConstantsConfig.SMS_TEMPLATE_TYPE_PHONE_CODE.getValue(),ConstantsConfig.SMS_TYPE_1.getValue());
+        if ("0".equals(sendStatus)) {
             return AjaxResult.error( "验证码发送失败");
         }
         //设置值

+ 62 - 0
leromro-core/src/main/java/com/leromro/core/domain/SmsSendRecord.java

@@ -0,0 +1,62 @@
+package com.leromro.core.domain;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.leromro.common.annotation.Excel;
+import com.leromro.common.core.domain.BaseEntity;
+
+/**
+ * 短信发送记录对象 l_sms_send_record
+ * 
+ * @author ruoyi
+ * @date 2025-06-04
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName("l_sms_send_record")
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "SmsSendRecord", description = "短信发送记录")
+public class SmsSendRecord extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    @TableId(type = IdType.AUTO)
+    private Long smsSendRecordId;
+
+    @TableField("sms_type")
+    @ApiModelProperty("短信类型 1验证码短信 2通知短信")
+    private String smsType;
+
+    @TableField("sms_send_status")
+    @ApiModelProperty("短信发送状态 0发送失败 1发送成功")
+    private String smsSendStatus;
+
+    @TableField("phone_number")
+    @ApiModelProperty("联系电话")
+    private String phoneNumber;
+
+    @TableField("msg_content")
+    @ApiModelProperty("消息内容")
+    private String msgContent;
+
+    @TableField("user_id")
+    @ApiModelProperty("接收短信的用户id")
+    private Long userId;
+
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @TableField("msg_send_time")
+    @ApiModelProperty("消息发送时间")
+    private LocalDateTime msgSendTime;
+
+
+}

+ 22 - 11
leromro-core/src/main/java/com/leromro/core/facade/ConversationRecordFacade.java

@@ -112,12 +112,11 @@ public class ConversationRecordFacade {
      * 发送聊天消息
      */
     @Transactional(rollbackFor = Exception.class)
-    public void sendMsg(ConversationMsgDTO dto) {
+    public R<String> sendMsg(ConversationMsgDTO dto) {
         SysUser user = SecurityUtils.getLoginUser().getUser();
         //保存消息
         ConversationMsgRecord conversationMsgRecord = ConversationMsgRecord.builder()
                 .conversationRecordId(dto.getConversationRecordId())
-                .senderId(user.getUserId())
                 .userId(dto.getUserId())
                 .volunteerId(dto.getVolunteerId())
                 .msgType(dto.getMsgType())
@@ -134,30 +133,39 @@ public class ConversationRecordFacade {
         Long receiver = null;
         if (dto.getSystem() == 1){
             //用户发送,设置用户已读
+            conversationMsgRecord.setSenderId(user.getUserId());
             conversationMsgRecord.setUserReadFlag("2");
             // 目前系统消息不允许发送,如果为订单消息则设置接收人为志愿者,如果是客服消息则设置区域编号和名称
             if ("2".equals(dto.getConversationType())){
                 receiver = dto.getVolunteerId();
-            }else {
+            }else if ("3".equals(dto.getConversationType())){
+                receiver = Long.valueOf(user.getDistrictCode());
                 conversationMsgRecord.setDistrictCode(user.getDistrictCode());
                 conversationMsgRecord.setDistrictName(user.getDistrictName());
+            }else {
+                return R.fail("不能和系统发送消息");
             }
             //设置会话
             wrapper.set(ConversationRecord::getVolunteerDelFlag, "0");
         } else if (dto.getSystem() == 2) {
             //志愿者发送,设置志愿者已读
             conversationMsgRecord.setVolunteerReadFlag("2");
+            conversationMsgRecord.setSenderId(user.getUserId());
             // 目前系统消息不允许发送,如果为订单消息则设置接收人为志愿者,如果是客服消息则设置区域编号和名称
             if ("2".equals(dto.getConversationType())){
                 receiver = dto.getUserId();
-            }else {
+            }else  if ("3".equals(dto.getConversationType())){
+                receiver = Long.valueOf(user.getDistrictCode());
                 conversationMsgRecord.setDistrictCode(user.getDistrictCode());
                 conversationMsgRecord.setDistrictName(user.getDistrictName());
+            }else {
+                return R.fail("不能和系统发送消息");
             }
             //设置会话
             wrapper.set(ConversationRecord::getUserDelFlag, "0");
         }else if (dto.getSystem() == 3){
             //系统发送,设置系统已读
+            conversationMsgRecord.setSenderId(Long.valueOf(user.getDistrictCode()));
             conversationMsgRecord.setCustomerServiceReadFlag("2");
             conversationMsgRecord.setUserId(dto.getUserId());
             conversationMsgRecord.setVolunteerId(dto.getVolunteerId());
@@ -177,6 +185,7 @@ public class ConversationRecordFacade {
         webSocketService.sendMessage(receiver,JSONUtil.toJsonStr(msgVO,new JSONConfig().setDateFormat("yyyy-MM-dd HH:mm:ss")));
         //推送总数
         conversationMsgRecordService.getUnreadMsgCountByUserId(dto.getSystem(), user.getUserId());
+        return R.ok();
     }
 
     /**
@@ -196,11 +205,12 @@ public class ConversationRecordFacade {
             wrapper.eq(ConversationMsgRecord::getVolunteerReadFlag, "0");
             wrapper.set(ConversationMsgRecord::getVolunteerReadFlag, "2");
         } else if (dto.getSystem() == 3) {
-            //后台,设置客服已读
-            wrapper.eq(ObjectUtil.isNotNull(dto.getUserId()),ConversationMsgRecord::getUserId, dto.getUserId());
-            wrapper.set(ObjectUtil.isNotNull(dto.getUserId()),ConversationMsgRecord::getUserReadFlag, "2");
-            wrapper.eq(ObjectUtil.isNotNull(dto.getVolunteerId()),ConversationMsgRecord::getVolunteerId, dto.getVolunteerId());
-            wrapper.set(ObjectUtil.isNotNull(dto.getVolunteerId()),ConversationMsgRecord::getVolunteerReadFlag, "2");
+            //后台发送,设置客服已读
+//            wrapper.eq(ObjectUtil.isNotNull(dto.getUserId()),ConversationMsgRecord::getUserId, dto.getUserId());
+//            wrapper.set(ObjectUtil.isNotNull(dto.getUserId()),ConversationMsgRecord::getUserReadFlag, "2");
+//            wrapper.eq(ObjectUtil.isNotNull(dto.getVolunteerId()),ConversationMsgRecord::getVolunteerId, dto.getVolunteerId());
+//            wrapper.set(ObjectUtil.isNotNull(dto.getVolunteerId()),ConversationMsgRecord::getVolunteerReadFlag, "2");
+            wrapper.set(ConversationMsgRecord::getCustomerServiceReadFlag, "2");
         }
         conversationMsgRecordService.update(wrapper);
         //推送总数
@@ -233,7 +243,7 @@ public class ConversationRecordFacade {
                 .eq(SysDept::getAreaType, "3"));
         //如果不存在区域中心,则提示
         if (ObjectUtil.isNull(dept)){
-            return R.fail("当前所在地区还未开展服务,如需加盟请联系XXXX");
+            return R.fail("当前所在地区还未开展服务,如需加盟请联系王先生 13372727333");
         }
         ConversationRecordVO vo = new ConversationRecordVO();
         LambdaQueryWrapper<ConversationRecord> wrapper = new LambdaQueryWrapper<ConversationRecord>().eq(ConversationRecord::getConversationType, "3");
@@ -251,6 +261,7 @@ public class ConversationRecordFacade {
                     .msgType("1")
                     .msgContent("您好,请问需要什么帮助")
                     .msgSendTime(LocalDateTime.now())
+                    .senderId(Long.valueOf(districtCode))
                     .userReadFlag("2")
                     .districtName(dept.getDistrictName())
                     .districtCode(dept.getDistrictCode())
@@ -270,7 +281,7 @@ public class ConversationRecordFacade {
                 conversationRecord.setUserName(SecurityUtils.getUsername());
                 conversationRecord.setUserOrVolunteer("1");
                 conversationMsgRecord.setUserId(SecurityUtils.getUserId());
-            } else  {
+            } else {
                 //设置会话信息
                 conversationRecord.setVolunteerId(SecurityUtils.getUserId());
                 conversationRecord.setVolunteerName(SecurityUtils.getUsername());

+ 5 - 1
leromro-core/src/main/java/com/leromro/core/facade/OrdersFacade.java

@@ -63,6 +63,9 @@ public class OrdersFacade {
     @Autowired
     private IVolunteerInfoService volunteerInfoService;
 
+    @Autowired
+    private SendSmsUtil sendSmsUtil;
+
 
     /**
      * 支付超时或取消
@@ -134,7 +137,8 @@ public class OrdersFacade {
                     //发送短信通知
                     VolunteerInfo info = volunteerInfoService.getById(mainOrders.getVolunteerInfoId());
                     if (ObjectUtil.isNotNull(info)) {
-                        SendSmsUtil.send(info.getPhonenumber(), "", ConstantsConfig.SMS_TEMPLATE_TYPE_VOLUNTEER_NEW_ORDER.getValue());
+                        sendSmsUtil.send(info.getVolunteerId(),info.getPhonenumber(), "您有新的订单,请及时查看",
+                                ConstantsConfig.SMS_TEMPLATE_TYPE_VOLUNTEER_NEW_ORDER.getValue(),ConstantsConfig.SMS_TYPE_2.getValue());
                     }
 
                 }else if ("FAIL".equals(notifyResult.getResultCode())){

+ 62 - 0
leromro-core/src/main/java/com/leromro/core/mapper/SmsSendRecordMapper.java

@@ -0,0 +1,62 @@
+package com.leromro.core.mapper;
+
+import java.util.List;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.leromro.core.domain.SmsSendRecord;
+
+/**
+ * 短信发送记录Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-06-04
+ */
+public interface SmsSendRecordMapper extends BaseMapper<SmsSendRecord>
+{
+    /**
+     * 查询短信发送记录
+     * 
+     * @param smsSendRecordId 短信发送记录主键
+     * @return 短信发送记录
+     */
+    public SmsSendRecord selectSmsSendRecordBySmsSendRecordId(Long smsSendRecordId);
+
+    /**
+     * 查询短信发送记录列表
+     * 
+     * @param smsSendRecord 短信发送记录
+     * @return 短信发送记录集合
+     */
+    public List<SmsSendRecord> selectSmsSendRecordList(SmsSendRecord smsSendRecord);
+
+    /**
+     * 新增短信发送记录
+     * 
+     * @param smsSendRecord 短信发送记录
+     * @return 结果
+     */
+    public int insertSmsSendRecord(SmsSendRecord smsSendRecord);
+
+    /**
+     * 修改短信发送记录
+     * 
+     * @param smsSendRecord 短信发送记录
+     * @return 结果
+     */
+    public int updateSmsSendRecord(SmsSendRecord smsSendRecord);
+
+    /**
+     * 删除短信发送记录
+     * 
+     * @param smsSendRecordId 短信发送记录主键
+     * @return 结果
+     */
+    public int deleteSmsSendRecordBySmsSendRecordId(Long smsSendRecordId);
+
+    /**
+     * 批量删除短信发送记录
+     * 
+     * @param smsSendRecordIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteSmsSendRecordBySmsSendRecordIds(Long[] smsSendRecordIds);
+}

+ 17 - 0
leromro-core/src/main/java/com/leromro/core/service/ISmsSendRecordService.java

@@ -0,0 +1,17 @@
+package com.leromro.core.service;
+
+import java.util.List;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.leromro.core.domain.SmsSendRecord;
+
+/**
+ * 短信发送记录Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-06-04
+ */
+public interface ISmsSendRecordService extends IService<SmsSendRecord>
+{
+    //异步保存短信发送记录
+    void asyncSaveSendRecord(Long userId,String phoneNumber,String msgContent,String smsType,String smsSendStatus);
+}

+ 1 - 1
leromro-core/src/main/java/com/leromro/core/service/impl/ConversationMsgRecordServiceImpl.java

@@ -66,7 +66,7 @@ public class ConversationMsgRecordServiceImpl extends ServiceImpl<ConversationMs
             //后台区域中心查看当前区域的未读消息
             SysUser user = userService.getById(userId);
             //socket鉴权之后,用户不会为空
-            wrapper.eq(ConversationMsgRecord::getDistrictCode, user.getDistrictCode())
+            wrapper.eq(ConversationMsgRecord::getDistrictCode, userId)
                     .eq(ConversationMsgRecord::getCustomerServiceReadFlag,"0");
         }
         //获取未读消息

+ 1 - 1
leromro-core/src/main/java/com/leromro/core/service/impl/ConversationRecordServiceImpl.java

@@ -87,7 +87,7 @@ public class ConversationRecordServiceImpl extends ServiceImpl<ConversationRecor
             }
             //如果是客服会话,当前系统也是后台,则显示用户名称
             if ("3".equals(vo.getConversationType()) && dto.getSystem().equals(3)) {
-                vo.setConversationTitle(StrUtil.isNotEmpty(vo.getUserName())? vo.getUserName() : vo.getVolunteerName());
+                vo.setConversationTitle("1".equals(vo.getUserOrVolunteer())? "用户" : "志愿者");
             }
         }
         return vos;

+ 8 - 4
leromro-core/src/main/java/com/leromro/core/service/impl/MainOrderServiceImpl.java

@@ -89,6 +89,9 @@ public class MainOrderServiceImpl extends ServiceImpl<MainOrdersMapper, MainOrde
     @Autowired
     private SysConfigMapper sysConfigMapper;
 
+    @Autowired
+    private SendSmsUtil sendSmsUtil;
+
     /**
      * @param userId
      * @return
@@ -107,9 +110,9 @@ public class MainOrderServiceImpl extends ServiceImpl<MainOrdersMapper, MainOrde
     @Override
     @Transactional(rollbackFor = Exception.class)
     public R<OrderPaymentVO> createOrders(OrderRequestDTO orderRequest) throws Exception {
-        if (1==1) {
-            return R.fail("当前地区志愿者批量认证中,暂时关闭预约功能,请谅解");
-        }
+//        if (1==1) {
+//            return R.fail("当前地区志愿者批量认证中,暂时关闭预约功能,请谅解");
+//        }
         //响应数据
         OrderPaymentVO vo = new OrderPaymentVO();
         //订单信息
@@ -352,7 +355,8 @@ public class MainOrderServiceImpl extends ServiceImpl<MainOrdersMapper, MainOrde
                     .msgContent("您有新的订单,请及时查看")
                     .build());
             //发送短信通知
-            SendSmsUtil.send(info.getPhonenumber(), "", ConstantsConfig.SMS_TEMPLATE_TYPE_VOLUNTEER_NEW_ORDER.getValue());
+            sendSmsUtil.send(info.getVolunteerId(),info.getPhonenumber(), "您有新的订单,请及时查看",
+                    ConstantsConfig.SMS_TEMPLATE_TYPE_VOLUNTEER_NEW_ORDER.getValue(),ConstantsConfig.SMS_TYPE_2.getValue());
         }
         return R.ok(vo);
     }

+ 4 - 1
leromro-core/src/main/java/com/leromro/core/service/impl/OrderRefundServiceImpl.java

@@ -80,6 +80,8 @@ public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, Order
     private IVolunteerInfoService volunteerInfoService;
     @Autowired
     private IConversationRecordService conversationRecordService;
+    @Autowired
+    private SendSmsUtil sendSmsUtil;
 
     /**
      * 查询订单取消/退款
@@ -392,7 +394,8 @@ public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, Order
                 .build());
         VolunteerInfo info = volunteerInfoService.getById(mainOrders.getVolunteerInfoId());
         if (ObjectUtil.isNotNull(info)) {
-            SendSmsUtil.send(info.getPhonenumber(), "", ConstantsConfig.SMS_TEMPLATE_TYPE_VOLUNTEER_ORDER_CANCELLED.getValue());
+            sendSmsUtil.send(info.getVolunteerId(),info.getPhonenumber(), "您有订单被顾客取消,请及时查看",
+                    ConstantsConfig.SMS_TEMPLATE_TYPE_VOLUNTEER_ORDER_CANCELLED.getValue(),ConstantsConfig.SMS_TYPE_2.getValue());
         }
     }
 

+ 47 - 0
leromro-core/src/main/java/com/leromro/core/service/impl/SmsSendRecordServiceImpl.java

@@ -0,0 +1,47 @@
+package com.leromro.core.service.impl;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.leromro.core.mapper.SmsSendRecordMapper;
+import com.leromro.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+import com.leromro.core.mapper.SmsSendRecordMapper;
+import com.leromro.core.domain.SmsSendRecord;
+import com.leromro.core.service.ISmsSendRecordService;
+
+/**
+ * 短信发送记录Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-06-04
+ */
+@Service
+public class SmsSendRecordServiceImpl extends ServiceImpl<SmsSendRecordMapper, SmsSendRecord> implements ISmsSendRecordService
+{
+    @Autowired
+    private SmsSendRecordMapper smsSendRecordMapper;
+
+
+    /**
+     * 异步保存短信发送记录,失败不影响业务
+     * @param userId
+     * @param phoneNumber
+     * @param msgContent
+     */
+    @Async("threadPoolTaskExecutor")
+    @Override
+    public void asyncSaveSendRecord(Long userId, String phoneNumber, String msgContent,String smsType,String smsSendStatus) {
+        SmsSendRecord record = SmsSendRecord.builder()
+                .userId(userId)
+                .smsType(smsType)
+                .smsSendStatus(smsSendStatus)
+                .phoneNumber(phoneNumber)
+                .msgContent(msgContent)
+                .msgSendTime(LocalDateTime.now())
+                .build();
+        this.save(record);
+    }
+}

+ 6 - 1
leromro-core/src/main/java/com/leromro/core/service/impl/VolunteerInfoServiceImpl.java

@@ -83,6 +83,9 @@ public class VolunteerInfoServiceImpl extends ServiceImpl<VolunteerInfoMapper, V
     @Autowired
     private MainOrderServiceImpl mainOrderService;
 
+    @Autowired
+    private SendSmsUtil sendSmsUtil;
+
     /**
      * 新增志愿者信息
      * @param dto
@@ -208,7 +211,9 @@ public class VolunteerInfoServiceImpl extends ServiceImpl<VolunteerInfoMapper, V
         JSONObject jsonObject = new JSONObject();
         jsonObject.putOnce("name", info.getName());
         jsonObject.putOnce("result", "2".equals(appStatus)? "通过" : "驳回");
-        SendSmsUtil.send(info.getPhonenumber(), jsonObject.toString(), ConstantsConfig.SMS_TEMPLATE_TYPE_VOLUNTEER_RESULT.getValue());
+        sendSmsUtil.send(info.getVolunteerId(),info.getPhonenumber(), jsonObject.toString(),
+                ConstantsConfig.SMS_TEMPLATE_TYPE_VOLUNTEER_RESULT.getValue(),ConstantsConfig.SMS_TYPE_1.getValue());
+
         // 用户成为志愿者积分处理
         userToVolunteerPointHandler(info.getVolunteerId());
     }

+ 5 - 1
leromro-core/src/main/java/com/leromro/core/service/impl/VolunteerPaymentRecordsServiceImpl.java

@@ -65,6 +65,9 @@ public class VolunteerPaymentRecordsServiceImpl extends ServiceImpl<VolunteerPay
     @Qualifier("aliPayService")
     private AlipayClient alipayClient;
 
+    @Autowired
+    private SendSmsUtil sendSmsUtil;
+
     /**
      * 查询志愿者打款单记录
      * 
@@ -245,7 +248,8 @@ public class VolunteerPaymentRecordsServiceImpl extends ServiceImpl<VolunteerPay
                 SysUser user = userService.getById(takeAmountRecord.getVolunteerUserId());
                 JSONObject json = new JSONObject();
                 json.putOnce("time", DateUtil.format(takeAmountRecord.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
-                SendSmsUtil.send(user.getPhonenumber(), json.toString(), ConstantsConfig.SMS_TEMPLATE_TYPE_VOLUNTEER_WITGDRAW.getValue());
+                sendSmsUtil.send(user.getUserId(),user.getPhonenumber(), json.toString(),
+                        ConstantsConfig.SMS_TEMPLATE_TYPE_VOLUNTEER_WITGDRAW.getValue(),ConstantsConfig.SMS_TYPE_1.getValue());
 
             } else {
                 //修改账户提现中的金额,把当前申请单金额加到账户余额中,把提现申请单金额从账户提现中的金额中减去

+ 26 - 2
leromro-core/src/main/java/com/leromro/core/socket/WebSocketService.java

@@ -5,8 +5,11 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alipay.api.domain.UserInfoVO;
+import com.leromro.common.core.domain.model.LoginUser;
 import com.leromro.core.domain.vo.UserMsgVO;
 import com.leromro.core.event.WebsocketEvent;
+import com.leromro.framework.config.WebsocketEndpointConfig;
+import com.leromro.framework.web.service.TokenService;
 import lombok.Data;
 import lombok.NonNull;
 import org.slf4j.Logger;
@@ -27,14 +30,17 @@ import java.util.concurrent.locks.ReentrantLock;
 
 @Data
 @Component
-@ServerEndpoint(value = "/websocket/{system}/{userId}")
+@ServerEndpoint(value = "/websocket/{system}/{userId}",configurator = WebsocketEndpointConfig.class)
 public class WebSocketService implements ApplicationContextAware {
 
     private static ApplicationContext applicationContext;
 
+    private static TokenService tokenService;
+
     @Override
     public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
         WebSocketService.applicationContext = applicationContext;
+        WebSocketService.tokenService = applicationContext.getBean(TokenService.class);
     }
 
 
@@ -64,6 +70,19 @@ public class WebSocketService implements ApplicationContextAware {
      */
     @OnOpen
     public void onOpen(Session session,@PathParam("system") Integer system, @PathParam("userId") Long userId) {
+        //如果权限校验没过,就直接断开
+        try {
+            LoginUser loginUser = (LoginUser)session.getUserProperties().get("loginUser");
+            if (ObjectUtil.isNull(loginUser)) {
+                log.info("用户{}socket权限校验未通过", userId);
+                session.close(new CloseReason(CloseReason.CloseCodes.VIOLATED_POLICY, "Token已过期,断开连接"));
+                return;
+            }
+        } catch (IOException e) {
+            log.error("session关闭异常{}", e.getMessage());
+        }
+
+        //权限通过,设置相关信息
         ReentrantLock lock = locks.computeIfAbsent(userId, k -> new ReentrantLock());
         lock.lock();
         CopyOnWriteArrayList<Session> sessions = userSessionMap.computeIfAbsent(userId, k -> new CopyOnWriteArrayList<>());
@@ -95,6 +114,10 @@ public class WebSocketService implements ApplicationContextAware {
      */
     @OnClose
     public void onClose() {
+        //如果权限校验没过,就直接断开
+        if (ObjectUtil.isNull(userId)){
+            return;
+        }
         log.info("----------------------关闭连接-------------------------------");
         ReentrantLock lock = locks.computeIfAbsent(userId, k -> new ReentrantLock());
         lock.lock();
@@ -124,7 +147,7 @@ public class WebSocketService implements ApplicationContextAware {
      * @param message 客户端发送过来的消息*/
     @OnMessage
     public void onMessage(String message, Session session) {
-        log.info("收到用户消息:"+userId+",报文:"+message);
+//        log.info("收到用户消息:"+userId+",报文:"+message);
     }
 
     @OnError
@@ -139,6 +162,7 @@ public class WebSocketService implements ApplicationContextAware {
     public void sendMessage(Long userId, String message){
         if (ObjectUtil.isNull(userId)){
             log.error("推送消息失败,用户为null,消息内容:{}", message);
+            return;
         }
         List<Session> sessions = userSessionMap.get(userId);
         if(sessions != null && !sessions.isEmpty()){

+ 23 - 7
leromro-core/src/main/java/com/leromro/core/utils/SendSmsUtil.java

@@ -7,28 +7,44 @@ import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
 import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody;
 import com.aliyun.teaopenapi.models.Config;
 import com.aliyun.teautil.models.RuntimeOptions;
-
+import com.leromro.core.service.ISmsSendRecordService;
+import com.leromro.framework.config.ConstantsConfig;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+@Slf4j
+@Service
 public class SendSmsUtil {
     private static final String accessKeyId = "LTAI5t7Xyw23riTKPgy99FNP";
     private static final String accessKeySecret = "vPXlxXmL5QVE0Iop4NCKvZQvGCZYgP";
     private static final String endpoint = "dysmsapi.aliyuncs.com";
     private static final String signName = "金树林";
 
-    public static String send(String phone, String templateParam, String templateCode) {
+    @Autowired
+    private ISmsSendRecordService smsSendRecordService;
+
+    public String send(Long userId,String phone, String templateParam, String templateCode,String smsType) {
+        String status;
         try {
             Config config = new Config().setAccessKeyId(accessKeyId).setAccessKeySecret(accessKeySecret).setEndpoint(endpoint);
-            SendSmsRequest sendSmsRequest = new SendSmsRequest().setPhoneNumbers(phone).setSignName(signName).setTemplateCode(templateCode).setTemplateParam(templateParam);
+            SendSmsRequest sendSmsRequest = new SendSmsRequest().setPhoneNumbers(phone).setSignName(signName).setTemplateCode(templateCode)
+                    .setTemplateParam("1".equals(smsType) ? templateParam : "");
             RuntimeOptions runtime = new RuntimeOptions();
             Client client = new Client(config);
             SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, runtime);
             SendSmsResponseBody body = sendSmsResponse.getBody();
             if (StrUtil.equals("OK", body.getCode())) {
-                return body.getCode();
+                status = "1";
+            }else {
+                status = "0";
             }
-            return null;
         } catch (Exception e) {
-            e.printStackTrace();
-            return null;
+            log.error("用户{}手机号{}短信发送异常:{}",userId,phone,e.getMessage());
+            status = "0";
         }
+        //异步保存短信发送记录
+        smsSendRecordService.asyncSaveSendRecord(userId,phone, templateParam, smsType,status);
+        return status;
+
     }
 }

+ 91 - 0
leromro-core/src/main/resources/mapper/core/SmsSendRecordMapper.xml

@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.leromro.core.mapper.SmsSendRecordMapper">
+    
+    <resultMap type="SmsSendRecord" id="SmsSendRecordResult">
+        <result property="smsSendRecordId"    column="sms_send_record_id"    />
+        <result property="phoneNumber"    column="phone_number"    />
+        <result property="msgContent"    column="msg_content"    />
+        <result property="userId"    column="user_id"    />
+        <result property="msgSendTime"    column="msg_send_time"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="updateTime"    column="update_time"    />
+        <result property="remark"    column="remark"    />
+    </resultMap>
+
+    <sql id="selectSmsSendRecordVo">
+        select sms_send_record_id, phone_number, msg_content, user_id, msg_send_time, create_by, create_time, update_by, update_time, remark from l_sms_send_record
+    </sql>
+
+    <select id="selectSmsSendRecordList" parameterType="SmsSendRecord" resultMap="SmsSendRecordResult">
+        <include refid="selectSmsSendRecordVo"/>
+        <where>  
+            <if test="phoneNumber != null  and phoneNumber != ''"> and phone_number = #{phoneNumber}</if>
+            <if test="msgContent != null  and msgContent != ''"> and msg_content = #{msgContent}</if>
+            <if test="userId != null  and userId != ''"> and user_id = #{userId}</if>
+            <if test="msgSendTime != null "> and msg_send_time = #{msgSendTime}</if>
+        </where>
+    </select>
+    
+    <select id="selectSmsSendRecordBySmsSendRecordId" parameterType="Long" resultMap="SmsSendRecordResult">
+        <include refid="selectSmsSendRecordVo"/>
+        where sms_send_record_id = #{smsSendRecordId}
+    </select>
+
+    <insert id="insertSmsSendRecord" parameterType="SmsSendRecord" useGeneratedKeys="true" keyProperty="smsSendRecordId">
+        insert into l_sms_send_record
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="phoneNumber != null">phone_number,</if>
+            <if test="msgContent != null">msg_content,</if>
+            <if test="userId != null">user_id,</if>
+            <if test="msgSendTime != null">msg_send_time,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="remark != null">remark,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="phoneNumber != null">#{phoneNumber},</if>
+            <if test="msgContent != null">#{msgContent},</if>
+            <if test="userId != null">#{userId},</if>
+            <if test="msgSendTime != null">#{msgSendTime},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="remark != null">#{remark},</if>
+         </trim>
+    </insert>
+
+    <update id="updateSmsSendRecord" parameterType="SmsSendRecord">
+        update l_sms_send_record
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="phoneNumber != null">phone_number = #{phoneNumber},</if>
+            <if test="msgContent != null">msg_content = #{msgContent},</if>
+            <if test="userId != null">user_id = #{userId},</if>
+            <if test="msgSendTime != null">msg_send_time = #{msgSendTime},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="remark != null">remark = #{remark},</if>
+        </trim>
+        where sms_send_record_id = #{smsSendRecordId}
+    </update>
+
+    <delete id="deleteSmsSendRecordBySmsSendRecordId" parameterType="Long">
+        delete from l_sms_send_record where sms_send_record_id = #{smsSendRecordId}
+    </delete>
+
+    <delete id="deleteSmsSendRecordBySmsSendRecordIds" parameterType="String">
+        delete from l_sms_send_record where sms_send_record_id in 
+        <foreach item="smsSendRecordId" collection="array" open="(" separator="," close=")">
+            #{smsSendRecordId}
+        </foreach>
+    </delete>
+</mapper>

+ 15 - 3
leromro-framework/src/main/java/com/leromro/framework/config/ConstantsConfig.java

@@ -1,12 +1,22 @@
 package com.leromro.framework.config;
 
+/**
+ * 系统常量配置类
+ */
 public enum ConstantsConfig {
+    /** 短信消息相关*/
+    //短信类型-验证码短信,需要参数的传这个
+    SMS_TYPE_1("sms_type_1", "1"),
+    //短信类型-通知短信
+    SMS_TYPE_2("sms_type_2", "2"),
 
+    //验证码获取时间间隔
     REDIS_ONE_MIN_TIMELONG("redis_one_min_timelong", "60"),
+    //验证码超时时间
     REDIS_SHORT_TIMELONG("redis_short_timelong", "1200"),
-//    短信通知
-    SMS_TEMPLATE_TYPE_PHONE_CODE("sms_template_type_phone_code", "SMS_484025217"),
-//    志愿者审批通知
+    //短信通知
+    SMS_TEMPLATE_TYPE_PHONE_CODE("sms_template_type_phone_code", "SMS_488015031"),
+    //志愿者审批通知
     SMS_TEMPLATE_TYPE_VOLUNTEER_RESULT("sms_template_type_volunteer_result","SMS_485465604"),
     //志愿者提现成功通知
     SMS_TEMPLATE_TYPE_VOLUNTEER_WITGDRAW("sms_template_type_volunteer_withdraw","SMS_487525281"),
@@ -15,6 +25,8 @@ public enum ConstantsConfig {
     //志愿者订单被取消短信提示
     SMS_TEMPLATE_TYPE_VOLUNTEER_ORDER_CANCELLED("sms_template_type_volunteer_order_cancelled","SMS_487325335");
 
+
+
     private final String KEY;
     private final String VALUE;
 

+ 6 - 0
leromro-framework/src/main/java/com/leromro/framework/config/WebSocketConfig.java

@@ -15,4 +15,10 @@ public class WebSocketConfig {
         return new ServerEndpointExporter();
     }
 
+    @Bean
+    public WebsocketEndpointConfig newConfigure() {
+        return new WebsocketEndpointConfig();
+    }
+
+
 }

+ 83 - 0
leromro-framework/src/main/java/com/leromro/framework/config/WebsocketEndpointConfig.java

@@ -0,0 +1,83 @@
+package com.leromro.framework.config;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.leromro.common.core.domain.model.LoginUser;
+import com.leromro.common.exception.WebSocketAuthenticationException;
+import com.leromro.common.utils.spring.SpringUtils;
+import com.leromro.framework.web.service.TokenService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.websocket.CloseReason;
+import javax.websocket.HandshakeResponse;
+import javax.websocket.server.HandshakeRequest;
+import javax.websocket.server.ServerEndpointConfig;
+import javax.servlet.http.HttpSession;
+import java.net.URI;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+public class WebsocketEndpointConfig extends ServerEndpointConfig.Configurator {
+
+    private final TokenService tokenService = SpringUtils.getBean(TokenService.class);
+ 
+    @Override
+    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
+        //获取token
+        String token = extractToken(request);
+        //从token中提取值,具体拒绝连接是在service中做的
+        validateToken(sec,token,request);
+
+    }
+ 
+    private String extractToken(HandshakeRequest request) {
+        // 1. 优先从 Header 中取
+        Map<String, List<String>> headers = request.getHeaders();
+        List<String> tokenList = headers.get("Sec-WebSocket-Protocol");
+        if (tokenList != null && !tokenList.isEmpty()) {
+            return tokenList.get(0).substring(6);
+        }
+        List<String> tokenList2 = headers.get("authorization");
+        if (tokenList2 != null && !tokenList2.isEmpty()) {
+            return tokenList2.get(0).substring(6);
+        }
+
+        // 2. 如果Header没有,从 URL query 参数取
+        String query = request.getQueryString();
+        if (query != null && query.startsWith("authorization=")) {
+            return query.substring(23);
+        }
+        return null;
+    }
+ 
+    private void validateToken(ServerEndpointConfig sec,String token,HandshakeRequest request) {
+        try {
+            // TODO: 这里可以接你的认证中心、JWT解析、Redis等逻辑
+            // JWT解析,验证用户属性
+            LoginUser loginUser = tokenService.getLoginUser(token);
+            if (ObjectUtil.isNull(loginUser) || ObjectUtil.isNull(loginUser.getUser())){
+                return;
+            }
+            URI requestURI = request.getRequestURI();
+            String userId = requestURI.getPath().split("/")[requestURI.getPath().split("/").length - 1];
+            String system = requestURI.getPath().split("/")[requestURI.getPath().split("/").length - 2];
+            if ("3".equals(system)){
+                if (ObjectUtil.isNull(loginUser.getUser().getDistrictCode()) || !loginUser.getUser().getDistrictCode().equals(userId)) {
+                    return;
+                }
+            }else {
+            // 保存到用户属性,后续可以从Session里拿
+                if (ObjectUtil.isNull(loginUser.getUserId()) || !loginUser.getUserId().equals(Long.parseLong(userId))){
+                    return;
+                }
+            }
+            sec.getUserProperties().put("loginUser", loginUser);
+        }catch (Exception e) {
+            log.error("websocket校验token失败:{}", e.getMessage());
+        }
+    }
+}