Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Feat vpn #68

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 4 additions & 13 deletions app/web/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,12 @@ import 'ant-design-dtinsight-theme/theme/dt-theme/index.less';
declare var window: any;

const App = () => {
const { changeLocalIp } = bindActionCreators(actions, useDispatch());
const hotJar = () => {
(function (h: any, o: any, t: any, j: any, a?: any, r?: any) {
h.hj = h.hj || function () { (h.hj.q = h.hj.q || []).push(arguments) };
h._hjSettings = { hjid: 2133522, hjsv: 6 };
a = o.getElementsByTagName('head')[0];
r = o.createElement('script'); r.async = 1;
r.src = t + h._hjSettings.hjid + j + h._hjSettings.hjsv;
a.appendChild(r);
})(window, document, 'https://static.hotjar.com/c/hotjar-', '.js?sv=');
}
const { fetchLocalIp } = bindActionCreators(actions, useDispatch());

useEffect(() => {
hotJar();
changeLocalIp();
fetchLocalIp();
}, [])

return (
<div style={{ height: '100%' }}>
<ConfigProvider locale={zhCN}>
Expand Down
118 changes: 108 additions & 10 deletions app/web/layouts/header/header.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
import React, { useState, useEffect } from 'react';
import { AppstoreOutlined, CloudOutlined, DesktopOutlined, TagOutlined, SettingOutlined, QuestionCircleOutlined } from '@ant-design/icons';
import { Layout, Menu } from 'antd';
import { AppstoreOutlined, CloudOutlined, DesktopOutlined, TagOutlined, SettingOutlined, QuestionCircleOutlined, EditOutlined } from '@ant-design/icons';
import { Form, Layout, Menu, Modal, FormInstance, Input, Tooltip, Popconfirm } from 'antd';
import { SyncOutlined } from '@ant-design/icons';
import { Link } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as actions from '@/store/actions';
import { API } from '@/api';
import logo from '@/asset/images/logo.png';
import config from '../../../../env.json';
import './style.scss';

const { SubMenu } = Menu;

const { Header } = Layout;

const formItemLayout: any = {
labelCol: {
span: 5
},
wrapperCol: {
span: 18
}
};

const navMenuList: any = [{
name: '应用中心',
path: '/page/toolbox',
Expand All @@ -40,19 +49,58 @@ const navMenuList: any = [{
icon: <TagOutlined />,
routers: ['tags']
}]

const HeaderComponent = (props: any) => {
const { location } = props;
const { location, proxyServer } = props;
const { localIp = '127.0.0.1' } = useSelector((state: any) => state.global);
const { pathname } = location;
const [selectedKeys, setSelectedKeys] = useState([pathname]);
const { changeLocalIp } = bindActionCreators(actions, useDispatch());
const handleSelectedKeys = (e: any) => {
setSelectedKeys(e.key);
}
const [visible, setVisible] = useState<boolean>(false);
const [popconfirmOpen, setPopconfirmOpen] = useState<boolean>(false);
const { setLocalIp } = bindActionCreators(actions, useDispatch());
let formRef: FormInstance<any> = null;

useEffect(() => {
let current = navMenuList.filter(item => item.routers.some((ele) => pathname.indexOf(ele) > -1))
current.length && setSelectedKeys([current[0].path])
}, [pathname])
// 检测是否通过 VPN 访问哆啦A梦
useEffect(() => {
checkIsVPN();
}, [localIp]);

const handleSelectedKeys = (e: any) => {
setSelectedKeys(e.key);
}

// 刷新获取真实IP
const handleGetRealIp = () => {
API.getLocalIp().then((response: any) => {
const { success, data } = response;
if (success) {
formRef.setFieldsValue({ localIp: data.localIp });
// 记录真实IP
localStorage.setItem('real-localIp', data.localIp);
}
})
}

const handleModalOk = () => {
formRef.validateFields().then((values: any) => {
setLocalIp(values.localIp);
setVisible(false);
});
}

// 检测当前本地IP是否为 VPN 服务器的IP,是则代表通过 VPN 使用哆啦A梦代理,提示右上角可以进行设置自定义本地IP
const checkIsVPN = () => {
const vpnIp = config.vpnIp || [];
const tipTime = Number(localStorage.getItem('vpnIp-tip-time') || '');
console.log(111, Date.now() - tipTime - 24 * 60 * 60)
if ((Date.now() - tipTime - 24 * 60 * 60) > 0) {
setPopconfirmOpen(vpnIp.includes(localIp))
}
}

return (
<Header className="dt-layout-header header_component">
Expand Down Expand Up @@ -85,10 +133,60 @@ const HeaderComponent = (props: any) => {
</a>
<span className="local-ip ml-20">{`本机IP: ${localIp}`}</span>

{/* 主动更新本地IP */}
<SyncOutlined className='refresh-cion' onClick={() => changeLocalIp(true)} />
{/* 自定义本地IP */}
<Popconfirm
visible={popconfirmOpen}
placement="bottomRight"
title="检测到您当前是通过 VPN 访问哆啦A梦代理服务,可点击设置自定义本机IP"
onConfirm={() => {
setVisible(true);
setPopconfirmOpen(false);
// 关闭提示后记录时间
localStorage.setItem('vpnIp-tip-time', `${Date.now()}`);
}}
onCancel={() => {
setPopconfirmOpen(false);
// 关闭提示后记录时间
localStorage.setItem('vpnIp-tip-time', `${Date.now()}`);
}}
>
<EditOutlined className='refresh-cion' onClick={() => {
!popconfirmOpen && setVisible(true);
}} />
</Popconfirm>
</div>
</div>

<Modal
title="自定义本机IP"
visible={visible}
onOk={handleModalOk}
className="proxy-rule-modal"
onCancel={() => { setVisible(false) }}
>
<Form
{...formItemLayout}
ref={(form) => formRef = form}
initialValues={{
localIp: proxyServer?.ip || localIp
}}
scrollToFirstError={true}
>
<Form.Item
label="本机IP"
name="localIp"
rules={[
{ required: true, message: '请输入本机IP' }
]}
>
<Input placeholder="请输入本机IP" addonAfter={
<Tooltip placement="bottom" title="获取真实IP">
<SyncOutlined className='refresh-cion' onClick={handleGetRealIp} />
</Tooltip>
} />
</Form.Item>
</Form>
</Modal>
</Header>
);
}
Expand Down
37 changes: 6 additions & 31 deletions app/web/pages/proxyServer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { Input, Button, Typography, Tag, Table, message as Message, Divider, Mod
import { API } from '@/api';
import ProxyServerModal from './components/proxyServerModal';
import ProxyRuleModal from './components/proxyRuleModal';
import Cookies from 'js-cookie';
import { connect } from 'react-redux'
import helpIcon from '@/asset/images/help-icon.png';
import config from '../../../../env.json';
Expand All @@ -17,8 +16,6 @@ const { Paragraph } = Typography;

class ProxyServer extends React.PureComponent<any, any> {
state: any = {
//代理服务
localIp: '',
currentProxyServer: {},
proxyServerModalVisible: false,
proxyServerModalConfirmLoading: false,
Expand Down Expand Up @@ -61,8 +58,8 @@ class ProxyServer extends React.PureComponent<any, any> {
loadMainData = () => {
this.getProxyServerList()
this.getCollectTagList()
this.getLocalIp()
}

getCollectTagList = () => {
let collectTagList = []
try {
Expand All @@ -73,29 +70,6 @@ class ProxyServer extends React.PureComponent<any, any> {
}
this.setState({ collectTagList })
}
getLocalIp = () => {
API.getLocalIp().then((response: any) => {
const { success, data, message } = response;
if (success) {
const localIp = data.localIp;
const rememberIp = Cookies.get('rememberIp') || ''
if (rememberIp && rememberIp !== localIp) {
notification.warning({
message: 'IP地址变更',
description: '您的IP地址【较上次登录时】已发生变更、请留意代理服务配置!',
duration: 30,
onClose: () => {
Cookies.set('rememberIp', localIp)
}
});
}

this.setState({
localIp
})
}
})
}
getProxyServerList = (checked?: boolean) => {
const { mainTableParams, collectTagList } = this.state;
this.setState({
Expand Down Expand Up @@ -135,7 +109,7 @@ class ProxyServer extends React.PureComponent<any, any> {
}
//获取子表格数据
loadSubTableData(row: any) {
const { localIp } = this.state;
const { localIp } = this.props;
const { id } = row;
const allIPChecked = localStorage.getItem(`${ localIp }-${ id }-all-ip-checked`) !== 'no'
this.setState({
Expand Down Expand Up @@ -438,7 +412,8 @@ class ProxyServer extends React.PureComponent<any, any> {
localStorage.setItem('collection-tags', JSON.stringify(newList));
};
tableExpandedRowRender = (mainTableRow: any) => {
const { subTableLoading, subTableData, localIp, allIPChecked } = this.state;
const { subTableLoading, subTableData, allIPChecked } = this.state;
const { localIp } = this.props;
const columns: any = [{
title: '序号',
key: 'index',
Expand Down Expand Up @@ -530,7 +505,7 @@ class ProxyServer extends React.PureComponent<any, any> {

// 只看我的 IP (false)或者全部(true)
handleIPFilter = (allIPChecked, mainTableRow) => {
const { localIp } = this.state;
const { localIp } = this.props;
localStorage.setItem(`${ localIp }-${ mainTableRow.id }-all-ip-checked`, allIPChecked ? 'yes' : 'no')
Message.success(`${ allIPChecked ? '查看全部' : '只看我的IP' }`)
this.setState({
Expand All @@ -549,8 +524,8 @@ class ProxyServer extends React.PureComponent<any, any> {
})
}
render() {
const { localIp } = this.props;
const {
localIp,
maintTableList,
mainTableParams,
maintTableTotal,
Expand Down
53 changes: 40 additions & 13 deletions app/web/store/actions.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,45 @@
import { message } from 'antd';
import { CHANGE_LOCAL_IP } from './constant';
import { handleLocalIpChanged } from '@/utils/localIp';
import config from '../../../env.json'

export const changeLocalIp = (showMsg = false) => (dispatch: any, getState: any, { API }: any) => {
API.getLocalIp().then((response: any) => {
const { success, data } = response;
if (success) {
console.log(data);
showMsg && message.success('刷新成功!')
// 从接口获取本机IP
export const fetchLocalIp = () => (dispatch: any, getState: any, { API }: any) => {
// 本地没有 localIp 再从接口获取
const localIp = localStorage.getItem('localIp');
if (localIp) {
dispatch({
type: CHANGE_LOCAL_IP,
payload: data
type: 'CHANGE_LOCAL_IP',
payload: {
host: `${localIp}:7001`,
localIp,
protocol: 'http'
}
})
handleLocalIpChanged(localIp);
} else {
API.getLocalIp().then((response: any) => {
const { success, data } = response;
if (success) {
dispatch({
type: 'CHANGE_LOCAL_IP',
payload: data
})
handleLocalIpChanged(data.localIp);
// 记录真实IP
localStorage.setItem('real-localIp', localIp);
}
});
}
}).catch(() => {
showMsg && message.warning('刷新失败!')
});
}

// 自定义本机IP
export const setLocalIp = (localIp) => (dispatch: any) => {
dispatch({
type: 'CHANGE_LOCAL_IP',
payload: {
host: `${localIp}:7001`,
localIp,
protocol: 'http'
}
})
handleLocalIpChanged(localIp);
}
1 change: 0 additions & 1 deletion app/web/store/constant.ts

This file was deleted.

4 changes: 2 additions & 2 deletions app/web/store/reducer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { CHANGE_LOCAL_IP } from './constant';
const initialState: any = {
localIp: '',
serverInfo: {
Expand All @@ -9,8 +8,9 @@ const initialState: any = {
export default (state = initialState, action: any) => {
const { type, payload } = action;
switch (type) {
case CHANGE_LOCAL_IP:
case 'CHANGE_LOCAL_IP':
const { localIp, protocol, host } = payload;
localStorage.setItem('localIp', localIp);
return {
...state,
localIp,
Expand Down
16 changes: 16 additions & 0 deletions app/web/utils/localIp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { notification } from 'antd';

// 本机IP发生变化进行提示
export const handleLocalIpChanged = (localIp) => {
const rememberIp = localStorage.getItem('rememberIp');
if (rememberIp !== null && rememberIp !== localIp) {
notification.warning({
message: 'IP地址变更',
description: '您的IP地址【较上次访问时】已发生变更,请留意代理服务配置!',
duration: 5,
onClose: () => {
localStorage.setItem('rememberIp', localIp)
}
});
}
}
13 changes: 13 additions & 0 deletions docs/docsify/zh-cn/configuration/envConfig.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,16 @@ dingBot 的通知模板的跳转路径,默认跳转到帮助文档,可自行
}
}
```

## vpnIp

- 类型:string[]
- 默认值:[]

使用公司内部 VPN 时,本地地址会变成 VPN 的机器地址

```json
{
"vpnIp": ["127.0.0.1"]
}
```
3 changes: 2 additions & 1 deletion env.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
"proxyHelpDocUrl": "https://dtstack.github.io/doraemon/docsify/#/zh-cn/guide/%E4%BB%A3%E7%90%86%E6%9C%8D%E5%8A%A1",
"mysql": {
"prod": {}
}
},
"vpnIp": []
}