mirror of
https://github.com/MrXujiang/h5-Dooring.git
synced 2025-12-11 17:32:50 +00:00
🆕 添加赞赏组件,优化组件结构,优化代码结构
This commit is contained in:
parent
9b21cca2eb
commit
786aa5ee1f
11
doc/index.html
Normal file
11
doc/index.html
Normal file
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -1,3 +1,6 @@
|
||||
.takeCat {
|
||||
display: inline-block;
|
||||
}
|
||||
.imgWrap {
|
||||
width: 160px;
|
||||
img {
|
||||
|
||||
@ -1,21 +1,31 @@
|
||||
import React, { memo } from 'react';
|
||||
import React, { memo, ReactElement, ReactNode } from 'react';
|
||||
import { Button, Popover } from 'antd';
|
||||
import { serverUrl } from '@/utils/tool';
|
||||
import styles from './index.less';
|
||||
|
||||
interface IProps {
|
||||
text: any;
|
||||
}
|
||||
|
||||
///这组件写的有问题 popover会重定位
|
||||
const content = (
|
||||
<div className={styles.imgWrap}>
|
||||
<img src="http://49.234.61.19/uploads/WechatIMG2_1742b586c3d.jpeg" alt="sponsorship" />
|
||||
<img src={`${serverUrl}/uploads/WechatIMG2_1742b586c3d.jpeg`} alt="sponsorship" />
|
||||
</div>
|
||||
);
|
||||
|
||||
export default memo(function ZanPao() {
|
||||
export default memo(function ZanPao(props: IProps) {
|
||||
const {
|
||||
text = (
|
||||
<Button type="primary" danger style={{ background: 'red !important' }} size="large">
|
||||
支持开源, 请作者喝茶~
|
||||
</Button>
|
||||
),
|
||||
} = props;
|
||||
return (
|
||||
<div className={styles.takeCat} style={{ display: 'inline-block' }}>
|
||||
<div className={styles.takeCat}>
|
||||
<Popover placement="top" title={null} content={content} trigger="hover">
|
||||
<Button type="primary" size="large">
|
||||
支持开源, 请作者喝奶茶~
|
||||
</Button>
|
||||
{text}
|
||||
</Popover>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -1,31 +1,23 @@
|
||||
import { dynamic } from 'umi';
|
||||
import Loading from '../components/LoadingCp';
|
||||
import { useMemo, memo, FC, useContext } from 'react';
|
||||
import { useMemo, memo, FC } from 'react';
|
||||
import React from 'react';
|
||||
import { dooringContext, dooringContextType } from '@/layouts';
|
||||
|
||||
export type componentsType = 'media' | 'base' | 'visible';
|
||||
|
||||
const DynamicFunc = (type: string, componentsType: string, context: dooringContextType) => {
|
||||
const prefix = context === 'pc' ? 'Pc' : '';
|
||||
const DynamicFunc = (type: string, componentsType: string) => {
|
||||
return dynamic({
|
||||
loader: async function() {
|
||||
let Component: FC<{ isTpl: boolean }>;
|
||||
|
||||
if (componentsType === 'base') {
|
||||
const { default: Graph } = await import(
|
||||
`@/components/Basic${prefix}Shop/BasicComponents/${type}`
|
||||
);
|
||||
const { default: Graph } = await import(`@/components/BasicShop/BasicComponents/${type}`);
|
||||
Component = Graph;
|
||||
} else if (componentsType === 'media') {
|
||||
const { default: Graph } = await import(
|
||||
`@/components/Basic${prefix}Shop/MediaComponents/${type}`
|
||||
);
|
||||
const { default: Graph } = await import(`@/components/BasicShop/MediaComponents/${type}`);
|
||||
Component = Graph;
|
||||
} else {
|
||||
const { default: Graph } = await import(
|
||||
`@/components/Basic${prefix}Shop/VisualComponents/${type}`
|
||||
);
|
||||
const { default: Graph } = await import(`@/components/BasicShop/VisualComponents/${type}`);
|
||||
Component = Graph;
|
||||
}
|
||||
return (props: DynamicType) => {
|
||||
@ -50,11 +42,10 @@ type DynamicType = {
|
||||
};
|
||||
const DynamicEngine = memo((props: DynamicType) => {
|
||||
const { type, config, category } = props;
|
||||
const context = useContext(dooringContext);
|
||||
const Dynamic = useMemo(() => {
|
||||
return (DynamicFunc(type, category, context.theme) as unknown) as FC<DynamicType>;
|
||||
return (DynamicFunc(type, category) as unknown) as FC<DynamicType>;
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [config, context.theme]);
|
||||
}, [config]);
|
||||
|
||||
return <Dynamic {...props} />;
|
||||
});
|
||||
|
||||
@ -39,7 +39,7 @@ const ViewRender = memo((props: ViewProps) => {
|
||||
}}
|
||||
>
|
||||
{pointData.map((value: PointDataItem) => (
|
||||
<div key={value.id} data-grid={value.point} className={styles.dragItem}>
|
||||
<div key={value.id} data-grid={value.point} className={onDragStart && styles.dragItem}>
|
||||
<DynamicEngine {...(value.item as any)} isTpl={false} />
|
||||
</div>
|
||||
))}
|
||||
|
||||
46
src/layouts/index.less
Normal file
46
src/layouts/index.less
Normal file
@ -0,0 +1,46 @@
|
||||
.dragPay {
|
||||
position: absolute;
|
||||
z-index: 99999;
|
||||
left: 414px;
|
||||
bottom: 56px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
border: 3px solid #20c961;
|
||||
background: #ffffff;
|
||||
overflow: hidden;
|
||||
padding: 5px;
|
||||
.wave {
|
||||
position: relative;
|
||||
left: -8px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
background-image: linear-gradient(-180deg, #8dec8a 13%, #70cf23 91%);
|
||||
border-radius: 50%;
|
||||
line-height: 60px;
|
||||
text-align: center;
|
||||
font-size: 32px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.waveMask {
|
||||
position: absolute;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
border-radius: 40%;
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
transform: translate(-50%, -82%) rotate(0);
|
||||
animation: toRotate 10s linear -5s infinite;
|
||||
z-index: 20;
|
||||
pointer-events: none;
|
||||
}
|
||||
@keyframes toRotate {
|
||||
50% {
|
||||
transform: translate(-50%, -70%) rotate(180deg);
|
||||
}
|
||||
100% {
|
||||
transform: translate(-50%, -70%) rotate(360deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,11 @@
|
||||
import React, { createContext, useCallback, useState } from 'react';
|
||||
import React, { useCallback, useState, useEffect } from 'react';
|
||||
import { library, generateRespones, RenderList, useRegister } from 'chatbot-antd';
|
||||
import { IRouteComponentProps } from 'umi';
|
||||
import { Button } from 'antd';
|
||||
import { IRouteComponentProps, history } from 'umi';
|
||||
import { Button, Modal } from 'antd';
|
||||
import Zan from '@/components/Zan';
|
||||
import { CustomerServiceOutlined } from '@ant-design/icons';
|
||||
import Draggable from 'react-draggable';
|
||||
import styles from './index.less';
|
||||
|
||||
library.push(
|
||||
//语料库,push进去,也可以不用
|
||||
@ -14,28 +17,15 @@ library.push(
|
||||
text: (
|
||||
<div>
|
||||
<a href="https://github.com/MrXujiang">@徐小夕</a>
|
||||
<a href="https://github.com/yehuozhili">@yehuozhili</a>
|
||||
<a href="https://github.com/zhangjinlongll">@zhangjinlongll</a>
|
||||
<a href="https://github.com/yehuozhili/learnsinglespa">@yehuozhili</a>
|
||||
</div>
|
||||
),
|
||||
useReg: /(.*?)作者是谁(.*?)/,
|
||||
},
|
||||
);
|
||||
|
||||
export type dooringContextType = 'h5' | 'pc';
|
||||
|
||||
export interface IdooringContextType {
|
||||
theme: dooringContextType;
|
||||
setTheme: Function;
|
||||
}
|
||||
export const dooringContext = createContext<IdooringContextType>({
|
||||
theme: 'h5',
|
||||
setTheme: () => {},
|
||||
});
|
||||
|
||||
export default function Layout({ children }: IRouteComponentProps) {
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
const [num, setNum] = useState(0);
|
||||
const callb = useCallback((v: RenderList) => {
|
||||
setTimeout(() => {
|
||||
//使用settimeout 更像机器人回话
|
||||
@ -47,21 +37,19 @@ export default function Layout({ children }: IRouteComponentProps) {
|
||||
}, 500);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const handleDeploy = () => {
|
||||
window.open('http://h5.dooring.cn/uploads/WechatIMG3_1758e9753e2.jpeg');
|
||||
};
|
||||
// 注册
|
||||
const [render, setList] = useRegister(
|
||||
modalOpen,
|
||||
callb,
|
||||
{
|
||||
onOk: () => {
|
||||
setModalOpen(false);
|
||||
setNum(0);
|
||||
},
|
||||
onCancel: () => {
|
||||
setModalOpen(false);
|
||||
setNum(0);
|
||||
},
|
||||
onOk: () => setModalOpen(false),
|
||||
onCancel: () => setModalOpen(false),
|
||||
title: 'h5-Dooring机器人客服',
|
||||
width: 400,
|
||||
width: 420,
|
||||
},
|
||||
{},
|
||||
<div>
|
||||
@ -71,72 +59,90 @@ export default function Layout({ children }: IRouteComponentProps) {
|
||||
<div>
|
||||
<div>
|
||||
1.{' '}
|
||||
<a href="https://github.com/MrXujiang/h5-Dooring" target="_blank" rel="noreferrer">
|
||||
<a href="https://github.com/MrXujiang/h5-Dooring" target="_blank">
|
||||
H5-Dooring源码地址
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
2.{' '}
|
||||
<a
|
||||
href="https://github.com/MrXujiang/h5-Dooring/graphs/contributors"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<a href="https://github.com/MrXujiang/h5-Dooring/graphs/contributors" target="_blank">
|
||||
贡献者列表
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
3. 如果复制/删除组件不生效, 请先点击需要复制/删除组件, 再右键删除/复制
|
||||
</div>
|
||||
<div style={{ color: 'red' }}>
|
||||
4. 如果二维码组件无法扫码, 请适当调小中间图标尺寸
|
||||
</div>
|
||||
<div style={{ fontSize: '12px' }}>
|
||||
3. dooring开源交流群(微信:Mr_xuxiaoxi)
|
||||
5. dooring开源交流群(微信:Mr_xuxiaoxi)
|
||||
</div>
|
||||
<div style={{ fontSize: '12px', marginTop: '10px' }}>
|
||||
|
||||
<Button type="primary" onClick={handleDeploy}>
|
||||
私有化部署
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
const [state, setState] = useState<dooringContextType>('h5');
|
||||
return (
|
||||
<dooringContext.Provider
|
||||
value={{
|
||||
theme: state,
|
||||
setTheme: setState,
|
||||
}}
|
||||
>
|
||||
<div style={{ height: '100%', width: '100%', overflow: 'hidden' }}>
|
||||
<div
|
||||
style={{
|
||||
position: 'fixed',
|
||||
right: `${num === 0 ? '-10px' : num === 1 ? '-100%' : '0px'}`,
|
||||
bottom: '80px',
|
||||
transition: 'all 0.3s ease-in-out',
|
||||
zIndex: 2,
|
||||
}}
|
||||
onMouseEnter={() => {
|
||||
//0初始,1点击 2移入
|
||||
setNum(2);
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
setNum(pre => (pre === 2 ? 0 : pre));
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
type="primary"
|
||||
style={{
|
||||
transition: 'all 0.3s ease-in-out',
|
||||
borderRadius: `${num === 0 ? '1000px' : '0px'}`,
|
||||
transform: `${num === 0 ? 'scale(0.5)' : 'scale(1)'}`,
|
||||
}}
|
||||
onClick={() => {
|
||||
setModalOpen(!modalOpen);
|
||||
!modalOpen && setNum(1);
|
||||
}}
|
||||
>
|
||||
<CustomerServiceOutlined></CustomerServiceOutlined>
|
||||
</Button>
|
||||
</div>
|
||||
useEffect(() => {
|
||||
setInterval(() => {
|
||||
const timeout = +localStorage.getItem('tt');
|
||||
if (timeout && timeout < Date.now()) {
|
||||
localStorage.removeItem('tt');
|
||||
Modal.info({
|
||||
title: 'Dooring温馨提示',
|
||||
content: <div>您的登录已过期, 请点击确认按钮重新登录</div>,
|
||||
okText: '确认',
|
||||
onOk() {
|
||||
localStorage.removeItem('rp');
|
||||
localStorage.removeItem('nickname');
|
||||
history.push('/login');
|
||||
},
|
||||
});
|
||||
}
|
||||
}, 1000 * 15);
|
||||
}, []);
|
||||
|
||||
{render}
|
||||
{children}
|
||||
const hackCodeStyle =
|
||||
window.location.pathname.indexOf('preview') < 0
|
||||
? { height: '100%' }
|
||||
: { height: '100%', overflow: 'auto' };
|
||||
return (
|
||||
<div style={hackCodeStyle}>
|
||||
<div
|
||||
style={{
|
||||
position: 'fixed',
|
||||
right: `${modalOpen ? '-100%' : '10px'}`,
|
||||
bottom: '16px',
|
||||
transition: 'all 0.5s ease-in-out',
|
||||
zIndex: 2,
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
type="primary"
|
||||
style={{ padding: '0 6px' }}
|
||||
onClick={() => setModalOpen(!modalOpen)}
|
||||
>
|
||||
<CustomerServiceOutlined></CustomerServiceOutlined>
|
||||
</Button>
|
||||
</div>
|
||||
</dooringContext.Provider>
|
||||
{render}
|
||||
{children}
|
||||
{window.location.pathname.indexOf('editor') > -1 && (
|
||||
<Draggable>
|
||||
<div className={styles.dragPay}>
|
||||
<div className={styles.wave}>
|
||||
<Zan text="⛽️" />
|
||||
</div>
|
||||
<div className={styles.waveMask}></div>
|
||||
</div>
|
||||
</Draggable>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import React, { memo, useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
||||
import React, { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useDrop } from 'react-dnd';
|
||||
import Draggable, { DraggableData, DraggableEvent } from 'react-draggable';
|
||||
import { ItemCallback } from 'react-grid-layout';
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import React, { useMemo, memo, ReactNode, useContext, CSSProperties } from 'react';
|
||||
import { useDrag } from 'react-dnd';
|
||||
import schemaH5 from 'components/BasicShop/schema';
|
||||
import schemaPc from 'components/BasicPcShop/schema';
|
||||
import schema from 'components/BasicShop/schema';
|
||||
import styles from './index.less';
|
||||
import { dooringContext } from '@/layouts';
|
||||
|
||||
@ -13,14 +12,7 @@ interface TargetBoxProps {
|
||||
|
||||
const TargetBox = memo((props: TargetBoxProps) => {
|
||||
const { item } = props;
|
||||
const context = useContext(dooringContext);
|
||||
const schema = useMemo(() => {
|
||||
if (context.theme === 'h5') {
|
||||
return schemaH5;
|
||||
} else {
|
||||
return schemaPc;
|
||||
}
|
||||
}, [context.theme]);
|
||||
|
||||
const [{ isDragging }, drag] = useDrag({
|
||||
item: {
|
||||
type: item.type,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import React, { useRef, memo, useMemo, useContext, useState, useEffect } from 'react';
|
||||
import React, { useRef, memo, useMemo, useState, useEffect } from 'react';
|
||||
import { Button, Input, Modal, Select, Upload, Tooltip, Badge } from 'antd';
|
||||
import {
|
||||
ArrowLeftOutlined,
|
||||
@ -20,7 +20,6 @@ import { saveAs } from 'file-saver';
|
||||
import req from '@/utils/req';
|
||||
import Code from '@/assets/code.png';
|
||||
import styles from './index.less';
|
||||
import { dooringContext } from '@/layouts';
|
||||
import MyPopover from 'yh-react-popover';
|
||||
|
||||
const { confirm } = Modal;
|
||||
@ -217,10 +216,9 @@ const HeaderComponent = memo((props: HeaderComponentProps) => {
|
||||
};
|
||||
|
||||
const handleReloadPage = () => {
|
||||
document.getElementById('previewPage').contentWindow.location.reload();
|
||||
document.getElementById('previewPage')?.contentWindow.location.reload();
|
||||
};
|
||||
|
||||
const { setTheme } = useContext(dooringContext);
|
||||
return (
|
||||
<div className={styles.header}>
|
||||
<div className={styles.logoArea}>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user