Commit 7b685e7a by guomingpang
parents eda60cb7 806f97d6
...@@ -80,6 +80,7 @@ ...@@ -80,6 +80,7 @@
"react": "^16.13.1", "react": "^16.13.1",
"react-app-polyfill": "^1.0.6", "react-app-polyfill": "^1.0.6",
"react-async-component": "^2.0.0", "react-async-component": "^2.0.0",
"react-cropper": "^2.1.8",
"react-dev-utils": "^10.2.1", "react-dev-utils": "^10.2.1",
"react-dom": "^16.13.1", "react-dom": "^16.13.1",
"react-infinite-scroller": "^1.2.4", "react-infinite-scroller": "^1.2.4",
......
import React from 'react';
import { Modal, Button } from 'antd';
import Cropper from 'react-cropper';
import 'cropperjs/dist/cropper.css';
import './ImgClipModal.less';
import { isNull } from 'underscore';
class ImgClipModal extends React.Component {
constructor(props) {
super(props);
this.state = {
hasImgReady: false, // 图片是否上传成功
cropperInstace:null,
}
}
render() {
const {
imgUrl,
title = "设置图片",
modalWidth=1080,
visible,
clipContentWidth='500px',
clipContentHeight='430px',
aspectRatio=16/9,
cropBoxWidth=500,
cropBoxHeight=282,
previewBoxWidth='500px',
previewBoxHeight='282px',
onConfirm,
onClose,
} = this.props;
const { hasImgReady,cropperInstace} = this.state;
return (
<Modal
className="img-clip-modal"
title={title}
width={modalWidth}
visible={visible}
maskClosable={false}
closeIcon={<span className="icon iconfont modal-close-icon">&#xe6ef;</span>}
onCancel={() => {
onClose();
}}
zIndex={10001}
footer={[
<Button
key="back"
onClick={() => {
onClose();
}}
>
重新上传
</Button>,
<Button
key="submit"
type="primary"
disabled={!hasImgReady}
onClick={() => {
const cutImg = this.state.cropperInstace.getCroppedCanvas().toDataURL();
const cutImageBlob = window.convertBase64ToBlob(cutImg);
onConfirm(cutImageBlob);
}}
>
确定
</Button>,
]}
>
<div className="clip-box">
<div
style={{
width:clipContentWidth,
height:clipContentHeight,
marginBottom: 0,
}}
>
<Cropper
style={{ height:clipContentHeight, width:clipContentWidth}}
className="cropper__box"
zoomTo={2}
aspectRatio={aspectRatio}
preview=".preview-url-box"
src={imgUrl}
viewMode={1}
guides={true}
background={false}
responsive={true}
autoCropArea={1}
checkOrientation={false}
cropBoxResizable={false}
center={true}
cropBoxMovable={false}
dragMode='move'
onInitialized={(instance) => {
this.setState({
cropperInstace:instance
})
}}
ready={()=>{
this.setState({
hasImgReady:true
})
this.state.cropperInstace.setCropBoxData({width:Number(cropBoxWidth),height:Number(cropBoxHeight),top:(215 - cropBoxHeight/2)});
console.log("height++++",this.state.cropperInstace.getImageData().height);
console.log("width++++",this.state.cropperInstace.getImageData().width);
const ratio = (this.state.cropperInstace.getImageData().width/2)/500;
console.log("ratio++++",ratio);
this.state.cropperInstace.setCanvasData({width:500});
const that = this;
document.querySelector('.cropper__box').addEventListener('dblclick', function (e) {
that.state.cropperInstace.rotate(90)
});
}}
/>
</div>
<div id="clipBtn" style={{ display: "none" }} ref="hiddenBtn"></div>
<div className="preview-img">
<div className="title">效果预览</div>
<div id="preview-url-box" style={{width:previewBoxWidth,height:previewBoxHeight}} className="preview-url-box">
</div>
<div className="tip-box">
<div className="tip">温馨提示</div>
<div className="tip">①预览效果图时可能存在延迟,单击左侧图片刷新即可</div>
<div className="tip">②设置图片时双击可旋转图片,滚动可放大或缩小图片</div>
</div>
</div>
</div>
</Modal>
)
}
}
export default ImgClipModal;
\ No newline at end of file
.img-clip-modal{
.preview-url-box{
overflow: hidden;
}
}
/*
* @Author: your name
* @Date: 2021-07-02 17:15:50
* @LastEditTime: 2021-07-04 18:10:34
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: /xiaomai-cloud-class-web/src/core/downLoad.js
*/
window.download = function download(data, strFileName, strMimeType) {
var self = window, // this script is only for browsers anyway...
defaultMime = 'application/octet-stream', // this default mime also triggers iframe downloads
mimeType = strMimeType || defaultMime,
payload = data,
url = !strFileName && !strMimeType && payload,
anchor = document.createElement('a'),
toString = function (a) {
return String(a);
},
myBlob = self.Blob || self.MozBlob || self.WebKitBlob || toString,
fileName = strFileName || 'download',
blob,
reader;
myBlob = myBlob.call ? myBlob.bind(self) : Blob;
if (String(this) === 'true') {
//reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
payload = [payload, mimeType];
mimeType = payload[0];
payload = payload[1];
}
if (url && url.length < 2048) {
// if no filename and no mime, assume a url was passed as the only argument
fileName = url.split('/').pop().split('?')[0];
anchor.href = url; // assign href prop to temp anchor
if (anchor.href.indexOf(url) !== -1) {
// if the browser determines that it's a potentially valid url path:
var ajax = new XMLHttpRequest();
ajax.open('GET', url, true);
ajax.responseType = 'blob';
ajax.onload = function (e) {
download(e.target.response, fileName, defaultMime);
};
setTimeout(function () {
ajax.send();
}, 0); // allows setting custom ajax headers using the return:
return ajax;
} // end if valid url?
} // end if url?
//go ahead and download dataURLs right away
if (/^data\:[\w+\-]+\/[\w+\-]+[,;]/.test(payload)) {
if (payload.length > 1024 * 1024 * 1.999 && myBlob !== toString) {
payload = dataUrlToBlob(payload);
mimeType = payload.type || defaultMime;
} else {
return navigator.msSaveBlob // IE10 can't do a[download], only Blobs:
? navigator.msSaveBlob(dataUrlToBlob(payload), fileName)
: saver(payload); // everyone else can save dataURLs un-processed
}
} //end if dataURL passed?
blob = payload instanceof myBlob ? payload : new myBlob([payload], { type: mimeType });
function dataUrlToBlob(strUrl) {
var parts = strUrl.split(/[:;,]/),
type = parts[1],
decoder = parts[2] == 'base64' ? atob : decodeURIComponent,
binData = decoder(parts.pop()),
mx = binData.length,
i = 0,
uiArr = new Uint8Array(mx);
for (i; i < mx; ++i) uiArr[i] = binData.charCodeAt(i);
return new myBlob([uiArr], { type: type });
}
function saver(url, winMode) {
if ('download' in anchor) {
//html5 A[download]
anchor.href = url;
anchor.setAttribute('download', fileName);
anchor.className = 'download-js-link';
anchor.innerHTML = 'downloading...';
anchor.style.display = 'none';
document.body.appendChild(anchor);
setTimeout(function () {
anchor.click();
document.body.removeChild(anchor);
if (winMode === true) {
setTimeout(function () {
self.URL.revokeObjectURL(anchor.href);
}, 250);
}
}, 66);
return true;
}
// handle non-a[download] safari as best we can:
if (/(Version)\/(\d+)\.(\d+)(?:\.(\d+))?.*Safari\//.test(navigator.userAgent)) {
url = url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
if (!window.open(url)) {
// popup blocked, offer direct download:
if (window.confirm('Displaying New Document\n\nUse Save As... to download, then click back to return to this page.')) {
window.location.href = url;
}
}
return true;
}
//do iframe dataURL download (old ch+FF):
var f = document.createElement('iframe');
document.body.appendChild(f);
if (!winMode) {
// force a mime that will download:
url = 'data:' + url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
}
f.src = url;
setTimeout(function () {
document.body.removeChild(f);
}, 333);
} //end saver
if (navigator.msSaveBlob) {
// IE10+ : (has Blob, but not a[download] or URL)
return navigator.msSaveBlob(blob, fileName);
}
if (self.URL) {
// simple fast and modern way using Blob and URL:
saver(self.URL.createObjectURL(blob), true);
} else {
// handle non-Blob()+non-URL browsers:
if (typeof blob === 'string' || blob.constructor === toString) {
try {
return saver('data:' + mimeType + ';base64,' + self.btoa(blob));
} catch (y) {
return saver('data:' + mimeType + ',' + encodeURIComponent(blob));
}
}
// Blob but not URL support:
reader = new FileReader();
reader.onload = function (e) {
saver(this.result);
};
reader.readAsDataURL(blob);
}
return true;
}; /* end download() */
\ No newline at end of file
<!-- <!--
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-08-24 12:20:57 * @Date: 2020-08-24 12:20:57
* @LastEditors: fusanqiasng * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-21 15:06:27 * @LastEditTime: 2021-07-08 19:38:52
* @Description: * @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有 * @Copyright: 杭州杰竞科技有限公司 版权所有
--> -->
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div> <div id="root"></div>
<!-- <!--
This HTML file is a template. This HTML file is a template.
If you open it directly in the browser, you will see an empty page. If you open it directly in the browser, you will see an empty page.
...@@ -61,166 +62,6 @@ ...@@ -61,166 +62,6 @@
To begin the development, run `npm start` or `yarn start`. To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`. To create a production bundle, use `npm run build` or `yarn build`.
--> -->
<script>
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], factory);
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory();
} else {
// Browser globals (root is window)
root.download = factory();
}
})(this, function () {
return function download(data, strFileName, strMimeType) {
var self = window, // this script is only for browsers anyway...
defaultMime = 'application/octet-stream', // this default mime also triggers iframe downloads
mimeType = strMimeType || defaultMime,
payload = data,
url = !strFileName && !strMimeType && payload,
anchor = document.createElement('a'),
toString = function (a) {
return String(a);
},
myBlob = self.Blob || self.MozBlob || self.WebKitBlob || toString,
fileName = strFileName || 'download',
blob,
reader;
myBlob = myBlob.call ? myBlob.bind(self) : Blob;
if (String(this) === 'true') {
//reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
payload = [payload, mimeType];
mimeType = payload[0];
payload = payload[1];
}
if (url && url.length < 2048) {
// if no filename and no mime, assume a url was passed as the only argument
fileName = url.split('/').pop().split('?')[0];
anchor.href = url; // assign href prop to temp anchor
if (anchor.href.indexOf(url) !== -1) {
// if the browser determines that it's a potentially valid url path:
var ajax = new XMLHttpRequest();
ajax.open('GET', url, true);
ajax.responseType = 'blob';
ajax.onload = function (e) {
download(e.target.response, fileName, defaultMime);
};
setTimeout(function () {
ajax.send();
}, 0); // allows setting custom ajax headers using the return:
return ajax;
} // end if valid url?
} // end if url?
//go ahead and download dataURLs right away
if (/^data\:[\w+\-]+\/[\w+\-]+[,;]/.test(payload)) {
if (payload.length > 1024 * 1024 * 1.999 && myBlob !== toString) {
payload = dataUrlToBlob(payload);
mimeType = payload.type || defaultMime;
} else {
return navigator.msSaveBlob // IE10 can't do a[download], only Blobs:
? navigator.msSaveBlob(dataUrlToBlob(payload), fileName)
: saver(payload); // everyone else can save dataURLs un-processed
}
} //end if dataURL passed?
blob = payload instanceof myBlob ? payload : new myBlob([payload], { type: mimeType });
function dataUrlToBlob(strUrl) {
var parts = strUrl.split(/[:;,]/),
type = parts[1],
decoder = parts[2] == 'base64' ? atob : decodeURIComponent,
binData = decoder(parts.pop()),
mx = binData.length,
i = 0,
uiArr = new Uint8Array(mx);
for (i; i < mx; ++i) uiArr[i] = binData.charCodeAt(i);
return new myBlob([uiArr], { type: type });
}
function saver(url, winMode) {
if ('download' in anchor) {
//html5 A[download]
anchor.href = url;
anchor.setAttribute('download', fileName);
anchor.className = 'download-js-link';
anchor.innerHTML = 'downloading...';
anchor.style.display = 'none';
document.body.appendChild(anchor);
setTimeout(function () {
anchor.click();
document.body.removeChild(anchor);
if (winMode === true) {
setTimeout(function () {
self.URL.revokeObjectURL(anchor.href);
}, 250);
}
}, 66);
return true;
}
// handle non-a[download] safari as best we can:
if (/(Version)\/(\d+)\.(\d+)(?:\.(\d+))?.*Safari\//.test(navigator.userAgent)) {
url = url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
if (!window.open(url)) {
// popup blocked, offer direct download:
if (confirm('Displaying New Document\n\nUse Save As... to download, then click back to return to this page.')) {
location.href = url;
}
}
return true;
}
//do iframe dataURL download (old ch+FF):
var f = document.createElement('iframe');
document.body.appendChild(f);
if (!winMode) {
// force a mime that will download:
url = 'data:' + url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
}
f.src = url;
setTimeout(function () {
document.body.removeChild(f);
}, 333);
} //end saver
if (navigator.msSaveBlob) {
// IE10+ : (has Blob, but not a[download] or URL)
return navigator.msSaveBlob(blob, fileName);
}
if (self.URL) {
// simple fast and modern way using Blob and URL:
saver(self.URL.createObjectURL(blob), true);
} else {
// handle non-Blob()+non-URL browsers:
if (typeof blob === 'string' || blob.constructor === toString) {
try {
return saver('data:' + mimeType + ';base64,' + self.btoa(blob));
} catch (y) {
return saver('data:' + mimeType + ',' + encodeURIComponent(blob));
}
}
// Blob but not URL support:
reader = new FileReader();
reader.onload = function (e) {
saver(this.result);
};
reader.readAsDataURL(blob);
}
return true;
}; /* end download() */
});
</script>
</body> </body>
</html> </html>
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-04-27 20:35:34 * @Date: 2020-04-27 20:35:34
* @LastEditors: Please set LastEditors * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-28 16:15:59 * @LastEditTime: 2021-07-08 19:22:18
* @Description: * @Description:
*/ */
...@@ -17,6 +17,7 @@ import { RootRouter } from './routes/index'; ...@@ -17,6 +17,7 @@ import { RootRouter } from './routes/index';
import 'antd/dist/antd.less'; import 'antd/dist/antd.less';
import 'video-react/dist/video-react.css'; import 'video-react/dist/video-react.css';
import '@/common/less/index.less'; import '@/common/less/index.less';
import '@/core/downloads';
import '@/core/function'; import '@/core/function';
import '@/core/xmTD'; import '@/core/xmTD';
import User from '@/common/js/user'; import User from '@/common/js/user';
......
...@@ -6,6 +6,7 @@ import Upload from '@/core/upload'; ...@@ -6,6 +6,7 @@ import Upload from '@/core/upload';
import StoreService from "@/domains/store-domain/storeService"; import StoreService from "@/domains/store-domain/storeService";
import User from "@/common/js/user"; import User from "@/common/js/user";
import Bus from '@/core/tbus'; import Bus from '@/core/tbus';
import ImgClipModal from '@/components/ImgClipModal'
import "./CollegeInfoPage.less"; import "./CollegeInfoPage.less";
let cutFlag = false; let cutFlag = false;
class CollegeInfoPage extends React.Component { class CollegeInfoPage extends React.Component {
...@@ -17,6 +18,7 @@ class CollegeInfoPage extends React.Component { ...@@ -17,6 +18,7 @@ class CollegeInfoPage extends React.Component {
logo:'', logo:'',
showSelectFileModal:false, showSelectFileModal:false,
cutImageBlob: null, cutImageBlob: null,
imageFile: null, // 需要被截取的图片
} }
} }
componentWillMount() { componentWillMount() {
...@@ -51,85 +53,13 @@ class CollegeInfoPage extends React.Component { ...@@ -51,85 +53,13 @@ class CollegeInfoPage extends React.Component {
}) })
} }
handleSelectCover = (file)=> { handleSelectCover = (file)=> {
this.uploadImage(file); this.setState({
visible: true,
imageFile:file
});
} }
//上传图片
uploadImage = (imageFile) => {
const { folderName } = imageFile;
const fileName = window.random_string(16) + folderName.slice(folderName.lastIndexOf("."));
const self = this;
this.setState(
{
visible: true,
},
() => {
setTimeout(() => {
const okBtnDom = document.querySelector("#headPicModal");
const options = {
size: [500, 128],
ok: okBtnDom,
maxZoom: 3,
style: {
jpgFillColor: "transparent",
},
done: function (dataUrl) {
clearTimeout(self.timer);
self.timer = setTimeout(() => {
if ((self.state.rotate != this.rotate()) || (self.state.scale != this.scale())) {
console.log(this.scale(), 'scale')
const _dataUrl = this.clip()
const cutImageBlob = self.convertBase64UrlToBlob(_dataUrl);
self.setState({
cutImageBlob,
dataUrl: _dataUrl,
rotate: this.rotate(),
scale: this.scale()
})
}
}, 500)
const cutImageBlob = self.convertBase64UrlToBlob(dataUrl);
self.setState({
cutImageBlob,
dataUrl
})
setTimeout(() => {
cutFlag = false;
}, 2000);
},
fail: (failInfo) => {
message.error("图片上传失败了,请重新上传");
},
loadComplete: function (img) {
setTimeout(() => {
const _dataUrl = this.clip()
self.setState({
dataUrl: _dataUrl,
hasImgReady: true
})
}, 100)
},
};
const imgUrl = `${imageFile.ossUrl}?${new Date().getTime()}`
if (!this.state.photoclip) {
const _photoclip = new PhotoClip("#headPicModal", options);
_photoclip.load(imgUrl);
this.setState({
photoclip: _photoclip,
});
} else {
this.state.photoclip.clear();
this.state.photoclip.load(imgUrl);
}
}, 200);
}
);
};
//获取resourceId //获取resourceId
getSignature = (blob, fileName) => { getSignature = (blob, fileName) => {
Upload.uploadBlobToOSS(blob, 'cover' + (new Date()).valueOf(),null,'signInfo').then((signInfo) => { Upload.uploadBlobToOSS(blob, 'cover' + (new Date()).valueOf(),null,'signInfo').then((signInfo) => {
...@@ -150,16 +80,7 @@ class CollegeInfoPage extends React.Component { ...@@ -150,16 +80,7 @@ class CollegeInfoPage extends React.Component {
logo:coverClicpPath logo:coverClicpPath
}) })
} }
// base64转换成blob
convertBase64UrlToBlob = (urlData) => {
const bytes = window.atob(urlData.split(",")[1]);
const ab = new ArrayBuffer(bytes.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], { type: "image/png" });
};
updateInfo=()=>{ updateInfo=()=>{
const { storeName, logo } = this.state; const { storeName, logo } = this.state;
if(!storeName){ if(!storeName){
...@@ -175,6 +96,7 @@ class CollegeInfoPage extends React.Component { ...@@ -175,6 +96,7 @@ class CollegeInfoPage extends React.Component {
User.setStoreName(storeName); User.setStoreName(storeName);
Bus.trigger('storeNameChange',storeName); Bus.trigger('storeNameChange',storeName);
message.success('保存成功'); message.success('保存成功');
Bus.trigger("updateCollegeInfo")
}); });
} }
render() { render() {
...@@ -185,6 +107,7 @@ class CollegeInfoPage extends React.Component { ...@@ -185,6 +107,7 @@ class CollegeInfoPage extends React.Component {
hasImgReady, hasImgReady,
logo, logo,
cutImageBlob, cutImageBlob,
imageFile
} = this.state; } = this.state;
return ( return (
<div className="page college-info-page"> <div className="page college-info-page">
...@@ -242,65 +165,9 @@ class CollegeInfoPage extends React.Component { ...@@ -242,65 +165,9 @@ class CollegeInfoPage extends React.Component {
onSelect={this.handleSelectCover} onSelect={this.handleSelectCover}
/> />
} }
<Modal { visible &&
title="设置图片" <ImgClipModal visible={visible} imgUrl={imageFile.ossUrl} aspectRatio='125/32' cropBoxHeight='128' onConfirm={this.getSignature} onClose={()=>{this.setState({ visible: false });}}/>
width={1080} }
visible={visible}
maskClosable={false}
closeIcon={<span className="icon iconfont modal-close-icon">&#xe6ef;</span>}
onCancel={() => {
this.setState({ visible: false });
}}
zIndex={10001}
footer={[
<Button
key="back"
onClick={() => {
this.setState({ visible: false });
}}
>
重新上传
</Button>,
<Button
key="submit"
type="primary"
disabled={!hasImgReady}
onClick={() => {
if (!cutFlag) {
cutFlag = true;
this.refs.hiddenBtn.click();
}
this.getSignature(cutImageBlob);
}}
>
确定
</Button>,
]}
>
<div className="clip-box">
<div
id="headPicModal"
ref="headPicModal"
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="preview-url-box" style={{width:500,height:128}}>
<img src={this.state.dataUrl} style={{ width: '100%' }} alt="" />
</div>
<div className="tip-box">
<div className="tip">温馨提示</div>
<div className="tip">①预览效果图时可能存在延迟,单击左侧图片刷新即可</div>
<div className="tip">②设置图片时双击可旋转图片,滚动可放大或缩小图片</div>
</div>
</div>
</div>
</Modal>
<div><Button type="primary" onClick={this.updateInfo} htmlType="submit" className="submit-btn">更新信息</Button></div> <div><Button type="primary" onClick={this.updateInfo} htmlType="submit" className="submit-btn">更新信息</Button></div>
</div> </div>
......
...@@ -13,8 +13,9 @@ import { ImgCutModalNew } from '@/components'; ...@@ -13,8 +13,9 @@ import { ImgCutModalNew } from '@/components';
import StoreService from "@/domains/store-domain/storeService"; import StoreService from "@/domains/store-domain/storeService";
import SelectPrepareFileModal from '@/modules/prepare-lesson/modal/SelectPrepareFileModal'; import SelectPrepareFileModal from '@/modules/prepare-lesson/modal/SelectPrepareFileModal';
import Upload from '@/core/upload'; import Upload from '@/core/upload';
// import PhotoClip from 'photoclip' import Cropper from 'react-cropper';
import ImgClipModal from '@/components/ImgClipModal'
import 'cropperjs/dist/cropper.css';
import './AddLiveBasic.less'; import './AddLiveBasic.less';
const defaultCover = 'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'; const defaultCover = 'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png';
...@@ -31,7 +32,8 @@ class AddLiveBasic extends React.Component { ...@@ -31,7 +32,8 @@ class AddLiveBasic extends React.Component {
courseCatalogList:[], courseCatalogList:[],
showSelectFileModal: false, showSelectFileModal: false,
cutImageBlob: null, cutImageBlob: null,
hasImgReady: false // 图片是否上传成功 hasImgReady: false, // 图片是否上传成功
cropperInstace:null
} }
} }
componentWillUnmount() { componentWillUnmount() {
...@@ -49,16 +51,6 @@ class AddLiveBasic extends React.Component { ...@@ -49,16 +51,6 @@ class AddLiveBasic extends React.Component {
}); });
} }
// 上传封面图
handleShowImgCutModal = (event) => {
const imageFile = event.target.files[0];
if (!imageFile) return;
this.setState({
imageFile,
showCutModal: true,
});
}
// 使用默认封面图 // 使用默认封面图
handleResetCoverUrl = () => { handleResetCoverUrl = () => {
const { data: { coverUrl } } = this.props; const { data: { coverUrl } } = this.props;
...@@ -87,85 +79,13 @@ class AddLiveBasic extends React.Component { ...@@ -87,85 +79,13 @@ class AddLiveBasic extends React.Component {
} }
} }
handleSelectCover = (file) => { handleSelectCover = (file) => {
this.uploadImage(file); this.setState({
visible: true,
imageFile:file
});
} }
//上传图片
uploadImage = (imageFile) => {
const { folderName } = imageFile;
const fileName =
window.random_string(16) + folderName.slice(folderName.lastIndexOf("."));
const self = this;
this.setState(
{
visible: true,
},
() => {
setTimeout(() => {
const okBtnDom = document.querySelector("#headPicModal");
const options = {
size: [500, 282],
ok: okBtnDom,
maxZoom: 3,
style: {
jpgFillColor: "transparent",
},
done: function (dataUrl) {
clearTimeout(self.timer);
self.timer = setTimeout(() => {
if ((self.state.rotate != this.rotate()) || (self.state.scale != this.scale())) {
console.log(this.scale(), 'scale')
const _dataUrl = this.clip()
const cutImageBlob = self.convertBase64UrlToBlob(_dataUrl);
self.setState({
cutImageBlob,
dataUrl: _dataUrl,
rotate: this.rotate(),
scale: this.scale()
})
}
}, 500)
const cutImageBlob = self.convertBase64UrlToBlob(dataUrl);
self.setState({
cutImageBlob,
dataUrl
})
setTimeout(() => {
cutFlag = false;
}, 2000);
},
fail: (failInfo) => {
message.error("图片上传失败了,请重新上传");
},
loadComplete: function (img) {
setTimeout(() => {
const _dataUrl = this.clip()
self.setState({
dataUrl: _dataUrl,
hasImgReady: true
})
}, 100)
},
};
const imgUrl = `${imageFile.ossUrl}?${new Date().getTime()}`
if (!this.state.photoclip) {
const _photoclip = new PhotoClip("#headPicModal", options);
_photoclip.load(imgUrl);
this.setState({
photoclip: _photoclip,
});
} else {
this.state.photoclip.clear();
this.state.photoclip.load(imgUrl);
}
}, 200);
}
);
};
//获取resourceId //获取resourceId
getSignature = (blob, fileName) => { getSignature = (blob, fileName) => {
...@@ -179,16 +99,6 @@ class AddLiveBasic extends React.Component { ...@@ -179,16 +99,6 @@ class AddLiveBasic extends React.Component {
}); });
}; };
// base64转换成blob
convertBase64UrlToBlob = (urlData) => {
const bytes = window.atob(urlData.split(",")[1]);
const ab = new ArrayBuffer(bytes.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], { type: "image/png" });
};
updateCover = () =>{ updateCover = () =>{
const {coverClicpPath,coverId} = this.state const {coverClicpPath,coverId} = this.state
this.setState({ this.setState({
...@@ -254,24 +164,6 @@ class AddLiveBasic extends React.Component { ...@@ -254,24 +164,6 @@ class AddLiveBasic extends React.Component {
<Cascader disabled={!isEdit ? true: false} defaultValue={[categoryName]} options={courseCatalogList} displayRender={ label => label.join('-')} fieldNames={fieldNames} onChange={this.catalogChange} style={{ width: 240 }} placeholder="请选择课程分类" suffixIcon={<span className="icon iconfont" style={{fontSize:'12px',color:'#BFBFBF'}}>&#xe835;</span>} /> <Cascader disabled={!isEdit ? true: false} defaultValue={[categoryName]} options={courseCatalogList} displayRender={ label => label.join('-')} fieldNames={fieldNames} onChange={this.catalogChange} style={{ width: 240 }} placeholder="请选择课程分类" suffixIcon={<span className="icon iconfont" style={{fontSize:'12px',color:'#BFBFBF'}}>&#xe835;</span>} />
} }
</div> </div>
<ImgCutModalNew
title="裁剪"
width={530}
cutWidth={500}
cutHeight={282}
cutContentWidth={500}
cutContentHeight={300}
visible={showCutModal}
imageFile={imageFile}
bizCode='LIVE_COURSE_MEDIA'
onOk={(urlStr, resourceId) => {
this.setState({ showCutModal: false });
this.props.onChange('coverId', resourceId, urlStr);
this.state.currentInputFile.value = '';
}}
onClose={() => this.setState({ showCutModal: false })}
reUpload={() => { this.state.currentInputFile.click() }}
/>
{showSelectFileModal && {showSelectFileModal &&
<SelectPrepareFileModal <SelectPrepareFileModal
key="basic" key="basic"
...@@ -287,66 +179,9 @@ class AddLiveBasic extends React.Component { ...@@ -287,66 +179,9 @@ class AddLiveBasic extends React.Component {
onSelect={this.handleSelectCover} onSelect={this.handleSelectCover}
/> />
} }
<Modal { visible &&
title="设置图片" <ImgClipModal visible={visible} imgUrl={imageFile.ossUrl} onConfirm={this.getSignature} onClose={()=>{this.setState({ visible: false });}}/>
width={1080} }
visible={visible}
maskClosable={false}
closeIcon={<span className="icon iconfont modal-close-icon">&#xe6ef;</span>}
onCancel={() => {
this.setState({ visible: false });
}}
zIndex={10001}
footer={[
<Button
key="back"
onClick={() => {
this.setState({ visible: false });
}}
>
重新上传
</Button>,
<Button
key="submit"
type="primary"
disabled={!hasImgReady}
onClick={() => {
if (!cutFlag) {
cutFlag = true;
this.refs.hiddenBtn.click();
}
this.getSignature(cutImageBlob);
}}
>
确定
</Button>,
]}
>
<div className="clip-box">
<div
id="headPicModal"
ref="headPicModal"
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>
{/* <img src={previewUrl} alt="图片预览" className="preview-url" /> */}
<div id="preview-url-box" style={{width:500,height:282}}>
<img src={this.state.dataUrl} style={{ width: '100%' }} alt="" />
</div>
<div className="tip-box">
<div className="tip">温馨提示</div>
<div className="tip">①预览效果图时可能存在延迟,单击左侧图片刷新即可</div>
<div className="tip">②设置图片时双击可旋转图片,滚动可放大或缩小图片</div>
</div>
</div>
</div>
</Modal>
</div> </div>
) )
} }
......
...@@ -81,4 +81,7 @@ ...@@ -81,4 +81,7 @@
#imgCutModalNew { #imgCutModalNew {
width: 500px; width: 500px;
height: 300px; height: 300px;
}
.preview-url-box{
overflow: hidden;
} }
\ No newline at end of file
...@@ -175,7 +175,10 @@ class AddLiveClass extends React.Component { ...@@ -175,7 +175,10 @@ class AddLiveClass extends React.Component {
<Tooltip <Tooltip
overlayStyle={{maxWidth: 300, zIndex: '9999'}} overlayStyle={{maxWidth: 300, zIndex: '9999'}}
title={<div style={{width: '266px'}}>支持按上课日期批量创建直播课,创建后按“课程名称_日期”命名,例如:<br/>张三的语文课_9月18日<br/>张三的语文课_9月19日......</div>}> title={<div style={{width: '266px'}}>支持按上课日期批量创建直播课,创建后按“课程名称_日期”命名,例如:<br/>张三的语文课_9月18日<br/>张三的语文课_9月19日......</div>}>
<span className="iconfont">&#xe61d;</span> <span
style={{ color: "rgba(191, 191, 191, 1)",fontWeight: 400 }}
className="iconfont"
>&#xe61d;</span>
</Tooltip> </Tooltip>
</span> </span>
<div> <div>
......
.live-course-list { .live-course-list {
margin-top: 12px; margin-top: 12px;
.record__item { .record__item {
overflow: hidden;
display: flex; display: flex;
align-items: center; align-items: center;
.course-cover { .course-cover {
...@@ -11,63 +11,61 @@ ...@@ -11,63 +11,61 @@
border-radius: 2px; border-radius: 2px;
margin-right: 8px; margin-right: 8px;
} }
.course-name{ .course-name {
font-size: 14px; font-size: 14px;
font-weight: 500; font-weight: 500;
color: #333333; color: #333333;
line-height: 20px; line-height: 20px;
font-weight: bold; font-weight: bold;
max-width:244px; max-width: 200px;
overflow: hidden; overflow: hidden;
text-overflow:ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
.course-time{ .course-time {
font-size: 12px; font-size: 12px;
font-weight: 400; font-weight: 400;
color: #666666; color: #666666;
line-height: 20px; line-height: 20px;
} }
.course-status { .course-status {
font-size:12px; font-size: 12px;
line-height:18px; line-height: 18px;
display:inline-block; display: inline-block;
border-radius:2px; border-radius: 2px;
padding:0 8px; padding: 0 8px;
margin-left:4px; margin-left: 4px;
} }
.teacher-assistant{ .teacher-assistant {
display:flex; display: flex;
.teacher{ .teacher {
font-size: 12px; font-size: 12px;
color: #666666; color: #666666;
max-width: 96px; max-width: 96px;
overflow: hidden; overflow: hidden;
text-overflow:ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
display:inline-block; display: inline-block;
padding-top:2px; padding-top: 2px;
} }
.assistant{ .assistant {
font-size: 12px; font-size: 12px;
color: #666666; color: #666666;
max-width: 96px; max-width: 96px;
overflow: hidden; overflow: hidden;
text-overflow:ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
display:inline-block; display: inline-block;
padding-top:2px; padding-top: 2px;
} }
.split { .split {
margin: 0 4px; margin: 0 4px;
color: #BFBFBF; color: #bfbfbf;
display: inline-blcok; display: inline-blcok;
} }
} }
} }
.related-task{ .related-task {
text-overflow: -o-ellipsis-lastline; text-overflow: -o-ellipsis-lastline;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
...@@ -76,37 +74,37 @@ ...@@ -76,37 +74,37 @@
line-clamp: 2; line-clamp: 2;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
} }
.categoryName{ .categoryName {
font-size: 14px; font-size: 14px;
color: #666666; color: #666666;
line-height: 20px; line-height: 20px;
} }
.courseware{ .courseware {
font-size: 14px; font-size: 14px;
color: #2966FF; color: #2966ff;
line-height: 20px; line-height: 20px;
text-align:right; text-align: right;
cursor:pointer; cursor: pointer;
} }
.quota-icon{ .quota-icon {
color:#2966FF; color: #2966ff;
cursor:pointer; cursor: pointer;
} }
.operate { .operate {
display: flex; display: flex;
align-items: center; align-items: center;
flex-wrap: wrap; flex-wrap: wrap;
.operate__item { .operate__item {
color: #2966FF; color: #2966ff;
cursor: pointer; cursor: pointer;
&.split { &.split {
margin: 0 8px; margin: 0 8px;
color: #BFBFBF; color: #bfbfbf;
} }
} }
} }
.operate-text { .operate-text {
color: #2966FF; color: #2966ff;
cursor: pointer; cursor: pointer;
} }
.course-start-end { .course-start-end {
...@@ -135,7 +133,27 @@ ...@@ -135,7 +133,27 @@
font-size: 12px; font-size: 12px;
} }
} }
tbody {
tr {
&:nth-child(even) {
background: transparent !important;
td {
background: #fff !important;
}
}
&:nth-child(odd) {
background: #fafafa !important;
td {
background: #fafafa !important;
}
}
&:hover {
td {
background: #f3f6fa !important;
}
}
}
}
} }
.live-course-more-menu { .live-course-more-menu {
background: white; background: white;
...@@ -155,4 +173,4 @@ ...@@ -155,4 +173,4 @@
.type { .type {
font-weight: 700; font-weight: 700;
} }
} }
\ No newline at end of file
/* /*
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-08-05 10:07:47 * @Date: 2020-08-05 10:07:47
* @LastEditors: fusanqiasng * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-16 18:16:14 * @LastEditTime: 2021-07-08 19:32:50
* @Description: 图文课新增/编辑页 * @Description: 图文课新增/编辑页
* @Copyright: 杭州杰竞科技有限公司 版权所有 * @Copyright: 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -25,6 +25,7 @@ import { randomString } from '@/domains/basic-domain/utils'; ...@@ -25,6 +25,7 @@ import { randomString } from '@/domains/basic-domain/utils';
import User from '@/common/js/user'; import User from '@/common/js/user';
import _ from 'underscore'; import _ from 'underscore';
import Upload from '@/core/upload'; import Upload from '@/core/upload';
import ImgClipModal from '@/components/ImgClipModal'
import './AddGraphicsCourse.less'; import './AddGraphicsCourse.less';
const EDIT_BOX_KEY = Math.random(); const EDIT_BOX_KEY = Math.random();
...@@ -279,79 +280,10 @@ class AddGraphicsCourse extends React.Component { ...@@ -279,79 +280,10 @@ class AddGraphicsCourse extends React.Component {
}; };
handleSelectCover = (file) => { handleSelectCover = (file) => {
this.uploadCoverImage(file); this.setState({
}; visible: true,
imageFile:file
//上传图片 });
uploadCoverImage = (imageFile) => {
const { folderName } = imageFile;
const fileName = window.random_string(16) + folderName.slice(folderName.lastIndexOf('.'));
const self = this;
this.setState(
{
visible: true,
},
() => {
setTimeout(() => {
const okBtnDom = document.querySelector('#headPicModal');
const options = {
size: [500, 282],
ok: okBtnDom,
maxZoom: 3,
style: {
jpgFillColor: 'transparent',
},
done: function (dataUrl) {
clearTimeout(self.timer);
self.timer = setTimeout(() => {
if (self.state.rotate != this.rotate() || self.state.scale != this.scale()) {
const _dataUrl = this.clip();
const cutImageBlob = self.convertBase64UrlToBlob(_dataUrl);
self.setState({
cutImageBlob,
dataUrl: _dataUrl,
rotate: this.rotate(),
scale: this.scale(),
});
}
}, 500);
const cutImageBlob = self.convertBase64UrlToBlob(dataUrl);
self.setState({
cutImageBlob,
dataUrl,
});
setTimeout(() => {
cutFlag = false;
}, 2000);
},
fail: (failInfo) => {
message.error('图片上传失败了,请重新上传');
},
loadComplete: function (img) {
setTimeout(() => {
const _dataUrl = this.clip();
self.setState({
dataUrl: _dataUrl,
hasImgReady: true,
});
}, 100);
},
};
const imgUrl = `${imageFile.ossUrl}?${new Date().getTime()}`;
if (!this.state.photoclip) {
const _photoclip = new PhotoClip('#headPicModal', options);
_photoclip.load(imgUrl);
this.setState({
photoclip: _photoclip,
});
} else {
this.state.photoclip.clear();
this.state.photoclip.load(imgUrl);
}
}, 200);
}
);
}; };
//获取resourceId //获取resourceId
...@@ -377,17 +309,6 @@ class AddGraphicsCourse extends React.Component { ...@@ -377,17 +309,6 @@ class AddGraphicsCourse extends React.Component {
}); });
}; };
// base64转换成blob
convertBase64UrlToBlob = (urlData) => {
const bytes = window.atob(urlData.split(',')[1]);
const ab = new ArrayBuffer(bytes.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], { type: 'image/png' });
};
// 保存 // 保存
handleSubmit = () => { handleSubmit = () => {
//过期判断 //过期判断
...@@ -619,61 +540,9 @@ class AddGraphicsCourse extends React.Component { ...@@ -619,61 +540,9 @@ class AddGraphicsCourse extends React.Component {
onSelect={this.handleSelectCover} onSelect={this.handleSelectCover}
/> />
)} )}
<Modal { visible &&
title='设置图片' <ImgClipModal visible={visible} imgUrl={imageFile.ossUrl} onConfirm={this.getSignature} onClose={()=>{this.setState({ visible: false });}}/>
width={1080} }
visible={visible}
maskClosable={false}
closeIcon={<span className='icon iconfont modal-close-icon'>&#xe6ef;</span>}
onCancel={() => {
this.setState({ visible: false });
}}
zIndex={10001}
footer={[
<Button
key='back'
onClick={() => {
this.setState({ visible: false });
}}>
重新上传
</Button>,
<Button
key='submit'
type='primary'
disabled={!hasImgReady}
onClick={() => {
if (!cutFlag) {
cutFlag = true;
this.refs.hiddenBtn.click();
}
this.getSignature(cutImageBlob);
}}>
确定
</Button>,
]}>
<div className='clip-box'>
<div
id='headPicModal'
ref='headPicModal'
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='preview-url-box' style={{ width: 500, height: 282 }}>
<img src={this.state.dataUrl} style={{ width: '100%' }} alt='' />
</div>
<div className='tip-box'>
<div className='tip'>温馨提示</div>
<div className='tip'>①预览效果图时可能存在延迟,单击左侧图片刷新即可</div>
<div className='tip'>②设置图片时双击可旋转图片,滚动可放大或缩小图片</div>
</div>
</div>
</div>
</Modal>
{this.state.previewGraphicsModal} {this.state.previewGraphicsModal}
</div> </div>
); );
......
/* /*
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-08-05 10:07:47 * @Date: 2020-08-05 10:07:47
* @LastEditors: yuananting * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-07 15:06:26 * @LastEditTime: 2021-07-06 14:47:23
* @Description: 线下课新增/编辑页 * @Description: 线下课新增/编辑页
* @Copyright: 杭州杰竞科技有限公司 版权所有 * @Copyright: 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -38,6 +38,7 @@ import moment from 'moment'; ...@@ -38,6 +38,7 @@ import moment from 'moment';
import Upload from '@/core/upload'; import Upload from '@/core/upload';
import GraphicsEditor from '../components/GraphicsEditor'; import GraphicsEditor from '../components/GraphicsEditor';
import MultipleDatePicker from '@/components/MultipleDatePicker'; import MultipleDatePicker from '@/components/MultipleDatePicker';
import ImgClipModal from '@/components/ImgClipModal'
import './AddOfflineCourse.less'; import './AddOfflineCourse.less';
const { Option } = Select; const { Option } = Select;
...@@ -355,83 +356,12 @@ class AddOfflineCourse extends React.Component { ...@@ -355,83 +356,12 @@ class AddOfflineCourse extends React.Component {
} }
handleSelectCover = (file)=> { handleSelectCover = (file)=> {
this.uploadCoverImage(file); this.setState({
visible: true,
imageFile:file
});
} }
//上传图片
uploadCoverImage = (imageFile) => {
const { folderName } = imageFile;
const fileName = window.random_string(16) + folderName.slice(folderName.lastIndexOf("."));
const self = this;
this.setState(
{
visible: true,
},
() => {
setTimeout(() => {
const okBtnDom = document.querySelector("#headPicModal");
const options = {
size: [500, 282],
ok: okBtnDom,
maxZoom: 3,
style: {
jpgFillColor: "transparent",
},
done: function (dataUrl) {
clearTimeout(self.timer);
self.timer = setTimeout(() => {
if ((self.state.rotate != this.rotate()) || (self.state.scale != this.scale())) {
const _dataUrl = this.clip()
const cutImageBlob = self.convertBase64UrlToBlob(_dataUrl);
self.setState({
cutImageBlob,
dataUrl: _dataUrl,
rotate: this.rotate(),
scale: this.scale()
})
}
}, 500)
const cutImageBlob = self.convertBase64UrlToBlob(dataUrl);
self.setState({
cutImageBlob,
dataUrl
})
setTimeout(() => {
cutFlag = false;
}, 2000);
},
fail: (failInfo) => {
message.error("图片上传失败了,请重新上传");
},
loadComplete: function (img) {
setTimeout(() => {
const _dataUrl = this.clip()
self.setState({
dataUrl: _dataUrl,
hasImgReady: true
})
}, 100)
},
};
const imgUrl = `${imageFile.ossUrl}?${new Date().getTime()}`
if (!this.state.photoclip) {
const _photoclip = new PhotoClip("#headPicModal", options);
_photoclip.load(imgUrl);
this.setState({
photoclip: _photoclip,
});
} else {
this.state.photoclip.clear();
this.state.photoclip.load(imgUrl);
}
}, 200);
}
);
};
//获取resourceId //获取resourceId
getSignature = (blob, fileName) => { getSignature = (blob, fileName) => {
...@@ -454,17 +384,6 @@ class AddOfflineCourse extends React.Component { ...@@ -454,17 +384,6 @@ class AddOfflineCourse extends React.Component {
}) })
} }
// base64转换成blob
convertBase64UrlToBlob = (urlData) => {
const bytes = window.atob(urlData.split(",")[1]);
const ab = new ArrayBuffer(bytes.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], { type: "image/png" });
};
preSubmit = () => { preSubmit = () => {
//过期判断 //过期判断
if (User.getExpirationTime() && moment().valueOf() > Number(User.getExpirationTime())) { if (User.getExpirationTime() && moment().valueOf() > Number(User.getExpirationTime())) {
...@@ -786,6 +705,7 @@ class AddOfflineCourse extends React.Component { ...@@ -786,6 +705,7 @@ class AddOfflineCourse extends React.Component {
quota, quota,
offlinePlace, offlinePlace,
isEditDisablie, isEditDisablie,
imageFile,
} = this.state; } = this.state;
const isDefaultCover = coverUrl === defaultCoverUrl; const isDefaultCover = coverUrl === defaultCoverUrl;
return ( return (
...@@ -1301,65 +1221,9 @@ class AddOfflineCourse extends React.Component { ...@@ -1301,65 +1221,9 @@ class AddOfflineCourse extends React.Component {
onSelect={this.handleSelectCover} onSelect={this.handleSelectCover}
/> />
} }
<Modal { visible &&
title="设置图片" <ImgClipModal visible={visible} imgUrl={imageFile.ossUrl} onConfirm={this.getSignature} onClose={()=>{this.setState({ visible: false });}}/>
width={1080} }
visible={visible}
maskClosable={false}
closeIcon={<span className="icon iconfont modal-close-icon">&#xe6ef;</span>}
onCancel={() => {
this.setState({ visible: false });
}}
zIndex={10001}
footer={[
<Button
key="back"
onClick={() => {
this.setState({ visible: false });
}}
>
重新上传
</Button>,
<Button
key="submit"
type="primary"
disabled={!hasImgReady}
onClick={() => {
if (!cutFlag) {
cutFlag = true;
this.refs.hiddenBtn.click();
}
this.getSignature(cutImageBlob);
}}
>
确定
</Button>,
]}
>
<div className="clip-box">
<div
id="headPicModal"
ref="headPicModal"
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="preview-url-box" style={{width:500,height:282}}>
<img src={this.state.dataUrl} style={{ width: '100%' }} alt="" />
</div>
<div className="tip-box">
<div className="tip">温馨提示</div>
<div className="tip">①预览效果图时可能存在延迟,单击左侧图片刷新即可</div>
<div className="tip">②设置图片时双击可旋转图片,滚动可放大或缩小图片</div>
</div>
</div>
</div>
</Modal>
{ this.state.previewOfflineModal } { this.state.previewOfflineModal }
</div> </div>
) )
......
...@@ -10,7 +10,7 @@ import Service from '@/common/js/service'; ...@@ -10,7 +10,7 @@ import Service from '@/common/js/service';
import User from '@/common/js/user'; import User from '@/common/js/user';
import college from '@/common/lottie/college'; import college from '@/common/lottie/college';
import { PageControl, XMTable } from '@/components'; import { PageControl, XMTable } from '@/components';
import { appId, LIVE_SHARE } from '@/domains/course-domain/constants'; import { LIVE_SHARE } from '@/domains/course-domain/constants';
import CourseService from '@/domains/course-domain/CourseService'; import CourseService from '@/domains/course-domain/CourseService';
import ShareLiveModal from '@/modules/course-manage/modal/ShareLiveModal'; import ShareLiveModal from '@/modules/course-manage/modal/ShareLiveModal';
import OfflineCourseData from '@/modules/course-manage/offline-course/OfflineCourseData'; import OfflineCourseData from '@/modules/course-manage/offline-course/OfflineCourseData';
...@@ -78,7 +78,7 @@ class OfflineCourseList extends React.Component { ...@@ -78,7 +78,7 @@ class OfflineCourseList extends React.Component {
} ${moment(startTime).format('HH:mm')} ~ ${moment(endTime).format('HH:mm')}`; } ${moment(startTime).format('HH:mm')} ~ ${moment(endTime).format('HH:mm')}`;
return ( return (
<div className='record__item'> <div className='record__item'>
<img className='course-cover' src={coverUrl || defaultCoverUrl} /> <img className='course-cover' src={coverUrl || defaultCoverUrl} alt='' />
<div style={{ width: 175 }}> <div style={{ width: 175 }}>
<Tooltip title={courseName}> <Tooltip title={courseName}>
<div className='course-name'>{courseName}</div> <div className='course-name'>{courseName}</div>
...@@ -152,14 +152,14 @@ class OfflineCourseList extends React.Component { ...@@ -152,14 +152,14 @@ class OfflineCourseList extends React.Component {
}, },
{ {
title: '报名时间', title: '报名时间',
width: 181, width: 200,
key: 'apply', key: 'apply',
dataIndex: 'apply', dataIndex: 'apply',
sorter: true, sorter: true,
render: (val, item) => { render: (val, item) => {
return ( return (
<div> <div style={{ whiteSpace: 'nowrap' }}>
{item.startTimeApply ? `${formatDate('MM-DD H:i', item.startTimeApply)} ~ ${formatDate('MM-DD H:i', item.endTimeApply)}` : '-'} {item.startTimeApply ? `${window.formatDate('MM-DD H:i', item.startTimeApply)} ~ ${window.formatDate('MM-DD H:i', item.endTimeApply)}` : '-'}
{item.whetherApplyFull === 'YES' && ( {item.whetherApplyFull === 'YES' && (
<span <span
style={{ style={{
...@@ -185,7 +185,7 @@ class OfflineCourseList extends React.Component { ...@@ -185,7 +185,7 @@ class OfflineCourseList extends React.Component {
dataIndex: 'created', dataIndex: 'created',
sorter: true, sorter: true,
render: (val) => { render: (val) => {
return formatDate('YYYY-MM-DD H:i', val); return <span style={{ whiteSpace: 'nowrap' }}>{window.formatDate('YYYY-MM-DD H:i', val)}</span>;
}, },
}, },
{ {
...@@ -360,8 +360,6 @@ class OfflineCourseList extends React.Component { ...@@ -360,8 +360,6 @@ class OfflineCourseList extends React.Component {
// 显示分享弹窗 // 显示分享弹窗
handleShowShareModal = (record, needStr = false) => { handleShowShareModal = (record, needStr = false) => {
const { courseId } = record; const { courseId } = record;
const _appId = appId;
const htmlUrl = `${LIVE_SHARE}offline_detail/${courseId}?id=${User.getStoreId()}`; const htmlUrl = `${LIVE_SHARE}offline_detail/${courseId}?id=${User.getStoreId()}`;
const longUrl = htmlUrl; const longUrl = htmlUrl;
const { courseName, courseMediaVOS } = record; const { courseName, courseMediaVOS } = record;
...@@ -437,7 +435,7 @@ class OfflineCourseList extends React.Component { ...@@ -437,7 +435,7 @@ class OfflineCourseList extends React.Component {
columns={this.parseColumns()} columns={this.parseColumns()}
onChange={this.handleChangeTable} onChange={this.handleChangeTable}
pagination={false} pagination={false}
scroll={{ x: 1500 }} scroll={{ x: 1300 }}
bordered bordered
className='offline-list-table' className='offline-list-table'
/> />
......
/* /*
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2020-08-05 10:07:47 * @Date: 2020-08-05 10:07:47
* @LastEditors: wufan * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-05-30 20:35:49 * @LastEditTime: 2021-07-08 19:34:10
* @Description: 视频课新增/编辑页 * @Description: 视频课新增/编辑页
* @Copyright: 杭州杰竞科技有限公司 版权所有 * @Copyright: 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -11,7 +11,6 @@ import React from 'react' ...@@ -11,7 +11,6 @@ import React from 'react'
import { Button, Input, Radio, message, Modal, Cascader } from 'antd' import { Button, Input, Radio, message, Modal, Cascader } from 'antd'
import { DISK_MAP, FileTypeIcon, FileVerifyMap } from '@/common/constants/academic/lessonEnum' import { DISK_MAP, FileTypeIcon, FileVerifyMap } from '@/common/constants/academic/lessonEnum'
import { ImgCutModalNew } from '@/components'
import ShowTips from '@/components/ShowTips' import ShowTips from '@/components/ShowTips'
import Breadcrumbs from '@/components/Breadcrumbs' import Breadcrumbs from '@/components/Breadcrumbs'
import moment from 'moment' import moment from 'moment'
...@@ -26,8 +25,8 @@ import User from '@/common/js/user' ...@@ -26,8 +25,8 @@ import User from '@/common/js/user'
import _ from 'underscore' import _ from 'underscore'
import Upload from '@/core/upload' import Upload from '@/core/upload'
import { randomString } from '@/domains/basic-domain/utils' import { randomString } from '@/domains/basic-domain/utils'
import ImgClipModal from '@/components/ImgClipModal'
import $ from 'jquery' import $ from 'jquery'
// import PhotoClip from 'photoclip';
import './AddVideoCourse.less' import './AddVideoCourse.less'
const EDIT_BOX_KEY = Math.random() const EDIT_BOX_KEY = Math.random()
...@@ -262,7 +261,6 @@ class AddVideoCourse extends React.Component { ...@@ -262,7 +261,6 @@ class AddVideoCourse extends React.Component {
_.each(studentIds, (item) => { _.each(studentIds, (item) => {
studentList.push({ studentId: item }) studentList.push({ studentId: item })
}) })
// this.setState({ studentModal: null });
this.setState({ studentList }) this.setState({ studentList })
this.setState({ studentModal: false }) this.setState({ studentModal: false })
} }
...@@ -428,81 +426,11 @@ class AddVideoCourse extends React.Component { ...@@ -428,81 +426,11 @@ class AddVideoCourse extends React.Component {
}) })
} }
handleSelectCover = (file) => { handleSelectCover = (file) => {
this.uploadImage(file) this.setState({
} visible: true,
imageFile:file
//上传图片 });
uploadImage = (imageFile) => {
const { folderName } = imageFile
const fileName = window.random_string(16) + folderName.slice(folderName.lastIndexOf('.'))
const self = this
this.setState(
{
visible: true
},
() => {
setTimeout(() => {
const okBtnDom = document.querySelector('#headPicModal')
const options = {
size: [500, 282],
ok: okBtnDom,
maxZoom: 3,
style: {
jpgFillColor: 'transparent'
},
done: function (dataUrl) {
clearTimeout(self.timer)
self.timer = setTimeout(() => {
if (self.state.rotate != this.rotate() || self.state.scale != this.scale()) {
const _dataUrl = this.clip()
const cutImageBlob = self.convertBase64UrlToBlob(_dataUrl)
self.setState({
cutImageBlob,
dataUrl: _dataUrl,
rotate: this.rotate(),
scale: this.scale()
})
}
}, 500)
const cutImageBlob = self.convertBase64UrlToBlob(dataUrl)
self.setState({
cutImageBlob,
dataUrl
})
setTimeout(() => {
cutFlag = false
}, 2000)
},
fail: (failInfo) => {
message.error('图片上传失败了,请重新上传')
},
loadComplete: function (img) {
setTimeout(() => {
const _dataUrl = this.clip()
self.setState({
dataUrl: _dataUrl,
hasImgReady: true
})
}, 100)
}
}
const imgUrl = `${imageFile.ossUrl}?${new Date().getTime()}`
if (!this.state.photoclip) {
const _photoclip = new PhotoClip('#headPicModal', options)
_photoclip.load(imgUrl)
this.setState({
photoclip: _photoclip
})
} else {
this.state.photoclip.clear()
this.state.photoclip.load(imgUrl)
}
}, 200)
}
)
} }
//获取resourceId //获取resourceId
getSignature = (blob, fileName) => { getSignature = (blob, fileName) => {
Upload.uploadBlobToOSS(blob, 'cover' + new Date().valueOf(), null, 'signInfo').then((signInfo) => { Upload.uploadBlobToOSS(blob, 'cover' + new Date().valueOf(), null, 'signInfo').then((signInfo) => {
...@@ -524,16 +452,6 @@ class AddVideoCourse extends React.Component { ...@@ -524,16 +452,6 @@ class AddVideoCourse extends React.Component {
coverId: coverId coverId: coverId
}) })
} }
// base64转换成blob
convertBase64UrlToBlob = (urlData) => {
const bytes = window.atob(urlData.split(',')[1])
const ab = new ArrayBuffer(bytes.length)
const ia = new Uint8Array(ab)
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i)
}
return new Blob([ab], { type: 'image/png' })
}
render() { render() {
const { const {
pageType, pageType,
...@@ -736,61 +654,9 @@ class AddVideoCourse extends React.Component { ...@@ -736,61 +654,9 @@ class AddVideoCourse extends React.Component {
onSelect={this.handleSelectCover} onSelect={this.handleSelectCover}
/> />
)} )}
<Modal { visible &&
title='设置图片' <ImgClipModal visible={visible} imgUrl={imageFile.ossUrl} onConfirm={this.getSignature} onClose={()=>{this.setState({ visible: false });}}/>
width={1080} }
visible={visible}
maskClosable={false}
closeIcon={<span className='icon iconfont modal-close-icon'>&#xe6ef;</span>}
onCancel={() => {
this.setState({ visible: false })
}}
zIndex={10001}
footer={[
<Button
key='back'
onClick={() => {
this.setState({ visible: false })
}}>
重新上传
</Button>,
<Button
key='submit'
type='primary'
disabled={!hasImgReady}
onClick={() => {
if (!cutFlag) {
cutFlag = true
this.refs.hiddenBtn.click()
}
this.getSignature(cutImageBlob)
}}>
确定
</Button>
]}>
<div className='clip-box'>
<div
id='headPicModal'
ref='headPicModal'
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='preview-url-box' style={{ width: 500, height: 282 }}>
<img src={this.state.dataUrl} style={{ width: '100%' }} alt='' />
</div>
<div className='tip-box'>
<div className='tip'>温馨提示</div>
<div className='tip'>①预览效果图时可能存在延迟,单击左侧图片刷新即可</div>
<div className='tip'>②设置图片时双击可旋转图片,滚动可放大或缩小图片</div>
</div>
</div>
</div>
</Modal>
{this.state.previewCourseModal} {this.state.previewCourseModal}
</div> </div>
) )
......
import { Dropdown, message, Modal, Switch, Table, Tooltip } from 'antd'; import { Dropdown, message, Modal, Switch, Tooltip } from 'antd';
import User from '@/common/js/user'; import User from '@/common/js/user';
import { PageControl } from '@/components'; import { PageControl } from '@/components';
import { LIVE_SHARE } from '@/domains/course-domain/constants'; import { LIVE_SHARE } from '@/domains/course-domain/constants';
...@@ -147,7 +147,7 @@ class VideoCourseList extends React.Component { ...@@ -147,7 +147,7 @@ class VideoCourseList extends React.Component {
关闭后,学院内不再展示此课程,但学员仍可通过分享的海报/链接查看此课程。 关闭后,学院内不再展示此课程,但学员仍可通过分享的海报/链接查看此课程。
</div> </div>
}> }>
<i className='icon iconfont' style={{ marginLeft: '5px', cursor: 'pointer', color: '#bfbfbf', fontSize: '14px' }}> <i className='icon iconfont' style={{ marginLeft: '5px', cursor: 'pointer', color: '#bfbfbf', fontSize: '14px', fontWeight: 'normal' }}>
&#xe61d; &#xe61d;
</i> </i>
</Tooltip> </Tooltip>
...@@ -185,7 +185,7 @@ class VideoCourseList extends React.Component { ...@@ -185,7 +185,7 @@ class VideoCourseList extends React.Component {
dataIndex: 'created', dataIndex: 'created',
sorter: true, sorter: true,
render: (val) => { render: (val) => {
return formatDate('YYYY-MM-DD H:i', val); return window.formatDate('YYYY-MM-DD H:i', val);
}, },
}, },
{ {
...@@ -195,7 +195,7 @@ class VideoCourseList extends React.Component { ...@@ -195,7 +195,7 @@ class VideoCourseList extends React.Component {
dataIndex: 'updated', dataIndex: 'updated',
sorter: true, sorter: true,
render: (val) => { render: (val) => {
return formatDate('YYYY-MM-DD H:i', val); return window.formatDate('YYYY-MM-DD H:i', val);
}, },
}, },
{ {
...@@ -211,7 +211,7 @@ class VideoCourseList extends React.Component { ...@@ -211,7 +211,7 @@ class VideoCourseList extends React.Component {
<Tooltip title={this.handlePlanName(record.relatedPlanList)} placement='top' arrowPointAtCenter> <Tooltip title={this.handlePlanName(record.relatedPlanList)} placement='top' arrowPointAtCenter>
{record.relatedPlanList.map((item, index) => { {record.relatedPlanList.map((item, index) => {
return ( return (
<span> <span key={item.planId}>
{item.planName} {index < record.relatedPlanList.length - 1 && <span></span>} {item.planName} {index < record.relatedPlanList.length - 1 && <span></span>}
</span> </span>
); );
...@@ -296,7 +296,7 @@ class VideoCourseList extends React.Component { ...@@ -296,7 +296,7 @@ class VideoCourseList extends React.Component {
handlePlanName = (planArray) => { handlePlanName = (planArray) => {
let planStr = ''; let planStr = '';
planArray.map((item, index) => { planArray.forEach((item, index) => {
if (index < planArray.length - 1) { if (index < planArray.length - 1) {
planStr = planStr + item.planName + '、'; planStr = planStr + item.planName + '、';
} else { } else {
......
/* /*
* @Author: zhangleyuan * @Author: zhangleyuan
* @Date: 2021-02-20 16:45:51 * @Date: 2021-02-20 16:45:51
* @LastEditors: fusanqiasng * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-01 15:20:33 * @LastEditTime: 2021-07-06 14:48:54
* @Description: 描述一下 * @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -12,7 +12,7 @@ import { withRouter } from 'react-router-dom'; ...@@ -12,7 +12,7 @@ import { withRouter } from 'react-router-dom';
import SelectOperatorModal from '../modal/SelectOperatorModal'; import SelectOperatorModal from '../modal/SelectOperatorModal';
import SelectPrepareFileModal from '@/modules/prepare-lesson/modal/SelectPrepareFileModal'; import SelectPrepareFileModal from '@/modules/prepare-lesson/modal/SelectPrepareFileModal';
import Upload from '@/core/upload'; import Upload from '@/core/upload';
// import PhotoClip from 'photoclip' import ImgClipModal from '@/components/ImgClipModal'
import './BasicInfo.less'; import './BasicInfo.less';
const { TextArea } = Input; const { TextArea } = Input;
...@@ -22,6 +22,7 @@ class BasicInfo extends React.Component { ...@@ -22,6 +22,7 @@ class BasicInfo extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
imageFile: null, // 需要被截取的图片
operatorModalVisible: false, operatorModalVisible: false,
showSelectFileModal: false, showSelectFileModal: false,
cutImageBlob: null, cutImageBlob: null,
...@@ -71,80 +72,11 @@ class BasicInfo extends React.Component { ...@@ -71,80 +72,11 @@ class BasicInfo extends React.Component {
}, 1000); }, 1000);
}; };
handleSelectCover = (file) => { handleSelectCover = (file) => {
this.uploadImage(file); this.setState({
}; visible: true,
imageFile:file
//上传图片 });
uploadImage = (imageFile) => {
const self = this;
this.setState(
{
visible: true,
},
() => {
setTimeout(() => {
const okBtnDom = document.querySelector('#headPicModal');
const options = {
size: [500, 282],
ok: okBtnDom,
maxZoom: 3,
style: {
jpgFillColor: 'transparent',
},
done: function (dataUrl) {
clearTimeout(self.timer);
self.timer = setTimeout(() => {
if (self.state.rotate !== this.rotate() || self.state.scale !== this.scale()) {
console.log(this.scale(), 'scale');
const _dataUrl = this.clip();
const cutImageBlob = self.convertBase64UrlToBlob(_dataUrl);
self.setState({
cutImageBlob,
dataUrl: _dataUrl,
rotate: this.rotate(),
scale: this.scale(),
});
}
}, 500);
const cutImageBlob = self.convertBase64UrlToBlob(dataUrl);
self.setState({
cutImageBlob,
dataUrl,
});
setTimeout(() => {
cutFlag = false;
}, 2000);
},
fail: (failInfo) => {
message.error('图片上传失败了,请重新上传');
},
loadComplete: function (img) {
setTimeout(() => {
const _dataUrl = this.clip();
self.setState({
dataUrl: _dataUrl,
hasImgReady: true,
});
}, 100);
},
};
const imgUrl = `${imageFile.ossUrl}?${new Date().getTime()}`;
if (!this.state.photoclip) {
const _photoclip = new PhotoClip('#headPicModal', options);
_photoclip.load(imgUrl);
this.setState({
photoclip: _photoclip,
});
} else {
this.state.photoclip.clear();
this.state.photoclip.load(imgUrl);
}
}, 200);
}
);
}; };
//获取resourceId //获取resourceId
getSignature = (blob, fileName) => { getSignature = (blob, fileName) => {
Upload.uploadBlobToOSS(blob, 'cover' + new Date().valueOf(), null, 'signInfo').then((signInfo) => { Upload.uploadBlobToOSS(blob, 'cover' + new Date().valueOf(), null, 'signInfo').then((signInfo) => {
...@@ -168,16 +100,6 @@ class BasicInfo extends React.Component { ...@@ -168,16 +100,6 @@ class BasicInfo extends React.Component {
this.props.onChange('coverId', coverId); this.props.onChange('coverId', coverId);
}, 1000); }, 1000);
}; };
// base64转换成blob
convertBase64UrlToBlob = (urlData) => {
const bytes = window.atob(urlData.split(',')[1]);
const ab = new ArrayBuffer(bytes.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], { type: 'image/png' });
};
limitNumber = (value) => { limitNumber = (value) => {
if (typeof value === 'string') { if (typeof value === 'string') {
return !isNaN(Number(value)) ? value.replace(/^(0+)|[^\d]/g, '') : ''; return !isNaN(Number(value)) ? value.replace(/^(0+)|[^\d]/g, '') : '';
...@@ -203,7 +125,7 @@ class BasicInfo extends React.Component { ...@@ -203,7 +125,7 @@ class BasicInfo extends React.Component {
}; };
render() { render() {
const { operatorModalVisible, showSelectFileModal, visible, hasImgReady, cutImageBlob } = this.state; const { operatorModalVisible, showSelectFileModal, visible, hasImgReady, cutImageBlob,imageFile} = this.state;
const { data } = this.props; const { data } = this.props;
const { planName, coverUrl, instro, enableState, operateType, selectOperatorList, percentCompleteLive, percentCompleteVideo, percentCompletePicture } = const { planName, coverUrl, instro, enableState, operateType, selectOperatorList, percentCompleteLive, percentCompleteVideo, percentCompletePicture } =
data; data;
...@@ -403,61 +325,9 @@ class BasicInfo extends React.Component { ...@@ -403,61 +325,9 @@ class BasicInfo extends React.Component {
onSelect={this.handleSelectCover} onSelect={this.handleSelectCover}
/> />
)} )}
<Modal { visible &&
title='设置图片' <ImgClipModal visible={visible} imgUrl={imageFile.ossUrl} onConfirm={this.getSignature} onClose={()=>{this.setState({ visible: false });}}/>
width={1080} }
visible={visible}
maskClosable={false}
closeIcon={<span className='icon iconfont modal-close-icon'>&#xe6ef;</span>}
onCancel={() => {
this.setState({ visible: false });
}}
zIndex={10001}
footer={[
<Button
key='back'
onClick={() => {
this.setState({ visible: false });
}}>
重新上传
</Button>,
<Button
key='submit'
type='primary'
disabled={!hasImgReady}
onClick={() => {
if (!cutFlag) {
cutFlag = true;
this.refs.hiddenBtn.click();
}
this.getSignature(cutImageBlob);
}}>
确定
</Button>,
]}>
<div className='clip-box'>
<div
id='headPicModal'
ref='headPicModal'
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='preview-url-box' style={{ width: 500, height: 282 }}>
<img src={this.state.dataUrl} style={{ width: '100%' }} alt='' />
</div>
<div className='tip-box'>
<div className='tip'>温馨提示</div>
<div className='tip'>①预览效果图时可能存在延迟,单击左侧图片刷新即可</div>
<div className='tip'>②设置图片时双击可旋转图片,滚动可放大或缩小图片</div>
</div>
</div>
</div>
</Modal>
</div> </div>
); );
} }
......
...@@ -8,9 +8,9 @@ ...@@ -8,9 +8,9 @@
*/ */
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Table, Modal, message, Tooltip, Switch, Dropdown } from 'antd'; import { Modal, message, Tooltip, Switch, Dropdown } from 'antd';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import { PageControl, XMTable } from "@/components"; import { PageControl, XMTable } from '@/components';
import PlanService from '@/domains/plan-domain/planService'; import PlanService from '@/domains/plan-domain/planService';
import SharePlanModal from '../modal/SharePlanModal'; import SharePlanModal from '../modal/SharePlanModal';
import { LIVE_SHARE } from '@/domains/course-domain/constants'; import { LIVE_SHARE } from '@/domains/course-domain/constants';
...@@ -29,6 +29,7 @@ function PlanList(props) { ...@@ -29,6 +29,7 @@ function PlanList(props) {
key: 'planName', key: 'planName',
dataIndex: 'planName', dataIndex: 'planName',
width: '18%', width: '18%',
fixed: 'left',
render: (val, record) => { render: (val, record) => {
return ( return (
<div className='plan_name_item'> <div className='plan_name_item'>
...@@ -86,7 +87,7 @@ function PlanList(props) { ...@@ -86,7 +87,7 @@ function PlanList(props) {
dataIndex: 'created', dataIndex: 'created',
sorter: true, sorter: true,
render: (val) => { render: (val) => {
return window.formatDate('YYYY-MM-DD H:i', val); return <span style={{ whiteSpace: 'nowrap' }}>{window.formatDate('YYYY-MM-DD H:i', val)}</span>;
}, },
}, },
{ {
...@@ -96,12 +97,12 @@ function PlanList(props) { ...@@ -96,12 +97,12 @@ function PlanList(props) {
dataIndex: 'updated', dataIndex: 'updated',
sorter: true, sorter: true,
render: (val) => { render: (val) => {
return window.formatDate('YYYY-MM-DD H:i', val); return <span style={{ whiteSpace: 'nowrap' }}>{window.formatDate('YYYY-MM-DD H:i', val)}</span>;
}, },
}, },
{ {
title: '参培人数', title: '参培人数',
width: 76, width: '10%',
key: 'cultureCustomerNum', key: 'cultureCustomerNum',
dataIndex: 'cultureCustomerNum', dataIndex: 'cultureCustomerNum',
sorter: true, sorter: true,
...@@ -114,7 +115,7 @@ function PlanList(props) { ...@@ -114,7 +115,7 @@ function PlanList(props) {
key: 'operate', key: 'operate',
dataIndex: 'operate', dataIndex: 'operate',
fixed: 'right', fixed: 'right',
width: 176, width: '14.5%',
render: (val, record) => { render: (val, record) => {
return ( return (
<div className='operate'> <div className='operate'>
...@@ -317,7 +318,7 @@ function PlanList(props) { ...@@ -317,7 +318,7 @@ function PlanList(props) {
scroll={{ x: 1400 }} scroll={{ x: 1400 }}
className='plan-list-table' className='plan-list-table'
renderEmpty={{ renderEmpty={{
description: <span style={{ display: 'block', paddingBottom: 24 }}>暂无数据</span> description: <span style={{ display: 'block', paddingBottom: 24 }}>暂无数据</span>,
}} }}
/> />
<div className='box-footer'> <div className='box-footer'>
......
.training-task{ .training-task {
thead{ thead {
display:none; display: none;
} }
.ant-form-item{ .ant-form-item {
margin-bottom:0 !important; margin-bottom: 0 !important;
} }
.add-task-con{ .add-task-con {
height: 52px; height: 52px;
background: #F7F8F9; background: #f7f8f9;
border-radius: 2px; border-radius: 2px;
padding:16px; padding: 16px;
margin-top:16px; margin-top: 16px;
.add-task-btn-disabled{ .add-task-btn-disabled {
color:#CCCCCC; color: #cccccc;
font-size:14px; font-size: 14px;
} }
.add-task-btn{ .add-task-btn {
color: #2966FF; color: #2966ff;
font-size:14px; font-size: 14px;
}
} }
}
} }
.plan-sort-task-item{ .plan-sort-task-item {
.task-con{ .task-con {
display:flex; display: flex;
padding:16px; padding: 16px;
background: #F7F8F9; background: #f7f8f9;
border-radius: 2px; border-radius: 2px;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
.task-instro{ .task-instro {
display:flex; display: flex;
align-items: center; align-items: center;
.open-icon{ .open-icon {
color:#999999; color: #999999;
font-size:10px; font-size: 10px;
} }
.task-name-con{ .task-name-con {
display:flex; display: flex;
align-items: center; align-items: center;
color:#333333; color: #333333;
font-size:14px; font-size: 14px;
.number{ .number {
margin-right:10px; margin-right: 10px;
margin-left:10px; margin-left: 10px;
} }
.task-name-input{ .task-name-input {
width: 300px; width: 300px;
height: 32px; height: 32px;
background: #FFFFFF; background: #ffffff;
border-radius: 4px; border-radius: 4px;
} }
} }
} }
.operate{ .operate {
display: none; display: none;
.operate__item{ .operate__item {
cursor:pointer; cursor: pointer;
margin-left:16px; margin-left: 16px;
color:#666666; color: #666666;
font-size:14px; font-size: 14px;
.icon{ .icon {
font-size:14px; font-size: 14px;
color:#999; color: #999;
} }
.text{ .text {
margin-left:8px; margin-left: 8px;
} }
} }
} }
&:hover{ &:hover {
.operate{ .operate {
display:block; display: block;
} }
} }
} }
.course-box{ .course-box {
.add-course-con{ .add-course-con {
padding:16px 51px; padding: 16px 51px;
color: #2966FF; color: #2966ff;
font-size:14px; font-size: 14px;
.add-course-btn-disabled{ .add-course-btn-disabled {
font-size:14px; font-size: 14px;
color:#ccc; color: #ccc;
} pointer-events: none;
}
} }
} }
} }
.plan-course-sort-item{ .plan-course-sort-item {
display:flex; display: flex;
padding:16px 16px 16px 0px; padding: 16px 16px 16px 0px;
margin-left:51px; margin-left: 51px;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
border-bottom:1px dotted #E8E8E8; border-bottom: 1px dotted #e8e8e8;
&:hover{ &:hover {
.course-operate{ .course-operate {
display:block; display: block;
} }
} }
.course-operate{ .course-operate {
display: none; display: none;
.operate__item{ .operate__item {
cursor:pointer; cursor: pointer;
margin-left:16px; margin-left: 16px;
color:#666666; color: #666666;
font-size:14px; font-size: 14px;
.icon{ .icon {
font-size:14px; font-size: 14px;
color:#999; color: #999;
} }
.text{ .text {
margin-left:8px; margin-left: 8px;
} }
} }
} }
.course-info{ .course-info {
.ant-form{ .ant-form {
display:inline-block; display: inline-block;
} }
.course-name-input{ .course-name-input {
margin-right:8px; margin-right: 8px;
} }
.course-type{ .course-type {
font-size:11px; font-size: 11px;
color:#666666; color: #666666;
padding:0px 6px; padding: 0px 6px;
border: 1px solid #999999; border: 1px solid #999999;
margin-right:4px; margin-right: 4px;
border-radius: 2px; border-radius: 2px;
line-height: 16px; line-height: 16px;
} }
.course-name{ .course-name {
color:#666666; color: #666666;
font-size:14px; font-size: 14px;
margin-right:8px; margin-right: 8px;
} }
.tip{ .tip {
font-size:14px; font-size: 14px;
color:#FF4F4F; color: #ff4f4f;
margin-right:2px; margin-right: 2px;
} }
.course-state{ .course-state {
color:#999; color: #999;
font-size:14px; font-size: 14px;
} }
} }
} }
...@@ -330,7 +330,7 @@ class UserLearningData extends React.Component { ...@@ -330,7 +330,7 @@ class UserLearningData extends React.Component {
<span> <span>
<span>学习进度</span> <span>学习进度</span>
<Tooltip title='学员培训计划中达到“已完成”状态的课程数/总课程数'> <Tooltip title='学员培训计划中达到“已完成”状态的课程数/总课程数'>
<i className='icon iconfont' style={{ marginLeft: '5px', cursor: 'pointer', color: '#bfbfbf', fontSize: '14px' }}> <i className='icon iconfont' style={{ marginLeft: '5px', cursor: 'pointer', color: '#bfbfbf', fontSize: '14px', fontWeight: 'normal' }}>
&#xe61d; &#xe61d;
</i> </i>
</Tooltip> </Tooltip>
......
...@@ -494,7 +494,7 @@ class SelectOperatorModal extends React.Component { ...@@ -494,7 +494,7 @@ class SelectOperatorModal extends React.Component {
} else { } else {
_list = _.reject(selectLive, (item) => item.liveCourseId === record.liveCourseId); _list = _.reject(selectLive, (item) => item.liveCourseId === record.liveCourseId);
} }
if (_list.length + currentTaskCourseData.length + selectVideo.length + selectPicture.length > 20) { if (_list.length + currentTaskCourseData.length + selectVideo.internal.length + selectVideo.external.length + selectPicture.length > 20) {
message.warning('无法继续选择,一个任务最多关联20个课程'); message.warning('无法继续选择,一个任务最多关联20个课程');
return; return;
} }
...@@ -505,14 +505,14 @@ class SelectOperatorModal extends React.Component { ...@@ -505,14 +505,14 @@ class SelectOperatorModal extends React.Component {
const { selectVideo, currentTaskCourseData, selectLive, selectPicture, videoCourseDivision } = this.state; const { selectVideo, currentTaskCourseData, selectLive, selectPicture, videoCourseDivision } = this.state;
let { [videoCourseDivision]: selectList } = selectVideo; let { [videoCourseDivision]: selectList } = selectVideo;
let otherVideoCourseDivision = videoCourseDivision === 'internal' ? 'external' : 'internal';
let _list = []; let _list = [];
if (selected || !_.find(selectList, (item) => item.id === record.id)) { if (selected || !_.find(selectList, (item) => item.id === record.id)) {
_list = _.uniq(selectList.concat([record]), false, (item) => item.id); _list = _.uniq(selectList.concat([record]), false, (item) => item.id);
} else { } else {
_list = _.reject(selectList, (item) => item.id === record.id); _list = _.reject(selectList, (item) => item.id === record.id);
} }
if (_list.length + currentTaskCourseData.length + selectLive.length + selectPicture.length > 20) { if (_list.length + selectVideo[otherVideoCourseDivision]?.length + currentTaskCourseData.length + selectLive.length + selectPicture.length > 20) {
message.warning('无法继续选择,一个任务最多关联20个课程'); message.warning('无法继续选择,一个任务最多关联20个课程');
return; return;
} }
...@@ -532,7 +532,7 @@ class SelectOperatorModal extends React.Component { ...@@ -532,7 +532,7 @@ class SelectOperatorModal extends React.Component {
} else { } else {
_list = _.reject(selectPicture, (item) => item.id === record.id); _list = _.reject(selectPicture, (item) => item.id === record.id);
} }
if (_list.length + currentTaskCourseData.length + selectLive.length + selectVideo.length > 20) { if (_list.length + currentTaskCourseData.length + selectLive.length + selectVideo.internal.length + selectVideo.external.length > 20) {
message.warning('无法继续选择,一个任务最多关联20个课程'); message.warning('无法继续选择,一个任务最多关联20个课程');
return; return;
} }
...@@ -757,9 +757,10 @@ class SelectOperatorModal extends React.Component { ...@@ -757,9 +757,10 @@ class SelectOperatorModal extends React.Component {
} else { } else {
_list = _.reject(selectLive, (item) => _.find(changeRows, (data) => data.liveCourseId === item.liveCourseId)); _list = _.reject(selectLive, (item) => _.find(changeRows, (data) => data.liveCourseId === item.liveCourseId));
} }
if (_list.length + currentTaskCourseData.length + selectVideo.length + selectPicture.length > 20) { if (_list.length + currentTaskCourseData.length + selectVideo.internal.length + selectVideo.external.length + selectPicture.length > 20) {
message.warning('无法继续选择,一个任务最多关联20个课程'); message.warning('无法继续选择,一个任务最多关联20个课程');
const extraLength = _list.length + currentTaskCourseData.length + selectVideo.length + selectPicture.length - 20; const extraLength =
_list.length + currentTaskCourseData.length + selectVideo.internal.length + selectVideo.external.length + +selectPicture.length - 20;
_list.splice(_list.length - extraLength, extraLength); _list.splice(_list.length - extraLength, extraLength);
} }
this.setState({ selectLive: _list }); this.setState({ selectLive: _list });
...@@ -847,14 +848,24 @@ class SelectOperatorModal extends React.Component { ...@@ -847,14 +848,24 @@ class SelectOperatorModal extends React.Component {
}, },
onSelectAll: (selected, _selectedRows, changeRows) => { onSelectAll: (selected, _selectedRows, changeRows) => {
let _list = []; let _list = [];
let otherVideoCourseDivision = videoCourseDivision === 'internal' ? 'external' : 'internal';
if (selected) { if (selected) {
_list = _.uniq(selectVideo[videoCourseDivision].concat(changeRows), false, (item) => item.id); _list = _.uniq(selectVideo[videoCourseDivision].concat(changeRows), false, (item) => item.id);
} else { } else {
_list = _.reject(selectVideo[videoCourseDivision], (item) => _.find(changeRows, (data) => data.id === item.id)); _list = _.reject(selectVideo[videoCourseDivision], (item) => _.find(changeRows, (data) => data.id === item.id));
} }
if (_list.length + currentTaskCourseData.length + selectLive.length + selectPicture.length > 20) { if (
_list.length + selectVideo[otherVideoCourseDivision]?.length + currentTaskCourseData.length + selectLive.length + selectPicture.length >
20
) {
message.warning('无法继续选择,一个任务最多关联20个课程'); message.warning('无法继续选择,一个任务最多关联20个课程');
const extraLength = _list.length + currentTaskCourseData.length + selectLive.length + selectPicture.length - 20; const extraLength =
_list.length +
selectVideo[otherVideoCourseDivision]?.length +
currentTaskCourseData.length +
selectLive.length +
selectPicture.length -
20;
_list.splice(_list.length - extraLength, extraLength); _list.splice(_list.length - extraLength, extraLength);
} }
this.setState({ this.setState({
...@@ -951,9 +962,10 @@ class SelectOperatorModal extends React.Component { ...@@ -951,9 +962,10 @@ class SelectOperatorModal extends React.Component {
} else { } else {
_list = _.reject(selectPicture, (item) => _.find(changeRows, (data) => data.id === item.id)); _list = _.reject(selectPicture, (item) => _.find(changeRows, (data) => data.id === item.id));
} }
if (_list.length + currentTaskCourseData.length + selectVideo.length + selectLive.length > 20) { if (_list.length + currentTaskCourseData.length + selectVideo.internal.length + selectVideo.external.length + selectLive.length > 20) {
message.warning('无法继续选择,一个任务最多关联20个课程'); message.warning('无法继续选择,一个任务最多关联20个课程');
const extraLength = _list.length + currentTaskCourseData.length + selectVideo.length + selectLive.length - 20; const extraLength =
_list.length + currentTaskCourseData.length + selectVideo.internal.length + selectVideo.external.length + selectLive.length - 20;
_list.splice(_list.length - extraLength, extraLength); _list.splice(_list.length - extraLength, extraLength);
} }
this.setState({ selectPicture: _list }); this.setState({ selectPicture: _list });
......
...@@ -436,7 +436,7 @@ class SelectPrepareFileModal extends React.Component { ...@@ -436,7 +436,7 @@ class SelectPrepareFileModal extends React.Component {
selectType, selectType,
multiple, multiple,
accept = ".ppt,.pptx,.doc,.docx,.pdf,.jpg,.jpeg,.png,.mp3,.mp4,.xlsx,.xls", accept = ".ppt,.pptx,.doc,.docx,.pdf,.jpg,.jpeg,.png,.mp3,.mp4,.xlsx,.xls",
tooltip = '支持文件类型:ppt、word、excel、pdf、jpg、jpeg、png、mp3、mp4' tooltip = '支持文件类型:ppt、word、excel、pdf、jpg、jpeg、png、mp3、mp4,支持批量上传文件'
} = this.props; } = this.props;
const selectedFileLength = selectedFileList.length; const selectedFileLength = selectedFileList.length;
......
...@@ -809,7 +809,7 @@ class FolderList extends React.Component { ...@@ -809,7 +809,7 @@ class FolderList extends React.Component {
<Choose> <Choose>
<When condition={hasManagementAuthority}> <When condition={hasManagementAuthority}>
<div className="lottie-icon-title">你还没有上传文件,点击 <div className="lottie-icon-title">你还没有上传文件,点击
<Tooltip title="支持文件类型:ppt、word、excel、pdf、jpg、mp3、mp4"> <Tooltip title="支持文件类型:ppt、word、excel、pdf、jpg、mp3、mp4,上传后默认私密,可邀请其他成员协作,支持批量上传文件">
<span <span
className="upload-btn" className="upload-btn"
onClick={this.handleChooseFile} onClick={this.handleChooseFile}
......
...@@ -314,7 +314,7 @@ class OperateArea extends React.Component { ...@@ -314,7 +314,7 @@ class OperateArea extends React.Component {
accept=".ppt,.pptx,.doc,.docx,.pdf,.jpg,.jpeg,.png,.mp3,.mp4,.xlsx,.xls" accept=".ppt,.pptx,.doc,.docx,.pdf,.jpg,.jpeg,.png,.mp3,.mp4,.xlsx,.xls"
onChange={(e) => this.handleUpload(e)} onChange={(e) => this.handleUpload(e)}
/> />
<Tooltip title="支持文件类型:ppt、word、excel、pdf、jpg、mp3、mp4,上传后默认私密,可邀请其他成员协作"> <Tooltip title="支持文件类型:ppt、word、excel、pdf、jpg、mp3、mp4,上传后默认私密,可邀请其他成员协作,支持批量上传文件">
<Button <Button
type={!showResultPage?"primary":""} type={!showResultPage?"primary":""}
disabled={showResultPage} disabled={showResultPage}
......
...@@ -5,6 +5,7 @@ import Service from "@/common/js/service"; ...@@ -5,6 +5,7 @@ import Service from "@/common/js/service";
import BaseService from "@/domains/basic-domain/baseService"; import BaseService from "@/domains/basic-domain/baseService";
import User from "@/common/js/user"; import User from "@/common/js/user";
import Breadcrumbs from "@/components/Breadcrumbs"; import Breadcrumbs from "@/components/Breadcrumbs";
import ImgClipModal from '@/components/ImgClipModal'
import './CreateCollege.less'; import './CreateCollege.less';
let cutFlag = false; let cutFlag = false;
...@@ -18,6 +19,7 @@ export default class CreateCollege extends React.Component { ...@@ -18,6 +19,7 @@ export default class CreateCollege extends React.Component {
logo: 'https://image.xiaomaiketang.com/xm/fe4NCjr7XF.png', logo: 'https://image.xiaomaiketang.com/xm/fe4NCjr7XF.png',
name: '', name: '',
enterpriseId: User.getEnterpriseId(), enterpriseId: User.getEnterpriseId(),
imageFile: null, // 需要被截取的图片
}; };
this.loginInputRef = React.createRef() this.loginInputRef = React.createRef()
} }
...@@ -46,95 +48,14 @@ export default class CreateCollege extends React.Component { ...@@ -46,95 +48,14 @@ export default class CreateCollege extends React.Component {
handleSelectCover = (e) => { handleSelectCover = (e) => {
const imageFile = e.target.files[0]; const imageFile = e.target.files[0];
Upload.uploadBlobToOSS(imageFile, 'cover' + (new Date()).valueOf()).then((url) => { Upload.uploadBlobToOSS(imageFile, 'cover' + (new Date()).valueOf()).then((url) => {
this.uploadImage({ folderName: imageFile.name, ossUrl: url }); this.setState({
visible: true,
imageFile:{ folderName: imageFile.name, ossUrl: url }
});
// this.uploadImage({ folderName: imageFile.name, ossUrl: url });
}) })
} }
//上传图片
uploadImage = (imageFile) => {
const { folderName } = imageFile;
const fileName = window.random_string(16) + folderName.slice(folderName.lastIndexOf("."));
const self = this;
this.setState(
{
visible: true,
},
() => {
setTimeout(() => {
const okBtnDom = document.querySelector("#headPicModal");
const options = {
size: [500, 128],
ok: okBtnDom,
maxZoom: 3,
style: {
jpgFillColor: "transparent",
},
done: function (dataUrl) {
clearTimeout(self.timer);
self.timer = setTimeout(() => {
if ((self.state.rotate != this.rotate()) || (self.state.scale != this.scale())) {
const _dataUrl = this.clip()
const cutImageBlob = self.convertBase64UrlToBlob(_dataUrl);
self.setState({
cutImageBlob,
dataUrl: _dataUrl,
rotate: this.rotate(),
scale: this.scale()
})
}
}, 500)
const cutImageBlob = self.convertBase64UrlToBlob(dataUrl);
self.setState({
cutImageBlob,
dataUrl
})
setTimeout(() => {
cutFlag = false;
}, 2000);
},
fail: (failInfo) => {
message.error("图片上传失败了,请重新上传");
},
loadComplete: function (img) {
setTimeout(() => {
const _dataUrl = this.clip()
self.setState({
dataUrl: _dataUrl,
hasImgReady: true
})
}, 100)
},
};
const imgUrl = `${imageFile.ossUrl}?${new Date().getTime()}`
if (!this.state.photoclip) {
const _photoclip = new PhotoClip("#headPicModal", options);
_photoclip.load(imgUrl);
this.setState({
photoclip: _photoclip,
});
} else {
this.state.photoclip.clear();
this.state.photoclip.load(imgUrl);
}
}, 200);
}
);
};
// base64转换成blob
convertBase64UrlToBlob = (urlData) => {
const bytes = window.atob(urlData.split(",")[1]);
const ab = new ArrayBuffer(bytes.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], { type: "image/png" });
};
//获取resourceId //获取resourceId
getSignature = (blob, fileName) => { getSignature = (blob, fileName) => {
...@@ -184,6 +105,7 @@ export default class CreateCollege extends React.Component { ...@@ -184,6 +105,7 @@ export default class CreateCollege extends React.Component {
hasImgReady, hasImgReady,
cutImageBlob, cutImageBlob,
showError, showError,
imageFile
} = this.state; } = this.state;
return ( return (
<div className="college-manage-page"> <div className="college-manage-page">
...@@ -247,65 +169,9 @@ export default class CreateCollege extends React.Component { ...@@ -247,65 +169,9 @@ export default class CreateCollege extends React.Component {
style={{ display: "none" }} style={{ display: "none" }}
onChange={this.handleSelectCover} onChange={this.handleSelectCover}
/> />
<Modal { visible &&
title="设置图片" <ImgClipModal visible={visible} imgUrl={imageFile.ossUrl} aspectRatio='125/32' cropBoxHeight='128' onConfirm={this.getSignature} onClose={()=>{this.setState({ visible: false });}}/>
width={1080} }
visible={visible}
maskClosable={false}
closeIcon={<span className="icon iconfont modal-close-icon">&#xe6ef;</span>}
onCancel={() => {
this.setState({ visible: false });
}}
zIndex={10001}
footer={[
<Button
key="back"
onClick={() => {
this.setState({ visible: false });
}}
>
重新上传
</Button>,
<Button
key="submit"
type="primary"
disabled={!hasImgReady}
onClick={() => {
if (!cutFlag) {
cutFlag = true;
this.refs.hiddenBtn.click();
}
this.getSignature(cutImageBlob);
}}
>
确定
</Button>,
]}
>
<div className="clip-box">
<div
id="headPicModal"
ref="headPicModal"
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="preview-url-box" style={{width:500,height:128}}>
<img src={this.state.dataUrl} style={{ width: '100%' }} alt="" />
</div>
<div className="tip-box">
<div className="tip">温馨提示</div>
<div className="tip">①预览效果图时可能存在延迟,单击左侧图片刷新即可</div>
<div className="tip">②设置图片时双击可旋转图片,滚动可放大或缩小图片</div>
</div>
</div>
</div>
</Modal>
</div> </div>
) )
} }
......
/* /*
* @Author: 吴文洁 * @Author: 吴文洁
* @Date: 2019-09-10 18:26:03 * @Date: 2019-09-10 18:26:03
* @LastEditors: Please set LastEditors * @LastEditors: yuananting
* @LastEditTime: 2021-06-24 19:28:14 * @LastEditTime: 2021-07-06 14:37:49
* @Description: * @Description:
*/ */
import React, { useRef, useContext, useEffect, useState } from 'react'; import React, { useRef, useContext, useEffect, useState } from 'react';
...@@ -271,14 +271,14 @@ function Header(props) { ...@@ -271,14 +271,14 @@ function Header(props) {
onChange={(e) => { onChange={(e) => {
setStoreId(e.target.value); setStoreId(e.target.value);
User.setStoreId(e.target.value); User.setStoreId(e.target.value);
list.map((item)=>{ list.map((item) => {
if(item.id === e.target.value){ if (item.id === e.target.value) {
User.setStoreUserId(item.storeUserId); User.setStoreUserId(item.storeUserId);
} }
}) });
User.setUserId(User.getUserId()); User.setUserId(User.getUserId());
User.setToken(User.getToken()); User.setToken(User.getToken());
User.setEnterpriseId(User.getEnterpriseId()) User.setEnterpriseId(User.getEnterpriseId());
window.RCHistory.push('/home'); window.RCHistory.push('/home');
window.location.reload(); window.location.reload();
}} }}
...@@ -320,10 +320,10 @@ function Header(props) { ...@@ -320,10 +320,10 @@ function Header(props) {
</div> </div>
)} )}
<div className='right-box'> <div className='right-box'>
<div className='right-bg-img'>
<img src='https://image.xiaomaiketang.com/xm/WCwjyyXYda.png'></img>
</div>
<div className='link-to-store'> <div className='link-to-store'>
<div className='right-bg-img'>
<img src='https://image.xiaomaiketang.com/xm/WCwjyyXYda.png'></img>
</div>
<div className='link'> <div className='link'>
<span className='link-btn'> <span className='link-btn'>
<span className='icon iconfont tool-tip-right'>&#xe85d;</span> <span className='icon iconfont tool-tip-right'>&#xe85d;</span>
......
...@@ -196,7 +196,6 @@ ...@@ -196,7 +196,6 @@
margin-left: 62px; margin-left: 62px;
.college-container { .college-container {
position: relative; position: relative;
width: 360px;
height: 50px; height: 50px;
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -310,13 +309,9 @@ ...@@ -310,13 +309,9 @@
display: flex; display: flex;
align-items: center; align-items: center;
} }
.right-bg-img {
img {
width: 277px;
height: 60px;
}
}
.link-to-store { .link-to-store {
position: relative;
display: flex; display: flex;
height: 49px; height: 49px;
line-height: 49px; line-height: 49px;
...@@ -329,6 +324,14 @@ ...@@ -329,6 +324,14 @@
.iconfont { .iconfont {
color: #fff; color: #fff;
} }
.right-bg-img {
position: absolute;
right: 347px;
img {
width: 277px;
height: 60px;
}
}
.link { .link {
cursor: pointer; cursor: pointer;
position: relative; position: relative;
......
...@@ -11,6 +11,7 @@ import StoreService from '@/domains/store-domain/storeService'; ...@@ -11,6 +11,7 @@ import StoreService from '@/domains/store-domain/storeService';
import classNames from 'classnames'; import classNames from 'classnames';
import User from "@/common/js/user" import User from "@/common/js/user"
import _ from 'underscore'; import _ from 'underscore';
import tBus from '@/core/tbus'
import "./Menu.less"; import "./Menu.less";
import { display } from 'html2canvas/dist/types/css/property-descriptors/display'; import { display } from 'html2canvas/dist/types/css/property-descriptors/display';
import ContactWidget from '@/components/ContactWidget'; import ContactWidget from '@/components/ContactWidget';
...@@ -138,11 +139,20 @@ function Aside(props: any) { ...@@ -138,11 +139,20 @@ function Aside(props: any) {
}); });
} }
return item; return item;
}); })
}, [props.location.pathname]); }, [props.location.pathname])
useEffect(() => {
getTopLeftLogo(); useEffect(()=> {
}, []); getTopLeftLogo()
tBus.bind("updateCollegeInfo",updateCollegeInfo)
return ()=> {
tBus.unbind("updateCollegeInfo",updateCollegeInfo)
}
},[])
function updateCollegeInfo() {
getTopLeftLogo()
}
function getTopLeftLogo() { function getTopLeftLogo() {
if (User.getToken()) { if (User.getToken()) {
......
/* /*
* @Author: wufan * @Author: wufan
* @Date: 2020-11-30 10:47:38 * @Date: 2020-11-30 10:47:38
* @LastEditors: wufan * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-21 11:16:21 * @LastEditTime: 2021-07-08 19:35:17
* @Description: web学院banner页面 * @Description: web学院banner页面
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -25,6 +25,7 @@ import "./StoreDecorationPage.less"; ...@@ -25,6 +25,7 @@ import "./StoreDecorationPage.less";
import Upload from "@/core/upload"; import Upload from "@/core/upload";
import { XMTable } from '@/components'; import { XMTable } from '@/components';
import college from '@/common/lottie/college'; import college from '@/common/lottie/college';
import ImgClipModal from '@/components/ImgClipModal'
const { confirm } = Modal; const { confirm } = Modal;
const DragHandle = sortableHandle(() => ( const DragHandle = sortableHandle(() => (
...@@ -51,7 +52,8 @@ class StoreH5Decoration extends React.Component { ...@@ -51,7 +52,8 @@ class StoreH5Decoration extends React.Component {
photoclip: null, photoclip: null,
preview: "", preview: "",
cutImageBlob: null, cutImageBlob: null,
hasImgReady: false // 图片是否上传成功 hasImgReady: false, // 图片是否上传成功
imageFile: null // 需要被截取的图片
}; };
} }
...@@ -208,88 +210,16 @@ class StoreH5Decoration extends React.Component { ...@@ -208,88 +210,16 @@ class StoreH5Decoration extends React.Component {
// 选择云盘资源 // 选择云盘资源
handleSelectImg = (file) => { handleSelectImg = (file) => {
this.setState({ if(file){
showSelectFileModal: false, this.setState({
});
this.uploadImage(file);
};
//上传图片
uploadImage = (imageFile) => {
const self = this;
this.setState(
{
visible: true, visible: true,
}, imageFile:file
() => { });
setTimeout(() => { }
const okBtnDom = document.querySelector("#headPicModal");
const options = {
size: [500, 172],
ok: okBtnDom,
maxZoom: 3,
style: {
jpgFillColor: "transparent",
},
done: function (dataUrl) {
clearTimeout(self.timer);
self.timer = setTimeout(() => {
if ((self.state.rotate != this.rotate()) || (self.state.scale != this.scale())) {
console.log(this.scale(), 'scale')
const _dataUrl = this.clip()
const cutImageBlob = self.convertBase64UrlToBlob(_dataUrl);
self.setState({
cutImageBlob,
dataUrl: _dataUrl,
rotate: this.rotate(),
scale: this.scale()
})
}
}, 500)
const cutImageBlob = self.convertBase64UrlToBlob(dataUrl);
self.setState({
cutImageBlob,
dataUrl
})
setTimeout(() => {
cutFlag = false;
}, 2000);
},
fail: (failInfo) => {
message.error("图片上传失败了,请重新上传");
},
loadComplete: function (img) {
setTimeout(() => {
const _dataUrl = this.clip()
self.setState({
dataUrl: _dataUrl,
hasImgReady: true
})
}, 100)
},
};
const imgUrl = `${imageFile.ossUrl}?${new Date().getTime()}`
if (!this.state.photoclip) {
const _photoclip = new PhotoClip("#headPicModal", options);
_photoclip.load(imgUrl);
this.setState({
photoclip: _photoclip,
});
} else {
this.state.photoclip.clear();
this.state.photoclip.load(imgUrl);
}
}, 200);
}
);
}; };
//获取resourceId //获取resourceId
getSignature = (blob) => { getSignature = (blob) => {
Upload.uploadBlobToOSS(blob, "avatar" + new Date().valueOf()).then( Upload.uploadBlobToOSS(blob, "avatar" + new Date().valueOf()).then(
...@@ -344,16 +274,6 @@ class StoreH5Decoration extends React.Component { ...@@ -344,16 +274,6 @@ class StoreH5Decoration extends React.Component {
}); });
}; };
// base64转换成blob
convertBase64UrlToBlob = (urlData) => {
const bytes = window.atob(urlData.split(",")[1]);
const ab = new ArrayBuffer(bytes.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], { type: "image/png" });
};
render() { render() {
const { const {
...@@ -362,7 +282,8 @@ class StoreH5Decoration extends React.Component { ...@@ -362,7 +282,8 @@ class StoreH5Decoration extends React.Component {
diskList, diskList,
visible, visible,
cutImageBlob, cutImageBlob,
hasImgReady hasImgReady,
imageFile,
} = this.state; } = this.state;
const DraggableContainer = (props) => ( const DraggableContainer = (props) => (
<SortableContainer <SortableContainer
...@@ -423,65 +344,9 @@ class StoreH5Decoration extends React.Component { ...@@ -423,65 +344,9 @@ class StoreH5Decoration extends React.Component {
}} }}
onSelect={this.handleSelectImg} onSelect={this.handleSelectImg}
/> />
<Modal { visible &&
title="设置图片" <ImgClipModal visible={visible} imgUrl={imageFile.ossUrl} aspectRatio='500/172' cropBoxHeight='172' onConfirm={this.getSignature} onClose={()=>{this.setState({ visible: false });}}/>
width={1080} }
visible={visible}
onCancel={() => {
this.setState({ visible: false });
}}
maskClosable={false}
closeIcon={<span className="icon iconfont modal-close-icon">&#xe6ef;</span>}
footer={[
<Button
key="back"
onClick={() => {
this.setState({ visible: false });
this.state.choosedBannerId ? this.handleReplaceDecoration(this.state.choosedBannerItem):this.handleToAddStoreDecoration();
}}
>
重新上传
</Button>,
<Button
key="submit"
type="primary"
disabled={!hasImgReady}
onClick={() => {
if (!cutFlag) {
cutFlag = true;
this.refs.hiddenBtn.click();
}
this.getSignature(cutImageBlob);
}}
>
确定
</Button>,
]}
>
<div className="clip-box">
<div
id="headPicModal"
ref="headPicModal"
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">
<img src={this.state.dataUrl} style={{ width: '100%' }} alt="" />
</div>
<div className="tip-box">
<div className="tip">温馨提示</div>
<div className="tip">①预览效果图时可能存在延迟,单击左侧图片刷新即可</div>
<div className="tip">②设置图片时双击可旋转图片,滚动可放大或缩小图片</div>
</div>
</div>
</div>
</Modal>
</div> </div>
); );
} }
......
...@@ -4,10 +4,10 @@ import { Form, Input, Button, Checkbox ,Select,Modal,message} from 'antd'; ...@@ -4,10 +4,10 @@ import { Form, Input, Button, Checkbox ,Select,Modal,message} from 'antd';
import {industryList,childIndustryList} from '@/domains/store-domain/constants' import {industryList,childIndustryList} from '@/domains/store-domain/constants'
import SelectPrepareFileModal from '@/modules/prepare-lesson/modal/SelectPrepareFileModal'; import SelectPrepareFileModal from '@/modules/prepare-lesson/modal/SelectPrepareFileModal';
import Upload from '@/core/upload'; import Upload from '@/core/upload';
// import PhotoClip from 'photoclip';
import StoreService from "@/domains/store-domain/storeService"; import StoreService from "@/domains/store-domain/storeService";
import User from "@/common/js/user"; import User from "@/common/js/user";
import Bus from '@/core/tbus'; import Bus from '@/core/tbus';
import ImgClipModal from '@/components/ImgClipModal'
import "./StoreInfo.less"; import "./StoreInfo.less";
let cutFlag = false; let cutFlag = false;
class StoreInfo extends React.Component { class StoreInfo extends React.Component {
...@@ -23,6 +23,7 @@ class StoreInfo extends React.Component { ...@@ -23,6 +23,7 @@ class StoreInfo extends React.Component {
logo:'', logo:'',
showSelectFileModal:false, showSelectFileModal:false,
cutImageBlob: null, cutImageBlob: null,
imageFile: null, // 需要被截取的图片
} }
} }
componentWillMount(){ componentWillMount(){
...@@ -73,85 +74,12 @@ class StoreInfo extends React.Component { ...@@ -73,85 +74,12 @@ class StoreInfo extends React.Component {
}) })
} }
handleSelectCover = (file)=> { handleSelectCover = (file)=> {
this.uploadImage(file); this.setState({
visible: true,
imageFile:file
});
} }
//上传图片
uploadImage = (imageFile) => {
const { folderName } = imageFile;
const fileName = window.random_string(16) + folderName.slice(folderName.lastIndexOf("."));
const self = this;
this.setState(
{
visible: true,
},
() => {
setTimeout(() => {
const okBtnDom = document.querySelector("#headPicModal");
const options = {
size: [500, 128],
ok: okBtnDom,
maxZoom: 3,
style: {
jpgFillColor: "transparent",
},
done: function (dataUrl) {
clearTimeout(self.timer);
self.timer = setTimeout(() => {
if ((self.state.rotate != this.rotate()) || (self.state.scale != this.scale())) {
console.log(this.scale(), 'scale')
const _dataUrl = this.clip()
const cutImageBlob = self.convertBase64UrlToBlob(_dataUrl);
self.setState({
cutImageBlob,
dataUrl: _dataUrl,
rotate: this.rotate(),
scale: this.scale()
})
}
}, 500)
const cutImageBlob = self.convertBase64UrlToBlob(dataUrl);
self.setState({
cutImageBlob,
dataUrl
})
setTimeout(() => {
cutFlag = false;
}, 2000);
},
fail: (failInfo) => {
message.error("图片上传失败了,请重新上传");
},
loadComplete: function (img) {
setTimeout(() => {
const _dataUrl = this.clip()
self.setState({
dataUrl: _dataUrl,
hasImgReady: true
})
}, 100)
},
};
const imgUrl = `${imageFile.ossUrl}?${new Date().getTime()}`
if (!this.state.photoclip) {
const _photoclip = new PhotoClip("#headPicModal", options);
_photoclip.load(imgUrl);
this.setState({
photoclip: _photoclip,
});
} else {
this.state.photoclip.clear();
this.state.photoclip.load(imgUrl);
}
}, 200);
}
);
};
//获取resourceId //获取resourceId
getSignature = (blob, fileName) => { getSignature = (blob, fileName) => {
Upload.uploadBlobToOSS(blob, 'cover' + (new Date()).valueOf(),null,'signInfo').then((signInfo) => { Upload.uploadBlobToOSS(blob, 'cover' + (new Date()).valueOf(),null,'signInfo').then((signInfo) => {
...@@ -172,16 +100,6 @@ class StoreInfo extends React.Component { ...@@ -172,16 +100,6 @@ class StoreInfo extends React.Component {
logo:coverClicpPath logo:coverClicpPath
}) })
} }
// base64转换成blob
convertBase64UrlToBlob = (urlData) => {
const bytes = window.atob(urlData.split(",")[1]);
const ab = new ArrayBuffer(bytes.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], { type: "image/png" });
};
updateInfo=()=>{ updateInfo=()=>{
const {storeName,storeFullName,logo,subjectType,corpIndustry,corpSubIndustry} = this.state; const {storeName,storeFullName,logo,subjectType,corpIndustry,corpSubIndustry} = this.state;
if(!storeName){ if(!storeName){
...@@ -216,7 +134,7 @@ class StoreInfo extends React.Component { ...@@ -216,7 +134,7 @@ class StoreInfo extends React.Component {
}); });
} }
render() { render() {
const {storeName,storeFullName,subjectType,corpIndustry,corpSubIndustry,showSelectFileModal,visible,hasImgReady,logo,cutImageBlob } = this.state; const {storeName,storeFullName,subjectType,corpIndustry,corpSubIndustry,showSelectFileModal,visible,hasImgReady,logo,cutImageBlob,imageFile} = this.state;
return ( return (
<div className="page store-info-page"> <div className="page store-info-page">
<div className="content-header">学院基本信息</div> <div className="content-header">学院基本信息</div>
...@@ -330,65 +248,9 @@ class StoreInfo extends React.Component { ...@@ -330,65 +248,9 @@ class StoreInfo extends React.Component {
onSelect={this.handleSelectCover} onSelect={this.handleSelectCover}
/> />
} }
<Modal { visible &&
title="设置图片" <ImgClipModal visible={visible} imgUrl={imageFile.ossUrl} aspectRatio='125/32' cropBoxHeight='128' onConfirm={this.getSignature} onClose={()=>{this.setState({ visible: false });}}/>
width={1080} }
visible={visible}
maskClosable={false}
closeIcon={<span className="icon iconfont modal-close-icon">&#xe6ef;</span>}
onCancel={() => {
this.setState({ visible: false });
}}
zIndex={10001}
footer={[
<Button
key="back"
onClick={() => {
this.setState({ visible: false });
}}
>
重新上传
</Button>,
<Button
key="submit"
type="primary"
disabled={!hasImgReady}
onClick={() => {
if (!cutFlag) {
cutFlag = true;
this.refs.hiddenBtn.click();
}
this.getSignature(cutImageBlob);
}}
>
确定
</Button>,
]}
>
<div className="clip-box">
<div
id="headPicModal"
ref="headPicModal"
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="preview-url-box" style={{width:500,height:128}}>
<img src={this.state.dataUrl} style={{ width: '100%' }} alt="" />
</div>
<div className="tip-box">
<div className="tip">温馨提示</div>
<div className="tip">①预览效果图时可能存在延迟,单击左侧图片刷新即可</div>
<div className="tip">②设置图片时双击可旋转图片,滚动可放大或缩小图片</div>
</div>
</div>
</div>
</Modal>
<div><Button type="primary" onClick={this.updateInfo} htmlType="submit" className="submit-btn">更新信息</Button></div> <div><Button type="primary" onClick={this.updateInfo} htmlType="submit" className="submit-btn">更新信息</Button></div>
</div> </div>
......
/* /*
* @Author: wufan * @Author: wufan
* @Date: 2020-11-30 10:47:38 * @Date: 2020-11-30 10:47:38
* @LastEditors: wufan * @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-21 11:16:31 * @LastEditTime: 2021-07-08 19:35:27
* @Description: web学院banner页面 * @Description: web学院banner页面
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -25,6 +25,7 @@ import "./StoreDecorationPage.less"; ...@@ -25,6 +25,7 @@ import "./StoreDecorationPage.less";
import Upload from "@/core/upload"; import Upload from "@/core/upload";
import { XMTable } from '@/components'; import { XMTable } from '@/components';
import college from '@/common/lottie/college'; import college from '@/common/lottie/college';
import ImgClipModal from '@/components/ImgClipModal'
const { confirm } = Modal; const { confirm } = Modal;
const DragHandle = sortableHandle(() => ( const DragHandle = sortableHandle(() => (
...@@ -51,7 +52,8 @@ class StoreWebDecoration extends React.Component { ...@@ -51,7 +52,8 @@ class StoreWebDecoration extends React.Component {
photoclip: null, photoclip: null,
preview: "", preview: "",
cutImageBlob: null, cutImageBlob: null,
hasImgReady: false // 图片是否上传成功 hasImgReady: false,// 图片是否上传成功
imageFile: null // 需要被截取的图片
}; };
} }
...@@ -207,87 +209,14 @@ class StoreWebDecoration extends React.Component { ...@@ -207,87 +209,14 @@ class StoreWebDecoration extends React.Component {
// 选择云盘资源 // 选择云盘资源
handleSelectImg = (file) => { handleSelectImg = (file) => {
this.setState({ if(file){
showSelectFileModal: false, this.setState({
});
this.uploadImage(file);
};
//上传图片
uploadImage = (imageFile) => {
const self = this;
this.setState(
{
visible: true, visible: true,
}, imageFile:file
() => { });
setTimeout(() => { }
const okBtnDom = document.querySelector("#headPicModal");
const options = {
size: [500, 73],
ok: okBtnDom,
maxZoom: 3,
style: {
jpgFillColor: "transparent",
},
done: function (dataUrl) {
clearTimeout(self.timer);
self.timer = setTimeout(() => {
if ((self.state.rotate != this.rotate()) || (self.state.scale != this.scale())) {
console.log(this.scale(), 'scale')
const _dataUrl = this.clip()
const cutImageBlob = self.convertBase64UrlToBlob(_dataUrl);
self.setState({
cutImageBlob,
dataUrl: _dataUrl,
rotate: this.rotate(),
scale: this.scale()
})
}
}, 500)
const cutImageBlob = self.convertBase64UrlToBlob(dataUrl);
self.setState({
cutImageBlob,
dataUrl
})
setTimeout(() => {
cutFlag = false;
}, 2000);
},
fail: (failInfo) => {
message.error("图片上传失败了,请重新上传");
},
loadComplete: function (img) {
setTimeout(() => {
const _dataUrl = this.clip()
self.setState({
dataUrl: _dataUrl,
hasImgReady: true
})
}, 100)
},
};
const imgUrl = `${imageFile.ossUrl}?${new Date().getTime()}`
if (!this.state.photoclip) {
const _photoclip = new PhotoClip("#headPicModal", options);
_photoclip.load(imgUrl);
this.setState({
photoclip: _photoclip,
});
} else {
this.state.photoclip.clear();
this.state.photoclip.load(imgUrl);
}
}, 200);
}
);
}; };
//获取resourceId //获取resourceId
getSignature = (blob) => { getSignature = (blob) => {
Upload.uploadBlobToOSS(blob, "avatar" + new Date().valueOf()).then( Upload.uploadBlobToOSS(blob, "avatar" + new Date().valueOf()).then(
...@@ -342,16 +271,7 @@ class StoreWebDecoration extends React.Component { ...@@ -342,16 +271,7 @@ class StoreWebDecoration extends React.Component {
}); });
}; };
// base64转换成blob
convertBase64UrlToBlob = (urlData) => {
const bytes = window.atob(urlData.split(",")[1]);
const ab = new ArrayBuffer(bytes.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], { type: "image/png" });
};
render() { render() {
const { const {
...@@ -360,7 +280,8 @@ class StoreWebDecoration extends React.Component { ...@@ -360,7 +280,8 @@ class StoreWebDecoration extends React.Component {
diskList, diskList,
visible, visible,
cutImageBlob, cutImageBlob,
hasImgReady hasImgReady,
imageFile
} = this.state; } = this.state;
const DraggableContainer = (props) => ( const DraggableContainer = (props) => (
<SortableContainer <SortableContainer
...@@ -421,65 +342,9 @@ class StoreWebDecoration extends React.Component { ...@@ -421,65 +342,9 @@ class StoreWebDecoration extends React.Component {
}} }}
onSelect={this.handleSelectImg} onSelect={this.handleSelectImg}
/> />
<Modal { visible &&
title="设置图片" <ImgClipModal visible={visible} imgUrl={imageFile.ossUrl} aspectRatio='500/73' cropBoxHeight='73' onConfirm={this.getSignature} onClose={()=>{this.setState({ visible: false });}}/>
width={1080} }
visible={visible}
onCancel={() => {
this.setState({ visible: false });
}}
maskClosable={false}
closeIcon={<span className="icon iconfont modal-close-icon">&#xe6ef;</span>}
footer={[
<Button
key="back"
onClick={() => {
this.setState({ visible: false });
this.state.choosedBannerId ? this.handleReplaceDecoration(this.state.choosedBannerItem):this.handleToAddStoreDecoration();
}}
>
重新上传
</Button>,
<Button
key="submit"
type="primary"
disabled={!hasImgReady}
onClick={() => {
if (!cutFlag) {
cutFlag = true;
this.refs.hiddenBtn.click();
}
this.getSignature(cutImageBlob);
}}
>
确定
</Button>,
]}
>
<div className="clip-box">
<div
id="headPicModal"
ref="headPicModal"
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">
<img src={this.state.dataUrl} style={{ width: '100%' }} alt="" />
</div>
<div className="tip-box">
<div className="tip">温馨提示</div>
<div className="tip">①预览效果图时可能存在延迟,单击左侧图片刷新即可</div>
<div className="tip">②设置图片时双击可旋转图片,滚动可放大或缩小图片</div>
</div>
</div>
</div>
</Modal>
</div> </div>
); );
} }
......
...@@ -11,6 +11,8 @@ import { XMContext } from '@/store/context'; ...@@ -11,6 +11,8 @@ import { XMContext } from '@/store/context';
import ExamShareModal from './ExamShareModal'; import ExamShareModal from './ExamShareModal';
import DataAnalysic from './DataAnalysic'; import DataAnalysic from './DataAnalysic';
import PreviewModal from './PreviewModal'; import PreviewModal from './PreviewModal';
import college from '@/common/lottie/college.json';
import './index.less'; import './index.less';
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
const { Search } = Input; const { Search } = Input;
...@@ -134,11 +136,12 @@ function ExaminationManager(props: any) { ...@@ -134,11 +136,12 @@ function ExaminationManager(props: any) {
}, },
{ {
title: '创建时间', title: '创建时间',
width: 150,
dataIndex: 'examCreateTime', dataIndex: 'examCreateTime',
align: fixStr.right, align: fixStr.right,
sorter: true, sorter: true,
sortOrder: field === 'examCreateTime' ? order : sortStatus.type, sortOrder: field === 'examCreateTime' ? order : sortStatus.type,
render: (text: any, record: any) => <span>{moment(text).format('YYYY-MM-DD HH:mm')}</span>, render: (text: any, record: any) => <span style={{ whiteSpace: 'nowrap' }}>{moment(text).format('YYYY-MM-DD HH:mm')}</span>,
}, },
{ {
title: '操作', title: '操作',
...@@ -425,6 +428,7 @@ function ExaminationManager(props: any) { ...@@ -425,6 +428,7 @@ function ExaminationManager(props: any) {
pagination={false} pagination={false}
style={{ margin: '0px 0 16px' }} style={{ margin: '0px 0 16px' }}
renderEmpty={{ renderEmpty={{
image: college,
description: <span style={{ display: 'block', paddingBottom: 24 }}>暂无数据</span>, description: <span style={{ display: 'block', paddingBottom: 24 }}>暂无数据</span>,
}}></XMTable> }}></XMTable>
{total > 0 && ( {total > 0 && (
......
...@@ -31,6 +31,8 @@ import _ from "underscore"; ...@@ -31,6 +31,8 @@ import _ from "underscore";
import PaperPreviewModal from "../modal/PreviewPaperModal"; import PaperPreviewModal from "../modal/PreviewPaperModal";
import MoveModal from '../../modal/MoveModal'; import MoveModal from '../../modal/MoveModal';
import Bus from "@/core/bus"; import Bus from "@/core/bus";
import college from '@/common/lottie/college';
const { Search } = Input; const { Search } = Input;
...@@ -625,6 +627,7 @@ class PaperList extends Component { ...@@ -625,6 +627,7 @@ class PaperList extends Component {
bordered bordered
loading={loading} loading={loading}
renderEmpty={{ renderEmpty={{
image: college,
description: <span style={{ display: 'block', paddingBottom: 24 }}>还没有试卷</span> description: <span style={{ display: 'block', paddingBottom: 24 }}>还没有试卷</span>
}} }}
/> />
...@@ -641,6 +644,7 @@ class PaperList extends Component { ...@@ -641,6 +644,7 @@ class PaperList extends Component {
pagination={false} pagination={false}
bordered bordered
renderEmpty={{ renderEmpty={{
image: college,
description: <span style={{ display: 'block', paddingBottom: 24 }}>还没有试卷</span> description: <span style={{ display: 'block', paddingBottom: 24 }}>还没有试卷</span>
}} }}
/> />
......
...@@ -2,38 +2,38 @@ ...@@ -2,38 +2,38 @@
.select-box { .select-box {
display: flex; display: flex;
align-items: center; align-items: center;
.select-container{ .select-container {
margin-right: 24px; margin-right: 24px;
.con{ .con {
background: #E9EFFF; background: #e9efff;
border-radius: 4px; border-radius: 4px;
padding: 3px 16px; padding: 3px 16px;
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
.tip{ .tip {
font-size:14px; font-size: 14px;
color:#2966FF; color: #2966ff;
margin-right:8px; margin-right: 8px;
} }
.text{ .text {
font-size:14px; font-size: 14px;
color:#666; color: #666;
margin-right:30px; margin-right: 30px;
} }
.clear{ .clear {
color:#5289FA; color: #5289fa;
font-size:14px; font-size: 14px;
} }
} }
} }
} }
.ant-radio-wrapper{ .ant-radio-wrapper {
left: -10px; left: -10px;
} }
.paper-list-filter { .paper-list-filter {
position: relative; position: relative;
.search-condition { .search-condition {
width: calc(100% - 80px); width: calc(100% - 80px);
display: flex; display: flex;
...@@ -75,8 +75,10 @@ ...@@ -75,8 +75,10 @@
.paper-list-content { .paper-list-content {
position: relative; position: relative;
margin-top: 12px; margin-top: 12px;
height: calc(100vh - 260px);
overflow: scroll;
.empty-list-tip { .empty-list-tip {
color: #2966FF; color: #2966ff;
cursor: pointer; cursor: pointer;
} }
.record-name { .record-name {
...@@ -88,7 +90,7 @@ ...@@ -88,7 +90,7 @@
display: flex; display: flex;
&__item { &__item {
color: #2966FF; color: #2966ff;
cursor: pointer; cursor: pointer;
&.split { &.split {
...@@ -98,7 +100,7 @@ ...@@ -98,7 +100,7 @@
} }
} }
} }
&.modal-select{ &.modal-select {
.search-condition { .search-condition {
width: calc(100% - 80px); width: calc(100% - 80px);
display: flex; display: flex;
......
...@@ -25,6 +25,8 @@ import AidToolService from "@/domains/aid-tool-domain/AidToolService"; ...@@ -25,6 +25,8 @@ import AidToolService from "@/domains/aid-tool-domain/AidToolService";
import _ from "underscore"; import _ from "underscore";
import Bus from "@/core/bus"; import Bus from "@/core/bus";
import moment from 'moment'; import moment from 'moment';
import { XMTable } from '@/components';
import college from '@/common/lottie/college';
const { Search } = Input; const { Search } = Input;
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
...@@ -201,19 +203,6 @@ class SelectQuestionList extends Component { ...@@ -201,19 +203,6 @@ class SelectQuestionList extends Component {
return columns; return columns;
}; };
// 自定义表格空状态
customizeRenderEmpty = () => {
return (
<Empty
image="https://image.xiaomaiketang.com/xm/emptyTable.png"
imageStyle={{
height: 100,
}}
description={"还没有题目"}
></Empty>
);
};
onShowSizeChange = (current, size) => { onShowSizeChange = (current, size) => {
if (current == size) { if (current == size) {
return; return;
...@@ -431,8 +420,11 @@ class SelectQuestionList extends Component { ...@@ -431,8 +420,11 @@ class SelectQuestionList extends Component {
)} )}
</div> </div>
<div className="select-question-content"> <div className="select-question-content">
<ConfigProvider renderEmpty={this.customizeRenderEmpty}> <XMTable
<Table renderEmpty={{
image: college,
description: '还没有题目'
}}
rowSelection={rowSelection} rowSelection={rowSelection}
rowKey={(record) => record.id} rowKey={(record) => record.id}
dataSource={dataSource} dataSource={dataSource}
...@@ -441,7 +433,6 @@ class SelectQuestionList extends Component { ...@@ -441,7 +433,6 @@ class SelectQuestionList extends Component {
onChange={this.handleChangeTable} onChange={this.handleChangeTable}
bordered bordered
/> />
</ConfigProvider>
<div className="box-footer"> <div className="box-footer">
<PageControl <PageControl
current={current - 1} current={current - 1}
......
...@@ -7,7 +7,10 @@ ...@@ -7,7 +7,10 @@
.content { .content {
width: 100%; width: 100%;
margin-left: 24px; margin-left: 24px;
height: calc(100vh - 160px); .question-list-content {
height: calc(100vh - 260px);
overflow: scroll;
}
} }
} }
} }
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React, { Component } from 'react'; import React, { Component } from 'react';
import { Table, ConfigProvider, Empty, Row, Input, Select, Tooltip, Space, Button, Modal, message, Menu, Dropdown, DatePicker } from 'antd'; import { Row, Input, Select, Tooltip, Space, Button, Modal, message, Menu, Dropdown, DatePicker } from 'antd';
import _ from 'underscore'; import _ from 'underscore';
import { Route, withRouter } from 'react-router-dom'; import { Route, withRouter } from 'react-router-dom';
import { DownOutlined } from '@ant-design/icons'; import { DownOutlined } from '@ant-design/icons';
...@@ -21,6 +21,8 @@ import Bus from '@/core/bus'; ...@@ -21,6 +21,8 @@ import Bus from '@/core/bus';
import moment from 'moment'; import moment from 'moment';
import Service from '@/common/js/service'; import Service from '@/common/js/service';
import MoveModal from '../../modal/MoveModal'; import MoveModal from '../../modal/MoveModal';
import college from '@/common/lottie/college';
import './QuestionList.less'; import './QuestionList.less';
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
...@@ -671,6 +673,7 @@ class QuestionList extends Component { ...@@ -671,6 +673,7 @@ class QuestionList extends Component {
onChange={this.handleChangeTable} onChange={this.handleChangeTable}
rowSelection={rowSelection} rowSelection={rowSelection}
renderEmpty={{ renderEmpty={{
image: college,
description: ( description: (
<span style={{ display: 'block', paddingBottom: 24 }}> <span style={{ display: 'block', paddingBottom: 24 }}>
<span>还没有题目</span> <span>还没有题目</span>
......
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