Files
fe_service_ebtp_frontend/src/pages/PartyMemberTopic/Home/index.tsx
2022-06-28 16:48:36 +08:00

534 lines
24 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useEffect, useRef, useState } from 'react';
import './index.less';
import { Button, Carousel, Col, Divider, Input, List, message, Modal, Radio, RadioChangeEvent, Row, Spin, Tooltip } from 'antd';
import * as echarts from 'echarts';
import Marquee from 'react-fast-marquee';
import topic_header from '@/assets/topic/topic_header.jpg'
import topic_activity_logo from '@/assets/topic/topic_activity_logo.png'
import topic_red_flag from '@/assets/topic/topic_red_flag.png'
import topic_other from '@/assets/topic/topic_other.png'
import topic_project_picture from '@/assets/topic/topic_project_picture.jpg'
import topic_bottom_button from '@/assets/topic/topic_bottom_button.png'
import topic_right_material from '@/assets/topic/topic_right_material.png'
import topic_partymember from '@/assets/topic/topic_partymember.png'
import topic_partybranch from '@/assets/topic/topic_partybranch.png'
import topic_totalamount from '@/assets/topic/topic_totalamount.png'
import topic_totalnumber from '@/assets/topic/topic_totalnumber.png'
import topic_commodity from '@/assets/topic/topic_commodity.png'
import topic_protocol from '@/assets/topic/topic_protocol.png'
import topic_header_img from '@/assets/topic/topic_header_img.png'
import topic_banner_default from '@/assets/topic/topic_banner_default.jpg'
import topic_activity_default from '@/assets/topic/topic_activity_default.jpg'
import { getHomeActivity, getHomeBanner, getHomeContact, getHomeGraceful, getHomeProject, getHomeRight, submitAdvice } from './service';
import { formatTime, getImageUrl, isEmpty, isNotEmpty } from '../utils';
//卡片头
const LeftCardTop = (props: any) => {
return (
<>
<div className='left-card-top'>
<div>
<span className='left-card-title'>{props.title}</span>
<img src={topic_red_flag} className='left-card-flag' />
</div>
{props.url && <div onClick={() => window.open(props.url)}>
<span className='left-card-other'></span>
<img src={topic_other} className='left-card-otherimg' />
</div>}
</div>
<Divider className='left-card-divider' />
</>
)
}
//右侧专业线标题
const RightDisplayTitle = (props: any) => {
return (
<div className='right-display-title'>
{props.title}
</div>
)
}
//右侧专业线内容
const RightDisplayContent = (props: any) => {
const displayContentClick = () => {
if (props.index == 0) {//党员数量
window.open("/partyMemberTopic/personInfor");
} else if (props.index == 1) {//党支部数量
window.open("/partyMemberTopic/partyBranch");
}
}
return (
props.data?.length > 0 ? (
<div className={props.index == 0 || props.index == 1 ? 'right-display-content right-display-content-pointer' : 'right-display-content'} onClick={() => displayContentClick()}>
<img src={props.img} className='right-display-content-img' />
<div className='right-display-content-right'>
<div className='right-display-content-title'>
<span>{props.data[props.index].dataName}</span>
{props.data[props.index].dataCompare != null && <span className='right-display-content-percentage'>
<span></span>
{props.data[props.index].dataCompare[0] == '+' ? (
<span className='right-display-content-percentage-increase'>{props.data[props.index].dataCompare} </span>
) : (
<span className='right-display-content-percentage-reduce'>{props.data[props.index].dataCompare} </span>
)}
</span>}
</div>
<div className='right-display-content-content'>
<span className={`right-display-content-number ${props.color}`}>{props.data[props.index].dataValue}</span>
<span className='right-display-content-unit'>{props.data[props.index].dataType}</span>
</div>
</div>
</div>
) : null
)
}
//右侧图表内容
const RightGraphContent = (props: any) => {
const random = Math.random().toString();
useEffect(() => {
type EChartsOption = echarts.EChartsOption;
const chartDom = document.getElementById(random)!;
const myChart = echarts.init(chartDom);
const option: EChartsOption = {
tooltip: {
trigger: 'item'
},
series: [
{
name: props.name,
type: 'pie',
radius: '90%',
color: ['#EE6666', '#FAC858', '#73C0DE', '#91CC75', '#5470C6', '#FC8452', '#9A60B4', '#3BA272'],
data: props.data,
label: {
formatter: props.type != null ? `{b}\n\n{c}${props.type} {d}%` : '{b}',
fontSize: '90%',
color: '#fff',
position: 'inner',
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
myChart.setOption(option);
}, [])
return (
<div id={random} style={{ width: '100%', height: '100%' }}></div>
)
}
//活动联系人卡片内容
const BottomCardContent = (props: any) => {
return (
<Col span={6}>
<div className='bottom-card'>
<div className='bottom-card-flex'>
<div className='bottom-card-title'>
<Tooltip placement="topLeft" title={`${props.data.remark} ${props.data.contactName}`}>
<span>{props.data.contactName}</span>
{isNotEmpty(props.data.remark) && <span className='bottom-card-title-type'>({props.data.remark})</span>}
</Tooltip>
</div>
<img src={topic_bottom_button} onClick={() => props.onClick()} />
</div>
<div className='bottom-card-content'>
<div>{props.data.contactEmail}</div>
<div>{props.data.contactMobiphone}</div>
<div>{props.data.contactDepartment}</div>
</div>
</div>
</Col>
)
}
//活动联系人-我要提意见Modal
const CommentModal = (props: any) => {
const { TextArea } = Input;
const [modalLoading, setModalLoading] = useState<boolean>(false);
const textRef = useRef<any>(null);
const radioRef = useRef<any>(null);
const onRadioChange = (e: RadioChangeEvent) => {
radioRef.current = e.target.value;
};
const onTextChange = (e: any) => {
textRef.current = e.target.value;
};
const onCancel = () => {
props.closeModal();
textRef.current = null;
radioRef.current = null;
}
const onSubmit = async () => {
if (isEmpty(textRef.current)) {
message.info("请先输入意见内容");
return;
}
setModalLoading(true);
const params = {
contactName: props.data?.contactName,
contactId: props.data?.contactId,
suggestionType: radioRef.current,
suggestionContent: textRef.current,
}
await submitAdvice(params).then(res => {
if (res?.code == 200) {
message.success("提交成功");
onCancel();
}
}).finally(() => {
setModalLoading(false);
})
}
return (
<Modal
className='topic-home-modal'
title={
<div className='bottom-modal-header'>
<img src={topic_header_img} />
<div className='bottom-modal-headertext'>
<span></span>
</div>
</div>
}
visible={props.visible}
onCancel={onCancel}
destroyOnClose
closable={false}
footer={null}
centered
maskStyle={{ backgroundColor: 'rgba(0, 0, 0, 0.3)' }}
width={450}
>
<Spin spinning={modalLoading}>
<div className='bottom-modal-body'>
<div className='radio-group'>
<Radio.Group onChange={onRadioChange} defaultValue={"1"}>
<Radio value="1" className="radio-content"></Radio>
<Radio value="2" className="radio-content"></Radio>
<Radio value="3" className="radio-content"></Radio>
<Radio value="4" className="radio-content"></Radio>
</Radio.Group>
</div>
<TextArea
rows={11}
className='bottom-modal-textarea'
maxLength={50}
defaultValue={''}
onChange={onTextChange}
placeholder="在这里输入我要提出的意见最多输入50字"
/>
<div className='bottom-modal-submit'>
<span className='submit-text'>{props.data?.contactDepartment}{props.data?.contactName}</span>
<div>
<Button className='submit-cancelbutton' onClick={onCancel}>
</Button>
<Button type='primary' className='submit-button' onClick={onSubmit}>
</Button>
</div>
</div>
</div>
</Spin>
</Modal>
)
}
const Home: React.FC<{}> = () => {
//banner data
const [bannerList, setBannerList] = useState<any[]>([]);
//graceful data
const [gracefulList, setGracefulList] = useState<any[]>([]);
//activity data
const [activityList, setActivityList] = useState<any[]>([]);
//project data
const [projectList, setProjectList] = useState<any[]>([]);
//right data
const [rightList, setRightList] = useState<any[]>([]);
//right data
const [rightGraphList, setRightGraphList] = useState<any[]>([]);
//right local data
const [contactData, setContactData] = useState<any[]>([]);
//right total data
const totalContactData = useRef<any>(null);
//bottom advice modalvisible
const [adviceVisible, setAdviceVisible] = useState<boolean>(false);
//bottom advice modal data
const [adviceItemData, setAdviceItemData] = useState<Object>({});
const openModal = (item: any) => {
setAdviceItemData(item);
setAdviceVisible(true);
}
const closeModal = () => {
setAdviceVisible(false);
setAdviceItemData({});
}
//get banner
const getBannerList = () => {
getHomeBanner().then(async res => {
if (res?.code == 200) {
const data = await getImageUrl(res?.data, 'titleImage', topic_banner_default);
setBannerList(data);
}
})
}
//get activity
const getActivityList = () => {
getHomeActivity().then(res => {
if (res?.code == 200) {
setActivityList(res?.data);
}
})
}
//get graceful
const getGracefulList = () => {
getHomeGraceful().then(async res => {
if (res?.code == 200) {
let data: any[] = [];
if (res?.data.length > 6) {
data = await getImageUrl(res?.data.slice(0, 6), 'image', topic_activity_default);
} else {
data = await getImageUrl(res?.data, 'image', topic_activity_default);
}
setGracefulList(data);
}
})
}
//get project
const getProjectList = () => {
getHomeProject().then(res => {
if (res?.code == 200) {
let data: any[] = [];
if (res?.data.length > 12) {
data = res?.data.slice(0, 12);
} else {
data = res?.data;
}
setProjectList(data);
}
})
}
//get right
const getRightList = () => {
getHomeRight().then(res => {
if (res?.code == 200) {
if (res?.data.length > 0) {
setRightList(res?.data.slice(0, 6));
setRightGraphList(res?.data.slice(6, 9));
}
}
})
}
//get contact
const getContactList = () => {
getHomeContact().then(res => {
if (res?.code == 200) {
const data = Object.entries(res?.data);
if (data.length > 3) {
setContactData(data.slice(0, 3));
totalContactData.current = data;
} else {
setContactData(data);
}
}
})
}
//to hard project
const hardProjectClick = (data: any) => {
sessionStorage.setItem("detailData", JSON.stringify(data));
window.open("/partyMemberTopic/hardDetail");
}
//to hard project
const newsDetailClick = (data: any) => {
sessionStorage.setItem("detailData", JSON.stringify(data));
window.open("/partyMemberTopic/newsDetail");
}
//other buttom onclick
const bottomOtherClick = (param: string) => {
if (param == '0') {
setContactData([...totalContactData.current]);
} else {
setContactData([...totalContactData.current.slice(0, 3)]);
}
}
useEffect(() => {
getBannerList();
getGracefulList();
getActivityList();
getProjectList();
getRightList();
getContactList();
}, [])
return (
<div className="topic-global">
<div className="topic-background">
<div className="top-picture">
<img src={topic_header} />
</div>
<div className="top-global">
<div className='left-global'>
<Carousel className='left-carousel' autoplay>
{bannerList?.length > 0 && bannerList.map(item => (
<div key={item.id}>
<div className='carousel-content' style={{ backgroundImage: `url(${item.imageUrl})` }} onClick={() => newsDetailClick(item)}>
<div className='carousel-textbg'>
<div className='carousel-text'>
<span className='carousel-text-content'>{item.imageWord}</span>
<span className='carousel-text-click'></span>
</div>
</div>
</div>
</div>
))}
</Carousel>
<div className='left-activity'>
<img src={topic_activity_logo} />
<div className='left-activity-marquee'>
<Marquee pauseOnHover gradient={false}>
<div className='left-activity-scroll'>
{activityList.length > 0 && activityList.map((item, index) => (
index % 2 == 0 && <div className='left-activity-scroll-content' key={index}>
<div>
<span className='left-activity-scroll-name'>{item.name}</span>
<span>{item.text}</span>
</div>
{(index != activityList.length - 1) && (
<div className='left-activity-scroll-end'>
<span className='left-activity-scroll-name'>{activityList[index + 1]?.name}</span>
<span>{activityList[index + 1]?.text}</span>
</div>
)}
</div>
))}
</div>
</Marquee>
</div>
</div>
<div className='left-card'>
<div className='left-graceful'>
<LeftCardTop title="活动风采" url="/partyMemberTopic/activityStyle" />
<div>
<Row gutter={[20, 31]}>
{gracefulList?.length > 0 && gracefulList.map((item, index) => (
<Col span={8} key={index}>
<div className='left-graceful-bg' style={{ backgroundImage: `url(${item.imageUrl})` }} onClick={() => newsDetailClick(item)}>
<div className='left-graceful-textbg'>
<span className='left-graceful-text'>{item.title}</span>
</div>
</div>
</Col>
))}
</Row>
</div>
</div>
<div className='left-project'>
<LeftCardTop title="攻坚克难项目" url="/partyMemberTopic/overDifficult" />
<div className='left-project-content'>
<img src={topic_project_picture} />
<div className='left-project-content-list'>
<List
size='small'
split={false}
dataSource={projectList}
renderItem={item => (
<List.Item>
<div className='left-project-content-item'>
<a onClick={() => hardProjectClick(item)} className='left-project-content-item-title'>{item.title}</a>
<span className='left-project-content-item-time'>{formatTime(item.createTime, 'MM-DD HH:mm')}</span>
</div>
</List.Item>
)}
>
</List>
</div>
</div>
</div>
</div>
</div>
<div className='right-global'>
<div>
<img src={topic_right_material} className='right-material' onClick={() => window.open("/partyMemberTopic/partyBranch")} />
</div>
<div className='right-display'>
<RightDisplayTitle title="党员及支部数量情况" />
<RightDisplayContent index={0} data={rightList} img={topic_partymember} color="number-blue" />
<RightDisplayContent index={1} data={rightList} img={topic_partybranch} color="number-blue" />
</div>
<Divider className='right-divider' />
<div className='right-display'>
<RightDisplayTitle title="2022年订单交易情况" />
<RightDisplayContent index={2} data={rightList} img={topic_totalamount} color="number-orange" />
<RightDisplayContent index={3} data={rightList} img={topic_totalnumber} color="number-orange" />
<RightDisplayContent index={4} data={rightList} img={topic_commodity} color="number-orange" />
<RightDisplayContent index={5} data={rightList} img={topic_protocol} color="number-orange" />
</div>
<Divider className='right-divider' />
{rightGraphList.length > 0 && rightGraphList.map(item => (
<div className='right-graph' key={item.dataClass}>
<div className='right-graph-title'>
{item.dataClass}
</div>
<div className='right-graph-subtitle'>
{isNotEmpty(item.dataName) && `${item.dataName}${item.dataValue}${item.dataType}`}
</div>
<div className='right-graph-content'>
<RightGraphContent name={item.dataClass} type={item.dataType} data={item.data} />
</div>
</div>
))}
</div>
</div>
<div className='bottom-global'>
<LeftCardTop title="活动联系人" />
{contactData.length > 0 && contactData.map(([name, value], index) => (
<div key={index}>
<div className='bottom-title'>{name}</div>
<div className='bottom-content'>
<Row gutter={[20, 20]}>
{value.map((item: any) => (
<BottomCardContent data={item} onClick={() => openModal(item)} key={item.id} />
))}
</Row>
</div>
</div>
))}
{contactData.length != 0 && contactData.length > 2 && (
<div className='bottom-other'>
<div>
<span className='bottom-other-text' onClick={() => bottomOtherClick(contactData.length > 3 ? '1' : '0')}>{contactData.length > 3 ? '收起' : '更多'}</span>
<img src={topic_other} className={contactData.length > 3 ? 'bottom-close-icon' : 'bottom-other-icon'} />
</div>
</div>
)}
</div>
<CommentModal visible={adviceVisible} closeModal={() => closeModal()} data={adviceItemData} />
</div>
</div>
);
};
export default Home;