forked from Gitlink/forgeplus-react
Merge pull request '修改合并代码gitLink带来的问题,增加协议模板在线编辑等功能' (#347) from tongChong/forgeplus-react:JKDevelop into JKDevelop
This commit is contained in:
commit
744153b4bd
|
@ -61,6 +61,12 @@ class Index extends Component {
|
||||||
<ProjectNew {...this.props} {...props} />
|
<ProjectNew {...this.props} {...props} />
|
||||||
)}
|
)}
|
||||||
></Route>
|
></Route>
|
||||||
|
<Route
|
||||||
|
path="/projects"
|
||||||
|
render={(props) => (
|
||||||
|
<ProjectIndex {...this.props} {...props} />
|
||||||
|
)}
|
||||||
|
></Route>
|
||||||
<Route
|
<Route
|
||||||
path="/explore/all"
|
path="/explore/all"
|
||||||
render={(props) => (
|
render={(props) => (
|
||||||
|
|
|
@ -10,12 +10,12 @@ import img_parise from '../Images/parise.png';
|
||||||
import SpecialModal from './SpecialModal';
|
import SpecialModal from './SpecialModal';
|
||||||
|
|
||||||
class IndexItem extends Component {
|
class IndexItem extends Component {
|
||||||
constructor(props){
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state={
|
this.state = {
|
||||||
visible:false,
|
visible: false,
|
||||||
user_apply_signatures:[],
|
user_apply_signatures: [],
|
||||||
project_id:undefined
|
project_id: undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TurnToDetail = (login, url) => {
|
TurnToDetail = (login, url) => {
|
||||||
|
@ -31,31 +31,31 @@ class IndexItem extends Component {
|
||||||
* is_secret:是否是特殊开源许可证项目
|
* is_secret:是否是特殊开源许可证项目
|
||||||
* id:创建者login
|
* id:创建者login
|
||||||
* is_member:是否是项目成员(如果是项目成员可以直接进入项目)
|
* is_member:是否是项目成员(如果是项目成员可以直接进入项目)
|
||||||
* */
|
* */
|
||||||
projectHref=(link , user_apply_signatures,project_id,is_secret , id,is_member)=>{
|
projectHref = (link, user_apply_signatures, project_id, is_secret, id, is_member) => {
|
||||||
const { user , showLoginDialog } = this.props;
|
const { user, showLoginDialog } = this.props;
|
||||||
if(is_secret && (!user || (user && !user.login))){
|
if (is_secret && (!user || (user && !user.login))) {
|
||||||
showLoginDialog();
|
showLoginDialog();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let signa = user_apply_signatures && user_apply_signatures[0];
|
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({
|
this.setState({
|
||||||
visible:true,
|
visible: true,
|
||||||
user_apply_signatures:user_apply_signatures.length>0 ? user_apply_signatures[0] : undefined,
|
user_apply_signatures: user_apply_signatures.length > 0 ? user_apply_signatures[0] : undefined,
|
||||||
project_id
|
project_id
|
||||||
})
|
})
|
||||||
}else{
|
} else {
|
||||||
this.props.history.push(link);
|
this.props.history.push(link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hideModal=()=>{
|
hideModal = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
visible:false
|
visible: false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
sureModal=()=>{
|
sureModal = () => {
|
||||||
this.hideModal();
|
this.hideModal();
|
||||||
const { getListData } = this.props;
|
const { getListData } = this.props;
|
||||||
getListData && getListData(1);
|
getListData && getListData(1);
|
||||||
|
@ -63,26 +63,26 @@ class IndexItem extends Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { projects } = this.props;
|
const { projects } = this.props;
|
||||||
const { visible , user_apply_signatures , project_id } = this.state;
|
const { visible, user_apply_signatures, project_id } = this.state;
|
||||||
return (
|
return (
|
||||||
<div className="project-list minH-670" style={{padding:"0px 20px"}}>
|
<div className="project-list minH-670" style={{ padding: "0px 20px" }}>
|
||||||
<SpecialModal {...this.props} visible={visible} hideModal={this.hideModal} user_apply_signatures={user_apply_signatures} project_id={project_id} sureModal={this.sureModal}></SpecialModal>
|
<SpecialModal {...this.props} visible={visible} hideModal={this.hideModal} user_apply_signatures={user_apply_signatures} project_id={project_id} sureModal={this.sureModal}></SpecialModal>
|
||||||
{ projects && projects.length > 0 ? projects.map((item, key) => {
|
{projects && projects.length > 0 ? projects.map((item, key) => {
|
||||||
return (
|
return (
|
||||||
<div className="p-r-Item" key={key}>
|
<div className="p-r-Item" key={key}>
|
||||||
{
|
{
|
||||||
item.platform === "educoder" ?
|
item.platform === "educoder" ?
|
||||||
<a href="javascript:void(0)" style={{cursor:"default"}} className="show-user-link">
|
<a href="javascript:void(0)" style={{ cursor: "default" }} className="show-user-link">
|
||||||
<img className="p-r-photo" alt="" src={item.author && item.author.image_url} ></img>
|
<img className="p-r-photo" alt="" src={item.author && item.author.image_url} ></img>
|
||||||
</a>
|
</a>
|
||||||
:
|
:
|
||||||
<Link to={`/${item.author && item.author.login}`} className="show-user-link">
|
<Link to={`/${item.author && item.author.login}`} className="show-user-link">
|
||||||
<img className="p-r-photo" alt="" src={getImageUrl(`/${item.author && item.author.image_url}`)} ></img>
|
<img className="p-r-photo" alt="" src={getImageUrl(`/${item.author && item.author.image_url}`)} ></img>
|
||||||
</Link>
|
</Link>
|
||||||
}
|
}
|
||||||
<div className="p-r-Infos">
|
<div className="p-r-Infos">
|
||||||
<div className="p-r-name">
|
<div className="p-r-name">
|
||||||
<AlignCenter>
|
{/* <AlignCenter>
|
||||||
<Link to={`/${item.author.login}/${item.identifier}`} title={`${item.author.name}/${item.name}`} className="color-grey-3 font-18 task-hide " style={{maxWidth: 470 }}>
|
<Link to={`/${item.author.login}/${item.identifier}`} title={`${item.author.name}/${item.name}`} className="color-grey-3 font-18 task-hide " style={{maxWidth: 470 }}>
|
||||||
{item.author.name}/{item.name}
|
{item.author.name}/{item.name}
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -100,7 +100,27 @@ class IndexItem extends Component {
|
||||||
<i className="iconfont icon-banbenku font-18 color-green" />
|
<i className="iconfont icon-banbenku font-18 color-green" />
|
||||||
</Tooltip>:""
|
</Tooltip>:""
|
||||||
}
|
}
|
||||||
</AlignCenter>
|
</AlignCenter> */}
|
||||||
|
<a onClick={() => this.projectHref(`/${item.author.login}/${item.identifier}`, item.user_apply_signatures, item.id, item.is_secret, item.author.login, item.is_member)} className="hide-1 color-grey-3 font-18 task-hide fwt-500 " style={{ whiteSpace: "wrap", display: 'flex', width: 400 }}>
|
||||||
|
{item.author.name}/{item.name}
|
||||||
|
{
|
||||||
|
item.forked_from_project_id ?
|
||||||
|
<span className="ml5">
|
||||||
|
<i className="iconfont icon-fork font-18 color-orange" />
|
||||||
|
</span>
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
{
|
||||||
|
item.type && item.type !== 0 ?
|
||||||
|
item.type === 2 ?
|
||||||
|
<Tooltip title="该项目是一个镜像" className="ml5">
|
||||||
|
<i className="iconfont icon-banbenku font-18 color-green" />
|
||||||
|
</Tooltip> :
|
||||||
|
<span className="ml5">
|
||||||
|
<i className="iconfont icon-jingxiang font-18 color-green" />
|
||||||
|
</span> : ""
|
||||||
|
}
|
||||||
|
</a>
|
||||||
<span className="p-r-tags">
|
<span className="p-r-tags">
|
||||||
<span className="pariseTag">
|
<span className="pariseTag">
|
||||||
<img src={img_parise} alt="" className="pariseImg" />赞 {item.praises_count}
|
<img src={img_parise} alt="" className="pariseImg" />赞 {item.praises_count}
|
||||||
|
@ -110,7 +130,7 @@ class IndexItem extends Component {
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<p className="break_word task-hide-2 mt10" style={{ maxHeight: "44px",lineHeight:"22px" }}>{item.description}</p>
|
<p className="break_word task-hide-2 mt10" style={{ maxHeight: "44px", lineHeight: "22px" }}>{item.description}</p>
|
||||||
|
|
||||||
<div className="p-r-about">
|
<div className="p-r-about">
|
||||||
<span className="p-r-detail">
|
<span className="p-r-detail">
|
||||||
|
@ -122,7 +142,7 @@ class IndexItem extends Component {
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}) : <Nodata _html="暂无数据~"></Nodata>
|
}) : <Nodata _html="暂无数据~"></Nodata>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,10 @@ function SpecialModal({ visible , hideModal , sureModal , showNotification , use
|
||||||
function sure(){
|
function sure(){
|
||||||
if(!user_apply_signatures || (user_apply_signatures && user_apply_signatures.status !== "waiting")){
|
if(!user_apply_signatures || (user_apply_signatures && user_apply_signatures.status !== "waiting")){
|
||||||
if(!id || (id && id.length === 0)){
|
if(!id || (id && id.length === 0)){
|
||||||
// showNotification("请先提交文件进行审核!");
|
const a = document.createElement('a');
|
||||||
getUrl(`/api/apply_signatures/template_file`)
|
a.href = getUrl(`/api/apply_signatures/template_file`);
|
||||||
|
a.click(); // 下载
|
||||||
|
showNotification("请先提交文件进行审核!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const url = `/apply_signatures.json`;
|
const url = `/apply_signatures.json`;
|
||||||
|
|
|
@ -50,7 +50,7 @@ function SubBanner() {
|
||||||
return(
|
return(
|
||||||
<div className="banners">
|
<div className="banners">
|
||||||
<div className="bannersCenter">
|
<div className="bannersCenter">
|
||||||
<p className="bTitle"><span>GitLink 确实开源</span></p>
|
<p className="bTitle"><span>osredm 红山开源</span></p>
|
||||||
<p className="bSubTitle">新一代开发创新服务平台 让你的创意在这里释放</p>
|
<p className="bSubTitle">新一代开发创新服务平台 让你的创意在这里释放</p>
|
||||||
<div className="bannerBox">
|
<div className="bannerBox">
|
||||||
{
|
{
|
||||||
|
|
|
@ -96,15 +96,15 @@ function Index(props){
|
||||||
<li>消息通知</li>
|
<li>消息通知</li>
|
||||||
<li className={(pathname.indexOf("/settings/notice")>-1 && pathname.indexOf("/settings/notice/config") == -1) || pathname.indexOf("/settings/notice/privateLetter")>-1 ?"active":""}><Link to={"/settings/notice"}><i className="iconfont icon-wodetongzhi"></i><span className="text-shodow-bold">我的通知</span></Link></li>
|
<li className={(pathname.indexOf("/settings/notice")>-1 && pathname.indexOf("/settings/notice/config") == -1) || pathname.indexOf("/settings/notice/privateLetter")>-1 ?"active":""}><Link to={"/settings/notice"}><i className="iconfont icon-wodetongzhi"></i><span className="text-shodow-bold">我的通知</span></Link></li>
|
||||||
<li className={pathname.indexOf("/settings/notice/config")>-1 ?"active":""}><Link to={'/settings/notice/config'}><i className="iconfont icon-tongzhiguanli"></i><span className="text-shodow-bold">通知管理</span></Link></li>
|
<li className={pathname.indexOf("/settings/notice/config")>-1 ?"active":""}><Link to={'/settings/notice/config'}><i className="iconfont icon-tongzhiguanli"></i><span className="text-shodow-bold">通知管理</span></Link></li>
|
||||||
</ul>}
|
</ul>} */}
|
||||||
<ul className="securityUl">
|
{pathname.indexOf("/settings/notice")>-1 && <ul className="securityUl ul-border-buttom">
|
||||||
<li>安全设置</li>
|
|
||||||
<li className={pathname.indexOf("/settings/SSH")>-1 ?"active":""}><Link to={`/settings/SSH`}><i className="iconfont icon-xuanzhongssh_icon mr5 font-14"></i><span className="text-shodow-bold">SSH密钥</span></Link></li>
|
|
||||||
</ul> */}
|
|
||||||
<ul className="securityUl ul-border-buttom">
|
|
||||||
<li>消息通知</li>
|
<li>消息通知</li>
|
||||||
<li className={(pathname.indexOf("/settings/notice")>-1 && pathname.indexOf("/settings/notice/config") == -1) || pathname.indexOf("/settings/notice/privateLetter")>-1 ?"active":""}><Link to={"/settings/notice"}><i className="iconfont icon-wodetongzhi"></i><span className="text-shodow-bold">我的通知</span></Link></li>
|
<li className={(pathname.indexOf("/settings/notice")>-1 && pathname.indexOf("/settings/notice/config") == -1) || pathname.indexOf("/settings/notice/privateLetter")>-1 ?"active":""}><Link to={"/settings/notice"}><i className="iconfont icon-wodetongzhi"></i><span className="text-shodow-bold">我的通知</span></Link></li>
|
||||||
</ul>
|
</ul>}
|
||||||
|
{pathname.indexOf("/settings/SSH")>-1 &&<ul className="securityUl">
|
||||||
|
<li>安全设置</li>
|
||||||
|
<li className={pathname.indexOf("/settings/SSH")>-1 ?"active":""}><Link to={`/settings/SSH`}><i className="iconfont icon-xuanzhongssh_icon mr5 font-14"></i><span className="text-shodow-bold">SSH密钥</span></Link></li>
|
||||||
|
</ul>}
|
||||||
</div>
|
</div>
|
||||||
<LongWidth>
|
<LongWidth>
|
||||||
<Gap>
|
<Gap>
|
||||||
|
|
|
@ -113,7 +113,7 @@ class Index extends Component {
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
{
|
{
|
||||||
false && projectDetail && projectDetail.permission && (projectDetail.permission === "Owner" || projectDetail.permission === "Admin") ?
|
projectDetail && projectDetail.permission && (projectDetail.permission === "Owner" || projectDetail.permission === "Admin") ?
|
||||||
<li
|
<li
|
||||||
className={pathname.indexOf("settings/special") > -1 ? "active" : ""}
|
className={pathname.indexOf("settings/special") > -1 ? "active" : ""}
|
||||||
>
|
>
|
||||||
|
|
|
@ -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<!DOCTYPE html>\n<html>\n_html_</html>`,
|
||||||
|
head: '<head>\n<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n<style>\n_styles_\n</style>\n</head>\n',
|
||||||
|
body: '<body>_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 (
|
||||||
|
<span className="link">
|
||||||
|
<span className={className} onClick={this.exportWord}>{title}</span>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExportWord.propTypes = propTypes;
|
||||||
|
ExportWord.defaultProps = defaultProps;
|
||||||
|
export default ExportWord;
|
|
@ -38,7 +38,7 @@ export default props => {
|
||||||
<Menu.Item><a href={`${main_web_site_url}/admin/industries/list`}>行业信息</a></Menu.Item>
|
<Menu.Item><a href={`${main_web_site_url}/admin/industries/list`}>行业信息</a></Menu.Item>
|
||||||
<Menu.Item><a href={`${main_web_site_url}/admin/placements/list`}>职位信息</a></Menu.Item>
|
<Menu.Item><a href={`${main_web_site_url}/admin/placements/list`}>职位信息</a></Menu.Item>
|
||||||
<Menu.Item><a href={`${main_web_site_url}/admin/task_templates/list`}>需求导入模板</a></Menu.Item>
|
<Menu.Item><a href={`${main_web_site_url}/admin/task_templates/list`}>需求导入模板</a></Menu.Item>
|
||||||
<Menu.Item><a href={`${main_web_site_url}/admin/agreement_setting`}>签订协议内容</a></Menu.Item>
|
<Menu.Item><Link to="/managements/task/agreement/content">协议签订模板</Link></Menu.Item>
|
||||||
<Menu.Item><a href={`${main_web_site_url}/admin/sign_agreement_setting`}>应征投稿协议内容</a></Menu.Item>
|
<Menu.Item><a href={`${main_web_site_url}/admin/sign_agreement_setting`}>应征投稿协议内容</a></Menu.Item>
|
||||||
</SubMenu>
|
</SubMenu>
|
||||||
<SubMenu title="代办事项" >
|
<SubMenu title="代办事项" >
|
||||||
|
|
|
@ -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 = '<html><head><meta charset="UTF-8"></head><body><table border="1">{table}</table></body></html>';
|
|
||||||
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 (
|
|
||||||
<Button
|
|
||||||
// colors={colors}
|
|
||||||
// size={size}
|
|
||||||
onClick={this.exportExcel}
|
|
||||||
>
|
|
||||||
{/*{exportIcon}{title}*/}
|
|
||||||
导出
|
|
||||||
</Button>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ExportExcel.propTypes = propTypes;
|
|
||||||
ExportExcel.defaultProps = defaultProps;
|
|
||||||
export default ExportExcel;
|
|
|
@ -3,7 +3,7 @@ import javaFetch from '../javaFetch';
|
||||||
|
|
||||||
|
|
||||||
let settings = localStorage.chromesetting && JSON.parse(localStorage.chromesetting);
|
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);
|
const service = javaFetch(actionUrl);
|
||||||
export const httpUrl = actionUrl;
|
export const httpUrl = actionUrl;
|
||||||
export const main_web_site_url = settings && settings.main_web_site_url;
|
export const main_web_site_url = settings && settings.main_web_site_url;
|
||||||
|
|
|
@ -44,6 +44,12 @@ const AgreementManage = Loadable({
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 协议签订模板
|
||||||
|
const AgreementContent = Loadable({
|
||||||
|
loader: () => import("./task/agreementContent"),
|
||||||
|
loading: Loading,
|
||||||
|
});
|
||||||
|
|
||||||
const PayProof = Loadable({
|
const PayProof = Loadable({
|
||||||
loader: () => import("./task/payProof"),
|
loader: () => import("./task/payProof"),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
|
@ -146,6 +152,14 @@ const Managements = (propsF) => {
|
||||||
)}
|
)}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
|
{/* 协议内容 */}
|
||||||
|
<Route
|
||||||
|
path="/managements/task/agreement/content"
|
||||||
|
render={(props) => (
|
||||||
|
<AgreementContent {...propsF} {...props} />
|
||||||
|
)}
|
||||||
|
></Route>
|
||||||
|
|
||||||
{/* 管理员上传支付凭证 */}
|
{/* 管理员上传支付凭证 */}
|
||||||
<Route
|
<Route
|
||||||
path="/managements/task/payProof"
|
path="/managements/task/payProof"
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
|
import { Input, Button, Form, message } from "antd";
|
||||||
|
import MDEditor from "../../../modules/tpm/challengesnew/tpm-md-editor";
|
||||||
|
import {getAgreement, agreementAdd,agreementEdit } from "../api";
|
||||||
|
import "../index.scss";
|
||||||
|
import "./index.scss";
|
||||||
|
|
||||||
|
export default Form.create()(({ form,current_user, showNotification, match, history }) => {
|
||||||
|
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) => (
|
||||||
|
<Form.Item label={label} className="mb0">
|
||||||
|
{getFieldDecorator(name, { rules, initialValue, validateFirst: true })(
|
||||||
|
widget
|
||||||
|
)}
|
||||||
|
{rightComponent}
|
||||||
|
</Form.Item>
|
||||||
|
),[]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="centerbox task-manage agreement-content">
|
||||||
|
{helper(
|
||||||
|
"协议名称",
|
||||||
|
"title",
|
||||||
|
[{ required: true, message: "请输入协议名称" }],
|
||||||
|
<Input
|
||||||
|
placeholder={"请输入协议名称"}
|
||||||
|
maxLength={50}
|
||||||
|
disabled
|
||||||
|
/>,
|
||||||
|
"协议模板"
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Form.Item className="mb0">
|
||||||
|
<MDEditor
|
||||||
|
placeholder={"请输入协议内容"}
|
||||||
|
height={500}
|
||||||
|
mdID={"order-new-description"}
|
||||||
|
initValue={content}
|
||||||
|
onChange={onContentChange}
|
||||||
|
className="mt20"
|
||||||
|
></MDEditor>
|
||||||
|
{getFieldDecorator("content", {
|
||||||
|
rules: [{ required: true, message: "请输入协议内容" }],
|
||||||
|
validateFirst: true,
|
||||||
|
})(<Input style={{ display: "none" }} />)}
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Button className="mt25" type="primary" onClick={saveFile}>
|
||||||
|
保存
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
.agreement-content{
|
||||||
|
.agreement-content-title{
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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({
|
return fetch({
|
||||||
url: '/api/paper/agreementSettings/1',
|
url: `/api/paper/agreementSettings/${params==1?params:''}`,
|
||||||
method: 'get'
|
method: 'get',
|
||||||
|
params:params!=1?params:null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import React, { useState, } from 'react';
|
import React, { useEffect, useState, } from 'react';
|
||||||
import { Modal, Form, Input, } from 'antd';
|
import { Modal, Form, Input, } from 'antd';
|
||||||
|
import RenderHtml from 'src/components/render-html';
|
||||||
import Upload from 'military/components/Upload';
|
import Upload from 'military/components/Upload';
|
||||||
import { uploadAgreePaper } from "../../api";
|
import ExportWord from 'military/components/ExportWord';
|
||||||
|
import { uploadAgreePaper,getAgreement } from "../../api";
|
||||||
|
|
||||||
import '../../index.scss';
|
import '../../index.scss';
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,6 +13,15 @@ export default Form.create()(props => {
|
||||||
const { getFieldDecorator, validateFields, setFieldsValue, } = form;
|
const { getFieldDecorator, validateFields, setFieldsValue, } = form;
|
||||||
|
|
||||||
const [fileList, setFileList] = useState([]);
|
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 => {
|
||||||
<div className="task-popup-content">
|
<div className="task-popup-content">
|
||||||
{/* paperAuditing */}
|
{/* paperAuditing */}
|
||||||
{checkedItem.paperAuditing && <p className=" mb10 color-orange task_tip">审核意见:{checkedItem.paperAuditing.message}</p>}
|
{checkedItem.paperAuditing && <p className=" mb10 color-orange task_tip">审核意见:{checkedItem.paperAuditing.message}</p>}
|
||||||
<a href="https://task.osredm.com/busiAttachments/download/121" className="icon icon-attachment font-13 color-blue" length="32">协议样板.word</a>
|
<ExportWord
|
||||||
<Form.Item className="upload-form" label="附件上传" required={true}>
|
className="icon icon-attachment font-13 color-blue"
|
||||||
|
title="协议模板.doc"
|
||||||
|
fileName="协议模板"
|
||||||
|
wordId="wordExpert"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Form.Item className="upload-form" label="协议上传" required={true}>
|
||||||
<Upload
|
<Upload
|
||||||
load={uploadFunc}
|
load={uploadFunc}
|
||||||
size={50}
|
size={50}
|
||||||
|
@ -68,6 +86,9 @@ export default Form.create()(props => {
|
||||||
validateFirst: true
|
validateFirst: true
|
||||||
})(<Input style={{ display: 'none' }} />)}
|
})(<Input style={{ display: 'none' }} />)}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<div id="wordExpert" style={{display:'none'}} >
|
||||||
|
<RenderHtml className="break_word_comments imageLayerParent" value={content} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
)
|
)
|
||||||
|
|
|
@ -88,7 +88,7 @@ span.list-gray {
|
||||||
}
|
}
|
||||||
|
|
||||||
.center-content .ant-pagination {
|
.center-content .ant-pagination {
|
||||||
margin: 2rem auto;
|
margin: 2rem auto !important;
|
||||||
text-align: center;
|
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{
|
.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;
|
border-color: #4154f1;
|
||||||
|
|
|
@ -95,16 +95,16 @@ export default Form.create()(({ form, showNotification, history}) => {
|
||||||
const columns = useMemo(() => {
|
const columns = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
title: '序号',
|
title: '成果编号',
|
||||||
dataIndex: 'index',
|
dataIndex: 'paperNumber',
|
||||||
render: (text, record, index) => {
|
render: (text, record) => {
|
||||||
return index + 1
|
return text ? <Link className="line_1 color-grey3" to={`/task/taskDetail/${record.taskId}`}>{text}</Link> : '--'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '申诉内容',
|
title: '申诉内容',
|
||||||
dataIndex: 'content',
|
dataIndex: 'content',
|
||||||
width: "30%",
|
width: "26%",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '申诉文件',
|
title: '申诉文件',
|
||||||
|
|
|
@ -90,7 +90,7 @@ export default Form.create()(({ current_user, form, showNotification, match, his
|
||||||
setReload(Math.random());
|
setReload(Math.random());
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
setFieldsValue({
|
setFieldsValue({
|
||||||
pass: '',
|
pass: 2,
|
||||||
message: '',
|
message: '',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ export default Form.create()(
|
||||||
|
|
||||||
// 获取协议内容
|
// 获取协议内容
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
applyModal && getAgreement().then(res => {
|
applyModal && getAgreement(1).then(res => {
|
||||||
if (res && res.data) {
|
if (res && res.data) {
|
||||||
setApplyContent({
|
setApplyContent({
|
||||||
title: res.data.title,
|
title: res.data.title,
|
||||||
|
|
|
@ -134,7 +134,7 @@ export default Form.create()(({ form, showNotification, match, history }) => {
|
||||||
|
|
||||||
<Button className="mr10" type="primary" onClick={onSearch}>搜索</Button>
|
<Button className="mr10" type="primary" onClick={onSearch}>搜索</Button>
|
||||||
<Button className="mr10" type="" onClick={clearSearch}>清除</Button>
|
<Button className="mr10" type="" onClick={clearSearch}>清除</Button>
|
||||||
<Button className="mr10" type="primary" onClick={() => { window.open(`${main_web_site_url}/admin/tasks/activity_managed_tasks.zip?review_status=reviewing&status_value=0`) }}>导出</Button>
|
{/* <Button className="mr10" type="primary" onClick={() => { window.open(`${main_web_site_url}/admin/tasks/activity_managed_tasks.zip?review_status=reviewing&status_value=0`) }}>导出</Button> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue