🎉 主要更新:
后端:
- 全新华为应用市场爬虫系统
- 三表分离数据库设计 (app_info, app_metrics, app_rating)
- 完整的API接口 (搜索、分类、热门、上新等)
- 元服务自动识别和分类
- 智能Token管理和数据处理
- 修复热门应用重复显示问题
前端:
- 全新首页设计 (今日上架、热门应用)
- 应用页面 (彩色分类磁贴、智能图标匹配)
- 今日上新页面 (日期切换)
- 热门应用页面 (卡片布局)
- 应用详情页面 (完整信息展示)
- Apple风格搜索栏
- Footer组件
- 底部导航栏优化 (4个导航项)
- 骨架屏加载效果
- FontAwesome图标集成
UI/UX:
- 统一浅色背景 (#F5F5F7)
- 流畅的过渡动画
- 响应式设计
- 毛玻璃效果
文档:
- CHANGELOG.md - 完整更新日志
- QUICKSTART.md - 快速开始
- 多个技术文档和使用指南
版本: v2.0.0
80 lines
2.3 KiB
Python
Executable File
80 lines
2.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
数据库迁移脚本 - 添加新字段
|
|
"""
|
|
import asyncio
|
|
from sqlalchemy import text
|
|
from app.database import engine
|
|
|
|
|
|
async def column_exists(conn, table_name: str, column_name: str) -> bool:
|
|
"""检查列是否存在"""
|
|
result = await conn.execute(text(f"""
|
|
SELECT COUNT(*)
|
|
FROM information_schema.COLUMNS
|
|
WHERE TABLE_SCHEMA = DATABASE()
|
|
AND TABLE_NAME = '{table_name}'
|
|
AND COLUMN_NAME = '{column_name}'
|
|
"""))
|
|
count = result.scalar()
|
|
return count > 0
|
|
|
|
|
|
async def add_column_if_not_exists(conn, table_name: str, column_name: str, column_def: str):
|
|
"""如果列不存在则添加"""
|
|
if not await column_exists(conn, table_name, column_name):
|
|
sql = f"ALTER TABLE {table_name} ADD COLUMN {column_name} {column_def}"
|
|
print(f"添加字段: {column_name}...")
|
|
await conn.execute(text(sql))
|
|
print(f"✓ {column_name} 添加成功")
|
|
else:
|
|
print(f"○ {column_name} 已存在,跳过")
|
|
|
|
|
|
async def migrate():
|
|
"""添加新字段到 app_info 表"""
|
|
print("=" * 60)
|
|
print("开始数据库迁移...")
|
|
print("=" * 60)
|
|
|
|
migrations = [
|
|
# (列名, 列定义)
|
|
("dev_id", "VARCHAR(100)"),
|
|
("supplier", "VARCHAR(255)"),
|
|
("kind_id", "VARCHAR(50)"),
|
|
("tag_name", "VARCHAR(100)"),
|
|
("price", "VARCHAR(50) DEFAULT '0'"),
|
|
("main_device_codes", "JSON"),
|
|
("target_sdk", "VARCHAR(50)"),
|
|
("min_sdk", "VARCHAR(50)"),
|
|
("compile_sdk_version", "INT"),
|
|
("min_hmos_api_level", "INT"),
|
|
("api_release_type", "VARCHAR(50) DEFAULT 'Release'"),
|
|
("ctype", "INT"),
|
|
("app_level", "INT"),
|
|
("packing_type", "INT"),
|
|
]
|
|
|
|
async with engine.begin() as conn:
|
|
for column_name, column_def in migrations:
|
|
try:
|
|
await add_column_if_not_exists(conn, "app_info", column_name, column_def)
|
|
except Exception as e:
|
|
print(f"✗ {column_name} 失败: {e}")
|
|
|
|
print("\n" + "=" * 60)
|
|
print("数据库迁移完成!")
|
|
print("=" * 60)
|
|
|
|
|
|
async def run_migration():
|
|
"""运行迁移并清理"""
|
|
try:
|
|
await migrate()
|
|
finally:
|
|
await engine.dispose()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(run_migration())
|