diff --git a/public/favicon.ico b/public/favicon.ico index 05b9d163..29b4c3af 100755 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/src/App.js b/src/App.js index 789c0af2..b75259ff 100644 --- a/src/App.js +++ b/src/App.js @@ -45,6 +45,11 @@ const OpsDetail = Loadable({ loader: () => import('./forge/DevOps/opsDetail'), loading: Loading, }) +// Notice项目公告 +const Notice = Loadable({ + loader: () => import('./military/notice'), + loading: Loading, +}) //403页面 const Shixunauthority = Loadable({ loader: () => import('./modules/403/Shixunauthority'), @@ -240,6 +245,15 @@ class App extends Component { } } /> + {/*公告*/} + { + return () + } + }> + {/*403*/} diff --git a/src/fetch.js b/src/fetch.js new file mode 100644 index 00000000..6a35c325 --- /dev/null +++ b/src/fetch.js @@ -0,0 +1,80 @@ +import { notification } from 'antd'; +import axios from 'axios'; +import cookie from 'react-cookies'; + +// export const httpUrl='http://117.50.100.12:8001'; +// export const httpUrl='http://192.168.31.72:8081'; +// export const httpUrl='http://192.168.31.72:8083'; +// export const httpUrl = 'http://106.75.31.211:58088'; //可视化 +export const httpUrl = 'http://117.50.100.12:8008'; //公告 +// export const httpUrl = 'http://117.50.100.12:8009'; //公告 + + + +// const TokenKey = 'autologin_forge_military'; +const TokenKey = 'autologin_trustie'; +axios.defaults.withCredentials = true; + +// 创建axios实例 +const service = axios.create({ + baseURL: httpUrl, + timeout: 5000 // 请求超时时间 +}); + + +// request拦截器 +service.interceptors.request.use(config => { + if (cookie.load(TokenKey)) { + config.headers['Authorization'] = cookie.load(TokenKey); // 让每个请求携带自定义token 请根据实际情况自行修改 + } + return config; +}, error => { + // Do something with request error + console.log(error); // for debug + Promise.reject(error); +}); +// respone拦截器 +service.interceptors.response.use( + response => { + const res = response; + if (res.status === 400) { + notification.open({ + message: "提示", + description: '请求错误', + }); + return Promise.reject('error'); + } + if (res.status === 401) { + notification.open({ + message: "提示", + description: '未授权,请登录!', + }); + return Promise.reject('error'); + } + if (res.status === 40001) { + notification.open({ + message: "提示", + description: '账户或密码错误!', + }); + return Promise.reject('error'); + } + if (response.status !== 200 && res.status !== 200) { + notification.open({ + message: "提示", + description: res.message, + }); + } else { + return response.data; + } + }, + error => { + console.log(error); + notification.open({ + message: "提示", + description: error.message, + }); + return Promise.reject(error); + } +); + +export default service; diff --git a/src/military/components/DelModal.jsx b/src/military/components/DelModal.jsx new file mode 100644 index 00000000..b2ba4434 --- /dev/null +++ b/src/military/components/DelModal.jsx @@ -0,0 +1,20 @@ +import { Modal } from 'antd'; + +export default ( + handleOk, + title, + content, + handleCancel) => { + return Modal.confirm({ + title: title || "警告", + content: content || "确认删除?", + okText: '确定', + cancelText: '取消', + onOk() { + handleOk && handleOk(); + }, + onCancel() { + handleCancel && handleCancel(); + } + }); +} \ No newline at end of file diff --git a/src/military/components/chooseNav/index.jsx b/src/military/components/chooseNav/index.jsx new file mode 100644 index 00000000..3f1216c4 --- /dev/null +++ b/src/military/components/chooseNav/index.jsx @@ -0,0 +1,29 @@ +import React, { useEffect, useState } from 'react'; +import classNames from 'classnames'; +import './index.scss'; + +export default (props) => { + const { title, options, changeOptionId, type } = props; + + const [option, setOption] = useState({ code: "", dicItemName: "" ,dicItemCode:""}); + + useEffect(() => { + changeOptionId(option, type); + }, [option]) + + return ( + +
+
{title}
+
+
{ setOption({ code: "", dicItemName: "" }) }}>全部
+ { + options.map((item) => { + return
{ setOption(item) }} >{item.dicItemName}
+ }) + } +
+
+ + ) +} \ No newline at end of file diff --git a/src/military/components/chooseNav/index.scss b/src/military/components/chooseNav/index.scss new file mode 100644 index 00000000..dd8728fa --- /dev/null +++ b/src/military/components/chooseNav/index.scss @@ -0,0 +1,41 @@ +.nav-content { + margin:20px 0; + background: #fff; + border-bottom: 1px solid #eaeaea; + box-shadow: #ddd 0px 0px 5px; +} +.shop-box { + width: 1280px; + border-top: 1px solid #eaeaea; + display: flex; + justify-content: start; +} +.choose-title { + width: 110px; + background: #f3f3f3; + text-align: center; + padding: 16px 0; + font-size: 14px; + color: #666; + font-weight: 600; +} +.choose-list { + width: 1170px; + padding: 16px 0; + display: flex; + justify-content: start; +} +.choose-item { + font-size: 14px; + text-align: center; + padding: 0 15px ; + cursor: pointer; + &:hover{ + color: #0072ff; + } +} + +.choose-item-checked { + color: #0072ff; +} + diff --git a/src/military/components/itemList/index.jsx b/src/military/components/itemList/index.jsx new file mode 100644 index 00000000..fc65227b --- /dev/null +++ b/src/military/components/itemList/index.jsx @@ -0,0 +1,23 @@ +import React from 'react'; +import { NewSvg } from '../../notice/svg'; +import './index.scss'; +export default (props) => { + const { list, itemClick, } = props; + + return ( + list.map(item => { + return ( +
+
{ itemClick(item.id) }}> + {item.achievementName || item.title} {item.new && } +
+
+ {item.publisher &&

发布单位:{item.publisher}

} +

发布时间:{(item.publishDate && item.publishDate.split(' ')[0]) || (item.createTime && item.createTime.split(' ')[0])}

+

{item.visits || 0}

+
+
+ ) + }) + ) +} \ No newline at end of file diff --git a/src/military/components/itemList/index.scss b/src/military/components/itemList/index.scss new file mode 100644 index 00000000..7b2e1be9 --- /dev/null +++ b/src/military/components/itemList/index.scss @@ -0,0 +1,47 @@ +.list-box { + position: relative; + padding: 17px 20px; + background: #fff; + border-bottom: 1px dashed #dedede; +} +.list-title { + font-size: 1rem; + color: #000; + cursor: pointer; + display: flex; + align-items: center; + svg { + margin-left: 0.5rem; + } +} +.list-title:hover { + color: #409eff; +} +.list-title span { + padding: 3px 5px; + margin-left: 0.5em; + background: #f8c753; + font-size: 13px; + color: #fff; + border-radius: 3px; +} + +.list-other { + margin-top: 0.5rem; + display: flex; + align-items: center; + & > p { + display: inline-block; + font-size: 0.875rem; + color: #666; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + p:first-child{ + width: 50%; + } + p:nth-child(2){ + width: 40%; + } +} diff --git a/src/military/index.scss b/src/military/index.scss new file mode 100644 index 00000000..e09fba2e --- /dev/null +++ b/src/military/index.scss @@ -0,0 +1,150 @@ +// 本模块公共样式 + +.centerbox { + width: 1200px; + margin: 40px auto; + position: relative; +} +.head-navigation{ + position: absolute; + top:-2.3em; + span{ + display: inline-flex; + align-items: center; + &:hover{ + color: #409eff; + } + } +} +.center-content { + background: #fff; + border: 1px solid #dedede; + box-shadow: #eee 0px 1px 1px 3px; +} +.centerScreen { + display: flex; + justify-content: space-between; + height: 46px; + background-color: #fff; + border-bottom: 1px solid #dedede; +} + +// 内容标题左侧样式 +.center-left-but { + display: flex; + justify-content: start; + align-items: center; + margin-left: 20px; + font-size: 16px; + font-weight: 600; +} +.center-left-butD { + height: 24px; + font-size: 14px; + font-weight: 500; + line-height: 24px; + color: #333; + padding: 0 10px; + background-color: #fff; + border: 1px solid #dedede; +} +.center-left-butD:hover { + background-color: #fff; + color: #409eff; + cursor: pointer; +} +.center-left-butDACT { + background-color: #409eff; + color: #fff; +} + +// 内容标题右侧样式 +.center-right-but { + display: flex; + align-items: center; +} +.center-right-but > span { + margin: 0 10px; + font-size: 16px; + color: #0089ff; + cursor: pointer; +} + +// 通用标签样式 +.list-tag { + display: inline-block; + margin-right: 10px; + background: #cfe9ff; + color: #0089ff; + font-size: 14px; + border-radius: 3px; + padding: 2px 5px; + line-height: 25px; +} + +// 文件预览modal样式 +.file-modal { + width: 800px !important; + .ant-modal-body { + padding-top: 40px; + .pdf-box { + height: 70vh; + overflow-y: scroll; + } + } + .ant-modal-close { + top: 0 !important; + } + .show-img { + width: 100%; + } + .react-pdf__Page__canvas, + .react-pdf__Page__textContent { + margin: 0 auto; + max-width: 100%; + } +} + +.edit-input { + max-width: 500px; +} + +.link{ + color: #0089ff; + cursor: pointer; + &:hover{ + color:#509eff; + } +} + +.color-grey-a{ + color: #aaa; +} + +.greater{ + position: relative; + top:-1px; +} + +.none_panels{ + display: flex; + justify-content: center; + align-items: center; + flex-flow: column nowrap; + height: 40vh; +} + + +.newFooter .footerInfos>ul { + padding: 0 40px; + box-sizing: border-box; + max-width: 25%; + text-align: left; +} + + +@media screen and (max-width: 1200px){ + .centerbox { + width: 98%; + } +} \ No newline at end of file diff --git a/src/military/notice.js b/src/military/notice.js new file mode 100644 index 00000000..f58084f1 --- /dev/null +++ b/src/military/notice.js @@ -0,0 +1,53 @@ +import React, { Component } from "react"; + +import { Route, Switch } from "react-router-dom"; +import { withRouter } from "react-router"; +import { SnackbarHOC } from "educoder"; +import { CNotificationHOC } from "../modules/courses/common/CNotificationHOC"; +import { TPMIndexHOC } from "../modules/tpm/TPMIndexHOC"; +import Loadable from "react-loadable"; +import Loading from "../Loading"; +import { ImageLayerOfCommentHOC } from "../modules/page/layers/ImageLayerOfCommentHOC"; +import './index.scss'; + +const NoticeList = Loadable({ + loader: () => import("./notice/noticeList"), + loading: Loading, +}); + +const NoticeDetail = Loadable({ + loader: () => import("./notice/noticeDetail"), + loading: Loading, +}); + + +class Index extends Component { + render() { + return ( +
+ + + ( + + )} + > + + ( + + )} + > + +
+ ); + } +} +export default withRouter( + ImageLayerOfCommentHOC({ + imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget", + parentSelector: ".newMain", + })(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(Index)))) +); diff --git a/src/military/notice/api.js b/src/military/notice/api.js new file mode 100644 index 00000000..53e72fa8 --- /dev/null +++ b/src/military/notice/api.js @@ -0,0 +1,39 @@ +import fetch from '../../fetch'; +import { notification } from 'antd'; + + +// 公告列表查询 +export async function getNoticeList(params) { + let res = await fetch({ + url: '/api/announcements/', + method: 'get', + params, + }); + if (res.code === '1') { + return res.data; + } else { + notification.open({ + message: "提示", + description: res.message || '请求错误', + }); + } +} + + +// 公告详情查询 +export async function getNoticeDetail(id) { + let res = await fetch({ + url: '/api/announcements/' + id, + method: 'get', + params:{flag:1} + }); + if (res.code === '1') { + return res.data; + } else { + notification.open({ + message: "提示", + description: res.message || '请求错误', + }); + } +} + diff --git a/src/military/notice/image/banner.png b/src/military/notice/image/banner.png new file mode 100644 index 00000000..3f969834 Binary files /dev/null and b/src/military/notice/image/banner.png differ diff --git a/src/military/notice/noticeDetail/index.jsx b/src/military/notice/noticeDetail/index.jsx new file mode 100644 index 00000000..b68b521d --- /dev/null +++ b/src/military/notice/noticeDetail/index.jsx @@ -0,0 +1,78 @@ +import React, { useEffect, useState } from 'react'; +import { Icon, } from 'antd'; +import { Link } from "react-router-dom"; +import { httpUrl } from '../../../fetch'; +import { getNoticeDetail } from '../api'; +import { noticeType } from '../static'; +import './index.scss'; + +const noticeTypeArr = []; +for (const item of noticeType) { + noticeTypeArr[item.code]=item.name; +} + +export default ({ match, history, showNotification }) => { + const [noticeData, setNoticeData] = useState({}); + const id = match.params.noticeId; + + useEffect(() => { + id && getNoticeDetail(id).then(data => { + if(data){ + data.publishDate=data.publishDate.split(' ')[0]; + data.createdAt=data.createdAt.split(' ')[0]; + data.closingDate=data.closingDate.split(' ')[0]; + } + setNoticeData(data || {}); + }) + }, [id]); + + return ( + + +
+
+ 首页 >  + 公告 >  + 公告详情 >  +
+
+ {/*
*/} +
+ {noticeData.title} +
+
+
+

公告类型:{noticeTypeArr[noticeData.type]}

+ {noticeData.publisher &&

发布单位:{noticeData.publisher}

} +

发布时间:{noticeData.publishDate || noticeData.createdAt}

+

截止时间:{noticeData.closingDate}

+

浏览:{noticeData.visits || 0}

+
+ +
+
公告主要内容
+
+
+
+ + { + noticeData.fileDownloadPath && + +
公告附件
+

+ { window.open(httpUrl + noticeData.fileDownloadPath) }}> + {noticeData.fileName} + + { window.open(httpUrl + noticeData.fileDownloadPath) }}>下载 +

+
+ } + +
+
+ +
+ + + ) +} diff --git a/src/military/notice/noticeDetail/index.scss b/src/military/notice/noticeDetail/index.scss new file mode 100644 index 00000000..073503a1 --- /dev/null +++ b/src/military/notice/noticeDetail/index.scss @@ -0,0 +1,75 @@ +.centerbox { + position: relative; +} +.notice-detail { + margin-top: 3.5rem; + .head-navigation { + top: -2.5rem; + } + .center-content { + overflow: auto; + border: 0; + } +} + +.notice-detail-content { + padding: 2rem 2.5rem 3rem; + + .anticon-caret-right { + color: #1890ff; + font-size: 1rem; + } +} + +.notice-title { + margin: 3rem auto 0; + text-align: center; + font-size: 1.375rem; + font-weight: bold; + line-height: 1.375rem; + color: #000000; +} + +// 内容详情 +.item-content { + padding: 10px 10px 0 30px; +} +.content-notice { + padding: 20px; +} + +.center-author { + display: flex; + flex-flow:row wrap-reverse; + justify-content: space-around; + align-items: center; + padding: .5rem; + background: #f9f9f9; + color: #333; + p { + padding: 0 .5rem; + } +} + +.content-text { + margin: 1.25rem 0; + min-height: 30vh; +} + +.notice-content-title { + margin: 0.5rem 0; + font-size: 1rem; + font-weight: bold; +} + +.notice-content-download { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 1rem; + background: #f9f9f9; + span:hover{ + cursor: pointer; + color: #1890ff; + } +} diff --git a/src/military/notice/noticeList/index.jsx b/src/military/notice/noticeList/index.jsx new file mode 100644 index 00000000..46fa5848 --- /dev/null +++ b/src/military/notice/noticeList/index.jsx @@ -0,0 +1,333 @@ +import React, { useEffect, useState } from 'react'; +import classNames from 'classnames'; +import { Pagination, Icon, Input, Tabs } from 'antd'; +import { Link } from "react-router-dom"; +import ItemList from '../../components/itemList'; +import Nodata from '../../../forge/Nodata'; +import Loading from "../../../Loading"; +import { AbandonSvg, AllSvg, ChangeSvg, CheckSvg } from '../svg'; +import noticePng from '../image/banner.png'; +import { getNoticeList } from '../api'; + +import './index.scss'; +const Search = Input.Search; +const { TabPane } = Tabs; + +const defaultColor = '#1890ff'; +const activeColor = '#fff'; + +export default (props) => { + + const [tab, setTab] = useState('0'); + const [loading, setLoading] = useState(false); + + const [title, setTitle] = useState(undefined); + const [orderBy, setOrderBy] = useState('publishDateDesc'); + + const [curPage, setCurPage] = useState(1); + const [total, setTotal] = useState(0); + const [noticeList, setNoticeList] = useState([]); + + const [changeList, setChangeList] = useState([]); + const [checkList, setCheckList] = useState([]); + const [abandonList, setAbandonList] = useState([]); + + + + useEffect(() => { + setLoading(true); + if (tab === '0') { + const params = { + orderBy, + curPage: 1, + isChecked: 1, + pageSize: 5, + status: 1, + type: 1, + title, + flag: 1, //后台管理查询:2;前台展示:1 + }; + getNoticeList(params).then(data => { + setChangeList(data.rows); + }); + getNoticeList({ ...params, type: 2 }).then(data => { + setCheckList(data.rows); + }); + getNoticeList({ ...params, type: 3 }).then(data => { + setAbandonList(data.rows); + setLoading(false); + }); + } else { + const params = { + orderBy, + curPage, + isChecked: 1, + pageSize: 10, + status: 1, + title, + type: tab, + flag: 1, //后台管理查询:2;前台展示:1 + }; + getNoticeList(params).then(data => { + setNoticeList(data.rows); + setTotal(data.total); + setLoading(false); + }) + } + }, [tab, title, orderBy, curPage]); + + + function changeSort(sortType) { + setOrderBy(sortType); + setCurPage(1); + } + + function noticeClick(id) { + props.history.push(`/notice/noticeDetail/${id}`); + } + + function sortNav() { + return
+ {/*
*/} + 搜索} + onSearch={(value) => setTitle(value)} /> + {/*
*/} +
+
{ changeSort('publishDateDesc') }}>时间降序
+ | +
{ changeSort('publishDateAsc') }}>时间升序
+
+
+ } + + function changeTab(key) { + setTab(key); + setCurPage(1); + setTitle(''); + setOrderBy('publishDateDesc'); + } + + return ( + + 图片加载失败 +
+
+ 首页 >  + 公告 >  +
+ { changeTab(key) }}> + + + 全部公告 + + } + key="0"> + + +
+ { + sortNav() + } + + { + loading ? : + + + {changeList.length > 0 && +
+
+ + 更正公告 +
+ {changeList.length === 5 && { changeTab('1') }}>查看更多 } +
+ +
+ } + + {checkList.length > 0 && +
+
+ + 中标公告 +
+ {checkList.length === 5 && { changeTab('2') }}>查看更多 } +
+ +
+ } + + {abandonList.length > 0 && +
+
+ + 废标公告 +
+ {abandonList.length === 5 && { changeTab('3') }}>查看更多 } +
+ +
+ } + + {changeList.length === 0 && checkList.length === 0 && abandonList.length === 0 && } + +
+ } + +
+
+ + + + + 更正公告 + + } + key="1"> + +
+ { + sortNav() + } + + { + loading ? : + +
+
+ + 更正公告 +
+
+ + {noticeList.length > 0 ?
+ { setCurPage(page) }} + current={curPage} + total={total} + showTotal={total => `共 ${total} 条`} + /> +
: } +
+ } + +
+
+ + + + + + 中标公告 + + } + key="2"> + + +
+ { + sortNav() + } + + { + loading ? : + +
+
+ + 中标公告 +
+
+ + {noticeList.length > 0 ?
+ { setCurPage(page) }} + current={curPage} + total={total} + showTotal={total => `共 ${total} 条`} + /> +
: } +
+ } + +
+
+ + + + + 废标公告 + + } + key="3"> + +
+ { + sortNav() + } + + { + loading ? : + +
+
+ + 废标公告 +
+
+ + {noticeList.length > 0 ?
+ { setCurPage(page) }} + current={curPage} + total={total} + showTotal={total => `共 ${total} 条`} + /> +
: } +
+ } +
+ +
+
+ +
+ +
+ + + ) +} \ No newline at end of file diff --git a/src/military/notice/noticeList/index.scss b/src/military/notice/noticeList/index.scss new file mode 100644 index 00000000..4fc4559e --- /dev/null +++ b/src/military/notice/noticeList/index.scss @@ -0,0 +1,95 @@ +.notice-list{ + .ant-tabs { + .ant-tabs-left-bar{ + border: 1px solid #E5E5E5; + .ant-tabs-nav-container{ + margin-right: 0; + } + .ant-tabs-nav-wrap{ + margin-right: 0; + } + + svg{ + margin-right:.75em; + } + } + .ant-tabs-tab{ + display: flex; + justify-content: start; + align-items: center; + margin-bottom: 0.5rem; + width: 13.5rem; + height: 2.8125rem; + background: #fff; + font-size: 1.125rem; + + } + .ant-tabs-left-content{ + border: 0; + } + .ant-tabs-tab-active{ + background: #1890FF; + color: #fff; + } + .ant-tabs-ink-bar{ + display: none !important; + } + } + + + .notice-sort-nav{ + display: flex; + justify-content: space-between; + padding: .625rem 1rem .5rem; + background: #f5f5f5; + } + + .notice-center-content{ + padding:1.25rem; + background: #fff; + + + } + + .item-head-title{ + display: flex; + justify-content: space-between; + align-items: center; + // height: 3.75rem; + padding: 1.25rem 0 .6rem 0; + .item-head-title-content{ + display: flex; + align-items: center; + font-size: 1rem; + font-weight: bold; + } + } + + + .ant-input-group-addon{ + border: 0 !important; + } + + .item-head-title{ + border-bottom: 1px solid #E5E5E5; + } + +} + +.center-right-but{ + .piece{ + margin:0 .8rem; + color: #aaa; + } + .sortLink{ + color: #333; + cursor: pointer; + &:hover{ + color: #1890FF; + } + &.active{ + color: #1890FF; + } + } +} + diff --git a/src/military/notice/static.js b/src/military/notice/static.js new file mode 100644 index 00000000..786a7880 --- /dev/null +++ b/src/military/notice/static.js @@ -0,0 +1,19 @@ +// 公告开始 +export const noticeStatus = [ + { code: 0, name: "关闭", dicItemName: '关闭' }, + { code: 1, name: "正常", dicItemName: '正常' }, + { code: 2, name: "草稿", dicItemName: '草稿' }, +]; + +export const noticeType = [ + { code: 1, name: "更正公告", dicItemName: "更正" }, + { code: 2, name: "中标公告", dicItemName: "中标" }, + { code: 3, name: "废标公告", dicItemName: "废标" }, +]; + +export const noticeChecked = [ + { code: 0, name: "未通过", dicItemName: "未通过" }, + { code: 1, name: "通过", dicItemName: "通过" }, + { code: 2, name: "未处理", dicItemName: "未处理" }, +]; +//公告结束 \ No newline at end of file diff --git a/src/military/notice/svg.js b/src/military/notice/svg.js new file mode 100644 index 00000000..2d208396 --- /dev/null +++ b/src/military/notice/svg.js @@ -0,0 +1,66 @@ +import React from 'react'; + +export function AbandonSvg({color}) { + return + + + + + + + + + + +} + +export function AllSvg({color}) { + return + + + + + + + + + + +} + +export function ChangeSvg({color}) { + return + + + + + + + + +} + +export function CheckSvg({color}) { + return + + + + + + + + + + + + + +} + +export function NewSvg() { + return + + + + +} \ No newline at end of file