From 8c58f304f8345e046b7d71481dae7ad4eebee27e Mon Sep 17 00:00:00 2001
From: chenhj <1263187585@qq.com>
Date: 星期四, 30 四月 2026 11:48:15 +0800
Subject: [PATCH] 增加永久文件接口
---
FILE_UPLOAD_README.md | 734 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/main/resources/application-dev-pro.yml | 4
2 files changed, 736 insertions(+), 2 deletions(-)
diff --git a/FILE_UPLOAD_README.md b/FILE_UPLOAD_README.md
new file mode 100644
index 0000000..558dc85
--- /dev/null
+++ b/FILE_UPLOAD_README.md
@@ -0,0 +1,734 @@
+# 鏂囦欢涓婁紶鍔熻兘璇存槑
+
+鏈枃妗e熀浜庝互涓嬩唬鐮佹暣鐞嗭細
+
+- `src/main/java/com/ruoyi/basic/utils/FileUtil.java`
+- `src/main/java/com/ruoyi/basic/enums/ApplicationTypeEnum.java`
+- `src/main/java/com/ruoyi/basic/enums/RecordTypeEnum.java`
+- `src/main/java/com/ruoyi/project/common/CommonController.java`
+- `src/main/java/com/ruoyi/basic/controller/StorageAttachmentController.java`
+
+鐢ㄤ簬璇存槑鏈」鐩腑鏂囦欢涓婁紶銆侀檮浠剁粦瀹氥�佹枃浠堕瑙�/涓嬭浇鐨勬暣浣撹璁★紝浠ュ強 `FileUtil` 涓瘡涓柟娉曠殑浣滅敤銆�
+
+## 1. 鏁翠綋璁捐
+
+鏈」鐩殑鏂囦欢浣撶郴鍒嗘垚涓ゅ眰锛�
+
+- `storage_blob`锛氬瓨鏂囦欢瀹炰綋淇℃伅
+ - 鍘熷鏂囦欢鍚�
+ - 鍞竴鏂囦欢鍚� `uidFilename`
+ - 鏂囦欢璺緞 `path`
+ - 鏂囦欢澶у皬 `byteSize`
+ - 鏂囦欢绫诲瀷 `contentType`
+ - 鍏叡璁块棶鏍囪瘑 `resourceKey`
+- `storage_attachment`锛氬瓨鏂囦欢鍜屼笟鍔¤褰曠殑鍏宠仈鍏崇郴
+ - `application`锛氭枃浠剁敤閫�
+ - `recordType`锛氫笟鍔¤褰曠被鍨�
+ - `recordId`锛氫笟鍔¤褰曚富閿�
+ - `storageBlobId`锛氬叧鑱旂殑鏂囦欢涓昏〃 id
+
+鍙互鐞嗚В涓猴細
+
+- `storage_blob` 璐熻矗鈥滄枃浠舵湰韬��
+- `storage_attachment` 璐熻矗鈥滄枃浠舵寕鍦ㄥ摢鏉′笟鍔℃暟鎹笂鈥�
+
+## 2. 涓婁紶娴佺▼
+
+### 2.1 鏅�氫笂浼�
+
+鎺ュ彛锛�
+
+- `POST /common/upload`
+
+鎺у埗鍣ㄤ綅缃細
+
+- `src/main/java/com/ruoyi/project/common/CommonController.java`
+
+鍏ュ弬锛�
+
+- 琛ㄥ崟瀛楁鍚嶏細`files`
+- 绫诲瀷锛歚List<MultipartFile>`
+
+浠g爜閫昏緫锛�
+
+1. 鍓嶇鍏堣皟鐢� `/common/upload`
+2. `CommonController.upload()` 璋冪敤 `storageBlobService.upload(files, false)`
+3. 鏈嶅姟灞備繚瀛樻枃浠跺厓鏁版嵁鍒� `storage_blob`
+4. 杩斿洖 `StorageBlobVO` 鍒楄〃锛岄噷闈㈤�氬父浼氬甫锛�
+ - 鏂囦欢 id
+ - 鍘熷鏂囦欢鍚�
+ - 鍞竴鏂囦欢鍚�
+ - 棰勮鍦板潃 `previewURL`
+ - 涓嬭浇鍦板潃 `downloadURL`
+
+璇存槑锛�
+
+- 姝ゆ椂鍙槸鈥滀笂浼犱簡鏂囦欢鈥�
+- 杩樻病鏈夊拰鍏蜂綋涓氬姟鍗曟嵁寤虹珛鍏崇郴
+
+### 2.2 鍏叡涓婁紶
+
+鎺ュ彛锛�
+
+- `POST /common/public/upload`
+
+浠g爜閫昏緫锛�
+
+- `CommonController.publicUpload()` 璋冪敤 `storageBlobService.upload(files, true)`
+
+璇存槑锛�
+
+- 璇ユ帴鍙d笂浼犵殑鏂囦欢璧扳�滃叕鍏辨枃浠垛�濇ā寮�
+- 鎺у埗鍣ㄦ敞閲婂凡鏄庣‘璇存槑锛氭案涔呮湁鏁堬紝鎱庣敤
+- 瀵瑰簲 URL 鏋勫缓鏃讹紝鍙兘璧� `publicKey` 鍙傛暟锛岃�屼笉鏄复鏃� `token`
+
+## 3. 闄勪欢缁戝畾娴佺▼
+
+涓婁紶瀹屾垚鍚庯紝濡傛灉闇�瑕佹妸鏂囦欢缁戝畾鍒版煇鏉′笟鍔¤褰曪紝闇�瑕佸啀璋冪敤闄勪欢鎺ュ彛銆�
+
+鎺ュ彛锛�
+
+- `POST /storageAttachment/add`
+
+鎺у埗鍣ㄤ綅缃細
+
+- `src/main/java/com/ruoyi/basic/controller/StorageAttachmentController.java`
+
+鏍稿績璇锋眰瀵硅薄锛�
+
+- `StorageAttachmentDTO`
+
+鍏朵腑缁ф壙浜� `StorageAttachment`锛屽苟棰濆鍖呭惈锛�
+
+- `storageBlobDTOs`锛氬緟缁戝畾鐨勬枃浠跺垪琛�
+
+甯哥敤瀛楁鍚箟锛�
+
+- `application`锛氭枃浠剁敤閫�
+- `recordType`锛氫笟鍔$被鍨�
+- `recordId`锛氫笟鍔′富閿�
+- `storageBlobDTOs[].id`锛氫笂浼犳垚鍔熷悗杩斿洖鐨勬枃浠� id
+
+绀轰緥璇锋眰浣擄細
+
+```json
+{
+ "application": "file",
+ "recordType": "common_file",
+ "recordId": 1001,
+ "storageBlobDTOs": [
+ {
+ "id": 12,
+ "application": "file"
+ },
+ {
+ "id": 13,
+ "application": "file"
+ }
+ ]
+}
+```
+
+缁戝畾閫昏緫璇存槑锛�
+
+1. 鍏堜笂浼犳枃浠讹紝鎷垮埌 `storage_blob.id`
+2. 鍐嶈皟鐢� `/storageAttachment/add`
+3. 鏈嶅姟灞傛渶缁堜細閫氳繃 `FileUtil` 淇濆瓨 `storage_attachment`
+4. 鍚庣画鍗冲彲鎸変笟鍔¤褰曟煡璇㈠嚭璇ヨ褰曚笅鐨勯檮浠�
+
+## 4. 鏌ヨ涓庡垹闄ら檮浠�
+
+### 4.1 鏌ヨ闄勪欢鍒楄〃
+
+鎺ュ彛锛�
+
+- `GET /storageAttachment/list`
+
+璇存槑锛�
+
+- 鎸� `StorageAttachmentDTO` 涓殑鏉′欢鏌ヨ
+- 甯歌鏉′欢鏄� `application`銆乣recordType`銆乣recordId`
+- 杩斿洖缁撴灉鏈川涓婃槸鍜屼笟鍔¤褰曞叧鑱斿悗鐨勬枃浠跺垪琛�
+
+### 4.2 鍒犻櫎闄勪欢
+
+鎺ュ彛锛�
+
+- `DELETE /storageAttachment/delete`
+
+璇锋眰浣擄細
+
+- `List<Long> ids`
+
+璇存槑锛�
+
+- 杩欓噷鐨� `ids` 鏄檮浠跺叧鑱旇〃 id锛屼竴鑸槸 `storage_attachment.id`
+- 鍒犻櫎鏃堕�氬父涓嶄粎浼氬垹鍏宠仈鍏崇郴锛屼篃浼氳繘涓�姝ュ垹闄ゅ搴旀枃浠惰褰�
+
+## 5. 棰勮涓庝笅杞芥祦绋�
+
+### 5.1 涓嬭浇鎺ュ彛
+
+鎺ュ彛锛�
+
+- `GET /common/download/{fileName}`
+
+鏀寔涓ょ璁块棶鏂瑰紡锛�
+
+- 涓存椂閾炬帴锛歚token`
+- 鍏叡閾炬帴锛歚publicKey`
+
+浠g爜閫昏緫锛�
+
+1. 濡傛灉璇锋眰閲屾湁 `publicKey`锛岃蛋 `storageBlobService.getPublicFile(fileName, publicKey)`
+2. 鍚﹀垯璧� `storageBlobService.getFileByToken(fileName, token)`
+3. 鍙栧埌瀹為檯鏂囦欢鍚庯紝璋冪敤 `fileUtil.compressFile(file)` 鍋氬浘鐗囧帇缂╁鐞�
+4. 璁剧疆涓嬭浇鍝嶅簲澶达紝杈撳嚭鏂囦欢娴�
+
+### 5.2 棰勮鎺ュ彛
+
+鎺ュ彛锛�
+
+- `GET /common/preview/{fileName}`
+
+鏀寔涓ょ璁块棶鏂瑰紡锛�
+
+- 涓存椂閾炬帴锛歚token`
+- 鍏叡閾炬帴锛歚publicKey`
+
+浠g爜閫昏緫锛�
+
+1. 鏍¢獙 `token` 鎴� `publicKey`
+2. 鑾峰彇鏂囦欢
+3. 璋冪敤 `fileUtil.compressFile(file)`
+4. 鏍规嵁鏂囦欢鍐呭绫诲瀷杩斿洖 inline 棰勮
+
+## 6. 鏋氫妇鍚箟
+
+### 6.1 `ApplicationTypeEnum`
+
+浣嶇疆锛�
+
+- `src/main/java/com/ruoyi/basic/enums/ApplicationTypeEnum.java`
+
+褰撳墠瀹氫箟鍊硷細
+
+| 鏋氫妇 | type | 璇存槑 |
+|---|---|---|
+| `IMAGE` | `image` | 鍥剧墖绫绘枃浠� |
+| `FILE` | `file` | 鏅�氭枃浠� |
+| `AFTER_FILE` | `after_file` | 鍞悗鐩稿叧鏂囦欢 |
+| `BEFORE_FILE` | `before_file` | 鍞墠/鍓嶇疆鐩稿叧鏂囦欢 |
+| `APK` | `apk` | 瀹夎鍖呮枃浠� |
+
+浣滅敤锛�
+
+- 鐢ㄤ簬鍖哄垎鍚屼竴鏉′笟鍔¤褰曚笅锛屼笉鍚岀敤閫旂殑鏂囦欢
+- `FileUtil` 鐨勫緢澶氭煡璇€�佸垹闄ゃ�佷繚瀛樻柟娉曢兘浼氱敤鍒拌瀛楁
+
+### 6.2 `RecordTypeEnum`
+
+浣嶇疆锛�
+
+- `src/main/java/com/ruoyi/basic/enums/RecordTypeEnum.java`
+
+浣滅敤锛�
+
+- 鐢ㄤ簬鏍囪鏂囦欢灞炰簬鍝被涓氬姟璁板綍
+- 渚嬪璐ㄦ銆侀噰璐�佸鎴枫�佸敭鍚庛�佸彴璐︺�侀�氱煡銆佽澶囩瓑妯″潡
+- 涓婁紶瀹屾垚鍚庯紝闄勪欢鏈�缁堥�氳繃 `recordType + recordId` 鍜屼笟鍔℃暟鎹叧鑱�
+
+璇存槑锛�
+
+- 璇ユ灇涓惧�煎緢澶氾紝鏂囨。涓嶉�愪釜灞曞紑
+- 瀹為檯浣跨敤鏃跺繀椤讳紶浠g爜涓凡瀹氫箟鐨� `type` 鍊�
+- 濡傦細
+ - `common_file`
+ - `after_sales_service`
+ - `quality_inspect`
+ - `product`
+ - `notice`
+
+## 7. `FileUtil` 鏂规硶璇存槑
+
+`FileUtil` 鏄湰濂楁枃浠朵笂浼犱綋绯荤殑鏍稿績宸ュ叿绫伙紝涓昏璐熻矗锛�
+
+- 鏂囦欢涓庝笟鍔¤褰曠粦瀹�
+- 鏂囦欢涓庨檮浠跺垹闄�
+- 闄勪欢鏌ヨ
+- 棰勮/涓嬭浇鍦板潃鐢熸垚
+- token 浣跨敤娆℃暟鎺у埗
+- 鍥剧墖鍘嬬缉
+
+涓嬮潰鎸夊姛鑳藉垎缁勮鏄庢瘡涓柟娉曘��
+
+### 7.1 淇濆瓨闄勪欢鍏崇郴
+
+#### 1. `saveStorageAttachment(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId, List<StorageBlobDTO> storageBlobDTOS)`
+
+浣滅敤锛�
+
+- 鎸夆�滄枃浠剁敤閫� + 璁板綍绫诲瀷 + 璁板綍 id鈥濅繚瀛橀檮浠跺叧绯�
+
+閫昏緫锛�
+
+1. 鏍¢獙 `application`銆乣recordType`銆乣recordId`
+2. 鍏堝垹闄よ繖缁勪笟鍔¤褰曚笅鐨勬棫闄勪欢
+3. 鎶婃柊鐨� `storageBlobDTOS` 杞垚 `storage_attachment` 璁板綍鍚庢壒閲忔彃鍏�
+
+閫傜敤鍦烘櫙锛�
+
+- 鏌愭潯涓氬姟鏁版嵁閲嶆柊淇濆瓨闄勪欢锛屾棫闄勪欢鏁翠綋鏇挎崲鎴愭柊闄勪欢
+
+#### 2. `saveStorageAttachmentByRecordTypeAndRecordId(String application, RecordTypeEnum recordType, Long recordId, List<StorageBlobDTO> storageBlobDTOS)`
+
+浣滅敤锛�
+
+- 鎸� `recordType + recordId` 淇濆瓨闄勪欢鍏崇郴锛宍application` 鍙寚瀹氾紝涔熷彲浠庢瘡涓枃浠跺璞¢噷璇诲彇
+
+閫昏緫鐗圭偣锛�
+
+- 濡傛灉 `application == null`锛屼細鏍规嵁 `storageBlobDTO.application` 鍒嗗埆鍒犻櫎鏃у叧绯�
+- 濡傛灉闄勪欢鍒楄〃涓虹┖锛屼細鐩存帴鍒犻櫎璇ヤ笟鍔¤褰曠殑闄勪欢鍏崇郴
+- 鎻掑叆鏃朵細鑷姩鍥炲~ `application`
+
+閫傜敤鍦烘櫙锛�
+
+- 涓�娆℃彁浜ら噷鍙兘鍖呭惈澶氱鐢ㄩ�旂殑闄勪欢
+- 鎴栬�呰皟鐢ㄦ柟涓嶆柟渚跨洿鎺ヤ紶鏋氫妇绫诲瀷
+
+### 7.2 鍒犻櫎鏂囦欢涓昏〃 `storage_blob`
+
+#### 3. `deleteStorageBlobs(List<Long> storageBlobIds)`
+
+浣滅敤锛�
+
+- 鎸夋枃浠朵富琛� id 鎵归噺鍒犻櫎鏂囦欢璁板綍
+
+#### 4. `deleteStorageBlobsByStorageAttachmentIds(List<Long> storageAttachmentIds)`
+
+浣滅敤锛�
+
+- 鍏堟牴鎹檮浠跺叧鑱� id 鏌ュ埌 `storageBlobId`
+- 鍐嶅垹闄ゅ搴旂殑鏂囦欢涓昏〃璁板綍
+
+#### 5. `deleteStorageBlobsByApplicationAndRecordTypeAndRecordIds(ApplicationTypeEnum application, RecordTypeEnum recordType, List<Long> recordIds)`
+
+浣滅敤锛�
+
+- 鏍规嵁鐢ㄩ�斻�佽褰曠被鍨嬨�佸涓笟鍔� id锛屾壒閲忓垹闄ゅ搴旂殑鏂囦欢涓昏〃璁板綍
+
+閫傜敤鍦烘櫙锛�
+
+- 鎵归噺鍒犻櫎鏌愮被涓氬姟鏁版嵁鏃讹紝鍚屾椂娓呯悊闄勪欢
+
+#### 6. `deleteStorageBlobsByRecordTypeAndRecordId(RecordTypeEnum recordType, Long recordId)`
+
+浣滅敤锛�
+
+- 鏍规嵁 `recordType + recordId` 鍒犻櫎璇ヤ笟鍔¤褰曚笅鎵�鏈夋枃浠朵富琛ㄨ褰�
+
+### 7.3 鍒犻櫎闄勪欢鍏崇郴 `storage_attachment`
+
+#### 7. `deleteStorageAttachmentsByStorageAttachmentIds(List<Long> storageAttachmentIds)`
+
+浣滅敤锛�
+
+- 鍏堝垹闄ら檮浠跺搴旂殑鏂囦欢涓昏〃璁板綍
+- 鍐嶅垹闄ら檮浠跺叧绯昏〃璁板綍
+
+#### 8. `deleteStorageAttachmentsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId)`
+
+浣滅敤锛�
+
+- 鍒犻櫎鎸囧畾鐢ㄩ�斻�佹寚瀹氫笟鍔¤褰曚笅鐨勯檮浠跺叧绯�
+
+鐗圭偣锛�
+
+- 浼氬厛鍒� blob锛屽啀鍒� attachment
+
+#### 9. `deleteStorageAttachmentsByRecordTypeAndRecordId(RecordTypeEnum recordType, Long recordId)`
+
+浣滅敤锛�
+
+- 鍒犻櫎鎸囧畾涓氬姟璁板綍涓嬪叏閮ㄩ檮浠跺叧绯伙紝涓嶅尯鍒嗙敤閫�
+
+#### 10. `deleteStorageAttachmentsByApplicationAndRecordTypeAndRecordIds(ApplicationTypeEnum application, RecordTypeEnum recordType, List<Long> recordIds)`
+
+浣滅敤锛�
+
+- 鎸夊涓笟鍔� id 鎵归噺鍒犻櫎闄勪欢鍏崇郴
+
+### 7.4 鏌ヨ闄勪欢鍏崇郴
+
+#### 11. `getStorageAttachmentsByStorageAttachmentIds(List<Long> storageAttachmentIds)`
+
+浣滅敤锛�
+
+- 鏍规嵁闄勪欢鍏崇郴 id 鏌ヨ `storage_attachment` 璁板綍
+
+#### 12. `getStorageAttachmentsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId)`
+
+浣滅敤锛�
+
+- 鎸夌敤閫斻�佷笟鍔$被鍨嬨�佷笟鍔� id 鏌ヨ闄勪欢鍏崇郴
+
+#### 13. `getStorageAttachmentsByRecordTypeAndRecordId(RecordTypeEnum recordType, Long recordId)`
+
+浣滅敤锛�
+
+- 鎸変笟鍔$被鍨嬨�佷笟鍔� id 鏌ヨ闄勪欢鍏崇郴
+
+### 7.5 鏌ヨ鏂囦欢淇℃伅 `StorageBlobVO`
+
+#### 14. `getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(StorageAttachmentDTO storageAttachmentDTO)`
+
+浣滅敤锛�
+
+- 閫氳繃 `StorageAttachmentDTO` 鏉′欢鏌ヨ鏂囦欢鍒楄〃
+
+鐗圭偣锛�
+
+- `application` 鍙��
+- 鏈�缁堣繑鍥炵殑鏄甫棰勮/涓嬭浇鍦板潃鐨� `StorageBlobVO`
+
+#### 15. `getStorageBlobVOsByStorageAttachmentIds(List<Long> storageAttachmentIds)`
+
+浣滅敤锛�
+
+- 鏍规嵁闄勪欢鍏崇郴 id 鏌ヨ鏂囦欢鍒楄〃
+
+鐗圭偣锛�
+
+- 浼氳嚜鍔ㄦ瀯寤猴細
+ - `previewURL`
+ - `downloadURL`
+ - `storageAttachmentId`
+
+#### 16. `getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId)`
+
+浣滅敤锛�
+
+- 鎸夌敤閫斻�佷笟鍔$被鍨嬨�佷笟鍔� id 鏌ヨ鏂囦欢鍒楄〃
+
+#### 17. `getStorageBlobVOsByRecordTypeAndRecordId(RecordTypeEnum recordType, Long recordId)`
+
+浣滅敤锛�
+
+- 鎸変笟鍔$被鍨嬨�佷笟鍔� id 鏌ヨ鏂囦欢鍒楄〃
+
+#### 18. `getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId, BigDecimal expired)`
+
+浣滅敤锛�
+
+- 鍜岀 16 涓柟娉曠被浼硷紝浣嗗彲浠ヨ嚜瀹氫箟閾炬帴杩囨湡鏃堕棿
+
+璇存槑锛�
+
+- `expired` 鍗曚綅鏄垎閽�
+- 杩斿洖鐨勯瑙�/涓嬭浇鍦板潃浼氭寜杩欎釜鏃堕棿鐢熸垚绛惧悕
+
+#### 19. `getStorageBlobVOsByStorageAttachmentIds(List<Long> storageAttachmentIds, BigDecimal expired)`
+
+浣滅敤锛�
+
+- 鏍规嵁闄勪欢鍏崇郴 id 鏌ヨ鏂囦欢鍒楄〃锛屽苟鑷畾涔夐摼鎺ヨ繃鏈熸椂闂�
+
+### 7.6 鏌ヨ闄勪欢瑙嗗浘 `StorageAttachmentVO`
+
+#### 20. `getStorageAttachmentVOSByStorageAttachmentIds(List<Long> storageAttachmentIds)`
+
+浣滅敤锛�
+
+- 鏌ヨ闄勪欢瑙嗗浘瀵硅薄
+
+鐗圭偣锛�
+
+- 姣忔潯闄勪欢璁板綍閲屼細宓屽鑷繁鐨� `storageBlobVOS`
+
+#### 21. `getStorageAttachmentVOSByStorageAttachmentIds(List<Long> storageAttachmentIds, BigDecimal expired)`
+
+浣滅敤锛�
+
+- 鏍规嵁闄勪欢鍏崇郴 id 鏌ヨ闄勪欢瑙嗗浘锛屽苟鑷畾涔夐摼鎺ヨ繃鏈熸椂闂�
+
+#### 22. `getStorageAttachmentVOSByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId)`
+
+浣滅敤锛�
+
+- 鎸変笟鍔$淮搴︽煡璇㈤檮浠惰鍥�
+
+#### 23. `getStorageAttachmentVOSByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId, BigDecimal expired)`
+
+浣滅敤锛�
+
+- 鎸変笟鍔$淮搴︽煡璇㈤檮浠惰鍥撅紝骞惰嚜瀹氫箟閾炬帴杩囨湡鏃堕棿
+
+### 7.7 浠呰幏鍙栭瑙堝湴鍧�
+
+#### 24. `getFilePreviewURLByStorageAttachmentIds(List<Long> storageAttachmentIds)`
+
+浣滅敤锛�
+
+- 鏍规嵁闄勪欢鍏崇郴 id 鍒楄〃锛岃繑鍥為瑙堝湴鍧�鍒楄〃
+
+#### 25. `getFilePreviewURLByStorageAttachmentIds(List<Long> storageAttachmentIds, BigDecimal expired)`
+
+浣滅敤锛�
+
+- 鏍规嵁闄勪欢鍏崇郴 id 鍒楄〃锛岃繑鍥炲甫鑷畾涔夎繃鏈熸椂闂寸殑棰勮鍦板潃鍒楄〃
+
+#### 26. `getFilePreviewURLByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId)`
+
+浣滅敤锛�
+
+- 鎸変笟鍔$淮搴﹁繑鍥為瑙堝湴鍧�鍒楄〃
+
+#### 27. `getFilePreviewURLByApplicationAndRecordTypeAndRecordIdAndExpired(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId, BigDecimal expired)`
+
+浣滅敤锛�
+
+- 鎸変笟鍔$淮搴﹁繑鍥炲甫鑷畾涔夎繃鏈熸椂闂寸殑棰勮鍦板潃鍒楄〃
+
+### 7.8 浠呰幏鍙栦笅杞藉湴鍧�
+
+#### 28. `getFileDownloadURLByStorageAttachmentIds(List<Long> storageAttachmentIds)`
+
+浣滅敤锛�
+
+- 鏍规嵁闄勪欢鍏崇郴 id 鍒楄〃锛岃繑鍥炰笅杞藉湴鍧�鍒楄〃
+
+#### 29. `getFileDownloadURLByStorageAttachmentIds(List<Long> storageAttachmentIds, BigDecimal expired)`
+
+浣滅敤锛�
+
+- 鏍规嵁闄勪欢鍏崇郴 id 鍒楄〃锛岃繑鍥炲甫鑷畾涔夎繃鏈熸椂闂寸殑涓嬭浇鍦板潃鍒楄〃
+
+#### 30. `getFileDownloadURLByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId)`
+
+浣滅敤锛�
+
+- 鎸変笟鍔$淮搴﹁繑鍥炰笅杞藉湴鍧�鍒楄〃
+
+#### 31. `getFileDownloadURLByApplicationAndRecordTypeAndRecordIdAndExpired(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId, BigDecimal expired)`
+
+浣滅敤锛�
+
+- 鎸変笟鍔$淮搴﹁繑鍥炲甫鑷畾涔夎繃鏈熸椂闂寸殑涓嬭浇鍦板潃鍒楄〃
+
+### 7.9 鏋勫缓绛惧悕 URL
+
+#### 32. `buildSignedPreviewUrl(StorageBlobVO storageBlob)`
+
+浣滅敤锛�
+
+- 浣跨敤绯荤粺榛樿杩囨湡鏃堕棿锛岀敓鎴愰瑙堥摼鎺�
+
+瀹為檯璋冪敤锛�
+
+- 鍐呴儴绛変环浜庤皟鐢� `buildSignedUrl(storageBlob, "/preview/", properties.getExpired())`
+
+#### 33. `buildSignedDownloadUrl(StorageBlobVO storageBlob)`
+
+浣滅敤锛�
+
+- 浣跨敤绯荤粺榛樿杩囨湡鏃堕棿锛岀敓鎴愪笅杞介摼鎺�
+
+瀹為檯璋冪敤锛�
+
+- 鍐呴儴绛変环浜庤皟鐢� `buildSignedUrl(storageBlob, "/download/", properties.getExpired())`
+
+#### 34. `buildSignedUrl(StorageBlobVO storageBlob, String actionPath, BigDecimal expired)`
+
+浣滅敤锛�
+
+- 鏋勫缓缁熶竴鐨勫甫绛惧悕棰勮/涓嬭浇鍦板潃
+
+鏀寔锛�
+
+- `actionPath = "/preview/"`
+- `actionPath = "/download/"`
+
+鏍稿績閫昏緫锛�
+
+1. 鏍¢獙璺緞鍙傛暟鍜屾枃浠朵俊鎭�
+2. 鎷兼帴鍩虹璁块棶鍦板潃
+3. 濡傛灉 `expired == -1`锛屼笉鐢熸垚 token锛岀洿鎺ヨ蛋 `publicKey`
+4. 鍚﹀垯鐢熸垚甯﹁繃鏈熸椂闂寸殑 JWT token
+5. 鎶� token 鐨勪娇鐢ㄦ鏁颁俊鎭啓鍏� Redis
+6. 杩斿洖鏈�缁� URL
+
+閲嶈璇存槑锛�
+
+- `expired` 鍗曚綅涓哄垎閽�
+- 榛樿杩囨湡鏃堕棿涓� 120 鍒嗛挓
+- 闈炴案涔呴摼鎺ヤ細鍙椻�滆繃鏈熸椂闂� + 浣跨敤娆℃暟闄愬埗鈥濆弻閲嶆帶鍒�
+
+### 7.10 token 浣跨敤鎺у埗
+
+#### 35. `cacheTokenUsage(String token, long expiredMillis)`
+
+浣滅敤锛�
+
+- 鎶� token 浣跨敤娆℃暟鍒濆鍖栧埌 Redis
+
+鐗圭偣锛�
+
+- 鍒濆鍊煎啓鍏ヤ负 `0`
+- TTL 涓� token 杩囨湡鏃堕棿淇濇寔涓�鑷�
+
+璇存槑锛�
+
+- 杩欐槸绉佹湁鏂规硶锛屼緵 `buildSignedUrl()` 鍐呴儴璋冪敤
+
+#### 36. `buildTokenUsageKey(String token)`
+
+浣滅敤锛�
+
+- 缁熶竴鐢熸垚 Redis key
+
+鏍煎紡锛�
+
+- `file:token:usage:{token}`
+
+璇存槑锛�
+
+- 杩欐槸绉佹湁鏂规硶
+
+#### 37. `validateTokenUsage(String token)`
+
+浣滅敤锛�
+
+- 鏍¢獙 token 鏄惁杩樿兘缁х画浣跨敤
+
+鏍稿績閫昏緫锛�
+
+1. 浠� Redis 璇诲彇褰撳墠浣跨敤娆℃暟
+2. 濡傛灉娌℃湁鍊硷紝璁や负閾炬帴宸茶繃鏈熸垨宸插け鏁�
+3. 濡傛灉杈惧埌涓婇檺锛岀珛鍗冲垹闄� Redis 璁板綍骞舵姤閿�
+4. 鍚﹀垯鑷涓�娆′娇鐢ㄦ鏁�
+5. 濡傛灉鑷鍚庤揪鍒颁笂闄愶紝鍐嶅垹闄� Redis 璁板綍
+
+璇存槑锛�
+
+- 璇ユ柟娉曢�氬父浼氬湪瀹為檯璁块棶鏂囦欢鏃剁敱鏈嶅姟灞傝皟鐢�
+
+#### 38. `resolveLimit()`
+
+浣滅敤锛�
+
+- 瑙f瀽 token 鍙娇鐢ㄦ鏁颁笂闄�
+
+瑙勫垯锛�
+
+- `properties.getUseLimit() <= 0` 鏃讹紝榛樿杩斿洖 `10`
+
+璇存槑锛�
+
+- 杩欐槸绉佹湁鏂规硶
+
+### 7.11 璺緞涓庡帇缂�
+
+#### 39. `buildRelativePath()`
+
+浣滅敤锛�
+
+- 鐢熸垚鏂囦欢瀛樺偍鐩稿璺緞
+
+鏍煎紡锛�
+
+- `yyyy/MMdd`
+
+渚嬪锛�
+
+- `2026/0430`
+
+鐢ㄩ�旓細
+
+- 涓�鑸敤浜庢寜鏃ユ湡鍒嗙洰褰曚繚瀛樹笂浼犳枃浠�
+
+#### 40. `compressFile(File file)`
+
+浣滅敤锛�
+
+- 瀵瑰浘鐗囪繘琛屽帇缂╋紝闈炲浘鐗囨垨涓嶆弧瓒虫潯浠舵椂杩斿洖鍘熸枃浠�
+
+鍘嬬缉鏉′欢锛�
+
+1. 寮�鍚簡 `properties.getCompress()`
+2. 鏂囦欢鏄浘鐗�
+3. 鏂囦欢澶у皬澶т簬 `properties.getNeedCompressSize()`
+
+澶勭悊閫昏緫锛�
+
+1. 鐩爣鏂囦欢鍚嶄负 `thumb_鍘熸枃浠跺悕`
+2. 濡傛灉鍘嬬缉鏂囦欢宸插瓨鍦紝鐩存帴澶嶇敤
+3. 浣跨敤 `Thumbnailator` 鎸夊師灏哄鍘嬬缉鐢昏川
+4. 濡傛灉鍘嬬缉澶辫触锛岄檷绾ц繑鍥炲師鏂囦欢
+
+璇存槑锛�
+
+- 褰撳墠涓嬭浇鍜岄瑙堟帴鍙i兘浼氳皟鐢ㄨ繖涓柟娉�
+
+#### 41. `isImage(String fileName)`
+
+浣滅敤锛�
+
+- 绠�鍗曞垽鏂枃浠舵槸鍚︽槸鍥剧墖
+
+鏀寔鍚庣紑锛�
+
+- `jpg`
+- `jpeg`
+- `png`
+
+璇存槑锛�
+
+- 杩欐槸绉佹湁鏂规硶锛屼緵 `compressFile()` 浣跨敤
+
+## 8. 鎺ㄨ崘浣跨敤椤哄簭
+
+涓氬姟涓婃渶甯歌鐨勬帴鍏ラ『搴忓涓嬶細
+
+1. 鍓嶇涓婁紶鏂囦欢鍒� `/common/upload`
+2. 鎷垮埌杩斿洖缁撴灉涓殑鏂囦欢 id
+3. 涓氬姟淇濆瓨鏃惰皟鐢� `/storageAttachment/add`
+4. 浼犲叆 `application + recordType + recordId + storageBlobDTOs`
+5. 鍚庣画椤甸潰鍥炴樉鏃舵寜涓氬姟鏉′欢璋冪敤闄勪欢鏌ヨ
+6. 鍓嶇浣跨敤杩斿洖鐨� `previewURL` 鎴� `downloadURL`
+
+## 9. 甯歌娉ㄦ剰鐐�
+
+### 9.1 鍏堜笂浼狅紝鍐嶇粦瀹�
+
+- `/common/upload` 鍙礋璐f枃浠跺叆搴�
+- `/storageAttachment/add` 鎵嶆槸鍜屼笟鍔℃暟鎹缓绔嬪叧绯�
+
+### 9.2 `application` 寰堥噸瑕�
+
+- 鍚屼竴鏉� `recordId` 涓嬪彲鑳芥湁澶氱粍涓嶅悓鐢ㄩ�旈檮浠�
+- 鍒犻櫎鍜屾煡璇㈡椂锛岀粡甯镐緷璧� `application`
+
+### 9.3 涓嬭浇閾炬帴涓嶆槸姘镐箙鏈夋晥
+
+- 鏅�氶摼鎺ヤ竴鑸�氳繃 JWT token 鎺у埗
+- 鍚屾椂鍙楄繃鏈熸椂闂村拰浣跨敤娆℃暟闄愬埗
+
+### 9.4 鍏叡鏂囦欢瑕佹厧鐢�
+
+- `public/upload` 涓婁紶鐨勬枃浠跺彲璧版案涔呭叕寮�璁块棶
+- 閫傚悎鍏紑璧勬簮锛屼笉閫傚悎鏁忔劅鏂囦欢
+
+### 9.5 鍥剧墖棰勮/涓嬭浇鍙兘杩斿洖鍘嬬缉鏂囦欢
+
+- 褰撳墠鎺у埗鍣ㄥ湪涓嬭浇鍜岄瑙堝墠閮戒細璋冪敤 `compressFile()`
+- 澶у浘鍦ㄨ闂椂鍙兘浣跨敤鍘嬬缉鍚庣殑鍓湰
+
+## 10. 涓�鍙ヨ瘽鎬荤粨
+
+鏈」鐩殑鏂囦欢涓婁紶鏂规鏄�滀袱闃舵妯″瀷鈥濓細
+
+- 绗竴闃舵涓婁紶鏂囦欢锛岀敓鎴� `storage_blob`
+- 绗簩闃舵缁戝畾涓氬姟锛岀敓鎴� `storage_attachment`
+
+鑰� `FileUtil` 鍒欒礋璐f妸鈥滀笂浼犲悗鐨勬枃浠垛�濆彉鎴愨�滃彲鏌ヨ銆佸彲棰勮銆佸彲涓嬭浇銆佸彲鍒犻櫎銆佸彲鎺ф椂鏁堚�濈殑瀹屾暣闄勪欢鑳藉姏銆�
diff --git a/src/main/resources/application-dev-pro.yml b/src/main/resources/application-dev-pro.yml
index 1552370..abb1950 100644
--- a/src/main/resources/application-dev-pro.yml
+++ b/src/main/resources/application-dev-pro.yml
@@ -254,8 +254,8 @@
# 鏂囦欢涓婁紶閰嶇疆
file:
- temp-dir: D:/ruoyi/temp/uploads # 涓存椂鐩綍
- upload-dir: D:/ruoyi/prod/uploads # 姝e紡鐩綍
+ temp-dir: D:/ruoyi/temp/uploads # 涓存椂鐩綍 鍚庢湡鍒犻櫎
+ upload-dir: D:/ruoyi/prod/uploads # 姝e紡鐩綍 鍚庢湡鍒犻櫎
path: C:/Users/12631/Desktop/download/uploads # 涓婁紶鐩綍
urlPrefix: /common # 閾炬帴鍓嶇紑
domain: http://127.0.0.1:7003 # 鍩熷悕鍓嶇紑
--
Gitblit v1.9.3