SsNavigation.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. <template>
  2. <view class="navigation-modal" :class="{ close: !showModal }" @tap="globalStore.setMenuSwitch(false)"></view>
  3. <view class="navigation" :class="{ close: !globalStore.menuSwitch, 'no-spread': !globalStore.spread }" :style="{ paddingTop: globalStore.paddingTop + 'px' }">
  4. <view class="navigation-main">
  5. <view class="services">
  6. <template v-if="globalStore.service" v-for="(item, index) in globalStore.service">
  7. <view class="service-item" :class="getServiceClass(index)" @tap="loadService(item)">
  8. <image class="service-icon" mode="aspectFit" :src="getImageUrl(item.imgUrl)" />
  9. <view class="service-content">
  10. <view class="service-title">{{ item.categoryName }}</view>
  11. <view class="service-intro">{{ item.profile }}</view>
  12. </view>
  13. </view>
  14. </template>
  15. </view>
  16. <div class="common-problem">
  17. <div class="common-problem-title">
  18. 常见问题
  19. <button class="refresh" @tap="refresh">
  20. <uni-load-more class="refresh-icon" v-if="loadingProblems" iconType="circle" :show-text="false" status="loading" color="#7E8AA2" :icon-size="12"></uni-load-more>
  21. <uni-icons v-else type="refreshempty" size="24rpx" color="#7E8AA2" />
  22. 换一换
  23. </button>
  24. </div>
  25. <div class="problem-list">
  26. <template v-if="problems" v-for="item in problems">
  27. <div class="problem-item" @click="quickSend(item.questionContent)">
  28. <image class="problem-icon" mode="aspectFit" :src="getStaticImageUrl('/images/question-filled.png')" />
  29. <div class="problem-item-text">{{ item.questionContent }}</div>
  30. </div>
  31. </template>
  32. </div>
  33. </div>
  34. </view>
  35. </view>
  36. </template>
  37. <script>
  38. import { useGlobalStore } from '../stores/global';
  39. import { RequestApi } from '@/api/requestApi';
  40. export default {
  41. data() {
  42. return {
  43. globalStore: useGlobalStore(),
  44. showModal: false,
  45. timeoutFlag: null,
  46. loadingProblems: false,
  47. problems: [],
  48. search: {
  49. keyword: '',
  50. page: 1,
  51. size: 6
  52. }
  53. };
  54. },
  55. mounted() {
  56. this.getCommonQuestions();
  57. },
  58. methods: {
  59. getServiceClass(index) {
  60. switch (index % 5) {
  61. case 1:
  62. return ' yellow';
  63. case 2:
  64. return ' purple';
  65. case 3:
  66. return ' yellow2';
  67. default:
  68. return '';
  69. }
  70. },
  71. callHotline() {
  72. this.$emit('callHotline');
  73. },
  74. getCommonQuestions() {
  75. this.loadingProblems = true;
  76. RequestApi.getCommonQuestionsRandom(this.search.keyword, this.search.page, this.search.size)
  77. .then((result) => {
  78. this.problems = result.records;
  79. })
  80. .finally(() => {
  81. this.loadingProblems = false;
  82. });
  83. },
  84. refresh() {
  85. this.getCommonQuestions();
  86. },
  87. quickSend(msg) {
  88. this.$emit('quickSend', msg);
  89. },
  90. loadService(item) {
  91. this.$emit('loadService', item.id, item.categoryName, item.imgUrl)
  92. }
  93. },
  94. watch: {
  95. 'globalStore.menuSwitch'() {
  96. if (this.timeoutFlag) {
  97. clearTimeout(this.timeoutFlag);
  98. }
  99. if (this.globalStore.menuSwitch) {
  100. this.showModal = true;
  101. } else {
  102. this.timeoutFlag = setTimeout(() => {
  103. this.showModal = false;
  104. }, 300);
  105. }
  106. }
  107. }
  108. };
  109. </script>
  110. <style scoped lang="scss">
  111. @import '@/static/global.scss';
  112. .navigation-modal {
  113. position: fixed;
  114. top: 0;
  115. left: 0;
  116. bottom: 0;
  117. right: 0;
  118. z-index: 499;
  119. background-color: rgba(0, 0, 0, 0.5);
  120. transition: opacity 0.3s linear;
  121. display: block;
  122. &.close {
  123. display: none !important;
  124. }
  125. }
  126. .navigation {
  127. position: fixed;
  128. top: 0;
  129. left: 0;
  130. bottom: 0;
  131. width: 576rpx;
  132. z-index: 500;
  133. display: flex;
  134. padding-top: 128rpx;
  135. transition: all 0.3s linear;
  136. background-color: #ffffff;
  137. background-repeat: no-repeat;
  138. background-position: center bottom;
  139. background-size: cover;
  140. background-image: url(getImageUrl('/images/background-2.png'));
  141. .navigation-main {
  142. width: 100%;
  143. padding: 0 32rpx;
  144. overflow: hidden;
  145. .services {
  146. padding: 40rpx 0;
  147. border-bottom: 1px solid #c2dbfd;
  148. margin-bottom: 20rpx;
  149. .service-item {
  150. border-radius: 16rpx;
  151. padding: 16rpx 24rpx;
  152. background: linear-gradient(180deg, #fafffd 0%, #e1f5f8 100%);
  153. margin-bottom: 32rpx;
  154. display: flex;
  155. align-items: center;
  156. box-shadow: 0 8rpx 12rpx 0 #bdd5f4;
  157. cursor: pointer;
  158. &.yellow {
  159. background: linear-gradient(180deg, #ffffff 0%, #f6f0ef 100%);
  160. }
  161. &.yellow2 {
  162. background: linear-gradient(180deg, #fffefd 0%, #fff8e8 100%);
  163. }
  164. &.purple {
  165. background: linear-gradient(180deg, #ffffff 0%, #f2f4ff 57%, #e8ebff 100%);
  166. }
  167. &.blue {
  168. background: linear-gradient(180deg, #f3fbff 0%, #d4efff 100%);
  169. }
  170. &:last-child {
  171. margin-bottom: 0;
  172. }
  173. .service-icon {
  174. width: 80rpx;
  175. height: 80rpx;
  176. margin-right: 20rpx;
  177. }
  178. .service-content {
  179. .service-title {
  180. font-size: 28rpx;
  181. line-height: 28rpx;
  182. font-weight: 500;
  183. color: #101333;
  184. margin-bottom: 12rpx;
  185. }
  186. .service-intro {
  187. font-size: 24rpx;
  188. line-height: 24rpx;
  189. font-weight: 400;
  190. color: #7e8aa2;
  191. }
  192. }
  193. }
  194. }
  195. .common-problem {
  196. .common-problem-title {
  197. color: #101333;
  198. font-size: 0.88rem;
  199. line-height: 0.88rem;
  200. font-weight: 600;
  201. margin-bottom: 1.25rem;
  202. display: flex;
  203. align-items: center;
  204. justify-content: space-between;
  205. .refresh {
  206. padding: 0;
  207. font-size: 0.88rem;
  208. color: #7e8aa2;
  209. background-color: transparent;
  210. height: unset;
  211. margin: unset;
  212. border: 0;
  213. &::after {
  214. display: none;
  215. }
  216. .refresh-icon {
  217. display: inline-block;
  218. }
  219. }
  220. }
  221. .problem-list {
  222. .problem-item {
  223. display: flex;
  224. align-items: center;
  225. font-size: 0.8rem;
  226. line-height: 0.8rem;
  227. margin-bottom: 1.4rem;
  228. color: #545764;
  229. cursor: pointer;
  230. .problem-icon {
  231. margin-right: 0.64rem;
  232. width: 1rem;
  233. height: 1rem;
  234. }
  235. .problem-item-text {
  236. width: calc(100% - 1.64rem);
  237. white-space: nowrap; /* 强制文本不换行 */
  238. overflow: hidden; /* 隐藏超出容器的内容 */
  239. text-overflow: ellipsis; /* 超出部分显示省略号 */
  240. }
  241. }
  242. }
  243. }
  244. }
  245. &.no-spread {
  246. transform: translateX(-100%);
  247. }
  248. &.close {
  249. left: -576rpx;
  250. .navigation-main {
  251. .services {
  252. .service-item {
  253. padding: 0 8rpx;
  254. justify-content: center;
  255. .service-icon {
  256. margin: 0 auto;
  257. }
  258. }
  259. }
  260. }
  261. .footer-switch {
  262. display: block;
  263. }
  264. }
  265. }
  266. </style>