Files
squirrelVsis/dist/model.js
睿 安 859af05c7f 修改保存逻辑:在上传文件前先通过C++编译服务验证脚本
- 修改model.ts的saveFileContent方法,在上传文件前先通过C++服务验证脚本
- 如果C++服务可连接,则先发送脚本进行编译验证,只有在返回200状态码(编译通过)后才上传到服务器
- 如果C++服务返回非200状态码(编译失败),则不允许上传并提示错误
- 如果C++服务不可连接,则直接上传到服务器
- 简化extension.ts中的保存事件监听器,仅执行UI更新和缓存更新
- 保持原有错误处理机制,确保在C++服务故障时也能正常上传文件

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-03 20:34:01 +08:00

325 lines
13 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileModel = void 0;
const vscode = __importStar(require("vscode"));
const apiClient_1 = require("./apiClient");
const localClient_1 = require("./localClient");
class FileModel {
constructor() {
this.fileList = new Map();
this.isConnected = false;
this.apiClient = new apiClient_1.ApiClient();
this.config = vscode.workspace.getConfiguration('squirrel');
}
// 更新配置
updateConfig() {
this.config = vscode.workspace.getConfiguration('squirrel');
const baseUrl = this.config.get('api.baseUrl', 'http://localhost');
const port = this.config.get('api.port', 8080);
this.apiClient.updateConfig(baseUrl, port);
}
// 连接到API
async connect() {
try {
this.updateConfig();
const baseUrl = this.config.get('api.baseUrl', 'http://localhost');
const port = this.config.get('api.port', 8080);
const defaultDir = this.config.get('defaultDirectory', 'sqr');
console.log(`尝试连接到: ${baseUrl}:${port}, 目录: ${defaultDir}`);
// 首先检查版本号
console.log('正在检查 pvfUtility 版本号...');
const version = await this.apiClient.getVersion();
console.log(`pvfUtility 版本: ${version}`);
// 测试连接并获取文件列表
const filesData = await this.apiClient.getFileList(defaultDir);
console.log(`API返回数据: ${JSON.stringify(filesData)}`);
// 将字符串按换行符分割成数组
const files = filesData.split(/\r?\n/).filter((file) => file.trim() !== '');
console.log(`成功获取到 ${files.length} 个文件`);
this.fileList.clear();
files.forEach((filePath) => {
const entry = {
key: filePath,
name: filePath.split('/').pop() || filePath,
isFile: true
};
this.fileList.set(filePath, entry);
});
// 自动加载所有文件内容
console.log('开始自动加载所有文件内容...');
await this.loadAllFileContents();
this.isConnected = true;
return true;
}
catch (error) {
console.error('连接失败详细信息:', error);
this.isConnected = false;
return false;
}
}
// 是否已连接
getIsConnected() {
return this.isConnected;
}
// 获取指定目录的子文件(支持树形结构)
getChildren(parentKey) {
if (!parentKey) {
// 获取根目录内容
const folders = new Map(); // folderKey -> name
const files = [];
for (const key of this.fileList.keys()) {
const idx = key.indexOf('/');
if (idx === -1) {
// 根目录文件
const entry = this.fileList.get(key);
if (entry)
files.push(entry);
}
else {
// 根目录文件夹
const folder = key.substring(0, idx);
if (!folders.has(folder))
folders.set(folder, folder);
}
}
const dirs = [...folders.keys()].map(k => ({
key: k,
name: k,
isFile: false
}));
return [...files, ...dirs].sort((a, b) => (a.isFile === b.isFile) ?
a.name.localeCompare(b.name, 'en', { sensitivity: 'base' }) :
(a.isFile ? 1 : -1));
}
// 获取子目录内容
const prefix = parentKey.endsWith('/') ? parentKey : parentKey + '/';
const seenFolders = new Set();
const result = [];
for (const key of this.fileList.keys()) {
if (!key.startsWith(prefix))
continue;
const rest = key.substring(prefix.length);
const slash = rest.indexOf('/');
if (slash === -1) {
// 直接子文件
const entry = this.fileList.get(key);
if (entry)
result.push(entry);
}
else {
// 子文件夹
const childFolder = rest.substring(0, slash);
const childKey = prefix + childFolder;
if (!seenFolders.has(childKey)) {
seenFolders.add(childKey);
result.push({
key: childKey,
name: childFolder,
isFile: false
});
}
}
}
result.sort((a, b) => (a.isFile === b.isFile) ?
a.name.localeCompare(b.name, 'en', { sensitivity: 'base' }) :
(a.isFile ? 1 : -1));
return result;
}
// 获取文件内容
async getFileContent(filePath) {
const entry = this.fileList.get(filePath);
if (!entry) {
return undefined;
}
// 如果已经加载过内容,直接返回
if (entry.content) {
return entry.content;
}
try {
// 获取编码设置
const encodingType = this.config.get('nutEncoding', 'UTF8');
const contents = await this.apiClient.getFileContents([filePath], encodingType);
const content = contents[filePath];
if (content !== undefined) {
entry.content = content;
entry.lastLoaded = new Date();
return content;
}
}
catch (error) {
vscode.window.showErrorMessage(`获取文件内容失败: ${error}`);
}
return undefined;
}
// 保存文件内容
async saveFileContent(filePath, content) {
// 先检查C++服务是否可连接
const isCppServiceConnected = await (0, localClient_1.checkCppServiceConnection)();
if (isCppServiceConnected) {
// C++服务可连接,先发送进行编译验证
try {
const sendSuccess = await (0, localClient_1.sendFileToCppService)(filePath, content);
if (sendSuccess) {
// C++编译服务返回200说明脚本编译通过允许上传
const success = await this.apiClient.uploadFileContent(filePath, content);
if (success) {
const entry = this.fileList.get(filePath);
if (entry) {
entry.content = content;
entry.lastLoaded = new Date();
}
return true;
}
}
else {
// C++编译服务返回非200说明脚本存在问题不允许上传
vscode.window.showErrorMessage(`脚本编译失败,无法保存文件 ${filePath}。请检查代码错误后再试。`);
return false;
}
}
catch (error) {
// 向C++服务发送文件过程中出现错误
vscode.window.showErrorMessage(`发送文件到编译服务时出错: ${error},但仍尝试直接保存文件`);
const success = await this.apiClient.uploadFileContent(filePath, content);
if (success) {
const entry = this.fileList.get(filePath);
if (entry) {
entry.content = content;
entry.lastLoaded = new Date();
}
return true;
}
}
}
else {
// C++服务不可连接,直接执行上传
try {
const success = await this.apiClient.uploadFileContent(filePath, content);
if (success) {
const entry = this.fileList.get(filePath);
if (entry) {
entry.content = content;
entry.lastLoaded = new Date();
}
return true;
}
}
catch (error) {
vscode.window.showErrorMessage(`保存文件失败: ${error}`);
}
}
return false;
}
// 刷新文件列表
async refresh() {
if (!this.isConnected) {
return false;
}
try {
this.updateConfig();
const defaultDir = this.config.get('defaultDirectory', 'sqr');
const filesData = await this.apiClient.getFileList(defaultDir);
// 将字符串按换行符分割成数组
const files = filesData.split(/\r?\n/).filter((file) => file.trim() !== '');
this.fileList.clear();
files.forEach((filePath) => {
const entry = {
key: filePath,
name: filePath.split('/').pop() || filePath,
isFile: true
};
this.fileList.set(filePath, entry);
});
return true;
}
catch (error) {
vscode.window.showErrorMessage(`刷新文件列表失败: ${error}`);
return false;
}
}
// 批量加载所有文件内容
async loadAllFileContents() {
try {
// 获取所有文件路径
const filePaths = Array.from(this.fileList.keys());
if (filePaths.length === 0) {
console.log('没有文件需要加载');
return;
}
console.log(`准备加载 ${filePaths.length} 个文件的内容`);
// 获取编码设置
const encodingType = this.config.get('nutEncoding', 'UTF8');
// 分批获取文件内容,避免一次性请求过多文件
const batchSize = 50; // 每批处理50个文件
for (let i = 0; i < filePaths.length; i += batchSize) {
const batch = filePaths.slice(i, i + batchSize);
console.log(`正在加载批次 ${Math.floor(i / batchSize) + 1}/${Math.ceil(filePaths.length / batchSize)}: ${batch.length} 个文件`);
try {
const contents = await this.apiClient.getFileContents(batch, encodingType);
// 更新文件内容
for (const [filePath, content] of Object.entries(contents)) {
const entry = this.fileList.get(filePath);
if (entry) {
entry.content = content;
entry.lastLoaded = new Date();
}
}
console.log(`批次 ${Math.floor(i / batchSize) + 1} 加载完成`);
}
catch (batchError) {
console.error(`加载批次 ${Math.floor(i / batchSize) + 1} 失败:`, batchError);
// 继续处理下一个批次,不中断整个过程
}
}
console.log('所有文件内容加载完成');
}
catch (error) {
console.error('批量加载文件内容失败:', error);
vscode.window.showErrorMessage(`批量加载文件内容失败: ${error}`);
}
}
// 获取文件条目
getFileEntry(filePath) {
return this.fileList.get(filePath);
}
// 获取所有nut文件路径
getAllNutFiles() {
return Array.from(this.fileList.keys())
.filter(filePath => filePath.endsWith('.nut'));
}
}
exports.FileModel = FileModel;
//# sourceMappingURL=model.js.map