Files
fe_service_ebtp_frontend/src/pages/PartyMemberTopic/Home/index.tsx
2022-06-26 10:42:10 +08:00

498 lines
21 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 } 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 { getHomeActivity, getHomeBanner, getHomeContact, getHomeGraceful, getHomeProject, getHomeRight, submitAdvice } from './service';
import { getFilelist } from '@/services/download_';
import { pictureDisplayPath } from '@/utils/DownloadUtils';
import moment from 'moment';
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>
<div>
<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) => {
return (
props.data?.length > 0 ? (
<div className='right-display-content'>
<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: 12,
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'>
<span>{props.data.contactName}</span>
<span className='bottom-card-title-type'>({props.data.contactName})</span>
</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>
)
}
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 () => {
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={350}
>
<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={9}
className='bottom-modal-textarea'
maxLength={200}
defaultValue={''}
onChange={onTextChange}
/>
<div className='bottom-modal-submit'>
<span className='submit-text'>{props.data?.contactDepartment}{props.data?.contactName}</span>
<Button type='primary' className='submit-button' onClick={onSubmit}>
</Button>
</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 data
const [contactData, setContactData] = useState<Object>({});
//bottom advice modalvisible
const [adviceVisible, setAdviceVisible] = useState<boolean>(false);
//bottom advice modal data
const [adviceItemData, setAdviceItemData] = useState<Object>({});
const getImageUrl = async (data: any[], paramName: string) => {
for (const ite of data) {
await getFilelist([ite[paramName]]).then(response => {//获取主图
if (response?.success && response?.data?.length > 0) {
const returnUrl = window.location.origin + pictureDisplayPath + '?filePath=' + response?.data[0].filePath;
ite["imageUrl"] = returnUrl;
}
})
}
return data;
}
const formatProjectTime = (time: string) => {
return moment(time).format('MM-DD HH:mm');
}
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');
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');
} else {
data = await getImageUrl(res?.data, 'image');
}
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) {
setContactData(res?.data);
}
})
}
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})` }}>
<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 && (
<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="活动风采" />
<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})` }}>
<div className='left-graceful-textbg'>
<span className='left-graceful-text'>{item.imageWord}</span>
</div>
</div>
</Col>
))}
</Row>
</div>
</div>
<div className='left-project'>
<LeftCardTop title="攻坚克难项目" />
<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'>
<span className='left-project-content-item-title'>{item.title}</span>
<span className='left-project-content-item-time'>{formatProjectTime(item.createTime)}</span>
</div>
</List.Item>
)}
>
</List>
</div>
</div>
</div>
</div>
</div>
<div className='right-global'>
<div>
<img src={topic_right_material} className='right-material' />
</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'>
{item.dataName != null && `${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="活动联系人" />
{Object.entries(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)} />
))}
</Row>
</div>
</div>
))}
<div className='bottom-other'>
<div>
<span className='bottom-other-text'></span>
<img src={topic_other} className='bottom-other-icon' />
</div>
</div>
</div>
<CommentModal visible={adviceVisible} closeModal={() => closeModal()} data={adviceItemData} />
</div>
</div>
);
};
export default Home;