README.md
@@ -138,15 +138,16 @@ ### 服务拓扑 | 服务 | 端口 | 职责 | |---|---|---| | `jnpf-gateway` | 30000 | API 网关,路由转发。基于 WebFlux,与 servlet 栈不能同进程,必须独立部署 | | **`jnpf-platform`** | **30002** | **平台聚合服务**:下列九个平台模块合并在一个 JVM 内 | | `jnpf-scheduletask` | 30009 | 定时任务(xxl-job admin),未并入 platform | | `jnpf-eln` | 30013 | ELN 电子实验记录(当前为骨架) | | `jnpf-biz-common` | 30015 | 公共业务能力聚合:OnlyOffice、审计等 | | `jnpf-dms` | 30016 | 文档管理 | | **`jnpf-lims`** | **30019** | **LIMS 实验室信息管理,主要业务模块** | | 服务 | 端口 | 职责 | |---|---|------------------------------------------------------| | `jnpf-gateway` | 30000 | API 网关,路由转发。基于 WebFlux,与 servlet 栈不能同进程,必须独立部署 | | **`jnpf-platform`** | **30002** | **平台聚合服务**:下列九个平台模块合并在一个 JVM 内 | | `jnpf-scheduletask` | 30009 | 定时任务(xxl-job admin),未并入 platform | | `jnpf-eln` | 30013 | ELN 电子实验记录(当前为骨架) | | `jnpf-biz-common` | 30015 | 公共业务能力聚合:OnlyOffice、审计等 | | `jnpf-dms` | 30016 | 文档管理 | | `jnpf-tms` | 30017 | TMS 考试培训管理 | | **`jnpf-lims`** | **30019** | **LIMS 实验室信息管理,主要业务模块** | | `jnpf-flow-engine` | 31000 | Flowable 7.0.1 流程引擎。**独立工程,不在根 pom**,用独立数据库 `jnpf_flow` | `jnpf-platform` 内含的九个模块: @@ -175,6 +176,7 @@ |---|---| | `/api/lims/`、`/api/extend/`(旧前缀,同指) | jnpf-lims | | `/api/dms/` | jnpf-dms | | `/api/tms/` | jnpf-tms | | `/api/eln/` | jnpf-eln | | `/api/biz/` | jnpf-biz-common(如 `/api/biz/onlyoffice/xxx`) | | `/api/audit/` | jnpf-biz-common(别名保留) | @@ -184,7 +186,7 @@ ### 业务模块分层 以 `jnpf-lims` 为例,其他业务模块(dms/eln)结构相同: 以 `jnpf-lims` 为例,其他业务模块(dms/eln/tms)结构相同: ``` jnpf-lims/ config/host-override/discovery.yaml
@@ -48,5 +48,7 @@ - uri: http://127.0.0.1:30015 jnpf-dms: - uri: http://127.0.0.1:30016 jnpf-tms: - uri: http://127.0.0.1:30017 jnpf-lims: - uri: http://127.0.0.1:30019 config/shared/discovery.yaml
@@ -53,5 +53,7 @@ - uri: http://cx-biz-common:30015 jnpf-dms: - uri: http://cx-dms:30016 jnpf-tms: - uri: http://cx-tms:30017 jnpf-lims: - uri: http://cx-lims:30019 config/shared/logger.yaml
@@ -12,6 +12,7 @@ # 新增服务时如果它在 log.level 里没有 INFO 条目,就往这里补一行。 jnpf.JnpfGatewayApplication: INFO jnpf.JnpfLimsApplication: INFO jnpf.JnpfTmsApplication: INFO # 解除注释后Druid连接池打印SQL语句 druid.sql.Statement: debug # druid.sql.DataSource: debug config/shared/router.yaml
@@ -63,6 +63,13 @@ - Path=/api/dms/** filters: - StripPrefix=2 # TMS 业务服务 - id: jnpf-tms uri: lb://jnpf-tms predicates: - Path=/api/tms/** filters: - StripPrefix=2 # 报表服务 - id: jnpf-datareport uri: lb://jnpf-datareport docker-compose.override.yml
@@ -125,6 +125,10 @@ <<: *no-local-data-plane ports: ["127.0.0.1:30016:30016"] volumes: *config-shared-volume cx-tms: <<: *no-local-data-plane ports: ["127.0.0.1:30017:30017"] volumes: *config-shared-volume # cx-visualdata 随平台聚合停用,保留以便回滚 # cx-visualdata: # <<: *no-local-data-plane docker-compose.testenv.yml
@@ -70,4 +70,5 @@ cx-eln: *no-local-pg cx-biz-common: *no-local-pg cx-dms: *no-local-pg cx-tms: *no-local-pg cx-scheduletask: *no-local-pg docker-compose.yml
@@ -554,6 +554,15 @@ <<: *hc-30000 test: ["CMD-SHELL", "exec 3<>/dev/tcp/127.0.0.1/30016"] cx-tms: <<: *cx container_name: cx-tms image: cx/tms:${CX_VERSION:-1.0.0} build: { context: ., dockerfile: dockerfile/tms/Dockerfile, args: { BASE_IMAGE: "${BASE_IMAGE:-bellsoft/liberica-openjre-rocky:21}" } } healthcheck: <<: *hc-30000 test: ["CMD-SHELL", "exec 3<>/dev/tcp/127.0.0.1/30017"] # ── cx-visualdata 已并入 cx-platform(2026-08-11),整段注释保留以便回滚 ── # cx-visualdata: # <<: *cx docker/delivery/assemble-offline-package.sh
@@ -69,6 +69,7 @@ jnpf-biz-common/jnpf-biz-common-server/target jnpf-lims/jnpf-lims-server/target jnpf-dms/jnpf-dms-server/target jnpf-tms/jnpf-tms-server/target ) for d in "${BIZ_JARS[@]}"; do ls "$d"/*.jar >/dev/null 2>&1 || die "缺业务 jar:${d}/*.jar —— 先 make jars" dockerfile/tms/Dockerfile
New file @@ -0,0 +1,19 @@ # 基础镜像:本地默认 Docker Hub 多架构(arm64 原生,L024);交付构建注入 SWR amd64 单架构 ARG BASE_IMAGE=bellsoft/liberica-openjre-rocky:21 FROM ${BASE_IMAGE} LABEL maintainer=cx-team # 设置时区 ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone WORKDIR /data/jnpfsoft/javaApi/jnpf-tms COPY jnpf-tms/jnpf-tms-server/target/*.jar ./jnpf-tms.jar COPY config/shared /config/shared ENV JNPF_CONFIG_DIR=/config EXPOSE 30017 ENTRYPOINT ["/bin/sh","-c","java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.math=ALL-UNNAMED --add-opens=java.base/sun.net.util=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/java.security=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/jdk.internal.module=ALL-UNNAMED --add-opens=java.base/sun.security.util=ALL-UNNAMED -Dfile.encoding=utf8 -Djava.security.egd=file:/dev/./urandom -jar jnpf-tms.jar"] jnpf-tms/jnpf-tms-api/pom.xml
New file @@ -0,0 +1,25 @@ <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>jnpf-tms</artifactId> <groupId>com.jnpf</groupId> <version>6.1.0-RELEASE</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>jnpf-tms-api</artifactId> <dependencies> <dependency> <groupId>com.jnpf</groupId> <artifactId>jnpf-common-feign</artifactId> </dependency> <dependency> <groupId>com.jnpf</groupId> <artifactId>jnpf-tms-entity</artifactId> <version>${project.version}</version> <scope>compile</scope> </dependency> </dependencies> </project> jnpf-tms/jnpf-tms-api/src/main/java/jnpf/utils/TmsFeignName.java
New file @@ -0,0 +1,11 @@ package jnpf.utils; /** * TMS 服务 Feign 名称常量,供其它服务引用。 */ public class TmsFeignName { public static final String TMS_SERVER_NAME = "jnpf-tms"; private TmsFeignName() { } } jnpf-tms/jnpf-tms-biz/pom.xml
New file @@ -0,0 +1,36 @@ <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>jnpf-tms</artifactId> <groupId>com.jnpf</groupId> <version>6.1.0-RELEASE</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>jnpf-tms-biz</artifactId> <dependencies> <dependency> <groupId>com.jnpf</groupId> <artifactId>jnpf-cloud-base</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>com.jnpf</groupId> <artifactId>jnpf-common-database</artifactId> </dependency> <dependency> <groupId>com.jnpf</groupId> <artifactId>jnpf-tms-entity</artifactId> <version>${project.version}</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.jnpf</groupId> <artifactId>jnpf-tms-api</artifactId> <version>${project.version}</version> <scope>compile</scope> </dependency> </dependencies> </project> jnpf-tms/jnpf-tms-biz/src/main/java/jnpf/tmsMapper/package-info.java
New file @@ -0,0 +1,4 @@ /** * TMS MyBatis Mapper 包(由 {@code @MapperScan("jnpf.tmsMapper")} 扫描)。 */ package jnpf.tmsMapper; jnpf-tms/jnpf-tms-biz/src/main/java/jnpf/tmsService/package-info.java
New file @@ -0,0 +1,4 @@ /** * TMS 业务服务包。 */ package jnpf.tmsService; jnpf-tms/jnpf-tms-controller/pom.xml
New file @@ -0,0 +1,26 @@ <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>jnpf-tms</artifactId> <groupId>com.jnpf</groupId> <version>6.1.0-RELEASE</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>jnpf-tms-controller</artifactId> <dependencies> <dependency> <groupId>com.jnpf</groupId> <artifactId>jnpf-common-springaop</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>com.jnpf</groupId> <artifactId>jnpf-tms-biz</artifactId> <version>${project.version}</version> <scope>compile</scope> </dependency> </dependencies> </project> jnpf-tms/jnpf-tms-controller/src/main/java/jnpf/tmsController/PingController.java
New file @@ -0,0 +1,18 @@ package jnpf.tmsController; import jnpf.base.ActionResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * 链路验收探针:网关 /api/tms/ping(StripPrefix=2)→ 本服务 /ping。 * 放行配置见 application.yml(sa-token / 租户 / 内部鉴权三处)。 */ @RestController public class PingController { @GetMapping("/ping") public ActionResult<String> ping() { return ActionResult.success("pong"); } } jnpf-tms/jnpf-tms-entity/pom.xml
New file @@ -0,0 +1,19 @@ <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>jnpf-tms</artifactId> <groupId>com.jnpf</groupId> <version>6.1.0-RELEASE</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>jnpf-tms-entity</artifactId> <dependencies> <dependency> <groupId>com.jnpf</groupId> <artifactId>jnpf-common-core</artifactId> </dependency> </dependencies> </project> jnpf-tms/jnpf-tms-entity/src/main/java/jnpf/tmsEntity/package-info.java
New file @@ -0,0 +1,4 @@ /** * TMS 实体 / DTO / VO 包。 */ package jnpf.tmsEntity; jnpf-tms/jnpf-tms-server/pom.xml
New file @@ -0,0 +1,97 @@ <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>jnpf-tms</artifactId> <groupId>com.jnpf</groupId> <version>6.1.0-RELEASE</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>jnpf-tms-server</artifactId> <dependencies> <dependency> <groupId>com.jnpf</groupId> <artifactId>jnpf-tms-controller</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <profiles> <profile> <id>default-package</id> <activation> <jdk>[,]</jdk> </activation> <build> <finalName>jnpf-tms-${project.version}</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>jnpf.JnpfTmsApplication</mainClass> <layout>ZIP</layout> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </profile> <profile> <id>external-package</id> <build> <finalName>jnpf-tms-${project.version}</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${external-lib-out-path}</outputDirectory> <overWriteReleases>true</overWriteReleases> <overWriteSnapshots>true</overWriteSnapshots> <overWriteIfNewer>true</overWriteIfNewer> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>jnpf.JnpfTmsApplication</mainClass> <addClasspath>true</addClasspath> <classpathPrefix>${external-lib-start-path}</classpathPrefix> </manifest> <manifestEntries> <Class-Path>.</Class-Path> </manifestEntries> </archive> </configuration> </plugin> </plugins> </build> </profile> </profiles> </project> jnpf-tms/jnpf-tms-server/src/main/java/jnpf/JnpfTmsApplication.java
New file @@ -0,0 +1,18 @@ package jnpf; import lombok.extern.slf4j.Slf4j; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; @Slf4j @SpringBootApplication @EnableFeignClients @MapperScan(value = "jnpf.tmsMapper") public class JnpfTmsApplication { public static void main(String[] args) { SpringApplication.run(JnpfTmsApplication.class, args); JnpfTmsApplication.log.info("TMS启动成功"); } } jnpf-tms/jnpf-tms-server/src/main/resources/application.yml
New file @@ -0,0 +1,58 @@ spring: application: name: jnpf-tms mvc: servlet: load-on-startup: 0 main: allow-bean-definition-overriding: true allow-circular-references: true config: # 配置来源 = 仓库 config/(镜像内 /config,经 JNPF_CONFIG_DIR 指向)。 import: - file:${JNPF_CONFIG_DIR:config}/shared/datasource.yaml - file:${JNPF_CONFIG_DIR:config}/shared/resources.yaml - file:${JNPF_CONFIG_DIR:config}/shared/system-config.yaml - file:${JNPF_CONFIG_DIR:config}/shared/frame-config.yaml - file:${JNPF_CONFIG_DIR:config}/shared/logger.yaml - file:${JNPF_CONFIG_DIR:config}/shared/mq.yaml - file:${JNPF_CONFIG_DIR:config}/shared/discovery.yaml - optional:file:${JNPF_CONFIG_DIR:config}/host-override/discovery.yaml # 应用服务器 server: tomcat: uri-encoding: UTF-8 port: 30017 management: endpoints: web: exposure: include: '*' endpoint: health: show-details: always logfile: access: unrestricted # ping 探针放行 jnpf: security: ignore: urls: - /ping - /api/tms/ping - /dev-api/tms/ping tenant: ignore-urls: - /ping - /api/tms/ping - /dev-api/tms/ping sa-token: filter: exclude-paths: - /ping - /api/tms/ping - /dev-api/tms/ping jnpf-tms/jnpf-tms-server/src/main/resources/logback-spring.xml
New file @@ -0,0 +1,300 @@ <?xml version="1.0" encoding="UTF-8"?> <configuration> <!--日志格式应用spring boot默认的格式,也可以自己更改--> <include resource="org/springframework/boot/logging/logback/defaults.xml"/> <property name="FILE_LOG_PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] [%thread] [%logger{50}] [%M] [%line] - %msg%n" /> <springProperty scope="context" name="SERVICE_NAME" source="spring.application.name" defaultValue="jnpf"/> <!--定义日志存放的位置,默认存放在项目启动的相对路径的目录--> <springProperty scope="context" name="LOG_PATH" source="log.path" defaultValue="log/${SERVICE_NAME}"/> <!-- 全局日志等级 --> <springProperty scope="context" name="LOG_LEVEL_ROOT" source="log.level.root" defaultValue="INFO"/> <!-- 服务自定义等级 如需自定义服务日志等级 修改下方的【自定义服务名】与nacos上的log.level.自定义服务名=等级 --> <springProperty scope="context" name="LOG_LEVEL" source="log.level.jnpf-tms" defaultValue="${LOG_LEVEL_ROOT}"/> <!-- 日志记录器,日期滚动记录,level为 ERROR 日志 --> <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文件的路径及文件名 --> <file>${LOG_PATH}/log_error.log</file> <!-- 日志记录器的滚动策略,按日期,按大小记录 --> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 --> <fileNamePattern>${LOG_PATH}/error/%d{yyyy-MM-dd,aux}/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!--日志最大的历史7天--> <maxHistory>7</maxHistory> <!-- 除按日志记录之外,还配置了日志文件不能超过2M,若超过2M,日志文件会以索引0开始, 命名日志文件,例如log-error-2013-12-21.0.log --> <maxFileSize>10MB</maxFileSize> </rollingPolicy> <!-- 追加方式记录日志 --> <append>true</append> <!-- 日志文件的格式 --> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>${FILE_LOG_PATTERN}</pattern> <charset>utf-8</charset> </encoder> <!-- 此日志文件只记录error级别的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>error</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- 日志记录器,日期滚动记录,level为 INFO 日志 --> <appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文件的路径及文件名 --> <file>${LOG_PATH}/log_info.log</file> <!-- 日志记录器的滚动策略,按日期,按大小记录 --> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 --> <fileNamePattern>${LOG_PATH}/info/%d{yyyy-MM-dd,aux}/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!--日志最大的历史7天--> <maxHistory>7</maxHistory> <!-- 除按日志记录之外,还配置了日志文件不能超过2M,若超过2M,日志文件会以索引0开始, 命名日志文件,例如log-error-2013-12-21.0.log --> <maxFileSize>10MB</maxFileSize> </rollingPolicy> <!-- 追加方式记录日志 --> <append>true</append> <!-- 日志文件的格式 --> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>${FILE_LOG_PATTERN}</pattern> <charset>utf-8</charset> </encoder> <!-- 此日志文件只记录info级别的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>info</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- 日志记录器,日期滚动记录,level为 WARN 日志 --> <appender name="FILE_WARN" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文件的路径及文件名 --> <file>${LOG_PATH}/log_warn.log</file> <!-- 日志记录器的滚动策略,按日期,按大小记录 --> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 --> <fileNamePattern>${LOG_PATH}/warn/%d{yyyy-MM-dd,aux}/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!--日志最大的历史7天--> <maxHistory>7</maxHistory> <!-- 除按日志记录之外,还配置了日志文件不能超过2M,若超过2M,日志文件会以索引0开始, 命名日志文件,例如log-error-2013-12-21.0.log --> <maxFileSize>10MB</maxFileSize> </rollingPolicy> <!-- 追加方式记录日志 --> <append>true</append> <!-- 日志文件的格式 --> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>${FILE_LOG_PATTERN}</pattern> <charset>utf-8</charset> </encoder> <!-- 此日志文件只记录warn级别的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>warn</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- 日志记录器,日期滚动记录,level为 DEBUG 日志 --> <appender name="FILE_DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文件的路径及文件名 --> <file>${LOG_PATH}/log_debug.log</file> <!-- 日志记录器的滚动策略,按日期,按大小记录 --> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 --> <fileNamePattern>${LOG_PATH}/debug/%d{yyyy-MM-dd,aux}/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!--日志最大的历史7天--> <maxHistory>7</maxHistory> <!-- 除按日志记录之外,还配置了日志文件不能超过2M,若超过2M,日志文件会以索引0开始, 命名日志文件,例如log-error-2013-12-21.0.log --> <maxFileSize>10MB</maxFileSize> </rollingPolicy> <!-- 追加方式记录日志 --> <append>true</append> <!-- 日志文件的格式 --> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>${FILE_LOG_PATTERN}</pattern> <charset>utf-8</charset> </encoder> <!-- 此日志文件只记录debug级别的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>debug</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- 日志记录器,日期滚动记录,所有日志 --> <appender name="FILE_ALL" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文件的路径及文件名 --> <file>${LOG_PATH}/log_total.log</file> <!-- 日志记录器的滚动策略,按日期,按大小记录 --> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 --> <fileNamePattern>${LOG_PATH}/total/%d{yyyy-MM-dd,aux}/log-total-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!--日志最大的历史7天--> <maxHistory>7</maxHistory> <!-- 除按日志记录之外,还配置了日志文件不能超过2M,若超过2M,日志文件会以索引0开始, 命名日志文件,例如log-error-2013-12-21.0.log --> <maxFileSize>10MB</maxFileSize> </rollingPolicy> <!-- 追加方式记录日志 --> <append>true</append> <!-- 日志文件的格式 --> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>${FILE_LOG_PATTERN}</pattern> <charset>utf-8</charset> </encoder> </appender> <!-- 异步输出 DEBUG --> <appender name="ASYNC_FILE_DEBUG" class="ch.qos.logback.classic.AsyncAppender"> <discardingThreshold>0</discardingThreshold> <queueSize>256</queueSize> <appender-ref ref="FILE_DEBUG"/> </appender> <!-- 异步输出 INFO --> <appender name="ASYNC_FILE_INFO" class="ch.qos.logback.classic.AsyncAppender"> <discardingThreshold>0</discardingThreshold> <queueSize>256</queueSize> <appender-ref ref="FILE_INFO"/> </appender> <!-- 异步输出 WARN --> <appender name="ASYNC_FILE_WARN" class="ch.qos.logback.classic.AsyncAppender"> <discardingThreshold>0</discardingThreshold> <queueSize>256</queueSize> <appender-ref ref="FILE_WARN"/> </appender> <!-- 异步输出 ERROR --> <appender name="ASYNC_FILE_ERROR" class="ch.qos.logback.classic.AsyncAppender"> <discardingThreshold>0</discardingThreshold> <queueSize>256</queueSize> <appender-ref ref="FILE_ERROR"/> </appender> <!-- 异步输出 ALL --> <appender name="ASYNC_FILE_ALL" class="ch.qos.logback.classic.AsyncAppender"> <discardingThreshold>0</discardingThreshold> <queueSize>256</queueSize> <appender-ref ref="FILE_ALL"/> </appender> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>${CONSOLE_LOG_PATTERN}</pattern> <charset>utf-8</charset> </encoder> </appender> <!-- 异步输出 控制台 --> <appender name="ASYNC_STDOUT" class="ch.qos.logback.classic.AsyncAppender"> <discardingThreshold>0</discardingThreshold> <queueSize>256</queueSize> <appender-ref ref="STDOUT"/> </appender> <!--<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender"> <!– 必填:目标:LogStash的 IP:Port –> <destination>192.168.0.50:50000</destination> <!– 可选:保持程序存活时间 –> <keepAliveDuration>5 minutes</keepAliveDuration> <!– 可选:重连延迟时长 –> <reconnectionDelay>10 second</reconnectionDelay> <!– 可选:等待策略 –> <waitStrategyType>sleeping</waitStrategyType> <!– ============ encoder必须配置,有多种可选 ============= –> <!– 编码器二:LoggingEventCompositeJsonEncoder –> <encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder"> <providers> <!– 时间戳:时区 –> <timestamp> <timeZone>UTC</timeZone> </timestamp> <!– 模式 –> <pattern> <pattern> { "severity": "%level", "service": "${SERVICE_NAME:-}", "trace": "%X{X-B3-TraceId:-}", "span": "%X{X-B3-SpanId:-}", "exportable": "%X{X-Span-Export:-}", "pid": "${PID:-}", "thread": "%thread", "class": "%logger{40}", "msg": "%message" <!–"idx_pre": "elk-original-third-access",–> <!–"json": "#asJson{%message}" 这个asJson可以把对应的字符串作为json对象取出来,这样es可以对json里面的字段索引了–> } </pattern> </pattern> </providers> </encoder> </appender>--> <!--<appender name="skywalking-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender"> <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout"> <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern> </layout> </encoder> </appender>--> <root level="${LOG_LEVEL}"> <appender-ref ref="ASYNC_STDOUT"/> <appender-ref ref="ASYNC_FILE_ERROR"/> <appender-ref ref="ASYNC_FILE_INFO"/> <appender-ref ref="ASYNC_FILE_WARN"/> <appender-ref ref="ASYNC_FILE_DEBUG"/> <appender-ref ref="ASYNC_FILE_ALL"/> <!--<appender-ref ref="LOGSTASH"/>--> <!--<appender-ref ref="skywalking-log"/>--> </root> </configuration> jnpf-tms/pom.xml
New file @@ -0,0 +1,21 @@ <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>jnpf-java-cloud</artifactId> <groupId>com.jnpf</groupId> <version>6.1.0-RELEASE</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>jnpf-tms</artifactId> <packaging>pom</packaging> <modules> <module>jnpf-tms-api</module> <module>jnpf-tms-entity</module> <module>jnpf-tms-biz</module> <module>jnpf-tms-controller</module> <module>jnpf-tms-server</module> </modules> </project> pom.xml
@@ -27,6 +27,7 @@ <module>jnpf-lims</module> <module>jnpf-dms</module> <module>jnpf-eln</module> <module>jnpf-tms</module> <!-- jnpf-audit 已于 2026-08-11 整体搬入 jnpf-biz-common(6 模块压到 3 个, jnpf-audit-server / cx-audit 退役),不再是顶层模块 --> <module>jnpf-biz-common</module> start-all.ps1
@@ -57,6 +57,7 @@ [PSCustomObject]@{ Name = 'jnpf-eln'; Jar = "jnpf-eln/jnpf-eln-server/target/jnpf-eln-$($Script:Version).jar"; Port = 30013 } [PSCustomObject]@{ Name = 'jnpf-lims'; Jar = "jnpf-lims/jnpf-lims-server/target/jnpf-lims-$($Script:Version).jar"; Port = 30019 } [PSCustomObject]@{ Name = 'jnpf-dms'; Jar = "jnpf-dms/jnpf-dms-server/target/jnpf-dms-$($Script:Version).jar"; Port = 30016 } [PSCustomObject]@{ Name = 'jnpf-tms'; Jar = "jnpf-tms/jnpf-tms-server/target/jnpf-tms-$($Script:Version).jar"; Port = 30017 } ) $Script:TargetServices = @() @@ -778,7 +779,7 @@ switch ($Name) { 'jnpf-platform' { return 1 } 'jnpf-biz-common' { return 2 } { $_ -in 'jnpf-lims', 'jnpf-dms' } { return 3 } { $_ -in 'jnpf-lims', 'jnpf-dms', 'jnpf-tms' } { return 3 } default { return 4 } } } @@ -883,7 +884,7 @@ --build, -b 启动前先编译项目 服务名(可选,省略 = 全部): jnpf-gateway jnpf-platform jnpf-biz-common jnpf-eln jnpf-lims jnpf-dms jnpf-gateway jnpf-platform jnpf-biz-common jnpf-eln jnpf-lims jnpf-dms jnpf-tms 注:jnpf-biz-common(30015) 含审计能力。 只起 jnpf-lims 而不起它,审计事件会投递失败并落 spool。 start-all.sh
@@ -153,6 +153,7 @@ "jnpf-eln jnpf-eln/jnpf-eln-server/target/jnpf-eln-${VERSION}.jar 30013" "jnpf-lims jnpf-lims/jnpf-lims-server/target/jnpf-lims-${VERSION}.jar 30019" "jnpf-dms jnpf-dms/jnpf-dms-server/target/jnpf-dms-${VERSION}.jar 30016" "jnpf-tms jnpf-tms/jnpf-tms-server/target/jnpf-tms-${VERSION}.jar 30017" ) # 补丁 #8:宿主栈直连坐标(覆盖 config/shared 里的 compose 默认值) @@ -497,7 +498,7 @@ --build, -b 启动前先编译项目 服务名(可选,省略 = 全部): jnpf-gateway jnpf-platform jnpf-biz-common jnpf-lims jnpf-dms jnpf-gateway jnpf-platform jnpf-biz-common jnpf-lims jnpf-dms jnpf-tms 注:jnpf-biz-common(30015) 含审计能力(2026-08-11 由原 jnpf-audit:30014 搬入)。 只起 jnpf-lims 而不起它,审计事件会投递失败并落 spool。 @@ -629,7 +630,7 @@ case "$1" in jnpf-platform) echo 1 ;; jnpf-biz-common) echo 2 ;; jnpf-lims|jnpf-dms) echo 3 ;; jnpf-lims|jnpf-dms|jnpf-tms) echo 3 ;; *) echo 4 ;; esac } stop-all.ps1
@@ -37,6 +37,7 @@ [PSCustomObject]@{ Name = 'jnpf-eln'; Jar = 'jnpf-eln-6.1.0-RELEASE.jar'; Port = 30013 } [PSCustomObject]@{ Name = 'jnpf-lims'; Jar = 'jnpf-lims-6.1.0-RELEASE.jar'; Port = 30019 } [PSCustomObject]@{ Name = 'jnpf-dms'; Jar = 'jnpf-dms-6.1.0-RELEASE.jar'; Port = 30016 } [PSCustomObject]@{ Name = 'jnpf-tms'; Jar = 'jnpf-tms-6.1.0-RELEASE.jar'; Port = 30017 } ) function Write-ColorLine { @@ -72,7 +73,7 @@ Write-Host '' Write-Host '省略服务名时停止全部服务;指定服务名时只停止对应服务:' Write-Host ' jnpf-gateway jnpf-platform jnpf-biz-common' Write-Host ' jnpf-eln jnpf-lims jnpf-dms' Write-Host ' jnpf-eln jnpf-lims jnpf-dms jnpf-tms' Write-Host '' Write-Host '示例:' Write-Host " .\$scriptName"