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.
220 lines
8.3 KiB
220 lines
8.3 KiB
<template>
|
|
<div>
|
|
<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"
|
|
:class="{ 'book-list-item--selected': book.selected }"
|
|
style="background-color: transparent;"
|
|
>
|
|
|
|
<div style="cursor: default;" @click.stop="toggleBookSelect(index)">
|
|
<img :src="book.imgPath ? (baseApi + '/api/fileRelevant/getImg?imgType=2&imgId=' + book.imgPath) : require('@/assets/images/screen/book.png')" alt="图书封面">
|
|
<div v-if="book.selected" class="select-style">
|
|
<div class="select-mask" />
|
|
<i class="iconfont icon-wancheng" style="font-size: 20px; right: 6px; top: 6px;" />
|
|
</div>
|
|
</div>
|
|
<!-- <span style="position: absolute; top: 0; left: 0; color: #fff;">{{ book.id }}</span> -->
|
|
<!-- <div style="position: relative; position: absolute; left: 0; bottom: 0; width: calc(100% - 15px); display: flex; justify-content: space-between; padding: 0 5px 0 10px; background: rgba(0,0,0,.5); cursor: pointer;">
|
|
<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(book)">
|
|
<i class="iconfont icon-shanchu" />
|
|
</div>
|
|
</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;">
|
|
<el-button size="mini" type="primary" @click.stop="uploadBook"><i class="iconfont icon-shangchuan" />图书上传</el-button>
|
|
<el-button :loading="deleteLoading" 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" @refresh="updateBookItem" />
|
|
</div>
|
|
<div class="config-remarks" style="margin-top: 20px;">推荐图书数量大于等于20本,显示效果最佳!当前已上传数量<span style="color: #0c0e1e; font-weight: bold;"> {{ bookList.length }}</span> 本<span v-if="bookList.length<20" style="color: #ed4a41; padding-left: 10px;">未达到展示的最佳效果</span></div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { FetchInitScreenBookRecommend, FetchDeleteScreenBookRecommend } from '@/api/digitalScreen/index'
|
|
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 {
|
|
deleteLoading: false,
|
|
bookList: [],
|
|
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',
|
|
'user'
|
|
]),
|
|
hasSelectedItems() {
|
|
return this.bookList.some(book => book.selected)
|
|
}
|
|
},
|
|
created() {
|
|
},
|
|
mounted() {
|
|
this.$emit('ready')
|
|
},
|
|
methods: {
|
|
initScreenBookRecommend() {
|
|
const param = {
|
|
'libcode': this.user.fonds.fondsNo
|
|
}
|
|
FetchInitScreenBookRecommend(param).then((res) => {
|
|
console.log('BookRecommend', res)
|
|
const newRes = res.map(item => ({
|
|
...item,
|
|
selected: false
|
|
}))
|
|
this.bookList = newRes
|
|
}).catch(err => {
|
|
console.log(err)
|
|
})
|
|
},
|
|
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
|
|
},
|
|
uploadBook() {
|
|
this.$refs.addBookRef.addBookDialogVisible = true
|
|
},
|
|
updateBookItem() {
|
|
this.initScreenBookRecommend()
|
|
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.deleteLoading = true
|
|
this.$confirm(`确定要删除选中的 ${selectedCount} 本图书吗?`, '提示', {
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
type: 'warning'
|
|
}).then(() => {
|
|
const ids = []
|
|
const selectedBooks = this.bookList.filter(book => book.selected)
|
|
selectedBooks.forEach(book => {
|
|
ids.push(book.id)
|
|
})
|
|
FetchDeleteScreenBookRecommend(ids).then((res) => {
|
|
console.log('res', res)
|
|
if (res.code !== 500) {
|
|
this.$message({ message: `已成功删除 ${selectedCount} 本图书`, type: 'success', offset: 8 })
|
|
this.$nextTick(() => {
|
|
this.$refs.bookSwiper.swiper.update()
|
|
})
|
|
this.initScreenBookRecommend()
|
|
} else {
|
|
this.$message({ message: '删除失败', type: 'error', offset: 8 })
|
|
}
|
|
this.deleteLoading = false
|
|
}).catch(err => {
|
|
console.log(err)
|
|
this.deleteLoading = false
|
|
})
|
|
// this.bookList = this.bookList.filter(book => !book.selected)
|
|
// this.$message.success(`已成功删除 ${selectedCount} 本图书`)
|
|
}).catch(() => {
|
|
this.deleteLoading = false
|
|
})
|
|
},
|
|
deleteBook(data) {
|
|
this.$confirm('确定要删除这本图书吗?', '提示', {
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
type: 'warning',
|
|
dangerouslyUseHTMLString: true
|
|
}).then(() => {
|
|
const ids = []
|
|
ids.push(data.id)
|
|
FetchDeleteScreenBookRecommend(ids).then((res) => {
|
|
console.log('res', res)
|
|
if (res.code !== 500) {
|
|
this.$message({ message: '删除成功', type: 'success', offset: 8 })
|
|
this.$nextTick(() => {
|
|
this.$refs.bookSwiper.swiper.update()
|
|
})
|
|
this.initScreenBookRecommend()
|
|
} else {
|
|
this.$message({ message: '删除失败', type: 'error', offset: 8 })
|
|
}
|
|
}).catch(err => {
|
|
console.log(err)
|
|
})
|
|
}).catch(() => {
|
|
// 取消删除不做处理
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
@import "~@/assets/styles/digitalScreen.scss";
|
|
</style>
|