forgeplus-react/src/components/CustomOperateModel/index.tsx

323 lines
8.4 KiB
TypeScript

import { Modal, Button, Carousel } from 'antd';
import Draggable from 'react-draggable';
import React, { Fragment, FC, useEffect, useState, forwardRef, useImperativeHandle } from 'react';
import { useRef } from 'react';
import styles from './index.less'
import { RightOutlined, LeftOutlined } from '@ant-design/icons'
import RenderHtml from '@/components/RenderHtml'
import Fetch from '@/utils/fetch';
import { openNewWindow } from '@/utils/util';
import {
connect,
Dispatch,
UserModelState,
GlobalSettingModelState,
useLocation,
history
} from 'umi';
import moment from 'moment'
import _ from 'lodash'
interface PageProps {
dispatch: Dispatch;
user: UserModelState;
globalSetting: GlobalSettingModelState;
}
const CustomOperateModel: FC<PageProps> = ({ dispatch, user, globalSetting }) => {
const [data, setData] = useState<any>({})
const [resData, setResData] = useState<any>([])
const [dataIndex, setDataIndex] = useState<number>(0)
const [visible, setVisible] = useState<boolean>(false)
const carouselsRef = useRef(null);
const lo = useLocation();
const dealDate = (type: any, num: number) => {
let date = null
if (type === 0) {
//弹出来一次,把时间设置长
date = moment().add(100, 'month').unix();
}
if (type === 1) {
date = moment().add(num, 'hour').unix();
}
if (type === 2) {
date = moment().add(num, 'days').unix();
}
if (type === 3) {
date = moment().add(num * 7, 'days').unix();
}
if (type === 4) {
date = moment().add(num, 'month').unix();
}
if (type === 5) {
date = moment().add(num * 3, 'month').unix();
}
return date;
// 0仅一次 1时 2天 3周 4月 5季
}
const recordTime = (re: any) => {
//记录时间
const recordStr = `${user?.userInfo?.login}-deadline-operate`;
let record: any = localStorage.getItem(recordStr) ? JSON.parse(localStorage.getItem(recordStr)) : []
record = record?.filter((e: any) => e.id !== re?.id)
const date = dealDate(re?.show_type, re?.show_count)
const param = {
id: re?.id,
deadline: date,
type: re?.show_type
}
record?.push(param)
localStorage.setItem(recordStr, JSON.stringify(record));
}
const onCancel = () => {
setCount(data?.id, 'close')
const nextData = resData[dataIndex + 1];
if (nextData) {
recordTime(nextData)
setData(nextData);
setDataIndex(dataIndex + 1)
setCount(nextData?.id, 'popup')
} else {
setVisible(false)
}
};
const pageItems = [{
name: '首页',
key: 0,
path: '/'
},
{
name: '实践课程',
key: 1,
path: '/paths'
},
{
name: '实践项目',
key: 2,
path: '/shixuns'
},
{
name: '教学课堂',
key: 3,
path: '/classrooms'
},
{
name: '在线竞赛',
key: 4,
path: '/competitions'
},
{
name: '教学案例',
key: 5,
path: '/moop_cases'
},
{
name: '交流问答',
key: 6,
path: '/forums/categories'
},
{
name: '个人中心',
key: 7,
path: '/users'
}]
// useEffect(() => {
// console.log(globalSetting?.operateModelPath, user?.userInfo?.login, 11444)
// if (!!globalSetting?.operateModelPath && user?.userInfo?.login) {
// getData();
// }
// }, [globalSetting?.operateModelPath, user?.userInfo?.login])
useEffect(() => {
return () => {
dispatch({
type: 'globalSetting/setOperateModelPath',
payload: ''
})
}
}, [])
useEffect(() => {
//个人中心
if (lo?.pathname?.includes('/users') && (lo?.pathname?.split('/')?.length === 4)) {
dispatch({
type: 'globalSetting/setOperateModelPath',
payload: '/users'
})
return;
}
//交流问答
if (lo?.pathname?.includes('/forums/categories')) {
dispatch({
type: 'globalSetting/setOperateModelPath',
payload: '/forums/categories'
})
return;
}
for (let i = 0; i < pageItems.length; i++) {
if (pageItems?.[i]?.path === lo?.pathname) {
dispatch({
type: 'globalSetting/setOperateModelPath',
payload: pageItems?.[i]?.path
})
return
}
}
}, [lo?.pathname])
useEffect(() => {
window.addEventListener("click", handleClick);
return () => {
window.removeEventListener("click", handleClick);
}
}, [data])
//父级找元素
const parentIndexOf = (node: any) => {
if (node?.getAttribute("data-operate-type")) { return node; }
for (let i = 0, n = node; n = n.parentNode; i++) {
if (n?.getAttribute("data-operate-type")) { return n; }
if (n == document.documentElement) { return false; } //找不到目标父节点,防止死循环
}
}
const handleClick = async (e: any) => {
const dom = parentIndexOf(e.target);
if (dom) {
const domName = dom?.getAttribute("data-operate-type");
if (domName === 'click') {
e.preventDefault();
const href = dom?.getAttribute("href");
const target = dom?.getAttribute("target");
await setCount(data?.id, 'enter')
if (target === '_blank') {
openNewWindow(href)
} else {
setVisible(false);
window.location.href = href;
}
}
}
}
const setCount = async (id: any, count_type: string) => {
const res = await Fetch('/api/popup_windows/popup_windows_counts.json', {
method: "get",
params: {
id,
count_type
}
});
return res;
}
const getData = async () => {
const res = await Fetch('/api/popup_windows/get_popup_windows.json', { method: "get" });
if (res?.status === 0 && res?.data?.length !== 0) {
const key = pageItems?.findIndex((e: any) => e.path === globalSetting?.operateModelPath)
let newData = _.cloneDeep(res?.data);
//页面筛选
newData = newData?.filter((e: any) => e.show_page?.includes(key));
//时间筛选
const recordStr = `${user?.userInfo?.login}-deadline-operate`;
let record: any = localStorage.getItem(recordStr) ? JSON.parse(localStorage.getItem(recordStr)) : []
console.log(record, 'record')
if (record?.length !== 0) {
newData = newData?.filter((e: any) => {
let bool: boolean = true;
const param = record?.find((r: any) => r.id === e.id);
if (param) {
//弹一次的情况
const date = moment().unix();
if (date <= param?.deadline) {
bool = false;
}
if (param?.type === 0) {
if (e.show_type === 0) {
bool = false;
} else {
bool = true;
}
}
}
return bool;
})
}
if (newData?.length) {
setData(newData?.[dataIndex]);
recordTime(newData?.[dataIndex])
setCount(newData?.[dataIndex]?.id, 'popup')
setVisible(true)
setResData(newData)
}
}
}
const renderShowOne = () => {
return <div className={styles.modalityModal}>
<div className={styles.modal} style={{ width: data?.width, height: data?.height }}>
<div className={styles.close} onClick={onCancel}>
<i className="iconfont icon-guanbi1" />
</div>
<Carousel
ref={carouselsRef}
dots={true}
>
{data?.content?.map((v: any, i: number) => <aside key={i} className={styles.itemWarp} >
<RenderHtml style={{ height: data?.height }} value={v} />
</aside>)}
</Carousel>
</div>
</div>
}
const renderShowTwo = () => {
return <div className={styles.selfdomModal}>
<div className={styles.modal} style={{ width: data?.width, height: data?.height }}>
<div className={styles.close} onClick={onCancel}>
<i className="iconfont icon-htmal5icon19" />
</div>
<Carousel
ref={carouselsRef}
dots={true}
>
{data?.content?.map((v: any, i: number) => <aside key={i} className={styles.itemWarp} >
<RenderHtml style={{ height: data?.height }} value={v} />
</aside>)}
</Carousel>
</div>
</div>
}
return (
<Fragment>
{visible &&
(data?.windows_style === 0 ? renderShowOne() : renderShowTwo())
}
</Fragment>
);
}
export default connect(
({
user,
globalSetting
}: {
user: UserModelState;
globalSetting: GlobalSettingModelState;
}) => ({
user,
globalSetting
}),
)(CustomOperateModel);