feat(admin): 内容管理支持多语言和标签
This commit is contained in:
1 parent
eaee765239
commit
2b2c6bd708
14 files changed
+1080
-458
No files matched your search
@@ -6,6 +6,12 @@ import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { AppIcon } from '@/components/AppIcon'
|
||||
import { AppIcons } from '@/constants/icons'
|
||||
import {
|
||||
languageCodes,
|
||||
languageLabel,
|
||||
localesFromColumns,
|
||||
payloadLocales
|
||||
} from '@/constants/contentLanguages'
|
||||
import {
|
||||
bindPlaylistCategoryDramasApi,
|
||||
createPlaylistCategoryApi,
|
||||
@@ -18,6 +24,7 @@ import {
|
||||
} from '@/api/admin/dramaPlaylistCategory'
|
||||
import { statusClass } from '@/utils/status'
|
||||
import { useRbac } from '@/stores/rbac'
|
||||
import LocaleTextFields from '@/views/components/LocaleTextFields.vue'
|
||||
import PageHeading from '@/views/components/PageHeading.vue'
|
||||
|
||||
const { can } = useRbac()
|
||||
@@ -46,7 +53,14 @@ const keyword = ref('')
|
||||
const dialogVisible = ref(false)
|
||||
const saving = ref(false)
|
||||
const editingId = ref(null)
|
||||
const form = reactive({ name: '', description: '', sort: 1, status: 1 })
|
||||
const languages = ref(['zh'])
|
||||
const emptyForm = () => ({
|
||||
locales: { zh: '' },
|
||||
descriptionLocales: { zh: '' },
|
||||
sort: 1,
|
||||
status: 1
|
||||
})
|
||||
const form = reactive(emptyForm())
|
||||
|
||||
const candidateVisible = ref(false)
|
||||
const candidateLoading = ref(false)
|
||||
@@ -108,18 +122,37 @@ function changePage(value) {
|
||||
loadDramas()
|
||||
}
|
||||
|
||||
function changeLanguages(codes) {
|
||||
languages.value = codes
|
||||
codes.forEach((code) => {
|
||||
if (form.descriptionLocales[code] == null) form.descriptionLocales[code] = ''
|
||||
})
|
||||
}
|
||||
|
||||
function openCreate() {
|
||||
editingId.value = null
|
||||
languages.value = ['zh']
|
||||
const maxSort = categories.value.reduce((max, item) => Math.max(max, item.sort || 0), 0)
|
||||
Object.assign(form, { name: '', description: '', sort: maxSort + 1, status: 1 })
|
||||
Object.assign(form, emptyForm(), { sort: maxSort + 1 })
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
function openEdit(row) {
|
||||
editingId.value = row.id
|
||||
const locales = localesFromColumns(row.locales, row.name, row.nameEn, row.nameId)
|
||||
languages.value = languageCodes(locales)
|
||||
const descriptionLocales = localesFromColumns(
|
||||
row.descriptionLocales,
|
||||
row.description,
|
||||
row.descriptionEn,
|
||||
row.descriptionId
|
||||
)
|
||||
languages.value.forEach((code) => {
|
||||
if (descriptionLocales[code] == null) descriptionLocales[code] = ''
|
||||
})
|
||||
Object.assign(form, {
|
||||
name: row.name,
|
||||
description: row.description || '',
|
||||
locales,
|
||||
descriptionLocales,
|
||||
sort: row.sort ?? 0,
|
||||
status: row.status ?? 1
|
||||
})
|
||||
@@ -127,15 +160,18 @@ function openEdit(row) {
|
||||
}
|
||||
|
||||
async function saveCategory() {
|
||||
if (!form.name.trim()) {
|
||||
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(),
|
||||
description: form.description.trim(),
|
||||
name: locales.zh,
|
||||
locales,
|
||||
descriptionLocales: payloadLocales(form.descriptionLocales, languages.value),
|
||||
sort: form.sort,
|
||||
status: form.status
|
||||
}
|
||||
@@ -390,22 +426,25 @@ onMounted(loadCategories)
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="editingId ? '编辑剧单分类' : '新建剧单分类'"
|
||||
width="460px"
|
||||
width="640px"
|
||||
>
|
||||
<el-form label-position="top">
|
||||
<el-form-item label="分类名称" required>
|
||||
<el-input v-model="form.name" maxlength="20" placeholder="例如:本周必看" />
|
||||
</el-form-item>
|
||||
<el-form-item label="描述">
|
||||
<el-input
|
||||
v-model="form.description"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
maxlength="255"
|
||||
show-word-limit
|
||||
placeholder="分类用途说明"
|
||||
/>
|
||||
</el-form-item>
|
||||
<LocaleTextFields
|
||||
:languages="languages"
|
||||
:locales="form.locales"
|
||||
label="名称"
|
||||
:maxlength="64"
|
||||
@update:languages="changeLanguages"
|
||||
/>
|
||||
<LocaleTextFields
|
||||
:languages="languages"
|
||||
:locales="form.descriptionLocales"
|
||||
label="描述"
|
||||
:maxlength="255"
|
||||
multiline
|
||||
:show-languages="false"
|
||||
:required="false"
|
||||
/>
|
||||
<div class="playlist-form-row">
|
||||
<el-form-item label="排序">
|
||||
<el-input-number v-model="form.sort" :min="0" :max="999" />
|
||||
|
||||
Reference in new issue
Block a user