工具完成
This commit is contained in:
32
server/index.js
Normal file
32
server/index.js
Normal file
@ -0,0 +1,32 @@
|
||||
const express = require('express')
|
||||
const cors = require('cors')
|
||||
const path = require('path')
|
||||
|
||||
const app = express()
|
||||
const PORT = process.env.PORT || 3001
|
||||
|
||||
// 中间件
|
||||
app.use(cors())
|
||||
app.use(express.json())
|
||||
app.use(express.urlencoded({ extended: true }))
|
||||
|
||||
// 静态文件服务
|
||||
app.use(express.static(path.join(__dirname, '../dist')))
|
||||
|
||||
// API路由
|
||||
app.use('/api', require('./routes/api'))
|
||||
|
||||
// 健康检查
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok', timestamp: new Date().toISOString() })
|
||||
})
|
||||
|
||||
// 处理Vue Router的历史模式
|
||||
app.get('*', (req, res) => {
|
||||
res.sendFile(path.join(__dirname, '../dist/index.html'))
|
||||
})
|
||||
|
||||
// 启动服务器
|
||||
app.listen(PORT, () => {
|
||||
console.log(`服务器运行在 http://localhost:${PORT}`)
|
||||
})
|
216
server/routes/api.js
Normal file
216
server/routes/api.js
Normal file
@ -0,0 +1,216 @@
|
||||
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
|
Reference in New Issue
Block a user