index.jsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. import React,{Component} from 'react';
  2. import style from './index.less';
  3. import {ItemBox,Textarea,Notify,TailInlineTag} from '@commonComp';
  4. import SearchDrop from '@components/SearchDrop';
  5. import CommonSymptom from '@components/CommonSymptom';
  6. import chooseType from '@containers/eleType.js';
  7. import config from "@config/index";
  8. import {isIE,getPageCoordinate,windowEventHandler,filterDataArr,getAllDataList,getAllDataStringList,ifOtherClear} from "@utils/tools.js";
  9. import store from '@store';
  10. import {getFeature} from '@store/async-actions/fetchModules';
  11. class MainSuit extends Component{
  12. constructor(props){
  13. super(props);
  14. this.state = {
  15. boxEditable:true,
  16. boxLeft:null,
  17. boxTop:null,
  18. symptom:false,
  19. timer:null,
  20. inpText:'',
  21. clearTimer:null,
  22. overFlag:false,
  23. };
  24. this.toggleEditable = this.toggleEditable.bind(this);
  25. this.handleFocus = this.handleFocus.bind(this);
  26. this.handleSelect = this.handleSelect.bind(this);
  27. this.handleSearchSelect = this.handleSearchSelect.bind(this);
  28. this.handleChange = this.handleChange.bind(this);
  29. this.handleClick = this.handleClick.bind(this);
  30. this.handleBlur = this.handleBlur.bind(this);
  31. }
  32. toggleEditable(){
  33. this.setState({
  34. boxEditable:!this.state.boxEditable
  35. })
  36. }
  37. getInlineTag(){
  38. const {datas,showArr,handleTailClick,selecteds,saveText,mainIds,allModules} = this.props;
  39. const boxMark = '1';
  40. let list = datas&&datas.map((item,i)=>{
  41. if(item.flag && item.flag==3){
  42. return <TailInlineTag {...item} showText={item.relationModuleName} handleTailClick={(obj)=>{handleTailClick(obj,saveText,allModules)}}></TailInlineTag>
  43. }else {
  44. return chooseType({item,boxMark,i,hideTag:false,showArr,selecteds,saveText,mainIds});
  45. }
  46. })
  47. return list;
  48. }
  49. handleFocus(e){
  50. e.stopPropagation();
  51. const {getCommonSymptoms,datas,clearDiagnose} = this.props;
  52. let innerText = e.target.innerText || e.target.innerHTML;//兼容火狐43
  53. clearDiagnose&&clearDiagnose();//清除复诊数据
  54. if(!isIE()){//IE会触发onfocus和onblur事件
  55. if(!innerText.trim()){//有内容就走搜索接口
  56. getCommonSymptoms && getCommonSymptoms();
  57. this.setState({
  58. symptom:true,
  59. inpText:innerText
  60. })
  61. }else{
  62. this.setState({
  63. symptom:false,
  64. inpText:innerText
  65. })
  66. }
  67. }else{
  68. window.event.cancelBubble = true;
  69. // IE 默认会有一个<br>
  70. // if(datas.length==0 && !innerText.trim()){
  71. if(datas.length==0 && innerText == '<br>'){
  72. getCommonSymptoms && getCommonSymptoms();
  73. this.setState({
  74. symptom:true
  75. })
  76. }
  77. }
  78. }
  79. handleSelect(item){//选中的常见症状
  80. if(item.select.length>0){
  81. const {clearCommS,insertMain,getData} = this.props;
  82. // 获取主诉模板
  83. // getData && getData();
  84. // 让模板出现
  85. this.setState({
  86. symptom: false,
  87. })
  88. //选中后清空下拉结果
  89. insertMain && insertMain(item);
  90. clearCommS && clearCommS();
  91. }else{//没有选中点确定-关闭
  92. this.setState({
  93. symptom: false
  94. })
  95. }
  96. }
  97. handleSearchSelect(item){
  98. const {clearSearch,insertSearch,datas,span,saveText} = this.props;
  99. let mainText = filterDataArr(saveText);//主诉字数
  100. const itemL = item.name.length;
  101. let lengths = mainText.length + itemL;
  102. if(lengths>config.limited){
  103. Notify.info(config.limitText);
  104. clearSearch && clearSearch();
  105. return
  106. }
  107. if(datas.length==0){//没有使用模板时点击搜索结构要展开模板
  108. // FF26 清空输入的值 bug2283
  109. const mainBox = document.getElementById('mainSuit');
  110. mainBox.innerHTML = "";
  111. insertSearch &&insertSearch({item,span});
  112. this.setState({
  113. search: false,
  114. inpText:''
  115. })
  116. }else{
  117. insertSearch &&insertSearch({item,span});
  118. this.setState({
  119. search: false,
  120. })
  121. }
  122. // 清空搜索结果
  123. clearSearch && clearSearch();
  124. }
  125. handleClick(e){
  126. // e.stopPropagation(); //冒泡到最顶层关闭其他下拉
  127. //搜索框位置
  128. const ele = document.activeElement;
  129. const height = ele.offsetHeight;
  130. let boxTop = (+(ele.offsetTop)+height);
  131. let boxLeft = ele.offsetLeft;
  132. this.setState({
  133. boxLeft:boxLeft,
  134. boxTop:boxTop
  135. });
  136. }
  137. handleChange(e){
  138. const ev = e || window.event;
  139. const data = ev.target.innerText || ev.target.innerHTML;
  140. const {getSearchData,searchData,datas,pushMessage,reTotalHide,saveText,clearSearch,CommonSymptoms,getCommonSymptoms} = this.props;
  141. const {overFlag,inpText} = this.state;
  142. reTotalHide && reTotalHide();//重置homePage中的控制项
  143. const that = this;
  144. if(data&&data.length > config.limited){
  145. Notify.info(config.limitText);
  146. if(overFlag){
  147. ev.target.innerText?(ev.target.innerText = inpText) : (ev.target.innerHTML = inpText);
  148. ev.target.blur();
  149. return
  150. }
  151. ev.target.blur();
  152. ev.target.innerText?(ev.target.innerText = data.substr(0,config.limited)):(ev.target.innerHTML = data.substr(0,config.limited)); //输入法内输入多个字再按enter的情况
  153. //console.log(333,data,ev)
  154. // ev.target.blur();
  155. this.setState({
  156. inpText:data.substr(0,config.limited),
  157. overFlag:true,
  158. symptom:false
  159. })
  160. return false;
  161. }
  162. this.setState({
  163. inpText:data,
  164. overFlag:false
  165. })
  166. if(datas && datas.length > 0){//使用模板
  167. return false;
  168. }
  169. // 有输入内容或搜索结果时关闭,否则显示
  170. // if(data && data.trim()||searchData.length>0){
  171. if(data && data.trim()){
  172. clearTimeout(this.state.timer);
  173. const timer = setTimeout(function(){
  174. pushMessage && pushMessage(data);
  175. //调搜索接口 使用模板走EditableSpan里的搜索方法
  176. // FF26 会多一个<br>
  177. getSearchData && getSearchData({inpStr:data.replace('<br>',''),boxMark:1,itemType:0});
  178. },config.delayTime);
  179. this.setState({
  180. symptom:false,
  181. timer
  182. })
  183. }else{
  184. clearTimeout(this.state.timer);
  185. // 内容为空-清空搜索数据-显示常见
  186. clearSearch();
  187. // 慢病流程下常见会被清空,所以要重新获取
  188. if(CommonSymptoms.length == 0){
  189. getCommonSymptoms && getCommonSymptoms();
  190. }
  191. this.setState({
  192. symptom:true
  193. })
  194. }
  195. // IE11聚焦时也会触发change事件,导致常见症状下拉出不来
  196. if(isIE() && data == '<br>'){
  197. this.setState({
  198. symptom:true
  199. })
  200. }
  201. /*clearTimeout(this.state.timer);
  202. const timer = setTimeout(function(){
  203. pushMessage && pushMessage(data);
  204. //调搜索接口 使用模板走EditableSpan里的搜索方法
  205. getSearchData && getSearchData({inpStr:data,boxMark:1,itemType:0});
  206. },config.delayTime);
  207. this.setState({
  208. timer
  209. });*/
  210. }
  211. //除主诉外 其他是否为空
  212. ifClear(){
  213. let baseList = store.getState();
  214. let jsonData = getAllDataList(baseList);
  215. let jsonStr = getAllDataStringList(baseList);
  216. let flg = ifOtherClear(jsonData,jsonStr,baseList);
  217. return flg;
  218. }
  219. handleBlur(e){//隐藏常见症状下拉、存自由输入的值
  220. const {freeText,saveText,datas,clearSearch,getSymptomFeature,currentData,saveChronic} = this.props;
  221. const that = this;
  222. let data = this.state.inpText;
  223. const inner = e.target.innerText || e.target.innerHTML ;console.log("触发了主诉失焦事件")
  224. //分词-现病史没有模板的时候才去获取
  225. if(inner.trim() && currentData&&currentData.length==0 && datas.length==0){
  226. getFeature(inner.replace('<br>','')).then((res)=>{
  227. if(res.data.code==0){
  228. const result = res.data.data;
  229. // 慢病
  230. if(result && result[0].chronicLabel==1){
  231. let flg = this.ifClear();
  232. if(!flg){
  233. saveChronic && saveChronic(result[0]);
  234. }
  235. }else{
  236. getSymptomFeature && getSymptomFeature(result);
  237. }
  238. }
  239. })
  240. }
  241. if(!isIE()){
  242. // inner?(e.target.innerText=""):(e.target.innerHTML="")
  243. e.target.innerText?(e.target.innerText=""):(e.target.innerHTML="");
  244. freeText && freeText(data.trim().replace('<br>',''));
  245. }else{
  246. if(datas.length==0){
  247. const ev = e || window.event;
  248. const data = ev.target.innerText || ev.target.innerHTML;
  249. // freeText && freeText(data.trim());
  250. freeText && freeText(data);
  251. }
  252. }
  253. // 延时关闭常见症状下拉、清空搜索结果,不延时会影响选中
  254. /* const clearTimer = setTimeout(function(){
  255. clearSearch && clearSearch();
  256. clearTimeout(clearTimer);
  257. },config.delayTime-200); */
  258. }
  259. /*componentWillReceiveProps(nextProps){ //主诉高度变化不会出现滚动内容看不见的情况,因为已经是最顶部,所以可以不必更新滚动条
  260. const contHeightDiff = nextProps.data&&this.props.data&&nextProps.data.length!==this.props.data.length;
  261. const dataDiff = !!nextProps.data!==!!this.props.data;
  262. if(contHeightDiff||dataDiff){
  263. this.context.scrollArea.refresh();
  264. }
  265. }*/
  266. render(){
  267. const {saveChronic,readMode,type,CommonSymptoms,searchData,fetchPushInfos,isRead,totalHide,handleInput,fuzhen,saveText,editClear,datas,commSymHide} = this.props;
  268. const {symptom,boxLeft,boxTop} = this.state;
  269. const symptomFlag = CommonSymptoms.length>0 ? true : false;
  270. const searchFlag = searchData.length>0 ? true : false;
  271. const boxTop1 = datas.length>0?boxTop:45;
  272. const boxLeft1 = datas.length>0?boxLeft:85;
  273. const mode = readMode===null||readMode===-1?type:readMode;
  274. if(+mode===1){ //文本模式
  275. return <Textarea title='主诉' boxMark='1' saveChronic={saveChronic} isRead={isRead} value={saveText[0]} handlePush={fetchPushInfos} handleInput={handleInput} />;
  276. }
  277. return <div className={style['main-suit']}>
  278. <ItemBox
  279. fuzhen={fuzhen}
  280. title='主诉'
  281. editable={editClear||datas.length==0?true:false}
  282. boxLineHeight="24px"
  283. handleFocus={this.handleFocus}
  284. onchange={this.handleChange}
  285. handleClick={this.handleClick}
  286. handleBlur={this.handleBlur}
  287. data={datas}
  288. boxId="mainSuit">
  289. {datas.length>0?<div style={{display:'inline-block'}}>{this.getInlineTag()}</div>:(saveText[0]?saveText[0]:'')}
  290. </ItemBox>
  291. {/*没有推送结果就不显示*/}
  292. {symptomFlag && !searchFlag ? <CommonSymptom data={CommonSymptoms} show={!totalHide&&symptom} onSelect={this.handleSelect} /> : ( searchFlag ? <SearchDrop data={searchData} show={!commSymHide} onSelect={this.handleSearchSelect} left={boxLeft1} top={boxTop1} mainEmpty={datas.length==0?true:false}/>:"")}
  293. </div>
  294. }
  295. }
  296. /*MainSuit.contextTypes = {
  297. scrollArea: React.PropTypes.object
  298. };*/
  299. export default MainSuit;