249 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
		
		
			
		
	
	
			249 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
|  | <template> | ||
|  |   <div class="message-rating-star"> | ||
|  |     <p class="rating-head"> | ||
|  |       {{ props.ratingTemplate.head }} | ||
|  |     </p> | ||
|  | 
 | ||
|  |     <div class="rating-card"> | ||
|  |       <span class="card-title">请对本次服务进行评价</span> | ||
|  |       <div class="card-wrapper"> | ||
|  |         <div style="max-width: 250px"> | ||
|  |           <div | ||
|  |             v-for="(item, index) in numberList" | ||
|  |             :key="index" | ||
|  |             :class="{ | ||
|  |               'active': !(index !== selectValue && index !== hoverValue), | ||
|  |               'de-active': index !== selectValue && index !== hoverValue, | ||
|  |             }" | ||
|  |             :style="{ | ||
|  |               marginLeft: index === 0 ? 0 + 'px' : 20 + 'px', | ||
|  |               margin: 5 + 'px', | ||
|  |             }" | ||
|  |             @click="setValue(index)" | ||
|  |             @mouseenter="setHoverValue(index)" | ||
|  |             @mouseleave="setHoverValue(-1)" | ||
|  |           > | ||
|  |             {{ item + 1 }} | ||
|  |           </div> | ||
|  |         </div> | ||
|  |       </div> | ||
|  |       <div :style="{ marginTop: 10 + 'px', marginBottom: 10 + 'px' }"> | ||
|  |         {{ | ||
|  |           hoverValue === -1 | ||
|  |             ? selectValue === -1 | ||
|  |               ? "如果满意请给好评哦~" | ||
|  |               : desc[selectValue] | ||
|  |             : desc[hoverValue] | ||
|  |         }} | ||
|  |       </div> | ||
|  |       <button | ||
|  |         class="submit-button" | ||
|  |         :disabled="hasReply || hasExpire" | ||
|  |         @click="submitRatingStar" | ||
|  |       > | ||
|  |         提交评价 | ||
|  |       </button> | ||
|  |     </div> | ||
|  |     <p | ||
|  |       v-if="hasReply" | ||
|  |       class="rating-tail" | ||
|  |       :style="{ | ||
|  |         marginTop: 20 + 'px', | ||
|  |       }" | ||
|  |     > | ||
|  |       {{ props.ratingTemplate.tail }} | ||
|  |     </p> | ||
|  |   </div> | ||
|  | </template> | ||
|  | 
 | ||
|  | <script lang="ts"> | ||
|  | import vue from '../../adapter-vue'; | ||
|  | import { CUSTOM_MESSAGE_SRC } from '../../constant'; | ||
|  | import { ratingTemplateType } from '../../interface'; | ||
|  | 
 | ||
|  | const { computed, ref, watchEffect } = vue; | ||
|  | 
 | ||
|  | interface Props { | ||
|  |   ratingTemplate: ratingTemplateType; | ||
|  | } | ||
|  | 
 | ||
|  | export default { | ||
|  |   props: { | ||
|  |     ratingTemplate: { | ||
|  |       type: Object as () => ratingTemplateType, | ||
|  |       default: () => ({}), | ||
|  |     }, | ||
|  |   }, | ||
|  |   emits: ['sendMessage'], | ||
|  |   setup(props: Props, { emit }) { | ||
|  |     const hasReply = ref<boolean>(false); | ||
|  |     const sessionId = ref<string>(''); | ||
|  |     const selectValue = ref<number>(-1); | ||
|  |     const hoverValue = ref<number>(-1); | ||
|  |     const hasExpire = ref<boolean>(false); | ||
|  | 
 | ||
|  |     const desc = computed(() => { | ||
|  |       return props.ratingTemplate?.menu.map(item => item.content); | ||
|  |     }); | ||
|  | 
 | ||
|  |     const numberList = computed(() => { | ||
|  |       return props.ratingTemplate?.menu.map((item, index) => index); | ||
|  |     }); | ||
|  | 
 | ||
|  |     watchEffect(() => { | ||
|  |       sessionId.value = props.ratingTemplate.sessionId || ''; | ||
|  |       if (props.ratingTemplate.selected != undefined) { | ||
|  |         for (let i = 0; i < props.ratingTemplate.menu.length; i++) { | ||
|  |           if (props.ratingTemplate.menu[i].id == props.ratingTemplate.selected.id) { | ||
|  |             hasReply.value = true; | ||
|  |             selectValue.value = i; | ||
|  |             break; | ||
|  |           } | ||
|  |         } | ||
|  |       } | ||
|  |       const timestamp = Math.floor(new Date().getTime() / 1000); | ||
|  |       if (timestamp > props.ratingTemplate.expireTime) { | ||
|  |         hasExpire.value = true; | ||
|  |       } | ||
|  |     }); | ||
|  | 
 | ||
|  |     const setValue = (val: number) => { | ||
|  |       if (!hasReply.value) { | ||
|  |         selectValue.value = val; | ||
|  |       } | ||
|  |     }; | ||
|  | 
 | ||
|  |     const setHoverValue = (value: number) => { | ||
|  |       if (!hasReply.value) { | ||
|  |         hoverValue.value = value; | ||
|  |       } | ||
|  |     }; | ||
|  | 
 | ||
|  |     const submitRatingStar = () => { | ||
|  |       if (selectValue.value >= 0) { | ||
|  |         const submitData = { | ||
|  |           data: JSON.stringify({ | ||
|  |             src: CUSTOM_MESSAGE_SRC.MENU_SELECTED, | ||
|  |             menuSelected: { | ||
|  |               id: props.ratingTemplate.menu[selectValue.value].id, | ||
|  |               content: props.ratingTemplate.menu[selectValue.value].content, | ||
|  |               sessionId: sessionId.value, | ||
|  |             }, | ||
|  |             customerServicePlugin: 0, | ||
|  |           }), | ||
|  |         }; | ||
|  |         hasReply.value = true; | ||
|  |         emit('sendMessage', submitData); | ||
|  |       } | ||
|  |     }; | ||
|  | 
 | ||
|  |     return { | ||
|  |       props, | ||
|  |       hasReply, | ||
|  |       sessionId, | ||
|  |       selectValue, | ||
|  |       hoverValue, | ||
|  |       hasExpire, | ||
|  |       desc, | ||
|  |       numberList, | ||
|  |       setValue, | ||
|  |       setHoverValue, | ||
|  |       submitRatingStar, | ||
|  |     }; | ||
|  |   }, | ||
|  | }; | ||
|  | </script> | ||
|  | <style lang="scss" scoped> | ||
|  | .rating-head { | ||
|  |   font-size: 14px; | ||
|  |   font-weight: 400; | ||
|  |   color: #999; | ||
|  | } | ||
|  | 
 | ||
|  | .rating-tail { | ||
|  |   font-size: 14px; | ||
|  |   font-weight: 400; | ||
|  |   color: #999; | ||
|  | } | ||
|  | 
 | ||
|  | .card-title { | ||
|  |   font-size: 14px; | ||
|  |   font-weight: 500; | ||
|  | } | ||
|  | 
 | ||
|  | .rating-card { | ||
|  |   min-width: 270px; | ||
|  |   width: 50%; | ||
|  |   background: #fbfbfb; | ||
|  |   border-radius: 20px; | ||
|  |   border: 0; | ||
|  |   margin-top: 10px; | ||
|  |   padding-top: 20px; | ||
|  |   padding-bottom: 20px; | ||
|  | 
 | ||
|  |   button:disabled { | ||
|  |     background: #d8d8d8; | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | .message-rating-star { | ||
|  |   text-align: center; | ||
|  |   display: flex; | ||
|  |   flex-flow: column wrap; | ||
|  |   justify-content: center; | ||
|  |   padding-bottom: 30px; | ||
|  |   align-items: center; | ||
|  | } | ||
|  | 
 | ||
|  | .card-wrapper { | ||
|  |   display: flex; | ||
|  |   flex-wrap: wrap; | ||
|  |   justify-content: center; | ||
|  |   padding-top: 10px; | ||
|  | } | ||
|  | 
 | ||
|  | .submit-button { | ||
|  |   width: 50%; | ||
|  |   height: 50px; | ||
|  |   background-color: #0365f9; | ||
|  |   font-size: 18px; | ||
|  |   font-weight: 400; | ||
|  |   color: white; | ||
|  |   border: 0; | ||
|  |   border-radius: 8px; | ||
|  |   cursor: pointer; | ||
|  | } | ||
|  | 
 | ||
|  | .de-active { | ||
|  |   height: 34px; | ||
|  |   width: 34px; | ||
|  |   display: inline-block; | ||
|  |   border: 0 solid #006eff0d; | ||
|  |   border-radius: 5px; | ||
|  |   color: #006eff; | ||
|  |   font-weight: 400; | ||
|  |   font-size: 16px; | ||
|  |   text-align: center; | ||
|  |   line-height: 34px; | ||
|  |   background: #006eff0d; | ||
|  | } | ||
|  | 
 | ||
|  | .active { | ||
|  |   width: 34px; | ||
|  |   height: 34px; | ||
|  |   display: inline-block; | ||
|  |   background: linear-gradient( | ||
|  |     136.96deg, | ||
|  |     rgba(10, 124, 255, 0.3) -39.64%, | ||
|  |     #0a7cff 131.39% | ||
|  |   ); | ||
|  |   border-radius: 5px; | ||
|  |   color: white; | ||
|  |   font-weight: 400; | ||
|  |   font-size: 16px; | ||
|  |   border: 0 solid #0a7cff; | ||
|  |   text-align: center; | ||
|  |   line-height: 34px; | ||
|  | } | ||
|  | </style> |