|
@ -1,38 +1,218 @@ |
|
|
from fastapi import Depends, APIRouter, status, Query, Path, HTTPException |
|
|
|
|
|
|
|
|
from fastapi import Depends, APIRouter, status, Query, Path, HTTPException,Request |
|
|
from internal.models import * |
|
|
from internal.models import * |
|
|
from internal.database import fetch_one, fetch_all, execute_query, response_success, raise_if_exists, raise_if_not_found |
|
|
from internal.database import fetch_one, fetch_all, execute_query, response_success, raise_if_exists, raise_if_not_found |
|
|
from dependencies import get_current_active_user |
|
|
from dependencies import get_current_active_user |
|
|
from datetime import datetime |
|
|
from datetime import datetime |
|
|
|
|
|
from limiter_config import limiter |
|
|
router = APIRouter( |
|
|
router = APIRouter( |
|
|
prefix="/disburses", |
|
|
prefix="/disburses", |
|
|
tags=['支出管理'] |
|
|
tags=['支出管理'] |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/list/specificdate") |
|
|
|
|
|
async def disburse_list(days: int): |
|
|
|
|
|
select_query = """SELECT DATE(create_at) AS create_date, SUM(disburseprice) AS total_disburseprice |
|
|
|
|
|
FROM disburses |
|
|
|
|
|
WHERE DATE(create_at) >= DATE_SUB(CURDATE(), INTERVAL %s DAY) -- 一周前的日期 |
|
|
|
|
|
GROUP BY DATE(create_at) |
|
|
|
|
|
ORDER BY create_date ASC;""" |
|
|
|
|
|
disburse_list = fetch_all(select_query, (days-1,)) |
|
|
|
|
|
|
|
|
@router.get("/line/nighweek") |
|
|
|
|
|
@limiter.limit("10/minute") |
|
|
|
|
|
async def disburse_list(request: Request,): |
|
|
|
|
|
select_query = """ |
|
|
|
|
|
-- Generate dates for the current week (Monday to Sunday) |
|
|
|
|
|
SELECT |
|
|
|
|
|
dates.selected_date AS create_date, |
|
|
|
|
|
COALESCE(SUM(d.disburseprice), 0) AS total_disburseprice |
|
|
|
|
|
FROM ( |
|
|
|
|
|
SELECT CURDATE() - INTERVAL (WEEKDAY(CURDATE()) - x.a) DAY AS selected_date |
|
|
|
|
|
FROM ( |
|
|
|
|
|
SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 |
|
|
|
|
|
UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 |
|
|
|
|
|
UNION ALL SELECT 6 |
|
|
|
|
|
) x |
|
|
|
|
|
) AS dates |
|
|
|
|
|
LEFT JOIN disburses d ON DATE(d.create_at) = dates.selected_date |
|
|
|
|
|
WHERE dates.selected_date BETWEEN CURDATE() - INTERVAL WEEKDAY(CURDATE()) DAY |
|
|
|
|
|
AND CURDATE() + INTERVAL (6 - WEEKDAY(CURDATE())) DAY |
|
|
|
|
|
GROUP BY dates.selected_date |
|
|
|
|
|
ORDER BY dates.selected_date ASC; |
|
|
|
|
|
""" |
|
|
|
|
|
disburse_list = fetch_all(select_query) |
|
|
|
|
|
return response_success(disburse_list, "disburse get list success") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/line/nighmonth") |
|
|
|
|
|
@limiter.limit("10/minute") |
|
|
|
|
|
async def disburse_list(request: Request,): |
|
|
|
|
|
select_query = """ |
|
|
|
|
|
-- Generate dates for the current month (1st to last day) |
|
|
|
|
|
SELECT |
|
|
|
|
|
dates.selected_date AS create_date, |
|
|
|
|
|
COALESCE(SUM(d.disburseprice), 0) AS total_disburseprice |
|
|
|
|
|
FROM ( |
|
|
|
|
|
SELECT DATE_FORMAT(CURDATE() - INTERVAL (DAY(CURDATE()) - 1) DAY + INTERVAL x.a DAY, '%Y-%m-%d') AS selected_date |
|
|
|
|
|
FROM ( |
|
|
|
|
|
SELECT @rownum := @rownum + 1 AS a |
|
|
|
|
|
FROM (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 |
|
|
|
|
|
UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 |
|
|
|
|
|
UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15 UNION ALL SELECT 16 |
|
|
|
|
|
UNION ALL SELECT 17 UNION ALL SELECT 18 UNION ALL SELECT 19 UNION ALL SELECT 20 UNION ALL SELECT 21 |
|
|
|
|
|
UNION ALL SELECT 22 UNION ALL SELECT 23 UNION ALL SELECT 24 UNION ALL SELECT 25 UNION ALL SELECT 26 |
|
|
|
|
|
UNION ALL SELECT 27 UNION ALL SELECT 28 UNION ALL SELECT 29 UNION ALL SELECT 30 UNION ALL SELECT 31) t1, |
|
|
|
|
|
(SELECT @rownum := -1) t2 |
|
|
|
|
|
) x |
|
|
|
|
|
WHERE DATE_FORMAT(CURDATE() - INTERVAL (DAY(CURDATE()) - 1) DAY + INTERVAL x.a DAY, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m') |
|
|
|
|
|
) AS dates |
|
|
|
|
|
LEFT JOIN disburses d ON DATE(d.create_at) = dates.selected_date |
|
|
|
|
|
GROUP BY dates.selected_date |
|
|
|
|
|
ORDER BY dates.selected_date ASC; |
|
|
|
|
|
""" |
|
|
|
|
|
disburse_list = fetch_all(select_query) |
|
|
|
|
|
return response_success(disburse_list, "disburse get list success") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/line/nighyear") |
|
|
|
|
|
@limiter.limit("10/minute") |
|
|
|
|
|
async def disburse_list(request: Request,): |
|
|
|
|
|
select_query = """ |
|
|
|
|
|
-- Generate months for the current year (January to December) |
|
|
|
|
|
SELECT |
|
|
|
|
|
DATE_FORMAT(months.selected_month, '%Y-%m') AS create_date, -- Only keep the year and month |
|
|
|
|
|
COALESCE(SUM(d.disburseprice), 0) AS total_disburseprice |
|
|
|
|
|
FROM ( |
|
|
|
|
|
-- Generate months from January to December of the current year |
|
|
|
|
|
SELECT DATE_FORMAT(CONCAT(YEAR(CURDATE()), '-', LPAD(x.a, 2, '0'), '-01'), '%Y-%m-01') AS selected_month |
|
|
|
|
|
FROM ( |
|
|
|
|
|
SELECT 1 AS a UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 |
|
|
|
|
|
UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 |
|
|
|
|
|
UNION ALL SELECT 12 |
|
|
|
|
|
) x |
|
|
|
|
|
) AS months |
|
|
|
|
|
LEFT JOIN disburses d ON DATE_FORMAT(d.create_at, '%Y-%m') = DATE_FORMAT(months.selected_month, '%Y-%m') -- Match by year and month only |
|
|
|
|
|
AND d.create_at >= DATE_FORMAT(CURDATE(), '%Y-01-01') |
|
|
|
|
|
AND d.create_at < DATE_FORMAT(CURDATE() + INTERVAL 1 YEAR, '%Y-01-01') |
|
|
|
|
|
GROUP BY DATE_FORMAT(months.selected_month, '%Y-%m') -- Group by year and month only |
|
|
|
|
|
ORDER BY create_date ASC; |
|
|
|
|
|
""" |
|
|
|
|
|
disburse_list = fetch_all(select_query) |
|
|
return response_success(disburse_list, "disburse get list success") |
|
|
return response_success(disburse_list, "disburse get list success") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/list/classifieddata") |
|
|
|
|
|
async def classified_list(days: int): |
|
|
|
|
|
select_query = """SELECT SUM(d.disburseprice) AS value,t.typename AS name FROM disburses d |
|
|
|
|
|
|
|
|
@router.get("/pie/nighweek") |
|
|
|
|
|
@limiter.limit("10/minute") |
|
|
|
|
|
async def classified_list(request: Request,): |
|
|
|
|
|
select_query = """ |
|
|
|
|
|
-- Generate classified data for the current week (Monday to Sunday) |
|
|
|
|
|
SELECT |
|
|
|
|
|
t.typename AS name, |
|
|
|
|
|
COALESCE(SUM(daily_totals.value), 0) AS value |
|
|
|
|
|
FROM ( |
|
|
|
|
|
-- Generate dates for the current week |
|
|
|
|
|
SELECT CURDATE() - INTERVAL (WEEKDAY(CURDATE()) - x.a) DAY AS selected_date |
|
|
|
|
|
FROM ( |
|
|
|
|
|
SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 |
|
|
|
|
|
UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 |
|
|
|
|
|
UNION ALL SELECT 6 |
|
|
|
|
|
) x |
|
|
|
|
|
) AS dates |
|
|
|
|
|
CROSS JOIN disbursetypes t -- Cross join to combine all dates with all typenames |
|
|
|
|
|
LEFT JOIN ( |
|
|
|
|
|
-- Subquery to aggregate daily totals per type |
|
|
|
|
|
SELECT |
|
|
|
|
|
DATE(d.create_at) AS create_date, |
|
|
|
|
|
t.typename AS name, |
|
|
|
|
|
SUM(d.disburseprice) AS value |
|
|
|
|
|
FROM disburses d |
|
|
JOIN disbursetypes t ON d.typeid = t.id |
|
|
JOIN disbursetypes t ON d.typeid = t.id |
|
|
WHERE d.create_at >= DATE_SUB(CURDATE(), INTERVAL %s DAY) |
|
|
|
|
|
|
|
|
WHERE DATE(d.create_at) BETWEEN CURDATE() - INTERVAL WEEKDAY(CURDATE()) DAY |
|
|
|
|
|
AND CURDATE() + INTERVAL (6 - WEEKDAY(CURDATE())) DAY |
|
|
|
|
|
GROUP BY DATE(d.create_at), t.typename |
|
|
|
|
|
) AS daily_totals ON daily_totals.create_date = dates.selected_date AND daily_totals.name = t.typename |
|
|
GROUP BY t.typename |
|
|
GROUP BY t.typename |
|
|
;""" |
|
|
|
|
|
classified_list = fetch_all(select_query, (days-1,)) |
|
|
|
|
|
|
|
|
ORDER BY t.typename ASC; |
|
|
|
|
|
""" |
|
|
|
|
|
classified_list = fetch_all(select_query) |
|
|
|
|
|
return response_success(classified_list, "disburse get list success") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/pie/nighmonth") |
|
|
|
|
|
@limiter.limit("10/minute") |
|
|
|
|
|
async def classified_list(request: Request,): |
|
|
|
|
|
select_query = """ |
|
|
|
|
|
-- Generate classified data for the current month (1st to last day of the month) |
|
|
|
|
|
SELECT |
|
|
|
|
|
t.typename AS name, |
|
|
|
|
|
COALESCE(SUM(daily_totals.value), 0) AS value |
|
|
|
|
|
FROM ( |
|
|
|
|
|
-- Generate dates for the current month |
|
|
|
|
|
SELECT DATE_FORMAT(CURDATE() - INTERVAL (DAY(CURDATE()) - 1) DAY + INTERVAL x.a DAY, '%Y-%m-%d') AS selected_date |
|
|
|
|
|
FROM ( |
|
|
|
|
|
SELECT @rownum := @rownum + 1 AS a |
|
|
|
|
|
FROM (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 |
|
|
|
|
|
UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 |
|
|
|
|
|
UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15 UNION ALL SELECT 16 |
|
|
|
|
|
UNION ALL SELECT 17 UNION ALL SELECT 18 UNION ALL SELECT 19 UNION ALL SELECT 20 UNION ALL SELECT 21 |
|
|
|
|
|
UNION ALL SELECT 22 UNION ALL SELECT 23 UNION ALL SELECT 24 UNION ALL SELECT 25 UNION ALL SELECT 26 |
|
|
|
|
|
UNION ALL SELECT 27 UNION ALL SELECT 28 UNION ALL SELECT 29 UNION ALL SELECT 30 UNION ALL SELECT 31) t1, |
|
|
|
|
|
(SELECT @rownum := -1) t2 |
|
|
|
|
|
) x |
|
|
|
|
|
WHERE DATE_FORMAT(CURDATE() - INTERVAL (DAY(CURDATE()) - 1) DAY + INTERVAL x.a DAY, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m') |
|
|
|
|
|
) AS dates |
|
|
|
|
|
CROSS JOIN disbursetypes t -- Cross join to combine all dates with all typenames |
|
|
|
|
|
LEFT JOIN ( |
|
|
|
|
|
-- Subquery to aggregate daily totals per type |
|
|
|
|
|
SELECT |
|
|
|
|
|
DATE(d.create_at) AS create_date, |
|
|
|
|
|
t.typename AS name, |
|
|
|
|
|
SUM(d.disburseprice) AS value |
|
|
|
|
|
FROM disburses d |
|
|
|
|
|
JOIN disbursetypes t ON d.typeid = t.id |
|
|
|
|
|
WHERE DATE(d.create_at) BETWEEN DATE_FORMAT(CURDATE() - INTERVAL (DAY(CURDATE()) - 1) DAY, '%Y-%m-%d') |
|
|
|
|
|
AND LAST_DAY(CURDATE()) |
|
|
|
|
|
GROUP BY DATE(d.create_at), t.typename |
|
|
|
|
|
) AS daily_totals ON daily_totals.create_date = dates.selected_date AND daily_totals.name = t.typename |
|
|
|
|
|
GROUP BY t.typename |
|
|
|
|
|
ORDER BY t.typename ASC; |
|
|
|
|
|
""" |
|
|
|
|
|
classified_list = fetch_all(select_query) |
|
|
|
|
|
return response_success(classified_list, "disburse get list success") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/pie/nighyear") |
|
|
|
|
|
@limiter.limit("10/minute") |
|
|
|
|
|
async def classified_list(request: Request,): |
|
|
|
|
|
select_query = """ |
|
|
|
|
|
-- Generate classified data for the current year (January to December) |
|
|
|
|
|
SELECT |
|
|
|
|
|
t.typename AS name, |
|
|
|
|
|
COALESCE(SUM(monthly_totals.value), 0) AS value |
|
|
|
|
|
FROM ( |
|
|
|
|
|
-- Generate months for the current year |
|
|
|
|
|
SELECT DATE_FORMAT(CONCAT(YEAR(CURDATE()), '-', LPAD(x.a, 2, '0'), '-01'), '%Y-%m-01') AS selected_month |
|
|
|
|
|
FROM ( |
|
|
|
|
|
SELECT 1 AS a UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 |
|
|
|
|
|
UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 |
|
|
|
|
|
UNION ALL SELECT 12 |
|
|
|
|
|
) x |
|
|
|
|
|
) AS months |
|
|
|
|
|
CROSS JOIN disbursetypes t -- Cross join to combine all months with all typenames |
|
|
|
|
|
LEFT JOIN ( |
|
|
|
|
|
-- Subquery to aggregate monthly totals per type |
|
|
|
|
|
SELECT |
|
|
|
|
|
DATE_FORMAT(d.create_at, '%Y-%m-01') AS create_month, |
|
|
|
|
|
t.typename AS name, |
|
|
|
|
|
SUM(d.disburseprice) AS value |
|
|
|
|
|
FROM disburses d |
|
|
|
|
|
JOIN disbursetypes t ON d.typeid = t.id |
|
|
|
|
|
WHERE DATE_FORMAT(d.create_at, '%Y-%m') BETWEEN DATE_FORMAT(CURDATE() - INTERVAL (YEAR(CURDATE()) - YEAR(d.create_at)) YEAR, '%Y-01') |
|
|
|
|
|
AND DATE_FORMAT(CURDATE(), '%Y-12') |
|
|
|
|
|
GROUP BY DATE_FORMAT(d.create_at, '%Y-%m-01'), t.typename |
|
|
|
|
|
) AS monthly_totals ON monthly_totals.create_month = months.selected_month AND monthly_totals.name = t.typename |
|
|
|
|
|
GROUP BY t.typename |
|
|
|
|
|
ORDER BY t.typename ASC; |
|
|
|
|
|
""" |
|
|
|
|
|
classified_list = fetch_all(select_query) |
|
|
return response_success(classified_list, "disburse get list success") |
|
|
return response_success(classified_list, "disburse get list success") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/list/consume") |
|
|
@router.get("/list/consume") |
|
|
async def consume_list(days: int): |
|
|
|
|
|
|
|
|
@limiter.limit("10/minute") |
|
|
|
|
|
async def consume_list(request: Request,days: int): |
|
|
current_year = datetime.now().year |
|
|
current_year = datetime.now().year |
|
|
target_year = current_year - days |
|
|
target_year = current_year - days |
|
|
|
|
|
|
|
@ -62,7 +242,8 @@ async def consume_list(days: int): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/list/calendar") |
|
|
@router.get("/list/calendar") |
|
|
async def calendar_list(): |
|
|
|
|
|
|
|
|
@limiter.limit("10/minute") |
|
|
|
|
|
async def calendar_list(request: Request,): |
|
|
select_query = """ |
|
|
select_query = """ |
|
|
SELECT t.typename AS NAME, YEAR(d.create_at) AS YEAR, SUM(d.disburseprice) AS total_amount |
|
|
SELECT t.typename AS NAME, YEAR(d.create_at) AS YEAR, SUM(d.disburseprice) AS total_amount |
|
|
FROM disburses d |
|
|
FROM disburses d |
|
|