chore: finalize amount migration fixes
This commit is contained in:
+15
-71
@@ -5,7 +5,6 @@ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
COMPOSE_FILE="${ROOT_DIR}/deploy/docker-compose.prod.yml"
|
||||
BACKEND_ENV="${ROOT_DIR}/backend/.env"
|
||||
BACKEND_LOG_DIR="${ROOT_DIR}/backend/logs"
|
||||
MIGRATIONS_DIR="${ROOT_DIR}/backend/migrations"
|
||||
HEALTH_URL="${PROD_HEALTH_URL:-http://127.0.0.1:7890/api/health}"
|
||||
PUBLIC_URL="${PROD_PUBLIC_URL:-http://hfb.221329.cc.cd:7890}"
|
||||
READY_TIMEOUT="${PROD_READY_TIMEOUT:-120}"
|
||||
@@ -62,7 +61,7 @@ show_help() {
|
||||
选项:
|
||||
--no-build 不重新构建镜像,仅启动已有镜像
|
||||
--no-migrate 不执行数据库迁移
|
||||
--reset-db 重置数据库(删除并重建,自动清理旧迁移记录)
|
||||
--reset-db 重置数据库(删除并重建)
|
||||
--logs 部署完成后跟随查看后端日志
|
||||
-h, --help 显示帮助信息
|
||||
|
||||
@@ -196,55 +195,24 @@ wait_service_healthy() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
mysql_exec() {
|
||||
compose exec -T mysql sh -c 'MYSQL_PWD="$MYSQL_PASSWORD" mysql -u"$MYSQL_USER" "$@"' sh "$@"
|
||||
}
|
||||
|
||||
mysql_root_exec() {
|
||||
compose exec -T mysql sh -c 'MYSQL_PWD="$MYSQL_ROOT_PASSWORD" mysql -uroot "$@"' sh "$@"
|
||||
}
|
||||
|
||||
mysql_scalar() {
|
||||
mysql_exec -N -s "$(require_env MYSQL_DATABASE)" -e "$1"
|
||||
}
|
||||
|
||||
ensure_migration_table() {
|
||||
mysql_exec "$(require_env 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
|
||||
}
|
||||
|
||||
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 [[ "${has_legacy}" != "0" ]]; then
|
||||
log_warn "检测到旧的迁移记录,正在清理..."
|
||||
mysql_exec "$(require_env MYSQL_DATABASE)" -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');"
|
||||
log_success "已清理旧迁移记录"
|
||||
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}"
|
||||
}
|
||||
|
||||
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_exec "$(require_env MYSQL_DATABASE)" -e \
|
||||
"INSERT IGNORE INTO schema_migrations (version) VALUES ('${version}');"
|
||||
done
|
||||
shopt -u nullglob
|
||||
fi
|
||||
goose_cmd() {
|
||||
compose run --rm --no-deps backend /app/goose -dir /app/migrations mysql "$(goose_dsn "$(require_env MYSQL_DSN)")" "$@"
|
||||
}
|
||||
|
||||
reset_database() {
|
||||
@@ -259,7 +227,7 @@ reset_database() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_warn "重置数据库 ${database}(会清理旧迁移记录)..."
|
||||
log_warn "重置数据库 ${database}..."
|
||||
mysql_root_exec -e \
|
||||
"DROP DATABASE IF EXISTS \`${database}\`; CREATE DATABASE \`${database}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
||||
log_success "数据库已重建"
|
||||
@@ -271,32 +239,8 @@ 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
|
||||
shopt -s nullglob
|
||||
for file in "${MIGRATIONS_DIR}"/*.sql; do
|
||||
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_exec "$(require_env MYSQL_DATABASE)" < "${file}"
|
||||
mysql_exec "$(require_env MYSQL_DATABASE)" -e \
|
||||
"INSERT INTO schema_migrations (version) VALUES ('${version}');"
|
||||
done
|
||||
shopt -u nullglob
|
||||
|
||||
log "使用 goose 执行数据库迁移..."
|
||||
goose_cmd up
|
||||
log_success "数据库迁移完成"
|
||||
}
|
||||
|
||||
|
||||
+37
-73
@@ -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() {
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
#!/bin/bash
|
||||
# 前端金额字段批量替换脚本
|
||||
|
||||
echo "开始批量替换前端金额字段..."
|
||||
|
||||
# 进入前端目录
|
||||
cd /Users/yml/codes/hfb_sys/frontend/src
|
||||
|
||||
# 1. 替换 API 类型定义中的字段名
|
||||
echo "1. 替换 API 类型定义..."
|
||||
|
||||
# Wallet 相关
|
||||
find . -name "*.ts" -type f -exec sed -i '' 's/available_balance:/available_balance_cent:/g' {} +
|
||||
find . -name "*.ts" -type f -exec sed -i '' 's/frozen_balance:/frozen_balance_cent:/g' {} +
|
||||
|
||||
# Ledger 相关
|
||||
find . -name "*.ts" -type f -exec sed -i '' 's/\bamount:/amount_cent:/g' {} +
|
||||
find . -name "*.ts" -type f -exec sed -i '' 's/balance_after:/balance_after_cent:/g' {} +
|
||||
|
||||
# Order 相关
|
||||
find . -name "*.ts" -type f -exec sed -i '' 's/display_amount:/display_amount_cent:/g' {} +
|
||||
find . -name "*.ts" -type f -exec sed -i '' 's/rent_amount:/rent_amount_cent:/g' {} +
|
||||
find . -name "*.ts" -type f -exec sed -i '' 's/owner_rent_amount:/owner_rent_amount_cent:/g' {} +
|
||||
find . -name "*.ts" -type f -exec sed -i '' 's/deposit_amount:/deposit_amount_cent:/g' {} +
|
||||
find . -name "*.ts" -type f -exec sed -i '' 's/platform_fee:/platform_fee_cent:/g' {} +
|
||||
|
||||
# Listing 相关
|
||||
find . -name "*.ts" -type f -exec sed -i '' 's/\bprice:/price_cent:/g' {} +
|
||||
|
||||
# 2. 替换 Vue 模板中的字段名
|
||||
echo "2. 替换 Vue 模板中的字段..."
|
||||
|
||||
find . -name "*.vue" -type f -exec sed -i '' 's/\.available_balance/.available_balance_cent/g' +
|
||||
find . -name "*.vue" -type f -exec sed -i '' 's/\.frozen_balance/.frozen_balance_cent/g' {} +
|
||||
find . -name "*.vue" -type f -exec sed -i '' 's/\.amount/.amount_cent/g' {} +
|
||||
find . -name "*.vue" -type f -exec sed -i '' 's/\.balance_after/.balance_after_cent/g' {} +
|
||||
find . -name "*.vue" -type f -exec sed -i '' 's/\.price/.price_cent/g' {} +
|
||||
find . -name "*.vue" -type f -exec sed -i '' 's/\.deposit_amount/.deposit_amount_cent/g' {} +
|
||||
|
||||
# 3. 替换函数调用
|
||||
echo "3. 替换函数调用..."
|
||||
|
||||
find . -name "*.vue" -type f -exec sed -i '' 's/formatMoney(/formatCent(/g' {} +
|
||||
find . -name "*.vue" -type f -exec sed -i '' 's/formatMoneyWithSymbol(/formatCentWithSymbol(/g' {} +
|
||||
|
||||
echo "批量替换完成!"
|
||||
echo "请手动检查并修复可能的错误替换。"
|
||||
Reference in New Issue
Block a user