@@ -1,6 +1,6 @@
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="frontend/docs/src/public/logo.png" width="150" height="150" alt="logo" />
|
<img src="frontend/web/public/logo.png" width="150" height="150" alt="logo" />
|
||||||
</p>
|
</p>
|
||||||
<h1>FastApiAdmin <img src="https://img.shields.io/badge/Version-v2.0.0-blue" alt="Version"></h1>
|
<h1>FastApiAdmin <img src="https://img.shields.io/badge/Version-v2.0.0-blue" alt="Version"></h1>
|
||||||
<h3>Modern Full-Stack Rapid Development Platform</h3>
|
<h3>Modern Full-Stack Rapid Development Platform</h3>
|
||||||
@@ -191,16 +191,16 @@ With **Pydantic v2** and **PostgreSQL (asyncpg)**, ORM writes expect native Pyth
|
|||||||
|
|
||||||
| Module | Screenshot |
|
| Module | Screenshot |
|
||||||
|------------|---------------------------------|
|
|------------|---------------------------------|
|
||||||
| Login |  |
|
| Login |  |
|
||||||
| Dashboard |  |
|
| Dashboard |  |
|
||||||
| Generator |  |
|
| Generator |  |
|
||||||
| AI |  |
|
| AI |  |
|
||||||
|
|
||||||
### Mobile
|
### Mobile
|
||||||
|
|
||||||
| Login <div style="width:60px"/> | Home <div style="width:60px"/> | Profile <div style="width:60px"/> |
|
| Login <div style="width:60px"/> | Home <div style="width:60px"/> | Profile <div style="width:60px"/> |
|
||||||
|----------|----------|----------|
|
|----------|----------|----------|
|
||||||
|  |  |  |
|
|  |  |  |
|
||||||
|
|
||||||
## 🚀 Quick Start
|
## 🚀 Quick Start
|
||||||
|
|
||||||
@@ -652,7 +652,7 @@ Thanks to the contributions and support of the following open-source projects:
|
|||||||
|
|
||||||
| Group QR Code | WeChat Pay QR Code |
|
| Group QR Code | WeChat Pay QR Code |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
|  |  |
|
|  |  |
|
||||||
|
|
||||||
## ❤️ Support the Project
|
## ❤️ Support the Project
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="frontend/docs/src/public/logo.png" width="150" height="150" alt="logo" />
|
<img src="frontend/web/public/logo.png" width="150" height="150" alt="logo" />
|
||||||
</p>
|
</p>
|
||||||
<h1>FastApiAdmin <sup style="background-color: #28a745; color: white; padding: 2px 6px; border-radius: 3px; font-size: 0.4em; vertical-align: super; margin-left: 5px;">v2.0.0</h1>
|
<h1>FastApiAdmin <sup style="background-color: #28a745; color: white; padding: 2px 6px; border-radius: 3px; font-size: 0.4em; vertical-align: super; margin-left: 5px;">v2.0.0</h1>
|
||||||
<h3>现代化全栈快速开发平台</h3>
|
<h3>现代化全栈快速开发平台</h3>
|
||||||
@@ -193,16 +193,16 @@ flowchart LR
|
|||||||
|
|
||||||
| 模块名 <div style="width:60px"/> | 截图 |
|
| 模块名 <div style="width:60px"/> | 截图 |
|
||||||
| ----- | --- |
|
| ----- | --- |
|
||||||
| 登录 |  |
|
| 登录 |  |
|
||||||
| 仪表盘 |  |
|
| 仪表盘 |  |
|
||||||
| 代码生成 |  |
|
| 代码生成 |  |
|
||||||
| 智能助手 |  |
|
| 智能助手 |  |
|
||||||
|
|
||||||
### 移动端
|
### 移动端
|
||||||
|
|
||||||
| 登录 <div style="width:60px"/> | 首页 <div style="width:60px"/> | 个人中心 <div style="width:60px"/> |
|
| 登录 <div style="width:60px"/> | 首页 <div style="width:60px"/> | 个人中心 <div style="width:60px"/> |
|
||||||
|----------|----------|----------|
|
|----------|----------|----------|
|
||||||
|  |  |  |
|
|  |  |  |
|
||||||
|
|
||||||
## 🚀 快速开始
|
## 🚀 快速开始
|
||||||
|
|
||||||
@@ -613,7 +613,7 @@ A:使用 `./deploy.sh` 脚本一键部署到生产环境。
|
|||||||
|
|
||||||
| 群组二维码 | 微信支付二维码 |
|
| 群组二维码 | 微信支付二维码 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
|  |  |
|
|  |  |
|
||||||
|
|
||||||
## ❤️ 支持项目
|
## ❤️ 支持项目
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ echo.
|
|||||||
echo %BLUE%服务说明:%RESET%
|
echo %BLUE%服务说明:%RESET%
|
||||||
echo 🚀 后端服务 - FastAPI 后端 (端口: 8001)
|
echo 🚀 后端服务 - FastAPI 后端 (端口: 8001)
|
||||||
echo 🌐 前端 Web - Vue 前端 (端口: 5173)
|
echo 🌐 前端 Web - Vue 前端 (端口: 5173)
|
||||||
echo 📱 前端 App - UniApp 应用 (端口: 8080)
|
REM echo 📱 前端 App - UniApp 应用 (端口: 8080) [已禁用:不开源]
|
||||||
echo 📚 文档服务 - VitePress 文档 (端口: 5174)
|
REM echo 📚 文档服务 - VitePress 文档 (端口: 5174) [已禁用:不开源]
|
||||||
echo.
|
echo.
|
||||||
echo %BLUE%日志位置:%RESET%
|
echo %BLUE%日志位置:%RESET%
|
||||||
echo %LOG_DIR%\
|
echo %LOG_DIR%\
|
||||||
@@ -50,8 +50,8 @@ echo.
|
|||||||
|
|
||||||
call :start_service "backend" "%SCRIPT_DIR%backend" "uv run main.py run --env=dev" "FastapiAdmin.Backend" "%BACKEND_PID%"
|
call :start_service "backend" "%SCRIPT_DIR%backend" "uv run main.py run --env=dev" "FastapiAdmin.Backend" "%BACKEND_PID%"
|
||||||
call :start_service "frontend" "%SCRIPT_DIR%frontend\web" "pnpm dev" "FastapiAdmin.Web" "%WEB_PID%"
|
call :start_service "frontend" "%SCRIPT_DIR%frontend\web" "pnpm dev" "FastapiAdmin.Web" "%WEB_PID%"
|
||||||
call :start_service "app" "%SCRIPT_DIR%frontend\app" "pnpm dev:h5" "FastapiAdmin.App" "%APP_PID%"
|
REM call :start_service "app" "%SCRIPT_DIR%frontend\app" "pnpm dev:h5" "FastapiAdmin.App" "%APP_PID%"
|
||||||
call :start_service "docs" "%SCRIPT_DIR%frontend\docs" "pnpm dev" "FastapiAdmin.Docs" "%DOCS_PID%"
|
REM call :start_service "docs" "%SCRIPT_DIR%frontend\docs" "pnpm dev" "FastapiAdmin.Docs" "%DOCS_PID%"
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo %GREEN%🎉 所有服务启动完成!%RESET%
|
echo %GREEN%🎉 所有服务启动完成!%RESET%
|
||||||
@@ -59,8 +59,8 @@ echo.
|
|||||||
echo %BLUE%访问地址:%RESET%
|
echo %BLUE%访问地址:%RESET%
|
||||||
echo 🚀 后端 API: http://localhost:8001/api/v1/docs
|
echo 🚀 后端 API: http://localhost:8001/api/v1/docs
|
||||||
echo 🌐 前端 Web: http://localhost:5173
|
echo 🌐 前端 Web: http://localhost:5173
|
||||||
echo 📱 前端 App: http://localhost:8080
|
REM echo 📱 前端 App: http://localhost:8080 [已禁用]
|
||||||
echo 📚 文档服务: http://localhost:5174
|
REM echo 📚 文档服务: http://localhost:5174 [已禁用]
|
||||||
echo.
|
echo.
|
||||||
goto :end
|
goto :end
|
||||||
|
|
||||||
@@ -99,8 +99,8 @@ echo %CYAN%⏹️ 开始停止所有服务...%RESET%
|
|||||||
echo.
|
echo.
|
||||||
call :stop_service "backend"
|
call :stop_service "backend"
|
||||||
call :stop_service "frontend"
|
call :stop_service "frontend"
|
||||||
call :stop_service "app"
|
REM call :stop_service "app"
|
||||||
call :stop_service "docs"
|
REM call :stop_service "docs"
|
||||||
echo %GREEN%🎉 所有服务已停止!%RESET%
|
echo %GREEN%🎉 所有服务已停止!%RESET%
|
||||||
echo.
|
echo.
|
||||||
goto :end
|
goto :end
|
||||||
@@ -136,8 +136,8 @@ echo %CYAN%🔍 检查服务状态...%RESET%
|
|||||||
echo.
|
echo.
|
||||||
call :check_service "backend"
|
call :check_service "backend"
|
||||||
call :check_service "frontend"
|
call :check_service "frontend"
|
||||||
call :check_service "app"
|
REM call :check_service "app"
|
||||||
call :check_service "docs"
|
REM call :check_service "docs"
|
||||||
goto :end
|
goto :end
|
||||||
|
|
||||||
:check_service
|
:check_service
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ docker/
|
|||||||
│ │ └── server.key # SSL 私钥文件
|
│ │ └── server.key # SSL 私钥文件
|
||||||
│ │ └── server.pem # SSL 证书文件
|
│ │ └── server.pem # SSL 证书文件
|
||||||
│ ├── web/ # 前端静态文件(Web)
|
│ ├── web/ # 前端静态文件(Web)
|
||||||
│ ├── app/ # 前端静态文件(小程序 H5)
|
│ ├── app/ # 前端静态文件(小程序 H5)[已禁用:不开源]
|
||||||
│ └── docs/ # 前端静态文件(官网文档)
|
│ └── docs/ # 前端静态文件(官网文档)[已禁用:不开源]
|
||||||
├── mysql/ # MySQL 数据目录
|
├── mysql/ # MySQL 数据目录
|
||||||
│ └── data/ # MySQL 数据持久化目录
|
│ └── data/ # MySQL 数据持久化目录
|
||||||
├── redis/ # Redis 数据目录
|
├── redis/ # Redis 数据目录
|
||||||
@@ -147,12 +147,14 @@ docker compose up -d --no-deps --build [service_name]
|
|||||||
|
|
||||||
部署完成后,可以通过以下地址访问:
|
部署完成后,可以通过以下地址访问:
|
||||||
|
|
||||||
- **官网**: https://域名(或 ip)/docs
|
- **官网**: https://域名(或 ip)/docs [已禁用:不开源]
|
||||||
- **前端**: https://域名(或 ip)/web
|
- **前端**: https://域名(或 ip)/web
|
||||||
- **小程序**: https://域名(或 ip)/app
|
- **小程序**: https://域名(或 ip)/app [已禁用:不开源]
|
||||||
- **API 文档**: https://域名(或 ip)/api/v1/docs
|
- **API 文档**: https://域名(或 ip)/api/v1/docs
|
||||||
- **登录信息**: 账号 admin,密码 123456
|
- **登录信息**: 账号 admin,密码 123456
|
||||||
|
|
||||||
|
> **注意**: `docs` 和 `app` 已禁用开源部署,如需使用请取消相关配置注释。
|
||||||
|
|
||||||
## 日志管理
|
## 日志管理
|
||||||
|
|
||||||
### 查看容器日志
|
### 查看容器日志
|
||||||
|
|||||||
@@ -153,8 +153,8 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||||
- ./nginx/web:/usr/share/nginx/html/web:ro
|
- ./nginx/web:/usr/share/nginx/html/web:ro
|
||||||
- ./nginx/app:/usr/share/nginx/html/app:ro
|
# - ./nginx/app:/usr/share/nginx/html/app:ro
|
||||||
- ./nginx/docs:/usr/share/nginx/html/docs:ro
|
# - ./nginx/docs:/usr/share/nginx/html/docs:ro
|
||||||
- ./nginx/ssl:/etc/nginx/ssl:ro
|
- ./nginx/ssl:/etc/nginx/ssl:ro
|
||||||
depends_on:
|
depends_on:
|
||||||
backend:
|
backend:
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ http {
|
|||||||
ssl_session_timeout 10m;
|
ssl_session_timeout 10m;
|
||||||
|
|
||||||
# ==================== 官网(根路径) ====================
|
# ==================== 官网(根路径) ====================
|
||||||
|
# 已禁用:docs 不开源,如需使用请取消注释
|
||||||
location / {
|
location / {
|
||||||
root /usr/share/nginx/html/docs/dist;
|
root /usr/share/nginx/html/docs/dist;
|
||||||
index index.html index.htm;
|
index index.html index.htm;
|
||||||
@@ -104,6 +105,7 @@ http {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ==================== 小程序 H5(/app) ====================
|
# ==================== 小程序 H5(/app) ====================
|
||||||
|
# 已禁用:app 不开源,如需使用请取消注释
|
||||||
location /app {
|
location /app {
|
||||||
alias /usr/share/nginx/html/app/dist/build/h5;
|
alias /usr/share/nginx/html/app/dist/build/h5;
|
||||||
try_files $uri $uri/ /app/index.html; #解决页面刷新404问题
|
try_files $uri $uri/ /app/index.html; #解决页面刷新404问题
|
||||||
|
|||||||
|
After Width: | Height: | Size: 721 KiB |
|
After Width: | Height: | Size: 604 KiB |
|
After Width: | Height: | Size: 563 KiB |
|
After Width: | Height: | Size: 232 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 3.3 MiB |
|
After Width: | Height: | Size: 1013 KiB |
|
After Width: | Height: | Size: 248 KiB |
|
After Width: | Height: | Size: 948 KiB |
|
After Width: | Height: | Size: 752 KiB |
|
After Width: | Height: | Size: 3.0 MiB |
|
After Width: | Height: | Size: 131 KiB |
@@ -100,4 +100,10 @@ function handleCurrentChange(val: number) {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped>
|
||||||
|
.pagination {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 12px 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -97,24 +97,10 @@
|
|||||||
<!-- CardList 概览统计(含在线用户/UV/PV/访问量等) -->
|
<!-- CardList 概览统计(含在线用户/UV/PV/访问量等) -->
|
||||||
<CardList />
|
<CardList />
|
||||||
|
|
||||||
<!-- 日程日历 + 我的收藏 -->
|
<!-- 关于项目 + 我的收藏 -->
|
||||||
<ElRow :gutter="16">
|
<ElRow :gutter="16">
|
||||||
<ElCol :xs="24" :span="12" class="flex flex-col">
|
<ElCol :xs="24" :span="12" class="flex flex-col">
|
||||||
<ElCard shadow="hover" class="workplace-surface workplace-ops-card flex flex-col h-full">
|
<AboutProject />
|
||||||
<template #header>
|
|
||||||
<div class="workplace-section-card__head">
|
|
||||||
<div>
|
|
||||||
<span class="workplace-panel-title">日程日历</span>
|
|
||||||
<p class="workplace-section-sub workplace-section-sub--inline">
|
|
||||||
点击日期添加或编辑(本地演示)
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div class="workplace-ops-card__body">
|
|
||||||
<FaCalendar />
|
|
||||||
</div>
|
|
||||||
</ElCard>
|
|
||||||
</ElCol>
|
</ElCol>
|
||||||
<ElCol :xs="24" :span="12" class="flex flex-col">
|
<ElCol :xs="24" :span="12" class="flex flex-col">
|
||||||
<ElCard shadow="hover" class="flex flex-col h-full">
|
<ElCard shadow="hover" class="flex flex-col h-full">
|
||||||
@@ -152,51 +138,60 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div v-if="quickLinks.length > 0">
|
<ElRow v-if="quickLinks.length > 0" :gutter="12">
|
||||||
<ElTooltip
|
<ElCol
|
||||||
v-for="(item, index) in quickLinks"
|
v-for="(item, index) in quickLinks"
|
||||||
:key="item.id || `${item.href}-${index}`"
|
:key="item.id || `${item.href}-${index}`"
|
||||||
placement="top"
|
:xs="24"
|
||||||
:show-after="400"
|
:sm="12"
|
||||||
:content="item.title"
|
:md="8"
|
||||||
|
:lg="8"
|
||||||
|
:xl="8"
|
||||||
|
class="mb-3"
|
||||||
>
|
>
|
||||||
<div
|
<ElTooltip
|
||||||
class="workplace-quick-row workplace-quick-row--compact workplace-quick-row--chip"
|
placement="top"
|
||||||
role="button"
|
:show-after="400"
|
||||||
tabindex="0"
|
:content="item.title"
|
||||||
@click="handleQuickLinkClick(item)"
|
|
||||||
@keydown.enter.prevent="handleQuickLinkClick(item)"
|
|
||||||
@keydown.space.prevent="handleQuickLinkClick(item)"
|
|
||||||
>
|
>
|
||||||
<span
|
|
||||||
class="workplace-quick-row__accent"
|
|
||||||
:style="{ backgroundColor: getQuickLinkColor(getQuickLinkStableIndex(item)) }"
|
|
||||||
/>
|
|
||||||
<div
|
<div
|
||||||
class="workplace-quick-row__icon"
|
class="workplace-quick-row workplace-quick-row--compact workplace-quick-row--chip"
|
||||||
:style="{ color: getQuickLinkColor(getQuickLinkStableIndex(item)) }"
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
@click="handleQuickLinkClick(item)"
|
||||||
|
@keydown.enter.prevent="handleQuickLinkClick(item)"
|
||||||
|
@keydown.space.prevent="handleQuickLinkClick(item)"
|
||||||
>
|
>
|
||||||
<FaMenuRouteIcon :icon="item.icon || 'menu'" />
|
<span
|
||||||
</div>
|
class="workplace-quick-row__accent"
|
||||||
<div class="workplace-quick-row__text">
|
:style="{ backgroundColor: getQuickLinkColor(getQuickLinkStableIndex(item)) }"
|
||||||
<span class="workplace-quick-row__title">{{ item.title }}</span>
|
/>
|
||||||
</div>
|
<div
|
||||||
<div class="workplace-quick-row__actions">
|
class="workplace-quick-row__icon"
|
||||||
<button
|
:style="{ color: getQuickLinkColor(getQuickLinkStableIndex(item)) }"
|
||||||
type="button"
|
|
||||||
class="workplace-quick-row__remove"
|
|
||||||
:disabled="!item.id && !item.href"
|
|
||||||
:title="item.id || item.href ? '移除收藏' : '无法移除(缺少路径)'"
|
|
||||||
:aria-label="`移除收藏 ${item.title}`"
|
|
||||||
@click.stop="handleDeleteLink(item)"
|
|
||||||
>
|
>
|
||||||
<ElIcon><Close /></ElIcon>
|
<FaMenuRouteIcon :icon="item.icon || 'menu'" />
|
||||||
</button>
|
</div>
|
||||||
|
<div class="workplace-quick-row__text">
|
||||||
|
<span class="workplace-quick-row__title">{{ item.title }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="workplace-quick-row__actions">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="workplace-quick-row__remove"
|
||||||
|
:disabled="!item.id && !item.href"
|
||||||
|
:title="item.id || item.href ? '移除收藏' : '无法移除(缺少路径)'"
|
||||||
|
:aria-label="`移除收藏 ${item.title}`"
|
||||||
|
@click.stop="handleDeleteLink(item)"
|
||||||
|
>
|
||||||
|
<ElIcon><Close /></ElIcon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</ElTooltip>
|
||||||
</ElTooltip>
|
</ElCol>
|
||||||
</div>
|
</ElRow>
|
||||||
<ElEmpty v-else :image-size="48">
|
<ElEmpty v-else :image-size="100">
|
||||||
<template #description>
|
<template #description>
|
||||||
<p class="workplace-quick-empty__title">暂无收藏</p>
|
<p class="workplace-quick-empty__title">暂无收藏</p>
|
||||||
<p class="workplace-quick-empty__hint">
|
<p class="workplace-quick-empty__hint">
|
||||||
@@ -210,8 +205,25 @@
|
|||||||
</ElCol>
|
</ElCol>
|
||||||
</ElRow>
|
</ElRow>
|
||||||
|
|
||||||
<!-- 最新动态 + 关于项目 -->
|
<!-- 日程日历 + 最新动态 -->
|
||||||
<ElRow :gutter="16">
|
<ElRow :gutter="16">
|
||||||
|
<ElCol :span="12" class="flex flex-col">
|
||||||
|
<ElCard shadow="hover" class="workplace-surface workplace-ops-card flex flex-col h-full">
|
||||||
|
<template #header>
|
||||||
|
<div class="workplace-section-card__head">
|
||||||
|
<div>
|
||||||
|
<span class="workplace-panel-title">日程日历</span>
|
||||||
|
<p class="workplace-section-sub workplace-section-sub--inline">
|
||||||
|
点击日期添加或编辑(本地演示)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="workplace-ops-card__body">
|
||||||
|
<FaCalendar />
|
||||||
|
</div>
|
||||||
|
</ElCard>
|
||||||
|
</ElCol>
|
||||||
<ElCol :span="12" class="flex flex-col">
|
<ElCol :span="12" class="flex flex-col">
|
||||||
<ElCard shadow="hover" class="h-full flex flex-col">
|
<ElCard shadow="hover" class="h-full flex flex-col">
|
||||||
<template #header>
|
<template #header>
|
||||||
@@ -228,7 +240,7 @@
|
|||||||
</ElLink>
|
</ElLink>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<ElScrollbar height="300px">
|
<ElScrollbar class="h-full">
|
||||||
<ElTimeline class="p-2">
|
<ElTimeline class="p-2">
|
||||||
<ElTimelineItem
|
<ElTimelineItem
|
||||||
v-for="(item, index) in vesionList"
|
v-for="(item, index) in vesionList"
|
||||||
@@ -263,9 +275,6 @@
|
|||||||
</ElScrollbar>
|
</ElScrollbar>
|
||||||
</ElCard>
|
</ElCard>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
<ElCol :span="12" class="flex flex-col">
|
|
||||||
<AboutProject />
|
|
||||||
</ElCol>
|
|
||||||
</ElRow>
|
</ElRow>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, nextTick, watch } from "vue";
|
import { ref, nextTick, watch } from "vue";
|
||||||
import WelcomeScreen from "./FaWelcomeScreen.vue";
|
import WelcomeScreen from "./FaWelcomeScreen.vue";
|
||||||
|
import FaMessageItem from "./FaMessageItem.vue";
|
||||||
import type { ChatMessage } from "../types";
|
import type { ChatMessage } from "../types";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|||||||
@@ -55,6 +55,10 @@ import { ElMessage, ElMessageBox } from "element-plus";
|
|||||||
import AiChatAPI, { ChatSession } from "@/api/module_ai/chat";
|
import AiChatAPI, { ChatSession } from "@/api/module_ai/chat";
|
||||||
import { Auth } from "@utils/auth";
|
import { Auth } from "@utils/auth";
|
||||||
import type { ChatMessage, UploadedFile } from "./types";
|
import type { ChatMessage, UploadedFile } from "./types";
|
||||||
|
import FaSidebar from "./components/FaSidebar.vue";
|
||||||
|
import FaChatNavbar from "./components/FaChatNavbar.vue";
|
||||||
|
import FaChatMessages from "./components/FaChatMessages.vue";
|
||||||
|
import FaChatInput from "./components/FaChatInput.vue";
|
||||||
|
|
||||||
// 状态
|
// 状态
|
||||||
const messages = ref<ChatMessage[]>([]);
|
const messages = ref<ChatMessage[]>([]);
|
||||||
|
|||||||
@@ -125,7 +125,7 @@
|
|||||||
:items="memoryDialogFormItems"
|
:items="memoryDialogFormItems"
|
||||||
:rules="rules"
|
:rules="rules"
|
||||||
label-suffix=":"
|
label-suffix=":"
|
||||||
:label-width="'auto'"
|
:label-width="'70px'"
|
||||||
label-position="right"
|
label-position="right"
|
||||||
:span="24"
|
:span="24"
|
||||||
:gutter="16"
|
:gutter="16"
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
</ElButton>
|
</ElButton>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElForm>
|
</ElForm>
|
||||||
<ElRow>
|
<div>
|
||||||
<ElTable
|
<ElTable
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
:data="data"
|
:data="data"
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
:total="total"
|
:total="total"
|
||||||
@pagination="emit('fetch')"
|
@pagination="emit('fetch')"
|
||||||
/>
|
/>
|
||||||
</ElRow>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<ElButton type="primary" :loading="confirmLoading" @click="emit('confirm')">确 定</ElButton>
|
<ElButton type="primary" :loading="confirmLoading" @click="emit('confirm')">确 定</ElButton>
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ import type { FormItem } from "@/components/forms/fa-form/index.vue";
|
|||||||
import FaSearchBar from "@/components/forms/fa-search-bar/index.vue";
|
import FaSearchBar from "@/components/forms/fa-search-bar/index.vue";
|
||||||
import FaForm from "@/components/forms/fa-form/index.vue";
|
import FaForm from "@/components/forms/fa-form/index.vue";
|
||||||
import { ElTag, ElMessage } from "element-plus";
|
import { ElTag, ElMessage } from "element-plus";
|
||||||
|
import FaPermissonDrawer from "./components/FaPermissonDrawer.vue";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "Role",
|
name: "Role",
|
||||||
|
|||||||
@@ -238,6 +238,7 @@ import type { FormItem } from "@/components/forms/fa-form/index.vue";
|
|||||||
import type { IContentConfig, IObject } from "@/components/modal/types";
|
import type { IContentConfig, IObject } from "@/components/modal/types";
|
||||||
import FaSearchBar from "@/components/forms/fa-search-bar/index.vue";
|
import FaSearchBar from "@/components/forms/fa-search-bar/index.vue";
|
||||||
import FaForm from "@/components/forms/fa-form/index.vue";
|
import FaForm from "@/components/forms/fa-form/index.vue";
|
||||||
|
import FaDeptTree from "./components/FaDeptTree.vue";
|
||||||
import { ElTag, ElMessage, ElMessageBox } from "element-plus";
|
import { ElTag, ElMessage, ElMessageBox } from "element-plus";
|
||||||
|
|
||||||
const { hasAuth } = useAuth();
|
const { hasAuth } = useAuth();
|
||||||
|
|||||||
@@ -206,6 +206,8 @@ import WorkflowDefinitionAPI, {
|
|||||||
type WorkflowForm,
|
type WorkflowForm,
|
||||||
} from "@/api/module_task/workflow/definition";
|
} from "@/api/module_task/workflow/definition";
|
||||||
import WorkflowNodeTypeAPI from "@/api/module_task/workflow/node-type";
|
import WorkflowNodeTypeAPI from "@/api/module_task/workflow/node-type";
|
||||||
|
import FaNodeConfigPanel from "./FaNodeConfigPanel.vue";
|
||||||
|
import FaEdgeConfigPanel from "./FaEdgeConfigPanel.vue";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "WorkflowCreateDrawer",
|
name: "WorkflowCreateDrawer",
|
||||||
@@ -965,9 +967,16 @@ function deleteEdge(edgeId: string, getEdges: () => Edge[], setEdges: (edges: Ed
|
|||||||
.canvas-container {
|
.canvas-container {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 400px;
|
min-height: 400px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.canvas-container :deep(.vue-flow) {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.vue-flow__controls) {
|
:deep(.vue-flow__controls) {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ import type { SearchFormItem } from "@/components/forms/fa-search-bar/index.vue"
|
|||||||
import FaTable from "@/components/tables/fa-table/index.vue";
|
import FaTable from "@/components/tables/fa-table/index.vue";
|
||||||
import FaTableHeader from "@/components/tables/fa-table-header/index.vue";
|
import FaTableHeader from "@/components/tables/fa-table-header/index.vue";
|
||||||
import FaTableHeaderLeft from "@/components/tables/fa-table-header-left/index.vue";
|
import FaTableHeaderLeft from "@/components/tables/fa-table-header-left/index.vue";
|
||||||
|
import FaWorkflowDesignDrawer from "../components/FaWorkflowDesignDrawer.vue";
|
||||||
import { useTable } from "@/hooks/core/useTable";
|
import { useTable } from "@/hooks/core/useTable";
|
||||||
import type { ColumnOption } from "@/types/component";
|
import type { ColumnOption } from "@/types/component";
|
||||||
import { ArrowDown } from "@element-plus/icons-vue";
|
import { ArrowDown } from "@element-plus/icons-vue";
|
||||||
|
|||||||