fix(popadmin): 音乐分类可编辑与勾选绑定
分类列表提供编辑面板(名称/排序/启用),单曲分类改为勾选保存,走既有 PATCH/PUT API。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
0ac9b8330f
commit
1498c0258f
@ -2539,6 +2539,17 @@ const pages = {
|
||||
<input id="catSort" type="number" placeholder="排序" value="0" style="width:80px;padding:8px;border-radius:8px;border:1px solid var(--border);background:#0b1220;color:var(--text)">
|
||||
<button type="button" id="catCreate">新建分类</button>
|
||||
</div>
|
||||
<div id="musicCatEditPanel" class="hidden" style="margin-bottom:10px;padding:12px;border:1px solid var(--border);border-radius:8px;background:#0b1220">
|
||||
<div class="toolbar" style="flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:0">
|
||||
<span class="muted">编辑分类 #<span id="catEditIdLabel"></span></span>
|
||||
<input type="hidden" id="catEditId">
|
||||
<input id="catEditName" placeholder="名称" style="padding:8px;border-radius:8px;border:1px solid var(--border);background:#111827;color:var(--text);min-width:140px">
|
||||
<input id="catEditSort" type="number" placeholder="排序" style="width:80px;padding:8px;border-radius:8px;border:1px solid var(--border);background:#111827;color:var(--text)">
|
||||
<label style="display:flex;align-items:center;gap:6px"><input type="checkbox" id="catEditEnabled">启用</label>
|
||||
<button type="button" id="catEditSave">保存</button>
|
||||
<button type="button" class="secondary" id="catEditCancel">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
<table>
|
||||
<thead><tr><th>ID</th><th>名称</th><th>层级</th><th>父级</th><th>排序</th><th>启用</th><th>操作</th></tr></thead>
|
||||
<tbody>
|
||||
@ -2554,7 +2565,7 @@ const pages = {
|
||||
<td>${esc(c.sortOrder)}</td>
|
||||
<td>${c.enabled ? '是' : '否'}</td>
|
||||
<td style="white-space:nowrap">
|
||||
<button type="button" class="secondary btn-sm" data-catedit="${esc(c.id)}">改</button>
|
||||
<button type="button" class="secondary btn-sm" data-catedit="${esc(c.id)}">编辑</button>
|
||||
<button type="button" class="secondary btn-sm" data-catdel="${esc(c.id)}">删</button>
|
||||
</td>
|
||||
</tr>`
|
||||
@ -2565,6 +2576,16 @@ const pages = {
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="musicTrackCatPanel" class="hidden section-block note" style="border:1px solid var(--border);padding:14px 16px;border-radius:10px;margin-bottom:12px">
|
||||
<h3 style="margin:0 0 8px">曲目分类绑定 · #<span id="trackCatIdLabel"></span> <span id="trackCatTitle" class="muted"></span></h3>
|
||||
<input type="hidden" id="trackCatTrackId">
|
||||
<div id="trackCatChecks" style="display:flex;flex-direction:column;gap:6px;max-height:240px;overflow:auto;margin-bottom:10px"></div>
|
||||
<div class="toolbar" style="gap:8px">
|
||||
<button type="button" id="trackCatSave">保存分类</button>
|
||||
<button type="button" class="secondary" id="trackCatCancel">取消</button>
|
||||
<span class="muted">可多选;清空勾选并保存=清除绑定</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="toolbar" style="flex-wrap:wrap;gap:8px;margin-bottom:12px">
|
||||
<input id="musicTitle" placeholder="曲名" style="padding:8px;border-radius:8px;border:1px solid var(--border);background:#0b1220;color:var(--text);min-width:180px">
|
||||
<label style="display:flex;align-items:center;gap:6px"><input type="checkbox" id="musicMember">需要会员</label>
|
||||
@ -2649,24 +2670,44 @@ const pages = {
|
||||
await api('/spark/music/categories', { method: 'POST', body: JSON.stringify(body) });
|
||||
pages.music();
|
||||
};
|
||||
$('content').querySelectorAll('[data-catedit]').forEach((btn) => {
|
||||
btn.onclick = async () => {
|
||||
const id = btn.dataset.catedit;
|
||||
const row = flatCats.find((x) => String(x.id) === String(id));
|
||||
const name = prompt('分类名称', row?.name || '');
|
||||
if (name == null) return;
|
||||
const sortRaw = prompt('排序(数字,越小越前)', String(row?.sortOrder ?? 0));
|
||||
if (sortRaw == null) return;
|
||||
const enabled = confirm('是否启用?(确定=是,取消=否)');
|
||||
const hideCatEdit = () => {
|
||||
const panel = $('musicCatEditPanel');
|
||||
if (panel) panel.classList.add('hidden');
|
||||
};
|
||||
$('catEditCancel').onclick = hideCatEdit;
|
||||
$('catEditSave').onclick = async () => {
|
||||
const id = $('catEditId').value;
|
||||
if (!id) return;
|
||||
const name = ($('catEditName').value || '').trim();
|
||||
if (!name) return alert('分类名称不能为空');
|
||||
const sortOrder = parseInt($('catEditSort').value, 10);
|
||||
try {
|
||||
await api('/spark/music/categories/' + id, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify({
|
||||
name: name.trim(),
|
||||
sortOrder: parseInt(sortRaw, 10) || 0,
|
||||
enabled,
|
||||
name,
|
||||
sortOrder: Number.isFinite(sortOrder) ? sortOrder : 0,
|
||||
enabled: !!$('catEditEnabled').checked,
|
||||
}),
|
||||
});
|
||||
alert('分类已保存');
|
||||
pages.music();
|
||||
} catch (e) {
|
||||
alert('分类保存失败:' + e.message);
|
||||
}
|
||||
};
|
||||
$('content').querySelectorAll('[data-catedit]').forEach((btn) => {
|
||||
btn.onclick = () => {
|
||||
const id = btn.dataset.catedit;
|
||||
const row = flatCats.find((x) => String(x.id) === String(id));
|
||||
if (!row) return alert('分类不存在');
|
||||
$('catEditId').value = id;
|
||||
$('catEditIdLabel').textContent = id;
|
||||
$('catEditName').value = row.name || '';
|
||||
$('catEditSort').value = String(row.sortOrder ?? 0);
|
||||
$('catEditEnabled').checked = !!row.enabled;
|
||||
$('musicCatEditPanel').classList.remove('hidden');
|
||||
$('catEditName').focus();
|
||||
};
|
||||
});
|
||||
$('content').querySelectorAll('[data-catdel]').forEach((btn) => {
|
||||
@ -2727,32 +2768,52 @@ const pages = {
|
||||
}
|
||||
};
|
||||
});
|
||||
$('content').querySelectorAll('[data-mcats]').forEach((btn) => {
|
||||
btn.onclick = async () => {
|
||||
const id = btn.dataset.mcats;
|
||||
const row = items.find((x) => String(x.id) === String(id));
|
||||
const selected = new Set((row?.categoryIds || []).map(String));
|
||||
const lines = flatCats.map((c) => {
|
||||
const mark = selected.has(String(c.id)) ? '[x]' : '[ ]';
|
||||
const pad = c.depth ? ' ' : '';
|
||||
return `${mark} ${pad}${c.id} ${c.name}`;
|
||||
});
|
||||
const tip =
|
||||
'勾选归属分类(多对多)。输入要归属的分类 ID,逗号分隔;留空=清除。\n\n' +
|
||||
lines.join('\n') +
|
||||
'\n\n当前:' +
|
||||
(row?.categoryIds || []).join(',');
|
||||
const raw = prompt(tip, (row?.categoryIds || []).join(','));
|
||||
if (raw == null) return;
|
||||
const categoryIds = raw
|
||||
.split(/[,,\s]+/)
|
||||
.map((s) => parseInt(s.trim(), 10))
|
||||
.filter((n) => Number.isFinite(n) && n > 0);
|
||||
const hideTrackCat = () => {
|
||||
const panel = $('musicTrackCatPanel');
|
||||
if (panel) panel.classList.add('hidden');
|
||||
};
|
||||
$('trackCatCancel').onclick = hideTrackCat;
|
||||
$('trackCatSave').onclick = async () => {
|
||||
const id = $('trackCatTrackId').value;
|
||||
if (!id) return;
|
||||
const categoryIds = Array.from($('trackCatChecks').querySelectorAll('input[type=checkbox]:checked'))
|
||||
.map((el) => parseInt(el.value, 10))
|
||||
.filter((n) => Number.isFinite(n) && n > 0);
|
||||
try {
|
||||
await api('/spark/music/' + id + '/categories', {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({ categoryIds }),
|
||||
});
|
||||
alert('分类绑定已保存');
|
||||
pages.music();
|
||||
} catch (e) {
|
||||
alert('分类绑定失败:' + e.message);
|
||||
}
|
||||
};
|
||||
$('content').querySelectorAll('[data-mcats]').forEach((btn) => {
|
||||
btn.onclick = () => {
|
||||
const id = btn.dataset.mcats;
|
||||
const row = items.find((x) => String(x.id) === String(id));
|
||||
if (!row) return;
|
||||
const selected = new Set((row.categoryIds || []).map(String));
|
||||
$('trackCatTrackId').value = id;
|
||||
$('trackCatIdLabel').textContent = id;
|
||||
$('trackCatTitle').textContent = row.title ? '· ' + row.title : '';
|
||||
$('trackCatChecks').innerHTML = flatCats.length
|
||||
? flatCats
|
||||
.map((c) => {
|
||||
const pad = c.depth ? 'padding-left:18px;' : '';
|
||||
const checked = selected.has(String(c.id)) ? 'checked' : '';
|
||||
const tier = c.depth === 0 ? '总分类' : '子分类';
|
||||
return `<label style="display:flex;align-items:center;gap:8px;${pad}">
|
||||
<input type="checkbox" value="${esc(c.id)}" ${checked}>
|
||||
<span>${esc(c.name)} <span class="muted">(#${esc(c.id)} · ${tier})</span></span>
|
||||
</label>`;
|
||||
})
|
||||
.join('')
|
||||
: '<div class="muted">暂无分类,请先在上方新建</div>';
|
||||
$('musicTrackCatPanel').classList.remove('hidden');
|
||||
$('musicTrackCatPanel').scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||
};
|
||||
});
|
||||
$('content').querySelectorAll('[data-mdel]').forEach((btn) => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user