ol-base-components 2.6.0 → 2.7.1

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/src/api/api.js CHANGED
@@ -5,9 +5,7 @@ const SwaggerClient = require("swagger-client");
5
5
 
6
6
  // eg:node api http://220.179.249.140:20019 ./modules
7
7
 
8
- const swaggerUrl = process.argv[2]
9
- ? `${process.argv[2]}/swagger/v1/swagger.json`
10
- : "";
8
+ const swaggerUrl = process.argv[2] ? `${process.argv[2]}/swagger/v1/swagger.json` : "";
11
9
  const modulesDir = process.argv[3] ? process.argv[3] : "src/api/modules";
12
10
 
13
11
  let defaultRemark = `/**
@@ -39,7 +37,7 @@ function setFileReadOnly(filePath) {
39
37
  }
40
38
 
41
39
  SwaggerClient(swaggerUrl)
42
- .then((client) => {
40
+ .then(client => {
43
41
  const swaggerData = client.spec; // 获取 Swagger 数据
44
42
 
45
43
  const apiModules = generateApiModules(swaggerData);
@@ -49,7 +47,7 @@ SwaggerClient(swaggerUrl)
49
47
  console.log(`创建了文件夹: ${modulesDir}`);
50
48
  }
51
49
 
52
- Object.keys(apiModules).forEach((fileName) => {
50
+ Object.keys(apiModules).forEach(fileName => {
53
51
  const outputPath = path.join(modulesDir, `${fileName}.js`);
54
52
  fs.writeFileSync(outputPath, apiModules[fileName], "utf-8");
55
53
  setFileReadOnly(outputPath);
@@ -59,7 +57,7 @@ SwaggerClient(swaggerUrl)
59
57
  // 生成index.js入口文件
60
58
  createIndexFile(apiModules);
61
59
  })
62
- .catch((err) => {
60
+ .catch(err => {
63
61
  console.error("获取 Swagger 数据时出错:", err);
64
62
  })
65
63
  .finally(() => {
@@ -69,7 +67,7 @@ SwaggerClient(swaggerUrl)
69
67
 
70
68
  function createIndexFile(apiModules) {
71
69
  let str = defaultRemark;
72
- Object.keys(apiModules).forEach((fileName) => {
70
+ Object.keys(apiModules).forEach(fileName => {
73
71
  str += `export * from "./${fileName}";\n`;
74
72
  });
75
73
  const outputPath = path.join(modulesDir, `index.js`);
@@ -87,12 +85,9 @@ function generateKeyName(url, method) {
87
85
 
88
86
  // 处理 {xxx} 转换为 ByXxx
89
87
  const processedArr = arr.map(
90
- (item) =>
88
+ item =>
91
89
  item
92
- .replace(
93
- /{(.*?)}/,
94
- (_, param) => `By${param.charAt(0).toUpperCase() + param.slice(1)}`
95
- ) // 处理 {xxx}
90
+ .replace(/{(.*?)}/, (_, param) => `By${param.charAt(0).toUpperCase() + param.slice(1)}`) // 处理 {xxx}
96
91
  .replace(/[-_]/g, "") // 去除 - 和 _
97
92
  );
98
93
 
@@ -106,8 +101,7 @@ function generateKeyName(url, method) {
106
101
  for (let i = 0; i < processedArr.length; i++) {
107
102
  if (i === 0 || processedArr[i] !== processedArr[i - 1]) {
108
103
  // 将每项首字母大写
109
- const capitalizedItem =
110
- processedArr[i].charAt(0).toUpperCase() + processedArr[i].slice(1);
104
+ const capitalizedItem = processedArr[i].charAt(0).toUpperCase() + processedArr[i].slice(1);
111
105
  resultArr.push(capitalizedItem);
112
106
  }
113
107
  }
@@ -116,7 +110,7 @@ function generateKeyName(url, method) {
116
110
  }
117
111
 
118
112
  // java数据类型转成js数据类型
119
- const javaTypeToJsType = (javaType) => {
113
+ const javaTypeToJsType = javaType => {
120
114
  switch (javaType) {
121
115
  case "integer":
122
116
  return "number";
@@ -130,11 +124,11 @@ const javaTypeToJsType = (javaType) => {
130
124
  };
131
125
 
132
126
  // 根据parameters参数返回path对应的接口参数,path参数都是必填的
133
- const getPathParameters = (parameters) => {
127
+ const getPathParameters = parameters => {
134
128
  if (!parameters && !Array.isArray(parameters)) return [];
135
129
  return parameters
136
- .filter((param) => param.in === "path") // 过滤出路径参数
137
- .map((param) => param.name); // 提取name属性
130
+ .filter(param => param.in === "path") // 过滤出路径参数
131
+ .map(param => param.name); // 提取name属性
138
132
  };
139
133
 
140
134
  const MethodEnum = {
@@ -143,14 +137,12 @@ const MethodEnum = {
143
137
  put: "put",
144
138
  delete: "del",
145
139
  };
146
- const generateApiModules = (swagger) => {
140
+ const generateApiModules = swagger => {
147
141
  const { tags, paths } = swagger;
148
142
  const apiModules = {};
149
143
  // 初始化模块对象
150
- tags.forEach((tag) => {
151
- apiModules[
152
- tag.name
153
- ] = `${defaultRemark}import { api } from "@/api/request/sendRuest"\n`;
144
+ tags.forEach(tag => {
145
+ apiModules[tag.name] = `${defaultRemark}import { api } from "@/api/request/sendRuest"\n`;
154
146
  });
155
147
 
156
148
  for (const [url, methods] of Object.entries(paths)) {
@@ -158,7 +150,7 @@ const generateApiModules = (swagger) => {
158
150
  const tags = details.tags || [];
159
151
  const parameters = details.parameters || [];
160
152
  const requestBody = details.requestBody || {};
161
- tags.forEach((tag) => {
153
+ tags.forEach(tag => {
162
154
  if (Object.keys(apiModules).includes(tag)) {
163
155
  // 生成 JSDoc 注释
164
156
  let functionDoc = ``;
@@ -171,21 +163,15 @@ const generateApiModules = (swagger) => {
171
163
  //parameters此参数
172
164
  if (Object.keys(details).includes("parameters")) {
173
165
  functionDoc += ` * @param {Object} params - 请求参数\n`;
174
- parameters.forEach((param) => {
175
- const paramType = param.schema
176
- ? javaTypeToJsType(param.schema.type)
177
- : "any";
166
+ parameters.forEach(param => {
167
+ const paramType = param.schema ? javaTypeToJsType(param.schema.type) : "any";
178
168
  const paramName = param.name;
179
- const temp = param.required
180
- ? `params.${paramName}`
181
- : `[params.${paramName}]`;
182
- functionDoc += ` * @param {${paramType}} ${temp} - ${
183
- param.description || ""
184
- }\n`;
169
+ const temp = param.required ? `params.${paramName}` : `[params.${paramName}]`;
170
+ functionDoc += ` * @param {${paramType}} ${temp} - ${param.description || ""}\n`;
185
171
  });
186
172
  pathParameters = getPathParameters(parameters);
187
173
  // 是否有query参数
188
- hasQuery = parameters.some((e) => e.in === "query");
174
+ hasQuery = parameters.some(e => e.in === "query");
189
175
  }
190
176
 
191
177
  // 如果有requestBody
@@ -201,7 +187,7 @@ const generateApiModules = (swagger) => {
201
187
  if (type === "object") {
202
188
  functionDoc += ` * @param {Object} body - 请求参数\n`;
203
189
 
204
- Object.keys(properties).forEach((key) => {
190
+ Object.keys(properties).forEach(key => {
205
191
  // 是否必填
206
192
  const isRequired =
207
193
  schema.required &&
@@ -209,9 +195,9 @@ const generateApiModules = (swagger) => {
209
195
  schema.required.includes(key);
210
196
 
211
197
  const temp = isRequired ? `body.${key}` : `[body.${key}]`;
212
- functionDoc += ` * @param {${javaTypeToJsType(
213
- properties[key].type
214
- )}} ${temp} - ${properties[key].description || ""}\n`;
198
+ functionDoc += ` * @param {${javaTypeToJsType(properties[key].type)}} ${temp} - ${
199
+ properties[key].description || ""
200
+ }\n`;
215
201
  });
216
202
  if (Object.keys(properties).length > 1) hasBody = true;
217
203
  } else if (type === "array") {
@@ -226,13 +212,13 @@ const generateApiModules = (swagger) => {
226
212
  let functionParams = [];
227
213
  if (hasQuery) functionParams.push("params");
228
214
  if (hasBody) functionParams.push("body");
229
- Object.assign(functionParams, pathParameters);
215
+ // Object.assign(functionParams, pathParameters);
216
+ functionParams = [...pathParameters, ...functionParams];
230
217
  functionParams.push("options = {}");
231
218
  // 函数
232
- functionDoc += `export const ${generateKeyName(
233
- url,
234
- method
235
- )} = (${functionParams.join(", ")}) => {\n`;
219
+ functionDoc += `export const ${generateKeyName(url, method)} = (${functionParams.join(
220
+ ", "
221
+ )}) => {\n`;
236
222
 
237
223
  functionDoc += ` return api({\n`;
238
224
  functionDoc += ` url: \`${url.replace(/{/g, "${")}\`,\n`;
package/src/api/run.js CHANGED
@@ -5,9 +5,7 @@ const path = require("path");
5
5
 
6
6
  // eg:node api http://220.179.249.140:20019 swagger.js
7
7
 
8
- const swaggerUrl = process.argv[2]
9
- ? `${process.argv[2]}/swagger/v1/swagger.json`
10
- : "";
8
+ const swaggerUrl = process.argv[2] ? `${process.argv[2]}/swagger/v1/swagger.json` : "";
11
9
  const outputPath = process.argv[3] || "src/api/swagger.js";
12
10
 
13
11
  let defaultRemark = `/**
@@ -38,11 +36,11 @@ function setFileReadOnly(filePath) {
38
36
  }
39
37
 
40
38
  http
41
- .get(swaggerUrl, (response) => {
39
+ .get(swaggerUrl, response => {
42
40
  let data = "";
43
41
 
44
42
  // 监听数据事件
45
- response.on("data", (chunk) => {
43
+ response.on("data", chunk => {
46
44
  data += chunk;
47
45
  });
48
46
 
@@ -61,7 +59,7 @@ http
61
59
  setFileReadOnly(outputPath);
62
60
  });
63
61
  })
64
- .on("error", (err) => {
62
+ .on("error", err => {
65
63
  clearInterval(spinner);
66
64
  process.stdout.write("\r");
67
65
  console.error("获取swagger.json时出错:", err);
@@ -75,12 +73,9 @@ function generateKeyName(url, method) {
75
73
 
76
74
  // 处理 {xxx} 转换为 ByXxx
77
75
  const processedArr = arr.map(
78
- (item) =>
76
+ item =>
79
77
  item
80
- .replace(
81
- /{(.*?)}/,
82
- (_, param) => `By${param.charAt(0).toUpperCase() + param.slice(1)}`
83
- ) // 处理 {xxx}
78
+ .replace(/{(.*?)}/, (_, param) => `By${param.charAt(0).toUpperCase() + param.slice(1)}`) // 处理 {xxx}
84
79
  .replace(/[-_]/g, "") // 去除 - 和 _
85
80
  );
86
81
 
@@ -94,8 +89,7 @@ function generateKeyName(url, method) {
94
89
  for (let i = 0; i < processedArr.length; i++) {
95
90
  if (i === 0 || processedArr[i] !== processedArr[i - 1]) {
96
91
  // 将每项首字母大写
97
- const capitalizedItem =
98
- processedArr[i].charAt(0).toUpperCase() + processedArr[i].slice(1);
92
+ const capitalizedItem = processedArr[i].charAt(0).toUpperCase() + processedArr[i].slice(1);
99
93
  resultArr.push(capitalizedItem);
100
94
  }
101
95
  }
@@ -110,11 +104,11 @@ function removeCurlyBraces(url) {
110
104
  }
111
105
 
112
106
  // 生成API模块
113
- const generateApiModules = (swagger) => {
107
+ const generateApiModules = swagger => {
114
108
  const { tags, paths } = swagger;
115
109
  const apiModules = {};
116
110
  // 初始化模块对象
117
- tags.forEach((tag) => {
111
+ tags.forEach(tag => {
118
112
  apiModules[tag.name] = {};
119
113
  });
120
114
 
@@ -123,13 +117,11 @@ const generateApiModules = (swagger) => {
123
117
  for (const [method, details] of Object.entries(methods)) {
124
118
  // 获取接口的tags
125
119
  const tags = details.tags || [];
126
- tags.forEach((tag) => {
120
+ tags.forEach(tag => {
127
121
  const key = generateKeyName(url, method);
128
122
  if (apiModules[tag]) {
129
123
  const summary = details.summary || "";
130
- apiModules[tag][key] = `${key}: "${removeCurlyBraces(
131
- url
132
- )}", //${method} ${summary}\n`;
124
+ apiModules[tag][key] = `${key}: "${removeCurlyBraces(url)}", //${method} ${summary}\n`;
133
125
  }
134
126
  });
135
127
  }
@@ -138,7 +130,7 @@ const generateApiModules = (swagger) => {
138
130
  // 生成最终的输出字符串
139
131
  let output = defaultRemark;
140
132
  for (const [moduleName, methods] of Object.entries(apiModules)) {
141
- const description = tags.find((e) => e.name === moduleName).description;
133
+ const description = tags.find(e => e.name === moduleName).description;
142
134
  output += `// ${description}\n`;
143
135
  output += `export const ${moduleName} = {\n`;
144
136
  for (const method of Object.values(methods)) {
package/src/bin/add.js CHANGED
@@ -1,7 +1,8 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
  const { Command } = require("commander");
3
3
  const fs = require("fs");
4
4
  const path = require("path");
5
+ const inquirer = require("inquirer");
5
6
  const vue2Template = require("./initTemplate");
6
7
  const program = new Command();
7
8
 
@@ -9,12 +10,25 @@ const spinnerChars = ["|", "/", "-", "\\"];
9
10
  let spinnerIndex = 0;
10
11
  let dotCount = 0;
11
12
  const maxDots = 3;
12
- const spinner = setInterval(() => {
13
- const dots = ".".repeat(dotCount);
14
- process.stdout.write(`\r${spinnerChars[spinnerIndex]} 正在玩命加载中${dots}`);
15
- spinnerIndex = (spinnerIndex + 1) % spinnerChars.length;
16
- dotCount = (dotCount + 1) % (maxDots + 1);
17
- }, 300);
13
+ let spinner;
14
+
15
+ // 启动加载动画
16
+ const startSpinner = () => {
17
+ spinner = setInterval(() => {
18
+ const dots = ".".repeat(dotCount);
19
+ process.stdout.write(`\r${spinnerChars[spinnerIndex]} 正在玩命加载中${dots}`);
20
+ spinnerIndex = (spinnerIndex + 1) % spinnerChars.length;
21
+ dotCount = (dotCount + 1) % (maxDots + 1);
22
+ }, 300);
23
+ };
24
+
25
+ // 停止加载动画
26
+ const stopSpinner = () => {
27
+ if (spinner) {
28
+ clearInterval(spinner);
29
+ process.stdout.write("\r");
30
+ }
31
+ };
18
32
 
19
33
  // 自定义错误处理 - 必须在使用 program.parse() 之前调用
20
34
  program.exitOverride();
@@ -24,41 +38,221 @@ try {
24
38
  .version("0.1.0")
25
39
  .argument("<moduleName>", "name of the module to create")
26
40
  .option("-p, --path <customPath>", "文件路径")
27
- .option(
28
- "-u, --url <pageUrl>",
29
- "分页接口URL (可选)",
30
- "/api/app/business-report/stock-bIPaged-result"
31
- )
32
- .option(
33
- "-e, --export <exportUrl>",
34
- "分页接口导出URL (可选)",
35
- "/api/app/business-report/export-stock-bI"
36
- )
37
- .option(
38
- "-m, --swaggerModule <swaggerModule>",
39
- "swagger.js模块名称 (可选)",
40
- "BusinessReport"
41
- )
42
- .action((moduleName, options) => {
43
- const dir = path.join(options.path || process.cwd(), moduleName);
44
- // 启动加载动画
45
- if (!fs.existsSync(dir)) {
46
- fs.mkdirSync(dir);
47
- // console.log(`创建文件夹: ${dir}`);
48
- const templateContent = vue2Template(moduleName, options);
49
- const outputPath = path.join(dir, `index.vue`)
41
+ .action(async (moduleName, options) => {
42
+ try {
43
+ console.log("🎉 欢迎使用Vue页面模板生成器!");
44
+ console.log(` 模块名称: ${moduleName}`);
45
+ console.log(`📂 保存路径: ${options.path || process.cwd()}`);
46
+ console.log("请按照提示配置页面功能:\n");
47
+
48
+ // 1. 分页接口地址(必填)
49
+ const pageUrlAnswer = await inquirer.prompt([
50
+ {
51
+ type: "input",
52
+ name: "pageUrl",
53
+ message: "请输入分页接口地址(必填):",
54
+ default: "/api/app/admission-info/admission-info",
55
+ validate: input => {
56
+ if (!input.trim()) {
57
+ return "分页接口地址不能为空";
58
+ }
59
+ return true;
60
+ },
61
+ },
62
+ ]);
63
+
64
+ // 2. 询问是否有导出接口
65
+ const exportAnswer = await inquirer.prompt([
66
+ {
67
+ type: "confirm",
68
+ name: "hasExport",
69
+ message: "是否有导出接口?",
70
+ default: true,
71
+ },
72
+ ]);
73
+
74
+ let exportUrl = "";
75
+ if (exportAnswer.hasExport) {
76
+ const exportUrlAnswer = await inquirer.prompt([
77
+ {
78
+ type: "input",
79
+ name: "exportUrl",
80
+ message: "请输入导出接口地址:",
81
+ default: "/api/app/admission-info/paged-result",
82
+ validate: input => {
83
+ if (!input.trim()) {
84
+ return "导出接口地址不能为空";
85
+ }
86
+ return true;
87
+ },
88
+ },
89
+ ]);
90
+ exportUrl = exportUrlAnswer.exportUrl;
91
+ }
92
+
93
+ // 3. 询问是否有新增/编辑/删除功能
94
+ const operationsAnswer = await inquirer.prompt([
95
+ {
96
+ type: "checkbox",
97
+ name: "operations",
98
+ message: "请选择需要的功能:",
99
+ choices: [
100
+ { name: "新增功能", value: "add" },
101
+ { name: "编辑功能", value: "edit" },
102
+ { name: "删除功能", value: "delete" },
103
+ { name: "详情功能", value: "detail" },
104
+ ],
105
+ default: [],
106
+ },
107
+ ]);
108
+
109
+ let idField = "id";
110
+ let addUrl = "";
111
+ let editUrl = "";
112
+ let deleteUrl = "";
113
+ let detailUrl = "";
114
+
115
+ // 如果有新增/编辑/删除/详情功能,直接使用分页接口地址
116
+ if (operationsAnswer.operations.length > 0) {
117
+ // 从分页接口地址中提取基础路径
118
+ // 假设分页接口格式为 /api/app/xxx/xxx-paged-result
119
+ // 我们需要提取 /api/app/xxx 部分
120
+ const pageUrl = pageUrlAnswer.pageUrl;
121
+ // const baseUrl = pageUrl.replace(/-paged-result.*$/, "").replace(/\/[^\/]*$/, "");
122
+ const baseUrl = pageUrl;
123
+
124
+ // 询问ID字段名
125
+ const idFieldAnswer = await inquirer.prompt([
126
+ {
127
+ type: "input",
128
+ name: "idField",
129
+ message: "请输入ID字段名:",
130
+ default: "admissionInfoId",
131
+ validate: input => {
132
+ if (!input.trim()) {
133
+ return "ID字段名不能为空";
134
+ }
135
+ return true;
136
+ },
137
+ },
138
+ ]);
139
+ idField = idFieldAnswer.idField;
140
+
141
+ // 根据选择的功能构建对应的接口地址
142
+ if (operationsAnswer.operations.includes("add")) {
143
+ addUrl = baseUrl;
144
+ }
145
+ if (operationsAnswer.operations.includes("edit")) {
146
+ editUrl = `${baseUrl}/{${idField}}`;
147
+ }
148
+ if (operationsAnswer.operations.includes("delete")) {
149
+ deleteUrl = `${baseUrl}/{${idField}}`;
150
+ }
151
+ if (operationsAnswer.operations.includes("detail")) {
152
+ detailUrl = `${baseUrl}/{${idField}}`;
153
+ }
154
+ }
155
+
156
+ // 4. 询问所有接口的模块名
157
+ const moduleAnswer = await inquirer.prompt([
158
+ {
159
+ type: "input",
160
+ name: "swaggerModule",
161
+ message: "请输入所有接口的模块名:",
162
+ default: "AdmissionInfo",
163
+ validate: input => {
164
+ if (!input.trim()) {
165
+ return "模块名不能为空";
166
+ }
167
+ return true;
168
+ },
169
+ },
170
+ ]);
171
+
172
+ // 启动加载动画
173
+ startSpinner();
174
+
175
+ const dir = path.join(options.path || process.cwd(), moduleName);
176
+
177
+ // 检查目录是否存在
178
+ if (fs.existsSync(dir)) {
179
+ stopSpinner();
180
+ console.log(`❌ 创建失败,文件夹 ${dir} 已存在`);
181
+ return;
182
+ }
183
+
184
+ // 创建目录
185
+ fs.mkdirSync(dir, { recursive: true });
186
+
187
+ // 合并所有配置
188
+ const config = {
189
+ moduleName,
190
+ path: options.path || process.cwd(),
191
+ pageUrl: pageUrlAnswer.pageUrl,
192
+ hasExport: exportAnswer.hasExport,
193
+ exportUrl: exportUrl,
194
+ hasAdd: operationsAnswer.operations.includes("add"),
195
+ addUrl: addUrl,
196
+ hasEdit: operationsAnswer.operations.includes("edit"),
197
+ editUrl: editUrl,
198
+ hasDelete: operationsAnswer.operations.includes("delete"),
199
+ deleteUrl: deleteUrl,
200
+ hasDetail: operationsAnswer.operations.includes("detail"),
201
+ detailUrl: detailUrl,
202
+ swaggerModule: moduleAnswer.swaggerModule,
203
+ idField: idField,
204
+ };
205
+
206
+ // 生成模板内容
207
+ const templateContent = vue2Template(moduleName, config);
208
+
209
+ // 保存文件
210
+ const outputPath = path.join(dir, `index.vue`);
50
211
  fs.writeFileSync(outputPath, templateContent);
51
- console.log(`✅ 模板 已生成并保存到 ${outputPath}`);
52
212
 
53
- } else {
54
- console.log(`❌ 创建失败,文件夹 ${dir} 已存在`);
55
- }
56
- if (options.debug) {
57
- console.log("调试信息:", options);
213
+ // 停止加载动画
214
+ stopSpinner();
215
+
216
+ // 输出成功信息
217
+ console.log(`✅ 模板已生成并保存到 ${outputPath}`);
218
+ console.log(` 文件路径: ${outputPath}`);
219
+
220
+ // 输出功能总结
221
+ const features = [];
222
+ if (exportAnswer.hasExport) features.push("导出功能");
223
+ if (operationsAnswer.operations.includes("add")) features.push("新增功能");
224
+ if (operationsAnswer.operations.includes("edit")) features.push("编辑功能");
225
+ if (operationsAnswer.operations.includes("delete")) features.push("删除功能");
226
+ if (operationsAnswer.operations.includes("detail")) features.push("详情功能");
227
+
228
+ if (features.length > 0) {
229
+ console.log(`🔧 已添加功能: ${features.join(", ")}`);
230
+ }
231
+
232
+ console.log(`📚 模块名: ${moduleAnswer.swaggerModule}`);
233
+ if (idField) {
234
+ console.log(`🆔 ID字段: ${idField}`);
235
+ }
236
+
237
+ // 显示接口地址预览
238
+ if (operationsAnswer.operations.length > 0) {
239
+ const pageUrl = pageUrlAnswer.pageUrl;
240
+ const baseUrl = pageUrl.replace(/-paged-result.*$/, "").replace(/\/[^\/]*$/, "");
241
+ console.log(`🔗 基础接口: ${baseUrl}`);
242
+ if (addUrl) console.log(`➕ 新增接口: ${addUrl}`);
243
+ if (editUrl) console.log(`✏️ 编辑接口: ${editUrl}`);
244
+ if (deleteUrl) console.log(`��️ 删除接口: ${deleteUrl}`);
245
+ if (detailUrl) console.log(`��️ 详情接口: ${detailUrl}`);
246
+ }
247
+
248
+ console.log("\n 模板生成完成!");
249
+ } catch (error) {
250
+ stopSpinner();
251
+ console.error("❌ 发生错误:", error.message);
252
+ process.exit(1);
58
253
  }
59
- clearInterval(spinner);
60
- process.stdout.write("\r");
61
254
  });
255
+
62
256
  program.parse(process.argv);
63
257
  } catch (err) {
64
258
  // 捕获 commander 的错误
@@ -66,13 +260,13 @@ try {
66
260
  console.log("❌ 错误:缺少必需的文件名称");
67
261
  console.log("📖 使用方法:");
68
262
  console.log(" npx add <文件名> -p <路径>");
69
- console.log("�� 示例:");
263
+ console.log(" 示例:");
70
264
  console.log(" npx add demo -p src/view");
71
265
  process.exit(1);
72
266
  } else {
73
267
  // 处理其他错误
74
- // console.error("❌ 发生错误:", err.message);
268
+ stopSpinner();
269
+ console.error("❌ 发生错误:", err.message);
75
270
  process.exit(1);
76
271
  }
77
272
  }
78
- // program.parse(process.argv);