文件上传
文件上传并保存到sqlite
npm install @nestjs/platform-express multer @nestjs/typeorm typeorm sqlite3
// file.entity.ts
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity()
export class File {
@PrimaryGeneratedColumn()
id: number;
@Column()
filename: string;
@Column('blob') // 使用 blob 类型存储文件二进制数据
data: Buffer;
@Column()
mimetype: string;
@Column()
size: number;
}
// file.controller.ts
import { Controller, Post, UseInterceptors, UploadedFile } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { FileService } from './file.service';
import { File } from './file.entity';
@Controller('files')
export class FileController {
constructor(private readonly fileService: FileService) {}
@Post('upload')
@UseInterceptors(FileInterceptor('file')) // 'file' 是表单字段名
async uploadFile(@UploadedFile() file: Express.Multer.File) {
return this.fileService.saveFile(
file.buffer, // 文件二进制数据
file.originalname, // 文件名
file.mimetype, // MIME 类型
file.size, // 文件大小
);
}
}
// file.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { File } from './file.entity';
@Injectable()
export class FileService {
constructor(
@InjectRepository(File)
private fileRepository: Repository<File>,
) {}
async saveFile(
data: Buffer,
filename: string,
mimetype: string,
size: number,
): Promise<File> {
const newFile = this.fileRepository.create({
filename,
data,
mimetype,
size,
});
return this.fileRepository.save(newFile);
}
}
从sqlite读取数据,并写入本地
// file.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { File } from './file.entity';
import * as fs from 'fs';
@Injectable()
export class FileService {
constructor(
@InjectRepository(File)
private fileRepository: Repository<File>,
) {}
async saveFileToDisk(id: number, outputPath: string): Promise<void> {
const fileRecord = await this.fileRepository.findOneBy({ id });
if (!fileRecord) {
throw new Error('File not found');
}
// 将 BLOB 数据写入本地文件
fs.writeFileSync(outputPath, fileRecord.data);
}
}
// 在 saveFileToDisk 方法中追加:
const directory = '/path/to/save'; // 目标目录
const outputPath = `${directory}/${fileRecord.filename}`;
// 确保目录存在
if (!fs.existsSync(directory)) {
fs.mkdirSync(directory, { recursive: true });
}
// 写入文件
fs.writeFileSync(outputPath, fileRecord.data);
console.log(`File saved to: ${outputPath}`);
electron主动向渲染进程发消息
// 主进程 - main.js
const { BrowserWindow, ipcMain } = require('electron');
function sendMessageToRenderer() {
const win = BrowserWindow.getFocusedWindow(); // 获取当前窗口
if (win) {
win.webContents.send('push-notification', {
title: '新消息',
content: '您有一条待处理任务'
});
}
}
// 定时推送示例
setInterval(sendMessageToRenderer, 5000);
// 渲染进程 - renderer.js
const { ipcRenderer } = require('electron');
ipcRenderer.on('push-notification', (event, data) => {
console.log('收到推送:', data.title, data.content);
// 更新UI或显示通知
});
预加载脚本安全暴露API
// preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
onPush: (callback) => ipcRenderer.on('push-notification', callback)
});
前端调用
// 渲染进程 - 前端页面
window.electronAPI.onPush((event, data) => {
alert(`通知:${data.title}\n${data.content}`);
});