飞天云平台-国产化
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

176 lines
6.6 KiB

<template>
<div class="config-item-main">
<span class="data-title">图书推荐</span>
<div class="upload-item">
<p>推荐列表</p>
<div class="book-swiper-wrapper">
<swiper
ref="bookSwiper"
:options="swiperOptions"
class="book-swiper"
>
<swiper-slide
v-for="(book, index) in bookList"
:key="book.id"
class="book-list-item"
>
<img :src="book.url || require('@/assets/images/screen/book.jpg')" alt="图书封面">
<span style="position: absolute; top: 0; left: 0;">{{ book.id }}</span>
<div class="book-select" @click.stop="toggleBookSelect(index)">
<i v-if="book.selected" class="iconfont icon-wancheng" />
<i v-else class="iconfont icon-weixuan" />
</div>
<div class="book-delete" @click.stop="deleteBook(index)">
<i class="iconfont icon-shanchu" />
</div>
</swiper-slide>
</swiper>
</div>
<!-- <div class="book-upload-btn" @click.stop="uploadBook"><i class="iconfont icon-shangchuan2" /></div> -->
</div>
<div style="display: flex; flex-direction: column; justify-content: flex-start; margin-left: 15px;">
<el-button size="mini" type="primary" @click.stop="uploadBook"><i class="iconfont icon-shangchuan" />图书上传</el-button>
<el-button size="mini" style="margin-left: 0 !important; margin-top: 10px;" :disabled="!hasSelectedItems" @click="batchDelete">
<i class="iconfont icon-shanchu" />
批量删除
</el-button>
</div>
<addBookDialog ref="addBookRef" />
</div>
</template>
<script>
import { swiper, swiperSlide } from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
import addBookDialog from './addBookDialog'
import { mapGetters } from 'vuex'
// import { getCurrentTime } from '@/utils/index'
// import { upload } from '@/utils/upload'
export default {
name: 'BookRecommend',
components: {
swiper,
swiperSlide,
addBookDialog
},
data() {
return {
bookList: [
{ id: 1, url: require('@/assets/images/screen/book.jpg'), selected: false },
{ id: 2, url: require('@/assets/images/screen/book.jpg'), selected: true },
{ id: 3, url: require('@/assets/images/screen/book.jpg'), selected: false },
{ id: 4, url: require('@/assets/images/screen/book.jpg'), selected: false },
{ id: 5, url: require('@/assets/images/screen/book.jpg'), selected: false },
{ id: 6, url: require('@/assets/images/screen/book.jpg'), selected: false },
{ id: 7, url: require('@/assets/images/screen/book.jpg'), selected: false },
{ id: 8, url: require('@/assets/images/screen/book.jpg'), selected: false },
{ id: 9, url: require('@/assets/images/screen/book.jpg'), selected: false },
{ id: 10, url: require('@/assets/images/screen/book.jpg'), selected: false },
{ id: 11, url: require('@/assets/images/screen/book.jpg'), selected: false },
{ id: 12, url: require('@/assets/images/screen/book.jpg'), selected: false },
{ id: 13, url: require('@/assets/images/screen/book.jpg'), selected: false },
{ id: 14, url: require('@/assets/images/screen/book.jpg'), selected: false },
{ id: 15, url: require('@/assets/images/screen/book.jpg'), selected: false }
],
swiperOptions: {
slidesPerView: 'auto', // 保持自动适应数量
freeMode: true, // 自由滑动模式
// 关键:添加间距配置(匹配 slide 的左右 margin 总和 5+5=10px)
spaceBetween: 10,
// 优化自由滑动动量,确保能滑到最末端
freeModeMomentum: true, // 启用动量滑动
freeModeMomentumRatio: 0.6, // 动量衰减比例(值越大滑动越远)
freeModeMomentumVelocityRatio: 1.2, // 动量速度比例
freeModeSticky: true, // 滑动结束时自动吸附到最近的项(增强稳定性)
// 关键:在最后一个 slide 后添加 20px 缓冲空间,避免被容器遮挡
slidesOffsetAfter: 20,
grabCursor: true,
on: {
resize: function() {
this.update()
}
}
}
}
},
computed: {
...mapGetters([
'baseApi'
]),
hasSelectedItems() {
return this.bookList.some(book => book.selected)
}
},
created() {
},
mounted() {
},
methods: {
updateBookSwiper() {
if (this.$refs.bookSwiper && this.$refs.bookSwiper.swiper) {
const swiper = this.$refs.bookSwiper.swiper
swiper.update() // 重新计算尺寸和位置
swiper.slideTo(swiper.activeIndex, 0) // 重置当前位置(避免偏移)
setTimeout(() => {
swiper.update()
}, 0)
}
},
// 图书推荐
toggleBookSelect(index) {
this.bookList[index].selected = !this.bookList[index].selected
},
deleteBook(index) {
this.$confirm('确定要删除这本图书吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
this.bookList.splice(index, 1)
this.$nextTick(() => {
this.$refs.bookSwiper.swiper.update()
})
this.$message.success('删除成功!')
}).catch(() => {
// 取消删除不做处理
})
},
uploadBook() {
this.$refs.addBookRef.addBookDialogVisible = true
// const newBookId = Date.now()
// this.bookList.unshift({
// id: newBookId,
// url: require('@/assets/images/screen/book.jpg'),
// selected: false
// })
// this.$nextTick(() => {
// this.$refs.bookSwiper.swiper.update()
// this.$refs.bookSwiper.swiper.slideTo(0, 300)
// })
},
batchDelete() {
const selectedCount = this.bookList.filter(book => book.selected).length
if (selectedCount === 0) return
this.$confirm(`确定要删除选中的 ${selectedCount} 本图书吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.bookList = this.bookList.filter(book => !book.selected)
this.$nextTick(() => {
this.$refs.bookSwiper.swiper.update()
})
this.$message.success(`已成功删除 ${selectedCount} 本图书`)
})
}
}
}
</script>
<style lang="scss" scoped>
@import "~@/assets/styles/digitalScreen.scss";
</style>