chore: finalize amount migration fixes

This commit is contained in:
yml
2026-06-09 17:45:29 +08:00
parent 38c0ba69dc
commit 87673288ef
16 changed files with 214 additions and 2327 deletions
+37 -73
View File
@@ -19,6 +19,8 @@ FRONTEND_HEALTH_URL="${DEV_FRONTEND_HEALTH_URL:-http://127.0.0.1:${FRONTEND_PORT
HTTP_READY_TIMEOUT="${DEV_HTTP_READY_TIMEOUT:-120}"
AUTO_KILL_PORTS="${DEV_AUTO_KILL_PORTS:-1}"
FORCE_NPM_CI="${DEV_FORCE_NPM_CI:-0}"
GOOSE_VERSION="${GOOSE_VERSION:-v3.27.1}"
GOOSE_BIN="${GOOSE_BIN:-}"
BACKEND_PID=""
FRONTEND_PID=""
@@ -59,7 +61,7 @@ show_help() {
用法: ./scripts/dev.sh [选项]
选项:
--reset-db 重置数据库(删除并重建,自动清理旧迁移记录
--reset-db 重置数据库(删除并重建)
--seed-only 仅重新同步基础数据
--no-migrate 不执行数据库迁移
--no-frontend 不启动前端
@@ -378,14 +380,6 @@ mysql_root() {
docker exec -i -e MYSQL_PWD=rootsecret hfb-mysql mysql -uroot "$@"
}
mysql_hfb() {
docker exec -i -e MYSQL_PWD=secret hfb-mysql mysql -uhfb "$@"
}
mysql_scalar() {
mysql_hfb --default-character-set=utf8mb4 -N -s -e "$1" "${MYSQL_DATABASE}"
}
validate_database_name() {
if [[ ! "${MYSQL_DATABASE}" =~ ^[A-Za-z0-9_]+$ ]]; then
log_error "DEV_MYSQL_DATABASE 只能包含字母、数字和下划线,当前值:${MYSQL_DATABASE}"
@@ -404,43 +398,42 @@ reset_database() {
log_success "数据库已重建"
}
ensure_migration_table() {
mysql_hfb --default-character-set=utf8mb4 "${MYSQL_DATABASE}" <<'SQL'
CREATE TABLE IF NOT EXISTS schema_migrations (
version VARCHAR(255) PRIMARY KEY,
applied_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
SQL
}
ensure_goose() {
if [[ -z "${GOOSE_BIN}" ]]; then
GOOSE_BIN="$(command -v goose || true)"
fi
clean_legacy_migrations() {
local has_legacy
has_legacy="$(mysql_scalar "SELECT COUNT(*) FROM schema_migrations WHERE version IN ('000002_payment_refund_schema', '000003_add_indexes', '000004_add_support_status', '000005_add_announcements', '000006_insert_sample_announcements', '000007_add_announcement_permissions', '000008_fix_announcement_charset', '000002_add_withdrawal_tables', '000003_add_encrypted_realname_fields');")"
if [[ -z "${GOOSE_BIN}" ]]; then
need_cmd go
log "未找到 goose,正在安装 ${GOOSE_VERSION}..."
(cd "${ROOT_DIR}/backend" && go install "github.com/pressly/goose/v3/cmd/goose@${GOOSE_VERSION}")
GOOSE_BIN="$(go env GOPATH)/bin/goose"
fi
if [[ "${has_legacy}" != "0" ]]; then
log_warn "检测到旧的迁移记录,正在清理..."
mysql_hfb --default-character-set=utf8mb4 -e \
"DELETE FROM schema_migrations WHERE version IN ('000002_payment_refund_schema', '000003_add_indexes', '000004_add_support_status', '000005_add_announcements', '000006_insert_sample_announcements', '000007_add_announcement_permissions', '000008_fix_announcement_charset', '000002_add_withdrawal_tables', '000003_add_encrypted_realname_fields');" "${MYSQL_DATABASE}"
log_success "已清理旧迁移记录"
if [[ ! -x "${GOOSE_BIN}" ]]; then
log_error "goose 不可执行:${GOOSE_BIN}"
exit 1
fi
}
bootstrap_existing_schema_history() {
local migration_count users_exists
migration_count="$(mysql_scalar "SELECT COUNT(*) FROM schema_migrations;")"
users_exists="$(mysql_scalar "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'users';")"
if [[ "${migration_count}" == "0" && "${users_exists}" != "0" ]]; then
log_warn "检测到已有表结构但没有迁移记录,补记当前所有迁移文件为已应用"
local file version
shopt -s nullglob
for file in "${MIGRATIONS_DIR}"/*.sql; do
version="$(basename "${file}" .sql)"
mysql_hfb --default-character-set=utf8mb4 -e \
"INSERT IGNORE INTO schema_migrations (version) VALUES ('${version}');" "${MYSQL_DATABASE}"
done
shopt -u nullglob
goose_dsn() {
local dsn="$1"
if [[ "${dsn}" != *"multiStatements="* ]]; then
if [[ "${dsn}" == *"?"* ]]; then
dsn="${dsn}&multiStatements=true"
else
dsn="${dsn}?multiStatements=true"
fi
fi
printf "%s" "${dsn}"
}
dev_goose_dsn() {
goose_dsn "hfb:secret@tcp(127.0.0.1:3306)/${MYSQL_DATABASE}?charset=utf8mb4&parseTime=True&loc=Local"
}
goose_cmd() {
"${GOOSE_BIN}" -dir "${MIGRATIONS_DIR}" mysql "$(dev_goose_dsn)" "$@"
}
run_migrations() {
@@ -449,39 +442,10 @@ run_migrations() {
return 0
fi
log "自动发现并执行数据库迁移..."
ensure_migration_table
bootstrap_existing_schema_history
# 只有在数据库未重置的情况下才需要清理旧迁移记录
if [[ "${RESET_DB}" != "1" ]]; then
clean_legacy_migrations
fi
local file version applied
local found=0
shopt -s nullglob
for file in "${MIGRATIONS_DIR}"/*.sql; do
found=1
version="$(basename "${file}" .sql)"
applied="$(mysql_scalar "SELECT COUNT(*) FROM schema_migrations WHERE version = '${version}';")"
if [[ "${applied}" != "0" ]]; then
log "跳过已应用迁移:${version}"
continue
fi
log "执行迁移:${version}"
mysql_hfb --default-character-set=utf8mb4 "${MYSQL_DATABASE}" < "${file}"
mysql_hfb --default-character-set=utf8mb4 -e \
"INSERT INTO schema_migrations (version) VALUES ('${version}');" "${MYSQL_DATABASE}"
done
shopt -u nullglob
if [[ "${found}" == "0" ]]; then
log_warn "未发现迁移文件:${MIGRATIONS_DIR}/*.sql"
else
log_success "数据库迁移完成"
fi
ensure_goose
log "使用 goose 执行数据库迁移..."
goose_cmd up
log_success "数据库迁移完成"
}
load_env_file() {