更新代码并修改远程仓库地址

This commit is contained in:
史悦
2025-09-02 13:53:24 +08:00
parent 9471480c89
commit 4c6e03a59f
9 changed files with 132 additions and 9 deletions

View File

@@ -0,0 +1,18 @@
{
"permissions": {
"allow": [
"Bash(docker build:*)",
"Bash(npm install)",
"Bash(mkdir:*)",
"Bash(docker run:*)",
"Bash(docker logs:*)",
"Bash(npm run build:*)",
"Bash(docker stop:*)",
"Bash(docker rm:*)",
"Bash(docker tag:*)",
"Bash(docker push:*)",
"Bash(docker login:*)"
],
"deny": []
}
}

View File

@@ -1,5 +1,5 @@
# 阶段一: 构建Vue前端
FROM node:18-alpine as frontend-builder
FROM node:18-alpine AS frontend-builder
# 设置工作目录
WORKDIR /app/frontend
@@ -13,18 +13,21 @@ RUN npm ci
# 复制前端源代码
COPY frontend/ ./
# 确保node_modules中的可执行文件有正确权限
RUN chmod +x node_modules/.bin/*
# 构建前端应用
RUN npm run build
# 阶段二: 构建Python后端
FROM python:3.10-slim as backend-builder
FROM python:3.10-slim AS backend-builder
# 设置工作目录
WORKDIR /app
# 安装系统依赖和构建依赖
RUN apt-get update && apt-get install -y \
libgl1-mesa-glx \
libgl1 \
ca-certificates \
build-essential \
&& rm -rf /var/lib/apt/lists/*
@@ -43,7 +46,7 @@ WORKDIR /app
# 安装运行时依赖
RUN apt-get update && apt-get install -y \
libgl1-mesa-glx \
libgl1 \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*

29
Dockerfile.backend Normal file
View File

@@ -0,0 +1,29 @@
# 简化版本:只构建后端,不包含前端
FROM python:3.10-slim
# 设置工作目录
WORKDIR /app
# 复制requirements.txt
COPY requirements.txt .
# 安装Python依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制后端代码
COPY *.py ./
COPY services/ ./services/
COPY utils/ ./utils/
# 创建数据目录和日志目录
RUN mkdir -p data logs
# 暴露端口
EXPOSE 8888
# 设置环境变量
ENV PYTHONPATH=/app
ENV PYTHONUNBUFFERED=1
# 启动应用
CMD ["python", "web_server.py"]

32
Dockerfile.full Normal file
View File

@@ -0,0 +1,32 @@
# 完整版本:包含前端和后端
FROM python:3.10-slim
# 设置工作目录
WORKDIR /app
# 复制requirements.txt
COPY requirements.txt .
# 安装Python依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制后端代码
COPY *.py ./
COPY services/ ./services/
COPY utils/ ./utils/
# 复制前端构建产物
COPY frontend/dist/ ./frontend/dist/
# 创建数据目录和日志目录
RUN mkdir -p data logs
# 暴露端口
EXPOSE 8888
# 设置环境变量
ENV PYTHONPATH=/app
ENV PYTHONUNBUFFERED=1
# 启动应用
CMD ["python", "web_server.py"]

27
docker-compose.local.yml Normal file
View File

@@ -0,0 +1,27 @@
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
container_name: stock-scanner-app-local
ports:
- "8999:8888"
environment:
- API_KEY=${API_KEY}
- API_URL=${API_URL}
- API_MODEL=${API_MODEL}
- API_TIMEOUT=${API_TIMEOUT}
- LOGIN_PASSWORD=${LOGIN_PASSWORD}
- ANNOUNCEMENT_TEXT=${ANNOUNCEMENT_TEXT}
volumes:
- ./logs:/app/logs
- ./data:/app/data
restart: unless-stopped
networks:
- stock-scanner-network
networks:
stock-scanner-network:
driver: bridge

View File

@@ -7,6 +7,7 @@ services:
build:
context: .
dockerfile: Dockerfile
platform: linux/amd64
container_name: stock-scanner-app
ports:
- "8888:8888"

View File

@@ -7,7 +7,7 @@ pandas==2.2.2
scipy==1.15.1
# 数据获取和分析库
akshare==1.16.35
akshare==1.17.44
tqdm==4.67.1
# Web框架与异步处理

View File

@@ -266,13 +266,17 @@ class AIAnalyzer:
chunk_data = json.loads(line)
# 检查是否有finish_reason
finish_reason = chunk_data.get("choices", [{}])[0].get("finish_reason")
choices = chunk_data.get("choices", [])
if not choices:
logger.debug("收到空的choices数组跳过")
continue
finish_reason = choices[0].get("finish_reason")
if finish_reason == "stop":
logger.debug("收到finish_reason=stop流结束")
continue
# 获取delta内容
delta = chunk_data.get("choices", [{}])[0].get("delta", {})
delta = choices[0].get("delta", {})
# 检查delta是否为空对象
if not delta or delta == {}:
@@ -350,7 +354,16 @@ class AIAnalyzer:
return
response_data = response.json()
analysis_text = response_data.get("choices", [{}])[0].get("message", {}).get("content", "")
choices = response_data.get("choices", [])
if not choices:
logger.error("API响应中没有choices数据")
yield json.dumps({
"stock_code": stock_code,
"error": "API响应格式错误缺少choices数据",
"status": "error"
})
return
analysis_text = choices[0].get("message", {}).get("content", "")
# 尝试从分析内容中提取投资建议
recommendation = self._extract_recommendation(analysis_text)

View File

@@ -117,7 +117,7 @@ def test_api_stream():
json_data = json.loads(data_content)
logger.debug(f"JSON结构: {_truncate_json_for_logging(json_data)}")
if 'choices' in json_data:
if 'choices' in json_data and json_data['choices']:
delta = json_data['choices'][0].get('delta', {})
content = delta.get('content', '')