chore: 添加远程桌面控制组件、文档和构建产物
This commit is contained in:
280
dist-api/chunk-W5TDYTXE.js
Normal file
280
dist-api/chunk-W5TDYTXE.js
Normal file
@@ -0,0 +1,280 @@
|
||||
import {
|
||||
resolveNotebookPath
|
||||
} from "./chunk-ER4KPD22.js";
|
||||
import {
|
||||
asyncHandler,
|
||||
createApiModule,
|
||||
defineApiModule,
|
||||
defineEndpoints,
|
||||
successResponse
|
||||
} from "./chunk-74TMTGBG.js";
|
||||
|
||||
// shared/modules/remote/api.ts
|
||||
var REMOTE_ENDPOINTS = defineEndpoints({
|
||||
getConfig: { path: "/config", method: "GET" },
|
||||
saveConfig: { path: "/config", method: "POST" },
|
||||
getScreenshot: { path: "/screenshot", method: "GET" },
|
||||
saveScreenshot: { path: "/screenshot", method: "POST" },
|
||||
getData: { path: "/data", method: "GET" },
|
||||
saveData: { path: "/data", method: "POST" }
|
||||
});
|
||||
|
||||
// shared/modules/remote/index.ts
|
||||
var REMOTE_MODULE = defineApiModule({
|
||||
id: "remote",
|
||||
name: "\u8FDC\u7A0B",
|
||||
basePath: "/remote",
|
||||
order: 25,
|
||||
version: "1.0.0",
|
||||
endpoints: REMOTE_ENDPOINTS
|
||||
});
|
||||
|
||||
// api/modules/remote/service.ts
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
var REMOTE_DIR = "remote";
|
||||
var RemoteService = class {
|
||||
constructor(deps = {}) {
|
||||
this.deps = deps;
|
||||
}
|
||||
getRemoteDir() {
|
||||
const { fullPath } = resolveNotebookPath(REMOTE_DIR);
|
||||
return { relPath: REMOTE_DIR, fullPath };
|
||||
}
|
||||
getDeviceDir(deviceName) {
|
||||
const safeName = this.sanitizeFileName(deviceName);
|
||||
const { fullPath } = resolveNotebookPath(path.join(REMOTE_DIR, safeName));
|
||||
return { relPath: path.join(REMOTE_DIR, safeName), fullPath };
|
||||
}
|
||||
sanitizeFileName(name) {
|
||||
return name.replace(/[<>:"/\\|?*]/g, "_").trim() || "unnamed";
|
||||
}
|
||||
getDeviceConfigPath(deviceName) {
|
||||
const { fullPath } = this.getDeviceDir(deviceName);
|
||||
return path.join(fullPath, "config.json");
|
||||
}
|
||||
getDeviceScreenshotPath(deviceName) {
|
||||
const { fullPath } = this.getDeviceDir(deviceName);
|
||||
return path.join(fullPath, "screenshot.png");
|
||||
}
|
||||
getDeviceDataPath(deviceName) {
|
||||
const { fullPath } = this.getDeviceDir(deviceName);
|
||||
return path.join(fullPath, "data.json");
|
||||
}
|
||||
async ensureDir(dirPath) {
|
||||
await fs.mkdir(dirPath, { recursive: true });
|
||||
}
|
||||
async getDeviceNames() {
|
||||
const { fullPath } = this.getRemoteDir();
|
||||
try {
|
||||
const entries = await fs.readdir(fullPath, { withFileTypes: true });
|
||||
const dirs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
||||
return dirs;
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
async getConfig() {
|
||||
const deviceNames = await this.getDeviceNames();
|
||||
const devices = await Promise.all(
|
||||
deviceNames.map(async (name) => {
|
||||
try {
|
||||
const configPath = this.getDeviceConfigPath(name);
|
||||
const content = await fs.readFile(configPath, "utf-8");
|
||||
const deviceConfig = JSON.parse(content);
|
||||
return {
|
||||
id: deviceConfig.id || name,
|
||||
deviceName: name,
|
||||
serverHost: deviceConfig.serverHost || "",
|
||||
desktopPort: deviceConfig.desktopPort || 3e3,
|
||||
gitPort: deviceConfig.gitPort || 3001,
|
||||
openCodePort: deviceConfig.openCodePort || 3002,
|
||||
fileTransferPort: deviceConfig.fileTransferPort || 3003,
|
||||
password: deviceConfig.password || ""
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
id: name,
|
||||
deviceName: name,
|
||||
serverHost: "",
|
||||
desktopPort: 3e3,
|
||||
gitPort: 3001,
|
||||
openCodePort: 3002,
|
||||
fileTransferPort: 3003,
|
||||
password: ""
|
||||
};
|
||||
}
|
||||
})
|
||||
);
|
||||
return { devices };
|
||||
}
|
||||
async saveConfig(config) {
|
||||
const { fullPath: remoteDirFullPath } = this.getRemoteDir();
|
||||
await this.ensureDir(remoteDirFullPath);
|
||||
const existingDevices = await this.getDeviceNames();
|
||||
const newDeviceNames = config.devices.map((d) => this.sanitizeFileName(d.deviceName));
|
||||
for (const oldDevice of existingDevices) {
|
||||
if (!newDeviceNames.includes(oldDevice)) {
|
||||
try {
|
||||
const oldDir = path.join(remoteDirFullPath, oldDevice);
|
||||
await fs.rm(oldDir, { recursive: true, force: true });
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const device of config.devices) {
|
||||
const deviceDir = this.getDeviceDir(device.deviceName);
|
||||
await this.ensureDir(deviceDir.fullPath);
|
||||
const deviceConfigPath = this.getDeviceConfigPath(device.deviceName);
|
||||
const deviceConfig = {
|
||||
id: device.id,
|
||||
serverHost: device.serverHost,
|
||||
desktopPort: device.desktopPort,
|
||||
gitPort: device.gitPort,
|
||||
openCodePort: device.openCodePort,
|
||||
fileTransferPort: device.fileTransferPort,
|
||||
password: device.password || ""
|
||||
};
|
||||
await fs.writeFile(deviceConfigPath, JSON.stringify(deviceConfig, null, 2), "utf-8");
|
||||
}
|
||||
}
|
||||
async getScreenshot(deviceName) {
|
||||
if (!deviceName) {
|
||||
return null;
|
||||
}
|
||||
const screenshotPath = this.getDeviceScreenshotPath(deviceName);
|
||||
try {
|
||||
return await fs.readFile(screenshotPath);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async saveScreenshot(dataUrl, deviceName) {
|
||||
console.log("[RemoteService] saveScreenshot:", { deviceName, dataUrlLength: dataUrl?.length });
|
||||
if (!deviceName || deviceName.trim() === "") {
|
||||
console.warn("[RemoteService] saveScreenshot skipped: no deviceName");
|
||||
return;
|
||||
}
|
||||
const deviceDir = this.getDeviceDir(deviceName);
|
||||
await this.ensureDir(deviceDir.fullPath);
|
||||
const base64Data = dataUrl.replace(/^data:image\/png;base64,/, "");
|
||||
const buffer = Buffer.from(base64Data, "base64");
|
||||
const screenshotPath = this.getDeviceScreenshotPath(deviceName);
|
||||
await fs.writeFile(screenshotPath, buffer);
|
||||
}
|
||||
async getData(deviceName) {
|
||||
if (!deviceName || deviceName.trim() === "") {
|
||||
return null;
|
||||
}
|
||||
const dataPath = this.getDeviceDataPath(deviceName);
|
||||
try {
|
||||
const content = await fs.readFile(dataPath, "utf-8");
|
||||
return JSON.parse(content);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async saveData(data, deviceName) {
|
||||
if (!deviceName || deviceName.trim() === "") {
|
||||
console.warn("[RemoteService] saveData skipped: no deviceName");
|
||||
return;
|
||||
}
|
||||
const deviceDir = this.getDeviceDir(deviceName);
|
||||
await this.ensureDir(deviceDir.fullPath);
|
||||
const dataPath = this.getDeviceDataPath(deviceName);
|
||||
await fs.writeFile(dataPath, JSON.stringify(data, null, 2), "utf-8");
|
||||
}
|
||||
};
|
||||
var createRemoteService = (deps) => {
|
||||
return new RemoteService(deps);
|
||||
};
|
||||
|
||||
// api/modules/remote/routes.ts
|
||||
import express from "express";
|
||||
var createRemoteRoutes = (deps) => {
|
||||
const router = express.Router();
|
||||
const { remoteService: remoteService2 } = deps;
|
||||
router.get(
|
||||
"/config",
|
||||
asyncHandler(async (req, res) => {
|
||||
const config = await remoteService2.getConfig();
|
||||
successResponse(res, config);
|
||||
})
|
||||
);
|
||||
router.post(
|
||||
"/config",
|
||||
asyncHandler(async (req, res) => {
|
||||
const config = req.body;
|
||||
await remoteService2.saveConfig(config);
|
||||
successResponse(res, null);
|
||||
})
|
||||
);
|
||||
router.get(
|
||||
"/screenshot",
|
||||
asyncHandler(async (req, res) => {
|
||||
const deviceName = req.query.device;
|
||||
const buffer = await remoteService2.getScreenshot(deviceName);
|
||||
if (!buffer) {
|
||||
return successResponse(res, "");
|
||||
}
|
||||
const base64 = `data:image/png;base64,${buffer.toString("base64")}`;
|
||||
successResponse(res, base64);
|
||||
})
|
||||
);
|
||||
router.post(
|
||||
"/screenshot",
|
||||
asyncHandler(async (req, res) => {
|
||||
const { dataUrl, deviceName } = req.body;
|
||||
console.log("[Remote] saveScreenshot called:", { deviceName, hasDataUrl: !!dataUrl });
|
||||
await remoteService2.saveScreenshot(dataUrl, deviceName);
|
||||
successResponse(res, null);
|
||||
})
|
||||
);
|
||||
router.get(
|
||||
"/data",
|
||||
asyncHandler(async (req, res) => {
|
||||
const deviceName = req.query.device;
|
||||
const data = await remoteService2.getData(deviceName);
|
||||
successResponse(res, data);
|
||||
})
|
||||
);
|
||||
router.post(
|
||||
"/data",
|
||||
asyncHandler(async (req, res) => {
|
||||
const { deviceName, lastConnected } = req.body;
|
||||
const data = {};
|
||||
if (lastConnected !== void 0) {
|
||||
data.lastConnected = lastConnected;
|
||||
}
|
||||
await remoteService2.saveData(data, deviceName);
|
||||
successResponse(res, null);
|
||||
})
|
||||
);
|
||||
return router;
|
||||
};
|
||||
var remoteService = new RemoteService();
|
||||
var routes_default = createRemoteRoutes({ remoteService });
|
||||
|
||||
// api/modules/remote/index.ts
|
||||
var createRemoteModule = () => {
|
||||
return createApiModule(REMOTE_MODULE, {
|
||||
routes: (container) => {
|
||||
const remoteService2 = container.getSync("remoteService");
|
||||
return createRemoteRoutes({ remoteService: remoteService2 });
|
||||
},
|
||||
lifecycle: {
|
||||
onLoad: (container) => {
|
||||
container.register("remoteService", () => new RemoteService());
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
var remote_default = createRemoteModule;
|
||||
|
||||
export {
|
||||
RemoteService,
|
||||
createRemoteService,
|
||||
createRemoteRoutes,
|
||||
createRemoteModule,
|
||||
remote_default
|
||||
};
|
||||
Reference in New Issue
Block a user