Sfoglia il codice sorgente

Merge remote-tracking branch 'origin/dev/byll' into dev/new1

# Conflicts:
#	src/common/components/EditableSpan/index.jsx
#	src/components/CheckBody/index.jsx
#	src/containers/eleType.js
zhouna 6 anni fa
parent
commit
b901e9ed95

+ 21 - 9
src/common/components/DropList/index.jsx

@@ -1,5 +1,6 @@
 import React,{Component} from 'react';
 import classNames from 'classnames';
+import ReactDom from "react-dom";
 
 import style from "./index.less";
 /****
@@ -23,6 +24,14 @@ class DropList extends Component{
     let isHide = this.props.show?'':style['hide'];
     return classNames(style['list'],name,isHide);
   }
+  
+  getStyle(){
+    const {left,top} = this.props;
+    return {
+      left:left?left+'px':'',
+      top:top?top+'px':''
+    }
+  }
   handleSelect(e,item){
     e.stopPropagation();
     const {onSelect} = this.props;
@@ -35,15 +44,18 @@ class DropList extends Component{
   }
   render(){
     const {data} = this.props;
-    return <div className={this.getClass()} contentEditable='false'>
-      <ul>
-        {data&&data.map((it)=>{
-          /*return <li onClick={(e)=>this.handleSelect(e,it)} className={it.selected||(it.selected!==false&&+it.defaultSelect===1)?style['selected']:''}>{it.labelPrefix}{it.questionDetailList&&it.questionDetailList.length>0?it.questionDetailList[0].name:it.name}{it.labelSuffix}</li>*/
-          return <li onClick={(e)=>this.handleSelect(e,it)} className={it.selected||(it.selected!==false&&+it.defaultSelect===1)?style['selected']:''}>{it.labelPrefix}{it.name}{it.labelSuffix}</li>
-        })}
-        <li onClick={(e)=>this.handleClear(e)} className='red'>清空选项</li>
-      </ul>
-    </div>
+    const domNode = document.getElementById('root');
+    return ReactDom.createPortal(
+      <div className={this.getClass()} style={this.getStyle()} contentEditable='false'>
+        <ul>
+          {data&&data.map((it)=>{
+            /*return <li onClick={(e)=>this.handleSelect(e,it)} className={it.selected||(it.selected!==false&&+it.defaultSelect===1)?style['selected']:''}>{it.labelPrefix}{it.questionDetailList&&it.questionDetailList.length>0?it.questionDetailList[0].name:it.name}{it.labelSuffix}</li>*/
+            return <li onClick={(e)=>this.handleSelect(e,it)} className={it.selected||(it.selected!==false&&+it.defaultSelect===1)?style['selected']:''}>{it.labelPrefix}{it.name}{it.labelSuffix}</li>
+          })}
+          <li onClick={(e)=>this.handleClear(e)} className='red'>清空选项</li>
+        </ul>
+      </div>
+    ,domNode)
   }
 }
 

+ 1 - 1
src/common/components/EditableSpan/index.jsx

@@ -1,7 +1,7 @@
 import React,{Component} from 'react';
 import style from './index.less';
 import config from "@config/index";
-import {filterArr,isIE} from '@utils/tools.js';
+import {filterArr,isIE,getPageCoordinate} from '@utils/tools.js';
 import Notify from '../Notify/index.js';
 import classNames from 'classnames';
 

+ 44 - 32
src/common/components/NumberPan/index.jsx

@@ -1,5 +1,6 @@
 import React,{Component} from 'react';
 import style from './index.less';
+import ReactDom from "react-dom";
 
 class NumberPan extends Component{
   constructor(props){
@@ -46,39 +47,50 @@ class NumberPan extends Component{
     });
     onSelect&&onSelect(text);
   }
-  render(){
-    const select = this.handleSelect.bind(this);
-    const {show} = this.props;      //table onBlur阻止冒泡是为了修复multSpread中数字键盘点击触发最外层数字组件onBlur事件
-    return <div className={style['panBox']}
-                onBlur={(e)=>e.stopPropagation()} style={{display:show?'table':'none'}}
+  getStyle(){
+    const {left,top,show} = this.props;
+    return {
+      left:left?left+'px':'0',
+      top:top?top+'px':'0',
+      display:show?'table':'none'        //table onBlur阻止冒泡是为了修复multSpread中数字键盘点击触发最外层数字组件onBlur事件
+    }
+  }
+  render(){  
+    const select = this.handleSelect.bind(this); 
+    const domNode = document.getElementById('root');
+    return ReactDom.createPortal(
+       <div className={style['panBox']} 
+                style={this.getStyle()}
+                onBlur={(e)=>e.stopPropagation()} 
                 onDoubleClick={(e)=>e.stopPropagation()}>
-    <table className={style['pan']} >
-      <tr>
-        <td><button onClick={select}>1</button></td>
-        <td><button onClick={select}>2</button></td>
-        <td><button onClick={select}>3</button></td>
-        <td><button onClick={select}>/</button></td>
-      </tr>
-      <tr>
-        <td><button onClick={select}>4</button></td>
-        <td><button onClick={select}>5</button></td>
-        <td><button onClick={select}>6</button></td>
-        <td><button onClick={this.handleBack.bind(this)}>回退</button></td>
-      </tr>
-      <tr>
-        <td><button onClick={select}>7</button></td>
-        <td><button onClick={select}>8</button></td>
-        <td><button onClick={select}>9</button></td>
-        <td><button onClick={this.handleClear.bind(this)}>清空</button></td>
-      </tr>
-      <tr>
-        <td><button onClick={select}>.</button></td>
-        <td><button onClick={select}>0</button></td>
-        <td><button onClick={select}>~</button></td>
-        <td><button onClick={this.handleClose.bind(this)}>确定</button></td>
-      </tr>
-    </table>
-    </div>
+      <table className={style['pan']} >
+        <tr>
+          <td><button onClick={select}>1</button></td>
+          <td><button onClick={select}>2</button></td>
+          <td><button onClick={select}>3</button></td>
+          <td><button onClick={select}>/</button></td>
+        </tr>
+        <tr>
+          <td><button onClick={select}>4</button></td>
+          <td><button onClick={select}>5</button></td>
+          <td><button onClick={select}>6</button></td>
+          <td><button onClick={this.handleBack.bind(this)}>回退</button></td>
+        </tr>
+        <tr>
+          <td><button onClick={select}>7</button></td>
+          <td><button onClick={select}>8</button></td>
+          <td><button onClick={select}>9</button></td>
+          <td><button onClick={this.handleClear.bind(this)}>清空</button></td>
+        </tr>
+        <tr>
+          <td><button onClick={select}>.</button></td>
+          <td><button onClick={select}>0</button></td>
+          <td><button onClick={select}>~</button></td>
+          <td><button onClick={this.handleClose.bind(this)}>确定</button></td>
+        </tr>
+      </table>
+      </div>
+    ,domNode)
   }
 }
 

+ 1 - 0
src/common/components/NumberPan/index.less

@@ -1,6 +1,7 @@
 @import "~@less/variables.less";
 .panBox{
   .pop;
+  display: table;
 }
 .pan{
   width: 280px;

+ 2 - 1
src/common/components/SearchOption/index.jsx

@@ -57,7 +57,8 @@ class SearchOption extends React.Component {
               show:true
           })
       }else{
-          this.handleClearVal('')            //这个要放开,输入为空清除列表
+          // this.handleClearVal('')            //这个要放开,输入为空清除列表ie8会有问题
+          handleChangeValue('');
           this.setState({
               show:false
           })

+ 4 - 0
src/common/js/func.js

@@ -172,6 +172,10 @@ export const getWindowInnerHeight = ()=>{
     return Math.min(by.clientHeight,ele.clientHeight);
   }
 };
+export const getWindowInnerWidth = ()=>{
+  let width = window.innerWidth || document.body.clientWidth || document.documentElement.clientWidth 
+  return width
+};
 
 export const getIds = (data)=>{
   let ids = [];

+ 1 - 1
src/common/less/variables.less

@@ -54,7 +54,7 @@
 .pop{
   position: absolute;
   // top:40px;
-  top:30px;
+  // top:30px;
   background: #fff;
   box-shadow: 0 10px 20px 0 #989DA3;
   // filter:progid:DXImageTransform.Microsoft.Shadow(color='#989DA3',Direction=125,Strength=6);

+ 1 - 1
src/components/BodyContainer/index.jsx

@@ -15,8 +15,8 @@ class BodyContainer extends Component {
         const { saveDateAll } = this.props;
         //console.log(saveDateAll)
         return <div className={style['container'] + ' clearfix'}>
-            <PushContainer></PushContainer>
             <SaveDataAll saveDateAll={saveDateAll}></SaveDataAll>
+            <PushContainer></PushContainer>
         </div>;
     }
 }

+ 22 - 9
src/components/CheckBody/index.jsx

@@ -3,14 +3,18 @@ import style from './index.less';
 import {Button,InlineTag,ItemBox,EditableSpan,Notify} from '@commonComp';
 import chooseType from '@containers/eleType.js';
 import SearchDrop from '@components/SearchDrop';
+import {getPageCoordinate,windowEventHandler} from '@utils/tools';
+import $ from "jquery";
 
 class CheckBody extends Component{
   constructor(props){
     super(props);
     this.state={
       boxMark:'4',
-      boxLeft:'0px',
-      boxTop:'0px'
+      boxLeft:0,
+      boxTop:0,
+      tmpScroll:0,
+      tmpTop:0,
     };
     this.handleClick = this.handleClick.bind(this);
     this.handleSearchSelect = this.handleSearchSelect.bind(this);
@@ -27,11 +31,10 @@ class CheckBody extends Component{
         return chooseType({item:it,boxMark,i,showArr,saveText,selecteds});
       });
     }
-
     return arr;
   }
   handleClick(e){//让搜索框跟随鼠标点击移动
-    //e.stopPropagation();
+    e.stopPropagation();
     const {fetchPushInfos,totalHide} = this.props;
     //fetchPushInfos&&fetchPushInfos();
     this.getData();
@@ -40,13 +43,23 @@ class CheckBody extends Component{
     }
     //若使用e.target,因为是onClick事件中,值可能是itembox的而不是span因此会有bug
     const ele = document.activeElement;
-    const height = ele.offsetHeight;
-    let boxTop = (+(ele.offsetTop)+height)+'px';
-    let boxLeft = ele.offsetLeft + 'px';
+    if(ele.toString().indexOf('HTMLSpanElement') == -1){     //点击的不是span无法聚焦就不再设置位置
+      return;
+    }
+    const leftL = ele.offsetLeft;      //用焦点元素的左边距替换鼠标点击的左边距,高度还是鼠标点击的位置
     this.setState({
-      boxLeft:boxLeft,
-      boxTop:boxTop
+      // boxLeft:getPageCoordinate(e).boxLeft,
+      boxLeft:leftL+90,
+      boxTop:getPageCoordinate(e).boxTop,
+      tmpScroll: $("#addScrollEvent")[0].scrollTop,
+      tmpTop:getPageCoordinate(e).boxTop
     });
+    windowEventHandler('scroll',()=>{      //弹窗跟随滚动条滚动或者关闭弹窗
+      let scrollYs = $("#addScrollEvent")[0].scrollTop;
+      this.setState({
+        boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
+      })
+    },$("#addScrollEvent")[0])
   }
   handleSearchSelect(obj){
    const {questionId,name} = obj;

+ 26 - 12
src/components/CurrentIll/index.jsx

@@ -4,7 +4,8 @@ import {Button,InlineTag,ItemBox,Notify,Textarea} from '@commonComp';
 import TailInlineTag from '@commonComp/TailInlineTag';
 import chooseType from '@containers/eleType.js';
 import SearchDrop from '@components/SearchDrop';
-import {filterDataArr} from '@utils/tools'
+import {filterDataArr,getPageCoordinate,windowEventHandler} from '@utils/tools'
+import $ from 'jquery';
 
 class CurrentIll extends Component{
   constructor(props){
@@ -16,9 +17,11 @@ class CurrentIll extends Component{
       mainFlag:true,
       mainData:[],
       boxMark:"2",
-      boxLeft:null,
-      boxTop:null,
-      show:true
+      boxLeft:0,
+      boxTop:0,
+      show:true,
+      tmpScroll:0,
+      tmpTop:0,
     }
     this.toggleEditable = this.toggleEditable.bind(this);
     this.handleFocus = this.handleFocus.bind(this);
@@ -56,7 +59,7 @@ class CurrentIll extends Component{
           showMoudle:true,
           forbidInput:false,
           boxEditable:false,
-        })
+      })
       changeEditIll(false)
       /*const showTimer = setTimeout(function(){
         that.setState({
@@ -80,13 +83,23 @@ class CurrentIll extends Component{
     // e.stopPropagation(); //冒泡到最顶层关闭其他下拉
     //若使用e.target,因为是onClick事件中,值可能是itembox的而不是span因此会有bug
     const ele = document.activeElement;
-    const height = ele.offsetHeight;
-    let boxTop = (+(ele.offsetTop)+height)+'px';
-    let boxLeft = +ele.offsetLeft+90 + 'px';
+    if(ele.toString().indexOf('HTMLSpanElement') == -1){     //点击的不是span无法聚焦就不再设置位置
+      return;
+    }
+    const leftL = ele.offsetLeft;      //用焦点元素的左边距替换鼠标点击的左边距,高度还是鼠标点击的位置
     this.setState({
-      boxLeft:boxLeft,
-      boxTop:boxTop
-    })
+      // boxLeft:getPageCoordinate(e).boxLeft,
+      boxLeft:leftL+90,
+      boxTop:getPageCoordinate(e).boxTop,
+      tmpScroll: $("#addScrollEvent")[0].scrollTop,
+      tmpTop:getPageCoordinate(e).boxTop
+    });
+    windowEventHandler('scroll',()=>{      //弹窗跟随滚动条滚动或者关闭弹窗
+      let scrollYs = $("#addScrollEvent")[0].scrollTop;
+      this.setState({
+        boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
+      })
+    },$("#addScrollEvent")[0])
   }
 
   handleSearchSelect(obj){
@@ -112,7 +125,8 @@ class CurrentIll extends Component{
   render(){
     const {fuzhen,type,fetchPushInfos,handleInput,isRead,saveText,searchData,totalHide,showArr,focusIndex,editClear,data} = this.props;
     const {showMoudle,forbidInput,boxMark,boxLeft,boxTop,show} = this.state;
-    const searchFlag = searchData.length>0 ? true : false;
+    const searchFlag = searchData.length > 0 ? true : false;
+
     if(+type===1){      //文本模式
       return <Textarea  title='现病史' boxMark='2'
                         isRead={isRead}

+ 15 - 15
src/components/EMRContainer/index.jsx

@@ -11,7 +11,8 @@ import OperationContainer from '../../containers/OperationContainer'
 import style from './index.less';
 import AdviceContainer from '../../containers/AdviceContainer';
 import InfoTitle from '@components/InfoTitle'
-import {getWindowInnerHeight} from '@common/js/func';
+import {windowEventHandler} from '@utils/tools'
+import {getWindowInnerHeight,getWindowInnerWidth} from '@common/js/func';
 
 class EMRContainer extends Component {
     constructor(props){
@@ -21,22 +22,21 @@ class EMRContainer extends Component {
     componentDidMount(){
         // const {initHospital} = this.props;
         // initHospital()
-        // const height = getWindowInnerHeight()-115;
-        // this.$cont.current.style.height = height+"px";
-        // const {initHistoryLastest} = this.props;
-        // let timer = setInterval(()=>{
-        //     let baseDate = store.getState().patInfo.message;
-        //     if(JSON.stringify(baseDate) != '{}') {
-        //         initHistoryLastest();
-        //         clearInterval(timer)
-        //     }
-        // },500)
-
+        const height = getWindowInnerHeight() - 115;
+        const width = getWindowInnerWidth() - 480;
+        this.$cont.current.style.height = height+"px";
+        this.$cont.current.style.width = width + "px";
+        windowEventHandler('resize', ()=>{
+          const height = getWindowInnerHeight() - 115;
+          const width = getWindowInnerWidth() - 480;
+          this.$cont.current.style.height = height + "px";
+          this.$cont.current.style.width = width + "px";
+        });
     }
     render() {
-        return <div className={style['EMR-container']}>
-            <div className={style['inner']} ref={this.$cont}>
-                <InfoTitle></InfoTitle>
+        return <div className={style['EMR-container']} ref={this.$cont} id="addScrollEvent">
+            <InfoTitle></InfoTitle>
+            <div className={style['inner']}>
                 <MainSuit></MainSuit>
                 <CurrentIll></CurrentIll>
                 <OtherHistory></OtherHistory>

+ 5 - 3
src/components/EMRContainer/index.less

@@ -2,14 +2,16 @@
 .EMR-container{
   background: #fff;
 //   margin-top: 10px;
-  margin-right:@push-width + 10px;
+  // margin-right:@push-width + 10px;
   padding: 0px 0 10px 0 ;
   box-sizing: border-box;
-  position: relative;
+  position: absolute;
   min-width: 700px;
+  float: left;
+  overflow-y:auto;
+  overflow-x: hidden;
 }
 .inner{
-//   overflow-y: auto;
   padding-top:80px;
   padding-bottom: 80px;
 }

+ 1 - 1
src/components/InfoTitle/index.less

@@ -8,7 +8,7 @@
   position: fixed;
   left: 10px;
   top: 50px;
-  right: 480px;
+  right: 470px;
   z-index: 204;
 }
 .operations, .health{

+ 24 - 10
src/components/MainSuit/index.jsx

@@ -6,7 +6,8 @@ import SearchDrop from '@components/SearchDrop';
 import CommonSymptom from '@components/CommonSymptom';
 import chooseType from '@containers/eleType.js';
 import config from "@config/index";
-import {isIE} from "@utils/tools.js"
+import {isIE,getPageCoordinate,windowEventHandler} from "@utils/tools.js"
+import $ from 'jquery';
 
 class MainSuit extends Component{
   constructor(props){
@@ -25,7 +26,9 @@ class MainSuit extends Component{
       blurTimer:null,
       inpText:'',
       clearTimer:null,
-      overFlag:false
+      overFlag:false,
+      tmpScroll:0,
+      tmpTop:0,
     };
     this.toggleEditable = this.toggleEditable.bind(this);
     this.handleFocus = this.handleFocus.bind(this);
@@ -132,14 +135,26 @@ class MainSuit extends Component{
 
   handleClick(e){//让搜索框跟随鼠标点击移动
     // e.stopPropagation(); //冒泡到最顶层关闭其他下拉
-    let boxLeft = e.pageX -32 + 'px';
-    // let boxTop = e.pageY - 112 + 'px';
-    let offsetTop = e.target.offsetTop;
-    let boxTop = offsetTop + 28 + 'px';
+    //若使用e.target,因为是onClick事件中,值可能是itembox的而不是span因此会有bug
+    const ele = document.activeElement;
+    console.log(ele.toString())
+    if(ele.toString().indexOf('HTMLSpanElement') == -1){     //点击的不是span无法聚焦就不再设置位置
+      return;
+    }
+    const leftL = ele.offsetLeft;      //用焦点元素的左边距替换鼠标点击的左边距,高度还是鼠标点击的位置
     this.setState({
-      boxLeft:boxLeft,
-      boxTop:boxTop
-    })
+      // boxLeft:getPageCoordinate(e).boxLeft,
+      boxLeft:leftL+90,
+      boxTop:getPageCoordinate(e).boxTop,
+      tmpScroll: $("#addScrollEvent")[0].scrollTop,
+      tmpTop:getPageCoordinate(e).boxTop
+    });
+    windowEventHandler('scroll',()=>{      //弹窗跟随滚动条滚动或者关闭弹窗
+      let scrollYs = $("#addScrollEvent")[0].scrollTop;
+      this.setState({
+        boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
+      })
+    },$("#addScrollEvent")[0])
   }
 
   handleChange(e){
@@ -227,7 +242,6 @@ class MainSuit extends Component{
     const {showModule,boxLeft,boxTop,show,symptom,search} = this.state;
     const symptomFlag = CommonSymptoms.length>0 ? true : false;
     const searchFlag = searchData.length>0 ? true : false;
-    
     if(+type===1){      //文本模式
       return <Textarea title='主诉' boxMark='1' isRead={isRead} value={saveText[0]} handlePush={fetchPushInfos} handleInput={handleInput} />;
     }

+ 24 - 4
src/components/NumberDrop/index.jsx

@@ -2,7 +2,8 @@ import React,{Component} from 'react';
 import className from 'classnames';
 import {NumberPan} from '@commonComp';
 import style from './index.less';
-import {handleEnter} from '@utils/tools.js';
+import $ from "jquery";
+import {handleEnter,getPageCoordinate} from '@utils/tools.js';
 /***
  * author:zn@2018-11-19
  * 接收参数:
@@ -20,7 +21,11 @@ class NumberDrop extends Component{
       numEditable:true,      //数字框是否可输入
       timer:null,
       hasSelect:false,       //是否点过下拉键盘
-      isClosed:false
+      isClosed:false,
+      boxLeft:0,
+      boxTop:0,
+      tmpTop:0,
+      tmpScroll:0
     };
     this.$span = React.createRef();
     this.$pre = React.createRef();
@@ -61,6 +66,18 @@ class NumberDrop extends Component{
     });
   }
   handleNumClick(e){      //数字框不可编辑的状态时点击事件,点击将数字框变为可输入且下拉不再显示直到失焦后再次聚集
+    this.setState({
+      boxLeft:getPageCoordinate(e).boxLeft,
+      boxTop:getPageCoordinate(e).boxTop,
+      tmpScroll: $("#addScrollEvent")[0].scrollTop,
+      tmpTop:getPageCoordinate(e).boxTop
+    });
+    $("#addScrollEvent").scroll(()=>{
+      let scrollYs = $("#addScrollEvent")[0].scrollTop;
+      this.setState({
+        boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
+      })
+    })
     e.stopPropagation();
     const {show,handleShow,ikey,id,patId,handleHide,value} = this.props;
     const {hasSelect} = this.state;
@@ -132,7 +149,7 @@ class NumberDrop extends Component{
   }
   render(){
     const {placeholder,prefix,suffix,show,value,handleHide} = this.props;
-    const {numEditable,editable,hasSelect} = this.state;
+    const {numEditable,editable,hasSelect,boxTop,boxLeft} = this.state;
     return <div className={this.getClasses()}
                 onDoubleClick={this.changeToEdit}
                 contentEditable={editable}
@@ -151,7 +168,10 @@ class NumberDrop extends Component{
       <span ref = {this.$suf}>&nbsp;{suffix}</span>
       <NumberPan handleSelect={(text)=>this.select(text)}
                  onClose={handleHide}
-                 show={show} toClear={!hasSelect}/>
+                 show={show} 
+                 toClear={!hasSelect}
+                 left={boxLeft}
+                 top={boxTop}/>
     </div>
   }
 }

+ 2 - 5
src/components/Operation/index.jsx

@@ -6,7 +6,7 @@ import saveHistory from '@common/images/saveHistory.png';
 import PrintPreviewContainer from '@containers/PrintPreviewContainer';
 import PreviewContainer from '@containers/PreviewContainer';
 import { ConfirmModal, Notify } from '@commonComp';
-import {getAllDataList,getAllDataStringList,isAllClear} from '@utils/tools';
+import {getAllDataList,getAllDataStringList,isAllClear,filterArr} from '@utils/tools';
 import store from '@store';
 
 
@@ -80,10 +80,7 @@ class Operation extends Component {
   keepHistory(){
     let baseList = store.getState();
     let jsonStr = getAllDataStringList(baseList);
-    if(JSON.parse(jsonStr.chief).length == 1 && JSON.parse(jsonStr.chief)[0].trim() ==''){
-        Notify.info('主诉不能为空');
-        return false;
-    }else if(jsonStr.chief && JSON.parse(jsonStr.chief).length < 1){
+    if(filterArr(JSON.parse(jsonStr.chief)) == ''){
         Notify.info('主诉不能为空');
         return false;
     }else if(!jsonStr.diag || jsonStr.diag.trim().length < 1){

+ 22 - 9
src/components/OtherHistory/index.jsx

@@ -2,7 +2,8 @@ import React,{Component} from 'react';
 import {Button,InlineTag,ItemBox,Textarea,Notify} from '@commonComp';
 import chooseType from '@containers/eleType.js';
 import SearchDrop from '@components/SearchDrop';
-import {filterDataArr} from '@utils/tools'
+import {filterDataArr,getPageCoordinate,windowEventHandler} from '@utils/tools'
+import $ from 'jquery';
 import style from './index.less';
 
 class OtherHistory extends Component{
@@ -11,8 +12,10 @@ class OtherHistory extends Component{
     this.state = {
       boxMark:'3',
       editable:true,
-      boxLeft:'0px',
-      boxTop:'0px'
+      boxLeft:0,
+      boxTop:0,
+      tmpScroll:0,
+      tmpTop:0
     };
     this.handleClick = this.handleClick.bind(this);
     this.handleSearchSelect = this.handleSearchSelect.bind(this);
@@ -64,13 +67,24 @@ class OtherHistory extends Component{
     //fetchPushInfos&&fetchPushInfos();
     //若使用e.target,因为是onClick事件中,值可能是itembox的而不是span因此会有bug
     const ele = document.activeElement;
-    const height = ele.offsetHeight;
-    let boxTop = (+(ele.offsetTop)+height)+'px';
-    let boxLeft = ele.offsetLeft + 'px';
+
+    if(ele.toString().indexOf('HTMLSpanElement') == -1){     //点击的不是span无法聚焦就不再设置位置
+      return;
+    }
+    const leftL = ele.offsetLeft;      //用焦点元素的左边距替换鼠标点击的左边距,高度还是鼠标点击的位置
     this.setState({
-      boxLeft:boxLeft,
-      boxTop:boxTop
+      // boxLeft:getPageCoordinate(e).boxLeft,
+      boxLeft:leftL+90,
+      boxTop:getPageCoordinate(e).boxTop,
+      tmpScroll: $("#addScrollEvent")[0].scrollTop,
+      tmpTop:getPageCoordinate(e).boxTop
     });
+    windowEventHandler('scroll',()=>{      //弹窗跟随滚动条滚动或者关闭弹窗
+      let scrollYs = $("#addScrollEvent")[0].scrollTop;
+      this.setState({
+        boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
+      })
+    },$("#addScrollEvent")[0])
   }
   /*componentWillReceiveProps(next){
     const isRead = this.props;
@@ -87,7 +101,6 @@ class OtherHistory extends Component{
     const {boxTop,boxLeft,boxMark} = this.state;
     const hasData = saveText.join("")||data.length>0;
     const show = showArr&&showArr[boxMark+focusTextIndex+'0'];
-
     if(+type===1){      //文本模式
       return <Textarea title='其他史' boxMark='3'
                        isRead={isRead}

+ 2 - 5
src/components/PrintPreview/index.jsx

@@ -1,5 +1,5 @@
 import React, { Component } from "react";
-import { getAllDataList, getAllDataStringList } from '@utils/tools';
+import { getAllDataList, getAllDataStringList,filterArr } from '@utils/tools';
 import style from "./index.less";
 import PreviewBody from "../PreviewBody";
 import store from '@store';
@@ -12,12 +12,9 @@ class PrintPreview extends Component {
         super(props)
     }
     surePrint(jsonStr){
-        if(JSON.parse(jsonStr.chief).length == 1 && JSON.parse(jsonStr.chief)[0].trim() ==''){
+        if(filterArr(JSON.parse(jsonStr.chief)) == ''){
           Notify.info('主诉不能为空');
             return false;
-        }else if(jsonStr.chief && JSON.parse(jsonStr.chief).length < 1){
-            Notify.info('主诉不能为空');
-            return false;
         }else if(!jsonStr.diag || jsonStr.diag.trim().length < 1){
             Notify.info('诊断不能为空');
             return false;

+ 4 - 6
src/components/PushContainer/index.less

@@ -5,14 +5,12 @@
   width: @push-width;
   float: right;
   padding-top: 20px;
-  position: absolute;
-  right: 10px;
   z-index: 200;
 
-  position: fixed;
-  top: 50px;
-  bottom: 10px;
-  right: 10px;
+  // position: fixed;     
+  // top: 50px;
+  // bottom: 10px;
+  // right: 10px;
   padding-bottom:50px;
 }
 .title{

+ 20 - 5
src/components/RadioDrop/index.jsx

@@ -1,5 +1,5 @@
 import React,{Component} from 'react';
-import {handleEnter} from '@utils/tools.js';
+import {handleEnter,getPageCoordinate,windowEventHandler} from '@utils/tools.js';
 import {DropList} from '@commonComp';
 import style from "./index.less";
 import $ from "jquery";
@@ -22,7 +22,11 @@ class RadioDrop extends Component{
     super(props);
     this.state={
       editable:false,
-      timer:null
+      timer:null,
+      boxLeft:0,
+      boxTop:0,
+      tmpScroll:0,
+      tmpTop:0,
     };
     this.$cont = React.createRef();
     this.handleSelect = this.handleSelect.bind(this);
@@ -77,9 +81,20 @@ class RadioDrop extends Component{
         handleShow && handleShow({ikey,id:patId||id});
       }
     },300);
+    
     this.setState({
-      timer
+      timer,
+      boxLeft:getPageCoordinate(e).boxLeft,
+      boxTop:getPageCoordinate(e).boxTop,
+      tmpScroll: $("#addScrollEvent")[0].scrollTop,
+      tmpTop:getPageCoordinate(e).boxTop
     });
+    windowEventHandler('scroll',()=>{      //弹窗跟随滚动条滚动或者关闭弹窗
+      let scrollYs = $("#addScrollEvent")[0].scrollTop;
+      this.setState({
+        boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
+      })
+    },$("#addScrollEvent")[0])
   }
   componentDidMount(){    //默认值选中
     const {data,ikey,handleSelect} = this.props;
@@ -120,6 +135,7 @@ class RadioDrop extends Component{
   }
   render(){
     const {data,prefix,suffix,placeholder,show,value} = this.props;
+    const {boxLeft,boxTop} = this.state;
     return <div className={style['container']} ref = {this.$cont}>
       {prefix}
       <div className={this.getClass()}
@@ -131,8 +147,7 @@ class RadioDrop extends Component{
         {value||placeholder}
       </div>
       {suffix}
-      <DropList onSelect={this.handleSelect} data={data}
-                show={show}/>
+      <DropList onSelect={this.handleSelect} data={data} left={boxLeft} top={boxTop} show={show}/>
     </div>
   }
 }

+ 14 - 10
src/components/SearchDrop/index.jsx

@@ -1,5 +1,6 @@
 import React,{Component} from 'react';
 import classNames from 'classnames';
+import ReactDom from "react-dom";
 
 import style from "./index.less";
 /****
@@ -40,8 +41,8 @@ class SearchDrop extends Component{
   getStyle(){
     const {left,top} = this.props;
     return {
-      left:left?left:'',
-      top:top?top:''
+      left:left?left+'px':'',
+      top:top?top+'px':''
     }
   }
 
@@ -53,14 +54,17 @@ class SearchDrop extends Component{
   }
   render(){
     let litext = '';
-    return <div className={this.getClass()} contenteditable="false" id="searchBox" style={this.getStyle()}>
-      <ul>
-        {this.props.data&&this.props.data.map((it)=>{
-          litext = it.showType==1?it.name:it.name+'('+it.retrievalName+')';
-          return <li onClick={(e)=>this.handleSelect(e,it)} title={litext}>{litext}</li>
-        })}
-      </ul>
-    </div>
+    const domNode = document.getElementById('root');
+    return ReactDom.createPortal(
+      <div className={this.getClass()} contenteditable="false" id="searchBox" style={this.getStyle()}>
+        <ul>
+          {this.props.data&&this.props.data.map((it)=>{
+            litext = it.showType==1?it.name:it.name+'('+it.retrievalName+')';
+            return <li onClick={(e)=>this.handleSelect(e,it)} title={litext}>{litext}</li>
+          })}
+        </ul>
+      </div>
+    ,domNode)
   }
 }
 

+ 82 - 45
src/components/SpreadDrop/index.jsx

@@ -2,8 +2,9 @@ import React,{Component} from 'react';
 import classNames from 'classnames';
 import config from '@config/index.js';
 import style from './index.less';
-import {deepClone,filterArr,handleEnter,isIE} from '@utils/tools.js';
+import {deepClone,filterArr,handleEnter,isIE,getPageCoordinate,windowEventHandler} from '@utils/tools.js';
 import {Notify} from '@commonComp';
+import ReactDom from "react-dom";
 import {getIds} from '@common/js/func.js';
 import $ from 'jquery';
 /****
@@ -35,8 +36,10 @@ class SpreadDrop extends Component{
       ban:{},  //放'伴'字段
       editable:false,      //双击编辑
       labelVal:'',  //存放标签原有的值--主诉字数限制用
-      boxLeft:null,
-      boxTop:null
+      boxLeft:0,
+      boxTop:0,
+      tmpScroll:0,
+      tmpTop:0,
     };
     this.$div = React.createRef();
     this.handleSelect = this.handleSelect.bind(this);
@@ -53,14 +56,26 @@ class SpreadDrop extends Component{
   }
   handleShow(e){//单击
     e&&e.stopPropagation();
-    let boxLeft = e.pageX -175 + 'px';
-    let offsetTop = e.target.offsetTop;
-    const ht = e.target.offsetHeight;   //如杂音选中文字有多行时,写死会遮挡
-    let boxTop = offsetTop + ht +2 + 'px';
+    // let boxLeft = e.pageX -175 + 'px';
+    // let offsetTop = e.target.offsetTop;
+    // const ht = e.target.offsetHeight;   //如杂音选中文字有多行时,写死会遮挡
+    // let boxTop = offsetTop + ht +2 + 'px';
+    // this.setState({
+    //   boxLeft:boxLeft,
+    //   boxTop:boxTop
+    // })
     this.setState({
-      boxLeft:boxLeft,
-      boxTop:boxTop
-    })
+      boxLeft:getPageCoordinate(e).boxLeft,
+      boxTop:getPageCoordinate(e).boxTop,
+      tmpScroll: $("#addScrollEvent")[0].scrollTop,
+      tmpTop:getPageCoordinate(e).boxTop
+    });
+    windowEventHandler('scroll',()=>{      //弹窗跟随滚动条滚动或者关闭弹窗
+      let scrollYs = $("#addScrollEvent")[0].scrollTop;
+      this.setState({
+        boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
+      })
+    },$("#addScrollEvent")[0])
     // window.event? window.event.cancelBubble = true : e.stopPropagation();
      this.setStateInit();      //恢复初始选中状态
     const {ikey,handleShow,placeholder,flag,id,value,tagType,type} = this.props;
@@ -295,8 +310,44 @@ class SpreadDrop extends Component{
     }
     return style['tag'];
   }
+  
+  componentDidMount(){
+    if(isIE()){
+      $(this.$div.current).onIe8Input(function(e){
+        this.onChange(e)
+      },this);
+    }
+  }
+
+  render(){
+    const {placeholder,value,show,data} = this.props;
+    const {editable,boxLeft,boxTop} = this.state;
+    return  <div className={style['container']}
+              onFocus={(e)=>e.stopPropagation()}
+              onBlur={(e)=>e.stopPropagation()}
+              onInput={(e)=>e.stopPropagation()}>
+        <div
+        ref={this.$div}
+        onClick={this.handleShow}
+        className={this.getClass()}
+        contentEditable={editable}
+        onDoubleClick={this.changeToEdit}
+        onBlur={this.handleBlur}
+        onInput={this.onChange}
+        onkeydown={handleEnter}
+        >{value||placeholder}</div>
+          <ListItems data={data} left={boxLeft} 
+            top={boxTop} show={show} handleSelect={this.handleSelect} handleConfirm={this.handleConfirm} handleClear={this.handleClear} {...this.state}></ListItems>
+      </div>
+  }
+}
+
+class ListItems extends Component{
+  constructor(props){
+    super(props);
+  }
   getLabels(){
-    const {data} = this.props;
+    const {data,handleSelect} = this.props;
     let detail = [];
     let isSpecialPos = false;       //是否特殊位置(单行在上面,如无殊)
     let isExclu = false;      //是否与其他互斥
@@ -310,53 +361,39 @@ class SpreadDrop extends Component{
       }else{
         detail = it.questionDetailList;
       }
-      return <ListItem data={detail}
+      return <ListItem datas={detail}
                        isRadio={isRadio}
                        joint={it.joint}
                        listIndex={i}
                        isSpecialPos={isSpecialPos}
                        isExclu={isExclu}
-                       handleClick={this.handleSelect}
-                       {...this.state}></ListItem>;
+                       handleClick={handleSelect}
+                       {...this.props}></ListItem>;
     });
     return list;
   }
-  componentDidMount(){
-    if(isIE()){
-      $(this.$div.current).onIe8Input(function(e){
-        this.onChange(e)
-      },this);
+  getStyle(){
+    const {left,top,show} = this.props;
+    return {
+      left:left?left+'px':'',
+      top:top?top+'px':'',
+      display:show?'block':'none'
     }
   }
-
-  render(){
-    const {placeholder,value,show} = this.props;
-    const {editable,boxLeft,boxTop} = this.state;
-    return <div className={style['container']}
-            onFocus={(e)=>e.stopPropagation()}
-            onBlur={(e)=>e.stopPropagation()}
-            onInput={(e)=>e.stopPropagation()}>
-      <div
-      ref={this.$div}
-      onClick={this.handleShow}
-      className={this.getClass()}
-      contentEditable={editable}
-      onDoubleClick={this.changeToEdit}
-      onBlur={this.handleBlur}
-      onInput={this.onChange}
-      onkeydown={handleEnter}
-      >{value||placeholder}</div>
-      <div className={style["drop-list"]} style={{display:show?'block':'none',top:boxTop,left:boxLeft}} contentEditable="false" onClick={(e)=>{e.stopPropagation();}}>
+  render (){   
+    const {handleClear,handleConfirm} = this.props;
+    const domNode = document.getElementById('root');
+    return ReactDom.createPortal(
+      <div className={style["drop-list"]} style={this.getStyle()} contentEditable="false" onClick={(e)=>{e.stopPropagation();}}>
         {this.getLabels()}
         <div className="oper">
-          <span className={style['clear']} onClick={this.handleClear}>清空选项</span>
-          <span className={style['confirm']} onClick={this.handleConfirm}>确定</span>
+          <span className={style['clear']} onClick={handleClear}>清空选项</span>
+          <span className={style['confirm']} onClick={handleConfirm}>确定</span>
         </div>
       </div>
-    </div>
+    ,domNode)
   }
 }
-
 class ListItem extends Component{
   constructor(props){
     super(props);
@@ -365,6 +402,7 @@ class ListItem extends Component{
     e.stopPropagation();
     // window.event? window.event.cancelBubble = true : e.stopPropagation();
     const {handleClick,isExclu,isRadio,data,exists,noneIds,withs,joint,listIndex} = this.props;
+
     const index=listIndex+''+i;
     //列单选处理
     if(isRadio){
@@ -406,15 +444,14 @@ class ListItem extends Component{
     }
   }
   render(){
-    const {data,isSpecialPos} = this.props;
+    const {datas,isSpecialPos} = this.props;
     const pos = isSpecialPos?style['independent']:'';
     return <ul className={classNames(style['row'],pos)} onBlur={(e)=>e.stopPropagation()}>
-      {data&&data.map((it,i)=>{
+      {datas&&datas.map((it,i)=>{
         return <li onClick={(e)=>this.handleClick(e,it,i)}
                    className={this.getClass(it.id)}>{it.labelPrefix}{it.name}{it.labelSuffix}</li>
       })}
     </ul>;
   }
-
 }
 export default SpreadDrop;

+ 3 - 1
src/containers/eleType.js

@@ -19,7 +19,7 @@ import Multiple from '@containers/Multiple';
 //单选类型
 export function singleRadio(params){
   const data = params.item;//console.log(111,data);
-  const {i,hideTag,boxMark,showArr,selecteds} = params;
+  const {i,hideTag,boxMark,showArr,selecteds,boxTop,boxLeft} = params;
   const showInx = boxMark+i+'0';    //单括号多标签的情况下需要识别同一个标签内多个下拉组件的显示状态
   switch (+data.controlType){
     case 0:
@@ -34,6 +34,8 @@ export function singleRadio(params){
                         boxMark={boxMark}
                         id={data.id}
                         ikey={showInx}
+                        boxTop={boxTop}
+                        boxLeft={boxLeft}
                         hideTag={hideTag}></RadioDrop>;
     case 2:
       const dataList = data.questionDetailList&&data.questionDetailList.length>0?data.questionDetailList:data.questionMapping;

+ 2 - 1
src/store/reducers/checkBody.js

@@ -13,7 +13,8 @@ const initState = {
                 searchData:[],
                 selecteds:[],
                 focusIndex:'',
-                isEmpty:true      //是否为空白,需要请求数据
+                isEmpty:true,      //是否为空白,需要请求数据
+                showSearchBox:false
           };
 export default function(state=initState,action){
   let res = Object.assign({},state);

+ 28 - 5
src/utils/tools.js

@@ -520,11 +520,20 @@ function preventDefault(event) {
 }
 
 //ie8添加解除事件兼容
-function windowEventHandler(type,func){
-    if(window.addEventListener){
-      window.addEventListener(type, func);
+function windowEventHandler(type,func,dom){
+    let win = dom?dom:window;
+    if(win.addEventListener){
+      win.addEventListener(type, func);
     }else{
-      window.attachEvent('on'+type,func);
+      win.attachEvent('on'+type,func);
+    }
+}
+function windowRemoveEventHandler(type,func,dom){
+    let win = dom?dom:window;
+    if(win.addEventListener){
+      win.removeEventListener(type, func);
+    }else{
+      win.detachEvent('on'+type,func);
     }
 }
 
@@ -615,6 +624,18 @@ function normalVal(min,max){
       return null;
   }
 }
+function getPageCoordinate(event){
+    let e = event || window.event;
+    var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
+    var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
+    var x = e.pageX || (e.clientX + scrollX);
+    var y = (e.pageY+25) || (e.clientY + scrollY + 25);
+    let obj = {
+      boxLeft : x ,
+      boxTop : y
+    }
+    return obj;
+}
 module.exports = {
     checkType: Type.checkType,
     regexp,
@@ -638,5 +659,7 @@ module.exports = {
     getEMRParams,
     windowEventHandler,
     isAllClear,
-    normalVal
+    normalVal,
+    getPageCoordinate,
+    windowRemoveEventHandler
 };