fix(remote): 添加 /api/files/upload 路由支持文件上传

This commit is contained in:
2026-03-09 19:41:42 +08:00
parent d65b3e7909
commit 4c18edf74f
6 changed files with 302 additions and 4 deletions

View File

@@ -118,6 +118,11 @@ class App {
});
});
this.container.register('openCodeService', (c) => {
const OpenCodeService = require('../services/opencode/OpenCodeService');
return new OpenCodeService();
});
this.container.register('giteaService', (c) => {
const GiteaService = require('../services/network/GiteaService');
const config = c.resolve('config');
@@ -191,6 +196,10 @@ class App {
frpService.start();
logger.info('FRP service started');
const openCodeService = this.container.resolve('openCodeService');
openCodeService.start();
logger.info('OpenCode service started');
const giteaService = this.container.resolve('giteaService');
giteaService.start();
logger.info('Gitea service started');
@@ -469,6 +478,10 @@ class App {
frpService.stop();
logger.info('FRP service stopped');
const openCodeService = this.container.resolve('openCodeService');
openCodeService.stop();
logger.info('OpenCode service stopped');
const giteaService = this.container.resolve('giteaService');
giteaService.stop();
logger.info('Gitea service stopped');

View File

@@ -1,6 +1,8 @@
const express = require('express');
const multer = require('multer');
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const { fileService } = require('../services/file');
const logger = require('../utils/logger');
@@ -17,6 +19,40 @@ router.get('/', (req, res) => {
}
});
router.post('/upload', upload.single('file'), (req, res) => {
try {
if (!req.file) {
return res.status(400).json({ error: 'No file provided' });
}
const remotePath = req.body.path || '';
const filename = req.file.originalname;
let targetDir;
if (remotePath) {
targetDir = path.join(fileService.uploadDir, remotePath);
} else {
targetDir = fileService.uploadDir;
}
if (!targetDir.startsWith(fileService.uploadDir)) {
return res.status(403).json({ error: 'Invalid path' });
}
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir, { recursive: true });
}
const targetPath = path.join(targetDir, filename);
fs.writeFileSync(targetPath, req.file.buffer);
res.json({ success: true, filename });
} catch (error) {
logger.error('Failed to upload file', { error: error.message });
res.status(500).json({ error: 'Failed to upload file' });
}
});
router.get('/drives', (req, res) => {
try {
const drives = fileService.getDrives();

View File

@@ -0,0 +1,97 @@
const { spawn } = require('child_process');
const config = require('../../config');
const logger = require('../../utils/logger');
class OpenCodeService {
constructor() {
this.process = null;
this.isRunning = false;
this.port = 3002;
}
start() {
if (this.isRunning) {
logger.warn('OpenCode service is already running');
return;
}
const password = config.get('security.password');
if (!password) {
logger.error('OpenCode password not found in config');
return;
}
try {
logger.info('Starting OpenCode service', { port: this.port });
const env = {
...process.env,
OPENCODE_SERVER_PASSWORD: password
};
this.process = spawn('opencode', ['serve', '--port', this.port.toString()], {
stdio: ['ignore', 'pipe', 'pipe'],
env,
windowsHide: true
});
this.isRunning = true;
this.process.stdout.on('data', (data) => {
const output = data.toString().trim();
if (output) {
logger.info(`[OpenCode] ${output}`);
}
});
this.process.stderr.on('data', (data) => {
const output = data.toString().trim();
if (output) {
logger.error(`[OpenCode] ${output}`);
}
});
this.process.on('error', (error) => {
logger.error('OpenCode process error', { error: error.message });
this.isRunning = false;
});
this.process.on('close', (code) => {
logger.info('OpenCode process closed', { code });
this.isRunning = false;
this.process = null;
});
logger.info('OpenCode service started successfully');
} catch (error) {
logger.error('Failed to start OpenCode service', { error: error.message });
this.isRunning = false;
}
}
stop() {
if (!this.isRunning || !this.process) {
return;
}
logger.info('Stopping OpenCode service');
try {
this.process.kill();
this.process = null;
this.isRunning = false;
logger.info('OpenCode service stopped');
} catch (error) {
logger.error('Failed to stop OpenCode service', { error: error.message });
}
}
getStatus() {
return {
running: this.isRunning,
port: this.port
};
}
}
module.exports = OpenCodeService;