| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
前后端分离项目实现的一个后端管理框架
个人学习项目,只会对明显的 bug 进行修复,不会进行过多新功能的更新
常用分支说明:
项目根目录提供了 .env.example 文件作为环境变量的模板。
开发环境: 复制 .env.example 为 .env.dev,根据需要修改变量(通常默认值即可用于本地开发)。
cp .env.example .env.dev生产环境: 复制 .env.example 为 .env.prod,并修改相关配置(如 NODE_ENV, SECRET_KEY, 数据库密码等)。
cp .env.example .env.prod注意:.env 和 .env.* (除了 .env.example) 已被加入 .gitignore,请勿提交包含敏感信息的配置文件。
开发环境使用 docker compose --env-file .env.dev up -d
构建生产镜像
修改.env.prod 中打包镜像版本信息
BACKEND_IMAGE=fastapi-admin/backend-prod:2.1.0 FRONTEND_IMAGE=fastapi-admin/frontend-prod:2.1.0
打包生成生产镜像
docker compose -f docker-compose-build.yml --env-file .env.prod build --no-cache
手动导出与导入镜像
#导出镜像 docker save -o <输出文件名.tar> <镜像名:标签> #导入镜像 docker load -i <镜像文件.tar>
参考项目目录下的 `nginx/dev.conf` 文件。
npm run build
参考项目目录下的 `nginx/prod.conf` 文件。
./service.sh {dev|pro} {start|stop|restart}
后端需要修改对应配置文件信息
开发模式下,uvicorn 服务能自动刷新,rpyc 服务无法自动刷新,需要手动重启
项目使用 Alembic 进行数据库版本管理和迁移,支持容器化环境。
当 Docker Compose 服务已启动时,使用 exec 命令:
# 查看当前迁移状态
docker-compose --env-file .env.dev exec backend_api alembic current
# 查看迁移历史
docker-compose --env-file .env.dev exec backend_api alembic history
# 生成新的迁移文件(自动检测模型变更)
docker-compose --env-file .env.dev exec backend_api alembic revision --autogenerate -m "迁移描述信息"
# 执行迁移到最新版本
docker-compose --env-file .env.dev exec backend_api alembic upgrade head
# 回滚到指定版本
docker-compose --env-file .env.dev exec backend_api alembic downgrade <revision_id>
# 回滚一个版本
docker-compose --env-file .env.dev exec backend_api alembic downgrade -1当 Docker Compose 服务未启动时,使用 run 命令:
# 生成新的迁移文件(自动检测模型变更)
docker compose -f .\docker-compose.yml --env-file .env.dev run backend_api alembic revision --autogenerate -m "迁移描述信息"
# 执行迁移到最新版本
docker compose -f .\docker-compose.yml --env-file .env.dev run backend_api alembic upgrade head
# 查看当前迁移状态
docker compose -f .\docker-compose.yml --env-file .env.dev run backend_api alembic current
# 查看迁移历史
docker compose -f .\docker-compose.yml --env-file .env.dev run backend_api alembic history注意: 使用 run 命令时必须指定 --env-file .env.dev 参数,否则环境变量无法正确加载。
# 进入后端目录
cd backend/app
# 查看当前迁移状态
alembic current
# 生成新的迁移文件
alembic revision --autogenerate -m "迁移描述信息"
# 执行迁移
alembic upgrade head<!-- 导入分页相关方法 -->
import usePagination from '@/composables/usePagination'
<!--定义一个搜索字段-->
const searchForm = {
name: null,
email: null,
enable: null
}
<!-- 传入查询相关字段信息 -->
const {
search,
tableData,
currentPage,
pageSize,
orderModel,
total,
freshCurrentPage,
handleSearch
} = usePagination('/api/users/search', searchForm)定义了一个分页模型
from typing import Optional, Generic, TypeVar
from pydantic import BaseModel
T = TypeVar('T')
class Pagination(BaseModel, Generic[T]):
search: T
page: Optional[int] = 1
page_size: Optional[int] = 10
model: Optional[str] = 'asc'使用
@router.post('/dict/item/search', summary="字典列表查询", response_model=ApiResponse[SearchResponse[DictRead]])
async def search_items(search: Pagination[DictItemSearch], session: Session = Depends(get_session)):
# 需要定义一个filter_type,用于区分各个字段的匹配形式,可用为:l_like、r_like、like、eq、ne、lt、le、gt、ge
filter_type = DictItemSearchFilter(dict_id='eq', label='like', enable='eq', value='like')
total = crud.internal.dict_item.search_total(session, search.search, filter_type.model_dump())
items: List[DictRead] = crud.internal.dict_item.search(session, search, filter_type.model_dump())
# 转义下数据类型,不然在执行return的时候,会去获取外键、关联字段相关的内容,容易造成数据量过多等问题
item_list = [DictRead.from_orm(item) for item in items]
return ApiResponse(
data={
'total': total,
'data': item_list
}
)通过 casbin 实现简化的权限管控功能,思路如下:
v-permission 定义了权限标识,当拥有权限时,可以页面上能显示按钮,同时,后端也会进行权限的判断。
方式一:使用指令 (推荐简单按钮使用)
<el-button
v-permission="'role:update'"
type="primary"
size="small"
@click="handleEdit(scope.row)"
>
编辑
</el-button>方式二:使用全局函数 (推荐复杂逻辑或组件使用) 全局挂载了 $hasPermi (或 $hasPermission) 方法,可在 v-if 或 JS 中使用。
<el-button
v-if="$hasPermi('role:update')"
type="primary"
size="small"
@click="handleEdit(scope.row)"
>
编辑
</el-button>
<!-- 支持多个权限满足其一 -->
<el-button v-if="$hasPermi(['role:update', 'role:admin'])" ...>
管理
</el-button>@router.put('/roles', summary="更新角色", response_model=ApiResponse[Role],
dependencies=[Depends(Authority('role:update'))])
async def update_roles(role_info: RoleUpdate, session: Session = Depends(get_session)):
print(role_info)
if role_info.name == 'admin':
ApiResponse(code=status.HTTP_400_BAD_REQUEST, message='admin权限组无法更新信息')
db_obj = crud.internal.role.get(session, role_info.id)
enable_menus = role_info.menus
delattr(role_info, 'menus')
db_obj = crud.internal.role.update(session, db_obj, role_info)
crud.internal.role.update_menus(session, db_obj, enable_menus)
return ApiResponse(
data=db_obj
)| Back | FazBrowse Home | New Git URL |