更新代码并修改远程仓库地址
This commit is contained in:
18
.claude/settings.local.json
Normal file
18
.claude/settings.local.json
Normal 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": []
|
||||
}
|
||||
}
|
||||
11
Dockerfile
11
Dockerfile
@@ -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
29
Dockerfile.backend
Normal 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
32
Dockerfile.full
Normal 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
27
docker-compose.local.yml
Normal 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
|
||||
@@ -7,6 +7,7 @@ services:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
platform: linux/amd64
|
||||
container_name: stock-scanner-app
|
||||
ports:
|
||||
- "8888:8888"
|
||||
|
||||
@@ -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框架与异步处理
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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', '')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user