293 lines
7.6 KiB
TypeScript
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
|
|
}
|
|
})
|