diff --git a/apps/server/src/models/resource/processor/ImageProcessor.ts b/apps/server/src/models/resource/processor/ImageProcessor.ts index ea01e75..45821f9 100644 --- a/apps/server/src/models/resource/processor/ImageProcessor.ts +++ b/apps/server/src/models/resource/processor/ImageProcessor.ts @@ -14,7 +14,7 @@ export class ImageProcessor extends BaseProcessor { const { url } = resource; const filepath = getUploadFilePath(url); const originMeta = resource.metadata as unknown as FileMetadata; - if (!originMeta.mimeType?.startsWith('image/')) { + if (!originMeta.filetype?.startsWith('image/')) { this.logger.log(`Skipping non-image resource: ${resource.id}`); return resource; } diff --git a/apps/server/src/models/resource/processor/VideoProcessor.ts b/apps/server/src/models/resource/processor/VideoProcessor.ts index 7853f5e..e98cd59 100644 --- a/apps/server/src/models/resource/processor/VideoProcessor.ts +++ b/apps/server/src/models/resource/processor/VideoProcessor.ts @@ -19,7 +19,7 @@ export class VideoProcessor extends BaseProcessor { ); const originMeta = resource.metadata as unknown as FileMetadata; - if (!originMeta.mimeType?.startsWith('video/')) { + if (!originMeta.filetype?.startsWith('video/')) { this.logger.log(`Skipping non-video resource: ${resource.id}`); return resource; } diff --git a/apps/server/src/models/resource/types.ts b/apps/server/src/models/resource/types.ts index 7e39e42..eb060ba 100644 --- a/apps/server/src/models/resource/types.ts +++ b/apps/server/src/models/resource/types.ts @@ -11,7 +11,7 @@ export interface ProcessResult { export interface BaseMetadata { size: number - mimeType: string + filetype: string filename: string extension: string modifiedAt: Date diff --git a/apps/server/src/queue/postprocess/postprocess.service.ts b/apps/server/src/queue/postprocess/postprocess.service.ts deleted file mode 100644 index eef571b..0000000 --- a/apps/server/src/queue/postprocess/postprocess.service.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { InjectQueue } from '@nestjs/bullmq'; -import { Injectable } from '@nestjs/common'; -import EventBus from '@server/utils/event-bus'; -import { Queue } from 'bullmq'; -import { ObjectType } from '@nice/common'; -import { QueueJobType } from '../types'; -@Injectable() -export class PostProcessService { - constructor(@InjectQueue('general') private generalQueue: Queue) {} - - private generateJobId(type: ObjectType, data: any): string { - // 根据类型和相关ID生成唯一的job标识 - switch (type) { - case ObjectType.ENROLLMENT: - return `stats_${type}_${data.courseId}`; - case ObjectType.LECTURE: - return `stats_${type}_${data.courseId}_${data.sectionId}`; - case ObjectType.POST: - return `stats_${type}_${data.courseId}`; - default: - return `stats_${type}_${Date.now()}`; - } - } -} diff --git a/apps/server/src/queue/worker/processor.ts b/apps/server/src/queue/worker/processor.ts index 5f3ec6f..74fe414 100755 --- a/apps/server/src/queue/worker/processor.ts +++ b/apps/server/src/queue/worker/processor.ts @@ -8,36 +8,7 @@ import { updatePostViewCount } from '../models/post/utils'; const logger = new Logger('QueueWorker'); export default async function processJob(job: Job) { try { - if (job.name === QueueJobType.UPDATE_STATS) { - const { sectionId, courseId, type } = job.data; - // 处理 section 统计 - // if (sectionId) { - // await updateSectionLectureStats(sectionId); - // logger.debug(`Updated section stats for sectionId: ${sectionId}`); - // } - // // 如果没有 courseId,提前返回 - // if (!courseId) { - // return; - // } - // 处理 course 相关统计 - switch (type) { - // case ObjectType.LECTURE: - // await updateCourseLectureStats(courseId); - // break; - // case ObjectType.ENROLLMENT: - // await updateCourseEnrollmentStats(courseId); - // break; - // case ObjectType.POST: - // await updateCourseReviewStats(courseId); - // break; - default: - logger.warn(`Unknown update stats type: ${type}`); - } - logger.debug( - `Updated course stats for courseId: ${courseId}, type: ${type}`, - ); - } if (job.name === QueueJobType.UPDATE_POST_VISIT_COUNT) { await updatePostViewCount(job.data.id, job.data.type); } diff --git a/apps/server/src/upload/tus.service.ts b/apps/server/src/upload/tus.service.ts index a9805d7..1066701 100644 --- a/apps/server/src/upload/tus.service.ts +++ b/apps/server/src/upload/tus.service.ts @@ -23,7 +23,7 @@ export class TusService implements OnModuleInit { constructor( private readonly resourceService: ResourceService, @InjectQueue('file-queue') private fileQueue: Queue, - ) {} + ) { } onModuleInit() { this.initializeTusServer(); this.setupTusEventHandlers(); @@ -68,7 +68,7 @@ export class TusService implements OnModuleInit { ) { try { const fileId = this.getFileId(upload.id); - const filename = upload.metadata.filename; + await this.resourceService.create({ data: { title: getFilenameWithoutExt(upload.metadata.filename), diff --git a/apps/web/src/app/auth/page.tsx b/apps/web/src/app/auth/page.tsx index ee304df..b042bfd 100644 --- a/apps/web/src/app/auth/page.tsx +++ b/apps/web/src/app/auth/page.tsx @@ -48,10 +48,10 @@ const AuthPage: React.FC = () => { transition={{ delay: 0.2, duration: 0.5 }} >
- 首长机关信箱 + 烽火建言
- 倾听官兵心声,及时响应诉求,竭诚为每一位战友解难题、办实事 + 用真心聆听每一位官兵的心声,第一时间回应大家的关切,把战友们的烦心事当作自己的心头事,用心用情解决每一个难题,全心全意办好每一件实事,让贴心服务成为军营最温暖的底色 {showLogin && ( - ))} - +
+ {imageResources.length > 0 && ( + + + {imageResources.map((resource) => ( + +
+
+ {resource.title} + 点击预览 +
+ ), + }} + style={{ + position: "absolute", + inset: 0, + width: "100%", + height: "100%", + objectFit: "cover", + }} + rootClassName="w-full h-full" + /> +
+ {resource.title && ( +
+ {resource.title} +
+ )} +
+ + ))} + + + )} + + {fileResources.length > 0 && ( +
+
+ {fileResources.map((resource) => ( +
+
+ {getFileIcon(resource.url)} +
+

+ {resource.title || "未命名文件"} +

+
+ + {resource.url.split(".").pop()?.toUpperCase()}文件 + + + {resource.metadata.size && + `${(resource.metadata.size / 1024 / 1024).toFixed(1)}MB`} + +
+
+
+ +
+ ))} +
+
+ )} ); -} +} \ No newline at end of file diff --git a/apps/web/src/components/models/post/detail/utils.ts b/apps/web/src/components/models/post/detail/utils.ts deleted file mode 100644 index 1cec3b0..0000000 --- a/apps/web/src/components/models/post/detail/utils.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const isContentEmpty = (html: string) => { - // 创建一个临时 div 来解析 HTML 内容 - const temp = document.createElement("div"); - temp.innerHTML = html; - // 获取纯文本内容并检查是否为空 - return !temp.textContent?.trim(); -}; diff --git a/apps/web/src/components/models/post/detail/utils.tsx b/apps/web/src/components/models/post/detail/utils.tsx new file mode 100644 index 0000000..3bc60fd --- /dev/null +++ b/apps/web/src/components/models/post/detail/utils.tsx @@ -0,0 +1,39 @@ +import { FilePdfOutlined, FileWordOutlined, FileExcelOutlined, FilePptOutlined, FileTextOutlined, FileZipOutlined, FileImageOutlined, FileUnknownOutlined } from "@ant-design/icons"; + +export const isContentEmpty = (html: string) => { + // 创建一个临时 div 来解析 HTML 内容 + const temp = document.createElement("div"); + temp.innerHTML = html; + // 获取纯文本内容并检查是否为空 + return !temp.textContent?.trim(); +}; +export const getFileIcon = (filename: string) => { + const extension = filename.split(".").pop()?.toLowerCase(); + switch (extension) { + case "pdf": + return ; + case "doc": + case "docx": + return ; + case "xls": + case "xlsx": + return ; + case "ppt": + case "pptx": + return ; + case "txt": + return ; + case "zip": + case "rar": + case "7z": + return ; + case "png": + case "jpg": + case "jpeg": + case "gif": + case "webp": + return ; + default: + return ; + } +};