mat/frontend-h5/src/views/Home.vue

84 lines
3.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import { ref, onMounted, watch } from 'vue'
import { useRouter } from 'vue-router'
import MajorCategoryCard from '@/components/MajorCategoryCard.vue'
import CategoryCard from '@/components/CategoryCard.vue'
import Skeleton from '@/components/Skeleton.vue'
import { useAuthStore } from '@/store/auth'
import { useUiStore } from '@/store/ui'
import { fetchCategoriesByMajor } from '@/api/material'
defineOptions({ name: 'Home' })
const router = useRouter()
const auth = useAuthStore()
const ui = useUiStore()
const majors = [
{ value: 'architecture', label: '建筑' },
{ value: 'landscape', label: '景观' },
{ value: 'equipment', label: '设备' },
{ value: 'decoration', label: '装修' },
]
const selected = ref(ui.selectedMajor)
const categories = ref([])
const loading = ref(false)
const loadCategories = async (major) => {
if (!major) { categories.value = []; return }
loading.value = true
try { categories.value = await fetchCategoriesByMajor(major) }
finally { loading.value = false }
}
const onSelect = (v) => {
selected.value = selected.value === v ? '' : v
ui.setMajor(selected.value)
}
watch(selected, loadCategories, { immediate: true })
onMounted(async () => {
if (!auth.user) { try { await auth.loadUser() } catch {} }
})
const goCategory = (c) => router.push({ name: 'CategoryDetail', params: { major: selected.value, category: c.value } })
const onLogout = () => { auth.logout(); router.replace('/login') }
</script>
<template>
<div class="min-h-screen">
<header class="h-12 px-4 flex items-center justify-between bg-white border-b border-line">
<div class="text-sm text-muted">你好<span class="text-neutral-800 font-medium">{{ auth.user?.username || '' }}</span></div>
<button class="text-sm text-muted active:text-danger" @click="onLogout">退出</button>
</header>
<section class="p-4 grid grid-cols-2 gap-3">
<MajorCategoryCard v-for="m in majors" :key="m.value"
:label="m.label" :value="m.value" :active="selected === m.value"
@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" />
</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>
<div v-else class="py-10 text-center text-sm text-muted">该大类暂无已审核材料</div>
</div>
<div v-else class="py-10 text-center text-sm text-muted">点击上方分类查看细分种类</div>
</transition>
</section>
</div>
</template>
<style scoped>
.fade-enter-active,.fade-leave-active{transition:all .2s ease}
.fade-enter-from,.fade-leave-to{opacity:0;transform:translateY(-4px)}
</style>