From c626652464e526c8a53dc71316de0bfbc8d32c3e Mon Sep 17 00:00:00 2001 From: zhangjiming Date: Thu, 3 Apr 2025 21:17:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E8=AE=B0=E5=BD=95=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=20mock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/UploadList.tsx | 152 +++++++++++++++++++----- src/services/apiTypes.ts | 1 + src/store/features/contextSlice.ts | 12 +- src/utils/bridge.ts | 44 ++++++- src/utils/constant.ts | 232 ++++++++++++++++++------------------- 5 files changed, 296 insertions(+), 145 deletions(-) diff --git a/src/pages/UploadList.tsx b/src/pages/UploadList.tsx index b889097..6a710d5 100644 --- a/src/pages/UploadList.tsx +++ b/src/pages/UploadList.tsx @@ -1,25 +1,117 @@ -import { ActionSheet, InfiniteScroll, List, NavBar, Popup } from 'antd-mobile'; +import { ActionSheet, Dialog, InfiniteScroll, List, NavBar, Toast } from 'antd-mobile'; import { useNavigate } from 'react-router-dom'; import { MoreOutline } from 'antd-mobile-icons'; -import { useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; -import { dataListFlat } from '../utils/constant'; -import MeasureGroups from '../components/MeasureGroups'; import MeasureItem from '../components/MeasureItem'; +import { Measurement } from '../services/apiTypes'; +import Bridge, { bridgeOb } from '../utils/bridge'; +import { useAppDispatch, useAppSelector } from '../utils/hooks'; +import { refreshSyncProgress } from '../store/features/contextSlice'; +const PAGE_SIZE = 10; export default function UploadList() { const navigate = useNavigate(); + const dispatch = useAppDispatch(); + + const context = useAppSelector((state) => state.context); const [showMenu, setShowMenu] = useState(false); + const [list, setList] = useState([]); + const [noMore, setNoMore] = useState(false); const actions = [ - { text: '重试失败任务', key: 'retry' }, - { text: '清空列表', key: 'clear' }, - { text: '清空已完成任务', key: 'clearCompleted' }, - ] - + { + text: '重试失败任务', + key: 'retry', + onClick: async () => { + setShowMenu(false); + if (context.syncProgress.fail === 0) { + return Toast.show('目前没有失败的任务'); + } + const res = await Bridge.retryFailureSync(); + if (!res.success) { + Toast.show(res.message); + } + }, + }, + { + text: '清空列表', + key: 'clear', + onClick: () => { + setShowMenu(false); + if (!context.syncProgress.finish) { + Dialog.confirm({ + content: '存在未完成的任务,确定清空?', + onConfirm: () => { + Bridge.clearSyncList().then((res) => { + if (res.success) { + loadData(); + } else { + Toast.show(res.message); + } + }); + }, + }); + } + }, + }, + { + text: '清空已完成任务', + key: 'clearCompleted', + onClick: async () => { + setShowMenu(false); + const res = await Bridge.clearFinishedSync(); + if (res.success) { + loadData(); + } else { + Toast.show(res.message); + } + }, + }, + ]; + + const loadData = useCallback(() => { + dispatch(refreshSyncProgress()); + Bridge.getSyncTaskList({ pageNum: 1, size: PAGE_SIZE }).then((res) => { + if (res.success) { + setList(res.data.list); + setNoMore(res.data.list.length < PAGE_SIZE); + } else { + Toast.show(res.message); + } + }); + }, [dispatch]); + + async function loadMoreData() { + const pageNum = Math.floor(list.length / PAGE_SIZE); + const res = await Bridge.getSyncTaskList({ pageNum: pageNum + 1, size: PAGE_SIZE }); + if (res.success) { + setList(list.concat(res.data.list)); + setNoMore(res.data.list.length < PAGE_SIZE); + } else { + Toast.show(res.message); + } + } + + useEffect(() => { + loadData(); + }, [loadData]); + + useEffect(() => { + const subscription = bridgeOb.subscribe((datagram) => { + if (datagram.type === 'sync-item-finish') { + const item = list.find((item) => item.id === datagram.data.id); + if (item) { + item.syncStatus = datagram.data.success ? 'finish' : 'fail'; + } + } + }); + return () => subscription.unsubscribe(); + }, [list]); + const back = () => navigate(-1); const right = ( @@ -35,31 +127,37 @@ export default function UploadList() { return (
- 上传数据 + 上传记录
- 剩余任务10个 + 剩余任务{context.syncProgress.remaining}个 - 失败0个 -

上传中

+ 失败{context.syncProgress.fail}个 +

{context.syncProgress.finish ? '完成' : '上传中'}

-
- - {dataListFlat.map((item) => ( - - navigate(`/measure/record/${item.id}`)} /> - - ))} - {/* */} - +
+ {list.length > 0 ? ( + + {list.map((item) => ( + + navigate(`/measure/record/${item.id}`)} + /> + + ))} + + + ) : ( +

暂无数据

+ )}
- setShowMenu(false)} - /> + setShowMenu(false)} />
); } diff --git a/src/services/apiTypes.ts b/src/services/apiTypes.ts index 3cb6a93..bdec02a 100644 --- a/src/services/apiTypes.ts +++ b/src/services/apiTypes.ts @@ -10,6 +10,7 @@ export type Measurement = { leftPoints: string; // json: 坐标数组 rightPoints: string; // json: 坐标数组 upload: boolean; + syncStatus: 'wait' | 'finish' | 'fail'; }; export type KTJOrg = { diff --git a/src/store/features/contextSlice.ts b/src/store/features/contextSlice.ts index 865bc3b..4e71528 100644 --- a/src/store/features/contextSlice.ts +++ b/src/store/features/contextSlice.ts @@ -68,10 +68,15 @@ export const saveConfig = createAsyncThunk( async (param: { server: string }, thunkAPI) => { const res = await Bridge.saveConfig(param); res.success && thunkAPI.dispatch(fetchConfig()); - return res + return res; } ); +export const refreshSyncProgress = createAsyncThunk('context/refreshSync', async () => { + const res = await Bridge.getSyncProcess(); + return res.success ? res.data : null; +}); + export const contextSlice = createSlice({ name: 'context', initialState, @@ -105,6 +110,11 @@ export const contextSlice = createSlice({ state.setting = action.payload; } }); + builder.addCase(refreshSyncProgress.fulfilled, (state, action) => { + if (action.payload) { + state.syncProgress = action.payload; + } + }); }, }); diff --git a/src/utils/bridge.ts b/src/utils/bridge.ts index 710e2a0..3097ab0 100644 --- a/src/utils/bridge.ts +++ b/src/utils/bridge.ts @@ -1,7 +1,7 @@ import { Subject } from 'rxjs'; import httpRequest from '../services/httpRequest'; import { Measurement } from '../services/apiTypes'; -import { MobileDatagram } from '../services/mobileWsType'; +import { MobileDatagram, SyncProgress } from '../services/mobileWsType'; declare global { interface Window { @@ -257,4 +257,46 @@ export default class Bridge { params, }); } + static getSyncTaskList(params: { pageNum: number; size: number }) { + return httpRequest>({ + url: '/api/sync/list', + method: "POST", + params + }) + } + static addSyncTask(params: {ids: number[]}) { + return httpRequest({ + url: '/api/sync/add', + method: "POST", + params + }) + } + static getSyncProcess() { + return httpRequest>({ + url: '/api/sync/progress', + method: "POST", + params:{} + }) + } + static clearSyncList() { + return httpRequest({ + url: '/api/sync/empty-all', + method: "POST", + params:{} + }) + } + static clearFinishedSync() { + return httpRequest({ + url: '/api/sync/empty-finish', + method: "POST", + params:{} + }) + } + static retryFailureSync() { + return httpRequest({ + url: '/api/sync/re-fail', + method: "POST", + params:{} + }) + } } diff --git a/src/utils/constant.ts b/src/utils/constant.ts index f21631e..e206347 100644 --- a/src/utils/constant.ts +++ b/src/utils/constant.ts @@ -1734,122 +1734,122 @@ export const sectionList = [ }, ]; -export const dataListFlat: Measurement[] = [ - { - id: 1, - name: '测量名称1', - createAt: '2025-03-02 10:20', - line: '京沪线', - section: 'A段', - direction: '上行', - railId: 2, - leftPoints: '[]', - rightPoints: '[]', - bureau: '北京铁路局', - upload: false, - }, - { - id: 2, - name: '测量名称2', - createAt: '2025-03-02 12:22', - line: '京沪线', - section: 'B段', - direction: '下行', - railId: 2, - leftPoints: '[]', - rightPoints: '[]', - bureau: '北京铁路局', - upload: false, - }, - { - id: 3, - name: '测量名称3', - createAt: '2025-03-02 12:20', - line: '京沪线', - section: 'C段', - direction: '上行', - railId: 2, - leftPoints: '[]', - rightPoints: '[]', - bureau: '北京铁路局', - upload: false, - }, -]; +// export const dataListFlat: Measurement[] = [ +// { +// id: 1, +// name: '测量名称1', +// createAt: '2025-03-02 10:20', +// line: '京沪线', +// section: 'A段', +// direction: '上行', +// railId: 2, +// leftPoints: '[]', +// rightPoints: '[]', +// bureau: '北京铁路局', +// upload: false, +// }, +// { +// id: 2, +// name: '测量名称2', +// createAt: '2025-03-02 12:22', +// line: '京沪线', +// section: 'B段', +// direction: '下行', +// railId: 2, +// leftPoints: '[]', +// rightPoints: '[]', +// bureau: '北京铁路局', +// upload: false, +// }, +// { +// id: 3, +// name: '测量名称3', +// createAt: '2025-03-02 12:20', +// line: '京沪线', +// section: 'C段', +// direction: '上行', +// railId: 2, +// leftPoints: '[]', +// rightPoints: '[]', +// bureau: '北京铁路局', +// upload: false, +// }, +// ]; export const dataList: Array<{ groupName: string; list: Measurement[] }> = [ - { - groupName: '2025-03-02', - list: [ - { - id: 1, - name: '测量名称1', - createAt: '2025-03-02 10:20', - line: '京沪线', - section: 'A段', - direction: '上行', - railId: 2, - leftPoints: '[]', - rightPoints: '[]', - bureau: '北京铁路局', - upload: false, - }, - { - id: 2, - name: '测量名称2', - createAt: '2025-03-02 12:22', - line: '京沪线', - section: 'B段', - direction: '下行', - railId: 2, - leftPoints: '[]', - rightPoints: '[]', - bureau: '北京铁路局', - upload: false, - }, - { - id: 3, - name: '测量名称3', - createAt: '2025-03-02 12:20', - line: '京沪线', - section: 'C段', - direction: '上行', - railId: 2, - leftPoints: '[]', - rightPoints: '[]', - bureau: '北京铁路局', - upload: false, - }, - ], - }, - { - groupName: '2025-02-01', - list: [ - { - id: 4, - name: '测量名称2', - createAt: '2025-03-02 10:20', - line: '京沪线', - section: 'D段', - direction: '下行', - railId: 2, - leftPoints: '[]', - rightPoints: '[]', - bureau: '北京铁路局', - upload: false, - }, - { - id: 5, - name: '测量名称2', - createAt: '2025-03-02 10:20', - line: '京沪线', - section: 'E段', - direction: '下行', - railId: 2, - leftPoints: '[]', - rightPoints: '[]', - bureau: '北京铁路局', - upload: false, - }, - ], - }, +// { +// groupName: '2025-03-02', +// list: [ +// { +// id: 1, +// name: '测量名称1', +// createAt: '2025-03-02 10:20', +// line: '京沪线', +// section: 'A段', +// direction: '上行', +// railId: 2, +// leftPoints: '[]', +// rightPoints: '[]', +// bureau: '北京铁路局', +// upload: false, +// }, +// { +// id: 2, +// name: '测量名称2', +// createAt: '2025-03-02 12:22', +// line: '京沪线', +// section: 'B段', +// direction: '下行', +// railId: 2, +// leftPoints: '[]', +// rightPoints: '[]', +// bureau: '北京铁路局', +// upload: false, +// }, +// { +// id: 3, +// name: '测量名称3', +// createAt: '2025-03-02 12:20', +// line: '京沪线', +// section: 'C段', +// direction: '上行', +// railId: 2, +// leftPoints: '[]', +// rightPoints: '[]', +// bureau: '北京铁路局', +// upload: false, +// }, +// ], +// }, +// { +// groupName: '2025-02-01', +// list: [ +// { +// id: 4, +// name: '测量名称2', +// createAt: '2025-03-02 10:20', +// line: '京沪线', +// section: 'D段', +// direction: '下行', +// railId: 2, +// leftPoints: '[]', +// rightPoints: '[]', +// bureau: '北京铁路局', +// upload: false, +// }, +// { +// id: 5, +// name: '测量名称2', +// createAt: '2025-03-02 10:20', +// line: '京沪线', +// section: 'E段', +// direction: '下行', +// railId: 2, +// leftPoints: '[]', +// rightPoints: '[]', +// bureau: '北京铁路局', +// upload: false, +// }, +// ], +// }, ];