2025-06-13 19:18:28 +08:00

352 lines
13 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* @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);