182 lines
4.6 KiB
JavaScript
182 lines
4.6 KiB
JavaScript
|
|
import { Button, Checkbox, makeStyles, Snackbar, TextField } from '@material-ui/core';
|
|||
|
|
import { Person } from '@material-ui/icons';
|
|||
|
|
import React, { useEffect, useMemo, useState } from 'react';
|
|||
|
|
import appconsts from '../../../../models/appconsts';
|
|||
|
|
import { sendsmtp } from '../../../../models/_/base';
|
|||
|
|
import { personelByAdcdExact } from '../../../../models/_/personel';
|
|||
|
|
import { HDGet } from '../../../../models/_/real';
|
|||
|
|
import DpAlert from '../../../../layouts/mui/DpAlert';
|
|||
|
|
|
|||
|
|
|
|||
|
|
const useStyle = makeStyles({
|
|||
|
|
root: {
|
|||
|
|
display: 'flex',
|
|||
|
|
height: '100%',
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
leftSide: {
|
|||
|
|
width: '50%',
|
|||
|
|
overflow: 'auto',
|
|||
|
|
padding: '0.5rem',
|
|||
|
|
marginRight: '1rem'
|
|||
|
|
},
|
|||
|
|
rightSide: {
|
|||
|
|
padding: '0.5rem',
|
|||
|
|
flexGrow: 1,
|
|||
|
|
},
|
|||
|
|
span: {
|
|||
|
|
padding: '0.5rem',
|
|||
|
|
},
|
|||
|
|
itemRoot: {
|
|||
|
|
display: 'flex',
|
|||
|
|
alignItems: 'center',
|
|||
|
|
borderBottom: '1px dashed #bce9f088',
|
|||
|
|
//marginBottom: '0.5rem',
|
|||
|
|
padding: '0.5rem 0'
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
icon: {
|
|||
|
|
marginRight: '1rem',
|
|||
|
|
},
|
|||
|
|
body: {
|
|||
|
|
flexGrow: 1,
|
|||
|
|
},
|
|||
|
|
action: {
|
|||
|
|
flexShrink: 0,
|
|||
|
|
},
|
|||
|
|
phone: {
|
|||
|
|
color: '#ccc',
|
|||
|
|
margin: '0 0.5rem',
|
|||
|
|
},
|
|||
|
|
desc: {
|
|||
|
|
color: '#aaa',
|
|||
|
|
fontSize: '0.8rem',
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
function Personel({ classes, data, onSelectChange, selected }) {
|
|||
|
|
return (
|
|||
|
|
<div className={classes.itemRoot}>
|
|||
|
|
<div className={classes.icon}>
|
|||
|
|
<Person />
|
|||
|
|
</div>
|
|||
|
|
<div className={classes.body}>
|
|||
|
|
<div>{data.name}<span className={classes.phone}>{data.phone}</span></div>
|
|||
|
|
<div className={classes.desc}>{`${data.department || ''}, ${data.position || ''}`}</div>
|
|||
|
|
</div>
|
|||
|
|
<div className={classes.action}>
|
|||
|
|
<Checkbox color="primary" checked={selected} onChange={(e, v) => onSelectChange(data, v)} />
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function SmtpPanel({ record }) {
|
|||
|
|
const classes = useStyle();
|
|||
|
|
|
|||
|
|
const [personels, setPersonels] = useState([]);
|
|||
|
|
const [selected, setSelected] = useState({});
|
|||
|
|
const [loading, setLoading] = useState(false);
|
|||
|
|
const [content, setContent] = useState(() => {
|
|||
|
|
const rz = record.rz;
|
|||
|
|
const brz = record[appconsts.stWarnLevelKey[record.level]];
|
|||
|
|
const arz = brz ? (rz - brz).toFixed(2) : '-';
|
|||
|
|
|
|||
|
|
return `报警水位${rz}m,测站${appconsts.stWarnLevel[record.level]}为${brz || '-'}m,超${arz || '-'}m`
|
|||
|
|
});
|
|||
|
|
const [msg, setMsg] = useState(null);
|
|||
|
|
|
|||
|
|
useEffect(() => {
|
|||
|
|
const fetchData = async () => {
|
|||
|
|
const st = await HDGet(record?.stcd);
|
|||
|
|
if (st?.adcd?.length >= 9) {
|
|||
|
|
const zhenAd = st.adcd.substr(0, 9);
|
|||
|
|
const data = await personelByAdcdExact(zhenAd);
|
|||
|
|
|
|||
|
|
setPersonels(data || []);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
fetchData();
|
|||
|
|
}, [record]);
|
|||
|
|
|
|||
|
|
const onSelectChange = (data, v) => {
|
|||
|
|
setSelected({
|
|||
|
|
...selected,
|
|||
|
|
[data.id]: v,
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const filterdata = useMemo(() => {
|
|||
|
|
return personels.filter(o => selected[o.id])
|
|||
|
|
}, [selected, personels]);
|
|||
|
|
|
|||
|
|
const selectAll = () => {
|
|||
|
|
const a = {};
|
|||
|
|
personels.forEach(p => a[p.id] = true);
|
|||
|
|
setSelected(a);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const doSend = async () => {
|
|||
|
|
if (loading) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const phones = filterdata.map(o => o.phone);
|
|||
|
|
setLoading(true);
|
|||
|
|
sendsmtp(phones, content).then((result) => {
|
|||
|
|
if (result) {
|
|||
|
|
setMsg({ type: 'success', msg: '短信已发送' });
|
|||
|
|
setSelected({})
|
|||
|
|
} else {
|
|||
|
|
setMsg({ type: 'error', msg: '发送失败' });
|
|||
|
|
}
|
|||
|
|
setLoading(false);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div className={classes.root}>
|
|||
|
|
|
|||
|
|
<div className={classes.leftSide}>
|
|||
|
|
{
|
|||
|
|
personels.map(o => (
|
|||
|
|
<Personel key={o.id} data={o} selected={!!selected[o.id]} classes={classes} onSelectChange={onSelectChange} />
|
|||
|
|
))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div className={classes.rightSide}>
|
|||
|
|
<TextField
|
|||
|
|
fullWidth
|
|||
|
|
label="短信内容"
|
|||
|
|
multiline
|
|||
|
|
rows={8}
|
|||
|
|
defaultValue={content}
|
|||
|
|
variant="outlined"
|
|||
|
|
onChange={(e) => setContent(e.target.value)}
|
|||
|
|
/>
|
|||
|
|
|
|||
|
|
<div className={classes.span}></div>
|
|||
|
|
|
|||
|
|
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
|||
|
|
<Button disabled={filterdata?.length === personels.length} onClick={selectAll}>全选</Button>
|
|||
|
|
<Button variant="outlined" color="primary" disabled={!content?.length || !filterdata?.length || loading} onClick={doSend}>发送</Button>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<Snackbar open={!!msg} autoHideDuration={6000} onClose={() => setMsg(null)}>
|
|||
|
|
{
|
|||
|
|
msg && (
|
|||
|
|
<DpAlert onClose={() => setMsg(null)} severity={msg?.type}>
|
|||
|
|
{msg?.msg}
|
|||
|
|
</DpAlert>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
</Snackbar>
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export default SmtpPanel
|