Merge branch 'develop'
# Conflicts: # deploy/build.sh
This commit is contained in:
commit
2310cac125
4
.vscode/launch.json
vendored
4
.vscode/launch.json
vendored
@ -2,9 +2,9 @@
|
|||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"type": "chrome",
|
"type": "chrome",
|
||||||
"name": "http://localhost:8000/metas/big-image-preview",
|
"name": "lambo",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"url": "http://localhost:8000/metas/big-image-preview"
|
"url": "http://localhost:8000/metas"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
159
docs/index.md
159
docs/index.md
@ -1,159 +0,0 @@
|
|||||||
---
|
|
||||||
hero:
|
|
||||||
title: lambo
|
|
||||||
description: 致力于提升前端开发效率与规范
|
|
||||||
actions:
|
|
||||||
- text: 快速上手
|
|
||||||
link: /bizs
|
|
||||||
features:
|
|
||||||
- title: biz
|
|
||||||
emoji: 🍑
|
|
||||||
description: 业务库
|
|
||||||
- title: hooks
|
|
||||||
emoji: 💎
|
|
||||||
description: hooks
|
|
||||||
- title: func
|
|
||||||
emoji: 🌈
|
|
||||||
description: 常用函数库
|
|
||||||
- title: meta
|
|
||||||
emoji: ☀️
|
|
||||||
description: 原子组件库
|
|
||||||
- title: constants
|
|
||||||
emoji: 🈶️
|
|
||||||
description: 静态定义库
|
|
||||||
- title: request
|
|
||||||
emoji: 🥣
|
|
||||||
description: 网络请求库
|
|
||||||
- title: types
|
|
||||||
emoji: 🈸
|
|
||||||
description: typescript 声明库
|
|
||||||
- title: material
|
|
||||||
emoji: 🥱
|
|
||||||
description: 物料库
|
|
||||||
- title: cli
|
|
||||||
emoji: 🐔
|
|
||||||
description: 脚手架
|
|
||||||
---
|
|
||||||
|
|
||||||
## 目录结构
|
|
||||||
|
|
||||||
<Tree>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
docs
|
|
||||||
<small>全局文档</small>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
index.md
|
|
||||||
<small>这是首页文档</small>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
packages
|
|
||||||
<small>组件包目录</small>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
biz
|
|
||||||
<small>业务组件</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
func
|
|
||||||
<small>函数库</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
hooks
|
|
||||||
<small>hooks</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
constants
|
|
||||||
<small>静态枚举值定义</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
meta
|
|
||||||
<small>元组件</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
request
|
|
||||||
<small>请求库</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
types
|
|
||||||
<small>类型定义库</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
material
|
|
||||||
<small>物料库</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
cli
|
|
||||||
<small>脚手架</small>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
src
|
|
||||||
<small>这是 src 文件夹</small>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
index.md
|
|
||||||
<small>这是 index.md</small>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
.dumirc.ts
|
|
||||||
<small>文档配置</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
package.json
|
|
||||||
<small>这是 package.json</small>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</Tree>
|
|
||||||
|
|
||||||
## 本文档食用说明
|
|
||||||
|
|
||||||
目前在进行中的项目为:@zhst/bizs、@zhst/hooks、@zhst/meta、@zhst/func..
|
|
||||||
|
|
||||||
bizs: 基于@zhst/hooks、@zhst/meta、@zhst/func 开发,基本贴近于业务。<Badge>doing</Badge>
|
|
||||||
|
|
||||||
meta:基于 antd 开发,作为公司的定制化原子组件。<Badge>doing</Badge>
|
|
||||||
|
|
||||||
hooks:基于 ahooks、@zhst/func 定制化二次开发。<Badge>doing</Badge>
|
|
||||||
|
|
||||||
func:基于 lodash-es 定制化二次开发 (由于 utils 包名被使用了)<Badge>doing</Badge>
|
|
||||||
|
|
||||||
## 后续构思
|
|
||||||
|
|
||||||
想做一个,基于智慧视通开发场景和业务场景的前端技术流程化方案,希望它能渗透到整个研发的所有流程中。
|
|
||||||
|
|
||||||
比如:代码规范、git 提交规范、物料库、基于 electron 的前端工具客户端(可集成物料库、图片上传小工具)、api 自动生成...
|
|
||||||
|
|
||||||
:::info{title=@zhst/lint}
|
|
||||||
lint 工具库,包含:eslint-config、eslint-plugin、commit-lint
|
|
||||||
:::
|
|
||||||
|
|
||||||
:::info{title=@zhst/metarial}
|
|
||||||
物料库,可以直接通过 clone npm 仓库的形式生成模板页面,页面没有任何依赖,一个页面就是一个项目。
|
|
||||||
:::
|
|
||||||
|
|
||||||
:::info{title=@zhst/app}
|
|
||||||
基于 electron 的前端客户端工具,初期功能构思方案有:文件上传、git 仓库管理、物料库可视化页面一键生成
|
|
||||||
:::
|
|
||||||
|
|
||||||
:::info{title=@zhst/autoapi}
|
|
||||||
接口一键生成工具
|
|
||||||
:::
|
|
||||||
|
|
||||||
:::info{title=@types/zhst}
|
|
||||||
类型定义库
|
|
||||||
:::
|
|
||||||
|
|
||||||
:::info{title=@zhst/constants}
|
|
||||||
静态变量枚举库
|
|
||||||
:::
|
|
||||||
|
|
||||||
:::info{title=@zhst/cli}
|
|
||||||
基于物料库的脚手架,可以直接通过可视化界面搭建项目,偏向于 lowcode+ 思维
|
|
||||||
:::
|
|
@ -51,7 +51,6 @@
|
|||||||
"prettier --parser=typescript --write"
|
"prettier --parser=typescript --write"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@changesets/cli": "^2.27.1",
|
"@changesets/cli": "^2.27.1",
|
||||||
"@commitlint/cli": "^17.1.2",
|
"@commitlint/cli": "^17.1.2",
|
||||||
|
@ -1,5 +1,200 @@
|
|||||||
# @zhst/biz
|
# @zhst/biz
|
||||||
|
|
||||||
|
## 0.21.5
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- fix: 修改 zhst/meta
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.20.3
|
||||||
|
|
||||||
|
## 0.21.4
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- zhst/biz、zhst/meta、zhst/material: 修改 od、修改 boxSelectTree
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.20.2
|
||||||
|
|
||||||
|
## 0.21.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- zhst/biz: fix: 边框颜色主题色,实时监控窗口有图片和选中,预警记录文字溢出
|
||||||
|
|
||||||
|
## 0.21.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.20.1
|
||||||
|
|
||||||
|
## 0.21.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.20.0
|
||||||
|
|
||||||
|
## 0.21.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- feat: 修复之前发版错乱问题
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/hooks@0.13.0
|
||||||
|
- @zhst/func@0.15.0
|
||||||
|
- @zhst/icon@0.5.0
|
||||||
|
- @zhst/meta@0.19.0
|
||||||
|
|
||||||
|
## 0.20.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/func@0.14.1
|
||||||
|
- @zhst/hooks@0.12.1
|
||||||
|
- @zhst/meta@0.18.1
|
||||||
|
|
||||||
|
## 0.20.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- feat: 重新发版
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- fix: zhst/biz 优化实时监控布局
|
||||||
|
|
||||||
|
## 0.19.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- zhst/biz: 实时监控预警记录添加滚动条
|
||||||
|
|
||||||
|
## 0.19.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- fix: 修复适配问题
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/hooks@0.11.0
|
||||||
|
- @zhst/func@0.13.0
|
||||||
|
- @zhst/icon@0.3.0
|
||||||
|
- @zhst/meta@0.17.0
|
||||||
|
|
||||||
|
## 0.18.8
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/func@0.12.0
|
||||||
|
- @zhst/hooks@0.10.4
|
||||||
|
- @zhst/meta@0.16.4
|
||||||
|
|
||||||
|
## 0.18.7
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- @zhst/func@0.11.3
|
||||||
|
- @zhst/hooks@0.10.3
|
||||||
|
- @zhst/meta@0.16.3
|
||||||
|
|
||||||
|
## 0.18.6
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- biz 优化无限滚动组件、boxselectTree 组件;material 修改算法编辑模块
|
||||||
|
|
||||||
|
## 0.18.5
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- zhst/biz 优化 boxselecttree
|
||||||
|
|
||||||
|
## 0.18.4
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- biz-transfer: 修改删除时透出
|
||||||
|
|
||||||
|
## 0.18.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- zhst/biz - 修改穿梭框事件透出
|
||||||
|
|
||||||
|
## 0.18.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- @zhst/func@0.11.2
|
||||||
|
- @zhst/hooks@0.10.2
|
||||||
|
- @zhst/meta@0.16.2
|
||||||
|
|
||||||
|
## 0.18.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- @zhst/func@0.11.1
|
||||||
|
- @zhst/hooks@0.10.1
|
||||||
|
- @zhst/meta@0.16.1
|
||||||
|
|
||||||
|
## 0.18.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- zhst/biz:新增摘要列表-无限滚动组件
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/hooks@0.10.0
|
||||||
|
- @zhst/func@0.11.0
|
||||||
|
- @zhst/meta@0.16.0
|
||||||
|
|
||||||
|
## 0.17.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- 视频添加 OD 框,查看大图首次点击修复
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.15.0
|
||||||
|
- @zhst/func@0.10.2
|
||||||
|
- @zhst/hooks@0.9.2
|
||||||
|
|
||||||
|
## 0.16.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- zhst/biz: fix: 在业务层控制窗口切换状态
|
||||||
|
|
||||||
|
## 0.16.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- zhst/meta 大图圈选组件点击选不上 bug 修复,attach 遮挡底部框事件阻止修复
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.14.0
|
||||||
|
|
||||||
|
## 0.15.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- biz: 视频播放首图添加 od 框
|
||||||
|
|
||||||
## 0.14.0
|
## 0.14.0
|
||||||
|
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@zhst/biz",
|
"name": "@zhst/biz",
|
||||||
"version": "0.14.0",
|
"version": "0.21.5",
|
||||||
"description": "业务库",
|
"description": "业务库",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"business",
|
"business",
|
||||||
@ -47,6 +47,7 @@
|
|||||||
"antd": "^5.12.5",
|
"antd": "^5.12.5",
|
||||||
"classnames": "^2.5.1",
|
"classnames": "^2.5.1",
|
||||||
"dayjs": "^1.11.10",
|
"dayjs": "^1.11.10",
|
||||||
"rc-util": "^5.38.1"
|
"rc-util": "^5.38.1",
|
||||||
|
"react-infinite-scroll-component": "^6.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,11 +223,6 @@ const BigImageModal: React.FC<BigImageModalProps, BigModalRef> = forwardRef((pro
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: 页面初始化
|
|
||||||
useEffect(() => {
|
|
||||||
}, [dataSource]);
|
|
||||||
|
|
||||||
// 暴露 ref 实例
|
// 暴露 ref 实例
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
ref,
|
ref,
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
:global {
|
:global {
|
||||||
i:hover {
|
i:hover {
|
||||||
color: #f0f0f0 !important;
|
color: #fff !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ const Navigation: React.FC<{
|
|||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<Button type="text" disabled={disabled} onClick={onClick}>
|
<Button type="text" disabled={disabled} shape='circle' onClick={onClick}>
|
||||||
<IconFont size={28} color={color} icon={prev ? 'icon-qiehuanzuo' : 'icon-qiehuanyou'} />
|
<IconFont size={28} color={color} icon={prev ? 'icon-qiehuanzuo' : 'icon-qiehuanyou'} />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useContext } from 'react';
|
import React, { useContext, useRef } from 'react';
|
||||||
import WindowToggle from './components/WindowToggle';
|
import WindowToggle, { ISize } from './components/WindowToggle';
|
||||||
import WarningRecordList from './components/WarningRecordList';
|
import WarningRecordList from './components/WarningRecordList';
|
||||||
import { ConfigProvider } from '@zhst/meta';
|
import { ConfigProvider } from '@zhst/meta';
|
||||||
import { IRecord } from '../WarningRecordCard';
|
import { IRecord } from '../WarningRecordCard';
|
||||||
@ -32,6 +32,10 @@ interface RealTimeMonitorProps {
|
|||||||
cardStyle?: React.CSSProperties;
|
cardStyle?: React.CSSProperties;
|
||||||
imgStyle?: React.CSSProperties;
|
imgStyle?: React.CSSProperties;
|
||||||
largeImageTitle?: string;
|
largeImageTitle?: string;
|
||||||
|
size: ISize;
|
||||||
|
setSize: React.Dispatch<React.SetStateAction<ISize>>
|
||||||
|
maxRecordCount?: number;
|
||||||
|
warningImgStyle?: React.CSSProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const RealTimeMonitor: React.FC<RealTimeMonitorProps> = (props) => {
|
export const RealTimeMonitor: React.FC<RealTimeMonitorProps> = (props) => {
|
||||||
@ -50,16 +54,24 @@ export const RealTimeMonitor: React.FC<RealTimeMonitorProps> = (props) => {
|
|||||||
onRecordClick,
|
onRecordClick,
|
||||||
selectedRecordId,
|
selectedRecordId,
|
||||||
isRecordListLoading,
|
isRecordListLoading,
|
||||||
|
size,
|
||||||
|
setSize,
|
||||||
|
maxRecordCount,
|
||||||
|
warningImgStyle,
|
||||||
} = props
|
} = props
|
||||||
|
const toggleRef = useRef<HTMLDivElement>()
|
||||||
const componentName = getPrefixCls('biz-real-time-monitor', customizePrefixCls);
|
const componentName = getPrefixCls('biz-real-time-monitor', customizePrefixCls);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={componentName} style={{ display: 'flex' }} >
|
<div className={componentName} style={{ display: 'flex' }} >
|
||||||
<WindowToggle
|
<WindowToggle
|
||||||
|
toggleRef={toggleRef}
|
||||||
selectedWindowKey={selectedWindowKey}
|
selectedWindowKey={selectedWindowKey}
|
||||||
dataSource={videoDataSource}
|
dataSource={videoDataSource}
|
||||||
handleWindowClick={handleWindowClick}
|
handleWindowClick={handleWindowClick}
|
||||||
handleCloseButtonClick={handleCloseButtonClick}
|
handleCloseButtonClick={handleCloseButtonClick}
|
||||||
|
size={size}
|
||||||
|
setSize={setSize}
|
||||||
/>
|
/>
|
||||||
<WarningRecordList
|
<WarningRecordList
|
||||||
dataSource={warningDataSource}
|
dataSource={warningDataSource}
|
||||||
@ -69,6 +81,9 @@ export const RealTimeMonitor: React.FC<RealTimeMonitorProps> = (props) => {
|
|||||||
viewLargerImageModalRef={viewLargerImageModalRef}
|
viewLargerImageModalRef={viewLargerImageModalRef}
|
||||||
isRecordListLoading={isRecordListLoading}
|
isRecordListLoading={isRecordListLoading}
|
||||||
recordListTitle="监控预警记录"
|
recordListTitle="监控预警记录"
|
||||||
|
maxHeight={toggleRef.current?.offsetHeight}
|
||||||
|
maxRecordCount={maxRecordCount}
|
||||||
|
imgStyle={warningImgStyle}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -4,6 +4,7 @@ import { ViewLargerImageModalRef } from '../../../ViewLargerImageModal';
|
|||||||
import WarningRecordCard from '../../../WarningRecordCard';
|
import WarningRecordCard from '../../../WarningRecordCard';
|
||||||
import ViewLargerImageModal from '../../../ViewLargerImageModal';
|
import ViewLargerImageModal from '../../../ViewLargerImageModal';
|
||||||
import { Empty, Space, Spin } from 'antd';
|
import { Empty, Space, Spin } from 'antd';
|
||||||
|
import { pxToRem } from '@zhst/func'
|
||||||
import { LoadingOutlined } from '@ant-design/icons';
|
import { LoadingOutlined } from '@ant-design/icons';
|
||||||
import "./index.less"
|
import "./index.less"
|
||||||
|
|
||||||
@ -28,6 +29,8 @@ interface WarningRecordListProps {
|
|||||||
cardStyle?: React.CSSProperties;
|
cardStyle?: React.CSSProperties;
|
||||||
imgStyle?: React.CSSProperties;
|
imgStyle?: React.CSSProperties;
|
||||||
largeImageTitle?: string;
|
largeImageTitle?: string;
|
||||||
|
maxHeight?: number;
|
||||||
|
maxRecordCount?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const WarningRecordList: React.FC<WarningRecordListProps> = (props) => {
|
const WarningRecordList: React.FC<WarningRecordListProps> = (props) => {
|
||||||
@ -43,11 +46,12 @@ const WarningRecordList: React.FC<WarningRecordListProps> = (props) => {
|
|||||||
style,
|
style,
|
||||||
cardStyle,
|
cardStyle,
|
||||||
imgStyle,
|
imgStyle,
|
||||||
largeImageTitle
|
largeImageTitle,
|
||||||
|
maxHeight,
|
||||||
|
maxRecordCount = 10
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='zhst-biz-warning-record-list' style={style}>
|
<div className='zhst-biz-warning-record-list' style={{ maxHeight: `${pxToRem(`${maxHeight}`)}`, ...style }} >
|
||||||
<div className='header'>{recordListTitle}</div>
|
<div className='header'>{recordListTitle}</div>
|
||||||
<div className='body'>
|
<div className='body'>
|
||||||
{
|
{
|
||||||
@ -58,14 +62,14 @@ const WarningRecordList: React.FC<WarningRecordListProps> = (props) => {
|
|||||||
: (dataSource?.length) > 0 ?
|
: (dataSource?.length) > 0 ?
|
||||||
<Space direction='vertical' size={10} >
|
<Space direction='vertical' size={10} >
|
||||||
{dataSource?.map((record, index) => {
|
{dataSource?.map((record, index) => {
|
||||||
if (index > 2) return
|
if (index > maxRecordCount - 1) return
|
||||||
return (<WarningRecordCard
|
return (<WarningRecordCard
|
||||||
key={record?.id}
|
key={record?.id}
|
||||||
record={record}
|
record={record}
|
||||||
onRecordClick={(record) => { onRecordClick?.(record) }}
|
onRecordClick={(record) => { onRecordClick?.(record) }}
|
||||||
selectedRecordId={selectedRecordId}
|
selectedRecordId={selectedRecordId}
|
||||||
cardStyle={{ width: 300, height: 264, ...cardStyle }}
|
cardStyle={{ ...cardStyle }}
|
||||||
imgStyle={{ width: 280, height: 169, ...imgStyle }}
|
imgStyle={{ ...imgStyle }}
|
||||||
/>)
|
/>)
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
|
@ -2,19 +2,21 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
border-left: solid 1px #00000026;
|
border-left: solid 1px #00000026;
|
||||||
width: 320px;
|
min-width: 320px;
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
background-color: #EFF2F4;
|
background-color: #EFF2F4;
|
||||||
padding: 10px 20px;
|
padding: 0 20px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
line-height: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.body {
|
.body {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
overflow: hidden;
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,35 +1,35 @@
|
|||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import VideoPlayerCard from '../../../VideoPlayerCard';
|
import VideoPlayerCard from '../../../VideoPlayerCard';
|
||||||
import { VideoPlayerCardProps } from '../../../VideoPlayerCard';
|
import { VideoPlayerCardProps } from '../../../VideoPlayerCard';
|
||||||
import { Segmented } from 'antd';
|
import { Row, Col, Segmented, theme } from 'antd';
|
||||||
import { AppstoreOutlined, BarsOutlined } from '@ant-design/icons';
|
import { AppstoreOutlined, BarsOutlined } from '@ant-design/icons';
|
||||||
import { theme } from 'antd/lib';
|
import { pxToRem } from '@zhst/func'
|
||||||
import './index.less'
|
import './index.less'
|
||||||
|
|
||||||
type Size = 'large' | 'small'
|
export type ISize = 'large' | 'small'
|
||||||
|
|
||||||
interface WindowToggleProps {
|
interface WindowToggleProps {
|
||||||
dataSource?: VideoPlayerCardProps[];
|
dataSource?: VideoPlayerCardProps[];
|
||||||
handleWindowClick?: (key?: string) => void;
|
handleWindowClick?: (key?: string) => void;
|
||||||
handleCloseButtonClick?: (key?: string) => void;
|
handleCloseButtonClick?: (key?: string) => void;
|
||||||
selectedWindowKey?: string;
|
selectedWindowKey?: string;
|
||||||
|
size: ISize;
|
||||||
|
setSize: React.Dispatch<React.SetStateAction<ISize>>
|
||||||
|
toggleRef: React.MutableRefObject<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const WindowToggle: React.FC<WindowToggleProps> = (props) => {
|
export const WindowToggle: React.FC<WindowToggleProps> = (props) => {
|
||||||
|
|
||||||
const { dataSource = [], handleWindowClick, handleCloseButtonClick, selectedWindowKey } = props
|
const { dataSource = [], handleWindowClick, handleCloseButtonClick, selectedWindowKey, size = "large", setSize, toggleRef } = props
|
||||||
const [size, setSize] = useState<Size>("large");
|
|
||||||
const { useToken } = theme
|
const { useToken } = theme
|
||||||
const { token } = useToken()
|
const { token } = useToken()
|
||||||
|
|
||||||
const getLabelStyle = (isSelected: boolean) => ({
|
const getLabelStyle = (isSelected: boolean) => ({
|
||||||
padding: "0 11px", background: "#fff",
|
padding: `0 ${pxToRem("11px")}`, background: "#fff",
|
||||||
...(isSelected ? { background: token.colorPrimary, color: '#fff' } : {}),
|
...(isSelected ? { background: token.colorPrimary, color: '#fff' } : {}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='zhst-biz-window-toggle'>
|
<div className='zhst-biz-window-toggle' ref={toggleRef}>
|
||||||
{/* 切换按钮 */}
|
{/* 切换按钮 */}
|
||||||
<div className='header'>
|
<div className='header'>
|
||||||
<Segmented
|
<Segmented
|
||||||
@ -44,25 +44,52 @@ export const WindowToggle: React.FC<WindowToggleProps> = (props) => {
|
|||||||
const { windowKey } = dataSource[0]
|
const { windowKey } = dataSource[0]
|
||||||
handleWindowClick?.(windowKey)
|
handleWindowClick?.(windowKey)
|
||||||
}
|
}
|
||||||
setSize(value as Size)
|
setSize(value as ISize)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='body'>
|
<div className='body'>
|
||||||
{
|
|
||||||
dataSource?.map((item, index) => {
|
<Row gutter={[0, 20]} style={{ width: "100%" }} > {/* 设置栅格间距 */}
|
||||||
if (size === "large" && index > 0) return
|
{
|
||||||
return (
|
size === "large" ?
|
||||||
<VideoPlayerCard
|
<>
|
||||||
key={item.windowKey}
|
{
|
||||||
selectedWindowKey={selectedWindowKey}
|
dataSource?.map((item, index) => { // 仅显示前四个元素,即两行两列
|
||||||
size={size} {...item}
|
if (index > 0) return null
|
||||||
handleWindowClick={handleWindowClick}
|
return (
|
||||||
handleCloseButtonClick={handleCloseButtonClick}
|
<Col xs={24} sm={24} md={24} lg={24} xl={24} key={item.windowKey}>
|
||||||
/>)
|
<VideoPlayerCard
|
||||||
})
|
key={""}
|
||||||
}
|
selectedWindowKey={selectedWindowKey}
|
||||||
|
size={size}
|
||||||
|
handleWindowClick={handleWindowClick}
|
||||||
|
handleCloseButtonClick={handleCloseButtonClick}
|
||||||
|
{...item}
|
||||||
|
/>
|
||||||
|
</Col>)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
: <>
|
||||||
|
{dataSource?.map((item) => {
|
||||||
|
return (
|
||||||
|
<Col xs={24} sm={12} md={12} lg={12} xl={12} className='sm-card' key={item.windowKey}>
|
||||||
|
<VideoPlayerCard
|
||||||
|
key={item.windowKey}
|
||||||
|
selectedWindowKey={selectedWindowKey}
|
||||||
|
size={size}
|
||||||
|
handleWindowClick={handleWindowClick}
|
||||||
|
handleCloseButtonClick={handleCloseButtonClick}
|
||||||
|
{...item}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
);
|
||||||
|
})}</>
|
||||||
|
}
|
||||||
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -29,17 +29,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.body {
|
.body {
|
||||||
flex: 1;
|
|
||||||
width: 100%;
|
|
||||||
background-color: #E5EAEC;
|
background-color: #E5EAEC;
|
||||||
padding: 10px;
|
padding: 20px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
>div {
|
.sm-card:nth-child(odd) {
|
||||||
margin: 10px;
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm-card:nth-child(even) {
|
||||||
|
padding-left: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,2 +1,4 @@
|
|||||||
import WindowToggle from './WindowToggle'
|
import WindowToggle from './WindowToggle'
|
||||||
export default WindowToggle
|
export default WindowToggle
|
||||||
|
import type { ISize } from './WindowToggle';
|
||||||
|
export type { ISize };
|
@ -3,6 +3,7 @@ import React, { useState } from 'react';
|
|||||||
import { IRecord, RealTimeMonitor, VideoPlayerCardProps, useViewLargerImageModal } from '@zhst/biz';
|
import { IRecord, RealTimeMonitor, VideoPlayerCardProps, useViewLargerImageModal } from '@zhst/biz';
|
||||||
import { videoData, warningData } from './mock';
|
import { videoData, warningData } from './mock';
|
||||||
import { Space } from 'antd';
|
import { Space } from 'antd';
|
||||||
|
import { pxToRem } from '@zhst/func';
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import './index.less'
|
import './index.less'
|
||||||
|
|
||||||
@ -23,6 +24,8 @@ export default () => {
|
|||||||
windowKey: 'forth-window',
|
windowKey: 'forth-window',
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
// 控制窗口切换
|
||||||
|
const [size, setSize] = useState<"large" | "small">('large')
|
||||||
const [videoDataSource, setVideoDataSource] = useState<VideoPlayerCardProps[]>(initialVideoDataSource);
|
const [videoDataSource, setVideoDataSource] = useState<VideoPlayerCardProps[]>(initialVideoDataSource);
|
||||||
const [warningDataSource, setWarningDataSource] = useState<IRecord[]>();
|
const [warningDataSource, setWarningDataSource] = useState<IRecord[]>();
|
||||||
const [selectedWindowKey, setSelectedWindowKey] = useState<string | undefined>('first-window');
|
const [selectedWindowKey, setSelectedWindowKey] = useState<string | undefined>('first-window');
|
||||||
@ -34,7 +37,6 @@ export default () => {
|
|||||||
const handleWindowClick = (key?: string) => {
|
const handleWindowClick = (key?: string) => {
|
||||||
setSelectedWindowKey(key)
|
setSelectedWindowKey(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
const clearWindowData = (key?: string) => {
|
const clearWindowData = (key?: string) => {
|
||||||
// 当关闭窗口时 也要刷新 右侧 预警记录接口 不要忘记
|
// 当关闭窗口时 也要刷新 右侧 预警记录接口 不要忘记
|
||||||
setVideoDataSource((pre) => {
|
setVideoDataSource((pre) => {
|
||||||
@ -47,16 +49,13 @@ export default () => {
|
|||||||
return newVideoDataSource
|
return newVideoDataSource
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDownloadImg = (imageKey?: string) => {
|
const handleDownloadImg = (imageKey?: string) => {
|
||||||
console.log(imageKey)
|
|
||||||
// 可以调用 下面 方法关闭弹窗
|
// 可以调用 下面 方法关闭弹窗
|
||||||
// viewLargerImageModalRef.current?.handleCancel()
|
// viewLargerImageModalRef.current?.handleCancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
const onRecordClick = (record?: IRecord) => {
|
const onRecordClick = (record?: IRecord) => {
|
||||||
// 点击的时候把数据 拿过来处理一下传给大图弹框
|
// 点击的时候把数据 拿过来处理一下传给大图弹框
|
||||||
const { imageKey, warningType, boxId, position, cabietId, warningTime, warningTimestamp, warningTimeFormat = 'YYYY-MM-DD HH:mm:ss' } = record || {}
|
const { imageKey, warningType, boxId, position, cabietId, warningTime, warningTimestamp, warningTimeFormat = 'YYYY-MM-DD HH:mm:ss', odRect = [] } = record || {}
|
||||||
const formattedDate = warningTimestamp ? dayjs(warningTimestamp).format(warningTimeFormat) : '';
|
const formattedDate = warningTimestamp ? dayjs(warningTimestamp).format(warningTimeFormat) : '';
|
||||||
const warningTimeShow = warningTime ? warningTime : formattedDate
|
const warningTimeShow = warningTime ? warningTime : formattedDate
|
||||||
//用于渲染右侧的 信息
|
//用于渲染右侧的 信息
|
||||||
@ -68,8 +67,7 @@ export default () => {
|
|||||||
{ label: '柜子ID', value: cabietId },
|
{ label: '柜子ID', value: cabietId },
|
||||||
]
|
]
|
||||||
// 调用这个方法打开弹框
|
// 调用这个方法打开弹框
|
||||||
viewLargerImageModalRef?.current?.show({ imageKey: imageKey, warningData: warningData })
|
viewLargerImageModalRef?.current?.show({ imageKey: imageKey, warningData: warningData, odRect: odRect })
|
||||||
|
|
||||||
setSelectedRecordId(record?.id)
|
setSelectedRecordId(record?.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +87,8 @@ export default () => {
|
|||||||
// 模拟 视频数据请求
|
// 模拟 视频数据请求
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// 对后端返回数据进行处理 组装一套符合属性的 数据
|
// 对后端返回数据进行处理 组装一套符合属性的 数据
|
||||||
const newVideoData: VideoPlayerCardProps = { imageKey: videoData.imageKey, title: videoData.title, }
|
// videoSrc : videoData.videoSrc
|
||||||
|
const newVideoData: VideoPlayerCardProps = { imageKey: videoData.imageKey, title: videoData.title, odRect: videoData.odRect }
|
||||||
setVideoDataSource((pre) => {
|
setVideoDataSource((pre) => {
|
||||||
const newVideoDataSource: VideoPlayerCardProps[] = pre.map((item) => {
|
const newVideoDataSource: VideoPlayerCardProps[] = pre.map((item) => {
|
||||||
// 传给 选中的视频窗口
|
// 传给 选中的视频窗口
|
||||||
@ -131,6 +130,7 @@ export default () => {
|
|||||||
warningInfo: [`盒子${o.boxId}`, `位置${o.position}`, `柜子ID${o.cabietId}`],
|
warningInfo: [`盒子${o.boxId}`, `位置${o.position}`, `柜子ID${o.cabietId}`],
|
||||||
// cabietText: `柜子ID: ${o.cabietId}`,
|
// cabietText: `柜子ID: ${o.cabietId}`,
|
||||||
warningTimestamp: o.warningTimestamp,
|
warningTimestamp: o.warningTimestamp,
|
||||||
|
odRect: o.odRect
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
setWarningDataSource(newWarningDataSource)
|
setWarningDataSource(newWarningDataSource)
|
||||||
@ -151,7 +151,12 @@ export default () => {
|
|||||||
selectedRecordId={selectedRecordId}
|
selectedRecordId={selectedRecordId}
|
||||||
viewLargerImageModalRef={viewLargerImageModalRef}
|
viewLargerImageModalRef={viewLargerImageModalRef}
|
||||||
isRecordListLoading={isRecordListLoading}
|
isRecordListLoading={isRecordListLoading}
|
||||||
recordListTitle="监控预警记录" />
|
recordListTitle="监控预警记录"
|
||||||
|
size={size}
|
||||||
|
setSize={setSize}
|
||||||
|
warningImgStyle={{ width: `${pxToRem("280px")}`, height: `${pxToRem("169px")}` }}
|
||||||
|
/>
|
||||||
|
|
||||||
<button onClick={() => { mockData() }}>模拟请求</button>
|
<button onClick={() => { mockData() }}>模拟请求</button>
|
||||||
</Space>
|
</Space>
|
||||||
)
|
)
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
export const videoData = {
|
export const videoData = {
|
||||||
imageKey: 'https://i.yourimageshare.com/lRHiD2UnAT.png',
|
imageKey: 'https://i.yourimageshare.com/lRHiD2UnAT.png',
|
||||||
// videoSrc: 'ws://10.0.0.7:9033/flv/File/test/test_h264_1.mp4.flv?ip=127.0.0.1',
|
videoSrc: 'ws://10.0.0.7:9033/flv/File/test/test_h264_1.mp4.flv?ip=127.0.0.1',
|
||||||
title: `盒子1 点位1`
|
title: `盒子1 点位1`,
|
||||||
|
odRect: [{
|
||||||
|
"id": "456",
|
||||||
|
"x": 0.1519352,
|
||||||
|
"y": 0.2965385,
|
||||||
|
"w": 0.05185461,
|
||||||
|
"h": 0.24698898,
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const warningData = [
|
export const warningData = [
|
||||||
@ -15,6 +22,13 @@ export const warningData = [
|
|||||||
// warningTime: "2023-03-01 ",
|
// warningTime: "2023-03-01 ",
|
||||||
warningTimestamp: Date.now(),
|
warningTimestamp: Date.now(),
|
||||||
// warningTimeFormat:"YYYY-MM-DD"
|
// warningTimeFormat:"YYYY-MM-DD"
|
||||||
|
odRect: [{
|
||||||
|
"id": "456",
|
||||||
|
"x": 0.1519352,
|
||||||
|
"y": 0.2965385,
|
||||||
|
"w": 0.05185461,
|
||||||
|
"h": 0.24698898,
|
||||||
|
}]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
imageKey: 'https://i.yourimageshare.com/lRHiD2UnAT.png',
|
imageKey: 'https://i.yourimageshare.com/lRHiD2UnAT.png',
|
||||||
@ -26,6 +40,13 @@ export const warningData = [
|
|||||||
// warningTime: "2023-03-01 ",
|
// warningTime: "2023-03-01 ",
|
||||||
warningTimestamp: Date.now(),
|
warningTimestamp: Date.now(),
|
||||||
// warningTimeFormat:"YYYY-MM-DD"
|
// warningTimeFormat:"YYYY-MM-DD"
|
||||||
|
odRect: [{
|
||||||
|
"id": "456",
|
||||||
|
"x": 0.1519352,
|
||||||
|
"y": 0.2965385,
|
||||||
|
"w": 0.05185461,
|
||||||
|
"h": 0.24698898,
|
||||||
|
}]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
imageKey: 'https://i.yourimageshare.com/lRHiD2UnAT.png',
|
imageKey: 'https://i.yourimageshare.com/lRHiD2UnAT.png',
|
||||||
@ -37,6 +58,13 @@ export const warningData = [
|
|||||||
// warningTime: "2023-03-01 ",
|
// warningTime: "2023-03-01 ",
|
||||||
warningTimestamp: Date.now(),
|
warningTimestamp: Date.now(),
|
||||||
// warningTimeFormat:"YYYY-MM-DD"
|
// warningTimeFormat:"YYYY-MM-DD"
|
||||||
|
odRect: [{
|
||||||
|
"id": "456",
|
||||||
|
"x": 0.1519352,
|
||||||
|
"y": 0.2965385,
|
||||||
|
"w": 0.05185461,
|
||||||
|
"h": 0.24698898,
|
||||||
|
}]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
imageKey: 'https://i.yourimageshare.com/lRHiD2UnAT.png',
|
imageKey: 'https://i.yourimageshare.com/lRHiD2UnAT.png',
|
||||||
@ -48,6 +76,13 @@ export const warningData = [
|
|||||||
// warningTime: "2023-03-01 ",
|
// warningTime: "2023-03-01 ",
|
||||||
warningTimestamp: Date.now(),
|
warningTimestamp: Date.now(),
|
||||||
// warningTimeFormat:"YYYY-MM-DD"
|
// warningTimeFormat:"YYYY-MM-DD"
|
||||||
|
odRect: [{
|
||||||
|
"id": "456",
|
||||||
|
"x": 0.1519352,
|
||||||
|
"y": 0.2965385,
|
||||||
|
"w": 0.05185461,
|
||||||
|
"h": 0.24698898,
|
||||||
|
}]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
imageKey: 'https://i.yourimageshare.com/lRHiD2UnAT.png',
|
imageKey: 'https://i.yourimageshare.com/lRHiD2UnAT.png',
|
||||||
@ -59,6 +94,13 @@ export const warningData = [
|
|||||||
// warningTime: "2023-03-01 ",
|
// warningTime: "2023-03-01 ",
|
||||||
warningTimestamp: Date.now(),
|
warningTimestamp: Date.now(),
|
||||||
// warningTimeFormat:"YYYY-MM-DD"
|
// warningTimeFormat:"YYYY-MM-DD"
|
||||||
|
odRect: [{
|
||||||
|
"id": "456",
|
||||||
|
"x": 0.1519352,
|
||||||
|
"y": 0.2965385,
|
||||||
|
"w": 0.05185461,
|
||||||
|
"h": 0.24698898,
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Card, Space, CardProps, Spin, Button } from 'antd';
|
import { Card, Space, CardProps, Spin, Button, theme } from 'antd';
|
||||||
import { theme } from 'antd/lib';
|
import { ConfigProvider, VideoPlayer, CropperImage, type VideoViewRef, } from '@zhst/meta';
|
||||||
import { ConfigProvider, VideoPlayer, type VideoViewRef, } from '@zhst/meta';
|
|
||||||
import React, { useState, useEffect, ReactNode, useRef, useContext } from 'react';
|
import React, { useState, useEffect, ReactNode, useRef, useContext } from 'react';
|
||||||
import { CloseOutlined, LoadingOutlined } from '@ant-design/icons';
|
import { CloseOutlined, LoadingOutlined } from '@ant-design/icons';
|
||||||
import './index.less'
|
import './index.less'
|
||||||
@ -18,44 +17,56 @@ export interface VideoPlayerCardProps {
|
|||||||
title?: string | ReactNode
|
title?: string | ReactNode
|
||||||
handleCloseButtonClick?: (key?: string) => void;
|
handleCloseButtonClick?: (key?: string) => void;
|
||||||
handleWindowClick?: (key?: string) => void;
|
handleWindowClick?: (key?: string) => void;
|
||||||
|
odRect?: {
|
||||||
|
id: string;
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
w: number;
|
||||||
|
h: number;
|
||||||
|
selectAble?: boolean;
|
||||||
|
}[]
|
||||||
|
[key: string]: any
|
||||||
}
|
}
|
||||||
|
|
||||||
export const VideoPlayerCard: React.FC<VideoPlayerCardProps> = (props) => {
|
export const VideoPlayerCard: React.FC<VideoPlayerCardProps> = (props) => {
|
||||||
|
|
||||||
|
|
||||||
const { ConfigContext } = ConfigProvider;
|
const { ConfigContext } = ConfigProvider;
|
||||||
const { getPrefixCls } = useContext(ConfigContext);
|
const { getPrefixCls } = useContext(ConfigContext);
|
||||||
const { prefixCls: customizePrefixCls, showType, imageKey, videoSrc, cardProps, isWindowLoading, errorReasonText, size, title, handleCloseButtonClick, handleWindowClick, windowKey, selectedWindowKey = '' } = props;
|
const { prefixCls: customizePrefixCls, showType, imageKey, videoSrc, cardProps, isWindowLoading, errorReasonText, size, title, handleCloseButtonClick, handleWindowClick, windowKey, selectedWindowKey = '', odRect = [] } = props;
|
||||||
const componentName = getPrefixCls('biz-video-player-card', customizePrefixCls);
|
const componentName = getPrefixCls('biz-video-player-card', customizePrefixCls);
|
||||||
const [cardContent, setCardContent] = useState<JSX.Element | null>(null);
|
const [cardContent, setCardContent] = useState<JSX.Element | null>(null);
|
||||||
const { useToken } = theme
|
const { useToken } = theme
|
||||||
const { token } = useToken()
|
const { token } = useToken()
|
||||||
const videoRef = useRef<VideoViewRef>(null)
|
const videoRef = useRef<VideoViewRef>(null)
|
||||||
|
const odRectDefault = odRect?.map(rect => ({
|
||||||
|
...rect,
|
||||||
|
selectAble: rect.hasOwnProperty('selectAble') ? rect.selectAble : false
|
||||||
|
}));
|
||||||
const selectedBorderStyle = {
|
const selectedBorderStyle = {
|
||||||
border: `2px solid ${token.colorPrimary}`, boxShadow: " 0px 2px 9px 0px rgba(0,0,0,0.16)"
|
border: `2px solid ${token.colorPrimary}`, boxShadow: " 0px 2px 9px 0px rgba(0,0,0,0.16)"
|
||||||
}
|
}
|
||||||
const cardStyle: React.CSSProperties = {
|
const cardStyle: React.CSSProperties = {
|
||||||
...(size === 'large' ? { height: 931 } : { height: 456, cursor: 'pointer' }),
|
|
||||||
...(size === 'small' && selectedWindowKey === windowKey ? selectedBorderStyle : {})
|
...(size === 'small' && selectedWindowKey === windowKey ? selectedBorderStyle : {})
|
||||||
};
|
};
|
||||||
const videoPlayerCardStyle = size === 'small' ? { width: "calc(50% - 20px)" } : { flex: 1 }
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isWindowLoading && (videoSrc || imageKey)) {
|
if (!isWindowLoading && (videoSrc || imageKey)) {
|
||||||
let contentElement: JSX.Element | null = null;
|
let contentElement: JSX.Element | null = null;
|
||||||
if (videoSrc) {
|
if (videoSrc) {
|
||||||
contentElement = (
|
contentElement = (
|
||||||
<VideoPlayer ref={videoRef} url={videoSrc} />
|
<VideoPlayer ref={videoRef} url={videoSrc} showOD odList={odRectDefault} />
|
||||||
);
|
);
|
||||||
videoRef.current?.setShowCrop(true)
|
videoRef.current?.setShowCrop(true)
|
||||||
|
|
||||||
} else if (imageKey) {
|
} else if (imageKey) {
|
||||||
contentElement = (
|
contentElement = (
|
||||||
<img
|
<div style={{ width: "100%", height: "100%" }}>
|
||||||
alt="首帧图"
|
<CropperImage
|
||||||
src={imageKey}
|
// editAble={true}
|
||||||
style={{ width: "100%", height: "100%", display: 'block' }}
|
selectAble={false}
|
||||||
/>
|
odList={odRectDefault}
|
||||||
|
url={imageKey}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
setCardContent(contentElement);
|
setCardContent(contentElement);
|
||||||
@ -63,10 +74,10 @@ export const VideoPlayerCard: React.FC<VideoPlayerCardProps> = (props) => {
|
|||||||
setCardContent(null)
|
setCardContent(null)
|
||||||
}
|
}
|
||||||
}, [showType, imageKey, videoSrc, isWindowLoading]);
|
}, [showType, imageKey, videoSrc, isWindowLoading]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={componentName} onClick={() => { handleWindowClick?.(windowKey) }} style={videoPlayerCardStyle}>
|
<div className={componentName} onClick={() => { handleWindowClick?.(windowKey) }} >
|
||||||
<Card
|
<Card
|
||||||
|
className={`${size === 'large' ? `${componentName}-large` : `${componentName}-small`}`}
|
||||||
title={
|
title={
|
||||||
<Space style={{ width: "100%", justifyContent: "space-between" }}>
|
<Space style={{ width: "100%", justifyContent: "space-between" }}>
|
||||||
<div>{title}</div>
|
<div>{title}</div>
|
||||||
@ -77,7 +88,7 @@ export const VideoPlayerCard: React.FC<VideoPlayerCardProps> = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
</Space>}
|
</Space>}
|
||||||
style={{ display: "flex", flexDirection: "column", borderRadius: 4, overflow: "hidden", ...cardStyle }}
|
style={{ display: "flex", flexDirection: "column", borderRadius: 4, overflow: "hidden", ...cardStyle }}
|
||||||
bodyStyle={{ flex: 1 }}
|
styles={{ body: { flex: 1 } }}
|
||||||
{...cardProps}
|
{...cardProps}
|
||||||
>
|
>
|
||||||
{cardContent ? (
|
{cardContent ? (
|
||||||
@ -85,7 +96,7 @@ export const VideoPlayerCard: React.FC<VideoPlayerCardProps> = (props) => {
|
|||||||
{cardContent}
|
{cardContent}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div style={{ backgroundColor: '#000', height: '100%', display: 'flex', padding: '20px', boxSizing: 'border-box' }}>
|
<div className={`${componentName}-error`} >
|
||||||
{
|
{
|
||||||
isWindowLoading ?
|
isWindowLoading ?
|
||||||
<div style={{ flex: 1, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
|
<div style={{ flex: 1, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
|
||||||
|
@ -7,7 +7,7 @@ const mockVideoPlayerCardProps: VideoPlayerCardProps = {
|
|||||||
showType: 'image',
|
showType: 'image',
|
||||||
videoSrc: 'ws://10.0.0.7:9033/flv/File/test/test_h264_1.mp4.flv?ip=127.0.0.1',
|
videoSrc: 'ws://10.0.0.7:9033/flv/File/test/test_h264_1.mp4.flv?ip=127.0.0.1',
|
||||||
// 如果需要在没有视频时显示图片封面
|
// 如果需要在没有视频时显示图片封面
|
||||||
// imageKey: 'https://i.yourimageshare.com/lRHiD2UnAT.png',
|
// imageKey : 'https://i.yourimageshare.com/lRHiD2UnAT.png',
|
||||||
size: 'small',
|
size: 'small',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,4 +1,21 @@
|
|||||||
.zhst-biz-video-player-card {
|
.zhst-biz-video-player-card {
|
||||||
|
&-large {
|
||||||
|
height: 931px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-small {
|
||||||
|
height: 456px;
|
||||||
|
cursor: pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
&-error {
|
||||||
|
background-color: #000;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
.ant-card-head {
|
.ant-card-head {
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import React, { useImperativeHandle, useRef, useState, forwardRef, useContext } from 'react';
|
import React, { useImperativeHandle, useRef, useState, forwardRef, useContext } from 'react';
|
||||||
import { Modal, ModalProps, Space, SpaceProps } from 'antd';
|
import { Modal, ModalProps, Space, SpaceProps, theme } from 'antd';
|
||||||
import theme from 'antd/lib/theme';
|
|
||||||
import { DownloadOutlined } from '@ant-design/icons';
|
import { DownloadOutlined } from '@ant-design/icons';
|
||||||
import { ConfigProvider,CropperImage} from '@zhst/meta';
|
import { ConfigProvider, CropperImage } from '@zhst/meta';
|
||||||
|
|
||||||
import './index.less'
|
import './index.less'
|
||||||
|
|
||||||
@ -44,8 +43,6 @@ export const ViewLargerImageModal = forwardRef<ViewLargerImageModalRef, ViewLarg
|
|||||||
const { getPrefixCls } = useContext(ConfigContext);
|
const { getPrefixCls } = useContext(ConfigContext);
|
||||||
const { prefixCls: customizePrefixCls, modalProps, downloadImg, imgStyle, title = '预警大图', downloadText = '下载大图', spaceProps } = props
|
const { prefixCls: customizePrefixCls, modalProps, downloadImg, imgStyle, title = '预警大图', downloadText = '下载大图', spaceProps } = props
|
||||||
const componentName = getPrefixCls('biz-warning-larger-image', customizePrefixCls);
|
const componentName = getPrefixCls('biz-warning-larger-image', customizePrefixCls);
|
||||||
|
|
||||||
|
|
||||||
const { useToken } = theme
|
const { useToken } = theme
|
||||||
const { token } = useToken()
|
const { token } = useToken()
|
||||||
const [open, setOpen] = useState<boolean>(false);
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
@ -85,14 +82,13 @@ export const ViewLargerImageModal = forwardRef<ViewLargerImageModalRef, ViewLarg
|
|||||||
{...modalProps}
|
{...modalProps}
|
||||||
>
|
>
|
||||||
<Space size={0} {...spaceProps}>
|
<Space size={0} {...spaceProps}>
|
||||||
<div className={`${componentName}-left-img`}>
|
<div className={`${componentName}-left-img`} style={{ ...imgStyle }}>
|
||||||
<div style={{ width: 789, height: 444, ...imgStyle }}>
|
<CropperImage
|
||||||
<CropperImage
|
// editAble={false}
|
||||||
// editAble={true}
|
// selectAble={false}
|
||||||
odList={odRectDefault}
|
odList={odRectDefault}
|
||||||
url={imageKey}
|
url={imageKey}
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className='right-context'>
|
<div className='right-context'>
|
||||||
{warningData?.map(({ label, value }) => (
|
{warningData?.map(({ label, value }) => (
|
||||||
@ -101,7 +97,7 @@ export const ViewLargerImageModal = forwardRef<ViewLargerImageModalRef, ViewLarg
|
|||||||
{value}
|
{value}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
{imageKey && downloadImg && <div className='img-download' style={{ color: token.colorPrimary }} onClick={() => downloadImg?.(imageKey)} ><DownloadOutlined /><span style={{ paddingLeft: 3 }}>{downloadText}</span></div>}
|
{imageKey && downloadImg && <div className='img-download' style={{ color: token.colorPrimary }} onClick={() => downloadImg?.(imageKey)} ><DownloadOutlined /><span className='img-download-text'>{downloadText}</span></div>}
|
||||||
</div>
|
</div>
|
||||||
</Space>
|
</Space>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@ -17,7 +17,7 @@ const backEndData = [
|
|||||||
warningTimestamp: Date.now(),
|
warningTimestamp: Date.now(),
|
||||||
// warningTimeFormat:"YYYY-MM-DD"
|
// warningTimeFormat:"YYYY-MM-DD"
|
||||||
odRect: [{
|
odRect: [{
|
||||||
// "id": "456",
|
"id": "456",
|
||||||
"x": 0.6519352,
|
"x": 0.6519352,
|
||||||
"y": 0.2965385,
|
"y": 0.2965385,
|
||||||
"w": 0.05185461,
|
"w": 0.05185461,
|
||||||
@ -35,7 +35,7 @@ const backEndData = [
|
|||||||
warningTimestamp: Date.now(),
|
warningTimestamp: Date.now(),
|
||||||
// warningTimeFormat:"YYYY-MM-DD"
|
// warningTimeFormat:"YYYY-MM-DD"
|
||||||
odRect: [{
|
odRect: [{
|
||||||
// "id": "456",
|
"id": "456",
|
||||||
"x": 0.1519352,
|
"x": 0.1519352,
|
||||||
"y": 0.2965385,
|
"y": 0.2965385,
|
||||||
"w": 0.05185461,
|
"w": 0.05185461,
|
||||||
@ -71,7 +71,6 @@ export default () => {
|
|||||||
const viewLargerImageModalRef = useViewLargerImageModal()
|
const viewLargerImageModalRef = useViewLargerImageModal()
|
||||||
|
|
||||||
const handleDownloadImg = () => {
|
const handleDownloadImg = () => {
|
||||||
console.log('download')
|
|
||||||
// 可以调用 下面 方法关闭弹窗
|
// 可以调用 下面 方法关闭弹窗
|
||||||
// viewLargerImageModalRef.current?.handleCancel()
|
// viewLargerImageModalRef.current?.handleCancel()
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
.zhst-biz-warning-larger-image {
|
.zhst-biz-warning-larger-image {
|
||||||
font-family: MicrosoftYaHei;
|
font-family: MicrosoftYaHei;
|
||||||
|
|
||||||
|
&-left-img {
|
||||||
|
width: 789px;
|
||||||
|
height: 444px;
|
||||||
|
}
|
||||||
|
|
||||||
.ant-modal-content {
|
.ant-modal-content {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 492px;
|
height: 492px;
|
||||||
@ -52,6 +57,10 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
.img-download-text {
|
||||||
|
padding-left: 3px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ title: ViewLargerImageModal 查看大图弹窗
|
|||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| show() |通过 ref 用于开启弹窗 可以将点击的 记录传给弹窗| | | |
|
| show() |通过 ref 用于开启弹窗 可以将点击的 记录传给弹窗| | | |
|
||||||
| handleCancel() | 通过 ref 用于关闭弹窗 | | | |
|
| handleCancel() | 通过 ref 用于关闭弹窗 | | | |
|
||||||
| imageKey | 图片地址 |string | | |
|
| imageKey | 图片地址 |string | | |
|
||||||
| contextData | 大图显示的数据 | | | |
|
| contextData | 大图显示的数据 | | | |
|
||||||
| imgStyle | 用于修改图片样式 | | | |
|
| imgStyle | 用于修改图片样式 | | | |
|
||||||
| downloadImg | 传入下载图片的方法 | | | |
|
| downloadImg | 传入下载图片的方法 | | | |
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import { Card, Space, Divider, CardProps } from 'antd';
|
import { Card, Space, Divider, CardProps, theme } from 'antd';
|
||||||
import { theme } from 'antd/lib';
|
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { ConfigProvider,CropperImage} from '@zhst/meta';
|
import { ConfigProvider, CropperImage } from '@zhst/meta';
|
||||||
|
|
||||||
import './index.less'
|
import './index.less'
|
||||||
export interface IRecord {
|
export interface IRecord {
|
||||||
|
|
||||||
@ -55,7 +53,7 @@ export interface IRecord {
|
|||||||
接收 od框 坐标
|
接收 od框 坐标
|
||||||
*/
|
*/
|
||||||
odRect?: {
|
odRect?: {
|
||||||
id?: string;
|
id: string;
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
w: number;
|
w: number;
|
||||||
@ -77,13 +75,11 @@ export interface WarningRecordCardProps {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const WarningRecordCard: React.FC<WarningRecordCardProps> = (props) => {
|
export const WarningRecordCard: React.FC<WarningRecordCardProps> = (props) => {
|
||||||
|
|
||||||
const { ConfigContext } = ConfigProvider;
|
const { ConfigContext } = ConfigProvider;
|
||||||
const { getPrefixCls } = useContext(ConfigContext);
|
const { getPrefixCls } = useContext(ConfigContext);
|
||||||
const { prefixCls: customizePrefixCls, record, onRecordClick, style, cardProps, selectedRecordId, cardStyle, imgStyle } = props;
|
const { prefixCls: customizePrefixCls, record, onRecordClick, style, cardProps, selectedRecordId, cardStyle, imgStyle } = props;
|
||||||
const componentName = getPrefixCls('biz-warning-record-card', customizePrefixCls);
|
const componentName = getPrefixCls('biz-warning-record-card', customizePrefixCls);
|
||||||
|
|
||||||
;
|
|
||||||
const { imageKey, id, warningType, warningInfo = [], cabietText, warningTime, warningTimestamp, warningTimeFormat = 'YYYY-MM-DD HH:mm:ss', odRect = [] } = record || {}
|
const { imageKey, id, warningType, warningInfo = [], cabietText, warningTime, warningTimestamp, warningTimeFormat = 'YYYY-MM-DD HH:mm:ss', odRect = [] } = record || {}
|
||||||
const formattedDate = warningTimestamp ? dayjs(warningTimestamp).format(warningTimeFormat) : '';
|
const formattedDate = warningTimestamp ? dayjs(warningTimestamp).format(warningTimeFormat) : '';
|
||||||
const warningTimeShow = warningTime ? warningTime : formattedDate
|
const warningTimeShow = warningTime ? warningTime : formattedDate
|
||||||
@ -99,42 +95,40 @@ export const WarningRecordCard: React.FC<WarningRecordCardProps> = (props) => {
|
|||||||
const selectedCardStyle: React.CSSProperties = {
|
const selectedCardStyle: React.CSSProperties = {
|
||||||
...(selectedRecordId === record?.id ? selectedBorderStyle : {})
|
...(selectedRecordId === record?.id ? selectedBorderStyle : {})
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
onRecordClick?.(record);
|
onRecordClick?.(record);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={componentName} key={id} onClick={handleClick} style={style}>
|
<div className={componentName} key={id} onClick={handleClick} style={style}>
|
||||||
<Card
|
<Card
|
||||||
cover={
|
className={`${componentName}-card`}
|
||||||
<div style={{ width: 336, height: 203, ...imgStyle }}>
|
style={{ ...selectedCardStyle, ...cardStyle }}
|
||||||
<CropperImage
|
|
||||||
// editAble={true}
|
|
||||||
odList={odRectDefault}
|
|
||||||
url={imageKey}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
style={{ width: 356, height: 302, padding: 10, borderRadius: 4, ...selectedCardStyle, ...cardStyle }}
|
|
||||||
{...cardProps}
|
{...cardProps}
|
||||||
>
|
>
|
||||||
<div className={`${componentName}-left-context`}>
|
<div className={`${componentName}-card-img`} style={{ ...imgStyle }}>
|
||||||
<div className={`${componentName}-left-context-warning-type`}>{warningType}</div>
|
<CropperImage
|
||||||
<Space size={0} split={<Divider type="vertical" />}>
|
// 无法触发 图片点击时间需要 加 selectAble
|
||||||
{warningInfo?.map((item, index) => (
|
selectAble={false}
|
||||||
<div key={index} className="info-item">
|
odList={odRectDefault}
|
||||||
{item}
|
url={imageKey}
|
||||||
</div>
|
/>
|
||||||
))}
|
|
||||||
</Space>
|
|
||||||
<div className={`${componentName}-left-context-warning-time`}>{warningTimeShow}</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className={`${componentName}-cabietInfo`} >{cabietText}</div>
|
<div style={{ display: 'flex' }}>
|
||||||
|
<div className={`${componentName}-left-context`}>
|
||||||
|
<div className={`${componentName}-left-context-warning-type`}>{warningType}</div>
|
||||||
|
<Space size={0} split={<Divider type="vertical" />}>
|
||||||
|
{warningInfo?.map((item, index) => (
|
||||||
|
<div key={index} className="info-item">
|
||||||
|
{item}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</Space>
|
||||||
|
<div className={`${componentName}-left-context-warning-time`}>{warningTimeShow}</div>
|
||||||
|
</div>
|
||||||
|
<div className={`${componentName}-cabietInfo`} >{cabietText}</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -16,7 +16,7 @@ const backEndData = [
|
|||||||
warningTimestamp: Date.now(),
|
warningTimestamp: Date.now(),
|
||||||
// warningTimeFormat:"YYYY-MM-DD"
|
// warningTimeFormat:"YYYY-MM-DD"
|
||||||
odRect: [{
|
odRect: [{
|
||||||
// "id": "123",
|
"id": "123",
|
||||||
"x": 0.5519352,
|
"x": 0.5519352,
|
||||||
"y": 0.2965385,
|
"y": 0.2965385,
|
||||||
"w": 0.05185461,
|
"w": 0.05185461,
|
||||||
@ -34,7 +34,7 @@ const backEndData = [
|
|||||||
warningTimestamp: Date.now(),
|
warningTimestamp: Date.now(),
|
||||||
// warningTimeFormat:"YYYY-MM-DD"
|
// warningTimeFormat:"YYYY-MM-DD"
|
||||||
odRect: [{
|
odRect: [{
|
||||||
// "id": "456",
|
"id": "456",
|
||||||
"x": 0.1519352,
|
"x": 0.1519352,
|
||||||
"y": 0.2965385,
|
"y": 0.2965385,
|
||||||
"w": 0.05185461,
|
"w": 0.05185461,
|
||||||
|
@ -1,24 +1,32 @@
|
|||||||
.zhst-biz-warning-record-card {
|
.zhst-biz-warning-record-card {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
.ant-card-body {
|
|
||||||
padding: 0;
|
|
||||||
font-family: MicrosoftYaHei;
|
|
||||||
line-height: 19px;
|
|
||||||
display: flex;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-card-bordered {
|
.ant-card-bordered {
|
||||||
border: 2px solid #f0f0f0;
|
border: 2px solid #f0f0f0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-cover-img img {
|
&-card {
|
||||||
width: 336px;
|
border-radius: 4px;
|
||||||
height: 203px;
|
max-width: 380px;
|
||||||
border-radius: 0,
|
|
||||||
|
&-img {
|
||||||
|
width: 356px ;
|
||||||
|
height: 203px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-card-body {
|
||||||
|
padding: 10px;
|
||||||
|
font-family: MicrosoftYaHei;
|
||||||
|
line-height: 19px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
&-left-context {
|
&-left-context {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ title: WarningRecordCard 预警记录卡片
|
|||||||
|
|
||||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| imageKey | 图片src | string | - | - |
|
| imageKey | 图片src | string | - | - |
|
||||||
| id | 数据的唯一id 用于key 传值| string | - | - |
|
| id | 数据的唯一id 用于key 传值| string | - | - |
|
||||||
| warningType | 预警类型 | string | - | - |
|
| warningType | 预警类型 | string | - | - |
|
||||||
| warningInfo | 盒子 点位 柜子 等信息 | string[] | - | - |
|
| warningInfo | 盒子 点位 柜子 等信息 | string[] | - | - |
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
import React, { FC } from 'react';
|
import React, { FC, useContext } from 'react';
|
||||||
import { Tabs, TabsProps } from 'antd'
|
import { Tabs, TabsProps } from 'antd'
|
||||||
|
import { ConfigProvider } from '@zhst/meta';
|
||||||
import BoxPanel from './components/boxPanel';
|
import BoxPanel from './components/boxPanel';
|
||||||
import type { BoxPanelProps } from './components/boxPanel';
|
import type { BoxPanelProps } from './components/boxPanel';
|
||||||
|
import './index.less'
|
||||||
|
import classNames from 'classnames';
|
||||||
export interface BoxSelectTreeProps extends BoxPanelProps {
|
export interface BoxSelectTreeProps extends BoxPanelProps {
|
||||||
onTabChange?: (e: any) => void
|
onTabChange?: (e: any) => void
|
||||||
tabsProps?: TabsProps
|
tabsProps?: TabsProps
|
||||||
|
prefixCls?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { ConfigContext } = ConfigProvider
|
||||||
|
|
||||||
const BoxSelectTree: FC<BoxSelectTreeProps> = (props) => {
|
const BoxSelectTree: FC<BoxSelectTreeProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
data,
|
data,
|
||||||
@ -28,69 +33,52 @@ const BoxSelectTree: FC<BoxSelectTreeProps> = (props) => {
|
|||||||
customImport,
|
customImport,
|
||||||
showOptions,
|
showOptions,
|
||||||
extraBtns,
|
extraBtns,
|
||||||
|
prefixCls: customizePrefixCls
|
||||||
} = props
|
} = props
|
||||||
|
const { getPrefixCls } = useContext(ConfigContext);
|
||||||
|
const componentName = getPrefixCls('biz-box-select-tree', customizePrefixCls);
|
||||||
|
|
||||||
const items: TabsProps['items'] = [
|
const items: TabsProps['items'] = [
|
||||||
{
|
{
|
||||||
key: '1',
|
key: '1',
|
||||||
label: <div style={{ textAlign:'center', width: '160px' }} >盒子</div>,
|
label: <div className={classNames(componentName + '-tab')} style={{ textAlign:'center' }} >盒子</div>,
|
||||||
children: (
|
|
||||||
<BoxPanel
|
|
||||||
searchInputProps={searchInputProps}
|
|
||||||
boxDataSource={boxDataSource}
|
|
||||||
treeProps={treeProps}
|
|
||||||
data={data}
|
|
||||||
onCreate={onCreate}
|
|
||||||
onCreateSubmit={onCreateSubmit}
|
|
||||||
onBoxBatchDelete={onBoxBatchDelete}
|
|
||||||
onBoxDelete={onBoxDelete}
|
|
||||||
onSearch={onSearch}
|
|
||||||
onItemCheck={onItemCheck}
|
|
||||||
onItemSelect={onItemSelect}
|
|
||||||
showOptions={showOptions}
|
|
||||||
customImport={customImport}
|
|
||||||
extraBtns={extraBtns}
|
|
||||||
onClockClick={onClockClick}
|
|
||||||
onImport={onImport}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '2',
|
key: '2',
|
||||||
label: <div style={{ textAlign:'center', width: '160px' }} >盒子组</div>,
|
label: <div className={classNames(componentName + '-tab')} style={{ textAlign:'center' }} >盒子组</div>,
|
||||||
children: (
|
|
||||||
<BoxPanel
|
|
||||||
searchInputProps={searchInputProps}
|
|
||||||
boxDataSource={boxDataSource}
|
|
||||||
treeProps={treeProps}
|
|
||||||
data={data}
|
|
||||||
onCreate={onCreate}
|
|
||||||
onCreateSubmit={onCreateSubmit}
|
|
||||||
onBoxBatchDelete={onBoxBatchDelete}
|
|
||||||
onBoxDelete={onBoxDelete}
|
|
||||||
onSearch={onSearch}
|
|
||||||
onItemCheck={onItemCheck}
|
|
||||||
onItemSelect={onItemSelect}
|
|
||||||
showOptions={showOptions}
|
|
||||||
customImport={customImport}
|
|
||||||
extraBtns={extraBtns}
|
|
||||||
onClockClick={onClockClick}
|
|
||||||
onImport={onImport}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs
|
<div className={componentName}>
|
||||||
defaultActiveKey="1"
|
<Tabs
|
||||||
centered
|
defaultActiveKey="1"
|
||||||
items={items}
|
centered
|
||||||
onChange={onTabChange}
|
items={items}
|
||||||
tabBarGutter={0}
|
onChange={onTabChange}
|
||||||
indicator={{ size: (origin) => origin, align: 'center' }}
|
tabBarGutter={0}
|
||||||
{...tabsProps}
|
indicator={{ size: (origin) => origin, align: 'center' }}
|
||||||
/>
|
{...tabsProps}
|
||||||
|
/>
|
||||||
|
<BoxPanel
|
||||||
|
searchInputProps={searchInputProps}
|
||||||
|
boxDataSource={boxDataSource}
|
||||||
|
treeProps={treeProps}
|
||||||
|
data={data}
|
||||||
|
onCreate={onCreate}
|
||||||
|
onCreateSubmit={onCreateSubmit}
|
||||||
|
onBoxBatchDelete={onBoxBatchDelete}
|
||||||
|
onBoxDelete={onBoxDelete}
|
||||||
|
onSearch={onSearch}
|
||||||
|
onItemCheck={onItemCheck}
|
||||||
|
onItemSelect={onItemSelect}
|
||||||
|
showOptions={showOptions}
|
||||||
|
customImport={customImport}
|
||||||
|
extraBtns={extraBtns}
|
||||||
|
onClockClick={onClockClick}
|
||||||
|
onImport={onImport}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
.zhst-biz-box-select-tree-panel {
|
||||||
|
&-search {
|
||||||
|
display: flex;
|
||||||
|
padding: 0 12px;
|
||||||
|
|
||||||
|
&-input {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-btns {
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-btns {
|
||||||
|
padding: 6px 12px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
&-common {
|
||||||
|
padding: 4px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-import {
|
||||||
|
padding: 4px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-divider {
|
||||||
|
margin: 8px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-tree {
|
||||||
|
padding: 6px 0;
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,14 @@
|
|||||||
import React, { FC, useState, useRef } from 'react';
|
import React, { FC, useState, useRef, useContext } from 'react';
|
||||||
import{ Button, Divider, Input, Space, TreeDataNode } from 'antd'
|
import{ Button, Divider, Input, Space, TreeDataNode } from 'antd'
|
||||||
import { ModalForm, ModalFormProps, ProFormInstance, ProFormText } from '@ant-design/pro-components'
|
import { ModalForm, ModalFormProps, ProFormInstance, ProFormText } from '@ant-design/pro-components'
|
||||||
|
import { ConfigProvider } from '@zhst/meta';
|
||||||
import { ClockCircleOutlined, CloseCircleOutlined, DiffOutlined, FolderAddOutlined, ImportOutlined, SwitcherOutlined } from '@ant-design/icons'
|
import { ClockCircleOutlined, CloseCircleOutlined, DiffOutlined, FolderAddOutlined, ImportOutlined, SwitcherOutlined } from '@ant-design/icons'
|
||||||
import type { TreeProps, InputProps } from 'antd';
|
import type { TreeProps, InputProps } from 'antd';
|
||||||
import type { BoxTreeProps } from '../../../tree';
|
import type { BoxTreeProps } from '../../../tree';
|
||||||
import TreeTransferModal from '../../../treeTransferModal'
|
import TreeTransferModal from '../../../treeTransferModal'
|
||||||
import BoxTree from '../../../tree';
|
import BoxTree from '../../../tree';
|
||||||
|
import './index.less'
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
export interface BoxPanelProps {
|
export interface BoxPanelProps {
|
||||||
searchInputProps?: InputProps
|
searchInputProps?: InputProps
|
||||||
@ -26,8 +29,11 @@ export interface BoxPanelProps {
|
|||||||
onCreate?: () => void
|
onCreate?: () => void
|
||||||
customImport?: any
|
customImport?: any
|
||||||
extraBtns?: any
|
extraBtns?: any
|
||||||
|
prefixCls?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { ConfigContext } = ConfigProvider
|
||||||
|
|
||||||
const BoxPanel: FC<BoxPanelProps> = (props) => {
|
const BoxPanel: FC<BoxPanelProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
searchInputProps,
|
searchInputProps,
|
||||||
@ -46,8 +52,12 @@ const BoxPanel: FC<BoxPanelProps> = (props) => {
|
|||||||
onBatch,
|
onBatch,
|
||||||
onCreate,
|
onCreate,
|
||||||
boxDataSource,
|
boxDataSource,
|
||||||
|
prefixCls: customizePrefixCls,
|
||||||
customImport
|
customImport
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
|
const { getPrefixCls } = useContext(ConfigContext);
|
||||||
|
const componentName = getPrefixCls('biz-box-select-tree-panel', customizePrefixCls);
|
||||||
const [isTreeCheckable, setIsTreeCheckable] = useState(false)
|
const [isTreeCheckable, setIsTreeCheckable] = useState(false)
|
||||||
const [targetItems, setTargetItems] = useState<TreeDataNode[]>([]);
|
const [targetItems, setTargetItems] = useState<TreeDataNode[]>([]);
|
||||||
const [boxChoiceOpen, setBoxChoiceOpen] = useState(false)
|
const [boxChoiceOpen, setBoxChoiceOpen] = useState(false)
|
||||||
@ -104,7 +114,7 @@ const BoxPanel: FC<BoxPanelProps> = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: '0 16px' }}>
|
<div className={componentName}>
|
||||||
{/* 盒子选择弹框 */}
|
{/* 盒子选择弹框 */}
|
||||||
<TreeTransferModal
|
<TreeTransferModal
|
||||||
open={boxChoiceOpen}
|
open={boxChoiceOpen}
|
||||||
@ -118,102 +128,109 @@ const BoxPanel: FC<BoxPanelProps> = (props) => {
|
|||||||
onTreeCheck={onTreeCheck} // 树check选中事件
|
onTreeCheck={onTreeCheck} // 树check选中事件
|
||||||
onItemDelete={onItemDelete} // 右侧点击删除事件
|
onItemDelete={onItemDelete} // 右侧点击删除事件
|
||||||
/>
|
/>
|
||||||
<Space size={12} direction='vertical' style={{ width: '100%' }}>
|
<div className={classNames(componentName + '-search')}>
|
||||||
<Space size={4} style={{ width: '100%', justifyContent: 'space-between' }} >
|
<Input
|
||||||
<Input size='middle' onChange={(e) => onSearch?.(e)} placeholder='请输入盒子名称' {...searchInputProps} />
|
className={classNames(componentName + '-search-input')}
|
||||||
{customImport || (
|
size='middle'
|
||||||
<>
|
onChange={(e) => onSearch?.(e)}
|
||||||
<Button type="text" onClick={() => onBatch?.() || handleCheckable()} icon={isTreeCheckable ? <SwitcherOutlined /> : <DiffOutlined />} />
|
placeholder='请输入盒子名称'
|
||||||
<Button type="text" onClick={() => onClockClick?.()} icon={<ClockCircleOutlined />} />
|
{...searchInputProps}
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Space>
|
|
||||||
{/* 是否显示操作按钮 */}
|
|
||||||
{showOptions && (
|
|
||||||
<>
|
|
||||||
<Space align='center'>
|
|
||||||
<Button type='text' style={{ padding: '4px 8px' }} onClick={() => onImport?.()} icon={<ImportOutlined />} >导入盒子</Button>
|
|
||||||
<Divider type="vertical" style={{ margin: '8px 0' }} />
|
|
||||||
{onCreate ?
|
|
||||||
(
|
|
||||||
<Button onClick={onCreate} type='text' style={{ padding: '4px 8px' }} icon={<FolderAddOutlined />} >新建组</Button>
|
|
||||||
) : (
|
|
||||||
<ModalForm<{
|
|
||||||
name: string
|
|
||||||
boxList?: any[]
|
|
||||||
}>
|
|
||||||
width={'600px'}
|
|
||||||
open={onCreate ? false : undefined}
|
|
||||||
formRef={createFormRef}
|
|
||||||
title="新建组"
|
|
||||||
modalProps={{ destroyOnClose: true }}
|
|
||||||
layout='horizontal'
|
|
||||||
labelCol={{ span: 6 }}
|
|
||||||
wrapperCol={{ span: 18 }}
|
|
||||||
trigger={<Button type='text' style={{ padding: '4px 8px' }} icon={<FolderAddOutlined />} >新建组</Button>}
|
|
||||||
submitter={{
|
|
||||||
searchConfig: {
|
|
||||||
submitText: '确定',
|
|
||||||
resetText: '取消',
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
onFinish={onCreateSubmit}
|
|
||||||
>
|
|
||||||
<ProFormText
|
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
max: 20,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pattern: /^[^\s]*$/g,
|
|
||||||
message: '禁止输入空格'
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
fieldProps={{ showCount: true }}
|
|
||||||
width="md"
|
|
||||||
name="name"
|
|
||||||
label="盒子组名称"
|
|
||||||
placeholder="请输入盒子名称"
|
|
||||||
/>
|
|
||||||
<ProFormText
|
|
||||||
width="md"
|
|
||||||
name="boxList"
|
|
||||||
label="盒子选择"
|
|
||||||
fieldProps={{
|
|
||||||
readOnly: true,
|
|
||||||
value: `已选择${createFormRef.current?.getFieldValue('boxList')?.length || 0}个盒子`,
|
|
||||||
suffix: (
|
|
||||||
<Space>
|
|
||||||
<a onClick={() => {
|
|
||||||
createFormRef.current?.setFieldValue('boxList', null)
|
|
||||||
onBoxChoiceReset()
|
|
||||||
}} >恢复默认</a>
|
|
||||||
<a onClick={() => setBoxChoiceOpen(true)}>范围选择</a>
|
|
||||||
</Space>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</ModalForm>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
<Divider type="vertical" style={{ margin: '8px 0' }} />
|
|
||||||
{/* @ts-ignore */}
|
|
||||||
<Button danger type='text' style={{ padding: '4px 8px' }} icon={<CloseCircleOutlined />} disabled={treeProps?.checkedKeys?.length <= 0} onClick={onBoxBatchDelete} >删除</Button>
|
|
||||||
</Space>
|
|
||||||
<Divider style={{ margin: 0 }} />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{extraBtns}
|
|
||||||
<BoxTree
|
|
||||||
treeCheckable={isTreeCheckable}
|
|
||||||
data={data}
|
|
||||||
onItemSelect={onItemSelect}
|
|
||||||
onItemCheck={onItemCheck}
|
|
||||||
onItemDelete={onBoxDelete}
|
|
||||||
{...treeProps}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
{customImport || (
|
||||||
|
<div
|
||||||
|
className={classNames(componentName + '-search-btns')}
|
||||||
|
>
|
||||||
|
<Button type="text" onClick={() => onBatch?.() || handleCheckable()} icon={isTreeCheckable ? <SwitcherOutlined /> : <DiffOutlined />} />
|
||||||
|
<Button type="text" onClick={() => onClockClick?.()} icon={<ClockCircleOutlined />} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{/* 是否显示操作按钮 */}
|
||||||
|
{showOptions && (
|
||||||
|
<>
|
||||||
|
<div className={classNames(componentName + '-btns')}>
|
||||||
|
<Button className={classNames(componentName + '-btns-common')} type='text' onClick={() => onImport?.()} icon={<ImportOutlined />} >导入盒子</Button>
|
||||||
|
<Divider className={classNames(componentName + '-btns-divider')} type="vertical" />
|
||||||
|
{onCreate ?
|
||||||
|
(
|
||||||
|
<Button className={classNames(componentName + '-btns-common')} onClick={onCreate} type='text' icon={<FolderAddOutlined />} >新建组</Button>
|
||||||
|
) : (
|
||||||
|
<ModalForm<{
|
||||||
|
name: string
|
||||||
|
boxList?: any[]
|
||||||
|
}>
|
||||||
|
className={classNames(componentName + '-create-modal')}
|
||||||
|
open={onCreate ? false : undefined}
|
||||||
|
formRef={createFormRef}
|
||||||
|
title="新建组"
|
||||||
|
modalProps={{ destroyOnClose: true }}
|
||||||
|
layout='horizontal'
|
||||||
|
labelCol={{ span: 6 }}
|
||||||
|
wrapperCol={{ span: 18 }}
|
||||||
|
trigger={<Button type='text' className={classNames(componentName + '-btns-common')} icon={<FolderAddOutlined />} >新建组</Button>}
|
||||||
|
submitter={{
|
||||||
|
searchConfig: {
|
||||||
|
submitText: '确定',
|
||||||
|
resetText: '取消',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
onFinish={onCreateSubmit}
|
||||||
|
>
|
||||||
|
<ProFormText
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
max: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: /^[^\s]*$/g,
|
||||||
|
message: '禁止输入空格'
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
fieldProps={{ showCount: true }}
|
||||||
|
width="md"
|
||||||
|
name="name"
|
||||||
|
label="盒子组名称"
|
||||||
|
placeholder="请输入盒子名称"
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
width="md"
|
||||||
|
name="boxList"
|
||||||
|
label="盒子选择"
|
||||||
|
fieldProps={{
|
||||||
|
readOnly: true,
|
||||||
|
value: `已选择${createFormRef.current?.getFieldValue('boxList')?.length || 0}个盒子`,
|
||||||
|
suffix: (
|
||||||
|
<Space>
|
||||||
|
<a onClick={() => {
|
||||||
|
createFormRef.current?.setFieldValue('boxList', null)
|
||||||
|
onBoxChoiceReset()
|
||||||
|
}} >恢复默认</a>
|
||||||
|
<a onClick={() => setBoxChoiceOpen(true)}>范围选择</a>
|
||||||
|
</Space>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ModalForm>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
<Divider className={classNames(componentName + '-btns-divider')} type="vertical" />
|
||||||
|
{/* @ts-ignore */}
|
||||||
|
<Button className={classNames(componentName + '-btns-common')} danger type='text' icon={<CloseCircleOutlined />} disabled={treeProps?.checkedKeys?.length <= 0} onClick={onBoxBatchDelete} >删除</Button>
|
||||||
|
</div>
|
||||||
|
<Divider style={{ margin: 0 }} />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{extraBtns}
|
||||||
|
<BoxTree
|
||||||
|
className={classNames(componentName + '-tree')}
|
||||||
|
treeCheckable={isTreeCheckable}
|
||||||
|
data={data}
|
||||||
|
onItemSelect={onItemSelect}
|
||||||
|
onItemCheck={onItemCheck}
|
||||||
|
onItemDelete={onBoxDelete}
|
||||||
|
{...treeProps}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@ const demo = () => {
|
|||||||
addonBefore: (
|
addonBefore: (
|
||||||
<Select
|
<Select
|
||||||
value={searchType}
|
value={searchType}
|
||||||
|
dropdownMatchSelectWidth={false}
|
||||||
onChange={_type => {
|
onChange={_type => {
|
||||||
setSearchType(_type)
|
setSearchType(_type)
|
||||||
setSearchVal('')
|
setSearchVal('')
|
||||||
|
5
packages/biz/src/boxSelectTree/index.less
Normal file
5
packages/biz/src/boxSelectTree/index.less
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.zhst-biz-box-select-tree {
|
||||||
|
&-tab {
|
||||||
|
width: 160px;
|
||||||
|
}
|
||||||
|
}
|
@ -17,4 +17,5 @@ export { default as ViewLargerImageModal, useViewLargerImageModal } from './View
|
|||||||
export type { VideoPlayerCardProps } from './VideoPlayerCard'
|
export type { VideoPlayerCardProps } from './VideoPlayerCard'
|
||||||
export { default as VideoPlayerCard } from './VideoPlayerCard'
|
export { default as VideoPlayerCard } from './VideoPlayerCard'
|
||||||
export { default as RealTimeMonitor } from './RealTimeMonitor'
|
export { default as RealTimeMonitor } from './RealTimeMonitor'
|
||||||
|
export { default as InfiniteList } from './infiniteList'
|
||||||
|
export type { InfiniteListProps, InfiniteListRefProps } from './infiniteList'
|
||||||
|
129
packages/biz/src/infiniteList/InfiniteList.tsx
Normal file
129
packages/biz/src/infiniteList/InfiniteList.tsx
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/**
|
||||||
|
* Created by jiangzhixiong
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { forwardRef, ReactNode, useContext, useImperativeHandle, useRef } from 'react'
|
||||||
|
import { ConfigProvider } from '@zhst/meta';
|
||||||
|
import { Divider, Flex } from 'antd';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import InfiniteScroll from 'react-infinite-scroll-component';
|
||||||
|
import { SearchCard, SearchCardProps } from './components';
|
||||||
|
import './index.less'
|
||||||
|
import { Idata } from './components/SearchCard';
|
||||||
|
|
||||||
|
const { ConfigContext } = ConfigProvider
|
||||||
|
|
||||||
|
export interface InfiniteListProps {
|
||||||
|
type?: 'custom' | 'auto'
|
||||||
|
prefixCls?: string;
|
||||||
|
height?: number;
|
||||||
|
itemRender?: (data?: any) => React.ReactNode
|
||||||
|
loading?: boolean; //
|
||||||
|
data: Idata[];
|
||||||
|
targetId?: string; // 滚动列表 ID
|
||||||
|
loadMore?: (data?: any) => any;
|
||||||
|
params?: {
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
hasMore: boolean;
|
||||||
|
endMessage?: ReactNode
|
||||||
|
loadingMessage?: ReactNode
|
||||||
|
onItemClick?: (data: any) => void;
|
||||||
|
searchCardProps?: SearchCardProps
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InfiniteListRefProps {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const InfiniteList = forwardRef<InfiniteListRefProps, InfiniteListProps>((props, ref) => {
|
||||||
|
const {
|
||||||
|
prefixCls: customizePrefixCls,
|
||||||
|
height,
|
||||||
|
type = 'auto',
|
||||||
|
loadingMessage = <p style={{ textAlign: 'center' }}>加载中...</p>,
|
||||||
|
targetId = 'scrollableDiv',
|
||||||
|
itemRender,
|
||||||
|
hasMore,
|
||||||
|
onItemClick,
|
||||||
|
loadMore,
|
||||||
|
data = [],
|
||||||
|
endMessage = <Divider plain>没有更多数据了...🤐</Divider>,
|
||||||
|
searchCardProps
|
||||||
|
} = props
|
||||||
|
const { getPrefixCls } = useContext(ConfigContext);
|
||||||
|
const componentName = getPrefixCls('biz-infinite-list', customizePrefixCls);
|
||||||
|
const listRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
|
||||||
|
useImperativeHandle(ref, () => ({
|
||||||
|
|
||||||
|
}))
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
id={targetId}
|
||||||
|
className={classNames(componentName)}
|
||||||
|
ref={listRef}
|
||||||
|
style={{
|
||||||
|
height,
|
||||||
|
overflow: 'auto',
|
||||||
|
padding: 12
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* {loading ? (
|
||||||
|
<p>加载中...</p>
|
||||||
|
) : (
|
||||||
|
<Flex wrap='wrap' gap="small" className={classNames(componentName + 'items')}>
|
||||||
|
{data?.list?.map((item) => (
|
||||||
|
itemRender?.(item) || (
|
||||||
|
<div className={classNames(componentName + 'items-item')}>
|
||||||
|
<SearchCard data={item} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
))}
|
||||||
|
</Flex>
|
||||||
|
)} */}
|
||||||
|
<InfiniteScroll
|
||||||
|
dataLength={data.length}
|
||||||
|
next={type === 'auto' ? loadMore! : () => {}}
|
||||||
|
hasMore={hasMore}
|
||||||
|
loader={loadingMessage}
|
||||||
|
endMessage={endMessage}
|
||||||
|
scrollableTarget={targetId}
|
||||||
|
>
|
||||||
|
<Flex wrap='wrap' gap="small" className={classNames(componentName + 'items')}>
|
||||||
|
{data?.map((item, idx) => (
|
||||||
|
itemRender?.(item) || (
|
||||||
|
<div
|
||||||
|
key={idx}
|
||||||
|
className={classNames(componentName + 'items-item')}
|
||||||
|
onClick={() => {
|
||||||
|
onItemClick?.(item)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SearchCard
|
||||||
|
id={idx + 1}
|
||||||
|
data={item}
|
||||||
|
width="184px"
|
||||||
|
{...searchCardProps}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
))}
|
||||||
|
</Flex>
|
||||||
|
</InfiniteScroll>
|
||||||
|
{/* <div style={{ marginTop: 8 }}>
|
||||||
|
{!noMore && (
|
||||||
|
<Button onClick={loadMore} disabled={loadingMore}>
|
||||||
|
{loadingMore ? '加载中...' : '点击加载更多'}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{noMore && <span>没有更多数据了</span>}
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default InfiniteList
|
105
packages/biz/src/infiniteList/components/SearchCard.tsx
Normal file
105
packages/biz/src/infiniteList/components/SearchCard.tsx
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/**
|
||||||
|
* Created by jiangzhixiong on 2024/04/28
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { forwardRef, useContext, useImperativeHandle } from 'react'
|
||||||
|
import { ConfigProvider, EMPTY_BASE64 } from '@zhst/meta'
|
||||||
|
import { Flex, Image } from 'antd';
|
||||||
|
import './index.less'
|
||||||
|
|
||||||
|
const { ConfigContext } = ConfigProvider
|
||||||
|
|
||||||
|
export interface Idata {
|
||||||
|
id?: string | number;
|
||||||
|
url?: string;
|
||||||
|
sort?: number;
|
||||||
|
title?: string;
|
||||||
|
subtitle?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SearchCardProps extends Idata {
|
||||||
|
prefixCls?: string;
|
||||||
|
data?: Idata
|
||||||
|
width?: string;
|
||||||
|
height?: string;
|
||||||
|
onCreateTxt?: string;
|
||||||
|
onCreate?: (data: any) => void;
|
||||||
|
onAddTxt?: string;
|
||||||
|
onAdd?: (data: any) => void;
|
||||||
|
onRemoveTxt?: string;
|
||||||
|
onRemove?: (data: any) => void;
|
||||||
|
customOptionRender?: React.ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SearchCardRefProps {
|
||||||
|
}
|
||||||
|
|
||||||
|
const SearchCard = forwardRef<SearchCardRefProps, SearchCardProps>((props, ref) => {
|
||||||
|
const {
|
||||||
|
prefixCls: customizePrefixCls,
|
||||||
|
url,
|
||||||
|
id,
|
||||||
|
title,
|
||||||
|
subtitle,
|
||||||
|
sort,
|
||||||
|
data,
|
||||||
|
onCreate,
|
||||||
|
onCreateTxt = '创建检索',
|
||||||
|
onAddTxt = '添加目标',
|
||||||
|
onRemoveTxt = '移除轨迹',
|
||||||
|
onAdd,
|
||||||
|
onRemove,
|
||||||
|
customOptionRender,
|
||||||
|
width = '184px',
|
||||||
|
height = '100%'
|
||||||
|
} = props
|
||||||
|
const { getPrefixCls } = useContext(ConfigContext)
|
||||||
|
const componentName = getPrefixCls('biz-search-card', customizePrefixCls);
|
||||||
|
|
||||||
|
const stopBumble = (e: React.MouseEvent<HTMLAnchorElement, MouseEvent>, fn?: ((data: Idata) => void), data?: Idata) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
fn?.(data!)
|
||||||
|
}
|
||||||
|
|
||||||
|
useImperativeHandle(ref, () => ({
|
||||||
|
|
||||||
|
}))
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={componentName}
|
||||||
|
style={{
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className={`${componentName}-main`}>
|
||||||
|
<i className={`${componentName}-main-num`}>{id || sort}</i>
|
||||||
|
<Image
|
||||||
|
className={`${componentName}-main-img`}
|
||||||
|
src={url || data?.url}
|
||||||
|
height={'240px'}
|
||||||
|
preview={false}
|
||||||
|
fallback={EMPTY_BASE64}
|
||||||
|
/>
|
||||||
|
<Flex align='center' justify='space-between' className={`${componentName}-main-opt`}>
|
||||||
|
{customOptionRender || (
|
||||||
|
<>
|
||||||
|
<a onClick={(e) => stopBumble(e, onCreate, data)}>{onCreateTxt}</a>
|
||||||
|
|
|
||||||
|
<a onClick={(e) => stopBumble(e, onAdd, data)}>{onAddTxt}</a>
|
||||||
|
|
|
||||||
|
<a onClick={(e) => stopBumble(e, onRemove, data)}>{onRemoveTxt}</a>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
</div>
|
||||||
|
<div className={`${componentName}-footer`}>
|
||||||
|
<p className={`${componentName}-footer-tit`}>{title || data?.title}</p>
|
||||||
|
<p className={`${componentName}-footer-subtitle`}>{subtitle || data?.subtitle}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default SearchCard
|
81
packages/biz/src/infiniteList/components/index.less
Normal file
81
packages/biz/src/infiniteList/components/index.less
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
.zhst-biz-search-card {
|
||||||
|
border: 2px solid transparent;
|
||||||
|
transition: .1s ease-in all;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border: 2px solid #09f;
|
||||||
|
|
||||||
|
.zhst-biz-search-card-main-opt {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-main {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&-num {
|
||||||
|
position: absolute;
|
||||||
|
right: 2px;
|
||||||
|
top: 2px;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-style: normal;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
color: rgb(153, 153, 153);
|
||||||
|
background-color: rgba(255, 255, 255, 75%);
|
||||||
|
z-index: 1;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-img {
|
||||||
|
width: 100%;
|
||||||
|
height: 240px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-opt {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
padding: 6px 3px;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
bottom: 0;
|
||||||
|
font-size: 12px;
|
||||||
|
background-color: #09f;
|
||||||
|
color: #fff;
|
||||||
|
box-sizing: border-box;
|
||||||
|
transition: .2s ease-in all;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-footer {
|
||||||
|
padding: 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&-tit {
|
||||||
|
margin: 0;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-subtitle {
|
||||||
|
margin: 0;
|
||||||
|
line-height: 20px;
|
||||||
|
transition: .1s ease-in all;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #09f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
packages/biz/src/infiniteList/components/index.tsx
Normal file
6
packages/biz/src/infiniteList/components/index.tsx
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* Created by jiangzhixiong on 2024/04/28
|
||||||
|
*/
|
||||||
|
|
||||||
|
export { default as SearchCard } from './SearchCard'
|
||||||
|
export type { SearchCardProps, SearchCardRefProps } from './SearchCard'
|
50
packages/biz/src/infiniteList/demo/basic.tsx
Normal file
50
packages/biz/src/infiniteList/demo/basic.tsx
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import { InfiniteList } from '@zhst/biz'
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const [data, setData] = useState([])
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
|
||||||
|
const loadMoreData = () => {
|
||||||
|
if (loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setLoading(true);
|
||||||
|
fetch('https://randomuser.me/api/?results=10&inc=id,key,name,gender,email,nat,picture&noinfo')
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((body) => {
|
||||||
|
let res = body.results.map(o => {
|
||||||
|
return {
|
||||||
|
title: o.name.first,
|
||||||
|
subtitle: o.name.last,
|
||||||
|
url: o.picture.large
|
||||||
|
}
|
||||||
|
})
|
||||||
|
setData([...data, ...res]);
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadMoreData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<InfiniteList
|
||||||
|
loading={loading}
|
||||||
|
loadMore={loadMoreData}
|
||||||
|
height={300}
|
||||||
|
hasMore={data.length < 100}
|
||||||
|
data={data}
|
||||||
|
onItemClick={_data => console.log('item点击:', _data)}
|
||||||
|
searchCardProps={{
|
||||||
|
onAdd: (_data) => console.log('新增', _data),
|
||||||
|
onCreate: (_data) => console.log('创建', _data),
|
||||||
|
onRemove: (_data) => console.log('删除', _data),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
58
packages/biz/src/infiniteList/demo/custom.tsx
Normal file
58
packages/biz/src/infiniteList/demo/custom.tsx
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import { InfiniteList } from '@zhst/biz'
|
||||||
|
import { Button, Input, Space } from 'antd'
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const [data, setData] = useState([])
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [params, setParams] = useState({})
|
||||||
|
|
||||||
|
const loadMoreData = (params?: { name: string; age?: number; sex: string; tel: number }) => {
|
||||||
|
if (loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setLoading(true);
|
||||||
|
fetch('https://randomuser.me/api/?results=10&inc=id,key,name,gender,email,nat,picture&noinfo')
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((body) => {
|
||||||
|
let res = body.results.map(o => {
|
||||||
|
return {
|
||||||
|
title: o.name.first,
|
||||||
|
subtitle: o.name.last,
|
||||||
|
url: o.picture.large
|
||||||
|
}
|
||||||
|
})
|
||||||
|
setData([...data, ...res]);
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadMoreData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Space direction='vertical'>
|
||||||
|
<Space>
|
||||||
|
<Input placeholder='名称' onChange={(e) => setParams(pre => ({ ...pre, name: e.target.value }))} style={{ width: '120px' }} />
|
||||||
|
<Input placeholder='年龄' onChange={(e) => setParams(pre => ({ ...pre, age: e.target.value }))} style={{ width: '120px' }} />
|
||||||
|
<Input placeholder='性别' onChange={(e) => setParams(pre => ({ ...pre, sex: e.target.value }))} style={{ width: '120px' }} />
|
||||||
|
<Input placeholder='手机号' onChange={(e) => setParams(pre => ({ ...pre, tel: e.target.value }))} style={{ width: '120px' }} />
|
||||||
|
<Button onClick={() => loadMoreData(params)}>加载更多</Button>
|
||||||
|
</Space>
|
||||||
|
<InfiniteList
|
||||||
|
loading={loading}
|
||||||
|
loadMore={() => loadMoreData(params)}
|
||||||
|
height={300}
|
||||||
|
hasMore={data.length < 100}
|
||||||
|
data={data}
|
||||||
|
type="custom"
|
||||||
|
loadingMessage={<Button onClick={() => loadMoreData(params)}>加载更多</Button>}
|
||||||
|
onItemClick={data => console.log('item点击:', data)}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
)
|
||||||
|
}
|
72
packages/biz/src/infiniteList/demo/customItem.tsx
Normal file
72
packages/biz/src/infiniteList/demo/customItem.tsx
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import { InfiniteList } from '@zhst/biz'
|
||||||
|
import { Button, Input, Space } from 'antd'
|
||||||
|
|
||||||
|
interface IData { name: string; age?: number; sex: string; tel: number }
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const [data, setData] = useState<any>([])
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [params, setParams] = useState<IData>({
|
||||||
|
name: '',
|
||||||
|
tel: 123,
|
||||||
|
age: 12,
|
||||||
|
sex: '男'
|
||||||
|
})
|
||||||
|
|
||||||
|
const loadMoreData = (params?: IData) => {
|
||||||
|
if (loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setLoading(true);
|
||||||
|
fetch('https://randomuser.me/api/?results=10&inc=id,key,name,gender,email,nat,picture&noinfo', {
|
||||||
|
})
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((body) => {
|
||||||
|
setData([...data, ...body.results]);
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadMoreData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Space direction='vertical'>
|
||||||
|
<Space>
|
||||||
|
<Input placeholder='名称' onChange={(e) => setParams(pre => ({ ...pre, name: e.target.value }))} style={{ width: '120px' }} />
|
||||||
|
<Input placeholder='年龄' onChange={(e) => setParams(pre => ({ ...pre, age: Number(e.target.value) }))} style={{ width: '120px' }} />
|
||||||
|
<Input placeholder='性别' onChange={(e) => setParams(pre => ({ ...pre, sex: e.target.value }))} style={{ width: '120px' }} />
|
||||||
|
<Input placeholder='手机号' onChange={(e) => setParams(pre => ({ ...pre, tel: Number(e.target.value) }))} style={{ width: '120px' }} />
|
||||||
|
<Button onClick={() => loadMoreData(params)}>加载更多</Button>
|
||||||
|
</Space>
|
||||||
|
<InfiniteList
|
||||||
|
loading={loading}
|
||||||
|
loadMore={() => loadMoreData(params)}
|
||||||
|
height={300}
|
||||||
|
hasMore={data.length < 100}
|
||||||
|
data={data}
|
||||||
|
type="custom"
|
||||||
|
loadingMessage={<Button onClick={() => loadMoreData(params)}>加载更多</Button>}
|
||||||
|
itemRender={() => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: '200px',
|
||||||
|
height: '100px',
|
||||||
|
border: '1px solid #000',
|
||||||
|
boxSizing: 'border-box'
|
||||||
|
}}>
|
||||||
|
自定义的子元素
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
onItemClick={data => console.log('item点击:', data)}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
)
|
||||||
|
}
|
17
packages/biz/src/infiniteList/demo/mock.ts
Normal file
17
packages/biz/src/infiniteList/demo/mock.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
const resultData = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13'];
|
||||||
|
|
||||||
|
export function getLoadMoreList(nextId: string | undefined, limit: number): Promise<any> {
|
||||||
|
let start = 0;
|
||||||
|
const end = start + limit;
|
||||||
|
const list = resultData.slice(start, end);
|
||||||
|
const nId = resultData.length >= end ? resultData[end] : undefined;
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve({
|
||||||
|
list,
|
||||||
|
nextId: nId,
|
||||||
|
isNoMore: list.length > 20
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
}
|
5
packages/biz/src/infiniteList/index.less
Normal file
5
packages/biz/src/infiniteList/index.less
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.zhst-biz-infinite-list {
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
38
packages/biz/src/infiniteList/index.md
Normal file
38
packages/biz/src/infiniteList/index.md
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
category: Components
|
||||||
|
title: infiniteList 无限滚动列表
|
||||||
|
toc: content
|
||||||
|
group:
|
||||||
|
title: 数据展示
|
||||||
|
---
|
||||||
|
|
||||||
|
无限滚动列表
|
||||||
|
|
||||||
|
## 代码演示
|
||||||
|
|
||||||
|
<code src="./demo/basic.tsx">基本用法</code>
|
||||||
|
<code src="./demo/custom.tsx">手动触发</code>
|
||||||
|
<code src="./demo/customItem.tsx">自定义子元素</code>
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| data | 数据源 | Idata[] | [] | - |
|
||||||
|
| loading | 数据源 | Array[] | [] | - |
|
||||||
|
| data | 数据源 | Array[] | [] | - |
|
||||||
|
| data | 数据源 | Array[] | [] | - |
|
||||||
|
| data | 数据源 | Array[] | [] | - |
|
||||||
|
| data | 数据源 | Array[] | [] | - |
|
||||||
|
| data | 数据源 | Array[] | [] | - |
|
||||||
|
|
||||||
|
## Idata
|
||||||
|
|
||||||
|
```js
|
||||||
|
interface Idata {
|
||||||
|
id?: string | number;
|
||||||
|
url?: string; // 链接
|
||||||
|
title?: string; // 标题
|
||||||
|
subtitle?: string; // 副标题
|
||||||
|
}
|
||||||
|
```
|
5
packages/biz/src/infiniteList/index.tsx
Normal file
5
packages/biz/src/infiniteList/index.tsx
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import InfinityList from './InfiniteList'
|
||||||
|
|
||||||
|
export type { InfiniteListProps, InfiniteListRefProps } from './InfiniteList'
|
||||||
|
|
||||||
|
export default InfinityList
|
@ -2,6 +2,8 @@ import React, { forwardRef, useContext, useImperativeHandle, useRef } from 'reac
|
|||||||
import { Button, Modal, ModalProps, Select, SelectProps, Space, theme } from 'antd';
|
import { Button, Modal, ModalProps, Select, SelectProps, Space, theme } from 'antd';
|
||||||
import { ConfigProvider, CropperImage, Scanner, CropperImageProps, CropperImageRefProps } from '@zhst/meta'
|
import { ConfigProvider, CropperImage, Scanner, CropperImageProps, CropperImageRefProps } from '@zhst/meta'
|
||||||
import { IconFont } from '@zhst/icon'
|
import { IconFont } from '@zhst/icon'
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import './index.less'
|
||||||
|
|
||||||
export interface ODModalProps extends ModalProps {
|
export interface ODModalProps extends ModalProps {
|
||||||
prefixCls?: string;
|
prefixCls?: string;
|
||||||
@ -95,7 +97,7 @@ const ODModal = forwardRef<ODModalRefProps, ODModalProps>((props, ref) => {
|
|||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
onOk={onOk}
|
onOk={onOk}
|
||||||
{...modalProps}
|
{...modalProps}
|
||||||
className={componentName}
|
rootClassName={componentName}
|
||||||
>
|
>
|
||||||
<Space size={12} direction='vertical' align='center' style={{ textAlign: 'center' }}>
|
<Space size={12} direction='vertical' align='center' style={{ textAlign: 'center' }}>
|
||||||
<Scanner style={{ width: odWidth, height: odHeight }} visible={scanning}>
|
<Scanner style={{ width: odWidth, height: odHeight }} visible={scanning}>
|
||||||
@ -118,7 +120,7 @@ const ODModal = forwardRef<ODModalRefProps, ODModalProps>((props, ref) => {
|
|||||||
<div>
|
<div>
|
||||||
选中类型:
|
选中类型:
|
||||||
<Select
|
<Select
|
||||||
style={{ width: '90px' }}
|
className={classNames(componentName + '-type')}
|
||||||
defaultValue={selectDefaultValue}
|
defaultValue={selectDefaultValue}
|
||||||
value={selectedType}
|
value={selectedType}
|
||||||
options={selectOptions}
|
options={selectOptions}
|
||||||
@ -129,7 +131,7 @@ const ODModal = forwardRef<ODModalRefProps, ODModalProps>((props, ref) => {
|
|||||||
<Button disabled={handSelectDisable} size='small' type="link" onClick={onHandSelect}><IconFont icon="icon-shoudongkuangxuan" /> 手动框选</Button>
|
<Button disabled={handSelectDisable} size='small' type="link" onClick={onHandSelect}><IconFont icon="icon-shoudongkuangxuan" /> 手动框选</Button>
|
||||||
<Button disabled={autoSelectDisable} size='small' type="link" onClick={onAutoSelect}><IconFont icon="icon-zidong" /> 自动框选</Button>
|
<Button disabled={autoSelectDisable} size='small' type="link" onClick={onAutoSelect}><IconFont icon="icon-zidong" /> 自动框选</Button>
|
||||||
<Button disabled={resetDisable} size='small' type="link" onClick={onReset}><IconFont icon="icon-zhongzhi3" /> 重置</Button>
|
<Button disabled={resetDisable} size='small' type="link" onClick={onReset}><IconFont icon="icon-zhongzhi3" /> 重置</Button>
|
||||||
{showRotateButton && <IconFont onIconClick={onRotate} styles={{ marginLeft: '6px' }} color={token.colorPrimary} icon="icon-xuanzhuan1" />}
|
{showRotateButton && <IconFont className={classNames(componentName + '-rotate')} onIconClick={onRotate} color={token.colorPrimary} icon="icon-xuanzhuan1" />}
|
||||||
</Space>
|
</Space>
|
||||||
)}
|
)}
|
||||||
</Space>
|
</Space>
|
||||||
|
@ -69,11 +69,8 @@ const demo = () => {
|
|||||||
autoSelectDisable={paintType === 'auto'}
|
autoSelectDisable={paintType === 'auto'}
|
||||||
onCropEnd={_cropData => console.log('结束绘制:', _cropData)}
|
onCropEnd={_cropData => console.log('结束绘制:', _cropData)}
|
||||||
onReset={() => console.log('重置')}
|
onReset={() => console.log('重置')}
|
||||||
onRotate={() => console.log('旋转', odModalRef.current.rotateTo(90))}
|
onRotate={() => console.log('旋转', odModalRef.current?.rotateTo?.(90))}
|
||||||
onTypeSelect={(val) => {
|
onTypeSelect={(val) => {
|
||||||
if (val === 1) {
|
|
||||||
|
|
||||||
}
|
|
||||||
setSelectedType(val)
|
setSelectedType(val)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
9
packages/biz/src/odModal/index.less
Normal file
9
packages/biz/src/odModal/index.less
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
.zhst-od-modal {
|
||||||
|
&-type {
|
||||||
|
width: 90px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-rotate {
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
import React, { FC, useState } from 'react';
|
import React, { FC, useState } from 'react';
|
||||||
import { Tree, Badge, TreeDataNode, Space, TreeProps } from 'antd';
|
import { Tree, Badge, TreeDataNode, Space, TreeProps, theme } from 'antd';
|
||||||
import theme from 'antd/es/theme'
|
|
||||||
import { CloseOutlined, EditOutlined, SettingOutlined } from '@ant-design/icons'
|
import { CloseOutlined, EditOutlined, SettingOutlined } from '@ant-design/icons'
|
||||||
import { ModalForm, ProFormText } from '@ant-design/pro-components';
|
import { ModalForm, ProFormText } from '@ant-design/pro-components';
|
||||||
import './index.less'
|
import './index.less'
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Button, Card, Flex, Input, InputProps, Tree } from 'antd';
|
import { Button, Card, ConfigProvider, theme, Flex, Input, InputProps, TransferProps, TreeDataNode, TreeProps, Tree } from 'antd';
|
||||||
import theme from 'antd/es/theme'
|
|
||||||
import { TransferProps, TreeDataNode, TreeProps } from 'antd';
|
|
||||||
import './index.less'
|
import './index.less'
|
||||||
import { DeleteOutlined, DoubleRightOutlined, SearchOutlined } from '@ant-design/icons';
|
import { DeleteOutlined, DoubleRightOutlined, SearchOutlined } from '@ant-design/icons';
|
||||||
import { getAllRootKeyById } from './treeTransferHelper';
|
|
||||||
|
|
||||||
const componentName = 'zhst-biz-treeTransfer'
|
const componentName = 'zhst-biz-treeTransfer'
|
||||||
|
|
||||||
@ -16,7 +13,7 @@ export interface TreeTransferProps {
|
|||||||
checkedKeys: string[];
|
checkedKeys: string[];
|
||||||
onTreeSelect?: TreeProps['onSelect']
|
onTreeSelect?: TreeProps['onSelect']
|
||||||
onTreeCheck?: TreeProps['onCheck']
|
onTreeCheck?: TreeProps['onCheck']
|
||||||
onItemDelete?: (key: string, info?: { root: TreeDataNode[], keys: string[] }) => void
|
onItemDelete?: (key: string, info?: TreeDataNode) => void
|
||||||
onChange?: TransferProps['onChange'];
|
onChange?: TransferProps['onChange'];
|
||||||
onOk?: (data: any) => void;
|
onOk?: (data: any) => void;
|
||||||
onReset?: () => void;
|
onReset?: () => void;
|
||||||
@ -56,20 +53,29 @@ const TreeTransfer: React.FC<TreeTransferProps> = ({
|
|||||||
<Card
|
<Card
|
||||||
className={`${componentName}-left_card`}
|
className={`${componentName}-left_card`}
|
||||||
title={<div style={{ textAlign: 'center' }} >可选择的范围</div>}
|
title={<div style={{ textAlign: 'center' }} >可选择的范围</div>}
|
||||||
bodyStyle={{ padding: 12 }}
|
|
||||||
>
|
>
|
||||||
<Input prefix={<SearchOutlined />} onChange={e => setKeyWords(e.target.value)} placeholder='请输入设备名称' {...searchInputProps} />
|
<Input prefix={<SearchOutlined />} onChange={e => setKeyWords(e.target.value)} placeholder='请输入设备名称' {...searchInputProps} />
|
||||||
<Tree
|
<ConfigProvider
|
||||||
style={{ marginTop: '6px' }}
|
theme={{
|
||||||
height={420}
|
components: {
|
||||||
blockNode
|
Tree: {
|
||||||
checkable
|
colorBgContainer: '#FCFCFC'
|
||||||
checkedKeys={checkedKeys}
|
}
|
||||||
treeData={findNodesWithKeyword(keyWords, dataSource)}
|
}
|
||||||
onCheck={(keys, info) => onTreeCheck?.(keys, info)}
|
}}
|
||||||
onSelect={(keys, info) => onTreeSelect?.(keys, info)}
|
>
|
||||||
{...treeProps}
|
<Tree
|
||||||
/>
|
className={`${componentName}-left_card-tree`}
|
||||||
|
height={420}
|
||||||
|
blockNode
|
||||||
|
checkable
|
||||||
|
checkedKeys={checkedKeys}
|
||||||
|
treeData={findNodesWithKeyword(keyWords, dataSource)}
|
||||||
|
onCheck={(keys, info) => onTreeCheck?.(keys, info)}
|
||||||
|
onSelect={(keys, info) => onTreeSelect?.(keys, info)}
|
||||||
|
{...treeProps}
|
||||||
|
/>
|
||||||
|
</ConfigProvider>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
<DoubleRightOutlined/>
|
<DoubleRightOutlined/>
|
||||||
@ -77,8 +83,6 @@ const TreeTransfer: React.FC<TreeTransferProps> = ({
|
|||||||
<Card
|
<Card
|
||||||
className={`${componentName}-right_card`}
|
className={`${componentName}-right_card`}
|
||||||
title={<div style={{ textAlign: 'center' }}>已选择的范围</div>}
|
title={<div style={{ textAlign: 'center' }}>已选择的范围</div>}
|
||||||
bodyStyle={{ padding: 0 }}
|
|
||||||
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`${componentName}-right_card__items`}
|
className={`${componentName}-right_card__items`}
|
||||||
@ -99,8 +103,8 @@ const TreeTransfer: React.FC<TreeTransferProps> = ({
|
|||||||
{item.title as any}
|
{item.title as any}
|
||||||
<div style={{ float: 'right' }}>
|
<div style={{ float: 'right' }}>
|
||||||
<DeleteOutlined onClick={() => {
|
<DeleteOutlined onClick={() => {
|
||||||
const { root, keys } = getAllRootKeyById(item.key as string, dataSource)
|
// const { root, keys } = getAllRootKeyById(item.key as string, dataSource)
|
||||||
onItemDelete?.(item.key as string, { root, keys })
|
onItemDelete?.(item.key as string, item)
|
||||||
}} />
|
}} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,9 +22,9 @@ const App: React.FC = () => {
|
|||||||
* @param key
|
* @param key
|
||||||
* @param param1
|
* @param param1
|
||||||
*/
|
*/
|
||||||
const onItemDelete = (key: any, { keys }: any) => {
|
const onItemDelete = (key: any, { keys = [] }: any) => {
|
||||||
setCheckedKeys(pre => {
|
setCheckedKeys(pre => {
|
||||||
const newKeys = pre.filter(_key => !keys.includes(_key))
|
const newKeys = pre.filter(_key => _key !== key)
|
||||||
console.log('newKeys', newKeys, keys)
|
console.log('newKeys', newKeys, keys)
|
||||||
return newKeys
|
return newKeys
|
||||||
})
|
})
|
||||||
|
@ -25,11 +25,48 @@ export const boxDataSource: TreeDataNode[] = [
|
|||||||
{ key: '0-1-3-3', title: '分组0-1-3-3', isLeaf: true },
|
{ key: '0-1-3-3', title: '分组0-1-3-3', isLeaf: true },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: '0-1-4',
|
||||||
|
title: '分组0-1-4',
|
||||||
|
isLeaf: false,
|
||||||
|
children: [
|
||||||
|
{ key: '0-1-4-1', title: '分组0-1-3-1', isLeaf: true },
|
||||||
|
{ key: '0-1-4-2', title: '分组0-1-3-2', isLeaf: true },
|
||||||
|
{ key: '0-1-4-3', title: '分组0-1-3-3', isLeaf: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '0-1-5',
|
||||||
|
title: '分组0-1-5',
|
||||||
|
isLeaf: false,
|
||||||
|
children: [
|
||||||
|
{ key: '0-1-5-1', title: '分组0-1-3-1', isLeaf: true },
|
||||||
|
{ key: '0-1-5-2', title: '分组0-1-3-2', isLeaf: true },
|
||||||
|
{ key: '0-1-5-3', title: '分组0-1-3-3', isLeaf: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{ key: '0-2', title: '分组0-2', isLeaf: false, checkable: false, },
|
{ key: '0-2', title: '分组0-2', isLeaf: false, checkable: false, },
|
||||||
{ key: '0-3', title: '分组0-3', isLeaf: false, checkable: false, },
|
{ key: '0-3', title: '分组0-3', isLeaf: false, checkable: false, },
|
||||||
{ key: '0-4', title: '分组0-4', isLeaf: false, checkable: false, },
|
{
|
||||||
|
key: '0-4',
|
||||||
|
title: '分组0-4',
|
||||||
|
isLeaf: false,
|
||||||
|
checkable: false,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
key: '0-4-5',
|
||||||
|
title: '分组0-4-5',
|
||||||
|
isLeaf: false,
|
||||||
|
children: [
|
||||||
|
{ key: '0-4-5-1', title: '分组0-1-3-1', isLeaf: true },
|
||||||
|
{ key: '0-4-5-2', title: '分组0-1-3-2', isLeaf: true },
|
||||||
|
{ key: '0-4-5-3', title: '分组0-1-3-3', isLeaf: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
{ key: '0-5', title: '分组0-4', isLeaf: false, checkable: false, },
|
{ key: '0-5', title: '分组0-4', isLeaf: false, checkable: false, },
|
||||||
{ key: '0-6', title: '分组0-4', isLeaf: false, checkable: false, },
|
{ key: '0-6', title: '分组0-4', isLeaf: false, checkable: false, },
|
||||||
];
|
];
|
||||||
|
@ -2,15 +2,19 @@
|
|||||||
&-left {
|
&-left {
|
||||||
&_card {
|
&_card {
|
||||||
width: 500px;
|
width: 500px;
|
||||||
height: 522px;
|
min-height: 544px;
|
||||||
background-color: #FCFCFC;
|
background-color: #FCFCFC;
|
||||||
|
|
||||||
|
&-tree {
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-right {
|
&-right {
|
||||||
&_card {
|
&_card {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
height: 522px;
|
min-height: 544px;
|
||||||
background-color: #FCFCFC;
|
background-color: #FCFCFC;
|
||||||
|
|
||||||
&__items {
|
&__items {
|
||||||
@ -18,6 +22,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc(100% - 105px);
|
height: calc(100% - 105px);
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
max-height: 422px;
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
@ -27,6 +32,7 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 4px 12px;
|
padding: 4px 12px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
transition: 0.3s ease-out all;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React, { FC, useState } from 'react';
|
import React, { FC, useState } from 'react';
|
||||||
import { Modal, ModalProps, Radio, RadioGroupProps, Select, SelectProps, TransferProps, TreeDataNode, TreeProps } from 'antd';
|
import { Modal, ModalProps, Radio, RadioGroupProps, Select, SelectProps, TransferProps, TreeDataNode, TreeProps } from 'antd';
|
||||||
import TreeTransfer from '../treeTransfer';
|
import TreeTransfer from '../treeTransfer';
|
||||||
|
import { TreeTransferProps } from '../treeTransfer'
|
||||||
|
|
||||||
export interface TreeTransferModalProps {
|
export interface TreeTransferModalProps {
|
||||||
dataSource: TreeDataNode[]
|
dataSource: TreeDataNode[]
|
||||||
@ -9,7 +10,7 @@ export interface TreeTransferModalProps {
|
|||||||
checkedKeys: string[];
|
checkedKeys: string[];
|
||||||
onTreeSelect?: TreeProps['onSelect']
|
onTreeSelect?: TreeProps['onSelect']
|
||||||
onTreeCheck?: TreeProps['onCheck']
|
onTreeCheck?: TreeProps['onCheck']
|
||||||
onItemDelete?: (key: string, info?: { root: TreeDataNode[], keys: string[] }) => void
|
onItemDelete?: TreeTransferProps['onItemDelete']
|
||||||
onChange?: TransferProps['onChange'];
|
onChange?: TransferProps['onChange'];
|
||||||
onOk?: (data: any) => void;
|
onOk?: (data: any) => void;
|
||||||
onReset?: () => void;
|
onReset?: () => void;
|
||||||
|
@ -2,11 +2,12 @@ import React, { useState } from 'react';
|
|||||||
import { TreeTransferModal } from '@zhst/biz';
|
import { TreeTransferModal } from '@zhst/biz';
|
||||||
import { Button, TreeDataNode } from 'antd';
|
import { Button, TreeDataNode } from 'antd';
|
||||||
import { TreeProps } from 'antd/lib';
|
import { TreeProps } from 'antd/lib';
|
||||||
import { boxDataSource } from './mock'
|
import { boxDataSource, boxGroupDataSource } from './mock'
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const [targetItems, setTargetItems] = useState<TreeDataNode[]>([]);
|
const [targetItems, setTargetItems] = useState<TreeDataNode[]>([]);
|
||||||
const [checkedKeys, setCheckedKeys] = useState<string[]>([]);
|
const [checkedKeys, setCheckedKeys] = useState<string[]>([]);
|
||||||
|
const [type, setType] = useState<string>('1');
|
||||||
const [open, setOpen] = useState(true)
|
const [open, setOpen] = useState(true)
|
||||||
|
|
||||||
const onTreeCheck: TreeProps['onCheck'] = (keys: any, info) => {
|
const onTreeCheck: TreeProps['onCheck'] = (keys: any, info) => {
|
||||||
@ -47,14 +48,17 @@ const App: React.FC = () => {
|
|||||||
<TreeTransferModal
|
<TreeTransferModal
|
||||||
open={open}
|
open={open}
|
||||||
onCancel={() => setOpen(false)}
|
onCancel={() => setOpen(false)}
|
||||||
onRadioChange={(e) => console.log('radioChange', e)} // 顶部 radio 事件
|
onRadioChange={(e) => setType(e.target.value)} // 顶部 radio 事件
|
||||||
dataSource={boxDataSource} // 数据源
|
dataSource={type === '1' ? boxDataSource : boxGroupDataSource} // 数据源
|
||||||
targetItems={targetItems} // 右侧选中项
|
targetItems={targetItems} // 右侧选中项
|
||||||
checkedKeys={checkedKeys} // 左侧选中
|
checkedKeys={checkedKeys} // 左侧选中
|
||||||
onReset={onReset} // 重置按钮事件
|
onReset={onReset} // 重置按钮事件
|
||||||
onOk={onOk} // 确定按钮事件
|
onOk={onOk} // 确定按钮事件
|
||||||
onTreeCheck={onTreeCheck} // 树check选中事件
|
onTreeCheck={onTreeCheck} // 树check选中事件
|
||||||
onItemDelete={onItemDelete} // 右侧点击删除事件
|
onItemDelete={onItemDelete} // 右侧点击删除事件
|
||||||
|
radioProps={{
|
||||||
|
value: type
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -3,33 +3,74 @@ import { TreeDataNode } from "antd";
|
|||||||
export const boxDataSource: TreeDataNode[] = [
|
export const boxDataSource: TreeDataNode[] = [
|
||||||
{
|
{
|
||||||
key: '0-0',
|
key: '0-0',
|
||||||
title: '分组0-0',
|
title: '全部盒子',
|
||||||
|
value: 0,
|
||||||
|
isLeaf: false,
|
||||||
|
checkable: false,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
key: '0-1',
|
||||||
|
title: '盒子组-1',
|
||||||
|
value: 1,
|
||||||
|
isLeaf: false,
|
||||||
|
children: [
|
||||||
|
{ key: '0-1-0', value: '10', title: '盒子1-0', isLeaf: true, },
|
||||||
|
{ key: '0-1-1', value: '11', title: '盒子1-1', isLeaf: true, },
|
||||||
|
{ key: '0-1-2', value: '12', title: '盒子1-2', isLeaf: true, },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ key: '0-2', value: '2', title: '盒子组-2', isLeaf: false, checkable: false, },
|
||||||
|
{ key: '0-3', value: '3', title: '盒子组-3', isLeaf: false, checkable: false, },
|
||||||
|
{
|
||||||
|
key: '0-4',
|
||||||
|
title: '盒子组-4',
|
||||||
|
value: '4',
|
||||||
|
isLeaf: false,
|
||||||
|
children: [
|
||||||
|
{ key: '0-4-10', value: '10', title: '盒子1-0', isLeaf: true, },
|
||||||
|
{ key: '0-4-11', value: '11', title: '盒子1-1', isLeaf: true, },
|
||||||
|
{ key: '0-4-12', value: '12', title: '盒子1-2', isLeaf: true, },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ key: '0-5', value: '5', title: '盒子组-4', isLeaf: false, checkable: false, },
|
||||||
|
{ key: '0-6', value: '6', title: '盒子组-4', isLeaf: false, checkable: false, },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
export const boxGroupDataSource: TreeDataNode[] = [
|
||||||
|
{
|
||||||
|
key: '0',
|
||||||
|
title: '盒子组-0',
|
||||||
|
value: '0',
|
||||||
isLeaf: false,
|
isLeaf: false,
|
||||||
checkable: false,
|
checkable: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '0-1',
|
key: '1',
|
||||||
title: '分组0-1',
|
value: '1',
|
||||||
|
title: '盒子组-1',
|
||||||
isLeaf: false,
|
isLeaf: false,
|
||||||
children: [
|
children: [
|
||||||
{ key: '0-1-0', title: '分组0-1-0', isLeaf: true, checkable: false },
|
{ key: '0-1-10', value: '10', title: '盒子1-0', isLeaf: true, },
|
||||||
{ key: '0-1-1', title: '分组0-1-1', isLeaf: true, checkable: false },
|
{ key: '0-1-11', value: '11', title: '盒子1-1', isLeaf: true, },
|
||||||
{ key: '0-1-2', title: '分组0-1-2', isLeaf: true, checkable: false },
|
{ key: '0-1-12', value: '12', title: '盒子1-2', isLeaf: true, },
|
||||||
{
|
|
||||||
key: '0-1-3',
|
|
||||||
title: '分组0-1-3',
|
|
||||||
isLeaf: false,
|
|
||||||
children: [
|
|
||||||
{ key: '0-1-3-1', title: '分组0-1-3-1', isLeaf: true },
|
|
||||||
{ key: '0-1-3-2', title: '分组0-1-3-2', isLeaf: true },
|
|
||||||
{ key: '0-1-3-3', title: '分组0-1-3-3', isLeaf: true },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{ key: '0-2', title: '分组0-2', isLeaf: false, checkable: false, },
|
{ key: '2', value: '2', title: '盒子组-2', isLeaf: false, checkable: false, },
|
||||||
{ key: '0-3', title: '分组0-3', isLeaf: false, checkable: false, },
|
{
|
||||||
{ key: '0-4', title: '分组0-4', isLeaf: false, checkable: false, },
|
key: '3',
|
||||||
{ key: '0-5', title: '分组0-4', isLeaf: false, checkable: false, },
|
title: '盒子组-3',
|
||||||
{ key: '0-6', title: '分组0-4', isLeaf: false, checkable: false, },
|
value: '3',
|
||||||
|
isLeaf: false,
|
||||||
|
children: [
|
||||||
|
{ key: '3-10', value: '10', title: '盒子1-0', isLeaf: true, },
|
||||||
|
{ key: '3-11', value: '11', title: '盒子1-1', isLeaf: true, },
|
||||||
|
{ key: '3-12', value: '12', title: '盒子1-2', isLeaf: true, },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ key: '4', value: '4', title: '盒子组-4', isLeaf: false, checkable: false, },
|
||||||
|
{ key: '5', value: '4', title: '盒子组-5', isLeaf: false, checkable: false, },
|
||||||
];
|
];
|
||||||
|
@ -2,7 +2,12 @@ import { defineConfig } from 'father';
|
|||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
||||||
esm: { output: 'es' },
|
esm: {
|
||||||
cjs: { output: 'lib' },
|
output: 'es',
|
||||||
// umd: { output: 'dist' }
|
ignores: ['**/demo/*', 'src/**/demo/*']
|
||||||
|
},
|
||||||
|
cjs: {
|
||||||
|
output: 'lib',
|
||||||
|
ignores: ['**/demo/*', 'src/**/demo/*']
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,94 @@
|
|||||||
# @zhst/utils
|
# @zhst/utils
|
||||||
|
|
||||||
|
## 0.15.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- feat: 修复之前发版错乱问题
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/request@0.15.0
|
||||||
|
|
||||||
|
## 0.14.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- zhst/func: 修改 pxToRem 算法
|
||||||
|
- @zhst/request@0.14.1
|
||||||
|
|
||||||
|
## 0.14.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- feat: 重新发版
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/request@0.14.0
|
||||||
|
|
||||||
|
## 0.13.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- fix: 修复适配问题
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/request@0.13.0
|
||||||
|
|
||||||
|
## 0.12.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- feat: zhst/func 添加 pxToRem 方法
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- @zhst/request@0.12.4
|
||||||
|
|
||||||
|
## 0.11.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/request@0.12.3
|
||||||
|
|
||||||
|
## 0.11.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/request@0.12.2
|
||||||
|
|
||||||
|
## 0.11.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/request@0.12.1
|
||||||
|
|
||||||
|
## 0.11.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- zhst/biz:新增摘要列表-无限滚动组件
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/request@0.12.0
|
||||||
|
|
||||||
|
## 0.10.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/request@0.11.0
|
||||||
|
|
||||||
## 0.10.1
|
## 0.10.1
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
||||||
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
||||||
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
||||||
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
||||||
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
||||||
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
||||||
/**
|
|
||||||
* Created by jiangzhixiong on 2024/03/20
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React, { useState } from 'react';
|
|
||||||
import { getValueByUrl } from '@zhst/func';
|
|
||||||
import { Input, Button, Space } from 'antd';
|
|
||||||
var demo = function demo() {
|
|
||||||
var _useState = useState(null),
|
|
||||||
_useState2 = _slicedToArray(_useState, 2),
|
|
||||||
url = _useState2[0],
|
|
||||||
setUrl = _useState2[1];
|
|
||||||
var _useState3 = useState(null),
|
|
||||||
_useState4 = _slicedToArray(_useState3, 2),
|
|
||||||
keyword = _useState4[0],
|
|
||||||
setKeyword = _useState4[1];
|
|
||||||
var _useState5 = useState(null),
|
|
||||||
_useState6 = _slicedToArray(_useState5, 2),
|
|
||||||
outputVal = _useState6[0],
|
|
||||||
setOutPutVal = _useState6[1];
|
|
||||||
var handleClick = function handleClick() {
|
|
||||||
var val = getValueByUrl(keyword, url);
|
|
||||||
setOutPutVal(val);
|
|
||||||
};
|
|
||||||
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Space, null, "\u94FE\u63A5\uFF1A", /*#__PURE__*/React.createElement(Input, {
|
|
||||||
onChange: function onChange(e) {
|
|
||||||
return setUrl(e.target.value);
|
|
||||||
}
|
|
||||||
}), "\u83B7\u53D6\u5B57\u6BB5\uFF1A", /*#__PURE__*/React.createElement(Input, {
|
|
||||||
onChange: function onChange(e) {
|
|
||||||
return setKeyword(e.target.value);
|
|
||||||
}
|
|
||||||
}), /*#__PURE__*/React.createElement(Button, {
|
|
||||||
onClick: handleClick
|
|
||||||
}, "\u63D0\u4EA4")), /*#__PURE__*/React.createElement("p", null, "\u8F93\u51FA\uFF1A", outputVal));
|
|
||||||
};
|
|
||||||
export default demo;
|
|
@ -71,4 +71,19 @@ export var getValueByUrl = function getValueByUrl(key, str) {
|
|||||||
result = new URLSearchParams(str.indexOf('?') > -1 ? str : "?".concat(str)).get(key);
|
result = new URLSearchParams(str.indexOf('?') > -1 ? str : "?".concat(str)).get(key);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 行内px 转 rem
|
||||||
|
* @param value px像素
|
||||||
|
* @param rootFontSize 根元素大小: 默认16px
|
||||||
|
*/
|
||||||
|
export var pxToRem = function pxToRem(value, rootFontSize) {
|
||||||
|
var fontSize = rootFontSize || 80 || parseFloat(document.documentElement.style.fontSize);
|
||||||
|
var valueArr = value.split(' ');
|
||||||
|
return valueArr.filter(function (o) {
|
||||||
|
return o;
|
||||||
|
}).map(function (val) {
|
||||||
|
return parseFloat(val) / fontSize + 'rem';
|
||||||
|
}).join(' ');
|
||||||
};
|
};
|
@ -1,48 +0,0 @@
|
|||||||
var __create = Object.create;
|
|
||||||
var __defProp = Object.defineProperty;
|
|
||||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
||||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
||||||
var __getProtoOf = Object.getPrototypeOf;
|
|
||||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
||||||
var __export = (target, all) => {
|
|
||||||
for (var name in all)
|
|
||||||
__defProp(target, name, { get: all[name], enumerable: true });
|
|
||||||
};
|
|
||||||
var __copyProps = (to, from, except, desc) => {
|
|
||||||
if (from && typeof from === "object" || typeof from === "function") {
|
|
||||||
for (let key of __getOwnPropNames(from))
|
|
||||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
||||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
||||||
}
|
|
||||||
return to;
|
|
||||||
};
|
|
||||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
||||||
// If the importer is in node compatibility mode or this is not an ESM
|
|
||||||
// file that has been converted to a CommonJS file using a Babel-
|
|
||||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
||||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
||||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
||||||
mod
|
|
||||||
));
|
|
||||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
||||||
|
|
||||||
// src/string/demo/getValueByUrl.tsx
|
|
||||||
var getValueByUrl_exports = {};
|
|
||||||
__export(getValueByUrl_exports, {
|
|
||||||
default: () => getValueByUrl_default
|
|
||||||
});
|
|
||||||
module.exports = __toCommonJS(getValueByUrl_exports);
|
|
||||||
var import_react = __toESM(require("react"));
|
|
||||||
var import_func = require("@zhst/func");
|
|
||||||
var import_antd = require("antd");
|
|
||||||
var demo = () => {
|
|
||||||
const [url, setUrl] = (0, import_react.useState)(null);
|
|
||||||
const [keyword, setKeyword] = (0, import_react.useState)(null);
|
|
||||||
const [outputVal, setOutPutVal] = (0, import_react.useState)(null);
|
|
||||||
const handleClick = () => {
|
|
||||||
let val = (0, import_func.getValueByUrl)(keyword, url);
|
|
||||||
setOutPutVal(val);
|
|
||||||
};
|
|
||||||
return /* @__PURE__ */ import_react.default.createElement("div", null, /* @__PURE__ */ import_react.default.createElement(import_antd.Space, null, "链接:", /* @__PURE__ */ import_react.default.createElement(import_antd.Input, { onChange: (e) => setUrl(e.target.value) }), "获取字段:", /* @__PURE__ */ import_react.default.createElement(import_antd.Input, { onChange: (e) => setKeyword(e.target.value) }), /* @__PURE__ */ import_react.default.createElement(import_antd.Button, { onClick: handleClick }, "提交")), /* @__PURE__ */ import_react.default.createElement("p", null, "输出:", outputVal));
|
|
||||||
};
|
|
||||||
var getValueByUrl_default = demo;
|
|
@ -22,7 +22,8 @@ __export(string_exports, {
|
|||||||
cutStr: () => cutStr,
|
cutStr: () => cutStr,
|
||||||
getStrLength: () => getStrLength,
|
getStrLength: () => getStrLength,
|
||||||
getValueByUrl: () => getValueByUrl,
|
getValueByUrl: () => getValueByUrl,
|
||||||
isUrl: () => isUrl
|
isUrl: () => isUrl,
|
||||||
|
pxToRem: () => pxToRem
|
||||||
});
|
});
|
||||||
module.exports = __toCommonJS(string_exports);
|
module.exports = __toCommonJS(string_exports);
|
||||||
var getStrLength = function(str) {
|
var getStrLength = function(str) {
|
||||||
@ -74,10 +75,16 @@ var getValueByUrl = (key, str) => {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
var pxToRem = (value, rootFontSize) => {
|
||||||
|
const fontSize = rootFontSize || 80;
|
||||||
|
const valueArr = value.split(" ");
|
||||||
|
return valueArr.filter((o) => o).map((val) => parseFloat(val) / fontSize + "rem").join(" ");
|
||||||
|
};
|
||||||
// Annotate the CommonJS export names for ESM import in node:
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
0 && (module.exports = {
|
0 && (module.exports = {
|
||||||
cutStr,
|
cutStr,
|
||||||
getStrLength,
|
getStrLength,
|
||||||
getValueByUrl,
|
getValueByUrl,
|
||||||
isUrl
|
isUrl,
|
||||||
|
pxToRem
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@zhst/func",
|
"name": "@zhst/func",
|
||||||
"version": "0.10.1",
|
"version": "0.15.0",
|
||||||
"description": "函数合集",
|
"description": "函数合集",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"hooks"
|
"hooks"
|
||||||
|
25
packages/func/src/string/demo/pxTorem.tsx
Normal file
25
packages/func/src/string/demo/pxTorem.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Created by jiangzhixiong on 2024/03/20
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { useState } from 'react'
|
||||||
|
import { pxToRem } from '@zhst/func'
|
||||||
|
import { Input } from 'antd'
|
||||||
|
|
||||||
|
const demo = () => {
|
||||||
|
const [outputVal, setOutPutVal ] = useState<any>(null)
|
||||||
|
|
||||||
|
const handleChange = (e: { target: { value: string } }) => {
|
||||||
|
const value = pxToRem(e.target.value)
|
||||||
|
setOutPutVal(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Input onChange={handleChange} />
|
||||||
|
<p>输出:{outputVal}</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default demo
|
131
packages/func/src/string/demo/scale.temp.ts
Normal file
131
packages/func/src/string/demo/scale.temp.ts
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
// !! 参考代码,不投入使用
|
||||||
|
/**
|
||||||
|
* 适应屏幕
|
||||||
|
*/
|
||||||
|
const screenAdapt = () => {
|
||||||
|
window.global = window;
|
||||||
|
(function () {
|
||||||
|
if ($(window).width() >= 1920) {
|
||||||
|
$(window).width() && $('body').css('width', $(window).width());
|
||||||
|
$(window).height() && $('body').css('height', $(window).height());
|
||||||
|
} else {
|
||||||
|
$(window).width() && $('body').css('width', "1920px");
|
||||||
|
|
||||||
|
var ratio = $(window).width() / (1920 || $('body').width());
|
||||||
|
$('body').css({
|
||||||
|
transform: "scale(" + ratio + ")",
|
||||||
|
transformOrigin: "left top",
|
||||||
|
backgroundSize: "100%",
|
||||||
|
height: "1080px"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$('head').append('<meta name="viewport" content=""/>');
|
||||||
|
|
||||||
|
|
||||||
|
//监听页面是否发生改变
|
||||||
|
$(window, document).resize(function () {
|
||||||
|
resize();
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
function resize () {
|
||||||
|
if (window.screen.display == 2) { // 等比缩放高度铺满
|
||||||
|
resizeCenter();
|
||||||
|
} else if (window.screen.display == 3) { //全屏铺满
|
||||||
|
resizeFull();
|
||||||
|
} else if (window.screen.display == 4) { //等比缩放高度铺满并且可以左右移动
|
||||||
|
resizeHeight();
|
||||||
|
} else { // 等比缩放宽度铺满
|
||||||
|
resizeWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
function resizeWidth () {
|
||||||
|
window.location.reload()
|
||||||
|
if ($(window).width() >= 1920) {
|
||||||
|
var ratio = $(window).width() / ($(window).width() || $('body').width());
|
||||||
|
$(window).height() && $('body').css('height', $(window).height());
|
||||||
|
} else {
|
||||||
|
$('body').css('height', "1080px");
|
||||||
|
}
|
||||||
|
var ratio = $(window).width() / (1920 || $('body').width());
|
||||||
|
$('body').css({
|
||||||
|
transform: "scale(" + ratio + ")",
|
||||||
|
transformOrigin: "left top",
|
||||||
|
backgroundSize: "100%"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function resizeCenter () {
|
||||||
|
if (!window.screen.height || !window.screen.width) return resizeCenterBak();
|
||||||
|
var ratio = $(window).height() / window.screen.height;
|
||||||
|
|
||||||
|
|
||||||
|
$('body').css({
|
||||||
|
transform: "scale(" + ratio + ")",
|
||||||
|
transformOrigin: "left top",
|
||||||
|
backgroundSize: 100 * (window.screen.width / $(window).width() * ratio) + "%" + ' 100%',
|
||||||
|
backgroundPosition: ($(window).width() - $('body').width() * ratio) / 2 + "px top",
|
||||||
|
marginLeft: ($(window).width() - $('body').width() * ratio) / 2
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function resizeHeight () { //
|
||||||
|
if (!window.screen.height || !window.screen.width) return resizeCenterBak();
|
||||||
|
var ratio = $(window).height() / window.screen.height;
|
||||||
|
|
||||||
|
|
||||||
|
$('body').css({
|
||||||
|
transform: "scale(" + ratio + ")",
|
||||||
|
transformOrigin: "left top",
|
||||||
|
backgroundSize: 100 * (window.screen.width / $(window).width() * ratio) + "%" + ' 100%',
|
||||||
|
backgroundPosition: ($(window).width() - $('body').width() * ratio) / 2 + "px top",
|
||||||
|
// marginLeft: ($(window).width() - $('body').width() * ratio) / 2
|
||||||
|
});
|
||||||
|
$('html').css({
|
||||||
|
overflowX: 'scroll',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function resizeFull () {
|
||||||
|
if (!window.screen.height || !window.screen.width) return resizeFullBak();
|
||||||
|
var ratioX = $(window).width() / window.screen.width;
|
||||||
|
var ratioY = $(window).height() / window.screen.height;
|
||||||
|
|
||||||
|
$('body').css({
|
||||||
|
transform: "scale(" + ratioX + ", " + ratioY + ")",
|
||||||
|
transformOrigin: "left top",
|
||||||
|
backgroundSize: "100% 100%",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function resizeCenterBak () {
|
||||||
|
var ratioX = $(window).width() / $('body').width();
|
||||||
|
var ratioY = $(window).height() / $('body').height();
|
||||||
|
var ratio = Math.min(ratioX, ratioY);
|
||||||
|
|
||||||
|
|
||||||
|
$('body').css({
|
||||||
|
transform: "scale(" + ratio + ")",
|
||||||
|
transformOrigin: "left top",
|
||||||
|
backgroundSize: (1 / ratioX) * 100 * ratio + "%",
|
||||||
|
backgroundPosition: ($(window).width() - $('body').width() * ratio) / 2 + "px top",
|
||||||
|
marginLeft: ($(window).width() - $('body').width() * ratio) / 2
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function resizeFullBak () {
|
||||||
|
var ratioX = $(window).width() / $('body').width();
|
||||||
|
var ratioY = $(window).height() / $('body').height();
|
||||||
|
|
||||||
|
|
||||||
|
$('body').css({
|
||||||
|
transform: "scale(" + ratioX + ", " + ratioY + ")",
|
||||||
|
transformOrigin: "left top",
|
||||||
|
backgroundSize: "100% " + ratioY * 100 + "%",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
@ -21,3 +21,4 @@ const value3 = getValueByUrl('a', 'a=123&token=asdfasdfsdf')
|
|||||||
```
|
```
|
||||||
|
|
||||||
<code src="./demo/getValueByUrl.tsx">调试台</code>
|
<code src="./demo/getValueByUrl.tsx">调试台</code>
|
||||||
|
<code src="./demo/pxTorem.tsx">px 转 rem</code>
|
||||||
|
@ -78,3 +78,15 @@ export const getValueByUrl = (key: string, str: string) => {
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 行内px 转 rem
|
||||||
|
* @param value px像素
|
||||||
|
* @param rootFontSize 根元素大小: 默认16px
|
||||||
|
*/
|
||||||
|
export const pxToRem = (value: string, rootFontSize?: number) => {
|
||||||
|
const fontSize = rootFontSize || 80 || parseFloat(document.documentElement.style.fontSize)
|
||||||
|
const valueArr = value.split(' ')
|
||||||
|
|
||||||
|
return valueArr.filter(o => o).map(val => ((parseFloat(val) / fontSize) + 'rem')).join(' ')
|
||||||
|
}
|
||||||
|
151
packages/func/src/utils/autoSize.ts
Normal file
151
packages/func/src/utils/autoSize.ts
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
// !! 开发中
|
||||||
|
// 手动添加mate标签
|
||||||
|
const addMeta = (name: string, content: string) => {
|
||||||
|
const meta = document.createElement('meta');
|
||||||
|
meta.content = content;
|
||||||
|
meta.name = name;
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(meta);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const autoResize = (opt: {
|
||||||
|
el: HTMLDivElement
|
||||||
|
targetWidth?: number
|
||||||
|
targetHeight?: number
|
||||||
|
}) => {
|
||||||
|
const { targetHeight = 1080, targetWidth = 1920, el } = opt
|
||||||
|
let targetRatio = targetWidth / targetHeight; // 宽高比率 (宽 / 高) - 默认:16 /9
|
||||||
|
|
||||||
|
// 当前设备(浏览器)的宽度
|
||||||
|
let clientWidth =
|
||||||
|
document.documentElement.clientWidth || document.body.clientWidth;
|
||||||
|
let clientHeight =
|
||||||
|
document.documentElement.clientHeight || document.body.clientHeight;
|
||||||
|
// 当前宽高比例
|
||||||
|
// let currentRatio = clientWidth / clientHeight;
|
||||||
|
|
||||||
|
if (clientWidth >= 1920) {
|
||||||
|
el.style.width = `${clientWidth}px`
|
||||||
|
el.style.height = `${clientHeight}px`
|
||||||
|
} else {
|
||||||
|
el.style.width = '1920px'
|
||||||
|
|
||||||
|
// let currentRatio =
|
||||||
|
}
|
||||||
|
|
||||||
|
addMeta(
|
||||||
|
'viewport',
|
||||||
|
'width=' + clientWidth + ',initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover',
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const resizeWidth = () => {
|
||||||
|
if ($(window).width() >= 1920) {
|
||||||
|
var ratio = $(window).width() / ($(window).width() || $('body').width());
|
||||||
|
$(window).height() && $('body').css('height', $(window).height());
|
||||||
|
} else {
|
||||||
|
$('body').css('height', "1080px");
|
||||||
|
}
|
||||||
|
var ratio = $(window).width() / (1920 || $('body').width());
|
||||||
|
$('body').css({
|
||||||
|
transform: "scale(" + ratio + ")",
|
||||||
|
transformOrigin: "left top",
|
||||||
|
backgroundSize: "100%"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function resizeCenter () {
|
||||||
|
if (!window.screen.height || !window.screen.width) return resizeCenterBak();
|
||||||
|
var ratio = $(window).height() / window.screen.height;
|
||||||
|
|
||||||
|
|
||||||
|
$('body').css({
|
||||||
|
transform: "scale(" + ratio + ")",
|
||||||
|
transformOrigin: "left top",
|
||||||
|
backgroundSize: 100 * (window.screen.width / $(window).width() * ratio) + "%" + ' 100%',
|
||||||
|
backgroundPosition: ($(window).width() - $('body').width() * ratio) / 2 + "px top",
|
||||||
|
marginLeft: ($(window).width() - $('body').width() * ratio) / 2
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function resizeHeight () { //
|
||||||
|
if (!window.screen.height || !window.screen.width) return resizeCenterBak();
|
||||||
|
var ratio = $(window).height() / window.screen.height;
|
||||||
|
|
||||||
|
$('body').css({
|
||||||
|
transform: "scale(" + ratio + ")",
|
||||||
|
transformOrigin: "left top",
|
||||||
|
backgroundSize: 100 * (window.screen.width / $(window).width() * ratio) + "%" + ' 100%',
|
||||||
|
backgroundPosition: ($(window).width() - $('body').width() * ratio) / 2 + "px top",
|
||||||
|
});
|
||||||
|
$('html').css({
|
||||||
|
overflowX: 'scroll',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function resizeFull () {
|
||||||
|
if (!window.screen.height || !window.screen.width) return resizeFullBak();
|
||||||
|
var ratioX = $(window).width() / window.screen.width;
|
||||||
|
var ratioY = $(window).height() / window.screen.height;
|
||||||
|
|
||||||
|
$('body').css({
|
||||||
|
transform: "scale(" + ratioX + ", " + ratioY + ")",
|
||||||
|
transformOrigin: "left top",
|
||||||
|
backgroundSize: "100% 100%",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function resizeCenterBak () {
|
||||||
|
var ratioX = $(window).width() / $('body').width();
|
||||||
|
var ratioY = $(window).height() / $('body').height();
|
||||||
|
var ratio = Math.min(ratioX, ratioY);
|
||||||
|
|
||||||
|
|
||||||
|
$('body').css({
|
||||||
|
transform: "scale(" + ratio + ")",
|
||||||
|
transformOrigin: "left top",
|
||||||
|
backgroundSize: (1 / ratioX) * 100 * ratio + "%",
|
||||||
|
backgroundPosition: ($(window).width() - $('body').width() * ratio) / 2 + "px top",
|
||||||
|
marginLeft: ($(window).width() - $('body').width() * ratio) / 2
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function resizeFullBak () {
|
||||||
|
var ratioX = $(window).width() / $('body').width();
|
||||||
|
var ratioY = $(window).height() / $('body').height();
|
||||||
|
|
||||||
|
|
||||||
|
$('body').css({
|
||||||
|
transform: "scale(" + ratioX + ", " + ratioY + ")",
|
||||||
|
transformOrigin: "left top",
|
||||||
|
backgroundSize: "100% " + ratioY * 100 + "%",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.screen.display === 2) { // 等比缩放高度铺满
|
||||||
|
resizeCenter();
|
||||||
|
} else if (window.screen.display === 3) { //全屏铺满
|
||||||
|
resizeFull();
|
||||||
|
} else if (window.screen.display === 4) { //等比缩放高度铺满并且可以左右移动
|
||||||
|
resizeHeight();
|
||||||
|
} else { // 等比缩放宽度铺满
|
||||||
|
resizeWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// if (currentRatio > targetRatio) {
|
||||||
|
// let scaleRatio = clientHeight / targetHeight; // 参照高度进行缩放(屏幕很宽的情况下)
|
||||||
|
// const transform = `scale(${scaleRatio}) translateX(-50%) left: 50%`;
|
||||||
|
// console.log('transform', transform)
|
||||||
|
// // el.style.transform =
|
||||||
|
// } else {
|
||||||
|
// // 4.开始缩放网页
|
||||||
|
// let scaleRatio = clientWidth / targetWidth; // 参照宽度进行缩放(默认情况下)
|
||||||
|
// console.log('scaleRatio', scaleRatio)
|
||||||
|
// el.style.transform = `scale(${scaleRatio})`;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
export default autoResize
|
@ -2,7 +2,12 @@ import { defineConfig } from 'father';
|
|||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
||||||
esm: { output: 'es' },
|
esm: {
|
||||||
cjs: { output: 'lib' },
|
output: 'es',
|
||||||
// umd: { output: 'dist' }
|
ignores: ['**/demo/*', 'src/**/demo/*']
|
||||||
|
},
|
||||||
|
cjs: {
|
||||||
|
output: 'lib',
|
||||||
|
ignores: ['**/demo/*', 'src/**/demo/*']
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,87 @@
|
|||||||
# @zhst/hooks
|
# @zhst/hooks
|
||||||
|
|
||||||
|
## 0.13.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- feat: 修复之前发版错乱问题
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/func@0.15.0
|
||||||
|
|
||||||
|
## 0.12.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/func@0.14.1
|
||||||
|
|
||||||
|
## 0.12.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- feat: 重新发版
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/func@0.14.0
|
||||||
|
|
||||||
|
## 0.11.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- fix: 修复适配问题
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/func@0.13.0
|
||||||
|
|
||||||
|
## 0.10.4
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/func@0.12.0
|
||||||
|
|
||||||
|
## 0.10.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- @zhst/func@0.11.3
|
||||||
|
|
||||||
|
## 0.10.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- @zhst/func@0.11.2
|
||||||
|
|
||||||
|
## 0.10.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- @zhst/func@0.11.1
|
||||||
|
|
||||||
|
## 0.10.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- zhst/biz:新增摘要列表-无限滚动组件
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/func@0.11.0
|
||||||
|
|
||||||
|
## 0.9.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- @zhst/func@0.10.2
|
||||||
|
|
||||||
## 0.9.1
|
## 0.9.1
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@zhst/hooks",
|
"name": "@zhst/hooks",
|
||||||
"version": "0.9.1",
|
"version": "0.13.0",
|
||||||
"description": "hooks合集",
|
"description": "hooks合集",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"hooks"
|
"hooks"
|
||||||
|
@ -2,6 +2,12 @@ import { defineConfig } from 'father';
|
|||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
||||||
esm: { output: 'es' },
|
esm: {
|
||||||
cjs: { output: 'lib' },
|
output: 'es',
|
||||||
|
ignores: ['**/demo/*', 'src/**/demo/*']
|
||||||
|
},
|
||||||
|
cjs: {
|
||||||
|
output: 'lib',
|
||||||
|
ignores: ['**/demo/*', 'src/**/demo/*']
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,23 @@
|
|||||||
# @zhst/icon
|
# @zhst/icon
|
||||||
|
|
||||||
|
## 0.5.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- feat: 修复之前发版错乱问题
|
||||||
|
|
||||||
|
## 0.4.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- feat: 重新发版
|
||||||
|
|
||||||
|
## 0.3.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- fix: 修复适配问题
|
||||||
|
|
||||||
## 0.2.0
|
## 0.2.0
|
||||||
|
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { IconFont } from '@zhst/icon';
|
|
||||||
var demo = function demo() {
|
|
||||||
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(IconFont, {
|
|
||||||
icon: "icon-daoru1"
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
export default demo;
|
|
@ -1,33 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
var iconJson = require("../font/iconfont.json");
|
|
||||||
import { IconFont } from '@zhst/icon';
|
|
||||||
import "./index.less";
|
|
||||||
import { message } from '@zhst/meta';
|
|
||||||
var demo = function demo() {
|
|
||||||
var iconArr = iconJson['glyphs'];
|
|
||||||
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("ul", {
|
|
||||||
className: 'demo-ul'
|
|
||||||
}, iconArr.map(function (item) {
|
|
||||||
var font_class = item.font_class,
|
|
||||||
name = item.name;
|
|
||||||
var fontName = "icon-".concat(font_class);
|
|
||||||
return /*#__PURE__*/React.createElement("li", {
|
|
||||||
className: 'demo-li'
|
|
||||||
}, /*#__PURE__*/React.createElement(IconFont, {
|
|
||||||
styles: {
|
|
||||||
marginBottom: 20
|
|
||||||
},
|
|
||||||
icon: fontName,
|
|
||||||
size: 32,
|
|
||||||
onIconClick: function onIconClick() {
|
|
||||||
navigator.clipboard.writeText(fontName);
|
|
||||||
message.success("\u590D\u5236".concat(fontName, "\u6210\u529F"));
|
|
||||||
}
|
|
||||||
}), /*#__PURE__*/React.createElement("div", {
|
|
||||||
className: "demo-li-name"
|
|
||||||
}, name), /*#__PURE__*/React.createElement("div", {
|
|
||||||
className: "demo-li-name"
|
|
||||||
}, fontName));
|
|
||||||
})));
|
|
||||||
};
|
|
||||||
export default demo;
|
|
@ -1,20 +0,0 @@
|
|||||||
.demo {
|
|
||||||
&-ul {
|
|
||||||
list-style-type: none;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-li {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
height: 150px;
|
|
||||||
width: 150px;
|
|
||||||
|
|
||||||
&-name {
|
|
||||||
color: #666;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@zhst/icon",
|
"name": "@zhst/icon",
|
||||||
"version": "0.2.0",
|
"version": "0.5.0",
|
||||||
"description": "图标库",
|
"description": "图标库",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"icon",
|
"icon",
|
||||||
|
@ -1,5 +1,253 @@
|
|||||||
# @zhst/material
|
# @zhst/material
|
||||||
|
|
||||||
|
## 0.17.4
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- fix: 修改 zhst/meta
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.20.3
|
||||||
|
- @zhst/biz@0.21.5
|
||||||
|
|
||||||
|
## 0.17.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- zhst/biz、zhst/meta、zhst/material: 修改 od、修改 boxSelectTree
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.20.2
|
||||||
|
- @zhst/biz@0.21.4
|
||||||
|
|
||||||
|
## 0.17.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/biz@0.21.3
|
||||||
|
|
||||||
|
## 0.17.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- fix: 修改 cropperImage 渲染问题
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.20.1
|
||||||
|
- @zhst/biz@0.21.2
|
||||||
|
|
||||||
|
## 0.17.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- fix: cropperImage 透出矩形坐标
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.20.0
|
||||||
|
- @zhst/biz@0.21.1
|
||||||
|
|
||||||
|
## 0.16.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- feat: 修复之前发版错乱问题
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/hooks@0.13.0
|
||||||
|
- @zhst/func@0.15.0
|
||||||
|
- @zhst/meta@0.19.0
|
||||||
|
- @zhst/biz@0.21.0
|
||||||
|
|
||||||
|
## 0.15.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/func@0.14.1
|
||||||
|
- @zhst/biz@0.20.1
|
||||||
|
- @zhst/hooks@0.12.1
|
||||||
|
- @zhst/meta@0.18.1
|
||||||
|
|
||||||
|
## 0.15.0
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/biz@0.19.2
|
||||||
|
|
||||||
|
## 0.14.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/hooks@0.12.0
|
||||||
|
- @zhst/func@0.14.0
|
||||||
|
- @zhst/meta@0.18.0
|
||||||
|
- @zhst/biz@0.20.0
|
||||||
|
|
||||||
|
## 0.14.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- fix: 修复适配问题
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/hooks@0.11.0
|
||||||
|
- @zhst/func@0.13.0
|
||||||
|
- @zhst/meta@0.17.0
|
||||||
|
- @zhst/biz@0.19.0
|
||||||
|
|
||||||
|
## 0.13.4
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/func@0.12.0
|
||||||
|
- @zhst/biz@0.18.8
|
||||||
|
- @zhst/hooks@0.10.4
|
||||||
|
- @zhst/meta@0.16.4
|
||||||
|
|
||||||
|
## 0.13.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- zhst/material: 修改 theme 组件引用方式
|
||||||
|
|
||||||
|
## 0.13.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- zhst/material: 修改 antd 依赖版本
|
||||||
|
|
||||||
|
## 0.13.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- zhst/material: 修复引用 antd/theme 失败
|
||||||
|
|
||||||
|
## 0.13.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- zhst/material: 添加盒子列表加载更多
|
||||||
|
|
||||||
|
## 0.12.7
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- @zhst/func@0.11.3
|
||||||
|
- @zhst/biz@0.18.7
|
||||||
|
- @zhst/hooks@0.10.3
|
||||||
|
- @zhst/meta@0.16.3
|
||||||
|
|
||||||
|
## 0.12.6
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- biz 优化无限滚动组件、boxselectTree 组件;material 修改算法编辑模块
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/biz@0.18.6
|
||||||
|
|
||||||
|
## 0.12.5
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/biz@0.18.5
|
||||||
|
|
||||||
|
## 0.12.4
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/biz@0.18.4
|
||||||
|
|
||||||
|
## 0.12.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/biz@0.18.3
|
||||||
|
|
||||||
|
## 0.12.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- zhst/request 修改报错提示逻辑、zhst/material - 删除算法配置路数
|
||||||
|
- @zhst/func@0.11.2
|
||||||
|
- @zhst/biz@0.18.2
|
||||||
|
- @zhst/hooks@0.10.2
|
||||||
|
- @zhst/meta@0.16.2
|
||||||
|
|
||||||
|
## 0.12.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- @zhst/func@0.11.1
|
||||||
|
- @zhst/biz@0.18.1
|
||||||
|
- @zhst/hooks@0.10.1
|
||||||
|
- @zhst/meta@0.16.1
|
||||||
|
|
||||||
|
## 0.12.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- zhst/biz:新增摘要列表-无限滚动组件
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/hooks@0.10.0
|
||||||
|
- @zhst/func@0.11.0
|
||||||
|
- @zhst/meta@0.16.0
|
||||||
|
- @zhst/biz@0.18.0
|
||||||
|
|
||||||
|
## 0.11.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- 视频添加 OD 框,查看大图首次点击修复
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.15.0
|
||||||
|
- @zhst/biz@0.17.0
|
||||||
|
- @zhst/func@0.10.2
|
||||||
|
- @zhst/hooks@0.9.2
|
||||||
|
|
||||||
|
## 0.10.4
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/biz@0.16.1
|
||||||
|
|
||||||
|
## 0.10.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.14.0
|
||||||
|
- @zhst/biz@0.16.0
|
||||||
|
|
||||||
|
## 0.10.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- material 修改找不到包的问题
|
||||||
|
|
||||||
|
## 0.10.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/biz@0.15.0
|
||||||
|
|
||||||
## 0.10.0
|
## 0.10.0
|
||||||
|
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@zhst/material",
|
"name": "@zhst/material",
|
||||||
"version": "0.10.0",
|
"version": "0.17.4",
|
||||||
"description": "物料库",
|
"description": "物料库",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"business",
|
"business",
|
||||||
@ -43,7 +43,7 @@
|
|||||||
"@zhst/meta": "workspace:^",
|
"@zhst/meta": "workspace:^",
|
||||||
"xterm": "^5.3.0",
|
"xterm": "^5.3.0",
|
||||||
"xterm-addon-fit": "^0.8.0",
|
"xterm-addon-fit": "^0.8.0",
|
||||||
"antd": "^5.14.2",
|
"antd": "^5.12.5",
|
||||||
"classnames": "^2.5.1",
|
"classnames": "^2.5.1",
|
||||||
"rc-util": "^5.38.1"
|
"rc-util": "^5.38.1"
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
import React, { forwardRef } from 'react';
|
import React, { forwardRef, ReactNode, useContext, useImperativeHandle } from 'react';
|
||||||
import { Flex, Image } from "antd";
|
import { Button, Flex, Image } from "antd";
|
||||||
import theme from 'antd/es/theme'
|
import theme from 'antd/es/theme'
|
||||||
import { CropperImage } from '@zhst/meta'
|
import { CropperImage, ConfigProvider } from '@zhst/meta'
|
||||||
import type { CropperImageProps } from '@zhst/meta'
|
import type { CropperImageProps } from '@zhst/meta'
|
||||||
import { AlgorithmConfigImg, ErrorImage } from '../utils/base64Images'
|
import { AlgorithmConfigImg, ErrorImage } from '../utils/base64Images'
|
||||||
import AlgorithmTable from './components/algorithmTable'
|
import AlgorithmTable from './components/algorithmTable'
|
||||||
import TimeTemplateTable from './components/timeTemplateTable';
|
import TimeTemplateTable from './components/timeTemplateTable';
|
||||||
import { AlgorithmTableProps } from './components/algorithmTable/AlgorithmTable';
|
import { AlgorithmTableProps } from './components/algorithmTable/AlgorithmTable';
|
||||||
import { TimeTemplateTableProps } from './components/timeTemplateTable/TimeTemplateTable';
|
import { TimeTemplateTableProps } from './components/timeTemplateTable/TimeTemplateTable';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import './index.less'
|
||||||
|
|
||||||
const { useToken } = theme
|
const { useToken } = theme
|
||||||
|
|
||||||
const Title = (props: any) => <h2 style={{ margin: '18px 16px', fontSize: '14px', color: 'rgba(0, 0, 0, 0.88)' }} >{props.children}</h2>
|
const Title = (props: any) => <h2 style={{ color: 'rgba(0, 0, 0, 0.88)' }} {...props}>{props.children}</h2>
|
||||||
|
|
||||||
export interface AlgorithmConfigProps {
|
export interface AlgorithmConfigProps {
|
||||||
onAddAlgorithm?: () => void
|
onAddAlgorithm?: () => void
|
||||||
@ -49,42 +51,71 @@ export interface AlgorithmConfigProps {
|
|||||||
type: AlgorithmTableProps<any>['tableType']
|
type: AlgorithmTableProps<any>['tableType']
|
||||||
title?:string; // boxList列表的属性名称【点位列表、盒子列表】
|
title?:string; // boxList列表的属性名称【点位列表、盒子列表】
|
||||||
onSelect?: (key: string, info?: any) => void
|
onSelect?: (key: string, info?: any) => void
|
||||||
|
/**
|
||||||
|
* 是否显示/隐藏加载更多按钮
|
||||||
|
*/
|
||||||
|
showLoadMoreButton?: boolean
|
||||||
|
/**
|
||||||
|
* 点击加载更多事件
|
||||||
|
*/
|
||||||
|
onLoadMoreButtonClick?: () => void;
|
||||||
|
/**
|
||||||
|
* 自定义加载更多按钮
|
||||||
|
*/
|
||||||
|
customLoadMoreButton: ReactNode
|
||||||
|
/**
|
||||||
|
* 自定义批量中间文案
|
||||||
|
*/
|
||||||
|
customBatchCenterContent: ReactNode
|
||||||
|
prefixCls?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AlgorithmConfigRef {
|
export interface AlgorithmConfigRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
const AlgorithmConfig = forwardRef<AlgorithmConfigRef, AlgorithmConfigProps>((props) => {
|
const { ConfigContext } = ConfigProvider
|
||||||
|
|
||||||
|
const AlgorithmConfig = forwardRef<AlgorithmConfigRef, AlgorithmConfigProps>((props, ref) => {
|
||||||
const {
|
const {
|
||||||
algorithmTableDataSource = [],
|
algorithmTableDataSource = [],
|
||||||
timeTemplateDataSource = [],
|
timeTemplateDataSource = [],
|
||||||
boxList = [],
|
|
||||||
drawListener,
|
drawListener,
|
||||||
cropperImageProps = {},
|
cropperImageProps = {},
|
||||||
algorithmTableProps,
|
algorithmTableProps,
|
||||||
timeTemplateTableProps,
|
timeTemplateTableProps,
|
||||||
selectedKey,
|
selectedKey,
|
||||||
|
boxList = [],
|
||||||
type = 'multiple',
|
type = 'multiple',
|
||||||
rowKey = 'id',
|
rowKey = 'id',
|
||||||
onSelect, title='盒子名称',
|
onSelect, title='盒子名称',
|
||||||
|
showLoadMoreButton,
|
||||||
|
onLoadMoreButtonClick,
|
||||||
|
customBatchCenterContent,
|
||||||
|
customLoadMoreButton,
|
||||||
|
prefixCls: customizePrefixCls
|
||||||
} = props
|
} = props
|
||||||
|
const { getPrefixCls } = useContext(ConfigContext);
|
||||||
|
const componentName = getPrefixCls('material-algo', customizePrefixCls);
|
||||||
|
|
||||||
const { token } = useToken()
|
const { token } = useToken()
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const { type: cropType } = cropperImageProps
|
const { type: cropType } = cropperImageProps
|
||||||
|
|
||||||
// useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
// }))
|
}))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex style={{ border: `1px solid ${token.colorBorder}`, backgroundColor: token.colorBgBase }}>
|
<Flex className={componentName} style={{ border: `1px solid ${token.colorBorder}`, backgroundColor: token.colorBgBase }}>
|
||||||
<div title={title} style={{ width: '13.9%' }}>
|
<div className={classNames(`${componentName}-left`)} title={title} style={{ position: 'relative', width: '13.9%' }}>
|
||||||
<Title>{title}</Title>
|
<Title className={classNames(`${componentName}-title`)}>{title}</Title>
|
||||||
<div style={{ borderTop: `1px solid ${token.colorBorder}` }}>
|
<div className={classNames(`${componentName}-left-list`)} style={{ borderTop: `1px solid ${token.colorBorder}` }}>
|
||||||
{boxList.map(item => {
|
{boxList.map(item => {
|
||||||
return (
|
return (
|
||||||
<p
|
<p
|
||||||
key={item.id}
|
// @ts-ignore
|
||||||
onClick={() => onSelect?.(item.id, item)}
|
key={item[rowKey]}
|
||||||
|
// @ts-ignore
|
||||||
|
onClick={() => onSelect?.(item[rowKey], item)}
|
||||||
style={{
|
style={{
|
||||||
margin: 0,
|
margin: 0,
|
||||||
padding: `${token.paddingXXS}px ${token.paddingLG}px`,
|
padding: `${token.paddingXXS}px ${token.paddingLG}px`,
|
||||||
@ -93,12 +124,27 @@ const AlgorithmConfig = forwardRef<AlgorithmConfigRef, AlgorithmConfigProps>((pr
|
|||||||
color: selectedKey === item[rowKey] ? token.colorPrimary : token.colorText,
|
color: selectedKey === item[rowKey] ? token.colorPrimary : token.colorText,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
backgroundColor: selectedKey === item[rowKey] ? token.blue1 : token.colorBgBase,
|
backgroundColor: selectedKey === item[rowKey] ? token.blue1 : token.colorBgBase,
|
||||||
transition: '0cancelDraw.2s ease'
|
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>
|
>{item.name}</p>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
{showLoadMoreButton && (
|
||||||
|
<div style={{ width: '100%', padding: '6px', position: 'absolute', left: '0', bottom: '0', boxSizing: 'border-box' }}>
|
||||||
|
{customLoadMoreButton || <Button onClick={onLoadMoreButtonClick} block>加载更多</Button>}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ boxSizing: 'border-box', width: '46.3%', textAlign: 'center', borderLeft: `1px solid ${token.colorBorder}`, borderRight: `1px solid ${token.colorBorder}` }}>
|
<div style={{ boxSizing: 'border-box', width: '46.3%', textAlign: 'center', borderLeft: `1px solid ${token.colorBorder}`, borderRight: `1px solid ${token.colorBorder}` }}>
|
||||||
{/* 单个配置 */}
|
{/* 单个配置 */}
|
||||||
@ -109,7 +155,7 @@ const AlgorithmConfig = forwardRef<AlgorithmConfigRef, AlgorithmConfigProps>((pr
|
|||||||
{...cropperImageProps}
|
{...cropperImageProps}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div style={{ padding: '84px' }}>
|
<div className={classNames(`${componentName}-middle-cont`)}>
|
||||||
<Image
|
<Image
|
||||||
width={'62.5%'}
|
width={'62.5%'}
|
||||||
src={AlgorithmConfigImg}
|
src={AlgorithmConfigImg}
|
||||||
@ -117,19 +163,21 @@ const AlgorithmConfig = forwardRef<AlgorithmConfigRef, AlgorithmConfigProps>((pr
|
|||||||
fallback={ErrorImage}
|
fallback={ErrorImage}
|
||||||
/>
|
/>
|
||||||
<h2>请进行批量配置</h2>
|
<h2>请进行批量配置</h2>
|
||||||
<ul style={{ display: 'inline-block', paddingLeft: 0, width: '51.8%', listStyle: 'none', textAlign: 'left', color: token.colorTextLabel }}>
|
{customBatchCenterContent || (
|
||||||
<li>· 盒子批量配置仅支持同型号盒子;</li>
|
<ul style={{ display: 'inline-block', paddingLeft: 0, width: '51.8%', listStyle: 'none', textAlign: 'left', color: token.colorTextLabel }}>
|
||||||
<li>· 采取覆盖式更新,不保留原有配置,且预警检测框默认全屏范围;</li>
|
<li>· 盒子批量配置仅支持同型号盒子;</li>
|
||||||
<li>· 人流量统计默认检测线为屏幕中央横向线条,且箭头指向下方;</li>
|
<li>· 采取覆盖式更新,不保留原有配置,且预警检测框默认全屏范围;</li>
|
||||||
<li>· 优先选择拉流正常的摄像头。</li>
|
<li>· 人流量统计默认检测线为屏幕中央横向线条,且箭头指向下方;</li>
|
||||||
</ul>
|
<li>· 优先选择拉流正常的摄像头。</li>
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ width: '39.8%' }} >
|
<div style={{ width: '39.8%' }} >
|
||||||
<div>
|
<div>
|
||||||
<Title>时间模板</Title>
|
<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 style={{ padding: `${token.paddingMD}px ${token.paddingSM}px`, borderTop: `1px solid ${token.colorBorder}`, borderBottom: `1px solid ${token.colorBorder}` }}>
|
||||||
<TimeTemplateTable
|
<TimeTemplateTable
|
||||||
dataSource={timeTemplateDataSource}
|
dataSource={timeTemplateDataSource}
|
||||||
@ -138,7 +186,7 @@ const AlgorithmConfig = forwardRef<AlgorithmConfigRef, AlgorithmConfigProps>((pr
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Title>算法应用</Title>
|
<Title className={classNames(`${componentName}-title`)}>算法应用</Title>
|
||||||
<div style={{ padding: `${token.paddingMD}px ${token.paddingSM}px`, borderTop: `1px solid ${token.colorBorder}` }}>
|
<div style={{ padding: `${token.paddingMD}px ${token.paddingSM}px`, borderTop: `1px solid ${token.colorBorder}` }}>
|
||||||
<AlgorithmTable
|
<AlgorithmTable
|
||||||
dataSource={algorithmTableDataSource}
|
dataSource={algorithmTableDataSource}
|
||||||
|
@ -1,16 +1,20 @@
|
|||||||
import React from 'react';
|
import React, { useContext } from 'react';
|
||||||
import { DeleteFilled, EditFilled, ImportOutlined, PlusCircleFilled } from '@ant-design/icons';
|
import { DeleteFilled, EditFilled, ImportOutlined, PlusCircleFilled } from '@ant-design/icons';
|
||||||
import type { ParamsType, ProColumns, ProTableProps } from '@ant-design/pro-components';
|
import type { ParamsType, ProColumns, ProTableProps } from '@ant-design/pro-components';
|
||||||
import {
|
import {
|
||||||
ProTable,
|
ProTable,
|
||||||
} from '@ant-design/pro-components';
|
} from '@ant-design/pro-components';
|
||||||
import { Popconfirm, Select, Space, Switch } from 'antd';
|
import { Popconfirm, Select, Space, Switch } from 'antd';
|
||||||
import theme from 'antd/es/theme';
|
import { ConfigProvider } from '@zhst/meta'
|
||||||
|
import theme from 'antd/es/theme'
|
||||||
import { AnyObject } from 'antd/es/_util/type';
|
import { AnyObject } from 'antd/es/_util/type';
|
||||||
import { SelectProps } from 'antd/lib';
|
import { SelectProps } from 'antd/lib';
|
||||||
import SchemaFormModal from '../schemaFormModal';
|
import SchemaFormModal from '../schemaFormModal';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import './index.less'
|
||||||
|
|
||||||
const { useToken } = theme
|
const { useToken } = theme
|
||||||
|
const { ConfigContext } = ConfigProvider
|
||||||
|
|
||||||
export interface AlgorithmTableProps<DataSource, Params extends ParamsType = ParamsType, ValueType = "text"> extends ProTableProps<DataSource, Params, ValueType> {
|
export interface AlgorithmTableProps<DataSource, Params extends ParamsType = ParamsType, ValueType = "text"> extends ProTableProps<DataSource, Params, ValueType> {
|
||||||
onAddAlgorithm?: (id?: string, record?: any) => void
|
onAddAlgorithm?: (id?: string, record?: any) => void
|
||||||
@ -40,7 +44,11 @@ const AlgorithmTable= <DataSource extends AnyObject = AnyObject>(
|
|||||||
onDraw,
|
onDraw,
|
||||||
tableType = 'multiple',
|
tableType = 'multiple',
|
||||||
sortList = [],
|
sortList = [],
|
||||||
|
prefixCls: customizePrefixCls
|
||||||
} = props
|
} = props
|
||||||
|
const { getPrefixCls } = useContext(ConfigContext);
|
||||||
|
const componentName = getPrefixCls('material-algo-algoTable', customizePrefixCls);
|
||||||
|
|
||||||
|
|
||||||
const { token } = useToken()
|
const { token } = useToken()
|
||||||
|
|
||||||
@ -53,21 +61,21 @@ const AlgorithmTable= <DataSource extends AnyObject = AnyObject>(
|
|||||||
title: '运行周期',
|
title: '运行周期',
|
||||||
dataIndex: 'runCycle',
|
dataIndex: 'runCycle',
|
||||||
valueType: 'select',
|
valueType: 'select',
|
||||||
width: 80,
|
|
||||||
valueEnum: {
|
valueEnum: {
|
||||||
1: { text: '黑夜' },
|
1: { text: '黑夜' },
|
||||||
0: { text: '白天' },
|
0: { text: '白天' },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
title: '算力占用',
|
// title: '算力占用',
|
||||||
dataIndex: 'powerOccupy',
|
// dataIndex: 'powerOccupy',
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
key: 'option',
|
key: 'option',
|
||||||
valueType: 'option',
|
valueType: 'option',
|
||||||
fixed: true,
|
fixed: 'right',
|
||||||
|
width: '120px',
|
||||||
render: (_DOM, record) => [
|
render: (_DOM, record) => [
|
||||||
<Switch value={record.status} onChange={_status => onItemSwitch?.(_status, record.id, 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>,
|
<a onClick={() => onDraw?.(record.id, record)} style={{ display: tableType === 'single' ? 'block' : 'none' }} href="#"><ImportOutlined /></a>,
|
||||||
@ -88,29 +96,34 @@ const AlgorithmTable= <DataSource extends AnyObject = AnyObject>(
|
|||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ProTable<DataSource>
|
<div className={componentName}>
|
||||||
columns={columns}
|
<Space className={classNames(`${componentName}-top`)} size={16}>
|
||||||
bordered
|
<Select
|
||||||
scroll={{ y: 240 }}
|
className={classNames(`${componentName}-top-select`)}
|
||||||
dataSource={[]}
|
value={selectedKey}
|
||||||
headerTitle={(
|
onChange={onSortSelect}
|
||||||
<Space size={16}>
|
options={sortList}
|
||||||
<Select
|
/>
|
||||||
value={selectedKey}
|
<PlusCircleFilled className={classNames(`${componentName}-top-plus`)} onClick={() => onAddAlgorithm?.(selectedKey)} style={{ color: token.colorPrimary, cursor: 'pointer' }} />
|
||||||
style={{ width: 320 }}
|
</Space>
|
||||||
onChange={onSortSelect}
|
<ProTable<DataSource>
|
||||||
options={sortList}
|
columns={columns}
|
||||||
/>
|
bordered
|
||||||
<PlusCircleFilled onClick={() => onAddAlgorithm?.()} style={{ fontSize: '24px', color: token.colorPrimary, cursor: 'pointer' }} />
|
scroll={{ y: 240, x: 600 }}
|
||||||
</Space>
|
dataSource={[]}
|
||||||
)}
|
cardProps={{
|
||||||
toolbar={undefined}
|
bodyStyle: {
|
||||||
rowKey="id"
|
padding: 0
|
||||||
search={false}
|
}
|
||||||
options={false}
|
}}
|
||||||
pagination={false}
|
toolbar={undefined}
|
||||||
{...props}
|
rowKey="id"
|
||||||
/>
|
search={false}
|
||||||
|
options={false}
|
||||||
|
pagination={false}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
.zhst-material-algo-algoTable {
|
||||||
|
&-top {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
|
||||||
|
&-select {
|
||||||
|
width: 320px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-plus {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,11 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type { ParamsType, ProColumns, ProTableProps } from '@ant-design/pro-components';
|
import type { ParamsType, ProColumns, ProTableProps } from '@ant-design/pro-components';
|
||||||
import {
|
import {
|
||||||
ProTable,
|
ProTable,
|
||||||
} from '@ant-design/pro-components';
|
} from '@ant-design/pro-components';
|
||||||
import { InputNumber } from 'antd';
|
|
||||||
import { AnyObject } from 'antd/es/_util/type';
|
import { AnyObject } from 'antd/es/_util/type';
|
||||||
|
import { InputNumber } from 'antd';
|
||||||
|
|
||||||
export interface TimeTemplateTableProps<DataSource, Params extends ParamsType = ParamsType, ValueType = "text"> extends ProTableProps<DataSource, Params, ValueType> {
|
export interface TimeTemplateTableProps<DataSource, Params extends ParamsType = ParamsType, ValueType = "text"> extends ProTableProps<DataSource, Params, ValueType> {
|
||||||
onItemBlur?: (value?: number | string, id?: any, record?: any) => void,
|
onItemBlur?: (value?: number | string, id?: any, record?: any) => void,
|
||||||
@ -31,10 +32,11 @@ const TimeTemplateTable = <DataSource extends AnyObject = AnyObject>(
|
|||||||
title: '布控星期',
|
title: '布控星期',
|
||||||
dataIndex: 'arrangeDay',
|
dataIndex: 'arrangeDay',
|
||||||
},
|
},
|
||||||
{
|
// TODO: 暂时先注释后续在做这个功能
|
||||||
title: '算力占用',
|
// {
|
||||||
dataIndex: 'powerOccupy',
|
// title: '算力占用',
|
||||||
},
|
// dataIndex: 'powerOccupy',
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
title: '配置路数',
|
title: '配置路数',
|
||||||
key: 'option',
|
key: 'option',
|
||||||
@ -46,6 +48,11 @@ const TimeTemplateTable = <DataSource extends AnyObject = AnyObject>(
|
|||||||
return (
|
return (
|
||||||
<ProTable<DataSource>
|
<ProTable<DataSource>
|
||||||
columns={columns}
|
columns={columns}
|
||||||
|
cardProps={{
|
||||||
|
bodyStyle: {
|
||||||
|
padding: 0
|
||||||
|
}
|
||||||
|
}}
|
||||||
bordered
|
bordered
|
||||||
scroll={{ y: 95 }}
|
scroll={{ y: 95 }}
|
||||||
toolbar={undefined}
|
toolbar={undefined}
|
||||||
|
@ -8,7 +8,7 @@ const algorithmTableDataSource: any = []
|
|||||||
const timeTemplateDataSource: any = []
|
const timeTemplateDataSource: any = []
|
||||||
const boxListData: any[] | (() => any[]) = []
|
const boxListData: any[] | (() => any[]) = []
|
||||||
|
|
||||||
for (let i = 0; i < 5; i += 1) {
|
for (let i = 0; i < 100; i += 1) {
|
||||||
algorithmTableDataSource.push({
|
algorithmTableDataSource.push({
|
||||||
id: String(i),
|
id: String(i),
|
||||||
templateName: '算法模板' + (i + 1),
|
templateName: '算法模板' + (i + 1),
|
||||||
|
21
packages/material/src/algorithmConfig/index.less
Normal file
21
packages/material/src/algorithmConfig/index.less
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
.zhst-material-algo {
|
||||||
|
&-title {
|
||||||
|
margin: 18px 16px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-left {
|
||||||
|
&-list {
|
||||||
|
padding-bottom: 36px;
|
||||||
|
max-height: 612px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
box-sizing: 'border-box';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-middle {
|
||||||
|
&-cont {
|
||||||
|
padding: 84px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { AlgorithmConfigModal } from '@zhst/material';
|
import { AlgorithmConfigModal } from '@zhst/material';
|
||||||
|
import { Button } from 'antd';
|
||||||
|
|
||||||
const algorithmTableDataSource: any = []
|
const algorithmTableDataSource: any = []
|
||||||
const timeTemplateDataSource: any = []
|
const timeTemplateDataSource: any = []
|
||||||
@ -26,7 +27,7 @@ for (let i = 0; i < 5; i += 1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const demo = () => {
|
const demo = () => {
|
||||||
const [open, setOpen] = useState(true)
|
const [open, setOpen] = useState(false)
|
||||||
const [algorithmTableList, setAlgorithmTableList] = useState(algorithmTableDataSource)
|
const [algorithmTableList, setAlgorithmTableList] = useState(algorithmTableDataSource)
|
||||||
const [timeTemplateData, setTimeTemplateData] = useState(timeTemplateDataSource)
|
const [timeTemplateData, setTimeTemplateData] = useState(timeTemplateDataSource)
|
||||||
const [boxList, setBoxList] = useState(boxListData)
|
const [boxList, setBoxList] = useState(boxListData)
|
||||||
@ -34,7 +35,8 @@ const demo = () => {
|
|||||||
const [algorithmSelectedKey, setAlgorithmSelectedKey] = useState('1')
|
const [algorithmSelectedKey, setAlgorithmSelectedKey] = useState('1')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ border: '1px solid #ccc', width: '340px', minHeight: '900px' }}>
|
<div>
|
||||||
|
<Button onClick={() => setOpen(true)}>打开</Button>
|
||||||
<AlgorithmConfigModal
|
<AlgorithmConfigModal
|
||||||
title="批量算法设置"
|
title="批量算法设置"
|
||||||
width={1500}
|
width={1500}
|
||||||
|
@ -47,12 +47,12 @@ const Password: FC<PasswordProps> = (props) => {
|
|||||||
<Form.Item
|
<Form.Item
|
||||||
name="rePassword"
|
name="rePassword"
|
||||||
label="确认密码"
|
label="确认密码"
|
||||||
dependencies={['password']}
|
dependencies={['newPassword']}
|
||||||
rules={[
|
rules={[
|
||||||
{ required: true, message: '请再次输入密码!' },
|
{ required: true, message: '请再次输入密码!' },
|
||||||
({ getFieldValue }) => ({
|
({ getFieldValue }) => ({
|
||||||
validator(_, value) {
|
validator(_, value) {
|
||||||
if (!value || getFieldValue('password') === value) {
|
if (!value || getFieldValue('newPassword') === value) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
return Promise.reject(new Error('两次输入的密码不一致!'));
|
return Promise.reject(new Error('两次输入的密码不一致!'));
|
||||||
|
@ -1,5 +1,161 @@
|
|||||||
# @zhst/utils
|
# @zhst/utils
|
||||||
|
|
||||||
|
## 0.20.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- fix: 修改 zhst/meta
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.20.3
|
||||||
|
|
||||||
|
## 0.20.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- zhst/biz、zhst/meta、zhst/material: 修改 od、修改 boxSelectTree
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.20.2
|
||||||
|
|
||||||
|
## 0.20.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- fix: 修改 cropperImage 渲染问题
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.20.1
|
||||||
|
|
||||||
|
## 0.20.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- fix: cropperImage 透出矩形坐标
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.20.0
|
||||||
|
|
||||||
|
## 0.19.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- feat: 修复之前发版错乱问题
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/hooks@0.13.0
|
||||||
|
- @zhst/func@0.15.0
|
||||||
|
- @zhst/icon@0.5.0
|
||||||
|
- @zhst/meta@0.19.0
|
||||||
|
|
||||||
|
## 0.18.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/func@0.14.1
|
||||||
|
- @zhst/hooks@0.12.1
|
||||||
|
- @zhst/meta@0.18.1
|
||||||
|
|
||||||
|
## 0.18.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- feat: 重新发版
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/hooks@0.12.0
|
||||||
|
- @zhst/func@0.14.0
|
||||||
|
- @zhst/icon@0.4.0
|
||||||
|
- @zhst/meta@0.18.0
|
||||||
|
|
||||||
|
## 0.17.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- fix: 修复适配问题
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/hooks@0.11.0
|
||||||
|
- @zhst/func@0.13.0
|
||||||
|
- @zhst/icon@0.3.0
|
||||||
|
- @zhst/meta@0.17.0
|
||||||
|
|
||||||
|
## 0.16.4
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/func@0.12.0
|
||||||
|
- @zhst/hooks@0.10.4
|
||||||
|
- @zhst/meta@0.16.4
|
||||||
|
|
||||||
|
## 0.16.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- @zhst/func@0.11.3
|
||||||
|
- @zhst/hooks@0.10.3
|
||||||
|
- @zhst/meta@0.16.3
|
||||||
|
|
||||||
|
## 0.16.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- @zhst/func@0.11.2
|
||||||
|
- @zhst/hooks@0.10.2
|
||||||
|
- @zhst/meta@0.16.2
|
||||||
|
|
||||||
|
## 0.16.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- @zhst/func@0.11.1
|
||||||
|
- @zhst/hooks@0.10.1
|
||||||
|
- @zhst/meta@0.16.1
|
||||||
|
|
||||||
|
## 0.16.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- zhst/biz:新增摘要列表-无限滚动组件
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/hooks@0.10.0
|
||||||
|
- @zhst/func@0.11.0
|
||||||
|
- @zhst/meta@0.16.0
|
||||||
|
|
||||||
|
## 0.15.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- 视频添加 OD 框,查看大图首次点击修复
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.15.0
|
||||||
|
- @zhst/func@0.10.2
|
||||||
|
- @zhst/hooks@0.9.2
|
||||||
|
|
||||||
|
## 0.14.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- zhst/meta 大图圈选组件点击选不上 bug 修复,attach 遮挡底部框事件阻止修复
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies
|
||||||
|
- @zhst/meta@0.14.0
|
||||||
|
|
||||||
## 0.13.0
|
## 0.13.0
|
||||||
|
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
@ -17,8 +17,7 @@ import React, { useEffect, useState, useRef, useImperativeHandle } from 'react';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { get, pick, isNull, generateImg, dataURLToBlob, getTransforms, addEventListenerWrapper, getFileByRect } from '@zhst/func';
|
import { get, pick, isNull, generateImg, dataURLToBlob, getTransforms, addEventListenerWrapper, getFileByRect } from '@zhst/func';
|
||||||
import Align from 'rc-align';
|
import Align from 'rc-align';
|
||||||
import { Button, Empty } from '..';
|
import { Empty, AttachImage } from '..';
|
||||||
import { IconFont as Icon } from '@zhst/icon';
|
|
||||||
import { Cropper, Viewer, EVENT_VIEWER_TRANSFORM_CHANGE, EVENT_VIEWER_READY, EVENT_CROP_START, EVENT_CROP_END } from "../ImageEditor";
|
import { Cropper, Viewer, EVENT_VIEWER_TRANSFORM_CHANGE, EVENT_VIEWER_READY, EVENT_CROP_START, EVENT_CROP_END } from "../ImageEditor";
|
||||||
import BtnGroup from "./components/BtnGroup";
|
import BtnGroup from "./components/BtnGroup";
|
||||||
import "./index.less";
|
import "./index.less";
|
||||||
@ -480,16 +479,6 @@ export var BigImagePreview = /*#__PURE__*/React.forwardRef(function (props, ref)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================= attact img =========================
|
|
||||||
var _useState17 = useState(0),
|
|
||||||
_useState18 = _slicedToArray(_useState17, 2),
|
|
||||||
selectAttachImgIndex = _useState18[0],
|
|
||||||
setSelectAttachImgIndex = _useState18[1];
|
|
||||||
var _useState19 = useState(false),
|
|
||||||
_useState20 = _slicedToArray(_useState19, 2),
|
|
||||||
isZoomin = _useState20[0],
|
|
||||||
setIsZoomin = _useState20[1];
|
|
||||||
|
|
||||||
// ============================== Ref ===============================
|
// ============================== Ref ===============================
|
||||||
useImperativeHandle(ref, function () {
|
useImperativeHandle(ref, function () {
|
||||||
return {
|
return {
|
||||||
@ -544,46 +533,10 @@ export var BigImagePreview = /*#__PURE__*/React.forwardRef(function (props, ref)
|
|||||||
setShowCrop: setShowCrop,
|
setShowCrop: setShowCrop,
|
||||||
cropType: cropType,
|
cropType: cropType,
|
||||||
selectAlgorithmVersion: selectAlgorithmVersion
|
selectAlgorithmVersion: selectAlgorithmVersion
|
||||||
}))), (attachImg === null || attachImg === void 0 ? void 0 : attachImg.length) && !showCrop && /*#__PURE__*/React.createElement("div", {
|
}))), (attachImg === null || attachImg === void 0 ? void 0 : attachImg.length) && !showCrop && /*#__PURE__*/React.createElement(AttachImage, {
|
||||||
className: classNames("".concat(componentName, "-attach"), isZoomin && "".concat(componentName, "-attach--zoomin"), "".concat(componentName, "-attach--fixed"), isZoomin && "".concat(componentName, "-attach--zoomin--fixed"))
|
showAttachImgLabel: showAttachImgLabel,
|
||||||
}, /*#__PURE__*/React.createElement("div", {
|
data: attachImg
|
||||||
className: classNames("".concat(componentName, "-attach__tab"))
|
}), (showScore || score) && /*#__PURE__*/React.createElement("div", {
|
||||||
}, showAttachImgLabel ? attachImg === null || attachImg === void 0 ? void 0 : attachImg.map(function (_ref6, index) {
|
|
||||||
var label = _ref6.label;
|
|
||||||
return /*#__PURE__*/React.createElement("div", {
|
|
||||||
key: index,
|
|
||||||
className: classNames("".concat(componentName, "-attach__tab-item"), selectAttachImgIndex === index && "".concat(componentName, "-attach__tab-item--select")),
|
|
||||||
onMouseEnter: function onMouseEnter() {
|
|
||||||
setSelectAttachImgIndex(index);
|
|
||||||
}
|
|
||||||
}, label);
|
|
||||||
}) : null), /*#__PURE__*/React.createElement("div", {
|
|
||||||
className: classNames("".concat(componentName, "-attach__scale"))
|
|
||||||
}, /*#__PURE__*/React.createElement(Button, {
|
|
||||||
type: "text"
|
|
||||||
//绝对定位下onClick事件失效采用onMouseDown
|
|
||||||
,
|
|
||||||
onMouseDown: function onMouseDown(e) {
|
|
||||||
//如果是左键执行
|
|
||||||
if (e.button == 0) {
|
|
||||||
setIsZoomin(function (pre) {
|
|
||||||
return !pre;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
style: {
|
|
||||||
color: '#fff'
|
|
||||||
}
|
|
||||||
}, /*#__PURE__*/React.createElement(Icon, {
|
|
||||||
styles: {
|
|
||||||
display: 'flex'
|
|
||||||
},
|
|
||||||
icon: isZoomin ? 'icon-cancle_fullscreen' : 'icon-fullscreen'
|
|
||||||
}))), /*#__PURE__*/React.createElement("img", {
|
|
||||||
draggable: "false",
|
|
||||||
className: classNames("".concat(componentName, "-attach__img"), "".concat(componentName, "-attach__img--fixed")),
|
|
||||||
src: get(attachImg, "".concat(selectAttachImgIndex, ".url"), '')
|
|
||||||
})), (showScore || score) && /*#__PURE__*/React.createElement("div", {
|
|
||||||
style: {
|
style: {
|
||||||
bottom: 20
|
bottom: 20
|
||||||
},
|
},
|
||||||
|
@ -101,8 +101,7 @@ var CompareImage = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
type: "primary",
|
type: "primary",
|
||||||
shape: "circle",
|
shape: "circle",
|
||||||
style: {
|
style: {
|
||||||
width: '56px',
|
width: '56px'
|
||||||
height: '56px'
|
|
||||||
},
|
},
|
||||||
icon: /*#__PURE__*/React.createElement(IconFont, {
|
icon: /*#__PURE__*/React.createElement(IconFont, {
|
||||||
icon: "icon-qiehuanzuo",
|
icon: "icon-qiehuanzuo",
|
||||||
@ -116,8 +115,7 @@ var CompareImage = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
type: "primary",
|
type: "primary",
|
||||||
shape: "circle",
|
shape: "circle",
|
||||||
style: {
|
style: {
|
||||||
width: '56px',
|
width: '56px'
|
||||||
height: '56px'
|
|
||||||
},
|
},
|
||||||
icon: /*#__PURE__*/React.createElement(IconFont, {
|
icon: /*#__PURE__*/React.createElement(IconFont, {
|
||||||
icon: "icon-qiehuanyou",
|
icon: "icon-qiehuanyou",
|
||||||
|
@ -123,6 +123,8 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
&__btn {
|
&__btn {
|
||||||
|
width: 56px;
|
||||||
|
height: 56px;
|
||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
|
|
||||||
|
@ -30,31 +30,32 @@ export default {
|
|||||||
_this$eventHandleList = this.eventHandleList,
|
_this$eventHandleList = this.eventHandleList,
|
||||||
eventHandleList = _this$eventHandleList === void 0 ? [] : _this$eventHandleList,
|
eventHandleList = _this$eventHandleList === void 0 ? [] : _this$eventHandleList,
|
||||||
options = this.options;
|
options = this.options;
|
||||||
//图片事件
|
// 鼠标滚轮事件
|
||||||
var scaleAble = get(options, 'scaleAble', true);
|
var scaleAble = get(options, 'scaleAble', true);
|
||||||
if (scaleAble) {
|
if (scaleAble) {
|
||||||
var handleWhele = addEventListenerWrapper(canvas, EVENT_WHEEL, this.onWheel.bind(this));
|
var handleWheel = addEventListenerWrapper(canvas, EVENT_WHEEL, this.onWheel.bind(this));
|
||||||
eventHandleList.push(handleWhele);
|
eventHandleList.push(handleWheel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 鼠标 - 拖拽事件
|
||||||
var dragAble = get(options, 'dragAble', true);
|
var dragAble = get(options, 'dragAble', true);
|
||||||
if (dragAble) {
|
if (dragAble) {
|
||||||
var handleDragStart = addEventListenerWrapper(canvas, EVENT_POINTER_DOWN, this.onDragStart.bind(this));
|
var handleDragStart = addEventListenerWrapper(canvas, EVENT_POINTER_DOWN, this.onDragStart.bind(this));
|
||||||
eventHandleList.push(addEventListenerWrapper);
|
eventHandleList.push(handleDragStart);
|
||||||
var handleDragMove = addEventListenerWrapper(element.ownerDocument, EVENT_POINTER_MOVE, this.onDragMove.bind(this));
|
var handleDragMove = addEventListenerWrapper(element.ownerDocument, EVENT_POINTER_MOVE, this.onDragMove.bind(this));
|
||||||
eventHandleList.push(handleDragMove);
|
eventHandleList.push(handleDragMove);
|
||||||
EVENT_POINTER_UP.trim().split(REGEXP_SPACES).forEach(function (eventName) {
|
EVENT_POINTER_UP.trim().split(REGEXP_SPACES).forEach(function (_eventName) {
|
||||||
var handleDragEnd = addEventListenerWrapper(element.ownerDocument, eventName, _this.onDragEnd.bind(_this));
|
var handleDragEnd = addEventListenerWrapper(element.ownerDocument, _eventName, _this.onDragEnd.bind(_this));
|
||||||
eventHandleList.push(handleDragEnd);
|
eventHandleList.push(handleDragEnd);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//rect事件
|
// 鼠标 - 点击事件
|
||||||
var handleClick = addEventListenerWrapper(canvas, EVENT_CLICK, this.onClick.bind(this));
|
var selectAble = get(options, 'selectAble', true);
|
||||||
eventHandleList.push(handleClick);
|
if (selectAble) {
|
||||||
// const handleLeveal = addEventListenerWrapper(canvas, EVENT_LEAVEL, this.onLeavel.bind(this));
|
var handleClick = addEventListenerWrapper(canvas, EVENT_CLICK, this.onClick.bind(this));
|
||||||
// eventHandleList.push(handleLeveal);
|
eventHandleList.push(handleClick);
|
||||||
// const handleEnter = addEventListenerWrapper(canvas, EVENT_ENTER, this.onEnter.bind(this));
|
}
|
||||||
// eventHandleList.push(handleEnter);
|
|
||||||
},
|
},
|
||||||
unbind: function unbind() {
|
unbind: function unbind() {
|
||||||
var eventHandleList = this.eventHandleList;
|
var eventHandleList = this.eventHandleList;
|
||||||
@ -67,7 +68,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/* 图片事件 */onWheel: function onWheel(event, cropBox) {
|
/* 鼠标滚轮事件 */onWheel: function onWheel(event, cropBox) {
|
||||||
var _this2 = this;
|
var _this2 = this;
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -97,6 +98,7 @@ export default {
|
|||||||
})
|
})
|
||||||
}, cropBox);
|
}, cropBox);
|
||||||
},
|
},
|
||||||
|
// 鼠标拖拽 - 开始拖拽
|
||||||
onDragStart: function onDragStart(event) {
|
onDragStart: function onDragStart(event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
// This line is required for preventing page zooming in iOS browsers
|
// This line is required for preventing page zooming in iOS browsers
|
||||||
@ -119,6 +121,7 @@ export default {
|
|||||||
this.action = ACTION_DRAG;
|
this.action = ACTION_DRAG;
|
||||||
addClass(this.canvas, CLASS_MOVE);
|
addClass(this.canvas, CLASS_MOVE);
|
||||||
},
|
},
|
||||||
|
// 鼠标拖拽 - 拖拽中
|
||||||
onDragMove: function onDragMove(event) {
|
onDragMove: function onDragMove(event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
@ -147,6 +150,7 @@ export default {
|
|||||||
this.pointer.startX = this.pointer.endX;
|
this.pointer.startX = this.pointer.endX;
|
||||||
this.pointer.startY = this.pointer.endY;
|
this.pointer.startY = this.pointer.endY;
|
||||||
},
|
},
|
||||||
|
// 鼠标拖拽 - 停止拖拽
|
||||||
onDragEnd: function onDragEnd(event) {
|
onDragEnd: function onDragEnd(event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
var action = this.action;
|
var action = this.action;
|
||||||
@ -158,14 +162,7 @@ export default {
|
|||||||
this.point = null;
|
this.point = null;
|
||||||
removeClass(this.canvas, CLASS_MOVE);
|
removeClass(this.canvas, CLASS_MOVE);
|
||||||
},
|
},
|
||||||
/* rect事件 */
|
// 鼠标点击
|
||||||
// onLeavel(event) {
|
|
||||||
// const pointerCenter = this.windowToCanvasAxis(event);
|
|
||||||
// this.highlightShape(pointerCenter);
|
|
||||||
// },
|
|
||||||
// onEnter(event) {
|
|
||||||
// this.highlightShape(null);
|
|
||||||
// },
|
|
||||||
onClick: function onClick(event) {
|
onClick: function onClick(event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
var pointerCenter = this.windowToCanvasAxis(event);
|
var pointerCenter = this.windowToCanvasAxis(event);
|
||||||
|
@ -13,7 +13,12 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|||||||
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
||||||
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
||||||
//@ts-nocheck
|
//@ts-nocheck
|
||||||
|
import * as turf from '@turf/turf';
|
||||||
import { AXIS_TYPE_ORIGIN, AXIS_TYPE_CANVAS, AXIS_TYPE_IMAGE } from "./constants";
|
import { AXIS_TYPE_ORIGIN, AXIS_TYPE_CANVAS, AXIS_TYPE_IMAGE } from "./constants";
|
||||||
|
export function rectToPolygon(axisRect) {
|
||||||
|
var polygon = turf.polygon([[[setNumberAccuracy(axisRect.x, -2), setNumberAccuracy(axisRect.y, -2)], [setNumberAccuracy(axisRect.x2, -2), setNumberAccuracy(axisRect.y, -2)], [setNumberAccuracy(axisRect.x2, -2), setNumberAccuracy(axisRect.y2, -2)], [setNumberAccuracy(axisRect.x, -2), setNumberAccuracy(axisRect.y2, -2)], [setNumberAccuracy(axisRect.x, -2), setNumberAccuracy(axisRect.y, -2)]]]);
|
||||||
|
return polygon;
|
||||||
|
}
|
||||||
|
|
||||||
//设置数据的精度
|
//设置数据的精度
|
||||||
//accuracy 表示精度 以原点为中心向左为正,向右为负,
|
//accuracy 表示精度 以原点为中心向左为正,向右为负,
|
||||||
@ -42,17 +47,14 @@ export default {
|
|||||||
targetTransform: {
|
targetTransform: {
|
||||||
translateX: 0,
|
translateX: 0,
|
||||||
translateY: 0,
|
translateY: 0,
|
||||||
scale: 0,
|
scale: 1,
|
||||||
rotate: 0
|
rotate: 0
|
||||||
// rotate: 90,
|
// rotate: 90,
|
||||||
},
|
},
|
||||||
windowToCanvasAxis: function windowToCanvasAxis(event) {
|
windowToCanvasAxis: function windowToCanvasAxis(event) {
|
||||||
var _this$canvas$getBound = this.canvas.getBoundingClientRect(),
|
|
||||||
x = _this$canvas$getBound.x,
|
|
||||||
y = _this$canvas$getBound.y;
|
|
||||||
return {
|
return {
|
||||||
x: event.pageX - x,
|
x: event.offsetX,
|
||||||
y: event.pageY - y,
|
y: event.offsetY,
|
||||||
__AXIS_TYPE__: AXIS_TYPE_CANVAS
|
__AXIS_TYPE__: AXIS_TYPE_CANVAS
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -76,7 +78,8 @@ export default {
|
|||||||
var targetTransform = this.targetTransform;
|
var targetTransform = this.targetTransform;
|
||||||
var translateX = targetTransform.translateX,
|
var translateX = targetTransform.translateX,
|
||||||
translateY = targetTransform.translateY,
|
translateY = targetTransform.translateY,
|
||||||
scale = targetTransform.scale;
|
_targetTransform$scal = targetTransform.scale,
|
||||||
|
scale = _targetTransform$scal === void 0 ? 1 : _targetTransform$scal;
|
||||||
var axis = _objectSpread(_objectSpread({
|
var axis = _objectSpread(_objectSpread({
|
||||||
x: translateX + x * scale,
|
x: translateX + x * scale,
|
||||||
y: translateY + y * scale
|
y: translateY + y * scale
|
||||||
|
@ -75,7 +75,14 @@ var Viewer = (_dec = Mixin(Render, Event, Shape, Helper), _dec(_class = /*#__PUR
|
|||||||
}, {
|
}, {
|
||||||
key: "build",
|
key: "build",
|
||||||
value: function build() {
|
value: function build() {
|
||||||
|
var _this$options = this.options,
|
||||||
|
_this$options$width = _this$options.width,
|
||||||
|
width = _this$options$width === void 0 ? 300 : _this$options$width,
|
||||||
|
_this$options$height = _this$options.height,
|
||||||
|
height = _this$options$height === void 0 ? 150 : _this$options$height;
|
||||||
var canvas = document.createElement('canvas');
|
var canvas = document.createElement('canvas');
|
||||||
|
canvas.width = width || canvas.width;
|
||||||
|
canvas.height = height || canvas.height;
|
||||||
addClass(canvas, CLASS_CANVAS);
|
addClass(canvas, CLASS_CANVAS);
|
||||||
this.element.appendChild(canvas);
|
this.element.appendChild(canvas);
|
||||||
this.canvas = canvas;
|
this.canvas = canvas;
|
||||||
|
@ -65,7 +65,6 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
initCanvas: function initCanvas() {
|
initCanvas: function initCanvas() {
|
||||||
if (!this.image) return;
|
|
||||||
//通过样式设置 不依赖父元素的prosition
|
//通过样式设置 不依赖父元素的prosition
|
||||||
var element = this.element,
|
var element = this.element,
|
||||||
canvas = this.canvas,
|
canvas = this.canvas,
|
||||||
@ -83,7 +82,7 @@ export default {
|
|||||||
var fitTransform = this.calcFitScreen();
|
var fitTransform = this.calcFitScreen();
|
||||||
this.targetTransform = Object.assign({}, this.targetTransform, fitTransform);
|
this.targetTransform = Object.assign({}, this.targetTransform, fitTransform);
|
||||||
dispatchEvent(this.element, EVENT_VIEWER_TRANSFORM_CHANGE, cloneDeep(this.targetTransform));
|
dispatchEvent(this.element, EVENT_VIEWER_TRANSFORM_CHANGE, cloneDeep(this.targetTransform));
|
||||||
//产品需求:fitscale 是minscale
|
//产品需求:fitscale 是 minscale
|
||||||
var _options$fitScaleAsMi = options.fitScaleAsMinScale,
|
var _options$fitScaleAsMi = options.fitScaleAsMinScale,
|
||||||
fitScaleAsMinScale = _options$fitScaleAsMi === void 0 ? false : _options$fitScaleAsMi;
|
fitScaleAsMinScale = _options$fitScaleAsMi === void 0 ? false : _options$fitScaleAsMi;
|
||||||
if (fitScaleAsMinScale) {
|
if (fitScaleAsMinScale) {
|
||||||
@ -106,8 +105,9 @@ export default {
|
|||||||
};
|
};
|
||||||
loop();
|
loop();
|
||||||
},
|
},
|
||||||
|
// 绘制画布
|
||||||
renderCanvas: function renderCanvas(_ctx) {
|
renderCanvas: function renderCanvas(_ctx) {
|
||||||
if (!this.image || !this.canvas) return;
|
if (!this.canvas) return;
|
||||||
var containerData = this.containerData,
|
var containerData = this.containerData,
|
||||||
canvas = this.canvas,
|
canvas = this.canvas,
|
||||||
targetTransform = this.targetTransform,
|
targetTransform = this.targetTransform,
|
||||||
@ -128,14 +128,14 @@ export default {
|
|||||||
ctx.setTransform(scale, 0, 0, scale, translateX, translateY);
|
ctx.setTransform(scale, 0, 0, scale, translateX, translateY);
|
||||||
// ctx.setTransform(scale, 0, 0, scale, translateX, translateY);
|
// ctx.setTransform(scale, 0, 0, scale, translateX, translateY);
|
||||||
//旋转
|
//旋转
|
||||||
var centerX = this.image.width / 2;
|
var centerX = this.image ? this.image.width / 2 : canvas.width;
|
||||||
var centerY = this.image.height / 2;
|
var centerY = this.image ? this.image.height / 2 : canvas.height;
|
||||||
ctx.translate(centerX, centerY);
|
ctx.translate(centerX, centerY);
|
||||||
ctx.rotate(rotate / 180 * Math.PI);
|
ctx.rotate(rotate / 180 * Math.PI);
|
||||||
ctx.translate(-centerX, -centerY);
|
ctx.translate(-centerX, -centerY);
|
||||||
|
|
||||||
//图片
|
//图片
|
||||||
ctx.drawImage(this.image, 0, 0);
|
this.image && ctx.drawImage(this.image, 0, 0);
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
//画图形
|
//画图形
|
||||||
ctx.save();
|
ctx.save();
|
||||||
|
@ -14,13 +14,9 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|||||||
import { isNil, isArray, isFunction } from '@zhst/func';
|
import { isNil, isArray, isFunction } from '@zhst/func';
|
||||||
import * as turf from '@turf/turf';
|
import * as turf from '@turf/turf';
|
||||||
import booleanPointInPolygon from '@turf/boolean-point-in-polygon';
|
import booleanPointInPolygon from '@turf/boolean-point-in-polygon';
|
||||||
import { setNumberAccuracy } from "./helper";
|
import { rectToPolygon } from "./helper";
|
||||||
import { SHAPE_TYPE_RECT, SHAPE_TYPE_CIRCLE, EVENT_SHAPE_SELECT } from "./constants";
|
import { SHAPE_TYPE_RECT, SHAPE_TYPE_CIRCLE, EVENT_SHAPE_SELECT } from "./constants";
|
||||||
import { dispatchEvent } from "../utils";
|
import { dispatchEvent } from "../utils";
|
||||||
function rectToPolygon(axisRect) {
|
|
||||||
var polygon = turf.polygon([[[setNumberAccuracy(axisRect.x, -2), setNumberAccuracy(axisRect.y, -2)], [setNumberAccuracy(axisRect.x2, -2), setNumberAccuracy(axisRect.y, -2)], [setNumberAccuracy(axisRect.x2, -2), setNumberAccuracy(axisRect.y2, -2)], [setNumberAccuracy(axisRect.x, -2), setNumberAccuracy(axisRect.y2, -2)], [setNumberAccuracy(axisRect.x, -2), setNumberAccuracy(axisRect.y, -2)]]]);
|
|
||||||
return polygon;
|
|
||||||
}
|
|
||||||
export default {
|
export default {
|
||||||
//store
|
//store
|
||||||
shapeList: [],
|
shapeList: [],
|
||||||
@ -47,20 +43,20 @@ export default {
|
|||||||
this.changeZoonAble(true);
|
this.changeZoonAble(true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//method
|
//method:添加矩形
|
||||||
addShape: function addShape(shap) {
|
addShape: function addShape(shape) {
|
||||||
var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : SHAPE_TYPE_RECT;
|
var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : SHAPE_TYPE_RECT;
|
||||||
this.color = shap.color ? shap.color : '';
|
this.color = shape.color ? shape.color : '';
|
||||||
if (isNil(shap) || this.disableAdd) return;
|
if (isNil(shape) || this.disableAdd) return;
|
||||||
var _this$shapeList = this.shapeList,
|
var _this$shapeList = this.shapeList,
|
||||||
preShapeList = _this$shapeList === void 0 ? [] : _this$shapeList;
|
preShapeList = _this$shapeList === void 0 ? [] : _this$shapeList;
|
||||||
var shapList = isArray(shap) ? shap : [shap];
|
var _shapeList = isArray(shape) ? shape : [shape];
|
||||||
shapList = shapList.map(function (v) {
|
_shapeList = _shapeList.map(function (v) {
|
||||||
return _objectSpread(_objectSpread({}, v), {}, {
|
return _objectSpread(_objectSpread({}, v), {}, {
|
||||||
__SHAPE_TYPE__: type
|
__SHAPE_TYPE__: type
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.shapeList = [].concat(_toConsumableArray(preShapeList), _toConsumableArray(shapList));
|
this.shapeList = [].concat(_toConsumableArray(preShapeList), _toConsumableArray(_shapeList));
|
||||||
},
|
},
|
||||||
//
|
//
|
||||||
setSelectShapId: function setSelectShapId(id) {
|
setSelectShapId: function setSelectShapId(id) {
|
||||||
@ -214,9 +210,12 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 绘制矩形
|
||||||
renderRect: function renderRect(ctx, shape, type) {
|
renderRect: function renderRect(ctx, shape, type) {
|
||||||
//算rect
|
//算rect
|
||||||
var axisRect = this.imgRectAxisToCanvasAxisRect(shape);
|
var axisRect = this.imgRectAxisToCanvasAxisRect(_objectSpread(_objectSpread({}, shape), {}, {
|
||||||
|
image: ctx.canvas
|
||||||
|
}));
|
||||||
var rect = {
|
var rect = {
|
||||||
x: axisRect.x2 > axisRect.x ? axisRect.x : axisRect.x2,
|
x: axisRect.x2 > axisRect.x ? axisRect.x : axisRect.x2,
|
||||||
y: axisRect.y2 > axisRect.y ? axisRect.y : axisRect.y2,
|
y: axisRect.y2 > axisRect.y ? axisRect.y : axisRect.y2,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
||||||
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
||||||
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
||||||
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
||||||
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||||
@ -18,15 +19,14 @@ import { noop, get, addEventListenerWrapper, dataURLToBlob, nextTick, toRealNumb
|
|||||||
import Align from 'rc-align';
|
import Align from 'rc-align';
|
||||||
import { useLatest, useUpdateEffect, useFullscreen, useUnmount } from '@zhst/hooks';
|
import { useLatest, useUpdateEffect, useFullscreen, useUnmount } from '@zhst/hooks';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import download from 'downloadjs';
|
import { message } from '..';
|
||||||
import { Button, message } from '..';
|
|
||||||
import { IconFont } from '@zhst/icon';
|
import { IconFont } from '@zhst/icon';
|
||||||
import { Cropper, EVENT_CROP_START, EVENT_CROP_END } from "../ImageEditor";
|
import { Cropper, EVENT_CROP_START, EVENT_CROP_END, Viewer } from "../ImageEditor";
|
||||||
import FlvPlayer, { FLV_EVENT } from "./components/FlvPlayer";
|
import FlvPlayer, { FLV_EVENT } from "./components/FlvPlayer";
|
||||||
import Range from "./components/Progress";
|
import Range from "./components/Progress";
|
||||||
import Loading from "./components/Loading";
|
import Loading from "./components/Loading";
|
||||||
import { CROP_TYPE } from "../utils/constants";
|
import { CROP_TYPE } from "../utils/constants";
|
||||||
import { getShowStatus } from "./videoPlayerHelper";
|
import { downloadFrame, getShowStatus } from "./videoPlayerHelper";
|
||||||
import "./index.less";
|
import "./index.less";
|
||||||
var componentName = "zhst-image__video-view";
|
var componentName = "zhst-image__video-view";
|
||||||
var VideoPlayer = /*#__PURE__*/forwardRef(function (props, ref) {
|
var VideoPlayer = /*#__PURE__*/forwardRef(function (props, ref) {
|
||||||
@ -42,6 +42,16 @@ var VideoPlayer = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
adjustY: true
|
adjustY: true
|
||||||
}
|
}
|
||||||
} : _props$screenshotButt,
|
} : _props$screenshotButt,
|
||||||
|
_props$autoPlay = props.autoPlay,
|
||||||
|
autoPlay = _props$autoPlay === void 0 ? false : _props$autoPlay,
|
||||||
|
odList = props.odList,
|
||||||
|
showOD = props.showOD,
|
||||||
|
_props$width = props.width,
|
||||||
|
width = _props$width === void 0 ? '100%' : _props$width,
|
||||||
|
_props$height = props.height,
|
||||||
|
height = _props$height === void 0 ? '532px' : _props$height,
|
||||||
|
_props$backgroundColo = props.backgroundColor,
|
||||||
|
backgroundColor = _props$backgroundColo === void 0 ? '#333' : _props$backgroundColo,
|
||||||
_props$screenshotButt2 = props.screenshotButtonRender,
|
_props$screenshotButt2 = props.screenshotButtonRender,
|
||||||
screenshotButtonRender = _props$screenshotButt2 === void 0 ? function () {
|
screenshotButtonRender = _props$screenshotButt2 === void 0 ? function () {
|
||||||
return /*#__PURE__*/React.createElement("div", {
|
return /*#__PURE__*/React.createElement("div", {
|
||||||
@ -53,7 +63,8 @@ var VideoPlayer = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
}, "\u56DE\u8C03DOM");
|
}, "\u56DE\u8C03DOM");
|
||||||
} : _props$screenshotButt2,
|
} : _props$screenshotButt2,
|
||||||
onCropChange = props.onCropChange,
|
onCropChange = props.onCropChange,
|
||||||
defaultNormalizationRect = props.defautlNormalizationRect;
|
defaultNormalizationRect = props.defautlNormalizationRect,
|
||||||
|
playerProps = props.playerProps;
|
||||||
// ========================== 播放 =========================
|
// ========================== 播放 =========================
|
||||||
//实例参数
|
//实例参数
|
||||||
var containerRef = useRef(null); //容器ref
|
var containerRef = useRef(null); //容器ref
|
||||||
@ -257,6 +268,8 @@ var VideoPlayer = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 重新加载
|
||||||
var _reload = /*#__PURE__*/function () {
|
var _reload = /*#__PURE__*/function () {
|
||||||
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
||||||
var oldTime;
|
var oldTime;
|
||||||
@ -309,6 +322,8 @@ var VideoPlayer = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
return _ref.apply(this, arguments);
|
return _ref.apply(this, arguments);
|
||||||
};
|
};
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
// 进度条操作
|
||||||
var seek = function seek(v) {
|
var seek = function seek(v) {
|
||||||
if (videoInsRef.current && isVideoLoadFinished) {
|
if (videoInsRef.current && isVideoLoadFinished) {
|
||||||
setPlayTime(parseFloat(v));
|
setPlayTime(parseFloat(v));
|
||||||
@ -317,6 +332,7 @@ var VideoPlayer = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
message.warning('待视频加载完,才可操作进度条');
|
message.warning('待视频加载完,才可操作进度条');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========================== 视频opt bar =========================
|
// ========================== 视频opt bar =========================
|
||||||
var _useFullscreen = useFullscreen(containerRef, {
|
var _useFullscreen = useFullscreen(containerRef, {
|
||||||
pageFullscreen: true
|
pageFullscreen: true
|
||||||
@ -354,17 +370,15 @@ var VideoPlayer = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
_useState22 = _slicedToArray(_useState21, 2),
|
_useState22 = _slicedToArray(_useState21, 2),
|
||||||
cropRect = _useState22[0],
|
cropRect = _useState22[0],
|
||||||
setCropRect = _useState22[1];
|
setCropRect = _useState22[1];
|
||||||
useEffect(function () {
|
|
||||||
var _videoInsRef$current4, _videoInsRef$current5;
|
// 监听showCrop, isReady - 是否可编辑、视频播放组件是否挂载
|
||||||
showCrop ? videoInsRef === null || videoInsRef === void 0 || (_videoInsRef$current4 = videoInsRef.current) === null || _videoInsRef$current4 === void 0 ? void 0 : _videoInsRef$current4.pause() : videoInsRef === null || videoInsRef === void 0 || (_videoInsRef$current5 = videoInsRef.current) === null || _videoInsRef$current5 === void 0 ? void 0 : _videoInsRef$current5.play();
|
|
||||||
}, [showCrop]);
|
|
||||||
useEffect(function () {
|
useEffect(function () {
|
||||||
var handlerCropStart;
|
var handlerCropStart;
|
||||||
var handlerCropEnd;
|
var handlerCropEnd;
|
||||||
setCropRect(null);
|
setCropRect(null);
|
||||||
if (!isReady) return;
|
if (!isReady) return;
|
||||||
if (showCrop) {
|
if (showCrop) {
|
||||||
var _canvas$parentNode;
|
var _canvas$parentNode, _videoInsRef$current4;
|
||||||
handlerCropStart = addEventListenerWrapper(corpContainerRef.current, EVENT_CROP_START, function () {
|
handlerCropStart = addEventListenerWrapper(corpContainerRef.current, EVENT_CROP_START, function () {
|
||||||
setCropRect(null);
|
setCropRect(null);
|
||||||
});
|
});
|
||||||
@ -412,18 +426,41 @@ var VideoPlayer = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
isFirstFlagRef.current = false;
|
isFirstFlagRef.current = false;
|
||||||
|
|
||||||
|
// 初始化圈选工具
|
||||||
cropInsRef.current = new Cropper(corpContainerRef.current, {
|
cropInsRef.current = new Cropper(corpContainerRef.current, {
|
||||||
showMask: true,
|
showMask: true,
|
||||||
cropBoxLimited: cropBoxLimited,
|
cropBoxLimited: cropBoxLimited,
|
||||||
|
editAble: false,
|
||||||
img: imageData,
|
img: imageData,
|
||||||
initialCropBoxData: initialCropBoxData
|
initialCropBoxData: initialCropBoxData
|
||||||
});
|
});
|
||||||
|
videoInsRef === null || videoInsRef === void 0 || (_videoInsRef$current4 = videoInsRef.current) === null || _videoInsRef$current4 === void 0 || _videoInsRef$current4.pause();
|
||||||
|
} else {
|
||||||
|
var _videoInsRef$current5;
|
||||||
|
var _element = videoInsRef.current._mediaElement || {};
|
||||||
|
videoInsRef === null || videoInsRef === void 0 || (_videoInsRef$current5 = videoInsRef.current) === null || _videoInsRef$current5 === void 0 || _videoInsRef$current5.play();
|
||||||
|
// 挂载图片选择
|
||||||
|
cropInsRef.current = new Viewer(corpContainerRef.current, {
|
||||||
|
scaleAble: false,
|
||||||
|
selectAble: false,
|
||||||
|
dragAble: false,
|
||||||
|
width: _element.clientWidth,
|
||||||
|
height: _element.clientHeight,
|
||||||
|
backgroundColor: 'transparent'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 判定是否存在od框
|
||||||
|
showOD && (odList === null || odList === void 0 ? void 0 : odList.forEach(function (_od) {
|
||||||
|
var _cropInsRef$current;
|
||||||
|
cropInsRef === null || cropInsRef === void 0 || (_cropInsRef$current = cropInsRef.current) === null || _cropInsRef$current === void 0 || _cropInsRef$current.addShape(_od);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
return function () {
|
return function () {
|
||||||
var _handlerCropStart, _handlerCropEnd, _cropInsRef$current, _cropInsRef$current$d;
|
var _handlerCropStart, _handlerCropEnd, _cropInsRef$current2, _cropInsRef$current2$;
|
||||||
(_handlerCropStart = handlerCropStart) === null || _handlerCropStart === void 0 || _handlerCropStart.remove();
|
(_handlerCropStart = handlerCropStart) === null || _handlerCropStart === void 0 || _handlerCropStart.remove();
|
||||||
(_handlerCropEnd = handlerCropEnd) === null || _handlerCropEnd === void 0 || _handlerCropEnd.remove();
|
(_handlerCropEnd = handlerCropEnd) === null || _handlerCropEnd === void 0 || _handlerCropEnd.remove();
|
||||||
cropInsRef === null || cropInsRef === void 0 || (_cropInsRef$current = cropInsRef.current) === null || _cropInsRef$current === void 0 || (_cropInsRef$current$d = _cropInsRef$current.destroy) === null || _cropInsRef$current$d === void 0 || _cropInsRef$current$d.call(_cropInsRef$current);
|
cropInsRef === null || cropInsRef === void 0 || (_cropInsRef$current2 = cropInsRef.current) === null || _cropInsRef$current2 === void 0 || (_cropInsRef$current2$ = _cropInsRef$current2.destroy) === null || _cropInsRef$current2$ === void 0 || _cropInsRef$current2$.call(_cropInsRef$current2);
|
||||||
cropInsRef.current = null;
|
cropInsRef.current = null;
|
||||||
};
|
};
|
||||||
}, [showCrop, isReady]);
|
}, [showCrop, isReady]);
|
||||||
@ -502,7 +539,7 @@ var VideoPlayer = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
};
|
};
|
||||||
}();
|
}();
|
||||||
|
|
||||||
//回调
|
// 监听showCrop、cropRect - 监听是否可编辑、绘制的矩形
|
||||||
useEffect(function () {
|
useEffect(function () {
|
||||||
//计算归一化crop rect
|
//计算归一化crop rect
|
||||||
var normalizationRect = null;
|
var normalizationRect = null;
|
||||||
@ -528,41 +565,11 @@ var VideoPlayer = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
}, [showCrop, cropRect]);
|
}, [showCrop, cropRect]);
|
||||||
|
|
||||||
// ========================== 截帧 =========================
|
// ========================== 截帧 =========================
|
||||||
var downloadVideoframe = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
|
var downloadVideoFrame = useCallback(function (opt) {
|
||||||
var _videoInsRef$current6, _videoInsRef$current7, video, canvas, ctx, base64;
|
var _videoInsRef$current6, _videoInsRef$current7;
|
||||||
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
|
videoInsRef === null || videoInsRef === void 0 || (_videoInsRef$current6 = videoInsRef.current) === null || _videoInsRef$current6 === void 0 || (_videoInsRef$current7 = _videoInsRef$current6.pause) === null || _videoInsRef$current7 === void 0 || _videoInsRef$current7.call(_videoInsRef$current6);
|
||||||
while (1) switch (_context4.prev = _context4.next) {
|
downloadFrame(videoRef.current, opt);
|
||||||
case 0:
|
}, []);
|
||||||
try {
|
|
||||||
videoInsRef === null || videoInsRef === void 0 || (_videoInsRef$current6 = videoInsRef.current) === null || _videoInsRef$current6 === void 0 || (_videoInsRef$current7 = _videoInsRef$current6.pause) === null || _videoInsRef$current7 === void 0 || _videoInsRef$current7.call(_videoInsRef$current6);
|
|
||||||
video = videoRef.current;
|
|
||||||
canvas = document.createElement('canvas');
|
|
||||||
ctx = canvas.getContext('2d');
|
|
||||||
//当视频处于还未加载出来时,截屏为黑色图片
|
|
||||||
if (video.readyState === 0) {
|
|
||||||
ctx === null || ctx === void 0 || ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
canvas.width = video.offsetWidth;
|
|
||||||
canvas.height = video.offsetHeight;
|
|
||||||
// @ts-ignore
|
|
||||||
ctx.fillStyle = 'black';
|
|
||||||
ctx === null || ctx === void 0 || ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
||||||
base64 = canvas.toDataURL();
|
|
||||||
} else {
|
|
||||||
canvas.width = video.videoWidth;
|
|
||||||
canvas.height = video.videoHeight;
|
|
||||||
ctx === null || ctx === void 0 || ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
||||||
base64 = canvas.toDataURL('image/png');
|
|
||||||
}
|
|
||||||
download(base64);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
case "end":
|
|
||||||
return _context4.stop();
|
|
||||||
}
|
|
||||||
}, _callee4);
|
|
||||||
})), []);
|
|
||||||
|
|
||||||
// ============================== 暴露出去的方法 ===============================
|
// ============================== 暴露出去的方法 ===============================
|
||||||
var latestIsReady = useLatest(isReady);
|
var latestIsReady = useLatest(isReady);
|
||||||
@ -573,17 +580,31 @@ var VideoPlayer = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
setShowCrop: function setShowCrop(dispatch) {
|
setShowCrop: function setShowCrop(dispatch) {
|
||||||
var isReady = latestIsReady.current;
|
var isReady = latestIsReady.current;
|
||||||
if (!isReady) return;
|
if (!isReady) return;
|
||||||
_setShowCrop(dispatch);
|
_setShowCrop === null || _setShowCrop === void 0 || _setShowCrop(dispatch);
|
||||||
},
|
},
|
||||||
downloadVideoframe: downloadVideoframe
|
downloadVideoFrame: downloadVideoFrame,
|
||||||
|
pause: function pause() {
|
||||||
|
var _videoInsRef$current8, _videoInsRef$current9;
|
||||||
|
(_videoInsRef$current8 = videoInsRef.current) === null || _videoInsRef$current8 === void 0 || (_videoInsRef$current9 = _videoInsRef$current8.pause) === null || _videoInsRef$current9 === void 0 || _videoInsRef$current9.call(_videoInsRef$current8);
|
||||||
|
},
|
||||||
|
play: function play() {
|
||||||
|
var _videoInsRef$current10, _videoInsRef$current11;
|
||||||
|
(_videoInsRef$current10 = videoInsRef.current) === null || _videoInsRef$current10 === void 0 || (_videoInsRef$current11 = _videoInsRef$current10.play) === null || _videoInsRef$current11 === void 0 || _videoInsRef$current11.call(_videoInsRef$current10);
|
||||||
|
},
|
||||||
|
reload: _reload
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
return /*#__PURE__*/React.createElement("div", {
|
return /*#__PURE__*/React.createElement("div", {
|
||||||
className: classNames("".concat(componentName)),
|
className: classNames("".concat(componentName)),
|
||||||
ref: containerRef
|
ref: containerRef,
|
||||||
}, url && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(FlvPlayer, {
|
style: {
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
backgroundColor: backgroundColor
|
||||||
|
}
|
||||||
|
}, url && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(FlvPlayer, _extends({
|
||||||
playId: playSeq,
|
playId: playSeq,
|
||||||
autoPlay: true,
|
autoPlay: autoPlay,
|
||||||
className: classNames("".concat(componentName, "-flv")),
|
className: classNames("".concat(componentName, "-flv")),
|
||||||
type: url.startsWith('http') ? 'mp4' : 'flv',
|
type: url.startsWith('http') ? 'mp4' : 'flv',
|
||||||
url: url,
|
url: url,
|
||||||
@ -594,12 +615,14 @@ var VideoPlayer = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
hasAudio: false,
|
hasAudio: false,
|
||||||
hasVideo: true
|
hasVideo: true
|
||||||
},
|
},
|
||||||
onCreat: initPlayer
|
onCreate: initPlayer
|
||||||
}), /*#__PURE__*/React.createElement("div", {
|
}, playerProps)), /*#__PURE__*/React.createElement("div", {
|
||||||
className: classNames("".concat(componentName, "-crop-container")),
|
className: classNames("".concat(componentName, "-crop-container")),
|
||||||
ref: corpContainerRef,
|
ref: corpContainerRef,
|
||||||
style: {
|
style: {
|
||||||
display: isFullscreen ? 'none' : 'block'
|
display: isFullscreen ? 'none' : 'block',
|
||||||
|
width: '100%',
|
||||||
|
height: '100%'
|
||||||
}
|
}
|
||||||
}), showCrop && cropRect && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
}), showCrop && cropRect && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
||||||
ref: alginContainerRef,
|
ref: alginContainerRef,
|
||||||
@ -625,27 +648,26 @@ var VideoPlayer = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
cropType: CROP_TYPE['CUSTOM']
|
cropType: CROP_TYPE['CUSTOM']
|
||||||
}))), !showCrop && /*#__PURE__*/React.createElement("div", {
|
}))), !showCrop && /*#__PURE__*/React.createElement("div", {
|
||||||
className: "".concat(componentName, "-opt")
|
className: "".concat(componentName, "-opt")
|
||||||
}, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Button, {
|
|
||||||
type: "text",
|
|
||||||
onClick: function onClick() {
|
|
||||||
if (!isPlay) {
|
|
||||||
var _videoInsRef$current8;
|
|
||||||
//播放中暂停
|
|
||||||
videoInsRef === null || videoInsRef === void 0 || (_videoInsRef$current8 = videoInsRef.current) === null || _videoInsRef$current8 === void 0 || _videoInsRef$current8.play();
|
|
||||||
_setShowCrop(false);
|
|
||||||
} else {
|
|
||||||
var _videoInsRef$current9;
|
|
||||||
videoInsRef === null || videoInsRef === void 0 || (_videoInsRef$current9 = videoInsRef.current) === null || _videoInsRef$current9 === void 0 || _videoInsRef$current9.pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, /*#__PURE__*/React.createElement(IconFont, {
|
}, /*#__PURE__*/React.createElement(IconFont, {
|
||||||
styles: {
|
styles: {
|
||||||
|
marginRight: '12px',
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
display: 'flex'
|
display: 'flex'
|
||||||
},
|
},
|
||||||
|
onIconClick: function onIconClick() {
|
||||||
|
if (!isPlay) {
|
||||||
|
var _videoInsRef$current12;
|
||||||
|
//播放中暂停
|
||||||
|
videoInsRef === null || videoInsRef === void 0 || (_videoInsRef$current12 = videoInsRef.current) === null || _videoInsRef$current12 === void 0 || _videoInsRef$current12.play();
|
||||||
|
_setShowCrop(false);
|
||||||
|
} else {
|
||||||
|
var _videoInsRef$current13;
|
||||||
|
videoInsRef === null || videoInsRef === void 0 || (_videoInsRef$current13 = videoInsRef.current) === null || _videoInsRef$current13 === void 0 || _videoInsRef$current13.pause();
|
||||||
|
}
|
||||||
|
},
|
||||||
color: "#1890ff",
|
color: "#1890ff",
|
||||||
icon: !isPlay ? 'icon-shipinbofang' : 'icon-shipinzanting'
|
icon: !isPlay ? 'icon-bofang3' : 'icon-zanting1'
|
||||||
}))), /*#__PURE__*/React.createElement("div", {
|
}), /*#__PURE__*/React.createElement("div", {
|
||||||
className: "".concat(componentName, "-opt-range"),
|
className: "".concat(componentName, "-opt-range"),
|
||||||
onClick: function onClick(e) {
|
onClick: function onClick(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@ -656,20 +678,19 @@ var VideoPlayer = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
max: showMaxDuration,
|
max: showMaxDuration,
|
||||||
showSlider: showSlider,
|
showSlider: showSlider,
|
||||||
onChange: seek
|
onChange: seek
|
||||||
}), /*#__PURE__*/React.createElement("div", null, formatDurationTime(playTime), "/", formatDurationTime(showMaxDuration))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Button, {
|
}), /*#__PURE__*/React.createElement("div", null, formatDurationTime(playTime), "/", formatDurationTime(showMaxDuration))), /*#__PURE__*/React.createElement(IconFont, {
|
||||||
type: "text",
|
styles: {
|
||||||
onClick: function onClick(e) {
|
display: 'flex',
|
||||||
|
marginLeft: '12px'
|
||||||
|
},
|
||||||
|
color: "#fff",
|
||||||
|
size: 18,
|
||||||
|
onIconClick: function onIconClick(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
toggleFullscreen();
|
toggleFullscreen();
|
||||||
}
|
|
||||||
}, /*#__PURE__*/React.createElement(IconFont, {
|
|
||||||
styles: {
|
|
||||||
color: '#fff',
|
|
||||||
display: 'flex'
|
|
||||||
},
|
},
|
||||||
size: 18,
|
icon: isFullscreen ? 'icon-suoxiao1' : 'icon-quanping1'
|
||||||
icon: isFullscreen ? 'icon-cancle_fullscreen' : 'icon-fullscreen'
|
})), !!showStatus && /*#__PURE__*/React.createElement(Loading, {
|
||||||
})))), !!showStatus && /*#__PURE__*/React.createElement(Loading, {
|
|
||||||
status: showStatus,
|
status: showStatus,
|
||||||
reload: function reload() {
|
reload: function reload() {
|
||||||
return _reload();
|
return _reload();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
var _excluded = ["className", "autoPlay", "config", "onCreat", "playId"];
|
var _excluded = ["className", "autoPlay", "config", "onCreate", "playId"];
|
||||||
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
||||||
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
||||||
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
||||||
@ -45,12 +45,13 @@ var VideoPlayer = /*#__PURE__*/function (_Component) {
|
|||||||
autoPlay = _this$props$autoPlay === void 0 ? true : _this$props$autoPlay,
|
autoPlay = _this$props$autoPlay === void 0 ? true : _this$props$autoPlay,
|
||||||
_this$props$config = _this$props.config,
|
_this$props$config = _this$props.config,
|
||||||
config = _this$props$config === void 0 ? {} : _this$props$config,
|
config = _this$props$config === void 0 ? {} : _this$props$config,
|
||||||
onCreat = _this$props.onCreat,
|
onCreate = _this$props.onCreate,
|
||||||
playId = _this$props.playId,
|
playId = _this$props.playId,
|
||||||
others = _objectWithoutProperties(_this$props, _excluded);
|
others = _objectWithoutProperties(_this$props, _excluded);
|
||||||
if ($video) {
|
if ($video) {
|
||||||
if (flvjs.isSupported() && _this.props.url && _this.props.url) {
|
if (flvjs.isSupported() && _this.props.url && _this.props.url) {
|
||||||
var reload = function reload() {
|
var reload = function reload() {
|
||||||
|
var _this$flvPlayer;
|
||||||
if (_this.flvPlayer && _this.flvPlayer.destroy) {
|
if (_this.flvPlayer && _this.flvPlayer.destroy) {
|
||||||
try {
|
try {
|
||||||
_this.flvPlayer.destroy();
|
_this.flvPlayer.destroy();
|
||||||
@ -65,7 +66,7 @@ var VideoPlayer = /*#__PURE__*/function (_Component) {
|
|||||||
flvPlayer.load();
|
flvPlayer.load();
|
||||||
_this.flvPlayer = flvPlayer;
|
_this.flvPlayer = flvPlayer;
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
var controller = _this.flvPlayer._transmuxer._controller;
|
var controller = (_this$flvPlayer = _this.flvPlayer) === null || _this$flvPlayer === void 0 || (_this$flvPlayer = _this$flvPlayer._transmuxer) === null || _this$flvPlayer === void 0 ? void 0 : _this$flvPlayer._controller;
|
||||||
var wsLoader = controller._ioctl._loader;
|
var wsLoader = controller._ioctl._loader;
|
||||||
var oldWsOnCompleteFunc = wsLoader._onComplete;
|
var oldWsOnCompleteFunc = wsLoader._onComplete;
|
||||||
wsLoader._onComplete = function () {
|
wsLoader._onComplete = function () {
|
||||||
@ -82,10 +83,9 @@ var VideoPlayer = /*#__PURE__*/function (_Component) {
|
|||||||
oldWsOnCompleteFunc();
|
oldWsOnCompleteFunc();
|
||||||
};
|
};
|
||||||
_this.flvPlayer.reload = reload;
|
_this.flvPlayer.reload = reload;
|
||||||
onCreat && onCreat(_this.flvPlayer, $video);
|
onCreate === null || onCreate === void 0 || onCreate(_this.flvPlayer, $video);
|
||||||
};
|
};
|
||||||
reload();
|
reload();
|
||||||
onCreat && onCreat(_this.flvPlayer, $video);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -95,9 +95,9 @@ var VideoPlayer = /*#__PURE__*/function (_Component) {
|
|||||||
key: "componentWillUnmount",
|
key: "componentWillUnmount",
|
||||||
value: function componentWillUnmount() {
|
value: function componentWillUnmount() {
|
||||||
if (this.flvPlayer) {
|
if (this.flvPlayer) {
|
||||||
var _this$flvPlayer, _this$flvPlayer2;
|
var _this$flvPlayer2, _this$flvPlayer3;
|
||||||
(_this$flvPlayer = this.flvPlayer) === null || _this$flvPlayer === void 0 || _this$flvPlayer.unload();
|
(_this$flvPlayer2 = this.flvPlayer) === null || _this$flvPlayer2 === void 0 || _this$flvPlayer2.unload();
|
||||||
(_this$flvPlayer2 = this.flvPlayer) === null || _this$flvPlayer2 === void 0 || _this$flvPlayer2.detachMediaElement();
|
(_this$flvPlayer3 = this.flvPlayer) === null || _this$flvPlayer3 === void 0 || _this$flvPlayer3.detachMediaElement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
@ -119,13 +119,11 @@ var VideoPlayer = /*#__PURE__*/function (_Component) {
|
|||||||
return /*#__PURE__*/React.createElement("video", {
|
return /*#__PURE__*/React.createElement("video", {
|
||||||
muted: true,
|
muted: true,
|
||||||
preload: "metadata",
|
preload: "metadata",
|
||||||
className: className
|
className: className,
|
||||||
// controls={true}
|
style: _objectSpread({
|
||||||
,
|
|
||||||
style: Object.assign({
|
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%'
|
height: '100%'
|
||||||
}, style ? style : {}),
|
}, style),
|
||||||
ref: this.initFlv
|
ref: this.initFlv
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ function _objectWithoutProperties(source, excluded) { if (source == null) return
|
|||||||
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Slider } from 'antd';
|
import { Slider, ConfigProvider } from 'antd';
|
||||||
import "./index.less";
|
import "./index.less";
|
||||||
var componentName = "zhst-image__range";
|
var componentName = "zhst-image__range";
|
||||||
export var Range = function Range(props) {
|
export var Range = function Range(props) {
|
||||||
@ -15,6 +15,15 @@ export var Range = function Range(props) {
|
|||||||
return /*#__PURE__*/React.createElement("div", {
|
return /*#__PURE__*/React.createElement("div", {
|
||||||
style: style,
|
style: style,
|
||||||
className: classNames("".concat(componentName), !showSlider && "".concat(componentName, "--no-slider"), className)
|
className: classNames("".concat(componentName), !showSlider && "".concat(componentName, "--no-slider"), className)
|
||||||
}, /*#__PURE__*/React.createElement(Slider, others));
|
}, /*#__PURE__*/React.createElement(ConfigProvider, {
|
||||||
|
theme: {
|
||||||
|
components: {
|
||||||
|
Slider: {
|
||||||
|
railBg: 'rgba(255, 255, 255, 0.6)',
|
||||||
|
railHoverBg: 'rgba(255, 255, 255, 0.6)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, /*#__PURE__*/React.createElement(Slider, others)));
|
||||||
};
|
};
|
||||||
export default Range;
|
export default Range;
|
@ -1,8 +1,6 @@
|
|||||||
.zhst-image__video-view {
|
.zhst-image__video-view {
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: 100%;
|
|
||||||
height: 532px;
|
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
|
|
||||||
// &-flv {
|
// &-flv {
|
||||||
@ -37,7 +35,7 @@
|
|||||||
height: 32px;
|
height: 32px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 12px;
|
padding: 0 12px 0 24px;
|
||||||
background-color: rgb(0 0 0 / 80%);
|
background-color: rgb(0 0 0 / 80%);
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import download from "downloadjs";
|
||||||
export function getShowStatus(isLoadingVideo, isEnd, isError) {
|
export function getShowStatus(isLoadingVideo, isEnd, isError) {
|
||||||
var status = null;
|
var status = null;
|
||||||
if (isLoadingVideo) {
|
if (isLoadingVideo) {
|
||||||
@ -10,4 +11,41 @@ export function getShowStatus(isLoadingVideo, isEnd, isError) {
|
|||||||
status = 'END';
|
status = 'END';
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 下载功能的可配置属性
|
||||||
|
|
||||||
|
// 视屏截帧、下载
|
||||||
|
export var downloadFrame = function downloadFrame(_videoDom, opt) {
|
||||||
|
var _ref = opt || {},
|
||||||
|
_ref$downloadAble = _ref.downloadAble,
|
||||||
|
downloadAble = _ref$downloadAble === void 0 ? true : _ref$downloadAble,
|
||||||
|
_ref$fileName = _ref.fileName,
|
||||||
|
fileName = _ref$fileName === void 0 ? 'image' : _ref$fileName,
|
||||||
|
_ref$fileType = _ref.fileType,
|
||||||
|
fileType = _ref$fileType === void 0 ? 'image/png' : _ref$fileType;
|
||||||
|
try {
|
||||||
|
var video = _videoDom;
|
||||||
|
var canvas = document.createElement('canvas');
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
var base64;
|
||||||
|
|
||||||
|
//当视频处于还未加载出来时,截屏为黑色图片
|
||||||
|
if (video.readyState === 0) {
|
||||||
|
ctx === null || ctx === void 0 || ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
canvas.width = video.offsetWidth;
|
||||||
|
canvas.height = video.offsetHeight;
|
||||||
|
// @ts-ignore
|
||||||
|
ctx.fillStyle = 'black';
|
||||||
|
ctx === null || ctx === void 0 || ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
} else {
|
||||||
|
canvas.width = video.videoWidth;
|
||||||
|
canvas.height = video.videoHeight;
|
||||||
|
ctx === null || ctx === void 0 || ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||||
|
}
|
||||||
|
base64 = canvas.toDataURL(fileType);
|
||||||
|
downloadAble && download(base64, fileName);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user