ol-base-components 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ol-base-components",
3
- "version": "3.5.1",
3
+ "version": "3.5.2",
4
4
  "private": false,
5
5
  "main": "dist/index.umd.js",
6
6
  "module": "dist/index.mjs",
@@ -19,6 +19,8 @@
19
19
  },
20
20
  "files": [
21
21
  "dist/",
22
+ "src/api/",
23
+ "src/bin/",
22
24
  "package.json"
23
25
  ],
24
26
  "bin": {
@@ -33,9 +35,6 @@
33
35
  "build:cli": "vue-cli-service build",
34
36
  "lint": "vue-cli-service lint",
35
37
  "add": "node src/bin/add.js",
36
- "openCloseloop": "node src/bin/openCloseloop.js",
37
- "openLoop": "node src/bin/openLoop.js",
38
- "news": "node src/bin/news.js",
39
38
  "prepublishOnly": "npm run build"
40
39
  },
41
40
  "dependencies": {
package/src/api/init.js CHANGED
@@ -17,31 +17,31 @@ let swaggerUrl = process.argv[2];
17
17
  // };
18
18
  async function extractSwaggerUrl() {
19
19
  const configPath = path.join(process.cwd(), "public", "configBaseUrl.js");
20
-
20
+
21
21
  if (!fs.existsSync(configPath)) {
22
22
  console.error("\n❌ 错误: 找不到 configBaseUrl.js 文件");
23
23
  console.error(`路径: ${configPath}`);
24
24
  return null;
25
25
  }
26
-
26
+
27
27
  try {
28
28
  const configContent = fs.readFileSync(configPath, "utf8");
29
29
  // 使用正则表达式提取 baseURL(排除注释行,支持缩进)
30
30
  const baseURLMatch = configContent.match(/^\s*[^\/]*baseURL:\s*["']([^"']+)["']/m);
31
-
31
+
32
32
  if (!baseURLMatch) {
33
33
  console.error("\n❌ 错误: 无法从 configBaseUrl.js 中提取 baseURL");
34
34
  console.error("请确保配置文件中有类似这样的配置:");
35
35
  console.error(" window.config = { baseURL: 'http://your-swagger-url' }");
36
36
  return null;
37
37
  }
38
-
38
+
39
39
  const baseURL = baseURLMatch[1] || "";
40
40
  if (!baseURL) {
41
41
  console.error("\n❌ 错误: baseURL 为空");
42
42
  return null;
43
43
  }
44
-
44
+
45
45
  return baseURL;
46
46
  } catch (err) {
47
47
  console.error("\n❌ 读取配置文件失败:", err.message);
@@ -52,15 +52,12 @@ async function extractSwaggerUrl() {
52
52
  // 执行 api.js 脚本
53
53
  function runApiScript() {
54
54
  return new Promise((resolve, reject) => {
55
- console.log("📝 正在执行 swagger 脚本...");
56
-
57
55
  const apiProcess = spawn("node", [path.join(__dirname, "api.js"), swaggerUrl], {
58
56
  stdio: "inherit",
59
57
  });
60
58
 
61
59
  apiProcess.on("close", code => {
62
60
  if (code === 0) {
63
- console.log("✅ swagger脚本执行完成");
64
61
  resolve();
65
62
  } else {
66
63
  reject(new Error(`swagger 脚本执行失败,退出码: ${code}`));
@@ -76,15 +73,12 @@ function runApiScript() {
76
73
  // 执行 run.js 脚本
77
74
  function runRunScript() {
78
75
  return new Promise((resolve, reject) => {
79
- console.log("🔧 正在执行 接口 脚本...");
80
-
81
76
  const runProcess = spawn("node", [path.join(__dirname, "run.js"), swaggerUrl], {
82
77
  stdio: "inherit",
83
78
  });
84
79
 
85
80
  runProcess.on("close", code => {
86
81
  if (code === 0) {
87
- console.log("✅ 接口脚本执行完成");
88
82
  resolve();
89
83
  } else {
90
84
  reject(new Error(`接口脚本执行失败,退出码: ${code}`));
@@ -100,8 +94,6 @@ function runRunScript() {
100
94
  // 执行 fetch-swagger.js 脚本
101
95
  function runFetchSwaggerScript() {
102
96
  return new Promise((resolve, reject) => {
103
- console.log("📥 正在下载 swagger.json...");
104
-
105
97
  const fetchProcess = spawn("node", [path.join(__dirname, "../bin/fetch-swagger.js")], {
106
98
  stdio: "inherit",
107
99
  });
@@ -126,11 +118,9 @@ async function main() {
126
118
  try {
127
119
  // 如果命令行没有传参,尝试从配置文件提取
128
120
  if (!swaggerUrl) {
129
- console.log("🔍 未指定 URL,正在从 configBaseUrl.js 自动检测...");
130
121
  const extractedUrl = await extractSwaggerUrl();
131
122
  if (extractedUrl) {
132
123
  swaggerUrl = extractedUrl;
133
- console.log(`✨ 自动检测到 baseURL: ${swaggerUrl}`);
134
124
  }
135
125
  }
136
126
 
@@ -138,12 +128,10 @@ async function main() {
138
128
  if (!swaggerUrl) {
139
129
  console.error("\n❌ 错误: 无法获取有效的 swagger URL");
140
130
  console.error("请手动指定 URL,用法:");
141
- console.error(" npx ol-base-components init http://your-swagger-url");
131
+ console.error("npx init http://你的swagger地址");
142
132
  process.exit(1);
143
133
  }
144
-
145
- console.log(`\n🚀 开始初始化,URL: ${swaggerUrl}`);
146
-
134
+ console.log(`\n🚀 正在执行接口脚本...`);
147
135
  // 先执行 api.js
148
136
  await runApiScript();
149
137
 
@@ -161,4 +149,4 @@ async function main() {
161
149
  }
162
150
 
163
151
  // 执行主函数
164
- main();
152
+ main();
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @file fetch-swagger.js
3
+ * @description 用于从指定的 baseURL 路径自动抓取 swagger.json 文件到 swagger 目录
4
+ * @author lijiapeng
5
+ * @created 2026-01-06
6
+ */
7
+
8
+ const fs = require('fs')
9
+ const path = require('path')
10
+ const http = require('http')
11
+ const https = require('https')
12
+
13
+ // 读取 configBaseUrl.js 文件
14
+ const configPath = path.join(__dirname, '../public/configBaseUrl.js')
15
+ const configContent = fs.readFileSync(configPath, 'utf8')
16
+
17
+ // 使用正则表达式提取 baseURL(排除注释行)
18
+ const baseURLMatch = configContent.match(/^\s*[^\/]*baseURL:\s*["']([^"']+)["']/m);
19
+ if (!baseURLMatch) {
20
+ console.error('错误: 无法从 configBaseUrl.js 中提取 baseURL')
21
+ process.exit(1)
22
+ }
23
+
24
+ const baseURL = baseURLMatch[1]
25
+ const swaggerUrl = `${baseURL}/swagger/v1/swagger.json`
26
+ const outputPath = path.join(__dirname, '../swagger/swagger.json')
27
+ const swaggerDir = path.dirname(outputPath)
28
+
29
+ // 如果 swagger 目录不存在,则创建
30
+ if (!fs.existsSync(swaggerDir)) {
31
+ try {
32
+ fs.mkdirSync(swaggerDir, { recursive: true })
33
+ console.log(`已创建目录: ${swaggerDir}`)
34
+ } catch (error) {
35
+ console.error(`错误: 无法创建目录 ${swaggerDir}:`, error.message)
36
+ process.exit(1)
37
+ }
38
+ }
39
+
40
+ // 如果文件已存在且为只读,先移除只读属性以便覆盖
41
+ if (fs.existsSync(outputPath)) {
42
+ try {
43
+ fs.chmodSync(outputPath, 0o666) // 0o666 = 读写权限,以便覆盖文件
44
+ } catch (error) {
45
+ // 忽略错误,继续执行
46
+ }
47
+ }
48
+
49
+ console.log(`正在从 ${swaggerUrl} 下载 swagger.json...`)
50
+
51
+ // 根据协议选择 http 或 https
52
+ const client = swaggerUrl.startsWith('https://') ? https : http
53
+
54
+ client
55
+ .get(swaggerUrl, (response) => {
56
+ if (response.statusCode !== 200) {
57
+ console.error(`错误: 下载失败,状态码: ${response.statusCode}`)
58
+ process.exit(1)
59
+ }
60
+
61
+ const fileStream = fs.createWriteStream(outputPath)
62
+ response.pipe(fileStream)
63
+
64
+ fileStream.on('finish', () => {
65
+ fileStream.close()
66
+ // 设置文件为只读,防止被修改
67
+ try {
68
+ fs.chmodSync(outputPath, 0o444) // 0o444 = 只读权限(所有用户)
69
+ console.log(`成功! swagger.json 已保存到 ${outputPath},并设置为只读`)
70
+ } catch (chmodError) {
71
+ console.warn(`警告: 无法设置文件为只读: ${chmodError.message}`)
72
+ console.log(`成功! swagger.json 已保存到 ${outputPath}`)
73
+ }
74
+ })
75
+ })
76
+ .on('error', (error) => {
77
+ console.error('下载失败:', error.message)
78
+ process.exit(1)
79
+ })
@@ -0,0 +1,409 @@
1
+ function generateKeyName(url, method) {
2
+ // 移除前缀 "/api/app"
3
+ const cleanedUrl = url.replace(/\/api\/app/, "");
4
+ const arr = cleanedUrl.split("/");
5
+
6
+ // 处理 {xxx} 转换为 ByXxx
7
+ const processedArr = arr.map(
8
+ item =>
9
+ item
10
+ .replace(/{(.*?)}/, (_, param) => `By${param.charAt(0).toUpperCase() + param.slice(1)}`) // 处理 {xxx}
11
+ .replace(/[-_]/g, "") // 去除 - 和 _
12
+ );
13
+
14
+ // 删除第一个空项
15
+ if (processedArr[0] === "") {
16
+ processedArr.shift();
17
+ }
18
+
19
+ // 去重和拼接相邻相同的项
20
+ const resultArr = [];
21
+ for (let i = 0; i < processedArr.length; i++) {
22
+ if (i === 0 || processedArr[i] !== processedArr[i - 1]) {
23
+ // 将每项首字母大写
24
+ const capitalizedItem = processedArr[i].charAt(0).toUpperCase() + processedArr[i].slice(1);
25
+ resultArr.push(capitalizedItem);
26
+ }
27
+ }
28
+ const key = resultArr.join("");
29
+ return `${method.toLowerCase()}${key}`;
30
+ }
31
+ const vue2Template = (moduleName, config = {}) => {
32
+ // 生成各种接口的key名称
33
+ let pageUrlKey = "",
34
+ exportUrlKey = "",
35
+ addUrlKey = "",
36
+ editUrlKey = "",
37
+ deleteUrlKey = "",
38
+ detailUrlKey = "",
39
+ baseUrlKey = ""; //接口选择优先级:新增 > 编辑 > 详,
40
+
41
+ if (config.pageUrl) pageUrlKey = generateKeyName(config.pageUrl, "get");
42
+ if (config.exportUrl) exportUrlKey = generateKeyName(config.exportUrl, "post");
43
+ if (config.detailUrl) {
44
+ detailUrlKey = generateKeyName(config.detailUrl, "get");
45
+ baseUrlKey = `${detailUrlKey}CompleteUrl`; //补充后缀
46
+ }
47
+ if (config.editUrl) {
48
+ editUrlKey = generateKeyName(config.editUrl, "put");
49
+ baseUrlKey = `${editUrlKey}CompleteUrl`; //补充后缀
50
+ }
51
+ if (config.addUrl) baseUrlKey = addUrlKey = generateKeyName(config.addUrl, "post");
52
+ if (config.deleteUrl) deleteUrlKey = generateKeyName(config.deleteUrl, "delete");
53
+
54
+ // 生成导入语句
55
+ const generateImports = () => {
56
+ const imports = [];
57
+ if (config.pageUrl) imports.push(`${pageUrlKey}`);
58
+ if (config.addUrl) imports.push(`${addUrlKey}`);
59
+ if (config.editUrl) imports.push(`${editUrlKey}`);
60
+ if (config.detailUrl) imports.push(`${detailUrlKey}`);
61
+ if (config.deleteUrl) imports.push(`${deleteUrlKey}`);
62
+ return imports.join(", ");
63
+ };
64
+
65
+ // 生成方法
66
+ const generateMethods = () => {
67
+ const methods = [];
68
+
69
+ // onCancel
70
+ if (config.hasAdd || config.hasEdit || config.hasDetail) {
71
+ methods.push(`
72
+ onCancel() {
73
+ this.formConfig.dialogVisible = false;
74
+ }`);
75
+ }
76
+
77
+ // onSubmit
78
+ if (config.hasAdd || config.hasEdit) {
79
+ methods.push(`
80
+ async onSubmit({ form, data }) {
81
+ if(form.type === 1){
82
+ //新建
83
+ const res = await ${addUrlKey}(data);
84
+ if(res.code !== 200) return;
85
+ this.$message("新建成功");
86
+ }else if (form.type === 2) {
87
+ //编辑
88
+ const res = await ${editUrlKey}(data['${config.rowId}'], data);
89
+ if(res.code !== 200) return;
90
+ this.$message("编辑成功");
91
+ this.init();
92
+ };
93
+ this.init();
94
+ this.onCancel()
95
+ }`);
96
+ }
97
+
98
+ if (config.hasAdd) {
99
+ methods.push(`
100
+ addBtnHandler() {
101
+ this.formConfig.title = "新增";
102
+ this.formConfig.type = 1;
103
+ this.formConfig.formData = {};
104
+ this.formConfig.dialogVisible = true;
105
+ }`);
106
+ }
107
+
108
+ if (config.hasEdit) {
109
+ methods.push(`
110
+ ${config.hasDetail ? `async ` : ``}editBtnHandler() {
111
+ const data = this.multipleSelection;
112
+ if(data.length !== 1) return this.$message.info("请选择一条数据");
113
+ const row = data[0];
114
+ ${
115
+ config.hasDetail
116
+ ? `const { result = {} } = await ${detailUrlKey}(row.${config.rowId});
117
+ this.formConfig.formData = result || {};`
118
+ : `this.formConfig.formData = { ...row };`
119
+ }
120
+ this.formConfig.title = "编辑";
121
+ this.formConfig.type = 2;
122
+ this.formConfig.dialogVisible = true;
123
+ }`);
124
+ }
125
+
126
+ // 有详情
127
+ if (config.hasDetail) {
128
+ methods.push(`
129
+ async detailBtnHandler() {
130
+ const data = this.multipleSelection;
131
+ if(data.length !== 1) return this.$message.info("请选择一条数据");
132
+ const row = data[0];
133
+ const { result = {} } = await ${detailUrlKey}(row.${config.rowId});
134
+ this.formConfig.formData = result || {};
135
+ this.formConfig.title = "详情";
136
+ this.formConfig.type = 0;
137
+ this.formConfig.dialogVisible = true;
138
+ }`);
139
+ }
140
+
141
+ if (config.hasDelete) {
142
+ methods.push(`
143
+ deleteBtnHandler() {
144
+ const data = this.multipleSelection;
145
+ if(data.length !== 1) return this.$message.info("请选择一条数据");
146
+ const row = data[0];
147
+ this.$confirm('确认删除当前数据吗?', '提示', {
148
+ confirmButtonText: '确定',
149
+ cancelButtonText: '取消',
150
+ type: 'warning'
151
+ }).then(() => {
152
+ ${deleteUrlKey}(row.${config.rowId}).then(() => {
153
+ this.$message.success('删除成功');
154
+ this.init();
155
+ }).catch(() => {
156
+ this.$message.error('删除失败');
157
+ });
158
+ }).catch(() => {});
159
+ }`);
160
+ }
161
+
162
+ if (config.hasExport) {
163
+ methods.push(`
164
+ export() {
165
+ this.post({
166
+ url: ${config.swaggerModule}.${exportUrlKey},
167
+ isLoading: true,
168
+ responseType: "blob",
169
+ data: Object.assign(this.formSearchData.value, {
170
+ Page: this.paginations.page,
171
+ MaxResultCount: this.paginations.limit
172
+ })
173
+ }).then(res => {
174
+ this.fnexsl(res);
175
+ });
176
+ }`);
177
+ }
178
+ return methods.join(",");
179
+ };
180
+
181
+ return `<!--
182
+ Filename: ${moduleName}.vue
183
+ name: ${moduleName}
184
+ Created Date: ${new Date().toLocaleString()}
185
+ Author:
186
+ -->
187
+ <template>
188
+ <div class="ol-container">
189
+ <ol-search
190
+ :url="swaggerUrl.${pageUrlKey}"
191
+ :form-search-data="formSearchData"
192
+ @handleSearch="handleSearch"
193
+ @handleReset="handleReset"
194
+ />
195
+ <ol-table
196
+ :url="swaggerUrl.${pageUrlKey}"
197
+ :paginations="paginations"
198
+ :btnlist="this.hasBtn(this)"
199
+ :empty-img="tableData.emptyImg"
200
+ :table-data="tableData"
201
+ :multiple-selection="multipleSelection"
202
+ @SelectionChange="SelectionChange"
203
+ @handleSizeChange="handleSizeChange"
204
+ @handleindexChange="handleindexChange"
205
+ />
206
+ ${config.hasDialog ? ` <el-dialog :title="formConfig.title" :visible.sync="formConfig.dialogVisible" width="80%">
207
+ <FormModule
208
+ v-if="formConfig.dialogVisible"
209
+ :formData="formConfig.formData"
210
+ :type="formConfig.type"
211
+ @onCancel="onCancel"
212
+ @onSubmit="onSubmit"
213
+ />
214
+ </el-dialog>
215
+ </div>` : "</div>"}
216
+ </template>
217
+ <script>
218
+ import { ${generateImports()} } from "@/api/modules";
219
+ import { ${config.swaggerModule} } from '@/api/swagger';
220
+ ${config.hasDialog ? `import FormModule from "./components/formModule.vue"` : ""}
221
+ export default {
222
+ name: "${moduleName}",
223
+ ${
224
+ config.hasDialog
225
+ ? `components: {
226
+ FormModule
227
+ },`
228
+ : ""
229
+ }
230
+ data() {
231
+ return {
232
+ swaggerUrl: ${config.swaggerModule},
233
+ multipleSelection: [],
234
+ // 查询表单
235
+ formSearchData: {
236
+ reset: true, // 重置
237
+ expendShow: true, // 展开
238
+ value: {},
239
+ tableSearch: []
240
+ },
241
+ // 表格数据
242
+ tableData: {
243
+ loading: false,
244
+ emptyImg: true,
245
+ options: {
246
+ selection: true, // 多选框
247
+ index: null, // 序号
248
+ headTool: true, // 开启头部工具栏
249
+ refreshBtn: true, // 开启表格头部刷新按钮
250
+ downloadBtn: true // 开启表格头部下载按钮
251
+ }, // 序号和复选框
252
+ rows: [], // 表数据
253
+ columns: [],
254
+ operatesAttrs: {},
255
+ operates: [], // 表格里面的操作按钮
256
+ tableHeightDiff: 330
257
+ },
258
+ paginations: {
259
+ page: 1, // 当前位于那页面
260
+ total: 10, // 总数
261
+ limit: 30, // 一页显示多少条
262
+ pagetionShow: true
263
+ },
264
+ ${
265
+ config.hasDialog
266
+ ? `formConfig: {
267
+ type: 1,
268
+ formData: {},
269
+ title:"",
270
+ dialogVisible: false
271
+ }`
272
+ : ""
273
+ }
274
+ }
275
+ },
276
+ created() {
277
+ this.init()
278
+ },
279
+ methods: {
280
+ async init() {
281
+ const params = {
282
+ ...this.formSearchData.value,
283
+ Page: this.paginations.page,
284
+ MaxResultCount: this.paginations.limit
285
+ };
286
+ const { result: { items = [], totalCount = 0 } = {} } = await ${pageUrlKey}(params, {
287
+ isLoading: true
288
+ });
289
+ this.tableData.rows = items;
290
+ this.paginations.total = totalCount;
291
+ this.tableData.emptyImg = true;
292
+ },
293
+ handleSearch(from) {
294
+ this.formSearchData.value = { ...from };
295
+ this.paginations.page = 1;
296
+ this.init();
297
+ },
298
+ handleReset() {
299
+ for (let key in this.formSearchData.value) {
300
+ this.formSearchData.value[key] = null;
301
+ }
302
+ this.paginations.page = 1;
303
+ },
304
+ SelectionChange(row) {
305
+ this.multipleSelection = row;
306
+ },
307
+ handleSizeChange(val) {
308
+ this.paginations.page = 1;
309
+ this.paginations.limit = val;
310
+ this.init();
311
+ },
312
+ handleindexChange(val) {
313
+ this.paginations.page = val;
314
+ this.init();
315
+ },${generateMethods()}
316
+ }
317
+ }
318
+ </script>
319
+ `;
320
+ };
321
+
322
+ const vue2Form = (moduleName, config = {}) => {
323
+
324
+ let editUrlKey = "",
325
+ detailUrlKey = "",
326
+ baseUrlKey = "";
327
+
328
+ if (config.detailUrl) {
329
+ detailUrlKey = generateKeyName(config.detailUrl, "get");
330
+ baseUrlKey = `${detailUrlKey}CompleteUrl`; //补充后缀
331
+ }
332
+
333
+ if (config.editUrl) {
334
+ editUrlKey = generateKeyName(config.editUrl, "put");
335
+ baseUrlKey = `${editUrlKey}CompleteUrl`; //补充后缀
336
+ }
337
+
338
+ if (config.addUrl) baseUrlKey = generateKeyName(config.addUrl, "post");
339
+
340
+ return `<!--
341
+ Filename: ${moduleName}.vue
342
+ name: ${moduleName}
343
+ Created Date: ${new Date().toLocaleString()}
344
+ Author:
345
+ -->
346
+ <template>
347
+ <ol-form
348
+ :url="swaggerUrl.${baseUrlKey}"
349
+ :form="form"
350
+ @onCancel="onCancel"
351
+ @onSubmit="onSubmit"
352
+ />
353
+ </template>
354
+ <script>
355
+ import { ${config.swaggerModule} } from '@/api/swagger';
356
+ export default {
357
+ name: "${moduleName}Form",
358
+ props: {
359
+ formData: {
360
+ type: Object,
361
+ default: () => ({})
362
+ },
363
+ type: {
364
+ type: Number,
365
+ default: 1
366
+ }
367
+ },
368
+ data() {
369
+ return {
370
+ swaggerUrl: ${config.swaggerModule},
371
+ form: {
372
+ type: this.type, // 0详情,1新增, 2编辑
373
+ title: "",
374
+ defaultValue: {}, // 默认值
375
+ value: {},
376
+ model: [],
377
+ rules: {},
378
+ attrs: {},
379
+ }
380
+ }
381
+ },
382
+ watch: {
383
+ type: {
384
+ handler(val){
385
+ this.form.type = val;
386
+ },
387
+ immediate: true
388
+ }
389
+ },
390
+ created(){
391
+ if(this.type !== 1) this.form.value = { ...this.formData };
392
+ },
393
+ methods: {
394
+ onCancel() {
395
+ this.$emit("onCancel");
396
+ },
397
+ onSubmit({form, data}) {
398
+ this.$emit("onSubmit", { form, data });
399
+ }
400
+ }
401
+ }
402
+ </script>
403
+ `;
404
+ };
405
+
406
+ module.exports = {
407
+ vue2Template,
408
+ vue2Form,
409
+ };