From 4e7e26d9716deb3c5d975b014c13c58cb2d98f6a Mon Sep 17 00:00:00 2001 From: gitee Date: Fri, 25 Jul 2025 16:22:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=81=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/README.md | 31 +++++++++ doc/server/Dockerfile | 14 ++++ doc/web/Dockerfile | 23 +++++++ doc/web/docs/conf.d/http.conf | 29 +++++++++ doc/web/docs/conf.d/https.conf | 44 +++++++++++++ doc/web/docs/conf.d/nginx.conf | 33 ++++++++++ doc/web/docs/conf.d/servers.conf.template | 6 ++ doc/web/docs/docker-entrypoint.sh | 64 +++++++++++++++++++ doc/web/docs/ssl/cert.pem | 21 ++++++ doc/web/docs/ssl/csr.pem | 17 +++++ doc/web/docs/ssl/key.pem | 28 ++++++++ .../supervision/config/SecurityConfig.java | 11 ++-- .../supervision/constant/PromptTemplate.java | 9 +-- .../com/supervision/domain/DigitalHuman.java | 6 ++ .../com/supervision/dto/DigitalHumanDTO.java | 6 ++ .../danmaku/DanmakuWebSocketHandler.java | 5 +- .../service/impl/AgentServiceImpl.java | 29 +++++---- .../impl/DigitalHumanManageServiceImpl.java | 3 +- .../service/impl/SysUserServiceImpl.java | 1 + src/main/resources/application.yml | 2 +- .../resources/mapper/DigitalHumanMapper.xml | 3 +- 21 files changed, 357 insertions(+), 28 deletions(-) create mode 100644 doc/README.md create mode 100644 doc/server/Dockerfile create mode 100644 doc/web/Dockerfile create mode 100644 doc/web/docs/conf.d/http.conf create mode 100644 doc/web/docs/conf.d/https.conf create mode 100644 doc/web/docs/conf.d/nginx.conf create mode 100644 doc/web/docs/conf.d/servers.conf.template create mode 100644 doc/web/docs/docker-entrypoint.sh create mode 100644 doc/web/docs/ssl/cert.pem create mode 100644 doc/web/docs/ssl/csr.pem create mode 100644 doc/web/docs/ssl/key.pem diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000..be9a233 --- /dev/null +++ b/doc/README.md @@ -0,0 +1,31 @@ +# 运行 + +## 构建后端docker镜像 + +进入Dockerfile所在目录执行命令: + +``` +docker build -t ai-demo-platform-server:1.0.0 . +``` + +## 启动后端服务 + +```shell +docker run -itd --name ai-demo-platform-server -v /data/ai-platform/server:/data/ai-platform/web/ -p 9908:9908 ai-demo-platform-server:1.0.0 +``` + +## 构建前端镜像 + +进入Dockerfile所在目录执行命令: + +``` +docker build -t ai-demo-platform-web:1.0.0 . +``` + +## 启动前端服务 + +> docker run -itd --name ai-demo-platform-web -v /data/ai-platform/web/nginx/html/:/usr/share/nginx/html/ -p 8972:80 -e AI_PLATFORM_SERVER=192.168.10.138:9908 ai-demo-platform-web:1.0.0 + +## 访问前端页面 + +http://192.168.10.138:8972/#/login admin/sst123456# diff --git a/doc/server/Dockerfile b/doc/server/Dockerfile new file mode 100644 index 0000000..a566b61 --- /dev/null +++ b/doc/server/Dockerfile @@ -0,0 +1,14 @@ +# 设置基础镜像 +FROM openjdk:17-jdk-alpine + +# 设置时区(安装 tzdata 并配置) +RUN apk add --no-cache tzdata && \ + ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ + echo "Asia/Shanghai" > /etc/timezone + + +# 暴漏服务端口 +EXPOSE 8080 + +# 设置启动命令 +ENTRYPOINT ["java","-Xms256m","-Xmx1g", "-Xss2m","-Dfile.encoding=utf-8","-Duser.timezone=Asia/Shanghai","-jar","/data/ai-platform/web/ai-demo-platform-1.0-SNAPSHOT.jar"] diff --git a/doc/web/Dockerfile b/doc/web/Dockerfile new file mode 100644 index 0000000..e68d5eb --- /dev/null +++ b/doc/web/Dockerfile @@ -0,0 +1,23 @@ +# 设置基础镜像 +FROM nginx:1.25 + +# 覆盖原镜像的启动脚本 +COPY ./docs/docker-entrypoint.sh /docker-entrypoint.sh +RUN chmod 777 /docker-entrypoint.sh + +# 删除默认的配置文件 +RUN rm /etc/nginx/conf.d/default.conf + +# 复制配置文件信息 +COPY ./docs/conf.d/http.conf ./docs/conf.d/https.conf /etc/nginx/conf.d/ +COPY ./docs/conf.d/nginx.conf /etc/nginx/nginx.conf +COPY ./docs/conf.d/servers.conf.template /data/ai-platform/nginx/conf/servers.conf.template + +# 复制ssl证书信息 +COPY ./docs/ssl /data/ai-platform/nginx/ssl + +# 暴漏服务端口 +EXPOSE 80 443 + +# 设置启动命令 +CMD ["nginx","-g","daemon off;"] \ No newline at end of file diff --git a/doc/web/docs/conf.d/http.conf b/doc/web/docs/conf.d/http.conf new file mode 100644 index 0000000..ddf0d75 --- /dev/null +++ b/doc/web/docs/conf.d/http.conf @@ -0,0 +1,29 @@ +server { + listen 80; + listen [::]:80; + server_name localhost; + + #access_log /var/log/nginx/host.access.log main; + client_max_body_size 20M; # 设置客户端请求的最大上传大小为 20MB,可以根据实际情况修改 + + location / { + root /usr/share/nginx/html/dist; + index index.html index.htm; + try_files $uri $uri/ /index.html; + # add_header Cache-Control no-store; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html/dist; + } + + location /ai-platform/ { + proxy_pass http://ai-platform-server/ai-platform/; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + +} \ No newline at end of file diff --git a/doc/web/docs/conf.d/https.conf b/doc/web/docs/conf.d/https.conf new file mode 100644 index 0000000..751c24c --- /dev/null +++ b/doc/web/docs/conf.d/https.conf @@ -0,0 +1,44 @@ +server { + listen 443 ssl; + server_name example.com; + + ssl_certificate /data/ai-platform/nginx/ssl/cert.pem; + ssl_certificate_key /data/ai-platform/nginx/ssl/key.pem; + + # 配置SSL参数 + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers on; + ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384; + + # 配置SSL会话缓存 + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 30m; + + # 配置SSL安全性选项 + ssl_stapling on; + ssl_stapling_verify on; + resolver 8.8.8.8 8.8.4.4 valid=300s; + resolver_timeout 5s; + + client_max_body_size 20M; # 设置客户端请求的最大上传大小为 20MB,可以根据实际情况修改 + + location / { + root /usr/share/nginx/html/dist; + index index.html index.htm; + try_files $uri $uri/ /index.html; + # add_header Cache-Control no-store; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html/dist; + } + + location /ai-platform/ { + proxy_pass http://ai-platform-server/ai-platform/; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} \ No newline at end of file diff --git a/doc/web/docs/conf.d/nginx.conf b/doc/web/docs/conf.d/nginx.conf new file mode 100644 index 0000000..0a48513 --- /dev/null +++ b/doc/web/docs/conf.d/nginx.conf @@ -0,0 +1,33 @@ +user nginx; +worker_processes auto; + +error_log /var/log/nginx/error.log notice; +pid /var/run/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + include /data/ai-platform/nginx/conf/*.conf; + include /etc/nginx/conf.d/*.conf; + +} \ No newline at end of file diff --git a/doc/web/docs/conf.d/servers.conf.template b/doc/web/docs/conf.d/servers.conf.template new file mode 100644 index 0000000..337b2f8 --- /dev/null +++ b/doc/web/docs/conf.d/servers.conf.template @@ -0,0 +1,6 @@ +# 前台服务后端地址,多个地址可用与负载均衡 +# 解析以逗号分隔的多个 upstream 值 + + upstream ai-platform-server { + server $AI_PLATFORM_SERVER; + } diff --git a/doc/web/docs/docker-entrypoint.sh b/doc/web/docs/docker-entrypoint.sh new file mode 100644 index 0000000..822d6e6 --- /dev/null +++ b/doc/web/docs/docker-entrypoint.sh @@ -0,0 +1,64 @@ +#!/bin/sh +# vim:sw=4:ts=4:et + +set -e +# /etc/nginx/conf.d/servers.conf 文件不存在,就通过环境变量 FU_HSI_SERVERS 生成/data/ai-platform/nginx/conf/servers.conf +if [ ! -f "/data/ai-platform/nginx/conf/servers.conf" ]; then + echo "BEGIN REPLACE SERVERS.CONF ...." + if [ -z "${AI_PLATFORM_SERVER}" ]; then + export AI_PLATFORM_SERVER="${AI_PLATFORM_SERVER}" + fi + + # 替换文件中的变量 + envsubst '$AI_PLATFORM_SERVER' < /data/ai-platform/nginx/conf/servers.conf.template > /data/ai-platform/nginx/conf/servers.conf + + echo "REPLACEMENT COMPLETE" + +else + echo "SERVERS.CONF ALREADY EXISTS" +fi + + + +entrypoint_log() { + if [ -z "${NGINX_ENTRYPOINT_QUIET_LOGS:-}" ]; then + echo "$@" + fi +} + +if [ "$1" = "nginx" ] || [ "$1" = "nginx-debug" ]; then + if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -maxdepth 1 -type f -print -quit 2>/dev/null | read v; then + entrypoint_log "$0: /docker-entrypoint.d/ is not empty, will attempt to perform configuration" + + entrypoint_log "$0: Looking for shell scripts in /docker-entrypoint.d/" + find "/docker-entrypoint.d/" -follow -type f -print | sort -V | while read -r f; do + case "$f" in + *.envsh) + if [ -x "$f" ]; then + entrypoint_log "$0: Sourcing $f"; + . "$f" + else + # warn on shell scripts without exec bit + entrypoint_log "$0: Ignoring $f, not executable"; + fi + ;; + *.sh) + if [ -x "$f" ]; then + entrypoint_log "$0: Launching $f"; + "$f" + else + # warn on shell scripts without exec bit + entrypoint_log "$0: Ignoring $f, not executable"; + fi + ;; + *) entrypoint_log "$0: Ignoring $f";; + esac + done + + entrypoint_log "$0: Configuration complete; ready for start up" + else + entrypoint_log "$0: No files found in /docker-entrypoint.d/, skipping configuration" + fi +fi + +exec "$@" \ No newline at end of file diff --git a/doc/web/docs/ssl/cert.pem b/doc/web/docs/ssl/cert.pem new file mode 100644 index 0000000..1764975 --- /dev/null +++ b/doc/web/docs/ssl/cert.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDdzCCAl8CFC5Pwm//gTURwneg5cjhbkyueufNMA0GCSqGSIb3DQEBCwUAMHgx +CzAJBgNVBAYTAkNIMQswCQYDVQQIDAJOSjEOMAwGA1UEBwwFbmogeWgxDDAKBgNV +BAoMA3NzdDEMMAoGA1UECwwDc3N0MQ8wDQYDVQQDDAZzc3RvcmcxHzAdBgkqhkiG +9w0BCQEWEDEyMzQ1NkBlbWFpbC5jb20wHhcNMjMxMTEwMDEyMzIzWhcNMjMxMjEw +MDEyMzIzWjB4MQswCQYDVQQGEwJDSDELMAkGA1UECAwCTkoxDjAMBgNVBAcMBW5q +IHloMQwwCgYDVQQKDANzc3QxDDAKBgNVBAsMA3NzdDEPMA0GA1UEAwwGc3N0b3Jn +MR8wHQYJKoZIhvcNAQkBFhAxMjM0NTZAZW1haWwuY29tMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA0/VotZw72C+GVQnKsVfwtxeXEPPfiUfE0/H6mp8A +jhxHnFofNK5mvjYs3++U9UEfP1jq84flaD5qgrEGzhauJg6NdrLdcd9RCguu8Pkm +YHIMVl9UzLQexKg15wh0Fc8S6vc3xGBPfosS29YJulXcUZB2CeVJ9CXCTx2Z1dRG +Ug9eMTiPwgB8GnQ56h2GjTyCnVWeVoXBFVef6sY0czkPoJVPk7TZI3K5BmaLBNX1 +0L4OzaJtOa6ZWll3rGxVrk/7oB+Z3t3l8NXF9SrmC039K3sZerNLjlVUdkGD52jz +xCc4Eixcus2pduKfIP3dUhdn05TNUln1/nIFRErcXUWdswIDAQABMA0GCSqGSIb3 +DQEBCwUAA4IBAQCLmsogw3J6KOyHnzaWQaKvhRzqPAupIBY4HYTk+hyOahgMMkkd ++3QIiWU/pp0Nu5iyYytzGRCQIz1Jh+xpk3UQVpayDB8C4XIB7oyzpuatTuyeCvq/ +lnDlk8jk64EewLLWE2pOce6yAKZ/xhcQiDI9YcjgGOkUOjv7Hgqhzwlafrt5FXGB +znFmVi5A52RqkkteplkRsl08OE5VmfxwFYJWZ7QXMlp5ec13oCE21PU+cmLLF/Vb +xl7JJKeMOgDICiSczcYzwP56SiYFktKQ8KmDotFWgBM9mtxkEcOqPb2Xe9vzOclk +AK+5bHhgF2yZGhjbNuzp/FwGSAIozuR5IXxJ +-----END CERTIFICATE----- diff --git a/doc/web/docs/ssl/csr.pem b/doc/web/docs/ssl/csr.pem new file mode 100644 index 0000000..ba2dff7 --- /dev/null +++ b/doc/web/docs/ssl/csr.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICvTCCAaUCAQAweDELMAkGA1UEBhMCQ0gxCzAJBgNVBAgMAk5KMQ4wDAYDVQQH +DAVuaiB5aDEMMAoGA1UECgwDc3N0MQwwCgYDVQQLDANzc3QxDzANBgNVBAMMBnNz +dG9yZzEfMB0GCSqGSIb3DQEJARYQMTIzNDU2QGVtYWlsLmNvbTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANP1aLWcO9gvhlUJyrFX8LcXlxDz34lHxNPx ++pqfAI4cR5xaHzSuZr42LN/vlPVBHz9Y6vOH5Wg+aoKxBs4WriYOjXay3XHfUQoL +rvD5JmByDFZfVMy0HsSoNecIdBXPEur3N8RgT36LEtvWCbpV3FGQdgnlSfQlwk8d +mdXURlIPXjE4j8IAfBp0Oeodho08gp1VnlaFwRVXn+rGNHM5D6CVT5O02SNyuQZm +iwTV9dC+Ds2ibTmumVpZd6xsVa5P+6Afmd7d5fDVxfUq5gtN/St7GXqzS45VVHZB +g+do88QnOBIsXLrNqXbinyD93VIXZ9OUzVJZ9f5yBURK3F1FnbMCAwEAAaAAMA0G +CSqGSIb3DQEBCwUAA4IBAQCFdN/RMNZtduCGs21f5Le4uGePh2nHzqB2tPzPsWYV +LLPO/pInHB0lQ3vJLFtIeaTLIDwB+AFcdM7rNhMGz9rj/Qrk9LCvgm+CQGUOy1h4 +r1tJ27z+8xfwHls/fgghHnSLoaUvma2FfIQzZc/rGTDLkdERBZ1skxOVqIw56qlA +aPyKUt9s/fg6P5xMSv5SDIR89n0i3TChSa8nNdHV1Ld44mLZ7Aw29ChXI5DaQ05t +B6rdNz3AofmxlkzHIlFl46kPMy4H5jgHWlOBT+eLHv/fecPWCNpgnr9vi7O2Ih9o +i8KHDeK1T9Bl5U+sGof6E0Sey/xBOEGnYzuiQUl4kxfL +-----END CERTIFICATE REQUEST----- diff --git a/doc/web/docs/ssl/key.pem b/doc/web/docs/ssl/key.pem new file mode 100644 index 0000000..adb651d --- /dev/null +++ b/doc/web/docs/ssl/key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDT9Wi1nDvYL4ZV +CcqxV/C3F5cQ89+JR8TT8fqanwCOHEecWh80rma+Nizf75T1QR8/WOrzh+VoPmqC +sQbOFq4mDo12st1x31EKC67w+SZgcgxWX1TMtB7EqDXnCHQVzxLq9zfEYE9+ixLb +1gm6VdxRkHYJ5Un0JcJPHZnV1EZSD14xOI/CAHwadDnqHYaNPIKdVZ5WhcEVV5/q +xjRzOQ+glU+TtNkjcrkGZosE1fXQvg7Nom05rplaWXesbFWuT/ugH5ne3eXw1cX1 +KuYLTf0rexl6s0uOVVR2QYPnaPPEJzgSLFy6zal24p8g/d1SF2fTlM1SWfX+cgVE +StxdRZ2zAgMBAAECggEAAPoKh3u20uI1LkMjSfnrxAw5x/w3tXw9LfTZgMjmycDb +m57Wsflzw8CgKFAEUbUBHdudCY5AwmA3QW7rZxu3pbk/caKVXqb2yqMPJVEgmiUs +ZWF/FIpn8eQMi4oAbvFLVwXYnfELrLubVKQB23f10fJmeNkzpApggNjUEqYtxMcH +MjfUmXzrZhvFKdRjdmyITa4gI9djuRvOIfWz0bZTePUtcfgCfpkM3lbxWRIst7Dg +FqCcgX68XOHHDCzzWTE7LasFBZx3mAcOyRMC+MKw96becC4r1c2KFFKh8tFp57y2 +hQ1ybjxeF2MaWf3I/ioi2uTUza+L8m2RsKwABcRwIQKBgQDUrnn/WtKdryDU0rBj +cwsKTrMCycblwYCJj58cGSiETTVJOlhh1N2QtE/kwQI69tUVOc7C5p5FZzk+iff7 +KwvwDqurtW5kKHE5IamUnKqv32bbHuRtg9CB0ktmmbxOrwP5s+QGhh5fKGvFKs3D +xVytLVw76f+BLK4NaBbzCdEN6wKBgQD/IT0F9f9XnTIa1a/bNVLCuRRZdWjDK40i +bD8EgO9T/FxK4yXSV3IB2C6mQNdMxDcmFBTS7EoXPZpZYuFCqBKQvV1OQ0yUAy2b ++PmmZMBakbpQHkIjkq2cgXNXaVdDeKPfoG4SqPz/6x7p/Np/UG9Ey8juNuQXmIiH +wwjwTfqVWQKBgQDNd6ogykuDTvd24/zIdxIJaTKD1Q+0U5asTvY2HRAJkNWT4ywT +h6Rt8eTlaJmRAXmmQezAWjA5eJnTE1NhcZrc1i9/eY4mcPPBcAX2rswvkLI7qsKg +EqJTaSiy/H7xvR8oE2SN8PBSmihTmSCkq3z3SUU8FLpkvxd/mDnjnm469QKBgQCg +rRQ7ftPTH+MAV3erPIfkrp8MQA88a181QKrncTRI1nRhjXCyafQZCUdH2So+5Iw+ +5QLAW6PFwzxD8yweyK74jOoIcgX2aZH92u2PR4CFCaYm8weAU84W9MfpUyRsD7xV +CDqKcfb0TeVoQ6Bv8f5Be34N2HAKFDxYFBK7FMEt8QKBgDNBG3n8/912dDWV1Dve +o4v+TAnlAMHgEXZH+VCCzeIyj1UkUh4sxdIGGaGCPrWGrqxIYIKPKX8gPIWQ7QJj +QJZyL5nqGXWwZUvBuHzE3tB24XJpuHGfg+oBdDfg0aiEMTQKnRORdgHHVdB9W3SN +2TrXQbtwB1X+wioA4615n6ih +-----END PRIVATE KEY----- diff --git a/src/main/java/com/supervision/config/SecurityConfig.java b/src/main/java/com/supervision/config/SecurityConfig.java index 76ca171..b8bc3c9 100644 --- a/src/main/java/com/supervision/config/SecurityConfig.java +++ b/src/main/java/com/supervision/config/SecurityConfig.java @@ -35,8 +35,9 @@ public class SecurityConfig { public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .csrf(AbstractHttpConfigurer::disable) // 禁用CSRF + .cors(Customizer.withDefaults()) .authorizeHttpRequests(auth -> auth - .requestMatchers("/auth/**","/agent/streamChat","/livetalking/chatCallBack","/**").permitAll() + .requestMatchers("/auth/login","/agent/streamChat","/livetalking/chatCallBack","/**").permitAll() .anyRequest().authenticated() ) .sessionManagement(session -> session @@ -44,9 +45,9 @@ public class SecurityConfig { ) .authenticationProvider(authenticationProvider()) .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) - // 👇 正确禁用方式(推荐) - .formLogin(Customizer.withDefaults()) // 启用默认配置 - .httpBasic(Customizer.withDefaults()); // 启用默认配置 + // 禁用 formLogin 和 httpBasic + .formLogin(AbstractHttpConfigurer::disable) + .httpBasic(AbstractHttpConfigurer::disable); return http.build(); } @@ -75,7 +76,7 @@ public class SecurityConfig { public static void main(String[] args) { String s = Base64.getEncoder().encodeToString(Keys.secretKeyFor(SignatureAlgorithm.HS256).getEncoded()); BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); - String encode = bCryptPasswordEncoder.encode("123456"); + String encode = bCryptPasswordEncoder.encode("sst123456#"); System.out.println(encode); } diff --git a/src/main/java/com/supervision/constant/PromptTemplate.java b/src/main/java/com/supervision/constant/PromptTemplate.java index a4925c2..0481bb7 100644 --- a/src/main/java/com/supervision/constant/PromptTemplate.java +++ b/src/main/java/com/supervision/constant/PromptTemplate.java @@ -6,12 +6,13 @@ public class PromptTemplate { public static final String GENERAL_INDUSTRY_TEMPLATE = """ 你是一个由苏胜天科技有限公司制造的通用行业的智能体,擅长处理各种行业的任务。请根据用户的需求,提供专业的建议和解决方案。 请以专业的语气回答问题,确保提供的信息准确且有用。 - 用户需求:{query} """; public static final String HEART_GUIDE_TEMPLATE = """ - 你是一个由苏胜天科技有限公司制造的心灵导师智能体,擅长提供情感支持和心理指导。请根据用户的需求,提供温暖和关怀的建议。 - 请以温柔的语气回答问题,确保提供的信息能够帮助用户感到被理解和支持。 - 用户需求:{query} + 你是小星老师,是由南京苏胜天信息科技有限公司开发的心理情感咨询类大模型,拥有超过10年的临床经验,擅长倾听和支持来访者探索内心世界。 + 与来访者交流时,请保持温暖、同理和尊重,不作任何评判;使用开放式提问,帮助对方自我觉察。 + 严格遵守职业伦理,保护来访者隐私;绝不在对话中泄露任何个人信息,也不提供医学诊断或用药建议。 + 当来访者表达焦虑、悲伤等负面情绪时,可适时引导呼吸练习、正念练习或情绪日记等自我调节技术。 + 保持中立与客观,适时给予积极肯定与鼓励;在结束对话时,为来访者提供后续支持渠道建议(如危机热线)。 """; } diff --git a/src/main/java/com/supervision/domain/DigitalHuman.java b/src/main/java/com/supervision/domain/DigitalHuman.java index 9228eda..fe07e9c 100644 --- a/src/main/java/com/supervision/domain/DigitalHuman.java +++ b/src/main/java/com/supervision/domain/DigitalHuman.java @@ -60,6 +60,12 @@ public class DigitalHuman implements Serializable { */ private String gender; + + /** + * 服务地址 + */ + private String serviceUrl; + /** * 创建时间 */ diff --git a/src/main/java/com/supervision/dto/DigitalHumanDTO.java b/src/main/java/com/supervision/dto/DigitalHumanDTO.java index 1966a97..7802579 100644 --- a/src/main/java/com/supervision/dto/DigitalHumanDTO.java +++ b/src/main/java/com/supervision/dto/DigitalHumanDTO.java @@ -48,6 +48,11 @@ public class DigitalHumanDTO { * 模特性别 0:女 1:男 */ private String gender; + + /** + * 服务地址 + */ + private String serviceUrl; public DigitalHumanDTO() { } @@ -61,5 +66,6 @@ public class DigitalHumanDTO { this.modelType = digitalHuman.getModelType(); this.headPicId = digitalHuman.getHeadPicId(); this.gender = digitalHuman.getGender(); + this.serviceUrl = digitalHuman.getServiceUrl(); } } diff --git a/src/main/java/com/supervision/service/danmaku/DanmakuWebSocketHandler.java b/src/main/java/com/supervision/service/danmaku/DanmakuWebSocketHandler.java index 3028c1f..3597d8b 100644 --- a/src/main/java/com/supervision/service/danmaku/DanmakuWebSocketHandler.java +++ b/src/main/java/com/supervision/service/danmaku/DanmakuWebSocketHandler.java @@ -43,6 +43,9 @@ public class DanmakuWebSocketHandler extends TextWebSocketHandler { // 保存到日志 String messageId = dialogueLogService.saveLog(danmaku); + // 发布到消息中心 + DanmakuPublisher.getInstance().publish(danmaku); + // 判断是否需要回复 if (isQuestion(danmaku.getContent())) { log.info("检测到问题: {}", danmaku.getContent()); @@ -50,8 +53,6 @@ public class DanmakuWebSocketHandler extends TextWebSocketHandler { livetalkingChatDTO.setMessageId(messageId); livetalkingService.chat(livetalkingChatDTO); } - // 发布到消息中心 - DanmakuPublisher.getInstance().publish(danmaku); } @Override diff --git a/src/main/java/com/supervision/service/impl/AgentServiceImpl.java b/src/main/java/com/supervision/service/impl/AgentServiceImpl.java index c4a1969..863466e 100644 --- a/src/main/java/com/supervision/service/impl/AgentServiceImpl.java +++ b/src/main/java/com/supervision/service/impl/AgentServiceImpl.java @@ -18,6 +18,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.ai.chat.messages.AssistantMessage; import org.springframework.ai.chat.messages.Message; +import org.springframework.ai.chat.messages.SystemMessage; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.metadata.ChatResponseMetadata; import org.springframework.ai.chat.prompt.Prompt; @@ -43,26 +44,28 @@ public class AgentServiceImpl implements AgentService { // 查询历史对话(记忆功能) List messages = buildHistoryMessages(agentChatReqDTO.getConversationId(), 10); // 构建当前对话 - Message message = buildQueryMessage(agentChatReqDTO.getQuery(), agentChatReqDTO.getAgentCode()); - Assert.notNull(message, "Agent not found for ID: " + agentChatReqDTO.getAgentCode()); - messages.add(message); + Assert.notEmpty(agentChatReqDTO.getAgentCode(), "Agent not found for code: " + agentChatReqDTO.getAgentCode()); + Message systemMessage = buildSystemMessage(agentChatReqDTO.getAgentCode()); + messages.add(0,systemMessage); + messages.add(new UserMessage(agentChatReqDTO.getQuery())); AgentDialogueLogDTO dialogueLogDTO = new AgentDialogueLogDTO(agentChatReqDTO); StringBuilder aiResponseBuilder = new StringBuilder(); + String conversationId = StrUtil.isNotEmpty(agentChatReqDTO.getConversationId()) ? agentChatReqDTO.getConversationId() : UUID.fastUUID().toString(); Flux map = aiCallService.stream(new Prompt(messages)) .scan(new ThinkTagState(), (state, response) -> { String chunk = response.getResult().getOutput().getText(); state.setChatResponse(response); return state.process(chunk); }) - .filter(state -> StrUtil.isNotEmpty(state.getFilteredText())) + .filter(state -> StrUtil.isNotBlank(state.getFilteredText())) .map(response -> { ChatResponseDTO responseDTO = new ChatResponseDTO(); responseDTO.setAnswer(response.getChatResponse().getResult().getOutput().getText()); - responseDTO.setConversationId(StrUtil.isNotEmpty(agentChatReqDTO.getConversationId()) ? agentChatReqDTO.getConversationId() : UUID.fastUUID().toString()); + responseDTO.setConversationId(conversationId); ChatResponseMetadata metadata = response.getChatResponse().getMetadata(); Boolean done = metadata.get("done"); responseDTO.setEvent(done ? "message_end" : "message"); - dialogueLogDTO.setConversationId(responseDTO.getConversationId()); + dialogueLogDTO.setConversationId(conversationId); aiResponseBuilder.append(responseDTO.getAnswer()); return responseDTO; }).doOnComplete(() -> { @@ -83,15 +86,13 @@ public class AgentServiceImpl implements AgentService { return paged.convert(AgentInfoDTO::new); } - private Message buildQueryMessage(String query,String agentCode) { - if (StrUtil.equals(agentCode, "1")) { - String template = PromptTemplate.GENERAL_INDUSTRY_TEMPLATE; - return new UserMessage(StrUtil.format(template, Map.of("query",query))); - }else if (StrUtil.equals(agentCode, "2")) { - String template = PromptTemplate.HEART_GUIDE_TEMPLATE; - return new UserMessage(StrUtil.format(template, Map.of("query",query))); + private Message buildSystemMessage(String agentCode) { + if (StrUtil.equals(agentCode, "tyhy")) { + return new SystemMessage(PromptTemplate.GENERAL_INDUSTRY_TEMPLATE); + }else if (StrUtil.equals(agentCode, "xlzx")) { + return new SystemMessage(PromptTemplate.HEART_GUIDE_TEMPLATE); } - return null; + throw new IllegalArgumentException("Unsupported agent code: " + agentCode); } private List buildHistoryMessages(String conversationId,int historySize) { List messages = new ArrayList<>(); diff --git a/src/main/java/com/supervision/service/impl/DigitalHumanManageServiceImpl.java b/src/main/java/com/supervision/service/impl/DigitalHumanManageServiceImpl.java index 1597cf0..9a6071f 100644 --- a/src/main/java/com/supervision/service/impl/DigitalHumanManageServiceImpl.java +++ b/src/main/java/com/supervision/service/impl/DigitalHumanManageServiceImpl.java @@ -1,6 +1,7 @@ package com.supervision.service.impl; import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -52,7 +53,7 @@ public class DigitalHumanManageServiceImpl implements DigitalHumanManageService public void chatCallBack(LivetalkingChatDTO digitalHumanVoiceDTO) { // 这里可以添加处理聊天回调的逻辑 log.info("Received chat callback: {}", JSONUtil.toJsonStr(digitalHumanVoiceDTO)); - + digitalHumanVoiceDTO.setAnswer(StrUtil.trim(digitalHumanVoiceDTO.getAnswer())); DigitalHumanDialogueLog dialogueLog = new DigitalHumanDialogueLog(); dialogueLog.setId(digitalHumanVoiceDTO.getMessageId()); dialogueLog.setDigitalHumanId(digitalHumanVoiceDTO.getHumanId()); diff --git a/src/main/java/com/supervision/service/impl/SysUserServiceImpl.java b/src/main/java/com/supervision/service/impl/SysUserServiceImpl.java index 74f2cfb..990d300 100644 --- a/src/main/java/com/supervision/service/impl/SysUserServiceImpl.java +++ b/src/main/java/com/supervision/service/impl/SysUserServiceImpl.java @@ -33,6 +33,7 @@ public class SysUserServiceImpl extends ServiceImpl Assert.notNull(one, "用户不存在"); user.setId(one.getId()); SysUser sysUser = user.toUser(); + sysUser.setPassword(one.getPassword());// 设置密码 return super.updateById(sysUser); } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 44e841b..708e034 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,7 +4,7 @@ server: context-path: /ai-platform spring: application: - name: pdf-qa-server + name: ai-platform datasource: druid: url: jdbc:postgresql://192.168.10.137:54321/ai-demo-platform diff --git a/src/main/resources/mapper/DigitalHumanMapper.xml b/src/main/resources/mapper/DigitalHumanMapper.xml index 6f810ac..5e241d8 100644 --- a/src/main/resources/mapper/DigitalHumanMapper.xml +++ b/src/main/resources/mapper/DigitalHumanMapper.xml @@ -13,12 +13,13 @@ + - id,model_name,industry, + id,model_name,industry,service_url, good_at,default_voice_id,online_status, model_type,head_pic_id,create_time, update_time