feat: 更新 FileUploader 组件和生成的 API 类型
- 更新 FileUploader.vue 组件 - 更新组件类型定义 - 更新 API 生成的类型定义 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
a1dcd529ef
commit
e7348656ff
@ -1,3 +1,3 @@
|
||||
VITE_API_BASE_URL=http://localhost:3000/api/v1
|
||||
VITE_API_BASE_URL=
|
||||
VITE_APP_TITLE=幼儿阅读教学服务平台
|
||||
VITE_SERVER_BASE_URL=http://localhost:3000
|
||||
VITE_SERVER_BASE_URL=
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
* Reading Platform Backend Service API Documentation
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*/
|
||||
import type { CourseLessonResponse } from './courseLessonResponse';
|
||||
|
||||
/**
|
||||
* 课程响应
|
||||
@ -126,4 +127,6 @@ export interface CourseResponse {
|
||||
createdAt?: string;
|
||||
/** 更新时间 */
|
||||
updatedAt?: string;
|
||||
/** 关联的课程环节 */
|
||||
courseLessons?: CourseLessonResponse[];
|
||||
}
|
||||
|
||||
@ -29,8 +29,11 @@ export * from './courseControllerGetReviewListParams';
|
||||
export * from './courseCreateRequest';
|
||||
export * from './courseLesson';
|
||||
export * from './courseLessonCreateRequest';
|
||||
export * from './courseLessonResponse';
|
||||
export * from './coursePackage';
|
||||
export * from './coursePackageControllerFindAllParams';
|
||||
export * from './coursePackageCourseItem';
|
||||
export * from './coursePackageResponse';
|
||||
export * from './courseResponse';
|
||||
export * from './courseUpdateRequest';
|
||||
export * from './createClassDto';
|
||||
@ -144,6 +147,7 @@ export * from './pageResourceLibrary';
|
||||
export * from './pageResultClassResponse';
|
||||
export * from './pageResultClazz';
|
||||
export * from './pageResultCourse';
|
||||
export * from './pageResultCoursePackageResponse';
|
||||
export * from './pageResultCourseResponse';
|
||||
export * from './pageResultGrowthRecord';
|
||||
export * from './pageResultGrowthRecordResponse';
|
||||
@ -153,6 +157,8 @@ export * from './pageResultNotification';
|
||||
export * from './pageResultNotificationResponse';
|
||||
export * from './pageResultParent';
|
||||
export * from './pageResultParentResponse';
|
||||
export * from './pageResultResourceItem';
|
||||
export * from './pageResultResourceLibrary';
|
||||
export * from './pageResultStudent';
|
||||
export * from './pageResultStudentResponse';
|
||||
export * from './pageResultTask';
|
||||
@ -178,6 +184,7 @@ export * from './resultClazz';
|
||||
export * from './resultCourse';
|
||||
export * from './resultCourseLesson';
|
||||
export * from './resultCoursePackage';
|
||||
export * from './resultCoursePackageResponse';
|
||||
export * from './resultCourseResponse';
|
||||
export * from './resultDto';
|
||||
export * from './resultDtoData';
|
||||
@ -191,6 +198,7 @@ export * from './resultListClassTeacherResponse';
|
||||
export * from './resultListClazz';
|
||||
export * from './resultListCourse';
|
||||
export * from './resultListCourseLesson';
|
||||
export * from './resultListCoursePackageResponse';
|
||||
export * from './resultListCourseResponse';
|
||||
export * from './resultListGrowthRecord';
|
||||
export * from './resultListGrowthRecordResponse';
|
||||
@ -219,6 +227,7 @@ export * from './resultPageResourceLibrary';
|
||||
export * from './resultPageResultClassResponse';
|
||||
export * from './resultPageResultClazz';
|
||||
export * from './resultPageResultCourse';
|
||||
export * from './resultPageResultCoursePackageResponse';
|
||||
export * from './resultPageResultCourseResponse';
|
||||
export * from './resultPageResultGrowthRecord';
|
||||
export * from './resultPageResultGrowthRecordResponse';
|
||||
@ -228,6 +237,8 @@ export * from './resultPageResultNotification';
|
||||
export * from './resultPageResultNotificationResponse';
|
||||
export * from './resultPageResultParent';
|
||||
export * from './resultPageResultParentResponse';
|
||||
export * from './resultPageResultResourceItem';
|
||||
export * from './resultPageResultResourceLibrary';
|
||||
export * from './resultPageResultStudent';
|
||||
export * from './resultPageResultStudentResponse';
|
||||
export * from './resultPageResultTask';
|
||||
|
||||
@ -8,11 +8,11 @@
|
||||
|
||||
export interface ItemCreateRequest {
|
||||
libraryId?: string;
|
||||
name?: string;
|
||||
code?: string;
|
||||
type?: string;
|
||||
title?: string;
|
||||
fileType?: string;
|
||||
filePath?: string;
|
||||
fileSize?: number;
|
||||
description?: string;
|
||||
quantity?: number;
|
||||
location?: string;
|
||||
tags?: string;
|
||||
tenantId?: string;
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
export interface ItemUpdateRequest {
|
||||
name?: string;
|
||||
title?: string;
|
||||
description?: string;
|
||||
quantity?: number;
|
||||
tags?: string;
|
||||
}
|
||||
|
||||
@ -24,19 +24,31 @@ export interface ResourceItem {
|
||||
libraryId?: string;
|
||||
/** 租户 ID */
|
||||
tenantId?: string;
|
||||
/** 资源类型 */
|
||||
type?: string;
|
||||
/** 资源名称 */
|
||||
name?: string;
|
||||
/** 资源编码 */
|
||||
code?: string;
|
||||
/** 资源标题 */
|
||||
title?: string;
|
||||
/** 资源描述 */
|
||||
description?: string;
|
||||
/** 数量 */
|
||||
/** 文件类型 (IMAGE/PDF/VIDEO/AUDIO/PPT/OTHER) */
|
||||
fileType?: string;
|
||||
/** 文件路径 */
|
||||
filePath?: string;
|
||||
/** 文件大小 (字节) */
|
||||
fileSize?: number;
|
||||
/** 资源标签 (JSON 数组) */
|
||||
tags?: string;
|
||||
/** 排序号 */
|
||||
sortOrder?: number;
|
||||
/** 资源类型(保留字段,兼容旧数据) */
|
||||
type?: string;
|
||||
/** 资源名称(保留字段,兼容旧数据) */
|
||||
name?: string;
|
||||
/** 资源编码(保留字段,兼容旧数据) */
|
||||
code?: string;
|
||||
/** 数量(保留字段,兼容旧数据) */
|
||||
quantity?: number;
|
||||
/** 可用数量 */
|
||||
/** 可用数量(保留字段,兼容旧数据) */
|
||||
availableQuantity?: number;
|
||||
/** 存放位置 */
|
||||
/** 存放位置(保留字段,兼容旧数据) */
|
||||
location?: string;
|
||||
/** 状态 */
|
||||
status?: string;
|
||||
|
||||
@ -26,6 +26,14 @@ export interface ResourceLibrary {
|
||||
name?: string;
|
||||
/** 资源库描述 */
|
||||
description?: string;
|
||||
/** 资源库类型 */
|
||||
type?: string;
|
||||
/** 资源库类型 (PICTURE_BOOK/MATERIAL/TEMPLATE) */
|
||||
libraryType?: string;
|
||||
/** 封面图片 URL */
|
||||
coverImage?: string;
|
||||
/** 创建人 ID */
|
||||
createdBy?: number;
|
||||
/** 状态 */
|
||||
status?: string;
|
||||
/** 排序号 */
|
||||
sortOrder?: number;
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
export interface TenantCreateRequest {
|
||||
/** 租户名称 */
|
||||
name: string;
|
||||
/** 租户编码 */
|
||||
/** 租户编码/登录账号 */
|
||||
code: string;
|
||||
/** 联系人 */
|
||||
contactName?: string;
|
||||
@ -24,10 +24,29 @@ export interface TenantCreateRequest {
|
||||
address?: string;
|
||||
/** Logo URL */
|
||||
logoUrl?: string;
|
||||
/** 过期时间 */
|
||||
/** 套餐类型 */
|
||||
packageType?: string;
|
||||
/** 教师配额 */
|
||||
teacherQuota?: number;
|
||||
/** 学生配额 */
|
||||
studentQuota?: number;
|
||||
/** 开始日期 */
|
||||
startDate?: string;
|
||||
/** 结束日期 */
|
||||
expireDate?: string;
|
||||
/**
|
||||
* 过期时间(兼容旧字段)
|
||||
* @deprecated
|
||||
*/
|
||||
expireAt?: string;
|
||||
/** 最大学生数 */
|
||||
/**
|
||||
* 最大学生数(兼容旧字段)
|
||||
* @deprecated
|
||||
*/
|
||||
maxStudents?: number;
|
||||
/** 最大教师数 */
|
||||
/**
|
||||
* 最大教师数(兼容旧字段)
|
||||
* @deprecated
|
||||
*/
|
||||
maxTeachers?: number;
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ export interface TenantResponse {
|
||||
id?: number;
|
||||
/** 租户名称 */
|
||||
name?: string;
|
||||
/** 租户编码 */
|
||||
/** 租户编码/登录账号 */
|
||||
code?: string;
|
||||
/** 用户名 */
|
||||
username?: string;
|
||||
@ -36,6 +36,24 @@ export interface TenantResponse {
|
||||
maxStudents?: number;
|
||||
/** 最大教师数 */
|
||||
maxTeachers?: number;
|
||||
/** 套餐类型 */
|
||||
packageType?: string;
|
||||
/** 教师配额 */
|
||||
teacherQuota?: number;
|
||||
/** 学生配额 */
|
||||
studentQuota?: number;
|
||||
/** 存储配额 */
|
||||
storageQuota?: number;
|
||||
/** 已用存储 */
|
||||
storageUsed?: number;
|
||||
/** 教师数量(已使用) */
|
||||
teacherCount?: number;
|
||||
/** 学生数量(已使用) */
|
||||
studentCount?: number;
|
||||
/** 开始日期 */
|
||||
startDate?: string;
|
||||
/** 结束日期 */
|
||||
expireDate?: string;
|
||||
/** 创建时间 */
|
||||
createdAt?: string;
|
||||
/** 更新时间 */
|
||||
|
||||
@ -24,10 +24,29 @@ export interface TenantUpdateRequest {
|
||||
logoUrl?: string;
|
||||
/** 状态 */
|
||||
status?: string;
|
||||
/** 过期时间 */
|
||||
/** 套餐类型 */
|
||||
packageType?: string;
|
||||
/** 教师配额 */
|
||||
teacherQuota?: number;
|
||||
/** 学生配额 */
|
||||
studentQuota?: number;
|
||||
/** 开始日期 */
|
||||
startDate?: string;
|
||||
/** 结束日期 */
|
||||
expireDate?: string;
|
||||
/**
|
||||
* 过期时间(兼容旧字段)
|
||||
* @deprecated
|
||||
*/
|
||||
expireAt?: string;
|
||||
/** 最大学生数 */
|
||||
/**
|
||||
* 最大学生数(兼容旧字段)
|
||||
* @deprecated
|
||||
*/
|
||||
maxStudents?: number;
|
||||
/** 最大教师数 */
|
||||
/**
|
||||
* 最大教师数(兼容旧字段)
|
||||
* @deprecated
|
||||
*/
|
||||
maxTeachers?: number;
|
||||
}
|
||||
|
||||
14
reading-platform-frontend/src/components.d.ts
vendored
14
reading-platform-frontend/src/components.d.ts
vendored
@ -13,12 +13,15 @@ declare module 'vue' {
|
||||
AButton: typeof import('ant-design-vue/es')['Button']
|
||||
ACard: typeof import('ant-design-vue/es')['Card']
|
||||
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
|
||||
ACheckboxGroup: typeof import('ant-design-vue/es')['CheckboxGroup']
|
||||
ACol: typeof import('ant-design-vue/es')['Col']
|
||||
ADivider: typeof import('ant-design-vue/es')['Divider']
|
||||
ADropdown: typeof import('ant-design-vue/es')['Dropdown']
|
||||
AEmpty: typeof import('ant-design-vue/es')['Empty']
|
||||
AForm: typeof import('ant-design-vue/es')['Form']
|
||||
AFormItem: typeof import('ant-design-vue/es')['FormItem']
|
||||
AInput: typeof import('ant-design-vue/es')['Input']
|
||||
AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
|
||||
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
||||
AInputSearch: typeof import('ant-design-vue/es')['InputSearch']
|
||||
ALayout: typeof import('ant-design-vue/es')['Layout']
|
||||
@ -29,14 +32,25 @@ declare module 'vue' {
|
||||
AMenuDivider: typeof import('ant-design-vue/es')['MenuDivider']
|
||||
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
|
||||
AModal: typeof import('ant-design-vue/es')['Modal']
|
||||
APageHeader: typeof import('ant-design-vue/es')['PageHeader']
|
||||
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
||||
AProgress: typeof import('ant-design-vue/es')['Progress']
|
||||
ARow: typeof import('ant-design-vue/es')['Row']
|
||||
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||
ASelectOptGroup: typeof import('ant-design-vue/es')['SelectOptGroup']
|
||||
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
||||
ASpace: typeof import('ant-design-vue/es')['Space']
|
||||
ASpin: typeof import('ant-design-vue/es')['Spin']
|
||||
AStep: typeof import('ant-design-vue/es')['Step']
|
||||
ASteps: typeof import('ant-design-vue/es')['Steps']
|
||||
ASwitch: typeof import('ant-design-vue/es')['Switch']
|
||||
ATable: typeof import('ant-design-vue/es')['Table']
|
||||
ATabPane: typeof import('ant-design-vue/es')['TabPane']
|
||||
ATabs: typeof import('ant-design-vue/es')['Tabs']
|
||||
ATag: typeof import('ant-design-vue/es')['Tag']
|
||||
ATextarea: typeof import('ant-design-vue/es')['Textarea']
|
||||
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
||||
AUpload: typeof import('ant-design-vue/es')['Upload']
|
||||
FilePreviewModal: typeof import('./components/FilePreviewModal.vue')['default']
|
||||
FileUploader: typeof import('./components/course/FileUploader.vue')['default']
|
||||
LessonConfigPanel: typeof import('./components/course/LessonConfigPanel.vue')['default']
|
||||
|
||||
@ -77,7 +77,7 @@ import {
|
||||
SwapOutlined,
|
||||
DeleteOutlined,
|
||||
} from '@ant-design/icons-vue';
|
||||
import { uploadFile } from '@/api/file';
|
||||
import { getOssToken, uploadToOss } from '@/api/file';
|
||||
|
||||
interface Props {
|
||||
filePath?: string;
|
||||
@ -107,7 +107,7 @@ const buttonText = computed(() => {
|
||||
const typeMap: Record<string, string> = {
|
||||
video: '上传视频',
|
||||
ppt: '上传课件',
|
||||
pdf: '上传PDF',
|
||||
pdf: '上传 PDF',
|
||||
image: '上传图片',
|
||||
audio: '上传音频',
|
||||
document: '上传文档',
|
||||
@ -144,18 +144,18 @@ const acceptTypes = computed(() => {
|
||||
|
||||
const previewUrl = computed(() => {
|
||||
if (!props.filePath) return '';
|
||||
// 如果已经是完整URL或以/uploads开头,直接返回
|
||||
// 如果已经是完整 URL 或以 /uploads 开头,直接返回
|
||||
if (props.filePath.startsWith('http') || props.filePath.startsWith('/uploads')) {
|
||||
return props.filePath;
|
||||
}
|
||||
// 如果路径已经包含uploads目录,不再添加前缀
|
||||
// 如果路径已经包含 uploads 目录,不再添加前缀
|
||||
if (props.filePath.includes('/uploads/')) {
|
||||
return props.filePath;
|
||||
}
|
||||
return `/uploads/${props.filePath}`;
|
||||
});
|
||||
|
||||
// 检查是否为PDF文件(用于ppt类型也支持PDF预览)
|
||||
// 检查是否为 PDF 文件(用于 ppt 类型也支持 PDF 预览)
|
||||
const isPdfFile = computed(() => {
|
||||
if (props.fileType === 'ppt' && props.filePath) {
|
||||
return props.filePath.toLowerCase().endsWith('.pdf');
|
||||
@ -196,7 +196,7 @@ const beforeUpload = async (file: File) => {
|
||||
message.error('请上传 Word 文档');
|
||||
return false;
|
||||
}
|
||||
// PPT类型允许PPT和PDF
|
||||
// PPT 类型允许 PPT 和 PDF
|
||||
if (props.fileType === 'ppt' &&
|
||||
!file.type.includes('presentation') &&
|
||||
!file.type.includes('powerpoint') &&
|
||||
@ -210,14 +210,23 @@ const beforeUpload = async (file: File) => {
|
||||
|
||||
uploading.value = true;
|
||||
try {
|
||||
// 1. 获取 OSS 直传 Token
|
||||
const uploadType = props.fileType === 'ppt' ? 'ppt' : props.fileType || 'other';
|
||||
const result = await uploadFile(file, uploadType);
|
||||
emit('update:filePath', result.filePath);
|
||||
const token = await getOssToken(file.name, uploadType);
|
||||
|
||||
// 2. 直接上传文件到 OSS
|
||||
await uploadToOss(file, token, (percent) => {
|
||||
console.log(`Upload progress: ${percent}%`);
|
||||
});
|
||||
|
||||
// 3. 上传成功后返回文件 URL
|
||||
const fileUrl = `${token.host}/${token.key}`;
|
||||
emit('update:filePath', fileUrl);
|
||||
emit('update:fileName', file.name);
|
||||
emit('change', { filePath: result.filePath, fileName: file.name });
|
||||
emit('change', { filePath: fileUrl, fileName: file.name });
|
||||
message.success('上传成功');
|
||||
} catch (error: any) {
|
||||
message.error('上传失败: ' + (error.response?.data?.message || error.message));
|
||||
message.error('上传失败:' + (error.response?.data?.message || error.message));
|
||||
} finally {
|
||||
uploading.value = false;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user