#!/usr/bin/env bash set -euo pipefail # ============================================================================= # 唤景平台世界模式(scense)一键部署脚本 —— 测试环境 # 部署目录 ~/scense_app,应用端口 9380,数据库 localhost:3306/scense (test/test123) # # 按 web-application-spec 的 8 步完整集成: # 1) 代码导入(git clone 模块到 pkgs/) 2) 依赖安装(pip install -e) # 3) 前端软链 wwwroot/{模块} 4) i18n 合并 # 5) 建表(json2ddl) 6) CRUD 生成(xls2ui) # 7) 初始化数据 8) 运行挂载(load_{模块}) # ============================================================================= APP_NAME="scense" APP_PORT=9380 APP_DIR="$(cd "$(dirname "$0")" && pwd)" DEPLOY_DIR="${DEPLOY_DIR:-$HOME/scense_app}" DB_HOST="${DB_HOST:-localhost}" DB_PORT="${DB_PORT:-3306}" DB_NAME="${DB_NAME:-scense}" DB_USER="${DB_USER:-test}" DB_PASSWORD="${DB_PASSWORD:-test123}" # 基础模块(框架层)与业务模块 FOUNDATION_MODULES="apppublic sqlor ahserver bricks" DB_MODULES="appbase rbac" BUSINESS_MODULES="world scene entity script_engine world_snapshot world_sync" echo "==> [1/8] sync code" mkdir -p "${DEPLOY_DIR}/app" "${DEPLOY_DIR}/conf" "${DEPLOY_DIR}/wwwroot" \ "${DEPLOY_DIR}/files" "${DEPLOY_DIR}/logs" "${DEPLOY_DIR}/pkgs" rsync -avz --delete \ "${APP_DIR}/app/" "${DEPLOY_DIR}/app/" \ "${APP_DIR}/conf/" "${DEPLOY_DIR}/conf/" \ "${APP_DIR}/wwwroot/" "${DEPLOY_DIR}/wwwroot/" \ "${APP_DIR}/scripts/" "${DEPLOY_DIR}/scripts/" echo "==> [2/8] clone + install modules" cd "${DEPLOY_DIR}" mkdir -p pkgs for m in ${FOUNDATION_MODULES} ${DB_MODULES} ${BUSINESS_MODULES}; do if [ ! -d "pkgs/${m}" ]; then git clone "git@git.opencomputing.cn:org/${m}.git" "pkgs/${m}" || \ git clone "https://git.opencomputing.cn/org/${m}.git" "pkgs/${m}" || true fi if [ -d "pkgs/${m}" ]; then (cd "pkgs/${m}" && git pull --ff-only || true) if [ -f "pkgs/${m}/pyproject.toml" ] || [ -f "pkgs/${m}/setup.py" ]; then pip install -e "pkgs/${m}" || true else export PYTHONPATH="${DEPLOY_DIR}/pkgs/${m}:${PYTHONPATH:-}" fi fi done echo "==> [3/8] wwwroot symlinks" for m in ${DB_MODULES} ${BUSINESS_MODULES}; do if [ -d "pkgs/${m}/wwwroot" ]; then ln -sfn "../pkgs/${m}/wwwroot" "wwwroot/${m}" fi done if [ -d "pkgs/bricks/dist" ]; then ln -sfn "../pkgs/bricks/dist" "wwwroot/bricks" fi echo "==> [4/8] i18n merge" mkdir -p wwwroot/i18n/zh wwwroot/i18n/en python - <<'PY' || true import json, os for lang in ("zh", "en"): merged = {} for m in ("apppublic","sqlor","ahserver","appbase","rbac","world","scene","entity","script_engine","world_snapshot","world_sync"): p = f"pkgs/{m}/i18n/{lang}/msg.txt" if os.path.isfile(p): for line in open(p, encoding="utf-8"): line = line.rstrip("\n") if "=" in line: k, v = line.split("=", 1) merged[k.strip()] = v.strip() out = f"wwwroot/i18n/{lang}/i18n.json" os.makedirs(os.path.dirname(out), exist_ok=True) json.dump(merged, open(out, "w", encoding="utf-8"), ensure_ascii=False, indent=2) print("i18n merged") PY echo "==> [5/8] init db (ddl)" mysql -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASSWORD}" \ < "${APP_DIR}/scripts/ddl.sql" echo "==> [6/8] CRUD generate" for m in ${BUSINESS_MODULES}; do if [ -d "pkgs/${m}/json" ] && [ -d "pkgs/${m}/models" ]; then (cd "pkgs/${m}" && xls2ui -m ../models -o "${DEPLOY_DIR}/wwwroot" "${m}" json/*.json || true) fi done echo "==> [7/8] init data" for m in ${BUSINESS_MODULES}; do if [ -d "pkgs/${m}/data" ]; then (cd "pkgs/${m}/data" && for f in *.xlsx; do [ -e "$f" ] && dbloader "${DEPLOY_DIR}" "${DB_NAME}" "$f" || true done) fi done echo "==> [8/8] restart" if [ -f "${DEPLOY_DIR}/run.sh" ]; then bash "${DEPLOY_DIR}/run.sh" restart else echo "warning: run.sh not found, start via: nohup python app/scense.py > logs/scense.log 2>&1 &" fi echo "==> done, app port ${APP_PORT}"