联调参赛报名、提交作品、管理页面接口(还有缺陷)

This commit is contained in:
谢思 2022-03-26 19:10:02 +08:00 committed by 何童崇
parent 65d616b116
commit aa805dc22c
11 changed files with 388 additions and 67 deletions

View File

@ -10,7 +10,7 @@ import Loading from "../Loading";
// import { getUserInfo } from './expert/api'; // import { getUserInfo } from './expert/api';
import { ImageLayerOfCommentHOC } from "../modules/page/layers/ImageLayerOfCommentHOC"; import { ImageLayerOfCommentHOC } from "../modules/page/layers/ImageLayerOfCommentHOC";
import './qz2022/index.scss'; import './qz2022/index.scss';
import { Button, Dropdown, Menu, Spin } from "antd"; import { Button, Dropdown, Menu, Popover, Spin } from "antd";
import banner from './qz2022/image/banner.png' import banner from './qz2022/image/banner.png'
import { paths } from "./qz2022/static"; import { paths } from "./qz2022/static";
@ -101,9 +101,9 @@ const Qz2022 = (props) => {
<Link to={{ pathname: `/competition/qz2022/contact` }}>联系我们</Link> <Link to={{ pathname: `/competition/qz2022/contact` }}>联系我们</Link>
</li> </li>
<li className={(active === "applys" || active === "production") ? "active" : ""}> <li className={(active === "applys" || active === "production") ? "active" : ""}>
<Dropdown overlay={menu} placement="bottomRight" overlayClassName="qz_manage"> <Popover content={menu} placement="bottomRight" overlayClassName="qz_manage">
<a>后台管理</a> <a>后台管理</a>
</Dropdown> </Popover>
</li> </li>
</ul>} </ul>}
{paths.indexOf(active) !== -1 && <div className="menu_border mt20 qz_main"></div>} {paths.indexOf(active) !== -1 && <div className="menu_border mt20 qz_main"></div>}
@ -154,13 +154,13 @@ const Qz2022 = (props) => {
{/* 后台管理-报名列表 */} {/* 后台管理-报名列表 */}
<Route path="/competition/qz2022/management/applys" <Route path="/competition/qz2022/management/applys"
render={ render={
() => (<Management {...props} />) () => (<Management {...props} qzDetail={qzDetail}/>)
} }
></Route> ></Route>
{/* 后台管理-作品列表 */} {/* 后台管理-作品列表 */}
<Route path="/competition/qz2022/management/production" <Route path="/competition/qz2022/management/production"
render={ render={
() => (<Management {...props} />) () => (<Management {...props} qzDetail={qzDetail}/>)
} }
></Route> ></Route>
</Switch> </Switch>

View File

@ -21,12 +21,46 @@ export function getQz2022() {
// 报名启智2022 竞赛 // 报名启智2022 竞赛
export async function enrollCompetition(data){ export async function enrollCompetition(data){
return fetch({ return fetch({
url: `${current_main_site_url}/api/competition_infos/${id}/enroll.json`, url: `${current_main_site_url}/api/competition_infos/qz2022/enroll.json`,
method: 'post', method: 'post',
data, data,
}); });
} }
// 竞赛提交作品
export async function uploadCompetition(data){
return fetch({
url: `${current_main_site_url}/api/competition_infos/qz2022/upload.json`,
method: 'post',
data,
});
}
// 管理-竞赛报名列表
export function getQzEnrollList(params) {
return fetch({
url: `${current_main_site_url}/api/competition_infos/qz2022/enroll_list.json`,
method: 'get',
params
});
}
// 管理-竞赛报名列表导出
export function exportEnrollList(params) {
return fetch({
url: `${current_main_site_url}/api/competition_infos/qz2022/enroll_list.xlsx`,
method: 'get',
});
}
// 管理-竞赛提交作品列表
export function getQzProList(params) {
return fetch({
url: `${current_main_site_url}/api/competition_infos/qz2022/enroll_list.json?upload=true`,
method: 'get',
params
});
}
//删除专家 //删除专家
export function deleteExpert(expertId) { export function deleteExpert(expertId) {
return fetch({ return fetch({

View File

@ -1,5 +1,5 @@
import React, { useState, useCallback, useMemo, useEffect } from "react"; import React, { useState, useCallback, useMemo, useEffect, useRef } from "react";
import { Input, Select, Button, Form, DatePicker, Table, Pagination, Upload, Modal } from 'antd'; import { Input, Select, Button, Form, message, DatePicker, Table, Pagination, Upload, Modal } from 'antd';
import {competitionArea, competitionType} from '../static.js'; import {competitionArea, competitionType} from '../static.js';
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { formatDuring } from 'educoder'; import { formatDuring } from 'educoder';
@ -22,6 +22,7 @@ export default Form.create()((props) => {
const { getFieldDecorator, validateFields, setFieldsValue } = form; const { getFieldDecorator, validateFields, setFieldsValue } = form;
const [applyStatue, setApplyState] = useState(undefined); const [applyStatue, setApplyState] = useState(undefined);
const [members, setMembers] = useState([]); const [members, setMembers] = useState([]);
const [errorMessage, setErrorMessage] = useState(undefined);
// form // form
const helper = useCallback( const helper = useCallback(
@ -53,22 +54,35 @@ export default Form.create()((props) => {
// //
function applySubmit(){ function applySubmit(){
//
if(members.length > 0){
let all = false;
members.map(item=>{
all = Object.keys(item).length === 5;
})
if(!all){
setErrorMessage("成员信息未填写完成");
return;
}
}
validateFields((error, values)=>{ validateFields((error, values)=>{
if(error){ if(error){
return return
}else{ }else{
console.log('正确输入');
// //
const params = { const params = {
...values, ...values,
members
} }
// enrollCompetition(params).then(response=>{ enrollCompetition(params).then(response=>{
// console.log(response); if(response && response.message === "success"){
// }) message.success('报名成功')
}
})
} }
}) })
} }
console.log('members', members);
return ( return (
<div className="qz_main"> <div className="qz_main">
<div className="step"> <div className="step">
@ -137,11 +151,13 @@ console.log('members', members);
</div>} </div>}
{helper('电话', {helper('电话',
'phone', 'phone',
[{ required: true, message: "请正确输入报名信息" }], [{ required: true, message: "请正确输入报名信息" },
<Input placeholder="超出限制长度32位字符请重新编辑" onBlur={()=>{verify("phone")}}/> {pattern: /^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$/, message: "请输入正确的手机号"}],
<Input placeholder="请输入电话" onBlur={()=>{verify("phone")}}/>
)} )}
<div> <div>
<p>成员</p> <p className="mt10">成员 : </p>
<p className="error_message">{errorMessage}</p>
{/* */} {/* */}
<EditTable setMembers={setMembers}/> <EditTable setMembers={setMembers}/>
</div> </div>

View File

@ -43,6 +43,8 @@
display: inline-block; display: inline-block;
width: 33%; width: 33%;
margin-right: 160px; margin-right: 160px;
margin-bottom: 0px;
.ant-input:hover{border-color:#2e5bfe;}
} }
.class_from{ .class_from{
display: inline; display: inline;
@ -104,6 +106,9 @@
&:hover{cursor: pointer;} &:hover{cursor: pointer;}
} }
} }
.error_message{
color: #f5222d;
}
} }
.apply_but{ .apply_but{
padding-bottom: 60px; padding-bottom: 60px;

View File

@ -17,7 +17,6 @@ class EditableCell extends React.Component {
save = (dataIndex, e) => { save = (dataIndex, e) => {
const { record, handleSave } = this.props; const { record, handleSave } = this.props;
console.log(dataIndex);
this.form.validateFields([dataIndex],(error, values) => { this.form.validateFields([dataIndex],(error, values) => {
if (error && error[e.currentTarget.id]) { if (error && error[e.currentTarget.id]) {
return; return;
@ -67,28 +66,27 @@ class EditableCell extends React.Component {
class EditableTable extends React.Component { class EditableTable extends React.Component {
constructor(props) { constructor(props) {
console.log(props,'表格');
super(props); super(props);
this.columns = [ this.columns = [
{ {
title: '姓名', title: '姓名',
dataIndex: 'name', dataIndex: 'real_name',
editable: true, editable: true,
}, },
{ {
title: '单位', title: '单位',
dataIndex: 'age', dataIndex: 'org_name',
editable: true, editable: true,
width: '30%', width: '30%',
}, },
{ {
title: '职务', title: '职务',
dataIndex: 'address', dataIndex: 'org_job',
editable: true, editable: true,
}, },
{ {
title: 'JXJXJX', title: 'JXJXJX',
dataIndex: 'militaryRank', dataIndex: 'org_rank',
editable: true, editable: true,
}, },
{ {
@ -108,10 +106,6 @@ class EditableTable extends React.Component {
dataSource: [ dataSource: [
{ {
key: '0', key: '0',
name: '',
age: '',
address: '',
militaryRank: ''
} }
], ],
count: 1, count: 1,

View File

@ -42,12 +42,13 @@
} }
.qzCont { .qzCont {
min-height: 35vh; min-height: 35vh;
border-radius: 4px; border-radius:4px;
box-shadow: 0px 3px 12px #ecf0ff;
} }
} }
.qz_manage { .qz_manage {
top: 510px !important; .ant-popover-inner-content{
padding: 0;
}
.ant-dropdown-menu-item > a { .ant-dropdown-menu-item > a {
color: #333; color: #333;
&:hover { &:hover {

View File

@ -1,5 +1,5 @@
import React, { useState, useCallback, useMemo, useEffect } from "react"; import React, { useState, useCallback, useMemo, useEffect } from "react";
import { Input, Select, Button, Form, DatePicker, Table, Pagination, Upload, Modal } from 'antd'; import { Input, Select, Button, Form, DatePicker, Table, Pagination, Upload, Modal, Icon } from 'antd';
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { formatDuring } from 'educoder'; import { formatDuring } from 'educoder';
import {competitionArea, competitionType} from '../static.js'; import {competitionArea, competitionType} from '../static.js';
@ -7,9 +7,11 @@ import PaginationTable from "../../components/paginationTable";
import './index.scss'; import './index.scss';
import '../index.scss'; import '../index.scss';
import { getQzEnrollList, getQzProList, exportEnrollList } from "../api.js";
const Option = Select.Option; const Option = Select.Option;
function Introduce({ form, showNotification, match, history:{location:{pathname}} }) { function Introduce({ form, showNotification, match, history:{location:{pathname}},qzDetail }) {
console.log(qzDetail);
// type01 // type01
const [type, setType] = useState(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght)); const [type, setType] = useState(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght));
const [reload, setReload] = useState(); const [reload, setReload] = useState();
@ -18,103 +20,196 @@ function Introduce({ form, showNotification, match, history:{location:{pathname}
const [pageSize, setPageSize] = useState(10); const [pageSize, setPageSize] = useState(10);
const [dataList, setDataList] = useState([]); const [dataList, setDataList] = useState([]);
const [total, setTotal] = useState(0); const [total, setTotal] = useState(0);
//
const [zone, setZone] = useState(undefined);
const [subCompetition, setSubCompetition] = useState(undefined);
useEffect(() => { useEffect(() => {
setType(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght)); setType(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght));
}, [pathname]); }, [pathname]);
useEffect(()=>{
console.log(zone, subCompetition);
const params = {
zone: zone === '-1' ? undefined : zone,
sub_competition: subCompetition === '-1' ? undefined : subCompetition
}
if(type === "applys"){
//
getQzEnrollList(params).then(response=>{
console.log(response);
if(response && response.message === "success"){
setTotal(response.count);
setDataList(response.data);
}
})
}else{
//
getQzProList(params).then(response=>{
if(response && response.message === "success"){
setTotal(response.count);
setDataList(response.data);
}
})
}
}, [type, zone, subCompetition])
const columns_apply = useMemo(() => { const columns_apply = useMemo(() => {
return [ return [
{ {
title: '参赛单位', title: '参赛单位',
dataIndex: 'index' dataIndex: 'org_name',
width: '10%',
align: 'center'
}, },
{ {
title: '参赛负责人', title: '参赛负责人',
dataIndex: 'containerName', dataIndex: 'leader',
key: 'containerName', key: 'leader',
}, },
{ {
title: '职务', title: '职务',
dataIndex: 'reviewEndOn', dataIndex: 'org_job',
key: 'reviewEndOn', key: 'org_job',
}, },
{ {
title: 'JXJXJX', title: 'JXJXJX',
dataIndex: 'surplus', dataIndex: 'org_rank',
key: 'surplus', key: 'org_rank',
}, },
{ {
title: '电话', title: '电话',
dataIndex: 'status', dataIndex: 'phone',
key: 'status', key: 'phone',
},
{
title: '赛区',
dataIndex: 'zone',
render:(text, record)=>{
return (qzDetail && qzDetail.zones[text]) || '--';
}
}, },
{ {
title: '赛项', title: '赛项',
dataIndex: 'status', dataIndex: 'sub_competition',
key: 'action', render:(text, record)=>{
return (qzDetail && qzDetail.sub_competitions[text]) || '--';
}
}, },
{ {
title: '课题来源', title: '课题来源',
dataIndex: 'status', dataIndex: 'subject_source_type',
key: 'status', render:(text, record)=>{
return text === '0' ? "自主提报" : record.subject_source_name || '--';
}
}, },
{ {
title: '成员', title: '成员',
dataIndex: 'status', dataIndex: 'members',
key: 'action', render:(text, record)=>{
console.log('members', text);
return '';
}
} }
]; ];
}, []); }, [qzDetail]);
const columns_production = useMemo(() => { const columns_production = useMemo(() => {
return [ return [
{ {
title: '参赛单位', title: '参赛单位',
dataIndex: 'index' dataIndex: 'org_name'
}, },
{ {
title: '参赛负责人', title: '参赛负责人',
dataIndex: 'containerName', dataIndex: 'leader',
key: 'containerName',
}, },
{ {
title: '赛区', title: '赛区',
dataIndex: 'reviewEndOn', dataIndex: 'zone',
key: 'reviewEndOn', render:(text, record)=>{
return (qzDetail && qzDetail.zones[text]) || '--';
}
}, },
{ {
title: '赛项', title: '赛项',
dataIndex: 'surplus', dataIndex: 'sub_competition',
key: 'surplus', render:(text, record)=>{
return (qzDetail && qzDetail.sub_competitions[text]) || '--';
}
}, },
{ {
title: '作品', title: '作品',
dataIndex: 'status', dataIndex: 'sttachments',
key: 'status',
}, },
]; ];
}, []); }, [qzDetail]);
const expandRow = (record) =>{
return <div className="expandRowManage">
<div className="row">
<div>序号</div>
<div>姓名</div>
<div className="job">单位</div>
<div>职务</div>
<div>军衔</div>
</div>
{record.members && record.members.map((item, index)=>{
return <div className="row">
<div>{index+1}</div>
<div>{item.real_name}</div>
<div className="job">{item.org_job}</div>
<div>{item.org_rank}</div>
<div>{item.org_name}</div>
</div>
})}
</div>
}
const customExpandIcon1 = useMemo((props)=>{
// console.log(props);
},[dataList])
const customExpandIcon = (props) => {
console.log(props);
if(props.record.members.length > 0){
if (props.expanded) {
return <a style={{ color: 'black',marginRight:8 }} onClick={e => {
props.onExpand(props.record, e);
}}>查看成员<i className="iconfont icon-changyongtubiao-xianxingdaochu-zhuanqu- font-12 ml5"></i></a>
} else {
return <a style={{ color: 'black' ,marginRight:8 }} onClick={e => {
props.onExpand(props.record, e);
}}>查看成员<i className="iconfont icon-jiantou9 font-12 ml5"></i></a>
}
}else{
return <span style={{marginRight:8 }}></span>
}
}
function exportApplyInfo(){
exportEnrollList();
}
return ( return (
<div className="qz_management"> <div className="qz_management">
<div className="qz_manage_head">启智2022{type === "applys" ? "报名" : "作品"}列表</div> <div className="qz_manage_head">启智2022{type === "applys" ? "报名" : "作品"}列表</div>
<div className="search"> <div className="search">
<div> <div className="font-14">
赛区 赛区
<Select defaultValue="-1" style={{ width: 200 }}> <Select defaultValue="-1" style={{ width: 200 }} onChange={(value)=>{setZone(value)}}>
<Option value='-1'>所有赛区</Option> <Option value='-1'>所有赛区</Option>
{competitionArea.map(item=> {return <Option value={item.value}>{item.title}</Option>})} {qzDetail && qzDetail.zones.map((item,i)=> {return <Option value={i} key={i}>{item}</Option>})}
</Select> </Select>
<span className="ml30">赛项</span> <span className="ml30">赛项</span>
<Select defaultValue="-1" style={{ width: 200 }}> <Select defaultValue="-1" style={{ width: 200 }} onChange={(value)=>{setSubCompetition(value)}}>
<Option value='-1'>所有赛项</Option> <Option value='-1'>所有赛项</Option>
{competitionType.map(item=> {return <Option value={item.value}>{item.title}</Option>})} {qzDetail && qzDetail.sub_competitions.map((item,i)=> {return <Option value={i} key={i}>{item}</Option>})}
</Select> </Select>
</div> </div>
{type === "applys" && <Button className="but_2e5">导出</Button>} {type === "applys" && <Button className="but_2e5" onClick={exportApplyInfo}>导出</Button>}
</div> </div>
<PaginationTable <PaginationTable
@ -124,7 +219,11 @@ function Introduce({ form, showNotification, match, history:{location:{pathname}
columns={type==="applys" ? columns_apply : columns_production} columns={type==="applys" ? columns_apply : columns_production}
total={total} total={total}
setCurPage={setCurPage} setCurPage={setCurPage}
current={curPage}/> current={curPage}
expandedRowRender={expandRow}
expandIconColumnIndex={8}
expandIconAsCell={false}
expandIcon={customExpandIcon}/>
</div> </div>
) )
} }

View File

@ -17,4 +17,10 @@
.pagination-table.qzManageTable { .pagination-table.qzManageTable {
padding: 0 30px; padding: 0 30px;
} }
.expandRowManage .row div{
display: inline-block;
width: 17%;
text-align: center;
&.job{width: 30%;}
}
} }

View File

@ -0,0 +1,94 @@
import React, { useEffect, useState } from "react";
import { Upload, Button } from 'antd';
import { appendFileSizeToUploadFileAll } from 'educoder';
import { httpUrl } from '../fetch';
function Uploads({ className, size, actionUrl, fileList, showNotification, load, accept, disabled,count }) {
const [files, setFiles] = useState(undefined);
useEffect(() => {
if (fileList) {
init();
}
}, [fileList]);
function init() {
let f = appendFileSizeToUploadFileAll(fileList);
setFiles(f);
}
function onAttachmentRemove(file) {
if (!file.percent || file.percent === 100) {
deleteAttachment(file);
return false;
}
}
function deleteAttachment(file) {
let id = (file.response && file.response.data && file.response.data.id) || file.id;
//
let nf = files.filter(item => {
let itemId = (item.response && item.response.data && item.response.data.id) || item.id;
return itemId !== id;
});
setFiles(nf);
backFiles(nf);
}
function backFiles(fileList) {
let filesId = [];
for (const item of fileList) {
if (item) {
let itemId = (item.response && item.response.data && item.response.data.id) || item.id;
itemId && filesId.push(itemId);
}
}
load && load(fileList, filesId.join());
}
function handleChange(info) {
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
let fileList = info.fileList;
if(count){
fileList = fileList.slice(-count);
}
setFiles(appendFileSizeToUploadFileAll(fileList));
if (info.file.response) {
for (let i = 0; i < fileList.length; i++) {
if (fileList[i].response && !fileList[i].response.data) {
fileList.splice(i, 1);
}
}
backFiles(fileList);
if (!info.file.response.data) {
info.file.response && showNotification(info.file.response.message)
}
}
}
}
function beforeUpload(file) {
const isLt100M = file.size / 1024 / 1024 < size;
if (!isLt100M) {
showNotification(`文件大小必须小于${size}MB!`);
}
return isLt100M;
}
const upload = {
name: 'file',
fileList: files,
disabled: disabled,
action: (httpUrl || actionUrl) + `/busiAttachments/upload`,
onChange: handleChange,
onRemove: onAttachmentRemove,
beforeUpload: beforeUpload,
};
return (
<Upload {...upload} className={className}>
<Button type="primary" disabled={disabled}>点击上传</Button>
<span className="ml10 color-grey-9">(你可以上传小于<span className="color-red">{size}MB</span>的文件)</span>
</Upload>
)
}
export default Uploads;

View File

@ -1,8 +1,10 @@
import React, { useState, useCallback, useMemo, useEffect } from "react"; import React, { useState, useCallback, useMemo, useEffect } from "react";
import { Input, Select, Button, Form, DatePicker, Table, Pagination, Upload, Modal, Icon } from 'antd'; import { Input, Select, Button, Form, DatePicker, Table, Pagination, Upload, Modal, Icon } from 'antd';
import { appendFileSizeToUploadFileAll } from 'educoder';
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { formatDuring } from 'educoder'; import { formatDuring } from 'educoder';
import {httpUrl} from '../fetch.js'; import {httpUrl} from '../fetch.js';
import {uploadCompetition} from '../api';
import refer_tip from "../image/refer_tip.svg"; import refer_tip from "../image/refer_tip.svg";
import refer from "../image/refer.svg"; import refer from "../image/refer.svg";
@ -11,23 +13,84 @@ import '../../index.scss';
const Option = Select.Option; const Option = Select.Option;
function Introduce({ form, showNotification, match, history }) { function Introduce({ form, showNotification, match, history }) {
const [referStatue, setreferState] = useState(true); // loading
const [loading, setLoading] = useState(false);
const [referStatue, setReferState] = useState(true);
const [files, setFiles] = useState(undefined);
const showUploadList = {
}
useEffect(() => { useEffect(() => {
}, []); }, []);
function handleChange(info) {
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
setLoading(true);
let fileList = info.fileList;
setFiles(appendFileSizeToUploadFileAll(fileList));
if (info.file.response) {
for (let i = 0; i < fileList.length; i++) {
if (fileList[i].response && !fileList[i].response.data) {
fileList.splice(i, 1);
}
}
if (!info.file.response.data) {
info.file.response && showNotification(info.file.response.message)
}
}
}
if(info.file.status == "done"){
setLoading(false);
}
}
//
function download(file){
const fileId = file.response.data.id;
window.open(`${httpUrl}/busiAttachments/download/${fileId}`);
}
//
function beforeUpload(file){
const isLt100M = file.size / 1024 / 1024 < 256;
if (!isLt100M) {
showNotification(`文件大小必须小于${256}MB!`);
}
return isLt100M;
}
//
function referProduction(){
if(files && files.length === 1){
uploadCompetition({"attachment_ids":Array.from(files[0].response.data.id)}).then(response=>{
console.log(response);
})
}
}
return ( return (
<div className="qz_main refer"> <div className="qz_main refer">
<img src={refer} className="refer_img mb20"/> <img src={refer} className="refer_img mb20"/>
<Upload <Upload
accept=".zip,.rar,.tar"
action={`${httpUrl}/busiAttachments/upload`} action={`${httpUrl}/busiAttachments/upload`}
fileList={files}
onChange={handleChange}
onDownload={download}
beforeUpload={beforeUpload}
showUploadList={{
showDownloadIcon: true,
downloadIcon: <i className="iconfont icon-xiazai-icon"></i>
}}
> >
<Button className="upload"><Icon type="upload" />上传</Button> <Button className="upload"><Icon type="upload" />上传</Button>
</Upload> </Upload>
<div className="refer_tip mt20">上传小于等于256m的作品压缩包仅限上传一个压缩包</div> <div className="refer_tip mt20">上传小于等于256m的作品压缩包仅限上传一个压缩包,格式如下: .zip, .rar, .tar</div>
<div className="refer_bor"></div> <div className="refer_bor"></div>
<Button type="primary">提交作品</Button> <Button type="primary" onClick={referProduction} loading={loading}>提交作品</Button>
</div> </div>
) )
} }

View File

@ -24,4 +24,13 @@
>span{ >span{
text-align: center; text-align: center;
} }
.ant-upload-list-item-info{
color: #2e5bfe;
:hover{color: #2e5bfe;}
.ant-upload-list-item-card-actions{
right: -55px;
.anticon{padding-right: 10px;}
}
}
.ant-upload-list-item:hover .ant-upload-list-item-info{background: none;}
} }