liujie
2026-09-15 ad491191ab50a259da548863d805c57d8a95d083
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package com.tourguide.api.admin;
 
import com.tourguide.common.api.ApiResponse;
import com.tourguide.common.api.PageResponse;
import com.tourguide.common.exception.BusinessException;
import com.tourguide.modules.finance.dto.FinanceLedgerPageResponse;
import com.tourguide.modules.finance.dto.WithdrawalProcessRequest;
import com.tourguide.modules.finance.dto.WithdrawalResponse;
import com.tourguide.modules.finance.service.AdminFinanceService;
import com.tourguide.security.AppUserPrincipal;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.time.LocalDate;
 
/**
 * 管理后台财务管理接口。
 * 提供平台收支流水、导游提现申请查询以及提现审核处理能力。
 */
@RestController
@RequestMapping("/api/admin")
public class AdminFinanceController {
    private final AdminFinanceService financeService;
 
    public AdminFinanceController(AdminFinanceService financeService) {
        this.financeService = financeService;
    }
 
    /**
     * 分页查询平台收入或退款支出流水,并按平台抽成比例计算平台与导游收益。
     *
     * @param page 页码,从 1 开始
     * @param size 每页记录数
     * @param direction 流水方向,INCOME 表示收入,其他受支持值表示退款支出
     * @param keyword 订单号、导游等关键字
     * @param paymentMethod 支付方式筛选条件
     * @param startDate 流水发生日期起始值,包含当天
     * @param endDate 流水发生日期结束值,包含当天
     * @return 财务流水分页数据及汇总金额
     */
    @GetMapping("/finance/ledger")
    public ApiResponse<FinanceLedgerPageResponse> ledger(@RequestParam(defaultValue = "1") long page,
                                                         @RequestParam(defaultValue = "10") long size,
                                                         @RequestParam(defaultValue = "INCOME") String direction,
                                                         @RequestParam(required = false) String keyword,
                                                         @RequestParam(required = false) String paymentMethod,
                                                         @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
                                                         @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate,
                                                         Authentication authentication) {
        String requiredAuthority = "REFUND".equalsIgnoreCase(direction)
                ? "PERM_FINANCE_REFUND_VIEW" : "PERM_FINANCE_DETAIL_VIEW";
        if (authentication.getAuthorities().stream()
                .noneMatch(authority -> requiredAuthority.equals(authority.getAuthority()))) {
            throw new BusinessException(403, "无权访问该财务流水");
        }
        return ApiResponse.success(financeService.ledger(page, size, direction, keyword, paymentMethod, startDate, endDate));
    }
 
    /**
     * 分页查询导游提现申请,支持按申请信息、处理状态和申请日期筛选。
     *
     * @param page 页码,从 1 开始
     * @param size 每页记录数
     * @param keyword 提现单号、导游姓名或手机号等关键字
     * @param status 提现处理状态
     * @param startDate 申请日期起始值,包含当天
     * @param endDate 申请日期结束值,包含当天
     * @return 提现申请分页结果
     */
    @GetMapping("/withdrawals")
    public ApiResponse<PageResponse<WithdrawalResponse>> withdrawals(@RequestParam(defaultValue = "1") long page,
                                                                      @RequestParam(defaultValue = "10") long size,
                                                                      @RequestParam(required = false) String keyword,
                                                                      @RequestParam(required = false) String status,
                                                                      @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
                                                                      @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
        return ApiResponse.success(financeService.withdrawals(page, size, keyword, status, startDate, endDate));
    }
 
    /**
     * 审核并处理指定提现申请,记录处理结果、备注和当前后台操作人。
     * 已处理或状态不允许变更的申请由业务层拒绝重复操作。
     *
     * @param id 提现申请主键
     * @param request 审核结果及处理备注
     * @param authentication 当前后台登录认证信息
     * @return 处理后的提现申请详情
     */
    @PutMapping("/withdrawals/{id}/process")
    public ApiResponse<WithdrawalResponse> processWithdrawal(@PathVariable Long id,
                                                              @Valid @RequestBody WithdrawalProcessRequest request,
                                                              @AuthenticationPrincipal AppUserPrincipal principal) {
        return ApiResponse.success(financeService.processWithdrawal(id, request, principal.getUsername()));
    }
}