

上传回显:

上传预览:

预览-删除

react 函数式组件
- /**
- * @Author
- * @Date Created in 2024/04/11 15:20
- * @DESCRIPTION: 主讲人信息
- * @Version V1.0
- */
- import React, {useEffect, useId, useState} from "react";
- import {
- Button,
- Col,
- DatePicker,
- Form,
- Image,
- Input,
- message,
- Modal,
- Pagination,
- Popconfirm, Popover,
- Row,
- Select,
- Space,
- Spin,
- Switch,
- Table,
- Tooltip,
- Typography,
- Upload
- } from "antd";
- import {
- deletePhoto,
- deleteSpeaker,
- getAllSpeaker,
- getSpeakerByPage,
- getSpeakerDepartment,
- getSpeakerDetail,
- getVisibleCollege,
- insertOrUpdateSpeaker,
- updateIsUse,
- uploadPhotoApi
- } from "api/index.js";
- import {useNavigate} from "react-router-dom";
- import {LeftOutlined, PlusOutlined} from "@ant-design/icons";
- import TextArea from "antd/es/input/TextArea.js";
- import MyUpload from "@/components/Upload/index.js";
-
- const {Title, Text} = Typography;
- const {RangePicker} = DatePicker;
- const getBase64 = (file) =>
- new Promise((resolve, reject) => {
- const reader = new FileReader();
- reader.readAsDataURL(file);
- reader.onload = () => resolve(reader.result);
- reader.onerror = (error) => reject(error);
- });
-
- export default () => {
- const [screeningForm] = Form.useForm();
- const [myModalForm] = Form.useForm();
- const [modalForm] = Form.useForm();
- const navigate = useNavigate();
- const [base64Data, setBase64Data] = useState(""); // 用于保存原始的 base64 数据
-
- const [isShowModal, setIsShowModal] = useState(false);
- const [resetPageSize, setResetPageSize] = useState(10);
- const [currentPage, setCurrentPage] = useState(1);
- const [currentPageSize, setCurrentPageSize] = useState(10);
- const [isInsert, setIsInsert] = useState(true);
- const [tableSource, setTableSource] = useState([])
- const [tableSourceDetail, setTableSourceDetail] = useState([])
- const [departmentOptions, setDepartmentOptions] = useState([])
- const [isUpdateShow, setIsUpdateShow] = useState(false);
- const [name, setName] = useState();
- const [nameId, setNameId] = useState();
- const [photoData, setPhotoData] = useState();
- const [isLoading,setIsLoading] = useState(false);
- // 参与讲座详情 分页参数
- const [detailParam, setDetailParam] = useState({});
- const [detailPage, setDetailPage] = useState(1);
- const [detailPageSize, setDetailPageSize] = useState(5);
- const detailPageChange = (pageNo, pageSize) => {
- setDetailPage(pageNo)
- setDetailPageSize(pageSize)
- const param = {
- ...detailParam,
- pageNum: pageNo,
- pageSize: pageSize,
- }
- getSpeakerDetail(param).then(res => {
- if (res.code === 200) {
- setTableSourceDetail(res.data)
- }
- })
- };
-
- const detailPageSizeChange = (current, pageSize) => {
- setDetailPage(current)
- setDetailPageSize(pageSize)
- }
-
- /// 上传相关 2 个 state
-
- const [tableList, setTableList] = useState(
- {
- "foreignSchool": '0',
- "name": null,
- "isUse": 0,
- "pageNum": 1,
- "pageSize": 10,
- "speakerTotal": null,
- });
- const speakerDetail = [
- {
- title: '讲座名称',
- dataIndex: 'speakerName',
- key: 'speakerName',
- width: 200,
- align: "center"
- },
- {
- title: '举办时间',
- dataIndex: 'holdingTime',
- key: 'holdingTime',
- width: 300,
- align: "center"
- },
- ]
- const tableColumns = [
- {
- title: '主讲人姓名',
- dataIndex: 'name',
- key: 'name',
- width: 120,
- render: (text) => (
- <Tooltip title={text}>
- <div
- style={{
- color: 'black',
- overflow: 'hidden',
- whiteSpace: 'nowrap',
- textOverflow: 'ellipsis',
- maxWidth: '30ch', // 设置超出部分的背景颜色
- }}
- >
- {text}
- div>
- Tooltip>
- ),
- },
- {
- title: '职工号',
- dataIndex: 'userId',
- key: 'userId',
- width: 120,
- render: (text) => (
- <Tooltip title={text}>
- <div
- style={{
- color: 'black',
- overflow: 'hidden',
- whiteSpace: 'nowrap',
- textOverflow: 'ellipsis',
- maxWidth: '30ch', // 设置超出部分的背景颜色
- }}
- >
- {text}
- div>
- Tooltip>
- ),
- },
- {
- title: '所属学院/单位',
- dataIndex: 'department',
- key: 'department',
- width: 150,
- render: (text) => (
- <Tooltip title={text}>
- <div
- style={{
- color: 'black',
- overflow: 'hidden',
- whiteSpace: 'nowrap',
- textOverflow: 'ellipsis',
- maxWidth: '10ch', // 设置超出部分的背景颜色
- }}
- >
- {text}
- div>
- Tooltip>
- ),
- },
- {
- title: '职务',
- dataIndex: 'job',
- key: 'job',
- width: 100,
- render: (text) => (
- <Tooltip title={text}>
- <div
- style={{
- color: 'black',
- overflow: 'hidden',
- whiteSpace: 'nowrap',
- textOverflow: 'ellipsis',
- maxWidth: '10ch', // 设置超出部分的背景颜色
- }}
- >
- {text}
- div>
- Tooltip>
- ),
- },
- {
- title: '专业领域',
- dataIndex: 'professionalField',
- key: 'professionalField',
- width: 150,
- render: (text) => (
- <Tooltip title={text}>
- <div
- style={{
- color: 'black',
- overflow: 'hidden',
- whiteSpace: 'nowrap',
- textOverflow: 'ellipsis',
- maxWidth: '10ch', // 设置超出部分的背景颜色
- }}
- >
- {text}
- div>
- Tooltip>
- ),
- },
- {
- title: '个人简介',
- dataIndex: 'personalProfile',
- key: 'personalProfile',
- width: 150,
- render: (text) => (
- <Popover
- color= '#252525'
- content={
- <div style={{ maxWidth: '300px',
- maxHeight: '300px',
- color: 'white',
- overflowY: 'auto',}}>
- {text}
- div>
- }
- trigger="hover" >
- <div
- style={{
- color: 'black',
- overflow: 'hidden',
- whiteSpace: 'nowrap',
- textOverflow: 'ellipsis',
- maxWidth: '10ch', // 设置超出部分的背景颜色
- }}
- >
- {text}
- div>
- Popover>
- ),
- },
- {
- title: '参与讲座',
- dataIndex: 'speakerTotal',
- key: 'speakerTotal',
- width: 120,
- align: "center",
- render: (text, record, index) => {
- return (
- <Space size="middle">
- <a onClick={event => {
- mySpeakerDetail(record);
- }}>{text || 0}场a>
- Space>
- )
- }
- },
- {
- title: '可见学院/单位',
- dataIndex: 'visibleCollege',
- key: 'visibleCollege',
- width: 150,
- render: (text) => (
- <Tooltip title={text}>
- <div
- style={{
- color: 'black',
- overflow: 'hidden',
- whiteSpace: 'nowrap',
- textOverflow: 'ellipsis',
- maxWidth: '10ch', // 设置超出部分的背景颜色
- }}
- >
- {text}
- div>
- Tooltip>
- ),
- },
- {
- title: '照片',
- dataIndex: 'photoNumber',
- key: 'photoNumber',
- width: 150,
- align: "center",
- render: (photoNumber) => (
- photoNumber ? (
- <Image
- src={photoNumber}
- alt="--"
- style={{maxWidth: '100px', maxHeight: '100px', cursor: 'pointer'}}
- />
- ) : (
- <span>span>
- )
- ),
- },
- {
- title: '开启有效',
- dataIndex: 'isUse',
- key: 'isUse',
- width: 150,
- align: "center",
- render: (text, record, index) => {
- return (
- <span>
- <Switch checked={text === "1"} onClick={(e) => {
- switchChange(record);
- }}/>
- span>
- )
- }
- },
- {
- title: "操作",
- key: "action",
- width: 150,
- render: (text, record, index) => {
- return (
- <Space size="middle">
- <a onClick={event => {
- updateShowModal(record);
- }}>修改a>
- {record.isUse === "0" && (
- <Popconfirm
- description="确定要删除吗?"
- onConfirm={confirm.bind(this, record)}
- onCancel={cancel}
- okText="删除"
- cancelText="取消"
- >
- <a>删除a>
- Popconfirm>
- )}
- Space>
- )
- }
- }
- ];
-
- const [modalVisible, setModalVisible] = useState(false);
- const [modalImage, setModalImage] = useState('');
-
- const showModal = (image) => {
- setModalVisible(true);
- setModalImage(image);
- };
- const cancel = (e) => {
- // console.log(e);
- // message.info('取消删除');
- };
- const handleModalClose = () => {
- setModalVisible(false);
- };
- //控制 保存按钮 是否被禁用
- const [isDisableSave, setIsDisableSave] = useState(false)
- const beforeUpload = (file) => {
- const isJpgOrPng = file.type === 'image/jpeg'
- || file.type === 'image/png'
- || file.type === 'image/jpg'
- || file.type === 'image/webp';
- if (!isJpgOrPng) {
- message.error('上传失败!');
- setIsDisableSave(true)
- return false;
- }
- const isLt2M = file.size / 1024 / 1024 < 5;
- if (!isLt2M) {
- message.error('照片大小不能超过5M!');
- setIsDisableSave(true)
- return false;
- }
- };
- //获取分页信息
- useEffect(() => {
- getSpeakerByPage(tableList).then((res) => {
- if (res.code === 200) {
- setTableSource(res.data)
- } else {
- message.error(res.data)
- }
- });
-
- }, [tableList]);
- //更新状态是否失效
- const switchChange = (record) => {
- record.isUse === "1" ? record.isUse = "0" : record.isUse = "1";
- // 在这里可以进行其他操作,比如更新数据或发送请求
- updateIsUse(record).then((res) => {
- if (res.code === 200) {
- message.success("修改成功")
- setTableList({
- "foreignSchool": '0',
- "name": null,
- "isUse": 0,
- "pageNum": 1,
- "pageSize": 10,
- "speakerTotal": null,
- })
- } else {
- message.error("修改失败")
- }
- })
- }
- // 删除弹窗
- const confirm = (record) => {
- const param = {
- ...record,
- foreignSchool: "0"
- }
- deleteSpeaker(param).then(res => {
- if (res.code === 200) {
- message.success('删除成功');
- setTableList({
- "foreignSchool": '0',
- "name": null,
- "isUse": 0,
- "pageNum": 1,
- "pageSize": 10,
- "speakerTotal": null,
- })
- } else {
- message.error("删除失败:" + res.message);
- }
- })
- };
- const onScreeningFormFinish = (values) => {
- setTableList({
- "foreignSchool": '0',
- "name": values.name,
- "isUse": 0,
- "pageNum": currentPage,
- "pageSize": currentPageSize,
- "speakerTotal": values.speakerTotal,
- })
- };
- // 分页
- const onPageChange = (pageNo, pageSize) => {
- setCurrentPage(pageNo)
- setCurrentPageSize(pageSize)
- setTableList({
- "foreignSchool": '0',
- "pageNum": pageNo,
- "pageSize": pageSize
- });
- };
-
- const pageSizeChange = (current, pageSize) => {
- setCurrentPage(current)
- setResetPageSize(pageSize)
- setCurrentPageSize(pageSize)
- }
- const onChange = (e) => {
- console.log(e);
- };
- const onScreeningFormFinishFailed = (errorInfo) => {
- message.error("信息有误,请仔细检查后重新提交!").then(r => {
- });
- };
- //详情:
- const mySpeakerDetail = (record) => {
- setTableSourceDetail([])
- setIsShowModal(true)
- const param = {
- ...record,
- pageNum: 1,
- pageSize: 5,
- }
- setDetailParam(record)
- getSpeakerDetail(param).then(res => {
- if (res.code === 200) {
- setTableSourceDetail(res.data)
- }
- })
-
- }
- //修改
- const updateShowModal = (record) => {
- setName(record.name)
- setNameId(record.userId)
- modalForm.resetFields();
- setIsUpdateShow(true)
- // 将照片置空
- setBase64Data("")
- setPreviewImage('');
- setFileList([])
- //赋值操作
- modalForm.setFieldValue("id", record.id)
- modalForm.setFieldValue("userId", record.userName);
- modalForm.setFieldValue("departmentId", record.department);
- modalForm.setFieldValue("job", record.job);
- modalForm.setFieldValue("professionalField", record.professionalField);
- modalForm.setFieldValue("personalProfile", record.personalProfile);
- const strings = record.visibleCollege.split(',');
- modalForm.setFieldValue("visibleCollege", strings)
-
- if (record.photoNumber !== null && record.photoNumber !== undefined) {
- const uid = Math.random().toString(36).substring(7); // 生成唯一 ID
- const blob = dataURItoBlob(record.photoNumber);
- const fileObj = new File([blob], 'image.png', {type: 'image/png'});
- setFileList([{uid: uid, name: 'image.png', status: 'done', url: record.photoNumber}]); // 将文件对象添加到 fileList 中
- setBase64Data(record.photoNumber)
- } else {
- setBase64Data("")
- setPreviewImage('')
- }
- setIsInsert(false)
- }
- const dataURItoBlob = dataURI => {
- const byteString = atob(dataURI.split(',')[1]);
- const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
- const ab = new ArrayBuffer(byteString.length);
- const ia = new Uint8Array(ab);
- for (let i = 0; i < byteString.length; i++) {
- ia[i] = byteString.charCodeAt(i);
- }
- return new Blob([ab], {type: mimeString});
- };
-
- const handleOk = () => {
- myModalForm.submit();
- };
- const goInsert = () => {
- modalForm.resetFields();
- setBase64Data("")
- setKey({})
- setFileList([])
- setIsInsert(false)
- };
- //返回
- const goSpeaker = () => {
- setIsUpdateShow(false)
- setPreviewImage('')
- setBase64Data("");
- setIsDisableSave(false)
- // navigate('/lectureManagement/mainSpeakerManagement/insertAfterSchool', {});
- if (key !== null && Object.keys(key).length !== 0) {
- deletePhoto(key).then((res) => {
- if (res.code === 200) {
- setKey({})
- }
- });
- }
- setIsInsert(true)
- };
- //重置
- const resetScreeningForm = () => {
- // 重置 pageSizeOptions
- setIsDisableSave(false)
- setIsUpdateShow(false)
- setBase64Data("")
- setIsInsert(true)
- setTableList({
- "foreignSchool": '0',
- "name": null,
- "isUse": 0,
- "pageNum": 1,
- "pageSize": 10,
- "speakerTotal": null,
- })
- setResetPageSize(10)
- screeningForm.resetFields()
- };
- // 弹窗取消按钮事件
- const handleCancel = () => {
- setDetailParam({})
- setIsShowModal(false);
- };
- const onFormValuesChanged = (changedValues, allValues) => {
- }
- const [loadings, setLoadings] = useState([]);
- const onModalFormFinish = (values) => {
- // 创建定时器并保存标识符
- setLoadings((prevLoadings) => {
- const newLoadings = [...prevLoadings];
- newLoadings[1] = true;
- return newLoadings;
- });
-
- const param = {
- ...values,
- id: values.id,
- name: values.userId || name,
- visibleCollege: values.visibleCollege.join(','),
- photoNumber: key.objectKey,
- userId: values.userId.value || nameId,
- }
- insertOrUpdateSpeaker(param).then(res => {
- if (res.data === true) {
- if (param.id === null || param.id === undefined) {
- setIsInsert(true)
- message.success("新增成功")
- } else {
- setIsInsert(true)
- message.success("修改成功")
- }
- setTableList({
- "foreignSchool": '0',
- "name": null,
- "isUse": 0,
- "pageNum": 1,
- "pageSize": 10,
- "speakerTotal": null,
- });
- setIsUpdateShow(false)
- setFileList([])
- myModalForm.resetFields()
- } else {
- message.error("主讲人信息重复!")
- }
- })
- setTimeout(() => {
- setLoadings((prevLoadings) => {
- const newLoadings = [...prevLoadings];
- newLoadings[1] = false;
- return newLoadings;
- });
- }, 1000);
- }
- const onModalFormFinishFailed = (errorInfo) => {
- message.error("信息有误,请仔细检查后重新提交!");
- };
- /// 输入框
- const [searchValue, setSearchValue] = useState();
- const [searching, setSearching] = useState(false);
- const [turnUser, setTurnUser] = useState([]);
- const [turnUserList, setTurnUserList] = useState([]);
- const [selectOption, setSelectOption] = useState([]);
- const [visibleCollegeList, setVisibleCollegeList] = useState([]);
-
- const changeTurnUser = (value, option) => {
- //解决方法,先把整个表单置空,然后再给第一个 下拉框赋值
- // modalForm.setFieldValue("departmentId","");
- myModalForm.resetFields();
- myModalForm.setFieldValue("userId", option);
- if (!value) {
- setTurnUser(null); // 清除选择的值
- setSelectOption([]); // 设置selectOption为空数组
- } else {
- setTurnUser(value);
- }
- }
- const handleDwmcChange = (value) => {
- // modalForm.setFieldValue("departmentId","");
- //解决方法,先把整个表单置空,然后再给第一个 下拉框赋值
- modalForm.resetFields();
- modalForm.setFieldValue("userId", value);
- // setSelectOption([])
- console.log("wo1",value)
- searchUser(value)
- }
- // 根据搜索的人 模糊匹配显示的人
- const searchUser = (value) => {
- if (value !== null && Object.keys(value).length !== 0) {
- const matchedValues = turnUserList.filter(item => item.label.toLowerCase()
- .includes(value.toLowerCase()));
- // 存储匹配到的value和label值
- setSelectOption(matchedValues);
- }
- }
- //获取主讲人对应的部门
- useEffect(() => {
- if (selectOption.length !== 0) {
- //解决方法,先把整个表单置空,然后再给第一个 下拉框赋值
- const user = {
- userId: selectOption[0].value,
- }
- getSpeakerDepartment(user).then(res => {
- if (res.code === 200) {
- const speakerDepartment = res.data.map((item) => ({
- value: item.departmentId,
- label: item.department
- }));
- setDepartmentOptions(speakerDepartment)
- }
- })
- }
- }, [selectOption]);
- //获取可见的单位;
- useEffect(() => {
- getVisibleCollege().then(res => {
- if (res.code === 200) {
- const visibleCollege = res.data.map((item) => ({
- value: item.departmentId,
- label: item.department
- }));
- setVisibleCollegeList(visibleCollege)
- }
- })
- }, []);
- //获取主讲人信息
- useEffect(() => {
- getAllSpeaker().then(res => {
- if (res.code === 200) {
- const speakerData = res.data.map((item) => ({
- value: item.userId,
- label: item.speakerName
- }));
- setTurnUserList(speakerData)
- }
- })
- }, []);
-
- //过滤搜索
- const selectFilterOption = (input, option) =>
- (option?.label ?? '').includes(input.toLowerCase());
- const selectFilterOptionTwo = (input, option) =>
- (option?.label ?? '').includes(input.toLowerCase());
- //
- const [previewOpen, setPreviewOpen] = useState(false);
- const [previewImage, setPreviewImage] = useState('');
- const [fileList, setFileList] = useState([]);
- const [key, setKey] = useState({});
- //预览图片
- const handlePreview = async file => {
- if (!file.url && !file.preview && file.originFileObj) {
- const preview = await getBase64(file.originFileObj);
- file.preview = preview;
- setPreviewImage(preview); // 设置预览放大的图片
- } else {
-
-
- setPreviewImage(file.url || file.preview); // 设置预览放大的图片
- }
- setPreviewOpen(true);
- };
-
-
- const handleChange = info => {
- if (info.file.status === 'done') {
- // 上传成功
- message.success('上传成功');
- setKey(info.file.response.data)
- // 在这里可以处理上传成功后的逻辑,比如更新 fileList 状态
- } else if (info.file.status === 'error') {
- // 上传失败
- // setFileList([])
- // message.error('上传失败', info.file.error);
- // 在这里可以处理上传失败后的逻辑,比如提示用户重新上传
- }
- // 更新 fileList 状态
- info.fileList.forEach(async file => {
- // 如果上传成功且有原始文件对象,则获取其 base64 编码值
- const base64 = await getBase64(file.originFileObj);
- setPhotoData(base64)
- });
- setFileList(info.fileList);
- };
-
- const uploadButton = (
- <button
- style={{
- border: 0,
- background: 'none',
- }}
- type="button"
- >
- <PlusOutlined/>
- <div
- style={{
- marginTop: 8,
- }}
- >
- div>
- button>
- );
-
- const onImagePreviewRemove = (file) => {
- setBase64Data("")
- setIsDisableSave(false)
- if (key !== null && Object.keys(key).length !== 0) {
- deletePhoto(key).then((res) => {
- if (res.code === 200) {
- setKey({});
- }
- });
- }
- }
- return (
- <div>
- {isInsert ? (
-
- <div className="container" style={{padding: '5px'}}>
-
- <Modal title={<h2 style={{textAlign: "center"}}>参与讲座详情h2>}
- open={isShowModal}
- footer={null}
- width={600}
- onCancel={handleCancel}
- >
- <div>
- <Table columns={speakerDetail} size={"middle"}
- style={{textAlign: 'center'}} // 整个表格数据居中
- dataSource={tableSourceDetail.list}
- pagination={false}/>
- <Row
- style={{marginTop: 10}}>
- <Col span={4}>
- <Text style={{float: "left"}}>
- 共 {tableSourceDetail.total} 项数据
- Text>
- Col>
- <Col span={20}>
- <Pagination
- style={{float: "right"}}
- total={tableSourceDetail.total}
- current={detailPage}
- defaultPageSize={5}
- onChange={detailPageChange}
- onShowSizeChange={detailPageSizeChange}
- />
- Col>
- Row>
- div>
- Modal>
-
- <Form form={screeningForm} onFinish={onScreeningFormFinish} style={{marginTop: 10}}
- onFinishFailed={onScreeningFormFinishFailed} autoComplete="off">
- <Row gutter={[10, 10]}>
- <Col span={7}>
- <Form.Item label="姓名" colon={false} name="name">
- <Input allowClear onChange={onChange} placeholder="请输入姓名"/>
- Form.Item>
- Col>
- <Col style={{marginLeft: '16.5%'}} span={9}>
- <Form.Item label="讲座名称" colon={false} name="speakerTotal">
- <Input allowClear onChange={onChange} placeholder="请输入"/>
- Form.Item>
- Col>
- <Col span={2}>
- <Form.Item colon={false}><Button style={{float: "right"}} type="primary"
- htmlType="submit">搜索Button>Form.Item>
- Col>
- <Col span={2}><Form.Item><Button style={{float: "right"}}
- onClick={resetScreeningForm}
- >重置Button>Form.Item>Col>
- Row>
- Form>
- <Row>
- <Col span={24}>
- <Button style={{float: "left"}} onClick={goInsert}>新增Button>
- Col>
- Row>
- <div style={{marginTop: 10}}>
- div>
-
- <div style={{marginTop: 10}}>
- <Table columns={tableColumns} size={"middle"}
- dataSource={tableSource.list}
- style={{textAlign: 'center'}} // 整个表格数据居中
- pagination={false}/>
- <Row
- style={{marginTop: 10}}>
- <Col span={4}>
- <Text
- style={{float: "left"}}>
- 共 {tableSource.total || 0} 项数据
- Text>
- Col>
- <Col span={20}>
- <Pagination
- style={{float: "right"}}
- total={tableSource.total}
- current={currentPage}
- defaultPageSize={10}
- defaultCurrent={1}
- onChange={onPageChange}
- pageSize={resetPageSize}
- onShowSizeChange={pageSizeChange}
- showSizeChanger={true}
- />
- Col>
- Row>
- div>
- div>
-
- ) : (
- <div className="container" style={{padding: '5px'}}>
- <div style={{
- minHeight: '1%',
- marginBottom: '20px',
- backgroundColor: '#fff',
- borderRadius: '8px',
- padding: '-2px',
- overflowY: "auto"
- }}>
- <Button type="text" style={{marginLeft: '-15px'}} onClick={goSpeaker}><LeftOutlined/> 返回 Button>
- div>
-
- <Form style={{marginTop: "20px"}}
- onValuesChange={onFormValuesChanged}
- form={myModalForm}
- autoComplete="on">
-
- Form>
- <Form style={{marginTop: "20px"}}
- form={modalForm}
- onFinish={onModalFormFinish}
- onFinishFailed={onModalFormFinishFailed}
- >
- <Row>
- <Col span={10}>
- <Form.Item label="主讲人姓名 "
- colon={false}
- name="userId"
- style={{marginBottom: '30px'}}
- rules={[
- {
- required: true,
- message: '此项为必填项,请填写后提交',
- },
- ]}>
- <Select
- showSearch
- disabled={isUpdateShow}
- filterOption={selectFilterOption} onSearch={searchUser}
- notFoundContent={searching ? <Spin size="small"/> : null}
- value={turnUser}
- placeholder="请输入主讲人姓名"
- onSelect={changeTurnUser}
- options={selectOption}
- onChange={handleDwmcChange}
- />
- Form.Item>
- Col>
- Row>
- <Row>
- <Col span={10}>
- <Form.Item label="所属学院/单位 " colon={false} name="departmentId"
- style={{marginBottom: '30px'}}
- rules={[
- {
- required: true,
- message: '此项为必填项,请填写后提交',
- },
- ]}
- >
- <Select
- placeholder="请输入所属学院/单位"
- options={departmentOptions}
- />
- Form.Item>
- Col>
- Row>
- <Row>
- <Col span={10}>
- <Form.Item
- label="职务 "
- colon={false}
- name="job"
- rules={[
- {
- required: true,
- message: '此项为必填项,请填写后提交',
- },
- ]}
- style={{marginBottom: '30px'}}
- >
- <Input
- showCount
- maxLength={100}
- allowClear={true}
- placeholder="请输入职务"
- />
- Form.Item>
- Col>
- Row>
- <Row>
- <Col span={10}>
- <Form.Item
- hidden={true}
- label="id"
- colon={false} name="id"
- style={{marginBottom: '30px'}}
- >
- <Input
- allowClear={true}
- placeholder="请输入"
- />
- Form.Item>
- Col>
- Row>
- <Row>
- <Col span={10}>
- <Form.Item
- label="专业领域 "
- colon={false} name="professionalField"
- rules={[
- {
- required: true,
- message: '此项为必填项,请填写后提交',
- },
- ]}
- style={{marginBottom: '30px'}}
- >
- <Input
- showCount
- maxLength={100}
- allowClear={true}
- placeholder="请输入专业领域"
- />
- Form.Item>
- Col>
- Row>
- <Row>
- <Col span={15}>
- <Form.Item
- label="个人简介 "
- colon={false} name="personalProfile"
- rules={[
- {
- required: true,
- message: '此项为必填项,请填写后提交',
- },
- ]}
- style={{marginBottom: '30px'}}
- >
- <TextArea
- showCount
- maxLength={1000}
- onChange={onChange}
- placeholder="请输入个人简介"
- style={{
- height: 120,
- resize: 'none',
- }}
- />
- Form.Item>
- Col>
- Row>
- <Row>
- <Col span={10}>
- <Form.Item
- style={{marginBottom: '30px'}}
- label="可见学院/单位 "
- colon={false}
- name="visibleCollege"
- rules={[
- {
- required: true,
- message: '此项为必填项,请填写后提交',
- },
- ]}
- >
- <Select
- disabled={isUpdateShow}
- allowClear={true}
- mode="multiple"
- placeholder="请输入可见学院/单位(可多选)"
- filterOption={selectFilterOptionTwo}
- options={visibleCollegeList}
- />
- Form.Item>
- Col>
- Row>
-
- <Row>
- <Col span={5}>
- <Form.Item
- label="照片上传 "
- style={{marginBottom: '50px'}}
- colon={false}
- >
- <Upload
- name="file"
- style={{width: '100px'}}
- action={uploadPhotoApi}
- listType="picture-card"
- onPreview={handlePreview}
- fileList={fileList} // 将 fileList 传递给 Upload 组件
- onChange={handleChange}
- onRemove={onImagePreviewRemove}
- beforeUpload={beforeUpload}
- >
- {fileList.length >= 1 ? null : uploadButton}
- Upload>
- {previewImage && (
- <Image style={{width: "100px"}}
- // className="custom-preview"
- src={previewImage}
- wrapperStyle={{
- display: 'none'
- }}
- className="ant-upload-list-item"
- preview={{
- visible: previewOpen,
- onVisibleChange: (visible) => setPreviewOpen(visible),
- afterOpenChange: (visible) => !visible && setPreviewImage(''),
- }}
- />
- )}
- <Row style={{marginTop: '10px'}}>
- <Col span={5}>
- <Form.Item colon={false}>
- <Button style={{ float: "left" }}
- type="primary"
- disabled={isDisableSave}
- loading={loadings[1]}
- htmlType="submit">保存Button>
- Form.Item>
- Col>
- <Col span={10} style={{ display: 'flex', alignItems: 'center' }}>
- <Form.Item style={{ marginLeft: '60px' }}>
- <Button onClick={resetScreeningForm}>取消Button>
- Form.Item>
- Col>
- Row>
-
-
- Form.Item>
-
- Col>
- Row>
- Form>
- div>
- )}
- div>
- );
- };
-
需要正常配置好Minio

- package com.ly.cloud.util.minio;
-
- import com.ly.cloud.config.MinioConfig;
- import io.minio.*;
- import io.minio.http.Method;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Component;
-
- import javax.annotation.Resource;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.InputStream;
-
- @Component
- public class MinioUtil {
-
- @Resource
- private MinioConfig minioConfig;
- /**
- * minio参数
- */
- @Value("${minio.url}")
- private String ENDPOINT;
- @Value("${minio.access-key}")
- private String ACCESS_KEY;
- @Value("${minio.secret-key}")
- private String SECRET_KEY ;
-
- /**
- * 桶占位符
- */
- private static final String BUCKET_PARAM = "${bucket}";
- /**
- * bucket权限-只读
- */
- private static final String READ_ONLY = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetObject\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "/*\"]}]}";
- /**
- * bucket权限-只读
- */
- private static final String WRITE_ONLY = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "/*\"]}]}";
- /**
- * bucket权限-读写
- */
- private static final String READ_WRITE = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:DeleteObject\",\"s3:GetObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\",\"s3:AbortMultipartUpload\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "/*\"]}]}";
-
- /**
- * 文件url前半段
- *
- * @param bucket 桶
- * @return 前半段
- */
- public String getObjectPrefixUrl(String bucket) {
- return String.format("%s/%s/", ENDPOINT, bucket);
- }
-
- /**
- * 创建桶
- *
- * @param bucket 桶
- */
- public void makeBucket(String bucket) throws Exception {
- MinioClient client = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY, SECRET_KEY).build();
- // 判断桶是否存在
- boolean isExist = client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
- if (!isExist) {
- // 新建桶
- client.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
- }
- }
-
- /**
- * 更新桶权限策略
- *
- * @param bucket 桶
- * @param policy 权限
- */
- public void setBucketPolicy(String bucket, String policy) throws Exception {
- MinioClient client = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY, SECRET_KEY).build();
- setBucketPolicy(bucket, policy, client);
- }
-
- /**
- * 更新桶权限策略
- *
- * @param bucket 桶
- * @param policy 权限
- */
- public void setBucketPolicy(String bucket, String policy, MinioClient client) throws Exception {
- switch (policy) {
- case "read-only":
- client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucket).config(READ_ONLY.replace(BUCKET_PARAM, bucket)).build());
- break;
- case "write-only":
- client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucket).config(WRITE_ONLY.replace(BUCKET_PARAM, bucket)).build());
- break;
- case "read-write":
- client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucket).config(READ_WRITE.replace(BUCKET_PARAM, bucket)).build());
- break;
- case "none":
- default:
- break;
- }
- }
-
- /**
- * 上传本地文件
- *
- * @param bucket 桶
- * @param objectKey 文件key
- * @param filePath 文件路径
- * @return 文件url
- */
- public String uploadFile(String bucket, String objectKey, String filePath) throws Exception {
- MinioClient client = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY, SECRET_KEY).build();
- client.uploadObject(UploadObjectArgs.builder().bucket(bucket).object(objectKey).filename(filePath).contentType("image/png").build());
- return getObjectPrefixUrl(bucket) + objectKey;
- }
-
- /**
- * 流式上传文件
- *
- * @param bucket 桶
- * @param objectKey 文件key
- * @param inputStream 文件输入流
- * @return 文件url
- */
- public String uploadInputStream(String bucket, String objectKey, InputStream inputStream) throws Exception {
- MinioClient client = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY, SECRET_KEY).build();
- client.putObject(PutObjectArgs.builder().bucket(bucket).object(objectKey).stream(inputStream, inputStream.available(), -1).contentType("image/png").build());
- return getObjectPrefixUrl(bucket) + objectKey;
- }
-
- /**
- * 下载文件
- * @param bucket 桶
- * @param objectKey 文件key
- * @return 文件流
- */
- public InputStream download(String bucket, String objectKey) throws Exception {
- MinioClient client = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY, SECRET_KEY).build();
- return client.getObject(GetObjectArgs.builder().bucket(bucket).object(objectKey).build());
- }
-
- /**
- * 文件复制
- *
- * @param sourceBucket 源桶
- * @param sourceObjectKey 源文件key
- * @param bucket 桶
- * @param objectKey 文件key
- * @return 新文件url
- */
- public String copyFile(String sourceBucket, String sourceObjectKey, String bucket, String objectKey) throws Exception {
- MinioClient client = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY, SECRET_KEY).build();
- CopySource source = CopySource.builder().bucket(sourceBucket).object(sourceObjectKey).build();
- client.copyObject(CopyObjectArgs.builder().bucket(bucket).object(objectKey).source(source).build());
- return getObjectPrefixUrl(bucket) + objectKey;
- }
-
- /**
- * 删除文件
- *
- * @param bucket 桶
- * @param objectKey 文件key
- */
- public void deleteFile(String bucket, String objectKey) throws Exception {
- MinioClient client = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY, SECRET_KEY).build();
- client.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectKey).build());
- }
-
- /**
- * 获取文件签名url
- * @param bucket 桶
- * @param objectKey 文件key
- * @param expires 签名有效时间 单位秒
- * @return 文件签名地址
- */
- public String getSignedUrl(String bucket, String objectKey, int expires) throws Exception {
- MinioClient client = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY, SECRET_KEY).build();
- return client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucket).object(objectKey).expiry(expires).build());
- }
-
-
- }
- @Override
- public Map
uploadPhoto(MultipartFile file) throws Exception { - FileInputStream stream = FileUtil.convertMultipartFileToInputStream(file);
- String stringTime = DateTimeUtils.stringTime();
- String fileName = generateRandomSixDigitNumber() + stringTime;
- minioUtil.uploadInputStream("mpbucket", "sjs/" + "/"+ fileName + ".png", stream);
- return map;
- }
下载:
返回base64 编码
- public static final String BASE_64 = "data:image/png;base64,";
-
- //获取文件的base 64 编码
- InputStream download = minioUtil.download("mpbucket", "sjs/" + SLASH_SUFFIX + fileName + ".png");
- byte[] bytes = IOUtils.toByteArray(download);
- String encoded = Base64.getEncoder().encodeToString(bytes);
- Map
map = new HashMap<>(); - map.put("objectKey", fileName + ".png");
- map.put("base64", BASE_64 + encoded);