Commit 776dfe7c by wufan

feat:完成h5banner

parent 6ba731e7
...@@ -26,6 +26,11 @@ ...@@ -26,6 +26,11 @@
width: 230px; width: 230px;
height: 79px; height: 79px;
} }
.web-banner-thumbnail {
width: 389px;
height: 67px;
}
.index-num { .index-num {
width: 30px; width: 30px;
height: 33px; height: 33px;
...@@ -88,5 +93,9 @@ ...@@ -88,5 +93,9 @@
width: 500px; width: 500px;
height: 73px; height: 73px;
} }
#H5-preview-url-box {
width: 500px;
height: 172px;
}
} }
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: wufan * @Author: wufan
* @Date: 2020-11-30 10:47:38 * @Date: 2020-11-30 10:47:38
* @LastEditors: wufan * @LastEditors: wufan
* @LastEditTime: 2020-12-21 14:12:44 * @LastEditTime: 2020-12-22 11:52:56
* @Description: 员工管理页面 * @Description: 员工管理页面
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -26,7 +26,7 @@ interface StoreDecoprationProps { ...@@ -26,7 +26,7 @@ interface StoreDecoprationProps {
} }
function StoreDecorationPage(props: StoreDecoprationProps) { function StoreDecorationPage(props: StoreDecoprationProps) {
const [currentTab, setCurrentTab] = useState("web"); const [currentTab, setCurrentTab] = useState("h5");
const { match } = props; const { match } = props;
return ( return (
...@@ -52,17 +52,6 @@ function StoreDecorationPage(props: StoreDecoprationProps) { ...@@ -52,17 +52,6 @@ function StoreDecorationPage(props: StoreDecoprationProps) {
currentTab === 'web' && <StoreWebDecorationTab/> currentTab === 'web' && <StoreWebDecorationTab/>
} }
{/* <Switch>
<Route
path="/store-decoration/h5"
component={StoreH5DecorationTab}
></Route>
<Route
path="/store-decoration/web"
component={StoreWebDecorationTab}
></Route>
</Switch> */}
</div> </div>
</div> </div>
</div> </div>
......
...@@ -2,15 +2,14 @@ ...@@ -2,15 +2,14 @@
* @Author: wufan * @Author: wufan
* @Date: 2020-11-30 10:47:38 * @Date: 2020-11-30 10:47:38
* @LastEditors: wufan * @LastEditors: wufan
* @LastEditTime: 2020-12-21 10:57:53 * @LastEditTime: 2020-12-22 13:48:59
* @Description: h5店铺banner页面 * @Description: web店铺banner页面
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React, { useEffect, useState } from "react"; import React from "react";
import { withRouter } from "react-router-dom"; import { withRouter } from "react-router-dom";
import _ from "underscore"; import _ from "underscore";
import PageControl from "@/components/PageControl";
import { Table, Modal, message, Button } from "antd"; import { Table, Modal, message, Button } from "antd";
import { QuestionCircleOutlined } from "@ant-design/icons"; import { QuestionCircleOutlined } from "@ant-design/icons";
import StoreService from "@/domains/store-domain/storeService"; import StoreService from "@/domains/store-domain/storeService";
...@@ -24,102 +23,54 @@ import arrayMove from "array-move"; ...@@ -24,102 +23,54 @@ import arrayMove from "array-move";
import "./StoreDecorationPage.less"; import "./StoreDecorationPage.less";
import User from "@/common/js/user"; import User from "@/common/js/user";
import SelectPrepareFileModal from "@/modules/prepare-lesson/modal/SelectPrepareFileModal"; import SelectPrepareFileModal from "@/modules/prepare-lesson/modal/SelectPrepareFileModal";
import './StoreDecorationPage.less'; import "./StoreDecorationPage.less";
import Upload from "@/core/upload";
const { confirm } = Modal; const { confirm } = Modal;
const DragHandle = sortableHandle(() => (
<MenuOutlined
style={{ cursor: "pointer", color: "#999" }}
className="drag-icon"
/>
));
const SortableItem = sortableElement((props) => <tr {...props} />);
const SortableContainer = sortableContainer((props) => <tbody {...props} />);
let cutFlag = false;
function StoreH5Decoration(props) { class StoreWebDecoration extends React.Component {
const [storeDecorationlist, setStoreDecorationlist] = useState([ constructor(props) {
{ super(props);
id: 1111, this.state = {
bannerPath: "https://image.xiaomaiketang.com/xm/rJeQaZxtc7.png", storeDecorationlist: [],
sequence: 0, query: {
}, storeId: User.getStoreId(),
{ termType: "H5_ADMIN",
id: 1111,
bannerPath: "https://image.xiaomaiketang.com/xm/CMyWNaDxbM.jpg",
sequence: 1,
},
{
id: 1111,
bannerPath: "https://image.xiaomaiketang.com/xm/pBcJdYkmNN.jpg",
sequence: 2,
},
{
id: 1111,
bannerPath: "https://image.xiaomaiketang.com/xm/p7hG4exMFf.png",
sequence: 3,
},
]);
const [query, setQuery] = useState({
storeId: User.getStoreId(),
termType: "H5_ADMIN",
});
const [showSelectFileModal, setShowSelectFileModal] = useState(false);
const [diskList, setDiskList] = useState([]);
const [visible, setVisible] = useState(false);
const DragHandle = sortableHandle(() => (
<MenuOutlined
style={{ cursor: "pointer", color: "#999" }}
className="drag-icon"
/>
));
const SortableItem = sortableElement((props) => <tr {...props} />);
const SortableContainer = sortableContainer((props) => <tbody {...props} />);
useEffect(() => {
getStoreDecorationList();
}, [query]);
function getStoreDecorationList() {
StoreService.getStoreDecorationList(query).then((res) => {
setStoreDecorationlist(res.result);
});
}
function handleReplaceDecoration(record) {}
function handleDeleteDecoration(record) {
StoreService.deleteStoreDecorationList({
storeBannerId: record.id,
termType: "H5_ADMIN",
}).then((res) => {
message.success("已删除");
});
}
function handleDeleteDecorationConfirm(record) {
return confirm({
title: "你确定要删除这个banner吗?",
icon: <QuestionCircleOutlined />,
okText: "删除",
cancelText: "取消",
onOk: () => {
handleDeleteDecoration(record);
}, },
}); showSelectFileModal: false,
diskList: [],
photoclip: null,
preview: "",
};
} }
function onSortEnd({ oldIndex, newIndex }) { componentDidMount() {
if (oldIndex !== newIndex) { this.getStoreDecorationList();
const newData = arrayMove(
[].concat(storeDecorationlist),
oldIndex,
newIndex
).filter((el) => !!el);
console.log("Sorted items: ", newData);
setStoreDecorationlist(newData);
}
} }
function DraggableBodyRow({ className, style, ...restProps }) { getStoreDecorationList = () => {
const index = storeDecorationlist.findIndex( StoreService.getStoreDecorationList(this.state.query).then((res) => {
(x) => x.index === restProps["data-row-key"] const data = _.map(res.result, (item, index) => {
); item.index = index;
return <SortableItem index={index} {...restProps} />; item.key = index;
} return item;
});
this.setState({
storeDecorationlist: data,
});
});
};
function parseColumn() { parseColumn = () => {
return [ return [
{ {
title: "Sort", title: "Sort",
...@@ -138,9 +89,10 @@ function StoreH5Decoration(props) { ...@@ -138,9 +89,10 @@ function StoreH5Decoration(props) {
}, },
}, },
{ {
title: "bannerPath", title: "banner",
dataIndex: "bannerPath", dataIndex: "bannerPath",
key: "bannerPath", key: "bannerPath",
className: "drag-visible",
render: (val) => { render: (val) => {
return <img src={val} alt="banner" className="banner-thumbnail" />; return <img src={val} alt="banner" className="banner-thumbnail" />;
}, },
...@@ -149,19 +101,20 @@ function StoreH5Decoration(props) { ...@@ -149,19 +101,20 @@ function StoreH5Decoration(props) {
title: "操作", title: "操作",
dataIndex: "operation", dataIndex: "operation",
width: "20%", width: "20%",
className: "drag-visible",
render: (val, record) => { render: (val, record) => {
return ( return (
<div className="operation"> <div className="operation">
<span <span
className="edit" className="edit"
onClick={() => handleReplaceDecoration(record)} onClick={() => this.handleReplaceDecoration(record)}
> >
替换 替换
</span> </span>
<span className="divider-line">{" | "}</span> <span className="divider-line">{" | "}</span>
<span <span
className="delete" className="delete"
onClick={() => handleDeleteDecorationConfirm(record)} onClick={() => this.handleDeleteDecorationConfirm(record)}
> >
删除 删除
</span> </span>
...@@ -170,110 +123,316 @@ function StoreH5Decoration(props) { ...@@ -170,110 +123,316 @@ function StoreH5Decoration(props) {
}, },
}, },
]; ];
} };
function handleToAddStoreDecoration() { handleToAddStoreDecoration = () => {
setShowSelectFileModal(true); this.setState({
} showSelectFileModal: true,
});
};
handleReplaceDecoration = (record) => {
this.setState({
showSelectFileModal: true,
choosedBannerId: record.id,
});
};
handleDeleteDecoration = (record) => {
StoreService.deleteStoreDecorationList({
storeBannerId: record.id,
termType: "H5_ADMIN",
}).then((res) => {
message.success("已删除");
this.getStoreDecorationList();
});
};
handleDeleteDecorationConfirm = (record) => {
return confirm({
title: "你确定要删除这个banner吗?",
icon: (
<span className="icon iconfont default-confirm-icon">&#xe834;</span>
),
okText: "删除",
cancelText: "取消",
onOk: () => {
this.handleDeleteDecoration(record);
},
});
};
onSortEnd = ({ oldIndex, newIndex }) => {
const { storeDecorationlist } = this.state;
if (oldIndex !== newIndex) {
const newData = arrayMove(
[].concat(storeDecorationlist),
oldIndex,
newIndex
).filter((el) => !!el);
this.setState(
{
storeDecorationlist: newData,
newSequence: storeDecorationlist[newIndex].sequence,
storeBannerId: storeDecorationlist[oldIndex].id,
},
() => {
this.moveBannerSequence();
}
);
}
};
DraggableBodyRow = ({ className, style, ...restProps }) => {
const { storeDecorationlist } = this.state;
// function findIndex base on Table rowKey props and should always be a right array index
const index = storeDecorationlist.findIndex(
(x) => x.index === restProps["data-row-key"]
);
return <SortableItem index={index} {...restProps} />;
};
// 选择暖场资源 // 选择暖场资源
function handleSelectVideo(file) { handleSelectVideo = (file) => {
setShowSelectFileModal(false); this.setState({
const { ossUrl, resourceId, folderName, folderFormat, folderSize } = file; showSelectFileModal: false,
const liveCourseWarmMedia = { });
contentType: "WARMUP", this.uploadImage(file);
mediaType: folderFormat === "MP4" ? "VIDEO" : "PICTURE", };
mediaContent: resourceId,
mediaUrl: ossUrl, //上传图片
mediaName: folderName, uploadImage = (imageFile) => {
size: folderSize, const { folderName } = imageFile;
const fileName =
window.random_string(16) + folderName.slice(folderName.lastIndexOf("."));
this.setState(
{
visible: true,
},
() => {
setTimeout(() => {
const okBtnDom = document.querySelector("#headPicModal");
const viewImgDom = document.querySelector("#H5-preview-url-box");
const options = {
size: [500, 172],
rotateFree: false,
ok: okBtnDom,
view: viewImgDom,
maxZoom: 3,
style: {
jpgFillColor: "transparent",
},
done: (dataUrl) => {
const cutImage = this.convertBase64UrlToBlob(dataUrl);
this.getSignature(cutImage, fileName);
setTimeout(() => {
cutFlag = false;
}, 2000);
},
fail: (failInfo) => {
console.log("failInfo-----", failInfo);
},
loadComplete: (img) => {
this.refs.headPicModal.click();
this.setState({
previewUrl: img.src,
});
},
};
if (!this.state.photoclip) {
const photoclip = new PhotoClip("#headPicModal", options);
photoclip.load(imageFile.ossUrl);
console.log("photoclip-222", photoclip);
this.setState({
photoclip,
});
} else {
this.state.photoclip.clear();
this.state.photoclip.load(imageFile.ossUrl);
}
}, 200);
}
);
};
//获取resourceId
getSignature = (blob) => {
Upload.uploadBlobToOSS(blob, "avatar" + new Date().valueOf()).then(
(addBannerPath) => {
this.setState({
addBannerPath,
});
}
);
};
editStoreBanner = () => {
const { addBannerPath, choosedBannerId } = this.state;
const params = {
bannerPath: addBannerPath,
storeBannerId: choosedBannerId,
termType: "H5_ADMIN",
}; };
console.log("liveCourseWarmMedia", liveCourseWarmMedia); StoreService.editStoreBanner(params).then((res) => {
message.success("设置成功");
} this.getStoreDecorationList();
});
};
moveBannerSequence = () => {
const { newSequence, storeBannerId } = this.state;
const params = {
sequence: newSequence,
storeBannerId: storeBannerId,
termType: "H5_ADMIN",
};
StoreService.moveBannerSequence(params).then((res) => {
this.getStoreDecorationList();
});
};
addStoreBanner = () => {
const { addBannerPath } = this.state;
const params = {
bannerPath: addBannerPath,
storeId: User.getStoreId(),
termType: "H5_ADMIN",
};
StoreService.addStoreBanner(params).then((res) => {
message.success("设置成功");
this.getStoreDecorationList();
});
};
const DraggableContainer = (props) => ( // base64转换成blob
<SortableContainer convertBase64UrlToBlob = (urlData) => {
useDragHandle const bytes = window.atob(urlData.split(",")[1]);
helperClass="row-dragging" const ab = new ArrayBuffer(bytes.length);
onSortEnd={onSortEnd} const ia = new Uint8Array(ab);
{...props} for (let i = 0; i < bytes.length; i++) {
/> ia[i] = bytes.charCodeAt(i);
); }
return new Blob([ab], { type: "image/png" });
};
return ( render() {
<div className="user-manage-page"> const {
<div className="box-header"> storeDecorationlist,
<div className="banner-setting"> showSelectFileModal,
<div className="title">banner设置</div> diskList,
<div className="tip"> visible,
图片支持bmp、jpeg、jpg、png、gif格式,最大5M,最多可添加5张,拖动可排序。建议尺寸750x252像素。 } = this.state;
const DraggableContainer = (props) => (
<SortableContainer
useDragHandle
helperClass="row-dragging"
onSortEnd={this.onSortEnd}
{...props}
/>
);
return (
<div className="user-manage-page">
<div className="box-header">
<div className="banner-setting">
<div className="title">banner设置</div>
<div className="tip">
图片支持bmp、jpeg、jpg、png、gif格式,最大5M,最多可添加5张,拖动可排序。建议尺寸750x252像素。
</div>
</div> </div>
<Button
onClick={() => {
this.handleToAddStoreDecoration();
}}
type="primary"
className="add-show-btn"
>
添加Banner
</Button>
</div> </div>
<Button <div className="box-body">
onClick={() => { <Table
handleToAddStoreDecoration(); size={"middle"}
}} pagination={false}
type="primary" dataSource={storeDecorationlist}
className="add-show-btn" columns={this.parseColumn()}
> rowKey={(item) => item.index}
添加Banner components={{
</Button> body: {
</div> wrapper: DraggableContainer,
<div className="box-body"> row: this.DraggableBodyRow,
<Table },
size={"middle"} }}
pagination={false} bordered
dataSource={storeDecorationlist} />
columns={parseColumn()} </div>
rowKey={(item) => item.index} <SelectPrepareFileModal
components={{ operateType="select"
body: { accept="image/jpeg,image/png,image/jpg"
wrapper: DraggableContainer, selectTypeList={["JPG", "JPEG", "PNG"]}
row: DraggableBodyRow, tooltip="支持文件类型:jpg、jpeg、png"
}, isOpen={showSelectFileModal}
diskList={diskList}
onClose={() => {
this.setState({ showSelectFileModal: false });
}} }}
bordered onSelect={this.handleSelectVideo}
/> />
</div> <Modal
<SelectPrepareFileModal
operateType="select"
accept="image/jpeg,image/png,image/jpg"
selectTypeList={["JPG", "JPEG", "PNG"]}
tooltip="支持文件类型:jpg、jpeg、png、mp4"
isOpen={showSelectFileModal}
diskList={diskList}
onClose={() => {
setShowSelectFileModal(false);
}}
onSelect={handleSelectVideo}
/>
<Modal
title="设置图片" title="设置图片"
width={1080} width={1080}
visible={visible} visible={visible}
onCancel={() => { setVisible(false)}} onCancel={() => {
this.setState({ visible: false });
}}
footer={[ footer={[
<Button key="reUpload" onClick={() => { setShowSelectFileModal(true); <Button
}}>重新上传</Button>, key="back"
<Button key="submit" type="primary" onClick={() => { onClick={() => {
if (!cutFlag) { this.setState({ visible: false });
cutFlag = true; this.handleToAddStoreDecoration();
this.refs.hiddenBtn.click(); }}
} >
}}> 重新上传
</Button>,
<Button
key="submit"
type="primary"
onClick={() => {
if (!cutFlag) {
cutFlag = true;
this.refs.hiddenBtn.click();
}
this.setState({ visible: false });
this.state.choosedBannerId
? this.editStoreBanner()
: this.addStoreBanner();
}}
>
确定 确定
</Button>, </Button>,
]}> ]}
<div id="headPicModal" style={{ >
width: '502px', <div className="clip-box">
height: '283px', <div
'marginBottom': 0 id="headPicModal"
}}></div> ref="headPicModal"
<div id="clipBtn" style={{ display: 'none' }} ref="hiddenBtn"></div> style={{
width: "500px",
height: "430px",
marginBottom: 0,
}}
></div>
<div id="clipBtn" style={{ display: "none" }} ref="hiddenBtn"></div>
<div className="preview-img">
<div className="title">效果预览</div>
<div id="H5-preview-url-box"></div>
</div>
</div>
</Modal> </Modal>
</div> </div>
); );
}
} }
export default withRouter(StoreH5Decoration); export default withRouter(StoreWebDecoration);
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: wufan * @Author: wufan
* @Date: 2020-11-30 10:47:38 * @Date: 2020-11-30 10:47:38
* @LastEditors: wufan * @LastEditors: wufan
* @LastEditTime: 2020-12-22 10:17:11 * @LastEditTime: 2020-12-22 13:49:20
* @Description: web店铺banner页面 * @Description: web店铺banner页面
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -41,28 +41,7 @@ class StoreWebDecoration extends React.Component { ...@@ -41,28 +41,7 @@ class StoreWebDecoration extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
storeDecorationlist: [ storeDecorationlist: [],
// {
// id: "1111",
// bannerPath: "https://image.xiaomaiketang.com/xm/rJeQaZxtc7.png",
// index: 0,
// key: "0",
// name: "https://image.xiaomaiketang.com/xm/rJeQaZxtc7.png",
// },
// {
// id: "222",
// bannerPath: "https://image.xiaomaiketang.com/xm/CMyWNaDxbM.jpg",
// index: 1,
// key: "1",
// name: "校长",
// },
// {
// id: "333",
// bannerPath: "https://image.xiaomaiketang.com/xm/pBcJdYkmNN.jpg",
// index: 2,
// key: "2",
// },
],
query: { query: {
storeId: User.getStoreId(), storeId: User.getStoreId(),
termType: "WEB_ADMIN", termType: "WEB_ADMIN",
...@@ -115,7 +94,7 @@ class StoreWebDecoration extends React.Component { ...@@ -115,7 +94,7 @@ class StoreWebDecoration extends React.Component {
key: "bannerPath", key: "bannerPath",
className: "drag-visible", className: "drag-visible",
render: (val) => { render: (val) => {
return <img src={val} alt="banner" className="banner-thumbnail" />; return <img src={val} alt="banner" className="web-banner-thumbnail" />;
}, },
}, },
{ {
...@@ -299,16 +278,15 @@ class StoreWebDecoration extends React.Component { ...@@ -299,16 +278,15 @@ class StoreWebDecoration extends React.Component {
}; };
editStoreBanner = () => { editStoreBanner = () => {
const { previewUrl, addBannerPath, choosedBannerId } = this.state; const { addBannerPath, choosedBannerId } = this.state;
const params = { const params = {
bannerPath: addBannerPath, bannerPath: addBannerPath,
storeBannerId: choosedBannerId, storeBannerId: choosedBannerId,
termType: "WEB_ADMIN", termType: "WEB_ADMIN",
}; };
StoreService.editStoreBanner(params).then((res) => { StoreService.editStoreBanner(params).then((res) => {
message.success("替换成功"); message.success("设置成功");
this.getStoreDecorationList(); this.getStoreDecorationList();
// this.state.photoclip.destroy();
}); });
}; };
...@@ -317,7 +295,6 @@ class StoreWebDecoration extends React.Component { ...@@ -317,7 +295,6 @@ class StoreWebDecoration extends React.Component {
const params = { const params = {
sequence: newSequence, sequence: newSequence,
storeBannerId: storeBannerId, storeBannerId: storeBannerId,
// storeId: User.getStoreId(),
termType: "WEB_ADMIN", termType: "WEB_ADMIN",
}; };
StoreService.moveBannerSequence(params).then((res) => { StoreService.moveBannerSequence(params).then((res) => {
...@@ -332,7 +309,7 @@ class StoreWebDecoration extends React.Component { ...@@ -332,7 +309,7 @@ class StoreWebDecoration extends React.Component {
termType: "WEB_ADMIN", termType: "WEB_ADMIN",
}; };
StoreService.addStoreBanner(params).then((res) => { StoreService.addStoreBanner(params).then((res) => {
message.success("添加成功"); message.success("设置成功");
this.getStoreDecorationList(); this.getStoreDecorationList();
}); });
}; };
...@@ -353,7 +330,6 @@ class StoreWebDecoration extends React.Component { ...@@ -353,7 +330,6 @@ class StoreWebDecoration extends React.Component {
storeDecorationlist, storeDecorationlist,
showSelectFileModal, showSelectFileModal,
diskList, diskList,
previewUrl,
visible, visible,
} = this.state; } = this.state;
const DraggableContainer = (props) => ( const DraggableContainer = (props) => (
...@@ -370,7 +346,7 @@ class StoreWebDecoration extends React.Component { ...@@ -370,7 +346,7 @@ class StoreWebDecoration extends React.Component {
<div className="banner-setting"> <div className="banner-setting">
<div className="title">banner设置</div> <div className="title">banner设置</div>
<div className="tip"> <div className="tip">
图片支持bmp、jpeg、jpg、png、gif格式,最大5M,最多可添加5张,拖动可排序。建议尺寸750x252像素。 图片支持bmp、jpeg、jpg、png、gif格式,最大5M,最多可添加5张,拖动可排序。建议尺寸1232x212像素。
</div> </div>
</div> </div>
<Button <Button
...@@ -459,7 +435,6 @@ class StoreWebDecoration extends React.Component { ...@@ -459,7 +435,6 @@ class StoreWebDecoration extends React.Component {
<div id="clipBtn" style={{ display: "none" }} ref="hiddenBtn"></div> <div id="clipBtn" style={{ display: "none" }} ref="hiddenBtn"></div>
<div className="preview-img"> <div className="preview-img">
<div className="title">效果预览</div> <div className="title">效果预览</div>
{/* <img src={previewUrl} alt="图片预览" className="preview-url" /> */}
<div id="preview-url-box"></div> <div id="preview-url-box"></div>
</div> </div>
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment