up 市场估值C wx index 专利

This commit is contained in:
dubingyan666 2025-10-05 17:38:22 +08:00
commit 23539014ca
12 changed files with 1210 additions and 9933 deletions

54
.github/copilot-instructions.md vendored Normal file
View File

@ -0,0 +1,54 @@
## 项目(快速)指导 — 供 AI 编码代理使用
下面的要点帮助你快速理解并在本代码库中高效工作。保持简短、具体并以可执行示例为主。
- 项目类型FastAPI 后端 (Python 3.11) + Vue3/Vite 前端(目录 `web/`)。后端使用 Tortoise ORM配置在 `app/settings/config.py`),前端用 pnpm/vite。
- 快速启动(后端):在项目根目录
- 建议 Python venv然后安装依赖`pip install -r requirements.txt`(或使用项目 README 中的 uv/uvenv 过程)。
- 启动:`python run.py`。这会通过 `uvicorn` 运行 `app:app`(见 `run.py`),开启 `reload=True`OpenAPI 在 `/docs`
- 快速启动(前端):进入 `web/`,使用 pnpm或 npm安装并运行`pnpm i``pnpm dev`
- 后端关键入口
- `run.py`:应用启动脚本,设置 uvicorn 日志格式并运行 `app:app`
- `app/__init__.py`:创建 FastAPI app调用 `core/init_app.py` 中的注册函数init 数据、注册中间件、异常处理与路由(路由前缀为 `/api`)。
- `app/core/init_app.py`(注意:此文件包含启动时的路由/中间件/异常注册逻辑,请优先阅读它来理解请求生命周期)。
- 重要配置点
- `app/settings/config.py`:使用 Pydantic Settings包含 `TORTOISE_ORM`(默认 SQLitedb 文件在项目根 `db.sqlite3`、JWT、SECRET_KEY、CORS 等。修改环境变量即可覆盖设置。
- `app/utils/api_config.py`:提供 `api_config` 全局实例,用来存放第三方 API示例`chinaz``xiaohongshu`)。常用方法:`api_config.get_api_key(provider)``get_endpoint_config(provider, endpoint)``add_endpoint(...)``save_config()`
- 路由与模块约定
- API 版本化:`app/api/v1/` 下放置 v1 接口。路由统一由 `core/init_app.py` 通过 `register_routers(..., prefix='/api')` 注册。
- 控制器HTTP handlers位于 `app/controllers/`,数据模型在 `app/models/`Pydantic schemas 在 `app/schemas/`
- 数据库与迁移
- 使用 Tortoise ORM`TORTOISE_ORM``app/settings/config.py`。项目把 `aerich.models` 列入 models见配置repository 中存在 `migrations/` 文件夹。若需变更模型,按项目现有工具链(如 aerich执行迁移在不确定时先检查 `pyproject.toml`/`requirements.txt` 是否包含 aerich 并复核 README。
- 日志与持久化
- 日志目录:`app/logs`(可在 `settings.LOGS_ROOT` 找到)。运行时可根据 `run.py` 中的 LOGGING_CONFIG 调整格式。
- 第三方 API 集成(示例)
- `api_config` 示例用法Python:
```py
from app.utils.api_config import api_config
cfg = api_config.get_endpoint_config('xiaohongshu', 'xiaohongshu_note_detail')
base = api_config.get_base_url('xiaohongshu')
key = api_config.get_api_key('xiaohongshu')
```
- 环境变量覆盖CHINAZ_API_KEY、XIAOHONGSHU_TOKEN、EXAMPLE_API_KEY 等会被 `api_config` 或 settings 读取。
- 编辑/贡献约定(可自动推断的现有模式)
- 新增 API`app/api/v1/...` 添加路由模块,控制器放 `app/controllers/`schema 放 `app/schemas/`,并在 `core/init_app.py` 中确保路由被注册。
- 新增模型:更新 `app/models/` 并生成迁移(项目使用 Tortoise + aerich 风格)。先检查 `migrations/models` 是否有对应变更。
- 调试提示
- 本地运行时使用 `python run.py`reload=True然后访问 `http://localhost:9999/docs` 查看 OpenAPI确认路由/依赖注入是否按预期工作。
- 常见故障点:环境变量未设置(导致 API keys 丢失、Tortoise 连接配置错误(检查 `TORTOISE_ORM.connections`)、以及中间件注册顺序会影响异常处理。
- 其它注意事项(小而具体)
- 前端以 `/api` 为后端前缀,修改后端接口时请同步前端 `web/src/api` 的调用。
- `app/utils/api_config.py` 会在模块导入时创建 `api_config` 单例;修改该文件时注意导入时机(不要在模块顶层做阻塞网络调用)。
如果需要我把 README 中的启动说明转成更精确的 shell 命令(或添加 aerich 的迁移示例命令),我可以继续补充。请告诉我你希望强调的额外部分或需要澄清的地方。

View File

@ -2,7 +2,7 @@ FROM node:18.12.0-alpine3.16 AS web
WORKDIR /opt/vue-fastapi-admin
COPY /web ./web
RUN cd /opt/vue-fastapi-admin/web && npm i --registry=https://registry.npmmirror.com && npm run build
RUN npm install -g pnpm && cd /opt/vue-fastapi-admin/web && pnpm install --registry=https://registry.npmmirror.com && pnpm run build
FROM python:3.11-slim-bullseye

View File

@ -9,6 +9,7 @@ from app.schemas.third_party_api import (
BaseAPIRequest,
ChinazAPIRequest,
XiaohongshuNoteRequest,
JizhiliaoSearchRequest,
APIResponse,
APIProviderInfo,
APIEndpointInfo,
@ -90,4 +91,24 @@ async def get_xiaohongshu_note(request: XiaohongshuNoteRequest):
return Fail(message=result.message)
except Exception as e:
logger.error(f"获取小红书笔记失败: {e}")
return Fail(message=f"获取小红书笔记失败: {str(e)}")
return Fail(message=f"获取小红书笔记失败: {str(e)}")
@router.post("/jizhiliao/index_search", summary="极致聊指数搜索")
async def jizhiliao_index_search(request: JizhiliaoSearchRequest):
"""调用极致聊指数搜索接口"""
try:
params = request.model_dump(by_alias=True, exclude_none=True, exclude={"timeout"})
timeout = request.timeout if request.timeout is not None else 30
result = await third_party_api_controller.search_jizhiliao_index(
params=params,
timeout=timeout
)
if result.success:
return Success(data=result.data, message=result.message)
else:
return Fail(message=result.message)
except Exception as e:
logger.error(f"极致聊指数搜索失败: {e}")
return Fail(message=f"极致聊指数搜索失败: {str(e)}")

View File

@ -96,11 +96,20 @@ class ThirdPartyAPIController:
params = {"noteId": note_id}
return await self.make_api_request(
provider="justoneapi",
provider="xiaohongshu",
endpoint="xiaohongshu_note_detail",
params=params
)
async def search_jizhiliao_index(self, params: Dict[str, Any], timeout: int = 30) -> APIResponse:
"""执行极致聊指数搜索"""
return await self.make_api_request(
provider="jizhiliao",
endpoint="index_search",
params=params,
timeout=timeout
)
# 创建全局控制器实例
third_party_api_controller = ThirdPartyAPIController()

View File

@ -1,5 +1,5 @@
from typing import Dict, Any, Optional, List
from pydantic import BaseModel, Field
from pydantic import BaseModel, Field, ConfigDict
class BaseAPIRequest(BaseModel):
@ -22,6 +22,23 @@ class XiaohongshuNoteRequest(BaseModel):
note_id: str = Field(..., description="笔记ID", example="68d2c71d000000000e00e9ea")
class JizhiliaoSearchRequest(BaseModel):
"""极致聊指数搜索请求"""
model_config = ConfigDict(populate_by_name=True)
keyword: str = Field(..., description="搜索关键词", example="人民日报")
mode: int = Field(2, description="搜索模式", example=2)
business_type: int = Field(
8192,
alias="BusinessType",
description="业务类型标识",
example=8192,
)
sub_search_type: int = Field(0, description="子搜索类型", example=0)
verifycode: Optional[str] = Field("", description="验证码", example="")
timeout: Optional[int] = Field(30, description="超时时间(秒)")
class APIResponse(BaseModel):
"""API响应模型"""
success: bool = Field(..., description="请求是否成功")

View File

@ -55,35 +55,45 @@ class APIConfig:
}
}
},
<<<<<<< HEAD
"justoneapi": {
"api_key": os.getenv("JUSTONEAPI_TOKEN", "YNSbIjdU"),
"base_url": "https://api.justoneapi.com",
"timeout": 30,
"retries": 3,
"endpoints": {
=======
"xiaohongshu": {
"api_key": os.getenv("XIAOHONGSHU_TOKEN", "YNSbIjdU"),
"base_url": "https://api.justoneapi.com",
"timeout": 30,
"retries": 3,
"endpoints": {
>>>>>>> b46c1a349b8413b2daf4a02b862ddcfde1953d76
"xiaohongshu_note_detail": {
"path": "/api/xiaohongshu/get-note-detail/v7",
"method": "GET",
"description": "小红书笔记详情查询",
"required_params": ["noteId"],
"optional_params": ["token"]
},
"xiaohongshu_user_info": {
"path": "/api/xiaohongshu/get-user-info/v7",
"method": "GET",
"description": "小红书用户信息查询",
"required_params": ["userId"],
"optional_params": ["token"]
},
"xiaohongshu_search_notes": {
"path": "/api/xiaohongshu/search-notes/v7",
"method": "GET",
"description": "小红书笔记搜索",
"required_params": ["keyword"],
"optional_params": ["page", "size", "token"]
}
"path": "/api/xiaohongshu/get-note-detail/v7",
"method": "GET",
"description": "小红书笔记详情查询",
"required_params": ["noteId"],
"optional_params": ["token"]
},
"xiaohongshu_user_info": {
"path": "/api/xiaohongshu/get-user-info/v7",
"method": "GET",
"description": "小红书用户信息查询",
"required_params": ["userId"],
"optional_params": ["token"]
},
"xiaohongshu_search_notes": {
"path": "/api/xiaohongshu/search-notes/v7",
"method": "GET",
"description": "小红书笔记搜索",
"required_params": ["keyword"],
"optional_params": ["page", "size", "token"]
}
}
},
<<<<<<< HEAD
# 微信指数
"dajiala": {
"api_key": "",
@ -101,6 +111,25 @@ class APIConfig:
}
},
"other_apis": {
=======
"jizhiliao": {
"api_key": os.getenv("JIZHILIAO_API_KEY", "JZL089ef0b7d0315d96"),
"base_url": "https://www.dajiala.com",
"timeout": 30,
"retries": 3,
"verifycode": os.getenv("JIZHILIAO_VERIFYCODE", ""),
"endpoints": {
"index_search": {
"path": "/fbmain/monitor/v3/web_search",
"method": "POST",
"description": "极致聊指数搜索",
"required_params": ["keyword", "mode", "BusinessType", "sub_search_type"],
"optional_params": ["key", "verifycode"]
}
}
},
"other": {
>>>>>>> b46c1a349b8413b2daf4a02b862ddcfde1953d76
# 可以添加其他第三方API配置
"example_api": {

View File

@ -146,18 +146,31 @@ class UniversalAPIManager:
if 'sign' not in prepared_params:
prepared_params['sign'] = self._generate_chinaz_sign()
elif provider == 'justoneapi':
# JustOneAPI需要token参数
elif provider == 'xiaohongshu':
# 小红书接口使用 JustOneAPI 平台,需要 token 参数
if 'token' not in prepared_params or not prepared_params['token']:
api_key = provider_config.get('api_key')
if api_key:
prepared_params['token'] = api_key
<<<<<<< HEAD
elif provider == 'dajiala':
# JustOneAPI需要token参数
api_key = provider_config.get('api_key')
if api_key:
prepared_params['key'] = api_key
=======
elif provider == 'jizhiliao':
# 极致聊接口需要 key默认从配置读取
if 'key' not in prepared_params or not prepared_params['key']:
api_key = provider_config.get('api_key')
if api_key:
prepared_params['key'] = api_key
if 'verifycode' not in prepared_params:
default_verifycode = provider_config.get('verifycode')
if default_verifycode is not None:
prepared_params['verifycode'] = default_verifycode
>>>>>>> b46c1a349b8413b2daf4a02b862ddcfde1953d76
return prepared_params
@ -276,7 +289,7 @@ class UniversalAPIManager:
}
return self.make_request('chinaz', 'judgement', params)
# JustOneAPI的便捷方法
# 小红书便捷方法
def get_xiaohongshu_note_detail(self, note_id: str) -> Dict[str, Any]:
"""
获取小红书笔记详情
@ -289,7 +302,31 @@ class UniversalAPIManager:
"""
params = {'noteId': note_id}
return self.make_request('justoneapi', 'xiaohongshu_note_detail', params)
return self.make_request('xiaohongshu', 'xiaohongshu_note_detail', params)
# 极致聊便捷方法
def search_jizhiliao_index(
self,
keyword: str,
mode: int = 2,
business_type: int = 8192,
sub_search_type: int = 0,
key: Optional[str] = None,
verifycode: Optional[str] = None,
) -> Dict[str, Any]:
"""执行极致聊指数搜索"""
params: Dict[str, Any] = {
'keyword': keyword,
'mode': mode,
'BusinessType': business_type,
'sub_search_type': sub_search_type,
}
if key is not None:
params['key'] = key
if verifycode is not None:
params['verifycode'] = verifycode
return self.make_request('jizhiliao', 'index_search', params)
# 通用方法
def list_providers(self) -> list:

View File

@ -4,14 +4,16 @@ annotated-types==0.7.0
anyio==4.8.0
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
asyncclick==8.1.8
asyncclick==8.1.8.0
black==24.10.0
certifi==2024.12.14
cffi==1.17.1
charset-normalizer==3.4.3
click==8.1.8
dictdiffer==0.9.0
dnspython==2.7.0
email-validator==2.2.0
email_validator==2.2.0
exceptiongroup==1.3.0
fastapi==0.111.0
fastapi-cli==0.0.7
h11==0.14.0
@ -21,40 +23,44 @@ httpx==0.28.1
idna==3.10
iso8601==2.1.0
isort==5.13.2
jinja2==3.1.5
Jinja2==3.1.5
loguru==0.7.3
markdown-it-py==3.0.0
markupsafe==3.0.2
MarkupSafe==3.0.2
mdurl==0.1.2
mypy-extensions==1.0.0
orjson==3.10.14
packaging==24.2
passlib==1.7.4
pathspec==0.12.1
pillow==11.3.0
platformdirs==4.3.6
pycparser==2.22
pydantic==2.10.5
pydantic-core==2.27.2
pydantic-settings==2.7.1
pygments==2.19.1
pyjwt==2.10.1
pydantic_core==2.27.2
Pygments==2.19.1
PyJWT==2.10.1
pypika-tortoise==0.3.2
python-dotenv==1.0.1
python-multipart==0.0.20
pytz==2024.2
pyyaml==6.0.2
PyYAML==6.0.2
requests==2.32.5
rich==13.9.4
rich-toolkit==0.13.2
ruff==0.9.1
setuptools==75.8.0
shellingham==1.5.4
sniffio==1.3.1
starlette==0.37.2
tomli==2.2.1
tortoise-orm==0.23.0
tqdm==4.67.1
typer==0.15.1
typing-extensions==4.12.2
typing_extensions==4.12.2
ujson==5.10.0
urllib3==2.5.0
uvicorn==0.34.0
uvloop==0.21.0; sys_platform != 'win32'
uvloop==0.21.0
watchfiles==1.0.4
websockets==14.1

8415
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,7 @@
"@iconify/json": "^2.2.228",
"@iconify/vue": "^4.1.1",
"@unocss/eslint-config": "^0.55.0",
"@vicons/ionicons5": "^0.13.0",
"@vueuse/core": "^10.3.0",
"@zclzone/eslint-config": "^0.0.4",
"axios": "^1.4.0",
@ -28,9 +29,9 @@
"sass": "^1.65.1",
"typescript": "^5.1.6",
"unocss": "^0.55.0",
"unplugin-auto-import": "^0.15.3",
"unplugin-auto-import": "^0.16.6",
"unplugin-icons": "^0.16.5",
"unplugin-vue-components": "^0.24.1",
"unplugin-vue-components": "^0.25.1",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-html": "^3.2.0",
"vite-plugin-svg-icons": "^2.0.1",

2464
web/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -32,4 +32,10 @@
该商品的发行量: 字符串类型
该商品最近一次市场活动时间: 字符串类型
月交易額: 字符串类型
该商品近30天价格波动区间: 字符串类型
该商品近30天价格波动区间: 字符串类型
export DOCKER_DEFAULT_PLATFORM=linux/amd64
docker build -t zfc931912343/guzhi-fastapi-admin:v1.0 .
docker push zfc931912343/guzhi-fastapi-admin:v1.0