部署脚本
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -74,6 +74,7 @@ db_config.conf
|
|||||||
|
|
||||||
# Local deployment bundles
|
# Local deployment bundles
|
||||||
.deploy/
|
.deploy/
|
||||||
|
/ccdi_????????.zip
|
||||||
|
|
||||||
output/
|
output/
|
||||||
|
|
||||||
@@ -93,4 +94,4 @@ tongweb_62318.properties
|
|||||||
|
|
||||||
.superpowers/
|
.superpowers/
|
||||||
|
|
||||||
tmp/
|
tmp/
|
||||||
|
|||||||
92
build_release_ccdi.sh
Executable file
92
build_release_ccdi.sh
Executable file
@@ -0,0 +1,92 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
ROOT_DIR=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
|
||||||
|
DATE_STAMP=$(date "+%Y%m%d")
|
||||||
|
RELEASE_ZIP="$ROOT_DIR/ccdi_${DATE_STAMP}.zip"
|
||||||
|
STAGE_DIR="$ROOT_DIR/.deploy/ccdi-release-package"
|
||||||
|
WORK_DIR="$STAGE_DIR/files"
|
||||||
|
BACKEND_JAR_SOURCE="$ROOT_DIR/ruoyi-admin/target/ruoyi-admin.jar"
|
||||||
|
FRONTEND_DIR="$ROOT_DIR/ruoyi-ui"
|
||||||
|
FRONTEND_DIST_DIR="$FRONTEND_DIR/dist"
|
||||||
|
FRONTEND_DIST_ZIP="$WORK_DIR/dist.zip"
|
||||||
|
|
||||||
|
log_info() {
|
||||||
|
printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error() {
|
||||||
|
printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$1" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
require_command() {
|
||||||
|
if ! command -v "$1" >/dev/null 2>&1; then
|
||||||
|
log_error "缺少命令: $1"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
reset_stage_dir() {
|
||||||
|
rm -rf "$STAGE_DIR"
|
||||||
|
mkdir -p "$WORK_DIR"
|
||||||
|
}
|
||||||
|
|
||||||
|
build_backend() {
|
||||||
|
log_info "开始构建后端生产 jar"
|
||||||
|
(
|
||||||
|
cd "$ROOT_DIR"
|
||||||
|
mvn -pl ruoyi-admin -am clean package -DskipTests
|
||||||
|
)
|
||||||
|
|
||||||
|
if [ ! -f "$BACKEND_JAR_SOURCE" ]; then
|
||||||
|
log_error "未生成后端 jar: $BACKEND_JAR_SOURCE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
build_frontend() {
|
||||||
|
log_info "开始构建前端生产 dist"
|
||||||
|
FRONTEND_DIR="$FRONTEND_DIR" zsh -lic 'cd "$FRONTEND_DIR" && nvm use >/dev/null && npm run build:prod'
|
||||||
|
|
||||||
|
if [ ! -f "$FRONTEND_DIST_DIR/index.html" ]; then
|
||||||
|
log_error "前端生产构建失败,未找到: $FRONTEND_DIST_DIR/index.html"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
(
|
||||||
|
cd "$FRONTEND_DIR"
|
||||||
|
zip -qr "$FRONTEND_DIST_ZIP" dist
|
||||||
|
)
|
||||||
|
|
||||||
|
if [ ! -f "$FRONTEND_DIST_ZIP" ]; then
|
||||||
|
log_error "未生成前端压缩包: $FRONTEND_DIST_ZIP"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
package_release() {
|
||||||
|
cp "$BACKEND_JAR_SOURCE" "$WORK_DIR/ruoyi-admin.jar"
|
||||||
|
|
||||||
|
rm -f "$RELEASE_ZIP"
|
||||||
|
(
|
||||||
|
cd "$WORK_DIR"
|
||||||
|
zip -qr "$RELEASE_ZIP" ruoyi-admin.jar dist.zip
|
||||||
|
)
|
||||||
|
|
||||||
|
log_info "上线压缩包已生成: $RELEASE_ZIP"
|
||||||
|
log_info "压缩包根层内容: ruoyi-admin.jar, dist.zip"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
require_command mvn
|
||||||
|
require_command zsh
|
||||||
|
require_command zip
|
||||||
|
|
||||||
|
reset_stage_dir
|
||||||
|
build_backend
|
||||||
|
build_frontend
|
||||||
|
package_release
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
212
deploy/deploy-release-prod.sh
Executable file
212
deploy/deploy-release-prod.sh
Executable file
@@ -0,0 +1,212 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
|
||||||
|
BACKEND_DIR="${SCRIPT_DIR}/backend"
|
||||||
|
FRONTEND_DIR="${SCRIPT_DIR}/frontend"
|
||||||
|
START_SCRIPT="${SCRIPT_DIR}/start-java-backend-prod.sh"
|
||||||
|
BACKUP_ROOT="${SCRIPT_DIR}/backups"
|
||||||
|
WORK_ROOT="${SCRIPT_DIR}/.deploy-work"
|
||||||
|
TIMESTAMP=$(date '+%Y%m%d%H%M%S')
|
||||||
|
BACKUP_DIR="${BACKUP_ROOT}/${TIMESTAMP}"
|
||||||
|
WORK_DIR="${WORK_ROOT}/release-${TIMESTAMP}"
|
||||||
|
RELEASE_ZIP="${1:-}"
|
||||||
|
|
||||||
|
RELEASE_JAR=""
|
||||||
|
RELEASE_DIST_ZIP=""
|
||||||
|
FRONTEND_SOURCE_DIR=""
|
||||||
|
|
||||||
|
timestamp() {
|
||||||
|
date '+%Y-%m-%d %H:%M:%S'
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info() {
|
||||||
|
printf '[%s] %s\n' "$(timestamp)" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error() {
|
||||||
|
printf '[%s] %s\n' "$(timestamp)" "$1" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: ./deploy-release-prod.sh [上线压缩包路径]
|
||||||
|
|
||||||
|
目录要求:
|
||||||
|
deploy-release-prod.sh
|
||||||
|
start-java-backend-prod.sh
|
||||||
|
backend/
|
||||||
|
frontend/
|
||||||
|
ccdi_YYYYMMDD.zip
|
||||||
|
|
||||||
|
说明:
|
||||||
|
未传上线压缩包路径时,脚本会自动使用当前脚本目录下唯一的 .zip 文件。
|
||||||
|
上线压缩包根层必须包含 ruoyi-admin.jar 和 dist.zip。
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
require_command() {
|
||||||
|
if ! command -v "$1" >/dev/null 2>&1; then
|
||||||
|
log_error "缺少命令: $1"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_path() {
|
||||||
|
input_path="$1"
|
||||||
|
|
||||||
|
case "${input_path}" in
|
||||||
|
/*)
|
||||||
|
printf '%s\n' "${input_path}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
input_dir=$(dirname "${input_path}")
|
||||||
|
input_base=$(basename "${input_path}")
|
||||||
|
printf '%s/%s\n' "$(CDPATH= cd -- "${input_dir}" && pwd)" "${input_base}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_release_zip() {
|
||||||
|
if [ -n "${RELEASE_ZIP}" ]; then
|
||||||
|
RELEASE_ZIP=$(resolve_path "${RELEASE_ZIP}")
|
||||||
|
else
|
||||||
|
mkdir -p "${WORK_ROOT}"
|
||||||
|
candidate_file="${WORK_ROOT}/zip-candidates-${TIMESTAMP}.txt"
|
||||||
|
find "${SCRIPT_DIR}" -maxdepth 1 -type f -name '*.zip' ! -name 'dist.zip' | sort > "${candidate_file}"
|
||||||
|
candidate_count=$(wc -l < "${candidate_file}" | tr -d ' ')
|
||||||
|
|
||||||
|
if [ "${candidate_count}" -eq 0 ]; then
|
||||||
|
log_error "未在脚本目录找到上线压缩包,请传入压缩包路径"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${candidate_count}" -gt 1 ]; then
|
||||||
|
log_error "脚本目录存在多个上线压缩包,请显式传入压缩包路径"
|
||||||
|
cat "${candidate_file}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
RELEASE_ZIP=$(sed -n '1p' "${candidate_file}")
|
||||||
|
rm -f "${candidate_file}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "${RELEASE_ZIP}" ]; then
|
||||||
|
log_error "上线压缩包不存在: ${RELEASE_ZIP}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_layout() {
|
||||||
|
if [ ! -d "${BACKEND_DIR}" ]; then
|
||||||
|
log_error "未找到后端目录: ${BACKEND_DIR}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "${FRONTEND_DIR}" ]; then
|
||||||
|
log_error "未找到前端目录: ${FRONTEND_DIR}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "${START_SCRIPT}" ]; then
|
||||||
|
log_error "未找到后端启动脚本: ${START_SCRIPT}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_dir() {
|
||||||
|
source_dir="$1"
|
||||||
|
target_dir="$2"
|
||||||
|
|
||||||
|
mkdir -p "${target_dir}"
|
||||||
|
if [ -n "$(find "${source_dir}" -mindepth 1 -maxdepth 1 -print -quit)" ]; then
|
||||||
|
cp -a "${source_dir}/." "${target_dir}/"
|
||||||
|
log_info "已备份 ${source_dir} 到 ${target_dir}"
|
||||||
|
else
|
||||||
|
log_info "目录为空,已创建空备份目录: ${target_dir}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_current_files() {
|
||||||
|
mkdir -p "${BACKUP_DIR}"
|
||||||
|
backup_dir "${BACKEND_DIR}" "${BACKUP_DIR}/backend"
|
||||||
|
backup_dir "${FRONTEND_DIR}" "${BACKUP_DIR}/frontend"
|
||||||
|
}
|
||||||
|
|
||||||
|
extract_release_package() {
|
||||||
|
mkdir -p "${WORK_DIR}/release" "${WORK_DIR}/frontend"
|
||||||
|
log_info "开始解压上线压缩包: ${RELEASE_ZIP}"
|
||||||
|
unzip -q "${RELEASE_ZIP}" -d "${WORK_DIR}/release"
|
||||||
|
|
||||||
|
RELEASE_JAR="${WORK_DIR}/release/ruoyi-admin.jar"
|
||||||
|
RELEASE_DIST_ZIP="${WORK_DIR}/release/dist.zip"
|
||||||
|
if [ ! -f "${RELEASE_JAR}" ]; then
|
||||||
|
log_error "上线压缩包根层缺少 ruoyi-admin.jar"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ ! -f "${RELEASE_DIST_ZIP}" ]; then
|
||||||
|
log_error "上线压缩包根层缺少 dist.zip"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
unzip -q "${RELEASE_DIST_ZIP}" -d "${WORK_DIR}/frontend"
|
||||||
|
FRONTEND_SOURCE_DIR="${WORK_DIR}/frontend/dist"
|
||||||
|
if [ ! -f "${FRONTEND_SOURCE_DIR}/index.html" ]; then
|
||||||
|
log_error "dist.zip 解压后未找到 dist/index.html"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
deploy_backend() {
|
||||||
|
target_jar="${BACKEND_DIR}/ruoyi-admin.jar"
|
||||||
|
deploying_jar="${BACKEND_DIR}/.ruoyi-admin.jar.deploying"
|
||||||
|
|
||||||
|
cp "${RELEASE_JAR}" "${deploying_jar}"
|
||||||
|
mv "${deploying_jar}" "${target_jar}"
|
||||||
|
log_info "后端 Jar 已部署: ${target_jar}"
|
||||||
|
}
|
||||||
|
|
||||||
|
deploy_frontend() {
|
||||||
|
find "${FRONTEND_DIR}" -mindepth 1 -maxdepth 1 -exec rm -rf {} +
|
||||||
|
cp -a "${FRONTEND_SOURCE_DIR}/." "${FRONTEND_DIR}/"
|
||||||
|
log_info "前端文件已部署到: ${FRONTEND_DIR}"
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup_work_dir() {
|
||||||
|
rm -rf "${WORK_DIR}"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
case "${1:-}" in
|
||||||
|
-h|--help|help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ "$#" -gt 1 ]; then
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
require_command "unzip"
|
||||||
|
require_command "find"
|
||||||
|
|
||||||
|
resolve_release_zip
|
||||||
|
assert_layout
|
||||||
|
backup_current_files
|
||||||
|
|
||||||
|
trap cleanup_work_dir 0
|
||||||
|
extract_release_package
|
||||||
|
deploy_backend
|
||||||
|
deploy_frontend
|
||||||
|
cleanup_work_dir
|
||||||
|
trap - 0
|
||||||
|
|
||||||
|
log_info "部署完成,备份目录: ${BACKUP_DIR}"
|
||||||
|
log_info "开始重启后端并输出日志"
|
||||||
|
bash "${START_SCRIPT}" restart
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
310
deploy/start-java-backend-prod.sh
Executable file
310
deploy/start-java-backend-prod.sh
Executable file
@@ -0,0 +1,310 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# ==================== 生产配置区:按服务器实际路径修改 ====================
|
||||||
|
|
||||||
|
# JDK 安装目录。留空时使用服务器已有 JAVA_HOME;仍为空时使用 PATH 中的 java。
|
||||||
|
BACKEND_JAVA_HOME=""
|
||||||
|
|
||||||
|
# 后端 Jar 所在目录。生产目录结构为:启动脚本在外层,Jar 位于 backend/ruoyi-admin.jar。
|
||||||
|
APP_HOME="${SCRIPT_DIR}/backend"
|
||||||
|
|
||||||
|
# 后端 Jar 文件名。
|
||||||
|
JAR_NAME="ruoyi-admin.jar"
|
||||||
|
|
||||||
|
# Spring Profile。
|
||||||
|
SPRING_PROFILES_ACTIVE="uat"
|
||||||
|
|
||||||
|
# JVM 参数。
|
||||||
|
JAVA_OPTS="-Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError"
|
||||||
|
|
||||||
|
# 额外应用启动参数,例如:--server.port=8080
|
||||||
|
APP_ARGS=""
|
||||||
|
|
||||||
|
# 停止进程等待秒数。
|
||||||
|
STOP_WAIT_SECONDS=30
|
||||||
|
|
||||||
|
# ==================== 以下为脚本逻辑,一般不需要修改 ====================
|
||||||
|
|
||||||
|
if [[ "${APP_HOME}" != /* ]]; then
|
||||||
|
APP_HOME="${SCRIPT_DIR}/${APP_HOME}"
|
||||||
|
fi
|
||||||
|
JAR_PATH="${APP_HOME}/${JAR_NAME}"
|
||||||
|
RELATIVE_JAR_PATH=""
|
||||||
|
if [[ "${APP_HOME}" == "${SCRIPT_DIR}/"* ]]; then
|
||||||
|
RELATIVE_JAR_PATH="${APP_HOME#${SCRIPT_DIR}/}/${JAR_NAME}"
|
||||||
|
fi
|
||||||
|
LOG_DIR="${APP_HOME}/logs"
|
||||||
|
CONSOLE_LOG="${LOG_DIR}/backend-console.log"
|
||||||
|
PID_FILE="${LOG_DIR}/backend-java.pid"
|
||||||
|
APP_MARKER="-Dccdi.backend.prod.home=${APP_HOME}"
|
||||||
|
JAVA_CMD="java"
|
||||||
|
|
||||||
|
timestamp() {
|
||||||
|
date "+%Y-%m-%d %H:%M:%S"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info() {
|
||||||
|
printf '[%s] %s\n' "$(timestamp)" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error() {
|
||||||
|
printf '[%s] %s\n' "$(timestamp)" "$1" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: ./start-java-backend-prod.sh [start|stop|restart|status|logs]
|
||||||
|
|
||||||
|
默认动作:
|
||||||
|
start 先关闭旧后端进程,再启动生产后端 Jar,启动成功后持续输出控制台日志
|
||||||
|
|
||||||
|
常用配置:
|
||||||
|
配置统一写在脚本顶部“生产配置区”,包括 BACKEND_JAVA_HOME、APP_HOME、SPRING_PROFILES_ACTIVE、JAVA_OPTS。
|
||||||
|
|
||||||
|
示例:
|
||||||
|
./start-java-backend-prod.sh restart
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_command() {
|
||||||
|
local command_name="$1"
|
||||||
|
if ! command -v "${command_name}" >/dev/null 2>&1; then
|
||||||
|
log_error "缺少命令: ${command_name}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_java_cmd() {
|
||||||
|
local configured_java_home="${BACKEND_JAVA_HOME}"
|
||||||
|
if [[ -z "${configured_java_home}" ]]; then
|
||||||
|
configured_java_home="${JAVA_HOME:-}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "${configured_java_home}" ]]; then
|
||||||
|
configured_java_home="${configured_java_home%/}"
|
||||||
|
if [[ ! -x "${configured_java_home}/bin/java" ]]; then
|
||||||
|
log_error "配置的 JAVA_HOME 无效,未找到可执行文件: ${configured_java_home}/bin/java"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
export JAVA_HOME="${configured_java_home}"
|
||||||
|
JAVA_CMD="${JAVA_HOME}/bin/java"
|
||||||
|
else
|
||||||
|
ensure_command "java"
|
||||||
|
JAVA_CMD="java"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "使用 Java 命令: ${JAVA_CMD}"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_process_table() {
|
||||||
|
local process_table
|
||||||
|
if ! process_table="$(ps -ef 2>/dev/null)"; then
|
||||||
|
log_error "执行 ps -ef 失败,无法扫描旧进程"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s\n' "${process_table}"
|
||||||
|
}
|
||||||
|
|
||||||
|
is_managed_pid() {
|
||||||
|
local pid="$1"
|
||||||
|
if [[ -z "${pid}" ]] || ! kill -0 "${pid}" 2>/dev/null; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local process_table
|
||||||
|
if ! process_table="$(get_process_table)"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local line
|
||||||
|
while IFS= read -r line; do
|
||||||
|
set -- ${line}
|
||||||
|
if [[ "${2:-}" == "${pid}" ]] && is_backend_process_line "${line}"; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done <<<"${process_table}"
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
is_backend_process_line() {
|
||||||
|
local line="$1"
|
||||||
|
[[ "${line}" != *"<defunct>"* ]] || return 1
|
||||||
|
[[ "${line}" == *" -jar ${JAR_PATH}"* ]] && return 0
|
||||||
|
[[ -n "${RELATIVE_JAR_PATH}" && "${line}" == *" -jar ${RELATIVE_JAR_PATH}"* ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
collect_pids() {
|
||||||
|
local all_pids=""
|
||||||
|
local pid
|
||||||
|
local process_table
|
||||||
|
if ! process_table="$(get_process_table)"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "${PID_FILE}" ]]; then
|
||||||
|
pid="$(cat "${PID_FILE}" 2>/dev/null || true)"
|
||||||
|
if is_managed_pid "${pid}"; then
|
||||||
|
all_pids="${all_pids} ${pid}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
local line
|
||||||
|
while IFS= read -r line; do
|
||||||
|
set -- ${line}
|
||||||
|
pid="${2:-}"
|
||||||
|
if [[ "${pid}" =~ ^[0-9]+$ ]] && is_backend_process_line "${line}"; then
|
||||||
|
all_pids="${all_pids} ${pid}"
|
||||||
|
fi
|
||||||
|
done <<<"${process_table}"
|
||||||
|
|
||||||
|
local unique_pids=""
|
||||||
|
for pid in ${all_pids}; do
|
||||||
|
case " ${unique_pids} " in
|
||||||
|
*" ${pid} "*) ;;
|
||||||
|
*) unique_pids="${unique_pids} ${pid}" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
xargs <<<"${unique_pids}" 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
start_backend() {
|
||||||
|
resolve_java_cmd
|
||||||
|
|
||||||
|
if [[ ! -f "${JAR_PATH}" ]]; then
|
||||||
|
log_error "未找到后端 Jar: ${JAR_PATH}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local running_pids
|
||||||
|
running_pids="$(collect_pids)"
|
||||||
|
if [[ -n "${running_pids}" ]]; then
|
||||||
|
log_error "检测到后端已在运行: ${running_pids}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "${LOG_DIR}"
|
||||||
|
printf '\n===== %s start =====\n' "$(timestamp)" >>"${CONSOLE_LOG}"
|
||||||
|
|
||||||
|
local profile_arg=""
|
||||||
|
if [[ -n "${SPRING_PROFILES_ACTIVE}" ]]; then
|
||||||
|
profile_arg="--spring.profiles.active=${SPRING_PROFILES_ACTIVE}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "开始启动后端 Jar: ${JAR_PATH}"
|
||||||
|
nohup "${JAVA_CMD}" "${APP_MARKER}" ${JAVA_OPTS} -jar "${JAR_PATH}" ${profile_arg} ${APP_ARGS} >>"${CONSOLE_LOG}" 2>&1 &
|
||||||
|
echo $! >"${PID_FILE}"
|
||||||
|
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
local starter_pid
|
||||||
|
starter_pid="$(cat "${PID_FILE}" 2>/dev/null || true)"
|
||||||
|
if [[ -z "${starter_pid}" ]] || ! kill -0 "${starter_pid}" 2>/dev/null; then
|
||||||
|
log_error "启动命令未保持运行,请检查日志: ${CONSOLE_LOG}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "后端启动完成,PID: ${starter_pid}"
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_backend() {
|
||||||
|
local pids
|
||||||
|
pids="$(collect_pids)"
|
||||||
|
|
||||||
|
if [[ -z "${pids}" ]]; then
|
||||||
|
log_info "未发现运行中的后端进程"
|
||||||
|
rm -f "${PID_FILE}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "准备停止后端进程: ${pids}"
|
||||||
|
local pid
|
||||||
|
for pid in ${pids}; do
|
||||||
|
kill -TERM "${pid}" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
|
||||||
|
local elapsed=0
|
||||||
|
local remaining_pids="${pids}"
|
||||||
|
while [[ -n "${remaining_pids}" && "${elapsed}" -lt "${STOP_WAIT_SECONDS}" ]]; do
|
||||||
|
sleep 1
|
||||||
|
elapsed=$((elapsed + 1))
|
||||||
|
remaining_pids=""
|
||||||
|
for pid in ${pids}; do
|
||||||
|
if kill -0 "${pid}" 2>/dev/null; then
|
||||||
|
remaining_pids="${remaining_pids} ${pid}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
remaining_pids="$(xargs <<<"${remaining_pids}" 2>/dev/null || true)"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -n "${remaining_pids}" ]]; then
|
||||||
|
log_info "仍有进程未退出,执行强制停止: ${remaining_pids}"
|
||||||
|
for pid in ${remaining_pids}; do
|
||||||
|
kill -KILL "${pid}" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "${PID_FILE}"
|
||||||
|
log_info "后端停止完成"
|
||||||
|
}
|
||||||
|
|
||||||
|
status_backend() {
|
||||||
|
local pids
|
||||||
|
pids="$(collect_pids)"
|
||||||
|
if [[ -n "${pids}" ]]; then
|
||||||
|
log_info "后端正在运行,进程: ${pids}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "后端未运行"
|
||||||
|
}
|
||||||
|
|
||||||
|
follow_logs() {
|
||||||
|
mkdir -p "${LOG_DIR}"
|
||||||
|
touch "${CONSOLE_LOG}"
|
||||||
|
log_info "持续输出日志中,按 Ctrl+C 仅退出日志查看,不会停止后端进程"
|
||||||
|
tail -n 200 -F "${CONSOLE_LOG}"
|
||||||
|
}
|
||||||
|
|
||||||
|
start_action() {
|
||||||
|
stop_backend
|
||||||
|
start_backend
|
||||||
|
follow_logs
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local action="${1:-start}"
|
||||||
|
case "${action}" in
|
||||||
|
start)
|
||||||
|
start_action
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
stop_backend
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
start_action
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
status_backend
|
||||||
|
;;
|
||||||
|
logs)
|
||||||
|
follow_logs
|
||||||
|
;;
|
||||||
|
-h|--help|help)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# nvmrc 配置实施记录
|
||||||
|
|
||||||
|
## 修改内容
|
||||||
|
|
||||||
|
- 在仓库根目录新增 `.nvmrc`,统一指定 Node 版本为 `14.21.3`。
|
||||||
|
- 保留并对齐前端目录 `ruoyi-ui/.nvmrc` 的既有配置,确保在仓库根目录或前端目录执行 `nvm use` 时使用同一 Node 版本。
|
||||||
|
|
||||||
|
## 影响范围
|
||||||
|
|
||||||
|
- 仅影响本地前端开发、构建、调试命令的 Node 版本选择。
|
||||||
|
- 不涉及后端代码、数据库结构、菜单权限或业务逻辑调整。
|
||||||
|
|
||||||
|
## 验证情况
|
||||||
|
|
||||||
|
- 已检查 `ruoyi-ui/.nvmrc` 当前内容为 `14.21.3`。
|
||||||
|
- 已检查 `ruoyi-ui/package.json`,当前前端为 Vue 2 / Vue CLI 4 依赖栈,适合继续使用 Node `14.21.3`。
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
# 生产服务器 Java 后端启动脚本实施记录
|
||||||
|
|
||||||
|
## 保存路径确认
|
||||||
|
|
||||||
|
- 本次新增生产服务器后端启停脚本,实施记录保存到 `docs/reports/implementation/`,符合仓库实施文档目录规范。
|
||||||
|
|
||||||
|
## 修改目标
|
||||||
|
|
||||||
|
- 新写一个可在生产服务器上运行的 Java 后端启停脚本。
|
||||||
|
- 脚本支持配置 Java Home,不依赖 Maven,不执行本地构建,只负责运行已上传到服务器的 `ruoyi-admin.jar`。
|
||||||
|
|
||||||
|
## 修改内容
|
||||||
|
|
||||||
|
- 新增 `deploy/start-java-backend-prod.sh`
|
||||||
|
- 在脚本顶部新增“生产配置区”,生产服务器上的 Java Home、Jar 目录、Profile、JVM 参数和额外应用参数均直接写在脚本文件中。
|
||||||
|
- 按生产服务器目录结构调整默认 Jar 路径:启动脚本位于外层目录,后端 Jar 位于 `backend/ruoyi-admin.jar`。
|
||||||
|
- 通过脚本内 `APP_HOME="${SCRIPT_DIR}/backend"` 指定生产服务器上的 Jar 所在目录。
|
||||||
|
- 通过脚本内 `BACKEND_JAVA_HOME` 指定脚本使用的 JDK,优先级高于系统 `JAVA_HOME`。
|
||||||
|
- 脚本内 `BACKEND_JAVA_HOME` 留空时读取系统 `JAVA_HOME`;两者都未配置时使用 `PATH` 中的 `java`。
|
||||||
|
- 支持 `start`、`stop`、`restart`、`status`、`logs` 操作。
|
||||||
|
- `start` 会先调用 `stop_backend`,通过 `ps -ef` 关闭旧后端进程,再启动新的 `backend/ruoyi-admin.jar`。
|
||||||
|
- `start` 和 `restart` 在后端启动成功后会自动持续输出 `backend/logs/backend-console.log`,按 `Ctrl+C` 仅退出日志查看,不停止后端进程。
|
||||||
|
- 支持 `stop` 单独停止后端进程。
|
||||||
|
- 使用 `APP_MARKER` 标记脚本启动的新进程,停止旧进程时统一通过 `ps -ef` 扫描进程列表,匹配当前 Jar 绝对路径或生产目录下的相对路径 `backend/ruoyi-admin.jar`。
|
||||||
|
- `stop` 可停止没有脚本标记但由同一 `backend/ruoyi-admin.jar` 启动的旧进程,用于覆盖生产服务器已有手工启动进程。
|
||||||
|
- 进程扫描会忽略 `<defunct>` 行,避免僵尸进程或历史残留干扰启停判断。
|
||||||
|
- 若 `ps -ef` 执行失败,脚本会明确报错并中止旧进程扫描,避免误判为“后端未运行”。
|
||||||
|
- 默认 Spring Profile 为 `uat`,可通过 `SPRING_PROFILES_ACTIVE` 覆盖。
|
||||||
|
|
||||||
|
## 使用方式
|
||||||
|
|
||||||
|
将 `deploy/start-java-backend-prod.sh` 放到生产服务器,并先修改脚本顶部“生产配置区”:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
BACKEND_JAVA_HOME=""
|
||||||
|
APP_HOME="${SCRIPT_DIR}/backend"
|
||||||
|
JAR_NAME="ruoyi-admin.jar"
|
||||||
|
SPRING_PROFILES_ACTIVE="uat"
|
||||||
|
JAVA_OPTS="-Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError"
|
||||||
|
APP_ARGS=""
|
||||||
|
```
|
||||||
|
|
||||||
|
配置完成后直接执行:
|
||||||
|
|
||||||
|
常用命令:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./start-java-backend-prod.sh start
|
||||||
|
./start-java-backend-prod.sh stop
|
||||||
|
./start-java-backend-prod.sh restart
|
||||||
|
./start-java-backend-prod.sh status
|
||||||
|
./start-java-backend-prod.sh logs
|
||||||
|
```
|
||||||
|
|
||||||
|
## 验证记录
|
||||||
|
|
||||||
|
- 执行 `bash -n deploy/start-java-backend-prod.sh`
|
||||||
|
- 结果:通过
|
||||||
|
- 说明:脚本 Bash 语法正确。
|
||||||
|
- 执行 `bash deploy/start-java-backend-prod.sh help`
|
||||||
|
- 结果:通过
|
||||||
|
- 说明:帮助信息正常输出,并说明启动成功后会持续输出控制台日志。
|
||||||
|
- 执行 `rg -n "start_backend|follow_logs" deploy/start-java-backend-prod.sh`
|
||||||
|
- 结果:通过
|
||||||
|
- 说明:已确认 `start` 与 `restart` 分支均使用 `start_action`,流程为先 `stop_backend`,再 `start_backend`,最后 `follow_logs`。
|
||||||
|
- 执行 `bash deploy/start-java-backend-prod.sh status`
|
||||||
|
- 结果:通过
|
||||||
|
- 说明:在允许执行 `ps -ef` 后,无后端进程时可正常输出未运行状态。
|
||||||
|
- 执行 `rg -n "pgrep" deploy/start-java-backend-prod.sh`
|
||||||
|
- 结果:无匹配
|
||||||
|
- 说明:已确认停止旧进程不再依赖 `pgrep`。
|
||||||
|
- 执行 `rg -n "ps -ef" deploy/start-java-backend-prod.sh`
|
||||||
|
- 结果:通过
|
||||||
|
- 说明:已确认旧进程扫描逻辑使用 `ps -ef`。
|
||||||
|
- 使用临时脚本副本和临时后端目录启动一个命令行包含 `-jar backend/ruoyi-admin.jar`、但不带脚本标记的模拟旧进程,再执行 `bash /tmp/start-java-backend-prod-test.sh stop`
|
||||||
|
- 结果:通过
|
||||||
|
- 说明:已验证 `stop` 可以停止同一 Jar 路径的旧进程,不要求旧进程必须由当前脚本启动。
|
||||||
|
- 修改临时脚本副本,将脚本内 `BACKEND_JAVA_HOME` 设置为 `/not-exist` 后执行 `bash /tmp/start-java-backend-prod-test.sh start`
|
||||||
|
- 结果:按预期失败
|
||||||
|
- 说明:脚本能在启动前拦截无效 Java Home,并输出明确错误。
|
||||||
|
- 执行 `bash deploy/start-java-backend-prod.sh start`
|
||||||
|
- 结果:按预期失败
|
||||||
|
- 说明:脚本能正确解析当前 Java 命令,并在当前本地未提供 `deploy/backend/ruoyi-admin.jar` 时中止启动。
|
||||||
|
|
||||||
|
## 影响范围
|
||||||
|
|
||||||
|
- 仅新增生产服务器后端启停脚本与本实施记录。
|
||||||
|
- 不修改 Java 业务代码、数据库脚本、前端页面和现有发布包生成脚本。
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# 生产上线部署脚本实施记录
|
||||||
|
|
||||||
|
## 保存路径确认
|
||||||
|
|
||||||
|
- 本次为生产上线部署脚本改动,实施记录保存到 `docs/reports/implementation/`,符合仓库实施文档目录规范。
|
||||||
|
|
||||||
|
## 修改目标
|
||||||
|
|
||||||
|
- 生成一个可放在上线环境执行的部署脚本。
|
||||||
|
- 上线环境目录下已有 `backend/`、`frontend/` 和一个上线压缩包。
|
||||||
|
- 上线压缩包根层包含 `ruoyi-admin.jar` 和 `dist.zip`。
|
||||||
|
- 执行脚本后先备份 `backend/` 与 `frontend/` 旧文件,再解压上线包并部署到对应目录,最后调用 `start-java-backend-prod.sh` 重启后端并输出日志。
|
||||||
|
|
||||||
|
## 修改内容
|
||||||
|
|
||||||
|
- 新增 `deploy/deploy-release-prod.sh`
|
||||||
|
- 默认按脚本同级目录解析 `backend/`、`frontend/`、`start-java-backend-prod.sh` 和上线压缩包。
|
||||||
|
- 使用 `/bin/sh` 写法,避免依赖 Bash 进程替换等服务器环境不一定支持的语法。
|
||||||
|
- 支持显式传入上线压缩包路径:`./deploy-release-prod.sh /path/to/ccdi_YYYYMMDD.zip`。
|
||||||
|
- 未传入压缩包时,自动使用脚本同级目录下唯一的 `.zip` 文件,并排除 `dist.zip`。
|
||||||
|
- 部署前将 `backend/` 和 `frontend/` 当前内容备份到 `backups/YYYYMMDDHHMMSS/`。
|
||||||
|
- 解压上线包后校验根层必须存在 `ruoyi-admin.jar` 和 `dist.zip`。
|
||||||
|
- 解压 `dist.zip` 后校验必须存在 `dist/index.html`。
|
||||||
|
- 后端部署为覆盖 `backend/ruoyi-admin.jar`。
|
||||||
|
- 前端部署为清空 `frontend/` 后复制 `dist/` 内文件到 `frontend/`。
|
||||||
|
- 部署完成后执行 `bash start-java-backend-prod.sh restart`,由现有启动脚本完成后端重启并持续输出后端日志。
|
||||||
|
|
||||||
|
## 使用方式
|
||||||
|
|
||||||
|
生产环境目录结构:
|
||||||
|
|
||||||
|
```text
|
||||||
|
上线目录/
|
||||||
|
├── deploy-release-prod.sh
|
||||||
|
├── start-java-backend-prod.sh
|
||||||
|
├── backend/
|
||||||
|
├── frontend/
|
||||||
|
└── ccdi_YYYYMMDD.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
执行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./deploy-release-prod.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
或显式指定压缩包:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./deploy-release-prod.sh /path/to/ccdi_YYYYMMDD.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
## 验证记录
|
||||||
|
|
||||||
|
- 执行 `sh -n deploy/deploy-release-prod.sh`
|
||||||
|
- 结果:通过
|
||||||
|
- 说明:脚本 Shell 语法正确。
|
||||||
|
- 执行 `sh deploy/deploy-release-prod.sh --help`
|
||||||
|
- 结果:通过
|
||||||
|
- 说明:帮助信息正常输出。
|
||||||
|
- 使用 `/tmp` 构造最小上线目录、旧 `backend/`、旧 `frontend/`、上线压缩包和假的 `start-java-backend-prod.sh` 后执行部署脚本
|
||||||
|
- 结果:通过
|
||||||
|
- 说明:已验证旧文件备份、新 Jar 覆盖、前端 `dist/` 文件部署,以及最终调用启动脚本 `restart`。
|
||||||
|
|
||||||
|
## 影响范围
|
||||||
|
|
||||||
|
- 仅新增生产上线部署脚本与本实施记录。
|
||||||
|
- 不修改 Java 业务代码、前端业务代码、数据库脚本和现有后端启动脚本。
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
# 生产上线初始化 SQL 生成实施记录
|
||||||
|
|
||||||
|
## 保存路径确认
|
||||||
|
|
||||||
|
- 生产初始化 SQL:`sql/ccdi_prod_init_20260428.sql`
|
||||||
|
- 实施记录:`docs/reports/implementation/2026-04-28-production-init-sql-implementation.md`
|
||||||
|
|
||||||
|
## 修改内容
|
||||||
|
|
||||||
|
- 新增 `sql/ccdi_prod_init_20260428.sql`,用于生产空库初始化。
|
||||||
|
- SQL 内容包含当前 `ccdi` 库最终态的 57 张表结构。
|
||||||
|
- SQL 必要数据范围:
|
||||||
|
- 若依基础配置、部门、岗位、用户、角色、菜单、角色菜单、字典、定时任务、公告。
|
||||||
|
- CCDI 默认模型参数,仅包含 `ccdi_model_param.project_id = 0` 的系统默认参数。
|
||||||
|
- 流水打标规则 `ccdi_bank_tag_rule`。
|
||||||
|
- SQL 不包含运行期业务数据:
|
||||||
|
- 项目、员工、流水、导入记录、风险结果、采购事项、实体库、中介库、操作日志、登录日志等数据均保持空表。
|
||||||
|
- 将导出结构中的非规范排序规则统一修正为 `utf8mb4_general_ci`,未保留 `utf8mb4_0900_ai_ci`。
|
||||||
|
- 针对生产执行时报错 `Specified key was too long; max key length is 767 bytes`,按生产要求删除旧库 767 bytes 限制下会超长的索引定义,保留字段长度、表结构和必要初始化数据不变。
|
||||||
|
- 删除的超长索引范围:
|
||||||
|
- Quartz 表中的长字符复合主键和依赖这些长字符复合键的外键索引。
|
||||||
|
- `ccdi_account_info.idx_ccdi_account_info_account_no`。
|
||||||
|
- `ccdi_asset_info.idx_family_person`。
|
||||||
|
- `ccdi_bank_statement.uk_bank_statement_dedup`。
|
||||||
|
- `ccdi_bank_statement.idx_batch_id_account`。
|
||||||
|
- `ccdi_bank_statement.c4c_bank_statement_stg_batch_id_IDX`。
|
||||||
|
- `ccdi_bank_statement_tag_result.uk_ccdi_bank_tag_object_hit`。
|
||||||
|
- `ccdi_enterprise_base_info.idx_enterprise_name`。
|
||||||
|
- `ccdi_evidence.idx_ccdi_evidence_source`。
|
||||||
|
- `ccdi_model_param.uk_project_model_param`。
|
||||||
|
- `ccdi_project.idx_project_name`。
|
||||||
|
|
||||||
|
## 验证情况
|
||||||
|
|
||||||
|
- 使用本机临时 MySQL 实例导入 `sql/ccdi_prod_init_20260428.sql` 验证通过。
|
||||||
|
- 导入后验证结果:
|
||||||
|
- 表数量:57。
|
||||||
|
- 非 `utf8mb4_general_ci` 表数量:0。
|
||||||
|
- 基础数据行数:
|
||||||
|
- `sys_config`:8。
|
||||||
|
- `sys_dept`:10。
|
||||||
|
- `sys_dict_type`:26。
|
||||||
|
- `sys_dict_data`:98。
|
||||||
|
- `sys_menu`:166。
|
||||||
|
- `sys_role`:2。
|
||||||
|
- `sys_role_menu`:134。
|
||||||
|
- `sys_user`:3。
|
||||||
|
- `sys_job`:3。
|
||||||
|
- `sys_notice`:2。
|
||||||
|
- `ccdi_bank_tag_rule`:35。
|
||||||
|
- `ccdi_model_param`:17,且全部为 `project_id = 0`。
|
||||||
|
- 业务数据抽查为空:
|
||||||
|
- `ccdi_project`:0。
|
||||||
|
- `ccdi_base_staff`:0。
|
||||||
|
- `ccdi_bank_statement`:0。
|
||||||
|
- `ccdi_file_upload_record`:0。
|
||||||
|
- `ccdi_purchase_transaction`:0。
|
||||||
|
- 测试完成后已关闭本机临时 MySQL 实例。
|
||||||
|
- 生产索引长度修复后,再次计算脚本内所有剩余索引长度,确认超过 767 bytes 的索引数量为 0。
|
||||||
|
- 删除超长索引后,再次使用本机临时 MySQL 实例导入验证通过:
|
||||||
|
- 表数量:57。
|
||||||
|
- 非 `utf8mb4_general_ci` 表数量:0。
|
||||||
|
- `ccdi_model_param`:17。
|
||||||
|
- `ccdi_bank_tag_rule`:35。
|
||||||
|
- `sys_menu`:166。
|
||||||
|
- `ccdi_project`:0。
|
||||||
|
- `ccdi_bank_statement`:0。
|
||||||
|
|
||||||
|
## 执行说明
|
||||||
|
|
||||||
|
- 目标生产库需为空库。
|
||||||
|
- 目标库字符集和排序规则建议使用:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE DATABASE ccdi DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
|
||||||
|
```
|
||||||
|
|
||||||
|
- 导入时需使用 `utf8mb4` 会话字符集。
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# CCDI 上线压缩包生成脚本实施记录
|
||||||
|
|
||||||
|
## 修改内容
|
||||||
|
|
||||||
|
- 新增根目录脚本 `build_release_ccdi.sh`。
|
||||||
|
- 脚本执行后会重新构建后端 `ruoyi-admin.jar`,并进入 `ruoyi-ui` 通过 `nvm use` 切换前端 Node 版本后执行 `npm run build:prod`。
|
||||||
|
- 脚本会在根目录生成 `ccdi_YYYYMMDD.zip`,压缩包根层仅包含 `ruoyi-admin.jar` 和 `dist.zip`,不再额外包裹 `deploy` 目录。
|
||||||
|
- `.gitignore` 新增 `/ccdi_????????.zip`,避免生成的上线压缩包进入 Git。
|
||||||
|
|
||||||
|
## 影响范围
|
||||||
|
|
||||||
|
- 仅新增发布包生成脚本与忽略规则,不修改业务代码。
|
||||||
|
- 临时打包目录使用 `.deploy/ccdi-release-package/`,该目录已作为本地部署产物被 Git 忽略。
|
||||||
|
|
||||||
|
## 使用方式
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./build_release_ccdi.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
生成结果示例:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ccdi_20260428.zip
|
||||||
|
├── ruoyi-admin.jar
|
||||||
|
└── dist.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
## 验证情况
|
||||||
|
|
||||||
|
- 已执行 `sh -n build_release_ccdi.sh`,脚本语法检查通过。
|
||||||
|
- 已执行 `git diff --check`,未发现空白错误。
|
||||||
|
- 已执行 `./build_release_ccdi.sh`,后端 Maven 打包成功,前端生产构建成功,并生成 `ccdi_20260428.zip`。
|
||||||
|
- 已执行 `unzip -l ccdi_20260428.zip`,确认压缩包根层仅包含 `ruoyi-admin.jar` 与 `dist.zip` 两个文件。
|
||||||
|
- 已执行 `git check-ignore -v ccdi_20260428.zip`,确认根目录上线压缩包会被 `.gitignore` 忽略。
|
||||||
146
ruoyi-admin/src/main/resources/application-uat.yml
Normal file
146
ruoyi-admin/src/main/resources/application-uat.yml
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
# 开发环境配置
|
||||||
|
ruoyi:
|
||||||
|
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
||||||
|
profile: backend/uploadPath
|
||||||
|
|
||||||
|
|
||||||
|
# 开发环境配置
|
||||||
|
server:
|
||||||
|
# 服务器的HTTP端口,默认为8080
|
||||||
|
port: 62318
|
||||||
|
servlet:
|
||||||
|
# 应用的访问路径
|
||||||
|
context-path: /
|
||||||
|
tomcat:
|
||||||
|
# tomcat的URI编码
|
||||||
|
uri-encoding: UTF-8
|
||||||
|
# 连接数满后的排队数,默认为100
|
||||||
|
accept-count: 1000
|
||||||
|
threads:
|
||||||
|
# tomcat最大线程数,默认为200
|
||||||
|
max: 800
|
||||||
|
# Tomcat启动初始化的线程数,默认值10
|
||||||
|
min-spare: 100
|
||||||
|
|
||||||
|
|
||||||
|
# 数据源配置
|
||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
type: com.alibaba.druid.pool.DruidDataSource
|
||||||
|
driverClassName: com.mysql.cj.jdbc.Driver
|
||||||
|
druid:
|
||||||
|
# 主库数据源
|
||||||
|
master:
|
||||||
|
url: jdbc:mysql://158.234.199.250:3306/ccdi?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||||
|
username: dbicm
|
||||||
|
password: Kfcx@1234
|
||||||
|
# 从库数据源
|
||||||
|
slave:
|
||||||
|
# 从数据源开关/默认关闭
|
||||||
|
enabled: false
|
||||||
|
url:
|
||||||
|
username:
|
||||||
|
password:
|
||||||
|
# 初始连接数
|
||||||
|
initialSize: 5
|
||||||
|
# 最小连接池数量
|
||||||
|
minIdle: 10
|
||||||
|
# 最大连接池数量
|
||||||
|
maxActive: 20
|
||||||
|
# 配置获取连接等待超时的时间
|
||||||
|
maxWait: 60000
|
||||||
|
# 配置连接超时时间
|
||||||
|
connectTimeout: 30000
|
||||||
|
# 配置网络超时时间
|
||||||
|
socketTimeout: 60000
|
||||||
|
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||||
|
timeBetweenEvictionRunsMillis: 60000
|
||||||
|
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||||
|
minEvictableIdleTimeMillis: 300000
|
||||||
|
# 配置一个连接在池中最大生存的时间,单位是毫秒
|
||||||
|
maxEvictableIdleTimeMillis: 900000
|
||||||
|
# 配置检测连接是否有效
|
||||||
|
validationQuery: SELECT 1 FROM DUAL
|
||||||
|
testWhileIdle: true
|
||||||
|
testOnBorrow: false
|
||||||
|
testOnReturn: false
|
||||||
|
webStatFilter:
|
||||||
|
enabled: true
|
||||||
|
statViewServlet:
|
||||||
|
enabled: true
|
||||||
|
# 设置白名单,不填则允许所有访问
|
||||||
|
allow:
|
||||||
|
url-pattern: /druid/*
|
||||||
|
# 控制台管理用户名和密码
|
||||||
|
login-username: ruoyi
|
||||||
|
login-password: 123456
|
||||||
|
filter:
|
||||||
|
stat:
|
||||||
|
enabled: true
|
||||||
|
# 慢SQL记录
|
||||||
|
log-slow-sql: true
|
||||||
|
slow-sql-millis: 1000
|
||||||
|
merge-sql: true
|
||||||
|
wall:
|
||||||
|
config:
|
||||||
|
multi-statement-allow: true
|
||||||
|
data:
|
||||||
|
# redis 配置
|
||||||
|
redis:
|
||||||
|
# 地址
|
||||||
|
host: r-kz640f6b20dac724.redis.rds.ops.dc-tst-zj96596.com
|
||||||
|
# 端口,默认为6379
|
||||||
|
port: 6379
|
||||||
|
# 数据库索引
|
||||||
|
database: 9
|
||||||
|
# 密码
|
||||||
|
password: Kfcx@1234
|
||||||
|
# 连接超时时间
|
||||||
|
timeout: 10s
|
||||||
|
lettuce:
|
||||||
|
pool:
|
||||||
|
# 连接池中的最小空闲连接
|
||||||
|
min-idle: 0
|
||||||
|
# 连接池中的最大空闲连接
|
||||||
|
max-idle: 8
|
||||||
|
# 连接池的最大数据库连接数
|
||||||
|
max-active: 8
|
||||||
|
# #连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||||
|
max-wait: -1ms
|
||||||
|
|
||||||
|
# 流水分析平台配置
|
||||||
|
lsfx:
|
||||||
|
api:
|
||||||
|
|
||||||
|
base-url: http://158.234.196.5:82/c4c3
|
||||||
|
# 生产环境
|
||||||
|
# base-url: http://64.202.32.176/c4c3
|
||||||
|
|
||||||
|
# 认证配置
|
||||||
|
app-id: remote_app
|
||||||
|
app-secret: dXj6eHRmPv # 见知提供的密钥
|
||||||
|
client-id: c2017e8d105c435a96f86373635b6a09 # 测试环境固定值
|
||||||
|
|
||||||
|
# 接口路径配置
|
||||||
|
endpoints:
|
||||||
|
get-token: /account/common/getToken
|
||||||
|
upload-file: /watson/api/project/remoteUploadSplitFile
|
||||||
|
fetch-inner-flow: /watson/api/project/getJZFileOrZjrcuFile
|
||||||
|
check-parse-status: /watson/api/project/upload/getpendings
|
||||||
|
get-bank-statement: /watson/api/project/getBSByLogId
|
||||||
|
# 新增接口
|
||||||
|
get-file-upload-status: /watson/api/project/bs/upload
|
||||||
|
delete-files: /watson/api/project/batchDeleteUploadFile
|
||||||
|
|
||||||
|
# RestTemplate配置
|
||||||
|
connection-timeout: 30000 # 连接超时30秒
|
||||||
|
read-timeout: 60000 # 读取超时60秒
|
||||||
|
|
||||||
|
# 连接池配置
|
||||||
|
pool:
|
||||||
|
max-total: 100 # 最大连接数
|
||||||
|
default-max-per-route: 20 # 每个路由最大连接数
|
||||||
|
|
||||||
|
credit-parse:
|
||||||
|
api:
|
||||||
|
url: http://192.168.0.111:62320/xfeature-mngs/conversation/htmlEval
|
||||||
1820
sql/ccdi_prod_init_20260428.sql
Normal file
1820
sql/ccdi_prod_init_20260428.sql
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user