Commit 8077ea6e authored by 周宏民's avatar 周宏民

feat:演示功能

parent f4d1fd37
Pipeline #89598 waiting for manual action with stages
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
/*
* @Title:
* @Author: hongmye
* @Date: 2023-12-26 18:34:42
*/
import { Image, Tooltip, message } from 'antd';
import React, { useMemo, useEffect, useState } from 'react';
import classNames from 'classnames';
import DataCarousel from '../DataCarousel';
import styles from './index.less';
const BottomItem = props => {
const { projectConfig, listData = [], configData = [], onLineUrl, handToPage } = props;
const [list, setList] = useState([]);
const [infoData, setInfoData] = useState({});
const renderNum = (num, type) => {
const numStr = num ? num.toString() : '0';
const arr = numStr.split('');
return arr.map(a => (
<div className={styles.l_item_num_item} type={type}>
{a}
</div>
));
};
const toPage = (url, col) => {
if (!url.includes('https')) return;
if (!url.includes('user/noscret') || projectConfig[col['平台名称']]) {
return handToPage(url);
}
message.warning('该账号没有权限,请联系管理人员');
};
const renderCol = (row, rindex) => {
if (!Array.isArray(row)) return null;
return (
<div className={styles.list_item_col}>
{row.map((col, cIndex) => (
<div
key={`${rindex}-${cIndex}`}
type={col['项目环境'] && col['项目环境'].includes('https') ? 'jump' : 'none'}
onClick={() => toPage(col['项目环境'], col)}
alt="点击体验"
className={styles.list_item}
>
<div className={styles.list_item_img_wrap}>
<div className={classNames(styles.list_item_img, 'list_item_img')}>
<Image
src={`${onLineUrl}CityInterface/rest/services/filedownload.svc/download/${col['项目图片']}`}
style={{ height: '100px', width: '100%', overflow: 'hidden' }}
preview={false}
/>
</div>
{col['重要程度'] === '样板' ? <div className={styles.list_item_img_tip} /> : null}
</div>
<div className={styles.list_item_info_wrap}>
<div className={styles.list_item_info_tip} type={col['所属行业']}>
{col['所属行业'] === '能源' ? '节水' : col['所属行业'] === '农饮水' ? '农水' : col['所属行业']}
</div>
<div className={styles.list_item_info_name}>
<Tooltip title={col['平台名称']} color="#1685FF">
{col['平台名称']}
</Tooltip>
</div>
<div className={styles.list_item_info_address}>{col['城市']}</div>
</div>
</div>
))}
</div>
);
};
const spliceArr = (arr, num) => {
const reArr = [];
arr.map(item => {
if (!reArr[reArr.length - 1] || reArr[reArr.length - 1].length === num) {
// 新行添加
reArr.push([]);
}
if (reArr[reArr.length - 1].length !== num) {
// 长度不够则直接添加
reArr[reArr.length - 1].push(item);
}
return null;
});
return reArr;
};
useEffect(() => {
const arr = [];
listData.forEach(i => {
let str = i['所属省份'];
if (i['所属省份']) {
if (str[str.length - 1] === '省') {
str = str.slice(0, str.length - 1);
}
}
i['城市'] = str;
arr.push(i);
});
setList(spliceArr(arr, 2));
}, [listData]);
useEffect(() => {
const obj = {
项目数量: '',
服务客户: '',
覆盖省份: '',
};
configData.forEach(c => {
if (obj[c['名称']] === '') {
obj[c['名称']] = c['数值'];
}
});
setInfoData(obj);
}, [configData]);
return (
<div className={classNames(styles.bottom_item, 'demo_bottom_item')}>
<div className={styles.left}>
<div className={styles.l_title_wrap}>
<div className={styles.l_title_sub}>熊猫智慧水务</div>
<div className={styles.l_title}>项目落地保障:</div>
</div>
<div className={styles.l_list}>
<div className={styles.l_item}>
<div className={styles.l_item_title} type="项目数量">
项目数量:
</div>
<div className={styles.l_item_num_list}>{renderNum(infoData['项目数量'], '项目数量')}</div>
<div className={styles.l_item_num_unit}></div>
</div>
<div className={styles.l_item}>
<div className={styles.l_item_title} type="服务客户">
服务客户:
</div>
<div className={styles.l_item_num_list}>{renderNum(infoData['服务客户'], '服务客户')}</div>
<div className={styles.l_item_num_unit}></div>
</div>
<div className={styles.l_item}>
<div className={styles.l_item_title} type="覆盖省份">
覆盖省份:
</div>
<div className={styles.l_item_num_list}>{renderNum(infoData['覆盖省份'], '覆盖省份')}</div>
<div className={styles.l_item_num_unit}></div>
</div>
</div>
</div>
<div className={styles.center}>
<DataCarousel
gap={1}
autoplay={5000}
itemHeight={270}
list={list}
renderItem={renderCol}
config={{
direction: 'horizontal',
width: 1520,
loop: false,
slidesPerView: 7,
}}
/>
</div>
</div>
);
};
export default BottomItem;
@imgSrc: '@/assets/images/demonstration';
.bottom_item {
display: flex;
width: 100%;
height: 100%;
overflow: hidden;
padding: 0 28px 10px;
background: url('@{imgSrc}/bottom_bg.png') no-repeat left top;
background-size: calc(100% - 27px) 42px;
.left {
flex: none;
width: 288px;
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
background: url('@{imgSrc}/项目落地保障.png') no-repeat center center;
background-size: 100% 100%;
padding: 25px 15px 20px 25px;
.l_title_wrap {
flex: none;
width: 100%;
.l_title_sub {
background: url('@{imgSrc}/tip.png') no-repeat left center;
background-size: 35px 36px;
padding-left: 35px;
font-size: 16px;
height: 36px;
line-height: 36px;
}
.l_title {
font-size: 22px;
font-family: Microsoft YaHei;
font-weight: bold;
color: #FBD84D;
line-height: 32px;
background: linear-gradient(0deg, #FFD270 0%, #FFFFFF 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.l_list {
height: 100%;
padding: 10px 0;
display: flex;
flex-direction: column;
justify-content: space-around;
.l_item {
display: flex;
align-items: center;
}
.l_item_title {
padding-left: 20px;
}
.l_item_num_list {
display: flex;
}
.l_item_num_item {
width: 32px;
height: 36px;
line-height: 36px;
text-align: center;
margin-right: 5px;
font-size: 24px;
font-weight: bold;
}
.l_item_num_unit {
font-size: 14px;
font-weight: 400;
align-self: flex-end;
}
.l_item_num_unit[type='add'] {
font-size: 24px;
font-weight: bold;
align-self: center;
}
.l_item_title[type='项目数量'] {
background: url('@{imgSrc}/项目数量.png') no-repeat left center;
background-size: 14px 14px;
}
.l_item_num_item[type='项目数量'] {
background: url('@{imgSrc}/项目数量num.png') no-repeat center/100% 100%;
}
.l_item_title[type='服务客户'] {
background: url('@{imgSrc}/服务客户.png') no-repeat left center;
background-size: 14px 14px;
}
.l_item_num_item[type='服务客户'] {
background: url('@{imgSrc}/服务客户num.png') no-repeat center/100% 100%;
}
.l_item_title[type='覆盖省份'] {
background: url('@{imgSrc}/覆盖省份.png') no-repeat left center;
background-size: 14px 14px;
}
.l_item_num_item[type='覆盖省份'] {
background: url('@{imgSrc}/覆盖省份num.png') no-repeat center/100% 100%;
}
}
}
.center {
flex: 1;
height: 100%;
overflow: hidden;
padding: 12px 0 0 13px;
}
.list_item[type='jump'] {
cursor: pointer;
}
.list_item[type='jump']:hover {
border: 1px solid #1685FF;
transform: scale(1.05);
}
.list_item[type='jump']:active {
opacity: 0.8;
}
.list_item {
width: 204px;
height: 130px;
border: 1px solid rgba(71, 88, 114, 0.8);
border-radius: 10px;
overflow: hidden;
margin-right: 8px;
margin-bottom: 8px;
transform-origin: center top;
transition: transform 0.3s;
.list_item_img_wrap {
width: 100%;
height: 100px;
overflow: hidden;
position: relative;
.list_item_img_tip {
position: absolute;
right: 0;
top: 0;
width: 57px;
height: 19px;
background: url('@{imgSrc}/案例.png') no-repeat center/100% 100%;
}
}
.list_item_info_wrap {
display: flex;
width: 100%;
overflow: hidden;
align-items: center;
padding: 3px 8px 0;
font-size: 12px;
font-weight: 400;
.list_item_info_tip {
flex: none;
width: 38px;
height: 20px;
text-align: center;
line-height: 18px;
margin-right: 5px;
background: url('@{imgSrc}/供水.png') no-repeat center/100% 100%;
}
.list_item_info_tip[type='水利'] {
background: url('@{imgSrc}/农水.png') no-repeat center/100% 100%;
}
.list_item_info_tip[type='能源'] {
background: url('@{imgSrc}/节水.png') no-repeat center/100% 100%;
}
.list_item_info_tip[type='排水'] {
background: url('@{imgSrc}/排水.png') no-repeat center/100% 100%;
}
.list_item_info_tip[type='农饮水'] {
background: url('@{imgSrc}/农饮水.png') no-repeat center/100% 100%;
}
.list_item_info_name {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.list_item_info_address {
flex: none;
font-size: 12px;
font-weight: 400;
color: #ACCDF0;
line-height: 1;
padding-left: 4px;
border-left: 1px solid rgba(216, 234, 253, 0.4);
}
}
}
.right {
flex: none;
height: 100%;
overflow: hidden;
width: 44px;
height: 100%;
background: url('@{imgSrc}/查看全部.png') no-repeat center/100% 100%;
writing-mode: vertical-rl;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
letter-spacing: 2px;
cursor: pointer;
}
}
:global {
.demo_bottom_item {
.swiper-wrapper {
display: flex;
.swiper-slide {
width: 212px;
}
}
.list_item_img {
.panda-console-base-image {
width: 100%;
}
img {
width: 100%;
height: 100%;
}
}
}
}
\ No newline at end of file
/*
* @Title:数据列表轮播组件
* @Author: hongmye
* @Date: 2023-02-08 16:03:42
*/
import PandaEmpty from '@wisdom-components/empty';
import classNames from 'classnames';
import React, { useEffect, useRef, useState } from 'react';
import 'swiper/components/navigation/navigation.min.css';
import 'swiper/components/pagination/pagination.min.css';
import SwiperCore, { Autoplay, Mousewheel, Navigation, Pagination } from 'swiper/core';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/swiper.min.css';
import styles from './index.less';
SwiperCore.use([Autoplay, Pagination, Navigation, Mousewheel]);
const DataCarousel = ({ list, itemHeight, renderItem, config, autoplay, onSwiper, showEmpty = true }) => {
const autoplayConfig = {
delay: autoplay,
disableOnInteraction: false,
};
const contentRef = useRef(null);
const swiperRef = useRef(null);
const [listData, setListData] = useState([]);
useEffect(() => {
setListData(list);
}, [list]);
return (
<div
className={classNames(styles.dataCarousel, 'dataCarousel')}
style={{ width: '100%', height: '100%' }}
ref={contentRef}
>
<div className={classNames(styles.dataCarouselSwiper)} style={{ width: '100%', height: '100%' }}>
{listData && listData.length ? (
<Swiper
slidesPerView="auto"
autoplay={autoplay * 1 && listData.length > 1 ? autoplayConfig : false}
loop
height={itemHeight}
direction="vertical"
onSlideChange={e => {}}
mousewheel
onSwiper={swiper => {
swiperRef.current = swiper;
onSwiper && onSwiper(swiper);
// 鼠标悬浮暂停效果
swiper.$el[0].addEventListener('mouseover', () => swiper.autoplay.stop());
// 鼠标移开后继续自动滚屏效果
swiper.$el[0].addEventListener('mouseleave', () => {
listData.length > 1 && autoplay * 1 ? swiper.autoplay.start() : '';
});
}}
{...config}
>
{listData.map((item, index) => (
<SwiperSlide key={index} virtualIndex={index} onClick={() => {}}>
{renderItem(item, index + 1)}
</SwiperSlide>
))}
</Swiper>
) : showEmpty ? (
<div style={{ paddingTop: 10 }}>
<PandaEmpty />
</div>
) : null}
</div>
</div>
);
};
export default DataCarousel;
@root-entry-name: 'default';
@import '~antd/es/style/themes/index.less';
.dataCarousel {
width: 100%;
height: 100%;
overflow-y: auto;
.dataCarouselSwiper {
overflow-y: auto;
}
}
.dataCarousel {
:global {
.swiper-container {
width: 100%;
height: 100%;
}
}
}
/*
* @Title:
* @Author: hongmye
* @Date: 2023-01-10 11:18:55
*/
import React, { memo, useEffect } from 'react';
import Iframe from 'react-iframe';
import Empty from '@wisdom-components/empty';
import axios from 'axios';
import styles from './index.less';
const IframeContainer = props => {
const { linkUrl, onMessageBack, loading } = props;
const onMessage = e => {
console.log('🚀 ~ e:', e);
onMessageBack && onMessageBack(e);
};
const onError = e => {
console.log('🚀 ~ e:', e);
// onMessageBack && onMessageBack({ type: '无法连接' });
};
useEffect(() => {
if (linkUrl) {
console.log('🚀 ~ linkUrl:', linkUrl);
const url = linkUrl;
const baseUrl = url.split('civbase')[0];
axios({
url: `${baseUrl}PandaCore/GCK/Basis/GetUserInfo`,
method: 'get',
params: {},
ignoreSite: true,
})
.then(res => {
console.log(res, 'res');
})
.catch(err => {
onMessageBack && onMessageBack({ type: '无法连接' });
});
}
}, [linkUrl, onMessageBack]);
useEffect(() => {
// iframe通信
window.addEventListener('message', onMessage);
window.addEventListener('error', onError, true);
return () => {
window.removeEventListener('message', onMessage);
window.removeEventListener('error', onError);
};
}, [linkUrl, onError, onMessage, onMessageBack]);
return (
// style={{ left: loading ? '-100%' : '' }}
<div className={styles['tab-iframe']}>
{linkUrl ? (
<Iframe
url={linkUrl}
// url="http://127.0.0.1:8082/civbase/user/noscret/?client=city&token=fc6f4fb33eec42e2bded7d4a47218af8"
width="100%"
height="100%"
display="block"
position="relative"
styles={{ border: 'none' }}
/>
) : (
<Empty description="配置url链接才能显示哦!" />
)}
</div>
);
};
export default IframeContainer;
.tab-iframe {
width: 100vw;
height: 100vh;
position: relative;
overflow: hidden;
z-index: 100;
iframe {
border: none;
}
}
\ No newline at end of file
/*
* @Title:
* @Author: hongmye
* @Date: 2023-12-26 18:34:42
*/
import React, { useMemo, useEffect, useState, memo } from 'react';
import { Tooltip, message } from 'antd';
import { schemeData } from '../configData';
import styles from './index.less';
let timer;
const LeftItem = props => {
const { selectKey, onChangeScheme, handToProduct, productData } = props;
const handlePage = item => {
const row = productData.find(p => p['产品类型'] === item.title);
if (row?.['产品地址']) {
if (!row['产品地址'].includes('https')) return message.warning('产品地址配置错误,请联系管理人员');
handToProduct(row['产品地址'], row['产品名称']);
} else {
return message.warning('未配置产品地址,请联系管理人员');
}
};
const onMouseEnter = (item, index) => {
if (timer) {
timer && clearTimeout(timer);
}
timer = setTimeout(() => {
onChangeScheme && onChangeScheme(item, index);
}, 500);
};
const onMouseLeave = (item, index) => {
timer && clearTimeout(timer);
};
useEffect(() => {}, []);
return (
<div className={styles.left_item}>
<div className={styles.l_title_wrap}>
<div className={styles.l_title_sub}>熊猫智慧水务</div>
<div className={styles.l_title}>全行业软硬件系统解决方案:</div>
</div>
<div className={styles.l_list}>
{schemeData.map((item, index) => (
<div
className={styles.l_list_item}
key={item.title}
type={item.title}
selectType={selectKey === item.title ? 'select' : ''}
onClick={event => handlePage(item)}
onMouseEnter={() => onMouseEnter(item, index)}
onMouseLeave={() => onMouseLeave(item, index)}
>
<div className={styles.l_list_item_title}>- {item.title} -</div>
<div className={styles.l_list_item_tip} />
</div>
))}
</div>
</div>
);
};
export default memo(LeftItem);
@imgSrc: '@/assets/images/demonstration';
.left_item {
.l_title_wrap {
width: 100%;
height: 123px;
background: url('@{imgSrc}/全行业软硬件系统解决方案.png') no-repeat center center;
background-size: 100% 100%;
padding: 30px 0 0 25px;
.l_title_sub {
background: url('@{imgSrc}/tip.png') no-repeat left center;
background-size: 35px 36px;
padding-left: 35px;
font-size: 16px;
height: 36px;
line-height: 36px;
}
.l_title {
font-size: 22px;
font-family: Microsoft YaHei;
font-weight: bold;
color: #FFFFFF;
padding-left: 5px;
line-height: 32px;
letter-spacing: 1px;
// text-shadow: 0px 8px 8px rgba(8, 34, 78, 0.75);
background: linear-gradient(0deg, #92D2FF 0%, #FFFFFF 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.l_list {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.l_list_item:hover {
opacity: 1;
top: -8px;
}
.l_list_item:hover .l_list_item_tip {
opacity: 1;
}
.l_list_item[selectType='select'] {
opacity: 1;
top: -8px;
.l_list_item_tip {
opacity: 1;
}
}
.l_list_item {
width: 178px;
height: 162px;
opacity: 0.7;
top: 0;
position: relative;
text-align: center;
margin-bottom: 15px;
cursor: pointer;
transition: all 0.5s;
.l_list_item_title {
padding-top: 115px;
font-size: 18px;
}
}
.l_list_item_tip {
width: 71px;
height: 37px;
background: url('@{imgSrc}/选中产品.png') no-repeat center center;
background-size: 100% 100%;
position: absolute;
transition: all 0.3s;
bottom: -12px;
left: calc(50% - 35.5px);
opacity: 0;
}
.l_list_item[type='供水产品'] {
background: url('@{imgSrc}/供水产品.png') no-repeat center center;
background-size: 100% 100%;
}
.l_list_item[type='水利产品'] {
background: url('@{imgSrc}/水利产品.png') no-repeat center center;
background-size: 100% 100%;
}
.l_list_item[type='排水产品'] {
background: url('@{imgSrc}/排水产品.png') no-repeat center center;
background-size: 100% 100%;
}
.l_list_item[type='节水产品'] {
background: url('@{imgSrc}/节水产品.png') no-repeat center center;
background-size: 100% 100%;
}
}
\ No newline at end of file
/*
* @Title:新产品动态
* @Author: hongmye
* @Date: 2023-12-26 18:34:42
*/
import React, { useMemo, useEffect, useState, memo } from 'react';
import { Tooltip, message } from 'antd';
import classNames from 'classnames';
import DataCarousel from '../DataCarousel';
import styles from './index.less';
const RightItem = props => {
const { listData, handToProduct } = props;
const toPage = row => {
if (!row['产品地址']) return message.warning('未配置产品地址,请联系管理人员');
if (!row['产品地址'].includes('https')) return message.warning('产品地址配置错误,请联系管理人员');
if (row['产品地址'] && row['产品地址'].includes('https')) {
handToProduct(row['产品地址'], row['产品名称']);
}
};
const renderRow = (row, index) => {
const rIndex = `r_${index % 5}`;
return (
<div
className={styles.r_list_item}
key={row['产品名称']}
name={row.ID === 0 ? '敬请期待' : ''}
rIndex={rIndex}
type={row['产品地址'] && row['产品地址'].includes('https') ? 'jump' : 'none'}
onClick={() => toPage(row)}
>
<div className={styles.r_list_item_title}>{row['产品名称']}</div>
<div className={styles.r_list_item_tip} />
</div>
);
};
return (
<div className={classNames(styles.right_item, 'right_item')}>
<div className={styles.r_title_wrap}>
<div className={styles.r_title_sub}>熊猫智慧水务</div>
<div className={styles.r_title}>新产品动态:</div>
</div>
<div className={styles.r_list}>
<DataCarousel
gap={1}
autoplay={5000}
itemHeight={350}
list={listData}
renderItem={renderRow}
config={{
loop: false,
slidesPerView: 6,
}}
/>
</div>
</div>
);
};
export default memo(RightItem);
@imgSrc: '@/assets/images/demonstration';
.right_item {
.r_title_wrap {
width: 100%;
height: 123px;
background: url('@{imgSrc}/全行业软硬件系统解决方案.png') no-repeat center center;
background-size: 100% 100%;
padding: 30px 0 0 25px;
.r_title_sub {
background: url('@{imgSrc}/tip.png') no-repeat left center;
background-size: 35px 36px;
padding-left: 35px;
font-size: 16px;
height: 36px;
line-height: 36px;
}
.r_title {
font-size: 22px;
font-family: Microsoft YaHei;
font-weight: bold;
color: #FFFFFF;
padding-left: 5px;
line-height: 32px;
letter-spacing: 1px;
background: linear-gradient(0deg, #92D2FF 0%, #FFFFFF 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.r_list {
height: 350px;
overflow: hidden;
.r_list_item[type='jump']:hover {
// bottom: -8px;
filter: brightness(160%)
}
.r_list_item[type='jump']:hover .r_list_item_tip {
opacity: 1;
}
.r_list_item:not(:last-child) {
margin-bottom: 10px;
}
.r_list_item {
width: 370px;
height: 48px;
font-size: 16px;
text-align: center;
font-weight: bold;
line-height: 46px;
position: relative;
left: 0;
transition: all 0.3s;
}
.r_list_item[type='jump'] {
cursor: pointer;
}
.r_list_item[type='jump']:active {
opacity: 0.8;
}
.r_list_item_tip {
width: 37px;
height: 40px;
background: url('@{imgSrc}/新产品动态_选中.png') no-repeat center center;
background-size: 100% 100%;
position: absolute;
transition: all 0.3s;
top: 0;
left: -30px;
opacity: 0;
}
.r_list_item[rIndex='r_1'] {
background: url('@{imgSrc}/bg1.png') no-repeat left center;
background-size: 100% 100%;
}
.r_list_item[rIndex='r_2'] {
background: url('@{imgSrc}/bg2.png') no-repeat left center;
background-size: 100% 100%;
}
.r_list_item[rIndex='r_3'] {
background: url('@{imgSrc}/bg3.png') no-repeat left center;
background-size: 100% 100%;
}
.r_list_item[rIndex='r_4'] {
background: url('@{imgSrc}/bg4.png') no-repeat left center;
background-size: 100% 100%;
}
.r_list_item[rIndex='r_0'] {
background: url('@{imgSrc}/bg5.png') no-repeat left center;
background-size: 100% 100%;
}
.r_list_item[name='敬请期待'] {
background: url('@{imgSrc}/敬请期待.png') no-repeat left center;
background-size: 100% 100%;
}
}
}
:global {
.right_item {
.swiper-wrapper {
.swiper-slide {
width: 100%;
height: 58px;
}
}
}
}
\ No newline at end of file
/*
* @Title:
* @Author: hongmye
* @Date: 2023-12-26 18:34:42
*/
import { Button } from 'antd';
import React, { useMemo, useEffect, useRef, useState, forwardRef, useImperativeHandle } from 'react';
import classNames from 'classnames';
import SwiperCore, { Autoplay, Mousewheel, Navigation, Pagination, EffectCoverflow } from 'swiper/core';
import { Swiper, SwiperSlide } from 'swiper/react';
import leftIcon from '@/assets/images/demonstration/arrow_left.png';
import rightIcon from '@/assets/images/demonstration/arrow_right.png';
import { schemeData } from '../configData';
import 'swiper/components/navigation/navigation.min.css';
import 'swiper/components/pagination/pagination.min.css';
import 'swiper/components/effect-coverflow/effect-coverflow.min.css';
import 'swiper/swiper.min.css';
import styles from './index.less';
const autoplay = 15000;
SwiperCore.use([Autoplay, Pagination, Navigation, Mousewheel, EffectCoverflow]);
const VideoItem = (props, ref) => {
const { selectKey = '', setSelectKey, showContent } = props;
const swiperRef = useRef(null);
const timer = useRef(null);
const [showVideo, setShowVideo] = useState(false);
const onSlideToLoop = index => {
if (swiperRef.current) {
swiperRef.current.slideToLoop(index);
}
};
useImperativeHandle(ref, () => ({
onSlideToLoop,
}));
const listData = schemeData.filter(i => !!i.video);
const renderItem = (row, index) => (
<div className={styles.video_box} key={row.title}>
<div className={styles.video_tip} type={row.title}>
<span />
{row.title}
</div>
<div className={styles.video_wrap}>
{showVideo ? <video autoPlay="autoPlay" muted controls src={row.video} loop /> : null}
</div>
</div>
);
const onSwiper = type => {
if (swiperRef.current) {
if (type === 'left') {
swiperRef.current.slidePrev();
}
if (type === 'right') {
swiperRef.current.slideNext();
}
}
};
const onSlideChange = e => {
const title = listData[e.realIndex]?.title;
if (title && title !== selectKey) {
setSelectKey(title);
}
if (e.$el[0]) {
const videoDom = e.$el[0].querySelector('video');
videoDom?.play && videoDom.play();
}
};
useEffect(() => {
if (showContent) {
timer.current = setTimeout(() => {
setShowVideo(true);
}, 800);
}
return () => {
if (timer.current) {
clearTimeout(timer.current);
timer.current = null;
}
};
}, [showContent]);
return (
<div className={classNames(styles.video_list, 'dt_video_list')}>
<Swiper
slidesPerView="auto"
autoplay={{
delay: autoplay,
disableOnInteraction: false,
}}
loop
height={450}
direction="horizontal"
onSlideChange={onSlideChange}
effect="coverflow"
coverflowEffect={{
rotate: 50,
stretch: 10,
depth: 60,
modifier: 2,
slideShadows: false,
}}
mousewheel
onSwiper={swiper => {
swiperRef.current = swiper;
// 鼠标悬浮暂停效果
swiper.$el[0].addEventListener('mouseover', () => swiper.autoplay.stop());
// 鼠标移开后继续自动滚屏效果
swiper.$el[0].addEventListener('mouseleave', () => {
listData.length > 1 && autoplay * 1 ? swiper.autoplay.start() : '';
});
}}
>
{listData.map((item, index) => (
<SwiperSlide key={index} virtualIndex={index} onClick={() => {}}>
{renderItem(item, index + 1)}
</SwiperSlide>
))}
</Swiper>
<div className={classNames(styles.swiper_btn, styles.swiper_left)} onClick={() => onSwiper('left')}>
<img src={leftIcon} alt="" />
</div>
<div className={classNames(styles.swiper_btn, styles.swiper_right)} onClick={() => onSwiper('right')}>
<img src={rightIcon} alt="" />
</div>
</div>
);
};
export default forwardRef(VideoItem);
@imgSrc: '@/assets/images/demonstration';
.video_list {
width: 100%;
padding: 0 30px;
height: calc(100% - 25px);
margin-top: 25px;
background: url('@{imgSrc}/视频bg2.png') no-repeat center center;
background-size: calc(100% - 30px) auto;
position: relative;
.swiper_btn {
position: absolute;
width: 36px;
height: 40px;
cursor: pointer;
z-index: 100;
img {
width: 100%;
}
}
.swiper_btn:active {
opacity: 0.8;
}
.swiper_left {
left: 20px;
top: 50%;
transform: translateY(-50%);
}
.swiper_right {
right: 20px;
top: 50%;
transform: translateY(-50%);
}
.video_box {
width: 100%;
height: 450px;
padding: 0 28px 20px;
background: url('@{imgSrc}/视频bg.png') no-repeat center center;
background-size: calc(100% - 56px) 100%;
display: flex;
justify-content: center;
align-items: center;
position: relative;
overflow: hidden;
}
.video_wrap {
position: relative;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
border-radius: 10px;
padding: 10px;
video {
object-fit: fill;
width: 100%;
height: 100%;
border-radius: 10px;
}
}
.video_tip {
width: 123px;
height: 32px;
background: url('@{imgSrc}/供水产品标题.png') no-repeat center center;
background-size: 100% 100%;
padding: 5px 0 0 15px;
font-weight: bold;
position: absolute;
left: 28px;
top: 0;
z-index: 12;
span {
display: inline-block;
width: 10px;
height: 10px;
border: 3px solid #FFFFFF;
box-shadow: 0px 2px 3px 0px rgba(9, 23, 55, 0.3);
border-radius: 50%;
margin-right: 10px;
}
}
.video_tip[type='水利产品'] {
background: url('@{imgSrc}/水利产品标题.png') no-repeat center center;
background-size: 100% 100%;
}
.video_tip[type='排水产品'] {
background: url('@{imgSrc}/排水产品标题.png') no-repeat center center;
background-size: 100% 100%;
}
.video_tip[type='节水产品'] {
background: url('@{imgSrc}/节水产品标题.png') no-repeat center center;
background-size: 100% 100%;
}
}
:global {
.dt_video_list {
.swiper-slide {
width: 100%;
}
.swiper-container {
width: 100%;
height: 100%;
}
}
}
\ No newline at end of file
/* eslint-disable prettier/prettier */
/*
* @Title:
* @Author: hongmye
* @Date: 2024-01-30 15:29:09
*/
import gongshuiVideo from '@/assets/videos/供水.mp4';
import shuiliVideo from '@/assets/videos/水利.mp4';
import paishuiVideo from '@/assets/videos/排水.mp4';
import jieshuiVideo from '@/assets/videos/节水.mp4';
const schemeData = [
{
title: '供水产品',
background: '',
url: '',
video: gongshuiVideo,
type: '供水',
},
{
title: '水利产品',
background: '',
url: '',
video: shuiliVideo,
type: '水利',
},
{
title: '排水产品',
background: '',
url: '',
video: paishuiVideo,
type: '排水',
},
{
title: '节水产品',
background: '',
url: '',
video: jieshuiVideo,
type: '能源',
},
];
const platformData = [
{
title: '统一接入',
subTitle: '汇聚水务全域数据',
top: '3网',
icon: '统一接入.png',
flex: 350,
url: '',
blank: true,
},
{
title: '融合治理',
subTitle: '夯实数据价值化路径',
top: '1库',
icon: '融合治理.png',
flex: 350,
url: '',
blank: true,
},
{
title: '熊猫智慧水务系列软件产品',
icon: '',
isCenter: true,
flex: 464,
url: '',
},
{
title: '业务集成',
subTitle: '贯通业务一站服务',
top: '5中心',
icon: '业务集成.png',
flex: 350,
url: '',
blank: true,
},
{
title: '智慧应用',
subTitle: '赋能水务新质生产力',
top: 'N应用',
icon: '智慧应用.png',
flex: 350,
url: '',
blank: true,
},
];
export { schemeData, platformData };
/*
* @Title:
* @Author: hongmye
* @Date: 2023-01-10 11:18:55
*/
import { useCallback, useEffect, useRef, useState } from 'react';
const useFullScreen = needFullscreen => {
const [isFullscreen, setIsFullscreen] = useState(!!document.fullscreenElement);
const ref = useRef();
useEffect(() => {
const handleToggleFullScreen = () => {
setIsFullscreen(!!document.fullscreenElement);
};
document.addEventListener('fullscreenchange', handleToggleFullScreen);
return () => {
document.removeEventListener('fullscreenchange', handleToggleFullScreen);
};
}, []);
const handleFullScreen = useCallback(() => {
ref.current?.requestFullscreen && ref.current?.requestFullscreen();
}, []);
const handleExitFullScreen = useCallback(() => {
document.exitFullscreen();
}, []);
useEffect(() => {
needFullscreen && handleFullScreen();
}, [handleFullScreen, needFullscreen]);
return [ref, isFullscreen, handleFullScreen, handleExitFullScreen];
};
export default useFullScreen;
This diff is collapsed.
@imgSrc: '@/assets/images/demonstration';
.demonstration {
height: 100%;
width: 100%;
overflow: hidden;
display: flex;
background:rgba(8, 33, 77, 1) url('@{imgSrc}/背景.png') no-repeat center center;
background-size: 100% 100%;
position: relative;
font-size: 14px;
font-family: Microsoft YaHei;
font-weight: 400;
color: #FFFFFF;
align-items: center;
justify-content: center;
.iframeExitIcon {
position: absolute;
top: 0;
left: -45px;
display: flex;
height: 44px;
width: 44px;
background: rgba(28, 94, 180, 0.95);
border-radius: 0 7px 7px 0;
flex-direction: column;
justify-content: space-around;
align-items: center;
font-size: 12px;
transition: all 0.2s;
padding: 3px 0;
img {
width: 17px;
height: 12px;
}
}
.iframeExit:hover {
.iframeExitIcon {
left: 0;
}
.iframeBackLeft {
left: -15px;
}
}
.iframeBackLeft {
position: absolute;
top: 0;
left: 0;
width: 14px;
height: 44px;
background: rgba(28, 94, 180, 0.95);
border-radius: 0 7px 7px 0;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s;
img {
width: 6px;
height: 11px;
}
}
.iframeExit {
width: 44px;
height: 44px;
position: absolute;
top: 4px;
left: 0;
color: #FFF;
cursor: pointer;
user-select: none;
position: absolute;
z-index: 110;
}
.demonstrationLoad {
width: 100%;
height: 100%;
position: absolute;
display: flex;
align-items: center;
justify-content: center;
top: 0;
left: 0;
z-index: 1080;
padding-bottom: 50px;
background-color: rgba(0, 0, 0, 0.6);
}
.demonstrationWrap {
height: 100%;
width: 100%;
overflow: hidden;
transform-origin: left top;
position: absolute;
left: 50%;
top: 50%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.CV_exit {
cursor: pointer;
position: absolute;
right: 0;
top: 0;
z-index: 10;
}
.top {
color: #fff;
display: flex;
justify-content: space-between;
align-items: flex-end;
flex: none;
.top_l {
width: 376px;
height: 35px;
background: url('@{imgSrc}/top_left.png') no-repeat center center;
background-size: 100% 100%;
text-align: center;
line-height: 35px;
letter-spacing: 4px;
font-weight: bold;
font-size: 18px;
color: #C9E2FC;
text-shadow: 0px 6px 6px #001333;
font-style: italic;
span {
color: #FFE44D;
}
}
.top_r {
width: 281px;
height: 35px;
.top_r_text {
width: 100%;
height: 35px;
line-height: 35px;
padding-left: 60px;
background: url('@{imgSrc}/引领中国智慧水务.png') no-repeat center center;
background-size: 100% 100%;
font-size: 15px;
letter-spacing: 3px;
}
}
.top_c {
padding-top: 15px;
.top_c_title {
font-size: 34px;
font-weight: bold;
padding-left: 80px;
color: #FFFFFF;
letter-spacing: 1px;
text-shadow: 0 8px 8px rgba(30, 64, 121, 0.35);
background: url('@{imgSrc}/熊猫图标.png') no-repeat left center;
background-size: 65px;
position: relative;
top: 10px;
line-height: 1;
}
}
}
.row {
padding: 0 33px;
display: flex;
overflow: hidden;
z-index: 10;
flex: none;
.row_l {
width: 372px;
flex: none;
}
.row_r {
width: 372px;
flex: none;
}
.row_c {
flex: 1;
}
}
.center_wrap {
position: relative;
flex: none;
}
.center_tip {
position: absolute;
left: 50%;
top: -38px;
transform: translateX(-50%);
width: 130px;
height: 82px;
z-index: 0;
background: url('@{imgSrc}/箭头.png') no-repeat center/100% 100%;
}
.center {
z-index: 10;
display: flex;
padding: 0 28px 0px;
width: 100%;
overflow: hidden;
line-height: 1;
align-items: flex-end;
position: relative;
top: -6px;
.center_title {
height: 89px;
padding-top: 43px;
text-align: center;
background: url('@{imgSrc}/熊猫智慧水务系列支撑能力平台.png') no-repeat center/100% 100%;
z-index: 10;
div {
font-size: 22px;
font-weight: bold;
color: #FFFFFF;
background: linear-gradient(0deg, #92D2FF 0%, #FFFFFF 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.center_col {
height: 93px;
font-size: 15px;
font-weight: bold;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
top: 0;
transition: all 0.3s;
margin-bottom: 5px;
position: relative;
top: 18px;
.center_item {
display: flex;
padding-left: 30px;
align-items: center;
font-size: 17px;
font-weight: bold;
span {
font-size: 16px;
font-weight: normal;
}
}
img {
width: 46px;
height: 46px;
}
.center_top {
height: 17px;
width: 229px;
text-align: center;
line-height: 17px;
font-weight: bold;
font-size: 12px;
color: #FFFFFF;
}
.center_item {
position: relative;
width: 350px;
height: 76px;
display: flex;
align-items: center;
padding-bottom: 20px;
background: url('@{imgSrc}/center_bg.png') no-repeat center/100% 100%;
}
}
.center_item_tip {
position: absolute;
width: 36px;
height: 4px;
background: url('@{imgSrc}/pointpoint.png') no-repeat center/100% 100%;
right: -18px;
top: center;
}
.center_col[type='统一接入'] {
.center_top {
background: url('@{imgSrc}/统一接入_top.png') no-repeat center/100% 100%;
}
}
.center_col[type='融合治理'] {
.center_top {
background: url('@{imgSrc}/融合治理_top.png') no-repeat center/100% 100%;
}
}
.center_col[type='业务集成'] {
.center_top {
background: url('@{imgSrc}/业务集成_top.png') no-repeat center/100% 100%;
}
}
.center_col[type='智慧应用'] {
.center_top {
background: url('@{imgSrc}/智慧应用_top.png') no-repeat center/100% 100%;
}
}
}
.bottom {
flex: none;
height: 290px;
overflow: hidden;
}
}
.loadingWrap {
position: absolute;
width: 100%;
height: 100%;
position: absolute;
display: flex;
align-items: center;
justify-content: center;
top: 0;
left: 0;
z-index: 1080;
padding-bottom: 50px;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment