Files
ReelShortWeb/src/views/contentManagement/CategoryManagementView.vue
T

169 lines
5.0 KiB
Vue

<!-- Author: fruit.com.cn -->
<script setup>
import { onMounted, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { AppIcons } from '@/constants/icons'
import {
createDramaCategoryApi,
deleteDramaCategoryApi,
listDramaCategoriesApi,
updateDramaCategoryApi
} from '@/api/admin/drama'
import { useRbac } from '@/stores/rbac'
import PageHeading from '@/views/components/PageHeading.vue'
const { can } = useRbac()
const loading = ref(false)
const list = ref([])
const dialogVisible = ref(false)
const saving = ref(false)
const editingId = ref(null)
const form = reactive({ name: '', sort: 1, status: 1 })
async function load() {
loading.value = true
try {
const res = await listDramaCategoriesApi()
list.value = res.data || []
} finally {
loading.value = false
}
}
function nextSort() {
return list.value.reduce((max, item) => Math.max(max, item.sort || 0), 0) + 1
}
function openCreate() {
editingId.value = null
Object.assign(form, { name: '', sort: nextSort(), status: 1 })
dialogVisible.value = true
}
function openEdit(row) {
editingId.value = row.id
Object.assign(form, { name: row.name, sort: row.sort ?? 0, status: row.status ?? 1 })
dialogVisible.value = true
}
async function saveCategory() {
if (!form.name.trim()) return ElMessage.warning('请填写类型名称')
saving.value = true
try {
const payload = { name: form.name.trim(), sort: form.sort, status: form.status }
if (editingId.value) {
await updateDramaCategoryApi(editingId.value, payload)
ElMessage.success('类型已更新')
} else {
await createDramaCategoryApi(payload)
ElMessage.success('类型已创建')
}
dialogVisible.value = false
await load()
} finally {
saving.value = false
}
}
async function confirmDelete(row) {
const count = row.dramaCount || 0
try {
await ElMessageBox.confirm(
count > 0
? `「${row.name}」下还有 ${count} 部短剧,删除会被拒绝。确定继续吗?`
: `确定删除类型「${row.name}」吗?`,
'删除确认',
{
confirmButtonText: '确认删除',
cancelButtonText: '取消',
type: 'warning',
confirmButtonClass: 'el-button--danger'
}
)
} catch {
return
}
await deleteDramaCategoryApi(row.id)
ElMessage.success('类型已删除')
await load()
}
onMounted(load)
</script>
<template>
<PageHeading
eyebrow="内容管理"
title="类型管理"
description="维护短剧类型,供新建短剧选择,也作为客户端分类筛选的依据。"
>
<el-button v-if="can('drama:create')" type="primary" class="primary-button" @click="openCreate">
<AppIcon :icon="AppIcons.add" />
新建类型
</el-button>
</PageHeading>
<section class="panel">
<el-table
v-loading="loading"
:data="list"
row-key="id"
border
class="drama-el-table"
empty-text="还没有短剧类型"
>
<el-table-column type="index" label="序号" width="80" />
<el-table-column prop="name" label="类型名称" min-width="200" />
<el-table-column label="短剧数" width="110">
<template #default="{ row }">{{ row.dramaCount || 0 }} 部</template>
</el-table-column>
<el-table-column prop="sort" label="排序" width="100" />
<el-table-column label="状态" width="110">
<template #default="{ row }">
<el-tag :type="row.status === 1 ? 'success' : 'info'" effect="light">{{
row.status === 1 ? '启用' : '停用'
}}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="200" fixed="right">
<template #default="{ row }">
<div class="table-actions">
<el-button v-if="can('drama:update')" type="primary" size="small" @click="openEdit(row)"
>编辑</el-button
>
<el-button
v-if="can('drama:delete')"
type="danger"
size="small"
@click="confirmDelete(row)"
>删除</el-button
>
</div>
</template>
</el-table-column>
</el-table>
</section>
<el-dialog v-model="dialogVisible" :title="editingId ? '编辑类型' : '新建类型'" width="460px">
<el-form label-position="top">
<el-form-item label="类型名称" required>
<el-input v-model="form.name" maxlength="20" placeholder="例如:都市情感" />
</el-form-item>
<div class="form-row">
<el-form-item label="排序">
<el-input-number v-model="form.sort" :min="0" :max="999" />
</el-form-item>
<el-form-item label="状态">
<el-switch v-model="form.status" :active-value="1" :inactive-value="0" />
</el-form-item>
</div>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" :loading="saving" @click="saveCategory">保存</el-button>
</template>
</el-dialog>
</template>