| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- <template>
- <div class="album-page-container">
- <header class="album-header-card">
- <div v-if="albumInfo" class="album-info-wrapper">
- <div class="album-cover-box">
- <el-image lazy fit="cover" class="header-cover-img" :src="albumInfo.coverUrl" />
- </div>
- <div class="album-detail-content">
- <div class="top-row">
- <h2 class="album-title">{{ albumInfo.title || '播放列表' }}</h2>
- <el-button type="primary" size="small" icon="el-icon-video-play" class="play-all-btn" @click="onPlayAlbum">播放全部</el-button>
- </div>
- <div class="filter-row">
- <div class="select-group">
- <span class="label hidden-xs-only">切换列表:</span>
- <el-select
- v-model="queryInfo.albumId"
- size="small"
- class="album-select"
- @change="onSelectChange"
- >
- <el-option
- v-for="(item, index) in allAlbums"
- :key="index"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </div>
- <div class="stats-tags">
- <el-tag size="mini" effect="plain" type="info">{{ albumInfo.total }} 个稿件</el-tag>
- <el-tag size="mini" effect="plain" type="success" class="mgl-8">{{ albumInfo.scopeStr }}</el-tag>
- </div>
- </div>
- </div>
- </div>
- </header>
- <main class="album-main-content">
- <div v-if="dataList.length === 0" class="empty-status">
- <el-empty description="暂无收藏内容" :image-size="150"></el-empty>
- </div>
- <el-row :gutter="20" class="video-grid">
- <el-col
- v-for="(item, index) in dataList"
- :key="index"
- :xs="12" :sm="8" :md="6" :lg="4" :xl="4"
- class="video-col"
- >
- <el-card :body-style="{ padding: '0px' }" class="video-card" shadow="hover">
- <div class="card-image-box">
- <router-link :to="`/video/${item.videoId}`" target="_blank">
- <el-image lazy fit="cover" class="card-cover" :src="item.coverUrl" />
- <div class="card-badges">
- <span class="duration">{{ item.duration }}</span>
- <span class="device-icon">
- <i :class="item.horizontal ? 'el-icon-monitor' : 'el-icon-mobile-phone'" />
- </span>
- </div>
- </router-link>
- </div>
- <div class="card-info">
- <router-link :to="`/video/${item.videoId}`" target="_blank" class="video-title-link">
- <h4 class="video-title">{{ item.title }}</h4>
- </router-link>
- <div class="video-meta">
- <router-link :to="`/user/${item.user.userId}`" target="_blank" class="user-link">
- <i class="el-icon-user" /> {{ item.user.screenName }}
- </router-link>
- <span class="pub-date">{{ item.pubDateStr }}</span>
- </div>
- <div class="card-btns">
- <el-button-group class="full-width-btns">
- <el-tooltip content="设为封面" placement="top" :disabled="screenWidth < 768">
- <el-button size="mini" icon="el-icon-picture-outline" @click="onSetCover(item)"></el-button>
- </el-tooltip>
- <el-tooltip content="删除收藏" placement="top" :disabled="screenWidth < 768">
- <el-button size="mini" type="danger" plain icon="el-icon-delete" @click="onDeleteItem(item)"></el-button>
- </el-tooltip>
- </el-button-group>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
- <div class="pagination-wrapper">
- <el-pagination
- background
- :small="screenWidth < 768"
- layout="total, prev, pager, next"
- :page-size="pageSize"
- :current-page="currentPage"
- :total="totalSize"
- @current-change="handleCurrentChange"
- />
- </div>
- </main>
- <el-backtop target=".admin-main"></el-backtop>
- </div>
- </template>
- <script>
- import { collectItem, getAlbumItems, getUserAlbumSelectList } from '@/api/collect'
- export default {
- name: 'AlbumPost',
- data() {
- return {
- allAlbums: [],
- queryInfo: { albumId: null, pn: 1 },
- screenWidth: document.body.clientWidth,
- currentPage: 1,
- pageSize: 12,
- totalSize: 0,
- dataList: [],
- albumInfo: null
- }
- },
- created() {
- this.getSelectList()
- const { albumId, pn } = this.$route.query
- if (albumId) this.queryInfo.albumId = albumId
- if (pn) {
- this.queryInfo.pn = parseInt(pn)
- this.currentPage = parseInt(pn)
- }
- this.getData()
- },
- mounted() {
- window.addEventListener('resize', this.handleResize)
- },
- beforeDestroy() {
- window.removeEventListener('resize', this.handleResize)
- },
- methods: {
- handleResize() {
- this.screenWidth = document.body.clientWidth
- },
- onSelectChange() {
- this.queryInfo.pn = 1
- this.currentPage = 1
- this.updateRouteAndData()
- },
- handleCurrentChange(page) {
- this.currentPage = page
- this.queryInfo.pn = page
- this.updateRouteAndData()
- const container = document.querySelector('.admin-main')
- if (container) container.scrollTo({ top: 0, behavior: 'smooth' })
- },
- updateRouteAndData() {
- this.$router.push({ path: '/bg/my/album', query: this.queryInfo })
- this.getData()
- },
- getData() {
- getAlbumItems(this.queryInfo).then(resp => {
- if (resp.code === 0) {
- this.dataList = resp.data.pageList.list
- this.totalSize = resp.data.pageList.totalSize
- this.albumInfo = resp.data.albumInfo
- this.queryInfo.albumId = this.albumInfo.albumId
- }
- })
- },
- getSelectList() {
- getUserAlbumSelectList().then(resp => {
- if (resp.code === 0) this.allAlbums = resp.data
- })
- },
- onSetCover(item) {
- collectItem({ albumId: this.albumInfo.albumId, postId: item.videoId, action: 3 }).then(res => {
- if (res.code === 0) {
- this.$message.success('已更新封面')
- this.getData()
- }
- })
- },
- onDeleteItem(item) {
- this.$confirm('确定移除该收藏吗?', '提示', { type: 'warning' }).then(() => {
- collectItem({ albumId: this.albumInfo.albumId, postId: item.videoId, action: 2 }).then(res => {
- if (res.code === 0) {
- this.$message.success('已移除')
- this.getData()
- }
- })
- }).catch(() => {})
- },
- onPlayAlbum() { this.$message.info('播放列表功能建设中') }
- }
- }
- </script>
- <style scoped>
- /* 1. 基础容器与布局修复 */
- .album-page-container {
- padding: 0;
- max-width: 1400px; /* 限制 PC 端最大宽度,防止卡片过稀疏 */
- margin: 0 auto;
- }
- .album-header-card {
- background: #fff;
- border-radius: 8px;
- padding: 24px;
- margin-bottom: 20px;
- box-shadow: 0 2px 12px rgba(0,0,0,0.04);
- }
- .album-info-wrapper {
- display: flex;
- gap: 24px;
- }
- .album-cover-box {
- width: 180px;
- height: 110px;
- flex-shrink: 0;
- border-radius: 6px;
- overflow: hidden;
- }
- .header-cover-img { width: 100%; height: 100%; }
- .album-detail-content { flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: space-between; }
- .top-row { display: flex; justify-content: space-between; align-items: flex-start; }
- .album-title { margin: 0; font-size: 20px; color: #303133; font-weight: 600; }
- .filter-row { display: flex; align-items: center; justify-content: space-between; margin-top: 15px; }
- .select-group { display: flex; align-items: center; }
- .album-select { width: 200px; }
- .mgl-8 { margin-left: 8px; }
- /* 2. 视频卡片 PC 端优化 */
- .video-grid { margin: 0 -10px; } /* 抵消 col 的 padding */
- .video-card {
- border-radius: 8px;
- border: 1px solid #ebeef5;
- margin-bottom: 20px;
- transition: all 0.3s ease;
- }
- .card-image-box {
- position: relative;
- width: 100%;
- padding-top: 56.25%; /* 16:9 比例锁定 */
- }
- .card-cover {
- position: absolute;
- top: 0; left: 0;
- width: 100%; height: 100%;
- }
- .card-badges {
- position: absolute;
- bottom: 6px; left: 0; right: 0;
- padding: 0 8px;
- display: flex;
- justify-content: space-between;
- background: linear-gradient(transparent, rgba(0,0,0,0.6));
- color: #fff; font-size: 12px;
- }
- .card-info { padding: 12px; }
- .video-title {
- margin: 0 0 10px 0;
- font-size: 14px;
- height: 40px; /* 两行高度固定 */
- line-height: 20px;
- color: #303133;
- display: -webkit-box;
- -webkit-line-clamp: 2;
- -webkit-box-orient: vertical;
- overflow: hidden;
- }
- .video-meta {
- display: flex;
- justify-content: space-between;
- font-size: 12px;
- color: #909399;
- margin-bottom: 12px;
- }
- .user-link { color: #606266; text-decoration: none; max-width: 60%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
- .user-link:hover { color: #409EFF; }
- /* 按钮组 */
- .full-width-btns { display: flex; width: 100%; }
- .full-width-btns .el-button { flex: 1; }
- .pagination-wrapper { padding: 40px 0; display: flex; justify-content: center; }
- /* 3. 移动端专项适配修复溢出 */
- @media screen and (max-width: 768px) {
- .album-header-card { padding: 15px; margin-bottom: 15px; }
- .album-info-wrapper { flex-direction: column; gap: 12px; align-items: center; text-align: center; }
- .album-cover-box { width: 140px; height: 85px; }
- .top-row { flex-direction: column; align-items: center; gap: 10px; }
- .album-title { font-size: 16px; }
- .filter-row { flex-direction: column; gap: 10px; align-items: stretch; }
- .album-select { width: 100%; }
- .video-grid { margin: 0 -5px; }
- .video-col { padding: 0 5px !important; }
- .video-title { font-size: 13px; height: 36px; line-height: 18px; margin-bottom: 6px; }
- .video-meta { flex-direction: column; gap: 4px; margin-bottom: 8px; }
- .card-info { padding: 8px; }
- }
- /* 隐藏辅助类 */
- @media screen and (max-width: 767px) {
- .hidden-xs-only { display: none !important; }
- }
- </style>
|