Browse Source

网页模板更新页面及交互

pull/95/head
zq 1 month ago
parent
commit
0bcb670e44
  1. 1
      src/router/index.js
  2. 29
      src/utils/icoConverter.js
  3. 399
      src/views/agent/siteTemplate.vue

1
src/router/index.js

@ -19,6 +19,7 @@ const blackHeaderList = [
];
const blackFooterList = [
'/', '/franchise', '/register', '/agent/siteAdd', '/agent/payInfoSetting','/agent/siteServiceEdit','/agent/siteAddFinally','/agent/siteServiceAdd',
'/agent/siteTemplate'
];
// const whiteSlideList = ['/', '/ui',
// '/agent/siteList',

29
src/utils/icoConverter.js

@ -0,0 +1,29 @@
export async function convertIcoToPng(file) {
// 1. 创建ICO的Blob URL
const icoUrl = URL.createObjectURL(file)
// 2. 加载到Image对象
const img = await new Promise((resolve, reject) => {
const img = new Image()
img.onload = () => resolve(img)
img.onerror = reject
img.src = icoUrl
})
// 3. 绘制到Canvas
const canvas = document.createElement('canvas')
canvas.width = img.width
canvas.height = img.height
const ctx = canvas.getContext('2d')
ctx.drawImage(img, 0, 0)
// 4. 转换为PNG
const pngDataUrl = canvas.toDataURL('image/png')
URL.revokeObjectURL(icoUrl) // 释放内存
return {
dataUrl: pngDataUrl,
width: img.width,
height: img.height
}
}

399
src/views/agent/siteTemplate.vue

@ -1,102 +1,440 @@
<template>
<div class="main-content12">
<div class="main-content12 siteTem-wrap">
<div class="content">
<div class="pageTemplete-wrap">
<div class=" flex-common" id="">
<h3>模板选择</h3>
<div class="templeteImgs flex">
<div class="templeteImgs-item column" v-for="item in templeteList" :key="item.tpl_id" @click="chooseTemplate(item)">
<img :src="item.picture" alt="" class="tem_img">
<span class="look">预览</span>
<!-- v-if="tpl_id== item.tpl_id" -->
<img src="@/assets/site/tem-active.svg" class="tem-active" v-if="tpl_id== item.tpl_id" alt="">
<div class="templeteImgs flex" v-if="templeteList.length">
<div class="templeteImgs-item column" v-for="(item, index) in templeteList" :key="item.tpl_id"
@click="chooseTemplate(item)">
<div class="outImg_tem">
<img :src="item.picture" alt="" preview class="tem_img">
</div>
<span class="look" @click.stop="previewImg(item, index)">预览</span>
<img src="@/assets/site/tem-active.svg" class="tem-active" v-if="tpl_id == item.id" alt="">
<p>{{ item.name }}</p>
</div>
</div>
</div>
<div class="flex-common flex-between mt12">
<div class="uploadLeft">
<div class="uploadwrap">
<label class="flex upload-title">站点ICO<img class="ml-4"
src="@/assets/form_qua_ic.svg" /></label>
<!-- <el-upload class="upload-demo" :on-change="handleAvatarChange" action="#" :multiple="false"
:limit="Number(1)" ref="avatorUpload" :auto-upload="false" accept=".ico">
<GuipButton class="upload-button" slot="trigger" type="ignore"
:btnstyle="{ width: '118px' }">
<i class="bgImg"></i>选择文件
</GuipButton>
<div slot="tip" class="el-upload__tip">浏览器标题前面的图片必须是ico格式尺寸32PX*32PX</div>
</el-upload> -->
<input type="file" accept=".ico" @change="handleAvatarChange" ref="fileInput"
style="display: none">
<GuipButton class="upload-button mt12" slot="trigger" type="ignore"
:btnstyle="{ width: '118px' }" @click="$refs.fileInput.click()">
<i class="bgImg"></i>选择文件
</GuipButton>
<p class="desc mt12">浏览器标题前面的图片必须是ico格式尺寸32PX</p>
</div>
<div class="uploadwrap mt24">
<label class="flex upload-title">站点首页Logo<img class="ml-4"
src="@/assets/form_qua_ic.svg" /></label>
<el-upload class="upload-demo" :on-change="handleAvatarChange1" action="#" :multiple="false"
:limit="Number(1)" ref="avatorUpload" :auto-upload="false">
<GuipButton class="upload-button" slot="trigger" type="ignore"
:btnstyle="{ width: '118px' }">
<i class="bgImg"></i>选择文件
</GuipButton>
<div slot="tip" class="el-upload__tip">站点左上角logo样式高度建议不超过60PX文件仅支持PNG格式</div>
</el-upload>
</div>
</div>
<div class="previewRight">
<h4>实时预览</h4>
<img :src="logoUrl" alt="" class="logo">
<img :src="icoUrl" alt="" class="ico">
<div class="img-preview" v-if="pictureUrl">
<img :src="pictureUrl" alt="" class="preview-img">
<img :src="previewLogo" v-if="previewLogo" alt="Logo预览" class="preview-logo">
<img :src="previewIco" v-if="previewIco" alt="ico预览" class="preview-ico">
</div>
</div>
</div>
</div>
<Footer></Footer>
<div v-if="previewVisible" class="preview-modal" @click="previewVisible = false">
<img :src="currentImage" class="preview-image">
</div>
</div>
<div class="register-btns center">
<GuipButton type="ignore" :btnstyle="{ width: '144px', height: '46px' }" @click="jumpCancle">取消
</GuipButton>
<GuipButton type="primary" :btnstyle="{ width: '144px', height: '46px' }" @click="update_site_tpl">保存
</GuipButton>
</div>
</div>
</template>
<script>
import GuipButton from '@/components/GuipButton.vue'
import Footer from '@/components/Footer.vue'
// import Viewer from 'v-viewer'
// import Vue from 'vue'
// import LightBox from 'vue-image-lightbox'
// import 'vue-image-lightbox/dist/vue-image-lightbox.min.css'
// import VueEasyLightbox from 'vue-easy-lightbox'
import { convertIcoToPng } from '@/utils/icoConverter'
export default {
//
name: '',
components: {
// GuipInput,
// GuipButton,
GuipButton,
Footer
// VueEasyLightbox
// LightBox
// GuipSwitch,
// GroupFormBtns
},
data() {
return {
activeName: '1',
tpl_id:'',
tpl_id: '',
logoUrl: '',
previewLogo: '',
previewIco: '',
icoUrl: '',
// media: [],
pictureUrl: '',
addImgList: {
'万方': require('@/assets/register/wanfang.png'),
'维普': require('@/assets/register/weipu.svg'),
'学术不端': require('@/assets/register/xueshubuduan.svg'),
},
templeteList:[]
templeteList: [],
formData: new FormData(),
showLightbox: false,
imageIndex: 0,
previewVisible: false,
}
},
mounted() {
this.get_site_tpl_list();
},
computed: {
// lightbox
media() {
return this.templeteList.map(item => ({
src: item.picture,
type: this.getImageType(item.picture),
thumb: item.thumbnail,
caption: item.name //
}))
}
},
methods: {
//
get_site_tpl_list(){
this.$http('POST', '/agentnew/ajax_get_site_tpl_list',{
uid:this.$route.query?.uid,
get_site_tpl_list() {
this.$http('POST', '/agentnew/ajax_get_site_tpl_list', {
uid: this.$route.query?.uid,
}, {
headers: {
'Auth': this.$token
}
}).then(response => {
this.$nextTick(() => {
if(response.data.length >0){
this.templeteList = [...response.data]
this.pictureUrl = response.data[0].picture;
this.tpl_id = response.data[0].id;
}
})
}).catch(error => {
console.error(error, 'error')
})
},
handleClick() {
// URL
getImageType(url) {
const ext = url.split('.').pop().toLowerCase()
switch (ext) {
case 'png': return 'image/png'
case 'jpg':
case 'jpeg': return 'image/jpeg'
case 'gif': return 'image/gif'
default: return 'image/jpeg' //
}
},
jumpCancle(){
console.log('object');
this.$router.go(-1)
},
update_site_tpl() {
this.formData.set('uid', this.$route.query.uid)
this.formData.set('tpl_id', this.tpl_id)
this.formData.set('is_public_tpl', 1)
this.$http('POST', '/agentnew/ajax_update_site_tpl',
this.formData
, {
headers: {
'Auth': this.$token
}
}).then(response => {
if(response.status){
this.$Message.success(response.info)
this.$router.go(-1)
}
}).catch(error => {
console.error(error, 'error')
})
},
chooseTemplate(item){
chooseTemplate(item) {
console.log('---11');
this.tpl_id = item.id;
this.pictureUrl = item.picture
},
previewImg(item, index) {
console.log('222---11');
this.imageIndex = index
this.currentImage = item.picture
this.previewVisible = true
},
hide() {
this.previewVisible = false
},
handleAvatarChange1(file, fileList) {
console.log(file, fileList, 'pictureUrl====')
//
if (file.raw.type !== 'image/png') {
this.$message.error('只能上传PNG格式的图片!')
return false
}
//
if (file.raw.type !== 'image/png') {
this.$message.error('只能上传PNG格式的图片!')
return false
}
let fileObj = file.raw
this.formData.set('logo', fileObj);
const reader = new FileReader()
reader.onload = (e) => {
this.previewLogo = e.target.result
}
reader.readAsDataURL(file.raw)
},
async handleAvatarChange(event) {
const file = event.target.files[0]
// console.log(file,'file==');
if (!file) return
this.formData.set('ico', file);
try {
let previewImages = [await convertIcoToPng(file)]
this.previewIco = previewImages[0].dataUrl
} catch (err) {
console.error('转换失败:', err)
alert('ICO文件解析失败')
}
}
}
}
</script>
<style scoped lang="scss">
.siteTem-wrap{
padding: 12px 12px 0;
height: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
.content{
flex: 1;
}
}
.register-btns {
// position: absolute;
// left: 0;
// bottom: 0;
width: 100%;
height: 78px;
box-sizing: border-box;
display: flex;
flex-direction: row;
justify-content: center;
background: #FFFFFF;
padding: 16px 0px;
/* 蓝色阴影_常规 */
box-shadow: 0px 4px 16px 0px rgba(17, 55, 143, 0.12);
z-index: 999;
button:nth-child(1) {
margin-right: 56px;
}
}
.pageTemplete-wrap {
width: 100%;
letter-spacing: 0.08em;
box-sizing: border-box;
}
.uploadLeft {
width: 43%;
}
.thumbnail {
width: 100px;
height: 100px;
cursor: pointer;
margin: 5px;
}
.preview-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.8);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.preview-image {
max-width: 80%;
max-height: 80%;
}
.previewRight {
width: 55%;
border-radius: 4px;
background: #FAFAFA;
padding: 24px 22px;
gap: 20px;
height: 297px;
display: flex;
flex-direction: column;
box-sizing: border-box;
overflow: hidden;
position: relative;
h4 {
margin: 0;
height: 18px;
text-align: left;
}
.preview-img{
width: 1400px;
}
.img-preview {
flex: 1;
overflow: hidden;
position: relative;
.preview-logo {
position: absolute;
top: 5px;
height: 50px;
left: 20px;
}
.preview-ico {
position: absolute;
top: 5px;
height: 32px;
width: 32px;
left: 200px;
}
}
.logo {
position: absolute;
}
.ico {
position: absolute;
}
}
.outImg_tem {
height: 110px;
overflow: hidden;
border-radius: 8px;
border: 2px solid #E8E9EA;
}
::v-deep .el-tabs__nav-wrap {
border-width: 0px 0px 1px 0px;
border-style: solid;
border-color: #DFE2E6;
}
.templeteImgs{
.uploadwrap {
text-align: left;
lable {
font-size: 14px;
font-weight: normal;
line-height: normal;
letter-spacing: 0.08em;
color: #1E2226;
}
.upload-demo {
margin-top: 12px;
}
.upload-button {
border-radius: 4px;
background: #F2F3F5;
box-sizing: border-box;
border: 1px solid #BABDC2;
.bgImg {
width: 20px;
height: 16px;
margin-right: 6px;
background-image: url(@/assets/site/uploadIcon.svg);
}
&:hover {
.bgImg {
background-image: url(@/assets/site/uploadIcon_light.svg);
}
}
}
.upload-title {
font-size: 14px;
font-weight: normal;
line-height: normal;
letter-spacing: 0.08em;
color: #23242B;
}
}
.templeteImgs {
max-width: 100%;
justify-content: flex-start;
white-space: nowrap;
overflow-x: auto;
gap: 13px;
.templeteImgs-item {
position: relative;
border-radius: 4px;
cursor: pointer;
.tem_img{
.tem_img {
width: 176px;
height: 110px;
border-radius: 8px;
border: 2px solid #E8E9EA;
border-radius: 6px;
}
p{
p {
display: inline-block;
width: 100%;
text-align: center;
@ -104,18 +442,20 @@ export default {
letter-spacing: 0.08em;
color: #626573;
}
.tem-active{
.tem-active {
position: absolute;
right: 0;
top: 0;
top: 2px;
width: 30px;
height: 30px;
}
.look{
.look {
// display: none;
transition: all .3s;
position: absolute;
right: 0;
right: 2px;
bottom: 26px;
width: 73px;
height: 30px;
@ -125,10 +465,11 @@ export default {
line-height: 30px;
color: #fff;
text-align: center;
border-radius: 0 0 4px 0;
border-radius: 0 0 6px 0;
}
&:hover{
.look{
&:hover {
.look {
display: block;
transition: all .3s;
}

Loading…
Cancel
Save