- 实现签到主页面,包含签到按钮、连续天数、今日状态展示 - 实现签到记录页面,包含日历视图和签到历史列表 - 实现个人中心页面,包含用户信息和签到统计 - 后端实现签到、查询状态、查询历史三个接口 - 使用 Supabase 存储签到记录数据 - 采用星空主题设计,深蓝紫渐变背景 + 金色星光强调色 - 完成所有接口测试和前后端匹配验证 - 通过 ESLint 检查和编译验证
152 lines
5.1 KiB
Bash
152 lines
5.1 KiB
Bash
#!/bin/bash
|
||
echo "⚙️ dev_run.sh 开始运行"
|
||
set -Eeuo pipefail
|
||
|
||
cd "${COZE_WORKSPACE_PATH}"
|
||
|
||
# ---------------------------------------------------------
|
||
# PID 文件,用于追踪上一次启动的进程树
|
||
# ---------------------------------------------------------
|
||
PID_FILE="/tmp/coze-dev-run.pid"
|
||
|
||
# ---------------------------------------------------------
|
||
# 工具函数
|
||
# ---------------------------------------------------------
|
||
kill_process_tree() {
|
||
local pid=$1
|
||
local children
|
||
children=$(pgrep -P "${pid}" 2>/dev/null || true)
|
||
for child in ${children}; do
|
||
kill_process_tree "${child}"
|
||
done
|
||
if kill -0 "${pid}" 2>/dev/null; then
|
||
echo "Killing PID ${pid}"
|
||
kill -9 "${pid}" 2>/dev/null || true
|
||
fi
|
||
}
|
||
|
||
kill_port_if_listening() {
|
||
local port=$1
|
||
local pids
|
||
pids=$(ss -H -lntp 2>/dev/null | awk -v port="${port}" '$4 ~ ":"port"$"' | grep -o 'pid=[0-9]*' | cut -d= -f2 | sort -u | paste -sd' ' - || true)
|
||
if [[ -z "${pids}" ]]; then
|
||
echo "Port ${port} is free."
|
||
return
|
||
fi
|
||
echo "Port ${port} in use by PIDs: ${pids}"
|
||
for pid in ${pids}; do
|
||
kill_process_tree "${pid}"
|
||
done
|
||
sleep 1
|
||
pids=$(ss -H -lntp 2>/dev/null | awk -v port="${port}" '$4 ~ ":"port"$"' | grep -o 'pid=[0-9]*' | cut -d= -f2 | sort -u | paste -sd' ' - || true)
|
||
if [[ -n "${pids}" ]]; then
|
||
echo "Warning: port ${port} still busy after cleanup, PIDs: ${pids}"
|
||
else
|
||
echo "Port ${port} cleared."
|
||
fi
|
||
}
|
||
|
||
# ---------------------------------------------------------
|
||
# 1. 清理上一次运行残留的整棵进程树
|
||
# ---------------------------------------------------------
|
||
cleanup_previous_run() {
|
||
# 1a. 通过 PID 文件清理上次的进程树
|
||
if [[ -f "${PID_FILE}" ]]; then
|
||
local old_pid
|
||
old_pid=$(cat "${PID_FILE}" 2>/dev/null || true)
|
||
if [[ -n "${old_pid}" ]] && kill -0 "${old_pid}" 2>/dev/null; then
|
||
echo "🧹 Killing previous dev process tree (root PID: ${old_pid})..."
|
||
kill_process_tree "${old_pid}"
|
||
fi
|
||
rm -f "${PID_FILE}"
|
||
fi
|
||
|
||
# 1b. 兜底:按特征匹配清理所有残留的相关进程(排除自身)
|
||
echo "🧹 Cleaning up any orphaned dev processes..."
|
||
local patterns=(
|
||
"pnpm dev"
|
||
"concurrently.*dev:web.*dev:server"
|
||
"nest start --watch"
|
||
"taro build --type h5 --watch"
|
||
"node --enable-source-maps.*/workspace/projects/server/dist/main"
|
||
"esbuild --service.*--ping"
|
||
)
|
||
for pattern in "${patterns[@]}"; do
|
||
local pids
|
||
pids=$(pgrep -f "${pattern}" 2>/dev/null || true)
|
||
for pid in ${pids}; do
|
||
# 不杀自己和自己的父进程链
|
||
if [[ "${pid}" != "$$" ]] && [[ "${pid}" != "${PPID}" ]]; then
|
||
echo " Killing orphan PID ${pid} matching '${pattern}'"
|
||
kill -9 "${pid}" 2>/dev/null || true
|
||
fi
|
||
done
|
||
done
|
||
sleep 1
|
||
}
|
||
|
||
# ---------------------------------------------------------
|
||
# 2. 安装依赖
|
||
# ---------------------------------------------------------
|
||
echo "📦 Installing dependencies..."
|
||
pnpm install
|
||
echo "✅ Dependencies installed successfully!"
|
||
|
||
# ---------------------------------------------------------
|
||
# 3. 清理旧进程 + 端口
|
||
# ---------------------------------------------------------
|
||
SERVER_PORT=3000
|
||
|
||
cleanup_previous_run
|
||
|
||
echo "Clearing port ${DEPLOY_RUN_PORT} (web) before start."
|
||
kill_port_if_listening "${DEPLOY_RUN_PORT}"
|
||
echo "Clearing port ${SERVER_PORT} (server) before start."
|
||
kill_port_if_listening "${SERVER_PORT}"
|
||
|
||
# ---------------------------------------------------------
|
||
# 4. 退出时自动清理子进程(信号 trap)
|
||
# ---------------------------------------------------------
|
||
cleanup_on_exit() {
|
||
echo "🛑 dev_run.sh exiting, cleaning up child processes..."
|
||
# 杀掉当前脚本的所有子进程
|
||
kill -- -$$ 2>/dev/null || true
|
||
rm -f "${PID_FILE}"
|
||
exit 0
|
||
}
|
||
trap cleanup_on_exit EXIT INT TERM HUP
|
||
|
||
# ---------------------------------------------------------
|
||
# 5. 启动服务
|
||
# ---------------------------------------------------------
|
||
start_service() {
|
||
cd "${COZE_WORKSPACE_PATH}"
|
||
|
||
# 动态注入环境变量
|
||
if [ -n "${COZE_PROJECT_DOMAIN_DEFAULT:-}" ]; then
|
||
export PROJECT_DOMAIN="$COZE_PROJECT_DOMAIN_DEFAULT"
|
||
echo "✅ 环境变量已动态注入: PROJECT_DOMAIN=$PROJECT_DOMAIN"
|
||
else
|
||
echo "⚠️ 警告: COZE_PROJECT_DOMAIN_DEFAULT 未设置,使用 .env.local 中的配置"
|
||
fi
|
||
|
||
# 启动 Taro H5 和 NestJS Server
|
||
echo "Starting Taro H5 Dev Server and NestJS Server..."
|
||
|
||
export PORT=${DEPLOY_RUN_PORT}
|
||
rm -f /tmp/coze-logs/dev.log
|
||
mkdir -p /tmp/coze-logs
|
||
|
||
# 后台启动并记录 PID
|
||
pnpm dev 2>&1 | tee /tmp/coze-logs/dev.log &
|
||
local dev_pid=$!
|
||
echo "${dev_pid}" > "${PID_FILE}"
|
||
echo "📝 Dev process started with PID: ${dev_pid} (saved to ${PID_FILE})"
|
||
|
||
# 前台等待,保证 trap 能正常捕获信号
|
||
wait "${dev_pid}" || true
|
||
}
|
||
|
||
echo "Starting HTTP services on port ${DEPLOY_RUN_PORT} (web) and ${SERVER_PORT} (server)..."
|
||
start_service
|