352 lines
13 KiB
TypeScript
352 lines
13 KiB
TypeScript
/*
|
||
* @Author: cclu
|
||
* @Date: 2022-04-28 17:16:50
|
||
* @LastEditTime: 2025-03-25 15:41:46
|
||
* @LastEditors: cclu 1106109051@qq.com
|
||
* @Description: 登录 页面
|
||
* @FilePath: \cloud-platform\src\pages\User\login\index.tsx
|
||
*/
|
||
import {
|
||
LockFilled,
|
||
UserOutlined
|
||
} from '@ant-design/icons';
|
||
import { Alert, Col, Divider, Row, Space, Typography } from 'antd';
|
||
import React, { useEffect, useState } from 'react';
|
||
import { LoginForm, ProFormText } from '@ant-design/pro-form';
|
||
import { useIntl, connect, Link } from 'umi';
|
||
|
||
import type { Dispatch } from 'umi';
|
||
import type { StateType } from '@/models/login';
|
||
import type { LoginParamsType } from '@/services/login';
|
||
import type { ConnectState } from '@/models/connect';
|
||
import loginBg from '@/assets/login-bg.png';
|
||
import styles from './index.less';
|
||
import { line } from '@antv/g2plot';
|
||
import session from '@/utils/session';
|
||
|
||
// 可接受的页面参数
|
||
export type LoginProps = {
|
||
dispatch: Dispatch;
|
||
userLogin: StateType;
|
||
submitting?: boolean;
|
||
};
|
||
|
||
const LoginMessage: React.FC<{
|
||
content: string;
|
||
}> = ({ content }) => (
|
||
<Alert
|
||
style={{
|
||
marginBottom: 24,
|
||
}}
|
||
message={content}
|
||
type="error"
|
||
showIcon
|
||
/>
|
||
);
|
||
/**
|
||
* @description: 登录页面
|
||
* @param {*} dispatch 接收的组件参数
|
||
* @param {*} userLogin 接收的组件参数
|
||
* @param {*} submitting 是否在提交
|
||
* @return {*}
|
||
*/
|
||
const Login: React.FC<LoginProps> = (props) => {
|
||
const { userLogin = {}, submitting } = props;
|
||
const { status } = userLogin;
|
||
const intl = useIntl();
|
||
|
||
// ip 位置等信息
|
||
const [baseInfo, setBaseInfo] = useState<any>()
|
||
// 浏览器信息
|
||
const [browser, setBrowser] = useState<any>()
|
||
// 系统信息
|
||
const [systemInfo, setSystemInfo] = useState<any>()
|
||
|
||
const handleSubmit = (values: any) => {
|
||
const { dispatch } = props;
|
||
dispatch({
|
||
type: 'login/login',
|
||
payload: { ...values },
|
||
});
|
||
};
|
||
|
||
function findIP(onNewIP) {
|
||
const peerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
|
||
const pc = new peerConnection({ iceServers: [] });
|
||
const noop = function () { };
|
||
const IPRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3})/;
|
||
const ipCandidates = [];
|
||
pc.createDataChannel("");
|
||
pc.createOffer().then(function (sdp) {
|
||
sdp.sdp.split('\n').forEach(function (line) {
|
||
if (line.indexOf('candidate') < 0) return;
|
||
line.match(IPRegex).forEach(function (ip) {
|
||
if (ipCandidates.indexOf(ip) < 0) onNewIP(ip);
|
||
ipCandidates.push(ip);
|
||
});
|
||
});
|
||
pc.setLocalDescription(sdp, noop, noop);
|
||
}).catch(function (reason) {
|
||
});
|
||
pc.onicecandidate = function (ice) {
|
||
if (!ice || !ice.candidate || !ice.candidate.candidate || !ice.candidate.candidate.match(IPRegex)) return;
|
||
const myIP = /([0-9]{1,3}(\.[0-9]{1,3}){3})/.exec(ice.candidate.candidate)[1];
|
||
console.log('myIP', myIP);
|
||
onNewIP(myIP);
|
||
};
|
||
}
|
||
function successCallBack(req: any) {
|
||
}
|
||
|
||
useEffect(() => {
|
||
// 第三方 说是不安全
|
||
// fetch('https://api.ipify.org?format=json').then(response => response.json())
|
||
// .then(json => console.log(json.ip));
|
||
// 失敗的
|
||
// fetch('http://eshangtech.com/ShopICO/getIp.php', { method: 'GET', mode: 'cors' }).then(response => response.text())
|
||
// .then(data => {
|
||
// console.log('ip', data);
|
||
// });
|
||
|
||
// 沒成功的 可以继续尝试
|
||
// if (navigator.geolocation) {
|
||
// alert('请允许获取您的位置定位')
|
||
// console.log('22');
|
||
|
||
// navigator.geolocation.getCurrentPosition(successCallback, errorCallback)
|
||
// } else {
|
||
// alert('您的浏览器不支持定位功能')
|
||
// }
|
||
|
||
// 可以一条龙拿到的
|
||
fetch('https://qifu-api.baidubce.com/ip/local/geo/v1/district').then(response => response.text()).then(data => {
|
||
const obj: any = JSON.parse(data).data
|
||
const res = {
|
||
...obj,
|
||
ip: JSON.parse(data).ip
|
||
}
|
||
session.set('basicInfo', res);
|
||
setBaseInfo(res)
|
||
});
|
||
|
||
const browserVersion = getBrowserVersion();
|
||
session.set('browserVersion', browserVersion);
|
||
setBrowser(browserVersion)
|
||
const systemBasin = getOsInfo()
|
||
session.set('systemBasin', systemBasin);
|
||
setSystemInfo(systemBasin)
|
||
}, [])
|
||
|
||
function successCallback(position: { coords: { latitude: any; longitude: any; }; }) {
|
||
const latitude = position.coords.latitude;
|
||
const longitude = position.coords.longitude;
|
||
}
|
||
|
||
function errorCallback(error) {
|
||
}
|
||
|
||
|
||
function getBrowserVersion() {
|
||
const userAgent: string = navigator.userAgent;
|
||
let version: any = "";
|
||
// 判断是否为 Chrome 浏览器
|
||
if (/Chrome\/(\S+)/.test(userAgent)) {
|
||
version = userAgent.match(/Chrome\/(\S+)/);
|
||
}
|
||
// 判断是否为 Firefox 浏览器
|
||
else if (/Firefox\/(\S+)/.test(userAgent)) {
|
||
version = userAgent.match(/Firefox\/(\S+)/);
|
||
}
|
||
// 判断是否为 Safari 浏览器
|
||
else if (/Safari\/(\S+)/.test(userAgent)) {
|
||
version = userAgent.match(/Version\/(\S+)/);
|
||
}
|
||
// 判断是否为 Edge 浏览器
|
||
else if (/Edg\/(\S+)/.test(userAgent)) {
|
||
version = userAgent.match(/Edg\/(\S+)/);
|
||
}
|
||
// 判断是否为 Internet Explorer 浏览器
|
||
else if (/MSIE (\S+);/.test(userAgent)) {
|
||
version = userAgent.match(/MSIE (\S+);/);
|
||
}
|
||
|
||
return version[0];
|
||
}
|
||
|
||
// 获取操作系统 版本
|
||
const getOsInfo = () => {
|
||
const userAgent = navigator.userAgent.toLowerCase();
|
||
let name = "";
|
||
let version = "";
|
||
if (userAgent.indexOf("win") > -1) {
|
||
name = "Windows";
|
||
if (userAgent.indexOf("windows nt 5.0") > -1) {
|
||
version = "Windows 2000";
|
||
} else if (
|
||
userAgent.indexOf("windows nt 5.1") > -1 ||
|
||
userAgent.indexOf("windows nt 5.2") > -1
|
||
) {
|
||
version = "Windows XP";
|
||
} else if (userAgent.indexOf("windows nt 6.0") > -1) {
|
||
version = "Windows Vista";
|
||
} else if (
|
||
userAgent.indexOf("windows nt 6.1") > -1 ||
|
||
userAgent.indexOf("windows 7") > -1
|
||
) {
|
||
version = "Windows 7";
|
||
} else if (
|
||
userAgent.indexOf("windows nt 6.2") > -1 ||
|
||
userAgent.indexOf("windows 8") > -1
|
||
) {
|
||
version = "Windows 8";
|
||
} else if (userAgent.indexOf("windows nt 6.3") > -1) {
|
||
version = "Windows 8.1";
|
||
} else if (
|
||
userAgent.indexOf("windows nt 6.2") > -1 ||
|
||
userAgent.indexOf("windows nt 10.0") > -1
|
||
) {
|
||
version = "Windows 10";
|
||
} else {
|
||
version = "";
|
||
}
|
||
} else if (userAgent.indexOf("iphone") > -1) {
|
||
name = "Iphone";
|
||
} else if (userAgent.indexOf("mac") > -1) {
|
||
name = "Mac";
|
||
} else if (
|
||
userAgent.indexOf("x11") > -1 ||
|
||
userAgent.indexOf("unix") > -1 ||
|
||
userAgent.indexOf("sunname") > -1 ||
|
||
userAgent.indexOf("bsd") > -1
|
||
) {
|
||
name = "Unix";
|
||
} else if (userAgent.indexOf("linux") > -1) {
|
||
if (userAgent.indexOf("android") > -1) {
|
||
name = "Android";
|
||
} else {
|
||
name = "Linux";
|
||
}
|
||
} else {
|
||
name = "";
|
||
}
|
||
|
||
return version;
|
||
};
|
||
|
||
|
||
return (
|
||
<Row gutter={16} align="middle" style={{ margin: 0, height: '100%' }}>
|
||
<Col xl={12} lg={16} md={12}>
|
||
|
||
<div className={styles.top}>
|
||
<div className={styles.header}>
|
||
|
||
<div className={styles.title}>云上服务区商业Saas平台</div>
|
||
|
||
<div className={styles.desc}>服务区管理一站式解决方案</div>
|
||
</div>
|
||
<img src={loginBg} className={styles.loginbg} alt="" />
|
||
</div>
|
||
</Col>
|
||
<Col xl={12} lg={8} md={12}>
|
||
<div className={styles.main}>
|
||
<div className={styles.title}>平台账号登录</div>
|
||
<LoginForm
|
||
className={styles.form}
|
||
initialValues={{
|
||
autoLogin: true,
|
||
}}
|
||
submitter={{
|
||
searchConfig: {
|
||
submitText: '登录',
|
||
},
|
||
render: (_, dom) => dom.pop(),
|
||
submitButtonProps: {
|
||
loading: submitting,
|
||
size: 'large',
|
||
// danger: true,
|
||
style: {
|
||
width: '100%',
|
||
// background: '#E2364B',
|
||
marginTop: 0
|
||
},
|
||
},
|
||
}}
|
||
onFinish={(values) => {
|
||
handleSubmit({
|
||
...values,
|
||
LoginIP: baseInfo?.ip ? baseInfo?.ip : '',
|
||
LoginPlace: `${baseInfo?.prov ? baseInfo?.prov : ''}${baseInfo?.prov && baseInfo?.city ? '-' : ''}${baseInfo?.city ? baseInfo?.city : ''}`,
|
||
BrowserVersion: browser || '',
|
||
OperatingSystem: systemInfo || '',
|
||
});
|
||
return Promise.resolve();
|
||
}}
|
||
>
|
||
|
||
|
||
{status === 'error' && !submitting && (
|
||
<LoginMessage
|
||
content={intl.formatMessage({
|
||
id: 'pages.login.accountLogin.errorMessage',
|
||
defaultMessage: 'Incorrect account or password',
|
||
})}
|
||
/>
|
||
)}
|
||
|
||
|
||
<ProFormText
|
||
name="UserPassport"
|
||
|
||
fieldProps={{
|
||
size: 'large',
|
||
prefix: <UserOutlined className={styles.prefixIcon} />,
|
||
}}
|
||
placeholder='账号'
|
||
rules={[
|
||
{
|
||
required: true,
|
||
message: '请输入您的账号',
|
||
},
|
||
]}
|
||
/>
|
||
<ProFormText.Password
|
||
name="UserPassWord"
|
||
fieldProps={{
|
||
size: 'large',
|
||
prefix: <LockFilled className={styles.prefixIcon} />,
|
||
}}
|
||
placeholder='密码'
|
||
|
||
rules={[
|
||
{
|
||
required: true,
|
||
message: '请输入您的密码',
|
||
},
|
||
]}
|
||
/>
|
||
|
||
|
||
</LoginForm>
|
||
{/* <div style={{ textAlign: 'center', width: 328, margin: 'auto' }}>
|
||
<Space split>
|
||
<Link to="/user/register">商户注册</Link> | <Link to="/user/forgetPassword"><Typography.Text type="secondary" >忘记密码?</Typography.Text></Link>
|
||
</Space>
|
||
</div> */}
|
||
<div className={styles['form-bottom']}>
|
||
<Divider className={styles.divider}>温馨提示</Divider>
|
||
<p>
|
||
我们为您提供驿商云帐号服务,在登录过程中会使用到您的帐号和网络信息提 升登录体验。点击“登录”表示您同意以上内容。
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</Col>
|
||
</Row>
|
||
);
|
||
};
|
||
|
||
export default connect(({ login, loading }: ConnectState) => ({
|
||
userLogin: login,
|
||
submitting: loading.effects['login/login'],
|
||
}))(Login);
|