# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## 项目概述

djapi 是一个 Django 5.2 项目，提供金融数据 API 和新闻联播视频处理能力。部署在 Linux 服务器上，通过 uWSGI + nginx 对外服务。

## 常用命令

```bash
# 开发服务器
python manage.py runserver 0.0.0.0:8000

# uWSGI 管理
uwsgi --ini uwsgi.ini                    # 启动
uwsgi --reload uwsgi.pid                 # 热重载
uwsgi --stop uwsgi.pid                   # 停止

# 数据库操作（Django ORM 主要用于 admin，业务数据走 MySQL）
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser

# API 文档地址
# /api/docs/   - Swagger UI
# /api/redoc/  - ReDoc
# /api/schema/ - OpenAPI Schema

# 视频处理脚本（独立运行，非 Django 管理）
python api/video/main.py
```

## 架构

### Django 层（薄）

- 项目只有一个 app：`api`
- views.py 仅做路由转发，每个 view 函数接收请求参数后直接调用 `api/stock/` 下的业务函数
- Django ORM 基本未使用（sqlite3 仅用于 admin），所有业务数据走 MySQL（通过 `mysqlHandle.py` 直连）
- DRF + drf_spectacular 已配置但 API 视图仍沿用原生 `JsonResponse`，未使用 DRF ViewSet/Serializer

### 子模块一：`api/stock/` — 股票数据

核心依赖 **Tushare** 获取 A 股数据，数据流是「Tushare API → pandas DataFrame → Django JsonResponse」。

- **`config.py`**：全局配置，包括 TS_TOKEN、默认日期范围、行业列表、扫描阈值等
- **`stock_utils.py`**：通用工具集，包含 tscodeCheck（股票代码格式校验/补全后缀）、dataCorrect（NaN 填充）、dataMerge（按 ts_code+trade_date 合并 DataFrame）、viewFunc_tsCodeAndDate（通用 view 包装器：从 request 提取参数→调用 data_func→返回 JsonResponse）
- **`stock_basic.py`**：日线行情（daily）、个股基本信息（stock_basic）、按行业查股票列表
- **`getStockParam.py`**：个股技术参数（市值等）
- **`getStockEp.py`**：TTM EPS 和季度 EPS
- **`getIndexs.py`**：指数行情，支持按名称模糊查询指数代码
- **`stockMargin.py`**：融资融券数据
- **`getStockFina.py`**：`FinanceData` 类，按财报日期获取资产负债表+利润表+现金流量表，计算运营/资产/负债/回报率等指标
- **`getStockDiv2.py`**：`analyze_stock_dividend_and_price()` — 核心股息率计算。查分红记录→生成 TTM 分红序列→合并日线行情→计算 div_yield = cash_div_year/close，含毛刺平滑处理
- **`smoothBrush.py`**：滑动窗口中位数法检测并平滑毛刺数据
- **`divSearch.py`**：批量扫描全市场股息率，输出 CSV
- **`xwlbDaily.py`**：从 MySQL 查询新闻联播数据（`xwlb_daily` 和 `xwlb_daily_ext` 表）
- **`mysqlHandle.py`**：`MySQLDB` 类封装 mysql-connector，提供 insert/query/update 方法

### 子模块二：`api/video/` — 新闻联播视频处理

离线批处理流水线：**抓取视频 → 下载 → 提取音频 → ASR 转文字 → AI 分割+取标题 → 入库**。

- **`getVideo5.py`**：主流程。生成 CCTV 节目页 URL → 解析完整版视频链接 → yt-dlp 下载视频 → ffmpeg 提取 MP3 → 调用音频识别 → 写入 MySQL
- **`audioRead.py`**：音频处理。MP3→WAV 转换、智能静音分割、DashScope Paraformer ASR 识别、Qwen 文本纠错
- **`deepseek.py`**：`DeepSeekAPI` 类，带重试/降级机制的 DeepSeek API 封装
- **`ai.py`**：遗留的独立 AI 调用函数（deepseek_text, qwen_text），被 video 模块直接调用
- **`newsProcess.py`**：post-processing —— 从 MySQL 取出当天原始识别文本，调用 DeepSeek 分割为独立新闻+生成标题，写入 `xwlb_daily_ext` 表
- **`main.py`**：定时任务入口，每天执行 `process_videos(today, today)`
- **`wasted/`**：废弃的旧版视频抓取脚本
- **`xwlb_video/`**：下载的视频和音频文件（服务器上）
- **`mysqlHandle.py`**（video 子目录）：与 stock 子目录功能相同的数据库连接类

### URL 路由

所有 API 端点挂载在 `/api/` 下，由 `api/urls.py` 定义，共约 20 个端点，按功能分为：
- 股票基础：`stockbasic/`, `stockinfo/`, `stockparam/`, `industrys/`
- 财务数据：`finance/`, `stockep/`, `quarterlyEps/`
- 行情+指数：`indexByName/`, `indexDatas/`
- 融资融券：`dailymargin/`, `stockmargin/`
- 分红：`getdiv/`
- 新闻联播：`xwlbNews/`, `xwlbFine/`

大多数 API 接受 ts_code、start_date、end_date 三个通用参数，经由 `viewFunc_tsCodeAndDate()` 统一处理。

### 部署

- 服务器用户 `simon`，项目路径 `/home/simon/myquant/djapi/`
- uWSGI 监听 127.0.0.1:5004，通过 socket 与 nginx 通信
- 虚拟环境：`/opt/miniconda/envs/django`
- 静态文件已 collect 到 `static/`，由 nginx 直接服务
- 生产域名：`api.doorcome.cn`、`echart.doorcome.cn`
- CORS 已配置，允许跨域 cookie（SameSite=None）

## 开发约束

- `api/video/` 是独立功能模块，默认不修改该目录下任何文件。仅当用户明确要求时才操作此目录。

## 注意事项

- `config.py` 中的 TS_TOKEN 和 `deepseek.py`/`ai.py`/`audioRead.py` 中的 API key、`mysqlHandle.py` 中的数据库密码均为硬编码 —— 生产环境应迁移到环境变量
- `api/stock/` 下的模块支持两种导入方式（相对导入和绝对导入），这是为了兼容「作为 Django app 被调用」和「直接命令行运行脚本」两种场景
- `api/video/` 模块设计为独立命令行运行，不依赖 Django 框架
- `db.sqlite3` 已提交到代码库，包含 Django admin 的用户数据
