feat(admin): 内容管理支持多语言和标签
This commit is contained in:
1 parent
eaee765239
commit
2b2c6bd708
14 files changed
+1080
-458
No files matched your search
@@ -4,6 +4,12 @@
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import {
|
||||
languageCodes,
|
||||
languageLabel,
|
||||
localesFromColumns,
|
||||
payloadLocales
|
||||
} from '@/constants/contentLanguages'
|
||||
import {
|
||||
createDramaCategoryApi,
|
||||
deleteDramaCategoryApi,
|
||||
@@ -11,6 +17,7 @@ import {
|
||||
updateDramaCategoryApi
|
||||
} from '@/api/admin/drama'
|
||||
import { useRbac } from '@/stores/rbac'
|
||||
import LocaleTextFields from '@/views/components/LocaleTextFields.vue'
|
||||
import PageHeading from '@/views/components/PageHeading.vue'
|
||||
|
||||
const { can } = useRbac()
|
||||
@@ -20,7 +27,8 @@ const list = ref([])
|
||||
const dialogVisible = ref(false)
|
||||
const saving = ref(false)
|
||||
const editingId = ref(null)
|
||||
const form = reactive({ name: '', sort: 1, status: 1 })
|
||||
const languages = ref(['zh'])
|
||||
const form = reactive({ locales: { zh: '' }, sort: 1, status: 1 })
|
||||
|
||||
async function load() {
|
||||
loading.value = true
|
||||
@@ -38,21 +46,29 @@ function nextSort() {
|
||||
|
||||
function openCreate() {
|
||||
editingId.value = null
|
||||
Object.assign(form, { name: '', sort: nextSort(), status: 1 })
|
||||
languages.value = ['zh']
|
||||
Object.assign(form, { locales: { zh: '' }, 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 })
|
||||
const locales = localesFromColumns(row.locales, row.name, row.nameEn, row.nameId)
|
||||
languages.value = languageCodes(locales)
|
||||
Object.assign(form, { locales, sort: row.sort ?? 0, status: row.status ?? 1 })
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
async function saveCategory() {
|
||||
if (!form.name.trim()) return ElMessage.warning('请填写类型名称')
|
||||
const locales = payloadLocales(form.locales, languages.value)
|
||||
const missing = languages.value.find((code) => !locales[code])
|
||||
if (!locales.zh || missing) {
|
||||
ElMessage.warning(missing ? `请填写${languageLabel(missing)}名称` : '请填写中文名称')
|
||||
return
|
||||
}
|
||||
saving.value = true
|
||||
try {
|
||||
const payload = { name: form.name.trim(), sort: form.sort, status: form.status }
|
||||
const payload = { name: locales.zh, locales, sort: form.sort, status: form.status }
|
||||
if (editingId.value) {
|
||||
await updateDramaCategoryApi(editingId.value, payload)
|
||||
ElMessage.success('类型已更新')
|
||||
@@ -115,7 +131,20 @@ onMounted(load)
|
||||
empty-text="还没有短剧类型"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="80" />
|
||||
<el-table-column prop="name" label="类型名称" min-width="200" />
|
||||
<el-table-column prop="name" label="类型名称" min-width="160" />
|
||||
<el-table-column label="语言" min-width="180">
|
||||
<template #default="{ row }">
|
||||
<el-tag
|
||||
v-for="code in languageCodes(
|
||||
row.locales || localesFromColumns(null, row.name, row.nameEn, row.nameId)
|
||||
)"
|
||||
:key="code"
|
||||
effect="light"
|
||||
class="locale-tag"
|
||||
>{{ languageLabel(code) }}</el-tag
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="短剧数" width="110">
|
||||
<template #default="{ row }">{{ row.dramaCount || 0 }} 部</template>
|
||||
</el-table-column>
|
||||
@@ -146,11 +175,14 @@ onMounted(load)
|
||||
</el-table>
|
||||
</section>
|
||||
|
||||
<el-dialog v-model="dialogVisible" :title="editingId ? '编辑类型' : '新建类型'" width="460px">
|
||||
<el-dialog v-model="dialogVisible" :title="editingId ? '编辑类型' : '新建类型'" width="560px">
|
||||
<el-form label-position="top">
|
||||
<el-form-item label="类型名称" required>
|
||||
<el-input v-model="form.name" maxlength="20" placeholder="例如:都市情感" />
|
||||
</el-form-item>
|
||||
<LocaleTextFields
|
||||
v-model:languages="languages"
|
||||
:locales="form.locales"
|
||||
label="名称"
|
||||
:maxlength="64"
|
||||
/>
|
||||
<div class="form-row">
|
||||
<el-form-item label="排序">
|
||||
<el-input-number v-model="form.sort" :min="0" :max="999" />
|
||||
@@ -166,3 +198,9 @@ onMounted(load)
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.locale-tag + .locale-tag {
|
||||
margin-left: 6px;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user