123 lines
3.9 KiB
Vue
123 lines
3.9 KiB
Vue
<script setup lang="ts">
|
||
/**
|
||
* 模板名称列表(C 端):点击进详情,新增进全屏表单
|
||
* 兼容微信小程序 / App / H5
|
||
*/
|
||
import { computed, ref } from 'vue'
|
||
import { onShow } from '@dcloudio/uni-app'
|
||
|
||
import { getupperCamelCaseList } from '../api'
|
||
import AppCardList, { type AppCardItem } from '@/components/AppCardList.vue'
|
||
import AppEmpty from '@/components/AppEmpty.vue'
|
||
import AppFab from '@/components/AppFab.vue'
|
||
import AppFilterBar from '@/components/AppFilterBar.vue'
|
||
import AppLoading from '@/components/AppLoading.vue'
|
||
import AppPageAtmosphere from '@/components/AppPageAtmosphere.vue'
|
||
import AppSearchBar from '@/components/AppSearchBar.vue'
|
||
import AppSkeleton from '@/components/AppSkeleton.vue'
|
||
import { usePullRefresh } from '@/composables/usePullRefresh'
|
||
|
||
const list = ref<any[]>([])
|
||
const keyword = ref('')
|
||
const draftKeyword = ref('')
|
||
const loading = ref(false)
|
||
const page = ref(1)
|
||
const finished = ref(false)
|
||
|
||
const selectedCount = computed(() => (keyword.value ? 1 : 0))
|
||
|
||
const cards = computed<AppCardItem[]>(() =>
|
||
list.value.map((item) => ({
|
||
id: item.id,
|
||
title: String(item.UNI_TITLE_FIELD || `模板名称#${item.id}`),
|
||
subtitle: String(item.UNI_SUBTITLE_FIELD || ''),
|
||
iconText: String(item.UNI_TITLE_FIELD || '模').slice(0, 1),
|
||
statusText: Number(item.status) === 0 ? '正常' : '禁用',
|
||
statusType: Number(item.status) === 0 ? 'success' : 'danger',
|
||
})),
|
||
)
|
||
|
||
onShow(() => reload())
|
||
// pages.json 该页需 enablePullDownRefresh: true
|
||
usePullRefresh(reload)
|
||
|
||
async function reload() {
|
||
page.value = 1
|
||
finished.value = false
|
||
list.value = []
|
||
await loadMore()
|
||
}
|
||
|
||
async function loadMore() {
|
||
if (loading.value || finished.value) return
|
||
loading.value = true
|
||
try {
|
||
const res = await getupperCamelCaseList({
|
||
page: page.value,
|
||
pageSize: 20,
|
||
keyword: keyword.value || undefined,
|
||
})
|
||
const items = res?.items || res?.data || []
|
||
list.value = page.value === 1 ? items : list.value.concat(items)
|
||
const total = Number(res?.total || 0)
|
||
if (!items.length || list.value.length >= total) finished.value = true
|
||
else page.value += 1
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
function onFilterReset() {
|
||
draftKeyword.value = ''
|
||
}
|
||
|
||
function onFilterConfirm() {
|
||
keyword.value = draftKeyword.value
|
||
reload()
|
||
}
|
||
|
||
function goDetail(item: AppCardItem) {
|
||
uni.navigateTo({ url: `/pages-sub/my-gen/dashCase/pages/detail?id=${item.id}` })
|
||
}
|
||
|
||
function goCreate() {
|
||
uni.navigateTo({ url: '/pages-sub/my-gen/dashCase/pages/form' })
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<AppPageAtmosphere tone="cool">
|
||
<view class="nl-page page">
|
||
<AppSearchBar
|
||
v-model="keyword"
|
||
placeholder="搜索模板名称"
|
||
@search="(v) => { keyword = v; reload() }"
|
||
@clear="() => { keyword = ''; reload() }"
|
||
/>
|
||
<AppFilterBar :selected-count="selectedCount" @reset="onFilterReset" @confirm="onFilterConfirm">
|
||
<view class="filter-row">
|
||
<text>关键词</text>
|
||
<input v-model="draftKeyword" class="filter-input" placeholder="关键词" />
|
||
</view>
|
||
</AppFilterBar>
|
||
<AppSkeleton v-if="loading && !cards.length" :rows="5" />
|
||
<AppCardList v-else-if="cards.length" :list="cards" @select="goDetail" />
|
||
<AppEmpty v-else text="暂无数据" />
|
||
<AppLoading v-if="loading && cards.length" text="加载更多…" />
|
||
<view v-else-if="cards.length" class="more" @tap="loadMore">
|
||
{{ finished ? '没有更多了' : '加载更多' }}
|
||
</view>
|
||
<AppFab @tap="goCreate" />
|
||
</view>
|
||
</AppPageAtmosphere>
|
||
</template>
|
||
|
||
<style scoped lang="scss">
|
||
.page { padding-bottom: 160rpx; }
|
||
.filter-row {
|
||
display: flex; align-items: center; justify-content: space-between; min-height: 72rpx; font-size: 26rpx;
|
||
}
|
||
.filter-input { flex: 1; text-align: right; margin-left: 24rpx; }
|
||
.more { text-align: center; color: $nl-color-text-muted; padding: 16rpx; font-size: 24rpx; }
|
||
</style>
|