Merge pull request #5 from PlayEdu/dev

Dev
This commit is contained in:
Teng 2023-05-10 10:57:43 +08:00 committed by GitHub
commit 24232ef396
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 172 additions and 62 deletions

View File

@ -119,8 +119,16 @@ export const LeftMenu: React.FC = () => {
}; };
useEffect(() => { useEffect(() => {
setSelectedKeys([location.pathname]); if (location.pathname.indexOf("/course/user") !== -1) {
setOpenKeys(openKeyMerge(location.pathname)); setSelectedKeys(["/course"]);
setOpenKeys(openKeyMerge("/course"));
} else if (location.pathname.indexOf("/member/learn") !== -1) {
setSelectedKeys(["/member/index"]);
setOpenKeys(openKeyMerge("/member/index"));
} else {
setSelectedKeys([location.pathname]);
setOpenKeys(openKeyMerge(location.pathname));
}
}, [location.pathname]); }, [location.pathname]);
return ( return (

View File

@ -0,0 +1,12 @@
import React from "react";
import { getToken } from "../../utils/index";
import { Navigate } from "react-router-dom";
interface PropInterface {
Component: any;
}
const PrivateRoute: React.FC<PropInterface> = ({ Component }) => {
return getToken() ? Component : <Navigate to="/login" replace={true} />;
};
export default PrivateRoute;

View File

@ -30,10 +30,10 @@ export const TreeDepartment = (props: PropInterface) => {
setUserTotal(res.data.user_total); setUserTotal(res.data.user_total);
if (JSON.stringify(departments) !== "{}") { if (JSON.stringify(departments) !== "{}") {
if (props.showNum) { if (props.showNum) {
const new_arr: any = checkNewArr(departments, 0, departCount); const new_arr: any[] = checkNewArr(departments, 0, departCount);
setTreeData(new_arr); setTreeData(new_arr);
} else { } else {
const new_arr: Option[] = checkArr(departments, 0); const new_arr: any[] = checkArr(departments, 0);
setTreeData(new_arr); setTreeData(new_arr);
} }
} else { } else {
@ -87,13 +87,17 @@ export const TreeDepartment = (props: PropInterface) => {
for (let i = 0; i < departments[id].length; i++) { for (let i = 0; i < departments[id].length; i++) {
if (!departments[departments[id][i].id]) { if (!departments[departments[id][i].id]) {
arr.push({ arr.push({
title: departments[id][i].name, title: (
<span className="tree-title-elli">{departments[id][i].name}</span>
),
key: departments[id][i].id, key: departments[id][i].id,
}); });
} else { } else {
const new_arr: Option[] = checkArr(departments, departments[id][i].id); const new_arr: any[] = checkArr(departments, departments[id][i].id);
arr.push({ arr.push({
title: departments[id][i].name, title: (
<span className="tree-title-elli">{departments[id][i].name}</span>
),
key: departments[id][i].id, key: departments[id][i].id,
children: new_arr, children: new_arr,
}); });
@ -105,16 +109,18 @@ export const TreeDepartment = (props: PropInterface) => {
const getNewTitle = (title: any, id: number, counts: any) => { const getNewTitle = (title: any, id: number, counts: any) => {
if (counts) { if (counts) {
let value = counts[id] || 0; let value = counts[id] || 0;
return title + "(" + value + ")"; return (
<span className="tree-title-elli">{title + "(" + value + ")"}</span>
);
} else { } else {
return title; return <span className="tree-title-elli">{title}</span>;
} }
}; };
const onSelect = (selectedKeys: any, info: any) => { const onSelect = (selectedKeys: any, info: any) => {
let label = "全部" + props.text; let label = "全部" + props.text;
if (info) { if (info) {
label = info.node.title; label = info.node.title.props.children;
} }
props.onUpdate(selectedKeys, label); props.onUpdate(selectedKeys, label);
setSelectKey(selectedKeys); setSelectKey(selectedKeys);
@ -123,7 +129,7 @@ export const TreeDepartment = (props: PropInterface) => {
const onExpand = (selectedKeys: any, info: any) => { const onExpand = (selectedKeys: any, info: any) => {
let label = "全部" + props.text; let label = "全部" + props.text;
if (info) { if (info) {
label = info.node.title; label = info.node.title.props.children;
} }
props.onUpdate(selectedKeys, label); props.onUpdate(selectedKeys, label);
setSelectKey(selectedKeys); setSelectKey(selectedKeys);

View File

@ -23,7 +23,7 @@ code {
} }
.w-174px { .w-174px {
max-width: 174px; max-width: 134px;
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
@ -457,6 +457,7 @@ textarea.ant-input {
margin-bottom: 8px !important; margin-bottom: 8px !important;
display: flex; display: flex;
align-items: center !important; align-items: center !important;
&.ant-tree-treenode-selected { &.ant-tree-treenode-selected {
background-color: #fff2f0 !important; background-color: #fff2f0 !important;
border-radius: 6px !important; border-radius: 6px !important;
@ -559,9 +560,11 @@ textarea.ant-input {
.tree-title-elli { .tree-title-elli {
width: 100%; width: 100%;
display: -webkit-box;
overflow: hidden; overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
} }
.ant-tabs { .ant-tabs {

View File

@ -10,7 +10,7 @@ import {
message, message,
Image, Image,
} from "antd"; } from "antd";
import { course } from "../../api"; import { course as Course } from "../../api";
import { useParams, useLocation } from "react-router-dom"; import { useParams, useLocation } from "react-router-dom";
import type { ColumnsType } from "antd/es/table"; import type { ColumnsType } from "antd/es/table";
import { BackBartment } from "../../compenents"; import { BackBartment } from "../../compenents";
@ -33,7 +33,11 @@ const CourseUserPage = () => {
const params = useParams(); const params = useParams();
const result = new URLSearchParams(useLocation().search); const result = new URLSearchParams(useLocation().search);
const [list, setList] = useState<any>([]); const [list, setList] = useState<any>([]);
const [users, setUsers] = useState<any>([]); const [course, setCourse] = useState<any>({});
const [records, setRecords] = useState<any>({});
const [hourCount, setHourCount] = useState<any>({});
const [userDepIds, setUserDepIds] = useState<any>({});
const [departments, setDepartments] = useState<any>({});
const [refresh, setRefresh] = useState(false); const [refresh, setRefresh] = useState(false);
const [page, setPage] = useState(1); const [page, setPage] = useState(1);
const [size, setSize] = useState(10); const [size, setSize] = useState(10);
@ -55,11 +59,30 @@ const CourseUserPage = () => {
preview={false} preview={false}
width={40} width={40}
height={40} height={40}
src={users.find((i: any) => i.id === record.user_id).avatar} src={record.avatar}
></Image> ></Image>
<span className="ml-8"> <span className="ml-8">{record.name}</span>
{users.find((i: any) => i.id === record.user_id).name} </div>
</span> ),
},
{
title: "邮箱",
render: (_, record: any) => <span>{record.email}</span>,
},
{
title: "部门",
render: (_, record: any) => (
<div className="float-left">
{userDepIds[record.id] &&
userDepIds[record.id].map((item: any, index: number) => {
return (
<span key={index}>
{index === userDepIds[record.id].length - 1
? departments[item]
: departments[item] + "、"}
</span>
);
})}
</div> </div>
), ),
}, },
@ -68,27 +91,72 @@ const CourseUserPage = () => {
dataIndex: "progress", dataIndex: "progress",
render: (_, record: any) => ( render: (_, record: any) => (
<span> <span>
{record.finished_count} / {record.hour_count}
{(records[record.id] && records[record.id].finished_count) ||
0} /{" "}
{(records[record.id] && records[record.id].hour_count) ||
course.class_hour}
</span> </span>
), ),
}, },
{ {
title: "第一次学习时间", title: "第一次学习时间",
dataIndex: "created_at", dataIndex: "created_at",
render: (text: string) => <span>{dateFormat(text)}</span>, render: (_, record: any) => (
<>
{records[record.id] ? (
<span>{dateFormat(records[record.id].created_at)}</span>
) : hourCount[record.id] ? (
<span>{dateFormat(hourCount[record.id])}</span>
) : (
<span>-</span>
)}
</>
),
}, },
{ {
title: "学习完成时间", title: "学习完成时间",
dataIndex: "finished_at", dataIndex: "finished_at",
render: (text: string) => <span>{dateFormat(text)}</span>, render: (_, record: any) => (
<>
{records[record.id] ? (
<span>{dateFormat(records[record.id].finished_at)}</span>
) : (
<span>-</span>
)}
</>
),
}, },
{ {
title: "学习进度", title: "学习进度",
dataIndex: "progress", dataIndex: "progress",
render: (progress: number) => ( render: (_, record: any) => (
<span className={progress >= 10000 ? "c-green" : "c-red"}> <>
{progress / 100}% {records[record.id] ? (
</span> <span
className={
Math.floor(
(records[record.id].finished_count /
records[record.id].hour_count) *
100
) >= 100
? "c-green"
: "c-red"
}
>
{Math.floor(
(records[record.id].finished_count /
records[record.id].hour_count) *
100
)}
%
</span>
) : hourCount[record.id] ? (
<span className="c-red">1%</span>
) : (
<span className="c-red">0%</span>
)}
</>
), ),
}, },
]; ];
@ -99,21 +167,24 @@ const CourseUserPage = () => {
const getList = () => { const getList = () => {
setLoading(true); setLoading(true);
course Course.courseUser(
.courseUser( Number(params.courseId),
Number(params.courseId), page,
page, size,
size, "",
"", "",
"", name,
name, email,
email, idCard
idCard )
)
.then((res: any) => { .then((res: any) => {
setTotal(res.data.total); setTotal(res.data.total);
setList(res.data.data); setList(res.data.data);
setUsers(res.data.users); setHourCount(res.data.user_course_hour_user_first_at);
setRecords(res.data.user_course_records);
setCourse(res.data.course);
setDepartments(res.data.departments);
setUserDepIds(res.data.user_dep_ids);
setLoading(false); setLoading(false);
}) })
.catch((err: any) => { .catch((err: any) => {
@ -160,12 +231,12 @@ const CourseUserPage = () => {
okText: "确认", okText: "确认",
cancelText: "取消", cancelText: "取消",
onOk() { onOk() {
course Course.destroyCourseUser(Number(params.courseId), selectedRowKeys).then(
.destroyCourseUser(Number(params.courseId), selectedRowKeys) () => {
.then(() => {
message.success("清除成功"); message.success("清除成功");
resetList(); resetList();
}); }
);
}, },
onCancel() { onCancel() {
console.log("Cancel"); console.log("Cancel");

View File

@ -68,7 +68,7 @@ const DepartmentPage = () => {
arr.push({ arr.push({
title: ( title: (
<> <>
<div className="w-174px mr-24">{departments[id][i].name}</div> <div className="tree-title-elli">{departments[id][i].name}</div>
<div className="d-flex"> <div className="d-flex">
<Tooltip placement="top" title="可拖拽排序"> <Tooltip placement="top" title="可拖拽排序">
<i <i
@ -103,7 +103,7 @@ const DepartmentPage = () => {
arr.push({ arr.push({
title: ( title: (
<> <>
<div className="w-174px mr-24">{departments[id][i].name}</div> <div className="tree-title-elli">{departments[id][i].name}</div>
<div className="d-flex"> <div className="d-flex">
<Tooltip placement="top" title="可拖拽排序"> <Tooltip placement="top" title="可拖拽排序">
<i <i

View File

@ -31,6 +31,7 @@ const MemberLearnPage = () => {
const [currentCourses, setCurrentCourses] = useState<any>([]); const [currentCourses, setCurrentCourses] = useState<any>([]);
const [openCourses, setOpenCourses] = useState<any>([]); const [openCourses, setOpenCourses] = useState<any>([]);
const [records, setRecords] = useState<any>({}); const [records, setRecords] = useState<any>({});
const [hourCount, setHourCount] = useState<any>({});
const [total2, setTotal2] = useState(0); const [total2, setTotal2] = useState(0);
const [refresh2, setRefresh2] = useState(false); const [refresh2, setRefresh2] = useState(false);
const [uid, setUid] = useState(Number(result.get("id"))); const [uid, setUid] = useState(Number(result.get("id")));
@ -153,6 +154,7 @@ const MemberLearnPage = () => {
setList2(res.data.departments); setList2(res.data.departments);
setCourses(res.data.dep_courses); setCourses(res.data.dep_courses);
setOpenCourses(res.data.open_courses); setOpenCourses(res.data.open_courses);
setHourCount(res.data.user_course_hour_count);
setRecords(res.data.user_course_records); setRecords(res.data.user_course_records);
if (res.data.departments.length > 0) { if (res.data.departments.length > 0) {
let box: any = []; let box: any = [];
@ -252,6 +254,8 @@ const MemberLearnPage = () => {
)} )}
% %
</span> </span>
) : hourCount[record.id] && hourCount[record.id] > 0 ? (
<span className="c-red">1%</span>
) : ( ) : (
<span className="c-red">0%</span> <span className="c-red">0%</span>
)} )}

View File

@ -66,7 +66,7 @@ const ResourceCategoryPage = () => {
arr.push({ arr.push({
title: ( title: (
<> <>
<div className="w-174px mr-24">{categories[id][i].name}</div> <div className="tree-title-elli">{categories[id][i].name}</div>
<div className="d-flex"> <div className="d-flex">
<Tooltip placement="top" title="可拖拽排序"> <Tooltip placement="top" title="可拖拽排序">
<i <i
@ -101,7 +101,7 @@ const ResourceCategoryPage = () => {
arr.push({ arr.push({
title: ( title: (
<> <>
<div className="w-174px mr-24">{categories[id][i].name}</div> <div className="tree-title-elli">{categories[id][i].name}</div>
<div className="d-flex"> <div className="d-flex">
<Tooltip placement="top" title="可拖拽排序"> <Tooltip placement="top" title="可拖拽排序">
<i <i

View File

@ -25,6 +25,7 @@ import SystemAdminrolesPage from "../pages/system/adminroles";
import DepartmentPage from "../pages/department"; import DepartmentPage from "../pages/department";
import TestPage from "../pages/test"; import TestPage from "../pages/test";
import ErrorPage from "../pages/error"; import ErrorPage from "../pages/error";
import PrivateRoute from "../compenents/private-route";
// const LoginPage = lazy(() => import("../pages/login")); // const LoginPage = lazy(() => import("../pages/login"));
@ -63,70 +64,75 @@ const routes: RouteObject[] = [
children: [ children: [
{ {
path: "/", path: "/",
element: <HomePage />, element: <PrivateRoute Component={<HomePage />} />,
children: [ children: [
{ {
path: "/", path: "/",
element: <DashboardPage />, element: <PrivateRoute Component={<DashboardPage />} />,
}, },
{ {
path: "/change-password", path: "/change-password",
element: <ChangePasswordPage />, element: <PrivateRoute Component={<ChangePasswordPage />} />,
}, },
{ {
path: "/resource-category", path: "/resource-category",
element: <ResourceCategoryPage />, element: <PrivateRoute Component={<ResourceCategoryPage />} />,
}, },
{ {
path: "/images", path: "/images",
element: <ResourceImagesPage />, element: <PrivateRoute Component={<ResourceImagesPage />} />,
}, },
{ {
path: "/videos", path: "/videos",
element: <ResourceVideosPage />, element: <PrivateRoute Component={<ResourceVideosPage />} />,
}, },
{ {
path: "/course", path: "/course",
element: <CoursePage />, element: <PrivateRoute Component={<CoursePage />} />,
}, },
{ {
path: "/course/user/:courseId", path: "/course/user/:courseId",
element: <CourseUserPage />, element: <PrivateRoute Component={<CourseUserPage />} />,
}, },
{ {
path: "/member", path: "/member",
element: <KeepAlive />, element: <KeepAlive />,
children: [ children: [
{ path: "/member/index", element: <MemberPage /> }, {
path: "/member/index",
element: <PrivateRoute Component={<MemberPage />} />,
},
{ {
path: "/member/import", path: "/member/import",
element: <MemberImportPage />, element: <PrivateRoute Component={<MemberImportPage />} />,
}, },
{ {
path: "/member/learn", path: "/member/learn",
element: <MemberLearnPage />, element: <PrivateRoute Component={<MemberLearnPage />} />,
}, },
{ {
path: "/member/departmentUser", path: "/member/departmentUser",
element: <MemberDepartmentProgressPage />, element: (
<PrivateRoute Component={<MemberDepartmentProgressPage />} />
),
}, },
], ],
}, },
{ {
path: "/system/config/index", path: "/system/config/index",
element: <SystemConfigPage />, element: <PrivateRoute Component={<SystemConfigPage />} />,
}, },
{ {
path: "/system/administrator", path: "/system/administrator",
element: <SystemAdministratorPage />, element: <PrivateRoute Component={<SystemAdministratorPage />} />,
}, },
{ {
path: "/system/adminroles", path: "/system/adminroles",
element: <SystemAdminrolesPage />, element: <PrivateRoute Component={<SystemAdminrolesPage />} />,
}, },
{ {
path: "/department", path: "/department",
element: <DepartmentPage />, element: <PrivateRoute Component={<DepartmentPage />} />,
}, },
], ],
}, },