Explorar o código

主诉-添加症状增加搜索功能-未完成

liucf %!s(int64=5) %!d(string=hai) anos
pai
achega
f6d39f7b4a

BIN=BIN
src/common/components/SearchBox/imgs/clear.png


BIN=BIN
src/common/components/SearchBox/imgs/search.png


+ 177 - 0
src/common/components/SearchBox/index.jsx

@@ -0,0 +1,177 @@
+import React from 'react';
+import styles from './index.less';
+import clear from './imgs/clear.png';
+import search from './imgs/search.png';
+import PropTypes from "prop-types";
+import config from '@config/index';
+import $ from 'jquery';
+import classNames from 'classnames';
+import SearchDrop from '@components/SearchDrop';
+import ScrollArea from 'react-scrollbar';
+/**
+ * 搜索框
+ * handleChangeValue  函数参数为输入框的value值
+ */
+class SearchBox extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            val:'',
+            showBox:false, //显示搜索结果
+            border:'',
+            show:false, //显示清空icon
+            timer:null,
+            searchData:[]
+        }
+        this.textInput = React.createRef();
+        this.handleClearVal = this.handleClearVal.bind(this);
+        this.handleFocus = this.handleFocus.bind(this);
+        this.handleBlur = this.handleBlur.bind(this);
+        this.clickIcon = this.clickIcon.bind(this);
+        this.handleSearchSelect = this.handleSearchSelect.bind(this);
+    }
+    componentDidMount(){
+      // this.props.handleChangeValue('');
+    }
+    handleClearVal(){
+        const { handleChangeValue } = this.props;
+        this.textInput.current.value = '';
+        this.textInput.current.focus();
+        this.setState({
+            val:'',
+            show:false
+        });
+        handleChangeValue('');
+    }
+    handleSearchSelect(e,item){
+      e.stopPropagation();
+      e.preventDefault();
+      const {cliIndex,chooseSearch,clearSearch} = this.props;
+      console.log("选择数据:",item);
+      this.setState({
+        val:'',
+        show:false
+      });
+      chooseSearch&&chooseSearch({item:item,index:cliIndex})
+      clearSearch&&clearSearch();
+      this.textInput.current.innerText = "";
+    }
+    handleInput(e){
+      e.stopPropagation();
+      e.preventDefault();
+      const { getSearchData ,mainIds} = this.props;
+        clearTimeout(this.state.timer);
+        let timer = setTimeout(()=>{
+            clearTimeout(this.state.timer);
+            if(e.target.value.trim() == ''){
+                this.setState({
+                  show:false
+                })
+                return
+            }
+            this.setState({
+                val:e.target.value,
+                show:true
+            })
+            getSearchData && getSearchData({inpStr:e.target.value.replace('<br>',''),boxMark:1,itemType:0,mainIds:mainIds});
+        },config.delayTime);
+        this.setState({
+            timer
+        });
+    }
+    handleFocus(e){
+      e.stopPropagation();
+      e.preventDefault();
+      if(this.state.val.trim() != ''){
+        return;
+      }else{
+          this.setState({border:true})
+      }
+    }
+    handleBlur(e){
+      e.stopPropagation();
+      e.preventDefault();
+      this.setState({border:false,val:''})
+    }
+    clickIcon(){
+      this.setState({showBox:true,val:''})
+      setTimeout(()=>{
+        this.textInput.current.focus();
+      },0)
+    }
+    componentWillReceiveProps(next){
+      // 隐藏时,清空搜索框内文字,清空搜索结果,隐藏搜索框
+      const { clearSearch } = this.props;
+      if(!next.show && next.show != this.props.show){
+        clearSearch();
+        this.textInput.current.innerText = "";
+        this.setState({
+          showBox:false,
+          val:'',
+          border:false,
+          searchData:[]
+        })
+      }
+    }
+    render() {
+        const { children,visible,mainSearchData } = this.props;
+        const { show ,border, showBox,searchData} = this.state;
+        const showBd = showBox?styles['borderNone']:'';
+        const borderCor = border?styles['border']:'';
+        const isShow = showBox?styles['show']:styles['hide'];
+        let litext = '';
+        const contStyle={
+          opacity:'0.4',
+          right:'0',
+          top:'1px',
+          zIndex:'15',
+          width:'14px',
+          background:'#f1f1f1'};
+        const barStyle={background:'#777',width:'100%'};
+        return (
+            <div className={classNames(styles['search'])} onClick={(e)=>{e.stopPropagation();}}>
+                <img className={styles.searchVal} src={search} alt="搜索" onClick={this.clickIcon}/>
+                <img style={{display:show?'block':'none'}} className={styles.clearVal} src={clear} onClick={this.handleClearVal} alt="清空" />
+                <input
+                    className={classNames(isShow,showBd,borderCor)}
+                    type="text"
+                    maxLength="30"
+                    ref={this.textInput}
+                    onFocus={this.handleFocus}
+                    onBlur={this.handleBlur}
+                    onInput={(e) => { 
+                        this.handleInput(e)
+                    }}
+                    onPropertyChange={(e) => {  // 兼容ie
+                        this.handleInput(e)
+                    }}
+                />
+                {mainSearchData&&mainSearchData.length>0 ? <div className={styles.autoList}>
+                    <ScrollArea speed={0.8}
+                      horizontal={false}
+                      stopScrollPropagation={mainSearchData.length>6?true:false}
+                      style={{maxHeight:'225px'}}
+                      verticalContainerStyle={contStyle}
+                      verticalScrollbarStyle={barStyle}
+                      contentClassName="content">
+                      <ul>
+                        {mainSearchData&&mainSearchData.map((it)=>{
+                          litext = it.showType==1?it.name:it.name+'('+it.retrievalName+')';
+                          return <li key={it.conceptId} onClick={(e)=>this.handleSearchSelect(e,it)} title={litext}>{litext}</li>
+                        })}
+                      </ul>
+                    </ScrollArea>
+                  </div>:''}
+            </div>
+        )
+    }
+}
+/*SearchBox.defaultProps = {
+    visible: false
+};
+
+SearchBox.propTypes = {
+    visible:PropTypes.bool,
+    handleChangeValue: PropTypes.func
+};*/
+export default SearchBox;

+ 52 - 0
src/common/components/SearchBox/index.less

@@ -0,0 +1,52 @@
+@import "~@less/variables.less";
+
+.search {
+    .contentZIndex1;
+    width: 316px;
+    padding: 8px;
+    box-sizing: border-box;
+    position: relative;
+    background-color: #fff;
+    .autoList {
+      position: absolute;
+      width: 300px;
+      background: #fff;
+      border: 1px solid #ccc;
+       ul{
+        // border: 1px solid #ccc;
+        li:hover{
+          border: 1px solid #3B9ED0;
+        }
+      } 
+    }
+    input {
+        width: 100%;
+        height: 34px;
+        line-height: 34px;
+        padding: 0 32px;
+        box-sizing: border-box;
+    }
+    .border {
+        border: 1px solid @blue;
+    }
+    .borderNone {
+        border: 1px solid #979797;
+    }
+    img {
+        position: absolute;
+        top: 15px;
+    }
+    .searchVal {
+        left: 18px;
+    }
+    .clearVal{
+        cursor: pointer;
+        right: 18px;
+    }
+}
+.show {
+    display:block;
+}
+.hide {
+    display: none;
+}

+ 3 - 1
src/common/components/index.js

@@ -24,6 +24,7 @@ import DelToast from "./DelToast";
 import TailInlineTag from "./TailInlineTag";
 import Footer from "./Footer";
 import WrapModalContainer from "./WrapModalContainer";
+import SearchBox from "./SearchBox";
 
 module.exports = {
     Banner,
@@ -52,5 +53,6 @@ module.exports = {
     MiniToast,
     TailInlineTag,
     Footer,
-    WrapModalContainer
+    WrapModalContainer,
+    SearchBox
 };

+ 3 - 3
src/components/MainSuit/index.jsx

@@ -163,7 +163,7 @@ class MainSuit extends Component{
       }
       ev.target.blur();
       ev.target.innerText?(ev.target.innerText = data.substr(0,config.limited)):(ev.target.innerHTML = data.substr(0,config.limited));  //输入法内输入多个字再按enter的情况
-      console.log(333,data,ev)
+      //console.log(333,data,ev)
       // ev.target.blur();
       this.setState({
         inpText:data.substr(0,config.limited),
@@ -236,9 +236,9 @@ class MainSuit extends Component{
     const {freeText,saveText,datas,clearSearch,getSymptomFeature,currentData,saveChronic} = this.props;
     const that = this;
     let data = this.state.inpText;
-    const inner = e.target.innerText || e.target.innerHTML ;
+    const inner = e.target.innerText || e.target.innerHTML ;console.log("触发了主诉失焦事件")
     //分词-现病史没有模板的时候才去获取
-    if(inner.trim() && currentData&&currentData.length==0){
+    if(inner.trim() && currentData&&currentData.length==0 && datas.length==0){
       getFeature(inner.replace('<br>','')).then((res)=>{
         if(res.data.code==0){
           const result = res.data.data;

+ 32 - 7
src/components/SpreadDrop/index.jsx

@@ -5,6 +5,7 @@ import style from './index.less';
 import {setPosition,deepClone,filterArr,handleEnter,isIE,windowEventHandler,filterDataArr,getIds,getPageCoordinate} from '@utils/tools.js';
 import {Notify} from '@commonComp';
 import ScrollArea from 'react-scrollbar';
+import SearchBox from '@containers/SearchBox'
 import $ from 'jquery';
 /****
  * 标签组合下拉,选中的项目展开
@@ -359,8 +360,9 @@ class SpreadDrop extends Component{
     }
   }*/
   render(){
-    const {placeholder,value,show,data,order} = this.props;
+    const {placeholder,value,show,data,order,type,tagType,ikey} = this.props;
     const {tmpDom,left} = this.state
+    const clickIndx = ikey.split('-')[1];//展开下拉的index
     if(!show&&tmpDom){
       $(tmpDom).parent().prev().attr({"contentEditable":true})
     }
@@ -379,8 +381,8 @@ class SpreadDrop extends Component{
         onInput={this.onChange}
         onkeydown={handleEnter}
         >{value||placeholder}</div>
-          <ListItems parDiv={this.$list} data={data} order={order} left={left}
-             show={show} handleSelect={this.handleSelect} handleConfirm={this.handleConfirm} handleClear={this.handleClear} {...this.state}></ListItems>
+          <ListItems parDiv={this.$list} data={data} order={order} left={left} boxMark={type} tagType={tagType}
+             show={show} cliIndex={clickIndx} handleSelect={this.handleSelect} handleConfirm={this.handleConfirm} handleClear={this.handleClear} {...this.state}></ListItems>
       </div>
   }
 }
@@ -424,7 +426,7 @@ class ListItems extends Component{
     }
   }
   render (){
-    const {handleClear,handleConfirm,order,parDiv} = this.props;
+    const {handleClear,handleConfirm,order,parDiv,boxMark,tagType,show,cliIndex} = this.props;
     return <div className={style["drop-list"]} ref={parDiv} style={this.getStyle()} contentEditable="false" onClick={(e)=>{e.stopPropagation();}}>
         <p className={style['orderTips']}>按{order?'从左到右从上到下':'点击'}顺序成文</p>
         {this.getLabels()}
@@ -432,6 +434,11 @@ class ListItems extends Component{
           <span className={style['clear']} onClick={handleClear}>清空选项</span>
           <span className={style['confirm']} onClick={handleConfirm}>确定</span>
         </div>
+        
+        {boxMark==1 && tagType==11 && <div className="search">
+                  <div className={style["line"]}></div>
+                  <SearchBox show={show} cliIndex={cliIndex}/>
+                </div>}
       </div>
   }
 }
@@ -526,11 +533,29 @@ class ListItem extends Component{
       return <li onClick={(e)=>this.handleClick(e,it,i)} className={this.getClass(it.id)} title={it.name.length>8?it.name:''}>{it.name&&it.name.length>8?it.name.slice(0,8)+'...':it.name}</li>
     });
   }
-  render(){
+
+  getMainData(){//主诉添加症状-带搜索框
     const {datas,isSpecialPos} = this.props;
+    return datas&&datas.map((it,i)=>{
+      /*if(isSpecialPos){
+        return <li onClick={(e)=>this.handleClick(e,it,i)} className={this.getClass(it.id)}>{it.name}</li>
+      }*/
+      return <li onClick={(e)=>this.handleClick(e,it,i)} 
+            className={this.getClass(it.id)} 
+            title={it.name.length>8?it.name:''}
+            style={{'width':'85px','display':'inline-block'}}>
+            {it.name&&it.name.length>8?it.name.slice(0,8)+'...':it.name}
+          </li>
+    });
+  }
+
+  render(){
+    const {datas,isSpecialPos,boxMark,tagType,listIndex} = this.props;
     const pos = isSpecialPos?style['independent']:'';
-    return  <ul className={classNames(style['row'],pos)} onBlur={(e)=>e.stopPropagation()}>
-      {this.getData()}
+    const ifMainSear = boxMark==1 && tagType==11?true:false;
+    const main = ifMainSear&&listIndex==1?style['mainUl']:'';//伴字ul不设置宽度
+    return  <ul className={classNames(style['row'],pos,main)} onBlur={(e)=>e.stopPropagation()}>
+      {ifMainSear?this.getMainData():this.getData()}
     </ul>
   }
 }

+ 10 - 0
src/components/SpreadDrop/index.less

@@ -20,6 +20,16 @@
     width: 100%;
     border-bottom: 1px @disable-border-color solid;
   }
+  .mainUl{
+    width: 425px;
+    white-space: normal;
+  }
+  .line{
+    width: 100%;
+    height: 1px;
+    background: #EAEDF1;
+    margin: 20px 0 0 10px;
+  }
   li{
     padding-left: 20px;
     cursor: pointer;

+ 58 - 0
src/containers/SearchBox.js

@@ -0,0 +1,58 @@
+import {connect} from 'react-redux';
+import SearchBox from '@commonComp/SearchBox';
+import {getSearch} from '@store/async-actions/fetchModules.js';
+import {CLEAR_ADD_SEARCH,SET_ADD_SEARCH,CHOOSE_SEARCH} from '@store/types/mainSuit';
+import {ISREAD} from '@store/types/homePage.js';
+import {billing} from '@store/async-actions/pushMessage';
+import {Notify} from '@commonComp';
+
+function mapStateToProps(state){
+  return{
+    mainSearchData:state.mainSuit.addSearchData,//主诉-添加症状-搜索结果
+    mainIds:state.mainSuit.mainIds  //搜索去重id
+  }
+}
+
+function mapDispatchToProps(dispatch){
+  return{
+    // 主诉-添加症状-搜索
+    getSearchData:(item)=>{
+      getSearch(item).then((res)=>{
+          let result = res.data;
+          if(+result.code == 0){
+            let data = result.data;
+            dispatch({
+              type:SET_ADD_SEARCH,
+              data:data
+            })
+          }else{
+            console.log(result.msg);
+          }
+      });
+    },
+    chooseSearch(obj){
+      // 主诉字数限制
+
+      dispatch({
+        type: CHOOSE_SEARCH,
+        item:obj.item,
+        index:obj.index
+      })
+      dispatch({    //自由文本标签数据更新
+        type:ISREAD
+      });
+      //右侧推送
+      setTimeout(function(){ 
+        dispatch(billing());
+      },200);
+    },
+    clearSearch:()=>{
+      dispatch({
+        type: CLEAR_ADD_SEARCH
+      })
+    },
+  }
+}
+
+const SearchBoxContainer = connect(mapStateToProps,mapDispatchToProps)(SearchBox);
+export default SearchBoxContainer;

+ 32 - 0
src/store/actions/mainSuit.js

@@ -403,6 +403,38 @@ export const setSearch = (state,action)=>{
   res.isEnd = action.isEnd;
   return res;
 }
+// 主诉-添加症状-选中搜索结果
+export const chooseSearch = (state,action)=>{
+  const res = Object.assign({},state);
+  // 缓存到localStorage中
+
+  // 插入data中
+  const index = parseInt(action.index);
+  const item = action.item;
+  let data = res.data;
+  let text = {id:item.questionId,name:item.name,value:item.name,tagType:config.tagType,conceptId:item.conceptId};
+  // 判断index前是saveText中是否有伴
+  let nText = {};
+  if(!data[index].pos){//第一病程
+    const preText = res.saveText.slice(0,index);
+    const ind = preText.indexOf("伴");
+    if(ind != -1){
+      nText = Object.assign({},text,{exist:2});
+    }else{
+      nText = Object.assign({},text,{exist:1});
+    }
+  }else{//第二及以上病程
+    nText = Object.assign({},text);
+  }
+  res.data.splice(index,0,nText);
+  res.saveText[index] = item.name;
+  res.mainIds.push(item.conceptId);
+  if(item.questionId){
+    res.mainTailIds.push(item.questionId);
+  }
+  res.update=Math.random();console.log("action111",action,res)
+  return res;
+}
 
 //将选中的搜索结果插入
 export const insertSearch = (state,action)=>{

+ 12 - 3
src/store/reducers/mainSuit.js

@@ -2,11 +2,11 @@ import {RECOVER_TAG_MAIN,COMM_SYMPTOMS,CLEAR_COMSYMPTOMS,SHOW_TAIL,INSERT_MAIN,
   SET_SEARCH,CLEAR_SEARCH,GET_BIGDATAPUSH,SET_MAINSUIT,MIX_CONFIRM,NUMBER_SELECT,
   RADIO_SELECT,COMM_CONFIRM,CHANGE_LABELVAL,SAVE_FREE,CLEAR_MAIN_SUIT,SET_DATA,
   INSERT_SEARCH,MAIN_FOCUS_INDEX,SETTEXTMODEVALUE,SETMAINTEXT,MAINADDLABELITEM,SETMAININPUT,DEL_MAIN,CHANGE_LABELVAL_NUMBER,
-  REMOVE_MAIN_ID,MAINSUIT_MUL,DEL_MAIN_LABLE,SET_FEATURE,SET_MS_RADIO_INPUT_VAL,SAVE_CHRONIC,MAIN_REMOVE_SPAN} from '../types/mainSuit'
+  REMOVE_MAIN_ID,MAINSUIT_MUL,DEL_MAIN_LABLE,SET_FEATURE,SET_MS_RADIO_INPUT_VAL,SAVE_CHRONIC,MAIN_REMOVE_SPAN,SET_ADD_SEARCH,CLEAR_ADD_SEARCH,CHOOSE_SEARCH} from '../types/mainSuit'
 import {recoveTag,getCommSymptoms,handleTailClick,insertMain,setSearch,getBigSymptom,setMainMoudle,confirm,
   setNumberValue,setRadioValue,commConfirm,changeLabelVal,saveFreeVal,clearMainSuit,insertSearch,setTextModeValue,setCheckText,
   addLabelItem,setInputLabel,backspaceText,changeNumLabelVal,removeId,multipleComfirn,delSingleLable,
-  getSymptomFeature,setRadioInputValue} from '../actions/mainSuit'
+  getSymptomFeature,setRadioInputValue,chooseSearch} from '../actions/mainSuit'
 
 
 const initState = {
@@ -29,7 +29,8 @@ const initState = {
   },
   chronicDesease:null, //慢病
   mainTailIds:[],  //获取症状尾巴用
-  mainReadSonM:[] //回读的子模板
+  mainReadSonM:[], //回读的子模板
+  addSearchData:[] //添加症状里的搜索
 }
 
 export default function(state=initState,action){
@@ -118,6 +119,14 @@ export default function(state=initState,action){
         res.editClear = true;
       }
       return res;
+    case SET_ADD_SEARCH: //添加症状-搜索
+      res.addSearchData = action.data;
+      return res;
+    case CHOOSE_SEARCH:
+      return chooseSearch(state,action);
+    case CLEAR_ADD_SEARCH://清空症状搜索结果
+      res.addSearchData = [];
+      return res;
     default:
       return state;
   }

+ 3 - 0
src/store/types/mainSuit.js

@@ -31,3 +31,6 @@ export const SET_MS_RADIO_INPUT_VAL = 'SET_MS_RADIO_INPUT_VAL';
 export const SAVE_CHRONIC = 'SAVE_CHRONIC'; //储存慢病信息
 export const RECOVER_TAG_MAIN = 'RECOVER_TAG_MAIN';   //恢复已删除标签
 export const MAIN_REMOVE_SPAN = 'MAIN_REMOVE_SPAN';   //删除最后一个空span
+export const SET_ADD_SEARCH = 'SET_ADD_SEARCH';   //添加症状-搜索
+export const CLEAR_ADD_SEARCH = 'CLEAR_ADD_SEARCH';   //添加症状-搜索
+export const CHOOSE_SEARCH = 'CHOOSE_SEARCH';   //添加症状-搜索