chore(admin): 删掉停用的老方案,养护方案页按猫狗分 tab

## 停用的 8 套直接删了
上一个提交把老方案(按 3 段配的)改名停用没删,理由是「万一新内容有问题
还能翻回去看」。你要求删掉,删了。

走 service 的 DeleteTemplate 而不是直接删主表:明细要跟着一起清。
复查孤儿明细 0 条。剩 10 套(5 阶段 × 2 物种,各一套)。

已套用出去的计划节点不受影响 —— 套用时就展开成实体行、和模板断开了。

## 按猫狗分 tab
混在一起 10 套要上下找,而且阶段名两边一样(幼年期/青年期…),扫一眼分不清
哪套是猫的。tab 上带条数,「阶段」列不再重复物种。

顺带两处:
  行按阶段顺序排 —— 数据库按 sort 排,但 sort 是全局的,分物种看时会跳号
  新建时默认跟当前 tab 的物种,省一步点击

品种管理页本来就有猫狗 tab;记录事项页不分物种(记录类型猫狗共用)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-07-30 12:53:22 +08:00
parent c4c0c2b7cd
commit cff6982613
3 changed files with 40 additions and 11 deletions
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -5,7 +5,7 @@
<link rel="icon" type="image/svg+xml" href="/admin/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>admin</title>
<script type="module" crossorigin src="/admin/assets/index-BOP-ztlG.js"></script>
<script type="module" crossorigin src="/admin/assets/index-BH08rQ_o.js"></script>
<link rel="stylesheet" crossorigin href="/admin/assets/index-PPcOOdtF.css">
</head>
<body>
+37 -8
View File
@@ -26,6 +26,10 @@ const REPEATS = [
{ key: 'once', label: '一次性' },
]
const WEEKDAYS = ['一', '二', '三', '四', '五', '六', '日']
// 阶段的展示顺序。后端 CareStages 就是这个顺序,但列表里要用它排序,
// 单独列一份免得依赖接口返回的时序
const STAGE_ORDER = ['刚到家 0-30 天', '幼年期', '青年期', '成年期', '中年期', '老年期']
const selectCls = 'h-9 rounded-md border border-input bg-card px-2 text-sm shrink-0'
type Item = {
@@ -78,6 +82,7 @@ function blank(kind: Item['kind']): Item {
export default function CareTemplates() {
const [list, setList] = useState<Tpl[]>([])
const [tab, setTab] = useState('cat')
const [types, setTypes] = useState<any[]>([])
const [stages, setStages] = useState<string[]>([])
const [open, setOpen] = useState(false)
@@ -106,7 +111,8 @@ export default function CareTemplates() {
}, [])
function create() {
setTpl({ id: '', species: 'cat', stage: '成年期', name: '', summary: '', sort: 0, enabled: true })
// 默认跟当前 tab 的物种,省一步点击
setTpl({ id: '', species: tab, stage: '成年期', name: '', summary: '', sort: 0, enabled: true })
setItems([])
setErr('')
setOpen(true)
@@ -159,6 +165,13 @@ export default function CareTemplates() {
upd(it._k, 'weekdays', next.join(','))
}
// 按 tab 过滤,并按阶段顺序排(数据库按 sort 排,但 sort 是全局的,
// 分物种看时会跳号)
const order = STAGE_ORDER
const shown = list
.filter((t) => t.species === tab)
.sort((a, b) => order.indexOf(a.stage) - order.indexOf(b.stage))
const plans = items.filter((i) => i.kind === 'plan')
const reminders = items.filter((i) => i.kind === 'reminder')
@@ -191,12 +204,30 @@ export default function CareTemplates() {
</Button>
</div>
{/* 猫狗分开看。混在一起 10 套要上下找,而且阶段名一样(幼年期/青年期…),
扫一眼分不清哪套是猫的 */}
<div className="mb-4 flex items-center gap-2">
{SPECIES.map((s) => {
const n = list.filter((t) => t.species === s.key).length
return (
<Button
key={s.key}
size="sm"
variant={tab === s.key ? 'default' : 'outline'}
onClick={() => setTab(s.key)}
>
<s.Icon className="h-4 w-4" /> {s.label} {n}
</Button>
)
})}
</div>
<Card>
<CardContent className="pt-6">
<Table>
<TableHeader>
<TableRow>
<TableHead className="w-24">/</TableHead>
<TableHead className="w-24"></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead className="w-20"></TableHead>
@@ -204,13 +235,11 @@ export default function CareTemplates() {
</TableRow>
</TableHeader>
<TableBody>
{list.map((t) => {
{shown.map((t) => {
const c = spread(t)
return (
<TableRow key={t.id}>
<TableCell className="text-muted-foreground">
{t.species === 'dog' ? '狗' : '猫'} · {t.stage}
</TableCell>
<TableCell className="text-muted-foreground">{t.stage}</TableCell>
<TableCell>
<div className="font-medium">{t.name || '(未命名)'}</div>
<div className="text-xs text-muted-foreground">{t.summary}</div>
@@ -232,10 +261,10 @@ export default function CareTemplates() {
</TableRow>
)
})}
{!list.length && (
{!shown.length && (
<TableRow>
<TableCell colSpan={5} className="py-10 text-center text-muted-foreground">
</TableCell>
</TableRow>
)}