commit 12c200b31c9a9155ba1ae54712ba1f9515fd42a7 Author: shuQAQshu Date: Sat Dec 27 17:18:53 2025 +0800 Initial commit diff --git a/app/__pycache__/main.cpython-310.pyc b/app/__pycache__/main.cpython-310.pyc new file mode 100644 index 0000000..1602bf8 Binary files /dev/null and b/app/__pycache__/main.cpython-310.pyc differ diff --git a/app/__pycache__/settings.cpython-310.pyc b/app/__pycache__/settings.cpython-310.pyc new file mode 100644 index 0000000..c2d3035 Binary files /dev/null and b/app/__pycache__/settings.cpython-310.pyc differ diff --git a/app/api/__pycache__/db.cpython-310.pyc b/app/api/__pycache__/db.cpython-310.pyc new file mode 100644 index 0000000..fb2a887 Binary files /dev/null and b/app/api/__pycache__/db.cpython-310.pyc differ diff --git a/app/api/__pycache__/login.cpython-310.pyc b/app/api/__pycache__/login.cpython-310.pyc new file mode 100644 index 0000000..42dedd8 Binary files /dev/null and b/app/api/__pycache__/login.cpython-310.pyc differ diff --git a/app/api/__pycache__/submit_record.cpython-310.pyc b/app/api/__pycache__/submit_record.cpython-310.pyc new file mode 100644 index 0000000..3fb1784 Binary files /dev/null and b/app/api/__pycache__/submit_record.cpython-310.pyc differ diff --git a/app/api/db.py b/app/api/db.py new file mode 100644 index 0000000..bfd5a36 --- /dev/null +++ b/app/api/db.py @@ -0,0 +1,24 @@ +from sqlalchemy import create_engine, MetaData +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +from app.settings import DATABASE_URL + +# 创建SQLAlchemy引擎 +engine = create_engine(DATABASE_URL) + +# 创建元数据对象 +metadata = MetaData() + +# 创建会话工厂 +SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) + +# 创建基类 +Base = declarative_base() + +# 依赖项:获取数据库会话 +def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close() \ No newline at end of file diff --git a/app/api/login.py b/app/api/login.py new file mode 100644 index 0000000..7712232 --- /dev/null +++ b/app/api/login.py @@ -0,0 +1,31 @@ +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from sqlalchemy import text +from app.api.db import get_db +from pydantic import BaseModel +from app.settings import WHITELIST_TABLE, WHITELIST_COLUMN + +router = APIRouter() + +# 请求模型 +class EmailRequest(BaseModel): + email: str + +# 检查邮箱是否在白名单中 +@router.post("/check-email") +async def check_email_in_whitelist(request: EmailRequest, db: Session = Depends(get_db)): + try: + # 构建查询语句 + query = text(f"SELECT COUNT(*) FROM {WHITELIST_TABLE} WHERE {WHITELIST_COLUMN} = :email") + + # 执行查询 + result = db.execute(query, {"email": request.email}) + count = result.scalar() + + if count > 0: + return {"status": "success", "message": "继续操作"} + else: + raise HTTPException(status_code=403, detail="邮箱不在白名单中,请联系管理员") + + except Exception as e: + raise HTTPException(status_code=500, detail=f"服务器错误:{str(e)}") \ No newline at end of file diff --git a/app/api/submit_record.py b/app/api/submit_record.py new file mode 100644 index 0000000..962042e --- /dev/null +++ b/app/api/submit_record.py @@ -0,0 +1,43 @@ +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from sqlalchemy import text +from app.api.db import get_db +from pydantic import BaseModel +from app.settings import SUBMIT_RECORD_TABLE +from datetime import datetime +import pytz + +router = APIRouter() + +class SubmitRecordRequest(BaseModel): + user_email: str + operation_type: str + storage_path: str + +@router.post("/submit-record") +async def submit_record(request: SubmitRecordRequest, db: Session = Depends(get_db)): + try: + if request.operation_type not in ['upload', 'delete']: + raise HTTPException(status_code=400, detail="操作类型必须是 'upload' 或 'delete'") + + china_tz = pytz.timezone('Asia/Shanghai') + operation_time = datetime.now(china_tz) + + query = text(f""" + INSERT INTO {SUBMIT_RECORD_TABLE} (user_email, operation_time, operation_type, storage_path) + VALUES (:user_email, :operation_time, :operation_type, :storage_path) + """) + + db.execute(query, { + "user_email": request.user_email, + "operation_time": operation_time, + "operation_type": request.operation_type, + "storage_path": request.storage_path + }) + db.commit() + + return {"status": "success", "message": "操作记录已保存"} + + except Exception as e: + db.rollback() + raise HTTPException(status_code=500, detail=f"服务器错误:{str(e)}") \ No newline at end of file diff --git a/app/base_packages.txt b/app/base_packages.txt new file mode 100644 index 0000000..4a1d7e1 --- /dev/null +++ b/app/base_packages.txt @@ -0,0 +1,7 @@ +name: backend_env +channels: + - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ + - defaults +dependencies: + - python=3.10 +prefix: D:\anaconda3\envs\backend_env diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..1d19149 --- /dev/null +++ b/app/main.py @@ -0,0 +1,28 @@ +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware +from app.api.login import router as login_router +from app.api.submit_record import router as submit_record_router +from app.api.db import Base, engine +from app.settings import API_V1_STR + +# 创建数据库表 +Base.metadata.create_all(bind=engine) + +app = FastAPI( + title="PBMDB API", + description="微生物数据库后端API", + version="1.0.0" +) + +# 配置CORS +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], # 在生产环境中应该设置具体的前端域名 + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +# 包含路由 +app.include_router(login_router, prefix=API_V1_STR, tags=["login"]) +app.include_router(submit_record_router, prefix=API_V1_STR, tags=["submit_record"]) diff --git a/app/requirements.txt b/app/requirements.txt new file mode 100644 index 0000000..5063652 --- /dev/null +++ b/app/requirements.txt @@ -0,0 +1,28 @@ +annotated-doc==0.0.4 +annotated-types==0.7.0 +anyio==4.12.0 +async-timeout==5.0.1 +asyncpg==0.31.0 +click==8.3.1 +colorama==0.4.6 +databases==0.9.0 +exceptiongroup==1.3.1 +fastapi==0.125.0 +greenlet==3.3.0 +h11==0.16.0 +httptools==0.7.1 +idna==3.11 +psycopg2==2.9.11 +psycopg2-binary==2.9.11 +pydantic==2.12.5 +pydantic_core==2.41.5 +python-dotenv==1.2.1 +pytz==2025.2 +PyYAML==6.0.3 +SQLAlchemy==2.0.45 +starlette==0.50.0 +typing-inspection==0.4.2 +typing_extensions==4.15.0 +uvicorn==0.38.0 +watchfiles==1.1.1 +websockets==15.0.1 diff --git a/app/settings.py b/app/settings.py new file mode 100644 index 0000000..6cbcec1 --- /dev/null +++ b/app/settings.py @@ -0,0 +1,12 @@ +# 数据库配置 +DATABASE_URL = 'postgresql://ABM_DB_user:4FynWQfy0AEotP1dgyimrGF7PSDJh1nDYnDwg4hN@122.205.95.244:5433/ABM_DB' + +# API配置 +API_V1_STR = "/api/v1" + +# 白名单验证相关配置 +WHITELIST_TABLE = "submit_user" +WHITELIST_COLUMN = "user_email" + +# 操作记录相关配置 +SUBMIT_RECORD_TABLE = "submit_record" \ No newline at end of file diff --git a/environment.yml b/environment.yml new file mode 100644 index 0000000..9b7e6a2 --- /dev/null +++ b/environment.yml @@ -0,0 +1,49 @@ +name: backend_env +channels: + - defaults + - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ +dependencies: + - bzip2=1.0.8=h2bbff1b_6 + - ca-certificates=2025.12.2=haa95532_0 + - expat=2.7.3=h885b0b7_4 + - libexpat=2.7.3=h885b0b7_4 + - libffi=3.4.4=hd77b12b_1 + - libzlib=1.3.1=h02ab6af_0 + - openssl=3.0.18=h543e019_0 + - pip=25.3=pyhc872135_0 + - python=3.10.19=h981015d_0 + - setuptools=80.9.0=py310haa95532_0 + - sqlite=3.51.0=hda9a48d_0 + - tk=8.6.15=hf199647_0 + - tzdata=2025b=h04d1e81_0 + - ucrt=10.0.22621.0=haa95532_0 + - vc=14.3=h2df5915_10 + - vc14_runtime=14.44.35208=h4927774_10 + - vs2015_runtime=14.44.35208=ha6b5a95_10 + - wheel=0.45.1=py310haa95532_0 + - xz=5.6.4=h4754444_1 + - zlib=1.3.1=h02ab6af_0 + - pip: + - annotated-doc==0.0.4 + - annotated-types==0.7.0 + - anyio==4.12.0 + - click==8.3.1 + - colorama==0.4.6 + - exceptiongroup==1.3.1 + - fastapi==0.125.0 + - greenlet==3.3.0 + - h11==0.16.0 + - httptools==0.7.1 + - idna==3.11 + - pydantic==2.12.5 + - pydantic-core==2.41.5 + - python-dotenv==1.2.1 + - pyyaml==6.0.3 + - sqlalchemy==2.0.45 + - starlette==0.50.0 + - typing-extensions==4.15.0 + - typing-inspection==0.4.2 + - uvicorn==0.38.0 + - watchfiles==1.1.1 + - websockets==15.0.1 +prefix: D:\anaconda3\envs\backend_env diff --git a/start_server.py b/start_server.py new file mode 100644 index 0000000..e35dd69 --- /dev/null +++ b/start_server.py @@ -0,0 +1,9 @@ +import uvicorn + +if __name__ == "__main__": + uvicorn.run( + "app.main:app", + host="0.0.0.0", + port=8000, + reload=True + ) \ No newline at end of file