message-rating-number.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <template>
  2. <div class="message-rating-star">
  3. <p class="rating-head">
  4. {{ props.ratingTemplate.head }}
  5. </p>
  6. <div class="rating-card">
  7. <span class="card-title">请对本次服务进行评价</span>
  8. <div class="card-wrapper">
  9. <div style="max-width: 250px">
  10. <div
  11. v-for="(item, index) in numberList"
  12. :key="index"
  13. :class="{
  14. 'active': !(index !== selectValue && index !== hoverValue),
  15. 'de-active': index !== selectValue && index !== hoverValue,
  16. }"
  17. :style="{
  18. marginLeft: index === 0 ? 0 + 'px' : 20 + 'px',
  19. margin: 5 + 'px',
  20. }"
  21. @click="setValue(index)"
  22. @mouseenter="setHoverValue(index)"
  23. @mouseleave="setHoverValue(-1)"
  24. >
  25. {{ item + 1 }}
  26. </div>
  27. </div>
  28. </div>
  29. <div :style="{ marginTop: 10 + 'px', marginBottom: 10 + 'px' }">
  30. {{
  31. hoverValue === -1
  32. ? selectValue === -1
  33. ? "如果满意请给好评哦~"
  34. : desc[selectValue]
  35. : desc[hoverValue]
  36. }}
  37. </div>
  38. <button
  39. class="submit-button"
  40. :disabled="hasReply || hasExpire"
  41. @click="submitRatingStar"
  42. >
  43. 提交评价
  44. </button>
  45. </div>
  46. <p
  47. v-if="hasReply"
  48. class="rating-tail"
  49. :style="{
  50. marginTop: 20 + 'px',
  51. }"
  52. >
  53. {{ props.ratingTemplate.tail }}
  54. </p>
  55. </div>
  56. </template>
  57. <script lang="ts">
  58. import vue from '../../adapter-vue';
  59. import { CUSTOM_MESSAGE_SRC } from '../../constant';
  60. import { ratingTemplateType } from '../../interface';
  61. const { computed, ref, watchEffect } = vue;
  62. interface Props {
  63. ratingTemplate: ratingTemplateType;
  64. }
  65. export default {
  66. props: {
  67. ratingTemplate: {
  68. type: Object as () => ratingTemplateType,
  69. default: () => ({}),
  70. },
  71. },
  72. emits: ['sendMessage'],
  73. setup(props: Props, { emit }) {
  74. const hasReply = ref<boolean>(false);
  75. const sessionId = ref<string>('');
  76. const selectValue = ref<number>(-1);
  77. const hoverValue = ref<number>(-1);
  78. const hasExpire = ref<boolean>(false);
  79. const desc = computed(() => {
  80. return props.ratingTemplate?.menu.map(item => item.content);
  81. });
  82. const numberList = computed(() => {
  83. return props.ratingTemplate?.menu.map((item, index) => index);
  84. });
  85. watchEffect(() => {
  86. sessionId.value = props.ratingTemplate.sessionId || '';
  87. if (props.ratingTemplate.selected != undefined) {
  88. for (let i = 0; i < props.ratingTemplate.menu.length; i++) {
  89. if (props.ratingTemplate.menu[i].id == props.ratingTemplate.selected.id) {
  90. hasReply.value = true;
  91. selectValue.value = i;
  92. break;
  93. }
  94. }
  95. }
  96. const timestamp = Math.floor(new Date().getTime() / 1000);
  97. if (timestamp > props.ratingTemplate.expireTime) {
  98. hasExpire.value = true;
  99. }
  100. });
  101. const setValue = (val: number) => {
  102. if (!hasReply.value) {
  103. selectValue.value = val;
  104. }
  105. };
  106. const setHoverValue = (value: number) => {
  107. if (!hasReply.value) {
  108. hoverValue.value = value;
  109. }
  110. };
  111. const submitRatingStar = () => {
  112. if (selectValue.value >= 0) {
  113. const submitData = {
  114. data: JSON.stringify({
  115. src: CUSTOM_MESSAGE_SRC.MENU_SELECTED,
  116. menuSelected: {
  117. id: props.ratingTemplate.menu[selectValue.value].id,
  118. content: props.ratingTemplate.menu[selectValue.value].content,
  119. sessionId: sessionId.value,
  120. },
  121. customerServicePlugin: 0,
  122. }),
  123. };
  124. hasReply.value = true;
  125. emit('sendMessage', submitData);
  126. }
  127. };
  128. return {
  129. props,
  130. hasReply,
  131. sessionId,
  132. selectValue,
  133. hoverValue,
  134. hasExpire,
  135. desc,
  136. numberList,
  137. setValue,
  138. setHoverValue,
  139. submitRatingStar,
  140. };
  141. },
  142. };
  143. </script>
  144. <style lang="scss" scoped>
  145. .rating-head {
  146. font-size: 14px;
  147. font-weight: 400;
  148. color: #999;
  149. }
  150. .rating-tail {
  151. font-size: 14px;
  152. font-weight: 400;
  153. color: #999;
  154. }
  155. .card-title {
  156. font-size: 14px;
  157. font-weight: 500;
  158. }
  159. .rating-card {
  160. min-width: 270px;
  161. width: 50%;
  162. background: #fbfbfb;
  163. border-radius: 20px;
  164. border: 0;
  165. margin-top: 10px;
  166. padding-top: 20px;
  167. padding-bottom: 20px;
  168. button:disabled {
  169. background: #d8d8d8;
  170. }
  171. }
  172. .message-rating-star {
  173. text-align: center;
  174. display: flex;
  175. flex-flow: column wrap;
  176. justify-content: center;
  177. padding-bottom: 30px;
  178. align-items: center;
  179. }
  180. .card-wrapper {
  181. display: flex;
  182. flex-wrap: wrap;
  183. justify-content: center;
  184. padding-top: 10px;
  185. }
  186. .submit-button {
  187. width: 50%;
  188. height: 50px;
  189. background-color: #0365f9;
  190. font-size: 18px;
  191. font-weight: 400;
  192. color: white;
  193. border: 0;
  194. border-radius: 8px;
  195. cursor: pointer;
  196. }
  197. .de-active {
  198. height: 34px;
  199. width: 34px;
  200. display: inline-block;
  201. border: 0 solid #006eff0d;
  202. border-radius: 5px;
  203. color: #006eff;
  204. font-weight: 400;
  205. font-size: 16px;
  206. text-align: center;
  207. line-height: 34px;
  208. background: #006eff0d;
  209. }
  210. .active {
  211. width: 34px;
  212. height: 34px;
  213. display: inline-block;
  214. background: linear-gradient(
  215. 136.96deg,
  216. rgba(10, 124, 255, 0.3) -39.64%,
  217. #0a7cff 131.39%
  218. );
  219. border-radius: 5px;
  220. color: white;
  221. font-weight: 400;
  222. font-size: 16px;
  223. border: 0 solid #0a7cff;
  224. text-align: center;
  225. line-height: 34px;
  226. }
  227. </style>