提交 61d5d9f5 作者: ZhangLingKun

Merge branch 'develop'

# Conflicts:
#	src/router/index.ts
......@@ -27,10 +27,10 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
pnpm-lock.yaml*
#pnpm-lock.yaml*
yarn-lock.yaml*
package-lock.yaml*
#package-lock.json*
#yarn.lock*
package-lock.json*
yarn.lock*
tsconfig.tsbuildinfo*
......@@ -2,14 +2,18 @@ FROM node:18-alpine as builder
ARG PROFILES_ACTIVE
ENV PROFILES_ACTIVE=$PROFILES_ACTIVE
WORKDIR /app
COPY package.json .
COPY package-lock.json .
RUN npm ci
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
RUN \
if [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i --frozen-lockfile; \
elif [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
else echo "Lockfile not found." && exit 1; \
fi
COPY . .
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; \
if [ "${PROFILES_ACTIVE}" = "development" ]; then echo "env PROFILES_ACTIVE=development. exec yarn run build:dev" && yarn run build:dev; \
else echo "env PROFILES_ACTIVE !=development. exec yarn run build" && yarn run build; \
fi
# nginx
......
......@@ -9,5 +9,10 @@
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<script type="text/javascript" >
window._AMapSecurityConfig = {
securityJsCode:'a9cd5c6e4eb563b65884efc14759d6a1',
}
</script>
</body>
</html>
......@@ -14,4 +14,4 @@ patches:
images:
- name: REGISTRY/NAMESPACE/IMAGE:TAG
newName: mmc-registry.cn-shenzhen.cr.aliyuncs.com/sharefly-dev/admin
newTag: 01280aac6badac09fd839261006483b7d09bb7d4
newTag: 2bc3f5681467023eaf7d732d8bffde2e434fe72a
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -5,7 +5,7 @@
"scripts": {
"dev": "vite",
"build": "vite build",
"buildDev": "vite build --mode development",
"build:dev": "vite build --mode development",
"build:tsc": "tsc && vite build",
"preview": "vite preview",
"lint": "npx eslint src",
......@@ -15,6 +15,7 @@
"format": "npm run prettier:fix && npm run lint:fix"
},
"dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",
"@ant-design/icons": "^5.0.1",
"@reduxjs/toolkit": "^1.9.2",
"@wangeditor/editor": "^5.1.23",
......@@ -31,6 +32,7 @@
"match-sorter": "^6.3.1",
"moment": "^2.29.4",
"pinyin-pro": "^3.14.0",
"prop-types": "^15.8.1",
"qs": "^6.10.3",
"query-string": "^8.1.0",
"react": "^18.1.0",
......@@ -66,4 +68,4 @@
"vite": "^4.3.9",
"vite-tsconfig-paths": "^3.5.0"
}
}
\ No newline at end of file
}
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -12,6 +12,7 @@ import { CustomManageAPI } from './modules/customManage';
import { MallManageAPI } from './modules/mallManage';
import { ResourceManageAPI } from './modules/resourceManageAPI';
import { ForumManageAPI } from './modules/forumManageAPI';
import { PilotTrainAPI } from './modules/pilotTrainAPI';
export {
CommonAPI,
......@@ -28,4 +29,5 @@ export {
MallManageAPI,
ResourceManageAPI,
ForumManageAPI,
PilotTrainAPI,
};
......@@ -37,6 +37,16 @@ export type listAppUserType = InterListFunction<
tagName: string;
tagRequire: string;
}[];
userRcdVO: {
createTime: string;
id: number;
rcdNickname: string;
rcdUserId: number;
rcdUserName: string;
remark: string;
userAccountId: number;
};
inviteCount: number;
}
>;
// 加盟标签列表
......@@ -107,6 +117,7 @@ export type listUserApplyTag = InterListFunction<
{
applyStatus?: number;
cooperationTagId?: number;
companyName?: string;
endTime?: string;
startTime?: string;
},
......@@ -115,11 +126,17 @@ export type listUserApplyTag = InterListFunction<
applyPhone: string;
applyTime: string;
approvalStatus: number;
attachmentList: null;
attachmentList: Array<{
type: number;
url: string;
}>;
companyName: string;
content: string;
cooperationTagId: number;
cooperationTagName: string;
id: number;
remark: string;
score: number;
userAccountId: number;
}
>;
......@@ -158,3 +175,61 @@ export type deleteApplyTag = InterFunction<
},
NonNullable<unknown>
>;
// 后台-编辑详情信息
export type editUserApplyTagDetails = InterFunction<
{
id: number;
},
{
address: string;
content: string;
cooperationTagId: number;
id: number;
lat: number;
lon: number;
name: string;
score: number;
}
>;
// 后台-编辑服务商信息
export type editUserApplyTag = InterFunction<
{
address?: string;
content?: string;
cooperationTagId?: number;
id: number;
lat?: number;
lon?: number;
name?: string;
score?: number;
},
NonNullable<unknown>
>;
// 裂变-邀请列表
export type listUserRcdType = InterListFunction<
{
userAccountId: number;
},
{
accountStatus: null;
accountType: null;
companyAuthStatus: number;
companyName: null;
cooperationTagVOS: null;
createTime: string;
deleted: null;
email: null;
id: number;
inviteCount: null;
nickName: string;
phoneNum: string;
portType: null;
remark: null;
source: null;
uid: null;
userImg: string;
userName: null;
userRcdVO: null;
userSex: null;
}
>;
import { InterFunction, InterItemFunction } from '~/api/interface';
//执照等级下拉
export type licenceGradeListType = InterFunction<any, { id: number; name: string }[]>;
//执照机型下拉
export type licenceModelsListType = InterFunction<any, { id: number; name: string }[]>;
//规模下拉
export type licenceScaleList = InterFunction<any, { id: number; name: string }[]>;
//执照类型下拉
export type licenceTypeListType = InterFunction<any, { id: number; name: string }[]>;
//机构列表
export type listOrgPageType = InterItemFunction<
{
statTime?: string;
endTime?: string;
gradeId?: number;
modelsId?: number;
name?: string;
region?: number;
typeId?: number;
id?: number;
},
{
auxiliaryPicture: string;
description: string;
detail: string;
detailedAddress: string;
id: number;
latitude: number;
longitude: number;
mainImage: string;
name: string;
programsDOList: Array<{
gradeId: number;
gradeName: number;
id: number;
mainImage: string;
modelsId: number;
modelsName: number;
orgId: string;
place: string;
price: number;
typeId: number;
typeName: number;
}>;
region: string;
regionName: string;
scaleId: number;
scaleName: number;
testCenter: number;
video: string;
createTime: string;
}[]
>;
//机构上传
export type insertOrgType = InterFunction<
{
auxiliaryPicture: string;
description: string;
detail: string;
detailedAddress: string;
latitude: number;
longitude: number;
mainImage: string;
name: string;
region: string;
regionName: string;
scaleId: number;
testCenter: number;
trainingProgramsVOS: Array<{
gradeId: number;
id: number;
mainImage: string;
modelsId: number;
place: string;
price: number;
typeId: number;
}>;
video: string;
},
any
>;
//机构删除
export type removeOrgType = InterFunction<{ id: number }, any>;
//机构修改
export type updateOrgType = InterFunction<
{
auxiliaryPicture: string;
description: string;
detail: string;
detailedAddress: string;
latitude: number;
longitude: number;
mainImage: string;
name: string;
region: string;
regionName: string;
scaleId: number;
testCenter: number;
trainingProgramsVOS: Array<{
gradeId: number;
id: number;
mainImage: string;
modelsId: number;
place: string;
price: number;
typeId: number;
}>;
video: string;
id: number;
},
any
>;
......@@ -7,8 +7,11 @@ import {
CompanyListTag,
cooperationListTag,
deleteApplyTag,
editUserApplyTag,
editUserApplyTagDetails,
listAppUserType,
listUserApplyTag,
listUserRcdType,
userAccountUpdateType,
} from '~/api/interface/customManageType';
......@@ -43,4 +46,13 @@ export class CustomManageAPI {
// 强制删除
static deleteApplyTag: deleteApplyTag = (params) =>
axios.get('/userapp/cooperation/deleteApplyTag', { params });
// 后台-编辑详情信息
static editUserApplyTagDetails: editUserApplyTagDetails = (params) =>
axios.get('/userapp/cooperation/editUserApplyTagDetails', { params });
// 后台-编辑服务商信息
static editUserApplyTag: editUserApplyTag = (params) =>
axios.post('/userapp/cooperation/editUserApplyTag', params);
// 裂变-邀请列表
static listUserRcd: listUserRcdType = (data) =>
axios.post('/userapp/user-account/listUserRcd', data);
}
import {
insertOrgType,
licenceGradeListType,
licenceModelsListType,
licenceScaleList,
licenceTypeListType,
listOrgPageType,
removeOrgType,
updateOrgType,
} from '~/api/interface/pilotTrainType';
import axios from '~/api/request';
export class PilotTrainAPI {
// 获取执照等级下拉
static getLicenceGradeList: licenceGradeListType = () =>
axios.get('/release/licence/pullDown/licenceGradeList');
//执照机型下拉
static getLicenceModelsList: licenceModelsListType = () =>
axios.get('/release/licence/pullDown/licenceModelsList');
// 机构规模下拉
static getLicenceScaleList: licenceScaleList = () =>
axios.get('/release/licence/pullDown/licenceScaleList');
// 执照类型下拉
static getLicenceTypeList: licenceTypeListType = () =>
axios.get('/release/licence/pullDown/licenceTypeList');
// 机构上传
static insertOrg: insertOrgType = (data) =>
axios.post('/release/licence/background/insertOrg', data);
// 机构列表
static getListOrgPage: listOrgPageType = (data) =>
axios.post('/release/licence/background/listOrgPage', data);
// 机构删除
static removeOrg: removeOrgType = (params) =>
axios.get('/release/licence/background/removeOrg', { params });
// 机构更新
static updateOrg: updateOrgType = (data) =>
axios.post('/release/licence/background/updateOrg', data);
}
......@@ -51,3 +51,12 @@
-moz-border-radius: 2em;
border-radius: 2em;
}
.ant-input-disabled{
color: rgba(0, 0, 0, 0.68) !important;
}
.ant-select-disabled{
.ant-select-selection-item{
color: rgba(0, 0, 0, 0.68) !important;
}
}
import { Form, InputNumber, Input } from 'antd';
import { Form, InputNumber, Input, Select } from 'antd';
import React from 'react';
import { Uploader } from '~/components/uploader';
import { UploadOutlined } from '@ant-design/icons';
// 表格可编辑单元格
interface EditableCellProps extends React.HTMLAttributes<HTMLElement> {
export interface EditableCellProps extends React.HTMLAttributes<HTMLElement> {
editing: boolean;
dataIndex: string;
title: any;
inputType: 'number' | 'text';
inputType: 'number' | 'text' | 'select' | 'uploader';
record: any;
index: number;
children: React.ReactNode;
}
const EditableCell: React.FC<EditableCellProps> = ({
const EditableCell: React.FC<
EditableCellProps & {
selectOption?: { name: string; id: number }[];
uploadSuccess?: (record: any, result: any) => void;
}
> = ({
editing,
dataIndex,
title,
inputType,
record,
index,
selectOption,
uploadSuccess,
children,
...restProps
}) => {
const inputNode =
inputType === 'number' ? <InputNumber /> : <Input placeholder={`请输入${title}`} />;
const inputNode = () => {
switch (inputType) {
case 'number':
return <InputNumber />;
case 'select':
return (
<Select placeholder={`请选择${title}`} style={{ textAlign: 'start' }}>
{selectOption &&
selectOption.map((v) => (
<Select.Option value={v.id} key={v.id}>
{v.name}
</Select.Option>
))}
</Select>
);
case 'uploader':
return (
<Uploader
fileUpload
listType='picture-card'
onChange={(value) => uploadSuccess?.(record, value)}
defaultFileList={record.fileList}
>
<UploadOutlined />
</Uploader>
);
default:
return <Input placeholder={`请输入${title}`} />;
}
};
const getMessage = () => {
switch (inputType) {
case 'number':
case 'text':
return `请输入${title}`;
case 'select':
return `请选择${title}`;
case 'uploader':
return `请上传${title}`;
default:
return `请输入${title}`;
}
};
return (
<td {...restProps}>
{editing ? (
......@@ -33,11 +82,11 @@ const EditableCell: React.FC<EditableCellProps> = ({
rules={[
{
required: true,
message: `请输入${title}`,
message: getMessage(),
},
]}
>
{inputNode}
{inputNode()}
</Form.Item>
) : (
children
......
import { FC, useEffect, useRef, useState } from 'react';
import { Select, Input, Modal } from 'antd';
import MapComponent from '~/components/select-map/map';
import { debounce } from 'lodash';
// 传参类型
interface propType {
title?: string;
open: boolean;
closed: any;
submit: any;
}
const SelectMapModal: FC<propType> = (props) => {
SelectMapModal.defaultProps = {
title: '选择地点',
};
// 参数
const { title, open, closed, submit } = props;
// 子组件事件
const childRef = useRef<{
onSearch: (e: string) => void;
addMarker: (e: { lat: number; lng: number }) => void;
clearMarker: () => void;
}>(null);
// 位置信息
const [position, setPosition] = useState<{
lat: number;
lon: number;
address: string;
adCode: number;
}>();
// 搜索地点
const [addressList, setAddressList] = useState<{ label: string; value: number; data: any }[]>();
// 取消事件
const handleCancel = () => {
setPosition(undefined);
setAddressList([]);
closed();
};
// 确认事件
const handleOk = () => {
submit(position);
};
// 搜索地点
const handleSearch = (e: string) => {
if (e) {
childRef.current?.onSearch(e);
} else {
setAddressList([]);
}
};
// 防抖
const handleSearchDebounced = debounce(handleSearch, 500);
// 选择了地址
const handleSearchAddress = (e: number) => {
if (e) {
console.log(addressList?.[e].data);
// eslint-disable-next-line no-unsafe-optional-chaining
const { lat, lng } = addressList?.[e].data.location;
childRef.current?.addMarker({ lat, lng });
setPosition({
lat: lat,
lon: lng,
address: `${addressList?.[e].data.name}`,
adCode: addressList?.[e].data.adcode,
});
} else {
childRef.current?.clearMarker();
setPosition(undefined);
}
};
// componentDidMount
useEffect(() => {
if (!open) return;
return () => {
setPosition(undefined);
};
}, [open]);
return (
<Modal open={open} title={title} onCancel={handleCancel} onOk={handleOk} destroyOnClose>
<div
style={{
display: 'flex',
justifyContent: 'flex-start',
alignItems: 'center',
marginBottom: '10px',
}}
>
<div style={{ width: '60px' }}>搜索地点:</div>
<Select
showSearch
placeholder={'请输入地点'}
optionFilterProp='children'
style={{ width: '80%', marginRight: '20px' }}
allowClear
onSearch={handleSearchDebounced}
filterOption={(input, option) =>
(option?.label ?? '').toLowerCase().includes(input.toLowerCase())
}
options={addressList}
onChange={handleSearchAddress}
/>
</div>
<MapComponent
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
ref={childRef}
onSelectAddress={(e) => {
setPosition({
lat: e.lat,
lon: e.lng,
address: e.formattedAddress,
adCode: Number(e.adcode),
});
}}
onSearchAddress={(e) => {
setAddressList(e.map((i, j) => ({ label: i.name, value: j, data: i })));
}}
></MapComponent>
<div
style={{
display: 'flex',
justifyContent: 'flex-start',
alignItems: 'center',
marginTop: '10px',
marginBottom: '20px',
}}
>
<div style={{ width: '60px' }}>选择地点:</div>
<Input
value={position?.address}
placeholder={'请选择地点'}
maxLength={25}
allowClear
style={{ width: '80%', marginRight: '20px' }}
disabled
/>
</div>
</Modal>
);
};
export default SelectMapModal;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
import AMapLoader from '@amap/amap-jsapi-loader';
import { Component } from 'react';
interface MapComponentProps {
onSelectAddress: (e: {
adcode: string;
building: string;
buildingType: string;
city: string;
citycode: string;
district: string;
formattedAddress: string;
neighborhood: string;
neighborhoodType: string;
province: string;
street: string;
streetNumber: string;
towncode: string;
township: string;
lat: number;
lng: number;
}) => void;
onSearchAddress: (
e: {
id: string;
name: string;
district: string;
adcode: string;
location: Array<number>;
address: string;
typecode: string;
}[],
) => void;
}
class MapComponent extends Component<MapComponentProps> {
constructor(props) {
super(props);
this.map = {};
this.autoComplete = {};
}
// dom渲染成功后进行map对象的创建
componentDidMount() {
AMapLoader.load({
key: '7a3a24e85672c06ab466d790fb5d38a3', // 申请好的Web端开发者Key,首次调用 load 时必填
version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: [], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
})
.then((AMap) => {
this.map = new AMap.Map('container', {
// 设置地图容器id
viewMode: '3D', // 是否为3D地图模式
zoom: 10, // 初始化地图级别
// center: [105.602725, 37.076636], // 初始化地图中心点位置
});
AMap.plugin(
['AMap.ToolBar', 'AMap.AutoComplete', 'AMap.Scale', 'AMap.Geocoder', 'AMap.Marker'],
() => {
// 缩放
const scale = new AMap.Scale();
this.map.addControl(scale);
// 工具栏
const toolbar = new AMap.ToolBar();
this.map.addControl(toolbar);
// 位置搜索
const autoOptions = {
//city 限定城市,默认全国
city: '全国',
};
// 实例化AutoComplete
this.autoComplete = new AMap.AutoComplete(autoOptions);
},
);
this.map.on('click', (e) => {
this.map.clearMap();
const { lat, lng } = e.lnglat;
// 新建marker实例
const marker = new AMap.Marker({
position: new AMap.LngLat(lng, lat), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
title: '选择的位置',
});
// 添加marker
this.map.add(marker);
// 获取地理信息
const geocoder = new AMap.Geocoder({
city: '全国',
});
// console.log('点击 --->', e);
geocoder.getAddress([lng, lat], (status, result) => {
if (status === 'complete' && result.info === 'OK') {
// result为对应的地理位置详细信息
const { formattedAddress, addressComponent } = result.regeocode;
console.log('点击选择-->', status, result);
this.props.onSelectAddress({
lat,
lng,
formattedAddress,
...addressComponent,
});
}
});
});
})
.catch((e) => {
console.log(e);
});
}
componentWillUnmount() {
this.map.destroy();
}
// 搜索数据
onSearch(keyword: string) {
// 根据关键字进行搜索
this.autoComplete.search(keyword, (status, result) => {
// 搜索成功时,result即是对应的匹配数据
if (status === 'complete' && result.info === 'OK') {
this.props.onSearchAddress(result.tips);
}
});
}
// 添加点标记
addMarker(e: { lat: number; lng: number }) {
const { lat, lng } = e;
this.map.clearMap();
// 新建marker实例
const marker = new AMap.Marker({
position: new AMap.LngLat(lng, lat), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
title: '选择的位置',
});
// 添加marker
this.map.add(marker);
// 设置中心点
this.map.setCenter([lng, lat]);
}
// 清除地图上的点标记
clearMarker() {
this.map.clearMap();
}
render() {
// 初始化创建地图容器,div标签作为地图容器,同时为该div指定id属性;
return <div id='container' className='map' style={{ height: '400px' }}></div>;
}
}
// 导出地图组建类
export default MapComponent;
......@@ -44,9 +44,7 @@ function LoginView() {
} else {
message.warning('请先配置权限');
}
//获取第一个路由
});
// 获取第一个路由
} else {
message.error('登录失败,请检查账号信息');
}
......
import { FC, useEffect, useState } from 'react';
import { Button, message, Modal } from 'antd';
import { InterDataType, InterListType, InterReqType } from '~/api/interface';
import { CustomManageAPI } from '~/api';
import {
applyTagDetails,
approvalApplyTag,
editUserApplyTag,
editUserApplyTagDetails,
listUserApplyTag,
} from '~/api/interface/customManageType';
import './index.scss';
import { PlusOutlined } from '@ant-design/icons';
import { Uploader } from '~/components/uploader';
import { InterDataType, InterListType, InterReqType } from '~/api/interface';
import { Button, Form, Input, message, Modal, Rate, Select, Space } from 'antd';
import { CustomManageAPI } from '~/api';
import SelectMapModal from '~/components/select-map';
// 列表的类型
type DataType = InterDataType<applyTagDetails>;
// 数据类型
type DataType = InterDataType<editUserApplyTagDetails>;
// 列表的类型
type TableType = InterListType<listUserApplyTag>;
// 请求的表单类型
type ReqType = InterReqType<approvalApplyTag>;
type ReqType = InterReqType<editUserApplyTag>;
// 传参类型
interface propType {
title: string;
......@@ -26,111 +24,157 @@ interface propType {
}
const AddEditModal: FC<propType> = (props) => {
AddEditModal.defaultProps = {
data: undefined,
};
// 参数
const { title, open, closed, data } = props;
const [applyTagDetail, setApplyTagDetail] = useState<DataType>();
// 表单数据
const [form] = Form.useForm<ReqType>();
// 详情数据
const [detail, setDetail] = useState<DataType>();
// 是否选择地址弹窗
const [openAddress, setOpenAddress] = useState<boolean>(false);
// 加盟列表
const [cooperationList, setCooperationList] = useState<{ label: string; value: number }[]>([]);
// 选择的地址
const [address, setAddress] = useState<{ lat: number; lon: number; address: string }>();
// 关闭弹窗
const handleCancel = () => {
form.resetFields();
closed();
};
// 点击事件
const handleOk = async (status: boolean) => {
await handleSubmit({ id: Number(data?.id), status });
// 获取审批详情
const getApplyTagDetails = async () => {
const res = await CustomManageAPI.editUserApplyTagDetails({
id: Number(data?.id),
});
if (res && res.code === '200') {
form.setFieldsValue({
...res.result,
name: res.result.name || data?.companyName,
});
setDetail(res.result);
// console.log('获取审批详情 -->', res.result);
}
};
// 获取加盟列表
const getCooperationList = async () => {
const res = await CustomManageAPI.cooperationListTag({});
if (res && res.code === '200') {
const list = res.result || [];
setCooperationList(list.map((i) => ({ label: i.tagName, value: i.id })));
}
};
// 确认事件
const handleOk = () => {
form
.validateFields()
.then(async (values) => {
await handleSubmit(values);
})
.catch((err) => {
message
.warning({
content: err.errorFields[0].errors[0],
})
.then();
});
};
// 提交事件
const handleSubmit = async (values: ReqType) => {
const res = await CustomManageAPI.approvalApplyTag(values);
const res = await CustomManageAPI.editUserApplyTag({
id: Number(data?.id),
...detail,
...values,
...address,
});
if (res && res.code === '200') {
message.success('操作成功');
handleCancel();
}
};
// 获取审批详情
const getApplyTagDetails = async () => {
const res = await CustomManageAPI.applyTagDetails({
id: data?.id,
userAccountId: data?.userAccountId,
});
if (res && res.code === '200') {
const { result } = res;
setApplyTagDetail(result);
}
};
// componentDidMount
useEffect(() => {
if (!open) return;
getCooperationList().then();
if (!data) return;
getApplyTagDetails().then();
// console.log('data --->', data);
}, [open]);
return (
<Modal open={open} title={title} onCancel={handleCancel} destroyOnClose footer={null}>
<div className='apply-detail'>
<div className='detail-text'>确定通过用户提交的加盟申请成为加盟商吗?</div>
<div className='detail-action'>
<Button type={'default'} onClick={() => handleOk(false)}>
驳回
</Button>
<Button type={'primary'} onClick={() => handleOk(true)}>
通过
</Button>
</div>
<div className='detail-title'>企业认证信息</div>
<div className='detail-item'>
<div className='item-label'>企业名称:</div>
<div className='item-value'>{applyTagDetail?.companyName || '无'}</div>
</div>
<div className='detail-item'>
<div className='item-label'>社会信用代码:</div>
<div className='item-value'>{applyTagDetail?.creditCode || '无'}</div>
</div>
<div className='detail-item'>
<div className='item-label'>工商营业执照:</div>
<div className='item-value'>
<Uploader
listType={'picture-card'}
fileUpload
fileLength={1}
fileSize={10}
fileType={['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/bmp']}
defaultFileList={
applyTagDetail?.licenseImg ? [{ url: applyTagDetail?.licenseImg }] : []
}
disabled={true}
>
<PlusOutlined />
</Uploader>
</div>
</div>
<div className='detail-item'>
<div className='item-label'>附件信息:</div>
<div className='item-value'>
<Uploader
listType={'picture-card'}
fileUpload
fileLength={1}
fileSize={10}
fileType={['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/bmp']}
defaultFileList={
applyTagDetail?.attachmentList?.length
? applyTagDetail?.attachmentList.map((i) => ({ url: i.url }))
: []
}
disabled={true}
>
<PlusOutlined />
</Uploader>
</div>
</div>
<div className='detail-item'>
<div className='item-label'>备注:</div>
<div className='item-value'>{applyTagDetail?.remark || '无'}</div>
</div>
</div>
</Modal>
<>
<Modal open={open} title={title} onCancel={handleCancel} onOk={handleOk} destroyOnClose>
<Form form={form} labelCol={{ span: 5 }} wrapperCol={{ span: 16 }}>
<Form.Item
label='网点名称'
name='name'
rules={[{ required: true, message: '请输入网点名称' }]}
>
<Input placeholder={'请输入企业名称'} maxLength={25} allowClear />
</Form.Item>
<Form.Item
label='加盟类型'
name='cooperationTagId'
rules={[{ required: true, message: '请选择加盟类型' }]}
>
<Select placeholder='请选择加盟类型' allowClear options={cooperationList} disabled />
</Form.Item>
<Form.Item
label='网点地址'
name='address'
rules={[{ required: true, message: '请选择网点地址' }]}
>
<Space.Compact style={{ width: '100%' }}>
<Input
placeholder='请选择网点地址'
maxLength={50}
allowClear
disabled
value={form.getFieldValue('address') || detail?.address}
/>
<Button
type='primary'
onClick={() => {
setOpenAddress(true);
}}
>
选择位置
</Button>
</Space.Compact>
</Form.Item>
<Form.Item
label='服务资质'
name='content'
rules={[{ required: true, message: '请输入服务资质' }]}
>
<Input.TextArea
placeholder={'请输入服务资质(“;”号换行)'}
maxLength={140}
allowClear
showCount
/>
</Form.Item>
<Form.Item
label='服务评分'
name='score'
initialValue={5}
rules={[{ required: true, message: '请选择服务评分' }]}
>
<Rate allowClear />
</Form.Item>
</Form>
</Modal>
<SelectMapModal
title={'选择位置'}
open={openAddress}
closed={() => {
setOpenAddress(false);
}}
submit={(e: { lat: number; lon: number; address: string }) => {
form.setFieldValue('address', e.address);
setAddress(e);
setOpenAddress(false);
}}
/>
</>
);
};
......
import { FC, useEffect, useState } from 'react';
import { Button, message, Modal } from 'antd';
import { InterDataType, InterListType, InterReqType } from '~/api/interface';
import { CustomManageAPI } from '~/api';
import {
applyTagDetails,
approvalApplyTag,
listUserApplyTag,
} from '~/api/interface/customManageType';
import './index.scss';
import { PlusOutlined } from '@ant-design/icons';
import { Uploader } from '~/components/uploader';
// 列表的类型
type DataType = InterDataType<applyTagDetails>;
// 列表的类型
type TableType = InterListType<listUserApplyTag>;
// 请求的表单类型
type ReqType = InterReqType<approvalApplyTag>;
// 传参类型
interface propType {
title: string;
open: boolean;
closed: any;
data?: TableType[0];
}
const ApprovalModal: FC<propType> = (props) => {
ApprovalModal.defaultProps = {
data: undefined,
};
// 参数
const { title, open, closed, data } = props;
const [applyTagDetail, setApplyTagDetail] = useState<DataType>();
// 关闭弹窗
const handleCancel = () => {
closed();
};
// 点击事件
const handleOk = async (status: boolean) => {
await handleSubmit({ id: Number(data?.id), status });
};
// 提交事件
const handleSubmit = async (values: ReqType) => {
const res = await CustomManageAPI.approvalApplyTag(values);
if (res && res.code === '200') {
message.success('操作成功');
handleCancel();
}
};
// 获取审批详情
const getApplyTagDetails = async () => {
const res = await CustomManageAPI.applyTagDetails({
id: data?.id,
userAccountId: data?.userAccountId,
});
if (res && res.code === '200') {
const { result } = res;
setApplyTagDetail(result);
}
};
// componentDidMount
useEffect(() => {
if (!open) return;
if (!data) return;
getApplyTagDetails().then();
// console.log('data --->', data);
}, [open]);
return (
<Modal open={open} title={title} onCancel={handleCancel} destroyOnClose footer={null}>
<div className='apply-detail'>
<div className='detail-text'>确定通过用户提交的加盟申请成为加盟商吗?</div>
<div className='detail-action'>
<Button type={'default'} onClick={() => handleOk(false)}>
驳回
</Button>
<Button type={'primary'} onClick={() => handleOk(true)}>
通过
</Button>
</div>
<div className='detail-title'>企业认证信息</div>
<div className='detail-item'>
<div className='item-label'>企业名称:</div>
<div className='item-value'>{applyTagDetail?.companyName || '无'}</div>
</div>
<div className='detail-item'>
<div className='item-label'>社会信用代码:</div>
<div className='item-value'>{applyTagDetail?.creditCode || '无'}</div>
</div>
<div className='detail-item'>
<div className='item-label'>工商营业执照:</div>
<div className='item-value'>
<Uploader
listType={'picture-card'}
fileUpload
fileLength={1}
fileSize={10}
fileType={['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/bmp']}
defaultFileList={
applyTagDetail?.licenseImg ? [{ url: applyTagDetail?.licenseImg }] : []
}
disabled={true}
>
<PlusOutlined />
</Uploader>
</div>
</div>
<div className='detail-item'>
<div className='item-label'>附件信息:</div>
<div className='item-value'>
<Uploader
listType={'picture-card'}
fileUpload
fileLength={1}
fileSize={10}
fileType={['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/bmp']}
defaultFileList={
applyTagDetail?.attachmentList?.length
? applyTagDetail?.attachmentList.map((i) => ({ url: i.url }))
: []
}
disabled={true}
>
<PlusOutlined />
</Uploader>
</div>
</div>
<div className='detail-item'>
<div className='item-label'>备注:</div>
<div className='item-value'>{applyTagDetail?.remark || '无'}</div>
</div>
</div>
</Modal>
);
};
export default ApprovalModal;
import { useEffect, useState } from 'react';
import SearchBox from '~/components/search-box';
import { CustomManageAPI } from '~/api';
import { Button, message, Modal, Table } from 'antd';
import { Button, message, Modal, Rate, Table } from 'antd';
import { ColumnsType } from 'antd/es/table';
import { InterListType, InterReqListType } from '~/api/interface';
import { listUserApplyTag } from '~/api/interface/customManageType';
import AddEditModal from './comp/addEditModal';
import ApprovalModal from './comp/approvalModal';
import AddEditModal from '~/pages/customManage/customIdentity/comp/addEditModal';
// 列表类型
type TableType = InterListType<listUserApplyTag>;
......@@ -24,8 +25,10 @@ const CustomIdentityView = () => {
const { confirm } = Modal;
// 加盟列表
const [cooperationList, setCooperationList] = useState<{ label: string; value: number }[]>([]);
// 新增弹窗
// 新增编辑弹窗
const [addModalVisible, setAddModalVisible] = useState<boolean>(false);
// 审批弹窗
const [approvalModalVisible, setApprovalModalVisible] = useState<boolean>(false);
// 需要编辑的数据
const [editData, setEditData] = useState<TableType[0]>();
// 表格数据
......@@ -112,6 +115,13 @@ const CustomIdentityView = () => {
render: (text) => cooperationList.find((i) => i.value === text)?.label || text,
},
{
title: '企业认证名称',
dataIndex: 'companyName',
align: 'center',
width: '200px',
ellipsis: true,
},
{
title: '联系人',
dataIndex: 'applyName',
align: 'center',
......@@ -122,6 +132,20 @@ const CustomIdentityView = () => {
align: 'center',
},
{
title: '服务资质',
dataIndex: 'content',
align: 'center',
width: '200px',
ellipsis: true,
},
{
title: '服务评价',
dataIndex: 'score',
align: 'center',
width: '120px',
render: (text) => text && <Rate disabled value={Number(text)} />,
},
{
title: '申请时间',
dataIndex: 'applyTime',
align: 'center',
......@@ -137,21 +161,31 @@ const CustomIdentityView = () => {
dataIndex: 'action',
align: 'center',
fixed: 'right',
width: '120px',
width: '150px',
render: (_text, record) => (
<>
<Button
type={'link'}
onClick={() => {
setAddModalVisible(true);
setApprovalModalVisible(true);
setEditData(JSON.parse(JSON.stringify(record)));
}}
disabled={record.approvalStatus !== 0}
>
审批
</Button>
<Button
type={'link'}
onClick={() => {
setAddModalVisible(true);
setEditData(JSON.parse(JSON.stringify(record)));
}}
disabled={[0, 2].includes(record.approvalStatus)}
>
编辑
</Button>
<Button type={'link'} danger onClick={() => handleDelete(record)}>
强制删除
删除
</Button>
</>
),
......@@ -162,6 +196,12 @@ const CustomIdentityView = () => {
<SearchBox
search={[
{
name: 'companyName',
label: '企业名称',
type: 'input',
placeholder: '请输入企业名称',
},
{
name: 'cooperationTagId',
label: '申请加盟类型',
type: 'Select',
......@@ -189,7 +229,7 @@ const CustomIdentityView = () => {
dataSource={tableData}
columns={columns}
rowKey='id'
// scroll={{ x: 1500 }}
scroll={{ x: 1200 }}
bordered
pagination={{
total: pagination.total,
......@@ -201,9 +241,21 @@ const CustomIdentityView = () => {
showTotal: (total, range) => `当前 ${range[0]}-${range[1]} 条记录 / 共 ${total} 条数据`,
}}
/>
{/*审批弹窗*/}
<ApprovalModal
open={approvalModalVisible}
title={editData?.id ? '审批' : '新增'}
data={editData}
closed={() => {
setApprovalModalVisible(false);
setEditData(undefined);
paginationChange(pagination.current, pagination.pageSize);
}}
/>
{/*编辑弹窗*/}
<AddEditModal
open={addModalVisible}
title={editData?.id ? '审批' : '新增'}
title={editData?.id ? '编辑' : '新增'}
data={editData}
closed={() => {
setAddModalVisible(false);
......
import React, { useEffect, useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import qs from 'query-string';
import SearchBox from '~/components/search-box';
import { Button, Table } from 'antd';
import { ArrowLeftOutlined } from '@ant-design/icons';
import { InterListType } from '~/api/interface';
import { listUserRcdType } from '~/api/interface/customManageType';
import { CustomManageAPI } from '~/api';
import { ColumnsType } from 'antd/es/table';
// 表格类型
type TableType = InterListType<listUserRcdType>;
function CustomListDetail() {
// 路由钩子
const location = useLocation();
// 导航钩子
const navigate = useNavigate();
// 表格数据
const [tableData, setTableData] = useState<TableType>([]);
// 表格分页配置
const [pagination, setPagination] = useState({
total: 0,
pageSize: 5,
current: 1,
totalPage: 0,
});
// 加载列表
const getTableList = async (value = {}) => {
// 只需要修改这个地方的接口即可
const res = await CustomManageAPI.listUserRcd({
userAccountId: Number(qs.parse(location.search).id),
pageNo: pagination.current,
pageSize: pagination.pageSize,
...value,
});
if (res && res.code === '200') {
const { list, pageNo, totalCount, pageSize, totalPage } = res.result; // 解构
setPagination({
total: totalCount,
current: pageNo,
pageSize,
totalPage,
});
setTableData(list);
}
};
// 翻页
const paginationChange = (pageNo: number, pageSize: number) => {
getTableList({ pageNo, pageSize }).then();
};
// 返回上一页
const handleBack = () => {
navigate(-1);
};
// componentDidMount
useEffect(() => {
getTableList().then();
}, []);
// 表格结构
const columns: ColumnsType<TableType[0]> = [
{
title: '序号',
dataIndex: 'accountNo',
align: 'center',
width: '50px',
render: (_text, _record, index) => (pagination.current - 1) * pagination.pageSize + index + 1,
},
{
title: '用户名称',
dataIndex: 'userName',
align: 'center',
render: (text, record) => text || record.nickName || '游客用户',
},
{
title: '手机号',
dataIndex: 'phoneNum',
align: 'center',
},
{
title: '注册时间',
dataIndex: 'createTime',
align: 'center',
},
];
return (
<>
<SearchBox
child={
<Button type={'primary'} icon={<ArrowLeftOutlined />} onClick={() => handleBack()}>
返回
</Button>
}
/>
<Table
size='small'
dataSource={tableData}
columns={columns}
rowKey='id'
// scroll={{ x: 1500 }}
bordered
pagination={{
total: pagination.total,
pageSize: pagination.pageSize,
current: pagination.current,
showSizeChanger: true,
showQuickJumper: true,
onChange: (page: number, pageSize: number) => paginationChange(page, pageSize),
showTotal: (total, range) => `当前 ${range[0]}-${range[1]} 条记录 / 共 ${total} 条数据`,
}}
/>
</>
);
}
export default CustomListDetail;
......@@ -6,6 +6,8 @@ import { ChangeModal } from '~/pages/customManage/customList/comp/changeModal';
import { InterListType, InterReqType } from '~/api/interface';
import { listAppUserType } from '~/api/interface/customManageType';
import { CustomManageAPI, SystemManageAPI } from '~/api';
import qs from 'query-string';
import { useNavigate } from 'react-router-dom';
// 表格数据类型
type TableType = InterListType<listAppUserType>;
......@@ -25,6 +27,8 @@ const portTypeList = [
function CustomListView() {
const { confirm } = Modal;
// 路由钩子
const navigate = useNavigate();
// 是否打开变更弹窗
const [isChangeVisModal, setIsChangeVisModal] = useState<boolean>(false);
// 表格分页配置
......@@ -86,6 +90,13 @@ function CustomListView() {
},
});
};
// 跳转详情
const handleInvite = (record: TableType[0]) => {
const search = {
id: record.id,
};
navigate(`/customManage/customList/detail?${qs.stringify(search)}`);
};
// componentDidMount
useEffect(() => {
query = {};
......@@ -97,7 +108,7 @@ function CustomListView() {
const columns: ColumnsType<TableType[0]> = [
{
title: '用户UID',
dataIndex: 'uid',
dataIndex: 'id',
align: 'center',
width: '100px',
},
......@@ -150,6 +161,7 @@ function CustomListView() {
title: '加盟身份',
dataIndex: 'cooperationTagVOS',
align: 'center',
width: '100px',
render: (_text, record) =>
record.cooperationTagVOS?.map((i, j) => (
<Tag color='processing' key={j} style={{ marginBottom: '10px' }}>
......@@ -159,15 +171,23 @@ function CustomListView() {
},
{
title: '上级推荐人',
dataIndex: 'remark',
align: 'center',
render: (_text) => `--`,
render: (_text, record) =>
record?.userRcdVO?.id &&
`${record?.userRcdVO?.rcdUserName || record?.userRcdVO?.rcdNickname}(${
record?.userRcdVO?.rcdUserId
})`,
},
{
title: '推荐伙伴',
dataIndex: 'remark',
dataIndex: 'inviteCount',
align: 'center',
render: (_text) => `--`,
render: (text, record) =>
!!text && (
<Button type={'link'} onClick={() => handleInvite(record)}>
{text}
</Button>
),
},
{
title: '相关运营',
......
/* eslint-disable */
// @ts-nocheck
import { useState } from 'react';
import { Form, Input, message, Modal, Upload, UploadProps } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
......
.base-info{
&-header{
font-weight: bold;
margin-bottom: 10px;
line-height: 20px;
}
.info-video-wrap{
position: relative;
width: 200px;
img{
position: absolute;
right: 0;
top: 0;
transform: translate(50%,-25%);
}
}
.region-info{
display: flex;
align-items: center;
div{
margin-right: 10px;
word-break: break-all;
}
}
}
......@@ -2,56 +2,248 @@ import { Button, Form, Input, Radio, Select } from 'antd';
import { Uploader } from '~/components/uploader';
import { EnvironmentOutlined, UploadOutlined } from '@ant-design/icons';
import './index.scss';
import React, { FC, forwardRef, useEffect, useImperativeHandle, useState } from 'react';
import deletePng from '~/assets/image/delete.png';
import SelectMapModal from '~/components/select-map';
import { PilotTrainAPI } from '~/api';
import { InterDataType, InterReqType } from '~/api/interface';
import { insertOrgType, licenceScaleList } from '~/api/interface/pilotTrainType';
const BaseInfo = () => {
//规模下拉返回类型
type scaleListType = InterDataType<licenceScaleList>;
interface selfProps {
ref: any;
}
//上传机构请求类型
type insertOrgParametersType = Omit<InterReqType<insertOrgType>, 'trainingProgramsVOS'>;
const BaseInfo: FC<selfProps> = forwardRef((props, ref) => {
const [baseInfoForm] = Form.useForm<insertOrgParametersType>();
//地图地点选择
const [selectMapShow, setSelectMapShow] = useState<boolean>(false);
// 位置信息
const [position, setPosition] = useState<{
lat: number;
lon: number;
address: string;
adCode: number;
}>();
const [mainImgList, setMainImgList] = useState<
{
id: number;
name: string;
uid: number;
url: string;
}[]
>([]);
const [subImgList, setSubImgList] = useState<
{
id: number;
name: string;
uid: number;
url: string;
}[]
>([]);
const [videoList, setVideoList] = useState<
{
id: number;
name: string;
uid: number;
url: string;
}[]
>([]);
//规模下拉列表
const [scaleList, setScaleList] = useState<scaleListType>([]);
useImperativeHandle(ref, () => ({
getForm: () => baseInfoForm,
getDefaultDataEvent: () => ({
setPosition,
setMainImgList,
setSubImgList,
setVideoList,
}),
getPosition: () => position,
}));
//上传结果
const uploaderChange = (
value: {
id: number;
name: string;
uid: number;
url: string;
}[],
type: string,
) => {
switch (type) {
case 'mainImg':
baseInfoForm.setFieldValue('mainImage', value[0].url || undefined);
setMainImgList(value);
break;
case 'subImg':
baseInfoForm.setFieldValue(
'auxiliaryPicture',
value.length ? value.map((v) => v.url).join(',') : undefined,
);
setSubImgList(value);
break;
case 'video':
baseInfoForm.setFieldValue('video', value[0].url);
setVideoList(value);
break;
default:
}
};
//视频删除
const deleteVideo = () => {
setVideoList([]);
baseInfoForm.setFieldValue('video', undefined);
};
//地图选点
const showSelectMap = () => [setSelectMapShow(true)];
const selectMapSubmit = (value: {
lat: number;
lon: number;
address: string;
adCode: number;
}) => {
baseInfoForm.setFieldsValue({
region: [
value.adCode.toString().substring(0, 2) + '0000',
value.adCode.toString().substring(0, 4) + '00',
].join(','),
});
setPosition(value);
setSelectMapShow(false);
};
const selectMapClose = () => {
setSelectMapShow(false);
};
//机构规模
const getLicenceScaleList = () => {
PilotTrainAPI.getLicenceScaleList().then(({ result }) => {
setScaleList(result || []);
});
};
useEffect(() => {
getLicenceScaleList();
}, []);
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'>
<Form
labelCol={{ span: 2 }}
wrapperCol={{ span: 7 }}
form={baseInfoForm}
initialValues={{ testCenter: 1 }}
>
<Form.Item
label='机构主图'
name='mainImage'
rules={[{ required: true, message: '请上传机构主图' }]}
>
<Uploader
fileUpload
listType='picture-card'
onChange={(result) => uploaderChange(result, 'mainImg')}
fileLength={1}
fileSize={5}
fileType={['image/jpg', 'image/jpeg', 'image/png']}
defaultFileList={mainImgList}
>
<UploadOutlined />
</Uploader>
</Form.Item>
<Form.Item label='机构副图'>
<Uploader fileUpload listType='picture-card'>
<Form.Item
label='机构副图'
name='auxiliaryPicture'
rules={[{ required: true, message: '请上传机构副图' }]}
>
<Uploader
fileUpload
listType='picture-card'
onChange={(result) => uploaderChange(result, 'subImg')}
fileLength={5}
fileSize={5}
fileType={['image/jpg', 'image/jpeg', 'image/png']}
defaultFileList={subImgList}
>
<UploadOutlined />
</Uploader>
</Form.Item>
<Form.Item label='机构视频'>
<Uploader fileUpload listType='text'>
<Button icon={<UploadOutlined />} type='primary'>
上传视频
</Button>
</Uploader>
<Form.Item label='机构视频' name='video'>
{videoList.length ? (
<div className='info-video-wrap'>
{/* eslint-disable-next-line jsx-a11y/media-has-caption */}
<video
src={videoList[0].url}
style={{ width: '200px', height: '200px' }}
controls
/>
{<img src={deletePng} alt='删除' onClick={deleteVideo} />}
</div>
) : (
<Uploader
fileUpload
listType='text'
onChange={(result) => uploaderChange(result, 'video')}
fileSize={1024}
fileType={['video/mp4', 'video/avi', 'video/wmv', 'video/rmvb']}
fileLength={1}
defaultFileList={videoList}
>
<Button icon={<UploadOutlined />} type='primary'>
上传视频
</Button>
</Uploader>
)}
</Form.Item>
<Form.Item label='机构名称'>
<Input placeholder='请输入机构名称' />
<Form.Item
label='机构名称'
name='name'
rules={[{ required: true, message: '请输入机构名称' }]}
>
<Input placeholder='请输入机构名称' maxLength={30} />
</Form.Item>
<Form.Item label='机构地区'>
<Button icon={<EnvironmentOutlined />} type='primary'></Button>
<Form.Item
label='机构地区'
name='region'
rules={[{ required: true, message: '请选择机构地区' }]}
>
<div className='region-info'>
{position?.address ? <div>{position?.address}</div> : ''}
<Button
icon={<EnvironmentOutlined />}
type='primary'
onClick={showSelectMap}
></Button>
</div>
</Form.Item>
<Form.Item label='考点机构'>
<Form.Item label='考点机构' name='testCenter'>
<Radio.Group>
<Radio value={1}></Radio>
<Radio value={0}></Radio>
</Radio.Group>
</Form.Item>
<Form.Item label='机构规模'>
<Form.Item label='机构规模' name='scaleId'>
<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>
{scaleList.map((scale) => (
<Select.Option value={scale.id} key={scale.id}>
{scale.name}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item label='机构描述'>
<Input.TextArea placeholder='请选择机构描述' />
<Form.Item label='机构描述' name='description'>
<Input.TextArea placeholder='请选择机构描述' maxLength={225} rows={4} showCount />
</Form.Item>
</Form>
</div>
<SelectMapModal submit={selectMapSubmit} closed={selectMapClose} open={selectMapShow} />
</div>
);
};
});
export default BaseInfo;
.introduce-info{
margin-top: 20px;
&-header{
font-weight: bold;
margin-bottom: 10px;
line-height: 20px;
}
&-rich{
}
}
import RichText from '~/components/richText';
import './index.scss';
import { Col, Row } from 'antd';
import { FC } from 'react';
interface selfProps {
setIntroduceInfoEvent: (html: string) => void;
introduceInfo: string;
}
const IntroduceInfo: FC<selfProps> = ({ setIntroduceInfoEvent, introduceInfo }) => {
const onChange = (html?: string) => {
setIntroduceInfoEvent(html || '');
};
return (
<div className='introduce-info'>
<div className='introduce-info-header'>机构介绍:</div>
<div className='introduce-info-rich'>
<Row>
<Col span={1}></Col>
<Col span={18}>
<RichText richTextContent={introduceInfo} onChange={onChange} />
</Col>
</Row>
</div>
</div>
);
};
export default IntroduceInfo;
.sku-info{
margin-top: 20px;
&-header{
font-weight: bold;
margin-bottom: 10px;
line-height: 20px;
}
&-table{
}
}
const SkuInfo = () => {
return <div className='sku-info'></div>;
import './index.scss';
import { Button, Col, Form, Row, Table } from 'antd';
import { MinusOutlined, PlusOutlined } from '@ant-design/icons';
import EditableCell from '~/components/EditableCell';
import React, { FC, forwardRef, useEffect, useImperativeHandle, useState } from 'react';
import { PilotTrainAPI } from '~/api';
import { InterDataType } from '~/api/interface';
import {
licenceGradeListType,
licenceModelsListType,
licenceTypeListType,
} from '~/api/interface/pilotTrainType';
type EditableTableProps = Parameters<typeof Table>[0];
type ColumnTypes = Exclude<EditableTableProps['columns'], undefined>;
type tableDataType = {
gradeId: number;
id: number;
mainImage: string;
modelsId: number;
price: number;
typeId: number;
fileList: any[];
};
//机型下拉返回类型
type modelsListType = InterDataType<licenceModelsListType>;
//等级下拉返回类型
type gradeListType = InterDataType<licenceGradeListType>;
//执照类型返回类型
type typeListType = InterDataType<licenceTypeListType>;
interface selfProps {
ref: any;
}
const SkuInfo: FC<selfProps> = forwardRef((props, ref) => {
const [skuForm] = Form.useForm<any>();
//机型下拉列表
const [modelsList, setModelsList] = useState<modelsListType>([]);
//等级下拉列表
const [gradeList, setGradeList] = useState<gradeListType>([]);
//执照类型列表
const [typeList, setTypeList] = useState<typeListType>([]);
const defaultColumns: (ColumnTypes[number] & {
editable?: boolean;
dataIndex?: string;
selectOption?: { name: string; id: number }[];
inputType?: string;
})[] = [
{
title: '序号',
align: 'center',
render: (_text: string, _record, index: number) => index + 1,
width: '10%',
},
{
title: '培训主图',
align: 'center',
dataIndex: 'mainImage',
width: '10%',
inputType: 'uploader',
editable: true,
},
{
title: '培训机型',
align: 'center',
editable: true,
dataIndex: 'modelsId',
inputType: 'select',
width: '15%',
selectOption: modelsList,
},
{
title: '培训等级',
align: 'center',
editable: true,
dataIndex: 'gradeId',
inputType: 'select',
width: '15%',
selectOption: gradeList,
},
{
title: '培训类型',
align: 'center',
editable: true,
dataIndex: 'typeId',
inputType: 'select',
width: '15%',
selectOption: typeList,
},
{
title: '培训价格',
align: 'center',
editable: true,
dataIndex: 'price',
width: '12%',
},
{
title: '操作',
width: '10%',
onHeaderCell: () => {
return {
style: {
textAlign: 'center',
},
};
},
render: (_text: string, record: any, index) => (
<>
{index === tableData.length - 1 ? (
<Button
icon={<PlusOutlined />}
type='primary'
onClick={addTrainSku}
style={{ marginRight: '10px' }}
></Button>
) : (
''
)}
{index ? (
<Button icon={<MinusOutlined />} danger onClick={() => deleteTrainSku(record)}></Button>
) : (
''
)}
</>
),
},
];
const columns = defaultColumns.map((col) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record: any) => ({
record,
editable: col.editable,
dataIndex: col.dataIndex,
title: col.title,
editing: true,
selectOption: col.selectOption,
inputType: col.inputType,
uploadSuccess: col.inputType === 'uploader' ? uploadSuccess : undefined,
}),
};
});
const [tableData, setTableData] = useState<tableDataType[]>([
{
id: Math.random(),
gradeId: -1,
mainImage: '',
modelsId: -1,
price: -1,
typeId: -1,
fileList: [],
},
]);
useImperativeHandle(ref, () => ({
getForm: () => skuForm,
getTableData: () => tableData,
setDefaultDataEvent: () => ({
setDefaultTableData: (value: any) => setTableData(value),
}),
}));
//加一条培训项目
const addTrainSku = () => {
setTableData([
...tableData,
{
id: Math.random(),
gradeId: -1,
mainImage: '',
modelsId: -1,
price: -1,
typeId: -1,
fileList: [],
},
]);
};
//删除一条培训项目
const deleteTrainSku = (record: tableDataType) => {
const index: number = tableData.findIndex((v) => v.id === record.id);
tableData.splice(index, 1);
setTableData([...tableData]);
};
//主图上传
const uploadSuccess = (record: tableDataType, result: any) => {
const index: number = tableData.findIndex((v) => v.id === record.id);
skuForm.setFieldValue('mainImage' + record.id, result[0].url);
tableData[index].mainImage = result[0].url;
tableData[index].fileList = result;
setTableData([...tableData]);
};
//培训机型下拉
const getLicenceModelsList = () => {
PilotTrainAPI.getLicenceModelsList().then(({ result }) => {
setModelsList(result || []);
});
};
//培训等级下拉
const getLicenceGradeList = () => {
PilotTrainAPI.getLicenceGradeList().then(({ result }) => {
setGradeList(result || []);
});
};
//培训类型下拉
const getLicenceTypeList = () => {
PilotTrainAPI.getLicenceTypeList().then(({ result }) => {
setTypeList(result || []);
});
};
useEffect(() => {
getLicenceModelsList();
getLicenceGradeList();
getLicenceTypeList();
}, []);
return (
<div className='sku-info'>
<div className='sku-info-header'>培训项目:</div>
<div className='sku-info-table'>
<Row>
<Col span={1}></Col>
<Col span={18}>
<Form form={skuForm} component={false}>
<Table
size='small'
rowKey='id'
bordered
columns={columns as ColumnTypes}
components={{
body: {
cell: EditableCell,
},
}}
dataSource={tableData}
pagination={false}
/>
</Form>
</Col>
</Row>
</div>
</div>
);
});
export default SkuInfo;
.institution-form{
&-operate{
height: 100px;
display: flex;
align-items: center;
justify-content: center;
button{
width: 100px;
height: 50px;
}
button:first-child{
margin-right: 50px;
}
}
}
import BaseInfo from './components/baseInfo';
import SkuInfo from './components/skuInfo';
import IntroduceInfo from './components/introduceInfo';
import './index.scss';
import { Button, message } from 'antd';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { useEffect, useRef, useState } from 'react';
import { PilotTrainAPI } from '~/api';
import { InterDataType } from '~/api/interface';
import { listOrgPageType } from '~/api/interface/pilotTrainType';
//sku类型
type tableDataType = {
gradeId: number;
id: number;
mainImage: string;
modelsId: number;
price: number;
typeId: number;
fileList: any[];
};
//机构列表返回类型
type institutionListType = InterDataType<listOrgPageType>['list'];
const AddOrEditInstitution = () => {
const baseRef = useRef<any>();
const skuRef = useRef<any>();
const navigate = useNavigate();
const [searchParams] = useSearchParams();
//机构介绍
const [introduceInfo, setIntroduceInfo] = useState<string>('');
//机构id
const [institutionId, setInstitutionId] = useState<number | undefined>(-1);
//机构详情
const [institutionDetail, setInstitutionDetail] = useState<institutionListType[0]>();
const setIntroduceInfoEvent = (html: string) => {
setIntroduceInfo(html);
};
//保存
const saveDataClick = () => {
Promise.all([
baseRef.current.getForm().validateFields(),
skuRef.current.getForm().validateFields(),
])
.then((value) => {
const skuReqData = skuRef.current.getTableData().map((v: tableDataType) => {
return Object.getOwnPropertyNames(v).reduce((pre: any, cur: string) => {
if (Object.getOwnPropertyNames(value[1]).includes(cur + v.id)) {
pre[cur] = value[1][cur + v.id];
}
return pre;
}, {});
});
PilotTrainAPI[institutionId ? 'updateOrg' : 'insertOrg']({
...value[0],
trainingProgramsVOS: skuReqData,
detail: introduceInfo,
longitude: baseRef.current.getPosition().lon,
latitude: baseRef.current.getPosition().lat,
detailedAddress: baseRef.current.getPosition().address,
id: institutionId || undefined,
}).then(({ code }) => {
if (code === '200') {
message.success(institutionId ? '编辑机构成功' : '上传机构成功');
navigate(-1);
}
});
})
.catch((error) => {
message.warning(error.errorFields[0].errors[0]);
});
};
//机构详情
const getOrgPageDetail = (id: number) => {
PilotTrainAPI.getListOrgPage({ pageNo: 1, pageSize: 10, id }).then(({ result }) => {
if (result.list) {
setInstitutionDetail({ ...result.list[0] });
}
});
};
//返回
const backRoute = () => {
navigate(-1);
};
useEffect(() => {
if (searchParams.get('id')) {
getOrgPageDetail(Number(searchParams.get('id')));
setInstitutionId(Number(searchParams.get('id')));
} else {
setInstitutionId(undefined);
}
}, []);
useEffect(() => {
if (institutionDetail) {
baseRef.current.getForm().setFieldsValue({
mainImage: institutionDetail.mainImage,
auxiliaryPicture: institutionDetail.auxiliaryPicture,
video: institutionDetail.video,
name: institutionDetail.name,
region: institutionDetail.region,
testCenter: institutionDetail.testCenter,
scaleId: institutionDetail.scaleId || undefined,
description: institutionDetail.description || undefined,
});
baseRef.current.getDefaultDataEvent().setPosition({
lat: institutionDetail.latitude,
lon: institutionDetail.longitude,
address: institutionDetail.detailedAddress,
adCode: institutionDetail.region.split(',')[1],
});
baseRef.current.getDefaultDataEvent().setMainImgList([
{
id: Math.random(),
uid: Math.random(),
url: institutionDetail.mainImage,
name: 'mainImage',
},
]);
baseRef.current.getDefaultDataEvent().setSubImgList(
institutionDetail.auxiliaryPicture.split(',').map((v: string) => ({
id: Math.random(),
uid: Math.random(),
url: v,
name: 'auxiliaryPicture',
})),
);
baseRef.current.getDefaultDataEvent().setVideoList([
{
id: Math.random(),
uid: Math.random(),
url: institutionDetail.video,
name: 'video',
},
]);
const programsList = institutionDetail.programsDOList.map((v) => ({
...v,
fileList: [
{
id: Math.random(),
uid: Math.random(),
name: 'img',
url: v.mainImage,
},
],
}));
skuRef.current.setDefaultDataEvent().setDefaultTableData(programsList);
const skuObj = institutionDetail.programsDOList.reduce((pre: any, cur: any) => {
Object.getOwnPropertyNames(cur)
.filter((key: string) => key !== 'id')
.forEach((v: string) => {
pre[v + cur.id] = cur[v];
});
return pre;
}, {});
skuRef.current.getForm().setFieldsValue(skuObj);
setIntroduceInfo(institutionDetail.detail);
}
}, [institutionDetail]);
return (
<div className='institution-form'>
<BaseInfo />
<BaseInfo ref={baseRef} />
<SkuInfo ref={skuRef} />
<IntroduceInfo setIntroduceInfoEvent={setIntroduceInfoEvent} introduceInfo={introduceInfo} />
<div className='institution-form-operate'>
<Button type='primary' onClick={saveDataClick}>
保存
</Button>
<Button onClick={backRoute}>返回</Button>
</div>
</div>
);
};
......
import SearchBox, { searchColumns } from '~/components/search-box';
import { Button, Table } from 'antd';
import { Button, message, Modal, Table, Tag } from 'antd';
import { ColumnsType } from 'antd/es/table';
import { PlusOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { PilotTrainAPI } from '~/api';
import { useEffect, useState } from 'react';
import { InterDataType, PaginationProps } from '~/api/interface';
import { listOrgPageType } from '~/api/interface/pilotTrainType';
//机构列表返回类型
type institutionListType = InterDataType<listOrgPageType>['list'];
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> = [
const tableColumns: ColumnsType<institutionListType[0]> = [
{
title: '序号',
align: 'center',
render: (_text: string, _record, index: number) =>
(pagination.pageNo - 1) * pagination.pageSize + index + 1,
},
{
title: '机构名称',
align: 'center',
dataIndex: 'name',
},
{
title: '培训类型',
align: 'center',
render: (_text: string, record) =>
record.programsDOList.map((v) => <Tag key={v.id}>{v.typeName}</Tag>),
width: '20%',
},
{
title: '创建日期',
dataIndex: 'createTime',
align: 'center',
},
{
title: '操作',
align: 'center',
render: (_text: string, record) => (
<>
<Button type='link' onClick={() => editInstitutionsClick(record)}>
编辑
</Button>
<Button type='link' danger onClick={() => deleteInstitutionsClick(record)}>
删除
</Button>
</>
),
},
];
const [tableData, setTableData] = useState<institutionListType>([]);
const [pagination, setPagination] = useState<PaginationProps & { totalCount: number }>({
pageNo: 1,
pageSize: 10,
totalCount: 0,
});
const toAddInstitutions = () => {
navigate('/pilotTraining/institutionsList/add');
};
//机构列表
const getListOrgPage = () => {
PilotTrainAPI.getListOrgPage({ pageNo: pagination.pageNo, pageSize: pagination.pageSize }).then(
({ result }) => {
setTableData(result.list || []);
pagination.totalCount = result.totalCount;
setPagination(pagination);
},
);
};
//分页-监听
const paginationChange = (pageNo: number, pageSize: number) => {
pagination.pageNo = pageNo;
pagination.pageSize = pageSize;
getListOrgPage();
};
//机构删除
const deleteInstitutionsClick = (record: institutionListType[0]) => {
Modal.confirm({
title: '删除机构',
content: '确认删除该机构吗?',
onOk: () => {
PilotTrainAPI.removeOrg({ id: record.id }).then(({ code }) => {
if (code === '200') {
message.success('删除成功');
if (pagination.pageNo !== 1 && tableData.length === 1) {
pagination.pageNo -= 1;
}
getListOrgPage();
}
});
},
});
};
//机构编辑
const editInstitutionsClick = (record: institutionListType[0]) => {
navigate({ pathname: '/pilotTraining/institutionsList/edit', search: `id=${record.id}` });
};
useEffect(() => {
getListOrgPage();
}, []);
return (
<div className='institutions-list'>
<SearchBox
......@@ -46,7 +120,20 @@ const InstitutionsList = () => {
</Button>
}
/>
<Table bordered columns={tableColumns} />
<Table
bordered
columns={tableColumns}
dataSource={tableData}
pagination={{
total: pagination.totalCount,
pageSize: pagination.pageSize,
current: pagination.pageNo,
showSizeChanger: true,
showQuickJumper: true,
onChange: (page: number, pageSize: number) => paginationChange(page, pageSize),
showTotal: (total, range) => `当前 ${range[0]}-${range[1]} 条记录 / 共 ${total} 条数据`,
}}
/>
</div>
);
};
......
......@@ -34,6 +34,7 @@ const bannerType = [
// { label: '红包', value: 7 },
{ label: '链接', value: 8 },
{ label: '富文本', value: 11 },
{ label: '分享', value: 12 },
];
const AddEditModal: React.FC<propType> = (props) => {
......@@ -234,6 +235,8 @@ const AddEditModal: React.FC<propType> = (props) => {
wrapperCol={{ span: 20 }}
>
<RichText
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
value={form.getFieldValue('textContent')}
onChange={(e) => form.setFieldValue('textContent', e)}
height={250}
......
......@@ -37,6 +37,7 @@ const bannerType = [
// { label: '红包', value: 7 },
{ label: '链接', value: 8 },
{ label: '富文本', value: 11 },
{ label: '分享', value: 12 },
];
// 全部数据
// let tableDataAll: TableType = [];
......
......@@ -110,13 +110,13 @@ function AccountManageView() {
width: '150px',
fixed: 'left',
},
{
title: '账号类型',
dataIndex: 'companyInfoVO',
align: 'center',
width: '10%',
render: (_text, record) => (record?.companyInfoVO?.companyType === 1 ? '合伙人' : '员工'),
},
// {
// title: '账号类型',
// dataIndex: 'companyInfoVO',
// align: 'center',
// width: '10%',
// render: (_text, record) => (record?.companyInfoVO?.companyType === 1 ? '合伙人' : '员工'),
// },
{ title: '姓名', dataIndex: 'userName', align: 'center', width: '10%' },
{
title: '所属单位',
......@@ -125,12 +125,12 @@ function AccountManageView() {
width: '150px',
ellipsis: true,
},
{
title: '渠道等级',
dataIndex: 'channelLevel',
align: 'center',
width: '150px',
},
// {
// title: '渠道等级',
// dataIndex: 'channelLevel',
// align: 'center',
// width: '150px',
// },
{
title: '角色',
align: 'center',
......@@ -157,12 +157,12 @@ function AccountManageView() {
width: '10%',
render: (text) => (text === 1 ? '可用' : '停用'),
},
{
title: '企业实名认证',
dataIndex: 'companyAuthStatus',
align: 'center',
width: '10%',
},
// {
// title: '企业实名认证',
// dataIndex: 'companyAuthStatus',
// align: 'center',
// width: '10%',
// },
{
title: '操作',
width: '160px',
......@@ -212,16 +212,16 @@ function AccountManageView() {
type: 'input',
placeholder: '请输入姓名或账号',
},
{
label: '账号类型',
name: 'userType',
type: 'Select',
placeholder: '请选择账号类型',
options: [
{ value: 1, label: '员工' },
{ value: 0, label: '合伙人' },
],
},
// {
// label: '账号类型',
// name: 'userType',
// type: 'Select',
// placeholder: '请选择账号类型',
// options: [
// { value: 1, label: '员工' },
// { value: 0, label: '合伙人' },
// ],
// },
{
label: '角色',
name: 'roleId',
......
......@@ -7,26 +7,38 @@ import Cookies from 'js-cookie';
//菜单类型
type menuType = InterDataType<listMenuInfoType>;
// 缓存路由列表
let routerListStore: any[] = [];
// 获取用户权限路由列表
export const authRouterList = async () => {
if (localStorage.getItem('roleId') && Cookies.get('SHAREFLY-TOKEN')) {
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)];
// 如果缓存中没有数据
if (routerListStore.length === 0) {
// 加载路由数据
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 || Obj.path?.includes('pilotTraining')) {
if (Obj.children) {
Obj.children = [...getRouteList(Obj.children)];
}
pre.push(Obj);
}
pre.push(Obj);
}
return pre;
}, []);
};
return Promise.resolve([...getRouteList(routerList)]);
return pre;
}, []);
};
const arr = [...getRouteList(routerList)];
// 将路由数据存到store中
routerListStore = arr;
// 完成后返回路由数据
return Promise.resolve(arr);
} else {
return Promise.resolve(routerListStore);
}
}
return Promise.resolve([]);
};
......
......@@ -102,14 +102,14 @@ const CategoryDetail = React.lazy(() => import('~/pages/categoryManage/category/
// 目录管理
const DirectoryManage = React.lazy(() => import('~/pages/categoryManage/directoryManage'));
//飞手培训
const InstitutionsListView = React.lazy(
() => import('~/pages/pilotTraining/ licensureExamination/institutionsList'),
);
//机构上传
const AddInstitutionsView = React.lazy(
() => import('~/pages/pilotTraining/ licensureExamination/addOrEditInstitution'),
);
// //飞手培训
// const InstitutionsListView = React.lazy(
// () => import('~/pages/pilotTraining/ licensureExamination/institutionsList'),
// );
// //机构上传
// const AddInstitutionsView = React.lazy(
// () => import('~/pages/pilotTraining/ licensureExamination/addOrEditInstitution'),
// );
// 系统管理
import AccountManageView from '~/pages/systemManage/accountManage';
......@@ -120,7 +120,8 @@ import BusinessCaseManage from '~/pages/resourceManage/businessCaseManage';
import CustomIdentityView from '~/pages/customManage/customIdentity';
import CompanyManageView from '~/pages/systemManage/companyManage';
import AccountLimit from '~/pages/systemManage/limitManage/roleList'; //账号权限
import LimitInfo from '~/pages/systemManage/limitManage/limitInfo'; //权限信息
import LimitInfo from '~/pages/systemManage/limitManage/limitInfo';
import CustomListDetail from '~/pages/customManage/customList/detail'; //权限信息
// const IndustryListView = React.lazy(() => import('~/pages/mallManage/industryManage/industryList')); //行业列表
// const IndustryDetailView = React.lazy(
......@@ -198,6 +199,17 @@ export const routerList: Array<RouteObjectType> = [
},
},
{
path: '/customManage/customList/detail',
element: withLoadingComponent(<CustomListDetail />),
errorElement: <ErrorPage />,
meta: {
id: 220,
title: '邀请列表',
icon: <SolutionOutlined />,
hidden: true,
},
},
{
path: '/customManage/customMoney',
element: withLoadingComponent(<CustomMoneyView />),
errorElement: <ErrorPage />,
......@@ -883,39 +895,50 @@ export const routerList: Array<RouteObjectType> = [
// },
// ],
// },
{
path: '/pilotTraining',
element: <LayoutView />,
errorElement: <ErrorPage />,
meta: {
id: 1500,
icon: <SettingOutlined />,
title: '飞手培训',
},
children: [
{
path: '/pilotTraining/institutionsList',
element: withLoadingComponent(<InstitutionsListView />),
errorElement: <ErrorPage />,
meta: {
id: 1510,
title: '执照考试',
icon: <UserOutlined />,
},
},
{
path: '/pilotTraining/institutionsList/add',
element: withLoadingComponent(<AddInstitutionsView />),
errorElement: <ErrorPage />,
meta: {
id: 1520,
title: '机构上传',
icon: <UserOutlined />,
hidden: true,
},
},
],
},
// {
// path: '/pilotTraining',
// element: <LayoutView />,
// errorElement: <ErrorPage />,
// meta: {
// id: 1500,
// icon: <BankOutlined />,
// title: '飞手培训',
// },
// children: [
// {
// path: '/pilotTraining/institutionsList',
// element: withLoadingComponent(<InstitutionsListView />),
// errorElement: <ErrorPage />,
// meta: {
// id: 1510,
// title: '执照考试',
// icon: <VerifiedOutlined />,
// },
// },
// {
// path: '/pilotTraining/institutionsList/add',
// element: withLoadingComponent(<AddInstitutionsView />),
// errorElement: <ErrorPage />,
// meta: {
// id: 1520,
// title: '机构上传',
// icon: <UserOutlined />,
// hidden: true,
// },
// },
// {
// path: '/pilotTraining/institutionsList/edit',
// element: withLoadingComponent(<AddInstitutionsView />),
// errorElement: <ErrorPage />,
// meta: {
// id: 1530,
// title: '机构编辑',
// icon: <UserOutlined />,
// hidden: true,
// },
// },
// ],
// },
{
path: '/systemManage',
element: <LayoutView />,
......@@ -943,7 +966,7 @@ export const routerList: Array<RouteObjectType> = [
meta: {
id: 1420,
title: '权限角色',
icon: <UserOutlined />,
icon: <TeamOutlined />,
},
},
{
......
......@@ -89,7 +89,7 @@ video {
border: 0;
font-size: 100%;
//font: inherit;
vertical-align: baseline;
//vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article,
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论