Merge branch 'dev'

# Conflicts:
#	backend/internal/modules/payment/payment_start.go
#	deploy/docker-compose.dev.yml
#	frontend/src/features/admin/AdminPaymentsPage.tsx
#	scripts/dev.sh
This commit is contained in:
yml
2026-11-12 22:56:13 +08:00
550 changed files with 147390 additions and 1387 deletions
+80 -8
View File
@@ -10,6 +10,10 @@ FRONTEND_PACKAGE_JSON="${FRONTEND_DIR}/package.json"
FRONTEND_PACKAGE_LOCK="${FRONTEND_DIR}/package-lock.json"
FRONTEND_NODE_MODULES="${FRONTEND_DIR}/node_modules"
FRONTEND_NODE_MODULES_LOCK="${FRONTEND_NODE_MODULES}/.package-lock.json"
ADMIN_WEB_DIR="${ROOT_DIR}/admin-web"
ADMIN_WEB_PACKAGE_LOCK="${ADMIN_WEB_DIR}/package-lock.json"
ADMIN_WEB_NODE_MODULES="${ADMIN_WEB_DIR}/node_modules"
ADMIN_WEB_NODE_MODULES_LOCK="${ADMIN_WEB_NODE_MODULES}/.package-lock.json"
DISTRIBUTION_DIR="${ROOT_DIR}/distribution-admin"
DISTRIBUTION_PACKAGE_JSON="${DISTRIBUTION_DIR}/package.json"
DISTRIBUTION_PACKAGE_LOCK="${DISTRIBUTION_DIR}/package-lock.json"
@@ -19,6 +23,7 @@ MIGRATIONS_DIR="${ROOT_DIR}/backend/migrations"
MYSQL_DATABASE="${DEV_MYSQL_DATABASE:-hfb_jysh}"
BACKEND_PORT="${DEV_BACKEND_PORT:-18089}"
FRONTEND_PORT="${DEV_FRONTEND_PORT:-5289}"
ADMIN_WEB_PORT="${DEV_ADMIN_WEB_PORT:-5292}"
DISTRIBUTION_PORT="${DEV_DISTRIBUTION_PORT:-5290}"
DISTRIBUTION_STOREFRONT_PORT="${DEV_DISTRIBUTION_STOREFRONT_PORT:-5291}"
DISTRIBUTION_STOREFRONT_SITE_CODE="${DEV_DISTRIBUTION_STOREFRONT_SITE_CODE:-test_1}"
@@ -28,6 +33,7 @@ MINIO_API_PORT="${DEV_MINIO_API_PORT:-29090}"
MINIO_CONSOLE_PORT="${DEV_MINIO_CONSOLE_PORT:-29091}"
BACKEND_HEALTH_URL="${DEV_BACKEND_HEALTH_URL:-http://127.0.0.1:${BACKEND_PORT}/health}"
FRONTEND_HEALTH_URL="${DEV_FRONTEND_HEALTH_URL:-http://127.0.0.1:${FRONTEND_PORT}/}"
ADMIN_WEB_HEALTH_URL="${DEV_ADMIN_WEB_HEALTH_URL:-http://127.0.0.1:${ADMIN_WEB_PORT}${VITE_ADMIN_BASE_PATH:-/console-jy8k3m}/login}"
DISTRIBUTION_HEALTH_URL="${DEV_DISTRIBUTION_HEALTH_URL:-http://127.0.0.1:${DISTRIBUTION_PORT}/}"
DISTRIBUTION_STOREFRONT_HEALTH_URL="${DEV_DISTRIBUTION_STOREFRONT_HEALTH_URL:-http://127.0.0.1:${DISTRIBUTION_STOREFRONT_PORT}/}"
HTTP_READY_TIMEOUT="${DEV_HTTP_READY_TIMEOUT:-120}"
@@ -35,6 +41,7 @@ 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:-}"
GOOSE_GOPROXY="${GOOSE_GOPROXY:-https://goproxy.cn,direct}"
# 国内网络通常无法稳定访问 proxy.golang.org;显式导出的 GOPROXY 优先。
if [[ -z "${GOPROXY:-}" ]]; then
@@ -43,6 +50,7 @@ fi
BACKEND_PID=""
FRONTEND_PID=""
ADMIN_WEB_PID=""
DISTRIBUTION_PID=""
DISTRIBUTION_STOREFRONT_PID=""
CLEANED_UP=0
@@ -85,6 +93,7 @@ show_help() {
--reset-db 重置数据库(删除并重建)
--no-migrate 不执行数据库迁移
--no-frontend 不启动主站前端
--no-admin 不启动独立管理端
--no-backend 不启动后端
--no-distribution 不启动分销后台
--no-distribution-storefront
@@ -99,6 +108,8 @@ show_help() {
后端启动端口
DEV_FRONTEND_PORT=5289
主站前端启动端口
DEV_ADMIN_WEB_PORT=5292
独立管理端启动端口
DEV_DISTRIBUTION_PORT=5290
分销后台启动端口
DEV_MYSQL_PORT=23306
@@ -113,6 +124,8 @@ show_help() {
后端健康检查地址
DEV_FRONTEND_HEALTH_URL=http://127.0.0.1:5289/
主站前端健康检查地址
DEV_ADMIN_WEB_HEALTH_URL=http://127.0.0.1:5292/console-jy8k3m/login
独立管理端健康检查地址
DEV_DISTRIBUTION_HEALTH_URL=http://127.0.0.1:5290/
分销后台健康检查地址
DEV_HTTP_READY_TIMEOUT=120
@@ -123,6 +136,8 @@ show_help() {
强制重新执行前端 npm ci
DEV_GOPROXY=https://goproxy.cn,direct
未显式设置 GOPROXY 时使用的 Go 模块代理
GOOSE_GOPROXY=https://goproxy.cn,direct
Goose 安装失败时使用的 Go 模块代理
示例:
./scripts/dev.sh # 正常启动(后端 + 主前后台 + 分销前台)
@@ -135,6 +150,7 @@ EOF
RESET_DB="${DEV_RESET_DB:-0}"
NO_MIGRATE=0
NO_FRONTEND=0
NO_ADMIN_WEB=0
NO_BACKEND=0
NO_DISTRIBUTION=0
NO_DISTRIBUTION_STOREFRONT=0
@@ -153,6 +169,10 @@ while [[ $# -gt 0 ]]; do
NO_FRONTEND=1
shift
;;
--no-admin)
NO_ADMIN_WEB=1
shift
;;
--no-backend)
NO_BACKEND=1
shift
@@ -181,7 +201,7 @@ cleanup() {
fi
CLEANED_UP=1
if [[ -z "${FRONTEND_PID}" && -z "${BACKEND_PID}" && -z "${DISTRIBUTION_PID}" && -z "${DISTRIBUTION_STOREFRONT_PID}" ]]; then
if [[ -z "${FRONTEND_PID}" && -z "${ADMIN_WEB_PID}" && -z "${BACKEND_PID}" && -z "${DISTRIBUTION_PID}" && -z "${DISTRIBUTION_STOREFRONT_PID}" ]]; then
return
fi
@@ -192,6 +212,9 @@ cleanup() {
if [[ -n "${DISTRIBUTION_PID}" ]] && kill -0 "${DISTRIBUTION_PID}" >/dev/null 2>&1; then
kill "${DISTRIBUTION_PID}" >/dev/null 2>&1 || true
fi
if [[ -n "${ADMIN_WEB_PID}" ]] && kill -0 "${ADMIN_WEB_PID}" >/dev/null 2>&1; then
kill "${ADMIN_WEB_PID}" >/dev/null 2>&1 || true
fi
if [[ -n "${FRONTEND_PID}" ]] && kill -0 "${FRONTEND_PID}" >/dev/null 2>&1; then
kill "${FRONTEND_PID}" >/dev/null 2>&1 || true
fi
@@ -453,7 +476,10 @@ ensure_goose() {
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}")
if ! (cd "${ROOT_DIR}/backend" && go install "github.com/pressly/goose/v3/cmd/goose@${GOOSE_VERSION}"); then
log_warn "默认 Go 模块代理不可用,改用 ${GOOSE_GOPROXY} 重试..."
(cd "${ROOT_DIR}/backend" && GOPROXY="${GOOSE_GOPROXY}" go install "github.com/pressly/goose/v3/cmd/goose@${GOOSE_VERSION}")
fi
GOOSE_BIN="$(go env GOPATH)/bin/goose"
fi
@@ -582,6 +608,40 @@ start_frontend() {
FRONTEND_PID="$!"
}
ensure_admin_web_dependencies() {
if [[ ! -f "${ADMIN_WEB_PACKAGE_LOCK}" ]]; then
log_error "缺少 admin-web/package-lock.json,无法执行 npm ci"
exit 1
fi
if [[ "${FORCE_NPM_CI}" == "1" || ! -d "${ADMIN_WEB_NODE_MODULES}" || ! -f "${ADMIN_WEB_NODE_MODULES_LOCK}" ]]; then
log "同步管理端依赖(npm ci)..."
(
cd "${ADMIN_WEB_DIR}"
npm ci
)
log_success "管理端依赖已同步"
else
log "管理端依赖已同步,跳过 npm ci"
fi
}
start_admin_web() {
ensure_admin_web_dependencies
log "启动独立管理端:http://localhost:${ADMIN_WEB_PORT}${VITE_ADMIN_BASE_PATH:-/console-jy8k3m}/login"
(
cd "${ADMIN_WEB_DIR}"
export PORT="${ADMIN_WEB_PORT}"
export DEV_FRONTEND_PORT="${ADMIN_WEB_PORT}"
export DEV_BACKEND_PORT="${BACKEND_PORT}"
export VITE_ADMIN_BASE_PATH="${VITE_ADMIN_BASE_PATH:-/console-jy8k3m}"
export VITE_API_PROXY_TARGET="${VITE_API_PROXY_TARGET:-http://127.0.0.1:${BACKEND_PORT}}"
npm run dev
) &
ADMIN_WEB_PID="$!"
}
distribution_dependencies_need_ci() {
if [[ "${FORCE_NPM_CI}" == "1" ]]; then
return 0
@@ -667,6 +727,11 @@ watch_processes() {
printf "主站前端进程已退出\n" >&2
exit 1
fi
if [[ -n "${ADMIN_WEB_PID}" ]] && ! kill -0 "${ADMIN_WEB_PID}" >/dev/null 2>&1; then
wait "${ADMIN_WEB_PID}" || true
printf "管理端进程已退出\n" >&2
exit 1
fi
if [[ -n "${DISTRIBUTION_PID}" ]] && ! kill -0 "${DISTRIBUTION_PID}" >/dev/null 2>&1; then
wait "${DISTRIBUTION_PID}" || true
printf "分销后台进程已退出\n" >&2
@@ -686,10 +751,10 @@ main() {
if [[ "${NO_BACKEND}" == "0" ]]; then
need_cmd go
fi
if [[ "${NO_FRONTEND}" == "0" || "${NO_DISTRIBUTION}" == "0" ]]; then
if [[ "${NO_FRONTEND}" == "0" || "${NO_ADMIN_WEB}" == "0" || "${NO_DISTRIBUTION}" == "0" ]]; then
need_cmd npm
fi
if [[ "${NO_BACKEND}" == "0" || "${NO_FRONTEND}" == "0" || "${NO_DISTRIBUTION}" == "0" ]]; then
if [[ "${NO_BACKEND}" == "0" || "${NO_FRONTEND}" == "0" || "${NO_ADMIN_WEB}" == "0" || "${NO_DISTRIBUTION}" == "0" ]]; then
need_cmd curl
fi
@@ -733,6 +798,12 @@ main() {
wait_http_ready "${FRONTEND_HEALTH_URL}" "主站前端" "${FRONTEND_PID}"
fi
if [[ "${NO_ADMIN_WEB}" == "0" && -d "${ADMIN_WEB_DIR}" ]]; then
ensure_port_free "${ADMIN_WEB_PORT}" "管理端"
start_admin_web
wait_http_ready "${ADMIN_WEB_HEALTH_URL}" "管理端" "${ADMIN_WEB_PID}"
fi
if [[ "${NO_DISTRIBUTION}" == "0" && -d "${DISTRIBUTION_DIR}" ]]; then
ensure_port_free "${DISTRIBUTION_PORT}" "分销后台"
start_distribution
@@ -745,16 +816,17 @@ main() {
wait_http_ready "${DISTRIBUTION_STOREFRONT_HEALTH_URL}" "分销前台" "${DISTRIBUTION_STOREFRONT_PID}"
fi
if [[ -z "${BACKEND_PID}" && -z "${FRONTEND_PID}" && -z "${DISTRIBUTION_PID}" && -z "${DISTRIBUTION_STOREFRONT_PID}" ]]; then
log "仅启动 Docker 开发依赖,前后端与分销端未启动"
if [[ -z "${BACKEND_PID}" && -z "${FRONTEND_PID}" && -z "${ADMIN_WEB_PID}" && -z "${DISTRIBUTION_PID}" && -z "${DISTRIBUTION_STOREFRONT_PID}" ]]; then
log "仅启动 Docker 开发依赖,前端、管理端、后端与分销端未启动"
return 0
fi
log_success "开发环境已就绪"
if [[ "${NO_FRONTEND}" == "0" ]]; then
local admin_base_path="${VITE_ADMIN_BASE_PATH:-/admin}"
log "主站前台:http://localhost:${FRONTEND_PORT}"
log "主站后台:http://localhost:${FRONTEND_PORT}${admin_base_path%/}/login"
fi
if [[ "${NO_ADMIN_WEB}" == "0" && -d "${ADMIN_WEB_DIR}" ]]; then
log "管理端:http://localhost:${ADMIN_WEB_PORT}${VITE_ADMIN_BASE_PATH:-/console-jy8k3m}/login"
fi
if [[ "${NO_DISTRIBUTION}" == "0" && -d "${DISTRIBUTION_DIR}" ]]; then
log "分销后台:http://localhost:${DISTRIBUTION_PORT}"