diff --git a/.idea/table_game_project.iml b/.idea/table_game_project.iml index 776095d..366c8c0 100644 --- a/.idea/table_game_project.iml +++ b/.idea/table_game_project.iml @@ -4,6 +4,7 @@ + diff --git a/README.md b/README.md index 05032df..88f0b6d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ screen -S backend conda activate tabel_game_admin -uvicorn backend.app.main:app --reload --host 127.0.0.1 +uvicorn backend.app.main:app --reload --host 127.0.0.1 --reload-include backend/config.conf diff --git a/backend/app/main.py b/backend/app/main.py index f4d0231..63c330d 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -21,6 +21,7 @@ from .routers import admin_message from .routers import user_messages from .routers import bell from .routers import admin_strategy +from .routers import admin_congif @@ -64,6 +65,9 @@ app.include_router(admin_message.router, prefix="/admin", tags=["Admin-Message"] app.include_router(admin_strategy.router, prefix="/admin", tags=["Admin-Strategy"]) +app.include_router(admin_congif.router, prefix="/admin", tags=["Admin-Config"]) + + diff --git a/backend/app/routers/admin_congif.py b/backend/app/routers/admin_congif.py new file mode 100644 index 0000000..d34dd37 --- /dev/null +++ b/backend/app/routers/admin_congif.py @@ -0,0 +1,59 @@ +from fastapi import APIRouter, HTTPException +from pydantic import BaseModel +from ..services.admin_config_service import ( + get_price_config, + get_night_config, + update_points_rate, + update_get_points_rate, + update_night_start, + update_night_end, + update_price_minutes +) +from ..services.admin_table_service import _verify_admin_permission + +router = APIRouter() + +class UpdatePointsRateRequest(BaseModel): + token: str + points_rate: float + +class UpdateNightTimeRequest(BaseModel): + token: str + time: str # 格式:"HH:MM:SS" + +class UpdatePriceMinutesRequest(BaseModel): + token: str + price_minutes: int + +@router.get("/config/price") +def get_price_config_api(): + return get_price_config() + +@router.get("/config/night") +def get_night_config_api(): + return get_night_config() + +@router.post("/config/points-rate") +def update_points_rate_api(request: UpdatePointsRateRequest): + _verify_admin_permission(request.token) + return update_points_rate(request.points_rate) + +@router.post("/config/get-points-rate") +def update_get_points_rate_api(request: UpdatePointsRateRequest): + _verify_admin_permission(request.token) + return update_get_points_rate(request.points_rate) + +@router.post("/config/night-start") +def update_night_start_api(request: UpdateNightTimeRequest): + _verify_admin_permission(request.token) + return update_night_start(request.time) + +@router.post("/config/night-end") +def update_night_end_api(request: UpdateNightTimeRequest): + _verify_admin_permission(request.token) + return update_night_end(request.time) + +@router.post("/config/price-minutes") +def update_price_minutes_api(request: UpdatePriceMinutesRequest): + _verify_admin_permission(request.token) + return update_price_minutes(request.price_minutes) diff --git a/backend/app/services/admin_config_service.py b/backend/app/services/admin_config_service.py new file mode 100644 index 0000000..0471e15 --- /dev/null +++ b/backend/app/services/admin_config_service.py @@ -0,0 +1,80 @@ +import configparser +from pathlib import Path +from fastapi import HTTPException + +config_path = Path("backend/config.conf") + +def _save_config(config): + try: + with open(config_path, 'w') as configfile: + config.write(configfile) + except Exception as e: + raise HTTPException(500, f"配置保存失败: {str(e)}") + +def get_price_config(): + config = configparser.ConfigParser() + config.read(config_path) + return { + "points_rate": float(config.get("price", "points_rate")), + "get_points_rate": float(config.get("price", "get_points_rate")) + } + +def get_night_config(): + config = configparser.ConfigParser() + config.read(config_path) + return { + "start_time": config.get("stay_up_late", "start_time"), + "end_time": config.get("stay_up_late", "end_time"), + "price_minutes": int(config.get("stay_up_late", "price_minutes")) + } + +def update_points_rate(new_rate: float): + config = configparser.ConfigParser() + config.read(config_path) + config.set("price", "points_rate", str(new_rate)) + _save_config(config) + return {"message": "积分抵扣率更新成功"} + +def update_get_points_rate(new_rate: float): + config = configparser.ConfigParser() + config.read(config_path) + config.set("price", "get_points_rate", str(new_rate)) + _save_config(config) + return {"message": "积分获取率更新成功"} + +def update_night_start(new_time: str): + # 添加时间格式验证 + try: + from datetime import datetime + datetime.strptime(new_time, "%H:%M:%S") + except ValueError: + raise HTTPException(400, "时间格式应为 HH:MM:SS") + + config = configparser.ConfigParser() + config.read(config_path) + config.set("stay_up_late", "start_time", new_time) + _save_config(config) + return {"message": "晚场开始时间更新成功"} + +def update_night_end(new_time: str): + # 同样添加时间验证 + try: + from datetime import datetime + datetime.strptime(new_time, "%H:%M:%S") + except ValueError: + raise HTTPException(400, "时间格式应为 HH:MM:SS") + config = configparser.ConfigParser() + config.read(config_path) + config.set("stay_up_late", "end_time", new_time) + _save_config(config) + return {"message": "晚场结束时间更新成功"} + +def update_price_minutes(minutes: int): + if minutes <= 0: + raise HTTPException(400, "分钟数必须大于0") + + config = configparser.ConfigParser() + config.read(config_path) + config.set("stay_up_late", "price_minutes", str(minutes)) + _save_config(config) + return {"message": "计费分钟间隔更新成功"} diff --git a/frontend/__init__.py b/frontend/__init__.py index ea0a3c2..d0e3e87 100644 --- a/frontend/__init__.py +++ b/frontend/__init__.py @@ -20,6 +20,7 @@ def create_app(): from frontend.routes.coupons import coupons_bp from frontend.routes.messages import messages_bp from frontend.routes.strategies import strategies_bp + from frontend.routes.config import config_bp app.config['DEBUG_TB_INTERCEPT_REDIRECTS'] = False toolbar = DebugToolbarExtension(app) @@ -36,6 +37,7 @@ def create_app(): app.register_blueprint(coupons_bp) app.register_blueprint(messages_bp) app.register_blueprint(strategies_bp) + app.register_blueprint(config_bp) # 添加自定义过滤器 @app.template_filter('datetime') diff --git a/frontend/routes/config.py b/frontend/routes/config.py new file mode 100644 index 0000000..aaa9886 --- /dev/null +++ b/frontend/routes/config.py @@ -0,0 +1,58 @@ +from flask import Blueprint, render_template, session, redirect, url_for, flash, request +import requests +from frontend.config import Config + +config_bp = Blueprint('config', __name__, url_prefix='/admin/config') + +@config_bp.route('/manage', methods=['GET', 'POST']) +def manage_config(): + if not session.get('token'): + return redirect(url_for('auth.login')) + + # 获取所有配置 + price_resp = requests.get(f"{Config.BASE_API_URL}/admin/config/price") + night_resp = requests.get(f"{Config.BASE_API_URL}/admin/config/night") + + config = { + 'price': price_resp.json() if price_resp.status_code == 200 else {}, + 'night': night_resp.json() if night_resp.status_code == 200 else {} + } + print(config) + + if request.method == 'POST': + field = request.form.get('field') + value = request.form.get('value') + + # 定义所有配置项的API端点映射 + endpoints = { + 'points_rate': '/points-rate', + 'get_points_rate': '/get-points-rate', + 'start_time': '/night-start', + 'end_time': '/night-end', + 'price_minutes': '/price-minutes' + } + + # 构建请求参数 + json_data = {"token": session['token']} + if field in ['points_rate', 'get_points_rate']: + json_data[field] = float(value) + elif field in ['start_time', 'end_time']: + json_data['time' if field in ['start_time', 'end_time'] else field] = value + else: + json_data[field] = int(value) + + resp = requests.post( + f"{Config.BASE_API_URL}/admin/config{endpoints[field]}", + json=json_data + ) + + if resp.status_code == 200: + flash("配置更新成功", "success") + else: + error_detail = resp.json().get('detail', '未知错误') + flash(f"更新失败: {error_detail}", "danger") + + return redirect(url_for('config.manage_config')) + + return render_template('config/manage.html', config=config) + diff --git a/frontend/templates/base.html b/frontend/templates/base.html index 26ed114..457249d 100644 --- a/frontend/templates/base.html +++ b/frontend/templates/base.html @@ -4,7 +4,7 @@ {% block title %}桌游厅点单系统管理后台{% endblock %} - +