吉光研途前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

280 lines
6.6 KiB

1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
  1. <template>
  2. <view class="page__view">
  3. <view class="bg">
  4. <image class="img" :src="configList.config_image_page_header" mode="scaleToFill"></image>
  5. </view>
  6. <!-- 搜索栏 -->
  7. <view class="section search">
  8. <uv-search v-model="keyword" placeholder="输入关键词搜索" bgColor="#FBFBFB" @custom="search" @search="search">
  9. <template #prefix>
  10. <image class="search-icon" src="@/static/image/icon-search.png" mode="widthFix"></image>
  11. </template>
  12. </uv-search>
  13. </view>
  14. <!-- 轮播图 -->
  15. <view class="section swiper">
  16. <uv-swiper :list="bannerList" keyName="image" indicator indicatorMode="dot" indicatorActiveColor="#4883F9" indicatorInactiveColor="#FFFFFF" :height="swiperHeight"></uv-swiper>
  17. </view>
  18. <view class="section card" v-for="group in list" :key="group.id">
  19. <view class="card-header">
  20. <view class="card-header-title">{{ group.title }}</view>
  21. <!-- <view class="card-header-tag">JGYT</view> -->
  22. </view>
  23. <view class="card-content">
  24. <view class="card-item card-row" v-for="item in group.children" :key="item.id">
  25. <view class="flex info">
  26. <image class="info-icon" :src="item.image" mode="widthFix"></image>
  27. <view class="info-label">{{ item.title }}</view>
  28. </view>
  29. <button class="btn" @click="jumpToCategory(group.id, item.id, item.title, 'queryThesisList')">查看</button>
  30. </view>
  31. </view>
  32. </view>
  33. <view class="section card" v-for="group in list2" :key="group.id">
  34. <view class="card-header">
  35. <view class="card-header-title">{{ group.title }}</view>
  36. <!-- <view class="card-header-tag">JGYT</view> -->
  37. </view>
  38. <view class="card-content">
  39. <view class="card-box">
  40. <view class="card-item info" v-for="item in group.children" :key="item.id" @click="jumpToCategory(group.id, item.id, item.title, 'queryThesisTwoList')">
  41. <image class="info-icon" :src="item.image" mode="widthFix"></image>
  42. <view class="info-label">{{ item.title }}</view>
  43. </view>
  44. </view>
  45. </view>
  46. </view>
  47. <tabber select="home" />
  48. </view>
  49. </template>
  50. <script>
  51. import tabber from '@/components/base/tabbar.vue'
  52. export default {
  53. components: {
  54. tabber,
  55. },
  56. data() {
  57. return {
  58. keyword: '',
  59. bannerList: [],
  60. list: [],
  61. list2: [],
  62. swiperHeight: '239rpx',
  63. }
  64. },
  65. onLoad() {
  66. const windowWidth = uni.getSystemInfoSync().windowWidth
  67. this.swiperHeight = `${(windowWidth - 18) * 239 / 714}px`
  68. this.fetchBanner()
  69. this.getData()
  70. },
  71. methods: {
  72. // 获取轮播图
  73. async fetchBanner() {
  74. try {
  75. this.bannerList = (await this.$fetch('queryBannerList', { type: '0' }))?.records // type:0-首页 1-案例 2-服务 3-其他
  76. } catch (err) {
  77. }
  78. },
  79. async fetchCategory(api) {
  80. try {
  81. let parents = (await this.$fetch(api, { pageNo: 1, pageSize: 1000 }))?.records?.filter(item => item.hasChild == '1')
  82. let results = await Promise.allSettled(parents.map(parent => { return this.$fetch(api, { pid: parent.id, pageNo: 1, pageSize: 1000 }) }))
  83. results.forEach((result, index) => {
  84. parents[index].children = result?.value?.records || []
  85. })
  86. return parents
  87. } catch (err) {
  88. return []
  89. }
  90. },
  91. async getData() {
  92. this.list = await this.fetchCategory('queryCategoryThesisList')
  93. this.list2 = await this.fetchCategory('queryCategoryThesisTwoList')
  94. },
  95. search() {
  96. uni.navigateTo({
  97. url: '/pages_order/thesis/search?search=' + this.keyword
  98. })
  99. this.keyword = ''
  100. },
  101. jumpToCategory(categoryOne, categoryTwo, title, api) {
  102. uni.navigateTo({
  103. url: `/pages_order/thesis/search?categoryOne=${categoryOne}&categoryTwo=${categoryTwo}&title=${title}&api=${api}`
  104. })
  105. },
  106. },
  107. }
  108. </script>
  109. <style scoped lang="scss">
  110. .page__view {
  111. padding-bottom: 182rpx;
  112. }
  113. .bg {
  114. width: 100%;
  115. height: 264rpx;
  116. .img {
  117. width: 100%;
  118. height: 100%;
  119. }
  120. }
  121. .section {
  122. margin: 0 18rpx 0 18rpx;
  123. }
  124. .search {
  125. width: calc(100% - 20rpx * 2);
  126. background-color: #FFFFFF;
  127. border-radius: 37rpx;
  128. padding: 13rpx 0 13rpx 18rpx;
  129. box-sizing: border-box;
  130. display: flex;
  131. align-items: center;
  132. /deep/ .uv-search__action {
  133. color: $uni-color;
  134. padding: 10rpx 18rpx;
  135. }
  136. &-icon {
  137. width: 26rpx;
  138. height: auto;
  139. }
  140. }
  141. .swiper {
  142. margin-top: 29rpx;
  143. margin-bottom: 26rpx;
  144. border-radius: 25rpx;
  145. overflow: hidden;
  146. /deep/ .uv-swiper-indicator__wrapper__dot {
  147. width: 15rpx;
  148. height: 15rpx;
  149. }
  150. /deep/ .uv-swiper-indicator__wrapper__dot--active {
  151. width: 15rpx;
  152. }
  153. }
  154. .card {
  155. margin-bottom: 35rpx;
  156. width: calc(100% - 20rpx * 2);
  157. box-sizing: border-box;
  158. padding-bottom: 45rpx;
  159. background-image: linear-gradient(164deg,#cfecfe 88rpx, #fcfdfe 176rpx);
  160. border: 3rpx solid #FFFFFF;
  161. border-radius: 25rpx;
  162. box-shadow: 0px 3rpx 6rpx 0rpx rgba(0,0,0,0.16);
  163. &-header {
  164. position: relative;
  165. width: 100%;
  166. box-sizing: border-box;
  167. padding: 46rpx 0 17rpx 33rpx;
  168. overflow: hidden;
  169. &-title {
  170. font-size: 42rpx;
  171. font-weight: 800;
  172. color: #000000;
  173. }
  174. &-tag {
  175. position: absolute;
  176. top: -40rpx;
  177. right: 12rpx;
  178. font-size: 156rpx;
  179. font-weight: 800;
  180. color: rgba(255,255,255,0.3);
  181. }
  182. }
  183. &-content {
  184. padding: 0 30rpx;
  185. box-sizing: border-box;
  186. }
  187. &-item {
  188. display: flex;
  189. align-items: center;
  190. justify-content: flex-start;
  191. column-gap: 50rpx;
  192. padding: 26rpx 28rpx;
  193. box-sizing: border-box;
  194. background: #f3f6fd;
  195. border-radius: 28rpx;
  196. box-shadow: 0rpx 3rpx 6rpx 0rpx rgba(0,0,0,0.16);
  197. }
  198. .info {
  199. &-icon {
  200. width: 80rpx;
  201. height: auto;
  202. }
  203. &-label {
  204. font-size: 32rpx;
  205. font-weight: 400;
  206. color: #000000;
  207. }
  208. }
  209. &-row {
  210. justify-content: space-between;
  211. padding: 15rpx 35rpx;
  212. & + & {
  213. margin-top: 33rpx;
  214. }
  215. .info {
  216. column-gap: 33rpx;
  217. }
  218. .btn {
  219. padding: 7rpx 30rpx;
  220. font-size: 28rpx;
  221. font-weight: 400;
  222. color: #4883F9;
  223. background: #FFFFFF;
  224. border-radius: 27rpx;
  225. }
  226. }
  227. &-box {
  228. display: grid;
  229. grid-template-columns: repeat(2, 1fr);
  230. column-gap: 34rpx;
  231. row-gap: 26rpx;
  232. .info {
  233. column-gap: 50rpx;
  234. }
  235. }
  236. }
  237. </style>