✨ feat(ID1000830): 【临】内部小程序销售报表面料排行出补充面料编号
【【临】内部小程序销售报表面料排行出补充面料编号】 https://www.tapd.cn/53459131/prong/stories/view/1153459131001000830
This commit is contained in:
parent
913cbc9d42
commit
c993fb84ef
53
src/components/table/components/CellTips/index.module.scss
Normal file
53
src/components/table/components/CellTips/index.module.scss
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
.mark {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.tooltip {
|
||||||
|
&-container {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
user-select: text;
|
||||||
|
color: white;
|
||||||
|
&-inner {
|
||||||
|
position: absolute;
|
||||||
|
background-color: #333333;
|
||||||
|
font-size: $font_size;
|
||||||
|
box-shadow: 0 0 30px 0 rgba(51, 51, 51, 0.2);
|
||||||
|
border-radius: 8px;
|
||||||
|
&-content {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: lighter;
|
||||||
|
color: white;
|
||||||
|
padding: 8px 12px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&-hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.arrowIcon {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
&-top {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
&-left {
|
||||||
|
transform: rotate(270deg);
|
||||||
|
}
|
||||||
|
&-right {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
&-bottom {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
326
src/components/table/components/CellTips/index.tsx
Normal file
326
src/components/table/components/CellTips/index.tsx
Normal file
@ -0,0 +1,326 @@
|
|||||||
|
import { View } from '@tarojs/components'
|
||||||
|
import Taro from '@tarojs/taro'
|
||||||
|
import { nextTick } from '@tarojs/runtime'
|
||||||
|
import classNames from 'classnames'
|
||||||
|
import { forwardRef, useCallback, useEffect, useId, useImperativeHandle, useMemo, useRef, useState, useTransition } from 'react'
|
||||||
|
import styles from './index.module.scss'
|
||||||
|
import IconFont from '@/components/iconfont/iconfont'
|
||||||
|
|
||||||
|
const SystemWidth = Taro.getSystemInfoSync().windowWidth
|
||||||
|
|
||||||
|
const arrowSize = 32
|
||||||
|
|
||||||
|
// 由于taro自动把px编译成rpx,所以这里需要把单位处理一下 转成真正的px
|
||||||
|
const convertPx = (px: number) => {
|
||||||
|
const realPx = (px / 750) * SystemWidth
|
||||||
|
return realPx
|
||||||
|
}
|
||||||
|
|
||||||
|
type Placement =
|
||||||
|
| 'top'
|
||||||
|
| 'top-start'
|
||||||
|
| 'top-end'
|
||||||
|
| 'right'
|
||||||
|
| 'right-start'
|
||||||
|
| 'right-end'
|
||||||
|
| 'bottom'
|
||||||
|
| 'bottom-start'
|
||||||
|
| 'bottom-end'
|
||||||
|
| 'left'
|
||||||
|
| 'left-start'
|
||||||
|
| 'left-end'
|
||||||
|
|
||||||
|
interface ToolTipEvent {
|
||||||
|
onVisibleChange?: (visible?: boolean) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ToolTipPropsType extends ToolTipEvent {
|
||||||
|
defaultVisible?: boolean
|
||||||
|
childrenNode: {
|
||||||
|
cellWidth: number
|
||||||
|
cellHeight: number
|
||||||
|
}
|
||||||
|
content: React.ReactNode
|
||||||
|
placement?: Placement
|
||||||
|
children?: React.ReactNode
|
||||||
|
customClassName?: string
|
||||||
|
customStyle?: React.CSSProperties
|
||||||
|
customContainerStyle?: React.CSSProperties
|
||||||
|
customContentStyle?: React.CSSProperties
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ToolTipRef {
|
||||||
|
show: () => void
|
||||||
|
hide: () => void
|
||||||
|
visible: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const popoverStyle = {
|
||||||
|
color: '#333333',
|
||||||
|
}
|
||||||
|
|
||||||
|
const ToolTip = (props: ToolTipPropsType, ref) => {
|
||||||
|
const id = useId()
|
||||||
|
const [, setForceUpdate] = useState({})
|
||||||
|
const { placement = 'top-start', defaultVisible = false, onVisibleChange, children, content = '请填入提示信息', customClassName, customStyle, customContentStyle, customContainerStyle, childrenNode } = props
|
||||||
|
|
||||||
|
const [visible, setVisible] = useState(defaultVisible)
|
||||||
|
|
||||||
|
const onVisibleChangeRef = useRef(onVisibleChange)
|
||||||
|
onVisibleChangeRef.current = onVisibleChange
|
||||||
|
|
||||||
|
// 暴露方法给外部
|
||||||
|
useImperativeHandle(
|
||||||
|
ref,
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
show: () => setVisible(true),
|
||||||
|
hide: () => setVisible(false),
|
||||||
|
visible,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[visible],
|
||||||
|
)
|
||||||
|
|
||||||
|
const handleClick = useCallback(() => {
|
||||||
|
setVisible((v) => {
|
||||||
|
onVisibleChangeRef.current?.(!v)
|
||||||
|
return !v
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const handleClickMark = useCallback(() => {
|
||||||
|
setVisible(false)
|
||||||
|
onVisibleChangeRef.current?.(false)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const getArrowSide = useMemo(() => {
|
||||||
|
const side = placement.split('-')[0] as string // placement = 'top-start' 取 'top'
|
||||||
|
|
||||||
|
const arrowSide = {
|
||||||
|
top: 'bottom',
|
||||||
|
right: 'left',
|
||||||
|
bottom: 'top',
|
||||||
|
left: 'right',
|
||||||
|
}[side] as string
|
||||||
|
return arrowSide
|
||||||
|
}, [placement])
|
||||||
|
|
||||||
|
const [viewport, setViewport] = useState<any>({})
|
||||||
|
const viewportRef = useRef(viewport)
|
||||||
|
viewportRef.current = viewport
|
||||||
|
|
||||||
|
const contextRectRef = useRef<any>(null)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (visible && !contextRectRef.current) {
|
||||||
|
nextTick(() => {
|
||||||
|
const query = Taro.createSelectorQuery()
|
||||||
|
query.select(`#content-${id}`).boundingClientRect((res) => {
|
||||||
|
console.log('contextRectRef', res)
|
||||||
|
contextRectRef.current = res
|
||||||
|
setForceUpdate({})
|
||||||
|
}).exec()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [visible, contextRectRef.current])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('useLayoutEffect')
|
||||||
|
const query = Taro.createSelectorQuery()
|
||||||
|
query.selectViewport().scrollOffset()
|
||||||
|
query.exec((res) => {
|
||||||
|
console.log(res[0])
|
||||||
|
console.log(res[1])
|
||||||
|
setViewport(res[0])
|
||||||
|
viewportRef.current = res[0]
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// 箭头 坐标
|
||||||
|
const arrowCoords = useMemo(() => {
|
||||||
|
const contextRect = contextRectRef.current
|
||||||
|
// contextRect 没获取到之前 隐藏
|
||||||
|
if (!contextRect) { return { top: '9999px' } }
|
||||||
|
console.log('getArrowSide==>', getArrowSide, childrenNode)
|
||||||
|
switch (getArrowSide) {
|
||||||
|
case 'bottom': // 下箭头
|
||||||
|
return {
|
||||||
|
left: childrenNode.cellWidth / 2 - convertPx(arrowSize) / 2,
|
||||||
|
top: -convertPx(arrowSize),
|
||||||
|
right: '',
|
||||||
|
bottom: '',
|
||||||
|
}
|
||||||
|
case 'left': // 左箭头
|
||||||
|
return {
|
||||||
|
left: childrenNode.cellWidth,
|
||||||
|
right: '',
|
||||||
|
top: childrenNode.cellHeight / 2 - convertPx(arrowSize) / 2,
|
||||||
|
bottom: '',
|
||||||
|
}
|
||||||
|
case 'top': // 上箭头
|
||||||
|
return {
|
||||||
|
left: childrenNode.cellWidth / 2 - convertPx(arrowSize) / 2,
|
||||||
|
right: '',
|
||||||
|
top: childrenNode.cellHeight,
|
||||||
|
bottom: '',
|
||||||
|
}
|
||||||
|
case 'right': // 右箭头
|
||||||
|
return {
|
||||||
|
left: -convertPx(arrowSize),
|
||||||
|
right: '',
|
||||||
|
top: childrenNode.cellHeight / 2 - convertPx(arrowSize) / 2,
|
||||||
|
bottom: '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [getArrowSide, childrenNode, contextRectRef.current])
|
||||||
|
|
||||||
|
// content 坐标
|
||||||
|
const contentCoords = useMemo(() => {
|
||||||
|
const placementSide = placement.split('-')[1] as string // placement = 'top-start' 取 'start'
|
||||||
|
console.log('placementSide', placementSide)
|
||||||
|
let coordsStyle = {}
|
||||||
|
const contextRect = contextRectRef.current
|
||||||
|
// contextRect 没获取到之前 隐藏
|
||||||
|
if (!contextRect) { return { top: '9999px' } }
|
||||||
|
console.log('contextRect', contextRect)
|
||||||
|
switch (getArrowSide) {
|
||||||
|
case 'bottom': // 下箭头
|
||||||
|
coordsStyle = {
|
||||||
|
bottom: convertPx(arrowSize) - 5,
|
||||||
|
top: '',
|
||||||
|
}
|
||||||
|
if (placementSide === 'start') {
|
||||||
|
return {
|
||||||
|
...coordsStyle,
|
||||||
|
left: 0,
|
||||||
|
right: '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (placementSide === 'end') {
|
||||||
|
return {
|
||||||
|
...coordsStyle,
|
||||||
|
left: '',
|
||||||
|
right: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return {
|
||||||
|
...coordsStyle,
|
||||||
|
left: `${-(contextRect?.width / 2 - childrenNode.cellWidth / 2)}px`,
|
||||||
|
right: '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 'left': // 左箭头
|
||||||
|
coordsStyle = {
|
||||||
|
left: childrenNode.cellWidth + convertPx(arrowSize) - 5,
|
||||||
|
right: '',
|
||||||
|
}
|
||||||
|
if (placementSide === 'start') {
|
||||||
|
return {
|
||||||
|
...coordsStyle,
|
||||||
|
top: 0,
|
||||||
|
bottom: '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (placementSide === 'end') {
|
||||||
|
return {
|
||||||
|
...coordsStyle,
|
||||||
|
top: '',
|
||||||
|
bottom: `${-childrenNode.cellHeight}px`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return {
|
||||||
|
...coordsStyle,
|
||||||
|
top: `${-(contextRect.height / 2 - childrenNode.cellHeight / 2)}px`,
|
||||||
|
bottom: '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 'top': // 上箭头
|
||||||
|
coordsStyle = {
|
||||||
|
top: childrenNode.cellHeight + convertPx(arrowSize) - 5,
|
||||||
|
bottom: '',
|
||||||
|
}
|
||||||
|
if (placementSide === 'start') {
|
||||||
|
return {
|
||||||
|
...coordsStyle,
|
||||||
|
left: 0,
|
||||||
|
right: '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (placementSide === 'end') {
|
||||||
|
return {
|
||||||
|
...coordsStyle,
|
||||||
|
left: '',
|
||||||
|
right: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return {
|
||||||
|
...coordsStyle,
|
||||||
|
left: `${-(contextRect?.width / 2 - childrenNode.cellWidth / 2)}px`,
|
||||||
|
right: '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 'right': // 右箭头
|
||||||
|
coordsStyle = {
|
||||||
|
left: '',
|
||||||
|
right: convertPx(arrowSize) - 5,
|
||||||
|
}
|
||||||
|
if (placementSide === 'start') {
|
||||||
|
return {
|
||||||
|
...coordsStyle,
|
||||||
|
top: 0,
|
||||||
|
bottom: '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (placementSide === 'end') {
|
||||||
|
return {
|
||||||
|
...coordsStyle,
|
||||||
|
top: '',
|
||||||
|
bottom: `${-childrenNode.cellHeight}px`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return {
|
||||||
|
...coordsStyle,
|
||||||
|
top: `${-(contextRect.height / 2 - childrenNode.cellHeight / 2)}px`,
|
||||||
|
bottom: '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [getArrowSide, childrenNode, contextRectRef.current])
|
||||||
|
|
||||||
|
const ContentComponent = useMemo(() => {
|
||||||
|
return (
|
||||||
|
<View className={classNames(styles.tooltip, visible ? '' : styles['tooltip-hidden'], customClassName)} style={customStyle}>
|
||||||
|
{/* 箭头 */}
|
||||||
|
<View className={classNames(styles.arrowIcon, styles[`arrowIcon-${getArrowSide}`])} style={arrowCoords}>
|
||||||
|
<IconFont name="icon-shouqi1" size={arrowSize} color={popoverStyle.color}></IconFont>
|
||||||
|
</View>
|
||||||
|
{/* content */}
|
||||||
|
<View className={styles['tooltip-inner']} id={`content-${id}`} style={{ ...contentCoords, ...customContentStyle }}>
|
||||||
|
<View className={styles['tooltip-inner-content']}>{content}</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}, [content, getArrowSide, visible, arrowCoords, contentCoords])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* 遮罩层 */}
|
||||||
|
<View className={classNames(styles.mark, visible ? '' : styles['tooltip-hidden'])} onClick={handleClickMark}></View>
|
||||||
|
<View style={customContainerStyle}>
|
||||||
|
<View className={styles['tooltip-container']}>
|
||||||
|
<View onClick={handleClick}>
|
||||||
|
{children}
|
||||||
|
</View>
|
||||||
|
{ContentComponent}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default forwardRef<ToolTipRef, ToolTipPropsType>(ToolTip)
|
||||||
@ -1,10 +1,13 @@
|
|||||||
import { ScrollView, Text, View } from '@tarojs/components'
|
import { RootPortal, ScrollView, Text, View } from '@tarojs/components'
|
||||||
|
import Taro from '@tarojs/taro'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import { useCallback, useMemo, useState } from 'react'
|
import React, { useCallback, useMemo, useRef, useState } from 'react'
|
||||||
import Iconfont from '../iconfont/iconfont'
|
import Iconfont from '../iconfont/iconfont'
|
||||||
import InfiniteScroll from '../infiniteScroll'
|
import InfiniteScroll from '../infiniteScroll'
|
||||||
import LoadMore, { LoadMoreStatus } from '../LoadMore'
|
import LoadMore, { LoadMoreStatus } from '../LoadMore'
|
||||||
|
import type { ToolTipRef } from '../toolTips'
|
||||||
|
import CellTips from './components/CellTips'
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
|
|
||||||
export interface ColumnsType {
|
export interface ColumnsType {
|
||||||
@ -14,6 +17,10 @@ export interface ColumnsType {
|
|||||||
key: string
|
key: string
|
||||||
render?: (text?: string, record?: RecordType, index?: number) => React.ReactNode
|
render?: (text?: string, record?: RecordType, index?: number) => React.ReactNode
|
||||||
ellipsis?: boolean | { isEllipsis: boolean; rows: number }
|
ellipsis?: boolean | { isEllipsis: boolean; rows: number }
|
||||||
|
showTipsConfig?: {
|
||||||
|
tips: string | ((text?: string, record?: RecordType, rowIndex?: number) => string)
|
||||||
|
isShowTips: boolean
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RecordType {
|
export interface RecordType {
|
||||||
@ -32,7 +39,10 @@ export interface TablePropsType {
|
|||||||
emptyText?: string
|
emptyText?: string
|
||||||
safeAreaInsetBottom?: boolean
|
safeAreaInsetBottom?: boolean
|
||||||
}
|
}
|
||||||
|
// 生成唯一的cellId
|
||||||
|
const generateCellId = (row: number, col: number) => {
|
||||||
|
return `cell-${row}-${col}`
|
||||||
|
}
|
||||||
const Table: FC<TablePropsType> = (props) => {
|
const Table: FC<TablePropsType> = (props) => {
|
||||||
const { columns, dataSource, onLoadMore, height = 400, moreText = '查看更多', loadingText = '加载中', noMoreText = '没有更多了', emptyText = '暂无数据', safeAreaInsetBottom = true } = props
|
const { columns, dataSource, onLoadMore, height = 400, moreText = '查看更多', loadingText = '加载中', noMoreText = '没有更多了', emptyText = '暂无数据', safeAreaInsetBottom = true } = props
|
||||||
|
|
||||||
@ -74,25 +84,72 @@ const Table: FC<TablePropsType> = (props) => {
|
|||||||
}
|
}
|
||||||
}, [dataSource])
|
}, [dataSource])
|
||||||
|
|
||||||
|
const toolTipsRef = useRef<ToolTipRef>(null)
|
||||||
|
// 当前的提示信息
|
||||||
|
const currentTips = useRef<{ title: string; tips?: string; width: string }>({ title: '', tips: '', width: '' })
|
||||||
|
// 当前的子节点的宽高
|
||||||
|
const currentChildrenNode = useRef<{ cellWidth: number; cellHeight: number }>({
|
||||||
|
cellWidth: 0,
|
||||||
|
cellHeight: 0,
|
||||||
|
})
|
||||||
|
const [toolTipsStyle, setToolTipsStyle] = useState<React.CSSProperties>({ position: 'fixed' })
|
||||||
|
const [, setForceUpdate] = useState({})
|
||||||
|
const handleClickCell = (id: string, columnConfig: ColumnsType, rowSource, rowIndex: number) => {
|
||||||
|
if (toolTipsRef.current?.visible) {
|
||||||
|
toolTipsRef.current?.hide()
|
||||||
|
}
|
||||||
|
// 提示
|
||||||
|
if (typeof columnConfig.showTipsConfig === 'object' && columnConfig.showTipsConfig.isShowTips) {
|
||||||
|
currentTips.current = {
|
||||||
|
width: columnConfig.width,
|
||||||
|
title: rowSource[columnConfig.dataIndex],
|
||||||
|
tips: typeof columnConfig.showTipsConfig?.tips === 'function' ? columnConfig.showTipsConfig?.tips(rowSource[columnConfig.dataIndex], rowSource, rowIndex) : columnConfig.showTipsConfig?.tips,
|
||||||
|
}
|
||||||
|
setForceUpdate({})
|
||||||
|
setTimeout(() => {
|
||||||
|
const query = Taro.createSelectorQuery()
|
||||||
|
query.select(`#${id}`).boundingClientRect()
|
||||||
|
query.exec((res) => {
|
||||||
|
currentChildrenNode.current = {
|
||||||
|
cellWidth: res[0].width,
|
||||||
|
cellHeight: res[0].height,
|
||||||
|
}
|
||||||
|
setToolTipsStyle({
|
||||||
|
position: 'fixed',
|
||||||
|
top: `${res[0].top}px`,
|
||||||
|
left: `${res[0].left}px`,
|
||||||
|
})
|
||||||
|
toolTipsRef.current?.show()
|
||||||
|
console.log('res===》', res)
|
||||||
|
})
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const hiddenChildrenToolTips = useMemo(() => {
|
||||||
|
return <Text id="hiddenTips" className={styles.td} style={{ color: 'transparent', width: currentChildrenNode.current.cellWidth, height: currentChildrenNode.current.cellHeight }}>{currentTips.current.title}</Text>
|
||||||
|
}, [currentTips.current.title])
|
||||||
|
|
||||||
const sourceContainer = () => {
|
const sourceContainer = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{!!dataSource?.list?.length
|
{!!dataSource?.list?.length
|
||||||
&& dataSource.list.map((source) => {
|
&& dataSource.list.map((source, row) => {
|
||||||
return (
|
return (
|
||||||
<View className={classnames(styles.tr, styles['bg-line'])} key={source.key}>
|
<View className={classnames(styles.tr, styles['bg-line'])} key={source.key}>
|
||||||
{columns.map((column, key) => {
|
{columns.map((column, col) => {
|
||||||
|
const cellId = generateCellId(row, col)
|
||||||
if (column.render) {
|
if (column.render) {
|
||||||
return (
|
return (
|
||||||
<View key={key} className={styles.td} style={{ width: column.width }}>
|
<View id={cellId} key={col} className={styles.td} style={{ width: column.width }}>
|
||||||
{/* 判断表头是不是有render 有就执行render */}
|
{/* 判断表头是不是有render 有就执行render */}
|
||||||
{column.render(source[column.dataIndex])}
|
{column.render(source[column.dataIndex], source, row)}
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return (
|
return (
|
||||||
<View key={key} className={classnames(styles.td, getColumnStyle(column))} style={{ width: column.width }}>
|
<View id={cellId} key={col} className={classnames(styles.td, getColumnStyle(column))} style={{ width: column.width }} onClick={() => handleClickCell(cellId, column, source, row)}>
|
||||||
{
|
{
|
||||||
source[column.dataIndex] // 根据表头填数据
|
source[column.dataIndex] // 根据表头填数据
|
||||||
}
|
}
|
||||||
@ -122,6 +179,9 @@ const Table: FC<TablePropsType> = (props) => {
|
|||||||
<InfiniteScroll enableLoadMoreStatus={false} safeAreaInsetBottom={safeAreaInsetBottom}>
|
<InfiniteScroll enableLoadMoreStatus={false} safeAreaInsetBottom={safeAreaInsetBottom}>
|
||||||
{sourceContainer()}
|
{sourceContainer()}
|
||||||
</InfiniteScroll>
|
</InfiniteScroll>
|
||||||
|
<CellTips childrenNode={currentChildrenNode.current} ref={toolTipsRef} customContainerStyle={toolTipsStyle} placement="top" content={currentTips.current?.tips}>
|
||||||
|
{hiddenChildrenToolTips}
|
||||||
|
</CellTips>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,10 +41,11 @@ interface ToolTipPropsType extends ToolTipEvent {
|
|||||||
children?: React.ReactNode
|
children?: React.ReactNode
|
||||||
customClassName?: string
|
customClassName?: string
|
||||||
customStyle?: React.CSSProperties
|
customStyle?: React.CSSProperties
|
||||||
|
customContainerStyle?: React.CSSProperties
|
||||||
customContentStyle?: React.CSSProperties
|
customContentStyle?: React.CSSProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ToolTipRef {
|
export interface ToolTipRef {
|
||||||
show: () => void
|
show: () => void
|
||||||
hide: () => void
|
hide: () => void
|
||||||
visible: boolean
|
visible: boolean
|
||||||
@ -57,11 +58,7 @@ const popoverStyle = {
|
|||||||
const ToolTip = (props: ToolTipPropsType, ref) => {
|
const ToolTip = (props: ToolTipPropsType, ref) => {
|
||||||
const id = useId()
|
const id = useId()
|
||||||
const [, setForceUpdate] = useState({})
|
const [, setForceUpdate] = useState({})
|
||||||
const { placement = 'top-start', defaultVisible = false, onVisibleChange, children, content = '请填入提示信息', customClassName, customStyle, customContentStyle } = props
|
const { placement = 'top-start', defaultVisible = false, onVisibleChange, children, content = '请填入提示信息', customClassName, customStyle, customContentStyle, customContainerStyle } = props
|
||||||
|
|
||||||
if (!content) {
|
|
||||||
throw new Error('tooltip: content 不能为空')
|
|
||||||
}
|
|
||||||
|
|
||||||
const [visible, setVisible] = useState(defaultVisible)
|
const [visible, setVisible] = useState(defaultVisible)
|
||||||
|
|
||||||
@ -318,7 +315,7 @@ const ToolTip = (props: ToolTipPropsType, ref) => {
|
|||||||
<>
|
<>
|
||||||
{/* 遮罩层 */}
|
{/* 遮罩层 */}
|
||||||
<View className={classNames(styles.mark, visible ? '' : styles['tooltip-hidden'])} onClick={handleClickMark}></View>
|
<View className={classNames(styles.mark, visible ? '' : styles['tooltip-hidden'])} onClick={handleClickMark}></View>
|
||||||
<View className={styles['tooltip-container']}>
|
<View className={styles['tooltip-container']} style={customContainerStyle}>
|
||||||
<View onClick={handleClick} id="children">
|
<View onClick={handleClick} id="children">
|
||||||
{children}
|
{children}
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
export default {
|
export default {
|
||||||
navigationBarTitleText: '销售统计',
|
navigationBarTitleText: '销售统计',
|
||||||
enablePullDownRefresh: true,
|
enablePullDownRefresh: false,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { memo, useCallback, useEffect, useRef, useState } from 'react'
|
|||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
import { ArrangedForm, OrderForm, PaymentAmountForm, ReturnGoodsOrderForm } from './config'
|
import { ArrangedForm, OrderForm, PaymentAmountForm, ReturnGoodsOrderForm } from './config'
|
||||||
import { ProductRankApi, PurchaserRankApi, SaleOrderDataFormApi, SalesmanRankApi } from '@/api/statistic/saleStatistic'
|
import { ProductRankApi, PurchaserRankApi, SaleOrderDataFormApi, SalesmanRankApi } from '@/api/statistic/saleStatistic'
|
||||||
import { dataUnit, formatPriceDiv, setPriceUnit } from '@/common/format'
|
import { dataUnit, formatHashTag, formatPriceDiv, setPriceUnit } from '@/common/format'
|
||||||
import { getFilterData } from '@/common/util'
|
import { getFilterData } from '@/common/util'
|
||||||
import Cell from '@/components/cell'
|
import Cell from '@/components/cell'
|
||||||
import Divider from '@/components/Divider'
|
import Divider from '@/components/Divider'
|
||||||
@ -16,7 +16,7 @@ import SelectSaleRankingIndicators from '@/components/SelectSaleRankingIndicator
|
|||||||
import SelectSaleType from '@/components/SelectSaleType'
|
import SelectSaleType from '@/components/SelectSaleType'
|
||||||
import type { ChangedValue } from '@/components/SelectTimePicker'
|
import type { ChangedValue } from '@/components/SelectTimePicker'
|
||||||
import SelectTimePicker from '@/components/SelectTimePicker'
|
import SelectTimePicker from '@/components/SelectTimePicker'
|
||||||
import type { TablePropsType } from '@/components/table'
|
import type { ColumnsType, TablePropsType } from '@/components/table'
|
||||||
import Table from '@/components/table'
|
import Table from '@/components/table'
|
||||||
import ToolTip from '@/components/toolTips'
|
import ToolTip from '@/components/toolTips'
|
||||||
import IconText from '@/components/iconText'
|
import IconText from '@/components/iconText'
|
||||||
@ -85,29 +85,33 @@ const productRankingColumns = [
|
|||||||
key: 'index',
|
key: 'index',
|
||||||
title: '编号',
|
title: '编号',
|
||||||
dataIndex: 'index',
|
dataIndex: 'index',
|
||||||
width: '20%',
|
width: '10%',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'product_name',
|
key: 'product_name',
|
||||||
title: '面料名称',
|
title: '面料名称',
|
||||||
dataIndex: 'product_name',
|
dataIndex: 'product_name',
|
||||||
width: '20%',
|
width: '45%',
|
||||||
ellipsis: {
|
ellipsis: {
|
||||||
isEllipsis: true,
|
isEllipsis: true,
|
||||||
rows: 2,
|
rows: 1,
|
||||||
|
},
|
||||||
|
showTipsConfig: {
|
||||||
|
tips: (text: string) => text,
|
||||||
|
isShowTips: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'roll',
|
key: 'roll',
|
||||||
title: '匹数',
|
title: '匹数',
|
||||||
dataIndex: 'roll',
|
dataIndex: 'roll',
|
||||||
width: '30%',
|
width: '20%',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'sales_amount',
|
key: 'sales_amount',
|
||||||
title: '交易金额',
|
title: '交易金额',
|
||||||
dataIndex: 'sales_amount',
|
dataIndex: 'sales_amount',
|
||||||
width: '30%',
|
width: '25%',
|
||||||
render: (text: string) => <Text className={styles.amount}>{text}</Text>,
|
render: (text: string) => <Text className={styles.amount}>{text}</Text>,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -118,13 +122,13 @@ const purchaserRankingColumns = [
|
|||||||
key: 'index',
|
key: 'index',
|
||||||
title: '编号',
|
title: '编号',
|
||||||
dataIndex: 'index',
|
dataIndex: 'index',
|
||||||
width: '20%',
|
width: '10%',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'purchaser_name',
|
key: 'purchaser_name',
|
||||||
title: '客户名称',
|
title: '客户名称',
|
||||||
dataIndex: 'purchaser_name',
|
dataIndex: 'purchaser_name',
|
||||||
width: '20%',
|
width: '45%',
|
||||||
ellipsis: {
|
ellipsis: {
|
||||||
isEllipsis: true,
|
isEllipsis: true,
|
||||||
rows: 2,
|
rows: 2,
|
||||||
@ -134,13 +138,13 @@ const purchaserRankingColumns = [
|
|||||||
key: 'roll',
|
key: 'roll',
|
||||||
title: '交易匹数',
|
title: '交易匹数',
|
||||||
dataIndex: 'roll',
|
dataIndex: 'roll',
|
||||||
width: '30%',
|
width: '20%',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'sales_amount',
|
key: 'sales_amount',
|
||||||
title: '交易金额',
|
title: '交易金额',
|
||||||
dataIndex: 'sales_amount',
|
dataIndex: 'sales_amount',
|
||||||
width: '30%',
|
width: '25%',
|
||||||
render: (text: string) => <Text className={styles.amount}>{text}</Text>,
|
render: (text: string) => <Text className={styles.amount}>{text}</Text>,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -151,13 +155,13 @@ const salesmanRankingColumns = [
|
|||||||
key: 'index',
|
key: 'index',
|
||||||
title: '编号',
|
title: '编号',
|
||||||
dataIndex: 'index',
|
dataIndex: 'index',
|
||||||
width: '20%',
|
width: '10%',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'sale_user_name',
|
key: 'sale_user_name',
|
||||||
title: '业务员名称',
|
title: '业务员名称',
|
||||||
dataIndex: 'sale_user_name',
|
dataIndex: 'sale_user_name',
|
||||||
width: '25%',
|
width: '45%',
|
||||||
ellipsis: {
|
ellipsis: {
|
||||||
isEllipsis: true,
|
isEllipsis: true,
|
||||||
rows: 2,
|
rows: 2,
|
||||||
@ -167,13 +171,13 @@ const salesmanRankingColumns = [
|
|||||||
key: 'roll',
|
key: 'roll',
|
||||||
title: '销售匹数',
|
title: '销售匹数',
|
||||||
dataIndex: 'roll',
|
dataIndex: 'roll',
|
||||||
width: '25%',
|
width: '20%',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'sales_amount',
|
key: 'sales_amount',
|
||||||
title: '销售金额',
|
title: '销售金额',
|
||||||
dataIndex: 'sales_amount',
|
dataIndex: 'sales_amount',
|
||||||
width: '30%',
|
width: '25%',
|
||||||
render: (text: string) => <Text className={styles.amount}>{text}</Text>,
|
render: (text: string) => <Text className={styles.amount}>{text}</Text>,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -262,7 +266,7 @@ const RankingBlock = (props: RankingBlockPropsType) => {
|
|||||||
list: res.data.list.map((item, index: number) => ({
|
list: res.data.list.map((item, index: number) => ({
|
||||||
key: index,
|
key: index,
|
||||||
index: index + 1,
|
index: index + 1,
|
||||||
product_name: item.product_name || '--',
|
product_name: formatHashTag(item.product_code, item.product_name) || '--',
|
||||||
sales_amount: `¥${priceformat(item.sales_amount)}`,
|
sales_amount: `¥${priceformat(item.sales_amount)}`,
|
||||||
roll: dataUnit(item.roll),
|
roll: dataUnit(item.roll),
|
||||||
})),
|
})),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user