@Mapper
public interface UserConfigMapper extends BaseMapper<UserConfigEntity> {
}
/**
* <p>
* 用户配置信息(即系统用户的各类业务配置)
* 每个用户一行记录,配置数据以json格式存储
* </p>
*
* @author wandl
* @since 2024-12-03
*/
@Getter
@Setter
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@TableName("sys_user_config")
public class UserConfigEntity extends AdminBaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
* 应用ID,如:综合评价的应用ID
*/
@TableField("app_id")
private String appId;
/**
* 租户ID(即学校代码)
*/
@TableField("tenant_id")
private String tenantId;
/**
* 用户ID
*/
@TableField("user_id")
private Long userId;
/**
* 配置项名称,如:AppKey
*/
@TableField("config_key")
private String configKey;
/**
* 配置项数据分类:key-value、json-object、json-array
*/
@TableField("config_data_type")
private ConfigDataType configDataType;
/**
* 配置项值,如:xxxxx12645645
*/
@TableField("config_value")
private String configValue;
public UserConfigVO toVO() {
return new UserConfigVO()
.setId(this.id)
.setConfigKey(this.configKey)
.setConfigDataType(this.configDataType)
.setConfigValue(this.configValue)
.setCreateTime(this.getCreateTime())
.setUpdateTime(this.getUpdateTime());
}
}
/**
* <p>
* 用户配置信息(即系统用户的各类业务配置)
* 每个用户一行记录,配置数据以json格式存储
* </p>
*
* @author wandl
* @since 2024-12-03
*/
@ApiModel(value = "UserConfigVO", description = "用户配置信息(即系统用户的各类业务配置)VO")
@Getter
@Setter
@Accessors(chain = true)
public class UserConfigVO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ApiModelProperty(value = "主键ID")
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 配置项名称,如:AppKey
*/
@ApiModelProperty(value = "配置项名称,如:AppKey")
private String configKey;
/**
* 配置项数据分类:key-value、json-object、json-array
*/
@ApiModelProperty(value = "配置项数据分类:key-value、json-object、json-array")
private ConfigDataType configDataType;
/**
* 配置项值,如:12645645
*/
@ApiModelProperty(value = "配置项值,如:12645645")
private String configValue;
/**
* 创建时间
*/
@ApiModelProperty(value = "创建时间")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
private LocalDateTime createTime;
/**
* 修改时间
*/
@ApiModelProperty(value = "修改时间")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
private LocalDateTime updateTime;
}
import java.util.List;
import java.util.Map;
/**
* 用户配置服务
*/
public interface IUserConfigService extends IService<UserConfigEntity> {
/**
* 保存用户配置
* @param configAddParam 用户配置
* @return 是否保存成功
*/
boolean saveUserConfig(UserConfigAddParam configAddParam);
/**
* 保存用户配置(批量)
* @param configSetAddParam 用户配置
* @return 是否保存成功
*/
boolean saveUserConfig(UserConfigSetAddParam configSetAddParam);
/**
* 删除用户配置
* @param appId 应用id
* @param configKeys 配置key
* @param tenantId 租户id
* @param userId 用户id
* @return 是否删除成功
*/
boolean deleteUserConfig(String appId, String tenantId, Long userId, String ... configKeys);
/**
* 更新用户配置
* @param configUpdateParam 用户配置
* @return 是否更新成功
*/
boolean updateUserConfig(UserConfigUpdateParam configUpdateParam);
/**
* 更新用户配置(批量)
* @param configSetUpdateParam 用户配置
* @return 是否更新成功
*/
boolean updateUserConfig(UserConfigSetUpdateParam configSetUpdateParam);
/**
* 根据用户id查询用户配置
* @param appId 应用id
* @param tenantId 租户id
* @param userId 用户id
* @return 用户配置列表
*/
Map<String, UserConfigVO> getUserConfigMap(String appId, String tenantId, Long userId);
/**
* 根据用户id查询用户配置
* @param appId 应用id
* @param tenantId 租户id
* @param userId 用户id
* @return 用户配置列表
*/
List<UserConfigVO> getUserConfigList(String appId, String tenantId, Long userId);
/**
* 根据用户id查询用户配置
* @param appId 应用id
* @param tenantId 租户id
* @param userId 用户id
* @param configKey 配置key
* @return 用户配置
*/
UserConfigVO getUserConfig(String appId, String tenantId, Long userId, String configKey);
}
@Service
@RequiredArgsConstructor
@Slf4j
public class UserConfigServiceImpl extends ServiceImpl<UserConfigMapper, UserConfigEntity> implements IUserConfigService {
public final RedisOperationTemplate redisOperationTemplate;
@Override
@Transactional(rollbackFor = Exception.class)
public boolean saveUserConfig(UserConfigAddParam configAddParam) {
// 1、根据AppId、TenantId、UserId、ConfigKey查询数据
UserConfigEntity oldEntity= getBaseMapper().selectOne(new LambdaQueryWrapper<UserConfigEntity>()
.eq(UserConfigEntity::getAppId, configAddParam.getAppId())
.eq(UserConfigEntity::getTenantId, configAddParam.getTenantId())
.eq(UserConfigEntity::getUserId, SubjectUtils.getUserIdLong())
.eq(UserConfigEntity::getConfigKey, configAddParam.getConfigKey()));
// 2、如果存在则更新
if (Objects.nonNull(oldEntity)){
oldEntity.setConfigDataType(configAddParam.getConfigDataType())
.setConfigValue(configAddParam.getConfigValue());
return this.updateById(oldEntity);
}
// 3、不存在则新增
UserConfigEntity entity = new UserConfigEntity()
.setAppId(configAddParam.getAppId())
.setTenantId(configAddParam.getTenantId())
.setUserId(SubjectUtils.getUserIdLong())
.setConfigKey(configAddParam.getConfigKey())
.setConfigDataType(configAddParam.getConfigDataType())
.setConfigValue(configAddParam.getConfigValue());
return this.save(entity);
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean saveUserConfig(UserConfigSetAddParam configSetAddParam) {
// 1、进行参数校验
if(Objects.isNull(configSetAddParam) || CollectionUtils.isEmpty(configSetAddParam.getParamList())){
log.warn("参数为空, configSetAddParam: {}", configSetAddParam);
return Boolean.FALSE;
}
// 2、查询当前操作租户的所有配置
Optional<UserConfigAddParam> firstParam = configSetAddParam.getParamList().stream().filter(Objects::nonNull).findFirst();
if (!firstParam.isPresent()) {
log.warn("参数为空, configSetAddParam: {}", configSetAddParam);
return Boolean.FALSE;
}
List<UserConfigEntity> newEntityList = Lists.newArrayList();
List<UserConfigEntity> updateEntityList = Lists.newArrayList();
// 3、查询到当前操作租户的所有配置
List<UserConfigEntity> oldEntityList = getBaseMapper().selectList(new LambdaQueryWrapper<UserConfigEntity>()
.eq(UserConfigEntity::getAppId, firstParam.get().getAppId())
.eq(UserConfigEntity::getTenantId, firstParam.get().getTenantId()));
if(CollectionUtils.isEmpty(oldEntityList)){
for (UserConfigAddParam configAddParam : configSetAddParam.getParamList()) {
newEntityList.add(new UserConfigEntity()
.setAppId(configAddParam.getAppId())
.setTenantId(configAddParam.getTenantId())
.setConfigKey(configAddParam.getConfigKey())
.setConfigDataType(configAddParam.getConfigDataType())
.setConfigValue(configAddParam.getConfigValue()));
}
} else {
// 根据ConfigKey转换成Map
Map<String, UserConfigEntity> oldEntityMap = oldEntityList.stream().collect(Collectors.toMap(UserConfigEntity::getConfigKey, entity -> entity, (a, b) -> a));
// 遍历新增数据
for (UserConfigAddParam configAddParam : configSetAddParam.getParamList()) {
// 如果不存在则新增
buildEntity(newEntityList, updateEntityList, oldEntityMap, configAddParam);
}
}
if (!CollectionUtils.isEmpty(newEntityList)){
this.saveBatch(newEntityList);
}
if (!CollectionUtils.isEmpty(updateEntityList)){
this.updateBatchById(updateEntityList);
}
return Boolean.TRUE;
}
private void buildEntity(List<UserConfigEntity> newEntityList, List<UserConfigEntity> updateEntityList, Map<String, UserConfigEntity> oldEntityMap, UserConfigAddParam configAddParam) {
UserConfigEntity oldEntity = oldEntityMap.get(configAddParam.getConfigKey());
if (Objects.isNull(oldEntity)) {
newEntityList.add(new UserConfigEntity()
.setAppId(configAddParam.getAppId())
.setTenantId(configAddParam.getTenantId())
.setConfigKey(configAddParam.getConfigKey())
.setConfigDataType(configAddParam.getConfigDataType())
.setConfigValue(configAddParam.getConfigValue()));
} else {
// 如果存在则更新
oldEntity.setConfigDataType(configAddParam.getConfigDataType())
.setConfigValue(configAddParam.getConfigValue());
updateEntityList.add(oldEntity);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean deleteUserConfig(String appId, String tenantId, Long userId, String... configKeys) {
// 1、进行参数校验
if(Objects.isNull(appId) || ArrayUtils.isEmpty(configKeys)){
return Boolean.FALSE;
}
// 2、删除数据
boolean rt = SqlHelper.retBool(getBaseMapper().delete(new LambdaQueryWrapper<UserConfigEntity>()
.eq(UserConfigEntity::getAppId, appId)
.eq(UserConfigEntity::getTenantId, tenantId)
.eq(UserConfigEntity::getUserId, userId)
.eq(configKeys.length == 1, UserConfigEntity::getConfigKey, configKeys[0])
.in(configKeys.length > 1, UserConfigEntity::getConfigKey, Arrays.asList(configKeys))));
// 3、删除成功则删除缓存
if (rt){
String rdsKey = BizRedisKey.USER_CONFIG.getKey(appId + StringPool.DASH + tenantId, userId);
redisOperationTemplate.hDel(rdsKey, configKeys);
}
return false;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean updateUserConfig(UserConfigUpdateParam configUpdateParam) {
// 1、根据ID查询数据,如果不存在则返回
UserConfigEntity entity = getBaseMapper().selectById(configUpdateParam.getId());
if (Objects.isNull(entity)){
return Boolean.FALSE;
}
// 2、更新数据
entity.setConfigKey(configUpdateParam.getConfigKey())
.setConfigDataType(configUpdateParam.getConfigDataType())
.setConfigValue(configUpdateParam.getConfigValue());
return this.updateById(entity);
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean updateUserConfig(UserConfigSetUpdateParam configSetUpdateParam) {
// 1、进行参数校验
if(Objects.isNull(configSetUpdateParam) || (CollectionUtils.isEmpty(configSetUpdateParam.getAddList())
&& CollectionUtils.isEmpty(configSetUpdateParam.getUpdateList()))){
return Boolean.FALSE;
}
// 2、有新增数据的时候,先处理新增数据
List<UserConfigEntity> newEntityList = Lists.newArrayList();
List<UserConfigEntity> updateEntityList = Lists.newArrayList();
if (!CollectionUtils.isEmpty(configSetUpdateParam.getAddList())){
// 2.1、第一个元素的AppId、TenantId查询当前操作用户的所有配置
Optional<UserConfigAddParam> firstParam = configSetUpdateParam.getAddList().stream().filter(Objects::nonNull).findFirst();
if (firstParam.isPresent()) {
// 2.1.1、查询到当前操作用户的所有配置
List<UserConfigEntity> oldEntityList = getBaseMapper().selectList(new LambdaQueryWrapper<UserConfigEntity>()
.eq(UserConfigEntity::getAppId, firstParam.get().getAppId())
.eq(UserConfigEntity::getTenantId, firstParam.get().getTenantId())
.eq(UserConfigEntity::getUserId, SubjectUtils.getUserIdLong()));
// 2.1.2、如果查询到当前操作用户的所有配置,则需要判断新增数据是否已经存在
if (!CollectionUtils.isEmpty(oldEntityList)) {
// 根据ConfigKey转换成Map
Map<String, UserConfigEntity> oldEntityMap = oldEntityList.stream().collect(Collectors.toMap(UserConfigEntity::getConfigKey, entity -> entity, (a, b) -> a));
// 遍历新增数据
for (UserConfigAddParam configAddParam : configSetUpdateParam.getAddList()) {
buildEntity(newEntityList, updateEntityList, oldEntityMap, configAddParam);
}
}
}
for (UserConfigAddParam configAddParam: configSetUpdateParam.getAddList()){
newEntityList.add(new UserConfigEntity()
.setAppId(configAddParam.getAppId())
.setTenantId(configAddParam.getTenantId())
.setUserId(SubjectUtils.getUserIdLong())
.setConfigKey(configAddParam.getConfigKey())
.setConfigDataType(configAddParam.getConfigDataType())
.setConfigValue(configAddParam.getConfigValue()));
}
this.saveBatch(newEntityList);
}
// 3、有更新数据的时候
if (!CollectionUtils.isEmpty(configSetUpdateParam.getUpdateList())){
// 3.1、第一个元素的AppId、TenantId查询当前操作用户的所有配置
Set<Long> idSet = configSetUpdateParam.getUpdateList().stream().filter(Objects::nonNull).map(UserConfigUpdateParam::getId).collect(Collectors.toSet());
if (!CollectionUtils.isEmpty(idSet)){
List<UserConfigEntity> oldEntityList = getBaseMapper().selectBatchIds(idSet);
// 3.2、如果有数据则进行更新
if (!CollectionUtils.isEmpty(oldEntityList)){
// 3.2.1、转换成Map
Map<Long, UserConfigEntity> oldEntityMap = oldEntityList.stream().collect(Collectors.toMap(UserConfigEntity::getId, entity -> entity, (a, b) -> a));
// 3.2.2、遍历更新数据
for (UserConfigUpdateParam configUpdateParam: configSetUpdateParam.getUpdateList()){
// 3.2.2.1、跳过空数据
if(Objects.isNull(configUpdateParam)){
continue;
}
// 3.2.2.2、根据ConfigKey查询数据,如果没有则跳过
UserConfigEntity oldEntity = oldEntityMap.get(configUpdateParam.getId());
if (Objects.isNull(oldEntity)){
continue;
}
// 3.2.2.3、 覆盖数据
oldEntity.setConfigDataType(configUpdateParam.getConfigDataType())
.setConfigValue(configUpdateParam.getConfigValue());
updateEntityList.add(oldEntity);
}
}
}
// 3.3、更新数据
if (!CollectionUtils.isEmpty(updateEntityList)){
this.updateBatchById(updateEntityList);
}
}
return Boolean.TRUE;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean save(UserConfigEntity entity) {
// 1、保存数据
boolean rt = super.save(entity);
// 2、保存成功则存入缓存
if (rt){
String rdsKey = BizRedisKey.TENANT_CONFIG.getKey(entity.getAppId() + StringPool.DASH + entity.getTenantId(), entity.getUserId());
redisOperationTemplate.hSet(rdsKey, entity.getConfigKey(), entity.toVO());
}
return rt;
}
@Override
public boolean saveOrUpdate(UserConfigEntity entity) {
// 1、保存/更新数据
boolean rt = super.saveOrUpdate(entity);
// 2、保存成功则存入缓存
if (rt){
String rdsKey = BizRedisKey.TENANT_CONFIG.getKey(entity.getAppId() + StringPool.DASH + entity.getTenantId(), entity.getUserId());
redisOperationTemplate.hSet(rdsKey, entity.getConfigKey(), entity.toVO());
}
return rt;
}
@Override
public boolean saveOrUpdateBatch(Collection<UserConfigEntity> entityList) {
throw new UnsupportedOperationException("不支持的方法!");
}
/**
* 批量插入
*
* @param entityList ignore
* @param batchSize ignore
* @return ignore
*/
@Override
@Transactional(rollbackFor = Exception.class)
public boolean saveBatch(Collection<UserConfigEntity> entityList, int batchSize) {
String sqlStatement = getSqlStatement(SqlMethod.INSERT_ONE);
return executeBatch(entityList, batchSize, (sqlSession, entity) -> {
int rt = sqlSession.insert(sqlStatement, entity);
if(rt > 0){
// 3.2、保存成功则存入缓存
String rdsKey = BizRedisKey.TENANT_CONFIG.getKey(entity.getAppId() + StringPool.DASH + entity.getTenantId(), entity.getUserId());
redisOperationTemplate.hSet(rdsKey, entity.getConfigKey(), entity.toVO());
}
});
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean updateBatchById(Collection<UserConfigEntity> entityList) {
String sqlStatement = getSqlStatement(SqlMethod.UPDATE_BY_ID);
return executeBatch(entityList, DEFAULT_BATCH_SIZE, (sqlSession, entity) -> {
MapperMethod.ParamMap<UserConfigEntity> param = new MapperMethod.ParamMap<>();
param.put(Constants.ENTITY, entity);
int rt = sqlSession.update(sqlStatement, param);
if(rt > 0){
// 3.2、保存成功则存入缓存
String rdsKey = BizRedisKey.TENANT_CONFIG.getKey(entity.getAppId() + StringPool.DASH + entity.getTenantId(), entity.getUserId());
redisOperationTemplate.hSet(rdsKey, entity.getConfigKey(), entity.toVO());
}
});
}
@Override
public boolean updateById(UserConfigEntity entity) {
boolean rt = super.updateById(entity);
// 3.2、保存成功则存入缓存
if (rt){
String rdsKey = BizRedisKey.TENANT_CONFIG.getKey(entity.getAppId() + StringPool.DASH + entity.getTenantId(), entity.getUserId());
redisOperationTemplate.hSet(rdsKey, entity.getConfigKey(), entity.toVO());
}
return rt;
}
@Override
public Map<String, UserConfigVO> getUserConfigMap(String appId, String tenantId, Long userId) {
if (Objects.isNull(appId) || !StringUtils.hasText(tenantId) || Objects.isNull(userId)) {
return Collections.emptyMap();
}
// 1、优先获取缓存中的数据
String rdsKey = BizRedisKey.USER_CONFIG.getKey(appId + StringPool.DASH + tenantId, userId);
Map<String, UserConfigVO> configMap = redisOperationTemplate.hmGetFor(rdsKey, String::valueOf, UserConfigVO.class);
// 2、如果缓存中有数据则直接返回
if (!CollectionUtils.isEmpty(configMap)) {
return configMap;
} else {
// 3、缓存中没有数据则查询数据库
List<UserConfigEntity> userConfigList = getBaseMapper().selectList(new LambdaQueryWrapper<UserConfigEntity>()
.eq(UserConfigEntity::getDeleted, 0)
.eq(UserConfigEntity::getAppId, appId)
.eq(UserConfigEntity::getTenantId, tenantId)
.eq(UserConfigEntity::getUserId, userId));
if (CollectionUtils.isEmpty(userConfigList)) {
return Collections.emptyMap();
}
// 4、将数据转换成map
configMap = userConfigList.stream().collect(Collectors.toMap(UserConfigEntity::getConfigKey, UserConfigEntity::toVO, (k1, k2) -> k1));
// 4、将数据存入缓存
redisOperationTemplate.hmSet(rdsKey, configMap);
return configMap;
}
}
@Override
public List<UserConfigVO> getUserConfigList(String appId, String tenantId, Long userId) {
// 1、获取配置信息
Map<String, UserConfigVO> configMap = getUserConfigMap(appId , tenantId, userId);
if (CollectionUtils.isEmpty(configMap)) {
return Collections.emptyList();
}
// 2、返回配置信息
return new ArrayList<>(configMap.values());
}
@Override
public UserConfigVO getUserConfig(String appId, String tenantId, Long userId, String configKey) {
// 1、获取配置信息
Map<String, UserConfigVO> configMap = getUserConfigMap(appId , tenantId, userId);
if (CollectionUtils.isEmpty(configMap)) {
return null;
}
// 2、返回配置信息
return configMap.get(configKey);
}
}
作者:Jeebiz 创建时间:2025-04-13 16:12
最后编辑:Jeebiz 更新时间:2025-04-13 16:32
最后编辑:Jeebiz 更新时间:2025-04-13 16:32