ldap开关联动部门、学员的新建、编辑、删除、排序、导入

This commit is contained in:
unknown 2023-09-06 11:30:41 +08:00
parent 3d29dd8963
commit 4122a2ac39
7 changed files with 190 additions and 114 deletions

View File

@ -32,6 +32,9 @@ const DepartmentPage = () => {
const [updateVisible, setUpdateVisible] = useState(false); const [updateVisible, setUpdateVisible] = useState(false);
const [did, setDid] = useState<number>(0); const [did, setDid] = useState<number>(0);
const [modal, contextHolder] = Modal.useModal(); const [modal, contextHolder] = Modal.useModal();
const ldapEnabled = useSelector(
(state: any) => state.systemConfig.value["ldap-enabled"]
);
const onSelect = (selectedKeys: any, info: any) => { const onSelect = (selectedKeys: any, info: any) => {
setSelectKey(selectedKeys); setSelectKey(selectedKeys);
@ -45,11 +48,11 @@ const DepartmentPage = () => {
}; };
useEffect(() => { useEffect(() => {
setLoading(true);
getData(); getData();
}, [refresh, permissions]); }, [refresh, permissions]);
const getData = () => { const getData = () => {
setLoading(true);
department.departmentList().then((res: any) => { department.departmentList().then((res: any) => {
const departments: DepartmentsBoxModel = res.data.departments; const departments: DepartmentsBoxModel = res.data.departments;
if (JSON.stringify(departments) !== "{}") { if (JSON.stringify(departments) !== "{}") {
@ -65,85 +68,108 @@ const DepartmentPage = () => {
const arr = []; const arr = [];
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({ if (ldapEnabled) {
title: ( arr.push({
<> title: (
<div className="tree-title-elli">{departments[id][i].name}</div> <>
<div className="d-flex"> <div className="tree-title-elli">{departments[id][i].name}</div>
<Tooltip placement="top" title="可拖拽排序"> </>
<i ),
className="iconfont icon-icon-drag mr-16" key: departments[id][i].id,
style={{ fontSize: 24 }} });
/> } else {
</Tooltip> arr.push({
{through("department-cud") && ( title: (
<> <>
<div className="tree-title-elli">{departments[id][i].name}</div>
<div className="d-flex">
<Tooltip placement="top" title="可拖拽排序">
<i <i
className="iconfont icon-icon-edit mr-16" className="iconfont icon-icon-drag mr-16"
style={{ fontSize: 24 }} style={{ fontSize: 24 }}
onClick={() => {
setDid(departments[id][i].id);
setUpdateVisible(true);
}}
/> />
<i </Tooltip>
className="iconfont icon-icon-delete" {through("department-cud") && (
style={{ fontSize: 24 }} <>
onClick={() => <i
removeItem( className="iconfont icon-icon-edit mr-16"
departments[id][i].id, style={{ fontSize: 24 }}
departments[id][i].name onClick={() => {
) setDid(departments[id][i].id);
} setUpdateVisible(true);
/> }}
</> />
)} <i
</div> className="iconfont icon-icon-delete"
</> style={{ fontSize: 24 }}
), onClick={() =>
key: departments[id][i].id, removeItem(
}); departments[id][i].id,
departments[id][i].name
)
}
/>
</>
)}
</div>
</>
),
key: departments[id][i].id,
});
}
} else { } else {
const new_arr: Option[] = checkArr(departments, departments[id][i].id); const new_arr: Option[] = checkArr(departments, departments[id][i].id);
arr.push({ if (ldapEnabled) {
title: ( arr.push({
<> title: (
<div className="tree-title-elli">{departments[id][i].name}</div> <>
<div className="d-flex"> <div className="tree-title-elli">{departments[id][i].name}</div>
<Tooltip placement="top" title="可拖拽排序"> </>
<i ),
className="iconfont icon-icon-drag mr-16" key: departments[id][i].id,
style={{ fontSize: 24 }} children: new_arr,
/> });
</Tooltip> } else {
{through("department-cud") && ( arr.push({
<> title: (
<>
<div className="tree-title-elli">{departments[id][i].name}</div>
<div className="d-flex">
<Tooltip placement="top" title="可拖拽排序">
<i <i
className="iconfont icon-icon-edit mr-16" className="iconfont icon-icon-drag mr-16"
style={{ fontSize: 24 }} style={{ fontSize: 24 }}
onClick={() => {
setDid(departments[id][i].id);
setUpdateVisible(true);
}}
/> />
<i </Tooltip>
className="iconfont icon-icon-delete" {through("department-cud") && (
style={{ fontSize: 24 }} <>
onClick={() => <i
removeItem( className="iconfont icon-icon-edit mr-16"
departments[id][i].id, style={{ fontSize: 24 }}
departments[id][i].name onClick={() => {
) setDid(departments[id][i].id);
} setUpdateVisible(true);
/> }}
</> />
)} <i
</div> className="iconfont icon-icon-delete"
</> style={{ fontSize: 24 }}
), onClick={() =>
key: departments[id][i].id, removeItem(
children: new_arr, departments[id][i].id,
}); departments[id][i].name
)
}
/>
</>
)}
</div>
</>
),
key: departments[id][i].id,
children: new_arr,
});
}
} }
} }
return arr; return arr;
@ -365,22 +391,29 @@ const DepartmentPage = () => {
return ( return (
<> <>
<div className="playedu-main-top mb-24"> {!ldapEnabled && (
{contextHolder} <div className="playedu-main-top mb-24">
<div className="d-flex"> {contextHolder}
<PerButton <div className="d-flex">
type="primary" <PerButton
text="新建部门" type="primary"
class="mr-16" text="新建部门"
icon={<PlusOutlined />} class="mr-16"
p="department-cud" icon={<PlusOutlined />}
onClick={() => setCreateVisible(true)} p="department-cud"
disabled={null} onClick={() => setCreateVisible(true)}
/> disabled={null}
/>
</div>
</div> </div>
</div> )}
<div className="playedu-main-body"> <div className="playedu-main-body">
<div style={{ width: 366 }}> {loading && (
<div className="float-left text-center mt-30">
<Spin></Spin>
</div>
)}
<div style={{ display: loading ? "none" : "block", width: 366 }}>
{treeData.length > 0 && ( {treeData.length > 0 && (
<Tree <Tree
onSelect={onSelect} onSelect={onSelect}

View File

@ -19,6 +19,7 @@ const InitPage = (props: Props) => {
if (props.configData) { if (props.configData) {
let config: SystemConfigStoreInterface = { let config: SystemConfigStoreInterface = {
"ldap-enabled": props.configData["ldap-enabled"],
systemName: props.configData["system.name"], systemName: props.configData["system.name"],
systemLogo: props.configData["system.logo"], systemLogo: props.configData["system.logo"],
systemApiUrl: props.configData["system.api_url"], systemApiUrl: props.configData["system.api_url"],

View File

@ -1,4 +1,4 @@
import { useState, useEffect } from "react"; import { useState } from "react";
import styles from "./index.module.less"; import styles from "./index.module.less";
import { Input, Button, message } from "antd"; import { Input, Button, message } from "antd";
import { login as loginApi, system } from "../../api/index"; import { login as loginApi, system } from "../../api/index";
@ -59,6 +59,7 @@ const LoginPage = () => {
const getSystemConfig = async () => { const getSystemConfig = async () => {
let res: any = await system.getSystemConfig(); let res: any = await system.getSystemConfig();
let data: SystemConfigStoreInterface = { let data: SystemConfigStoreInterface = {
"ldap-enabled": res.data["ldap-enabled"],
systemName: res.data["system.name"], systemName: res.data["system.name"],
systemLogo: res.data["system.logo"], systemLogo: res.data["system.logo"],
systemApiUrl: res.data["system.api_url"], systemApiUrl: res.data["system.api_url"],

View File

@ -21,6 +21,7 @@ import {
import { user } from "../../api/index"; import { user } from "../../api/index";
import { dateFormat } from "../../utils/index"; import { dateFormat } from "../../utils/index";
import { Link, Navigate, useLocation } from "react-router-dom"; import { Link, Navigate, useLocation } from "react-router-dom";
import { useSelector } from "react-redux";
import { TreeDepartment, PerButton } from "../../compenents"; import { TreeDepartment, PerButton } from "../../compenents";
import { MemberCreate } from "./compenents/create"; import { MemberCreate } from "./compenents/create";
import { MemberUpdate } from "./compenents/update"; import { MemberUpdate } from "./compenents/update";
@ -66,6 +67,9 @@ const MemberPage = () => {
const [user_dep_ids, setUserDepIds] = useState<DepIdsModel>({}); const [user_dep_ids, setUserDepIds] = useState<DepIdsModel>({});
const [departments, setDepartments] = useState<DepartmentsModel>({}); const [departments, setDepartments] = useState<DepartmentsModel>({});
const [did, setDid] = useState(Number(result.get("did"))); const [did, setDid] = useState(Number(result.get("did")));
const ldapEnabled = useSelector(
(state: any) => state.systemConfig.value["ldap-enabled"]
);
useEffect(() => { useEffect(() => {
setDid(Number(result.get("did"))); setDid(Number(result.get("did")));
@ -180,19 +184,23 @@ const MemberPage = () => {
disabled={null} disabled={null}
/> />
</Link> </Link>
<div className="form-column"></div> {!ldapEnabled && (
<Dropdown menu={{ items }}> <>
<Button <div className="form-column"></div>
type="link" <Dropdown menu={{ items }}>
className="b-link c-red" <Button
onClick={(e) => e.preventDefault()} type="link"
> className="b-link c-red"
<Space size="small" align="center"> onClick={(e) => e.preventDefault()}
>
<DownOutlined /> <Space size="small" align="center">
</Space>
</Button> <DownOutlined />
</Dropdown> </Space>
</Button>
</Dropdown>
</>
)}
</Space> </Space>
); );
}, },
@ -297,16 +305,18 @@ const MemberPage = () => {
</div> </div>
<div className="float-left j-b-flex mb-24"> <div className="float-left j-b-flex mb-24">
<div className="d-flex"> <div className="d-flex">
<PerButton {!ldapEnabled && (
type="primary" <PerButton
text="添加学员" type="primary"
class="mr-16" text="添加学员"
icon={<PlusOutlined />} class="mr-16"
p="user-store" icon={<PlusOutlined />}
onClick={() => setCreateVisible(true)} p="user-store"
disabled={null} onClick={() => setCreateVisible(true)}
/> disabled={null}
{dep_ids.length === 0 && ( />
)}
{!ldapEnabled && dep_ids.length === 0 && (
<Link style={{ textDecoration: "none" }} to={`/member/import`}> <Link style={{ textDecoration: "none" }} to={`/member/import`}>
<PerButton <PerButton
type="default" type="default"

View File

@ -1,5 +1,5 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { Button, Tree, Modal, message, Tooltip } from "antd"; import { Button, Tree, Modal, message, Tooltip, Spin } from "antd";
// import styles from "./index.module.less"; // import styles from "./index.module.less";
import { PlusOutlined, ExclamationCircleFilled } from "@ant-design/icons"; import { PlusOutlined, ExclamationCircleFilled } from "@ant-design/icons";
import { resourceCategory } from "../../../api/index"; import { resourceCategory } from "../../../api/index";
@ -24,6 +24,7 @@ const ResourceCategoryPage = () => {
(state: any) => state.loginUser.value.permissions (state: any) => state.loginUser.value.permissions
); );
const [loading, setLoading] = useState<boolean>(true); const [loading, setLoading] = useState<boolean>(true);
const [init, setInit] = useState(true);
const [refresh, setRefresh] = useState(false); const [refresh, setRefresh] = useState(false);
const [treeData, setTreeData] = useState<Option[]>([]); const [treeData, setTreeData] = useState<Option[]>([]);
const [selectKey, setSelectKey] = useState<number[]>([]); const [selectKey, setSelectKey] = useState<number[]>([]);
@ -33,6 +34,7 @@ const ResourceCategoryPage = () => {
const [modal, contextHolder] = Modal.useModal(); const [modal, contextHolder] = Modal.useModal();
useEffect(() => { useEffect(() => {
setInit(true);
getData(); getData();
}, [refresh, permissions]); }, [refresh, permissions]);
@ -56,6 +58,7 @@ const ResourceCategoryPage = () => {
setTreeData(new_arr); setTreeData(new_arr);
} }
setLoading(false); setLoading(false);
setInit(false);
}); });
}; };
@ -390,7 +393,12 @@ const ResourceCategoryPage = () => {
</div> </div>
</div> </div>
<div className="playedu-main-body"> <div className="playedu-main-body">
<div style={{ width: 366 }}> {init && (
<div className="float-left text-center mt-30">
<Spin></Spin>
</div>
)}
<div style={{ display: init ? "none" : "block", width: 366 }}>
{treeData.length > 0 && ( {treeData.length > 0 && (
<Tree <Tree
onSelect={onSelect} onSelect={onSelect}

View File

@ -12,13 +12,18 @@ import {
Slider, Slider,
Space, Space,
} from "antd"; } from "antd";
// import styles from "./index.module.less"; import { appConfig, system } from "../../../api/index";
import { appConfig } from "../../../api/index";
import { UploadImageButton } from "../../../compenents"; import { UploadImageButton } from "../../../compenents";
import { useDispatch } from "react-redux";
import type { TabsProps } from "antd"; import type { TabsProps } from "antd";
import type { CheckboxChangeEvent } from "antd/es/checkbox"; import type { CheckboxChangeEvent } from "antd/es/checkbox";
import {
SystemConfigStoreInterface,
saveConfigAction,
} from "../../../store/system/systemConfigSlice";
const SystemConfigPage = () => { const SystemConfigPage = () => {
const dispatch = useDispatch();
const [form] = Form.useForm(); const [form] = Form.useForm();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [logo, setLogo] = useState(""); const [logo, setLogo] = useState("");
@ -239,6 +244,23 @@ const SystemConfigPage = () => {
message.success("保存成功!"); message.success("保存成功!");
setLoading(false); setLoading(false);
getDetail(); getDetail();
getSystemConfig();
});
};
const getSystemConfig = async () => {
system.getSystemConfig().then((res: any) => {
let data: SystemConfigStoreInterface = {
"ldap-enabled": res.data["ldap-enabled"],
systemName: res.data["system.name"],
systemLogo: res.data["system.logo"],
systemApiUrl: res.data["system.api_url"],
systemPcUrl: res.data["system.pc_url"],
systemH5Url: res.data["system.h5_url"],
memberDefaultAvatar: res.data["member.default_avatar"],
courseDefaultThumbs: res.data["default.course_thumbs"],
};
dispatch(saveConfigAction(data));
}); });
}; };

View File

@ -1,6 +1,7 @@
import { createSlice } from "@reduxjs/toolkit"; import { createSlice } from "@reduxjs/toolkit";
type SystemConfigStoreInterface = { type SystemConfigStoreInterface = {
"ldap-enabled"?: boolean;
systemApiUrl?: string; systemApiUrl?: string;
systemPcUrl?: string; systemPcUrl?: string;
systemH5Url?: string; systemH5Url?: string;