|
@@ -1,7 +1,7 @@
|
|
|
#!/usr/bin/env python3
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
-from fastapi import APIRouter, Request, Depends, Query, HTTPException, status,WebSocket,WebSocketDisconnect
|
|
|
+from fastapi import APIRouter, Request, Depends, Query, HTTPException, status,WebSocket,WebSocketDisconnect,UploadFile,File
|
|
|
from common.security import valid_access_token,valid_websocket_token
|
|
|
from fastapi.responses import JSONResponse,StreamingResponse
|
|
|
from common.db import db_czrz
|
|
@@ -21,6 +21,9 @@ from utils.resource_provision_util import *
|
|
|
from common.websocketManager import *
|
|
|
import json
|
|
|
import traceback
|
|
|
+import pandas as pd
|
|
|
+from io import BytesIO
|
|
|
+import openpyxl
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
@@ -41,6 +44,7 @@ def get_data_field(table_id: int, db: Session = Depends(get_db)):
|
|
|
AND COLUMN_NAME NOT IN :ignore_fields order by ORDINAL_POSITION
|
|
|
""")
|
|
|
columns_result = db.execute(columns_query, {
|
|
|
+ "layer_name": info.layer_name,
|
|
|
"schema_name": info.database_name,
|
|
|
"table_name": info.table_name,
|
|
|
"ignore_fields": tuple(ignore_fields_list)
|
|
@@ -106,7 +110,7 @@ async def get_data_list(table_id: int,page: int = Query(1, gt=0, description='
|
|
|
schema_name = table_structure["schema_name"]
|
|
|
columns = [col["column_name"] for col in table_structure["columns"]]
|
|
|
|
|
|
- sql = f"SELECT {', '.join(columns)} FROM `{schema_name}`.`{table_name}` where del_flag='0'"
|
|
|
+ sql = f"SELECT {', '.join(columns)} FROM `{schema_name}`.`{table_name}` where del_flag='0' order by update_time desc"
|
|
|
totalsql = f'select count(*) from ({sql})t'
|
|
|
|
|
|
total = db.execute(text(totalsql)).fetchone()[0]
|
|
@@ -210,7 +214,90 @@ async def delete_data(table_id: int, data_id: int, db: Session = Depends(get_db)
|
|
|
traceback.print_exc()
|
|
|
return JSONResponse(status_code=500, content={'code': 500, 'msg': f"接口发生错误:{e}"})
|
|
|
|
|
|
-def get_data_info():
|
|
|
- pass
|
|
|
-def insert_data():
|
|
|
- pass
|
|
|
+
|
|
|
+@router.get("/generate_import_template/{table_id}")
|
|
|
+async def generate_import_template(table_id: int, db: Session = Depends(get_db)):
|
|
|
+ # 获取表结构
|
|
|
+ table_structure = get_data_field(table_id, db)
|
|
|
+ columns = table_structure["columns"]
|
|
|
+ layer_name = table_structure["layer_name"]
|
|
|
+
|
|
|
+ # 创建 DataFrame column_name
|
|
|
+ data = {}
|
|
|
+ for col in columns :
|
|
|
+ data[col["column_comment"]]=col['column_name']
|
|
|
+ column_names = [col["column_comment"] for col in columns]
|
|
|
+ df = pd.DataFrame(data=[data],columns=column_names)
|
|
|
+
|
|
|
+ # 将 DataFrame 转换为 Excel 文件
|
|
|
+ output = BytesIO()
|
|
|
+ with pd.ExcelWriter(output, engine="openpyxl") as writer:
|
|
|
+ df.to_excel(writer, index=False, sheet_name=layer_name)
|
|
|
+ encoded_filename = f'{layer_name}导入模板.xlsx'
|
|
|
+ # 设置响应头
|
|
|
+ output.seek(0)
|
|
|
+ from urllib.parse import quote
|
|
|
+ encoded_filename = quote(encoded_filename, encoding='utf-8')
|
|
|
+ headers = {
|
|
|
+ 'Content-Disposition': f'attachment; filename*=UTF-8\'\'{encoded_filename}',
|
|
|
+ 'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
|
|
+ }
|
|
|
+
|
|
|
+ return StreamingResponse(output, headers=headers,
|
|
|
+ media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
|
|
+
|
|
|
+
|
|
|
+# 数据批量导入
|
|
|
+@router.post("/import_data/{table_id}")
|
|
|
+async def import_data(table_id: int, file: UploadFile = File(...), db: Session = Depends(get_db)):
|
|
|
+ # 获取表结构
|
|
|
+ table_structure = get_data_field(table_id, db)
|
|
|
+ table_name = table_structure["table_name"]
|
|
|
+ schema_name = table_structure["schema_name"]
|
|
|
+ columns = table_structure["columns"]
|
|
|
+
|
|
|
+ # 读取 Excel 文件
|
|
|
+ try:
|
|
|
+ workbook = openpyxl.load_workbook(file.file)
|
|
|
+ sheet = workbook.active
|
|
|
+ except Exception as e:
|
|
|
+ traceback.print_exc()
|
|
|
+ return JSONResponse(status_code=400, content={'code': 400, 'msg': f"接口发生错误:{e}"})
|
|
|
+ # raise HTTPException(status_code=400, detail="Invalid Excel file")
|
|
|
+
|
|
|
+ # 获取字段名和字段备注名
|
|
|
+ column_names = [col["column_name"] for col in columns]
|
|
|
+ column_comments = [col["column_comment"] for col in columns]
|
|
|
+
|
|
|
+ # 检查第一行是否为字段备注名
|
|
|
+ first_row = [cell.value for cell in sheet[1]]
|
|
|
+ if first_row != column_comments:
|
|
|
+ print("接口发生错误:Excel columns do not match the expected columns")
|
|
|
+
|
|
|
+ return JSONResponse(status_code=400, content={'code': 400, 'msg': f"接口发生错误:Excel columns do not match the expected columns"})
|
|
|
+ # raise HTTPException(status_code=400, detail="Excel columns do not match the expected columns")
|
|
|
+
|
|
|
+ # 检查第二行是否为字段名
|
|
|
+ second_row = [cell.value for cell in sheet[2]]
|
|
|
+ if second_row != column_names:
|
|
|
+ print("接口发生错误:Excel columns do not match the expected columns")
|
|
|
+ return JSONResponse(status_code=400,
|
|
|
+ content={'code': 400, 'msg': f"接口发生错误:Excel columns do not match the expected columns"})
|
|
|
+
|
|
|
+ # raise HTTPException(status_code=400, detail="Excel columns do not match the expected columns")
|
|
|
+
|
|
|
+ # 将数据插入到数据库
|
|
|
+ try:
|
|
|
+ insert_query = text(
|
|
|
+ f"INSERT INTO `{schema_name}`.`{table_name}` ({', '.join(column_names)}) VALUES ({', '.join([':' + col for col in column_names])})")
|
|
|
+ for row in sheet.iter_rows(min_row=3, values_only=True):
|
|
|
+ db.execute(insert_query, dict(zip(column_names, row)))
|
|
|
+ db.commit()
|
|
|
+ return {"message": "Data imported successfully"}
|
|
|
+ except Exception as e:
|
|
|
+ db.rollback()
|
|
|
+ traceback.print_exc()
|
|
|
+ return JSONResponse(status_code=500,
|
|
|
+ content={'code': 500, 'msg': f"接口发生错误:{e}"})
|
|
|
+
|
|
|
+ # raise HTTPException(status_code=500, detail=str(e))
|