feat(zhst/material): 升级智能柜的算法配置面板
This commit is contained in:
parent
7f64ffe221
commit
b5a74de4d9
@ -1,8 +1,9 @@
|
||||
import React, { forwardRef, ReactNode, useContext, useImperativeHandle } from 'react';
|
||||
import { Button, Flex, Image } from "antd";
|
||||
import React, { forwardRef, memo, ReactNode, useContext, useImperativeHandle } from 'react';
|
||||
import theme from 'antd/es/theme'
|
||||
import { CropperImage, ConfigProvider } from '@zhst/meta'
|
||||
import type { CropperImageProps } from '@zhst/meta'
|
||||
import { CameraOutlined } from '@ant-design/icons'
|
||||
import { Flex, Button, Image } from 'antd'
|
||||
import { VideoPlayer, ConfigProvider } from '@zhst/meta'
|
||||
import type { VideoViewProps } from '@zhst/meta'
|
||||
import { AlgorithmConfigImg, ErrorImage } from '../utils/base64Images'
|
||||
import AlgorithmTable from './components/algorithmTable'
|
||||
import TimeTemplateTable from './components/timeTemplateTable';
|
||||
@ -10,10 +11,11 @@ import { AlgorithmTableProps } from './components/algorithmTable/AlgorithmTable'
|
||||
import { TimeTemplateTableProps } from './components/timeTemplateTable/TimeTemplateTable';
|
||||
import classNames from 'classnames';
|
||||
import './index.less'
|
||||
import { Alert } from 'antd';
|
||||
|
||||
const { useToken } = theme
|
||||
|
||||
const Title = (props: any) => <h2 style={{ color: 'rgba(0, 0, 0, 0.88)' }} {...props}>{props.children}</h2>
|
||||
const Title = memo((props: any) => (<h2 style={{ color: 'rgba(0, 0, 0, 0.88)' }} {...props}>{props.children}</h2>))
|
||||
|
||||
export interface AlgorithmConfigProps {
|
||||
onAddAlgorithm?: () => void
|
||||
@ -43,13 +45,18 @@ export interface AlgorithmConfigProps {
|
||||
id: string;
|
||||
name: string;
|
||||
}[]
|
||||
algorithmTableProps?: AlgorithmTableProps<any>
|
||||
timeTemplateTableProps?: TimeTemplateTableProps<any>
|
||||
cropperImageProps?: CropperImageProps
|
||||
algorithmTableProps?: Partial<AlgorithmTableProps<any>>
|
||||
timeTemplateTableProps?: Partial<TimeTemplateTableProps<any>>
|
||||
selectedKey?: string
|
||||
rowKey?: string
|
||||
type: AlgorithmTableProps<any>['tableType']
|
||||
title?:string; // boxList列表的属性名称【点位列表、盒子列表】
|
||||
/**
|
||||
* @description 当前选中的视频链接
|
||||
*/
|
||||
videoUrl?: string
|
||||
videoProps?: Partial<VideoViewProps>
|
||||
errorMessage?: string;
|
||||
onSelect?: (key: string, info?: any) => void
|
||||
/**
|
||||
* 是否显示/隐藏加载更多按钮
|
||||
@ -59,6 +66,12 @@ export interface AlgorithmConfigProps {
|
||||
* 点击加载更多事件
|
||||
*/
|
||||
onLoadMoreButtonClick?: () => void;
|
||||
/**
|
||||
* 自定义左侧box
|
||||
* @param data 当前box详情
|
||||
* @returns
|
||||
*/
|
||||
customBoxItemRender?: (data?: any) => void
|
||||
/**
|
||||
* 自定义加载更多按钮
|
||||
*/
|
||||
@ -79,15 +92,18 @@ const AlgorithmConfig = forwardRef<AlgorithmConfigRef, AlgorithmConfigProps>((pr
|
||||
const {
|
||||
algorithmTableDataSource = [],
|
||||
timeTemplateDataSource = [],
|
||||
drawListener,
|
||||
cropperImageProps = {},
|
||||
algorithmTableProps,
|
||||
timeTemplateTableProps,
|
||||
videoProps,
|
||||
selectedKey,
|
||||
customBoxItemRender,
|
||||
errorMessage,
|
||||
boxList = [],
|
||||
type = 'multiple',
|
||||
type = 'single',
|
||||
rowKey = 'id',
|
||||
onSelect, title='盒子名称',
|
||||
onSelect,
|
||||
title='盒子名称',
|
||||
videoUrl,
|
||||
showLoadMoreButton,
|
||||
onLoadMoreButtonClick,
|
||||
customBatchCenterContent,
|
||||
@ -96,47 +112,46 @@ const AlgorithmConfig = forwardRef<AlgorithmConfigRef, AlgorithmConfigProps>((pr
|
||||
} = props
|
||||
const { getPrefixCls } = useContext(ConfigContext);
|
||||
const componentName = getPrefixCls('material-algo', customizePrefixCls);
|
||||
|
||||
const { token } = useToken()
|
||||
// @ts-ignore
|
||||
const { type: cropType } = cropperImageProps
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
}))
|
||||
|
||||
return (
|
||||
<Flex className={componentName} style={{ border: `1px solid ${token.colorBorder}`, backgroundColor: token.colorBgBase }}>
|
||||
<div className={classNames(`${componentName}-left`)} title={title} style={{ position: 'relative', width: '13.9%' }}>
|
||||
<Flex className={componentName} style={{ backgroundColor: token.colorBgBase }}>
|
||||
<div className={classNames(`${componentName}-left`)} title={title} style={{ position: 'relative' }}>
|
||||
<Title className={classNames(`${componentName}-title`)}>{title}</Title>
|
||||
<div className={classNames(`${componentName}-left-list`)} style={{ borderTop: `1px solid ${token.colorBorder}` }}>
|
||||
<div className={classNames(`${componentName}-left-list`)}>
|
||||
{boxList.map(item => {
|
||||
return (
|
||||
<p
|
||||
// @ts-ignore
|
||||
key={item[rowKey]}
|
||||
// @ts-ignore
|
||||
onClick={() => onSelect?.(item[rowKey], item)}
|
||||
style={{
|
||||
margin: 0,
|
||||
padding: `${token.paddingXXS}px ${token.paddingLG}px`,
|
||||
cursor: 'pointer',
|
||||
customBoxItemRender?.(item) || (
|
||||
<p
|
||||
// @ts-ignore
|
||||
color: selectedKey === item[rowKey] ? token.colorPrimary : token.colorText,
|
||||
key={item[rowKey]}
|
||||
// @ts-ignore
|
||||
backgroundColor: selectedKey === item[rowKey] ? token.blue1 : token.colorBgBase,
|
||||
transition: '.2s ease all',
|
||||
}}
|
||||
onMouseEnter={(e: any) => {
|
||||
e.target.style.backgroundColor = token.colorPrimaryBg
|
||||
e.target.style.color = token.colorPrimary
|
||||
}}
|
||||
onMouseLeave={(e: any) => {
|
||||
// @ts-ignore
|
||||
if (selectedKey === item[rowKey]) return
|
||||
e.target.style.color = token.colorText
|
||||
e.target.style.backgroundColor = null
|
||||
}}
|
||||
>{item.name}</p>
|
||||
onClick={() => onSelect?.(item[rowKey], item)}
|
||||
style={{
|
||||
margin: 0,
|
||||
padding: `${token.paddingXXS}px`,
|
||||
cursor: 'pointer',
|
||||
// @ts-ignore
|
||||
color: selectedKey === item[rowKey] ? token.colorPrimary : token.colorText,
|
||||
// @ts-ignore
|
||||
backgroundColor: selectedKey === item[rowKey] ? token.blue1 : token.colorBgBase,
|
||||
transition: '.2s ease all',
|
||||
}}
|
||||
onMouseEnter={(e: any) => {
|
||||
e.target.style.backgroundColor = token.colorPrimaryBg
|
||||
e.target.style.color = token.colorPrimary
|
||||
}}
|
||||
onMouseLeave={(e: any) => {
|
||||
// @ts-ignore
|
||||
if (selectedKey === item[rowKey]) return
|
||||
e.target.style.color = token.colorText
|
||||
e.target.style.backgroundColor = null
|
||||
}}
|
||||
><CameraOutlined style={{ marginRight: 8 }} />{item.name}</p>
|
||||
)
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
@ -146,13 +161,13 @@ const AlgorithmConfig = forwardRef<AlgorithmConfigRef, AlgorithmConfigProps>((pr
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div style={{ boxSizing: 'border-box', width: '46.3%', textAlign: 'center', borderLeft: `1px solid ${token.colorBorder}`, borderRight: `1px solid ${token.colorBorder}` }}>
|
||||
<div className={classNames(`${componentName}-middle`)} style={{ boxSizing: 'border-box', width: '46.3%', textAlign: 'center', }}>
|
||||
{errorMessage && <Alert style={{ marginBottom: 16 }} message={`错误代码:${errorMessage || '-'}`} type="error" showIcon />}
|
||||
{/* 单个配置 */}
|
||||
{type === 'single' ? (
|
||||
<CropperImage
|
||||
type="line"
|
||||
onCropEnd={drawListener}
|
||||
{...cropperImageProps}
|
||||
<VideoPlayer
|
||||
url={videoUrl!}
|
||||
{...videoProps}
|
||||
/>
|
||||
) : (
|
||||
<div className={classNames(`${componentName}-middle-cont`)}>
|
||||
@ -175,10 +190,10 @@ const AlgorithmConfig = forwardRef<AlgorithmConfigRef, AlgorithmConfigProps>((pr
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div style={{ width: '39.8%' }} >
|
||||
<div className={classNames(`${componentName}-right`)} >
|
||||
<div>
|
||||
<Title className={classNames(`${componentName}-title`)}>时间模板</Title>
|
||||
<div style={{ padding: `${token.paddingMD}px ${token.paddingSM}px`, borderTop: `1px solid ${token.colorBorder}`, borderBottom: `1px solid ${token.colorBorder}` }}>
|
||||
<div >
|
||||
<TimeTemplateTable
|
||||
dataSource={timeTemplateDataSource}
|
||||
{...timeTemplateTableProps}
|
||||
@ -187,9 +202,10 @@ const AlgorithmConfig = forwardRef<AlgorithmConfigRef, AlgorithmConfigProps>((pr
|
||||
</div>
|
||||
<div>
|
||||
<Title className={classNames(`${componentName}-title`)}>算法应用</Title>
|
||||
<div style={{ padding: `${token.paddingMD}px ${token.paddingSM}px`, borderTop: `1px solid ${token.colorBorder}` }}>
|
||||
<div >
|
||||
<AlgorithmTable
|
||||
dataSource={algorithmTableDataSource}
|
||||
timeTemplateData={timeTemplateDataSource}
|
||||
tableType={type}
|
||||
{...algorithmTableProps}
|
||||
/>
|
||||
|
@ -1,27 +1,24 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { DeleteFilled, EditFilled, ImportOutlined, PlusCircleFilled } from '@ant-design/icons';
|
||||
import type { ParamsType, ProColumns, ProTableProps } from '@ant-design/pro-components';
|
||||
import {
|
||||
ProTable,
|
||||
} from '@ant-design/pro-components';
|
||||
import { Popconfirm, Select, Space, Switch } from 'antd';
|
||||
import { Button, ButtonProps, Popconfirm, Select, Space, Switch } from 'antd';
|
||||
import { ConfigProvider } from '@zhst/meta'
|
||||
import theme from 'antd/es/theme'
|
||||
import { AnyObject } from 'antd/es/_util/type';
|
||||
import { SelectProps } from 'antd/lib';
|
||||
import SchemaFormModal from '../schemaFormModal';
|
||||
import classNames from 'classnames';
|
||||
import './index.less'
|
||||
|
||||
const { useToken } = theme
|
||||
const { ConfigContext } = ConfigProvider
|
||||
|
||||
export interface AlgorithmTableProps<DataSource, Params extends ParamsType = ParamsType, ValueType = "text"> extends ProTableProps<DataSource, Params, ValueType> {
|
||||
onAddAlgorithm?: (id?: string, record?: any) => void
|
||||
onItemSwitch?: (status?: boolean, id?: string, info?: any) => void
|
||||
onItemEdit?: (values?: any, info?: any) => void
|
||||
onItemEdit?: (values?: any, type?: 'edit' | 'delete' | 'draw' | 'switch' | 'runCycle', info?: any ) => void
|
||||
onItemDelete?: (id?: string, info?: any) => void
|
||||
onSortSelect?: SelectProps['onChange']
|
||||
onReuse?: ButtonProps['onClick']
|
||||
onDraw?: (id: any, info?: any) => void
|
||||
selectedKey?: string
|
||||
sortList?: {
|
||||
@ -29,87 +26,90 @@ export interface AlgorithmTableProps<DataSource, Params extends ParamsType = Par
|
||||
value: string;
|
||||
}[]
|
||||
tableType?: 'multiple' | 'single' // 多选/单选
|
||||
timeTemplateData?: any[]
|
||||
}
|
||||
|
||||
const AlgorithmTable= <DataSource extends AnyObject = AnyObject>(
|
||||
props: AlgorithmTableProps<DataSource, ParamsType, 'text'>
|
||||
) => {
|
||||
const {
|
||||
onAddAlgorithm,
|
||||
onItemSwitch,
|
||||
onItemEdit,
|
||||
onItemDelete,
|
||||
onSortSelect,
|
||||
selectedKey,
|
||||
onDraw,
|
||||
tableType = 'multiple',
|
||||
onReuse,
|
||||
timeTemplateData = [],
|
||||
sortList = [],
|
||||
prefixCls: customizePrefixCls
|
||||
} = props
|
||||
const { getPrefixCls } = useContext(ConfigContext);
|
||||
const componentName = getPrefixCls('material-algo-algoTable', customizePrefixCls);
|
||||
|
||||
|
||||
const { token } = useToken()
|
||||
|
||||
const columns: ProColumns<DataSource>[] = [
|
||||
{
|
||||
editable: false,
|
||||
title: '算法名称',
|
||||
dataIndex: 'templateName',
|
||||
},
|
||||
{
|
||||
disable: true,
|
||||
title: '运行周期',
|
||||
key: 'runCycle',
|
||||
dataIndex: 'runCycle',
|
||||
valueType: 'select',
|
||||
valueEnum: {
|
||||
1: { text: '黑夜' },
|
||||
0: { text: '白天' },
|
||||
render: (_, record) => {
|
||||
return (
|
||||
<Select
|
||||
style={{ width: 120 }}
|
||||
placeholder="运行周期"
|
||||
defaultValue={record.runCycle}
|
||||
onChange={value => onItemEdit?.(value, 'runCycle', record)}
|
||||
>
|
||||
{timeTemplateData.map(o => (
|
||||
<Select.Option key={o.id} >{o.templateName}</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
)
|
||||
},
|
||||
},
|
||||
// {
|
||||
// title: '算力占用',
|
||||
// dataIndex: 'powerOccupy',
|
||||
// },
|
||||
{
|
||||
editable: false,
|
||||
title: '启动状态',
|
||||
dataIndex: 'status',
|
||||
render: (_, record) => <Switch defaultChecked={record.status} onChange={_status => onItemEdit?.(_status, 'switch', record)} />
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'option',
|
||||
valueType: 'option',
|
||||
fixed: 'right',
|
||||
width: '120px',
|
||||
width: 140,
|
||||
render: (_DOM, record) => [
|
||||
<Switch value={record.status} onChange={_status => onItemSwitch?.(_status, record.id, record)} />,
|
||||
<a onClick={() => onDraw?.(record.id, record)} style={{ display: tableType === 'single' ? 'block' : 'none' }} href="#"><ImportOutlined /></a>,
|
||||
<SchemaFormModal
|
||||
type={record.templateType}
|
||||
onFinish={async (values) => onItemEdit?.(values, record)}
|
||||
trigger={<a href="#"><EditFilled /></a>}
|
||||
/>
|
||||
,
|
||||
<a onClick={() => onItemEdit?.(record.id, 'draw', record)}>框选</a>,
|
||||
<a onClick={() => onItemEdit?.(record.id, 'edit', record)}>编辑</a>,
|
||||
<Popconfirm
|
||||
title="确定删除吗?"
|
||||
onConfirm={() => onItemDelete?.(record.id, record)}
|
||||
onConfirm={() => onItemEdit?.(record.id, 'delete', record)}
|
||||
>
|
||||
<a href="#"><DeleteFilled /></a>
|
||||
<a style={{ color: 'red' }}>删除</a>
|
||||
</Popconfirm>,
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
console.log('123', 123)
|
||||
|
||||
return (
|
||||
<div className={componentName}>
|
||||
<Space className={classNames(`${componentName}-top`)} size={16}>
|
||||
<Select
|
||||
className={classNames(`${componentName}-top-select`)}
|
||||
value={selectedKey}
|
||||
placeholder="新增算法"
|
||||
onChange={onSortSelect}
|
||||
options={sortList}
|
||||
/>
|
||||
<PlusCircleFilled className={classNames(`${componentName}-top-plus`)} onClick={() => onAddAlgorithm?.(selectedKey)} style={{ color: token.colorPrimary, cursor: 'pointer' }} />
|
||||
<Button onClick={onReuse}>配置复用</Button>
|
||||
</Space>
|
||||
<ProTable<DataSource>
|
||||
columns={columns}
|
||||
bordered
|
||||
scroll={{ y: 240, x: 600 }}
|
||||
scroll={{ y: 400, x: 600 }}
|
||||
dataSource={[]}
|
||||
cardProps={{
|
||||
bodyStyle: {
|
||||
|
@ -3,7 +3,7 @@
|
||||
margin-bottom: 12px;
|
||||
|
||||
&-select {
|
||||
width: 320px;
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
&-plus {
|
||||
|
@ -5,8 +5,7 @@ import {
|
||||
ProTable,
|
||||
} from '@ant-design/pro-components';
|
||||
import { AnyObject } from 'antd/es/_util/type';
|
||||
import { InputNumber } from 'antd';
|
||||
|
||||
import './index.less'
|
||||
export interface TimeTemplateTableProps<DataSource, Params extends ParamsType = ParamsType, ValueType = "text"> extends ProTableProps<DataSource, Params, ValueType> {
|
||||
onItemBlur?: (value?: number | string, id?: any, record?: any) => void,
|
||||
}
|
||||
@ -14,10 +13,6 @@ export interface TimeTemplateTableProps<DataSource, Params extends ParamsType =
|
||||
const TimeTemplateTable = <DataSource extends AnyObject = AnyObject>(
|
||||
props: TimeTemplateTableProps<DataSource, ParamsType, 'text'>
|
||||
) => {
|
||||
const {
|
||||
onItemBlur,
|
||||
} = props
|
||||
|
||||
|
||||
const columns: ProColumns<DataSource>[] = [
|
||||
{
|
||||
@ -32,28 +27,17 @@ const TimeTemplateTable = <DataSource extends AnyObject = AnyObject>(
|
||||
title: '布控星期',
|
||||
dataIndex: 'arrangeDay',
|
||||
},
|
||||
// TODO: 暂时先注释后续在做这个功能
|
||||
// {
|
||||
// title: '算力占用',
|
||||
// dataIndex: 'powerOccupy',
|
||||
// },
|
||||
{
|
||||
title: '配置路数',
|
||||
key: 'option',
|
||||
valueType: 'option',
|
||||
render: (_, record) => <InputNumber value={record.lineNum} onBlur={e => onItemBlur?.(e.target.value, record.id, record)} min={0} />,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<ProTable<DataSource>
|
||||
className='time-template-table'
|
||||
columns={columns}
|
||||
cardProps={{
|
||||
bodyStyle: {
|
||||
padding: 0
|
||||
}
|
||||
}}
|
||||
bordered
|
||||
scroll={{ y: 95 }}
|
||||
toolbar={undefined}
|
||||
rowKey="id"
|
||||
|
@ -0,0 +1,3 @@
|
||||
.time-template-table {
|
||||
margin-bottom: 32px;
|
||||
}
|
@ -2,7 +2,7 @@ import React, { useRef, useState } from 'react';
|
||||
import { AlgorithmConfig, AlgorithmConfigRef } from '@zhst/material';
|
||||
import type { AlgorithmConfigProps } from '@zhst/material';
|
||||
import { Button, Space, Switch } from 'antd';
|
||||
import { CropperImageRefProps } from '@zhst/meta';
|
||||
import { CropperImageRefProps, VideoViewRef } from '@zhst/meta';
|
||||
|
||||
|
||||
const algorithmTableDataSource: any = []
|
||||
@ -20,7 +20,7 @@ for (let i = 0; i < 100; i += 1) {
|
||||
odRect:{
|
||||
"x":0.553125,"y":0.29722223,"w":0.048958335,"h":0.2462963
|
||||
},
|
||||
runCycle: i % 2 !== 0 ? '白天' : '黑夜',
|
||||
runCycle: String(i),
|
||||
creator: Math.floor(Math.random() * 20),
|
||||
});
|
||||
timeTemplateDataSource.push({
|
||||
@ -38,6 +38,8 @@ for (let i = 0; i < 100; i += 1) {
|
||||
})
|
||||
}
|
||||
|
||||
export const VIDEO_URL = `ws://10.0.0.7:9033/flv/File/test/test_h264_${Math.floor(Math.random() * 6) + 1}.mp4.flv?ip=127.0.0.1`
|
||||
|
||||
const demo = () => {
|
||||
const [algorithmTableList, setAlgorithmTableList] = useState(algorithmTableDataSource)
|
||||
const [timeTemplateData, setTimeTemplateData] = useState(timeTemplateDataSource)
|
||||
@ -45,14 +47,15 @@ const demo = () => {
|
||||
const [selectedKey, setSelectedKey] = useState('1')
|
||||
const [cropType, setCropType] = useState<'line' | 'rect'>('line')
|
||||
const [algorithmSelectedKey, setAlgorithmSelectedKey] = useState('1')
|
||||
const [tableType, setTableType] = useState<AlgorithmConfigProps['type']>('multiple')
|
||||
const [tableType, setTableType] = useState<AlgorithmConfigProps['type']>('single')
|
||||
const [editAble, setEditAble] = useState(false)
|
||||
const algorithmConfigRef = useRef<AlgorithmConfigRef>(null)
|
||||
const cropperImageRef = useRef<CropperImageRefProps>(null)
|
||||
const videoRef = useRef<VideoViewRef>(null)
|
||||
const [videoUrl, setVideoUrl] = useState('')
|
||||
const [odList, setOdList] = useState([])
|
||||
|
||||
// 绘画事件
|
||||
const handleDraw = (id: any, info: any) => {
|
||||
console.log('cropperImageRef', cropperImageRef)
|
||||
setEditAble(true)
|
||||
setCropType('line')
|
||||
}
|
||||
@ -75,15 +78,41 @@ const demo = () => {
|
||||
selectedKey={selectedKey}
|
||||
onSelect={key => {
|
||||
setSelectedKey(key)
|
||||
setVideoUrl(VIDEO_URL)
|
||||
setOdList([
|
||||
{
|
||||
"id": "123",
|
||||
"x": 0.5519352,
|
||||
"y": 0.2965385,
|
||||
"w": 0.05185461,
|
||||
"h": 0.24698898,
|
||||
selectAble: false,
|
||||
},
|
||||
{
|
||||
"id": "456",
|
||||
"x": 0.58543766,
|
||||
"y": Math.random(),
|
||||
"w": 0.052037954,
|
||||
"h": 0.2664015
|
||||
}
|
||||
])
|
||||
// setTimeTemplateData([])
|
||||
// setTableList([])
|
||||
// setBoxList([])
|
||||
}}
|
||||
videoUrl={videoUrl}
|
||||
videoProps={{
|
||||
ref: videoRef,
|
||||
onCropChange: (showCrop, normalizationRect) => {
|
||||
console.log('showCrop', showCrop, normalizationRect)
|
||||
},
|
||||
showOD: true,
|
||||
odList
|
||||
}}
|
||||
type={tableType}
|
||||
// 算法模块
|
||||
algorithmTableProps={{
|
||||
onItemSwitch: (status, id) => {
|
||||
console.log('算法状态 switch 变更')
|
||||
setAlgorithmTableList((pre: any[]) => {
|
||||
let arr = pre.map(o => {
|
||||
if (o.id === id) {
|
||||
@ -94,30 +123,25 @@ const demo = () => {
|
||||
return arr
|
||||
})
|
||||
},
|
||||
onItemEdit: async (values, itemInfo) => {
|
||||
console.log('算法单项编辑表单提交', values, itemInfo)
|
||||
onItemEdit: async (values, type, info) => {
|
||||
videoRef.current?.setShowCrop(true)
|
||||
console.log('算法单项编辑表单提交', videoRef, info)
|
||||
return true
|
||||
},
|
||||
onDraw: (id, info) => handleDraw(id, info),
|
||||
onItemDelete: (id, itemInfo) => console.log('删除', id, itemInfo),
|
||||
onAddAlgorithm: (id) => console.log('添加模板', id),
|
||||
selectedKey: algorithmSelectedKey,
|
||||
onSortSelect: (value) => setAlgorithmSelectedKey(value),
|
||||
// onSortSelect: (value) => setAlgorithmSelectedKey(value),
|
||||
sortList: [
|
||||
{ label: '白天', value: '1' },
|
||||
{ label: '黑夜', value: '2' },
|
||||
{ label: '火焰识别', value: '1' },
|
||||
{ label: '人脸识别', value: '2' },
|
||||
]
|
||||
}}
|
||||
// 时间模板模块
|
||||
timeTemplateTableProps={{
|
||||
onItemBlur: (val, id, itemInfo) => console.log('失焦事件', val, id, itemInfo),
|
||||
}}
|
||||
cropperImageProps={{
|
||||
type: cropType,
|
||||
editAble,
|
||||
ref: cropperImageRef,
|
||||
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
|
||||
}}
|
||||
/>
|
||||
</Space>
|
||||
);
|
||||
|
@ -1,21 +1,38 @@
|
||||
.zhst-material-algo {
|
||||
display: flex;
|
||||
&-title {
|
||||
margin: 18px 16px;
|
||||
margin: 16px 0;
|
||||
margin-top: 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&-left {
|
||||
flex: 0 0 240px;
|
||||
border-right: 1px solid #e5e5e5;
|
||||
&-list {
|
||||
padding-bottom: 36px;
|
||||
max-height: 612px;
|
||||
max-height: 892px;
|
||||
overflow-y: scroll;
|
||||
box-sizing: 'border-box';
|
||||
}
|
||||
}
|
||||
|
||||
&-middle {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 0 0 1040px;
|
||||
margin: 0 24px;
|
||||
height: auto;
|
||||
|
||||
&-cont {
|
||||
align-items: center;
|
||||
padding: 84px;
|
||||
border: 1px solid #e5e5e5;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
&-right {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
@ -358,6 +358,7 @@ const VideoPlayer = forwardRef<VideoViewRef, VideoViewProps>((props, ref) => {
|
||||
if (!isReady) return;
|
||||
|
||||
if (showCrop) {
|
||||
// 编辑状态
|
||||
handlerCropStart = addEventListenerWrapper(corpContainerRef.current, EVENT_CROP_START, () => {
|
||||
setCropRect(null);
|
||||
});
|
||||
@ -372,7 +373,7 @@ const VideoPlayer = forwardRef<VideoViewRef, VideoViewProps>((props, ref) => {
|
||||
alignRef?.current?.forceAlign?.();
|
||||
});
|
||||
let video: any = videoRef.current;
|
||||
//计算 limitcroppbox
|
||||
//计算 limit crop box
|
||||
let scale = Math.min(
|
||||
video.offsetWidth / video.videoWidth,
|
||||
video.offsetHeight / video.videoHeight
|
||||
@ -435,8 +436,7 @@ const VideoPlayer = forwardRef<VideoViewRef, VideoViewProps>((props, ref) => {
|
||||
height: _element.clientHeight,
|
||||
backgroundColor: 'transparent'
|
||||
});
|
||||
|
||||
// 判定是否存在od框
|
||||
// 预览状态
|
||||
showOD && odList?.forEach(_od => {
|
||||
cropInsRef?.current?.addShape(_od);
|
||||
})
|
||||
@ -447,7 +447,7 @@ const VideoPlayer = forwardRef<VideoViewRef, VideoViewProps>((props, ref) => {
|
||||
cropInsRef?.current?.destroy?.();
|
||||
cropInsRef.current = null;
|
||||
};
|
||||
}, [showCrop, isReady]);
|
||||
}, [showCrop, isReady, odList]);
|
||||
|
||||
const latestCropRect = useLatest(cropRect);
|
||||
|
||||
@ -507,6 +507,7 @@ const VideoPlayer = forwardRef<VideoViewRef, VideoViewProps>((props, ref) => {
|
||||
// 监听showCrop、cropRect - 监听是否可编辑、绘制的矩形
|
||||
useEffect(() => {
|
||||
//计算归一化crop rect
|
||||
// ! 待优化
|
||||
let normalizationRect = null;
|
||||
if (showCrop && cropRect) {
|
||||
let video: any = videoRef.current;
|
||||
|
Loading…
Reference in New Issue
Block a user