Files
nanxiisletAdmin/src/stores/project.ts
2025-12-28 22:12:08 +08:00

293 lines
7.6 KiB
TypeScript

/**
* 项目状态管理
*
* 管理平台中的业务项目及当前选中的子项目状态
*/
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import {
mockProjects as initialProjects,
generateNextVersion,
type PlatformProject,
type ProjectMenuItem,
type ProjectVersion
} from '@/mock/projects'
export const useProjectStore = defineStore('project', () => {
// 所有项目列表(响应式)
const projects = ref<PlatformProject[]>([...initialProjects])
// 当前选中的项目ID
const currentProjectId = ref<string | null>(null)
// 所有启用的项目列表
const enabledProjects = computed(() => projects.value.filter(p => p.enabled))
// 当前选中的项目
const currentProject = computed<PlatformProject | null>(() => {
if (!currentProjectId.value) return null
return projects.value.find(p => p.id === currentProjectId.value) || null
})
// 当前项目的菜单
const currentProjectMenus = computed<ProjectMenuItem[]>(() => {
return currentProject.value?.menus || []
})
// 当前项目的 baseUrl
const currentProjectBaseUrl = computed<string>(() => {
return currentProject.value?.baseUrl || ''
})
// 是否处于子项目模式
const isInSubProject = computed(() => !!currentProjectId.value)
/**
* 切换到指定项目
*/
function switchProject(projectId: string | null) {
currentProjectId.value = projectId
}
/**
* 退出子项目,返回框架
*/
function exitSubProject() {
currentProjectId.value = null
}
/**
* 添加新项目
*/
function addProject(project: PlatformProject) {
// 为新项目创建初始版本
const initialVersion: ProjectVersion = {
id: `v-${Date.now()}`,
version: '1.0.0',
description: '初始版本',
createdAt: new Date().toISOString(),
createdBy: '管理员',
snapshot: {
name: project.name,
shortName: project.shortName,
logo: project.logo,
color: project.color,
description: project.description,
baseUrl: project.baseUrl,
menus: project.menus || []
}
}
project.currentVersion = '1.0.0'
project.versions = [initialVersion]
projects.value.push(project)
}
/**
* 更新项目
*/
function updateProject(projectId: string, updates: Partial<PlatformProject>) {
const index = projects.value.findIndex(p => p.id === projectId)
if (index > -1) {
projects.value[index] = {
...projects.value[index],
...updates
}
}
}
/**
* 删除项目
*/
function deleteProject(projectId: string) {
const index = projects.value.findIndex(p => p.id === projectId)
if (index > -1) {
projects.value.splice(index, 1)
}
// 如果删除的是当前项目,退出子项目模式
if (currentProjectId.value === projectId) {
currentProjectId.value = null
}
}
/**
* 切换项目状态
*/
function toggleProjectEnabled(projectId: string) {
const project = projects.value.find(p => p.id === projectId)
if (project) {
project.enabled = !project.enabled
}
}
/**
* 根据ID获取项目
*/
function getProjectById(projectId: string): PlatformProject | undefined {
return projects.value.find(p => p.id === projectId)
}
/**
* 创建新版本
*/
function createVersion(projectId: string, description: string): ProjectVersion | null {
const project = projects.value.find(p => p.id === projectId)
if (!project) return null
const newVersion = generateNextVersion(project.currentVersion)
const versionRecord: ProjectVersion = {
id: `v-${Date.now()}`,
version: newVersion,
description,
createdAt: new Date().toISOString(),
createdBy: '管理员',
snapshot: {
name: project.name,
shortName: project.shortName,
logo: project.logo,
color: project.color,
description: project.description,
baseUrl: project.baseUrl,
menus: JSON.parse(JSON.stringify(project.menus)) // 深拷贝
}
}
if (!project.versions) {
project.versions = []
}
project.versions.push(versionRecord)
project.currentVersion = newVersion
return versionRecord
}
/**
* 回退到指定版本
*/
function rollbackToVersion(projectId: string, versionId: string): boolean {
const project = projects.value.find(p => p.id === projectId)
if (!project || !project.versions) return false
const version = project.versions.find(v => v.id === versionId)
if (!version) return false
// 恢复快照数据
const { snapshot } = version
project.name = snapshot.name
project.shortName = snapshot.shortName
project.logo = snapshot.logo
project.color = snapshot.color
project.description = snapshot.description
project.baseUrl = snapshot.baseUrl
project.menus = JSON.parse(JSON.stringify(snapshot.menus)) // 深拷贝
project.currentVersion = version.version
return true
}
/**
* 获取项目的版本列表
*/
function getProjectVersions(projectId: string): ProjectVersion[] {
const project = projects.value.find(p => p.id === projectId)
return project?.versions || []
}
/**
* 删除指定版本(不能删除当前版本)
*/
function deleteVersion(projectId: string, versionId: string): boolean {
const project = projects.value.find(p => p.id === projectId)
if (!project || !project.versions) return false
const versionIndex = project.versions.findIndex(v => v.id === versionId)
if (versionIndex === -1) return false
const version = project.versions[versionIndex]
// 不能删除当前版本
if (version.version === project.currentVersion) return false
project.versions.splice(versionIndex, 1)
return true
}
/**
* 根据菜单key获取完整路由路径
* 返回格式: /app/{projectId}/{path}
*/
function getMenuRoutePath(menuKey: string): string | null {
if (!currentProject.value) return null
const projectId = currentProject.value.id
const menus = currentProject.value.menus
// 递归查找菜单项
function findMenuPath(items: ProjectMenuItem[]): string | null {
for (const item of items) {
if (item.key === menuKey && item.path) {
return `/app/${projectId}${item.path}`
}
if (item.children) {
const found = findMenuPath(item.children)
if (found) return found
}
}
return null
}
return findMenuPath(menus)
}
/**
* 获取菜单项到路由的映射
*/
function getMenuRouteMap(): Record<string, string> {
if (!currentProject.value) return {}
const projectId = currentProject.value.id
const map: Record<string, string> = {}
function processMenus(items: ProjectMenuItem[]) {
for (const item of items) {
if (item.path) {
map[item.key] = `/app/${projectId}${item.path}`
}
if (item.children) {
processMenus(item.children)
}
}
}
processMenus(currentProject.value.menus)
return map
}
return {
// 状态
projects,
currentProjectId,
currentProject,
currentProjectMenus,
currentProjectBaseUrl,
enabledProjects,
isInSubProject,
// 方法
switchProject,
exitSubProject,
addProject,
updateProject,
deleteProject,
toggleProjectEnabled,
getProjectById,
// 版本管理方法
createVersion,
rollbackToVersion,
getProjectVersions,
deleteVersion,
// 菜单路由方法
getMenuRoutePath,
getMenuRouteMap
}
})