index.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <template>
  2. <view class="page">
  3. <view v-if="state.questions.length <= 0" class="flex-center mt-40 animation-loading">
  4. <uv-icon name="photo"></uv-icon>
  5. </view>
  6. <view class="sheet">
  7. <view class="sheet_bar" v-for="(item, index) in state.questions" :key="index">
  8. <view class="head" @click="toggle(index)">
  9. <view class="pt-32 pb-32 flex-align-center">
  10. <view class="fs-28 fw-500 color-000">{{ item.question }}</view>
  11. <view
  12. class="width-40 ml-auto flex-end flex-shrink transition"
  13. :style="{
  14. transform: item.open ? 'rotate(180deg)' : 'rotate(0deg)',
  15. }"
  16. >
  17. <uv-icon name="arrow-down"></uv-icon>
  18. </view>
  19. </view>
  20. </view>
  21. <view :class="['body', item.open ? 'body-open' : 'body-hidden']">
  22. <view
  23. v-for="(answerItem, answerIndex) in item.answer"
  24. :key="answerIndex"
  25. :class="[
  26. 'fs-28',
  27. 'lh-48',
  28. 'color-666',
  29. answerIndex === 0 ? 'mt-0' : 'mt-10',
  30. ]"
  31. >{{ answerItem }}
  32. </view
  33. >
  34. </view>
  35. </view>
  36. </view>
  37. <view
  38. class="flex-center flex-column contact mt-20"
  39. hover-class="hover-scale"
  40. @click="call"
  41. v-if="state.questions.length"
  42. >
  43. <image
  44. class="width-96"
  45. mode="widthFix"
  46. src="/static/images/contact-customer.png"
  47. />
  48. <view class="mt-16 color-666 fs-28">电话客服</view>
  49. </view>
  50. </view>
  51. </template>
  52. <script setup lang="ts">
  53. import {onHide, onShow} from "@dcloudio/uni-app";
  54. import {reactive} from "vue";
  55. import {body} from "@/utils/https"
  56. const initState = () => ({
  57. questions: [] as any[],
  58. servicerPhone: "",
  59. })
  60. const state = reactive(initState())
  61. const call = () => {
  62. uni.makePhoneCall({
  63. phoneNumber: state.servicerPhone,
  64. });
  65. };
  66. const toggle = (index: number) => {
  67. state.questions = state.questions.map((item, i) => {
  68. return {
  69. ...item,
  70. open: item.open ? false : i === index,
  71. };
  72. });
  73. };
  74. onShow((options) => {
  75. if (options) {
  76. state.servicerPhone = options.service;
  77. }
  78. body(`faq/list`).then((res: any) => {
  79. state.questions = res.list;
  80. })
  81. });
  82. onHide(() => {
  83. Object.assign(state, initState());
  84. })
  85. </script>
  86. <style lang="scss">
  87. .page {
  88. min-height: 100vh;
  89. background: #f6f7fa;
  90. box-sizing: border-box;
  91. padding: 40rpx 32rpx;
  92. }
  93. .contact {
  94. height: 216rpx;
  95. border-radius: 24rpx;
  96. background: #fff;
  97. }
  98. .sheet {
  99. box-sizing: border-box;
  100. border-radius: 24rpx;
  101. background: #fff;
  102. overflow: hidden;
  103. &_bar {
  104. .head {
  105. padding: 0rpx 24rpx;
  106. box-sizing: border-box;
  107. & > view {
  108. border-bottom: 1rpx solid rgba(0, 0, 0, 0.1);
  109. }
  110. }
  111. .body {
  112. box-sizing: border-box;
  113. background-color: rgba(52, 125, 255, 0.06);
  114. transition: all 0.3s;
  115. padding: 0rpx 24rpx;
  116. }
  117. .body-hidden {
  118. height: 0px;
  119. overflow: hidden;
  120. }
  121. .body-open {
  122. height: auto;
  123. padding-top: 24rpx;
  124. padding-bottom: 24rpx;
  125. }
  126. &:last-child {
  127. .head {
  128. & > view {
  129. border-bottom: none;
  130. }
  131. }
  132. }
  133. }
  134. }
  135. </style>