216 lines
4.9 KiB
JavaScript
216 lines
4.9 KiB
JavaScript
const express = require('express')
|
||
const router = express.Router()
|
||
const { promisify } = require('util')
|
||
const { exec } = require('child_process')
|
||
const execAsync = promisify(exec)
|
||
|
||
// IP查询API
|
||
router.get('/ip/:ip?', async (req, res) => {
|
||
try {
|
||
const ip = req.params.ip || req.ip || req.connection.remoteAddress
|
||
|
||
// 如果是IPv6的IPv4映射地址,提取IPv4部分
|
||
const cleanIp = ip.replace(/^::ffff:/, '')
|
||
|
||
// 使用免费的IP查询服务
|
||
const fetch = require('node-fetch')
|
||
const response = await fetch(`http://ip-api.com/json/${cleanIp}?lang=zh-CN`)
|
||
const data = await response.json()
|
||
|
||
if (data.status === 'success') {
|
||
res.json({
|
||
success: true,
|
||
data: {
|
||
ip: cleanIp,
|
||
country: data.country,
|
||
region: data.regionName,
|
||
city: data.city,
|
||
isp: data.isp,
|
||
timezone: data.timezone,
|
||
lat: data.lat,
|
||
lon: data.lon
|
||
}
|
||
})
|
||
} else {
|
||
res.json({
|
||
success: false,
|
||
message: '无法查询该IP地址信息'
|
||
})
|
||
}
|
||
} catch (error) {
|
||
console.error('IP查询错误:', error)
|
||
res.status(500).json({
|
||
success: false,
|
||
message: '服务器内部错误'
|
||
})
|
||
}
|
||
})
|
||
|
||
// 获取当前IP
|
||
router.get('/myip', (req, res) => {
|
||
const ip = req.ip || req.connection.remoteAddress
|
||
const cleanIp = ip.replace(/^::ffff:/, '')
|
||
|
||
res.json({
|
||
success: true,
|
||
data: {
|
||
ip: cleanIp
|
||
}
|
||
})
|
||
})
|
||
|
||
// 代理请求API(用于HTTP测试工具)
|
||
router.post('/proxy', async (req, res) => {
|
||
try {
|
||
const { url, method = 'GET', headers = {}, body } = req.body
|
||
|
||
if (!url) {
|
||
return res.status(400).json({
|
||
success: false,
|
||
message: 'URL参数不能为空'
|
||
})
|
||
}
|
||
|
||
const fetch = require('node-fetch')
|
||
|
||
const options = {
|
||
method: method.toUpperCase(),
|
||
headers: {
|
||
'User-Agent': 'Vue-Tools-Kit/1.0.0',
|
||
...headers
|
||
}
|
||
}
|
||
|
||
if (body && ['POST', 'PUT', 'PATCH'].includes(options.method)) {
|
||
options.body = body
|
||
}
|
||
|
||
const startTime = Date.now()
|
||
const response = await fetch(url, options)
|
||
const endTime = Date.now()
|
||
|
||
const responseHeaders = {}
|
||
for (const [key, value] of response.headers.entries()) {
|
||
responseHeaders[key] = value
|
||
}
|
||
|
||
const responseBody = await response.text()
|
||
|
||
res.json({
|
||
success: true,
|
||
data: {
|
||
status: response.status,
|
||
statusText: response.statusText,
|
||
headers: responseHeaders,
|
||
body: responseBody,
|
||
responseTime: endTime - startTime,
|
||
url: response.url
|
||
}
|
||
})
|
||
|
||
} catch (error) {
|
||
console.error('代理请求错误:', error)
|
||
res.status(500).json({
|
||
success: false,
|
||
message: error.message || '请求失败'
|
||
})
|
||
}
|
||
})
|
||
|
||
// Markdown转换API
|
||
router.post('/markdown/convert', (req, res) => {
|
||
try {
|
||
const { content, type } = req.body
|
||
|
||
if (!content) {
|
||
return res.status(400).json({
|
||
success: false,
|
||
message: '内容不能为空'
|
||
})
|
||
}
|
||
|
||
if (type === 'html-to-md') {
|
||
// HTML转Markdown
|
||
const TurndownService = require('turndown')
|
||
const turndownService = new TurndownService()
|
||
const markdown = turndownService.turndown(content)
|
||
|
||
res.json({
|
||
success: true,
|
||
data: { result: markdown }
|
||
})
|
||
} else if (type === 'md-to-html') {
|
||
// Markdown转HTML
|
||
const { marked } = require('marked')
|
||
const html = marked(content)
|
||
|
||
res.json({
|
||
success: true,
|
||
data: { result: html }
|
||
})
|
||
} else {
|
||
res.status(400).json({
|
||
success: false,
|
||
message: '不支持的转换类型'
|
||
})
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('Markdown转换错误:', error)
|
||
res.status(500).json({
|
||
success: false,
|
||
message: '转换失败: ' + error.message
|
||
})
|
||
}
|
||
})
|
||
|
||
// 文件格式化API
|
||
router.post('/format/code', (req, res) => {
|
||
try {
|
||
const { content, type } = req.body
|
||
|
||
if (!content) {
|
||
return res.status(400).json({
|
||
success: false,
|
||
message: '内容不能为空'
|
||
})
|
||
}
|
||
|
||
let formatted = content
|
||
|
||
switch (type) {
|
||
case 'json':
|
||
try {
|
||
const parsed = JSON.parse(content)
|
||
formatted = JSON.stringify(parsed, null, 2)
|
||
} catch (e) {
|
||
throw new Error('JSON格式错误')
|
||
}
|
||
break
|
||
|
||
case 'xml':
|
||
// 简单的XML格式化
|
||
formatted = content
|
||
.replace(/></g, '>\n<')
|
||
.replace(/^\s*\n/gm, '')
|
||
break
|
||
|
||
default:
|
||
throw new Error('不支持的格式化类型')
|
||
}
|
||
|
||
res.json({
|
||
success: true,
|
||
data: { result: formatted }
|
||
})
|
||
|
||
} catch (error) {
|
||
console.error('代码格式化错误:', error)
|
||
res.status(500).json({
|
||
success: false,
|
||
message: error.message || '格式化失败'
|
||
})
|
||
}
|
||
})
|
||
|
||
module.exports = router
|