duqing2026's picture
升级优化
05c3aec
import os
import json
import uuid
from datetime import datetime
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
DATA_FILE = os.environ.get("DATA_FILE", "requests.json")
DEFAULT_REQUESTS = [
{
"id": "1",
"title": "增加暗色模式",
"description": "建议增加暗色模式支持,方便夜间使用。",
"category": "界面设计 (UI/UX)",
"votes": 15,
"status": "planned",
"created_at": datetime.now().isoformat(),
"comments": []
},
{
"id": "2",
"title": "支持图片上传",
"description": "在提交反馈时,希望可以上传截图,这样能更直观地说明问题。",
"category": "功能建议 (Feature)",
"votes": 8,
"status": "pending",
"created_at": datetime.now().isoformat(),
"comments": []
},
{
"id": "3",
"title": "移动端适配优化",
"description": "目前在手机上查看列表时,排版有些拥挤,建议优化移动端显示。",
"category": "界面设计 (UI/UX)",
"votes": 12,
"status": "in_progress",
"created_at": datetime.now().isoformat(),
"comments": []
}
]
def load_data():
if not os.path.exists(DATA_FILE):
save_data(DEFAULT_REQUESTS)
return DEFAULT_REQUESTS
try:
with open(DATA_FILE, "r", encoding="utf-8") as f:
data = json.load(f)
if not isinstance(data, list):
# If data is corrupted (not a list), backup and reset
print(f"Warning: {DATA_FILE} contains invalid data (not a list). Resetting.")
os.rename(DATA_FILE, DATA_FILE + ".bak")
save_data(DEFAULT_REQUESTS)
return DEFAULT_REQUESTS
return data
except Exception as e:
print(f"Error loading data: {e}. Resetting.")
# If file is corrupted, reset
if os.path.exists(DATA_FILE):
os.rename(DATA_FILE, DATA_FILE + ".bak")
save_data(DEFAULT_REQUESTS)
return DEFAULT_REQUESTS
def save_data(data):
try:
with open(DATA_FILE, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
except Exception as e:
print(f"Error saving data: {e}")
@app.route("/")
def index():
return render_template("index.html")
@app.route("/api/requests", methods=["GET"])
def get_requests():
data = load_data()
# Sort by votes (desc) then date (desc)
data.sort(key=lambda x: (x.get("votes", 0), x.get("created_at", "")), reverse=True)
return jsonify(data)
@app.route("/api/requests", methods=["POST"])
def add_request():
data = load_data()
payload = request.json
if not payload.get("title") or not payload.get("description"):
return jsonify({"error": "Title and description are required"}), 400
new_request = {
"id": str(uuid.uuid4()),
"title": payload["title"],
"description": payload["description"],
"category": payload.get("category", "General"),
"votes": 1,
"status": "pending", # pending, planned, in_progress, completed, rejected
"created_at": datetime.now().isoformat(),
"comments": []
}
data.append(new_request)
save_data(data)
return jsonify(new_request)
@app.route("/api/requests/<req_id>/vote", methods=["POST"])
def vote_request(req_id):
data = load_data()
for req in data:
if req["id"] == req_id:
req["votes"] = req.get("votes", 0) + 1
save_data(data)
return jsonify({"success": True, "votes": req["votes"]})
return jsonify({"error": "Request not found"}), 404
@app.route("/api/requests/<req_id>/status", methods=["POST"])
def update_status(req_id):
# Simple admin check (in a real app, use auth)
# Here we just trust the client for the demo/MVP purpose
payload = request.json
new_status = payload.get("status")
if new_status not in ["pending", "planned", "in_progress", "completed", "rejected"]:
return jsonify({"error": "Invalid status"}), 400
data = load_data()
for req in data:
if req["id"] == req_id:
req["status"] = new_status
save_data(data)
return jsonify({"success": True, "status": new_status})
return jsonify({"error": "Request not found"}), 404
if __name__ == "__main__":
app.run(host="0.0.0.0", port=7860)