diff --git a/src/forge/Index.js b/src/forge/Index.js index 062a03dd..ddf7552c 100644 --- a/src/forge/Index.js +++ b/src/forge/Index.js @@ -61,6 +61,12 @@ class Index extends Component { )} > + ( + + )} + > ( diff --git a/src/forge/Main/IndexItem.js b/src/forge/Main/IndexItem.js index fecadb13..ac5eb23c 100644 --- a/src/forge/Main/IndexItem.js +++ b/src/forge/Main/IndexItem.js @@ -10,12 +10,12 @@ import img_parise from '../Images/parise.png'; import SpecialModal from './SpecialModal'; class IndexItem extends Component { - constructor(props){ + constructor(props) { super(props); - this.state={ - visible:false, - user_apply_signatures:[], - project_id:undefined + this.state = { + visible: false, + user_apply_signatures: [], + project_id: undefined } } TurnToDetail = (login, url) => { @@ -31,31 +31,31 @@ class IndexItem extends Component { * is_secret:是否是特殊开源许可证项目 * id:创建者login * is_member:是否是项目成员(如果是项目成员可以直接进入项目) - * */ - projectHref=(link , user_apply_signatures,project_id,is_secret , id,is_member)=>{ - const { user , showLoginDialog } = this.props; - if(is_secret && (!user || (user && !user.login))){ + * */ + projectHref = (link, user_apply_signatures, project_id, is_secret, id, is_member) => { + const { user, showLoginDialog } = this.props; + if (is_secret && (!user || (user && !user.login))) { showLoginDialog(); return; } let signa = user_apply_signatures && user_apply_signatures[0]; - if((is_secret && !is_member && (!signa || (signa && signa.status !== "passed"))) && user.login !== id ){ + if ((is_secret && !is_member && (!signa || (signa && signa.status !== "passed"))) && user.login !== id) { this.setState({ - visible:true, - user_apply_signatures:user_apply_signatures.length>0 ? user_apply_signatures[0] : undefined, + visible: true, + user_apply_signatures: user_apply_signatures.length > 0 ? user_apply_signatures[0] : undefined, project_id }) - }else{ + } else { this.props.history.push(link); } } - hideModal=()=>{ + hideModal = () => { this.setState({ - visible:false + visible: false }) } - sureModal=()=>{ + sureModal = () => { this.hideModal(); const { getListData } = this.props; getListData && getListData(1); @@ -63,26 +63,26 @@ class IndexItem extends Component { render() { const { projects } = this.props; - const { visible , user_apply_signatures , project_id } = this.state; + const { visible, user_apply_signatures, project_id } = this.state; return ( -
+
- { projects && projects.length > 0 ? projects.map((item, key) => { + {projects && projects.length > 0 ? projects.map((item, key) => { return (
{ item.platform === "educoder" ? - - - - : - - - + + + + : + + + }
-

{item.description}

+

{item.description}

@@ -122,7 +142,7 @@ class IndexItem extends Component {
) }) : - } + }
) } diff --git a/src/forge/Main/SpecialModal.jsx b/src/forge/Main/SpecialModal.jsx index 2c9a21f8..dd1fab9e 100644 --- a/src/forge/Main/SpecialModal.jsx +++ b/src/forge/Main/SpecialModal.jsx @@ -16,8 +16,10 @@ function SpecialModal({ visible , hideModal , sureModal , showNotification , use function sure(){ if(!user_apply_signatures || (user_apply_signatures && user_apply_signatures.status !== "waiting")){ if(!id || (id && id.length === 0)){ - // showNotification("请先提交文件进行审核!"); - getUrl(`/api/apply_signatures/template_file`) + const a = document.createElement('a'); + a.href = getUrl(`/api/apply_signatures/template_file`); + a.click(); // 下载 + showNotification("请先提交文件进行审核!"); return; } const url = `/apply_signatures.json`; diff --git a/src/forge/Main/projecthome/SubBanner.jsx b/src/forge/Main/projecthome/SubBanner.jsx index cb868b94..4be1b238 100644 --- a/src/forge/Main/projecthome/SubBanner.jsx +++ b/src/forge/Main/projecthome/SubBanner.jsx @@ -50,7 +50,7 @@ function SubBanner() { return(
-

GitLink 确实开源

+

osredm 红山开源

新一代开发创新服务平台 让你的创意在这里释放

{ diff --git a/src/forge/SecuritySetting/Index.jsx b/src/forge/SecuritySetting/Index.jsx index c010befe..830b1157 100644 --- a/src/forge/SecuritySetting/Index.jsx +++ b/src/forge/SecuritySetting/Index.jsx @@ -96,15 +96,15 @@ function Index(props){
  • 消息通知
  • -1 && pathname.indexOf("/settings/notice/config") == -1) || pathname.indexOf("/settings/notice/privateLetter")>-1 ?"active":""}>我的通知
  • -1 ?"active":""}>通知管理
  • - } -
      -
    • 安全设置
    • -
    • -1 ?"active":""}>SSH密钥
    • -
    */} -
      +
    } */} + {pathname.indexOf("/settings/notice")>-1 &&
    • 消息通知
    • -1 && pathname.indexOf("/settings/notice/config") == -1) || pathname.indexOf("/settings/notice/privateLetter")>-1 ?"active":""}>我的通知
    • -
    + } + {pathname.indexOf("/settings/SSH")>-1 &&
      +
    • 安全设置
    • +
    • -1 ?"active":""}>SSH密钥
    • +
    }
    diff --git a/src/forge/Settings/Index.js b/src/forge/Settings/Index.js index 78c4636d..ae957911 100644 --- a/src/forge/Settings/Index.js +++ b/src/forge/Settings/Index.js @@ -113,7 +113,7 @@ class Index extends Component {

    { - false && projectDetail && projectDetail.permission && (projectDetail.permission === "Owner" || projectDetail.permission === "Admin") ? + projectDetail && projectDetail.permission && (projectDetail.permission === "Owner" || projectDetail.permission === "Admin") ?
  • -1 ? "active" : ""} > diff --git a/src/military/components/ExportWord.js b/src/military/components/ExportWord.js new file mode 100644 index 00000000..10479c4b --- /dev/null +++ b/src/military/components/ExportWord.js @@ -0,0 +1,97 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +// todo 支持图表,例如echart +const propTypes = { + wordId: PropTypes.string, // wordID + fileName: PropTypes.string, // 导出文件的名字 + title: PropTypes.element, // 名称标题 + styles: PropTypes.string, // word中的样式 +}; + +const defaultProps = { + wordId: '', + className:'', + fileName: 'filename', + title: '导出Word', + styles: 'table{width:100%} ', + success:()=>{}, +}; + +class ExportWord extends Component { + + exportWord = () => { + const { wordId, fileName } = this.props; + this.getBlob(wordId, fileName); + }; + + + getBlob = (wordId, fileName) => { + // IE10 以下 + if (typeof window === 'undefined' || (typeof navigator !== 'undefined' && /MSIE [1-9]\./.test(navigator.userAgent))) { + return; + } + const location =window.location; + const mHtml = { + top: `Mime-Version: 1.0\nContent-Base: ${location.href}\nContent-Type: Multipart/related; boundary="NEXT.ITEM-BOUNDARY";type="text/html"\n\n--NEXT.ITEM-BOUNDARY\nContent-Type: text/html; charset="utf-8"\nContent-Location: ${location.href}\n\n\n\n_html_`, + head: '\n\n\n\n', + body: '_body_', + }; + + const activeDoc = document.getElementById(wordId); // 获取 dom 节点 + + if(activeDoc.querySelector(".markdown-body")){ + let imgNode =activeDoc.querySelectorAll('.markdown-body img'); + if(imgNode.length){ + for(const item of imgNode){ + let itemSrc=item.getAttribute('src'); + if(itemSrc.indexOf('http')===-1){ + item.setAttribute('src',location.origin+itemSrc); + } + } + } + } + + // 默认样式 + const defaultStyle = '.text-div{ text-decoration: underline; margin-right: 15px; } .textarea-div{ text-decoration: underline; } table td,table th{padding: 6px 13px;border: 1px solid #ddd;} table{border-collapse: collapse;}'; + const mHtmlBottom = '\n--NEXT.ITEM-BOUNDARY--';// 文件尾信息 + + // 替换模板里的内容 + const fileContent = mHtml.top.replace('_html_', mHtml.head.replace('_styles_', defaultStyle ) + mHtml.body.replace('_body_', activeDoc.innerHTML)) + mHtmlBottom; + // 创建包含文件内容的blob + const blob = new Blob([fileContent], { type: 'application/msword;charset=utf-8' }); + // 下载word文件 + this.saveAs(blob, `${fileName}.doc`); + // 下载成功后执行回调方法 + this.props.success(); + }; + + + saveAs = (blob, name) => { // 实现下载操作 + // IE 10+ (native saveAs) + if (typeof navigator !== 'undefined' && navigator.msSaveOrOpenBlob) { + return navigator.msSaveOrOpenBlob(blob, name); + } + const urlObj = window.URL || window.webkitURL || window; + const objectUrl = urlObj.createObjectURL(blob); + const a = document.createElement('a'); + a.href = objectUrl; + // 模拟点击事件 + a.download = name; + a.click(); // 下载 + }; + + + render() { + const { title,className } = this.props; + return ( + + {title} + + ); + } +} + +ExportWord.propTypes = propTypes; +ExportWord.defaultProps = defaultProps; +export default ExportWord; diff --git a/src/military/components/adminRouter/index.jsx b/src/military/components/adminRouter/index.jsx index 2328006a..3325c868 100644 --- a/src/military/components/adminRouter/index.jsx +++ b/src/military/components/adminRouter/index.jsx @@ -38,7 +38,7 @@ export default props => { 行业信息 职位信息 需求导入模板 - 签订协议内容 + 协议签订模板 应征投稿协议内容 diff --git a/src/military/expert/components/exportExcel/index.js b/src/military/expert/components/exportExcel/index.js deleted file mode 100644 index 38e57814..00000000 --- a/src/military/expert/components/exportExcel/index.js +++ /dev/null @@ -1,200 +0,0 @@ -import React, {Component} from 'react'; -import {Button} from 'antd'; -import PropTypes from "prop-types"; - -const propTypes = { - tableClass: PropTypes.string, // tableClass - fileName: PropTypes.string, // 导出文件的名字 - worksheet: PropTypes.string, //导出工作簿名字 - // colors: PropTypes.string, // button 样式 - // size: PropTypes.string, //按钮大小(lg xg sm md) - // style: PropTypes.string, // 按钮样式 - // exportIcon: PropTypes.element, // 自定义导出图标 - title: PropTypes.element, //名称标题 - filterElement: PropTypes.array, //过滤元素 -}; - -const defaultProps = { - tableClass: '', - fileName: "filename", - worksheet: 'worksheet', - // colors: "primary", - // size: 'sm', - // style: '', - exportIcon: null, - title: '导出', - filterElement: ['button'] -}; - -class ExportExcel extends Component { - exportExcel = () => { - const {tableClass, fileName, worksheet} = this.props; - if (this.getExplorer() === 'ie') { - //创建AX对象excel - const curTbl = document.querySelector(tableClass).cloneNode(true); - // eslint-disable-next-line no-undef - let oXL = new ActiveXObject("Excel.Application"); - let oWB = oXL.Workbooks.Add(); //获取workbook对象 - let xlSheet = oWB.Worksheets(1); //激活当前sheet - let sel = document.body.createTextRange(); //把表格中的内容移到TextRange中 - sel.moveToElementText(curTbl); - sel.select;//全选TextRange中内容 - sel.execCommand("Copy");//复制TextRange中内容 - xlSheet.Paste(); //粘贴到活动的EXCEL中 - oXL.Visible = true; //设置excel可见属性 - let fName = null; - try { - fName = oXL.Application.GetSaveAsFilename("Excel.xls", "Excel Spreadsheets (*.xls), *.xls"); - } catch (e) { - } finally { - oWB.SaveAs(fName); - // oWB.Close(savechanges = false); - oXL.Quit(); - oXL = null; - // 下面代码用于解决IE call Excel的一个BUG, MSDN中提供的方法: - // setTimeout(CollectGarbage, 1); - // 由于不能清除(或同步)网页的受信任状态, 所以将导致SaveAs()等方法在 - // 下次调用时无效. - window.location.reload(); - } - - } else { - this.tableToExcel(tableClass, fileName, worksheet) - } - } - - - traverseNodes = (node, newTd) => { - if (node.hasChildNodes) { - const sonNodes = node.childNodes; - const {filterElement} = this.props; - for (let sonNode of sonNodes) { - if (!filterElement.includes(sonNode.nodeName.toLowerCase())) { // 对不必要对element过滤 - this.traverseNodes(sonNode, newTd); - } - - } - } - return this.display(node, newTd); - } - - display = (node, newTd) => { - const {nodeName, nodeValue} = node; - let newSpan = document.createElement("span"); - newSpan.innerText = nodeValue; - if (nodeName === 'INPUT' || nodeName === 'TEXTAREA') { // 对 input 处理 - const {type, checked, value} = node; - newSpan.innerText = value; - if (type === 'radio' || type === 'checkbox') { - console.log("type", type) - newSpan.innerText = type === 'radio' ? (checked ? "●" : "○") : (checked ? "■" : "□"); - newSpan.style.fontSize = '16px'; - newSpan.style.paddingLeft = '15px'; - } - } - if (node.nodeName === 'IMG') { - const {width, height} = node; - newTd.appendChild(node); - newTd.style.height = height + "px"; - newTd.style.width = width + "px"; - } - if (newSpan.innerText.trim()) { - newTd.appendChild(newSpan); - } - - return newTd - } - - - tableToExcel = (table, fileName, worksheet) => { - const uri = 'data:application/vnd.ms-excel;base64,'; - // 定义文档的类型 - const template = '{table}
    '; - const base64 = function (s) { - return window.btoa(unescape(encodeURIComponent(s))) - }; - // 将template中的变量替换为页面内容ctx获取到的值 - const format = function (s, c) { - return s.replace(/{(\w+)}/g, function (m, p) { - return c[p]; - }) - } - if (!table.nodeType) { - table = document.querySelector(table).cloneNode(true); - } - - let newTable = document.createElement("table"); - const trArray = table.getElementsByTagName('tr'); - for (let trItem of trArray) { - let newTr = document.createElement("tr"); - const thArray = trItem.getElementsByTagName('th'); - const tdArray = trItem.getElementsByTagName('td'); - for (let thItem of thArray) { - let newTh = document.createElement("th"); - const {rowSpan = 1, colSpan = 1, style} = thItem; - this.traverseNodes(thItem, newTh); - newTh.rowSpan = rowSpan; //跨行 - newTh.colSpan = colSpan; //跨列 - newTh.style = style; // 样式 - newTr.appendChild(newTh); - } - for (let tdItem of tdArray) { - let newTd = document.createElement("td"); - const {rowSpan = 1, colSpan = 1, style} = tdItem; - this.traverseNodes(tdItem, newTd); - newTd.rowSpan = rowSpan; //跨行 - newTd.colSpan = colSpan; //跨列 - newTd.style = style; // 样式 - newTr.appendChild(newTd); - } - if (newTr.childNodes.length > 1) { - newTable.appendChild(newTr); - } - } - const ctx = {worksheet, table: newTable.innerHTML}; // 获取表单的名字和表单查询的内容 - const a = document.createElement("a"); // 虚拟一个a 标签 - // format()函数:通过格式操作使任意类型的数据转换成一个字符串 - // base64():进行编码 - a.href = uri + base64(format(template, ctx)); - a.download = fileName + ".xls";//设置文件的名字 - a.click();// 下载 - } - - // 获取当前浏览器 - getExplorer = () => { - const explorer = window.navigator.userAgent; - if (explorer.indexOf("MSIE") >= 0) { //ie - return 'ie'; - } - else if (explorer.indexOf("Firefox") >= 0) { //firefox - return 'Firefox'; - } - else if (explorer.indexOf("Chrome") >= 0) { //Chrome - return 'Chrome'; - } - else if (explorer.indexOf("Opera") >= 0) { //Opera - return 'Opera'; - } - else if (explorer.indexOf("Safari") >= 0) { //Safari - return 'Safari'; - } - } - - render() { - const {colors, exportIcon, size, title} = this.props; - return ( - - ) - } -} - -ExportExcel.propTypes = propTypes; -ExportExcel.defaultProps = defaultProps; -export default ExportExcel; diff --git a/src/military/expert/fetch.js b/src/military/expert/fetch.js index 9cb95bd5..ca278fde 100644 --- a/src/military/expert/fetch.js +++ b/src/military/expert/fetch.js @@ -3,7 +3,7 @@ import javaFetch from '../javaFetch'; let settings = localStorage.chromesetting && JSON.parse(localStorage.chromesetting); -let actionUrl = settings && settings.api_urls && settings.api_urls.expert ? settings.api_urls.expert : 'http://111.8.36.180:8094'; +let actionUrl = settings && settings.api_urls && settings.api_urls.task ? settings.api_urls.task : 'https://task.osredm.com'; const service = javaFetch(actionUrl); export const httpUrl = actionUrl; export const main_web_site_url = settings && settings.main_web_site_url; diff --git a/src/military/managements.js b/src/military/managements.js index 098b8f02..dacec72e 100644 --- a/src/military/managements.js +++ b/src/military/managements.js @@ -44,6 +44,12 @@ const AgreementManage = Loadable({ loading: Loading, }); +// 协议签订模板 +const AgreementContent = Loadable({ + loader: () => import("./task/agreementContent"), + loading: Loading, +}); + const PayProof = Loadable({ loader: () => import("./task/payProof"), loading: Loading, @@ -146,6 +152,14 @@ const Managements = (propsF) => { )} > + {/* 协议内容 */} + ( + + )} + > + {/* 管理员上传支付凭证 */} { + const { getFieldDecorator, validateFields, setFieldsValue } = form; + + const [id,setId]=useState(0); + const [content,setContent]=useState(null); + + useEffect(()=>{ + getAgreement({title:'协议模板'}).then(res=>{ + if(res.data){ + setContent(res.data.content); + setId(res.data.id); + } + }) + },[]) + + // 保存,包括新增和修改 + function saveFile() { + validateFields((err, values) => { + if (!err) { + id?agreementEdit({ + ...values, + userId:current_user.user_id, + id, + }).then((res) => dealRes(res)): + agreementAdd({ + ...values, + userId:current_user.user_id, + id:0, + }).then((res) => dealRes(res)) + } + }) + } + + function dealRes(res) { + if (res && res.message === "success") { + showNotification("操作成功"); + } else { + message.error(res&&res.message||'操作失败'); + } + } + + function onContentChange(value) { + setContent(value); + setFieldsValue({ + content: value + }); + }; + + const helper = useCallback( + (label, name, rules, widget, initialValue, rightComponent) => ( + + {getFieldDecorator(name, { rules, initialValue, validateFirst: true })( + widget + )} + {rightComponent} + + ),[]); + + return ( +
    + {helper( + "协议名称", + "title", + [{ required: true, message: "请输入协议名称" }], + , + "协议模板" + )} + + + + {getFieldDecorator("content", { + rules: [{ required: true, message: "请输入协议内容" }], + validateFirst: true, + })()} + + + +
    + ); +}); diff --git a/src/military/task/agreementContent/index.scss b/src/military/task/agreementContent/index.scss new file mode 100644 index 00000000..2c63fa4b --- /dev/null +++ b/src/military/task/agreementContent/index.scss @@ -0,0 +1,5 @@ +.agreement-content{ + .agreement-content-title{ + display: inline-block; + } +} \ No newline at end of file diff --git a/src/military/task/api.js b/src/military/task/api.js index 01655030..96f7684f 100644 --- a/src/military/task/api.js +++ b/src/military/task/api.js @@ -288,12 +288,30 @@ export function checkHavePaper(taskId) { }); } +// 新增协议 +export function agreementAdd(data) { + return fetch({ + url: '/api/paper/agreementSettings/', + method: 'post', + data, + }); +} + +// 修改协议 +export function agreementEdit(data) { + return fetch({ + url: '/api/paper/agreementSettings/', + method: 'put', + data + }); +} // 获取协议 -export function getAgreement() { +export function getAgreement(params) { return fetch({ - url: '/api/paper/agreementSettings/1', - method: 'get' + url: `/api/paper/agreementSettings/${params==1?params:''}`, + method: 'get', + params:params!=1?params:null }); } diff --git a/src/military/task/components/agreementModal/index.jsx b/src/military/task/components/agreementModal/index.jsx index 294df42f..00cb937b 100644 --- a/src/military/task/components/agreementModal/index.jsx +++ b/src/military/task/components/agreementModal/index.jsx @@ -1,7 +1,10 @@ -import React, { useState, } from 'react'; +import React, { useEffect, useState, } from 'react'; import { Modal, Form, Input, } from 'antd'; +import RenderHtml from 'src/components/render-html'; import Upload from 'military/components/Upload'; -import { uploadAgreePaper } from "../../api"; +import ExportWord from 'military/components/ExportWord'; +import { uploadAgreePaper,getAgreement } from "../../api"; + import '../../index.scss'; @@ -10,6 +13,15 @@ export default Form.create()(props => { const { getFieldDecorator, validateFields, setFieldsValue, } = form; const [fileList, setFileList] = useState([]); + const [content,setContent]=useState(''); + + useEffect(()=>{ + visible && getAgreement({title:'协议模板'}).then(res=>{ + if(res.data){ + setContent(res.data.content); + } + }) + },visible) // 上传附件后得到的文件数组 @@ -55,8 +67,14 @@ export default Form.create()(props => {
    {/* paperAuditing */} {checkedItem.paperAuditing &&

    审核意见:{checkedItem.paperAuditing.message}

    } - 协议样板.word - + + + { validateFirst: true })()} +
    + +
    ) diff --git a/src/military/task/components/complainModal/index.scss b/src/military/task/components/complainModal/index.scss deleted file mode 100644 index e69de29b..00000000 diff --git a/src/military/task/index.scss b/src/military/task/index.scss index 36be5da3..0744cbea 100644 --- a/src/military/task/index.scss +++ b/src/military/task/index.scss @@ -88,7 +88,7 @@ span.list-gray { } .center-content .ant-pagination { - margin: 2rem auto; + margin: 2rem auto !important; text-align: center; .ant-pagination-item:focus, .ant-pagination-item:hover, .ant-pagination-item-active, .ant-pagination-prev:hover a, .ant-pagination-next:hover a, .ant-pagination-options-quick-jumper input:focus, .ant-pagination-options-quick-jumper input:hover{ border-color: #4154f1; diff --git a/src/military/task/paperComplain/index.js b/src/military/task/paperComplain/index.js index a8564856..967826df 100644 --- a/src/military/task/paperComplain/index.js +++ b/src/military/task/paperComplain/index.js @@ -95,16 +95,16 @@ export default Form.create()(({ form, showNotification, history}) => { const columns = useMemo(() => { return [ { - title: '序号', - dataIndex: 'index', - render: (text, record, index) => { - return index + 1 + title: '成果编号', + dataIndex: 'paperNumber', + render: (text, record) => { + return text ? {text} : '--' } }, { title: '申诉内容', dataIndex: 'content', - width: "30%", + width: "26%", }, { title: '申诉文件', diff --git a/src/military/task/paperManage/index.jsx b/src/military/task/paperManage/index.jsx index 6c26eda4..8f38481b 100644 --- a/src/military/task/paperManage/index.jsx +++ b/src/military/task/paperManage/index.jsx @@ -90,7 +90,7 @@ export default Form.create()(({ current_user, form, showNotification, match, his setReload(Math.random()); setVisible(false); setFieldsValue({ - pass: '', + pass: 2, message: '', }) } diff --git a/src/military/task/taskDetail/index.jsx b/src/military/task/taskDetail/index.jsx index 2a33540a..c13c893d 100644 --- a/src/military/task/taskDetail/index.jsx +++ b/src/military/task/taskDetail/index.jsx @@ -114,7 +114,7 @@ export default Form.create()( // 获取协议内容 useEffect(() => { - applyModal && getAgreement().then(res => { + applyModal && getAgreement(1).then(res => { if (res && res.data) { setApplyContent({ title: res.data.title, diff --git a/src/military/task/taskManage/index.js b/src/military/task/taskManage/index.js index b3776641..7e6c566f 100644 --- a/src/military/task/taskManage/index.js +++ b/src/military/task/taskManage/index.js @@ -134,7 +134,7 @@ export default Form.create()(({ form, showNotification, match, history }) => { - + {/* */}