From 1bb4a887781f6af557ba6d213c215635acb7d9e3 Mon Sep 17 00:00:00 2001 From: zhangjiming Date: Tue, 1 Apr 2025 17:45:48 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E9=87=8F=E5=8E=86=E5=8F=B2=E6=8C=89?= =?UTF-8?q?=E5=88=86=E7=BB=84=E6=98=BE=E7=A4=BA=E5=92=8C=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/GroupItem.tsx | 28 ++++++++ src/components/MeasureGroups.tsx | 63 +++++++++++++++++ src/components/MeasurementItem.tsx | 45 ++++++++++++ src/index.tsx | 3 +- src/pages/Measure.tsx | 34 ++++----- src/pages/Mine2.tsx | 139 +++++++++++++++++++++++++++++++++++++ 6 files changed, 294 insertions(+), 18 deletions(-) create mode 100644 src/components/GroupItem.tsx create mode 100644 src/components/MeasureGroups.tsx create mode 100644 src/components/MeasurementItem.tsx create mode 100644 src/pages/Mine2.tsx diff --git a/src/components/GroupItem.tsx b/src/components/GroupItem.tsx new file mode 100644 index 0000000..bc9fe43 --- /dev/null +++ b/src/components/GroupItem.tsx @@ -0,0 +1,28 @@ +import icon_check_s from '../assets/icon_check_s_s.svg'; +import icon_check_u from '../assets/icon_check_s_u.svg'; + +export default function GroupItem({ + title, + editMode = false, + selected = false, + onGroupSelect, +}: { + title: string; + editMode?: boolean; + selected?: boolean; + onGroupSelect?: () => void; +}) { + const select = () => { + if (editMode) { + return icon; + } + return null; + }; + + return ( +
+ {select()} + {title} +
+ ); +} diff --git a/src/components/MeasureGroups.tsx b/src/components/MeasureGroups.tsx new file mode 100644 index 0000000..9ef02ca --- /dev/null +++ b/src/components/MeasureGroups.tsx @@ -0,0 +1,63 @@ +import { InfiniteScroll, List } from 'antd-mobile'; +import { Measurement } from '../services/apiTypes'; +import { useNavigate } from 'react-router'; +import GroupItem from './GroupItem'; +import MeasurementItem from './MeasurementItem'; +import * as R from 'ramda'; + +export default function MeasureGroups({ + dataList, + editMode, + hasMore, + loadMore, + onItemSelect, + onGroupSelect, + selectedIds, +}: { + dataList: Array<{ groupName: string; list: Measurement[] }>; + editMode: boolean; + hasMore: boolean; + loadMore: () => Promise; + onItemSelect: (groupIndex: number, id: number) => void; + onGroupSelect: (groupIndex: number) => void; + selectedIds: Array; +}) { + const navigate = useNavigate(); + + const isSubset = (ids: number[]) => R.intersection(selectedIds, ids).length === ids.length; + + return ( +
+ {dataList.length > 0 ? ( + <> + {dataList.map((group, idx) => ( +
+ item.id))} + onGroupSelect={() => onGroupSelect(idx)} + /> + + {group.list.map((item) => ( + + onItemSelect(idx, item.id)} + onDetail={() => navigate(`/measure/record/${item.id}`)} + /> + + ))} + +
+ ))} + + + ) : ( +

暂无数据

+ )} +
+ ); +} diff --git a/src/components/MeasurementItem.tsx b/src/components/MeasurementItem.tsx new file mode 100644 index 0000000..baa6f90 --- /dev/null +++ b/src/components/MeasurementItem.tsx @@ -0,0 +1,45 @@ +import icon_check_s from '../assets/icon_check_s_s.svg'; +import icon_check_u from '../assets/icon_check_s_u.svg'; +import icon_arr from '../assets/icon_arr_p_r.svg'; +import { Measurement } from '../services/apiTypes'; + +export default function MeasurementItem({ + item, + editMode, + selected, + onDetail, + onSelected, +}: { + item: Measurement; + editMode: boolean; + selected: boolean; + onDetail?: () => void; + onSelected?: () => void; +}) { + return ( +
+ {editMode && ( +
+ icon +
+ )} +
+
+

{item.name}

+ {/* {item.createAt.replace('T',' ').split(' ')[1]} */} +
+
+

{`${item.line}`}

+

{`${item.section}`}

+

{`${item.direction}方向`}

+
+
+ {!editMode && ( + + )} +
+ ); +} diff --git a/src/index.tsx b/src/index.tsx index 03ba115..95741e6 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -17,6 +17,7 @@ import Measure from './pages/Measure'; import Setting from './pages/Setting'; import Bluetooth from './pages/Bluetooth'; import Mine from './pages/Mine'; +import Mine2 from './pages/Mine2'; import MeasureSave from './pages/MeasureSave'; import MeasureRecord from './pages/MeasureRecord'; @@ -28,7 +29,7 @@ const router = createHashRouter( }> }> }> - }> + }> }> diff --git a/src/pages/Measure.tsx b/src/pages/Measure.tsx index 56499a3..b01c41e 100644 --- a/src/pages/Measure.tsx +++ b/src/pages/Measure.tsx @@ -14,23 +14,23 @@ import { useAppDispatch, useAppSelector } from '../utils/hooks'; import { updateTaskState } from '../store/features/measureSlice'; import Bridge from '../utils/bridge'; -declare global { - interface Window { - ReactNativeWebView: { postMessage: (arg: string) => void }; - funcMap: Record; - bridgeCall: (func: string, args: any[]) => void; - } -} -window.funcMap = { - add: (a: number, b: number) => a + b, - sub: (a: number, b: number) => a - b, -}; - -window.bridgeCall = (func, ...args) => { - console.log(func, args); - const res = window.funcMap[func].apply(null, args); - console.log('res:', res); -}; +// declare global { +// interface Window { +// ReactNativeWebView: { postMessage: (arg: string) => void }; +// funcMap: Record; +// bridgeCall: (func: string, args: any[]) => void; +// } +// } +// window.funcMap = { +// add: (a: number, b: number) => a + b, +// sub: (a: number, b: number) => a - b, +// }; + +// window.bridgeCall = (func, ...args) => { +// console.log(func, args); +// const res = window.funcMap[func].apply(null, args); +// console.log('res:', res); +// }; export default function Measure() { const navigate = useNavigate(); diff --git a/src/pages/Mine2.tsx b/src/pages/Mine2.tsx new file mode 100644 index 0000000..f3025e1 --- /dev/null +++ b/src/pages/Mine2.tsx @@ -0,0 +1,139 @@ +import { NavBar, Toast } from 'antd-mobile'; +import { useEffect, useRef, useState } from 'react'; +import { Measurement } from '../services/apiTypes'; +import Bridge from '../utils/bridge'; +import MeasureGroups from '../components/MeasureGroups'; +import { MoreOutline } from 'antd-mobile-icons'; +import * as R from 'ramda'; + +const PAGE_SIZE = 10; + +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, + }, + ], + }, +]; + +export default function Mine2() { + const [editMode, setEditMode] = useState(false); + const [selectedIds, setSelectedIds] = useState([]); + async function loadMoreRecords() {} + + const onItemSelect = (groupIdx: number, id: number) => { + if (selectedIds.includes(id)) { + setSelectedIds(R.reject((item) => item === id, selectedIds)); + } else { + setSelectedIds([...selectedIds, id]); + } + }; + + const onGroupSelect = (groupIdx: number) => { + const ids = dataList[groupIdx].list.map((item) => item.id); + if (R.intersection(selectedIds, ids).length === ids.length) { + setSelectedIds(R.difference(selectedIds, ids)); + } else { + setSelectedIds(R.union(selectedIds, ids)); + } + }; + + const right = ( +
setEditMode(!editMode)} + className="flex justify-end" + style={{ fontSize: 24 }} + > + +
+ ); + + return ( +
+ + 我的 + +
+ +
+
+ ); +}