feat: 新增隐藏备注记录显示开关并简化设置与日志菜单文案
- 设置页「外观设置」新增「显示已隐藏备注的记录」开关,默认关闭,切换即时保存 - 新增 GET/PUT /api/setting/show-hidden-data 接口,用户级偏好持久化于 t_user_preference - 收支记录列表与 Excel 导出按该偏好过滤,关闭时排除已隐藏备注的记录 - 移除「备注关键字搜索时总是跳过隐藏记录」逻辑,改由该偏好统一控制,统计备注搜索同步放开 - 列表内隐藏备注后,偏好关闭时该行即时移除,当前页清空自动回退上一页 - 外观设置面板拆分为两个浅灰底分组,两个配置项区分更清晰 - 顶部用户菜单与设置/日志页标题由「系统设置/系统日志」简化为「设置/日志」,同步中英日三语
This commit is contained in:
@@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import cn.rosercode.finance.common.Result;
|
||||
import cn.rosercode.finance.dto.BillSourceStatsRequest;
|
||||
import cn.rosercode.finance.dto.ExcludedDisplayStyleRequest;
|
||||
import cn.rosercode.finance.dto.ShowHiddenDataRequest;
|
||||
import cn.rosercode.finance.service.UserPreferenceService;
|
||||
import cn.rosercode.finance.util.UserContext;
|
||||
|
||||
@@ -84,4 +85,30 @@ public class UserSettingController {
|
||||
userPreferenceService.saveExcludedDisplayStyle(userId, request.getStyle());
|
||||
return Result.success(userPreferenceService.getExcludedDisplayStyle(userId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前用户是否在收支记录列表与导出中显示已隐藏备注的记录。
|
||||
*
|
||||
* @return true-显示,false-不显示
|
||||
*/
|
||||
@GetMapping("/show-hidden-data")
|
||||
@Operation(summary = "查询隐藏备注记录显示偏好", description = "读取当前用户是否在收支记录列表与导出中显示已隐藏备注的记录")
|
||||
public Result<Boolean> getShowHiddenData() {
|
||||
return Result.success(userPreferenceService.getShowHiddenData(UserContext.getUserId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新当前用户是否在收支记录列表与导出中显示已隐藏备注的记录。
|
||||
*
|
||||
* @param request 显示偏好更新请求
|
||||
* @return 更新后的显示偏好
|
||||
*/
|
||||
@PutMapping("/show-hidden-data")
|
||||
@Operation(summary = "更新隐藏备注记录显示偏好", description = "设置当前用户是否在收支记录列表与导出中显示已隐藏备注的记录")
|
||||
public Result<Boolean> updateShowHiddenData(@RequestBody ShowHiddenDataRequest request) {
|
||||
Long userId = UserContext.getUserId();
|
||||
boolean show = Boolean.TRUE.equals(request.getShow());
|
||||
userPreferenceService.saveShowHiddenData(userId, show);
|
||||
return Result.success(userPreferenceService.getShowHiddenData(userId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package cn.rosercode.finance.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 「显示已隐藏备注记录」偏好更新请求对象。
|
||||
*
|
||||
* @date 2026-09-23 09:18:55
|
||||
*/
|
||||
@Data
|
||||
public class ShowHiddenDataRequest {
|
||||
|
||||
/** 是否在收支记录列表与导出中显示已隐藏备注的记录 */
|
||||
private Boolean show;
|
||||
}
|
||||
@@ -40,4 +40,20 @@ public interface UserPreferenceService {
|
||||
* @param style 展示样式
|
||||
*/
|
||||
void saveExcludedDisplayStyle(Long userId, String style);
|
||||
|
||||
/**
|
||||
* 获取当前用户是否在收支记录列表与导出中显示已隐藏备注的记录,未配置时回退默认值(不显示)。
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return true-显示,false-不显示
|
||||
*/
|
||||
boolean getShowHiddenData(Long userId);
|
||||
|
||||
/**
|
||||
* 保存当前用户是否在收支记录列表与导出中显示已隐藏备注的记录。
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param show 是否显示
|
||||
*/
|
||||
void saveShowHiddenData(Long userId, boolean show);
|
||||
}
|
||||
|
||||
@@ -285,10 +285,9 @@ public class StatisticsServiceImpl implements StatisticsService {
|
||||
if (query.getMaxAmount() != null) {
|
||||
wrapper.le("amount", query.getMaxAmount());
|
||||
}
|
||||
// 备注关键字模糊匹配;备注已隐藏的记录不参与搜索
|
||||
// 备注关键字模糊匹配
|
||||
if (StringUtils.hasText(query.getRemark())) {
|
||||
wrapper.like("remark", query.getRemark());
|
||||
wrapper.and(w -> w.isNull("remark_hidden").or().eq("remark_hidden", false));
|
||||
}
|
||||
// 标签筛选(多选);同时勾选「未打标签」时与其取并集
|
||||
boolean hasTagIds = query.getTagIds() != null && !query.getTagIds().isEmpty();
|
||||
|
||||
@@ -46,6 +46,7 @@ import cn.rosercode.finance.mapper.TransactionTagMapper;
|
||||
import cn.rosercode.finance.service.ChannelService;
|
||||
import cn.rosercode.finance.service.TransactionGroupService;
|
||||
import cn.rosercode.finance.service.TransactionService;
|
||||
import cn.rosercode.finance.service.UserPreferenceService;
|
||||
import cn.rosercode.finance.util.TransactionDedupUtils;
|
||||
import cn.rosercode.finance.vo.TagVO;
|
||||
import cn.rosercode.finance.vo.TransactionExportVO;
|
||||
@@ -70,6 +71,7 @@ public class TransactionServiceImpl implements TransactionService {
|
||||
private final TransactionGroupItemMapper transactionGroupItemMapper;
|
||||
private final ChannelService channelService;
|
||||
private final TransactionGroupService transactionGroupService;
|
||||
private final UserPreferenceService userPreferenceService;
|
||||
private final VoConverter voConverter;
|
||||
|
||||
public TransactionServiceImpl(TransactionMapper transactionMapper,
|
||||
@@ -81,6 +83,7 @@ public class TransactionServiceImpl implements TransactionService {
|
||||
TransactionGroupItemMapper transactionGroupItemMapper,
|
||||
ChannelService channelService,
|
||||
TransactionGroupService transactionGroupService,
|
||||
UserPreferenceService userPreferenceService,
|
||||
VoConverter voConverter) {
|
||||
this.transactionMapper = transactionMapper;
|
||||
this.categoryMapper = categoryMapper;
|
||||
@@ -91,6 +94,7 @@ public class TransactionServiceImpl implements TransactionService {
|
||||
this.transactionGroupItemMapper = transactionGroupItemMapper;
|
||||
this.channelService = channelService;
|
||||
this.transactionGroupService = transactionGroupService;
|
||||
this.userPreferenceService = userPreferenceService;
|
||||
this.voConverter = voConverter;
|
||||
}
|
||||
|
||||
@@ -145,11 +149,14 @@ public class TransactionServiceImpl implements TransactionService {
|
||||
if (query.getMaxAmount() != null) {
|
||||
wrapper.le(Transaction::getAmount, query.getMaxAmount());
|
||||
}
|
||||
// 按备注关键字模糊匹配;备注已隐藏的记录不参与搜索
|
||||
// 按备注关键字模糊匹配
|
||||
if (StringUtils.hasText(query.getRemark())) {
|
||||
wrapper.like(Transaction::getRemark, query.getRemark())
|
||||
.and(w -> w.isNull(Transaction::getRemarkHidden)
|
||||
.or().eq(Transaction::getRemarkHidden, false));
|
||||
wrapper.like(Transaction::getRemark, query.getRemark());
|
||||
}
|
||||
// 是否显示已隐藏备注的记录由用户偏好控制,默认不显示
|
||||
if (!userPreferenceService.getShowHiddenData(userId)) {
|
||||
wrapper.and(w -> w.isNull(Transaction::getRemarkHidden)
|
||||
.or().eq(Transaction::getRemarkHidden, false));
|
||||
}
|
||||
// 按标签筛选:命中任一选中标签、有任意标签,或筛选无任何标签的记录(多条件取并集)
|
||||
boolean hasTagIds = query.getTagIds() != null && !query.getTagIds().isEmpty();
|
||||
@@ -802,11 +809,14 @@ public class TransactionServiceImpl implements TransactionService {
|
||||
if (query.getMaxAmount() != null) {
|
||||
wrapper.le(Transaction::getAmount, query.getMaxAmount());
|
||||
}
|
||||
// 按备注关键字模糊匹配;备注已隐藏的记录不参与搜索
|
||||
// 按备注关键字模糊匹配
|
||||
if (StringUtils.hasText(query.getRemark())) {
|
||||
wrapper.like(Transaction::getRemark, query.getRemark())
|
||||
.and(w -> w.isNull(Transaction::getRemarkHidden)
|
||||
.or().eq(Transaction::getRemarkHidden, false));
|
||||
wrapper.like(Transaction::getRemark, query.getRemark());
|
||||
}
|
||||
// 是否显示已隐藏备注的记录由用户偏好控制,默认不显示
|
||||
if (!userPreferenceService.getShowHiddenData(userId)) {
|
||||
wrapper.and(w -> w.isNull(Transaction::getRemarkHidden)
|
||||
.or().eq(Transaction::getRemarkHidden, false));
|
||||
}
|
||||
// 按标签筛选:命中任一选中标签、有任意标签,或筛选无任何标签的记录(多条件取并集)
|
||||
boolean hasTagIds = query.getTagIds() != null && !query.getTagIds().isEmpty();
|
||||
|
||||
@@ -37,6 +37,9 @@ public class UserPreferenceServiceImpl implements UserPreferenceService {
|
||||
/** 偏好键:「不计入统计」记录的展示样式 */
|
||||
private static final String KEY_EXCLUDED_DISPLAY_STYLE = "excludedDisplayStyle";
|
||||
|
||||
/** 偏好键:是否显示已隐藏备注的记录 */
|
||||
private static final String KEY_SHOW_HIDDEN_DATA = "showHiddenData";
|
||||
|
||||
/** 默认计入统计的账单来源,其余来源默认不计入 */
|
||||
private static final Set<String> DEFAULT_INCLUDED_SOURCES = Set.of("WECHAT", "ALIPAY");
|
||||
|
||||
@@ -120,6 +123,29 @@ public class UserPreferenceServiceImpl implements UserPreferenceService {
|
||||
log.info("保存不计入统计展示样式: userId={}, style={}", userId, resolved);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* 结果按用户缓存,未配置时默认不显示。
|
||||
*/
|
||||
@Override
|
||||
@Cacheable(cacheNames = CacheConfig.USER_PREFERENCE_CACHE, key = "'showHiddenData:' + #userId")
|
||||
public boolean getShowHiddenData(Long userId) {
|
||||
return Boolean.parseBoolean(findValue(userId, KEY_SHOW_HIDDEN_DATA));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* 保存后失效该用户的显示偏好缓存。
|
||||
*/
|
||||
@Override
|
||||
@CacheEvict(cacheNames = CacheConfig.USER_PREFERENCE_CACHE, key = "'showHiddenData:' + #userId")
|
||||
public void saveShowHiddenData(Long userId, boolean show) {
|
||||
upsert(userId, KEY_SHOW_HIDDEN_DATA, Boolean.toString(show));
|
||||
log.info("保存隐藏备注记录显示偏好: userId={}, show={}", userId, show);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询指定用户的某个偏好值。
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user