Files
ks-app-employment-service/packageB/train/video/videoDetail.vue
2025-10-31 17:47:51 +08:00

317 lines
8.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<AppLayout :title="title" :show-bg-image="false" @onScrollBottom="getDataList('add')">
<!-- <template #headerleft>
<view class="btnback">
<image src="@/static/icon/back.png" @click="navBack"></image>
</view>
</template> -->
<template #headContent>
<view class="collection-search">
<view class="search-content">
<view class="header-input button-click">
<uni-icons class="iconsearch" color="#6A6A6A" type="search" size="22"></uni-icons>
<input
class="input"
v-model="searchKeyword"
@confirm="searchVideo"
placeholder="输入视频名称"
placeholder-class="inputplace"
/>
<uni-icons
v-if="searchKeyword"
class="clear-icon"
type="clear"
size="24"
color="#999"
@click="clearSearch"
/>
</view>
</view>
</view>
</template>
<view class="main-list">
<view class="list-title">
<text>视频列表</text>
<view class="title-line"></view>
</view>
<view class="video-grid" v-if="pageState.list.length">
<view
v-for="video in pageState.list"
:key="video.id || video.videoId"
class="video-item"
:style="getItemBackgroundStyle('video-bg.png')"
@click="playVideo(video)"
>
<view class="video-cover">
<image
:src="video.coverImage || video.videoCover || '/static/icon/video.png'"
mode="aspectFill"
></image>
</view>
<view class="video-info">
{{ video.title || video.videoName || '未命名视频' }}
</view>
</view>
</view>
<empty v-else pdTop="200"></empty>
</view>
</AppLayout>
</template>
<script setup>
import { inject, ref, reactive } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
const { $api, navTo, navBack } = inject('globalFunction');
// state
const title = ref('');
const searchKeyword = ref('');
const pageState = reactive({
page: 0,
list: [],
total: 0,
maxPage: 1,
pageSize: 12,
search: {},
});
const baseUrl = 'http://10.110.145.145/images/train/';
const getItemBackgroundStyle = (imageName) => ({
backgroundImage: `url(${baseUrl + imageName})`,
backgroundSize: 'cover', // 覆盖整个容器
backgroundPosition: 'center', // 居中
backgroundRepeat: 'no-repeat'
});
// 模拟视频数据
const mockVideoData = [
{
id: '1',
title: '职业技能培训基础课程',
coverImage: '/static/icon/server1.png',
videoUrl: ''
},
{
id: '2',
title: '面试技巧分享',
coverImage: '/static/icon/server2.png',
videoUrl: ''
},
{
id: '3',
title: '简历制作指南',
coverImage: '/static/icon/server3.png',
videoUrl: ''
},
{
id: '4',
title: '职场沟通技巧',
coverImage: '/static/icon/server4.png',
videoUrl: ''
},
{
id: '5',
title: '职业规划讲座',
coverImage: '/static/icon/flame.png',
videoUrl: ''
},
{
id: '6',
title: '行业趋势分析',
coverImage: '/static/icon/flame2.png',
videoUrl: ''
}
];
onLoad(() => {
getDataList('refresh');
});
// 搜索视频
function searchVideo() {
getDataList('refresh');
}
// 清除搜索内容
function clearSearch() {
searchKeyword.value = '';
getDataList('refresh');
}
// 获取视频列表
function getDataList(type = 'add') {
if (type === 'refresh') {
pageState.page = 1;
pageState.maxPage = 1;
}
if (type === 'add' && pageState.page < pageState.maxPage) {
pageState.page += 1;
}
// 模拟API请求延迟
setTimeout(() => {
// 在实际项目中这里应该调用真实的API接口
// 目前使用模拟数据
let filteredList = [...mockVideoData];
// 如果有搜索关键词,进行过滤
if (searchKeyword.value.trim()) {
filteredList = filteredList.filter(video =>
video.title.toLowerCase().includes(searchKeyword.value.toLowerCase())
);
}
const start = 0;
const end = pageState.pageSize;
const pageData = filteredList.slice(start, end);
if (type === 'add') {
pageState.list = [...pageState.list, ...pageData];
} else {
pageState.list = pageData;
}
pageState.total = filteredList.length;
pageState.maxPage = Math.ceil(pageState.total / pageState.pageSize);
}, 300);
}
// 播放视频
function playVideo(video) {
// 在实际项目中,这里应该导航到视频播放页面
// 或者调用视频播放组件
console.log('播放视频:', video.title);
// 示例navTo(`/pages/videoPlayer/videoPlayer?id=${video.id}`);
$api.msg(`准备播放: ${video.title}`);
}
</script>
<style lang="stylus" scoped>
.btnback{
width: 64rpx;
height: 64rpx;
}
.btn {
display: flex;
justify-content: space-between;
align-items: center;
width: 52rpx;
height: 52rpx;
}
image {
height: 100%;
width: 100%;
}
.collection-search{
padding: 10rpx 20rpx;
.search-content{
position: relative
display: flex
align-items: center
padding: 14rpx 0
.header-input{
padding: 0
width: calc(100%);
position: relative
.iconsearch{
position: absolute
left: 30rpx;
top: 50%
transform: translate(0, -50%)
z-index: 1
}
.input{
padding: 0 80rpx 0 80rpx
height: 80rpx;
background: #FFFFFF;
border-radius: 75rpx 75rpx 75rpx 75rpx;
border: 2rpx solid #ECECEC
font-size: 28rpx;
}
.clear-icon{
position: absolute
right: 30rpx;
top: 50%
transform: translate(0, -50%)
z-index: 1
cursor: pointer
}
.inputplace{
font-weight: 400;
font-size: 28rpx;
color: #B5B5B5;
}
}
}
}
.main-list{
background-color: #ffffff;
padding: 20rpx 20rpx 28rpx 20rpx;
margin:10rpx 30rpx ;
box-shadow: 0px 3px 20px 0px rgba(0,105,234,0.1);
border-radius: 12px;
}
.list-title{
font-weight: bold;
font-size: 36rpx;
color: #404040;
position: relative;
margin-bottom: 20px;
}
.title-line{
position: absolute;
bottom: -10rpx;
left: 36rpx;
width: 70rpx;
height: 8rpx;
background: linear-gradient(90deg, #FFAD58 0%, #FF7A5B 100%);
border-radius: 2px;
}
.video-grid{
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20rpx;
}
.video-item{
border-radius: 12rpx;
overflow: hidden;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
transition: transform 0.2s;
padding: 20rpx
}
.video-item:active{
transform: scale(0.98);
}
.video-cover{
position: relative;
width: 100%;
padding-top: 56.25%; /* 16:9 比例 */
background: #f0f0f0;
border-radius: 4rpx;
}
.video-cover image{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.video-info{
padding: 16rpx 16rpx 0 16rpx;
font-size: 26rpx;
color: #333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: center;
}
.video-title{
font-size: 28rpx;
color: #333;
line-height: 40rpx;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
</style>