mirror of
https://github.com/MrXujiang/h5-Dooring.git
synced 2025-12-12 10:12:51 +00:00
add:规划 抽离公用组件-以zarm为两端复用对象 antd为pc端组件
This commit is contained in:
parent
242553ac4a
commit
ce965598a9
21
src/components/BasicPcShop/BasicComponents/Footer/index.tsx
Normal file
21
src/components/BasicPcShop/BasicComponents/Footer/index.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import React, { memo } from 'react';
|
||||||
|
import { IFooterConfig } from './schema';
|
||||||
|
const Footer = memo((props: IFooterConfig) => {
|
||||||
|
const { bgColor, text, color, align, fontSize, height } = props;
|
||||||
|
return (
|
||||||
|
<footer
|
||||||
|
style={{
|
||||||
|
backgroundColor: bgColor,
|
||||||
|
color,
|
||||||
|
fontSize,
|
||||||
|
textAlign: align,
|
||||||
|
height,
|
||||||
|
lineHeight: height + 'px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{text}
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Footer;
|
||||||
87
src/components/BasicPcShop/BasicComponents/Footer/schema.ts
Normal file
87
src/components/BasicPcShop/BasicComponents/Footer/schema.ts
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import {
|
||||||
|
IColorConfigType,
|
||||||
|
INumberConfigType,
|
||||||
|
ISelectConfigType,
|
||||||
|
ITextConfigType,
|
||||||
|
TColorDefaultType,
|
||||||
|
TNumberDefaultType,
|
||||||
|
TSelectDefaultType,
|
||||||
|
TTextDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
|
||||||
|
export type TfooterSelectKeyType = 'left' | 'center' | 'right';
|
||||||
|
|
||||||
|
export type TFooterEditData = Array<
|
||||||
|
IColorConfigType | INumberConfigType | ITextConfigType | ISelectConfigType<TfooterSelectKeyType>
|
||||||
|
>;
|
||||||
|
export interface IFooterConfig {
|
||||||
|
bgColor: TColorDefaultType;
|
||||||
|
text: TTextDefaultType;
|
||||||
|
color: TColorDefaultType;
|
||||||
|
align: TSelectDefaultType<TfooterSelectKeyType>;
|
||||||
|
fontSize: TNumberDefaultType;
|
||||||
|
height: TNumberDefaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IFooterSchema {
|
||||||
|
editData: TFooterEditData;
|
||||||
|
config: IFooterConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Footer: IFooterSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'bgColor',
|
||||||
|
name: '背景色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'height',
|
||||||
|
name: '高度',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'text',
|
||||||
|
name: '文字',
|
||||||
|
type: 'Text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'fontSize',
|
||||||
|
name: '字体大小',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'color',
|
||||||
|
name: '文字颜色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'align',
|
||||||
|
name: '对齐方式',
|
||||||
|
type: 'Select',
|
||||||
|
range: [
|
||||||
|
{
|
||||||
|
key: 'left',
|
||||||
|
text: '左对齐',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'center',
|
||||||
|
text: '居中对齐',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'right',
|
||||||
|
text: '右对齐',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
bgColor: 'rgba(0,0,0,1)',
|
||||||
|
text: '页脚Footer',
|
||||||
|
color: 'rgba(255,255,255,1)',
|
||||||
|
align: 'center',
|
||||||
|
fontSize: 16,
|
||||||
|
height: 48,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export default Footer;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'Footer',
|
||||||
|
h: 24,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
23
src/components/BasicPcShop/BasicComponents/Header/index.less
Normal file
23
src/components/BasicPcShop/BasicComponents/Header/index.less
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
.header {
|
||||||
|
box-sizing: content-box;
|
||||||
|
padding: 3px 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 50px;
|
||||||
|
background-color: #000;
|
||||||
|
.logo {
|
||||||
|
margin-right: 10px;
|
||||||
|
max-width: 160px;
|
||||||
|
max-height: 46px;
|
||||||
|
height: 46px;
|
||||||
|
overflow: hidden;
|
||||||
|
img {
|
||||||
|
height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
font-size: 20px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/components/BasicPcShop/BasicComponents/Header/index.tsx
Normal file
20
src/components/BasicPcShop/BasicComponents/Header/index.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { memo } from 'react';
|
||||||
|
import styles from './index.less';
|
||||||
|
import React from 'react';
|
||||||
|
import { IHeaderConfig } from './schema';
|
||||||
|
|
||||||
|
const Header = memo((props: IHeaderConfig) => {
|
||||||
|
const { bgColor, logo, logoText, fontSize, color } = props;
|
||||||
|
return (
|
||||||
|
<header className={styles.header} style={{ backgroundColor: bgColor }}>
|
||||||
|
<div className={styles.logo}>
|
||||||
|
<img src={logo && logo[0].url} alt={logoText} />
|
||||||
|
</div>
|
||||||
|
<div className={styles.title} style={{ fontSize, color }}>
|
||||||
|
{logoText}
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Header;
|
||||||
81
src/components/BasicPcShop/BasicComponents/Header/schema.ts
Normal file
81
src/components/BasicPcShop/BasicComponents/Header/schema.ts
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import {
|
||||||
|
IColorConfigType,
|
||||||
|
INumberConfigType,
|
||||||
|
ITextConfigType,
|
||||||
|
IUploadConfigType,
|
||||||
|
TColorDefaultType,
|
||||||
|
TNumberDefaultType,
|
||||||
|
TTextDefaultType,
|
||||||
|
TUploadDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
|
||||||
|
export type THeaderEditData = Array<
|
||||||
|
IColorConfigType | INumberConfigType | IUploadConfigType | ITextConfigType
|
||||||
|
>;
|
||||||
|
export interface IHeaderConfig {
|
||||||
|
bgColor: TColorDefaultType;
|
||||||
|
logo: TUploadDefaultType;
|
||||||
|
logoText: TTextDefaultType;
|
||||||
|
fontSize: TNumberDefaultType;
|
||||||
|
color: TColorDefaultType;
|
||||||
|
height: TNumberDefaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IHeaderSchema {
|
||||||
|
editData: THeaderEditData;
|
||||||
|
config: IHeaderConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Header: IHeaderSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'bgColor',
|
||||||
|
name: '背景色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'height',
|
||||||
|
name: '高度',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'logo',
|
||||||
|
name: 'logo',
|
||||||
|
type: 'Upload',
|
||||||
|
isCrop: true,
|
||||||
|
cropRate: 1000 / 618,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'logoText',
|
||||||
|
name: 'logo文字',
|
||||||
|
type: 'Text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'color',
|
||||||
|
name: '文字颜色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'fontSize',
|
||||||
|
name: '文字大小',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
bgColor: 'rgba(0,0,0,1)',
|
||||||
|
logo: [
|
||||||
|
{
|
||||||
|
uid: '001',
|
||||||
|
name: 'image.png',
|
||||||
|
status: 'done',
|
||||||
|
url: 'http://io.nainor.com/uploads/3_1740be8a482.png',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
logoText: '页头Header',
|
||||||
|
fontSize: 20,
|
||||||
|
color: 'rgba(255,255,255,1)',
|
||||||
|
height: 50,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Header;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'Header',
|
||||||
|
h: 28,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
364
src/components/BasicPcShop/BasicComponents/Icon/icon.ts
Normal file
364
src/components/BasicPcShop/BasicComponents/Icon/icon.ts
Normal file
@ -0,0 +1,364 @@
|
|||||||
|
export type AntdIconType =
|
||||||
|
| 'max'
|
||||||
|
| 'required'
|
||||||
|
| 'default'
|
||||||
|
| 'high'
|
||||||
|
| 'low'
|
||||||
|
| 'disabled'
|
||||||
|
| 'start'
|
||||||
|
| 'open'
|
||||||
|
| 'media'
|
||||||
|
| 'hidden'
|
||||||
|
| 'cite'
|
||||||
|
| 'data'
|
||||||
|
| 'dir'
|
||||||
|
| 'form'
|
||||||
|
| 'label'
|
||||||
|
| 'slot'
|
||||||
|
| 'span'
|
||||||
|
| 'style'
|
||||||
|
| 'summary'
|
||||||
|
| 'title'
|
||||||
|
| 'pattern'
|
||||||
|
| 'async'
|
||||||
|
| 'defer'
|
||||||
|
| 'manifest'
|
||||||
|
| 'color'
|
||||||
|
| 'content'
|
||||||
|
| 'size'
|
||||||
|
| 'wrap'
|
||||||
|
| 'multiple'
|
||||||
|
| 'height'
|
||||||
|
| 'rotate'
|
||||||
|
| 'translate'
|
||||||
|
| 'width'
|
||||||
|
| 'prefix'
|
||||||
|
| 'src'
|
||||||
|
| 'children'
|
||||||
|
| 'key'
|
||||||
|
| 'list'
|
||||||
|
| 'step'
|
||||||
|
| 'aria-label'
|
||||||
|
| 'spin'
|
||||||
|
| 'accept'
|
||||||
|
| 'acceptCharset'
|
||||||
|
| 'action'
|
||||||
|
| 'allowFullScreen'
|
||||||
|
| 'allowTransparency'
|
||||||
|
| 'alt'
|
||||||
|
| 'as'
|
||||||
|
| 'autoComplete'
|
||||||
|
| 'autoFocus'
|
||||||
|
| 'autoPlay'
|
||||||
|
| 'capture'
|
||||||
|
| 'cellPadding'
|
||||||
|
| 'cellSpacing'
|
||||||
|
| 'charSet'
|
||||||
|
| 'challenge'
|
||||||
|
| 'checked'
|
||||||
|
| 'classID'
|
||||||
|
| 'cols'
|
||||||
|
| 'colSpan'
|
||||||
|
| 'controls'
|
||||||
|
| 'coords'
|
||||||
|
| 'crossOrigin'
|
||||||
|
| 'dateTime'
|
||||||
|
| 'download'
|
||||||
|
| 'encType'
|
||||||
|
| 'formAction'
|
||||||
|
| 'formEncType'
|
||||||
|
| 'formMethod'
|
||||||
|
| 'formNoValidate'
|
||||||
|
| 'formTarget'
|
||||||
|
| 'frameBorder'
|
||||||
|
| 'headers'
|
||||||
|
| 'href'
|
||||||
|
| 'hrefLang'
|
||||||
|
| 'htmlFor'
|
||||||
|
| 'httpEquiv'
|
||||||
|
| 'integrity'
|
||||||
|
| 'keyParams'
|
||||||
|
| 'keyType'
|
||||||
|
| 'kind'
|
||||||
|
| 'loop'
|
||||||
|
| 'marginHeight'
|
||||||
|
| 'marginWidth'
|
||||||
|
| 'maxLength'
|
||||||
|
| 'mediaGroup'
|
||||||
|
| 'method'
|
||||||
|
| 'min'
|
||||||
|
| 'minLength'
|
||||||
|
| 'muted'
|
||||||
|
| 'name'
|
||||||
|
| 'nonce'
|
||||||
|
| 'noValidate'
|
||||||
|
| 'optimum'
|
||||||
|
| 'placeholder'
|
||||||
|
| 'playsInline'
|
||||||
|
| 'poster'
|
||||||
|
| 'preload'
|
||||||
|
| 'readOnly'
|
||||||
|
| 'rel'
|
||||||
|
| 'reversed'
|
||||||
|
| 'rows'
|
||||||
|
| 'rowSpan'
|
||||||
|
| 'sandbox'
|
||||||
|
| 'scope'
|
||||||
|
| 'scoped'
|
||||||
|
| 'scrolling'
|
||||||
|
| 'seamless'
|
||||||
|
| 'selected'
|
||||||
|
| 'shape'
|
||||||
|
| 'sizes'
|
||||||
|
| 'srcDoc'
|
||||||
|
| 'srcLang'
|
||||||
|
| 'srcSet'
|
||||||
|
| 'target'
|
||||||
|
| 'type'
|
||||||
|
| 'useMap'
|
||||||
|
| 'value'
|
||||||
|
| 'wmode'
|
||||||
|
| 'defaultChecked'
|
||||||
|
| 'defaultValue'
|
||||||
|
| 'suppressContentEditableWarning'
|
||||||
|
| 'suppressHydrationWarning'
|
||||||
|
| 'accessKey'
|
||||||
|
| 'className'
|
||||||
|
| 'contentEditable'
|
||||||
|
| 'contextMenu'
|
||||||
|
| 'draggable'
|
||||||
|
| 'id'
|
||||||
|
| 'lang'
|
||||||
|
| 'spellCheck'
|
||||||
|
| 'tabIndex'
|
||||||
|
| 'radioGroup'
|
||||||
|
| 'role'
|
||||||
|
| 'about'
|
||||||
|
| 'datatype'
|
||||||
|
| 'inlist'
|
||||||
|
| 'property'
|
||||||
|
| 'resource'
|
||||||
|
| 'typeof'
|
||||||
|
| 'vocab'
|
||||||
|
| 'autoCapitalize'
|
||||||
|
| 'autoCorrect'
|
||||||
|
| 'autoSave'
|
||||||
|
| 'itemProp'
|
||||||
|
| 'itemScope'
|
||||||
|
| 'itemType'
|
||||||
|
| 'itemID'
|
||||||
|
| 'itemRef'
|
||||||
|
| 'results'
|
||||||
|
| 'security'
|
||||||
|
| 'unselectable'
|
||||||
|
| 'inputMode'
|
||||||
|
| 'is'
|
||||||
|
| 'aria-activedescendant'
|
||||||
|
| 'aria-atomic'
|
||||||
|
| 'aria-autocomplete'
|
||||||
|
| 'aria-busy'
|
||||||
|
| 'aria-checked'
|
||||||
|
| 'aria-colcount'
|
||||||
|
| 'aria-colindex'
|
||||||
|
| 'aria-colspan'
|
||||||
|
| 'aria-controls'
|
||||||
|
| 'aria-current'
|
||||||
|
| 'aria-describedby'
|
||||||
|
| 'aria-details'
|
||||||
|
| 'aria-disabled'
|
||||||
|
| 'aria-dropeffect'
|
||||||
|
| 'aria-errormessage'
|
||||||
|
| 'aria-expanded'
|
||||||
|
| 'aria-flowto'
|
||||||
|
| 'aria-grabbed'
|
||||||
|
| 'aria-haspopup'
|
||||||
|
| 'aria-hidden'
|
||||||
|
| 'aria-invalid'
|
||||||
|
| 'aria-keyshortcuts'
|
||||||
|
| 'aria-labelledby'
|
||||||
|
| 'aria-level'
|
||||||
|
| 'aria-live'
|
||||||
|
| 'aria-modal'
|
||||||
|
| 'aria-multiline'
|
||||||
|
| 'aria-multiselectable'
|
||||||
|
| 'aria-orientation'
|
||||||
|
| 'aria-owns'
|
||||||
|
| 'aria-placeholder'
|
||||||
|
| 'aria-posinset'
|
||||||
|
| 'aria-pressed'
|
||||||
|
| 'aria-readonly'
|
||||||
|
| 'aria-relevant'
|
||||||
|
| 'aria-required'
|
||||||
|
| 'aria-roledescription'
|
||||||
|
| 'aria-rowcount'
|
||||||
|
| 'aria-rowindex'
|
||||||
|
| 'aria-rowspan'
|
||||||
|
| 'aria-selected'
|
||||||
|
| 'aria-setsize'
|
||||||
|
| 'aria-sort'
|
||||||
|
| 'aria-valuemax'
|
||||||
|
| 'aria-valuemin'
|
||||||
|
| 'aria-valuenow'
|
||||||
|
| 'aria-valuetext'
|
||||||
|
| 'dangerouslySetInnerHTML'
|
||||||
|
| 'onCopy'
|
||||||
|
| 'onCopyCapture'
|
||||||
|
| 'onCut'
|
||||||
|
| 'onCutCapture'
|
||||||
|
| 'onPaste'
|
||||||
|
| 'onPasteCapture'
|
||||||
|
| 'onCompositionEnd'
|
||||||
|
| 'onCompositionEndCapture'
|
||||||
|
| 'onCompositionStart'
|
||||||
|
| 'onCompositionStartCapture'
|
||||||
|
| 'onCompositionUpdate'
|
||||||
|
| 'onCompositionUpdateCapture'
|
||||||
|
| 'onFocus'
|
||||||
|
| 'onFocusCapture'
|
||||||
|
| 'onBlur'
|
||||||
|
| 'onBlurCapture'
|
||||||
|
| 'onChange'
|
||||||
|
| 'onChangeCapture'
|
||||||
|
| 'onBeforeInput'
|
||||||
|
| 'onBeforeInputCapture'
|
||||||
|
| 'onInput'
|
||||||
|
| 'onInputCapture'
|
||||||
|
| 'onReset'
|
||||||
|
| 'onResetCapture'
|
||||||
|
| 'onSubmit'
|
||||||
|
| 'onSubmitCapture'
|
||||||
|
| 'onInvalid'
|
||||||
|
| 'onInvalidCapture'
|
||||||
|
| 'onLoad'
|
||||||
|
| 'onLoadCapture'
|
||||||
|
| 'onError'
|
||||||
|
| 'onErrorCapture'
|
||||||
|
| 'onKeyDown'
|
||||||
|
| 'onKeyDownCapture'
|
||||||
|
| 'onKeyPress'
|
||||||
|
| 'onKeyPressCapture'
|
||||||
|
| 'onKeyUp'
|
||||||
|
| 'onKeyUpCapture'
|
||||||
|
| 'onAbort'
|
||||||
|
| 'onAbortCapture'
|
||||||
|
| 'onCanPlay'
|
||||||
|
| 'onCanPlayCapture'
|
||||||
|
| 'onCanPlayThrough'
|
||||||
|
| 'onCanPlayThroughCapture'
|
||||||
|
| 'onDurationChange'
|
||||||
|
| 'onDurationChangeCapture'
|
||||||
|
| 'onEmptied'
|
||||||
|
| 'onEmptiedCapture'
|
||||||
|
| 'onEncrypted'
|
||||||
|
| 'onEncryptedCapture'
|
||||||
|
| 'onEnded'
|
||||||
|
| 'onEndedCapture'
|
||||||
|
| 'onLoadedData'
|
||||||
|
| 'onLoadedDataCapture'
|
||||||
|
| 'onLoadedMetadata'
|
||||||
|
| 'onLoadedMetadataCapture'
|
||||||
|
| 'onLoadStart'
|
||||||
|
| 'onLoadStartCapture'
|
||||||
|
| 'onPause'
|
||||||
|
| 'onPauseCapture'
|
||||||
|
| 'onPlay'
|
||||||
|
| 'onPlayCapture'
|
||||||
|
| 'onPlaying'
|
||||||
|
| 'onPlayingCapture'
|
||||||
|
| 'onProgress'
|
||||||
|
| 'onProgressCapture'
|
||||||
|
| 'onRateChange'
|
||||||
|
| 'onRateChangeCapture'
|
||||||
|
| 'onSeeked'
|
||||||
|
| 'onSeekedCapture'
|
||||||
|
| 'onSeeking'
|
||||||
|
| 'onSeekingCapture'
|
||||||
|
| 'onStalled'
|
||||||
|
| 'onStalledCapture'
|
||||||
|
| 'onSuspend'
|
||||||
|
| 'onSuspendCapture'
|
||||||
|
| 'onTimeUpdate'
|
||||||
|
| 'onTimeUpdateCapture'
|
||||||
|
| 'onVolumeChange'
|
||||||
|
| 'onVolumeChangeCapture'
|
||||||
|
| 'onWaiting'
|
||||||
|
| 'onWaitingCapture'
|
||||||
|
| 'onAuxClick'
|
||||||
|
| 'onAuxClickCapture'
|
||||||
|
| 'onClick'
|
||||||
|
| 'onClickCapture'
|
||||||
|
| 'onContextMenu'
|
||||||
|
| 'onContextMenuCapture'
|
||||||
|
| 'onDoubleClick'
|
||||||
|
| 'onDoubleClickCapture'
|
||||||
|
| 'onDrag'
|
||||||
|
| 'onDragCapture'
|
||||||
|
| 'onDragEnd'
|
||||||
|
| 'onDragEndCapture'
|
||||||
|
| 'onDragEnter'
|
||||||
|
| 'onDragEnterCapture'
|
||||||
|
| 'onDragExit'
|
||||||
|
| 'onDragExitCapture'
|
||||||
|
| 'onDragLeave'
|
||||||
|
| 'onDragLeaveCapture'
|
||||||
|
| 'onDragOver'
|
||||||
|
| 'onDragOverCapture'
|
||||||
|
| 'onDragStart'
|
||||||
|
| 'onDragStartCapture'
|
||||||
|
| 'onDrop'
|
||||||
|
| 'onDropCapture'
|
||||||
|
| 'onMouseDown'
|
||||||
|
| 'onMouseDownCapture'
|
||||||
|
| 'onMouseEnter'
|
||||||
|
| 'onMouseLeave'
|
||||||
|
| 'onMouseMove'
|
||||||
|
| 'onMouseMoveCapture'
|
||||||
|
| 'onMouseOut'
|
||||||
|
| 'onMouseOutCapture'
|
||||||
|
| 'onMouseOver'
|
||||||
|
| 'onMouseOverCapture'
|
||||||
|
| 'onMouseUp'
|
||||||
|
| 'onMouseUpCapture'
|
||||||
|
| 'onSelect'
|
||||||
|
| 'onSelectCapture'
|
||||||
|
| 'onTouchCancel'
|
||||||
|
| 'onTouchCancelCapture'
|
||||||
|
| 'onTouchEnd'
|
||||||
|
| 'onTouchEndCapture'
|
||||||
|
| 'onTouchMove'
|
||||||
|
| 'onTouchMoveCapture'
|
||||||
|
| 'onTouchStart'
|
||||||
|
| 'onTouchStartCapture'
|
||||||
|
| 'onPointerDown'
|
||||||
|
| 'onPointerDownCapture'
|
||||||
|
| 'onPointerMove'
|
||||||
|
| 'onPointerMoveCapture'
|
||||||
|
| 'onPointerUp'
|
||||||
|
| 'onPointerUpCapture'
|
||||||
|
| 'onPointerCancel'
|
||||||
|
| 'onPointerCancelCapture'
|
||||||
|
| 'onPointerEnter'
|
||||||
|
| 'onPointerEnterCapture'
|
||||||
|
| 'onPointerLeave'
|
||||||
|
| 'onPointerLeaveCapture'
|
||||||
|
| 'onPointerOver'
|
||||||
|
| 'onPointerOverCapture'
|
||||||
|
| 'onPointerOut'
|
||||||
|
| 'onPointerOutCapture'
|
||||||
|
| 'onGotPointerCapture'
|
||||||
|
| 'onGotPointerCaptureCapture'
|
||||||
|
| 'onLostPointerCapture'
|
||||||
|
| 'onLostPointerCaptureCapture'
|
||||||
|
| 'onScroll'
|
||||||
|
| 'onScrollCapture'
|
||||||
|
| 'onWheel'
|
||||||
|
| 'onWheelCapture'
|
||||||
|
| 'onAnimationStart'
|
||||||
|
| 'onAnimationStartCapture'
|
||||||
|
| 'onAnimationEnd'
|
||||||
|
| 'onAnimationEndCapture'
|
||||||
|
| 'onAnimationIteration'
|
||||||
|
| 'onAnimationIterationCapture'
|
||||||
|
| 'onTransitionEnd'
|
||||||
|
| 'onTransitionEndCapture'
|
||||||
|
| 'twoToneColor';
|
||||||
27
src/components/BasicPcShop/BasicComponents/Icon/index.tsx
Normal file
27
src/components/BasicPcShop/BasicComponents/Icon/index.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import React, { memo } from 'react';
|
||||||
|
import * as Icon from '@ant-design/icons';
|
||||||
|
import IconImg from 'assets/icon.png';
|
||||||
|
import { AntdIconProps } from '@ant-design/icons/lib/components/AntdIcon';
|
||||||
|
import { AntdIconType } from './icon';
|
||||||
|
import { IIconConfig } from './schema';
|
||||||
|
|
||||||
|
interface IconType extends IIconConfig {
|
||||||
|
isTpl?: boolean;
|
||||||
|
}
|
||||||
|
const XIcon = memo((props: IconType) => {
|
||||||
|
const { color, size, type, spin, isTpl } = props;
|
||||||
|
|
||||||
|
const MyIcon: React.ForwardRefExoticComponent<Pick<AntdIconProps, AntdIconType> &
|
||||||
|
React.RefAttributes<HTMLSpanElement>> = Icon[type];
|
||||||
|
|
||||||
|
return isTpl ? (
|
||||||
|
<div style={{ textAlign: 'center' }}>
|
||||||
|
<img style={{ verticalAlign: '-20px', width: '82px' }} src={IconImg} alt={type} />
|
||||||
|
图标
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<MyIcon twoToneColor={color} style={{ fontSize: size }} spin={spin} />
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default XIcon;
|
||||||
144
src/components/BasicPcShop/BasicComponents/Icon/schema.ts
Normal file
144
src/components/BasicPcShop/BasicComponents/Icon/schema.ts
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
import {
|
||||||
|
ICardPickerConfigType,
|
||||||
|
IColorConfigType,
|
||||||
|
INumberConfigType,
|
||||||
|
ISwitchConfigType,
|
||||||
|
TCardPickerDefaultType,
|
||||||
|
TColorDefaultType,
|
||||||
|
TNumberDefaultType,
|
||||||
|
TSwitchDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
|
||||||
|
export type TIconEditData = Array<
|
||||||
|
IColorConfigType | INumberConfigType | ISwitchConfigType | ICardPickerConfigType<IconTypes>
|
||||||
|
>;
|
||||||
|
export interface IIconConfig {
|
||||||
|
color: TColorDefaultType;
|
||||||
|
size: TNumberDefaultType;
|
||||||
|
spin: TSwitchDefaultType;
|
||||||
|
type: TCardPickerDefaultType<IconTypes>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IIconSchema {
|
||||||
|
editData: TIconEditData;
|
||||||
|
config: IIconConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IconTypes =
|
||||||
|
| 'AccountBookTwoTone'
|
||||||
|
| 'AlertTwoTone'
|
||||||
|
| 'ApiTwoTone'
|
||||||
|
| 'AppstoreTwoTone'
|
||||||
|
| 'AudioTwoTone'
|
||||||
|
| 'BankTwoTone'
|
||||||
|
| 'BellTwoTone'
|
||||||
|
| 'BookTwoTone'
|
||||||
|
| 'BugTwoTone'
|
||||||
|
| 'BuildTwoTone'
|
||||||
|
| 'BulbTwoTone'
|
||||||
|
| 'CalculatorTwoTone'
|
||||||
|
| 'CalendarTwoTone'
|
||||||
|
| 'CameraTwoTone'
|
||||||
|
| 'CarTwoTone'
|
||||||
|
| 'CarryOutTwoTone'
|
||||||
|
| 'CiCircleTwoTone'
|
||||||
|
| 'CloudTwoTone'
|
||||||
|
| 'CodeTwoTone'
|
||||||
|
| 'CrownTwoTone'
|
||||||
|
| 'CustomerServiceTwoTone'
|
||||||
|
| 'DollarCircleTwoTone'
|
||||||
|
| 'EnvironmentTwoTone'
|
||||||
|
| 'ExperimentTwoTone'
|
||||||
|
| 'FireTwoTone'
|
||||||
|
| 'GiftTwoTone'
|
||||||
|
| 'InsuranceTwoTone'
|
||||||
|
| 'LikeTwoTone'
|
||||||
|
| 'LockTwoTone'
|
||||||
|
| 'MailTwoTone'
|
||||||
|
| 'MessageTwoTone'
|
||||||
|
| 'PhoneTwoTone'
|
||||||
|
| 'PictureTwoTone'
|
||||||
|
| 'PlaySquareTwoTone'
|
||||||
|
| 'RedEnvelopeTwoTone'
|
||||||
|
| 'ShopTwoTone'
|
||||||
|
| 'TrademarkCircleTwoTone'
|
||||||
|
| 'StarTwoTone'
|
||||||
|
| 'SafetyCertificateTwoTone'
|
||||||
|
| 'SettingTwoTone'
|
||||||
|
| 'RocketTwoTone';
|
||||||
|
|
||||||
|
const Icon: IIconSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'color',
|
||||||
|
name: '颜色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'size',
|
||||||
|
name: '大小',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'spin',
|
||||||
|
name: '旋转动画',
|
||||||
|
type: 'Switch',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'type',
|
||||||
|
name: '图标类型',
|
||||||
|
type: 'CardPicker',
|
||||||
|
icons: [
|
||||||
|
'AccountBookTwoTone',
|
||||||
|
'AlertTwoTone',
|
||||||
|
'ApiTwoTone',
|
||||||
|
'AppstoreTwoTone',
|
||||||
|
'AudioTwoTone',
|
||||||
|
'BankTwoTone',
|
||||||
|
'BellTwoTone',
|
||||||
|
'BookTwoTone',
|
||||||
|
'BugTwoTone',
|
||||||
|
'BuildTwoTone',
|
||||||
|
'BulbTwoTone',
|
||||||
|
'CalculatorTwoTone',
|
||||||
|
'CalendarTwoTone',
|
||||||
|
'CameraTwoTone',
|
||||||
|
'CarTwoTone',
|
||||||
|
'CarryOutTwoTone',
|
||||||
|
'CiCircleTwoTone',
|
||||||
|
'CloudTwoTone',
|
||||||
|
'CodeTwoTone',
|
||||||
|
'CrownTwoTone',
|
||||||
|
'CustomerServiceTwoTone',
|
||||||
|
'DollarCircleTwoTone',
|
||||||
|
'EnvironmentTwoTone',
|
||||||
|
'ExperimentTwoTone',
|
||||||
|
'FireTwoTone',
|
||||||
|
'GiftTwoTone',
|
||||||
|
'InsuranceTwoTone',
|
||||||
|
'LikeTwoTone',
|
||||||
|
'LockTwoTone',
|
||||||
|
'MailTwoTone',
|
||||||
|
'MessageTwoTone',
|
||||||
|
'PhoneTwoTone',
|
||||||
|
'PictureTwoTone',
|
||||||
|
'PlaySquareTwoTone',
|
||||||
|
'RedEnvelopeTwoTone',
|
||||||
|
'ShopTwoTone',
|
||||||
|
'TrademarkCircleTwoTone',
|
||||||
|
'StarTwoTone',
|
||||||
|
'SafetyCertificateTwoTone',
|
||||||
|
'SettingTwoTone',
|
||||||
|
'RocketTwoTone',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
color: 'rgba(74,144,226,1)',
|
||||||
|
size: 36,
|
||||||
|
spin: false,
|
||||||
|
type: 'CarTwoTone',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Icon;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'Icon',
|
||||||
|
h: 23,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
12
src/components/BasicPcShop/BasicComponents/Image/index.tsx
Normal file
12
src/components/BasicPcShop/BasicComponents/Image/index.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import React, { memo } from 'react';
|
||||||
|
import { IImageConfig } from './schema';
|
||||||
|
const Image = memo((props: IImageConfig) => {
|
||||||
|
const { imgUrl, round = 0 } = props;
|
||||||
|
return (
|
||||||
|
<div style={{ borderRadius: round, width: '100%', textAlign: 'center', overflow: 'hidden' }}>
|
||||||
|
<img src={imgUrl && imgUrl[0].url} alt="" style={{ width: '100%' }} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Image;
|
||||||
46
src/components/BasicPcShop/BasicComponents/Image/schema.ts
Normal file
46
src/components/BasicPcShop/BasicComponents/Image/schema.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import {
|
||||||
|
INumberConfigType,
|
||||||
|
IUploadConfigType,
|
||||||
|
TNumberDefaultType,
|
||||||
|
TUploadDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
|
||||||
|
export type TImageEditData = Array<IUploadConfigType | INumberConfigType>;
|
||||||
|
export interface IImageConfig {
|
||||||
|
imgUrl: TUploadDefaultType;
|
||||||
|
round: TNumberDefaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IImageSchema {
|
||||||
|
editData: TImageEditData;
|
||||||
|
config: IImageConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Image: IImageSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'imgUrl',
|
||||||
|
name: '上传',
|
||||||
|
type: 'Upload',
|
||||||
|
isCrop: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'round',
|
||||||
|
name: '圆角',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
imgUrl: [
|
||||||
|
{
|
||||||
|
uid: '001',
|
||||||
|
name: 'image.png',
|
||||||
|
status: 'done',
|
||||||
|
url: 'http://io.nainor.com/uploads/4_1740bf4535c.png',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
round: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Image;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'Image',
|
||||||
|
h: 188,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
19
src/components/BasicPcShop/BasicComponents/List/index.less
Normal file
19
src/components/BasicPcShop/BasicComponents/List/index.less
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
.list {
|
||||||
|
margin: 20px auto;
|
||||||
|
width: 94%;
|
||||||
|
.sourceList {
|
||||||
|
.sourceItem {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
.imgWrap {
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
margin-left: 12px;
|
||||||
|
.tit {
|
||||||
|
line-height: 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
51
src/components/BasicPcShop/BasicComponents/List/index.tsx
Normal file
51
src/components/BasicPcShop/BasicComponents/List/index.tsx
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import React, { memo } from 'react';
|
||||||
|
import styles from './index.less';
|
||||||
|
import { IListConfig } from './schema';
|
||||||
|
const List = memo((props: IListConfig) => {
|
||||||
|
const { round, sourceData, imgSize, fontSize, color } = props;
|
||||||
|
return (
|
||||||
|
<div className={styles.list}>
|
||||||
|
<div className={styles.sourceList}>
|
||||||
|
{sourceData.map((item, i) => {
|
||||||
|
return (
|
||||||
|
<div className={styles.sourceItem} key={i}>
|
||||||
|
<div className={styles.imgWrap}>
|
||||||
|
<img
|
||||||
|
src={
|
||||||
|
item.imgUrl[0]
|
||||||
|
? item.imgUrl[0].url
|
||||||
|
: 'http://io.nainor.com/uploads/01_173e15d3493.png'
|
||||||
|
}
|
||||||
|
alt={item.desc}
|
||||||
|
style={{
|
||||||
|
width: parseFloat(imgSize),
|
||||||
|
height: imgSize,
|
||||||
|
objectFit: 'cover',
|
||||||
|
borderRadius: round,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className={styles.content}>
|
||||||
|
<a
|
||||||
|
className={styles.tit}
|
||||||
|
style={{ fontSize, color }}
|
||||||
|
href={item.link ? item.link : '#'}
|
||||||
|
>
|
||||||
|
{item.title}
|
||||||
|
<div
|
||||||
|
className={styles.desc}
|
||||||
|
style={{ fontSize: fontSize * 0.8, color: 'rgba(0,0,0, .3)' }}
|
||||||
|
>
|
||||||
|
{item.desc}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default List;
|
||||||
116
src/components/BasicPcShop/BasicComponents/List/schema.ts
Normal file
116
src/components/BasicPcShop/BasicComponents/List/schema.ts
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import {
|
||||||
|
IColorConfigType,
|
||||||
|
IDataListConfigType,
|
||||||
|
INumberConfigType,
|
||||||
|
ISelectConfigType,
|
||||||
|
TColorDefaultType,
|
||||||
|
TDataListDefaultType,
|
||||||
|
TNumberDefaultType,
|
||||||
|
TSelectDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
export type TListSelectKeyType = '60' | '80' | '100' | '120' | '150';
|
||||||
|
export type TListEditData = Array<
|
||||||
|
IColorConfigType | IDataListConfigType | INumberConfigType | ISelectConfigType<TListSelectKeyType>
|
||||||
|
>;
|
||||||
|
export interface IListConfig {
|
||||||
|
sourceData: TDataListDefaultType;
|
||||||
|
round: TNumberDefaultType;
|
||||||
|
imgSize: TSelectDefaultType<TListSelectKeyType>;
|
||||||
|
fontSize: TNumberDefaultType;
|
||||||
|
color: TColorDefaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IListSchema {
|
||||||
|
editData: TListEditData;
|
||||||
|
config: IListConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const List: IListSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'sourceData',
|
||||||
|
name: '数据源',
|
||||||
|
type: 'DataList',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'round',
|
||||||
|
name: '圆角',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'imgSize',
|
||||||
|
name: '图片大小',
|
||||||
|
type: 'Select',
|
||||||
|
range: [
|
||||||
|
{
|
||||||
|
key: '60',
|
||||||
|
text: '60 x 60',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '80',
|
||||||
|
text: '80 x 80',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '100',
|
||||||
|
text: '100 x 100',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '120',
|
||||||
|
text: '120 x 120',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '150',
|
||||||
|
text: '150 x 150',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'fontSize',
|
||||||
|
name: '文字大小',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'color',
|
||||||
|
name: '文字颜色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
sourceData: [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
title: '趣谈小课',
|
||||||
|
desc: '致力于打造优质小课程',
|
||||||
|
link: 'xxxxx',
|
||||||
|
imgUrl: [
|
||||||
|
{
|
||||||
|
uid: '001',
|
||||||
|
name: 'image.png',
|
||||||
|
status: 'done',
|
||||||
|
url: 'http://io.nainor.com/uploads/1_1740c6fbcd9.png',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
title: '趣谈小课',
|
||||||
|
desc: '致力于打造优质小课程',
|
||||||
|
link: 'xxxxx',
|
||||||
|
imgUrl: [
|
||||||
|
{
|
||||||
|
uid: '002',
|
||||||
|
name: 'image.png',
|
||||||
|
status: 'done',
|
||||||
|
url: 'http://io.nainor.com/uploads/1_1740c6fbcd9.png',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
round: 0,
|
||||||
|
imgSize: '80',
|
||||||
|
fontSize: 16,
|
||||||
|
color: 'rgba(153,153,153,1)',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default List;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'List',
|
||||||
|
h: 110,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
import React, { memo } from 'react';
|
||||||
|
import styles from './index.less';
|
||||||
|
import { ILongTextConfig } from './schema';
|
||||||
|
const LongText = memo((props: ILongTextConfig) => {
|
||||||
|
const { text, fontSize, color, indent, lineHeight, textAlign } = props;
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={styles.textWrap}
|
||||||
|
style={{ color, textIndent: indent + 'px', fontSize, lineHeight, textAlign }}
|
||||||
|
>
|
||||||
|
{text}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
export default LongText;
|
||||||
@ -0,0 +1,92 @@
|
|||||||
|
import {
|
||||||
|
IColorConfigType,
|
||||||
|
INumberConfigType,
|
||||||
|
ISelectConfigType,
|
||||||
|
ITextAreaConfigType,
|
||||||
|
TColorDefaultType,
|
||||||
|
TNumberDefaultType,
|
||||||
|
TSelectDefaultType,
|
||||||
|
TTextAreaDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
export type TLongTextSelectKeyType = 'left' | 'center' | 'right';
|
||||||
|
|
||||||
|
export type TLongTextEditData = Array<
|
||||||
|
| ITextAreaConfigType
|
||||||
|
| IColorConfigType
|
||||||
|
| INumberConfigType
|
||||||
|
| ISelectConfigType<TLongTextSelectKeyType>
|
||||||
|
>;
|
||||||
|
export interface ILongTextConfig {
|
||||||
|
text: TTextAreaDefaultType;
|
||||||
|
color: TColorDefaultType;
|
||||||
|
fontSize: TNumberDefaultType;
|
||||||
|
indent: TNumberDefaultType;
|
||||||
|
lineHeight: TNumberDefaultType;
|
||||||
|
textAlign: TSelectDefaultType<TLongTextSelectKeyType>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ILongTextSchema {
|
||||||
|
editData: TLongTextEditData;
|
||||||
|
config: ILongTextConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LongText: ILongTextSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'text',
|
||||||
|
name: '文字',
|
||||||
|
type: 'TextArea',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'color',
|
||||||
|
name: '标题颜色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'fontSize',
|
||||||
|
name: '字体大小',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'indent',
|
||||||
|
name: '首行缩进',
|
||||||
|
type: 'Number',
|
||||||
|
range: [0, 100],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'textAlign',
|
||||||
|
name: '对齐方式',
|
||||||
|
type: 'Select',
|
||||||
|
range: [
|
||||||
|
{
|
||||||
|
key: 'left',
|
||||||
|
text: '左对齐',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'center',
|
||||||
|
text: '居中对齐',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'right',
|
||||||
|
text: '右对齐',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'lineHeight',
|
||||||
|
name: '行高',
|
||||||
|
type: 'Number',
|
||||||
|
step: 0.1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
text: '我是长文本有一段故事,dooring可视化编辑器无限可能,赶快来体验吧,骚年们,奥利给~',
|
||||||
|
color: 'rgba(60,60,60,1)',
|
||||||
|
fontSize: 14,
|
||||||
|
indent: 20,
|
||||||
|
lineHeight: 1.8,
|
||||||
|
textAlign: 'left',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LongText;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'LongText',
|
||||||
|
h: 36,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
14
src/components/BasicPcShop/BasicComponents/Qrcode/index.tsx
Normal file
14
src/components/BasicPcShop/BasicComponents/Qrcode/index.tsx
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import React, { memo } from 'react';
|
||||||
|
import { IQrcodeConfig } from './schema';
|
||||||
|
|
||||||
|
const Qrcode = memo((props: IQrcodeConfig) => {
|
||||||
|
const { qrcode, text, color, fontSize = 14 } = props;
|
||||||
|
return (
|
||||||
|
<div style={{ width: '240px', margin: '16px auto' }}>
|
||||||
|
<img src={qrcode && qrcode[0].url} alt={text} style={{ width: '100%' }} />
|
||||||
|
<div style={{ textAlign: 'center', color, fontSize, paddingTop: '8px' }}>{text}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Qrcode;
|
||||||
67
src/components/BasicPcShop/BasicComponents/Qrcode/schema.ts
Normal file
67
src/components/BasicPcShop/BasicComponents/Qrcode/schema.ts
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import {
|
||||||
|
IColorConfigType,
|
||||||
|
INumberConfigType,
|
||||||
|
ITextConfigType,
|
||||||
|
IUploadConfigType,
|
||||||
|
TColorDefaultType,
|
||||||
|
TNumberDefaultType,
|
||||||
|
TTextDefaultType,
|
||||||
|
TUploadDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
|
||||||
|
export type TQrcodeEditData = Array<
|
||||||
|
IUploadConfigType | ITextConfigType | IColorConfigType | INumberConfigType
|
||||||
|
>;
|
||||||
|
export interface IQrcodeConfig {
|
||||||
|
qrcode: TUploadDefaultType;
|
||||||
|
text: TTextDefaultType;
|
||||||
|
color: TColorDefaultType;
|
||||||
|
fontSize: TNumberDefaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IQrcodeSchema {
|
||||||
|
editData: TQrcodeEditData;
|
||||||
|
config: IQrcodeConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Qrcode: IQrcodeSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'qrcode',
|
||||||
|
name: '二维码',
|
||||||
|
type: 'Upload',
|
||||||
|
isCrop: true,
|
||||||
|
cropRate: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'text',
|
||||||
|
name: '文字',
|
||||||
|
type: 'Text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'color',
|
||||||
|
name: '文字颜色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'fontSize',
|
||||||
|
name: '文字大小',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
qrcode: [
|
||||||
|
{
|
||||||
|
uid: '001',
|
||||||
|
name: 'image.png',
|
||||||
|
status: 'done',
|
||||||
|
url: 'http://io.nainor.com/uploads/code_173e1705e0c.png',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
text: '二维码',
|
||||||
|
color: 'rgba(153,153,153,1)',
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Qrcode;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'Qrcode',
|
||||||
|
h: 150,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
13
src/components/BasicPcShop/BasicComponents/Text/index.tsx
Normal file
13
src/components/BasicPcShop/BasicComponents/Text/index.tsx
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import React, { memo } from 'react';
|
||||||
|
import styles from './index.less';
|
||||||
|
import { ITextConfig } from './schema';
|
||||||
|
|
||||||
|
const Text = memo((props: ITextConfig) => {
|
||||||
|
const { align, text, fontSize, color, lineHeight } = props;
|
||||||
|
return (
|
||||||
|
<div className={styles.textWrap} style={{ color, textAlign: align, fontSize, lineHeight }}>
|
||||||
|
{text}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
export default Text;
|
||||||
78
src/components/BasicPcShop/BasicComponents/Text/schema.ts
Normal file
78
src/components/BasicPcShop/BasicComponents/Text/schema.ts
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import {
|
||||||
|
IColorConfigType,
|
||||||
|
INumberConfigType,
|
||||||
|
ISelectConfigType,
|
||||||
|
ITextConfigType,
|
||||||
|
TColorDefaultType,
|
||||||
|
TNumberDefaultType,
|
||||||
|
TSelectDefaultType,
|
||||||
|
TTextDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
|
||||||
|
export type TTextSelectKeyType = 'left' | 'right' | 'center';
|
||||||
|
export type TTextEditData = Array<
|
||||||
|
ITextConfigType | IColorConfigType | INumberConfigType | ISelectConfigType<TTextSelectKeyType>
|
||||||
|
>;
|
||||||
|
export interface ITextConfig {
|
||||||
|
text: TTextDefaultType;
|
||||||
|
color: TColorDefaultType;
|
||||||
|
fontSize: TNumberDefaultType;
|
||||||
|
align: TSelectDefaultType<TTextSelectKeyType>;
|
||||||
|
lineHeight: TNumberDefaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ITextSchema {
|
||||||
|
editData: TTextEditData;
|
||||||
|
config: ITextConfig;
|
||||||
|
}
|
||||||
|
const Text: ITextSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'text',
|
||||||
|
name: '文字',
|
||||||
|
type: 'Text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'color',
|
||||||
|
name: '标题颜色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'fontSize',
|
||||||
|
name: '字体大小',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'align',
|
||||||
|
name: '对齐方式',
|
||||||
|
type: 'Select',
|
||||||
|
range: [
|
||||||
|
{
|
||||||
|
key: 'left',
|
||||||
|
text: '左对齐',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'center',
|
||||||
|
text: '居中对齐',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'right',
|
||||||
|
text: '右对齐',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'lineHeight',
|
||||||
|
name: '行高',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
text: '我是文本',
|
||||||
|
color: 'rgba(60,60,60,1)',
|
||||||
|
fontSize: 18,
|
||||||
|
align: 'center',
|
||||||
|
lineHeight: 2,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export default Text;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'Text',
|
||||||
|
h: 20,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
20
src/components/BasicPcShop/BasicComponents/schema.ts
Normal file
20
src/components/BasicPcShop/BasicComponents/schema.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import Footer from './Footer/schema';
|
||||||
|
import Header from './Header/schema';
|
||||||
|
import Icon from './Icon/schema';
|
||||||
|
import Image from './Image/schema';
|
||||||
|
import List from './List/schema';
|
||||||
|
import LongText from './LongText/schema';
|
||||||
|
import Qrcode from './Qrcode/schema';
|
||||||
|
import Text from './Text/schema';
|
||||||
|
|
||||||
|
const basicSchema = {
|
||||||
|
Footer,
|
||||||
|
Header,
|
||||||
|
Icon,
|
||||||
|
Image,
|
||||||
|
List,
|
||||||
|
LongText,
|
||||||
|
Qrcode,
|
||||||
|
Text
|
||||||
|
};
|
||||||
|
export default basicSchema;
|
||||||
24
src/components/BasicPcShop/BasicComponents/template.ts
Normal file
24
src/components/BasicPcShop/BasicComponents/template.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import Footer from './Footer/template';
|
||||||
|
import Header from './Header/template';
|
||||||
|
import Icon from './Icon/template';
|
||||||
|
import Image from './Image/template';
|
||||||
|
import List from './List/template';
|
||||||
|
import LongText from './LongText/template';
|
||||||
|
import Qrcode from './Qrcode/template';
|
||||||
|
import Text from './Text/template';
|
||||||
|
|
||||||
|
const basicTemplate = [
|
||||||
|
Footer,
|
||||||
|
Header,
|
||||||
|
Icon,
|
||||||
|
Image,
|
||||||
|
List,
|
||||||
|
LongText,
|
||||||
|
Qrcode,
|
||||||
|
Text,
|
||||||
|
];
|
||||||
|
const BasicTemplate = basicTemplate.map(v => {
|
||||||
|
return { ...v, category: 'base' };
|
||||||
|
});
|
||||||
|
|
||||||
|
export default BasicTemplate;
|
||||||
1049
src/components/BasicPcShop/MediaComponents/Video/index.css
Normal file
1049
src/components/BasicPcShop/MediaComponents/Video/index.css
Normal file
File diff suppressed because one or more lines are too long
21
src/components/BasicPcShop/MediaComponents/Video/index.tsx
Normal file
21
src/components/BasicPcShop/MediaComponents/Video/index.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import React, { memo } from 'react';
|
||||||
|
import { Player, BigPlayButton } from 'video-react';
|
||||||
|
import './index.css';
|
||||||
|
import { IVideoConfig } from './schema';
|
||||||
|
|
||||||
|
const VideoPlayer = memo((props: IVideoConfig) => {
|
||||||
|
const { poster, url } = props;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Player
|
||||||
|
playsInline
|
||||||
|
poster={poster[0].url}
|
||||||
|
src={url || 'https://gossv.vcg.com/cmsUploadVideo/creative/1移轴/7月移轴.mp4'}
|
||||||
|
>
|
||||||
|
<BigPlayButton position="center" />
|
||||||
|
</Player>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default VideoPlayer;
|
||||||
45
src/components/BasicPcShop/MediaComponents/Video/schema.ts
Normal file
45
src/components/BasicPcShop/MediaComponents/Video/schema.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import {
|
||||||
|
ITextConfigType,
|
||||||
|
IUploadConfigType,
|
||||||
|
TTextDefaultType,
|
||||||
|
TUploadDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
|
||||||
|
export type TVideoEditData = Array<IUploadConfigType | ITextConfigType>;
|
||||||
|
export interface IVideoConfig {
|
||||||
|
poster: TUploadDefaultType;
|
||||||
|
url: TTextDefaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IVideoSchema {
|
||||||
|
editData: TVideoEditData;
|
||||||
|
config: IVideoConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Video: IVideoSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'poster',
|
||||||
|
name: '视频封面',
|
||||||
|
type: 'Upload',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'url',
|
||||||
|
name: '视频链接',
|
||||||
|
type: 'Text',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
poster: [
|
||||||
|
{
|
||||||
|
uid: '001',
|
||||||
|
name: 'image.png',
|
||||||
|
status: 'done',
|
||||||
|
url: 'http://io.nainor.com/uploads/1_1740c6fbcd9.png',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
url: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Video;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'Video',
|
||||||
|
h: 107,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
6
src/components/BasicPcShop/MediaComponents/schema.ts
Normal file
6
src/components/BasicPcShop/MediaComponents/schema.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import Video from './Video/schema';
|
||||||
|
|
||||||
|
const mediaSchema = {
|
||||||
|
Video,
|
||||||
|
};
|
||||||
|
export default mediaSchema;
|
||||||
9
src/components/BasicPcShop/MediaComponents/template.ts
Normal file
9
src/components/BasicPcShop/MediaComponents/template.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import Video from './Video/template';
|
||||||
|
|
||||||
|
const mediaTemplate = [Video];
|
||||||
|
|
||||||
|
const MediaTemplate = mediaTemplate.map(v => {
|
||||||
|
return { ...v, category: 'media' };
|
||||||
|
});
|
||||||
|
|
||||||
|
export default MediaTemplate;
|
||||||
13
src/components/BasicPcShop/VisualComponents/Area/index.less
Normal file
13
src/components/BasicPcShop/VisualComponents/Area/index.less
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
.chartWrap {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
.chartTitle {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
canvas {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
76
src/components/BasicPcShop/VisualComponents/Area/index.tsx
Normal file
76
src/components/BasicPcShop/VisualComponents/Area/index.tsx
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import { Chart } from '@antv/f2';
|
||||||
|
import React, { memo, useEffect, useRef } from 'react';
|
||||||
|
// import { uuid } from 'utils/tool';
|
||||||
|
import AreaImg from '@/assets/area.png';
|
||||||
|
|
||||||
|
import styles from './index.less';
|
||||||
|
import { IChartConfig } from './schema';
|
||||||
|
|
||||||
|
interface XChartProps extends IChartConfig {
|
||||||
|
isTpl: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const XLine = (props: XChartProps) => {
|
||||||
|
const { isTpl, data, color, size, paddingTop, title } = props;
|
||||||
|
const chartRef = useRef(null);
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isTpl) {
|
||||||
|
const chart = new Chart({
|
||||||
|
el: chartRef.current || undefined,
|
||||||
|
pixelRatio: window.devicePixelRatio, // 指定分辨率
|
||||||
|
});
|
||||||
|
|
||||||
|
// step 2: 处理数据
|
||||||
|
const dataX = data.map(item => ({ ...item, value: Number(item.value), a: '1' }));
|
||||||
|
|
||||||
|
// Step 2: 载入数据源
|
||||||
|
chart.source(dataX, {
|
||||||
|
percent: {
|
||||||
|
formatter: function formatter(val) {
|
||||||
|
return val * 100 + '%';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
chart.tooltip({
|
||||||
|
showCrosshairs: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
chart.scale({
|
||||||
|
name: {
|
||||||
|
range: [0, 1],
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
tickCount: 5,
|
||||||
|
min: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
chart.axis('name', {
|
||||||
|
label: function label(text, index, total) {
|
||||||
|
const textCfg: any = {};
|
||||||
|
if (index === 0) {
|
||||||
|
textCfg.textAlign = 'left';
|
||||||
|
} else if (index === total - 1) {
|
||||||
|
textCfg.textAlign = 'right';
|
||||||
|
}
|
||||||
|
return textCfg;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
chart.area().position('name*value');
|
||||||
|
chart.line().position('name*value');
|
||||||
|
chart.render();
|
||||||
|
}
|
||||||
|
}, [data, isTpl]);
|
||||||
|
return (
|
||||||
|
<div className={styles.chartWrap}>
|
||||||
|
<div className={styles.chartTitle} style={{ color, fontSize: size, paddingTop }}>
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
{isTpl ? <img src={AreaImg} alt="dooring chart" /> : <canvas ref={chartRef}></canvas>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(XLine);
|
||||||
82
src/components/BasicPcShop/VisualComponents/Area/schema.ts
Normal file
82
src/components/BasicPcShop/VisualComponents/Area/schema.ts
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import {
|
||||||
|
IColorConfigType,
|
||||||
|
INumberConfigType,
|
||||||
|
ITableConfigType,
|
||||||
|
ITextConfigType,
|
||||||
|
TColorDefaultType,
|
||||||
|
TNumberDefaultType,
|
||||||
|
TTableDefaultType,
|
||||||
|
TTextDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
|
||||||
|
export type TChartEditData = Array<
|
||||||
|
ITextConfigType | INumberConfigType | IColorConfigType | ITableConfigType
|
||||||
|
>;
|
||||||
|
export interface IChartConfig {
|
||||||
|
title: TTextDefaultType;
|
||||||
|
size: TNumberDefaultType;
|
||||||
|
color: TColorDefaultType;
|
||||||
|
paddingTop: TNumberDefaultType;
|
||||||
|
data: TTableDefaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IChartSchema {
|
||||||
|
editData: TChartEditData;
|
||||||
|
config: IChartConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Chart: IChartSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'title',
|
||||||
|
name: '标题',
|
||||||
|
type: 'Text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'size',
|
||||||
|
name: '标题大小',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'color',
|
||||||
|
name: '标题颜色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'paddingTop',
|
||||||
|
name: '上边距',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'data',
|
||||||
|
name: '数据源',
|
||||||
|
type: 'Table',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
title: '面积图',
|
||||||
|
size: 14,
|
||||||
|
color: 'rgba(0,0,0,1)',
|
||||||
|
paddingTop: 10,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
name: 'A',
|
||||||
|
value: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'B',
|
||||||
|
value: 60,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'C',
|
||||||
|
value: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'D',
|
||||||
|
value: 80,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Chart;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'Area',
|
||||||
|
h: 108,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
13
src/components/BasicPcShop/VisualComponents/Chart/index.less
Normal file
13
src/components/BasicPcShop/VisualComponents/Chart/index.less
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
.chartWrap {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
.chartTitle {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
canvas {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
49
src/components/BasicPcShop/VisualComponents/Chart/index.tsx
Normal file
49
src/components/BasicPcShop/VisualComponents/Chart/index.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { Chart } from '@antv/f2';
|
||||||
|
import React, { memo, useEffect, useRef } from 'react';
|
||||||
|
// import { uuid } from 'utils/tool';
|
||||||
|
import ChartImg from '@/assets/chart.png';
|
||||||
|
|
||||||
|
import styles from './index.less';
|
||||||
|
import { IChartConfig } from './schema';
|
||||||
|
|
||||||
|
interface XChartProps extends IChartConfig {
|
||||||
|
isTpl: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const XChart = (props: XChartProps) => {
|
||||||
|
const { isTpl, data, color, size, paddingTop, title } = props;
|
||||||
|
const chartRef = useRef(null);
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isTpl) {
|
||||||
|
const chart = new Chart({
|
||||||
|
el: chartRef.current || undefined,
|
||||||
|
pixelRatio: window.devicePixelRatio, // 指定分辨率
|
||||||
|
});
|
||||||
|
|
||||||
|
// step 2: 处理数据
|
||||||
|
const dataX = data.map(item => ({ ...item, value: Number(item.value) }));
|
||||||
|
|
||||||
|
// Step 2: 载入数据源
|
||||||
|
chart.source(dataX);
|
||||||
|
|
||||||
|
// Step 3:创建图形语法,绘制柱状图,由 genre 和 sold 两个属性决定图形位置,genre 映射至 x 轴,sold 映射至 y 轴
|
||||||
|
chart
|
||||||
|
.interval()
|
||||||
|
.position('name*value')
|
||||||
|
.color('name');
|
||||||
|
|
||||||
|
// Step 4: 渲染图表
|
||||||
|
chart.render();
|
||||||
|
}
|
||||||
|
}, [data, isTpl]);
|
||||||
|
return (
|
||||||
|
<div className={styles.chartWrap}>
|
||||||
|
<div className={styles.chartTitle} style={{ color, fontSize: size, paddingTop }}>
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
{isTpl ? <img src={ChartImg} alt="dooring chart" /> : <canvas ref={chartRef}></canvas>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(XChart);
|
||||||
78
src/components/BasicPcShop/VisualComponents/Chart/schema.ts
Normal file
78
src/components/BasicPcShop/VisualComponents/Chart/schema.ts
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import {
|
||||||
|
IColorConfigType,
|
||||||
|
INumberConfigType,
|
||||||
|
ITableConfigType,
|
||||||
|
ITextConfigType,
|
||||||
|
TColorDefaultType,
|
||||||
|
TNumberDefaultType,
|
||||||
|
TTableDefaultType,
|
||||||
|
TTextDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
|
||||||
|
export type TChartEditData = Array<
|
||||||
|
ITextConfigType | INumberConfigType | IColorConfigType | ITableConfigType
|
||||||
|
>;
|
||||||
|
export interface IChartConfig {
|
||||||
|
title: TTextDefaultType;
|
||||||
|
size: TNumberDefaultType;
|
||||||
|
color: TColorDefaultType;
|
||||||
|
paddingTop: TNumberDefaultType;
|
||||||
|
data: TTableDefaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IChartSchema {
|
||||||
|
editData: TChartEditData;
|
||||||
|
config: IChartConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Chart: IChartSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'title',
|
||||||
|
name: '标题',
|
||||||
|
type: 'Text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'size',
|
||||||
|
name: '标题大小',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'color',
|
||||||
|
name: '标题颜色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'paddingTop',
|
||||||
|
name: '上边距',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'data',
|
||||||
|
name: '数据源',
|
||||||
|
type: 'Table',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
title: '柱状图',
|
||||||
|
size: 14,
|
||||||
|
color: 'rgba(0,0,0,1)',
|
||||||
|
paddingTop: 10,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
name: 'A',
|
||||||
|
value: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'B',
|
||||||
|
value: 60,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'C',
|
||||||
|
value: 20,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Chart;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'Chart',
|
||||||
|
h: 102,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
13
src/components/BasicPcShop/VisualComponents/Line/index.less
Normal file
13
src/components/BasicPcShop/VisualComponents/Line/index.less
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
.chartWrap {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
.chartTitle {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
canvas {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
73
src/components/BasicPcShop/VisualComponents/Line/index.tsx
Normal file
73
src/components/BasicPcShop/VisualComponents/Line/index.tsx
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import { Chart } from '@antv/f2';
|
||||||
|
import React, { memo, useEffect, useRef } from 'react';
|
||||||
|
// import { uuid } from 'utils/tool';
|
||||||
|
import LineImg from '@/assets/line.png';
|
||||||
|
|
||||||
|
import styles from './index.less';
|
||||||
|
import { IChartConfig } from './schema';
|
||||||
|
|
||||||
|
interface XChartProps extends IChartConfig {
|
||||||
|
isTpl: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const XLine = (props: XChartProps) => {
|
||||||
|
const { isTpl, data, color, size, paddingTop, title } = props;
|
||||||
|
const chartRef = useRef(null);
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isTpl) {
|
||||||
|
const chart = new Chart({
|
||||||
|
el: chartRef.current || undefined,
|
||||||
|
pixelRatio: window.devicePixelRatio, // 指定分辨率
|
||||||
|
});
|
||||||
|
|
||||||
|
// step 2: 处理数据
|
||||||
|
const dataX = data.map(item => ({ ...item, value: Number(item.value) }));
|
||||||
|
|
||||||
|
// Step 2: 载入数据源
|
||||||
|
chart.source(dataX, {
|
||||||
|
value: {
|
||||||
|
tickCount: 5,
|
||||||
|
min: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
chart.tooltip({
|
||||||
|
showCrosshairs: true,
|
||||||
|
showItemMarker: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
chart.axis('name', {
|
||||||
|
label: function label(text, index, total) {
|
||||||
|
const textCfg: any = {};
|
||||||
|
if (index === 0) {
|
||||||
|
textCfg.textAlign = 'left';
|
||||||
|
} else if (index === total - 1) {
|
||||||
|
textCfg.textAlign = 'right';
|
||||||
|
}
|
||||||
|
return textCfg;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
chart.line().position('name*value');
|
||||||
|
chart
|
||||||
|
.point()
|
||||||
|
.position('name*value')
|
||||||
|
.style({
|
||||||
|
stroke: '#fff',
|
||||||
|
lineWidth: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
chart.render();
|
||||||
|
}
|
||||||
|
}, [data, isTpl]);
|
||||||
|
return (
|
||||||
|
<div className={styles.chartWrap}>
|
||||||
|
<div className={styles.chartTitle} style={{ color, fontSize: size, paddingTop }}>
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
{isTpl ? <img src={LineImg} alt="dooring chart" /> : <canvas ref={chartRef}></canvas>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(XLine);
|
||||||
82
src/components/BasicPcShop/VisualComponents/Line/schema.ts
Normal file
82
src/components/BasicPcShop/VisualComponents/Line/schema.ts
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import {
|
||||||
|
IColorConfigType,
|
||||||
|
INumberConfigType,
|
||||||
|
ITableConfigType,
|
||||||
|
ITextConfigType,
|
||||||
|
TColorDefaultType,
|
||||||
|
TNumberDefaultType,
|
||||||
|
TTableDefaultType,
|
||||||
|
TTextDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
|
||||||
|
export type TChartEditData = Array<
|
||||||
|
ITextConfigType | INumberConfigType | IColorConfigType | ITableConfigType
|
||||||
|
>;
|
||||||
|
export interface IChartConfig {
|
||||||
|
title: TTextDefaultType;
|
||||||
|
size: TNumberDefaultType;
|
||||||
|
color: TColorDefaultType;
|
||||||
|
paddingTop: TNumberDefaultType;
|
||||||
|
data: TTableDefaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IChartSchema {
|
||||||
|
editData: TChartEditData;
|
||||||
|
config: IChartConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Chart: IChartSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'title',
|
||||||
|
name: '标题',
|
||||||
|
type: 'Text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'size',
|
||||||
|
name: '标题大小',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'color',
|
||||||
|
name: '标题颜色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'paddingTop',
|
||||||
|
name: '上边距',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'data',
|
||||||
|
name: '数据源',
|
||||||
|
type: 'Table',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
title: '折线图',
|
||||||
|
size: 14,
|
||||||
|
color: 'rgba(0,0,0,1)',
|
||||||
|
paddingTop: 10,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
name: 'A',
|
||||||
|
value: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'B',
|
||||||
|
value: 60,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'C',
|
||||||
|
value: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'D',
|
||||||
|
value: 80,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Chart;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'Line',
|
||||||
|
h: 104,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
13
src/components/BasicPcShop/VisualComponents/Pie/index.less
Normal file
13
src/components/BasicPcShop/VisualComponents/Pie/index.less
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
.chartWrap {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
.chartTitle {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
canvas {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
100
src/components/BasicPcShop/VisualComponents/Pie/index.tsx
Normal file
100
src/components/BasicPcShop/VisualComponents/Pie/index.tsx
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
import { Chart } from '@antv/f2';
|
||||||
|
import React, { memo, useEffect, useRef } from 'react';
|
||||||
|
// import { uuid } from 'utils/tool';
|
||||||
|
import PieImg from '@/assets/pie.png';
|
||||||
|
|
||||||
|
import styles from './index.less';
|
||||||
|
import { IChartConfig } from './schema';
|
||||||
|
|
||||||
|
interface XChartProps extends IChartConfig {
|
||||||
|
isTpl: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DataMap {
|
||||||
|
[name: string]: number | string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const XLine = (props: XChartProps) => {
|
||||||
|
const { isTpl, data, color, size, paddingTop, title } = props;
|
||||||
|
const chartRef = useRef(null);
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isTpl) {
|
||||||
|
const chart = new Chart({
|
||||||
|
el: chartRef.current || undefined,
|
||||||
|
pixelRatio: window.devicePixelRatio, // 指定分辨率
|
||||||
|
});
|
||||||
|
|
||||||
|
// step 2: 处理数据
|
||||||
|
const dataX = data.map(item => ({ ...item, value: Number(item.value), a: '1' }));
|
||||||
|
|
||||||
|
// Step 2: 载入数据源
|
||||||
|
chart.source(dataX, {
|
||||||
|
percent: {
|
||||||
|
formatter: function formatter(val) {
|
||||||
|
return val * 100 + '%';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取数据的map类型,用以展示图例说明
|
||||||
|
const dataMap: DataMap = dataX.reduce((prev: any, cur) => {
|
||||||
|
return prev.name
|
||||||
|
? { [prev.name]: prev.value, ...{ [cur.name]: cur.value } }
|
||||||
|
: { ...prev, ...{ [cur.name]: cur.value } };
|
||||||
|
});
|
||||||
|
|
||||||
|
chart.legend({
|
||||||
|
position: 'right',
|
||||||
|
itemFormatter: function itemFormatter(val) {
|
||||||
|
return val + ' ' + dataMap[val] + '%';
|
||||||
|
},
|
||||||
|
});
|
||||||
|
chart.tooltip(false);
|
||||||
|
chart.coord('polar', {
|
||||||
|
transposed: true,
|
||||||
|
radius: 0.85,
|
||||||
|
});
|
||||||
|
chart.axis(false);
|
||||||
|
chart
|
||||||
|
.interval()
|
||||||
|
.position('a*value')
|
||||||
|
.color('name', [
|
||||||
|
'#1890FF',
|
||||||
|
'#13C2C2',
|
||||||
|
'#2FC25B',
|
||||||
|
'#FACC14',
|
||||||
|
'#00CC99',
|
||||||
|
'#CC3366',
|
||||||
|
'#CC6600',
|
||||||
|
'#CC66CC',
|
||||||
|
'#FF3366',
|
||||||
|
'#0066CC',
|
||||||
|
])
|
||||||
|
.adjust('stack')
|
||||||
|
.style({
|
||||||
|
lineWidth: 1,
|
||||||
|
stroke: '#fff',
|
||||||
|
lineJoin: 'round',
|
||||||
|
lineCap: 'round',
|
||||||
|
})
|
||||||
|
.animate({
|
||||||
|
appear: {
|
||||||
|
duration: 1200,
|
||||||
|
easing: 'bounceOut',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
chart.render();
|
||||||
|
}
|
||||||
|
}, [data, isTpl]);
|
||||||
|
return (
|
||||||
|
<div className={styles.chartWrap}>
|
||||||
|
<div className={styles.chartTitle} style={{ color, fontSize: size, paddingTop }}>
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
{isTpl ? <img src={PieImg} alt="dooring chart" /> : <canvas ref={chartRef}></canvas>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(XLine);
|
||||||
82
src/components/BasicPcShop/VisualComponents/Pie/schema.ts
Normal file
82
src/components/BasicPcShop/VisualComponents/Pie/schema.ts
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import {
|
||||||
|
IColorConfigType,
|
||||||
|
INumberConfigType,
|
||||||
|
ITableConfigType,
|
||||||
|
ITextConfigType,
|
||||||
|
TColorDefaultType,
|
||||||
|
TNumberDefaultType,
|
||||||
|
TTableDefaultType,
|
||||||
|
TTextDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
|
||||||
|
export type TChartEditData = Array<
|
||||||
|
ITextConfigType | INumberConfigType | IColorConfigType | ITableConfigType
|
||||||
|
>;
|
||||||
|
export interface IChartConfig {
|
||||||
|
title: TTextDefaultType;
|
||||||
|
size: TNumberDefaultType;
|
||||||
|
color: TColorDefaultType;
|
||||||
|
paddingTop: TNumberDefaultType;
|
||||||
|
data: TTableDefaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IChartSchema {
|
||||||
|
editData: TChartEditData;
|
||||||
|
config: IChartConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Chart: IChartSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'title',
|
||||||
|
name: '标题',
|
||||||
|
type: 'Text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'size',
|
||||||
|
name: '标题大小',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'color',
|
||||||
|
name: '标题颜色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'paddingTop',
|
||||||
|
name: '上边距',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'data',
|
||||||
|
name: '数据源',
|
||||||
|
type: 'Table',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
title: '饼图',
|
||||||
|
size: 14,
|
||||||
|
color: 'rgba(0,0,0,1)',
|
||||||
|
paddingTop: 10,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
name: 'A',
|
||||||
|
value: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'B',
|
||||||
|
value: 60,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'C',
|
||||||
|
value: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'D',
|
||||||
|
value: 80,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Chart;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'Pie',
|
||||||
|
h: 106,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
13
src/components/BasicPcShop/VisualComponents/schema.ts
Normal file
13
src/components/BasicPcShop/VisualComponents/schema.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import Chart from './Chart/schema';
|
||||||
|
import Line from './Line/schema';
|
||||||
|
import Pie from './Pie/schema';
|
||||||
|
import Area from './Area/schema';
|
||||||
|
|
||||||
|
const visualSchema = {
|
||||||
|
Chart,
|
||||||
|
Line,
|
||||||
|
Pie,
|
||||||
|
Area,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default visualSchema;
|
||||||
11
src/components/BasicPcShop/VisualComponents/template.ts
Normal file
11
src/components/BasicPcShop/VisualComponents/template.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import Chart from './Chart/template';
|
||||||
|
import Line from './Line/template';
|
||||||
|
import Pie from './Pie/template';
|
||||||
|
import Area from './Area/template';
|
||||||
|
|
||||||
|
const visualTemplate = [Chart, Line, Pie, Area];
|
||||||
|
|
||||||
|
const VisualTemplate = visualTemplate.map(v => {
|
||||||
|
return { ...v, category: 'visual' };
|
||||||
|
});
|
||||||
|
export default VisualTemplate;
|
||||||
11
src/components/BasicPcShop/schema.ts
Normal file
11
src/components/BasicPcShop/schema.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import BasicSchema from './BasicComponents/schema';
|
||||||
|
import MediaSchema from './MediaComponents/schema';
|
||||||
|
import VisualSchema from './VisualComponents/schema';
|
||||||
|
|
||||||
|
const schema = {
|
||||||
|
...BasicSchema,
|
||||||
|
...MediaSchema,
|
||||||
|
...VisualSchema,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default schema;
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
import { NoticeBar } from 'zarm';
|
||||||
|
import React, { memo } from 'react';
|
||||||
|
import { INoticeConfig } from './schema';
|
||||||
|
const Notice = memo((props: INoticeConfig) => {
|
||||||
|
const { text, speed, theme, isClose = false } = props;
|
||||||
|
return (
|
||||||
|
<NoticeBar theme={theme === 'default' ? undefined : theme} closable={isClose} speed={speed}>
|
||||||
|
<span style={{ color: 'inherit' }}>{text}</span>
|
||||||
|
</NoticeBar>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Notice;
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
import {
|
||||||
|
INumberConfigType,
|
||||||
|
ISelectConfigType,
|
||||||
|
ISwitchConfigType,
|
||||||
|
ITextConfigType,
|
||||||
|
TNumberDefaultType,
|
||||||
|
TSelectDefaultType,
|
||||||
|
TSwitchDefaultType,
|
||||||
|
TTextDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
|
||||||
|
export type TNoticeSelectKeyType = 'default' | 'warning' | 'primary' | 'success' | 'danger';
|
||||||
|
export type TNoticeEditData = Array<
|
||||||
|
ITextConfigType | INumberConfigType | ISelectConfigType<TNoticeSelectKeyType> | ISwitchConfigType
|
||||||
|
>;
|
||||||
|
export interface INoticeConfig {
|
||||||
|
text: TTextDefaultType;
|
||||||
|
speed: TNumberDefaultType;
|
||||||
|
theme: TSelectDefaultType<TNoticeSelectKeyType>;
|
||||||
|
isClose: TSwitchDefaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface INoticeSchema {
|
||||||
|
editData: TNoticeEditData;
|
||||||
|
config: INoticeConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Notice: INoticeSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'text',
|
||||||
|
name: '文本',
|
||||||
|
type: 'Text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'speed',
|
||||||
|
name: '滚动速度',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'theme',
|
||||||
|
name: '主题',
|
||||||
|
type: 'Select',
|
||||||
|
range: [
|
||||||
|
{
|
||||||
|
key: 'default',
|
||||||
|
text: '默认',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'warning',
|
||||||
|
text: '警告',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'primary',
|
||||||
|
text: '主要',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'success',
|
||||||
|
text: '成功',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'danger',
|
||||||
|
text: '危险',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'isClose',
|
||||||
|
name: '是否可关闭',
|
||||||
|
type: 'Switch',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
text: '通知栏: 趣谈前端上线啦',
|
||||||
|
speed: 50,
|
||||||
|
theme: 'warning',
|
||||||
|
isClose: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Notice;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'Notice',
|
||||||
|
h: 20,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
.tabWrap {
|
||||||
|
padding-top: 16px;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
.content {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
.item {
|
||||||
|
padding: 20px 20px 0;
|
||||||
|
width: 50%;
|
||||||
|
text-align: center;
|
||||||
|
justify-content: center;
|
||||||
|
.imgWrap {
|
||||||
|
display: inline-block;
|
||||||
|
width: 80%;
|
||||||
|
img {
|
||||||
|
border-radius: 6px;
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
line-height: 2.4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
import React, { useEffect, useRef } from 'react';
|
||||||
|
import { Tabs } from 'zarm';
|
||||||
|
import styles from './index.less';
|
||||||
|
import { ITabConfig } from './schema';
|
||||||
|
|
||||||
|
const { Panel } = Tabs;
|
||||||
|
|
||||||
|
const XTab = (props: ITabConfig) => {
|
||||||
|
const { tabs = ['分类一', '分类二'], activeColor, color, fontSize, sourceData } = props;
|
||||||
|
|
||||||
|
const tabWrapRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (tabWrapRef.current) {
|
||||||
|
let res = tabWrapRef.current.querySelector('.za-tabs__line') as HTMLElement;
|
||||||
|
if (res) {
|
||||||
|
res.style.backgroundColor = activeColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [activeColor]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.tabWrap} ref={tabWrapRef}>
|
||||||
|
<Tabs
|
||||||
|
scrollThreshold={3}
|
||||||
|
onChange={i => {
|
||||||
|
console.log(i);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{tabs.map((item, i) => {
|
||||||
|
return (
|
||||||
|
<Panel title={item} key={i}>
|
||||||
|
<div className={styles.content}>
|
||||||
|
{sourceData
|
||||||
|
.filter(item => item.type === i)
|
||||||
|
.map((item, i) => {
|
||||||
|
return (
|
||||||
|
<div className={styles.item} key={i}>
|
||||||
|
<a className={styles.imgWrap} href={item.link} title={item.desc}>
|
||||||
|
<img
|
||||||
|
src={
|
||||||
|
item.imgUrl[0]
|
||||||
|
? item.imgUrl[0].url
|
||||||
|
: 'http://io.nainor.com/uploads/01_173e15d3493.png'
|
||||||
|
}
|
||||||
|
alt={item.title}
|
||||||
|
/>
|
||||||
|
<div className={styles.title} style={{ fontSize, color }}>
|
||||||
|
{item.title}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default XTab;
|
||||||
118
src/components/CommonComponents/BasicComponents/Tab/schema.ts
Normal file
118
src/components/CommonComponents/BasicComponents/Tab/schema.ts
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
import {
|
||||||
|
IColorConfigType,
|
||||||
|
IDataListConfigType,
|
||||||
|
IMutiTextConfigType,
|
||||||
|
INumberConfigType,
|
||||||
|
TColorDefaultType,
|
||||||
|
TDataListDefaultType,
|
||||||
|
TMutiTextDefaultType,
|
||||||
|
TNumberDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
|
||||||
|
export type TTabEditData = Array<
|
||||||
|
IMutiTextConfigType | IColorConfigType | INumberConfigType | IDataListConfigType
|
||||||
|
>;
|
||||||
|
export interface ITabConfig {
|
||||||
|
tabs: TMutiTextDefaultType;
|
||||||
|
color: TColorDefaultType;
|
||||||
|
activeColor: TColorDefaultType;
|
||||||
|
fontSize: TNumberDefaultType;
|
||||||
|
imgSize: TNumberDefaultType;
|
||||||
|
sourceData: TDataListDefaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ITabSchema {
|
||||||
|
editData: TTabEditData;
|
||||||
|
config: ITabConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Tab: ITabSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'tabs',
|
||||||
|
name: '项目类别',
|
||||||
|
type: 'MutiText',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'activeColor',
|
||||||
|
name: '激活颜色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'color',
|
||||||
|
name: '文字颜色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'fontSize',
|
||||||
|
name: '文字大小',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'imgSize',
|
||||||
|
name: '图片大小',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'sourceData',
|
||||||
|
name: '数据源',
|
||||||
|
type: 'DataList',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
tabs: ['类别一', '类别二'],
|
||||||
|
color: 'rgba(153,153,153,1)',
|
||||||
|
activeColor: 'rgba(0,102,204,1)',
|
||||||
|
fontSize: 16,
|
||||||
|
imgSize: 100,
|
||||||
|
sourceData: [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
title: '趣谈小课1',
|
||||||
|
desc: '致力于打造优质小课程',
|
||||||
|
link: 'xxxxx',
|
||||||
|
type: 0,
|
||||||
|
imgUrl: [
|
||||||
|
{
|
||||||
|
uid: '001',
|
||||||
|
name: 'image.png',
|
||||||
|
status: 'done',
|
||||||
|
url: 'http://io.nainor.com/uploads/1_1740c6fbcd9.png',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
title: '趣谈小课2',
|
||||||
|
desc: '致力于打造优质小课程',
|
||||||
|
link: 'xxxxx',
|
||||||
|
type: 0,
|
||||||
|
imgUrl: [
|
||||||
|
{
|
||||||
|
uid: '001',
|
||||||
|
name: 'image.png',
|
||||||
|
status: 'done',
|
||||||
|
url: 'http://io.nainor.com/uploads/2_1740c7033a9.png',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '3',
|
||||||
|
title: '趣谈小课3',
|
||||||
|
desc: '致力于打造优质小课程',
|
||||||
|
link: 'xxxxx',
|
||||||
|
type: 1,
|
||||||
|
imgUrl: [
|
||||||
|
{
|
||||||
|
uid: '001',
|
||||||
|
name: 'image.png',
|
||||||
|
status: 'done',
|
||||||
|
url: 'http://io.nainor.com/uploads/1_1740c6fbcd9.png',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Tab;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'Tab',
|
||||||
|
h: 130,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
28
src/components/CommonComponents/BasicComponents/schema.ts
Normal file
28
src/components/CommonComponents/BasicComponents/schema.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import Carousel from './Carousel/schema';
|
||||||
|
import Footer from './Footer/schema';
|
||||||
|
import Form from './Form/schema';
|
||||||
|
import Header from './Header/schema';
|
||||||
|
import Icon from './Icon/schema';
|
||||||
|
import Image from './Image/schema';
|
||||||
|
import List from './List/schema';
|
||||||
|
import LongText from './LongText/schema';
|
||||||
|
import Notice from './Notice/schema';
|
||||||
|
import Qrcode from './Qrcode/schema';
|
||||||
|
import Tab from './Tab/schema';
|
||||||
|
import Text from './Text/schema';
|
||||||
|
|
||||||
|
const basicSchema = {
|
||||||
|
Carousel,
|
||||||
|
Footer,
|
||||||
|
Form,
|
||||||
|
Header,
|
||||||
|
Icon,
|
||||||
|
Image,
|
||||||
|
List,
|
||||||
|
LongText,
|
||||||
|
Notice,
|
||||||
|
Qrcode,
|
||||||
|
Tab,
|
||||||
|
Text,
|
||||||
|
};
|
||||||
|
export default basicSchema;
|
||||||
32
src/components/CommonComponents/BasicComponents/template.ts
Normal file
32
src/components/CommonComponents/BasicComponents/template.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import Carousel from './Carousel/template';
|
||||||
|
import Footer from './Footer/template';
|
||||||
|
import Form from './Form/template';
|
||||||
|
import Header from './Header/template';
|
||||||
|
import Icon from './Icon/template';
|
||||||
|
import Image from './Image/template';
|
||||||
|
import List from './List/template';
|
||||||
|
import LongText from './LongText/template';
|
||||||
|
import Notice from './Notice/template';
|
||||||
|
import Qrcode from './Qrcode/template';
|
||||||
|
import Tab from './Tab/template';
|
||||||
|
import Text from './Text/template';
|
||||||
|
|
||||||
|
const basicTemplate = [
|
||||||
|
Carousel,
|
||||||
|
Footer,
|
||||||
|
Form,
|
||||||
|
Header,
|
||||||
|
Icon,
|
||||||
|
Image,
|
||||||
|
List,
|
||||||
|
LongText,
|
||||||
|
Notice,
|
||||||
|
Qrcode,
|
||||||
|
Tab,
|
||||||
|
Text,
|
||||||
|
];
|
||||||
|
const BasicTemplate = basicTemplate.map(v => {
|
||||||
|
return { ...v, category: 'base' };
|
||||||
|
});
|
||||||
|
|
||||||
|
export default BasicTemplate;
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
.carousel__item__pic {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
max-height: 220px;
|
||||||
|
overflow: hidden;
|
||||||
|
vertical-align: top;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
import React, { memo, PropsWithChildren } from 'react';
|
||||||
|
import { Carousel } from 'zarm';
|
||||||
|
import styles from './index.less';
|
||||||
|
import { ICarouselConfig } from './schema';
|
||||||
|
|
||||||
|
interface CarouselTypes extends ICarouselConfig {
|
||||||
|
isTpl: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const XCarousel = memo((props: PropsWithChildren<CarouselTypes>) => {
|
||||||
|
const { direction, swipeable, autoPlay, isTpl, imgList, tplImg } = props;
|
||||||
|
const contentRender = () => {
|
||||||
|
return imgList.map((item, i) => {
|
||||||
|
return (
|
||||||
|
<div className={styles.carousel__item__pic} key={+i}>
|
||||||
|
<img src={item.imgUrl.length > 0 ? item.imgUrl[0].url : ''} alt="" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div style={{ width: '100%', overflow: 'hidden' }}>
|
||||||
|
{isTpl ? (
|
||||||
|
<div className={styles.carousel__item__pic}>
|
||||||
|
<img src={tplImg} alt="" />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<Carousel
|
||||||
|
onChange={index => {
|
||||||
|
// console.log(`onChange: ${index}`);
|
||||||
|
}}
|
||||||
|
direction={direction}
|
||||||
|
swipeable={swipeable}
|
||||||
|
autoPlay={autoPlay}
|
||||||
|
loop
|
||||||
|
>
|
||||||
|
{contentRender()}
|
||||||
|
</Carousel>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default XCarousel;
|
||||||
@ -0,0 +1,98 @@
|
|||||||
|
import {
|
||||||
|
IDataListConfigType,
|
||||||
|
IRadioConfigType,
|
||||||
|
ISwitchConfigType,
|
||||||
|
TDataListDefaultType,
|
||||||
|
TRadioDefaultType,
|
||||||
|
TSwitchDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
|
||||||
|
export type CarouselDirectionKeyType = 'down' | 'left';
|
||||||
|
|
||||||
|
export type TCarouselEditData = Array<
|
||||||
|
IRadioConfigType<CarouselDirectionKeyType> | ISwitchConfigType | IDataListConfigType
|
||||||
|
>;
|
||||||
|
export interface ICarouselConfig {
|
||||||
|
direction: TRadioDefaultType<CarouselDirectionKeyType>;
|
||||||
|
swipeable: TSwitchDefaultType;
|
||||||
|
autoPlay: TSwitchDefaultType;
|
||||||
|
imgList: TDataListDefaultType;
|
||||||
|
tplImg: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ICarouselSchema {
|
||||||
|
editData: TCarouselEditData;
|
||||||
|
config: ICarouselConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Carousel: ICarouselSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'direction',
|
||||||
|
name: '方向',
|
||||||
|
type: 'Radio',
|
||||||
|
range: [
|
||||||
|
{
|
||||||
|
key: 'down',
|
||||||
|
text: '从上到下',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'left',
|
||||||
|
text: '从左到右',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'swipeable',
|
||||||
|
name: '是否可拖拽',
|
||||||
|
type: 'Switch',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'autoPlay',
|
||||||
|
name: '是否自动播放',
|
||||||
|
type: 'Switch',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'imgList',
|
||||||
|
name: '图片列表',
|
||||||
|
type: 'DataList',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
direction: 'left',
|
||||||
|
swipeable: false,
|
||||||
|
autoPlay: false,
|
||||||
|
imgList: [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
title: '趣谈小课1',
|
||||||
|
desc: '致力于打造优质小课程',
|
||||||
|
link: 'xxxxx',
|
||||||
|
imgUrl: [
|
||||||
|
{
|
||||||
|
uid: '001',
|
||||||
|
name: 'image.png',
|
||||||
|
status: 'done',
|
||||||
|
url: 'http://io.nainor.com/uploads/1_1740bd7c3dc.png',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
title: '趣谈小课1',
|
||||||
|
desc: '致力于打造优质小课程',
|
||||||
|
link: 'xxxxx',
|
||||||
|
imgUrl: [
|
||||||
|
{
|
||||||
|
uid: '001',
|
||||||
|
name: 'image.png',
|
||||||
|
status: 'done',
|
||||||
|
url: 'http://io.nainor.com/uploads/2_1740bd8d525.png',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
tplImg: 'http://io.nainor.com/uploads/carousal_17442e1420f.png',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export default Carousel;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'Carousel',
|
||||||
|
h: 82,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
import { Input, Cell, DateSelect, Radio, Select } from 'zarm';
|
||||||
|
import styles from './baseForm.less';
|
||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
baseFormDateTpl,
|
||||||
|
baseFormMyRadioTpl,
|
||||||
|
baseFormMySelectTpl,
|
||||||
|
baseFormNumberTpl,
|
||||||
|
baseFormTextAreaTpl,
|
||||||
|
baseFormTextTpl,
|
||||||
|
baseFormUnionType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
// 维护表单控件, 提高form渲染性能
|
||||||
|
|
||||||
|
type TBaseForm = {
|
||||||
|
[key in baseFormUnionType]: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
const BaseForm: TBaseForm = {
|
||||||
|
Text: (props: baseFormTextTpl & { onChange: (v: string | undefined) => void }) => {
|
||||||
|
const { label, placeholder, onChange } = props;
|
||||||
|
return (
|
||||||
|
<Cell title={label}>
|
||||||
|
<Input clearable type="text" placeholder={placeholder} onChange={onChange} />
|
||||||
|
</Cell>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
Textarea: (props: baseFormTextAreaTpl & { onChange: (v: string | undefined) => void }) => {
|
||||||
|
const { label, placeholder, onChange } = props;
|
||||||
|
return (
|
||||||
|
<Cell title={label}>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
rows={3}
|
||||||
|
autoHeight
|
||||||
|
showLength
|
||||||
|
placeholder={placeholder}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
|
</Cell>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
Number: (props: baseFormNumberTpl & { onChange: (v: string | undefined | number) => void }) => {
|
||||||
|
const { label, placeholder, onChange } = props;
|
||||||
|
return (
|
||||||
|
<Cell title={label}>
|
||||||
|
<Input type="number" placeholder={placeholder} onChange={onChange} />
|
||||||
|
</Cell>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
MyRadio: (props: baseFormMyRadioTpl & { onChange: (v: string | undefined | number) => void }) => {
|
||||||
|
const { label, options, onChange } = props;
|
||||||
|
return (
|
||||||
|
<div className={styles.radioWrap}>
|
||||||
|
<div className={styles.radioTitle}>{label}</div>
|
||||||
|
<Cell>
|
||||||
|
<Radio.Group onChange={onChange}>
|
||||||
|
{options.map((item, i) => {
|
||||||
|
return (
|
||||||
|
<Radio value={item.value} key={i} className={styles.radioItem}>
|
||||||
|
{item.label}
|
||||||
|
</Radio>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Radio.Group>
|
||||||
|
</Cell>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
Date: (props: baseFormDateTpl & { onChange: (v: Date) => void }) => {
|
||||||
|
const { label, placeholder, onChange } = props;
|
||||||
|
return (
|
||||||
|
<Cell title={label}>
|
||||||
|
<DateSelect
|
||||||
|
placeholder={placeholder}
|
||||||
|
mode="date"
|
||||||
|
min="1949-05-15"
|
||||||
|
max="2100-05-15"
|
||||||
|
onOk={onChange}
|
||||||
|
/>
|
||||||
|
</Cell>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
MySelect: (
|
||||||
|
props: baseFormMySelectTpl & { onChange: ((v: Record<string, any>) => void) | undefined },
|
||||||
|
) => {
|
||||||
|
const { label, options, onChange } = props;
|
||||||
|
return (
|
||||||
|
<Cell title={label}>
|
||||||
|
<Select dataSource={options} onOk={onChange} />
|
||||||
|
</Cell>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BaseForm;
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
.radioWrap {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
.radioTitle {
|
||||||
|
padding: 6px 16px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
.radioItem {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
.formWrap {
|
||||||
|
margin: 10px;
|
||||||
|
padding: 20px 16px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 2px 6px #f0f0f0;
|
||||||
|
.title {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
.formContent {
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
import React, { memo, useCallback } from 'react';
|
||||||
|
import { Button } from 'zarm';
|
||||||
|
import BaseForm from './BaseForm';
|
||||||
|
import styles from './index.less';
|
||||||
|
import { IFormConfig } from './schema';
|
||||||
|
|
||||||
|
const FormComponent = (props: IFormConfig) => {
|
||||||
|
const { title, bgColor, fontSize, titColor, btnColor, btnTextColor, api, formControls } = props;
|
||||||
|
const formData: Record<string, any> = {};
|
||||||
|
const handleChange = useCallback(
|
||||||
|
(item, v) => {
|
||||||
|
if (item.options) {
|
||||||
|
formData[item.label] = v[0].label;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
formData[item.label] = v;
|
||||||
|
},
|
||||||
|
[formData],
|
||||||
|
);
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (api) {
|
||||||
|
fetch(api, {
|
||||||
|
body: JSON.stringify(formData),
|
||||||
|
cache: 'no-cache',
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/json',
|
||||||
|
},
|
||||||
|
method: 'POST',
|
||||||
|
mode: 'cors',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className={styles.formWrap} style={{ backgroundColor: bgColor }}>
|
||||||
|
{title && (
|
||||||
|
<div className={styles.title} style={{ fontSize, color: titColor }}>
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className={styles.formContent}>
|
||||||
|
{formControls.map(item => {
|
||||||
|
const FormItem = BaseForm[item.type];
|
||||||
|
return <FormItem onChange={handleChange.bind(this, item)} {...item} key={item.id} />;
|
||||||
|
})}
|
||||||
|
<div style={{ textAlign: 'center', padding: '16px 0' }}>
|
||||||
|
<Button
|
||||||
|
theme="primary"
|
||||||
|
size="sm"
|
||||||
|
block
|
||||||
|
onClick={handleSubmit}
|
||||||
|
style={{ backgroundColor: btnColor, borderColor: btnColor, color: btnTextColor }}
|
||||||
|
>
|
||||||
|
提交
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(FormComponent);
|
||||||
108
src/components/CommonComponents/VisualComponents/Form/schema.ts
Normal file
108
src/components/CommonComponents/VisualComponents/Form/schema.ts
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
import {
|
||||||
|
IColorConfigType,
|
||||||
|
IFormItemsConfigType,
|
||||||
|
INumberConfigType,
|
||||||
|
ITextConfigType,
|
||||||
|
TColorDefaultType,
|
||||||
|
TFormItemsDefaultType,
|
||||||
|
TNumberDefaultType,
|
||||||
|
TTextDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
|
||||||
|
export type TFormEditData = Array<
|
||||||
|
ITextConfigType | INumberConfigType | IColorConfigType | ITextConfigType | IFormItemsConfigType
|
||||||
|
>;
|
||||||
|
export interface IFormConfig {
|
||||||
|
title: TTextDefaultType;
|
||||||
|
fontSize: TNumberDefaultType;
|
||||||
|
titColor: TColorDefaultType;
|
||||||
|
bgColor: TColorDefaultType;
|
||||||
|
btnColor: TColorDefaultType;
|
||||||
|
btnTextColor: TColorDefaultType;
|
||||||
|
api: TTextDefaultType;
|
||||||
|
formControls: TFormItemsDefaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IFormSchema {
|
||||||
|
editData: TFormEditData;
|
||||||
|
config: IFormConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Form: IFormSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'title',
|
||||||
|
name: '标题',
|
||||||
|
type: 'Text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'fontSize',
|
||||||
|
name: '标题大小',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'titColor',
|
||||||
|
name: '标题颜色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'bgColor',
|
||||||
|
name: '背景色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'btnColor',
|
||||||
|
name: '按钮颜色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'btnTextColor',
|
||||||
|
name: '按钮文本颜色',
|
||||||
|
type: 'Color',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'api',
|
||||||
|
name: '表单Api地址',
|
||||||
|
type: 'Text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'formControls',
|
||||||
|
name: '表单控件',
|
||||||
|
type: 'FormItems',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
title: '表单定制组件',
|
||||||
|
fontSize: 18,
|
||||||
|
titColor: 'rgba(60,60,60,1)',
|
||||||
|
bgColor: 'rgba(255,255,255,1)',
|
||||||
|
btnColor: 'rgba(129,173,173,1)',
|
||||||
|
btnTextColor: 'rgba(255,255,255,1)',
|
||||||
|
api: '',
|
||||||
|
formControls: [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
type: 'Text',
|
||||||
|
label: '姓名',
|
||||||
|
placeholder: '请输入姓名',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
type: 'Number',
|
||||||
|
label: '年龄',
|
||||||
|
placeholder: ' 请输入年龄',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '4',
|
||||||
|
type: 'MySelect',
|
||||||
|
label: '爱好',
|
||||||
|
options: [
|
||||||
|
{ label: '选项一', value: '1' },
|
||||||
|
{ label: '选项二', value: '2' },
|
||||||
|
{ label: '选项三', value: '3' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export default Form;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'Form',
|
||||||
|
h: 172,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
import React, { memo } from 'react';
|
||||||
|
import { Progress } from 'zarm';
|
||||||
|
import styles from './index.less';
|
||||||
|
import { IXProgressConfig } from './schema';
|
||||||
|
|
||||||
|
const XProgress = memo((props: IXProgressConfig) => {
|
||||||
|
const { theme, size, shape, percent, strokeWidth } = props;
|
||||||
|
return (
|
||||||
|
<div className={styles.textWrap} style={{ textAlign: 'center' }}>
|
||||||
|
<Progress
|
||||||
|
shape={shape}
|
||||||
|
size={size}
|
||||||
|
percent={percent}
|
||||||
|
theme={theme}
|
||||||
|
strokeWidth={strokeWidth}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default XProgress;
|
||||||
@ -0,0 +1,95 @@
|
|||||||
|
import {
|
||||||
|
INumberConfigType,
|
||||||
|
IRadioConfigType,
|
||||||
|
ISelectConfigType,
|
||||||
|
TNumberDefaultType,
|
||||||
|
TRadioDefaultType,
|
||||||
|
TSelectDefaultType,
|
||||||
|
} from '@/components/PanelComponents/FormEditor/types';
|
||||||
|
export type TXProgressSelectKeyType = 'success' | 'warning' | 'danger';
|
||||||
|
export type TXProgressRadiotKeyType = 'circle' | 'line' | 'semi-circle';
|
||||||
|
export type TXProgressEditData = Array<
|
||||||
|
| ISelectConfigType<TXProgressSelectKeyType>
|
||||||
|
| IRadioConfigType<TXProgressRadiotKeyType>
|
||||||
|
| INumberConfigType
|
||||||
|
>;
|
||||||
|
export interface IXProgressConfig {
|
||||||
|
theme: TSelectDefaultType<TXProgressSelectKeyType>;
|
||||||
|
shape: TRadioDefaultType<TXProgressRadiotKeyType>;
|
||||||
|
size: TNumberDefaultType;
|
||||||
|
percent: TNumberDefaultType;
|
||||||
|
strokeWidth: TNumberDefaultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IXProgressSchema {
|
||||||
|
editData: TXProgressEditData;
|
||||||
|
config: IXProgressConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const XProgress: IXProgressSchema = {
|
||||||
|
editData: [
|
||||||
|
{
|
||||||
|
key: 'theme',
|
||||||
|
name: '主题',
|
||||||
|
type: 'Select',
|
||||||
|
range: [
|
||||||
|
{
|
||||||
|
key: 'success',
|
||||||
|
text: '成功',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'warning',
|
||||||
|
text: '警告',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'danger',
|
||||||
|
text: '危险',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'shape',
|
||||||
|
name: '形状',
|
||||||
|
type: 'Radio',
|
||||||
|
range: [
|
||||||
|
{
|
||||||
|
key: 'circle',
|
||||||
|
text: '圆形',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'line',
|
||||||
|
text: '线形',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'semi-circle',
|
||||||
|
text: '半圆形',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'size',
|
||||||
|
name: '大小',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'percent',
|
||||||
|
name: '进度值',
|
||||||
|
type: 'Number',
|
||||||
|
range: [0, 100],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'strokeWidth',
|
||||||
|
name: '线条粗细',
|
||||||
|
type: 'Number',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
theme: 'success',
|
||||||
|
shape: 'circle',
|
||||||
|
size: 200,
|
||||||
|
percent: 30,
|
||||||
|
strokeWidth: 10,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default XProgress;
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const template = {
|
||||||
|
type: 'XProgress',
|
||||||
|
h: 102,
|
||||||
|
};
|
||||||
|
export default template;
|
||||||
Loading…
x
Reference in New Issue
Block a user