You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Thymeleaf页面无法展示Transaction实体分组数据问题排查

解决交易分组数据在Thymeleaf页面不显示的问题

让我们一步步排查并修复你遇到的问题——交易能成功保存但页面空白,核心问题出在分组逻辑缺失、无效的方法调用、Model数据未传递以及模板变量错误这几个方面:

1. 修复TransactionGroup类的无效方法

你写的setTransactions重载方法完全没有给transactions列表赋值,相当于空操作。我们需要初始化列表并添加有效的添加交易方法:

public class TransactionGroup {
    private LocalDate date;
    // 初始化空列表,避免NullPointerException
    private List<Transaction> transactions = new ArrayList<>();

    // 保留原有的getter和setter
    public LocalDate getDate() { return date; }
    public void setDate(LocalDate date) { this.date = date; }
    public List<Transaction> getTransactions() { return transactions; }
    public void setTransactions(List<Transaction> transactions) { this.transactions = transactions; }

    // 添加一个有效的添加交易方法,替代原来的无效重载
    public void addTransaction(Transaction transaction) {
        this.transactions.add(transaction);
    }
}

2. 在页面展示方法中实现按日期分组逻辑

你当前的saveIncome方法里创建TransactionGroup的代码毫无意义——分组逻辑应该在展示交易列表的Controller方法中完成,而不是保存的时候。假设你跳转到的/api/wallet/userWallet/balance/{userId}对应的Controller方法如下,添加分组逻辑:

@GetMapping("/api/wallet/userWallet/balance/{userId}")
public String showUserBalance(@PathVariable long userId, Model model) {
    // 1. 获取该用户的所有交易记录
    List<Transaction> userTransactions = transactionService.getTransactionsByUserId(userId);
    
    // 2. 按日期分组,转换成TransactionGroup列表
    List<TransactionGroup> transactionGroups = userTransactions.stream()
        .collect(Collectors.groupingBy(Transaction::getDate)) // 按交易日期分组
        .entrySet().stream()
        .map(entry -> {
            TransactionGroup group = new TransactionGroup();
            group.setDate(entry.getKey());
            group.setTransactions(entry.getValue()); // 把同日期的交易放入分组
            return group;
        })
        .sorted(Comparator.comparing(TransactionGroup::getDate).reversed()) // 按日期倒序显示(最新的在前)
        .collect(Collectors.toList());
    
    // 3. 把分组后的数据放入Model,传给Thymeleaf页面
    model.addAttribute("transactionGroups", transactionGroups);
    
    // 这里可以添加其他需要的属性,比如用户钱包余额等
    return "balance_page"; // 替换成你实际的页面模板名称
}

3. 清理saveIncome方法中的无效代码

删除saveIncome里调用无效setTransactions的代码,因为分组逻辑已经移到展示页面的方法中了:

@PostMapping("/saveIncome/{walletId}")
public String saveIncome(@PathVariable(value = "walletId") long walletId, @Valid Transaction transaction, BindingResult result, Model model) {

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    UserDetailsImpl user = (UserDetailsImpl) authentication.getPrincipal();
    long userId = user.getId();

    Wallet wallet = walletService.getWalletById(walletId);

    boolean thereAreErrors = result.hasErrors();
    if (thereAreErrors) {
        model.addAttribute("incomeCategories", IncomeCategories.values());
        return "income_transaction";
    }

    transaction.setWallet(wallet);
    transaction.setUserId(userId);
    transaction.setWalletName(wallet.getWalletName());
    
    // 删掉这行无效代码:
    // transactionGroup.setTransactions(transaction.getWalletName(), transaction.getAmount(), transaction.getNote(), transaction.getDate(), transaction.getTransactionType(), transaction.getExpenseCategories(), transaction.getIncomeCategories());
    
    transactionService.saveIncome(transaction, walletId, userId);
    return "redirect:/api/wallet/userWallet/balance/" + userId;
}

4. 修复Thymeleaf模板的变量错误

你的模板里有两个关键错误:

  • 循环的变量应该是transactionGroups(我们放入Model的分组列表),而不是单个transactionGroup
  • 内部循环的变量是transaction,引用属性时应该用${transaction.amount}而不是${transactions.amount}(复数形式错误)

修改后的模板代码:

<div th:each="group : ${transactionGroups}">
    <h1 th:text="${#temporals.format(group.date, 'yyyy-MM-dd')}"></h1>

    <div th:each="transaction : ${group.transactions}">
        <h2>Amount: <span th:text="${transaction.amount}"></span></h2><br>
        <h2>Note: <span th:text="${transaction.note} ?: 'No note'"></span></h2><br>
        <h2>Wallet name: <span th:text="${transaction.walletName}"></span></h2><br>
        <!-- 根据交易类型显示对应分类,避免显示null -->
        <h2 th:if="${transaction.transactionType == 'EXPENSE'}">Expense Category: <span th:text="${transaction.expenseCategories}"></span></h2><br>
        <h2 th:if="${transaction.transactionType == 'INCOME'}">Income Category: <span th:text="${transaction.incomeCategories}"></span></h2>
        <hr>
    </div>
</div>

最后需要检查的点

  • 确保transactionService.getTransactionsByUserId(userId)能正确查询到该用户的所有交易记录
  • 确认交易的date字段在保存时已经被正确赋值(比如前端表单传递了正确的日期,或者后端默认设置为LocalDate.now())
  • 检查Thymeleaf模板的路径是否正确,跳转的页面是否是你修改的这个模板

内容的提问来源于stack exchange,提问作者Frosty Nah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 16:30:37