|
@@ -1,32 +1,66 @@
|
|
|
<script setup lang='ts'>
|
|
<script setup lang='ts'>
|
|
|
import Back from '@/components/back.uvue'
|
|
import Back from '@/components/back.uvue'
|
|
|
import Loading from '@/components/loading.uvue'
|
|
import Loading from '@/components/loading.uvue'
|
|
|
-import { ref, onMounted } from 'vue'
|
|
|
|
|
|
|
+import { ref, onMounted, nextTick } from 'vue'
|
|
|
import { type SubjectKnowledgeCardResult, getSubjectKnowledgeCard } from '@/services/subject/card'
|
|
import { type SubjectKnowledgeCardResult, getSubjectKnowledgeCard } from '@/services/subject/card'
|
|
|
import { fetchSubjectConfigInfo } from '@/services/subject/info'
|
|
import { fetchSubjectConfigInfo } from '@/services/subject/info'
|
|
|
import type { SubjectCatalogResult } from '@/services/subject/catalog'
|
|
import type { SubjectCatalogResult } from '@/services/subject/catalog'
|
|
|
|
|
+// import uni from "@dcloudio/vite-plugin-uni";
|
|
|
|
|
|
|
|
const activeCategory = ref<string>()
|
|
const activeCategory = ref<string>()
|
|
|
const activeTab = ref<string>('knowledge')
|
|
const activeTab = ref<string>('knowledge')
|
|
|
const isLoading = ref(true)
|
|
const isLoading = ref(true)
|
|
|
const categories = ref<SubjectCatalogResult[]>([])
|
|
const categories = ref<SubjectCatalogResult[]>([])
|
|
|
-
|
|
|
|
|
const cards = ref<SubjectKnowledgeCardResult[]>([])
|
|
const cards = ref<SubjectKnowledgeCardResult[]>([])
|
|
|
|
|
+const cardsScrollView = ref<any>(null)
|
|
|
|
|
+const categoryRefs = ref<any>()
|
|
|
async function getDataList() {
|
|
async function getDataList() {
|
|
|
- const res = await fetchSubjectConfigInfo({ id: '69afc7e048070409048c06b6' })
|
|
|
|
|
|
|
+ const res = await getSubjectKnowledgeCard({ subjectId: '69afc7e048070409048c06b6' })
|
|
|
|
|
+ cards.value = res.userCardList || []
|
|
|
categories.value = res.catalogList || []
|
|
categories.value = res.catalogList || []
|
|
|
- handleSelect(res.id as string)
|
|
|
|
|
}
|
|
}
|
|
|
-function handleSelect(subjectId: string) {
|
|
|
|
|
- activeCategory.value = subjectId
|
|
|
|
|
- getSubjectKnowledgeCard({ subjectId }).then(res => {
|
|
|
|
|
- console.log(res)
|
|
|
|
|
- cards.value = res.catalogList || []
|
|
|
|
|
|
|
+function handleSelect(categoryId: string) {
|
|
|
|
|
+ activeCategory.value = categoryId
|
|
|
|
|
+ // 滚动到对应分类位置
|
|
|
|
|
+ console.log(11, categoryRefs.value)
|
|
|
|
|
+ //找到第一个元素上categoryId属性与categoryId相同的元素
|
|
|
|
|
+ const element = categoryRefs.value.find((item: any) => {
|
|
|
|
|
+ return item.dataset.category === categoryId
|
|
|
})
|
|
})
|
|
|
|
|
+ console.log(11, element)
|
|
|
|
|
+ if (element) {
|
|
|
|
|
+ const rect = element.getBoundingClientRect()
|
|
|
|
|
+ console.log(rect)
|
|
|
|
|
+ if (cardsScrollView.value) {
|
|
|
|
|
+ cardsScrollView.value.scrollTo({
|
|
|
|
|
+ top: rect.top, // 减去顶部偏移
|
|
|
|
|
+ animated: true
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function onScroll(e: any) {
|
|
|
|
|
+ const scrollTop = e.detail.scrollTop
|
|
|
|
|
+ // 遍历所有分类,检查哪个分类在可视区域
|
|
|
|
|
+ for (const category of categories.value) {
|
|
|
|
|
+ const element = categoryRefs.value[category.id]
|
|
|
|
|
+ if (element) {
|
|
|
|
|
+ const rect = element.getBoundingClientRect()
|
|
|
|
|
+ // 检查元素是否在可视区域内
|
|
|
|
|
+ if (rect.top <= 150 && rect.bottom >= 150) {
|
|
|
|
|
+ activeCategory.value = category.id
|
|
|
|
|
+ break
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
|
await getDataList()
|
|
await getDataList()
|
|
|
isLoading.value = false
|
|
isLoading.value = false
|
|
|
|
|
+ nextTick(() => {
|
|
|
|
|
+ handleSelect(categories.value[0].id as string)
|
|
|
|
|
+ })
|
|
|
})
|
|
})
|
|
|
</script>
|
|
</script>
|
|
|
<template>
|
|
<template>
|
|
@@ -52,11 +86,13 @@ onMounted(async () => {
|
|
|
<view class="tab" :class="{ active: activeTab === 'honor' }" @tap="activeTab = 'honor'">荣誉</view>
|
|
<view class="tab" :class="{ active: activeTab === 'honor' }" @tap="activeTab = 'honor'">荣誉</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
- <scroll-view direction="vertical" :show-scrollbar="false" class="cards">
|
|
|
|
|
|
|
+ <scroll-view direction="vertical" :show-scrollbar="false" class="cards" ref="cardsScrollView"
|
|
|
|
|
+ @scroll="onScroll">
|
|
|
<view class="grid grid-cols-5 gap-4">
|
|
<view class="grid grid-cols-5 gap-4">
|
|
|
- <view class="card" v-for="card in cards" :key="card.id">
|
|
|
|
|
- <image src="/static/home/21.png" class="w-full h-full" />
|
|
|
|
|
- <view class="card-title">{{ card.name }}</view>
|
|
|
|
|
|
|
+ <view class="card" v-for="card in cards" :key="card.id" :data-category="card.catalogId" ref="categoryRefs">
|
|
|
|
|
+ <image v-if="card.userCardId" :src="card.iconPath" class="w-full h-full" />
|
|
|
|
|
+ <image v-else src="https://oss.xiaoxiongcode.com/static/home/21.png" class="w-full h-full" />
|
|
|
|
|
+ <view class="card-title">{{ card.cardName }}</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</scroll-view>
|
|
</scroll-view>
|
|
@@ -132,6 +168,14 @@ onMounted(async () => {
|
|
|
height: calc(100vh - 90px);
|
|
height: calc(100vh - 90px);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ .category-section {
|
|
|
|
|
+ margin-bottom: 40px;
|
|
|
|
|
+
|
|
|
|
|
+ .category-title {
|
|
|
|
|
+ @apply text-white font-bold text-xl mb-4;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
.card {
|
|
.card {
|
|
|
// background-color: rgba(255, 255, 255, 0.9);
|
|
// background-color: rgba(255, 255, 255, 0.9);
|
|
|
// border-radius: 16px;
|
|
// border-radius: 16px;
|