From 5a0ce194a94f0b7345c5b174bae6c7df47ec5948 Mon Sep 17 00:00:00 2001 From: yaoyun8 Date: Tue, 26 Dec 2023 04:26:57 -0800 Subject: [PATCH 01/16] feat: add materials script --- package.json | 9 +- scripts/buildMaterials.mjs | 95 ++++++++++++++++++ scripts/connection.mjs | 198 +++++++++++++++++++++++++++++++++++++ scripts/splitMaterials.mjs | 45 +++++++++ 4 files changed, 345 insertions(+), 2 deletions(-) create mode 100644 scripts/buildMaterials.mjs create mode 100644 scripts/connection.mjs create mode 100644 scripts/splitMaterials.mjs diff --git a/package.json b/package.json index 365ca8e216..c6fd9184ab 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,9 @@ "pub:preminor": "pnpm run build:plugin && pnpm run build:alpha && pnpm lerna version preminor --preid beta --no-push --yes && lerna publish from-package --pre-dist-tag beta --yes", "pub:prepatch": "pnpm run build:plugin && pnpm run build:alpha && pnpm lerna version prepatch --preid beta --no-push --yes && lerna publish from-package --pre-dist-tag beta --yes", "pub:prerelease": "pnpm run build:plugin && pnpm run build:alpha && pnpm lerna version prerelease --preid beta --no-push --yes && lerna publish from-package --pre-dist-tag beta --yes", - "setup": "node ./scripts/setup.js" + "setup": "node ./scripts/setup.js", + "splitMaterials": "node ./scripts/splitMaterials.mjs", + "buildMaterials": "node ./scripts/buildMaterials.mjs" }, "devDependencies": { "@babel/eslint-parser": "^7.21.3", @@ -30,15 +32,18 @@ "@vitejs/plugin-vue-jsx": "^1.3.2", "assert": "^2.0.0", "buffer": "^6.0.3", + "chokidar": "^3.5.3", + "concurrently": "^8.2.0", "cross-env": "^7.0.3", "eslint": "^8.38.0", "eslint-plugin-vue": "^8.0.0", + "fast-glob": "^3.3.2", "fs-extra": "^10.1.0", "husky": "^8.0.0", - "concurrently": "^8.2.0", "lerna": "^7.2.0", "less": "^4.1.2", "lint-staged": "^13.2.0", + "mysql": "^2.18.1", "path": "^0.12.7", "rimraf": "^3.0.2", "rollup-plugin-polyfill-node": "^0.12.0", diff --git a/scripts/buildMaterials.mjs b/scripts/buildMaterials.mjs new file mode 100644 index 0000000000..05e909e884 --- /dev/null +++ b/scripts/buildMaterials.mjs @@ -0,0 +1,95 @@ +import fsExtra from 'fs-extra' +import path from 'node:path' +import chokidar from 'chokidar' +import fg from 'fast-glob' +import MysqlConnection from './connection.mjs' + +// 物料资产包 +const bundlePath = path.join(process.cwd(), '/packages/design-core/public/mock/bundle.json') +// mockServer应用数据 +const appInfoPath = path.join(process.cwd(), '/mockServer/src/services/appinfo.json') +const appInfo = fsExtra.readJSONSync(appInfoPath) +const bundle = { + data: { + framework: 'Vue', + materials: { + components: [], + blocks: [], + snippets: [] + } + } +} + +const write = () => { + fsExtra.outputJSONSync(bundlePath, bundle, { spaces: 2 }) + fsExtra.outputJSONSync(appInfoPath, appInfo, { spaces: 2 }) +} + +const generateComponents = () => { + try { + fg(['materials/**/*.json']).then((files) => { + const { components = [], snippets = [], blocks = [] } = bundle.data.materials + const componentsMap = [] + const appInfoBlocksLabels = appInfo.blockHistories.map((item) => item.label) + + files.forEach((file) => { + const material = fsExtra.readJsonSync(file) + + if (file.includes('/blocks/')) { + blocks.push(material) + + if (!appInfoBlocksLabels.includes(material.label)) { + appInfo.blockHistories.push(material) + } + + return + } + + const { snippet: componentSnippet, category, ...componentInfo } = material + + components.push(componentInfo) + + const snippet = snippets.find((item) => item.group === category) + + if (snippet) { + componentSnippet && snippet.children.push(componentSnippet) + } else if (category && componentInfo) { + snippets.push({ + group: category, + children: [componentSnippet] + }) + } + + const { component, npm = {} } = componentInfo + + componentsMap.push({ component, npm }) + }) + + appInfo.materialHistory.components = componentsMap + + write() + }) + } catch (error) { + throw new Error(`构建物料资产包失败:${error}`) + } +} + +const connection = new MysqlConnection() + +const watcher = chokidar.watch('materials/**/*.json', { ignoreInitial: true }) + +watcher.on('all', (event, file) => { + console.log('组件更新 =>', event, file) + // 监听物料文件变化,更新物料资产包 + generateComponents() + + if (!connection.connected) return + + const component = fsExtra.readJsonSync(path.join(process.cwd(), file)) + + if (event === 'change') { + connection.updateComponent(component) + } else if (event === 'add') { + connection.insertComponent(component) + } +}) diff --git a/scripts/connection.mjs b/scripts/connection.mjs new file mode 100644 index 0000000000..2a540ee9a8 --- /dev/null +++ b/scripts/connection.mjs @@ -0,0 +1,198 @@ +// const mysql = require('mysql') +import mysql from 'mysql' + +class MysqlConnection { + constructor(config) { + const { host = 'localhost', port = '3306', user = 'root', password = 'yao8yun5!', database = '' } = config || {} + // 是否连接上了数据库 + this.connected = false + + this.connection = mysql.createConnection({ + host, // 主机名(服务器地址) + port, // 端口号 + user, // 用户名 + password, // 密码 + database // 数据库名称 + }) + + this.connection.connect((error) => { + if (error) { + console.log('连接数据库失败:', error) + } else { + console.log('连接数据库成功') + this.connected = true + } + }) + } + + /** + * 执行sql语句,更新数据库 + * @param {string} sql sql语句 + * @param {string} componentName 组件名称 + */ + connectQuery(sql, componentName) { + this.connection.query(sql, (error) => { + if (error) { + console.log(`组件 ${componentName} 执行sql失败:${error}`) + } + }) + } + + /** + * 组件字段映射 + * @param {string} field 字段名 + * @returns 映射后的字段名 + */ + fieldTransform(field) { + const fieldMap = { + docUrl: 'doc_url', + devMode: 'dev_mode', + schema: 'schema_fragment' + } + + return fieldMap[field] || field + } + + /** + * 格式化单引号 + * @param {string} str 待格式化的字符串 + * @returns 格式化后的字符串 + */ + formatSingleQuoteValue(str) { + return str.replace(/'/g, "\\'") + } + + /** + * 生成更新组件的sql语句 + * @param {object} component 组件数据 + * @returns 更新组件的sql语句 + */ + updateComponent(component) { + const values = [] + let sqlContent = 'update user_components set ' + + Object.keys(component).forEach((key) => { + const { [key]: value } = component + const field = this.fieldTransform(key) + let updateContent = '' + + if (['id', 'component'].includes(field)) { + return + } + + if (typeof value === 'string') { + const formatValue = this.formatSingleQuoteValue(value) + + updateContent = `\`${field}\` = '${formatValue}'` + } else if (typeof field === 'number' || field === null) { + updateContent = `\`${field}\` = ${value}` + } else { + const formatValue = this.formatSingleQuoteValue(JSON.stringify(value)) + + updateContent = `\`${field}\` = '${formatValue}'` + } + + values.push(updateContent) + }) + + sqlContent += values.join() + sqlContent += ` where component = '${component.component}';` + + this.connectQuery(sqlContent, component.component) + } + + /** + * 生成新增组件的sql语句 + * @param {object} component 组件数据 + * @returns 新增组件的sql语句 + */ + insertComponent(component) { + const { + version, + name, + component: componentName, + icon, + description, + docUrl, + screenshot, + tags, + keywords, + devMode, + npm, + group, + category, + priority = 1, + snippets, + schema, + configure, + public: publicRight = 0, + framework = 'vue', + isOfficial = 0, + isDefault = 0, + tiny_reserved = 0, + component_metadata = null, + tenant = null, + library = null, + createBy = 86, + updatedBy = 86 + } = component + const values = `('${version}', + '${this.formatSingleQuoteValue(JSON.stringify(name))}', + '${componentName}', + '${icon}', + '${this.formatSingleQuoteValue(description)}', + '${docUrl}', + '${screenshot}', + '${tags}', + '${keywords}', + '${devMode}', + '${this.formatSingleQuoteValue(JSON.stringify(npm))}', + '${group}', + '${category}', + '${priority}', + '${this.formatSingleQuoteValue(JSON.stringify(snippets))}', + '${this.formatSingleQuoteValue(JSON.stringify(schema))}', + '${this.formatSingleQuoteValue(JSON.stringify(configure))}', + '${publicRight}', + '${framework}', + '${isOfficial}', + '${isDefault}', + '${tiny_reserved}', + '${component_metadata}', + '${tenant}', + '${library}', + '${createBy}', + '${updatedBy}', + );` + + const sqlContent = `INSERT INTO user_components (version, name, component, icon, description, doc_url, + screenshot, tags, keywords, dev_mode, npm, \`group\`, \`category\`, priority, snippets, + schema_fragment, configure, \`public\`, framework, isOfficial, isDefault, tiny_reserved, + component_metadata, tenant, library, createdBy, updatedBy) VALUES ${values}\n`.replace(/\n/g, '') + + this.connectQuery(sqlContent, componentName) + } + + /** + * 初始化数据库数据,判断是否已存在组件,不存在时执行新增组件 + * @param {object} component 组件数据 + */ + initDB(component) { + this.connection.query( + `SELECT * FROM components.user_components WHERE component = '${component.component}'`, + (error, result) => { + if (error) { + console.log(`查询组件 ${component.component} 失败:`, error) + + return + } + + if (!result.length) { + this.insertComponent(component) + } + } + ) + } +} + +export default MysqlConnection diff --git a/scripts/splitMaterials.mjs b/scripts/splitMaterials.mjs new file mode 100644 index 0000000000..f8d660e6a2 --- /dev/null +++ b/scripts/splitMaterials.mjs @@ -0,0 +1,45 @@ +import fs from 'fs-extra' +import path from 'node:path' + +const bundlePath = path.join(process.cwd(), '/packages/design-core/public/mock/bundle.json') +const bundle = fs.readJSONSync(bundlePath) +const { components, snippets, blocks } = bundle.data.materials + +const capitalize = (str) => `${str.charAt(0).toUpperCase()}${str.slice(1)}` +const toPascalCase = (str) => str.split('-').map(capitalize).join('') + +try { + components.forEach((comp) => { + snippets.some((child) => { + const snippet = child.children.find((item) => { + if (Array.isArray(comp.component)) { + return toPascalCase(comp.component[0]) === toPascalCase(item.snippetName) + } + + return toPascalCase(comp.component) === toPascalCase(item.snippetName) + }) + + if (snippet) { + comp.snippet = { ...snippet } + comp.category = child.group + + return true + } + + return false + }) + + const fileName = Array.isArray(comp.component) ? comp.component[0] : comp.component + const componentPath = path.join(process.cwd(), '/materials/components', `${fileName}.json`) + + fs.outputJsonSync(componentPath, comp, { spaces: 2 }) + }) + + blocks.forEach((block) => { + const blockPath = path.join(process.cwd(), '/materials/blocks', `${block.label}.json`) + + fs.outputJsonSync(blockPath, block, { spaces: 2 }) + }) +} catch (error) { + throw new Error(`拆分物料资产包失败, ${error}`) +} From 287e6fa176ad1357bbebda3dff3c949fca3e237f Mon Sep 17 00:00:00 2001 From: yaoyun8 Date: Wed, 27 Dec 2023 00:48:25 -0800 Subject: [PATCH 02/16] =?UTF-8?q?fix=EF=BC=9A=E4=BC=98=E5=8C=96=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E8=A1=8C=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + scripts/buildMaterials.mjs | 90 ++++++++++++++++++-- scripts/connection.mjs | 169 +++++++++++++++++++++++++++++-------- scripts/logger.mjs | 28 ++++++ scripts/splitMaterials.mjs | 9 +- 5 files changed, 251 insertions(+), 46 deletions(-) create mode 100644 scripts/logger.mjs diff --git a/package.json b/package.json index c6fd9184ab..c80c7de2f5 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "lint-staged": "^13.2.0", "mysql": "^2.18.1", "path": "^0.12.7", + "picocolors": "^1.0.0", "rimraf": "^3.0.2", "rollup-plugin-polyfill-node": "^0.12.0", "rollup-plugin-terser": "^7.0.2", diff --git a/scripts/buildMaterials.mjs b/scripts/buildMaterials.mjs index 05e909e884..53105bab69 100644 --- a/scripts/buildMaterials.mjs +++ b/scripts/buildMaterials.mjs @@ -3,6 +3,7 @@ import path from 'node:path' import chokidar from 'chokidar' import fg from 'fast-glob' import MysqlConnection from './connection.mjs' +import logger from './logger.mjs' // 物料资产包 const bundlePath = path.join(process.cwd(), '/packages/design-core/public/mock/bundle.json') @@ -19,12 +20,47 @@ const bundle = { } } } +const connection = new MysqlConnection() const write = () => { fsExtra.outputJSONSync(bundlePath, bundle, { spaces: 2 }) fsExtra.outputJSONSync(appInfoPath, appInfo, { spaces: 2 }) } +const validateComponent = (file, component) => { + const requiredFields = ['component'] + const fields = Object.keys(component) + const requiredList = requiredFields.filter((field) => !fields.includes(field)) + + if (requiredList.length) { + logger.error(`组件文件 ${file} 缺少必要字段:${requiredList.join('、')}。`) + + return false + } + + if (!component.npm) { + logger.warn(`组件文件 ${file} 缺少 npm 字段,出码时将不能通过import语句导入组件。`) + + return false + } + + return true +} + +const validateBlock = (file, block) => { + const requiredFields = ['label', 'assets'] + const fields = Object.keys(block) + const requiredList = requiredFields.filter((field) => !fields.includes(field)) + + if (requiredList.length) { + logger.error(`区块文件 ${file} 缺少必要字段:${requiredList.join('、')}。`) + + return false + } + + return true +} + const generateComponents = () => { try { fg(['materials/**/*.json']).then((files) => { @@ -33,9 +69,19 @@ const generateComponents = () => { const appInfoBlocksLabels = appInfo.blockHistories.map((item) => item.label) files.forEach((file) => { - const material = fsExtra.readJsonSync(file) + const material = fsExtra.readJsonSync(file, { throws: false }) + + if (!material) { + logger.error(`读取物料文件 ${file} 失败`) + + return + } if (file.includes('/blocks/')) { + const valid = validateBlock(file, material) + + if (!valid) return + blocks.push(material) if (!appInfoBlocksLabels.includes(material.label)) { @@ -45,45 +91,60 @@ const generateComponents = () => { return } - const { snippet: componentSnippet, category, ...componentInfo } = material + const valid = validateComponent(file, material) + + if (!valid) return + + const { snippets: componentSnippets, category, ...componentInfo } = material components.push(componentInfo) const snippet = snippets.find((item) => item.group === category) if (snippet) { - componentSnippet && snippet.children.push(componentSnippet) + componentSnippets && snippet.children.push(componentSnippets[0]) } else if (category && componentInfo) { snippets.push({ group: category, - children: [componentSnippet] + children: componentSnippets || [] }) } const { component, npm = {} } = componentInfo componentsMap.push({ component, npm }) + + if (connection.connected) { + connection.initDB(material) + } }) appInfo.materialHistory.components = componentsMap write() }) + + logger.success('构建物料资产包成功') } catch (error) { - throw new Error(`构建物料资产包失败:${error}`) + logger.error(`构建物料资产包失败:${error}`) } } -const connection = new MysqlConnection() - const watcher = chokidar.watch('materials/**/*.json', { ignoreInitial: true }) watcher.on('all', (event, file) => { - console.log('组件更新 =>', event, file) + const eventMap = { + add: '新增', + change: '更新', + unlink: '删除' + } + + logger.info(`${eventMap[event]}组件文件 ${file}`) + // 监听物料文件变化,更新物料资产包 generateComponents() - if (!connection.connected) return + if (!connection.connected || event === 'unlink') return const component = fsExtra.readJsonSync(path.join(process.cwd(), file)) @@ -93,3 +154,14 @@ watcher.on('all', (event, file) => { connection.insertComponent(component) } }) + +connection + .connect() + .then(() => { + connection.initUserComponentsTable().finally(() => { + generateComponents() + }) + }) + .catch(() => { + generateComponents() + }) diff --git a/scripts/connection.mjs b/scripts/connection.mjs index 2a540ee9a8..12afa04f78 100644 --- a/scripts/connection.mjs +++ b/scripts/connection.mjs @@ -1,27 +1,34 @@ // const mysql = require('mysql') import mysql from 'mysql' +import logger from './logger.mjs' +const componentsTableName = 'user_components' class MysqlConnection { constructor(config) { - const { host = 'localhost', port = '3306', user = 'root', password = 'yao8yun5!', database = '' } = config || {} + this.config = config || { + host: 'localhost', // 主机名(服务器地址) + port: '3306', // 端口号 + user: 'root', // 用户名 + password: 'password', // 密码 + database: 'components' // 数据库名称 + } // 是否连接上了数据库 this.connected = false + this.connection = mysql.createConnection(this.config) + } - this.connection = mysql.createConnection({ - host, // 主机名(服务器地址) - port, // 端口号 - user, // 用户名 - password, // 密码 - database // 数据库名称 - }) - - this.connection.connect((error) => { - if (error) { - console.log('连接数据库失败:', error) - } else { - console.log('连接数据库成功') - this.connected = true - } + connect() { + return new Promise((resolve, reject) => { + this.connection.connect((error) => { + if (error) { + logger.warn('连接数据库失败') + reject() + } else { + logger.success('连接数据库成功') + this.connected = true + resolve() + } + }) }) } @@ -30,11 +37,15 @@ class MysqlConnection { * @param {string} sql sql语句 * @param {string} componentName 组件名称 */ - connectQuery(sql, componentName) { - this.connection.query(sql, (error) => { - if (error) { - console.log(`组件 ${componentName} 执行sql失败:${error}`) - } + query(sql) { + return new Promise((resolve, reject) => { + this.connection.query(sql, (error, result) => { + if (error) { + reject(error) + } else { + resolve(result) + } + }) }) } @@ -98,7 +109,13 @@ class MysqlConnection { sqlContent += values.join() sqlContent += ` where component = '${component.component}';` - this.connectQuery(sqlContent, component.component) + this.query(sqlContent, component.component) + .then(() => { + logger.success(`更新组件 ${component.component} 成功`) + }) + .catch((error) => { + logger.success(`更新组件 ${component.component} 失败:${error}`) + }) } /** @@ -168,9 +185,15 @@ class MysqlConnection { const sqlContent = `INSERT INTO user_components (version, name, component, icon, description, doc_url, screenshot, tags, keywords, dev_mode, npm, \`group\`, \`category\`, priority, snippets, schema_fragment, configure, \`public\`, framework, isOfficial, isDefault, tiny_reserved, - component_metadata, tenant, library, createdBy, updatedBy) VALUES ${values}\n`.replace(/\n/g, '') + component_metadata, tenant, library, createdBy, updatedBy) VALUES ${values}`.replace(/\n/g, '') - this.connectQuery(sqlContent, componentName) + this.query(sqlContent, componentName) + .then(() => { + logger.success(`新增组件 ${component.component} 成功`) + }) + .catch((error) => { + logger.success(`新增组件 ${component.component} 失败:${error}`) + }) } /** @@ -178,20 +201,98 @@ class MysqlConnection { * @param {object} component 组件数据 */ initDB(component) { - this.connection.query( - `SELECT * FROM components.user_components WHERE component = '${component.component}'`, - (error, result) => { - if (error) { - console.log(`查询组件 ${component.component} 失败:`, error) - - return - } + const selectSqlContent = `SELECT * FROM components.user_components WHERE component = '${component.component}'` + this.query(selectSqlContent) + .then((result) => { if (!result.length) { this.insertComponent(component) } - } - ) + }) + .catch((error) => { + logger.success(`查询组件 ${component.component} 失败:${error}`) + }) + } + + /** + * 创建组件表 + * @returns promise + */ + createUserComponentsTable() { + const sqlContent = ` + CREATE TABLE ${componentsTableName} ( + id int(10) UNSIGNED NOT NULL AUTO_INCREMENT, + version varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + name longtext CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + component varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + icon varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + description varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + doc_url varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + screenshot varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + tags varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + keywords varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + dev_mode varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + npm longtext CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + \`group\` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + category varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + priority int(11) NULL DEFAULT NULL, + snippets longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL, + schema_fragment longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL, + configure longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL, + createdBy int(11) NULL DEFAULT NULL, + updatedBy int(11) NULL DEFAULT NULL, + created_by int(11) NULL DEFAULT NULL, + updated_by int(11) NULL DEFAULT NULL, + created_at timestamp NULL DEFAULT CURRENT_TIMESTAMP, + updated_at timestamp NULL DEFAULT CURRENT_TIMESTAMP, + public int(11) NULL DEFAULT NULL, + framework varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + isOfficial tinyint(1) NULL DEFAULT NULL, + isDefault tinyint(1) NULL DEFAULT NULL, + tiny_reserved tinyint(1) NULL DEFAULT NULL, + tenant int(11) NULL DEFAULT NULL, + component_metadata longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL, + library int(11) NULL DEFAULT NULL, + PRIMARY KEY (id) USING BTREE, + UNIQUE INDEX unique_component(createdBy, framework, component, version) USING BTREE + ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC; + `.replace(/\n/g, '') + + return new Promise((resolve, reject) => { + this.query(sqlContent, (error, result) => { + if (error) { + reject(error) + } else { + resolve(result) + } + }) + }) + } + + /** + * 初始化组件表 + * @returns promise + */ + initUserComponentsTable() { + return new Promise((resolve, reject) => { + // 查询是否已存在表 + this.query(`SHOW TABLES LIKE '${componentsTableName}'`, (error, result) => { + if (error) { + reject(error) + } else if (result.length) { + // 已存在 + resolve() + } else { + this.createUserComponentsTable() + .then(() => { + resolve() + }) + .catch((err) => { + reject(err) + }) + } + }) + }) } } diff --git a/scripts/logger.mjs b/scripts/logger.mjs new file mode 100644 index 0000000000..ae154e9f92 --- /dev/null +++ b/scripts/logger.mjs @@ -0,0 +1,28 @@ +import colors from 'picocolors' + +const logger = {} +const loggerTypes = ['info', 'warn', 'error', 'success'] + +const output = (type, msg) => { + const format = () => { + const colorMap = { + info: 'cyan', + warn: 'yellow', + error: 'red', + success: 'green' + } + const time = new Date().toLocaleTimeString() + const colorMsg = colors[colorMap[type]](msg) + + return `${colors.dim(time)} ${colorMsg}` + } + + // eslint-disable-next-line no-console + return console.log(format()) +} + +loggerTypes.forEach((type) => { + logger[type] = (msg) => output(type, msg) +}) + +export default logger diff --git a/scripts/splitMaterials.mjs b/scripts/splitMaterials.mjs index f8d660e6a2..b93a30080d 100644 --- a/scripts/splitMaterials.mjs +++ b/scripts/splitMaterials.mjs @@ -1,5 +1,6 @@ import fs from 'fs-extra' import path from 'node:path' +import logger from './logger.mjs' const bundlePath = path.join(process.cwd(), '/packages/design-core/public/mock/bundle.json') const bundle = fs.readJSONSync(bundlePath) @@ -20,7 +21,7 @@ try { }) if (snippet) { - comp.snippet = { ...snippet } + comp.snippets = [snippet] comp.category = child.group return true @@ -30,7 +31,7 @@ try { }) const fileName = Array.isArray(comp.component) ? comp.component[0] : comp.component - const componentPath = path.join(process.cwd(), '/materials/components', `${fileName}.json`) + const componentPath = path.join(process.cwd(), '/materials/components', `${toPascalCase(fileName)}.json`) fs.outputJsonSync(componentPath, comp, { spaces: 2 }) }) @@ -40,6 +41,8 @@ try { fs.outputJsonSync(blockPath, block, { spaces: 2 }) }) + + logger.success('拆分物料资产包完成') } catch (error) { - throw new Error(`拆分物料资产包失败, ${error}`) + logger.error(`拆分物料资产包失败: ${error}`) } From 9174c346d2db41bc3322bb2de277d085b0ea3ee7 Mon Sep 17 00:00:00 2001 From: yaoyun8 Date: Wed, 27 Dec 2023 01:17:35 -0800 Subject: [PATCH 03/16] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E5=A4=8D=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/connection.mjs | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/scripts/connection.mjs b/scripts/connection.mjs index 12afa04f78..4560b7b523 100644 --- a/scripts/connection.mjs +++ b/scripts/connection.mjs @@ -80,7 +80,7 @@ class MysqlConnection { */ updateComponent(component) { const values = [] - let sqlContent = 'update user_components set ' + let sqlContent = `update ${componentsTableName} set ` Object.keys(component).forEach((key) => { const { [key]: value } = component @@ -182,7 +182,7 @@ class MysqlConnection { '${updatedBy}', );` - const sqlContent = `INSERT INTO user_components (version, name, component, icon, description, doc_url, + const sqlContent = `INSERT INTO ${componentsTableName} (version, name, component, icon, description, doc_url, screenshot, tags, keywords, dev_mode, npm, \`group\`, \`category\`, priority, snippets, schema_fragment, configure, \`public\`, framework, isOfficial, isDefault, tiny_reserved, component_metadata, tenant, library, createdBy, updatedBy) VALUES ${values}`.replace(/\n/g, '') @@ -201,7 +201,7 @@ class MysqlConnection { * @param {object} component 组件数据 */ initDB(component) { - const selectSqlContent = `SELECT * FROM components.user_components WHERE component = '${component.component}'` + const selectSqlContent = `SELECT * FROM ${this.config.database}.${componentsTableName} WHERE component = '${component.component}'` this.query(selectSqlContent) .then((result) => { @@ -261,8 +261,10 @@ class MysqlConnection { return new Promise((resolve, reject) => { this.query(sqlContent, (error, result) => { if (error) { + logger.success(`创建表 ${componentsTableName} 失败:${error}`) reject(error) } else { + logger.success(`创建表 ${componentsTableName} 成功`) resolve(result) } }) @@ -276,22 +278,24 @@ class MysqlConnection { initUserComponentsTable() { return new Promise((resolve, reject) => { // 查询是否已存在表 - this.query(`SHOW TABLES LIKE '${componentsTableName}'`, (error, result) => { - if (error) { + this.query(`SHOW TABLES LIKE '${componentsTableName}'`) + .then((result) => { + if (result.length) { + // 已存在 + resolve() + } else { + this.createUserComponentsTable() + .then(() => { + resolve() + }) + .catch((err) => { + reject(err) + }) + } + }) + .catch((error) => { reject(error) - } else if (result.length) { - // 已存在 - resolve() - } else { - this.createUserComponentsTable() - .then(() => { - resolve() - }) - .catch((err) => { - reject(err) - }) - } - }) + }) }) } } From af0ff353844bea410fd09ff970d09e0c1479ff5a Mon Sep 17 00:00:00 2001 From: yaoyun8 Date: Wed, 27 Dec 2023 01:48:37 -0800 Subject: [PATCH 04/16] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E5=A4=8D=E6=8F=92?= =?UTF-8?q?=E5=85=A5=E7=BB=84=E4=BB=B6=E6=95=B0=E6=8D=AEsql=E8=AF=AD?= =?UTF-8?q?=E5=8F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/connection.mjs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/connection.mjs b/scripts/connection.mjs index 4560b7b523..0b62f5c0f8 100644 --- a/scripts/connection.mjs +++ b/scripts/connection.mjs @@ -70,6 +70,10 @@ class MysqlConnection { * @returns 格式化后的字符串 */ formatSingleQuoteValue(str) { + if (typeof str !== 'string') { + return str + } + return str.replace(/'/g, "\\'") } @@ -175,9 +179,7 @@ class MysqlConnection { '${isOfficial}', '${isDefault}', '${tiny_reserved}', - '${component_metadata}', '${tenant}', - '${library}', '${createBy}', '${updatedBy}', );` @@ -185,7 +187,7 @@ class MysqlConnection { const sqlContent = `INSERT INTO ${componentsTableName} (version, name, component, icon, description, doc_url, screenshot, tags, keywords, dev_mode, npm, \`group\`, \`category\`, priority, snippets, schema_fragment, configure, \`public\`, framework, isOfficial, isDefault, tiny_reserved, - component_metadata, tenant, library, createdBy, updatedBy) VALUES ${values}`.replace(/\n/g, '') + tenant, createdBy, updatedBy) VALUES ${values}`.replace(/\n/g, '') this.query(sqlContent, componentName) .then(() => { From 4435955e0d408b4938fa3d7e11032cc3715fce6f Mon Sep 17 00:00:00 2001 From: yaoyun8 Date: Wed, 27 Dec 2023 01:55:25 -0800 Subject: [PATCH 05/16] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E5=A4=8D=E6=8F=92?= =?UTF-8?q?=E5=85=A5=E7=BB=84=E4=BB=B6=E6=95=B0=E6=8D=AEsql=E8=AF=AD?= =?UTF-8?q?=E5=8F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/connection.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/connection.mjs b/scripts/connection.mjs index 0b62f5c0f8..bffc481145 100644 --- a/scripts/connection.mjs +++ b/scripts/connection.mjs @@ -181,7 +181,7 @@ class MysqlConnection { '${tiny_reserved}', '${tenant}', '${createBy}', - '${updatedBy}', + '${updatedBy}' );` const sqlContent = `INSERT INTO ${componentsTableName} (version, name, component, icon, description, doc_url, From b0338712de9403492d322c647edf386f97a8545f Mon Sep 17 00:00:00 2001 From: yaoyun8 Date: Wed, 27 Dec 2023 01:58:25 -0800 Subject: [PATCH 06/16] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E5=A4=8D=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E7=BB=84=E4=BB=B6sql=E8=AF=AD=E5=8F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/connection.mjs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/connection.mjs b/scripts/connection.mjs index bffc481145..c895d20dea 100644 --- a/scripts/connection.mjs +++ b/scripts/connection.mjs @@ -151,9 +151,7 @@ class MysqlConnection { isOfficial = 0, isDefault = 0, tiny_reserved = 0, - component_metadata = null, - tenant = null, - library = null, + tenant = 1, createBy = 86, updatedBy = 86 } = component From 9abb6a30555cd9889f47c5c7faa8976a2e1b20c7 Mon Sep 17 00:00:00 2001 From: yaoyun8 Date: Wed, 27 Dec 2023 02:07:18 -0800 Subject: [PATCH 07/16] =?UTF-8?q?fix=EF=BC=9A=E5=88=9B=E5=BB=BA=E8=A1=A8?= =?UTF-8?q?=E5=BC=82=E6=AD=A5=E6=89=A7=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/connection.mjs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/connection.mjs b/scripts/connection.mjs index c895d20dea..ce6dd5078d 100644 --- a/scripts/connection.mjs +++ b/scripts/connection.mjs @@ -259,15 +259,15 @@ class MysqlConnection { `.replace(/\n/g, '') return new Promise((resolve, reject) => { - this.query(sqlContent, (error, result) => { - if (error) { - logger.success(`创建表 ${componentsTableName} 失败:${error}`) - reject(error) - } else { + this.query(sqlContent) + .then((result) => { logger.success(`创建表 ${componentsTableName} 成功`) resolve(result) - } - }) + }) + .catch((error) => { + logger.success(`创建表 ${componentsTableName} 失败:${error}`) + reject(error) + }) }) } From af2452e42eade72fb36791ce055fea2237b94017 Mon Sep 17 00:00:00 2001 From: yaoyun8 Date: Wed, 27 Dec 2023 17:52:55 -0800 Subject: [PATCH 08/16] =?UTF-8?q?fix=EF=BC=9A=E8=A1=A5=E5=85=85=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/buildMaterials.mjs | 24 +++++++++++++++ scripts/connection.mjs | 21 +++++++------ scripts/logger.mjs | 2 +- scripts/splitMaterials.mjs | 62 +++++++++++++++++++++----------------- 4 files changed, 72 insertions(+), 37 deletions(-) diff --git a/scripts/buildMaterials.mjs b/scripts/buildMaterials.mjs index 53105bab69..4c612e0ec9 100644 --- a/scripts/buildMaterials.mjs +++ b/scripts/buildMaterials.mjs @@ -22,11 +22,20 @@ const bundle = { } const connection = new MysqlConnection() +/** + * 更新物料资产包和应用mock数据 + */ const write = () => { fsExtra.outputJSONSync(bundlePath, bundle, { spaces: 2 }) fsExtra.outputJSONSync(appInfoPath, appInfo, { spaces: 2 }) } +/** + * 校验组件文件数据 + * @param {string} file 组件文件路径 + * @param {object} component 组件数据 + * @returns + */ const validateComponent = (file, component) => { const requiredFields = ['component'] const fields = Object.keys(component) @@ -47,6 +56,12 @@ const validateComponent = (file, component) => { return true } +/** + * 校验区块文件数据 + * @param {string} file 区块文件路径 + * @param {object} block 区块数据 + * @returns + */ const validateBlock = (file, block) => { const requiredFields = ['label', 'assets'] const fields = Object.keys(block) @@ -61,6 +76,12 @@ const validateBlock = (file, block) => { return true } +/** + * 读取materials目录下的json文件,执行下列操作 + * 1. 合并生成物料资产包 + * 2. 更新应用的组件数据componentsMap + * 3. 连接上数据库后,将组件数据写入数据库(新增或更新) + */ const generateComponents = () => { try { fg(['materials/**/*.json']).then((files) => { @@ -130,6 +151,7 @@ const generateComponents = () => { } } +// 监听materials下json文件的变化 const watcher = chokidar.watch('materials/**/*.json', { ignoreInitial: true }) watcher.on('all', (event, file) => { @@ -155,6 +177,7 @@ watcher.on('all', (event, file) => { } }) +// 连接数据库 connection .connect() .then(() => { @@ -163,5 +186,6 @@ connection }) }) .catch(() => { + // 未能连接数据库也可以执行更新本地mock数据 generateComponents() }) diff --git a/scripts/connection.mjs b/scripts/connection.mjs index ce6dd5078d..499897d49b 100644 --- a/scripts/connection.mjs +++ b/scripts/connection.mjs @@ -2,16 +2,19 @@ import mysql from 'mysql' import logger from './logger.mjs' +// 组件表名称 const componentsTableName = 'user_components' +// 数据库配置 +const mysqlConfig = { + host: 'localhost', // 主机名(服务器地址) + port: '3306', // 端口号 + user: 'root', // 用户名 + password: 'admin', // 密码 + database: 'components' // 数据库名称 +} class MysqlConnection { constructor(config) { - this.config = config || { - host: 'localhost', // 主机名(服务器地址) - port: '3306', // 端口号 - user: 'root', // 用户名 - password: 'password', // 密码 - database: 'components' // 数据库名称 - } + this.config = config || mysqlConfig // 是否连接上了数据库 this.connected = false this.connection = mysql.createConnection(this.config) @@ -21,7 +24,7 @@ class MysqlConnection { return new Promise((resolve, reject) => { this.connection.connect((error) => { if (error) { - logger.warn('连接数据库失败') + logger.warn('未能连接到数据库,请查看数据库配置是否正确') reject() } else { logger.success('连接数据库成功') @@ -272,7 +275,7 @@ class MysqlConnection { } /** - * 初始化组件表 + * 初始化数据库的组件表 * @returns promise */ initUserComponentsTable() { diff --git a/scripts/logger.mjs b/scripts/logger.mjs index ae154e9f92..9b56add05e 100644 --- a/scripts/logger.mjs +++ b/scripts/logger.mjs @@ -14,7 +14,7 @@ const output = (type, msg) => { const time = new Date().toLocaleTimeString() const colorMsg = colors[colorMap[type]](msg) - return `${colors.dim(time)} ${colorMsg}` + return `[buildMaterials] [${colors.dim(time)}] ${colorMsg}` } // eslint-disable-next-line no-console diff --git a/scripts/splitMaterials.mjs b/scripts/splitMaterials.mjs index b93a30080d..5c0cdd61b6 100644 --- a/scripts/splitMaterials.mjs +++ b/scripts/splitMaterials.mjs @@ -3,46 +3,54 @@ import path from 'node:path' import logger from './logger.mjs' const bundlePath = path.join(process.cwd(), '/packages/design-core/public/mock/bundle.json') +const materialsDir = '/materials' const bundle = fs.readJSONSync(bundlePath) const { components, snippets, blocks } = bundle.data.materials const capitalize = (str) => `${str.charAt(0).toUpperCase()}${str.slice(1)}` const toPascalCase = (str) => str.split('-').map(capitalize).join('') -try { - components.forEach((comp) => { - snippets.some((child) => { - const snippet = child.children.find((item) => { - if (Array.isArray(comp.component)) { - return toPascalCase(comp.component[0]) === toPascalCase(item.snippetName) +/** + * 将物料资产包拆分为单个组件 + */ +const splitMaterials = () => { + try { + components.forEach((comp) => { + snippets.some((child) => { + const snippet = child.children.find((item) => { + if (Array.isArray(comp.component)) { + return toPascalCase(comp.component[0]) === toPascalCase(item.snippetName) + } + + return toPascalCase(comp.component) === toPascalCase(item.snippetName) + }) + + if (snippet) { + comp.snippets = [snippet] + comp.category = child.group + + return true } - return toPascalCase(comp.component) === toPascalCase(item.snippetName) + return false }) - if (snippet) { - comp.snippets = [snippet] - comp.category = child.group + const fileName = Array.isArray(comp.component) ? comp.component[0] : comp.component + const componentPath = path.join(process.cwd(), materialsDir, 'components', `${toPascalCase(fileName)}.json`) - return true - } - - return false + fs.outputJsonSync(componentPath, comp, { spaces: 2 }) }) - const fileName = Array.isArray(comp.component) ? comp.component[0] : comp.component - const componentPath = path.join(process.cwd(), '/materials/components', `${toPascalCase(fileName)}.json`) - - fs.outputJsonSync(componentPath, comp, { spaces: 2 }) - }) - - blocks.forEach((block) => { - const blockPath = path.join(process.cwd(), '/materials/blocks', `${block.label}.json`) + blocks.forEach((block) => { + const blockPath = path.join(process.cwd(), materialsDir, 'blocks', `${block.label}.json`) - fs.outputJsonSync(blockPath, block, { spaces: 2 }) - }) + fs.outputJsonSync(blockPath, block, { spaces: 2 }) + }) - logger.success('拆分物料资产包完成') -} catch (error) { - logger.error(`拆分物料资产包失败: ${error}`) + logger.success('拆分物料资产包完成') + } catch (error) { + logger.error(`拆分物料资产包失败: ${error}`) + } } + +splitMaterials() From 4866652227fc77af3604ed22108a3fa2f2270c96 Mon Sep 17 00:00:00 2001 From: yaoyun8 Date: Wed, 27 Dec 2023 18:59:23 -0800 Subject: [PATCH 09/16] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E6=94=B9=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E6=95=B0=E6=8D=AE=E5=BA=93=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/connection.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/connection.mjs b/scripts/connection.mjs index 499897d49b..539e175575 100644 --- a/scripts/connection.mjs +++ b/scripts/connection.mjs @@ -10,7 +10,7 @@ const mysqlConfig = { port: '3306', // 端口号 user: 'root', // 用户名 password: 'admin', // 密码 - database: 'components' // 数据库名称 + database: 'tiny_engine' // 数据库名称 } class MysqlConnection { constructor(config) { From 1e81b8d03a33c23b313bdb583c70e1205b75f53b Mon Sep 17 00:00:00 2001 From: yaoyun8 Date: Wed, 27 Dec 2023 19:08:33 -0800 Subject: [PATCH 10/16] =?UTF-8?q?fix=EF=BC=9A=E6=8F=90=E5=8F=96=E7=89=A9?= =?UTF-8?q?=E6=96=99=E4=BF=9D=E5=AD=98=E6=96=87=E4=BB=B6=E5=A4=B9=E5=90=8D?= =?UTF-8?q?=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/buildMaterials.mjs | 10 ++++++++-- scripts/splitMaterials.mjs | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/scripts/buildMaterials.mjs b/scripts/buildMaterials.mjs index 4c612e0ec9..94c6d2b7f2 100644 --- a/scripts/buildMaterials.mjs +++ b/scripts/buildMaterials.mjs @@ -5,6 +5,8 @@ import fg from 'fast-glob' import MysqlConnection from './connection.mjs' import logger from './logger.mjs' +// 物料文件存放文件夹名称 +const materialsDir = 'materials' // 物料资产包 const bundlePath = path.join(process.cwd(), '/packages/design-core/public/mock/bundle.json') // mockServer应用数据 @@ -84,7 +86,11 @@ const validateBlock = (file, block) => { */ const generateComponents = () => { try { - fg(['materials/**/*.json']).then((files) => { + fg([`${materialsDir}/**/*.json`]).then((files) => { + if(!files.length) { + logger.warn('物料文件夹为空,请检查路径') + } + const { components = [], snippets = [], blocks = [] } = bundle.data.materials const componentsMap = [] const appInfoBlocksLabels = appInfo.blockHistories.map((item) => item.label) @@ -152,7 +158,7 @@ const generateComponents = () => { } // 监听materials下json文件的变化 -const watcher = chokidar.watch('materials/**/*.json', { ignoreInitial: true }) +const watcher = chokidar.watch(`${materialsDir}/**/*.json`, { ignoreInitial: true }) watcher.on('all', (event, file) => { const eventMap = { diff --git a/scripts/splitMaterials.mjs b/scripts/splitMaterials.mjs index 5c0cdd61b6..0965a8e7d1 100644 --- a/scripts/splitMaterials.mjs +++ b/scripts/splitMaterials.mjs @@ -2,8 +2,10 @@ import fs from 'fs-extra' import path from 'node:path' import logger from './logger.mjs' +// 物料资产包mock数据路径 const bundlePath = path.join(process.cwd(), '/packages/design-core/public/mock/bundle.json') -const materialsDir = '/materials' +// 物料文件存放文件夹名称 +const materialsDir = 'materials' const bundle = fs.readJSONSync(bundlePath) const { components, snippets, blocks } = bundle.data.materials From 4ea2f6724ee999e61ae7f979daab5137d83c0db5 Mon Sep 17 00:00:00 2001 From: yaoyun8 Date: Wed, 27 Dec 2023 22:49:36 -0800 Subject: [PATCH 11/16] =?UTF-8?q?fix=EF=BC=9A=E4=BC=98=E5=8C=96logger?= =?UTF-8?q?=E8=BE=93=E5=87=BA=E8=AF=AD=E5=8F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/buildMaterials.mjs | 6 +++-- scripts/connection.mjs | 18 +++++++++++-- scripts/logger.mjs | 55 ++++++++++++++++++++++++-------------- scripts/splitMaterials.mjs | 4 ++- 4 files changed, 58 insertions(+), 25 deletions(-) diff --git a/scripts/buildMaterials.mjs b/scripts/buildMaterials.mjs index 94c6d2b7f2..10db7787fe 100644 --- a/scripts/buildMaterials.mjs +++ b/scripts/buildMaterials.mjs @@ -3,8 +3,9 @@ import path from 'node:path' import chokidar from 'chokidar' import fg from 'fast-glob' import MysqlConnection from './connection.mjs' -import logger from './logger.mjs' +import Logger from './logger.mjs' +const logger = new Logger('buildMaterials') // 物料文件存放文件夹名称 const materialsDir = 'materials' // 物料资产包 @@ -22,6 +23,7 @@ const bundle = { } } } + const connection = new MysqlConnection() /** @@ -88,7 +90,7 @@ const generateComponents = () => { try { fg([`${materialsDir}/**/*.json`]).then((files) => { if(!files.length) { - logger.warn('物料文件夹为空,请检查路径') + logger.warn('物料文件夹为空,请先执行`pnpm splitMaterials`命令拆分物料资产包') } const { components = [], snippets = [], blocks = [] } = bundle.data.materials diff --git a/scripts/connection.mjs b/scripts/connection.mjs index 539e175575..8ac5a621fc 100644 --- a/scripts/connection.mjs +++ b/scripts/connection.mjs @@ -1,7 +1,8 @@ // const mysql = require('mysql') import mysql from 'mysql' -import logger from './logger.mjs' +import Logger from './logger.mjs' +const logger = new Logger('buildMaterials') // 组件表名称 const componentsTableName = 'user_components' // 数据库配置 @@ -125,6 +126,16 @@ class MysqlConnection { }) } + /** + * 新建的组件关联物料资产包 + * @param {number} id 新建的组件id + */ + relationMaterialHistory(id) { + const sqlContent = `INSERT INTO \`material_histories_components__user_components_mhs\` (\`material-history_id\`, \`user-component_id\`) VALUES (639, ${id})` + + this.query(sqlContent) + } + /** * 生成新增组件的sql语句 * @param {object} component 组件数据 @@ -191,8 +202,11 @@ class MysqlConnection { tenant, createdBy, updatedBy) VALUES ${values}`.replace(/\n/g, '') this.query(sqlContent, componentName) - .then(() => { + .then((result) => { + const id = result.insertId + logger.success(`新增组件 ${component.component} 成功`) + this.relationMaterialHistory(id) }) .catch((error) => { logger.success(`新增组件 ${component.component} 失败:${error}`) diff --git a/scripts/logger.mjs b/scripts/logger.mjs index 9b56add05e..e7e8657565 100644 --- a/scripts/logger.mjs +++ b/scripts/logger.mjs @@ -1,28 +1,43 @@ import colors from 'picocolors' -const logger = {} -const loggerTypes = ['info', 'warn', 'error', 'success'] - -const output = (type, msg) => { - const format = () => { - const colorMap = { - info: 'cyan', - warn: 'yellow', - error: 'red', - success: 'green' +class Logger { + constructor(command) { + this.command = command + } + + output(type, msg) { + const format = () => { + const colorMap = { + info: 'cyan', + warn: 'yellow', + error: 'red', + success: 'green' + } + const time = new Date().toLocaleTimeString() + const colorMsg = colors[colorMap[type]](msg) + + return `[${this.command}] [${colors.dim(time)}] ${colorMsg}` } - const time = new Date().toLocaleTimeString() - const colorMsg = colors[colorMap[type]](msg) - return `[buildMaterials] [${colors.dim(time)}] ${colorMsg}` + // eslint-disable-next-line no-console + return console.log(format()) } - // eslint-disable-next-line no-console - return console.log(format()) -} + info(msg) { + this.output('info', msg) + } -loggerTypes.forEach((type) => { - logger[type] = (msg) => output(type, msg) -}) + warn(msg) { + this.output('warn', msg) + } + + error(msg) { + this.output('error', msg) + } + + success(msg) { + this.output('success', msg) + } +} -export default logger +export default Logger diff --git a/scripts/splitMaterials.mjs b/scripts/splitMaterials.mjs index 0965a8e7d1..e81143c0b1 100644 --- a/scripts/splitMaterials.mjs +++ b/scripts/splitMaterials.mjs @@ -1,6 +1,8 @@ import fs from 'fs-extra' import path from 'node:path' -import logger from './logger.mjs' +import Logger from './logger.mjs' + +const logger = new Logger('splitMaterials') // 物料资产包mock数据路径 const bundlePath = path.join(process.cwd(), '/packages/design-core/public/mock/bundle.json') From 40c4b708360534b3ab5d41c03c334c24dca0914e Mon Sep 17 00:00:00 2001 From: yaoyun8 Date: Thu, 28 Dec 2023 00:14:20 -0800 Subject: [PATCH 12/16] =?UTF-8?q?fix=EF=BC=9A=E5=88=A0=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/connection.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/connection.mjs b/scripts/connection.mjs index 8ac5a621fc..d5d4c57ae4 100644 --- a/scripts/connection.mjs +++ b/scripts/connection.mjs @@ -1,4 +1,3 @@ -// const mysql = require('mysql') import mysql from 'mysql' import Logger from './logger.mjs' From 14a4f1ebd816be2718c34bd61f0fb2196e697746 Mon Sep 17 00:00:00 2001 From: yaoyun8 Date: Thu, 28 Dec 2023 00:16:22 -0800 Subject: [PATCH 13/16] =?UTF-8?q?fix=EF=BC=9A=E6=8F=90=E5=8F=96=E7=89=A9?= =?UTF-8?q?=E6=96=99=E8=B5=84=E4=BA=A7=E5=8C=85=E5=85=B3=E8=81=94id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/connection.mjs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/connection.mjs b/scripts/connection.mjs index d5d4c57ae4..b8665bc49c 100644 --- a/scripts/connection.mjs +++ b/scripts/connection.mjs @@ -4,6 +4,8 @@ import Logger from './logger.mjs' const logger = new Logger('buildMaterials') // 组件表名称 const componentsTableName = 'user_components' +// 组件关联到物料资产包的id +const materialHistoryId = 639 // 数据库配置 const mysqlConfig = { host: 'localhost', // 主机名(服务器地址) @@ -130,7 +132,7 @@ class MysqlConnection { * @param {number} id 新建的组件id */ relationMaterialHistory(id) { - const sqlContent = `INSERT INTO \`material_histories_components__user_components_mhs\` (\`material-history_id\`, \`user-component_id\`) VALUES (639, ${id})` + const sqlContent = `INSERT INTO \`material_histories_components__user_components_mhs\` (\`material-history_id\`, \`user-component_id\`) VALUES (${materialHistoryId}, ${id})` this.query(sqlContent) } From 399f401d43b940308a9e051bc8ba763d66d29c0f Mon Sep 17 00:00:00 2001 From: yaoyun8 Date: Thu, 28 Dec 2023 05:29:35 -0800 Subject: [PATCH 14/16] =?UTF-8?q?fix=EF=BC=9Asql=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=8F=90=E5=8F=96env?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.local | 5 +++++ package.json | 1 + scripts/connection.mjs | 23 ++++++++++++++++++----- 3 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 .env.local diff --git a/.env.local b/.env.local new file mode 100644 index 0000000000..a361a78c8f --- /dev/null +++ b/.env.local @@ -0,0 +1,5 @@ +SQL_HOST=localhost +SQL_PORT=3306 +SQL_USER=root +SQL_PASSWORD=admin +SQL_DATABASE=tiny_engine \ No newline at end of file diff --git a/package.json b/package.json index c80c7de2f5..328eb7d3d4 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "chokidar": "^3.5.3", "concurrently": "^8.2.0", "cross-env": "^7.0.3", + "dotenv": "^16.3.1", "eslint": "^8.38.0", "eslint-plugin-vue": "^8.0.0", "fast-glob": "^3.3.2", diff --git a/scripts/connection.mjs b/scripts/connection.mjs index b8665bc49c..57fb0d8faa 100644 --- a/scripts/connection.mjs +++ b/scripts/connection.mjs @@ -1,18 +1,31 @@ import mysql from 'mysql' import Logger from './logger.mjs' +import fs from 'node:fs' +import path from 'node:path' +import dotenv from 'dotenv' +// 先构造出.env*文件的绝对路径 +const appDirectory = fs.realpathSync(process.cwd()); +const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath); +const pathsDotenv = resolveApp(".env"); + +// 加载.env.local +dotenv.config({ path: `${pathsDotenv}.local` }) + +const { SQL_HOST, SQL_PORT, SQL_USER, SQL_PASSWORD, SQL_DATABASE } = process.env const logger = new Logger('buildMaterials') +logger.info(`${SQL_HOST}、${SQL_PORT}`) // 组件表名称 const componentsTableName = 'user_components' // 组件关联到物料资产包的id const materialHistoryId = 639 // 数据库配置 const mysqlConfig = { - host: 'localhost', // 主机名(服务器地址) - port: '3306', // 端口号 - user: 'root', // 用户名 - password: 'admin', // 密码 - database: 'tiny_engine' // 数据库名称 + host: SQL_HOST, // 主机名(服务器地址) + port: SQL_PORT, // 端口号 + user: SQL_USER, // 用户名 + password: SQL_PASSWORD, // 密码 + database: SQL_DATABASE // 数据库名称 } class MysqlConnection { constructor(config) { From 33d8f34dca921abfec66a1533b95b7cdaa7c1b0e Mon Sep 17 00:00:00 2001 From: yaoyun8 Date: Thu, 28 Dec 2023 18:14:10 -0800 Subject: [PATCH 15/16] =?UTF-8?q?fix=EF=BC=9A=E5=88=A0=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/connection.mjs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/scripts/connection.mjs b/scripts/connection.mjs index 57fb0d8faa..ed00c6980c 100644 --- a/scripts/connection.mjs +++ b/scripts/connection.mjs @@ -4,17 +4,16 @@ import fs from 'node:fs' import path from 'node:path' import dotenv from 'dotenv' -// 先构造出.env*文件的绝对路径 -const appDirectory = fs.realpathSync(process.cwd()); -const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath); -const pathsDotenv = resolveApp(".env"); +const logger = new Logger('buildMaterials') +// 先构造出.env*文件的绝对路径 +const appDirectory = fs.realpathSync(process.cwd()) +const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath) +const pathsDotenv = resolveApp('.env') // 加载.env.local dotenv.config({ path: `${pathsDotenv}.local` }) - const { SQL_HOST, SQL_PORT, SQL_USER, SQL_PASSWORD, SQL_DATABASE } = process.env -const logger = new Logger('buildMaterials') -logger.info(`${SQL_HOST}、${SQL_PORT}`) + // 组件表名称 const componentsTableName = 'user_components' // 组件关联到物料资产包的id From a091a83f45821f94bae63652e08581229a19ce54 Mon Sep 17 00:00:00 2001 From: yaoyun8 Date: Thu, 28 Dec 2023 18:52:35 -0800 Subject: [PATCH 16/16] =?UTF-8?q?fix=EF=BC=9A=E7=89=A9=E6=96=99=E8=B5=84?= =?UTF-8?q?=E4=BA=A7=E5=8C=85=E5=85=B3=E8=81=94=E8=A1=A8=E5=94=AF=E4=B8=80?= =?UTF-8?q?=E6=80=A7=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/connection.mjs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/scripts/connection.mjs b/scripts/connection.mjs index ed00c6980c..e973b529bb 100644 --- a/scripts/connection.mjs +++ b/scripts/connection.mjs @@ -144,9 +144,14 @@ class MysqlConnection { * @param {number} id 新建的组件id */ relationMaterialHistory(id) { - const sqlContent = `INSERT INTO \`material_histories_components__user_components_mhs\` (\`material-history_id\`, \`user-component_id\`) VALUES (${materialHistoryId}, ${id})` + const uniqSql = `SELECT * FROM \`material_histories_components__user_components_mhs\` WHERE \`material-history_id\`=${materialHistoryId} AND \`user-component_id\`=${id}` + this.query(uniqSql).then((result) => { + if (!result.length) { + const sqlContent = `INSERT INTO \`material_histories_components__user_components_mhs\` (\`material-history_id\`, \`user-component_id\`) VALUES (${materialHistoryId}, ${id})` - this.query(sqlContent) + this.query(sqlContent) + } + }) } /**