Merge branches 'dev_aliyun' and 'dev_jupyter' of https://bdgit.educoder.net/Hjqreturn/educoder into dev_jupyter

chromesetting
杨树明 5 years ago
commit 97ce2d63af

@ -42,5 +42,16 @@ class JupytersController < ApplicationController
render json: {status: 0, url: info[:url], port: info[:port]}
end
def active_with_tpm
shixun = Shixun.find_by(identifier: params[:identifier])
jupyter_active_tpm(shixun)
render json: {status: 0}
end
def active_with_tpi
myshixun = Myshixun.find_by(identifier: params[:identifier])
jupyter_active_tpm(myshixun)
render json: {status: 0}
end
end
end

@ -191,5 +191,26 @@ module JupyterService
edu_setting('jupyter_service').gsub("PORT", jupyter_port)
end
def _jupyter_active(tpiID)
shixun_tomcat = edu_setting('cloud_bridge')
uri = "#{shixun_tomcat}/bridge/jupyter/active"
params = {:tpiID => tpiID}
res = uri_post uri, params
if res && res['code'].to_i != 0
raise("实训云平台繁忙繁忙等级120")
end
end
# tpm 延时
def jupyter_active_tpm(shixun)
tpiID = "tpm#{shixun.id}"
_jupyter_active(tpiID)
end
# tpi 延时
def jupyter_active_tpi(myshixun)
tpiID = myshixun.id
_jupyter_active(tpiID)
end
end

@ -33,6 +33,8 @@ Rails.application.routes.draw do
get :get_info_with_tpm
get :reset_with_tpi
get :reset_with_tpm
get :active_with_tpm
get :active_with_tpi
end
end

@ -0,0 +1,18 @@
//用于嵌入到jupyter pod中的js
//guange 2019.12.18
window.onload=function(){
console.log("开始发送消息了");
runEvery10Sec();
}
function runEvery10Sec() {
// 1000 * 10 = 10 秒钟
console.log("每隔10秒中一次");
require(["base/js/namespace"],function(Jupyter) {
Jupyter.notebook.save_checkpoint();
});
window.parent.postMessage('jupytermessage','*');
setTimeout( runEvery10Sec, 1000 * 10 );
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,35 @@
/*
* @Author: your name
* @Date: 2019-12-20 11:40:56
* @LastEditTime : 2019-12-20 13:38:49
* @LastEditors : Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: /notebook/Users/yangshuming/Desktop/new__educode/educoder/public/react/public/js/jupyter.js
*/
window.onload=function(){
require(["base/js/namespace"],function(Jupyter) {
Jupyter.notebook.save_checkpoint();
});
}
// //子目标父窗口接收子窗口发送的消息
// let message = {type: 'open', link:'需要发送的消息'};
//子窗口向父窗口发送消息,消息中包含我们想跳转的链接
window.parent.postMessage('jupytermessage','需要发送的消息');
// //目标父窗口接收子窗口发送的消息
// window.addEventListener('message', (e)=>{
// let origin = event.origin || event.originalEvent.origin;
// if (origin !== '需要发送的消息') {
// return;
// }else {
// //更换iframe的src,实现iframe页面跳转
// 执行方法
// }
// },false);

@ -52,7 +52,7 @@ export function initAxiosInterceptors(props) {
//proxy="http://47.96.87.25:48080"
proxy="https://pre-newweb.educoder.net"
proxy="https://test-newweb.educoder.net"
//proxy="https://test-jupyterweb.educoder.net"
proxy="https://test-jupyterweb.educoder.net"
//proxy="http://192.168.2.63:3001"
// 在这里使用requestMap控制避免用户通过双击等操作发出重复的请求

@ -14,4 +14,29 @@
color: #fff;
left: 13px;
user-select: none;
}
.jupyter_float_button {
background-image: url(./images/float_switch.jpg);
height: 112px;
width: 38px;
position: absolute;
right: 0px;
top: 32%;
cursor: pointer;
left:auto;
z-index: 99999999;
}
.jupyter_float_button .text {
position: relative;
writing-mode: vertical-rl;
top: 36px;
color: #fff;
left: 13px;
user-select: none;
}
.newjupyter_float_button{
right: 330px;
}

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import '../VNC.css'
const $ = window.$;
class FloatButton extends Component {
componentDidMount() {

@ -148,7 +148,9 @@ class TPMBanner extends Component {
})
}
}
}
@ -866,8 +868,8 @@ class TPMBanner extends Component {
</li>
</ul>
{
this.props.is_jupyter===true?"":
{/*{*/}
{/* this.props.is_jupyter===true?"":*/}
<Popover placement="right" content={
<div style={{"width": "530px"}} >
@ -932,7 +934,7 @@ class TPMBanner extends Component {
</div>
</Popover>
}
{/*// }*/}
{

@ -9,14 +9,34 @@
import './index.scss';
import React, { useEffect, useState } from 'react';
import SplitPane from 'react-split-pane';
import { Button, Modal } from 'antd';
import { Button, Modal,Drawer ,Pagination,Empty,Tooltip,Icon,message} from 'antd';
import {
connect
} from 'react-redux';
import FloatButton from '../../page/component/FloatButton';
import UserInfo from '../../developer/components/userInfo';
import actions from '../../../redux/actions';
import LeftPane from './leftPane';
import RightPane from './rightPane';
import MyIcon from "../../../common/components/MyIcon";
function jsCopy(s) {
var copyEle = document.getElementById(s);
const range = document.createRange(); // 创造range
window.getSelection().removeAllRanges(); //清除页面中已有的selection
range.selectNode(copyEle); // 选中需要复制的节点
window.getSelection().addRange(range); // 执行选中元素
const copyStatus = document.execCommand("Copy"); // 执行copy操作
// 对成功与否定进行提示
copyStatuss(copyStatus)
}
function copyStatuss(copyStatus){
if (copyStatus) {
message.success('复制成功');
} else {
message.error('复制失败');
}
}
function JupyterTPI (props) {
// 获取 identifier 值
@ -39,19 +59,46 @@ function JupyterTPI (props) {
changeLoadingState,
changeGetJupyterUrlState,
jupyter_identifier,
changeCurrentPage
changeCurrentPage,
changeshowDrawer,
drawervisible,
} = props;
const emptyCtx = (
<div className="jupyter_empty">
<Empty />
</div>
);
const {identifier} = params;
const [userInfo, setUserInfo] = useState({});
const [jupyterInfo, setJupyterInfo] = useState({});
const [updateTip, setUpdateTip] = useState(true);
const [myIdentifier, setMyIdentifier] = useState('');
const [renderCtx, setRenderCtx] = useState(() => (emptyCtx));
// 保存代码
const addEventListeners = () => {
window.addEventListener('message', (e) => {
console.log("触发了jupytermessage");
if(e){
if(e.data){
if(e.data==="jupytermessage"){
saveJupyterTpi();
}
}
}
});
}
useEffect(() => {
/* jupyter TPI
* 获取 用户信息,
* 实训的 identifier, 状态 名称 是否被修改等信息
*/
addEventListeners()
getJupyterInfo(identifier);
}, [identifier]);
@ -107,6 +154,28 @@ function JupyterTPI (props) {
})
}
// 重置环境
const handleEnvironmentTpi = () => {
Modal.confirm({
title: '重置环境',
content: (
<p style={{ lineHeight: '24px' }}>
你在本文件中修改的内容将丢失,<br />
是否确定重置环境
</p>
),
okText: '确定',
cancelText: '取消',
onOk () {
// console.log('调用重置代码....', myIdentifier);
// if (myIdentifier) {
// syncJupyterCode(myIdentifier, '重置成功');
// }
}
})
}
// 退出实训
const handleClickQuitTpi = () => {
// console.log(jupyterInfo);
@ -138,6 +207,54 @@ function JupyterTPI (props) {
getJupyterTpiDataSet(jupyter_identifier);
}
const swtichFirstDrawer = () => {
changeshowDrawer(!drawervisible)
}
const firstDrawerWidth = ()=>{
return 260
};
// 分页处理
const handleChangePage = (page) => {
// console.log(page, pageSize);
handlePageChange(page);
}
// const listCtx = ;
useEffect(() => {
if (dataSets.length > 0) {
console.log('数据集的个数: ', dataSets.length);
const oList = dataSets.map((item, i) => {
return (
<li className="jupyter_item" key={`key_${i}`}>
<Tooltip
placement="right"
// title={item.file_path}
mouseLeaveDelay={0.3}
>
<Icon type="file-text" className="jupyter_icon"/>
<span className="jupyter_name ml10">{item.title}</span>
<a className={"fr color-blue"}
onClick={() => {
jsCopy("file_path"+i)
}}>复制地址</a>
<input id={"file_path"+i} className={"file_path_input"} value={item.file_path}/>
</Tooltip>
</li>
);
});
const oUl = (
<ul className="jupyter_data_list">
{ oList }
</ul>
);
setRenderCtx(oUl);
}
}, [props]);
return (
<div className="jupyter_area">
<div className="jupyter_header">
@ -151,9 +268,17 @@ function JupyterTPI (props) {
<Button
className="btn_common"
type="link"
icon="sync"
icon="history"
onClick={handleClickResetTpi}
>重置实训</Button>
>重置实训</Button>
<Button
className="btn_common"
type="link"
icon="sync"
onClick={handleEnvironmentTpi}
>重置环境</Button>
<Button
className="btn_common"
type="link"
@ -162,16 +287,17 @@ function JupyterTPI (props) {
>退出实训</Button>
</p>
</div>
<div className="jupyter_ctx">
<SplitPane split="vertical" minSize={350} maxSize={-350} defaultSize="30%">
<div className={'split-pane-left'}>
<LeftPane
dataSets={dataSets}
total={total}
pagination={pagination}
onPageChange={handlePageChange}
/>
</div>
<SplitPane split="vertical" minSize={350} maxSize={-350} defaultSize="100%">
{/*<div className={'split-pane-left'}>*/}
{/* <LeftPane*/}
{/* dataSets={dataSets}*/}
{/* total={total}*/}
{/* pagination={pagination}*/}
{/* onPageChange={handlePageChange}*/}
{/* />*/}
{/*</div>*/}
<SplitPane split="vertical" defaultSize="100%" allowResize={false}>
<RightPane
identifier={myIdentifier}
@ -181,9 +307,38 @@ function JupyterTPI (props) {
onReloadUrl={handleOnReloadUrl}
onSave={handleOnSave}
/>
<div />
<FloatButton onClick={swtichFirstDrawer} className={drawervisible===false?"jupyter_float_button":"jupyter_float_button newjupyter_float_button"}>{"数据集"}</FloatButton>
</SplitPane>
</SplitPane>
<Drawer
placement={"right"}
closable={false}
mask={false}
// onClose={this.onClose}
visible={drawervisible}
className={"RightPaneDrawer"}
>
<p className={"RightPaneDrawertop"}></p>
<div className="jupyter_data_sets_area newjupyter_data_sets_area">
<h2 className="jupyter_h2_title">
{/*<MyIcon type="iconwenti" className="jupyter_data_icon"/>*/}
<i className={"iconfont icon-base"}></i>
{/* <span className="iconfont icon-java jupyter_data_icon"></span>数据集 */}
</h2>
{ renderCtx }
<div className='jupyter_pagination'>
{total<20?"":<Pagination
simple
current={pagination.page}
pageSize={pagination.limit}
total={total}
onChange={handleChangePage}
/>}
</div>
</div>
</Drawer>
</div>
</div>
);
@ -199,7 +354,7 @@ const mapStateToProps = (state) => {
jupyter_pagination,
jupyter_identifier
} = state.jupyterReducer;
const { loading } = state.commonReducer;
const { loading ,drawervisible} = state.commonReducer;
return {
loading,
jupyter_info,
@ -208,7 +363,8 @@ const mapStateToProps = (state) => {
jupyter_tpi_url_state,
total: jupyter_data_set_count,
pagination: jupyter_pagination,
jupyter_identifier
jupyter_identifier,
drawervisible,
};
}
@ -221,7 +377,9 @@ const mapDispatchToProps = (dispatch) => ({
getJupyterTpiUrl: (identifier) => dispatch(actions.getJupyterTpiUrl(identifier)),
saveJupyterTpi: () => dispatch(actions.saveJupyterTpi()),
changeLoadingState: (flag) => dispatch(actions.changeLoadingState(flag)),
changeCurrentPage: (current) => dispatch(actions.changeCurrentPage(current))
changeCurrentPage: (current) => dispatch(actions.changeCurrentPage(current)),
//展开Drawer
changeshowDrawer: (type) => dispatch(actions.changeshowDrawer(type))
});
export default connect(

@ -9,7 +9,7 @@
-webkit-background-clip: padding;
background-clip: padding-box;
}
.Resizer:hover {
-webkit-transition: all 2s ease;
transition: all 2s ease;
@ -56,6 +56,7 @@
line-height: 60px;
background-color: #070F1A;
padding-left: 30px;
z-index:999999;
.jupyter_title{
display: flex;
flex-direction: column;
@ -102,4 +103,59 @@
font-size: 14px;
}
}
}
}
.RightPaneDrawer{
.RightPaneDrawertop{
width:330px;
height:29px;
background:rgba(17,28,36,1);
}
.ant-drawer-content-wrapper{
width:330px !important;
box-shadow: -2px 0 8px #070F1A !important;
}
.ant-drawer-body{
padding: 0px;
}
.ant-drawer-wrapper-body{
padding-top: 60px;
background: #070F1A;
overflow: hidden !important;
}
.ant-pagination{
color:#fff !important;
}
}
.newjupyter_data_sets_area{
background:#070F1A !important;
.jupyter_h2_title {
height:49px;
line-height: 49px;
background: #070F1A !important;
border-bottom: 1px solid #17212F !important;
color:#FFFFFF !important;
border-top: 1px solid #17212F !important;
}
.iconfont{
color:#28b887!important;
font-size: 30px !important;
margin-right: 20px;
}
.jupyter_pagination{
border-top: 1px solid #070F1A !important;
}
.jupyter_name{
color:#FFFFFF !important;
}
.file_path_input{
position: absolute;
right: -50%;
}
}

@ -2,15 +2,15 @@
height: 100%;
background: #fff;
.jupyter_h2_title{
height: 44px;
line-height: 44px;
//height: 44px;
//line-height: 44px;
// background-color: #EEEEEE;
background: #fff;
padding: 0 20px;
font-size: 16px;
// box-size: border-box;
box-sizing: border-box;
border-bottom: 1px solid rgba(238,238,238,1);
//border-bottom: 1px solid rgba(238,238,238,1);
.jupyter_data_icon{
// color: #7286ff;
color: #1890ff;
@ -24,14 +24,15 @@
.jupyter_data_list,
.jupyter_empty{
height: calc(100vh - 160px);
//height: calc(100vh - 160px);
min-height: 350px;
overflow-y: auto;
}
.jupyter_data_list{
.jupyter_item{
line-height:45px;
border-bottom: 1px solid rgba(238,238,238, 1);
//border-bottom: 1px solid rgba(238,238,238, 1);
padding: 0 30px 0 60px;
overflow: hidden;
text-overflow:ellipsis;

@ -65,13 +65,13 @@ function RightPane (props) {
className='jupyter_iframe_style'
></iframe>
</div>
<div className="jupyter_submit">
<Button
loading={loading}
type="primary"
onClick={handleClickSubmit}
>保存</Button>
</div>
{/*<div className="jupyter_submit">*/}
{/* <Button*/}
{/* loading={loading}*/}
{/* type="primary"*/}
{/* onClick={handleClickSubmit}*/}
{/* >保存</Button>*/}
{/*</div>*/}
</div>
));

@ -10,8 +10,6 @@ import { Modal, Spin, Tooltip ,message,Icon,Button,Divider} from 'antd';
import axios from 'axios';
import 'antd/lib/pagination/style/index.css';
import '../shixunchildCss/Challenges.css';
import AccountProfile from"../../../user/AccountProfile";

@ -25,6 +25,7 @@ class Challengesjupyter extends Component {
boxoffsetHeigh:0,
opentitletype:true,
isopentitletype:"Less",
enlarge:false,
}
}
@ -100,12 +101,13 @@ class Challengesjupyter extends Component {
}
componentDidMount() {
var that=this;
setTimeout(this.ChallengesList(), 1000);
let id = this.props.match.params.shixunId;
let ChallengesURL = `/jupyters/get_info_with_tpm.json`;
let datas={
identifier:id,
}
let datas={
identifier:id,
}
axios.get(ChallengesURL, {params: datas}).then((response) => {
if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
setTimeout(() => {
@ -113,26 +115,23 @@ class Challengesjupyter extends Component {
booljupyterurls:true,
})
}, 600)
}else{
if(response.data.status===0){
setTimeout(() => {
this.setState({
jupyter_url:response.data.url,
jupyter_port:response.data.port,
booljupyterurls:true,
})
}, 800)
}else{
if(response.data.status===0){
setTimeout(() => {
this.setState({
jupyter_url:response.data.url,
jupyter_port:response.data.port,
booljupyterurls:true,
})
}, 800)
}else{
setTimeout(() => {
this.setState({
booljupyterurls:true,
})
}, 600)
}
setTimeout(() => {
this.setState({
booljupyterurls:true,
})
}, 600)
}
}
}).catch((error) => {
@ -145,6 +144,20 @@ class Challengesjupyter extends Component {
});
setTimeout(this.getjianjiesize(), 1000);
window.addEventListener('message', (e) => {
console.log("触发了jupytermessage");
console.log(e);
if(e){
if(e.data){
if(e.data==="jupytermessage"){
that.modifyjupyter();
}
}
}
});
}
updatamakedowns = () => {
@ -198,13 +211,13 @@ class Challengesjupyter extends Component {
modifyjupyter=()=>{
let id=this.props.match.params.shixunId;
var jupyter_port="";
try{
jupyter_port= parseInt(this.state.jupyter_port);
}catch (e) {
jupyter_port=this.state.jupyter_port;
var jupyter_port="";
try{
jupyter_port= parseInt(this.state.jupyter_port);
}catch (e) {
jupyter_port=this.state.jupyter_port;
}
}
const url=`/jupyters/save_with_tpm.json`;
const data={
identifier:id,
@ -213,7 +226,8 @@ class Challengesjupyter extends Component {
axios.get(url, {params: data})
.then((result) => {
if (result.data.status === 0) {
this.props.showNotification(`应用成功`);
// this.props.showNotification(`应用成功`);
console.log("应用成功了");
}
}).catch((error) => {
})
@ -224,10 +238,14 @@ class Challengesjupyter extends Component {
opentitletype:!this.state.opentitletype
})
}
onclki=(bool)=>{
this.setState({
enlarge:bool
})
}
render() {
let{ChallengesDataList,booljupyterurls}=this.state;
let{ChallengesDataList,booljupyterurls,enlarge}=this.state;
let id = this.props.match.params.shixunId;
//老师
const is_teacher = this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false;
@ -365,18 +383,35 @@ class Challengesjupyter extends Component {
""
:
(
admin===true||business===true||mysidentity===true?
<div className={"shixunjianjiecballenges edu-back-white sortinxdirection mt20"}>
<div className="renwuxiangssi sortinxdirection">
<div><p className="renwuxiangqdiv">任务详情</p></div>
<div><p className="renwuxiangqdivtest ml1 shixunbingbaocun">请将实训题目写在下方并保存</p></div>
</div>
<div className="renwuxiangssit xaxisreverseorder">
<div className="challenbaocun" onClick={() => this.modifyjupyter(this.state)}><p
className="challenbaocuntest">应用到实训</p></div>
admin===true||business===true||mysidentity===true?
<div style={{
height: '63px',
}} className={enlarge?"shixunjianjiecballenges edu-back-white intermediatecenter fangdaone":"shixunjianjiecballenges edu-back-white mt20"}>
<div className={enlarge?"sortinxdirection jupyterswidth":"sortinxdirection"} >
<div className="renwuxiangssi sortinxdirection">
<div><p className="renwuxiangqdiv">任务详情</p></div>
<div><p className="renwuxiangqdivtest ml1 shixunbingbaocun">请将实训题目写在下方并保存</p></div>
</div>
<div className="renwuxiangssit xaxisreverseorder">
{
enlarge===true?
<i className="iconfont icon-suoxiao2 font-18 ml2 ysliconfont" style={{
marginLeft: '30px',
}} onClick={()=>this.onclki(false)}></i>
:
<i className="iconfont icon-fangda font-18 ml2 ysliconfont" style={{
marginLeft: '30px',
}} onClick={()=>this.onclki(true)}></i>
}
{/*<div className="challenbaocun" ><p*/}
{/* className="challenbaocuntest">导入</p>*/}
{/*</div>*/}
</div>
</div>
</div>
:
:
""
)
@ -393,7 +428,6 @@ class Challengesjupyter extends Component {
}
iframe {
border-left: 1px solid #eeeeee;
border-top: 1px solid #eeeeee;
border-right: 1px solid #eeeeee;
border-bottom: 1px solid #eeeeee;
}
@ -408,25 +442,25 @@ class Challengesjupyter extends Component {
}
</style>
{
admin===true||business===true||mysidentity===true?
<div>
<div className="pb47">
{
this.state.jupyter_url===null || this.state.jupyter_url===undefined?
(
booljupyterurls===false?
<LoadingSpin></LoadingSpin>
:""
)
:
<iframe src={this.state.jupyter_url}
sandbox="allow-same-origin allow-scripts allow-top-navigation " scrolling="no" id="frame"
name="framename" width="100%" height="700" frameBorder="0"
></iframe>
}
</div>
admin===true||business===true||mysidentity===true?
<div>
<div className="pb47">
{
this.state.jupyter_url===null || this.state.jupyter_url===undefined?
(
booljupyterurls===false?
<LoadingSpin></LoadingSpin>
:""
)
:
<iframe src={this.state.jupyter_url} className={enlarge?"fangdatwo":""}
sandbox="allow-same-origin allow-scripts allow-top-navigation " scrolling="no" id="frame"
name="framename" width="100%" height="700" frameBorder="0"
></iframe>
}
</div>
:""
</div>
:""
}
</div>
</div>

@ -27,14 +27,14 @@
line-height: 25px;
}
.challenbaocun{
width:103px;
width:60px;
height:30px;
background:#29BD8B;
border-radius:3px;
cursor:pointer
}
.challenbaocuntest{
width:103px;
width:60px;
height:30px;
font-size:16px;
color:#FFFFFF;
@ -131,7 +131,6 @@
height: 76px;
line-height: 35px;
padding: 20px;
border-bottom: 1px solid #eeee;
}
.padding1020pxshixun{
@ -185,4 +184,34 @@
.icon-shanchu_Hover:hover{
color:rgb(255, 85, 85) !important;
}
.ysliconfont{
text-align: center;
line-height: 29px;
color: #8a8a8a;
}
.fangdaone{
height: 63px;
width: 100%;
position: fixed;
top: 0px;
left: 0px;
z-index: 999999;
right: 0px;
}
.fangdatwo{
height: 100%;
width: 100%;
position: fixed;
top:0px;
margin-top: 63px;
bottom: 0px;
left: 0px;
z-index: 999999;
right: 0px;
}
.jupyterswidth{
width: 1140px;
}

@ -63,6 +63,7 @@ const types = {
CHANGE_JUPYTER_CURRENT_PAGE: 'CHANGE_JUPYTER_CURRENT_PAGE',
SAVE_NOTICE_COUNT: 'SAVE_NOTICE_COUNT', // 保存代码块是否更新
AUTO_UPDATE_CODE: 'AUTO_UPDATE_CODE', // 自动更新代码
CHANGE_SHOW_DRAWER: 'CHANGE_SHOW_DRAWER',
}
export default types;

@ -72,7 +72,8 @@ import {
syncJupyterCode,
changeGetJupyterUrlState,
saveJupyterTpi,
changeCurrentPage
changeCurrentPage,
changeshowDrawer,
} from './jupyter';
export default {
@ -127,6 +128,7 @@ export default {
syncJupyterCode,
changeGetJupyterUrlState,
saveJupyterTpi,
changeCurrentPage
changeCurrentPage,
changeshowDrawer
// isUpdateCodeCtx
}

@ -154,4 +154,12 @@ export const changeCurrentPage = (current) => {
type: types.CHANGE_JUPYTER_CURRENT_PAGE,
payload: current
}
}
// 改变当前页数
export const changeshowDrawer = (type) => {
return {
type: types.CHANGE_SHOW_DRAWER,
payload: type
}
}

@ -14,7 +14,8 @@ const initialState = {
excuteState: '', // 代码执行状态
submitLoading: false, // 提交按钮状态
publishLoading: false, // 发布
isMySource: false
isMySource: false,
drawervisible:false
}
const commonReducer = (state = initialState, action) => {
@ -50,6 +51,11 @@ const commonReducer = (state = initialState, action) => {
...state,
isMySource: action.payload
}
case types.CHANGE_SHOW_DRAWER:
return {
...state,
drawervisible: action.payload
}
default:
return state;
}

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save