Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion web/src/hooks/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useUpdateEffect } from "ahooks";
import { useRequest, useUpdateEffect } from "ahooks";
import { App } from "antd";
import type { Locale } from "antd/es/locale";
import enUS from "antd/es/locale/en_US";
Expand All @@ -24,6 +24,7 @@ import { GetMineRoleList } from "@/services/default";
import { ITeamListProps, IUserDataItem } from "@/dtos/main";
import { GetTeamsMineApi } from "@/services/main";
import { isEmpty } from "ramda";
import { GetUnreadCountApi } from "@/services/warning";

interface IAuthContextType {
navigate: NavigateFunction;
Expand All @@ -50,6 +51,7 @@ interface IAuthContextType {
setCurrentAccount: React.Dispatch<React.SetStateAction<IUserDataItem>>;
teamList: ITeamListProps[];
getMineTeam: (name: string) => void;
unreadyCount: number;
}

interface IPermissions {
Expand Down Expand Up @@ -81,6 +83,8 @@ export const AuthProvider = (props: { children: ReactElement }) => {

const [locale, setLocal] = useState<Locale>(zhCN);

const [unreadyCount, setUnreadyCount] = useState<number>(0);

const [isGetPermission, setIsGetPermission] = useState<boolean>(false);

const [token, setToken] = useState(
Expand Down Expand Up @@ -333,6 +337,24 @@ export const AuthProvider = (props: { children: ReactElement }) => {
return location.pathname.split("/").filter((item) => item.trim() !== "");
};

const { run: getUnreadCount } = useRequest(GetUnreadCountApi, {
manual: true,
pollingInterval: 5000,
pollingWhenHidden: false,
onSuccess: (res) => {
setUnreadyCount(res ?? 0);
},
onError: (err) => {
message.error("獲取未獨數量數據失敗" + `:${err?.message}`);

setUnreadyCount(0);
},
});

useEffect(() => {
token && getUnreadCount();
}, [token]);

useEffect(() => {
if (language) {
i18n.changeLanguage(language);
Expand Down Expand Up @@ -403,6 +425,7 @@ export const AuthProvider = (props: { children: ReactElement }) => {
setCurrentAccount,
teamList,
getMineTeam,
unreadyCount,
};

return (
Expand Down
19 changes: 19 additions & 0 deletions web/src/icon/warning/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const CleanIcon = () => {
return (
<svg
width="1em"
height="1em"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g id="icon/clear">
<path
id="Union"
d="M7 4H9V2H7V4ZM10 2V4H13C13.5523 4 14 4.44772 14 5V7C14 7.50427 13.6267 7.92137 13.1414 7.99007L13.8369 12.8586C13.923 13.461 13.4555 14 12.847 14H3.15301C2.54446 14 2.077 13.461 2.16306 12.8586L2.85856 7.99007C2.37326 7.92137 2 7.50427 2 7V5C2 4.44772 2.44772 4 3 4H6V2C6 1.44772 6.44772 1 7 1H9C9.55228 1 10 1.44772 10 2ZM12.1327 7H13V5H9H7H3L3 7H3.8673H12.1327ZM12.1327 8H3.8673L3.15301 13H5V11H6V13H7.5V11H8.5V13H10V11H11V13H12.847L12.1327 8Z"
fill="#8B98AD"
/>
</g>
</svg>
);
};
9 changes: 7 additions & 2 deletions web/src/pages/main/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import { isEmpty } from "ramda";
type MenuItem = Required<MenuProps>["items"][number];

export const Main = () => {
const { isGetPermission } = useAuth();
const { isGetPermission, unreadyCount } = useAuth();

const {
t,
Expand Down Expand Up @@ -175,7 +175,12 @@ export const Main = () => {
key: "/warning",
label: (
<Link to="/warning/list">
{t(KEYS.WARNING_LIST, { ns: "main" })}
<div className="flex">
{t(KEYS.WARNING_LIST, { ns: "main" })}
<div className="bg-[#FF706C] h-5 min-w-5 px-1 rounded-full border-[0.1rem] border-white text-white text-[0.65rem] flex justify-center items-center">
{unreadyCount}
</div>
</div>
</Link>
),
icon: !collapsed ? (
Expand Down
48 changes: 46 additions & 2 deletions web/src/pages/warning/component/warning-list/hook.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useContext, useEffect, useState } from "react";
import { useContext, useEffect, useRef, useState } from "react";

import {
IPageDto,
Expand Down Expand Up @@ -47,6 +47,12 @@ export const useAction = () => {
window.dispatchEvent(e);
};

const isStopLoadingList = useRef<boolean>(false);

const isFirstLoad = useRef<boolean>(true);

const timeoutRef = useRef<NodeJS.Timeout | null>(null);

const loadWarningData = async (
pageIndex: number,
pageSize: number,
Expand All @@ -56,6 +62,8 @@ export const useAction = () => {
searchKeyWord?: string,
selectValues?: number[]
) => {
if (isStopLoadingList.current) return;

if (!currentTeam.id) {
message.error("TeamId not found!");
return;
Expand Down Expand Up @@ -84,12 +92,28 @@ export const useAction = () => {
data.MonitorTypes = selectValues;
}

updateData("loading", true);
isFirstLoad.current && updateData("loading", true);

try {
const { count, records } = (await GetRecordList(data)) || {};
updateData("records", records);
updateData("count", count);

isFirstLoad.current = false;

timeoutRef.current = setTimeout(
() =>
loadWarningData(
data.PageIndex,
data.PageSize,
data.StartTime,
data.EndTime,
data.Status,
data.EquipmentName,
data.MonitorTypes
),
5000
);
} catch {
message.error("获取数据失败");
updateData("records", []);
Expand All @@ -103,9 +127,23 @@ export const useAction = () => {

useEffect(() => {
loadWarningData(dto.PageIndex, dto.PageSize);

return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}

isStopLoadingList.current = true;
};
}, []);

const onChangePage = (pageIndex: number, pageSize: number) => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}

isFirstLoad.current = true;

loadWarningData(
pageIndex,
pageSize,
Expand All @@ -118,6 +156,12 @@ export const useAction = () => {
};

useUpdateEffect(() => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}

isFirstLoad.current = true;

loadWarningData(
1,
dto.PageSize,
Expand Down
9 changes: 8 additions & 1 deletion web/src/pages/warning/component/warning-list/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const statusComponent = (
text: string,
icon: ReactElement,
canViewDetailWarning: boolean,
isRead: boolean | undefined,
func: VoidFunction
) => {
const handleClick = () => {
Expand All @@ -31,11 +32,14 @@ const statusComponent = (

return (
<span
className={`py-[0.25rem] px-[0.625rem] border border-solid rounded-lg space-x-1 cursor-pointer ${boxBorderColor}`}
className={`relative py-[0.25rem] px-[0.625rem] border border-solid rounded-lg space-x-1 cursor-pointer ${boxBorderColor}`}
onClick={handleClick}
>
{icon}
<span className={`${textColor} select-none`}>{text}</span>
{!isRead && (
<div className="absolute -right-1 -top-1 w-2 h-2 bg-red-500 rounded-full" />
)}
</span>
);
};
Expand Down Expand Up @@ -122,6 +126,7 @@ export const WarningList = () => {
"待標記",
<PlusOutlined className="text-[#18283C] text-sm" />,
pagePermission.canViewDetailWarning,
record.isRead,
() =>
navigate(`/warning/${record.id}`, {
state: {
Expand All @@ -137,6 +142,7 @@ export const WarningList = () => {
"通過",
<CheckOutlined className="text-[#04B6B5] text-sm" />,
pagePermission.canViewDetailWarning,
record.isRead ?? false,
() =>
navigate(`/warning/${record.id}`, {
state: {
Expand All @@ -152,6 +158,7 @@ export const WarningList = () => {
"異常",
<ExclamationCircleOutlined className="text-[#FF908C] text-sm" />,
pagePermission.canViewDetailWarning,
record.isRead ?? false,
() =>
navigate(`/warning/${record.id}`, {
state: {
Expand Down
30 changes: 27 additions & 3 deletions web/src/pages/warning/hook.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useDebounceEffect, useDebounceFn } from "ahooks";
import { useDebounceEffect, useDebounceFn, useRequest } from "ahooks";
import dayjs, { Dayjs } from "dayjs";
import { clone } from "ramda";
import { useEffect, useRef, useState } from "react";
Expand All @@ -7,7 +7,7 @@ import { IRecordRequest, IStatusType } from "@/dtos/default";
import { IRegisterRecordRequest } from "@/dtos/warning";
import { useAuth } from "@/hooks/use-auth";
import { GetRecordList } from "@/services/default";
import { PostRegisterRecord } from "@/services/warning";
import { PostBatchMark, PostRegisterRecord } from "@/services/warning";
import { onDownLoadWorkbook } from "@/utils";

interface IKey {
Expand All @@ -29,7 +29,8 @@ const keyName: IKey = {
};

export const useAction = () => {
const { location, message, t, pagePermission, currentTeam } = useAuth();
const { location, message, t, pagePermission, currentTeam, unreadyCount } =
useAuth();

const state = location.state as {
status: IStatusType;
Expand Down Expand Up @@ -71,6 +72,8 @@ export const useAction = () => {

const [searchKeyWord, setSearchKeyWord] = useState<string>("");

const [openDelete, setOpenDelete] = useState<boolean>(false);

const onStatusClick = (value: IStatusType) => {
setStatus(value);
};
Expand Down Expand Up @@ -301,6 +304,21 @@ export const useAction = () => {
}
);

const { run: onDelete, loading: deleteLoading } = useRequest(
() => PostBatchMark({}),
{
manual: true,
debounceWait: 500,
debounceLeading: false,
onSuccess: () => {
message.success("清除未讀成功");
},
onError: (err) => {
message.success(`清除未讀失敗:${err}`);
},
}
);

useEffect(() => {
getHeight();

Expand Down Expand Up @@ -351,6 +369,12 @@ export const useAction = () => {
handleOnExportDebounceFn,
markedStatus,
pagePermission,
deleteLoading,
message,
unreadyCount,
openDelete,
setOpenDelete,
onDelete,
setTimeDto,
setKeyWord,
onTypeClick,
Expand Down
39 changes: 37 additions & 2 deletions web/src/pages/warning/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SearchOutlined } from "@ant-design/icons";
import { Button, Input, Modal, Radio } from "antd";
import Icon, { SearchOutlined } from "@ant-design/icons";
import { Button, Input, Modal, Radio, Popconfirm } from "antd";
import { createContext } from "react";
import { useOutlet } from "react-router-dom";

Expand All @@ -14,6 +14,7 @@ import importImg from "../../assets/import.png";
import pinImg from "../../assets/pin.png";
import { useAction } from "./hook";
import { IWarningSearchDataContext } from "./props";
import { CleanIcon } from "@/icon/warning";

const { TextArea } = Input;

Expand All @@ -36,6 +37,12 @@ export const Warning = () => {
handleOnExportDebounceFn,
markedStatus,
pagePermission,
deleteLoading,
message,
unreadyCount,
openDelete,
setOpenDelete,
onDelete,
setTimeDto,
setKeyWord,
onTypeClick,
Expand Down Expand Up @@ -76,6 +83,34 @@ export const Warning = () => {
value={status}
onClick={onStatusClick}
/>
<div
className="flex items-center pl-[0.5rem] cursor-pointer"
onClick={() => {
unreadyCount === 0
? message.warning("当前没有未读信息")
: setOpenDelete(true);
}}
>
<Popconfirm
title="確定要清除未讀嗎?"
onConfirm={onDelete}
placement="bottom"
okText="確定"
cancelText="取消"
okButtonProps={{ loading: deleteLoading }}
open={openDelete}
>
<div className="flex items-center pl-[0.5rem] cursor-pointer">
<Icon
component={CleanIcon}
className="pt-[0.1rem] text-[1rem]"
/>
<span className="text-[#8d8f93] font-bold text-[0.88rem] whitespace-nowrap">
清除未讀
</span>
</div>
</Popconfirm>
</div>
</div>
)}
</div>
Expand Down
Loading