From 987c6e21ecb319a55b614e89a1d389cdc5da6506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A6=BA=E7=8B=A8?= <18119604035@163.com> Date: Mon, 27 Mar 2023 12:15:31 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=AA=E4=BA=BA=E4=BF=A1=E6=81=AF=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=92=8C=E5=88=87=E8=8A=B1=E9=83=A8=E9=97=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/user.ts | 7 +++ src/compenents/header/index.tsx | 70 ++++++++++++++++++++++++--- src/compenents/user-info/index.tsx | 78 ++++++++++++++++++++---------- src/js/config.ts | 3 ++ src/pages/index/index.tsx | 7 ++- src/store/user/loginUserSlice.ts | 11 ++++- 6 files changed, 141 insertions(+), 35 deletions(-) create mode 100644 src/js/config.ts diff --git a/src/api/user.ts b/src/api/user.ts index 175a4e9..5583425 100644 --- a/src/api/user.ts +++ b/src/api/user.ts @@ -18,3 +18,10 @@ export function courses(depId: number) { dep_id: depId, }); } + +// 修改头像 +export function avatar(file: any) { + return client.put("/api/v1/user/avatar", { + file: file, + }); +} diff --git a/src/compenents/header/index.tsx b/src/compenents/header/index.tsx index 166642a..2fc5e34 100644 --- a/src/compenents/header/index.tsx +++ b/src/compenents/header/index.tsx @@ -1,9 +1,13 @@ -import React, { useState } from "react"; +import React, { useState, useEffect } from "react"; import styles from "./index.module.scss"; -import { Modal, Button, Dropdown, MenuProps } from "antd"; +import { Modal, Button, Dropdown } from "antd"; +import type { MenuProps } from "antd"; import { useDispatch, useSelector } from "react-redux"; import { Link, useNavigate } from "react-router-dom"; -import { logoutAction } from "../../store/user/loginUserSlice"; +import { + logoutAction, + saveCurrentDepId, +} from "../../store/user/loginUserSlice"; import { ChangePasswordModel } from "../change-password"; import { UserInfoModel } from "../user-info"; import { ExclamationCircleFilled } from "@ant-design/icons"; @@ -20,6 +24,27 @@ export const Header: React.FC = () => { const [changePasswordVisiale, setChangePasswordVisiale] = useState(false); const [userInfoVisiale, setUserInfoVisiale] = useState(false); + const [departmentsMenu, setDepartmentsMenu] = useState([]); + const [currentDepartment, setCurrentDepartment] = useState(""); + + useEffect(() => { + setCurrentDepartment(departments[0].name); + const arr: any = [ + { + key: "1", + type: "group", + label: "部门", + children: [], + }, + ]; + departments.map((item: any) => { + arr[0].children.push({ + key: item.id, + label: item.name, + }); + }); + setDepartmentsMenu(arr); + }, [departments]); const onClick: MenuProps["onClick"] = ({ key }) => { if (key === "login_out") { @@ -75,6 +100,32 @@ export const Header: React.FC = () => { }, ]; + const depItems: MenuProps["items"] = departmentsMenu; + + const onDepClick: MenuProps["onClick"] = ({ key }) => { + let name: string = ""; + departments.map((item: any) => { + if (Number(key) === item.id) { + name = item.name; + } + }); + confirm({ + title: "操作确认", + icon: , + content: "确认切换部门?", + centered: true, + okText: "确认", + cancelText: "取消", + onOk() { + setCurrentDepartment(name); + dispatch(saveCurrentDepId(Number(key))); + }, + onCancel() { + console.log("Cancel"); + }, + }); + }; + return (
@@ -84,10 +135,15 @@ export const Header: React.FC = () => {
- {departments.length > 0 && ( -
- {departments[0].name} -
+ {departments.length === 1 && ( +
{currentDepartment}
+ )} + {departments.length > 1 && ( + +
+ {currentDepartment} +
+
)} diff --git a/src/compenents/user-info/index.tsx b/src/compenents/user-info/index.tsx index efd8373..28cf71d 100644 --- a/src/compenents/user-info/index.tsx +++ b/src/compenents/user-info/index.tsx @@ -1,7 +1,12 @@ import React, { useState, useEffect } from "react"; -import { Modal, Image, Form, Input, message } from "antd"; +import { Modal, Image, Form, message, Upload, Button } from "antd"; import styles from "./index.module.less"; import { user } from "../../api/index"; +import { useDispatch } from "react-redux"; +import { loginAction } from "../../store/user/loginUserSlice"; +import type { UploadProps } from "antd"; +import config from "../../js/config"; +import { getToken } from "../../utils/index"; interface PropInterface { open: boolean; @@ -9,9 +14,12 @@ interface PropInterface { } export const UserInfoModel: React.FC = ({ open, onCancel }) => { + const dispatch = useDispatch(); const [form] = Form.useForm(); const [loading, setLoading] = useState(true); const [avatar, setAvatar] = useState(""); + const [name, setName] = useState(""); + const [idCard, setIdCard] = useState(""); useEffect(() => { getUser(); @@ -20,21 +28,41 @@ export const UserInfoModel: React.FC = ({ open, onCancel }) => { const getUser = () => { user.detail().then((res: any) => { setAvatar(res.data.user.avatar); - form.setFieldsValue({ - name: res.data.user.name, - }); + setName(res.data.user.name); + setIdCard(res.data.user.id_card); + dispatch(loginAction(res.data)); }); }; - const onFinish = (values: any) => { - user.password(avatar, values.name).then((res: any) => { - message.success("保存成功!"); - onCancel(); - }); - }; - - const onFinishFailed = (errorInfo: any) => { - console.log("Failed:", errorInfo); + const props: UploadProps = { + name: "file", + multiple: false, + method: "PUT", + action: config.app_url + "/api/v1/user/avatar", + headers: { + Accept: "application/json", + authorization: "Bearer " + getToken(), + }, + beforeUpload: (file) => { + const isPNG = file.type === ("image/png" || "image/jpg"); + if (!isPNG) { + message.error(`${file.name}不是图片文件`); + } + return isPNG || Upload.LIST_IGNORE; + }, + onChange(info: any) { + const { status, response } = info.file; + if (status === "done") { + if (response.code === 0) { + message.success(`${info.file.name} 上传成功`); + getUser(); + } else { + message.error(response.msg); + } + } else if (status === "error") { + message.error(`${info.file.name} 上传失败`); + } + }, }; return ( @@ -45,25 +73,22 @@ export const UserInfoModel: React.FC = ({ open, onCancel }) => { forceRender open={open} width={416} - onOk={() => form.submit()} onCancel={() => onCancel()} maskClosable={false} + footer={null} > -
+
{avatar && ( @@ -75,15 +100,18 @@ export const UserInfoModel: React.FC = ({ open, onCancel }) => { preview={false} /> )} -
更换头像
+
+ + + +
- - + +
{name}
+
+ +
{idCard}
diff --git a/src/js/config.ts b/src/js/config.ts new file mode 100644 index 0000000..b022a45 --- /dev/null +++ b/src/js/config.ts @@ -0,0 +1,3 @@ +export default { + app_url: import.meta.env.VITE_APP_URL || "", +}; diff --git a/src/pages/index/index.tsx b/src/pages/index/index.tsx index 1d3fc1c..e11628d 100644 --- a/src/pages/index/index.tsx +++ b/src/pages/index/index.tsx @@ -19,14 +19,17 @@ const IndexPage = () => { const departments = useSelector( (state: any) => state.loginUser.value.departments ); + const currentDepId = useSelector( + (state: any) => state.loginUser.value.currentDepId + ); useEffect(() => { getData(); - }, [tabKey]); + }, [tabKey, currentDepId]); const getData = () => { setLoading(true); - user.courses(departments[0].id).then((res: any) => { + user.courses(currentDepId).then((res: any) => { const records = res.data.learn_course_records; setStats(res.data.stats); setLearnCourseRecords(records); diff --git a/src/store/user/loginUserSlice.ts b/src/store/user/loginUserSlice.ts index 9d6beb8..59ad814 100644 --- a/src/store/user/loginUserSlice.ts +++ b/src/store/user/loginUserSlice.ts @@ -3,12 +3,14 @@ import { createSlice } from "@reduxjs/toolkit"; type UserStoreInterface = { user: null; departments: string[]; + currentDepId: number; isLogin: boolean; }; let defaultValue: UserStoreInterface = { user: null, departments: [], + currentDepId: 0, isLogin: false, }; @@ -22,16 +24,23 @@ const loginUserSlice = createSlice({ stage.value.user = e.payload.user; stage.value.departments = e.payload.departments; stage.value.isLogin = true; + if (e.payload.departments.length > 0 && stage.value.currentDepId === 0) { + stage.value.currentDepId = e.payload.departments[0].id; + } }, logoutAction(stage) { stage.value.user = null; stage.value.departments = []; stage.value.isLogin = false; }, + saveCurrentDepId(stage, e) { + stage.value.currentDepId = e.payload; + }, }, }); export default loginUserSlice.reducer; -export const { loginAction, logoutAction } = loginUserSlice.actions; +export const { loginAction, logoutAction, saveCurrentDepId } = + loginUserSlice.actions; export type { UserStoreInterface };