Commit 916ea520 authored by 崔佳豪's avatar 崔佳豪

feat: 新增新产品引导页

parent e2ee9bcc
Pipeline #54011 passed with stages
......@@ -5,7 +5,8 @@ export const API = {
GET_DATA_DICTIONARY_LIST:
'/CityInterface/Services/CityServer_WorkFlow/REST/WorkFlowREST.svc/GetDataDictionaryList',
GET_ACCOUNT_PAGELIST: `/CityInterface/Services/CityServer_CaseManage/REST/CaseManageREST.svc/GetAccountPageList`,
// GET_ACCOUNT_PAGELIST: `/CityInterface/Services/CityServer_CaseManage/REST/CaseManageREST.svc/GetAccountPageList`,
GET_ACCOUNT_PAGELIST: `/PandaWorkFlow/WorkFlow/AccountManage/GetAccountPageList`,
// 云平台使用分析
LOGIN_STATISTIC: `${portalURL}/OMManage/LoginStatisticServer`,
......@@ -23,7 +24,7 @@ const services = {
getAccountPageList: {
url: API.GET_ACCOUNT_PAGELIST,
method: constants.REQUEST_METHOD_GET,
method: constants.REQUEST_METHOD_POST,
type: constants.REQUEST_HTTP,
},
......
......@@ -68,6 +68,13 @@ const BootPage = props => {
(event, type) => {
event.persist();
event.preventDefault();
// 新增熊猫新产品引导页
if(type === '熊猫新产品') {
props.history.push(`/cloud/introduction/newproducts`);
return;
}
setLoadding(true);
const config = props.global;
// const loginAction = new LoginAction(props);
......
import React from 'react';
import classnames from 'classnames';
import styles from './index.less';
import cover from './images/default.png';
import tagHot from './images/hot.png';
import tagNew from './images/new.png';
const assetPath = `${window.location.origin}/PandaWorkFlow/WorkFlow/AccountManage/DownloadFiles`;
const tags = {
'New': tagNew,
'Hot': tagHot,
}
const Card = ({onCardClick, ...props}) => {
const { promoteTip, config } = props;
return (
<div className={styles.card} onClick={e => onCardClick(e, props)}>
{ promoteTip ? <img className={styles.tag} src={tags[promoteTip]}/> : null }
<div className={styles.face}>
<img src={config && config['封面图'] ? `${assetPath}?filePath=${config['封面图']}` : cover} />
<div className={styles['card-footer']}>
<p className={classnames(styles['card-title'], styles['nowrap-text'])}>{config && config['标题']}</p>
<p className={classnames(styles['card-desc'], styles['nowrap-text'])}>{config && config['副标题']}</p>
</div>
</div>
{
config && config['介绍图'] ? (
<div className={styles.back}>
<img src={`${assetPath}?filePath=${config['介绍图']}`}/>
</div>
) : null
}
</div>
);
};
export default Card;
import React from 'react';
import styles from './index.less';
import Card from './Card';
import classnames from 'classnames';
const Panel = ({ products = [], onCardClick, pageIndex, pageSize }) => {
return (
<div className={classnames(styles.panel)} num={pageIndex == 0 ? products.length : pageSize}>
{ products.map((item, index) => <Card key={index} {...item} onCardClick={onCardClick}/>)}
</div>
);
};
export default Panel;
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.
import React, { useState, useEffect, useRef } from 'react';
import { Carousel, Spin, notification } from 'antd';
import { connect } from 'react-redux';
import { chunk } from 'lodash';
import classnames from 'classnames';
import SecurityLayout from '@/layouts/SecurityLayout';
import styles from './index.less';
import Panel from './Panel';
import { appService, cloudService } from '@/api'
import { actionCreators } from '@/containers/App/store';
import { defaultApp } from '@/micro';
import LoginAction from '../../../user/login/login';
import Cookies from 'js-cookie';
import { decode, encode } from 'js-base64';
import title from './images/title.png';
/**
* 熊猫新产品引导页
*/
const pageSize = 6;
const NewProducts = props => {
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(false);
const ref = useRef();
// 获取卡片数据
useEffect(() => {
setLoading(true);
cloudService.getAccountPageList({
pageIndex: 1,
pageSize: 100,
sortFields: '排序',
direction: 'desc',
accountName: '演示_熊猫新产品',
// info: searchInfo,
// queryWhere:
// " and (登录时间 >= '" + stime + "' and 登录时间 <= '" + etime + "')",
ignoreSite: true,
}).then(res => {
setLoading(false);
const configData = JSON.parse(res.data.jsonData || '[]');
const configMap = configData.reduce((pre, item, index) => {
item['排序'] = index
if(item.site && item['是否显示'] === '是') {
pre[item.site] = item;
}
return pre;
}, {});
const Groups = props.global?.userInfo?.Groups ?? [];
const data = Groups
.filter(item => item.industry === '熊猫新产品' && configMap[item.site])
.map(item => ({ ...item, config: configMap[item.site] }));
data.sort((a,b) => a.config['排序'] - b.config['排序']);
setProducts(chunk(data, pageSize));
}).catch(err => {
setLoading(false);
notification.error({ message: '提示', duration: 3, description: '获取产品信息错误' })
})
}, []);
// 卡片点击事件
const handleClick = (e, data) => {
setLoading(true);
appService
.getUserInfo({
token: props.global.token,
subOID: 'subOID',
site: data.site,
ignoreSite: true,
})
.then(res => {
// 重置一些环境配置
const config = { ...props.global };
config.uiwidgets = [];
config.widgets = [];
config.allWidgets = [];
config.userInfo = res;
props.updateConfig && props.updateConfig(config);
// 默认有个上次记住的登入企业,存在印象。这里把cookie和localStorage中的都重新设置一下
const date = new Date();
date.setTime(date.getTime() + 24 * 60 * 60 * 1000);
const encodeSite = encode(encodeURIComponent(data.site));
localStorage.setItem('loginSite', JSON.stringify({[config.token]: data.site}))
Cookies.set('site', encodeSite, {
expires: date,
path: '/',
});
const loginAction = new LoginAction({...props, global: config});
// props.instance && props.instance.updateConfig(config);
loginAction && loginAction.getUserInfoAndConfig('', true, '熊猫新产品');
});
};
// toggleIndustry 事件
useEffect(() => {
// 借用引导页的触发逻辑进入系统
const handleToggleIndustry = event => {
setLoading(false);
props.history.push(`/?client=${props.global.client}`);
defaultApp();
// window.share.event.emit('triggerMicro', props.global);
props.updateCurrentIndex(0);
};
window.share.event.on('toggleIndustry', handleToggleIndustry);
return () => {
window.share.event.removeListener('toggleIndustry', handleToggleIndustry);
};
}, [window.share.event, props]);
// 卡片左右切换
const onPrev = e => ref.current && ref.current.prev();
const onNext = e => ref.current && ref.current.next();
return (
<SecurityLayout>
<div className={styles.newproducts}>
<Spin spinning={loading}>
<div className={styles.page}>
<h1>
<img className={styles['title-img']} src={title} alt="熊猫智慧水务新产品"/>
</h1>
<div className={styles.container}>
<Carousel ref={ref}>
{ products.map((item, index) => <Panel key={index} products={item} pageIndex={index} pageSize={pageSize} onCardClick={handleClick}/>) }
</Carousel>
{
products && products.length > 1 && (
<>
<div className={classnames(styles['cus-arrow'], styles['cus-arrow-prev'])} title="上一页" onClick={onPrev}></div>
<div className={classnames(styles['cus-arrow'], styles['cus-arrow-next'])} title="下一页" onClick={onNext}></div>
</>
)
}
</div>
</div>
</Spin>
</div>
</SecurityLayout>
);
};
const mapStateToProps = (state) => ({
global: state.getIn(['global', 'globalConfig']),
});
const mapDispatchToProps = (dispatch) => ({
updateConfig(config) {
dispatch(actionCreators.getConfig(config));
},
updateCurrentIndex(index) {
dispatch(actionCreators.updateCurrentIndex(index));
},
});
export default connect(mapStateToProps, mapDispatchToProps)(NewProducts);
\ No newline at end of file
@wh-scale: 1080/1920;
.nowrap-text {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.newproducts {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
background-position: center;
background-size: 100% 100%;
background-repeat: no-repeat;
background-image: url('./images/bg.png');
font-size: 20px;
.page {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-evenly;
height: 100%;
}
:global {
.@{ant-prefix}-spin-nested-loading,
.@{ant-prefix}-spin-container {
width: 100%;
height: 100%;
overflow: hidden;
}
.@{ant-prefix}-spin {
max-height: unset !important;
}
.@{ant-prefix}-carousel {
.slick-slider {
.slick-dots-bottom {
display: none !important;
}
}
}
}
p,
h1 {
font-size: 20px;
margin-bottom: 0;
}
.title-img {
width: 35.6em;
}
.container {
min-height: 396px;
width: 100%;
position: relative;
}
.cus-arrow {
width: 2em;
height: 2em;
position: absolute;
top: 50%;
transform: translateY(-50%);
background-position: center;
background-size: 100% 100%;
background-repeat: no-repeat;
cursor: pointer;
&.cus-arrow-prev {
left: 2em;
background-image: url('./images/arrow_left.png');
}
&.cus-arrow-next {
right: 2em;
background-image: url('./images/arrow_right.png');
}
}
}
.panel {
font-size: 20px;
width: 100%;
height: 100%;
// padding: 0 200px;
display: flex;
align-items: center;
justify-content: flex-start;
flex-wrap: wrap;
gap: 1em;
margin: 0 auto;
width: 24em;
&[num="2"],
&[num="4"] {
width: (24em * 2 + 1em);
}
&[num="3"],
&[num="5"],
&[num="6"] {
width: (24em * 3 + 2em);
}
&[num="1"],
&[num="2"],
&[num="3"] {
margin-bottom: 5em;
}
}
.card {
position: relative;
transition: all 0.2s;
overflow: hidden;
cursor: pointer;
.tag {
width: 3em;
position: absolute;
left: 8px;
top: 6px;
}
.face {
img {
user-select: none;
width: 24em;
height: (24em * @wh-scale);
}
.card-footer {
background-color: #FFF;
font-family: PingFang SC;
color: #000000;
text-align: center;
height: 3.2em;
.card-title {
font-size: 1em;
font-weight: bold;
line-height: 1.8;
}
.card-desc {
font-size: 0.7em;
line-height: 2;
}
}
}
.back {
pointer-events: none;
position: absolute;
left: 0;
top: 0;
background-color: lightblue;
width: 100%;
height: 100%;
overflow: hidden;
opacity: 0;
transform: translateY(100%);
transition: all 0.5s;
transition-delay: 0.2s;
& > img {
width: 100%;
height: 100%;
}
}
&:hover {
transform: scale(1.05);
.back {
opacity: 1;
transform: translateY(0);
}
}
}
@media screen and (max-width: 1440px) {
.newproducts {
p, h1 {
font-size: 14px;
}
.cus-arrow {
&.cus-arrow-prev {
left: 15px;
}
&.cus-arrow-next {
right: 15px;
}
}
}
.panel {
font-size: 14px;
}
}
@media screen and (min-width: 1440px) and (max-width: 1600px) {
.newproducts {
p, h1 {
font-size: 16px;
}
.cus-arrow {
&.cus-arrow-prev {
left: 15px;
}
&.cus-arrow-next {
right: 15px;
}
}
}
.panel {
font-size: 16px;
}
}
\ No newline at end of file
......@@ -807,7 +807,13 @@ class Login {
)
: null;
if (userInfo) {
if (industry === '熊猫新产品' && site) {
self.globalConfig.userInfo = {
site: decodeURIComponent(decode(site)),
Groups: self.globalConfig.userInfo.Groups,
};
self.updateConfig && self.updateConfig(self.globalConfig);
} else if (userInfo) {
self.globalConfig.userInfo = {
site: userInfo.site ? userInfo.site : null,
Groups: self.globalConfig.userInfo.Groups,
......
......@@ -5,6 +5,7 @@ import { dynamic } from '@wisdom-utils/runtime';
import BasicLayout from '../layouts/BasicLayout';
import BootPage from '../pages/bootpage';
import UsingAnalysis from '../pages/cloud/analysis/using';
import NewProducts from '../pages/cloud/introduction/newproducts';
import CommonMenu from '../pages/commonMenu';
import Iframe from '../pages/iframe';
import Login from '../pages/user/login';
......@@ -48,6 +49,10 @@ export const dyRoutes = (routes, layout, theme) => {
path: '/cloud/analysis/using',
component: UsingAnalysis,
},
{
path: '/cloud/introduction/newproducts',
component: NewProducts,
},
{
path: '/',
// component: theme === 'lightgreen.css' ? HNLayout : BasicLayout,
......
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