index.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. <template>
  2. <view>
  3. <view class="container">
  4. <image class="home_top_bg" src="https://beiliyo-2025.obs.cn-north-4.myhuaweicloud.com/fs/20250115/1736955760372.png" mode="widthFix"></image>
  5. <view class="tabbox">
  6. <view ref="tabbar" class="tabbar">
  7. <view :id="index" :class="activeTab == index ? 'active tabbar-item':'tabbar-item'"
  8. v-for="(tab,index) in tabList" :key="tab.id" @click="handleTab(index)">{{tab.name}}</view>
  9. </view>
  10. <view ref="underline" class="tabbar-tabline tabbar-tabline-animation"
  11. :style="{left: indicatorLineLeft + 'px', width: indicatorLineWidth + 'px'}">
  12. <image class="tabbar-tabline-image" src="@/static/images/course/hall_on_icon.png" mode="aspectFill">
  13. </image>
  14. </view>
  15. </view>
  16. <!-- 内容 -->
  17. <swiper :current="activeTab" @change="onSwiperChange" :style="'height:' + clientHeight + 'px;'">
  18. <swiper-item>
  19. <scroll-view scroll-y="true" :style="'height:' + clientHeight + 'px;'" :scroll-top="scrollTopHall"
  20. @scroll="scroll($event,'scrollTopHall')">
  21. <doctorHall ref="doctorHall" :swiperAutoplay="swiperAutoplay" />
  22. </scroll-view>
  23. </swiper-item>
  24. <swiper-item>
  25. <scroll-view scroll-y="true" :style="'height:' + clientHeight + 'px;'" :scroll-top="scrollTopStudy"
  26. @scroll="scroll($event,'scrollTopStudy')">
  27. <studyCenter ref="studyCenter" />
  28. </scroll-view>
  29. </swiper-item>
  30. </swiper>
  31. </view>
  32. <tabbar :actindex="1"></tabbar>
  33. </view>
  34. </template>
  35. <script>
  36. import doctorHall from './components/doctorHall.vue';
  37. import studyCenter from './components/studyCenter.vue';
  38. import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
  39. import mescrollBody from "@/uni_modules/mescroll-uni/components/mescroll-body/mescroll-body.vue";
  40. import {
  41. getDictByKey
  42. } from '@/api/common'
  43. import {
  44. getCourseCate,
  45. getCourseList
  46. } from '@/api/course'
  47. import {
  48. getAdvList
  49. } from '@/api/adv.js'
  50. export default {
  51. mixins: [MescrollMixin], // 使用mixin
  52. components: {
  53. mescrollBody,
  54. doctorHall,
  55. studyCenter
  56. },
  57. data() {
  58. return {
  59. mescroll: "",
  60. downOption: { //下拉刷新
  61. auto: true // 不自动加载 (mixin已处理第一个tab触发downCallback)
  62. },
  63. upOption: { //上拉加载
  64. auto: false, // 不自动加载
  65. page: {
  66. num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
  67. size: 10 // 每页数据的数量
  68. },
  69. noMoreSize: 5, //如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看; 默认5
  70. empty: {
  71. tip: '~ 空空如也 ~' // 提示
  72. // btnText: '去看看'
  73. }
  74. },
  75. imageList: [],
  76. advs: [],
  77. mtabs: [],
  78. tabIndex: 0, // 当前tab的下标
  79. fixedTop: false,
  80. top: 0,
  81. cateId: 0,
  82. isBest: false,
  83. dataList: [],
  84. recommendList: [],
  85. swHeightArr: {},
  86. swHeight: "400px",
  87. keyWord: "",
  88. dataItem: {},
  89. swiperAutoplay: true,
  90. famousItemHei: 0,
  91. scrollTopHall: 0,
  92. scrollTopStudy: 0,
  93. old: {
  94. scrollTopStudy: 0,
  95. scrollTopHall: 0,
  96. },
  97. activeTab: 0,
  98. scrollViewId:'scrollView0',
  99. indicatorLineLeft: 0,
  100. indicatorLineWidth: 0,
  101. tabList: [{
  102. id: "tab01",
  103. name: '名医讲堂'
  104. }, {
  105. id: "tab02",
  106. name: '学习中心'
  107. }],
  108. clientHeight: 0,
  109. }
  110. },
  111. onPageScroll(e) {
  112. this.top = e.scrollTop;
  113. },
  114. computed: {
  115. // 计算属性的 getter
  116. headerBG: function() {
  117. var top = this.top / 88;
  118. return 'rgba(255,92,3, ' + top + ')';
  119. },
  120. },
  121. onReady() {
  122. uni.getSystemInfo({
  123. success: (res) => {
  124. this.clientHeight = res.windowHeight - uni.upx2px(120) - res.statusBarHeight - 50;
  125. }
  126. })
  127. this.tabListSize = {};
  128. this.selectorQuery();
  129. },
  130. onShow() {
  131. this.swiperAutoplay = true;
  132. if (this.activeTab == 1) {
  133. this.$nextTick(() => {
  134. this.$refs['studyCenter'].onShowFun()
  135. });
  136. }
  137. },
  138. onHide() {
  139. this.swiperAutoplay = false;
  140. },
  141. mounted() {
  142. try {
  143. const system = uni.getSystemInfoSync();
  144. let itemWid = (system.windowWidth - 40 - 32) * 0.5 * 0.95;
  145. let tempHei = itemWid * 0.5;
  146. tempHei = uni.upx2px(tempHei) + 30;
  147. this.famousItemHei = tempHei;
  148. } catch (e) {
  149. }
  150. },
  151. methods: {
  152. scroll(e, type) {
  153. this.old[type] = e.detail.scrollTop
  154. },
  155. handleTab(activeTab) {
  156. this.activeTab = activeTab
  157. this.$nextTick(() => {
  158. this.selectorQuery()
  159. })
  160. },
  161. updateIndicator(left, width) {
  162. this.indicatorLineLeft = left;
  163. this.indicatorLineWidth = width;
  164. },
  165. selectorQuery() {
  166. uni.createSelectorQuery().in(this).selectAll('.tabbar-item').boundingClientRect((rects) => {
  167. rects.forEach((rect) => {
  168. this.tabListSize[rect.id] = rect;
  169. })
  170. this.updateIndicator(this.tabListSize[this.activeTab].left, this.tabListSize[this.activeTab]
  171. .width);
  172. }).exec();
  173. },
  174. // swiper划动
  175. onSwiperChange(e) {
  176. this.changeIdx(e.detail.current);
  177. },
  178. // 更新当前页
  179. changeIdx(index) {
  180. if (this.activeTab === index) return;
  181. this.activeTab = index;
  182. this.scrollViewId = 'scrollView' + this.activeTab;
  183. this.$nextTick(() => {
  184. this.selectorQuery()
  185. });
  186. },
  187. /*下拉刷新的回调 */
  188. downCallback() {
  189. this.mescroll.resetUpScroll(true);
  190. },
  191. /*上拉加载的回调*/
  192. upCallback(page) {
  193. this.mescroll.endByPage(1, 1);
  194. },
  195. getCourseCate: function() {
  196. let that = this;
  197. getCourseCate().then(res => {
  198. if (res.code == 200) {
  199. this.mtabs = res.data;
  200. let findIdx = this.mtabs.findIndex(item => item.dictLabel == '精选');
  201. // console.log("qxj findIdx:"+findIdx);
  202. if (findIdx == -1) {
  203. let dictItem = {
  204. "dictValue": 0,
  205. "dictLabel": "精选"
  206. };
  207. this.mtabs.unshift(dictItem);
  208. }
  209. this.isBest = true;
  210. if (this.mtabs.length > 0) {
  211. this.cateId = this.mtabs[0].dictValue;
  212. for (let i = 0; i < this.mtabs.length; i++) {
  213. if (i <= 4) {
  214. this.tabChange(i);
  215. }
  216. }
  217. //this.tabIndex=0;
  218. //this.dataItem=this.dataList[this.tabIndex.toString()]
  219. this.tabChange(0);
  220. }
  221. }
  222. },
  223. rej => {}
  224. );
  225. },
  226. getFamousCourseList: function(index) {
  227. let that = this;
  228. let params = {};
  229. if (this.isBest) {
  230. params = {
  231. "isBest": 1
  232. };
  233. } else {
  234. params = {
  235. "cateId": this.cateId
  236. };
  237. }
  238. if (this.dataList.hasOwnProperty(index + "")) {
  239. this.updateSwiperHeight(index);
  240. return;
  241. }
  242. getCourseList(params, 1, 6).then(res => {
  243. if (res.code == 200) {
  244. this.dataList[index + ""] = res.data.list;
  245. //this.$nextTick(() => {
  246. this.updateSwiperHeight(index);
  247. //});
  248. }
  249. },
  250. rej => {}
  251. );
  252. },
  253. getRecommendList: function() {
  254. let that = this;
  255. const params = {
  256. "isTui": 1
  257. };
  258. getCourseList(params, 1, 10).then(res => {
  259. if (res.code == 200) {
  260. this.recommendList = res.data.list;
  261. }
  262. },
  263. rej => {}
  264. );
  265. },
  266. swiperChange(e) {
  267. // console.log("qxj swiperChange");
  268. this.tabIndex = e.detail.current;
  269. this.tabChange(this.tabIndex);
  270. },
  271. tabChange(index) {
  272. // console.log("qxj tabChange index:"+index);
  273. this.tabIndex = index;
  274. const item = this.mtabs[index];
  275. if (item) {
  276. if (item.dictLabel == '精选') {
  277. this.isBest = true;
  278. } else {
  279. this.isBest = false;
  280. }
  281. this.cateId = item.dictValue;
  282. this.getFamousCourseList(index);
  283. }
  284. },
  285. updateSwiperHeight() {
  286. let dataArr = this.dataList[this.tabIndex.toString()];
  287. if (dataArr == undefined || dataArr.length == 0) {
  288. this.swHeight = 150;
  289. } else {
  290. uni.createSelectorQuery().in(this).select('#swiper-content').boundingClientRect(rect => {
  291. //console.log("qxj swHeight:"+this.swHeight);
  292. if (rect != null) {
  293. this.swHeight = rect.height + 20;
  294. }
  295. if (this.swHeight <= 100) {
  296. //所以(total + pagesize -1) / pagesize就得到总页数
  297. // console.log("qxj famousItemHei:"+this.famousItemHei);
  298. this.swHeight = (dataArr.length + 1) / 2 * this.famousItemHei;
  299. return;
  300. }
  301. }).exec();
  302. }
  303. },
  304. getAdvList() {
  305. //联网加载数据
  306. var that = this;
  307. var data = {
  308. advType: 12,
  309. status: 1
  310. }
  311. getAdvList(data).then(res => {
  312. if (res.code == 200) {
  313. that.imageList = [];
  314. that.advs = [];
  315. res.data.forEach(function(element) {
  316. if (element.imageUrl != null && element.imageUrl != "") {
  317. that.advs.push(element);
  318. that.imageList.push(element.imageUrl);
  319. }
  320. });
  321. } else {
  322. uni.showToast({
  323. icon: 'none',
  324. title: "请求失败"
  325. });
  326. }
  327. });
  328. },
  329. // 页面跳转
  330. navTo(url) {
  331. console.log("qxj url:" + url);
  332. uni.navigateTo({
  333. url: url
  334. });
  335. },
  336. loginNavTo(url) {
  337. this.utils.isLogin().then(res => {
  338. if(res){
  339. this.$navTo(url);
  340. }
  341. })
  342. }
  343. }
  344. }
  345. </script>
  346. <style scoped lang="scss">
  347. @mixin u-flex($flexD, $alignI, $justifyC) {
  348. display: flex;
  349. flex-direction: $flexD;
  350. align-items: $alignI;
  351. justify-content: $justifyC;
  352. }
  353. .container {
  354. font-family: PingFang SC, PingFang SC;
  355. padding-top: var(--status-bar-height);
  356. box-sizing: border-box;
  357. position: relative;
  358. z-index: 2;
  359. }
  360. .home_top_bg {
  361. width: 100%;
  362. height: auto;
  363. position: absolute;
  364. top: 0;
  365. left: 0;
  366. z-index: -1;
  367. }
  368. .tabbox {
  369. position: relative;
  370. margin-bottom: 22rpx;
  371. position: relative;
  372. .tabbar {
  373. height: 88rpx;
  374. @include u-flex(row, center, center);
  375. font-weight: 600;
  376. font-size: 32rpx;
  377. color: #222222;
  378. line-height: 88rpx;
  379. position: relative;
  380. .tabbar-item {
  381. margin: 0 24rpx;
  382. }
  383. .active {
  384. font-weight: 600;
  385. font-size: 40rpx;
  386. color: #018C39;
  387. position: relative;
  388. }
  389. }
  390. .tabbar-tabline-image {
  391. width: 36rpx;
  392. height: 12rpx;
  393. }
  394. .tabbar-tabline {
  395. position: absolute;
  396. bottom: 0;
  397. width: 0;
  398. height: 12rpx;
  399. display: flex;
  400. align-items: center;
  401. justify-content: center;
  402. }
  403. .tabbar-tabline-animation {
  404. transition-duration: 0.2s;
  405. transition-property: left;
  406. }
  407. }
  408. </style>