Skip to content

qiyangvc/aigame

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

151 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

环境配置

默认采用 conda 进行 Pyhton 虚拟环境管理,请提前配好 conda 环境

  1. 创建 Python 虚拟环境
conda create -n aigame python=3.12
conda activate aigame

如果是在 windows 上使用 conda,可能会遇到 conda activate 无效问题,请查看此链接解决

  1. 下载 Python 依赖
git clone https://github.com/SYSUMSC/aigame.git
cd aigame

pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip install -r requirements.txt
  1. 运行
cd app
python main.py

接着在本地浏览器打开 localhost:8000/admin 路径,开发默认账号是 admin,密码是 123456

后台API文档地址localhost:8000/docs

赛题模板

点此处跳转至赛题模板文档

路径说明

|-app #fastapi后台
|---admin #admin后台,采用layuiadmin框架开发
|-----static
|-------adminui
|---------dist
|-----------css
|-----------modules
|-------layui
|---------css
|---------font
|-------modules
|---------layim
|-----------res
|-------------html
|-------------images
|-------------skin
|-------------voice
|-------style
|---------imgs
|-----------template
|-----templates
|-----router.py
|---api #api,采用fastapi+sqlmodel
|-----admin
|-------auth.py
|-------competition.py
|-------problem.py
|-------router.py
|-------team.py
|-------user.py
|-----user
|-------auth.py
|-------info.py
|-------router.py
|-------team.py
|-----deps.py
|-----exception_handler.py
|-----response_model.py
|---core #定义一些辅助函数
|-----__init__.py
|-----config.py
|-----security.py
|-----utils.py
|---db #定义数据库连接器
|-----session.py
|---middleware #定义鉴权工具
|-----auth_middleware.py
|---schemas #定义数据库模型和api模型
|-----__init__.py
|-----competition.py
|-----config.py
|-----problem.py
|-----team.py
|-----user.py
|---main.py #启动文件

数据库字段变更迁移说明

如果增加了新的model 需要在alembic\env.py引入

# 导入所有的模型
from app.schemas.user import User

在项目根路径执行,生成当前的版本

python -m alembic revision --autogenerate -m "说明"

将alembic的版本更新到schema的最新版

python -m alembic upgrade head

开发说明

前台前端开发说明

采用ts+vue3+pinia+tailwind+bootstrap5+pnpm

初始化环境

cd frontend
pnpm i

运行则输入pnpm dev

后台前端开发说明

采用layuiadmin,layui官网:开始使用 - Layui 文档

对于一个数据模型, 主要包含增删改查,

  • 增改,通过table页面点添加或者编辑,打开form页面

  • 删查,在table页面进行,支持单个删除,整体删除,查询

推荐使用vscode aide插件,复制app/admin,app/schema给ai,就可以快速让ai写出来增删改查页面

导航

template/index.html修改具体url

table页面

user.html为例子

创建在template,大概只需要改title和header要查询的字段,然后extra_js改具体url,比如队伍就是team的;以及修改table.render的col字段,定义显示什么

{% extends 'table_base.html' %}
{% block title %}
  用户管理
{% endblock %}

{% block header %}
  {{ search_field('用户名', 'username', '请输入用户名') }}
  {{ search_field('邮箱', 'email', '请输入邮箱') }}
  {{ search_field('学号', 'student_id', '请输入学号') }}
{% endblock %}

{% block extra_js %}
  <script>
    layui
      .config({
        base: '/admin/static/' // 静态资源所在路径
      })
      .use(['index', 'table', 'laytpl', 'admin'], function () {
        //省略
  </script>
{% endblock %}

router.py定义路由

@admin_router.get("/admin/user")
async def user(request: Request):
    return templates.TemplateResponse("user.html", {"request": request})

form页面

user_form.html为例子

创建在template

{% extends 'form_base.html' %}
{% block title %}
  用户管理-表单
{% endblock %}
{% block content %}
    {% from 'form_macros.html' import input_field, select_field %}
    {{ input_field('用户名', 'username', '请输入用户名', required=True) }}
    {{ input_field('姓名', 'name', '请输入姓名', required=True) }}
    {{ input_field('邮箱', 'email', '请输入邮箱', 'email', required=True) }}
    {{ select_field('状态', 'status', [{'value': 'active', 'label': '激活'}, {'value': 'inactive', 'label': '未激活'}], required=True) }}
{% endblock %}

根据form_macros定义的宏,类似调用函数来构建表单,减少重复代码

router.py定义路由

async def user_form(request: Request):
    return templates.TemplateResponse("user_form.html", {"request": request})

后端API开发说明

/app/api 定义了 adminuser 的后端API,通过 router.py 结合不同的路由

鉴权通过中间件 app\middleware\auth_middleware.py 要求请求header或者json body包含access_token 目前比较混乱

前台API开发说明

数据结构定义在 app\schemas,通过SQLModel封装,无需手动写sql

传递参数方式

json body

后端

(其实更好的做法应该类似后台那样先定义接收模型,而不是用await request.json()接收,这里偷懒了)

@team_router.post("/create_team", response_model=ResponseModel, tags=["User"])
async def create_team(request: Request, current_user: str = Depends(get_current_user), session: AsyncSession = Depends(get_session)):
    try:
        body = await request.json()
        name = body.get("name")

前端

const res = await axios.post("/api/user/create_team", {
  name: newTeamName.value,
});

前端负载为json

form参数

后端

async def join_team(invite_code: str = Form(...), current_user: str = Depends(get_current_user), session: AsyncSession = Depends(get_session)):

前端

常规应该是提取form的内容,然而这里没有实际的form所以要先创建form对象

const formData = new FormData();
formData.append("invite_code", inviteCode.value);
const res = await axios.post("/api/user/join_team", formData, {
  headers: {
    "Content-Type": "multipart/form-data",
  },
});

负载会显示表单数据 alt text

get参数

早期join_team如下

invite_code 没有指定Form类型,所以是get参数

async def join_team(invite_code: str, current_user: str = Depends(get_current_user), session: AsyncSession = Depends(get_session)):

url中?后面的都是get参数

const res = await axios.post(`/api/user/join_team?invite_code=${encodeURIComponent(inviteCode.value)}`)

后台API开发说明

数据结构定义在 app\schemas,通过SQLModel封装,无需手动写sql

主要是对数据表的增删改查, 比如user.py就是对app\schemas\user.py的增删改查

数据传输通过POST json

app\schemas\user.py 定义的 UserSchema 用于 增加,修改 需要传递的参数

app\schemas\user.py 定义的 UserSearchSchema 用于 搜索(查找) 需要传递的参数

一个提交post json的例子,主要是设置contentTypedata记得JSON.stringify

$.ajax({
  url: "/api/admin/",
  method: "POST",
  contentType: "application/json;charset=UTF-8",
  data: JSON.stringify({ ids: ids }),
  success: function (res) {
  },
});

格式化 import

python -m isort .

美化jinja html

d:\ProgramData\miniconda3\envs\newaigame\python.exe -m pip install -U djlint --target D:\ProgramData\miniconda3\envs\newaigame\Lib\site-packages

fastcrud文档:https://igorbenav.github.io/fastcrud/

SQLModel文档:https://sqlmodel.fastapi.org.cn/

接口说明,返回json,有字段code 0正常,1异常,msg中文消息,data=数据(可能没有),count数据总长度,是分页前的总长度(可能没有)

错误返回的http码仍是200,只是code变为1,msg为异常原因,禁止使用返回接口raise HTTPException(status_code=404, detail="错误")

后台对于一个表,通常有的操作有

  • 新增,修改(传入id),根据ModelSchema字段进行添加

  • 删除(传入id),批量删除(传入ids,,分割)

  • 查询 post参数根据ModelSearchSchema的字段进行查询,如果是int则=匹配,如果是str则like % %匹配 get参数为page,limit

  • 使用json body传参(后台layuiadmin需要修改)

                      contentType: "application/json;charset=UTF-8",
                      data: JSON.stringify(field),
    

vscode拓展

admin相关

  • Jinja2 Snippet Kit
  • Better Jinja
  • djlint

About

web项目

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors