index.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. import { Layout, Dropdown, Menu, Modal, Input, Form, Space, Button } from 'antd';
  2. import { withRouter } from 'react-router'
  3. import { useState, useEffect } from 'react';
  4. import { useSelector, useDispatch } from 'react-redux';
  5. import { RedoOutlined } from '@ant-design/icons';
  6. import MyMessage from "../MyMessage";
  7. import { panesNow } from '@reducers/tabPanes.js';
  8. import { getTimeDetail } from '@utils/index';
  9. import logo from '@images/logo.png';
  10. import msg from '@images/msg.png';
  11. import me from '@images/me.png';
  12. import down from '@images/down.png';
  13. import './index.less'
  14. import { message } from "antd/lib/index";
  15. import { add, active } from '@reducers/tabPanes'
  16. import { setUnReadNum, setRegularNum, setRulerNum, setProblemNum, setLossNum, setDiagNum, setDocNum, setDrugNum, setDutyNum, setSurgeryNum } from '@reducers/userInfo.js';
  17. import apiObj from '@api/index';
  18. const { post, api, xPost } = apiObj;
  19. const propTypes = {
  20. }
  21. const defaultProps = {};
  22. const { Header } = Layout;
  23. function AHeader({ history, hideName }) {
  24. const dispatch = useDispatch();//当前选中的菜单
  25. const { panes, activeTab } = useSelector(state => {
  26. return state.tabPanes;
  27. });
  28. const [form] = Form.useForm();
  29. const [dateTime, setDateTime] = useState('');
  30. const [visible, setVisible] = useState(false);
  31. //const [unReadNum,setUnReadNum] = useState(0);
  32. const [systemName, setSystemName] = useState("");
  33. //const [userName,setUserName] = useState("");
  34. const userName = localStorage.getItem("userName");
  35. const hospitalId = localStorage.getItem("hospitalId");
  36. const softwareArr = JSON.parse(localStorage.getItem("software"));
  37. const { user, unReadNum, regularNum, rulerNum, problemNum, lossNum, diagNum, docNum, drugNum, dutyNum, surgeryNum } = useSelector((state) => {
  38. return state.userInfo;
  39. });
  40. //退出
  41. function loginOut() {
  42. localStorage.removeItem("token");
  43. localStorage.removeItem("systemId");
  44. localStorage.removeItem("hospitalId");
  45. localStorage.removeItem("software")
  46. dispatch(panesNow([]));
  47. history.push('/login');
  48. }
  49. function getRefresh() {
  50. console.log(activeTab);
  51. let count
  52. if (activeTab.split('&')[0] == "SJZL-ZZSWH") {
  53. count = regularNum
  54. count++
  55. dispatch(setRegularNum(count));
  56. } else if (activeTab.split('&')[0] == "SJZL-ZDJYGZWH") {
  57. count = rulerNum
  58. count++
  59. dispatch(setRulerNum(count));
  60. } else if (activeTab.split('&')[0] == "SJZL-ZDJYWTMX") {
  61. count = problemNum
  62. count++
  63. dispatch(setProblemNum(count));
  64. } else if (activeTab.split('&')[0] == "SJZL-BLSJDSMX") {
  65. count = lossNum
  66. count++
  67. dispatch(setLossNum(count));
  68. } else if (activeTab.split('&')[0] == "JCSJ-ZDXXWH") {
  69. count = diagNum
  70. count++
  71. dispatch(setDiagNum(count));
  72. } else if (activeTab.split('&')[0] == "JCSJ-WSMBWH") {
  73. count = docNum
  74. count++
  75. dispatch(setDocNum(count));
  76. } else if (activeTab.split('&')[0] == "JCSJ-YPXXWH") {
  77. count = drugNum
  78. count++
  79. dispatch(setDrugNum(count));
  80. } else if (activeTab.split('&')[0] == "JCSJ-ZWZCBGJL") {
  81. count = dutyNum
  82. count++
  83. dispatch(setDutyNum(count));
  84. } else if (activeTab.split('&')[0] == "JCSJ-SSXXWH") {
  85. count = surgeryNum
  86. count++
  87. dispatch(setSurgeryNum(count));
  88. }
  89. }
  90. //获取未读消息数量
  91. function getNotNoticeCount() {
  92. xPost(api.getNotNoticeCount).then((res) => {
  93. if (res.data.code === 200) {
  94. const data = res.data.data || {};
  95. let count = data.count;
  96. count = count > 99 ? '99+' : count;
  97. dispatch(setUnReadNum(count));
  98. initWebsocket(count);
  99. } else {
  100. //message.warning(res.data.msg || '请求失败');
  101. }
  102. })
  103. }
  104. //未读消息页面显示并带入未读筛选条件
  105. function showMyMsgPage() {
  106. const pageKey = 'ZNTZ-WDTZ&我的通知';
  107. const item = panes.find((it) => it.key === pageKey);
  108. if (item) { //已存在当前tab,则定位即可不增加
  109. dispatch(active({ idName: pageKey, isUnRead: true }));
  110. return;
  111. }
  112. dispatch(
  113. add({ title: '我的通知', content: <MyMessage />, key: pageKey, isUnRead: true })
  114. )
  115. }
  116. async function initWebsocket(num) {
  117. const mqtt = require('mqtt');
  118. const client = mqtt.connect(api.websocketUrl);
  119. //const hisId = getCookie("hospitalId");
  120. client.on('connect', function () {
  121. client.subscribe(hospitalId + "-" + user.id, function (err) {
  122. if (!err) {
  123. console.log(hospitalId + "-" + user.id + "订阅成功")
  124. }
  125. })
  126. })
  127. client.on('message', function (topic, message) {
  128. let n = num > unReadNum ? num : unReadNum;
  129. setUnReadNum(+n)
  130. console.log('收到消息+1:', message.toString())
  131. })
  132. }
  133. //获取系统、用户名称用于页头显示
  134. function getSysName() {
  135. setSystemName(localStorage.getItem("systemName"));
  136. }
  137. /*function handleUserInfo(data){
  138. const { userInfo, software } = data;
  139. const sysId = getCookie("systemId");
  140. const hisId = getCookie("hospitalId");
  141. const sys = software.find((it) => {
  142. return +it.id === +sysId
  143. });
  144. dispatch(setUser(userInfo));
  145. sys && dispatch(setSys({ sysId, sysName: sys.name, hisId }));
  146. }
  147. //获取组织列表
  148. function getUserHos() {
  149. return new Promise((resolve)=>{
  150. xPost(api.getUserHospitals).then((res)=>{
  151. resolve(res);
  152. });
  153. });
  154. }*/
  155. //修改密码
  156. function changePsd() {
  157. setVisible(true)
  158. }
  159. //时间
  160. let interVal;
  161. function countTime() {
  162. interVal = setInterval(() => {
  163. setDateTime(getTimeDetail())
  164. }, 1000);
  165. }
  166. function cancel() {
  167. setVisible(false)
  168. form.resetFields();
  169. }
  170. const onFinish = values => {
  171. const params = values
  172. post(api.midifyPassword, params).then((res) => {
  173. if (res.data.code === 200) {
  174. message.success('修改成功');
  175. }
  176. })
  177. }
  178. useEffect(() => {
  179. getSysName();
  180. countTime();
  181. getNotNoticeCount();
  182. return function clearUp() {
  183. clearInterval(interVal)
  184. }
  185. }, ['unReadNum']);
  186. const menu = (
  187. <Menu>
  188. <Menu.Item key="0">
  189. <span className='changePsd' onClick={changePsd}>修改密码</span>
  190. </Menu.Item>
  191. <Menu.Divider />
  192. <Menu.Item key="3" onClick={loginOut}>退出</Menu.Item>
  193. </Menu>
  194. );
  195. return (
  196. <Header className='page-header'>
  197. <img className='logo' src={logo} alt="" />
  198. {hideName ? '' : <><span className='break-line'>|</span>
  199. <span className='sys-name'>{systemName}<span className='refresh' onClick={getRefresh}><RedoOutlined /></span></span></>}
  200. <div className='infos'>
  201. <span className='time'>{dateTime}</span>
  202. <span className='break-line'>|</span>
  203. <div className="unRead-msg-cont" onClick={showMyMsgPage}>
  204. <img className='msg-icon' src={msg} alt="未读消息" />
  205. {unReadNum ? <span className='unRead-msg'>{unReadNum}</span> : ''}
  206. </div>
  207. <div className="user">
  208. <Dropdown overlay={menu} trigger={['click']}>
  209. <span className="ant-dropdown-link" onClick={e => e.preventDefault()}>
  210. <img className='user-icon' src={me} alt="用户头像" />
  211. <i className='user-name'>{userName}</i>
  212. <img src={down} alt="" />
  213. </span>
  214. </Dropdown>
  215. </div>
  216. </div>
  217. {visible ?
  218. <Modal
  219. title='修改密码'
  220. okText='确定'
  221. cancelText='取消'
  222. width={'40%'}
  223. visible={visible}
  224. onCancel={cancel}
  225. footer={null}
  226. forceRender={true}
  227. centered={true}
  228. maskClosable={false}
  229. >
  230. <Form
  231. labelCol={{ span: 6 }}
  232. wrapperCol={{ span: 16 }}
  233. form={form}
  234. name="register"
  235. onFinish={onFinish}
  236. >
  237. <Form.Item
  238. name="password"
  239. label="原密码"
  240. required
  241. >
  242. <Input.Password placeholder="8-12位大小写字母、数字、特殊字符" />
  243. </Form.Item>
  244. <Form.Item
  245. name="modifyPassword"
  246. label="新密码"
  247. dependencies={['password']}
  248. rules={[
  249. {
  250. required: true,
  251. message: '8-12位大小写字母、数字、特殊字符',
  252. },
  253. ({ getFieldValue }) => ({
  254. validator(_, value) {
  255. const passwordReg = /^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\d)(?=.*?[#@*&.]).*$/;
  256. if (!value || getFieldValue('password') === value) {
  257. return Promise.reject(new Error('新密码不能于原密码相同'));
  258. }
  259. if (!passwordReg.test(value)) {
  260. return Promise.reject(new Error('密码必须同时包含大写字母、小写字母和数字'));
  261. }
  262. if (value.length < 8 || value.length > 12) {
  263. return Promise.reject(new Error('密码长度8-12位'));
  264. }
  265. },
  266. }),
  267. ]}
  268. >
  269. <Input.Password placeholder="8-12位大小写字母、数字、特殊字符" />
  270. </Form.Item>
  271. <Form.Item
  272. name="againnewpassword"
  273. label="确认新密码"
  274. dependencies={['password']}
  275. rules={[
  276. {
  277. required: true,
  278. message: '8-12位大小写字母、数字、特殊字符',
  279. },
  280. ({ getFieldValue }) => ({
  281. validator(_, value) {
  282. if (!value || getFieldValue('modifyPassword') === value) {
  283. return Promise.resolve();
  284. }
  285. return Promise.reject(new Error('两次密码不一致,请确认密码'));
  286. },
  287. }),
  288. ]}
  289. >
  290. <Input.Password placeholder="8-12位大小写字母、数字、特殊字符" />
  291. </Form.Item>
  292. <Form.Item wrapperCol={{ offset: 8, span: 16 }}>
  293. <Space size="middle">
  294. <Button htmlType="button" onClick={e => cancel()}>
  295. 取消
  296. </Button>
  297. <Button type="primary" htmlType="submit">
  298. 保存
  299. </Button>
  300. </Space>
  301. </Form.Item>
  302. </Form>
  303. </Modal>
  304. : ''}
  305. </Header>
  306. )
  307. }
  308. AHeader.propTypes = propTypes;
  309. AHeader.defaultProps = defaultProps;
  310. export default withRouter(AHeader);