fix(工单): 提交时校验
This commit is contained in:
parent
c6be29d756
commit
acea3b32f6
@ -75,7 +75,17 @@
|
||||
<el-cascader v-model='ticketForm.ticket_category_id' class='w-full' placeholder='请选择分类' :options='activeCategoryOptions' :props='categoryCascaderProps' />
|
||||
</el-form-item>
|
||||
<el-form-item label='标题'><el-input v-model='ticketForm.title' /></el-form-item>
|
||||
<el-form-item label='内容'><el-input v-model='ticketForm.content' type='textarea' :rows='6' /></el-form-item>
|
||||
<el-form-item label='内容'>
|
||||
<div class='ticket-content-field'>
|
||||
<el-input v-model='ticketForm.content' type='textarea' :rows='6' />
|
||||
<div v-if='selectedCategoryDescriptions.length > 0' class='category-descriptions'>
|
||||
<div v-for='item in selectedCategoryDescriptions' :key='item.id' class='category-description-line'>
|
||||
<span class='category-description-name'>{{ item.name }}</span>
|
||||
<span>{{ item.description }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click='ticketDialogVisible = false'>取消</el-button>
|
||||
@ -193,7 +203,6 @@ const perPage = ref(20)
|
||||
const filters = reactive<any>({ status: '', category_id: null, mine: false })
|
||||
const categories = ref<any[]>([])
|
||||
const categoryTree = ref<any[]>([])
|
||||
const activeCategories = computed(() => categories.value.filter((item) => item.is_active))
|
||||
const categoryCascaderProps = { value: 'id', label: 'name', checkStrictly: true, emitPath: false }
|
||||
const categoryOptions = computed(() => buildCategoryOptions(categoryTree.value))
|
||||
const activeCategoryOptions = computed(() => buildCategoryOptions(categoryTree.value, true))
|
||||
@ -262,14 +271,22 @@ function handleSizeChange(nextSize: number): void {
|
||||
}
|
||||
|
||||
function openCreateTicket(): void {
|
||||
Object.assign(ticketForm, { ticket_category_id: activeCategories.value[0]?.id || null, title: '', content: '' })
|
||||
Object.assign(ticketForm, { ticket_category_id: null, title: '', content: '' })
|
||||
ticketDialogVisible.value = true
|
||||
}
|
||||
|
||||
async function submitTicket(): Promise<void> {
|
||||
const ticketCategoryId = selectedCategoryId(ticketForm.ticket_category_id)
|
||||
if (!ticketCategoryId || !ticketForm.title?.trim() || !ticketForm.content?.trim()) {
|
||||
ElMessage.warning('请完整填写工单信息')
|
||||
if (!ticketCategoryId) {
|
||||
ElMessage.warning('请选择工单分类')
|
||||
return
|
||||
}
|
||||
if (!ticketForm.title?.trim()) {
|
||||
ElMessage.warning('请输入工单标题')
|
||||
return
|
||||
}
|
||||
if (!ticketForm.content?.trim()) {
|
||||
ElMessage.warning('请输入工单内容')
|
||||
return
|
||||
}
|
||||
savingTicket.value = true
|
||||
@ -415,6 +432,21 @@ function categoryLabel(categoryId: number | string | null | undefined): string {
|
||||
return path.length > 0 ? path.join(' / ') : '-'
|
||||
}
|
||||
|
||||
const selectedCategoryDescriptions = computed(() => {
|
||||
const categoryId = selectedCategoryId(ticketForm.ticket_category_id)
|
||||
if (!categoryId) {
|
||||
return []
|
||||
}
|
||||
|
||||
return findCategoryNodes(categoryTree.value, categoryId)
|
||||
.filter((item) => String(item.description || '').trim() !== '')
|
||||
.map((item) => ({
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
description: String(item.description || '').trim(),
|
||||
}))
|
||||
})
|
||||
|
||||
function findCategoryPath(items: any[], categoryId: number, parents: string[] = []): string[] {
|
||||
for (const item of items) {
|
||||
const nextPath = [...parents, item.name]
|
||||
@ -430,6 +462,21 @@ function findCategoryPath(items: any[], categoryId: number, parents: string[] =
|
||||
return []
|
||||
}
|
||||
|
||||
function findCategoryNodes(items: any[], categoryId: number, parents: any[] = []): any[] {
|
||||
for (const item of items) {
|
||||
const nextPath = [...parents, item]
|
||||
if (Number(item.id) === categoryId) {
|
||||
return nextPath
|
||||
}
|
||||
const childPath = findCategoryNodes(item.children || [], categoryId, nextPath)
|
||||
if (childPath.length > 0) {
|
||||
return childPath
|
||||
}
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
|
||||
async function removeCategory(row: any): Promise<void> {
|
||||
await ElMessageBox.confirm(`确认删除分类「${row.name}」吗?历史工单会保留但分类置空。`, '提示', { type: 'warning' })
|
||||
await ticketsApi.removeCategory(row.id)
|
||||
@ -474,4 +521,8 @@ onMounted(async () => {
|
||||
.message-box { border: 1px solid #e2e8f0; border-radius: 8px; padding: 10px; background: #f8fafc; }
|
||||
.message-sender { font-size: 12px; color: #64748b; margin-bottom: 6px; }
|
||||
.message-content { white-space: pre-wrap; color: #0f172a; }
|
||||
.ticket-content-field { width: 100%; display: flex; flex-direction: column; gap: 10px; }
|
||||
.category-descriptions { border: 1px solid #e5e7eb; border-radius: 6px; background: #f8fafc; padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; }
|
||||
.category-description-line { color: #334155; line-height: 1.5; word-break: break-word; }
|
||||
.category-description-name { color: #111827; font-weight: 600; margin-right: 8px; }
|
||||
</style>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user