type RowData = {
id: string
pid: string
price: number
count: number
totalPrice: number
isLeaf: boolean
}
const list: RowData[] = [
{ id: '1', pid: '', price: 0, count: 3, totalPrice: 0, isLeaf: false },
{ id: '1.1', pid: '1', price: 10, count: 20, totalPrice: 0, isLeaf: true },
{ id: '1.2', pid: '1', price: 20, count: 30, totalPrice: 0, isLeaf: true },
{ id: '2', pid: '', price: 0, count: 4, totalPrice: 0, isLeaf: false },
{ id: '2.1', pid: '2', price: 0, count: 2, totalPrice: 0, isLeaf: false },
{ id: '2.1.1', pid: '2.1', price: 1, count: 10, totalPrice: 0, isLeaf: true },
{ id: '2.1.2', pid: '2.1', price: 12, count: 5, totalPrice: 0, isLeaf: true },
]
function calculateTotalPrice(list: RowData[]): void {
const arr1 = list.map((v) => {
if (v.isLeaf) {
return { ...v, totalPrice: v.price * v.count }
} else {
return v
}
})
function getNodePath(id: string, arr: RowData[]): string[] {
const node = arr.find((v) => v.id === id)
if (node?.pid) {
const path = getNodePath(node.pid, arr)
path.push(node.id)
return path
}
return [id]
}
const arr2: (RowData & { path: string[] })[] = arr1.map((v) => ({ ...v, path: getNodePath(v.id, arr1) }))
const arr3 = arr2.sort((a, b) => b.path.length - a.path.length)
const arr4: (RowData & { path: string[] })[] = arr3.map(({ ...rest }) => rest)
arr4.forEach((v, _i, arr) => {
if (!v.isLeaf) {
const children = arr.filter((v2) => v2.path.includes(v.id) && v2.id !== v.id)
v.price = children.reduce((total, v2) => total + v2.totalPrice, 0)
v.totalPrice = v.price * v.count
}
})
console.log(arr4)
}
calculateTotalPrice(list)
import { useEffect, useState } from 'react'
export function useOnReady<T>(callback: T, isReady: boolean | (() => boolean)) {
const [done, set] = useState(false)
useEffect(() => {
if (done) return
if ((typeof isReady === 'boolean' && isReady) || (typeof isReady === 'function' && isReady())) {
if (typeof callback === 'function') {
callback()
set(true)
}
}
}, [callback, isReady, done])
}