video-page-layout.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. <template>
  2. <z-paging ref="paging" v-model="list" @query="handleQuery" @on-refresh="handleRefresh">
  3. <view v-if="list.length" class="p-30">
  4. <tree-view :tree-data="list" @leaf-click="handleLeafClick">
  5. <template #icon="{deep}">
  6. <uv-icon v-if="deep==0" name="arrow-right"/>
  7. </template>
  8. <template #node="{node, deep}">
  9. <view v-if="deep==0" class="flex-1 fx-col gap-5">
  10. <text class="text-main font-[PingFang]">{{ node.label }}</text>
  11. </view>
  12. <view v-else class="flex-1 fx-row items-center gap-10">
  13. <uv-icon :name="node.img" width="40" height="40" img-mode="cover"
  14. class="rounded-[20px] overflow-hidden"/>
  15. <text class="text-main text-sm font-[PingFang]">{{ node.name }}</text>
  16. </view>
  17. </template>
  18. <template #command="{node, deep}">
  19. <uv-button v-if="deep > 0" type="primary" shape="circle" text="播放" icon="play-circle"
  20. icon-color="(--primary-color)" plain :custom-style="{height: '32px'}"
  21. @click="handleVideoPlay(node)"/>
  22. </template>
  23. </tree-view>
  24. </view>
  25. </z-paging>
  26. </template>
  27. <script setup>
  28. import {ref} from 'vue'
  29. import TreeView from "@/pages/topic-center/index/components/tree-view.vue";
  30. import {useCacheStore} from "@/hooks/useCacheStore";
  31. import {cacheActions} from "@/hooks/defineCacheActions";
  32. import {empty} from "@/uni_modules/uv-ui-tools/libs/function/test";
  33. import {useTransfer} from "@/hooks/useTransfer";
  34. import mxConst from "@/common/mxConst";
  35. const props = defineProps({
  36. subject: {
  37. type: Object,
  38. default: () => ({})
  39. }
  40. })
  41. const list = ref([])
  42. const {dispatchCache, removeCache} = useCacheStore()
  43. const {transferTo} = useTransfer()
  44. const paging = ref(null)
  45. const handleQuery = async () => {
  46. try {
  47. const {code: subject} = props.subject
  48. const res = await dispatchCache(cacheActions.getVideoKnowledge, {subject})
  49. // 默认收起,因为有缓存,防止用户之前打开过多引起渲染缓慢
  50. res.rows.forEach(k => k.expanded = false)
  51. // completeByNoMore 非标准返回,后台未分页
  52. paging.value.completeByNoMore(res.rows, true)
  53. } catch {
  54. paging.value.complete(false)
  55. }
  56. }
  57. const handleRefresh = async () => {
  58. // 知识点树可以精准清除
  59. const {code: subject} = props.subject
  60. removeCache(cacheActions.getVideoKnowledge, {subject})
  61. // 视频只能全清,但因为缓存结果有挂在知识点上所以,旁边的tab见效没有那么快
  62. removeCache(cacheActions.getVideoOfKnowledge)
  63. }
  64. const handleLeafClick = async ({node, deep}) => {
  65. if (deep === 0) {
  66. node.expanded = !!!node.expanded // 强制展开
  67. if (empty(node.children)) {
  68. if (!node.loading) {
  69. node.loading = true
  70. try {
  71. const payload = {subject: props.subject.code, knowledge: node.code, pageNum: 1, pageSize: 100}
  72. const res = await dispatchCache(cacheActions.getVideoOfKnowledge, payload)
  73. node.children = res.rows
  74. } catch (e) {
  75. node.expanded = false // 异常强制关闭
  76. } finally {
  77. node.loading = false
  78. }
  79. }
  80. }
  81. }
  82. }
  83. const handleVideoPlay = (node) => {
  84. // 尝试传递更多数据,不使用playVideo,启用usingCache
  85. // playVideo(node.aliId, node.aliIdType, node.name)
  86. const nodeWithKnowledge = list.value.find(n => n.children?.includes(node))
  87. transferTo(mxConst.routes.videoPlay, {
  88. aliId: node.aliId,
  89. aliIdType: node.aliIdType,
  90. title: node.name,
  91. node: nodeWithKnowledge
  92. }, null, true)
  93. }
  94. </script>
  95. <style scoped>
  96. </style>