From 840a0b1b82cfab7de0e8d7cb94153b977551cb3b Mon Sep 17 00:00:00 2001 From: huangjin <huangjin@lucahealthcare.com> Date: Fri, 30 Aug 2024 10:06:56 +0800 Subject: [PATCH] uat --- .gitignore | 33 + .idea/misc.xml | 10 +- .idea/modules.xml | 8 - mvnw | 259 +++++++ pom.xml | 93 +++ .../java/com/luca/pilot/PilotApplication.java | 16 + .../pilot/bizEnum/CrfQuestionTypeEnum.java | 42 ++ .../com/luca/pilot/bizEnum/TableEnum.java | 54 ++ .../java/com/luca/pilot/bo/BindDataBo.java | 18 + .../com/luca/pilot/bo/CrfJsonValueBo.java | 21 + .../com/luca/pilot/bo/CrfJsonValueKeyBo.java | 22 + .../java/com/luca/pilot/bo/CrfProblemBo.java | 26 + .../luca/pilot/bo/CrfTableJsonTopicBo.java | 20 + .../config/MongoArchiveTemplateConfig.java | 37 + .../pilot/config/MongoBaseTemplateConfig.java | 39 ++ .../pilot/entity/AbstractAuditingEntity.java | 35 + .../com/luca/pilot/entity/BaseModuleView.java | 63 ++ .../pilot/entity/ClinicalTrialsEvent.java | 92 +++ .../com/luca/pilot/entity/CollectModule.java | 88 +++ src/main/java/com/luca/pilot/entity/Crf.java | 40 ++ .../java/com/luca/pilot/entity/CrfAnswer.java | 70 ++ .../pilot/entity/DigitalMedicalDetails.java | 78 +++ .../com/luca/pilot/entity/ModuleEntity.java | 51 ++ .../entity/PatientScaleEvaluatingEntity.java | 44 ++ src/main/java/com/luca/pilot/entity/Plan.java | 91 +++ .../com/luca/pilot/entity/PlanModule.java | 84 +++ .../java/com/luca/pilot/entity/PlanTask.java | 157 +++++ .../luca/pilot/entity/PlanTaskDetails.java | 100 +++ .../pilot/entity/PlanTaskDetailsModule.java | 62 ++ .../pilot/entity/PlanTaskModuleRelate.java | 51 ++ .../java/com/luca/pilot/entity/Project.java | 95 +++ .../com/luca/pilot/entity/Questionnaire.java | 43 ++ .../pilot/entity/QuestionnaireAnswer.java | 68 ++ .../entity/QuestionnaireAnswerOption.java | 55 ++ .../entity/QuestionnaireAnswerRecord.java | 56 ++ .../entity/ScaleModuleDetailsEntity.java | 33 + .../luca/pilot/entity/ScaleModuleEntity.java | 29 + src/main/java/com/luca/pilot/entity/Site.java | 89 +++ .../luca/pilot/entity/SynchronizeTime.java | 14 + .../com/luca/pilot/entity/UserArchive.java | 207 ++++++ .../luca/pilot/entity/UserArchiveMapping.java | 33 + .../pilot/service/BaseModuleViewService.java | 10 + .../com/luca/pilot/service/PlanService.java | 10 + .../impl/BaseModuleViewServiceImpl.java | 57 ++ .../pilot/service/impl/PlanServiceImpl.java | 643 ++++++++++++++++++ .../java/com/luca/pilot/util/CrfUtil.java | 228 +++++++ src/main/resources/application-dev.yml | 11 + src/main/resources/application-hj.yml | 15 + src/main/resources/application-uat.yml | 13 + src/main/resources/application.yml | 15 + .../com/luca/pilot/PilotApplicationTests.java | 13 + .../java/com/luca/pilot/PlanTaskTest.java | 90 +++ 52 files changed, 3622 insertions(+), 9 deletions(-) create mode 100644 .gitignore delete mode 100644 .idea/modules.xml create mode 100644 mvnw create mode 100644 pom.xml create mode 100644 src/main/java/com/luca/pilot/PilotApplication.java create mode 100644 src/main/java/com/luca/pilot/bizEnum/CrfQuestionTypeEnum.java create mode 100644 src/main/java/com/luca/pilot/bizEnum/TableEnum.java create mode 100644 src/main/java/com/luca/pilot/bo/BindDataBo.java create mode 100644 src/main/java/com/luca/pilot/bo/CrfJsonValueBo.java create mode 100644 src/main/java/com/luca/pilot/bo/CrfJsonValueKeyBo.java create mode 100644 src/main/java/com/luca/pilot/bo/CrfProblemBo.java create mode 100644 src/main/java/com/luca/pilot/bo/CrfTableJsonTopicBo.java create mode 100644 src/main/java/com/luca/pilot/config/MongoArchiveTemplateConfig.java create mode 100644 src/main/java/com/luca/pilot/config/MongoBaseTemplateConfig.java create mode 100644 src/main/java/com/luca/pilot/entity/AbstractAuditingEntity.java create mode 100644 src/main/java/com/luca/pilot/entity/BaseModuleView.java create mode 100644 src/main/java/com/luca/pilot/entity/ClinicalTrialsEvent.java create mode 100644 src/main/java/com/luca/pilot/entity/CollectModule.java create mode 100644 src/main/java/com/luca/pilot/entity/Crf.java create mode 100644 src/main/java/com/luca/pilot/entity/CrfAnswer.java create mode 100644 src/main/java/com/luca/pilot/entity/DigitalMedicalDetails.java create mode 100644 src/main/java/com/luca/pilot/entity/ModuleEntity.java create mode 100644 src/main/java/com/luca/pilot/entity/PatientScaleEvaluatingEntity.java create mode 100644 src/main/java/com/luca/pilot/entity/Plan.java create mode 100644 src/main/java/com/luca/pilot/entity/PlanModule.java create mode 100644 src/main/java/com/luca/pilot/entity/PlanTask.java create mode 100644 src/main/java/com/luca/pilot/entity/PlanTaskDetails.java create mode 100644 src/main/java/com/luca/pilot/entity/PlanTaskDetailsModule.java create mode 100644 src/main/java/com/luca/pilot/entity/PlanTaskModuleRelate.java create mode 100644 src/main/java/com/luca/pilot/entity/Project.java create mode 100644 src/main/java/com/luca/pilot/entity/Questionnaire.java create mode 100644 src/main/java/com/luca/pilot/entity/QuestionnaireAnswer.java create mode 100644 src/main/java/com/luca/pilot/entity/QuestionnaireAnswerOption.java create mode 100644 src/main/java/com/luca/pilot/entity/QuestionnaireAnswerRecord.java create mode 100644 src/main/java/com/luca/pilot/entity/ScaleModuleDetailsEntity.java create mode 100644 src/main/java/com/luca/pilot/entity/ScaleModuleEntity.java create mode 100644 src/main/java/com/luca/pilot/entity/Site.java create mode 100644 src/main/java/com/luca/pilot/entity/SynchronizeTime.java create mode 100644 src/main/java/com/luca/pilot/entity/UserArchive.java create mode 100644 src/main/java/com/luca/pilot/entity/UserArchiveMapping.java create mode 100644 src/main/java/com/luca/pilot/service/BaseModuleViewService.java create mode 100644 src/main/java/com/luca/pilot/service/PlanService.java create mode 100644 src/main/java/com/luca/pilot/service/impl/BaseModuleViewServiceImpl.java create mode 100644 src/main/java/com/luca/pilot/service/impl/PlanServiceImpl.java create mode 100644 src/main/java/com/luca/pilot/util/CrfUtil.java create mode 100644 src/main/resources/application-dev.yml create mode 100644 src/main/resources/application-hj.yml create mode 100644 src/main/resources/application-uat.yml create mode 100644 src/main/resources/application.yml create mode 100644 src/test/java/com/luca/pilot/PilotApplicationTests.java create mode 100644 src/test/java/com/luca/pilot/PlanTaskTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/.gitignore @@ -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/ diff --git a/.idea/misc.xml b/.idea/misc.xml index 639900d..accd629 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,14 @@ <?xml version="1.0" encoding="UTF-8"?> <project version="4"> - <component name="ProjectRootManager"> + <component name="ExternalStorageConfigurationManager" enabled="true" /> + <component name="MavenProjectsManager"> + <option name="originalFiles"> + <list> + <option value="$PROJECT_DIR$/pom.xml" /> + </list> + </option> + </component> + <component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK"> <output url="file://$PROJECT_DIR$/out" /> </component> </project> \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index fa1044b..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="ProjectModuleManager"> - <modules> - <module fileurl="file://$PROJECT_DIR$/.idea/ai-chat-pilot.iml" filepath="$PROJECT_DIR$/.idea/ai-chat-pilot.iml" /> - </modules> - </component> -</project> \ No newline at end of file diff --git a/mvnw b/mvnw new file mode 100644 index 0000000..d7c358e --- /dev/null +++ b/mvnw @@ -0,0 +1,259 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.2 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash> +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..53b403f --- /dev/null +++ b/pom.xml @@ -0,0 +1,93 @@ +<?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>2.3.2.RELEASE</version> + <relativePath/> <!-- lookup parent from repository --> + </parent> + + <!-- Generated by https://start.springboot.io --> + <!-- 优质的 spring/boot/data/security/cloud æ¡†æž¶ä¸æ–‡æ–‡æ¡£å°½åœ¨ => https://springdoc.cn --> + <groupId>com.luca</groupId> + <artifactId>pilot</artifactId> + <version>0.0.1-SNAPSHOT</version> + <name>pilot</name> + <description>pilot data clean</description> + <url/> + <licenses> + <license/> + </licenses> + <developers> + <developer/> + </developers> + <scm> + <connection/> + <developerConnection/> + <tag/> + <url/> + </scm> + <properties> + <java.version>11</java.version> + </properties> + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-mongodb</artifactId> + </dependency> + + <dependency> + <groupId>org.springframework.data</groupId> + <artifactId>spring-data-jpa</artifactId> + </dependency> + + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>cn.hutool</groupId> + <artifactId>hutool-all</artifactId> + <version>5.7.3</version> + </dependency> + + <dependency> + <groupId>com.alibaba</groupId> + <artifactId>fastjson</artifactId> + <version>1.2.76</version> + </dependency> + + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <configuration> + <excludes> + <exclude> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + </exclude> + </excludes> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/src/main/java/com/luca/pilot/PilotApplication.java b/src/main/java/com/luca/pilot/PilotApplication.java new file mode 100644 index 0000000..f511a0d --- /dev/null +++ b/src/main/java/com/luca/pilot/PilotApplication.java @@ -0,0 +1,16 @@ +package com.luca.pilot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableScheduling; + + +@SpringBootApplication +@EnableScheduling +public class PilotApplication { + + public static void main(String[] args) { + SpringApplication.run(PilotApplication.class, args); + } + +} diff --git a/src/main/java/com/luca/pilot/bizEnum/CrfQuestionTypeEnum.java b/src/main/java/com/luca/pilot/bizEnum/CrfQuestionTypeEnum.java new file mode 100644 index 0000000..5a17f72 --- /dev/null +++ b/src/main/java/com/luca/pilot/bizEnum/CrfQuestionTypeEnum.java @@ -0,0 +1,42 @@ +package com.luca.pilot.bizEnum; + +import cn.hutool.core.util.ObjectUtil; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @Classname CrfQuestionTypeEnum + * @Description TODO + * @Date 2023/7/18 10:29 + * @Created by èŒƒå®‡å¤ + */ +@Getter +@AllArgsConstructor +public enum CrfQuestionTypeEnum { + + CUSTOMIZE("CUSTOMIZE", "æ„外类型"), + TEMPLATE("TEMPLATE", "外层框架"), + REGULAR("REGULAR", "固定结构"), + TEXT("TEXT", "输入框"), + TEXTAREA("TEXTAREA", "多行输入框"), + NUMBER("NUMBER", "数值"), + DATE("DATE", "日期选择"), + SELECT("SELECT", "下拉å•选"), + RADIO("RADIO", "点击å•选"), + MUTISELECT("MUTISELECT", "下拉多选"), + CRFTABLE("CRFTABLE", "矩阵填空"), + CASCADER("CASCADER", "级è”选择"), + ; + + private String code; + private String desc; + + public static CrfQuestionTypeEnum getDeviceEnum(String code) { + for (CrfQuestionTypeEnum value : CrfQuestionTypeEnum.values()) { + if (ObjectUtil.equal(value.code, code)) { + return value; + } + } + return null; + } +} diff --git a/src/main/java/com/luca/pilot/bizEnum/TableEnum.java b/src/main/java/com/luca/pilot/bizEnum/TableEnum.java new file mode 100644 index 0000000..b95133c --- /dev/null +++ b/src/main/java/com/luca/pilot/bizEnum/TableEnum.java @@ -0,0 +1,54 @@ +package com.luca.pilot.bizEnum; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum TableEnum { + + armOutstretched("armOutstretched", "clinical_trials_arm_outstretched"), + bodyPosturalTremorMiddle("bodyPosturalTremorMiddle", "clinical_trials_body_postural_tremor_middle"), + bodyPosturalTremorMiddleBlind("bodyPosturalTremorMiddleBlind", "clinical_trials_body_postural_tremor_middle_blind"), + seatedSteppingLeft("seatedSteppingLeft", "clinical_trials_foot_tap_seated_left"), + seatedSteppingRight("seatedSteppingRight", "clinical_trials_foot_tap_seated_right"), + gaitStability("gaitStability", "clinical_trials_gait_and_balance"), + gaitUTurn("gaitUTurn", "clinical_trials_gait_u_turn"), + handKineticTremorLeft("handKineticTremorLeft", "clinical_trials_hand_kinetic_tremor_left"), + handKineticTremorRight("handKineticTremorRight", "clinical_trials_hand_kinetic_tremor_right"), + handPosturalTremorLeft("handPosturalTremorLeft", "clinical_trials_hand_postural_tremor_left"), + handPosturalTremorRight("handPosturalTremorRight", "clinical_trials_hand_postural_tremor_right"), + handRestTremorLeft("handRestTremorLeft", "clinical_trials_hand_rest_tremor_left"), + handRestTremorRight("handRestTremorRight", "clinical_trials_hand_rest_tremor_right"), + indexFingerTappingTwoTargetLeft("indexFingerTappingTwoTargetLeft", "clinical_trials_index_finger_tap_two_target_left"), + indexFingerTappingTwoTargetRight("indexFingerTappingTwoTargetRight", "clinical_trials_index_finger_tap_two_target_right"), + indexFingerTappingOneTargetLeft("indexFingerTappingOneTargetLeft", "clinical_trials_index_finger_tapping_one_target_left"), + indexFingerTappingOneTargetRight("indexFingerTappingOneTargetRight", "clinical_trials_index_finger_tapping_one_target_right"), + legRestTremorLeft("legRestTremorLeft", "clinical_trials_leg_rest_tremor_left"), + legRestTremorRight("legRestTremorRight", "clinical_trials_leg_rest_tremor_right"), + mci("mci", "clinical_trials_mci"), + handPronationSupinationLeft("handPronationSupinationLeft", "clinical_trials_palm_flip_left"), + handPronationSupinationRight("handPronationSupinationRight", "clinical_trials_palm_flip_right"), + sitToStand30s("sitToStand30s", "clinical_trials_sit_to_stand_by_thirty"), + tremor("tremor", "clinical_trials_tremor_detection"), + twoFingerTappingTwoTargetLeft("twoFingerTappingTwoTargetLeft", "clinical_trials_two_finger_tapping_two_target_left"), + twoFingerTappingTwoTargetRight("twoFingerTappingTwoTargetRight", "clinical_trials_two_finger_tapping_two_target_right"), + vision("vision", "clinical_trials_vision"), + visionColorBlindnessType("visionColorBlindnessType", "clinical_trials_vision_color_blindness_type"), + visionContrastSensitivity("visionContrastSensitivity", "clinical_trials_vision_contrast_sensitivity"), + visionEsdmt("visionEsdmt", "clinical_trials_vision_esdmt"), + visionVibrationSensitivity("visionVibrationSensitivity", "clinical_trials_vision_vibration_sensitivity"), + ; + + private final String moudleItemType; + private final String tableName; + + public static String getTableNameByType(String type) { + for (TableEnum value : TableEnum.values()) { + if (value.getMoudleItemType().equals(type)) { + return value.getTableName(); + } + } + return null; + } +} diff --git a/src/main/java/com/luca/pilot/bo/BindDataBo.java b/src/main/java/com/luca/pilot/bo/BindDataBo.java new file mode 100644 index 0000000..7f0722d --- /dev/null +++ b/src/main/java/com/luca/pilot/bo/BindDataBo.java @@ -0,0 +1,18 @@ +package com.luca.pilot.bo; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @Classname BindDataBo + * @Description TODO + * @Date 2023/7/18 10:37 + * @Created by èŒƒå®‡å¤ + */ +@Data +@Accessors(chain = true) +public class BindDataBo { + private String dataType; + private String choiceField; + private String dataId; +} diff --git a/src/main/java/com/luca/pilot/bo/CrfJsonValueBo.java b/src/main/java/com/luca/pilot/bo/CrfJsonValueBo.java new file mode 100644 index 0000000..369cbd4 --- /dev/null +++ b/src/main/java/com/luca/pilot/bo/CrfJsonValueBo.java @@ -0,0 +1,21 @@ +package com.luca.pilot.bo; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @Classname CrfJsonValueBo + * @Description TODO + * @Date 2023/7/17 18:17 + * @Created by èŒƒå®‡å¤ + */ +@Data +@Accessors(chain = true) +public class CrfJsonValueBo { + + private String key; + private String keyPrefix; + private String name; + private String value; + private String text; +} diff --git a/src/main/java/com/luca/pilot/bo/CrfJsonValueKeyBo.java b/src/main/java/com/luca/pilot/bo/CrfJsonValueKeyBo.java new file mode 100644 index 0000000..e1a12b4 --- /dev/null +++ b/src/main/java/com/luca/pilot/bo/CrfJsonValueKeyBo.java @@ -0,0 +1,22 @@ +package com.luca.pilot.bo; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @Classname CrfJsonValueBo + * @Description TODO + * @Date 2023/7/17 18:17 + * @Created by èŒƒå®‡å¤ + */ +@Data +@Accessors(chain = true) +public class CrfJsonValueKeyBo { + + private String id; + private String keyPrefix; + private String title; + private String value; + private String colKey; + private String colName; +} diff --git a/src/main/java/com/luca/pilot/bo/CrfProblemBo.java b/src/main/java/com/luca/pilot/bo/CrfProblemBo.java new file mode 100644 index 0000000..ec6c0bd --- /dev/null +++ b/src/main/java/com/luca/pilot/bo/CrfProblemBo.java @@ -0,0 +1,26 @@ +package com.luca.pilot.bo; + +import com.luca.pilot.bizEnum.CrfQuestionTypeEnum; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @Classname CrfProblemBo + * @Description TODO + * @Date 2023/7/18 10:37 + * @Created by èŒƒå®‡å¤ + */ +@Data +@Accessors(chain = true) +public class CrfProblemBo { + + private String title; + + private String key; + + private CrfQuestionTypeEnum questionType; + + private BindDataBo dataBo; + + private String properties; +} diff --git a/src/main/java/com/luca/pilot/bo/CrfTableJsonTopicBo.java b/src/main/java/com/luca/pilot/bo/CrfTableJsonTopicBo.java new file mode 100644 index 0000000..0f491d4 --- /dev/null +++ b/src/main/java/com/luca/pilot/bo/CrfTableJsonTopicBo.java @@ -0,0 +1,20 @@ +package com.luca.pilot.bo; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @Classname CrfTableJsonTopicBo + * @Description TODO + * @Date 2023/7/20 13:58 + * @Created by èŒƒå®‡å¤ + */ +@Data +@Accessors(chain = true) +public class CrfTableJsonTopicBo { + + private String id; + private String title; + private String dataIndex; + private String type; +} diff --git a/src/main/java/com/luca/pilot/config/MongoArchiveTemplateConfig.java b/src/main/java/com/luca/pilot/config/MongoArchiveTemplateConfig.java new file mode 100644 index 0000000..18998d4 --- /dev/null +++ b/src/main/java/com/luca/pilot/config/MongoArchiveTemplateConfig.java @@ -0,0 +1,37 @@ +package com.luca.pilot.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.data.mongodb.MongoDatabaseFactory; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; + +/** + * @author Wong + * @date 2024/1/6 14:17 + */ +@Slf4j +@Configuration +@EnableMongoRepositories(mongoTemplateRef = "mongoArchiveTemplate") +public class MongoArchiveTemplateConfig { + + @Value("${spring.data.archive-mongodb.uri}") + private String uri; + + @Bean(name = "mongoArchiveTemplate") + public MongoTemplate mongoECrfTemplate() { + log.info("-----------------------Backend Init MongoECrfTemplate Success-----------------------------------"); + return new MongoTemplate(mongoECrfFactory()); + } + + @Bean + public MongoDatabaseFactory mongoECrfFactory() { + SimpleMongoClientDatabaseFactory simpleMongoClientDbFactory = new SimpleMongoClientDatabaseFactory(uri); + return simpleMongoClientDbFactory; + } + +} diff --git a/src/main/java/com/luca/pilot/config/MongoBaseTemplateConfig.java b/src/main/java/com/luca/pilot/config/MongoBaseTemplateConfig.java new file mode 100644 index 0000000..e2ff090 --- /dev/null +++ b/src/main/java/com/luca/pilot/config/MongoBaseTemplateConfig.java @@ -0,0 +1,39 @@ +package com.luca.pilot.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.data.mongodb.MongoDatabaseFactory; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; + +/** + * @author Wong + * @date 2024/1/6 14:17 + */ +@Slf4j +@Configuration +//@EnableMongoRepositories(basePackages = "com.luca.pilot.entity") +public class MongoBaseTemplateConfig { + + @Value("${spring.data.base-mongodb.uri}") + private String uri; + + @Primary + @Bean(name = "mongoTemplate") + public MongoTemplate mongoBaseTemplate() { + log.info("-----------------------Backend Init MongoBaseTemplate Success -----------------------------------"); + return new MongoTemplate(mongoBaseFactory()); + } + + @Bean + @Primary + public MongoDatabaseFactory mongoBaseFactory() { + SimpleMongoClientDatabaseFactory simpleMongoClientDbFactory = new SimpleMongoClientDatabaseFactory(uri); + return simpleMongoClientDbFactory; + } + +} diff --git a/src/main/java/com/luca/pilot/entity/AbstractAuditingEntity.java b/src/main/java/com/luca/pilot/entity/AbstractAuditingEntity.java new file mode 100644 index 0000000..e13fd16 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/AbstractAuditingEntity.java @@ -0,0 +1,35 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import org.springframework.data.mongodb.core.mapping.Field; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * Base abstract class for entities which will hold definitions for created, last modified by date. + */ +@Data +public abstract class AbstractAuditingEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + @Field("created_by") + private String createdBy; + + @Field("created_at") + private String createdAt; + + @Field("last_modified_by") + private String lastModifiedBy; + + @Field("last_modified_at") + private String lastModifiedAt; + + /** + * åˆ é™¤æ ‡è®°ï¼ˆfalse:æœªåˆ é™¤ true:å·²åˆ é™¤ï¼‰ + */ + private boolean deleted = false; + +} diff --git a/src/main/java/com/luca/pilot/entity/BaseModuleView.java b/src/main/java/com/luca/pilot/entity/BaseModuleView.java new file mode 100644 index 0000000..f041064 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/BaseModuleView.java @@ -0,0 +1,63 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.experimental.Accessors; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +@Data +@Accessors(chain = true) +@Document(collection = "base_module_view") +public class BaseModuleView { + + private Long id; + + @Field("tenant_id") + private Long tenantId; + + private String name; + + @Field("module_item_type") + private String moduleItemType; + + private Integer status; + + @Field("module_code") + private String moduleCode; + + @Field("module_enabled") + private Boolean moduleEnabled; + + @Field("module_type") + private String moduleType; + + @Field("project_code") + private String projectCode; + + @Field("project_enabled") + private Boolean projectEnabled; + + @Field("collect_type") + private String collectType; + + @Field("local_algorithm") + private String localAlgorithm; + + @Field("supplement_img_url") + private String supplementImgUrl; + + @Field("supplement_media_url") + private String supplementMediaUrl; + + @Field("collect_duration") + private String collectDuration; + + @Field("description") + private String description; + + private String deleted; + + @Field("created_at") + private String createdAt; + +} diff --git a/src/main/java/com/luca/pilot/entity/ClinicalTrialsEvent.java b/src/main/java/com/luca/pilot/entity/ClinicalTrialsEvent.java new file mode 100644 index 0000000..66a0f9d --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/ClinicalTrialsEvent.java @@ -0,0 +1,92 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * <p> + * + * </p> + * + * @author Wong + * @since 2023-11-30 + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@Document("clinical_trials_event") +public class ClinicalTrialsEvent extends AbstractAuditingEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + private Long id; + + /** + * 项目Code + */ + private String projectCode; + + /** + * uaa用户id + */ + private Long uaaUserId; + + /** + * DBM-事件id + */ + @Field("event_id") + private Long eventId; + + /** + * 计划任务id + */ + @Field("plan_details_id") + private Long planDetailsId; + + /** + * å…³è”æ¨¡å—分类(例如: DIGITAL_MEDICAL/COLLECT_FLOW) + */ + @Field("relation_type") + private String relationType; + + /** + * å…³è”æ¨¡å—id + */ + @Field("relation_id") + private Long relationId; + + /** + * 模å—项类型 (例如: sitToStand/collect_module) + */ + @Field("module_item_type") + private String moduleItemType; + + /** + * ç§‘ç ”é‡‡é›† - 采集类型 + */ + @Field("collect_type") + private String collectType; + + /** + * ç§‘ç ”é‡‡é›† - 本地算法 + */ + private String localAlgorithm; + + /** + * 开始时间 + */ + private String startTime; + + /** + * å®Œæˆæ—¶é—´ + */ + private String finishTime; + + +} diff --git a/src/main/java/com/luca/pilot/entity/CollectModule.java b/src/main/java/com/luca/pilot/entity/CollectModule.java new file mode 100644 index 0000000..43ecb7a --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/CollectModule.java @@ -0,0 +1,88 @@ +package com.luca.pilot.entity; + + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.io.Serializable; + +/** + * <p> + * ç§‘ç ”é‡‡é›†ä¿¡æ¯è¡¨ + * </p> + * + * @author linfeng.yang + * @since 2023-06-13 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Document("collect_module") +public class CollectModule extends AbstractAuditingEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + private Long id; + + /** + * 租户ID + */ + private Long tenantId; + + /** + * åç§° + */ + private String name; + + /** + * ç¼–ç + */ + private String code; + + /** + * 采集类型 + */ + private String collectType; + + /** + * 采集时长 + */ + private Integer collectDuration; + + /** + * 本地算法 + */ + private String localAlgorithm; + + /** + * 示例媒体文件URL + */ + private String mediaUrl; + + /** + * 示例媒体文件å‰ç«¯ä½¿ç”¨ + */ + private String audioMinioPath; + + /** + * æè¿° + */ + private String description; + + /** + * å›¾ç‰‡åœ°å€ + */ + private String imgUrl; + + /** + * 是å¦è®¡æ—¶ 0或者null å¦ 1 是 + */ + private String isTime; + + /** + * 计时时间 + */ + private String time; + + +} diff --git a/src/main/java/com/luca/pilot/entity/Crf.java b/src/main/java/com/luca/pilot/entity/Crf.java new file mode 100644 index 0000000..7015eb9 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/Crf.java @@ -0,0 +1,40 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +import java.io.Serializable; + +/** + * <p> + * + * </p> + * + * @author linfeng.yang + * @since 2021-11-24 + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = true) +@Document("crf") +public class Crf extends AbstractAuditingEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + private Long id; + + private String name; + + private String description; + + private Long sourceId; + + @Field("question_json") + private String questionJson; + + @Field("crf_top_id") + private Long crfTopId; +} diff --git a/src/main/java/com/luca/pilot/entity/CrfAnswer.java b/src/main/java/com/luca/pilot/entity/CrfAnswer.java new file mode 100644 index 0000000..b190335 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/CrfAnswer.java @@ -0,0 +1,70 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +import java.io.Serializable; + +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = true) +@Document("crf_answer") +public class CrfAnswer extends AbstractAuditingEntity implements Serializable { + + + private static final long serialVersionUID = 1L; + + + /** + * CrfAnswer表主键ID + */ + private Long id; + + /** + * crf表ID + */ + @Field("crf_id") + private Long crfId; + + /** + * crfTop表主键ID + */ + @Field("crf_top_id") + private Long crfTopId; + + /** + * 租户ID + */ + private Long tenantId; + + + /** + * ç”æ¡ˆçš„大json + */ + @Field("answer_json") + private String answerJson; + + @Field("plan_task_details_id") + private Long planTaskDetailsId; + + /** + * SiteId + */ + private String siteId; + + /** + * projectCode + */ + private String projectCode; + + /** + * patientCode + */ + private String patientCode; + + + +} diff --git a/src/main/java/com/luca/pilot/entity/DigitalMedicalDetails.java b/src/main/java/com/luca/pilot/entity/DigitalMedicalDetails.java new file mode 100644 index 0000000..4c24066 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/DigitalMedicalDetails.java @@ -0,0 +1,78 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.data.mongodb.core.mapping.Document; + +/** + * <p> + * æ•°å—é¶ç‚¹å模å—详细信æ¯è¡¨ + * </p> + * + * @since 2022-01-17 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Document(collection = "digital_medical_details") +public class DigitalMedicalDetails extends AbstractAuditingEntity { + + /** + * id + */ + private Long id; + + /** + * 租户id + */ + private Long tenantId; + + /** + * åç§° + */ + private String name; + + /** + * code + */ + private String code; + + /** + * æè¿° + */ + private String description; + + /** + * 算法id + */ + private Long algorithmId; + + /** + * 算法åç§° + */ + private String algorithmName; + + /** + * 算法类型 + * com.luca.enumeration.DbmAlgorithmType枚举 + * 对应 + * com.lucahealthcare.luca.common.enumerations.ModuleItemType枚举 + */ + private String algorithmType; + + /** + * 算法支æŒè®¾å¤‡ + */ + private String algorithmDevices; + + /** + * 算法详情 + */ + private String algorithmDetails; + + /** + * æ•°å—è¯Šç–—è¯¦æƒ…ä¸‹çš„åæ•°å—诊疗id,JSONArray, todo:å† éœ–è¯´æ”¾åˆ°ç®—æ³•ä¸‹ + */ + private String subAlgorithm; + + +} diff --git a/src/main/java/com/luca/pilot/entity/ModuleEntity.java b/src/main/java/com/luca/pilot/entity/ModuleEntity.java new file mode 100644 index 0000000..098fb84 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/ModuleEntity.java @@ -0,0 +1,51 @@ +package com.luca.pilot.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +/** + * @author jiangbangfa + * @date 2021/7/20 上åˆ9:39 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = true) +@Document("module") +public class ModuleEntity extends AbstractAuditingEntity { + + private Long id; + + /** + * 项目code + */ + @Field("project_code") + private String projectCode; + + /** + * 模å—code + */ + private String code; + + /** + * 模å—åç§° + */ + private String name; + + /** + * 模å—类型 + */ + private String type; + + /** + * 模å—çŠ¶æ€ + */ + private Boolean enabled; + +} diff --git a/src/main/java/com/luca/pilot/entity/PatientScaleEvaluatingEntity.java b/src/main/java/com/luca/pilot/entity/PatientScaleEvaluatingEntity.java new file mode 100644 index 0000000..8e00d0f --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/PatientScaleEvaluatingEntity.java @@ -0,0 +1,44 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +/** + * @author linfeng.yang + * @date 2021/8/03 下åˆ14:40 + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = true) +@Document("patient_scale_evaluating") +public class PatientScaleEvaluatingEntity extends AbstractAuditingEntity { + private static final long serialVersionUID = 1L; + + private Long id; + private String code; + + @Field("project_code") + private String projectCode; + private String patientCode; + private String siteId; + @Field("scale_code") + private String scaleCode; + @Field("scale_result") + private String scaleResult; + private String ruleId; + + /** + * é‡è¡¨ç”题总得分 + */ + @Field("total_score") + private String totalScore; + + /** + * 患者任务详情id + */ + @Field("plan_task_details_id") + private Long planTaskDetailsId; +} diff --git a/src/main/java/com/luca/pilot/entity/Plan.java b/src/main/java/com/luca/pilot/entity/Plan.java new file mode 100644 index 0000000..8319284 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/Plan.java @@ -0,0 +1,91 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +import java.time.LocalDate; + +/** + * <p> + * 计划表 + * </p> + * + * @author Lt + * @since 2021-11-08 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Document(collection="plan") +public class Plan extends AbstractAuditingEntity { + + /** + * id + */ + private Long id; + + /** + * 租户id + */ + @Field("tenant_id") + private Long tenantId; + + /** + * 项目id + */ + @Field("project_id") + private Long projectId; + + /** + * 计划åç§° + */ + private String name; + + /** + * è®¡åˆ’ç¼–å· + */ + private String number; + + /** + * 生效日期 + */ + @Field("effective_date") + private LocalDate effectiveDate; + + /** + * 计划天数 + */ + private Integer days; + + /** + * æè¿° + */ + private String description; + + /** + * 是å¦å¯ç”¨(0:ç¦ç”¨ 1:å¯ç”¨) + */ + private Boolean enabled; + + /** + * 计划二维ç + */ + @Field("plan_url") + private String planUrl; + + /** + * æ ‡ç¾ids + */ + @Field("patient_tags") + private String patientTags; + + /** + * 是å¦éœ€è¦åŒ»ç”Ÿå®¡æ ¸ 0 ä¸éœ€è¦ 1 éœ€è¦ + */ + @Field("doctor_audit") + private Integer doctorAudit; + + + +} diff --git a/src/main/java/com/luca/pilot/entity/PlanModule.java b/src/main/java/com/luca/pilot/entity/PlanModule.java new file mode 100644 index 0000000..c990dea --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/PlanModule.java @@ -0,0 +1,84 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import org.springframework.data.mongodb.core.mapping.Document; + +@Data +@Document(collection="plan_module") +public class PlanModule { + + private String key; + /** + * æ‚£è€…ç¼–å· + */ + private String subjectId; + /** + * éšæœºæ•° + */ + private String randomizationId; + + + /** + * plan + */ + private String projectCode; + private String projectName; + private String siteName; + private Long planId; + private String planCode; + private String planEffectiveDate; + private Integer planDuration; + + /** + * plan task + */ + private String planTaskName; + private String planTaskdescription; + private Integer planTaskType; + private Integer planTaskTaskCount; + private Integer planTaskFinishDay; + private Integer planTaskLoopType; + private Boolean planTaskEnabled; + private Integer planTaskIsCirculation; + private Integer planTaskBeginDay; + private Integer planTaskCirculationDay; + private Integer planTaskWindowPhase; + private Integer planTaskEndDay; + + /** + * plan task detail + */ + private String taskStartDate; + private String taskEndDate; + private Integer taskCompleteStatus; + private String taskCompleteTime; + private Integer taskEnabled; + private Integer taskCompleteOrder; + + /** + * plan module relate + */ + private String moduleType; + private Long moduleId; + private String moduleName; + + + + /** + * plan task detail module + */ + private Integer moduleComplete; + private String moduleIgnoreRemark; + private String moduleFinishTime; + + /** + * 组装 + */ + private String result; + private String digitalModuleTableName; + + /** + * event + */ + private Long digitalModuleEventId; +} diff --git a/src/main/java/com/luca/pilot/entity/PlanTask.java b/src/main/java/com/luca/pilot/entity/PlanTask.java new file mode 100644 index 0000000..d7cff83 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/PlanTask.java @@ -0,0 +1,157 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +/** + * <p> + * 患者任务计划 + * </p> + * + * @author Lt + * @since 2021-11-08 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Document(collection="plan_task") +public class PlanTask extends AbstractAuditingEntity { + + /** + * id + */ + private Long id; + + /** + * 租户id + */ + @Field("tenant_id") + private Long tenantId; + + /** + * 项目id + */ + @Field("project_id") + private Long projectId; + + /** + * 计划id + */ + @Field("plan_id") + private Long planId; + + /** + * 任务åç§° + */ + @Field("name") + private String name; + + /** + * 任务æè¿° + */ + @Field("description") + private String description; + + /** + * 循环类型(1:周 2:月 3:项目) + */ + @Field("loop_type") + private Integer loopType; + + /** + * 执行类型(循环类型=周 1:指定星期 2:å¾ªçŽ¯å‘¨å†…å‡ æ¬¡; 循环类型=月 1:ä»Žå½“æœˆå‡ æ—¥å¼€å§‹ 2:指定日期) + */ + @Field("execute_type") + private Integer executeType; + + /** + * 执行日期(cron表达å¼ç®€åŒ–) + */ + @Field("execute_cron") + private String executeCron; + + /** + * 周执行频次(循环类型为周类型,å¾ªçŽ¯å‘¨å†…å‡ æ¬¡æ—¶è®¾å€¼) + */ + @Field("week_frequency") + private Integer weekFrequency; + + /** + * 是å¦å¯ç”¨(0:ç¦ç”¨ 1:å¯ç”¨) + */ + @Field("enabled") + private Boolean enabled; + + /** + * è®¡åˆ’ç›®æ ‡id + */ + @Field("target_id") + private Long targetId; + /** + * çª—å£æœŸ + */ + @Field("window_phase") + private Integer windowPhase; + + /** + * 预约时间 + */ + @Field("reserve_time") + private String reserveTime; + + /** + * 共需多少天 + */ + @Field("finish_day") + private Integer finishDay; + + /** + * 任务类型(0:患者任务 1:医生éšè®¿) + */ + @Field("task_type") + private Integer taskType; + + /** + * ä¸€æ—¥éœ€å®Œæˆæ¬¡æ•° + */ + @Field("task_count") + private Integer taskCount; + + /** + * 是å¦å¼€å¯çª—壿œŸ 1å¼€å¯ 0 æœªå¼€å¯ + */ + @Field("is_window_phase") + private Integer isWindowPhase; + + /** + * 是å¦å¾ªçޝ 1是 0 å¦ + */ + @Field("is_circulation") + private Integer isCirculation; + + /** + * ç¬¬å‡ å¤©å¾ªçŽ¯ + */ + @Field("circulation_day") + private Integer circulationDay; + + /** + * ç¬¬å‡ å¤©å¼€å§‹ + */ + @Field("begin_day") + private Integer beginDay; + + /** + * 入组类型éšè®¿ç»“æŸäºŽç¬¬å‡ 天,0为至éšè®¿ç»“æŸ + */ + @Field("end_day") + private Integer endDay; + + /** + * 分组id + */ + @Field("group_id") + private Long groupId; + +} diff --git a/src/main/java/com/luca/pilot/entity/PlanTaskDetails.java b/src/main/java/com/luca/pilot/entity/PlanTaskDetails.java new file mode 100644 index 0000000..2b2209f --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/PlanTaskDetails.java @@ -0,0 +1,100 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +import java.time.LocalDateTime; + +/** + * <p> + * 患者任务计划详情表 + * </p> + * + * @author Lt + * @since 2021-11-08 + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = true) +@Document(collection="plan_task_details") +public class PlanTaskDetails extends AbstractAuditingEntity { + + /** + * id + */ + private Long id; + + /** + * 计划code //todo ä¸´æ—¶å—æ®µ + */ + @Field("schedule_task_code") + private String scheduleTaskCode; + + /** + * 租户id + */ + @Field("tenant_id") + private Long tenantId; + + /** + * 项目id + */ + @Field("project_id") + private Long projectId; + + /** + * 患者任务计划id + */ + @Field("plan_task_id") + private Long planTaskId; + + /** + * 患者code + */ + @Field("patient_code") + private String patientCode; + + /** + * 计划开始日期 + */ + @Field("start_date") + private String startDate; + + /** + * è®¡åˆ’ç»“æŸæ—¥æœŸ + */ + @Field("end_date") + private String endDate; + + /** + * 计划完æˆçжæ€(0:æœªå®Œæˆ 1:已完æˆ) + */ + @Field("complete_status") + private Integer completeStatus; + + /** + * è®¡åˆ’å®Œæˆæ—¶é—´ + */ + @Field("complete_time") + private String completeTime; + + /** + * 命䏿¡ä»¶(è‹¥æ˜¯å¾ªçŽ¯å‘¨å†…å‡ æ¬¡1111100:æ ‡è¯† 周一到周五åš,周å…周天ä¸åš; 其它类型任务:1) + */ + private String hit; + + /** + * 完æˆé¡ºåº + */ + @Field("complete_order") + private Integer completeOrder; + + /** + * 0 ç¦ç”¨ 1 å¯ç”¨ + */ + private Integer enabled; + +} diff --git a/src/main/java/com/luca/pilot/entity/PlanTaskDetailsModule.java b/src/main/java/com/luca/pilot/entity/PlanTaskDetailsModule.java new file mode 100644 index 0000000..6a4a1e6 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/PlanTaskDetailsModule.java @@ -0,0 +1,62 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +/** + * <p> + * 患者任务计划详情表 + * </p> + * + * @author Lt + * @since 2021-11-08 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Document(collection = "plan_task_details_module") +public class PlanTaskDetailsModule extends AbstractAuditingEntity { + + /** + * id + */ +// @TableId(type = IdType.INPUT) + private Long id; + + /** + * 租户id + */ + private Long tenantId; + + /** + * 患者任务计划详情id + */ + @Field("plan_task_details_id") + private Long planTaskDetailsId; + + /** + * å…³è”项目类型 + */ + @Field("relation_type") + private String relationType; + + /** + * å…³è”id + */ + @Field("relation_id") + private Long relationId; + + /** + * 模å—任务完æˆçжæ€(0:æœªå®Œæˆ 1:已完æˆ) + */ + @Field("module_complete") + private Integer moduleComplete; + + /** + * 忽略备注 + */ + @Field("ignore_remark") + private String ignoreRemark; + +} diff --git a/src/main/java/com/luca/pilot/entity/PlanTaskModuleRelate.java b/src/main/java/com/luca/pilot/entity/PlanTaskModuleRelate.java new file mode 100644 index 0000000..380f87c --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/PlanTaskModuleRelate.java @@ -0,0 +1,51 @@ +package com.luca.pilot.entity; + + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +/** + * <p> + * 患者任务计划与模å—å…³è”表 + * </p> + * + * @author Lt + * @since 2021-11-08 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Document(collection="plan_task_module_relate") +public class PlanTaskModuleRelate extends AbstractAuditingEntity { + + /** + * id + */ + private Long id; + + /** + * 租户id + */ + @Field("tenant_id") + private Long tenantId; + + /** + * å…³è”model类型 + */ + @Field("relation_type") + private String relationType; + + /** + * å…³è”id + */ + @Field("relation_id") + private Long relationId; + + /** + * 患者任务计划id + */ + @Field("plan_task_id") + private Long planTaskId; + +} diff --git a/src/main/java/com/luca/pilot/entity/Project.java b/src/main/java/com/luca/pilot/entity/Project.java new file mode 100644 index 0000000..a1363fb --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/Project.java @@ -0,0 +1,95 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +import java.time.LocalDate; + +/** + * @author jiangbangfa + * @date 2021/7/19 下åˆ6:13 + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = true) +@Document(collection="project") +public class Project extends AbstractAuditingEntity { + + + private Long id; + + private String code; + + private String name; + + @Field("app_ids") + private String appIds; + + @Field("invite_code") + private String inviteCode; + + private Long type; + + private String number; + + @Field("tenant_id") + private Long tenantId; + + @Field("bid_unit") + private String bidUnit; + + private String version; + +// @Field("start_at") +// private LocalDate startAt; +// +// @Field("end_at") +// private LocalDate endAt; + + private String url; + @Field("dashboard_show_code") + private String dashboardShowCode; + + @Field("dashboard_show_name") + private String dashboardShowName; + + /** + * 日记使用 方案åç§° éžå¿…å¡« + */ + @Field("scheme_name") + private String schemeName; + + /** + * 日记使用 æ–¹æ¡ˆç¼–å· éžå¿…å¡« + */ + @Field("scheme_code") + private String schemeCode; + +// /** +// * 是å¦è®¤è¯ +// */ +// @Field("enable_id_verification") +// private Boolean enableIdVerification; + + + /** + * 0 未é”库 1 å·²é”库 + */ + private Integer locked; + + /** + * ç ”ç©¶éšè®¿æ—¶é•¿ + */ + @Field("study_follow_up_time") + private Integer studyFollowUpTime; + + /** + * 计划人数 + */ + @Field("plan_people") + private Long planPeople; + +} diff --git a/src/main/java/com/luca/pilot/entity/Questionnaire.java b/src/main/java/com/luca/pilot/entity/Questionnaire.java new file mode 100644 index 0000000..7a2dfa0 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/Questionnaire.java @@ -0,0 +1,43 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +import java.io.Serializable; + +/** + * <p> + * + * </p> + * + * @author linfeng.yang + * @since 2021-10-21 + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = true) +@Document("questionnaire") +public class Questionnaire extends AbstractAuditingEntity implements Serializable { + + private static final long serialVersionUID = 1L; + private Long id; + + private String url; + + private String name; + + private String description; + + private Integer status; + + @Field("top_id") + private Long topId; + + private Long sourceId; + + private Long tenantId; + +} diff --git a/src/main/java/com/luca/pilot/entity/QuestionnaireAnswer.java b/src/main/java/com/luca/pilot/entity/QuestionnaireAnswer.java new file mode 100644 index 0000000..afe1219 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/QuestionnaireAnswer.java @@ -0,0 +1,68 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +import java.io.Serializable; + +/** + * <p> + * + * </p> + * + * @author linfeng.yang + * @since 2021-11-02 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Document("questionnaire_answer") +public class QuestionnaireAnswer extends AbstractAuditingEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + private Long id; + + @Field("questionnaire_id") + private Long questionnaireId; + + @Field("questionnaire_name") + private String questionnaireName; + + @Field("question_id") + private Long questionId; + + @Field("question_name") + private String questionName; + + private String type; + + private Long tenantId; + + + /** + * 患者任务详情id + */ + @Field("plan_task_details_id") + private Long planTaskDetailsId; + + /** + * ç¡çœ é—®å·ç¡çœ 类型 + */ + private Integer sleepType; + + /** + * site Id + */ + private String siteId; + /** + * 主记录id + */ + @Field("record_id") + private Long recordId; + +// @ApiModelProperty(value = "å…³è”schedule") +// private String scheduleTaskCode; + +} diff --git a/src/main/java/com/luca/pilot/entity/QuestionnaireAnswerOption.java b/src/main/java/com/luca/pilot/entity/QuestionnaireAnswerOption.java new file mode 100644 index 0000000..41e4b59 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/QuestionnaireAnswerOption.java @@ -0,0 +1,55 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * <p> + * + * </p> + * + * @author linfeng.yang + * @since 2021-11-02 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Document("questionnaire_answer_option") +public class QuestionnaireAnswerOption extends AbstractAuditingEntity implements Serializable{ + + private static final long serialVersionUID = 1L; + + private Long id; + + @Field("answer_id") + private Long answerId; + + @Field("option_id") + private Long optionId; + + @Field("option_name") + private String optionName; + + @Field("question_id") + private Long questionId; + + private String content; + + @Field("date_at") + private String dateAt; + + @Field("number_answer") + private BigDecimal numberAnswer; + + @Field("left_min") + private BigDecimal leftMin; + + @Field("right_max") + private BigDecimal rightMax; + +} diff --git a/src/main/java/com/luca/pilot/entity/QuestionnaireAnswerRecord.java b/src/main/java/com/luca/pilot/entity/QuestionnaireAnswerRecord.java new file mode 100644 index 0000000..db02ed9 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/QuestionnaireAnswerRecord.java @@ -0,0 +1,56 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * <p> + * + * </p> + * + * @author linfeng.yang + * @since 2021-10-21 + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@Document("questionnaire_answer_record") +public class QuestionnaireAnswerRecord extends AbstractAuditingEntity implements Serializable{ + + private static final long serialVersionUID = 1L; + + private Long id; + + @Field("top_id") + private Long topId; + + @Field("project_code") + private String projectCode; + + @Field("site_id") + private String siteId; + + @Field("patient_code") + private String patientCode; + + /** + * 患者任务详情id + */ + @Field("plan_task_details_id") + private Long planTaskDetailsId; + + /** + * è®¡åˆ’å®Œæˆæ—¶é—´ + */ + @Field("complete_time") + private String completeTime; + + + +} diff --git a/src/main/java/com/luca/pilot/entity/ScaleModuleDetailsEntity.java b/src/main/java/com/luca/pilot/entity/ScaleModuleDetailsEntity.java new file mode 100644 index 0000000..39cf369 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/ScaleModuleDetailsEntity.java @@ -0,0 +1,33 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.math.BigDecimal; + +/** + * @author linfeng.yang + * @date 2021/8/03 下åˆ14:40 + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = true) +@Document("scale_module_details") +public class ScaleModuleDetailsEntity extends AbstractAuditingEntity { + + private Long id; + private String code; + private String name; + private String description; + private String ruleDescription; + private Integer status; //0:未å‘布 1:å·²å‘布 2:已下架 + private String tags; + private String scaleImg; + private String url; + private String abbreviation; + private BigDecimal scaleScore; + private String ruleResult; + private String ruleContent; +} diff --git a/src/main/java/com/luca/pilot/entity/ScaleModuleEntity.java b/src/main/java/com/luca/pilot/entity/ScaleModuleEntity.java new file mode 100644 index 0000000..0379b66 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/ScaleModuleEntity.java @@ -0,0 +1,29 @@ +package com.luca.pilot.entity; + + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +/** + * @author linfeng.yang + * @date 2021/8/03 下åˆ14:40 + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = true) +@Document("scale_module") +public class ScaleModuleEntity extends AbstractAuditingEntity { + + private Long id; + private String code; + @Field("project_code") + private String projectCode; + @Field("module_code") + private String moduleCode; + @Field("scale_code") + private String scaleCode; + private Boolean enabled; +} diff --git a/src/main/java/com/luca/pilot/entity/Site.java b/src/main/java/com/luca/pilot/entity/Site.java new file mode 100644 index 0000000..22c70b6 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/Site.java @@ -0,0 +1,89 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +@EqualsAndHashCode(callSuper = true) +@Data +@Document(collection="site") +public class Site extends AbstractAuditingEntity { + /** + * siteId + */ + private Long id; + + /** + * 租户id + */ + private Long tenantId; + + /** + * 项目id + */ + private Long projectId; + + /** + * siteåç§°(L:32) + */ + @Field("site_name") + private String siteName; + + /** + * æè¿°(L:128) + */ + private String description; + + /** + * logo + */ + private String logoUrl; + + /** + * çŸ¥æƒ…åŒæ„书文本 + */ + private String agreementText; + + /** + * çŸ¥æƒ…åŒæ„类型 0 æ— 1 é€šç”¨æ¨¡æ¿ 2 site自定义 + */ + private Integer agreementType; + + /** + * ç›®æ ‡æ‚£è€…æ•° + */ + private Long targetPatientsNum; + + /** + * çœçº§id + */ + private Long provinceId; + + /** + * 市级id + */ + private Long cityId; + + /** + * 区/县级id + */ + private Long areaId; + + /** + * çœçº§-市级-区/县级 + */ + private String address; + + /** + * 时区 + */ + private String timeZone; + + /** + * å¯ç”¨çŠ¶æ€ + */ + private Boolean enable; + + +} \ No newline at end of file diff --git a/src/main/java/com/luca/pilot/entity/SynchronizeTime.java b/src/main/java/com/luca/pilot/entity/SynchronizeTime.java new file mode 100644 index 0000000..9391f86 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/SynchronizeTime.java @@ -0,0 +1,14 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.time.LocalDateTime; +@Data +@Document(collection="synchronize_time") +public class SynchronizeTime { + + private String _id; + private LocalDateTime plan; + +} diff --git a/src/main/java/com/luca/pilot/entity/UserArchive.java b/src/main/java/com/luca/pilot/entity/UserArchive.java new file mode 100644 index 0000000..5e1579c --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/UserArchive.java @@ -0,0 +1,207 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.experimental.Accessors; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Data +@Accessors(chain = true) +@Document("user_archive") +public class UserArchive { + + @Id + private String id; + /** + * åå— + */ + private String name; + + /** + * æ‰‹æœºå· + */ + private String phoneNo; + + /** + * ç”·|女 + */ + private String gender; + + /** + * YYYY-MM-DDæ ¼å¼ + */ + private String birthday; + + /** + * 身份è¯åŽå››ä½ + */ + private String idCardLastFour; + + /** + * 身份è¯å· + */ + private String idCard; + + /** + * åœ°å€ + */ + private String address; + + /** + * å¦åކ + */ + private String education; + + /** + * èŒä¸šï¼ˆé€€ä¼‘å‰ï¼‰ + */ + private String job; + + /** + * 婚姻状况 + */ + private String maritalStatus; + + /** + * å±…ä½çŠ¶æ€ + */ + private String dwellStatus; + + /** + * 身高 + */ + private String height; + + /** + * ä½“é‡ + */ + private String weight; + + /** + * 是å¦å–œæ¬¢å¬éŸ³ä¹ + */ + private String likeMusic; + + /** + * æ¯å‘¨å¬éŸ³ä¹æ—¶é•¿ + */ + private String weekMusciDuration; + + /** + * å¤šä¹…å…¥ç¡ + */ + private String fallAsleep; + + /** + * ç¡çœ å‡ å°æ—¶ + */ + private String sleepTime; + + /** + * å½±å“ç¡çœ 情况 + */ + private String sleepAffect; + + /** + * 是å¦è¯ç‰©åŠ©çœ + */ + private String drugHelpSleep; + + /** + * 是å¦å¬ä¸æ¸…å½±å“生活 + */ + private String hearingAffectLife; + + /** + * æ˜¯å¦æ‚£æœ‰ç³–å°¿ç—… + */ + private String diabetes; + /** + * æ˜¯å¦æ‚£æœ‰é«˜è¡€åŽ‹ + */ + private String hypertension; + /** + * 是å¦é¥®é…’ + */ + private String drink; + /** + * 是å¦å¸çƒŸ + */ + private String smoke; + + /** + * 规则md5 + */ + private String schemaMd5; + + /** + * æ°‘æ— + */ + private String nation; + + /** + * æ—¢å¾€ç—…å² + */ + private String pastMedicalHistory; + + /** + * éšæœºæ•° + */ + private String randomizationId; + /** + * 过æ•å² + */ + private String allergyHistory; + + private String nlfh;//',"å¥åº·å¿—愿者,年龄18至75å²ï¼ˆåŒ…å«è¾¹ç•Œå€¼ï¼‰ï¼Œç”·å¥³ä¸é™" + private String brqs;//',"能够本人ç¾ç½²çŸ¥æƒ…åŒæ„书" + private String yypd;//',"æ„¿æ„åœ¨ç ”ç©¶æœŸé—´ä½©æˆ´æ‰‹çŽ¯æ”¶é›†æ•°æ®è®¾å¤‡" + private String yytgdz;//',"æ„¿æ„æä¾›æœ‰æ•ˆçš„è”系地å€ï¼Œä»¥æŽ¥æ”¶ç ”究设备" + private String ywf;//',"å®¶ä¸éœ€å…·å¤‡Wi-Fi网络连接,网络速度100 MbpsåŠä»¥ä¸Š" + private String yysysj;//',"æ„¿æ„使用é…备数æ®å¥—é¤çš„æ‰‹æœºï¼Œå¹¶é‡‡ç”¨åˆé€‚的数æ®è¿žæŽ¥æ–¹å¼ä¼ è¾“ç ”ç©¶æ‰€æ”¶é›†çš„æ•°æ®" + private String ysjxtbs;//',"有神ç»ç³»ç»Ÿæˆ–精神疾病病å²ï¼Œæˆ–è®¤çŸ¥å—æŸæˆ–失去行为能力的å—试者" + private String yhgfxshsb;//',"有很高风险æŸå设备或ä¸èƒ½é•¿æ—¶é—´ä½©æˆ´çš„å—试者,如ç»å¸¸æ¸¸æ³³è€…" + private String gmpf;//',"对å¯ç©¿æˆ´è®¾å¤‡è¿‡æ•或有皮肤过æ•å²çš„å—试者" + private String yzyfx;//',"由于å¥åº·çŠ¶å†µé—®é¢˜ï¼Œè¢«è¯„ä¼°ä¸ºæœ‰ä½é™¢é£Žé™©çš„å—试者" + private String wsyznsb;//',"既往从未使用过智能设备的å—试者" + private String ssz;//',"在ç›é€‰æ—¶å˜åœ¨éœ€è¦æ²»ç–—的急性或慢性疾病的å—试者(包括但ä¸é™äºŽå…疫缺陷或å…ç–«æŠ‘åˆ¶ç–¾ç—…ã€æ¶æ€§è‚¿ç˜¤æˆ–皮肤疾病ç‰ï¼‰" + private String yywly;//',"有è¯ç‰©æ»¥ç”¨æˆ–è¯ç‰©ä¾èµ–ç—…å²çš„å—试者" + private String cyqtsy;//',"ç›®å‰å‚与其他è¯ç‰©æˆ–医疗设备临床试验的å—试者" + private String zzbr;//',"ç›®å‰æ£åœ¨å“ºä¹³çš„女性" + private String yjzbsh;//',"ç ”ç©¶è€…è®¤ä¸ºå—试者å˜åœ¨ä¸é€‚åˆå‚ä¸Žè¯•éªŒçš„å…¶ä»–åŽŸå› " + private String wcglx;//',"å—试者在ç¾ç½²çŸ¥æƒ…åŒæ„æ—¶æˆ–æ•´ä¸ªç ”ç©¶æœŸé—´ï¼Œæ— å‡ºå›½æ—…è¡Œè®¡åˆ’" + + private String screeningNum; // ç›é€‰å· + private String addressHome; // å®¶åºä½å€ + + // ------------------ æ‚£è€…æ¡£æ¡ˆå›ºå®šæ•°æ® ------------------- + /** + * æ‚£è€…ç¼–å· subjectId + */ + private String subjectId; + + /** + * 0ç¦ç”¨ 1å¯ç”¨(默认) + */ + private Integer enable = 1; + + /** + * 是å¦å°å˜ 0å¦ 1是 + */ + private Integer isArchive = 0; + + /** + * 创建时间 + */ + private String createAt; + + /** + * 创建人 + */ + private String createBy; + + /** + * 文件url + */ + private String fileUrl; +} diff --git a/src/main/java/com/luca/pilot/entity/UserArchiveMapping.java b/src/main/java/com/luca/pilot/entity/UserArchiveMapping.java new file mode 100644 index 0000000..220db16 --- /dev/null +++ b/src/main/java/com/luca/pilot/entity/UserArchiveMapping.java @@ -0,0 +1,33 @@ +package com.luca.pilot.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +/** + * @author linfeng.yang + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = true) +@Document(collection="user_archive_mapping") +public class UserArchiveMapping extends AbstractAuditingEntity { + private Long id; + @Field("project_code") + private String projectCode; + + @Field("site_id") + private Long siteId; + + @Field("uaa_user_id") + private Long uaaUserId; + + @Field("patient_code") + private String patientCode; + + @Field("user_archive_id") + private String userArchiveId; + +} diff --git a/src/main/java/com/luca/pilot/service/BaseModuleViewService.java b/src/main/java/com/luca/pilot/service/BaseModuleViewService.java new file mode 100644 index 0000000..78b1388 --- /dev/null +++ b/src/main/java/com/luca/pilot/service/BaseModuleViewService.java @@ -0,0 +1,10 @@ +package com.luca.pilot.service; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + + +public interface BaseModuleViewService { + + void synchronizeModuleView(); +} diff --git a/src/main/java/com/luca/pilot/service/PlanService.java b/src/main/java/com/luca/pilot/service/PlanService.java new file mode 100644 index 0000000..94be7ce --- /dev/null +++ b/src/main/java/com/luca/pilot/service/PlanService.java @@ -0,0 +1,10 @@ +package com.luca.pilot.service; + +public interface PlanService { + + + void synchronizePlanTask(); + + void test(); + +} diff --git a/src/main/java/com/luca/pilot/service/impl/BaseModuleViewServiceImpl.java b/src/main/java/com/luca/pilot/service/impl/BaseModuleViewServiceImpl.java new file mode 100644 index 0000000..a1ee712 --- /dev/null +++ b/src/main/java/com/luca/pilot/service/impl/BaseModuleViewServiceImpl.java @@ -0,0 +1,57 @@ +package com.luca.pilot.service.impl; + +import com.luca.pilot.entity.BaseModuleView; +import com.luca.pilot.entity.ModuleEntity; +import com.luca.pilot.entity.ScaleModuleDetailsEntity; +import com.luca.pilot.entity.ScaleModuleEntity; +import com.luca.pilot.service.BaseModuleViewService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class BaseModuleViewServiceImpl implements BaseModuleViewService { + + @Resource(name = "mongoTemplate") + private MongoTemplate mongoTemplate; + + @Override + public void synchronizeModuleView() { + queryScale(); + } + + private void queryScale() { + List<ScaleModuleDetailsEntity> scaleModuleDetailsList = mongoTemplate.findAll(ScaleModuleDetailsEntity.class); + List<ScaleModuleEntity> scaleModuleList = mongoTemplate.findAll(ScaleModuleEntity.class); + List<ModuleEntity> moduleList = mongoTemplate.findAll(ModuleEntity.class); + + List<BaseModuleView> views = scaleModuleDetailsList.stream().map(x -> { + ScaleModuleEntity sm = scaleModuleList.stream().filter(y -> y.getScaleCode().equals(x.getCode())).findFirst().orElse(null); + if(Objects.nonNull(sm)) { + ModuleEntity m = moduleList.stream().filter(y -> y.getCode().equals(sm.getModuleCode())).findFirst().orElse(null); + BaseModuleView view = new BaseModuleView() + .setId(x.getId()) + .setName(x.getName()) + .setStatus(x.getStatus()) + .setModuleCode(Objects.isNull(sm) ? "" : sm.getScaleCode()) + .setModuleEnabled(Objects.isNull(sm) ? null : sm.getEnabled()) + .setModuleType(Objects.isNull(m) ? "" : m.getType()) + .setProjectCode(Objects.isNull(m) ? "" : m.getProjectCode()) + .setProjectEnabled(Objects.isNull(m) ? null : m.getEnabled()); + return view; + } + return null; + }).collect(Collectors.toList()); + + mongoTemplate.insertAll(views); + } + +} diff --git a/src/main/java/com/luca/pilot/service/impl/PlanServiceImpl.java b/src/main/java/com/luca/pilot/service/impl/PlanServiceImpl.java new file mode 100644 index 0000000..8e4dc42 --- /dev/null +++ b/src/main/java/com/luca/pilot/service/impl/PlanServiceImpl.java @@ -0,0 +1,643 @@ +package com.luca.pilot.service.impl; + +import cn.hutool.core.map.MapUtil; +import cn.hutool.json.JSONUtil; +import com.luca.pilot.bizEnum.TableEnum; +import com.luca.pilot.entity.*; +import com.luca.pilot.service.PlanService; +import com.luca.pilot.util.CrfUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.mongodb.core.BulkOperations; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.data.mongodb.core.query.Update; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import javax.annotation.Resource; +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Slf4j +@Service +public class PlanServiceImpl implements PlanService { + + @Resource(name = "mongoTemplate") + private MongoTemplate mongoTemplate; + + @Resource(name = "mongoArchiveTemplate") + private MongoTemplate mongoArchiveTemplate; + + @Override + @Scheduled(cron ="0 0/5 * * * ?") + public void synchronizePlanTask() { + log.info("-----------synchronizePlanTask start-----------"); + LocalDateTime now = LocalDateTime.now(); + + SynchronizeTime synchronizeTime = findSynchronizeTime(); + + LocalDateTime lastSynchronizeTime = null; + if (Objects.nonNull(synchronizeTime)) { + lastSynchronizeTime = synchronizeTime.getPlan(); + } + + Query countQuery = new Query(); + if (Objects.nonNull(lastSynchronizeTime)) { + countQuery.addCriteria(Criteria.where("last_modified_at").gt(String.valueOf(lastSynchronizeTime))); + } + long totalPlanTaskDetailsCount = mongoTemplate.count(countQuery, PlanTaskDetails.class); + log.info("PlanTaskDetails 在大于 {} æ—¶é—´å†…æœªæŸ¥è¯¢åˆ°æ•°æ® {} æ¡", lastSynchronizeTime, totalPlanTaskDetailsCount); + + if (totalPlanTaskDetailsCount == 0) { + return; + } + + saveSynchronizeTime(synchronizeTime, now); + + long skip = totalPlanTaskDetailsCount / 10000; + if (totalPlanTaskDetailsCount % 10000 > 0) { + skip++; + } + + long totalPlanModuleCount = mongoTemplate.count(countQuery, PlanModule.class); + + BulkOperations bulkOps = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, PlanModule.class); + + for (int i = 0; i < skip; i++) { + countQuery.skip(i * 10000L); + countQuery.limit(10000); + List<PlanTaskDetails> planTaskDetails = mongoTemplate.find(countQuery, PlanTaskDetails.class); + log.info("第{}次查询 planTaskDetails count:{}", i + 1, planTaskDetails.size()); + // 获å–对应档案,å–subjectId å’Œ randomId + List<UserArchiveMapping> userArchiveMappings = queryArchiveMapping(planTaskDetails); + List<UserArchive> userArchives = queryArchive(userArchiveMappings); + + List<Project> projects = queryProjct(planTaskDetails); + List<Site> sites = querySites(userArchiveMappings); + + List<PlanTask> planTasks = queryPlanTasks(planTaskDetails); + List<Plan> plans = queryPlans(planTasks); + List<PlanTaskModuleRelate> planMoudleRelates = queryPlanMoudleRelates(planTasks); + List<PlanTaskDetailsModule> planTaskDetailsModules = queryPlanTaskDetaiMoudles(planTaskDetails); + + Map<Long, String> relationNameMap = queryRelateMoudleName(planMoudleRelates); + + Map<Long, Map<String, String>> resultMap = queryPlanTaskDetailResult(planTaskDetails); + + Map<Long, Map<Long, Long>> digitalMedicalEventMap = queryDigitalMedicalEvent(planTaskDetails); + Map<Long, Map<Long, String>> digitalMedicalTypeMap = queryDigitalMedicalType(planTaskDetails); + + List<PlanModule> planMoudles = new ArrayList<>(); + + + //以 planTaskDetail å’Œ planMoudleRelate 为基准 + // 一个 planTaskDetail 能对应多个 planMoudleRelate,å³ä¸€æ¬¡ä»»åŠ¡é…置了多少个模å—(问å·ï¼Œé‡è¡¨ï¼Œæ•°å—é¶ç‚¹ï¼‰ + for (PlanTaskDetails planTaskDetail : planTaskDetails) { + UserArchiveMapping userArchiveMapping = userArchiveMappings.stream().filter(x -> x.getPatientCode().equals(planTaskDetail.getPatientCode())).findFirst().orElse(null); + + UserArchive userArchive = userArchives.stream().filter(x -> Objects.nonNull(userArchiveMapping) && x.getId().equals(userArchiveMapping.getUserArchiveId())).findFirst().orElse(null); + + Project project = projects.stream().filter(x -> x.getId().equals(planTaskDetail.getProjectId())).findFirst().orElse(null); + + Site site = sites.stream().filter(x -> Objects.nonNull(userArchiveMapping) && x.getId().equals(userArchiveMapping.getSiteId())).findFirst().orElse(null); + + PlanTask planTask = planTasks.stream().filter(x -> x.getId().equals(planTaskDetail.getPlanTaskId())).findFirst().orElse(null); + + Plan plan = plans.stream().filter(x -> Objects.nonNull(planTask) && x.getId().equals(planTask.getPlanId())).findFirst().orElse(null); + + List<PlanTaskModuleRelate> relates = planMoudleRelates.stream().filter(x -> Objects.nonNull(planTask) && x.getPlanTaskId().equals(planTask.getId())).collect(Collectors.toList()); + + List<PlanTaskDetailsModule> modules = planTaskDetailsModules.stream().filter(x -> Objects.nonNull(planTaskDetail) && x.getPlanTaskDetailsId().equals(planTaskDetail.getId())).collect(Collectors.toList()); + + for (PlanTaskModuleRelate relate : relates) { + PlanModule planMoudle = new PlanModule(); + + planMoudle.setKey(planTaskDetail.getId() + String.valueOf(relate.getId())); + + if (Objects.nonNull(userArchive)) { + planMoudle.setSubjectId(userArchive.getSubjectId()); + planMoudle.setRandomizationId(userArchive.getRandomizationId()); + } + + if (Objects.nonNull(project)) { + + planMoudle.setProjectName(project.getName()); + } + if (Objects.nonNull(site)) { + planMoudle.setSiteName(site.getSiteName()); + } + + if (Objects.nonNull(plan)) { + planMoudle.setPlanId(plan.getId()); + planMoudle.setPlanCode(plan.getNumber()); + planMoudle.setPlanEffectiveDate(parseTimeFromDate(plan.getEffectiveDate())); + planMoudle.setPlanDuration(plan.getDays()); + } + + if (Objects.nonNull(planTask)) { + planMoudle.setPlanTaskName(planTask.getName()); + planMoudle.setPlanTaskdescription(planTask.getDescription()); + planMoudle.setPlanTaskType(planTask.getTaskType()); + planMoudle.setPlanTaskTaskCount(planTask.getTaskCount()); + planMoudle.setPlanTaskFinishDay(planTask.getFinishDay()); + planMoudle.setPlanTaskLoopType(planTask.getLoopType()); + planMoudle.setPlanTaskEnabled(planTask.getEnabled()); + planMoudle.setPlanTaskIsCirculation(planTask.getIsCirculation()); + planMoudle.setPlanTaskBeginDay(planTask.getBeginDay()); + planMoudle.setPlanTaskCirculationDay(planTask.getCirculationDay()); + planMoudle.setPlanTaskWindowPhase(planTask.getWindowPhase()); + planMoudle.setPlanTaskEndDay(planTask.getEndDay()); + } + + if (Objects.nonNull(planTaskDetail)) { + planMoudle.setProjectCode(String.valueOf(planTaskDetail.getProjectId())); + planMoudle.setTaskStartDate(planTaskDetail.getStartDate()); + planMoudle.setTaskEndDate(planTaskDetail.getEndDate()); + planMoudle.setTaskCompleteStatus(planTaskDetail.getCompleteStatus()); + planMoudle.setTaskCompleteTime(planTaskDetail.getCompleteTime()); + planMoudle.setTaskEnabled(planTaskDetail.getEnabled()); + planMoudle.setTaskCompleteOrder(planTaskDetail.getCompleteOrder()); + } + + if (Objects.nonNull(relate)) { + planMoudle.setModuleType(relate.getRelationType()); + planMoudle.setModuleId(relate.getRelationId()); + } + + if (MapUtil.isNotEmpty(relationNameMap) && Objects.nonNull(relationNameMap.get(relate.getRelationId()))) { + planMoudle.setModuleName(relationNameMap.get(relate.getRelationId())); + } + + if (MapUtil.isNotEmpty(resultMap)) { + Map<String, String> planTaskDetailMap = resultMap.get(planTaskDetail.getId()); + + if (MapUtil.isNotEmpty(planTaskDetailMap)) { + String result = planTaskDetailMap.get(String.valueOf(relate.getRelationId())); + if (!StringUtils.isEmpty(result)) { + planMoudle.setResult(result); + } + } + } + + if (relate.getRelationType().equals("DIGITAL_MEDICAL")) { + if (MapUtil.isNotEmpty(digitalMedicalEventMap)) { + Map<Long, Long> eventMap = digitalMedicalEventMap.get(planTaskDetail.getId()); + if (MapUtil.isNotEmpty(eventMap)) { + Long eventId = eventMap.get(relate.getRelationId()); + if (Objects.nonNull(eventId)) { + planMoudle.setDigitalModuleEventId(eventId); + } + } + } + if (MapUtil.isNotEmpty(digitalMedicalTypeMap)) { + Map<Long, String> typeMap = digitalMedicalTypeMap.get(planTaskDetail.getId()); + if (MapUtil.isNotEmpty(typeMap)) { + String eventType = typeMap.get(relate.getRelationId()); + if (Objects.nonNull(eventType)) { + String tableName = TableEnum.getTableNameByType(eventType); + if (Objects.nonNull(tableName)) { + planMoudle.setDigitalModuleTableName(tableName); + } + } + } + } + } + + PlanTaskDetailsModule module = modules.stream().filter(x -> x.getRelationId().equals(relate.getRelationId())).findFirst().orElse(null); + if (Objects.nonNull(module)) { + planMoudle.setModuleComplete(module.getModuleComplete()); + planMoudle.setModuleIgnoreRemark(module.getIgnoreRemark()); + if (Objects.nonNull(module.getModuleComplete()) && module.getModuleComplete().equals(1)) { + planMoudle.setModuleFinishTime(module.getLastModifiedAt()); + } + } else { + planMoudle.setModuleComplete(0); + } + + // 是å¦ç¬¬ä¸€æ¬¡å…¨é‡æ’å…¥ + if (totalPlanModuleCount > 0) { + Query upsertQuery = new Query(Criteria.where("key").is(planMoudle.getKey())); + Update update = buildUpdate(planMoudle); + bulkOps.upsert(upsertQuery, update); + } + planMoudles.add(planMoudle); + } + } + + // 是å¦ç¬¬ä¸€æ¬¡å…¨é‡æ’å…¥ + if (totalPlanModuleCount > 0) { + bulkOps.execute(); + log.info("bulkOps 更新或新增:{} æ¡", planMoudles.size()); + } else { + if (!CollectionUtils.isEmpty(planMoudles)) { + mongoTemplate.insert(planMoudles, PlanModule.class); + log.info("mongoTemplate 直接新增:{} æ¡", planMoudles.size()); + } + } + + } + + log.info("synchronizePlanTask end, 耗时:{} ç§’", LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")) - now.toEpochSecond(ZoneOffset.of("+8"))); + + } + + private SynchronizeTime findSynchronizeTime() { + Query query = new Query().limit(1); + return mongoTemplate.findOne(query, SynchronizeTime.class); + } + + private void saveSynchronizeTime(SynchronizeTime synchronizeTime, LocalDateTime now) { + if (Objects.isNull(synchronizeTime)) { + SynchronizeTime time = new SynchronizeTime(); + time.setPlan(now); + mongoTemplate.save(time); + } else { + Query updateQuery = new Query(); + updateQuery.addCriteria(Criteria.where("_id").is(synchronizeTime.get_id())); + Update update = new Update(); + update.set("plan", now); + mongoTemplate.updateFirst(updateQuery, update, SynchronizeTime.class); + } + } + + private Update buildUpdate(PlanModule planMoudle) { + return new Update() + .set("key", planMoudle.getKey()) + .set("subjectId", planMoudle.getSubjectId()) + .set("randomizationId", planMoudle.getRandomizationId()) + .set("projectCode", planMoudle.getProjectCode()) + .set("projectName", planMoudle.getProjectName()) + .set("siteName", planMoudle.getSiteName()) + .set("planId", planMoudle.getPlanId()) + .set("planCode", planMoudle.getPlanCode()) + .set("planDuration", planMoudle.getPlanDuration()) + .set("planTaskName", planMoudle.getPlanTaskName()) + .set("planTaskdescription", planMoudle.getPlanTaskdescription()) + .set("planTaskType", planMoudle.getPlanTaskType()) + .set("planTaskTaskCount", planMoudle.getPlanTaskTaskCount()) + .set("planTaskFinishDay", planMoudle.getPlanTaskFinishDay()) + .set("planTaskLoopType", planMoudle.getPlanTaskLoopType()) + .set("planTaskEnabled", planMoudle.getPlanTaskEnabled()) + .set("planTaskIsCirculation", planMoudle.getPlanTaskIsCirculation()) + .set("planTaskBeginDay", planMoudle.getPlanTaskBeginDay()) + .set("planTaskCirculationDay", planMoudle.getPlanTaskCirculationDay()) + .set("planTaskWindowPhase", planMoudle.getPlanTaskWindowPhase()) + .set("planTaskEndDay", planMoudle.getPlanTaskEndDay()) + .set("taskStartDate", planMoudle.getTaskStartDate()) + .set("taskEndDate", planMoudle.getTaskEndDate()) + .set("taskCompleteStatus", planMoudle.getTaskCompleteStatus()) + .set("taskCompleteTime", planMoudle.getTaskCompleteTime()) + .set("taskEnabled", planMoudle.getTaskEndDate()) + .set("taskCompleteOrder", planMoudle.getTaskCompleteOrder()) + .set("moduleType", planMoudle.getModuleType()) + .set("moduleId", planMoudle.getModuleId()) + .set("moduleName", planMoudle.getModuleName()) + .set("moduleComplete", planMoudle.getModuleComplete()) + .set("moduleIgnoreRemark", planMoudle.getModuleIgnoreRemark()) + .set("moduleFinishTime", planMoudle.getModuleFinishTime()) + .set("result", planMoudle.getResult()) + .set("digitalModuleTableName", planMoudle.getDigitalModuleTableName()) + .set("digitalModuleEventId", planMoudle.getDigitalModuleEventId()) + .set("planEffectiveDate", planMoudle.getPlanEffectiveDate()); + } + + @Override + public void test() { + + } + + + private String parseTimeFromDate(LocalDate timeStr) { + LocalDateTime localDateTime = timeStr.atStartOfDay(); + DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + return localDateTime.format(fmt); + } + + private List<PlanTaskDetailsModule> queryPlanTaskDetaiMoudles(List<PlanTaskDetails> planTaskDetails) { + + Set<Long> planTskDetailIds = planTaskDetails.stream().map(PlanTaskDetails::getId).collect(Collectors.toSet()); + if (CollectionUtils.isEmpty(planTskDetailIds)) { + return new ArrayList<>(); + } + return mongoTemplate.find(new Query().addCriteria(Criteria.where("plan_task_details_id").in(planTskDetailIds)), PlanTaskDetailsModule.class); + + } + + private Map<Long, Map<Long, String>> queryDigitalMedicalType(List<PlanTaskDetails> planTaskDetails) { + Set<Long> planTskDetailIds = planTaskDetails.stream().map(PlanTaskDetails::getId).collect(Collectors.toSet()); + if (CollectionUtils.isEmpty(planTskDetailIds)) { + return new HashMap<>(); + } + + Map<Long, List<ClinicalTrialsEvent>> eventMap = mongoTemplate.find(new Query().addCriteria(Criteria.where("plan_details_id").in(planTskDetailIds).and("relation_type").is("DIGITAL_MEDICAL")), ClinicalTrialsEvent.class) + .stream().collect(Collectors.groupingBy(ClinicalTrialsEvent::getPlanDetailsId)); + + Map<Long, Map<Long, String>> map = new HashMap<>(); + eventMap.forEach((k, v) -> { + Map<Long, String> innerMap = new HashMap<>(); + if (!CollectionUtils.isEmpty(v)) { + v.forEach(event -> { + innerMap.put(event.getRelationId(), event.getModuleItemType()); + }); + map.put(k, innerMap); + } + }); + + return map; + } + + private Map<Long, Map<Long, Long>> queryDigitalMedicalEvent(List<PlanTaskDetails> planTaskDetails) { + Set<Long> planTskDetailIds = planTaskDetails.stream().map(PlanTaskDetails::getId).collect(Collectors.toSet()); + if (CollectionUtils.isEmpty(planTskDetailIds)) { + return new HashMap<>(); + } + + Map<Long, List<ClinicalTrialsEvent>> eventMap = mongoTemplate.find(new Query().addCriteria(Criteria.where("plan_details_id").in(planTskDetailIds).and("relation_type").is("DIGITAL_MEDICAL")), ClinicalTrialsEvent.class) + .stream().collect(Collectors.groupingBy(ClinicalTrialsEvent::getPlanDetailsId)); + + Map<Long, Map<Long, Long>> map = new HashMap<>(); + eventMap.forEach((k, v) -> { + Map<Long, Long> innerMap = new HashMap<>(); + if (!CollectionUtils.isEmpty(v)) { + v.forEach(event -> { + innerMap.put(event.getRelationId(), event.getEventId()); + }); + map.put(k, innerMap); + } + }); + + return map; + } + + private Map<Long, Map<String, String>> queryPlanTaskDetailResult(List<PlanTaskDetails> planTaskDetails) { + Map<Long, Map<String, String>> map = new HashMap<>(); + Map<Long, Map<String, String>> scaleMap = queryScaleResult(planTaskDetails); + map.putAll(scaleMap); + Map<Long, Map<String, String>> questonaireMap = queryQuestionaireResult(planTaskDetails); + + questonaireMap.forEach((k, v) -> { + if (map.containsKey(k)) { + map.get(k).putAll(v); + } else { + map.put(k, v); + } + }); + + Map<Long, Map<String, String>> crfMap = queryCrfResult(planTaskDetails); + crfMap.forEach((k, v) -> { + if (map.containsKey(k)) { + map.get(k).putAll(v); + } else { + map.put(k, v); + } + }); + + return map; + } + + private Map<Long, Map<String, String>> queryCrfResult(List<PlanTaskDetails> planTaskDetails) { + Set<Long> planTskDetailIds = planTaskDetails.stream().map(PlanTaskDetails::getId).collect(Collectors.toSet()); + if (CollectionUtils.isEmpty(planTskDetailIds)) { + return new HashMap<>(); + } + + List<CrfAnswer> crfAnswers = mongoTemplate.find(new Query().addCriteria(Criteria.where("plan_task_details_id").in(planTskDetailIds)), CrfAnswer.class); + + Map<Long, List<CrfAnswer>> crfAnswersMap = crfAnswers.stream().collect(Collectors.groupingBy(CrfAnswer::getPlanTaskDetailsId)); + + Set<Long> crfIds = crfAnswers.stream().map(CrfAnswer::getCrfId).collect(Collectors.toSet()); + Map<Long, String> crfMap = mongoTemplate.find(new Query().addCriteria(Criteria.where("id").in(crfIds)), Crf.class) + .stream().collect(Collectors.toMap(Crf::getId, Crf::getQuestionJson, (k1, k2) -> k2)); + + Map<Long, Map<String, String>> map = new HashMap<>(); + crfAnswersMap.forEach((k, v) -> { + if (!CollectionUtils.isEmpty(v)) { + Map<String, String> innerMap = new HashMap<>(); + v.forEach(crfAnswer -> { + String questionJson = crfMap.get(crfAnswer.getCrfId()); + if (Objects.nonNull(questionJson) && Objects.nonNull(crfAnswer.getAnswerJson())) { + try { + String result = CrfUtil.parseCrfProblemAndAnswer(questionJson, crfAnswer.getAnswerJson()); + if (Objects.nonNull(result)) { + innerMap.put(crfAnswer.getCrfTopId().toString(), result); + } + } catch (Exception e) { + e.printStackTrace(); + + } + } + }); + map.put(k, innerMap); + } + }); + + return map; + } + + private Map<Long, Map<String, String>> queryQuestionaireResult(List<PlanTaskDetails> planTaskDetails) { + Set<Long> planTskDetailIds = planTaskDetails.stream().map(PlanTaskDetails::getId).collect(Collectors.toSet()); + if (CollectionUtils.isEmpty(planTskDetailIds)) { + return new HashMap<>(); + } + + List<QuestionnaireAnswerRecord> records = mongoTemplate.find(new Query().addCriteria(Criteria.where("plan_task_details_id").in(planTskDetailIds)), QuestionnaireAnswerRecord.class); + + if (CollectionUtils.isEmpty(records)) { + return new HashMap<>(); + } + + Set<Long> recordIds = records.stream().map(QuestionnaireAnswerRecord::getId).collect(Collectors.toSet()); + List<QuestionnaireAnswer> answers = mongoTemplate.find(new Query().addCriteria(Criteria.where("record_id").in(recordIds)), QuestionnaireAnswer.class); + + Set<Long> ansowerIds = answers.stream().map(QuestionnaireAnswer::getId).collect(Collectors.toSet()); + List<QuestionnaireAnswerOption> answerOptions = mongoTemplate.find(new Query().addCriteria(Criteria.where("answer_id").in(ansowerIds)), QuestionnaireAnswerOption.class); + + Map<Long, Map<String, String>> map = new HashMap<>(); + + for (QuestionnaireAnswerRecord record : records) { + + List<QuestionnaireAnswer> answerList = answers.stream().filter(x -> x.getRecordId().equals(record.getId())).collect(Collectors.toList()); + + Map<String, String> resultMap = new HashMap<>(); + List<String> keyValueNewVos = new ArrayList<>(); + for (QuestionnaireAnswer answer : answerList) { + Stream<QuestionnaireAnswerOption> questionnaireAnswerOptionStream = answerOptions.stream().filter(x -> x.getAnswerId().equals(answer.getId()) && x.getQuestionId().equals(answer.getQuestionId())); + Optional<QuestionnaireAnswerOption> optionalAnswerOption = questionnaireAnswerOptionStream.findAny(); + + switch (answer.getType()) { + case "CHOICE": + keyValueNewVos.add(answer.getQuestionName() + ":" + optionalAnswerOption.map(QuestionnaireAnswerOption::getOptionName).orElse("-")); + break; + case "SLIDE": + case "DATE_SELECT": + case "NUMBER": + keyValueNewVos.add(answer.getQuestionName() + ":" + optionalAnswerOption.map(option -> String.valueOf(option.getNumberAnswer())).orElse("-")); + break; + case "MULTIPLE_CHOICE": + List<String> optionNames = answerOptions.stream() + .filter(x -> x.getAnswerId().equals(answer.getId()) && x.getQuestionId().equals(answer.getQuestionId())) + .map(QuestionnaireAnswerOption::getOptionName) + .collect(Collectors.toList()); + keyValueNewVos.add(answer.getQuestionName() + ":" + (optionNames.isEmpty() ? "-" : String.join(",", optionNames))); + break; + case "DATE": + keyValueNewVos.add(answer.getQuestionName() + ":" + optionalAnswerOption.map(QuestionnaireAnswerOption::getDateAt).orElse("-")); + break; + + case "SECTION_NUMBER": + keyValueNewVos.add(answer.getQuestionName() + ":" + (optionalAnswerOption.map(option -> option.getLeftMin() + "-" + option.getRightMax()).orElse("-"))); + break; + case "TEXT": + keyValueNewVos.add(answer.getQuestionName() + ":" + optionalAnswerOption.map(QuestionnaireAnswerOption::getContent).orElse("-")); + break; + } + } + resultMap.put(String.valueOf(record.getTopId()), JSONUtil.toJsonStr(keyValueNewVos)); + map.put(record.getPlanTaskDetailsId(), resultMap); + } + + return map; + } + + private Map<Long, Map<String, String>> queryScaleResult(List<PlanTaskDetails> planTaskDetails) { + Set<Long> planTskDetailIds = planTaskDetails.stream().map(PlanTaskDetails::getId).collect(Collectors.toSet()); + if (CollectionUtils.isEmpty(planTskDetailIds)) { + return new HashMap<>(); + } + + Map<Long, List<PatientScaleEvaluatingEntity>> scaleEvaluatMap = + mongoTemplate.find(new Query().addCriteria(Criteria.where("plan_task_details_id").in(planTskDetailIds)), PatientScaleEvaluatingEntity.class) + .stream().collect(Collectors.groupingBy(PatientScaleEvaluatingEntity::getPlanTaskDetailsId)); + + Map<Long, Map<String, String>> map = new HashMap<>(); + + scaleEvaluatMap.forEach((k, v) -> { + if (!CollectionUtils.isEmpty(v)) { + Map<String, String> result = new HashMap<>(); + v.forEach(item -> { + List<String> sb = new ArrayList<>(); + if (Objects.nonNull(item.getScaleResult())) { + sb.add("result:" + item.getScaleResult()); + } + if (Objects.nonNull(item.getTotalScore())) { + sb.add("totalScore:" + item.getTotalScore()); + } + if (!CollectionUtils.isEmpty(sb)) { + result.put(item.getScaleCode(), JSONUtil.toJsonStr(sb)); + } + + }); + + map.put(k, result); + } + }); + + return map; + } + + private Map<Long, String> queryRelateMoudleName(List<PlanTaskModuleRelate> planMoudleRelates) { + /** + * QUESTIONNAIRE 1 + * SCALE 1 + * DIGITAL_MEDICAL + * CRF 1 + * COLLECT_FLOW + * + * INTELLIGENT_DEVICE + * EXERCISE_MODULE + * + * E_DIARY + */ + Map<Long, String> map = new HashMap<>(); + List<Long> questionnaireIds = planMoudleRelates.stream().filter(relate -> relate.getRelationType().equals("QUESTIONNAIRE")).map(PlanTaskModuleRelate::getRelationId).collect(Collectors.toList()); + Map<Long, String> questionaireMap = mongoTemplate.find(new Query().addCriteria(Criteria.where("top_id").in(questionnaireIds)), Questionnaire.class) + .stream().collect(Collectors.toMap(Questionnaire::getTopId, Questionnaire::getName, (k1, k2) -> k2)); + if (MapUtil.isNotEmpty(questionaireMap)) { + map.putAll(questionaireMap); + } + + List<Long> crfTopIds = planMoudleRelates.stream().filter(relate -> relate.getRelationType().equals("CRF")).map(PlanTaskModuleRelate::getRelationId).collect(Collectors.toList()); + Map<Long, String> crfMap = mongoTemplate.find(new Query().addCriteria(Criteria.where("crf_top_id").in(crfTopIds)), Crf.class) + .stream().collect(Collectors.toMap(Crf::getCrfTopId, Crf::getName, (k1, k2) -> k2)); + if (MapUtil.isNotEmpty(crfMap)) { + map.putAll(crfMap); + } + + List<Long> scaleIds = planMoudleRelates.stream().filter(relate -> relate.getRelationType().equals("SCALE")).map(PlanTaskModuleRelate::getRelationId).collect(Collectors.toList()); + Map<Long, String> scaleMap = mongoTemplate.find(new Query().addCriteria(Criteria.where("id").in(scaleIds)), ScaleModuleDetailsEntity.class) + .stream().collect(Collectors.toMap(ScaleModuleDetailsEntity::getId, ScaleModuleDetailsEntity::getName, (k1, k2) -> k2)); + if (MapUtil.isNotEmpty(scaleMap)) { + map.putAll(scaleMap); + } + + List<Long> digitalMedicalIds = planMoudleRelates.stream().filter(relate -> relate.getRelationType().equals("DIGITAL_MEDICAL")).map(PlanTaskModuleRelate::getRelationId).collect(Collectors.toList()); + Map<Long, String> digitalMedicalMap = mongoTemplate.find(new Query().addCriteria(Criteria.where("id").in(digitalMedicalIds)), DigitalMedicalDetails.class) + .stream().collect(Collectors.toMap(DigitalMedicalDetails::getId, DigitalMedicalDetails::getName, (k1, k2) -> k2)); + if (MapUtil.isNotEmpty(digitalMedicalMap)) { + map.putAll(digitalMedicalMap); + } + + List<Long> collectMoudleIds = planMoudleRelates.stream().filter(relate -> relate.getRelationType().equals("COLLECT_FLOW")).map(PlanTaskModuleRelate::getRelationId).collect(Collectors.toList()); + Map<Long, String> collectMoudleMap = mongoTemplate.find(new Query().addCriteria(Criteria.where("id").in(collectMoudleIds)), CollectModule.class) + .stream().collect(Collectors.toMap(CollectModule::getId, CollectModule::getName, (k1, k2) -> k2)); + if (MapUtil.isNotEmpty(collectMoudleMap)) { + map.putAll(collectMoudleMap); + } + + return map; + } + + private List<UserArchiveMapping> queryArchiveMapping(List<PlanTaskDetails> planTaskDetails) { + List<String> patientCodes = planTaskDetails.stream().map(PlanTaskDetails::getPatientCode).collect(Collectors.toList()); + Query archiveMappingquery = new Query(); + archiveMappingquery.addCriteria(Criteria.where("patient_code").in(patientCodes)); + return mongoTemplate.find(archiveMappingquery, UserArchiveMapping.class); + } + + private List<PlanTaskModuleRelate> queryPlanMoudleRelates(List<PlanTask> planTasks) { + List<Long> planTaskIds = planTasks.stream().map(PlanTask::getId).collect(Collectors.toList()); + return mongoTemplate.find(new Query().addCriteria(Criteria.where("planTaskId").in(planTaskIds)), PlanTaskModuleRelate.class); + } + + private List<Site> querySites(List<UserArchiveMapping> userArchiveMappings) { + List<Long> siteIds = userArchiveMappings.stream().map(UserArchiveMapping::getSiteId).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(siteIds)) { + return new ArrayList<>(); + } + return mongoTemplate.find(new Query().addCriteria(Criteria.where("id").in(siteIds)), + Site.class); + } + + private List<Project> queryProjct(List<PlanTaskDetails> planTaskDetails) { + List<Long> projectIds = planTaskDetails.stream().map(PlanTaskDetails::getProjectId).collect(Collectors.toList()); + return mongoTemplate.find(new Query().addCriteria(Criteria.where("id").in(projectIds)), Project.class); + } + + private List<Plan> queryPlans(List<PlanTask> planTasks) { + List<Long> planIds = planTasks.stream().map(PlanTask::getPlanId).collect(Collectors.toList()); + return mongoTemplate.find(new Query().addCriteria(Criteria.where("id").in(planIds)), + Plan.class); + } + + private List<PlanTask> queryPlanTasks(List<PlanTaskDetails> planTaskDetails) { + List<Long> planTaskIds = planTaskDetails.stream().map(PlanTaskDetails::getPlanTaskId).collect(Collectors.toList()); + return mongoTemplate.find(new Query().addCriteria(Criteria.where("id").in(planTaskIds)), + PlanTask.class); + } + + private List<UserArchive> queryArchive(List<UserArchiveMapping> userArchiveMappings) { + List<String> archiveIds = userArchiveMappings + .stream().map(UserArchiveMapping::getUserArchiveId).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(archiveIds)) { + return new ArrayList<>(); + } + return mongoArchiveTemplate.find(new Query().addCriteria(Criteria.where("_id").in(archiveIds)), + UserArchive.class); + } +} diff --git a/src/main/java/com/luca/pilot/util/CrfUtil.java b/src/main/java/com/luca/pilot/util/CrfUtil.java new file mode 100644 index 0000000..6efcca4 --- /dev/null +++ b/src/main/java/com/luca/pilot/util/CrfUtil.java @@ -0,0 +1,228 @@ +package com.luca.pilot.util; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.Feature; +import com.luca.pilot.bizEnum.CrfQuestionTypeEnum; +import com.luca.pilot.bo.*; + +import java.util.*; +import java.util.stream.Collectors; + +public class CrfUtil { + + public static String parseCrfProblemAndAnswer(String crfProblemJson, String crfAswerJson) { + if (Objects.isNull(crfProblemJson) || "".equals(crfProblemJson) + || Objects.isNull(crfAswerJson) || "".equals(crfAswerJson)) { + return ""; + } + + List<CrfProblemBo> crfProblemBos = crfProblemJsonAnalysisNew(crfProblemJson); + + List<String> dataIds = crfProblemBos.stream().map(CrfProblemBo::getDataBo).filter(Objects::nonNull).collect(Collectors.toList()) + .stream().map(BindDataBo::getDataId).collect(Collectors.toList()); + + List<CrfJsonValueBo> crfJsonValueBos = crfJsonAnalysis(crfAswerJson); + + List<String> crfAswers = new ArrayList<>(); + crfJsonValueBos.stream().filter(x -> dataIds.contains(x.getKey())).forEach(item -> { + if (Objects.nonNull(item.getName()) && Objects.nonNull(item.getText())) { + crfAswers.add(item.getName() + ":" + item.getText()); + } + }); + if (CollectionUtil.isEmpty(crfAswers)) { + return null; + } + return JSONUtil.toJsonStr(crfAswers); + } + + /** + * crf 问题json è§£æž + */ + public static List<CrfProblemBo> crfProblemJsonAnalysisNew(String crfProblemJson) { + if (Objects.isNull(crfProblemJson) || "".equals(crfProblemJson)) { + return Collections.emptyList(); + } + var jsonObject = JSONObject.parseObject(crfProblemJson, Feature.OrderedField); + if (jsonObject == null) { + return Collections.emptyList(); + } + List<JSONObject> bos = new ArrayList<>(); + problemJsonNew(bos, jsonObject, null); + + if (CollectionUtil.isEmpty(bos)) { + return Collections.emptyList(); + } + return bos.stream().filter(item -> Objects.nonNull(item.get("questionType"))).map(item -> { + var crfProblemBo = new CrfProblemBo() + .setTitle(String.valueOf(item.get("title"))) + .setProperties(JSONObject.toJSONString(item.get("properties"))) + .setQuestionType(CrfQuestionTypeEnum.getDeviceEnum(JSONObject.toJSONString(item.get("questionType")).replace("\"", ""))); + var bindData = JSONObject.toJSONString(item.get("BindData")); + if (!"".equals(bindData)) { + crfProblemBo.setDataBo( + new BindDataBo() + .setDataId(JSONObject.parseObject(bindData).getString("dataId")) + .setDataType(JSONObject.parseObject(bindData).getString("dataType")) + .setChoiceField(JSONObject.parseObject(bindData).getString("choiceField")) + ); + } + return crfProblemBo; + }).collect(Collectors.toList()); + } + + private static void problemJsonNew(List<JSONObject> array, JSONObject data, String prefix) { + if (Objects.isNull(data)) { + return; + } + + var title = data.get("title"); + if (Objects.nonNull(prefix)) { + title = prefix + "," + title; + data.put("title", title); + + } + var properties = data.get("properties"); + if (Objects.isNull(properties)) { + var columns = data.get("columns"); + var defaultValue = data.get("defaultValue"); + if (Objects.isNull(defaultValue)) { + array.add(data); + return; + } + try { + var head = JSONObject.parseObject(data.get("BindData").toString(), Feature.OrderedField).get("dataId").toString(); + var columnsBos = JSONObject.parseArray(JSONObject.toJSONString(columns), CrfTableJsonTopicBo.class).stream() + .filter(bo -> !"title".equals(bo.getDataIndex())) // 去掉最左一列 dataIndex 为 title 的列 + .collect(Collectors.toList()); + var defaultValueBos = JSONObject.parseArray(JSONObject.toJSONString(defaultValue), CrfTableJsonTopicBo.class); + for (int i = 0; i < columnsBos.size(); i++) { + for (int j = 0; j < defaultValueBos.size(); j++) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("title", title + "," + defaultValueBos.get(j).getTitle() + "-" + columnsBos.get(i).getTitle()); + jsonObject.put("questionType", CrfQuestionTypeEnum.CRFTABLE.getCode()); + jsonObject.put("BindData", + new BindDataBo() + .setChoiceField("MH") + .setDataType("CUSTOMIZE") + .setDataId(head + "-" + columnsBos.get(i).getDataIndex() + "-" + defaultValueBos.get(j).getId()) + ); + array.add(jsonObject); + } + } + } catch (Exception e) { + array.add(data); + return; + } + return; + } + + var propertiesJsonObject = JSONObject.parseObject(properties.toString(), Feature.OrderedField); + array.add(data); + var keySet = propertiesJsonObject.keySet(); + var collect = keySet.stream().map(key -> JSONObject.parseObject(JSONObject.toJSONString(propertiesJsonObject.get(key)), Feature.OrderedField)).collect(Collectors.toList()); + for (JSONObject item : collect) { + problemJsonNew(array, item, Objects.nonNull(title) ? title.toString() : null); + } + } + + /** + * crf ç”æ¡ˆjson è§£æž + */ + public static List<CrfJsonValueBo> crfJsonAnalysis(String crfJson) { + Map<String, String> map = new HashMap<>(); + if (Objects.isNull(crfJson) || "".equals(crfJson)) { + return Collections.emptyList(); + } + var jsonObject = JSONObject.parseObject(crfJson); + if (jsonObject == null) { + return Collections.emptyList(); + } + var formStr = JSONObject.toJSONString(jsonObject.get("form")); + if ("".equals(formStr)) { + return Collections.emptyList(); + } + var array = JSONObject.parseArray(formStr, CrfJsonValueBo.class); + if (CollectionUtil.isNotEmpty(array)) { + var bos = jsonArray(array); + if (CollectionUtil.isEmpty(bos)) { + return Collections.emptyList(); + } + var collect = bos.stream().map(item -> { + try { + var boList = JSONObject.parseArray(item.getText(), CrfJsonValueKeyBo.class); + if (CollectionUtil.isEmpty(boList)) { + return null; + } + List<CrfJsonValueBo> valueBos = new ArrayList<>(); + var colKey = JSONObject.parseArray(boList.get(0).getColKey()); + for (int i = 0; i < colKey.size(); i++) { + for (CrfJsonValueKeyBo crfJsonValueKeyBo : boList) { + var valueArray = JSONObject.parseArray(crfJsonValueKeyBo.getValue()); + valueBos.add( + new CrfJsonValueBo() + .setKey(item.getKey() + "-" + colKey.get(i) + "-" + crfJsonValueKeyBo.getId()) + .setName(crfJsonValueKeyBo.getTitle()) + .setValue(crfJsonValueKeyBo.getValue()) + .setText(Objects.isNull(valueArray.get(i)) ? "-" : valueArray.get(i).toString()) + ); + } + } + return valueBos; + } catch (Exception e) { + // log.info("ã€COPD-DATA-DOCTOR】 ★ crf json è§£æžå¼‚常"); + return null; + } + }).filter(java.util.Objects::nonNull).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(collect)) { + collect.forEach(bos::addAll); + } + return bos.stream().peek(item -> { + item.setKeyPrefix(item.getKey()); + }).collect(Collectors.toList()); + } + return Collections.emptyList(); + } + + + /** + * é€’å½’è§£æž + * + * @param array + * @return + */ + private static List<CrfJsonValueBo> jsonArray(List<CrfJsonValueBo> array) { + var collect = array.stream().filter(item -> Objects.nonNull(item.getValue()) && !"".equals(item.getValue())).collect(Collectors.toList()); + if (CollectionUtil.isEmpty(collect)) { + return collect; + } + List<CrfJsonValueBo> bos = new ArrayList<>(); + for (CrfJsonValueBo item : collect) { + if (Objects.nonNull(item) && Objects.nonNull(item.getValue()) && !"".equals(item.getValue()) && !"null".equals(item.getValue())) { + try { + var boList = JSONObject.parseArray(item.getValue(), CrfJsonValueBo.class).stream().filter(Objects::nonNull).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(boList)) { + bos.addAll(jsonArray(boList)); + } + } catch (Exception e) { + continue; + } + } + } + collect.addAll(bos); + return collect; + } + + public static void main(String[] args) { + + String a = "{\"form\":[{\"name\":\"基本信æ¯\",\"key\":\"baseInfo_q2OjsA\",\"value\":[{\"key\":\"patientType\",\"name\":\"组别\",\"value\":null,\"text\":null},{\"key\":\"patientName\",\"name\":\"唯一识别ç \",\"value\":\"78N6A\",\"text\":\"78N6A\"},{\"key\":\"patientGender\",\"name\":\"性别\",\"value\":[\"F\"],\"text\":\"女\"},{\"key\":\"patientNation\",\"name\":\"æ°‘æ—\",\"value\":null,\"text\":null},{\"key\":\"patientBirthmonth\",\"name\":\"出生年月\",\"value\":\"19930509\",\"text\":\"19930509\"},{\"key\":\"patientAge\",\"name\":\"年龄\",\"value\":\"29\",\"text\":\"29 å²\"},{\"key\":\"patientHeight\",\"name\":\"身高\",\"value\":\"167\",\"text\":\"167 cm\"},{\"key\":\"patientWeight\",\"name\":\"体é‡\",\"value\":\"54\",\"text\":\"54 kg\"},{\"key\":\"tips\",\"name\":\"备注\",\"value\":null,\"text\":null}]},{\"name\":\"个人å²\",\"key\":\"smokeHistory_2NufHa\",\"value\":[{\"key\":\"smokeHis\",\"name\":\"å¸çƒŸå²\",\"value\":[\"2\"],\"text\":\"戒烟超过1å¹´\"},{\"key\":\"ApreviousSurgical\",\"name\":\"既往手术å²\",\"value\":null,\"text\":null},{\"key\":\"previousSurgical\",\"name\":\"既往手术å²-åç§°\",\"value\":null,\"text\":null},{\"key\":\"surgicalTime\",\"name\":\"手术时间(年月)\",\"value\":null,\"text\":null},{\"key\":\"AIndtoxins\",\"name\":\"工业毒物接触å²\",\"value\":[\"0\"],\"text\":\"æ— \"},{\"key\":\"Indtoxins\",\"name\":\"工业毒物接触时长\",\"value\":null,\"text\":null},{\"key\":\"AdustRemoval\",\"name\":\"粉尘接触\",\"value\":[\"1\"],\"text\":\"有\"},{\"key\":\"dustRemoval\",\"name\":\"粉尘接触时长\",\"value\":null,\"text\":null},{\"key\":\"Aradioactive\",\"name\":\"放射性物质接触\",\"value\":[\"0\"],\"text\":\"æ— \"},{\"key\":\"radioactive\",\"name\":\"放射性物质接触时长\",\"value\":null,\"text\":null},{\"key\":\"foodAllergies\",\"name\":\"食物过æ•å²\",\"value\":[\"no\"],\"text\":\"æ— \"},{\"key\":\"drugAllergies\",\"name\":\"è¯ç‰©è¿‡æ•å²\",\"value\":[\"yes\"],\"text\":\"有\"},{\"key\":\"drugAllergiesother\",\"name\":\"其他过æ•å²(如花粉)\",\"value\":null,\"text\":null},{\"key\":\"familyAllergies\",\"name\":\"父æ¯/ç¥–çˆ¶æ¯æ˜¯å¦æœ‰è¿‡æ•\",\"value\":[\"yes\"],\"text\":\"有\"},{\"key\":\"ispollutionpollution\",\"name\":\"æ˜¯å¦æ›¾é•¿æœŸï¼ˆå¤§äºŽäº”年)接触空气污染?\",\"value\":[\"no\"],\"text\":\"å¦\"},{\"key\":\"COVID\",\"name\":\"è¿‘1ä¸ªæœˆæ˜¯å¦æ–°å† 感染\",\"value\":[\"1\"],\"text\":\"是\"}]},{\"name\":\"现病å²(呼å¸ç³»ç»Ÿç–¾ç—…)-近两周\",\"key\":\"CM_history_45UfkY\",\"value\":[{\"key\":\"nowDiseaseTime\",\"name\":\"当å‰ç–¾ç—…è¯Šæ–æ—¶é—´\",\"value\":null,\"text\":null},{\"key\":\"isHot\",\"name\":\"å‘çƒ\",\"value\":null,\"text\":null},{\"key\":\"nasalObstruction\",\"name\":\"鼻塞\",\"value\":null,\"text\":null},{\"key\":\"runNose\",\"name\":\"æµæ¶•\",\"value\":null,\"text\":null},{\"key\":\"frequency\",\"name\":\"咳嗽(没有感冒时)\",\"value\":null,\"text\":null},{\"key\":\"expectoration\",\"name\":\"咳痰é‡\",\"value\":null,\"text\":null},{\"key\":\"vomicaNt\",\"name\":\"咳脓痰\",\"value\":null,\"text\":null},{\"key\":\"pant\",\"name\":\"呼å¸å›°éš¾\",\"value\":null,\"text\":null},{\"key\":\"isBlood\",\"name\":\"咯血\",\"value\":null,\"text\":null},{\"key\":\"chestPain\",\"name\":\"胸痛\",\"value\":null,\"text\":null},{\"key\":\"otherqtzz\",\"name\":\"其他症状\",\"value\":null,\"text\":null},{\"key\":\"everyDayBreathBad\",\"name\":\"æ¯å¤©éƒ½æœ‰å‘¼å¸ç—‡çŠ¶ï¼Œåœ¨ä½“åŠ›æ´»åŠ¨ä¹‹åŽå–˜æ†‹åŠ é‡\",\"value\":null,\"text\":null},{\"key\":\"nowWorseAir\",\"name\":\"是å¦é‡åˆ°åˆºæ¿€æ€§æ°”体ç‰è¿‡æ•性物质,或者情绪激动时,会引å‘呼å¸é“症状,但是之åŽèƒ½æ¢å¤æ£å¸¸\",\"value\":null,\"text\":null},{\"key\":\"NDDrugNameis\",\"name\":\"æ˜¯å¦æœ‰è¯ç‰©æ²»ç–—\",\"value\":null,\"text\":null},{\"key\":\"XBSHDetail\",\"name\":\"治疗è¯ç‰©è¯¦æƒ…(è¯ç‰©åç§°/剂é‡/ç»™è¯é€”径/频率)\",\"value\":null,\"text\":null}]},{\"name\":\"现病å²(其他呼å¸ç³»ç»Ÿç–¾ç—…)\",\"key\":\"CMO_history_g3RXLT\",\"value\":[{\"key\":\"isHaveOtherBreath\",\"name\":\"æ˜¯å¦æœ‰å…¶ä»–呼å¸ç³»ç»Ÿç–¾ç—…\",\"value\":null,\"text\":null},{\"key\":\"otherDiseaseTime\",\"name\":\"è¯Šæ–æ—¶é—´\",\"value\":null,\"text\":null},{\"key\":\"otherDiseaseName\",\"name\":\"疾病åç§°\",\"value\":null,\"text\":null},{\"key\":\"NDOBDrugNameis\",\"name\":\"æ˜¯å¦æœ‰è¯ç‰©æ²»ç–—\",\"value\":null,\"text\":null},{\"key\":\"XBSOBDetail\",\"name\":\"治疗è¯ç‰©è¯¦æƒ…(è¯ç‰©åç§°/剂é‡/ç»™è¯é€”径/频率)\",\"value\":null,\"text\":null}]},{\"name\":\"现病å²(éžå‘¼å¸ç³»ç»Ÿç–¾ç—…)\",\"key\":\"CMF_history_q4Z5Br\",\"value\":[{\"key\":\"isHaveFBreath\",\"name\":\"æ˜¯å¦æœ‰éžå‘¼å¸ç³»ç»Ÿç–¾ç—…\",\"value\":null,\"text\":null},{\"key\":\"FDiseaseTime\",\"name\":\"è¯Šæ–æ—¶é—´\",\"value\":null,\"text\":null},{\"key\":\"FDiseaseName\",\"name\":\"疾病åç§°\",\"value\":null,\"text\":null},{\"key\":\"NDFDrugNameis\",\"name\":\"æ˜¯å¦æœ‰è¯ç‰©æ²»ç–—\",\"value\":null,\"text\":null},{\"key\":\"XBSFDetail\",\"name\":\"治疗è¯ç‰©è¯¦æƒ…(è¯ç‰©åç§°/剂é‡/ç»™è¯é€”径/频率)\",\"value\":null,\"text\":null}]},{\"name\":\"COPD过去1å¹´å†…æ€¥æ€§åŠ é‡æƒ…况(ä»…COPD患者填写)\",\"key\":\"AEstatus_j4CJXr\",\"value\":[{\"key\":\"AETimes\",\"name\":\"AE总次数\",\"value\":null,\"text\":null},{\"key\":\"MidAE\",\"name\":\"ä¸åº¦AE\",\"value\":null,\"text\":null},{\"key\":\"highAE\",\"name\":\"é‡åº¦AE\",\"value\":null,\"text\":null}]},{\"name\":\"HRCT\",\"key\":\"lungCTcheck_qHV_iL\",\"value\":[{\"key\":\"HRCTclear\",\"name\":\"是å¦å·²å®ŒæˆHRCT检查\",\"value\":null,\"text\":null},{\"key\":\"HRCTtime\",\"name\":\"HRCT检查日期\",\"value\":null,\"text\":null},{\"key\":\"HRCTcheck\",\"name\":\"HRCT诊æ–\",\"value\":null,\"text\":null},{\"key\":\"HRCTdescribe\",\"name\":\"HRCTæè¿°\",\"value\":null,\"text\":null}]},{\"name\":\"胸部X线\",\"key\":\"lungCTcheckLower_DPV4NP\",\"value\":[{\"key\":\"chestXDateclear\",\"name\":\"是å¦å·²å®Œæˆèƒ¸éƒ¨X线检查\",\"value\":null,\"text\":null},{\"key\":\"chestXDate\",\"name\":\"胸部X线检查日期\",\"value\":null,\"text\":null},{\"key\":\"chestXresult\",\"name\":\"胸部X线检查结果\",\"value\":null,\"text\":null},{\"key\":\"chestXdescribe\",\"name\":\"胸部X线检查æè¿°\",\"value\":null,\"text\":null}]},{\"name\":\"肺功能(哮喘与COPD必填)\",\"key\":\"lungFunction_inf_PtaUZb\",\"value\":[{\"key\":\"zqgkzjEight\",\"name\":\"是å¦åœæ”¯æ°”ç®¡èˆ’å¼ å‰‚æˆ–æ¿€ç´ ç±»8h以上\",\"value\":null,\"text\":null},{\"key\":\"pulResult\",\"name\":\"èˆ’å¼ è¯•éªŒ\",\"value\":null,\"text\":null},{\"key\":\"sdacJl\",\"name\":\"æ²™ä¸èƒºé†‡å¸å…¥å‰‚é‡\",\"value\":null,\"text\":null},{\"key\":\"before\",\"name\":\"æ”¯æ°”ç®¡æ‰©å¼ å‰‚å¸å…¥å‰\",\"value\":[{\"predicted\":\"--\",\"real\":\"--\",\"percent\":\"--\",\"id\":\"0\",\"title\":\"FEV1%\"},{\"predicted\":\"--\",\"real\":\"--\",\"percent\":\"--\",\"id\":\"1\",\"title\":\"FEV1\"},{\"predicted\":\"--\",\"real\":\"--\",\"percent\":\"--\",\"id\":\"2\",\"title\":\"FVC\"},{\"predicted\":\"--\",\"real\":\"--\",\"percent\":\"--\",\"id\":\"3\",\"title\":\"FEV1/FVC\"}],\"text\":[{\"title\":\"FEV1%\",\"value\":[\"--\",\"--\",\"--\"],\"colKey\":[\"predicted\",\"real\",\"percent\"],\"colName\":[\"预计值\",\"剿¬¡\",\"å‰/预\"],\"id\":\"0\"},{\"title\":\"FEV1\",\"value\":[\"--\",\"--\",\"--\"],\"colKey\":[\"predicted\",\"real\",\"percent\"],\"colName\":[\"预计值\",\"剿¬¡\",\"å‰/预\"],\"id\":\"1\"},{\"title\":\"FVC\",\"value\":[\"--\",\"--\",\"--\"],\"colKey\":[\"predicted\",\"real\",\"percent\"],\"colName\":[\"预计值\",\"剿¬¡\",\"å‰/预\"],\"id\":\"2\"},{\"title\":\"FEV1/FVC\",\"value\":[\"--\",\"--\",\"--\"],\"colKey\":[\"predicted\",\"real\",\"percent\"],\"colName\":[\"预计值\",\"剿¬¡\",\"å‰/预\"],\"id\":\"3\"}]},{\"key\":\"after\",\"name\":\"æ”¯æ°”ç®¡æ‰©å¼ å‰‚å¸å…¥åŽ\",\"value\":[{\"real\":\"--\",\"percent\":\"--\",\"better\":\"--\",\"id\":\"0\",\"title\":\"FEV1%\"},{\"real\":\"--\",\"percent\":\"--\",\"better\":\"--\",\"id\":\"1\",\"title\":\"FEV1\"},{\"real\":\"--\",\"percent\":\"--\",\"better\":\"--\",\"id\":\"2\",\"title\":\"FVC\"},{\"real\":\"--\",\"percent\":\"--\",\"better\":\"--\",\"id\":\"3\",\"title\":\"FEV1/FVC\"}],\"text\":[{\"title\":\"FEV1%\",\"value\":[\"--\",\"--\",\"--\"],\"colKey\":[\"real\",\"percent\",\"better\"],\"colName\":[\"åŽæ¬¡\",\"åŽ/预\",\"改善率\"],\"id\":\"0\"},{\"title\":\"FEV1\",\"value\":[\"--\",\"--\",\"--\"],\"colKey\":[\"real\",\"percent\",\"better\"],\"colName\":[\"åŽæ¬¡\",\"åŽ/预\",\"改善率\"],\"id\":\"1\"},{\"title\":\"FVC\",\"value\":[\"--\",\"--\",\"--\"],\"colKey\":[\"real\",\"percent\",\"better\"],\"colName\":[\"åŽæ¬¡\",\"åŽ/预\",\"改善率\"],\"id\":\"2\"},{\"title\":\"FEV1/FVC\",\"value\":[\"--\",\"--\",\"--\"],\"colKey\":[\"real\",\"percent\",\"better\"],\"colName\":[\"åŽæ¬¡\",\"åŽ/预\",\"改善率\"],\"id\":\"3\"}]}]}],\"crfId\":\"1828353427575558144\",\"answer\":{\"patientName\":\"78N6A\",\"patientGender\":[\"F\"],\"patientPhone\":\"\",\"patientBirth\":\"\",\"patientHeight\":\"167\",\"patientWeight\":\"54\",\"patientAge\":\"29\",\"patientBirthmonth\":\"19930509\",\"smokeHis\":[\"2\"],\"AIndtoxins\":[\"0\"],\"AdustRemoval\":[\"1\"],\"Aradioactive\":[\"0\"],\"foodAllergies\":[\"no\"],\"drugAllergies\":[\"yes\"],\"familyAllergies\":[\"yes\"],\"ispollutionpollution\":[\"no\"],\"COVID\":[\"1\"],\"before\":[{\"id\":\"0\",\"title\":\"FEV1%\"},{\"id\":\"1\",\"title\":\"FEV1\"},{\"id\":\"2\",\"title\":\"FVC\"},{\"id\":\"3\",\"title\":\"FEV1/FVC\"}],\"after\":[{\"id\":\"0\",\"title\":\"FEV1%\"},{\"id\":\"1\",\"title\":\"FEV1\"},{\"id\":\"2\",\"title\":\"FVC\"},{\"id\":\"3\",\"title\":\"FEV1/FVC\"}]}}"; + String form = "{\"displayType\":\"column\",\"code\":\"patient_inf\",\"name\":\"患者录入表å•\",\"type\":\"object\",\"properties\":{\"baseInfo_q2OjsA\":{\"type\":\"object\",\"description\":\"\",\"title\":\"基本信æ¯\",\"questionType\":\"TEMPLATE\",\"lucaBanpickDataId\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"DM\",\"dataId\":\"baseInfo\"},\"properties\":{\"radio_pZJcYQ\":{\"title\":\"组别\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"patientType\"},\"options\":[{\"id\":\"0\",\"name\":\"COPD\",\"code\":\"1\"},{\"id\":\"1\",\"name\":\"支气管哮喘\",\"code\":\"2\"},{\"id\":\"2\",\"name\":\"æ”¯æ°”ç®¡æ‰©å¼ \",\"code\":\"3\"},{\"id\":\"3\",\"name\":\"上呼å¸é“感染\",\"code\":\"4\"},{\"id\":\"4\",\"name\":\"下呼å¸é“感染\",\"code\":\"5\"},{\"id\":\"5\",\"name\":\"慢性支气管炎\",\"code\":\"7\"},{\"id\":\"6\",\"name\":\"咳嗽\",\"code\":\"8\"},{\"id\":\"7\",\"name\":\"å¥åº·äºº\",\"code\":\"6\"}],\"enum\":[\"1\",\"2\",\"3\",\"4\",\"5\",\"7\",\"8\",\"6\"],\"enumNames\":[\"COPD\",\"支气管哮喘\",\"æ”¯æ°”ç®¡æ‰©å¼ \",\"上呼å¸é“感染\",\"下呼å¸é“感染\",\"慢性支气管炎\",\"咳嗽\",\"å¥åº·äºº\"]},\"input_eI5d5N\":{\"title\":\"唯一识别ç \",\"type\":\"string\",\"questionType\":\"TEXT\",\"required\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"DM\",\"dataId\":\"patientName\"},\"rangeLength\":{\"min\":1,\"max\":5},\"min\":1,\"max\":5,\"show\":{\"questions\":[],\"options\":[]}},\"radio_2BZqLQ\":{\"title\":\"性别\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"required\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"DM\",\"dataId\":\"patientGender\"},\"options\":[{\"id\":\"0\",\"name\":\"ç”·\",\"code\":\"M\"},{\"id\":\"1\",\"name\":\"女\",\"code\":\"F\"}],\"enum\":[\"M\",\"F\"],\"enumNames\":[\"ç”·\",\"女\"]},\"input_1vS3p_\":{\"title\":\"æ°‘æ—\",\"type\":\"string\",\"questionType\":\"TEXT\",\"required\":false,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"patientNation\"},\"rangeLength\":{\"min\":0,\"max\":200},\"min\":0,\"max\":200},\"input_BBOEYs\":{\"title\":\"出生年月\",\"type\":\"string\",\"questionType\":\"TEXT\",\"description\":\"如1990å¹´12月,请输入199012\",\"required\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"patientBirthmonth\"},\"rangeLength\":{\"min\":0,\"max\":200},\"min\":0,\"max\":200},\"number_GfRINe\":{\"title\":\"年龄\",\"type\":\"number\",\"questionType\":\"NUMBER\",\"widget\":\"CrfInputNumber\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"patientAge\"},\"range\":{\"min\":0,\"max\":0},\"unit\":\"å²\",\"min\":0,\"max\":0,\"required\":true},\"number_xhJFdf\":{\"title\":\"身高\",\"type\":\"number\",\"questionType\":\"NUMBER\",\"widget\":\"CrfInputNumber\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"DM\",\"dataId\":\"patientHeight\"},\"range\":{\"min\":0,\"max\":0},\"unit\":\"cm\",\"min\":0,\"max\":0,\"required\":true},\"number_2NItPR\":{\"title\":\"体é‡\",\"type\":\"number\",\"questionType\":\"NUMBER\",\"widget\":\"CrfInputNumber\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"DM\",\"dataId\":\"patientWeight\"},\"range\":{\"min\":0,\"max\":0},\"unit\":\"kg\",\"min\":0,\"max\":0,\"required\":true},\"textarea_InDWcs\":{\"title\":\"备注\",\"type\":\"string\",\"format\":\"textarea\",\"questionType\":\"TEXTAREA\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"tips\"},\"rangeLength\":{\"min\":0,\"max\":400},\"min\":0,\"max\":400}}},\"smokeHistory_2NufHa\":{\"type\":\"object\",\"description\":\"\",\"title\":\"个人å²\",\"questionType\":\"TEMPLATE\",\"lucaBanpickDataId\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"DM\",\"dataId\":\"smokeHistory\"},\"required\":true,\"properties\":{\"radio_wxrmgo\":{\"title\":\"å¸çƒŸå²\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"required\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"smokeHis\"},\"options\":[{\"id\":\"0\",\"name\":\"æ£åœ¨å¸çƒŸ/戒烟未满1å¹´\",\"code\":\"1\"},{\"id\":\"1\",\"name\":\"戒烟超过1å¹´\",\"code\":\"2\"},{\"id\":\"2\",\"name\":\"从ä¸å¸çƒŸ\",\"code\":\"3\"}],\"enum\":[\"1\",\"2\",\"3\"],\"enumNames\":[\"æ£åœ¨å¸çƒŸ/戒烟未满1å¹´\",\"戒烟超过1å¹´\",\"从ä¸å¸çƒŸ\"]},\"radio_PjH1Z_\":{\"title\":\"既往手术å²\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"ApreviousSurgical\"},\"options\":[{\"id\":\"0\",\"name\":\"有\",\"code\":\"1\"},{\"id\":\"1\",\"name\":\"æ— \",\"code\":\"0\"}],\"enum\":[\"1\",\"0\"],\"enumNames\":[\"有\",\"æ— \"]},\"input_ELJeHV\":{\"title\":\"既往手术å²-åç§°\",\"type\":\"string\",\"questionType\":\"TEXT\",\"description\":\"\",\"required\":false,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"previousSurgical\"},\"rangeLength\":{\"min\":0,\"max\":200},\"min\":0,\"max\":200},\"input_meEqwd\":{\"title\":\"手术时间(年月)\",\"type\":\"string\",\"questionType\":\"TEXT\",\"description\":\"如1990å¹´12月,请输入199012\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"surgicalTime\"},\"rangeLength\":{\"min\":0,\"max\":200},\"min\":0,\"max\":200},\"radio_Sk6gDE\":{\"title\":\"工业毒物接触å²\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"required\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"AIndtoxins\"},\"options\":[{\"id\":\"0\",\"name\":\"有\",\"code\":\"1\"},{\"id\":\"1\",\"name\":\"æ— \",\"code\":\"0\"}],\"enum\":[\"1\",\"0\"],\"enumNames\":[\"有\",\"æ— \"]},\"number_ML7RDe\":{\"title\":\"工业毒物接触时长\",\"type\":\"number\",\"questionType\":\"NUMBER\",\"widget\":\"CrfInputNumber\",\"description\":\"\",\"required\":false,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"Indtoxins\"},\"range\":{\"min\":0,\"max\":0},\"unit\":\"å¹´\",\"min\":0,\"max\":0},\"radio_ksSICF\":{\"title\":\"粉尘接触\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"required\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"AdustRemoval\"},\"options\":[{\"id\":\"0\",\"name\":\"有\",\"code\":\"1\"},{\"id\":\"1\",\"name\":\"æ— \",\"code\":\"0\"}],\"enum\":[\"1\",\"0\"],\"enumNames\":[\"有\",\"æ— \"]},\"number_0Pj-iN\":{\"title\":\"粉尘接触时长\",\"type\":\"number\",\"questionType\":\"NUMBER\",\"widget\":\"CrfInputNumber\",\"description\":\"\",\"required\":false,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"dustRemoval\"},\"range\":{\"min\":0,\"max\":0},\"unit\":\"å¹´\",\"min\":0,\"max\":0},\"radio_IFLN4Y\":{\"title\":\"放射性物质接触\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"required\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"Aradioactive\"},\"options\":[{\"id\":\"0\",\"name\":\"有\",\"code\":\"1\"},{\"id\":\"1\",\"name\":\"æ— \",\"code\":\"0\"}],\"enum\":[\"1\",\"0\"],\"enumNames\":[\"有\",\"æ— \"]},\"number_xhGgoA\":{\"title\":\"放射性物质接触时长\",\"type\":\"number\",\"questionType\":\"NUMBER\",\"widget\":\"CrfInputNumber\",\"description\":\"\",\"required\":false,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"radioactive\"},\"range\":{\"min\":0,\"max\":0},\"unit\":\"å¹´\",\"min\":0,\"max\":0},\"radio_CoFBNM\":{\"title\":\"食物过æ•å²\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"description\":\"\",\"required\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"foodAllergies\"},\"options\":[{\"id\":\"0\",\"name\":\"有\",\"code\":\"yes\"},{\"id\":\"1\",\"name\":\"æ— \",\"code\":\"no\"}],\"enum\":[\"yes\",\"no\"],\"enumNames\":[\"有\",\"æ— \"]},\"radio_9lmZfk\":{\"title\":\"è¯ç‰©è¿‡æ•å²\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"required\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"drugAllergies\"},\"options\":[{\"id\":\"0\",\"name\":\"有\",\"code\":\"yes\"},{\"id\":\"1\",\"name\":\"æ— \",\"code\":\"no\"}],\"enum\":[\"yes\",\"no\"],\"enumNames\":[\"有\",\"æ— \"]},\"input_-LeeUZ\":{\"title\":\"其他过æ•å²(如花粉)\",\"type\":\"string\",\"questionType\":\"TEXT\",\"required\":false,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"drugAllergiesother\"},\"rangeLength\":{\"min\":0,\"max\":200},\"min\":0,\"max\":200},\"radio_VHyLEJ\":{\"title\":\"父æ¯/ç¥–çˆ¶æ¯æ˜¯å¦æœ‰è¿‡æ•\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"description\":\"è¿‡æ•æ€§é¼»ç‚Žã€æ¹¿ç–¹çš®è‚¤è¿‡æ•ã€é£Ÿç‰©è¿‡æ•ç‰\",\"required\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"familyAllergies\"},\"options\":[{\"id\":\"0\",\"name\":\"有\",\"code\":\"yes\"},{\"id\":\"1\",\"name\":\"æ— \",\"code\":\"no\"}],\"enum\":[\"yes\",\"no\"],\"enumNames\":[\"有\",\"æ— \"]},\"radio_nnqvcY\":{\"title\":\"æ˜¯å¦æ›¾é•¿æœŸï¼ˆå¤§äºŽäº”年)接触空气污染?\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"description\":\"空气污染包å«ç²‰å°˜ã€åˆºæ¿€æ°”体ã€éº»å°†å®¤èŒ¶é¦†å®¤äºŒæ‰‹çƒŸï¼Œæˆ–常年工作在化工ã€çººç»‡è½¦é—´ç‰æœ‰ç©ºæ°”污染的环境\",\"required\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"ispollutionpollution\"},\"options\":[{\"id\":\"0\",\"name\":\"是\",\"code\":\"yes\"},{\"id\":\"1\",\"name\":\"å¦\",\"code\":\"no\"}],\"enum\":[\"yes\",\"no\"],\"enumNames\":[\"是\",\"å¦\"]},\"radio_5veO9S\":{\"title\":\"è¿‘1ä¸ªæœˆæ˜¯å¦æ–°å† 感染\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"description\":\"鼻或咽æ‹å抗原/èšåˆé…¶é“¾å应 (PCR)检测阳性\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"COVID\"},\"options\":[{\"id\":\"0\",\"name\":\"是\",\"code\":\"1\"},{\"id\":\"1\",\"name\":\"å¦\",\"code\":\"2\"}],\"enum\":[\"1\",\"2\"],\"enumNames\":[\"是\",\"å¦\"],\"required\":true}}},\"CM_history_45UfkY\":{\"type\":\"object\",\"title\":\"现病å²(呼å¸ç³»ç»Ÿç–¾ç—…)-近两周\",\"description\":\"\",\"questionType\":\"TEMPLATE\",\"lucaBanpickDataId\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"DM\",\"dataId\":\"CM_history\"},\"properties\":{\"date_SZbSoa\":{\"title\":\"当å‰ç–¾ç—…è¯Šæ–æ—¶é—´\",\"type\":\"string\",\"format\":\"date\",\"questionType\":\"DATE\",\"widget\":\"CrfDatePick\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"nowDiseaseTime\"}},\"radio_RRlBks\":{\"title\":\"å‘çƒ\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"isHot\"},\"options\":[{\"id\":\"0\",\"name\":\"37.3~38℃\",\"code\":\"1\"},{\"id\":\"1\",\"name\":\"38.1~39℃\",\"code\":\"2\"},{\"id\":\"2\",\"name\":\"39.1~41℃\",\"code\":\"3\"},{\"id\":\"3\",\"name\":\"≥41℃\",\"code\":\"4\"}],\"enum\":[\"1\",\"2\",\"3\",\"4\"],\"enumNames\":[\"37.3~38℃\",\"38.1~39℃\",\"39.1~41℃\",\"≥41℃\"]},\"radio_9Wf2Pa\":{\"title\":\"鼻塞\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"nasalObstruction\"},\"options\":[{\"id\":\"0\",\"name\":\"有\",\"code\":\"yes\"},{\"id\":\"1\",\"name\":\"æ— \",\"code\":\"no\"}],\"enum\":[\"yes\",\"no\"],\"enumNames\":[\"有\",\"æ— \"]},\"radio_BKQTvO\":{\"title\":\"æµæ¶•\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"runNose\"},\"options\":[{\"id\":\"0\",\"name\":\"有\",\"code\":\"yes\"},{\"id\":\"1\",\"name\":\"æ— \",\"code\":\"no\"}],\"enum\":[\"yes\",\"no\"],\"enumNames\":[\"有\",\"æ— \"]},\"radio_3oCGKT\":{\"title\":\"咳嗽(没有感冒时)\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"VS\",\"dataId\":\"frequency\"},\"options\":[{\"id\":\"0\",\"name\":\"æ— æ˜Žæ˜¾å’³å—½\",\"code\":\"neverCough\"},{\"id\":\"1\",\"name\":\"早晨居多\",\"code\":\"mornMore\"},{\"id\":\"2\",\"name\":\"夜间居多\",\"code\":\"nightMore\"},{\"id\":\"3\",\"name\":\"免天嶿œ‰å’³å—½\",\"code\":\"occasionalCough\"},{\"id\":\"4\",\"name\":\"咳嗽频ç¹\",\"code\":\"frequentCough\"}],\"enum\":[\"neverCough\",\"mornMore\",\"nightMore\",\"occasionalCough\",\"frequentCough\"],\"enumNames\":[\"æ— æ˜Žæ˜¾å’³å—½\",\"早晨居多\",\"夜间居多\",\"免天嶿œ‰å’³å—½\",\"咳嗽频ç¹\"]},\"radio_4MD3cs\":{\"title\":\"咳痰é‡\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"VS\",\"dataId\":\"expectoration\"},\"options\":[{\"id\":\"0\",\"name\":\"æ— æ˜Žæ˜¾å’³ç—°\",\"code\":\"neverExpectorate\"},{\"id\":\"1\",\"name\":\"咳痰10ml以下\",\"code\":\"belowTen\"},{\"id\":\"2\",\"name\":\"咳痰10ml以上\",\"code\":\"aboveTen\"}],\"enum\":[\"neverExpectorate\",\"belowTen\",\"aboveTen\"],\"enumNames\":[\"æ— æ˜Žæ˜¾å’³ç—°\",\"咳痰10ml以下\",\"咳痰10ml以上\"]},\"radio_svNkPO\":{\"title\":\"咳脓痰\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"vomicaNt\"},\"options\":[{\"id\":\"0\",\"name\":\"有\",\"code\":\"yes\"},{\"id\":\"1\",\"name\":\"æ— \",\"code\":\"no\"}],\"enum\":[\"yes\",\"no\"],\"enumNames\":[\"有\",\"æ— \"]},\"radio_EKR86w\":{\"title\":\"呼å¸å›°éš¾\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"VS\",\"dataId\":\"pant\"},\"options\":[{\"id\":\"0\",\"name\":\"æ— \",\"code\":\"neverPant\"},{\"id\":\"1\",\"name\":\"剧烈活动时出现\",\"code\":\"occasionallyPant\"},{\"id\":\"2\",\"name\":\"日常活动时å‘ç”Ÿï¼Œä¼‘æ¯æ—¶ä¸å‘生\",\"code\":\"whenActive\"},{\"id\":\"3\",\"name\":\"å–˜æ¯ä¸èƒ½å¹³èººï¼Œå½±å“休æ¯ä¸Žæ´»åЍ\",\"code\":\"alwaysPant\"}],\"enum\":[\"neverPant\",\"occasionallyPant\",\"whenActive\",\"alwaysPant\"],\"enumNames\":[\"æ— \",\"剧烈活动时出现\",\"日常活动时å‘ç”Ÿï¼Œä¼‘æ¯æ—¶ä¸å‘生\",\"å–˜æ¯ä¸èƒ½å¹³èººï¼Œå½±å“休æ¯ä¸Žæ´»åЍ\"]},\"radio_H-oWj_\":{\"title\":\"咯血\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"isBlood\"},\"options\":[{\"id\":\"0\",\"name\":\"有\",\"code\":\"yes\"},{\"id\":\"1\",\"name\":\"æ— \",\"code\":\"no\"}],\"enum\":[\"yes\",\"no\"],\"enumNames\":[\"有\",\"æ— \"]},\"radio_iFybYL\":{\"title\":\"胸痛\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"chestPain\"},\"options\":[{\"id\":\"0\",\"name\":\"有\",\"code\":\"yes\"},{\"id\":\"1\",\"name\":\"æ— \",\"code\":\"no\"}],\"enum\":[\"yes\",\"no\"],\"enumNames\":[\"有\",\"æ— \"]},\"input_Tv2xuD\":{\"title\":\"其他症状\",\"type\":\"string\",\"questionType\":\"TEXT\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"otherqtzz\"},\"rangeLength\":{\"min\":0,\"max\":200},\"min\":0,\"max\":200},\"radio_pMRb1u\":{\"title\":\"æ¯å¤©éƒ½æœ‰å‘¼å¸ç—‡çŠ¶ï¼Œåœ¨ä½“åŠ›æ´»åŠ¨ä¹‹åŽå–˜æ†‹åŠ é‡\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"description\":\"å–˜æ¯ï¼Œå’³å—½ï¼Œå‘¼å¸å›°éš¾ï¼Œèƒ¸é—·æˆ–疼痛\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"everyDayBreathBad\"},\"options\":[{\"id\":\"0\",\"name\":\"是\",\"code\":\"yes\"},{\"id\":\"1\",\"name\":\"å¦\",\"code\":\"no\"}],\"enum\":[\"yes\",\"no\"],\"enumNames\":[\"是\",\"å¦\"]},\"radio_6FzCNg\":{\"title\":\"是å¦é‡åˆ°åˆºæ¿€æ€§æ°”体ç‰è¿‡æ•性物质,或者情绪激动时,会引å‘呼å¸é“症状,但是之åŽèƒ½æ¢å¤æ£å¸¸\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"description\":\"å–˜æ¯ï¼Œå’³å—½ï¼Œå‘¼å¸å›°éš¾ï¼Œèƒ¸é—·æˆ–疼痛\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"nowWorseAir\"},\"options\":[{\"id\":\"0\",\"name\":\"是\",\"code\":\"yes\"},{\"id\":\"1\",\"name\":\"å¦\",\"code\":\"no\"}],\"enum\":[\"yes\",\"no\"],\"enumNames\":[\"是\",\"å¦\"]},\"radio_mN0BSK\":{\"title\":\"æ˜¯å¦æœ‰è¯ç‰©æ²»ç–—\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"NDDrugNameis\"},\"options\":[{\"id\":\"0\",\"name\":\"有\",\"code\":\"1\"},{\"id\":\"1\",\"name\":\"æ— \",\"code\":\"0\"}],\"enum\":[\"1\",\"0\"],\"enumNames\":[\"有\",\"æ— \"]},\"textarea_VcEcqT\":{\"title\":\"治疗è¯ç‰©è¯¦æƒ…(è¯ç‰©åç§°/剂é‡/ç»™è¯é€”径/频率)\",\"type\":\"string\",\"format\":\"textarea\",\"questionType\":\"TEXTAREA\",\"description\":\"填写示例:è¯ç‰©1,2mgï¼Œå£æœï¼Œæ¯å¤©2次\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"XBSHDetail\"},\"rangeLength\":{\"min\":0,\"max\":400},\"min\":0,\"max\":400}}},\"CMO_history_g3RXLT\":{\"type\":\"object\",\"description\":\"\",\"title\":\"现病å²(其他呼å¸ç³»ç»Ÿç–¾ç—…)\",\"questionType\":\"TEMPLATE\",\"lucaBanpickDataId\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"DM\",\"dataId\":\"CMO_history\"},\"properties\":{\"radio_gmS0wy\":{\"title\":\"æ˜¯å¦æœ‰å…¶ä»–呼å¸ç³»ç»Ÿç–¾ç—…\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"isHaveOtherBreath\"},\"options\":[{\"id\":\"0\",\"name\":\"有\",\"code\":\"yes\"},{\"id\":\"1\",\"name\":\"æ— \",\"code\":\"no\"}],\"enum\":[\"yes\",\"no\"],\"enumNames\":[\"有\",\"æ— \"]},\"date_SZbSoa\":{\"title\":\"è¯Šæ–æ—¶é—´\",\"type\":\"string\",\"format\":\"date\",\"questionType\":\"DATE\",\"widget\":\"CrfDatePick\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"otherDiseaseTime\"}},\"input_sXY8NP\":{\"title\":\"疾病åç§°\",\"type\":\"string\",\"questionType\":\"TEXT\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"otherDiseaseName\"},\"rangeLength\":{\"min\":0,\"max\":200},\"min\":0,\"max\":200},\"radio_bsMHh_\":{\"title\":\"æ˜¯å¦æœ‰è¯ç‰©æ²»ç–—\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"NDOBDrugNameis\"},\"options\":[{\"id\":\"0\",\"name\":\"有\",\"code\":\"1\"},{\"id\":\"1\",\"name\":\"æ— \",\"code\":\"0\"}],\"enum\":[\"1\",\"0\"],\"enumNames\":[\"有\",\"æ— \"]},\"textarea_ju4cIb\":{\"title\":\"治疗è¯ç‰©è¯¦æƒ…(è¯ç‰©åç§°/剂é‡/ç»™è¯é€”径/频率)\",\"type\":\"string\",\"format\":\"textarea\",\"questionType\":\"TEXTAREA\",\"description\":\"填写示例:è¯ç‰©1,2mgï¼Œå£æœï¼Œæ¯å¤©2次\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"XBSOBDetail\"},\"rangeLength\":{\"min\":0,\"max\":400},\"min\":0,\"max\":400}}},\"CMF_history_q4Z5Br\":{\"type\":\"object\",\"description\":\"\",\"title\":\"现病å²(éžå‘¼å¸ç³»ç»Ÿç–¾ç—…)\",\"questionType\":\"TEMPLATE\",\"lucaBanpickDataId\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"DM\",\"dataId\":\"CMF_history\"},\"properties\":{\"radio_gmS0wy\":{\"title\":\"æ˜¯å¦æœ‰éžå‘¼å¸ç³»ç»Ÿç–¾ç—…\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"isHaveFBreath\"},\"options\":[{\"id\":\"0\",\"name\":\"有\",\"code\":\"yes\"},{\"id\":\"1\",\"name\":\"æ— \",\"code\":\"no\"}],\"enum\":[\"yes\",\"no\"],\"enumNames\":[\"有\",\"æ— \"]},\"date_SZbSoa\":{\"title\":\"è¯Šæ–æ—¶é—´\",\"type\":\"string\",\"format\":\"date\",\"questionType\":\"DATE\",\"widget\":\"CrfDatePick\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"FDiseaseTime\"}},\"input_sXY8NP\":{\"title\":\"疾病åç§°\",\"type\":\"string\",\"questionType\":\"TEXT\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"FDiseaseName\"},\"rangeLength\":{\"min\":0,\"max\":200},\"min\":0,\"max\":200},\"radio_Arisrv\":{\"title\":\"æ˜¯å¦æœ‰è¯ç‰©æ²»ç–—\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"NDFDrugNameis\"},\"options\":[{\"id\":\"0\",\"name\":\"有\",\"code\":\"1\"},{\"id\":\"1\",\"name\":\"æ— \",\"code\":\"0\"}],\"enum\":[\"1\",\"0\"],\"enumNames\":[\"有\",\"æ— \"]},\"textarea_FrL9N0\":{\"title\":\"治疗è¯ç‰©è¯¦æƒ…(è¯ç‰©åç§°/剂é‡/ç»™è¯é€”径/频率)\",\"type\":\"string\",\"format\":\"textarea\",\"questionType\":\"TEXTAREA\",\"description\":\"填写示例:è¯ç‰©1,2mgï¼Œå£æœï¼Œæ¯å¤©2次\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"XBSFDetail\"},\"rangeLength\":{\"min\":0,\"max\":400},\"min\":0,\"max\":400}}},\"AEstatus_j4CJXr\":{\"type\":\"object\",\"description\":\"\",\"title\":\"COPD过去1å¹´å†…æ€¥æ€§åŠ é‡æƒ…况(ä»…COPD患者填写)\",\"questionType\":\"TEMPLATE\",\"lucaBanpickDataId\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"DM\",\"dataId\":\"AEstatus\"},\"properties\":{\"number_d3YdWP\":{\"title\":\"AE总次数\",\"type\":\"number\",\"questionType\":\"NUMBER\",\"widget\":\"CrfInputNumber\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"AETimes\"},\"range\":{\"min\":0,\"max\":0},\"unit\":\"次\",\"min\":0,\"max\":0},\"number_s3YyoQ\":{\"title\":\"ä¸åº¦AE\",\"type\":\"number\",\"questionType\":\"NUMBER\",\"widget\":\"CrfInputNumber\",\"description\":\"ä½¿ç”¨çŸæ•ˆæ”¯æ°”ç®¡æ‰©å¼ å‰‚å’ŒæŠ—ç”Ÿç´ æ²»ç–—å’Œ/æˆ–å£æœç³–çš®è´¨æ¿€ç´ \",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"MidAE\"},\"range\":{\"min\":0,\"max\":0},\"unit\":\"次\",\"min\":0,\"max\":0},\"number_b5HNLY\":{\"title\":\"é‡åº¦AE\",\"type\":\"number\",\"questionType\":\"NUMBER\",\"widget\":\"CrfInputNumber\",\"description\":\"需è¦ä½é™¢æˆ–急诊ã€ICU 治疗\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"highAE\"},\"range\":{\"min\":0,\"max\":0},\"unit\":\"次\",\"min\":0,\"max\":0}}},\"lungCTcheck_qHV_iL\":{\"type\":\"object\",\"description\":\"\",\"title\":\"HRCT\",\"questionType\":\"TEMPLATE\",\"lucaBanpickDataId\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"DM\",\"dataId\":\"lungCTcheck\"},\"properties\":{\"radio_eQ7i2_\":{\"title\":\"是å¦å·²å®ŒæˆHRCT检查\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"HRCTclear\"},\"options\":[{\"id\":\"0\",\"name\":\"是\",\"code\":\"yes\"},{\"id\":\"1\",\"name\":\"å¦\",\"code\":\"no\"}],\"enum\":[\"yes\",\"no\"],\"enumNames\":[\"是\",\"å¦\"]},\"date_eLLo3o\":{\"title\":\"HRCT检查日期\",\"type\":\"string\",\"format\":\"date\",\"questionType\":\"DATE\",\"widget\":\"CrfDatePick\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"HRCTtime\"}},\"input_REgSRb\":{\"title\":\"HRCT诊æ–\",\"type\":\"string\",\"questionType\":\"TEXT\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"HRCTcheck\"},\"rangeLength\":{\"min\":0,\"max\":200},\"min\":0,\"max\":200},\"textarea_1nJhSZ\":{\"title\":\"HRCTæè¿°\",\"type\":\"string\",\"format\":\"textarea\",\"questionType\":\"TEXTAREA\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"HRCTdescribe\"},\"rangeLength\":{\"min\":0,\"max\":400},\"min\":0,\"max\":400}}},\"lungCTcheckLower_DPV4NP\":{\"type\":\"object\",\"description\":\"\",\"title\":\"胸部X线\",\"questionType\":\"TEMPLATE\",\"lucaBanpickDataId\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"DM\",\"dataId\":\"lungCTcheckLower\"},\"properties\":{\"radio_F3h09O\":{\"title\":\"是å¦å·²å®Œæˆèƒ¸éƒ¨X线检查\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"chestXDateclear\"},\"options\":[{\"id\":\"0\",\"name\":\"是\",\"code\":\"yes\"},{\"id\":\"1\",\"name\":\"å¦\",\"code\":\"no\"}],\"enum\":[\"yes\",\"no\"],\"enumNames\":[\"是\",\"å¦\"]},\"date_OPurFU\":{\"title\":\"胸部X线检查日期\",\"type\":\"string\",\"format\":\"date\",\"questionType\":\"DATE\",\"widget\":\"CrfDatePick\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"chestXDate\"}},\"input_GhAtyb\":{\"title\":\"胸部X线检查结果\",\"type\":\"string\",\"questionType\":\"TEXT\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"chestXresult\"},\"rangeLength\":{\"min\":0,\"max\":200},\"min\":0,\"max\":200},\"textarea_V0f1S3\":{\"title\":\"胸部X线检查æè¿°\",\"type\":\"string\",\"format\":\"textarea\",\"questionType\":\"TEXTAREA\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"chestXdescribe\"},\"rangeLength\":{\"min\":0,\"max\":400},\"min\":0,\"max\":400}}},\"lungFunction_inf_PtaUZb\":{\"type\":\"object\",\"description\":\"\",\"title\":\"肺功能(哮喘与COPD必填)\",\"questionType\":\"TEMPLATE\",\"lucaBanpickDataId\":true,\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"DM\",\"dataId\":\"lungFunction_inf\"},\"properties\":{\"radio_eiDPtt\":{\"title\":\"是å¦åœæ”¯æ°”ç®¡èˆ’å¼ å‰‚æˆ–æ¿€ç´ ç±»8h以上\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"zqgkzjEight\"},\"options\":[{\"id\":\"0\",\"name\":\"是\",\"code\":\"yes\"},{\"id\":\"1\",\"name\":\"å¦\",\"code\":\"no\"}],\"enum\":[\"yes\",\"no\"],\"enumNames\":[\"是\",\"å¦\"]},\"radio_TwQ-dW\":{\"title\":\"èˆ’å¼ è¯•éªŒ\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"pulResult\"},\"options\":[{\"id\":\"0\",\"name\":\"阳性\",\"code\":\"positive\"},{\"id\":\"1\",\"name\":\"阴性\",\"code\":\"negative\"}],\"enum\":[\"positive\",\"negative\"],\"enumNames\":[\"阳性\",\"阴性\"]},\"radio_g2D3JC\":{\"title\":\"æ²™ä¸èƒºé†‡å¸å…¥å‰‚é‡\",\"type\":\"string\",\"widget\":\"radio\",\"questionType\":\"RADIO\",\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"MH\",\"dataId\":\"sdacJl\"},\"options\":[{\"id\":\"0\",\"name\":\"100μg\",\"code\":\"1\"},{\"id\":\"1\",\"name\":\"200μg\",\"code\":\"2\"},{\"id\":\"2\",\"name\":\"400μg\",\"code\":\"3\"},{\"id\":\"3\",\"name\":\"ä¸è¯¦\",\"code\":\"4\"}],\"enum\":[\"1\",\"2\",\"3\",\"4\"],\"enumNames\":[\"100μg\",\"200μg\",\"400μg\",\"ä¸è¯¦\"]},\"newTabel_CeMggW\":{\"title\":\"æ”¯æ°”ç®¡æ‰©å¼ å‰‚å¸å…¥å‰\",\"type\":\"array\",\"questionType\":\"CRFTABLE\",\"widget\":\"CrfTable\",\"items\":{\"type\":\"object\",\"properties\":{}},\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"VS\",\"dataId\":\"before\"},\"columns\":[{\"id\":\"0\",\"title\":\"æŒ‡æ ‡\",\"dataIndex\":\"title\",\"type\":\"TEXT\"},{\"id\":\"1\",\"title\":\"预计值\",\"dataIndex\":\"predicted\",\"type\":\"INPUT\"},{\"id\":\"2\",\"title\":\"剿¬¡\",\"dataIndex\":\"real\",\"type\":\"INPUT\"},{\"id\":\"3\",\"title\":\"å‰/预\",\"dataIndex\":\"percent\",\"type\":\"INPUT\"}],\"defaultValue\":[{\"id\":\"0\",\"title\":\"FEV1%\"},{\"id\":\"1\",\"title\":\"FEV1\"},{\"id\":\"2\",\"title\":\"FVC\"},{\"id\":\"3\",\"title\":\"FEV1/FVC\"}],\"description\":\"\"},\"newTabel_U738QJ\":{\"title\":\"æ”¯æ°”ç®¡æ‰©å¼ å‰‚å¸å…¥åŽ\",\"type\":\"array\",\"questionType\":\"CRFTABLE\",\"widget\":\"CrfTable\",\"items\":{\"type\":\"object\",\"properties\":{}},\"BindData\":{\"dataType\":\"CUSTOMIZE\",\"choiceField\":\"DM\",\"dataId\":\"after\"},\"columns\":[{\"id\":\"0\",\"title\":\"æŒ‡æ ‡\",\"dataIndex\":\"title\",\"type\":\"TEXT\"},{\"id\":\"1\",\"title\":\"åŽæ¬¡\",\"dataIndex\":\"real\",\"type\":\"INPUT\"},{\"id\":\"2\",\"title\":\"åŽ/预\",\"dataIndex\":\"percent\",\"type\":\"INPUT\"},{\"id\":\"3\",\"title\":\"改善率\",\"dataIndex\":\"better\",\"type\":\"INPUT\"}],\"defaultValue\":[{\"id\":\"0\",\"title\":\"FEV1%\"},{\"id\":\"1\",\"title\":\"FEV1\"},{\"id\":\"2\",\"title\":\"FVC\"},{\"id\":\"3\",\"title\":\"FEV1/FVC\"}],\"description\":\"\"}}}}}"; + + System.out.println(JSONUtil.toJsonStr(crfProblemJsonAnalysisNew(form))); + System.out.println(JSONUtil.toJsonStr(crfJsonAnalysis(a))); + + System.out.println(parseCrfProblemAndAnswer(form, a)); + } + +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml new file mode 100644 index 0000000..ba66105 --- /dev/null +++ b/src/main/resources/application-dev.yml @@ -0,0 +1,11 @@ +# server +SERVER-PORT: 8181 + +#MGDB +MGDB-ADDRESS: 47.92.245.13:30606 +MGDB-NAME: root +MGDB-PASSWORD: 123456 +MGDB-DATABASE: luca-copy-dev +MGDB-AUTHSOURCE: admin + +ARCHIVE-MGDB-DATABASE: luca_dev diff --git a/src/main/resources/application-hj.yml b/src/main/resources/application-hj.yml new file mode 100644 index 0000000..24c2218 --- /dev/null +++ b/src/main/resources/application-hj.yml @@ -0,0 +1,15 @@ +# server +SERVER-PORT: 8181 + +#MGDB +MGDB-ADDRESS: 47.92.245.13:30606 +MGDB-NAME: root +MGDB-PASSWORD: 123456 +MGDB-DATABASE: luca-copy-dev +#MGDB-DATABASE: luca-copy-uat +MGDB-AUTHSOURCE: admin + +ARCHIVE-MGDB-DATABASE: luca_dev +#ARCHIVE-MGDB-DATABASE: luca_uat + + diff --git a/src/main/resources/application-uat.yml b/src/main/resources/application-uat.yml new file mode 100644 index 0000000..830c610 --- /dev/null +++ b/src/main/resources/application-uat.yml @@ -0,0 +1,13 @@ +# server +SERVER-PORT: 8181 + +#MGDB +MGDB-ADDRESS: 47.92.245.13:30606 +MGDB-NAME: root +MGDB-PASSWORD: 123456 +MGDB-DATABASE: luca-copy-uat +MGDB-AUTHSOURCE: admin + +ARCHIVE-MGDB-DATABASE: luca_uat + + diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..5026fde --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,15 @@ +server: + port: ${SERVER-PORT:8181} + +spring: + profiles: + active: ${ACTIVE-PROFILES:local} + application: + name: BACKEND + data: + base-mongodb: + uri: mongodb://${MGDB-NAME}:${MGDB-PASSWORD}@${MGDB-ADDRESS}/${MGDB-DATABASE}?authSource=${MGDB-AUTHSOURCE} + archive-mongodb: + uri: mongodb://${MGDB-NAME}:${MGDB-PASSWORD}@${MGDB-ADDRESS}/${ARCHIVE-MGDB-DATABASE}?authSource=${MGDB-AUTHSOURCE} + + diff --git a/src/test/java/com/luca/pilot/PilotApplicationTests.java b/src/test/java/com/luca/pilot/PilotApplicationTests.java new file mode 100644 index 0000000..9490718 --- /dev/null +++ b/src/test/java/com/luca/pilot/PilotApplicationTests.java @@ -0,0 +1,13 @@ +package com.luca.pilot; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class PilotApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/src/test/java/com/luca/pilot/PlanTaskTest.java b/src/test/java/com/luca/pilot/PlanTaskTest.java new file mode 100644 index 0000000..9460f7c --- /dev/null +++ b/src/test/java/com/luca/pilot/PlanTaskTest.java @@ -0,0 +1,90 @@ +package com.luca.pilot; + +import cn.hutool.json.JSONUtil; +import com.luca.pilot.entity.UserArchive; +import com.luca.pilot.service.BaseModuleViewService; +import com.luca.pilot.service.PlanService; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.test.context.ActiveProfiles; + +import java.util.List; + +@Slf4j +@SpringBootTest +@ActiveProfiles("hj") +public class PlanTaskTest { + @Autowired + private MongoTemplate mongoTemplate; + @Autowired + private PlanService planService; + @Autowired + private BaseModuleViewService baseModuleViewService; + + + @Test + void synchronizePlanTask2() { + // 创建查询æ¡ä»¶ + Query query = new Query(); + query.addCriteria(Criteria.where("createAt").lt("2023-12-07 14:50")); + long count = mongoTemplate.count(query, UserArchive.class); + log.info("total count:{}", count); + + long skip = count / 10; + if (count % 10 > 0) { + skip++; + } + + + for (int i = 0; i < skip; i++) { + query.skip(i * 10L); + query.limit(10); + List<UserArchive> userArchives = mongoTemplate.find(query, UserArchive.class); + log.info("userArchives count:{}", userArchives.size()); + } + + } + + @Test + void synchronizeModuleView() { + baseModuleViewService.synchronizeModuleView(); + } + + + + @Test + void synchronizePlanTask() { + planService.synchronizePlanTask(); + } + + @Test + void contextLoads() { + Book book = new Book(); + book.setId(10); + book.setName("testMongoDB"); + book.setType("testMongoDB"); + book.setDescription("testMongoDB"); + mongoTemplate.save(book); + } + + @Test + void find() { + List<Book> all = mongoTemplate.findAll(Book.class); + System.out.println(all); + } + + @Data + class Book { + private int id; + private String name; + private String type; + private String description; + } +} + -- GitLab