Spaces:
Running
Running
Upload 5 files
Browse files- router_items.py +73 -0
router_items.py
CHANGED
|
@@ -104,6 +104,79 @@ def _build_creator_trend_data(account: str, u_items: list, months: list) -> dict
|
|
| 104 |
}
|
| 105 |
|
| 106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
@router.get("/api/creators")
|
| 108 |
async def get_creators(sort: str = "downloads", limit: int = 100):
|
| 109 |
"""
|
|
|
|
| 104 |
}
|
| 105 |
|
| 106 |
|
| 107 |
+
@router.get("/api/creators/search")
|
| 108 |
+
async def search_creators(keyword: str, sort: str = "downloads", limit: int = 50):
|
| 109 |
+
"""
|
| 110 |
+
搜索创作者
|
| 111 |
+
根据关键词搜索创作者(name、account、shortDesc 不区分大小写子串匹配)
|
| 112 |
+
"""
|
| 113 |
+
users_db = db.load_data("users.json", default_data={})
|
| 114 |
+
items_db = db.load_data("items.json", default_data=[])
|
| 115 |
+
|
| 116 |
+
# 🚀 P1性能优化:预构建 author->items 索引
|
| 117 |
+
author_items_index = {}
|
| 118 |
+
for item in items_db:
|
| 119 |
+
author = item.get("author")
|
| 120 |
+
if author:
|
| 121 |
+
if author not in author_items_index:
|
| 122 |
+
author_items_index[author] = []
|
| 123 |
+
author_items_index[author].append(item)
|
| 124 |
+
|
| 125 |
+
creators = []
|
| 126 |
+
months = get_last_6_months()
|
| 127 |
+
keyword_lower = keyword.lower()
|
| 128 |
+
|
| 129 |
+
for account, u in users_db.items():
|
| 130 |
+
# 🚀 P1性能优化:直接从索引获取
|
| 131 |
+
u_items = author_items_index.get(account, [])
|
| 132 |
+
|
| 133 |
+
# 只搜索有发布作品的用户
|
| 134 |
+
if not u_items:
|
| 135 |
+
continue
|
| 136 |
+
|
| 137 |
+
# 获取搜索字段并转为小写
|
| 138 |
+
name = u.get("name", account)
|
| 139 |
+
short_desc = u.get("intro") or ""
|
| 140 |
+
|
| 141 |
+
# 不区分大小写的子串匹配
|
| 142 |
+
search_text = f"{name} {account} {short_desc}".lower()
|
| 143 |
+
if keyword_lower not in search_text:
|
| 144 |
+
continue
|
| 145 |
+
|
| 146 |
+
tools_count = 0
|
| 147 |
+
apps_count = 0
|
| 148 |
+
|
| 149 |
+
for i in u_items:
|
| 150 |
+
itype = i.get("type", "")
|
| 151 |
+
if itype == "tool":
|
| 152 |
+
tools_count += 1
|
| 153 |
+
elif itype == "app":
|
| 154 |
+
apps_count += 1
|
| 155 |
+
|
| 156 |
+
creators.append({
|
| 157 |
+
"account": account, "name": name, "avatar": u.get("avatarDataUrl", ""),
|
| 158 |
+
"bannerUrl": u.get("bannerUrl"),
|
| 159 |
+
"shortDesc": short_desc, "fullDesc": short_desc,
|
| 160 |
+
"likes": sum(i.get("likes", 0) for i in u_items), "favorites": sum(i.get("favorites", 0) for i in u_items),
|
| 161 |
+
"downloads": sum(i.get("uses", 0) for i in u_items),
|
| 162 |
+
"views": sum(i.get("views", 0) for i in u_items),
|
| 163 |
+
"daily_views": sum(i.get("daily_views", 0) for i in u_items),
|
| 164 |
+
"toolsCount": tools_count, "appsCount": apps_count, "followers": len(u.get("followers", [])), "created_at": u.get("created_at", 0),
|
| 165 |
+
"recent_tips": u.get("tip_history", {}).get(datetime.date.today().strftime("%Y-%m"), 0),
|
| 166 |
+
})
|
| 167 |
+
|
| 168 |
+
# 排序逻辑与 /api/creators 保持一致
|
| 169 |
+
if sort == "likes": creators.sort(key=lambda x: x.get("likes", 0), reverse=True)
|
| 170 |
+
elif sort == "favorites": creators.sort(key=lambda x: x.get("favorites", 0), reverse=True)
|
| 171 |
+
elif sort == "downloads": creators.sort(key=lambda x: x.get("downloads", 0), reverse=True)
|
| 172 |
+
elif sort == "tips": creators.sort(key=lambda x: x.get("recent_tips", 0), reverse=True)
|
| 173 |
+
elif sort == "views": creators.sort(key=lambda x: x.get("views", 0), reverse=True)
|
| 174 |
+
elif sort == "daily_views": creators.sort(key=lambda x: x.get("daily_views", 0), reverse=True)
|
| 175 |
+
else: creators.sort(key=lambda x: x.get("created_at", 0), reverse=True)
|
| 176 |
+
|
| 177 |
+
return {"status": "success", "data": creators[:limit]}
|
| 178 |
+
|
| 179 |
+
|
| 180 |
@router.get("/api/creators")
|
| 181 |
async def get_creators(sort: str = "downloads", limit: int = 100):
|
| 182 |
"""
|