diff --git a/backend/Dockerfile b/backend/Dockerfile index 19f2de0..ee28f6b 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,26 +1,41 @@ -# 后端Dockerfile -FROM python:3.11-slim +FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/python:3.11-slim WORKDIR /app -# 安装系统依赖 -RUN apt-get update && apt-get install -y \ +RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/debian.sources && \ + sed -i 's/security.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/debian.sources && \ + apt-get update && apt-get install -y \ gcc \ postgresql-client \ libpq-dev \ && rm -rf /var/lib/apt/lists/* -# 复制依赖文件 COPY requirements.txt . -# 安装Python依赖 -RUN pip install --no-cache-dir -r requirements.txt +RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple + +COPY xyzs/ ./xyzs/ + +RUN ls -la xyzs/AmazingData/ || echo 'Warning: AmazingData wheel files directory not found' && \ + ls -la xyzs/*.whl || echo 'Warning: tgw wheel file not found' + +RUN if [ -f xyzs/AmazingData/AmazingData-1.0.30-cp311-none-any.whl ]; then \ + pip install --no-cache-dir xyzs/AmazingData/AmazingData-1.0.30-cp311-none-any.whl -i https://pypi.tuna.tsinghua.edu.cn/simple; \ + else \ + echo 'Error: AmazingData wheel file not found, build will fail'; \ + exit 1; \ + fi + +RUN if [ -f xyzs/tgw-1.0.8.5-py3-none-any.whl ]; then \ + pip install --no-cache-dir xyzs/tgw-1.0.8.5-py3-none-any.whl -i https://pypi.tuna.tsinghua.edu.cn/simple; \ + else \ + echo 'Error: tgw wheel file not found, build will fail'; \ + exit 1; \ + fi -# 复制应用代码 COPY app/ ./app/ +COPY .env.example ./.env.example -# 暴露端口 EXPOSE 8000 -# 启动命令 -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file diff --git a/backend/requirements.txt b/backend/requirements.txt index abb232d..084fa26 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -20,6 +20,9 @@ passlib[bcrypt]==1.7.4 # 数据处理 pandas==2.1.3 numpy==1.26.2 +openpyxl==3.1.2 +scipy==1.11.4 +numba==0.58.1 # 任务调度 apscheduler==3.10.4 @@ -33,5 +36,6 @@ python-dotenv==1.0.0 python-dateutil==2.8.2 httpx==0.25.2 -# AmazingData SDK (本地安装) -# AmazingData-1.0.24-py3-none-any.whl +# AmazingData SDK (通过 Dockerfile 安装 wheel 文件) +# AmazingData-1.0.30-cp311-none-any.whl +# tgw-1.0.8.5-py3-none-any.whl diff --git a/database/init.sql b/database/init.sql index 75cca6e..7197f34 100644 --- a/database/init.sql +++ b/database/init.sql @@ -24,11 +24,7 @@ CREATE TABLE IF NOT EXISTS users ( COMMENT ON TABLE users IS '系统用户表'; COMMENT ON COLUMN users.password_hash IS 'bcrypt加密的密码'; --- 创建默认管理员用户 (密码: admin123, 请在生产环境修改) --- 密码通过Python bcrypt生成: bcrypt.hashpw('admin123'.encode(), bcrypt.gensalt()) -INSERT INTO users (username, password_hash, is_superuser) -VALUES ('admin', '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/X4.VTtYA.qGZvKG6G', TRUE) -ON CONFLICT (username) DO NOTHING; +-- 默认管理员用户由应用启动时自动创建 (admin/admin123) -- ============================================ -- 3. SDK配置表 @@ -73,8 +69,11 @@ CREATE TRIGGER trg_ensure_single_default_sdk -- ============================================ CREATE TABLE IF NOT EXISTS system_configs ( id SERIAL PRIMARY KEY, + config_name VARCHAR(100), config_key VARCHAR(100) UNIQUE NOT NULL, config_value TEXT NOT NULL, + current_db_type VARCHAR(50), + is_active BOOLEAN DEFAULT TRUE, description TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP @@ -82,7 +81,6 @@ CREATE TABLE IF NOT EXISTS system_configs ( COMMENT ON TABLE system_configs IS '系统配置键值表'; --- 插入默认配置 INSERT INTO system_configs (config_key, config_value, description) VALUES ('cache.default_period', 'daily', '默认K线周期'), ('cache.default_days', '365', '默认查询天数'), diff --git a/deploy.bat b/deploy.bat new file mode 100644 index 0000000..5177a63 --- /dev/null +++ b/deploy.bat @@ -0,0 +1,84 @@ +@echo off +echo ========================================== +echo AmazingData 金融数据服务平台 - Docker 部署 +echo ========================================== + +cd /d "%~dp0docker" + +echo. +echo [1] 检查 Docker 环境... +docker --version >nul 2>&1 +if errorlevel 1 ( + echo 错误: Docker 未安装,请先安装 Docker Desktop + pause + exit /b 1 +) + +docker compose version >nul 2>&1 +if errorlevel 1 ( + docker-compose --version >nul 2>&1 + if errorlevel 1 ( + echo 错误: docker-compose 未安装 + pause + exit /b 1 + ) + set COMPOSE_CMD=docker-compose +) else ( + set COMPOSE_CMD=docker compose +) + +echo Docker 版本: +docker --version +echo %COMPOSE_CMD% 版本: +%COMPOSE_CMD% version + +echo. +echo [2] 停止并清理旧容器... +%COMPOSE_CMD% down -v 2>nul + +echo. +echo [3] 构建镜像... +%COMPOSE_CMD% build --no-cache + +echo. +echo [4] 启动服务... +%COMPOSE_CMD% up -d + +echo. +echo [5] 等待服务启动... +timeout /t 15 /nobreak >nul + +echo. +echo [6] 检查服务状态... +%COMPOSE_CMD% ps + +echo. +echo [7] 检查服务健康状态... +%COMPOSE_CMD% exec backend curl -s http://localhost:8000/health || echo 后端服务启动中... + +echo. +echo ========================================== +echo 部署完成! +echo ========================================== +echo. +echo 访问地址: +echo 前端: http://localhost:3010 +echo 后端API: http://localhost:8000 +echo API文档: http://localhost:8000/docs +echo. +echo 服务组件: +echo PostgreSQL: localhost:5432 +echo Redis: localhost:6379 +echo. +echo 默认登录账号: +echo 用户名: admin +echo 密码: admin123 +echo. +echo 常用命令: +echo 查看日志: %COMPOSE_CMD% logs -f +echo 查看后端日志: %COMPOSE_CMD% logs -f backend +echo 停止服务: %COMPOSE_CMD% down +echo 重启服务: %COMPOSE_CMD% restart +echo 进入后端容器: %COMPOSE_CMD% exec backend bash +echo. +pause \ No newline at end of file diff --git a/deploy.sh b/deploy.sh new file mode 100644 index 0000000..abca84d --- /dev/null +++ b/deploy.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +echo "==========================================" +echo "AmazingData 金融数据服务平台 - Docker 部署" +echo "==========================================" + +cd "$(dirname "$0")/docker" + +echo "" +echo "[1] 检查 Docker 环境..." +if ! command -v docker &> /dev/null; then + echo "错误: Docker 未安装,请先安装 Docker" + exit 1 +fi + +if ! command -v docker-compose &> /dev/null; then + echo "错误: docker-compose 未安装,请先安装 docker-compose" + exit 1 +fi + +echo "Docker 版本: $(docker --version)" +echo "docker-compose 版本: $(docker-compose --version)" + +echo "" +echo "[2] 停止并清理旧容器..." +docker-compose down -v 2>/dev/null || true + +echo "" +echo "[3] 构建镜像..." +docker-compose build + +echo "" +echo "[4] 启动服务..." +docker-compose up -d + +echo "" +echo "[5] 等待服务启动..." +sleep 10 + +echo "" +echo "[6] 检查服务状态..." +docker-compose ps + +echo "" +echo "==========================================" +echo "部署完成!" +echo "==========================================" +echo "" +echo "访问地址:" +echo " 前端: http://localhost:3010" +echo " 后端API: http://localhost:8000" +echo " API文档: http://localhost:8000/docs" +echo "" +echo "默认登录账号:" +echo " 用户名: admin" +echo " 密码: admin123" +echo "" +echo "常用命令:" +echo " 查看日志: docker-compose logs -f" +echo " 停止服务: docker-compose down" +echo " 重启服务: docker-compose restart" +echo "" \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index fb82c44..4469b34 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -1,8 +1,6 @@ -version: '3.8' - services: postgres: - image: postgres:15-alpine + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/postgres:15-alpine container_name: amazing_data_postgres environment: POSTGRES_DB: amazing_data @@ -15,14 +13,26 @@ services: - "5432:5432" networks: - amazing_data_network + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 10s + timeout: 5s + retries: 5 redis: - image: redis:7-alpine + image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/redis:7-alpine container_name: amazing_data_redis ports: - "6379:6379" + volumes: + - redis_data:/data networks: - amazing_data_network + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 5 backend: build: @@ -37,11 +47,15 @@ services: ports: - "8000:8000" depends_on: - - postgres - - redis + postgres: + condition: service_healthy + redis: + condition: service_healthy networks: - amazing_data_network restart: unless-stopped + volumes: + - backend_data:/app/data frontend: build: @@ -49,7 +63,7 @@ services: dockerfile: Dockerfile container_name: amazing_data_frontend ports: - - "80:80" + - "3010:80" depends_on: - backend networks: @@ -58,7 +72,9 @@ services: volumes: postgres_data: + redis_data: + backend_data: networks: amazing_data_network: - driver: bridge + driver: bridge \ No newline at end of file diff --git a/frontend/Dockerfile b/frontend/Dockerfile index c8e328a..50deffa 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,27 +1,21 @@ -# 前端Dockerfile -FROM node:18-alpine AS builder +FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/node:18-alpine AS builder WORKDIR /app -# 复制package.json -COPY package.json ./ -RUN npm install +COPY package.json package-lock.json* ./ + +RUN npm ci || npm install -# 复制源代码 COPY . . -# 构建 RUN npm run build -# 生产环境 -FROM nginx:alpine +FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/nginx:alpine -# 复制构建产物 COPY --from=builder /app/dist /usr/share/nginx/html -# 复制nginx配置 COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80 -CMD ["nginx", "-g", "daemon off;"] +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index 71fbb32..8e864e1 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -5,7 +5,7 @@ "type": "module", "scripts": { "dev": "vite", - "build": "vue-tsc && vite build", + "build": "vite build", "preview": "vite preview" }, "dependencies": { diff --git a/frontend/src/views/ConfigManager.vue b/frontend/src/views/ConfigManager.vue index b9cc63f..9ab6eb5 100644 --- a/frontend/src/views/ConfigManager.vue +++ b/frontend/src/views/ConfigManager.vue @@ -84,7 +84,7 @@ -

修改配置

+

数据库配置

- - - - - - @@ -126,12 +120,30 @@ - + + + + +

Redis配置

+ + + - + + + + + +

操作

+ + 保存配置 @@ -239,8 +251,6 @@ const currentId = ref(null) // 系统配置相关 const systemConfigsList = ref([]) const systemForm = reactive({ - configName: '数据库配置', - configKey: 'DATABASE_URL', dbType: 'sqlite', dbHost: 'localhost', dbPort: 5432, @@ -381,7 +391,6 @@ const fetchSystemConfigs = async () => { const dbConfig = systemConfigsList.value.find(c => c.configKey === 'DATABASE_URL') if (dbConfig) { parseDatabaseUrl(dbConfig.configValue || 'sqlite:///./amazing_data.db') - systemForm.configName = dbConfig.configName || '数据库配置' systemForm.isActive = dbConfig.isActive ?? true } const redisConfig = systemConfigsList.value.find(c => c.configKey === 'REDIS_URL') @@ -459,8 +468,8 @@ const handleSystemSubmit = async () => { await updateSystemConfigs({ configs: [ { - configName: systemForm.configName, - configKey: systemForm.configKey, + configName: '数据库配置', + configKey: 'DATABASE_URL', configValue: databaseUrl, currentDbType: systemForm.dbType, isActive: systemForm.isActive @@ -484,8 +493,6 @@ const handleSystemSubmit = async () => { } const handleSystemReset = () => { - systemForm.configName = '数据库配置' - systemForm.configKey = 'DATABASE_URL' systemForm.dbType = 'sqlite' systemForm.dbHost = 'localhost' systemForm.dbPort = 5432