diff --git a/code/web/client/assets/color.less b/code/web/client/assets/color.less index 6ddc7cb..5f56f53 100644 --- a/code/web/client/assets/color.less +++ b/code/web/client/assets/color.less @@ -1147,10 +1147,10 @@ tr > .ant-picker-cell-in-view.ant-picker-cell-range-hover-start:last-child::afte .ant-mentions-dropdown-menu-item-active {background-color: @item-hover-bg;} .ant-menu-item-danger.ant-menu-item {color: #ff4d4f;} .ant-menu-item-danger.ant-menu-item:hover, .ant-menu-item-danger.ant-menu-item-active {color: #ff4d4f;} -.ant-menu-item-danger.ant-menu-item:active {background: color(~`colorPalette("@{calendar-input-bg}", 1)`);} +.ant-menu-item-danger.ant-menu-item:active {background: #fff1f0;} .ant-menu-item-danger.ant-menu-item-selected {color: #ff4d4f;} .ant-menu-item-danger.ant-menu-item-selected > a, .ant-menu-item-danger.ant-menu-item-selected > a:hover {color: #ff4d4f;} -.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-danger.ant-menu-item-selected {background-color: color(~`colorPalette("@{calendar-input-bg}", 1)`);} +.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-danger.ant-menu-item-selected {background-color: #fff1f0;} .ant-menu-inline .ant-menu-item-danger.ant-menu-item::after {border-right-color: #ff4d4f;} .ant-menu-dark .ant-menu-item-danger.ant-menu-item, .ant-menu-dark .ant-menu-item-danger.ant-menu-item:hover, .ant-menu-dark .ant-menu-item-danger.ant-menu-item > a {color: #ff4d4f;} .ant-menu-dark.ant-menu-dark:not(.ant-menu-horizontal) .ant-menu-item-danger.ant-menu-item-selected {color: #fff;background-color: #ff4d4f;} @@ -1727,15 +1727,15 @@ tr.ant-table-expanded-row:hover > td {background: @table-expanded-row-bg;} .ant-tag-checkable:active, .ant-tag-checkable-checked {color: #fff;} .ant-tag-checkable-checked {background-color: @primary-color;} .ant-tag-checkable:active {background-color: color(~`colorPalette("@{primary-color}", 7)`);} -.ant-tag-pink {color: #c41d7f;background: color(~`colorPalette("@{table-header-cell-split-color}", 4)`);border-color: #ffadd2;} +.ant-tag-pink {color: #c41d7f;background: color(~`colorPalette("@{alert-warning-border-color}", 1)`);border-color: #ffadd2;} .ant-tag-pink-inverse {color: #fff;background: #eb2f96;border-color: #eb2f96;} -.ant-tag-magenta {color: #c41d7f;background: color(~`colorPalette("@{table-header-cell-split-color}", 4)`);border-color: #ffadd2;} +.ant-tag-magenta {color: #c41d7f;background: color(~`colorPalette("@{alert-warning-border-color}", 1)`);border-color: #ffadd2;} .ant-tag-magenta-inverse {color: #fff;background: #eb2f96;border-color: #eb2f96;} -.ant-tag-red {color: #cf1322;background: color(~`colorPalette("@{calendar-input-bg}", 1)`);border-color: #ffa39e;} +.ant-tag-red {color: #cf1322;background: #fff1f0;border-color: #ffa39e;} .ant-tag-red-inverse {color: #fff;background: #f5222d;border-color: #f5222d;} .ant-tag-volcano {color: #d4380d;background: #fff2e8;border-color: #ffbb96;} .ant-tag-volcano-inverse {color: #fff;background: #fa541c;border-color: #fa541c;} -.ant-tag-orange {color: #d46b08;background: #fff7e6;border-color: #ffd591;} +.ant-tag-orange {color: #d46b08;background: color(~`colorPalette("@{shadow-color}", 1)`);border-color: #ffd591;} .ant-tag-orange-inverse {color: #fff;background: #fa8c16;border-color: #fa8c16;} .ant-tag-yellow {color: #d4b106;background: #feffe6;border-color: #fffb8f;} .ant-tag-yellow-inverse {color: #fff;background: #fadb14;border-color: #fadb14;} @@ -1743,15 +1743,15 @@ tr.ant-table-expanded-row:hover > td {background: @table-expanded-row-bg;} .ant-tag-gold-inverse {color: #fff;background: #faad14;border-color: #faad14;} .ant-tag-cyan {color: #08979c;background: #e6fffb;border-color: #87e8de;} .ant-tag-cyan-inverse {color: #fff;background: #13c2c2;border-color: #13c2c2;} -.ant-tag-lime {color: #7cb305;background: #fcffe6;border-color: #eaff8f;} +.ant-tag-lime {color: #7cb305;background: color(~`colorPalette("@{dropdown-menu-submenu-disabled-bg}", 1)`);border-color: #eaff8f;} .ant-tag-lime-inverse {color: #fff;background: #a0d911;border-color: #a0d911;} .ant-tag-green {color: #389e0d;background: #f6ffed;border-color: #b7eb8f;} .ant-tag-green-inverse {color: #fff;background: #52c41a;border-color: #52c41a;} .ant-tag-blue {color: #096dd9;background: color(~`colorPalette("@{transfer-item-hover-bg}", 1)`);border-color: #91d5ff;} .ant-tag-blue-inverse {color: #fff;background: #1890ff;border-color: #1890ff;} -.ant-tag-geekblue {color: #1d39c4;background: #f0f5ff;border-color: #adc6ff;} +.ant-tag-geekblue {color: #1d39c4;background: color(~`colorPalette("@{badge-text-color}", 1)`);border-color: #adc6ff;} .ant-tag-geekblue-inverse {color: #fff;background: #2f54eb;border-color: #2f54eb;} -.ant-tag-purple {color: #531dab;background: #f9f0ff;border-color: #d3adf7;} +.ant-tag-purple {color: #531dab;background: color(~`colorPalette("@{table-header-sort-bg}", 2)`);border-color: #d3adf7;} .ant-tag-purple-inverse {color: #fff;background: #722ed1;border-color: #722ed1;} .ant-tag-success {color: #52c41a;background: @success-color-deprecated-bg;border-color: @success-color-deprecated-border;} .ant-tag-processing {color: @primary-color;background: @info-color-deprecated-bg;border-color: @info-color-deprecated-border;} diff --git a/code/web/client/src/app.js b/code/web/client/src/app.js index d5d17ca..844a85a 100644 --- a/code/web/client/src/app.js +++ b/code/web/client/src/app.js @@ -3,6 +3,7 @@ import React, { useEffect } from 'react'; import Layout from './layout'; import Auth from './sections/auth'; +import Gateway from './sections/gateway'; import Search from './sections/search'; const App = props => { @@ -15,7 +16,7 @@ const App = props => { return ( ) } diff --git a/code/web/client/src/index.js b/code/web/client/src/index.js index ddcd05a..c6ccf44 100644 --- a/code/web/client/src/index.js +++ b/code/web/client/src/index.js @@ -4,4 +4,4 @@ import React from 'react'; import { render } from 'react-dom'; import App from './app'; -render((), document.getElementById('App')); \ No newline at end of file +render((), document.getElementById('App')); \ No newline at end of file diff --git a/code/web/client/src/layout/components/header/index.js b/code/web/client/src/layout/components/header/index.js index e666f10..13856ff 100644 --- a/code/web/client/src/layout/components/header/index.js +++ b/code/web/client/src/layout/components/header/index.js @@ -8,7 +8,7 @@ import lightVars from '$themes/light.json'; import exampleVars from '$themes/example.json' import styles from './style.css'; import { - MenuFoldOutlined, MenuUnfoldOutlined, UserOutlined, LogoutOutlined,SmileOutlined + MenuFoldOutlined, MenuUnfoldOutlined, UserOutlined, LogoutOutlined, SmileOutlined,ApartmentOutlined } from '@ant-design/icons'; const themeMap = { @@ -61,7 +61,7 @@ const Header = props => {
- 安心云4.0 + DevOps {/* {user.orgName} */}
@@ -72,6 +72,11 @@ const Header = props => { selectedKeys={[current]} style={{ border: 0 }} onClick={handelClick} > + 运维工具} > + } > + 网关配置 + + 主题切换} > 亮色风格 diff --git a/code/web/client/src/layout/containers/no-match/index.js b/code/web/client/src/layout/containers/no-match/index.js index c0437a5..59b81ea 100644 --- a/code/web/client/src/layout/containers/no-match/index.js +++ b/code/web/client/src/layout/containers/no-match/index.js @@ -4,6 +4,7 @@ import React from 'react'; import moment from 'moment' const NoMatch = props => { + console.log("404") return (

404

diff --git a/code/web/client/src/layout/index.js b/code/web/client/src/layout/index.js index ba1db6b..8cada45 100644 --- a/code/web/client/src/layout/index.js +++ b/code/web/client/src/layout/index.js @@ -60,6 +60,10 @@ const Root = props => { } flat(routes); + combineRoutes.push({ + key: "nomatch", + component: NoMatch + }) return combineRoutes; } @@ -90,7 +94,7 @@ const Root = props => { let actions = { layout: layoutActions } - + for (let s of sections) { if (!s.key) console.warn('请给你的section添加一个key值,section name:' + s.name); for (let r of s.routes) { @@ -147,6 +151,9 @@ const Root = props => { component={route.component} /> ))) + + console.log(combineRoutes) + console.log(outerRoutes) }, []) return ( @@ -161,12 +168,10 @@ const Root = props => { history={history} routes={innnerRoutes} > - {combineRoutes} + + {combineRoutes} + -
diff --git a/code/web/client/src/sections/auth/containers/login.js b/code/web/client/src/sections/auth/containers/login.js index bfcc85c..dc048cd 100644 --- a/code/web/client/src/sections/auth/containers/login.js +++ b/code/web/client/src/sections/auth/containers/login.js @@ -27,7 +27,7 @@ const Login = props => { useEffect(() => { if (user && user.authorized) { - dispatch(push('/search')); + dispatch(push('/')); } }, [user]) @@ -56,7 +56,7 @@ const Login = props => { height: 410, padding: 30, }}> -

安心云 4.0

+

DevOps

用户名
diff --git a/code/web/client/src/sections/gateway/actions/gateway.js b/code/web/client/src/sections/gateway/actions/gateway.js new file mode 100644 index 0000000..e38120e --- /dev/null +++ b/code/web/client/src/sections/gateway/actions/gateway.js @@ -0,0 +1,48 @@ +'use strict'; + +import { basicAction } from '@peace/utils' +import { ApiTable } from '$utils' + +export function list(query) { + return dispatch => basicAction({ + type: 'get', + dispatch: dispatch, + query: query, + actionType: 'GET_GATEWAY_LIST', + url: ApiTable.getGateways, + msg: { error: '获取网关配置列表失败' }, + reducer: { name: 'gateways' } + }) +} + +export function add(data) { + return dispatch => basicAction({ + type: 'post', + dispatch: dispatch, + data: data, + actionType: 'POST_GATEWAY_CONFIG', + url: ApiTable.addGatewayConfig, + msg: { option: '添加网关配置' } + }) +} + +export function edit(data, gatewayId) { + return dispatch => basicAction({ + type: 'put', + dispatch: dispatch, + data: data, + actionType: 'EDIT_GATEWAY_CONFIG', + url: `${ApiTable.editGatewayConfig.replace('{gatewayId}', gatewayId)}`, + msg: { option: '编辑网关配置' } + }) +} + +export function del(gatewayId) { + return dispatch => basicAction({ + type: 'del', + dispatch: dispatch, + actionType: 'DEL_GATEWAY_CONFIG', + url: ApiTable.delGatewayConfig.replace('{gatewayId}', gatewayId), + msg: { option: '删除网关配置' } + }) +} \ No newline at end of file diff --git a/code/web/client/src/sections/gateway/actions/index.js b/code/web/client/src/sections/gateway/actions/index.js new file mode 100644 index 0000000..885c2d4 --- /dev/null +++ b/code/web/client/src/sections/gateway/actions/index.js @@ -0,0 +1,7 @@ +'use strict'; + +import * as gateway from './gateway' + +export default { + ...gateway +} \ No newline at end of file diff --git a/code/web/client/src/sections/gateway/containers/ConfigModal.js b/code/web/client/src/sections/gateway/containers/ConfigModal.js new file mode 100644 index 0000000..faec21c --- /dev/null +++ b/code/web/client/src/sections/gateway/containers/ConfigModal.js @@ -0,0 +1,86 @@ +import React, { useEffect, useRef } from 'react'; +import { connect } from 'react-redux'; +import { Spin, Button, Modal, Form, Switch } from 'antd'; +import ProForm, { ProFormText, ProFormSelect, ProFormDateTimePicker } from '@ant-design/pro-form'; +import { useState } from 'react'; + +const ConfigModal = (props) => { + const { dispatch, actions, visible, close, editData, types, catalogs } = props + const formRef = useRef() + const { gateway } = actions + + return { + formRef.current.validateFields() + .then(v => { + dispatch(editData ? gateway.edit(v, editData.id) : gateway.add(v)) + .then(res => { + if (res.success) { + dispatch(gateway.list()) + close() + } + }) + }) + }} + onCancel={() => { + close() + }} + > + + + + + + + +} + +function mapStateToProps(state) { + const { auth, global, } = state; + return { + user: auth.user, + actions: global.actions + }; +} + +export default connect(mapStateToProps)(ConfigModal); diff --git a/code/web/client/src/sections/gateway/containers/Gateway.js b/code/web/client/src/sections/gateway/containers/Gateway.js new file mode 100644 index 0000000..9f8212e --- /dev/null +++ b/code/web/client/src/sections/gateway/containers/Gateway.js @@ -0,0 +1,135 @@ +import React, { useState,useEffect,useRef } from 'react'; +import { connect } from 'react-redux'; +import { Spin,Button, Card, Input } from 'antd'; +import '../style.less'; +import { push } from 'react-router-redux' +import ProTable, { TableDropdown } from '@ant-design/pro-table'; + +const GatewayMode = ["tcp", "udp", "mqtt", "http", "dtu"] +const InMode = GatewayMode +const OutMode = GatewayMode +const ProtocolTypes = ["DeviceA", "DeviceB", "DeviceC", "DeviceD"] + + + +const Gateway = (props) => { + const { dispatch, actions, user, loading, gateways } = props + + const { gateway } = actions; + const [configModalVis, setConfigModalVis] = useState(false) + const [editData, setEditData] = useState(null) + + + useEffect(() => { + // dispatch(task.getTaskList()) + }, []) + + const actionRef = useRef(); + const columns = [ + { + dataIndex: 'id', + valueType: 'indexBorder', + width: 48, + }, { + title: '名称', + dataIndex: 'name', + ellipsis: true + }, + { + title: '输入模式', + dataIndex: 'in_mode', + filters: true, + onFilter: true, + valueType: 'select', + valueEnum: InMode, + }, + { + title: '输出模式', + dataIndex: 'out_mode', + filters: true, + onFilter: true, + valueType: 'select', + valueEnum: OutMode, + }, { + title: '输入配置', + dataIndex: 'in_config' + }, { + title: '输出配置', + dataIndex: 'out_config' + }, { + title: '协议', + dataIndex: 'protocol', + valueType: 'select', + valueEnum: ProtocolTypes + }, { + title: '协议信息', + dataIndex: 'protocol_info' + }, { + title: '操作', + valueType: 'option', + key: 'option', + render: (txt, row, _, action) => [ + + ], + } + ] + + return ( + + { + const query = { + limit: params.pageSize, + offset: params.pageSize * (params.current - 1) + } + const res = await dispatch(gateway.list(query)); + return { + ...res, + total: res.payload.data ? res.payload.data.count : 0 + } + }} + options={false} + toolBarRender={() => [ + , + ]} + > + + + { + configModalVis ? + { + setConfigModalVis(false) + setEditData(null) + }} + editData={editData} + /> : '' + } + + ) +} + +function mapStateToProps(state) { + const { auth, global } = state; + return { + user: auth.user, + actions: global.actions + }; +} + +export default connect(mapStateToProps)(Gateway); diff --git a/code/web/client/src/sections/gateway/containers/index.js b/code/web/client/src/sections/gateway/containers/index.js new file mode 100644 index 0000000..78f2b4a --- /dev/null +++ b/code/web/client/src/sections/gateway/containers/index.js @@ -0,0 +1,5 @@ +'use strict'; + +import Gateway from './Gateway'; + +export { Gateway }; \ No newline at end of file diff --git a/code/web/client/src/sections/gateway/index.js b/code/web/client/src/sections/gateway/index.js new file mode 100644 index 0000000..de236be --- /dev/null +++ b/code/web/client/src/sections/gateway/index.js @@ -0,0 +1,15 @@ +'use strict'; + +import reducers from './reducers'; +import routes from './routes'; +import actions from './actions'; +import { getNavItem } from './nav-item'; + +export default { + key: 'gateway', + name: '网关配置', + reducers: reducers, + routes: routes, + actions: actions, + getNavItem: getNavItem +}; \ No newline at end of file diff --git a/code/web/client/src/sections/gateway/nav-item.js b/code/web/client/src/sections/gateway/nav-item.js new file mode 100644 index 0000000..ffac98a --- /dev/null +++ b/code/web/client/src/sections/gateway/nav-item.js @@ -0,0 +1,16 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; +import { Menu } from 'antd'; +import { SettingOutlined } from '@ant-design/icons'; + +const SubMenu = Menu.SubMenu; + +export function getNavItem(user, dispatch) { + return ( + } title={'网关配置'}> + + 配置清单 + + + ); +} \ No newline at end of file diff --git a/code/web/client/src/sections/gateway/reducers/index.js b/code/web/client/src/sections/gateway/reducers/index.js new file mode 100644 index 0000000..7ed1088 --- /dev/null +++ b/code/web/client/src/sections/gateway/reducers/index.js @@ -0,0 +1,5 @@ +'use strict'; + +export default { + +} \ No newline at end of file diff --git a/code/web/client/src/sections/gateway/routes.js b/code/web/client/src/sections/gateway/routes.js new file mode 100644 index 0000000..6989c7c --- /dev/null +++ b/code/web/client/src/sections/gateway/routes.js @@ -0,0 +1,12 @@ +'use strict'; +import { Gateway} from './containers'; + +export default [{ + type: 'inner', + route: { + path: '/gateway_profile', + key: 'gateway', + breadcrumb: '网关配置', + component: Gateway + } +}]; \ No newline at end of file diff --git a/code/web/client/src/sections/gateway/style.less b/code/web/client/src/sections/gateway/style.less new file mode 100644 index 0000000..3323452 --- /dev/null +++ b/code/web/client/src/sections/gateway/style.less @@ -0,0 +1,3 @@ +#example:hover { + font-size: larger; +} \ No newline at end of file diff --git a/code/web/client/src/sections/search/containers/search.js b/code/web/client/src/sections/search/containers/search.js index 6cbe327..293c998 100644 --- a/code/web/client/src/sections/search/containers/search.js +++ b/code/web/client/src/sections/search/containers/search.js @@ -26,6 +26,9 @@ const Search = (props) => { return (
+ {/* + + */} {toplogo} { } > {getHighlightedText(item.title, keyword)}} + title={
} description={item.ext?.desc ? item.ext.desc : undefined} // description={item.content} /> - {getHighlightedText(item.content, keyword)} +
)} /> : diff --git a/code/web/client/src/sections/search/containers/toplogo.js b/code/web/client/src/sections/search/containers/toplogo.js index ec91a6e..af7c22d 100644 --- a/code/web/client/src/sections/search/containers/toplogo.js +++ b/code/web/client/src/sections/search/containers/toplogo.js @@ -1,6 +1,6 @@ import React, { useEffect } from 'react'; export default ( - + ) \ No newline at end of file diff --git a/code/web/client/src/sections/search/style.less b/code/web/client/src/sections/search/style.less index fee7fdd..0b58e61 100644 --- a/code/web/client/src/sections/search/style.less +++ b/code/web/client/src/sections/search/style.less @@ -16,6 +16,12 @@ // justify-content: center; justify-content: flex-start; align-items: center; + + vertical-align:top; + } + + .svgblock{ + vertical-align:top; } .parent-top{ diff --git a/code/web/client/src/utils/webapi.js b/code/web/client/src/utils/webapi.js index 4fb4175..75a17b7 100644 --- a/code/web/client/src/utils/webapi.js +++ b/code/web/client/src/utils/webapi.js @@ -2,11 +2,20 @@ import request from 'superagent'; export const ApiTable = { - login: 'login', - logout: 'logout', + login: 'v1/login', + logout: 'v1/logout', search: 'v1/search/{wd}', + search: 'v1/search/{wd}', + + //网关配置 + getGateways: 'gateway/list', + addGatewayConfig: 'gateway', + getGatewayConfig: 'gateway/{gatewayId}', + editGatewayConfig: 'gateway/{gatewayId}', + delGatewayConfig: 'gateway/{gatewayId}', + getEnterprisesMembers: 'enterprises/{enterpriseId}/members', }; diff --git a/code/web/node_modules.rar b/code/web/node_modules.rar deleted file mode 100644 index 981d157..0000000 Binary files a/code/web/node_modules.rar and /dev/null differ