- Remove .DS_Store file. - Update .gitignore to include .DS_Store. - Modify proxy configuration to use environment variable for backend URL. - Correct component paths in routes. - Implement outdoor fair detail fetching with improved API call. - Enhance EditModal for outdoor fair with dynamic dictionary options. - Add functionality to upload outdoor fair photos. - Update service layer to handle outdoor fair dictionary options.
232 lines
5.3 KiB
Bash
Executable File
232 lines
5.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
RUNTIME_DIR="${RUNTIME_DIR:-${ROOT_DIR}/.local}"
|
||
LOG_DIR="${RUNTIME_DIR}/logs"
|
||
LOG_FILE="${LOG_FILE:-${LOG_DIR}/frontend.log}"
|
||
PID_FILE="${PID_FILE:-${RUNTIME_DIR}/frontend.pid}"
|
||
|
||
BACKEND_URL="${LOCAL_BACKEND_URL:-http://127.0.0.1:9091}"
|
||
FRONTEND_PORT="${PORT:-8000}"
|
||
NPM_CMD="${NPM_CMD:-npm}"
|
||
MAX_CMD="${ROOT_DIR}/node_modules/.bin/max"
|
||
|
||
info() {
|
||
printf '\033[1;32m%s\033[0m\n' "$*"
|
||
}
|
||
|
||
error() {
|
||
printf '\033[1;31m%s\033[0m\n' "$*" >&2
|
||
}
|
||
|
||
usage() {
|
||
cat <<'EOF'
|
||
用法:./local.sh <命令> [参数]
|
||
|
||
命令:
|
||
install 使用 package-lock.json 安装依赖
|
||
start [--skip-install] 检查本地后端并在后台启动前端
|
||
stop 停止本脚本启动的前端进程
|
||
restart [--skip-install] 重启前端
|
||
status 查看前端和本地后端状态
|
||
logs [行数] 查看并持续跟踪日志,默认显示最后 200 行
|
||
help 显示帮助
|
||
|
||
可选环境变量:
|
||
LOCAL_BACKEND_URL 本地后端地址,默认 http://127.0.0.1:9091
|
||
PORT 前端端口,默认 8000
|
||
NPM_CMD npm 命令,默认 npm
|
||
EOF
|
||
}
|
||
|
||
prepare_runtime() {
|
||
mkdir -p "${LOG_DIR}"
|
||
}
|
||
|
||
read_pid() {
|
||
if [[ -f "${PID_FILE}" ]]; then
|
||
tr -d '[:space:]' < "${PID_FILE}"
|
||
fi
|
||
}
|
||
|
||
is_running() {
|
||
local pid
|
||
pid="$(read_pid)"
|
||
[[ -n "${pid}" ]] && kill -0 "${pid}" 2>/dev/null
|
||
}
|
||
|
||
install_dependencies() {
|
||
command -v "${NPM_CMD}" >/dev/null 2>&1 || {
|
||
error "未找到 npm 命令:${NPM_CMD}"
|
||
exit 1
|
||
}
|
||
|
||
info "正在根据 package-lock.json 安装依赖..."
|
||
(
|
||
cd "${ROOT_DIR}"
|
||
"${NPM_CMD}" ci
|
||
)
|
||
}
|
||
|
||
check_backend() {
|
||
local status
|
||
command -v curl >/dev/null 2>&1 || {
|
||
error "未找到 curl,无法检查本地后端"
|
||
exit 1
|
||
}
|
||
|
||
status="$(curl -s -o /dev/null --max-time 3 -w '%{http_code}' "${BACKEND_URL}/" || true)"
|
||
if [[ -z "${status}" || "${status}" == "000" ]]; then
|
||
error "本地后端不可访问:${BACKEND_URL}"
|
||
error "请先在 shz-backend 中执行:./local.sh start"
|
||
exit 1
|
||
fi
|
||
info "本地后端已连接:${BACKEND_URL}(HTTP ${status})"
|
||
}
|
||
|
||
start_frontend() {
|
||
local skip_install="${1:-}"
|
||
|
||
prepare_runtime
|
||
if is_running; then
|
||
info "前端已在运行,PID:$(read_pid)"
|
||
return 0
|
||
fi
|
||
rm -f "${PID_FILE}"
|
||
|
||
check_backend
|
||
|
||
if [[ ! -x "${MAX_CMD}" ]]; then
|
||
if [[ "${skip_install}" == "--skip-install" ]]; then
|
||
error "依赖尚未安装,不能跳过安装:${MAX_CMD} 不存在"
|
||
exit 1
|
||
fi
|
||
install_dependencies
|
||
elif [[ -n "${skip_install}" && "${skip_install}" != "--skip-install" ]]; then
|
||
error "未知参数:${skip_install}"
|
||
exit 2
|
||
fi
|
||
|
||
export REACT_APP_ENV=dev
|
||
export MOCK=none
|
||
export UMI_ENV=dev
|
||
export LOCAL_BACKEND_URL="${BACKEND_URL}"
|
||
export PORT="${FRONTEND_PORT}"
|
||
|
||
info "正在启动前端:http://localhost:${FRONTEND_PORT}"
|
||
info "后端代理目标:${BACKEND_URL}"
|
||
(
|
||
cd "${ROOT_DIR}"
|
||
nohup "${MAX_CMD}" dev >> "${LOG_FILE}" 2>&1 &
|
||
printf '%s\n' "$!" > "${PID_FILE}"
|
||
)
|
||
|
||
local frontend_status="000"
|
||
for _ in {1..60}; do
|
||
if ! is_running; then
|
||
break
|
||
fi
|
||
frontend_status="$(curl -s -o /dev/null --max-time 1 -w '%{http_code}' \
|
||
"http://127.0.0.1:${FRONTEND_PORT}/" || true)"
|
||
if [[ -n "${frontend_status}" && "${frontend_status}" != "000" ]]; then
|
||
info "前端已启动,PID:$(read_pid),HTTP ${frontend_status}"
|
||
info "日志命令:./local.sh logs"
|
||
return 0
|
||
fi
|
||
sleep 1
|
||
done
|
||
|
||
rm -f "${PID_FILE}"
|
||
error "前端未能在 60 秒内启动,最近日志如下:"
|
||
tail -n 80 "${LOG_FILE}" >&2 || true
|
||
exit 1
|
||
}
|
||
|
||
stop_frontend() {
|
||
local pid
|
||
pid="$(read_pid)"
|
||
|
||
if ! is_running; then
|
||
rm -f "${PID_FILE}"
|
||
info "前端未运行"
|
||
return 0
|
||
fi
|
||
|
||
info "正在停止前端,PID:${pid}"
|
||
kill "${pid}"
|
||
for _ in {1..15}; do
|
||
if ! kill -0 "${pid}" 2>/dev/null; then
|
||
rm -f "${PID_FILE}"
|
||
info "前端已停止"
|
||
return 0
|
||
fi
|
||
sleep 1
|
||
done
|
||
|
||
error "前端未在 15 秒内停止,请检查 PID:${pid}"
|
||
exit 1
|
||
}
|
||
|
||
show_status() {
|
||
local backend_status
|
||
if is_running; then
|
||
info "前端正在运行,PID:$(read_pid),地址:http://localhost:${FRONTEND_PORT}"
|
||
else
|
||
rm -f "${PID_FILE}"
|
||
info "前端未运行"
|
||
fi
|
||
|
||
backend_status="$(curl -s -o /dev/null --max-time 2 -w '%{http_code}' "${BACKEND_URL}/" || true)"
|
||
if [[ -n "${backend_status}" && "${backend_status}" != "000" ]]; then
|
||
info "本地后端可访问:${BACKEND_URL}(HTTP ${backend_status})"
|
||
else
|
||
error "本地后端不可访问:${BACKEND_URL}"
|
||
fi
|
||
info "日志文件:${LOG_FILE}"
|
||
}
|
||
|
||
show_logs() {
|
||
local lines="${1:-200}"
|
||
if [[ ! "${lines}" =~ ^[0-9]+$ ]]; then
|
||
error "日志行数必须是非负整数:${lines}"
|
||
exit 2
|
||
fi
|
||
|
||
prepare_runtime
|
||
touch "${LOG_FILE}"
|
||
info "正在跟踪日志:${LOG_FILE}(Ctrl+C 退出)"
|
||
tail -n "${lines}" -f "${LOG_FILE}"
|
||
}
|
||
|
||
command="${1:-help}"
|
||
case "${command}" in
|
||
install)
|
||
install_dependencies
|
||
;;
|
||
start)
|
||
start_frontend "${2:-}"
|
||
;;
|
||
stop)
|
||
stop_frontend
|
||
;;
|
||
restart)
|
||
stop_frontend
|
||
start_frontend "${2:-}"
|
||
;;
|
||
status)
|
||
show_status
|
||
;;
|
||
logs)
|
||
show_logs "${2:-200}"
|
||
;;
|
||
help|-h|--help)
|
||
usage
|
||
;;
|
||
*)
|
||
error "未知命令:${command}"
|
||
usage >&2
|
||
exit 2
|
||
;;
|
||
esac
|