138 lines
4.1 KiB
JavaScript
138 lines
4.1 KiB
JavaScript
import React, {useRef, useEffect, useCallback, useLayoutEffect} from 'react';
|
|
import _ from 'lodash'
|
|
import {imgUrl as url} from '../../../utils/requests'
|
|
|
|
let defaultUrl = "/img/noImg.png";
|
|
|
|
const fetchImg = fileCode => {
|
|
// console.log("fetchImg")
|
|
return new Promise((resolve, reject) => {
|
|
let ajax = new XMLHttpRequest();
|
|
ajax.open("GET", `${url}${fileCode}`, true);
|
|
ajax.responseType = "blob";
|
|
ajax.setRequestHeader("Cache-Control", "max-age=3600")
|
|
ajax.setRequestHeader("Authorization", window.localStorage.getItem("token"))
|
|
ajax.onload = function () {
|
|
if (ajax.status == 200) {
|
|
ajax.response.text().then(res => {
|
|
// console.log("res", JSON.parse(res))
|
|
try{
|
|
res = JSON.parse(res);
|
|
}catch(e){
|
|
console.log(e)
|
|
}
|
|
if (res.error) {
|
|
resolve(defaultUrl)
|
|
} else {
|
|
let blob = ajax.response;
|
|
let oFileReader = new FileReader();
|
|
oFileReader.onloadend = function (e) {
|
|
console.log("e", e)
|
|
let base64 = e.target.result;
|
|
resolve(base64)
|
|
};
|
|
oFileReader.readAsDataURL(blob);
|
|
}
|
|
})
|
|
}
|
|
}
|
|
ajax.send();
|
|
})
|
|
}
|
|
|
|
function InfoCard(props) {
|
|
const imgBox = useRef();
|
|
const {imgKey, status = {}, columns = [],extraColumns = [], data = {}, cardWidth = 256, contentHeight} = props;
|
|
const {key = '', value, color} = status;
|
|
|
|
const setImg = useCallback(async () => {
|
|
let url = defaultUrl;
|
|
if (imgKey && data[imgKey]) {
|
|
url = await fetchImg(data[imgKey]);
|
|
}
|
|
imgBox.current && (imgBox.current.style.backgroundImage = `url('${url}')`)
|
|
}, [data[imgKey]])
|
|
|
|
useLayoutEffect(() => {
|
|
let observer = new IntersectionObserver((entries, observer) => {
|
|
if(entries[0].intersectionRatio > 0) setImg();
|
|
}, {});
|
|
observer && observer.observe(imgBox.current);
|
|
return () => {
|
|
observer && observer.unobserve(imgBox.current);
|
|
}
|
|
}, [setImg])
|
|
|
|
return (
|
|
<div className='infoCard'>
|
|
<div className="img" ref={imgBox}/>
|
|
{data[key] && (
|
|
<div className="status" style={{backgroundColor: color? color(data[key]) : "unset" }}>
|
|
{value? value(data[key]) : data[key]}
|
|
</div>
|
|
)}
|
|
<div className="contentBox">
|
|
{columns.concat(extraColumns).map(({title, code, text}) => {
|
|
return (
|
|
<div key={title} className="info-item">
|
|
<span className='label'>{title}</span>
|
|
<span className='value'>{text || data[code]}</span>
|
|
</div>
|
|
)
|
|
})}
|
|
</div>
|
|
<style jsx>{`
|
|
.infoCard{
|
|
height: 100%;
|
|
width: ${cardWidth? cardWidth + 'px' : '100%'};
|
|
min-width: ${cardWidth? cardWidth + 'px' : '100%'};
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
.infoCard > .img{
|
|
background-size: cover;
|
|
background-position: center center;
|
|
background-repeat: no-repeat;
|
|
background-color: rgba(0,0,0,0.2);
|
|
flex: 1;
|
|
}
|
|
.infoCard > .status{
|
|
position: absolute;
|
|
top:0;
|
|
left:0;
|
|
font-size: 16px;
|
|
color: #FFFFFF;
|
|
font-weight: 600;
|
|
line-height: 28px;
|
|
padding: 0 8px;
|
|
}
|
|
.infoCard > .contentBox{
|
|
background: rgba(6,45,141,0.80);
|
|
border: 1px solid rgba(255,255,255,0.16);
|
|
padding: 5px 10px;
|
|
height: ${contentHeight? contentHeight + 'px' : 'unset'};
|
|
}
|
|
.infoCard .info-item{
|
|
display: flex;
|
|
justify-content: space-between;
|
|
line-height: 28px;
|
|
font-size: 12px;
|
|
white-space: nowrap;
|
|
}
|
|
.infoCard .info-item .label,
|
|
.infoCard .info-item .value{
|
|
text-overflow: ellipsis;
|
|
overflow: hidden;
|
|
}
|
|
.infoCard .info-item .value{
|
|
font-size: 14px;
|
|
color: #28EAFF;
|
|
font-weight: 500;
|
|
}
|
|
`}</style>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default InfoCard; |