refactor: 重构偏好模块.
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
package com.orion.ops.module.infra.handler.preference.model;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.orion.lang.define.wrapper.Ref;
|
||||
import com.orion.lang.utils.collect.Maps;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 偏好
|
||||
@@ -18,8 +23,9 @@ public interface PreferenceModel {
|
||||
*
|
||||
* @return map
|
||||
*/
|
||||
default Map<String, Object> toMap() {
|
||||
return JSON.parseObject(JSON.toJSONString(this));
|
||||
default Map<String, String> toMap() {
|
||||
JSONObject map = JSON.parseObject(JSON.toJSONString(this));
|
||||
return Maps.map(map, Function.identity(), v -> JSON.toJSONString(Ref.of(v)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ Authorization: {{token}}
|
||||
|
||||
{
|
||||
"type": "SYSTEM",
|
||||
"config": {
|
||||
}
|
||||
"item": "",
|
||||
"value": ""
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package com.orion.ops.module.infra.controller;
|
||||
|
||||
import com.orion.lang.define.wrapper.HttpWrapper;
|
||||
import com.orion.ops.framework.web.core.annotation.RestWrapper;
|
||||
import com.orion.ops.module.infra.entity.request.preference.PreferenceUpdatePartialRequest;
|
||||
import com.orion.ops.module.infra.entity.request.preference.PreferenceUpdateRequest;
|
||||
import com.orion.ops.module.infra.entity.vo.PreferenceVO;
|
||||
import com.orion.ops.module.infra.service.PreferenceService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -12,6 +13,7 @@ import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 用户偏好 api
|
||||
@@ -33,21 +35,22 @@ public class PreferenceController {
|
||||
private PreferenceService preferenceService;
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新用户偏好-整体")
|
||||
@Operation(summary = "更新用户偏好-单个")
|
||||
public Integer updatePreference(@Validated @RequestBody PreferenceUpdateRequest request) {
|
||||
return preferenceService.updatePreference(request, false);
|
||||
return preferenceService.updatePreference(request);
|
||||
}
|
||||
|
||||
@PutMapping("/update-partial")
|
||||
@Operation(summary = "更新用户偏好-部分")
|
||||
public Integer updatePreferencePartial(@Validated @RequestBody PreferenceUpdateRequest request) {
|
||||
return preferenceService.updatePreference(request, true);
|
||||
public HttpWrapper<?> updatePreferencePartial(@Validated @RequestBody PreferenceUpdatePartialRequest request) {
|
||||
preferenceService.updatePreferencePartial(request);
|
||||
return HttpWrapper.ok();
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "查询用户偏好")
|
||||
@Parameter(name = "type", description = "type", required = true)
|
||||
public PreferenceVO getPreference(@RequestParam("type") String type) {
|
||||
public Map<String, Object> getPreference(@RequestParam("type") String type) {
|
||||
return preferenceService.getPreferenceByType(type);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
package com.orion.ops.module.infra.convert;
|
||||
|
||||
import com.orion.ops.module.infra.entity.domain.PreferenceDO;
|
||||
import com.orion.ops.module.infra.entity.request.preference.PreferenceUpdateRequest;
|
||||
import com.orion.ops.module.infra.entity.vo.PreferenceVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* 用户偏好 内部对象转换器
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023-9-27 18:37
|
||||
*/
|
||||
@Mapper
|
||||
public interface PreferenceConvert {
|
||||
|
||||
PreferenceConvert MAPPER = Mappers.getMapper(PreferenceConvert.class);
|
||||
|
||||
@Mapping(target = "config", ignore = true)
|
||||
PreferenceDO to(PreferenceUpdateRequest request);
|
||||
|
||||
@Mapping(target = "config", ignore = true)
|
||||
PreferenceVO to(PreferenceDO domain);
|
||||
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.orion.ops.module.infra.define.cache;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.orion.lang.define.cache.key.CacheKeyBuilder;
|
||||
import com.orion.lang.define.cache.key.CacheKeyDefine;
|
||||
import com.orion.lang.define.cache.key.struct.RedisCacheStruct;
|
||||
import com.orion.lang.define.wrapper.Ref;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -19,8 +19,8 @@ public interface PreferenceCacheKeyDefine {
|
||||
CacheKeyDefine PREFERENCE = new CacheKeyBuilder()
|
||||
.key("user:preference:{}:{}")
|
||||
.desc("用户偏好 ${userId} ${type}")
|
||||
.type(JSONObject.class)
|
||||
.struct(RedisCacheStruct.STRING)
|
||||
.type(Ref.class)
|
||||
.struct(RedisCacheStruct.HASH)
|
||||
.timeout(1, TimeUnit.DAYS)
|
||||
.build();
|
||||
|
||||
|
||||
@@ -38,8 +38,12 @@ public class PreferenceDO extends BaseDO {
|
||||
@TableField("type")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "偏好配置")
|
||||
@TableField("config")
|
||||
private String config;
|
||||
@Schema(description = "配置项")
|
||||
@TableField("item")
|
||||
private String item;
|
||||
|
||||
@Schema(description = "配置值")
|
||||
@TableField("value")
|
||||
private String value;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.orion.ops.module.infra.entity.request.preference;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 用户偏好 部分更新请求对象
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023-9-27 18:37
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(name = "PreferenceUpdatePartialRequest", description = "用户偏好 部分更新请求对象")
|
||||
public class PreferenceUpdatePartialRequest implements Serializable {
|
||||
|
||||
@NotBlank
|
||||
@Size(max = 12)
|
||||
@Schema(description = "类型")
|
||||
private String type;
|
||||
|
||||
@NotEmpty
|
||||
@Schema(description = "偏好配置")
|
||||
private Map<String, Object> config;
|
||||
|
||||
}
|
||||
@@ -7,10 +7,8 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 用户偏好 更新请求对象
|
||||
@@ -31,8 +29,12 @@ public class PreferenceUpdateRequest implements Serializable {
|
||||
@Schema(description = "类型")
|
||||
private String type;
|
||||
|
||||
@NotEmpty
|
||||
@NotBlank
|
||||
@Size(max = 32)
|
||||
@Schema(description = "偏好配置")
|
||||
private Map<String, Object> config;
|
||||
private String item;
|
||||
|
||||
@Schema(description = "偏好配置")
|
||||
private Object value;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.orion.ops.module.infra.entity.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 用户偏好 视图响应对象
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023-9-27 18:37
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(name = "PreferenceVO", description = "用户偏好 视图响应对象")
|
||||
public class PreferenceVO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "偏好配置")
|
||||
private Map<String, Object> config;
|
||||
|
||||
}
|
||||
@@ -17,7 +17,7 @@ public class TerminalPreferenceStrategy implements IPreferenceStrategy<TerminalP
|
||||
@Override
|
||||
public TerminalPreferenceModel getDefault() {
|
||||
return TerminalPreferenceModel.builder()
|
||||
.darkTheme("dark")
|
||||
.darkTheme("auto")
|
||||
.newConnectionType("group")
|
||||
.displaySetting(TerminalPreferenceModel.DisplaySettingModel.builder()
|
||||
.fontFamily("_")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.orion.ops.module.infra.service;
|
||||
|
||||
import com.orion.ops.module.infra.entity.request.preference.PreferenceUpdatePartialRequest;
|
||||
import com.orion.ops.module.infra.entity.request.preference.PreferenceUpdateRequest;
|
||||
import com.orion.ops.module.infra.entity.vo.PreferenceVO;
|
||||
import com.orion.ops.module.infra.enums.PreferenceTypeEnum;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -17,21 +17,27 @@ import java.util.concurrent.Future;
|
||||
public interface PreferenceService {
|
||||
|
||||
/**
|
||||
* 更新用户偏好
|
||||
* 更新用户偏好-单个
|
||||
*
|
||||
* @param request request
|
||||
* @param partial 是否为部分更新
|
||||
* @return effect
|
||||
*/
|
||||
Integer updatePreference(PreferenceUpdateRequest request, boolean partial);
|
||||
Integer updatePreference(PreferenceUpdateRequest request);
|
||||
|
||||
/**
|
||||
* 更新用户偏好-部分
|
||||
*
|
||||
* @param request request
|
||||
*/
|
||||
void updatePreferencePartial(PreferenceUpdatePartialRequest request);
|
||||
|
||||
/**
|
||||
* 查询用户偏好
|
||||
*
|
||||
* @param type type
|
||||
* @return row
|
||||
* @return rows
|
||||
*/
|
||||
PreferenceVO getPreferenceByType(String type);
|
||||
Map<String, Object> getPreferenceByType(String type);
|
||||
|
||||
/**
|
||||
* 获取用户偏好
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
package com.orion.ops.module.infra.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.orion.lang.define.wrapper.Ref;
|
||||
import com.orion.lang.function.Functions;
|
||||
import com.orion.lang.utils.collect.Maps;
|
||||
import com.orion.ops.framework.common.utils.Valid;
|
||||
import com.orion.ops.framework.redis.core.utils.RedisStrings;
|
||||
import com.orion.ops.framework.redis.core.utils.RedisMaps;
|
||||
import com.orion.ops.framework.security.core.utils.SecurityUtils;
|
||||
import com.orion.ops.module.infra.dao.PreferenceDAO;
|
||||
import com.orion.ops.module.infra.define.cache.PreferenceCacheKeyDefine;
|
||||
import com.orion.ops.module.infra.entity.domain.PreferenceDO;
|
||||
import com.orion.ops.module.infra.entity.request.preference.PreferenceUpdatePartialRequest;
|
||||
import com.orion.ops.module.infra.entity.request.preference.PreferenceUpdateRequest;
|
||||
import com.orion.ops.module.infra.entity.vo.PreferenceVO;
|
||||
import com.orion.ops.module.infra.enums.PreferenceTypeEnum;
|
||||
import com.orion.ops.module.infra.service.PreferenceService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -24,6 +25,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -41,51 +43,73 @@ public class PreferenceServiceImpl implements PreferenceService {
|
||||
private PreferenceDAO preferenceDAO;
|
||||
|
||||
@Override
|
||||
public Integer updatePreference(PreferenceUpdateRequest request, boolean partial) {
|
||||
public Integer updatePreference(PreferenceUpdateRequest request) {
|
||||
Long userId = SecurityUtils.getLoginUserId();
|
||||
String type = request.getType();
|
||||
String item = request.getItem();
|
||||
Valid.valid(PreferenceTypeEnum::of, type);
|
||||
// 查询
|
||||
PreferenceDO preference = preferenceDAO.of()
|
||||
.wrapper(this.buildQueryWrapper(userId, type))
|
||||
.createWrapper()
|
||||
.eq(PreferenceDO::getUserId, userId)
|
||||
.eq(PreferenceDO::getType, type)
|
||||
.eq(PreferenceDO::getItem, item)
|
||||
.then()
|
||||
.getOne();
|
||||
int effect;
|
||||
if (preference == null) {
|
||||
// 直接插入
|
||||
// 插入
|
||||
PreferenceDO insertRecord = new PreferenceDO();
|
||||
insertRecord.setUserId(userId);
|
||||
insertRecord.setType(type);
|
||||
insertRecord.setConfig(JSON.toJSONString(request.getConfig()));
|
||||
insertRecord.setItem(item);
|
||||
insertRecord.setValue(this.toJsonValue(request.getValue()));
|
||||
effect = preferenceDAO.insert(insertRecord);
|
||||
} else {
|
||||
// 更新
|
||||
PreferenceDO updateRecord = new PreferenceDO();
|
||||
updateRecord.setId(preference.getId());
|
||||
if (partial) {
|
||||
// 部分更新
|
||||
JSONObject config = JSON.parseObject(preference.getConfig());
|
||||
config.putAll(request.getConfig());
|
||||
updateRecord.setConfig(JSON.toJSONString(config));
|
||||
} else {
|
||||
// 全部更新
|
||||
updateRecord.setConfig(JSON.toJSONString(request.getConfig()));
|
||||
}
|
||||
updateRecord.setValue(this.toJsonValue(request.getValue()));
|
||||
effect = preferenceDAO.updateById(updateRecord);
|
||||
// 删除缓存
|
||||
RedisStrings.delete(PreferenceCacheKeyDefine.PREFERENCE.format(userId, type));
|
||||
}
|
||||
// 删除缓存
|
||||
RedisMaps.delete(PreferenceCacheKeyDefine.PREFERENCE.format(userId, type));
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreferenceVO getPreferenceByType(String type) {
|
||||
public void updatePreferencePartial(PreferenceUpdatePartialRequest request) {
|
||||
Long userId = SecurityUtils.getLoginUserId();
|
||||
String type = request.getType();
|
||||
Map<String, Object> config = request.getConfig();
|
||||
Valid.valid(PreferenceTypeEnum::of, type);
|
||||
// 删除配置
|
||||
LambdaQueryWrapper<PreferenceDO> wrapper = preferenceDAO.lambda()
|
||||
.eq(PreferenceDO::getUserId, userId)
|
||||
.eq(PreferenceDO::getType, type)
|
||||
.in(PreferenceDO::getItem, config.keySet());
|
||||
preferenceDAO.delete(wrapper);
|
||||
// 插入配置
|
||||
List<PreferenceDO> records = config.entrySet()
|
||||
.stream()
|
||||
.map(s -> {
|
||||
PreferenceDO insertRecord = new PreferenceDO();
|
||||
insertRecord.setUserId(userId);
|
||||
insertRecord.setType(type);
|
||||
insertRecord.setItem(s.getKey());
|
||||
insertRecord.setValue(this.toJsonValue(s.getValue()));
|
||||
return insertRecord;
|
||||
}).collect(Collectors.toList());
|
||||
preferenceDAO.insertBatch(records);
|
||||
// 删除缓存
|
||||
RedisMaps.delete(PreferenceCacheKeyDefine.PREFERENCE.format(userId, type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getPreferenceByType(String type) {
|
||||
Long userId = SecurityUtils.getLoginUserId();
|
||||
PreferenceTypeEnum typeEnum = Valid.valid(PreferenceTypeEnum::of, type);
|
||||
Map<String, Object> config = this.getPreferenceByCache(userId, typeEnum);
|
||||
// 返回
|
||||
return PreferenceVO.builder()
|
||||
.config(config)
|
||||
.build();
|
||||
return this.getPreferenceByCache(userId, typeEnum);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -104,7 +128,7 @@ public class PreferenceServiceImpl implements PreferenceService {
|
||||
List<String> deleteKeys = Arrays.stream(PreferenceTypeEnum.values())
|
||||
.map(s -> PreferenceCacheKeyDefine.PREFERENCE.format(userId, s))
|
||||
.collect(Collectors.toList());
|
||||
RedisStrings.delete(deleteKeys);
|
||||
RedisMaps.delete(deleteKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,47 +142,58 @@ public class PreferenceServiceImpl implements PreferenceService {
|
||||
String typeValue = type.getType();
|
||||
// 查询缓存 用 string 防止数据类型丢失
|
||||
String key = PreferenceCacheKeyDefine.PREFERENCE.format(userId, type);
|
||||
Map<String, Object> config = RedisStrings.getJson(key);
|
||||
Map<String, String> config = RedisMaps.entities(key);
|
||||
boolean setCache = Maps.isEmpty(config);
|
||||
// 查询数据库
|
||||
if (Maps.isEmpty(config)) {
|
||||
config = preferenceDAO.of()
|
||||
.wrapper(this.buildQueryWrapper(userId, typeValue))
|
||||
.optionalOne()
|
||||
.map(PreferenceDO::getConfig)
|
||||
.map(JSON::parseObject)
|
||||
.orElse(null);
|
||||
.createWrapper()
|
||||
.eq(PreferenceDO::getUserId, userId)
|
||||
.eq(PreferenceDO::getType, type)
|
||||
.then()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(
|
||||
PreferenceDO::getItem,
|
||||
PreferenceDO::getValue,
|
||||
Functions.right())
|
||||
);
|
||||
}
|
||||
// 初始化
|
||||
if (Maps.isEmpty(config)) {
|
||||
// 获取默认值
|
||||
config = type.getStrategy()
|
||||
.getDefault()
|
||||
.toMap();
|
||||
// 插入
|
||||
PreferenceDO entity = new PreferenceDO();
|
||||
entity.setUserId(userId);
|
||||
entity.setType(typeValue);
|
||||
entity.setConfig(JSON.toJSONString(config));
|
||||
preferenceDAO.insert(entity);
|
||||
// 插入默认值
|
||||
List<PreferenceDO> entities = config
|
||||
.entrySet()
|
||||
.stream()
|
||||
.map(s -> {
|
||||
PreferenceDO entity = new PreferenceDO();
|
||||
entity.setUserId(userId);
|
||||
entity.setType(typeValue);
|
||||
entity.setItem(s.getKey());
|
||||
entity.setValue(s.getValue());
|
||||
return entity;
|
||||
}).collect(Collectors.toList());
|
||||
preferenceDAO.insertBatch(entities);
|
||||
}
|
||||
// 设置缓存
|
||||
if (setCache) {
|
||||
RedisStrings.setJson(key, PreferenceCacheKeyDefine.PREFERENCE, config);
|
||||
RedisMaps.putAll(key, PreferenceCacheKeyDefine.PREFERENCE, config);
|
||||
}
|
||||
return config;
|
||||
// unref
|
||||
return Maps.map(config, Function.identity(), v -> JSON.parseObject(v, Ref.class).getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建查询 wrapper
|
||||
* 转为 json 对象
|
||||
*
|
||||
* @param userId userId
|
||||
* @param type type
|
||||
* @return wrapper
|
||||
* @param o o
|
||||
* @return value
|
||||
*/
|
||||
private LambdaQueryWrapper<PreferenceDO> buildQueryWrapper(Long userId, String type) {
|
||||
return preferenceDAO.wrapper()
|
||||
.eq(PreferenceDO::getUserId, userId)
|
||||
.eq(PreferenceDO::getType, type);
|
||||
private String toJsonValue(Object o) {
|
||||
return JSON.toJSONString(Ref.of(o));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,12 +12,13 @@
|
||||
<result column="deleted" property="deleted"/>
|
||||
<result column="user_id" property="userId"/>
|
||||
<result column="type" property="type"/>
|
||||
<result column="config" property="config"/>
|
||||
<result column="item" property="item"/>
|
||||
<result column="value" property="value"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 通用查询结果列 -->
|
||||
<sql id="Base_Column_List">
|
||||
id, user_id, type, config, create_time, update_time, creator, updater, deleted
|
||||
id, user_id, type, item, value, create_time, update_time, creator, updater, deleted
|
||||
</sql>
|
||||
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user