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>
 |