提交 22501de7 authored 作者: 杨凯's avatar 杨凯

Merge branch 'test'

# Conflicts:
#	family-doctor-server/src/main/resources/application-pro.yml
...@@ -41,4 +41,7 @@ public class DoctorSchedVo { ...@@ -41,4 +41,7 @@ public class DoctorSchedVo {
@ApiModelProperty("医生职称") @ApiModelProperty("医生职称")
private String doctorTitle; private String doctorTitle;
@ApiModelProperty(value = "医生简介")
private String introduction;
} }
...@@ -90,6 +90,17 @@ ...@@ -90,6 +90,17 @@
<artifactId>spring-boot-starter-amqp</artifactId> <artifactId>spring-boot-starter-amqp</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<!--swagger接口文档--> <!--swagger接口文档-->
<dependency> <dependency>
<groupId>io.springfox</groupId> <groupId>io.springfox</groupId>
......
package com.ebaiyihui.family.doctor.server.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
/**
* @ClassName: JedisProperties
* @Author:yanliang
* @Date:2024/4/26 09:33
* @Description
*/
@Data
@Configuration
@Component
@ConfigurationProperties(prefix = "spring.redis.jedis.pool")
public class JedisProperties {
private Integer maxIdle;
private Integer maxWait;
private Integer minIdle;
private Integer maxActive;
}
package com.ebaiyihui.family.doctor.server.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @ClassName: RedisAutoConfiguration
* @Author:yanliang
* @Date:2024/4/26 09:44
* @Description
*/
@Configuration
public class RedisAutoConfiguration {
@Autowired
private RedisConnectionFactory factory;
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
}
\ No newline at end of file
package com.ebaiyihui.family.doctor.server.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
import java.util.HashSet;
import java.util.Set;
/**
* @ClassName: RedisConfig
* @Author:yanliang
* @Date:2024/4/26 09:36
* @Description
*/
@Configuration
public class RedisConfig {
@Autowired
private RedisProperties redisProperties;
@Autowired
private JedisProperties jedisProperties;
@Bean
public JedisCluster getJedisCluster() {
// 截取集群节点
String[] cluster = redisProperties.getCluster().getNodes().toArray(new String[0]);
// 创建set集合
Set<HostAndPort> nodes = new HashSet<>();
// 循环数组把集群节点添加到set集合中
for (String node : cluster) {
String[] host = node.split(":");
//添加集群节点
nodes.add(new HostAndPort(host[0], Integer.parseInt(host[1])));
}
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(jedisProperties.getMaxIdle());
jedisPoolConfig.setMaxWaitMillis(jedisProperties.getMaxWait());
//创建集群对象
JedisCluster jedisCluster = new JedisCluster(nodes, redisProperties.getTimeout(), jedisPoolConfig);
return jedisCluster;
}
}
package com.ebaiyihui.family.doctor.server.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @ClassName: RedisProperties
* @Author:yanliang
* @Date:2024/4/26 09:37
* @Description
*/
@Data
@Configuration
@Component
@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {
private int timeout;
private Cluster cluster;
public static class Cluster {
private List<String> nodes;
private Integer maxRedirects;
public List<String> getNodes() {
return nodes;
}
public void setNodes(List<String> nodes) {
this.nodes = nodes;
}
public Integer getMaxRedirects() {
return maxRedirects;
}
public void setMaxRedirects(Integer maxRedirects) {
this.maxRedirects = maxRedirects;
}
}
}
\ No newline at end of file
package com.ebaiyihui.family.doctor.server.controller; package com.ebaiyihui.family.doctor.server.controller;
import com.alibaba.fastjson.JSONObject;
import com.ebaiyihui.family.doctor.common.bo.ImMessageDTO; import com.ebaiyihui.family.doctor.common.bo.ImMessageDTO;
import com.ebaiyihui.family.doctor.common.dto.SendImMsgDTO; import com.ebaiyihui.family.doctor.common.dto.SendImMsgDTO;
import com.ebaiyihui.family.doctor.server.service.ImMsgTemplateService; import com.ebaiyihui.family.doctor.server.service.ImMsgTemplateService;
import com.ebaiyihui.family.doctor.server.util.RedisUtil;
import com.ebaiyihui.framework.response.BaseResponse; import com.ebaiyihui.framework.response.BaseResponse;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -13,6 +15,8 @@ import org.springframework.web.bind.annotation.RequestMapping; ...@@ -13,6 +15,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.Objects;
/** /**
* @ClassName: ImMsgTemplateController * @ClassName: ImMsgTemplateController
* @Author:yanliang * @Author:yanliang
...@@ -28,17 +32,31 @@ public class ImMsgTemplateController { ...@@ -28,17 +32,31 @@ public class ImMsgTemplateController {
@Autowired @Autowired
private ImMsgTemplateService imMsgTemplateService; private ImMsgTemplateService imMsgTemplateService;
@Autowired
private RedisUtil redisUtil;
private static final String JTYS_SEND_IM_MESSAGE = "jtys_send_im_message_";
private static final Integer OUT_TIME = 10 * 60;
@RequestMapping(value = "/sendImMsg", method = RequestMethod.POST) @RequestMapping(value = "/sendImMsg", method = RequestMethod.POST)
public BaseResponse<String> sendImMsg(@RequestBody SendImMsgDTO reqVo, public BaseResponse<String> sendImMsg(@RequestBody SendImMsgDTO reqVo,
BindingResult bindingResult) { BindingResult bindingResult) {
BaseResponse<String> response = null; String response = null;
try { try {
response = imMsgTemplateService.sendImMsg(reqVo); String key = JTYS_SEND_IM_MESSAGE + reqVo.getAdmId() + "_" + reqVo.getType();
Object sendImMsgKeyValue = redisUtil.get(key);
log.info("sendImMsgKeyValue={}", String.valueOf(sendImMsgKeyValue));
if (Objects.isNull(sendImMsgKeyValue)) {
response = imMsgTemplateService.sendImMsg(reqVo);
redisUtil.set(String.valueOf(key), JSONObject.toJSONString(reqVo), OUT_TIME);
}
} catch (Exception e) { } catch (Exception e) {
return BaseResponse.error(e.getMessage()); return BaseResponse.error(e.getMessage());
} }
return BaseResponse.success("消息推送成功"); return BaseResponse.success(response);
} }
@RequestMapping(value = "/unReadMsgCount", method = RequestMethod.POST) @RequestMapping(value = "/unReadMsgCount", method = RequestMethod.POST)
......
...@@ -13,7 +13,7 @@ import com.ebaiyihui.framework.response.BaseResponse; ...@@ -13,7 +13,7 @@ import com.ebaiyihui.framework.response.BaseResponse;
public interface ImMsgTemplateService { public interface ImMsgTemplateService {
BaseResponse<String> sendImMsg(SendImMsgDTO reqVo); String sendImMsg(SendImMsgDTO reqVo);
BaseResponse<String> unReadMsgCount(ImMessageDTO imMessageEntity); BaseResponse<String> unReadMsgCount(ImMessageDTO imMessageEntity);
} }
...@@ -321,6 +321,8 @@ public class DoctorServiceImpl implements DoctorService { ...@@ -321,6 +321,8 @@ public class DoctorServiceImpl implements DoctorService {
doctorSchedVo.setDoctorPortrait(res.getData().getPortrait()); doctorSchedVo.setDoctorPortrait(res.getData().getPortrait());
doctorSchedVo.setDoctorProfession(res.getData().getProfession()); doctorSchedVo.setDoctorProfession(res.getData().getProfession());
doctorSchedVo.setDoctorTitle(res.getData().getTitle()); doctorSchedVo.setDoctorTitle(res.getData().getTitle());
doctorSchedVo.setIntroduction(res.getData().getIntroduction());
} }
return BaseResponse.success(doctorSchedVo); return BaseResponse.success(doctorSchedVo);
} }
......
...@@ -70,7 +70,7 @@ public class ImMsgTemplateServiceImpl implements ImMsgTemplateService { ...@@ -70,7 +70,7 @@ public class ImMsgTemplateServiceImpl implements ImMsgTemplateService {
@Async @Async
@Override @Override
public BaseResponse<String> sendImMsg(SendImMsgDTO sendImMsgDTO) { public String sendImMsg(SendImMsgDTO sendImMsgDTO) {
QueryWrapper<ImMsgTemplateEntity> wrapper = new QueryWrapper<>(); QueryWrapper<ImMsgTemplateEntity> wrapper = new QueryWrapper<>();
ImMsgTemplateEntity imMsgTemplate = new ImMsgTemplateEntity(); ImMsgTemplateEntity imMsgTemplate = new ImMsgTemplateEntity();
...@@ -86,7 +86,7 @@ public class ImMsgTemplateServiceImpl implements ImMsgTemplateService { ...@@ -86,7 +86,7 @@ public class ImMsgTemplateServiceImpl implements ImMsgTemplateService {
if (!flag) { if (!flag) {
throw new BusinessException("消息推送失败"); throw new BusinessException("消息推送失败");
} }
return BaseResponse.success("消息推送成功"); return "消息推送成功";
} }
@Override @Override
......
package com.ebaiyihui.family.doctor.server.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;
import redis.clients.jedis.JedisCluster;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* @ClassName: RedisUtil
* @Author:yanliang
* @Date:2024/4/26 09:49
* @Description
*/
@Slf4j
@Component("redisUtil")
public final class RedisUtil {
@Resource
private RedisTemplate<String, String> redisTemplate;
@Autowired
StringRedisTemplate stringRedisTemplate;
@Autowired
public JedisCluster jedisCluster;
public void setJedisCluster(JedisCluster jedisCluster) {
this.jedisCluster = jedisCluster;
}
/**
* 根据key获取value
*
* @param key
* @return
*/
public String get(final String key) {
String result = redisTemplate.execute((RedisCallback<String>) connection -> {
RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
byte[] value = connection.get(serializer.serialize(key));
return serializer.deserialize(value);
});
return result;
}
/**
* 存储
*
* @param key
* @param value
* @return
*/
public boolean set(final String key, final String value) {
boolean result = redisTemplate.execute((RedisCallback<Boolean>) connection -> {
RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
connection.set(serializer.serialize(key), serializer.serialize(value));
return true;
});
return result;
}
/**
* 过期存储
*
* @param key
* @param value
* @param expirationTime 过期时间
* @return
*/
public boolean set(final String key, final String value, final long expirationTime) {
boolean result = redisTemplate.execute((RedisCallback<Boolean>) connection -> {
RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
connection.set(serializer.serialize(key), serializer.serialize(value), Expiration.seconds(expirationTime),
RedisStringCommands.SetOption.UPSERT);
return true;
});
return result;
}
/**
* 删除缓存
*
* @param key
* @return
*/
public boolean delete(final String key) {
boolean result = redisTemplate.execute((RedisCallback<Boolean>) connection -> {
RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
connection.del(serializer.serialize(key));
return true;
});
return result;
}
/**
* 哈希 添加
*
* @param key
* @param hashKey
* @param value
*/
public boolean setHash(String key, String hashKey, String value) {
return redisTemplate.execute((RedisCallback<Boolean>) connection -> {
RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
connection.hSet(serializer.serialize(key), serializer.serialize(hashKey), serializer.serialize(value));
return true;
});
}
/**
* 哈希获取数据
*
* @param key
* @param hashKey
* @return
*/
public Object getHash(String key, String hashKey) {
return redisTemplate.execute((RedisCallback<Boolean>) connection -> {
RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
connection.hGet(serializer.serialize(key), serializer.serialize(hashKey));
return true;
});
}
/**
* 列表添加
*
* @param key
* @param value
*/
public boolean rPush(String key, String value) {
return redisTemplate.execute((RedisCallback<Boolean>) connection -> {
RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
connection.rPush(serializer.serialize(key), new byte[][]{serializer.serialize(value)});
return true;
});
}
/**
* 列表获取
*
* @param key
* @param l
* @param l1
* @return
*/
public List<?> lRange(String key, long l, long l1) {
ListOperations<String, ?> list = redisTemplate.opsForList();
return list.range(key, l, l1);
}
/**
* 集合添加
*
* @param key
* @param value
*/
public void add(String key, String value) {
redisTemplate.opsForSet().add(key, value);
}
/**
* 集合获取
*
* @param key
* @return
*/
public Set<String> setMembers(String key) {
return redisTemplate.opsForSet().members(key);
}
/**
* 有序集合添加
*
* @param key
* @param value
* @param scoure
*/
public void zAdd(String key, String value, double scoure) {
ZSetOperations<String, String> zset = redisTemplate.opsForZSet();
zset.add(key, value, scoure);
}
/**
* 有序集合获取
*
* @param key
* @param scoure
* @param scoure1
* @return
*/
public Set<String> rangeByScore(String key, double scoure, double scoure1) {
ZSetOperations<String, String> zset = redisTemplate.opsForZSet();
return zset.rangeByScore(key, scoure, scoure1);
}
/**
* 获取Redis锁
*
* @param key 锁键值
* @param lockTime 锁时间
* @return 是否获取成功
*/
public Boolean getLock(String key, Long lockTime) {
String lock = this.get(key);
if (lock == null) {
this.set(key, "lock", lockTime);
return true;
}
return false;
}
/**
* 删除redis锁
*
* @param key
* @return
*/
public boolean del(String key) {
return stringRedisTemplate.delete(key);
}
private static final Long RELEASE_SUCCESS = 1L;
private static final String LOCK_SUCCESS = "OK";
private static final long WAIT_TIMEOUT = 10; // 获取锁的最大等待时间,单位为秒
/**
* 获取分布式锁
*
* @param lockKey 锁
* @param requestId 请求标识
* @param expireTime 超期时间
* @return 是否获取成功
*/
public boolean lock(String lockKey, String requestId, int expireTime) {
try {
expireTime = 1000 * expireTime;
String result = jedisCluster.set(lockKey, requestId, "NX", "PX", expireTime);
return LOCK_SUCCESS.equals(result);
} catch (Exception e) {
log.error("tryLock is error", e);
return false;
}
}
/**
* 尝试获取分布式锁
*
* @param lockKey 锁
* @param requestId 请求标识
* @param expireTime 超期时间
* @return 是否获取成功
*/
public boolean tryLock(String lockKey, String requestId, int expireTime) {
long start = System.currentTimeMillis();
try {
while (true) {
expireTime = 1000 * expireTime;
String result = jedisCluster.set(lockKey, requestId, "NX", "PX", expireTime);
if (LOCK_SUCCESS.equals(result)) {
return true; // 获取锁成功
}
// 判断是否超时
if (System.currentTimeMillis() - start > WAIT_TIMEOUT * 1000) {
return false;
}
// 休眠一段时间后重试
TimeUnit.MILLISECONDS.sleep(100);
}
} catch (Exception e) {
log.error("tryLock is error", e);
return false;
}
}
/**
* 释放分布式锁
*
* @param lockKey 锁
* @param requestId 请求标识
* @return 是否释放成功
*/
public boolean unLock(String lockKey, String requestId) {
try {
//eval命令执行Lua代码的时候,Lua代码将被当成一个命令去执行,并且直到eval命令执行完成,Redis才会执行其他命令
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Object result = jedisCluster.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
return RELEASE_SUCCESS.equals(result);
} catch (Exception e) {
log.error("unLock is error", e);
return false;
}
}
}
spring: spring:
# redis: redis:
# database: 0 database: 0
# cluster: cluster:
# nodes: 39.105.23.253:6382,39.106.26.175:6381,101.200.127.120:6382 nodes: redis-node1:6371,redis-node2:6372,redis-node3:6373
# timeout: 3600 timeout: 3600
# jedis: jedis:
# shutdown-timeout: 3600 shutdown-timeout: 3600
# pool: pool:
# max-wait: -1 max-wait: -1
# max-active: 300 max-active: 300
# max-idle: 8 max-idle: 8
# min-idle: 2 min-idle: 2
datasource: datasource:
driver-class-name: com.mysql.jdbc.Driver driver-class-name: com.mysql.jdbc.Driver
username: root username: root
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论