index.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. <template>
  2. <view class="page">
  3. <LoginRequiredState v-if="!isLoggedIn" />
  4. <template v-else>
  5. <InformationTabs v-model="activeTab" :tabs="tabs" />
  6. <AcademicInfoPanel v-if="activeTab === 'academic'" ref="academicPanelRef" />
  7. <ProductAlbumPanel v-else ref="albumPanelRef" />
  8. </template>
  9. </view>
  10. </template>
  11. <script setup lang="ts">
  12. import { computed, ref } from 'vue'
  13. import { onPullDownRefresh, onReachBottom, onShareAppMessage } from '@dcloudio/uni-app'
  14. import { useUserStore } from '@/stores/modules/user'
  15. import AcademicInfoPanel from './components/academic/AcademicInfoPanel.vue'
  16. import ProductAlbumPanel from './components/album/ProductAlbumPanel.vue'
  17. import InformationTabs from './components/shared/InformationTabs.vue'
  18. import LoginRequiredState from './components/shared/LoginRequiredState.vue'
  19. type TabKey = 'academic' | 'album'
  20. interface TabItem {
  21. label: string
  22. value: TabKey
  23. }
  24. interface PanelExpose {
  25. refresh: () => Promise<void>
  26. loadMore: () => Promise<void>
  27. }
  28. interface ShareDataset {
  29. id?: string | number
  30. title?: string
  31. activeTab?: TabKey
  32. }
  33. const userStore = useUserStore()
  34. const isLoggedIn = computed<boolean>(() => {
  35. return Boolean(userStore.isLoggedIn)
  36. })
  37. const tabs: TabItem[] = [
  38. {
  39. label: '学术信息',
  40. value: 'academic',
  41. },
  42. {
  43. label: '产品相册',
  44. value: 'album',
  45. },
  46. ]
  47. const activeTab = ref<TabKey>('academic')
  48. const academicPanelRef = ref<PanelExpose | null>(null)
  49. const albumPanelRef = ref<PanelExpose | null>(null)
  50. const currentPanel = computed<PanelExpose | null>(() => {
  51. return activeTab.value === 'academic' ? academicPanelRef.value : albumPanelRef.value
  52. })
  53. onReachBottom(() => {
  54. if (!isLoggedIn.value) return
  55. void currentPanel.value?.loadMore()
  56. })
  57. onPullDownRefresh(async () => {
  58. try {
  59. if (!isLoggedIn.value) return
  60. await currentPanel.value?.refresh()
  61. } finally {
  62. uni.stopPullDownRefresh()
  63. }
  64. })
  65. onShareAppMessage((res) => {
  66. const dataset =
  67. res.from === 'button' ? (res.target?.dataset as ShareDataset | undefined) : undefined
  68. const id = dataset?.id
  69. const title = dataset?.title || '要易小助手'
  70. const type = dataset?.activeTab || activeTab.value
  71. return {
  72. title,
  73. path: id
  74. ? `/pages-sub-packages/information/detail/index?type=${type}&id=${id}`
  75. : '/pages/information/index',
  76. }
  77. })
  78. </script>
  79. <style scoped lang="scss">
  80. .page {
  81. min-height: 100vh;
  82. background: #fff;
  83. }
  84. </style>