From 7547de82ecb1c078e962c7dee1078edf2711fd3e Mon Sep 17 00:00:00 2001 From: Pine Date: Thu, 27 Aug 2026 19:09:35 +0800 Subject: [PATCH] =?UTF-8?q?feat(web):=20=E4=BB=BB=E5=8A=A1=E5=B9=BF?= =?UTF-8?q?=E5=9C=BA/=E8=AF=A6=E6=83=85=E9=80=8F=E5=87=BA=20can=5Faccept(?= =?UTF-8?q?=E5=8F=AF=E6=8E=A5/=E5=8E=9F=E5=9B=A0)=20+=20=E6=8C=89=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E6=94=BE=E8=A1=8C=E6=8A=A2=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 任务卡/详情显示「✓可抢 / 条件不符(附原因)」徽标;原因展示在卡内 - 条件不符时禁用抢单按钮;未登录仅浏览、抢单/报名引导登录 - 竞标任务按钮显示「报名」;详情页同样按 can_accept 放行/禁用 - 首页「接单生态」CTA 指向 #/tasks 任务广场 --- website/src/styles/tasks.css | 3 +++ website/src/user/Home.jsx | 2 +- website/src/user/TaskDetail.jsx | 16 ++++++++++++++-- website/src/user/Tasks.jsx | 16 ++++++++++++---- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/website/src/styles/tasks.css b/website/src/styles/tasks.css index 6772ca2..46935b2 100644 --- a/website/src/styles/tasks.css +++ b/website/src/styles/tasks.css @@ -20,6 +20,9 @@ .tk-cat { font-size: 11px; font-weight: 700; color: var(--primary); background: var(--primary-soft); border-radius: 999px; padding: 3px 10px; } .tk-mode { font-size: 11px; font-weight: 600; color: var(--on-surface); background: var(--surface); border: 1px solid var(--border); border-radius: 999px; padding: 3px 10px; } .tk-excl { font-size: 11px; font-weight: 600; color: var(--warning); background: var(--warning-soft); border-radius: 999px; padding: 3px 10px; } +.tk-can { font-size: 11px; font-weight: 700; color: var(--success); background: var(--success-soft); border-radius: 999px; padding: 3px 10px; } +.tk-nocan { font-size: 11px; font-weight: 700; color: var(--muted); background: var(--panel-2); border: 1px solid var(--line); border-radius: 999px; padding: 3px 10px; } +.tk-why { margin-top: 10px; font-size: 12px; color: var(--muted); line-height: 1.5; } .tk-title { font-size: 17px; font-weight: 700; color: var(--heading); line-height: 1.4; } .tk-desc { margin-top: 8px; font-size: 13.5px; color: var(--text-soft); line-height: 1.65; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; } .tk-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; } diff --git a/website/src/user/Home.jsx b/website/src/user/Home.jsx index 853be91..ac026d3 100644 --- a/website/src/user/Home.jsx +++ b/website/src/user/Home.jsx @@ -165,7 +165,7 @@ export default function Home() {

我们开放接单生态

把你的技能、经验、兴趣,变成能交付的东西——一段录课、一个模板、一次咨询、一份陪跑。到生态里接下属于自己的单。

先来交流沙龙,聊聊你那门手艺怎么变现。

-
+
待接单Live
diff --git a/website/src/user/TaskDetail.jsx b/website/src/user/TaskDetail.jsx index b0e8b1c..2ee79da 100644 --- a/website/src/user/TaskDetail.jsx +++ b/website/src/user/TaskDetail.jsx @@ -19,6 +19,9 @@ export default function TaskDetail() { getId() && getTask(getId()).then((t) => { setTask(t || null); setLoaded(true); }); }, []); + const reasons = Array.isArray(task && task.accept_reasons) ? task.accept_reasons : []; + const can = task && task.can_accept; // true/false/undefined + const onGrab = async () => { if (!isAuthed()) { setErr('抢单需先登录(OPC 端身份)。'); return; } setBusy(true); setErr(''); @@ -42,6 +45,8 @@ export default function TaskDetail() { {MODE[task.mode] || '抢单'} {task.exclusive && 独占} {task.status === 'published' ? '待接单' : task.status} + {can === true && ✓ 你可抢} + {can === false && 条件不符}

{task.title}

{task.task_code && 短码 {task.task_code}} @@ -64,9 +69,16 @@ export default function TaskDetail() { {task.publisher_name ?
发包方
{task.publisher_name}
: null}
- + {can === false ? ( + <> + +

{reasons.join(';')}

+ + ) : ( + + )} {err &&

{err}

} - {!isAuthed() &&

抢单需登录,去登录 / 注册

} + {!isAuthed() &&

抢单/报名需登录,去登录 / 注册

}
diff --git a/website/src/user/Tasks.jsx b/website/src/user/Tasks.jsx index 53a4ca3..638f891 100644 --- a/website/src/user/Tasks.jsx +++ b/website/src/user/Tasks.jsx @@ -14,12 +14,16 @@ const money = (a, b) => { }; function TaskCard({ t, onGrab, busy, mine }) { + const can = t.can_accept; // true/false/undefined(未登录) + const reasons = Array.isArray(t.accept_reasons) ? t.accept_reasons : []; return (
{t.category || '综合'} - {MODE[t.mode] || '抢单'} + {t.mode === 'bid' && 竞标} {t.exclusive && 独占} + {can === true && ✓ 可抢} + {can === false && 条件不符}

{t.title}

{t.description}

@@ -29,10 +33,14 @@ function TaskCard({ t, onGrab, busy, mine }) { {t.deadline && {t.deadline}} {t.delivery_days ? {t.delivery_days} 天交付 : null}
+ {can === false &&

{reasons.join(';')}

}
- + {!mine && can !== false && ( + + )} + {mine && !t.can_accept && } {t.task_code}