|
|
|
@ -75,7 +75,7 @@ |
|
|
|
@keyup.enter="handleBlur('openForm', 'open_lib_secret')" |
|
|
|
/> |
|
|
|
</el-form-item> |
|
|
|
<el-form-item label="sm4-key" prop="sm4_key"> |
|
|
|
<el-form-item label="sm4‑key" prop="sm4_key"> |
|
|
|
<el-tooltip |
|
|
|
v-if="!editStatus.openForm.sm4_key" |
|
|
|
class="item" |
|
|
|
@ -176,7 +176,6 @@ |
|
|
|
</el-form-item> |
|
|
|
</el-form> |
|
|
|
</div> |
|
|
|
<!-- <div class="config-remarks">双击输入框可进行编辑。</div> --> |
|
|
|
</div> |
|
|
|
<div class="config-item"> |
|
|
|
<div class="config-item-main"> |
|
|
|
@ -208,7 +207,7 @@ |
|
|
|
</el-form> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<!-- 监听子组件 update:qr‑code‑url 更新父组件本地变量 --> |
|
|
|
<!-- 微信二维码组件 --> |
|
|
|
<WeChatQrCode |
|
|
|
ref="wecharQrCodeRef" |
|
|
|
:is-mini-program="true" |
|
|
|
@ -220,25 +219,124 @@ |
|
|
|
@ready="onWechatQrCodeReady" |
|
|
|
/> |
|
|
|
|
|
|
|
<!-- ==========新增:图书馆Logo上传板块========== --> |
|
|
|
<div class="config-item"> |
|
|
|
<div class="config-item-main"> |
|
|
|
<span class="data-title">图书馆Logo</span> |
|
|
|
<div class="upload-item logo-item"> |
|
|
|
<div v-if="libraryLogoUrl" class="logo-preview"> |
|
|
|
<img :src="libraryLogoUrl" alt="图书馆logo"> |
|
|
|
</div> |
|
|
|
<!-- <div v-else style="color:#999;font-size:12px;margin-bottom:8px;">暂未上传logo</div> --> |
|
|
|
<div class="upload-btn" style="margin-left: 0;"> |
|
|
|
<input |
|
|
|
id="logoUpFile" |
|
|
|
ref="logoFileInput" |
|
|
|
type="file" |
|
|
|
name="logoUpFile" |
|
|
|
accept="image/*" |
|
|
|
@change="changeLibraryLogo($event)" |
|
|
|
> |
|
|
|
<div |
|
|
|
class="upload-libImg" |
|
|
|
:class="{ 'is-disabled': logoUploadLoading }" |
|
|
|
@click="handleClickLogoUpload" |
|
|
|
> |
|
|
|
<i class="iconfont icon-shangchuan2" /> |
|
|
|
<span>{{ logoUploadLoading ? '上传中...' : '上传Logo' }}</span> |
|
|
|
</div> |
|
|
|
<!-- <span style="color:#909399;font-size:12px;margin-left:8px;">仅支持单张,最大5MB</span> --> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- banner图片板块 --> |
|
|
|
<div class="config-item"> |
|
|
|
<div class="config-item-main"> |
|
|
|
<span class="data-title">banner图片</span> |
|
|
|
<div class="upload-item"> |
|
|
|
<div class="book-swiper-wrapper"> |
|
|
|
<swiper |
|
|
|
ref="adImgSwiper" |
|
|
|
:options="swiperOptions" |
|
|
|
class="book-swiper" |
|
|
|
> |
|
|
|
<swiper-slide |
|
|
|
v-for="(imgItem, index) in advImgList" |
|
|
|
:key="imgItem.code" |
|
|
|
class="book-list-item" |
|
|
|
:class="{ 'book-list-item--selected': imgItem.selected }" |
|
|
|
> |
|
|
|
<div style="cursor: default; height: 130px !important;" @click.stop="toggleBookSelect(index)"> |
|
|
|
<img :src="imgItem.imgPath || require('@/assets/images/cover-bg.png')" alt="banner图"> |
|
|
|
<div v-if="imgItem.selected" class="select-style"> |
|
|
|
<div class="select-mask" /> |
|
|
|
<i class="iconfont icon-wancheng" /> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</swiper-slide> |
|
|
|
</swiper> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div style="margin-left: 20px;"> |
|
|
|
<div class="upload-btn" style="margin-left: 0; "> |
|
|
|
<input |
|
|
|
id="upFile" |
|
|
|
ref="fileInput" |
|
|
|
type="file" |
|
|
|
name="upFile" |
|
|
|
accept="image/*" |
|
|
|
@change="changeBannerImg($event)" |
|
|
|
> |
|
|
|
<el-button |
|
|
|
size="mini" |
|
|
|
type="primary" |
|
|
|
:disabled="advImgList.length >=5 || uploadLoading" |
|
|
|
> |
|
|
|
<i class="iconfont icon-shangchuan" />图片上传 |
|
|
|
</el-button> |
|
|
|
<span v-if="advImgList.length >=5" style="color:#f56c6c;font-size:12px;margin-left:8px;">已达最大5张上限</span> |
|
|
|
</div> |
|
|
|
<el-button |
|
|
|
:loading="deleteLoading" |
|
|
|
size="mini" |
|
|
|
:disabled="!hasSelectedItems" |
|
|
|
style="margin-top: 10px;" |
|
|
|
@click="batchDelete" |
|
|
|
> |
|
|
|
<i class="iconfont icon-shanchu" /> |
|
|
|
批量删除 |
|
|
|
</el-button> |
|
|
|
<div style="font-size: 12px; color: #9098a4;">最多可上传 5 张 (尺寸建议 750px*130px)</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
<script> |
|
|
|
import { FetchInitScreenSetting, FetchEditScreenSetting } from '@/api/digitalScreen/index' |
|
|
|
import { FetchInitScreenSetting, FetchEditScreenSetting, FetchDeleteScreenSetting } from '@/api/digitalScreen/index' |
|
|
|
import { mapGetters } from 'vuex' |
|
|
|
import WeChatQrCode from './module/wecharQrCode' |
|
|
|
import { upload } from '@/utils/upload' |
|
|
|
import { swiper, swiperSlide } from 'vue-awesome-swiper' |
|
|
|
import 'swiper/dist/css/swiper.css' |
|
|
|
|
|
|
|
export default { |
|
|
|
name: 'WeChatMiniProgram', |
|
|
|
components: { |
|
|
|
WeChatQrCode |
|
|
|
WeChatQrCode, |
|
|
|
swiper, |
|
|
|
swiperSlide |
|
|
|
}, |
|
|
|
data() { |
|
|
|
return { |
|
|
|
wecharQrCodeUrl: null, |
|
|
|
wechatQrRecordId: null, |
|
|
|
welcomePlay: null, |
|
|
|
openForm: { |
|
|
|
open_lib_http: null, |
|
|
|
open_lib_appId: null, |
|
|
|
@ -273,7 +371,26 @@ export default { |
|
|
|
openForm: {}, |
|
|
|
vxForm: {}, |
|
|
|
adminForm: {} |
|
|
|
} |
|
|
|
}, |
|
|
|
advImgList: [], |
|
|
|
swiperOptions: { |
|
|
|
slidesPerView: 'auto', |
|
|
|
freeMode: true, |
|
|
|
grabCursor: true, |
|
|
|
on: { |
|
|
|
resize: function() { |
|
|
|
this.update() |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
deleteLoading: false, |
|
|
|
uploadLoading: false, |
|
|
|
|
|
|
|
// ==========图书馆logo相关data========== |
|
|
|
libraryLogoId: null, |
|
|
|
libraryLogoUrl: null, |
|
|
|
logoUploadLoading: false, |
|
|
|
logoDeleteLoading: false |
|
|
|
} |
|
|
|
}, |
|
|
|
computed: { |
|
|
|
@ -287,6 +404,9 @@ export default { |
|
|
|
} else { |
|
|
|
return process.env.VUE_APP_WECHAT_URL |
|
|
|
} |
|
|
|
}, |
|
|
|
hasSelectedItems() { |
|
|
|
return this.advImgList.some(book => book.selected) |
|
|
|
} |
|
|
|
}, |
|
|
|
mounted() { |
|
|
|
@ -295,6 +415,11 @@ export default { |
|
|
|
methods: { |
|
|
|
initScreenSetting() { |
|
|
|
FetchInitScreenSetting({ 'libcode': this.user.fonds.fondsNo }).then(res => { |
|
|
|
this.advImgList = [] |
|
|
|
// logo重置 |
|
|
|
this.libraryLogoId = null |
|
|
|
this.libraryLogoUrl = null |
|
|
|
|
|
|
|
Object.values(res).forEach(item => { |
|
|
|
const { code, context, id } = item |
|
|
|
if (code === 'open_lib_http') { |
|
|
|
@ -318,15 +443,26 @@ export default { |
|
|
|
} |
|
|
|
if (code === 'wechat_qr_code') { |
|
|
|
this.wechatQrRecordId = id |
|
|
|
console.log('id', id) |
|
|
|
// context为后端存的相对文件路径 |
|
|
|
console.log('context', context) |
|
|
|
// this.wecharQrCodeUrl = context ? this.baseApi + '/files/' + context : null |
|
|
|
this.wecharQrCodeUrl = context ? this.imgHttpsUrl + '/files/' + context : null |
|
|
|
} |
|
|
|
// 图书馆logo回显 |
|
|
|
if (code === 'library_logo' && context) { |
|
|
|
this.libraryLogoId = id |
|
|
|
this.libraryLogoUrl = this.imgHttpsUrl + '/files/' + context |
|
|
|
} |
|
|
|
// 解析banner vx_banner1~vx_banner5 |
|
|
|
if (/^vx_banner[1-5]$/.test(code) && context) { |
|
|
|
this.advImgList.push({ |
|
|
|
id, |
|
|
|
code, |
|
|
|
imgPath: this.imgHttpsUrl + '/files/' + context, |
|
|
|
rawContext: context, |
|
|
|
selected: false |
|
|
|
}) |
|
|
|
} |
|
|
|
}) |
|
|
|
// 数据加载完后,通知子组件刷新图片 |
|
|
|
this.$nextTick(() => { |
|
|
|
this.updateSwiper() |
|
|
|
if (this.$refs.wecharQrCodeRef) { |
|
|
|
this.$refs.wecharQrCodeRef.reloadImage() |
|
|
|
} |
|
|
|
@ -336,7 +472,6 @@ export default { |
|
|
|
}) |
|
|
|
}, |
|
|
|
onWechatQrCodeReady() { |
|
|
|
// ready不再主动调用reloadImage,交给initScreenSetting数据回来之后nextTick执行 |
|
|
|
}, |
|
|
|
handleDblClick(formName, field) { |
|
|
|
this.originalValues[formName][field] = this[formName][field] |
|
|
|
@ -395,6 +530,160 @@ export default { |
|
|
|
} |
|
|
|
} |
|
|
|
return labels[formName][field] || field |
|
|
|
}, |
|
|
|
updateSwiper() { |
|
|
|
if (this.$refs.adImgSwiper && this.$refs.adImgSwiper.swiper) { |
|
|
|
const swiper = this.$refs.adImgSwiper.swiper |
|
|
|
swiper.update() |
|
|
|
swiper.slideReset() |
|
|
|
} |
|
|
|
}, |
|
|
|
toggleBookSelect(index) { |
|
|
|
this.advImgList[index].selected = !this.advImgList[index].selected |
|
|
|
}, |
|
|
|
async changeBannerImg(e) { |
|
|
|
const file = e.target.files[0] |
|
|
|
this.$refs.fileInput.value = '' |
|
|
|
if (!file) return |
|
|
|
|
|
|
|
// 校验最大5张 |
|
|
|
if (this.advImgList.length >= 5) { |
|
|
|
this.$message.warning('最多只能上传5张banner图片') |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
if (!file.type.startsWith('image/')) { |
|
|
|
this.$message({ message: '只可上传图片', type: 'error', offset: 8 }) |
|
|
|
return |
|
|
|
} |
|
|
|
const MAX_SIZE = 5 * 1024 * 1024 |
|
|
|
if (file.size > MAX_SIZE) { |
|
|
|
this.$message.error('图片不能超过5MB') |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
this.uploadLoading = true |
|
|
|
const res = await upload(this.baseApi + '/api/fileRelevant/uploadHttpsImg', file) |
|
|
|
if (res.data.code === 200) { |
|
|
|
const filePath = res.data.data |
|
|
|
await this.submitBannerCover(filePath) |
|
|
|
} else { |
|
|
|
this.$message.error('图片上传失败') |
|
|
|
} |
|
|
|
} catch (err) { |
|
|
|
console.error('上传异常:', err) |
|
|
|
this.$message.error('图片上传失败') |
|
|
|
} finally { |
|
|
|
this.uploadLoading = false |
|
|
|
} |
|
|
|
}, |
|
|
|
// 提交一张banner,自动找空位vx_banner1~vx_banner5 |
|
|
|
async submitBannerCover(imgUrl) { |
|
|
|
const libcode = this.user.fonds.fondsNo |
|
|
|
// 找出已经占用的code |
|
|
|
const usedCodes = this.advImgList.map(item => item.code) |
|
|
|
let targetCode = '' |
|
|
|
for (let i = 1; i <= 5; i++) { |
|
|
|
const c = `vx_banner${i}` |
|
|
|
if (!usedCodes.includes(c)) { |
|
|
|
targetCode = c |
|
|
|
break |
|
|
|
} |
|
|
|
} |
|
|
|
if (!targetCode) { |
|
|
|
this.$message.warning('banner图已满5张,无法继续上传') |
|
|
|
return |
|
|
|
} |
|
|
|
const param = { |
|
|
|
libcode, |
|
|
|
code: targetCode, |
|
|
|
context: imgUrl, |
|
|
|
remarks: null |
|
|
|
} |
|
|
|
await FetchEditScreenSetting(param) |
|
|
|
this.$message.success('banner图片保存成功') |
|
|
|
// 追加到列表 |
|
|
|
this.advImgList.push({ |
|
|
|
code: targetCode, |
|
|
|
imgPath: this.imgHttpsUrl + '/files/' + imgUrl, |
|
|
|
rawContext: imgUrl, |
|
|
|
selected: false |
|
|
|
}) |
|
|
|
this.$nextTick(() => { |
|
|
|
this.updateSwiper() |
|
|
|
}) |
|
|
|
}, |
|
|
|
// 批量删除:把选中项对应的code调用接口context置空,前端移除 |
|
|
|
async batchDelete() { |
|
|
|
const selectedItems = this.advImgList.filter(book => book.selected) |
|
|
|
const selectedCount = selectedItems.length |
|
|
|
if (selectedCount === 0) return |
|
|
|
this.deleteLoading = true |
|
|
|
try { |
|
|
|
await this.$confirm(`确定要删除选中的 ${selectedCount} 张宣传图片吗?`, '提示', { |
|
|
|
confirmButtonText: '确定', |
|
|
|
cancelButtonText: '取消', |
|
|
|
type: 'warning' |
|
|
|
}) |
|
|
|
console.log('selectedItems', selectedItems) |
|
|
|
for (const item of selectedItems) { |
|
|
|
console.log('item', item) |
|
|
|
await FetchDeleteScreenSetting({ id: item.id }) |
|
|
|
} |
|
|
|
this.$message.success('删除成功') |
|
|
|
await this.initScreenSetting() |
|
|
|
} catch (err) { |
|
|
|
// 取消弹窗会进入catch,不处理 |
|
|
|
} finally { |
|
|
|
this.deleteLoading = false |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
// ==========图书馆Logo上传方法========== |
|
|
|
handleClickLogoUpload() { |
|
|
|
if (this.logoUploadLoading) return |
|
|
|
this.$refs.logoFileInput.click() |
|
|
|
}, |
|
|
|
async changeLibraryLogo(e) { |
|
|
|
const file = e.target.files[0] |
|
|
|
this.$refs.logoFileInput.value = '' |
|
|
|
if (!file) return |
|
|
|
|
|
|
|
if (!file.type.startsWith('image/')) { |
|
|
|
this.$message.error('只可上传图片') |
|
|
|
return |
|
|
|
} |
|
|
|
const MAX_SIZE = 5 * 1024 * 1024 |
|
|
|
if (file.size > MAX_SIZE) { |
|
|
|
this.$message.error('图片不能超过5MB') |
|
|
|
return |
|
|
|
} |
|
|
|
try { |
|
|
|
this.logoUploadLoading = true |
|
|
|
const res = await upload(this.baseApi + '/api/fileRelevant/uploadHttpsImg', file) |
|
|
|
if (res.data.code === 200) { |
|
|
|
const imgUrl = res.data.data |
|
|
|
const libcode = this.user.fonds.fondsNo |
|
|
|
const param = { |
|
|
|
id: this.libraryLogoId, |
|
|
|
libcode, |
|
|
|
code: 'library_logo', |
|
|
|
context: imgUrl, |
|
|
|
remarks: null |
|
|
|
} |
|
|
|
await FetchEditScreenSetting(param) |
|
|
|
this.$message.success('logo上传成功') |
|
|
|
await this.initScreenSetting() |
|
|
|
} else { |
|
|
|
this.$message.error('logo上传失败') |
|
|
|
} |
|
|
|
} catch (err) { |
|
|
|
console.error('logo上传异常', err) |
|
|
|
this.$message.error('logo上传失败') |
|
|
|
} finally { |
|
|
|
this.logoUploadLoading = false |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -402,9 +691,36 @@ export default { |
|
|
|
|
|
|
|
<style scoped lang="scss"> |
|
|
|
@import "~@/assets/styles/digitalScreen.scss"; |
|
|
|
.area-config .config-item-main .data-title{ |
|
|
|
width: 100px !important; |
|
|
|
} |
|
|
|
.content-area { |
|
|
|
height: 734px; |
|
|
|
// height: 734px; |
|
|
|
border-radius: 4px; |
|
|
|
width: 100%; |
|
|
|
} |
|
|
|
.logo-preview{ |
|
|
|
width: 120px; |
|
|
|
height: 120px; |
|
|
|
border-radius: 50%; |
|
|
|
overflow: hidden; |
|
|
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.4); |
|
|
|
margin-right: 15px; |
|
|
|
img{ |
|
|
|
display: block; |
|
|
|
width: 100%; |
|
|
|
height: 100%; |
|
|
|
object-fit: cover; |
|
|
|
border-radius: 50%; |
|
|
|
} |
|
|
|
} |
|
|
|
.book-swiper-wrapper { |
|
|
|
max-width: 1000px !important; |
|
|
|
} |
|
|
|
|
|
|
|
.book-list-item{ |
|
|
|
width: 300px !important; |
|
|
|
height: 130px !important; |
|
|
|
margin: 0 10px !important; |
|
|
|
} |
|
|
|
</style> |