租赁系统

This commit is contained in:
yyb
2026-01-05 15:46:59 +08:00
parent 61fa33c27c
commit 5559163b2e
385 changed files with 33178 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
package com.m2pool.lease.redis;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @Description 用户登录对象
* @Date 2024/6/11 14:13
* @Author dy
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EmailCodeValue implements Serializable {
private String email;
private String emailCode;
private int times;
}

View File

@@ -0,0 +1,115 @@
package com.m2pool.lease.redis;
/**
* @Description 用户权限redis
* @Date 2025/12/23 16:19
* @Author yyb
*/
public class RedisAuthKey {
private static final String LOGIN_CODE_KEY= "login:code";
private static final String REGISTER_CODE_KEY= "register:code";
private static final String UPDATE_PASSWORD_CODE_KEY= "update:password:code";
private static final String USER_LOCK_KEY= "user:lock";
private static final String PASSWORD_ERROR_COUNT_KEY= "password:error:count";
private static final String USER_LOGIN_KEY= "user:login";
private static final String GOOGLE_BIND_CODE_KEY = "google:bind:code";
private static final String GOOGLE_CLOSE_CODE_KEY= "google:close:code";
private static final String GOOGLE_OPEN_CODE_KEY= "google:open:code";
private static final String CLOSE_ACCOUNT_KEY= "close:account";
/**
* 获取登录验证码key
* @param email
* @return
*/
public static String getLoginCodeKey(String email) {
return LOGIN_CODE_KEY + ":" + email;
}
/**
* 获取注册验证码key
* @param email
* @return
*/
public static String getRegisterCodeKey(String email) {
return REGISTER_CODE_KEY + ":" + email;
}
/**
* 获取修改密码验证码key
* @param email
* @return
*/
public static String getUpdatePasswordCodeKey(String email) {
return UPDATE_PASSWORD_CODE_KEY + ":" + email;
}
/**
* 获取用户密码输入次数过多 禁止登录 key
* @param email
* @return
*/
public static String getUserLockKey(String email) {
return USER_LOCK_KEY + ":" + email;
}
/**
* 获取用户密码输入次数 key
* @param email
* @return
*/
public static String getPasswordErrorCountKey(String email) {
return PASSWORD_ERROR_COUNT_KEY + ":" + email;
}
/**
* 获取用户登录信息 key
* @param email
* @return
*/
public static String getUserLoginKey(String email) {
return USER_LOGIN_KEY + ":" + email;
}
/**
* 获取用户谷歌bind验证码 key
* @param email
* @return
*/
public static String getGoogleBindCodeKey(String email) {
return GOOGLE_BIND_CODE_KEY + ":" + email;
}
/**
* 获取用户谷歌关闭验证码 key
* @param email
* @return
*/
public static String getGoogleCloseCodeKey(String email) {
return GOOGLE_CLOSE_CODE_KEY + ":" + email;
}
/**
* 获取用户谷歌验证开启 key
* @param email
* @return
*/
public static String getGoogleOpenCodeKey(String email) {
return GOOGLE_BIND_CODE_KEY + ":" + email;
}
public static String getCloseAccountKey(String email) {
return CLOSE_ACCOUNT_KEY + ":" + email;
}
}

View File

@@ -0,0 +1,72 @@
package com.m2pool.lease.redis;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* @Description redis key
* @Date 2025/8/18 09:49
* @Author yyb
*/
public class RedisCoinInfoKey {
// 静态不可变的 Map存储币种名和对应价格标识
private static final Map<String, String> COIN_PRICE_MAP;
private static final Map<String, String> COIN_MHS_MAP;
private static final Map<String, String> COIN_REWARD_MAP;
static {
Map<String, String> mapPrice = new HashMap<>();
mapPrice.put("nexa", "nexa:price");
mapPrice.put("mona", "mona:price");
mapPrice.put("rxd", "rxd:price");
mapPrice.put("grs", "grs:price");
mapPrice.put("dgbs","dgb:price");
mapPrice.put("dgbq","dgb:price");
mapPrice.put("dgbo","dgb:price");
mapPrice.put("alph","alph:price");
mapPrice.put("eth","eth:price");
Map<String, String> mapMhs = new HashMap<>();
mapMhs.put("nexa", "nexa:mhs");
mapMhs.put("mona", "mona:mhs");
mapMhs.put("rxd", "rxd:mhs");
mapMhs.put("grs", "grs:mhs");
mapMhs.put("dgbo","dgbo:mhs");
mapMhs.put("dgbq","dgbq:mhs");
mapMhs.put("dgbs","dgbs:mhs");
mapMhs.put("alph","alph:mhs");
Map<String, String> mapReward = new HashMap<>();
mapReward.put("nexa", "nexa:reward");
mapReward.put("mona", "mona:reward");
mapReward.put("rxd", "rxd:reward");
mapReward.put("grs", "grs:reward");
mapReward.put("dgbs","dgb:reward");
mapReward.put("dgbq","dgb:reward");
mapReward.put("dgbo","dgb:reward");
mapReward.put("alph","alph:reward");
COIN_PRICE_MAP = Collections.unmodifiableMap(mapPrice);
COIN_MHS_MAP = Collections.unmodifiableMap(mapMhs);
COIN_REWARD_MAP = Collections.unmodifiableMap(mapReward);
}
/**
* 根据币种名获取对应的价格标识
* @param coinName 币种名
* @return 对应的价格标识,若不存在则返回 null
*/
public static String getPiceKey(String coinName) {
return COIN_PRICE_MAP.get(coinName);
}
public static String getMhsKey(String coinName) {
return COIN_MHS_MAP.get(coinName);
}
public static String getRewardKey(String coinName) {
return COIN_REWARD_MAP.get(coinName);
}
}

View File

@@ -0,0 +1,73 @@
package com.m2pool.lease.redis.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.util.Assert;
import java.nio.charset.Charset;
/**
* @Description redis使用FastJson序列化
* @Date 2024/6/13 10:01
* @Author dy
*/
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {
@SuppressWarnings("unused")
private ObjectMapper objectMapper = new ObjectMapper();
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class<T> clazz;
static
{
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
}
public FastJson2JsonRedisSerializer(Class<T> clazz)
{
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException
{
if (t == null)
{
return new byte[0];
}
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException
{
if (bytes == null || bytes.length <= 0)
{
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return JSON.parseObject(str, clazz);
}
public void setObjectMapper(ObjectMapper objectMapper)
{
Assert.notNull(objectMapper, "'objectMapper' must not be null");
this.objectMapper = objectMapper;
}
protected JavaType getJavaType(Class<?> clazz)
{
return TypeFactory.defaultInstance().constructType(clazz);
}
}

View File

@@ -0,0 +1,139 @@
package com.m2pool.lease.redis.config;//package com.m2pool.lease.redis.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @Description redis配置
* @Date 2024/6/13 09:58
* @Author dy
*/
@RefreshScope
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.database:0}")
private int database = 0;
@Bean
@SuppressWarnings(value = { "unchecked", "rawtypes" })
public RedisTemplate<Object, Object> redisTemplate(@Qualifier("redisConnectionFactory0") RedisConnectionFactory connectionFactory)
{
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
serializer.setObjectMapper(mapper);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
// Hash的key也采用StringRedisSerializer的序列化方式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
@Bean(name = "redisTemplate7")
public RedisTemplate<Object, Object> redisTemplate7(@Qualifier("redisConnectionFactory7") RedisConnectionFactory redisConnectionFactory0) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory0);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new StringRedisSerializer());
return template;
}
/**
* 7号 数据库 - >
* @return
*/
@Bean
public RedisConnectionFactory redisConnectionFactory7() {
LettuceConnectionFactory factory = new LettuceConnectionFactory();
factory.setHostName(host);
factory.setPort(port);
factory.setDatabase(7);
return factory;
}
/**
* 默认 数据库
* @return
*/
@Bean
@Primary //添加@Primary默认使用的库
public RedisConnectionFactory redisConnectionFactory0() {
LettuceConnectionFactory factory = new LettuceConnectionFactory();
factory.setHostName(host);
factory.setPort(port);
factory.setDatabase(database);
return factory;
}
@Bean
public DefaultRedisScript<Long> limitScript()
{
// 泛型是返回值的类型
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
// 设置脚本
redisScript.setScriptText(limitScriptText());
// 设置返回值类型
redisScript.setResultType(Long.class);
return redisScript;
}
/**
* 限流脚本
*/
private String limitScriptText()
{
return "local key = KEYS[1]\n" +
"local count = tonumber(ARGV[1])\n" +
"local time = tonumber(ARGV[2])\n" +
"local current = redis.call('get', key);\n" +
"if current and tonumber(current) > count then\n" +
" return tonumber(current);\n" +
"end\n" +
"current = redis.call('incr', key)\n" +
"if tonumber(current) == 1 then\n" +
" redis.call('expire', key, time)\n" +
"end\n" +
"return tonumber(current);";
}
}

View File

@@ -0,0 +1,313 @@
package com.m2pool.lease.redis.service;//package com.m2pool.lease.redis.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* @Description redis 相关
* @Date 2024/6/13 9:22
* @Author dy
*/
@SuppressWarnings(value = { "unchecked", "rawtypes" })
@Component
public class RedisService {
@Autowired
@Qualifier("redisTemplate")
private RedisTemplate redisTemplate;
@Autowired
@Qualifier("redisTemplate7")
private RedisTemplate redisTemplate7;
/**
* 缓存基本的对象Integer、String、实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
*/
public <T> void setCacheObject(final String key, final T value)
{
redisTemplate.opsForValue().set(key, value);
}
/**
* 缓存基本的对象Integer、String、实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
* @param timeout 时间
* @param timeUnit 时间颗粒度
*/
public <T> void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit)
{
redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
}
public <T> void setCacheObject7(final String key, final T value, final Long timeout, final TimeUnit timeUnit)
{
redisTemplate7.opsForValue().set(key, value, timeout, timeUnit);
}
/**
* 设置有效时间
*
* @param key Redis键
* @param timeout 超时时间
* @return true=设置成功false=设置失败
*/
public boolean expire(final String key, final long timeout)
{
return expire(key, timeout, TimeUnit.SECONDS);
}
/**
* 设置有效时间
*
* @param key Redis键
* @param timeout 超时时间
* @param unit 时间单位
* @return true=设置成功false=设置失败
*/
public boolean expire(final String key, final long timeout, final TimeUnit unit)
{
return redisTemplate.expire(key, timeout, unit);
}
/**
* 获取有效时间
*
* @param key Redis键
* @return 有效时间
*/
public long getExpire(final String key)
{
return redisTemplate.getExpire(key);
}
/**
* 获取有效时间
*
* @param key Redis键
* @return 有效时间
*/
public long getExpire(final String key,TimeUnit timetype)
{
return redisTemplate.getExpire(key,timetype);
}
/**
* 判断 key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public Boolean hasKey(String key)
{
return redisTemplate.hasKey(key);
}
/**
* 获得缓存的基本对象。
*
* @param key 缓存键值
* @return 缓存键值对应的数据
*/
public <T> T getCacheObject(final String key)
{
ValueOperations<String, T> operation = redisTemplate.opsForValue();
return operation.get(key);
}
public <T> T getCacheObject7(final String key)
{
ValueOperations<String, T> operation = redisTemplate7.opsForValue();
return operation.get(key);
}
/**
* 所有数字类型转换为BigDecimal
* @param key 缓存键值
* @return 缓存键值对应数据
*/
public BigDecimal getCacheBigDecimal(final String key) {
ValueOperations<String, Object> operation = redisTemplate.opsForValue();
Object value = operation.get(key);
if (value != null) {
if (value instanceof BigDecimal) {
return (BigDecimal) value;
} else if (value instanceof String) {
try {
return new BigDecimal((String) value);
} catch (NumberFormatException e) {
// 处理字符串无法转换为 BigDecimal 的情况
return null;
}
} else if (value instanceof Number) {
return new BigDecimal(value.toString());
}
}
return null;
}
/**
* 删除单个对象
*
* @param key
*/
public boolean deleteObject(final String key)
{
return redisTemplate.delete(key);
}
/**
* 删除集合对象
*
* @param collection 多个对象
* @return
*/
public long deleteObject(final Collection collection)
{
return redisTemplate.delete(collection);
}
/**
* 缓存List数据
*
* @param key 缓存的键值
* @param dataList 待缓存的List数据
* @return 缓存的对象
*/
public <T> long setCacheList(final String key, final List<T> dataList)
{
Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
return count == null ? 0 : count;
}
/**
* 获得缓存的list对象
*
* @param key 缓存的键值
* @return 缓存键值对应的数据
*/
public <T> List<T> getCacheList(final String key)
{
return redisTemplate.opsForList().range(key, 0, -1);
}
/**
* 缓存Set
*
* @param key 缓存键值
* @param dataSet 缓存的数据
* @return 缓存数据的对象
*/
public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet)
{
BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
Iterator<T> it = dataSet.iterator();
while (it.hasNext())
{
setOperation.add(it.next());
}
return setOperation;
}
/**
* 获得缓存的set
*
* @param key
* @return
*/
public <T> Set<T> getCacheSet(final String key)
{
return redisTemplate.opsForSet().members(key);
}
/**
* 缓存Map
*
* @param key
* @param dataMap
*/
public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
{
if (dataMap != null) {
redisTemplate.opsForHash().putAll(key, dataMap);
}
}
/**
* 获得缓存的Map
*
* @param key
* @return
*/
public <T> Map<String, T> getCacheMap(final String key)
{
return redisTemplate.opsForHash().entries(key);
}
/**
* 往Hash中存入数据
*
* @param key Redis键
* @param hKey Hash键
* @param value 值
*/
public <T> void setCacheMapValue(final String key, final String hKey, final T value)
{
redisTemplate.opsForHash().put(key, hKey, value);
}
/**
* 获取Hash中的数据
*
* @param key Redis键
* @param hKey Hash键
* @return Hash中的对象
*/
public <T> T getCacheMapValue(final String key, final String hKey)
{
HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
return opsForHash.get(key, hKey);
}
/**
* 获取多个Hash中的数据
*
* @param key Redis键
* @param hKeys Hash键集合
* @return Hash对象集合
*/
public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
{
return redisTemplate.opsForHash().multiGet(key, hKeys);
}
/**
* 获得缓存的基本对象列表
*
* @param pattern 字符串前缀
* @return 对象列表
*/
public Collection<String> keys(final String pattern)
{
return redisTemplate.keys(pattern);
}
}