/* eslint-disable react/jsx-key */
import DragModal from '@/components/DragModal';
import { Add, Join, Pwd } from '@/components/DragModal/formdoms';
import Header from '@/components/Header';
import Highlighter from '@/components/Highlighter';
import IconFont from '@/components/IconFont';
import Weather from '@/components/Weather';
import { doFetch, getFetch } from '@/utils/doFetch';
import { DesktopOutlined, MessageOutlined, SearchOutlined, SettingFilled } from '@ant-design/icons';
import { history, Outlet, useLocation, useModel } from '@umijs/max';
import { useRequest } from 'ahooks';
import {
Avatar,
Badge,
Col,
ConfigProvider,
Drawer,
Dropdown,
Grid,
Input,
List,
message,
Modal,
notification,
Popconfirm,
Row,
Segmented,
Skeleton,
Tooltip,
Typography,
} from 'antd';
import zhCN from 'antd/locale/zh_CN';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
import { useEffect, useMemo, useRef, useState } from 'react';
import { Scrollbars } from 'react-custom-scrollbars';
import io from 'socket.io-client';
import styles from './index.less';
const { Paragraph } = Typography;
const { useBreakpoint } = Grid;
let col = { xs: 24, sm: 24, md: { span: 12 } },
cols = { xs: 24, sm: 24, md: { span: 12 } };
dayjs.locale('zh-cn');
const gaodekey = { key: 'ef1aace83eafd3eab2d42e013b456bae' };
const socket = io(REACT_APP_URL, { query: { id: localStorage.getItem('ID') } });
function difftime(start, end) {
const diffInMs = start.diff(end);
if (diffInMs < 60 * 60 * 1000) {
// 时间差小于 1 小时,转为分钟
const diffInMinutes = Math.round(diffInMs / (60 * 1000));
return diffInMinutes + '分钟前';
} else {
// 时间差大于等于 1 小时,继续判断是否超过 24 小时
const diffInHours = Math.round(diffInMs / (60 * 60 * 1000));
if (diffInHours >= 24) {
// 时间差超过 24 小时,转为天
const diffInDays = Math.round(diffInHours / 24);
return diffInDays + '天前';
} else {
// 时间差在 1 小时到 24 小时之间,直接输出小时数
return diffInHours + '小时前';
}
}
}
function Welcome(props) {
const {
initialState: { currentUser, fetchUserInfo },
setInitialState,
} = useModel('@@initialState');
const { pathname } = useLocation();
const screens = useBreakpoint();
let scrollRef = useRef();
const [modal, setmodal] = useState({
open: false,
});
const [ips, setips] = useState({});
const [dot, setdot] = useState(false);
const [drawer, setdrawer] = useState({
open: false,
});
const [dom, setdom] = useState(null);
const [search, setsearch] = useState();
const items = useMemo(() => {
return currentUser?.org_id
? [
{
key: '3',
label: 修改密码,
},
{
key: '4',
danger: true,
label: '退出登录',
},
]
: [
{
key: '1',
label: 创建组织,
},
{
key: '2',
label: 加入组织,
},
{
key: '3',
label: 修改密码,
},
{
key: '4',
danger: true,
label: '退出登录',
},
];
}, [currentUser?.org_id]);
const { run, loading } = useRequest(
() => {
return fetchUserInfo();
},
{
manual: true,
onSuccess: (res) => {
setInitialState((s) => ({
...s,
currentUser: res,
}));
},
},
);
const [isread, setisread] = useState(0);
const [count, setcount] = useState({
noread: 0,
readed: 0,
});
const messagelist = useRequest(
async () => {
let res = await getFetch({
url: '/webtool/v1/notice',
params: { isread },
});
return res?.data ?? [];
},
{
debounceWait: 300,
refreshDeps: [drawer?.open, isread],
onSuccess: (res) => {
if (!res) return;
if (isread === 0) {
setdot(res?.length > 0);
setcount((s) => ({
...s,
noread: res?.length,
}));
} else {
setcount((s) => ({
...s,
readed: res?.length,
}));
}
},
},
);
const weather = useRequest(
async () => {
const url = new URL('https://restapi.amap.com/v3/ip');
url.search = new URLSearchParams(gaodekey).toString();
let ip = await fetch(url);
ip = await ip.json();
setips(ip); //设置ip
const params = { ...gaodekey, city: ip.adcode, extensions: 'base' };
const urls = new URL('https://restapi.amap.com/v3/weather/weatherInfo');
urls.search = new URLSearchParams(params).toString();
let wea = await fetch(urls);
wea = await wea.json();
return {
...ip,
...(wea?.lives?.[0] ?? {}),
};
},
{
debounceWait: 300,
},
);
const tomorrow = useRequest(
async () => {
if (!ips?.adcode) {
return {};
}
const params = { ...gaodekey, city: ips.adcode, extensions: 'all' };
const urls = new URL('https://restapi.amap.com/v3/weather/weatherInfo');
urls.search = new URLSearchParams(params).toString();
let wea = await fetch(urls);
wea = await wea.json();
let casts = wea?.forecasts?.[0]?.casts ?? {};
let tomorrowres =
casts?.filter((it) => it.date === dayjs().add(1, 'day').format('YYYY-MM-DD'))?.[0] ?? {};
return {
...tomorrowres,
};
},
{
debounceWait: 300,
refreshDeps: [ips?.adcode],
},
);
const tasklist = useRequest(
async () => {
if (!search || search === '') {
return [];
}
let res = await getFetch({
url: '/webtool/v1/item',
params: { search },
});
return res?.data ?? [];
},
{
debounceWait: 800,
refreshDeps: [search],
},
);
useEffect(() => {
socket.connect();
socket.on('message', (data) => {
let div = document.createElement('div');
div.innerHTML = data?.reply ?? '';
const strings =
div.innerText.length > 25 ? `${div.innerText.substring(0, 25)}...` : div.innerText;
notification.info({
message: (
{data?.title}
),
duration: 0,
description: (
发送人:
{data?.otherinfo?.user_name}
任务:
{
if (location.hash?.indexOf(`/welcome/project/${data?.project_id}`) === -1) {
history.push(`/welcome/project/${data?.project_id}`);
}
setInitialState((s) => ({
...s,
curitem: data,
}));
notification?.destroy();
//转为已读
let res = await doFetch({
url: `/webtool/v1/notice/${data?.id}`,
params: { isread: true },
method: 'PUT',
});
if (res?.code === 0) {
messagelist?.refresh();
}
}}
>
{data?.mission_name}
{data?.deadline && (
于
{dayjs(data?.deadline).format('MM-DD')}
前截止
)}
{data?.reply && (
回复
{strings}
)}
),
placement: 'bottomRight',
});
messagelist?.refresh();
});
socket.on('onlineUsers', (data) => {
setInitialState((s) => {
const a = data,
b = s.activeUserIdList;
if (a.length === b.length && a.sort().toString() === b.sort().toString())
return {
...s,
};
else
return {
...s,
activeUserIdList: data,
};
});
});
return () => {
// 关闭 WebSocket 连接
socket.disconnect();
};
}, []);
useEffect(() => {
setdom(null);
}, [pathname]);
const stylefit = useMemo(() => {
if (!screens?.md) {
return {
size: {
width: 30,
height: 30,
},
};
} else {
return {
size: {
width: 40,
height: 40,
},
};
}
}, [screens?.md]);
return (
{
setmodal((s) => ({
...s,
open: false,
}));
}}
>
{modal?.title === '创建组织' && (
{
run();
setmodal((s) => ({
...s,
open: false,
}));
}}
/>
)}
{modal?.title === '加入组织' && (
{
run();
setmodal((s) => ({
...s,
open: false,
}));
}}
/>
)}
{modal?.title === '修改密码' && (
{
run();
setmodal((s) => ({
...s,
open: false,
}));
}}
/>
)}
{
setdrawer((s) => ({
...s,
open: false,
}));
setsearch(null);
}}
extra={
<>
{
setisread(val);
}}
options={[
{
label: (
未读
{count?.noread !== 0 && (
{count?.noread}
)}
),
value: 0,
},
{
label: (
已读
{count?.readed !== 0 && (
{count?.readed}
)}
),
value: 1,
},
]}
/>
{
setdrawer((s) => ({
...s,
open: false,
}));
setsearch(null);
}}
>
esc
>
}
destroyOnClose={drawer?.title !== 'ChatGPT'}
width={'100%'}
contentWrapperStyle={{ maxWidth: 1280 }}
>
{drawer?.title === 'ChatGPT' && (
)}
{drawer?.title === '消息中心' && (
{
let div = document.createElement('div');
div.innerHTML = item?.reply;
const strings =
div.innerText.length > 25
? `${div.innerText.substring(0, 25)}...`
: div.innerText;
return (
{difftime(dayjs(), dayjs(item.created_at))}
,
]}
onClick={async () => {
if (location.hash?.indexOf(`/welcome/project/${item?.project_id}`) === -1) {
history.push(`/welcome/project/${item?.project_id}`);
}
await setInitialState((s) => ({
...s,
curitem: item,
}));
await setdrawer((s) => ({
...s,
open: false,
}));
//转为已读
let res = await doFetch({
url: `/webtool/v1/notice/${item?.id}`,
params: { isread: true },
method: 'PUT',
});
if (res?.code === 0) {
messagelist?.refresh();
}
}}
>
{item?.other_user?.head_url ||
item?.other_user?.user_name.charAt(0)}
}
title={
item.title === '你有新的任务' ? (
任务:{item.mission_name}
) : item.title === '你有新的回复' ? (
回复:{item.mission_name}
) : null
}
/>
);
}}
/>
)}
{drawer?.title !== '消息中心' && drawer?.title !== 'ChatGPT' && (
{
return (
{difftime(dayjs(), dayjs(item.created_at))}
,
]}
onClick={async () => {
if (location.hash?.indexOf(`/welcome/project/${item?.project_id}`) === -1) {
history.push(`/welcome/project/${item?.project_id}`);
}
await setInitialState((s) => ({
...s,
curitem: { ...item, item_id: item?.id },
}));
await setdrawer((s) => ({
...s,
open: false,
}));
setsearch(null);
}}
>
{item?.user?.head_url || item?.user?.user_name.charAt(0)}
}
title={
{item.mission_name}
{item.step_id > 9999999 ? (
_任务池
) : (
''
)}
}
description={
item?.deadline && (
{dayjs(item?.deadline).format('YYYY年MM月DD日')}
前截止
)
}
/>
{item.remark}
);
}}
/>
)}
{pathname === '/welcome/homepage' ? (
<>
{
if (!value) {
message.warning('用户名不可为空');
return;
}
let res = await doFetch({
url: '/webtool/v1/user/' + currentUser?.id,
params: {
user_name: value,
},
method: 'PUT',
});
if (res.code === 0) {
run();
}
},
}}
>
{currentUser?.user_name}
{currentUser?.org_id && (
{currentUser?.org_name}
组织代码,
tooltips: '复制组织代码',
}}
style={{ margin: 0, fontSize: 12 }}
>
{
doFetch({
url: `/webtool/v1/user/${currentUser?.id}`,
params: { org_id: null },
method: 'PUT',
}).then((res) => {
if (res?.code === 0) {
message.success('退出成功');
history.push('/welcome/homepage');
run();
}
});
}}
>
退出组织
)}
{['吴昊'].includes(currentUser?.user_name) && (
{
history.push('/dashboard');
}}
className="sorts"
style={{ width: 40, height: 40, fontSize: 16 }}
>
)}
>
) : (
{
history.push('/welcome/homepage');
}}
style={{
width: 42,
height: 42,
flexShrink: 0,
marginRight: 8,
}}
>
{dom}
)}
{
setdrawer((s) => ({
...s,
open: true,
width: 1000,
title: (
}
defaultValue={search}
onChange={(e) => {
setsearch(e.target.value);
}}
/>
),
}));
}}
>
{
//utools action
if (window.utools) {
Modal.confirm({
title: '免责声明',
content:
'chatgpt为作者为方便用户使用找到的网上的镜像,可能存在求打赏与收费的现象,该行为与本tasks平台无关,请谨慎充值。',
okText: '同意',
cancelText: '拒绝',
onOk: () => {
window.utools.ubrowser
.goto('https://chat.aidutu.cn/')
.run({ width: 980, height: 640 });
},
});
} else {
//brower action
setdrawer((s) => ({
...s,
open: true,
width: 1000,
title: 'ChatGPT',
}));
}
}}
>
{
setdrawer((s) => ({
...s,
open: true,
width: 600,
title: '消息中心',
}));
}}
>
{
switch (key) {
case '1':
setmodal((s) => ({
...s,
open: true,
title: '创建组织',
}));
break;
case '2':
setmodal((s) => ({
...s,
open: true,
title: '加入组织',
}));
break;
case '3':
setmodal((s) => ({
...s,
open: true,
title: '修改密码',
}));
break;
case '4':
socket.disconnect();
doFetch({ url: '/webtool/logout', params: {} }).then((res) => {
localStorage.removeItem('TOKENES');
history.push('/user/login');
});
break;
default:
break;
}
},
}}
trigger="hover"
getPopupContainer={() => document.getElementById('head')}
>
);
}
export default Welcome;