This commit is contained in:
1 parent
23026dc371
commit
9ce014e7b3
4 files changed
+217
-20
No files matched your search
@@ -4,11 +4,14 @@ import request from '@/axios'
|
|||||||
import type { PageResult } from './types'
|
import type { PageResult } from './types'
|
||||||
|
|
||||||
export interface DramaClassificationItem {
|
export interface DramaClassificationItem {
|
||||||
id: number
|
id: string
|
||||||
name: string
|
name: string
|
||||||
|
code: string
|
||||||
nameEn: string
|
nameEn: string
|
||||||
nameId: string
|
nameId: string
|
||||||
locales?: Record<string, string>
|
locales?: Record<string, string>
|
||||||
|
layoutType: 'GRID' | 'RANKING'
|
||||||
|
revision: string
|
||||||
sort: number
|
sort: number
|
||||||
status: number
|
status: number
|
||||||
dramaCount: number
|
dramaCount: number
|
||||||
@@ -18,17 +21,20 @@ export interface DramaClassificationItem {
|
|||||||
export interface DramaClassificationSaveData {
|
export interface DramaClassificationSaveData {
|
||||||
name: string
|
name: string
|
||||||
locales: Record<string, string>
|
locales: Record<string, string>
|
||||||
|
code?: string
|
||||||
|
layoutType?: 'GRID' | 'RANKING'
|
||||||
sort?: number
|
sort?: number
|
||||||
status?: number
|
status?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ClassificationDramaItem {
|
export interface ClassificationDramaItem {
|
||||||
id: number
|
id: string
|
||||||
title: string
|
title: string
|
||||||
cover: string
|
cover: string
|
||||||
status: string
|
status: string
|
||||||
totalEpisodes: number
|
totalEpisodes: number
|
||||||
sort: number
|
sort: number
|
||||||
|
position?: number
|
||||||
updatedAt: string
|
updatedAt: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,19 +49,19 @@ export const listClassificationsApi = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const createClassificationApi = (data: DramaClassificationSaveData) => {
|
export const createClassificationApi = (data: DramaClassificationSaveData) => {
|
||||||
return request.post<number>({ url: '/admin/drama-classifications', data })
|
return request.post<string>({ url: '/admin/drama-classifications', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updateClassificationApi = (id: number, data: DramaClassificationSaveData) => {
|
export const updateClassificationApi = (id: string, data: DramaClassificationSaveData) => {
|
||||||
return request.put<void>({ url: `/admin/drama-classifications/${id}`, data })
|
return request.put<void>({ url: `/admin/drama-classifications/${id}`, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deleteClassificationApi = (id: number) => {
|
export const deleteClassificationApi = (id: string) => {
|
||||||
return request.delete<void>({ url: `/admin/drama-classifications/${id}` })
|
return request.delete<void>({ url: `/admin/drama-classifications/${id}` })
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 分类下已关联的短剧 */
|
/** 分类下已关联的短剧 */
|
||||||
export const listClassificationDramasApi = (id: number, params: ClassificationDramaPageParams) => {
|
export const listClassificationDramasApi = (id: string, params: ClassificationDramaPageParams) => {
|
||||||
return request.get<PageResult<ClassificationDramaItem>>({
|
return request.get<PageResult<ClassificationDramaItem>>({
|
||||||
url: `/admin/drama-classifications/${id}/dramas`,
|
url: `/admin/drama-classifications/${id}/dramas`,
|
||||||
params
|
params
|
||||||
@@ -64,7 +70,7 @@ export const listClassificationDramasApi = (id: number, params: ClassificationDr
|
|||||||
|
|
||||||
/** 尚未关联到该分类的短剧(添加弹窗用) */
|
/** 尚未关联到该分类的短剧(添加弹窗用) */
|
||||||
export const listClassificationDramaCandidatesApi = (
|
export const listClassificationDramaCandidatesApi = (
|
||||||
id: number,
|
id: string,
|
||||||
params: ClassificationDramaPageParams
|
params: ClassificationDramaPageParams
|
||||||
) => {
|
) => {
|
||||||
return request.get<PageResult<ClassificationDramaItem>>({
|
return request.get<PageResult<ClassificationDramaItem>>({
|
||||||
@@ -74,7 +80,7 @@ export const listClassificationDramaCandidatesApi = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 批量关联短剧,返回实际新增数量 */
|
/** 批量关联短剧,返回实际新增数量 */
|
||||||
export const bindClassificationDramasApi = (id: number, dramaIds: number[]) => {
|
export const bindClassificationDramasApi = (id: string, dramaIds: string[]) => {
|
||||||
return request.post<number>({
|
return request.post<number>({
|
||||||
url: `/admin/drama-classifications/${id}/dramas`,
|
url: `/admin/drama-classifications/${id}/dramas`,
|
||||||
data: { dramaIds }
|
data: { dramaIds }
|
||||||
@@ -82,8 +88,16 @@ export const bindClassificationDramasApi = (id: number, dramaIds: number[]) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 从分类移除短剧 */
|
/** 从分类移除短剧 */
|
||||||
export const unbindClassificationDramaApi = (id: number, dramaId: number) => {
|
export const unbindClassificationDramaApi = (id: string, dramaId: string) => {
|
||||||
return request.delete<void>({
|
return request.delete<void>({
|
||||||
url: `/admin/drama-classifications/${id}/dramas/${dramaId}`
|
url: `/admin/drama-classifications/${id}/dramas/${dramaId}`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 原子保存推荐榜完整内容与顺序 */
|
||||||
|
export const saveRankingItemsApi = (id: string, dramaIds: string[]) => {
|
||||||
|
return request.put<void>({
|
||||||
|
url: `/admin/drama-classifications/${id}/ranking-items`,
|
||||||
|
data: { dramaIds }
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { computed, onMounted, reactive, ref } from 'vue'
|
import { computed, onMounted, reactive, ref } from 'vue'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import { VueDraggable } from 'vue-draggable-plus'
|
||||||
import { AppIcon } from '@/components/AppIcon'
|
import { AppIcon } from '@/components/AppIcon'
|
||||||
import { AppIcons } from '@/constants/icons'
|
import { AppIcons } from '@/constants/icons'
|
||||||
import {
|
import {
|
||||||
@@ -19,6 +20,7 @@ import {
|
|||||||
listClassificationDramaCandidatesApi,
|
listClassificationDramaCandidatesApi,
|
||||||
listClassificationDramasApi,
|
listClassificationDramasApi,
|
||||||
listClassificationsApi,
|
listClassificationsApi,
|
||||||
|
saveRankingItemsApi,
|
||||||
unbindClassificationDramaApi,
|
unbindClassificationDramaApi,
|
||||||
updateClassificationApi
|
updateClassificationApi
|
||||||
} from '@/api/admin/dramaClassification'
|
} from '@/api/admin/dramaClassification'
|
||||||
@@ -43,6 +45,7 @@ const activeId = ref(null)
|
|||||||
const activeClassification = computed(
|
const activeClassification = computed(
|
||||||
() => classifications.value.find((item) => item.id === activeId.value) || null
|
() => classifications.value.find((item) => item.id === activeId.value) || null
|
||||||
)
|
)
|
||||||
|
const isRanking = computed(() => activeClassification.value?.layoutType === 'RANKING')
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const dramas = ref([])
|
const dramas = ref([])
|
||||||
@@ -50,12 +53,19 @@ const total = ref(0)
|
|||||||
const pageIndex = ref(1)
|
const pageIndex = ref(1)
|
||||||
const pageSize = ref(10)
|
const pageSize = ref(10)
|
||||||
const keyword = ref('')
|
const keyword = ref('')
|
||||||
|
const rankingDirty = ref(false)
|
||||||
|
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const saving = ref(false)
|
const saving = ref(false)
|
||||||
const editingId = ref(null)
|
const editingId = ref(null)
|
||||||
const languages = ref(['zh'])
|
const languages = ref(['zh'])
|
||||||
const emptyForm = () => ({ locales: { zh: '' }, sort: 1, status: 1 })
|
const emptyForm = () => ({
|
||||||
|
locales: { zh: '' },
|
||||||
|
code: '',
|
||||||
|
layoutType: 'GRID',
|
||||||
|
sort: 1,
|
||||||
|
status: 1
|
||||||
|
})
|
||||||
const form = reactive(emptyForm())
|
const form = reactive(emptyForm())
|
||||||
|
|
||||||
const candidateVisible = ref(false)
|
const candidateVisible = ref(false)
|
||||||
@@ -91,10 +101,11 @@ async function loadDramas() {
|
|||||||
const res = await listClassificationDramasApi(activeId.value, {
|
const res = await listClassificationDramasApi(activeId.value, {
|
||||||
keyword: keyword.value || undefined,
|
keyword: keyword.value || undefined,
|
||||||
pageIndex: pageIndex.value,
|
pageIndex: pageIndex.value,
|
||||||
pageSize: pageSize.value
|
pageSize: isRanking.value ? 50 : pageSize.value
|
||||||
})
|
})
|
||||||
dramas.value = res.data?.list || []
|
dramas.value = res.data?.list || []
|
||||||
total.value = res.data?.total || 0
|
total.value = res.data?.total || 0
|
||||||
|
rankingDirty.value = false
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@@ -105,6 +116,7 @@ function selectClassification(row) {
|
|||||||
activeId.value = row.id
|
activeId.value = row.id
|
||||||
pageIndex.value = 1
|
pageIndex.value = 1
|
||||||
keyword.value = ''
|
keyword.value = ''
|
||||||
|
rankingDirty.value = false
|
||||||
loadDramas()
|
loadDramas()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +144,8 @@ function openEdit(row) {
|
|||||||
languages.value = languageCodes(locales)
|
languages.value = languageCodes(locales)
|
||||||
Object.assign(form, {
|
Object.assign(form, {
|
||||||
locales,
|
locales,
|
||||||
|
code: row.code || '',
|
||||||
|
layoutType: row.layoutType || 'GRID',
|
||||||
sort: row.sort ?? 0,
|
sort: row.sort ?? 0,
|
||||||
status: row.status ?? 1
|
status: row.status ?? 1
|
||||||
})
|
})
|
||||||
@@ -150,6 +164,10 @@ async function saveClassification() {
|
|||||||
const payload = {
|
const payload = {
|
||||||
name: locales.zh,
|
name: locales.zh,
|
||||||
locales,
|
locales,
|
||||||
|
code:
|
||||||
|
form.code ||
|
||||||
|
(form.layoutType === 'RANKING' && !editingId.value ? 'RECOMMEND_RANKING' : undefined),
|
||||||
|
layoutType: form.layoutType,
|
||||||
sort: form.sort,
|
sort: form.sort,
|
||||||
status: form.status
|
status: form.status
|
||||||
}
|
}
|
||||||
@@ -197,7 +215,12 @@ async function removeDrama(row) {
|
|||||||
} catch {
|
} catch {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
await unbindClassificationDramaApi(activeId.value, row.id)
|
if (isRanking.value) {
|
||||||
|
const remaining = dramas.value.filter((item) => item.id !== row.id).map((item) => item.id)
|
||||||
|
await saveRankingItemsApi(activeId.value, remaining)
|
||||||
|
} else {
|
||||||
|
await unbindClassificationDramaApi(activeId.value, row.id)
|
||||||
|
}
|
||||||
ElMessage.success('已移出')
|
ElMessage.success('已移出')
|
||||||
await Promise.all([loadDramas(), loadClassifications()])
|
await Promise.all([loadDramas(), loadClassifications()])
|
||||||
}
|
}
|
||||||
@@ -247,11 +270,23 @@ async function confirmBind() {
|
|||||||
}
|
}
|
||||||
binding.value = true
|
binding.value = true
|
||||||
try {
|
try {
|
||||||
const res = await bindClassificationDramasApi(
|
if (isRanking.value) {
|
||||||
activeId.value,
|
const existingIds = dramas.value.map((item) => item.id)
|
||||||
selectedDramas.value.map((item) => item.id)
|
const selectedIds = selectedDramas.value.map((item) => item.id)
|
||||||
)
|
const nextIds = [...new Set([...existingIds, ...selectedIds])]
|
||||||
ElMessage.success(`已关联 ${res.data ?? selectedDramas.value.length} 部短剧`)
|
if (nextIds.length > 50) {
|
||||||
|
ElMessage.warning('推荐榜最多 50 部短剧')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await saveRankingItemsApi(activeId.value, nextIds)
|
||||||
|
ElMessage.success(`推荐榜已增加 ${selectedIds.length} 部短剧`)
|
||||||
|
} else {
|
||||||
|
const res = await bindClassificationDramasApi(
|
||||||
|
activeId.value,
|
||||||
|
selectedDramas.value.map((item) => item.id)
|
||||||
|
)
|
||||||
|
ElMessage.success(`已关联 ${res.data ?? selectedDramas.value.length} 部短剧`)
|
||||||
|
}
|
||||||
candidateVisible.value = false
|
candidateVisible.value = false
|
||||||
await Promise.all([loadDramas(), loadClassifications()])
|
await Promise.all([loadDramas(), loadClassifications()])
|
||||||
} finally {
|
} finally {
|
||||||
@@ -259,6 +294,22 @@ async function confirmBind() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onRankingChange() {
|
||||||
|
dramas.value = dramas.value.map((item, index) => ({ ...item, position: index + 1 }))
|
||||||
|
rankingDirty.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveRankingOrder() {
|
||||||
|
if (!activeId.value || !dramas.value.length) return
|
||||||
|
await saveRankingItemsApi(
|
||||||
|
activeId.value,
|
||||||
|
dramas.value.map((item) => item.id)
|
||||||
|
)
|
||||||
|
rankingDirty.value = false
|
||||||
|
ElMessage.success('推荐榜顺序已保存')
|
||||||
|
await loadClassifications()
|
||||||
|
}
|
||||||
|
|
||||||
function formatTime(value) {
|
function formatTime(value) {
|
||||||
if (!value) return '—'
|
if (!value) return '—'
|
||||||
return String(value).replace('T', ' ').slice(0, 19)
|
return String(value).replace('T', ' ').slice(0, 19)
|
||||||
@@ -271,7 +322,7 @@ onMounted(loadClassifications)
|
|||||||
<PageHeading
|
<PageHeading
|
||||||
eyebrow="内容管理"
|
eyebrow="内容管理"
|
||||||
title="分类管理"
|
title="分类管理"
|
||||||
description="分类是运营自定义的分组,与「类型」无关;一个分类可以关联任意多部短剧。"
|
description="普通分类使用剧目网格;推荐榜使用独立排行布局,并按后台配置顺序展示。"
|
||||||
>
|
>
|
||||||
<el-button v-if="can('drama:create')" type="primary" class="primary-button" @click="openCreate">
|
<el-button v-if="can('drama:create')" type="primary" class="primary-button" @click="openCreate">
|
||||||
<AppIcon :icon="AppIcons.add" />
|
<AppIcon :icon="AppIcons.add" />
|
||||||
@@ -293,9 +344,11 @@ onMounted(loadClassifications)
|
|||||||
<div class="classification-toolbar__title">
|
<div class="classification-toolbar__title">
|
||||||
{{ activeClassification?.name || '请选择分类' }}
|
{{ activeClassification?.name || '请选择分类' }}
|
||||||
<small>共 {{ total }} 部关联短剧</small>
|
<small>共 {{ total }} 部关联短剧</small>
|
||||||
|
<el-tag v-if="isRanking" size="small" type="warning">推荐榜</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div class="classification-toolbar__search">
|
<div class="classification-toolbar__search">
|
||||||
<el-input
|
<el-input
|
||||||
|
v-if="!isRanking"
|
||||||
v-model="keyword"
|
v-model="keyword"
|
||||||
placeholder="搜索短剧名称"
|
placeholder="搜索短剧名称"
|
||||||
clearable
|
clearable
|
||||||
@@ -303,7 +356,15 @@ onMounted(loadClassifications)
|
|||||||
@keyup.enter="search"
|
@keyup.enter="search"
|
||||||
@clear="search"
|
@clear="search"
|
||||||
/>
|
/>
|
||||||
<el-button type="primary" plain @click="search">查询</el-button>
|
<el-button v-if="!isRanking" type="primary" plain @click="search">查询</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="isRanking && can('drama:update')"
|
||||||
|
type="primary"
|
||||||
|
:disabled="!rankingDirty"
|
||||||
|
@click="saveRankingOrder"
|
||||||
|
>
|
||||||
|
保存排序
|
||||||
|
</el-button>
|
||||||
<el-button v-if="can('drama:update')" :disabled="!activeId" @click="openCandidates">
|
<el-button v-if="can('drama:update')" :disabled="!activeId" @click="openCandidates">
|
||||||
<AppIcon :icon="AppIcons.add" />
|
<AppIcon :icon="AppIcons.add" />
|
||||||
添加短剧
|
添加短剧
|
||||||
@@ -311,7 +372,41 @@ onMounted(loadClassifications)
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<VueDraggable
|
||||||
|
v-if="isRanking"
|
||||||
|
v-model="dramas"
|
||||||
|
item-key="id"
|
||||||
|
handle=".ranking-row__drag"
|
||||||
|
class="ranking-list"
|
||||||
|
@end="onRankingChange"
|
||||||
|
>
|
||||||
|
<div v-for="(row, index) in dramas" :key="row.id" class="ranking-row">
|
||||||
|
<button class="ranking-row__drag" type="button" title="拖动调整排名">
|
||||||
|
<AppIcon :icon="AppIcons.drag" />
|
||||||
|
</button>
|
||||||
|
<span class="ranking-row__rank">{{ index + 1 }}</span>
|
||||||
|
<img v-if="row.cover" :src="row.cover" class="ranking-row__cover" alt="封面" />
|
||||||
|
<div v-else class="ranking-row__cover ranking-row__cover--empty">无</div>
|
||||||
|
<div class="ranking-row__content">
|
||||||
|
<strong>{{ row.title }}</strong>
|
||||||
|
<span class="status-dot" :class="statusClass(row.status)">
|
||||||
|
{{ STATUS_TEXT[row.status] || row.status }} · {{ row.totalEpisodes || 0 }} 集
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<el-button
|
||||||
|
v-if="can('drama:update')"
|
||||||
|
type="danger"
|
||||||
|
size="small"
|
||||||
|
@click="removeDrama(row)"
|
||||||
|
>
|
||||||
|
移出
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<el-empty v-if="!dramas.length" description="推荐榜还没有短剧" />
|
||||||
|
</VueDraggable>
|
||||||
|
|
||||||
<el-table
|
<el-table
|
||||||
|
v-else
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:data="dramas"
|
:data="dramas"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
@@ -353,7 +448,7 @@ onMounted(loadClassifications)
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div class="classification-pagination">
|
<div v-if="!isRanking" class="classification-pagination">
|
||||||
<el-pagination
|
<el-pagination
|
||||||
:current-page="pageIndex"
|
:current-page="pageIndex"
|
||||||
:page-size="pageSize"
|
:page-size="pageSize"
|
||||||
@@ -434,6 +529,74 @@ onMounted(loadClassifications)
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ranking-list {
|
||||||
|
display: grid;
|
||||||
|
gap: 1px;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid var(--el-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ranking-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 36px 48px 52px minmax(0, 1fr) auto;
|
||||||
|
min-height: 72px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: var(--el-bg-color);
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ranking-row + .ranking-row {
|
||||||
|
border-top: 1px solid var(--el-border-color-lighter);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ranking-row__drag {
|
||||||
|
display: inline-flex;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
padding: 0;
|
||||||
|
color: var(--el-text-color-secondary);
|
||||||
|
cursor: grab;
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ranking-row__rank {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ranking-row__cover {
|
||||||
|
width: 44px;
|
||||||
|
height: 58px;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ranking-row__cover--empty {
|
||||||
|
display: flex;
|
||||||
|
color: var(--el-text-color-placeholder);
|
||||||
|
background: var(--el-fill-color-light);
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ranking-row__content {
|
||||||
|
display: grid;
|
||||||
|
min-width: 0;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ranking-row__content strong {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.classification-cover--empty {
|
.classification-cover--empty {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -64,6 +64,23 @@ const emit = defineEmits([
|
|||||||
@update:languages="emit('update:languages', $event)"
|
@update:languages="emit('update:languages', $event)"
|
||||||
@update:locales="emit('update:form', { ...form, locales: $event })"
|
@update:locales="emit('update:form', { ...form, locales: $event })"
|
||||||
/>
|
/>
|
||||||
|
<el-form-item label="展示样式">
|
||||||
|
<el-radio-group
|
||||||
|
:model-value="form.layoutType"
|
||||||
|
@update:model-value="emit('update:form', { ...form, layoutType: $event })"
|
||||||
|
>
|
||||||
|
<el-radio-button label="GRID">普通分类</el-radio-button>
|
||||||
|
<el-radio-button label="RANKING">推荐榜</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分类编码">
|
||||||
|
<el-input
|
||||||
|
:model-value="form.code"
|
||||||
|
maxlength="64"
|
||||||
|
placeholder="例如 RECOMMEND_RANKING"
|
||||||
|
@update:model-value="emit('update:form', { ...form, code: $event.toUpperCase() })"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
<div class="classification-form-row">
|
<div class="classification-form-row">
|
||||||
<el-form-item label="排序">
|
<el-form-item label="排序">
|
||||||
<el-input-number
|
<el-input-number
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ const { can } = useRbac()
|
|||||||
>
|
>
|
||||||
<div class="classification-list__main">
|
<div class="classification-list__main">
|
||||||
<span class="classification-list__name">{{ item.name }}</span>
|
<span class="classification-list__name">{{ item.name }}</span>
|
||||||
|
<el-tag v-if="item.layoutType === 'RANKING'" size="small" type="warning">
|
||||||
|
推荐榜
|
||||||
|
</el-tag>
|
||||||
<span class="classification-list__count">{{ item.dramaCount || 0 }}</span>
|
<span class="classification-list__count">{{ item.dramaCount || 0 }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="classification-list__actions" @click.stop>
|
<div class="classification-list__actions" @click.stop>
|
||||||
|
|||||||
Reference in new issue
Block a user