fix: PMC 测试清单未完成项 + YYX#row22 未读角标
PMC#16 账户登录地址不正确: - 写死的 https://airshelf.com/login(不存在的域名)改成 ${location.origin}/login, 与邀请链接同源,成员拿到的就是当前真实访问地址。 PMC#17/#18 成员三档额度只有月度生效、日/总纯装饰 → 列表显示与配置对不上: - TeamMember 新增 daily_credit_limit / total_credit_limit(0=不限,迁移 0006); - reserve_credit 逐档真实管控(每日/每月/累计总额),口径=窗口内 CHARGE 流水 + 在途预留; - 成员列表"每日额度"由写死"不限"改成真实日额度+今日已用,并新增"总额度"列; - 创建/编辑弹窗三档额度真入库真生效;补 3 个计费单测(日/总拦截、0=不限)。 PMC#24 同批生成的图片文字/内容雷同: - 根因=套图/自由创作同批 N 张用同一 prompt 且无变化(只有模特上身图按 index 变); - 给平台套图/自由参考/纯文生图都加按 index 的版式变体,避开传 seed(防中转站 400)。 PMC#25 重跑应在原任务上重跑而非新开任务: - 全批"重跑"改为原地复位同一批次卡;"重跑这张/再生成"改为补图进原卡(不覆盖好图、不新开任务)。 YYX#row22 图片生成未读角标(本仓库既有改动一并提交): - AITask 新增 read_at(迁移 0020 + 索引一致性迁移 0021);导航栏"图片生成"未读胶囊、 商品预览右下角未读分数;查看某商品即标记其生成任务已读、清零角标。 注:PMC#14/#15/#20/#22/#23 早前提交已修,需部署重测;PMC#13/#21 为 provider 侧 生成失败,代码侧重试/退费/僵尸回收/错误外露已就位,需部署后看真实 error_message 定位; PMC#19 收件箱标记与设计稿逐字一致,待截图复现。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -111,6 +111,7 @@ class AITaskViewSet(TeamScopedViewSetMixin, ReadOnlyModelViewSet):
|
||||
queryset = queryset.annotate(
|
||||
rp_batch_id=KeyTextTransform("batch_id", "request_payload"),
|
||||
rp_mode=KeyTextTransform("mode", "request_payload"),
|
||||
rp_product_id=KeyTextTransform("product_id", "request_payload"),
|
||||
)
|
||||
raw = self.request.query_params.get("task_type", "").strip()
|
||||
if raw:
|
||||
@@ -119,6 +120,46 @@ class AITaskViewSet(TeamScopedViewSetMixin, ReadOnlyModelViewSet):
|
||||
queryset = queryset.filter(task_type__in=types)
|
||||
return queryset
|
||||
|
||||
# YYX#row22:只有「工作台图片生成」(mode∈model/cover/image)才计入未读;
|
||||
# 脚本/实体抽取/故事板等流水线内部任务不进这块未读统计。
|
||||
_GEN_MODES = ("model", "cover", "image")
|
||||
|
||||
def _unread_base(self):
|
||||
"""本团队、属于图片生成、且未读(read_at is null)的任务集合(已 annotate rp_mode/rp_product_id)。"""
|
||||
return self.get_queryset().filter(rp_mode__in=self._GEN_MODES, read_at__isnull=True)
|
||||
|
||||
@action(detail=False, methods=["get"], url_path="unread")
|
||||
def unread(self, request):
|
||||
"""未读生成任务汇总:总数(导航胶囊) + 按商品分组(商品预览角标)。"""
|
||||
rows = self._unread_base().values_list("rp_product_id", flat=True)
|
||||
total = 0
|
||||
by_product: dict[str, int] = {}
|
||||
for pid in rows:
|
||||
total += 1
|
||||
if pid:
|
||||
by_product[str(pid)] = by_product.get(str(pid), 0) + 1
|
||||
return Response({"total": total, "by_product": by_product})
|
||||
|
||||
@action(detail=False, methods=["post"], url_path="mark-read")
|
||||
def mark_read(self, request):
|
||||
"""标记已读 → 清零未读胶囊。
|
||||
body 可选:product_id(只清该商品) / batch_id(只清该批) / ids(指定任务);
|
||||
都不传 = 把当前团队所有未读生成任务标记已读(进任务中心时调用)。"""
|
||||
qs = self._unread_base()
|
||||
product_id = str(request.data.get("product_id") or "").strip()
|
||||
batch_id = str(request.data.get("batch_id") or "").strip()
|
||||
ids = request.data.get("ids") or []
|
||||
if isinstance(ids, str):
|
||||
ids = [s for s in ids.split(",") if s.strip()]
|
||||
if product_id:
|
||||
qs = qs.filter(rp_product_id=product_id)
|
||||
if batch_id:
|
||||
qs = qs.filter(rp_batch_id=batch_id)
|
||||
if ids:
|
||||
qs = qs.filter(id__in=[str(i).strip() for i in ids if str(i).strip()])
|
||||
updated = qs.update(read_at=timezone.now())
|
||||
return Response({"updated": updated})
|
||||
|
||||
|
||||
class ImageConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
|
||||
"""图片创作工作室的「对话」CRUD。
|
||||
|
||||
Reference in New Issue
Block a user