版本管理(控制LDBA-APP 零点八零)

字典复用
This commit is contained in:
wangw 2024-04-02 14:27:06 +08:00
parent 1d93bc217c
commit 5f633fefb6
18 changed files with 586 additions and 60 deletions

View File

@ -19,11 +19,15 @@ import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.serializer.SerializerFeature;
import io.lettuce.core.RedisClient;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties; import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.Cache; import org.springframework.cache.Cache;
import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.CachingConfigurerSupport;
@ -32,8 +36,11 @@ import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisOperations; import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializationContext;
@ -54,9 +61,44 @@ import java.util.Map;
@Configuration @Configuration
@EnableCaching @EnableCaching
@ConditionalOnClass(RedisOperations.class) @ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class) //@EnableConfigurationProperties(RedisProperties.class)
public class RedisConfig extends CachingConfigurerSupport { public class RedisConfig extends CachingConfigurerSupport {
@Autowired
private RedisProperties redisProperties;
@Bean
@Primary
public RedisConnectionFactory redisConnectionFactory() {
LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisProperties.getHost(), redisProperties.getPort());
lettuceConnectionFactory.setPassword(redisProperties.getPassword());
lettuceConnectionFactory.setDatabase(redisProperties.getDatabase());
return lettuceConnectionFactory;
}
@Bean
public RedisConnectionFactory redisConnectionFactory5() {
LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisProperties.getHost(), redisProperties.getPort());
lettuceConnectionFactory.setPassword(redisProperties.getPassword());
lettuceConnectionFactory.setDatabase(5);
return lettuceConnectionFactory;
}
@Bean(name = "redis5Template")
public RedisTemplate<Object, Object> redis5Template(@Qualifier("redisConnectionFactory5") RedisConnectionFactory redisConnectionFactory5) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
//序列化
FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
// value值的序列化采用fastJsonRedisSerializer
template.setValueSerializer(fastJsonRedisSerializer);
template.setHashValueSerializer(fastJsonRedisSerializer);
// key的序列化采用StringRedisSerializer
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setConnectionFactory(redisConnectionFactory5);
// 配置序列化等信息
return template;
}
/** /**
* 设置 redis 数据默认过期时间默认2小时 * 设置 redis 数据默认过期时间默认2小时
* 设置@cacheable 序列化方式 * 设置@cacheable 序列化方式
@ -73,7 +115,7 @@ public class RedisConfig extends CachingConfigurerSupport {
@SuppressWarnings("all") @SuppressWarnings("all")
@Bean(name = "redisTemplate") @Bean(name = "redisTemplate")
@ConditionalOnMissingBean(name = "redisTemplate") @ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { public RedisTemplate<Object, Object> redisTemplate(@Qualifier("redisConnectionFactory")RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>(); RedisTemplate<Object, Object> template = new RedisTemplate<>();
//序列化 //序列化
FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
@ -83,16 +125,11 @@ public class RedisConfig extends CachingConfigurerSupport {
// fastjson 升级到 1.2.83 后需要指定序列化白名单 // fastjson 升级到 1.2.83 后需要指定序列化白名单
ParserConfig.getGlobalInstance().addAccept("cn.ysk.cashier.pojo"); ParserConfig.getGlobalInstance().addAccept("cn.ysk.cashier.pojo");
ParserConfig.getGlobalInstance().addAccept("cn.ysk.cashier.service"); ParserConfig.getGlobalInstance().addAccept("cn.ysk.cashier.service");
// 模块内的实体类
// ParserConfig.getGlobalInstance().addAccept("cn.ysk.cashier.mnt.domain");
// ParserConfig.getGlobalInstance().addAccept("cn.ysk.cashier.quartz.domain");
// ParserConfig.getGlobalInstance().addAccept("cn.ysk.cashier.system.domain");
// 模块内的 Dto // 模块内的 Dto
ParserConfig.getGlobalInstance().addAccept("cn.ysk.cashier.mnt"); ParserConfig.getGlobalInstance().addAccept("cn.ysk.cashier.mnt");
ParserConfig.getGlobalInstance().addAccept("cn.ysk.cashier.system"); ParserConfig.getGlobalInstance().addAccept("cn.ysk.cashier.system");
ParserConfig.getGlobalInstance().addAccept("cn.ysk.cashier.quartz"); ParserConfig.getGlobalInstance().addAccept("cn.ysk.cashier.quartz");
ParserConfig.getGlobalInstance().addAccept("cn.ysk.cashier.config"); ParserConfig.getGlobalInstance().addAccept("cn.ysk.cashier.config");
// ParserConfig.getGlobalInstance().addAccept("cn.ysk.cashier.system.service.dto");
// key的序列化采用StringRedisSerializer // key的序列化采用StringRedisSerializer
template.setKeySerializer(new StringRedisSerializer()); template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer());
@ -107,17 +144,17 @@ public class RedisConfig extends CachingConfigurerSupport {
@Override @Override
public KeyGenerator keyGenerator() { public KeyGenerator keyGenerator() {
return (target, method, params) -> { return (target, method, params) -> {
Map<String,Object> container = new HashMap<>(8); Map<String, Object> container = new HashMap<>(8);
Class<?> targetClassClass = target.getClass(); Class<?> targetClassClass = target.getClass();
// 类地址 // 类地址
container.put("class",targetClassClass.toGenericString()); container.put("class", targetClassClass.toGenericString());
// 方法名称 // 方法名称
container.put("methodName",method.getName()); container.put("methodName", method.getName());
// 包名称 // 包名称
container.put("package",targetClassClass.getPackage()); container.put("package", targetClassClass.getPackage());
// 参数列表 // 参数列表
for (int i = 0; i < params.length; i++) { for (int i = 0; i < params.length; i++) {
container.put(String.valueOf(i),params[i]); container.put(String.valueOf(i), params[i]);
} }
// 转为JSON字符串 // 转为JSON字符串
String jsonString = JSON.toJSONString(container); String jsonString = JSON.toJSONString(container);
@ -159,10 +196,10 @@ public class RedisConfig extends CachingConfigurerSupport {
/** /**
* Value 序列化 * Value 序列化
* *
* @author /
* @param <T> * @param <T>
* @author /
*/ */
class FastJsonRedisSerializer<T> implements RedisSerializer<T> { class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
private final Class<T> clazz; private final Class<T> clazz;
@ -213,14 +250,14 @@ class StringRedisSerializer implements RedisSerializer<Object> {
return (bytes == null ? null : new String(bytes, charset)); return (bytes == null ? null : new String(bytes, charset));
} }
@Override @Override
public @Nullable byte[] serialize(Object object) { public @Nullable byte[] serialize(Object object) {
String string = JSON.toJSONString(object); String string = JSON.toJSONString(object);
if (org.apache.commons.lang3.StringUtils.isBlank(string)) { if (org.apache.commons.lang3.StringUtils.isBlank(string)) {
return null; return null;
} }
string = string.replace("\"", ""); string = string.replace("\"", "");
return string.getBytes(charset); return string.getBytes(charset);
} }
} }

View File

@ -19,11 +19,14 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*; import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.data.redis.core.RedisConnectionUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -38,14 +41,22 @@ import java.util.concurrent.TimeUnit;
public class RedisUtils { public class RedisUtils {
private static final Logger log = LoggerFactory.getLogger(RedisUtils.class); private static final Logger log = LoggerFactory.getLogger(RedisUtils.class);
private RedisTemplate<Object, Object> redisTemplate; private RedisTemplate<Object, Object> redisTemplate;
private RedisTemplate<Object, Object> redisTemplate5;
@Value("${jwt.online-key}") @Value("${jwt.online-key}")
private String onlineKey; private String onlineKey;
public RedisUtils(RedisTemplate<Object, Object> redisTemplate) { public RedisUtils(RedisTemplate<Object, Object> redisTemplate,@Qualifier("redis5Template")RedisTemplate<Object, Object> redisTemplate5) {
this.redisTemplate = redisTemplate; this.redisTemplate = redisTemplate;
this.redisTemplate.setHashKeySerializer(new StringRedisSerializer()); this.redisTemplate.setHashKeySerializer(new StringRedisSerializer());
this.redisTemplate.setKeySerializer(new StringRedisSerializer()); this.redisTemplate.setKeySerializer(new StringRedisSerializer());
this.redisTemplate.setStringSerializer(new StringRedisSerializer()); this.redisTemplate.setStringSerializer(new StringRedisSerializer());
this.redisTemplate5 = redisTemplate5;
this.redisTemplate5.setHashKeySerializer(new StringRedisSerializer());
this.redisTemplate5.setKeySerializer(new StringRedisSerializer());
this.redisTemplate5.setStringSerializer(new StringRedisSerializer());
} }
/** /**
@ -218,7 +229,7 @@ public class RedisUtils {
public List<Object> multiGet(List<String> keys) { public List<Object> multiGet(List<String> keys) {
List list = redisTemplate.opsForValue().multiGet(Sets.newHashSet(keys)); List list = redisTemplate.opsForValue().multiGet(Sets.newHashSet(keys));
List resultList = Lists.newArrayList(); List resultList = Lists.newArrayList();
Optional.ofNullable(list).ifPresent(e-> list.forEach(ele-> Optional.ofNullable(ele).ifPresent(resultList::add))); Optional.ofNullable(list).ifPresent(e -> list.forEach(ele -> Optional.ofNullable(ele).ifPresent(resultList::add)));
return resultList; return resultList;
} }
@ -717,6 +728,7 @@ public class RedisUtils {
/** /**
* 根据 prefix+id 删除key 不做模糊匹配 * 根据 prefix+id 删除key 不做模糊匹配
*
* @param prefix 前缀 * @param prefix 前缀
* @param ids id * @param ids id
*/ */
@ -732,19 +744,74 @@ public class RedisUtils {
log.info("缓存删除数量:" + count + ""); log.info("缓存删除数量:" + count + "");
log.info("--------------------------------------------"); log.info("--------------------------------------------");
} }
/** /**
* redis 库存操作 * redis 库存操作
*
* @param type 1为修改库存 2为移除库存 * @param type 1为修改库存 2为移除库存
* @param map k: * @param map k:
*/ */
public void redisUp(Integer type,String shopId,Map<Integer,Double> map) { public void redisUp(Integer type, String shopId, Map<Integer, Double> map) {
String redisKey= CacheKey.PRODUCT_SKU+shopId+ ":"; String redisKey = CacheKey.PRODUCT_SKU + shopId + ":";
if(type==1) { if (type == 1) {
for (Map.Entry<Integer, Double> entry : map.entrySet()) { for (Map.Entry<Integer, Double> entry : map.entrySet()) {
incrBy(redisKey+entry.getKey(),entry.getValue()); incrBy(redisKey + entry.getKey(), entry.getValue());
} }
} else if (type == 2) { } else if (type == 2) {
delByIntKey(redisKey,map.keySet()); delByIntKey(redisKey, map.keySet());
} }
} }
// ================================================================
/****************************** redis 5库 *************************/
/**
* 普通缓存放入
* redis5库 (零点八零app库)
*
* @param key
* @param value
* @return true成功 false失败
*/
public boolean set5(String key, Object value) {
try {
redisTemplate5.opsForValue().set(key, value);
// redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 删除缓存
* redis5库 (零点八零app库)
*
* @param key 可以传一个值 或多个
*/
public void del5(String... keys) {
if (keys != null && keys.length > 0) {
if (keys.length == 1) {
boolean result = redisTemplate5.delete(keys[0]);
log.debug("--------------------------------------------");
log.debug(new StringBuilder("删除缓存:").append(keys[0]).append(",结果:").append(result).toString());
log.debug("--------------------------------------------");
} else {
Set<Object> keySet = new HashSet<>();
for (String key : keys) {
keySet.addAll(redisTemplate5.keys(key));
}
long count = redisTemplate5.delete(keySet);
log.debug("--------------------------------------------");
log.debug("成功删除缓存:" + keySet.toString());
log.debug("缓存删除数量:" + count + "");
log.debug("--------------------------------------------");
}
}
}
} }

View File

@ -0,0 +1,53 @@
package cn.ysk.cashier.controller;
import cn.ysk.cashier.annotation.Log;
import cn.ysk.cashier.dto.TbVersionQueryCriteria;
import cn.ysk.cashier.pojo.TbVersion;
import cn.ysk.cashier.service.TbVersionService;
import org.springframework.data.domain.Pageable;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
@RestController
@RequiredArgsConstructor
@Api(tags = "版本管理")
@RequestMapping("/api/tbVersion")
public class TbVersionController {
private final TbVersionService tbVersionService;
@GetMapping
@Log("查询版本")
@ApiOperation("查询版本")
public ResponseEntity<Object> queryTbVersion(TbVersionQueryCriteria criteria){
return new ResponseEntity<>(tbVersionService.queryAllPage(criteria),HttpStatus.OK);
}
@PostMapping
@Log("新增版本")
@ApiOperation("新增版本")
public ResponseEntity<Object> createTbVersion(@Validated @RequestBody TbVersion resources){
return new ResponseEntity<>(tbVersionService.create(resources),HttpStatus.CREATED);
}
@PutMapping
@Log("修改版本")
@ApiOperation("修改版本")
public ResponseEntity<Object> updateTbVersion(@Validated @RequestBody TbVersion resources){
tbVersionService.update(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@DeleteMapping
@Log("删除版本")
@ApiOperation("删除版本")
public ResponseEntity<Object> deleteTbVersion(@RequestBody Integer[] ids) {
tbVersionService.deleteAll(ids);
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@ -0,0 +1,37 @@
package cn.ysk.cashier.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @website https://eladmin.vip
* @description /
* @author ww
* @date 2024-03-29
**/
@Data
public class TbVersionDto implements Serializable {
private Integer id;
/** LDBL_APP;WX; */
private String source;
/** ios;android; */
private String type;
/** 版本号 */
private String version;
/** 0不更新1更新 */
private Integer isUp;
/** 更新提示内容 */
private String message;
/** 创建时间 */
private Long createdAt;
/** 更新时间 */
private Long updatedAt;
}

View File

@ -0,0 +1,33 @@
package cn.ysk.cashier.dto;
import cn.ysk.cashier.annotation.Query;
import lombok.Data;
/**
* @website https://eladmin.vip
* @author ww
* @date 2024-03-29
**/
@Data
public class TbVersionQueryCriteria{
@Query
/** LDBL-APP;WX; */
private String source;
@Query
/** ios;android; */
private String type;
@Query
/** 版本号 */
private String version;
@Query
/** 0不更新1更新 */
private Integer isUp;
private Integer pageSize;
private Integer page;
private String sort;
}

View File

@ -0,0 +1,12 @@
package cn.ysk.cashier.mapper;
import cn.ysk.cashier.base.BaseMapper;
import cn.ysk.cashier.dto.TbVersionDto;
import cn.ysk.cashier.pojo.TbVersion;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface TbVersionMapper extends BaseMapper<TbVersionDto, TbVersion> {
}

View File

@ -0,0 +1,52 @@
package cn.ysk.cashier.pojo;
import lombok.Data;
import cn.hutool.core.bean.BeanUtil;
import io.swagger.annotations.ApiModelProperty;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import java.io.Serializable;
@Entity
@Data
@Table(name="tb_version")
public class TbVersion implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "`id`")
@ApiModelProperty(value = "id")
private Integer id;
@Column(name = "`source`")
@ApiModelProperty(value = "LDBL-APP;WX;")
private String source;
@Column(name = "`type`")
@ApiModelProperty(value = "ios;android;")
private String type;
@Column(name = "`version`")
@ApiModelProperty(value = "版本号")
private String version;
@Column(name = "`is_up`")
@ApiModelProperty(value = "0不更新1更新")
private Integer isUp;
@Column(name = "`message`")
@ApiModelProperty(value = "更新提示内容")
private String message;
@Column(name = "`created_at`")
@ApiModelProperty(value = "创建时间")
private Long createdAt;
@Column(name = "`updated_at`")
@ApiModelProperty(value = "更新时间")
private Long updatedAt;
public void copy(TbVersion source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}

View File

@ -0,0 +1,18 @@
package cn.ysk.cashier.repository;
import cn.ysk.cashier.pojo.TbVersion;
import org.apache.ibatis.annotations.Param;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
/**
* @author ww
* @website https://eladmin.vip
* @date 2024-03-29
**/
public interface TbVersionRepository extends JpaRepository<TbVersion, Integer>, JpaSpecificationExecutor<TbVersion> {
@Query("SELECT count(1) FROM TbVersion WHERE source = :name AND type =:type AND version =:version")
int isExist(@Param("type") String type, @Param("name") String name, @Param("version") String version);
}

View File

@ -0,0 +1,60 @@
package cn.ysk.cashier.service;
import cn.ysk.cashier.dto.TbPlatformDictQueryCriteria;
import cn.ysk.cashier.dto.TbVersionDto;
import cn.ysk.cashier.dto.TbVersionQueryCriteria;
import cn.ysk.cashier.pojo.TbVersion;
import org.springframework.data.domain.Pageable;
import java.util.List;
import java.util.Map;
/**
* @website https://eladmin.vip
* @description 服务接口
* @author ww
* @date 2024-03-29
**/
public interface TbVersionService {
/**
* 查询数据分页
* @param criteria 条件
* pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAllPage(TbVersionQueryCriteria criteria);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<TbVersionDto>
*/
List<TbVersionDto> queryAll(TbVersionQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return TbVersionDto
*/
TbVersionDto findById(Integer id);
/**
* 创建
* @param resources /
* @return TbVersionDto
*/
TbVersionDto create(TbVersion resources);
/**
* 编辑
* @param resources /
*/
void update(TbVersion resources);
/**
* 多选删除
* @param ids /
*/
void deleteAll(Integer[] ids);
}

View File

@ -0,0 +1,108 @@
package cn.ysk.cashier.service.impl;
import cn.ysk.cashier.dto.TbVersionDto;
import cn.ysk.cashier.dto.TbVersionQueryCriteria;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.mapper.TbVersionMapper;
import cn.ysk.cashier.pojo.TbVersion;
import cn.ysk.cashier.repository.TbVersionRepository;
import cn.ysk.cashier.service.TbVersionService;
import cn.ysk.cashier.utils.PageUtil;
import cn.ysk.cashier.utils.QueryHelp;
import cn.ysk.cashier.utils.RedisUtils;
import cn.ysk.cashier.utils.ValidationUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.Instant;
import java.util.List;
import java.util.Map;
/**
* @author ww
* @website https://eladmin.vip
* @description 服务实现
* @date 2024-03-29
**/
@Service
@RequiredArgsConstructor
public class TbVersionServiceImpl implements TbVersionService {
private final TbVersionRepository tbVersionRepository;
private final TbVersionMapper tbVersionMapper;
private final RedisUtils redisUtils;
@Override
public Map<String, Object> queryAllPage(TbVersionQueryCriteria criteria) {
Pageable pageable = PageRequest.of(criteria.getPage(), criteria.getPageSize(), Sort.by("createdAt"));
Page<TbVersion> page = tbVersionRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
return PageUtil.toPage(page.map(tbVersionMapper::toDto));
}
@Override
public List<TbVersionDto> queryAll(TbVersionQueryCriteria criteria) {
return tbVersionMapper.toDto(tbVersionRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
}
@Override
@Transactional
public TbVersionDto findById(Integer id) {
TbVersion tbVersion = tbVersionRepository.findById(id).orElseGet(TbVersion::new);
ValidationUtil.isNull(tbVersion.getId(), "TbVersion", "id", id);
return tbVersionMapper.toDto(tbVersion);
}
@Override
@Transactional(rollbackFor = Exception.class)
public TbVersionDto create(TbVersion resources) {
int exist = tbVersionRepository.isExist(resources.getSource(), resources.getType(), resources.getVersion());
if (exist > 0) {
throw new BadRequestException("该版本已存在。");
}
resources.setCreatedAt(Instant.now().toEpochMilli());
TbVersionDto dto = tbVersionMapper.toDto(tbVersionRepository.save(resources));
if (dto.getIsUp() == 1) {
//产品标识型号版本
//LDBL_APP_VERSION:ios:version 存在即需要强制更新
redisUtils.set5(dto.getSource() + "_VERSION:" + dto.getType() + ":" + dto.getVersion(), dto.getMessage());
}
return dto;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(TbVersion resources) {
TbVersion tbVersion = tbVersionRepository.findById(resources.getId()).orElseGet(TbVersion::new);
ValidationUtil.isNull(tbVersion.getId(), "TbVersion", "id", resources.getId());
redisUtils.del5(tbVersion.getSource() + "_VERSION:" + tbVersion.getType() + ":" + tbVersion.getVersion());
tbVersion.copy(resources);
tbVersion.setUpdatedAt(Instant.now().toEpochMilli());
tbVersionRepository.save(tbVersion);
if (resources.getIsUp() == 1) {
//产品标识型号版本
//LDBL_APP_VERSION:ios:version 存在即需要强制更新
redisUtils.set5(tbVersion.getSource() + "_VERSION:" + tbVersion.getType() + ":" + tbVersion.getVersion(), tbVersion.getMessage());
} else {
redisUtils.del5(tbVersion.getSource() + "_VERSION:" + tbVersion.getType() + ":" + tbVersion.getVersion());
}
}
@Override
public void deleteAll(Integer[] ids) {
for (Integer id : ids) {
TbVersion tbVersion = tbVersionRepository.findById(id).orElseGet(TbVersion::new);
ValidationUtil.isNull(tbVersion.getId(), "TbVersion", "id", id);
tbVersionRepository.deleteById(id);
if (tbVersion.getIsUp() == 1) {
redisUtils.del5(tbVersion.getSource() + "_VERSION:" + tbVersion.getType() + ":" + tbVersion.getVersion());
}
}
}
}

View File

@ -51,4 +51,8 @@ public class Dict extends BaseEntity implements Serializable {
@ApiModelProperty(value = "描述") @ApiModelProperty(value = "描述")
private String description; private String description;
@Column(name = "is_child")
@ApiModelProperty(value = "描述 是否有子类0否1是")
private Integer isChild;
} }

View File

@ -16,12 +16,14 @@
package cn.ysk.cashier.system.domain; package cn.ysk.cashier.system.domain;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import io.swagger.models.auth.In;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import cn.ysk.cashier.base.BaseEntity; import cn.ysk.cashier.base.BaseEntity;
import javax.persistence.*; import javax.persistence.*;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
/** /**
* @author Zheng Jie * @author Zheng Jie
@ -51,6 +53,11 @@ public class DictDetail extends BaseEntity implements Serializable {
@ApiModelProperty(value = "字典值") @ApiModelProperty(value = "字典值")
private String value; private String value;
@JoinColumn(name = "rele_id")
@ApiModelProperty(value = "自关联id 三级时存在",hidden = true)
private Integer releId;
@ApiModelProperty(value = "排序") @ApiModelProperty(value = "排序")
private Integer dictSort = 999; private Integer dictSort = 999;
} }

View File

@ -18,8 +18,11 @@ package cn.ysk.cashier.system.repository;
import cn.ysk.cashier.system.domain.DictDetail; import cn.ysk.cashier.system.domain.DictDetail;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import java.util.List; import java.util.List;
import java.util.Set;
/** /**
* @author Zheng Jie * @author Zheng Jie
@ -35,4 +38,13 @@ public interface DictDetailRepository extends JpaRepository<DictDetail, Long>, J
List<DictDetail> findByDictName(String name); List<DictDetail> findByDictName(String name);
@Modifying
@Query(value = "delete from sys_dict_detail where rele_id in ?1", nativeQuery = true)
void delAllByIdIn(Set<Long> idSet);
@Modifying
@Query(value = "delete from sys_dict_detail where detail_id = ?1 or rele_id=?1",nativeQuery = true)
void delAllById(Long id);
} }

View File

@ -24,6 +24,7 @@ import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.annotation.Log; import cn.ysk.cashier.annotation.Log;
import cn.ysk.cashier.exception.BadRequestException; import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.system.service.DictDetailService; import cn.ysk.cashier.system.service.DictDetailService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault; import org.springframework.data.web.PageableDefault;
@ -32,14 +33,15 @@ import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* @author Zheng Jie * @author Zheng Jie
* @date 2019-04-10 * @date 2019-04-10
*/ */
@RestController @RestController
@RequiredArgsConstructor @RequiredArgsConstructor
@Api(tags = "系统:字典详情管理") @Api(tags = "系统:字典详情管理")
@ -52,33 +54,20 @@ public class DictDetailController {
@ApiOperation("查询字典详情") @ApiOperation("查询字典详情")
@GetMapping @GetMapping
public ResponseEntity<Object> queryDictDetail(DictDetailQueryCriteria criteria, public ResponseEntity<Object> queryDictDetail(DictDetailQueryCriteria criteria,
@PageableDefault(sort = {"dictSort"}, direction = Sort.Direction.ASC) Pageable pageable){ @PageableDefault(sort = {"dictSort"}, direction = Sort.Direction.ASC) Pageable pageable) {
return new ResponseEntity<>(dictDetailService.queryAll(criteria,pageable),HttpStatus.OK); return new ResponseEntity<>(dictDetailService.queryAll(criteria, pageable), HttpStatus.OK);
}
@ApiOperation("通过dict查询字典详情")
@GetMapping("/{name}")
public ResponseEntity<Object> queryDictById(@PathVariable String name){
return new ResponseEntity<>(dictDetailService.queryName(name),HttpStatus.OK);
}
@ApiOperation("查询多个字典详情")
@GetMapping(value = "/map")
public ResponseEntity<Object> getDictDetailMaps(@RequestParam String dictName){
String[] names = dictName.split("[,]");
Map<String, List<DictDetailDto>> dictMap = new HashMap<>(16);
for (String name : names) {
dictMap.put(name, dictDetailService.getDictByName(name));
}
return new ResponseEntity<>(dictMap, HttpStatus.OK);
} }
@Log("新增字典详情") @Log("新增字典详情")
@ApiOperation("新增字典详情") @ApiOperation("新增字典详情")
@PostMapping @PostMapping
@PreAuthorize("@el.check('dict:add')") @PreAuthorize("@el.check('dict:add')")
public ResponseEntity<Object> createDictDetail(@Validated @RequestBody DictDetail resources){ public ResponseEntity<Object> createDictDetail(@Validated @RequestBody DictDetail resources) {
if (resources.getId() != null) { if (resources.getId() != null) {
throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); throw new BadRequestException("A new " + ENTITY_NAME + " cannot already have an ID");
}
if (resources.getDict() != null && resources.getReleId() != null) {
throw new BadRequestException("参数错误");
} }
dictDetailService.create(resources); dictDetailService.create(resources);
return new ResponseEntity<>(HttpStatus.CREATED); return new ResponseEntity<>(HttpStatus.CREATED);
@ -88,7 +77,7 @@ public class DictDetailController {
@ApiOperation("修改字典详情") @ApiOperation("修改字典详情")
@PutMapping @PutMapping
@PreAuthorize("@el.check('dict:edit')") @PreAuthorize("@el.check('dict:edit')")
public ResponseEntity<Object> updateDictDetail(@Validated(DictDetail.Update.class) @RequestBody DictDetail resources){ public ResponseEntity<Object> updateDictDetail(@Validated(DictDetail.Update.class) @RequestBody DictDetail resources) {
dictDetailService.update(resources); dictDetailService.update(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT); return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} }
@ -97,7 +86,7 @@ public class DictDetailController {
@ApiOperation("删除字典详情") @ApiOperation("删除字典详情")
@DeleteMapping(value = "/{id}") @DeleteMapping(value = "/{id}")
@PreAuthorize("@el.check('dict:del')") @PreAuthorize("@el.check('dict:del')")
public ResponseEntity<Object> deleteDictDetail(@PathVariable Long id){ public ResponseEntity<Object> deleteDictDetail(@PathVariable Long id) {
dictDetailService.delete(id); dictDetailService.delete(id);
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }

View File

@ -30,4 +30,7 @@ public class DictDetailQueryCriteria {
@Query(propName = "name",joinName = "dict") @Query(propName = "name",joinName = "dict")
private String dictName; private String dictName;
@Query(propName = "id",joinName = "dictDetail")
private String releId;
} }

View File

@ -32,6 +32,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -59,9 +60,14 @@ public class DictDetailServiceImpl implements DictDetailService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void create(DictDetail resources) { public void create(DictDetail resources) {
if(resources.getDict()!=null){
Dict dict = dictRepository.findById(resources.getDict().getId()).orElseGet(Dict::new);
dict.setIsChild(1);
dictRepository.save(dict);
// 清理缓存
delCaches(resources);
}
dictDetailRepository.save(resources); dictDetailRepository.save(resources);
// 清理缓存
delCaches(resources);
} }
@Override @Override
@ -85,9 +91,18 @@ public class DictDetailServiceImpl implements DictDetailService {
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void delete(Long id) { public void delete(Long id) {
DictDetail dictDetail = dictDetailRepository.findById(id).orElseGet(DictDetail::new); DictDetail dictDetail = dictDetailRepository.findById(id).orElseGet(DictDetail::new);
Dict dict = dictDetail.getDict();
// 清理缓存 // 清理缓存
delCaches(dictDetail); delCaches(dictDetail);
dictDetailRepository.deleteById(id); // dictDetailRepository.deleteById(id);
dictDetailRepository.delAllById(id);
if (dict!=null) {
List<DictDetail> dictDetails = queryName(dict.getName());
if(CollectionUtils.isEmpty(dictDetails)){
dict.setIsChild(0);
dictRepository.save(dict);
}
}
} }
@Override @Override

View File

@ -17,7 +17,10 @@ package cn.ysk.cashier.system.service.impl;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.ysk.cashier.system.domain.Dict; import cn.ysk.cashier.system.domain.Dict;
import cn.ysk.cashier.system.domain.DictDetail;
import cn.ysk.cashier.system.repository.DictDetailRepository;
import cn.ysk.cashier.system.repository.DictRepository; import cn.ysk.cashier.system.repository.DictRepository;
import cn.ysk.cashier.system.service.DictDetailService;
import cn.ysk.cashier.system.service.DictService; import cn.ysk.cashier.system.service.DictService;
import cn.ysk.cashier.system.service.dto.DictDetailDto; import cn.ysk.cashier.system.service.dto.DictDetailDto;
import cn.ysk.cashier.system.service.dto.DictDto; import cn.ysk.cashier.system.service.dto.DictDto;
@ -33,6 +36,7 @@ import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
/** /**
* @author Zheng Jie * @author Zheng Jie
@ -45,6 +49,7 @@ public class DictServiceImpl implements DictService {
private final DictRepository dictRepository; private final DictRepository dictRepository;
private final DictMapper dictMapper; private final DictMapper dictMapper;
private final DictDetailRepository dictDetailRepository;
private final RedisUtils redisUtils; private final RedisUtils redisUtils;
@Override @Override
@ -83,6 +88,13 @@ public class DictServiceImpl implements DictService {
// 清理缓存 // 清理缓存
List<Dict> dicts = dictRepository.findByIdIn(ids); List<Dict> dicts = dictRepository.findByIdIn(ids);
for (Dict dict : dicts) { for (Dict dict : dicts) {
Dict byName = dictRepository.findByName(dict.getName());
if(CollectionUtil.isNotEmpty(byName.getDictDetails())){
Set<Long> idSet = byName.getDictDetails().stream()
.map(DictDetail::getId) // 提取id
.collect(Collectors.toSet()); // 转为Set集合
dictDetailRepository.delAllByIdIn(idSet);
}
delCaches(dict); delCaches(dict);
} }
dictRepository.deleteByIdIn(ids); dictRepository.deleteByIdIn(ids);

View File

@ -31,6 +31,13 @@ spring:
dialect: org.hibernate.dialect.MySQL5InnoDBDialect dialect: org.hibernate.dialect.MySQL5InnoDBDialect
show_sql: true show_sql: true
redisdb5:
#数据库索引
database: ${REDIS_DB:5}
host: ${REDIS_HOST:127.0.0.1}
port: ${REDIS_PORT:6379}
password: ${REDIS_PWD:111111}
redis: redis:
#数据库索引 #数据库索引
database: ${REDIS_DB:0} database: ${REDIS_DB:0}