Browse Source

feature:重构服务仪表盘

liweimin 2 years ago
commit
eb4c581cf3
17 changed files with 470 additions and 0 deletions
  1. 16 0
      .editorconfig
  2. 20 0
      .gitignore
  3. 8 0
      .prettierignore
  4. 11 0
      .prettierrc
  5. 23 0
      .umirc.ts
  6. 15 0
      README.md
  7. 0 0
      mock/.gitkeep
  8. 41 0
      package.json
  9. 11 0
      src/api/api.tsx
  10. 55 0
      src/api/index.ts
  11. 35 0
      src/pages/home.tsx
  12. 6 0
      src/pages/index.less
  13. 148 0
      src/pages/index.tsx
  14. 22 0
      src/router/index.tsx
  15. 12 0
      src/utils/index.tsx
  16. 37 0
      tsconfig.json
  17. 10 0
      typings.d.ts

+ 16 - 0
.editorconfig

@@ -0,0 +1,16 @@
+# http://editorconfig.org
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[Makefile]
+indent_style = tab

+ 20 - 0
.gitignore

@@ -0,0 +1,20 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/npm-debug.log*
+/yarn-error.log
+/yarn.lock
+/package-lock.json
+
+# production
+/dist
+
+# misc
+.DS_Store
+
+# umi
+/src/.umi
+/src/.umi-production
+/src/.umi-test
+/.env.local

+ 8 - 0
.prettierignore

@@ -0,0 +1,8 @@
+**/*.md
+**/*.svg
+**/*.ejs
+**/*.html
+package.json
+.umi
+.umi-production
+.umi-test

+ 11 - 0
.prettierrc

@@ -0,0 +1,11 @@
+{
+  "singleQuote": true,
+  "trailingComma": "all",
+  "printWidth": 80,
+  "overrides": [
+    {
+      "files": ".prettierrc",
+      "options": { "parser": "json" }
+    }
+  ]
+}

+ 23 - 0
.umirc.ts

@@ -0,0 +1,23 @@
+import { defineConfig } from 'umi';
+import  routes from './src/router'
+
+export default defineConfig({
+  // nodeModulesTransform: {
+  //   type: 'none',
+  // },
+  layout: {
+    name: 'RPC Project',
+    layout: 'side', 
+    navTheme: 'light',
+  },
+  routes,
+  fastRefresh: {},
+  // publicPath:'/',
+  proxy:{
+    '/api': {
+      'target': 'https://rpc-dashboard.ywtinfo.com/api/',
+      'changeOrigin': true,
+      'pathRewrite': { '^/api' : '' },
+    },
+  },
+});

+ 15 - 0
README.md

@@ -0,0 +1,15 @@
+# umi project
+
+## Getting Started
+
+Install dependencies,
+
+```bash
+$ yarn
+```
+
+Start the dev server,
+
+```bash
+$ yarn start
+```

+ 0 - 0
mock/.gitkeep


+ 41 - 0
package.json

@@ -0,0 +1,41 @@
+{
+  "private": true,
+  "scripts": {
+    "start": "umi dev",
+    "build": "umi build",
+    "postinstall": "umi generate tmp",
+    "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
+    "test": "umi-test",
+    "test:coverage": "umi-test --coverage"
+  },
+  "homepage": ".",
+  "gitHooks": {
+    "pre-commit": "lint-staged"
+  },
+  "lint-staged": {
+    "*.{js,jsx,less,md,json}": [
+      "prettier --write"
+    ],
+    "*.ts?(x)": [
+      "prettier --parser=typescript --write"
+    ]
+  },
+  "dependencies": {
+    "@ahooksjs/use-url-state": "^3.5.0",
+    "@ant-design/pro-layout": "^6.5.0",
+    "ahooks": "^3.5.2",
+    "react": "17.x",
+    "react-dom": "17.x",
+    "umi": "^3.5.26"
+  },
+  "devDependencies": {
+    "@types/react": "^17.0.0",
+    "@types/react-dom": "^17.0.0",
+    "@umijs/preset-react": "1.x",
+    "@umijs/test": "^3.5.26",
+    "lint-staged": "^10.0.7",
+    "prettier": "^2.2.0",
+    "typescript": "^4.1.2",
+    "yorkie": "^2.0.0"
+  }
+}

+ 11 - 0
src/api/api.tsx

@@ -0,0 +1,11 @@
+import HttpRequest from './index'
+
+const url = 'https://rpc-dashboard.ywtinfo.com/api'
+export default {
+    testApi: ():Promise<any> => HttpRequest({
+        url: url + '/getenvs',
+        method: 'get',
+        params: {
+        }
+    })
+}

+ 55 - 0
src/api/index.ts

@@ -0,0 +1,55 @@
+// request.js
+
+import { extend } from "umi-request";
+
+const errmsgMap = {
+    
+}
+
+interface Config {
+  url:string
+  method:string
+  params?:any
+}
+
+const HttpRequest = ({url, method, params}: Config) => {
+    let config = {
+        method, // 请求方式
+        params: (method == 'GET' || method == 'get') ? params : {}, // 如果是get请求使用 params
+        data: (method == 'POST' || method == 'post') ? params : '', // 如果是post请求使用 data
+        timeout: 5000,
+        headers: {
+            'Content-Type': 'text/plain',
+            "Access-Control-Allow-Origin":"*"
+        },
+        prefix: '',
+        suffix: '',
+        errorHandler: function (error:any) {
+            if (error.response) {
+              console.log(error.response.status);
+              console.log(error.response.headers);
+              console.log(error.data);
+              console.log(error.request);
+            } else {
+              console.log(error.message);
+            }
+            throw error;
+        },
+    }
+    const request = extend(config)
+
+    
+    request.interceptors.request.use((request,options) =>{
+      console.log('request ===>',request)
+      return {url,options}
+    })
+    
+    request.interceptors.response.use((response)=>{
+      console.log('response ==>',response)
+      return response
+    },{})
+    
+    return request(url)
+}
+
+export default HttpRequest;

+ 35 - 0
src/pages/home.tsx

@@ -0,0 +1,35 @@
+import styles from './index.less';
+import { Layout, Menu } from 'antd';
+import { useState } from 'react';
+const { SubMenu } = Menu;
+const { Header, Content, Sider } = Layout;
+
+export default function IndexPage() {
+  const [value, setValue] = useState(0);
+  const complexIncrease = () => {
+    setTimeout(() => {
+      setValue(value + 1)
+    },0)
+  }
+  return (
+    <>
+    <section>
+        <h2>计数器</h2>
+        <h3>{value}</h3>
+
+        <button>-</button>
+        <button onClick={() => setValue(value+1)}>+</button>
+      </section>
+      <section>
+        <h2>计数器</h2>
+        <h3>{value}</h3>
+
+        <button onClick={complexIncrease}>延迟</button>
+      </section>
+      </>
+    // <Layout>
+    //   <span>home</span>
+      
+    // </Layout>
+  );
+}

+ 6 - 0
src/pages/index.less

@@ -0,0 +1,6 @@
+.title {
+  background: rgb(121, 242, 157);
+}
+.ant-tabs > .ant-tabs-nav .ant-tabs-nav-wrap {
+  justify-content: center !important;
+}

+ 148 - 0
src/pages/index.tsx

@@ -0,0 +1,148 @@
+import './index.less';
+import { Layout, Menu, Tabs, Table, Divider, Tag } from 'antd';
+import React from 'react';
+import useUrlState from '@ahooksjs/use-url-state';
+import { useMount } from 'ahooks'
+import api from '../api/api'
+import { useEffect, useState } from 'react';
+import timestampToTime from '@/utils';
+const { TabPane } = Tabs;
+const { SubMenu } = Menu;
+const { Column, ColumnGroup } = Table;
+const { Header, Content, Sider } = Layout;
+type Detail = {
+  Detail:string
+  Env:string
+  Host:string
+  Port:number
+  ServiceName:string
+  UpTime:number
+  Version?:string
+}
+const data: Detail[] = [
+  {
+    Detail: "",
+    Env: "qa",
+    Host: "127.0.0.1",
+    Port: 6910,
+    ServiceName: "com.ywt.gapi.check_prescription.CheckPrescriptionService",
+    UpTime: 1649995051,
+    Version: "",
+  },{
+    Detail: "",
+    Env: "qa",
+    Host: "127.0.0.1",
+    Port: 6910,
+    ServiceName: "com.ywt.gapi.check_prescription.CheckPrescriptionService",
+    UpTime: 1649995051,
+    Version: ""
+  },{
+    Detail: "",
+    Env: "qa",
+    Host: "127.0.0.1",
+    Port: 6910,
+    ServiceName: "com.ywt.gapi.check_prescription.CheckPrescriptionService",
+    UpTime: 1649995051,
+    Version: ""
+  },
+];
+const data2: Detail[] = data.map(item => {return {...item,Env:'dev'}})
+const data3: Detail[] = data.map(item => {return {...item,Env:'qa1'}})
+const data4: Detail[] = data.map(item => {return {...item,Env:'prod'}})
+const tabsList = [
+  {
+    name: 'qa',
+    key: 'qa',
+    list: data
+  },
+  {
+    name: 'dev',
+    key: 'dev',
+    list: data2
+  },
+  {
+    name: 'qa1',
+    key: 'qa1',
+    list: data3
+  },
+  {
+    name: 'prod',
+    key: 'prod',
+    list: data4
+  }
+];
+export default function IndexPage() {
+  const [key,setKey] = useState('qa')
+  const [list,setList] = useState(data)
+  const [label,setLabel] = useUrlState({ count: tabsList[0].name })
+  useMount(()=>{
+      setLabel({ count: label.count ? label.count : tabsList[0].name })
+      setKey(label.count ? label.count : tabsList[0].key)
+  })
+  const columns = [
+    {
+      title: '服务名称',
+      dataIndex: 'ServiceName',
+    },
+    {
+      title: 'IP',
+      dataIndex: 'Host',
+    },
+    {
+      title: '端口',
+      dataIndex: 'Port',
+    },
+    {
+      title: 'Env',
+      dataIndex: 'Env',
+    },
+    {
+      title: '上线时间',
+      dataIndex: 'UpTime',
+      render: (text:number) => <a>{timestampToTime(text)}</a>
+    },
+    {
+      title: '备注',
+      dataIndex: 'Detail',
+    },
+  ];
+  
+  useEffect(() => {
+    api.testApi().then((res) => {
+      console.log(res);
+    })
+  })
+
+  const tabChange = (index:string) => {
+    setKey(index)
+    const instance = tabsList.find(item=>item.key === index)
+    if(instance){
+      setList(instance.list)
+      setLabel({ count: instance.name})
+    }
+  }
+
+
+  return (
+    <Layout>
+      <div style={{ justifyContent: 'center' }}>
+        <Tabs defaultActiveKey={key} activeKey={key} onChange={tabChange}>
+          {tabsList.map((item) => {
+            return (
+              <TabPane tab={item.name} key={item.key} >
+                
+              </TabPane>
+            )
+          })}
+        </Tabs>
+        <Table
+          columns={columns}
+          dataSource={list}
+          key="tablekey11"
+        >
+        </Table>
+      </div>
+    </Layout>
+  );
+}
+

+ 22 - 0
src/router/index.tsx

@@ -0,0 +1,22 @@
+export default [
+  {
+    path: '/grpcService',
+    component: '@/pages/index',
+    menu: {
+      name: 'GRPC服务',
+      flatMenu: false,
+      hideInMenu: false,
+      hideChildrenInMenu: false,
+    },
+  },
+  {
+    path: '/restService',
+    component: '@/pages/home',
+    menu: {
+      name: 'REST服务',
+      flatMenu: false,
+      hideInMenu: false,
+      hideChildrenInMenu: false,
+    },
+  }
+];

+ 12 - 0
src/utils/index.tsx

@@ -0,0 +1,12 @@
+export default function timestampToTime(time: number) {
+  if(!time) return
+  let timestamp = time.toString().length <= 10 ? time * 1000 : time
+  let date = new Date(timestamp);//时间戳为10位需*1000,时间戳为13位的话不需乘1000
+  let Y = date.getFullYear() + '-';
+  let M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
+  let D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' ';
+  let h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
+  let m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':';
+  let s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
+  return Y + M + D + h + m + s;
+}

+ 37 - 0
tsconfig.json

@@ -0,0 +1,37 @@
+{
+  "compilerOptions": {
+    "target": "esnext",
+    "module": "esnext",
+    "moduleResolution": "node",
+    "resolveJsonModule": true,
+    "importHelpers": true,
+    "jsx": "react-jsx",
+    "esModuleInterop": true,
+    "sourceMap": true,
+    "baseUrl": "./",
+    "strict": true,
+    "paths": {
+      "@/*": ["src/*"],
+      "@@/*": ["src/.umi/*"]
+    },
+    "allowSyntheticDefaultImports": true
+  },
+  "include": [
+    "mock/**/*",
+    "src/**/*",
+    "config/**/*",
+    ".umirc.ts",
+    "typings.d.ts"
+  ],
+  "exclude": [
+    "node_modules",
+    "lib",
+    "es",
+    "dist",
+    "typings",
+    "**/__test__",
+    "test",
+    "docs",
+    "tests"
+  ]
+}

+ 10 - 0
typings.d.ts

@@ -0,0 +1,10 @@
+declare module '*.css';
+declare module '*.less';
+declare module '*.png';
+declare module '*.svg' {
+  export function ReactComponent(
+    props: React.SVGProps<SVGSVGElement>,
+  ): React.ReactElement;
+  const url: string;
+  export default url;
+}