feat(h5): 首页默认展示全部大类的材料种类,未选中时分组列出
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
a084f5c7e0
commit
1a0af18457
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { ref, onMounted, watch } from 'vue'
|
||||
import { ref, onMounted, computed, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import MajorCategoryCard from '@/components/MajorCategoryCard.vue'
|
||||
import CategoryCard from '@/components/CategoryCard.vue'
|
||||
|
|
@ -21,14 +21,17 @@ const majors = [
|
|||
]
|
||||
|
||||
const selected = ref(ui.selectedMajor)
|
||||
const categories = ref([])
|
||||
const categoriesByMajor = ref({})
|
||||
const loading = ref(false)
|
||||
|
||||
const loadCategories = async (major) => {
|
||||
if (!major) { categories.value = []; return }
|
||||
const loadAll = async () => {
|
||||
loading.value = true
|
||||
try { categories.value = await fetchCategoriesByMajor(major) }
|
||||
finally { loading.value = false }
|
||||
try {
|
||||
const results = await Promise.all(majors.map((m) => fetchCategoriesByMajor(m.value)))
|
||||
const map = {}
|
||||
majors.forEach((m, i) => { map[m.value] = results[i] })
|
||||
categoriesByMajor.value = map
|
||||
} finally { loading.value = false }
|
||||
}
|
||||
|
||||
const onSelect = (v) => {
|
||||
|
|
@ -36,13 +39,25 @@ const onSelect = (v) => {
|
|||
ui.setMajor(selected.value)
|
||||
}
|
||||
|
||||
watch(selected, loadCategories, { immediate: true })
|
||||
const visibleGroups = computed(() => {
|
||||
if (selected.value) {
|
||||
return [{ major: majors.find((m) => m.value === selected.value), categories: categoriesByMajor.value[selected.value] || [] }]
|
||||
}
|
||||
return majors.map((m) => ({ major: m, categories: categoriesByMajor.value[m.value] || [] }))
|
||||
})
|
||||
|
||||
watch(selected, (v) => {
|
||||
if (v && !categoriesByMajor.value[v]) {
|
||||
fetchCategoriesByMajor(v).then((r) => { categoriesByMajor.value = { ...categoriesByMajor.value, [v]: r } })
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
if (!auth.user) { try { await auth.loadUser() } catch {} }
|
||||
await loadAll()
|
||||
})
|
||||
|
||||
const goCategory = (c) => router.push({ name: 'CategoryDetail', params: { major: selected.value, category: c.value } })
|
||||
const goCategory = (major, c) => router.push({ name: 'CategoryDetail', params: { major, category: c.value } })
|
||||
const onLogout = () => { auth.logout(); router.replace('/login') }
|
||||
</script>
|
||||
|
||||
|
|
@ -59,20 +74,24 @@ const onLogout = () => { auth.logout(); router.replace('/login') }
|
|||
@click="onSelect(m.value)" />
|
||||
</section>
|
||||
|
||||
<section class="px-4 pb-6">
|
||||
<transition name="fade">
|
||||
<div v-if="selected">
|
||||
<div class="text-xs text-muted mb-2">细分种类</div>
|
||||
<div v-if="loading" class="grid grid-cols-2 gap-3">
|
||||
<Skeleton v-for="n in 4" :key="n" class="h-14" />
|
||||
<section class="px-4 pb-6 space-y-5">
|
||||
<div v-if="loading && !Object.keys(categoriesByMajor).length" class="grid grid-cols-2 gap-3">
|
||||
<Skeleton v-for="n in 6" :key="n" class="h-14" />
|
||||
</div>
|
||||
|
||||
<template v-else>
|
||||
<div v-for="g in visibleGroups" :key="g.major.value">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<div class="text-xs text-muted">{{ g.major.label }} · 材料种类</div>
|
||||
<span class="text-[11px] text-muted tnum">{{ g.categories.length }} 类</span>
|
||||
</div>
|
||||
<div v-else-if="categories.length" class="grid grid-cols-2 gap-3">
|
||||
<CategoryCard v-for="c in categories" :key="c.value" :value="c.value" :count="c.count" @click="goCategory(c)" />
|
||||
<div v-if="g.categories.length" class="grid grid-cols-2 gap-3">
|
||||
<CategoryCard v-for="c in g.categories" :key="c.value" :value="c.value" :count="c.count"
|
||||
@click="goCategory(g.major.value, c)" />
|
||||
</div>
|
||||
<div v-else class="py-10 text-center text-sm text-muted">该大类暂无已审核材料</div>
|
||||
<div v-else class="py-6 text-center text-xs text-muted bg-white rounded-card">暂无已审核材料</div>
|
||||
</div>
|
||||
<div v-else class="py-10 text-center text-sm text-muted">点击上方分类查看细分种类</div>
|
||||
</transition>
|
||||
</template>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
Loading…
Reference in New Issue