From 3a9e82337571485125309fa6d211f2a21d580960 Mon Sep 17 00:00:00 2001 From: sion123 <450702724@qq.com> Date: Sun, 16 Nov 2025 22:09:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .cursor/rules/backend.mdc | 119 +++++++++++++++++- frontend/app/web-gold/src/api/material.js | 5 +- .../material/MaterialUploadModal.vue | 34 ++--- .../src/views/material/MaterialList.vue | 7 -- .../src/main/resources/application.yaml | 6 +- 5 files changed, 129 insertions(+), 42 deletions(-) diff --git a/.cursor/rules/backend.mdc b/.cursor/rules/backend.mdc index 49cdf5cdab..8ba3f5006a 100644 --- a/.cursor/rules/backend.mdc +++ b/.cursor/rules/backend.mdc @@ -20,12 +20,121 @@ globs: **/*.java, **/*.xml, **/*.yaml, **/*.yml - **VO 层**: 视图对象,用于前后端交互 - **DO 层**: 数据对象,对应数据库表 +## 目录结构规范 + +### 模块目录结构 + +业务模块的标准目录结构如下: + +``` +yudao-module-{模块名}/ +└── src/main/java/cn/iocoder/yudao/module/{模块名}/ + ├── controller/ # Controller 层 + │ └── {Xxx}Controller.java + ├── service/ # Service 层 + │ ├── {Xxx}Service.java # Service 接口 + │ ├── {Xxx}ServiceImpl.java # Service 实现类 + │ └── {Xxx}Util.java # Service 工具类(可选) + ├── mapper/ # Mapper 层 + │ └── {Xxx}Mapper.java + ├── dataobject/ # DO 对象(可选) + │ └── {Xxx}DO.java + ├── vo/ # VO 对象 + │ ├── {Xxx}SaveReqVO.java + │ ├── {Xxx}PageReqVO.java + │ ├── {Xxx}UpdateReqVO.java + │ └── {Xxx}RespVO.java + ├── enums/ # 枚举类(可选) + │ └── {Xxx}Enum.java + └── mq/ # 消息队列(可选) + └── consumer/ + └── {Xxx}Consumer.java +``` + +### 目录结构说明 + +- **mapper/**: Mapper 接口,继承 `BaseMapperX` +- **dataobject/**: DO 对象(可选),继承 `BaseDO` 或 `TenantBaseDO` +- 如果模块没有 DO 对象,可以省略 `dataobject/` 包 + +### 包命名规范 + +#### Controller 包 +- Controller 类名:`{Xxx}Controller` 或 `App{Xxx}Controller` +- 直接放在 `controller/` 包下 + +#### Service 包 +- Service 接口:`{Xxx}Service.java` +- Service 实现:`{Xxx}ServiceImpl.java` +- Service 工具类:`{Xxx}Util.java` 或 `{Xxx}Helper.java` + +#### Mapper 包 +- Mapper 接口:`mapper/{Xxx}Mapper.java` +- Mapper 接口继承 `BaseMapperX` + +#### DO 包 +- DO 对象:`dataobject/{Xxx}DO.java`(可选) +- DO 类名:`{Xxx}DO.java` +- 继承 `BaseDO` 或 `TenantBaseDO` + +#### VO 包 +- Request VO: `{Xxx}SaveReqVO`、`{Xxx}PageReqVO`、`{Xxx}UpdateReqVO` +- Response VO: `{Xxx}RespVO` +- App VO: `App{Xxx}ReqVO`、`App{Xxx}RespVO` +- 直接放在 `vo/` 包下 + +### 目录结构示例 + +#### 示例 1:简单模块(tikhup) +``` +tikhup/ +├── controller/ +│ └── TikHupController.java +├── service/ +│ ├── TikHupService.java +│ ├── TikHupServiceImpl.java +│ └── TikFileTransCharacters.java +├── mapper/ +│ ├── TikPromptMapper.java +│ └── TikTokenMapper.java +└── vo/ + ├── TikPromptVO.java + └── TikTokenVO.java +``` + +#### 示例 2:完整模块(file) +``` +file/ +├── controller/ +│ ├── AppTikUserFileController.java +│ ├── AppTikFileGroupController.java +│ └── AppTikTestController.java +├── service/ +│ ├── TikUserFileService.java +│ ├── TikUserFileServiceImpl.java +│ ├── TikFileGroupService.java +│ └── TikFileGroupServiceImpl.java +├── mapper/ +│ ├── TikUserFileMapper.java +│ └── TikFileGroupMapper.java +├── vo/ +│ ├── AppTikUserFilePageReqVO.java +│ ├── AppTikUserFileRespVO.java +│ └── AppTikFileGroupCreateReqVO.java +└── enums/ + └── TikFileCategoryEnum.java +``` + +### 目录结构原则 + +1. **统一性**:同一模块内保持结构一致 +2. **简洁性**:使用 `mapper/` 和 `dataobject/` 包,结构清晰 +3. **可选性**:没有 DO 对象时可以省略 `dataobject/` 包 +4. **可扩展性**:预留扩展空间,便于后续功能扩展 + ## Controller 层规范 -### 包结构 -- `controller.admin.*`: 管理后台接口 -- `controller.app.*`: 用户端接口(C 端) -- App Controller 和 VO 必须添加 `App` 前缀 + ### 注解使用 - 使用 `@RestController` 而非 `@Controller` @@ -260,7 +369,7 @@ public UserPromptDO getUserPrompt(Long id) { ### 路径前缀 - 管理后台:`/admin-api` -- 用户端:`/app-api` +- 用户端:`/api` - Controller 路径:`/模块/资源`,如 `/ai/user-prompt` ### HTTP 方法 diff --git a/frontend/app/web-gold/src/api/material.js b/frontend/app/web-gold/src/api/material.js index d99ec401cb..ce58eedc38 100644 --- a/frontend/app/web-gold/src/api/material.js +++ b/frontend/app/web-gold/src/api/material.js @@ -39,10 +39,9 @@ export const MaterialService = { const formData = new FormData() formData.append('file', file) formData.append('fileCategory', fileCategory) + // 大文件上传需要更长的超时时间(30分钟) return http.post(`${BASE_URL}/upload`, formData, { - headers: { - 'Content-Type': 'multipart/form-data' - } + timeout: 30 * 60 * 1000 // 30分钟 }) }, diff --git a/frontend/app/web-gold/src/components/material/MaterialUploadModal.vue b/frontend/app/web-gold/src/components/material/MaterialUploadModal.vue index ca46bae2c9..ee14966859 100644 --- a/frontend/app/web-gold/src/components/material/MaterialUploadModal.vue +++ b/frontend/app/web-gold/src/components/material/MaterialUploadModal.vue @@ -25,7 +25,7 @@

点击或拖拽文件到此处上传

- 支持多文件上传,单个文件不超过 500MB + 支持多文件上传,单个文件不超过 100MB
支持格式:视频(MP4、MOV、AVI等)、图片(JPG、PNG、GIF等)、音频(MP3、WAV等)

@@ -63,7 +63,7 @@ {{ uploading ? '上传中...' : `上传 (${fileList.length})` }} @@ -94,16 +94,16 @@ const emit = defineEmits(['update:visible', 'confirm', 'cancel']) // 数据 const fileList = ref([]) -const fileCategory = ref('video') // 文件分类,默认为视频集 +// 文件分类使用默认值,不再在UI中显示 +const DEFAULT_FILE_CATEGORY = 'video' // 支持的文件类型 const acceptTypes = 'video/*,image/*,audio/*,.mp4,.mov,.avi,.mkv,.jpg,.jpeg,.png,.gif,.webp,.mp3,.wav,.aac' -// 监听 visible 变化,重置文件列表和分类 +// 监听 visible 变化,重置文件列表 watch(() => props.visible, (newVal) => { if (!newVal) { fileList.value = [] - fileCategory.value = 'video' // 重置为默认分类 } }) @@ -134,9 +134,9 @@ const formatFileSize = (bytes) => { // 上传前处理 const handleBeforeUpload = (file) => { - // 检查文件大小(500MB) - if (file.size > 500 * 1024 * 1024) { - message.warning(`文件 ${file.name} 超过 500MB,已跳过`) + // 检查文件大小(100MB) + if (file.size > 100 * 1024 * 1024) { + message.warning(`文件 ${file.name} 超过 100MB,已跳过`) return false } @@ -214,12 +214,8 @@ const handleConfirm = () => { return } - if (!fileCategory.value) { - message.warning('请选择文件分类') - return - } - - emit('confirm', files, fileCategory.value) + // 使用默认分类 + emit('confirm', files, DEFAULT_FILE_CATEGORY) } // 处理 visible 变化 @@ -239,16 +235,6 @@ const handleCancel = () => { padding: 8px 0; } -.upload-category-select { - margin-bottom: 24px; -} - -.upload-label { - margin-bottom: 8px; - font-weight: 500; - color: var(--color-text); -} - .upload-area { margin-bottom: 24px; } diff --git a/frontend/app/web-gold/src/views/material/MaterialList.vue b/frontend/app/web-gold/src/views/material/MaterialList.vue index b8928e3150..8ea8602772 100644 --- a/frontend/app/web-gold/src/views/material/MaterialList.vue +++ b/frontend/app/web-gold/src/views/material/MaterialList.vue @@ -148,7 +148,6 @@ const uploading = ref(false) // 筛选条件 const filters = reactive({ - fileCategory: undefined, fileName: '', createTime: undefined }) @@ -204,11 +203,6 @@ const handleConfirmUpload = async (files, fileCategory) => { return } - if (!fileCategory) { - message.warning('请选择文件分类') - return - } - uploading.value = true let successCount = 0 let failCount = 0 @@ -289,7 +283,6 @@ const handleFilterChange = () => { } const handleResetFilters = () => { - filters.fileCategory = undefined filters.fileName = '' filters.createTime = undefined pagination.pageNo = 1 diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index f599ba39e9..98315b3424 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -12,8 +12,8 @@ spring: servlet: # 文件上传相关配置项 multipart: - max-file-size: 16MB # 单个文件大小 - max-request-size: 32MB # 设置总上传的文件大小 + max-file-size: 100MB # 单个文件大小 + max-request-size: 200MB # 设置总上传的文件大小(支持多文件上传) # Jackson 配置项 jackson: @@ -348,4 +348,4 @@ yudao: message-bus: type: redis # 消息总线的类型 -debug: false \ No newline at end of file +debug: false