184 lines
4.9 KiB
TypeScript
184 lines
4.9 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import { ref, watch, computed } from 'vue'
|
|
|
|
// 设计组件实例
|
|
export interface DesignComponentInstance {
|
|
id: string // 实例唯一ID
|
|
componentId: string // 设计组件类型ID
|
|
name: string // 显示名称
|
|
props: Record<string, any> // 属性值
|
|
}
|
|
|
|
// 设计组件定义
|
|
export interface DesignComponentMeta {
|
|
id: string
|
|
name: string
|
|
description: string
|
|
props: Record<string, any>
|
|
}
|
|
|
|
// 生成唯一ID
|
|
const generateId = () => Math.random().toString(36).substring(2, 9)
|
|
|
|
export const useDesignStore = defineStore('design', () => {
|
|
// 设计中心已添加的组件实例列表
|
|
const components = ref<DesignComponentInstance[]>([])
|
|
|
|
// 当前选中的组件实例ID
|
|
const selectedId = ref<string | null>(null)
|
|
|
|
// 设计组件元数据缓存
|
|
const componentMetas = ref<DesignComponentMeta[]>([])
|
|
|
|
// 是否已加载
|
|
const isLoaded = ref(false)
|
|
|
|
// 当前选中的组件实例
|
|
const selectedComponent = computed(() => {
|
|
if (!selectedId.value) return null
|
|
return components.value.find(c => c.id === selectedId.value) || null
|
|
})
|
|
|
|
// 当前选中组件的元数据(属性定义)
|
|
const selectedComponentMeta = computed(() => {
|
|
if (!selectedComponent.value) return null
|
|
return componentMetas.value.find(m => m.id === selectedComponent.value!.componentId) || null
|
|
})
|
|
|
|
// 加载设计组件元数据
|
|
const loadComponentMetas = async () => {
|
|
try {
|
|
const response = await fetch('/api/design-components')
|
|
if (response.ok) {
|
|
componentMetas.value = await response.json()
|
|
}
|
|
} catch (error) {
|
|
console.error('加载设计组件元数据失败:', error)
|
|
}
|
|
}
|
|
|
|
// 加载设计中心状态
|
|
const loadState = async () => {
|
|
try {
|
|
const response = await fetch('/api/design-state')
|
|
if (response.ok) {
|
|
const data = await response.json()
|
|
if (data.components) {
|
|
components.value = data.components
|
|
}
|
|
if (data.selectedId) {
|
|
selectedId.value = data.selectedId
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.log('使用默认设计状态')
|
|
}
|
|
isLoaded.value = true
|
|
}
|
|
|
|
// 保存设计中心状态
|
|
const saveState = async () => {
|
|
try {
|
|
await fetch('/api/design-state', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
components: components.value,
|
|
selectedId: selectedId.value,
|
|
lastUpdated: new Date().toISOString()
|
|
})
|
|
})
|
|
} catch (error) {
|
|
console.error('保存设计状态失败:', error)
|
|
}
|
|
}
|
|
|
|
// 监听变化自动保存
|
|
watch([components, selectedId], () => {
|
|
if (isLoaded.value) {
|
|
saveState()
|
|
}
|
|
}, { deep: true })
|
|
|
|
// 添加设计组件到设计中心
|
|
const addComponent = (componentId: string) => {
|
|
const meta = componentMetas.value.find(m => m.id === componentId)
|
|
if (!meta) {
|
|
console.warn('未找到设计组件:', componentId)
|
|
return
|
|
}
|
|
|
|
// 计算同类型组件的数量
|
|
const sameTypeCount = components.value.filter(c => c.componentId === componentId).length
|
|
|
|
const instance: DesignComponentInstance = {
|
|
id: generateId(),
|
|
componentId: componentId,
|
|
name: `${meta.name} ${sameTypeCount + 1}`,
|
|
props: JSON.parse(JSON.stringify(meta.props))
|
|
}
|
|
|
|
components.value.push(instance)
|
|
selectedId.value = instance.id
|
|
}
|
|
|
|
// 移除设计组件
|
|
const removeComponent = (instanceId: string) => {
|
|
const index = components.value.findIndex(c => c.id === instanceId)
|
|
if (index > -1) {
|
|
components.value.splice(index, 1)
|
|
if (selectedId.value === instanceId) {
|
|
selectedId.value = components.value.length > 0 ? components.value[0].id : null
|
|
}
|
|
}
|
|
}
|
|
|
|
// 选中设计组件
|
|
const selectComponent = (instanceId: string | null) => {
|
|
selectedId.value = instanceId
|
|
}
|
|
|
|
// 更新组件属性
|
|
const updateComponentProps = (instanceId: string, key: string, value: any) => {
|
|
const component = components.value.find(c => c.id === instanceId)
|
|
if (component) {
|
|
component.props[key] = value
|
|
}
|
|
}
|
|
|
|
// 重新排序组件(拖拽后)
|
|
const reorderComponents = (newOrder: DesignComponentInstance[]) => {
|
|
components.value = newOrder
|
|
}
|
|
|
|
// 获取组件元数据
|
|
const getComponentMeta = (componentId: string) => {
|
|
return componentMetas.value.find(m => m.id === componentId)
|
|
}
|
|
|
|
// 初始化
|
|
const init = async () => {
|
|
await loadComponentMetas()
|
|
await loadState()
|
|
}
|
|
|
|
return {
|
|
components,
|
|
selectedId,
|
|
selectedComponent,
|
|
selectedComponentMeta,
|
|
componentMetas,
|
|
isLoaded,
|
|
init,
|
|
loadComponentMetas,
|
|
loadState,
|
|
saveState,
|
|
addComponent,
|
|
removeComponent,
|
|
selectComponent,
|
|
updateComponentProps,
|
|
reorderComponents,
|
|
getComponentMeta
|
|
}
|
|
})
|