feat(ai-web): 完成图片上传和显示
This commit is contained in:
@@ -11,7 +11,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "file-store")
|
||||
public class FileStoreConfiguration {
|
||||
public class FileStoreProperties {
|
||||
private String downloadPrefix;
|
||||
private String uploadPath;
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.lanyuanxiaoyao.service.ai.core.entity.amis.AmisResponse;
|
||||
import com.lanyuanxiaoyao.service.ai.web.configuration.FileStoreConfiguration;
|
||||
import com.lanyuanxiaoyao.service.ai.web.configuration.FileStoreProperties;
|
||||
import com.lanyuanxiaoyao.service.ai.web.entity.vo.DataFileVO;
|
||||
import com.lanyuanxiaoyao.service.ai.web.service.DataFileService;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
@@ -41,17 +41,17 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
@RestController
|
||||
@RequestMapping("/upload")
|
||||
public class DataFileController {
|
||||
private final FileStoreConfiguration fileStoreConfiguration;
|
||||
private final FileStoreProperties fileStoreProperties;
|
||||
private final DataFileService dataFileService;
|
||||
private final String uploadFolderPath;
|
||||
private final String cacheFolderPath;
|
||||
private final String sliceFolderPath;
|
||||
|
||||
public DataFileController(FileStoreConfiguration fileStoreConfiguration, DataFileService dataFileService) {
|
||||
this.fileStoreConfiguration = fileStoreConfiguration;
|
||||
public DataFileController(FileStoreProperties fileStoreProperties, DataFileService dataFileService) {
|
||||
this.fileStoreProperties = fileStoreProperties;
|
||||
this.dataFileService = dataFileService;
|
||||
|
||||
this.uploadFolderPath = fileStoreConfiguration.getUploadPath();
|
||||
this.uploadFolderPath = fileStoreProperties.getUploadPath();
|
||||
this.cacheFolderPath = StrUtil.format("{}/cache", uploadFolderPath);
|
||||
this.sliceFolderPath = StrUtil.format("{}/slice", uploadFolderPath);
|
||||
}
|
||||
@@ -60,7 +60,7 @@ public class DataFileController {
|
||||
public AmisResponse<FinishResponse> upload(@RequestParam("file") MultipartFile file) throws IOException {
|
||||
String filename = file.getOriginalFilename();
|
||||
Long id = dataFileService.initialDataFile(filename);
|
||||
String url = StrUtil.format("{}/upload/download/{}", fileStoreConfiguration.getDownloadPrefix(), id);
|
||||
String url = StrUtil.format("{}/upload/download/{}", fileStoreProperties.getDownloadPrefix(), id);
|
||||
byte[] bytes = file.getBytes();
|
||||
String originMd5 = SecureUtil.md5(new ByteArrayInputStream(bytes));
|
||||
File targetFile = new File(StrUtil.format("{}/{}", uploadFolderPath, originMd5));
|
||||
@@ -80,7 +80,7 @@ public class DataFileController {
|
||||
}
|
||||
|
||||
@GetMapping("/download/{id}")
|
||||
public void download(@PathVariable Long id, HttpServletResponse response) throws IOException {
|
||||
public void download(@PathVariable("id") Long id, HttpServletResponse response) throws IOException {
|
||||
DataFileVO dataFile = dataFileService.downloadFile(id);
|
||||
File targetFile = new File(dataFile.getPath());
|
||||
response.setHeader("Content-Type", dataFile.getType());
|
||||
@@ -157,7 +157,7 @@ public class DataFileController {
|
||||
request.uploadId,
|
||||
request.filename,
|
||||
request.uploadId.toString(),
|
||||
StrUtil.format("{}/upload/download/{}", fileStoreConfiguration.getDownloadPrefix(), request.uploadId)
|
||||
StrUtil.format("{}/upload/download/{}", fileStoreProperties.getDownloadPrefix(), request.uploadId)
|
||||
));
|
||||
} else {
|
||||
throw new RuntimeException("合并文件失败");
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
package com.lanyuanxiaoyao.service.ai.web.controller.feedback;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.lanyuanxiaoyao.service.ai.core.entity.amis.AmisCrudResponse;
|
||||
import com.lanyuanxiaoyao.service.ai.core.entity.amis.AmisResponse;
|
||||
import com.lanyuanxiaoyao.service.ai.web.configuration.FileStoreProperties;
|
||||
import com.lanyuanxiaoyao.service.ai.web.entity.Feedback;
|
||||
import com.lanyuanxiaoyao.service.ai.web.service.feedback.FeedbackService;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.collections.api.factory.Lists;
|
||||
import org.eclipse.collections.api.list.ImmutableList;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -16,27 +22,49 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@RestController
|
||||
@RequestMapping("feedback")
|
||||
public class FeedbackController {
|
||||
private final FileStoreProperties fileStoreProperties;
|
||||
private final FeedbackService feedbackService;
|
||||
|
||||
public FeedbackController(FeedbackService feedbackService) {
|
||||
public FeedbackController(FileStoreProperties fileStoreProperties, FeedbackService feedbackService) {
|
||||
this.fileStoreProperties = fileStoreProperties;
|
||||
this.feedbackService = feedbackService;
|
||||
}
|
||||
|
||||
@PostMapping("add")
|
||||
public void add(
|
||||
@RequestParam("source") String source,
|
||||
@RequestParam(value = "pictures", required = false) ImmutableList<Long> pictures
|
||||
) {
|
||||
feedbackService.add(source, ObjectUtil.defaultIfNull(pictures, Lists.immutable.empty()));
|
||||
public void add(@RequestBody CreateItem item) {
|
||||
log.info("Enter method: add[item]. item:{}", item);
|
||||
feedbackService.add(item.source, ObjectUtil.defaultIfNull(item.pictures, Lists.immutable.empty()));
|
||||
}
|
||||
|
||||
@GetMapping("list")
|
||||
public AmisResponse<?> list() {
|
||||
return AmisResponse.responseCrudData(feedbackService.list());
|
||||
public AmisCrudResponse list() {
|
||||
return AmisResponse.responseCrudData(feedbackService.list().collect(feedback -> new ListItem(fileStoreProperties, feedback)));
|
||||
}
|
||||
|
||||
@GetMapping("delete")
|
||||
public void delete(@RequestParam("id") Long id) {
|
||||
feedbackService.remove(id);
|
||||
}
|
||||
|
||||
@Data
|
||||
public static final class CreateItem {
|
||||
private String source;
|
||||
private ImmutableList<Long> pictures;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static final class ListItem {
|
||||
private Long id;
|
||||
private String source;
|
||||
private ImmutableList<String> pictures;
|
||||
private Feedback.Status status;
|
||||
|
||||
public ListItem(FileStoreProperties fileStoreProperties, Feedback feedback) {
|
||||
this.id = feedback.getId();
|
||||
this.source = feedback.getSource();
|
||||
this.pictures = feedback.getPictureIds()
|
||||
.collect(id -> StrUtil.format("{}/upload/download/{}", fileStoreProperties.getDownloadPrefix(), id));
|
||||
this.status = feedback.getStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,9 +51,7 @@ public class FeedbackService {
|
||||
.precompileSql(),
|
||||
SnowflakeId.next(),
|
||||
source,
|
||||
ObjectUtil.isEmpty(pictureIds)
|
||||
? null
|
||||
: pictureIds.makeString(",")
|
||||
ObjectUtil.isEmpty(pictureIds) ? null : pictureIds.makeString(",")
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ deploy:
|
||||
jdk: "jdk17"
|
||||
replicas: 1
|
||||
arguments:
|
||||
"[file-store.download-prefix]": 'http://132.126.207.130:35690/hudi_services/ai_knowledge'
|
||||
"[file-store.download-prefix]": 'http://132.126.207.130:35690/hudi_services/service_ai_web'
|
||||
"[file-store.upload-path]": ${deploy.runtime.data-path}/knowledge
|
||||
"[spring.datasource.url]": ${deploy.runtime.database.config.url}
|
||||
"[spring.datasource.username]": ${deploy.runtime.database.config.username}
|
||||
|
||||
@@ -1,9 +1,25 @@
|
||||
import React from 'react'
|
||||
import {amisRender, commonInfo, crudCommonOptions} from '../../../util/amis.tsx'
|
||||
import styled from 'styled-components'
|
||||
import {amisRender, commonInfo, crudCommonOptions, mappingField, mappingItem} from '../../../util/amis.tsx'
|
||||
|
||||
const FeedbackDiv = styled.div`
|
||||
.feedback-list-images {
|
||||
.antd-Img-container {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const statusMapping = [
|
||||
mappingItem('分析中', 'ANALYSIS_PROCESSING', 'label-warning'),
|
||||
mappingItem('分析完成', 'ANALYSIS_SUCCESS', 'label-primary'),
|
||||
mappingItem('处理完成', 'FINISHED', 'label-success'),
|
||||
]
|
||||
|
||||
const Feedback: React.FC = () => {
|
||||
return (
|
||||
<div className="feedback">
|
||||
<FeedbackDiv className="feedback">
|
||||
{amisRender(
|
||||
{
|
||||
type: 'page',
|
||||
@@ -28,10 +44,7 @@ const Feedback: React.FC = () => {
|
||||
body: {
|
||||
debug: commonInfo.debug,
|
||||
type: 'form',
|
||||
api: {
|
||||
url: `${commonInfo.baseAiUrl}/feedback/add`,
|
||||
dataType: 'form',
|
||||
},
|
||||
api: `${commonInfo.baseAiUrl}/feedback/add`,
|
||||
body: [
|
||||
{
|
||||
type: 'editor',
|
||||
@@ -50,12 +63,14 @@ const Feedback: React.FC = () => {
|
||||
label: '相关截图',
|
||||
autoUpload: false,
|
||||
multiple: true,
|
||||
joinValues: false,
|
||||
extractValue: true,
|
||||
// 5MB 5242880
|
||||
// 100MB 104857600
|
||||
// 500MB 524288000
|
||||
// 1GB 1073741824
|
||||
maxSize: 5242880,
|
||||
receiver: `${commonInfo.baseAiUrl}/upload`
|
||||
receiver: `${commonInfo.baseAiUrl}/upload`,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -66,11 +81,26 @@ const Feedback: React.FC = () => {
|
||||
{
|
||||
name: 'id',
|
||||
label: '编号',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
name: 'source',
|
||||
label: '故障描述',
|
||||
},
|
||||
{
|
||||
name: 'pictures',
|
||||
label: '相关截图',
|
||||
width: 200,
|
||||
className: 'feedback-list-images',
|
||||
type: 'images',
|
||||
enlargeAble: true,
|
||||
enlargeWithGallary: true,
|
||||
},
|
||||
{
|
||||
name: 'status',
|
||||
label: '状态',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
...mappingField('status', statusMapping),
|
||||
},
|
||||
{
|
||||
type: 'operation',
|
||||
@@ -101,7 +131,7 @@ const Feedback: React.FC = () => {
|
||||
],
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
</FeedbackDiv>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user