提交 fb69fdf3 作者: 龚洪江

功能,机构联调

上级 9cc2c40f
......@@ -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,
};
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
>;
import {
insertOrgType,
licenceGradeListType,
licenceModelsListType,
licenceScaleList,
licenceTypeListType,
listOrgPageType,
removeOrgType,
updateOrg,
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);
}
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
......
......@@ -24,7 +24,12 @@ const SelectMapModal: FC<propType> = (props) => {
clearMarker: () => void;
}>(null);
// 位置信息
const [position, setPosition] = useState<{ lat: number; lon: number; address: string }>();
const [position, setPosition] = useState<{
lat: number;
lon: number;
address: string;
adCode: number;
}>();
// 搜索地点
const [addressList, setAddressList] = useState<{ label: string; value: number; data: any }[]>();
// 取消事件
......@@ -50,7 +55,7 @@ const SelectMapModal: FC<propType> = (props) => {
// 选择了地址
const handleSearchAddress = (e: number) => {
if (e) {
// console.log(addressList?.[e].data);
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 });
......@@ -58,6 +63,7 @@ const SelectMapModal: FC<propType> = (props) => {
lat: lat,
lon: lng,
address: `${addressList?.[e].data.name}`,
adCode: addressList?.[e].data.adcode,
});
} else {
childRef.current?.clearMarker();
......@@ -102,6 +108,7 @@ const SelectMapModal: FC<propType> = (props) => {
lat: e.lat,
lon: e.lng,
address: e.formattedAddress,
adCode: Number(e.adcode),
});
}}
onSearchAddress={(e) => {
......
......@@ -93,7 +93,7 @@ class MapComponent extends Component<MapComponentProps> {
if (status === 'complete' && result.info === 'OK') {
// result为对应的地理位置详细信息
const { formattedAddress, addressComponent } = result.regeocode;
// console.log('点击选择-->', status, result);
console.log('点击选择-->', status, result);
this.props.onSelectAddress({
lat,
lng,
......
......@@ -44,9 +44,7 @@ function LoginView() {
} else {
message.warning('请先配置权限');
}
//获取第一个路由
});
// 获取第一个路由
} else {
message.error('登录失败,请检查账号信息');
}
......
.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>(-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')));
}
}, []);
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>
);
};
......
......@@ -3,12 +3,13 @@ import { RouteObjectType, routerList } from '~/router/router';
import { InterDataType } from '~/api/interface';
import { listMenuInfoType } from '~/api/interface/systemManageType';
import { SystemManageAPI } from '~/api';
import Cookies from 'js-cookie';
//菜单类型
type menuType = InterDataType<listMenuInfoType>;
// 获取用户权限路由列表
export const authRouterList = async () => {
if (localStorage.getItem('roleId')) {
if (localStorage.getItem('roleId') && Cookies.get('SHAREFLY-TOKEN')) {
const { result } = await SystemManageAPI.getListRoleMenuInfo({
roleId: Number(localStorage.getItem('roleId')),
});
......@@ -16,7 +17,7 @@ export const authRouterList = async () => {
const getRouteList = (data: RouteObjectType[]) => {
return data.reduce((pre: RouteObjectType[], cur) => {
const Obj: RouteObjectType = { ...cur };
if (ids.includes(Obj.meta.id) || Obj.meta.hidden) {
if (ids.includes(Obj.meta.id) || Obj.meta.hidden || Obj.path?.includes('pilotTraining')) {
if (Obj.children) {
Obj.children = [...getRouteList(Obj.children)];
}
......
......@@ -914,6 +914,17 @@ export const routerList: Array<RouteObjectType> = [
hidden: true,
},
},
{
path: '/pilotTraining/institutionsList/edit',
element: withLoadingComponent(<AddInstitutionsView />),
errorElement: <ErrorPage />,
meta: {
id: 1530,
title: '机构编辑',
icon: <UserOutlined />,
hidden: true,
},
},
],
},
{
......
......@@ -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,
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论