11 changed files with 1374 additions and 223 deletions
-
20src/api/digitalScreen/index.js
-
BINsrc/assets/images/screen/book.jpg
-
BINsrc/assets/images/screen/book.png
-
82src/assets/styles/digitalScreen.scss
-
455src/views/digitalScreen/index.vue
-
313src/views/digitalScreen/module/advSetting.vue
-
45src/views/digitalScreen/module/areaSetting.vue
-
176src/views/digitalScreen/module/bookRecommend.vue
-
342src/views/digitalScreen/module/mediaSetting.vue
-
160src/views/digitalScreen/module/previewSetting.vue
-
4src/views/system/group/index.vue
@ -0,0 +1,20 @@ |
|||||
|
import request from '@/utils/request' |
||||
|
import qs from 'qs' |
||||
|
|
||||
|
export function FetchInitScreenSetting(params) { |
||||
|
return request({ |
||||
|
url: 'api/screenSetting/initScreenSetting' + '?' + qs.stringify(params, { indices: false }), |
||||
|
method: 'get' |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 编辑智慧大屏后台参数
|
||||
|
export function FetchEditScreenSetting(parameter) { |
||||
|
return request({ |
||||
|
url: 'api/screenSetting/editScreenSetting', |
||||
|
method: 'post', |
||||
|
data: parameter |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export default { FetchInitScreenSetting, FetchEditScreenSetting } |
After Width: 180 | Height: 180 | Size: 21 KiB |
After Width: 1080 | Height: 1920 | Size: 412 KiB |
@ -0,0 +1,313 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<div class="config-item"> |
||||
|
<div class="config-item-main"> |
||||
|
<span class="data-title">播放设置</span> |
||||
|
<el-form ref="advForm" class="advForm" :model="advForm" size="small" label-width="100px"> |
||||
|
<el-form-item label="图片切换时长" prop="time"> |
||||
|
<div v-if="!editStatus.advForm.time" style="display: flex; justify-content: flex-start; width: 340px; height: 32px; align-items: flex-start;"> |
||||
|
<span class="edit-readonly" @dblclick="handleDblClick('advForm', 'time')"> {{ advForm.time || '' }} </span> |
||||
|
<span class="edit-slot">秒</span> |
||||
|
</div> |
||||
|
<el-input v-else ref="advFormtime" v-model="advForm.time" @blur="handleBlur('advForm', 'time')" @keyup.enter="handleBlur('advForm', 'time')"><template slot="append">秒</template></el-input> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
</div> |
||||
|
<div class="config-remarks">双击输入框可进行编辑,如有多张图片循环播放,则默认单张图片播放时长为5秒。</div> |
||||
|
</div> |
||||
|
<div class="config-item"> |
||||
|
<div class="config-item-main"> |
||||
|
<span class="data-title">宣传图片</span> |
||||
|
<div class="upload-item"> |
||||
|
<p>图片列表</p> |
||||
|
<div class="book-swiper-wrapper"> |
||||
|
<swiper |
||||
|
ref="adImgSwiper" |
||||
|
:options="swiperOptions" |
||||
|
class="book-swiper" |
||||
|
> |
||||
|
<swiper-slide |
||||
|
v-for="(book, index) in advImgList" |
||||
|
:key="book.id" |
||||
|
class="book-list-item" |
||||
|
> |
||||
|
<img :src="book.url || require('@/assets/images/cover-bg.png')" 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> |
||||
|
<div style="margin-left: 20px;"> |
||||
|
<div class="upload-btn"> |
||||
|
<input id="upFile" type="file" name="upFile" @change="changeFile($event)"> |
||||
|
<el-button size="mini" type="primary"><i class="iconfont icon-shangchuan" />图片上传</el-button> |
||||
|
</div> |
||||
|
<el-button size="mini" :disabled="!hasSelectedItems" style="margin-top: 10px;" @click="batchDelete"> |
||||
|
<i class="iconfont icon-shanchu" /> |
||||
|
批量删除 |
||||
|
</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { swiper, swiperSlide } from 'vue-awesome-swiper' |
||||
|
import 'swiper/dist/css/swiper.css' |
||||
|
import { mapGetters } from 'vuex' |
||||
|
import { getCurrentTime } from '@/utils/index' |
||||
|
// import { upload } from '@/utils/upload' |
||||
|
|
||||
|
export default { |
||||
|
name: 'AdvSetting', |
||||
|
components: { |
||||
|
swiper, |
||||
|
swiperSlide |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
advForm: { |
||||
|
time: null |
||||
|
}, |
||||
|
editStatus: { |
||||
|
advForm: { |
||||
|
time: false |
||||
|
} |
||||
|
}, |
||||
|
originalValues: { |
||||
|
advForm: {} |
||||
|
}, |
||||
|
advImgList: [ |
||||
|
{ id: 1, url: require('@/assets/images/screen/screen4.png'), selected: false }, |
||||
|
{ id: 2, url: require('@/assets/images/screen/screen4.png'), selected: true }, |
||||
|
{ id: 3, url: require('@/assets/images/screen/screen4.png'), selected: false }, |
||||
|
{ id: 4, url: require('@/assets/images/screen/screen4.png'), selected: false }, |
||||
|
{ id: 5, url: require('@/assets/images/screen/screen4.png'), selected: false } |
||||
|
], |
||||
|
swiperOptions: { |
||||
|
slidesPerView: 'auto', // 自动适应数量 |
||||
|
freeMode: true, // 自由滑动模式 |
||||
|
grabCursor: true, // 抓手光标 |
||||
|
on: { |
||||
|
resize: function() { |
||||
|
this.update() |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
file: null, // 附件 change |
||||
|
fileNames: '', // 附件 - name |
||||
|
formatType: '', // 附件 - type |
||||
|
postfix: '', // 附件 - 文件后缀 |
||||
|
fileSize: '', // 附件 - 大小 |
||||
|
filePath: '', // 附件 - path |
||||
|
px: '', // 附件 - 分辨率 |
||||
|
nowDate: '', // 当前时间 |
||||
|
fileJsonString: null, |
||||
|
imageUrl: null |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
...mapGetters([ |
||||
|
'baseApi' |
||||
|
]), |
||||
|
hasSelectedItems() { |
||||
|
return this.advImgList.some(book => book.selected) |
||||
|
} |
||||
|
}, |
||||
|
created() { |
||||
|
}, |
||||
|
mounted() { |
||||
|
}, |
||||
|
methods: { |
||||
|
updateSwiper() { |
||||
|
if (this.$refs.adImgSwiper && this.$refs.adImgSwiper.swiper) { |
||||
|
const swiper = this.$refs.adImgSwiper.swiper |
||||
|
swiper.update() |
||||
|
swiper.slideReset() |
||||
|
} |
||||
|
}, |
||||
|
handleDblClick(formName, field) { |
||||
|
this.originalValues[formName][field] = this[formName][field] |
||||
|
this.editStatus[formName][field] = true |
||||
|
this.$nextTick(() => { |
||||
|
const input = this.$refs[`${formName}${field}`] |
||||
|
if (input) input.focus() |
||||
|
}) |
||||
|
}, |
||||
|
handleBlur(formName, field) { |
||||
|
this.editStatus[formName][field] = false |
||||
|
if (this[formName][field] !== this.originalValues[formName][field]) { |
||||
|
this.saveEdit(formName, field) |
||||
|
} |
||||
|
}, |
||||
|
saveEdit(formName, field) { |
||||
|
const value = this[formName][field] |
||||
|
console.log(`保存${formName}.${field}:`, value) |
||||
|
if (!value) { |
||||
|
this.$message.warning(`${this.getFieldLabel(formName, field)}不能为空`) |
||||
|
this[formName][field] = this.originalValues[formName][field] |
||||
|
return |
||||
|
} |
||||
|
this.$message.success(`${this.getFieldLabel(formName, field)}更新成功`) |
||||
|
}, |
||||
|
toggleBookSelect(index) { |
||||
|
this.advImgList[index].selected = !this.advImgList[index].selected |
||||
|
}, |
||||
|
deleteBook(index) { |
||||
|
this.$confirm('确定要删除这本图书吗?', '提示', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning', |
||||
|
dangerouslyUseHTMLString: true |
||||
|
}).then(() => { |
||||
|
this.advImgList.splice(index, 1) |
||||
|
this.$nextTick(() => { |
||||
|
this.updateSwiper() |
||||
|
}) |
||||
|
this.$message.success('删除成功!') |
||||
|
}).catch(() => { |
||||
|
// 取消删除不做处理 |
||||
|
}) |
||||
|
}, |
||||
|
batchDelete() { |
||||
|
const selectedCount = this.advImgList.filter(book => book.selected).length |
||||
|
if (selectedCount === 0) return |
||||
|
|
||||
|
this.$confirm(`确定要删除选中的 ${selectedCount} 本图书吗?`, '提示', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
this.advImgList = this.advImgList.filter(book => !book.selected) |
||||
|
this.$nextTick(() => { |
||||
|
this.updateSwiper() |
||||
|
}) |
||||
|
this.$message.success(`已成功删除 ${selectedCount} 本图书`) |
||||
|
}) |
||||
|
}, |
||||
|
// 选择附件 |
||||
|
async changeFile(e) { |
||||
|
const file = e.target.files[0] |
||||
|
|
||||
|
if (file && file.type.startsWith('image/')) { |
||||
|
this.file = e.target.files[0] |
||||
|
this.fileSize = this.file.size |
||||
|
// this.formatType = this.file.type.substring(0, this.file.type.indexOf('/')) |
||||
|
this.fileNames = this.file.name |
||||
|
|
||||
|
const fileBase64 = await this.getBase64(this.file) |
||||
|
const res = await this.getImgPx(fileBase64) |
||||
|
this.imageUrl = fileBase64 |
||||
|
this.px = res.width + 'px*' + res.height + 'px' |
||||
|
// if (this.uploadType === 'book') { |
||||
|
// // 上传附件 |
||||
|
// upload(this.baseApi + '/api/fileRelevant/uploadBookImg', this.file).then(res => { |
||||
|
// console.log(res) |
||||
|
// if (res.data.code === 200) { |
||||
|
// this.filePath = res.data.data |
||||
|
// this.$emit('childCover', res.data.data) |
||||
|
// // this.uploadSave() |
||||
|
// } |
||||
|
// }) |
||||
|
// } else { |
||||
|
// // 上传附件 |
||||
|
// upload(this.baseApi + '/api/fileRelevant/uploadOtherImg', this.file).then(res => { |
||||
|
// console.log(res) |
||||
|
// if (res.data.code === 200) { |
||||
|
// this.filePath = res.data.data |
||||
|
// this.$emit('childCover', res.data.data) |
||||
|
// // this.uploadSave() |
||||
|
// } |
||||
|
// }) |
||||
|
// } |
||||
|
} else { |
||||
|
this.$message({ message: '只可上传图片', type: 'error', offset: 8 }) |
||||
|
this.imageUrl = null |
||||
|
} |
||||
|
}, |
||||
|
// 上传附件 - 选择上传即保存 |
||||
|
uploadSave() { |
||||
|
this.nowDate = getCurrentTime() |
||||
|
const json = { |
||||
|
'file_name': this.fileNames, |
||||
|
'file_size': this.fileSize, |
||||
|
'file_type': this.postfix, |
||||
|
'file_path': this.filePath, |
||||
|
'sequence': null, |
||||
|
'file_dpi': this.px, |
||||
|
'file_thumbnail': '', |
||||
|
'create_time': this.nowDate, |
||||
|
'id': null, |
||||
|
'is_quote': null, |
||||
|
'last_modified': this.file.lastModified |
||||
|
} |
||||
|
const arrayUpload = [] |
||||
|
arrayUpload.push(json) |
||||
|
// this.$emit('childCover', this.fileNames) |
||||
|
|
||||
|
this.fileJsonString = JSON.stringify(arrayUpload) |
||||
|
console.log(this.fileJsonString) |
||||
|
}, |
||||
|
// 将上传的图片转为base64 |
||||
|
getBase64(file) { |
||||
|
const reader = new FileReader() |
||||
|
reader.readAsDataURL(file) |
||||
|
return new Promise((resolve) => { |
||||
|
reader.onload = () => { |
||||
|
resolve(reader.result) |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
// 获取图片的分辨率 |
||||
|
getImgPx(img) { |
||||
|
const image = new Image() |
||||
|
image.src = img |
||||
|
return new Promise((resolve) => { |
||||
|
image.onload = () => { |
||||
|
const width = image.width |
||||
|
const height = image.height |
||||
|
resolve({ width, height }) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
@import "~@/assets/styles/digitalScreen.scss"; |
||||
|
.edit-readonly{ |
||||
|
width: 289px !important; |
||||
|
border-right: none !important; |
||||
|
margin-right: 0 !important; |
||||
|
border-radius: 4px 0 0 4px !important; |
||||
|
} |
||||
|
.edit-slot { |
||||
|
background-color: #f5f7fa; |
||||
|
color: #909399; |
||||
|
display: block; |
||||
|
position: relative; |
||||
|
border: 1px solid #dcdfe6; |
||||
|
border-radius: 0 4px 4px 0; |
||||
|
padding: 0 20px; |
||||
|
white-space: nowrap; |
||||
|
height: 32px; |
||||
|
} |
||||
|
.book-swiper-wrapper { |
||||
|
max-width: 1000px !important; |
||||
|
} |
||||
|
|
||||
|
.book-list-item{ |
||||
|
width: 480px !important; |
||||
|
height: 270px !important; |
||||
|
margin: 0 10px !important; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,176 @@ |
|||||
|
<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> |
@ -0,0 +1,342 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<div class="config-item"> |
||||
|
<div class="config-item-main"> |
||||
|
<span class="data-title">重要通知</span> |
||||
|
<div class="upload-item" style="align-items: flex-start;"> |
||||
|
<p>通知列表</p> |
||||
|
<el-card class="box-card" style="padding: 20px;"> |
||||
|
<el-table |
||||
|
:data="tableData" |
||||
|
style="width: 100%" |
||||
|
max-height="360" |
||||
|
> |
||||
|
<el-table-column type="selection" align="center" width="55" /> |
||||
|
<el-table-column prop="name" label="标题" width="200" /> |
||||
|
<el-table-column prop="startTime" label="开始时间" width="200" /> |
||||
|
<el-table-column prop="endTime" label="结束时间" width="200" /> |
||||
|
<el-table-column fixed="right" label="操作" width="100"> |
||||
|
<template> |
||||
|
<!-- slot-scope="scope" --> |
||||
|
<el-button style="padding: 5px 6px !important;"><i class="iconfont icon-bianji" />编辑</el-button> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
<el-pagination |
||||
|
style="margin: 34px 0 10px 0 !important;" |
||||
|
:current-page="page.page" |
||||
|
:total="page.total" |
||||
|
:page-size="page.size" |
||||
|
:pager-count="5" |
||||
|
layout="total, prev, pager, next, sizes" |
||||
|
@size-change="handleSizeChange" |
||||
|
@current-change="handleCurrentPage" |
||||
|
/> |
||||
|
</el-card> |
||||
|
<!-- @click="toDelete(crud.selections)" --> |
||||
|
<div style="display: flex; flex-direction: column; justify-content: flex-start; margin-left: 15px;"> |
||||
|
<el-button size="mini" @click="noticeDialogVisible=true"> |
||||
|
<i class="iconfont icon-xinzeng" /> |
||||
|
新增 |
||||
|
</el-button> |
||||
|
<el-button size="mini" style="margin-left: 0; margin-top: 14px;"> |
||||
|
<i class="iconfont icon-shanchu" /> |
||||
|
删除 |
||||
|
</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="config-item"> |
||||
|
<div class="config-item-main"> |
||||
|
<span class="data-title">宣传视频</span> |
||||
|
<div class="upload-item" style="align-items: flex-start;"> |
||||
|
<p>视频列表</p> |
||||
|
<el-card class="box-card" style="padding: 20px;"> |
||||
|
<el-table |
||||
|
:data="videoTableData" |
||||
|
style="width: 100%" |
||||
|
max-height="360" |
||||
|
> |
||||
|
<el-table-column type="selection" align="center" width="55" /> |
||||
|
<el-table-column prop="name" label="标题" width="200" /> |
||||
|
<el-table-column prop="startTime" label="开始时间" width="200" /> |
||||
|
<el-table-column prop="endTime" label="结束时间" width="200" /> |
||||
|
<el-table-column fixed="right" label="操作" width="100"> |
||||
|
<template> |
||||
|
<!-- slot-scope="scope" --> |
||||
|
<el-button style="padding: 5px 6px !important;"><i class="iconfont icon-bianji" />编辑</el-button> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
<el-pagination |
||||
|
style="margin: 34px 0 10px 0 !important;" |
||||
|
:current-page="videoPage.page" |
||||
|
:total="videoPage.total" |
||||
|
:page-size="videoPage.size" |
||||
|
:pager-count="5" |
||||
|
layout="total, prev, pager, next, sizes" |
||||
|
@size-change="handleVideoSizeChange" |
||||
|
@current-change="handleVideoCurrentPage" |
||||
|
/> |
||||
|
</el-card> |
||||
|
<!-- @click="toDelete(crud.selections)" --> |
||||
|
<div style="display: flex; flex-direction: column; justify-content: flex-start; margin-left: 15px;"> |
||||
|
<el-button size="mini" @click="videoDialogVisible=true"> |
||||
|
<i class="iconfont icon-xinzeng" /> |
||||
|
新增 |
||||
|
</el-button> |
||||
|
<el-button size="mini" style="margin-left: 0; margin-top: 14px;"> |
||||
|
<i class="iconfont icon-shanchu" /> |
||||
|
删除 |
||||
|
</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<el-dialog class="auto-dialog" :close-on-click-modal="false" :modal-append-to-body="false" append-to-body :before-close="handleClose" :visible.sync="noticeDialogVisible" title="新增通知"> |
||||
|
<div class="setting-dialog"> |
||||
|
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="90px"> |
||||
|
<div> |
||||
|
<el-form-item label="标题" prop="title"> |
||||
|
<el-input v-model="form.title" placeholder="请输入" style="width: 586px;" /> |
||||
|
</el-form-item> |
||||
|
</div> |
||||
|
<el-form-item label="开始时间" prop="startTime"> |
||||
|
<el-date-picker |
||||
|
v-model="form.startTime" |
||||
|
type="datetime" |
||||
|
placeholder="选择日期时间" |
||||
|
default-time="12:00:00" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="结束时间" prop="endTime"> |
||||
|
<el-date-picker |
||||
|
v-model="form.endTime" |
||||
|
type="datetime" |
||||
|
placeholder="选择日期时间" |
||||
|
default-time="12:00:00" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<div> |
||||
|
<el-form-item label="通知内容" prop="remarks"> |
||||
|
<el-input v-model="form.remarks" type="textarea" rows="5" placeholder="请输入" style="width: 586px;" /> |
||||
|
</el-form-item> |
||||
|
</div> |
||||
|
</el-form> |
||||
|
<div slot="footer" class="dialog-footer"> |
||||
|
<el-button type="text" @click="handleClose">取消</el-button> |
||||
|
<el-button :loading="btnLoading" type="primary" @click="handleComfired('form')">确定</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
|
||||
|
<el-dialog class="auto-dialog" :close-on-click-modal="false" :modal-append-to-body="false" append-to-body :before-close="handleClose" :visible.sync="videoDialogVisible" title="新增宣传视频"> |
||||
|
<div class="setting-dialog"> |
||||
|
<el-form ref="videoForm" :inline="true" :model="videoForm" :rules="rules" size="small" label-width="90px"> |
||||
|
<div> |
||||
|
<el-form-item label="标题" prop="title"> |
||||
|
<el-input v-model="videoForm.title" placeholder="请输入" style="width: 586px;" /> |
||||
|
</el-form-item> |
||||
|
</div> |
||||
|
<el-form-item label="开始时间" prop="startTime"> |
||||
|
<el-date-picker |
||||
|
v-model="videoForm.startTime" |
||||
|
type="datetime" |
||||
|
placeholder="选择日期时间" |
||||
|
default-time="12:00:00" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="结束时间" prop="endTime"> |
||||
|
<el-date-picker |
||||
|
v-model="videoForm.endTime" |
||||
|
type="datetime" |
||||
|
placeholder="选择日期时间" |
||||
|
default-time="12:00:00" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<div> |
||||
|
<el-form-item class="book-cover-upload" label="宣传视频" prop="fileNames"> |
||||
|
<el-input v-model="videoForm.fileNames" placeholder="请上传" :readonly="true" /> |
||||
|
<div class="upload-btn"> |
||||
|
<!-- @change="changeFile($event)" --> |
||||
|
<input id="upFile" type="file" name="upFile"> |
||||
|
<el-button size="small" type="primary"><i class="iconfont icon-shangchuan" />上传</el-button> |
||||
|
</div> |
||||
|
</el-form-item> |
||||
|
</div> |
||||
|
</el-form> |
||||
|
<div slot="footer" class="dialog-footer"> |
||||
|
<el-button type="text" @click="handleClose">取消</el-button> |
||||
|
<el-button :loading="btnLoading" type="primary" @click="handleComfired('videoForm')">确定</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
|
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { mapGetters } from 'vuex' |
||||
|
|
||||
|
export default { |
||||
|
name: 'MediaSetting', |
||||
|
components: { }, |
||||
|
data() { |
||||
|
return { |
||||
|
tableData: [ |
||||
|
{ name: 'XXXX通知', startTime: '2025-05-01 10:05:00', endTime: '2025-05-01 10:05:00' }, |
||||
|
{ name: 'XXXX通知', startTime: '2025-05-01 10:05:00', endTime: '2025-05-01 10:05:00' } |
||||
|
], |
||||
|
page: { |
||||
|
page: 1, |
||||
|
size: 10, |
||||
|
total: 0 |
||||
|
}, |
||||
|
noticeDialogVisible: false, |
||||
|
form: { |
||||
|
title: '', |
||||
|
startTime: '', |
||||
|
endTime: '', |
||||
|
remarks: '' |
||||
|
}, |
||||
|
videoTableData: [ |
||||
|
{ name: 'XXXX宣传视频', startTime: '2025-05-01 10:05:00', endTime: '2025-05-01 10:05:00' }, |
||||
|
{ name: 'XXXX宣传视频', startTime: '2025-05-01 10:05:00', endTime: '2025-05-01 10:05:00' } |
||||
|
], |
||||
|
videoDialogVisible: false, |
||||
|
videoForm: { |
||||
|
title: '', |
||||
|
startTime: '', |
||||
|
endTime: '', |
||||
|
videoUrl: '' |
||||
|
}, |
||||
|
videoPage: { |
||||
|
page: 1, |
||||
|
size: 10, |
||||
|
total: 0 |
||||
|
}, |
||||
|
rules: { |
||||
|
title: [ |
||||
|
{ required: true, message: '标题不可为空', trigger: 'blur' } |
||||
|
], |
||||
|
startTime: [ |
||||
|
{ required: true, message: '请选择开始时间', trigger: 'change' } |
||||
|
], |
||||
|
endTime: [ |
||||
|
{ required: true, message: '请选择结束时间', trigger: 'change' } |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
...mapGetters([ |
||||
|
'baseApi' |
||||
|
]) |
||||
|
}, |
||||
|
created() { |
||||
|
}, |
||||
|
methods: { |
||||
|
handleClose() { |
||||
|
this.noticeDialogVisible = false |
||||
|
this.videoDialogVisible = false |
||||
|
}, |
||||
|
handleSizeChange(size) { |
||||
|
this.page.size = size |
||||
|
this.page.page = 1 |
||||
|
}, |
||||
|
handleCurrentPage(val) { |
||||
|
this.page.page = val |
||||
|
}, |
||||
|
handleVideoSizeChange(size) { |
||||
|
this.videoPage.size = size |
||||
|
this.videoPage.page = 1 |
||||
|
}, |
||||
|
handleVideoCurrentPage(val) { |
||||
|
this.videoPage.page = val |
||||
|
}, |
||||
|
handleComfired(form) { |
||||
|
this.$refs[form].validate((valid) => { |
||||
|
if (valid) { |
||||
|
this.addBookDialogVisible = false |
||||
|
// const ids = [] |
||||
|
// this.selectBookData.forEach(val => { |
||||
|
// ids.push(val.id) |
||||
|
// }) |
||||
|
// const params = { |
||||
|
// 'gridId': this.selectGridVal.id, |
||||
|
// 'ids': ids |
||||
|
// } |
||||
|
// console.log('params', params) |
||||
|
// FetchManualShelving(params).then(() => { |
||||
|
// this.$message({ message: '批量上架成功', type: 'success', offset: 8 }) |
||||
|
// this.handleCloseDialog() |
||||
|
// }).catch(err => { |
||||
|
// console.log(err) |
||||
|
// this.addBookDialogVisible = false |
||||
|
// }) |
||||
|
} else { |
||||
|
console.log('error submit!!') |
||||
|
return false |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
@import "~@/assets/styles/digitalScreen.scss"; |
||||
|
::v-deep .book-cover-upload { |
||||
|
display: flex; |
||||
|
justify-content: flex-start; |
||||
|
.el-form-item__content{ |
||||
|
position: relative; |
||||
|
width: 580px !important; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
margin-left: 0 !important; |
||||
|
.input-style{ |
||||
|
width: 490px; |
||||
|
height: 34px; |
||||
|
line-height: 34px; |
||||
|
padding: 0 20px; |
||||
|
border: 1px solid #e6e8ed; |
||||
|
border-radius: 3px; |
||||
|
&.error-box{ |
||||
|
border-color: #ed4a41; |
||||
|
} |
||||
|
} |
||||
|
.error-tip{ |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
bottom: -26px; |
||||
|
font-size: 12px; |
||||
|
color: #ff4949; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.upload-btn{ |
||||
|
position: relative; |
||||
|
width: 62px; |
||||
|
margin-right: 0 !important; |
||||
|
margin-left: 10px; |
||||
|
overflow: initial !important; |
||||
|
#upFile{ |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
top: 0; |
||||
|
width: 84px; |
||||
|
height: 34px; |
||||
|
} |
||||
|
.el-button{ |
||||
|
margin-top: -2px; |
||||
|
font-weight: bold; |
||||
|
border-color: #0348f3; |
||||
|
color: #0348f3; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,160 @@ |
|||||
|
<template> |
||||
|
<div style="position: absolute; right: 0; top: 2px;"> |
||||
|
<el-button size="mini"> |
||||
|
<i class="iconfont icon-sulan" /> |
||||
|
大屏预览 |
||||
|
</el-button> |
||||
|
<el-button :loading="resetLoading" size="mini" style="padding: 7px 6px 7px 10px;" @click="toVerify('reset')"> |
||||
|
<i class="iconfont icon-zishebeiguanli" /> |
||||
|
</el-button> |
||||
|
|
||||
|
<el-dialog class="tip-dialog tip-middle-dialog" title="操作提示" :close-on-click-modal="false" :modal-append-to-body="false" append-to-body :visible.sync="verifyDialogVisible" :before-close="handleClose"> |
||||
|
<div class="setting-dialog"> |
||||
|
<div class="tip-content"> |
||||
|
<p class="tipMsg">大屏预览网址设置成功后,即可点击按钮预览大屏(建议全屏观看)!</p> |
||||
|
<p class="delt-tip"><span>注意:此操作需超级管理员输入维护验证码后完成设置,暂不对普通用户开放!</span></p> |
||||
|
</div> |
||||
|
<el-form ref="verfiyForm" :model="verfiyForm" style="margin-top:30px;" @submit.native.prevent> |
||||
|
<el-form-item label="维护验证码" label-width="110px"> |
||||
|
<el-input v-model="verfiyForm.verifyCode" show-password style="width: 480px;" /> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
<div slot="footer" class="dialog-footer"> |
||||
|
<el-button @click="handleClose">取消 </el-button> |
||||
|
<el-button type="primary" @click.native="handleConfirm">确定</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
|
||||
|
<el-dialog class="tip-dialog tip-middle-dialog" title="大屏预览网址" :close-on-click-modal="false" :modal-append-to-body="false" append-to-body :visible.sync="previewDialog" :before-close="handleClose"> |
||||
|
<div class="setting-dialog"> |
||||
|
<el-form ref="form" :model="form" :rules="rules"> |
||||
|
<el-form-item label="网址" label-width="110px" prop="link"> |
||||
|
<el-input v-model="form.link" style="width: 480px;" /> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
<div slot="footer" class="dialog-footer"> |
||||
|
<el-button @click="handleClose">取消 </el-button> |
||||
|
<el-button type="primary" @click.native="handleUrlConfirm">确定</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { mapGetters } from 'vuex' |
||||
|
import { encrypt } from '@/utils/rsaEncrypt' |
||||
|
import { verifyMaintenance } from '@/api/system/param' |
||||
|
|
||||
|
export default { |
||||
|
name: 'PreviewSetting', |
||||
|
components: { |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
verifyDialogVisible: false, |
||||
|
verfiyForm: { |
||||
|
verifyCode: '' |
||||
|
}, |
||||
|
verifyStatus: '', |
||||
|
showVerifyDialog: true, |
||||
|
resetLoading: false, |
||||
|
previewDialog: false, |
||||
|
form: { |
||||
|
link: '' |
||||
|
}, |
||||
|
rules: { |
||||
|
link: [ |
||||
|
{ required: true, message: '网址不可为空', trigger: 'blur' } |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
...mapGetters([ |
||||
|
'baseApi' |
||||
|
]) |
||||
|
}, |
||||
|
created() { |
||||
|
}, |
||||
|
mounted() { |
||||
|
}, |
||||
|
methods: { |
||||
|
toVerify(btn) { |
||||
|
this.verifyStatus = btn |
||||
|
this.verifyDialogVisible = true |
||||
|
// if (btn === 'reset') { |
||||
|
// this.verifyDialogVisible = true |
||||
|
// } else { |
||||
|
// if (this.form.ip) { |
||||
|
// if (this.showVerifyDialog) { |
||||
|
// this.verifyDialogVisible = true |
||||
|
// return false |
||||
|
// } |
||||
|
// } else { |
||||
|
// this.$refs.form.validateField(['ip'], err => { |
||||
|
// console.log('err', err) |
||||
|
// if (err) { |
||||
|
// return |
||||
|
// } |
||||
|
// }) |
||||
|
// } |
||||
|
// } |
||||
|
}, |
||||
|
handleConfirm() { |
||||
|
verifyMaintenance(encrypt(this.verfiyForm.verifyCode)).then((res) => { |
||||
|
if (res) { |
||||
|
this.verifyDialogVisible = false |
||||
|
this.verfiyForm.verifyCode = '' |
||||
|
this.showVerifyDialog = false |
||||
|
this.previewDialog = true |
||||
|
// if (this.verifyStatus === 'add') { |
||||
|
// crudStockTask.FetchEditSetting(this.crud.form).then(res => { |
||||
|
// this.$message({ message: '修改成功', type: 'success', offset: 8 }) |
||||
|
// this.initData() |
||||
|
// }).catch(() => { |
||||
|
// }) |
||||
|
// } else { |
||||
|
// this.resetLoading = true |
||||
|
// // 重启服务 |
||||
|
// this.handleConnectAIService() |
||||
|
// } |
||||
|
} else { |
||||
|
this.$message({ message: '验证码错误!', type: 'error', offset: 8 }) |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
handleUrlConfirm() { |
||||
|
this.$refs.form.validate((valid) => { |
||||
|
if (valid) { |
||||
|
console.log('submit!') |
||||
|
this.previewDialog = false |
||||
|
this.form.link = '' |
||||
|
} else { |
||||
|
console.log('error submit!!') |
||||
|
return false |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
handleClose() { |
||||
|
if (this.$refs.verfiyForm) { |
||||
|
this.verfiyForm.verifyCode = '' |
||||
|
this.$refs.verfiyForm.resetFields() |
||||
|
this.verifyDialogVisible = false |
||||
|
} |
||||
|
if (this.$refs.form) { |
||||
|
this.previewDialog = false |
||||
|
this.form.link = '' |
||||
|
this.$refs.form.resetFields() |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
@import "~@/assets/styles/digitalScreen.scss"; |
||||
|
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue