20 changed files with 341 additions and 28 deletions
-
2src/main/java/a8k/a8kproj/fakeproj/FAKE_PROJ_01_FLOW1.java
-
2src/main/java/a8k/a8kproj/fakeproj/FAKE_PROJ_02_FLOW2.java
-
2src/main/java/a8k/a8kproj/fakeproj/FAKE_PROJ_03.java
-
2src/main/java/a8k/a8kproj/fakeproj/FAKE_PROJ_04.java
-
2src/main/java/a8k/a8kproj/fakeproj/FAKE_PROJ_05.java
-
2src/main/java/a8k/a8kproj/fakeproj/FAKE_PROJ_06.java
-
2src/main/java/a8k/a8kproj/fakeproj/FAKE_PROJ_07_EXPIRED.java
-
2src/main/java/a8k/a8kproj/fakeproj/FakeProjInfo.java
-
97src/main/java/a8k/controler/filemgr/OptFileMgrController.java
-
8src/main/java/a8k/service/app/appctrl/AppConsumablesScanService.java
-
4src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ5_PROCESS.java
-
17src/main/java/a8k/service/dao/ProjectBaseInfoDao.java
-
4src/main/java/a8k/service/dao/type/a8kidcard/zenum/A8kReactionFlowType.java
-
2src/main/java/a8k/unittest/TestOptAnalyzer.java
-
4src/main/java/a8k/utils/ProjProcessContextUtils.java
-
31src/main/java/a8k/utils/ZCSVUtils.java
-
11src/main/java/a8k/utils/ZSqlite.java
-
24src/main/java/a8k/utils/ZSqliteJdbcHelper.java
-
32src/main/resources/a8k/db/zapp_a8k_project_info.csv
-
119src/main/resources/templates/optfilemgr/index.html
@ -0,0 +1,97 @@ |
|||||
|
package a8k.controler.filemgr; |
||||
|
|
||||
|
import a8k.service.app.appdata.FileMgrService; |
||||
|
import a8k.type.appret.ApiV1Ret; |
||||
|
import a8k.type.appret.AppRetV1; |
||||
|
import cn.hutool.core.net.URLDecoder; |
||||
|
import jakarta.annotation.PostConstruct; |
||||
|
import jakarta.annotation.Resource; |
||||
|
import jakarta.servlet.http.HttpServletRequest; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.core.io.FileSystemResource; |
||||
|
import org.springframework.http.ContentDisposition; |
||||
|
import org.springframework.http.HttpHeaders; |
||||
|
import org.springframework.http.ResponseEntity; |
||||
|
import org.springframework.stereotype.Controller; |
||||
|
import org.springframework.ui.Model; |
||||
|
import org.springframework.web.bind.annotation.*; |
||||
|
|
||||
|
import java.io.File; |
||||
|
import java.nio.charset.StandardCharsets; |
||||
|
import java.nio.file.Paths; |
||||
|
import java.util.List; |
||||
|
|
||||
|
@Controller |
||||
|
@Slf4j |
||||
|
@RequestMapping("/optfilemgr") |
||||
|
public class OptFileMgrController { |
||||
|
|
||||
|
|
||||
|
@Resource |
||||
|
FileMgrService fileMgrService; |
||||
|
|
||||
|
record FileGroup(String name, List<FileInfo> files) { |
||||
|
} |
||||
|
|
||||
|
record FileInfo(String filePath, String name) { |
||||
|
} |
||||
|
|
||||
|
|
||||
|
FileGroup buidOptFileGroup() { |
||||
|
List<FileInfo> files = fileMgrService.getOptReportList().stream() |
||||
|
.map(fileName -> new FileInfo(fileMgrService.getOptReportFilePath(fileName), fileName)) |
||||
|
.toList(); |
||||
|
return new FileGroup("光学报告", files); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@GetMapping("") |
||||
|
public String fileDownloadPage(Model model) { |
||||
|
// Mock data for file groups and files |
||||
|
List<FileGroup> fileGroups = List.of( |
||||
|
buidOptFileGroup() |
||||
|
); |
||||
|
model.addAttribute("fileGroups", fileGroups); |
||||
|
return "optfilemgr/index.html"; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@GetMapping("/download/**") |
||||
|
@ResponseBody |
||||
|
public ResponseEntity<org.springframework.core.io.Resource> download(HttpServletRequest request) { |
||||
|
String path = request.getRequestURI().substring("/optfilemgr/download/".length()); |
||||
|
//转义地址中空格,TODO:支持处理中文文件名 |
||||
|
// path = path.replaceAll("%20", " "); |
||||
|
path = URLDecoder.decode(path, StandardCharsets.UTF_8); |
||||
|
|
||||
|
|
||||
|
String fileName = Paths.get(path).getFileName().toString(); |
||||
|
log.info("Download file:{} path:{}", fileName, path); |
||||
|
|
||||
|
|
||||
|
File file = new File(path); |
||||
|
|
||||
|
String contentDisposition = ContentDisposition |
||||
|
.builder("attachment") |
||||
|
.filename(fileName, StandardCharsets.UTF_8) // Use the original filename |
||||
|
.build().toString(); |
||||
|
return ResponseEntity.ok() |
||||
|
.header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition) |
||||
|
.body(new FileSystemResource(file.getAbsolutePath())); |
||||
|
} |
||||
|
|
||||
|
// http://127.0.0.1/optfilemgr/download/runenv/files/optReport/Fake(%20xxxx)-FOPT-20241112172645.txt |
||||
|
|
||||
|
@GetMapping("/export/**") |
||||
|
@ResponseBody |
||||
|
public ResponseEntity<?> export(HttpServletRequest request) { |
||||
|
String path = request.getRequestURI().substring("/optfilemgr/export/".length()); |
||||
|
log.info("Export file: {}", path); |
||||
|
//返回AppRetV1.success("导出成功") |
||||
|
// %2Ffiles%2FoptReport%2FFake(%20xxxx)-FOPT-20241112172645.txt |
||||
|
return ResponseEntity.ok(AppRetV1.success("导出成功")); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
projId,projName,projShortName,subProjNum,reactionTemperature,color,reactionFlowType,wBloodSampleVolUl,serumSampleVolUl,shakeTimes,bigBufferSampleUl,reactionPlateIncubationTimeMin,reactionPlateDropletVolUl, |
||||
|
1,hsCRP,CA,1,25,#FFC0CB,SampleAndBS,10,10,3,0,3,75, |
||||
|
2,PCT,PC,1,25,#DC143C,SampleAndBS,150,150,3,0,12,75, |
||||
|
3,TSH,TS,1,25,#DB7093,SampleAndBSAndProbeSubstance,150,150,3,75,12,75, |
||||
|
4,PRL,PL,1,25,#FF69B4,SampleAndBS,75,75,3,0,10,75, |
||||
|
5,T3,T3,1,25,#FF1493,SampleAndBSAndProbeSubstance,75,75,3,75,8,75, |
||||
|
6,T4,T4,1,25,#C71585,SampleAndBSAndProbeSubstance,75,75,3,75,8,75, |
||||
|
7,Total β hCG,HC,1,25,#DA70D6,SampleAndBS,50,30,3,0,15,75, |
||||
|
8,LH,LH,1,25,#D8BFD8,SampleAndBS,150,150,3,0,15,75, |
||||
|
9,FSH,FS,1,25,#DDA0DD,SampleAndBS,150,150,3,0,15,75, |
||||
|
10,Progesterone,PG,1,25,#EE82EE,SampleAndBS,30,30,3,0,15,75, |
||||
|
12,Tn-I plus,TG,1,25,#FF00FF,SampleAndBSAndProbeSubstance,50,50,3,150,12,75, |
||||
|
13,NT-proBNP,NB,1,25,#8B008B,SampleAndBSAndProbeSubstance,10,10,3,150,12,75, |
||||
|
14,CK-MB,CK,1,25,#800080,SampleAndBS,75,75,3,0,12,75, |
||||
|
15,Myoglobin,MY,1,25,#BA55D3,SampleAndBS,10,10,3,0,12,75, |
||||
|
16,D-Dimer,DD,1,25,#9400D3,SampleAndBS,10,10,3,0,12,75, |
||||
|
17,HbAlC,HB,1,25,#9932CC,SampleAndBSAndProbeSubstance,5,5,3,100,12,75, |
||||
|
18,PCT plus,PP,1,25,#4B0082,SampleAndBSAndProbeSubstance,35,35,3,150,12,75, |
||||
|
20,Tn-I/CK-MB/Myoglobin,CT,3,25,#9370DB,SampleAndBSAndProbeSubstance,75,75,3,150,12,75, |
||||
|
22,PCT/hsCRP,PR,1,25,#6A5ACD,SampleAndBSAndProbeSubstance,35,35,3,150,12,75, |
||||
|
24,SAA,SA,1,25,#E6E6FA,SampleAndBS,10,10,3,0,3,75, |
||||
|
25,AMH,AM,1,25,#F8F8FF,SampleAndBSAndProbeSubstance,50,50,3,150,12,75, |
||||
|
26,SAA/CRP,SC,2,25,#0000FF,SampleAndBS,10,10,3,0,3,75, |
||||
|
27,Vitamin D,VD,1,25,#0000FF,SampleAndBSAndProbeSubstance,30,30,3,150,12,75, |
||||
|
33,ST2,ST,1,25,#6495ED,SampleAndBSAndProbeSubstance,75,75,3,150,12,75, |
||||
|
36,MxA,MX,1,25,#708090,SampleAndBSAndProbeSubstance,35,35,3,150,12,75, |
||||
|
48,IL-6,IL,1,25,#AFEEEE,SampleAndBSAndProbeSubstance,35,35,3,150,12,75, |
||||
|
49,Gastrin 17,GA,1,25,#00FFFF,SampleAndBSAndProbeSubstance,50,50,3,150,15,75, |
||||
|
50,Pepsinogen I/II,PS,2,25,#00FFFF,SampleAndBSAndProbeSubstance,10,10,3,150,10,75, |
||||
|
52,NT-proBNP/ST2,NS,2,25,#2F4F4F,SampleAndBSAndProbeSubstance,10,10,3,150,12,75, |
||||
|
54,Troponin T,TT,1,25,#008080,SampleAndBSAndProbeSubstance,35,35,3,150,12,75, |
||||
|
55,BNP,BP,1,25,#48D1CC,SampleAndBSAndProbeSubstance,35,35,3,150,12,75, |
@ -0,0 +1,119 @@ |
|||||
|
<!-- src/main/resources/templates/optfilemgr/index.html --> |
||||
|
<!DOCTYPE html> |
||||
|
<html lang="en"> |
||||
|
<head> |
||||
|
<meta charset="UTF-8"> |
||||
|
<title>光学报告管理</title> |
||||
|
<link href="/background/js/bootstrap.min.css" rel="stylesheet"> |
||||
|
<style> |
||||
|
body { |
||||
|
padding: 20px; |
||||
|
} |
||||
|
|
||||
|
h1 { |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
.download-title { |
||||
|
font-size: 2em; |
||||
|
color: #007bff; |
||||
|
text-align: left; |
||||
|
margin-bottom: 30px; |
||||
|
} |
||||
|
|
||||
|
table { |
||||
|
width: 100%; |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
th, td { |
||||
|
padding: 10px; |
||||
|
text-align: left; |
||||
|
} |
||||
|
|
||||
|
th { |
||||
|
background-color: #f8f9fa; |
||||
|
} |
||||
|
</style> |
||||
|
</head> |
||||
|
<body> |
||||
|
<div class="container"> |
||||
|
<h1 class="download-title">光学报告管理</h1> |
||||
|
<table class="table table-bordered"> |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th>文件名称</th> |
||||
|
<th>下载</th> |
||||
|
<th>导出</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody th:each="group : ${fileGroups}"> |
||||
|
<tr th:each="file : ${group.files}"> |
||||
|
<td th:text="${file.name}"></td> |
||||
|
<td> |
||||
|
<a th:href="@{'/optfilemgr/download/' + ${file.filePath}}" |
||||
|
class="btn btn-outline-primary download-link">下载</a> |
||||
|
</td> |
||||
|
<td> |
||||
|
<button class="btn btn-outline-secondary export-link" th:data-filepath="${file.filePath}">导出</button> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
|
||||
|
<!-- Notification Modal --> |
||||
|
<div class="modal fade" id="notificationModal" tabindex="-1" role="dialog" aria-labelledby="notificationModalLabel" |
||||
|
aria-hidden="true"> |
||||
|
<div class="modal-dialog" role="document"> |
||||
|
<div class="modal-content"> |
||||
|
<div class="modal-header"> |
||||
|
<h5 class="modal-title" id="notificationModalLabel">通知</h5> |
||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> |
||||
|
<span aria-hidden="true">×</span> |
||||
|
</button> |
||||
|
</div> |
||||
|
<div class="modal-body" id="notificationModalContent"> |
||||
|
|
||||
|
</div> |
||||
|
<div class="modal-footer"> |
||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<script src="/background/js/jquery-3.5.1.min.js"></script> |
||||
|
<script src="/background/js/bootstrap.min.js"></script> |
||||
|
<script> |
||||
|
document.addEventListener('DOMContentLoaded', function () { |
||||
|
var downloadLinks = document.querySelectorAll('.download-link'); |
||||
|
downloadLinks.forEach(function (link) { |
||||
|
link.addEventListener('click', function () { |
||||
|
$('#notificationModalContent').text('文件下载成功'); |
||||
|
$('#notificationModal').modal('show'); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
var exportLinks = document.querySelectorAll('.export-link'); |
||||
|
exportLinks.forEach(function (link) { |
||||
|
link.addEventListener('click', function () { |
||||
|
var filePath = link.getAttribute('data-filepath'); |
||||
|
fetch('/optfilemgr/export/' + filePath, { |
||||
|
method: 'GET' |
||||
|
}) |
||||
|
.then(response => response.json()) |
||||
|
.then(data => { |
||||
|
var formattedJson = JSON.stringify(data, null, 2); |
||||
|
$('#notificationModalContent').html('<pre>' + formattedJson + '</pre>'); |
||||
|
$('#notificationModal').modal('show'); |
||||
|
}) |
||||
|
.catch(error => { |
||||
|
console.error('Error:', error); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
</script> |
||||
|
</body> |
||||
|
</html> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue