mirror of
https://github.com/PlayEdu/backend
synced 2025-07-22 00:19:37 +08:00
数据结构添加interface
This commit is contained in:
parent
3b2f7f222c
commit
cf7feffe27
@ -12,7 +12,6 @@ import {
|
||||
Dropdown,
|
||||
} from "antd";
|
||||
import { course } from "../../api";
|
||||
// import styles from "./index.module.less";
|
||||
import {
|
||||
PlusOutlined,
|
||||
DownOutlined,
|
||||
@ -33,43 +32,46 @@ const { confirm } = Modal;
|
||||
|
||||
interface DataType {
|
||||
id: React.Key;
|
||||
title: string;
|
||||
created_at: string;
|
||||
thumb: string;
|
||||
charge: number;
|
||||
class_hour: number;
|
||||
created_at: string;
|
||||
is_required: number;
|
||||
is_show: number;
|
||||
short_desc: string;
|
||||
thumb: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
const CoursePage = () => {
|
||||
const result = new URLSearchParams(useLocation().search);
|
||||
const navigate = useNavigate();
|
||||
const [list, setList] = useState<any>([]);
|
||||
const [list, setList] = useState<DataType[]>([]);
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
const [page, setPage] = useState(1);
|
||||
const [size, setSize] = useState(10);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [category_ids, setCategoryIds] = useState<any>([]);
|
||||
const [title, setTitle] = useState<string>("");
|
||||
const [dep_ids, setDepIds] = useState<any>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [category_ids, setCategoryIds] = useState<number[]>([]);
|
||||
const [title, setTitle] = useState("");
|
||||
const [dep_ids, setDepIds] = useState<number[]>([]);
|
||||
const [selLabel, setLabel] = useState<string>(
|
||||
result.get("label") ? String(result.get("label")) : "全部分类"
|
||||
);
|
||||
const [selDepLabel, setDepLabel] = useState<string>(
|
||||
result.get("label") ? String(result.get("label")) : "全部部门"
|
||||
);
|
||||
const [course_category_ids, setCourseCategoryIds] = useState<any>({});
|
||||
const [course_dep_ids, setCourseDepIds] = useState<any>({});
|
||||
const [categories, setCategories] = useState<any>({});
|
||||
const [departments, setDepartments] = useState<any>({});
|
||||
const [course_category_ids, setCourseCategoryIds] =
|
||||
useState<CategoryIdsModel>({});
|
||||
const [course_dep_ids, setCourseDepIds] = useState<DepIdsModel>({});
|
||||
const [categories, setCategories] = useState<CategoriesModel>({});
|
||||
const [departments, setDepartments] = useState<DepartmentsModel>({});
|
||||
const [tabKey, setTabKey] = useState(result.get("did") ? "2" : "1");
|
||||
|
||||
const [createVisible, setCreateVisible] = useState<boolean>(false);
|
||||
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
||||
const [updateHourVisible, setHourUpdateVisible] = useState<boolean>(false);
|
||||
const [updateAttachmentVisible, setUpdateAttachmentVisible] =
|
||||
useState<boolean>(false);
|
||||
const [cid, setCid] = useState<number>(0);
|
||||
const [createVisible, setCreateVisible] = useState(false);
|
||||
const [updateVisible, setUpdateVisible] = useState(false);
|
||||
const [updateHourVisible, setHourUpdateVisible] = useState(false);
|
||||
const [updateAttachmentVisible, setUpdateAttachmentVisible] = useState(false);
|
||||
const [cid, setCid] = useState(0);
|
||||
const [cateId, setCateId] = useState(Number(result.get("cid")));
|
||||
const [did, setDid] = useState(Number(result.get("did")));
|
||||
|
||||
|
@ -22,30 +22,61 @@ const { confirm } = Modal;
|
||||
|
||||
interface DataType {
|
||||
id: React.Key;
|
||||
title: string;
|
||||
created_at: string;
|
||||
thumb: string;
|
||||
charge: number;
|
||||
is_show: number;
|
||||
avatar: string;
|
||||
create_city?: string;
|
||||
create_ip?: string;
|
||||
created_at?: string;
|
||||
credit1?: number;
|
||||
email: string;
|
||||
id_card?: string;
|
||||
is_active?: number;
|
||||
is_lock?: number;
|
||||
is_set_password?: number;
|
||||
is_verify?: number;
|
||||
login_at?: string;
|
||||
name: string;
|
||||
updated_at?: string;
|
||||
verify_at?: string;
|
||||
}
|
||||
|
||||
type UserCourseRecordsModel = {
|
||||
[key: number]: CourseRecordModel;
|
||||
};
|
||||
|
||||
type CourseRecordModel = {
|
||||
course_id: number;
|
||||
created_at: string;
|
||||
finished_at?: string;
|
||||
finished_count: number;
|
||||
hour_count: number;
|
||||
id: number;
|
||||
is_finished: number;
|
||||
progress: number;
|
||||
updated_at: string;
|
||||
user_id: number;
|
||||
};
|
||||
|
||||
type HourCountModel = {
|
||||
[key: number]: string;
|
||||
};
|
||||
|
||||
const CourseUserPage = () => {
|
||||
const params = useParams();
|
||||
const result = new URLSearchParams(useLocation().search);
|
||||
const [list, setList] = 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 [list, setList] = useState<DataType[]>([]);
|
||||
const [course, setCourse] = useState<CourseModel | null>(null);
|
||||
const [records, setRecords] = useState<UserCourseRecordsModel>({});
|
||||
const [hourCount, setHourCount] = useState<HourCountModel>({});
|
||||
const [userDepIds, setUserDepIds] = useState<DepIdsModel>({});
|
||||
const [departments, setDepartments] = useState<DepartmentsModel>({});
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
const [page, setPage] = useState(1);
|
||||
const [size, setSize] = useState(10);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [name, setName] = useState<string>("");
|
||||
const [email, setEmail] = useState<string>("");
|
||||
const [idCard, setIdCard] = useState<string>("");
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [name, setName] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [idCard, setIdCard] = useState("");
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<any>([]);
|
||||
const [title, setTitle] = useState<string>(String(result.get("title")));
|
||||
|
||||
@ -95,7 +126,7 @@ const CourseUserPage = () => {
|
||||
{(records[record.id] && records[record.id].finished_count) ||
|
||||
0} /{" "}
|
||||
{(records[record.id] && records[record.id].hour_count) ||
|
||||
course.class_hour}
|
||||
course?.class_hour}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
@ -116,11 +147,11 @@ const CourseUserPage = () => {
|
||||
},
|
||||
{
|
||||
title: "学习完成时间",
|
||||
dataIndex: "finished_at",
|
||||
dataIndex: "id",
|
||||
render: (_, record: any) => (
|
||||
<>
|
||||
{records[record.id] ? (
|
||||
<span>{dateFormat(records[record.id].finished_at)}</span>
|
||||
<span>{dateFormat(String(records[record.id].finished_at))}</span>
|
||||
) : (
|
||||
<span>-</span>
|
||||
)}
|
||||
|
@ -12,10 +12,38 @@ import { dashboard } from "../../api/index";
|
||||
import { timeFormat } from "../../utils/index";
|
||||
import * as echarts from "echarts";
|
||||
|
||||
type BasicDataModel = {
|
||||
admin_user_total: number;
|
||||
course_total: number;
|
||||
department_total: number;
|
||||
resource_category_total: number;
|
||||
resource_image_total: number;
|
||||
resource_video_total: number;
|
||||
user_learn_today: number;
|
||||
user_learn_top10?: Top10Model[];
|
||||
user_learn_top10_users?: Top10UserModel;
|
||||
user_learn_yesterday: number;
|
||||
user_today: number;
|
||||
user_total: number;
|
||||
user_yesterday: number;
|
||||
version: string;
|
||||
};
|
||||
|
||||
type Top10Model = {
|
||||
created_date: string;
|
||||
duration: number;
|
||||
id: number;
|
||||
user_id: number;
|
||||
};
|
||||
|
||||
type Top10UserModel = {
|
||||
[key: number]: UserModel;
|
||||
};
|
||||
|
||||
const DashboardPage = () => {
|
||||
let chartRef = useRef(null);
|
||||
const navigate = useNavigate();
|
||||
const [basicData, setBasicData] = useState<any>([]);
|
||||
const [basicData, setBasicData] = useState<BasicDataModel | null>(null);
|
||||
|
||||
const getData = () => {
|
||||
dashboard.dashboardList().then((res: any) => {
|
||||
@ -164,31 +192,35 @@ const DashboardPage = () => {
|
||||
<div className={styles["label"]}>今日学习学员</div>
|
||||
<div className={styles["info"]}>
|
||||
<div className={styles["num"]}>
|
||||
{basicData.user_learn_today}
|
||||
</div>
|
||||
<div className={styles["compare"]}>
|
||||
<span className="mr-5">较昨日</span>
|
||||
{compareNum(
|
||||
basicData.user_learn_today,
|
||||
basicData.user_learn_yesterday
|
||||
)}
|
||||
{basicData?.user_learn_today}
|
||||
</div>
|
||||
{basicData && (
|
||||
<div className={styles["compare"]}>
|
||||
<span className="mr-5">较昨日</span>
|
||||
{compareNum(
|
||||
basicData.user_learn_today,
|
||||
basicData.user_learn_yesterday
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles["label-item"]}>
|
||||
<div className={styles["label"]}>总学员数</div>
|
||||
<div className={styles["info"]}>
|
||||
<div className={styles["num"]}>{basicData.user_total}</div>
|
||||
<div className={styles["compare"]}>
|
||||
<span className="mr-5">较昨日</span>
|
||||
{compareNum(basicData.user_today, 0)}
|
||||
</div>
|
||||
<div className={styles["num"]}>{basicData?.user_total}</div>
|
||||
{basicData && (
|
||||
<div className={styles["compare"]}>
|
||||
<span className="mr-5">较昨日</span>
|
||||
{compareNum(basicData.user_today, 0)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles["label-item"]}>
|
||||
<div className={styles["label"]}>线上课数</div>
|
||||
<div className={styles["info"]}>
|
||||
<div className={styles["num"]}>{basicData.course_total}</div>
|
||||
<div className={styles["num"]}>{basicData?.course_total}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -249,7 +281,7 @@ const DashboardPage = () => {
|
||||
<div className="playedu-main-top mt-24" style={{ minHeight: 376 }}>
|
||||
<div className={styles["large-title"]}>今日学习排行</div>
|
||||
<div className={styles["rank-list"]}>
|
||||
{basicData.user_learn_top10 && (
|
||||
{basicData?.user_learn_top10 && (
|
||||
<div className={styles["half-list"]}>
|
||||
<div className={styles["rank-item"]}>
|
||||
<div className={styles["left-item"]}>
|
||||
@ -258,15 +290,16 @@ const DashboardPage = () => {
|
||||
src={iconN1}
|
||||
alt=""
|
||||
/>
|
||||
{basicData.user_learn_top10[0] && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[0].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
{basicData.user_learn_top10[0] &&
|
||||
basicData.user_learn_top10_users && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[0].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{basicData.user_learn_top10[0] && (
|
||||
<div className={styles["item-time"]}>
|
||||
@ -283,15 +316,16 @@ const DashboardPage = () => {
|
||||
src={iconN2}
|
||||
alt=""
|
||||
/>
|
||||
{basicData.user_learn_top10[1] && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[1].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
{basicData.user_learn_top10[1] &&
|
||||
basicData.user_learn_top10_users && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[1].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{basicData.user_learn_top10[1] && (
|
||||
<div className={styles["item-time"]}>
|
||||
@ -308,15 +342,16 @@ const DashboardPage = () => {
|
||||
src={iconN3}
|
||||
alt=""
|
||||
/>
|
||||
{basicData.user_learn_top10[2] && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[2].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
{basicData.user_learn_top10[2] &&
|
||||
basicData.user_learn_top10_users && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[2].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{basicData.user_learn_top10[2] && (
|
||||
<div className={styles["item-time"]}>
|
||||
@ -329,15 +364,16 @@ const DashboardPage = () => {
|
||||
<div className={styles["rank-item"]}>
|
||||
<div className={styles["left-item"]}>
|
||||
<div className={styles["item-num"]}>4</div>
|
||||
{basicData.user_learn_top10[3] && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[3].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
{basicData.user_learn_top10[3] &&
|
||||
basicData.user_learn_top10_users && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[3].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{basicData.user_learn_top10[3] && (
|
||||
<div className={styles["item-time"]}>
|
||||
@ -350,15 +386,16 @@ const DashboardPage = () => {
|
||||
<div className={styles["rank-item"]}>
|
||||
<div className={styles["left-item"]}>
|
||||
<div className={styles["item-num"]}>5</div>
|
||||
{basicData.user_learn_top10[4] && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[4].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
{basicData.user_learn_top10[4] &&
|
||||
basicData.user_learn_top10_users && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[4].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{basicData.user_learn_top10[4] && (
|
||||
<div className={styles["item-time"]}>
|
||||
@ -370,20 +407,21 @@ const DashboardPage = () => {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{basicData.user_learn_top10 && (
|
||||
{basicData?.user_learn_top10 && (
|
||||
<div className={styles["half-list"]}>
|
||||
<div className={styles["rank-item"]}>
|
||||
<div className={styles["left-item"]}>
|
||||
<div className={styles["item-num"]}>6</div>
|
||||
{basicData.user_learn_top10[5] && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[5].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
{basicData.user_learn_top10[5] &&
|
||||
basicData.user_learn_top10_users && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[5].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{basicData.user_learn_top10[5] && (
|
||||
<div className={styles["item-time"]}>
|
||||
@ -396,15 +434,16 @@ const DashboardPage = () => {
|
||||
<div className={styles["rank-item"]}>
|
||||
<div className={styles["left-item"]}>
|
||||
<div className={styles["item-num"]}>7</div>
|
||||
{basicData.user_learn_top10[6] && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[6].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
{basicData.user_learn_top10[6] &&
|
||||
basicData.user_learn_top10_users && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[6].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{basicData.user_learn_top10[6] && (
|
||||
<div className={styles["item-time"]}>
|
||||
@ -417,15 +456,16 @@ const DashboardPage = () => {
|
||||
<div className={styles["rank-item"]}>
|
||||
<div className={styles["left-item"]}>
|
||||
<div className={styles["item-num"]}>8</div>
|
||||
{basicData.user_learn_top10[7] && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[7].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
{basicData.user_learn_top10[7] &&
|
||||
basicData.user_learn_top10_users && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[7].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{basicData.user_learn_top10[7] && (
|
||||
<div className={styles["item-time"]}>
|
||||
@ -438,15 +478,16 @@ const DashboardPage = () => {
|
||||
<div className={styles["rank-item"]}>
|
||||
<div className={styles["left-item"]}>
|
||||
<div className={styles["item-num"]}>9</div>
|
||||
{basicData.user_learn_top10[8] && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[8].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
{basicData.user_learn_top10[8] &&
|
||||
basicData.user_learn_top10_users && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[8].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{basicData.user_learn_top10[8] && (
|
||||
<div className={styles["item-time"]}>
|
||||
@ -459,15 +500,16 @@ const DashboardPage = () => {
|
||||
<div className={styles["rank-item"]}>
|
||||
<div className={styles["left-item"]}>
|
||||
<div className={styles["item-num"]}>10</div>
|
||||
{basicData.user_learn_top10[9] && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[9].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
{basicData.user_learn_top10[9] &&
|
||||
basicData.user_learn_top10_users && (
|
||||
<div className={styles["item-name"]}>
|
||||
{
|
||||
basicData.user_learn_top10_users[
|
||||
basicData.user_learn_top10[9].user_id
|
||||
]?.name
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{basicData.user_learn_top10[9] && (
|
||||
<div className={styles["item-time"]}>
|
||||
@ -489,7 +531,7 @@ const DashboardPage = () => {
|
||||
<div className={styles["label"]}>部门数</div>
|
||||
<div className={styles["info"]}>
|
||||
<div className={styles["num"]}>
|
||||
{basicData.department_total}
|
||||
{basicData?.department_total}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -497,7 +539,7 @@ const DashboardPage = () => {
|
||||
<div className={styles["label"]}>分类数</div>
|
||||
<div className={styles["info"]}>
|
||||
<div className={styles["num"]}>
|
||||
{basicData.resource_category_total}
|
||||
{basicData?.resource_category_total}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -505,7 +547,7 @@ const DashboardPage = () => {
|
||||
<div className={styles["label"]}>管理员</div>
|
||||
<div className={styles["info"]}>
|
||||
<div className={styles["num"]}>
|
||||
{basicData.admin_user_total}
|
||||
{basicData?.admin_user_total}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -25,8 +25,8 @@ const DepartmentPage = () => {
|
||||
);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
const [treeData, setTreeData] = useState<any>([]);
|
||||
const [selectKey, setSelectKey] = useState<any>([]);
|
||||
const [treeData, setTreeData] = useState<Option[]>([]);
|
||||
const [selectKey, setSelectKey] = useState<number[]>([]);
|
||||
|
||||
const [createVisible, setCreateVisible] = useState<boolean>(false);
|
||||
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
||||
|
@ -28,34 +28,43 @@ const { confirm } = Modal;
|
||||
|
||||
interface DataType {
|
||||
id: React.Key;
|
||||
name: string;
|
||||
avatar: string;
|
||||
create_city?: string;
|
||||
create_ip?: string;
|
||||
created_at?: string;
|
||||
credit1?: number;
|
||||
email: string;
|
||||
created_at: string;
|
||||
credit1: number;
|
||||
id_card: string;
|
||||
is_lock: number;
|
||||
id_card?: string;
|
||||
is_active?: number;
|
||||
is_lock?: number;
|
||||
is_set_password?: number;
|
||||
is_verify?: number;
|
||||
login_at?: string;
|
||||
name: string;
|
||||
updated_at?: string;
|
||||
verify_at?: string;
|
||||
}
|
||||
|
||||
const MemberPage = () => {
|
||||
const result = new URLSearchParams(useLocation().search);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [page, setPage] = useState(1);
|
||||
const [size, setSize] = useState(10);
|
||||
const [list, setList] = useState<any>([]);
|
||||
const [list, setList] = useState<DataType[]>([]);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
|
||||
const [nickname, setNickname] = useState<string>("");
|
||||
const [email, setEmail] = useState<string>("");
|
||||
const [dep_ids, setDepIds] = useState<any>([]);
|
||||
const [nickname, setNickname] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [dep_ids, setDepIds] = useState<number[]>([]);
|
||||
const [selLabel, setLabel] = useState<string>(
|
||||
result.get("label") ? String(result.get("label")) : "全部部门"
|
||||
);
|
||||
const [createVisible, setCreateVisible] = useState<boolean>(false);
|
||||
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
||||
const [mid, setMid] = useState<number>(0);
|
||||
const [user_dep_ids, setUserDepIds] = useState<any>({});
|
||||
const [departments, setDepartments] = useState<any>({});
|
||||
const [createVisible, setCreateVisible] = useState(false);
|
||||
const [updateVisible, setUpdateVisible] = useState(false);
|
||||
const [mid, setMid] = useState(0);
|
||||
const [user_dep_ids, setUserDepIds] = useState<DepIdsModel>({});
|
||||
const [departments, setDepartments] = useState<DepartmentsModel>({});
|
||||
const [did, setDid] = useState(Number(result.get("did")));
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -11,33 +11,71 @@ import { MemberLearnProgressDialog } from "./compenents/progress";
|
||||
|
||||
interface DataType {
|
||||
id: React.Key;
|
||||
title: string;
|
||||
type: string;
|
||||
charge: number;
|
||||
class_hour: number;
|
||||
created_at: string;
|
||||
total_duration: number;
|
||||
finished_duration: number;
|
||||
is_finished: boolean;
|
||||
is_required: number;
|
||||
is_show: number;
|
||||
short_desc: string;
|
||||
thumb: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
type UserCourseRecordsModel = {
|
||||
[key: number]: UserRecordModel;
|
||||
};
|
||||
|
||||
type UserRecordModel = {
|
||||
course_id: number;
|
||||
created_at: string;
|
||||
finished_at?: string;
|
||||
finished_count: number;
|
||||
hour_count: number;
|
||||
id: number;
|
||||
is_finished: number;
|
||||
progress: number;
|
||||
updated_at: string;
|
||||
user_id: number;
|
||||
};
|
||||
|
||||
type HourCountModel = {
|
||||
[key: number]: number;
|
||||
};
|
||||
|
||||
type OptionModel = {
|
||||
label: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
type DepartmentsListModel = {
|
||||
reated_at: string;
|
||||
id: number;
|
||||
name: string;
|
||||
parent_chain: string;
|
||||
parent_id: number;
|
||||
sort: number;
|
||||
updated_at: string;
|
||||
};
|
||||
|
||||
const MemberLearnPage = () => {
|
||||
let chartRef = useRef(null);
|
||||
const navigate = useNavigate();
|
||||
const result = new URLSearchParams(useLocation().search);
|
||||
const [loading2, setLoading2] = useState<boolean>(false);
|
||||
const [list2, setList2] = useState<any>([]);
|
||||
const [loading2, setLoading2] = useState(false);
|
||||
const [list2, setList2] = useState<DepartmentsListModel[]>([]);
|
||||
const [courses, setCourses] = useState<any>({});
|
||||
const [deps, setDeps] = useState<any>([]);
|
||||
const [depValue, setDepValue] = useState<number>(0);
|
||||
const [currentCourses, setCurrentCourses] = useState<any>([]);
|
||||
const [openCourses, setOpenCourses] = useState<any>([]);
|
||||
const [records, setRecords] = useState<any>({});
|
||||
const [hourCount, setHourCount] = useState<any>({});
|
||||
const [deps, setDeps] = useState<OptionModel[]>([]);
|
||||
const [depValue, setDepValue] = useState(0);
|
||||
const [currentCourses, setCurrentCourses] = useState<DataType[]>([]);
|
||||
const [openCourses, setOpenCourses] = useState<CourseModel[]>([]);
|
||||
const [records, setRecords] = useState<UserCourseRecordsModel>({});
|
||||
const [hourCount, setHourCount] = useState<HourCountModel>({});
|
||||
const [total2, setTotal2] = useState(0);
|
||||
const [refresh2, setRefresh2] = useState(false);
|
||||
const [uid, setUid] = useState(Number(result.get("id")));
|
||||
const [userName, setUserName] = useState<string>(String(result.get("name")));
|
||||
const [visiable, setVisiable] = useState(false);
|
||||
const [courseId, setcourseId] = useState<number>(0);
|
||||
const [courseId, setcourseId] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
setUid(Number(result.get("id")));
|
||||
@ -157,7 +195,7 @@ const MemberLearnPage = () => {
|
||||
setHourCount(res.data.user_course_hour_count);
|
||||
setRecords(res.data.user_course_records);
|
||||
if (res.data.departments.length > 0) {
|
||||
let box: any = [];
|
||||
let box: OptionModel[] = [];
|
||||
res.data.departments.map((item: any) => {
|
||||
box.push({
|
||||
label: item.name,
|
||||
@ -223,7 +261,7 @@ const MemberLearnPage = () => {
|
||||
render: (_, record: any) => (
|
||||
<>
|
||||
{records[record.id] ? (
|
||||
<span>{dateFormat(records[record.id].finished_at)}</span>
|
||||
<span>{dateFormat(String(records[record.id].finished_at))}</span>
|
||||
) : (
|
||||
<span>-</span>
|
||||
)}
|
||||
@ -232,7 +270,6 @@ const MemberLearnPage = () => {
|
||||
},
|
||||
{
|
||||
title: "学习进度",
|
||||
dataIndex: "is_finished",
|
||||
render: (_, record: any) => (
|
||||
<>
|
||||
{records[record.id] ? (
|
||||
|
@ -9,11 +9,9 @@ import {
|
||||
Select,
|
||||
Button,
|
||||
} from "antd";
|
||||
import type { MenuProps } from "antd";
|
||||
import { resource } from "../../../api";
|
||||
// import styles from "./index.module.less";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { DownOutlined, ExclamationCircleFilled } from "@ant-design/icons";
|
||||
import { ExclamationCircleFilled } from "@ant-design/icons";
|
||||
import type { ColumnsType } from "antd/es/table";
|
||||
import { dateFormat } from "../../../utils/index";
|
||||
import { TreeCategory, UploadCoursewareButton } from "../../../compenents";
|
||||
@ -22,34 +20,45 @@ import { CoursewareUpdateDialog } from "./compenents/update-dialog";
|
||||
const { confirm } = Modal;
|
||||
|
||||
interface DataType {
|
||||
admin_id: number;
|
||||
created_at: string;
|
||||
disk: string;
|
||||
extension: string;
|
||||
file_id: string;
|
||||
id: React.Key;
|
||||
name: string;
|
||||
created_at: string;
|
||||
parent_id: number;
|
||||
path: string;
|
||||
size: number;
|
||||
type: string;
|
||||
number: number;
|
||||
url: string;
|
||||
}
|
||||
|
||||
type AdminUsersModel = {
|
||||
[key: number]: string;
|
||||
};
|
||||
|
||||
const ResourceCoursewarePage = () => {
|
||||
const result = new URLSearchParams(useLocation().search);
|
||||
const [list, setList] = useState<any>([]);
|
||||
const [adminUsers, setAdminUsers] = useState<any>({});
|
||||
const [existingTypes, setExistingTypes] = useState<any>([]);
|
||||
const [list, setList] = useState<DataType[]>([]);
|
||||
const [adminUsers, setAdminUsers] = useState<AdminUsersModel>({});
|
||||
const [existingTypes, setExistingTypes] = useState<string[]>([]);
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
const [page, setPage] = useState(1);
|
||||
const [size, setSize] = useState(10);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [category_ids, setCategoryIds] = useState<any>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [category_ids, setCategoryIds] = useState<number[]>([]);
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<any>([]);
|
||||
const [type, setType] = useState("WORD,EXCEL,PPT,PDF,TXT,RAR,ZIP");
|
||||
const [title, setTitle] = useState<string>("");
|
||||
const [multiConfig, setMultiConfig] = useState<boolean>(false);
|
||||
const [title, setTitle] = useState("");
|
||||
const [multiConfig, setMultiConfig] = useState(false);
|
||||
const [selLabel, setLabel] = useState<string>(
|
||||
result.get("label") ? String(result.get("label")) : "全部课件"
|
||||
);
|
||||
const [cateId, setCateId] = useState(Number(result.get("cid")));
|
||||
const [updateId, setUpdateId] = useState(0);
|
||||
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
||||
const [updateVisible, setUpdateVisible] = useState(false);
|
||||
const types = [
|
||||
{ label: "全部", value: "WORD,EXCEL,PPT,PDF,TXT,RAR,ZIP" },
|
||||
{ label: "WORD", value: "WORD" },
|
||||
|
@ -14,7 +14,7 @@ import { resource } from "../../../api";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import styles from "./index.module.less";
|
||||
import { UploadImageSub } from "../../../compenents/upload-image-button/upload-image-sub";
|
||||
import { TreeCategory, PerButton } from "../../../compenents";
|
||||
import { TreeCategory } from "../../../compenents";
|
||||
import { ExclamationCircleFilled, CheckOutlined } from "@ant-design/icons";
|
||||
|
||||
const { confirm } = Modal;
|
||||
@ -39,14 +39,14 @@ const ResourceImagesPage = () => {
|
||||
const [page, setPage] = useState(1);
|
||||
const [size, setSize] = useState(32);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [category_ids, setCategoryIds] = useState<any>([]);
|
||||
const [selectKey, setSelectKey] = useState<any>([]);
|
||||
const [visibleArr, setVisibleArr] = useState<any>([]);
|
||||
const [hoverArr, setHoverArr] = useState<any>([]);
|
||||
const [category_ids, setCategoryIds] = useState<number[]>([]);
|
||||
const [selectKey, setSelectKey] = useState<number[]>([]);
|
||||
const [visibleArr, setVisibleArr] = useState<boolean[]>([]);
|
||||
const [hoverArr, setHoverArr] = useState<boolean[]>([]);
|
||||
const [selLabel, setLabel] = useState<string>(
|
||||
result.get("label") ? String(result.get("label")) : "全部图片"
|
||||
);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [cateId, setCateId] = useState(Number(result.get("cid")));
|
||||
|
||||
useEffect(() => {
|
||||
@ -96,7 +96,7 @@ const ResourceImagesPage = () => {
|
||||
.then((res: any) => {
|
||||
setTotal(res.data.result.total);
|
||||
setImageList(res.data.result.data);
|
||||
let data = res.data.result.data;
|
||||
let data: ImageItem[] = res.data.result.data;
|
||||
let arr = [];
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
arr.push(false);
|
||||
|
@ -25,8 +25,8 @@ const ResourceCategoryPage = () => {
|
||||
);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
const [treeData, setTreeData] = useState<any>([]);
|
||||
const [selectKey, setSelectKey] = useState<any>([]);
|
||||
const [treeData, setTreeData] = useState<Option[]>([]);
|
||||
const [selectKey, setSelectKey] = useState<number[]>([]);
|
||||
const [createVisible, setCreateVisible] = useState<boolean>(false);
|
||||
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
||||
const [cid, setCid] = useState<number>(0);
|
||||
|
@ -2,7 +2,6 @@ import { useEffect, useState } from "react";
|
||||
import { Modal, Table, message, Space, Dropdown, Button } from "antd";
|
||||
import type { MenuProps } from "antd";
|
||||
import { resource } from "../../../api";
|
||||
// import styles from "./index.module.less";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { DownOutlined, ExclamationCircleFilled } from "@ant-design/icons";
|
||||
import type { ColumnsType } from "antd/es/table";
|
||||
@ -16,32 +15,54 @@ const { confirm } = Modal;
|
||||
|
||||
interface DataType {
|
||||
id: React.Key;
|
||||
name: string;
|
||||
admin_id: number;
|
||||
created_at: string;
|
||||
disk: string;
|
||||
extension: string;
|
||||
file_id: string;
|
||||
name: string;
|
||||
parent_id: number;
|
||||
path: string;
|
||||
size: number;
|
||||
type: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
type VideosExtraModel = {
|
||||
[key: number]: VideoModel;
|
||||
};
|
||||
|
||||
type VideoModel = {
|
||||
duration: number;
|
||||
poster: string;
|
||||
rid: number;
|
||||
};
|
||||
|
||||
type AdminUsersModel = {
|
||||
[key: number]: string;
|
||||
};
|
||||
|
||||
const ResourceVideosPage = () => {
|
||||
const result = new URLSearchParams(useLocation().search);
|
||||
const [videoList, setVideoList] = useState<any>([]);
|
||||
const [videosExtra, setVideoExtra] = useState<any>([]);
|
||||
const [adminUsers, setAdminUsers] = useState<any>({});
|
||||
const [videoList, setVideoList] = useState<DataType[]>([]);
|
||||
const [videosExtra, setVideoExtra] = useState<VideosExtraModel>({});
|
||||
const [adminUsers, setAdminUsers] = useState<AdminUsersModel>({});
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
const [page, setPage] = useState(1);
|
||||
const [size, setSize] = useState(10);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [category_ids, setCategoryIds] = useState<any>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [category_ids, setCategoryIds] = useState<number[]>([]);
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<any>([]);
|
||||
const [selLabel, setLabel] = useState<string>(
|
||||
result.get("label") ? String(result.get("label")) : "全部视频"
|
||||
);
|
||||
const [cateId, setCateId] = useState(Number(result.get("cid")));
|
||||
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
||||
const [playVisible, setPlayeVisible] = useState<boolean>(false);
|
||||
const [multiConfig, setMultiConfig] = useState<boolean>(false);
|
||||
const [updateVisible, setUpdateVisible] = useState(false);
|
||||
const [playVisible, setPlayeVisible] = useState(false);
|
||||
const [multiConfig, setMultiConfig] = useState(false);
|
||||
const [updateId, setUpdateId] = useState(0);
|
||||
const [playUrl, setPlayUrl] = useState<string>("");
|
||||
const [playUrl, setPlayUrl] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
setCateId(Number(result.get("cid")));
|
||||
@ -72,20 +93,22 @@ const ResourceVideosPage = () => {
|
||||
{
|
||||
title: "视频时长",
|
||||
dataIndex: "id",
|
||||
render: (id: string) => (
|
||||
render: (id: number) => (
|
||||
<DurationText duration={videosExtra[id].duration}></DurationText>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "创建人",
|
||||
dataIndex: "admin_id",
|
||||
render: (text: number) =>
|
||||
JSON.stringify(adminUsers) !== "{}" && <span>{adminUsers[text]}</span>,
|
||||
render: (admin_id: number) =>
|
||||
JSON.stringify(adminUsers) !== "{}" && (
|
||||
<span>{adminUsers[admin_id]}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
dataIndex: "created_at",
|
||||
render: (text: string) => <span>{dateFormat(text)}</span>,
|
||||
render: (created_at: string) => <span>{dateFormat(created_at)}</span>,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
|
@ -15,29 +15,48 @@ const { confirm } = Modal;
|
||||
|
||||
interface DataType {
|
||||
id: React.Key;
|
||||
name: string;
|
||||
created_at: string;
|
||||
email: string;
|
||||
is_ban_login: number;
|
||||
login_at: string;
|
||||
login_ip: string;
|
||||
is_ban_login: number;
|
||||
login_times: number;
|
||||
name: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
type RolesModel = {
|
||||
[key: number]: RoleModel[];
|
||||
};
|
||||
|
||||
type RoleModel = {
|
||||
created_at: string;
|
||||
id: number;
|
||||
name: string;
|
||||
slug: string;
|
||||
updated_at: string;
|
||||
};
|
||||
|
||||
type RoleIdsModel = {
|
||||
[key: number]: number[];
|
||||
};
|
||||
|
||||
const SystemAdministratorPage = () => {
|
||||
const navigate = useNavigate();
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [page, setPage] = useState(1);
|
||||
const [size, setSize] = useState(10);
|
||||
const [list, setList] = useState<any>([]);
|
||||
const [roles, setRoles] = useState<any>([]);
|
||||
const [userRoleIds, setUserRoleIds] = useState<any>({});
|
||||
const [list, setList] = useState<DataType[]>([]);
|
||||
const [roles, setRoles] = useState<RolesModel>({});
|
||||
const [userRoleIds, setUserRoleIds] = useState<RoleIdsModel>({});
|
||||
const [total, setTotal] = useState(0);
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
const [createVisible, setCreateVisible] = useState<boolean>(false);
|
||||
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
||||
const [createRoleVisible, setCreateRoleVisible] = useState<boolean>(false);
|
||||
const [updateRoleVisible, setUpdateRoleVisible] = useState<boolean>(false);
|
||||
const [cid, setCid] = useState<number>(0);
|
||||
const [role_ids, setRoleIds] = useState<any>([]);
|
||||
const [createVisible, setCreateVisible] = useState(false);
|
||||
const [updateVisible, setUpdateVisible] = useState(false);
|
||||
const [createRoleVisible, setCreateRoleVisible] = useState(false);
|
||||
const [updateRoleVisible, setUpdateRoleVisible] = useState(false);
|
||||
const [cid, setCid] = useState(0);
|
||||
const [role_ids, setRoleIds] = useState<number[]>([]);
|
||||
const [selLabel, setLabel] = useState<string>("全部管理员");
|
||||
const [roleDelSuccess, setRoleDelSuccess] = useState(false);
|
||||
const [isSuper, setIsSuper] = useState(false);
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { Table, Typography, Input, Button, DatePicker } from "antd";
|
||||
import { adminLog } from "../../../api";
|
||||
// import styles from "./index.module.less";
|
||||
import type { ColumnsType } from "antd/es/table";
|
||||
import { dateWholeFormat, transUtcTime } from "../../../utils/index";
|
||||
import { AdminLogDetailDialog } from "./compenents/detail-dialog";
|
||||
@ -11,22 +10,26 @@ import moment from "moment";
|
||||
interface DataType {
|
||||
id: React.Key;
|
||||
admin_id: number;
|
||||
ip: string;
|
||||
opt: string;
|
||||
admin_name: string;
|
||||
module: string;
|
||||
created_at: string;
|
||||
title: string;
|
||||
error_msg?: string;
|
||||
ip: string;
|
||||
ip_area: string;
|
||||
method: string;
|
||||
module: string;
|
||||
opt: number;
|
||||
param: string;
|
||||
request_method: string;
|
||||
result: string;
|
||||
title: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
const SystemLogPage = () => {
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [page, setPage] = useState(1);
|
||||
const [size, setSize] = useState(10);
|
||||
const [list, setList] = useState<any>([]);
|
||||
const [list, setList] = useState<DataType[]>([]);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
const [title, setTitle] = useState("");
|
||||
|
47
src/playedu.d.ts
vendored
47
src/playedu.d.ts
vendored
@ -15,6 +15,53 @@ declare global {
|
||||
poster: string; //视频帧
|
||||
};
|
||||
}
|
||||
|
||||
interface UserModel {
|
||||
avatar: string;
|
||||
create_city?: string;
|
||||
create_ip?: string;
|
||||
created_at?: string;
|
||||
credit1?: number;
|
||||
email: string;
|
||||
id: number;
|
||||
id_card?: string;
|
||||
is_active?: number;
|
||||
is_lock?: number;
|
||||
is_set_password?: number;
|
||||
is_verify?: number;
|
||||
login_at?: string;
|
||||
name: string;
|
||||
updated_at?: string;
|
||||
verify_at?: string;
|
||||
}
|
||||
|
||||
interface CourseModel {
|
||||
charge: number;
|
||||
class_hour: number;
|
||||
created_at: string;
|
||||
id: number;
|
||||
is_required: number;
|
||||
is_show: number;
|
||||
short_desc: string;
|
||||
thumb: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
interface CategoriesModel {
|
||||
[key: number]: string;
|
||||
}
|
||||
|
||||
interface DepartmentsModel {
|
||||
[key: number]: string;
|
||||
}
|
||||
|
||||
interface DepIdsModel {
|
||||
[key: number]: number[];
|
||||
}
|
||||
|
||||
interface CategoryIdsModel {
|
||||
[key: number]: number[];
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
||||
|
Loading…
x
Reference in New Issue
Block a user