refactor: 前端架构重构 - 提取 CSS 和逻辑到独立模块
前端重构: - 删除旧的大体积 Vue 组件(HomeView, FileManage, TextSplit 等) - 删除旧的 composables(useFormatters, useModels, useProjects) - 新增 core/, page-logic/, pages/, shared/ 模块化目录结构 - 提取 CSS 到 styles/pages/ 目录 - 添加全局样式 variables.css 和 common.css 后端 API 更新: - chunks: 语义分割 API 增强 - files: 文件处理 API 更新 - models: 模型管理 API 更新 - questions: 问答管理 API 更新 - database: 数据库连接优化 - semantic_embedding: 语义嵌入服务优化 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
6
frontend/src/shared/composables/index.ts
Normal file
6
frontend/src/shared/composables/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Composables - 可复用业务逻辑
|
||||
*/
|
||||
export * from './useFormatters'
|
||||
export * from './useProjects'
|
||||
export * from './useModels'
|
||||
71
frontend/src/shared/composables/useFormatters.ts
Normal file
71
frontend/src/shared/composables/useFormatters.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* 格式化工具函数
|
||||
*/
|
||||
|
||||
/**
|
||||
* 格式化文件大小
|
||||
*/
|
||||
export function formatSize(bytes: number): string {
|
||||
if (bytes === 0) return '0 B'
|
||||
const k = 1024
|
||||
const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化日期
|
||||
*/
|
||||
export function formatDate(date: string | Date): string {
|
||||
const d = new Date(date)
|
||||
const year = d.getFullYear()
|
||||
const month = String(d.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(d.getDate()).padStart(2, '0')
|
||||
return `${year}-${month}-${day}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化日期时间
|
||||
*/
|
||||
export function formatDateTime(date: string | Date): string {
|
||||
const d = new Date(date)
|
||||
const year = d.getFullYear()
|
||||
const month = String(d.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(d.getDate()).padStart(2, '0')
|
||||
const hours = String(d.getHours()).padStart(2, '0')
|
||||
const minutes = String(d.getMinutes()).padStart(2, '0')
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化相对时间
|
||||
*/
|
||||
export function formatRelativeTime(date: string | Date): string {
|
||||
const now = new Date()
|
||||
const d = new Date(date)
|
||||
const diff = now.getTime() - d.getTime()
|
||||
|
||||
const seconds = Math.floor(diff / 1000)
|
||||
const minutes = Math.floor(seconds / 60)
|
||||
const hours = Math.floor(minutes / 60)
|
||||
const days = Math.floor(hours / 24)
|
||||
|
||||
if (days > 7) {
|
||||
return formatDate(date)
|
||||
} else if (days > 0) {
|
||||
return `${days} 天前`
|
||||
} else if (hours > 0) {
|
||||
return `${hours} 小时前`
|
||||
} else if (minutes > 0) {
|
||||
return `${minutes} 分钟前`
|
||||
} else {
|
||||
return '刚刚'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化数字(千分位)
|
||||
*/
|
||||
export function formatNumber(num: number): string {
|
||||
return num.toLocaleString('zh-CN')
|
||||
}
|
||||
112
frontend/src/shared/composables/useModels.ts
Normal file
112
frontend/src/shared/composables/useModels.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* 模型相关业务逻辑
|
||||
*/
|
||||
import { ref } from 'vue'
|
||||
import { modelApi } from '@/core/api'
|
||||
import type { Model } from '@/shared/types'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
export function useModels() {
|
||||
const loading = ref(false)
|
||||
const models = ref<Model[]>([])
|
||||
|
||||
/**
|
||||
* 获取模型列表
|
||||
*/
|
||||
const fetchModels = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await modelApi.list()
|
||||
// 处理两种响应格式
|
||||
if (Array.isArray(res)) {
|
||||
models.value = res
|
||||
} else if (res?.data && Array.isArray(res.data)) {
|
||||
models.value = res.data
|
||||
} else if (res?.results && Array.isArray(res.results)) {
|
||||
models.value = res.results
|
||||
} else {
|
||||
models.value = []
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('获取模型列表失败:', error)
|
||||
ElMessage.error('获取模型列表失败')
|
||||
models.value = []
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加模型
|
||||
*/
|
||||
const addModel = async (data: Partial<Model>): Promise<boolean> => {
|
||||
try {
|
||||
await modelApi.create(data)
|
||||
ElMessage.success('添加成功')
|
||||
await fetchModels()
|
||||
return true
|
||||
} catch (error: any) {
|
||||
console.error('添加模型失败:', error)
|
||||
ElMessage.error(error?.message || '添加模型失败')
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新模型
|
||||
*/
|
||||
const updateModel = async (id: number, data: Partial<Model>): Promise<boolean> => {
|
||||
try {
|
||||
await modelApi.update(id, data)
|
||||
ElMessage.success('更新成功')
|
||||
await fetchModels()
|
||||
return true
|
||||
} catch (error: any) {
|
||||
console.error('更新模型失败:', error)
|
||||
ElMessage.error(error?.message || '更新模型失败')
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除模型
|
||||
*/
|
||||
const deleteModel = async (id: number): Promise<boolean> => {
|
||||
try {
|
||||
await modelApi.delete(id)
|
||||
ElMessage.success('删除成功')
|
||||
await fetchModels()
|
||||
return true
|
||||
} catch (error: any) {
|
||||
console.error('删除模型失败:', error)
|
||||
ElMessage.error(error?.message || '删除模型失败')
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认模型
|
||||
*/
|
||||
const setDefaultModel = async (id: number): Promise<boolean> => {
|
||||
try {
|
||||
await modelApi.setDefault(id)
|
||||
ElMessage.success('设置成功')
|
||||
await fetchModels()
|
||||
return true
|
||||
} catch (error: any) {
|
||||
console.error('设置默认模型失败:', error)
|
||||
ElMessage.error(error?.message || '设置默认模型失败')
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
loading,
|
||||
models,
|
||||
fetchModels,
|
||||
addModel,
|
||||
updateModel,
|
||||
deleteModel,
|
||||
setDefaultModel
|
||||
}
|
||||
}
|
||||
98
frontend/src/shared/composables/useProjects.ts
Normal file
98
frontend/src/shared/composables/useProjects.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* 项目相关业务逻辑
|
||||
*/
|
||||
import { ref } from 'vue'
|
||||
import { projectApi } from '@/core/api'
|
||||
import type { Project, ProjectCreate } from '@/shared/types'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
export function useProjects() {
|
||||
const loading = ref(false)
|
||||
const projects = ref<Project[]>([])
|
||||
|
||||
/**
|
||||
* 获取项目列表
|
||||
*/
|
||||
const fetchProjects = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await projectApi.list()
|
||||
// 处理两种响应格式
|
||||
if (Array.isArray(res)) {
|
||||
projects.value = res
|
||||
} else if (res?.data && Array.isArray(res.data)) {
|
||||
projects.value = res.data
|
||||
} else if (res?.results && Array.isArray(res.results)) {
|
||||
projects.value = res.results
|
||||
} else {
|
||||
projects.value = []
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('获取项目列表失败:', error)
|
||||
ElMessage.error('获取项目列表失败')
|
||||
projects.value = []
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建项目
|
||||
*/
|
||||
const createProject = async (data: ProjectCreate): Promise<Project | null> => {
|
||||
try {
|
||||
const res = await projectApi.create(data)
|
||||
ElMessage.success('创建成功')
|
||||
await fetchProjects()
|
||||
return res
|
||||
} catch (error: any) {
|
||||
console.error('创建项目失败:', error)
|
||||
ElMessage.error(error?.message || '创建项目失败')
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除项目
|
||||
*/
|
||||
const deleteProject = async (id: number): Promise<boolean> => {
|
||||
try {
|
||||
await projectApi.delete(id)
|
||||
ElMessage.success('删除成功')
|
||||
await fetchProjects()
|
||||
return true
|
||||
} catch (error: any) {
|
||||
console.error('删除项目失败:', error)
|
||||
ElMessage.error(error?.message || '删除项目失败')
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目详情
|
||||
*/
|
||||
const fetchProject = async (id: number): Promise<Project | null> => {
|
||||
try {
|
||||
const res = await projectApi.get(id)
|
||||
if (res && typeof res === 'object' && 'id' in res) {
|
||||
return res as Project
|
||||
} else if (res?.data) {
|
||||
return res.data as Project
|
||||
}
|
||||
return null
|
||||
} catch (error: any) {
|
||||
console.error('获取项目详情失败:', error)
|
||||
ElMessage.error('获取项目详情失败')
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
loading,
|
||||
projects,
|
||||
fetchProjects,
|
||||
createProject,
|
||||
deleteProject,
|
||||
fetchProject
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user