- Clone all reference and business modules to pkgs/ - Interactive DB config (host, port, user, password) - Auto-create database, import schema, encrypt password in config.json - Auto-run permission initialization - Generate start.sh/stop.sh
302 lines
10 KiB
Bash
Executable File
302 lines
10 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"
|
|
if ls *.xlsx >/dev/null 2>&1; then
|
|
xls2ddl mysql . > "$MOD_DIR/mysql.ddl.sql" 2>/dev/null || true
|
|
elif ls *.json >/dev/null 2>&1; then
|
|
json2ddl mysql . > "$MOD_DIR/mysql.ddl.sql" 2>/dev/null || true
|
|
fi
|
|
if [ -f "$MOD_DIR/mysql.ddl.sql" ] && [ -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"
|
|
fi
|
|
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."
|
|
|
|
# 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 ""
|