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