befly 3.5.1 → 3.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/index.ts CHANGED
@@ -1,147 +1,34 @@
1
1
  #!/usr/bin/env bun
2
2
  /**
3
3
  * Befly CLI - 命令行工具入口
4
- * Befly 框架提供项目管理和脚本执行功能
4
+ * 只提供 sync 命令,用于同步所有数据
5
+ *
6
+ * 使用方法:
7
+ * befly sync # 使用当前环境(默认 development)
5
8
  *
6
9
  * 环境变量加载:
7
- * 1. Bun 自动加载:根据 NODE_ENV 自动加载 .env.{NODE_ENV} 文件
8
- * 2. 手动指定:bun --env-file=.env.xxx befly <command>
9
- * 3. 默认环境:如未设置 NODE_ENV,Bun 加载 .env.development
10
+ * Bun 自动根据 NODE_ENV 加载对应的 .env 文件:
11
+ * - NODE_ENV=development → .env.development
12
+ * - NODE_ENV=production .env.production
13
+ * - NODE_ENV=test → .env.test
10
14
  */
11
15
 
12
- import { Command } from 'commander';
13
- import { buildCommand } from '../commands/build.js';
14
16
  import { syncCommand } from '../commands/sync.js';
15
- import { syncDbCommand } from '../commands/syncDb.js';
16
- import { syncApiCommand } from '../commands/syncApi.js';
17
- import { syncMenuCommand } from '../commands/syncMenu.js';
18
- import { syncDevCommand } from '../commands/syncDev.js';
19
17
  import { Logger } from '../lib/logger.js';
20
- import { join } from 'pathe';
21
- import { getPackageVersion } from '../commands/util.js';
22
-
23
- /**
24
- * 读取 package.json 版本号
25
- */
26
- function getVersion(): string {
27
- const coreDir = join(import.meta.dir, '..');
28
- return getPackageVersion(coreDir);
29
- }
30
-
31
- /**
32
- * Bun 版本要求
33
- */
34
- const REQUIRED_BUN_VERSION = '1.3.0';
35
18
 
36
19
  /**
37
- * 比较版本号
20
+ * 主函数
38
21
  */
39
- function compareVersions(v1: string, v2: string): number {
40
- const parts1 = v1.split('.').map(Number);
41
- const parts2 = v2.split('.').map(Number);
42
-
43
- for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
44
- const num1 = parts1[i] || 0;
45
- const num2 = parts2[i] || 0;
46
-
47
- if (num1 > num2) return 1;
48
- if (num1 < num2) return -1;
49
- }
50
-
51
- return 0;
52
- }
53
-
54
- /**
55
- * 获取 Bun 版本
56
- */
57
- function getBunVersion(): string | null {
22
+ async function main() {
23
+ // 执行 sync 命令
58
24
  try {
59
- if (typeof Bun !== 'undefined' && Bun.version) {
60
- return Bun.version;
61
- }
62
-
63
- const proc = Bun.spawnSync(['bun', '--version'], {
64
- stdout: 'pipe',
65
- stderr: 'pipe'
66
- });
67
-
68
- if (proc.exitCode === 0) {
69
- const version = proc.stdout.toString().trim();
70
- return version;
71
- }
72
-
73
- return null;
74
- } catch {
75
- return null;
76
- }
77
- }
78
-
79
- /**
80
- * 检查 Bun 版本
81
- */
82
- function checkBunVersion(): void {
83
- const currentVersion = getBunVersion();
84
-
85
- if (!currentVersion) {
86
- Logger.error('未检测到 Bun 运行时');
87
- Logger.info('\nBefly CLI 需要 Bun v1.3.0 或更高版本');
88
- Logger.info('请访问 https://bun.sh 安装 Bun\n');
89
- Logger.info('安装命令:');
90
- Logger.info(' Windows (PowerShell): powershell -c "irm bun.sh/install.ps1 | iex"');
91
- Logger.info(' macOS/Linux: curl -fsSL https://bun.sh/install | bash\n');
92
- process.exit(1);
93
- }
94
-
95
- const comparison = compareVersions(currentVersion, REQUIRED_BUN_VERSION);
96
-
97
- if (comparison < 0) {
98
- Logger.error(`Bun 版本过低: ${currentVersion}`);
99
- Logger.info(`\n需要 Bun v${REQUIRED_BUN_VERSION} 或更高版本`);
100
- Logger.info('请升级 Bun:\n');
101
- Logger.info(' bun upgrade\n');
25
+ await syncCommand();
26
+ Logger.printEnv();
27
+ } catch (error: any) {
28
+ Logger.error('命令执行失败:', error.message || error);
102
29
  process.exit(1);
103
30
  }
104
31
  }
105
32
 
106
- // 检查 Bun 版本
107
- checkBunVersion();
108
-
109
- const program = new Command();
110
-
111
- program.name('befly').description('Befly CLI - 为 Befly 框架提供命令行工具').version(getVersion());
112
-
113
- /**
114
- * 包装命令处理函数,在执行后打印环境
115
- */
116
- function wrapCommand<T extends (...args: any[]) => any>(fn: T): T {
117
- return (async (...args: any[]) => {
118
- const result = await fn(...args);
119
- Logger.printEnv();
120
- return result;
121
- }) as T;
122
- }
123
-
124
- // build 命令 - 构建项目
125
- program.command('build').description('构建项目').option('-o, --outdir <path>', '输出目录', 'dist').option('--minify', '压缩代码', false).option('--sourcemap', '生成 sourcemap', false).action(wrapCommand(buildCommand));
126
-
127
- // sync 命令 - 一次性执行所有同步
128
- program.command('sync').description('一次性执行所有同步操作(syncApi + syncMenu + syncDev)').option('--plan', '计划模式,只显示不执行', false).option('-e, --env <environment>', '指定环境 (development, production, test)').action(wrapCommand(syncCommand));
129
-
130
- // syncDb 命令 - 同步数据库
131
- program.command('syncDb').description('同步数据库表结构').option('-t, --table <name>', '指定表名').option('--dry-run', '预览模式,只显示不执行', false).option('-e, --env <environment>', '指定环境 (development, production, test)').action(wrapCommand(syncDbCommand));
132
-
133
- // syncApi 命令 - 同步 API 接口
134
- program.command('syncApi').description('同步 API 接口到数据库').option('--plan', '计划模式,只显示不执行', false).option('-e, --env <environment>', '指定环境 (development, production, test)').action(wrapCommand(syncApiCommand));
135
-
136
- // syncMenu 命令 - 同步菜单
137
- program.command('syncMenu').description('同步菜单配置到数据库').option('--plan', '计划模式,只显示不执行', false).option('-e, --env <environment>', '指定环境 (development, production, test)').action(wrapCommand(syncMenuCommand));
138
-
139
- // syncDev 命令 - 同步开发者账号
140
- program.command('syncDev').description('同步开发者管理员账号').option('--plan', '计划模式,只显示不执行', false).option('-e, --env <environment>', '指定环境 (development, production, test)').action(wrapCommand(syncDevCommand));
141
-
142
- // 显示建议和错误
143
- program.showSuggestionAfterError();
144
- program.showHelpAfterError();
145
-
146
- // 解析命令行参数
147
- program.parse();
33
+ // 运行主函数
34
+ main();
package/checks/table.ts CHANGED
@@ -221,7 +221,7 @@ export default async function (): Promise<boolean> {
221
221
 
222
222
  if (fileValid) {
223
223
  validFiles++;
224
- Logger.info(`${fileType}表 ${fileName} 验证通过(${fileRules} 个字段)`);
224
+ // Logger.info(`${fileType}表 ${fileName} 验证通过(${fileRules} 个字段)`);
225
225
  } else {
226
226
  invalidFiles++;
227
227
  }
@@ -232,17 +232,15 @@ export default async function (): Promise<boolean> {
232
232
  }
233
233
 
234
234
  // 输出统计信息
235
- Logger.info(`表定义检查完成:`);
236
- Logger.info(` 总文件数: ${totalFiles}`);
237
- Logger.info(` 总规则数: ${totalRules}`);
238
- Logger.info(` 通过文件: ${validFiles}`);
239
- Logger.info(` 失败文件: ${invalidFiles}`);
235
+ // Logger.info(` 总文件数: ${totalFiles}`);
236
+ // Logger.info(` 总规则数: ${totalRules}`);
237
+ // Logger.info(` 通过文件: ${validFiles}`);
238
+ // Logger.info(` 失败文件: ${invalidFiles}`);
240
239
 
241
240
  if (invalidFiles > 0) {
242
241
  Logger.warn(`表定义检查失败,请修复上述错误后重试`);
243
242
  return false;
244
243
  } else {
245
- Logger.info(`所有表定义检查通过 ✓`);
246
244
  return true;
247
245
  }
248
246
  } catch (error: any) {
package/commands/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Build、Start、Sync、SyncApi、SyncMenu、SyncDev 命令实现
2
+ * Sync 命令实现
3
3
  */
4
4
 
5
5
  import { join } from 'pathe';
@@ -7,102 +7,6 @@ import { existsSync } from 'node:fs';
7
7
  import { Logger } from '../lib/logger.js';
8
8
  import { getProjectRoot } from './util.js';
9
9
 
10
- // ========== Build 命令 ==========
11
- interface BuildOptions {
12
- outdir: string;
13
- minify: boolean;
14
- sourcemap: boolean;
15
- }
16
-
17
- export async function buildCommand(options: BuildOptions) {
18
- try {
19
- const projectRoot = getProjectRoot();
20
- const mainFile = join(projectRoot, 'main.ts');
21
-
22
- if (!existsSync(mainFile)) {
23
- Logger.error('未找到 main.ts 文件');
24
- process.exit(1);
25
- }
26
-
27
- Logger.info('正在构建项目...');
28
-
29
- const args = ['build', mainFile, '--outdir', options.outdir, '--target', 'bun'];
30
-
31
- if (options.minify) {
32
- args.push('--minify');
33
- }
34
-
35
- if (options.sourcemap) {
36
- args.push('--sourcemap');
37
- }
38
-
39
- const proc = Bun.spawn(['bun', ...args], {
40
- cwd: projectRoot,
41
- stdout: 'pipe',
42
- stderr: 'pipe'
43
- });
44
-
45
- await proc.exited;
46
-
47
- if (proc.exitCode === 0) {
48
- Logger.success('项目构建完成');
49
- Logger.success(`输出目录: ${options.outdir}`);
50
- } else {
51
- Logger.error('项目构建失败');
52
- process.exit(1);
53
- }
54
- } catch (error) {
55
- Logger.error('构建失败:');
56
- console.error(error);
57
- process.exit(1);
58
- }
59
- }
60
-
61
- // ========== Start 命令 ==========
62
- interface StartOptions {
63
- port: string;
64
- host: string;
65
- }
66
-
67
- export async function startCommand(options: StartOptions) {
68
- try {
69
- const projectRoot = getProjectRoot();
70
- const mainFile = join(projectRoot, 'main.ts');
71
-
72
- if (!existsSync(mainFile)) {
73
- Logger.error('未找到 main.ts 文件');
74
- process.exit(1);
75
- }
76
-
77
- process.env.NODE_ENV = 'production';
78
- process.env.APP_PORT = options.port;
79
- process.env.APP_HOST = options.host;
80
-
81
- Logger.info('正在启动生产服务器...\n');
82
- Logger.info(`端口: ${options.port}`);
83
- Logger.info(`主机: ${options.host}`);
84
- Logger.info(`环境: production\n`);
85
-
86
- const proc = Bun.spawn(['bun', 'run', mainFile], {
87
- cwd: projectRoot,
88
- stdout: 'inherit',
89
- stderr: 'inherit',
90
- stdin: 'inherit',
91
- env: {
92
- ...process.env,
93
- FORCE_COLOR: '1'
94
- }
95
- });
96
-
97
- await proc.exited;
98
- process.exit(proc.exitCode || 0);
99
- } catch (error) {
100
- Logger.error('启动失败:');
101
- console.error(error);
102
- process.exit(1);
103
- }
104
- }
105
-
106
10
  // ========== Sync 命令 ==========
107
11
  interface SyncOptions {
108
12
  table?: string;
package/commands/sync.ts CHANGED
@@ -1,54 +1,86 @@
1
1
  /**
2
2
  * Sync 命令 - 一次性执行所有同步操作
3
- * 按顺序执行:syncApi → syncMenu → syncDev
3
+ * 按顺序执行:syncDb → syncApi → syncMenu → syncDev
4
4
  */
5
5
 
6
6
  import { Logger } from '../lib/logger.js';
7
- import { syncApiCommand } from './syncApi.js';
8
- import { syncMenuCommand } from './syncMenu.js';
9
- import { syncDevCommand } from './syncDev.js';
7
+ import { Env } from '../config/env.js';
8
+ import { syncDbCommand, type SyncDbStats } from './syncDb.js';
9
+ import { syncApiCommand, type SyncApiStats } from './syncApi.js';
10
+ import { syncMenuCommand, type SyncMenuStats } from './syncMenu.js';
11
+ import { syncDevCommand, type SyncDevStats } from './syncDev.js';
10
12
  import { existsSync, mkdirSync } from 'node:fs';
11
13
 
12
- interface SyncOptions {
13
- env?: string;
14
- plan?: boolean;
15
- }
14
+ interface SyncOptions {}
16
15
 
17
16
  export async function syncCommand(options: SyncOptions = {}) {
18
17
  try {
19
- Logger.info('========================================');
20
- Logger.info('开始执行完整同步流程');
21
- Logger.info('========================================\n');
22
-
23
18
  const startTime = Date.now();
24
19
 
25
20
  // 确保 logs 目录存在
26
21
  if (!existsSync('./logs')) {
27
22
  mkdirSync('./logs', { recursive: true });
28
- Logger.info('✅ 已创建 logs 目录\n');
29
23
  }
30
24
 
31
- // 1. 同步接口(并缓存)
32
- Logger.info('【步骤 1/3】同步接口数据\n');
33
- await syncApiCommand(options);
34
- Logger.info('\n✅ 接口同步完成\n');
25
+ // 1. 同步数据库表结构
26
+ const dbStats = await syncDbCommand({ dryRun: false });
35
27
 
36
- // 2. 同步菜单(并缓存)
37
- Logger.info('【步骤 2/3】同步菜单数据\n');
38
- await syncMenuCommand(options);
39
- Logger.info('\n✅ 菜单同步完成\n');
28
+ // 2. 同步接口(并缓存)
29
+ const apiStats = await syncApiCommand();
40
30
 
41
- // 3. 同步开发管理员(并缓存角色权限)
42
- Logger.info('【步骤 3/3】同步开发管理员\n');
43
- await syncDevCommand(options);
44
- Logger.info('\n✅ 开发管理员同步完成\n');
31
+ // 3. 同步菜单(并缓存)
32
+ const menuStats = await syncMenuCommand();
33
+
34
+ // 4. 同步开发管理员(并缓存角色权限)
35
+ const devStats = await syncDevCommand();
45
36
 
46
37
  // 输出总结
47
38
  const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);
48
- Logger.info('========================================');
49
- Logger.info('🎉 所有同步操作已完成!');
50
39
  Logger.info(`总耗时: ${totalTime} 秒`);
51
- Logger.info('========================================');
40
+
41
+ console.log(
42
+ Bun.inspect.table([
43
+ { 项目: '处理表数', 数量: dbStats.processedTables },
44
+ { 项目: '创建表', 数量: dbStats.createdTables },
45
+ { 项目: '修改表', 数量: dbStats.modifiedTables },
46
+ { 项目: '新增字段', 数量: dbStats.addFields },
47
+ { 项目: '字段名称变更', 数量: dbStats.nameChanges },
48
+ { 项目: '字段类型变更', 数量: dbStats.typeChanges },
49
+ { 项目: '索引新增', 数量: dbStats.indexCreate },
50
+ { 项目: '索引删除', 数量: dbStats.indexDrop }
51
+ ])
52
+ );
53
+
54
+ Logger.info('\n📊 接口同步统计');
55
+ console.log(
56
+ Bun.inspect.table([
57
+ { 项目: '总接口数', 数量: apiStats.totalApis },
58
+ { 项目: '新增接口', 数量: apiStats.created },
59
+ { 项目: '更新接口', 数量: apiStats.updated },
60
+ { 项目: '删除接口', 数量: apiStats.deleted }
61
+ ])
62
+ );
63
+
64
+ Logger.info('\n📊 菜单同步统计');
65
+ console.log(
66
+ Bun.inspect.table([
67
+ { 项目: '总菜单数', 数量: menuStats.totalMenus },
68
+ { 项目: '父级菜单', 数量: menuStats.parentMenus },
69
+ { 项目: '子级菜单', 数量: menuStats.childMenus },
70
+ { 项目: '新增菜单', 数量: menuStats.created },
71
+ { 项目: '更新菜单', 数量: menuStats.updated },
72
+ { 项目: '删除菜单', 数量: menuStats.deleted }
73
+ ])
74
+ );
75
+
76
+ Logger.info('\n📊 开发账号同步统计');
77
+ console.log(
78
+ Bun.inspect.table([
79
+ { 项目: '管理员数量', 数量: devStats.adminCount },
80
+ { 项目: '角色数量', 数量: devStats.roleCount },
81
+ { 项目: '缓存角色数', 数量: devStats.cachedRoles }
82
+ ])
83
+ );
52
84
  } catch (error: any) {
53
85
  Logger.error('同步过程中发生错误:', error);
54
86
  process.exit(1);
@@ -32,6 +32,13 @@ interface ApiInfo {
32
32
  addonTitle: string;
33
33
  }
34
34
 
35
+ export interface SyncApiStats {
36
+ totalApis: number;
37
+ created: number;
38
+ updated: number;
39
+ deleted: number;
40
+ }
41
+
35
42
  /**
36
43
  * 递归扫描目录下的所有 .ts 文件
37
44
  */
@@ -111,36 +118,29 @@ async function scanAllApis(projectRoot: string): Promise<ApiInfo[]> {
111
118
  const apis: ApiInfo[] = [];
112
119
 
113
120
  // 1. 扫描 Core 框架 API
114
- Logger.debug('=== 扫描 Core 框架 API (core/apis) ===');
115
121
  const coreApisDir = join(dirname(projectRoot), 'core', 'apis');
116
122
  try {
117
123
  const coreApiFiles = scanTsFiles(coreApisDir);
118
- Logger.debug(` 找到 ${coreApiFiles.length} 个核心 API 文件`);
119
124
 
120
125
  for (const filePath of coreApiFiles) {
121
126
  const apiInfo = await extractApiInfo(filePath, coreApisDir, 'core', '', '核心接口');
122
127
  if (apiInfo) {
123
128
  apis.push(apiInfo);
124
- Logger.debug(` └ ${apiInfo.path} - ${apiInfo.name}`);
125
129
  }
126
130
  }
127
131
 
128
132
  // 2. 扫描项目 API
129
- Logger.info('\n=== 扫描项目 API (apis) ===');
130
133
  const projectApisDir = join(projectRoot, 'apis');
131
134
  const projectApiFiles = scanTsFiles(projectApisDir);
132
- Logger.debug(` 找到 ${projectApiFiles.length} 个项目 API 文件`);
133
135
 
134
136
  for (const filePath of projectApiFiles) {
135
137
  const apiInfo = await extractApiInfo(filePath, projectApisDir, 'app', '', '项目接口');
136
138
  if (apiInfo) {
137
139
  apis.push(apiInfo);
138
- Logger.debug(` └ ${apiInfo.path} - ${apiInfo.name}`);
139
140
  }
140
141
  }
141
142
 
142
143
  // 3. 扫描组件 API (node_modules/@befly-addon/*)
143
- Logger.info('\n=== 扫描组件 API (node_modules/@befly-addon/*) ===');
144
144
  const addonNames = scanAddons();
145
145
 
146
146
  for (const addonName of addonNames) {
@@ -148,7 +148,6 @@ async function scanAllApis(projectRoot: string): Promise<ApiInfo[]> {
148
148
 
149
149
  // 检查 apis 子目录是否存在
150
150
  if (!addonDirExists(addonName, 'apis')) {
151
- Logger.debug(` [${addonName}] 无 apis 目录,跳过`);
152
151
  continue;
153
152
  }
154
153
 
@@ -162,17 +161,15 @@ async function scanAllApis(projectRoot: string): Promise<ApiInfo[]> {
162
161
  const config = await configFile.json();
163
162
  addonTitle = config.title || addonName;
164
163
  } catch (error) {
165
- Logger.debug(` [${addonName}] 无法读取配置文件,使用默认标题`);
164
+ // 忽略配置读取错误
166
165
  }
167
166
 
168
167
  const addonApiFiles = scanTsFiles(addonApisDir);
169
- Logger.debug(` [${addonName}] 找到 ${addonApiFiles.length} 个 API 文件`);
170
168
 
171
169
  for (const filePath of addonApiFiles) {
172
170
  const apiInfo = await extractApiInfo(filePath, addonApisDir, 'addon', addonName, addonTitle);
173
171
  if (apiInfo) {
174
172
  apis.push(apiInfo);
175
- Logger.debug(` └ ${apiInfo.path} - ${apiInfo.name}`);
176
173
  }
177
174
  }
178
175
  }
@@ -180,6 +177,7 @@ async function scanAllApis(projectRoot: string): Promise<ApiInfo[]> {
180
177
  return apis;
181
178
  } catch (error: any) {
182
179
  Logger.error(`接口扫描失败:`, error);
180
+ return apis;
183
181
  }
184
182
  }
185
183
 
@@ -191,6 +189,7 @@ async function syncApis(helper: any, apis: ApiInfo[]): Promise<{ created: number
191
189
 
192
190
  for (const api of apis) {
193
191
  try {
192
+ // 根据 path 查询是否存在
194
193
  const existing = await helper.getOne({
195
194
  table: 'core_api',
196
195
  where: { path: api.path }
@@ -209,7 +208,6 @@ async function syncApis(helper: any, apis: ApiInfo[]): Promise<{ created: number
209
208
  }
210
209
  });
211
210
  stats.updated++;
212
- Logger.debug(` └ 更新接口: ${api.name} (ID: ${existing.id}, Path: ${api.path})`);
213
211
  } else {
214
212
  const id = await helper.insData({
215
213
  table: 'core_api',
@@ -223,7 +221,6 @@ async function syncApis(helper: any, apis: ApiInfo[]): Promise<{ created: number
223
221
  }
224
222
  });
225
223
  stats.created++;
226
- Logger.debug(` └ 新增接口: ${api.name} (ID: ${id}, Path: ${api.path})`);
227
224
  }
228
225
  } catch (error: any) {
229
226
  Logger.error(`同步接口 "${api.name}" 失败:`, error);
@@ -237,8 +234,6 @@ async function syncApis(helper: any, apis: ApiInfo[]): Promise<{ created: number
237
234
  * 删除配置中不存在的记录
238
235
  */
239
236
  async function deleteObsoleteRecords(helper: any, apiPaths: Set<string>): Promise<number> {
240
- Logger.info(`\n=== 删除配置中不存在的记录 ===`);
241
-
242
237
  const allRecords = await helper.getAll({
243
238
  table: 'core_api',
244
239
  fields: ['id', 'path', 'name'],
@@ -253,34 +248,22 @@ async function deleteObsoleteRecords(helper: any, apiPaths: Set<string>): Promis
253
248
  where: { id: record.id }
254
249
  });
255
250
  deletedCount++;
256
- Logger.debug(` └ 删除记录: ${record.name} (ID: ${record.id}, path: ${record.path})`);
257
251
  }
258
252
  }
259
253
 
260
- if (deletedCount === 0) {
261
- Logger.info(' ✅ 无需删除的记录');
262
- }
263
-
264
254
  return deletedCount;
265
255
  }
266
256
 
267
257
  /**
268
258
  * SyncApi 命令主函数
269
259
  */
270
- export async function syncApiCommand(options: SyncApiOptions = {}) {
260
+ export async function syncApiCommand(options: SyncApiOptions = {}): Promise<SyncApiStats> {
271
261
  try {
272
262
  if (options.plan) {
273
263
  Logger.info('[计划] 同步 API 接口到数据库(plan 模式不执行)');
274
- Logger.info('[计划] 1. 扫描 apis addons/*/apis 目录');
275
- Logger.info('[计划] 2. 提取每个 API 的配置信息');
276
- Logger.info('[计划] 3. 根据 path 检查接口是否存在');
277
- Logger.info('[计划] 4. 存在则更新,不存在则新增');
278
- Logger.info('[计划] 5. 删除文件中不存在的接口记录');
279
- return;
264
+ return { totalApis: 0, created: 0, updated: 0, deleted: 0 };
280
265
  }
281
266
 
282
- Logger.info('开始同步 API 接口到数据库...\n');
283
-
284
267
  const projectRoot = process.cwd();
285
268
 
286
269
  // 连接数据库(SQL + Redis)
@@ -289,7 +272,6 @@ export async function syncApiCommand(options: SyncApiOptions = {}) {
289
272
  const helper = Database.getDbHelper();
290
273
 
291
274
  // 1. 检查表是否存在
292
- Logger.debug('=== 检查数据表 ===');
293
275
  const exists = await helper.tableExists('core_api');
294
276
 
295
277
  if (!exists) {
@@ -297,30 +279,17 @@ export async function syncApiCommand(options: SyncApiOptions = {}) {
297
279
  process.exit(1);
298
280
  }
299
281
 
300
- Logger.info(`✅ 表 core_api 存在\n`);
301
-
302
282
  // 2. 扫描所有 API 文件
303
- Logger.debug('=== 步骤 2: 扫描 API 文件 ===');
304
283
  const apis = await scanAllApis(projectRoot);
305
284
  const apiPaths = new Set(apis.map((api) => api.path));
306
- Logger.info(`\n✅ 共扫描到 ${apis.length} 个 API 接口\n`);
307
285
 
308
286
  // 3. 同步 API 数据
309
- Logger.debug('=== 步骤 3: 同步 API 数据(新增/更新) ===');
310
287
  const stats = await syncApis(helper, apis);
311
288
 
312
289
  // 4. 删除文件中不存在的接口
313
290
  const deletedCount = await deleteObsoleteRecords(helper, apiPaths);
314
291
 
315
- // 5. 输出统计信息
316
- Logger.info(`\n=== 接口同步完成 ===`);
317
- Logger.info(`新增接口: ${stats.created} 个`);
318
- Logger.info(`更新接口: ${stats.updated} 个`);
319
- Logger.info(`删除接口: ${deletedCount} 个`);
320
- Logger.info(`当前总接口数: ${apis.length} 个`);
321
-
322
- // 6. 缓存接口数据到 Redis
323
- Logger.info('\n=== 步骤 4: 缓存接口数据到 Redis ===');
292
+ // 5. 缓存接口数据到 Redis
324
293
  try {
325
294
  const apiList = await helper.getAll({
326
295
  table: 'core_api',
@@ -328,16 +297,17 @@ export async function syncApiCommand(options: SyncApiOptions = {}) {
328
297
  orderBy: ['addonName#ASC', 'path#ASC']
329
298
  });
330
299
 
331
- const result = await RedisHelper.setObject('apis:all', apiList);
332
-
333
- if (result === null) {
334
- Logger.warn('⚠️ 接口缓存失败');
335
- } else {
336
- Logger.info(`✅ 已缓存 ${apiList.length} 个接口到 Redis (Key: apis:all)`);
337
- }
300
+ await RedisHelper.setObject('apis:all', apiList);
338
301
  } catch (error: any) {
339
- Logger.error('⚠️ 接口缓存异常:', error);
302
+ // 忽略缓存错误
340
303
  }
304
+
305
+ return {
306
+ totalApis: apis.length,
307
+ created: stats.created,
308
+ updated: stats.updated,
309
+ deleted: deletedCount
310
+ };
341
311
  } catch (error: any) {
342
312
  Logger.error('API 同步失败:', error);
343
313
  process.exit(1);