diff --git a/root/pom.xml b/root/pom.xml
index 19f3ca19..10a3820d 100644
--- a/root/pom.xml
+++ b/root/pom.xml
@@ -17,6 +17,7 @@
../common
../modules
../web
+ ../web-ai
../web-api
../web-fast
../web-mini
diff --git a/web-ai/README.md b/web-ai/README.md
new file mode 100644
index 00000000..280759eb
--- /dev/null
+++ b/web-ai/README.md
@@ -0,0 +1,19 @@
+## 介绍
+
+jeesite-web-ai 拷贝自 jeesite-web 只保留了 AI 模块的引用,
+
+可直接运行 AiApplication.java 文件,启动一个 Web 服务。
+
+启动 Web 服务后,可通过网页浏览器访问 JeeSite 系统。
+
+## 更多介绍
+
+1.
+
+## 文档
+
+部署文档:http://jeesite.com/docs/install-deploy/
+
+常见问题:http://jeesite.com/docs/faq/
+
+更多文档:http://jeesite.com/docs
diff --git a/web-ai/bin/docker-build.bat b/web-ai/bin/docker-build.bat
new file mode 100644
index 00000000..a70a6f87
--- /dev/null
+++ b/web-ai/bin/docker-build.bat
@@ -0,0 +1,19 @@
+@echo off
+rem /**
+rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+rem * No deletion without permission, or be held responsible to law.
+rem *
+rem * Author: ThinkGem@163.com
+rem */
+echo.
+echo [Ϣ] WeḅDocker
+echo.
+
+%~d0
+cd %~dp0
+
+cd ..
+call mvn clean package docker:remove docker:build -Dmaven.test.skip=true -U
+
+cd bin
+pause
\ No newline at end of file
diff --git a/web-ai/bin/docker-build.sh b/web-ai/bin/docker-build.sh
new file mode 100644
index 00000000..ab475930
--- /dev/null
+++ b/web-ai/bin/docker-build.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+# /**
+# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+# * No deletion without permission, or be held responsible to law.
+# *
+# * Author: ThinkGem@163.com
+# *
+# */
+echo ""
+echo "[信息] 打包Web工程,编译Docker镜像。"
+echo ""
+
+cd ..
+mvn clean package docker:remove docker:build -Dmaven.test.skip=true -U
+
+cd bin
\ No newline at end of file
diff --git a/web-ai/bin/docker/Dockerfile b/web-ai/bin/docker/Dockerfile
new file mode 100644
index 00000000..ec998b79
--- /dev/null
+++ b/web-ai/bin/docker/Dockerfile
@@ -0,0 +1,22 @@
+FROM docker.m.daocloud.io/openjdk:17
+LABEL maintainer="ThinkGem@163.com"
+ENV TZ "Asia/Shanghai"
+ENV LANG C.UTF-8
+VOLUME /tmp
+VOLUME /data
+
+WORKDIR /app
+
+#RUN mkdir WEB-INF
+#ADD jeesite.lic ./WEB-INF
+ADD ./maven/web.war ./app.war
+
+#ENV JAVA_OPTS "$JAVA_OPTS -Xms256m -Xmx1024m"
+ENV JAVA_OPTS "$JAVA_OPTS -Dspring.profiles.active=prod"
+
+ENTRYPOINT if [ -f "app.war" ]; then jar -xvf app.war && rm app.war; \
+ fi && cd WEB-INF && sh startup.sh && cd WEB-INF && sh startup.sh
+
+EXPOSE 8980
+
+#docker run -p 8980:8980 thinkgem/jeesite-web:5.10
diff --git a/web-ai/bin/init-data.bat b/web-ai/bin/init-data.bat
new file mode 100644
index 00000000..42886268
--- /dev/null
+++ b/web-ai/bin/init-data.bat
@@ -0,0 +1,34 @@
+@echo off
+rem /**
+rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+rem * No deletion without permission, or be held responsible to law.
+rem *
+rem * Author: ThinkGem@163.com
+rem */
+echo.
+echo [Ϣ] ʼݿ⡣
+echo.
+echo [Ϣ] Ҫ״ΰװ JeeSite װ Module ݱʼģѰװԶԡ
+echo.
+echo [Ϣ] ٷĬṩijʼݿDZȽϰȫģûаɾҵݱݵĽű
+echo.
+echo [Ϣ] ð汾ųǷΪȫȱݿٲ
+echo.
+pause
+
+%~d0
+cd %~dp0
+
+cd ..
+
+call mvn clean compile -Dmaven.test.skip=true -U
+echo.
+echo [Ϣ] ɣ濪ʼʼݿ⡣
+echo.
+pause
+
+set "MAVEN_OPTS=%MAVEN_OPTS% -Xms512m -Xmx1024m"
+call mvn test -Dmaven.test.skip=false -Dtest=com.jeesite.test.InitData
+
+cd bin
+pause
\ No newline at end of file
diff --git a/web-ai/bin/init-data.sh b/web-ai/bin/init-data.sh
new file mode 100644
index 00000000..71018685
--- /dev/null
+++ b/web-ai/bin/init-data.sh
@@ -0,0 +1,35 @@
+#!/usr/bin/env bash
+# /**
+# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+# * No deletion without permission, or be held responsible to law.
+# *
+# * Author: ThinkGem@163.com
+# *
+# */
+echo ""
+echo "[信息] 初始化数据库。"
+echo ""
+echo "[信息] 本操作主要用于首次安装 JeeSite 或后安装 Module 的数据表初始化,若模块已安装会自动忽略。"
+echo ""
+echo "[信息] 官方默认提供的初始化数据库工具是比较安全的,她没有包含删除您的业务数据表及数据的脚本。"
+echo ""
+echo "[信息] 如果你是升级到该版本,不排除你是否升级完整,为安全起见,建议先备份数据库后再操作。"
+echo ""
+echo "请按回车键继续 ... "
+read text
+
+cd ..
+
+mvn clean compile -Dmaven.test.skip=true -U
+echo ""
+echo "[信息] 依赖下载完成,下面开始初始化数据库。"
+echo ""
+echo "请按回车键继续 ... "
+read text
+
+MAVEN_OPTS="$MAVEN_OPTS -Xms512m -Xmx1024m"
+mvn test -Dmaven.test.skip=false -Dtest=com.jeesite.test.InitData
+
+cd bin
+echo "请按回车键完成 ... "
+read text
\ No newline at end of file
diff --git a/web-ai/bin/package.bat b/web-ai/bin/package.bat
new file mode 100644
index 00000000..7613a836
--- /dev/null
+++ b/web-ai/bin/package.bat
@@ -0,0 +1,22 @@
+@echo off
+rem /**
+rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+rem * No deletion without permission, or be held responsible to law.
+rem *
+rem * Author: ThinkGem@163.com
+rem */
+echo.
+echo [Ϣ] Weḅwar/jarļ
+echo.
+
+%~d0
+cd %~dp0
+
+call mvn -v
+echo.
+
+cd ..
+call mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
+
+cd bin
+pause
\ No newline at end of file
diff --git a/web-ai/bin/package.sh b/web-ai/bin/package.sh
new file mode 100644
index 00000000..b066d9f3
--- /dev/null
+++ b/web-ai/bin/package.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+# /**
+# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+# * No deletion without permission, or be held responsible to law.
+# *
+# * Author: ThinkGem@163.com
+# */
+echo ""
+echo "[信息] 打包Web工程,生成war/jar包文件。"
+echo ""
+
+mvn -v
+echo ""
+
+cd ..
+mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
+
+cd bin
\ No newline at end of file
diff --git a/web-ai/bin/run-tomcat.bat b/web-ai/bin/run-tomcat.bat
new file mode 100644
index 00000000..1d090eea
--- /dev/null
+++ b/web-ai/bin/run-tomcat.bat
@@ -0,0 +1,20 @@
+@echo off
+rem /**
+rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+rem * No deletion without permission, or be held responsible to law.
+rem *
+rem * Author: ThinkGem@163.com
+rem */
+echo.
+echo [Ϣ] ʹ Spring Boot Tomcat Web ̡
+echo.
+
+%~d0
+cd %~dp0
+
+cd ..
+title %cd%
+set "MAVEN_OPTS=%MAVEN_OPTS% -Xms512m -Xmx1024m"
+call mvn clean spring-boot:run -Dmaven.test.skip=true
+
+pause
\ No newline at end of file
diff --git a/web-ai/bin/run-tomcat.sh b/web-ai/bin/run-tomcat.sh
new file mode 100644
index 00000000..982b7958
--- /dev/null
+++ b/web-ai/bin/run-tomcat.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+# /**
+# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+# * No deletion without permission, or be held responsible to law.
+# *
+# * Author: ThinkGem@163.com
+# *
+# */
+echo ""
+echo "[信息] 使用 Spring Boot Tomcat 运行 Web 工程。"
+echo ""
+
+cd ..
+MAVEN_OPTS="$MAVEN_OPTS -Xms512m -Xmx1024m"
+mvn clean spring-boot:run -Dmaven.test.skip=true
\ No newline at end of file
diff --git a/web-ai/bin/run-web.bat b/web-ai/bin/run-web.bat
new file mode 100644
index 00000000..e03845ac
--- /dev/null
+++ b/web-ai/bin/run-web.bat
@@ -0,0 +1,31 @@
+@echo off
+rem /**
+rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+rem * No deletion without permission, or be held responsible to law.
+rem *
+rem * Author: ThinkGem@163.com
+rem */
+echo.
+echo [Ϣ] WeḅWeb̡
+echo.
+
+%~d0
+cd %~dp0
+
+rem Weḅʼ
+cd ..
+call mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
+cd target
+rem Weḅ
+
+
+rem web.jar Ϊ jar
+mkdir app
+copy web.war app
+cd app
+jar -xvf web.war
+del web.war
+cd WEB-INF
+call startup.bat
+
+pause
\ No newline at end of file
diff --git a/web-ai/bin/run-web.sh b/web-ai/bin/run-web.sh
new file mode 100644
index 00000000..d570fe4b
--- /dev/null
+++ b/web-ai/bin/run-web.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+# /**
+# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+# * No deletion without permission, or be held responsible to law.
+# *
+# * Author: ThinkGem@163.com
+# *
+# */
+echo ""
+echo "[信息] 打包Web工程,并运行Web工程。"
+echo ""
+
+# 打包Web工程(开始)
+cd ..
+mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
+cd target
+# 打包Web工程(结束)
+
+
+# 根据情况修改 web.jar 为您的 jar 包名称
+mkdir app
+cp web.war ./app
+cd app
+jar -xvf web.war
+rm web.war
+cd WEB-INF
+sh ./startup.sh
\ No newline at end of file
diff --git a/web-ai/pom.xml b/web-ai/pom.xml
new file mode 100644
index 00000000..4569e154
--- /dev/null
+++ b/web-ai/pom.xml
@@ -0,0 +1,139 @@
+
+
+ 4.0.0
+
+
+ com.jeesite
+ jeesite-parent
+ 5.11.1.springboot3-SNAPSHOT
+ ../parent/pom.xml
+
+
+ jeesite-web-ai
+ war
+
+ Web AI 服务,也可为分离端提供接口服务
+
+ JeeSite Web AI
+ http://jeesite.com
+ 2013-Now
+
+
+
+ web
+ com.jeesite.modules.AiApplication
+
+
+ 8980:8980
+
+
+
+
+
+
+
+ com.jeesite
+ jeesite-module-core
+ ${project.parent.version}
+
+
+
+
+ com.jeesite
+ jeesite-module-cms
+ ${project.parent.version}
+
+
+
+
+ com.jeesite
+ jeesite-module-cms-ai
+ ${project.parent.version}
+
+
+
+
+ com.jeesite
+ jeesite-vue-dist
+ 5.11.1-SNAPSHOT
+
+
+
+
+
+ ${finalName}
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+ ${finalName}
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-eclipse-plugin
+
+ ${finalName}
+
+
+
+
+
+
+
+
+ thinkgem
+ WangZhen
+ thinkgem at 163.com
+ Project lead
+ +8
+
+
+
+
+ JeeSite
+ http://jeesite.com
+
+
+
+
+ aliyun-repos
+ https://maven.aliyun.com/repository/public
+ true
+ false
+
+
+ jeesite-repos
+ https://maven.jeesite.net/repository/maven-public
+
+
+
+
+ aliyun-repos
+ https://maven.aliyun.com/repository/public
+ true
+ false
+
+
+ jeesite-repos
+ https://maven.jeesite.net/repository/maven-public
+
+
+
+
diff --git a/web-ai/src/main/java/com/jeesite/modules/AiApplication.java b/web-ai/src/main/java/com/jeesite/modules/AiApplication.java
new file mode 100644
index 00000000..bda551a5
--- /dev/null
+++ b/web-ai/src/main/java/com/jeesite/modules/AiApplication.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+ * No deletion without permission, or be held responsible to law.
+ */
+package com.jeesite.modules;
+
+import com.jeesite.common.config.Global;
+import com.jeesite.common.io.FileUtils;
+import com.jeesite.common.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+/**
+ * Application
+ * @author ThinkGem
+ */
+@SpringBootApplication
+public class AiApplication extends SpringBootServletInitializer {
+
+ private static final Logger logger = LoggerFactory.getLogger(AiApplication.class);
+
+ public static void main(String[] args) {
+ SpringApplication.run(AiApplication.class, args);
+ String vuePath = Global.getProperty("vuePath");
+ String ctxPath = Global.getProperty("server.servlet.context-path");
+ if (StringUtils.isNoneBlank(vuePath) && !StringUtils.equals(ctxPath, "/js")) {
+ logger.info(
+ "\r\n\r\n==============================================================\r\n"
+ + "\r\n 提示:您修改了 server.servlet.context-path 参数,需要您"
+ + "\r\n 同步修改 _app.config.js 中的 VITE_GLOB_API_URL_PREFIX 参数 "
+ + "\r\n 请修改为 VITE_GLOB_API_URL_PREFIX=\"" + ctxPath + "\""
+ + "\r\n\r\n==============================================================\r\n");
+ }
+ logger.info(
+ "\r\n\r\n==============================================================\r\n"
+ + "\r\n 启动完成,访问地址:http://127.0.0.1:"
+ + Global.getProperty("server.port") + FileUtils.path("/"
+ + Global.getProperty("server.servlet.context-path"))
+ + "\r\n\r\n 默认管理账号: system 密码: admin"
+ + "\r\n\r\n==============================================================\r\n");
+ }
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
+ this.setRegisterErrorPageFilter(false); // 错误页面有容器来处理,而不是SpringBoot
+ return builder.sources(AiApplication.class);
+ }
+
+}
\ No newline at end of file
diff --git a/web-ai/src/main/resources/config/application-prod.yml b/web-ai/src/main/resources/config/application-prod.yml
new file mode 100644
index 00000000..39514c4c
--- /dev/null
+++ b/web-ai/src/main/resources/config/application-prod.yml
@@ -0,0 +1,41 @@
+
+# 使用环境配置,只需 JVM 参数里加:-Dspring.profiles.active=prod
+
+server:
+
+ port: 8980
+ servlet:
+ context-path: /js
+
+# 数据库连接
+jdbc:
+
+ # Mysql 数据库配置
+ type: mysql
+ driver: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://192.168.56.1:3306/jeesite?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=Asia/Shanghai
+ username: jeesite
+ password: jeesite
+ testSql: SELECT 1
+
+ # 数据库连接池配置
+ pool:
+
+ # 初始化连接数
+ init: 1
+ # 最小连接数
+ minIdle: 3
+ # 最大连接数
+ maxActive: 20
+
+# 日志配置
+logging:
+ config: classpath:config/logback-spring-prod.xml
+
+# MyBatis 相关
+mybatis:
+
+ # Mapper文件刷新线程
+ mapper:
+ refresh:
+ enabled: false
diff --git a/web-ai/src/main/resources/config/application.yml b/web-ai/src/main/resources/config/application.yml
new file mode 100644
index 00000000..8b7f5176
--- /dev/null
+++ b/web-ai/src/main/resources/config/application.yml
@@ -0,0 +1,239 @@
+
+#======================================#
+#========== Project settings ==========#
+#======================================#
+
+# 产品或项目名称、软件开发公司名称
+productName: JeeSite Demo
+companyName: ThinkGem
+
+# 产品版本、版权年份
+productVersion: V5.11
+copyrightYear: 2025
+
+# 是否演示模式
+demoMode: false
+
+# 专为分离端提供接口服务
+apiMode: false
+
+#======================================#
+#========== Server settings ===========#
+#======================================#
+
+server:
+
+ port: 8980
+ servlet:
+ context-path: /js
+ register-default-servlet: false
+# encoding.enabled: true
+ tomcat:
+ uri-encoding: UTF-8
+ # 表单请求数据的最大大小
+ max-http-form-post-size: 20MB
+# # 进程的最大连接数
+# max-connections: 8192
+# # 连接数满后的排队个数
+# accept-count: 100
+# # 线程数最大和最小个数
+# threads:
+# max: 200
+# min-spare: 10
+
+ # 当 Nginx 为 https,tomcat 为 http 时,设置该选项为 true
+ schemeHttps: false
+
+#======================================#
+#========== Database sttings ==========#
+#======================================#
+
+# 数据库连接
+jdbc:
+
+ # Mysql 数据库配置
+ type: mysql
+ driver: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://127.0.0.1:3306/jeesite_v5?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
+ username: root
+ password: 123456
+ testSql: SELECT 1
+
+ # 连接信息加密
+ encrypt:
+
+ # 加密连接用户名
+ username: false
+ # 加密连接密码
+ password: false
+
+ # 数据库连接池配置
+ pool:
+
+ # 初始化连接数
+ init: 1
+ # 最小空闲连接数
+ minIdle: 3
+ # 最大激活连接数
+ maxActive: 20
+
+#======================================#
+#========== Spring settings ===========#
+#======================================#
+
+spring:
+
+ # 应用程序名称
+ application:
+ name: jeesite-web-ai
+
+ # 环境名称(注意:不可设置为 test 它是单元测试专用的名称)
+ profiles:
+ active: default
+
+ # 打印横幅
+ main:
+ bannerMode: "off"
+
+ # MVC 映射匹配策略
+ mvc:
+ pathmatch:
+ matching-strategy: ANT_PATH_MATCHER
+
+# 日志配置(fatal、error、warn、info、debug)
+logging:
+ config: classpath:config/logback-spring.xml
+# level:
+# root: warn
+# com.jeesite: debug
+
+# MyBatis 相关
+mybatis:
+
+ # Mapper文件刷新线程
+ mapper:
+ refresh:
+ enabled: true
+
+#======================================#
+#========== System settings ===========#
+#======================================#
+
+# 管理基础路径
+adminPath: /a
+
+# 前端基础路径
+frontPath: /f
+
+# Vue 资源文件路径,与 VITE_PUBLIC_PATH 一致。
+# 映射到 src/main/resources/{vuePath} 文件夹
+vuePath: /vue
+
+# 用户相关
+user:
+
+ # 多租户模式(SAAS模式)(专业版)
+ useCorpModel: false
+
+# 国际化管理(专业版)
+lang:
+ enabled: true
+
+# 任务调度(标准版)
+job:
+ enabled: true
+
+# 代码生成
+gen:
+ enabled: true
+
+# 系统监控
+state:
+ enabled: true
+
+#======================================#
+#========= Framework settings =========#
+#======================================#
+
+# Shiro 相关
+shiro:
+
+ # defaultPath: ${shiro.loginUrl}
+ defaultPath: ${vuePath}/login
+
+ # 登录相关设置
+ loginUrl: ${adminPath}/login
+ logoutUrl: ${shiro.loginUrl}
+ successUrl: ${adminPath}/index
+
+ # 简单 SSO 登录相关配置
+ sso:
+ # 如果启用/sso/{username}/{token}单点登录,请修改此安全key并与单点登录系统key一致。
+ secretKey: ~
+ # 是否加密单点登录安全Key
+ encryptKey: true
+ # token 时效性,如:1天:yyyyMMdd、1小时:yyyyMMddHH、1分钟:yyyyMMddHHmm
+ encryptKeyDateFormat: yyyyMMdd
+
+ # 登录提交信息加密(如果不需要加密,设置为空即可)
+ loginSubmit:
+ # 加密用户名、密码、验证码,后再提交(key设置为3个,用逗号分隔)加密方式:DES(4.1.9及之前版本默认设置)
+ # v4.2.0+ 开始支持 Base64 加密方式,方便移动端及第三方系统处理认证,可直接设置 Key 为 Base64(4.2.0+默认设置)
+ #secretKey: thinkgem,jeesite,com
+ secretKey: Base64
+ #secretKey: ~
+
+ # 记住我密钥设置,你可以通过 com.jeesite.test.RememberMeKeyGen 类快速生成一个秘钥。
+ # 若不设置,则每次启动系统后自动生成一个新秘钥,这样会导致每次重启后,客户端记录的用户信息将失效。
+ rememberMe:
+ secretKey: ~
+
+ # 是否允许跨域访问 CORS,如果允许,设置允许的域名。v4.2.3 开始支持多个域名和模糊匹配,例如:http://*.jeesite.com,http://*.jeesite.net
+ accessControlAllowOrigin: '*'
+
+ # 允许跨域访问时 CORS,可以获取和返回的方法和请求头
+ accessControlAllowMethods: GET, POST, OPTIONS
+ accessControlAllowHeaders: content-type, x-requested-with, x-ajax, x-token, x-remember
+ accessControlExposeHeaders: x-token, x-remember
+
+# Session 相关
+session:
+ # 会话唯一标识SessionId在Cookie中的名称。
+ sessionIdCookieName: ai.jeesite.session.id
+ sessionIdCookiePath: ${server.servlet.context-path}
+
+# Web 相关
+web:
+
+ # 核心模块的Web功能开启(其它微服务时设为false)
+ core:
+ enabled: true
+
+ # 在线API文档工具
+ swagger:
+ enabled: true
+
+# 错误页面500.html是否输出错误信息(正式环境,为提供安全性可设置为false)
+error:
+ page:
+ printErrorInfo: true
+
+#======================================#
+#======== FileUpload settings =========#
+#======================================#
+
+# 文件上传
+file:
+ enabled: true
+
+#======================================#
+#========== Message settings ==========#
+#======================================#
+
+# 消息提醒中心(专业版)
+msg:
+ enabled: true
+
+#======================================#
+#========== Project settings ==========#
+#======================================#
diff --git a/web-ai/src/main/resources/config/beetl.properties b/web-ai/src/main/resources/config/beetl.properties
new file mode 100644
index 00000000..5a9fef83
--- /dev/null
+++ b/web-ai/src/main/resources/config/beetl.properties
@@ -0,0 +1,21 @@
+
+#设置与beetl-default.properties相同的属性将被覆盖默认设置
+
+##导入项目中的调用静态方法类(项目中设置,自动合并IMPORT_PACKAGE设置)
+#IMPORT_PACKAGE_PROJECT=\
+# com.jeesite.modules.project.utils.;\
+
+## 内置的方法
+#FN.date = org.beetl.ext.fn.DateFunction
+
+##内置的功能包
+#FNP.strutil = org.beetl.ext.fn.StringUtil
+
+##内置的格式化函数
+#FT.dateFormat = org.beetl.ext.format.DateFormat
+
+##内置的默认格式化函数
+#FTC.java.util.Date = org.beetl.ext.format.DateFormat
+
+## 标签类
+#TAG.include= org.beetl.ext.tag.IncludeTag
diff --git a/web-ai/src/main/resources/config/logback-spring-prod.xml b/web-ai/src/main/resources/config/logback-spring-prod.xml
new file mode 100644
index 00000000..5a16c941
--- /dev/null
+++ b/web-ai/src/main/resources/config/logback-spring-prod.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %d{MM-dd HH:mm:ss.SSS} %clr(%-5p) %clr([%-39logger{39}]){cyan} - %m%n%wEx
+
+
+
+
+
+ ${log.path}/debug.log
+
+ ${log.path}/debug.%d{yyyy-MM-dd}.%i.log.zip
+ 50MB
+ 30
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} %-5p ${PID:- } [%15.15t] [%-39logger{39}] [%X{TRACE_ID}] - %m%n%wEx
+
+
+
+
+
+
+ ${log.path}/error.log
+
+ ${log.path}/error.%d{yyyy-MM-dd}.%i.log.zip
+ 50MB
+ 30
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} %-5p ${PID:- } [%15.15t] [%-39logger{39}] [%X{TRACE_ID}] - %m%n%wEx
+
+
+ ERROR
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web-ai/src/main/resources/config/logback-spring.xml b/web-ai/src/main/resources/config/logback-spring.xml
new file mode 100644
index 00000000..9bc86e57
--- /dev/null
+++ b/web-ai/src/main/resources/config/logback-spring.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %d{MM-dd HH:mm:ss.SSS} %clr(%-5p) %clr([%-39logger{39}]){cyan} - %m%n%wEx
+
+
+
+
+
+ ${log.path}/debug.log
+
+ ${log.path}/debug.%d{yyyy-MM-dd}.%i.log.zip
+ 50MB
+ 30
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} %-5p ${PID:- } [%15.15t] [%-39logger{39}] [%X{TRACE_ID}] - %m%n%wEx
+
+
+
+
+
+
+ ${log.path}/error.log
+
+ ${log.path}/error.%d{yyyy-MM-dd}.%i.log.zip
+ 50MB
+ 30
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} %-5p ${PID:- } [%15.15t] [%-39logger{39}] [%X{TRACE_ID}] - %m%n%wEx
+
+
+ ERROR
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web-ai/src/main/resources/config/ueditor.json b/web-ai/src/main/resources/config/ueditor.json
new file mode 100644
index 00000000..9ba6e287
--- /dev/null
+++ b/web-ai/src/main/resources/config/ueditor.json
@@ -0,0 +1,94 @@
+/* 前后端通信相关的配置,注释只允许使用多行方式,此文件修改及生效,不用重启服务 */
+{
+ /* 上传图片配置项 */
+ "imageActionName": "uploadimage", /* 执行上传图片的action名称 */
+ "imageFieldName": "upfile", /* 提交的图片表单名称 */
+ "imageMaxSize": 2048000, /* 上传大小限制,单位B */
+ "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
+ "imageCompressEnable": true, /* 是否压缩图片,默认是true */
+ "imageCompressBorder": 800, /* 图片压缩最大宽度限制 */
+ "imageInsertAlign": "none", /* 插入的图片浮动方式 */
+ "imageUrlPrefix": "", /* 图片访问路径前缀 */
+ "imagePathFormat": "/userfiles/editor/{userid}/images/{yyyy}{mm}{dd}/{filename}_${time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
+ /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
+ /* {time} 会替换成时间戳 */
+ /* {yyyy} 会替换成四位年份 */
+ /* {yy} 会替换成两位年份 */
+ /* {mm} 会替换成两位月份 */
+ /* {dd} 会替换成两位日期 */
+ /* {hh} 会替换成两位小时 */
+ /* {ii} 会替换成两位分钟 */
+ /* {ss} 会替换成两位秒 */
+ /* 非法字符 \ : * ? " < > | */
+ /* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */
+
+ /* 涂鸦图片上传配置项 */
+ "scrawlActionName": "uploadscrawl", /* 执行上传涂鸦的action名称 */
+ "scrawlFieldName": "upfile", /* 提交的图片表单名称 */
+ "scrawlPathFormat": "/userfiles/editor/{userid}/images/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ "scrawlMaxSize": 2048000, /* 上传大小限制,单位B */
+ "scrawlUrlPrefix": "", /* 图片访问路径前缀 */
+ "scrawlInsertAlign": "none",
+
+ /* 截图工具上传 */
+ "snapscreenActionName": "uploadimage", /* 执行上传截图的action名称 */
+ "snapscreenPathFormat": "/userfiles/editor/{userid}/images/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ "snapscreenUrlPrefix": "", /* 图片访问路径前缀 */
+ "snapscreenInsertAlign": "none", /* 插入的图片浮动方式 */
+
+ /* 抓取远程图片配置 */
+ "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
+ "catcherActionName": "catchimage", /* 执行抓取远程图片的action名称 */
+ "catcherFieldName": "source", /* 提交的图片列表表单名称 */
+ "catcherPathFormat": "/userfiles/editor/{userid}/images/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ "catcherUrlPrefix": "", /* 图片访问路径前缀 */
+ "catcherMaxSize": 2048000, /* 上传大小限制,单位B */
+ "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */
+
+ /* 上传视频配置 */
+ "videoActionName": "uploadvideo", /* 执行上传视频的action名称 */
+ "videoFieldName": "upfile", /* 提交的视频表单名称 */
+ "videoPathFormat": "/userfiles/editor/{userid}/videos/{yyyy}{mm}{dd}/{filename}_${time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ "videoUrlPrefix": "", /* 视频访问路径前缀 */
+ "videoMaxSize": 102400000, /* 上传大小限制,单位B,默认100MB */
+ "videoAllowFiles": [
+ ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
+ ".ogg", ".ogv", ".mov", ".wmv", ".mp4",".m4v", ".webm", ".mp3", ".wav", ".mid"], /* 上传视频格式显示 */
+
+ /* 上传文件配置 */
+ "fileActionName": "uploadfile", /* controller里,执行上传视频的action名称 */
+ "fileFieldName": "upfile", /* 提交的文件表单名称 */
+ "filePathFormat": "/userfiles/editor/{userid}/files/{yyyy}{mm}{dd}/{filename}_${time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ "fileUrlPrefix": "", /* 文件访问路径前缀 */
+ "fileMaxSize": 51200000, /* 上传大小限制,单位B,默认50MB */
+ "fileAllowFiles": [
+ ".png", ".jpg", ".jpeg", ".gif", ".bmp",
+ ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
+ ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
+ ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso", ".ipa", ".apk",
+ ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
+ ], /* 上传文件格式显示 */
+
+ /* 列出指定目录下的图片 */
+ "imageManagerActionName": "listimage", /* 执行图片管理的action名称 */
+ "imageManagerListPath": "/userfiles/editor/{userid}/images/", /* 指定要列出图片的目录 */
+ "imageManagerListSize": 100, /* 每次列出文件数量 */
+ "imageManagerUrlPrefix": "", /* 图片访问路径前缀 */
+ "imageManagerInsertAlign": "none", /* 插入的图片浮动方式 */
+ "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件类型 */
+
+ /* 列出指定目录下的文件 */
+ "fileManagerActionName": "listfile", /* 执行文件管理的action名称 */
+ "fileManagerListPath": "/userfiles/editor/{userid}/files/", /* 指定要列出文件的目录 */
+ "fileManagerListSize": 100, /* 每次列出文件数量 */
+ "fileManagerUrlPrefix": "", /* 文件访问路径前缀 */
+ "fileManagerAllowFiles": [
+ ".png", ".jpg", ".jpeg", ".gif", ".bmp",
+ ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
+ ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
+ ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
+ ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
+ ] /* 列出的文件类型 */
+
+}
\ No newline at end of file
diff --git a/web-ai/src/main/resources/static/common/common.css b/web-ai/src/main/resources/static/common/common.css
new file mode 100644
index 00000000..f94b7e40
--- /dev/null
+++ b/web-ai/src/main/resources/static/common/common.css
@@ -0,0 +1,5 @@
+/*!
+ * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+ * No deletion without permission, or be held responsible to law.
+ * 项目自定义的公共CSS,可覆盖jeesite.css里的样式
+ */
diff --git a/web-ai/src/main/resources/static/common/common.js b/web-ai/src/main/resources/static/common/common.js
new file mode 100644
index 00000000..14bccc01
--- /dev/null
+++ b/web-ai/src/main/resources/static/common/common.js
@@ -0,0 +1,5 @@
+/*!
+ * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+ * No deletion without permission, or be held responsible to law.
+ * 项目自定义的公共JavaScript,可覆盖jeesite.js里的方法
+ */
diff --git a/web-ai/src/main/resources/static/favicon.png b/web-ai/src/main/resources/static/favicon.png
new file mode 100644
index 00000000..72734e51
Binary files /dev/null and b/web-ai/src/main/resources/static/favicon.png differ
diff --git a/web-ai/src/main/resources/vue/_app.config.js b/web-ai/src/main/resources/vue/_app.config.js
new file mode 100644
index 00000000..1c8d6286
--- /dev/null
+++ b/web-ai/src/main/resources/vue/_app.config.js
@@ -0,0 +1,2 @@
+window.__PRODUCTION__JEESITE__CONF__={"VITE_GLOB_APP_TITLE":"JeeSite 快速开发平台","VITE_GLOB_APP_SHORT_NAME":"jeesite","VITE_GLOB_API_URL":"",
+ "VITE_GLOB_API_URL_PREFIX":"/js","VITE_GLOB_ADMIN_PATH":"/a","VITE_FILE_PREVIEW":"true"};Object.freeze(window.__PRODUCTION__JEESITE__CONF__);Object.defineProperty(window,"__PRODUCTION__JEESITE__CONF__",{configurable:false,writable:false,});var _hmt =_hmt ||[];(function(){var hm =document.createElement("script");hm.src ="https://hm.baidu.com/hm.js?65b88e88a94e0118de2962f328f17622";var s =document.getElementsByTagName("script")[0];s.parentNode.insertBefore(hm,s);})();
\ No newline at end of file
diff --git a/web-ai/src/main/webapp/WEB-INF/startup.bat b/web-ai/src/main/webapp/WEB-INF/startup.bat
new file mode 100644
index 00000000..fd6ced8b
--- /dev/null
+++ b/web-ai/src/main/webapp/WEB-INF/startup.bat
@@ -0,0 +1,51 @@
+@echo off
+rem /**
+rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+rem * No deletion without permission, or be held responsible to law.
+rem *
+rem * Author: ThinkGem@163.com
+rem */
+echo.
+echo [Ϣ] Web̡
+echo.
+rem pause
+rem echo.
+
+%~d0
+cd %~dp0
+
+title %cd%
+
+rem JDKĿ¼
+rem set "JAVA_HOME=%cd%\jdk1.8.0_x64"
+
+rem ·
+set "CLASS_PATH=%cd%/../"
+
+rem ŻJVM
+set "JAVA_OPTS=%JAVA_OPTS% -Xms512m -Xmx1024m"
+
+rem ʽһⲿԶļ飩
+rem set "JAVA_OPTS=%JAVA_OPTS% -Dspring.config.location=%cd%\app.yml"
+
+rem ʽûƣزͬļ
+rem set "JAVA_OPTS=%JAVA_OPTS% -Dspring.profiles.active=prod"
+
+if "%JAVA_HOME%" == "" goto noJavaHome
+if not "%JAVA_HOME%" == "" goto gotJavaHome
+goto end
+
+:noJavaHome
+set RUN_JAVA=java
+goto runJava
+
+:gotJavaHome
+set "RUN_JAVA=%JAVA_HOME%\bin\java"
+goto runJava
+
+:runJava
+call "%RUN_JAVA%" -cp %CLASS_PATH% %JAVA_OPTS% org.springframework.boot.loader.launch.WarLauncher
+goto end
+
+:end
+pause
diff --git a/web-ai/src/main/webapp/WEB-INF/startup.sh b/web-ai/src/main/webapp/WEB-INF/startup.sh
new file mode 100644
index 00000000..b30ebb23
--- /dev/null
+++ b/web-ai/src/main/webapp/WEB-INF/startup.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+# /**
+# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+# * No deletion without permission, or be held responsible to law.
+# *
+# * Author: ThinkGem@163.com
+# */
+echo ""
+echo "[信息] 运行Web工程。"
+echo ""
+
+cd "$(cd "$(dirname "$0")"; pwd)"
+
+# 设置JDK目录
+# JAVA_HOME="$PWD/jdk1.8.0_x64"
+
+# 设置类加载路径
+CLASS_PATH="$PWD/../"
+
+# 优化JVM参数
+# JAVA_OPTS="$JAVA_OPTS -Xms512m -Xmx1024m"
+
+# 方式一、配置外部自定义的属性文件(建议)
+# JAVA_OPTS="$JAVA_OPTS -Dspring.config.location=$PWD/app.yml"
+
+# 方式二、配置环境名称,加载不同的属性文件
+# JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=prod"
+
+if [ -z "$JAVA_HOME" ]; then
+ RUN_JAVA=java
+else
+ RUN_JAVA="$JAVA_HOME"/bin/java
+fi
+
+exec "$RUN_JAVA" -cp $CLASS_PATH $JAVA_OPTS org.springframework.boot.loader.launch.WarLauncher
\ No newline at end of file
diff --git a/web-ai/src/test/java/com/jeesite/test/InitData.java b/web-ai/src/test/java/com/jeesite/test/InitData.java
new file mode 100644
index 00000000..fd4999a5
--- /dev/null
+++ b/web-ai/src/test/java/com/jeesite/test/InitData.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+ * No deletion without permission, or be held responsible to law.
+ */
+package com.jeesite.test;
+
+import org.junit.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+
+import com.jeesite.common.tests.BaseInitDataTests;
+import com.jeesite.modules.AiApplication;
+
+/**
+ * 初始化数据表
+ * @author ThinkGem
+ */
+@ActiveProfiles("test")
+@SpringBootTest(classes = AiApplication.class)
+public class InitData extends BaseInitDataTests {
+
+ @Test
+ public void initData01() throws Exception{
+ logger.info("数据库初始化完成。");
+ }
+
+ @Override
+ public void initProperty() {
+ System.setProperty("jeesite.initdata", "true");
+ }
+
+}
diff --git a/web-ai/src/test/java/com/jeesite/test/RememberMeKeyGen.java b/web-ai/src/test/java/com/jeesite/test/RememberMeKeyGen.java
new file mode 100644
index 00000000..b8733002
--- /dev/null
+++ b/web-ai/src/test/java/com/jeesite/test/RememberMeKeyGen.java
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+ * No deletion without permission, or be held responsible to law.
+ */
+package com.jeesite.test;
+
+import org.apache.shiro.crypto.cipher.AesCipherService;
+import org.apache.shiro.lang.codec.Base64;
+
+/**
+ * v4.1.8 开始将不为记住我功能,设置默认密钥,即启动系统时生成新密钥。
+ * 这样会造成一个问题,比如:重启服务后,记住登录的用户因为解密失败,而需要重新登录。
+ * 为了解决这个问题,您可以通过这个类获取一个新密钥,设置到 shiro.rememberMe.secretKey 中即可。
+ * 另外,如果你从配置文件里将 shiro.rememberMe.secretKey 设置为空,启动系统时也会自动设置一个新的密钥。
+ * @author ThinkGem
+ * @version 2019年11月6日
+ */
+public class RememberMeKeyGen {
+
+ public static void main(String[] args) {
+ byte[] cipherKey = new AesCipherService().generateNewKey().getEncoded();
+ String secretKey = Base64.encodeToString(cipherKey);
+ System.out.println("shiro.rememberMe.secretKey = " + secretKey);
+ }
+
+}
diff --git a/web-ai/src/test/java/logback-test.xml b/web-ai/src/test/java/logback-test.xml
new file mode 100644
index 00000000..a9a15b7f
--- /dev/null
+++ b/web-ai/src/test/java/logback-test.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+ %d{HH:mm:ss.SSS} %clr(%-5p) %clr([%-39logger{39}]){cyan} - %m%n%wEx
+
+
+
+
+
+
+
+
+
\ No newline at end of file