fixed: 订单分页效果

This commit is contained in:
LittleBoy 2025-04-14 21:34:46 +08:00
parent 605a769b89
commit 1be407d34e
11 changed files with 83 additions and 30 deletions

View File

@ -263,7 +263,9 @@
} }
} }
} }
.w-min-60px{
min-width: 60px;
}
.list-scroller-container { .list-scroller-container {
overflow: auto; overflow: auto;
margin-right: -20px; margin-right: -20px;

View File

@ -2,6 +2,7 @@ import React, {CSSProperties, useCallback, useEffect, useImperativeHandle, useRe
import {useInViewport, useScroll} from "ahooks"; import {useInViewport, useScroll} from "ahooks";
import { LoadingOutlined } from '@ant-design/icons'; import { LoadingOutlined } from '@ant-design/icons';
import {Spin} from "antd"; import {Spin} from "antd";
import {t} from "i18next";
export type InfiniteScrollerRef = { export type InfiniteScrollerRef = {
scrollToPosition: (top: number) => void scrollToPosition: (top: number) => void
@ -65,7 +66,7 @@ const InfiniteScroller = React.forwardRef<InfiniteScrollerRef, InfiniteScrollerP
{props.loading && <div style={{minHeight:'30vh'}}></div>} {props.loading && <div style={{minHeight:'30vh'}}></div>}
{props?.pagination && props.pagination.total > props.pagination.limit * props.pagination.page && (props.loadingPlaceholder || {props?.pagination && props.pagination.total > props.pagination.limit * props.pagination.page && (props.loadingPlaceholder ||
<div className="data-load-control-element py-10 text-center"> <div className="data-load-control-element py-10 text-center">
<div className="loading-text">...</div> <div className="loading-text">{t('loading')}</div>
</div>)} </div>)}
{props?.empty && !props.loading && props.pagination?.total == 0 && <div className="flex justify-center text-center pt-20"> {props?.empty && !props.loading && props.pagination?.total == 0 && <div className="flex justify-center text-center pt-20">
<div className="rounded-lg px-4 py-10"> <div className="rounded-lg px-4 py-10">

View File

@ -38,6 +38,7 @@
"playlist_count": "{{count}} videos in total", "playlist_count": "{{count}} videos in total",
"title": "Livestream" "title": "Livestream"
}, },
"loading": "Loading...",
"login": { "login": {
"code_sending": "Sending...", "code_sending": "Sending...",
"invalid_username_or_pwd": "Invalid phone number or code", "invalid_username_or_pwd": "Invalid phone number or code",
@ -149,6 +150,12 @@
"remaining_duration_warning": "Unable to generate videos due to insufficient remaining time", "remaining_duration_warning": "Unable to generate videos due to insufficient remaining time",
"text": "Orders" "text": "Orders"
}, },
"page": {
"size_10": "10 per page",
"size_20": "20 per page",
"size_30": "30 per page",
"total_item": "{{total}} videos in total"
},
"recycle": { "recycle": {
"remove_forever": "Remove Forever", "remove_forever": "Remove Forever",
"restore_video": "Restore" "restore_video": "Restore"

View File

@ -38,6 +38,7 @@
"playlist_count": "当前播放列表共 {{count}} 条", "playlist_count": "当前播放列表共 {{count}} 条",
"title": "直播界面" "title": "直播界面"
}, },
"loading": "加载中...",
"login": { "login": {
"code_sending": "发送中", "code_sending": "发送中",
"invalid_username_or_pwd": "账号或密码错误", "invalid_username_or_pwd": "账号或密码错误",
@ -149,6 +150,12 @@
"remaining_duration_warning": "视频生成剩余时长为零,将无法生成视频,请尽快充值额度。", "remaining_duration_warning": "视频生成剩余时长为零,将无法生成视频,请尽快充值额度。",
"text": "订单记录" "text": "订单记录"
}, },
"page": {
"size_10": "10条/页",
"size_20": "20条/页",
"size_30": "30条/页",
"total_item": "共计{{total}}条"
},
"recycle": { "recycle": {
"remove_forever": "彻底删除", "remove_forever": "彻底删除",
"restore_video": "还原视频" "restore_video": "还原视频"

View File

@ -97,3 +97,22 @@
} }
} }
} }
.orderDataList{
:global {
.id{
@apply pl-0;
width: 120px;
&:after{
display: none;
}
}
.title {
@apply flex-1 pl-4;
min-width: 100px;
&:after {
display: block;
}
}
}
}

View File

@ -5,7 +5,7 @@ import styles from "@/pages/news/components/style.module.scss";
import {formatDurationToTime, formatTime} from "@/util/strings.ts"; import {formatDurationToTime, formatTime} from "@/util/strings.ts";
import {IconDelete, IconEdit, IconWarningCircle} from "@/components/icons"; import {IconDelete, IconEdit, IconWarningCircle} from "@/components/icons";
import {Empty, Popconfirm} from "antd"; import {Empty, Pagination, PaginationProps, Popconfirm} from "antd";
import {useRequest, useSetState} from "ahooks"; import {useRequest, useSetState} from "ahooks";
import {getList} from "@/service/api/order.ts"; import {getList} from "@/service/api/order.ts";
@ -14,36 +14,38 @@ function OrderIndex() {
const {t} = useTranslation() const {t} = useTranslation()
const [params, setParams] = useState<ApiArticleSearchParams>({ const [params, setParams] = useState<ApiArticleSearchParams>({
pagination: {page: 1, limit: 12}, pagination: {page: 1, limit: 12},
time_flag: 1, time_flag: 0,
}) })
const {data} = useRequest(()=>getList(params),{ const {data} = useRequest(() => getList(params), {
refreshDeps:[params], refreshDeps: [params],
}) })
return <div className="container pb-5 page-order-index"> return <div className="container pb-5 page-order-index">
<SearchPanel <SearchPanel
hideNewsSource={true} defaultParams={params} onSearch={setParams} hideNewsSource={true}
defaultParams={params}
onSearch={setParams}
rightRender={<div>{t('order.left_time')}: <span rightRender={<div>{t('order.left_time')}: <span
className={`${!data?.remaining_duration || Number(data?.remaining_duration) < 3600 ? 'text-red-600' : ''}`}>{formatDurationToTime(data?.remaining_duration)}</span> className={`${!data?.remaining_duration || Number(data?.remaining_duration) < 3600 ? 'text-red-600' : ''}`}>{formatDurationToTime(data?.remaining_duration)}</span>
</div>} </div>}
/> />
<div className=" mt-2"> <div className="mt-2">
<div className={styles.newListTable}> <div className={`${styles.newListTable} ${styles.orderDataList} `}>
<div className="header row flex"> <div className="header row flex">
<div className="col w-[160px]">{t('order.list.id')}</div> <div className="col id w-[160px]">{t('order.list.id')}</div>
<div className="col w-[180px]">{t('order.list.cover')}</div> <div className="col w-[180px]">{t('order.list.cover')}</div>
<div className="col title">{t('order.list.title')}</div> <div className="col title w-min-60px">{t('order.list.title')}</div>
<div className="col w-[180px]">{t('order.list.order_time')}</div> <div className="col w-[180px]">{t('order.list.order_time')}</div>
<div className="col w-[180px]">{t('order.list.consume_time')}</div> <div className="col w-[180px]">{t('order.list.consume_time')}</div>
<div className="col w-[180px]">{t('order.list.operator')}</div> <div className="col w-[180px]">{t('order.list.operator')}</div>
</div> </div>
<div className="data-list-container"> <div >
{data?.list.length === 0 && <div style={{marginTop:50}}> {data?.list.length === 0 && <div style={{marginTop: 50}}>
<Empty /> <Empty/>
</div>} </div>}
{data?.list.map((item, i) => { {data?.list.map((item, i) => {
return <div key={i} className="row flex"> return <div key={i} className="row flex">
<div className="col w-[160px] text-center"> <div className="col id w-[160px] text-center">
<div className="flex-1"> <div className="flex-1">
<div className="text-base">{item.order_id}</div> <div className="text-base">{item.order_id}</div>
</div> </div>
@ -51,7 +53,7 @@ function OrderIndex() {
<div className="col w-[180px]"> <div className="col w-[180px]">
<img src={item.img_url} className="rounded w-[140px] h-[60px]" alt=""/> <img src={item.img_url} className="rounded w-[140px] h-[60px]" alt=""/>
</div> </div>
<div className="col flex-1"> <div className="col flex-1 w-min-60px">
<div className="text-sm line-clamp-2">{item.title}</div> <div className="text-sm line-clamp-2">{item.title}</div>
</div> </div>
<div className="col w-[180px]"> <div className="col w-[180px]">
@ -66,6 +68,22 @@ function OrderIndex() {
</div> </div>
</div> </div>
})} })}
<div className="footer flex justify-end mt-10">
<Pagination
total={data?.pagination.total || 0}
showTotal={(total) => <div>{t('page.total_item', {total})}</div>}
showSizeChanger={{
options: [
{value: 10, label: t('page.size_10')},
{value: 20, label: t('page.size_20')},
{value: 30, label: t('page.size_30')}
]
}}
showQuickJumper={true}
hideOnSinglePage={true}
/>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,4 +1,4 @@
import React, {useEffect, useMemo, useRef, useState} from "react"; import React, {useEffect, useRef, useState} from "react";
import {Checkbox, Modal, Space} from "antd"; import {Checkbox, Modal, Space} from "antd";
import {useRequest, useSetState} from "ahooks"; import {useRequest, useSetState} from "ahooks";
import {useTranslation} from "react-i18next"; import {useTranslation} from "react-i18next";
@ -42,9 +42,9 @@ export default function RecycleIndex() {
onSuccess: (data) => { onSuccess: (data) => {
setData(prev => { setData(prev => {
// 判断页码是否是第1页 // 判断页码是否是第1页
//if (data.pagination.page == 1) return data; if (data.pagination.page == 1) return data;
return { return {
list: data?.list || [], //[...(prev?.list || []), ...(data?.list || [])], list: [...(prev?.list || []), ...(data?.list || [])],
pagination: data.pagination || { pagination: data.pagination || {
page: 1, page: 1,
limit: DEFAULT_PAGE_LIMIT.limit limit: DEFAULT_PAGE_LIMIT.limit

View File

@ -36,7 +36,7 @@ const AppRouter = () => {
const initRemainingDuration = () => { const initRemainingDuration = () => {
getRemainingDuration().then(remain => { getRemainingDuration().then(remain => {
if(remain > 0){ if(remain <= 0){
Modal.warning({ Modal.warning({
wrapClassName:'root-modal-confirm', wrapClassName:'root-modal-confirm',
title: t('confirm.title'), title: t('confirm.title'),

View File

@ -5,10 +5,7 @@ type OrderInfoData = DataList<OrderInfo> & {
} }
export function getList(params: OrderSearchParam) { export function getList(params: OrderSearchParam) {
return post<OrderInfoData>('/order/list', { return post<OrderInfoData>('/order/list', params)
page_num: params.pagination.page || 1,
page_size: params.pagination.limit || 10,
})
} }

View File

@ -1,10 +1,7 @@
import {post} from "@/service/request.ts"; import {post} from "@/service/request.ts";
export function getList(params: VideoSearchParams) { export function getList(params: NormalSearchParams) {
return post<DataList<VideoInfo>>('/recycle/list', { return post<DataList<VideoInfo>>('/recycle/list', params)
page_num: params.pagination.page || 1,
page_size: params.pagination.limit || 10,
})
} }
export function remove(ids: Id[]) { export function remove(ids: Id[]) {
return post('/recycle/remove', {ids}) return post('/recycle/remove', {ids})

5
src/types/api.d.ts vendored
View File

@ -86,6 +86,11 @@ declare interface ListCrawlerNewsItem extends BasicArticleInfo {
// 内部文章关联id // 内部文章关联id
internal_article_id: number; internal_article_id: number;
} }
declare interface NormalSearchParams extends ApiRequestPageParams{
// 标题
title?: string;
time_flag?: number;
}
declare interface VideoSearchParams extends ApiRequestPageParams{ declare interface VideoSearchParams extends ApiRequestPageParams{
// 标题 // 标题
title?: string; title?: string;