diff --git a/package.json b/package.json index 35c425c..d4b7f14 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "antd": "^4.7.0", "antd-img-crop": "^3.10.0", "axios": "^0.19.2", + "braft-editor": "^2.3.9", "chatbot-antd": "^0.6.0", "codemirror": "^5.57.0", "dom-to-image": "^2.6.0", diff --git a/src/assets/richText.png b/src/assets/richText.png new file mode 100644 index 0000000..be1d423 Binary files /dev/null and b/src/assets/richText.png differ diff --git a/src/components/BasicShop/BasicComponents/RichText/index.less b/src/components/BasicShop/BasicComponents/RichText/index.less new file mode 100644 index 0000000..66c8363 --- /dev/null +++ b/src/components/BasicShop/BasicComponents/RichText/index.less @@ -0,0 +1,17 @@ +.richTextWrap { + :global(p) { + margin-bottom: 0; + } + :global(img) { + max-width: 100%; + text-align: center; + } + :global(blockquote) { + margin: 0 0 10px; + padding: 12px 20px; + background-color: #f1f2f3; + border-left: 5px solid #ccc; + color: #666; + font-style: italic; + } +} diff --git a/src/components/BasicShop/BasicComponents/RichText/index.tsx b/src/components/BasicShop/BasicComponents/RichText/index.tsx new file mode 100644 index 0000000..56433d3 --- /dev/null +++ b/src/components/BasicShop/BasicComponents/RichText/index.tsx @@ -0,0 +1,30 @@ +import React, { memo, useState } from 'react'; +import styles from './index.less'; +import { IButtonConfig } from './schema'; +import logo from '@/assets/richText.png'; + +interface IProps extends IButtonConfig { + isTpl: boolean; +} + +const XButton = memo((props: IProps) => { + const { isTpl, borderColor, borderWidth, round, padding, content } = props; + + return isTpl ? ( +
+ +
+ ) : ( +
+
+
+ ); +}); +export default XButton; diff --git a/src/components/BasicShop/BasicComponents/RichText/schema.ts b/src/components/BasicShop/BasicComponents/RichText/schema.ts new file mode 100644 index 0000000..feb9075 --- /dev/null +++ b/src/components/BasicShop/BasicComponents/RichText/schema.ts @@ -0,0 +1,64 @@ +import { + IColorConfigType, + INumberConfigType, + ITextConfigType, + TColorDefaultType, + TNumberDefaultType, + TTextDefaultType, + IRichTextConfigType, + TRichTextDefaultType, +} from '@/components/PanelComponents/FormEditor/types'; + +export type TButtonEditData = Array< + ITextConfigType | IColorConfigType | INumberConfigType | IRichTextConfigType +>; + +export interface IButtonConfig { + round: TNumberDefaultType; + borderWidth: TNumberDefaultType; + padding: TNumberDefaultType; + borderColor: TColorDefaultType; + content: TRichTextDefaultType; +} + +export interface IButtonSchema { + editData: TButtonEditData; + config: IButtonConfig; +} +const Button: IButtonSchema = { + editData: [ + { + key: 'round', + name: '边框圆角', + type: 'Number', + }, + { + key: 'borderWidth', + name: '边框宽度', + type: 'Number', + }, + { + key: 'borderColor', + name: '边框颜色', + type: 'Color', + }, + { + key: 'padding', + name: '内边距', + type: 'Number', + }, + { + key: 'content', + name: '内容', + type: 'RichText', + }, + ], + config: { + round: 0, + borderWidth: 0, + borderColor: 'rgba(255,255,255,1)', + padding: 0, + content: '', + }, +}; +export default Button; diff --git a/src/components/BasicShop/BasicComponents/RichText/template.ts b/src/components/BasicShop/BasicComponents/RichText/template.ts new file mode 100644 index 0000000..049a8e7 --- /dev/null +++ b/src/components/BasicShop/BasicComponents/RichText/template.ts @@ -0,0 +1,6 @@ +const template = { + type: 'RichText', + h: 120, + displayName: '富文本组件', +}; +export default template; diff --git a/src/components/BasicShop/BasicComponents/schema.ts b/src/components/BasicShop/BasicComponents/schema.ts index b4e6bf1..8945800 100644 --- a/src/components/BasicShop/BasicComponents/schema.ts +++ b/src/components/BasicShop/BasicComponents/schema.ts @@ -11,6 +11,7 @@ import Notice from './Notice/schema'; import Qrcode from './Qrcode/schema'; import Tab from './Tab/schema'; import Text from './Text/schema'; +import RichText from './RichText/schema'; const basicSchema = { Carousel, @@ -26,5 +27,6 @@ const basicSchema = { Qrcode, Tab, Text, + RichText, }; export default basicSchema; diff --git a/src/components/BasicShop/BasicComponents/template.ts b/src/components/BasicShop/BasicComponents/template.ts index bb90856..b38a50e 100644 --- a/src/components/BasicShop/BasicComponents/template.ts +++ b/src/components/BasicShop/BasicComponents/template.ts @@ -11,6 +11,7 @@ import Qrcode from './Qrcode/template'; import Tab from './Tab/template'; import Text from './Text/template'; import WhiteTpl from './WhiteTpl/template'; +import RichText from './RichText/template'; const basicTemplate = [ Carousel, @@ -26,6 +27,7 @@ const basicTemplate = [ Tab, Text, WhiteTpl, + RichText, ]; const BasicTemplate = basicTemplate.map(v => { return { ...v, category: 'base' }; diff --git a/src/components/PanelComponents/FormEditor/index.tsx b/src/components/PanelComponents/FormEditor/index.tsx index 3945838..1bdbfc4 100644 --- a/src/components/PanelComponents/FormEditor/index.tsx +++ b/src/components/PanelComponents/FormEditor/index.tsx @@ -8,6 +8,7 @@ import CardPicker from '../CardPicker'; import Table from '../Table'; import Pos from '../Pos'; import { Store } from 'antd/lib/form/interface'; +import RichText from '../XEditor'; import FormItems from '../FormItems'; // import styles from './index.less'; const normFile = (e: any) => { @@ -158,6 +159,11 @@ const FormEditor = (props: FormEditorProps) => { )} + {item.type === 'RichText' && ( + + + + )} ); })} diff --git a/src/components/PanelComponents/XEditor/index.less b/src/components/PanelComponents/XEditor/index.less new file mode 100644 index 0000000..4783014 --- /dev/null +++ b/src/components/PanelComponents/XEditor/index.less @@ -0,0 +1,4 @@ +.avatarUploader > :global(.ant-upload) { + width: 128px; + height: 128px; +} diff --git a/src/components/PanelComponents/XEditor/index.tsx b/src/components/PanelComponents/XEditor/index.tsx new file mode 100644 index 0000000..ff739db --- /dev/null +++ b/src/components/PanelComponents/XEditor/index.tsx @@ -0,0 +1,94 @@ +import React, { useState, useEffect, memo } from 'react'; +import req from '@/utils/req'; +import BraftEditor from 'braft-editor'; +import 'braft-editor/dist/index.css'; +import styles from './index.less'; + +const controls = [ + { + key: 'bold', + text: 加粗, + }, + 'undo', + 'redo', + 'emoji', + 'list-ul', + 'list-ol', + 'blockquote', + 'text-align', + 'font-size', + 'line-height', + 'letter-spacing', + 'text-color', + 'italic', + 'underline', + 'link', + 'media', +]; + +export default memo(function XEditor(props: any) { + const [editorState, setEditorState] = useState(BraftEditor.createEditorState()); + + const { value, onChange } = props; + + const myUploadFn = param => { + const fd = new FormData(); + fd.append('file', param.file); + + req + .post('xxxx', fd, { + headers: { + 'Content-Type': 'multipart/form-data', + }, + onUploadProgress: function(event) { + // 上传进度发生变化时调用param.progress + console.log((event.loaded / event.total) * 100); + param.progress((event.loaded / event.total) * 100); + }, + }) + .then(res => { + console.log(res); + // 上传成功后调用param.success并传入上传后的文件地址 + param.success({ + url: res.url, + meta: { + id: Date.now(), + title: res.filename, + alt: '趣谈前端', + }, + }); + }) + .catch(err => { + param.error({ + msg: '上传失败.', + }); + }); + }; + + const submitContent = () => { + const htmlContent = editorState.toHTML(); + onChange && onChange(htmlContent); + }; + + const handleEditorChange = editorState => { + setEditorState(editorState); + if (onChange) { + const htmlContent = editorState.toHTML(); + onChange(htmlContent); + } + }; + + useEffect(() => { + const htmlContent = value || ''; + setEditorState(BraftEditor.createEditorState(htmlContent)); + }, []); + return ( + + ); +}); diff --git a/src/components/Zan/index.tsx b/src/components/Zan/index.tsx index c53f694..1857198 100644 --- a/src/components/Zan/index.tsx +++ b/src/components/Zan/index.tsx @@ -5,7 +5,7 @@ import styles from './index.less'; ///这组件写的有问题 popover会重定位 const content = (
- sponsorship + sponsorship
); diff --git a/src/pages/home/index.less b/src/pages/home/index.less index 4764bee..0701447 100644 --- a/src/pages/home/index.less +++ b/src/pages/home/index.less @@ -53,7 +53,7 @@ .footer { margin-top: 50px; text-align: center; - font-size: 50px; + font-size: 15px; p { font-size: 16px; } diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index b8f3453..0efc776 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -1,13 +1,13 @@ import React from 'react'; -import { Tabs, message, Button } from 'antd'; +import { Tabs, message } from 'antd'; import { history } from 'umi'; import { MobileOutlined, ConsoleSqlOutlined, - GithubOutlined, CodeOutlined, IdcardOutlined, } from '@ant-design/icons'; +import Zan from '@/components/Zan'; import styles from './index.less'; const { TabPane } = Tabs; @@ -90,21 +90,30 @@ const Home = () => { diff --git a/yarn.lock b/yarn.lock index 9f25b4f..8bf67ff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3978,6 +3978,39 @@ braces@^3.0.1, braces@~3.0.2: dependencies: fill-range "^7.0.1" +braft-convert@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/braft-convert/-/braft-convert-2.3.0.tgz#27d5905136c334903d083b7a2352a72045627888" + integrity sha512-5km+dLHk8iYDv2iEYDrDQ2ld/ZoUx66QLql0qdm5PqZEcNXc8dBHGLORfzeu3iMw1jLeAiHxtdY5+ypuIhczVg== + dependencies: + draft-convert "^2.0.0" + draft-js "^0.10.3" + +braft-editor@^2.3.9: + version "2.3.9" + resolved "https://registry.yarnpkg.com/braft-editor/-/braft-editor-2.3.9.tgz#fd2b8e23ea71191016579a1ed8231d16ad8f5b4a" + integrity sha512-mqdPk/zI2dhFK8tW/A4Qj/AkkARLh5L/niNw+iif5wFqb6zh15rMlrShgz1nWO/QXyAKr8XtDgxiBbR0zWwtRg== + dependencies: + "@babel/runtime" "^7.0.0" + braft-convert "^2.3.0" + braft-finder "^0.0.19" + braft-utils "^3.0.8" + draft-convert "^2.0.0" + draft-js "^0.10.3" + draft-js-multidecorators "^1.0.0" + draftjs-utils "^0.9.4" + immutable "~3.7.4" + +braft-finder@^0.0.19: + version "0.0.19" + resolved "https://registry.yarnpkg.com/braft-finder/-/braft-finder-0.0.19.tgz#c324d82526ed3476a93de86cc9b407f4e188bc8d" + integrity sha512-0kzI6/KbomJJhYX1hpjn4edCKhblyUyWdUrsgBmOrwy0vrj+pPkm69+Uf8Uj6KGAULM6LF0ooC++p7fqUGgFHw== + +braft-utils@^3.0.8: + version "3.0.12" + resolved "https://registry.yarnpkg.com/braft-utils/-/braft-utils-3.0.12.tgz#2b755ce1d8397d96b627b6767f74d07f25729d85" + integrity sha512-O2cKysURNC4HSEMKgNmQ2RluwcrxvYrztlEmyPN5SzktiNX3vaLFQoo0Ez3PlIhvjaGrIBSIT2Oyh2N6mn6TFg== + brorand@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" @@ -5618,6 +5651,36 @@ dotenv@8.2.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== +draft-convert@^2.0.0: + version "2.1.10" + resolved "https://registry.yarnpkg.com/draft-convert/-/draft-convert-2.1.10.tgz#07552f0aadff7ac01c8619d769210d4ea8fcab77" + integrity sha512-PRdcjBqFUfEb2jlPM+bOyyCNlTzGaHdyhvKsw5nur6Dj1YclmuAiTwJ8yTsEa95YI9kwzbO5ccZ/+tYj/LlS0A== + dependencies: + "@babel/runtime" "^7.5.5" + immutable "~3.7.4" + invariant "^2.2.1" + +draft-js-multidecorators@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/draft-js-multidecorators/-/draft-js-multidecorators-1.0.0.tgz#6c4be8d7b78dd2b966ee51ee6cc179b9b535e612" + integrity sha1-bEvo17eN0rlm7lHubMF5ubU15hI= + dependencies: + immutable "*" + +draft-js@^0.10.3: + version "0.10.5" + resolved "https://registry.yarnpkg.com/draft-js/-/draft-js-0.10.5.tgz#bfa9beb018fe0533dbb08d6675c371a6b08fa742" + integrity sha512-LE6jSCV9nkPhfVX2ggcRLA4FKs6zWq9ceuO/88BpXdNCS7mjRTgs0NsV6piUCJX9YxMsB9An33wnkMmU2sD2Zg== + dependencies: + fbjs "^0.8.15" + immutable "~3.7.4" + object-assign "^4.1.0" + +draftjs-utils@^0.9.4: + version "0.9.4" + resolved "https://registry.yarnpkg.com/draftjs-utils/-/draftjs-utils-0.9.4.tgz#976c61aa133dbbbfedd65ae1dd6627d7b98c6f08" + integrity sha512-KYjABSbGpJrwrwmxVj5UhfV37MF/p0QRxKIyL+/+QOaJ8J9z1FBKxkblThbpR0nJi9lxPQWGg+gh+v0dAsSCCg== + duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" @@ -6486,7 +6549,7 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" -fbjs@^0.8.0, fbjs@^0.8.3, fbjs@^0.8.9: +fbjs@^0.8.0, fbjs@^0.8.15, fbjs@^0.8.3, fbjs@^0.8.9: version "0.8.17" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= @@ -7415,11 +7478,16 @@ immer@^7.0.5: resolved "https://registry.yarnpkg.com/immer/-/immer-7.0.9.tgz#28e7552c21d39dd76feccd2b800b7bc86ee4a62e" integrity sha512-Vs/gxoM4DqNAYR7pugIxi0Xc8XAun/uy7AQu4fLLqaTBHxjOP9pJ266Q9MWA/ly4z6rAFZbvViOtihxUZ7O28A== -immutable@^3.8.1: +immutable@*, immutable@^3.8.1: version "3.8.2" resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM= +immutable@~3.7.4: + version "3.7.6" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.7.6.tgz#13b4d3cb12befa15482a26fe1b2ebae640071e4b" + integrity sha1-E7TTyxK++hVIKib+Gy665kAHHks= + import-cwd@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9"