d717fb3735
API 对接: - 入库/出库/库存/财务/往来单位/基础数据全部对接后端 REST API - 新增 repositories、providers、models 层,统一分层架构 - auth 从 flutter_secure_storage 迁移到 shared_preferences 登陆跳转修复: - 将 _RouterNotifier 提取为独立 Riverpod provider,appRouterProvider 使用 ref.read 避免依赖链导致 router 重建后跳回 /login - redirect 函数新增 initialized 守卫,防止 auth 未恢复时误重定向 - 添加调试日志(Router/Auth/ApiClient)定位 401 触发的 logout 链路 退出菜单 UI: - 去掉 ListTile,改用 Row + 自定义 padding,文字左对齐 - MouseRegion + AnimatedContainer 实现 hover 高亮(普通项蓝底/退出红底) - 菜单圆角 6px,elevation 8,分割线高度 1px Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
210 lines
6.8 KiB
Bash
Executable File
210 lines
6.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# 如果用 sh 调用,自动切换到 bash
|
|
if [ -z "$BASH_VERSION" ]; then
|
|
exec bash "$0" "$@"
|
|
fi
|
|
# dev.sh — 本地开发环境管理
|
|
#
|
|
# 启动:
|
|
# bash scripts/dev.sh run # 启动前后端(后端无改动则跳过重启)
|
|
# bash scripts/dev.sh run --force # 强制重启后端
|
|
# bash scripts/dev.sh --backend-only # 仅启动后端
|
|
# bash scripts/dev.sh --frontend-only # 仅启动前端
|
|
#
|
|
# 数据库:
|
|
# bash scripts/dev.sh reset # 删表重建 + 写入测试数据
|
|
# bash scripts/dev.sh seed # 写入测试数据(已存在则跳过)
|
|
# bash scripts/dev.sh clear # 清空所有数据(不写入)
|
|
|
|
set -e
|
|
|
|
export PATH="/opt/homebrew/bin:/opt/homebrew/sbin:$PATH"
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
BACKEND_DIR="$ROOT/backend"
|
|
CLIENT_DIR="$ROOT/client"
|
|
LOG_DIR="$ROOT/scripts/.logs"
|
|
BACKEND_LOG="$LOG_DIR/backend.log"
|
|
BACKEND_PID_FILE="$LOG_DIR/backend.pid"
|
|
BACKEND_HASH_FILE="$LOG_DIR/backend.hash"
|
|
|
|
mkdir -p "$LOG_DIR"
|
|
|
|
# ── 颜色输出 ──────────────────────────────────────────────
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
RED='\033[0;31m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m'
|
|
|
|
info() { echo -e "${CYAN}[dev]${NC} $*"; }
|
|
success() { echo -e "${GREEN}[dev]${NC} $*"; }
|
|
warn() { echo -e "${YELLOW}[dev]${NC} $*"; }
|
|
error() { echo -e "${RED}[dev]${NC} $*"; }
|
|
|
|
# ── 参数解析 ──────────────────────────────────────────────
|
|
COMMAND="${1:-run}"
|
|
FORCE=false
|
|
RUN_BACKEND=true
|
|
RUN_FRONTEND=true
|
|
|
|
case "$COMMAND" in
|
|
run)
|
|
[ "${2:-}" = "--force" ] && FORCE=true
|
|
;;
|
|
seed|reset|clear)
|
|
# seed / reset / clear 三个命令
|
|
SEED_ARG=""
|
|
[ "$COMMAND" = "reset" ] && SEED_ARG="--reset"
|
|
[ "$COMMAND" = "clear" ] && SEED_ARG="--clear"
|
|
[ -n "${2:-}" ] && SEED_ARG="$2"
|
|
info "写入初始测试数据..."
|
|
cd "$BACKEND_DIR"
|
|
go run cmd/seed/main.go $SEED_ARG
|
|
exit 0
|
|
;;
|
|
--backend-only)
|
|
COMMAND=run
|
|
RUN_FRONTEND=false
|
|
[ "${2:-}" = "--force" ] && FORCE=true
|
|
;;
|
|
--frontend-only)
|
|
COMMAND=run
|
|
RUN_BACKEND=false
|
|
;;
|
|
*)
|
|
error "未知命令: $COMMAND"
|
|
echo "用法: bash scripts/dev.sh [run [--force] | reset | clear | seed | --backend-only | --frontend-only]"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# ── 清理函数 ──────────────────────────────────────────────
|
|
cleanup() {
|
|
echo ""
|
|
info "正在关闭服务..."
|
|
# 不杀后端:run 模式下后端是持久进程,Ctrl+C 只退出 flutter
|
|
info "后端继续在后台运行。如需停止:bash scripts/dev.sh stop"
|
|
exit 0
|
|
}
|
|
trap cleanup INT TERM
|
|
|
|
# ── 依赖检查 ──────────────────────────────────────────────
|
|
check_deps() {
|
|
local missing=0
|
|
if [ "$RUN_BACKEND" = true ] && ! command -v go &>/dev/null; then
|
|
error "未找到 go,请确认 PATH 包含 Homebrew bin"
|
|
missing=1
|
|
fi
|
|
if [ "$RUN_FRONTEND" = true ] && ! command -v flutter &>/dev/null; then
|
|
error "未找到 flutter,请安装 Flutter SDK"
|
|
missing=1
|
|
fi
|
|
[ "$missing" -eq 1 ] && exit 1
|
|
return 0
|
|
}
|
|
|
|
# ── 计算后端源码 hash ──────────────────────────────────────
|
|
backend_hash() {
|
|
# 对所有 .go 文件 + go.mod 内容做 hash
|
|
find "$BACKEND_DIR" -name "*.go" -o -name "go.mod" -o -name "go.sum" \
|
|
| sort \
|
|
| xargs shasum 2>/dev/null \
|
|
| shasum \
|
|
| awk '{print $1}'
|
|
}
|
|
|
|
# ── 检查后端进程是否还活着 ───────────────────────────────
|
|
backend_running() {
|
|
if [ ! -f "$BACKEND_PID_FILE" ]; then return 1; fi
|
|
local pid
|
|
pid=$(cat "$BACKEND_PID_FILE")
|
|
kill -0 "$pid" 2>/dev/null
|
|
}
|
|
|
|
# ── 杀掉占用 8080 的进程 ──────────────────────────────────
|
|
kill_port_8080() {
|
|
local pids
|
|
pids=$(lsof -ti:8080 2>/dev/null || true)
|
|
if [ -n "$pids" ]; then
|
|
warn "端口 8080 被占用,正在清理..."
|
|
echo "$pids" | xargs kill -9 2>/dev/null || true
|
|
sleep 1
|
|
success "端口 8080 已释放"
|
|
fi
|
|
}
|
|
|
|
# ── 等待后端就绪 ──────────────────────────────────────────
|
|
wait_backend() {
|
|
info "等待后端启动..."
|
|
local i=0
|
|
while [ $i -lt 30 ]; do
|
|
if curl -s -o /dev/null http://localhost:8080/api/v1/auth/login 2>/dev/null; then
|
|
success "后端已就绪 → http://localhost:8080"
|
|
return 0
|
|
fi
|
|
sleep 1
|
|
i=$((i + 1))
|
|
done
|
|
warn "后端启动超时,请查看日志:tail -f $BACKEND_LOG"
|
|
}
|
|
|
|
# ── 启动后端 ──────────────────────────────────────────────
|
|
start_backend() {
|
|
local current_hash
|
|
current_hash=$(backend_hash)
|
|
local saved_hash=""
|
|
[ -f "$BACKEND_HASH_FILE" ] && saved_hash=$(cat "$BACKEND_HASH_FILE")
|
|
|
|
# 判断是否需要重启
|
|
if [ "$FORCE" = false ] && backend_running && [ "$current_hash" = "$saved_hash" ]; then
|
|
local pid
|
|
pid=$(cat "$BACKEND_PID_FILE")
|
|
success "后端无改动,跳过重启 (PID $pid) → http://localhost:8080"
|
|
return 0
|
|
fi
|
|
|
|
if backend_running; then
|
|
local pid
|
|
pid=$(cat "$BACKEND_PID_FILE")
|
|
warn "后端代码已变更,重启中 (旧 PID $pid)..."
|
|
kill "$pid" 2>/dev/null || true
|
|
sleep 1
|
|
fi
|
|
|
|
kill_port_8080
|
|
|
|
info "编译并启动后端 (Go)..."
|
|
cd "$BACKEND_DIR"
|
|
go run main.go >>"$BACKEND_LOG" 2>&1 &
|
|
local new_pid=$!
|
|
echo "$new_pid" > "$BACKEND_PID_FILE"
|
|
echo "$current_hash" > "$BACKEND_HASH_FILE"
|
|
info "后端进程 PID=$new_pid,日志:tail -f $BACKEND_LOG"
|
|
wait_backend
|
|
}
|
|
|
|
# ════════════════════════════════════════════════════════
|
|
check_deps
|
|
|
|
if [ "$RUN_BACKEND" = true ]; then
|
|
start_backend
|
|
fi
|
|
|
|
if [ "$RUN_FRONTEND" = true ]; then
|
|
info "启动 Flutter (macOS)..."
|
|
cd "$CLIENT_DIR"
|
|
flutter pub get
|
|
echo ""
|
|
success "Flutter 启动中,窗口将自动弹出..."
|
|
echo -e "${CYAN}提示:关闭 Flutter 窗口或按 q 退出前端,后端继续运行${NC}"
|
|
echo -e "${CYAN} 再次执行 bash scripts/dev.sh run 可复用已有后端${NC}"
|
|
echo ""
|
|
flutter run -d macos
|
|
else
|
|
echo ""
|
|
success "后端运行中,按 Ctrl+C 退出此脚本(后端仍在后台)"
|
|
echo -e " 查看日志:tail -f $BACKEND_LOG"
|
|
wait "$(cat "$BACKEND_PID_FILE")" 2>/dev/null || true
|
|
fi
|