Files
lgp-admin-plus-api/app/template/uniapp/pages/list.vue
2026-08-11 09:39:41 +08:00

121 lines
3.8 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 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 AppFilterBar from '@/components/AppFilterBar.vue'
import AppSearchBar from '@/components/AppSearchBar.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>
<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>
<AppCardList v-if="cards.length" :list="cards" @select="goDetail" />
<AppEmpty v-else text="暂无数据" />
<view v-if="cards.length" class="more" @tap="loadMore">
{{ finished ? '没有更多了' : loading ? '加载中…' : '加载更多' }}
</view>
<view class="fab" @tap="goCreate">新增</view>
</view>
</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; }
.fab {
position: fixed; right: 32rpx; bottom: calc(48rpx + env(safe-area-inset-bottom));
min-width: 120rpx; height: 88rpx; padding: 0 36rpx; border-radius: 999rpx;
background: $nl-color-primary; color: #fff; display: flex; align-items: center; justify-content: center;
font-weight: 700; box-shadow: 0 16rpx 40rpx rgba(255, 107, 0, 0.35);
}
</style>