diff --git a/.gitignore b/.gitignore index 55f3464..9699423 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ data.db image.jpg __pycache__/ -demo.__pycache__ \ No newline at end of file +demo.__pycache__ +uploads \ No newline at end of file diff --git a/README.md b/README.md index e72c452..185eafe 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,36 @@ ## 小北学生线上签到平台 -**让你免除必须到指定地点签到的烦恼(未完成),本代码采用 [MIT License](LICENSE) , 仅供学习交流** +**让你免除必须到指定地点签到的烦恼,本代码采用 [MIT License](LICENSE) , 仅供学习交流** #### 已有功能 - 登录 - 获取个人信息 - 获取签到信息 +- 上传图片签到 -## 📜 License +### 界面 + +- 登录界面 + +  + +- 个人界面 + +  + +- 首页 + +  + +- 签到列表 + +  + +- 签到页 + +  + +### 📜 License This project is licensed under the [MIT License](LICENSE). diff --git a/images/image.png b/images/image.png new file mode 100644 index 0000000..9d65587 Binary files /dev/null and b/images/image.png differ diff --git a/images/image2.png b/images/image2.png new file mode 100644 index 0000000..db25255 Binary files /dev/null and b/images/image2.png differ diff --git a/images/image3.png b/images/image3.png new file mode 100644 index 0000000..5995949 Binary files /dev/null and b/images/image3.png differ diff --git a/images/image4.png b/images/image4.png new file mode 100644 index 0000000..fe59bdf Binary files /dev/null and b/images/image4.png differ diff --git a/images/image5.png b/images/image5.png new file mode 100644 index 0000000..f237849 Binary files /dev/null and b/images/image5.png differ diff --git a/routers/auth.py b/routers/auth.py index a9cc68d..6be6f01 100644 --- a/routers/auth.py +++ b/routers/auth.py @@ -1,3 +1,4 @@ +from datetime import datetime from fastapi import APIRouter, Request, Response from fastapi.responses import JSONResponse, RedirectResponse from models import User @@ -13,7 +14,13 @@ async def index(request: Request): token = request.cookies.get("xbxs_token") if token: return RedirectResponse("/home") - return templates.TemplateResponse("login.html", {"request": request}) + return templates.TemplateResponse( + "login.html", + { + "request": request, + "year": datetime.now().year, + }, + ) @router.post("/login") diff --git a/routers/home.py b/routers/home.py index d5f9252..ae8f36d 100644 --- a/routers/home.py +++ b/routers/home.py @@ -1,6 +1,19 @@ from datetime import datetime -from fastapi import APIRouter, Depends, HTTPException, Request, status -from fastapi.responses import HTMLResponse +import json +import os +from typing import List +from uuid import uuid4 +from fastapi import ( + APIRouter, + Depends, + File, + Form, + HTTPException, + Request, + UploadFile, + status, +) +from fastapi.responses import HTMLResponse, RedirectResponse from starlette.templating import Jinja2Templates from services.services import XBXS @@ -88,7 +101,6 @@ async def sign_detail( know_detail = await xbxs.get_know(str(knowing_id)) data = know_detail.get("data", {}) - # 获取具体的数据 knowing_name = data.get("knowingName", "未知签到") start_date = data.get("startDate", "未知") @@ -98,12 +110,14 @@ async def sign_detail( send_role = data.get("sendRole", "未知") is_check = data.get("isCheck", 0) is_picture = data.get("isPicture", 0) - is_finish_know = data.get("isFinishKnowing", 0) + # is_finish_know = data.get("isFinishKnowing", 0) + locations = json.loads(data.get("location", [])) return templates.TemplateResponse( "sign_detail.html", { "request": request, + "know_id": knowing_id, "knowing_name": knowing_name, "start_date": start_date, "start_time": start_time, @@ -112,6 +126,33 @@ async def sign_detail( "send_role": send_role, "is_check": is_check, "is_picture": is_picture, - "is_finish_know": is_finish_know, + "locations": locations, + # "is_finish_know": is_finish_know, }, ) + + +# 完善的 sign 完成接口 +@router.post("/sign/{know_id}/complete") +async def complete_sign( + know_id: int, + request: Request, + location: str = Form(...), # 获取经纬度,必填 + address: str = Form(...), # 获取经纬度,必填 + remark: str = Form(...), # 获取备注,必填 + images: List[UploadFile] = File(...), # 获取上传的图片,支持多张 + xbxs: XBXS = Depends(get_xbxs), +): + # 备注必填,未填写时返回错误 + if not remark: + raise HTTPException(status_code=400, detail="备注是必填项") + + print(location, remark, know_id, images, address) + + try: + await xbxs.update_student_know(str(know_id), remark, address, location, images) + except Exception as e: + raise HTTPException(status_code=500, detail="保存签到数据失败") + + # 成功后跳转到签到列表 + return RedirectResponse(url="/sign", status_code=status.HTTP_303_SEE_OTHER) diff --git a/services/services.py b/services/services.py index 8fd39bc..f0597a8 100644 --- a/services/services.py +++ b/services/services.py @@ -1,5 +1,7 @@ import base64 +from typing import List from uuid import uuid4 +from fastapi import UploadFile import httpx import config from services.student_cache import get_student_by_token, save_student @@ -136,25 +138,35 @@ class XBXS: pass return result - async def update_student_know(self, knowingID: str): - files = { - "file0": ( - str(uuid4()), - open("./image.jpg", "rb"), - "image/jpeg", + async def update_student_know( + self, + knowingID: str, + remark: str, + address: str, + location: str, + images: List[UploadFile], + ): + files = {} + for i, image in enumerate(images): + # 为每个图片生成一个唯一的 UUID 文件名 + files[f"file{i}"] = ( + str(uuid4()), # 这里使用 UUID 作为文件名 + await image.read(), + "image/jpeg", # 假设是 jpeg 格式,按需修改 ) - } - resp = await self.client.post( - "/xiaobei-api/student/know/updateStudentKnow", - data={ - "address": "1388号", - "remark": "无", - "knowingId": knowingID, - "location": "106.5346788194445:29.343291015625", - "size": "1", - }, - ) - resp.raise_for_status() + # resp = await self.client.post( + # "/xiaobei-api/student/know/updateStudentKnow", + # data={ + # "address": address, + # "remark": remark, + # "knowingId": knowingID, + # "location": location, + # # "location": "106.5346788194445:29.343291015625", + # "size": len(images), + # }, + # files=files, + # ) + # resp.raise_for_status() async def get_student_info_cached(self): cached = get_student_by_token(str(self.token)) diff --git a/templates/auth.html b/templates/auth.html new file mode 100644 index 0000000..f15aa32 --- /dev/null +++ b/templates/auth.html @@ -0,0 +1,23 @@ + + + +
+ +