317 lines
11 KiB
Bash
Executable File

#!/bin/bash
# Integrated CRM Application - Automated Build & Deploy Script
# Clones all dependencies, configures database, initializes tables and permissions
set -e
APP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PKGS_DIR="$APP_DIR/pkgs"
GIT_BASE="git@git.opencomputing.cn:yumoqing"
echo "============================================"
echo " Integrated CRM Application Builder"
echo "============================================"
echo ""
# ============================================================
# Step 1: Create required directories
# ============================================================
echo "[1/10] Creating directories..."
mkdir -p "$PKGS_DIR"
mkdir -p "$APP_DIR/logs"
mkdir -p "$APP_DIR/files"
mkdir -p "$APP_DIR/wwwroot"
mkdir -p "$APP_DIR/conf"
# ============================================================
# Step 2: Setup Python virtual environment
# ============================================================
echo "[2/10] Setting up Python virtual environment..."
if [ ! -d "$APP_DIR/py3" ]; then
python3 -m venv "$APP_DIR/py3"
fi
source "$APP_DIR/py3/bin/activate"
pip install --upgrade pip --quiet
# ============================================================
# Step 3: Install core dependencies
# ============================================================
echo "[3/10] Installing core dependencies..."
pip install git+https://git.opencomputing.cn/yumoqing/apppublic --quiet
pip install git+https://git.opencomputing.cn/yumoqing/sqlor --quiet
pip install git+https://git.opencomputing.cn/yumoqing/ahserver --quiet
pip install xls2ddl --quiet
pip install pymysql --quiet
pip install cryptography --quiet
# ============================================================
# Step 4: Clone all modules to pkgs/
# ============================================================
echo "[4/10] Cloning modules to pkgs/..."
REFERENCE_MODULES="apppublic sqlor ahserver appbase rbac"
BUSINESS_MODULES="customer_management opportunity_management contract_management financial_management workflow_approval unified_dashboard"
for module in $REFERENCE_MODULES $BUSINESS_MODULES; do
MOD_DIR="$PKGS_DIR/$module"
if [ -d "$MOD_DIR/.git" ]; then
echo " Pulling latest $module..."
cd "$MOD_DIR" && git pull --quiet 2>/dev/null
else
echo " Cloning $module..."
git clone --quiet "$GIT_BASE/$module.git" "$MOD_DIR"
fi
# Install module
pip install -e "$MOD_DIR" --quiet 2>/dev/null || true
done
cd "$APP_DIR"
# ============================================================
# Step 5: Generate database DDL and CRUD UI
# ============================================================
echo "[5/10] Generating database DDL..."
> "$APP_DIR/integrated_crm_app_schema.sql"
for module in rbac customer_management opportunity_management contract_management financial_management workflow_approval unified_dashboard; do
MOD_DIR="$PKGS_DIR/$module"
if [ -d "$MOD_DIR/models" ]; then
cd "$MOD_DIR/models"
# Generate DDL to a temp file, filter out exception/error lines
TEMP_DDL=$(mktemp)
if ls *.xlsx >/dev/null 2>&1; then
xls2ddl mysql . > "$TEMP_DDL" 2>/dev/null || true
elif ls *.json >/dev/null 2>&1; then
json2ddl mysql . > "$TEMP_DDL" 2>/dev/null || true
fi
# Filter: only keep lines that look like valid SQL (CREATE TABLE, CREATE INDEX, comments, blank lines, semicolons)
if [ -f "$TEMP_DDL" ] && [ -s "$TEMP_DDL" ]; then
grep -v "^Exception:" "$TEMP_DDL" > "$MOD_DIR/mysql.ddl.sql" 2>/dev/null || true
if [ -s "$MOD_DIR/mysql.ddl.sql" ]; then
echo "-- Module: $module" >> "$APP_DIR/integrated_crm_app_schema.sql"
cat "$MOD_DIR/mysql.ddl.sql" >> "$APP_DIR/integrated_crm_app_schema.sql"
echo "" >> "$APP_DIR/integrated_crm_app_schema.sql"
echo " Generated DDL for $module"
else
echo " WARNING: No valid DDL generated for $module"
fi
fi
rm -f "$TEMP_DDL"
fi
done
cd "$APP_DIR"
echo "[5/10] Generating CRUD UI..."
for module in rbac customer_management opportunity_management contract_management financial_management workflow_approval unified_dashboard; do
MOD_DIR="$PKGS_DIR/$module"
if [ -d "$MOD_DIR/json" ] && [ -d "$MOD_DIR/models" ]; then
echo " Generating UI for $module..."
cd "$MOD_DIR/json"
for jsonfile in *.json; do
if [ -f "$jsonfile" ]; then
xls2ui -m ../models -o ../wwwroot "$module" "$jsonfile" 2>/dev/null || true
fi
done
fi
done
cd "$APP_DIR"
# ============================================================
# Step 6: Create wwwroot symbolic links
# ============================================================
echo "[6/10] Creating wwwroot symbolic links..."
for module in rbac customer_management opportunity_management contract_management financial_management workflow_approval unified_dashboard; do
MOD_DIR="$PKGS_DIR/$module"
if [ -d "$MOD_DIR/wwwroot" ]; then
ln -sfn "$MOD_DIR/wwwroot" "$APP_DIR/wwwroot/$module"
echo " Linked wwwroot/$module"
fi
done
# Link bricks framework
if [ -d "$PKGS_DIR/bricks/dist" ]; then
ln -sfn "$PKGS_DIR/bricks/dist" "$APP_DIR/wwwroot/bricks"
elif [ -d "$PKGS_DIR/appbase/wwwroot/bricks" ]; then
ln -sfn "$PKGS_DIR/appbase/wwwroot/bricks" "$APP_DIR/wwwroot/bricks"
fi
# ============================================================
# Step 7: Interactive database configuration
# ============================================================
echo ""
echo "[7/10] Database Configuration"
echo "--------------------------------------------"
read -p " MySQL host [localhost]: " DB_HOST
DB_HOST=${DB_HOST:-localhost}
read -p " MySQL port [3306]: " DB_PORT
DB_PORT=${DB_PORT:-3306}
read -p " MySQL admin user (needs CREATE DATABASE permission) [root]: " DB_ADMIN_USER
DB_ADMIN_USER=${DB_ADMIN_USER:-root}
read -sp " MySQL admin password: " DB_ADMIN_PASS
echo ""
read -p " CRM database name [crm_db]: " DB_NAME
DB_NAME=${DB_NAME:-crm_db}
read -p " CRM database user [hermes]: " DB_USER
DB_USER=${DB_USER:-hermes}
read -sp " CRM database password: " DB_PASS
echo ""
# ============================================================
# Step 8: Create database, import schema, configure app
# ============================================================
echo "[8/10] Initializing database..."
# Create database and user via MySQL admin
mysql -h "$DB_HOST" -P "$DB_PORT" -u "$DB_ADMIN_USER" -p"$DB_ADMIN_PASS" <<EOSQL
CREATE DATABASE IF NOT EXISTS \`$DB_NAME\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS '$DB_USER'@'%' IDENTIFIED BY '$DB_PASS';
GRANT ALL PRIVILEGES ON \`$DB_NAME\`.* TO '$DB_USER'@'%';
FLUSH PRIVILEGES;
EOSQL
echo " Database '$DB_NAME' created."
# Import schema
mysql -h "$DB_HOST" -P "$DB_PORT" -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" < "$APP_DIR/integrated_crm_app_schema.sql"
echo " Schema imported."
# Fix permission table column lengths (rbac xlsx may define shorter lengths)
mysql -h "$DB_HOST" -P "$DB_PORT" -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" <<EOSQL
ALTER TABLE permission MODIFY COLUMN permtype VARCHAR(255) COMMENT '权限类型';
EOSQL
echo " Permission table columns fixed."
# Generate config.json with encrypted password
python3 <<PYEOF
import sys, json
sys.path.insert(0, '$PKGS_DIR/apppublic')
from appPublic.aes import aes_encode_b64
password_key = "!@#\$%^&*(*&^\$QWERTYUIqwertyui234567"
encrypted_pass = aes_encode_b64(password_key, "$DB_PASS")
config = {
"password_key": password_key,
"logger": {
"name": "integrated_crm_app",
"level": "info",
"file": "\$[workdir]\$/logs/app.log"
},
"filesroot": "\$[workdir]\$/files",
"databases": {
"crm_db": {
"driver": "mysql",
"kwargs": {
"host": "$DB_HOST",
"port": $DB_PORT,
"user": "$DB_USER",
"password": encrypted_pass,
"db": "$DB_NAME",
"charset": "utf8mb4"
}
}
},
"website": {
"paths": [
["\$[workdir]\$/wwwroot", "/main"],
["\$[workdir]\$/wwwroot/bricks", "/bricks"]
],
"processors": [
[".ui", "bui"],
[".dspy", "dspy"],
[".tmpl", "tmpl"]
],
"session_max_time": 3600,
"session_issue_time": 1800,
"client_max_size": 10485760
}
}
with open("$APP_DIR/conf/config.json", "w") as f:
json.dump(config, f, indent=2)
print(" config.json generated.")
PYEOF
# ============================================================
# Step 9: Initialize permissions
# ============================================================
echo "[9/10] Initializing permissions..."
cd "$APP_DIR"
python3 -c "
import asyncio, json, sys, os
os.chdir('$APP_DIR')
sys.path.insert(0, '$APP_DIR')
from appPublic.jsonConfig import getConfig
from appPublic.dictObject import DictObject
from sqlor.dbpools import DBPools
config = getConfig('$APP_DIR', {'workdir': '$APP_DIR'})
db_config = {}
for k, v in config.databases.items():
db_config[k] = DictObject(driver=v['driver'], kwargs=DictObject(**v['kwargs']))
DBPools(db_config)
from app.init_permissions import init_permissions_from_config
dbname = list(config.databases.keys())[0]
asyncio.run(init_permissions_from_config(dbname))
"
echo " Permissions initialized."
# ============================================================
# Step 10: Create start/stop scripts
# ============================================================
echo "[10/10] Creating service scripts..."
cat > "$APP_DIR/start.sh" << 'STARTSCRIPT'
#!/bin/bash
APP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$APP_DIR"
source "$APP_DIR/py3/bin/activate"
export PYTHONPATH="$APP_DIR:$PYTHONPATH"
PORT="${1:-8080}"
echo "Starting Integrated CRM Application on port $PORT..."
echo "Access: http://localhost:$PORT/main/login.ui"
python app/integrated_crm_app.py --port "$PORT" --root wwwroot/
STARTSCRIPT
cat > "$APP_DIR/stop.sh" << 'STOPSCRIPT'
#!/bin/bash
pkill -f "integrated_crm_app.py" 2>/dev/null || true
echo "Application stopped."
STOPSCRIPT
chmod +x "$APP_DIR/start.sh" "$APP_DIR/stop.sh"
# ============================================================
# Done
# ============================================================
echo ""
echo "============================================"
echo " Build completed successfully!"
echo "============================================"
echo ""
echo "Next steps:"
echo " 1. Start the application:"
echo " ./start.sh [port] (default: 8080)"
echo ""
echo " 2. Register the first admin user:"
echo " http://localhost:8080/user/register.ui"
echo ""
echo " 3. Assign admin_superuser role to your user:"
echo " mysql -u $DB_USER -p $DB_NAME"
echo " INSERT INTO userroles (userid, roleid) VALUES ('<your_userid>', 'admin_superuser');"
echo ""
echo " 4. Access the application:"
echo " http://localhost:8080/main/login.ui"
echo ""