add old lci module

This commit is contained in:
qing committed 2026-08-02 20:15:07 +08:00
1 parent 38a6e815f0
commit 8499631091
171 files changed
+25562

No files matched your search

@@ -0,0 +1,2 @@
/mvnw text eol=lf
*.cmd text eol=crlf
+33
View File
@@ -0,0 +1,33 @@
HELP.md
target/
.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
+79
View File
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.cancerai</groupId>
<artifactId>pmc-backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>pmc-backend</name>
<description>pmc management backend</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.13.1</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,15 @@
package org.cancerai.pmc_backend;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
public class PmcBackendApplication {
public static void main(String[] args) {
SpringApplication.run(PmcBackendApplication.class, args);
}
}
@@ -0,0 +1,74 @@
package org.cancerai.pmc_backend.controller;
import jakarta.servlet.http.HttpServletResponse;
import org.cancerai.pmc_backend.entility.Note;
import org.cancerai.pmc_backend.utils.DNFSUtils;
import org.cancerai.pmc_backend.utils.HttpResponseText;
import org.cancerai.pmc_backend.vo.Result;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
@CrossOrigin(origins = "*")
@RestController
@RequestMapping("/api")
public class DNFSController {
@GetMapping("/get-notes")
public static Result getNotes(@RequestParam int pid) {
return Result.success(HttpResponseText.SUCCESS_TO_REQUEST, DNFSUtils.getNodes(pid));
}
@PutMapping("/add-note")
public Result addNote(
@RequestParam int pid,
@RequestParam String title,
@RequestParam String content,
HttpServletResponse response
) {
HashMap<String, String> re = DNFSUtils.addNote(pid, title, content);
String value = re.get("message");
if ("Note added successfully".equals(value)) {
return Result.success(HttpResponseText.SUCCESS_TO_ADD_NOTE);
} else {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return Result.error(HttpResponseText.INTERNAL_SERVER_ERROR);
}
}
@DeleteMapping("/delete-note")
public Result deleteNote(
@RequestParam int id,
HttpServletResponse response
) {
HashMap<String, String> re = DNFSUtils.deleteNote(id);
String value = re.get("message");
if ("Note deleted successfully".equals(value)) {
return Result.success(HttpResponseText.SUCCESS_TO_DELETE_NOTE);
} else {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return Result.error(HttpResponseText.INTERNAL_SERVER_ERROR);
}
}
@PatchMapping("/update-note")
public static Result updateNote(
@RequestBody Note note,
HttpServletResponse response
) {
int id = note.getId();
int pid = note.getPid();
String title = note.getTitle();
String content = note.getContent();
HashMap<String, String> re = DNFSUtils.updateNote(id, pid, title, content);
String value = re.get("message");
if ("Your change is up-to-date.".equals(value)) {
return Result.success(HttpResponseText.SUCCESS_TO_UPDATE_NOTE);
} else {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return Result.error(HttpResponseText.INTERNAL_SERVER_ERROR);
}
}
}
@@ -0,0 +1,29 @@
package org.cancerai.pmc_backend.controller;
import jakarta.servlet.http.HttpServletResponse;
import org.cancerai.pmc_backend.entility.User;
import org.cancerai.pmc_backend.service.LoginService;
import org.cancerai.pmc_backend.utils.EncryptUtils;
import org.cancerai.pmc_backend.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@CrossOrigin(origins = "*")
@RestController
@RequestMapping("/api")
public class LoginController {
@Autowired
private LoginService loginService;
@PostMapping("/login")
public Result login(
@RequestBody User user,
HttpServletResponse response
) {
String name = user.getName();
String password = EncryptUtils.SHA256Encrypt(user.getPassword());
return loginService.verifyUser(name, password, response);
}
}
@@ -0,0 +1,52 @@
package org.cancerai.pmc_backend.controller;
import org.cancerai.pmc_backend.entility.ProcessEntility;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import java.util.ArrayList;
@CrossOrigin(origins = "*")
@RestController()
public class ProcessController {
@GetMapping("/get-process")
public ArrayList<ProcessEntility> cleanProcess() {
ArrayList<String> arr = getProcessList();
ArrayList<ProcessEntility> result = new ArrayList<>();
final String DEAD = "Dead";
// exclude Dead lines
for (String i : arr) {
String[] item = i.split("\t");
String pid = item[0];
String status = item[1];
String cmd = item[2];
if (DEAD.equals(status)) {
continue;
}
result.add(new ProcessEntility(pid, status, cmd));
}
return result;
}
private static ArrayList<String> getProcessList() {
ArrayList<String> array = new ArrayList<>();
WebClient webClient = WebClient.create("http://127.0.0.1:8012");
String response = webClient.post()
.uri("/api/list")
.retrieve()
.bodyToMono(String.class)
.block();
String[] splitRes = response.split("\n");
for (String item : splitRes) {
array.add(item);
}
return array;
}
}
@@ -0,0 +1,57 @@
package org.cancerai.pmc_backend.entility;
public class Note {
private String content;
private int id;
private int pid;
private String title;
public Note(String content, int id, int pid, String title) {
this.content = content;
this.id = id;
this.pid = pid;
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Override
public String toString() {
return "Note{" +
"content='" + content + '\'' +
", id=" + id +
", pid=" + pid +
", title='" + title + '\'' +
'}';
}
}
@@ -0,0 +1,37 @@
package org.cancerai.pmc_backend.entility;
public class ProcessEntility {
private String pid;
private String status;
private String cmd;
public ProcessEntility(String pid, String status, String cmd) {
this.pid = pid;
this.status = status;
this.cmd = cmd;
}
public String getPid() {
return pid;
}
public void setPid(String pid) {
this.pid = pid;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
}
@@ -0,0 +1,22 @@
package org.cancerai.pmc_backend.entility;
public class User {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
@@ -0,0 +1,45 @@
package org.cancerai.pmc_backend.exception;
import org.cancerai.pmc_backend.vo.Result;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.resource.NoResourceFoundException;
@RestControllerAdvice
public class GlobalExceptionHandler {
// 400
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMessageNotReadableException.class)
public static Result JWTSignature(HttpMessageNotReadableException e) {
e.printStackTrace();
return Result.error("请求参数无效");
}
// 401
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public static Result requestMethodNotSupport(HttpRequestMethodNotSupportedException e) {
e.printStackTrace();
return Result.error("请求方法错误");
}
// 404
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(NoResourceFoundException.class)
public static Result ResourceNotFound(NoResourceFoundException e) {
e.printStackTrace();
return Result.error("未找到静态资源");
}
// 500
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Exception.class)
public static Result exception(Exception e) {
e.printStackTrace();
return Result.error("服务器内部错误");
}
}
@@ -0,0 +1,91 @@
package org.cancerai.pmc_backend.filter;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.cancerai.pmc_backend.utils.HttpResponseText;
import org.cancerai.pmc_backend.utils.JWTUtils;
import org.cancerai.pmc_backend.vo.Result;
import org.springframework.core.annotation.Order;
import java.io.IOException;
import java.io.PrintWriter;
@WebFilter(urlPatterns = "/api/*")
@Order(1)
public class LoginFilter implements Filter {
final String[] EXCLUDE_URL_LIST = {
"/api/login"
};
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// set content security policy
response.setHeader("Content-Security-Policy", "default-src *");
// exclude url
String uri = request.getRequestURI();
for (String item : EXCLUDE_URL_LIST) {
if (item.equals(uri)) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
}
// Allow OPTION method
if ("OPTIONS".equals(request.getMethod())) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
String token = request.getHeader("token");
if (token == null || token.isEmpty()) {
// set response header
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("application/json");
// construct body
Gson gson = new GsonBuilder().serializeNulls().create();
String responseBody = gson.toJson(Result.error(HttpResponseText.UNAUTHORIZED)).toString();
// set response body
PrintWriter writer = response.getWriter();
writer.write(responseBody);
writer.flush();
return;
}
try {
JWTUtils.parseJWT(token);
} catch (MalformedJwtException e) {
// set response body
Gson gson = new GsonBuilder().serializeNulls().create();
String body = gson.toJson(Result.error(HttpResponseText.JWT_MALFORMED));
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter writer = response.getWriter();
writer.write(body);
writer.flush();
return;
} catch (ExpiredJwtException e) {
// set response body
Gson gson = new GsonBuilder().serializeNulls().create();
String body = gson.toJson(Result.error(HttpResponseText.JWT_EXPIRED));
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter writer = response.getWriter();
writer.write(body);
writer.flush();
return;
}
// Allow
filterChain.doFilter(servletRequest, servletResponse);
response.setHeader("Content-Security-Policy", "default-src *");
}
}
@@ -0,0 +1,67 @@
package org.cancerai.pmc_backend.service;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import jakarta.servlet.http.HttpServletResponse;
import org.cancerai.pmc_backend.entility.Note;
import org.cancerai.pmc_backend.utils.DNFSUtils;
import org.cancerai.pmc_backend.utils.JWTUtils;
import org.cancerai.pmc_backend.vo.Result;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@Service
public class LoginService {
public static Result verifyUser(String name, String password, HttpServletResponse response) {
ArrayList<HashMap<String, String>> allUsersInfo = getAllUsersInfo();
boolean isExist = false;
for (HashMap<String, String> u : allUsersInfo) {
if (name.equals(u.get("name"))
&& password.equals(u.get("password"))
) {
isExist = true;
}
}
if (isExist) {
return Result.success(
"登陆成功",
JWTUtils.genJWT(name, password));
} else {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return Result.error("账号或密码错误");
}
}
private static ArrayList<HashMap<String, String>> getAllUsersInfo() {
Gson gson = new Gson();
// StringBuilder stringBuilder = new StringBuilder();
ArrayList<String> userList = new ArrayList<>();
ArrayList<Note> re = DNFSUtils.getNodes(0);
String jsonString = gson.toJson(re);
JsonArray jsonArray = gson.fromJson(jsonString, JsonArray.class);
for (JsonElement jsonElement : jsonArray) {
// To json
JsonObject jsonObject = jsonElement.getAsJsonObject();
// The value is \" + VALUE + \"
String titleString = jsonObject.get("title").toString();
String titleValue = titleString.substring(1, titleString.length() - 1);
if ("Users".equals(titleValue)) {
String contentString = jsonObject.get("content").toString();
String contentValue = contentString.substring(1, contentString.length() - 1);
String[] contentSplit = contentValue.split("\\\\n");
userList.addAll(Arrays.asList(contentSplit));
}
}
return DNFSUtils.parseUserInfo(userList);
}
}
@@ -0,0 +1,105 @@
package org.cancerai.pmc_backend.utils;
import org.cancerai.pmc_backend.entility.Note;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.HashMap;
public class DNFSUtils {
private final static String domain = "http://qsont.xyz:8006";
public static ArrayList<Note> getNodes(Integer pid) {
RestTemplate restTemplate = new RestTemplate();
// prepare request body
HashMap<String, Integer> requestBody = new HashMap<>();
requestBody.put("pid", pid);
// prepare request header
HttpHeaders requestHeader = new HttpHeaders();
requestHeader.setContentType(MediaType.APPLICATION_JSON);
ResponseEntity<ArrayList<Note>> response = restTemplate.exchange(
domain + "/get_notes",
HttpMethod.POST,
new HttpEntity<>(requestBody, requestHeader),
new ParameterizedTypeReference<ArrayList<Note>>() {
}
);
return response.getBody();
}
public static HashMap<String, String> addNote(int pid, String title, String content) {
RestTemplate restTemplate = new RestTemplate();
HashMap<String, String> body = new HashMap<>();
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.APPLICATION_JSON);
body.put("pid", String.valueOf(pid));
body.put("title", title);
body.put("content", content);
return restTemplate.exchange(
domain + "/add_note",
HttpMethod.POST,
new HttpEntity<>(body, header),
new ParameterizedTypeReference<HashMap<String, String>>() {
}
).getBody();
}
public static HashMap<String, String> deleteNote(int id) {
RestTemplate restTemplate = new RestTemplate();
HashMap<String, String> body = new HashMap<>();
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.APPLICATION_JSON);
body.put("id", String.valueOf(id));
return restTemplate.exchange(
domain + "/delete_note",
HttpMethod.POST,
new HttpEntity<>(body, header),
new ParameterizedTypeReference<HashMap<String, String>>() {
}
).getBody();
}
public static HashMap<String, String> updateNote(int id, int pid, String title, String content) {
RestTemplate restTemplate = new RestTemplate();
HashMap<String, String> body = new HashMap<>();
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.APPLICATION_JSON);
body.put("id", String.valueOf(id));
body.put("pid", String.valueOf(pid));
body.put("title", title);
body.put("content", content);
return restTemplate.exchange(
domain + "/update_note",
HttpMethod.POST,
new HttpEntity<>(body, header),
new ParameterizedTypeReference<HashMap<String, String>>() {
}
).getBody();
}
public static ArrayList<HashMap<String, String>> parseUserInfo(ArrayList<String> userLIst) {
ArrayList<HashMap<String, String>> array = new ArrayList<>();
for (String s : userLIst) {
HashMap<String, String> map = new HashMap<>();
String[] splitArray = s.split("::");
map.put("id", splitArray[0]);
map.put("name", splitArray[1]);
map.put("password", splitArray[2]);
map.put("role", splitArray[3]);
array.add(map);
}
return array;
}
}
@@ -0,0 +1,30 @@
package org.cancerai.pmc_backend.utils;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class EncryptUtils {
public static String SHA256Encrypt(String str) {
try {
// 获取SHA-256算法实例
MessageDigest digest = MessageDigest.getInstance("SHA-256");
// 计算哈希值(指定UTF-8编码避免平台差异)
byte[] hashBytes = digest.digest(str.getBytes(StandardCharsets.UTF_8));
// 将字节数组转换为十六进制字符串
StringBuilder hexString = new StringBuilder();
for (byte b : hashBytes) {
// 将每个字节转换为两位十六进制数,不足两位补0
String hex = String.format("%02x", 0xFF & b);
hexString.append(hex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
// SHA-256是Java标准算法,理论上不会抛出此异常
throw new RuntimeException("SHA-256算法不支持", e);
}
}
}
@@ -0,0 +1,14 @@
package org.cancerai.pmc_backend.utils;
public class HttpResponseText {
// success
public final static String SUCCESS_TO_REQUEST = "Request OK";
public final static String SUCCESS_TO_ADD_NOTE = "成功添加节点";
public final static String SUCCESS_TO_DELETE_NOTE = "成功删除节点";
public final static String SUCCESS_TO_UPDATE_NOTE = "成功更新节点";
// error
public final static String UNAUTHORIZED = "Cannot authorized identity, access denied";
public final static String JWT_MALFORMED = "JWT无效";
public final static String JWT_EXPIRED = "JWT过期";
public final static String INTERNAL_SERVER_ERROR = "服务器内部错误";
}
@@ -0,0 +1,42 @@
package org.cancerai.pmc_backend.utils;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Base64;
import java.util.Date;
public class JWTUtils {
final private static String key = "cancerai_key_qpalzm102938";
final private static String encodedKey = Base64.getEncoder()
.encodeToString(key.getBytes(StandardCharsets.UTF_8));
// set JWT kwy
final static Key jwtKey = Keys.hmacShaKeyFor(encodedKey.getBytes());
public static String genJWT(String name, String password) {
final Date expirationTime = new Date(
System.currentTimeMillis()
+ (60 * 1000 // 1min
* 60 // 1h
* 24 // 1day
* 2 // 2 days
));
return Jwts.builder()
.claim("userName", name)
.claim("user-password", password)
.signWith(jwtKey, SignatureAlgorithm.HS256)
.setExpiration(expirationTime)
.compact();
}
public static void parseJWT(String jwt) {
Jwts.parserBuilder()
.setSigningKey(jwtKey)
.build()
.parseClaimsJws(jwt);
}
}
@@ -0,0 +1,44 @@
package org.cancerai.pmc_backend.vo;
public class Result {
private String message;
private Object data;
private Result(String message, Object data) {
this.message = message;
this.data = data;
}
public static Result success(String message) {
return new Result(message, null);
}
public static Result success(String message, Object data) {
return new Result(message, data);
}
public static Result error(String message) {
return new Result(message, null);
}
public static Result error(String message, Object data) {
return new Result(message, data);
}
// getter and setter
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
@@ -0,0 +1,2 @@
server:
port: 8011
@@ -0,0 +1,21 @@
package org.cancerai.pmc_backend;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class PmcBackendApplicationTests {
@Test
void contextLoads() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append('a');
System.out.println(stringBuilder);
stringBuilder.setLength(0);
stringBuilder.append('b');
System.out.println(stringBuilder);
}
}