Home.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. <template>
  2. <div>
  3. <el-row class="movie-list">
  4. <el-col v-if="user" :md="24">
  5. <el-card :body-style="{ padding: '0px' }" class="card">
  6. <div slot="header" class="clearfix">
  7. <el-row>
  8. <el-col :md="1">
  9. <el-avatar>
  10. <el-image :src="user.avatarUrl" />
  11. </el-avatar>
  12. </el-col>
  13. <el-col :md="22">
  14. <span>{{ user.screenName }}</span>
  15. <span v-html="'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'" />
  16. <el-button
  17. type="danger"
  18. size="mini"
  19. :icon="followButton.icon"
  20. @click="followUser(user.userId)"
  21. >
  22. <span>{{ followButton.text }}</span>
  23. </el-button>
  24. <el-button
  25. type="danger"
  26. size="mini"
  27. icon="el-icon-message"
  28. @click="sendMessage(user.userId)"
  29. >
  30. <span>发消息</span>
  31. </el-button>
  32. <el-tag v-if="user.biliUserId !== undefined && user.biliUserId !== null" size="mini" type="'success'" disable-transitions>
  33. <a target="_blank" :href="`https://space.bilibili.com/` + user.biliUserId">bili</a>
  34. </el-tag>
  35. </el-col>
  36. <el-col :md="1">
  37. <StampBadge
  38. v-if="user.vip"
  39. style="position: relative; top: 0; right: 0"
  40. size="small"
  41. color="warning"
  42. content="小会员"
  43. :rotate="0"
  44. />
  45. </el-col>
  46. </el-row>
  47. <el-row>
  48. <span v-if="user.signature !== null" v-html="user.signature" />
  49. <span v-if="user.signature === undefined || user.signature === null">-</span>
  50. </el-row>
  51. <el-row>
  52. <br>
  53. <router-link target="_blank" :to="`/user/${user.userId}/following`">
  54. <span class="el-icon-user">关注数: {{ user.following }}</span>
  55. </router-link>
  56. <span v-html="'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'" />
  57. <router-link target="_blank" :to="`/user/${user.userId}/follower`">
  58. <span class="el-icon-user">粉丝数: {{ user.follower }}</span>
  59. </router-link>
  60. </el-row>
  61. </div>
  62. </el-card>
  63. </el-col>
  64. </el-row>
  65. <el-row>
  66. <el-col :md="24" class="movie-list">
  67. <el-tabs v-if="userContentData !== null" v-model="activeName" @tab-click="tabClick">
  68. <el-tab-pane name="video">
  69. <span slot="label">
  70. 视频<el-badge :value="userContentData.videoCount" :max="9999" class="item" type="warning" />
  71. </span>
  72. <div v-if="activeName === 'video'">
  73. <el-col v-for="(video, index) in dataList" :key="index" :md="6" :sm="12" :xs="12">
  74. <video-card :video="video" />
  75. </el-col>
  76. </div>
  77. </el-tab-pane>
  78. <el-tab-pane name="image">
  79. <span slot="label">
  80. 图片<el-badge :value="userContentData.imageCount" :max="9999" class="item" type="warning" />
  81. </span>
  82. <div v-if="activeName === 'image'">
  83. <el-col v-for="(album, index) in dataList" :key="index" :md="6" :sm="12" :xs="12">
  84. <image-album-card :image-album="album" />
  85. </el-col>
  86. </div>
  87. </el-tab-pane>
  88. <el-tab-pane name="album">
  89. <span slot="label">
  90. 播放列表<el-badge :value="userContentData.albumCount" :max="9999" class="item" type="warning" />
  91. </span>
  92. <div v-if="activeName === 'album'">
  93. <el-col
  94. v-for="(item, index) in dataList"
  95. :key="index"
  96. :md="6"
  97. :sm="12"
  98. :xs="12"
  99. style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px"
  100. >
  101. <el-card :body-style="{ padding: '0px' }" class="card">
  102. <div class="imgs" style="cursor: pointer" :title="item.albumName">
  103. <router-link style="text-decoration-line: none" target="_blank" :to="`/playlist/${item.albumId}`">
  104. <el-image
  105. lazy
  106. fit="cover"
  107. class="coverImg"
  108. :src="item.coverUrl"
  109. />
  110. <span class="el-icon-files" style="position: absolute; bottom: 0; right: 10%; color:red">
  111. {{ item.total }}
  112. </span>
  113. </router-link>
  114. </div>
  115. <div style="padding: 14px">
  116. <router-link style="text-decoration-line: none" target="_blank" :to="`/playlist/${item.albumId}`">
  117. <span style="left: 0;margin-bottom: 0px;color: black;">{{ item.albumName | ellipsis }}</span>
  118. </router-link>
  119. </div>
  120. </el-card>
  121. </el-col>
  122. </div>
  123. </el-tab-pane>
  124. </el-tabs>
  125. </el-col>
  126. <el-col :span="24" class="pagination">
  127. <el-pagination
  128. background
  129. :small="screenWidth <= 768"
  130. hide-on-single-page
  131. layout="prev, pager, next"
  132. :page-size="pageSize"
  133. :current-page="currentPage"
  134. :total="totalSize"
  135. @current-change="handleCurrentChange"
  136. @prev-click="handleCurrentChange"
  137. @next-click="handleCurrentChange"
  138. />
  139. </el-col>
  140. </el-row>
  141. <el-row v-if="showEmpty" class="not-result">
  142. <el-col :span="12" :offset="6">
  143. <img src="@/assets/img/icon/not-collection.png">
  144. <div>该用户还没发布任何东西呢</div>
  145. </el-col>
  146. </el-row>
  147. </div>
  148. </template>
  149. <script>
  150. import StampBadge from '@/components/StampBadge'
  151. import VideoCard from '@/components/card/VideoCard'
  152. import ImageAlbumCard from '@/components/card/ImageAlbumCard'
  153. import { getUserInfo, checkRelation, followUser, unfollowUser } from '@/api/user'
  154. import { getUserContentData, getUserVideos } from '@/api/video'
  155. import { getAlbumImage1 } from '@/api/image'
  156. import { getUserPlaylist } from '@/api/collect'
  157. export default {
  158. name: 'UserHome',
  159. filters: {
  160. ellipsis(value) {
  161. if (!value) return ''
  162. const max = 15
  163. if (value.length > max) {
  164. return value.slice(0, max) + '...'
  165. }
  166. return value
  167. },
  168. ellipsisUsername(value) {
  169. if (!value) return ''
  170. const max = 10
  171. if (value.length > max) {
  172. return value.slice(0, max) + '...'
  173. }
  174. return value
  175. }
  176. },
  177. components: { StampBadge, VideoCard, ImageAlbumCard },
  178. data() {
  179. return {
  180. // 屏幕宽度, 为了控制分页条的大小
  181. screenWidth: document.body.clientWidth,
  182. user: null,
  183. userId: null,
  184. followButton: {
  185. icon: 'el-icon-plus',
  186. text: '关注'
  187. },
  188. activeName: 'video',
  189. currentPage: 1,
  190. pageSize: 12,
  191. totalSize: 0,
  192. dataList: [],
  193. queryInfo: {
  194. userId: null,
  195. pn: 1
  196. },
  197. showEmpty: true,
  198. userContentData: null
  199. }
  200. },
  201. watch: {
  202. $route() {
  203. this.$router.go()
  204. }
  205. },
  206. created() {
  207. this.userId = this.$route.params.id
  208. this.queryInfo.userId = this.userId
  209. getUserInfo(this.userId).then(resp => {
  210. if (resp.code === 0) {
  211. this.user = resp.data
  212. const path = this.$route.path
  213. if (path.endsWith('video')) {
  214. this.activeName = 'video'
  215. document.title = this.user.screenName + '的视频'
  216. } else if (path.endsWith('image')) {
  217. this.activeName = 'image'
  218. document.title = this.user.screenName + '的图片'
  219. } else if (path.endsWith('album')) {
  220. this.activeName = 'album'
  221. document.title = this.user.screenName + '的播放列表'
  222. } else {
  223. document.title = this.user.screenName + '的主页'
  224. }
  225. this.getData()
  226. }
  227. })
  228. checkRelation(this.userId).then(resp => {
  229. if (resp.code === 0) {
  230. if (resp.data) {
  231. this.followButton.text = '已关注'
  232. this.followButton.icon = 'el-icon-check'
  233. }
  234. }
  235. })
  236. getUserContentData(this.userId).then(resp => {
  237. if (resp.code === 0) {
  238. this.userContentData = resp.data
  239. }
  240. })
  241. },
  242. mounted() {
  243. // 当窗口宽度改变时获取屏幕宽度
  244. window.onresize = () => {
  245. return () => {
  246. window.screenWidth = document.body.clientWidth
  247. this.screenWidth = window.screenWidth
  248. }
  249. }
  250. },
  251. methods: {
  252. followUser(userId) {
  253. if (this.followButton.text === '关注') {
  254. followUser(userId).then(resp => {
  255. if (resp.code === 0) {
  256. this.followButton.text = '已关注'
  257. this.followButton.icon = 'el-icon-check'
  258. }
  259. })
  260. } else {
  261. unfollowUser(userId).then(resp => {
  262. if (resp.code === 0) {
  263. this.followButton.text = '关注'
  264. this.followButton.icon = 'el-icon-plus'
  265. }
  266. })
  267. }
  268. },
  269. sendMessage(userId) {
  270. this.$message.info('暂未实现')
  271. },
  272. handleCurrentChange(pageNumber) {
  273. this.currentPage = pageNumber
  274. this.queryInfo.pn = pageNumber
  275. this.getData()
  276. // 回到顶部
  277. scrollTo(0, 0)
  278. },
  279. tabClick(tab) {
  280. this.dataList = []
  281. this.activeName = tab.name
  282. this.goToTab(this.activeName)
  283. },
  284. goToTab(activeName) {
  285. const path = '/user/' + this.userId + '/' + activeName
  286. if (this.$route.path === path) {
  287. this.$router.go(0)
  288. return
  289. }
  290. this.$router.push(path)
  291. },
  292. getData() {
  293. this.dataList = []
  294. if (this.activeName === 'video') {
  295. this.userVideoListWrapper(this.currentPage, this.userId)
  296. } else if (this.activeName === 'image') {
  297. this.userImageWrapper(this.currentPage, this.userId)
  298. } else if (this.activeName === 'album') {
  299. this.userAlbumWrapper(this.currentPage, this.userId)
  300. }
  301. },
  302. userVideoListWrapper(pageNumber, userId) {
  303. getUserVideos(userId, pageNumber).then(resp => {
  304. if (resp.code === 0) {
  305. const respData = resp.data
  306. this.dataList = respData.list
  307. this.totalSize = respData.totalSize
  308. this.showEmpty = this.dataList.length === 0
  309. }
  310. })
  311. },
  312. userImageWrapper(pageNumber, userId) {
  313. getAlbumImage1(pageNumber, userId).then(resp => {
  314. if (resp.code === 0) {
  315. const respData = resp.data
  316. this.dataList = respData.list
  317. this.totalSize = respData.totalSize
  318. this.showEmpty = this.dataList.length === 0
  319. }
  320. })
  321. },
  322. userAlbumWrapper(pageNumber, userId) {
  323. getUserPlaylist(this.queryInfo).then(resp => {
  324. if (resp.code === 0) {
  325. const respData = resp.data
  326. this.dataList = respData.list
  327. this.totalSize = respData.totalSize
  328. this.showEmpty = this.dataList.length === 0
  329. }
  330. })
  331. }
  332. }
  333. }
  334. </script>
  335. <style scoped>
  336. .movie-list {
  337. padding-top: 15px;
  338. padding-left: 6%;
  339. padding-right: 6%;
  340. }
  341. .pagination {
  342. text-align: center;
  343. padding: 10px;
  344. }
  345. /*处于手机屏幕时*/
  346. @media screen and (max-width: 768px){
  347. .movie-list {
  348. padding-top: 8px;
  349. padding-left: 0.5%;
  350. padding-right: 0.5%;
  351. }
  352. .coverImg {
  353. height: 120px !important;
  354. }
  355. }
  356. .not-result {
  357. padding-top: 100px;
  358. padding-bottom: 100px;
  359. text-align: center;
  360. }
  361. .item {
  362. margin-top: 10px;
  363. margin-right: 40px;
  364. }
  365. .coverImg {
  366. width: 100%;
  367. height: 90px;
  368. display: block;
  369. }
  370. .imgs {
  371. position: relative;
  372. }
  373. </style>