diff --git a/.env.example b/.env.example deleted file mode 100644 index e312b838..00000000 --- a/.env.example +++ /dev/null @@ -1,26 +0,0 @@ -PROJECT_NAME="SQLBot" -# Backend -BACKEND_CORS_ORIGINS="http://localhost,http://localhost:5173,https://localhost,https://localhost:5173" -SECRET_KEY=y5txe1mRmS_JpOrUzFzHEu-kIQn3lf7ll0AOv9DQh0s - -TOKEN_KEY="X-SQLBOT-TOKEN" -DEFAULT_PWD="SQLBot@123456" -ASSISTANT_TOKEN_KEY="X-SQLBOT-ASSISTANT-TOKEN" - -LOG_LEVEL="INFO" # DEBUG, INFO, WARNING, ERROR -LOG_DIR="/opt/sqlbot/logs" -LOG_FORMAT="%(asctime)s - %(name)s - %(levelname)s:%(lineno)d - %(message)s" -SQL_DEBUG=False - -CACHE_TYPE="memory" - -# Postgres -POSTGRES_SERVER=localhost -POSTGRES_PORT=5432 -POSTGRES_DB=sqlbot -POSTGRES_USER=root -POSTGRES_PASSWORD=132456 # Change this to your pwd - -MCP_IMAGE_PATH=/opt/sqlbot/images -MCP_IMAGE_HOST=http://localhost:3000 -SERVER_IMAGE_HOST=https://sqlbot.fit2cloud.cn/images/ diff --git a/docker-compose.yaml b/docker-compose.yaml index d212c54e..0667984b 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -19,19 +19,13 @@ services: PROJECT_NAME: "SQLBot" DEFAULT_PWD: "SQLBot@123456" # MCP settings - MCP_IMAGE_PATH: /opt/sqlbot/images - MCP_IMAGE_HOST: http://localhost:3000 - SERVER_IMAGE_HOST: https://sqlbot.fit2cloud.cn/images/ + SERVER_IMAGE_HOST: https://YOUR_SERVE_IP:MCP_PORT/images/ # Auth & Security - TOKEN_KEY: "X-SQLBOT-TOKEN" - ASSISTANT_TOKEN_KEY: "X-SQLBOT-ASSISTANT-TOKEN" SECRET_KEY: y5txe1mRmS_JpOrUzFzHEu-kIQn3lf7ll0AOv9DQh0s # CORS settings BACKEND_CORS_ORIGINS: "http://localhost,http://localhost:5173,https://localhost,https://localhost:5173" # Logging LOG_LEVEL: "INFO" - LOG_DIR: "/opt/sqlbot/logs" - LOG_FORMAT: "%(asctime)s - %(name)s - %(levelname)s:%(lineno)d - %(message)s" SQL_DEBUG: False volumes: - ./data/sqlbot/excel:/opt/sqlbot/data/excel diff --git a/installer/docker-compose-pg.yml b/installer/docker-compose-pg.yml new file mode 100644 index 00000000..7cbd5220 --- /dev/null +++ b/installer/docker-compose-pg.yml @@ -0,0 +1,16 @@ +services: + sqlbot-db: + image: registry.cn-qingdao.aliyuncs.com/dataease/postgres:17.5 + container_name: sqlbot-db + restart: always + networks: + - sqlbot-network + volumes: + - ./data/postgresql:/var/lib/postgresql/data + env_file: + - conf/sqlbot.conf + healthcheck: + test: ["CMD-SHELL", "pg_isready"] + interval: 3s + timeout: 5s + retries: 5 diff --git a/installer/docker-compose.yaml b/installer/docker-compose.yaml new file mode 100644 index 00000000..e90d2db0 --- /dev/null +++ b/installer/docker-compose.yaml @@ -0,0 +1,22 @@ +services: + sqlbot: + image: registry.cn-qingdao.aliyuncs.com/dataease/sqlbot:v0.9.5 + container_name: sqlbot + restart: always + networks: + - sqlbot-network + ports: + - ${SQLBOT_WEB_PORT}:8000 + - ${SQLBOT_MCP_PORT}:8001 + env_file: + - conf/sqlbot.conf + volumes: + - ./data/sqlbot/excel:/opt/sqlbot/data/excel + - ./data/sqlbot/images:/opt/sqlbot/images + - ./data/sqlbot/logs:/opt/sqlbot/logs + depends_on: + sqlbot-db: + condition: service_healthy + +networks: + sqlbot-network: diff --git a/installer/install.conf b/installer/install.conf new file mode 100644 index 00000000..0146ef90 --- /dev/null +++ b/installer/install.conf @@ -0,0 +1,34 @@ +# 基础配置 +## 安装目录 +SQLBOT_BASE=/opt +## SQLBot 端口 +SQLBOT_WEB_PORT=8000 +SQLBOT_MCP_PORT=8001 + +# 数据库配置 +## 是否使用外部数据库 +SQLBOT_EXTERNAL_DB=false +## 数据库地址 +SQLBOT_DB_HOST=sqlbot-db +## 数据库端口 (仅使用外部数据库时才生效) +SQLBOT_DB_PORT=5432 +## SQLBot 数据库库名 +SQLBOT_DB_DB=sqlbot +## 数据库用户名 +SQLBOT_DB_USER=root +## 数据库密码,密码如包含特殊字符,请用双引号引起来,例如 SQLBOT_DB_PASSWORD="Test@4&^%*^" +SQLBOT_DB_PASSWORD=Password123@pg + +# 其他配置 +## 普通用户默认密码 +SQLBOT_DEFAULT_PWD=SQLBot@123456 +## SQLBot Secret Key +SQLBOT_SECRET_KEY=y5txe1mRmS_JpOrUzFzHEu-kIQn3lf7ll0AOv9DQh0s +## Cross-Origin Resource Sharing (CORS) 设置 +SQLBOT_CORS_ORIGINS=http://localhost,http://localhost:5173,https://localhost,https://localhost:5173 +## 日志级别 DEBUG, INFO, WARNING, ERROR +SQLBOT_LOG_LEVEL="INFO" +## 缓存类型 +SQLBOT_CACHE_TYPE="memory" +## MCP 图片存储路径 +SQLBOT_SERVER_IMAGE_HOST=https://YOUR_SERVER_IP:MCP_PORT/images/ \ No newline at end of file diff --git a/installer/install.sh b/installer/install.sh new file mode 100644 index 00000000..dd73d867 --- /dev/null +++ b/installer/install.sh @@ -0,0 +1,284 @@ +#!/bin/bash + +INSTALL_TYPE='install' +title_count=1 + +CURRENT_DIR=$( + cd "$(dirname "$0")" + pwd +) + +function log() { + echo -e "${1}" 2>&1 | tee -a ${CURRENT_DIR}/install.log +} + +function log_title () { + log "${title_count}. ${1}" + let title_count++ +} + +function log_content () { + log "\t${1}" +} + +function check_and_prepare_env_params() { + log "当前时间 : $(date)" + log_title "检查安装环境并初始化环境变量" + + cd ${CURRENT_DIR} + if [ -f /usr/bin/sctl ]; then + echo "当前版本: $(sctl version | head -n 1)" + + # 获取已安装的 SQLBOT 的运行目录 + SQLBOT_BASE=$(grep "^SQLBOT_BASE=" /usr/bin/sctl | cut -d'=' -f2) + SQLBOT_BASE_OLD=${SQLBOT_BASE} + sed -i -e "s#SQLBOT_BASE=.*#SQLBOT_BASE_BASE=${SQLBOT_BASE}#g" sctl + \cp sctl /usr/local/bin && chmod +x /usr/local/bin/sctl + + log_content "停止 SQLBot 服务" + sctl stop + + INSTALL_TYPE='upgrade' + fi + + set -a + source ${CURRENT_DIR}/install.conf + if [[ ${SQLBOT_BASE_OLD} ]];then + SQLBOT_BASE=${SQLBOT_BASE_OLD} + export SQLBOT_BASE=${SQLBOT_BASE_OLD} + fi + if [[ -d ${SQLBOT_BASE} ]] && [[ -f ${SQLBOT_BASE}/sqlbot/.env ]]; then + source $SQLBOT_BASE/sqlbot/.env + INSTALL_TYPE='upgrade' + log_content "升级安装" + else + INSTALL_TYPE='install' + mkdir -p ${SQLBOT_BASE} + log_content "全新安装" + fi + set +a +} + +function set_run_base_path() { + log_title "设置运行目录" + SQLBOT_RUN_BASE=$SQLBOT_BASE/sqlbot + CONF_FOLDER=${SQLBOT_RUN_BASE}/conf + TEMPLATES_FOLDER=${SQLBOT_RUN_BASE}/templates + log_content "运行目录 $SQLBOT_RUN_BASE" + log_content "配置文件目录 $CONF_FOLDER" +} + +function prepare_sqlbot_run_base() { + log_title "初始化运行目录" + cd ${CURRENT_DIR} + mkdir -p ${SQLBOT_RUN_BASE} + log_content "复制安装文件到运行目录" + cp -r ./sqlbot/* ${SQLBOT_RUN_BASE}/ + + cd ${SQLBOT_RUN_BASE} + env | grep SQLBOT_ >.env + + mkdir -p ${SQLBOT_RUN_BASE}/conf + mkdir -p ${SQLBOT_RUN_BASE}/data/sqlbot/{excel,images,logs} + + if [ "${SQLBOT_EXTERNAL_DB}" = "false" ]; then + mkdir -p ${SQLBOT_RUN_BASE}/data/postgresql + export SQLBOT_DB_PORT=5432 + else + sed -i -e "/^ depends_on/,+2d" docker-compose.yml + fi + + log_content "调整配置文件参数" + cd ${SQLBOT_RUN_BASE} + cp -r ${TEMPLATES_FOLDER}/* ${CONF_FOLDER} + + cd ${TEMPLATES_FOLDER} + templates_files=( sqlbot.conf ) + for i in ${templates_files[@]}; do + if [ -f $i ]; then + envsubst < $i > ${CONF_FOLDER}/$i + fi + done +} + +function update_sctl() { + log_title "安装 sctl 命令行工具" + log_content "安装至 /usr/local/bin/sctl & /usr/bin/sctl" + cd ${CURRENT_DIR} + sed -i -e "s#SQLBOT_BASE=.*#SQLBOT_BASE=${SQLBOT_BASE}#g" sctl + \cp sctl /usr/local/bin && chmod +x /usr/local/bin/sctl + if [ ! -f /usr/bin/sctl ]; then + ln -s /usr/local/bin/sctl /usr/bin/sctl 2>/dev/null + fi +} + +function prepare_system_settings() { + log_title "修改操作系统相关设置" + if which getenforce >/dev/null 2>&1 && [ $(getenforce) == "Enforcing" ];then + log_content "关闭 SELINUX" + setenforce 0 + sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config + fi + + if which firewall-cmd >/dev/null 2>&1; then + if systemctl is-active firewalld &>/dev/null ;then + log_content "开启防火墙端口 ${SQLBOT_WEB_PORT}" + firewall-cmd --zone=public --add-port=${SQLBOT_WEB_PORT}/tcp --permanent + log_content "开启防火墙端口 ${SQLBOT_MCP_PORT}" + firewall-cmd --zone=public --add-port=${SQLBOT_MCP_PORT}/tcp --permanent + firewall-cmd --reload + else + log_content "防火墙未开启,忽略端口开放" + fi + fi +} + +function install_docker() { + log_title "安装 docker" + #Install docker + ##Install Latest Stable Docker Release + cd ${CURRENT_DIR} + + if which docker >/dev/null 2>&1; then + log_content "检测到 Docker 已安装,跳过安装步骤" + log_content "启动 Docker " + service docker start >/dev/null 2>&1 | tee -a ${CURRENT_DIR}/install.log + else + if [[ -d docker ]]; then + log_content "离线安装 docker" + cp docker/bin/* /usr/bin/ + cp docker/service/docker.service /etc/systemd/system/ + chmod +x /usr/bin/docker* + chmod 644 /etc/systemd/system/docker.service + else + log_content "在线安装 docker" + curl -fsSL https://resource.fit2cloud.com/get-docker-linux.sh -o get-docker.sh 2>&1 | tee -a ${CURRENT_DIR}/install.log + if [[ ! -f get-docker.sh ]];then + log_content "docker 在线安装脚本下载失败,请稍候重试" + exit 1 + fi + sudo sh get-docker.sh 2>&1 | tee -a ${CURRENT_DIR}/install.log + fi + + docker_config_folder="/etc/docker" + if [ ! -d "$docker_config_folder" ];then + mkdir -p "$docker_config_folder" + cat < $docker_config_folder/daemon.json + { + "log-driver": "json-file", + "log-opts": { + "max-file": "3", + "max-size": "10m" + } + } +EOF + fi + + log_content "启动 docker" + systemctl enable docker >/dev/null 2>&1; systemctl daemon-reload; systemctl start docker 2>&1 | tee -a ${CURRENT_DIR}/install.log + + docker version >/dev/null 2>&1 + if [ $? -ne 0 ]; then + log_content "docker 安装失败" + exit 1 + else + log_content "docker 安装成功" + + fi + fi +} + +function install_docker_compose() { + log_title "安装 docker-compose" + #Install docker-compose + cd ${CURRENT_DIR} + ##Install Latest Stable Docker Compose Release + docker-compose version >/dev/null 2>&1 + if [ $? -ne 0 ]; then + docker compose version >/dev/null 2>&1 + if [ $? -eq 0 ]; then + echo 'docker compose "$@"' > /usr/bin/docker-compose + chmod +x /usr/bin/docker-compose + else + if [[ -d docker ]]; then + log_content "离线安装 docker-compose" + cp docker/bin/docker-compose /usr/bin/ + chmod +x /usr/bin/docker-compose + else + log_content "在线安装 docker-compose" + curl -L https://resource.fit2cloud.com/docker/compose/releases/download/v2.16.0/docker-compose-$(uname -s | tr A-Z a-z)-$(uname -m) -o /usr/local/bin/docker-compose 2>&1 | tee -a ${CURRENT_DIR}/install.log + if [[ ! -f /usr/local/bin/docker-compose ]];then + log_content "docker-compose 下载失败,请稍候重试" + exit 1 + fi + chmod +x /usr/local/bin/docker-compose + ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose + fi + fi + + docker-compose version >/dev/null + if [ $? -ne 0 ]; then + log_content "docker-compose 安装失败" + exit 1 + else + log_content "docker-compose 安装成功" + fi + else + log_content "检测到 Docker Compose 已安装,跳过安装步骤" + fi + export COMPOSE_HTTP_TIMEOUT=180 +} + +function load_images() { + log_title "加载 SQLBOT 镜像" + cd ${CURRENT_DIR} + + for i in $(docker images --format '{{.Repository}}:{{.Tag}}' | grep dataease); do + current_images[${#current_images[@]}]=${i##*/} + done + + # 加载镜像 + if [[ -d images ]]; then + for i in $(ls images); do + if [[ "${current_images[@]}" =~ "${i%.tar.gz}" ]]; then + log_content "已存在镜像 ${i%.tar.gz}" + else + log_content "加载镜像 ${i%.tar.gz}" + docker load -i images/$i >/dev/null 2>&1 | tee -a ${CURRENT_DIR}/install.log + fi + done + else + SQLBOTVERSION=$(cat ${CURRENT_DIR}/sqlbot/templates/version) + curl -sfL https://resource.fit2cloud.com/installation-log.sh | sh -s sqlbot ${INSTALL_TYPE} ${SQLBOTVERSION} + fi +} + +function start_sqlbot() { + log_title "启动 SQLBOT 服务" + sctl reload 2>&1 | tee -a ${CURRENT_DIR}/install.log + if [[ $? -ne 0 ]]; then + log_content "SQLBOT 服务启动失败,请检查日志" + exit 1 + fi + echo + if [[ $INSTALL_TYPE != "upgrade" ]];then + echo -e "======================= 安装完成 =======================\n" 2>&1 | tee -a ${CURRENT_DIR}/install.log + echo -e "系统登录信息如下:\n\t访问地址: http://服务器IP:$SQLBOT_WEB_PORT\n\t用户名: admin\n\t初始密码: SQLBot@123456" 2>&1 | tee -a ${CURRENT_DIR}/install.log + else + echo -e "======================= 升级完成 =======================\n" 2>&1 | tee -a ${CURRENT_DIR}/install.log + fi +} + +function main() { + check_and_prepare_env_params + set_run_base_path + prepare_sqlbot_run_base + update_sctl + prepare_system_settings + install_docker + install_docker_compose + load_images + start_sqlbot +} + +main diff --git a/installer/sctl b/installer/sctl new file mode 100644 index 00000000..b191ebc9 --- /dev/null +++ b/installer/sctl @@ -0,0 +1,210 @@ +#!/bin/bash +action=$1 +target=$2 + +SQLBOT_BASE=/opt +SQLBOT_RUNNING_BASE=${SQLBOT_BASE}/sqlbot +SQLBOT_LOG_PATH=${SQLBOT_RUNNING_BASE}/data/sqlbot/logs +compose_files="-f docker-compose.yml" +compose_cmd="docker-compose" +current_version="" + +set -a +source ${SQLBOT_RUNNING_BASE}/.env +set +a +export COMPOSE_HTTP_TIMEOUT=180 + +docker-compose version >/dev/null 2>&1 +if [ $? -ne 0 ]; then + docker compose version >/dev/null 2>&1 + if [ $? -ne 0 ]; then + compose_cmd="docker compose" + fi +fi + +if [[ ! ${SQLBOT_EXTERNAL_DB} ]] || [ "${SQLBOT_EXTERNAL_DB}" = "false" ]; then + compose_files="${compose_files} -f docker-compose-pg.yml" +fi + +function usage() { + echo "SQLBot 控制脚本" + echo + echo "Usage: " + echo " ./sctl [COMMAND] [ARGS...]" + echo " ./sctl --help" + echo + echo "Commands: " + echo " status 查看 SQLBot 服务运行状态" + echo " start 启动 SQLBot 服务" + echo " stop 停止 SQLBot 服务" + echo " restart 重启 SQLBot 服务" + echo " reload 重载 SQLBot 服务" + echo " clear-images 清理 SQLBot 旧版本的相关镜像" + echo " clear-logs 清理 SQLBot 历史日志" + echo " version 查看 SQLBot 版本" +} + +function _healthcheck() { + echo + container_name=$(grep "container_name" $SQLBOT_RUNNING_BASE/docker-compose.yml | awk -F': ' '{print $2}') + sleep 1 + if [ -z '$(docker ps --filter "name=^$container_name$" -q)' ];then + echo "未找到容器 $container_name。" + exit 1 + fi + + for b in {1..90} + do + sleep 1 + read status healthy<<<$(docker inspect $container_name --format '{{.State.Status}} {{.State.Health.Status}}') + if [[ "$healthy" == "starting" ]];then + printf "\rSQLBot 服务状态 : 正在启动 ... %3ds" $b + elif [[ "$status" == "running" ]] && [[ "$healthy" == "healthy" ]];then + printf "\rSQLBot 服务状态 : 正常运行 " + echo + return; + else + echo + echo -e "SQLBot 服务状态 : \033[31m无法访问\033[0m" + exit 1 + fi + done + echo + echo "【警告】服务在等待时间内未完全启动!请稍后使用 sctl status 检查服务运行状况。" + echo +} +function _get_current_version() { + sqlbot_current_version=$(grep "^ image:.*sqlbot:" ${SQLBOT_RUNNING_BASE}/docker-compose.yml | awk -F'sqlbot:' '{print $2}') + if test -z $sqlbot_current_version; then + echo "获取当前版本失败,请检查当前版本是否正确" + exit 1 + fi + current_version=$sqlbot_current_version +} + +function status() { + echo + echo "SQLBot 容器运行状态" + cd ${SQLBOT_RUNNING_BASE} + ${compose_cmd} ${compose_files} ps + + echo + docker_root_dir=$(docker info | grep "Docker Root Dir" | awk -F': ' '{print $2}') + echo "Docker 目录及文件大小 : " + du -sh $docker_root_dir + echo + echo "Docker 目录所在磁盘使用情况 : " + df -H $docker_root_dir + + echo + echo "日志文件大小 : " + du -Sh ${SQLBOT_RUNNING_BASE}/logs/ + + echo + echo "SQLBot 运行目录及文件大小 : " + du -sh ${SQLBOT_BASE} + echo + echo "SQLBot 运行目录使用情况 : " + df -H ${SQLBOT_BASE} + + _healthcheck +} +function start() { + echo + cd ${SQLBOT_RUNNING_BASE} + ${compose_cmd} ${compose_files} up -d + _healthcheck +} +function stop() { + echo + cd ${SQLBOT_RUNNING_BASE} + ${compose_cmd} ${compose_files} down -v ${target} +} +function restart() { + stop + start +} +function reload() { + start +} +function version() { + echo + _get_current_version + echo "current version is $current_version" +} +function clear_images() { + echo + for f in $SQLBOT_RUNNING_BASE/*.yml; do + [[ -e "$f" ]] || break + grep "^ image:.*:" "$f" | uniq | while read -r component_image_defined; do + component_version=$(echo ${component_image_defined} | awk -F":" '{print $3}' | uniq) + component_image=$(echo ${component_image_defined} | awk -F'image: ' '{print $2}' | awk -F':' '{print $1}') + + if [[ $(docker images | grep "$component_image[[:space:]]" | grep -v " $component_version " | wc -l) == 0 ]]; then + echo "$component_image 不存在旧版本镜像" + else + echo "存在非当前版本镜像 : " + docker images | grep "$component_image[[:space:]]" | grep -v " $component_version " + echo "清理${component}镜像" + docker rmi $(docker images | grep "$component_image[[:space:]]" | grep -v " $component_version " | awk -F' ' '{print $1":"$2}') + echo "清理完毕" + fi + done + done + + if [ $(docker images -f dangling=true -q | wc -l) -gt 0 ]; then + echo "清理虚悬镜像" + docker rmi $(docker images -f dangling=true -q) + echo "清理完毕" + fi +} +function clear_logs() { + echo "开始清理 SQLBot 历史日志" + rm -rf ${SQLBOT_LOG_PATH}/*.*.* + echo "" > ${SQLBOT_LOG_PATH}/info.log + echo "" > ${SQLBOT_LOG_PATH}/debug.log + echo "" > ${SQLBOT_LOG_PATH}/error.log + echo "清理完毕" +} + +function main() { + case "${action}" in + status) + status + ;; + start) + start + ;; + stop) + stop + ;; + restart) + restart + ;; + reload) + reload + ;; + clear-images) + clear_images + ;; + clear-logs) + clear_logs + ;; + version) + version + ;; + help) + usage + ;; + --help) + usage + ;; + "") + usage + ;; + *) + echo "不支持的参数,请使用 help 或 --help 参数获取帮助" + ;; + esac +} +main \ No newline at end of file diff --git a/installer/templates/sqlbot.conf b/installer/templates/sqlbot.conf new file mode 100644 index 00000000..c4012e67 --- /dev/null +++ b/installer/templates/sqlbot.conf @@ -0,0 +1,20 @@ +PROJECT_NAME="SQLBot" +# Backend +BACKEND_CORS_ORIGINS=${SQLBOT_CORS_ORIGINS} +SECRET_KEY=${SQLBOT_SECRET_KEY} + +DEFAULT_PWD=${SQLBOT_DEFAULT_PWD} + +LOG_LEVEL=${SQLBOT_LOG_LEVEL} # DEBUG, INFO, WARNING, ERROR +SQL_DEBUG=False + +CACHE_TYPE=${SQLBOT_CACHE_TYPE} + +# Postgres +POSTGRES_SERVER=${SQLBOT_DB_HOST} +POSTGRES_PORT=${SQLBOT_DB_PORT} +POSTGRES_DB=${SQLBOT_DB_DB} +POSTGRES_USER=${SQLBOT_DB_USER} +POSTGRES_PASSWORD=${SQLBOT_DB_PASSWORD} # Change this to your pwd + +SERVER_IMAGE_HOST=${SQLBOT_SERVER_IMAGE_HOST} \ No newline at end of file diff --git a/installer/uninstall.sh b/installer/uninstall.sh new file mode 100644 index 00000000..2e4f79cd --- /dev/null +++ b/installer/uninstall.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +SQLBOT_BASE=/opt + +read -r -p "即将卸载 SQLBot 服务,包括删除运行目录、数据及相关镜像,是否继续? [Y/n] " input + +case $input in + [yY][eE][sS]|[yY]) + echo "Yes" + ;; + [nN][oO]|[nN]) + echo "No" + exit 1 + ;; + *) + echo "无效输入..." + exit 1 + ;; +esac + +echo "停止 SQLBot 服务" +sctl stop >/dev/null 2>&1 + +if [ -f /usr/bin/sctl ]; then + # 获取已安装的 SQLBot 的运行目录 + SQLBOT_BASE=$(grep "^SQLBOT_BASE=" /usr/bin/sctl | cut -d'=' -f2) +fi + +# 清理 SQLBot 相关镜像 +if test ! -z "$(docker images -f dangling=true -q)"; then + echo "清理虚悬镜像" + docker rmi $(docker images -f dangling=true -q) +fi + +if test -n "$(docker images | grep 'registry.cn-qingdao.aliyuncs.com/dataease/sqlbot')"; then + echo "清理 SQLBot 镜像" + docker rmi $(docker images | grep "registry.cn-qingdao.aliyuncs.com/dataease/sqlbot" | awk -F' ' '{print $1":"$2}') +fi + +# 清理 SQLBot 运行目录及命令行工具 sctl +rm -rf ${SQLBOT_BASE}/sqlbot /usr/bin/sctl + +echo "SQLBot 服务卸载完成" \ No newline at end of file diff --git a/sqlbot-assistant-demo.html b/sqlbot-assistant-demo.html new file mode 100644 index 00000000..a7b960b3 --- /dev/null +++ b/sqlbot-assistant-demo.html @@ -0,0 +1,593 @@ + + + + + + 优购电商 - 您的一站式购物平台 + + + + + + +
+ +
+ + +
+
+

发现优质商品,享受便捷购物

+

+ 优购电商为您提供海量正品商品,全场包邮,7天无理由退换货,让您购物无忧 +

+ 立即购物 +
+
+ + +
+
+
+

我们的优势

+
+
+
+
🚚
+

快速配送

+

全国300+城市次日达,部分地区可实现当日送达

+
+
+
🔒
+

正品保障

+

所有商品100%正品,假一赔十,购物更放心

+
+
+
💯
+

无忧售后

+

7天无理由退换货,专业客服团队24小时在线服务

+
+
+
+
+ + +
+
+
+

热门商品

+
+
+
+
+ 智能手表 +
+
+

智能手表 Pro

+

多功能健康监测,超长续航

+
¥899
+ 加入购物车 +
+
+
+
+ 无线耳机 +
+
+

无线降噪耳机

+

主动降噪,Hi-Fi音质

+
¥599
+ 加入购物车 +
+
+
+
+ 投影仪 +
+
+

便携式投影仪

+

1080P高清,内置电池

+
¥1299
+ 加入购物车 +
+
+
+
+ 空气炸锅 +
+
+

智能空气炸锅

+

无油健康烹饪,大容量

+
¥399
+ 加入购物车 +
+
+
+
+
+ + +
+
+
+

客户评价

+
+
+
+
+ "在优购电商购物体验非常好,商品质量有保障,物流速度也很快,客服态度也很专业,会继续支持!" +
+
+
+ 张女士 +
+
+

张女士

+

上海

+
+
+
+
+
+ "第一次在优购买东西就爱上了这个平台,价格实惠,经常有活动,退换货也很方便,强烈推荐!" +
+
+
+ 李先生 +
+
+

李先生

+

北京

+
+
+
+
+
+ "对比了好几个电商平台,最后还是选择优购,商品种类齐全,售后服务有保障,购物很放心。" +
+
+
+ 王小姐 +
+
+

王小姐

+

广州

+
+
+
+
+
+
+ + + + +