Browse Source

大屏

master
xuhuajiao 1 month ago
parent
commit
9a1e6874c6
  1. 20
      src/api/digitalScreen/index.js
  2. BIN
      src/assets/images/screen/book.jpg
  3. BIN
      src/assets/images/screen/book.png
  4. 82
      src/assets/styles/digitalScreen.scss
  5. 455
      src/views/digitalScreen/index.vue
  6. 313
      src/views/digitalScreen/module/advSetting.vue
  7. 45
      src/views/digitalScreen/module/areaSetting.vue
  8. 176
      src/views/digitalScreen/module/bookRecommend.vue
  9. 342
      src/views/digitalScreen/module/mediaSetting.vue
  10. 160
      src/views/digitalScreen/module/previewSetting.vue
  11. 4
      src/views/system/group/index.vue

20
src/api/digitalScreen/index.js

@ -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 }

BIN
src/assets/images/screen/book.jpg

After

Width: 180  |  Height: 180  |  Size: 21 KiB

BIN
src/assets/images/screen/book.png

After

Width: 1080  |  Height: 1920  |  Size: 412 KiB

82
src/assets/styles/digitalScreen.scss

@ -1,10 +1,11 @@
.config-title{
position: relative;
display: flex;
justify-content: flex-start;
align-items: center;
color: #0c0e1e;
height: 32px;
line-height: 32px;
height: 40px;
line-height: 40px;
margin-bottom: 16px;
overflow: hidden;
p{
@ -184,20 +185,20 @@
height: 100px;
display: block;
}
.book-list-upload{
display: flex;
flex-wrap: nowrap;
gap: 10px;
overflow-x: auto; // 超出宽度时显示横向滚动条
scrollbar-width: thin;
max-width: 1000px;
}
// .book-list-upload{
// display: flex;
// flex-wrap: nowrap;
// gap: 10px;
// overflow-x: auto; // 超出宽度时显示横向滚动条
// scrollbar-width: thin;
// max-width: 1000px;
// }
.book-swiper-wrapper {
position: relative;
// width: 100%;
max-width: 970px;
overflow: hidden;
width: 100%;
// padding: 0 20px;
max-width: 1140px;
overflow: visible !important; // 避免意外截断
}
.book-swiper {
width: 100%;
@ -207,10 +208,10 @@
width: 110px;
height: 160px;
flex-shrink: 0; // 禁止压缩保持固定尺寸
overflow: hidden;
border: 1px solid #fff;
border-radius: 4px;
transition: all 0.2s;
margin: 0 5px;
&:hover {
border-color: #0348F3; // hover时高亮边框
box-shadow: 0 2px 8px rgba(3, 72, 243, 0.1);
@ -235,7 +236,7 @@
}
}
.book-select {
left: 3px;
left: 6px;
.icon-wancheng {
display: none;
color: #0348F3;
@ -279,19 +280,50 @@
color: #8c939d;
}
}
.book-recommend{
position: relative;
padding-bottom: 40px;
}
.batch-delete-btn{
position: absolute;
bottom: 0;
left: 100px;
}
// .book-recommend{
// position: relative;
// padding-bottom: 40px;
// }
// .batch-delete-btn{
// position: absolute;
// bottom: 0;
// left: 100px;
// }
}
// 输入框聚焦样式增强
::v-deep .el-input__inner:focus {
border-color: #0348f3;
box-shadow: 0 0 0 2px rgba(3, 72, 243, 0.2);
}
.upload-img-input{
position: relative;
width: 120px;
height: 120px;
& input{
position: absolute;
left: 0;
top: 0;
height: 120px;
opacity: 0;
}
}
.upload-libImg{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 120px;
height: 120px;
font-size: 14px;
font-weight: bold;
color: #1F55EB;
text-align: center;
border: 1px dashed #BCC2C7;
background-color: #EDEFF3;
border-radius: 4px;
& i{
font-size: 30px;
}
}

455
src/views/digitalScreen/index.vue

@ -11,8 +11,8 @@
<i class="iconfont icon-zhuyi-lan" />
<span>注意标题不要超过17个字否则影响美观</span>
</div>
<previewSetting />
</div>
<!-- 屏幕内容设置 -->
<div class="config-screen">
<div
@ -48,7 +48,6 @@
</div>
</div>
</div>
<transition name="tab-slide" mode="out-in">
<div :key="activeTab" class="content-area">
<div v-if="currentScreenItem">
@ -72,52 +71,52 @@
<div v-if="currentScreenItem.id === 1" class="config-item">
<div class="config-item-main">
<span class="data-title">到馆统计</span>
<el-radio-group v-model="arrival_library_setting" aria-hidden="false">
<el-radio :label="1">本地数据</el-radio>
<el-radio :label="2">基数计算</el-radio>
<el-radio :label="3">第三方接口</el-radio>
<el-radio-group v-model="arrival_library_setting" aria-hidden="false" @change="handleArrivalSettingChange">
<el-radio label="1">本地数据</el-radio>
<el-radio label="2">基数计算</el-radio>
<el-radio label="3">第三方接口</el-radio>
</el-radio-group>
</div>
<div v-if="arrival_library_setting === 2" class="library-form">
<div v-if="arrival_library_setting === '2'" class="library-form">
<!-- 原到馆统计表单 -->
<el-form ref="librarySettingForm" :model="librarySettingForm" size="small" label-width="100px">
<el-form ref="librarySettingForm" :model="librarySettingForm" :rules="rules" size="small" label-width="100px">
<el-form-item label="本年到馆" prop="visit_base">
<span v-if="!editStatus.librarySettingForm.visit_base" class="edit-readonly" @dblclick="handleDblClick('librarySettingForm', 'visit_base')">
{{ librarySettingForm.visit_base || '0' }}
{{ librarySettingForm.visit_base }}
</span>
<el-input v-else ref="librarySettingFormvisit_base" v-model="librarySettingForm.visit_base" type="number" @blur="handleBlur('librarySettingForm', 'visit_base')" @keyup.enter="handleBlur('librarySettingForm', 'visit_base')" />
<el-checkbox v-model="librarySettingForm.remarks" label="直接显示" name="form.remarks" />
<el-checkbox v-model="librarySettingForm.visit_base_checked" label="直接显示" name="visit_base_checked" @change="handleCheckboxChange('visit_base', $event)" />
</el-form-item>
<el-form-item label="去年到馆" prop="last_year_visit_base">
<span v-if="!editStatus.librarySettingForm.last_year_visit_base" class="edit-readonly" @dblclick="handleDblClick('librarySettingForm', 'last_year_visit_base')">
{{ librarySettingForm.last_year_visit_base || '0' }}
{{ librarySettingForm.last_year_visit_base }}
</span>
<el-input v-else ref="librarySettingFormlast_year_visit_base" v-model="librarySettingForm.last_year_visit_base" type="number" @blur="handleBlur('librarySettingForm', 'last_year_visit_base')" @keyup.enter="handleBlur('librarySettingForm', 'last_year_visit_base')" />
</el-form-item>
<el-form-item label="今日到馆" prop="today_visit">
<span v-if="!editStatus.librarySettingForm.today_visit" class="edit-readonly" @dblclick="handleDblClick('librarySettingForm', 'today_visit')">
{{ librarySettingForm.today_visit || '0' }} </span>
{{ librarySettingForm.today_visit }} </span>
<el-input v-else ref="librarySettingFormtoday_visit" v-model="librarySettingForm.today_visit" type="number" @blur="handleBlur('librarySettingForm', 'today_visit')" @keyup.enter="handleBlur('librarySettingForm', 'today_visit')" />
<el-checkbox label="直接显示" name="form.remarks" />
<el-checkbox v-model="librarySettingForm.today_visit_checked" label="直接显示" name="today_visit_checked" @change="handleCheckboxChange('today_visit', $event)" />
</el-form-item>
<el-form-item label="昨日到馆" prop="yesterday_visit">
<span v-if="!editStatus.librarySettingForm.yesterday_visit" class="edit-readonly" @dblclick="handleDblClick('librarySettingForm', 'yesterday_visit')"> {{ librarySettingForm.yesterday_visit || '0' }} </span>
<span v-if="!editStatus.librarySettingForm.yesterday_visit" class="edit-readonly" @dblclick="handleDblClick('librarySettingForm', 'yesterday_visit')"> {{ librarySettingForm.yesterday_visit }} </span>
<el-input v-else ref="librarySettingFormyesterday_visit" v-model="librarySettingForm.yesterday_visit" type="number" @blur="handleBlur('librarySettingForm', 'yesterday_visit')" @keyup.enter="handleBlur('librarySettingForm', 'yesterday_visit')" />
<el-checkbox label="直接显示" name="form.remarks" />
<el-checkbox v-model="librarySettingForm.yesterday_visit_checked" label="直接显示" name="yesterday_visit_checked" @change="handleCheckboxChange('yesterday_visit', $event)" />
</el-form-item>
<el-form-item label="本月到馆" prop="this_month_visit">
<span v-if="!editStatus.librarySettingForm.this_month_visit" class="edit-readonly" @dblclick="handleDblClick('librarySettingForm', 'this_month_visit')">
{{ librarySettingForm.this_month_visit || '0' }}
{{ librarySettingForm.this_month_visit }}
</span>
<el-input v-else ref="librarySettingFormthis_month_visit" v-model="librarySettingForm.this_month_visit" type="number" @blur="handleBlur('librarySettingForm', 'this_month_visit')" @keyup.enter="handleBlur('librarySettingForm', 'this_month_visit')" />
<el-checkbox label="直接显示" name="form.remarks" />
<el-checkbox v-model="librarySettingForm.this_month_visit_checked" label="直接显示" name="this_month_visit_checked" @change="handleCheckboxChange('this_month_visit', $event)" />
</el-form-item>
<el-form-item label="上月到馆" prop="last_month_visit">
<span v-if="!editStatus.librarySettingForm.last_month_visit" class="edit-readonly" @dblclick="handleDblClick('librarySettingForm', 'last_month_visit')">
{{ librarySettingForm.last_month_visit || '0' }}
{{ librarySettingForm.last_month_visit }}
</span>
<el-input v-else ref="librarySettingFormlast_month_visit" v-model="librarySettingForm.last_month_visit" type="number" @blur="handleBlur('librarySettingForm', 'last_month_visit')" @keyup.enter="handleBlur('librarySettingForm', 'last_month_visit')" />
<el-checkbox label="直接显示" name="form.remarks" />
<el-checkbox v-model="librarySettingForm.last_month_visit_checked" label="直接显示" name="last_month_visit" @change="handleCheckboxChange('last_month_visit', $event)" />
</el-form-item>
</el-form>
<div class="config-remarks">双击输入框可进行编辑注意<br>
@ -252,60 +251,24 @@
<div v-if="currentScreenItem.id === 1 || currentScreenItem.id === 4" class="config-item">
<div class="config-item-main">
<span class="data-title">二维码</span>
<div class="upload-item">
<div class="upload-item" style="margin-bottom: 20px;">
<p>公众号二维码</p>
<el-upload
class="avatar-uploader"
action="https://jsonplaceholder.typicode.com/posts/"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
>
<img v-if="vxImageUrl" :src="vxImageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon" />
</el-upload>
</div>
</div>
<div class="config-remarks">双击可上传图片二维码用于总览屏媒体屏在任意分屏编辑均可生效</div>
</div>
<div v-if="currentScreenItem.id === 1" class="config-item">
<div class="config-item-main">
<span class="data-title">图书推荐</span>
<div class="upload-item book-recommend">
<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/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 style="display: flex; justify-content: flex-start;">
<img style="display: block; height: 120px; margin-right: 15px;" src="@/assets/images/cover-bg.png" alt="">
<div class="upload-img-input">
<!-- @change="changeAiFile" -->
<input ref="fileInput" type="file" multiple>
<div class="upload-libImg"><i class="iconfont icon-shangchuan2" /><span>点击上传</span></div>
</div>
</div>
<div class="book-upload-btn" @click.stop="uploadBook"><i class="iconfont icon-shangchuan2" /></div>
<el-button class="batch-delete-btn" size="mini" :disabled="!hasSelectedItems" @click="batchDelete">
<i class="iconfont icon-shanchu" />
批量删除
</el-button>
</div>
</div>
<div class="config-remarks">双击可上传图片二维码用于总览屏媒体屏在任意分屏编辑均可生效</div>
</div>
<bookRecommend v-if="currentScreenItem.id === 1" ref="bookRecommendRef" />
<areaSetting v-if="currentScreenItem.id === 2" ref="areaSettingRef" />
<mediaSetting v-if="currentScreenItem.id === 4" ref="mediaSettingRef" />
<advSetting v-if="currentScreenItem.id === 5" ref="advSettingRef" />
</div>
</div>
</div>
@ -314,25 +277,26 @@
</div>
</div>
</transition>
<addBookDialog ref="addBookRef" />
</div>
</template>
<script>
import { FetchInitScreenSetting, FetchEditScreenSetting } from '@/api/digitalScreen/index'
import Sortable from 'sortablejs'
import { swiper, swiperSlide } from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
import addBookDialog from './module/addBookDialog'
import previewSetting from './module/previewSetting'
import bookRecommend from './module/bookRecommend'
import areaSetting from './module/areaSetting'
import mediaSetting from './module/mediaSetting'
import advSetting from './module/advSetting'
export default {
name: 'DigitalScreen',
components: {
swiper,
swiperSlide,
addBookDialog,
areaSetting
previewSetting,
bookRecommend,
areaSetting,
mediaSetting,
advSetting
},
data() {
return {
@ -353,7 +317,7 @@ export default {
clickTimer: null, // /
isDoubleClick: false,
//
arrival_library_setting: 1,
arrival_library_setting: '1',
librarySettingForm: {
visit_base: null,
remarks: null,
@ -390,39 +354,35 @@ export default {
vx_AppSecret: false
},
librarySettingForm: {
visit_base: false,
last_year_visit_base: false,
today_visit: false,
yesterday_visit: false,
this_month_visit: false,
last_month_visit: false
//
visit_base: null,
last_year_visit_base: null,
today_visit: null,
yesterday_visit: null,
this_month_visit: null,
last_month_visit: null,
//
visit_base_checked: false, //
today_visit_checked: false, //
yesterday_visit_checked: false, //
this_month_visit_checked: false, //
last_month_visit_checked: false //
}
},
originalValues: {
openForm: {},
hotForm: {},
vxForm: {},
librarySettingForm: {}
librarySettingForm: {},
specialFields: {}
},
bookList: [
{ id: 1, url: require('@/assets/images/cover-bg.png'), selected: false },
{ id: 2, url: require('@/assets/images/cover-bg.png'), selected: true },
{ id: 3, url: require('@/assets/images/cover-bg.png'), selected: false },
{ id: 4, url: require('@/assets/images/cover-bg.png'), selected: false },
{ id: 5, url: require('@/assets/images/cover-bg.png'), selected: false }
],
// Swiper
swiperOptions: {
slidesPerView: 'auto', //
spaceBetween: 10, //
freeMode: true, //
grabCursor: true, //
watchSlidesProgress: true,
on: {
resize: function() {
this.update() // resize
}
}
rules: {
visit_base: [
{ required: true, message: '本年累计到馆不可为空', trigger: 'blur' }
],
last_year_visit_base: [
{ required: true, message: '去年到馆不可为空', trigger: 'blur' }
]
}
}
},
@ -440,20 +400,137 @@ export default {
},
currentScreenItem() {
return this.screenItems[this.activeTab]
},
hasSelectedItems() {
return this.bookList.some(book => book.selected)
}
},
created() {
this.initTitle()
this.initScreenSetting()
},
mounted() {
this.$nextTick(() => {
this.draggableScreen()
if (this.$refs.bookRecommendRef) {
this.$refs.bookRecommendRef.updateBookSwiper()
}
})
},
methods: {
// checked(val) {
// // 1.
// this.librarySettingForm.visit_base_checked = val
// console.log('', this.librarySettingForm.visit_base_checked)
// // 2. DOM
// this.$nextTick(() => {
// // DOM
// console.log('DOM')
// })
// },
//
initScreenSetting() {
FetchInitScreenSetting().then(res => {
console.log('初始化', res)
//
Object.values(res).forEach(item => {
const { code, context } = item
// code
switch (code) {
//
case 'arrival_library_setting':
this.arrival_library_setting = context
break
case 'visit_base':
this.librarySettingForm.visit_base = context
break
case 'last_year_visit_base':
this.librarySettingForm.last_year_visit_base = context
break
case 'today_visit':
this.librarySettingForm.today_visit = context
break
case 'yesterday_visit':
this.librarySettingForm.yesterday_visit = context
break
case 'this_month_visit':
this.librarySettingForm.this_month_visit = context
break
case 'last_month_visit':
this.librarySettingForm.last_month_visit = context
break
//
case 'open_lib_http':
this.openForm.open_lib_http = context
break
case 'open_lib_appId':
this.openForm.open_lib_appId = context
break
case 'open_lib_secret':
this.openForm.open_lib_secret = context
break
//
case 'hot_search_http':
this.hotForm.hot_search_http = context
break
//
case 'vx_appID':
this.vxForm.vx_appID = context
break
case 'vx_AppSecret':
this.vxForm.vx_AppSecret = context
break
//
case 'wechar_qr_code':
this.vxImageUrl = context //
break
// show1-show55
case 'show1':
if (this.screenItems[0]) this.screenItems[0].time = context
break
case 'show2':
if (this.screenItems[1]) this.screenItems[1].time = context
break
case 'show3':
if (this.screenItems[2]) this.screenItems[2].time = context
break
case 'show4':
if (this.screenItems[3]) this.screenItems[3].time = context
break
case 'show5':
if (this.screenItems[4]) this.screenItems[4].time = context
break
// show_screen"1,2,3,4"ID
case 'show_screen':
if (context) {
const enabledIds = context.split(',').map(Number)
this.screenItems.forEach(item => {
item.enabled = enabledIds.includes(item.id)
})
}
break
}
})
// initScreenSetting
// initScreenSettingthis.$set
Object.values(res).forEach(item => {
const { code, context, remarks } = item
if (['visit_base', 'today_visit', 'yesterday_visit', 'this_month_visit', 'last_month_visit'].includes(code)) {
// $set
this.$set(this.librarySettingForm, code, context)
// $set
this.$set(this.librarySettingForm, `${code}_checked`, remarks === '1')
}
})
}).catch(() => {
})
},
handleTabClick(index) {
// Tab
if (this.isDoubleClick) {
@ -462,6 +539,18 @@ export default {
}
this.prevActiveTab = this.activeTab //
this.activeTab = index
this.$nextTick(() => {
if (this.currentScreenItem && this.currentScreenItem.id === 5) {
if (this.$refs.advSettingRef) {
this.$refs.advSettingRef.updateSwiper()
}
} else if (this.currentScreenItem && this.currentScreenItem.id === 1) {
if (this.$refs.bookRecommendRef) {
this.$refs.bookRecommendRef.updateBookSwiper()
}
}
})
},
initTitle() {
@ -606,17 +695,88 @@ export default {
this.saveEdit(formName, field)
}
},
//
handleArrivalSettingChange(newValue) {
const virtualFormName = 'specialFields'
const field = 'arrival_library_setting'
//
if (this.originalValues[virtualFormName] === undefined) {
this.originalValues[virtualFormName] = {}
}
if (this.originalValues[virtualFormName][field] === undefined) {
this.originalValues[virtualFormName][field] = this.arrival_library_setting
}
//
// saveEdit
this.saveEdit(virtualFormName, field)
},
// saveEdit
saveEdit(formName, field) {
const value = this[formName][field]
const value = this[formName === 'specialFields' ? field : `${formName}.${field}`]
console.log(`保存${formName}.${field}`, value)
if (!value) {
// 0/1/2/3
if (formName !== 'specialFields' && !value) {
this.$message.warning(`${this.getFieldLabel(formName, field)}不能为空`)
this[formName][field] = this.originalValues[formName][field]
return
}
this.$message.success(`${this.getFieldLabel(formName, field)}更新成功`)
// 00
const isEmpty = value === '' || value === null || value === undefined
// 0
if (formName === 'librarySettingForm' && isEmpty) {
this.$message.warning(`${this.getFieldLabel(formName, field)}不能为空`)
this[formName][field] = this.originalValues[formName][field]
return
}
//
const checkBoxField = `${field}_checked` //
const isChecked = this[formName][checkBoxField] //
// remarks
const param = {
code: field,
context: value,
remarks: isChecked ? '1' : '0' //
}
if (formName === 'librarySettingForm') {
const checkBoxField = `${field}_checked`
param.remarks = this[formName][checkBoxField] ? '1' : '0'
}
//
FetchEditScreenSetting(param).then(res => {
this.$message.success(`${this.getFieldLabel(formName, field)}更新成功`)
}).catch(() => {
this.$message.error(`${this.getFieldLabel(formName, field)}更新失败`)
this[formName][field] = this.originalValues[formName][field]
})
},
//
handleCheckboxChange(code, checked) {
this.$set(this.librarySettingForm, `${code}_checked`, checked)
this.saveCheckboxStatus(code, checked)
},
saveCheckboxStatus(code, checked) {
const param = {
code: code, // visit_base
context: this.librarySettingForm[code], //
remarks: checked ? '1' : '0' // 转为后端需要的'1'/'0'
}
FetchEditScreenSetting(param).then(res => {
this.$message.success(`"${this.getFieldLabel('librarySettingForm', code)}"的直接显示状态已更新`)
}).catch(() => {
this.$message.error('状态更新失败')
//
this.$set(this.librarySettingForm, `${code}_checked`, !checked)
})
},
//
getFieldLabel(formName, field) {
@ -640,76 +800,12 @@ export default {
yesterday_visit: '昨日到馆',
this_month_visit: '本月到馆',
last_month_visit: '上月到馆'
},
specialFields: {
arrival_library_setting: '到馆统计设置'
}
}
return labels[formName][field] || field
},
//
handleAvatarSuccess(res, file) {
this.vxImageUrl = URL.createObjectURL(file.raw)
},
beforeAvatarUpload(file) {
const isJPG = file.type === 'image/jpeg'
const isLt2M = file.size / 1024 / 1024 < 2
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG 格式!')
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!')
}
return isJPG && isLt2M
},
//
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/cover-bg.png'),
// 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} 本图书`)
})
}
}
}
@ -717,7 +813,6 @@ export default {
<style scoped lang="scss">
@import "~@/assets/styles/digitalScreen.scss";
.config-screen{
display: flex;
justify-content: flex-start;
@ -725,6 +820,8 @@ export default {
padding: 12px 0 20px 0;
position: relative;
border-top: 1px solid #ebeef5;
height: 175px;
overflow: hidden;
&::before {
content: '';
@ -743,7 +840,7 @@ export default {
.config-screen-item{
position: relative;
width: 242px;
margin-right: 14px;
margin-right: 12px;
cursor: pointer;
transition: all 0.3s ease; //
z-index: 2; //

313
src/views/digitalScreen/module/advSetting.vue

@ -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>

45
src/views/digitalScreen/module/areaSetting.vue

@ -145,25 +145,24 @@
</el-form-item>
</div>
<div>
<el-form-item label="宣传图片" prop="remarks" />
<!--<div class="upload-container">
<i v-if="fileList.length === 0" class="iconfont icon-tianjiawenjian upload-icon" />
<div v-for="item in fileList" :key="item.name" class="file-list">
<i class="iconfont icon-xiaowenjian" />
{{ item.name }}
<i class="el-icon-close" @click="deleteFile(item)" />
<el-form-item label="宣传图片" prop="remarks">
<div style="display: flex; justify-content: flex-start;">
<div class="libImg-list">
<img v-for="(item,index) in libImgList" :key="index" :src="item.url" alt="">
</div>
<div class="upload-img-input">
<!-- @change="changeAiFile" -->
<input ref="fileInput" type="file" multiple>
<div class="upload-libImg"><i class="iconfont icon-shangchuan2" /><span>点击上传</span></div>
</div>
</div>
<div class="upload-input">
<input ref="fileInput" type="file" multiple @change="changeAiFile">
<div class="upload-zip"><i class="iconfont icon-shangchuan2" />点击上传</div>
</div>
</div> -->
</el-form-item>
</div>
</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"></el-button>
<el-button :loading="btnLoading" type="primary" @click="handleComfired"></el-button>
</div>
</div>
</el-dialog>
@ -229,7 +228,12 @@ export default {
libCode: [
{ required: true, message: '馆代码不可为空', trigger: 'blur' }
]
}
},
libImgList: [
// { url: require('@/assets/images/cover-bg.png') },
// { url: require('@/assets/images/cover-bg.png') },
// { url: require('@/assets/images/cover-bg.png') }
]
}
},
computed: {
@ -386,9 +390,6 @@ export default {
display: flex;
justify-content: flex-start;
margin-right: 0 !important;
.el-form-item__label{
}
.el-form-item__content{
width: 586px !important;
display: flex;
@ -398,6 +399,16 @@ export default {
}
}
}
}
.libImg-list{
display: flex;
justify-content: flex-start;
img{
display: block;
height: 120px;
margin-right: 10px;
}
}
</style>

176
src/views/digitalScreen/module/bookRecommend.vue

@ -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>

342
src/views/digitalScreen/module/mediaSetting.vue

@ -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>

160
src/views/digitalScreen/module/previewSetting.vue

@ -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>

4
src/views/system/group/index.vue

@ -68,10 +68,10 @@
librarySearchInterface 图书查询接口
librarySearchClntcode 图书查询接口 - 参数 - 馆代码
strFTZNCode 飞天服务码 -->
<el-form-item label="IP地址" prop="libraryIp">
<el-form-item label="人脸接口" prop="libraryIp">
<el-input v-model="form.libraryIp" />
</el-form-item>
<el-form-item label="验证IP地址" prop="checkReaderIp">
<el-form-item label="读者验证接口" prop="checkReaderIp">
<el-input v-model="form.checkReaderIp" />
</el-form-item>
<el-form-item label="读者验证方式" prop="checkReaderType">

Loading…
Cancel
Save