Commit f3158df3 authored by duiba's avatar duiba

弹窗

parent 970d30e1
This source diff could not be displayed because it is too large. You can view the blob instead.
import React from 'react'
import './AdminIndex.scss'
import { Layout, Menu, Breadcrumb, Button } from 'antd';
import ToolModal from '../../modal/ToolModal'
import PublishModal from '../../modal/PublishModal'
import TypeModal from '../../modal/TypeModal'
import PageModal from '../../modal/PageModal'
import { useContext, useEffect, useState } from "react";
function AdminIndex() {
const [visible, setVisible] = useState(false)
const [publish, setPublish] = useState(false)
const [typeModal, setTypeModal] = useState(false)
const [pageModal, setpageModal] = useState(false)
return (
<div className='admin'>
<Button onClick={() => setVisible(true)}>新建工具盒</Button>
<Button onClick={() => setTypeModal(true)}>新建类型</Button>
<Button onClick={() => setPublish(true)}>发布</Button>
<Button onClick={() => setpageModal(true)}>页面管理</Button>
{visible && <ToolModal
visible={visible}
onCancel={() =>
setVisible(false)
}
/>}
{publish && <PublishModal
visible={publish}
onCancel={() =>
setPublish(false)
}
/>}
{typeModal && <TypeModal
visible={typeModal}
onCancel={() =>
setTypeModal(false)
}
/>}
{pageModal && <PageModal
visible={pageModal}
onCancel={() =>
setpageModal(false)
}
/>}
</div>
)
}
export default AdminIndex
.admin {
float: left;
.ant-btn{
width: 100px !important;
}
width: 100px;
// height: 100px;
// border: 1px solid red;
#components-layout-demo-top-side .logo {
float: left;
width: 120px;
height: 31px;
margin: 16px 24px 16px 0;
background: rgba(255, 255, 255, 0.3);
}
.ant-row-rtl #components-layout-demo-top-side .logo {
float: right;
margin: 16px 0 16px 24px;
}
.site-layout-background {
background: #fff;
}
}
\ No newline at end of file
...@@ -5,16 +5,18 @@ import followed from '../../static/followed.png' ...@@ -5,16 +5,18 @@ import followed from '../../static/followed.png'
import setting from '../../static/setting.svg' import setting from '../../static/setting.svg'
import trash from '../../static/trash.svg' import trash from '../../static/trash.svg'
import dragIcon from '../../static/dragIcon.svg' import dragIcon from '../../static/dragIcon.svg'
import {useContext, useState} from "react"; import { useContext, useState } from "react";
import {PopContext, Root} from "../../dataCenter/Root"; import { PopContext, Root } from "../../dataCenter/Root";
import PopToolBoxConfig from "../Pop_ToolBoxConfig/Pop_toolBoxConfig"; import PopToolBoxConfig from "../Pop_ToolBoxConfig/Pop_toolBoxConfig";
import ToolModal from "../../modal/ToolModal"
function ContentItem(props) { function ContentItem(props) {
const [visible, setVisible] = useState(false)
const {fetchData, updateIndex} = useContext(Root) const { fetchData, updateIndex } = useContext(Root)
const {showPop} = useContext(PopContext) const { showPop } = useContext(PopContext)
const {toolBoxIcon, toolBoxName, toolBoxDesc, toolBoxUrl, follow, toolBoxId} = props.value const { toolBoxIcon, toolBoxName, toolBoxDesc, toolBoxUrl, follow, toolBoxId } = props.value
const [itemIcon, setItemIcon] = useState(toolBoxIcon) const [itemIcon, setItemIcon] = useState(toolBoxIcon)
...@@ -22,7 +24,7 @@ function ContentItem(props) { ...@@ -22,7 +24,7 @@ function ContentItem(props) {
window.location.href = url window.location.href = url
} }
const deleteItem = toolBoxId => { const deleteItem = toolBoxId => {
fetchData('/delete/deleteToolBoxById', {toolBoxId}) fetchData('/delete/deleteToolBoxById', { toolBoxId })
.then(() => updateIndex()) .then(() => updateIndex())
} }
...@@ -30,20 +32,28 @@ function ContentItem(props) { ...@@ -30,20 +32,28 @@ function ContentItem(props) {
<div className="content-item"> <div className="content-item">
<div className="content-adminTool"> <div className="content-adminTool">
<img src={dragIcon} alt="" /> <img src={dragIcon} alt="" />
<img src={setting} alt="" onClick={() => showPop((<PopToolBoxConfig value={props.value}/>))}/> <img src={setting} alt="" onClick={() => setVisible(true)} />
<img src={trash} alt="" onClick={() => deleteItem(toolBoxId)}/> <img src={trash} alt="" onClick={() => deleteItem(toolBoxId)} />
</div> </div>
<div className="item-icon" onClick={() => jumpUrl(toolBoxUrl)}> <div className="item-icon" onClick={() => jumpUrl(toolBoxUrl)}>
<img src={itemIcon} alt='' onError={(e) => setItemIcon(defaultIcon)}/> <img src={itemIcon} alt='' onError={(e) => setItemIcon(defaultIcon)} />
</div> </div>
<div className="item-name" onClick={() => jumpUrl(toolBoxUrl)}>{toolBoxName}</div> <div className="item-name" onClick={() => jumpUrl(toolBoxUrl)}>{toolBoxName}</div>
<div className="item-desc">{toolBoxDesc}</div> <div className="item-desc">{toolBoxDesc}</div>
<a className='item-url' href={toolBoxUrl}>{toolBoxUrl}</a> <a className='item-url' href={toolBoxUrl}>{toolBoxUrl}</a>
<div className="follow"> <div className="follow">
<img className='icon-follow' src={follow ? followed : notFollow} alt=""/> <img className='icon-follow' src={follow ? followed : notFollow} alt="" />
收藏 收藏
</div> </div>
{visible && <ToolModal
visible={visible}
onCancel={() =>
setVisible(false)
}
data={props.value}
/>}
</div> </div>
) )
} }
......
const apiConfig = { const apiConfig = {
domain: 'http://' + window.location.hostname + ':3001', domain: 'http://' + '172.16.231.162' + ':3001',
} }
export default apiConfig export default apiConfig
...@@ -27,7 +27,7 @@ function DataCenter(props) { ...@@ -27,7 +27,7 @@ function DataCenter(props) {
} }
const fetchData = (path, requestData, dataName) => const fetchData = (path, requestData, dataName) =>
fetch(generateUrl(path, requestData), {credentials: 'include',mode: 'no-cors'}) fetch(generateUrl(path, requestData), {credentials: 'include'})
.then(res => res.json()) .then(res => res.json())
.then(res => { .then(res => {
if (res.success) { if (res.success) {
......
import React, { useState } from 'react';
import { Button, Modal, Form, Input, Radio, Select, Table, Space } from 'antd';
import PublishModal from "./PublishModal"
function PageModal({ visible, onCancel, onPublish }) {
const [publish, setPublish] = useState(false)
const [pageData, setpageData] = useState('')
const onChangePage = (values) => {
console.log(values);
setpageData(values);
setPublish(true)
};
const onRemovePage = (values) => {
console.log(values);
// setVisible(false);
};
const columns = [
{
title: '页面名称',
dataIndex: 'name',
width: 200,
},
{
title: '页面类型',
dataIndex: 'age',
width: 300,
},
{
title: '操作',
key: 'action',
width: 100,
render: (text, record) => (
<Space size="middle">
<a onClick={() => onChangePage(record)}>替换</a>
{/* <a onClick={() => onRemovePage(record)}>删除</a> */}
</Space>
),
},
];
const data = [
{
key: '1',
name: '1 Brown',
age: 32,
address: 'New York No. 1 Lake Park',
},
{
key: '2',
name: '2 Green',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: '3 Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
{
key: '4',
name: '4 Brown',
age: 32,
address: 'New York No. 1 Lake Park',
},
{
key: '5',
name: '5 Green',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '6',
name: '6 Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
{
key: '7',
name: '7 Brown',
age: 32,
address: 'New York No. 1 Lake Park',
},
{
key: '8',
name: '8 Green',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '9',
name: '9 Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
{
key: '10',
name: '10 Brown',
age: 32,
address: 'New York No. 1 Lake Park',
},
{
key: '11',
name: '11 Green',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '12',
name: '12 Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
];
return (
<>
<Modal
visible={visible}
title="页面管理"
okText="确定"
cancelText="取消"
width='1000px'
onCancel={onCancel}
onOk={onCancel}
>
<Table columns={columns} dataSource={data} pagination={{ pageSize: 10 }} size="middle" />
</Modal>
{publish && <PublishModal
visible={publish}
onCancel={() =>
setPublish(false)
}
data={pageData}
/>}
</>
)
}
export default PageModal
import './PublishModal.scss'
import React, { useState, useEffect } from 'react';
import { UnControlled as CodeMirror } from 'react-codemirror2'
import { Button, Modal, Form, Input, Radio, Select, message } from 'antd';
import 'codemirror/addon/display/autorefresh';
import 'codemirror/addon/comment/comment';
import 'codemirror/addon/edit/matchbrackets';
import 'codemirror/keymap/sublime';
import 'codemirror/theme/eclipse.css';
import 'codemirror/theme/monokai.css';
import 'codemirror/lib/codemirror.js';
import 'codemirror/lib/codemirror.css';
import 'codemirror/theme/solarized.css'
import 'codemirror/mode/javascript/javascript'
import 'codemirror/addon/selection/active-line';
import 'codemirror/addon/fold/foldgutter.css';
const { Option } = Select;
const PublishModal = ({ visible, onCancel, data }) => {
const [code, setcode] = useState('')
const [pageName, setPageName] = useState('')
const [oldCode, setoldCode] = useState('')
const onCreate = (values) => {
console.log(code);
if (!code || !pageName) {
message.error('请补全信息!')
return
}
fetch('http://172.16.231.162:3001/submit/release', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
pageName: pageName,
code: code
})
})
.then(response => response.json())
.then(data => console.log(data));
onCancel()
};
useEffect(() => {
setPageName(data.name)
}, [])
return (
<Modal
visible={visible}
title="发布"
okText="发布"
cancelText="取消"
onCancel={onCancel}
onOk={onCreate}
width='1000px'
>
<Form.Item
name="pageName"
label="页面名称"
rules={[
{
required: true,
message: '请输入页面名称!',
},
]}
>
<Input placeholder="请输入页面名称" value={pageName} onChange={(e) => { setPageName(e.target.value) }} />
</Form.Item>
<Form.Item
name="type"
label="布局代码"
rules={[
{
required: true,
message: '请输入页面名称!',
},
]}
>
<div className='codeMain'>
<CodeMirror
onChange={(editor, data, value) => {
setcode(value)
}}
value={oldCode}
options={{
styleActiveLine: true,//光标代码高亮
lineNumbers: true,
theme: 'monokai',
tabSize: 2,
keyMap: 'sublime',
mode: 'text/javascript',
smartIndent: true, //自动缩进
lineWrapping: true,
autofocus: true
}}
/>
</div>
</Form.Item>
</Modal>
);
};
export default PublishModal
\ No newline at end of file
.codeMain{
.CodeMirror{
height: 600px !important;
width: 850px;
}
}
\ No newline at end of file
import React, { useState,useEffect } from 'react';
import { Button, Modal, Form, Input, Radio, Select } from 'antd';
const { Option } = Select;
const ToolModal = ({ visible, onCancel, data }) => {
const [form] = Form.useForm();
const formItemLayout = {
labelCol: { span: 4 },
wrapperCol: { span: 18 },
};
const onCreate = (values) => {
console.log('Received values of form: ', values);
// setVisible(false);
};
const onGenderChange = (value) => {
switch (value) {
case 'male':
form.setFieldsValue({
note: 'Hi, man!',
});
return;
case 'female':
form.setFieldsValue({
note: 'Hi, lady!',
});
return;
case 'other':
form.setFieldsValue({
note: 'Hi there!',
});
}
};
useEffect(() => {
data && form.setFieldsValue({
name: data.toolBoxName,
icon: data.toolBoxIcon,
url: data.toolBoxUrl,
depict: data.toolBoxDesc,
})
}, [])
return (
<Modal
visible={visible}
title={data ? '修改工具箱' : '新建工具箱'}
okText="确定"
cancelText="取消"
onCancel={onCancel}
onOk={() => {
form
.validateFields()
.then((values) => {
form.resetFields();
onCreate(values);
})
.catch((info) => {
console.log('Validate Failed:', info);
});
}}
>
<Form
form={form}
// layout="vertical"
{...formItemLayout}
name="form_in_modal"
initialValues={{
modifier: 'public',
}}
>
<Form.Item
name="name"
label="名称"
rules={[
{
required: true,
message: '请输入名称!',
},
]}
>
<Input placeholder="请输入名称" />
</Form.Item>
<Form.Item name="icon"
label="图标"
rules={[
{
required: true,
message: '请输入图标url!',
},
]}
>
<Input placeholder="请输入图标url" />
</Form.Item>
<Form.Item
name="depict"
label="描述"
rules={[
{
required: true,
message: '请输入描述!',
},
]}
>
<Input placeholder="请输入描述" />
</Form.Item>
<Form.Item
name="url"
label="链接"
rules={[
{
required: true,
message: '请输入链接!',
},
]}
>
<Input placeholder="请输入链接" />
</Form.Item>
{!data && <Form.Item
name="type"
label="类型"
rules={[
{
required: true,
message: '请选择类型!',
},
]}
>
<Select
placeholder="请选择类型"
onChange={onGenderChange}
allowClear
>
<Option value="male">male</Option>
<Option value="female">female</Option>
<Option value="other">other</Option>
</Select>
</Form.Item>}
</Form>
</Modal>
);
};
export default ToolModal
\ No newline at end of file
import React, { useState } from 'react';
import { Button, Modal, Form, Input, Radio, Select } from 'antd';
const { Option } = Select;
const TypeModal = ({ visible, onCancel }) => {
const [form] = Form.useForm();
const formItemLayout = {
labelCol: { span: 4 },
wrapperCol: { span: 18 },
};
const onCreate = (values) => {
console.log('Received values of form: ', values);
// setVisible(false);
};
return (
<Modal
visible={visible}
title="新建类型"
okText="确定"
cancelText="取消"
onCancel={onCancel}
onOk={() => {
form
.validateFields()
.then((values) => {
form.resetFields();
onCreate(values);
})
.catch((info) => {
console.log('Validate Failed:', info);
});
}}
>
<Form
form={form}
// layout="vertical"
{...formItemLayout}
name="form_in_modal"
initialValues={{
modifier: 'public',
}}
>
<Form.Item
name="type"
label="类型"
rules={[
{
required: true,
message: '请输入类型!',
},
]}
>
<Input placeholder="请输入类型" />
</Form.Item>
</Form>
</Modal>
);
};
export default TypeModal
\ No newline at end of file
...@@ -12,7 +12,7 @@ function Index() { ...@@ -12,7 +12,7 @@ function Index() {
setPop(popComponent) setPop(popComponent)
} }
const getUser = ()=>{ const getUser = ()=>{
fetchData('/users/getUser', {}, 'userInfo') fetchData('/users/getUser', {userId:'100001'}, 'userInfo')
.catch(res => .catch(res =>
res.code === 70001 && (window.location.href = '/login') res.code === 70001 && (window.location.href = '/login')
) )
......
import './index.scss' import './index.scss'
import ToolType from "../../component/ToolType/ToolType"; import ToolType from "../../component/ToolType/ToolType";
import Content from "../../component/ContentAdmin/Content"; import Content from "../../component/ContentAdmin/Content";
import {useContext, useEffect, useState} from "react"; import { useContext, useEffect, useState } from "react";
import PopAddToolBox from "../../component/Pop_addToolBox/Pop_addToolBox"; import PopAddToolBox from "../../component/Pop_addToolBox/Pop_addToolBox";
import {PopContext, Root} from "../../dataCenter/Root"; import { PopContext, Root } from "../../dataCenter/Root";
import PopAddType from "../../component/Pop_addType/Pop_addType"; import PopAddType from "../../component/Pop_addType/Pop_addType";
import logo from '../../static/logo.png' import logo from '../../static/logo.png'
import AdminIndex from '../../component/AdminIndex/AdminIndex'
function IndexAdmin() { function IndexAdmin() {
const {updateIndex} = useContext(Root) const { updateIndex } = useContext(Root)
const {fetchData, dataCenter} = useContext(Root)
const [pop, setPop] = useState() const [pop, setPop] = useState()
const showPop = popComponent => { const showPop = popComponent => {
setPop(popComponent) setPop(popComponent)
} }
const getUser = ()=>{
fetchData('/users/getUser', {userId:'100001'}, 'userInfo')
.catch(res =>
res.code === 70001 && (window.location.href = '/login')
)
}
useEffect(()=>{
getUser()
},[])
useEffect(() => { useEffect(() => {
updateIndex() updateIndex()
// dataCenter()
}, []) }, [])
return ( return (
<PopContext.Provider value={{hidePop: () => setPop(''), showPop: popName => showPop(popName)}}> <PopContext.Provider value={{hidePop: () => setPop(''), showPop: popName => showPop(popName)}}>
<div className="indexAdmin"> <div className="index">
<div className="welcome-top">
<span>欢迎您!
<span className="welcome-uname">{dataCenter?.userInfo?.uname}</span>
<a className="login-btn">退出登录</a>
</span>
</div>
<div className="nav"> <div className="nav">
<div className="nav-title"><img src={logo} alt=""/></div> <div className="nav-title">
<img src={logo} alt=""/>
</div>
<div className="nav-weather"><iframe width="360" height="40" frameBorder="0" scrolling="no" hspace="0" src="https://i.tianqi.com/?c=code&a=getcode&id=40&icon=1"/></div>
</div> </div>
<div className="adminTool"> <div className="tool-nav">
<ToolType/>
</div>
<div className="container">
<Content/>
</div>
{
pop
}
<div className></div>
<div className="index-footer">
兑吧研发中心·杭州兑吧网络科技游戏公司版权所有
<br/>
浙ICP备14017299号-1
</div>
<AdminIndex />
{/* <div className="adminTool">
<button className='btn-admin' onClick={() => setPop((<PopAddToolBox/>))}>新建工具盒</button> <button className='btn-admin' onClick={() => setPop((<PopAddToolBox/>))}>新建工具盒</button>
<button className='btn-admin' onClick={() => setPop((<PopAddType/>))}>新建类型</button> <button className='btn-admin' onClick={() => setPop((<PopAddType/>))}>新建类型</button>
</div> </div>
...@@ -38,8 +78,11 @@ function IndexAdmin() { ...@@ -38,8 +78,11 @@ function IndexAdmin() {
</div> </div>
{ {
pop pop
} } */}
</div> </div>
</PopContext.Provider> </PopContext.Provider>
) )
} }
......
...@@ -2,38 +2,63 @@ ...@@ -2,38 +2,63 @@
body { body {
background: $backgroundColor; background: $backgroundColor;
} }
.indexAdmin { .index {
width: 100%; width: 100%;
height: 100%; height: 100%;
color: $fontColor; color: $fontColor;
background: #f1f1f1;
.adminTool{ font-size: 14px;
position: absolute; font-style: normal;
width: 160px; .welcome-top{
background-color: #444;
color: #fff;
text-align: right;
padding: 7px 10px;
font-size: 13px;
.welcome-uname{
padding: 0px 4px;
font-weight: bold;
}
.login-btn{
cursor: pointer;
text-decoration: underline;
}
}
.index-footer{
text-align: center; text-align: center;
top: 60px; color: #b3b3b3;
.btn-admin{ line-height: 26px;
width: 120px; margin-top: 12px;
height: 35px; }
.nav-weather{
float: right;
padding-top: 18px;
&::after{
display: block;
clear: both;
content: "";
} }
} }
.nav { .nav {
width: 100%; width: 100%;
height: 40px; height: 60px;
background: $topBarBg; //background: $topBarBg;
color: #fff; color: #fff;
max-width: 1190px;
min-width: 612px;
margin: auto;
border-bottom: 2px solid #dedede;
.nav-title { .nav-title {
width: 150px; width: 150px;
height: 40px; height: 50px;
font-size: 32px; font-size: 32px;
line-height: 40px; line-height: 50px;
font-weight: bold;; font-weight: bold;;
text-align: center; text-align: center;
margin-left: 20px; margin-left: 20px;
float: left;
margin-top: 6px;
img { img {
width: 100%; width: 100%;
} }
...@@ -43,14 +68,18 @@ body { ...@@ -43,14 +68,18 @@ body {
.tool-nav { .tool-nav {
width: 100%; width: 100%;
min-width: 612px; min-width: 612px;
max-width: 1190px;
box-sizing: border-box; box-sizing: border-box;
margin: 0 auto 0;
} }
} }
.container { .container {
width: 100%; width: 100%;
min-width: 612px; min-width: 612px;
padding: 20px 180px; max-width: 1190px;
padding: 20px 0;
margin: 0 auto 0;
box-sizing: border-box; box-sizing: border-box;
} }
...@@ -8,7 +8,7 @@ function Login(props) { ...@@ -8,7 +8,7 @@ function Login(props) {
const [needLogin,setNeedLogin] = useState(false) const [needLogin,setNeedLogin] = useState(false)
const [input, setInput] = useFormState() const [input, setInput] = useFormState()
const getUser = ()=>{ const getUser = ()=>{
fetchData('/users/getUser', {}, 'userInfo') fetchData('/users/getUser', {userId:'100001'}, 'userInfo')
.then(res => res.data.uid && (window.location.href = '/index')) .then(res => res.data.uid && (window.location.href = '/index'))
.catch(res => .catch(res =>
res.code === 70001 && setNeedLogin(true) res.code === 70001 && setNeedLogin(true)
...@@ -16,7 +16,7 @@ function Login(props) { ...@@ -16,7 +16,7 @@ function Login(props) {
} }
const doLogin = () => { const doLogin = () => {
if (needLogin){ if (needLogin){
fetchData('/users/login',{userId: input.userId}) fetchData('/users/login',{userId: '100001'})
.then(()=>{ .then(()=>{
getUser() getUser()
}) })
......
...@@ -3591,6 +3591,11 @@ code-point-at@^1.0.0: ...@@ -3591,6 +3591,11 @@ code-point-at@^1.0.0:
resolved "http://npm.dui88.com:80/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" resolved "http://npm.dui88.com:80/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
codemirror@^5.62.3:
version "5.62.3"
resolved "https://registry.nlark.com/codemirror/download/codemirror-5.62.3.tgz?cache=0&sync_timestamp=1629450520293&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcodemirror%2Fdownload%2Fcodemirror-5.62.3.tgz#5cfdee6931c8b2d1b39ae773aaaaec2cc6b5558e"
integrity sha1-XP3uaTHIstGzmudzqqrsLMa1VY4=
collect-v8-coverage@^1.0.0: collect-v8-coverage@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "http://npm.dui88.com:80/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" resolved "http://npm.dui88.com:80/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59"
...@@ -10105,6 +10110,11 @@ react-app-polyfill@^2.0.0: ...@@ -10105,6 +10110,11 @@ react-app-polyfill@^2.0.0:
regenerator-runtime "^0.13.7" regenerator-runtime "^0.13.7"
whatwg-fetch "^3.4.1" whatwg-fetch "^3.4.1"
react-codemirror2@^7.2.1:
version "7.2.1"
resolved "https://registry.npm.taobao.org/react-codemirror2/download/react-codemirror2-7.2.1.tgz#38dab492fcbe5fb8ebf5630e5bb7922db8d3a10c"
integrity sha1-ONq0kvy+X7jr9WMOW7eSLbjToQw=
react-dev-utils@^11.0.3: react-dev-utils@^11.0.3:
version "11.0.4" version "11.0.4"
resolved "http://npm.dui88.com:80/react-dev-utils/-/react-dev-utils-11.0.4.tgz#a7ccb60257a1ca2e0efe7a83e38e6700d17aa37a" resolved "http://npm.dui88.com:80/react-dev-utils/-/react-dev-utils-11.0.4.tgz#a7ccb60257a1ca2e0efe7a83e38e6700d17aa37a"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment