feat(tasks): 任务管理表单增强 —— 发布方角色/可见性/指派类型/归属园区/竞标名额/接单条件JSON/托管方式 + C端可见/公有任务开关

This commit is contained in:
Pine
2026-08-27 19:29:51 +08:00
parent b001a19b3d
commit 40156975a1
+78
View File
@@ -26,6 +26,9 @@ const EMPTY_FORM = {
tags: "", mode: "grab", budget_min: "0", budget_max: "0", deadline: "",
delivery_days: "0", headcount: "0", exclusive: false,
display_priority: "0", publisher_id: "", publisher_name: "", status: "published",
publisher_role: "operator", visibility: "public", c_visible: true, park_public: false,
assign_type: "", assign_park_id: "", assign_opc_id: "", park_id: "",
bid_quota: "0", win_quota: "0", eligibility: "{}", settle_mode: "operator_escrow",
};
export default function TasksPage() {
@@ -55,6 +58,12 @@ export default function TasksPage() {
display_priority: String(r.display_priority ?? 0),
publisher_id: r.publisher_id || "", publisher_name: r.publisher_name || "",
status: r.status || "published",
publisher_role: r.publisher_role || "operator", visibility: r.visibility || "public",
c_visible: !!r.c_visible, park_public: !!r.park_public,
assign_type: r.assign_type || "", assign_park_id: r.assign_park_id || "",
assign_opc_id: r.assign_opc_id || "", park_id: r.park_id || "",
bid_quota: String(r.bid_quota ?? 0), win_quota: String(r.win_quota ?? 0),
eligibility: r.eligibility || "{}", settle_mode: r.settle_mode || "operator_escrow",
});
setOpen(true);
};
@@ -72,6 +81,13 @@ export default function TasksPage() {
headcount: Number(form.headcount) || 0,
display_priority: Number(form.display_priority) || 0,
exclusive: !!form.exclusive,
publisher_role: form.publisher_role || "operator",
visibility: form.visibility || "public",
c_visible: !!form.c_visible, park_public: !!form.park_public,
assign_type: form.assign_type || "", assign_park_id: form.assign_park_id || "",
assign_opc_id: form.assign_opc_id || "", park_id: form.park_id || "",
bid_quota: Number(form.bid_quota) || 0, win_quota: Number(form.win_quota) || 0,
eligibility: form.eligibility || "{}", settle_mode: form.settle_mode || "operator_escrow",
};
if (editing) await tasksApi.update(editing.id, body);
else await tasksApi.create(body);
@@ -161,6 +177,68 @@ export default function TasksPage() {
<div className="space-y-1.5"><Label></Label><Input type="number" value={form.display_priority} onChange={(e) => setForm((f) => ({ ...f, display_priority: e.target.value }))} /></div>
<div className="flex items-end pb-2"><label className="flex items-center gap-2 text-sm"><input type="checkbox" checked={!!form.exclusive} onChange={(e) => setForm((f) => ({ ...f, exclusive: e.target.checked }))} /> ()</label></div>
</div>
<div className="rounded-lg border p-3 space-y-3">
<p className="text-xs font-semibold text-muted-foreground"></p>
<div className="grid grid-cols-2 gap-4">
<div className="space-y-1.5"><Label></Label>
<Select value={form.publisher_role} onValueChange={(v) => setForm((f) => ({ ...f, publisher_role: v }))}>
<SelectTrigger className="w-full"><SelectValue /></SelectTrigger>
<SelectContent>
<SelectItem value="operator">(operator)</SelectItem>
<SelectItem value="enterprise">(enterprise)</SelectItem>
<SelectItem value="park">(park)</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-1.5"><Label></Label>
<Select value={form.visibility} onValueChange={(v) => setForm((f) => ({ ...f, visibility: v }))}>
<SelectTrigger className="w-full"><SelectValue /></SelectTrigger>
<SelectContent>
<SelectItem value="public">(public)</SelectItem>
<SelectItem value="assigned_only">(assigned_only)</SelectItem>
<SelectItem value="c_visible">C端可见(c_visible)</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-1.5"><Label>()</Label>
<Select value={form.assign_type} onValueChange={(v) => setForm((f) => ({ ...f, assign_type: v }))}>
<SelectTrigger className="w-full"><SelectValue /></SelectTrigger>
<SelectContent>
<SelectItem value=""></SelectItem>
<SelectItem value="opc"> OPC</SelectItem>
<SelectItem value="park"></SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-1.5"><Label>ID / OPC ID</Label>
<div className="flex gap-2">
<Input value={form.assign_park_id} placeholder="园区ID" onChange={(e) => setForm((f) => ({ ...f, assign_park_id: e.target.value }))} />
<Input value={form.assign_opc_id} placeholder="OPC ID" onChange={(e) => setForm((f) => ({ ...f, assign_opc_id: e.target.value }))} />
</div>
</div>
<div className="space-y-1.5"><Label>ID()</Label><Input value={form.park_id} onChange={(e) => setForm((f) => ({ ...f, park_id: e.target.value }))} /></div>
<div className="space-y-1.5"><Label></Label>
<Select value={form.settle_mode} onValueChange={(v) => setForm((f) => ({ ...f, settle_mode: v }))}>
<SelectTrigger className="w-full"><SelectValue /></SelectTrigger>
<SelectContent>
<SelectItem value="operator_escrow"></SelectItem>
<SelectItem value="offline">线()</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-1.5"><Label>(0=)</Label><Input type="number" value={form.bid_quota} onChange={(e) => setForm((f) => ({ ...f, bid_quota: e.target.value }))} /></div>
<div className="space-y-1.5"><Label>(0=1)</Label><Input type="number" value={form.win_quota} onChange={(e) => setForm((f) => ({ ...f, win_quota: e.target.value }))} /></div>
</div>
<div className="grid grid-cols-2 gap-4">
<label className="flex items-center gap-2 text-sm"><input type="checkbox" checked={!!form.c_visible} onChange={(e) => setForm((f) => ({ ...f, c_visible: e.target.checked }))} /> C端任务广场可见</label>
<label className="flex items-center gap-2 text-sm"><input type="checkbox" checked={!!form.park_public} onChange={(e) => setForm((f) => ({ ...f, park_public: e.target.checked }))} /> ()</label>
</div>
<div className="space-y-1.5"><Label>(JSON{`opc_certified, region, gender, years_min, field, skill, case_req`})</Label>
<textarea className="min-h-20 w-full rounded-md border border-input px-3 py-2 text-xs font-mono"
value={form.eligibility} onChange={(e) => setForm((f) => ({ ...f, eligibility: e.target.value }))} />
</div>
</div>
<div className="space-y-1.5"><Label>()</Label>
<textarea className="min-h-24 w-full rounded-md border border-input px-3 py-2 text-sm" value={form.description} onChange={(e) => setForm((f) => ({ ...f, description: e.target.value }))} />
</div>