From aa805dc22ceba7eeabdbce4d15c0a57be6ff1a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A2=E6=80=9D?= Date: Sat, 26 Mar 2022 19:10:02 +0800 Subject: [PATCH] =?UTF-8?q?=E8=81=94=E8=B0=83=E5=8F=82=E8=B5=9B=E6=8A=A5?= =?UTF-8?q?=E5=90=8D=E3=80=81=E6=8F=90=E4=BA=A4=E4=BD=9C=E5=93=81=E3=80=81?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E9=A1=B5=E9=9D=A2=E6=8E=A5=E5=8F=A3=EF=BC=88?= =?UTF-8?q?=E8=BF=98=E6=9C=89=E7=BC=BA=E9=99=B7=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/military/qz2022.js | 10 +- src/military/qz2022/api.js | 36 ++++- src/military/qz2022/apply/index.jsx | 36 +++-- src/military/qz2022/apply/index.scss | 5 + src/military/qz2022/editTable/index.jsx | 14 +- src/military/qz2022/index.scss | 7 +- src/military/qz2022/management/index.jsx | 169 +++++++++++++++++----- src/military/qz2022/management/index.scss | 6 + src/military/qz2022/refer/Upload.jsx | 94 ++++++++++++ src/military/qz2022/refer/index.jsx | 69 ++++++++- src/military/qz2022/refer/index.scss | 9 ++ 11 files changed, 388 insertions(+), 67 deletions(-) create mode 100644 src/military/qz2022/refer/Upload.jsx diff --git a/src/military/qz2022.js b/src/military/qz2022.js index 464f1635a..a691f07a8 100644 --- a/src/military/qz2022.js +++ b/src/military/qz2022.js @@ -10,7 +10,7 @@ import Loading from "../Loading"; // import { getUserInfo } from './expert/api'; import { ImageLayerOfCommentHOC } from "../modules/page/layers/ImageLayerOfCommentHOC"; 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 { paths } from "./qz2022/static"; @@ -101,9 +101,9 @@ const Qz2022 = (props) => { 联系我们
  • - + 后台管理 - +
  • } {paths.indexOf(active) !== -1 &&
    } @@ -154,13 +154,13 @@ const Qz2022 = (props) => { {/* 后台管理-报名列表 */} () + () => () } > {/* 后台管理-作品列表 */} () + () => () } > diff --git a/src/military/qz2022/api.js b/src/military/qz2022/api.js index f9046ae26..c16ac243c 100644 --- a/src/military/qz2022/api.js +++ b/src/military/qz2022/api.js @@ -21,12 +21,46 @@ export function getQz2022() { // 报名启智2022 竞赛 export async function enrollCompetition(data){ 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', 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) { return fetch({ diff --git a/src/military/qz2022/apply/index.jsx b/src/military/qz2022/apply/index.jsx index 35977bedc..982bf54b8 100644 --- a/src/military/qz2022/apply/index.jsx +++ b/src/military/qz2022/apply/index.jsx @@ -1,5 +1,5 @@ -import React, { useState, useCallback, useMemo, useEffect } from "react"; -import { Input, Select, Button, Form, DatePicker, Table, Pagination, Upload, Modal } from 'antd'; +import React, { useState, useCallback, useMemo, useEffect, useRef } from "react"; +import { Input, Select, Button, Form, message, DatePicker, Table, Pagination, Upload, Modal } from 'antd'; import {competitionArea, competitionType} from '../static.js'; import { Link } from "react-router-dom"; import { formatDuring } from 'educoder'; @@ -22,6 +22,7 @@ export default Form.create()((props) => { const { getFieldDecorator, validateFields, setFieldsValue } = form; const [applyStatue, setApplyState] = useState(undefined); const [members, setMembers] = useState([]); + const [errorMessage, setErrorMessage] = useState(undefined); // form表单公共处理函数 const helper = useCallback( @@ -53,22 +54,35 @@ export default Form.create()((props) => { //提交报名信息 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)=>{ if(error){ return }else{ - console.log('正确输入'); // 用户输入正确 报名该竞赛 const params = { ...values, + members } - // enrollCompetition(params).then(response=>{ - // console.log(response); - // }) + enrollCompetition(params).then(response=>{ + if(response && response.message === "success"){ + message.success('报名成功') + } + }) } }) } -console.log('members', members); + return (
    @@ -137,11 +151,13 @@ console.log('members', members);
    } {helper('电话', 'phone', - [{ required: true, message: "请正确输入报名信息" }], - {verify("phone")}}/> + [{ required: true, message: "请正确输入报名信息" }, + {pattern: /^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$/, message: "请输入正确的手机号"}], + {verify("phone")}}/> )}
    -

    成员

    +

    成员 :

    +

    {errorMessage}

    {/* */}
    diff --git a/src/military/qz2022/apply/index.scss b/src/military/qz2022/apply/index.scss index 950061ded..528d3d4cd 100644 --- a/src/military/qz2022/apply/index.scss +++ b/src/military/qz2022/apply/index.scss @@ -43,6 +43,8 @@ display: inline-block; width: 33%; margin-right: 160px; + margin-bottom: 0px; + .ant-input:hover{border-color:#2e5bfe;} } .class_from{ display: inline; @@ -104,6 +106,9 @@ &:hover{cursor: pointer;} } } + .error_message{ + color: #f5222d; + } } .apply_but{ padding-bottom: 60px; diff --git a/src/military/qz2022/editTable/index.jsx b/src/military/qz2022/editTable/index.jsx index 7d30e05a1..ec6f0a29a 100644 --- a/src/military/qz2022/editTable/index.jsx +++ b/src/military/qz2022/editTable/index.jsx @@ -17,7 +17,6 @@ class EditableCell extends React.Component { save = (dataIndex, e) => { const { record, handleSave } = this.props; - console.log(dataIndex); this.form.validateFields([dataIndex],(error, values) => { if (error && error[e.currentTarget.id]) { return; @@ -67,28 +66,27 @@ class EditableCell extends React.Component { class EditableTable extends React.Component { constructor(props) { - console.log(props,'表格'); super(props); this.columns = [ { title: '姓名', - dataIndex: 'name', + dataIndex: 'real_name', editable: true, }, { title: '单位', - dataIndex: 'age', + dataIndex: 'org_name', editable: true, width: '30%', }, { title: '职务', - dataIndex: 'address', + dataIndex: 'org_job', editable: true, }, { title: 'JXJXJX', - dataIndex: 'militaryRank', + dataIndex: 'org_rank', editable: true, }, { @@ -108,10 +106,6 @@ class EditableTable extends React.Component { dataSource: [ { key: '0', - name: '', - age: '', - address: '', - militaryRank: '' } ], count: 1, diff --git a/src/military/qz2022/index.scss b/src/military/qz2022/index.scss index 2bbc759c7..9008be73c 100644 --- a/src/military/qz2022/index.scss +++ b/src/military/qz2022/index.scss @@ -42,12 +42,13 @@ } .qzCont { min-height: 35vh; - border-radius: 4px; - box-shadow: 0px 3px 12px #ecf0ff; + border-radius:4px; } } .qz_manage { - top: 510px !important; + .ant-popover-inner-content{ + padding: 0; + } .ant-dropdown-menu-item > a { color: #333; &:hover { diff --git a/src/military/qz2022/management/index.jsx b/src/military/qz2022/management/index.jsx index b668b55a6..ccf022ee8 100644 --- a/src/military/qz2022/management/index.jsx +++ b/src/military/qz2022/management/index.jsx @@ -1,5 +1,5 @@ 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 { formatDuring } from 'educoder'; import {competitionArea, competitionType} from '../static.js'; @@ -7,9 +7,11 @@ import PaginationTable from "../../components/paginationTable"; import './index.scss'; import '../index.scss'; +import { getQzEnrollList, getQzProList, exportEnrollList } from "../api.js"; const Option = Select.Option; -function Introduce({ form, showNotification, match, history:{location:{pathname}} }) { +function Introduce({ form, showNotification, match, history:{location:{pathname}},qzDetail }) { + console.log(qzDetail); // 报名列表和作品列表到指向此处,type做区分,0报名,1作品 const [type, setType] = useState(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght)); const [reload, setReload] = useState(); @@ -18,103 +20,196 @@ function Introduce({ form, showNotification, match, history:{location:{pathname} const [pageSize, setPageSize] = useState(10); const [dataList, setDataList] = useState([]); const [total, setTotal] = useState(0); + // 赛区 赛项 + const [zone, setZone] = useState(undefined); + const [subCompetition, setSubCompetition] = useState(undefined); useEffect(() => { setType(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght)); }, [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(() => { return [ { title: '参赛单位', - dataIndex: 'index' + dataIndex: 'org_name', + width: '10%', + align: 'center' }, { title: '参赛负责人', - dataIndex: 'containerName', - key: 'containerName', + dataIndex: 'leader', + key: 'leader', }, { title: '职务', - dataIndex: 'reviewEndOn', - key: 'reviewEndOn', + dataIndex: 'org_job', + key: 'org_job', }, { title: 'JXJXJX', - dataIndex: 'surplus', - key: 'surplus', + dataIndex: 'org_rank', + key: 'org_rank', }, { title: '电话', - dataIndex: 'status', - key: 'status', + dataIndex: 'phone', + key: 'phone', + }, + { + title: '赛区', + dataIndex: 'zone', + render:(text, record)=>{ + return (qzDetail && qzDetail.zones[text]) || '--'; + } }, { title: '赛项', - dataIndex: 'status', - key: 'action', + dataIndex: 'sub_competition', + render:(text, record)=>{ + return (qzDetail && qzDetail.sub_competitions[text]) || '--'; + } }, { title: '课题来源', - dataIndex: 'status', - key: 'status', + dataIndex: 'subject_source_type', + render:(text, record)=>{ + return text === '0' ? "自主提报" : record.subject_source_name || '--'; + } }, { title: '成员', - dataIndex: 'status', - key: 'action', + dataIndex: 'members', + render:(text, record)=>{ + console.log('members', text); + return ''; + } } ]; - }, []); + }, [qzDetail]); const columns_production = useMemo(() => { return [ { title: '参赛单位', - dataIndex: 'index' + dataIndex: 'org_name' }, { title: '参赛负责人', - dataIndex: 'containerName', - key: 'containerName', + dataIndex: 'leader', }, { title: '赛区', - dataIndex: 'reviewEndOn', - key: 'reviewEndOn', + dataIndex: 'zone', + render:(text, record)=>{ + return (qzDetail && qzDetail.zones[text]) || '--'; + } }, { title: '赛项', - dataIndex: 'surplus', - key: 'surplus', + dataIndex: 'sub_competition', + render:(text, record)=>{ + return (qzDetail && qzDetail.sub_competitions[text]) || '--'; + } }, { title: '作品', - dataIndex: 'status', - key: 'status', + dataIndex: 'sttachments', }, ]; - }, []); + }, [qzDetail]); + const expandRow = (record) =>{ + return
    +
    +
    序号
    +
    姓名
    +
    单位
    +
    职务
    +
    军衔
    +
    + {record.members && record.members.map((item, index)=>{ + return
    +
    {index+1}
    +
    {item.real_name}
    +
    {item.org_job}
    +
    {item.org_rank}
    +
    {item.org_name}
    +
    + })} +
    + } + + const customExpandIcon1 = useMemo((props)=>{ + // console.log(props); + },[dataList]) + + const customExpandIcon = (props) => { + console.log(props); + if(props.record.members.length > 0){ + if (props.expanded) { + return { + props.onExpand(props.record, e); + }}>查看成员 + } else { + return { + props.onExpand(props.record, e); + }}>查看成员 + } + }else{ + return + } + } + + function exportApplyInfo(){ + exportEnrollList(); + } + return (
    启智2022{type === "applys" ? "报名" : "作品"}列表
    -
    +
    赛区: - {setZone(value)}}> - {competitionArea.map(item=> {return })} + {qzDetail && qzDetail.zones.map((item,i)=> {return })} 赛项: - {setSubCompetition(value)}}> - {competitionType.map(item=> {return })} + {qzDetail && qzDetail.sub_competitions.map((item,i)=> {return })}
    - {type === "applys" && } + {type === "applys" && }
    + current={curPage} + expandedRowRender={expandRow} + expandIconColumnIndex={8} + expandIconAsCell={false} + expandIcon={customExpandIcon}/>
    ) } diff --git a/src/military/qz2022/management/index.scss b/src/military/qz2022/management/index.scss index 24782cb10..7feaf794a 100644 --- a/src/military/qz2022/management/index.scss +++ b/src/military/qz2022/management/index.scss @@ -17,4 +17,10 @@ .pagination-table.qzManageTable { padding: 0 30px; } + .expandRowManage .row div{ + display: inline-block; + width: 17%; + text-align: center; + &.job{width: 30%;} + } } diff --git a/src/military/qz2022/refer/Upload.jsx b/src/military/qz2022/refer/Upload.jsx new file mode 100644 index 000000000..8722e0544 --- /dev/null +++ b/src/military/qz2022/refer/Upload.jsx @@ -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 ( + + + (你可以上传小于{size}MB的文件) + + ) +} +export default Uploads; \ No newline at end of file diff --git a/src/military/qz2022/refer/index.jsx b/src/military/qz2022/refer/index.jsx index 859d94457..df9032f21 100644 --- a/src/military/qz2022/refer/index.jsx +++ b/src/military/qz2022/refer/index.jsx @@ -1,8 +1,10 @@ import React, { useState, useCallback, useMemo, useEffect } from "react"; import { Input, Select, Button, Form, DatePicker, Table, Pagination, Upload, Modal, Icon } from 'antd'; +import { appendFileSizeToUploadFileAll } from 'educoder'; import { Link } from "react-router-dom"; import { formatDuring } from 'educoder'; import {httpUrl} from '../fetch.js'; +import {uploadCompetition} from '../api'; import refer_tip from "../image/refer_tip.svg"; import refer from "../image/refer.svg"; @@ -11,23 +13,84 @@ import '../../index.scss'; const Option = Select.Option; 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(() => { }, []); + 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 (
    + }} > -
    上传小于等于256m的作品压缩包(仅限上传一个压缩包)
    +
    上传小于等于256m的作品压缩包(仅限上传一个压缩包,格式如下: .zip, .rar, .tar)
    - +
    ) } diff --git a/src/military/qz2022/refer/index.scss b/src/military/qz2022/refer/index.scss index d797de1d7..4e4b39161 100644 --- a/src/military/qz2022/refer/index.scss +++ b/src/military/qz2022/refer/index.scss @@ -24,4 +24,13 @@ >span{ 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;} } \ No newline at end of file