Files
nj/scripts/dev.sh
iven c441aa4e34
Some checks failed
Main Merge / backend (push) Has been cancelled
Main Merge / frontend (push) Has been cancelled
fix(app): RemoteJournalRepository 创建日记 date 格式修复 — ISO 8601 → NaiveDate
根因: JournalEntry.toJson() 发送 '2026-06-04T12:00:00.123456',
后端 CreateJournalReq.date 是 chrono::NaiveDate,只接受 '2026-06-04'。
反序列化失败导致创建日记被拒绝,前端静默吞掉错误。

修复: createJournal 发送前将 date 截取为 YYYY-MM-DD 格式。
2026-06-04 10:47:14 +08:00

202 lines
5.7 KiB
Bash

#!/bin/bash
# 暖记开发环境启动脚本 — 自动清理旧进程 + 启动后端和前端
#
# 用法:
# ./scripts/dev.sh # 启动全部 (后端+管理端+学生端)
# ./scripts/dev.sh backend # 只启动后端
# ./scripts/dev.sh admin # 只启动管理端前端 (React, port 5174)
# ./scripts/dev.sh app # 只启动学生端 Flutter (port 8080)
# ./scripts/dev.sh stop # 停止所有服务
set -e
# ===== 配置 =====
BACKEND_PORT=3000
ADMIN_PORT=5174 # 管理端前端 (React + Ant Design)
APP_PORT=8080 # 学生端前端 (Flutter Web)
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 $ADMIN_PORT "管理端前端"
kill_port $APP_PORT "学生端前端"
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)..."
cd /g/nj
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
}
# ===== 启动管理端前端 (React + Ant Design) =====
start_admin() {
log_info "清理旧管理端进程..."
kill_port $ADMIN_PORT "管理端前端"
sleep 1
log_info "启动管理端前端 (React + Vite)..."
cd /g/nj/apps/web
pnpm dev &
log_info "等待管理端就绪..."
for i in $(seq 1 20); do
if curl -s -o /dev/null "http://localhost:${ADMIN_PORT}" 2>/dev/null; then
log_ok "管理端已就绪 → http://localhost:${ADMIN_PORT}"
return 0
fi
sleep 2
done
log_err "管理端启动超时"
return 1
}
# ===== 启动学生端 Flutter Web =====
start_app() {
log_info "清理旧学生端进程..."
kill_port $APP_PORT "学生端前端"
sleep 1
log_info "编译并启动 Flutter Web..."
cd /g/nj/app
D:/flutter/bin/flutter.bat run -d chrome --web-port=$APP_PORT &
log_info "等待学生端就绪..."
for i in $(seq 1 30); do
if curl -s -o /dev/null "http://localhost:${APP_PORT}" 2>/dev/null; then
log_ok "学生端已就绪 → http://localhost:${APP_PORT}"
return 0
fi
sleep 3
done
log_err "学生端启动超时"
return 1
}
# ===== 主流程 =====
case "${1:-all}" in
stop)
stop_all
;;
backend)
check_deps
start_backend
;;
admin)
check_deps
start_admin
;;
app)
check_deps
start_app
;;
all)
check_deps
start_backend
start_admin
start_app
log_ok "=== 暖记开发环境已启动 ==="
log_ok "后端 API: http://localhost:${BACKEND_PORT}"
log_ok "管理端: http://localhost:${ADMIN_PORT} (admin/admin123)"
log_ok "学生端: http://localhost:${APP_PORT}"
;;
*)
echo "用法: $0 [all|backend|admin|app|stop]"
exit 1
;;
esac