feat: 功能优化

This commit is contained in:
2025-11-16 22:09:41 +08:00
parent 995385f520
commit 3a9e823375
5 changed files with 129 additions and 42 deletions

View File

@@ -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<T>`
- **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<T>`
#### 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 方法

View File

@@ -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分钟
})
},

View File

@@ -25,7 +25,7 @@
</p>
<p class="ant-upload-text">点击或拖拽文件到此处上传</p>
<p class="ant-upload-hint">
支持多文件上传单个文件不超过 500MB
支持多文件上传单个文件不超过 100MB
<br />
支持格式视频MP4MOVAVI等图片JPGPNGGIF等音频MP3WAV等
</p>
@@ -63,7 +63,7 @@
<a-button
type="primary"
:loading="uploading"
:disabled="fileList.length === 0 || !fileCategory"
:disabled="fileList.length === 0"
@click="handleConfirm"
>
{{ 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;
}

View File

@@ -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

View File

@@ -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
debug: false