Compare commits
33 Commits
5d49c82190
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eea6307c87 | ||
|
|
c5366e006b | ||
|
|
f0f295bfc9 | ||
|
|
e34c5d2e3e | ||
|
|
86d6fcaec7 | ||
|
|
2c09d97cec | ||
|
|
37ac0cd311 | ||
|
|
9fa38a3065 | ||
|
|
d908f99fbd | ||
|
|
5b0b23336c | ||
|
|
263b91c42a | ||
|
|
a53c90a348 | ||
|
|
e3583dad0c | ||
|
|
514a65a5e6 | ||
|
|
57a57ace77 | ||
|
|
1338e6458c | ||
|
|
9fd46b3a20 | ||
|
|
8e8b1a7684 | ||
|
|
4d8238dd7f | ||
|
|
73f7d3085a | ||
|
|
3f8652395c | ||
|
|
8c6e0aa353 | ||
|
|
e15dd6289d | ||
|
|
7d33227d70 | ||
|
|
8fda8f7669 | ||
|
|
57a828c5b4 | ||
|
|
b9f6aa0cc2 | ||
|
|
dcb9028d86 | ||
|
|
57a2787bf8 | ||
|
|
813ddfaeac | ||
|
|
0cbf6b28ef | ||
|
|
7efb2527d0 | ||
|
|
f085c9d506 |
2
pom.xml
2
pom.xml
@@ -8,7 +8,7 @@
|
|||||||
<artifactId>hudi-service</artifactId>
|
<artifactId>hudi-service</artifactId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<description>Hudi服务应用集合</description>
|
<description>Hudi服务模块系列应用</description>
|
||||||
<modules>
|
<modules>
|
||||||
<module>service-common</module>
|
<module>service-common</module>
|
||||||
<module>service-dependencies</module>
|
<module>service-dependencies</module>
|
||||||
|
|||||||
84
service-ai/.gitignore
vendored
84
service-ai/.gitignore
vendored
@@ -1,84 +0,0 @@
|
|||||||
.idea/**/workspace.xml
|
|
||||||
.idea/**/tasks.xml
|
|
||||||
.idea/**/usage.statistics.xml
|
|
||||||
.idea/**/dictionaries
|
|
||||||
.idea/**/shelf
|
|
||||||
.idea/**/aws.xml
|
|
||||||
.idea/**/contentModel.xml
|
|
||||||
.idea/**/dataSources/
|
|
||||||
.idea/**/dataSources.ids
|
|
||||||
.idea/**/dataSources.local.xml
|
|
||||||
.idea/**/sqlDataSources.xml
|
|
||||||
.idea/**/dynamic.xml
|
|
||||||
.idea/**/uiDesigner.xml
|
|
||||||
.idea/**/dbnavigator.xml
|
|
||||||
.idea/**/gradle.xml
|
|
||||||
.idea/**/libraries
|
|
||||||
cmake-build-*/
|
|
||||||
.idea/**/mongoSettings.xml
|
|
||||||
*.iws
|
|
||||||
out/
|
|
||||||
.idea_modules/
|
|
||||||
atlassian-ide-plugin.xml
|
|
||||||
.idea/replstate.xml
|
|
||||||
.idea/sonarlint/
|
|
||||||
com_crashlytics_export_strings.xml
|
|
||||||
crashlytics.properties
|
|
||||||
crashlytics-build.properties
|
|
||||||
fabric.properties
|
|
||||||
.idea/httpRequests
|
|
||||||
.idea/caches/build_file_checksums.ser
|
|
||||||
target/
|
|
||||||
pom.xml.tag
|
|
||||||
pom.xml.releaseBackup
|
|
||||||
pom.xml.versionsBackup
|
|
||||||
pom.xml.next
|
|
||||||
release.properties
|
|
||||||
dependency-reduced-pom.xml
|
|
||||||
buildNumber.properties
|
|
||||||
.mvn/timing.properties
|
|
||||||
.mvn/wrapper/maven-wrapper.jar
|
|
||||||
.project
|
|
||||||
.classpath
|
|
||||||
*~
|
|
||||||
.fuse_hidden*
|
|
||||||
.directory
|
|
||||||
.Trash-*
|
|
||||||
.nfs*
|
|
||||||
.gradle
|
|
||||||
**/build/
|
|
||||||
!src/**/build/
|
|
||||||
gradle-app.setting
|
|
||||||
!gradle-wrapper.jar
|
|
||||||
!gradle-wrapper.properties
|
|
||||||
.gradletasknamecache
|
|
||||||
Thumbs.db
|
|
||||||
Thumbs.db:encryptable
|
|
||||||
ehthumbs.db
|
|
||||||
ehthumbs_vista.db
|
|
||||||
*.stackdump
|
|
||||||
[Dd]esktop.ini
|
|
||||||
$RECYCLE.BIN/
|
|
||||||
*.cab
|
|
||||||
*.msi
|
|
||||||
*.msix
|
|
||||||
*.msm
|
|
||||||
*.msp
|
|
||||||
*.lnk
|
|
||||||
.DS_Store
|
|
||||||
.AppleDouble
|
|
||||||
.LSOverride
|
|
||||||
Icon
|
|
||||||
._*
|
|
||||||
.DocumentRevisions-V100
|
|
||||||
.fseventsd
|
|
||||||
.Spotlight-V100
|
|
||||||
.TemporaryItems
|
|
||||||
.Trashes
|
|
||||||
.VolumeIcon.icns
|
|
||||||
.com.apple.timemachine.donotpresent
|
|
||||||
.AppleDB
|
|
||||||
.AppleDesktop
|
|
||||||
Network Trash Folder
|
|
||||||
Temporary Items
|
|
||||||
.apdisk
|
|
||||||
10
service-ai/.idea/.gitignore
generated
vendored
10
service-ai/.idea/.gitignore
generated
vendored
@@ -1,10 +0,0 @@
|
|||||||
# 默认忽略的文件
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
# 基于编辑器的 HTTP 客户端请求
|
|
||||||
/httpRequests/
|
|
||||||
# 依赖于环境的 Maven 主目录路径
|
|
||||||
/mavenHomeManager.xml
|
|
||||||
# Datasource local storage ignored files
|
|
||||||
/dataSources/
|
|
||||||
/dataSources.local.xml
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ApifoxUploaderProjectSetting">
|
|
||||||
<option name="apiAccessToken" value="APS-0ZZaS4q0gUiFOlbBJMN8hAmS7viQNi4D" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
8
service-ai/.idea/GitCommitMessageStorage.xml
generated
8
service-ai/.idea/GitCommitMessageStorage.xml
generated
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="GitCommitMessageStorage">
|
|
||||||
<option name="messageStorage">
|
|
||||||
<MessageStorage />
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
29
service-ai/.idea/codeStyles/Project.xml
generated
29
service-ai/.idea/codeStyles/Project.xml
generated
@@ -1,29 +0,0 @@
|
|||||||
<component name="ProjectCodeStyleConfiguration">
|
|
||||||
<code_scheme name="Project" version="173">
|
|
||||||
<JavaCodeStyleSettings>
|
|
||||||
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
|
|
||||||
<value />
|
|
||||||
</option>
|
|
||||||
<option name="IMPORT_LAYOUT_TABLE">
|
|
||||||
<value>
|
|
||||||
<package name="" withSubpackages="true" static="false" module="true" />
|
|
||||||
<package name="" withSubpackages="true" static="false" />
|
|
||||||
<emptyLine />
|
|
||||||
<package name="" withSubpackages="true" static="true" />
|
|
||||||
</value>
|
|
||||||
</option>
|
|
||||||
</JavaCodeStyleSettings>
|
|
||||||
<JetCodeStyleSettings>
|
|
||||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
|
||||||
</JetCodeStyleSettings>
|
|
||||||
<ScalaCodeStyleSettings>
|
|
||||||
<option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
|
|
||||||
</ScalaCodeStyleSettings>
|
|
||||||
<codeStyleSettings language="JAVA">
|
|
||||||
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
|
|
||||||
</codeStyleSettings>
|
|
||||||
<codeStyleSettings language="kotlin">
|
|
||||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
|
||||||
</codeStyleSettings>
|
|
||||||
</code_scheme>
|
|
||||||
</component>
|
|
||||||
5
service-ai/.idea/codeStyles/codeStyleConfig.xml
generated
5
service-ai/.idea/codeStyles/codeStyleConfig.xml
generated
@@ -1,5 +0,0 @@
|
|||||||
<component name="ProjectCodeStyleConfiguration">
|
|
||||||
<state>
|
|
||||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
|
||||||
</state>
|
|
||||||
</component>
|
|
||||||
15
service-ai/.idea/compiler.xml
generated
15
service-ai/.idea/compiler.xml
generated
@@ -1,15 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="CompilerConfiguration">
|
|
||||||
<annotationProcessing>
|
|
||||||
<profile name="Maven default annotation processors profile" enabled="true">
|
|
||||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
|
||||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
|
||||||
<outputRelativeToContentRoot value="true" />
|
|
||||||
<module name="service-ai-knowledge" />
|
|
||||||
<module name="service-ai-chat" />
|
|
||||||
<module name="service-ai-core" />
|
|
||||||
</profile>
|
|
||||||
</annotationProcessing>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
13
service-ai/.idea/encodings.xml
generated
13
service-ai/.idea/encodings.xml
generated
@@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="Encoding">
|
|
||||||
<file url="file://$PROJECT_DIR$/service-ai-chat/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/service-ai-chat/src/main/resources" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/service-ai-core/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/service-ai-core/src/main/resources" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/service-ai-knowledge/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/service-ai-knowledge/src/main/resources" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
30
service-ai/.idea/jarRepositories.xml
generated
30
service-ai/.idea/jarRepositories.xml
generated
@@ -1,30 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="RemoteRepositoriesConfiguration">
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="central" />
|
|
||||||
<option name="name" value="Central Repository" />
|
|
||||||
<option name="url" value="https://repo.maven.apache.org/maven2" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="lanyuanxiaoyao-maven-central" />
|
|
||||||
<option name="name" value="lanyuanxiaoyao-maven-central" />
|
|
||||||
<option name="url" value="https://maven.lanyuanxiaoyao.com/central" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="central" />
|
|
||||||
<option name="name" value="Maven Central repository" />
|
|
||||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="jboss.community" />
|
|
||||||
<option name="name" value="JBoss Community repository" />
|
|
||||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="central" />
|
|
||||||
<option name="name" value="Central Repository" />
|
|
||||||
<option name="url" value="https://maven.lanyuanxiaoyao.com/central" />
|
|
||||||
</remote-repository>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
12
service-ai/.idea/misc.xml
generated
12
service-ai/.idea/misc.xml
generated
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<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_17" default="true" project-jdk-name="temurin-17" project-jdk-type="JavaSDK" />
|
|
||||||
</project>
|
|
||||||
6
service-ai/.idea/vcs.xml
generated
6
service-ai/.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
root_path=$(dirname $(cd $(dirname $0);pwd))
|
|
||||||
source $(realpath $root_path/..)/bin/library.sh
|
|
||||||
deploy service-ai-core
|
|
||||||
package service-ai-chat
|
|
||||||
upload $root_path/service-ai-chat/target/service-ai-chat-1.0.0-SNAPSHOT.jar
|
|
||||||
@@ -1,172 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<groupId>com.lanyuanxiaoyao</groupId>
|
|
||||||
<artifactId>service-ai</artifactId>
|
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
|
||||||
<packaging>pom</packaging>
|
|
||||||
<description>Hudi AI服务集合</description>
|
|
||||||
<modules>
|
|
||||||
<module>service-ai-core</module>
|
|
||||||
<module>service-ai-chat</module>
|
|
||||||
<module>service-ai-knowledge</module>
|
|
||||||
</modules>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<maven.compiler.source>17</maven.compiler.source>
|
|
||||||
<maven.compiler.target>17</maven.compiler.target>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
|
|
||||||
<build-tag>b2b12</build-tag>
|
|
||||||
|
|
||||||
<spring-boot.version>3.4.3</spring-boot.version>
|
|
||||||
<spring-cloud.version>2024.0.1</spring-cloud.version>
|
|
||||||
<spring-ai.version>1.0.0-M6</spring-ai.version>
|
|
||||||
<eclipse-collections.version>11.1.0</eclipse-collections.version>
|
|
||||||
<curator.version>5.1.0</curator.version>
|
|
||||||
<hutool.version>5.8.27</hutool.version>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencyManagement>
|
|
||||||
<dependencies>
|
|
||||||
<!-- 当前项目依赖 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.lanyuanxiaoyao</groupId>
|
|
||||||
<artifactId>service-common</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.lanyuanxiaoyao</groupId>
|
|
||||||
<artifactId>service-configuration</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.lanyuanxiaoyao</groupId>
|
|
||||||
<artifactId>service-dependencies</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.lanyuanxiaoyao</groupId>
|
|
||||||
<artifactId>service-forest</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.lanyuanxiaoyao</groupId>
|
|
||||||
<artifactId>service-ai-core</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- spring boot 相关依赖 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-dependencies</artifactId>
|
|
||||||
<version>${spring-boot.version}</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-dependencies</artifactId>
|
|
||||||
<version>${spring-cloud.version}</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.ai</groupId>
|
|
||||||
<artifactId>spring-ai-bom</artifactId>
|
|
||||||
<version>${spring-ai.version}</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.dtflys.forest</groupId>
|
|
||||||
<artifactId>forest-spring-boot3-starter</artifactId>
|
|
||||||
<version>1.5.36</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
|
||||||
<artifactId>jackson-datatype-eclipse-collections</artifactId>
|
|
||||||
<version>2.17.1</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.ulisesbocchio</groupId>
|
|
||||||
<artifactId>jasypt-spring-boot-starter</artifactId>
|
|
||||||
<version>3.0.5</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- 日志相关 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>pl.tkowalcz.tjahzi</groupId>
|
|
||||||
<artifactId>logback-appender</artifactId>
|
|
||||||
<version>0.9.23</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.loki4j</groupId>
|
|
||||||
<artifactId>loki-logback-appender-jdk8</artifactId>
|
|
||||||
<version>1.4.2</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- 其他 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>dev.failsafe</groupId>
|
|
||||||
<artifactId>failsafe</artifactId>
|
|
||||||
<version>3.3.1</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.collections</groupId>
|
|
||||||
<artifactId>eclipse-collections</artifactId>
|
|
||||||
<version>${eclipse-collections.version}</version>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.collections</groupId>
|
|
||||||
<artifactId>eclipse-collections-api</artifactId>
|
|
||||||
<version>${eclipse-collections.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>cn.hutool</groupId>
|
|
||||||
<artifactId>hutool-all</artifactId>
|
|
||||||
<version>${hutool.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</dependencyManagement>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<pluginManagement>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-source-plugin</artifactId>
|
|
||||||
<version>3.3.0</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
|
||||||
<version>3.3.0</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
||||||
<version>${spring-boot.version}</version>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</pluginManagement>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<distributionManagement>
|
|
||||||
<repository>
|
|
||||||
<id>${releases.id}</id>
|
|
||||||
<name>${releases.name}</name>
|
|
||||||
<url>${releases.url}</url>
|
|
||||||
</repository>
|
|
||||||
<snapshotRepository>
|
|
||||||
<id>${snapshots.id}</id>
|
|
||||||
<name>${snapshots.name}</name>
|
|
||||||
<url>${snapshots.url}</url>
|
|
||||||
</snapshotRepository>
|
|
||||||
</distributionManagement>
|
|
||||||
|
|
||||||
</project>
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>com.lanyuanxiaoyao</groupId>
|
|
||||||
<artifactId>service-ai</artifactId>
|
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<artifactId>service-ai-chat</artifactId>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.lanyuanxiaoyao</groupId>
|
|
||||||
<artifactId>service-ai-core</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.ai</groupId>
|
|
||||||
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>repackage</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</project>
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.chat;
|
|
||||||
|
|
||||||
import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
|
||||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
|
||||||
import org.springframework.retry.annotation.EnableRetry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @version 20250514
|
|
||||||
*/
|
|
||||||
@SpringBootApplication(scanBasePackages = "com.lanyuanxiaoyao.service")
|
|
||||||
@EnableDiscoveryClient
|
|
||||||
@EnableConfigurationProperties
|
|
||||||
@EnableEncryptableProperties
|
|
||||||
@EnableRetry
|
|
||||||
public class AiChatApplication {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
SpringApplication.run(AiChatApplication.class, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.chat.controller;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.lanyuanxiaoyao.service.ai.chat.entity.MessageVO;
|
|
||||||
import com.lanyuanxiaoyao.service.ai.chat.tools.DatetimeTools;
|
|
||||||
import java.io.IOException;
|
|
||||||
import org.eclipse.collections.api.list.ImmutableList;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.ai.chat.client.ChatClient;
|
|
||||||
import org.springframework.ai.chat.messages.AssistantMessage;
|
|
||||||
import org.springframework.ai.chat.messages.Message;
|
|
||||||
import org.springframework.ai.chat.messages.UserMessage;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 聊天
|
|
||||||
*
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @version 20250514
|
|
||||||
*/
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("chat")
|
|
||||||
public class ChatController {
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ChatController.class);
|
|
||||||
|
|
||||||
private final ChatClient chatClient;
|
|
||||||
|
|
||||||
public ChatController(ChatClient.Builder builder) {
|
|
||||||
this.chatClient = builder
|
|
||||||
.defaultSystem("始终在中文语境下进行对话")
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ChatClient.ChatClientRequestSpec buildRequest(ImmutableList<MessageVO> messages) {
|
|
||||||
return chatClient.prompt()
|
|
||||||
.messages(
|
|
||||||
messages
|
|
||||||
.collect(message -> StrUtil.equals(message.getRole(), "assistant")
|
|
||||||
? new AssistantMessage(message.getContent())
|
|
||||||
: new UserMessage(message.getContent()))
|
|
||||||
.collect(message -> (Message) message)
|
|
||||||
.toList()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("sync")
|
|
||||||
@ResponseBody
|
|
||||||
public String chatSync(@RequestBody ImmutableList<MessageVO> messages) {
|
|
||||||
return buildRequest(messages)
|
|
||||||
.call()
|
|
||||||
.content();
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("async")
|
|
||||||
public SseEmitter chatAsync(@RequestBody ImmutableList<MessageVO> messages) {
|
|
||||||
SseEmitter emitter = new SseEmitter();
|
|
||||||
buildRequest(messages)
|
|
||||||
.stream()
|
|
||||||
.content()
|
|
||||||
.subscribe(
|
|
||||||
content -> {
|
|
||||||
try {
|
|
||||||
emitter.send(content);
|
|
||||||
} catch (IOException e) {
|
|
||||||
emitter.completeWithError(e);
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
emitter::completeWithError,
|
|
||||||
emitter::complete
|
|
||||||
);
|
|
||||||
return emitter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.chat.entity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @version 20250516
|
|
||||||
*/
|
|
||||||
public class MessageVO {
|
|
||||||
private String role;
|
|
||||||
private String content;
|
|
||||||
|
|
||||||
public String getRole() {
|
|
||||||
return role;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRole(String role) {
|
|
||||||
this.role = role;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getContent() {
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContent(String content) {
|
|
||||||
this.content = content;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "MessageVO{" +
|
|
||||||
"role='" + role + '\'' +
|
|
||||||
", content='" + content + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.chat.tools;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import org.springframework.ai.tool.annotation.Tool;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @version 20250516
|
|
||||||
*/
|
|
||||||
public class DatetimeTools {
|
|
||||||
private final static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
||||||
|
|
||||||
@Tool(description = "获取当前时间")
|
|
||||||
public String getCurrentTime() {
|
|
||||||
return LocalDateTime.now().format(formatter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
spring:
|
|
||||||
application:
|
|
||||||
name: service-ai-chat
|
|
||||||
profiles:
|
|
||||||
include: random-port,common,metrics,forest
|
|
||||||
ai:
|
|
||||||
openai:
|
|
||||||
base-url: http://132.121.206.65:10086
|
|
||||||
api-key: ENC(K+Hff9QGC+fcyi510VIDd9CaeK/IN5WBJ9rlkUsHEdDgIidW+stHHJlsK0lLPUXXREha+ToQZqqDXJrqSE+GUKCXklFhelD8bRHFXBIeP/ZzT2cxhzgKUXgjw3S0Qw2R)
|
|
||||||
chat:
|
|
||||||
options:
|
|
||||||
model: 'Qwen3-1.7'
|
|
||||||
mvc:
|
|
||||||
async:
|
|
||||||
request-timeout: 300000
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
<configuration>
|
|
||||||
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
|
|
||||||
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
|
|
||||||
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
|
|
||||||
|
|
||||||
<springProperty scope="context" name="LOKI_PUSH_URL" source="loki.url"/>
|
|
||||||
<springProperty scope="context" name="LOGGING_PARENT" source="logging.parent"/>
|
|
||||||
<springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
|
|
||||||
|
|
||||||
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
|
|
||||||
<encoder>
|
|
||||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %clr(%5p) %clr([${HOSTNAME}]){yellow} %clr([%t]){magenta} %clr(%logger{40}){cyan} #@# %m%n%wEx</pattern>
|
|
||||||
</encoder>
|
|
||||||
</appender>
|
|
||||||
|
|
||||||
<appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
|
||||||
<file>${LOGGING_PARENT:-.}/${APP_NAME:-run}.log</file>
|
|
||||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
|
||||||
<fileNamePattern>${LOGGING_PARENT:-.}/archive/${APP_NAME:-run}-%d{yyyy-MM-dd}.gz</fileNamePattern>
|
|
||||||
<MaxHistory>7</MaxHistory>
|
|
||||||
</rollingPolicy>
|
|
||||||
<encoder>
|
|
||||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %p [${HOSTNAME}] [%t] %logger #@# %m%n%wEx</pattern>
|
|
||||||
</encoder>
|
|
||||||
</appender>
|
|
||||||
|
|
||||||
<logger name="com.zaxxer.hikari" level="ERROR"/>
|
|
||||||
<logger name="com.netflix.discovery.shared.resolver.aws.ConfigClusterResolver" level="WARN"/>
|
|
||||||
|
|
||||||
<root level="INFO">
|
|
||||||
<appender-ref ref="Console"/>
|
|
||||||
<!-- <appender-ref ref="RollingFile"/>-->
|
|
||||||
</root>
|
|
||||||
</configuration>
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.chat;
|
|
||||||
|
|
||||||
import org.springframework.ai.chat.client.ChatClient;
|
|
||||||
import org.springframework.ai.openai.OpenAiChatModel;
|
|
||||||
import org.springframework.ai.openai.OpenAiChatOptions;
|
|
||||||
import org.springframework.ai.openai.api.OpenAiApi;
|
|
||||||
import reactor.core.Disposable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @version 20250514
|
|
||||||
*/
|
|
||||||
public class TestChat {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
ChatClient client = ChatClient.builder(
|
|
||||||
OpenAiChatModel.builder()
|
|
||||||
.openAiApi(
|
|
||||||
OpenAiApi.builder()
|
|
||||||
.baseUrl("http://132.121.206.65:10086")
|
|
||||||
.apiKey("*XMySqV%>hR&v>>g*NwCs3tpQ5FVMFEF2VHVTj<MYQd$&@$sY7CgqNyea4giJi4")
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
.defaultOptions(
|
|
||||||
OpenAiChatOptions.builder()
|
|
||||||
.model("Qwen3-1.7")
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
.build();
|
|
||||||
String content = client.prompt()
|
|
||||||
.user("你好")
|
|
||||||
.call()
|
|
||||||
.content();
|
|
||||||
System.out.println(content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>com.lanyuanxiaoyao</groupId>
|
|
||||||
<artifactId>service-ai</artifactId>
|
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<artifactId>service-ai-core</artifactId>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.lanyuanxiaoyao</groupId>
|
|
||||||
<artifactId>service-forest</artifactId>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.dtflys.forest</groupId>
|
|
||||||
<artifactId>forest-spring-boot-starter</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.springframework.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>commons-logging</groupId>
|
|
||||||
<artifactId>commons-logging</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-aop</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.dtflys.forest</groupId>
|
|
||||||
<artifactId>forest-spring-boot3-starter</artifactId>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>commons-logging</groupId>
|
|
||||||
<artifactId>commons-logging</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.service.configuration;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.security.config.Customizer;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
|
||||||
import org.springframework.security.core.userdetails.User;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
|
||||||
import org.springframework.web.cors.CorsConfiguration;
|
|
||||||
import org.springframework.web.cors.CorsConfigurationSource;
|
|
||||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @version 20250514
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
@EnableWebSecurity
|
|
||||||
public class SecurityConfig {
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
|
||||||
return http.authorizeHttpRequests(registry -> registry.anyRequest().authenticated())
|
|
||||||
.httpBasic(Customizer.withDefaults())
|
|
||||||
.csrf(AbstractHttpConfigurer::disable)
|
|
||||||
.cors(configurer -> configurer.configurationSource(corsConfigurationSource()))
|
|
||||||
.formLogin(AbstractHttpConfigurer::disable)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private CorsConfigurationSource corsConfigurationSource() {
|
|
||||||
CorsConfiguration configuration = new CorsConfiguration();
|
|
||||||
configuration.setAllowCredentials(true);
|
|
||||||
configuration.addAllowedHeader("*");
|
|
||||||
configuration.addAllowedMethod("*");
|
|
||||||
configuration.addAllowedOriginPattern("*");
|
|
||||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
|
||||||
source.registerCorsConfiguration("/**", configuration);
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public InMemoryUserDetailsManager userDetailsService(SecurityProperties securityProperties) {
|
|
||||||
UserDetails user = User.builder()
|
|
||||||
.username(securityProperties.getUsername())
|
|
||||||
.password("{noop}" + securityProperties.getDarkcode())
|
|
||||||
.authorities(securityProperties.getAuthority())
|
|
||||||
.build();
|
|
||||||
return new InMemoryUserDetailsManager(user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>com.lanyuanxiaoyao</groupId>
|
|
||||||
<artifactId>service-ai</artifactId>
|
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<artifactId>service-ai-knowledge</artifactId>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.lanyuanxiaoyao</groupId>
|
|
||||||
<artifactId>service-ai-core</artifactId>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.google.protobuf</groupId>
|
|
||||||
<artifactId>protobuf-java</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.ai</groupId>
|
|
||||||
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.ai</groupId>
|
|
||||||
<artifactId>spring-ai-qdrant-store-spring-boot-starter</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.ai</groupId>
|
|
||||||
<artifactId>spring-ai-markdown-document-reader</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>repackage</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</project>
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.knowledge;
|
|
||||||
|
|
||||||
import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
|
|
||||||
import org.springframework.boot.ApplicationArguments;
|
|
||||||
import org.springframework.boot.ApplicationRunner;
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
|
||||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
|
||||||
import org.springframework.retry.annotation.EnableRetry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @version 20250515
|
|
||||||
*/
|
|
||||||
@SpringBootApplication(scanBasePackages = "com.lanyuanxiaoyao.service")
|
|
||||||
@EnableDiscoveryClient
|
|
||||||
@EnableConfigurationProperties
|
|
||||||
@EnableEncryptableProperties
|
|
||||||
@EnableRetry
|
|
||||||
public class KnowledgeApplication implements ApplicationRunner {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
SpringApplication.run(KnowledgeApplication.class, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run(ApplicationArguments args) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.knowledge.controller;
|
|
||||||
|
|
||||||
import com.lanyuanxiaoyao.service.ai.knowledge.entity.CollectionVO;
|
|
||||||
import com.lanyuanxiaoyao.service.ai.knowledge.entity.PointVO;
|
|
||||||
import io.qdrant.client.QdrantClient;
|
|
||||||
import io.qdrant.client.grpc.Collections;
|
|
||||||
import io.qdrant.client.grpc.Points;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import org.eclipse.collections.api.factory.Lists;
|
|
||||||
import org.eclipse.collections.api.list.ImmutableList;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.ai.embedding.EmbeddingModel;
|
|
||||||
import org.springframework.ai.reader.markdown.MarkdownDocumentReader;
|
|
||||||
import org.springframework.ai.reader.markdown.config.MarkdownDocumentReaderConfig;
|
|
||||||
import org.springframework.ai.vectorstore.VectorStore;
|
|
||||||
import org.springframework.ai.vectorstore.qdrant.QdrantVectorStore;
|
|
||||||
import org.springframework.core.io.ByteArrayResource;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @version 20250515
|
|
||||||
*/
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("knowledge")
|
|
||||||
public class KnowledgeController {
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(KnowledgeController.class);
|
|
||||||
|
|
||||||
private final QdrantClient client;
|
|
||||||
private final EmbeddingModel embeddingModel;
|
|
||||||
|
|
||||||
public KnowledgeController(VectorStore vectorStore, EmbeddingModel embeddingModel) {
|
|
||||||
client = (QdrantClient) vectorStore.getNativeClient().orElseThrow();
|
|
||||||
this.embeddingModel = embeddingModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("add")
|
|
||||||
public void add(
|
|
||||||
@RequestParam("name") String name,
|
|
||||||
@RequestParam("strategy") String strategy
|
|
||||||
) throws ExecutionException, InterruptedException {
|
|
||||||
logger.info("Enter method: add[name, strategy]. name:{},strategy:{}", name, strategy);
|
|
||||||
client.createCollectionAsync(
|
|
||||||
name,
|
|
||||||
Collections.VectorParams.newBuilder()
|
|
||||||
.setDistance(Collections.Distance.valueOf(strategy))
|
|
||||||
.setSize(embeddingModel.dimensions())
|
|
||||||
.build()
|
|
||||||
).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("list")
|
|
||||||
public ImmutableList<CollectionVO> list() throws ExecutionException, InterruptedException {
|
|
||||||
return client.listCollectionsAsync()
|
|
||||||
.get()
|
|
||||||
.stream()
|
|
||||||
.collect(Collectors.toCollection(Lists.mutable::empty))
|
|
||||||
.collect(name -> {
|
|
||||||
try {
|
|
||||||
Collections.CollectionInfo info = client.getCollectionInfoAsync(name).get();
|
|
||||||
CollectionVO vo = new CollectionVO();
|
|
||||||
vo.setName(name);
|
|
||||||
vo.setPoints(info.getPointsCount());
|
|
||||||
vo.setSegments(info.getSegmentsCount());
|
|
||||||
vo.setStatus(info.getStatus().name());
|
|
||||||
Collections.VectorParams vectorParams = info.getConfig().getParams().getVectorsConfig().getParams();
|
|
||||||
vo.setStrategy(vectorParams.getDistance().name());
|
|
||||||
vo.setSize(vectorParams.getSize());
|
|
||||||
return vo;
|
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.toImmutable();
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("list_points")
|
|
||||||
public ImmutableList<PointVO> listPoints(@RequestParam("name") String name) throws ExecutionException, InterruptedException {
|
|
||||||
Points.ScrollResponse response = client.scrollAsync(
|
|
||||||
Points.ScrollPoints.newBuilder()
|
|
||||||
.setCollectionName(name)
|
|
||||||
// .setLimit(2)
|
|
||||||
.setWithPayload(Points.WithPayloadSelector.newBuilder().setEnable(true).build())
|
|
||||||
.setWithVectors(Points.WithVectorsSelector.newBuilder().setEnable(false).build())
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
.get();
|
|
||||||
return response.getResultList()
|
|
||||||
.stream()
|
|
||||||
.collect(Collectors.toCollection(Lists.mutable::empty))
|
|
||||||
.collect(point -> {
|
|
||||||
PointVO vo = new PointVO();
|
|
||||||
vo.setId(point.getId().getUuid());
|
|
||||||
vo.setText(point.getPayloadMap().get("doc_content").getStringValue());
|
|
||||||
return vo;
|
|
||||||
})
|
|
||||||
.toImmutable();
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("delete")
|
|
||||||
public void delete(@RequestParam("name") String name) throws ExecutionException, InterruptedException {
|
|
||||||
client.deleteCollectionAsync(name).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = "preview_text", consumes = "text/plain;charset=utf-8")
|
|
||||||
public ImmutableList<String> previewText(
|
|
||||||
@RequestParam("name") String name,
|
|
||||||
@RequestParam(value = "mode", defaultValue = "normal") String mode,
|
|
||||||
@RequestBody String text
|
|
||||||
) {
|
|
||||||
return Lists.immutable.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = "process_text", consumes = "text/plain;charset=utf-8")
|
|
||||||
public void processText(
|
|
||||||
@RequestParam("name") String name,
|
|
||||||
@RequestBody String text
|
|
||||||
) {
|
|
||||||
VectorStore source = QdrantVectorStore.builder(client, embeddingModel)
|
|
||||||
.collectionName(name)
|
|
||||||
.initializeSchema(true)
|
|
||||||
.build();
|
|
||||||
MarkdownDocumentReader reader = new MarkdownDocumentReader(
|
|
||||||
new ByteArrayResource(text.getBytes(StandardCharsets.UTF_8)),
|
|
||||||
MarkdownDocumentReaderConfig.builder()
|
|
||||||
.withHorizontalRuleCreateDocument(true)
|
|
||||||
.withIncludeCodeBlock(false)
|
|
||||||
.withIncludeBlockquote(false)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
source.add(reader.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.knowledge.entity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @version 20250516
|
|
||||||
*/
|
|
||||||
public class CollectionVO {
|
|
||||||
private String name;
|
|
||||||
private String strategy;
|
|
||||||
private Long size;
|
|
||||||
private Long points;
|
|
||||||
private Long segments;
|
|
||||||
private String status;
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStrategy() {
|
|
||||||
return strategy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStrategy(String strategy) {
|
|
||||||
this.strategy = strategy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getSize() {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSize(Long size) {
|
|
||||||
this.size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getPoints() {
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPoints(Long points) {
|
|
||||||
this.points = points;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getSegments() {
|
|
||||||
return segments;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSegments(Long segments) {
|
|
||||||
this.segments = segments;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(String status) {
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "CollectionVO{" +
|
|
||||||
"name='" + name + '\'' +
|
|
||||||
", strategy='" + strategy + '\'' +
|
|
||||||
", size=" + size +
|
|
||||||
", points=" + points +
|
|
||||||
", segments=" + segments +
|
|
||||||
", status='" + status + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.knowledge.entity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @version 20250516
|
|
||||||
*/
|
|
||||||
public class PointVO {
|
|
||||||
private String id;
|
|
||||||
private String text;
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getText() {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setText(String text) {
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "PointVO{" +
|
|
||||||
"id='" + id + '\'' +
|
|
||||||
", text='" + text + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
spring:
|
|
||||||
application:
|
|
||||||
name: service-ai-knowledge
|
|
||||||
profiles:
|
|
||||||
include: common,metrics,forest
|
|
||||||
cloud:
|
|
||||||
zookeeper:
|
|
||||||
enabled: true
|
|
||||||
connect-string: b1m2.hdp.dc:2181,b1m3.hdp.dc:2181,b1m4.hdp.dc:2181,b1m5.hdp.dc:2181,b1m6.hdp.dc:2181
|
|
||||||
discovery:
|
|
||||||
enabled: ${spring.cloud.zookeeper.enabled}
|
|
||||||
root: /hudi-services
|
|
||||||
instance-id: ${spring.application.name}-127.0.0.1-${random.uuid}-20250514
|
|
||||||
metadata:
|
|
||||||
discovery: zookeeper
|
|
||||||
ip: 127.0.0.1
|
|
||||||
hostname: localhost
|
|
||||||
hostname_full: localhost
|
|
||||||
start_time: 20250514112750
|
|
||||||
security:
|
|
||||||
meta:
|
|
||||||
authority: ENC(GXKnbq1LS11U2HaONspvH+D/TkIx13aWTaokdkzaF7HSvq6Z0Rv1+JUWFnYopVXu)
|
|
||||||
username: ENC(moIO5mO39V1Z+RDwROK9JXY4GfM8ZjDgM6Si7wRZ1MPVjbhTpmLz3lz28rAiw7c2LeCmizfJzHkEXIwGlB280g==)
|
|
||||||
darkcode: ENC(0jzpQ7T6S+P7bZrENgYsUoLhlqGvw7DA2MN3BRqEOwq7plhtg72vuuiPQNnr3DaYz0CpyTvxInhpx11W3VZ1trD6NINh7O3LN70ZqO5pWXk=)
|
|
||||||
ai:
|
|
||||||
openai:
|
|
||||||
base-url: http://132.121.206.65:10086
|
|
||||||
api-key: ENC(K+Hff9QGC+fcyi510VIDd9CaeK/IN5WBJ9rlkUsHEdDgIidW+stHHJlsK0lLPUXXREha+ToQZqqDXJrqSE+GUKCXklFhelD8bRHFXBIeP/ZzT2cxhzgKUXgjw3S0Qw2R)
|
|
||||||
chat:
|
|
||||||
options:
|
|
||||||
model: 'Qwen3-1.7'
|
|
||||||
embedding:
|
|
||||||
options:
|
|
||||||
model: 'Bge-m3'
|
|
||||||
vectorstore:
|
|
||||||
qdrant:
|
|
||||||
api-key: lanyuanxiaoyao
|
|
||||||
jasypt:
|
|
||||||
encryptor:
|
|
||||||
password: 'r#(R,P"Dp^A47>WSn:Wn].gs/+"v:q_Q*An~zF*g-@j@jtSTv5H/,S-3:R?r9R}.'
|
|
||||||
server:
|
|
||||||
port: 8080
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
<configuration>
|
|
||||||
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
|
|
||||||
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
|
|
||||||
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
|
|
||||||
|
|
||||||
<springProperty scope="context" name="LOKI_PUSH_URL" source="loki.url"/>
|
|
||||||
<springProperty scope="context" name="LOGGING_PARENT" source="logging.parent"/>
|
|
||||||
<springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
|
|
||||||
|
|
||||||
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
|
|
||||||
<encoder>
|
|
||||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %clr(%5p) %clr([${HOSTNAME}]){yellow} %clr([%t]){magenta} %clr(%logger{40}){cyan} #@# %m%n%wEx</pattern>
|
|
||||||
</encoder>
|
|
||||||
</appender>
|
|
||||||
|
|
||||||
<appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
|
||||||
<file>${LOGGING_PARENT:-.}/${APP_NAME:-run}.log</file>
|
|
||||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
|
||||||
<fileNamePattern>${LOGGING_PARENT:-.}/archive/${APP_NAME:-run}-%d{yyyy-MM-dd}.gz</fileNamePattern>
|
|
||||||
<MaxHistory>7</MaxHistory>
|
|
||||||
</rollingPolicy>
|
|
||||||
<encoder>
|
|
||||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %p [${HOSTNAME}] [%t] %logger #@# %m%n%wEx</pattern>
|
|
||||||
</encoder>
|
|
||||||
</appender>
|
|
||||||
|
|
||||||
<logger name="com.zaxxer.hikari" level="ERROR"/>
|
|
||||||
<logger name="com.netflix.discovery.shared.resolver.aws.ConfigClusterResolver" level="WARN"/>
|
|
||||||
|
|
||||||
<root level="INFO">
|
|
||||||
<appender-ref ref="Console"/>
|
|
||||||
<!-- <appender-ref ref="RollingFile"/>-->
|
|
||||||
</root>
|
|
||||||
</configuration>
|
|
||||||
@@ -60,6 +60,10 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.juicefs</groupId>
|
||||||
|
<artifactId>juicefs-hadoop</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.lanyuanxiaoyao</groupId>
|
<groupId>com.lanyuanxiaoyao</groupId>
|
||||||
<artifactId>service-configuration</artifactId>
|
<artifactId>service-configuration</artifactId>
|
||||||
|
|||||||
@@ -168,8 +168,8 @@ public class RunnerApplication implements ApplicationRunner {
|
|||||||
MapUtil.builder()
|
MapUtil.builder()
|
||||||
.put("currentPath", absolutRootPath)
|
.put("currentPath", absolutRootPath)
|
||||||
.put("hosts", hostInfoList
|
.put("hosts", hostInfoList
|
||||||
.collect(HostInfoWrapper::getHostnameIp)
|
.collect(HostInfoWrapper::getHostnameIp)
|
||||||
.toSortedList((o1, o2) -> Comparator.<String>naturalOrder().compare(o1.getIp(), o2.getIp())))
|
.toSortedList((o1, o2) -> Comparator.<String>naturalOrder().compare(o1.getIp(), o2.getIp())))
|
||||||
.put("selectedHosts", selectedHosts)
|
.put("selectedHosts", selectedHosts)
|
||||||
.put("runtime", runtimeInfo)
|
.put("runtime", runtimeInfo)
|
||||||
.put("info", serviceInfo)
|
.put("info", serviceInfo)
|
||||||
@@ -187,8 +187,8 @@ public class RunnerApplication implements ApplicationRunner {
|
|||||||
MapUtil.builder()
|
MapUtil.builder()
|
||||||
.put("currentPath", absolutRootPath)
|
.put("currentPath", absolutRootPath)
|
||||||
.put("hosts", hostInfoList
|
.put("hosts", hostInfoList
|
||||||
.collect(HostInfoWrapper::getHostnameIp)
|
.collect(HostInfoWrapper::getIp)
|
||||||
.toSortedList((o1, o2) -> Comparator.<String>naturalOrder().compare(o1.getIp(), o2.getIp())))
|
.toSortedList(Comparator.naturalOrder()))
|
||||||
.put("runtime", runtimeInfo)
|
.put("runtime", runtimeInfo)
|
||||||
.put("info", serviceInfo)
|
.put("info", serviceInfo)
|
||||||
.put("arguments", serviceInfo.getArguments())
|
.put("arguments", serviceInfo.getArguments())
|
||||||
@@ -199,13 +199,13 @@ public class RunnerApplication implements ApplicationRunner {
|
|||||||
StrUtil.format("stop-{}.sh", serviceInfo.getName())
|
StrUtil.format("stop-{}.sh", serviceInfo.getName())
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
generateTemplate(
|
generateTemplate(
|
||||||
"cloud/log.ftl",
|
"cloud/log.ftl",
|
||||||
MapUtil.builder()
|
MapUtil.builder()
|
||||||
.put("currentPath", absolutRootPath)
|
.put("currentPath", absolutRootPath)
|
||||||
.put("hosts", hostInfoList
|
.put("hosts", hostInfoList
|
||||||
.collect(HostInfoWrapper::getHostnameIp)
|
.collect(HostInfoWrapper::getIp)
|
||||||
.toSortedList((o1, o2) -> Comparator.<String>naturalOrder().compare(o1.getIp(), o2.getIp())))
|
.toSortedList(Comparator.naturalOrder()))
|
||||||
.put("selectedHosts", selectedHosts)
|
.put("selectedHosts", selectedHosts)
|
||||||
.put("runtime", runtimeInfo)
|
.put("runtime", runtimeInfo)
|
||||||
.put("info", serviceInfo)
|
.put("info", serviceInfo)
|
||||||
@@ -228,18 +228,6 @@ public class RunnerApplication implements ApplicationRunner {
|
|||||||
Paths.get(root.toString(), "stop.sh")
|
Paths.get(root.toString(), "stop.sh")
|
||||||
);
|
);
|
||||||
|
|
||||||
generateTemplate(
|
|
||||||
"cloud/ssh-script.ftl",
|
|
||||||
MapUtil.builder()
|
|
||||||
.put("currentPath", absolutRootPath)
|
|
||||||
.put("hosts", hostInfoList
|
|
||||||
.collect(HostInfoWrapper::getHostnameIp)
|
|
||||||
.toSortedList((o1, o2) -> Comparator.<String>naturalOrder().compare(o1.getIp(), o2.getIp())))
|
|
||||||
.put("runtime", runtimeInfo)
|
|
||||||
.build(),
|
|
||||||
Paths.get(root.toString(), "ssh.sh")
|
|
||||||
);
|
|
||||||
|
|
||||||
MutableMap<String, MutableList<ServiceInfoWrapper>> groups = Maps.mutable.empty();
|
MutableMap<String, MutableList<ServiceInfoWrapper>> groups = Maps.mutable.empty();
|
||||||
for (ServiceInfoWrapper service : serviceInfoList) {
|
for (ServiceInfoWrapper service : serviceInfoList) {
|
||||||
service.getGroups().add(0, "all");
|
service.getGroups().add(0, "all");
|
||||||
|
|||||||
@@ -13,5 +13,5 @@ for host in <#noparse>${hosts[@]}</#noparse>
|
|||||||
do
|
do
|
||||||
hostname=`ssh $host 'echo $HOSTNAME'`
|
hostname=`ssh $host 'echo $HOSTNAME'`
|
||||||
echo "$host $hostname"
|
echo "$host $hostname"
|
||||||
scp $host:${runtime.logPath}/${info.name}.log ${currentPath}/logs/${info.name}/$hostname.log
|
ssh $host "cat ${runtime.logPath}/${info.name}.log" > ${currentPath}/logs/${info.name}/$hostname.log
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
command=$@
|
|
||||||
|
|
||||||
hosts=(
|
|
||||||
<#list hosts as host>
|
|
||||||
${host.ip}
|
|
||||||
</#list>
|
|
||||||
)
|
|
||||||
|
|
||||||
for host in <#noparse>${hosts[@]}</#noparse>
|
|
||||||
do
|
|
||||||
hostname=`ssh $host 'echo $HOSTNAME'`
|
|
||||||
echo "$host $hostname"
|
|
||||||
ssh $host $command
|
|
||||||
done
|
|
||||||
@@ -1,7 +1,14 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
hosts=(
|
||||||
<#list hosts as host>
|
<#list hosts as host>
|
||||||
host=${host.ip}
|
${host}
|
||||||
echo "${info.name} ${host.ip} ${host.hostname} $datetime"
|
|
||||||
ssh $host 'bash -s' < ${currentPath}/stop.sh ${runtime.jarPath}/${info.name}.jar
|
|
||||||
</#list>
|
</#list>
|
||||||
|
)
|
||||||
|
|
||||||
|
for host in <#noparse>${hosts[@]}</#noparse>
|
||||||
|
do
|
||||||
|
hostname=`ssh $host 'echo $HOSTNAME'`
|
||||||
|
echo "$host $hostname"
|
||||||
|
ssh $host 'bash -s' < ${currentPath}/stop.sh ${runtime.jarPath}/${info.name}.jar
|
||||||
|
done
|
||||||
|
|||||||
@@ -80,6 +80,10 @@
|
|||||||
<groupId>org.apache.hudi</groupId>
|
<groupId>org.apache.hudi</groupId>
|
||||||
<artifactId>hudi-flink${flink.major.version}-bundle</artifactId>
|
<artifactId>hudi-flink${flink.major.version}-bundle</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.juicefs</groupId>
|
||||||
|
<artifactId>juicefs-hadoop</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.curator</groupId>
|
<groupId>org.apache.curator</groupId>
|
||||||
<artifactId>curator-framework</artifactId>
|
<artifactId>curator-framework</artifactId>
|
||||||
|
|||||||
@@ -72,6 +72,10 @@
|
|||||||
<groupId>org.apache.hudi</groupId>
|
<groupId>org.apache.hudi</groupId>
|
||||||
<artifactId>hudi-flink${flink.major.version}-bundle</artifactId>
|
<artifactId>hudi-flink${flink.major.version}-bundle</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.juicefs</groupId>
|
||||||
|
<artifactId>juicefs-hadoop</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.curator</groupId>
|
<groupId>org.apache.curator</groupId>
|
||||||
<artifactId>curator-framework</artifactId>
|
<artifactId>curator-framework</artifactId>
|
||||||
|
|||||||
@@ -174,11 +174,6 @@ public class ExecutorService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setEnvironment(Configuration configuration, String key, String value) {
|
private void setEnvironment(Configuration configuration, String key, String value) {
|
||||||
logger.info("Setting environment variable {} = {}", key, value);
|
|
||||||
if (ObjectUtil.isNull(value)) {
|
|
||||||
logger.warn("Environment variable {} is null", key);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
configuration.setString(ResourceManagerOptions.CONTAINERIZED_MASTER_ENV_PREFIX + key, value);
|
configuration.setString(ResourceManagerOptions.CONTAINERIZED_MASTER_ENV_PREFIX + key, value);
|
||||||
configuration.setString(ResourceManagerOptions.CONTAINERIZED_TASK_MANAGER_ENV_PREFIX + key, value);
|
configuration.setString(ResourceManagerOptions.CONTAINERIZED_TASK_MANAGER_ENV_PREFIX + key, value);
|
||||||
}
|
}
|
||||||
|
|||||||
90
service-web/client/.gitignore
vendored
90
service-web/client/.gitignore
vendored
@@ -1,90 +0,0 @@
|
|||||||
.idea/**
|
|
||||||
.idea/**/workspace.xml
|
|
||||||
.idea/**/tasks.xml
|
|
||||||
.idea/**/usage.statistics.xml
|
|
||||||
.idea/**/dictionaries
|
|
||||||
.idea/**/shelf
|
|
||||||
.idea/**/aws.xml
|
|
||||||
.idea/**/contentModel.xml
|
|
||||||
.idea/**/dataSources/
|
|
||||||
.idea/**/dataSources.ids
|
|
||||||
.idea/**/dataSources.local.xml
|
|
||||||
.idea/**/sqlDataSources.xml
|
|
||||||
.idea/**/dynamic.xml
|
|
||||||
.idea/**/uiDesigner.xml
|
|
||||||
.idea/**/dbnavigator.xml
|
|
||||||
.idea/**/gradle.xml
|
|
||||||
.idea/**/libraries
|
|
||||||
cmake-build-*/
|
|
||||||
.idea/**/mongoSettings.xml
|
|
||||||
*.iws
|
|
||||||
out/
|
|
||||||
.idea_modules/
|
|
||||||
atlassian-ide-plugin.xml
|
|
||||||
.idea/replstate.xml
|
|
||||||
.idea/sonarlint/
|
|
||||||
com_crashlytics_export_strings.xml
|
|
||||||
crashlytics.properties
|
|
||||||
crashlytics-build.properties
|
|
||||||
fabric.properties
|
|
||||||
.idea/httpRequests
|
|
||||||
.idea/caches/build_file_checksums.ser
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
.pnpm-debug.log*
|
|
||||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
|
||||||
pids
|
|
||||||
*.pid
|
|
||||||
*.seed
|
|
||||||
*.pid.lock
|
|
||||||
lib-cov
|
|
||||||
coverage
|
|
||||||
*.lcov
|
|
||||||
.nyc_output
|
|
||||||
.grunt
|
|
||||||
bower_components
|
|
||||||
.lock-wscript
|
|
||||||
build/Release
|
|
||||||
node_modules/
|
|
||||||
jspm_packages/
|
|
||||||
web_modules/
|
|
||||||
*.tsbuildinfo
|
|
||||||
.npm
|
|
||||||
.eslintcache
|
|
||||||
.stylelintcache
|
|
||||||
.rpt2_cache/
|
|
||||||
.rts2_cache_cjs/
|
|
||||||
.rts2_cache_es/
|
|
||||||
.rts2_cache_umd/
|
|
||||||
.node_repl_history
|
|
||||||
*.tgz
|
|
||||||
.yarn-integrity
|
|
||||||
.env
|
|
||||||
.env.development.local
|
|
||||||
.env.test.local
|
|
||||||
.env.production.local
|
|
||||||
.env.local
|
|
||||||
.cache
|
|
||||||
.parcel-cache
|
|
||||||
.next
|
|
||||||
out
|
|
||||||
.nuxt
|
|
||||||
dist
|
|
||||||
.cache/
|
|
||||||
.vuepress/dist
|
|
||||||
.temp
|
|
||||||
.docusaurus
|
|
||||||
.serverless/
|
|
||||||
.fusebox/
|
|
||||||
.dynamodb/
|
|
||||||
.tern-port
|
|
||||||
.vscode-test
|
|
||||||
.yarn/cache
|
|
||||||
.yarn/unplugged
|
|
||||||
.yarn/build-state.yml
|
|
||||||
.yarn/install-state.gz
|
|
||||||
.pnp.*
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="zh">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8"/>
|
|
||||||
<link rel="icon" href="icon.png"/>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
||||||
<title>Hudi 服务总台</title>
|
|
||||||
<style>
|
|
||||||
html, body, #root {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="root"></div>
|
|
||||||
<script type="module" src="/src/index.tsx"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "hudi-service-web-client",
|
|
||||||
"private": true,
|
|
||||||
"version": "0.0.0",
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"dev": "vite",
|
|
||||||
"build": "tsc -b && vite build",
|
|
||||||
"preview": "vite preview"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@ant-design/icons": "^6.0.0",
|
|
||||||
"@ant-design/pro-components": "^2.8.7",
|
|
||||||
"@ant-design/x": "^1.2.0",
|
|
||||||
"@echofly/fetch-event-source": "^3.0.2",
|
|
||||||
"@fortawesome/fontawesome-free": "^6.7.2",
|
|
||||||
"@tinyflow-ai/react": "^0.1.6",
|
|
||||||
"amis": "^6.12.0",
|
|
||||||
"antd": "^5.25.0",
|
|
||||||
"axios": "^1.9.0",
|
|
||||||
"licia": "^1.48.0",
|
|
||||||
"markdown-it": "^14.1.0",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0",
|
|
||||||
"react-router": "^7.5.3",
|
|
||||||
"styled-components": "^6.1.18"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/markdown-it": "^14.1.2",
|
|
||||||
"@types/react": "^18.2.0",
|
|
||||||
"@types/react-dom": "^18.2.0",
|
|
||||||
"@vitejs/plugin-react-swc": "^3.9.0",
|
|
||||||
"globals": "^16.0.0",
|
|
||||||
"sass": "^1.87.0",
|
|
||||||
"typescript": "~5.8.3",
|
|
||||||
"typescript-eslint": "^8.30.1",
|
|
||||||
"vite": "^6.3.5"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
6730
service-web/client/pnpm-lock.yaml
generated
6730
service-web/client/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 19 KiB |
@@ -1,10 +0,0 @@
|
|||||||
import {createRoot} from 'react-dom/client'
|
|
||||||
import {createHashRouter, RouterProvider} from 'react-router'
|
|
||||||
|
|
||||||
import './components/Registry.ts'
|
|
||||||
|
|
||||||
import {routes} from './route.tsx'
|
|
||||||
|
|
||||||
createRoot(document.getElementById('root')!).render(
|
|
||||||
<RouterProvider router={createHashRouter(routes)}/>,
|
|
||||||
)
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
import {ProLayout} from '@ant-design/pro-components'
|
|
||||||
import React, {useEffect} from 'react'
|
|
||||||
import {Outlet, useLocation, useNavigate} from 'react-router'
|
|
||||||
import {menus} from '../route.tsx'
|
|
||||||
|
|
||||||
const App: React.FC = () => {
|
|
||||||
const navigate = useNavigate()
|
|
||||||
const location = useLocation()
|
|
||||||
return (
|
|
||||||
<ProLayout
|
|
||||||
token={{
|
|
||||||
header: {
|
|
||||||
colorBgHeader: '#292f33',
|
|
||||||
colorHeaderTitle: '#ffffff',
|
|
||||||
colorTextMenu: '#dfdfdf',
|
|
||||||
colorTextMenuSecondary: '#dfdfdf',
|
|
||||||
colorTextMenuSelected: '#ffffff',
|
|
||||||
colorTextMenuActive: '#ffffff',
|
|
||||||
colorBgMenuItemSelected: '#22272b',
|
|
||||||
colorTextRightActionsItem: '#dfdfdf',
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
logo={<img src="icon.png" alt="logo"/>}
|
|
||||||
title="Hudi 服务总台"
|
|
||||||
route={menus}
|
|
||||||
location={{pathname: location.pathname}}
|
|
||||||
menu={{type: 'sub'}}
|
|
||||||
menuItemRender={(item, dom) => {
|
|
||||||
return <div onClick={() => navigate(item.path || '/')}>{dom}</div>
|
|
||||||
}}
|
|
||||||
fixSiderbar={true}
|
|
||||||
layout="mix"
|
|
||||||
splitMenus={true}
|
|
||||||
style={{minHeight: '100vh'}}
|
|
||||||
contentStyle={{backgroundColor: 'white', padding: '10px 10px 10px 20px'}}
|
|
||||||
>
|
|
||||||
<Outlet/>
|
|
||||||
</ProLayout>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default App
|
|
||||||
@@ -1,193 +0,0 @@
|
|||||||
import {ClearOutlined, UserOutlined} from '@ant-design/icons'
|
|
||||||
import {Bubble, Sender, useXAgent, useXChat, Welcome} from '@ant-design/x'
|
|
||||||
import {fetchEventSource} from '@echofly/fetch-event-source'
|
|
||||||
import {Button, Divider, Flex, Switch, Tooltip, Typography} from 'antd'
|
|
||||||
import markdownIt from 'markdown-it'
|
|
||||||
import {useRef, useState} from 'react'
|
|
||||||
import styled from 'styled-components'
|
|
||||||
|
|
||||||
const md = markdownIt({html: true, breaks: true})
|
|
||||||
const ConversationDiv = styled.div`
|
|
||||||
height: calc(100vh - 76px);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 10px;
|
|
||||||
|
|
||||||
.conversation-welcome {
|
|
||||||
flex: 1;
|
|
||||||
width: 70%;
|
|
||||||
margin: 30px auto 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.conversation-list {
|
|
||||||
flex: 1;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
padding-left: 30px;
|
|
||||||
padding-right: 30px;
|
|
||||||
|
|
||||||
think {
|
|
||||||
color: gray;
|
|
||||||
display: block;
|
|
||||||
border-left: 3px solid;
|
|
||||||
padding-left: 5px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
white-space: pre-line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.conversation-sender {
|
|
||||||
height: 100px;
|
|
||||||
padding-left: 30px;
|
|
||||||
padding-right: 30px;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
function Conversation() {
|
|
||||||
const abortController = useRef<AbortController | null>(null)
|
|
||||||
const [input, setInput] = useState<string>('')
|
|
||||||
const [think, setThink] = useState<boolean>(true)
|
|
||||||
|
|
||||||
const [agent] = useXAgent<{ role: string, content: string }>({
|
|
||||||
request: async (info, callbacks) => {
|
|
||||||
await fetchEventSource('http://127.0.0.1:8080/chat/async', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(info.messages),
|
|
||||||
signal: abortController.current?.signal,
|
|
||||||
onmessage: ev => {
|
|
||||||
console.log(ev)
|
|
||||||
callbacks.onUpdate({
|
|
||||||
id: ev.id,
|
|
||||||
event: 'delta',
|
|
||||||
data: ev.data,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onclose: () => callbacks.onSuccess([]),
|
|
||||||
})
|
|
||||||
},
|
|
||||||
})
|
|
||||||
const {onRequest, messages, setMessages} = useXChat({
|
|
||||||
agent,
|
|
||||||
transformMessage: ({originMessage, chunk}) => {
|
|
||||||
let text = ''
|
|
||||||
try {
|
|
||||||
if (chunk?.data) {
|
|
||||||
text = chunk.data
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
content: (originMessage?.content || '') + text,
|
|
||||||
role: 'assistant',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
resolveAbortController: controller => {
|
|
||||||
abortController.current = controller
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ConversationDiv>
|
|
||||||
{messages.length > 0
|
|
||||||
? (<Bubble.List
|
|
||||||
className="conversation-list"
|
|
||||||
roles={{
|
|
||||||
assistant: {
|
|
||||||
placement: 'start',
|
|
||||||
avatar: {
|
|
||||||
icon: <img src="icon.png" alt=""/>,
|
|
||||||
style: {
|
|
||||||
background: 'transparent',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
messageRender: content => {
|
|
||||||
let split = content.split('</think>')
|
|
||||||
if (split.length > 1) {
|
|
||||||
content = `${split[0]}</think>${md.render(split[1])}`
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<Typography>
|
|
||||||
<div dangerouslySetInnerHTML={{__html: content}}/>
|
|
||||||
</Typography>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
user: {
|
|
||||||
placement: 'end',
|
|
||||||
avatar: {
|
|
||||||
icon: <UserOutlined/>,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
items={messages.map(({id, message}) => ({
|
|
||||||
key: id,
|
|
||||||
...message,
|
|
||||||
}))}
|
|
||||||
/>)
|
|
||||||
: (<div className="conversation-welcome">
|
|
||||||
<Welcome
|
|
||||||
variant="borderless"
|
|
||||||
icon={<img src="icon.png" alt="icon"/>}
|
|
||||||
title="你好,我是基于大模型深度思考技术构建的 AI 运营助手"
|
|
||||||
description="我可以帮你查询、检索Hudi 服务的运行情况,分析、处理 Hudi 服务的运营故障,输出、解读 Hudi 系统整体运营报告"
|
|
||||||
/>
|
|
||||||
</div>)}
|
|
||||||
<div className="conversation-sender">
|
|
||||||
<Sender
|
|
||||||
value={input}
|
|
||||||
onChange={setInput}
|
|
||||||
onSubmit={message => {
|
|
||||||
onRequest({
|
|
||||||
message: {
|
|
||||||
role: 'user',
|
|
||||||
content: (!think && messages.length === 0) ? `/no_think ${message}` : message,
|
|
||||||
},
|
|
||||||
stream: true,
|
|
||||||
})
|
|
||||||
setInput('')
|
|
||||||
}}
|
|
||||||
onCancel={() => abortController.current?.abort()}
|
|
||||||
footer={({components}) => {
|
|
||||||
const {SendButton, LoadingButton} = components
|
|
||||||
return (
|
|
||||||
<Flex justify="space-between" align="center">
|
|
||||||
<Flex gap="small" align="center">
|
|
||||||
深度思考
|
|
||||||
<Switch
|
|
||||||
size="small"
|
|
||||||
value={think}
|
|
||||||
onChange={setThink}
|
|
||||||
disabled={messages.length > 0}
|
|
||||||
/>
|
|
||||||
<Divider type="vertical"/>
|
|
||||||
<Tooltip title="清空对话">
|
|
||||||
<Button
|
|
||||||
icon={<ClearOutlined/>}
|
|
||||||
type="text"
|
|
||||||
size="small"
|
|
||||||
onClick={() => setMessages([])}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
</Flex>
|
|
||||||
<Flex align="center">
|
|
||||||
{agent.isRequesting() ? (
|
|
||||||
<LoadingButton type="default"/>
|
|
||||||
) : (
|
|
||||||
<SendButton type="primary" disabled={false}/>
|
|
||||||
)}
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
actions={false}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</ConversationDiv>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Conversation
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
function Inspection() {
|
|
||||||
return (
|
|
||||||
<div className="inspection">
|
|
||||||
逗你的,什么都没做,哎嘿!
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Inspection
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import {useParams} from 'react-router'
|
|
||||||
import {amisRender, crudCommonOptions} from '../../../util/amis.tsx'
|
|
||||||
|
|
||||||
const DataDetail: React.FC = () => {
|
|
||||||
const {name} = useParams()
|
|
||||||
return (
|
|
||||||
<div className="import-detail h-full">
|
|
||||||
{amisRender(
|
|
||||||
{
|
|
||||||
className: 'h-full',
|
|
||||||
type: 'page',
|
|
||||||
title: `数据详情 (知识库:${name})`,
|
|
||||||
size: 'lg',
|
|
||||||
actions: [],
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'crud',
|
|
||||||
api: {
|
|
||||||
url: 'http://127.0.0.1:8080/knowledge/list_points?name=${name}',
|
|
||||||
headers: {
|
|
||||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
...crudCommonOptions(),
|
|
||||||
headerToolbar: [
|
|
||||||
'reload',
|
|
||||||
],
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: 'id',
|
|
||||||
hidden: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'text',
|
|
||||||
label: '内容',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'operation',
|
|
||||||
label: '操作',
|
|
||||||
width: 100,
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
label: '编辑',
|
|
||||||
level: 'link',
|
|
||||||
size: 'lg',
|
|
||||||
actionType: 'dialog',
|
|
||||||
dialog: {
|
|
||||||
title: '编辑文段',
|
|
||||||
size: 'md',
|
|
||||||
body: {
|
|
||||||
type: 'form',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'input-text',
|
|
||||||
name: 'id',
|
|
||||||
disabled: true,
|
|
||||||
label: '文段ID',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'editor',
|
|
||||||
label: '内容',
|
|
||||||
name: 'text',
|
|
||||||
language: 'plaintext',
|
|
||||||
options: {
|
|
||||||
lineNumbers: 'off',
|
|
||||||
wordWrap: 'bounded',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
label: '删除',
|
|
||||||
className: 'text-danger hover:text-red-600',
|
|
||||||
level: 'link',
|
|
||||||
size: 'xs',
|
|
||||||
actionType: 'ajax',
|
|
||||||
api: {
|
|
||||||
method: 'get',
|
|
||||||
headers: {
|
|
||||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
confirmText: '确认删除',
|
|
||||||
confirmTitle: '删除',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: name,
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default DataDetail
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import {useParams} from 'react-router'
|
|
||||||
import styled from 'styled-components'
|
|
||||||
import {amisRender} from '../../../util/amis.tsx'
|
|
||||||
|
|
||||||
const ImportDataDiv = styled.div`
|
|
||||||
.antd-EditorControl {
|
|
||||||
min-height: 500px !important;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const DataImport: React.FC = () => {
|
|
||||||
const {name} = useParams()
|
|
||||||
return (
|
|
||||||
<ImportDataDiv className="import-data h-full">
|
|
||||||
{amisRender({
|
|
||||||
type: 'page',
|
|
||||||
title: `数据导入 (知识库:${name})`,
|
|
||||||
body: [
|
|
||||||
[
|
|
||||||
{
|
|
||||||
className: 'h-full',
|
|
||||||
type: 'grid',
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'form',
|
|
||||||
wrapWithPanel: false,
|
|
||||||
mode: 'horizontal',
|
|
||||||
actions: [],
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
name: 'mode',
|
|
||||||
type: 'radios',
|
|
||||||
label: '解析模式',
|
|
||||||
value: 'normal',
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
value: 'normal',
|
|
||||||
label: '常规模式',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'llm',
|
|
||||||
label: '智能模式',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'qa',
|
|
||||||
label: 'Q/A模式',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'type',
|
|
||||||
type: 'radios',
|
|
||||||
label: '数据形式',
|
|
||||||
value: 'text',
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
value: 'text',
|
|
||||||
label: '文本',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'file',
|
|
||||||
label: '文件',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
visibleOn: 'type === \'text\'',
|
|
||||||
type: 'editor',
|
|
||||||
label: '数据内容',
|
|
||||||
name: 'content',
|
|
||||||
language: 'plaintext',
|
|
||||||
options: {
|
|
||||||
lineNumbers: 'off',
|
|
||||||
wordWrap: 'bounded',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
visibleOn: 'type === \'file\'',
|
|
||||||
type: 'input-file',
|
|
||||||
name: 'files',
|
|
||||||
label: '数据文件',
|
|
||||||
accept: '.txt,.csv',
|
|
||||||
autoUpload: false,
|
|
||||||
drag: true,
|
|
||||||
multiple: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
className: 'text-right',
|
|
||||||
type: 'button-toolbar',
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
label: '预览',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'submit',
|
|
||||||
label: '提交',
|
|
||||||
level: 'primary',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'card',
|
|
||||||
className: 'h-full',
|
|
||||||
header: {
|
|
||||||
title: '解析预览',
|
|
||||||
subTitle: '截取部份文本进行解析预览',
|
|
||||||
},
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'list',
|
|
||||||
source: '${rows}',
|
|
||||||
listItem: [
|
|
||||||
{
|
|
||||||
body: {
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '${content}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
})}
|
|
||||||
</ImportDataDiv>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default DataImport
|
|
||||||
@@ -1,176 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import {useNavigate} from 'react-router'
|
|
||||||
import {amisRender, crudCommonOptions, mappingField, mappingItem} from '../../../util/amis.tsx'
|
|
||||||
|
|
||||||
const strategyMapping = [
|
|
||||||
mappingItem('文本', 'Cosine'),
|
|
||||||
mappingItem('图片', 'Euclid'),
|
|
||||||
]
|
|
||||||
|
|
||||||
const statusMapping = [
|
|
||||||
mappingItem('正常', 'Green', 'label-success'),
|
|
||||||
mappingItem('优化中', 'Yellow', 'label-warning'),
|
|
||||||
mappingItem('错误', 'Red', 'label-danger'),
|
|
||||||
mappingItem('等待中', 'Grey', 'label-primary'),
|
|
||||||
]
|
|
||||||
|
|
||||||
const Knowledge: React.FC = () => {
|
|
||||||
const navigate = useNavigate()
|
|
||||||
return (
|
|
||||||
<div className="knowledge">
|
|
||||||
{amisRender(
|
|
||||||
{
|
|
||||||
type: 'page',
|
|
||||||
title: '知识库',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'crud',
|
|
||||||
api: {
|
|
||||||
url: 'http://127.0.0.1:8080/knowledge/list',
|
|
||||||
headers: {
|
|
||||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
...crudCommonOptions(),
|
|
||||||
headerToolbar: [
|
|
||||||
'reload',
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
label: '',
|
|
||||||
icon: 'fa fa-plus',
|
|
||||||
actionType: 'dialog',
|
|
||||||
dialog: {
|
|
||||||
title: '新增知识库',
|
|
||||||
size: 'md',
|
|
||||||
body: {
|
|
||||||
type: 'form',
|
|
||||||
api: {
|
|
||||||
url: 'http://127.0.0.1:8080/knowledge/add',
|
|
||||||
dataType: 'form',
|
|
||||||
headers: {
|
|
||||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'input-text',
|
|
||||||
name: 'name',
|
|
||||||
label: '名称',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'select',
|
|
||||||
name: 'strategy',
|
|
||||||
label: '类型',
|
|
||||||
value: 'Cosine',
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
label: '文本',
|
|
||||||
value: 'Cosine',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '图片',
|
|
||||||
value: 'Euclid',
|
|
||||||
disabled: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: 'name',
|
|
||||||
label: '名称',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '类型',
|
|
||||||
width: 80,
|
|
||||||
align: 'center',
|
|
||||||
...mappingField('strategy', strategyMapping),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'points',
|
|
||||||
label: '文本数',
|
|
||||||
width: 80,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '状态',
|
|
||||||
width: 80,
|
|
||||||
align: 'center',
|
|
||||||
...mappingField('status', statusMapping),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'operation',
|
|
||||||
label: '操作',
|
|
||||||
width: 150,
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
label: '详情',
|
|
||||||
level: 'link',
|
|
||||||
size: 'xs',
|
|
||||||
onEvent: {
|
|
||||||
click: {
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
actionType: 'custom',
|
|
||||||
// @ts-ignore
|
|
||||||
script: (context, action, event) => {
|
|
||||||
navigate(`/ai/knowledge/detail/${context.props.data['name']}`)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
label: '导入',
|
|
||||||
level: 'link',
|
|
||||||
size: 'xs',
|
|
||||||
onEvent: {
|
|
||||||
click: {
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
actionType: 'custom',
|
|
||||||
// @ts-ignore
|
|
||||||
script: (context, action, event) => {
|
|
||||||
navigate(`/ai/knowledge/import/${context.props.data['name']}`)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
label: '删除',
|
|
||||||
className: 'text-danger hover:text-red-600',
|
|
||||||
level: 'link',
|
|
||||||
size: 'xs',
|
|
||||||
actionType: 'ajax',
|
|
||||||
api: {
|
|
||||||
method: 'get',
|
|
||||||
url: 'http://127.0.0.1:8080/knowledge/delete?name=${name}',
|
|
||||||
headers: {
|
|
||||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
confirmText: '确认删除',
|
|
||||||
confirmTitle: '删除',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Knowledge
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import {
|
|
||||||
amisRender,
|
|
||||||
commonInfo,
|
|
||||||
crudCommonOptions,
|
|
||||||
serviceLogByAppName,
|
|
||||||
serviceLogByAppNameAndHost,
|
|
||||||
time,
|
|
||||||
} from '../../util/amis.tsx'
|
|
||||||
|
|
||||||
const cloudCrud = (title: string, path: string) => {
|
|
||||||
return {
|
|
||||||
type: 'crud',
|
|
||||||
title: title,
|
|
||||||
api: `${commonInfo.baseUrl}${path}`,
|
|
||||||
...crudCommonOptions(),
|
|
||||||
interval: 2000,
|
|
||||||
headerToolbar: ['reload'],
|
|
||||||
loadDataOnce: true,
|
|
||||||
perPage: 100,
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
label: '名称',
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: `\${name} \${IF(size === undefined, '', '<span class="font-bold label label-primary">' + size + '</span>')}`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'status',
|
|
||||||
label: '状态',
|
|
||||||
align: 'center',
|
|
||||||
width: 60,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'serviceUpTime',
|
|
||||||
label: '启动时间',
|
|
||||||
...time('serviceUpTime'),
|
|
||||||
align: 'center',
|
|
||||||
width: 160,
|
|
||||||
},
|
|
||||||
{name: 'url', label: '地址'},
|
|
||||||
{
|
|
||||||
type: 'operation',
|
|
||||||
label: '操作',
|
|
||||||
width: 100,
|
|
||||||
fixed: 'right',
|
|
||||||
className: 'nowrap',
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
label: '日志',
|
|
||||||
type: 'action',
|
|
||||||
level: 'link',
|
|
||||||
tooltip: '打开Grafana日志',
|
|
||||||
onEvent: {
|
|
||||||
click: {
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
actionType: 'custom',
|
|
||||||
// @ts-ignore
|
|
||||||
script: (context, doAction, event) => {
|
|
||||||
let data = context.props.data
|
|
||||||
let url = ''
|
|
||||||
if (data['metadata']) {
|
|
||||||
url = serviceLogByAppNameAndHost(data.serviceId, data.metadata.hostname)
|
|
||||||
} else if (data['name']) {
|
|
||||||
url = serviceLogByAppName(data.name)
|
|
||||||
}
|
|
||||||
window.open(url, '_blank')
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const Cloud: React.FC = () => {
|
|
||||||
return (
|
|
||||||
<div className="hudi-cloud">
|
|
||||||
{amisRender(
|
|
||||||
{
|
|
||||||
type: 'wrapper',
|
|
||||||
body: [
|
|
||||||
cloudCrud('服务列表', '/cloud/list'),
|
|
||||||
cloudCrud('服务列表 (IP)', '/cloud/list_ip'),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Cloud
|
|
||||||
@@ -1,635 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import {amisRender, commonInfo, crudCommonOptions, readOnlyDialogOptions} from '../../util/amis.tsx'
|
|
||||||
|
|
||||||
const color = (number: number) => {
|
|
||||||
let color = 'text-success'
|
|
||||||
if (number > 30) {
|
|
||||||
color = 'text-primary'
|
|
||||||
}
|
|
||||||
if (number > 90) {
|
|
||||||
color = 'text-danger'
|
|
||||||
}
|
|
||||||
return color
|
|
||||||
}
|
|
||||||
|
|
||||||
const versionDetailDialog = (variable: string, target: string) => {
|
|
||||||
return {
|
|
||||||
disabledOn: `${variable} === 0`,
|
|
||||||
type: 'action',
|
|
||||||
label: '详情',
|
|
||||||
level: 'link',
|
|
||||||
size: 'sm',
|
|
||||||
actionType: 'dialog',
|
|
||||||
dialog: {
|
|
||||||
title: '详情',
|
|
||||||
actions: [],
|
|
||||||
size: 'md',
|
|
||||||
closeOnEsc: false,
|
|
||||||
closeOnOutside: false,
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'service',
|
|
||||||
api: {
|
|
||||||
method: 'get',
|
|
||||||
url: `${commonInfo.baseUrl}/overview/version_detail`,
|
|
||||||
data: {
|
|
||||||
target: target,
|
|
||||||
version: '${version}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'table',
|
|
||||||
source: '${items}',
|
|
||||||
affixHeader: false,
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
label: 'Flink job id',
|
|
||||||
fixed: 'left',
|
|
||||||
type: 'wrapper',
|
|
||||||
size: 'none',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '${id}',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
level: 'link',
|
|
||||||
label: '',
|
|
||||||
icon: 'fa fa-copy',
|
|
||||||
size: 'xs',
|
|
||||||
actionType: 'copy',
|
|
||||||
content: '${id}',
|
|
||||||
tooltip: '复制 ID',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '别名',
|
|
||||||
type: 'wrapper',
|
|
||||||
fixed: 'left',
|
|
||||||
size: 'none',
|
|
||||||
className: 'nowrap',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '${alias}',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
level: 'link',
|
|
||||||
label: '',
|
|
||||||
icon: 'fa fa-copy',
|
|
||||||
size: 'xs',
|
|
||||||
actionType: 'copy',
|
|
||||||
content: '${alias}',
|
|
||||||
tooltip: '复制别名',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const tableDetailDialog = (variable: string, targetList: any) => {
|
|
||||||
return {
|
|
||||||
disabledOn: `${variable} === 0`,
|
|
||||||
type: 'action',
|
|
||||||
label: '详情',
|
|
||||||
level: 'link',
|
|
||||||
size: 'sm',
|
|
||||||
actionType: 'dialog',
|
|
||||||
dialog: {
|
|
||||||
title: '详情',
|
|
||||||
size: 'md',
|
|
||||||
...readOnlyDialogOptions(),
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'table',
|
|
||||||
source: `\${${targetList}}`,
|
|
||||||
affixHeader: false,
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
label: 'Flink job id',
|
|
||||||
fixed: 'left',
|
|
||||||
type: 'wrapper',
|
|
||||||
size: 'none',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '${id}',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
level: 'link',
|
|
||||||
label: '',
|
|
||||||
icon: 'fa fa-copy',
|
|
||||||
size: 'xs',
|
|
||||||
actionType: 'copy',
|
|
||||||
content: '${id}',
|
|
||||||
tooltip: '复制 ID',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '别名',
|
|
||||||
type: 'wrapper',
|
|
||||||
fixed: 'left',
|
|
||||||
size: 'none',
|
|
||||||
className: 'nowrap',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '${alias}',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
level: 'link',
|
|
||||||
label: '',
|
|
||||||
icon: 'fa fa-copy',
|
|
||||||
size: 'xs',
|
|
||||||
actionType: 'copy',
|
|
||||||
content: '${alias}',
|
|
||||||
tooltip: '复制别名',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const overviewYarnJob = (cluster: string, search: string, queue: string | undefined, yarnQueue: string) => {
|
|
||||||
return {
|
|
||||||
className: 'text-base leading-none',
|
|
||||||
type: 'table-view',
|
|
||||||
border: false,
|
|
||||||
padding: '0 10px 0 15px',
|
|
||||||
trs: [
|
|
||||||
{
|
|
||||||
tds: [
|
|
||||||
{
|
|
||||||
body: `${cluster}`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
padding: '0px',
|
|
||||||
body: queue === undefined ? {} : {
|
|
||||||
type: 'service',
|
|
||||||
api: `${commonInfo.baseUrl}/overview/queue?queue=${queue}`,
|
|
||||||
interval: 10000,
|
|
||||||
silentPolling: true,
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '${size}',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
padding: '0px',
|
|
||||||
width: 200,
|
|
||||||
body: {
|
|
||||||
type: 'service',
|
|
||||||
api: {
|
|
||||||
method: 'get',
|
|
||||||
url: `${commonInfo.baseUrl}/overview/yarn-cluster`,
|
|
||||||
data: {
|
|
||||||
cluster: cluster,
|
|
||||||
queue: yarnQueue,
|
|
||||||
},
|
|
||||||
// @ts-ignore
|
|
||||||
adaptor: function (payload, response) {
|
|
||||||
let rootUsed = (payload['data']['root']['usedCapacity'] * 100 / payload['data']['root']['capacity'])
|
|
||||||
let targetUsed = (payload['data']['target']['absoluteUsedCapacity'] * 100 / payload['data']['target']['absoluteMaxCapacity'])
|
|
||||||
return {
|
|
||||||
...payload,
|
|
||||||
data: {
|
|
||||||
...payload.data,
|
|
||||||
rootUsed: rootUsed,
|
|
||||||
rootUsedColor: color(rootUsed),
|
|
||||||
targetUsed: targetUsed,
|
|
||||||
targetUsedColor: color(targetUsed),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
interval: 10000,
|
|
||||||
silentPolling: true,
|
|
||||||
body: {
|
|
||||||
type: 'table-view',
|
|
||||||
border: false,
|
|
||||||
trs: [
|
|
||||||
{
|
|
||||||
tds: [
|
|
||||||
{
|
|
||||||
body: {
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '<span class="font-bold ${rootUsedColor}">${ROUND(rootUsed, 0)}%</span>',
|
|
||||||
},
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
body: {
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '<span class="font-bold ${targetUsedColor}">${ROUND(targetUsed, 0)}%</span>',
|
|
||||||
},
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
padding: '0px',
|
|
||||||
width: 200,
|
|
||||||
body: {
|
|
||||||
type: 'service',
|
|
||||||
api: {
|
|
||||||
url: `${commonInfo.baseUrl}/overview/yarn-job`,
|
|
||||||
data: {
|
|
||||||
cluster: cluster,
|
|
||||||
search: search,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
interval: 10000,
|
|
||||||
silentPolling: true,
|
|
||||||
body: {
|
|
||||||
type: 'table-view',
|
|
||||||
border: false,
|
|
||||||
trs: [
|
|
||||||
{
|
|
||||||
tds: [
|
|
||||||
{
|
|
||||||
body: {
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '<span class=\'font-bold text-cyan-300\'>${scheduling}</span>',
|
|
||||||
},
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
body: {
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '<span class="font-bold text-success">${running}</span>',
|
|
||||||
},
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const Overview: React.FC = () => {
|
|
||||||
return (
|
|
||||||
<div className="hudi-overview">
|
|
||||||
{amisRender(
|
|
||||||
{
|
|
||||||
type: 'wrapper',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'service',
|
|
||||||
// language=JavaScript
|
|
||||||
dataProvider: 'const timer = setInterval(() => {\n setData({date: new Date().toLocaleString()})\n}, 1000)\nreturn () => {\n clearInterval(timer)\n}',
|
|
||||||
body: [
|
|
||||||
'当前时间:',
|
|
||||||
{
|
|
||||||
type: 'tpl',
|
|
||||||
className: 'font-bold',
|
|
||||||
tpl: '${date}',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{type: 'divider'},
|
|
||||||
{
|
|
||||||
type: 'crud',
|
|
||||||
title: '同步表数量',
|
|
||||||
api: `${commonInfo.baseUrl}/overview`,
|
|
||||||
...crudCommonOptions(),
|
|
||||||
interval: 60000,
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: 'type',
|
|
||||||
label: '表类型',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'total',
|
|
||||||
label: '总表数',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'focus',
|
|
||||||
label: '重点表',
|
|
||||||
className: 'text-danger font-bold',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '普通表',
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '${total - focus}',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'crud',
|
|
||||||
title: '同步表数量',
|
|
||||||
api: `${commonInfo.baseUrl}/overview/sync_running_status`,
|
|
||||||
...crudCommonOptions(),
|
|
||||||
interval: 10000,
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: 'type',
|
|
||||||
label: '类型',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'total',
|
|
||||||
label: '任务数',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'running',
|
|
||||||
label: '运行中',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'stopped',
|
|
||||||
label: '已停止',
|
|
||||||
className: 'text-danger font-bold',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'operation',
|
|
||||||
label: '操作',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
buttons: [
|
|
||||||
tableDetailDialog('stopped', 'list'),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
className: 'pl-2 my-5',
|
|
||||||
type: 'wrapper',
|
|
||||||
size: 'none',
|
|
||||||
body: {
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '同步集群资源用量情况',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'table-view',
|
|
||||||
border: false,
|
|
||||||
trs: [
|
|
||||||
{
|
|
||||||
background: '#F9F9F9',
|
|
||||||
tds: [
|
|
||||||
{
|
|
||||||
bold: true,
|
|
||||||
body: '集群',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
bold: true,
|
|
||||||
body: '集群资源',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
bold: true,
|
|
||||||
body: '队列资源',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
bold: true,
|
|
||||||
body: '调度中',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
bold: true,
|
|
||||||
body: '运行中',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
overviewYarnJob(commonInfo.clusters.sync_names(), 'Sync', undefined, 'default'),
|
|
||||||
{type: 'divider'},
|
|
||||||
{
|
|
||||||
className: 'pl-2 my-5',
|
|
||||||
type: 'wrapper',
|
|
||||||
size: 'none',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '压缩集群资源用量情况',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
className: 'mt-2',
|
|
||||||
type: 'service',
|
|
||||||
api: `${commonInfo.baseUrl}/overview/queue?queue=compaction-queue-pre`,
|
|
||||||
interval: 10000,
|
|
||||||
silentPolling: true,
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '预调度队列:<span class="font-bold">${size}</span>',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'table-view',
|
|
||||||
border: false,
|
|
||||||
bold: true,
|
|
||||||
trs: [
|
|
||||||
{
|
|
||||||
background: '#F9F9F9',
|
|
||||||
tds: [
|
|
||||||
{
|
|
||||||
bold: true,
|
|
||||||
body: '集群',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
bold: true,
|
|
||||||
body: '队列',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
bold: true,
|
|
||||||
body: '集群资源',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
bold: true,
|
|
||||||
body: '队列资源',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
bold: true,
|
|
||||||
body: '调度中',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
bold: true,
|
|
||||||
body: '运行中',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
// @ts-ignore
|
|
||||||
...Object.keys(commonInfo.clusters.compaction).map(name => overviewYarnJob(name, 'Compaction', `compaction-queue-${name}`, commonInfo.clusters.compaction[name])),
|
|
||||||
{type: 'divider'},
|
|
||||||
{
|
|
||||||
type: 'service',
|
|
||||||
api: `${commonInfo.baseUrl}/overview/version`,
|
|
||||||
interval: 10000,
|
|
||||||
silentPolling: true,
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'table',
|
|
||||||
title: '跨天情况 (${version})',
|
|
||||||
source: '${items}',
|
|
||||||
...crudCommonOptions(),
|
|
||||||
headerToolbar: [
|
|
||||||
'${version}',
|
|
||||||
],
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: 'type',
|
|
||||||
label: '类型',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'unReceive',
|
|
||||||
label: '未接收',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'operation',
|
|
||||||
label: '操作',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
buttons: [
|
|
||||||
versionDetailDialog('unReceive', 'unReceive_${key}'),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'unScheduled',
|
|
||||||
label: '未跨天',
|
|
||||||
className: 'text-danger font-bold',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'operation',
|
|
||||||
label: '操作',
|
|
||||||
width: 100,
|
|
||||||
align: 'center',
|
|
||||||
buttons: [
|
|
||||||
versionDetailDialog('unScheduled', 'unScheduled_${key}'),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'crud',
|
|
||||||
title: '调度策略',
|
|
||||||
api: `${commonInfo.baseUrl}/overview/schedule_jobs`,
|
|
||||||
...crudCommonOptions(),
|
|
||||||
interval: 60000,
|
|
||||||
loadDataOnce: true,
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: 'job',
|
|
||||||
label: '策略描述',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'trigger',
|
|
||||||
label: 'Cron表达式',
|
|
||||||
className: 'font-mono',
|
|
||||||
width: 250,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'crud',
|
|
||||||
title: '监控指标运行进度',
|
|
||||||
api: `${commonInfo.baseUrl}/overview/monitor_progress`,
|
|
||||||
...crudCommonOptions(),
|
|
||||||
interval: 2000,
|
|
||||||
loadDataOnce: true,
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: 'name',
|
|
||||||
label: '名称',
|
|
||||||
width: 150,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'running',
|
|
||||||
label: '状态',
|
|
||||||
type: 'mapping',
|
|
||||||
width: 70,
|
|
||||||
map: {
|
|
||||||
'true': '运行中',
|
|
||||||
'false': '未运行',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '进度',
|
|
||||||
type: 'progress',
|
|
||||||
value: '${ROUND(progress * 100)}',
|
|
||||||
map: 'bg-primary',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Overview
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
import {
|
|
||||||
amisRender,
|
|
||||||
commonInfo,
|
|
||||||
copyField,
|
|
||||||
crudCommonOptions,
|
|
||||||
paginationCommonOptions,
|
|
||||||
time,
|
|
||||||
yarnQueueCrud,
|
|
||||||
} from '../../util/amis.tsx'
|
|
||||||
|
|
||||||
const queueCrud = (name: string) => {
|
|
||||||
return {
|
|
||||||
type: 'crud',
|
|
||||||
title: name,
|
|
||||||
api: `${commonInfo.baseUrl}/queue/all?name=${name}`,
|
|
||||||
...crudCommonOptions(),
|
|
||||||
interval: 10000,
|
|
||||||
loadDataOnce: true,
|
|
||||||
perPage: 5,
|
|
||||||
headerToolbar: [
|
|
||||||
'reload',
|
|
||||||
'filter-toggler',
|
|
||||||
{
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '共 <span class=\'text-primary font-bold\'>${total|default:0}</span> 个任务',
|
|
||||||
},
|
|
||||||
paginationCommonOptions(false),
|
|
||||||
],
|
|
||||||
footerToolbar: [],
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: 'data.flinkJobId',
|
|
||||||
label: '任务 ID',
|
|
||||||
width: 190,
|
|
||||||
...copyField('data.flinkJobId'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'data.alias',
|
|
||||||
label: '别名',
|
|
||||||
className: 'nowrap',
|
|
||||||
...copyField('data.alias'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'data.batch',
|
|
||||||
label: '批次',
|
|
||||||
width: 100,
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '<span class="label label-warning">${data.batch}</span>',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'priority',
|
|
||||||
label: '优先级',
|
|
||||||
width: 60,
|
|
||||||
align: 'center',
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '<span class="label bg-info">${priority}</span>',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'data.comment',
|
|
||||||
label: '备注',
|
|
||||||
className: 'nowrap',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'createTime',
|
|
||||||
label: '任务提交时间',
|
|
||||||
...time('createTime'),
|
|
||||||
width: 160,
|
|
||||||
fixed: 'right',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const Queue = () => {
|
|
||||||
let items = []
|
|
||||||
for (let name of Object.keys(commonInfo.clusters.compaction)) {
|
|
||||||
// @ts-ignore
|
|
||||||
items.push(yarnQueueCrud(name, commonInfo.clusters.compaction[name]))
|
|
||||||
items.push(queueCrud(`compaction-queue-${name}`))
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<div className="hudi-queue">
|
|
||||||
{amisRender(
|
|
||||||
{
|
|
||||||
type: 'wrapper',
|
|
||||||
body: [
|
|
||||||
queueCrud('compaction-queue-pre'),
|
|
||||||
...items,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Queue
|
|
||||||
@@ -1,256 +0,0 @@
|
|||||||
import {
|
|
||||||
aliasTextInput,
|
|
||||||
amisRender,
|
|
||||||
commonInfo,
|
|
||||||
compactionStatusMapping,
|
|
||||||
crudCommonOptions,
|
|
||||||
filterableField,
|
|
||||||
flinkJobDialog,
|
|
||||||
flinkJobIdTextInput,
|
|
||||||
hudiTableTypeMapping,
|
|
||||||
mappingField,
|
|
||||||
paginationCommonOptions,
|
|
||||||
runModeMapping,
|
|
||||||
tableMetaDialog,
|
|
||||||
tableRunningStateMapping,
|
|
||||||
timeAndFrom,
|
|
||||||
} from '../../util/amis.tsx'
|
|
||||||
|
|
||||||
function Table() {
|
|
||||||
return (
|
|
||||||
<div className="hudi-table">
|
|
||||||
{amisRender(
|
|
||||||
{
|
|
||||||
type: 'wrapper',
|
|
||||||
size: 'none',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
id: 'table-service',
|
|
||||||
type: 'service',
|
|
||||||
data: {},
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'crud',
|
|
||||||
api: {
|
|
||||||
method: 'get',
|
|
||||||
url: `${commonInfo.baseUrl}/table/list`,
|
|
||||||
data: {
|
|
||||||
page: '${page|default:undefined}',
|
|
||||||
count: '${perPage|default:undefined}',
|
|
||||||
order: '${orderBy|default:undefined}',
|
|
||||||
direction: '${orderDir|default:undefined}',
|
|
||||||
search_flink_job_id: '${flinkJobId|default:undefined}',
|
|
||||||
search_alias: '${alias|default:undefined}',
|
|
||||||
filter_hudi_table_type: '${tableMeta\\.hudi\\.targetTableType|default:undefined}',
|
|
||||||
filter_run_mode: '${flinkJob\\.runMode|default:undefined}',
|
|
||||||
filter_compaction_status: '${syncState\\.compactionStatus|default:undefined}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
...crudCommonOptions(),
|
|
||||||
// interval: 10000,
|
|
||||||
filter: {
|
|
||||||
title: '表筛选',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'group',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
...flinkJobIdTextInput('58d0da94-1b3c-4234-948d-482ae3425e70'),
|
|
||||||
size: 'lg',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
...aliasTextInput('58d0da94-1b3c-4234-948d-482ae3425e70'),
|
|
||||||
size: 'lg',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
type: 'submit',
|
|
||||||
level: 'primary',
|
|
||||||
label: '查询',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'reset',
|
|
||||||
label: '重置',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
filterTogglable: true,
|
|
||||||
filterDefaultVisible: true,
|
|
||||||
perPage: 20,
|
|
||||||
headerToolbar: [
|
|
||||||
'reload',
|
|
||||||
'filter-toggler',
|
|
||||||
paginationCommonOptions(),
|
|
||||||
],
|
|
||||||
footerToolbar: [
|
|
||||||
paginationCommonOptions(),
|
|
||||||
],
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
label: 'Flink job id',
|
|
||||||
width: 195,
|
|
||||||
fixed: 'left',
|
|
||||||
type: 'wrapper',
|
|
||||||
size: 'none',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
level: 'link',
|
|
||||||
label: '${flinkJobId}',
|
|
||||||
size: 'xs',
|
|
||||||
actionType: 'dialog',
|
|
||||||
tooltip: '查看详情',
|
|
||||||
dialog: flinkJobDialog(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
level: 'link',
|
|
||||||
label: '',
|
|
||||||
icon: 'fa fa-copy',
|
|
||||||
size: 'xs',
|
|
||||||
actionType: 'copy',
|
|
||||||
content: '${flinkJobId}',
|
|
||||||
tooltip: '复制 ID',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '别名',
|
|
||||||
type: 'wrapper',
|
|
||||||
fixed: 'left',
|
|
||||||
size: 'none',
|
|
||||||
className: 'nowrap',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
level: 'link',
|
|
||||||
label: '${tableMeta.alias}',
|
|
||||||
size: 'xs',
|
|
||||||
actionType: 'dialog',
|
|
||||||
tooltip: '查看详情',
|
|
||||||
dialog: tableMetaDialog(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
level: 'link',
|
|
||||||
label: '',
|
|
||||||
icon: 'fa fa-copy',
|
|
||||||
size: 'xs',
|
|
||||||
actionType: 'copy',
|
|
||||||
content: '${tableMeta.alias}',
|
|
||||||
tooltip: '复制别名',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'tableMeta.hudi.targetTableType',
|
|
||||||
label: '表类型',
|
|
||||||
width: 60,
|
|
||||||
align: 'center',
|
|
||||||
...mappingField('tableMeta.hudi.targetTableType', hudiTableTypeMapping),
|
|
||||||
filterable: filterableField(hudiTableTypeMapping, true),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'flinkJob.runMode',
|
|
||||||
label: '任务类型',
|
|
||||||
width: 60,
|
|
||||||
align: 'center',
|
|
||||||
...mappingField('flinkJob.runMode', runModeMapping),
|
|
||||||
filterable: filterableField(runModeMapping, true),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'syncRunning',
|
|
||||||
label: '同步运行状态',
|
|
||||||
align: 'center',
|
|
||||||
...mappingField('syncRunning', tableRunningStateMapping),
|
|
||||||
className: 'bg-green-50',
|
|
||||||
width: 75,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'source_start_time',
|
|
||||||
label: '同步启动时间',
|
|
||||||
...timeAndFrom('syncState.sourceStartTime', 'syncState.sourceStartTimeFromNow', '未启动'),
|
|
||||||
sortable: true,
|
|
||||||
className: 'bg-green-50',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'source_receive_time',
|
|
||||||
label: '同步接收时间',
|
|
||||||
...timeAndFrom('syncState.sourceReceiveTime', 'syncState.sourceReceiveTimeFromNow', '无数据'),
|
|
||||||
sortable: true,
|
|
||||||
className: 'bg-green-50',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'source_checkpoint_time',
|
|
||||||
label: '同步心跳时间',
|
|
||||||
...timeAndFrom('syncState.sourceCheckpointTime', 'syncState.sourceCheckpointTimeFromNow', '未启动'),
|
|
||||||
sortable: true,
|
|
||||||
className: 'bg-green-50',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'source_publish_time',
|
|
||||||
label: '源端发布时间',
|
|
||||||
...timeAndFrom('syncState.sourcePublishTime', 'syncState.sourcePublishTimeFromNow', '无增量'),
|
|
||||||
sortable: true,
|
|
||||||
className: 'bg-green-50',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'source_operation_time',
|
|
||||||
label: '源端业务时间',
|
|
||||||
...timeAndFrom('syncState.sourceOperationTime', 'syncState.sourceOperationTimeFromNow', '无增量'),
|
|
||||||
sortable: true,
|
|
||||||
className: 'bg-green-50',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'compactionRunning',
|
|
||||||
label: '压缩运行状态',
|
|
||||||
align: 'center',
|
|
||||||
...mappingField('compactionRunning', tableRunningStateMapping),
|
|
||||||
className: 'bg-cyan-50',
|
|
||||||
width: 75,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'syncState.compactionStatus',
|
|
||||||
label: '压缩状态',
|
|
||||||
width: 60,
|
|
||||||
align: 'center',
|
|
||||||
...mappingField('syncState.compactionStatus', compactionStatusMapping),
|
|
||||||
filterable: filterableField(compactionStatusMapping, true),
|
|
||||||
className: 'bg-cyan-50',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'compaction_start_time',
|
|
||||||
label: '压缩启动时间',
|
|
||||||
...timeAndFrom('syncState.compactionStartTime', 'syncState.compactionStartTimeFromNow'),
|
|
||||||
sortable: true,
|
|
||||||
className: 'bg-cyan-50',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'compaction_latest_operation_time',
|
|
||||||
label: '压缩业务时间',
|
|
||||||
...timeAndFrom('syncState.compactionLatestOperationTime', 'syncState.compactionLatestOperationTimeFromNow', '无'),
|
|
||||||
sortable: true,
|
|
||||||
className: 'bg-cyan-50',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'compaction_finish_time',
|
|
||||||
label: '压缩完成时间',
|
|
||||||
...timeAndFrom('syncState.compactionFinishTime', 'syncState.compactionFinishTimeFromNow'),
|
|
||||||
sortable: true,
|
|
||||||
className: 'bg-cyan-50',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Table
|
|
||||||
@@ -1,195 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import {amisRender, commonInfo, paginationCommonOptions, serviceLogByAppName, yarnCrudColumns} from '../../util/amis.tsx'
|
|
||||||
|
|
||||||
const Task: React.FC = () => {
|
|
||||||
return (
|
|
||||||
<div className="hudi-task">
|
|
||||||
{amisRender(
|
|
||||||
{
|
|
||||||
type: 'wrapper',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'form',
|
|
||||||
title: '检索文件',
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
type: 'submit',
|
|
||||||
label: '提交任务',
|
|
||||||
actionType: 'ajax',
|
|
||||||
api: {
|
|
||||||
method: 'get',
|
|
||||||
url: `${commonInfo.baseUrl}/task/scan`,
|
|
||||||
data: {
|
|
||||||
key: '${key|default:undefined}',
|
|
||||||
hdfs: '${hdfs|default:undefined}',
|
|
||||||
pulsar: '${pulsar|default:undefined}',
|
|
||||||
topic: '${topic|default:undefined}',
|
|
||||||
mode: '${scan_mode|default:undefined}',
|
|
||||||
fields: '${fields|default:undefined}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
name: 'scan_mode',
|
|
||||||
type: 'checkboxes',
|
|
||||||
label: '检索范围',
|
|
||||||
checkAll: true,
|
|
||||||
required: true,
|
|
||||||
value: 'log',
|
|
||||||
options: [
|
|
||||||
{label: '消息队列', value: 'queue'},
|
|
||||||
{label: '日志文件', value: 'log'},
|
|
||||||
{label: '数据文件', value: 'base'},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input-text',
|
|
||||||
name: 'key',
|
|
||||||
label: '检索字段',
|
|
||||||
required: true,
|
|
||||||
clearable: true,
|
|
||||||
description: '检索带有该字符的记录',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input-text',
|
|
||||||
name: 'hdfs',
|
|
||||||
label: 'HDFS路经',
|
|
||||||
requiredOn: '${CONTAINS(scan_mode, \'log\') || CONTAINS(scan_mode, \'base\')}',
|
|
||||||
visibleOn: '${CONTAINS(scan_mode, \'log\') || CONTAINS(scan_mode, \'base\')}',
|
|
||||||
clearable: true,
|
|
||||||
description: '输入表HDFS路径',
|
|
||||||
autoComplete: `${commonInfo.baseUrl}/table/all_hdfs?key=$term`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input-text',
|
|
||||||
name: 'fields',
|
|
||||||
label: '指定字段',
|
|
||||||
visibleOn: '${CONTAINS(scan_mode, \'base\')}',
|
|
||||||
clearable: true,
|
|
||||||
description: '逗号分隔,可以大幅提高parquet文件检索速度,但无法获取指定字段外的字段内容',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'group',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'input-text',
|
|
||||||
name: 'topic',
|
|
||||||
label: 'Pulsar主题',
|
|
||||||
requiredOn: '${CONTAINS(scan_mode, \'queue\')}',
|
|
||||||
visibleOn: '${CONTAINS(scan_mode, \'queue\')}',
|
|
||||||
clearable: true,
|
|
||||||
description: '输入Pulsar主题',
|
|
||||||
autoComplete: `${commonInfo.baseUrl}/table/all_pulsar_topic?key=$term`,
|
|
||||||
columnRatio: 4,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input-text',
|
|
||||||
name: 'pulsar',
|
|
||||||
label: 'Pulsar地址',
|
|
||||||
requiredOn: '${CONTAINS(scan_mode, \'queue\')}',
|
|
||||||
visibleOn: '${CONTAINS(scan_mode, \'queue\')}',
|
|
||||||
clearable: true,
|
|
||||||
description: '输入Pulsar地址',
|
|
||||||
autoComplete: `${commonInfo.baseUrl}/table/all_pulsar?key=$term`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'form',
|
|
||||||
title: '综合查询',
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
label: '总数&最后操作时间',
|
|
||||||
actionType: 'ajax',
|
|
||||||
api: {
|
|
||||||
method: 'get',
|
|
||||||
url: `${commonInfo.baseUrl}/task/table_summary`,
|
|
||||||
data: {
|
|
||||||
hdfs: '${hdfs|default:undefined}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
label: '最后10条记录',
|
|
||||||
actionType: 'ajax',
|
|
||||||
api: {
|
|
||||||
method: 'get',
|
|
||||||
url: `${commonInfo.baseUrl}/task/table_sampling`,
|
|
||||||
data: {
|
|
||||||
hdfs: '${hdfs|default:undefined}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'input-text',
|
|
||||||
name: 'hdfs',
|
|
||||||
label: 'HDFS路经',
|
|
||||||
required: true,
|
|
||||||
clearable: true,
|
|
||||||
description: '输入表HDFS路径',
|
|
||||||
autoComplete: `${commonInfo.baseUrl}/table/all_hdfs?key=$term`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'crud',
|
|
||||||
api: {
|
|
||||||
method: 'get',
|
|
||||||
url: `${commonInfo.baseUrl}/yarn/job_list`,
|
|
||||||
data: {
|
|
||||||
clusters: commonInfo.clusters.sync_names(),
|
|
||||||
page: '${page|default:undefined}',
|
|
||||||
count: '${perPage|default:undefined}',
|
|
||||||
order: '${orderBy|default:undefined}',
|
|
||||||
direction: '${orderDir|default:undefined}',
|
|
||||||
filter_state: '${state|default:undefined}',
|
|
||||||
filter_final_status: '${finalStatus|default:undefined}',
|
|
||||||
search_id: '${id|default:undefined}',
|
|
||||||
search_name: 'Service_Task',
|
|
||||||
precise: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
affixHeader: false,
|
|
||||||
interval: 10000,
|
|
||||||
syncLocation: false,
|
|
||||||
silentPolling: true,
|
|
||||||
resizable: false,
|
|
||||||
perPage: 10,
|
|
||||||
headerToolbar: [
|
|
||||||
'reload',
|
|
||||||
{
|
|
||||||
label: '任务管理器日志',
|
|
||||||
type: 'action',
|
|
||||||
tooltip: '打开Grafana日志',
|
|
||||||
onEvent: {
|
|
||||||
click: {
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
actionType: 'custom',
|
|
||||||
script: () => window.open(serviceLogByAppName('service-executor-manager'), '_blank'),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
paginationCommonOptions(),
|
|
||||||
],
|
|
||||||
footerToolbar: [],
|
|
||||||
columns: yarnCrudColumns(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Task
|
|
||||||
@@ -1,316 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import {
|
|
||||||
aliasTextInput,
|
|
||||||
amisRender,
|
|
||||||
commonInfo,
|
|
||||||
crudCommonOptions,
|
|
||||||
flinkJobIdTextInput,
|
|
||||||
formReloadFlinkJobIdTextInputAndAliasTextInput,
|
|
||||||
hdfsDialog,
|
|
||||||
paginationCommonOptions,
|
|
||||||
readOnlyDialogOptions,
|
|
||||||
timelineColumns,
|
|
||||||
} from '../../util/amis.tsx'
|
|
||||||
|
|
||||||
const Tool: React.FC = () => {
|
|
||||||
return (
|
|
||||||
<div className="hudi-tool">
|
|
||||||
{amisRender(
|
|
||||||
{
|
|
||||||
type: 'wrapper',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'panel',
|
|
||||||
title: '乱七八糟小工具',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
label: 'SQL日志',
|
|
||||||
actionType: 'dialog',
|
|
||||||
dialog: {
|
|
||||||
title: '日志',
|
|
||||||
...readOnlyDialogOptions(),
|
|
||||||
size: 'lg',
|
|
||||||
body: {
|
|
||||||
type: 'crud',
|
|
||||||
api: `${commonInfo.baseUrl}/log/query_sql_log`,
|
|
||||||
...crudCommonOptions(),
|
|
||||||
loadDataOnce: true,
|
|
||||||
perPage: 50,
|
|
||||||
headerToolbar: [
|
|
||||||
'reload',
|
|
||||||
paginationCommonOptions(undefined, 10),
|
|
||||||
],
|
|
||||||
footerToolbar: [
|
|
||||||
paginationCommonOptions(undefined, 10),
|
|
||||||
],
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: 'sql',
|
|
||||||
label: 'SQL',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'createTime',
|
|
||||||
label: '执行时间',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
label: 'ZK节点',
|
|
||||||
className: 'ml-2',
|
|
||||||
actionType: 'dialog',
|
|
||||||
dialog: {
|
|
||||||
title: '日志',
|
|
||||||
...readOnlyDialogOptions(),
|
|
||||||
size: 'lg',
|
|
||||||
body: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'form',
|
|
||||||
title: 'HDFS文件管理器',
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
label: '直接下载',
|
|
||||||
type: 'action',
|
|
||||||
onEvent: {
|
|
||||||
click: {
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
actionType: 'custom',
|
|
||||||
// @ts-ignore
|
|
||||||
script: (context, action, event) => {
|
|
||||||
let downloadUrl = `${event.data.base}/hudi/hdfs_download?root=${encodeURI(event.data.hdfs)}`
|
|
||||||
window.open(downloadUrl, '_blank')
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'submit',
|
|
||||||
label: '查看',
|
|
||||||
actionType: 'dialog',
|
|
||||||
dialog: hdfsDialog('hdfs'),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'input-text',
|
|
||||||
name: 'hdfs',
|
|
||||||
label: 'HDFS根路经',
|
|
||||||
required: true,
|
|
||||||
clearable: true,
|
|
||||||
description: '输入表HDFS路径',
|
|
||||||
autoComplete: `${commonInfo.baseUrl}/table/all_hdfs?key=$term`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'form',
|
|
||||||
title: '查询时间线',
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
type: 'submit',
|
|
||||||
label: '查询时间线',
|
|
||||||
actionType: 'dialog',
|
|
||||||
dialog: {
|
|
||||||
title: 'Hudi 表时间线',
|
|
||||||
actions: [],
|
|
||||||
size: 'lg',
|
|
||||||
body: {
|
|
||||||
type: 'crud',
|
|
||||||
api: {
|
|
||||||
method: 'get',
|
|
||||||
url: `${commonInfo.baseUrl}/hudi/timeline/list_hdfs`,
|
|
||||||
data: {
|
|
||||||
page: '${page|default:undefined}',
|
|
||||||
count: '${perPage|default:undefined}',
|
|
||||||
order: '${orderBy|default:undefined}',
|
|
||||||
direction: '${orderDir|default:undefined}',
|
|
||||||
hdfs: '${hdfs|default:undefined}',
|
|
||||||
filter_type: '${type|default:active}',
|
|
||||||
filter_action: '${action|default:undefined}',
|
|
||||||
filter_state: '${state|default:undefined}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
...crudCommonOptions(),
|
|
||||||
perPage: 50,
|
|
||||||
headerToolbar: [
|
|
||||||
'reload',
|
|
||||||
paginationCommonOptions(undefined, 10),
|
|
||||||
],
|
|
||||||
footerToolbar: [
|
|
||||||
paginationCommonOptions(undefined, 10),
|
|
||||||
],
|
|
||||||
columns: timelineColumns(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'submit',
|
|
||||||
label: '查询表结构',
|
|
||||||
actionType: 'dialog',
|
|
||||||
dialog: {
|
|
||||||
title: 'Hudi 表结构',
|
|
||||||
actions: [],
|
|
||||||
size: 'lg',
|
|
||||||
body: {
|
|
||||||
type: 'service',
|
|
||||||
api: {
|
|
||||||
method: 'get',
|
|
||||||
url: `${commonInfo.baseUrl}/hudi/schema`,
|
|
||||||
data: {
|
|
||||||
hdfs: '${hdfs|default:undefined}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
body: {
|
|
||||||
type: 'page',
|
|
||||||
body: {
|
|
||||||
type: 'json',
|
|
||||||
source: '${detail}',
|
|
||||||
levelExpand: 3,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'input-text',
|
|
||||||
name: 'hdfs',
|
|
||||||
label: 'HDFS路经',
|
|
||||||
required: true,
|
|
||||||
clearable: true,
|
|
||||||
description: '输入表HDFS路径',
|
|
||||||
autoComplete: `${commonInfo.baseUrl}/table/all_hdfs?key=$term`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'form',
|
|
||||||
title: '提交压缩任务',
|
|
||||||
api: {
|
|
||||||
method: 'get',
|
|
||||||
url: `${commonInfo.baseUrl}/schedule/table`,
|
|
||||||
data: {
|
|
||||||
flink_job_id: '${flinkJobId|default:undefined}',
|
|
||||||
alias: '${alias|default:undefined}',
|
|
||||||
recommend: '${recommend === \'undefined\' ? undefined : recommend|default:undefined}',
|
|
||||||
force: '${force === \'undefined\' ? undefined : force|default:undefined}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
...formReloadFlinkJobIdTextInputAndAliasTextInput('0fe6a96c-6b6e-4346-b18e-c631c2389f48'),
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'group',
|
|
||||||
body: [
|
|
||||||
flinkJobIdTextInput('0fe6a96c-6b6e-4346-b18e-c631c2389f48', true),
|
|
||||||
aliasTextInput('0fe6a96c-6b6e-4346-b18e-c631c2389f48', true),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'group',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
name: 'recommend',
|
|
||||||
type: 'radios',
|
|
||||||
label: '优先指定集群',
|
|
||||||
selectFirst: true,
|
|
||||||
options: [
|
|
||||||
{label: '无', value: 'undefined'},
|
|
||||||
...Object.keys(commonInfo.clusters.compaction)
|
|
||||||
.map(name => {
|
|
||||||
return {label: name, value: name}
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'force',
|
|
||||||
type: 'radios',
|
|
||||||
label: '强制指定集群',
|
|
||||||
selectFirst: true,
|
|
||||||
options: [
|
|
||||||
{label: '无', value: 'undefined'},
|
|
||||||
...Object.keys(commonInfo.clusters.compaction)
|
|
||||||
.map(name => {
|
|
||||||
return {label: name, value: name}
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'form',
|
|
||||||
title: '批量提交压缩任务',
|
|
||||||
api: {
|
|
||||||
method: 'post',
|
|
||||||
url: `${commonInfo.baseUrl}/schedule/table_batch`,
|
|
||||||
dataType: 'form',
|
|
||||||
},
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
name: 'lines',
|
|
||||||
type: 'textarea',
|
|
||||||
label: '表信息 (flink_job_id alias\\n)',
|
|
||||||
clearable: true,
|
|
||||||
minRows: 5,
|
|
||||||
maxRows: 5,
|
|
||||||
className: 'no-resize',
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'form',
|
|
||||||
title: '停止所有压缩任务',
|
|
||||||
api: {
|
|
||||||
method: 'get',
|
|
||||||
url: `${commonInfo.baseUrl}/schedule/stop_all`,
|
|
||||||
data: {
|
|
||||||
flink_job_id: '${flinkJobId|default:undefined}',
|
|
||||||
alias: '${alias|default:undefined}',
|
|
||||||
disable_meta: '${disableMeta|default:undefined}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
...formReloadFlinkJobIdTextInputAndAliasTextInput('163e043e-8cee-41fd-b5a4-0442ac682aec'),
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'group',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
...flinkJobIdTextInput('163e043e-8cee-41fd-b5a4-0442ac682aec', true),
|
|
||||||
columnRatio: 5,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
...aliasTextInput('163e043e-8cee-41fd-b5a4-0442ac682aec', true),
|
|
||||||
columnRatio: 5,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'disableMeta',
|
|
||||||
type: 'checkbox',
|
|
||||||
label: '是否禁用表',
|
|
||||||
option: '表status设为n',
|
|
||||||
columnRatio: 2,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Tool
|
|
||||||
@@ -1,185 +0,0 @@
|
|||||||
import {
|
|
||||||
aliasTextInput,
|
|
||||||
amisRender,
|
|
||||||
commonInfo,
|
|
||||||
crudCommonOptions,
|
|
||||||
filterableField,
|
|
||||||
flinkJobDialog,
|
|
||||||
flinkJobIdTextInput,
|
|
||||||
mappingField,
|
|
||||||
paginationCommonOptions,
|
|
||||||
tableMetaDialog,
|
|
||||||
versionUpdateStateMapping,
|
|
||||||
} from '../../util/amis.tsx'
|
|
||||||
|
|
||||||
function Version() {
|
|
||||||
return (
|
|
||||||
<div className="hudi-version">
|
|
||||||
{amisRender(
|
|
||||||
{
|
|
||||||
type: 'wrapper',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'crud',
|
|
||||||
api: {
|
|
||||||
method: 'get',
|
|
||||||
url: `${commonInfo.baseUrl}/version_update/list`,
|
|
||||||
data: {
|
|
||||||
page: '${page|default:undefined}',
|
|
||||||
count: '${perPage|default:undefined}',
|
|
||||||
order: '${orderBy|default:undefined}',
|
|
||||||
direction: '${orderDir|default:undefined}',
|
|
||||||
search_flink_job_id: '${flinkJobId|default:undefined}',
|
|
||||||
search_alias: '${alias|default:undefined}',
|
|
||||||
search_version: '${version|default:undefined}',
|
|
||||||
filter_schedules: '${updated|default:undefined}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
now: '${DATETOSTR(DATEMODIFY(NOW(), -1, \'days\'), \'YYYYMMDD\')}',
|
|
||||||
},
|
|
||||||
...crudCommonOptions(),
|
|
||||||
interval: 10000,
|
|
||||||
filter: {
|
|
||||||
mode: 'inline',
|
|
||||||
title: '表筛选',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'group',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
...flinkJobIdTextInput('c5cac9d3-844a-4d86-b2c5-0c10f2283667'),
|
|
||||||
size: 'md',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
...aliasTextInput('c5cac9d3-844a-4d86-b2c5-0c10f2283667'),
|
|
||||||
size: 'md',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input-date',
|
|
||||||
name: 'version',
|
|
||||||
label: '版本',
|
|
||||||
clearable: true,
|
|
||||||
placeholder: '通过版本搜索',
|
|
||||||
size: 'md',
|
|
||||||
format: 'YYYYMMDD',
|
|
||||||
inputFormat: 'YYYYMMDD',
|
|
||||||
value: '${now}',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
type: 'submit',
|
|
||||||
level: 'primary',
|
|
||||||
label: '查询',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'reset',
|
|
||||||
label: '重置',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
filterTogglable: true,
|
|
||||||
filterDefaultVisible: true,
|
|
||||||
perPage: 20,
|
|
||||||
headerToolbar: [
|
|
||||||
'reload',
|
|
||||||
'filter-toggler',
|
|
||||||
{
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '共 <span class=\'text-primary font-bold\'>${total|default:0}</span> 个表,其中 <span class=\'text-success font-bold\'>${scheduled|default:0}</span> 个表已跨天,<span class=\'text-danger font-bold\'>${unScheduled|default:0}</span> 个表未跨天',
|
|
||||||
},
|
|
||||||
paginationCommonOptions(),
|
|
||||||
],
|
|
||||||
footerToolbar: [
|
|
||||||
paginationCommonOptions(),
|
|
||||||
],
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
label: 'Flink job id',
|
|
||||||
width: 195,
|
|
||||||
fixed: 'left',
|
|
||||||
type: 'wrapper',
|
|
||||||
size: 'none',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
level: 'link',
|
|
||||||
label: '${flinkJobId}',
|
|
||||||
size: 'xs',
|
|
||||||
actionType: 'dialog',
|
|
||||||
tooltip: '查看详情',
|
|
||||||
dialog: flinkJobDialog(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
level: 'link',
|
|
||||||
label: '',
|
|
||||||
icon: 'fa fa-copy',
|
|
||||||
size: 'xs',
|
|
||||||
actionType: 'copy',
|
|
||||||
content: '${flinkJobId}',
|
|
||||||
tooltip: '复制 ID',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '别名',
|
|
||||||
type: 'wrapper',
|
|
||||||
fixed: 'left',
|
|
||||||
size: 'none',
|
|
||||||
className: 'nowrap',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
level: 'link',
|
|
||||||
label: '${tableMeta.alias}',
|
|
||||||
size: 'xs',
|
|
||||||
actionType: 'dialog',
|
|
||||||
tooltip: '查看详情',
|
|
||||||
dialog: tableMetaDialog(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'action',
|
|
||||||
level: 'link',
|
|
||||||
label: '',
|
|
||||||
icon: 'fa fa-copy',
|
|
||||||
size: 'xs',
|
|
||||||
actionType: 'copy',
|
|
||||||
content: '${tableMeta.alias}',
|
|
||||||
tooltip: '复制别名',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'priority',
|
|
||||||
label: '表优先级',
|
|
||||||
align: 'center',
|
|
||||||
width: 75,
|
|
||||||
sortable: true,
|
|
||||||
}, {
|
|
||||||
name: 'version',
|
|
||||||
label: '版本',
|
|
||||||
align: 'center',
|
|
||||||
width: 75,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'updated',
|
|
||||||
label: '状态',
|
|
||||||
align: 'center',
|
|
||||||
...mappingField('updated', versionUpdateStateMapping),
|
|
||||||
filterable: filterableField(versionUpdateStateMapping, true),
|
|
||||||
width: 70,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Version
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import {useLocation, useParams} from 'react-router'
|
|
||||||
import {
|
|
||||||
amisRender,
|
|
||||||
commonInfo,
|
|
||||||
crudCommonOptions,
|
|
||||||
paginationCommonOptions,
|
|
||||||
yarnCrudColumns,
|
|
||||||
yarnQueueCrud,
|
|
||||||
} from '../../util/amis.tsx'
|
|
||||||
|
|
||||||
const Yarn: React.FC = () => {
|
|
||||||
const {clusters, queue, search} = useParams()
|
|
||||||
const location = useLocation()
|
|
||||||
return (
|
|
||||||
<div key={location.key} className="hudi-yarn">
|
|
||||||
{amisRender(
|
|
||||||
{
|
|
||||||
type: 'wrapper',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
id: `${clusters}-yarn-service`,
|
|
||||||
name: `${clusters}-yarn-service`,
|
|
||||||
type: 'service',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '<span class="font-bold text-xl">集群资源</span>',
|
|
||||||
},
|
|
||||||
yarnQueueCrud(clusters, queue),
|
|
||||||
{
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '<span class="font-bold text-xl">集群任务</span>',
|
|
||||||
// className: 'mb-2 block',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'crud',
|
|
||||||
api: {
|
|
||||||
method: 'get',
|
|
||||||
url: `${commonInfo.baseUrl}/yarn/job_list`,
|
|
||||||
data: {
|
|
||||||
clusters: `${clusters}`,
|
|
||||||
page: '${page|default:undefined}',
|
|
||||||
count: '${perPage|default:undefined}',
|
|
||||||
order: '${orderBy|default:undefined}',
|
|
||||||
direction: '${orderDir|default:undefined}',
|
|
||||||
filter_state: '${state|default:undefined}',
|
|
||||||
filter_final_status: '${finalStatus|default:undefined}',
|
|
||||||
search_id: '${id|default:undefined}',
|
|
||||||
search_name: '${name|default:undefined}',
|
|
||||||
completion: 'true',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
defaultParams: {
|
|
||||||
name: search,
|
|
||||||
},
|
|
||||||
...crudCommonOptions(),
|
|
||||||
interval: 10000,
|
|
||||||
filter: {
|
|
||||||
mode: 'inline',
|
|
||||||
title: '任务筛选',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'group',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'input-text',
|
|
||||||
name: 'id',
|
|
||||||
label: 'ID',
|
|
||||||
clearable: true,
|
|
||||||
placeholder: '通过 ID 搜索',
|
|
||||||
size: 'md',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input-text',
|
|
||||||
name: 'name',
|
|
||||||
label: '名称',
|
|
||||||
clearable: true,
|
|
||||||
placeholder: '通过名称搜索',
|
|
||||||
size: 'md',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
type: 'submit',
|
|
||||||
level: 'primary',
|
|
||||||
label: '查询',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'reset',
|
|
||||||
label: '重置',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
filterTogglable: true,
|
|
||||||
filterDefaultVisible: false,
|
|
||||||
perPage: 20,
|
|
||||||
headerToolbar: [
|
|
||||||
'reload',
|
|
||||||
'filter-toggler',
|
|
||||||
{
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '共 <span class=\'text-primary font-bold\'>${total|default:0}</span> 个任务,其中 <span class=\'text-success font-bold\'>${running|default:0}</span> 个任务运行中,<span class=\'text-danger font-bold\'>${unRunning|default:0}</span> 个任务处于非运行状态',
|
|
||||||
},
|
|
||||||
paginationCommonOptions(),
|
|
||||||
],
|
|
||||||
footerToolbar: [
|
|
||||||
paginationCommonOptions(),
|
|
||||||
],
|
|
||||||
columns: yarnCrudColumns(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Yarn
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import {amisRender, commonInfo, yarnQueueCrud} from '../../util/amis.tsx'
|
|
||||||
|
|
||||||
const YarnCluster: React.FC = () => {
|
|
||||||
return (
|
|
||||||
<div className="hudi-yarn-cluster">
|
|
||||||
{amisRender(
|
|
||||||
{
|
|
||||||
type: 'wrapper',
|
|
||||||
body: [
|
|
||||||
...Object.keys(commonInfo.clusters.compaction).map(name => yarnQueueCrud(name)),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default YarnCluster
|
|
||||||
@@ -1,206 +0,0 @@
|
|||||||
import {
|
|
||||||
CheckSquareOutlined,
|
|
||||||
CloudOutlined,
|
|
||||||
ClusterOutlined,
|
|
||||||
CompressOutlined,
|
|
||||||
DatabaseOutlined,
|
|
||||||
InfoCircleOutlined,
|
|
||||||
OpenAIOutlined,
|
|
||||||
QuestionOutlined,
|
|
||||||
SunOutlined,
|
|
||||||
SyncOutlined,
|
|
||||||
TableOutlined,
|
|
||||||
ToolOutlined,
|
|
||||||
} from '@ant-design/icons'
|
|
||||||
import {Navigate, type RouteObject} from 'react-router'
|
|
||||||
import Conversation from './pages/ai/Conversation.tsx'
|
|
||||||
import Inspection from './pages/ai/Inspection.tsx'
|
|
||||||
import DataDetail from './pages/ai/knowledge/DataDetail.tsx'
|
|
||||||
import DataImport from './pages/ai/knowledge/DataImport.tsx'
|
|
||||||
import Knowledge from './pages/ai/knowledge/Knowledge.tsx'
|
|
||||||
import App from './pages/App.tsx'
|
|
||||||
import Cloud from './pages/overview/Cloud.tsx'
|
|
||||||
import Overview from './pages/overview/Overview.tsx'
|
|
||||||
import Queue from './pages/overview/Queue.tsx'
|
|
||||||
import Table from './pages/overview/Table.tsx'
|
|
||||||
import Task from './pages/overview/Task.tsx'
|
|
||||||
import Tool from './pages/overview/Tool.tsx'
|
|
||||||
import Version from './pages/overview/Version.tsx'
|
|
||||||
import Yarn from './pages/overview/Yarn.tsx'
|
|
||||||
import YarnCluster from './pages/overview/YarnCluster.tsx'
|
|
||||||
import {commonInfo} from './util/amis.tsx'
|
|
||||||
|
|
||||||
export const routes: RouteObject[] = [
|
|
||||||
{
|
|
||||||
path: '/',
|
|
||||||
Component: App,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
index: true,
|
|
||||||
element: <Navigate to="/overview" replace/>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'overview',
|
|
||||||
Component: Overview,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'table',
|
|
||||||
Component: Table,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'queue',
|
|
||||||
Component: Queue,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'version',
|
|
||||||
Component: Version,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'yarn/:clusters/:queue/:search?',
|
|
||||||
Component: Yarn,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'cloud',
|
|
||||||
Component: Cloud,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'yarn_cluster',
|
|
||||||
Component: YarnCluster,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'tool',
|
|
||||||
Component: Tool,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'task',
|
|
||||||
Component: Task,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'ai',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
index: true,
|
|
||||||
element: <Navigate to="/ai/conversation" replace/>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'inspection',
|
|
||||||
Component: Inspection,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'conversation',
|
|
||||||
Component: Conversation,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'knowledge',
|
|
||||||
Component: Knowledge,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'knowledge/import/:name',
|
|
||||||
Component: DataImport,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'knowledge/detail/:name',
|
|
||||||
Component: DataDetail,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
export const menus = {
|
|
||||||
routes: [
|
|
||||||
{
|
|
||||||
path: '/',
|
|
||||||
name: '概览',
|
|
||||||
icon: <InfoCircleOutlined/>,
|
|
||||||
routes: [
|
|
||||||
{
|
|
||||||
path: '/overview',
|
|
||||||
name: '概览',
|
|
||||||
icon: <InfoCircleOutlined/>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/table',
|
|
||||||
name: '表任务',
|
|
||||||
icon: <TableOutlined/>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/queue',
|
|
||||||
name: '压缩队列',
|
|
||||||
icon: <CompressOutlined/>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/version',
|
|
||||||
name: '跨天',
|
|
||||||
icon: <SunOutlined/>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: `/yarn/${commonInfo.clusters.sync_names()}/root/Sync`,
|
|
||||||
name: '同步集群',
|
|
||||||
icon: <SyncOutlined/>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: `/yarn/${commonInfo.clusters.compaction_names()}/default/Compaction`,
|
|
||||||
name: '压缩集群',
|
|
||||||
icon: <SyncOutlined/>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/cloud',
|
|
||||||
name: '服务',
|
|
||||||
icon: <CloudOutlined/>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'a86f7c51-ae60-4ca4-8c4d-40b86b445a04',
|
|
||||||
name: '集群',
|
|
||||||
icon: <ClusterOutlined/>,
|
|
||||||
routes: [
|
|
||||||
{
|
|
||||||
path: '/yarn_cluster',
|
|
||||||
name: '概览',
|
|
||||||
icon: <InfoCircleOutlined/>,
|
|
||||||
},
|
|
||||||
...Object.keys(commonInfo.clusters.compaction).map(name => ({
|
|
||||||
// @ts-ignore
|
|
||||||
path: `/yarn/${name}/${commonInfo.clusters.compaction[name]}`,
|
|
||||||
name: `${name} 集群`,
|
|
||||||
icon: <ClusterOutlined/>,
|
|
||||||
})),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/tool',
|
|
||||||
name: '工具',
|
|
||||||
icon: <ToolOutlined/>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/task',
|
|
||||||
name: '任务',
|
|
||||||
icon: <CheckSquareOutlined/>,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/ai',
|
|
||||||
name: 'AI',
|
|
||||||
icon: <OpenAIOutlined/>,
|
|
||||||
routes: [
|
|
||||||
{
|
|
||||||
path: '/ai/conversation',
|
|
||||||
name: '智慧问答',
|
|
||||||
icon: <QuestionOutlined/>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/ai/inspection',
|
|
||||||
name: '智能巡检',
|
|
||||||
icon: <CheckSquareOutlined/>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/ai/knowledge',
|
|
||||||
name: '知识库',
|
|
||||||
icon: <DatabaseOutlined/>,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
1
service-web/client/src/vite-env.d.ts
vendored
1
service-web/client/src/vite-env.d.ts
vendored
@@ -1 +0,0 @@
|
|||||||
/// <reference types="vite/client" />
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
||||||
"target": "ESNext",
|
|
||||||
"useDefineForClassFields": true,
|
|
||||||
"lib": [
|
|
||||||
"ESNext",
|
|
||||||
"DOM",
|
|
||||||
"DOM.Iterable"
|
|
||||||
],
|
|
||||||
"module": "ESNext",
|
|
||||||
"skipLibCheck": true,
|
|
||||||
/* Bundler mode */
|
|
||||||
"moduleResolution": "bundler",
|
|
||||||
"allowImportingTsExtensions": true,
|
|
||||||
"verbatimModuleSyntax": true,
|
|
||||||
"moduleDetection": "force",
|
|
||||||
"noEmit": true,
|
|
||||||
"jsx": "react-jsx",
|
|
||||||
/* Linting */
|
|
||||||
"strict": true,
|
|
||||||
"noUnusedLocals": true,
|
|
||||||
"noUnusedParameters": true,
|
|
||||||
"erasableSyntaxOnly": true,
|
|
||||||
"noFallthroughCasesInSwitch": true,
|
|
||||||
"noUncheckedSideEffectImports": true
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"src"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import react from '@vitejs/plugin-react-swc'
|
|
||||||
import {defineConfig, UserConfig} from 'vite'
|
|
||||||
|
|
||||||
// https://vite.dev/config/
|
|
||||||
export default defineConfig(({mode}) => {
|
|
||||||
let config: UserConfig = {
|
|
||||||
plugins: [react()],
|
|
||||||
}
|
|
||||||
if (mode === 'production') {
|
|
||||||
config.base = '/hudi_services/service_web'
|
|
||||||
}
|
|
||||||
return config
|
|
||||||
})
|
|
||||||
@@ -28,29 +28,6 @@
|
|||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-resources-plugin</artifactId>
|
|
||||||
<version>3.3.1</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>copy-web-dist</id>
|
|
||||||
<phase>compile</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>copy-resources</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<outputDirectory>${project.build.outputDirectory}/static</outputDirectory>
|
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<directory>${project.basedir}/client/dist</directory>
|
|
||||||
<filtering>false</filtering>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module version="4">
|
|
||||||
<component name="AdditionalModuleElements">
|
|
||||||
<content url="file://$MODULE_DIR$" dumb="true">
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/client/dist" />
|
|
||||||
</content>
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
@@ -8,26 +8,27 @@ import com.lanyuanxiaoyao.service.configuration.ExecutorProvider;
|
|||||||
import com.lanyuanxiaoyao.service.configuration.entity.info.JobIdAndAlias;
|
import com.lanyuanxiaoyao.service.configuration.entity.info.JobIdAndAlias;
|
||||||
import com.lanyuanxiaoyao.service.configuration.entity.monitor.MetricsProgress;
|
import com.lanyuanxiaoyao.service.configuration.entity.monitor.MetricsProgress;
|
||||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnApplication;
|
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnApplication;
|
||||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnQueue;
|
|
||||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnRootQueue;
|
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnRootQueue;
|
||||||
import com.lanyuanxiaoyao.service.configuration.entity.zookeeper.ZookeeperNode;
|
import com.lanyuanxiaoyao.service.configuration.entity.zookeeper.ZookeeperNode;
|
||||||
import com.lanyuanxiaoyao.service.forest.service.*;
|
import com.lanyuanxiaoyao.service.forest.service.InfoService;
|
||||||
|
import com.lanyuanxiaoyao.service.forest.service.MonitorService;
|
||||||
|
import com.lanyuanxiaoyao.service.forest.service.QueueService;
|
||||||
|
import com.lanyuanxiaoyao.service.forest.service.ScheduleService;
|
||||||
|
import com.lanyuanxiaoyao.service.forest.service.YarnService;
|
||||||
|
import com.lanyuanxiaoyao.service.forest.service.ZookeeperService;
|
||||||
import com.lanyuanxiaoyao.service.web.controller.base.AmisCrudResponse;
|
import com.lanyuanxiaoyao.service.web.controller.base.AmisCrudResponse;
|
||||||
import com.lanyuanxiaoyao.service.web.controller.base.AmisMapResponse;
|
import com.lanyuanxiaoyao.service.web.controller.base.AmisMapResponse;
|
||||||
import com.lanyuanxiaoyao.service.web.controller.base.AmisResponse;
|
import com.lanyuanxiaoyao.service.web.controller.base.AmisResponse;
|
||||||
import com.lanyuanxiaoyao.service.web.controller.base.BaseController;
|
import com.lanyuanxiaoyao.service.web.controller.base.BaseController;
|
||||||
import com.lanyuanxiaoyao.service.web.entity.JobIdAndAliasVO;
|
import com.lanyuanxiaoyao.service.web.entity.JobIdAndAliasVO;
|
||||||
import com.lanyuanxiaoyao.service.web.entity.ScheduleTimeVO;
|
import com.lanyuanxiaoyao.service.web.entity.ScheduleTimeVO;
|
||||||
import com.lanyuanxiaoyao.service.web.entity.overview.TableCountVO;
|
|
||||||
import com.lanyuanxiaoyao.service.web.entity.overview.TaskCountVO;
|
|
||||||
import com.lanyuanxiaoyao.service.web.entity.overview.VersionCountVO;
|
|
||||||
import com.lanyuanxiaoyao.service.web.entity.overview.YarnCountVO;
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import org.eclipse.collections.api.factory.Lists;
|
import org.eclipse.collections.api.factory.Lists;
|
||||||
|
import org.eclipse.collections.api.factory.Maps;
|
||||||
import org.eclipse.collections.api.list.ImmutableList;
|
import org.eclipse.collections.api.list.ImmutableList;
|
||||||
import org.eclipse.collections.api.list.MutableList;
|
import org.eclipse.collections.api.list.MutableList;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -66,7 +67,7 @@ public class OverviewController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("")
|
@GetMapping("")
|
||||||
public AmisCrudResponse overview() throws ExecutionException, InterruptedException {
|
public AmisMapResponse overview() throws ExecutionException, InterruptedException {
|
||||||
CompletableFuture<Long> tableCountFuture = CompletableFuture.supplyAsync(infoService::tableCount, ExecutorProvider.EXECUTORS);
|
CompletableFuture<Long> tableCountFuture = CompletableFuture.supplyAsync(infoService::tableCount, ExecutorProvider.EXECUTORS);
|
||||||
CompletableFuture<Long> tableFocusCountFuture = CompletableFuture.supplyAsync(infoService::tableFocusCount, ExecutorProvider.EXECUTORS);
|
CompletableFuture<Long> tableFocusCountFuture = CompletableFuture.supplyAsync(infoService::tableFocusCount, ExecutorProvider.EXECUTORS);
|
||||||
CompletableFuture<Long> hudiCountFuture = CompletableFuture.supplyAsync(infoService::hudiCount, ExecutorProvider.EXECUTORS);
|
CompletableFuture<Long> hudiCountFuture = CompletableFuture.supplyAsync(infoService::hudiCount, ExecutorProvider.EXECUTORS);
|
||||||
@@ -81,12 +82,13 @@ public class OverviewController extends BaseController {
|
|||||||
hiveCountFuture,
|
hiveCountFuture,
|
||||||
hiveFocusCountFuture
|
hiveFocusCountFuture
|
||||||
).get();
|
).get();
|
||||||
ImmutableList<TableCountVO> list = Lists.immutable.of(
|
return AmisResponse.responseMapData()
|
||||||
new TableCountVO("逻辑表", tableCountFuture.get(), tableFocusCountFuture.get()),
|
.setData("table_count", tableCountFuture.get())
|
||||||
new TableCountVO("湖底表", hudiCountFuture.get(), hudiFocusCountFuture.get()),
|
.setData("table_focus_count", tableFocusCountFuture.get())
|
||||||
new TableCountVO("嗨福表", hiveCountFuture.get(), hiveFocusCountFuture.get())
|
.setData("hudi_count", hudiCountFuture.get())
|
||||||
);
|
.setData("hudi_focus_count", hudiFocusCountFuture.get())
|
||||||
return AmisResponse.responseCrudData(list);
|
.setData("hive_count", hiveCountFuture.get())
|
||||||
|
.setData("hive_focus_count", hiveFocusCountFuture.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("yarn-job")
|
@GetMapping("yarn-job")
|
||||||
@@ -97,6 +99,7 @@ public class OverviewController extends BaseController {
|
|||||||
.setData("name", cluster)
|
.setData("name", cluster)
|
||||||
.setData("total", applications.size())
|
.setData("total", applications.size())
|
||||||
.setData("running", applications.count(app -> StrUtil.equals(app.getState(), "RUNNING")))
|
.setData("running", applications.count(app -> StrUtil.equals(app.getState(), "RUNNING")))
|
||||||
|
.setData("running", applications.count(app -> StrUtil.equals(app.getState(), "RUNNING")))
|
||||||
.setData("scheduling", applications.count(app -> StrUtil.equals(app.getState(), "ACCEPTED")))
|
.setData("scheduling", applications.count(app -> StrUtil.equals(app.getState(), "ACCEPTED")))
|
||||||
.setData("failure", applications.count(app -> StrUtil.equals(app.getState(), "FAILED")));
|
.setData("failure", applications.count(app -> StrUtil.equals(app.getState(), "FAILED")));
|
||||||
}
|
}
|
||||||
@@ -128,13 +131,10 @@ public class OverviewController extends BaseController {
|
|||||||
CompletableFuture<Long> unScheduledNormalTableCount = CompletableFuture.supplyAsync(() -> infoService.unScheduledNormalTableCount(version), ExecutorProvider.EXECUTORS);
|
CompletableFuture<Long> unScheduledNormalTableCount = CompletableFuture.supplyAsync(() -> infoService.unScheduledNormalTableCount(version), ExecutorProvider.EXECUTORS);
|
||||||
CompletableFuture<Long> unScheduledFocusTableCount = CompletableFuture.supplyAsync(() -> infoService.unScheduledFocusTableCount(version), ExecutorProvider.EXECUTORS);
|
CompletableFuture<Long> unScheduledFocusTableCount = CompletableFuture.supplyAsync(() -> infoService.unScheduledFocusTableCount(version), ExecutorProvider.EXECUTORS);
|
||||||
CompletableFuture.allOf(unReceiveNormalTableCount, unReceiveFocusCount, unScheduledNormalTableCount, unScheduledFocusTableCount).get();
|
CompletableFuture.allOf(unReceiveNormalTableCount, unReceiveFocusCount, unScheduledNormalTableCount, unScheduledFocusTableCount).get();
|
||||||
ImmutableList<VersionCountVO> list = Lists.immutable.of(
|
|
||||||
new VersionCountVO("focus", "重点表", unReceiveFocusCount.get(), unScheduledFocusTableCount.get()),
|
|
||||||
new VersionCountVO("normal", "普通表", unReceiveNormalTableCount.get(), unScheduledNormalTableCount.get())
|
|
||||||
);
|
|
||||||
return AmisResponse.responseMapData()
|
return AmisResponse.responseMapData()
|
||||||
.setData("version", version)
|
.setData("version", version)
|
||||||
.setData("items", list);
|
.setData("unReceive", Maps.immutable.of("normal", unReceiveNormalTableCount.get(), "focus", unReceiveFocusCount.get()))
|
||||||
|
.setData("unSchedule", Maps.immutable.of("normal", unScheduledNormalTableCount.get(), "focus", unScheduledFocusTableCount.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("version_detail")
|
@GetMapping("version_detail")
|
||||||
@@ -175,7 +175,7 @@ public class OverviewController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("sync_running_status")
|
@GetMapping("sync_running_status")
|
||||||
public AmisCrudResponse syncRunningStatus() {
|
public AmisMapResponse syncRunningStatus() {
|
||||||
ImmutableList<String> locks = zookeeperService.getChildren(NameHelper.ZK_SYNC_RUNNING_LOCK_PATH).collect(ZookeeperNode::getPath);
|
ImmutableList<String> locks = zookeeperService.getChildren(NameHelper.ZK_SYNC_RUNNING_LOCK_PATH).collect(ZookeeperNode::getPath);
|
||||||
MutableList<JobIdAndAlias> runningJob = Lists.mutable.<JobIdAndAlias>empty().asSynchronized();
|
MutableList<JobIdAndAlias> runningJob = Lists.mutable.<JobIdAndAlias>empty().asSynchronized();
|
||||||
MutableList<JobIdAndAlias> unRunningJob = Lists.mutable.<JobIdAndAlias>empty().asSynchronized();
|
MutableList<JobIdAndAlias> unRunningJob = Lists.mutable.<JobIdAndAlias>empty().asSynchronized();
|
||||||
@@ -203,11 +203,17 @@ public class OverviewController extends BaseController {
|
|||||||
unRunningTable.add(ia);
|
unRunningTable.add(ia);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ImmutableList<TaskCountVO> list = Lists.immutable.of(
|
return AmisResponse.responseMapData()
|
||||||
new TaskCountVO("同步任务数", ids.size(), runningJob.size(), unRunningJob.size(), unRunningJob.toImmutable()),
|
.setData("totalJob", ids.size())
|
||||||
new TaskCountVO("同步表数", idAliases.size(), runningTable.size(), unRunningTable.size(), unRunningTable.toImmutable())
|
.setData("runningJob", runningJob.size())
|
||||||
);
|
.setData("runningJobList", runningJob)
|
||||||
return AmisResponse.responseCrudData(list);
|
.setData("unRunningJob", unRunningJob.size())
|
||||||
|
.setData("unRunningJobList", unRunningJob)
|
||||||
|
.setData("totalTable", idAliases.size())
|
||||||
|
.setData("runningTable", runningTable.size())
|
||||||
|
.setData("runningTableList", runningTable)
|
||||||
|
.setData("unRunningTable", unRunningTable.size())
|
||||||
|
.setData("unRunningTableList", unRunningTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("monitor_progress")
|
@GetMapping("monitor_progress")
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.service.web.entity.overview;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @version 20250509
|
|
||||||
*/
|
|
||||||
public class TableCountVO {
|
|
||||||
private final String type;
|
|
||||||
private final Long total;
|
|
||||||
private final Long focus;
|
|
||||||
|
|
||||||
public TableCountVO(String type, Long total, Long focus) {
|
|
||||||
this.type = type;
|
|
||||||
this.total = total;
|
|
||||||
this.focus = focus;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getTotal() {
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getFocus() {
|
|
||||||
return focus;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "TableCountVO{" +
|
|
||||||
"type='" + type + '\'' +
|
|
||||||
", total=" + total +
|
|
||||||
", focus=" + focus +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.service.web.entity.overview;
|
|
||||||
|
|
||||||
import com.lanyuanxiaoyao.service.configuration.entity.info.JobIdAndAlias;
|
|
||||||
import org.eclipse.collections.api.list.ImmutableList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @version 20250509
|
|
||||||
*/
|
|
||||||
public class TaskCountVO {
|
|
||||||
private final String type;
|
|
||||||
private final Integer total;
|
|
||||||
private final Integer running;
|
|
||||||
private final Integer stopped;
|
|
||||||
private final ImmutableList<JobIdAndAlias> list;
|
|
||||||
|
|
||||||
public TaskCountVO(String type, Integer total, Integer running, Integer stopped, ImmutableList<JobIdAndAlias> list) {
|
|
||||||
this.type = type;
|
|
||||||
this.total = total;
|
|
||||||
this.running = running;
|
|
||||||
this.stopped = stopped;
|
|
||||||
this.list = list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getTotal() {
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getRunning() {
|
|
||||||
return running;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getStopped() {
|
|
||||||
return stopped;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ImmutableList<JobIdAndAlias> getList() {
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "TaskCountVO{" +
|
|
||||||
"type='" + type + '\'' +
|
|
||||||
", total=" + total +
|
|
||||||
", running=" + running +
|
|
||||||
", stopped=" + stopped +
|
|
||||||
", list=" + list +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.service.web.entity.overview;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @version 20250509
|
|
||||||
*/
|
|
||||||
public class VersionCountVO {
|
|
||||||
private final String key;
|
|
||||||
private final String type;
|
|
||||||
private final Long unReceive;
|
|
||||||
private final Long unScheduled;
|
|
||||||
|
|
||||||
public VersionCountVO(String key, String type, Long unReceive, Long unScheduled) {
|
|
||||||
this.key = key;
|
|
||||||
this.type = type;
|
|
||||||
this.unReceive = unReceive;
|
|
||||||
this.unScheduled = unScheduled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getKey() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getUnReceive() {
|
|
||||||
return unReceive;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getUnScheduled() {
|
|
||||||
return unScheduled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "VersionCountVO{" +
|
|
||||||
"key='" + key + '\'' +
|
|
||||||
", type='" + type + '\'' +
|
|
||||||
", unReceive=" + unReceive +
|
|
||||||
", unScheduled=" + unScheduled +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.service.web.entity.overview;
|
|
||||||
|
|
||||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnQueue;
|
|
||||||
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnRootQueue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @version 20250509
|
|
||||||
*/
|
|
||||||
public class YarnCountVO {
|
|
||||||
private final String cluster;
|
|
||||||
private final Integer total;
|
|
||||||
private final Integer running;
|
|
||||||
private final Integer scheduling;
|
|
||||||
private final Integer failure;
|
|
||||||
private final YarnRootQueue root;
|
|
||||||
private final YarnQueue target;
|
|
||||||
private final Integer queue;
|
|
||||||
|
|
||||||
public YarnCountVO(String cluster, Integer total, Integer running, Integer scheduling, Integer failure, YarnRootQueue root, YarnQueue target, Integer queue) {
|
|
||||||
this.cluster = cluster;
|
|
||||||
this.total = total;
|
|
||||||
this.running = running;
|
|
||||||
this.scheduling = scheduling;
|
|
||||||
this.failure = failure;
|
|
||||||
this.root = root;
|
|
||||||
this.target = target;
|
|
||||||
this.queue = queue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCluster() {
|
|
||||||
return cluster;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getTotal() {
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getRunning() {
|
|
||||||
return running;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getScheduling() {
|
|
||||||
return scheduling;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getFailure() {
|
|
||||||
return failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
public YarnRootQueue getRoot() {
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
public YarnQueue getTarget() {
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getQueue() {
|
|
||||||
return queue;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "YarnCountVO{" +
|
|
||||||
"cluster='" + cluster + '\'' +
|
|
||||||
", total=" + total +
|
|
||||||
", running=" + running +
|
|
||||||
", scheduling=" + scheduling +
|
|
||||||
", failure=" + failure +
|
|
||||||
", root=" + root +
|
|
||||||
", target=" + target +
|
|
||||||
", queue=" + queue +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,6 +7,23 @@
|
|||||||
<springProperty scope="context" name="LOGGING_PARENT" source="logging.parent"/>
|
<springProperty scope="context" name="LOGGING_PARENT" source="logging.parent"/>
|
||||||
<springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
|
<springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
|
||||||
|
|
||||||
|
<appender name="Loki" class="com.github.loki4j.logback.Loki4jAppender">
|
||||||
|
<metricsEnabled>true</metricsEnabled>
|
||||||
|
<http class="com.github.loki4j.logback.ApacheHttpSender">
|
||||||
|
<url>${LOKI_PUSH_URL:-http://localhost/loki/api/v1/push}</url>
|
||||||
|
</http>
|
||||||
|
<format>
|
||||||
|
<label>
|
||||||
|
<pattern>app=${APP_NAME:-none},host=${HOSTNAME:-none},level=%level</pattern>
|
||||||
|
<readMarkers>true</readMarkers>
|
||||||
|
</label>
|
||||||
|
<message>
|
||||||
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %p [${HOSTNAME}] [%t] %logger #@# %m%n%wEx</pattern>
|
||||||
|
</message>
|
||||||
|
<sortByTime>true</sortByTime>
|
||||||
|
</format>
|
||||||
|
</appender>
|
||||||
|
|
||||||
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
|
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
<encoder>
|
<encoder>
|
||||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %clr(%5p) %clr([${HOSTNAME}]){yellow} %clr([%t]){magenta} %clr(%logger{40}){cyan} #@# %m%n%wEx</pattern>
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %clr(%5p) %clr([${HOSTNAME}]){yellow} %clr([%t]){magenta} %clr(%logger{40}){cyan} #@# %m%n%wEx</pattern>
|
||||||
@@ -28,6 +45,7 @@
|
|||||||
<logger name="com.netflix.discovery.shared.resolver.aws.ConfigClusterResolver" level="WARN"/>
|
<logger name="com.netflix.discovery.shared.resolver.aws.ConfigClusterResolver" level="WARN"/>
|
||||||
|
|
||||||
<root level="INFO">
|
<root level="INFO">
|
||||||
|
<appender-ref ref="Loki"/>
|
||||||
<appender-ref ref="Console"/>
|
<appender-ref ref="Console"/>
|
||||||
<appender-ref ref="RollingFile"/>
|
<appender-ref ref="RollingFile"/>
|
||||||
</root>
|
</root>
|
||||||
|
|||||||
BIN
service-web/src/main/resources/static/assets/icon.png
Normal file
BIN
service-web/src/main/resources/static/assets/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
150
service-web/src/main/resources/static/common/info.js
Normal file
150
service-web/src/main/resources/static/common/info.js
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
const commonInfo = {
|
||||||
|
baseUrl: 'http://132.126.207.130:35690/hudi_services/service_web',
|
||||||
|
// baseUrl: '/hudi_services/service_web',
|
||||||
|
clusters: {
|
||||||
|
// hudi同步运行集群和yarn队列名称
|
||||||
|
sync: {
|
||||||
|
'b12': 'default',
|
||||||
|
},
|
||||||
|
sync_names() {
|
||||||
|
return Object.keys(this.sync).join(',')
|
||||||
|
},
|
||||||
|
// hudi压缩运行集群和yarn队列名称
|
||||||
|
compaction: {
|
||||||
|
'b12': 'default',
|
||||||
|
'b1': 'datalake',
|
||||||
|
'a4': 'ten_iap.datalake',
|
||||||
|
},
|
||||||
|
compaction_names() {
|
||||||
|
return Object.keys(this.compaction).join(',')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
loki: {
|
||||||
|
// grafana链接,用于直接打开grafana日志查看
|
||||||
|
grafanaUrl: 'http://132.126.207.125:35700',
|
||||||
|
// grafana对应hudi使用的loki配置的datasource id
|
||||||
|
hudi: {
|
||||||
|
datasource: 'f648174e-7593-45cf-8fe8-8f8d5cf0fdde',
|
||||||
|
},
|
||||||
|
// grafana对应服务使用的loki配置的datasource id
|
||||||
|
service: {
|
||||||
|
datasource: 'b6fee51c-facd-4261-a0eb-8c69a975fba3',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries
|
||||||
|
* {datasource, queryMap}
|
||||||
|
*/
|
||||||
|
function generateLokiPanel(queries) {
|
||||||
|
return {
|
||||||
|
LWF: {
|
||||||
|
queries: [
|
||||||
|
...queries.map(item => {
|
||||||
|
let name = item['name']
|
||||||
|
let datasource = item['datasource']
|
||||||
|
let queryMap = item['queryMap']
|
||||||
|
let query = Object.keys(queryMap)
|
||||||
|
.sort()
|
||||||
|
.map(key => `${key}="${queryMap[key]}"`)
|
||||||
|
let match = "\\d{4}-(?P<time>\\d{2}-\\d{2}\\s*\\d{2}:\\d{2}:\\d{2}).+#@#\\s*(?P<content>[\\w\\W]+)"
|
||||||
|
let format = "{{.time}} [{{.host}}] [{{.level}}] [{{.app}}] {{.content}}"
|
||||||
|
// language=TEXT
|
||||||
|
let expression = `{${query.join(",")}}\n| regexp "${match.replaceAll('\\', '\\\\')}"\n| line_format \`${format}\``
|
||||||
|
return {
|
||||||
|
refId: name,
|
||||||
|
expr: expression,
|
||||||
|
queryType: "range",
|
||||||
|
datasource: {
|
||||||
|
type: "loki",
|
||||||
|
uid: datasource
|
||||||
|
},
|
||||||
|
editorMode: "code"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
range: {
|
||||||
|
from: "now-1h",
|
||||||
|
to: "now"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateQuery(name, datasource, queryMap) {
|
||||||
|
return {
|
||||||
|
name: name,
|
||||||
|
datasource: datasource,
|
||||||
|
queryMap: queryMap,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateLokiUrl(baseUrl, queries) {
|
||||||
|
return `${baseUrl}/explore?panes=${encodeURIComponent(JSON.stringify(generateLokiPanel(queries)))}&schemaVersion=1&orgId=1`
|
||||||
|
}
|
||||||
|
|
||||||
|
function targetHudiSyncLokiUrlByAlias(flinkJobId) {
|
||||||
|
return generateLokiUrl(
|
||||||
|
commonInfo.loki.grafanaUrl,
|
||||||
|
[
|
||||||
|
generateQuery(
|
||||||
|
"Hudi 运行日志",
|
||||||
|
commonInfo.loki.hudi.datasource,
|
||||||
|
{"flink_job_id": flinkJobId}
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function targetHudiCompactionLokiUrlByAlias(alias) {
|
||||||
|
return generateLokiUrl(
|
||||||
|
commonInfo.loki.grafanaUrl,
|
||||||
|
[
|
||||||
|
generateQuery(
|
||||||
|
"Hudi 运行日志",
|
||||||
|
commonInfo.loki.hudi.datasource,
|
||||||
|
{"alias": alias}
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function targetYarnApplicationLokiUrlByAppId(applicationId) {
|
||||||
|
return generateLokiUrl(
|
||||||
|
commonInfo.loki.grafanaUrl,
|
||||||
|
[
|
||||||
|
generateQuery(
|
||||||
|
"Hudi 运行日志",
|
||||||
|
commonInfo.loki.hudi.datasource,
|
||||||
|
{"app_id": applicationId}
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function serviceLogByAppName(name) {
|
||||||
|
return generateLokiUrl(
|
||||||
|
commonInfo.loki.grafanaUrl,
|
||||||
|
[
|
||||||
|
generateQuery(
|
||||||
|
"Service 运行日志",
|
||||||
|
commonInfo.loki.service.datasource,
|
||||||
|
{"app": name}
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function serviceLogByAppNameAndHost(name, host) {
|
||||||
|
return generateLokiUrl(
|
||||||
|
commonInfo.loki.grafanaUrl,
|
||||||
|
[
|
||||||
|
generateQuery(
|
||||||
|
"Service 运行日志",
|
||||||
|
commonInfo.loki.service.datasource,
|
||||||
|
{"app": name, "host": host}
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
function time(field) {
|
||||||
|
return {
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: `\${IF(${field}, DATETOSTR(${field}, 'YYYY-MM-DD HH:mm:ss'), undefined)}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cloudCrud(title, path) {
|
||||||
|
return {
|
||||||
|
type: 'crud',
|
||||||
|
title: title,
|
||||||
|
api: `\${base}${path}`,
|
||||||
|
...crudCommonOptions(),
|
||||||
|
interval: 2000,
|
||||||
|
headerToolbar: ['reload'],
|
||||||
|
loadDataOnce: true,
|
||||||
|
perPage: 100,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
label: '名称',
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: `\${name} \${IF(size === undefined, '', '<span class="font-bold label label-primary">' + size + '</span>')}`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'status',
|
||||||
|
label: '状态',
|
||||||
|
align: 'center',
|
||||||
|
width: 60,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'serviceUpTime',
|
||||||
|
label: '启动时间',
|
||||||
|
...time('serviceUpTime'),
|
||||||
|
align: 'center',
|
||||||
|
width: 160,
|
||||||
|
},
|
||||||
|
{name: 'url', label: '地址'},
|
||||||
|
{
|
||||||
|
type: 'operation',
|
||||||
|
label: '操作',
|
||||||
|
width: 100,
|
||||||
|
fixed: 'right',
|
||||||
|
className: 'nowrap',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
label: "日志",
|
||||||
|
type: "action",
|
||||||
|
level: "link",
|
||||||
|
tooltip: '打开Grafana日志',
|
||||||
|
onEvent: {
|
||||||
|
click: {
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
actionType: 'custom',
|
||||||
|
script: (context, doAction, event) => {
|
||||||
|
let data = context.props.data
|
||||||
|
let url = ''
|
||||||
|
if (data['metadata']) {
|
||||||
|
url = serviceLogByAppNameAndHost(data.serviceId, data.metadata.hostname)
|
||||||
|
} else if (data['name']) {
|
||||||
|
url = serviceLogByAppName(data.name)
|
||||||
|
}
|
||||||
|
window.open(url, '_blank')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cloudTab() {
|
||||||
|
return {
|
||||||
|
title: 'Cloud',
|
||||||
|
icon: 'fa fa-cloud',
|
||||||
|
tab: [
|
||||||
|
/*{
|
||||||
|
type: 'service',
|
||||||
|
silentPolling: true,
|
||||||
|
schemaApi: 'get:${base}/cloud/deploy_plan',
|
||||||
|
},*/
|
||||||
|
cloudCrud('服务列表', '/cloud/list'),
|
||||||
|
cloudCrud('服务列表 (IP)', '/cloud/list_ip'),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
2217
service-web/src/main/resources/static/components/common.js
Normal file
2217
service-web/src/main/resources/static/components/common.js
Normal file
File diff suppressed because it is too large
Load Diff
445
service-web/src/main/resources/static/components/overview-tab.js
Normal file
445
service-web/src/main/resources/static/components/overview-tab.js
Normal file
@@ -0,0 +1,445 @@
|
|||||||
|
function color(number) {
|
||||||
|
let color = 'text-success'
|
||||||
|
if (number > 30) {
|
||||||
|
color = 'text-primary'
|
||||||
|
}
|
||||||
|
if (number > 90) {
|
||||||
|
color = 'text-danger'
|
||||||
|
}
|
||||||
|
return color
|
||||||
|
}
|
||||||
|
|
||||||
|
function versionDetailDialog(variable, target) {
|
||||||
|
return {
|
||||||
|
disabledOn: `${variable} === 0`,
|
||||||
|
type: 'action',
|
||||||
|
label: '详情',
|
||||||
|
level: 'link',
|
||||||
|
size: 'sm',
|
||||||
|
actionType: 'dialog',
|
||||||
|
dialog: {
|
||||||
|
title: '详情',
|
||||||
|
actions: [],
|
||||||
|
size: 'md',
|
||||||
|
closeOnEsc: false,
|
||||||
|
closeOnOutside: false,
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'service',
|
||||||
|
api: {
|
||||||
|
method: 'get',
|
||||||
|
url: '${base}/overview/version_detail',
|
||||||
|
data: {
|
||||||
|
target: `${target}`,
|
||||||
|
version: '${version}',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: "table",
|
||||||
|
source: "${items}",
|
||||||
|
affixHeader: false,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
label: 'Flink job id',
|
||||||
|
fixed: 'left',
|
||||||
|
type: 'wrapper',
|
||||||
|
size: 'none',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '${id}',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'action',
|
||||||
|
level: 'link',
|
||||||
|
label: '',
|
||||||
|
icon: 'fa fa-copy',
|
||||||
|
size: 'xs',
|
||||||
|
actionType: 'copy',
|
||||||
|
content: '${id}',
|
||||||
|
tooltip: '复制 ID',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '别名',
|
||||||
|
type: 'wrapper',
|
||||||
|
fixed: 'left',
|
||||||
|
size: 'none',
|
||||||
|
className: 'nowrap',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '${alias}',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'action',
|
||||||
|
level: 'link',
|
||||||
|
label: '',
|
||||||
|
icon: 'fa fa-copy',
|
||||||
|
size: 'xs',
|
||||||
|
actionType: 'copy',
|
||||||
|
content: '${alias}',
|
||||||
|
tooltip: '复制别名',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function tableDetailDialog(variable, targetList) {
|
||||||
|
return {
|
||||||
|
disabledOn: `${variable} === 0`,
|
||||||
|
type: 'action',
|
||||||
|
label: '详情',
|
||||||
|
level: 'link',
|
||||||
|
size: 'sm',
|
||||||
|
actionType: 'dialog',
|
||||||
|
dialog: {
|
||||||
|
title: '详情',
|
||||||
|
size: 'md',
|
||||||
|
...readOnlyDialogOptions(),
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: "table",
|
||||||
|
source: `\${${targetList}}`,
|
||||||
|
affixHeader: false,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
label: 'Flink job id',
|
||||||
|
fixed: 'left',
|
||||||
|
type: 'wrapper',
|
||||||
|
size: 'none',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '${id}',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'action',
|
||||||
|
level: 'link',
|
||||||
|
label: '',
|
||||||
|
icon: 'fa fa-copy',
|
||||||
|
size: 'xs',
|
||||||
|
actionType: 'copy',
|
||||||
|
content: '${id}',
|
||||||
|
tooltip: '复制 ID',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '别名',
|
||||||
|
type: 'wrapper',
|
||||||
|
fixed: 'left',
|
||||||
|
size: 'none',
|
||||||
|
className: 'nowrap',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '${alias}',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'action',
|
||||||
|
level: 'link',
|
||||||
|
label: '',
|
||||||
|
icon: 'fa fa-copy',
|
||||||
|
size: 'xs',
|
||||||
|
actionType: 'copy',
|
||||||
|
content: '${alias}',
|
||||||
|
tooltip: '复制别名',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function overviewYarnJob(cluster, search, queue, yarnQueue) {
|
||||||
|
return {
|
||||||
|
className: 'font-mono',
|
||||||
|
type: 'service',
|
||||||
|
api: `\${base}/overview/yarn-job?cluster=${cluster}&search=${search}`,
|
||||||
|
interval: 10000,
|
||||||
|
silentPolling: true,
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
className: 'mr-1 font-bold',
|
||||||
|
tpl: `\${PADSTART('${cluster}', 3)}`,
|
||||||
|
},
|
||||||
|
queue === undefined ? {} : {
|
||||||
|
type: 'service',
|
||||||
|
className: 'inline ml-2',
|
||||||
|
api: `\${base}/overview/queue?queue=compaction-queue-${cluster}`,
|
||||||
|
interval: 10000,
|
||||||
|
silentPolling: true,
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: "${PADSTART(size, 2)}",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
' ',
|
||||||
|
{
|
||||||
|
type: 'service',
|
||||||
|
className: 'inline',
|
||||||
|
api: {
|
||||||
|
method: 'get',
|
||||||
|
url: `\${base}/overview/yarn-cluster`,
|
||||||
|
data: {
|
||||||
|
cluster: cluster,
|
||||||
|
queue: yarnQueue,
|
||||||
|
},
|
||||||
|
adaptor: function (payload, response) {
|
||||||
|
let rootUsed = (payload['data']['root']['usedCapacity'] * 100 / payload['data']['root']['capacity']).toFixed(0)
|
||||||
|
let targetUsed = (payload['data']['target']['absoluteUsedCapacity'] * 100 / payload['data']['target']['absoluteMaxCapacity']).toFixed(0)
|
||||||
|
return {
|
||||||
|
...payload,
|
||||||
|
data: {
|
||||||
|
...payload.data,
|
||||||
|
rootUsed: rootUsed,
|
||||||
|
rootUsedColor: color(rootUsed),
|
||||||
|
targetUsed: targetUsed,
|
||||||
|
targetUsedColor: color(targetUsed),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
interval: 10000,
|
||||||
|
silentPolling: true,
|
||||||
|
body: [
|
||||||
|
'(',
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '<span class="font-bold ${rootUsedColor}">${PADSTART(ROUND(rootUsed), 3)}%</span>',
|
||||||
|
},
|
||||||
|
',',
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '<span class="font-bold ${targetUsedColor}">${PADSTART(ROUND(targetUsed), 3)}%</span>',
|
||||||
|
},
|
||||||
|
')'
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'(',
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: "<span class='font-bold text-cyan-300'>${PADSTART(scheduling, 2)}</span>",
|
||||||
|
},
|
||||||
|
',',
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '<span class="font-bold text-success">${PADSTART(running, 3)}</span>',
|
||||||
|
},
|
||||||
|
')',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function overviewTab() {
|
||||||
|
return {
|
||||||
|
className: 'white-space-pre',
|
||||||
|
title: '概览',
|
||||||
|
icon: 'fa fa-circle-info',
|
||||||
|
tab: [
|
||||||
|
{
|
||||||
|
type: 'service',
|
||||||
|
// language=JavaScript
|
||||||
|
dataProvider: 'const timer = setInterval(() => {\n setData({date: new Date().toLocaleString()})\n}, 1000)\nreturn () => {\n clearInterval(timer)\n}',
|
||||||
|
body: [
|
||||||
|
'当前时间:',
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
className: 'font-bold',
|
||||||
|
tpl: '${date}'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{type: 'divider'},
|
||||||
|
'<span class="italic text-gray-500 my-2">表数量 (重点表数量, 普通表数量)</span>',
|
||||||
|
{
|
||||||
|
type: 'service',
|
||||||
|
api: '${base}/overview',
|
||||||
|
interval: 60000,
|
||||||
|
silentPolling: true,
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '逻辑表:<span class="font-bold mr-1 font-mono">${PADSTART(table_count, 4)} (<span class="text-primary">${PADSTART(table_focus_count, 4)}</span>, ${PADSTART(table_count - table_focus_count, 4)})</span>',
|
||||||
|
},
|
||||||
|
'<br>',
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '湖底表:<span class="font-bold mr-1 font-mono">${PADSTART(hudi_count, 4)} (<span class="text-primary">${PADSTART(hudi_focus_count, 4)}</span>, ${PADSTART(hudi_count - hudi_focus_count, 4)})</span>',
|
||||||
|
},
|
||||||
|
'<br>',
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '嗨福表:<span class="font-bold mr-1 font-mono">${PADSTART(hive_count, 4)} (<span class="text-primary">${PADSTART(hive_focus_count, 4)}</span>, ${PADSTART(hive_count - hive_focus_count, 4)})</span>',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{type: 'divider'},
|
||||||
|
{
|
||||||
|
type: 'service',
|
||||||
|
api: '${base}/overview/sync_running_status',
|
||||||
|
interval: 10000,
|
||||||
|
silentPolling: true,
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '任务数<span class="font-bold m-2 font-mono">${totalJob}</span>'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
className: 'mx-2',
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '运行中<span class="font-bold m-2 font-mono">${PADSTART(runningJob, 3)}</span>'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '已停止<span class="font-bold m-2 font-mono text-danger">${PADSTART(unRunningJob, 3)}</span>'
|
||||||
|
},
|
||||||
|
tableDetailDialog('unRunningJob', 'unRunningJobList'),
|
||||||
|
'<br/>',
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '总表数<span class="font-bold m-2 font-mono">${totalTable}</span>'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
className: 'mx-2',
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '运行中<span class="font-bold m-2 font-mono">${PADSTART(runningTable, 3)}</span>'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '已停止<span class="font-bold m-2 font-mono text-danger">${PADSTART(unRunningTable, 3)}</span>'
|
||||||
|
},
|
||||||
|
tableDetailDialog('unRunningTable', 'unRunningTableList'),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{type: 'divider'},
|
||||||
|
'<span class="italic text-gray-500 my-2">集群 (集群总资源使用,队列资源使用)(调度中任务数,运行中任务数)</span>',
|
||||||
|
overviewYarnJob(commonInfo.clusters.sync_names(), 'Sync', undefined, 'default'),
|
||||||
|
{type: 'divider'},
|
||||||
|
{
|
||||||
|
className: 'my-2',
|
||||||
|
type: 'service',
|
||||||
|
api: `\${base}/overview/queue?queue=compaction-queue-pre`,
|
||||||
|
interval: 10000,
|
||||||
|
silentPolling: true,
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '预调度队列:<span class="font-bold">${size}</span>',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'<span class="italic text-gray-500 my-2">集群 压缩队列任务数(集群总资源使用,队列资源使用)(调度中任务数,运行中任务数)</span>',
|
||||||
|
...Object.keys(commonInfo.clusters.compaction).map(name => overviewYarnJob(name, 'Compaction', `compaction-queue-${name}`, commonInfo.clusters.compaction[name])),
|
||||||
|
{type: 'divider'},
|
||||||
|
{
|
||||||
|
type: 'service',
|
||||||
|
api: '${base}/overview/version',
|
||||||
|
interval: 10000,
|
||||||
|
silentPolling: true,
|
||||||
|
body: [
|
||||||
|
'版本:',
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
className: 'font-bold',
|
||||||
|
tpl: '${version}',
|
||||||
|
},
|
||||||
|
'<br/>',
|
||||||
|
'<span class="italic text-gray-500 my-2">未接收, 未跨天</span>',
|
||||||
|
'<br/>',
|
||||||
|
'重点表:',
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '<span class="font-bold font-mono">${PADSTART(unReceive.focus, 3)}</span>',
|
||||||
|
},
|
||||||
|
versionDetailDialog('unReceive.focus', 'unReceive_focus'),
|
||||||
|
',',
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '<span class="font-bold font-mono">${PADSTART(unSchedule.focus, 3)}</span>',
|
||||||
|
},
|
||||||
|
versionDetailDialog('unSchedule.focus', 'unScheduled_focus'),
|
||||||
|
'<br/>',
|
||||||
|
'普通表:',
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '<span class="font-bold font-mono">${PADSTART(unReceive.normal, 3)}</span>',
|
||||||
|
},
|
||||||
|
versionDetailDialog('unReceive.normal', 'unReceive_normal'),
|
||||||
|
',',
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '<span class="font-bold font-mono">${PADSTART(unSchedule.normal, 3)}</span>',
|
||||||
|
},
|
||||||
|
versionDetailDialog('unSchedule.normal', 'unScheduled_normal'),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{type: 'divider'},
|
||||||
|
{
|
||||||
|
type: 'service',
|
||||||
|
api: '${base}/overview/schedule_jobs',
|
||||||
|
interval: 60000,
|
||||||
|
silentPolling: true,
|
||||||
|
body: [
|
||||||
|
'调度策略',
|
||||||
|
{
|
||||||
|
type: 'each',
|
||||||
|
name: 'items',
|
||||||
|
items: {
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '<div class="font-mono"><span class="font-bold">${trigger}</span> <span class="text-gray-500">(${job})</span></div>'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{type: 'divider'},
|
||||||
|
{
|
||||||
|
type: 'crud',
|
||||||
|
title: '监控指标运行进度',
|
||||||
|
api: `\${base}/overview/monitor_progress`,
|
||||||
|
...crudCommonOptions(),
|
||||||
|
interval: 2000,
|
||||||
|
loadDataOnce: true,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
label: '名称',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'running',
|
||||||
|
label: '状态',
|
||||||
|
type: 'mapping',
|
||||||
|
width: 50,
|
||||||
|
map: {
|
||||||
|
'true': '运行中',
|
||||||
|
'false': '未运行',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '进度',
|
||||||
|
type: 'progress',
|
||||||
|
value: '${ROUND(progress * 100)}',
|
||||||
|
map: 'bg-primary',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
function queueCrud(name) {
|
||||||
|
return {
|
||||||
|
type: 'crud',
|
||||||
|
title: name,
|
||||||
|
api: `\${base}/queue/all?name=${name}`,
|
||||||
|
...crudCommonOptions(),
|
||||||
|
interval: 10000,
|
||||||
|
loadDataOnce: true,
|
||||||
|
perPage: 5,
|
||||||
|
headerToolbar: [
|
||||||
|
"reload",
|
||||||
|
'filter-toggler',
|
||||||
|
{
|
||||||
|
type: "tpl",
|
||||||
|
tpl: "共 <span class='text-primary font-bold'>${total|default:0}</span> 个任务"
|
||||||
|
},
|
||||||
|
paginationCommonOptions(false)
|
||||||
|
],
|
||||||
|
footerToolbar: [],
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'data.flinkJobId',
|
||||||
|
label: '任务 ID',
|
||||||
|
width: 190,
|
||||||
|
...copyField('data.flinkJobId')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'data.alias',
|
||||||
|
label: '别名',
|
||||||
|
className: 'nowrap',
|
||||||
|
...copyField('data.alias')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'data.batch',
|
||||||
|
label: '批次',
|
||||||
|
width: 100,
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '<span class="label label-warning">${data.batch}</span>'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'priority',
|
||||||
|
label: '优先级',
|
||||||
|
width: 60,
|
||||||
|
align: 'center',
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '<span class="label bg-info">${priority}</span>'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'data.comment',
|
||||||
|
label: '备注',
|
||||||
|
className: 'nowrap',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createTime',
|
||||||
|
label: '任务提交时间',
|
||||||
|
...time('createTime'),
|
||||||
|
width: 160,
|
||||||
|
fixed: 'right'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function queueTab() {
|
||||||
|
let items = []
|
||||||
|
for (let name of Object.keys(commonInfo.clusters.compaction)) {
|
||||||
|
items.push(yarnQueueCrud(name, commonInfo.clusters.compaction[name]))
|
||||||
|
items.push(queueCrud(`compaction-queue-${name}`))
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
title: '压缩队列',
|
||||||
|
icon: 'fa fa-van-shuttle',
|
||||||
|
tab: [
|
||||||
|
queueCrud('compaction-queue-pre'),
|
||||||
|
...items
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
function runningTable(name) {
|
||||||
|
return {
|
||||||
|
type: 'table',
|
||||||
|
title: `${name}`,
|
||||||
|
itemAction: {
|
||||||
|
type: 'button',
|
||||||
|
actionType: 'dialog',
|
||||||
|
dialog: {
|
||||||
|
title: 'Path',
|
||||||
|
body: '${path}',
|
||||||
|
actions: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{name: 'label', label: '名称'},
|
||||||
|
{
|
||||||
|
name: 'createTime',
|
||||||
|
label: '创建时间',
|
||||||
|
...timeAndFrom('createTime', 'createTimeFromNow', undefined, false),
|
||||||
|
width: 70,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function runningTab() {
|
||||||
|
return {
|
||||||
|
title: '运行中',
|
||||||
|
tab: [
|
||||||
|
{
|
||||||
|
type: 'grid',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'service',
|
||||||
|
api: '${base}/running/sync',
|
||||||
|
body: runningTable('同步')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'service',
|
||||||
|
api: '${base}/running/compaction',
|
||||||
|
body: runningTable('压缩')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
230
service-web/src/main/resources/static/components/table-tab.js
Normal file
230
service-web/src/main/resources/static/components/table-tab.js
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
function tableTab() {
|
||||||
|
return {
|
||||||
|
title: `表任务`,
|
||||||
|
icon: 'fa fa-table',
|
||||||
|
tab: [
|
||||||
|
{
|
||||||
|
id: 'table-service',
|
||||||
|
type: 'service',
|
||||||
|
data: {},
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'crud',
|
||||||
|
api: {
|
||||||
|
method: 'get',
|
||||||
|
url: `\${base}/table/list`,
|
||||||
|
data: {
|
||||||
|
page: '${page|default:undefined}',
|
||||||
|
count: '${perPage|default:undefined}',
|
||||||
|
order: '${orderBy|default:undefined}',
|
||||||
|
direction: '${orderDir|default:undefined}',
|
||||||
|
search_flink_job_id: '${flinkJobId|default:undefined}',
|
||||||
|
search_alias: '${alias|default:undefined}',
|
||||||
|
filter_hudi_table_type: '${tableMeta\\.hudi\\.targetTableType|default:undefined}',
|
||||||
|
filter_run_mode: '${flinkJob\\.runMode|default:undefined}',
|
||||||
|
filter_compaction_status: '${syncState\\.compactionStatus|default:undefined}'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
...crudCommonOptions(),
|
||||||
|
// interval: 10000,
|
||||||
|
filter: {
|
||||||
|
title: '表筛选',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'group',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
...flinkJobIdTextInput("58d0da94-1b3c-4234-948d-482ae3425e70"),
|
||||||
|
size: 'lg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...aliasTextInput("58d0da94-1b3c-4234-948d-482ae3425e70"),
|
||||||
|
size: 'lg',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
type: "submit",
|
||||||
|
level: "primary",
|
||||||
|
label: "查询",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "reset",
|
||||||
|
label: "重置",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
filterTogglable: true,
|
||||||
|
filterDefaultVisible: true,
|
||||||
|
perPage: 20,
|
||||||
|
headerToolbar: [
|
||||||
|
"reload",
|
||||||
|
'filter-toggler',
|
||||||
|
paginationCommonOptions(),
|
||||||
|
],
|
||||||
|
footerToolbar: [
|
||||||
|
paginationCommonOptions(),
|
||||||
|
],
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
label: 'Flink job id',
|
||||||
|
width: 195,
|
||||||
|
fixed: 'left',
|
||||||
|
type: 'wrapper',
|
||||||
|
size: 'none',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'action',
|
||||||
|
level: 'link',
|
||||||
|
label: '${flinkJobId}',
|
||||||
|
size: 'xs',
|
||||||
|
actionType: 'dialog',
|
||||||
|
tooltip: '查看详情',
|
||||||
|
dialog: flinkJobDialog(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'action',
|
||||||
|
level: 'link',
|
||||||
|
label: '',
|
||||||
|
icon: 'fa fa-copy',
|
||||||
|
size: 'xs',
|
||||||
|
actionType: 'copy',
|
||||||
|
content: '${flinkJobId}',
|
||||||
|
tooltip: '复制 ID',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '别名',
|
||||||
|
type: 'wrapper',
|
||||||
|
fixed: 'left',
|
||||||
|
size: 'none',
|
||||||
|
className: 'nowrap',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'action',
|
||||||
|
level: 'link',
|
||||||
|
label: '${tableMeta.alias}',
|
||||||
|
size: 'xs',
|
||||||
|
actionType: 'dialog',
|
||||||
|
tooltip: '查看详情',
|
||||||
|
dialog: tableMetaDialog(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'action',
|
||||||
|
level: 'link',
|
||||||
|
label: '',
|
||||||
|
icon: 'fa fa-copy',
|
||||||
|
size: 'xs',
|
||||||
|
actionType: 'copy',
|
||||||
|
content: '${tableMeta.alias}',
|
||||||
|
tooltip: '复制别名',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'tableMeta.hudi.targetTableType',
|
||||||
|
label: '表类型',
|
||||||
|
width: 60,
|
||||||
|
align: 'center',
|
||||||
|
...mappingField('tableMeta.hudi.targetTableType', hudiTableTypeMapping),
|
||||||
|
filterable: filterableField(hudiTableTypeMapping, true)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'flinkJob.runMode',
|
||||||
|
label: '任务类型',
|
||||||
|
width: 60,
|
||||||
|
align: 'center',
|
||||||
|
...mappingField('flinkJob.runMode', runModeMapping),
|
||||||
|
filterable: filterableField(runModeMapping, true)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'syncRunning',
|
||||||
|
label: '同步运行状态',
|
||||||
|
align: 'center',
|
||||||
|
...mappingField('syncRunning', tableRunningStateMapping),
|
||||||
|
className: 'bg-green-50',
|
||||||
|
width: 75,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'source_start_time',
|
||||||
|
label: '同步启动时间',
|
||||||
|
...timeAndFrom('syncState.sourceStartTime', 'syncState.sourceStartTimeFromNow', '未启动'),
|
||||||
|
sortable: true,
|
||||||
|
className: 'bg-green-50',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'source_receive_time',
|
||||||
|
label: '同步接收时间',
|
||||||
|
...timeAndFrom('syncState.sourceReceiveTime', 'syncState.sourceReceiveTimeFromNow', '无数据'),
|
||||||
|
sortable: true,
|
||||||
|
className: 'bg-green-50',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'source_checkpoint_time',
|
||||||
|
label: '同步心跳时间',
|
||||||
|
...timeAndFrom('syncState.sourceCheckpointTime', 'syncState.sourceCheckpointTimeFromNow', '未启动'),
|
||||||
|
sortable: true,
|
||||||
|
className: 'bg-green-50',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'source_publish_time',
|
||||||
|
label: '源端发布时间',
|
||||||
|
...timeAndFrom('syncState.sourcePublishTime', 'syncState.sourcePublishTimeFromNow', '无增量'),
|
||||||
|
sortable: true,
|
||||||
|
className: 'bg-green-50',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'source_operation_time',
|
||||||
|
label: '源端业务时间',
|
||||||
|
...timeAndFrom('syncState.sourceOperationTime', 'syncState.sourceOperationTimeFromNow', '无增量'),
|
||||||
|
sortable: true,
|
||||||
|
className: 'bg-green-50',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'compactionRunning',
|
||||||
|
label: '压缩运行状态',
|
||||||
|
align: 'center',
|
||||||
|
...mappingField('compactionRunning', tableRunningStateMapping),
|
||||||
|
className: 'bg-cyan-50',
|
||||||
|
width: 75,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'syncState.compactionStatus',
|
||||||
|
label: '压缩状态',
|
||||||
|
width: 60,
|
||||||
|
align: 'center',
|
||||||
|
...mappingField('syncState.compactionStatus', compactionStatusMapping),
|
||||||
|
filterable: filterableField(compactionStatusMapping, true),
|
||||||
|
className: 'bg-cyan-50',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'compaction_start_time',
|
||||||
|
label: '压缩启动时间',
|
||||||
|
...timeAndFrom('syncState.compactionStartTime', 'syncState.compactionStartTimeFromNow'),
|
||||||
|
sortable: true,
|
||||||
|
className: 'bg-cyan-50',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'compaction_latest_operation_time',
|
||||||
|
label: '压缩业务时间',
|
||||||
|
...timeAndFrom('syncState.compactionLatestOperationTime', 'syncState.compactionLatestOperationTimeFromNow', '无'),
|
||||||
|
sortable: true,
|
||||||
|
className: 'bg-cyan-50',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'compaction_finish_time',
|
||||||
|
label: '压缩完成时间',
|
||||||
|
...timeAndFrom('syncState.compactionFinishTime', 'syncState.compactionFinishTimeFromNow'),
|
||||||
|
sortable: true,
|
||||||
|
className: 'bg-cyan-50',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
185
service-web/src/main/resources/static/components/task-tab.js
Normal file
185
service-web/src/main/resources/static/components/task-tab.js
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
function taskTab() {
|
||||||
|
return {
|
||||||
|
title: `离线检索`,
|
||||||
|
icon: 'fa fa-magnifying-glass',
|
||||||
|
tab: [
|
||||||
|
{
|
||||||
|
type: 'form',
|
||||||
|
title: '检索文件',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
type: 'submit',
|
||||||
|
label: '提交任务',
|
||||||
|
actionType: 'ajax',
|
||||||
|
api: {
|
||||||
|
method: 'get',
|
||||||
|
url: '${base}/task/scan',
|
||||||
|
data: {
|
||||||
|
key: '${key|default:undefined}',
|
||||||
|
hdfs: '${hdfs|default:undefined}',
|
||||||
|
pulsar: '${pulsar|default:undefined}',
|
||||||
|
topic: '${topic|default:undefined}',
|
||||||
|
mode: '${scan_mode|default:undefined}',
|
||||||
|
fields: '${fields|default:undefined}',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
name: 'scan_mode',
|
||||||
|
type: 'checkboxes',
|
||||||
|
label: '检索范围',
|
||||||
|
checkAll: true,
|
||||||
|
required: true,
|
||||||
|
value: 'log',
|
||||||
|
options: [
|
||||||
|
{label: '消息队列', value: 'queue'},
|
||||||
|
{label: '日志文件', value: 'log'},
|
||||||
|
{label: '数据文件', value: 'base'},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'key',
|
||||||
|
label: '检索字段',
|
||||||
|
required: true,
|
||||||
|
clearable: true,
|
||||||
|
description: '检索带有该字符的记录',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'hdfs',
|
||||||
|
label: 'HDFS路经',
|
||||||
|
requiredOn: '${CONTAINS(scan_mode, \'log\') || CONTAINS(scan_mode, \'base\')}',
|
||||||
|
visibleOn: '${CONTAINS(scan_mode, \'log\') || CONTAINS(scan_mode, \'base\')}',
|
||||||
|
clearable: true,
|
||||||
|
description: '输入表HDFS路径',
|
||||||
|
autoComplete: '${base}/table/all_hdfs?key=$term',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'fields',
|
||||||
|
label: '指定字段',
|
||||||
|
visibleOn: '${CONTAINS(scan_mode, \'base\')}',
|
||||||
|
clearable: true,
|
||||||
|
description: '逗号分隔,可以大幅提高parquet文件检索速度,但无法获取指定字段外的字段内容',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'group',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'topic',
|
||||||
|
label: 'Pulsar主题',
|
||||||
|
requiredOn: '${CONTAINS(scan_mode, \'queue\')}',
|
||||||
|
visibleOn: '${CONTAINS(scan_mode, \'queue\')}',
|
||||||
|
clearable: true,
|
||||||
|
description: '输入Pulsar主题',
|
||||||
|
autoComplete: '${base}/table/all_pulsar_topic?key=$term',
|
||||||
|
columnRatio: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'pulsar',
|
||||||
|
label: 'Pulsar地址',
|
||||||
|
requiredOn: '${CONTAINS(scan_mode, \'queue\')}',
|
||||||
|
visibleOn: '${CONTAINS(scan_mode, \'queue\')}',
|
||||||
|
clearable: true,
|
||||||
|
description: '输入Pulsar地址',
|
||||||
|
autoComplete: '${base}/table/all_pulsar?key=$term',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'form',
|
||||||
|
title: '综合查询',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
type: 'action',
|
||||||
|
label: '总数&最后操作时间',
|
||||||
|
actionType: 'ajax',
|
||||||
|
api: {
|
||||||
|
method: 'get',
|
||||||
|
url: '${base}/task/table_summary',
|
||||||
|
data: {
|
||||||
|
hdfs: '${hdfs|default:undefined}',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'action',
|
||||||
|
label: '最后10条记录',
|
||||||
|
actionType: 'ajax',
|
||||||
|
api: {
|
||||||
|
method: 'get',
|
||||||
|
url: '${base}/task/table_sampling',
|
||||||
|
data: {
|
||||||
|
hdfs: '${hdfs|default:undefined}',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'hdfs',
|
||||||
|
label: 'HDFS路经',
|
||||||
|
required: true,
|
||||||
|
clearable: true,
|
||||||
|
description: '输入表HDFS路径',
|
||||||
|
autoComplete: '${base}/table/all_hdfs?key=$term',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'crud',
|
||||||
|
api: {
|
||||||
|
method: 'get',
|
||||||
|
url: `\${base}/yarn/job_list`,
|
||||||
|
data: {
|
||||||
|
clusters: commonInfo.clusters.sync_names(),
|
||||||
|
page: '${page|default:undefined}',
|
||||||
|
count: '${perPage|default:undefined}',
|
||||||
|
order: '${orderBy|default:undefined}',
|
||||||
|
direction: '${orderDir|default:undefined}',
|
||||||
|
filter_state: '${state|default:undefined}',
|
||||||
|
filter_final_status: '${finalStatus|default:undefined}',
|
||||||
|
search_id: '${id|default:undefined}',
|
||||||
|
search_name: 'Service_Task',
|
||||||
|
precise: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
affixHeader: false,
|
||||||
|
interval: 10000,
|
||||||
|
syncLocation: false,
|
||||||
|
silentPolling: true,
|
||||||
|
resizable: false,
|
||||||
|
perPage: 10,
|
||||||
|
headerToolbar: [
|
||||||
|
"reload",
|
||||||
|
{
|
||||||
|
label: "任务管理器日志",
|
||||||
|
type: "action",
|
||||||
|
tooltip: '打开Grafana日志',
|
||||||
|
onEvent: {
|
||||||
|
click: {
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
actionType: 'custom',
|
||||||
|
script: () => window.open(serviceLogByAppName("service-executor-manager"), '_blank'),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
paginationCommonOptions(),
|
||||||
|
],
|
||||||
|
footerToolbar: [],
|
||||||
|
columns: yarnCrudColumns(),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
294
service-web/src/main/resources/static/components/tool-tab.js
Normal file
294
service-web/src/main/resources/static/components/tool-tab.js
Normal file
@@ -0,0 +1,294 @@
|
|||||||
|
function toolTab() {
|
||||||
|
return {
|
||||||
|
title: `小工具`,
|
||||||
|
icon: 'fa fa-toolbox',
|
||||||
|
tab: [
|
||||||
|
{
|
||||||
|
type: 'panel',
|
||||||
|
title: '乱七八糟小工具',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'action',
|
||||||
|
label: 'SQL日志',
|
||||||
|
actionType: 'dialog',
|
||||||
|
dialog: {
|
||||||
|
title: '日志',
|
||||||
|
...readOnlyDialogOptions(),
|
||||||
|
size: 'lg',
|
||||||
|
body: {
|
||||||
|
type: 'crud',
|
||||||
|
api: '${base}/log/query_sql_log',
|
||||||
|
...crudCommonOptions(),
|
||||||
|
loadDataOnce: true,
|
||||||
|
perPage: 50,
|
||||||
|
headerToolbar: [
|
||||||
|
"reload",
|
||||||
|
paginationCommonOptions(undefined, 10),
|
||||||
|
],
|
||||||
|
footerToolbar: [
|
||||||
|
paginationCommonOptions(undefined, 10),
|
||||||
|
],
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'sql',
|
||||||
|
label: 'SQL',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createTime',
|
||||||
|
label: '执行时间',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'action',
|
||||||
|
label: 'ZK节点',
|
||||||
|
className: 'ml-2',
|
||||||
|
actionType: 'dialog',
|
||||||
|
dialog: {
|
||||||
|
title: '日志',
|
||||||
|
...readOnlyDialogOptions(),
|
||||||
|
size: 'lg',
|
||||||
|
body: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'form',
|
||||||
|
title: 'HDFS文件管理器',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
label: '直接下载',
|
||||||
|
type: 'action',
|
||||||
|
onEvent: {
|
||||||
|
click: {
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
actionType: 'custom',
|
||||||
|
script: (context, action, event) => {
|
||||||
|
let downloadUrl = `${event.data.base}/hudi/hdfs_download?root=${encodeURI(event.data.hdfs)}`
|
||||||
|
window.open(downloadUrl, '_blank')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'submit',
|
||||||
|
label: '查看',
|
||||||
|
actionType: 'dialog',
|
||||||
|
dialog: hdfsDialog('hdfs'),
|
||||||
|
}
|
||||||
|
],
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'hdfs',
|
||||||
|
label: 'HDFS根路经',
|
||||||
|
required: true,
|
||||||
|
clearable: true,
|
||||||
|
description: '输入表HDFS路径',
|
||||||
|
autoComplete: '${base}/table/all_hdfs?key=$term',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'form',
|
||||||
|
title: '查询时间线',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
type: 'submit',
|
||||||
|
label: '查询时间线',
|
||||||
|
actionType: 'dialog',
|
||||||
|
dialog: {
|
||||||
|
title: 'Hudi 表时间线',
|
||||||
|
actions: [],
|
||||||
|
size: 'lg',
|
||||||
|
body: {
|
||||||
|
type: 'crud',
|
||||||
|
api: {
|
||||||
|
method: 'get',
|
||||||
|
url: '${base}/hudi/timeline/list_hdfs',
|
||||||
|
data: {
|
||||||
|
page: '${page|default:undefined}',
|
||||||
|
count: '${perPage|default:undefined}',
|
||||||
|
order: '${orderBy|default:undefined}',
|
||||||
|
direction: '${orderDir|default:undefined}',
|
||||||
|
hdfs: '${hdfs|default:undefined}',
|
||||||
|
filter_type: "${type|default:active}",
|
||||||
|
filter_action: '${action|default:undefined}',
|
||||||
|
filter_state: '${state|default:undefined}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
...crudCommonOptions(),
|
||||||
|
perPage: 50,
|
||||||
|
headerToolbar: [
|
||||||
|
"reload",
|
||||||
|
paginationCommonOptions(undefined, 10),
|
||||||
|
],
|
||||||
|
footerToolbar: [
|
||||||
|
paginationCommonOptions(undefined, 10),
|
||||||
|
],
|
||||||
|
columns: timelineColumns(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'submit',
|
||||||
|
label: '查询表结构',
|
||||||
|
actionType: 'dialog',
|
||||||
|
dialog: {
|
||||||
|
title: 'Hudi 表结构',
|
||||||
|
actions: [],
|
||||||
|
size: 'lg',
|
||||||
|
body: {
|
||||||
|
type: 'service',
|
||||||
|
api: {
|
||||||
|
method: 'get',
|
||||||
|
url: '${base}/hudi/schema',
|
||||||
|
data: {
|
||||||
|
hdfs: '${hdfs|default:undefined}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
type: 'page',
|
||||||
|
body: {
|
||||||
|
type: 'json',
|
||||||
|
source: '${detail}',
|
||||||
|
levelExpand: 3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'hdfs',
|
||||||
|
label: 'HDFS路经',
|
||||||
|
required: true,
|
||||||
|
clearable: true,
|
||||||
|
description: '输入表HDFS路径',
|
||||||
|
autoComplete: '${base}/table/all_hdfs?key=$term',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'form',
|
||||||
|
title: '提交压缩任务',
|
||||||
|
api: {
|
||||||
|
method: 'get',
|
||||||
|
url: '${base}/schedule/table',
|
||||||
|
data: {
|
||||||
|
flink_job_id: '${flinkJobId|default:undefined}',
|
||||||
|
alias: '${alias|default:undefined}',
|
||||||
|
recommend: "${recommend === 'undefined' ? undefined : recommend|default:undefined}",
|
||||||
|
force: "${force === 'undefined' ? undefined : force|default:undefined}",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
...formReloadFlinkJobIdTextInputAndAliasTextInput("0fe6a96c-6b6e-4346-b18e-c631c2389f48"),
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'group',
|
||||||
|
body: [
|
||||||
|
flinkJobIdTextInput("0fe6a96c-6b6e-4346-b18e-c631c2389f48", true),
|
||||||
|
aliasTextInput("0fe6a96c-6b6e-4346-b18e-c631c2389f48", true),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'group',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
name: 'recommend',
|
||||||
|
type: 'radios',
|
||||||
|
label: '优先指定集群',
|
||||||
|
selectFirst: true,
|
||||||
|
options: [
|
||||||
|
{label: '无', value: 'undefined'},
|
||||||
|
...Object.keys(commonInfo.clusters.compaction)
|
||||||
|
.map(name => {
|
||||||
|
return {label: name, value: name}
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'force',
|
||||||
|
type: 'radios',
|
||||||
|
label: '强制指定集群',
|
||||||
|
selectFirst: true,
|
||||||
|
options: [
|
||||||
|
{label: '无', value: 'undefined'},
|
||||||
|
...Object.keys(commonInfo.clusters.compaction)
|
||||||
|
.map(name => {
|
||||||
|
return {label: name, value: name}
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'form',
|
||||||
|
title: '批量提交压缩任务',
|
||||||
|
api: {
|
||||||
|
method: 'post',
|
||||||
|
url: '${base}/schedule/table_batch',
|
||||||
|
dataType: 'form',
|
||||||
|
},
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
name: 'lines',
|
||||||
|
type: 'textarea',
|
||||||
|
label: '表信息 (flink_job_id alias\\n)',
|
||||||
|
clearable: true,
|
||||||
|
minRows: 5,
|
||||||
|
maxRows: 5,
|
||||||
|
className: 'no-resize',
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'form',
|
||||||
|
title: '停止所有压缩任务',
|
||||||
|
api: {
|
||||||
|
method: 'get',
|
||||||
|
url: '${base}/schedule/stop_all',
|
||||||
|
data: {
|
||||||
|
flink_job_id: '${flinkJobId|default:undefined}',
|
||||||
|
alias: '${alias|default:undefined}',
|
||||||
|
disable_meta: "${disableMeta|default:undefined}",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
...formReloadFlinkJobIdTextInputAndAliasTextInput("163e043e-8cee-41fd-b5a4-0442ac682aec"),
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'group',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
...flinkJobIdTextInput("163e043e-8cee-41fd-b5a4-0442ac682aec", true),
|
||||||
|
columnRatio: 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...aliasTextInput("163e043e-8cee-41fd-b5a4-0442ac682aec", true),
|
||||||
|
columnRatio: 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'disableMeta',
|
||||||
|
type: 'checkbox',
|
||||||
|
label: '是否禁用表',
|
||||||
|
option: '表status设为n',
|
||||||
|
columnRatio: 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
164
service-web/src/main/resources/static/components/version-tab.js
Normal file
164
service-web/src/main/resources/static/components/version-tab.js
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
function versionTab() {
|
||||||
|
return {
|
||||||
|
title: '跨天',
|
||||||
|
icon: 'fa fa-cloud-sun',
|
||||||
|
tab: [
|
||||||
|
{
|
||||||
|
type: 'crud',
|
||||||
|
api: {
|
||||||
|
method: 'get',
|
||||||
|
url: `\${base}/version_update/list`,
|
||||||
|
data: {
|
||||||
|
page: '${page|default:undefined}',
|
||||||
|
count: '${perPage|default:undefined}',
|
||||||
|
order: '${orderBy|default:undefined}',
|
||||||
|
direction: '${orderDir|default:undefined}',
|
||||||
|
search_flink_job_id: '${flinkJobId|default:undefined}',
|
||||||
|
search_alias: '${alias|default:undefined}',
|
||||||
|
search_version: '${version|default:undefined}',
|
||||||
|
filter_schedules: '${updated|default:undefined}'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
now: "${DATETOSTR(DATEMODIFY(NOW(), -1, 'days'), 'YYYYMMDD')}"
|
||||||
|
},
|
||||||
|
...crudCommonOptions(),
|
||||||
|
interval: 10000,
|
||||||
|
filter: {
|
||||||
|
mode: 'inline',
|
||||||
|
title: '表筛选',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'group',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
...flinkJobIdTextInput('c5cac9d3-844a-4d86-b2c5-0c10f2283667'),
|
||||||
|
size: 'md'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...aliasTextInput('c5cac9d3-844a-4d86-b2c5-0c10f2283667'),
|
||||||
|
size: 'md'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input-date',
|
||||||
|
name: 'version',
|
||||||
|
label: '版本',
|
||||||
|
clearable: true,
|
||||||
|
placeholder: '通过版本搜索',
|
||||||
|
size: 'md',
|
||||||
|
format: 'YYYYMMDD',
|
||||||
|
inputFormat: 'YYYYMMDD',
|
||||||
|
value: '${now}',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
type: "submit",
|
||||||
|
level: "primary",
|
||||||
|
label: "查询",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "reset",
|
||||||
|
label: "重置",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
filterTogglable: true,
|
||||||
|
filterDefaultVisible: true,
|
||||||
|
perPage: 20,
|
||||||
|
headerToolbar: [
|
||||||
|
"reload",
|
||||||
|
'filter-toggler',
|
||||||
|
{
|
||||||
|
type: "tpl",
|
||||||
|
tpl: "共 <span class='text-primary font-bold'>${total|default:0}</span> 个表,其中 <span class='text-success font-bold'>${scheduled|default:0}</span> 个表已跨天,<span class='text-danger font-bold'>${unScheduled|default:0}</span> 个表未跨天"
|
||||||
|
},
|
||||||
|
paginationCommonOptions(),
|
||||||
|
],
|
||||||
|
footerToolbar: [
|
||||||
|
paginationCommonOptions(),
|
||||||
|
],
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
label: 'Flink job id',
|
||||||
|
width: 195,
|
||||||
|
fixed: 'left',
|
||||||
|
type: 'wrapper',
|
||||||
|
size: 'none',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'action',
|
||||||
|
level: 'link',
|
||||||
|
label: '${flinkJobId}',
|
||||||
|
size: 'xs',
|
||||||
|
actionType: 'dialog',
|
||||||
|
tooltip: '查看详情',
|
||||||
|
dialog: flinkJobDialog(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'action',
|
||||||
|
level: 'link',
|
||||||
|
label: '',
|
||||||
|
icon: 'fa fa-copy',
|
||||||
|
size: 'xs',
|
||||||
|
actionType: 'copy',
|
||||||
|
content: '${flinkJobId}',
|
||||||
|
tooltip: '复制 ID',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '别名',
|
||||||
|
type: 'wrapper',
|
||||||
|
fixed: 'left',
|
||||||
|
size: 'none',
|
||||||
|
className: 'nowrap',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'action',
|
||||||
|
level: 'link',
|
||||||
|
label: '${tableMeta.alias}',
|
||||||
|
size: 'xs',
|
||||||
|
actionType: 'dialog',
|
||||||
|
tooltip: '查看详情',
|
||||||
|
dialog: tableMetaDialog(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'action',
|
||||||
|
level: 'link',
|
||||||
|
label: '',
|
||||||
|
icon: 'fa fa-copy',
|
||||||
|
size: 'xs',
|
||||||
|
actionType: 'copy',
|
||||||
|
content: '${tableMeta.alias}',
|
||||||
|
tooltip: '复制别名',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'priority',
|
||||||
|
label: '表优先级',
|
||||||
|
align: 'center',
|
||||||
|
width: 75,
|
||||||
|
sortable: true,
|
||||||
|
}, {
|
||||||
|
name: 'version',
|
||||||
|
label: '版本',
|
||||||
|
align: 'center',
|
||||||
|
width: 75,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updated',
|
||||||
|
label: '状态',
|
||||||
|
align: 'center',
|
||||||
|
...mappingField('updated', versionUpdateStateMapping),
|
||||||
|
filterable: filterableField(versionUpdateStateMapping, true),
|
||||||
|
width: 70,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
function yarnClusterTab() {
|
||||||
|
return {
|
||||||
|
title: '集群概览',
|
||||||
|
icon: 'fa fa-circle-nodes',
|
||||||
|
tab: [
|
||||||
|
{
|
||||||
|
type: 'tabs',
|
||||||
|
mountOnEnter: true,
|
||||||
|
unmountOnExit: true,
|
||||||
|
tabsMode: 'line',
|
||||||
|
tabs: [
|
||||||
|
{
|
||||||
|
title: '总体情况',
|
||||||
|
tab: [
|
||||||
|
...Object.keys(commonInfo.clusters.compaction).map(name => yarnQueueCrud(name))
|
||||||
|
],
|
||||||
|
},
|
||||||
|
...Object.keys(commonInfo.clusters.compaction).map(name => yarnTab(name, name)),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
103
service-web/src/main/resources/static/components/yarn-tab.js
Normal file
103
service-web/src/main/resources/static/components/yarn-tab.js
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
function yarnTab(cluster, title, queueNames = 'root', searchName = undefined) {
|
||||||
|
return {
|
||||||
|
title: `${title}集群`,
|
||||||
|
icon: 'fa fa-rotate',
|
||||||
|
tab: [
|
||||||
|
{
|
||||||
|
id: `${cluster}-yarn-service`,
|
||||||
|
name: `${cluster}-yarn-service`,
|
||||||
|
type: 'service',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '<span class="font-bold text-xl">集群资源</span>',
|
||||||
|
},
|
||||||
|
yarnQueueCrud(cluster, queueNames),
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '<span class="font-bold text-xl">集群任务</span>',
|
||||||
|
// className: 'mb-2 block',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'crud',
|
||||||
|
api: {
|
||||||
|
method: 'get',
|
||||||
|
url: '${base}/yarn/job_list',
|
||||||
|
data: {
|
||||||
|
clusters: `${cluster}`,
|
||||||
|
page: '${page|default:undefined}',
|
||||||
|
count: '${perPage|default:undefined}',
|
||||||
|
order: '${orderBy|default:undefined}',
|
||||||
|
direction: '${orderDir|default:undefined}',
|
||||||
|
filter_state: '${state|default:undefined}',
|
||||||
|
filter_final_status: '${finalStatus|default:undefined}',
|
||||||
|
search_id: '${id|default:undefined}',
|
||||||
|
search_name: '${name|default:undefined}',
|
||||||
|
completion: 'true',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
defaultParams: {
|
||||||
|
name: searchName
|
||||||
|
},
|
||||||
|
...crudCommonOptions(),
|
||||||
|
interval: 10000,
|
||||||
|
filter: {
|
||||||
|
mode: 'inline',
|
||||||
|
title: '任务筛选',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'group',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'id',
|
||||||
|
label: 'ID',
|
||||||
|
clearable: true,
|
||||||
|
placeholder: '通过 ID 搜索',
|
||||||
|
size: 'md'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'name',
|
||||||
|
label: '名称',
|
||||||
|
clearable: true,
|
||||||
|
placeholder: '通过名称搜索',
|
||||||
|
size: 'md'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
type: "submit",
|
||||||
|
level: "primary",
|
||||||
|
label: "查询",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "reset",
|
||||||
|
label: "重置",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
filterTogglable: true,
|
||||||
|
filterDefaultVisible: false,
|
||||||
|
perPage: 20,
|
||||||
|
headerToolbar: [
|
||||||
|
"reload",
|
||||||
|
'filter-toggler',
|
||||||
|
{
|
||||||
|
type: "tpl",
|
||||||
|
tpl: "共 <span class='text-primary font-bold'>${total|default:0}</span> 个任务,其中 <span class='text-success font-bold'>${running|default:0}</span> 个任务运行中,<span class='text-danger font-bold'>${unRunning|default:0}</span> 个任务处于非运行状态"
|
||||||
|
},
|
||||||
|
paginationCommonOptions(),
|
||||||
|
],
|
||||||
|
footerToolbar: [
|
||||||
|
paginationCommonOptions(),
|
||||||
|
],
|
||||||
|
columns: yarnCrudColumns(),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
94
service-web/src/main/resources/static/extra.html
Normal file
94
service-web/src/main/resources/static/extra.html
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8"/>
|
||||||
|
<meta
|
||||||
|
content="IE=edge"
|
||||||
|
http-equiv="X-UA-Compatible"
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
content="width=device-width, initial-scale=1.0"
|
||||||
|
name="viewport"
|
||||||
|
/>
|
||||||
|
<title>Hudi 服务页面</title>
|
||||||
|
<link rel="icon" href="assets/icon.png"/>
|
||||||
|
<link href="sdk/antd.css" rel="stylesheet"/>
|
||||||
|
<link href="sdk/helper.css" rel="stylesheet"/>
|
||||||
|
<link href="sdk/iconfont.css" rel="stylesheet"/>
|
||||||
|
<style>
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-resize textarea {
|
||||||
|
resize: none !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script src="sdk/sdk.js"></script>
|
||||||
|
<script src="common/info.js"></script>
|
||||||
|
<script src="components/common.js"></script>
|
||||||
|
<script src="components/table-tab.js"></script>
|
||||||
|
<script src="components/yarn-tab.js"></script>
|
||||||
|
<script src="components/yarn-cluster-tab.js"></script>
|
||||||
|
<script src="components/cloud-tab.js"></script>
|
||||||
|
<script src="components/queue-tab.js"></script>
|
||||||
|
<script src="components/running-tab.js"></script>
|
||||||
|
<script src="components/version-tab.js"></script>
|
||||||
|
<script src="components/overview-tab.js"></script>
|
||||||
|
<script src="components/tool-tab.js"></script>
|
||||||
|
<script src="components/task-tab.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
(function () {
|
||||||
|
let amis = amisRequire('amis/embed')
|
||||||
|
let amisJSON = {
|
||||||
|
type: 'page',
|
||||||
|
title: 'Hudi 服务总台',
|
||||||
|
subTitle: 'Hudi 全链路服务监控和控制台',
|
||||||
|
body: {
|
||||||
|
type: 'tabs',
|
||||||
|
mountOnEnter: true,
|
||||||
|
unmountOnExit: true,
|
||||||
|
tabsMode: 'strong',
|
||||||
|
tabs: [
|
||||||
|
overviewTab(),
|
||||||
|
tableTab(),
|
||||||
|
queueTab(),
|
||||||
|
versionTab(),
|
||||||
|
yarnTab(commonInfo.clusters.sync_names(), '同步', undefined, 'Sync'),
|
||||||
|
yarnTab(commonInfo.clusters.compaction_names(), '压缩', 'default', 'Compaction'),
|
||||||
|
cloudTab(),
|
||||||
|
yarnClusterTab(),
|
||||||
|
toolTab(),
|
||||||
|
taskTab(),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let debug = false
|
||||||
|
let server = amis.embed(
|
||||||
|
'#root',
|
||||||
|
amisJSON,
|
||||||
|
{
|
||||||
|
data: {
|
||||||
|
base: commonInfo.baseUrl
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
theme: 'antd',
|
||||||
|
enableAMISDebug: debug,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (debug) {
|
||||||
|
console.log('Source', amisJSON)
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
90
service-web/src/main/resources/static/index.html
Normal file
90
service-web/src/main/resources/static/index.html
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8"/>
|
||||||
|
<meta
|
||||||
|
content="IE=edge"
|
||||||
|
http-equiv="X-UA-Compatible"
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
content="width=device-width, initial-scale=1.0"
|
||||||
|
name="viewport"
|
||||||
|
/>
|
||||||
|
<title>Hudi 服务页面</title>
|
||||||
|
<link rel="icon" href="assets/icon.png"/>
|
||||||
|
<link href="sdk/antd.css" rel="stylesheet"/>
|
||||||
|
<link href="sdk/helper.css" rel="stylesheet"/>
|
||||||
|
<link href="sdk/iconfont.css" rel="stylesheet"/>
|
||||||
|
<style>
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-resize textarea {
|
||||||
|
resize: none !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script src="sdk/sdk.js"></script>
|
||||||
|
<script src="common/info.js"></script>
|
||||||
|
<script src="components/common.js"></script>
|
||||||
|
<script src="components/table-tab.js"></script>
|
||||||
|
<script src="components/yarn-tab.js"></script>
|
||||||
|
<script src="components/yarn-cluster-tab.js"></script>
|
||||||
|
<script src="components/cloud-tab.js"></script>
|
||||||
|
<script src="components/queue-tab.js"></script>
|
||||||
|
<script src="components/running-tab.js"></script>
|
||||||
|
<script src="components/version-tab.js"></script>
|
||||||
|
<script src="components/overview-tab.js"></script>
|
||||||
|
<script src="components/tool-tab.js"></script>
|
||||||
|
<script src="components/task-tab.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
(function () {
|
||||||
|
let amis = amisRequire('amis/embed')
|
||||||
|
let amisJSON = {
|
||||||
|
type: 'page',
|
||||||
|
title: 'Hudi 服务总台',
|
||||||
|
subTitle: 'Hudi 全链路服务监控和控制台',
|
||||||
|
body: {
|
||||||
|
type: 'tabs',
|
||||||
|
mountOnEnter: true,
|
||||||
|
unmountOnExit: true,
|
||||||
|
tabsMode: 'strong',
|
||||||
|
tabs: [
|
||||||
|
overviewTab(),
|
||||||
|
tableTab(),
|
||||||
|
queueTab(),
|
||||||
|
versionTab(),
|
||||||
|
yarnTab(commonInfo.clusters.sync_names(), '同步', undefined, 'Sync'),
|
||||||
|
yarnTab(commonInfo.clusters.compaction_names(), '压缩', 'default', 'Compaction')
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let debug = false
|
||||||
|
let server = amis.embed(
|
||||||
|
'#root',
|
||||||
|
amisJSON,
|
||||||
|
{
|
||||||
|
data: {
|
||||||
|
base: commonInfo.baseUrl
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
theme: 'antd',
|
||||||
|
enableAMISDebug: debug,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (debug) {
|
||||||
|
console.log('Source', amisJSON)
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
356
service-web/src/main/resources/static/sdk/ang-ie11.css
Normal file
356
service-web/src/main/resources/static/sdk/ang-ie11.css
Normal file
File diff suppressed because one or more lines are too long
292
service-web/src/main/resources/static/sdk/ang.css
Normal file
292
service-web/src/main/resources/static/sdk/ang.css
Normal file
File diff suppressed because one or more lines are too long
355
service-web/src/main/resources/static/sdk/antd-ie11.css
Normal file
355
service-web/src/main/resources/static/sdk/antd-ie11.css
Normal file
File diff suppressed because one or more lines are too long
291
service-web/src/main/resources/static/sdk/antd.css
Normal file
291
service-web/src/main/resources/static/sdk/antd.css
Normal file
File diff suppressed because one or more lines are too long
100
service-web/src/main/resources/static/sdk/barcode.js
Normal file
100
service-web/src/main/resources/static/sdk/barcode.js
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/Barcode.js*/
|
||||||
|
amis.define("0066873",(function(t,e,n,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});e.default=function t(e,n){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.data=e,this.text=n.text||e,this.options=n}}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/CODE39/index.js*/
|
||||||
|
amis.define("f3f69cf",(function(e,t,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.CODE39=void 0;var o,u=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=e("0066873");var a=function(e){function t(e,n){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),e=e.toUpperCase(),n.mod43&&(e+=function(e){return f[e]}(function(e){for(var t=0,n=0;n<e.length;n++)t+=s(e[n]);return t%=43}(e))),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),u(t,[{key:"encode",value:function(){for(var e=l("*"),t=0;t<this.data.length;t++)e+=l(this.data[t])+"0";return{data:e+=l("*"),text:this.text}}},{key:"valid",value:function(){return-1!==this.data.search(/^[0-9A-Z\-\.\ \$\/\+\%]+$/)}}]),t}(((o=i)&&o.__esModule?o:{default:o}).default),f=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","-","."," ","$","/","+","%","*"],c=[20957,29783,23639,30485,20951,29813,23669,20855,29789,23645,29975,23831,30533,22295,30149,24005,21623,29981,23837,22301,30023,23879,30545,22343,30161,24017,21959,30065,23921,22385,29015,18263,29141,17879,29045,18293,17783,29021,18269,17477,17489,17681,20753,35770];function l(e){return function(e){return c[e].toString(2)}(s(e))}function s(e){return f.indexOf(e)}t.CODE39=a}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/CODE128/constants.js*/
|
||||||
|
amis.define("555ccbc",(function(e,r,S,_){"use strict";var A;function C(e,r,S){return r in e?Object.defineProperty(e,r,{value:S,enumerable:!0,configurable:!0,writable:!0}):e[r]=S,e}Object.defineProperty(r,"__esModule",{value:!0});var T=r.SET_A=0,n=r.SET_B=1,i=r.SET_C=2,t=(r.SHIFT=98,r.START_A=103),R=r.START_B=104,o=r.START_C=105;r.MODULO=103,r.STOP=106,r.FNC1=207,r.SET_BY_CODE=(C(A={},t,T),C(A,R,n),C(A,o,i),A),r.SWAP={101:T,100:n,99:i},r.A_START_CHAR=String.fromCharCode(208),r.B_START_CHAR=String.fromCharCode(209),r.C_START_CHAR=String.fromCharCode(210),r.A_CHARS="[\0-_È-Ï]",r.B_CHARS="[ -È-Ï]",r.C_CHARS="(Ï*[0-9]{2}Ï*)",r.BARS=[11011001100,11001101100,11001100110,10010011e3,10010001100,10001001100,10011001e3,10011000100,10001100100,11001001e3,11001000100,11000100100,10110011100,10011011100,10011001110,10111001100,10011101100,10011100110,11001110010,11001011100,11001001110,11011100100,11001110100,11101101110,11101001100,11100101100,11100100110,11101100100,11100110100,11100110010,11011011e3,11011000110,11000110110,10100011e3,10001011e3,10001000110,10110001e3,10001101e3,10001100010,11010001e3,11000101e3,11000100010,10110111e3,10110001110,10001101110,10111011e3,10111000110,10001110110,11101110110,11010001110,11000101110,11011101e3,11011100010,11011101110,11101011e3,11101000110,11100010110,11101101e3,11101100010,11100011010,11101111010,11001000010,11110001010,1010011e4,10100001100,1001011e4,10010000110,10000101100,10000100110,1011001e4,10110000100,1001101e4,10011000010,10000110100,10000110010,11000010010,1100101e4,11110111010,11000010100,10001111010,10100111100,10010111100,10010011110,10111100100,10011110100,10011110010,11110100100,11110010100,11110010010,11011011110,11011110110,11110110110,10101111e3,10100011110,10001011110,10111101e3,10111100010,11110101e3,11110100010,10111011110,10111101110,11101011110,11110101110,11010000100,1101001e4,11010011100,1100011101011]}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/CODE128/CODE128.js*/
|
||||||
|
amis.define("aee9dc4",(function(e,t,r,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o,i=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),u=e("0066873"),a=(o=u)&&o.__esModule?o:{default:o},c=e("555ccbc");var s=function(e){function t(e,r){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t);var n=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e.substring(1),r));return n.bytes=e.split("").map((function(e){return e.charCodeAt(0)})),n}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),i(t,[{key:"valid",value:function(){return/^[\x00-\x7F\xC8-\xD3]+$/.test(this.data)}},{key:"encode",value:function(){var e=this.bytes,r=e.shift()-105,n=c.SET_BY_CODE[r];if(void 0===n)throw new RangeError("The encoding does not start with a start character.");!0===this.shouldEncodeAsEan128()&&e.unshift(c.FNC1);var o=t.next(e,1,n);return{text:this.text===this.data?this.text.replace(/[^\x20-\x7E]/g,""):this.text,data:t.getBar(r)+o.result+t.getBar((o.checksum+r)%c.MODULO)+t.getBar(c.STOP)}}},{key:"shouldEncodeAsEan128",value:function(){var e=this.options.ean128||!1;return"string"==typeof e&&(e="true"===e.toLowerCase()),e}}],[{key:"getBar",value:function(e){return c.BARS[e]?c.BARS[e].toString():""}},{key:"correctIndex",value:function(e,t){if(t===c.SET_A){var r=e.shift();return r<32?r+64:r-32}return t===c.SET_B?e.shift()-32:10*(e.shift()-48)+e.shift()-48}},{key:"next",value:function(e,r,n){if(!e.length)return{result:"",checksum:0};var o=void 0,i=void 0;if(e[0]>=200){i=e.shift()-105;var u=c.SWAP[i];void 0!==u?o=t.next(e,r+1,u):(n!==c.SET_A&&n!==c.SET_B||i!==c.SHIFT||(e[0]=n===c.SET_A?e[0]>95?e[0]-96:e[0]:e[0]<32?e[0]+96:e[0]),o=t.next(e,r+1,n))}else i=t.correctIndex(e,n),o=t.next(e,r+1,n);var a=i*r;return{result:t.getBar(i)+o.result,checksum:a+o.checksum}}}]),t}(a.default);t.default=s}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/CODE128/auto.js*/
|
||||||
|
amis.define("c05cae2",(function(e,n,r,t){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var u=e("555ccbc"),i=function(e){return e.match(new RegExp("^"+u.A_CHARS+"*"))[0].length},C=function(e){return e.match(new RegExp("^"+u.B_CHARS+"*"))[0].length},a=function(e){return e.match(new RegExp("^"+u.C_CHARS+"*"))[0]};function c(e,n){var r=n?u.A_CHARS:u.B_CHARS,t=e.match(new RegExp("^("+r+"+?)(([0-9]{2}){2,})([^0-9]|$)"));if(t)return t[1]+String.fromCharCode(204)+g(e.substring(t[1].length));var i=e.match(new RegExp("^"+r+"+"))[0];return i.length===e.length?e:i+String.fromCharCode(n?205:206)+c(e.substring(i.length),!n)}function g(e){var n=a(e),r=n.length;if(r===e.length)return e;e=e.substring(r);var t=i(e)>=C(e);return n+String.fromCharCode(t?206:205)+c(e,t)}n.default=function(e){var n=void 0;if(a(e).length>=2)n=u.C_START_CHAR+g(e);else{var r=i(e)>C(e);n=(r?u.A_START_CHAR:u.B_START_CHAR)+c(e,r)}return n.replace(/[\xCD\xCE]([^])[\xCD\xCE]/,(function(e,n){return String.fromCharCode(203)+n}))}}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/CODE128/CODE128_AUTO.js*/
|
||||||
|
amis.define("2e27535",(function(e,t,o,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=c(e("aee9dc4")),i=c(e("c05cae2"));function c(e){return e&&e.__esModule?e:{default:e}}function f(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}var u=function(e){function t(e,o){if(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),/^[\x00-\x7F\xC8-\xD3]+$/.test(e))var n=f(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,(0,i.default)(e),o));else n=f(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,o));return f(n)}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t}(r.default);t.default=u}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/CODE128/CODE128A.js*/
|
||||||
|
amis.define("e99aefe",(function(e,t,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o,u=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=e("aee9dc4"),a=(o=i)&&o.__esModule?o:{default:o},c=e("555ccbc");var f=function(e){function t(e,n){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,c.A_START_CHAR+e,n))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),u(t,[{key:"valid",value:function(){return new RegExp("^"+c.A_CHARS+"+$").test(this.data)}}]),t}(a.default);t.default=f}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/CODE128/CODE128B.js*/
|
||||||
|
amis.define("286477e",(function(e,t,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o,u=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=e("aee9dc4"),a=(o=i)&&o.__esModule?o:{default:o},c=e("555ccbc");var f=function(e){function t(e,n){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,c.B_START_CHAR+e,n))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),u(t,[{key:"valid",value:function(){return new RegExp("^"+c.B_CHARS+"+$").test(this.data)}}]),t}(a.default);t.default=f}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/CODE128/CODE128C.js*/
|
||||||
|
amis.define("518ea87",(function(e,t,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o,u=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=e("aee9dc4"),a=(o=i)&&o.__esModule?o:{default:o},c=e("555ccbc");var f=function(e){function t(e,n){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,c.C_START_CHAR+e,n))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),u(t,[{key:"valid",value:function(){return new RegExp("^"+c.C_CHARS+"+$").test(this.data)}}]),t}(a.default);t.default=f}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/CODE128/index.js*/
|
||||||
|
amis.define("8bfc7dc",(function(e,t,u,d){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.CODE128C=t.CODE128B=t.CODE128A=t.CODE128=void 0;var f=l(e("2e27535")),a=l(e("e99aefe")),C=l(e("286477e")),O=l(e("518ea87"));function l(e){return e&&e.__esModule?e:{default:e}}t.CODE128=f.default,t.CODE128A=a.default,t.CODE128B=C.default,t.CODE128C=O.default}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/EAN_UPC/constants.js*/
|
||||||
|
amis.define("15fbfb2",(function(L,G,e,E){"use strict";Object.defineProperty(G,"__esModule",{value:!0});G.SIDE_BIN="101",G.MIDDLE_BIN="01010",G.BINARIES={L:["0001101","0011001","0010011","0111101","0100011","0110001","0101111","0111011","0110111","0001011"],G:["0100111","0110011","0011011","0100001","0011101","0111001","0000101","0010001","0001001","0010111"],R:["1110010","1100110","1101100","1000010","1011100","1001110","1010000","1000100","1001000","1110100"],O:["0001101","0011001","0010011","0111101","0100011","0110001","0101111","0111011","0110111","0001011"],E:["0100111","0110011","0011011","0100001","0011101","0111001","0000101","0010001","0001001","0010111"]},G.EAN2_STRUCTURE=["LL","LG","GL","GG"],G.EAN5_STRUCTURE=["GGLLL","GLGLL","GLLGL","GLLLG","LGGLL","LLGGL","LLLGG","LGLGL","LGLLG","LLGLG"],G.EAN13_STRUCTURE=["LLLLLL","LLGLGG","LLGGLG","LLGGGL","LGLLGG","LGGLLG","LGGGLL","LGLGLG","LGLGGL","LGGLGL"]}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/EAN_UPC/encoder.js*/
|
||||||
|
amis.define("8b3d10d",(function(n,e,t,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var u=n("15fbfb2");e.default=function(n,e,t){var r=n.split("").map((function(n,t){return u.BINARIES[e[t]]})).map((function(e,t){return e?e[n[t]]:""}));if(t){var i=n.length-1;r=r.map((function(n,e){return e<i?n+t:n}))}return r.join("")}}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/EAN_UPC/EAN.js*/
|
||||||
|
amis.define("86352b0",(function(t,e,n,o){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,n,o){return n&&t(e.prototype,n),o&&t(e,o),e}}(),i=t("15fbfb2"),u=a(t("8b3d10d"));function a(t){return t&&t.__esModule?t:{default:t}}var f=function(t){function e(t,n){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e);var o=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t,n));return o.fontSize=!n.flat&&n.fontSize>10*n.width?10*n.width:n.fontSize,o.guardHeight=n.height+o.fontSize/2+n.textMargin,o}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(e,t),r(e,[{key:"encode",value:function(){return this.options.flat?this.encodeFlat():this.encodeGuarded()}},{key:"leftText",value:function(t,e){return this.text.substr(t,e)}},{key:"leftEncode",value:function(t,e){return(0,u.default)(t,e)}},{key:"rightText",value:function(t,e){return this.text.substr(t,e)}},{key:"rightEncode",value:function(t,e){return(0,u.default)(t,e)}},{key:"encodeGuarded",value:function(){var t={fontSize:this.fontSize},e={height:this.guardHeight};return[{data:i.SIDE_BIN,options:e},{data:this.leftEncode(),text:this.leftText(),options:t},{data:i.MIDDLE_BIN,options:e},{data:this.rightEncode(),text:this.rightText(),options:t},{data:i.SIDE_BIN,options:e}]}},{key:"encodeFlat",value:function(){return{data:[i.SIDE_BIN,this.leftEncode(),i.MIDDLE_BIN,this.rightEncode(),i.SIDE_BIN].join(""),text:this.text}}}]),e}(a(t("0066873")).default);e.default=f}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/EAN_UPC/EAN13.js*/
|
||||||
|
amis.define("2482046",(function(t,e,o,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n,i=function(){function t(t,e){for(var o=0;o<e.length;o++){var r=e[o];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,o,r){return o&&t(e.prototype,o),r&&t(e,r),e}}(),a=function t(e,o,r){null===e&&(e=Function.prototype);var n=Object.getOwnPropertyDescriptor(e,o);if(void 0===n){var i=Object.getPrototypeOf(e);return null===i?void 0:t(i,o,r)}if("value"in n)return n.value;var a=n.get;return void 0!==a?a.call(r):void 0},u=t("15fbfb2"),s=t("86352b0"),p=(n=s)&&n.__esModule?n:{default:n};var c=function(t){return(10-t.substr(0,12).split("").map((function(t){return+t})).reduce((function(t,e,o){return o%2?t+3*e:t+e}),0)%10)%10},l=function(t){function e(t,o){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e),-1!==t.search(/^[0-9]{12}$/)&&(t+=c(t));var r=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t,o));return r.lastChar=o.lastChar,r}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(e,t),i(e,[{key:"valid",value:function(){return-1!==this.data.search(/^[0-9]{13}$/)&&+this.data[12]===c(this.data)}},{key:"leftText",value:function(){return a(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"leftText",this).call(this,1,6)}},{key:"leftEncode",value:function(){var t=this.data.substr(1,6),o=u.EAN13_STRUCTURE[this.data[0]];return a(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"leftEncode",this).call(this,t,o)}},{key:"rightText",value:function(){return a(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"rightText",this).call(this,7,6)}},{key:"rightEncode",value:function(){var t=this.data.substr(7,6);return a(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"rightEncode",this).call(this,t,"RRRRRR")}},{key:"encodeGuarded",value:function(){var t=a(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"encodeGuarded",this).call(this);return this.options.displayValue&&(t.unshift({data:"000000000000",text:this.text.substr(0,1),options:{textAlign:"left",fontSize:this.fontSize}}),this.options.lastChar&&(t.push({data:"00"}),t.push({data:"00000",text:this.options.lastChar,options:{fontSize:this.fontSize}}))),t}}]),e}(p.default);e.default=l}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/EAN_UPC/EAN8.js*/
|
||||||
|
amis.define("ef05be9",(function(t,e,r,o){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n,i=function(){function t(t,e){for(var r=0;r<e.length;r++){var o=e[r];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,r,o){return r&&t(e.prototype,r),o&&t(e,o),e}}(),u=function t(e,r,o){null===e&&(e=Function.prototype);var n=Object.getOwnPropertyDescriptor(e,r);if(void 0===n){var i=Object.getPrototypeOf(e);return null===i?void 0:t(i,r,o)}if("value"in n)return n.value;var u=n.get;return void 0!==u?u.call(o):void 0},a=t("86352b0"),c=(n=a)&&n.__esModule?n:{default:n};var f=function(t){return(10-t.substr(0,7).split("").map((function(t){return+t})).reduce((function(t,e,r){return r%2?t+e:t+3*e}),0)%10)%10},l=function(t){function e(t,r){return function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e),-1!==t.search(/^[0-9]{7}$/)&&(t+=f(t)),function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t,r))}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(e,t),i(e,[{key:"valid",value:function(){return-1!==this.data.search(/^[0-9]{8}$/)&&+this.data[7]===f(this.data)}},{key:"leftText",value:function(){return u(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"leftText",this).call(this,0,4)}},{key:"leftEncode",value:function(){var t=this.data.substr(0,4);return u(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"leftEncode",this).call(this,t,"LLLL")}},{key:"rightText",value:function(){return u(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"rightText",this).call(this,4,4)}},{key:"rightEncode",value:function(){var t=this.data.substr(4,4);return u(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"rightEncode",this).call(this,t,"RRRR")}}]),e}(c.default);e.default=l}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/EAN_UPC/EAN5.js*/
|
||||||
|
amis.define("863b430",(function(e,t,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),u=e("15fbfb2"),i=f(e("8b3d10d")),a=f(e("0066873"));function f(e){return e&&e.__esModule?e:{default:e}}var c=function(e){function t(e,n){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),o(t,[{key:"valid",value:function(){return-1!==this.data.search(/^[0-9]{5}$/)}},{key:"encode",value:function(){var e,t=u.EAN5_STRUCTURE[(e=this.data,e.split("").map((function(e){return+e})).reduce((function(e,t,n){return n%2?e+9*t:e+3*t}),0)%10)];return{data:"1011"+(0,i.default)(this.data,t,"01"),text:this.text}}}]),t}(a.default);t.default=c}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/EAN_UPC/EAN2.js*/
|
||||||
|
amis.define("95bb041",(function(e,t,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),a=e("15fbfb2"),u=i(e("8b3d10d"));function i(e){return e&&e.__esModule?e:{default:e}}var f=function(e){function t(e,n){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),o(t,[{key:"valid",value:function(){return-1!==this.data.search(/^[0-9]{2}$/)}},{key:"encode",value:function(){var e=a.EAN2_STRUCTURE[parseInt(this.data)%4];return{data:"1011"+(0,u.default)(this.data,e,"01"),text:this.text}}}]),t}(i(e("0066873")).default);t.default=f}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/EAN_UPC/UPC.js*/
|
||||||
|
amis.define("ab9f86d",(function(t,e,i,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=function(){function t(t,e){for(var i=0;i<e.length;i++){var n=e[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,i,n){return i&&t(e.prototype,i),n&&t(e,n),e}}();e.checksum=u;var o=r(t("8b3d10d"));function r(t){return t&&t.__esModule?t:{default:t}}var s=function(t){function e(t,i){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e),-1!==t.search(/^[0-9]{11}$/)&&(t+=u(t));var n=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t,i));return n.displayValue=i.displayValue,i.fontSize>10*i.width?n.fontSize=10*i.width:n.fontSize=i.fontSize,n.guardHeight=i.height+n.fontSize/2+i.textMargin,n}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(e,t),a(e,[{key:"valid",value:function(){return-1!==this.data.search(/^[0-9]{12}$/)&&this.data[11]==u(this.data)}},{key:"encode",value:function(){return this.options.flat?this.flatEncoding():this.guardedEncoding()}},{key:"flatEncoding",value:function(){var t="";return t+="101",t+=(0,o.default)(this.data.substr(0,6),"LLLLLL"),t+="01010",t+=(0,o.default)(this.data.substr(6,6),"RRRRRR"),{data:t+="101",text:this.text}}},{key:"guardedEncoding",value:function(){var t=[];return this.displayValue&&t.push({data:"00000000",text:this.text.substr(0,1),options:{textAlign:"left",fontSize:this.fontSize}}),t.push({data:"101"+(0,o.default)(this.data[0],"L"),options:{height:this.guardHeight}}),t.push({data:(0,o.default)(this.data.substr(1,5),"LLLLL"),text:this.text.substr(1,5),options:{fontSize:this.fontSize}}),t.push({data:"01010",options:{height:this.guardHeight}}),t.push({data:(0,o.default)(this.data.substr(6,5),"RRRRR"),text:this.text.substr(6,5),options:{fontSize:this.fontSize}}),t.push({data:(0,o.default)(this.data[11],"R")+"101",options:{height:this.guardHeight}}),this.displayValue&&t.push({data:"00000000",text:this.text.substr(11,1),options:{textAlign:"right",fontSize:this.fontSize}}),t}}]),e}(r(t("0066873")).default);function u(t){var e,i=0;for(e=1;e<11;e+=2)i+=parseInt(t[e]);for(e=0;e<11;e+=2)i+=3*parseInt(t[e]);return(10-i%10)%10}e.default=s}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/EAN_UPC/UPCE.js*/
|
||||||
|
amis.define("9e23739",(function(t,e,i,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(t,e){for(var i=0;i<e.length;i++){var n=e[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,i,n){return i&&t(e.prototype,i),n&&t(e,n),e}}(),o=s(t("8b3d10d")),u=s(t("0066873")),a=t("ab9f86d");function s(t){return t&&t.__esModule?t:{default:t}}function O(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}var l=["XX00000XXX","XX10000XXX","XX20000XXX","XXX00000XX","XXXX00000X","XXXXX00005","XXXXX00006","XXXXX00007","XXXXX00008","XXXXX00009"],E=[["EEEOOO","OOOEEE"],["EEOEOO","OOEOEE"],["EEOOEO","OOEEOE"],["EEOOOE","OOEEEO"],["EOEEOO","OEOOEE"],["EOOEEO","OEEOOE"],["EOOOEE","OEEEOO"],["EOEOEO","OEOEOE"],["EOEOOE","OEOEEO"],["EOOEOE","OEEOEO"]],f=function(t){function e(t,i){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e);var n=O(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t,i));if(n.isValid=!1,-1!==t.search(/^[0-9]{6}$/))n.middleDigits=t,n.upcA=c(t,"0"),n.text=i.text||""+n.upcA[0]+t+n.upcA[n.upcA.length-1],n.isValid=!0;else{if(-1===t.search(/^[01][0-9]{7}$/))return O(n);if(n.middleDigits=t.substring(1,t.length-1),n.upcA=c(n.middleDigits,t[0]),n.upcA[n.upcA.length-1]!==t[t.length-1])return O(n);n.isValid=!0}return n.displayValue=i.displayValue,i.fontSize>10*i.width?n.fontSize=10*i.width:n.fontSize=i.fontSize,n.guardHeight=i.height+n.fontSize/2+i.textMargin,n}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(e,t),r(e,[{key:"valid",value:function(){return this.isValid}},{key:"encode",value:function(){return this.options.flat?this.flatEncoding():this.guardedEncoding()}},{key:"flatEncoding",value:function(){var t="";return t+="101",t+=this.encodeMiddleDigits(),{data:t+="010101",text:this.text}}},{key:"guardedEncoding",value:function(){var t=[];return this.displayValue&&t.push({data:"00000000",text:this.text[0],options:{textAlign:"left",fontSize:this.fontSize}}),t.push({data:"101",options:{height:this.guardHeight}}),t.push({data:this.encodeMiddleDigits(),text:this.text.substring(1,7),options:{fontSize:this.fontSize}}),t.push({data:"010101",options:{height:this.guardHeight}}),this.displayValue&&t.push({data:"00000000",text:this.text[7],options:{textAlign:"right",fontSize:this.fontSize}}),t}},{key:"encodeMiddleDigits",value:function(){var t=this.upcA[0],e=this.upcA[this.upcA.length-1],i=E[parseInt(e)][parseInt(t)];return(0,o.default)(this.middleDigits,i)}}]),e}(u.default);function c(t,e){for(var i=parseInt(t[t.length-1]),n=l[i],r="",o=0,u=0;u<n.length;u++){var s=n[u];r+="X"===s?t[o++]:s}return""+(r=""+e+r)+(0,a.checksum)(r)}e.default=f}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/EAN_UPC/index.js*/
|
||||||
|
amis.define("4f36e44",(function(e,f,t,u){"use strict";Object.defineProperty(f,"__esModule",{value:!0}),f.UPCE=f.UPC=f.EAN2=f.EAN5=f.EAN8=f.EAN13=void 0;var d=i(e("2482046")),a=i(e("ef05be9")),l=i(e("863b430")),E=i(e("95bb041")),A=i(e("ab9f86d")),N=i(e("9e23739"));function i(e){return e&&e.__esModule?e:{default:e}}f.EAN13=d.default,f.EAN8=a.default,f.EAN5=l.default,f.EAN2=E.default,f.UPC=A.default,f.UPCE=N.default}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/ITF/constants.js*/
|
||||||
|
amis.define("36aaa8a",(function(e,a,i,t){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.START_BIN="1010",a.END_BIN="11101",a.BINARIES=["00110","10001","01001","11000","00101","10100","01100","00011","10010","01010"]}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/ITF/ITF.js*/
|
||||||
|
amis.define("9ee8c21",(function(e,t,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o,a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=e("36aaa8a"),u=e("0066873");function c(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function f(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}var l=function(e){function t(){return c(this,t),f(this,(t.__proto__||Object.getPrototypeOf(t)).apply(this,arguments))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),a(t,[{key:"valid",value:function(){return-1!==this.data.search(/^([0-9]{2})+$/)}},{key:"encode",value:function(){var e=this,t=this.data.match(/.{2}/g).map((function(t){return e.encodePair(t)})).join("");return{data:i.START_BIN+t+i.END_BIN,text:this.text}}},{key:"encodePair",value:function(e){var t=i.BINARIES[e[1]];return i.BINARIES[e[0]].split("").map((function(e,n){return("1"===e?"111":"1")+("1"===t[n]?"000":"0")})).join("")}}]),t}(((o=u)&&o.__esModule?o:{default:o}).default);t.default=l}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/ITF/ITF14.js*/
|
||||||
|
amis.define("bb51808",(function(e,t,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o,u=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=e("9ee8c21"),a=(o=i)&&o.__esModule?o:{default:o};var c=function(e){var t=e.substr(0,13).split("").map((function(e){return parseInt(e,10)})).reduce((function(e,t,n){return e+t*(3-n%2*2)}),0);return 10*Math.ceil(t/10)-t},f=function(e){function t(e,n){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),-1!==e.search(/^[0-9]{13}$/)&&(e+=c(e)),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),u(t,[{key:"valid",value:function(){return-1!==this.data.search(/^[0-9]{14}$/)&&+this.data[13]===c(this.data)}}]),t}(a.default);t.default=f}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/ITF/index.js*/
|
||||||
|
amis.define("95f71b3",(function(e,t,u,d){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ITF14=t.ITF=void 0;var f=n(e("9ee8c21")),i=n(e("bb51808"));function n(e){return e&&e.__esModule?e:{default:e}}t.ITF=f.default,t.ITF14=i.default}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/MSI/MSI.js*/
|
||||||
|
amis.define("c5c608e",(function(e,t,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o,a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=e("0066873");var u=function(e){function t(e,n){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),a(t,[{key:"encode",value:function(){for(var e="110",t=0;t<this.data.length;t++){var n=parseInt(this.data[t]).toString(2);n=f(n,4-n.length);for(var r=0;r<n.length;r++)e+="0"==n[r]?"100":"110"}return{data:e+="1001",text:this.text}}},{key:"valid",value:function(){return-1!==this.data.search(/^[0-9]+$/)}}]),t}(((o=i)&&o.__esModule?o:{default:o}).default);function f(e,t){for(var n=0;n<t;n++)e="0"+e;return e}t.default=u}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/MSI/checksums.js*/
|
||||||
|
amis.define("e892ab5",(function(e,n,t,r){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.mod10=function(e){for(var n=0,t=0;t<e.length;t++){var r=parseInt(e[t]);(t+e.length)%2==0?n+=r:n+=2*r%10+Math.floor(2*r/10)}return(10-n%10)%10},n.mod11=function(e){for(var n=0,t=[2,3,4,5,6,7],r=0;r<e.length;r++){var o=parseInt(e[e.length-1-r]);n+=t[r%t.length]*o}return(11-n%11)%11}}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/MSI/MSI10.js*/
|
||||||
|
amis.define("fd64aa4",(function(e,t,o,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r,i=e("c5c608e"),c=(r=i)&&r.__esModule?r:{default:r},f=e("e892ab5");var u=function(e){function t(e,o){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e+(0,f.mod10)(e),o))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t}(c.default);t.default=u}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/MSI/MSI11.js*/
|
||||||
|
amis.define("4c3deb2",(function(e,t,o,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r,c=e("c5c608e"),i=(r=c)&&r.__esModule?r:{default:r},u=e("e892ab5");var f=function(e){function t(e,o){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e+(0,u.mod11)(e),o))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t}(i.default);t.default=f}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/MSI/MSI1010.js*/
|
||||||
|
amis.define("1d2817f",(function(e,t,o,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r,i=e("c5c608e"),c=(r=i)&&r.__esModule?r:{default:r},f=e("e892ab5");var u=function(e){function t(e,o){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),e+=(0,f.mod10)(e),e+=(0,f.mod10)(e),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,o))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t}(c.default);t.default=u}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/MSI/MSI1110.js*/
|
||||||
|
amis.define("c0cc622",(function(e,t,o,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r,c=e("c5c608e"),i=(r=c)&&r.__esModule?r:{default:r},u=e("e892ab5");var f=function(e){function t(e,o){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),e+=(0,u.mod11)(e),e+=(0,u.mod10)(e),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,o))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t}(i.default);t.default=f}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/MSI/index.js*/
|
||||||
|
amis.define("e699b6e",(function(e,d,t,u){"use strict";Object.defineProperty(d,"__esModule",{value:!0}),d.MSI1110=d.MSI1010=d.MSI11=d.MSI10=d.MSI=void 0;var f=S(e("c5c608e")),M=S(e("fd64aa4")),a=S(e("4c3deb2")),c=S(e("1d2817f")),I=S(e("c0cc622"));function S(e){return e&&e.__esModule?e:{default:e}}d.MSI=f.default,d.MSI10=M.default,d.MSI11=a.default,d.MSI1010=c.default,d.MSI1110=I.default}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/pharmacode/index.js*/
|
||||||
|
amis.define("f5140b4",(function(e,t,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.pharmacode=void 0;var o,i=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),u=e("0066873");var a=function(e){function t(e,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t);var r=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n));return r.number=parseInt(e,10),r}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),i(t,[{key:"encode",value:function(){for(var e=this.number,t="";!isNaN(e)&&0!=e;)e%2==0?(t="11100"+t,e=(e-2)/2):(t="100"+t,e=(e-1)/2);return{data:t=t.slice(0,-2),text:this.text}}},{key:"valid",value:function(){return this.number>=3&&this.number<=131070}}]),t}(((o=u)&&o.__esModule?o:{default:o}).default);t.pharmacode=a}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/codabar/index.js*/
|
||||||
|
amis.define("7d225bf",(function(e,t,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.codabar=void 0;var o,a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=e("0066873");var u=function(e){function t(e,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),0===e.search(/^[0-9\-\$\:\.\+\/]+$/)&&(e="A"+e+"A");var r=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e.toUpperCase(),n));return r.text=r.options.text||r.text.replace(/[A-D]/g,""),r}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),a(t,[{key:"valid",value:function(){return-1!==this.data.search(/^[A-D][0-9\-\$\:\.\+\/]+[A-D]$/)}},{key:"encode",value:function(){for(var e=[],t=this.getEncodings(),n=0;n<this.data.length;n++)e.push(t[this.data.charAt(n)]),n!==this.data.length-1&&e.push("0");return{text:this.text,data:e.join("")}}},{key:"getEncodings",value:function(){return{0:"101010011",1:"101011001",2:"101001011",3:"110010101",4:"101101001",5:"110101001",6:"100101011",7:"100101101",8:"100110101",9:"110100101","-":"101001101",$:"101100101",":":"1101011011","/":"1101101011",".":"1101101101","+":"1011011011",A:"1011001001",B:"1001001011",C:"1010010011",D:"1010011001"}}}]),t}(((o=i)&&o.__esModule?o:{default:o}).default);t.codabar=u}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/GenericBarcode/index.js*/
|
||||||
|
amis.define("bf352be",(function(e,t,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.GenericBarcode=void 0;var o,i=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),u=e("0066873");var c=function(e){function t(e,n){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),i(t,[{key:"encode",value:function(){return{data:"10101010101010101010101010101010101010101",text:this.text}}},{key:"valid",value:function(){return!0}}]),t}(((o=u)&&o.__esModule?o:{default:o}).default);t.GenericBarcode=c}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/barcodes/index.js*/
|
||||||
|
amis.define("aef9ccb",(function(e,E,c,C){"use strict";Object.defineProperty(E,"__esModule",{value:!0});var a=e("f3f69cf"),f=e("8bfc7dc"),I=e("4f36e44"),d=e("95f71b3"),r=e("e699b6e"),b=e("f5140b4"),M=e("7d225bf"),O=e("bf352be");E.default={CODE39:a.CODE39,CODE128:f.CODE128,CODE128A:f.CODE128A,CODE128B:f.CODE128B,CODE128C:f.CODE128C,EAN13:I.EAN13,EAN8:I.EAN8,EAN5:I.EAN5,EAN2:I.EAN2,UPC:I.UPC,UPCE:I.UPCE,ITF14:d.ITF14,ITF:d.ITF,MSI:r.MSI,MSI10:r.MSI10,MSI11:r.MSI11,MSI1010:r.MSI1010,MSI1110:r.MSI1110,pharmacode:b.pharmacode,codabar:M.codabar,GenericBarcode:O.GenericBarcode}}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/help/merge.js*/
|
||||||
|
amis.define("3ab5a26",(function(e,r,t,n){"use strict";Object.defineProperty(r,"__esModule",{value:!0});var a=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e};r.default=function(e,r){return a({},e,r)}}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/help/linearizeEncodings.js*/
|
||||||
|
amis.define("3d98e11",(function(e,t,r,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){var t=[];return function e(r){if(Array.isArray(r))for(var a=0;a<r.length;a++)e(r[a]);else r.text=r.text||"",r.data=r.data||"",t.push(r)}(e),t}}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/help/fixOptions.js*/
|
||||||
|
amis.define("d56d516",(function(i,n,r,t){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default=function(i){return i.marginTop=i.marginTop||i.margin,i.marginBottom=i.marginBottom||i.margin,i.marginRight=i.marginRight||i.margin,i.marginLeft=i.marginLeft||i.margin,i}}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/help/optionsFromStrings.js*/
|
||||||
|
amis.define("f2a46ae",(function(e,t,a,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){var t=["width","height","textMargin","fontSize","margin","marginTop","marginBottom","marginLeft","marginRight"];for(var a in t)t.hasOwnProperty(a)&&(a=t[a],"string"==typeof e[a]&&(e[a]=parseInt(e[a],10)));"string"==typeof e.displayValue&&(e.displayValue="false"!=e.displayValue);return e}}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/options/defaults.js*/
|
||||||
|
amis.define("2822867",(function(t,i,o,e){"use strict";Object.defineProperty(i,"__esModule",{value:!0});var n={width:2,height:100,format:"auto",displayValue:!0,fontOptions:"",font:"monospace",text:void 0,textAlign:"center",textPosition:"bottom",textMargin:2,fontSize:20,background:"#ffffff",lineColor:"#000000",margin:10,marginTop:void 0,marginBottom:void 0,marginLeft:void 0,marginRight:void 0,valid:function(){}};i.default=n}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/help/getOptionsFromElement.js*/
|
||||||
|
amis.define("432cb14",(function(e,t,a,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var u=d(e("f2a46ae")),o=d(e("2822867"));function d(e){return e&&e.__esModule?e:{default:e}}t.default=function(e){var t={};for(var a in o.default)o.default.hasOwnProperty(a)&&(e.hasAttribute("jsbarcode-"+a.toLowerCase())&&(t[a]=e.getAttribute("jsbarcode-"+a.toLowerCase())),e.hasAttribute("data-"+a.toLowerCase())&&(t[a]=e.getAttribute("data-"+a.toLowerCase())));return t.value=e.getAttribute("jsbarcode-value")||e.getAttribute("data-value"),t=(0,u.default)(t)}}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/renderers/shared.js*/
|
||||||
|
amis.define("279197b",(function(t,e,n,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.getTotalWidthOfEncodings=e.calculateEncodingAttributes=e.getBarcodePadding=e.getEncodingHeight=e.getMaximumHeightOfEncodings=void 0;var a,o=t("3ab5a26"),r=(a=o)&&a.__esModule?a:{default:a};function g(t,e){return e.height+(e.displayValue&&t.text.length>0?e.fontSize+e.textMargin:0)+e.marginTop+e.marginBottom}function d(t,e,n){if(n.displayValue&&e<t){if("center"==n.textAlign)return Math.floor((t-e)/2);if("left"==n.textAlign)return 0;if("right"==n.textAlign)return Math.floor(t-e)}return 0}function u(t,e,n){var i;if(n)i=n;else{if("undefined"==typeof document)return 0;i=document.createElement("canvas").getContext("2d")}i.font=e.fontOptions+" "+e.fontSize+"px "+e.font;var a=i.measureText(t);return a?a.width:0}e.getMaximumHeightOfEncodings=function(t){for(var e=0,n=0;n<t.length;n++)t[n].height>e&&(e=t[n].height);return e},e.getEncodingHeight=g,e.getBarcodePadding=d,e.calculateEncodingAttributes=function(t,e,n){for(var i=0;i<t.length;i++){var a,o=t[i],f=(0,r.default)(e,o.options);a=f.displayValue?u(o.text,f,n):0;var l=o.data.length*f.width;o.width=Math.ceil(Math.max(a,l)),o.height=g(o,f),o.barcodePadding=d(a,l,f)}},e.getTotalWidthOfEncodings=function(t){for(var e=0,n=0;n<t.length;n++)e+=t[n].width;return e}}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/renderers/canvas.js*/
|
||||||
|
amis.define("a98feb3",(function(t,n,e,i){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var a,s=function(){function t(t,n){for(var e=0;e<n.length;e++){var i=n[e];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(n,e,i){return e&&t(n.prototype,e),i&&t(n,i),n}}(),o=t("3ab5a26"),r=(a=o)&&a.__esModule?a:{default:a},h=t("279197b");var c=function(){function t(n,e,i){!function(t,n){if(!(t instanceof n))throw new TypeError("Cannot call a class as a function")}(this,t),this.canvas=n,this.encodings=e,this.options=i}return s(t,[{key:"render",value:function(){if(!this.canvas.getContext)throw new Error("The browser does not support canvas.");this.prepareCanvas();for(var t=0;t<this.encodings.length;t++){var n=(0,r.default)(this.options,this.encodings[t].options);this.drawCanvasBarcode(n,this.encodings[t]),this.drawCanvasText(n,this.encodings[t]),this.moveCanvasDrawing(this.encodings[t])}this.restoreCanvas()}},{key:"prepareCanvas",value:function(){var t=this.canvas.getContext("2d");t.save(),(0,h.calculateEncodingAttributes)(this.encodings,this.options,t);var n=(0,h.getTotalWidthOfEncodings)(this.encodings),e=(0,h.getMaximumHeightOfEncodings)(this.encodings);this.canvas.width=n+this.options.marginLeft+this.options.marginRight,this.canvas.height=e,t.clearRect(0,0,this.canvas.width,this.canvas.height),this.options.background&&(t.fillStyle=this.options.background,t.fillRect(0,0,this.canvas.width,this.canvas.height)),t.translate(this.options.marginLeft,0)}},{key:"drawCanvasBarcode",value:function(t,n){var e,i=this.canvas.getContext("2d"),a=n.data;e="top"==t.textPosition?t.marginTop+t.fontSize+t.textMargin:t.marginTop,i.fillStyle=t.lineColor;for(var s=0;s<a.length;s++){var o=s*t.width+n.barcodePadding;"1"===a[s]?i.fillRect(o,e,t.width,t.height):a[s]&&i.fillRect(o,e,t.width,t.height*a[s])}}},{key:"drawCanvasText",value:function(t,n){var e,i,a=this.canvas.getContext("2d"),s=t.fontOptions+" "+t.fontSize+"px "+t.font;t.displayValue&&(i="top"==t.textPosition?t.marginTop+t.fontSize-t.textMargin:t.height+t.textMargin+t.marginTop+t.fontSize,a.font=s,"left"==t.textAlign||n.barcodePadding>0?(e=0,a.textAlign="left"):"right"==t.textAlign?(e=n.width-1,a.textAlign="right"):(e=n.width/2,a.textAlign="center"),a.fillText(n.text,e,i))}},{key:"moveCanvasDrawing",value:function(t){this.canvas.getContext("2d").translate(t.width,0)}},{key:"restoreCanvas",value:function(){this.canvas.getContext("2d").restore()}}]),t}();n.default=c}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/renderers/svg.js*/
|
||||||
|
amis.define("1880ba9",(function(t,e,i,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r,s=function(){function t(t,e){for(var i=0;i<e.length;i++){var n=e[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,i,n){return i&&t(e.prototype,i),n&&t(e,n),e}}(),o=t("3ab5a26"),a=(r=o)&&r.__esModule?r:{default:r},u=t("279197b");var h="http://www.w3.org/2000/svg",d=function(){function t(e,i,n){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.svg=e,this.encodings=i,this.options=n,this.document=n.xmlDocument||document}return s(t,[{key:"render",value:function(){var t=this.options.marginLeft;this.prepareSVG();for(var e=0;e<this.encodings.length;e++){var i=this.encodings[e],n=(0,a.default)(this.options,i.options),r=this.createGroup(t,n.marginTop,this.svg);this.setGroupOptions(r,n),this.drawSvgBarcode(r,n,i),this.drawSVGText(r,n,i),t+=i.width}}},{key:"prepareSVG",value:function(){for(;this.svg.firstChild;)this.svg.removeChild(this.svg.firstChild);(0,u.calculateEncodingAttributes)(this.encodings,this.options);var t=(0,u.getTotalWidthOfEncodings)(this.encodings),e=(0,u.getMaximumHeightOfEncodings)(this.encodings),i=t+this.options.marginLeft+this.options.marginRight;this.setSvgAttributes(i,e),this.options.background&&this.drawRect(0,0,i,e,this.svg).setAttribute("style","fill:"+this.options.background+";")}},{key:"drawSvgBarcode",value:function(t,e,i){var n,r=i.data;n="top"==e.textPosition?e.fontSize+e.textMargin:0;for(var s=0,o=0,a=0;a<r.length;a++)o=a*e.width+i.barcodePadding,"1"===r[a]?s++:s>0&&(this.drawRect(o-e.width*s,n,e.width*s,e.height,t),s=0);s>0&&this.drawRect(o-e.width*(s-1),n,e.width*s,e.height,t)}},{key:"drawSVGText",value:function(t,e,i){var n,r,s=this.document.createElementNS(h,"text");e.displayValue&&(s.setAttribute("style","font:"+e.fontOptions+" "+e.fontSize+"px "+e.font),r="top"==e.textPosition?e.fontSize-e.textMargin:e.height+e.textMargin+e.fontSize,"left"==e.textAlign||i.barcodePadding>0?(n=0,s.setAttribute("text-anchor","start")):"right"==e.textAlign?(n=i.width-1,s.setAttribute("text-anchor","end")):(n=i.width/2,s.setAttribute("text-anchor","middle")),s.setAttribute("x",n),s.setAttribute("y",r),s.appendChild(this.document.createTextNode(i.text)),t.appendChild(s))}},{key:"setSvgAttributes",value:function(t,e){var i=this.svg;i.setAttribute("width",t+"px"),i.setAttribute("height",e+"px"),i.setAttribute("x","0px"),i.setAttribute("y","0px"),i.setAttribute("viewBox","0 0 "+t+" "+e),i.setAttribute("xmlns",h),i.setAttribute("version","1.1"),i.setAttribute("style","transform: translate(0,0)")}},{key:"createGroup",value:function(t,e,i){var n=this.document.createElementNS(h,"g");return n.setAttribute("transform","translate("+t+", "+e+")"),i.appendChild(n),n}},{key:"setGroupOptions",value:function(t,e){t.setAttribute("style","fill:"+e.lineColor+";")}},{key:"drawRect",value:function(t,e,i,n,r){var s=this.document.createElementNS(h,"rect");return s.setAttribute("x",t),s.setAttribute("y",e),s.setAttribute("width",i),s.setAttribute("height",n),r.appendChild(s),s}}]),t}();e.default=d}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/renderers/object.js*/
|
||||||
|
amis.define("a69cf15",(function(e,n,t,i){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var o=function(){function e(e,n){for(var t=0;t<n.length;t++){var i=n[t];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(n,t,i){return t&&e(n.prototype,t),i&&e(n,i),n}}();var r=function(){function e(n,t,i){!function(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}(this,e),this.object=n,this.encodings=t,this.options=i}return o(e,[{key:"render",value:function(){this.object.encodings=this.encodings}}]),e}();n.default=r}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/renderers/index.js*/
|
||||||
|
amis.define("1973ca7",(function(e,a,t,d){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var r=n(e("a98feb3")),u=n(e("1880ba9")),f=n(e("a69cf15"));function n(e){return e&&e.__esModule?e:{default:e}}a.default={CanvasRenderer:r.default,SVGRenderer:u.default,ObjectRenderer:f.default}}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/exceptions/exceptions.js*/
|
||||||
|
amis.define("ade2392",(function(t,e,n,o){"use strict";function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function c(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}Object.defineProperty(e,"__esModule",{value:!0});var a=function(t){function e(t,n){r(this,e);var o=i(this,(e.__proto__||Object.getPrototypeOf(e)).call(this));return o.name="InvalidInputException",o.symbology=t,o.input=n,o.message='"'+o.input+'" is not a valid input for '+o.symbology,o}return c(e,Error),e}(),u=function(t){function e(){r(this,e);var t=i(this,(e.__proto__||Object.getPrototypeOf(e)).call(this));return t.name="InvalidElementException",t.message="Not supported type to render on",t}return c(e,Error),e}(),s=function(t){function e(){r(this,e);var t=i(this,(e.__proto__||Object.getPrototypeOf(e)).call(this));return t.name="NoElementException",t.message="No element to render on.",t}return c(e,Error),e}();e.InvalidInputException=a,e.InvalidElementException=u,e.NoElementException=s}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/help/getRenderProperties.js*/
|
||||||
|
amis.define("6521707",(function(e,n,t,r){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a=d(e("432cb14")),f=d(e("1973ca7")),u=e("ade2392");function d(e){return e&&e.__esModule?e:{default:e}}function l(e){if("string"==typeof e)return function(e){var n=document.querySelectorAll(e);if(0===n.length)return;for(var t=[],r=0;r<n.length;r++)t.push(l(n[r]));return t}(e);if(Array.isArray(e)){for(var n=[],t=0;t<e.length;t++)n.push(l(e[t]));return n}if("undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLImageElement)return r=e,{element:d=document.createElement("canvas"),options:(0,a.default)(r),renderer:f.default.CanvasRenderer,afterRender:function(){r.setAttribute("src",d.toDataURL())}};if(e&&e.nodeName&&"svg"===e.nodeName.toLowerCase()||"undefined"!=typeof SVGElement&&e instanceof SVGElement)return{element:e,options:(0,a.default)(e),renderer:f.default.SVGRenderer};if("undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement)return{element:e,options:(0,a.default)(e),renderer:f.default.CanvasRenderer};if(e&&e.getContext)return{element:e,renderer:f.default.CanvasRenderer};if(e&&"object"===(void 0===e?"undefined":o(e))&&!e.nodeName)return{element:e,renderer:f.default.ObjectRenderer};throw new u.InvalidElementException;var r,d}n.default=l}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/exceptions/ErrorHandler.js*/
|
||||||
|
amis.define("51e0b19",(function(t,e,n,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=function(){function t(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(e,n,i){return n&&t(e.prototype,n),i&&t(e,i),e}}();var r=function(){function t(e){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.api=e}return a(t,[{key:"handleCatch",value:function(t){if("InvalidInputException"!==t.name)throw t;if(this.api._options.valid===this.api._defaults.valid)throw t.message;this.api._options.valid(!1),this.api.render=function(){}}},{key:"wrapBarcodeCall",value:function(t){try{var e=t.apply(void 0,arguments);return this.api._options.valid(!0),e}catch(t){return this.handleCatch(t),this.api}}}]),t}();e.default=r}));
|
||||||
|
;/*!node_modules/jsbarcode/bin/JsBarcode.js*/
|
||||||
|
amis.define("c4d188f",(function(e,r,t,o){"use strict";var n=c(e("aef9ccb")),i=c(e("3ab5a26")),a=c(e("3d98e11")),s=c(e("d56d516")),d=c(e("6521707")),f=c(e("f2a46ae")),u=c(e("51e0b19")),p=e("ade2392"),l=c(e("2822867"));function c(e){return e&&e.__esModule?e:{default:e}}var h=function(){},_=function(e,r,t){var o=new h;if(void 0===e)throw Error("No element to render on was provided.");return o._renderProperties=(0,d.default)(e),o._encodings=[],o._options=l.default,o._errorHandler=new u.default(o),void 0!==r&&((t=t||{}).format||(t.format=P()),o.options(t)[t.format](r,t).render()),o};for(var v in _.getModule=function(e){return n.default[e]},n.default)n.default.hasOwnProperty(v)&&y(n.default,v);function y(e,r){h.prototype[r]=h.prototype[r.toUpperCase()]=h.prototype[r.toLowerCase()]=function(t,o){var n=this;return n._errorHandler.wrapBarcodeCall((function(){o.text=void 0===o.text?void 0:""+o.text;var a=(0,i.default)(n._options,o);a=(0,f.default)(a);var s=e[r],d=w(t,s,a);return n._encodings.push(d),n}))}}function w(e,r,t){var o=new r(e=""+e,t);if(!o.valid())throw new p.InvalidInputException(o.constructor.name,e);var n=o.encode();n=(0,a.default)(n);for(var s=0;s<n.length;s++)n[s].options=(0,i.default)(t,n[s].options);return n}function P(){return n.default.CODE128?"CODE128":Object.keys(n.default)[0]}function m(e,r,t){r=(0,a.default)(r);for(var o=0;o<r.length;o++)r[o].options=(0,i.default)(t,r[o].options),(0,s.default)(r[o].options);(0,s.default)(t),new(0,e.renderer)(e.element,r,t).render(),e.afterRender&&e.afterRender()}h.prototype.options=function(e){return this._options=(0,i.default)(this._options,e),this},h.prototype.blank=function(e){var r=new Array(e+1).join("0");return this._encodings.push({data:r}),this},h.prototype.init=function(){var e;if(this._renderProperties)for(var r in Array.isArray(this._renderProperties)||(this._renderProperties=[this._renderProperties]),this._renderProperties){e=this._renderProperties[r];var t=(0,i.default)(this._options,e.options);"auto"==t.format&&(t.format=P()),this._errorHandler.wrapBarcodeCall((function(){var r=w(t.value,n.default[t.format.toUpperCase()],t);m(e,r,t)}))}},h.prototype.render=function(){if(!this._renderProperties)throw new p.NoElementException;if(Array.isArray(this._renderProperties))for(var e=0;e<this._renderProperties.length;e++)m(this._renderProperties[e],this._encodings,this._options);else m(this._renderProperties,this._encodings,this._options);return this},h.prototype._defaults=l.default,"undefined"!=typeof window&&(window.JsBarcode=_),"undefined"!=typeof jQuery&&(jQuery.fn.JsBarcode=function(e,r){var t=[];return jQuery(this).each((function(){t.push(this)})),_(t,e,r)}),t.exports=_}));
|
||||||
93
service-web/src/main/resources/static/sdk/charts.js
Normal file
93
service-web/src/main/resources/static/sdk/charts.js
Normal file
File diff suppressed because one or more lines are too long
16
service-web/src/main/resources/static/sdk/codemirror.js
Normal file
16
service-web/src/main/resources/static/sdk/codemirror.js
Normal file
File diff suppressed because one or more lines are too long
130
service-web/src/main/resources/static/sdk/color-picker.js
Normal file
130
service-web/src/main/resources/static/sdk/color-picker.js
Normal file
File diff suppressed because one or more lines are too long
14
service-web/src/main/resources/static/sdk/cropperjs.js
Normal file
14
service-web/src/main/resources/static/sdk/cropperjs.js
Normal file
File diff suppressed because one or more lines are too long
355
service-web/src/main/resources/static/sdk/cxd-ie11.css
Normal file
355
service-web/src/main/resources/static/sdk/cxd-ie11.css
Normal file
File diff suppressed because one or more lines are too long
291
service-web/src/main/resources/static/sdk/cxd.css
Normal file
291
service-web/src/main/resources/static/sdk/cxd.css
Normal file
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user