提交 d6f45940 作者: 龚洪江

Merge branch 'develop'

......@@ -6,17 +6,11 @@ COPY package.json .
COPY package-lock.json .
RUN npm ci
COPY . .
#EXPOSE 5173
#CMD ["npm", "run", "dev"]
#RUN \
# if [[ $PROFILES_ACTIVE=="development" ]]; then echo "env PROFILES_ACTIVE=development. exec npm run buildDev" && npm run buildDev; \
# else echo "env PROFILES_ACTIVE not found. exec npm run build" && npm run build; \
# fi
RUN \
if [ "${PROFILES_ACTIVE}" = "development" ]; then echo "env PROFILES_ACTIVE=development. exec npm run buildDev" && npm run buildDev; \
else echo "env PROFILES_ACTIVE !=development. exec npm run build" && npm run build; \
fi
RUN npm run build
# nginx
FROM nginx:alpine as production
......
#请求接口地址
VITE_REQUEST_BASE_URL='https://www.iuav.shop'
#VITE_REQUEST_BASE_URL='https://test.iuav.shop'
#VITE_REQUEST_BASE_URL='https://www.iuav.shop'
VITE_REQUEST_BASE_URL='https://test.iuav.shop'
#VITE_REQUEST_BASE_URL='/api'
#旧版接口地址
#VITE_REQUEST_BASE_URL='https://iuav.mmcuav.cn'
......
......@@ -14,4 +14,4 @@ patches:
images:
- name: REGISTRY/NAMESPACE/IMAGE:TAG
newName: mmc-registry.cn-shenzhen.cr.aliyuncs.com/sharefly-dev/admin
newTag: 3d01c556f245af2ef9ce589600a0c716b455c84c
newTag: 01280aac6badac09fd839261006483b7d09bb7d4
......@@ -3,7 +3,7 @@ kind: Deployment
metadata:
name: admin-deployment
spec:
replicas: 2
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
......
import './assets/style/App.scss';
import PrivateRouter from '~/router/privateRouter';
import { BrowserRouter } from 'react-router-dom';
const App = () => (
<>
<PrivateRouter />
<BrowserRouter>
<PrivateRouter />
</BrowserRouter>
</>
);
......
......@@ -24,6 +24,11 @@ export type BackEndLoginType = InterFunction<
phoneNum: string;
remark: string;
};
roleInfo: {
id: number;
roleName: string;
roleNo: string;
};
}
>;
// 上传图片
......
import { InterFunction, InterItemFunction } from '~/api/interface';
import { InterFunction, InterListFunction } from '~/api/interface';
//论坛-列表
export type forumListType = InterItemFunction<
export type forumListType = InterListFunction<
{ keyword?: string },
{
id: number;
description: string;
mediaVO: null;
show: number;
userBaseInfo: {
nickName: string;
userImg: string;
userName: null;
phone: string;
uid: string;
userImg: string;
userName: string;
};
show: number;
id: number;
}[]
userAccountId: number;
dynamicPublishTime: string;
checkStatus: 0 | 1 | 2;
}
>;
//论坛-删除
export type deleteForumType = InterFunction<{ dynamicId: number }, any>;
......@@ -44,3 +48,8 @@ export type likeUserInfoType = InterFunction<
{ dynamicId: number },
{ nickName: string; userImg: string; userName: string }[]
>;
// 论坛-审核
export type checkDynamicType = InterFunction<
{ dynamicId: number; status: number },
NonNullable<unknown>
>;
......@@ -45,6 +45,11 @@ export type listBAccountPageType = InterListFunction<
phoneNum: string;
remark: string;
};
roleInfoDTO: {
id: number;
roleName: string;
roleNo: string;
};
}
>;
// 账号-新增
......@@ -62,6 +67,8 @@ export type insertBAccountType = InterFunction<
provinceCode?: number;
remark?: string;
userName: string;
companyId: number;
roleId: number;
},
NonNullable<unknown>
>;
......
import {
checkDynamicType,
deleteForumType,
forumDetailType,
forumListType,
......@@ -23,4 +24,7 @@ export class ForumManageAPI {
// 论坛-点赞人信息
static getLikeUserInfoList: likeUserInfoType = (params) =>
axios.get('/release/backstage/forum/likeUserInfo', { params });
// 动态审核
static checkDynamic: checkDynamicType = (params) =>
axios.get('/release/backstage/forum/checkDynamic', { params });
}
......@@ -176,8 +176,7 @@ const AddOrEditSkuModal: React.FC<ModalProps & selfProps> = ({
setIsCustomProd(e.target.value === 1);
};
// // 清除表单
const onCancel = () => {
// 关闭前恢复初始值
const clearEvent = () => {
skuForm.resetFields();
selfProduct.resetFields();
setSelfProductData([
......@@ -195,6 +194,10 @@ const AddOrEditSkuModal: React.FC<ModalProps & selfProps> = ({
productSpecCPQVO: {},
});
setIsCustomProd(false);
};
const onCancel = () => {
// 关闭前恢复初始值
clearEvent();
handleCancel();
};
//获取产品列表
......@@ -335,7 +338,7 @@ const AddOrEditSkuModal: React.FC<ModalProps & selfProps> = ({
delProductSpecId: selfIds,
});
}
// onCancel();
clearEvent();
});
// 验证自定义表单
......
......@@ -16,7 +16,7 @@ interface selfProps {
deleteSku: (record: specEntity) => void;
isDetail: boolean;
}
//机构列表
const StockSku: React.FC<selfProps> = ({
addOrEditSku,
specData,
......
......@@ -5,6 +5,7 @@ import { RouteObjectType, routerList } from '~/router/router';
import { useLocation, useNavigate } from 'react-router-dom';
import { GetRouteByID, getRouteID, getRoutePid } from '~/utils/router';
import { useSelector } from 'react-redux';
import { authRouterList, routerItem } from '~/router';
type MenuItem = Required<MenuProps>['items'][number];
......@@ -30,11 +31,9 @@ export function MenuView() {
// 点击侧边栏事件 onSelect改为onClick
const onSelect: MenuProps['onClick'] = (keys) => {
setSelectedKeys([keys.key]);
// setSelectedKeys(keys.selectedKeys);
const id = Number(keys.key);
const current = GetRouteByID(id, routerList);
// console.log(current?.path);
if (current) navigate(current?.path);
const current: routerItem | undefined = GetRouteByID(id, routerList);
navigate({ pathname: current?.path });
};
// 递归将路由转换为侧边栏数据
const getItem = (routerList: RouteObjectType[]) => {
......@@ -61,7 +60,9 @@ export function MenuView() {
// 组件挂载
useEffect(() => {
// 设置侧边栏数据
setItems(getItem(routerList));
authRouterList().then((value) => {
setItems(getItem(value));
});
// 设置当前选中的项目
setOpenKeys([getRoutePid(routerList, location.pathname).toString()]);
// 设置当前选中的项目的subMenu
......@@ -84,13 +85,6 @@ export function MenuView() {
items={items}
style={{ backgroundColor: ' #F3F6FF ' }}
/>
{/* <div className="sider-collapsed" onClick={() => setCollapsed(!collapsed)}> */}
{/* <Button */}
{/* className="collapsed-icon" */}
{/* type="link" */}
{/* icon={collapsed ? <RightOutlined /> : <LeftOutlined />} */}
{/* /> */}
{/* </div> */}
</Sider>
);
}
......@@ -5,6 +5,7 @@ import { Button, Dropdown, MenuProps, Modal } from 'antd';
import Logo from '../../../assets/icon/logo_big.png';
import './index.scss';
import { REMOVE_MENU, REMOVE_MENU_ID, SET_COLLAPSE } from '~/store/module/menu';
import { REMOVE_ROLE_ID } from '~/store/module/userInfo';
import { useDispatch, useSelector } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import Cookies from 'js-cookie';
......@@ -41,6 +42,7 @@ export function TitleView() {
Cookies.remove('SHAREFLY-TOKEN');
dispatch(REMOVE_MENU());
dispatch(REMOVE_MENU_ID());
dispatch(REMOVE_ROLE_ID());
},
});
}}
......
......@@ -13,8 +13,6 @@ import { authRouterList } from '~/router';
// 请求的类型
type ReqType = InterReqType<BackEndLoginType>;
// 返回的类型
// type ResType = InterDataType<BackEndLoginType>;
function LoginView() {
// eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/ban-ts-comment
......@@ -39,21 +37,21 @@ function LoginView() {
Cookies.set('remember', String(values?.remember));
// 存用户信息
dispatch(SET_USERINFO(res.result));
// 获取用户的权限
await getFirstRoute();
// console.log('SXTB_TOKEN --->', Cookies.get('SXTB-TOKEN'));
localStorage.setItem('roleId', res.result.roleInfo.id.toString());
authRouterList().then((value: any) => {
if (value.length) {
navigate({ pathname: value[0].children.find((v: any) => !v.meta.hidden)?.path });
} else {
message.warning('请先配置权限');
}
//获取第一个路由
});
// 获取第一个路由
} else {
message.error('登录失败,请检查账号信息');
}
};
// 获取第一个路由
const getFirstRoute = () => {
// 获取可用的路由表
const routeList = authRouterList();
// 获取第一个路由
navigate(routeList[0]?.children?.[0]?.path);
// console.log('获取第一个路由--->', routeList[0]?.children?.[0]?.path);
};
// componentDidMount
useEffect(() => {
// 是否保存密码
......
......@@ -3,13 +3,20 @@ import { Button, message, Modal, Table, Tooltip } from 'antd';
import { ColumnsType } from 'antd/es/table';
import { useEffect, useState } from 'react';
import DynamicDetailModal from './components/dynamicDetailModal';
import { ForumManageAPI } from '../../../api';
import { InterDataType, InterReqListType, PaginationProps } from '../../../api/interface';
import { forumDetailType, forumListType } from '../../../api/interface/forumManageType';
import { ForumManageAPI } from '~/api';
import { InterDataType, InterListType, InterReqListType, PaginationProps } from '~/api/interface';
import { forumDetailType, forumListType } from '~/api/interface/forumManageType';
import './index.scss';
// 动态审核状态
const checkStatusList = [
{ label: '审核中', value: 0 },
{ label: '审核通过', value: 1 },
{ label: '审核不通过', value: 2 },
];
//论坛列表返回类型
type forumType = InterDataType<forumListType>['list'];
type forumType = InterListType<forumListType>;
//论坛列表参数类型
type forumParameters = InterReqListType<forumListType>;
//论坛详情返回类型
......@@ -44,6 +51,12 @@ const DynamicList = () => {
),
},
{
title: '审核状态',
align: 'center',
dataIndex: 'checkStatus',
render: (text: number) => checkStatusList.find((i) => i.value === text)?.label || text,
},
{
title: '用户UID',
align: 'center',
render: (_text: string, record) => <div>{record.userBaseInfo?.uid || ''}</div>,
......@@ -54,18 +67,41 @@ const DynamicList = () => {
render: (_text: string, record) => <div>{record.userBaseInfo?.phone || ''}</div>,
},
{
title: '发布时间',
align: 'center',
dataIndex: 'dynamicPublishTime',
},
{
title: '操作',
align: 'center',
fixed: 'right',
width: 180,
render: (_text: string, record) => (
<>
<Button
type='link'
onClick={() => handleCheckStatus(record)}
disabled={record.checkStatus !== 0}
>
审核
</Button>
<Button type='link' onClick={() => lookDynamicDetail(record)}>
查看详情
详情
</Button>
<Button type='link' onClick={() => deleteForumClick(record)}>
强制删除
<Button
type='link'
onClick={() => deleteForumClick(record)}
danger
disabled={record.checkStatus === 0}
>
删除
</Button>
<Button type='link' onClick={() => hiddenForumClick(record)}>
{record.show ? '恢复显示' : '强制隐藏'}
<Button
type='link'
onClick={() => hiddenForumClick(record)}
disabled={record.checkStatus === 0}
>
{record.show ? '显示' : '隐藏'}
</Button>
</>
),
......@@ -155,7 +191,30 @@ const DynamicList = () => {
}
});
};
// 是否确认审核
const handleCheckStatus = (record: forumType[0]) => {
Modal.confirm({
title: `确认审核`,
content: `请确认是否审核通过?通过后动态将展示在论坛列表`,
okText: '审核通过',
cancelText: '审核不通过',
onOk: async () => {
const res = await ForumManageAPI.checkDynamic({ dynamicId: record.id, status: 1 });
if (res && res.code === '200') {
message.success('操作成功');
paginationChange(pagination.pageNo, pagination.pageSize);
}
},
onCancel: async () => {
const res = await ForumManageAPI.checkDynamic({ dynamicId: record.id, status: 2 });
if (res && res.code === '200') {
message.success('操作成功');
paginationChange(pagination.pageNo, pagination.pageSize);
}
},
});
};
// 组件挂载
useEffect(() => {
getDynamicList();
}, []);
......@@ -163,6 +222,7 @@ const DynamicList = () => {
<div className='dynamic-list'>
<SearchBox search={searchColumnsData} searchData={searchSuccess} />
<Table
size={'small'}
bordered
columns={tableColumns}
dataSource={tableData}
......
......@@ -76,6 +76,7 @@ const GoodsAddOrEditOrDetail = () => {
};
const addOrEditSkuModalCancel = () => {
setAddOrEditSkuModalShow(false);
setCurtRowData({});
};
const addOrEditSkuModalOk = (data: specEntity) => {
if (Object.keys(curtRowData).length != 0) {
......@@ -85,7 +86,7 @@ const GoodsAddOrEditOrDetail = () => {
} else {
setSpecData([...specData, data]);
}
setAddOrEditSkuModalShow(false);
addOrEditSkuModalCancel();
};
//根据目录获取分类列表
const getCategoryList = (directoryId: number) => {
......
......@@ -77,6 +77,7 @@ const GoodsAddOrEditOrDetail = () => {
};
const addOrEditSkuModalCancel = () => {
setAddOrEditSkuModalShow(false);
setCurtRowData({});
};
const addOrEditSkuModalOk = (data: specEntity) => {
if (Object.keys(curtRowData).length != 0) {
......@@ -86,7 +87,7 @@ const GoodsAddOrEditOrDetail = () => {
} else {
setSpecData([...specData, data]);
}
setAddOrEditSkuModalShow(false);
addOrEditSkuModalCancel();
};
//根据目录获取分类列表
const getCategoryList = (directoryId: number) => {
......
import SearchBox, { searchColumns } from '~/components/search-box';
import { Table } from 'antd';
import { ColumnsType } from 'antd/es/table';
const PilotTrainingOrder = () => {
const search: searchColumns[] = [
{ label: '买家账号', placeholder: '请输入买家账号', name: '', type: 'input' },
{ label: '订单编号', placeholder: '请输入买家账号', name: '', type: 'input' },
];
const tableColumns: ColumnsType<any> = [
{
title: '序号',
align: 'center',
},
{
title: '机构名称',
align: 'center',
},
{
title: '商品名称',
align: 'center',
},
{
title: '商品图片',
align: 'center',
},
{
title: '订单金额',
align: 'center',
},
{
title: '买家信息',
align: 'center',
},
{
title: '订单状态',
align: 'center',
},
{
title: '订单编号',
align: 'center',
},
{
title: '备注',
align: 'center',
},
{
title: '操作',
align: 'center',
},
];
return (
<div className='pilot-train-order'>
<SearchBox search={search} />
<Table bordered columns={tableColumns} />
</div>
);
};
export default PilotTrainingOrder;
import { Button, Form, Input, Radio, Select } from 'antd';
import { Uploader } from '~/components/uploader';
import { EnvironmentOutlined, UploadOutlined } from '@ant-design/icons';
import './index.scss';
const BaseInfo = () => {
return (
<div className='base-info'>
<div className='base-info-header'>基本信息:</div>
<div className='base-info-form'>
<Form labelCol={{ span: 2 }} wrapperCol={{ span: 7 }}>
<Form.Item label='机构主图'>
<Uploader fileUpload listType='picture-card'>
<UploadOutlined />
</Uploader>
</Form.Item>
<Form.Item label='机构副图'>
<Uploader fileUpload listType='picture-card'>
<UploadOutlined />
</Uploader>
</Form.Item>
<Form.Item label='机构视频'>
<Uploader fileUpload listType='text'>
<Button icon={<UploadOutlined />} type='primary'>
上传视频
</Button>
</Uploader>
</Form.Item>
<Form.Item label='机构名称'>
<Input placeholder='请输入机构名称' />
</Form.Item>
<Form.Item label='机构地区'>
<Button icon={<EnvironmentOutlined />} type='primary'></Button>
</Form.Item>
<Form.Item label='考点机构'>
<Radio.Group>
<Radio value={1}></Radio>
<Radio value={0}></Radio>
</Radio.Group>
</Form.Item>
<Form.Item label='机构规模'>
<Select placeholder='请选择机构规模'>
<Select.Option>2-4名</Select.Option>
<Select.Option>4-6名</Select.Option>
<Select.Option>6-8名</Select.Option>
<Select.Option>10名以上</Select.Option>
</Select>
</Form.Item>
<Form.Item label='机构描述'>
<Input.TextArea placeholder='请选择机构描述' />
</Form.Item>
</Form>
</div>
</div>
);
};
export default BaseInfo;
const SkuInfo = () => {
return <div className='sku-info'></div>;
};
export default SkuInfo;
import BaseInfo from './components/baseInfo';
const AddOrEditInstitution = () => {
return (
<div className='institution-form'>
<BaseInfo />
</div>
);
};
export default AddOrEditInstitution;
import SearchBox, { searchColumns } from '~/components/search-box';
import { Button, Table } from 'antd';
import { ColumnsType } from 'antd/es/table';
import { PlusOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
const InstitutionsList = () => {
const navigate = useNavigate();
const search: searchColumns[] = [
{ label: '机构名称', name: '', placeholder: '请输入机构名称', type: 'input' },
{ label: '培训类型', name: '', placeholder: '请选择培训类型', type: 'select', options: [] },
{ label: '选择日期', name: '', placeholder: '请选择日期', type: 'rangePicker', options: [] },
];
const tableColumns: ColumnsType<any> = [
{
title: '序号',
align: 'center',
},
{
title: '机构名称',
align: 'center',
},
{
title: '培训类型',
align: 'center',
},
{
title: '创建日期',
align: 'center',
},
{
title: '操作',
align: 'center',
},
];
const toAddInstitutions = () => {
navigate('/pilotTraining/institutionsList/add');
};
return (
<div className='institutions-list'>
<SearchBox
search={search}
child={
<Button icon={<PlusOutlined />} type='primary' onClick={toAddInstitutions}>
新增
</Button>
}
/>
<Table bordered columns={tableColumns} />
</div>
);
};
export default InstitutionsList;
import SearchBox, { searchColumns } from '~/components/search-box';
import { Button, Table } from 'antd';
import { Button, Table, Image } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import { ColumnsType } from 'antd/es/table';
import { useState } from 'react';
import { useEffect, useState } from 'react';
import AddOrEditTagModal from './components/addOrEditTagModal';
import { InterDataType, InterReqType } from '~/api/interface';
import { cooperationListTag } from '~/api/interface/customManageType';
import { CustomManageAPI } from '~/api';
// 列表类型
type TableType = InterDataType<cooperationListTag>;
// 请求的参数
type ReqType = InterReqType<cooperationListTag>;
// 搜索表单的数据
let query: ReqType = {};
//行业新闻
const TagManage = () => {
const searchColumnsData: searchColumns[] = [
......@@ -18,31 +29,91 @@ const TagManage = () => {
{
title: '序号',
align: 'center',
render: (_text, _record, index) => (pagination.current - 1) * pagination.pageSize + index + 1,
},
{
title: '标签名称',
align: 'center',
dataIndex: 'tagName',
},
{
title: '标签描述',
align: 'center',
dataIndex: 'tagDescription',
width: '250px',
ellipsis: true,
},
{
title: '标签类型',
title: '标签需求',
align: 'center',
dataIndex: 'tagRequire',
width: '250px',
ellipsis: true,
},
{
title: '标签等级图标',
align: 'center',
dataIndex: 'tagImg',
render: (text) => <Image src={text} alt={'图标'} style={{ width: '32px', height: '32px' }} />,
},
{
title: '操作',
align: 'center',
fixed: 'right',
width: '100px',
render: () => (
<>
<Button type='link'>编辑</Button>
<Button type='link'>删除</Button>
<Button type='link' danger>
删除
</Button>
</>
),
},
];
const [tableData] = useState<any>([{ id: 1 }]);
// 表格数据
const [tableData, setTableData] = useState<TableType>([]);
// 表格分页配置
// eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/ban-ts-comment
// @ts-ignore
const [pagination, setPagination] = useState({
total: 0,
pageSize: 10,
current: 1,
totalPage: 0,
});
// 加载列表
const getTableList = async (value = {}) => {
// 只需要修改这个地方的接口即可
const res = await CustomManageAPI.cooperationListTag({
pageNo: pagination.current,
pageSize: pagination.pageSize,
...value,
...query,
});
if (res && res.code === '200') {
// const { list, pageNo, totalCount, pageSize, totalPage } = res.result; // 解构
// setPagination({
// total: totalCount,
// current: pageNo,
// pageSize,
// totalPage,
// });
setTableData(res.result);
}
};
// 翻页
// eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/ban-ts-comment
// @ts-ignore
const paginationChange = (pageNo: number, pageSize: number) => {
getTableList({ pageNo, pageSize }).then();
};
// 表单提交
const onFinish = (data: ReqType) => {
pagination.current = 1;
query = data;
getTableList(data).then();
};
const [addOrEditTagModalShow, setAddOrEditTagModalShow] = useState<boolean>(false);
const addOrEditTagClick = () => {
......@@ -51,6 +122,9 @@ const TagManage = () => {
const addOrEditTagModalCancel = () => {
setAddOrEditTagModalShow(false);
};
useEffect(() => {
getTableList().then();
}, []);
return (
<div className='tag-manage'>
<SearchBox
......@@ -60,8 +134,15 @@ const TagManage = () => {
新建
</Button>
}
searchData={onFinish}
/>
<Table bordered columns={tableColumns} dataSource={tableData} rowKey='id'></Table>
<Table
bordered
columns={tableColumns}
dataSource={tableData}
rowKey='id'
size={'small'}
></Table>
<AddOrEditTagModal open={addOrEditTagModalShow} onCancel={addOrEditTagModalCancel} />
</div>
);
......
......@@ -14,6 +14,7 @@ interface propType {
open: boolean;
closed: any;
data?: TableType[0];
roleList: { label: string; value: number }[];
}
const AddEditModal: React.FC<propType> = (props) => {
AddEditModal.defaultProps = {
......@@ -77,7 +78,8 @@ const AddEditModal: React.FC<propType> = (props) => {
if (!data) return;
form.setFieldsValue({
...data,
companyId: companyList.find((i) => i.label === data.companyName)?.value || undefined,
companyId: companyList.find((i) => i.label === data.companyName)?.value,
roleId: data.roleInfoDTO.id,
});
}, [companyList]);
return (
......@@ -147,7 +149,7 @@ const AddEditModal: React.FC<propType> = (props) => {
<Select
placeholder={'请选择角色'}
style={{ width: '168px' }}
options={[{ value: 1, label: '超级管理员' }]}
options={props.roleList}
/>
</Form.Item>
</Col>
......
......@@ -36,6 +36,8 @@ function AccountManageView() {
current: 1,
totalPage: 0,
});
//角色列表
const [roleList, setRoleList] = useState<{ label: string; value: number }[]>([]);
// 加载列表
const getTableList = async (value = {}) => {
// 只需要修改这个地方的接口即可
......@@ -87,10 +89,17 @@ function AccountManageView() {
const getEditAuth = (value: TableType[0]) => {
return value.companyInfoVO.id !== userInfo.companyInfoVO.id && userInfo.companyInfoVO.id !== 1;
};
//角色列表
const getRoleList = () => {
SystemManageAPI.getListRoleInfoPage({ pageNo: 1, pageSize: 9999 }).then(({ result }) => {
setRoleList((result.list || []).map((v) => ({ value: v.id, label: v.roleName })));
});
};
// componentDidMount
useEffect(() => {
query = {};
getTableList().then();
getRoleList();
}, []);
// 表格结构
const columns: ColumnsType<TableType[0]> = [
......@@ -126,9 +135,10 @@ function AccountManageView() {
title: '角色',
align: 'center',
width: '10%',
render: (_text: string, record) => <div>{record.roleInfoDTO.roleName}</div>,
},
{ title: '手机号', dataIndex: 'phoneNum', align: 'center', width: '150px' },
{ title: '邮箱', align: 'center', width: '12%', dataIndex: 'email' },
{ title: '邮箱', align: 'center', width: '18%', dataIndex: 'email' },
{
title: '备注',
align: 'center',
......@@ -217,7 +227,7 @@ function AccountManageView() {
name: 'roleId',
type: 'Select',
placeholder: '请选择账号角色',
options: [],
options: roleList,
},
{
label: '状态',
......@@ -271,6 +281,7 @@ function AccountManageView() {
setEditData(undefined);
paginationChange(pagination.current, pagination.pageSize);
}}
roleList={roleList}
/>
<ChangeModal
open={changeModalVisible}
......
......@@ -45,7 +45,7 @@ const LimitInfo = () => {
return data.reduce((pre: number[], cur) => {
pre.push(cur.id);
if (cur.children) {
pre.push(...getChildKeys(cur.children));
pre.push(...getAllKeys(cur.children));
}
return pre;
}, []);
......
import { createBrowserRouter, RouteObject } from 'react-router-dom';
import { RouteObjectType, routerList, whiteRouterList } from '~/router/router';
import { RouteObject } from 'react-router-dom';
import { RouteObjectType, routerList } from '~/router/router';
import { InterDataType } from '~/api/interface';
import { listMenuInfoType } from '~/api/interface/systemManageType';
import { SystemManageAPI } from '~/api';
//菜单类型
type menuType = InterDataType<listMenuInfoType>;
// 获取用户权限路由列表
export const authRouterList = () => {
// TODO: 获取用户权限
// 模拟获取用户权限成功
// 获取用户能使用的全部路由
// TODO: 在此处对用户权限进行判断,返回不同的路由表
// 获取用户可用路由列表
return [...routerList];
export const authRouterList = async () => {
if (localStorage.getItem('roleId')) {
const { result } = await SystemManageAPI.getListRoleMenuInfo({
roleId: Number(localStorage.getItem('roleId')),
});
const ids: number[] = getAllKeys([result]);
const getRouteList = (data: RouteObjectType[]) => {
return data.reduce((pre: RouteObjectType[], cur) => {
const Obj: RouteObjectType = { ...cur };
if (ids.includes(Obj.meta.id) || Obj.meta.hidden) {
if (Obj.children) {
Obj.children = [...getRouteList(Obj.children)];
}
pre.push(Obj);
}
return pre;
}, []);
};
return Promise.resolve([...getRouteList(routerList)]);
}
return Promise.resolve([]);
};
//获取全部节点
const getAllKeys = (data: menuType[]) => {
return data.reduce((pre: number[], cur) => {
pre.push(cur.id);
if (cur.children) {
pre.push(...getAllKeys(cur.children));
}
return pre;
}, []);
};
// 整合路由数据
export const routes = [...authRouterList(), ...whiteRouterList];
// 导出路由表
export const router = createBrowserRouter(routes);
// 路由表类型
export type routerItem = RouteObject & RouteObjectType;
import { authRouterList, router } from '~/router/index';
import { RouterProvider } from 'react-router-dom';
import { useEffect } from 'react';
import { authRouterList } from '~/router/index';
import { useNavigate, useLocation, useRoutes } from 'react-router-dom';
import { useEffect, useState } from 'react';
import Cookies from 'js-cookie';
import { whiteRouterList } from '~/router/router';
import { message } from 'antd';
function PrivateRouter() {
// 路由钩子
// const location = useLocation();
const location = useLocation();
const navigate = useNavigate();
const [router, setRouter] = useState(whiteRouterList);
// 在切换路由之前判断
const beforeEach = () => {
// TODO: 判断是否登录 (需要改为实时获取地址栏的路由)
const path = location.pathname;
const token = Cookies.get('SHAREFLY-TOKEN');
if (!token && path !== '/login') {
location.replace('/login');
return;
}
// 如果该用户没有权限,跳转到登录页
if (authRouterList().length === 0) {
message.info('请先配置权限!', 2000).then(() => {
location.replace('/login');
});
navigate('/login', { replace: true });
return;
}
};
useEffect(() => {
beforeEach();
// 整合路由数据
authRouterList().then((value) => {
if (value.length) {
const routes = [...value, ...whiteRouterList];
setRouter(routes); //不同账号登录时,重新更新路由(有瑕疵)
} else if (localStorage.getItem('roleId')) {
message.warning('该账号暂无权限');
navigate('/login', { replace: true });
}
});
}, [location.pathname]);
return <RouterProvider router={router} />;
return useRoutes(router);
}
export default PrivateRouter;
......@@ -2,6 +2,8 @@ import { createSlice } from '@reduxjs/toolkit';
const initialState = {
userInfo: JSON.parse(localStorage.getItem('SXTB-ADMIN-USER-INFO') as string) || [],
roleId: -1,
roleList: [],
};
export const userInfoSlice = createSlice({
......@@ -12,9 +14,24 @@ export const userInfoSlice = createSlice({
state.userInfo = action.payload;
localStorage.setItem('SXTB-ADMIN-USER-INFO', JSON.stringify(action.payload));
},
SET_ROLE_ID(state, action) {
state.roleId = action.payload;
localStorage.setItem('roleId', action.payload);
},
REMOVE_ROLE_ID() {
localStorage.removeItem('roleId');
},
SET_ROLE_LIST(state, action) {
state.roleList = action.payload;
localStorage.setItem('roleObj', JSON.stringify(action.payload));
},
REMOVE_ROLE_LIST() {
localStorage.removeItem('roleObj');
},
},
});
export const { SET_USERINFO } = userInfoSlice.actions;
export const { SET_USERINFO, SET_ROLE_ID, SET_ROLE_LIST, REMOVE_ROLE_LIST, REMOVE_ROLE_ID } =
userInfoSlice.actions;
export const UserInfo = userInfoSlice.reducer;
// 过滤路由
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { limitEntity } from '@/api/modules/role';
export const filterRouter = (list: any, routeList: limitEntity[]) => {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论