App.jsx 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. import React, {Component} from 'react';
  2. import {Layout, Menu, Button, Spin, Icon, LocaleProvider} from 'antd';
  3. import {BrowserRouter as Router, Route, Link, Switch, Redirect} from "react-router-dom";
  4. import {Query} from "react-apollo";
  5. import gql from "graphql-tag";
  6. import moment from 'moment';
  7. import 'moment/locale/zh-cn';
  8. import {FormattedMessage} from 'react-intl';
  9. import zhCN from 'antd/lib/locale-provider/zh_CN';
  10. import QuantService from "./quantService/QuantService";
  11. import TrialCase from "./graphqlService/trialCase/TrialCase";
  12. import UserCreate from "./graphqlService/userCreate/UserCreate";
  13. import WXTrialCase from "./wechatService/wxTrialCase/WXTrialCase";
  14. import WXUserCreate from "./wechatService/wxUserCreate/WXUserCreate";
  15. import Login from "../login/Login";
  16. import './graphqlService/common/graphql/index.css';
  17. import './index.css'
  18. import Create from "./graphqlService/common/schema/Create";
  19. import WxCreate from "./wechatService/wxCreate/WxCreate";
  20. import {SHOW_ALL_SCHEMA, SHOW_ALL_WXCONFIG} from "../gql";
  21. import axios from 'axios';
  22. import {getCookie} from "../cookie";
  23. axios.defaults.withCredentials = true;
  24. const {SubMenu} = Menu;
  25. const {Header, Sider} = Layout;
  26. moment.locale('en');
  27. class App extends Component {
  28. constructor(props) {
  29. super(props);
  30. this.state = {
  31. menuLevel1: "graphql-service",
  32. sideBar: "ecommerce",
  33. collapsed: false,
  34. inlineCollapsed: false,
  35. language: props.language,
  36. locale: props.language === "中文" ? zhCN : undefined,
  37. languageButton: props.language === "中文" ? "English" : "中文",
  38. visible: false,
  39. wxVisible: false
  40. };
  41. }
  42. componentWillMount() {
  43. let urlList = window.location.pathname.split("/");
  44. let urlListLength = urlList.length;
  45. if (urlListLength > 2) {
  46. this.setState({menuLevel1: urlList[1]});
  47. if (urlList[3] !== 'index') {
  48. this.setState({sideBar: urlList[3]});
  49. }
  50. }
  51. }
  52. onCollapse = (collapsed) => {
  53. this.setState({collapsed});
  54. };
  55. switchMenu = (menuName, e) => {
  56. this.setState({
  57. [menuName]: e.key,
  58. });
  59. };
  60. switchMenuTab = (menuName, e) => {
  61. this.setState({
  62. [menuName]: e.key,
  63. });
  64. if (e.key === "graphql-service") {
  65. this.setState({sideBar: "ecommerce"});
  66. }
  67. };
  68. switchSidebar = (value) => {
  69. this.setState({
  70. sideBar: value,
  71. });
  72. };
  73. switchMenuLevel = (menuName, value) => {
  74. this.setState({
  75. [menuName]: value,
  76. });
  77. };
  78. showModal = () => {
  79. this.setState({
  80. visible: true,
  81. });
  82. };
  83. wxShowModal = () => {
  84. this.setState({
  85. wxVisible: true,
  86. });
  87. };
  88. hideModal = () => {
  89. this.setState({
  90. visible: false,
  91. });
  92. };
  93. wxHideModal = () => {
  94. this.setState({
  95. wxVisible: false,
  96. });
  97. };
  98. changeLocale = (e) => {
  99. e.stopPropagation();
  100. let {language} = this.state;
  101. // console.log('app language',language);
  102. let changeLanguage = language === "中文" ? "English" : "中文";
  103. let local = language === "中文" ? undefined : zhCN;
  104. let languageButton = language === "中文" ? "中文" : "English";
  105. sessionStorage.setItem("language", changeLanguage);
  106. this.props.changeLanguage(changeLanguage);
  107. this.setState({
  108. language: changeLanguage,
  109. locale: local,
  110. languageButton: languageButton
  111. });
  112. if (!local) {
  113. moment.locale('en');
  114. } else {
  115. moment.locale('zh-cn');
  116. }
  117. };
  118. render() {
  119. const {locale, languageButton, visible, wxVisible} = this.state;
  120. return (
  121. <Router>
  122. <Layout style={{minHeight: '100vh'}}>
  123. <Header className="header" style={{position: 'fixed', zIndex: 1, width: '100%'}}>
  124. <Link to="/"
  125. onClick={() => this.setState({menuLevel1: "graphql-service", sideBar: "ecommerce"})}>
  126. <div className="logo-wrapper">
  127. <div className='logo'/>
  128. </div>
  129. </Link>
  130. <Menu
  131. theme="dark"
  132. mode="horizontal"
  133. selectedKeys={[this.state.menuLevel1]}
  134. style={{lineHeight: '64px'}}
  135. onClick={(e) => this.switchMenuTab('menuLevel1', e)}
  136. >
  137. <Menu.Item key="graphql-service">
  138. <Link to="/graphql-service/trial-case/index"><FormattedMessage
  139. id="Graphql Service"/></Link>
  140. </Menu.Item>
  141. <Menu.Item key="wechat-service">
  142. <Link to="/wechat-service/trial-case/index"><FormattedMessage
  143. id="Wechat Service"/></Link>
  144. </Menu.Item>
  145. <Menu.Item key="quant-service">
  146. <Link to="/quant-service/trial-case/index"><FormattedMessage id="Quantization Service"/></Link>
  147. </Menu.Item>
  148. </Menu>
  149. <Link to="/login">
  150. <Button className='login-button' type='primary'
  151. onClick={() => this.switchMenuLevel('menuLevel1', 'user')}>Login</Button>
  152. </Link>
  153. <div className="change-locale">
  154. <Button size="small" onClick={(e) => this.changeLocale(e)}>{languageButton}</Button>
  155. </div>
  156. </Header>
  157. {(() => {
  158. switch (this.state.menuLevel1) {
  159. case 'graphql-service':
  160. return (
  161. <Sider
  162. width={200}
  163. style={{background: '#fff', marginTop: '64px', zIndex: '0'}}
  164. collapsible
  165. collapsed={this.state.collapsed}
  166. onCollapse={this.onCollapse}
  167. >
  168. <GraphqlSidebar inlineCollapsed={this.state.inlineCollapsed}
  169. sideBar={this.state.sideBar} switchMenu={this.switchMenu}
  170. showModal={this.showModal}/>
  171. </Sider>
  172. );
  173. case 'wechat-service':
  174. return (
  175. <Sider
  176. width={200}
  177. style={{background: '#fff', marginTop: '64px', zIndex: '0'}}
  178. collapsible
  179. collapsed={this.state.collapsed}
  180. onCollapse={this.onCollapse}
  181. >
  182. <WxConfigSiderbar inlineCollapsed={this.state.inlineCollapsed}
  183. sideBar={this.state.sideBar} switchMenu={this.switchMenu}
  184. wxShowModal={this.wxShowModal}/>
  185. </Sider>
  186. );
  187. case 'quant-service':
  188. return (
  189. <Sider
  190. width={200}
  191. style={{background: '#fff', marginTop: '64px', zIndex: '0'}}
  192. collapsible
  193. collapsed={this.state.collapsed}
  194. onCollapse={this.onCollapse}
  195. >
  196. <Menu
  197. theme="dark"
  198. mode="inline"
  199. inlineCollapsed={this.state.inlineCollapsed}
  200. defaultSelectedKeys={['quant-service']}
  201. defaultOpenKeys={['trial-case']}
  202. // openKeys={['cloud-function']}
  203. onClick={(e) => this.switchMenu('sideBar', e)}
  204. selectedKeys={[this.state.sideBar]}
  205. style={{
  206. borderRight: 0,
  207. overflow: 'auto',
  208. height: '100vh',
  209. left: '0',
  210. width: '200px',
  211. position: 'fixed'
  212. }}
  213. >
  214. <SubMenu key="trial-case" title={<span><Icon type="appstore"
  215. theme="twoTone"/><span>Case Show</span></span>}>
  216. <Menu.Item key="quant-service">
  217. <Link to="/quant-service/trial-case/quant case">quant case</Link>
  218. </Menu.Item>
  219. </SubMenu>
  220. <Menu.Item key="instructions">
  221. <a href="https://ioobot-document.netlify.com/" title="instructions"
  222. target="instructions">
  223. <Icon type="file-text" theme="twoTone"/>
  224. <span>Instructions</span>
  225. </a>
  226. </Menu.Item>
  227. </Menu>
  228. </Sider>
  229. );
  230. case 'user':
  231. return (
  232. <Sider
  233. width={200}
  234. style={{background: '#fff', marginTop: '64px', zIndex: '0'}}
  235. collapsible
  236. collapsed={this.state.collapsed}
  237. onCollapse={this.onCollapse}
  238. >
  239. <Menu
  240. theme="dark"
  241. defaultSelectedKeys={['cloud-settings']}
  242. onClick={(e) => this.switchMenu('sideBar', e)}
  243. selectedKeys={[this.state.sideBar]}
  244. style={{
  245. borderRight: 0,
  246. overflow: 'auto',
  247. height: '100vh',
  248. left: '0',
  249. width: '200px',
  250. position: 'fixed'
  251. }}
  252. >
  253. <Menu.Item key="account">
  254. <Icon type="setting" theme="twoTone"/>
  255. <span>Account center</span>
  256. <Link to="/login/account"/>
  257. </Menu.Item>
  258. <Menu.Item key="cloud-settings">
  259. <Icon type="cloud" theme="twoTone"/>
  260. <span>Cloud settings</span>
  261. <Link to="/login/cloud"/>
  262. </Menu.Item>
  263. </Menu>
  264. </Sider>
  265. );
  266. default:
  267. return (
  268. <Sider
  269. width={200}
  270. style={{background: '#fff', marginTop: '64px', zIndex: '0'}}
  271. collapsible
  272. collapsed={this.state.collapsed}
  273. onCollapse={this.onCollapse}
  274. >
  275. <GraphqlSidebar inlineCollapsed={this.state.inlineCollapsed}
  276. sideBar={this.state.sideBar} switchMenu={this.switchMenu}
  277. showModal={this.showModal}/>
  278. </Sider>
  279. );
  280. }
  281. })()}
  282. <Create visible={visible} hideModal={this.hideModal} switchSidebar={this.switchSidebar}/>
  283. <WxCreate visible={wxVisible} hideModal={this.wxHideModal} switchSidebar={this.switchSidebar}/>
  284. <LocaleProvider locale={locale}>
  285. <Layout style={{marginTop: '64px', zIndex: '0'}}
  286. key={locale ? locale.locale : 'en'/* Have to refresh for production environment */}>
  287. <Switch>
  288. <Route path="/" exact component={TrialCase}/>
  289. <Route path="/graphql-service/trial-case/:case" component={TrialCase}/>
  290. <Route path="/graphql-service/my-create/:case" component={UserCreate}/>
  291. <Route path="/wechat-service/trial-case/:case" component={WXTrialCase}/>
  292. <Route path="/wechat-service/my-create/:case" component={WXUserCreate}/>
  293. <Route path="/quant-service/:sidebar/:case" component={QuantService}/>
  294. <Route path="/login/:setting" component={Login}/>
  295. <Route path="/login" component={Login}/>
  296. <Redirect path="*" to="/"/>
  297. </Switch>
  298. </Layout>
  299. </LocaleProvider>
  300. </Layout>
  301. </Router>
  302. );
  303. }
  304. }
  305. export default App;
  306. class GraphqlSidebar extends Component {
  307. constructor(props) {
  308. super(props);
  309. this.state = {
  310. userID: getCookie('user_id'),
  311. }
  312. }
  313. render() {
  314. return (
  315. <Query query={gql(SHOW_ALL_SCHEMA)} variables={{user_id: this.state.userID}}>
  316. {
  317. ({loading, error, data}) => {
  318. // console.log('user schema data',data);
  319. if (loading) return <Spin style={{marginLeft: 3}}/>;
  320. if (error) return 'error!';
  321. localStorage.setItem('ecommerce', data.caseSchema.find(obj => obj.schemaName === 'ecommerce').schemaData);
  322. localStorage.setItem('subscribe', data.caseSchema.find(obj => obj.schemaName === 'subscribe').schemaData);
  323. localStorage.setItem('bills', data.caseSchema.find(obj => obj.schemaName === 'bills').schemaData);
  324. return (
  325. <Menu
  326. theme="dark"
  327. mode="inline"
  328. inlineCollapsed={this.props.inlineCollapsed}
  329. defaultSelectedKeys={['ecommerce']}
  330. defaultOpenKeys={['trial-case', 'my-create']}
  331. // openKeys={['trial-case', 'my-create']}
  332. onClick={(e) => this.props.switchMenu('sideBar', e)}
  333. selectedKeys={[this.props.sideBar]}
  334. style={{
  335. borderRight: 0,
  336. overflow: 'auto',
  337. height: '100vh',
  338. left: '0',
  339. width: '200px',
  340. position: 'fixed'
  341. }}
  342. >
  343. <SubMenu key="trial-case" title={<span><Icon type="appstore" theme="twoTone"/><span>Case Show</span></span>}>
  344. {
  345. data.caseSchema.map((schema) =>
  346. <Menu.Item key={schema.schemaName}>
  347. <Link to={{
  348. pathname: `/graphql-service/trial-case/${schema.schemaName}`,
  349. state: {
  350. schemaName: schema.schemaName,
  351. schemaID: schema.id
  352. }
  353. }}>{schema.schemaName}</Link>
  354. </Menu.Item>)
  355. }
  356. </SubMenu>
  357. <Menu.Item key="create-graphql" onClick={this.props.showModal}>
  358. <Icon type="edit" theme="twoTone"/>
  359. <span>Create</span>
  360. <Icon type="plus" style={{
  361. position: 'absolute',
  362. top: '35%',
  363. right: '6px',
  364. color: 'white'
  365. }}/>
  366. </Menu.Item>
  367. <SubMenu key="my-create" title={<span><Icon type="user" theme="outlined"/><span>My Create</span></span>}>
  368. {
  369. data.userSchema.map((schema) =>
  370. <Menu.Item key={schema.schemaName}>
  371. <Link to={{
  372. pathname: `/graphql-service/my-create/${schema.schemaName}`,
  373. state: {
  374. schemaName: schema.schemaName,
  375. schemaID: schema.id
  376. }
  377. }}>{schema.schemaName}</Link>
  378. </Menu.Item>)
  379. }
  380. </SubMenu>
  381. <Menu.Item key="instructions">
  382. <a href="https://ioobot-document.netlify.com/" title="instructions" target="_blank"
  383. rel="noopener noreferrer">
  384. <Icon type="file-text" theme="twoTone"/>
  385. <span>Instructions</span>
  386. </a>
  387. </Menu.Item>
  388. </Menu>
  389. )
  390. }
  391. }
  392. </Query>
  393. )
  394. }
  395. }
  396. class WxConfigSiderbar extends Component {
  397. constructor(props) {
  398. super(props);
  399. this.state = {
  400. userID: getCookie('user_id'),
  401. }
  402. }
  403. render() {
  404. return (
  405. <Query query={gql(SHOW_ALL_WXCONFIG)} variables={{user_id: this.state.userID}}>
  406. {
  407. ({loading, error, data}) => {
  408. if (loading) return <Spin style={{marginLeft: 3}}/>;
  409. if (error) return 'error!';
  410. return (
  411. <Menu
  412. theme="dark"
  413. mode="inline"
  414. inlineCollapsed={this.props.inlineCollapsed}
  415. defaultSelectedKeys={['my-wechat']}
  416. defaultOpenKeys={['trial-case', 'my-create']}
  417. // openKeys={['trial-case', 'my-create']}
  418. onClick={(e) => this.props.switchMenu('sideBar', e)}
  419. selectedKeys={[this.props.sideBar]}
  420. style={{
  421. borderRight: 0,
  422. overflow: 'auto',
  423. height: '100vh',
  424. left: '0',
  425. width: '200px',
  426. position: 'fixed'
  427. }}
  428. >
  429. <SubMenu key="trial-case" title={<span><Icon type="appstore" theme="twoTone"/><span>Case Show</span></span>}>
  430. {
  431. data.caseWxConfig.map((config) =>
  432. <Menu.Item key={config.appName}>
  433. <Link to={{
  434. pathname: `/wechat-service/trial-case/${config.appName}`,
  435. state: {
  436. appName: config.appName,
  437. configID: config.id
  438. }
  439. }}>{config.appName}</Link>
  440. </Menu.Item>)
  441. }
  442. </SubMenu>
  443. <Menu.Item key="create-config" onClick={this.props.wxShowModal}>
  444. <Icon type="edit" theme="twoTone"/>
  445. <span>Create</span>
  446. <Icon type="plus" style={{
  447. position: 'absolute',
  448. top: '35%',
  449. right: '6px',
  450. color: 'white'
  451. }}/>
  452. </Menu.Item>
  453. <SubMenu key="my-create" title={<span><Icon type="user" theme="outlined"/><span>My Create</span></span>}>
  454. {
  455. data.userWxConfig.map((config) =>
  456. <Menu.Item key={config.appName}>
  457. <Link to={{
  458. pathname: `/wechat-service/my-create/${config.appName}`,
  459. state: {
  460. appName: config.appName,
  461. configID: config.id
  462. }
  463. }}>{config.appName}</Link>
  464. </Menu.Item>)
  465. }
  466. </SubMenu>
  467. <Menu.Item key="instructions">
  468. <a href="https://ioobot-document.netlify.com/" title="instructions" target="_blank"
  469. rel="noopener noreferrer">
  470. <Icon type="file-text" theme="twoTone"/>
  471. <span>Instructions</span>
  472. </a>
  473. </Menu.Item>
  474. </Menu>
  475. )
  476. }
  477. }
  478. </Query>
  479. )
  480. }
  481. }