Skip to content

Commit 46f4a8c

Browse files
authored
feat: add download functionality for example operator and update Dock… (#188)
* feat: add download functionality for example operator and update Dockerfile * feat: enhance download response by exposing content disposition header * feat: update download function to accept filename parameter for example operator
1 parent 8fc4455 commit 46f4a8c

File tree

6 files changed

+64
-1
lines changed

6 files changed

+64
-1
lines changed

backend/services/operator-market-service/src/main/java/com/datamate/operator/application/OperatorService.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.datamate.common.domain.model.ChunkUploadPreRequest;
44
import com.datamate.common.domain.service.FileService;
55
import com.datamate.common.infrastructure.exception.BusinessException;
6+
import com.datamate.common.infrastructure.exception.SystemErrorCode;
67
import com.datamate.operator.domain.contants.OperatorConstant;
78
import com.datamate.operator.infrastructure.converter.OperatorConverter;
89
import com.datamate.operator.domain.model.OperatorView;
@@ -21,10 +22,13 @@
2122
import org.apache.commons.collections4.MapUtils;
2223
import org.apache.commons.lang3.StringUtils;
2324
import org.springframework.beans.factory.annotation.Value;
25+
import org.springframework.core.io.Resource;
26+
import org.springframework.core.io.UrlResource;
2427
import org.springframework.stereotype.Service;
2528
import org.springframework.transaction.annotation.Transactional;
2629

2730
import java.io.File;
31+
import java.net.MalformedURLException;
2832
import java.util.ArrayList;
2933
import java.util.List;
3034
import java.util.Map;
@@ -165,6 +169,20 @@ public void overrideSettings(OperatorDto operatorDto) {
165169
}
166170
}
167171

172+
public Resource downloadExampleOperator(File file) {
173+
try {
174+
Resource resource = new UrlResource(file.toURI());
175+
if (resource.exists()) {
176+
return resource;
177+
} else {
178+
throw BusinessException.of(SystemErrorCode.RESOURCE_NOT_FOUND);
179+
}
180+
} catch (MalformedURLException ex) {
181+
log.error("File not found: {}", file.getName(), ex);
182+
throw BusinessException.of(SystemErrorCode.RESOURCE_NOT_FOUND);
183+
}
184+
}
185+
168186
private String convertObjectToListString(Object object) {
169187
if (object == null) {
170188
return null;

backend/services/operator-market-service/src/main/java/com/datamate/operator/interfaces/rest/OperatorController.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.datamate.operator.interfaces.rest;
22

3+
import com.datamate.common.infrastructure.common.IgnoreResponseWrap;
34
import com.datamate.common.interfaces.PagedResponse;
45
import com.datamate.operator.application.OperatorService;
56
import com.datamate.operator.domain.contants.OperatorConstant;
@@ -8,9 +9,14 @@
89
import com.datamate.operator.interfaces.dto.UploadOperatorRequest;
910
import lombok.RequiredArgsConstructor;
1011
import org.apache.commons.collections4.CollectionUtils;
12+
import org.springframework.core.io.Resource;
13+
import org.springframework.http.HttpHeaders;
14+
import org.springframework.http.HttpStatus;
1115
import org.springframework.http.MediaType;
16+
import org.springframework.http.ResponseEntity;
1217
import org.springframework.web.bind.annotation.*;
1318

19+
import java.io.File;
1420
import java.util.List;
1521

1622
@RestController
@@ -70,4 +76,23 @@ public void chunkUpload(@ModelAttribute UploadOperatorRequest request) {
7076
public void operatorDelete(@PathVariable("id") String id) {
7177
operatorService.deleteOperator(id);
7278
}
79+
80+
@IgnoreResponseWrap
81+
@GetMapping(value = "/examples/download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE + ";charset=UTF-8")
82+
public ResponseEntity<Resource> downloadDatasetFileById() {
83+
try {
84+
File file = new File("/opt/backend/test_operator.tar");
85+
Resource resource = operatorService.downloadExampleOperator(file);
86+
return ResponseEntity.ok()
87+
.contentType(MediaType.APPLICATION_OCTET_STREAM)
88+
.header(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION)
89+
.header(HttpHeaders.CONTENT_DISPOSITION,
90+
"attachment; filename=\"" + file.getName() + "\"")
91+
.body(resource);
92+
} catch (IllegalArgumentException e) {
93+
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
94+
} catch (Exception e) {
95+
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
96+
}
97+
}
7398
}

frontend/src/pages/OperatorMarket/Home/OperatorMarket.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
EditOutlined,
66
FilterOutlined,
77
PlusOutlined,
8+
DownloadOutlined
89
} from "@ant-design/icons";
910
import { Boxes } from "lucide-react";
1011
import { SearchControls } from "@/components/SearchControls";
@@ -20,6 +21,7 @@ import { ListView } from "./components/List";
2021
import useFetchData from "@/hooks/useFetchData";
2122
import {
2223
deleteOperatorByIdUsingDelete,
24+
downloadExampleOperatorUsingGet,
2325
queryCategoryTreeUsingGet,
2426
queryOperatorsUsingPost,
2527
} from "../operator.api";
@@ -58,6 +60,11 @@ export default function OperatorMarketPage() {
5860
navigate(`/data/operator-market/create`);
5961
};
6062

63+
const handleDownload = async () => {
64+
await downloadExampleOperatorUsingGet("test_operator.tar");
65+
message.success("文件下载成功");
66+
};
67+
6168
const handleUpdateOperator = (operator: OperatorI) => {
6269
navigate(`/data/operator-market/create/${operator.id}`);
6370
};
@@ -119,7 +126,13 @@ export default function OperatorMarketPage() {
119126
<div className="flex justify-between">
120127
<h1 className="text-xl font-bold text-gray-900">算子市场</h1>
121128
<div className="flex gap-2">
122-
<TagManagement />
129+
{/*<TagManagement />*/}
130+
<Button
131+
icon={<DownloadOutlined />}
132+
onClick={handleDownload}
133+
>
134+
下载示例算子
135+
</Button>
123136
<Button
124137
type="primary"
125138
icon={<PlusOutlined />}

frontend/src/pages/OperatorMarket/operator.api.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ export function uploadOperatorChunkUsingPost(_, data: FormData, config?: any) {
4848
...config,
4949
});
5050
}
51+
52+
export function downloadExampleOperatorUsingGet(fileName: string) {
53+
return download("/api/operators/examples/download", null, fileName);
54+
}
55+
5156
// 发布算子
5257
export function publishOperatorUsingPost(operatorId: string | number) {
5358
return post(`/api/operators/${operatorId}/publish`);
6 KB
Binary file not shown.

scripts/images/backend/Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ COPY --from=datax-builder /DataX/target/datax/datax /opt/datax
3131

3232
COPY scripts/images/backend/start.sh /opt/backend/start.sh
3333

34+
COPY runtime/ops/examples/test_operator/test_operator.tar /opt/backend/test_operator.tar
35+
3436
RUN dos2unix /opt/backend/start.sh \
3537
&& chmod +x /opt/backend/start.sh \
3638
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

0 commit comments

Comments
 (0)