初始化参股
This commit is contained in:
272
前端/pages/cases/list.uvue
Normal file
272
前端/pages/cases/list.uvue
Normal file
@@ -0,0 +1,272 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<!-- 分类筛选 -->
|
||||
<view class="category-bar">
|
||||
<scroll-view class="category-scroll" scroll-x>
|
||||
<view class="category-list">
|
||||
<view
|
||||
class="category-item"
|
||||
:class="{ 'category-active': currentCategory == item.id }"
|
||||
v-for="item in categories"
|
||||
:key="item.id"
|
||||
@click="selectCategory(item.id)"
|
||||
>
|
||||
<text
|
||||
class="category-text"
|
||||
:class="{ 'category-text-active': currentCategory == item.id }"
|
||||
>{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 案例列表 -->
|
||||
<scroll-view
|
||||
class="case-scroll"
|
||||
scroll-y
|
||||
@scrolltolower="loadMore"
|
||||
>
|
||||
<view class="case-list">
|
||||
<case-card
|
||||
v-for="item in caseList"
|
||||
:key="item.id"
|
||||
:caseData="item"
|
||||
@click="goToDetail"
|
||||
></case-card>
|
||||
</view>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<view class="load-status">
|
||||
<text class="load-text" v-if="loading">加载中...</text>
|
||||
<text class="load-text" v-else-if="noMore">没有更多了</text>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view class="empty-state" v-if="!loading && caseList.length == 0">
|
||||
<text class="empty-icon">📭</text>
|
||||
<text class="empty-text">暂无相关案例</text>
|
||||
</view>
|
||||
|
||||
<!-- 底部间距 -->
|
||||
<view class="bottom-space"></view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { getCaseList } from '@/api/index.uts'
|
||||
import { SOFA_CATEGORIES, PAGE_SIZE } from '@/utils/config.uts'
|
||||
|
||||
// 分类类型
|
||||
type CategoryItem = {
|
||||
id : string
|
||||
name : string
|
||||
}
|
||||
|
||||
// 案例类型
|
||||
type CaseItem = {
|
||||
id : string
|
||||
title : string
|
||||
category : string
|
||||
categoryName : string
|
||||
coverImage : string
|
||||
material : string
|
||||
duration : string
|
||||
price : string
|
||||
views : number
|
||||
likes : number
|
||||
}
|
||||
|
||||
// 分类列表
|
||||
const categories = ref<CategoryItem[]>([])
|
||||
|
||||
// 当前分类
|
||||
const currentCategory = ref('all')
|
||||
|
||||
// 案例列表
|
||||
const caseList = ref<CaseItem[]>([])
|
||||
|
||||
// 分页
|
||||
const page = ref(1)
|
||||
const total = ref(0)
|
||||
|
||||
// 加载状态
|
||||
const loading = ref(false)
|
||||
const noMore = ref(false)
|
||||
|
||||
// 初始化分类
|
||||
const initCategories = () => {
|
||||
categories.value = SOFA_CATEGORIES.map((item) : CategoryItem => {
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.name
|
||||
} as CategoryItem
|
||||
})
|
||||
}
|
||||
|
||||
// 选择分类
|
||||
const selectCategory = (id : string) => {
|
||||
if (currentCategory.value == id) return
|
||||
currentCategory.value = id
|
||||
page.value = 1
|
||||
caseList.value = []
|
||||
noMore.value = false
|
||||
fetchCaseList()
|
||||
}
|
||||
|
||||
// 获取案例列表
|
||||
const fetchCaseList = async () => {
|
||||
if (loading.value || noMore.value) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const params = {
|
||||
category: currentCategory.value,
|
||||
page: page.value,
|
||||
pageSize: PAGE_SIZE
|
||||
} as UTSJSONObject
|
||||
|
||||
const res = await getCaseList(params)
|
||||
const data = res.data as UTSJSONObject
|
||||
// 适应后端返回格式:{ items: [], total: 0, page: 1, limit: 10 }
|
||||
const list = data['items'] as UTSJSONObject[] || []
|
||||
total.value = data['total'] as number || 0
|
||||
|
||||
const newList = list.map((item) : CaseItem => {
|
||||
return {
|
||||
id: item['id'] as string,
|
||||
title: item['title'] as string,
|
||||
category: item['category'] as string,
|
||||
categoryName: item['categoryName'] as string,
|
||||
coverImage: item['coverImage'] as string,
|
||||
material: item['material'] as string,
|
||||
duration: item['duration'] as string,
|
||||
price: item['price'] as string,
|
||||
views: item['views'] as number,
|
||||
likes: item['likes'] as number
|
||||
} as CaseItem
|
||||
})
|
||||
|
||||
if (page.value == 1) {
|
||||
caseList.value = newList
|
||||
} else {
|
||||
caseList.value = [...caseList.value, ...newList]
|
||||
}
|
||||
|
||||
if (caseList.value.length >= total.value) {
|
||||
noMore.value = true
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取案例列表失败', e)
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
// 加载更多
|
||||
const loadMore = () => {
|
||||
if (!noMore.value && !loading.value) {
|
||||
page.value++
|
||||
fetchCaseList()
|
||||
}
|
||||
}
|
||||
|
||||
// 跳转详情
|
||||
const goToDetail = (id : string) => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/cases/detail?id=${id}`
|
||||
})
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
initCategories()
|
||||
fetchCaseList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.page {
|
||||
flex: 1;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* 分类栏 */
|
||||
.category-bar {
|
||||
background-color: #ffffff;
|
||||
padding: 24rpx 0;
|
||||
border-bottom-width: 1rpx;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-color: #EBEEF5;
|
||||
}
|
||||
|
||||
.category-scroll {
|
||||
flex-direction: row;
|
||||
}
|
||||
.category-scroll ::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.category-list {
|
||||
flex-direction: row;
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
|
||||
.category-item {
|
||||
padding: 16rpx 32rpx;
|
||||
margin-right: 16rpx;
|
||||
border-radius: 999rpx;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.category-active {
|
||||
background-color: #D4A574;
|
||||
}
|
||||
|
||||
.category-text {
|
||||
font-size: 28rpx;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.category-text-active {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/* 案例列表 */
|
||||
.case-scroll {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.case-list {
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
/* 加载状态 */
|
||||
.load-status {
|
||||
padding: 32rpx 0;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.load-text {
|
||||
font-size: 26rpx;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
padding: 120rpx 0;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
font-size: 80rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 28rpx;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
/* 底部间距 */
|
||||
.bottom-space {
|
||||
height: 120rpx;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user