feat: react/mobile
This commit is contained in:
parent
9d6340c83e
commit
452b6bb803
53
.umirc.ts
53
.umirc.ts
@ -1,4 +1,5 @@
|
||||
import { defineConfig } from 'umi';
|
||||
import px2rem from 'postcss-px2rem';
|
||||
|
||||
export default defineConfig({
|
||||
favicon: '#',
|
||||
@ -7,53 +8,27 @@ export default defineConfig({
|
||||
immer: true,
|
||||
hmr: false,
|
||||
},
|
||||
publicPath: '/',
|
||||
webpack5: {},
|
||||
mfsu: {},
|
||||
dynamicImport: {
|
||||
loading: '@/components/PageLoading/index',
|
||||
},
|
||||
extraPostCSSPlugins: [px2rem({ remUnit: 66.7, exclude: /node_modules/i })],
|
||||
routes: [
|
||||
{
|
||||
path: '/window',
|
||||
component: '@/layouts/WindowLayout',
|
||||
routes: [
|
||||
{
|
||||
path: 'demo',
|
||||
component: '@/pages/index',
|
||||
name: '一级菜单',
|
||||
title: '一级菜单',
|
||||
icon: 'EntranceOutlined',
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
component: '@/layouts/BasicLayout',
|
||||
// wrappers: ['@/wrappers/SecurityLayout'],
|
||||
component: '@/layouts/BlankLayout',
|
||||
wrappers: ['@/wrappers/SecurityWrapper'],
|
||||
routes: [
|
||||
{ exact: true, path: '/', redirect: '/a' },
|
||||
// { exact: true, path: '/', redirect: '/home' },
|
||||
{
|
||||
path: 'a',
|
||||
path: '/',
|
||||
component: '@/pages/index',
|
||||
name: '一级菜单',
|
||||
title: '一级菜单',
|
||||
icon: 'EntranceOutlined',
|
||||
},
|
||||
{
|
||||
path: 'b',
|
||||
name: '一级菜单',
|
||||
title: '一级菜单',
|
||||
icon: 'EntranceOutlined',
|
||||
routes: [
|
||||
{ exact: true, path: '/b', redirect: '/b/c' },
|
||||
{
|
||||
path: 'c',
|
||||
component: '@/pages/index',
|
||||
name: '二级菜单',
|
||||
title: '二级菜单',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
@ -98,10 +73,20 @@ export default defineConfig({
|
||||
},
|
||||
locale: {
|
||||
default: 'zh-CN',
|
||||
antd: true,
|
||||
antd: false,
|
||||
},
|
||||
ignoreMomentLocale: true,
|
||||
targets: {
|
||||
ie: 10,
|
||||
}
|
||||
},
|
||||
extraBabelPlugins: [
|
||||
[
|
||||
'import',
|
||||
{
|
||||
libraryName: 'antd-mobile',
|
||||
libraryDirectory: 'es/components',
|
||||
style: false,
|
||||
},
|
||||
],
|
||||
],
|
||||
});
|
||||
|
12
package.json
12
package.json
@ -40,29 +40,37 @@
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^4.7.0",
|
||||
"@ant-design/pro-layout": "^6.15.4",
|
||||
"antd": "^4.20.6",
|
||||
"@nicecode/tools": "^0.2.12",
|
||||
"antd-mobile": "^5.12.6",
|
||||
"antd-mobile-icons": "^0.2.2",
|
||||
"axios": "^0.19.2",
|
||||
"classnames": "^2.2.6",
|
||||
"js-cookie": "^2.2.1",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"umi": "^3.5.15"
|
||||
"umi": "^3.5.15",
|
||||
"weixin-js-sdk": "^1.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nicecode/commit-lint": "^0.1.2",
|
||||
"@types/classnames": "^2.2.10",
|
||||
"@types/react": "^18.0.9",
|
||||
"@types/react-dom": "^18.0.5",
|
||||
"@typescript-eslint/eslint-plugin": "^5.26.0",
|
||||
"@typescript-eslint/parser": "^5.26.0",
|
||||
"@umijs/preset-react": "1.x",
|
||||
"@umijs/test": "^3.0.16",
|
||||
"babel-plugin-import": "^1.13.5",
|
||||
"babel-plugin-transform-remove-console": "^6.9.4",
|
||||
"commitlint": "^17.0.1",
|
||||
"cross-env": "^7.0.2",
|
||||
"eruda": "^2.4.1",
|
||||
"eslint": "^7.16.0",
|
||||
"eslint-config-alloy": "^4.5.1",
|
||||
"eslint-plugin-react": "^7.30.0",
|
||||
"husky": "^8.0.1",
|
||||
"lint-staged": "^10.0.7",
|
||||
"postcss-px2rem": "^0.3.0",
|
||||
"prettier": "^1.19.1",
|
||||
"typescript": "^4.1.3",
|
||||
"yorkie": "^2.0.0"
|
||||
|
@ -1,2 +1,4 @@
|
||||
import '@/utils/flexible';
|
||||
import 'antd-mobile/es/global';
|
||||
import '@/styles/index.less';
|
||||
import '@/styles/reset.less';
|
||||
|
@ -1,44 +0,0 @@
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import BreadcrumbItem from './BreadcrumbItem';
|
||||
import './index.less';
|
||||
|
||||
interface BreadcrumbProps {
|
||||
routes: any[];
|
||||
}
|
||||
|
||||
const Breadcrumb: React.FC<BreadcrumbProps> = ({ routes }) => {
|
||||
const validRoutes = routes.filter(item => !!item);
|
||||
|
||||
return (
|
||||
<div className="g-basic-layout-header-breadcrumb">
|
||||
<BreadcrumbItem.Root
|
||||
className={classnames({
|
||||
'g-basic-layout-header-breadcrumb-item-active': !validRoutes.length,
|
||||
})}
|
||||
/>
|
||||
{validRoutes.map(
|
||||
(item: any, index) =>
|
||||
item && (
|
||||
<span key={item.key}>
|
||||
<span className="g-basic-layout-header-breadcrumb-divider">
|
||||
/
|
||||
</span>
|
||||
<BreadcrumbItem
|
||||
path={item.path}
|
||||
className={classnames({
|
||||
'g-basic-layout-header-breadcrumb-item-active':
|
||||
index === validRoutes.length - 1,
|
||||
})}
|
||||
disabled={index === validRoutes.length - 1}
|
||||
>
|
||||
{item.name}
|
||||
</BreadcrumbItem>
|
||||
</span>
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Breadcrumb;
|
@ -1,48 +0,0 @@
|
||||
import React from 'react';
|
||||
import { history } from 'umi';
|
||||
import { Button } from 'antd';
|
||||
import { ButtonProps } from 'antd/lib/button';
|
||||
import { HomeOutlined } from '@ant-design/icons';
|
||||
import classnames from 'classnames';
|
||||
import './index.less';
|
||||
|
||||
interface BreadcrumbItemProps extends ButtonProps {
|
||||
path: string;
|
||||
}
|
||||
|
||||
const BreadcrumbItem = ({
|
||||
path,
|
||||
children,
|
||||
className,
|
||||
...rest
|
||||
}: BreadcrumbItemProps) => {
|
||||
return (
|
||||
<Button
|
||||
className={classnames('g-basic-layout-header-breadcrumb-item', className)}
|
||||
type="text"
|
||||
onClick={() => history.push(path)}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
const RootItem: React.FC<ButtonProps> = ({ className, ...rest }) => (
|
||||
<Button
|
||||
className={classnames(
|
||||
'g-basic-layout-header-breadcrumb-item',
|
||||
'g-basic-layout-header-breadcrumb-item-root',
|
||||
className,
|
||||
)}
|
||||
type="text"
|
||||
onClick={() => history.push('/')}
|
||||
{...rest}
|
||||
>
|
||||
<HomeOutlined />
|
||||
</Button>
|
||||
);
|
||||
|
||||
BreadcrumbItem.Root = RootItem;
|
||||
|
||||
export default BreadcrumbItem;
|
@ -1,84 +0,0 @@
|
||||
@import '../../styles/var.less';
|
||||
|
||||
.g-basic-layout {
|
||||
&-header {
|
||||
display: flex;
|
||||
|
||||
&-breadcrumb {
|
||||
.g-basic-layout-header-breadcrumb-item {
|
||||
color: @M4;
|
||||
padding: 0;
|
||||
|
||||
&:active {
|
||||
color: @M4;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: @S3;
|
||||
background-color: @M7;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background-color: @M7;
|
||||
}
|
||||
|
||||
&-active {
|
||||
color: @M2;
|
||||
|
||||
&[disabled],
|
||||
&[disabled]:hover,
|
||||
&[disabled]:focus,
|
||||
&[disabled]:active {
|
||||
color: @M2;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.g-basic-layout-header-breadcrumb-divider {
|
||||
color: @M4;
|
||||
margin: 0 @Sp-3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-pro-sider-logo img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.ant-pro-global-header {
|
||||
background-color: @M7;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.ant-pro-basicLayout-content {
|
||||
margin: @Sp-5 @Sp-8;
|
||||
}
|
||||
|
||||
.ant-page-header-heading {
|
||||
&-left {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&-title {
|
||||
font-size: @Fs-4;
|
||||
line-height: @Lh-4;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-layout {
|
||||
background-color: @M7;
|
||||
}
|
||||
|
||||
.ant-layout-sider,
|
||||
.ant-menu.ant-menu-dark,
|
||||
.ant-menu-dark .ant-menu-sub,
|
||||
.ant-menu.ant-menu-dark .ant-menu-sub {
|
||||
background-color: @S1;
|
||||
}
|
||||
|
||||
.ant-layout-content {
|
||||
min-height: calc(100vh - 72px);
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
import React from 'react';
|
||||
import { history, Link } from 'umi';
|
||||
import { EnterOutlined } from '@ant-design/icons';
|
||||
import ProLayout, { MenuDataItem } from '@ant-design/pro-layout';
|
||||
import { HeaderViewProps } from '@ant-design/pro-layout/lib/Header';
|
||||
// import User from '@/components/User';
|
||||
import Breadcrumb from './Breadcrumb';
|
||||
import './index.less';
|
||||
|
||||
|
||||
interface IBasicLayout {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const BasicLayout: React.FC<IBasicLayout> = ({ children, ...rest }: any) => {
|
||||
const iconMap = {
|
||||
EnterOutlined: <EnterOutlined />,
|
||||
};
|
||||
|
||||
// 带子菜单的一级导航
|
||||
const renderSubMenuItem = (itemProps: MenuDataItem): React.ReactNode => {
|
||||
return (
|
||||
<>
|
||||
{itemProps.icon && iconMap[itemProps.icon as string]}
|
||||
<span>{itemProps.name}</span>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
// 不带子菜单的导航
|
||||
const renderMenuItem = (itemProps: MenuDataItem): React.ReactNode => {
|
||||
return itemProps.isUrl || !itemProps.path ? (
|
||||
<>
|
||||
{itemProps.icon && iconMap[itemProps.icon as string]}
|
||||
<span>{itemProps.name}</span>
|
||||
</>
|
||||
) : (
|
||||
<Link to={itemProps.path}>
|
||||
{itemProps.icon && iconMap[itemProps.icon as string]}
|
||||
<span>{itemProps.name}</span>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
// 面包屑
|
||||
const renderHeaderContent: (
|
||||
props: HeaderViewProps,
|
||||
) => React.ReactNode = props => {
|
||||
// 匹配到到路由和面包屑信息
|
||||
const { matchMenuKeys, breadcrumb } = props as any;
|
||||
const matchRoutes = matchMenuKeys.map((item: any) => breadcrumb[item]);
|
||||
return (
|
||||
<div className="g-basic-layout-header">
|
||||
<Breadcrumb routes={matchRoutes} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// 用户信息
|
||||
// const renderUserAvatar = () => <User />;
|
||||
|
||||
return (
|
||||
<ProLayout
|
||||
className="g-basic-layout"
|
||||
logo="http://jzx-h5.oss-cn-hangzhou.aliyuncs.com/static/pill.png?x-oss-process=img/q/80"
|
||||
title="nicecode"
|
||||
siderWidth={180}
|
||||
fixedHeader
|
||||
fixSiderbar
|
||||
onMenuHeaderClick={() => history.push('/')}
|
||||
subMenuItemRender={renderSubMenuItem}
|
||||
menuItemRender={renderMenuItem}
|
||||
headerContentRender={renderHeaderContent}
|
||||
// rightContentRender={renderUserAvatar}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</ProLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default BasicLayout;
|
@ -1,33 +0,0 @@
|
||||
import { history } from 'umi';
|
||||
import { Image, Divider } from 'antd';
|
||||
import User from '@/components/User';
|
||||
import './index.less';
|
||||
|
||||
function Header() {
|
||||
return (
|
||||
<div className="g-window-layout-header">
|
||||
<div
|
||||
className="g-window-layout-header-logo"
|
||||
onClick={() => history.push('/')}
|
||||
>
|
||||
<Image
|
||||
src={require('../../assets/images/logo.png')}
|
||||
alt="logo"
|
||||
preview={false}
|
||||
width={36}
|
||||
height={24}
|
||||
/>
|
||||
<Divider
|
||||
type="vertical"
|
||||
className="g-window-layout-header-logo-divider"
|
||||
/>
|
||||
<span className="g-window-layout-header-logo-text">react-template</span>
|
||||
</div>
|
||||
<div className="g-window-layout-header-actions">
|
||||
<User />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Header;
|
@ -1,65 +0,0 @@
|
||||
@import '../../styles/var.less';
|
||||
|
||||
@headerHeader: 64px;
|
||||
|
||||
.g-window-layout {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 1200px;
|
||||
min-height: 100vh;
|
||||
background-color: @M7;
|
||||
|
||||
&-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: @headerHeader;
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
|
||||
&-wrapper {
|
||||
background-color: #000000;
|
||||
}
|
||||
|
||||
&-logo {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #ffffff;
|
||||
cursor: pointer;
|
||||
|
||||
&-divider.ant-divider {
|
||||
border-color: #ffffff;
|
||||
height: 12px;
|
||||
margin: 0 @Sp-5;
|
||||
}
|
||||
|
||||
&-text {
|
||||
font-size: @Fs-3;
|
||||
}
|
||||
}
|
||||
|
||||
&-actions {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&-content {
|
||||
flex: 1;
|
||||
width: 1200px;
|
||||
min-height: 600px;
|
||||
margin: 0 auto;
|
||||
padding: @Sp-8;
|
||||
background-color: #ffffff;
|
||||
box-shadow: @Sh-2;
|
||||
border-radius: @Ra-2;
|
||||
|
||||
&-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
min-height: 500px;
|
||||
padding: @Sp-8 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
import React from 'react';
|
||||
import Header from './Header';
|
||||
import './index.less';
|
||||
|
||||
interface IWindowLayout {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const WindowLayout: React.FC<IWindowLayout> = ({ children }) => {
|
||||
return (
|
||||
<div className="g-window-layout">
|
||||
<div className="g-window-layout-header-wrapper">
|
||||
<Header />
|
||||
</div>
|
||||
<div className="g-window-layout-content-wrapper">
|
||||
<div className="g-window-layout-content">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default WindowLayout;
|
15
src/pages/document.ejs
Normal file
15
src/pages/document.ejs
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="full-screen" content="yes">
|
||||
<meta name="x5-fullscreen" content="true">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<title>加载中...</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root" style="position:relative;"></div>
|
||||
</body>
|
||||
</html>
|
@ -1,5 +1,6 @@
|
||||
.title {
|
||||
margin: 100px auto;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
// background: rgb(121, 242, 157);
|
||||
}
|
||||
|
27
src/services/common.ts
Normal file
27
src/services/common.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
/**
|
||||
* 获取微信授权信息
|
||||
* @returns 获取微信授权信息
|
||||
*/
|
||||
export async function getWxAuthorities(data: { url: string; }): Promise<any> {
|
||||
return request.post('/dianhun/traffic/accident/weixin/param/v1', data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @returns 获取微信授权信息
|
||||
*/
|
||||
export async function getUserInfo(data: any): Promise<any> {
|
||||
return request.post(
|
||||
process.env.BASE_API + '/dianhun/traffic/accident/weixin/code/v1',
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
export async function jumpToWxUrl(params: any): Promise<any> {
|
||||
return request.post(
|
||||
process.env.BASE_API + '/dianhun/traffic/accident/weixin/redirectUrl/v1',
|
||||
params,
|
||||
);
|
||||
}
|
53
src/utils/flexible.ts
Normal file
53
src/utils/flexible.ts
Normal file
@ -0,0 +1,53 @@
|
||||
(function flexible(window, document) {
|
||||
let docEl = document.documentElement;
|
||||
let dpr = window.devicePixelRatio || 1;
|
||||
|
||||
// adjust body font size
|
||||
function setBodyFontSize() {
|
||||
if (document.body) {
|
||||
document.body.style.fontSize = 12 * dpr + 'px';
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', setBodyFontSize);
|
||||
}
|
||||
}
|
||||
setBodyFontSize();
|
||||
|
||||
// set 1rem = viewWidth / 10
|
||||
function setRemUnit() {
|
||||
let width = document.documentElement.clientWidth;
|
||||
let height = document.documentElement.clientHeight;
|
||||
let rem = 0
|
||||
if (width > height) {
|
||||
// 横屏
|
||||
// @ts-ignore
|
||||
rem = height * 1.78;
|
||||
} else {
|
||||
// 竖屏
|
||||
rem = width * 1.78;
|
||||
}
|
||||
docEl.style.fontSize = rem / 10 + 'px';
|
||||
}
|
||||
|
||||
setRemUnit();
|
||||
|
||||
// reset rem unit on page resize
|
||||
window.addEventListener('resize', setRemUnit);
|
||||
window.addEventListener('pageshow', (e) => {
|
||||
if (e.persisted) {
|
||||
setRemUnit();
|
||||
}
|
||||
});
|
||||
|
||||
// detect 0.5px supports
|
||||
if (dpr >= 2) {
|
||||
let fakeBody = document.createElement('body');
|
||||
let testElement = document.createElement('div');
|
||||
testElement.style.border = '.5px solid transparent';
|
||||
fakeBody.appendChild(testElement);
|
||||
docEl.appendChild(fakeBody);
|
||||
if (testElement.offsetHeight === 1) {
|
||||
docEl.classList.add('hairlines');
|
||||
}
|
||||
docEl.removeChild(fakeBody);
|
||||
}
|
||||
})(window, document);
|
@ -0,0 +1,55 @@
|
||||
import { Toast } from 'antd-mobile';
|
||||
|
||||
export const resize = () => {
|
||||
let width = document.documentElement.clientWidth;
|
||||
let height = document.documentElement.clientHeight;
|
||||
console.log(width, height);
|
||||
let root = document.querySelector('#root') as any;
|
||||
root.style.position = 'relative';
|
||||
// root.style.overflow = 'hidden';
|
||||
root.style.top = '50%';
|
||||
root.style.left = '50%';
|
||||
root.style['transform-origin'] = '50% 50%';
|
||||
|
||||
if (width > height) {
|
||||
// 横屏
|
||||
// 判断比例是否正确
|
||||
root.style.width = height * 1.78 + 'px';
|
||||
root.style.height = height + 'px';
|
||||
root.style.transform = 'translate(-50%, -50%)';
|
||||
// 不旋转
|
||||
} else {
|
||||
// 竖屏
|
||||
root.style.width = width * 1.78 + 'px';
|
||||
root.style.height = width + 'px';
|
||||
root.style.transform = 'translate(-50%, -50%) rotate(90deg)';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 复制粘贴
|
||||
* @param value 需要复制粘贴的值
|
||||
*/
|
||||
export const copy = function (value: any) {
|
||||
return new Promise((resolve) => {
|
||||
let copyTextArea = null;
|
||||
try {
|
||||
copyTextArea = document.createElement('textarea');
|
||||
copyTextArea.style.height = '0px';
|
||||
copyTextArea.style.opacity = '0';
|
||||
copyTextArea.style.width = '0px';
|
||||
document.body.appendChild(copyTextArea);
|
||||
copyTextArea.value = value;
|
||||
copyTextArea.select();
|
||||
document.execCommand('copy');
|
||||
Toast.show({
|
||||
content: '链接复制成功!',
|
||||
});
|
||||
resolve(value);
|
||||
} finally {
|
||||
if (copyTextArea?.parentNode) {
|
||||
copyTextArea.parentNode.removeChild(copyTextArea);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
import axios from 'axios';
|
||||
import { message } from 'antd';
|
||||
import { Toast } from 'antd-mobile';
|
||||
import CodeMsg from '@/assets/data/code';
|
||||
import { BaseResponse } from '@/interfaces/base';
|
||||
|
||||
@ -11,7 +11,9 @@ export const DEFAULT_TIP_MESSAGE = '请求失败,请刷新重试';
|
||||
*/
|
||||
export function handleError(data: BaseResponse): void {
|
||||
const msg = CodeMsg[data.code] || data.msg || DEFAULT_TIP_MESSAGE;
|
||||
message.error(msg);
|
||||
Toast.show({
|
||||
content: msg,
|
||||
})
|
||||
}
|
||||
|
||||
// create an axios instance
|
||||
@ -33,9 +35,13 @@ service.interceptors.request.use(
|
||||
error => {
|
||||
// Do something with request error
|
||||
if (error.status === '504') {
|
||||
message.error('网关超时,请重试!');
|
||||
Toast.show({
|
||||
content: '网关超时,请重试!',
|
||||
})
|
||||
} else {
|
||||
message.error(`网络异常[-${error.status}]`);
|
||||
Toast.show({
|
||||
content: `网络异常[-${error.status}]`,
|
||||
})
|
||||
console.log(error); // for debug
|
||||
}
|
||||
Promise.reject(error);
|
||||
|
120
src/utils/wxShare.ts
Normal file
120
src/utils/wxShare.ts
Normal file
@ -0,0 +1,120 @@
|
||||
import { getWxAuthorities } from '@/services/common';
|
||||
import { checkDevice } from '@nicecode/tools';
|
||||
import wx from 'weixin-js-sdk';
|
||||
|
||||
// 要用到微信API
|
||||
function getJSSDK(
|
||||
shareUrl: string,
|
||||
shareMsg: {
|
||||
title: string;
|
||||
desc: string;
|
||||
link: string;
|
||||
imgUrl: string;
|
||||
},
|
||||
) {
|
||||
if (checkDevice.isWeChat()) {
|
||||
getWxAuthorities({ url: shareUrl }).then(
|
||||
(res: {
|
||||
data: {
|
||||
appId: string;
|
||||
timestamp: number;
|
||||
echostr: string;
|
||||
signature: string;
|
||||
};
|
||||
}) => {
|
||||
wx.config({
|
||||
// debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
|
||||
appId: res.data.appId, // 必填,公众号的唯一标识
|
||||
timestamp: res.data.timestamp, // 必填,生成签名的时间戳
|
||||
nonceStr: res.data.echostr, // 必填,生成签名的随机串
|
||||
signature: res.data.signature, // 必填,签名
|
||||
jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData'],
|
||||
});
|
||||
wx.ready(() => {
|
||||
// 分享给微信朋友
|
||||
wx.updateAppMessageShareData({
|
||||
title: shareMsg.title,
|
||||
desc: shareMsg.desc,
|
||||
link: shareMsg.link,
|
||||
imgUrl: shareMsg.imgUrl,
|
||||
success: function success(res: any) {
|
||||
console.log(res, '分享成功');
|
||||
},
|
||||
cancel: function cancel() {
|
||||
// console.log('已取消');
|
||||
},
|
||||
fail: function fail() {
|
||||
// alert(JSON.stringify(res));
|
||||
},
|
||||
});
|
||||
// 2.2 监听“分享到朋友圈”按钮点击、自定义分享内容及分享结果接口
|
||||
wx.updateTimelineShareData({
|
||||
title: shareMsg.title,
|
||||
link: shareMsg.link,
|
||||
imgUrl: shareMsg.imgUrl,
|
||||
success: function success(_res: any) {
|
||||
// alert('已分享');
|
||||
},
|
||||
cancel: function cancel(_res: any) {
|
||||
// alert('已取消');
|
||||
},
|
||||
fail: function fail() {
|
||||
// alert(JSON.stringify(res));
|
||||
},
|
||||
});
|
||||
// 2.3 监听“分享到QQ”按钮点击、自定义分享内容及分享结果接口
|
||||
// wx.onMenuShareQQ({
|
||||
// title: shareMsg.title,
|
||||
// desc: shareMsg.desc,
|
||||
// link: shareMsg.linkurl,
|
||||
// imgUrl: shareMsg.img,
|
||||
// trigger: function trigger(res) {
|
||||
// //alert('用户点击分享到QQ');
|
||||
// },
|
||||
// complete: function complete(res) {
|
||||
// alert(JSON.stringify(res));
|
||||
// },
|
||||
// success: function success(res) {
|
||||
// //alert('已分享');
|
||||
// },
|
||||
// cancel: function cancel(res) {
|
||||
// //alert('已取消');
|
||||
// },
|
||||
// fail: function fail(res) {
|
||||
// //alert(JSON.stringify(res));
|
||||
// }
|
||||
// });
|
||||
// 2.4 监听“分享到微博”按钮点击、自定义分享内容及分享结果接口
|
||||
// wx.onMenuShareWeibo({
|
||||
// title: shareMsg.title,
|
||||
// desc: shareMsg.desc,
|
||||
// link: shareMsg.linkurl,
|
||||
// imgUrl: shareMsg.img,
|
||||
// trigger: function trigger(res) {
|
||||
// //alert('用户点击分享到微博');
|
||||
// },
|
||||
// complete: function complete(res) {
|
||||
// // alert(JSON.stringify(res));
|
||||
// },
|
||||
// success: function success(res) {
|
||||
// //alert('已分享');
|
||||
// },
|
||||
// cancel: function cancel(res) {
|
||||
// // alert('已取消');
|
||||
// },
|
||||
// fail: function fail(res) {
|
||||
// // alert(JSON.stringify(res));
|
||||
// }
|
||||
// });
|
||||
});
|
||||
wx.error(() => {
|
||||
// alert("微信验证失败");
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
export default {
|
||||
// 获取JSSDK
|
||||
getJSSDK,
|
||||
};
|
4
typings.d.ts
vendored
4
typings.d.ts
vendored
@ -3,4 +3,6 @@ declare module '*.less';
|
||||
declare module '*.png';
|
||||
declare module '*.jpeg';
|
||||
declare module '*.jpg';
|
||||
declare module 'immer'
|
||||
declare module 'eruda'
|
||||
declare module 'weixin-js-sdk'
|
||||
declare module 'postcss-px2rem'
|
||||
|
Loading…
Reference in New Issue
Block a user