1 Commits

Author SHA1 Message Date
clay
ea1557e8a3 Merge pull request 'dev' (#19) from dev into prod
Reviewed-on: http://git.feashow.cn/wenhua/fateverse-react/pulls/19
2023-11-11 09:19:40 +00:00
20 changed files with 19 additions and 15270 deletions

View File

@@ -33,6 +33,8 @@ steps:
REGISTRY_NAMESPACE:
from_secret: registry_namespace
commands: # 定义在Docker容器中执行的shell命令
- cd /app/build/$DRONE_REPO_NAME/
- cat Dockerfile
- sed -i 's/$REGISTRY/'"$REGISTRY"'/' deployment.yml
- sed -i 's/$REGISTRY_NAMESPACE/'"$REGISTRY_NAMESPACE"'/' deployment.yml
- sed -i 's/$DRONE_REPO_NAME/'"$DRONE_REPO_NAME"'/' deployment.yml
@@ -70,7 +72,7 @@ volumes:
trigger:
branch:
# - prod
- dev
- prod
# - dev
event:
- push

10763
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,59 +0,0 @@
import request from "@/utils/request";
interface queryParamsType {
deptName?: string;
state?: number;
}
interface addParamsType {
deptName: string;
leader:string;
leaderId:number;
parentId?:number;
ancestors?:string
delFlag?:string
deptId?:number
email?:string
phone?:string
state?:string
}
export const getDatasAPI = (params: queryParamsType) => {
console.log(params);
return request({
url: "/admin/dept",
method: "get",
params: params,
});
};
export const editDataAPI = (params: addParamsType) => {
console.log(params);
params.leaderId=0
return request({
url: "/admin/dept",
method: "put",
data:params
});
};
export const delDataAPI=(deptId:number)=>{
console.log(deptId);
return request({
url:`admin/dept/${deptId}`,
method:'delete'
})
}
export const addDataAPI=(dept:addParamsType)=>{
console.log(dept);
dept.leaderId=0
return request({
url:`admin/dept`,
method:'post',
data:dept
})
}
export const getDataAPI=(deptId:number)=>{
return request({
url:`/admin/dept/${deptId}`,
method:'get'
})
}

View File

@@ -1,23 +0,0 @@
import request from "../../utils/request";
export const getNoticeListApi = (params: any) => {
return request({
url: "/notice/notify",
method: "get",
params,
});
};
export const getNoticeInfoApi = (id: number) => {
return request({
url: "/notice/notify/" + id,
method: "get",
});
};
export const deleteNoticeInfoApi = (id: number) => {
return request({
url: "/notice/notify/" + id,
method: "delete",
});
};

View File

@@ -1,51 +0,0 @@
import request from "../../utils/request";
interface postListParams {
postCode?: string;
postName?: string;
state?: string;
pageNum?: string;
pageSize?: string;
}
export const getPostListApi = (data: postListParams) => {
const { postCode, postName, state, pageNum } = data;
const params = data
? {
postCode,
postName,
state,
pageNum,
pageSize: 500,
}
: undefined;
return request({
url: "/admin/post",
method: "get",
params,
});
};
export const addPostApi = (data: any) => {
return request({
url: "/admin/post",
method: "post",
data,
});
};
export const editPostApi = (data: any) => {
return request({
url: "/admin/post",
method: "put",
data,
});
};
export const deletePostApi = (postId: any) => {
return request({
url: "/admin/post/" + postId,
method: "delete",
});
};

View File

@@ -1,67 +0,0 @@
import request from "@/utils/request";
interface paramsType {
cluster?: string;
contentType?: string;
noticeTitle?: string;
noticeType?: string;
publishId?: number;
sendType?: string;
pageNum?: number;
pageSize?: number;
}
interface addParamsType {
action?: string;
cluster?: string;
contentType?: string;
noticeContent?: string;
noticeTitle?: string;
noticeType?: string;
remark?: string;
sendType?: string;
senderIds?: number[];
}
export const getDataListAPI = (params: paramsType) => {
return request({
url: "/notice/notice",
method: "get",
params: params,
});
};
export const getUserListAPI = () => {
return request({
url: "/admin/user",
method: "get",
});
};
export const getRolesListAPI = () => {
return request({
url: "/admin/role",
method: "get",
});
};
export const getDeptsListAPI = () => {
return request({
url: "/admin/dept",
method: "get",
});
};
export const addDataAPI = (addParams: addParamsType) => {
return request({
url: `/notice/notice`,
method: "post",
data: addParams,
});
};
export const deleteDataAPI = (noticeId: number) => {
return request({
url: `/notice/notice/${noticeId}`,
method: "delete",
});
};
export const getDataAPI = (noticeId: number) => {
return request({
url: `/notice/notice/${noticeId}`,
method: "get",
});
};

View File

@@ -1,75 +0,0 @@
import request from "@/utils/request";
interface paramsType {
createTime?: string;
dataScope?: string;
deptIds?: any[];
menuIds?: any[];
roleId?: number;
roleKey?: string;
roleName?: string;
state?: string;
endTime?: string;
startTime?: string;
pageNum?: number;
pageSize?: number;
}
export const getRolesDataAPI = (params: paramsType) => {
const { endTime, roleKey, roleName, startTime, state, pageNum, pageSize } =
params;
// console.log('API',params);
return request({
url: "/admin/role",
method: "get",
params: {
endTime,
roleKey,
roleName,
startTime,
state,
pageNum,
pageSize,
},
});
};
export const delRoleAPI = (roleId: paramsType) => {
// console.log(roleId);
return request({
url: `/admin/role/${roleId}`,
method: "delete",
});
};
export const getMenuLiseAPI = () => {
return request({
url: "/admin/menu",
method: "get",
});
};
export const addRoleAPI = (data: any) => {
// console.log('addAPI',data);
return request({
url: `/admin/role`,
method: "post",
data,
});
};
export const getRoleAPI = (params: paramsType) => {
const { roleId } = params;
return request({
url: `/admin/role/${roleId}`,
method: "get",
});
};
export const setRoleDataAPI = (data: any) => {
// data.menuIds=[]
// const {roleId}=params
console.log("修改", data);
return request({
url: `/admin/role`,
method: "put",
data: data,
});
};

View File

@@ -1,86 +0,0 @@
import request from "../../utils/request";
interface userListParams {
deptId?: string;
userName?: string;
phoneNumber?: string;
state?: string;
startTime?: string;
endTime?: string;
pageNum?: number;
pageSize?: number;
}
export const getDeptTreeApi = () => {
return request({
url: "/admin/dept",
method: "get",
});
};
export const getUserInfoApi = (userId: string) => {
return request({
url: "/admin/user/info/" + userId,
method: "get",
});
};
export const getRoleListApi = () => {
return request({
url: "/admin/role",
method: "get",
});
};
export const getPostListApi = () => {
return request({
url: "/admin/post",
method: "get",
});
};
export const getUserListApi = (data: userListParams) => {
const { deptId, userName, phoneNumber, state, startTime, endTime, pageNum } =
data;
const params = data
? {
deptId,
userName,
phoneNumber,
state,
startTime,
endTime,
pageNum,
pageSize: 500,
}
: undefined;
return request({
url: "/admin/user",
method: "get",
params,
});
};
export const addUserApi = (data: any) => {
return request({
url: "/admin/user",
method: "post",
data,
});
};
export const editUserApi = (data: any) => {
return request({
url: "/admin/user",
method: "put",
data,
});
};
export const deleteUserApi = (userId: any) => {
return request({
url: "/admin/user/" + userId,
method: "delete",
});
};

View File

@@ -1,48 +0,0 @@
.deptBox{
background: white;
padding: 20px;
.tablebox{
table{
thead{
th::before{
}
tr{
.ant-table-cell{
background: white;
color:#909399
}
}
}
tbody{
tr{
.ant-table-cell{
background: white;
color:#606266
}
}
}
}
.ant-table-cell{
button:focus
{
outline: none;
}
button:hover
{
border: 0px rgb(250, 250, 250);
}
}
}
.newAdd{
display: flex;
margin-top: 15px;
button{
margin-left: 15px;
}
}
}

View File

@@ -1,575 +1,5 @@
import { useState,useEffect } from "react";
import {
Button,
Input,
Select,
message,
Table,
Tag,
Modal,
Form,
InputNumber,
Radio,
ConfigProvider,
TreeSelect,
Row,
Col,
// Icon
} from "antd";
import type { ColumnsType } from "antd/es/table";
import {
SyncOutlined,
SearchOutlined,
ExclamationCircleFilled,
SwapOutlined,
} from "@ant-design/icons";
import zh_CN from "antd/es/locale/zh_CN";
import "dayjs/locale/zh-cn";
// import 'moment/locale/zh-cn';
import {
getDatasAPI,
delDataAPI,
addDataAPI,
editDataAPI,
getDataAPI,
} from "../../../api/system/dept";
import "./index.scss";
// import { useForm } from "antd/es/form/Form";
interface searchValueType {
deptName: string | undefined;
state: string | undefined;
}
//表格单项数据类型
interface TableDataType {
children: number[];
createTime: string;
deptId: number;
deptName: string;
orderNum: string;
state: string;
}
let thisDept = {};
let treeData: any = [];
let isTreeAnyId = false;
export default function Dept() {
const { confirm } = Modal;
//提示组件
const [messageApi, contextHolder] = message.useMessage();
const [isAllExpend, setIsAllExpend] = useState(true);
//搜索框内所有内容
let [searchValue, setSearchValue] = useState<searchValueType>({
deptName: undefined,
state: undefined,
});
// const is
//树列表数据
// const [isTreeAnyId,setIsTreeAnyId]=useState(false)
const [treeAnyId, setTreeAnyId] = useState<number[]>([]);
const [expandedRowKeys, setExpandedRowKeys] = useState<number[]>([]);
//Modal
const [isModalOpen, setIsModalOpen] = useState(false);
const [modalTitle, setModalTitle] = useState('');
//表单区域
const [isDisbaled, setIsDisbaled] = useState<boolean>(false);
//serach
const [formSearch] = Form.useForm();
const [formModal] = Form.useForm();
//当前页面页数
//表格内数据
let [tableData, setTableData] = useState<TableDataType[]>([]);
//表格格式
const columns: ColumnsType<TableDataType> = [
{
title: "部门名称",
dataIndex: "deptName",
key: "deptName",
},
{
title: "排序",
dataIndex: "orderNum",
key: "orderNum",
},
{
title: "状态",
key: "state",
dataIndex: "state",
render: (text) => (
<>
{text === "0" ? (
<Tag color="success"></Tag>
) : (
<Tag color="error"></Tag>
)}
</>
),
},
{
title: "创建时间",
key: "createTime",
dataIndex: "createTime",
},
{
title: "操作",
key: "",
dataIndex: "",
render: (text) => (
<>
<Button type="link" onClick={() => handleNewAdd(text.deptId)}>
{"新增"}
</Button>
{/* <Button type='link' danger onClick={() => handleClickDel(text)}>{'删除'}</Button> */}
<Button type="link" onClick={() => handleEdit(text)}>
{"修改"}
</Button>
{text.parentId !== 0 ? (
<Button type="link" onClick={() => handleDelete(text)}>
{"删除"}
</Button>
) : null}
</>
),
},
];
//请求表格内容参数
let [queryTableDataParams, setQueryTableDataParams] = useState<any>({
deptName: undefined,
state: undefined,
});
const handleDelete = (dept: any) => {
confirm({
title: "系统提示",
icon: <ExclamationCircleFilled />,
content: `确定删除部门名称为${dept.deptName}的数据吗`,
okText: "确定",
okType: "danger",
cancelText: "取消",
onOk() {
(async () => {
try {
let { code } = await delDataAPI(dept.deptId);
if (code === 1000) {
console.log("del", dept.deptId);
messageApi.open({
type: "success",
content: "操作成功",
});
getDatas({});
}
} catch (error) {
console.log(error);
}
})();
},
onCancel() {
console.log("Cancel");
},
});
};
const handleSerach = () => {
searchValue = formSearch.getFieldsValue();
setSearchValue(searchValue)
console.log(searchValue);
setQueryTableDataParams({ ...searchValue });
};
const handleReset = () => {
formSearch.resetFields();
searchValue = formSearch.getFieldsValue();
setSearchValue(searchValue)
setQueryTableDataParams({ ...searchValue });
};
const handleEdit = async (dept: any) => {
if (dept.parentId === 0) {
setIsDisbaled(true);
formModal.setFieldsValue({ ...thisDept, parentId: dept.deptName });
} else {
setIsDisbaled(false);
// formModal.setFieldsValue({...thisDept});
}
await getData(dept.deptId);
if (dept.parentId === 0) {
setIsDisbaled(true);
formModal.setFieldsValue({ ...thisDept, parentId: dept.deptName });
} else {
setIsDisbaled(false);
formModal.setFieldsValue({ ...thisDept });
}
console.log(thisDept);
setModalTitle("修改部门");
setIsModalOpen(true);
};
const handleNewAdd = (deptId?: string) => {
setModalTitle("新增部门");
setIsModalOpen(true);
if (deptId) {
formModal.setFieldsValue({
parentId: deptId,
deptName: '',
orderNum: 0,
leader: '',
phone: '',
email: '',
state: "0",
});
} else
formModal.setFieldsValue({
parentId: undefined,
deptName: undefined,
orderNum: 0,
leader: undefined,
phone: undefined,
email: undefined,
state: "0",
});
};
const handleModalOk = () => {
formModal
.validateFields()
.then((values) => {
console.log("add", values);
if (modalTitle == "新增部门") {
console.log(values);
postAdd(values);
} else if (modalTitle == "修改部门") {
editData(values);
}
})
.catch((info) => {
console.log("Validate Failed:", info);
});
};
//遍历菜单树获取所有节点ID
const getTree = function (tree: any) {
tree.title = tree.deptName;
tree.value = tree.deptId;
if (!isTreeAnyId) {
treeAnyId.push(tree.deptId);
setTreeAnyId([...treeAnyId]);
}
if (tree.children) {
for (let child of tree.children) {
getTree(child);
}
}
setExpandedRowKeys([...treeAnyId])
};
const handleModalCanle = () => {
setIsModalOpen(false);
};
//获取详细数据
const getData = async (deptId: number) => {
try {
const { code, data } = await getDataAPI(deptId);
if (code === 1000) {
thisDept = data;
// console.log(thisDept);
}
} catch (error) {}
};
//修改数据
const editData = async (dept: any) => {
try {
const { code } = await editDataAPI({ ...thisDept, ...dept });
if (code === 1000) {
messageApi.open({
type: "success",
content: "操作成功",
});
setIsModalOpen(false);
getDatas(queryTableDataParams);
} else {
messageApi.open({
type: "error",
content: "操作失败",
});
}
} catch (error) {}
};
//获取部门数据
const getDatas = async (queryTableDataParams: any) => {
console.log("参数:", queryTableDataParams);
try {
const { code, data } = await getDatasAPI(queryTableDataParams);
console.log(data);
if (code === 1000) {
console.log(isTreeAnyId);
for (let child of data) {
getTree(child);
}
console.log(treeAnyId);
setExpandedRowKeys([...treeAnyId]);
// console.log(treeAnyId);
console.log(data);
setTableData(data);
treeData = data;
console.log(treeData);
// setTotal(data.total);
}
} catch (err: any) {
console.log("555", err);
}
isTreeAnyId = true;
};
//新增
const postAdd = async (dept: any) => {
try {
let { code } = await addDataAPI(dept);
console.log(code);
if (code === 1000) {
console.log("success");
messageApi.open({
type: "success",
content: "操作成功",
});
formModal.setFieldsValue({});
getDatas({ ...queryTableDataParams });
setIsModalOpen(false);
} else {
messageApi.open({
type: "error",
content: "部门名称已存在",
});
}
} catch (error) {}
};
useEffect(() => {
queryTableDataParams = {
...queryTableDataParams,
};
getDatas(queryTableDataParams);
return ()=>{
setIsAllExpend(true),
isTreeAnyId=false
}
}, [queryTableDataParams]);
return (
<ConfigProvider locale={zh_CN}>
<div className="deptBox">
<Form
layout="inline"
initialValues={undefined}
form={formSearch}
onFinish={handleSerach}
style={{ fontWeight: "700" }}
>
<Form.Item
label="部门名称"
name="deptName"
style={{ width: 300 + "px", marginTop: "10px" }}
>
<Input placeholder="请输入部门名称" allowClear />
</Form.Item>
<Form.Item
label="状态"
name="state"
wrapperCol={{ span: 22 }}
style={{ marginTop: "10px" }}
>
<Select
style={{ width: 300 + "px",textAlign:"left" }}
allowClear
showSearch
placeholder="请选择部门状态"
optionFilterProp="lable"
options={[
{
value: 0,
label: "正常",
},
{
value: 1,
label: "停用",
},
]}
/>
</Form.Item>
<Form.Item style={{ marginTop: "10px" }}>
<Button
type="primary"
htmlType="submit"
style={{ marginLeft: 20 + "px" }}
onClick={() => handleSerach()}
>
<SearchOutlined />
</Button>
</Form.Item>
<Form.Item style={{ marginTop: "10px" }}>
<Button onClick={() => handleReset()}>
<SyncOutlined />
</Button>
</Form.Item>
</Form>
{/* 新增 */}
<div className="newAdd">
<Button type="primary" onClick={() => handleNewAdd()}>
+
</Button>
<Button
type="primary"
style={{ backgroundColor: "rgb(144,147,153)" }}
onClick={() => {
setIsAllExpend(!isAllExpend);
if (isAllExpend) {
setExpandedRowKeys([]);
} else setExpandedRowKeys(treeAnyId);
}}
>
<SwapOutlined rotate={90} />
{isAllExpend ? "全部收起" : "全部展开"}
</Button>
</div>
{/* 弹出 */}
<Modal
open={isModalOpen}
title={modalTitle}
okText="确定"
cancelText="取消"
onCancel={handleModalCanle}
onOk={handleModalOk}
width={"700px"}
>
<Form
form={formModal}
// layout="inline"
name="form_in_modal"
initialValues={{ state: "0" }}
labelAlign="right"
// labelCol={{span:12}}
wrapperCol={{ span: 16 }}
>
<Row>
<Col span={24}>
<Form.Item
name="parentId"
label="上级部门"
rules={[{ required: true, message: "请选择上级部门" }]}
// style={{ width: 100 + "%" }}
>
<TreeSelect
disabled={isDisbaled}
// showSearch
style={{ width: "559px" }}
// value={value}
dropdownStyle={{ maxHeight: 400, overflow: "auto" }}
placeholder="请选择上级部门"
allowClear
// treeDefaultExpandAll
// onChange={onChange}
treeData={treeData}
//
/>
</Form.Item>
</Col>
</Row>
<Row>
<Col span={12}>
<Form.Item
name="deptName"
label="部门名称"
rules={[{ required: true, message: "请输入部门名称" }]}
// style={{ width: 45 + "%", marginTop: "20px" }}
>
<Input placeholder="请输入部门名称" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
required
name="orderNum"
label="显示顺序"
rules={[{ required: true, message: "请输入部门显示顺序" }]}
// style={{ width: 40 + "%", marginTop: "20px" }}
>
<InputNumber min={0} controls={true} />
</Form.Item>
</Col>
</Row>
<Row style={{translate:'25px'}}>
<Col span={12}>
<Form.Item
name="leader"
label="负责人"
// style={{ width: 40 + "%", marginTop: "20px", marginLeft: "10px" }}
>
<Input placeholder="请输入负责人" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="phone"
label="联系电话"
// style={{ width: 40 + "%", marginTop: "20px" }}
>
<Input placeholder="请输入联系电话" />
</Form.Item>
</Col>
</Row>
<Row style={{translate:'38px'}}>
<Col span={12}>
<Form.Item
name="email"
label="邮箱"
// style={{ width: 40 + "%", marginTop: "20px", marginLeft: "10px" }}
>
<Input placeholder="请输入邮箱" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="state"
label="状态"
className="collection-create-form_last-form-item"
// style={{ width: 40 + "%", marginTop: "20px", marginLeft: "10px" }}
>
<Radio.Group>
<Radio defaultChecked={true} value="0">
</Radio>
<Radio value="1"></Radio>
</Radio.Group>
</Form.Item>
</Col>
</Row>
</Form>
</Modal>
{/* 表格 */}
<div className="tablebox">
{contextHolder}
<Table
expandedRowKeys={expandedRowKeys}
onExpand={(expanded, record) => {
// console.log(expanded, record);
if (expanded) {
setExpandedRowKeys([record.deptId, ...expandedRowKeys]);
} else {
const newEx = expandedRowKeys.filter((element) => {
return element != record.deptId;
});
// console.log(expandedRowKeys);
setExpandedRowKeys(newEx);
}
console.log(expandedRowKeys);
}}
columns={columns}
rowKey={"deptId"}
dataSource={tableData}
pagination={false}
/>
</div>
</div>
</ConfigProvider>
);
return(
<div>dept</div>
)
}

View File

@@ -1,60 +0,0 @@
#content {
display: flex;
border-top: 1px solid black;
.dept-content {
flex: 20%;
padding: 35px 12px 0 0;
height: calc(100vh - 85px);
}
.left-dept {
flex: 20%;
padding: 35px 12px 0 0;
height: calc(100vh - 85px);
border: 1px solid red;
border-top: 1px solid black;
}
.right {
flex: 80%;
height: 190px;
display: flex;
flex-direction: column;
.search-content {
display: flex;
width: 500px;
justify-content: space-around;
padding: 35px 12px 0 0;
margin-left: 20px;
}
}
.table-content {
margin: 12px 0 0 12px;
.ant-table-thead > tr > th {
color: #909399;
text-align: center;
}
.ant-table-tbody > tr > td {
text-align: center;
}
}
.add-content {
display: flex;
margin-left: 12px;
margin-top: 20px;
button:focus,
button:focus-visible {
outline: none;
}
}
.user-mid-button {
display: flex;
margin-left: 12px;
margin-top: 20px;
button:focus,
button:focus-visible {
outline: none;
}
}
}

View File

@@ -1,242 +1,5 @@
import "./index.scss";
import { Select, Button, Table, Space, Tag, message, Modal } from "antd";
import {
EditOutlined,
DeleteOutlined,
ExclamationCircleFilled,
} from "@ant-design/icons";
import {
getNoticeListApi,
deleteNoticeInfoApi,
} from "../../../../api/system/notice";
import { useEffect, useState } from "react";
import { SearchOutlined, RedoOutlined } from "@ant-design/icons";
export default function Inform() {
const [noticeInfo, setNoticeInfo] = useState<string>("");
const [isNoticeOpen, setIsNoticeOpen] = useState<boolean>(false);
const [listData, setListData] = useState([]);
const [messageApi, contextHolder] = message.useMessage();
const [queryParams, setQueryParams] = useState<QueryParamsType>({
state: undefined,
pageSize: undefined,
pageNum: undefined,
});
const columns = [
{
title: "序号",
dataIndex: "noticeId",
key: "noticeId",
render: (text: string) => <>{text ? text : "null"}</>,
},
{
title: "公告标题",
dataIndex: "noticeTitle",
key: "noticeTitle",
render: (text: string) => <>{text ? text : "null"}</>,
},
{
title: "阅读状态",
key: "state",
dataIndex: "state",
render: (text: string) => (
<>
{text === "1" ? (
<Tag color="warning"></Tag>
) : (
<Tag color="error"></Tag>
)}
</>
),
},
{
title: "操作",
key: "operate",
dataIndex: "operate",
render: (_: string, record: object) => (
<div style={{ color: "#58aaff" }}>
<Space>
<EditOutlined />
<a
href="#"
onClick={() => handleInfo(record)}
style={{ color: " #58aaff" }}
>
</a>
<DeleteOutlined />
<a
href="#"
onClick={() => handleDel(record)}
style={{ color: " #58aaff" }}
>
</a>
</Space>
</div>
),
},
];
interface QueryParamsType {
state?: string;
pageSize?: number;
pageNum?: number;
}
const getList = async (newQueryParams: object) => {
try {
const { code, data } = await getNoticeListApi(newQueryParams);
if (code === 1000) {
setListData(data.rows);
}
} catch (err) {
console.error(err);
}
};
const handleReset = async () => {
setQueryParams({});
getList({});
};
const handleSearch = () => {
getList(queryParams);
};
const handleInfo = (record: any) => {
setIsNoticeOpen(true);
setNoticeInfo(record.noticeTitle);
};
const handleInfoOk = () => {
setIsNoticeOpen(false);
};
const handleInfoCancel = () => {
setIsNoticeOpen(false);
};
const handleDel = async (record: any) => {
Modal.confirm({
title: `确定删除Id为-${record.noticeId}-, 名称为-${record.noticeTitle}-的岗位吗?`,
icon: <ExclamationCircleFilled />,
async onOk() {
const { code } = await deleteNoticeInfoApi(record.noticeId);
try {
if (code === 1000) {
messageApi.open({
type: "success",
content: "删除成功",
});
getList({});
} else {
messageApi.open({
type: "error",
content: "删除失败",
});
}
} catch (err) {
console.log(err);
}
},
onCancel() {
messageApi.open({
type: "warning",
content: "取消成功",
});
},
});
};
const handlePageChange = (page: number) => {
setQueryParams({
...queryParams,
pageNum: page,
});
};
useEffect(() => {
getList(queryParams);
}, []);
return (
<div id="content">
<>
<div className="right">
<div className="search-content">
<>
<Space>
<div></div>
<Select
style={{ width: 220 }}
placeholder="请选择状态"
allowClear
options={[
{ value: "1", label: "已读" },
{ value: "0", label: "未读" },
]}
value={queryParams.state}
onChange={(value: any) =>
setQueryParams({
...queryParams,
state: value,
})
}
/>
</Space>
<Space>
<div className="search-button">
<Button type="primary" onClick={handleSearch}>
<SearchOutlined />
</Button>
</div>
</Space>
<Space>
<div className="reset-button" onClick={handleReset}>
<Button>
<RedoOutlined />
</Button>
</div>
</Space>
</>
</div>
<Modal
title="通知弹框"
open={isNoticeOpen}
onOk={handleInfoOk}
onCancel={handleInfoCancel}
footer={null}
>
<h1>{noticeInfo}</h1>
</Modal>
<div className="table-content">
<>
{contextHolder}
<Table
columns={columns}
dataSource={listData}
className="article-table"
pagination={{
onChange: handlePageChange,
locale: {
jump_to: "跳至",
page: "页",
},
showQuickJumper: true,
showTotal: (total, range) =>
`${range[0]}-${range[1]} 条,共 ${total}`,
}}
/>
</>
</div>
</div>
</>
</div>
);
}
return(
<div>1</div>
)
}

View File

@@ -1,64 +0,0 @@
.Box{
width: 100%;
height: 100%;
background-color: white;
padding: 15px;
.tablebox{
table{
thead{
th::before{
}
tr{
.ant-table-cell{
background: white;
color:#909399
}
}
}
tbody{
tr{
.ant-table-cell{
background: white;
color:#606266
}
}
}
}
.ant-table-cell{
button:focus
{
outline: none;
}
button:hover
{
border: 0px rgb(250, 250, 250);
}
}
}
.newadd{
width: 60px;
height: 40px;
margin-top: 15px;
}
}
.myTree{
margin-top: 10px;
border: 1px solid rgb(173, 131, 131);
width: 250px;
}
.checkBox{
margin-top: 5px;
width: 250px;
display: flex;
label{
height: 20px;
margin-right: 10px;
}
}
.tox-tinymce{
width: 700px;
}

View File

@@ -1,858 +1,5 @@
import { useState, useEffect } from "react";
import {
Button,
Input,
Select,
message,
Table,
Tag,
Modal,
Pagination,
Form,
Radio,
ConfigProvider,
Row,
Col,
TreeSelect,
} from "antd";
import { Editor } from "@tinymce/tinymce-react";
import type { ColumnsType } from "antd/es/table";
import {
SyncOutlined,
SearchOutlined,
ExclamationCircleFilled,
} from "@ant-design/icons";
import zh_CN from "antd/es/locale/zh_CN";
import "dayjs/locale/zh-cn";
import "./index.scss";
import {
getDataListAPI,
getUserListAPI,
getRolesListAPI,
getDeptsListAPI,
addDataAPI,
deleteDataAPI,
getDataAPI,
} from "../../../../api/system/publish";
interface searchValueType {
dateTime: string[] | undefined;
roleName: string | undefined;
roleKey: string | undefined;
state: string | undefined;
startTime: string | undefined;
endTime: string | undefined;
}
//表格单项数据类型
interface TableDataType {
createTime: string;
dataScope: string;
deptIds: any[];
menuIds: any[];
roleId: number;
roleKey: string;
roleName: string;
roleSort: string;
state: string;
updateTime: string;
key?: number;
total?: number;
}
interface dataType {
senders: string[];
cluster?: string | null;
createBy?: string | null;
contentType?: string | null;
noticeContent: string;
noticeId?: number | null;
noticeTitle?: string | null;
noticeType?: string | null;
sendType?: string | null;
state?: string | null;
}
//当前选择的角色信息
interface queryParamsType {
cluster?: string;
contentType?: string;
noticeTitle?: string;
noticeType?: string;
publishId?: number;
sendType?: string;
pageNum?: number;
pageSize?: number;
}
let thisrole: any = {};
export default function Inform() {
const editorInit = {
language: "zh_CN",
min_height: 400,
plugins:
"print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template code codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help emoticons autosave bdmap indent2em autoresize formatpainter axupimgs",
toolbar:
["code undo redo restoredraft | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough link | anchor | alignleft aligncenter alignright alignjustify outdent indent | \
styleselect formatselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \
table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | bdmap indent2em lineheight formatpainter axupimgs"],
importcss_append: true,
//自定义文件选择器的回调内容
// file_picker_callback: function (callback, value, meta) {
// if (meta.filetype === 'file') {
// callback('https://www.baidu.com/img/bd_logo1.png', { text: 'My text' });
// }
// if (meta.filetype === 'image') {
// callback('https://www.baidu.com/img/bd_logo1.png', { alt: 'My alt text' });
// }
// if (meta.filetype === 'media') {
// callback('movie.mp4', { source2: 'alt.ogg', poster: 'https://www.baidu.com/img/bd_logo1.png' });
// }
// }
};
const { confirm } = Modal;
//提示组件
const [messageApi, contextHolder] = message.useMessage();
//搜索框内所有内容
let [searchValue, setSearchValue] = useState<searchValueType>({
dateTime: undefined,
roleName: undefined,
roleKey: undefined,
startTime: undefined,
state: undefined,
endTime: undefined,
});
const [thisNotice, setThisNotice] = useState<dataType>({
noticeContent: "",
senders: [],
});
const [allDisplay,setAllDisplay]=useState('block')
//Modal
const [isModalOpen, setIsModalOpen] = useState(false);
const [isDetailModalOpen, setIsDetailModalOpen] = useState(false);
const [modalTitle, setModalTitle] = useState("");
//表单区域
const [addForm] = Form.useForm();
const [detailForm] = Form.useForm();
//serach
const [formSearch] = Form.useForm();
//当前页面页数
let [count, setCount] = useState(1);
//表格内数据
let [tableData, setTableData] = useState<TableDataType[]>([]);
//发送对象数据
const [senderIds, setSenderIds] = useState<any>(undefined);
const [editorValue,setEditorValue]=useState('')
//表格数据总条数
let [total, setTotal] = useState<number>(0);
//表格格式
const columns: ColumnsType<TableDataType> = [
{
title: "序号",
dataIndex: "key",
key: "key",
},
{
title: "公告标题",
dataIndex: "noticeTitle",
key: "noticeTitle",
},
{
title: "公告类型",
dataIndex: "noticeType",
key: "noticeType",
render: (text) => {
switch (text) {
case "1":
return <Tag color="processing"></Tag>;
case "2":
return <Tag color="processing"></Tag>;
}
},
},
{
title: "内容类型",
key: "contentType",
dataIndex: "contentType",
render: (text) => {
switch (text) {
case "text":
return <Tag color=""></Tag>;
case "html":
return <Tag color="success"></Tag>;
}
},
},
{
title: "发送类型",
key: "sendType",
dataIndex: "sendType",
render: (text) => {
switch (text) {
case "user":
return <></>;
case "role":
return <></>;
case "dept":
return <></>;
case "all":
return <></>;
}
},
},
{
title: "创建时间",
key: "createTime",
dataIndex: "createTime",
},
{
title: "操作",
key: "",
dataIndex: "",
render: (text) => (
<>
<Button type="link" onClick={() => handleDetail(text)}>
{"详情"}
</Button>
<Button type="link" danger onClick={() => handleDelete(text)}>
{"删除"}
</Button>
</>
),
},
];
//请求表格内容参数
let [queryTableDataParams, setQueryTableDataParams] = useState<any>({
cluster: undefined,
contentType: undefined,
noticeTitle: undefined,
noticeType: undefined,
publishId: undefined,
sendType: undefined,
pageSize: undefined,
pageNum: undefined,
});
const onSendTypeChange = (value: string) => {
console.log(value);
if (value === "user") {
getUserList();
setAllDisplay('block')
} else if (value === "role") {
getRolesList();
setAllDisplay('block')
} else if (value === "dept") {
getDeptsList();
setAllDisplay('block')
}
else {
setAllDisplay('none')
}
};
const onEditorChange=(Value:string)=>{
setEditorValue(Value)
}
// let thisrole: any = {roleId:'s'};
const handleDetail = (text: any) => {
getData(text.noticeId);
// console.log(thisNotice.);
setIsDetailModalOpen(true);
};
const handleDelete = (text: any) => {
console.log(text);
confirm({
title: "系统提示",
icon: <ExclamationCircleFilled />,
content: `确定删除部门名称为${text.noticeTitle}的数据吗`,
okText: "确定",
okType: "danger",
cancelText: "取消",
onOk() {
(async () => {
try {
let { code } = await deleteDataAPI(text.noticeId);
if (code === 1000) {
messageApi.open({
type: "success",
content: "操作成功",
});
getDataList({});
}
} catch (error) {
console.log(error);
}
})();
},
onCancel() {
console.log("Cancel");
},
});
};
const handleSerach = () => {
searchValue = formSearch.getFieldsValue();
setSearchValue(searchValue);
count = 1;
setQueryTableDataParams({ ...searchValue });
};
const handleReset = () => {
formSearch.resetFields();
searchValue = formSearch.getFieldsValue();
setSearchValue(searchValue);
setQueryTableDataParams({ ...searchValue });
};
//Modal区域
const handleModalOk = () => {
addForm
.validateFields()
.then((values) => {
// form.resetFields();
if (modalTitle == "新增公告") {
if(values.sendType==='all') values.senderIds=['0']
console.log(values);
postAdd({ ...values, cluster: "notice", action: "SEND" ,noticeContent:editorValue});
}
})
.catch((info) => {
console.log("Validate Failed:", info);
});
console.log("modal thisrole", thisrole);
};
const handleModalCanle = () => {
setIsModalOpen(false);
};
const handleDetailCanle = () => {
setIsDetailModalOpen(false);
};
//新增
const handleNewAdd = () => {
setModalTitle("新增公告");
addForm.setFieldsValue({
noticeTitle: undefined,
noticeType: "1",
sendType: undefined,
senderIds: undefined,
contentType: "html",
});
setAllDisplay('block');
setEditorValue('')
setIsModalOpen(true);
};
const filterOption = (
input: string,
option?: { label: string; value: string }
) => (option?.label ?? "").toLowerCase().includes(input.toLowerCase());
//表格函数
//从服务器获取数据
//页码改变
const pageChange = (page: number, pageSize: number) => {
console.log(page, pageSize);
queryTableDataParams = { ...queryTableDataParams, pageNum: page, pageSize };
// setQueryParams({...queryParams,pageNum:page,pageSize})
console.log(queryTableDataParams);
getDataList(queryTableDataParams);
setCount(page);
};
//新增请求
const postAdd = async (value: any) => {
try {
let { code } = await addDataAPI(value);
if (code === 1000) {
console.log("success");
messageApi.open({
type: "success",
content: "操作成功",
});
addForm.setFieldsValue({
noticeTitle: undefined,
noticeType: "1",
sendType: undefined,
senderIds: undefined,
contentType: "html",
});
getDataList({ ...queryTableDataParams, pageNum: count });
setIsModalOpen(false);
} else {
messageApi.open({
type: "error",
content: "角色名称已存在",
});
}
} catch (error) {}
};
const getData = async (noticeId: number) => {
try {
const { data, code } = await getDataAPI(noticeId);
if (code === 1000) {
setThisNotice({ ...data });
}
} catch (error) {
console.log(error);
}
};
const getTree = function (tree: any) {
tree.title = tree.deptName;
tree.value = tree.deptId;
if (tree.children) {
for (let child of tree.children) {
getTree(child);
}
}
};
const getUserList = async () => {
try {
const { code, data } = await getUserListAPI();
if (code === 1000) {
let userIds: any = [];
console.log(data.rows);
data.rows.forEach((item: any) => {
userIds.push({ value: item.userId, label: item.userName });
});
setSenderIds([...userIds]);
}
} catch (error) {
console.log(error);
}
};
const getRolesList = async () => {
try {
const { code, data } = await getRolesListAPI();
if (code === 1000) {
let RolesIds: any = [];
console.log(data.rows);
data.rows.forEach((item: any) => {
RolesIds.push({ value: item.roleId, label: item.roleName });
});
setSenderIds([...RolesIds]);
}
} catch (error) {
console.log(error);
}
};
const getDeptsList = async () => {
try {
const { code, data } = await getDeptsListAPI();
if (code === 1000) {
for (let child of data) {
getTree(child);
}
console.log(data);
setSenderIds([...data]);
}
} catch (err: any) {
console.log("555", err);
}
};
const getDataList = async (queryTableDataParams: queryParamsType) => {
console.log("参数:", queryTableDataParams);
try {
const { code, data } = await getDataListAPI(queryTableDataParams);
if (code === 1000) {
const sortData = data.rows.sort(
(a: TableDataType, b: TableDataType) =>
parseInt(a.roleSort) - parseInt(b.roleSort)
);
sortData.forEach((element: TableDataType, i: number) => {
element.key = i + 1;
});
setTableData(sortData);
setTotal(data.total);
}
} catch (err: any) {
console.log("555", err);
}
};
useEffect(() => {
// setQueryParams({...queryParams,...valueSch})
queryTableDataParams = {
...queryTableDataParams,
// ...searchValue,
pageNum: count,
};
getDataList(queryTableDataParams);
// console.log(queryParams);
}, [queryTableDataParams]);
return (
<ConfigProvider locale={zh_CN}>
<div className="Box">
<Form
layout="inline"
initialValues={undefined}
form={formSearch}
onFinish={handleSerach}
style={{ fontWeight: "700" }}
>
<Form.Item
label="公告标题"
name="noticeTitle"
style={{ width: 350 + "px", marginTop: "10px" }}
>
<Input placeholder="请输入公告标题" allowClear />
</Form.Item>
<Form.Item
label="公告类型"
name="noticeType"
style={{ width: 350 + "px", marginTop: "10px" }}
>
<Select
style={{ textAlign: "left" }}
allowClear
showSearch
placeholder="请选择公告类型"
optionFilterProp="lable"
filterOption={filterOption}
options={[
{
value: "1",
label: "通知",
},
{
value: "2",
label: "公告",
},
]}
/>
</Form.Item>
<Form.Item
label="内容类型"
name="contentType"
style={{ width: 350 + "px", marginTop: "10px" }}
>
<Select
style={{ textAlign: "left" }}
allowClear
showSearch
placeholder="请选择内容类型"
optionFilterProp="lable"
filterOption={filterOption}
options={[
{
value: "text",
label: "文本",
},
{
value: "html",
label: "富文本",
},
]}
/>
</Form.Item>
<Form.Item
label="发送类型"
name="sendType"
style={{ width: 350 + "px", marginTop: "10px" }}
>
<Select
style={{ textAlign: "left" }}
allowClear
showSearch
placeholder="请选择发送类型"
optionFilterProp="lable"
filterOption={filterOption}
options={[
{
value: "user",
label: "用户",
},
{
value: "role",
label: "角色",
},
{
value: "dept",
label: "部门",
},
{
value: "all",
label: "全发",
},
]}
/>
</Form.Item>
<Form.Item style={{ marginTop: "10px" }}>
<Button
type="primary"
htmlType="submit"
style={{ marginLeft: 20 + "px" }}
onClick={() => handleSerach()}
>
<SearchOutlined />
</Button>
</Form.Item>
<Form.Item style={{ marginTop: "10px" }}>
<Button onClick={() => handleReset()}>
<SyncOutlined />
</Button>
</Form.Item>
</Form>
{/* 新增 */}
<div className="newadd">
<Button type="primary" onClick={handleNewAdd}>
+
</Button>
</div>
{/* 弹出 */}
<Modal
open={isModalOpen}
title={modalTitle}
width={800}
okText="确定"
cancelText="取消"
onCancel={handleModalCanle}
onOk={handleModalOk}
>
<Form
form={addForm}
layout="horizontal"
name="form_in_modal"
initialValues={{ noticeType: "1", contentType: "1" }}
labelAlign="right"
wrapperCol={{ span: 16 }}
>
<Row>
<Col span={12}>
<Form.Item
name="noticeTitle"
label="公告标题"
rules={[{ required: true, message: "请输入公告标题" }]}
>
<Input placeholder="请输入公告标题" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="noticeType"
label="公告类型"
rules={[{ required: true }]}
>
<Radio.Group>
<Radio defaultChecked={true} value="1">
</Radio>
<Radio value="2"></Radio>
</Radio.Group>
</Form.Item>
</Col>
</Row>
<Row>
<Col span={12}>
<Form.Item
required
name="sendType"
label="发送类型"
rules={[{ required: true, message: "选择发送类型" }]}
>
<Select
style={{ textAlign: "left" }}
allowClear
showSearch
placeholder="请选择发送类型"
optionFilterProp="lable"
filterOption={filterOption}
onChange={(value) => onSendTypeChange(value)}
options={[
{
value: "user",
label: "用户",
},
{
value: "role",
label: "角色",
},
{
value: "dept",
label: "部门",
},
{
value: "all",
label: "全发",
},
]}
/>
</Form.Item>
</Col>
<Col span={12}>{
allDisplay==='block'?<Form.Item
name="senderIds"
label="发送对象"
rules={[{ required: true, message: "选择发送对象" }]}
>
{senderIds === undefined ? (
<Select
mode="multiple"
style={{ textAlign: "left" }}
allowClear
showSearch
placeholder="请选择发送对象"
optionFilterProp="lable"
filterOption={filterOption}
/>
) : senderIds[0].children === undefined ? (
<Select
mode="multiple"
style={{ textAlign: "left" }}
allowClear
showSearch
placeholder="请选择发送对象"
optionFilterProp="lable"
filterOption={filterOption}
options={senderIds}
/>
) : (
<TreeSelect
multiple
style={{ textAlign: "left" }}
dropdownStyle={{ maxHeight: 400, overflow: "auto" }}
placeholder="请选择发送对象"
allowClear
treeData={senderIds}
//
/>
)}
</Form.Item>
:null
}
</Col>
</Row>
<Row>
<Form.Item
name="contentType"
label="内容类型"
rules={[{ required: true, message: "选择发送类型" }]}
>
<Radio.Group>
<Radio defaultChecked={true} value="html">
</Radio>
<Radio value="text"></Radio>
</Radio.Group>
</Form.Item>
</Row>
<Form.Item name="noticeContent" label="公告内容">
<Row>
<div>
<Editor
apiKey="v4zo4n22oanvco29ws5drh0pecuf3gh53clx53cccj3grjwg"
initialValue=""
init={editorInit}
value={editorValue}
onEditorChange={(Value)=>onEditorChange(Value)}
></Editor></div>
</Row>
</Form.Item>
</Form>
</Modal>
<Modal
open={isDetailModalOpen}
title={"公告详情"}
width={1200}
footer={null}
onCancel={handleDetailCanle}
>
<Form
form={detailForm}
layout="horizontal"
name="form_in_modal"
initialValues={{}}
labelAlign="right"
wrapperCol={{ span: 16 }}
>
<Row>
<Col span={8}>
<Form.Item
name="noticeTitle"
label="公告标题"
// initialValue={'ssss'}
>
<span> {thisNotice.noticeTitle}</span>
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name="sendType"
label="发送类型"
// initialValue={'ssss'}
>
<span>
{" "}
{thisNotice.sendType === "user"
? "用户"
: thisNotice.sendType === "role"
? "角色"
: thisNotice.sendType === "dept"
? "部门"
: "全发"}
</span>
</Form.Item>
</Col>
<Col span={8}>
<Form.Item name="sendIds" label="发送对象">
<span>{thisNotice.senders.join("")}</span>
</Form.Item>
</Col>
</Row>
<Row>
<Col span={8}>
<Form.Item name="noticeType" label="公告类型">
<span>
{thisNotice.noticeType === "1" ? (
<Tag color="processing"></Tag>
) : (
<Tag color="processing"></Tag>
)}
</span>
</Form.Item>
</Col>
<Col span={8}>
<Form.Item name="contentType" label="内容类型">
<span>
{thisNotice.contentType === "html" ? (
<Tag color="success"></Tag>
) : (
<Tag></Tag>
)}
</span>
</Form.Item>
</Col>
</Row>
<Row>
<Form.Item name="noticeContent" label="公告内容">
<span
dangerouslySetInnerHTML={{ __html: thisNotice.noticeContent }}
></span>
</Form.Item>
</Row>
</Form>
</Modal>
{/* 表格 */}
<div className="tablebox">
{contextHolder}
<Table columns={columns} dataSource={tableData} pagination={false} />
<Pagination
style={{
float: "right",
marginTop: "10px",
}}
total={total}
current={count}
showSizeChanger
showQuickJumper
onChange={(page, pageSize) => pageChange(page, pageSize)}
showTotal={(total) => `${total}`}
/>
</div>
</div>
</ConfigProvider>
);
}
return(
<div>2</div>
)
}

View File

@@ -1,103 +0,0 @@
#content {
display: flex;
border-top: 1px solid black;
.dept-content {
flex: 20%;
padding: 35px 12px 0 0;
height: calc(100vh - 85px);
}
.left-dept {
flex: 20%;
padding: 35px 12px 0 0;
height: calc(100vh - 85px);
border: 1px solid red;
border-top: 1px solid black;
}
.right {
flex: 80%;
height: 190px;
display: flex;
flex-direction: column;
.search-content {
display: flex;
flex-direction: column;
padding: 35px 12px 0 0;
.content-top {
display: flex;
.input-item {
display: flex;
align-items: center;
margin-right: 20px;
width: 270px;
div {
width: 120px;
font-weight: bold;
}
}
:nth-child(3) {
div {
margin-right: -30px;
}
}
}
.content-bottom {
display: flex;
margin-left: 12px;
margin-top: 20px;
div {
margin-right: 10px;
}
.time-selector {
display: flex;
align-items: center;
div {
width: 120px;
font-weight: bold;
}
.time-picker {
width: 400px;
text-align: center;
margin-left: -30px;
margin-right: 25px;
}
}
button:focus,
button:focus-visible {
outline: none;
}
}
}
.table-content {
margin: 12px 0 0 12px;
.ant-table-thead > tr > th {
color: #909399;
text-align: center;
}
.ant-table-tbody > tr > td {
text-align: center;
}
}
.add-content {
display: flex;
margin-left: 12px;
margin-top: 20px;
button:focus,
button:focus-visible {
outline: none;
}
}
.user-mid-button {
display: flex;
margin-left: 12px;
margin-top: 20px;
button:focus,
button:focus-visible {
outline: none;
}
}
}
}

View File

@@ -1,472 +0,0 @@
import "./index.scss";
import {
Input,
Select,
Button,
Table,
Space,
Tag,
message,
Modal,
Form,
Row,
Col,
Radio,
InputNumber,
} from "antd";
import {
EditOutlined,
DeleteOutlined,
ExclamationCircleFilled,
} from "@ant-design/icons";
import {
getPostListApi,
addPostApi,
editPostApi,
deletePostApi,
} from "../../../api/system/post";
import { useEffect, useState } from "react";
import { SearchOutlined, RedoOutlined, PlusOutlined } from "@ant-design/icons";
export default function Post() {
const [form] = Form.useForm();
const [echoData, setEchoData] = useState<QueryParamsType>({});
const [listData, setListData] = useState([]);
const [radioValue, setRadioValue] = useState(1);
const [messageApi, contextHolder] = message.useMessage();
const [modalTitle, setModalTitle] = useState<string>("");
const [buttonType, setButtonType] = useState<string>("");
const [isShowModal, setIsShowModal] = useState<boolean>(false);
const [queryParams, setQueryParams] = useState<QueryParamsType>({
postName: undefined,
postCode: undefined,
state: undefined,
postSort: undefined,
pageSize: undefined,
pageNum: undefined,
});
const columns = [
{
title: "序号",
dataIndex: "postId",
key: "Id",
render: (text: string) => <>{text ? text : "null"}</>,
},
{
title: "岗位名称",
dataIndex: "postName",
key: "postName",
render: (text: string) => <>{text ? text : "null"}</>,
},
{
title: "岗位编码",
dataIndex: "postCode",
key: "postCode",
render: (text: string) => <>{text ? text : "null"}</>,
},
{
title: "排序",
key: "postSort",
dataIndex: "postSort",
render: (text: string) => <>{text ? text : "--"}</>,
},
{
title: "状态",
key: "state",
dataIndex: "state",
render: (text: string) => (
<>
{text === "0" ? (
<Tag color="processing"></Tag>
) : (
<Tag color="processing"></Tag>
)}
</>
),
},
{
title: "创建时间",
key: "createTime",
dataIndex: "createTime",
render: (text: string) => <>{text ? text : "null"}</>,
},
{
title: "操作",
key: "operate",
dataIndex: "operate",
render: (_: string, record: object) => (
<div style={{ color: "#58aaff" }}>
<Space>
<EditOutlined />
<a
href="#"
onClick={() => handleEdit(record)}
style={{ color: " #58aaff" }}
>
</a>
<DeleteOutlined />
<a
href="#"
onClick={() => handleDel(record)}
style={{ color: " #58aaff" }}
>
</a>
</Space>
</div>
),
},
];
interface QueryParamsType {
postName?: string;
postCode?: string;
state?: string;
postSort?: string;
postId?: string;
pageSize?: number;
pageNum?: number;
}
const getPostList = async (newQueryParams: object) => {
try {
const { code, data } = await getPostListApi(newQueryParams);
if (code === 1000) {
setListData(data.rows);
}
} catch (err) {
console.error(err);
}
};
const handleAdd = () => {
setModalTitle("新增用户");
setButtonType("ADD");
setIsShowModal(true);
};
const handleEdit = (data: any) => {
setModalTitle("修改用户");
setButtonType("EDIT");
setIsShowModal(true);
console.log(data);
setEchoData({
postId: data.postId,
});
handleEcho(data);
};
const handleConfirm = () => {
form.validateFields().then((values) => {
console.log(values);
console.log(buttonType);
if (buttonType === "ADD") {
handleConfirmAdd(values);
} else if (buttonType === "EDIT") {
handleConfirmEdit(values);
} else {
messageApi.open({
type: "error",
content: "系统异常,请刷新后重试",
});
}
});
};
const handleConfirmAdd = async (data: object) => {
console.log(data);
const { code } = await addPostApi(data);
try {
if (code === 1000) {
messageApi.open({
type: "success",
content: "创建成功",
});
setQueryParams({});
handleClear();
} else {
messageApi.open({
type: "error",
content: "岗位名称已经存在",
});
}
} catch (err) {
console.log(err);
}
};
const handleConfirmEdit = async (data: object) => {
const editData = {
...data,
postId: echoData.postId,
};
console.log(editData);
const { code } = await editPostApi(editData);
try {
if (code === 1000) {
messageApi.open({
type: "success",
content: "修改成功",
});
setQueryParams({});
handleClear();
} else {
messageApi.open({
type: "error",
content: "修改失败",
});
}
} catch (err) {
console.log(err);
}
};
const handleReset = async () => {
setQueryParams({});
getPostList({});
};
const handleSearch = () => {
getPostList(queryParams);
};
const handleDel = async (record: any) => {
Modal.confirm({
title: `确定删除Id为-${record.postId}-, 岗位名称为-${record.postName}-的岗位吗?`,
icon: <ExclamationCircleFilled />,
async onOk() {
const { code } = await deletePostApi(record.postId);
try {
if (code === 1000) {
messageApi.open({
type: "success",
content: "删除成功",
});
setQueryParams({});
} else {
messageApi.open({
type: "error",
content: "删除失败",
});
}
} catch (err) {
console.log(err);
}
},
onCancel() {
messageApi.open({
type: "warning",
content: "取消成功",
});
},
});
};
const handleSearchValues = (e: any) => {
const { name, value } = e.target;
setQueryParams({ ...queryParams, [name]: value });
};
const handlePageChange = (page: number) => {
setQueryParams({
...queryParams,
pageNum: page,
});
};
const handleEcho = (data: any) => {
const { postName, postCode, state, postSort } = data;
form.setFieldsValue({
postName,
postCode,
state,
postSort,
});
};
const handleCancel = () => {
handleClear();
};
const handleClear = () => {
form.resetFields();
setIsShowModal(false);
};
const onRadio = (e: any) => {
setRadioValue(e.target.value);
};
useEffect(() => {
getPostList(queryParams);
}, []);
return (
<div id="content">
<>
<div className="right">
<div className="search-content">
<>
<div className="content-top">
<div className="input-item">
<div></div>
<Input
placeholder="请输入岗位名称"
name="postName"
allowClear
value={queryParams.postName}
onChange={handleSearchValues}
/>
</div>
<div className="input-item">
<div></div>
<Input
placeholder="请输入岗位编码"
name="postCode"
allowClear
value={queryParams.postCode}
onChange={handleSearchValues}
/>
</div>
<div className="input-item">
<div></div>
<Select
style={{ width: 120 }}
placeholder="用户状态"
allowClear
options={[
{ value: "1", label: "正常" },
{ value: "0", label: "停用" },
]}
value={queryParams.state}
onChange={(value: any) =>
setQueryParams({
...queryParams,
state: value,
})
}
/>
</div>
</div>
<div className="content-bottom">
<div className="search-button">
<Button type="primary" onClick={handleSearch}>
<SearchOutlined />
</Button>
</div>
<div className="reset-button" onClick={handleReset}>
<Button>
<RedoOutlined />
</Button>
</div>
</div>
</>
</div>
<div className="add-content">
<>
<Button type="primary" onClick={handleAdd}>
<PlusOutlined />
</Button>
</>
</div>
<div className="table-content">
<>
{contextHolder}
<Table
columns={columns}
dataSource={listData}
className="article-table"
pagination={{
onChange: handlePageChange,
locale: {
jump_to: "跳至",
page: "页",
},
showQuickJumper: true,
showTotal: (total, range) =>
`${range[0]}-${range[1]} 条,共 ${total}`,
}}
/>
</>
</div>
<>
{contextHolder}
<Modal
title={modalTitle}
width={600}
okText="确认"
cancelText="取消"
open={isShowModal}
onOk={handleConfirm}
onCancel={handleCancel}
>
<Form
form={form}
name="basic"
initialValues={{ remember: true }}
onFinish={handleConfirm}
labelCol={{ span: 4 }}
autoComplete="off"
className="modal-form"
>
<Row>
<Col span={24}>
<Form.Item
label="岗位名称"
name="postName"
rules={[{ required: true, message: "请输入岗位名称" }]}
>
<Input defaultValue={""} placeholder="请输入岗位名称" />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
label="岗位编码"
name="postCode"
rules={[{ required: true, message: "请输入岗位编码" }]}
>
<Input defaultValue={""} placeholder="请输入岗位编码" />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
label="显示顺序"
name="postSort"
rules={[{ required: false }]}
>
<InputNumber />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
label="状态"
name="state"
rules={[
{
required: false,
},
]}
>
<Radio.Group onChange={onRadio} value={radioValue}>
<Radio value="1"></Radio>
<Radio value="0"></Radio>
</Radio.Group>
</Form.Item>
</Col>
</Row>
</Form>
</Modal>
</>
</div>
</>
</div>
);
}

View File

@@ -1,103 +0,0 @@
.roleBox{
width: 100%;
height: 100%;
background-color: white;
padding: 15px;
// display: flex;
// flex-wrap: wrap;
// .SearchBox{
// display: flex;
// flex-wrap: wrap;
// .ipt{
// margin-top: 10px;
// margin-right: 10px;
// height: 32px;
// line-height: 32px;
// display: flex;
// span{
// font-weight: 700;
// // line-height: 32px;
// padding-right: 12px;
// // color: #606266;
// }
// .item,input{
// flex: 1;
// font-weight: 400;
// // width: 300px;
// margin-right: 40px;
// .ant-space-item{
// // margin-left: 500px;
// width: 500px;
// }
// }
// }
// .btn{
// button{
// margin-right: 15px;
// }
// margin-top: 10px;
// }
// }
// .btn{
// button{
// margin-right: 15px;
// }
// margin-top: 10px;
// }
.tablebox{
table{
thead{
th::before{
}
tr{
.ant-table-cell{
background: white;
color:#909399
}
}
}
tbody{
tr{
.ant-table-cell{
background: white;
color:#606266
}
}
}
}
.ant-table-cell{
button:focus
{
outline: none;
}
button:hover
{
border: 0px rgb(250, 250, 250);
}
}
}
.newadd{
width: 60px;
height: 40px;
margin-top: 15px;
}
}
.myTree{
margin-top: 10px;
border: 1px solid rgb(173, 131, 131);
width: 250px;
}
.checkBox{
margin-top: 5px;
width: 250px;
display: flex;
label{
height: 20px;
margin-right: 10px;
}
}

View File

@@ -1,715 +0,0 @@
import { useState, useEffect } from "react";
import {
Button,
Input,
Select,
DatePicker,
Space,
message,
Table,
Tag,
Modal,
Pagination,
Form,
Checkbox,
InputNumber,
Radio,
Tree,
ConfigProvider,
} from "antd";
import type { CheckboxChangeEvent } from "antd/es/checkbox";
import type { DatePickerProps, RangePickerProps } from "antd/es/date-picker";
import type { ColumnsType } from "antd/es/table";
import {
SyncOutlined,
SearchOutlined,
ExclamationCircleFilled,
} from "@ant-design/icons";
import zh_CN from "antd/es/locale/zh_CN";
import dataLocale from "antd/es/date-picker/locale/zh_CN";
import "dayjs/locale/zh-cn";
import "./index.scss";
import {
getRolesDataAPI,
delRoleAPI,
getRoleAPI,
addRoleAPI,
setRoleDataAPI,
getMenuLiseAPI,
} from "../../../api/system/role";
// import { useForm } from "antd/es/form/Form";
interface searchValueType {
dateTime: string[] | undefined;
roleName: string | undefined;
roleKey: string | undefined;
state: string | undefined;
startTime: string | undefined;
endTime: string | undefined;
}
//表格单项数据类型
interface TableDataType {
createTime: string;
dataScope: string;
deptIds: any[];
menuIds: any[];
roleId: number;
roleKey: string;
roleName: string;
roleSort: string;
state: string;
updateTime: string;
key?: number;
total?: number;
}
//当前选择的角色信息
const fieldNames = {
title: "menuName",
key: "menuId",
children: "children",
};
let thisrole: any = {};
let treeIds: number[] = [];
export default function Role() {
const { confirm } = Modal;
const { RangePicker } = DatePicker;
//提示组件
const [messageApi, contextHolder] = message.useMessage();
//搜索框内所有内容
let [searchValue, setSearchValue] = useState<searchValueType>({
dateTime: undefined,
roleName: undefined,
roleKey: undefined,
startTime: undefined,
state: undefined,
endTime: undefined,
});
//树列表数据
const [menuTreeData, setMenuTreeData] = useState([]);
//父子联动
const [checkStrictly, setCheckStrictly] = useState(false);
//树所有节点IDs
//树是否自动展开
const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
const [checkedKeys, setCheckedKeys] = useState<React.Key[]>([]);
const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
//Modal
const [isModalOpen, setIsModalOpen] = useState(false);
const [modalTitle, setModalTitle] = useState("");
//表单区域
const [form] = Form.useForm();
//serach
const [formSearch] = Form.useForm();
//当前页面页数
let [count, setCount] = useState(1);
//表格内数据
let [tableData, setTableData] = useState<TableDataType[]>([]);
//表格数据总条数
let [total, setTotal] = useState<number>(0);
//表格格式
const columns: ColumnsType<TableDataType> = [
{
title: "序号",
dataIndex: "key",
key: "key",
},
{
title: "角色名称",
dataIndex: "roleName",
key: "roleName",
},
{
title: "角色权限",
dataIndex: "roleKey",
key: "roleKey",
},
{
title: "数据范围",
key: "dataScope",
dataIndex: "dataScope",
render: (text) => {
switch (text) {
case "1":
return <></>;
case "2":
return <></>;
case "3":
return <></>;
default:
return <></>;
}
},
},
{
title: "显示顺序",
key: "roleSort",
dataIndex: "roleSort",
},
{
title: "状态",
key: "state",
dataIndex: "state",
render: (text) => (
<>
{text === "0" ? (
<Tag color="success"></Tag>
) : (
<Tag color="error"></Tag>
)}
</>
),
},
{
title: "创建时间",
key: "createTime",
dataIndex: "createTime",
},
{
title: "操作",
key: "",
dataIndex: "",
render: (text) => (
<>
<Button type="link" onClick={() => handleEdit(text)}>
{"修改"}
</Button>
{/* <Button type='link' danger onClick={() => handleClickDel(text)}>{'删除'}</Button> */}
<Button type="link" danger onClick={() => handleDelete(text)}>
{"删除"}
</Button>
<Button type="link">{"分配用户"}</Button>
</>
),
},
];
//请求表格内容参数
let [queryTableDataParams, setQueryTableDataParams] = useState<any>({
roleKey: undefined,
roleName: undefined,
state: undefined,
endTime: undefined,
startTime: undefined,
pageNum: undefined,
pageSize: undefined,
});
const [allChecked, setAllChecked] = useState(false);
const onTreeExpand = (expandedKeysValue: React.Key[]) => {
// console.log("onExpand", expandedKeysValue);
setExpandedKeys(expandedKeysValue);
};
const onCheckExpand = (e: CheckboxChangeEvent) => {
console.log(`checked = ${e.target.checked}`);
console.log(treeIds);
if (e.target.checked) setExpandedKeys(treeIds);
else setExpandedKeys([]);
console.log(expandedKeys);
};
const onCheckAll = (e: CheckboxChangeEvent) => {
console.log(`checked = ${e.target.checked}`);
setAllChecked(!allChecked);
if (!allChecked) setCheckedKeys(treeIds);
else setCheckedKeys([]);
};
const onCheckFaSon = (e: CheckboxChangeEvent) => {
console.log(`checked = ${e.target.checked}`);
setCheckStrictly(!e.target.checked);
};
const onTreeCheck = (checkedKeysValue: any) => {
// console.log("onCheck", checkedKeysValue.checked);
console.log("onCheck", checkedKeysValue);
console.log("treeIds", treeIds);
if (checkedKeysValue.length != treeIds.length) {
setAllChecked(false);
} else {
setAllChecked(true);
}
if (checkStrictly === false) {
form.setFieldsValue({ menuIds: checkedKeysValue });
setCheckedKeys(checkedKeysValue);
} else {
form.setFieldsValue({ menuIds: checkedKeysValue.checked });
setCheckedKeys(checkedKeysValue.checked);
}
};
const onTreeSelect = (selectedKeysValue: React.Key[], info: any) => {
console.log("onSelect", info);
// setExpandedKeys([...expandedKeys,...selectedKeysValue])
setSelectedKeys(selectedKeysValue);
};
//当前角色的数据
// let thisrole: any = {roleId:'s'};
const handleEdit = async (role: any) => {
await getRoleData(role);
setModalTitle("修改角色");
// setCheckedKeys(role)
setIsModalOpen(true);
};
const handleDelete = (role: any) => {
console.log(role);
confirm({
title: "系统提示",
icon: <ExclamationCircleFilled />,
content: `确定删除角色名称为${role.roleName}的数据吗`,
okText: "确定",
okType: "danger",
cancelText: "取消",
onOk() {
handleClickDel(role);
},
onCancel() {
console.log("Cancel");
},
});
};
const handleSerach = () => {
searchValue = formSearch.getFieldsValue();
if (typeof searchValue.dateTime !== "undefined") {
searchValue.startTime = (searchValue.dateTime as string[])[0];
searchValue.endTime = (searchValue.dateTime as string[])[1];
}
setSearchValue(searchValue);
count = 1;
setQueryTableDataParams({ ...searchValue });
};
const handleReset = () => {
formSearch.resetFields();
searchValue = formSearch.getFieldsValue();
setSearchValue(searchValue);
setQueryTableDataParams({ ...searchValue });
// setSearchValue({ ...searchValue });
// setCount(1)
};
//Modal区域
const handleModalOk = () => {
form
.validateFields()
.then((values) => {
// form.resetFields();
console.log("add", values);
if (modalTitle == "新增角色") {
postAdd({ ...values, menuIds: checkedKeys });
} else if (modalTitle == "修改角色") {
console.log(thisrole);
console.log(checkedKeys);
console.log("now", { ...thisrole, ...values, menuIds: checkedKeys });
// console.log({ ...thisrole, ...values,menuIds:setCheckedKeys });
thisrole = { ...thisrole, ...values, menuIds: checkedKeys };
editRoleData({ ...thisrole });
}
})
.catch((info) => {
console.log("Validate Failed:", info);
});
console.log("modal thisrole", thisrole);
};
const handleModalCanle = () => {
setIsModalOpen(false);
};
//新增
const handleNewAdd = () => {
setModalTitle("新增角色");
form.setFieldsValue({
roleName: "",
roleKey: "",
state: "0",
dataScope: "1",
roleSort: "0",
});
setCheckedKeys([]);
setIsModalOpen(true);
};
const onDateChange = (
valueDate: DatePickerProps["value"] | RangePickerProps["value"],
dateString: [string, string] | string
) => {
// setSelectedDate(valueDate)
console.log(valueDate);
searchValue.startTime = dateString[0];
searchValue.endTime = dateString[1];
formSearch.setFieldsValue({ dateTime: [dateString[0], dateString[1]] });
setSearchValue(searchValue);
// setSearchValue({ ...searchValue })
};
const filterOption = (
input: string,
option?: { label: string; value: string }
) => (option?.label ?? "").toLowerCase().includes(input.toLowerCase());
//表格函数
//从服务器获取数据
//页码改变
const pageChange = (page: number, pageSize: number) => {
console.log(page, pageSize);
queryTableDataParams = { ...queryTableDataParams, pageNum: page, pageSize };
// setQueryParams({...queryParams,pageNum:page,pageSize})
console.log(queryTableDataParams);
getRolesData(queryTableDataParams);
setCount(page);
};
//删除单项
const handleClickDel = (role: TableDataType) => {
console.log(role);
let { roleId } = role;
del(roleId);
};
//遍历菜单树获取所有节点ID
const getTreeIds = function (tree: any) {
// console.log('Ids:',tree);
tree.forEach((item: any) => {
// console.log(item);
treeIds.push(item.menuId);
if (item.children != null) getTreeIds(item.children);
});
};
//获取单个角色详细信息
const getRoleData = async (role: any) => {
// const {roleId,roleKey,roleName,roleSort,dataScope,state,meunIds}=role
// thisrole=role
try {
let { code, data } = await getRoleAPI(role);
if (code === 1000) {
console.log("role:", data);
thisrole = data;
console.log("thisrole", thisrole);
form.setFieldsValue(thisrole);
setCheckedKeys(data.menuIds);
}
} catch (error) {
console.log(error);
}
// setOpen(true);
};
//获取菜单权限树
const getMenuList = async () => {
try {
let menul = await getMenuLiseAPI();
console.log("tree", menul.data);
if (treeIds.length == 0) getTreeIds(menul.data);
console.log(treeIds);
setMenuTreeData(menul.data);
// treeData = menul.data
// setMenulist(menul.data)
} catch (error) {
console.log(error);
}
};
//新增请求
const postAdd = async (value: any) => {
try {
let { code } = await addRoleAPI(value);
console.log(code);
if (code === 1000) {
console.log("success");
messageApi.open({
type: "success",
content: "操作成功",
});
form.setFieldsValue({
roleName: "",
roleKey: "",
state: "0",
dataScope: "1",
});
getRolesData({ ...queryTableDataParams, pageNum: count });
setIsModalOpen(false);
} else {
messageApi.open({
type: "error",
content: "角色名称已存在",
});
}
} catch (error) {}
};
const getRolesData = async (queryTableDataParams: any) => {
console.log("参数:", queryTableDataParams);
try {
const { code, data } = await getRolesDataAPI(queryTableDataParams);
if (code === 1000) {
const sortData = data.rows.sort(
(a: TableDataType, b: TableDataType) =>
parseInt(a.roleSort) - parseInt(b.roleSort)
);
sortData.forEach((element: TableDataType, i: number) => {
element.key = i + 1;
});
setTableData(sortData);
setTotal(data.total);
}
} catch (err: any) {
console.log("555", err);
}
};
//服务器删除角色
const del = async (roleId: number) => {
try {
let { code } = await delRoleAPI({ roleId });
if (code === 1000) {
console.log("del", roleId);
messageApi.open({
type: "success",
content: "操作成功",
});
getRolesData({ pageNum: count });
}
} catch (error) {
console.log(error);
}
};
//修改角色信息
const editRoleData = async (role: any) => {
console.log(role);
try {
let { code, data } = await setRoleDataAPI(thisrole);
// let a = await setRoleDataAPI(role);
if (code === 1000) {
thisrole = { ...thisrole, ...data };
getRolesData({ ...queryTableDataParams, pageNum: count });
messageApi.open({
type: "success",
content: "操作成功",
});
setIsModalOpen(false);
form.setFieldsValue({
roleName: "",
roleKey: "",
state: "0",
dataScope: "1",
});
} else {
messageApi.open({
type: "error",
content: "角色名称已存在!",
});
}
} catch (error) {
messageApi.open({
type: "error",
content: "系统未知错误",
});
console.log(error);
}
};
useEffect(() => {
// setQueryParams({...queryParams,...valueSch})
queryTableDataParams = {
...queryTableDataParams,
// ...searchValue,
pageNum: count,
};
getRolesData(queryTableDataParams);
// console.log(queryParams);
}, [queryTableDataParams]);
useEffect(() => {
getMenuList();
}, []);
return (
<ConfigProvider locale={zh_CN}>
<div className="roleBox">
<Form
layout="inline"
initialValues={undefined}
form={formSearch}
onFinish={handleSerach}
style={{ fontWeight: "700" }}
>
<Form.Item
label="角色名称"
name="roleName"
style={{ width: 300 + "px", marginTop: "10px" }}
>
<Input placeholder="请输入角色名称" allowClear />
</Form.Item>
<Form.Item
label="权限字符"
name="roleKey"
style={{ width: 300 + "px", marginTop: "10px" }}
>
<Input allowClear placeholder="请输入权限字符" />
</Form.Item>
<Form.Item
label="状态:"
name="state"
wrapperCol={{ span: 22 }}
style={{ marginTop: "10px" }}
>
<Select
style={{ width: 300 + "px", textAlign: "left" }}
allowClear
showSearch
placeholder="请选择角色状态"
optionFilterProp="lable"
// onChange={onStateChange}
// onSearch={onSearch}
filterOption={filterOption}
// value={searchValue.state}
options={[
{
value: "0",
label: "正常",
},
{
value: "1",
label: "停用",
},
]}
/>
</Form.Item>
<Form.Item
label="登陆时间"
name="dateTime"
style={{ marginTop: "10px" }}
>
<Space direction="vertical" style={{ width: 400 + "px" }}>
<RangePicker
locale={dataLocale}
showTime
format="YYYY-MM-DD HH:mm:ss"
onChange={onDateChange}
/>
</Space>
</Form.Item>
<Form.Item style={{ marginTop: "10px" }}>
<Button
type="primary"
htmlType="submit"
style={{ marginLeft: 20 + "px" }}
onClick={() => handleSerach()}
>
<SearchOutlined />
</Button>
</Form.Item>
<Form.Item style={{ marginTop: "10px" }}>
<Button onClick={() => handleReset()}>
<SyncOutlined />
</Button>
</Form.Item>
</Form>
{/* 新增 */}
<div className="newadd">
<Button type="primary" onClick={handleNewAdd}>
+
</Button>
</div>
{/* 弹出 */}
<Modal
open={isModalOpen}
title={modalTitle}
okText="确定"
cancelText="取消"
onCancel={handleModalCanle}
onOk={handleModalOk}
>
<Form
form={form}
layout="horizontal"
name="form_in_modal"
initialValues={{ dataScope: "1", state: "0" }}
>
<Form.Item
name="roleName"
label="角色名称"
rules={[{ required: true, message: "请输入角色名称" }]}
>
<Input placeholder="请输入角色名称" />
</Form.Item>
<Form.Item
name="roleKey"
label="角色权限"
rules={[{ required: true, message: "请输入角色权限" }]}
>
<Input placeholder="请输入角色权限" />
</Form.Item>
<Form.Item
required
name="roleSort"
label="显示顺序"
rules={[{ required: true, message: "请输入角色显示顺序" }]}
>
<InputNumber min={0} max={10} controls={true} />
</Form.Item>
<Form.Item name="dataScope" label="数据范围">
<Radio.Group>
<Radio value="1" defaultChecked={true}>
</Radio>
<Radio value="2"></Radio>
<Radio value="3"></Radio>
<Radio value="4"></Radio>
</Radio.Group>
</Form.Item>
<Form.Item
name="state"
label="状态"
className="collection-create-form_last-form-item"
>
<Radio.Group>
<Radio defaultChecked={true} value="0">
</Radio>
<Radio value="1"></Radio>
</Radio.Group>
</Form.Item>
<Form.Item
name="menuIds"
label="菜单权限"
className="collection-create-form_last-form-item"
>
{/* <input type="text" /> */}
<div className="checkBox">
<Checkbox onChange={onCheckExpand}></Checkbox>
<Checkbox onChange={onCheckAll} checked={allChecked}>
</Checkbox>
<Checkbox onChange={onCheckFaSon}></Checkbox>
</div>
<div
className="myTree"
style={{ maxHeight: "250px", overflowY: "auto" }}
>
<Tree
fieldNames={fieldNames}
checkable
onExpand={onTreeExpand}
expandedKeys={expandedKeys}
autoExpandParent={true}
onCheck={onTreeCheck}
checkedKeys={checkedKeys}
checkStrictly={checkStrictly}
onSelect={onTreeSelect}
selectedKeys={selectedKeys}
treeData={menuTreeData}
/>
</div>
</Form.Item>
</Form>
</Modal>
{/* 表格 */}
<div className="tablebox">
{contextHolder}
<Table columns={columns} dataSource={tableData} pagination={false} />
<Pagination
style={{
float: "right",
marginTop: "10px",
}}
total={total}
current={count}
showSizeChanger
showQuickJumper
onChange={(page, pageSize) => pageChange(page, pageSize)}
showTotal={(total) => `${total}`}
/>
</div>
</div>
</ConfigProvider>
);
}

View File

@@ -1,104 +0,0 @@
#content {
display: flex;
border-top: 1px solid black;
.dept-content {
flex: 20%;
padding: 35px 12px 0 0;
height: calc(100vh - 85px);
}
.left-dept {
flex: 20%;
padding: 35px 12px 0 0;
height: calc(100vh - 85px);
border: 1px solid red;
border-top: 1px solid black;
}
.right-user {
flex: 80%;
height: 190px;
display: flex;
flex-direction: column;
.search-content {
display: flex;
flex-direction: column;
padding: 35px 12px 0 0;
.content-top {
display: flex;
.input-item {
display: flex;
align-items: center;
margin-right: 20px;
width: 270px;
div {
width: 120px;
font-weight: bold;
}
}
:nth-child(3) {
div {
margin-right: -30px;
}
}
}
.content-bottom {
display: flex;
margin-left: -20px;
margin-top: 20px;
div {
margin-right: 10px;
}
.time-selector {
display: flex;
align-items: center;
div {
width: 120px;
font-weight: bold;
}
.time-picker {
width: 400px;
text-align: center;
margin-left: -30px;
margin-right: 25px;
}
}
button:focus,
button:focus-visible {
outline: none;
}
}
}
.table-content {
margin: 12px 0 0 12px;
.ant-table-thead > tr > th {
color: #909399;
text-align: center;
}
.ant-table-tbody > tr > td {
text-align: center;
}
}
.add-content {
display: flex;
margin-left: 12px;
margin-top: 20px;
button:focus,
button:focus-visible {
outline: none;
}
}
.user-mid-button {
display: flex;
margin-left: 12px;
margin-top: 20px;
button:focus,
button:focus-visible {
outline: none;
}
}
}
}

View File

@@ -1,807 +1,7 @@
import "./index.scss";
import {
Input,
Tree,
Select,
DatePicker,
Button,
Table,
Space,
Tag,
message,
Modal,
Form,
Row,
Col,
TreeSelect,
Radio,
} from "antd";
import {
EditOutlined,
DeleteOutlined,
ExclamationCircleFilled,
} from "@ant-design/icons";
import {
getUserListApi,
deleteUserApi,
getDeptTreeApi,
addUserApi,
getRoleListApi,
getUserInfoApi,
editUserApi,
} from "../../../api/system/users";
import dataLocale from "antd/es/date-picker/locale/zh_CN";
import React, { useEffect, useState, useMemo } from "react";
import { SearchOutlined, PlusOutlined } from "@ant-design/icons";
export default function User() {
const postIdList: number[] = [];
const [form] = Form.useForm();
const [searchForm] = Form.useForm();
const [echoId, setEchoId] = useState<any>();
const [myTreeData, setMyTreeData] = useState<[]>([]);
const [listData, setListData] = useState([]);
const [radioValue, setRadioValue] = useState(1);
const [searchTreeValue, setSearchTreeValue] = useState("");
const [roleList, setRoleList] = useState<any[]>([]);
const [messageApi, contextHolder] = message.useMessage();
const [modalTitle, setModalTitle] = useState<string>("");
const [buttonType, setButtonType] = useState<string>("");
const [isShowModal, setIsShowModal] = useState<boolean>(false);
const [autoExpandParent, setAutoExpandParent] = useState(true);
const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([
100, 102, 101, 104,
]);
const [treeValue, setTreeValue] = useState<string>();
const fieldNames = {
label: "deptName",
title: "deptName",
value: "deptId",
key: "deptName",
};
const [queryParams, setQueryParams] = useState<QueryParamsType>({
deptId: undefined,
userName: undefined,
phoneNumber: undefined,
state: undefined,
startTime: undefined,
endTime: undefined,
pageNum: undefined,
pageSize: undefined,
});
const columns = [
{
title: "序号",
dataIndex: "userId",
key: "Id",
render: (text: string) => <>{text ? text : "null"}</>,
},
{
title: "用户名称",
dataIndex: "userName",
key: "userName",
render: (text: string) => <>{text ? text : "null"}</>,
},
{
title: "用户昵称",
dataIndex: "nickName",
key: "nikeName",
render: (text: string) => <>{text ? text : "null"}</>,
},
{
title: "部门",
key: "deptId",
dataIndex: "deptName",
render: (text: string) => <>{text ? text : "--"}</>,
},
{
title: "手机号码",
key: "phoneNumber",
dataIndex: "phoneNumber",
render: (text: string) => <>{text ? text : "--"}</>,
},
{
title: "状态",
key: "state",
dataIndex: "state",
render: (text: string) => (
<>
{text === "0" ? (
<Tag color="processing"></Tag>
) : (
<Tag color="processing"></Tag>
)}
</>
),
},
{
title: "创建时间",
key: "createTime",
dataIndex: "createTime",
render: (text: string) => <>{text ? text : "null"}</>,
},
{
title: "操作",
key: "operate",
dataIndex: "operate",
render: (_: string, record: object) => (
<div style={{ color: "#58aaff" }}>
<Space>
<EditOutlined />
<a
href="#"
onClick={() => handleEdit(record)}
style={{ color: " #58aaff" }}
>
</a>
<DeleteOutlined />
<a
href="#"
onClick={() => handleDel(record)}
style={{ color: " #58aaff" }}
>
</a>
</Space>
</div>
),
},
];
interface AddUserType {
email: string;
nickName: string;
password: string;
phoneNumber: string;
postIds: number[];
roleIds: number[];
sex: string;
state: string;
userName: string;
}
interface QueryParamsType {
deptId?: number;
userName?: string;
phoneNumber?: string;
state?: string;
startTime?: string | any;
endTime?: string | any;
pageNum?: number;
pageSize?: number;
}
let addUserParams: AddUserType = {
email: "",
nickName: "",
password: "",
phoneNumber: "",
postIds: [],
roleIds: [],
sex: "",
state: "",
userName: "",
};
const getDeptTreeData = async () => {
try {
const { code, data } = await getDeptTreeApi();
if (code === 1000) {
setMyTreeData(data);
handleLoopPostList(data);
setExpandedKeys(postIdList);
}
} catch (error) {
console.error(error);
}
};
const getUserList = async (newQueryParams: object) => {
try {
const { code, data } = await getUserListApi(newQueryParams);
if (code === 1000) {
setListData(data.rows);
}
} catch (err) {
console.error(err);
}
};
const getUserInfo = async () => {
try {
const { code, data } = await getUserInfoApi(echoId);
if (code === 1000) {
handleEcho(data);
}
} catch (error) {
console.error(error);
}
};
const getRoleList = async () => {
try {
const { code, data } = await getRoleListApi();
if (code === 1000) {
setRoleList(data.rows);
}
} catch (err) {
console.log(err);
}
};
const handleAdd = () => {
setModalTitle("新增用户");
setButtonType("ADD");
setIsShowModal(true);
};
const handleEdit = (echoData: any) => {
setModalTitle("修改用户");
setButtonType("EDIT");
setIsShowModal(true);
setEchoId(echoData.userId);
};
const handleConfirm = () => {
form.validateFields().then((values) => {
Object.keys(values).forEach(
(key) => values[key] === undefined && delete values[key]
);
addUserParams = {
...addUserParams,
...values,
userId: echoId,
};
if (buttonType === "ADD") {
handleAddUser();
} else if (buttonType === "EDIT") {
handleEditUser();
} else {
messageApi.open({
type: "error",
content: "系统异常,请刷新后重试",
});
}
});
};
const handleAddUser = async () => {
const { code } = await addUserApi(addUserParams);
try {
if (code === 1000) {
messageApi.open({
type: "success",
content: "创建成功",
});
setQueryParams({});
handleClear();
} else {
messageApi.open({
type: "error",
content: "用户名已经存在",
});
}
} catch (err) {
console.log(err);
}
};
const handleEditUser = async () => {
const { code } = await editUserApi(addUserParams);
try {
if (code === 1000) {
messageApi.open({
type: "success",
content: "修改成功",
});
setQueryParams({});
handleClear();
} else {
messageApi.open({
type: "error",
content: "修改失败",
});
}
} catch (err) {
console.log(err);
}
};
const handleReset = async () => {
searchForm.resetFields();
setQueryParams({});
getUserList({});
};
const handleSearch = () => {
getUserList(queryParams);
};
const handleDel = async (record: any) => {
Modal.confirm({
title: `确定删除Id为-${record.userId}-, 用户名为-${record.userName}-的用户吗?`,
icon: <ExclamationCircleFilled />,
async onOk() {
const { code } = await deleteUserApi(record.userId);
try {
if (code === 1000) {
messageApi.open({
type: "success",
content: "删除成功",
});
setQueryParams({});
} else {
messageApi.open({
type: "error",
content: "删除失败",
});
}
} catch (err) {
console.log(err);
}
},
onCancel() {
messageApi.open({
type: "warning",
content: "取消成功",
});
},
});
};
const handleTimePikerValue = (_: any, dates: string[]) => {
setQueryParams({
...queryParams,
startTime: dates[0],
endTime: dates[1],
});
searchForm.setFieldsValue({ dataTime: [dates[0], dates[1]] });
};
const handleSearchValues = (e: any) => {
const { name, value } = e.target;
setQueryParams({ ...queryParams, [name]: value });
};
const handlePageChange = (page: number) => {
setQueryParams({
...queryParams,
pageNum: page,
});
};
const handleTreeSelect = (deptId: any) => {
console.log(queryParams);
getUserList({
...queryParams,
deptId: deptId[0],
});
};
const handleEcho = (data: any) => {
const { userName, nickName, sex, state, phoneNumber, deptId, email } =
data.user;
const { postIds, roleIds } = data;
form.setFieldsValue({
userName,
nickName,
state,
phoneNumber,
sex,
deptId,
email,
postIds,
roleIds,
});
};
const handleCancel = () => {
handleClear();
};
const handleClear = () => {
form.resetFields();
setIsShowModal(false);
};
const handleExpandKeys = (key: string, data: object[]) => {
const filterRes = new RegExp(key, "i");
data.forEach((item: any) => {
if (filterRes.test(item?.title?.props?.children)) {
postIdList.push(item.key);
}
item.children ? handleExpandKeys(key, item.children) : "";
});
};
const handleLoopPostList = (loopData: object[]) => {
loopData.forEach((item: any) => {
if (item?.deptId) {
const flag = postIdList.some((someItem) => {
someItem === item.deptId;
});
if (!flag) {
postIdList.push(item.deptId);
}
}
item.children ? handleLoopPostList(item.children) : "";
});
};
const onRadio = (e: any) => {
setRadioValue(e.target.value);
};
const onTreeSelect = (newValue: string) => {
setTreeValue(newValue);
};
const onTreeSearch = (e?: any) => {
const { value } = e.target ? e.target : null;
setSearchTreeValue(value);
handleExpandKeys(value, treeData);
setExpandedKeys(postIdList);
setAutoExpandParent(true);
};
const onExpand = (newExpandedKeys: React.Key[]) => {
console.log(newExpandedKeys);
setExpandedKeys(newExpandedKeys);
setAutoExpandParent(false);
};
const treeData = useMemo(() => {
const loop = (data: any[]): any[] =>
data.map((item) => {
const strTitle = item.deptName as string;
const index = strTitle.indexOf(searchTreeValue);
const beforeStr = strTitle.substring(0, index);
const afterStr = strTitle.slice(index + searchTreeValue.length);
const title =
index > -1 ? (
<span>
{beforeStr}
<span className="site-tree-search-value">{searchTreeValue}</span>
{afterStr}
</span>
) : (
<span>{strTitle}</span>
);
if (item.children) {
return { title, key: item.deptId, children: loop(item.children) };
}
return {
title,
key: item.deptId,
};
});
return loop(myTreeData);
}, [myTreeData]);
useEffect(() => {
getDeptTreeData();
getRoleList();
getUserInfo();
}, [echoId]);
useEffect(() => {
getUserList({});
}, []);
return (
<div id="content">
<div className="dept-content">
<Input
allowClear
style={{ marginBottom: 8 }}
prefix={<SearchOutlined />}
placeholder="请输入部门名称"
onChange={onTreeSearch}
/>
<Tree
onExpand={onExpand}
defaultExpandAll={true}
expandedKeys={expandedKeys}
autoExpandParent={autoExpandParent}
treeData={treeData}
onSelect={handleTreeSelect}
/>
</div>
<>
<div className="right-user">
<Form
layout="inline"
form={searchForm}
onFinish={handleSearch}
style={{ fontWeight: "700", marginLeft: 12, marginTop: 23 }}
>
<Form.Item
label="用户名称"
name="userName"
style={{ width: 300 + "px", marginTop: "10px" }}
>
<Input
placeholder="请输入用户名称"
name="userName"
allowClear
value={queryParams.userName}
onChange={handleSearchValues}
/>
</Form.Item>
<Form.Item
label="手机号码"
name="phoneNumber"
style={{ width: 300 + "px", marginTop: "10px" }}
>
<Input
placeholder="请输入手机号码"
name="phoneNumber"
allowClear
value={queryParams.phoneNumber}
onChange={handleSearchValues}
/>
</Form.Item>
<Form.Item label="状态" name="state" style={{ marginTop: "10px" }}>
<Select
style={{ width: 250 }}
placeholder="用户状态"
allowClear
options={[
{ value: "1", label: "正常" },
{ value: "0", label: "停用" },
]}
value={queryParams.state}
onChange={(value: any) =>
setQueryParams({
...queryParams,
state: value,
})
}
/>
</Form.Item>
<Form.Item
label="创建时间"
name="dateTime"
style={{ marginTop: "10px" }}
>
<DatePicker.RangePicker
locale={dataLocale}
showTime
format="YYYY-MM-DD HH:mm:ss"
onChange={handleTimePikerValue}
/>
</Form.Item>
<Form.Item style={{ marginTop: "10px" }}>
<Button
type="primary"
htmlType="submit"
style={{ marginLeft: 20 + "px" }}
>
</Button>
</Form.Item>
<Form.Item style={{ marginTop: "10px" }}>
<Button onClick={handleReset}></Button>
</Form.Item>
</Form>
<div className="add-content">
<>
<Button type="primary" onClick={handleAdd}>
<PlusOutlined />
</Button>
</>
</div>
<div className="table-content">
<>
{contextHolder}
<Table
columns={columns}
dataSource={listData}
className="article-table"
pagination={{
onChange: handlePageChange,
locale: {
jump_to: "跳至",
page: "页",
},
showQuickJumper: true,
showTotal: (total, range) =>
`${range[0]}-${range[1]} 条,共 ${total}`,
}}
/>
</>
</div>
<>
{contextHolder}
<Modal
title={modalTitle}
width={700}
okText="确认"
cancelText="取消"
open={isShowModal}
onOk={handleConfirm}
onCancel={handleCancel}
>
<Form
form={form}
name="basic"
initialValues={{ remember: true }}
labelCol={{ span: 6 }}
onFinish={handleConfirm}
autoComplete="off"
className="modal-form"
>
<Row>
<Col span={12}>
<Form.Item
label="用户名称"
name="userName"
rules={[{ required: true, message: "请输入用户名称" }]}
>
<Input defaultValue={""} placeholder="请输入用户名称" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="用户昵称"
name="nickName"
rules={[{ required: true, message: "请输入用户昵称" }]}
>
<Input defaultValue={""} placeholder="请输入用户昵称" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="用户性别"
name="sex"
rules={[{ required: false }]}
>
<Select
placeholder="请选择用户性别"
options={[
{ value: "0", label: "男" },
{ value: "1", label: "女" },
{ value: "2", label: "未知" },
]}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="用户密码"
name="password"
rules={[{ required: true, message: "请输入用户密码" }]}
>
<Input.Password
defaultValue={""}
placeholder="请输入密码"
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="归属部门"
name="deptId"
rules={[{ required: false }]}
>
<TreeSelect
showSearch
style={{ width: "100%" }}
value={treeValue}
dropdownStyle={{ maxHeight: 400, overflow: "auto" }}
placeholder="请选择"
allowClear
fieldNames={fieldNames}
treeDefaultExpandAll
onChange={onTreeSelect}
treeData={myTreeData}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="手机号码"
name="phoneNumber"
rules={[{ required: false }]}
>
<Input placeholder="请输入手机号码" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="邮箱"
name="email"
rules={[{ required: false }]}
>
<Input defaultValue={""} placeholder="请输入邮箱" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="状态"
name="state"
rules={[
{
required: false,
message: "Please input your password!",
},
]}
>
<Radio.Group onChange={onRadio} value={radioValue}>
<Radio value="1"></Radio>
<Radio value="0"></Radio>
</Radio.Group>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="岗位"
name="postIds"
rules={[
{
required: false,
message: "Please input your password!",
},
]}
>
<Select
mode="multiple"
defaultValue={[]}
options={[
{ value: "董事长", label: "董事长" },
{ value: "项目经理", label: "项目经理" },
{ value: "人力资源", label: "人力资源" },
{ value: "普通员工", label: "普通员工" },
]}
placeholder="请选择岗位"
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="角色"
name="roleIds"
rules={[
{
required: false,
message: "Please input your password!",
},
]}
>
<Select mode="multiple" placeholder="请选择角色">
{roleList.map((item) => (
<Select.Option key={item.roleId} value={item.roleId}>
{item.roleName}
</Select.Option>
))}
</Select>
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
label="备注"
labelCol={{ span: 3 }}
rules={[
{
required: false,
message: "Please input your password!",
},
]}
>
<Input.TextArea placeholder="请输入内容" />
</Form.Item>
</Col>
</Row>
</Form>
</Modal>
</>
</div>
</>
</div>
);
}
return(
<div>user</div>
)
}