ZHIWEI666 commited on
Commit
35b2edc
·
verified ·
1 Parent(s): 7c4a0ac

Upload 7 files

Browse files
Files changed (2) hide show
  1. models.py +2 -0
  2. router_prompts.py +37 -1
models.py CHANGED
@@ -278,6 +278,7 @@ class PromptCreate(BaseModel):
278
  media_type: str = "image" # "image" 或 "video"(示例媒体类型)
279
  video_url: Optional[str] = None # 示例视频 URL(仅 media_type=video)
280
  price: int = 0 # 定价(0=免费)
 
281
 
282
  class PromptUpdate(BaseModel):
283
  """ 更新提示词 """
@@ -289,6 +290,7 @@ class PromptUpdate(BaseModel):
289
  media_type: Optional[str] = None
290
  video_url: Optional[str] = None
291
  price: Optional[int] = None
 
292
 
293
  class PromptCategoryAdd(BaseModel):
294
  """ 添加提示词分类 """
 
278
  media_type: str = "image" # "image" 或 "video"(示例媒体类型)
279
  video_url: Optional[str] = None # 示例视频 URL(仅 media_type=video)
280
  price: int = 0 # 定价(0=免费)
281
+ tags: Optional[List[str]] = None # 自定义标签(最多10个,每个≤12字)
282
 
283
  class PromptUpdate(BaseModel):
284
  """ 更新提示词 """
 
290
  media_type: Optional[str] = None
291
  video_url: Optional[str] = None
292
  price: Optional[int] = None
293
+ tags: Optional[List[str]] = None
294
 
295
  class PromptCategoryAdd(BaseModel):
296
  """ 添加提示词分类 """
router_prompts.py CHANGED
@@ -52,6 +52,8 @@ MAX_PROMPT_TEXT_LEN = 20000
52
  MAX_PRICE = 10000
53
  MAX_CATEGORY_LEN = 8
54
  MAX_CATEGORY_PER_TYPE = 30
 
 
55
 
56
 
57
  def calculate_tx_hash(tx_id, account, tx_type, amount, prev_hash):
@@ -59,6 +61,22 @@ def calculate_tx_hash(tx_id, account, tx_type, amount, prev_hash):
59
  return hashlib.sha256(data.encode()).hexdigest()
60
 
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  def _load_categories() -> dict:
63
  """读取分类数据,不存在时用内置默认值初始化并持久化"""
64
  categories = db.load_data("prompt_categories.json", default_data=None)
@@ -161,6 +179,21 @@ async def add_prompt_category(request: Request, body: PromptCategoryAdd, current
161
  # 📝 提示词CRUD接口
162
  # ==========================================
163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  @router.get("/api/prompts")
165
  async def get_prompts(prompt_type: str = None, category: str = None,
166
  page: int = 1, limit: int = 20, sort: str = "latest"):
@@ -342,7 +375,8 @@ async def create_prompt(prompt: PromptCreate, current_user: str = Depends(requir
342
  "views": 0,
343
  "daily_views": 0,
344
  "viewed_by": [],
345
- "daily_views_date": ""
 
346
  }
347
 
348
  prompts_db = db.load_data("prompts.json", default_data=[])
@@ -412,6 +446,8 @@ async def update_prompt(prompt_id: str, update_data: PromptUpdate, current_user:
412
  prompt["video_url"] = update_data.video_url
413
  if update_data.video_url:
414
  prompt["media_type"] = "video"
 
 
415
  result_holder["prompt"] = prompt
416
  return True
417
  result_holder["error"] = "not_found"
 
52
  MAX_PRICE = 10000
53
  MAX_CATEGORY_LEN = 8
54
  MAX_CATEGORY_PER_TYPE = 30
55
+ MAX_TAGS = 10 # 单个提示词最多标签数
56
+ MAX_TAG_LEN = 12 # 单个标签最大字数
57
 
58
 
59
  def calculate_tx_hash(tx_id, account, tx_type, amount, prev_hash):
 
61
  return hashlib.sha256(data.encode()).hexdigest()
62
 
63
 
64
+ def _sanitize_tags(tags) -> list:
65
+ """清洗标签:去空白/去重/截断,最多 MAX_TAGS 个,每个≤ MAX_TAG_LEN 字"""
66
+ if not isinstance(tags, list):
67
+ return []
68
+ cleaned = []
69
+ for tag in tags:
70
+ if not isinstance(tag, str):
71
+ continue
72
+ name = tag.strip()[:MAX_TAG_LEN]
73
+ if name and name not in cleaned:
74
+ cleaned.append(name)
75
+ if len(cleaned) >= MAX_TAGS:
76
+ break
77
+ return cleaned
78
+
79
+
80
  def _load_categories() -> dict:
81
  """读取分类数据,不存在时用内置默认值初始化并持久化"""
82
  categories = db.load_data("prompt_categories.json", default_data=None)
 
179
  # 📝 提示词CRUD接口
180
  # ==========================================
181
 
182
+ @router.get("/api/prompt-tags")
183
+ async def get_prompt_tags():
184
+ """
185
+ 🏷️ 聚合全站标签(发布表单推荐用,按使用次数降序,最多返回100个)
186
+ """
187
+ prompts_db = db.load_data("prompts.json", default_data=[])
188
+ counter = {}
189
+ for prompt in prompts_db:
190
+ for tag in (prompt.get("tags") or []):
191
+ if isinstance(tag, str) and tag.strip():
192
+ counter[tag] = counter.get(tag, 0) + 1
193
+ ranked = sorted(counter.items(), key=lambda kv: (-kv[1], kv[0]))[:100]
194
+ return {"status": "success", "data": [{"name": n, "count": c} for n, c in ranked]}
195
+
196
+
197
  @router.get("/api/prompts")
198
  async def get_prompts(prompt_type: str = None, category: str = None,
199
  page: int = 1, limit: int = 20, sort: str = "latest"):
 
375
  "views": 0,
376
  "daily_views": 0,
377
  "viewed_by": [],
378
+ "daily_views_date": "",
379
+ "tags": _sanitize_tags(prompt.tags)
380
  }
381
 
382
  prompts_db = db.load_data("prompts.json", default_data=[])
 
446
  prompt["video_url"] = update_data.video_url
447
  if update_data.video_url:
448
  prompt["media_type"] = "video"
449
+ if update_data.tags is not None:
450
+ prompt["tags"] = _sanitize_tags(update_data.tags)
451
  result_holder["prompt"] = prompt
452
  return True
453
  result_holder["error"] = "not_found"