From c4366eeab10e7678446b1e0249a92bafad0fe12b Mon Sep 17 00:00:00 2001 From: Fantasy lee <129943055+Fantasylee21@users.noreply.github.com> Date: Sun, 25 May 2025 15:58:17 +0800 Subject: [PATCH 1/5] =?UTF-8?q?[feat]:=20=E5=AE=9E=E7=8E=B0=E5=9B=BE?= =?UTF-8?q?=E5=BA=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/v1/endpoints/auth.py | 48 ++++++++++++++++++++++++++++++++++-- app/main.py | 3 ++- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/app/api/v1/endpoints/auth.py b/app/api/v1/endpoints/auth.py index 52c779d..29a795d 100644 --- a/app/api/v1/endpoints/auth.py +++ b/app/api/v1/endpoints/auth.py @@ -1,4 +1,4 @@ -from fastapi import APIRouter, HTTPException, Depends +from fastapi import APIRouter, HTTPException, Depends, UploadFile from sqlalchemy.ext.asyncio import AsyncSession from passlib.context import CryptContext from datetime import datetime, timedelta @@ -17,6 +17,10 @@ from app.utils.get_db import get_db from app.utils.redis import get_redis_client from app.curd.note import find_recent_notes_in_db +from fastapi import File, UploadFile +from fastapi.responses import FileResponse +import os +from uuid import uuid4 router = APIRouter() @@ -159,4 +163,44 @@ async def get_recent_notes(db: AsyncSession = Depends(get_db)): notes = await find_recent_notes_in_db(db) return { "notes": notes - } \ No newline at end of file + } + +# 上传图片接口 +@router.post("/image/upload", response_model=dict) +async def upload_image(image: UploadFile = File(...)): + """ + 上传图片接口 + """ + try: + # 生成唯一文件名 + file_extension = os.path.splitext(image.filename)[1] + unique_filename = f"{uuid4()}{file_extension}" + image_path = os.path.join("/lhcos-data/images", unique_filename) + + # 确保以二进制模式写入文件,避免编码问题 + with open(image_path, "wb") as f: + f.write(await image.read()) + + # # 生成 URL 路径 + image_url = f"/images/{unique_filename}" + + return {"image_url": image_url} + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + + +@router.get("/image/{imgname}", response_model=dict) +async def get_image(imgname: str): + """ + 获取图片接口 + """ + try: + image_path = os.path.join("/lhcos-data/images", imgname) + if not os.path.exists(image_path): + raise HTTPException(status_code=404, detail="Image not found") + return FileResponse( + path=image_path, + media_type="image/png" # 根据实际图片类型修改或动态设置 + ) + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) \ No newline at end of file diff --git a/app/main.py b/app/main.py index e4e1c3c..df2a5a3 100644 --- a/app/main.py +++ b/app/main.py @@ -41,4 +41,5 @@ async def log_requests(request: Request, call_next): ) # 挂载静态文件目录 -app.mount("/static", StaticFiles(directory="app/static"), name="static") \ No newline at end of file +app.mount("/static", StaticFiles(directory="app/static"), name="static") +app.mount("/images", StaticFiles(directory="/lhcos-data/images"), name="images") \ No newline at end of file From 6fea4fc500a5a06afb7d02858dc0bc3bf7088b3e Mon Sep 17 00:00:00 2001 From: Fantasy lee <129943055+Fantasylee21@users.noreply.github.com> Date: Sun, 25 May 2025 16:09:54 +0800 Subject: [PATCH 2/5] =?UTF-8?q?[feat]:=20=E6=9B=B4=E6=96=B0=E5=A4=B4?= =?UTF-8?q?=E5=83=8F=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/curd/user.py | 2 +- app/main.py | 2 +- requirements.txt | Bin 2112 -> 1691 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/curd/user.py b/app/curd/user.py index 6545c34..67b0673 100644 --- a/app/curd/user.py +++ b/app/curd/user.py @@ -9,7 +9,7 @@ async def get_user_by_email(db: AsyncSession, email: str): return result.scalar_one_or_none() async def create_user(db: AsyncSession, email: str, username: str, hashed_password: str): - new_user = User(email=email, username=username, password=hashed_password, avatar="/static/avatar/default.png") + new_user = User(email=email, username=username, password=hashed_password, avatar="/lhcos-data/avatar/default.png") db.add(new_user) await db.commit() await db.refresh(new_user) diff --git a/app/main.py b/app/main.py index df2a5a3..bd2079f 100644 --- a/app/main.py +++ b/app/main.py @@ -41,5 +41,5 @@ async def log_requests(request: Request, call_next): ) # 挂载静态文件目录 -app.mount("/static", StaticFiles(directory="app/static"), name="static") +app.mount("/avatar", StaticFiles(directory="/lhcos-data/avatar"), name="avatar") app.mount("/images", StaticFiles(directory="/lhcos-data/images"), name="images") \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 4e6397855868750eeaf9f08f06488e8c4d8cacb9..52cdfb819870e1d46eb86c2ed20b6667d1963880 100644 GIT binary patch literal 1691 zcmah~O^@3+487~WSg>R#nK}4S6zE~G1GL)(7Ci-uEjwytNtNWxIKO@$WzY0jz!#F@ z*W)9tj8Ah8)?B)-j)WXd^@ zCwi#z8Z@5O{6x{*YCMI0CLv`X$@0Vngw^#`Hna9i?z#h_?#g+kHwiPCa*6vOjp7}G={g6sJ@eEfzD`U@hR5)xAB_h^r1Zpav8zcnMNV;pPpeEzW zREm)h8qGF1f`0TaXYVa$(eeXnrl_^E8hAG7Sg@-Q#q$W;HRrI6U7)q6BEOMU(y+|n zP$;}=W@a^MnyKUs1vSp}-i>A=4Sd;8lL=vJ5yC67VI+uQ)nh$duZGRqGCL1oo#02{ zYW=jtg}hF@VfJmdM2QBL7j-LmHUR8J#oH3Ts}by^2}tI2e)aK&N@=2ympNcs1YOH~ z&`uQ|oItN4_V)_a=4dX}`(!|b((>{B!5<9ORja}3RB-+6nk#KwT4t(*MiEqhqX7{v zls%{cUcLu3MC}jFrr-LZS8h;c$p9~;l*(!fz|yiXjIzMLQyb5Xwf+^NDC`S%nI^O^ zc*z)j_LpVsx+8B0tgx!&%E((xIIN(52s8~EP|br+`AF(O`%>zZmX6uk54bC45Wwj4_0gVvOHi% z7c{r1vBN|@TIZ;LEvUQ5^9Ek3w2S~DQuLSy7&bgerjdFtFb|R0ZxP%bcTeJLY0FiM8>3-s%BT5B!2i?<8 zfPf{yH^W)K;i#qU=TJ^ETppM%a_*Qf(SpVeRZ4!#9Va7}Fb&DC#x?Sc6OHII>L4=L F?0+S|`ltW^ literal 2112 zcmZ8iOK;j>5ZrU6{uEG*Ns}CU=(TF3R;kn@BF4M|hT5hH`SERMcD}U@LT)Jgnw_0p z|NA?)jUBA9y|s3<9sc)hpYfU6*lzs!Xdi42O9`K6*bBF3uw{0Oe1%*bqagNzldtR2-J2DS#a3YC~+gSsXBPWVn=)?}_M)eYZ0VxrE(?Kkf6 zj6Ag?Q9L`#JqK|Y$X$DtB`Ps~g6tEo!XEQfr?4eH@=)*WMHmX_t*{r5zxUtAcJI{- zAm8Ds!OI>`AS8-U$s^DmY~_AOTc=*8-5kX70tgzQtrKrV((|?eXAKxX!($DPD)lqu zeSzOOpUVDpSeW6#v6SFrfgC-~%=4>HDu8;~*$mOt#0K7+H~SNJ)C1>3ZkMnT?HriI zoaQFoWJx)fUL*LY1MRCe~s^1*JYNtl%++)5#17b z={}5O4b5#0J3ZdI_z5gAarRAo>{&I{F;R0vh?#0xxrfvktZeZ+Cm_aHv7g}9USVTa zqETkzrGi%2fErIIi2BQ&=SLuUfyXdT^Q5JQ?SxLA@O_zj6^pUE73_O>Xn%;7&(w1t z@H^GQxkvuHw1Y&(X;Jwxv*=h`8XlGFM0X(a3p?W*eEQ47&e@yl^Cq3p`zoQMb(s6? z@zr3?+$_zI9TkqSMulKp^|ep*pn@x~9+!=F>L%E^_L*I%hTi#LQs0sBtNpT{&X#gX zx#WV@M?6pV!@hNVvX(ZCwWtkl4cVsRIICNqg{<1_QQEu`>=65|t0y&$(KqjUn|AR! z_VNk{K`8Xnck6kyBgCRNgC^Twnh_Lq0t#Z`OnFm7sqCLuwU2pEXyejq8r(!(I7aH- z63lRd+Beo`k7BGrJ?*G^=-)7n@1m~u Date: Sun, 25 May 2025 16:14:58 +0800 Subject: [PATCH 3/5] =?UTF-8?q?[docs]:=20=E6=9B=B4=E6=96=B0requirements.tx?= =?UTF-8?q?t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 52cdfb8..ccc5d03 100644 --- a/requirements.txt +++ b/requirements.txt @@ -27,7 +27,7 @@ fastapi-pagination==0.13.0 fire==0.7.0 fonttools==4.57.0 greenlet==3.1.1 -h11==0.16.0 +h11==0.14.0 httpcore==1.0.8 httpx==0.28.1 idna==3.10 @@ -85,7 +85,7 @@ six==1.17.0 sniffio==1.3.1 soupsieve==2.7 SQLAlchemy==2.0.40 -starlette==0.46.1 +starlette==0.46.2 stringzilla==3.12.5 termcolor==3.0.1 tifffile==2025.3.30 @@ -94,5 +94,5 @@ typing-inspection==0.4.0 typing_extensions==4.13.1 tzdata==2025.2 urllib3==2.4.0 -uvicorn==0.34.0 +uvicorn==0.34.2 win32_setctime==1.2.0 From da39a51ddd5a1768a69e04c0edc275affd3f27e7 Mon Sep 17 00:00:00 2001 From: Fantasy lee <129943055+Fantasylee21@users.noreply.github.com> Date: Sun, 25 May 2025 16:24:34 +0800 Subject: [PATCH 4/5] =?UTF-8?q?[fix]:=20=E4=BF=AE=E8=A1=A5=E5=AD=98?= =?UTF-8?q?=E5=82=A8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/main.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/main.py b/app/main.py index bd2079f..137c0c0 100644 --- a/app/main.py +++ b/app/main.py @@ -4,6 +4,7 @@ from loguru import logger from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles +import os app = FastAPI() @@ -41,5 +42,8 @@ async def log_requests(request: Request, call_next): ) # 挂载静态文件目录 +os.makedirs("/lhcos-data/avatar", exist_ok=True) +os.makedirs("/lhcos-data/images", exist_ok=True) + app.mount("/avatar", StaticFiles(directory="/lhcos-data/avatar"), name="avatar") app.mount("/images", StaticFiles(directory="/lhcos-data/images"), name="images") \ No newline at end of file From bb0d212192b6e7483e366e81d9b3df1967ed37e2 Mon Sep 17 00:00:00 2001 From: Fantasy lee <129943055+Fantasylee21@users.noreply.github.com> Date: Sun, 25 May 2025 16:39:51 +0800 Subject: [PATCH 5/5] =?UTF-8?q?[fix]:=20=E4=BF=AE=E8=A1=A5=E5=AD=98?= =?UTF-8?q?=E5=82=A8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/main.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/app/main.py b/app/main.py index 137c0c0..ae95cc1 100644 --- a/app/main.py +++ b/app/main.py @@ -41,9 +41,23 @@ async def log_requests(request: Request, call_next): allow_headers=["*"], # 允许的请求头 ) +from pathlib import Path +is_github_actions = os.environ.get("GITHUB_ACTIONS") == "true" + +if is_github_actions: + # GitHub Actions 环境 - 使用项目内临时目录 + BASE_DIR = Path(__file__).resolve().parent.parent + AVATAR_DIR = os.path.join(BASE_DIR, "static", "avatar") + IMAGES_DIR = os.path.join(BASE_DIR, "static", "images") +else: + # 生产环境 - 使用实际云存储目录 + AVATAR_DIR = "/lhcos-data/avatar" + IMAGES_DIR = "/lhcos-data/images" + +# 确保目录存在 +os.makedirs(AVATAR_DIR, exist_ok=True) +os.makedirs(IMAGES_DIR, exist_ok=True) + # 挂载静态文件目录 -os.makedirs("/lhcos-data/avatar", exist_ok=True) -os.makedirs("/lhcos-data/images", exist_ok=True) - -app.mount("/avatar", StaticFiles(directory="/lhcos-data/avatar"), name="avatar") -app.mount("/images", StaticFiles(directory="/lhcos-data/images"), name="images") \ No newline at end of file +app.mount("/avatar", StaticFiles(directory=AVATAR_DIR), name="avatar") +app.mount("/images", StaticFiles(directory=IMAGES_DIR), name="images") \ No newline at end of file