import type { ProjectInfo, Page, ReferLine, CustomElement } from "#/project"; import type { ComponentType } from "@/components"; import { defineStore } from "pinia"; import componentAll from "@/components"; import { ScreenFillEnum } from "@/enum/screenFillEnum"; import { update, defaultsDeep } from "lodash"; import { getNormalizedContainer } from "@/utils/common"; type ProjectState = { projectInfo: ProjectInfo; activePageIndex: number; addCompData: { key: number; name: string; componentType: ComponentType; container: { style: Record; props: Record; }; } | null; mode: "edit" | "preview"; selectedElementKeys: number[]; }; const defaultPage: Page = { name: "页面1", background: { type: "color", color: "#0b074b", image: "", fillType: "", }, elements: [], referLines: [], }; const CURRENT_PROJECT = "currentProject"; export const useProjectStore = defineStore({ id: "project", state: (): ProjectState => ({ // 项目信息 projectInfo: { name: "", description: "", sizeType: "", width: 0, height: 0, fillType: ScreenFillEnum.Auto, pages: [{ ...defaultPage }], }, // 当前编辑页面索引 activePageIndex: 0, // 添加组件临时数据 addCompData: null, // 视图模式 mode: "edit", // 选中的元素 selectedElementKeys: [], }), getters: { referLines(state) { return state.projectInfo.pages[state.activePageIndex].referLines; }, elements(state) { return state.projectInfo.pages[state.activePageIndex].elements; }, currentPage(state) { return state.projectInfo.pages[state.activePageIndex]; }, }, actions: { setProjectInfo(info: any) { Object.assign(this.projectInfo, info); localStorage.setItem(CURRENT_PROJECT, JSON.stringify(info)); }, getCurrentProjectInfo(): ProjectInfo | undefined { const info = JSON.parse(localStorage.getItem(CURRENT_PROJECT) || ""); this.setProjectInfo(info as unknown as ProjectInfo); return info; }, addReferLine(line: ReferLine) { this.projectInfo.pages[this.activePageIndex].referLines.push(line); }, removeReferLine(key: number) { const index = this.referLines.findIndex((line) => line.key === key); index !== -1 && this.projectInfo.pages[this.activePageIndex].referLines.splice( index, 1 ); }, updateReferLine(line: ReferLine) { const index = this.referLines.findIndex((l) => l.key === line.key); if (index !== -1) { this.projectInfo.pages[this.activePageIndex].referLines[index] = line; } }, // 添加组件 async addElement(element: any) { this.addCompData = null; if (!element) return; const elements = this.projectInfo.pages[this.activePageIndex].elements; // 获取每个自定义组件暴露出来的属性 const { defaultPropsValue } = (await componentAll[element.componentType as ComponentType]?.()) || {}; const { width = 400, height = 260 } = defaultPropsValue?.container?.props || {}; const { props: containerProps = {}, style = {} } = defaultPropsValue?.container || {}; const index = elements.filter((item) => item.componentType === element.componentType) .length + 1; const { x, y } = element.container.props; const container = getNormalizedContainer({ style, props: { ...containerProps, width, height, x: x - width / 2, y: y - height / 2, }, }); // 添加组件 this.projectInfo.pages[this.activePageIndex].elements.push({ ...defaultsDeep(element, defaultPropsValue), name: element.name + index, zIndex: elements.length + 1, visible: true, locked: false, container, }); this.selectedElementKeys = [element.key]; }, // 更新组件 updateElement(key: number, path: string, payload: any) { const element = this.projectInfo.pages[ this.activePageIndex ].elements.find((item) => item.key === key); // 如果是锁定状态不能修改宽高 位置 if ( element && element.locked && [ "container.props.width", "container.props.height", "container.props.x", "container.props.y", ].includes(path) ) return; if (element) { update(element, path, () => payload); } }, // 删除组件 removeElement(key: number) { const index = this.projectInfo.pages[ this.activePageIndex ].elements.findIndex((item) => item.key === key); if (index !== -1) { this.projectInfo.pages[this.activePageIndex].elements.splice(index, 1); } }, // 设置临时添加组件数据 setAddCompData(data: any) { this.addCompData = data; }, // 清除临时添加组件数据 clearAddCompData() { this.addCompData = null; }, setMode(mode: "edit" | "preview") { this.mode = mode; }, // 设置选中的元素 setSelectedElementKeys(keys: number[]) { this.selectedElementKeys = keys; }, // 删除所有选中的元素 clearAllSelectedElement() { this.selectedElementKeys = []; }, }, });