import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import fs from 'fs' import path from 'path' import type { Plugin } from 'vite' // 配置文件路径 const CONFIG_FILE = path.resolve(__dirname, 'config.json') const DESIGN_STATE_FILE = path.resolve(__dirname, 'design-state.json') const MATERIAL_STATES_FILE = path.resolve(__dirname, 'material-states.json') const VUE_FILE_SELECTION_FILE = path.resolve(__dirname, 'vue-file-selection.json') const DESIGN_COMPONENTS_DIR = path.resolve(__dirname, 'src/designComponents') // 通用JSON文件读写处理器 function createJsonHandler(filePath: string) { return { read: () => { if (fs.existsSync(filePath)) { return fs.readFileSync(filePath, 'utf-8') } return JSON.stringify({}) }, write: (data: string) => { fs.writeFileSync(filePath, data) } } } // 读取设计组件元数据 function loadDesignComponentMetas() { const metas: any[] = [] if (!fs.existsSync(DESIGN_COMPONENTS_DIR)) { return metas } const dirs = fs.readdirSync(DESIGN_COMPONENTS_DIR) for (const dir of dirs) { const jsonPath = path.join(DESIGN_COMPONENTS_DIR, dir, 'index.json') if (fs.existsSync(jsonPath)) { try { const content = fs.readFileSync(jsonPath, 'utf-8') const meta = JSON.parse(content) metas.push({ id: dir, ...meta }) } catch (e) { console.error(`加载设计组件元数据失败: ${dir}`, e) } } } return metas } // 自定义插件:处理配置文件的读写 function configApiPlugin(): Plugin { const configHandler = createJsonHandler(CONFIG_FILE) const designStateHandler = createJsonHandler(DESIGN_STATE_FILE) const materialStatesHandler = createJsonHandler(MATERIAL_STATES_FILE) const vueFileSelectionHandler = createJsonHandler(VUE_FILE_SELECTION_FILE) return { name: 'config-api', configureServer(server) { // 布局配置 API server.middlewares.use('/api/config', (req, res, next) => { if (req.method === 'GET') { try { res.setHeader('Content-Type', 'application/json') res.end(configHandler.read()) } catch (error) { res.statusCode = 500 res.end(JSON.stringify({ error: 'Failed to read config' })) } } else if (req.method === 'POST') { let body = '' req.on('data', (chunk) => body += chunk.toString()) req.on('end', () => { try { const config = JSON.parse(body) configHandler.write(JSON.stringify(config, null, 2)) res.setHeader('Content-Type', 'application/json') res.end(JSON.stringify({ success: true })) } catch (error) { res.statusCode = 500 res.end(JSON.stringify({ error: 'Failed to save config' })) } }) } else { next() } }) // 设计组件元数据 API server.middlewares.use('/api/design-components', (req, res, next) => { if (req.method === 'GET') { try { const metas = loadDesignComponentMetas() res.setHeader('Content-Type', 'application/json') res.end(JSON.stringify(metas)) } catch (error) { res.statusCode = 500 res.end(JSON.stringify({ error: 'Failed to load design components' })) } } else { next() } }) // 设计中心状态 API server.middlewares.use('/api/design-state', (req, res, next) => { if (req.method === 'GET') { try { res.setHeader('Content-Type', 'application/json') res.end(designStateHandler.read()) } catch (error) { res.statusCode = 500 res.end(JSON.stringify({ error: 'Failed to read design state' })) } } else if (req.method === 'POST') { let body = '' req.on('data', (chunk) => body += chunk.toString()) req.on('end', () => { try { const state = JSON.parse(body) designStateHandler.write(JSON.stringify(state, null, 2)) res.setHeader('Content-Type', 'application/json') res.end(JSON.stringify({ success: true })) } catch (error) { res.statusCode = 500 res.end(JSON.stringify({ error: 'Failed to save design state' })) } }) } else { next() } }) // 物料组件状态 API (独立存储) server.middlewares.use('/api/material-states', (req, res, next) => { if (req.method === 'GET') { try { res.setHeader('Content-Type', 'application/json') res.end(materialStatesHandler.read()) } catch (error) { res.statusCode = 500 res.end(JSON.stringify({ error: 'Failed to read material states' })) } } else if (req.method === 'POST') { let body = '' req.on('data', (chunk) => body += chunk.toString()) req.on('end', () => { try { const states = JSON.parse(body) materialStatesHandler.write(JSON.stringify(states, null, 2)) res.setHeader('Content-Type', 'application/json') res.end(JSON.stringify({ success: true })) } catch (error) { res.statusCode = 500 res.end(JSON.stringify({ error: 'Failed to save material states' })) } }) } else { next() } }) // Vue文件选择状态 API server.middlewares.use('/api/vue-file-selection', (req, res, next) => { if (req.method === 'GET') { try { res.setHeader('Content-Type', 'application/json') res.end(vueFileSelectionHandler.read()) } catch (error) { res.statusCode = 500 res.end(JSON.stringify({ error: 'Failed to read vue file selection' })) } } else if (req.method === 'POST') { let body = '' req.on('data', (chunk) => body += chunk.toString()) req.on('end', () => { try { const selection = JSON.parse(body) vueFileSelectionHandler.write(JSON.stringify(selection, null, 2)) res.setHeader('Content-Type', 'application/json') res.end(JSON.stringify({ success: true })) } catch (error) { res.statusCode = 500 res.end(JSON.stringify({ error: 'Failed to save vue file selection' })) } }) } else { next() } }) } } } // https://vite.dev/config/ export default defineConfig({ plugins: [vue(), configApiPlugin()], })