| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 |
- import { appTasks } from '@ohos/hvigor-ohos-plugin';
- import { HvigorPlugin, HvigorNode } from '@ohos/hvigor';
- import fs from 'fs';
- import path from 'path';
- function customPlugin(): HvigorPlugin {
- return {
- pluginId: 'customPlugin',
- apply(node: HvigorNode) {
- try {
- // console.log('node', JSON.stringify(node))
- // 根据node对象结构获取项目路径
- const projectPath = node.nodeDir.filePath;
- console.log('目标路径:', projectPath);
- // 获取所有子模块
- const modules = node.allSubNodes.filter(subNode => subNode.node.classKind === 'module');
- console.log('模块数量:', modules.length);
- // 打印每个模块的路径
- const modulePaths = [];
- modules.forEach((module, index) => {
- try {
- // 从module.node._nodePath获取模块路径
- const modulePath = module.node._nodePath;
- if (modulePath) {
- console.log(`模块 ${index + 1} 路径:`, modulePath);
- modulePaths.push(modulePath);
- } else {
- console.log(`模块 ${index + 1} 路径: 无法获取路径`);
- }
- } catch (error) {
- console.error(`获取模块 ${index + 1} 路径时出错:`, error);
- }
- });
- // 遍历并处理所有模块
- modulePaths.forEach((modulePath, index) => {
- console.log(`处理模块 ${index + 1}:`, modulePath);
- processModule(modulePath, projectPath);
- });
- } catch (error) {
- console.error('Error in custom plugin:', error);
- }
- }
- }
- function processModule(modulePath: string, projectPath: string) {
- try {
- // 构建pages目录路径 (基于模块路径)
- const pagesPath = path.join(modulePath, 'src', 'main', 'ets', 'pages');
- console.log('pages路径:', pagesPath);
- // 构建profile目录路径 (基于模块路径)
- const rawfilePath = path.join(modulePath, 'src', 'main', 'resources', 'base', 'profile');
- console.log('profile路径:', rawfilePath);
- // 确保profile目录存在
- if (!fs.existsSync(rawfilePath)) {
- fs.mkdirSync(rawfilePath, { recursive: true });
- }
- // router_map.json文件路径
- const routerMapPath = path.join(rawfilePath, 'router_map.json');
- // module.json5文件路径
- const moduleJsonPath = path.join(modulePath, 'src', 'main', 'module.json5');
- // 初始化routerMap
- let routerMap = {
- routerMap: []
- };
- // 如果router_map.json文件已存在,则读取现有内容
- if (fs.existsSync(routerMapPath)) {
- try {
- const existingContent = fs.readFileSync(routerMapPath, 'utf8');
- routerMap = JSON.parse(existingContent);
- console.log('读取现有的router_map.json文件');
- } catch (error) {
- console.error('读取router_map.json文件出错:', error);
- }
- }
- // 检查pages目录是否存在
- if (fs.existsSync(pagesPath)) {
- // 读取目录内容
- const files = fs.readdirSync(pagesPath);
- console.log(`Found ${files.length} files/directories in pages folder:`);
- // 遍历并处理每个文件
- files.forEach((file, index) => {
- const fullPath = path.join(pagesPath, file);
- const stat = fs.statSync(fullPath);
- const type = stat.isDirectory() ? '[DIR]' : '[FILE]';
- console.log(`${index + 1}. ${type} ${file}`);
- // 如果是文件,读取文件内容
- if (!stat.isDirectory() && file.endsWith('.ets')) {
- try {
- const content = fs.readFileSync(fullPath, 'utf8');
- // console.log(`Content of ${file}:`);
- // console.log(content);
- // 检查是否有@RouterPage修饰器
- if (content.includes('@RouterPage')) {
- // 生成Builder函数名(去掉Page后缀,加上Builder后缀)
- const fileNameWithoutExtension = file.replace('.ets', '');
- const builderName = fileNameWithoutExtension.replace(/Page$/, '') + 'Builder';
- // 检查是否已经存在Builder函数
- const builderRegex = new RegExp(`@Builder\\s+function\\s+${builderName}\\s*\\(\\)`, 'g');
- if (!builderRegex.test(content)) {
- // 构造新的内容,在文件末尾添加Builder函数
- const structName = fileNameWithoutExtension; // 假设struct名称与文件名相同
- const builderFunction = `\n@Builder\nfunction ${builderName}() {\n ${structName}()\n}\n`;
- const newContent = content + builderFunction;
- // 写入文件
- fs.writeFileSync(fullPath, newContent, 'utf8');
- console.log(`Added ${builderName} function to ${file}`);
- } else {
- console.log(`Builder function ${builderName} already exists in ${file}`);
- }
- // 添加到routerMap中
- const pageEntry = {
- name: fileNameWithoutExtension,
- pageSourceFile: `src/main/ets/pages/${file}`,
- buildFunction: builderName
- };
- // 检查是否已存在该条目
- const existingIndex = routerMap.routerMap.findIndex(item => item.name === fileNameWithoutExtension);
- if (existingIndex >= 0) {
- // 更新现有条目
- routerMap.routerMap[existingIndex] = pageEntry;
- } else {
- // 添加新条目
- routerMap.routerMap.push(pageEntry);
- }
- }
- console.log('----------------------------------------');
- } catch (readError) {
- console.error(`Error reading file ${file}:`, readError);
- }
- }
- });
- // 将routerMap写入router_map.json文件
- try {
- fs.writeFileSync(routerMapPath, JSON.stringify(routerMap, null, 2), 'utf8');
- console.log('router_map.json文件已更新');
- } catch (writeError) {
- console.error('写入router_map.json文件出错:', writeError);
- }
- // 更新module.json5文件,添加routerMap字段
- try {
- if (fs.existsSync(moduleJsonPath)) {
- const moduleJsonContent = fs.readFileSync(moduleJsonPath, 'utf8');
- // 使用正则表达式在"module": {后添加routerMap字段
- if (moduleJsonContent.includes('"module"')) {
- // 检查是否已经存在routerMap字段
- if (!moduleJsonContent.includes('"routerMap"')) {
- // 在"module": {后添加routerMap字段
- const updatedContent = moduleJsonContent.replace(
- /("module"\s*:\s*{)/,
- '$1\n "routerMap": "$profile:router_map",'
- );
- fs.writeFileSync(moduleJsonPath, updatedContent, 'utf8');
- console.log('module.json5文件已更新,添加了routerMap字段');
- } else {
- console.log('module.json5中已存在routerMap字段');
- }
- } else {
- console.log('module.json5中未找到"module"字段');
- }
- } else {
- console.log('module.json5文件不存在');
- }
- } catch (error) {
- console.error('更新module.json5文件出错:', error);
- }
- } else {
- console.log('Pages directory not found');
- }
- } catch (error) {
- console.error(`处理模块 ${modulePath} 时出错:`, error);
- }
- }
- }
- function rDBPlugin(): HvigorPlugin {
- return {
- pluginId: 'customPlugin',
- apply(node: HvigorNode) {
- try {
- // 根据node对象结构获取项目路径
- const projectPath = node.nodeDir.filePath;
- console.log('目标路径:', projectPath);
- // 获取所有子模块
- const modules = node.allSubNodes.filter(subNode => subNode.node.classKind === 'module');
- console.log('模块数量:', modules.length);
- // 打印每个模块的路径
- const modulePaths = [];
- modules.forEach((module, index) => {
- try {
- // 从module.node._nodePath获取模块路径
- const modulePath = module.node._nodePath;
- if (modulePath) {
- console.log(`模块 ${index + 1} 路径:`, modulePath);
- modulePaths.push(modulePath);
- if (modulePath.includes('basic')) {
- processTables(modulePath)
- }
- } else {
- console.log(`模块 ${index + 1} 路径: 无法获取路径`);
- }
- } catch (error) {
- console.error(`获取模块 ${index + 1} 路径时出错:`, error);
- }
- });
- // 遍历并处理所有模块
- // modulePaths.forEach((modulePath, index) => {
- // console.log(`处理模块 ${index + 1}:`, modulePath);
- // processTables(); // 处理tables目录的逻辑
- // });
- // processTables(modulePaths[])
- } catch (error) {
- console.error('Error in custom plugin:', error);
- }
- }
- }
- function processTables(currentDir:string) {
- try {
- // 构建tables目录路径
- const tablesPath = path.join(currentDir, 'src', 'main', 'ets', 'rdb', 'tables');
- console.log('tables路径:', tablesPath);
- // 检查tables目录是否存在
- if (fs.existsSync(tablesPath)) {
- // 读取目录内容
- const files = fs.readdirSync(tablesPath);
- console.log(`Found ${files.length} files/directories in tables folder:`);
- const tableNames: string[] = [];
- const sqlStatements: string[] = [];
- // 替换原有的字段处理逻辑
- files.forEach((file, index) => {
- const fullPath = path.join(tablesPath, file);
- const stat = fs.statSync(fullPath);
- const type = stat.isDirectory() ? '[DIR]' : '[FILE]';
- console.log(`${index + 1}. ${type} ${file}`);
- // 如果是文件,读取文件内容
- if (!stat.isDirectory() && file.endsWith('.ets')) {
- try {
- const content = fs.readFileSync(fullPath, 'utf8');
- // 使用正则表达式匹配interface名称
- const interfaceRegex = /export\s+interface\s+(\w+)/g;
- let match;
- while ((match = interfaceRegex.exec(content)) !== null) {
- const interfaceName = match[1];
- tableNames.push(interfaceName);
- // 解析接口属性并生成字段
- const fieldDefinitions = parseInterfaceFields(content, interfaceName);
- // 生成CREATE TABLE SQL语句(包含字段)
- const sqlStatement =
- `static readonly CREATE_${interfaceName.toUpperCase()}_TABLE = 'CREATE TABLE IF NOT EXISTS ${interfaceName} (${fieldDefinitions})';`;
- sqlStatements.push(sqlStatement);
- console.log(`Found interface: ${interfaceName}`);
- }
- } catch (readError) {
- console.error(`Error reading file ${file}:`, readError);
- }
- }
- });
- // 添加解析接口字段的辅助函数
- function parseInterfaceFields(content: string, interfaceName: string): string {
- // 查找接口定义区域
- const interfaceStart = content.indexOf(`export interface ${interfaceName}`);
- if (interfaceStart === -1) {
- return 'ID INTEGER PRIMARY KEY AUTOINCREMENT';
- }
- const openBrace = content.indexOf('{', interfaceStart);
- const closeBrace = content.indexOf('}', openBrace);
- if (openBrace === -1 || closeBrace === -1) {
- return 'ID INTEGER PRIMARY KEY AUTOINCREMENT';
- }
- const interfaceBody = content.substring(openBrace + 1, closeBrace);
- const lines = interfaceBody.split('\n');
- const fields: string[] = [];
- let hasPrimaryKey = false;
- lines.forEach(line => {
- const fieldMatch = line.trim().match(/^(\w+)\??\s*:\s*(.+?);?$/);
- if (fieldMatch) {
- const fieldName = fieldMatch[1];
- const fieldType = fieldMatch[2].trim();
- // 根据TypeScript类型映射到SQLite类型
- let sqliteType = 'TEXT';
- if (fieldType.includes('number') || fieldType.includes('Number')) {
- sqliteType = 'INTEGER';
- } else if (fieldType.includes('boolean') || fieldType.includes('Boolean')) {
- sqliteType = 'INTEGER';
- } else if (fieldType.includes('Date')) {
- sqliteType = 'TEXT';
- }
- // 检查是否为主键字段(约定以id命名的字段作为主键)
- if (fieldName.toLowerCase() === 'id') {
- fields.push(`${fieldName} INTEGER PRIMARY KEY AUTOINCREMENT`);
- hasPrimaryKey = true;
- } else {
- // 处理可选字段
- const nullable = line.trim().includes('?') ? '' : ' NOT NULL';
- fields.push(`${fieldName} ${sqliteType}${nullable}`);
- }
- }
- });
- // 如果没有定义主键,则添加默认主键
- if (!hasPrimaryKey) {
- fields.unshift('ID INTEGER PRIMARY KEY AUTOINCREMENT');
- }
- return fields.join(', ');
- }
- // 更新RelationalStoreUtils.ets文件中的tables数组
- const relationalStorePath =
- path.join(currentDir, 'src', 'main', 'ets', 'rdb', 'utils', 'RelationalStoreUtis.ets');
- if (fs.existsSync(relationalStorePath)) {
- let content = fs.readFileSync(relationalStorePath, 'utf8');
- // 更新tables数组
- if (tableNames.length > 0) {
- const tablesArray = `private static tables: string[] = [${tableNames.map(name => `'${name}'`).join(', ')}]`;
- const updatedContent = content.replace(/private static tables: string\[\] = \[[^\]]*\]/, tablesArray);
- fs.writeFileSync(relationalStorePath, updatedContent, 'utf8');
- console.log('RelationalStoreUtis.ets文件已更新');
- }
- }
- // 替换原有的更新RDBSql.ets文件的代码块
- // 更新RDBSql.ts文件
- const rdbSqlPath = path.join(currentDir, 'src', 'main', 'ets', 'rdb', 'sqls', 'RDBSql.ts');
- if (fs.existsSync(rdbSqlPath)) {
- let content = fs.readFileSync(rdbSqlPath, 'utf8');
- // 构建SQL语句对象属性
- if (sqlStatements.length > 0) {
- // 提取属性名和值
- const sqlProperties: string[] = [];
- sqlStatements.forEach(statement => {
- // 从 static readonly CREATE_USER_TABLE = 'CREATE TABLE...' 提取属性
- const propertyName = statement.split('=')[0].trim().replace('static readonly ', '');
- const propertyValue = statement.split('=')[1].trim().slice(1, -2); // 去掉引号和分号
- sqlProperties.push(` ${propertyName}: '${propertyValue}'`);
- });
- // 构建新的对象内容
- const newContent = `export const rDbSql = {\n${sqlProperties.join(',\n')}\n}`;
- fs.writeFileSync(rdbSqlPath, newContent, 'utf8');
- console.log('RDBSql.ts文件已更新为对象形式');
- }
- } else {
- // 如果文件不存在,创建新文件
- if (sqlStatements.length > 0) {
- const sqlProperties: string[] = [];
- sqlStatements.forEach(statement => {
- const propertyName = statement.split('=')[0].trim().replace('static readonly ', '');
- const propertyValue = statement.split('=')[1].trim().slice(1, -2);
- sqlProperties.push(` ${propertyName}: '${propertyValue}'`);
- });
- const newContent = `export const rDbSql = {\n${sqlProperties.join(',\n')}\n}`;
- // 确保目录存在
- const dirPath = path.dirname(rdbSqlPath);
- if (!fs.existsSync(dirPath)) {
- fs.mkdirSync(dirPath, { recursive: true });
- }
- fs.writeFileSync(rdbSqlPath, newContent, 'utf8');
- console.log('RDBSql.ts文件已创建并初始化为对象形式');
- }
- }
- console.log('----------------------------------------');
- } else {
- console.log('Tables directory not found');
- }
- } catch (error) {
- console.error(`处理tables目录时出错:`, error);
- }
- }
- }
- export default {
- system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
- plugins: [
- customPlugin(), // 应用自定义Plugin
- rDBPlugin()
- ] /* Custom plugin to extend the functionality of Hvigor. */
- }
|