128 lines
3.2 KiB
Go
128 lines
3.2 KiB
Go
package adminfinance
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
|
|
"hfb_sys/backend/internal/timeutil"
|
|
"hfb_sys/backend/pkg/response"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type Handler struct {
|
|
service *Service
|
|
}
|
|
|
|
func NewHandler(service *Service) *Handler {
|
|
return &Handler{service: service}
|
|
}
|
|
|
|
func (h *Handler) Dashboard(c *gin.Context) {
|
|
query, ok := parseDashboardQuery(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
item, err := h.service.Dashboard(query)
|
|
if err != nil {
|
|
writeFinanceError(c, err)
|
|
return
|
|
}
|
|
response.OK(c, item)
|
|
}
|
|
|
|
func (h *Handler) Details(c *gin.Context) {
|
|
query, ok := parseDetailQuery(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
result, err := h.service.Details(query)
|
|
if err != nil {
|
|
writeFinanceError(c, err)
|
|
return
|
|
}
|
|
response.OK(c, result)
|
|
}
|
|
|
|
func parseDashboardQuery(c *gin.Context) (DashboardQuery, bool) {
|
|
start, end, ok := parseDateRange(c, 6)
|
|
if !ok {
|
|
return DashboardQuery{}, false
|
|
}
|
|
return DashboardQuery{StartDate: start, EndDate: end}, true
|
|
}
|
|
|
|
func parseDetailQuery(c *gin.Context) (DetailQuery, bool) {
|
|
start, end, ok := parseDateRange(c, 29)
|
|
if !ok {
|
|
return DetailQuery{}, false
|
|
}
|
|
query := DetailQuery{
|
|
OrderNo: c.Query("order_no"),
|
|
OrderStatus: c.Query("order_status"),
|
|
SettlementStatus: c.Query("settlement_status"),
|
|
DateType: c.DefaultQuery("date_type", "settled"),
|
|
StartDate: start,
|
|
EndDate: end,
|
|
}
|
|
if query.DateType != "created" && query.DateType != "settled" {
|
|
response.BadRequest(c, "日期类型不正确")
|
|
return query, false
|
|
}
|
|
if raw := c.Query("user_id"); raw != "" {
|
|
value, err := strconv.ParseUint(raw, 10, 64)
|
|
if err != nil || value == 0 {
|
|
response.BadRequest(c, "用户 ID 不正确")
|
|
return query, false
|
|
}
|
|
query.UserID = value
|
|
}
|
|
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
|
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
|
query.Page = page
|
|
query.PageSize = pageSize
|
|
return query, true
|
|
}
|
|
|
|
func parseDateRange(c *gin.Context, defaultLookbackDays int) (time.Time, time.Time, bool) {
|
|
loc := timeutil.ShanghaiLocation()
|
|
today := timeutil.ShanghaiNow()
|
|
defaultStart := time.Date(today.Year(), today.Month(), today.Day(), 0, 0, 0, 0, loc).AddDate(0, 0, -defaultLookbackDays)
|
|
defaultEnd := time.Date(today.Year(), today.Month(), today.Day(), 23, 59, 59, int(time.Second-time.Nanosecond), loc)
|
|
|
|
start := defaultStart
|
|
end := defaultEnd
|
|
if raw := c.Query("start_date"); raw != "" {
|
|
parsed, err := time.ParseInLocation("2006-01-02", raw, loc)
|
|
if err != nil {
|
|
response.BadRequest(c, "开始日期不正确")
|
|
return start, end, false
|
|
}
|
|
start = parsed
|
|
}
|
|
if raw := c.Query("end_date"); raw != "" {
|
|
parsed, err := time.ParseInLocation("2006-01-02", raw, loc)
|
|
if err != nil {
|
|
response.BadRequest(c, "结束日期不正确")
|
|
return start, end, false
|
|
}
|
|
end = parsed.AddDate(0, 0, 1).Add(-time.Nanosecond)
|
|
}
|
|
if start.After(end) {
|
|
response.BadRequest(c, "开始日期不能晚于结束日期")
|
|
return start, end, false
|
|
}
|
|
return start, end, true
|
|
}
|
|
|
|
func writeFinanceError(c *gin.Context, err error) {
|
|
switch {
|
|
case errors.Is(err, ErrDependencyUnavailable):
|
|
response.ServiceUnavailable(c, "数据库未连接")
|
|
default:
|
|
response.Error(c, http.StatusInternalServerError, "finance_error", "财务数据暂时不可用")
|
|
}
|
|
}
|