t
This commit is contained in:
235
main.py
235
main.py
@@ -1661,6 +1661,241 @@ async def success_page(request: Request):
|
||||
CONFIG = load_config()
|
||||
return templates.TemplateResponse("success.html", {"request": request, "config": CONFIG})
|
||||
|
||||
@app.get("/data-base", response_class=HTMLResponse)
|
||||
async def data_base_page(request: Request):
|
||||
"""
|
||||
渲染数据库管理页面。
|
||||
"""
|
||||
return templates.TemplateResponse("data_base.html", {"request": request})
|
||||
|
||||
@app.get("/api/db/tables")
|
||||
def get_db_tables():
|
||||
"""
|
||||
获取数据库中所有的表。
|
||||
"""
|
||||
try:
|
||||
conn = get_db_connection()
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
cur.execute("""
|
||||
SELECT table_name
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = 'public'
|
||||
AND table_type = 'BASE TABLE'
|
||||
ORDER BY table_name
|
||||
""")
|
||||
rows = cur.fetchall()
|
||||
|
||||
tables = [row['table_name'] for row in rows]
|
||||
|
||||
cur.close()
|
||||
release_db_connection(conn)
|
||||
|
||||
return {"success": True, "tables": tables}
|
||||
except Exception as e:
|
||||
return JSONResponse(content={"success": False, "message": str(e)}, status_code=500)
|
||||
|
||||
@app.get("/api/db/table/{table_name}")
|
||||
def get_table_data(table_name: str, page: int = 1, page_size: int = 50):
|
||||
"""
|
||||
获取指定表的数据。
|
||||
"""
|
||||
try:
|
||||
conn = get_db_connection()
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
# 获取主键
|
||||
cur.execute("""
|
||||
SELECT a.attname AS column_name
|
||||
FROM pg_index i
|
||||
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
|
||||
WHERE i.indrelid = %s::regclass
|
||||
AND i.indisprimary
|
||||
""", (table_name,))
|
||||
pk_result = cur.fetchone()
|
||||
primary_key = pk_result['column_name'] if pk_result else ''
|
||||
|
||||
# 获取总行数
|
||||
cur.execute(f'SELECT COUNT(*) as count FROM "{table_name}"')
|
||||
total = cur.fetchone()['count']
|
||||
|
||||
# 分页查询
|
||||
offset = (page - 1) * page_size
|
||||
query = f'SELECT * FROM "{table_name}" ORDER BY "{primary_key}" LIMIT %s OFFSET %s'
|
||||
cur.execute(query, (page_size, offset))
|
||||
rows = cur.fetchall()
|
||||
|
||||
# 转换为普通字典
|
||||
result_rows = []
|
||||
for row in rows:
|
||||
result_rows.append(dict(row))
|
||||
|
||||
# 获取列名
|
||||
columns = list(result_rows[0].keys()) if result_rows else []
|
||||
|
||||
cur.close()
|
||||
release_db_connection(conn)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"rows": result_rows,
|
||||
"columns": columns,
|
||||
"total": total,
|
||||
"primary_key": primary_key,
|
||||
"page": page,
|
||||
"page_size": page_size
|
||||
}
|
||||
except Exception as e:
|
||||
return JSONResponse(content={"success": False, "message": str(e)}, status_code=500)
|
||||
|
||||
@app.get("/api/db/table/{table_name}/columns")
|
||||
def get_table_columns(table_name: str):
|
||||
"""
|
||||
获取指定表的列信息。
|
||||
"""
|
||||
try:
|
||||
conn = get_db_connection()
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
cur.execute("""
|
||||
SELECT
|
||||
column_name,
|
||||
data_type,
|
||||
is_nullable,
|
||||
column_default
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = %s
|
||||
AND table_schema = 'public'
|
||||
ORDER BY ordinal_position
|
||||
""", (table_name,))
|
||||
rows = cur.fetchall()
|
||||
|
||||
cur.close()
|
||||
release_db_connection(conn)
|
||||
|
||||
return {"success": True, "columns": rows}
|
||||
except Exception as e:
|
||||
return JSONResponse(content={"success": False, "message": str(e)}, status_code=500)
|
||||
|
||||
@app.post("/api/db/table/{table_name}/insert")
|
||||
async def insert_table_data(table_name: str, request: Request):
|
||||
"""
|
||||
向指定表插入数据。
|
||||
"""
|
||||
try:
|
||||
body = await request.json()
|
||||
data = body.get('data', {})
|
||||
|
||||
if not data:
|
||||
return JSONResponse(content={"success": False, "message": "没有数据"}, status_code=400)
|
||||
|
||||
conn = get_db_connection()
|
||||
cur = conn.cursor()
|
||||
|
||||
columns = list(data.keys())
|
||||
values = list(data.values())
|
||||
placeholders = ','.join(['%s'] * len(columns))
|
||||
column_names = ','.join([f'"{col}"' for col in columns])
|
||||
|
||||
query = f'INSERT INTO "{table_name}" ({column_names}) VALUES ({placeholders})'
|
||||
cur.execute(query, values)
|
||||
|
||||
conn.commit()
|
||||
cur.close()
|
||||
release_db_connection(conn)
|
||||
|
||||
return {"success": True, "message": "添加成功"}
|
||||
except Exception as e:
|
||||
return JSONResponse(content={"success": False, "message": str(e)}, status_code=500)
|
||||
|
||||
@app.put("/api/db/table/{table_name}/update")
|
||||
async def update_table_data(table_name: str, request: Request):
|
||||
"""
|
||||
更新指定表的数据。
|
||||
"""
|
||||
try:
|
||||
body = await request.json()
|
||||
data = body.get('data', {})
|
||||
record_id = body.get('id')
|
||||
|
||||
if not data or not record_id:
|
||||
return JSONResponse(content={"success": False, "message": "缺少参数"}, status_code=400)
|
||||
|
||||
conn = get_db_connection()
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
# 获取主键
|
||||
cur.execute("""
|
||||
SELECT a.attname AS column_name
|
||||
FROM pg_index i
|
||||
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
|
||||
WHERE i.indrelid = %s::regclass
|
||||
AND i.indisprimary
|
||||
""", (table_name,))
|
||||
pk_result = cur.fetchone()
|
||||
primary_key = pk_result['column_name'] if pk_result else None
|
||||
|
||||
if not primary_key:
|
||||
return JSONResponse(content={"success": False, "message": "表没有主键,无法更新"}, status_code=400)
|
||||
|
||||
# 构建更新语句
|
||||
set_clause = ','.join([f'"{col}" = %s' for col in data.keys()])
|
||||
values = list(data.values())
|
||||
values.append(record_id)
|
||||
|
||||
query = f'UPDATE "{table_name}" SET {set_clause} WHERE "{primary_key}" = %s'
|
||||
cur.execute(query, values)
|
||||
|
||||
conn.commit()
|
||||
cur.close()
|
||||
release_db_connection(conn)
|
||||
|
||||
return {"success": True, "message": "更新成功"}
|
||||
except Exception as e:
|
||||
return JSONResponse(content={"success": False, "message": str(e)}, status_code=500)
|
||||
|
||||
@app.delete("/api/db/table/{table_name}/delete")
|
||||
async def delete_table_data(table_name: str, request: Request):
|
||||
"""
|
||||
删除指定表的数据。
|
||||
"""
|
||||
try:
|
||||
body = await request.json()
|
||||
ids = body.get('ids', [])
|
||||
|
||||
if not ids:
|
||||
return JSONResponse(content={"success": False, "message": "没有要删除的记录"}, status_code=400)
|
||||
|
||||
conn = get_db_connection()
|
||||
cur = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
# 获取主键
|
||||
cur.execute("""
|
||||
SELECT a.attname AS column_name
|
||||
FROM pg_index i
|
||||
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
|
||||
WHERE i.indrelid = %s::regclass
|
||||
AND i.indisprimary
|
||||
""", (table_name,))
|
||||
pk_result = cur.fetchone()
|
||||
primary_key = pk_result['column_name'] if pk_result else None
|
||||
|
||||
if not primary_key:
|
||||
return JSONResponse(content={"success": False, "message": "表没有主键,无法删除"}, status_code=400)
|
||||
|
||||
# 删除 ids 中的记录
|
||||
placeholders = ','.join(['%s'] * len(ids))
|
||||
query = f'DELETE FROM "{table_name}" WHERE "{primary_key}" IN ({placeholders})'
|
||||
cur.execute(query, ids)
|
||||
|
||||
conn.commit()
|
||||
cur.close()
|
||||
release_db_connection(conn)
|
||||
|
||||
return {"success": True, "message": f"成功删除 {cur.rowcount} 条记录"}
|
||||
except Exception as e:
|
||||
return JSONResponse(content={"success": False, "message": str(e)}, status_code=500)
|
||||
|
||||
class TicketPaymentRequest(BaseModel):
|
||||
name: str
|
||||
phone: str
|
||||
|
||||
Reference in New Issue
Block a user