前端修复: - calendar_page: 移除不存在的 JournalEntry.content getter - responsive_scaffold: 移除不存在的 notchThickness 参数 - splash_page: SingleTickerProvider → TickerProvider (多 AnimationController) - profile_page: UserRoleType.name → .code (修复运行时崩溃) - 导入缺失的 user.dart 后端修复: - class_service: generate_class_code 取 UUID 后6位(随机部分)避免碰撞 - diary_role_seed: 移除不存在的 id 列,使用复合主键 ON CONFLICT 基础设施: - config/default.toml: CORS 改为通配符(开发模式) - scripts/dev.sh: 统一启动脚本(自动清理端口) - docs/opendesign/: Open Design 设计规格 HTML 原型稿 验证结果: flutter analyze 0 error, cargo test 77/77 通过, 17个页面全部渲染正常
172 lines
4.8 KiB
Bash
172 lines
4.8 KiB
Bash
#!/bin/bash
|
||
# 暖记开发环境启动脚本 — 自动清理旧进程 + 启动后端和前端
|
||
#
|
||
# 用法:
|
||
# ./scripts/dev.sh # 启动全部
|
||
# ./scripts/dev.sh backend # 只启动后端
|
||
# ./scripts/dev.sh frontend # 只启动前端
|
||
# ./scripts/dev.sh stop # 停止所有服务
|
||
|
||
set -e
|
||
|
||
# ===== 配置 =====
|
||
BACKEND_PORT=3000
|
||
FRONTEND_PORT=8080
|
||
PG_HOST="localhost"
|
||
PG_PORT=5432
|
||
PG_USER="postgres"
|
||
PG_PASS="123123"
|
||
PG_DB="nuanji"
|
||
|
||
# ===== 颜色 =====
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m'
|
||
|
||
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||
log_ok() { echo -e "${GREEN}[OK]${NC} $1"; }
|
||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||
log_err() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||
|
||
# ===== 清理端口占用的进程 =====
|
||
kill_port() {
|
||
local port=$1
|
||
local name=$2
|
||
local pids=$(netstat -ano 2>/dev/null | grep ":${port}.*LISTENING" | awk '{print $5}' | sort -u)
|
||
|
||
if [ -n "$pids" ]; then
|
||
for pid in $pids; do
|
||
if [ "$pid" != "0" ]; then
|
||
taskkill //F //PID "$pid" 2>/dev/null && \
|
||
log_ok "已停止 ${name} (PID: ${pid}, 端口: ${port})" || \
|
||
log_warn "无法停止 ${name} (PID: ${pid})"
|
||
fi
|
||
done
|
||
else
|
||
log_info "${name} 端口 ${port} 空闲"
|
||
fi
|
||
}
|
||
|
||
stop_all() {
|
||
log_info "停止所有暖记服务..."
|
||
kill_port $BACKEND_PORT "后端"
|
||
kill_port $FRONTEND_PORT "前端"
|
||
# 也杀掉可能的残留 Chrome 进程(Flutter dev 启动的)
|
||
taskkill //F //IM erp-server.exe 2>/dev/null && log_ok "已停止 erp-server.exe" || true
|
||
log_ok "所有服务已停止"
|
||
}
|
||
|
||
# ===== 检查依赖 =====
|
||
check_deps() {
|
||
log_info "检查依赖..."
|
||
|
||
# PostgreSQL
|
||
if PGPASSWORD=$PG_PASS /d/postgreSQL/bin/psql.exe -U $PG_USER -h $PG_HOST -p $PG_PORT \
|
||
-d $PG_DB -c "SELECT 1" > /dev/null 2>&1; then
|
||
log_ok "PostgreSQL 已连接 (${PG_DB}@${PG_HOST}:${PG_PORT})"
|
||
else
|
||
log_err "无法连接 PostgreSQL (${PG_DB}@${PG_HOST}:${PG_PORT})"
|
||
log_err "请确保 PostgreSQL 已启动且数据库 ${PG_DB} 存在"
|
||
exit 1
|
||
fi
|
||
|
||
# Redis
|
||
if redis-cli ping > /dev/null 2>&1; then
|
||
log_ok "Redis 已连接"
|
||
else
|
||
log_err "无法连接 Redis (localhost:6379)"
|
||
exit 1
|
||
fi
|
||
|
||
# Flutter
|
||
if D:/flutter/bin/flutter.bat --version > /dev/null 2>&1; then
|
||
log_ok "Flutter SDK 可用"
|
||
else
|
||
log_err "Flutter SDK 不可用"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# ===== 启动后端 =====
|
||
start_backend() {
|
||
log_info "清理旧后端进程..."
|
||
kill_port $BACKEND_PORT "后端"
|
||
taskkill //F //IM erp-server.exe 2>/dev/null || true
|
||
sleep 1
|
||
|
||
log_info "编译并启动后端 (diary feature)..."
|
||
ERP__DATABASE__URL="postgres://${PG_USER}:${PG_PASS}@${PG_HOST}:${PG_PORT}/${PG_DB}" \
|
||
ERP__REDIS__URL="redis://localhost:6379" \
|
||
ERP__JWT__SECRET="nuanji-dev-jwt-secret-2024-warm-notes-hmac-key-32b" \
|
||
ERP__AUTH__SUPER_ADMIN_PASSWORD="admin123" \
|
||
ERP__WECHAT__APPID="wx_dev_placeholder" \
|
||
ERP__WECHAT__SECRET="wx_dev_secret_placeholder" \
|
||
ERP__WECHAT__DEV_MODE="true" \
|
||
ERP__CRYPTO__KEK="0000000000000000000000000000000000000000000000000000000000000000" \
|
||
cargo run -p erp-server --features diary &
|
||
|
||
# 等待后端就绪
|
||
log_info "等待后端就绪..."
|
||
for i in $(seq 1 30); do
|
||
if curl -s "http://localhost:${BACKEND_PORT}/api/v1/health" > /dev/null 2>&1; then
|
||
log_ok "后端已就绪 → http://localhost:${BACKEND_PORT}"
|
||
return 0
|
||
fi
|
||
sleep 2
|
||
done
|
||
log_err "后端启动超时"
|
||
return 1
|
||
}
|
||
|
||
# ===== 启动前端 =====
|
||
start_frontend() {
|
||
log_info "清理旧前端进程..."
|
||
kill_port $FRONTEND_PORT "前端"
|
||
sleep 1
|
||
|
||
log_info "编译并启动 Flutter Web..."
|
||
cd /g/nj/app
|
||
D:/flutter/bin/flutter.bat run -d chrome --web-port=$FRONTEND_PORT &
|
||
|
||
log_info "等待前端就绪..."
|
||
for i in $(seq 1 30); do
|
||
if curl -s "http://localhost:${FRONTEND_PORT}" > /dev/null 2>&1; then
|
||
log_ok "前端已就绪 → http://localhost:${FRONTEND_PORT}"
|
||
return 0
|
||
fi
|
||
sleep 3
|
||
done
|
||
log_err "前端启动超时"
|
||
return 1
|
||
}
|
||
|
||
# ===== 主流程 =====
|
||
case "${1:-all}" in
|
||
stop)
|
||
stop_all
|
||
;;
|
||
backend)
|
||
check_deps
|
||
start_backend
|
||
;;
|
||
frontend)
|
||
check_deps
|
||
start_frontend
|
||
;;
|
||
all)
|
||
check_deps
|
||
start_backend
|
||
start_frontend
|
||
log_ok "=== 暖记开发环境已启动 ==="
|
||
log_ok "后端: http://localhost:${BACKEND_PORT}"
|
||
log_ok "前端: http://localhost:${FRONTEND_PORT}"
|
||
log_ok "API 文档: http://localhost:${BACKEND_PORT}/api/v1/health"
|
||
;;
|
||
*)
|
||
echo "用法: $0 [all|backend|frontend|stop]"
|
||
exit 1
|
||
;;
|
||
esac
|