Browse Source

大屏界面

master
xuhuajiao 3 months ago
parent
commit
70a3204184
  1. 43
      src/api/digitalScreen/index.js
  2. BIN
      src/assets/images/screen/screen5.png
  3. 34
      src/assets/styles/digitalScreen.scss
  4. 10
      src/views/components/upload.vue
  5. 620
      src/views/digitalScreen/index.vue
  6. 59
      src/views/digitalScreen/module/addBookDialog.vue
  7. 84
      src/views/digitalScreen/module/advSetting.vue
  8. 101
      src/views/digitalScreen/module/areaSetting.vue
  9. 41
      src/views/digitalScreen/module/bookRecommend.vue
  10. 1
      src/views/digitalScreen/module/mediaSetting.vue
  11. 205
      src/views/digitalScreen/module/wecharQrCode.vue

43
src/api/digitalScreen/index.js

@ -17,4 +17,45 @@ export function FetchEditScreenSetting(parameter) {
}) })
} }
export default { FetchInitScreenSetting, FetchEditScreenSetting }
// 智慧大屏图书推荐
export function FetchInitScreenBookRecommend(params) {
return request({
url: 'api/screenSetting/initScreenBookRecommend' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
// 编辑智慧大屏图书推荐
export function FetchEditScreenBookRecommend(parameter) {
return request({
url: 'api/screenSetting/editScreenBookRecommend',
method: 'post',
data: parameter
})
}
// 智慧大屏分馆列表
export function FetchInitScreenBranch(params) {
return request({
url: 'api/screenSetting/initScreenBranch' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
// 编辑智慧大屏分馆
export function FetchEditScreenBranch(parameter) {
return request({
url: 'api/screenSetting/editScreenBranch',
method: 'post',
data: parameter
})
}
export default {
FetchInitScreenSetting,
FetchEditScreenSetting,
FetchInitScreenBookRecommend,
FetchEditScreenBookRecommend,
FetchInitScreenBranch,
FetchEditScreenBranch
}

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

Before

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

After

Width: 3556  |  Height: 2000  |  Size: 292 KiB

34
src/assets/styles/digitalScreen.scss

@ -99,7 +99,7 @@
} }
} }
.library-form{ .library-form{
padding-left: 70px;
padding-left: 100px;
margin-top: 10px; margin-top: 10px;
.el-input{ .el-input{
width: 240px !important; width: 240px !important;
@ -195,7 +195,7 @@
// } // }
.book-swiper-wrapper { .book-swiper-wrapper {
position: relative; position: relative;
width: 100%;
// width: 100%;
// padding: 0 20px; // padding: 0 20px;
max-width: 1140px; max-width: 1140px;
overflow: visible !important; // 避免意外截断 overflow: visible !important; // 避免意外截断
@ -208,14 +208,14 @@
width: 110px; width: 110px;
height: 160px; height: 160px;
flex-shrink: 0; // 禁止压缩保持固定尺寸 flex-shrink: 0; // 禁止压缩保持固定尺寸
border: 1px solid #fff;
border: 2px solid #fff;
border-radius: 4px; border-radius: 4px;
transition: all 0.2s; transition: all 0.2s;
margin: 0 5px; margin: 0 5px;
&:hover {
border-color: #0348F3; // hover时高亮边框
box-shadow: 0 2px 8px rgba(3, 72, 243, 0.1);
}
// &:hover {
// border-color: #0348F3; // hover时高亮边框
// box-shadow: 0 2px 8px rgba(3, 72, 243, 0.1);
// }
img{ img{
display: block; display: block;
width: 100%; width: 100%;
@ -242,8 +242,9 @@
color: #0348F3; color: #0348F3;
} }
.icon-weixuan { .icon-weixuan {
color: #A6ADB6;
color: #fff;
} }
} }
.book-delete { .book-delete {
@ -263,6 +264,17 @@
} }
border-color: #0348F3; border-color: #0348F3;
} }
&:hover {
border-color: #c9d4f0;
box-shadow: 0 2px 8px rgba(3, 72, 243, 0.1);
}
&.book-list-item--selected {
background:rgba(0,0,0,0.5);
border-color: #ED4A41;
box-shadow: 0 2px 12px rgba(3, 72, 243, 0.2);
}
} }
.book-upload-btn{ .book-upload-btn{
width: 160px; width: 160px;
@ -305,6 +317,7 @@
position: absolute; position: absolute;
left: 0; left: 0;
top: 0; top: 0;
width: 120px;
height: 120px; height: 120px;
opacity: 0; opacity: 0;
} }
@ -327,3 +340,8 @@
font-size: 30px; font-size: 30px;
} }
} }
// 选中时图片轻微缩放增强反馈
.book-list-item--selected .book-img{
transform: scale(0.95);
}

10
src/views/components/upload.vue

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<el-form-item class="book-cover-upload" :label="labelName" prop="cover">
<el-form-item v-if="uploadType !== 'other-digital'" class="book-cover-upload" :label="labelName" prop="cover">
<el-input v-model="fileNames" placeholder="请上传" :readonly="true" /> <el-input v-model="fileNames" placeholder="请上传" :readonly="true" />
<!-- <p :class="['input-style', form.cover === null ? 'error-box' :'']">{{ form.cover }}</p> --> <!-- <p :class="['input-style', form.cover === null ? 'error-box' :'']">{{ form.cover }}</p> -->
<!-- <span v-if="form.cover === null" class="error-tip">请上传图书封面</span> --> <!-- <span v-if="form.cover === null" class="error-tip">请上传图书封面</span> -->
@ -9,6 +9,11 @@
<el-button size="small" type="primary"><i class="iconfont icon-shangchuan" />上传</el-button> <el-button size="small" type="primary"><i class="iconfont icon-shangchuan" />上传</el-button>
</div> </div>
</el-form-item> </el-form-item>
<div v-else class="upload-img-input">
<input ref="fileInput" type="file" @change="changeFile($event)">
<div class="upload-libImg"><i class="iconfont icon-shangchuan2" /><span>点击上传</span></div>
</div>
</div> </div>
</template> </template>
@ -70,7 +75,7 @@ export default {
const res = await this.getImgPx(fileBase64) const res = await this.getImgPx(fileBase64)
this.imageUrl = fileBase64 this.imageUrl = fileBase64
this.px = res.width + 'px*' + res.height + 'px' this.px = res.width + 'px*' + res.height + 'px'
if (this.uploadType === 'book') {
if (this.uploadType === 'book' || this.uploadType !== 'other-digital') {
// //
upload(this.baseApi + '/api/fileRelevant/uploadBookImg', this.file).then(res => { upload(this.baseApi + '/api/fileRelevant/uploadBookImg', this.file).then(res => {
console.log(res) console.log(res)
@ -146,6 +151,7 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import "~@/assets/styles/digitalScreen.scss";
::v-deep .book-cover-upload { ::v-deep .book-cover-upload {
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;

620
src/views/digitalScreen/index.vue

@ -50,7 +50,6 @@
</div> </div>
<transition name="tab-slide" mode="out-in"> <transition name="tab-slide" mode="out-in">
<div :key="activeTab" class="content-area"> <div :key="activeTab" class="content-area">
<div v-if="currentScreenItem">
<!-- {{ currentScreenItem.name }}ID: {{ currentScreenItem.id }}内容 - 这里是第{{ activeTab + 1 }}个大屏的详细配置 --> <!-- {{ currentScreenItem.name }}ID: {{ currentScreenItem.id }}内容 - 这里是第{{ activeTab + 1 }}个大屏的详细配置 -->
<div> <div>
<div class="screen-content-title"> <div class="screen-content-title">
@ -136,7 +135,7 @@
class="edit-readonly" class="edit-readonly"
@dblclick="handleDblClick('openForm', 'open_lib_http')" @dblclick="handleDblClick('openForm', 'open_lib_http')"
> >
{{ openForm.open_lib_http || '' }}
{{ openForm.open_lib_http }}
</span> </span>
<el-input <el-input
v-else v-else
@ -152,7 +151,7 @@
class="edit-readonly" class="edit-readonly"
@dblclick="handleDblClick('openForm', 'open_lib_appId')" @dblclick="handleDblClick('openForm', 'open_lib_appId')"
> >
{{ openForm.open_lib_appId || '' }}
{{ openForm.open_lib_appId }}
</span> </span>
<el-input <el-input
v-else v-else
@ -168,7 +167,7 @@
class="edit-readonly" class="edit-readonly"
@dblclick="handleDblClick('openForm', 'open_lib_secret')" @dblclick="handleDblClick('openForm', 'open_lib_secret')"
> >
{{ openForm.open_lib_secret || '' }}
{{ openForm.open_lib_secret }}
</span> </span>
<el-input <el-input
v-else v-else
@ -193,7 +192,7 @@
class="edit-readonly" class="edit-readonly"
@dblclick="handleDblClick('hotForm', 'hot_search_http')" @dblclick="handleDblClick('hotForm', 'hot_search_http')"
> >
{{ hotForm.hot_search_http || '' }}
{{ hotForm.hot_search_http }}
</span> </span>
<el-input <el-input
v-else v-else
@ -218,7 +217,7 @@
class="edit-readonly" class="edit-readonly"
@dblclick="handleDblClick('vxForm', 'vx_appID')" @dblclick="handleDblClick('vxForm', 'vx_appID')"
> >
{{ vxForm.vx_appID || '' }}
{{ vxForm.vx_appID }}
</span> </span>
<el-input <el-input
v-else v-else
@ -234,7 +233,7 @@
class="edit-readonly" class="edit-readonly"
@dblclick="handleDblClick('vxForm', 'vx_AppSecret')" @dblclick="handleDblClick('vxForm', 'vx_AppSecret')"
> >
{{ vxForm.vx_AppSecret || '' }}
{{ vxForm.vx_AppSecret }}
</span> </span>
<el-input <el-input
v-else v-else
@ -248,34 +247,14 @@
</div> </div>
<div class="config-remarks">双击输入框可进行编辑图书馆公众号AppIDAppSecrect 仅用于总览屏显示公众号粉丝数量</div> <div class="config-remarks">双击输入框可进行编辑图书馆公众号AppIDAppSecrect 仅用于总览屏显示公众号粉丝数量</div>
</div> </div>
<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" style="margin-bottom: 20px;">
<p>公众号二维码</p>
<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>
</div>
<div class="config-remarks">双击可上传图片二维码用于总览屏媒体屏在任意分屏编辑均可生效</div>
</div>
<bookRecommend v-if="currentScreenItem.id === 1" ref="bookRecommendRef" />
<areaSetting v-if="currentScreenItem.id === 2" ref="areaSettingRef" />
<wecharQrCode v-if="currentScreenItem.id === 1 || currentScreenItem.id === 4" ref="wecharQrCodeRef" :qr-code-url="wecharQrCodeUrl" @triggerInit="initScreenSetting" @ready="onWechatQrCodeReady" />
<bookRecommend v-if="currentScreenItem.id === 1" ref="bookRecommendRef" @ready="initScreenBookRecommend" />
<areaSetting v-if="currentScreenItem.id === 2" ref="areaSettingRef" :map-data="mapData" @triggerInit="initScreenSetting" @ready="initScreenBranch" />
<mediaSetting v-if="currentScreenItem.id === 4" ref="mediaSettingRef" /> <mediaSetting v-if="currentScreenItem.id === 4" ref="mediaSettingRef" />
<advSetting v-if="currentScreenItem.id === 5" ref="advSettingRef" />
<advSetting v-if="currentScreenItem.id === 5" ref="advSettingRef" :welcome-play="welcomePlay" @triggerInit="initScreenSetting" />
</div> </div>
</div> </div>
</div> </div>
<div v-else>
请选择一个大屏进行配置
</div>
</div>
</transition> </transition>
</div> </div>
</template> </template>
@ -284,6 +263,7 @@
import { FetchInitScreenSetting, FetchEditScreenSetting } from '@/api/digitalScreen/index' import { FetchInitScreenSetting, FetchEditScreenSetting } from '@/api/digitalScreen/index'
import Sortable from 'sortablejs' import Sortable from 'sortablejs'
import previewSetting from './module/previewSetting' import previewSetting from './module/previewSetting'
import wecharQrCode from './module/wecharQrCode'
import bookRecommend from './module/bookRecommend' import bookRecommend from './module/bookRecommend'
import areaSetting from './module/areaSetting' import areaSetting from './module/areaSetting'
import mediaSetting from './module/mediaSetting' import mediaSetting from './module/mediaSetting'
@ -293,6 +273,7 @@ export default {
name: 'DigitalScreen', name: 'DigitalScreen',
components: { components: {
previewSetting, previewSetting,
wecharQrCode,
bookRecommend, bookRecommend,
areaSetting, areaSetting,
mediaSetting, mediaSetting,
@ -306,11 +287,11 @@ export default {
originalTitle: '', originalTitle: '',
activeTab: 0, activeTab: 0,
screenItems: [ screenItems: [
{ id: 1, time: '5', name: '总览屏', enabled: true, editing: false, originalTime: '5' },
{ id: 2, time: '5', name: '区域屏', enabled: true, editing: false, originalTime: '5' },
{ id: 3, time: '5', name: '统计屏', enabled: true, editing: false, originalTime: '5' },
{ id: 4, time: '5', name: '媒体屏', enabled: true, editing: false, originalTime: '5' },
{ id: 5, time: '5', name: '欢迎屏', enabled: true, editing: false, originalTime: '5' }
{ id: 1, time: '5', name: '总览屏', enabled: true, editing: false, originalTime: '5', code: 'show1' },
{ id: 2, time: '5', name: '区域屏', enabled: true, editing: false, originalTime: '5', code: 'show2' },
{ id: 3, time: '5', name: '统计屏', enabled: true, editing: false, originalTime: '5', code: 'show3' },
{ id: 4, time: '5', name: '媒体屏', enabled: true, editing: false, originalTime: '5', code: 'show4' },
{ id: 5, time: '5', name: '欢迎屏', enabled: true, editing: false, originalTime: '5', code: 'show5' }
], ],
editingLock: false, editingLock: false,
prevActiveTab: 0, prevActiveTab: 0,
@ -339,7 +320,9 @@ export default {
vx_appID: null, vx_appID: null,
vx_AppSecret: null vx_AppSecret: null
}, },
vxImageUrl: '',
wecharQrCodeUrl: null,
mapData: null,
welcomePlay: null,
editStatus: { editStatus: {
openForm: { openForm: {
open_lib_http: false, open_lib_http: false,
@ -361,7 +344,6 @@ export default {
yesterday_visit: null, yesterday_visit: null,
this_month_visit: null, this_month_visit: null,
last_month_visit: null, last_month_visit: null,
//
visit_base_checked: false, // visit_base_checked: false, //
today_visit_checked: false, // today_visit_checked: false, //
yesterday_visit_checked: false, // yesterday_visit_checked: false, //
@ -370,6 +352,7 @@ export default {
} }
}, },
originalValues: { originalValues: {
title: '',
openForm: {}, openForm: {},
hotForm: {}, hotForm: {},
vxForm: {}, vxForm: {},
@ -404,10 +387,10 @@ export default {
}, },
created() { created() {
this.initTitle() this.initTitle()
this.initScreenSetting()
}, },
mounted() { mounted() {
this.$nextTick(() => { this.$nextTick(() => {
this.initScreenSetting()
this.draggableScreen() this.draggableScreen()
if (this.$refs.bookRecommendRef) { if (this.$refs.bookRecommendRef) {
this.$refs.bookRecommendRef.updateBookSwiper() this.$refs.bookRecommendRef.updateBookSwiper()
@ -415,152 +398,126 @@ export default {
}) })
}, },
methods: { 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')
// })
// },
initScreenBranch() {
this.$refs.areaSettingRef.initScreenBranch()
},
initScreenBookRecommend() {
this.$refs.bookRecommendRef.initScreenBookRecommend()
},
onWechatQrCodeReady() {
this.$refs.wecharQrCodeRef.reloadImage()
},
// //
initScreenSetting() { initScreenSetting() {
FetchInitScreenSetting().then(res => { FetchInitScreenSetting().then(res => {
console.log('初始化', res)
//
const showScreenItem = Object.values(res).find(item => item.code === 'show_screen')
if (showScreenItem) {
// context
if (showScreenItem.context) {
const enabledIds = showScreenItem.context.split(',').map(Number)
this.screenItems.forEach(item => {
item.enabled = enabledIds.includes(item.id)
})
}
// remarks
if (showScreenItem.remarks) {
const orderIds = showScreenItem.remarks.split(',').map(Number)
// remarksscreenItems
this.screenItems.sort((a, b) => {
return orderIds.indexOf(a.id) - orderIds.indexOf(b.id)
})
}
}
Object.values(res).forEach(item => { Object.values(res).forEach(item => {
const { code, context } = item const { code, context } = item
// code
switch (code) {
//
case 'arrival_library_setting':
//
if (code === 'screen_title') {
this.screen_title = context
this.originalTitle = this.screen_title
this.originalValues.title = this.screen_title
return
}
//
if (code === 'arrival_library_setting') {
this.arrival_library_setting = context 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':
return
}
// show1-show5
if (code.startsWith('show') && !isNaN(parseInt(code.replace('show', '')))) {
const screenId = parseInt(code.replace('show', ''))
const screenItem = this.screenItems.find(item => item.id === screenId)
if (screenItem) {
screenItem.time = context || '5' // 5
screenItem.originalTime = screenItem.time // originalTime
}
return
}
//
if (['visit_base', 'last_year_visit_base', 'today_visit', 'yesterday_visit', 'this_month_visit', 'last_month_visit'].includes(code)) {
this.$set(this.librarySettingForm, code, context)
return
}
//
if (code === 'open_lib_http') {
this.openForm.open_lib_http = context this.openForm.open_lib_http = context
break
case 'open_lib_appId':
} else if (code === 'open_lib_appId') {
this.openForm.open_lib_appId = context this.openForm.open_lib_appId = context
break
case 'open_lib_secret':
} else if (code === 'open_lib_secret') {
this.openForm.open_lib_secret = context this.openForm.open_lib_secret = context
break
}
//
case 'hot_search_http':
//
if (code === 'hot_search_http') {
this.hotForm.hot_search_http = context this.hotForm.hot_search_http = context
break
}
//
case 'vx_appID':
//
if (code === 'vx_appID') {
this.vxForm.vx_appID = context this.vxForm.vx_appID = context
break
case 'vx_AppSecret':
} else if (code === 'vx_AppSecret') {
this.vxForm.vx_AppSecret = context 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
//
if (code === 'wechar_qr_code') {
this.wecharQrCodeUrl = context
}
if (code === 'map_data') {
this.mapData = context
}
if (code === 'welcome_play') {
this.welcomePlay = context
} }
}) })
// initScreenSetting
// initScreenSettingthis.$set
Object.values(res).forEach(item => { Object.values(res).forEach(item => {
const { code, context, remarks } = item const { code, context, remarks } = item
if (['visit_base', 'today_visit', 'yesterday_visit', 'this_month_visit', 'last_month_visit'].includes(code)) { if (['visit_base', 'today_visit', 'yesterday_visit', 'this_month_visit', 'last_month_visit'].includes(code)) {
// $set
this.$set(this.librarySettingForm, code, context) this.$set(this.librarySettingForm, code, context)
// $set
this.$set(this.librarySettingForm, `${code}_checked`, remarks === '1') this.$set(this.librarySettingForm, `${code}_checked`, remarks === '1')
} }
}) })
}).catch(() => { }).catch(() => {
}) })
}, },
handleTabClick(index) {
// Tab
if (this.isDoubleClick) {
this.isDoubleClick = false
return
}
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() { initTitle() {
this.screen_title = '默认大屏标题'
this.screen_title = '' //
this.originalTitle = this.screen_title this.originalTitle = this.screen_title
this.originalValues.title = this.screen_title
}, },
handleTitleDblClick() { handleTitleDblClick() {
this.isEditable = true this.isEditable = true
this.originalTitle = this.screen_title this.originalTitle = this.screen_title
this.originalValues.title = this.screen_title
this.$nextTick(() => { this.$nextTick(() => {
const titleInput = this.$refs.titleInput const titleInput = this.$refs.titleInput
if (titleInput) { if (titleInput) {
@ -570,49 +527,184 @@ export default {
}, },
handleTitleBlur() { handleTitleBlur() {
this.isEditable = false this.isEditable = false
if (this.screen_title !== this.originalTitle) {
this.updateTitle()
}
},
updateTitle() {
if (this.screen_title.length > 17) { if (this.screen_title.length > 17) {
this.$message.warning('标题不能超过17个字,请修改!') this.$message.warning('标题不能超过17个字,请修改!')
this.screen_title = this.originalTitle this.screen_title = this.originalTitle
return return
} }
console.log('更新标题接口调用,新标题:', this.screen_title)
this.originalTitle = this.screen_title
this.$message.success('标题更新成功!')
if (this.screen_title !== this.originalTitle) {
this.saveEdit('title', 'screen_title')
}
}, },
//
handleTabClick(index) {
// Tab
if (this.isDoubleClick) {
this.isDoubleClick = false
return
}
this.prevActiveTab = this.activeTab
this.activeTab = index
this.$nextTick(() => {
if (this.currentScreenItem && this.currentScreenItem.id === 1) {
if (this.$refs.bookRecommendRef) {
this.$refs.bookRecommendRef.updateBookSwiper()
}
} else if (this.currentScreenItem && this.currentScreenItem.id === 5) {
if (this.$refs.advSettingRef) {
this.$refs.advSettingRef.updateSwiper()
}
}
})
},
// handleTabClick(index) {
// if (this.isDoubleClick) {
// this.isDoubleClick = false
// return
// }
// const prevTab = this.activeTab
// this.activeTab = index
// if (prevTab === index) {
// return
// }
// this.$nextTick(() => {
// const currentId = this.currentScreenItem?.id
// if (!currentId) return
// switch (currentId) {
// case 1:
// this.handleScreen1()
// break
// case 4:
// this.handleScreen4()
// break
// case 5:
// this.handleScreen5()
// break
// }
// })
// },
// // ID=1
// handleScreen1() {
// if (this.$refs.bookRecommendRef) {
// this.$refs.bookRecommendRef.updateBookSwiper()
// } else {
// console.warn('bookRecommendID=1')
// }
// this.refreshWechatQrCode()
// },
// // ID=1
// handleScreen4() {
// this.refreshWechatQrCode()
// },
// // ID=5
// handleScreen5() {
// if (this.$refs.advSettingRef) {
// this.$refs.advSettingRef.updateSwiper()
// } else {
// console.warn('advSettingID=5')
// }
// },
// refreshWechatQrCode() {
// if (this.$refs.wecharQrCodeRef) {
// this.$refs.wecharQrCodeRef.reloadImage()
// } else {
// console.log('wecharQrCode')
// }
// },
// - show_screen
toggleScreenStatus(index) { toggleScreenStatus(index) {
const currentEnabledCount = this.enabledCount
if (this.screenItems[index].enabled && currentEnabledCount <= 1) {
this.$message.warning('至少需要启用一个大屏')
return
}
//
this.screenItems[index].enabled = !this.screenItems[index].enabled this.screenItems[index].enabled = !this.screenItems[index].enabled
const statusText = this.screenItems[index].enabled ? '启用' : '停用' const statusText = this.screenItems[index].enabled ? '启用' : '停用'
this.$message.info(`大屏${index + 1}${statusText}`)
this.$message.info(`大屏${index + 1}-即${this.screenItems[index].name}${statusText}`)
this.submitScreenOrderAndStatus()
}, },
// //
draggableScreen() { draggableScreen() {
const tbody = document.querySelector('.config-screen')
const container = document.querySelector('.config-screen')
const that = this const that = this
Sortable.create(tbody, {
let originalOrder = [...this.screenItems.map(item => item.id)]
Sortable.create(container, {
draggable: '.config-screen-item', draggable: '.config-screen-item',
animation: 150,
onStart() {
originalOrder = [...that.screenItems.map(item => item.id)]
},
onEnd({ newIndex, oldIndex }) { onEnd({ newIndex, oldIndex }) {
if (newIndex === oldIndex) return if (newIndex === oldIndex) return
const activeItemId = that.screenItems[that.activeTab].id const activeItemId = that.screenItems[that.activeTab].id
// //
const movedItem = that.screenItems.splice(oldIndex, 1)[0] const movedItem = that.screenItems.splice(oldIndex, 1)[0]
that.screenItems.splice(newIndex, 0, movedItem) that.screenItems.splice(newIndex, 0, movedItem)
// //
const newActiveIndex = that.screenItems.findIndex(item => item.id === activeItemId) const newActiveIndex = that.screenItems.findIndex(item => item.id === activeItemId)
// Tab
if (newActiveIndex !== -1) { if (newActiveIndex !== -1) {
that.activeTab = newActiveIndex that.activeTab = newActiveIndex
} }
//
const newOrder = [...that.screenItems.map(item => item.id)]
if (!that.arraysEqual(originalOrder, newOrder)) {
// show_screen
that.submitScreenOrderAndStatus()
}
} }
}) })
}, },
//
arraysEqual(arr1, arr2) {
if (arr1.length !== arr2.length) return false
for (let i = 0; i < arr1.length; i++) {
if (arr1[i] !== arr2[i]) return false
}
return true
},
// show_screen
submitScreenOrderAndStatus() {
// 1. IDenabledtrue
const enabledIds = this.screenItems
.filter(item => item.enabled)
.map(item => item.id)
.join(',')
// 2.
const orderIds = this.screenItems
.map(item => item.id)
.join(',')
// 3. saveEdit使specialFields
const formName = 'specialFields'
const field = 'show_screen'
//
if (!this.originalValues[formName]) {
this.originalValues[formName] = {}
}
this.originalValues[formName][field] = {
context: enabledIds,
remarks: orderIds
}
// saveEdit
this.saveEdit(formName, field)
},
// //
handleTimeClick(event) { handleTimeClick(event) {
// //
@ -657,40 +749,47 @@ export default {
} }
}) })
}, },
handleTimeBlur(item) { handleTimeBlur(item) {
//
if (item.time === '' || isNaN(item.time) || parseInt(item.time) <= 0) { if (item.time === '' || isNaN(item.time) || parseInt(item.time) <= 0) {
this.$message.warning('播放时长必须为大于0的数字') this.$message.warning('播放时长必须为大于0的数字')
item.time = item.originalTime item.time = item.originalTime
} else { } else {
if (item.time !== item.originalTime) {
//
item.time = parseInt(item.time).toString() item.time = parseInt(item.time).toString()
this.updateScreenTime(item)
//
if (item.time !== item.originalTime) {
this.submitScreenTime(item)
} }
} }
item.editing = false item.editing = false
}, },
updateScreenTime(item) {
console.log(`更新大屏${item.id}播放时长为${item.time}`)
this.$message.success(`大屏${item.id}播放时长已更新`)
// show1-show5
submitScreenTime(item) {
// 使specialFields
const formName = 'specialFields'
const field = item.code
//
if (!this.originalValues[formName]) {
this.originalValues[formName] = {}
}
this.originalValues[formName][field] = item.originalTime
// saveEdit
this.saveEdit(formName, field)
}, },
//
//
handleDblClick(formName, field) { handleDblClick(formName, field) {
//
this.originalValues[formName][field] = this[formName][field] this.originalValues[formName][field] = this[formName][field]
//
this.editStatus[formName][field] = true this.editStatus[formName][field] = true
//
this.$nextTick(() => { this.$nextTick(() => {
const input = this.$refs[`${formName}${field}`] const input = this.$refs[`${formName}${field}`]
if (input) input.focus() if (input) input.focus()
}) })
}, },
// /
handleBlur(formName, field) { handleBlur(formName, field) {
//
this.editStatus[formName][field] = false this.editStatus[formName][field] = false
//
if (this[formName][field] !== this.originalValues[formName][field]) { if (this[formName][field] !== this.originalValues[formName][field]) {
this.saveEdit(formName, field) this.saveEdit(formName, field)
} }
@ -700,87 +799,137 @@ export default {
const virtualFormName = 'specialFields' const virtualFormName = 'specialFields'
const field = 'arrival_library_setting' const field = 'arrival_library_setting'
//
if (this.originalValues[virtualFormName] === undefined) {
//
if (!this.originalValues[virtualFormName]) {
this.originalValues[virtualFormName] = {} this.originalValues[virtualFormName] = {}
} }
if (this.originalValues[virtualFormName][field] === undefined) { if (this.originalValues[virtualFormName][field] === undefined) {
this.originalValues[virtualFormName][field] = this.arrival_library_setting this.originalValues[virtualFormName][field] = this.arrival_library_setting
} }
// saveEdit
this.saveEdit(virtualFormName, field) this.saveEdit(virtualFormName, field)
}, },
// saveEdit
handleCheckboxChange(field, checked) {
this.$set(this.librarySettingForm, `${field}_checked`, checked)
this.saveEdit('librarySettingForm', field)
},
saveEdit(formName, field) { saveEdit(formName, field) {
const value = this[formName === 'specialFields' ? field : `${formName}.${field}`]
console.log(`保存${formName}.${field}`, value)
let code = field
let context
let remarks = ''
// 0/1/2/3
if (formName !== 'specialFields' && !value) {
this.$message.warning(`${this.getFieldLabel(formName, field)}不能为空`)
this[formName][field] = this.originalValues[formName][field]
return
//
if (formName === 'title') {
code = 'screen_title'
context = this.screen_title
} else if (formName === 'specialFields' && field === 'show_screen') {
// show_screen
context = this.originalValues[formName][field].context
remarks = this.originalValues[formName][field].remarks
} else if (formName === 'specialFields' && field.startsWith('show')) {
// show1-show5
// screenItemstime
const screenItem = this.screenItems.find(item => item.code === field)
context = screenItem ? screenItem.time : '5' // 5
} else if (formName === 'specialFields') {
// arrival_library_setting
context = this[field]
} else {
//
context = this[formName][field]
if (formName === 'librarySettingForm') {
remarks = this[formName][`${field}_checked`] ? '1' : '0'
}
} }
// 00
const isEmpty = value === '' || value === null || value === undefined
// 0
if (formName === 'librarySettingForm' && isEmpty) {
// 2.
// show_screen
if (formName === 'specialFields' && field === 'show_screen') {
if (!context) {
this.$message.warning('至少需要启用一个大屏')
return
}
} else if (formName === 'specialFields' && field.startsWith('show')) {
// show1-show5
if (!context || isNaN(context) || parseInt(context) <= 0) {
this.$message.warning('播放时长必须为大于0的数字')
this.rollbackValue(formName, field)
return
}
} else if (!context && context !== 0) {
//
this.$message.warning(`${this.getFieldLabel(formName, field)}不能为空`) this.$message.warning(`${this.getFieldLabel(formName, field)}不能为空`)
this[formName][field] = this.originalValues[formName][field]
this.rollbackValue(formName, field)
return return
} }
//
const checkBoxField = `${field}_checked` //
const isChecked = this[formName][checkBoxField] //
// 3.
const submitParam = { code, context, remarks }
// remarks
const param = {
code: field,
context: value,
remarks: isChecked ? '1' : '0' //
// 4.
FetchEditScreenSetting(submitParam)
.then(() => {
this.$message.success(`${this.getFieldLabel(formName, field)}更新成功`)
//
if (formName === 'title') {
this.originalTitle = this.screen_title
this.originalValues.title = this.screen_title
} else if (formName === 'specialFields' && field.startsWith('show') && field !== 'show_screen') {
// originalTime
const screenItem = this.screenItems.find(item => item.code === field)
if (screenItem) {
screenItem.originalTime = context
} }
if (formName === 'librarySettingForm') {
const checkBoxField = `${field}_checked`
param.remarks = this[formName][checkBoxField] ? '1' : '0'
this.originalValues[formName][field] = context
} else if (formName !== 'specialFields' || field !== 'show_screen') {
this.originalValues[formName][field] = context
} }
//
FetchEditScreenSetting(param).then(res => {
this.$message.success(`${this.getFieldLabel(formName, field)}更新成功`)
}).catch(() => {
})
.catch(() => {
this.$message.error(`${this.getFieldLabel(formName, field)}更新失败`) this.$message.error(`${this.getFieldLabel(formName, field)}更新失败`)
this[formName][field] = this.originalValues[formName][field]
this.rollbackValue(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'
//
rollbackValue(formName, field) {
if (this.originalValues[formName]?.[field] !== undefined) {
if (formName === 'title') {
this.screen_title = this.originalValues[formName][field]
} else if (formName === 'specialFields' && field.startsWith('show') && field !== 'show_screen') {
//
const screenItem = this.screenItems.find(item => item.code === field)
if (screenItem) {
screenItem.time = this.originalValues[formName][field]
screenItem.originalTime = this.originalValues[formName][field]
}
} else if (formName === 'specialFields') {
this[field] = this.originalValues[formName][field]
} else {
this[formName][field] = this.originalValues[formName][field]
//
if (formName === 'librarySettingForm') {
const originalChecked = this.originalValues[formName][`${field}_checked`]
if (originalChecked !== undefined) {
this[formName][`${field}_checked`] = originalChecked
}
}
}
} }
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) { getFieldLabel(formName, field) {
const labels = { const labels = {
title: {
screen_title: '大屏标题'
},
specialFields: {
arrival_library_setting: '到馆统计设置',
show_screen: '大屏显示设置',
show1: '总览屏播放时长',
show2: '区域屏播放时长',
show3: '统计屏播放时长',
show4: '媒体屏播放时长',
show5: '欢迎屏播放时长'
},
openForm: { openForm: {
open_lib_http: 'OpenLib地址', open_lib_http: 'OpenLib地址',
open_lib_appId: 'AppId', open_lib_appId: 'AppId',
@ -800,9 +949,6 @@ export default {
yesterday_visit: '昨日到馆', yesterday_visit: '昨日到馆',
this_month_visit: '本月到馆', this_month_visit: '本月到馆',
last_month_visit: '上月到馆' last_month_visit: '上月到馆'
},
specialFields: {
arrival_library_setting: '到馆统计设置'
} }
} }
return labels[formName][field] || field return labels[formName][field] || field
@ -935,7 +1081,7 @@ export default {
// + // +
.content-area { .content-area {
height: 520px;
height: 510px;
border-radius: 4px; border-radius: 4px;
width: 100%; width: 100%;
overflow-y: scroll; overflow-y: scroll;

59
src/views/digitalScreen/module/addBookDialog.vue

@ -3,8 +3,8 @@
<div class="setting-dialog"> <div class="setting-dialog">
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="90px"> <el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="90px">
<div style="width: 696px;"> <div style="width: 696px;">
<el-form-item label="题名" prop="title">
<el-input v-model="form.title" placeholder="请输入" />
<el-form-item label="题名" prop="name">
<el-input v-model="form.name" placeholder="请输入" />
</el-form-item> </el-form-item>
<el-form-item label="著者" prop="author"> <el-form-item label="著者" prop="author">
<el-input v-model="form.author" placeholder="请输入" /> <el-input v-model="form.author" placeholder="请输入" />
@ -12,11 +12,11 @@
<el-form-item label="ISBN" prop="isbn"> <el-form-item label="ISBN" prop="isbn">
<el-input v-model="form.isbn" placeholder="请输入" /> <el-input v-model="form.isbn" placeholder="请输入" />
</el-form-item> </el-form-item>
<el-form-item label="分类号" prop="classNo">
<el-input v-model="form.classNo" placeholder="请输入" />
<el-form-item label="分类号" prop="callnos">
<el-input v-model="form.callnos" placeholder="请输入" />
</el-form-item> </el-form-item>
<el-form-item label="出版年份" prop="publishYear">
<el-input v-model="form.publishYear" placeholder="请输入" />
<el-form-item label="出版年份" prop="publisherdate">
<el-input v-model="form.publisherdate" placeholder="请输入" />
</el-form-item> </el-form-item>
<div> <div>
<el-form-item label="出版社" prop="publisher"> <el-form-item label="出版社" prop="publisher">
@ -24,13 +24,13 @@
</el-form-item> </el-form-item>
</div> </div>
<div> <div>
<el-form-item label="简介" prop="remarks">
<el-input v-model="form.remarks" type="textarea" row="4" placeholder="请输入" style="width: 586px;" />
<el-form-item label="简介" prop="explain">
<el-input v-model="form.explain" type="textarea" row="4" placeholder="请输入" style="width: 586px;" />
</el-form-item> </el-form-item>
</div> </div>
<UploadCover :label-name="labelName" :form="form" upload-type="book" @childCover="handleCover" /> <UploadCover :label-name="labelName" :form="form" upload-type="book" @childCover="handleCover" />
</div> </div>
<div v-if="form.bookCover" class="preview-cover">
<div v-if="form.imgPath" class="preview-cover">
<p>封面预览</p> <p>封面预览</p>
<img :src="bookCover" alt=""> <img :src="bookCover" alt="">
</div> </div>
@ -45,6 +45,7 @@
</template> </template>
<script> <script>
import { FetchEditScreenBookRecommend } from '@/api/digitalScreen/index'
import UploadCover from '@/views/components/upload.vue' import UploadCover from '@/views/components/upload.vue'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
@ -55,11 +56,11 @@ export default {
return { return {
btnLoading: false, btnLoading: false,
addBookDialogVisible: false, addBookDialogVisible: false,
form: { id: null, title: null, author: null, isbn: null, classNo: null, publishYear: null, publisher: null, bookCover: null, bookRecNo: null, remarks: null },
form: { id: null, name: null, author: null, isbn: null, callnos: null, publisherdate: null, publisher: null, imgPath: null, explain: null },
bookCover: null, bookCover: null,
labelName: '图书封面', labelName: '图书封面',
rules: { rules: {
title: [
name: [
{ required: true, message: '题名不可为空', trigger: 'blur' } { required: true, message: '题名不可为空', trigger: 'blur' }
], ],
// author: [ // author: [
@ -68,7 +69,7 @@ export default {
isbn: [ isbn: [
{ required: true, message: 'ISBN不可为空', trigger: 'blur' } { required: true, message: 'ISBN不可为空', trigger: 'blur' }
] ]
// classNo: [
// callnos: [
// { required: true, message: '', trigger: 'blur' } // { required: true, message: '', trigger: 'blur' }
// ], // ],
// publisher: [ // publisher: [
@ -88,10 +89,10 @@ export default {
handleCover(value) { handleCover(value) {
console.log(value) console.log(value)
if (value) { if (value) {
this.form.bookCover = value
this.bookCover = this.baseApi + '/api/fileRelevant/getImg?imgType=2&imgId=' + value + '.jpg'
this.form.imgPath = value
this.bookCover = this.baseApi + '/api/fileRelevant/getImg?imgType=2&imgId=' + value
} else { } else {
this.form.bookCover = null
this.form.imgPath = null
this.bookCover = null this.bookCover = null
} }
}, },
@ -102,22 +103,18 @@ export default {
this.$refs.form.validate((valid) => { this.$refs.form.validate((valid) => {
if (valid) { if (valid) {
this.addBookDialogVisible = false 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
// })
console.log(this.form)
FetchEditScreenBookRecommend(this.form).then((res) => {
if (res.code !== 500) {
this.$message({ message: '推荐图书新增成功', type: 'success', offset: 8 })
} else {
this.$message({ message: res.message, type: 'error', offset: 8 })
}
this.handleClose()
}).catch(err => {
console.log(err)
this.addBookDialogVisible = false
})
} else { } else {
console.log('error submit!!') console.log('error submit!!')
return false return false

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

@ -4,12 +4,12 @@
<div class="config-item-main"> <div class="config-item-main">
<span class="data-title">播放设置</span> <span class="data-title">播放设置</span>
<el-form ref="advForm" class="advForm" :model="advForm" size="small" label-width="100px"> <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>
<el-form-item label="图片切换时长" prop="welcome_play">
<div v-if="!editStatus.advForm.welcome_play" style="display: flex; justify-content: flex-start; width: 340px; height: 32px; align-items: flex-start;">
<span class="edit-readonly" @dblclick="handleDblClick('advForm', 'welcome_play')"> {{ advForm.welcome_play || '' }} </span>
<span class="edit-slot"></span> <span class="edit-slot"></span>
</div> </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-input v-else ref="advFormwelcome_play" v-model="advForm.welcome_play" @blur="handleBlur('advForm', 'welcome_play')" @keyup.enter="handleBlur('advForm', 'welcome_play')"><template slot="append"></template></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@ -30,16 +30,19 @@
v-for="(book, index) in advImgList" v-for="(book, index) in advImgList"
:key="book.id" :key="book.id"
class="book-list-item" class="book-list-item"
:class="{ 'book-list-item--selected': book.selected }"
> >
<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)">
<div style="cursor: default;" @click.stop="toggleBookSelect(index)">
<img :src="book.url || require('@/assets/images/cover-bg.png')" alt="图书封面"></img>
</div>
<!-- <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-if="book.selected" class="iconfont icon-wancheng" />
<i v-else class="iconfont icon-weixuan" /> <i v-else class="iconfont icon-weixuan" />
</div> </div>
<div class="book-delete" @click.stop="deleteBook(index)"> <div class="book-delete" @click.stop="deleteBook(index)">
<i class="iconfont icon-shanchu" /> <i class="iconfont icon-shanchu" />
</div>
</div> -->
</swiper-slide> </swiper-slide>
</swiper> </swiper>
</div> </div>
@ -60,6 +63,7 @@
</template> </template>
<script> <script>
import { FetchEditScreenSetting } from '@/api/digitalScreen/index'
import { swiper, swiperSlide } from 'vue-awesome-swiper' import { swiper, swiperSlide } from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css' import 'swiper/dist/css/swiper.css'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
@ -72,21 +76,27 @@ export default {
swiper, swiper,
swiperSlide swiperSlide
}, },
props: {
welcomePlay: {
type: String,
default: null
}
},
data() { data() {
return { return {
advForm: { advForm: {
time: null
welcome_play: null
}, },
editStatus: { editStatus: {
advForm: { advForm: {
time: false
welcome_play: false
} }
}, },
originalValues: { originalValues: {
advForm: {} advForm: {}
}, },
advImgList: [ advImgList: [
{ id: 1, url: require('@/assets/images/screen/screen4.png'), selected: false },
{ id: 1, url: require('@/assets/images/screen/screen5.png'), selected: false },
{ id: 2, url: require('@/assets/images/screen/screen4.png'), selected: true }, { id: 2, url: require('@/assets/images/screen/screen4.png'), selected: true },
{ id: 3, url: require('@/assets/images/screen/screen4.png'), selected: false }, { id: 3, url: require('@/assets/images/screen/screen4.png'), selected: false },
{ id: 4, url: require('@/assets/images/screen/screen4.png'), selected: false }, { id: 4, url: require('@/assets/images/screen/screen4.png'), selected: false },
@ -122,18 +132,21 @@ export default {
return this.advImgList.some(book => book.selected) return this.advImgList.some(book => book.selected)
} }
}, },
watch: {
welcomePlay(newVal) {
if (newVal !== this.advForm.welcome_play) {
this.advForm.welcome_play = newVal
this.originalValues.advForm.welcome_play = newVal
}
}
},
created() { created() {
this.advForm.welcome_play = this.welcomePlay
}, },
mounted() { mounted() {
}, },
methods: { methods: {
updateSwiper() {
if (this.$refs.adImgSwiper && this.$refs.adImgSwiper.swiper) {
const swiper = this.$refs.adImgSwiper.swiper
swiper.update()
swiper.slideReset()
}
},
handleDblClick(formName, field) { handleDblClick(formName, field) {
this.originalValues[formName][field] = this[formName][field] this.originalValues[formName][field] = this[formName][field]
this.editStatus[formName][field] = true this.editStatus[formName][field] = true
@ -145,18 +158,43 @@ export default {
handleBlur(formName, field) { handleBlur(formName, field) {
this.editStatus[formName][field] = false this.editStatus[formName][field] = false
if (this[formName][field] !== this.originalValues[formName][field]) { if (this[formName][field] !== this.originalValues[formName][field]) {
this.saveEdit(formName, field)
this.submitMapData(formName, field)
} }
}, },
saveEdit(formName, field) {
submitMapData(formName, field) {
const value = this[formName][field] const value = this[formName][field]
console.log(`保存${formName}.${field}`, value)
if (!value) { if (!value) {
this.$message.warning(`${this.getFieldLabel(formName, field)}不能为空`)
this.$message.warning(`图片切换时长不能为空`)
this[formName][field] = this.originalValues[formName][field] this[formName][field] = this.originalValues[formName][field]
return return
} }
this.$message.success(`${this.getFieldLabel(formName, field)}更新成功`)
const param = {
'code': field,
'context': value,
'remarks': null
}
FetchEditScreenSetting(param)
.then((res) => {
if (res.code !== 500) {
this.$message.success('图片切换时长更新成功')
this.$emit('update:welcomePlay', value)
this.$emit('triggerInit')
} else {
this.$message.error('图片切换时长更新失败')
}
})
.catch(() => {
this.$message.error('图片切换时长更新失败')
})
},
updateSwiper() {
if (this.$refs.adImgSwiper && this.$refs.adImgSwiper.swiper) {
const swiper = this.$refs.adImgSwiper.swiper
swiper.update()
swiper.slideReset()
}
}, },
toggleBookSelect(index) { toggleBookSelect(index) {
this.advImgList[index].selected = !this.advImgList[index].selected this.advImgList[index].selected = !this.advImgList[index].selected

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

@ -4,22 +4,23 @@
<div class="config-item-main"> <div class="config-item-main">
<span class="data-title">地图DataV</span> <span class="data-title">地图DataV</span>
<el-form ref="areaForm" class="areaForm" :model="areaForm" size="small" label-width="100px"> <el-form ref="areaForm" class="areaForm" :model="areaForm" size="small" label-width="100px">
<el-form-item label="GeoJSON" prop="geoJSON">
<el-form-item label="GeoJSON" prop="map_data">
<span <span
v-if="!editStatus.areaForm.geoJSON"
v-if="!editStatus.areaForm.map_data"
class="edit-readonly" class="edit-readonly"
@dblclick="handleDblClick('areaForm', 'geoJSON')"
style="padding: 4px 15px;"
@dblclick="handleDblClick('areaForm', 'map_data')"
> >
{{ areaForm.geoJSON || '' }}
{{ areaForm.map_data || '' }}
</span> </span>
<el-input <el-input
v-else v-else
ref="areaFormgeoJSON"
v-model="areaForm.geoJSON"
ref="areaFormmap_data"
v-model="areaForm.map_data"
type="textarea" type="textarea"
rows="5" rows="5"
@blur="handleBlur('areaForm', 'geoJSON')"
@keyup.enter="handleBlur('areaForm', 'geoJSON')"
@blur="handleBlur('areaForm', 'map_data')"
@keyup.enter="handleBlur('areaForm', 'map_data')"
/> />
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -50,6 +51,7 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
<el-pagination <el-pagination
v-if="tableData.length !== 0"
style="margin: 34px 0 10px 0 !important;" style="margin: 34px 0 10px 0 !important;"
:current-page="page.page" :current-page="page.page"
:total="page.total" :total="page.total"
@ -171,19 +173,27 @@
</template> </template>
<script> <script>
import { FetchEditScreenSetting, FetchInitScreenBranch } from '@/api/digitalScreen/index'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
export default { export default {
name: 'AreaSetting', name: 'AreaSetting',
components: { }, components: { },
props: {
mapData: {
type: String,
default: null
}
},
data() { data() {
return { return {
btnLoading: false,
areaForm: { areaForm: {
geoJSON: null
map_data: null
}, },
editStatus: { editStatus: {
areaForm: { areaForm: {
geoJSON: false
map_data: false
} }
}, },
originalValues: { originalValues: {
@ -192,17 +202,10 @@ export default {
geoJsonVisible: false, geoJsonVisible: false,
link: 'https://datav.aliyun.com/portal/school/atlas/area_selector', link: 'https://datav.aliyun.com/portal/school/atlas/area_selector',
copied: false, copied: false,
tableData: [{
name: '总管',
libCode: 'lib001',
province: '114.133561,30.641408',
number: '3'
}, {
name: '分管1',
libCode: 'lib001',
province: '114.133561,30.641408',
number: '3'
}],
tableData: [
// { name: '', libCode: 'lib001', province: '114.133561,30.641408', number: '3' },
// { name: '1', libCode: 'lib001', province: '114.133561,30.641408', number: '3' }
],
page: { page: {
page: 1, page: 1,
size: 10, size: 10,
@ -241,42 +244,70 @@ export default {
'baseApi' 'baseApi'
]) ])
}, },
watch: {
mapData(newVal) {
if (newVal !== this.areaForm.map_data) {
this.areaForm.map_data = newVal
this.originalValues.areaForm.map_data = newVal
}
}
},
created() { created() {
this.areaForm.map_data = this.mapData
},
mounted() {
this.$emit('ready')
}, },
methods: { methods: {
//
initScreenBranch() {
FetchInitScreenBranch().then((res) => {
console.log('initScreenBranch', res)
}).catch(err => {
console.log(err)
})
},
handleDblClick(formName, field) { handleDblClick(formName, field) {
//
this.originalValues[formName][field] = this[formName][field] this.originalValues[formName][field] = this[formName][field]
//
this.editStatus[formName][field] = true this.editStatus[formName][field] = true
//
this.$nextTick(() => { this.$nextTick(() => {
const input = this.$refs[`${formName}${field}`] const input = this.$refs[`${formName}${field}`]
if (input) input.focus() if (input) input.focus()
}) })
}, },
// /
handleBlur(formName, field) { handleBlur(formName, field) {
//
this.editStatus[formName][field] = false this.editStatus[formName][field] = false
//
if (this[formName][field] !== this.originalValues[formName][field]) { if (this[formName][field] !== this.originalValues[formName][field]) {
this.saveEdit(formName, field)
this.submitMapData(formName, field)
} }
}, },
//
saveEdit(formName, field) {
submitMapData(formName, field) {
const value = this[formName][field] const value = this[formName][field]
console.log(`保存${formName}.${field}`, value)
if (!value) { if (!value) {
this.$message.warning(`${this.getFieldLabel(formName, field)}不能为空`)
this.$message.warning(`GeoJSON不能为空`)
this[formName][field] = this.originalValues[formName][field] this[formName][field] = this.originalValues[formName][field]
return return
} }
this.$message.success(`${this.getFieldLabel(formName, field)}更新成功`)
const param = {
'code': field,
'context': value,
'remarks': null
}
FetchEditScreenSetting(param)
.then((res) => {
if (res.code !== 500) {
this.$message.success('GeoJSON更新成功')
this.$emit('update:mapData', value)
this.$emit('triggerInit')
} else {
this.$message.error('GeoJSON更新失败')
}
})
.catch(() => {
this.$message.error('GeoJSON更新失败')
})
}, },
handleClose() { handleClose() {
this.geoJsonVisible = false this.geoJsonVisible = false
this.libDialogVisible = false this.libDialogVisible = false

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

@ -28,7 +28,7 @@
</div> </div>
<!-- <div class="book-upload-btn" @click.stop="uploadBook"><i class="iconfont icon-shangchuan2" /></div> --> <!-- <div class="book-upload-btn" @click.stop="uploadBook"><i class="iconfont icon-shangchuan2" /></div> -->
</div> </div>
<div style="display: flex; flex-direction: column; justify-content: flex-start; margin-left: 15px;">
<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 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"> <el-button size="mini" style="margin-left: 0 !important; margin-top: 10px;" :disabled="!hasSelectedItems" @click="batchDelete">
<i class="iconfont icon-shanchu" /> <i class="iconfont icon-shanchu" />
@ -40,6 +40,7 @@
</template> </template>
<script> <script>
import { FetchInitScreenBookRecommend } from '@/api/digitalScreen/index'
import { swiper, swiperSlide } from 'vue-awesome-swiper' import { swiper, swiperSlide } from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css' import 'swiper/dist/css/swiper.css'
import addBookDialog from './addBookDialog' import addBookDialog from './addBookDialog'
@ -57,21 +58,21 @@ export default {
data() { data() {
return { return {
bookList: [ 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 }
// { 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: { swiperOptions: {
slidesPerView: 'auto', // slidesPerView: 'auto', //
@ -105,8 +106,16 @@ export default {
created() { created() {
}, },
mounted() { mounted() {
this.$emit('ready')
}, },
methods: { methods: {
initScreenBookRecommend() {
FetchInitScreenBookRecommend().then((res) => {
console.log('BookRecommend', res)
}).catch(err => {
console.log(err)
})
},
updateBookSwiper() { updateBookSwiper() {
if (this.$refs.bookSwiper && this.$refs.bookSwiper.swiper) { if (this.$refs.bookSwiper && this.$refs.bookSwiper.swiper) {
const swiper = this.$refs.bookSwiper.swiper const swiper = this.$refs.bookSwiper.swiper

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

@ -186,6 +186,7 @@ export default {
components: { }, components: { },
data() { data() {
return { return {
btnLoading: false,
tableData: [ 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' },
{ 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' }

205
src/views/digitalScreen/module/wecharQrCode.vue

@ -0,0 +1,205 @@
<template>
<div class="config-item">
<div class="config-item-main">
<span class="data-title">二维码</span>
<div class="upload-item" style="margin-bottom: 20px;">
<p>公众号二维码</p>
<div style="display: flex; justify-content: flex-start;">
<div class="image-container">
<div v-if="isLoading" class="image-loading">
<div class="spinner" />
<span class="loading-text">加载中...</span>
</div>
<img
v-show="!isLoading || imageError"
:key="imageKey"
style="display: block; height: 120px; margin-right: 15px; transition: opacity 0.3s ease-in-out;"
:src="currentQrCodeUrl"
:class="{ 'image-loaded': !isLoading && currentQrCodeUrl }"
alt="公众号二维码"
@load="handleImageLoad"
@error="handleImageError"
>
<!-- 错误提示 -->
<div v-if="imageError" class="image-error">
<i class="iconfont icon-error" />
<span>加载失败</span>
</div>
</div>
<UploadCover upload-type="other-digital" @childCover="handleCover" />
</div>
</div>
</div>
<div class="config-remarks">双击可上传图片二维码用于总览屏媒体屏在任意分屏编辑均可生效</div>
</div>
</template>
<script>
import { FetchEditScreenSetting } from '@/api/digitalScreen/index'
import UploadCover from '@/views/components/upload.vue'
import { mapGetters } from 'vuex'
export default {
name: 'WecharQrCode',
components: { UploadCover },
props: {
qrCodeUrl: {
type: String,
default: null
}
},
data() {
return {
defaultImg: '@/assets/images/cover-bg.png',
imageKey: 0,
localQrCodeUrl: null,
isLoading: false, //
imageError: false //
}
},
computed: {
...mapGetters(['baseApi']),
currentQrCodeUrl() {
if (this.localQrCodeUrl) {
return this.localQrCodeUrl
}
if (this.qrCodeUrl) {
return this.qrCodeUrl.startsWith('http') ? this.qrCodeUrl : this.baseApi + this.qrCodeUrl
}
return this.defaultImg
}
},
watch: {
qrCodeUrl(newVal) {
this.localQrCodeUrl = newVal
this.reloadImage()
},
currentQrCodeUrl(newVal) {
if (newVal && newVal !== this.defaultImg) {
this.reloadImage()
}
}
},
created() {
this.localQrCodeUrl = this.qrCodeUrl
},
mounted() {
this.$emit('ready')
},
methods: {
handleCover(value) {
if (value) {
const imgUrl = this.baseApi + '/api/fileRelevant/getImg?imgType=1&imgId=' + value
this.submitCover(imgUrl)
} else {
this.localQrCodeUrl = null
this.imageKey++
this.isLoading = false
this.imageError = false
}
},
submitCover(imgUrl) {
const param = {
'code': 'wechar_qr_code',
'context': imgUrl,
'remarks': null
}
FetchEditScreenSetting(param)
.then(() => {
this.$message.success('公众号二维码更新成功')
this.localQrCodeUrl = imgUrl
this.reloadImage()
this.$emit('update:qrCodeUrl', imgUrl)
this.$emit('triggerInit')
})
.catch(() => {
this.$message.error('公众号二维码更新失败')
})
},
reloadImage() {
this.isLoading = true
this.imageError = false
this.imageKey++
},
//
handleImageLoad() {
this.isLoading = false
this.imageError = false
},
//
handleImageError() {
this.isLoading = false
this.imageError = true
}
}
}
</script>
<style lang="scss" scoped>
@import "~@/assets/styles/digitalScreen.scss";
.image-container {
position: relative;
min-width: 120px;
height: 120px;
// margin-right: 15px;
}
.image-loading {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 120px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #f5f5f5;
border-radius: 4px;
}
.spinner {
width: 20px;
height: 20px;
border: 2px solid #eee;
border-top: 2px solid #0348f3;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 8px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading-text {
font-size: 12px;
color: #666;
}
.image-loaded {
opacity: 1;
}
.image-error {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 120px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #f5f5f5;
border-radius: 4px;
color: #ED4A41;
font-size: 12px;
}
.image-error .icon-error {
font-size: 20px;
margin-bottom: 8px;
}
</style>
Loading…
Cancel
Save