tanyu_admin 1.0.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.
@@ -0,0 +1,29 @@
1
+ const axios = require('axios');
2
+ const qs = require('qs');
3
+
4
+ let data = qs.stringify({
5
+ 'IF_ENCODE': 'V3+M9KUe3Wem533P6CXo7Pr79X8pmCLI/WAQPybu1Rmrzk8fvXbcz97Kx+z9BIJnOyo7s4DsV4GI6CLGxLHZEciVX5Os5+u5/yIrU0k+LZ+BiYMVL2q7Zxda/krU+2XHRdi/E1L+VjUh5P1PQ4WN5xpFgfY4eCGqhsjEnAg28ZBGapBB7/14UxZnD6JX230kUa3lfdT6LPnTPU+Mf8cB0dJjU5v62ba9QjI6dYmhffXochfDh3ndeGZoYlgxQpL1FSyJTIRRCu+P15BXKekTKWEJ2Uhi9iZY0RUY3Ne6dp5K85KIowxG9eBC5tNXFB55M3MQvN9762HQmoyLZMTm3A==',
6
+ 'IF_ENCODEPARAM': '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'
7
+ });
8
+
9
+ let config = {
10
+ method: 'POST',
11
+ url: 'http://192.168.1.1/getpage.gch?pid=1002&nextpage=app_virtual_conf_t.gch',
12
+ headers: {
13
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36',
14
+ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
15
+ 'Content-Type': 'application/x-www-form-urlencoded',
16
+ 'Accept-Language': 'zh-CN,zh;q=0.9',
17
+ 'Cache-Control': 'max-age=0',
18
+ 'Origin': 'http://192.168.1.1',
19
+ 'Proxy-Connection': 'keep-alive',
20
+ 'Referer': 'http://192.168.1.1/getpage.gch?pid=1002&nextpage=app_virtual_conf_t.gch',
21
+ 'Upgrade-Insecure-Requests': '1',
22
+ 'Cookie': '_TESTCOOKIESUPPORT=1; SID=28b56d3b5a6b6eb4f32557ba8b843f634deabd4f69c4dceaa5b445adc47e06fb'
23
+ },
24
+ data: data
25
+ };
26
+
27
+ axios.request(config)
28
+ .then(response => console.log(response))
29
+ .catch(error => console.log('error', error));
@@ -0,0 +1,29 @@
1
+ const axios = require('axios');
2
+ const qs = require('qs');
3
+
4
+ let data = qs.stringify({
5
+ 'IF_ENCODE': "cBdTJBUFObmLbtm99LwstDJzhVkcPOvShgpiGnwhLYdFNeJ3PqrgOgfFosOeve6BxfSXfLDouNwrDuxWS0VnLDE+XdANTjYFt0TJghOE+3cfZ6s0KVap6WSkMyySfdsoYaK2kctFFnrw8pUxCeIh8LAoGi33DFGeUo6ZL3oMxrCHo1gM54pl/kulVrC6u/Efol/bkD3BDNeyjLmMwZhb17pmejEoDj6KqJJftG4xMdEQTlm/iblEcoHu5NTP7aBitAT+rMAizC+pygmvGqlxgPklrS5GOGrF/NI08j/yfeDKzgIyj4+qELC/riUuF5M6i0b13+1+jYDU98lZZxx1Jg==",
6
+ 'IF_ENCODEPARAM': "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"
7
+ });
8
+
9
+ let config = {
10
+ method: 'POST',
11
+ url: 'http://192.168.1.1/getpage.gch?pid=1002&nextpage=app_virtual_conf_t.gch',
12
+ headers: {
13
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36',
14
+ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
15
+ 'Content-Type': 'application/x-www-form-urlencoded',
16
+ 'Accept-Language': 'zh-CN,zh;q=0.9',
17
+ 'Cache-Control': 'max-age=0',
18
+ 'Origin': 'http://192.168.1.1',
19
+ 'Proxy-Connection': 'keep-alive',
20
+ 'Referer': 'http://192.168.1.1/template.gch?pid=1002&nextpage=app_virtual_conf_t.gch',
21
+ 'Upgrade-Insecure-Requests': '1',
22
+ 'Cookie': 'SID=946e3dfb38e6fdbf66ffabe0d58a63573ebef289d9b008545415989d10b1e1e0; _TESTCOOKIESUPPORT=1'
23
+ },
24
+ data: data
25
+ };
26
+
27
+ axios.request(config)
28
+ .then(response => console.log(response))
29
+ .catch(error => console.log('error', error));
@@ -0,0 +1,57 @@
1
+ /**
2
+ * axios-interceptor 使用示例
3
+ */
4
+
5
+ // 方式1: 使用默认实例
6
+ const { axios } = require('./axios-interceptor');
7
+
8
+ async function example1() {
9
+ console.log('=== 示例1: 使用默认实例 ===\n');
10
+
11
+ try {
12
+ // GET 请求
13
+ await axios.get('http://192.168.1.1/cu.html');
14
+
15
+ // POST 请求
16
+ await axios.post('http://192.168.1.1/cu.html', {
17
+ username: 'admin',
18
+ password: 'test123'
19
+ });
20
+ } catch (error) {
21
+ // 错误已经被拦截器记录
22
+ }
23
+ }
24
+
25
+ // 方式2: 创建自定义实例
26
+ const { createAxiosInstance } = require('./axios-interceptor');
27
+
28
+ async function example2() {
29
+ console.log('\n=== 示例2: 创建自定义实例 ===\n');
30
+
31
+ const customAxios = createAxiosInstance({
32
+ baseURL: 'http://192.168.1.1',
33
+ timeout: 5000,
34
+ headers: {
35
+ 'User-Agent': 'Custom Agent'
36
+ }
37
+ });
38
+
39
+ try {
40
+ await customAxios.get('/cu.html');
41
+ } catch (error) {
42
+ // 错误已经被拦截器记录
43
+ }
44
+ }
45
+
46
+ // 方式3: 在现有代码中替换 axios
47
+ // 在 index.js 或 modem-api.js 中:
48
+ // const axios = require('axios'); // 旧代码
49
+ // const { axios } = require('./axios-interceptor'); // 新代码
50
+
51
+ // 运行示例
52
+ if (require.main === module) {
53
+ (async () => {
54
+ await example1();
55
+ await example2();
56
+ })();
57
+ }
@@ -0,0 +1,191 @@
1
+ const axios = require('axios');
2
+
3
+ /**
4
+ * 格式化日志时间戳
5
+ */
6
+ function formatTimestamp() {
7
+ const now = new Date();
8
+ return now.toISOString().replace('T', ' ').substring(0, 23);
9
+ }
10
+
11
+ /**
12
+ * 格式化请求数据用于日志输出
13
+ */
14
+ function formatRequestData(data) {
15
+ if (!data) return '';
16
+
17
+ // 如果是字符串且很长,截断显示
18
+ if (typeof data === 'string') {
19
+ return data.length > 200 ? data.substring(0, 200) + '...' : data;
20
+ }
21
+
22
+ // 如果是对象,转为JSON
23
+ try {
24
+ const json = JSON.stringify(data);
25
+ return json.length > 200 ? json.substring(0, 200) + '...' : json;
26
+ } catch (e) {
27
+ return '[Complex Data]';
28
+ }
29
+ }
30
+
31
+ /**
32
+ * 创建配置好拦截器的 axios 实例
33
+ */
34
+ function createAxiosInstance(options = {}) {
35
+ // 合并默认配置和用户配置
36
+ const defaultConfig = {
37
+ // 代理配置 - 代理到本地7897端口(用于调试/抓包)
38
+ // 可通过环境变量 ENABLE_PROXY=false 禁用
39
+ proxy: {
40
+ host: '127.0.0.1',
41
+ port: 7897,
42
+ protocol: 'http'
43
+ }
44
+ };
45
+
46
+ const instance = axios.create({ ...defaultConfig, ...options });
47
+
48
+ // 请求拦截器
49
+ instance.interceptors.request.use(
50
+ (config) => {
51
+ // 记录请求开始时间
52
+ config.metadata = { startTime: Date.now() };
53
+
54
+ // 构建日志信息
55
+ const logParts = [
56
+ `[${formatTimestamp()}]`,
57
+ `[REQUEST]`,
58
+ `${config.method?.toUpperCase() || 'GET'}`,
59
+ config.url
60
+ ];
61
+
62
+ // 添加查询参数信息
63
+ if (config.params) {
64
+ logParts.push(`| Params: ${JSON.stringify(config.params)}`);
65
+ }
66
+
67
+ // 添加请求体信息(如果有)
68
+ if (config.data) {
69
+ const formattedData = formatRequestData(config.data);
70
+ if (formattedData) {
71
+ logParts.push(`| Data: ${formattedData}`);
72
+ }
73
+ }
74
+
75
+ // 添加重要的请求头信息
76
+ if (config.headers) {
77
+ const importantHeaders = {};
78
+ if (config.headers['Content-Type']) {
79
+ importantHeaders['Content-Type'] = config.headers['Content-Type'];
80
+ }
81
+ if (config.headers['Cookie']) {
82
+ importantHeaders['Cookie'] = '[REDACTED]'; // 隐藏敏感信息
83
+ }
84
+ if (config.headers['Authorization']) {
85
+ importantHeaders['Authorization'] = '[REDACTED]'; // 隐藏敏感信息
86
+ }
87
+
88
+ if (Object.keys(importantHeaders).length > 0) {
89
+ logParts.push(`| Headers: ${JSON.stringify(importantHeaders)}`);
90
+ }
91
+ }
92
+
93
+ // console.log(logParts.join(' '));
94
+
95
+ return config;
96
+ },
97
+ (error) => {
98
+ console.error(`[${formatTimestamp()}] [REQUEST ERROR]`, error.message);
99
+ return Promise.reject(error);
100
+ }
101
+ );
102
+
103
+ // 响应拦截器
104
+ instance.interceptors.response.use(
105
+ (response) => {
106
+ // 计算请求耗时
107
+ const duration = response.config.metadata
108
+ ? Date.now() - response.config.metadata.startTime
109
+ : 0;
110
+
111
+ // 构建日志信息
112
+ const logParts = [
113
+ `[${formatTimestamp()}]`,
114
+ `[RESPONSE]`,
115
+ `${response.config.method?.toUpperCase() || 'GET'}`,
116
+ response.config.url,
117
+ `| Status: ${response.status}`,
118
+ `| Duration: ${duration}ms`
119
+ ];
120
+
121
+ // 添加响应大小信息
122
+ if (response.data) {
123
+ let dataSize = 0;
124
+ if (typeof response.data === 'string') {
125
+ dataSize = response.data.length;
126
+ } else if (Buffer.isBuffer(response.data)) {
127
+ dataSize = response.data.length;
128
+ } else {
129
+ try {
130
+ dataSize = JSON.stringify(response.data).length;
131
+ } catch (e) {
132
+ dataSize = 0;
133
+ }
134
+ }
135
+
136
+ if (dataSize > 0) {
137
+ const sizeKB = (dataSize / 1024).toFixed(2);
138
+ logParts.push(`| Size: ${sizeKB}KB`);
139
+ }
140
+ }
141
+
142
+ // console.log(logParts.join(' ')); // 已禁用 RESPONSE 日志
143
+
144
+ return response;
145
+ },
146
+ (error) => {
147
+ // 计算请求耗时
148
+ const duration = error.config?.metadata
149
+ ? Date.now() - error.config.metadata.startTime
150
+ : 0;
151
+
152
+ // 构建错误日志
153
+ const logParts = [
154
+ `[${formatTimestamp()}]`,
155
+ `[RESPONSE ERROR]`,
156
+ `${error.config?.method?.toUpperCase() || 'GET'}`,
157
+ error.config?.url || 'Unknown URL'
158
+ ];
159
+
160
+ if (error.response) {
161
+ // 服务器返回了错误状态码
162
+ logParts.push(`| Status: ${error.response.status}`);
163
+ logParts.push(`| Duration: ${duration}ms`);
164
+ logParts.push(`| Error: ${error.message}`);
165
+ } else if (error.request) {
166
+ // 请求已发送但没有收到响应
167
+ logParts.push(`| Duration: ${duration}ms`);
168
+ logParts.push(`| Error: No response received - ${error.message}`);
169
+ } else {
170
+ // 请求配置出错
171
+ logParts.push(`| Error: ${error.message}`);
172
+ }
173
+
174
+ // console.error(logParts.join(' ')); // 已禁用 RESPONSE ERROR 日志
175
+
176
+ return Promise.reject(error);
177
+ }
178
+ );
179
+
180
+ return instance;
181
+ }
182
+
183
+ // 创建默认实例
184
+ const axiosInstance = createAxiosInstance();
185
+
186
+ // 导出
187
+ module.exports = {
188
+ default: axiosInstance,
189
+ createAxiosInstance,
190
+ axios: axiosInstance
191
+ };
package/cli.js ADDED
@@ -0,0 +1,313 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { Command } = require('commander');
4
+ const Table = require('cli-table3');
5
+ const chalk = require('chalk');
6
+ const { refreshFromModem, addHost, deleteHost } = require('./modem-api');
7
+ const { loadConfigFromFile, saveConfigToJson } = require('./parser');
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+
11
+ const program = new Command();
12
+
13
+ // 配置文件路径
14
+ const CACHE_DIR = './.cache';
15
+ const CACHE_HTML = path.join(CACHE_DIR, 'page.html');
16
+ const DATA_FILE = './virtual_hosts.json';
17
+
18
+ /**
19
+ * 格式化协议显示
20
+ */
21
+ function formatProtocol(protocol) {
22
+ const protocolMap = {
23
+ '0': 'TCP',
24
+ '1': 'UDP',
25
+ '2': 'TCP/UDP'
26
+ };
27
+ return protocolMap[protocol] || protocol;
28
+ }
29
+
30
+ /**
31
+ * 格式化启用状态
32
+ */
33
+ function formatEnable(enable) {
34
+ if (enable === '1') {
35
+ return chalk.green('✓ 启用');
36
+ } else {
37
+ return chalk.red('✗ 禁用');
38
+ }
39
+ }
40
+
41
+ /**
42
+ * 验证 IP 地址格式
43
+ */
44
+ function isValidIP(ip) {
45
+ const ipRegex = /^(\d{1,3}\.){3}\d{1,3}$/;
46
+ if (!ipRegex.test(ip)) return false;
47
+
48
+ const parts = ip.split('.');
49
+ return parts.every(part => {
50
+ const num = parseInt(part, 10);
51
+ return num >= 0 && num <= 255;
52
+ });
53
+ }
54
+
55
+ /**
56
+ * 验证端口号
57
+ */
58
+ function isValidPort(port) {
59
+ const portNum = parseInt(port, 10);
60
+ return !isNaN(portNum) && portNum >= 1 && portNum <= 65535;
61
+ }
62
+
63
+ /**
64
+ * router add 命令 - 快速添加端口转发规则
65
+ */
66
+ async function addRouter(ip, port, name) {
67
+ try {
68
+ // 验证 IP 地址
69
+ if (!isValidIP(ip)) {
70
+ console.error(chalk.red('✗ 无效的 IP 地址:'), ip);
71
+ console.log(chalk.yellow('提示: IP 地址格式应为 xxx.xxx.xxx.xxx'));
72
+ process.exit(1);
73
+ }
74
+
75
+ // 验证端口号
76
+ if (!isValidPort(port)) {
77
+ console.error(chalk.red('✗ 无效的端口号:'), port);
78
+ console.log(chalk.yellow('提示: 端口号范围应为 1-65535'));
79
+ process.exit(1);
80
+ }
81
+
82
+ console.log(chalk.blue('正在添加端口转发规则...'));
83
+ console.log(chalk.gray(` 名称: ${name}`));
84
+ console.log(chalk.gray(` 内部主机: ${ip}`));
85
+ console.log(chalk.gray(` 端口: ${port} (外部) -> ${port} (内部)`));
86
+ console.log(chalk.gray(` 协议: TCP/UDP`));
87
+
88
+ // 构建配置对象
89
+ const hostConfig = {
90
+ Name: name,
91
+ InternalHost: ip,
92
+ MinExtPort: port,
93
+ MaxExtPort: port,
94
+ MinIntPort: port,
95
+ MaxIntPort: port,
96
+ Protocol: '2', // TCP/UDP
97
+ Enable: '1', // 启用
98
+ WANCViewName: 'IGD.WD1.WCD2.WCPPP1',
99
+ WANCName: '',
100
+ Description: 'NULL',
101
+ LeaseDuration: 'NULL',
102
+ PortMappCreator: 'NULL',
103
+ MinRemoteHost: '0.0.0.0',
104
+ MaxRemoteHost: '0.0.0.0',
105
+ InternalMacHost: 'NULL',
106
+ MacEnable: '0'
107
+ };
108
+
109
+ // 提交到光猫
110
+ const result = await addHost(hostConfig);
111
+
112
+ if (result.success) {
113
+ console.log(chalk.green('\n✓ 端口转发规则添加成功!'));
114
+
115
+ // 更新本地缓存
116
+ if (result.html) {
117
+ // 确保 .cache 目录存在
118
+ if (!fs.existsSync(CACHE_DIR)) {
119
+ fs.mkdirSync(CACHE_DIR, { recursive: true });
120
+ }
121
+
122
+ fs.writeFileSync(CACHE_HTML, result.html);
123
+ const configs = loadConfigFromFile(CACHE_HTML);
124
+ saveConfigToJson(configs, DATA_FILE);
125
+
126
+ console.log(chalk.gray(`配置已同步到本地缓存`));
127
+ }
128
+ } else {
129
+ console.error(chalk.red('\n✗ 添加失败:'), result.error || '未知错误');
130
+ process.exit(1);
131
+ }
132
+
133
+ } catch (error) {
134
+ console.error(chalk.red('✗ 错误:'), error.message);
135
+ process.exit(1);
136
+ }
137
+ }
138
+
139
+ /**
140
+ * router del 命令 - 根据索引删除端口转发规则
141
+ */
142
+ async function deleteRouter(index) {
143
+ try {
144
+ // 验证索引是否为有效数字
145
+ const indexNum = parseInt(index, 10);
146
+ if (isNaN(indexNum) || indexNum < 0) {
147
+ console.error(chalk.red('✗ 无效的索引号:'), index);
148
+ console.log(chalk.yellow('提示: 索引号必须是非负整数'));
149
+ console.log(chalk.gray('使用'), chalk.cyan('router list'), chalk.gray('查看所有配置的索引号'));
150
+ process.exit(1);
151
+ }
152
+
153
+ console.log(chalk.blue(`正在删除索引为 ${indexNum} 的配置...`));
154
+
155
+ // 执行删除
156
+ const result = await deleteHost(indexNum);
157
+
158
+ if (result.success) {
159
+ console.log(chalk.green('\n✓ 端口转发规则删除成功!'));
160
+
161
+ // 更新本地缓存
162
+ if (result.html) {
163
+ // 确保 .cache 目录存在
164
+ if (!fs.existsSync(CACHE_DIR)) {
165
+ fs.mkdirSync(CACHE_DIR, { recursive: true });
166
+ }
167
+
168
+ fs.writeFileSync(CACHE_HTML, result.html);
169
+ const updatedConfigs = loadConfigFromFile(CACHE_HTML);
170
+ saveConfigToJson(updatedConfigs, DATA_FILE);
171
+
172
+ console.log(chalk.gray(`配置已同步到本地缓存`));
173
+ }
174
+ } else {
175
+ console.error(chalk.red('\n✗ 删除失败:'), result.error || '未知错误');
176
+ process.exit(1);
177
+ }
178
+
179
+ } catch (error) {
180
+ console.error(chalk.red('✗ 错误:'), error.message);
181
+ process.exit(1);
182
+ }
183
+ }
184
+
185
+ /**
186
+ * router list 命令 - 列出所有虚拟主机配置
187
+ */
188
+ async function listRouters(options) {
189
+ try {
190
+ // console.log(chalk.blue('正在从光猫获取配置...'));
191
+
192
+ // 从光猫刷新配置
193
+ const refreshResult = await refreshFromModem();
194
+
195
+ if (!refreshResult.success) {
196
+ console.error(chalk.red('✗ 获取配置失败:'), refreshResult.error);
197
+ process.exit(1);
198
+ }
199
+
200
+ // 确保 .cache 目录存在
201
+ if (!fs.existsSync(CACHE_DIR)) {
202
+ fs.mkdirSync(CACHE_DIR, { recursive: true });
203
+ }
204
+
205
+ // 保存 HTML 到缓存
206
+ fs.writeFileSync(CACHE_HTML, refreshResult.html);
207
+
208
+ // 解析配置
209
+ const configs = loadConfigFromFile(CACHE_HTML);
210
+
211
+ // 保存到 JSON
212
+ saveConfigToJson(configs, DATA_FILE);
213
+
214
+ if (configs.length === 0) {
215
+ console.log(chalk.yellow('没有找到任何虚拟主机配置'));
216
+ return;
217
+ }
218
+
219
+ // console.log(chalk.green(`\n✓ 成功获取 ${configs.length} 个虚拟主机配置\n`));
220
+
221
+ // 创建表格
222
+ const table = new Table({
223
+ head: [
224
+ chalk.cyan('索引'),
225
+ chalk.cyan('名称'),
226
+ chalk.cyan('状态'),
227
+ chalk.cyan('协议'),
228
+ chalk.cyan('外部端口'),
229
+ chalk.cyan('内部主机'),
230
+ chalk.cyan('内部端口'),
231
+ chalk.cyan('WAN连接')
232
+ ],
233
+ colWidths: [6, 20, 10, 10, 12, 16, 12, 25]
234
+ });
235
+
236
+ // 添加数据行
237
+ configs.forEach((config) => {
238
+ const extPort = config.MinExtPort === config.MaxExtPort
239
+ ? config.MinExtPort
240
+ : `${config.MinExtPort}-${config.MaxExtPort}`;
241
+
242
+ const intPort = config.MinIntPort === config.MaxIntPort
243
+ ? config.MinIntPort
244
+ : `${config.MinIntPort}-${config.MaxIntPort}`;
245
+
246
+ table.push([
247
+ config.index,
248
+ config.Name || '-',
249
+ formatEnable(config.Enable),
250
+ formatProtocol(config.Protocol),
251
+ extPort,
252
+ config.InternalHost || '-',
253
+ intPort,
254
+ config.WANCName || '-'
255
+ ]);
256
+ });
257
+
258
+ console.log(table.toString());
259
+
260
+ // 显示详细信息选项
261
+ if (options.verbose) {
262
+ console.log(chalk.gray('\n详细信息:'));
263
+ configs.forEach((config, idx) => {
264
+ console.log(chalk.gray(`\n[${idx + 1}] ${config.Name}`));
265
+ console.log(chalk.gray(` ViewName: ${config.ViewName}`));
266
+ console.log(chalk.gray(` WANCViewName: ${config.WANCViewName}`));
267
+ console.log(chalk.gray(` Description: ${config.Description || '无'}`));
268
+ console.log(chalk.gray(` RemoteHost: ${config.MinRemoteHost}-${config.MaxRemoteHost}`));
269
+ console.log(chalk.gray(` MacEnable: ${config.MacEnable}`));
270
+ console.log(chalk.gray(` InternalMacHost: ${config.InternalMacHost}`));
271
+ });
272
+ }
273
+
274
+ // console.log(chalk.gray(`\n配置已保存到: ${DATA_FILE}`));
275
+
276
+ } catch (error) {
277
+ console.error(chalk.red('✗ 错误:'), error.message);
278
+ process.exit(1);
279
+ }
280
+ }
281
+
282
+ // 配置 CLI
283
+ program
284
+ .name('router')
285
+ .description('虚拟主机管理命令行工具')
286
+ .version('1.0.0');
287
+
288
+ // router list 命令
289
+ program
290
+ .command('list')
291
+ .description('列出所有虚拟主机配置')
292
+ .option('-v, --verbose', '显示详细信息')
293
+ .action(listRouters);
294
+
295
+ // router add 命令
296
+ program
297
+ .command('add <ip> <port> <name>')
298
+ .description('快速添加端口转发规则 (外部端口和内部端口一致)')
299
+ .action(addRouter);
300
+
301
+ // router del 命令
302
+ program
303
+ .command('del <index>')
304
+ .description('根据索引删除端口转发规则')
305
+ .action(deleteRouter);
306
+
307
+ // 解析命令行参数
308
+ program.parse(process.argv);
309
+
310
+ // 如果没有提供任何命令,显示帮助信息
311
+ if (!process.argv.slice(2).length) {
312
+ program.outputHelp();
313
+ }
@@ -0,0 +1,5 @@
1
+ Traceback (most recent call last):
2
+ File "<string>", line 1, in <module>
3
+ import sys; sys.stdout.reconfigure(encoding='utf-8'); exec(open('search.py').read())
4
+ ~~~~~~~~~~~~~~~~~~~~~~^^
5
+ UnicodeDecodeError: 'gbk' codec can't decode byte 0x85 in position 3913: illegal multibyte sequence