1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package com.ruoyi.account.controller;
 
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.basic.dto.StorageBlobVO;
import com.ruoyi.basic.mapper.StorageAttachmentMapper;
import com.ruoyi.basic.mapper.StorageBlobMapper;
import com.ruoyi.basic.pojo.StorageAttachment;
import com.ruoyi.basic.pojo.StorageBlob;
import com.ruoyi.basic.utils.FileUtil;
import com.ruoyi.framework.web.domain.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
 
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
 
@RestController
@RequiredArgsConstructor
@Tag(name = "账户附件管理")
@RequestMapping("/account/accountFile")
public class AccountFileController {
 
    private final StorageAttachmentMapper storageAttachmentMapper;
    private final StorageBlobMapper storageBlobMapper;
    private final FileUtil fileUtil;
 
    @GetMapping("/listPage")
    @Operation(summary = "分页查询附件列表")
    public R listPage(
            @RequestParam Long accountId,
            @RequestParam String accountType,
            @RequestParam(defaultValue = "1") Long current,
            @RequestParam(defaultValue = "10") Long size) {
 
        Page<StorageBlobVO> page = new Page<>(current, size);
 
        LambdaQueryWrapper<StorageAttachment> queryWrapper = new LambdaQueryWrapper<StorageAttachment>()
                .eq(StorageAttachment::getRecordType, accountType)
                .eq(StorageAttachment::getRecordId, accountId);
 
        Long total = storageAttachmentMapper.selectCount(queryWrapper);
        page.setTotal(total);
 
        if (total == 0) {
            page.setRecords(new ArrayList<>());
            return R.ok(page);
        }
 
        List<StorageAttachment> storageAttachments = storageAttachmentMapper.selectList(queryWrapper);
        Map<Long, Long> blobIdToAttachmentIdMap = storageAttachments.stream()
                .collect(Collectors.toMap(StorageAttachment::getStorageBlobId, StorageAttachment::getId));
 
        List<Long> storageBlobIds = storageAttachments.stream()
                .map(StorageAttachment::getStorageBlobId)
                .collect(Collectors.toList());
 
        List<StorageBlob> storageBlobs = storageBlobMapper.selectByIds(storageBlobIds);
        List<StorageBlobVO> storageBlobVOS = new ArrayList<>();
        for (StorageBlob storageBlob : storageBlobs) {
            StorageBlobVO storageBlobVO = new StorageBlobVO();
            BeanUtils.copyProperties(storageBlob, storageBlobVO);
            storageBlobVO.setPreviewURL(fileUtil.buildSignedPreviewUrl(storageBlobVO));
            storageBlobVO.setUrl(fileUtil.buildSignedPreviewUrl(storageBlobVO));
            storageBlobVO.setName(storageBlob.getOriginalFilename());
            storageBlobVO.setDownloadURL(fileUtil.buildSignedDownloadUrl(storageBlobVO));
            storageBlobVO.setStorageAttachmentId(blobIdToAttachmentIdMap.get(storageBlob.getId()));
            storageBlobVOS.add(storageBlobVO);
        }
 
        page.setRecords(storageBlobVOS);
        return R.ok(page);
    }
 
    @PostMapping("/add")
    @Operation(summary = "保存附件")
    public R add(@RequestBody Map<String, Object> params) {
        Long accountId = params.get("accountId") != null ? Long.valueOf(params.get("accountId").toString()) : null;
        String accountType = params.get("accountType") != null ? params.get("accountType").toString() : null;
 
        Long storageBlobId = null;
        if (params.get("id") != null) {
            storageBlobId = Long.valueOf(params.get("id").toString());
        } else if (params.get("url") != null) {
            String url = params.get("url").toString();
            int previewIdx = url.indexOf("/preview/");
            if (previewIdx >= 0) {
                String afterPreview = url.substring(previewIdx + "/preview/".length());
                int queryIdx = afterPreview.indexOf("?");
                String uidFilename = queryIdx >= 0 ? afterPreview.substring(0, queryIdx) : afterPreview;
                StorageBlob blob = storageBlobMapper.selectOne(new LambdaQueryWrapper<StorageBlob>()
                        .eq(StorageBlob::getUidFilename, uidFilename).last("limit 1"));
                if (blob != null) {
                    storageBlobId = blob.getId();
                }
            }
        }
 
        if (accountId == null || accountType == null || storageBlobId == null) {
            return R.fail("参数不完整");
        }
 
        StorageAttachment storageAttachment = new StorageAttachment();
        storageAttachment.setRecordType(accountType);
        storageAttachment.setRecordId(accountId);
        storageAttachment.setStorageBlobId(storageBlobId);
        storageAttachment.setDeleted(0L);
        storageAttachmentMapper.insert(storageAttachment);
 
        return R.ok();
    }
 
    @DeleteMapping("/del")
    @Operation(summary = "删除附件")
    public R del(@RequestBody List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return R.fail("参数不能为空");
        }
        fileUtil.deleteStorageAttachmentsByStorageAttachmentIds(ids);
        return R.ok();
    }
}