luolei 5 лет назад
Родитель
Сommit
a4e0219790

+ 1 - 1
build/webpack.dev.conf.js

@@ -34,7 +34,7 @@ const devWebpackConfig = merge(baseWebpackConfig, {
     compress: true,
     // host: HOST || config.dev.host,
     // host: '192.168.3.6',
-    host: '192.168.162.1',
+    host: '192.168.1.103',
     port: PORT || config.dev.port,
     open: config.dev.autoOpenBrowser,
     overlay: config.dev.errorOverlay

+ 27 - 6
src/common/CheckBox.vue

@@ -1,14 +1,14 @@
 <template>
-  <div class="check-wrap" v-if="item">
+  <div class="check-wrap" v-if="item" :style="{'display':slide?'block':'none'}">
     <!-- <p v-for="(it,index) in datas.questionDetailList" :key="it.id" class="list" @click="handleClick(it,index,'',true)"> -->
       <p v-for="(it,index) in datas.questionDetailList" :key="it.id" :class="['list',{'block':((it.description||it.name).indexOf('${'))!=-1}]" @click="handleClick(it,index,'',true)">
-      <img :src="it.select==1?check:defaultPic">
-      <span v-if="((it.description||it.name).indexOf('${'))==-1" :class="[{'check':it.select==1},{'exclu':exclusion !==999 && it.exclusion !== exclusion}]">{{it.description||it.name}}</span>
+      <!-- <img :src="it.select==1?check:defaultPic"> -->
+      <span v-if="((it.description||it.name).indexOf('${'))==-1" :class="['radioCheck',{'check':it.select==1},{'exclu':exclusion !==999 && it.exclusion !== exclusion}]">{{it.description||it.name}}</span>
       <OptionInp v-else 
           :item="it" 
           ref="inp"
           @handleInp="inpVal($event,index)" 
-          @handleSelec="handleClick(it,index,true)"
+          @handleSelec="handleClick(it,index,true,1)"
           :exclu="exclusion !==999 && it.exclusion !== exclusion" 
           />
     </p>
@@ -22,6 +22,15 @@ import MultiLineInput from '../common/MultiLineInput.vue';
 import OptionInp from '../common/OptionInp.vue';
   export default{
     name:'CheckBox',
+    props:{
+      item:{
+        default:''
+      },
+      slide:{
+        default:false,
+        type:Boolean
+      }
+    },
     data(){
       return{
         imgUrl:imageUrlPrefix,
@@ -31,7 +40,6 @@ import OptionInp from '../common/OptionInp.vue';
         exclusion:999 //互斥
       }
     },
-    props:['item'],
     created(){
       // this.datas = JSON.parse(JSON.stringify(this.item));
       this.datas = this.item;
@@ -127,6 +135,7 @@ import OptionInp from '../common/OptionInp.vue';
 <style lang="less" scoped>
 @import '../less/base.less';
   .check-wrap{
+    .bgques;
     img{
       width:100%;
     }
@@ -136,7 +145,7 @@ import OptionInp from '../common/OptionInp.vue';
     .list{
       color: #colors[text];
       margin:0 .1rem .1rem 0;
-      padding: .12rem .1rem;
+      padding: .12rem .1rem .12rem 0;
       display: inline-block;
       white-space: nowrap;
       overflow-x: hidden;
@@ -149,8 +158,20 @@ import OptionInp from '../common/OptionInp.vue';
         vertical-align: middle;
       }
     }
+    .radioCheck {
+      display: inline-block;
+      line-height: .52rem;
+      min-width: 2rem;
+      text-align: center;
+      padding:.1rem .1rem;
+      box-sizing: border-box;
+      border-radius: .38rem;
+      border: 1px solid #DFE0E4;
+    }
+    
     .check{
       color: #colors[theme];
+      border: 1px solid #colors[theme];
     }
     .exclu{
       color:#colors[exclu];

+ 7 - 2
src/common/ComTextArea.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="comArea">
+  <div class="comArea" :style="{'display':slide?'block':'none'}">
     <textarea @input="changeVal" 
             :style="{width:width,height:height}" 
             v-model="txt" 
@@ -26,6 +26,10 @@ export default {
     item:{
       type:Object,
       require: true
+    },
+    slide:{
+      default:false,
+      type:Boolean
     }
   },
   data() {
@@ -66,7 +70,9 @@ export default {
 }
 </script>
 <style lang="less" scoped>
+@import '../less/base.less';
   .comArea {
+    .bgques;
     textarea {
       color: #4F50FF;
       resize: none;
@@ -77,7 +83,6 @@ export default {
       border-radius: .08rem /* 8/100 */;
       -webkit-appearance: none;
       padding: .16rem /* 16/100 */ .3rem /* 30/100 */;
-      margin-bottom: .3rem;
       background-color: transparent;
     }
   }

+ 10 - 2
src/common/Input.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="inp-wrap">
+  <div class="inp-wrap" :style="{'display':slide?'block':'none'}">
     <input :type="item.controlType==6?'text':'number'" 
           :maxlength="item.controlType==6?'':10"
           :class="{'change':borColor}" 
@@ -14,6 +14,15 @@
   import $ from 'jquery';
   export default {
     name:'Input',
+    props:{
+      item:{
+        default:''
+      },
+      slide:{
+        default:false,
+        type:Boolean
+      }
+    },
     data(){
       return{
         msg:"输入框",
@@ -21,7 +30,6 @@
         borColor:false
       }
     },
-    props:['item'],
     methods:{
       changeVal(e){
         this.borColor = true;

+ 7 - 3
src/common/MultiLineInput.vue

@@ -1,5 +1,5 @@
 <template>
-  <div :class="['multipIpt',{'border':border,'inline':inline,'check':select}]">
+  <div :style="{'margin-bottom':isLast?'0':'.3rem'}" :class="['multipIpt',{'border':border,'inline':inline,'check':select}]">
     <span class="prefix" v-if="content.prefix">{{content.prefix}}</span>
     <div class="sticP" :style="{paddingRight:content.suffix?'1rem':'0'}">
         <div class="iptWrap">
@@ -57,7 +57,11 @@ export default {
     select:{ //是否选中
       default:false,
       type:Boolean
-    }
+    },
+    isLast:{ //是否为最后一个
+      default:false,
+      type:Boolean
+    },
   },
   data(){
     return {
@@ -130,7 +134,7 @@ export default {
     padding: 0 .12rem 0 .26rem;
     box-sizing: border-box;
     position: relative;
-    margin: .3rem 0;
+    margin-bottom: .3rem;
     .contentVal {
       font-size: .3rem /* 30/100 */;
       color: #colors[theme];

+ 3 - 3
src/common/OptionInp.vue

@@ -1,6 +1,6 @@
 <!-- 带输入框选项 -->
 <template>
-  <div :class="['inpbox',{'check':item.select},{'exclu':exclu}]">
+  <div :class="['inpbox',{'iptCheck':item.select},{'exclu':exclu}]">
     <span class="prefix" v-if="msg.prefix">{{msg.prefix}}</span>
     <!-- <div class="inp" @click="preClick"> -->
       <input :type="msg.type=='number'?'number':'text'" 
@@ -41,10 +41,10 @@ import $ from 'jquery';
         if(this.msg.type=='number'){//数字键盘
           this.txt = e.target.value=e.target.value.replace(/^\.$/,'')
         }
-        
         const newData = Object.assign({},this.part,{value:this.txt});
         this.$emit("updata",newData);
         this.$emit('handleInp',this.txt);
+        this.$emit('handleSelec');
       },
       handleBlur(){
           // $(".btscroll").css({'position':'fixed'})
@@ -72,7 +72,7 @@ import $ from 'jquery';
       handleCli(e){
         e.stopPropagation();
         // const select = this.item.select;
-        if(!this.select){//聚焦时自动选中该项
+        if(!this.select&&this.txt){//聚焦时自动选中该项
           this.$emit('handleSelec');
         } 
       }

+ 18 - 8
src/common/PickTime.vue

@@ -1,16 +1,27 @@
 <!-- 时间类型控件 -->
 <template>
-  <div class="toast-wrap">
-    <p v-show="val" :class="['ptab',{'check':val != '请选择'}]" @click="showPicker">{{val}}</p>
-    <p v-show="val != '请选择'" class="tip">点击可修改</p>
-    <Picker ref="picker" :show="showTime" @comfirn="getTimeVal" @cancel="close" :picIndex="picIndex"/>
-  </div> 
+  <!-- <transition name="fade"> -->
+    <div :style="{'display':slide?'block':'none'}" class="toast-wrap">
+      <p v-show="val" :class="['ptab',{'check':val != '请选择'}]" @click="showPicker">{{val}}</p>
+      <p v-show="val != '请选择'" class="tip">点击可修改</p>
+      <Picker ref="picker" :show="showTime" @comfirn="getTimeVal" @cancel="close" :picIndex="picIndex"/>
+    </div> 
+  <!-- </transition> -->
 </template>
 <script type="text/javascript">
   import $ from 'jquery';
   import Picker from './Picker.vue';
   export default {
     name:'PickTime',
+    props:{
+      item:{
+        default:''
+      },
+      slide:{
+        default:false,
+        type:Boolean
+      }
+    },
     data() {
       return {
         val:this.item.value || '请选择',
@@ -18,7 +29,6 @@
         picIndex:this.item.pickIndex||[]
       }
     },
-    props:['item'],
     methods: {
       showPicker(){
         this.showTime = true;
@@ -61,16 +71,16 @@
 <style lang="less" scoped>
   @import '../less/base.less';
   .toast-wrap{
-    margin-bottom: .2rem;
     position: relative;
     z-index: 116;
+    .bgques;
     .ptab{
       width:100%;
       height: .8rem;
       line-height: .8rem;
       text-align: center;
       border:1px solid #E6E6E6;
-      border-radius: .1rem;
+      border-radius: .4rem;
       color:#7C828E;
     }
     .check{

+ 47 - 13
src/common/Radio.vue

@@ -1,10 +1,10 @@
 <template>
-  <div class="radio-wrap" v-if="item">
+  <div class="radio-wrap bgques" v-if="item" :style="{'display':slide?'block':'none'}">
     <!-- <p v-for="(it,index) in datas.questionDetailList" :key="it.id" class="list" @click="handleClick(it,index,true)"> -->
-    <p v-for="(it,index) in datas.questionDetailList" :key="it.id" :class="['list',{'block':((it.description||it.name).indexOf('${'))!=-1}]" @click="handleClick(it,index,true)">
-      <img :src="it.select==1?check:defaultPic">
-      <span v-if="((it.description||it.name).indexOf('${'))==-1" :class="{'check':it.select==1}">{{it.description||it.name}}</span>
-      <OptionInp v-else :item="it" @handleInp="inpVal($event,index)" @handleSelec="handleClick(it,index)"/>
+    <p v-for="(it,index) in datas.questionDetailList" :key="it.id" :class="['list',{'block':((it.description||it.name).indexOf('${'))!=-1}]">
+      <!-- <img :src="it.select==1?check:defaultPic"> -->
+      <span v-if="((it.description||it.name).indexOf('${'))==-1" :class="['radioCheck',{'check':it.select==1}]" @click="handleClick(it,index,true)">{{it.description||it.name}}</span>
+      <OptionInp v-else :item="it" @handleInp="inpVal($event,index)" @handleSelec="handleClick(it,index,false,true)"/>
     </p>
   </div>
 </template>
@@ -16,6 +16,15 @@ import MultiLineInput from '../common/MultiLineInput.vue';
 import OptionInp from '../common/OptionInp.vue';
   export default{
     name:'Radio',
+    props:{
+      item:{
+        default:''
+      },
+      slide:{
+        default:false,
+        type:Boolean
+      }
+    },
     data(){
       return{
         defaultPic:icon,
@@ -24,13 +33,12 @@ import OptionInp from '../common/OptionInp.vue';
         imgUrl:imageUrlPrefix,
       }
     },
-    props:['item'],
     created(){
       // this.datas = JSON.parse(JSON.stringify(this.item));
       this.datas = this.item;
     },
     methods:{
-      handleClick(it,index,flg){
+      handleClick(it,index,flg,ipt){
         if(flg){
           document.activeElement.blur();      
           document.activeElement.scrollIntoViewIfNeeded(true);
@@ -39,11 +47,22 @@ import OptionInp from '../common/OptionInp.vue';
           },300)
         }
         const list = this.datas;
-        let data = list.questionDetailList&&list.questionDetailList.slice(0); //数组深拷贝?
-        for(let i=0;i<data.length; i++){
-          data[i].select = 0
-          if(i==index){
-            data[i].select = 1;
+        let data = list.questionDetailList&&list.questionDetailList.slice(0); //数组深拷贝
+        if(ipt){//输入框单选,输入了内容才算选中,删除内容算取消
+          for(let i=0;i<data.length; i++){
+            if(i==index){
+              data[i].select=data[i].value?1:0;
+            }else{
+              data[i].select = 0
+            }
+          }
+        }else{
+          for(let i=0;i<data.length; i++){
+            if(i==index){
+              data[i].select = data[i].select==1?0:1;
+            }else{
+              data[i].select = 0
+            }
           }
         }
         let temp = concatVal(data);
@@ -79,6 +98,7 @@ import OptionInp from '../common/OptionInp.vue';
 <style lang="less" scoped>
 @import '../less/base.less';
   .radio-wrap{
+    .bgques;
     img{
       width:100%;
     }
@@ -88,7 +108,7 @@ import OptionInp from '../common/OptionInp.vue';
     .list{
       color: #colors[text];
       margin:0 .1rem .1rem 0;
-      padding: .12rem .1rem;
+      padding: .12rem .1rem .12rem 0;
       display: inline-block;
       white-space: nowrap;
       overflow-x: hidden;
@@ -102,8 +122,22 @@ import OptionInp from '../common/OptionInp.vue';
         white-space: normal;
         vertical-align: middle;
       }
+      .radioCheck {
+        display: inline-block;
+        line-height: .52rem;
+        min-width: 2rem;
+        text-align: center;
+        padding:.1rem .1rem;
+        box-sizing: border-box;
+        border-radius: .38rem;
+        border: 1px solid #DFE0E4;
+      }
       .check{
         color: #colors[theme];
+        border: 1px solid #colors[theme];
+      }
+      .iptCheck {
+        color: #colors[theme];
       }
     }
   }

+ 12 - 3
src/common/RadioSelect.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="radio-wrap radioSelect" v-if="item">
+  <div class="radio-wrap radioSelect" v-if="item" :style="{'display':slide?'block':'none'}">
     <p class="please">请尽量选择其他不适症状</p>
     <div class="list" @click="handleClickShow(1)" :class="[{'setColor':!!hasStr}]">
       <span>有:<i>{{hasStr?hasStr:'点击选择症状'}}</i></span>
@@ -32,6 +32,15 @@ import {patt,imageUrlPrefix,concatVal} from '@utils/tools.js'
 import SymptomLis from '../common/SymptomLis.vue';
   export default{
     name:'RadioSelect',
+    props:{
+      item:{
+        default:''
+      },
+      slide:{
+        default:false,
+        type:Boolean
+      }
+    },
     data(){
       return{
         defaultPic:icon,
@@ -45,7 +54,6 @@ import SymptomLis from '../common/SymptomLis.vue';
         hasStr:''
       }
     },
-    props:['item'],
     created(){
       // this.datas = JSON.parse(JSON.stringify(this.item));
       this.datas = this.item;
@@ -155,6 +163,7 @@ import SymptomLis from '../common/SymptomLis.vue';
 <style lang="less" scoped>
 @import '../less/base.less';
   .radio-wrap{
+    .bgques;    
     .setColor {
       color: #4F50FF!important;
     }
@@ -163,7 +172,7 @@ import SymptomLis from '../common/SymptomLis.vue';
     }
     .list{
       color: #colors[text];
-      margin:0 .1rem .2rem 0;
+      margin-bottom: .2rem;
       padding: .12rem .1rem;
       background-color: #f5f5f5;
       white-space: nowrap;

+ 4 - 0
src/common/SymptomLis.vue

@@ -6,6 +6,7 @@
                 <div v-for="(it,index) in selectLis" :key="it.id" :class="['text', {'select':it.select==1}]" v-if="it.flg==undefined||it.flg==flg" @click="select(index)">
                   {{it.description||it.name}}
                 </div>
+                <p class="noData">暂无数据</p>
               </div>
               <div class="makeSure" @click="makeSure">确定</div>
             </div>
@@ -138,5 +139,8 @@ import {setScroll} from '@utils/tools.js';
       .mask;
       z-index: 999;
     }
+    .noData {
+      font-size: .28rem;
+    }
   }
 </style>

+ 22 - 17
src/common/Toast.vue

@@ -2,6 +2,7 @@
     <portal to="notification-outlet">
       <div class="toast-wrap" v-if="show">
             <div class="content">
+              <div class="title">温馨提示</div>
               <div class="text" v-html="message||msg">
                 <!-- {{message||msg}} -->
               </div>
@@ -41,47 +42,51 @@ import $ from 'jquery';
   .toast-wrap{
     .content{
       width: 6.3rem;
-      height: 3.52rem;
       background: #fff;
       z-index: 999;
-      // position: absolute;
       position: fixed;
       top:50%;
       left: 50%;
       transform: translate(-50%,-50%);
-      padding: .5rem;
+      padding: 0.6rem 0.5rem 1.5rem .5rem;
       box-sizing: border-box;
       border-radius: .2rem;
       z-index: 1000;
+      overflow: hidden;
+      .title {
+        font-size: .32rem;
+        text-align: center;
+        font-weight: 800;
+      }
       .text{
         color:#colors[quest];
         text-align: center;
-        height: 1.25rem;
-        // overflow-y: auto;
-        padding-top: .2rem;
+        padding-top: .4rem;
         font-size: .3rem;
       }
       .btn{
-        margin-top: .30rem;
-        padding: 0 .7rem;
         display: flex;
         justify-content: space-between;
+        position: absolute;
+        bottom: 0;
+        left: 0;
+        width: 6.3rem;
+        height: .9rem;
+        line-height: .9rem;
+        border-top: 1px solid #colors[line];
         span{
           display: inline-block;
-          width: 1.6rem;
-          height: .70rem;
-          line-height: .70rem;
+          width: 50%;
           text-align: center;
-          font-size: .30rem;
-          border-radius: .35rem;
+          font-size: .32rem;
         }
         .comf{
-          color:#F64B44;
-          border:2px solid rgba(246,75,68,1);
+          border-right: 1px solid #colors[line];
+          box-sizing: border-box;
+          color: #FF6167;
         }
         .canc{
-          color: #colors[theme];
-          border:2px solid rgba(79,80,255,1);
+          color: #colors[btn];
         }
       }
     }

+ 3 - 1
src/components/Department.vue

@@ -71,6 +71,8 @@
     }
 </script>
 <style lang="less" scoped>
+@import '../less/base.less';
+
     .department {
         font-size: .3rem;
         padding: .3rem 0 1rem 0;
@@ -86,7 +88,7 @@
             }
             .list {
                 background:rgba(255,255,255,1);
-                box-shadow:0px 3px 15px 0px rgba(217,217,217,0.5);
+                box-shadow:0px 3px 20px 0px rgba(192,187,224,0.23);
                 border-radius:.1rem;
                 overflow: hidden;
                 margin-bottom: .3rem;

+ 98 - 18
src/components/Detail.vue

@@ -1,43 +1,56 @@
 <template>
   <div class="detail-wrap">
     <!-- <div v-for="(item,index) in datas"> -->
-    <div v-for="(item,index) in checkDatas.questionMapping">
-      <p class="quest"><span v-show="item.required==1" style="color: red;">*</span>{{index + 1 +'.' + (item.description || item.name)}}</p>
-      <img class="questionImg" :src="item.url.replace('{imageUrlPrefix}',imgUrl)" v-if="item.url">
+    <div class="preQuestion" v-for="(item,index) in checkDatas.questionMapping">
+      <div class="quest" @click="slideToggle(index)">
+        <span style="color: red;">{{item.required==1?'*':''}}</span>
+        {{index + 1 +'.' + (item.description || item.name)}}
+        
+        <i :class="[{'slideT':item.slide}]"></i>
+      </div>
+      <img class="questionImg" :src="item.url.replace('{imageUrlPrefix}',imgUrl)" v-if="item.url&&!!item.slide">
       <Radio v-if="item.controlType==1" 
             :item="item"
             :key="item.id"
+            :slide="!!item.slide"
             @updata="updataData"/>
       <RadioSelect v-if="item.controlType==8" 
             :item="item"
+            :slide="!!item.slide"
             :key="item.id"
             @updata="updataData"/>
-      <CheckBox v-if="item.controlType==2" 
+      <CheckBox v-if="item.controlType==2"
             :item="item"
             :key="item.id"
+            :slide="!!item.slide"
             @updata="updataData"/>
       <!-- 文本域 -->
       <ComTextArea v-if="item.controlType == 5"
             :item="item"
+            :slide="!!item.slide"
             @updata="updataData"/>
       <!-- 输入框 -->
       <Input v-if="item.controlType==6 || item.controlType==7"
             :item="item"
             :key="item.id"
+            :slide="!!item.slide"
             @updata="updataData"/>
-      <template
-        v-if="item.controlType == 3"
-        v-for="(part,index) in item.questionDetailList"
-      >
-        <MultiLineInput
-          v-if="item.controlType == 3"
-          :msg="part.description||part.name"
-          :part="part"
-          @updata="updataData($event,item)"
-        ></MultiLineInput>
-      </template>
+      <div class="multiWrap" :style="{'display':!!item.slide?'block':'none'}" v-if="item.controlType == 3">
+        <template
+          v-for="(part,index) in item.questionDetailList"
+        >
+          <MultiLineInput
+            v-if="item.controlType == 3"
+            :msg="part.description||part.name"
+            :part="part"
+            :isLast="item.questionDetailList.length-1 == index"
+            @updata="updataData($event,item)"
+          ></MultiLineInput>
+        </template>
+      </div>
       <PickTime v-if="item.controlType == 9" 
               @updata="updataData"
+              :slide="!!item.slide"
               :item="item"/>
     </div>
   </div>
@@ -57,7 +70,7 @@ import {patt,trimDots,imageUrlPrefix} from '@utils/tools.js'
     data(){
       return{
         checkDatas:{},
-        imgUrl:imageUrlPrefix,
+        imgUrl:imageUrlPrefix
       }
     },
     props:['datas','data'],
@@ -74,6 +87,47 @@ import {patt,trimDots,imageUrlPrefix} from '@utils/tools.js'
       PickTime
     },
     methods:{
+      slideAll(){
+        let mapping = this.checkDatas.questionMapping;
+        let num = 0;
+        for(let i in mapping){
+          if(mapping[i].slide != 1){
+            ++num
+          }
+        }
+        if(num == mapping.length){//没有任何展开项
+          for(let i in mapping){
+            mapping[i].slide = 1
+          }
+          this.$emit('setBtnTxt','折叠全部')
+        }else{//有已经展开的了,就折叠已展开的
+          for(let i in mapping){
+            mapping[i].slide = 0
+          }
+          this.$emit('setBtnTxt','展开全部')
+        }
+        this.checkDatas = Object.assign({},this.checkDatas);
+      },
+      slideToggle(idx){
+        let mapping = this.checkDatas.questionMapping;
+        let num = 0;
+        for(let i in mapping){
+          if(i == idx){
+            mapping[i].slide = mapping[i].slide==1?0:1
+          }
+        }
+        for(let i in mapping){
+          if(mapping[i].slide != 1){
+            ++num
+          }
+        }
+        if(num == mapping.length){//没有任何展开项
+          this.$emit('setBtnTxt','展开全部')
+        }else{//有已经展开的了,就折叠已展开的
+          this.$emit('setBtnTxt','折叠全部')
+        }
+        this.checkDatas = Object.assign({},this.checkDatas);
+      },
       updataData(data,item){
         const origMapping = this.datas.questionMapping;
         let mapping = this.checkDatas.questionMapping;
@@ -256,14 +310,40 @@ import {patt,trimDots,imageUrlPrefix} from '@utils/tools.js'
 @import '../less/base.less';
   .detail-wrap{
     // padding: .3rem .5rem 1.2rem .6rem;
-    padding: .3rem .4rem 1rem ;
+    padding: 0 0 1.5rem;
     font-size: .3rem;
     .quest{
       color:#colors[quest];
-      margin-bottom: .2rem;
+      position: relative;
+      // margin-bottom: .2rem;
+      .pubques;
+      span {
+        display: inline-block;
+        position: relative;
+        left: -0.1rem;
+        width: .1rem;
+      }
+      i{
+        position: absolute;
+        right: .2rem;
+        top: 50%;
+        margin-top: -.16rem;
+        width: .32rem;
+        height: .32rem;
+        background: url("../images/slideT.png") no-repeat;
+        background-size: cover;
+        transition: all 0.03s;
+      }
+      .slideT {
+        transform: rotateZ(-180deg);
+        transform-origin: center center;
+      }
     }
     .questionImg {
       width: 100%;
     }
+    .multiWrap {
+      .bgques;
+    }
   }
 </style>

+ 34 - 12
src/components/DetailBox.vue

@@ -9,6 +9,7 @@
                   ref="detail"
                   :data="data"
                   @check="changeCheck($event)"
+                  @setBtnTxt="setBtnTxt($event)"
                   @checkReq="changeFins($event)"/>
         </div>
         <!-- <div class="foot" @click="complete">完成</div> -->
@@ -23,7 +24,10 @@
       </div>
     </div>
     <!-- <div :class="['foot',{'noCheck':!checkF}]" @click="complete">完成</div> -->
-    <div style="position:absolute" :class="['foot',{'noCheck':!checkF || !reqFinish}]" @click="complete">完成</div>
+    <div style="position:absolute" class="foot">
+      <div class="slide" @click="slideAll()">{{btnTxt}}</div>
+      <div class="nextBtn compete" :class="{'noCheck':!checkF || !reqFinish}" @click="complete">完成</div>
+    </div>
     <Toast :message="clearTxt" 
           :show="showToast"
           @comfirn="comfirnDel" 
@@ -48,11 +52,12 @@
         compFlag:false,
         clearTxt:"是否清空当前已选内容?",
         showToast:false,
-        tips:"请完成病情预问诊可让医生提前了解病情",
+        tips:"温馨提示:请完成病情预问诊可让医生提前了解病情",
         checkF:false, //详情页有无已选项标识
         show:detailShow,
         reqFinish:false,
-        showPic:false
+        showPic:false,
+        btnTxt:'展开全部'
       }
     },
     mounted(){
@@ -74,6 +79,12 @@
       })
     },
     methods:{
+      setBtnTxt(txt){
+        this.btnTxt = txt
+      },
+      slideAll(){
+        this.$refs.detail.slideAll();
+      },
       onScroll(data) {
         this.$store.commit('setScroll', data)
         document.activeElement.scrollIntoViewIfNeeded(true);        
@@ -170,14 +181,12 @@
     z-index: 110;
   }
   .tmpDom {
-    height: 1rem;
+    height: 1.5rem;
   }
   .detailBox-wrap{
     width: 100%;
-    // overflow-y: auto;
     position: absolute;
-    // bottom: 0; //iPhone6plus键盘收起会跳转
-    top:45px;
+    top:1rem;
     bottom: 0;
     left: 0;
     z-index: 666;
@@ -187,8 +196,9 @@
     animation: wave .4s linear;
     height: 100%;
     overflow: hidden;
+    border-radius:.2rem .2rem 0px 0px;
     .head{
-      height: 1rem; //增加了提示
+      height: 1.6rem; //增加了提示
       line-height: .88rem;
       display: flex; //有清空时
       justify-content: space-between;
@@ -201,16 +211,19 @@
       background-color: #fff;
       top: 45px;
       box-sizing: border-box;
+      border-radius:.2rem .2rem 0px 0px;
       i{
         position: absolute;
-        top:0.64rem;
+        bottom:0;
         left:0;
         font-size: .22rem;
         width:100%;
-        height: .33rem;
-        line-height: .33rem;
+        height: .6rem;
+        line-height: .6rem;
         display: inline-block;
-        text-align: center;
+        background-color: #EAF1F9;
+        color: #colors[btn];
+        text-indent: .4rem;
       }
       .icon{
         display: inline-block;
@@ -234,6 +247,15 @@
   }
   .foot{
     .footer;
+    .slide {
+      color: #7C828E;
+      width: 49%;
+      display: inline-block;
+    }
+    .compete {
+      width: 49%;
+      display: inline-block;
+    }
     animation-delay:.6s;
     animation: foo .4s linear;
     /* width:100%;

+ 3 - 1
src/components/Login.vue

@@ -59,6 +59,7 @@ import { phoneTest, identify, jgpattern,name } from "@utils/tools.js";
 import Submit from "../common/Submit";
 import Tiptoast from "../common/Tiptoast";
 import api from "@utils/api.js";
+import $ from "jquery";
 export default {
   name: "Login",
   data() {
@@ -101,6 +102,7 @@ export default {
       this.show = !show;
     },
     blur() {
+      // document.activeElement.scrollIntoView({behavior: "smooth"})
       if(MobileDevice.getModels().join(' or ').indexOf('6') == -1){
         document.activeElement.scrollIntoViewIfNeeded(true);      
         setTimeout(() => {
@@ -192,7 +194,7 @@ export default {
                   recordId: msg.recordId,
                   time:(new Date((msg.recordTime).replace(/\-/g, "/"))).getTime()
                 };
-                localStorage.setItem('loginParam',JSON.stringify(params))//保存登陆信息,扫码进入删除该参数
+                localStorage.setItem('loginParam',JSON.stringify(params))//保存登陆信息,扫码进入删除该参数
                 this.$router.push({
                   path: "/home",
                   query: params

+ 135 - 142
src/components/PathInfo.vue

@@ -1,56 +1,51 @@
 <template>
   <div class="path-wrap">
     <div class="content">
-      <p class="info">挂号用户信息查询如下:</p>
-      <div class="con">
-        <p class="name">
-          <span>{{pathInfo.patientName}}</span>|
-          <span>{{pathInfo.patientSex}}</span>|
-          <span>{{pathInfo.patientAge}}岁</span>
+      <div class="topContent">
+        <p class="hospitalName">{{pathInfo.hospitalName}}</p>
+        <h2>智能预问诊</h2>
+        <p class="explain">该系统通过智能引导式问诊,帮助医生规范、全面的采集患者的症状、体征、病史等信息,从而实现诊疗流程的优化和配置。</p>
+      </div>
+      <div class="minContent">
+        <p class="msg"><i class="person"></i>挂号信息</p>
+        <p class="perMsg perLine">
+          <span class="msgTitle">患者信息:</span>
+          <span class="perDetail">{{pathInfo.patientName}}</span>
+          <span class="perDetail">{{pathInfo.patientSex}}</span>
+          <span class="perDetail">{{pathInfo.patientAge}}岁</span>
         </p>
-        <p>
-          <span>挂号科室:</span>
-          <span>{{pathInfo.hospitalDeptName}}</span>
+        <p class="perLine">
+          <span class="msgTitle">挂号科室:</span>
+          <span>{{pathInfo.hospitalDeptName}}</span>  
         </p>
-        <p>
-          <span>门诊号:</span>
-          <span>{{pathInfo.recordId}}</span>
-          <span style="margin-left:.20rem">预约医生:</span>
+        <p class="perLine">
+          <span class="msgTitle">预约医生:</span>
           <span>{{pathInfo.doctorName}}</span>
         </p>
-        <p>
-          <span>预约时间:</span>
+        <p class="perLine">
+          <span class="msgTitle">门诊号:</span>
+          <span>{{pathInfo.recordId}}</span>
+        </p>
+        <p class="perLine">
+          <span class="msgTitle">预约时间:</span>
           <span>{{time}}</span>
         </p>
-        <p class="already" v-if="type !== 1">{{text[type]}}</p>
       </div>
-      <div class="out-box">
-        <div class="emery">
-          <div class="baner">
-            <p>{{pathInfo.hospitalName}}</p>
-            <p class="big">智能预问诊</p>
-          </div>
-          <div class="inner">
-            <p>该系统通过智能引导式问诊,帮助医生规范、全面的采集患者的症状、体征、病史等信息,从而实现诊疗流程的优化和配置。</p>
-            <button @click="getStart">开始</button>
-          </div>
-          <!-- <p v-if="type==3">您已完成过一次预问诊,是否再次录入</p> -->
-        </div>
-        <div class="child" v-if="child.length>0&&child[0].value==1 && !hideChild">
-          <div class="baner">
-            <p>{{pathInfo.hospitalName}}</p>
-            <p class="big">儿童体质检测</p>
-          </div>
-          <div class="inner">
-            <p>该标准将为0-12岁儿童在为体质辨识及与中医体质相关疾病的预防、养生保健、健康管理提供依据,使体质分类科学化、规范化。</p>
-            <button>开始</button>
-          </div>
-        </div>
+      <div class="btmContent" @click="getStart">开始</div>
+      <div class="con">
+        <p class="already" v-if="type !== 1">{{text[type]}}</p>
       </div>
     </div>
+    
+    <Toast
+      :message="message"
+      :show="showToast"
+      @comfirn="comfirnDel"
+      @cancel="cancelDel"
+    />
     <Submit
       v-if="submit"
-      :fail="message"
+      :fail="tipMsg"
       showType="fail"
     ></Submit>
   </div>
@@ -58,6 +53,7 @@
 <script type="text/javascript">
   import api from '@utils/api.js'
   import Submit from '../common/Submit';
+  import Toast from '../common/Toast.vue';
   import {getUrlArgObject,setScroll,dateParser} from '@utils/tools.js'
   import BScroll from 'better-scroll';
   export default {
@@ -77,9 +73,11 @@
         hideChild:true,  //隐藏儿童
         submit:false,
         scroll:null,
-        message:'',
+        tipMsg:'',
         time:'',
-        params:{}
+        params:{},
+        showToast:false,
+        message:'您已完成一次预问诊,是否重新录入?'
       }
     },
     created(){
@@ -94,6 +92,12 @@
       })
     },
     methods:{
+      comfirnDel() {
+        this.goNext()
+      },
+      cancelDel() {
+        this.showToast = false
+      },
       getPathInfo(){
         let query = this.$route.query
         let hasQuery = JSON.stringify(query) == '{}'
@@ -121,7 +125,6 @@
           if(result.code==0){
             this.pathInfo = result.data;
             this.$store.commit('savePathInfo',result.data);
-            this.recordCheck(); //校验是否填过
             this.getAll(); //获取模板
           }
         })
@@ -152,10 +155,23 @@
         api.recordCheck(param).then((res)=>{
           const result = res.data;
           if(result.code==0){
-            this.type = result.data.type;
+            let type = result.data.type;
+              this.goNext()
+            if(type == 3||type == 6){
+              this.showToast = true
+            }else{
+              this.goNext()
+            }
           }
         })
       },
+      goNext(){
+        if(this.isReady){
+          this.$router.replace({path:'/tab'})
+        }else{
+          this.defaultWaring('请先维护症状模块')
+        }
+      },
       getAll(){
         const param = {
           'age':this.pathInfo.patientAge,
@@ -181,16 +197,11 @@
           this.defaultWaring('网络异常请稍后重试');
           return
         }
-        if(this.isReady){
-          // this.$router.push({path:'/tab'})
-          this.$router.replace({path:'/tab'})
-        }else{
-          this.defaultWaring('请先维护症状模块')
-        }
+        this.recordCheck(); //校验是否填过
       },
       defaultWaring(msg){
         this.submit = true
-        this.message = msg
+        this.tipMsg = msg
         let timer = setTimeout(() => {
           this.submit = false
           clearTimeout(timer)
@@ -198,7 +209,8 @@
       }, 
     },
     components:{
-      Submit
+      Submit,
+      Toast
     }
   }
 </script>
@@ -210,109 +222,90 @@
     width: 100%;
     height: 100%;
     .content {
-      padding-top: .5rem;
-      padding-bottom: .2rem;
+      padding-bottom: .16rem;
       box-sizing: border-box;
+      position: absolute;
+      width: 100%;
+      height: 100%;
     }
-    .info{
-      font-size: .32rem;
-      font-weight: 700;
-      color: #040428;
-      margin-left: .6rem;
-      font-weight: bold;
-    }
-    .con{
-      margin-left: .6rem;
-      position: relative;
-      >p{
-        color: #colors[text];
-        margin-top: .27rem;
+    .topContent {
+      // background-color: #6678FF;
+      height: 4.78rem;
+      padding: .72rem .6rem;
+      box-sizing: border-box;
+      background:url(../images/topContent.png) no-repeat;
+      background-size: cover;
+      .hospitalName {
+        color: #FFFFFF;
+        font-size: .32rem;
       }
-      .name{
-        color: #colors[text];
-        margin-top: .27rem;
-        span{
-          margin-right: .08rem;
-        }
+      h2 {
+        font-size: .56rem;
+        padding: .36rem 0 .18rem 0;
+        color: #fff;
       }
-      .dept{
-        p{
-          display: inline-block;
-          margin-top: .27rem;
-          span{
-            color: #colors[text];
-          }
-        }
-        p:first-child{
-          margin-right: .25rem;
-        }
+      .explain {
+        font-size: .24rem;
+        color: #fff;
+        line-height: .4rem;
       }
-      .already{
-        position: absolute;
-        left: 0;
-        bottom:-.6rem;
-        color: #colors[text];
-      }
-    }
-    .out-box{
-      white-space: nowrap;
-      overflow-x: auto;
-      padding:0 .15rem .15rem 0;
-      -webkit-overflow-scrolling: touch;  
-      text-align: center;//隐藏儿童
     }
-    .emery,.child{
-      display: inline-block;
-      vertical-align: top;
-      width:5.1rem;
-      margin-top: .91rem;
+    .minContent {
+      padding: .3rem .6rem .6rem .6rem;
       box-sizing: border-box;
-      .baner{
-        box-sizing: border-box;
-        width:100%;
-        height: 2.3rem;
-        padding-top: .5rem;
-        p{
-          color:#fff;
-        }
-        .big{
-          font-size: .56rem;
-          margin-top: .12rem;
+      border-radius: 5px;
+      width: 90%;
+      box-shadow:0px 12px 24px 0px rgba(198,187,224,0.15);
+      position: relative;
+      top: -0.7rem;
+      background-color: #fff;
+      margin: 0 auto;
+      .msg {
+        font-size: .32rem;
+        padding-bottom: .28rem;
+        border-bottom: 1px solid #E6E6E6;
+        margin-bottom: .6rem;
+        .person {
+          display: inline-block;
+          width: .38rem;
+          height: .4rem;
+          background: url(../images/person.png) no-repeat;
+          background-size: cover;
+          margin-right: .3rem;
+          position: relative;
+          top: .06rem;
         }
       }
-      .inner{
-        height: 4.5rem;
-        box-shadow:-.05rem .05rem .10rem -.04rem #989da3,.05rem .05rem .10rem -.04rem #989da3;
-        border-radius: 0 0 .20rem .20rem;
-        padding: .45rem .6rem .6rem;
-        box-sizing: border-box;
-        position: relative;
-        p{
-          font-size: .24rem;
-          line-height: .5rem;
-          white-space: normal;
-          min-height: 100px;
-        }
-        button{
-          width: 4rem;
-          height: .88rem;
-          color: #fff;
-          font-size: .32rem;
-          margin: .40rem 0 0 -.05rem;
-          background: -webkit-gradient(linear, right top, left top, from(#4F8BFF), to(#4F4FFF));
-          background: -webkit-linear-gradient(right, #4F8BFF, #4F4FFF);
-          box-shadow: 0 .12rem .24rem 0 rgba(79,129,255,0.40);
-          border-radius: .44rem;
+      .perLine {
+        font-size: .3rem;
+        padding-bottom: .2rem;
+      }
+      .msgTitle {
+        display: inline-block;
+        width: 1.5rem;
+        color: #777777;
+      }
+      .perMsg {
+        .perDetail {
+          margin-right: .24rem;
         }
       }
+      
     }
-    .emery .baner{
-      background: url('../images/banerbg@1.5x.png') no-repeat;
-      background-size: cover;
-    }
-    .child .baner{
-      background: url('../images/childbg@1.5x.png') no-repeat;
-      background-size: cover;
+    .btmContent {
+      width: 94%;
+      height: .88rem;
+      line-height: .88rem;
+      text-align: center;
+      background-color: #colors[btn];
+      font-size: .32rem;
+      color: #fff;
+      margin: 0 auto;
+      border-radius: 5px;
+      position: absolute;
+      bottom: .88rem;
+      transform: translateX(-50%);
+      left: 50%;
     }
   }
 </style>

+ 15 - 9
src/components/Symptom.vue

@@ -45,17 +45,23 @@
         v-if="checkText.length>0"
       >
         <p class="title">{{nameStr}}</p>
-        <p v-for="(value,index) in checkText">{{value.textP}}</p>
+        <div class="bgResult">
+          <p v-for="(value,index) in checkText">{{value.textP}}</p>
+        </div>
       </div>
     </div>
     <div v-if="modluesLen>1"
-      :class="['footer',{'nofoot':chooseSymp.length==0}]"
       @click="toNext"
-    >下一步</div>
+      class="footer"
+    >
+      <div class="nextBtn" :class="{'nofoot':chooseSymp.length==0}">下一步</div>
+    </div>
     <div v-if="modluesLen==1"
-      :class="['footer',{'nofoot':chooseSymp.length==0}]"
+      class="footer"
       @click="toNext"
-    >预览并提交病历</div>
+    >
+      <div class="nextBtn" :class="{'nofoot':chooseSymp.length==0}">预览并提交病历</div>    
+    </div>
     <Toast
       :message="delText"
       :show="showToast"
@@ -350,7 +356,7 @@ export default {
       display: inline-block;
       min-width:1.9rem;
       height: .74rem;
-      background: linear-gradient(-270deg, #3638EE, #4E72FF);
+      background: #colors[btn];
       box-shadow: 0 .08rem .16rem 0 rgba(79,129,255,0.40);
       border-radius: .08rem;
       white-space: nowrap;
@@ -380,9 +386,9 @@ export default {
   .result{
     padding-right: .3rem;
     .title{
-      color: #4F50FF;
+      color: #colors[btn];
       padding-left: .1rem;
-      border-left: .08rem solid #4F50FF;
+      border-left: .08rem solid #colors[btn];
       margin-bottom: .19rem;
       font-weight: 700;
     }
@@ -405,6 +411,6 @@ export default {
   .footer;
 }
 .nofoot{
-  background:#CACCFF;
+  background:#CACCFF!important;
 }
 </style>

BIN
src/images/icon_close@2x.png


+ 40 - 11
src/less/base.less

@@ -3,10 +3,13 @@
 // @theme-color:#4F50FF;
 // 命名空间和访问符,映射
 #colors(){
-  theme:#4F50FF; //主题色,选中色
+  theme:#6678FF; //主题色,选中色
   text:#7C828E; //患者信息及选项文字颜色
   quest:#000000; //问题颜色
   exclu:#e6e7e9; //互斥文字颜色
+  btn:#6678FF;//按钮颜色
+  line:#E6E6E6;//按钮颜色
+  bgques:#F9F9F9;//问题背景颜色
 }
 .mask{
   width:100%;
@@ -18,16 +21,23 @@
 }
 .footer{
   width:100%;
-  height: .88rem;
-  line-height: .88rem;
   text-align: center;
-  color:#fff;
-  font-size: .32rem;
-  background: linear-gradient(-270deg, #4F4FFF,#4F8BFF);
   position: fixed;
   bottom: 0;
   left: 0;
   z-index: 998;
+  padding: .22rem .3rem .18rem .3rem;
+  box-sizing: border-box;
+  box-shadow:0px -2px 10px 0px rgba(0,0,0,0.06);
+  font-size: .32rem;
+  background-color: #fff;
+  .nextBtn {
+    color:#fff;
+    height: .88rem;
+    line-height: .88rem;
+    background: #colors[btn];
+    border-radius: 5px;
+  }
 }
 .dbfooter{
   width:100%;
@@ -48,12 +58,12 @@
   }
   .back{
     width: 40%;
-    color: #0043E8;
+    color: #colors[btn];
   }
   .next{
     width: 58%;
     color: #fff;
-    background: linear-gradient(-270deg, #4F4FFF,#4F8BFF);
+    background: #colors[btn];
   }
 }
 .over{
@@ -89,7 +99,7 @@
 }
 
 .result{
-  padding-right: .3rem;
+  // padding-right: .3rem;
   .title{
     // color: #4F50FF;
     // color: #colors[theme];
@@ -102,6 +112,11 @@
     color: #666;
     line-height: .44rem;
   }
+  .bgResult {
+    background-color: #F5F5F5;
+    padding: .24rem;
+    border-radius: 5px;
+  }
 }
 
 .btscroll {
@@ -114,11 +129,25 @@
   z-index: 99;
   box-sizing: border-box;
   .content {
-    padding-bottom: 2.3rem;
+    padding-bottom: 3rem;
     box-sizing: border-box;
   }
 }
 
 .toastWrapper {
   background-color: #colors[quest];
-}
+}
+.bgques {//问题内容
+  background-color: #colors[bgques];
+  padding: .28rem .3rem;
+  display: none;
+}
+.pubques {//问题题目
+  font-size: .32rem;
+  // font-weight: 800;
+  padding: .45rem 0.5rem .45rem .3rem;
+  word-break: break-all;
+  background-color: #fff;
+  box-shadow:0px 2px 8px 0px rgba(0,0,0,0.04);
+}
+

+ 1 - 1
src/less/index.less

@@ -3,7 +3,7 @@ body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, input, textarea, p, t
   margin: 0;
   padding: 0;
   font-family: Arial, sans-serif, "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB";
-  color: #323232;
+  color: #333333;
   // -webkit-text-size-adjust:100%;
   -webkit-text-size-adjust:auto;
   -webkit-tap-highlight-color: rgba(0,0,0,0);

+ 7 - 6
src/utils/tools.js

@@ -1,7 +1,8 @@
 
 const qs = require('qs');
 const $ = require('jquery');
-const imageUrlPrefix = 'http://192.168.2.241:82' //后台图片地址
+// const imageUrlPrefix = 'http://192.168.2.241:82' //后台图片地址
+const imageUrlPrefix = 'http://192.168.2.121:82' //后台图片地址
 // const imageUrlPrefix = 'http://192.168.2.236:82' //后台图片地址
 
 const getUrlArgObject = (parm) => {
@@ -328,11 +329,11 @@ function setScroll(scroll,flg,wrapper){
       tap: true,
       probeType:3,
       // bounceTime:800,
-      momentumLimitTime:300,//只有在屏幕上快速滑动的时间小于 momentumLimitTime,才能开启 momentum 动画。
-      momentumLimitDistance:15,//只有在屏幕上快速滑动的距离大于 momentumLimitDistance,才能开启 momentum 动画。
-      swipeTime:500,//设置 momentum 动画的动画时长
-      deceleration:0.015,
-      swipeBounceTime:500,
+      // momentumLimitTime:300,//只有在屏幕上快速滑动的时间小于 momentumLimitTime,才能开启 momentum 动画。
+      // momentumLimitDistance:15,//只有在屏幕上快速滑动的距离大于 momentumLimitDistance,才能开启 momentum 动画。
+      // swipeTime:500,//设置 momentum 动画的动画时长
+      // deceleration:0.015,
+      // swipeBounceTime:500,
       bounce: {
         top: false,
         bottom: false,