feat: 完善课表档案、课件归档、提醒与客户端更新并发布 1.4.1

- 重写课表档案工作区并合并时间表、课表与完整档案导入导出
- 修复课前/上下课提醒遮罩与通知收回冲突
- 增加课件文件夹分类、教师归档路径和客户端本机归档
- 打通客户端下载/安装/完成状态上报并在管理端展示更新过程
- 修复侧栏折叠裁切、课时多选与上传控件样式
- 统一版本到 1.4.1
This commit is contained in:
LoveChengke committed 2026-10-18 17:39:54 +08:00
1 parent 2612a912ef
commit 6347d1e5aa
59 files changed
+2251 -584

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@classhelper/shared",
"version": "1.4.0",
"version": "1.4.1",
"private": true,
"description": "ClassHelper - 三端共享的类型、常量与工具函数",
"type": "module",
+5
View File
@@ -75,6 +75,11 @@ export interface ReleaseProgressDto {
percent: number | null;
error: string;
}
/** 设备上报状态与服务端缓存安装包的下载状态分开。 */
export interface ClientUpdateProgressDto extends Omit<ReleaseProgressDto, 'stage'> {
stage: ReleaseProgressDto['stage'] | 'completed';
updatedAt?: string;
}
export interface CollectiveGradeAnalysisDto {
mode: 'collective';
classId: string;
+31
View File
@@ -37,6 +37,9 @@ export interface CoursewareDto {
archiveDate: string;
sha256: string;
createdAt: string;
/** 上传时固定的归档相对路径,不含服务端磁盘根目录。 */
archivePath?: string;
folderPath?: string;
teacher: { id: string; name: string };
classes: CoursewareClassDto[];
}
@@ -45,6 +48,34 @@ export interface CoursewareUploadRequest {
size: number;
classIds: string[];
mode: 'cloud' | 'push';
folderPath?: string;
}
export interface CoursewareFolderDto {
id: string;
path: string;
}
/** 跨平台目录名;保留中文,处理 Windows 保留名与路径分隔符。 */
export function coursewarePathSegment(value: string): string {
const safe =
value
.replace(/[<>:"/\\|?*\u0000-\u001f]/g, '_')
.replace(/[. ]+$/, '')
.slice(0, 180) || '_';
return /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(?:\.|$)/i.test(safe) ? `_${safe}` : safe;
}
export function coursewareArchivePath(teacher: string, uploadedAt: Date, name: string): string {
const pad = (n: number) => String(n).padStart(2, '0');
return [
'Teachers',
coursewarePathSegment(teacher),
String(uploadedAt.getFullYear()),
pad(uploadedAt.getMonth() + 1),
pad(uploadedAt.getDate()),
[uploadedAt.getHours(), uploadedAt.getMinutes(), uploadedAt.getSeconds()].map(pad).join('-'),
coursewarePathSegment(name),
].join('/');
}
export interface CoursewarePushDto {
id: string;
+3
View File
@@ -1,5 +1,6 @@
import type { CoursewareTransfer } from './courseware.js';
import type {
ClientUpdateProgressDto,
PermissionScope as ContractPermissionScope,
ReleaseProgressDto as ContractReleaseProgressDto,
} from './class-plan.js';
@@ -1552,6 +1553,7 @@ export interface ClientCommandDto {
/** Web 端「客户端设备」列表里的一台机器 */
export interface ClientDeviceDto {
updateProgress?: ClientUpdateProgressDto | null;
id: string;
classId: string | null;
className: string | null;
@@ -1590,6 +1592,7 @@ export interface ClientDeviceDto {
/** `POST /api/clients/heartbeat`:客户端每 30 秒一次的上报 */
export interface ClientHeartbeatRequest {
updateProgress?: ClientUpdateProgressDto;
/** 旧版缺省为 1;第二版正确解析统一响应并支持安装时机。 */
agentProtocol?: number;
deviceKey: string;