feat(ticket): 添加水票释放计划功能
- 在应用配置中注册新的释放计划页面路由 ticket/release/index - 简化 API 请求参数结构,移除不必要的包装对象 - 在用户票券列表中添加释放计划详情入口和跳转逻辑 - 显示票券套票名称信息增强用户体验 - 在配送时间选择中添加日期验证防止选择过去日期 - 新增完整的释放计划详情页面实现列表展示、下拉刷新、上拉加载等功能 - 添加释放计划状态显示和数量统计信息展示
This commit is contained in:
@@ -9,6 +9,7 @@ import type { GltUserTicketRelease } from '@/api/glt/gltUserTicketRelease/model'
|
|||||||
import { ensureLoggedIn } from '@/utils/auth'
|
import { ensureLoggedIn } from '@/utils/auth'
|
||||||
|
|
||||||
const PAGE_SIZE = 10
|
const PAGE_SIZE = 10
|
||||||
|
const MAX_FETCH_ROUNDS = 10
|
||||||
|
|
||||||
export default function TicketReleasePlanPage() {
|
export default function TicketReleasePlanPage() {
|
||||||
const [list, setList] = useState<GltUserTicketRelease[]>([])
|
const [list, setList] = useState<GltUserTicketRelease[]>([])
|
||||||
@@ -74,34 +75,58 @@ export default function TicketReleasePlanPage() {
|
|||||||
|
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
try {
|
try {
|
||||||
const currentPage = isRefresh ? 1 : page
|
const baseList = isRefresh ? [] : list
|
||||||
const res = await pageGltUserTicketRelease({
|
const seen = new Set(baseList.map(r => String(r.id ?? `${r.userTicketId ?? ''}:${r.periodNo ?? ''}:${r.releaseTime ?? ''}`)))
|
||||||
page: currentPage,
|
|
||||||
limit: PAGE_SIZE,
|
|
||||||
userId: uid,
|
|
||||||
userTicketId: userTicketId as any
|
|
||||||
} as any)
|
|
||||||
|
|
||||||
const incoming = Array.isArray(res?.list) ? res.list : []
|
let nextPage = isRefresh ? 1 : page
|
||||||
const safe = incoming
|
let serverHasMore = true
|
||||||
.filter(r => Number((r as any)?.deleted) !== 1)
|
let added = 0
|
||||||
.filter(r => !userTicketId || String(r.userTicketId || '') === userTicketId)
|
let nextList = baseList.slice()
|
||||||
.sort((a, b) => {
|
|
||||||
const at = dayjs(a.releaseTime || a.createTime || 0).valueOf()
|
for (let round = 0; round < MAX_FETCH_ROUNDS; round++) {
|
||||||
const bt = dayjs(b.releaseTime || b.createTime || 0).valueOf()
|
if (!serverHasMore) break
|
||||||
return bt - at
|
|
||||||
})
|
// Only query by current logged-in userId; userTicketId is filtered on the client.
|
||||||
|
const res = await pageGltUserTicketRelease({
|
||||||
|
page: nextPage,
|
||||||
|
limit: PAGE_SIZE,
|
||||||
|
userId: uid
|
||||||
|
} as any)
|
||||||
|
|
||||||
|
const incoming = Array.isArray(res?.list) ? res.list : []
|
||||||
|
const safe = incoming
|
||||||
|
.filter(r => Number((r as any)?.deleted) !== 1)
|
||||||
|
.filter(r => !userTicketId || String(r.userTicketId || '') === userTicketId)
|
||||||
|
.filter(r => {
|
||||||
|
const k = String(r.id ?? `${r.userTicketId ?? ''}:${r.periodNo ?? ''}:${r.releaseTime ?? ''}`)
|
||||||
|
if (seen.has(k)) return false
|
||||||
|
seen.add(k)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
if (safe.length) {
|
||||||
|
nextList = nextList.concat(safe)
|
||||||
|
added += safe.length
|
||||||
|
}
|
||||||
|
|
||||||
|
serverHasMore = incoming.length >= PAGE_SIZE
|
||||||
|
if (!serverHasMore) break
|
||||||
|
nextPage += 1
|
||||||
|
|
||||||
|
// Stop early once we got something to render for this ticket.
|
||||||
|
if (added > 0) break
|
||||||
|
}
|
||||||
|
|
||||||
|
nextList.sort((a, b) => {
|
||||||
|
const at = dayjs(a.releaseTime || a.createTime || 0).valueOf()
|
||||||
|
const bt = dayjs(b.releaseTime || b.createTime || 0).valueOf()
|
||||||
|
return bt - at
|
||||||
|
})
|
||||||
|
|
||||||
const nextList = isRefresh ? safe : list.concat(safe)
|
|
||||||
setList(nextList)
|
setList(nextList)
|
||||||
|
setTotal(nextList.length)
|
||||||
const serverCount = typeof (res as any)?.count === 'number' ? Number((res as any).count) : undefined
|
setHasMore(serverHasMore)
|
||||||
const nextTotal = typeof serverCount === 'number' ? serverCount : nextList.length
|
setPage(nextPage)
|
||||||
setTotal(nextTotal)
|
|
||||||
setHasMore(typeof serverCount === 'number' ? nextList.length < serverCount : incoming.length >= PAGE_SIZE)
|
|
||||||
|
|
||||||
if (incoming.length > 0) setPage(currentPage + 1)
|
|
||||||
else setHasMore(false)
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('加载释放计划失败:', e)
|
console.error('加载释放计划失败:', e)
|
||||||
Taro.showToast({ title: '加载失败', icon: 'none' })
|
Taro.showToast({ title: '加载失败', icon: 'none' })
|
||||||
@@ -163,7 +188,7 @@ export default function TicketReleasePlanPage() {
|
|||||||
) : null}
|
) : null}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{list.length === 0 && !loading ? (
|
{list.length === 0 && !loading && !hasMore ? (
|
||||||
<View className="flex flex-col justify-center items-center" style={{ height: 'calc(100vh - 220px)' }}>
|
<View className="flex flex-col justify-center items-center" style={{ height: 'calc(100vh - 220px)' }}>
|
||||||
<Empty description="暂无释放计划" style={{ backgroundColor: 'transparent' }} />
|
<Empty description="暂无释放计划" style={{ backgroundColor: 'transparent' }} />
|
||||||
</View>
|
</View>
|
||||||
@@ -218,4 +243,3 @@ export default function TicketReleasePlanPage() {
|
|||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user