themblem/web/src/components/mini-program-preview.vue
2025-08-17 12:24:08 +01:00

160 lines
3.6 KiB
Vue

<template>
<div class="preview" :style="background_style">
<div class="top">
<div class="carousel section" @click="click_section('carousel')">
<Carousel :items="data.carousel" />
</div>
<div class="video section" @click="click_section('video')">
<video v-if="data.video" :src="data.video.url" controls></video>
</div>
</div>
<div class="middle">
<div class="row icon_links section" @click="click_section('icons')">
<div v-for="x, i in data.icons" :key="i" class="item" :class="{ 'col-3': data.icons_per_line == 4, 'col-4': data.icons_per_line == 3}">
<div>
<img :src="x.url" alt=""/>
</div>
<div>
{{ x.title }}
</div>
</div>
</div>
<button class="scan section" @click="click_section('scan_button')" :style="scan_button_style">{{ scan_button_text }}</button>
</div>
<div class="bottom">
<div class="static section" @click="click_section('static')">
<img v-for="x, i in data.static" :key="i" :src="x.url">
</div>
</div>
</div>
</template>
<script>
import Carousel from './carousel';
export default {
name: 'MiniProgramPreview',
props: ['data'],
components: {
Carousel,
},
data: function () {
return {
};
},
computed: {
background_style: function() {
var ret = {};
var data = this.data;
if (!data) {
return { };
}
if (data.background_type == 'color') {
ret.backgroundColor = data.background_color;
} else if (data.background_type == 'gradient') {
ret.backgroundImage = 'linear-gradient(' + data.background_gradiant_begin + ', ' + data.background_gradiant_end + ')';
} else if (data.background_type == 'image') {
ret.backgroundImage = 'url(' + data.background_image + ')';
ret.backgroundRepeat = 'no-repeat';
ret.backgroundSize = 'cover';
}
return ret;
},
scan_button_text: function() {
return this.data && this.data.scan_button ? this.data.scan_button.text : '开始扫码';
},
scan_button_style: function() {
var ret = {};
if (this.data && this.data.scan_button) {
if (this.data.scan_button.color) {
ret.backgroundColor = this.data.scan_button.color;
}
if (this.data.scan_button.text_color) {
ret.color = this.data.scan_button.text_color;
}
}
return ret;
},
},
methods: {
click_section: function (section) {
this.$emit('click_section', section);
},
},
mounted() {
},
}
</script>
<style scoped>
div.container {
width: 100%;
}
div.preview {
margin: 1rem auto;
width: 500px;
min-height: 1000px;
border: 1px solid #888;
}
div.top {
min-height: 350px;
}
div.top, div.bottom, div.middle {
margin: 1rem;
}
div.carousel {
height: 120px;
}
div.video {
margin: 1rem auto;
height: 200px;
}
video {
height: 100%;
width: 100%;
}
div.icon_links {
text-align: center;
}
div.icon_links .item{
margin: 0.5rem 0;
}
div.icon_links img {
width: 64px;
height: 64px;
}
div.icon_links a {
text-decoration: none;
color: #444;
}
button.scan {
border: 1px solid white;
background-color: green;
color: white;
font-size: 1.5rem;
padding: 1rem 5rem;
border-radius: 8px;
margin: 1rem auto;
display: block;
}
div.static {
margin: 1rem auto;
width: 100%;
min-height: 120px
}
.static img {
width: 100%;
margin: 5px 0;
}
div.section {
cursor: pointer;
border: 1px solid rgba(200, 200, 200, 0.5);
}
div.section:hover {
border: 1px solid blue;
}
div.one-icon {
max-width: 400px;
}
</style>