Symptom.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. <template>
  2. <div class="symp-wrap symper btscroll">
  3. <div class="content">
  4. <div
  5. class="choose"
  6. v-if="chooseSymp.length>0"
  7. >
  8. <p class="quest">已选症状</p>
  9. <p
  10. class="choo-symp"
  11. v-for="(v,i) in chooseSymp"
  12. >
  13. <span @click="showChecked(v,i)">{{v.description || v.name}}</span>
  14. <span @click="deletSymp(v,i)"><img
  15. src="../images/del.png"
  16. alt=""
  17. ></span>
  18. </p>
  19. </div>
  20. <div class="label">
  21. <p class="quest" id="test">{{quesText}}<img
  22. @click="search(true)"
  23. class="searchImg"
  24. src="../images/search.png"
  25. alt=""
  26. ></p>
  27. <div class="showHide" ref="showHide">
  28. <span
  29. class="symp"
  30. v-for="(it,ind) in symp"
  31. :key="it.conceptId"
  32. @touchstart.prevent="touchstart(it,ind)"
  33. @touchend.prevent="touchend(it,ind)"
  34. >{{it.description || it.name}}</span>
  35. </div>
  36. <p class="tip" v-show="chooseSymp.length==0">长按症状按钮可显示症状解释说明 <span @click="slideToggle" v-show="slide">{{slideTxt}}</span></p>
  37. </div>
  38. <div
  39. class="result"
  40. v-if="checkText.length>0"
  41. >
  42. <p class="title"><span class="line"></span>{{nameStr}}</p>
  43. <div class="bgResult">
  44. <template v-for="(value,index) in checkText">
  45. <!-- 患者于时间单位前诱因出现症状,其余题目的内容; -->
  46. <span :key="index" v-if="index==0">{{(value.idx==1?'':'伴')+value.textP}}{{checkText.length==1?'':','}}</span>
  47. <span :key="index" v-if="index==1">{{(checkText[0].idx == 1?'伴':'')+value.textP}}{{checkText.length==2?'':'、'}}</span>
  48. <span :key="index" v-if="index>1">{{value.textP}}{{index == checkText.length-1?'':'、'}}</span>
  49. </template>
  50. </div>
  51. </div>
  52. </div>
  53. <div v-if="modluesLen>1"
  54. @click="toNext"
  55. class="footer"
  56. >
  57. <div class="nextBtn" :class="{'nofoot':chooseSymp.length==0}">下一步</div>
  58. </div>
  59. <div v-if="modluesLen==1"
  60. class="footer"
  61. @click="toNext"
  62. >
  63. <div class="nextBtn" :class="{'nofoot':chooseSymp.length==0}">预览并提交病历</div>
  64. </div>
  65. <Toast
  66. :message="delText"
  67. :show="showToast"
  68. @comfirn="comfirnDel"
  69. @cancel="cancelDel"
  70. />
  71. <Search
  72. v-if="this.$store.state.searchShow"
  73. @search="search"
  74. @showDetil="showDetil"
  75. :age="age"
  76. :chooseSymp="chooseSymp"
  77. :sexType="sexType"
  78. ></Search>
  79. <Tiptoast :show="showExp" :data="message" @close="closeTip"/>
  80. </div>
  81. </template>
  82. <script type="text/javascript">
  83. import api from '@utils/api.js';
  84. import Toast from '../common/Toast.vue';
  85. import Tiptoast from '../common/Tiptoast.vue';
  86. import Search from './Search.vue';
  87. import {moduleCP,setScroll,trimDots} from '@utils/tools'
  88. import BScroll from 'better-scroll';
  89. import $ from 'jquery';
  90. export default {
  91. name: 'Symptom',
  92. props:['modluesLen','nameStr'],
  93. data() {
  94. let { datas, pathInfo,searchShow } = this.$store.state;
  95. const { choose, text } = this.$store.state.symptom;
  96. return {
  97. age: pathInfo.patientAge,
  98. sexType: pathInfo.patientSex == '男' ? 1 : (pathInfo.patientSex == '女' ? 2 : 3),
  99. deptName: pathInfo.selfDeptName,
  100. hosCode: pathInfo.hospitalCode,
  101. chooseSymp: choose, //已选症状
  102. symp: [], //症状
  103. labelDetail: {}, //明细
  104. checkText: text, //症状情况文字
  105. questId: null, //id
  106. delText: "是否删除该信息?<br/>(已填内容将清除)",
  107. delIndex: null,
  108. showToast: false,
  109. searchShow: searchShow,//显示搜索界面
  110. tmpItem:{},//检索的症状
  111. isSearch:false,
  112. scroll:null,
  113. quesText:"请问您这次哪里最不舒服?",
  114. startTime:'',
  115. timer:null,
  116. showExp:false,
  117. message:{
  118. title:'',
  119. text:''
  120. },
  121. start:{},
  122. end:{},
  123. slide:false,
  124. slideTxt:'展开',
  125. staticSymp:[]
  126. }
  127. },
  128. created() {
  129. if (this.chooseSymp.length > 0) {
  130. this.quesText = "请问您还有其他不适吗?";
  131. // 推送
  132. const sympText = this.getSympText();
  133. this.getPush(sympText);
  134. } else {
  135. this.getSympList(); //常见
  136. }
  137. },
  138. mounted(){
  139. this.$nextTick(()=>{
  140. let scroll = setScroll(BScroll,true,'.symper')
  141. this.scroll = scroll
  142. scroll.on('scroll', this.onScroll)
  143. })
  144. },
  145. watch:{
  146. checkText:{//更新推送
  147. handler(newVal,oldVal){
  148. const sympText = this.getSympText();
  149. if(sympText){
  150. if(this.chooseSymp.length>1){
  151. this.getPush(sympText);
  152. }
  153. this.quesText = "请问您还有其他不适吗?";
  154. }else{
  155. this.getSympList();
  156. this.quesText = "请问您这次哪里最不舒服?";
  157. }
  158. },
  159. deep:true
  160. }
  161. },
  162. methods: {
  163. slideToggle(){
  164. let flg = this.slideTxt
  165. if(flg == '展开'){
  166. this.$refs.showHide.style.height = 'auto'
  167. this.slideTxt = '收起'
  168. }else{
  169. this.$refs.showHide.style.height = '3rem'
  170. this.slideTxt = '展开'
  171. }
  172. },
  173. touchend(item,flg) {//症状点开详情
  174. clearTimeout(this.timer);
  175. this.end = this.$store.state.scroll
  176. if(JSON.stringify(this.start) != JSON.stringify(this.end)){
  177. return
  178. }
  179. let endTime = +new Date();
  180. if(endTime - this.startTime < 500){//点击事件
  181. if(this.chooseSymp.length == 0){
  182. item.idx = 1
  183. }
  184. this.common(item,flg);
  185. this.slideTxt = '展开'
  186. }
  187. this.startTime = "";
  188. },
  189. touchstart(it){
  190. this.start = this.$store.state.scroll
  191. this.startTime = +new Date();
  192. const that = this;
  193. this.timer = setTimeout(function(){
  194. // 长按事件
  195. that.showExp = true;
  196. if(it.explains){
  197. that.message.title = it.description || it.name;
  198. that.message.text = it.explains;
  199. }else{
  200. that.message.title = "";
  201. that.message.text = "暂无资料";
  202. }
  203. },600)
  204. },
  205. closeTip(){
  206. this.showExp = false,
  207. this.message.title = '';
  208. this.message.text = '';
  209. },
  210. onScroll(data) {
  211. this.$store.commit('setScroll', data);
  212. document.activeElement.scrollIntoViewIfNeeded(true);
  213. },
  214. search(flg) {
  215. this.$store.commit('setSearchShow', flg);
  216. },
  217. getSympList() {
  218. const param = {
  219. "age": this.age,
  220. "deptName": this.deptName,
  221. "sexType": this.sexType
  222. }
  223. api.getSymptom(param).then((res) => {
  224. const result = res.data;
  225. if (result.code == 0) {
  226. this.symp = result.data;
  227. if(result.data.length>9){
  228. this.slide = true
  229. }else{
  230. this.slide = false
  231. }
  232. }
  233. })
  234. },
  235. toNext() {
  236. // 把1切换成完成图标,且2高亮--判断有几个模块显示,1个--提交预览;1个以上--下一步
  237. if (this.chooseSymp.length == 0) { return }
  238. // 把症状情况的数据存起-已选
  239. this.$store.commit('setChoose', { choose: this.chooseSymp, type: moduleCP['symp'] });
  240. if(this.modluesLen==1){
  241. this.$emit('next','preview')
  242. }else{
  243. this.$emit('next');
  244. }
  245. },
  246. common(item,flg){
  247. if(this.chooseSymp.length>12){
  248. this.$store.commit('setSearchShow', false);
  249. return
  250. }
  251. this.questId = item.questionId || item.id || item.conceptId;
  252. const id = item.questionId || item.id; //常见症状questionId,推送id,两者均有可能没有
  253. //将选中的name存到store中的text
  254. if (id&&this.chooseSymp.length == 0) {//只有第一次
  255. const param = {
  256. "age": this.age,
  257. "id": id,
  258. "sexType": this.sexType
  259. }
  260. api.getById(param).then((res) => {
  261. const result = res.data;
  262. if (result.code == 0) {
  263. const mapping = result.data.questionMapping;
  264. this.labelDetail = result.data;
  265. if(this.chooseSymp.length == 0){
  266. result.data.idx = 1
  267. this.$store.commit('setText', { type: moduleCP['symp'], text: '患者出现'+item.name,textP: '患者出现'+(item.description||item.name), pId: this.questId,idx:flg });
  268. }else{
  269. this.$store.commit('setText', { type: moduleCP['symp'], text: item.name,textP: item.description||item.name, pId: this.questId,idx:flg });
  270. }
  271. this.$store.commit('setOrigin', { type: moduleCP['symp'], data: result.data });
  272. if (mapping && mapping.length > 0) {
  273. for(let i = 0;i < mapping.length;i++){
  274. if(mapping[i].flag == 3){
  275. this.staticSymp = mapping[i].questionDetailList
  276. }
  277. }
  278. this.$store.commit('setDetail',{detail:result.data,ppId:null,moduleType:moduleCP['symp'],sign:1,idx:this.chooseSymp.length})
  279. this.$store.commit('setSearchShow', false);
  280. this.chooseSymp.push(item);
  281. } else {
  282. this.chooseSymp.push(item);
  283. this.$store.commit('setSearchShow', false);
  284. }
  285. const sympText = this.getSympText();
  286. this.getPush(sympText);
  287. }
  288. }).catch(()=>{
  289. if(this.chooseSymp.length == 1){
  290. const sympText = this.getSympText();
  291. this.getPush(sympText);
  292. }
  293. })
  294. } else {//没有questionId或id
  295. if(this.chooseSymp.length == 0){
  296. item.idx = 1
  297. this.$store.commit('setText', { type: moduleCP['symp'], text: '患者出现'+item.name,textP: '患者出现'+(item.description||item.name), pId: this.questId,idx:flg });
  298. }else{
  299. this.$store.commit('setText', { type: moduleCP['symp'], text: item.name,textP: item.description||item.name, pId: this.questId,idx:flg });
  300. }
  301. this.chooseSymp.push(item);
  302. const sympText = this.getSympText();
  303. this.getPush(sympText);
  304. // this.checkText = this.$store.state.symptom.text;
  305. }
  306. },
  307. showDetil(item,flg) {//搜索点开的详情
  308. this.tmpItem=item
  309. this.isSearch=flg||false
  310. this.common(item,flg,this.chooseSymp);
  311. },
  312. getSympText() {//推送使用医生端信息
  313. const text = this.$store.state.symptom.text;
  314. let msg = "";
  315. for (let i in text) {
  316. if(text[i] && text[i].text){
  317. msg += text[i].text;
  318. }
  319. }
  320. return trimDots(msg);
  321. },
  322. getPush(symptoms) {//推理
  323. const param = {
  324. "age": this.age,
  325. "hosCode": this.hosCode,
  326. "sex": this.sexType,
  327. "symptom": symptoms //症状+选择的明细,string
  328. }
  329. api.getPush(param).then((res) => {
  330. const result = res.data;
  331. if (result.code == 0) {
  332. let symp = result.data.symptom;
  333. let symped = JSON.parse(JSON.stringify(this.chooseSymp));//已选症状
  334. let sympStic = JSON.parse(JSON.stringify(this.staticSymp));//首次有无症状
  335. let sympAll = sympStic.concat(symp);
  336. var obj = {};
  337. sympAll = sympAll.reduce(function(item, next) {
  338. obj[next.name] ? '' : obj[next.name] = true && item.push(next);
  339. return item;
  340. }, []);
  341. // console.log(sympAll,symped)
  342. for(let i = 0;i < sympAll.length;i++){//去掉已选的已选症状
  343. for(let j = 0;j < symped.length;j++){//去掉
  344. if(symped[j].name == sympAll[i].name){
  345. sympAll.splice(i,1)
  346. }
  347. }
  348. }
  349. this.symp = sympAll.slice(0,12);
  350. // this.symp = symp;
  351. this.$refs.showHide.style.height = 'auto'
  352. }
  353. }).catch(()=>{
  354. })
  355. },
  356. deletSymp(item, index) {
  357. this.delIndex = index;
  358. this.questId = item.questionId || item.id || item.conceptId;
  359. if (this.chooseSymp.length == 1) {
  360. this.delText = "是否删除该信息?<br/>删除后将重新填写预问诊流程 <br/>(已填内容将清除)"
  361. }
  362. this.showToast = true;
  363. $(".btscroll").css({'position':'fixed'})
  364. $(".foot").css({'position':'fixed','bottom':'0'})
  365. },
  366. comfirnDel() {
  367. $(".btscroll").css({'position':'absolute','top':'0'})
  368. $(".foot").css({'position':'absolute','bottom':'0'})
  369. this.chooseSymp.splice(this.delIndex, 1);
  370. this.checkText.splice(this.delIndex, 1);
  371. this.$store.commit('delText', { type: moduleCP['symp'], pId: this.questId })
  372. // 删除setDatas数据,防止回读
  373. this.$store.commit('setDatas', { type: moduleCP['symp'], pId: this.questId ,data:''})
  374. // 删除完-常见;其他-推送
  375. if (this.chooseSymp.length > 0) {
  376. } else {
  377. // 全部删除完 重新走问诊流程
  378. // this.$router.push("/")
  379. // this.$router.replace({path:'/'})
  380. // 停留在当前页 8-19
  381. this.quesText = "请问您这次哪里最不舒服?";
  382. this.getSympList();
  383. }
  384. this.cancelDel();
  385. },
  386. cancelDel() {
  387. $(".btscroll").css({'position':'absolute','top':'0'})
  388. $(".foot").css({'position':'absolute','bottom':'0'})
  389. this.showToast = false;
  390. this.delIndex = null;
  391. this.questId = null;
  392. this.delText = "是否删除该信息?<br/>(已填内容将清除)";
  393. },
  394. showChecked(item,i) {
  395. const origin = this.$store.state.symptom.origin;
  396. const read = this.$store.state.symptom.datas;
  397. const data = read[(item.questionId||item.id)] || origin[(item.questionId||item.id)];
  398. if (data&&data.questionMapping && data.questionMapping.length > 0) {
  399. this.$store.commit('setDetail',{detail:data,ppId:null,moduleType:moduleCP['symp'],sign:1,idx:i})
  400. }
  401. },
  402. },
  403. components: {
  404. Toast,
  405. Search,
  406. Tiptoast
  407. }
  408. }
  409. </script>
  410. <style lang="less" scoped>
  411. @import "../less/base.less";
  412. .showHide {
  413. overflow: hidden;
  414. height: 3rem;
  415. }
  416. .tip span {
  417. color: #colors[theme];
  418. float: right;
  419. font-size: .28rem;
  420. }
  421. .symp-wrap {
  422. font-size: 0.3rem;
  423. .quest {
  424. color: #colors[quest];
  425. margin-bottom: 0.36rem;
  426. font-weight: 700;
  427. .searchImg {
  428. width: 0.44rem;
  429. height: 0.44rem;
  430. float: right;
  431. }
  432. }
  433. }
  434. .choose{
  435. padding-bottom: .2rem;
  436. .choo-symp{
  437. display: inline-block;
  438. min-width:2rem;
  439. height: .74rem;
  440. background: #colors[btn];
  441. border-radius: .08rem;
  442. white-space: nowrap;
  443. margin: 0 .25rem .3rem 0;
  444. span{
  445. display: inline-block;
  446. vertical-align: top;
  447. }
  448. span:first-child{
  449. min-width:1.42rem;
  450. height: .74rem;
  451. line-height: .74rem;
  452. text-align: center;
  453. color: #fff;
  454. }
  455. img{
  456. width:.48rem;
  457. height: .74rem;
  458. }
  459. }
  460. .choo-symp:last-child{
  461. margin-right: 0;
  462. }
  463. .label{
  464. .label;
  465. }
  466. .result{
  467. padding-right: .3rem;
  468. // .title{
  469. // color: #colors[btn];
  470. // padding-left: .1rem;
  471. // margin-bottom: .19rem;
  472. // font-weight: 700;
  473. // }
  474. p{
  475. color: #666;
  476. line-height: .44rem;
  477. }
  478. }
  479. .footer{
  480. .footer;
  481. }
  482. }
  483. .label{
  484. .label;
  485. }
  486. .result{
  487. .result;
  488. }
  489. .footer{
  490. .footer;
  491. }
  492. .nofoot{
  493. background:#CACCFF!important;
  494. }
  495. </style>