Commit 4857055b authored by 吴永生#A02208's avatar 吴永生#A02208

feat: 项目成员开发

parent d18077bb
......@@ -3,6 +3,7 @@ import React, { useContext } from 'react';
import _ from 'lodash';
import localStorageKey from '@/utils/localStorageKey';
import { BACKEND_API_URI_PREFIX } from './api_prefix';
import qs from 'qs';
......@@ -115,15 +116,23 @@ export class Http {
return requestMethod.then((res) => res.data);
}
getConfig(config?: IAxiosRequestConfig) {
getConfig(config?: IAxiosRequestConfig, data?: any ) {
let Authorization: string =
`Bearer ` +
JSON.parse(localStorage.getItem(localStorageKey.TOKEN) || "{}")
?.access_token || "";
return {
const newConfig = {
headers:{'Content-Type': "application/x-www-form-urlencoded",Authorization, ...config?.headers, },...config
}
console.log(config,2222)
if (
newConfig?.headers['Content-Type'] === "application/x-www-form-urlencoded"
) {
newConfig.data = qs.stringify(data);
}
console.log(newConfig,1113)
return newConfig
}
......@@ -135,18 +144,18 @@ export class Http {
}
patch<T>(url: string, data?: any, config?: IAxiosRequestConfig) {
return this.request<T>({ method: 'PATCH', url: `${BACKEND_API_URI_PREFIX}${url}`, data, ...this.getConfig(config) });
return this.request<T>({ method: 'PATCH', url: `${BACKEND_API_URI_PREFIX}${url}`, data, ...this.getConfig(config, data) });
}
put<T>(url: string, data?: any, config?: IAxiosRequestConfig) {
return this.request<T>({ method: 'PUT', url: `${BACKEND_API_URI_PREFIX}${url}`, data, ...this.getConfig(config) });
return this.request<T>({ method: 'PUT', url: `${BACKEND_API_URI_PREFIX}${url}`, data, ...this.getConfig(config, data) });
}
post<T>(url: string, data?: any, config?: IAxiosRequestConfig) {
if (config?.allowIntercept) {
return this.requestInterception<T>({ method: 'POST', url: `${BACKEND_API_URI_PREFIX}${url}`, data, ...this.getConfig(config) });
return this.requestInterception<T>({ method: 'POST', url: `${BACKEND_API_URI_PREFIX}${url}`, data, ...this.getConfig(config, data) });
}
return this.request<T>({ method: 'POST', url: `${BACKEND_API_URI_PREFIX}${url}`, data, ...this.getConfig(config) });
return this.request<T>({ method: 'POST', url: `${BACKEND_API_URI_PREFIX}${url}`, data, ...this.getConfig(config, data) });
}
del<T>(url: string, config?: IAxiosRequestConfig) {
......@@ -166,3 +175,9 @@ export function useHttp(raw?: boolean) {
}
export default rawHttp;
export interface IResponse<T> {
errorCode: number;
massage: string;
data: T;
}
......@@ -151,7 +151,7 @@ export default function EnhancedTable(props) {
</TableCell>
}
{
headCells.map((item, k) => {
headCells.filter(item=>item.id !== 'checkbox').map((item, k) => {
return (
<TableCell key={k} component="th" id={labelId + k}
// align={}
......
......@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2021-12-04 15:46:25
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-05 18:06:47
* @LastEditTime: 2022-06-06 20:34:00
* @FilePath: /lionet-slb-pc/src/components/SearchView/components/Collapse.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......@@ -13,7 +13,7 @@ import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import Select, { SelectChangeEvent } from "@mui/material/Select";
interface IOption {
export interface IOption {
label: string;
value: string;
disabled?: boolean;
......@@ -39,7 +39,7 @@ export default function BasicSelect(props: IProps) {
return (
<Box sx={{ minWidth: 120 }}>
<FormControl fullWidth>
<InputLabel id="demo-simple-select-label">
<InputLabel className="aa33" id="demo-simple-select-label">
{title || "请选择"}
</InputLabel>
<Select
......
......@@ -2,21 +2,104 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-04 18:28:31
* @LastEditTime: 2022-06-06 20:02:38
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import Dialog from "@/components/mui/Dialog";
import { memo } from "react";
import { toJS } from "mobx";
import { observer } from "mobx-react-lite";
import SelectComponent from "@/components/Material.Ui/Select";
import Table from "@/components/Material.Ui/Table";
import Dialog from "@/components/mui/Dialog";
import { memo, useEffect, useMemo, useState } from "react";
import { Box } from "@mui/material";
import SearchIcon from "@mui/icons-material/Search";
import Input from "@/components/Material.Ui/Input";
import { IResponse, useHttp } from "@/api/http";
import { useStores } from "@/store";
// import Select from "@/components/Material.Ui/Select";
interface IProps {
setAddMemberDialog: (val: boolean) => void;
addMemberDialog: boolean;
}
const AddMember = (props: IProps) => {
const AddMember = observer((props: IProps) => {
const { addMemberDialog, setAddMemberDialog } = props;
const http = useHttp();
const { currentProjectStore } = useStores();
const [tableData, setTableData] = useState([]);
const selectOption = useMemo(() => {
return [
{ key: "DEVELOPER", label: "研发者" },
{ key: "MANAGER", label: "管理者" },
{ key: "VIEWER", label: "查看者" },
];
}, []);
const columns = [
{ id: "checkbox", width: 50 },
{ id: "username", label: "项目成员", width: 160 },
{
id: "projectRole",
label: "项目权限",
width: 160,
render: () => {
return (
// <SelectComponent
// fullWidth={true}
// option={selectOption}
// type={"select"}
// changeType={"select"}
// // textAlign={"right"}
// // value={nodeNum}
// onChange={(val: any) => console.log(val, 1111)}
// // customClass={classes.SelectComponentCustomClass}
// />
<SelectComponent
option={selectOption}
// value={this.state.selectRegionValue ? this.state.selectRegionValue.name : ""}
size={"xsmall"}
callback={(value: any) => console.log(value)}
rootStyle={{
paddingRight: "0",
width: "180px",
border: "1px solid #136EFA",
}}
textStyle={{ fontSize: "13px" }}
sz={"sm"}
customSvg={{
width: "32px",
height: "32px",
backgroundColor: "rgba(19, 110, 250, 0.1)",
borderRadius: "4px",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
/>
);
},
},
];
useEffect(() => {
if (!addMemberDialog) return;
const projectInfo = toJS(currentProjectStore?.currentProjectInfo);
http
.get<IResponse<any>>("/cpp/project/listusers", {
params: { id: projectInfo?.id || "" },
})
.then((res) => {
if (res.data.length) {
setTableData(res?.data);
}
});
}, [currentProjectStore?.currentProjectInfo, http, addMemberDialog]);
const onClose = () => {
setAddMemberDialog(false);
};
......@@ -29,12 +112,32 @@ const AddMember = (props: IProps) => {
open={addMemberDialog}
onClose={onClose}
onConfirm={onConfirm}
title="移出项目"
title="添加成员"
>
<div>确认移出该成员吗?</div>
<Box>
<Input
onChange={(e: any) => {
console.log(e);
}}
fullWidth={true}
size="xsmall"
placeholder="搜索项目成员"
endAdornment={<SearchIcon style={{ color: "#8A9099" }} />}
/>
</Box>
<Table
rowHover={true}
stickyheader={true}
rows={tableData}
rowsPerPage="99"
headCells={columns}
footer={false}
tableStyle={{ minWidth: "auto" }}
borderBottom="none"
/>
</Dialog>
</>
);
};
});
export default memo(AddMember);
......@@ -2,41 +2,94 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-05 18:15:22
* @LastEditTime: 2022-06-06 20:37:26
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
// import Dialog from "@/components/Material.Ui/Dialog";
import Select from "@/components/mui/Select";
import { memo, useEffect, useState } from "react";
import { observer } from "mobx-react-lite";
import { toJS } from "mobx";
import Select, { IOption } from "@/components/mui/Select";
import Dialog from "@/components/mui/Dialog";
import { memo } from "react";
import { IResponse, useHttp } from "@/api/http";
import { useStores } from "@/store/index";
import { IDialogInfo } from "../interface";
import { useMessage } from "@/components/MySnackbar";
interface IProps {
setPermissionDialog: (val: boolean) => void;
permissionDialog: boolean;
setPermissionDialog: (val: IDialogInfo) => void;
permissionDialog: IDialogInfo;
}
const ChangePermission = (props: IProps) => {
const ChangePermission = observer((props: IProps) => {
const { permissionDialog, setPermissionDialog } = props;
const { currentProjectStore } = useStores();
const Message = useMessage();
const http = useHttp();
const [selectOptions, setSelectOptions] = useState<IOption[]>([]);
const [selectValue, setSelectValue] = useState<IOption | undefined>();
useEffect(() => {
if (permissionDialog?.isShow) {
http.get<IResponse<any>>("/cpp/project/listroles").then((res) => {
const arr = [];
const { data } = res;
for (const key in data) {
arr.push({
label: String(data[key]),
value: key,
});
}
setSelectOptions(arr);
});
}
}, [http, permissionDialog]);
const changePermission = (val: any) => {
setSelectValue(val);
};
const onClose = () => {
setPermissionDialog(false);
setPermissionDialog({ isShow: false, username: "" });
};
const onConfirm = () => {
setPermissionDialog(false);
const projectInfo = toJS(currentProjectStore?.currentProjectInfo);
http
.put<IResponse<any>>("/cpp/project/updateuserrole", {
id: projectInfo?.id || "",
username: permissionDialog.username,
role: selectValue?.value || "",
})
.then((res) => {
const { errorCode } = res;
if (errorCode === 0) {
Message.success("更改成功!");
setPermissionDialog({ isShow: false, username: "" });
}
});
};
return (
<>
<Dialog
open={permissionDialog}
open={permissionDialog?.isShow}
onClose={onClose}
onConfirm={onConfirm}
title="更改权限"
>
<Select title="项目权限" options={[]} />
<div style={{ marginTop: 12 }}>
<Select
title="项目权限"
onChange={changePermission}
options={selectOptions}
/>
</div>
</Dialog>
</>
);
};
});
export default memo(ChangePermission);
......@@ -2,32 +2,59 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-04 17:54:50
* @LastEditTime: 2022-06-06 18:09:33
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
// import Dialog from "@/components/Material.Ui/Dialog";
import { IResponse, useHttp } from "@/api/http";
import Dialog from "@/components/mui/Dialog";
import { useMessage } from "@/components/MySnackbar";
import { useStores } from "@/store";
import { toJS } from "mobx";
import { observer } from "mobx-react-lite";
import { memo } from "react";
import { IDialogInfo } from "../interface";
interface IProps {
setRemoveDialog: (val: boolean) => void;
removeDialog: boolean;
setRemoveDialog: (val: IDialogInfo) => void;
removeDialog: IDialogInfo;
}
const RemoveItem = (props: IProps) => {
const RemoveItem = observer((props: IProps) => {
const { removeDialog, setRemoveDialog } = props;
const http = useHttp();
const Message = useMessage();
const { currentProjectStore } = useStores();
const onClose = () => {
setRemoveDialog(false);
setRemoveDialog({ isShow: false, username: "" });
};
const onConfirm = () => {
setRemoveDialog(false);
const projectInfo = toJS(currentProjectStore?.currentProjectInfo);
console.log(111111, {
id: projectInfo?.id || "",
username: removeDialog.username,
});
http
.del<IResponse<any>>(
`/cpp/project/removemember?id=${projectInfo?.id || ""}&username=${
removeDialog.username || ""
}`
)
.then((res) => {
const { errorCode } = res;
if (errorCode === 0) {
Message.success("删除成功!");
setRemoveDialog({ isShow: false, username: "" });
}
});
};
return (
<>
<Dialog
open={removeDialog}
open={removeDialog?.isShow}
onClose={onClose}
onConfirm={onConfirm}
title="移出项目"
......@@ -36,6 +63,6 @@ const RemoveItem = (props: IProps) => {
</Dialog>
</>
);
};
});
export default memo(RemoveItem);
......@@ -2,46 +2,58 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-04 18:33:02
* @LastEditTime: 2022-06-06 21:40:48
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { memo, useEffect, useState } from "react";
import _ from "lodash";
import { Box } from "@mui/material";
import Button from "@mui/material/Button";
import SearchIcon from "@mui/icons-material/Search";
import Add from "@mui/icons-material/Add";
import Table from "@/components/Material.Ui/Table";
import { useHttp } from "@/api/http";
import { IResponse, useHttp } from "@/api/http";
import Input from "@/components/Material.Ui/Input";
import RemoveItem from "./components/RemoveItem";
import ChangePermission from "./components/ChangePermission";
import AddMember from "./components/AddMember";
import styles from "./index.module.css";
import { IDialogInfo } from "./interface";
import { toJS } from "mobx";
import { useStores } from "@/store";
const ProjectMembers = () => {
const http = useHttp();
const { currentProjectStore } = useStores();
const columns = [
{ id: "username", label: "成员名称", width: "20%" },
{ id: "projectRoleDesc", label: "项目权限", width: "20%" },
{ id: "phone", label: "联系方式", width: "20%" },
{ id: "username", label: "成员名称" },
{ id: "projectRoleDesc", label: "项目权限" },
{ id: "phone", label: "联系方式" },
{
id: "operation",
label: "操作",
width: "20%",
width: 160,
render: (item: any) => {
console.log(item, "000000");
return (
<>
<span
style={{ color: "#1370FF", cursor: "pointer" }}
onClick={onPermissionBtn}
onClick={() => {
onPermissionBtn(item.username);
}}
>
更改权限
</span>
<span className={styles.removeItemBox} onClick={onRemoveItemBtn}>
<span
className={styles.removeItemBox}
onClick={() => {
onRemoveItemBtn(item.username);
}}
>
移出项目
</span>
</>
......@@ -51,21 +63,46 @@ const ProjectMembers = () => {
];
/** 删除成员 */
const [removeDialog, setRemoveDialog] = useState<boolean>(false);
const [removeDialog, setRemoveDialog] = useState<IDialogInfo>({
isShow: false,
username: "",
});
/** 更改权限 */
const [permissionDialog, setPermissionDialog] = useState<boolean>(false);
const [permissionDialog, setPermissionDialog] = useState<IDialogInfo>({
isShow: false,
username: "",
});
/** 添加成员 */
const [addMemberDialog, setAddMemberDialog] = useState<boolean>(false);
const [tableData, setTableData] = useState([]);
const [projectName, setProjectName] = useState("");
const [filterTableData, setFilterTableData] = useState([]);
useEffect(() => {
const projectInfo = toJS(currentProjectStore?.currentProjectInfo);
if (!projectInfo?.id) return;
http
.get("/cpp/project/list", {
params: { product: "cadd" },
.get<IResponse<any>>("/cpp/project/get", {
params: { id: projectInfo?.id || "" },
})
.then((res) => {
console.log(res);
setTableData(res?.data?.members || []);
});
}, [http]);
}, [currentProjectStore?.currentProjectInfo, http]);
useEffect(() => {
if (!!projectName) {
const newVal =
tableData.filter((item: any) => {
return item?.username?.includes(projectName);
}) || [];
setFilterTableData(newVal || []);
} else {
console.log(2222);
setFilterTableData(tableData);
}
}, [projectName, tableData]);
/** 点击添加成员 */
const onAddMember = () => {
......@@ -73,13 +110,13 @@ const ProjectMembers = () => {
};
/** 点击删除成员 */
const onRemoveItemBtn = () => {
setRemoveDialog(true);
const onRemoveItemBtn = (userName: string) => {
setRemoveDialog({ isShow: true, username: userName });
};
/** 点击更改权限 */
const onPermissionBtn = () => {
setPermissionDialog(true);
const onPermissionBtn = (userName: string) => {
setPermissionDialog({ isShow: true, username: userName });
};
return (
......@@ -87,13 +124,15 @@ const ProjectMembers = () => {
<Box className={styles.headerBox}>
<Input
onChange={(e: any) => {
console.log(e);
_.debounce(() => {
setProjectName(e.target.value);
}, 200)();
}}
size="xsmall"
placeholder="搜索项目成员"
endAdornment={<SearchIcon />}
endAdornment={<SearchIcon style={{ color: "#8A9099" }} />}
/>
<Button
style={{ backgroundColor: "#1370FF " }}
variant="contained"
onClick={onAddMember}
startIcon={<Add />}
......@@ -105,12 +144,7 @@ const ProjectMembers = () => {
<Table
rowHover={true}
stickyheader={true}
rows={[
{
username: "wuyongs",
phone: 2323424,
},
]}
rows={filterTableData}
rowsPerPage={"99"}
headCells={columns}
nopadding={true}
......
/*
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-06-06 15:07:36
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-06 15:07:55
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/ProjectMembers/interface.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
export interface IDialogInfo {
isShow: boolean;
username?: string;
}
\ No newline at end of file
......@@ -2,7 +2,7 @@
* @Author: 吴永生#A02208 yongsheng.wu@wholion.com
* @Date: 2022-05-31 10:18:13
* @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
* @LastEditTime: 2022-06-05 18:29:59
* @LastEditTime: 2022-06-06 20:14:27
* @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
......@@ -40,17 +40,19 @@ const ProjectSetting = observer(() => {
setValue(val);
};
if (currentProjectStore.currentProjectInfo.name) {
if (currentProjectStore.currentProjectInfo.name || true) {
return (
<Box style={{ padding: 24 }}>
<div>
<div style={{ padding: 24 }}>
<div style={{ display: "flex", alignItems: "center" }}>
<img src={projectImg} alt="项目logo" />
<span>{currentProjectStore.currentProjectInfo.name}</span>
<span style={{ marginLeft: 12 }}>
{currentProjectStore.currentProjectInfo.name}
</span>
</div>
<Box sx={{ width: "100%", typography: "body1" }}>
<Tabs value={value} onChange={changeTabs} tabList={tabList} />
</Box>
</Box>
</div>
);
} else {
return <NoProject />;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment