|
|
<template>
|
|
|
<div class="body" id="signed">
|
|
|
<u-image class="bkg" width="100vw" height="100%" :src="require('@/static/certificate-bkg.png')"></u-image>
|
|
|
<u-image class="city" mode="widthFix" width="100vw" :src="require('@/static/city.png')"></u-image>
|
|
|
<u-image class="people" mode="widthFix" :width="278" :src="require('@/static/people.png')"></u-image>
|
|
|
<u-image mode="widthFix" width="100vw" class="piaodai" :src="require('@/static/piaodai.png')"></u-image>
|
|
|
<u-image id="share-img" v-show="!isHidden" class="share-img" mode="scaleToFill" :width="99" :height="99" :src="require('@/static/share.png')" @click="$u.throttle(share)"> mode=</u-image>
|
|
|
<div class="content">
|
|
|
<u-image style="display:flex;align-items: center;margin: auto;" mode="widthFix" :width="335" :src="require('@/static/certificate-word.png')"></u-image>
|
|
|
|
|
|
<div class="container">
|
|
|
<u-image class="container__jiangbei" :height="206" mode="heightFix" :src="require('@/static/jiangbei.png')"></u-image>
|
|
|
<u-image class="container__bkg" height="100%" width="100%" mode="scaleToFill" :src="require('@/static/container-bkg.png')"></u-image>
|
|
|
|
|
|
<div class="container__text">
|
|
|
<div class="container__text--title">
|
|
|
<u-image :width="100" :src="signInfo.upload ? signInfo.upload.url : ''" mode="heightFix" :height="56"></u-image>同学,
|
|
|
</div>
|
|
|
<div class="container__text--total">
|
|
|
你已完成2023年“我是党史记录人——红色少年行”未成年人研学线上打卡。
|
|
|
</div>
|
|
|
<div class="container__text--total">
|
|
|
学党史悟精神聚力量,你是第<span>{{ vuex_user.address || 0 }}</span>位完成者,快邀请你的同学一起完成线上打卡吧!
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<u-image class="qrcode" :src="require('@/static/qrcode.png')" width="220" height="220" border-radius="10"></u-image>
|
|
|
</div>
|
|
|
|
|
|
<div class="footer">
|
|
|
主办单位:中共苏州市委党史工作办公室 <br>
|
|
|
承办单位:江苏有线苏州分公司
|
|
|
</div>
|
|
|
|
|
|
<transition name="share-pop" enter-active-class="fade-in" leave-to-class="fade-out">
|
|
|
<view class="share_cover" v-show="isShare" @click="isShare = false">
|
|
|
<image src="/static/toShare.png" class="share_cover_arrow"></image>
|
|
|
<view class="share_cover_word">
|
|
|
请点击右上角将它发送给指定朋友或分享到朋友圈
|
|
|
</view>
|
|
|
</view>
|
|
|
</transition>
|
|
|
|
|
|
<view class="share" v-if="isHidden">
|
|
|
<view class="share-mask" @click="isHidden = false">
|
|
|
</view>
|
|
|
|
|
|
<view class="share-page">
|
|
|
<image :src="imgData" mode="widthFix"></image>
|
|
|
|
|
|
<view class="share-page__btn">
|
|
|
<view class="share-page__btn--share" @click="isShare = true">分享</view>
|
|
|
<view class="share-page__btn--save" @click="$u.throttle(save)">保存</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<!-- <u-modal v-model="isShowModal" title="您的名字是?" @confirm="saveName">-->
|
|
|
<!-- <view class="slot-content" style="padding: 10rpx 20rpx;">-->
|
|
|
<!-- <u-input v-model="name"></u-input>-->
|
|
|
<!-- </view>-->
|
|
|
<!-- </u-modal>-->
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import {
|
|
|
ROOTPATH
|
|
|
} from '@/common/config.js'
|
|
|
import {base64ToFile} from '@/common/util'
|
|
|
import html2canvas from '@/lib/html2canvas.min.js'
|
|
|
export default {
|
|
|
data() {
|
|
|
return {
|
|
|
signInfo: '',
|
|
|
isShare: false,
|
|
|
isHidden: false,
|
|
|
imgData: '',
|
|
|
//isShowModal: false,
|
|
|
|
|
|
name: '',
|
|
|
};
|
|
|
},
|
|
|
methods: {
|
|
|
saveName () {
|
|
|
|
|
|
this.$u.api.saveUser(Object.assign(this.vuex_user, {
|
|
|
name: this.name
|
|
|
}))
|
|
|
},
|
|
|
|
|
|
async getPoster () {
|
|
|
const res = await this.$u.api.getPoster({
|
|
|
user_id: this.vuex_user.id,
|
|
|
type: 2
|
|
|
})
|
|
|
this.signInfo = res
|
|
|
console.log(1123,res)
|
|
|
},
|
|
|
|
|
|
share() {
|
|
|
this.isHidden = true
|
|
|
|
|
|
uni.showLoading({
|
|
|
title: '图片生成中..'
|
|
|
})
|
|
|
|
|
|
let dom = document.querySelector('#signed')
|
|
|
html2canvas(dom, {
|
|
|
width: dom.clientWidth, //dom 原始宽度
|
|
|
height: dom.clientHeight,
|
|
|
scrollY: 0,
|
|
|
scrollX: 0,
|
|
|
useCORS: true,
|
|
|
ignoreElements:(element) => {
|
|
|
return element.id == 'share-img'
|
|
|
}
|
|
|
}).then(cnv => {
|
|
|
uni.hideLoading()
|
|
|
|
|
|
this.imgData = cnv.toDataURL('image/png', 1)
|
|
|
}).catch(err => {
|
|
|
uni.showToast({
|
|
|
title: '生成失败,请重试',
|
|
|
icon: 'error'
|
|
|
})
|
|
|
this.isHidden = false
|
|
|
console.log(err);
|
|
|
})
|
|
|
},
|
|
|
save() {
|
|
|
uni.showToast({
|
|
|
title: "请长按分享图片进行保存或者分享",
|
|
|
icon: "none"
|
|
|
})
|
|
|
|
|
|
|
|
|
let form = new FormData()
|
|
|
form.append('file', base64ToFile(this.imgData, 'sign'))
|
|
|
form.append('active_tag', 'map_point')
|
|
|
let vuex_token = this.vuex_token;
|
|
|
form.append('token', vuex_token)
|
|
|
let xhr = new XMLHttpRequest()
|
|
|
xhr.open('post', `${ROOTPATH}/api/mobile/upload-file`)
|
|
|
|
|
|
xhr.onreadystatechange = () => {
|
|
|
if (xhr.status === 200 && xhr.readyState === 4) {
|
|
|
let val = JSON.parse(xhr.responseText);
|
|
|
console.log(val);
|
|
|
this.$u.api.savePoster({
|
|
|
upload_id: val.id,
|
|
|
type: 1
|
|
|
}).then(res => {
|
|
|
// uni.showToast({
|
|
|
// title: "保存成功",
|
|
|
// icon: "none"
|
|
|
// })
|
|
|
}).catch(err => {
|
|
|
// uni.showToast({
|
|
|
// title: "保存成功",
|
|
|
// icon: "none"
|
|
|
// })
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
xhr.send(form)
|
|
|
}
|
|
|
},
|
|
|
async onShow() {
|
|
|
await this.getPoster()
|
|
|
if (!this.signInfo?.upload) {
|
|
|
uni.navigateTo({
|
|
|
url: '/pages/sign/sign'
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss">
|
|
|
.body {
|
|
|
overflow: hidden;
|
|
|
min-height: 100vh;
|
|
|
|
|
|
position: relative;
|
|
|
}
|
|
|
.footer {
|
|
|
text-align: center;
|
|
|
font-size: 18rpx;
|
|
|
font-weight: 400;
|
|
|
color: #F8DB97;
|
|
|
|
|
|
padding: 20rpx 0;
|
|
|
position: absolute;
|
|
|
bottom: 0;
|
|
|
left: 0;
|
|
|
right: 0;
|
|
|
}
|
|
|
/* ----------------------------------------------
|
|
|
* Generated by Animista on 2023-6-26 17:51:36
|
|
|
* Licensed under FreeBSD License.
|
|
|
* See http://animista.net/license for more info.
|
|
|
* w: http://animista.net, t: @cssanimista
|
|
|
* ---------------------------------------------- */
|
|
|
|
|
|
/**
|
|
|
* ----------------------------------------
|
|
|
* animation jello-horizontal
|
|
|
* ----------------------------------------
|
|
|
*/
|
|
|
@keyframes jello-horizontal {
|
|
|
0% {
|
|
|
transform: scale3d(1, 1, 1);
|
|
|
}
|
|
|
15% {
|
|
|
transform: scale3d(1.25, 0.75, 1);
|
|
|
}
|
|
|
20% {
|
|
|
transform: scale3d(0.75, 1.25, 1);
|
|
|
}
|
|
|
25% {
|
|
|
transform: scale3d(1.15, 0.85, 1);
|
|
|
}
|
|
|
33% {
|
|
|
transform: scale3d(0.95, 1.05, 1);
|
|
|
}
|
|
|
38% {
|
|
|
transform: scale3d(1.05, 0.95, 1);
|
|
|
}
|
|
|
50% {
|
|
|
transform: scale3d(1, 1, 1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.share-img {
|
|
|
animation: jello-horizontal 3.2s both infinite;
|
|
|
|
|
|
z-index: 99999;
|
|
|
position: fixed;
|
|
|
left: 55rpx;
|
|
|
bottom: 86rpx;
|
|
|
}
|
|
|
.people {
|
|
|
|
|
|
position: absolute;
|
|
|
right: 23rpx;
|
|
|
bottom: -120rpx;
|
|
|
}
|
|
|
.city {
|
|
|
|
|
|
position: absolute;
|
|
|
left: 0;
|
|
|
right: 0;
|
|
|
bottom: 154rpx;
|
|
|
}
|
|
|
.piaodai {
|
|
|
|
|
|
position: absolute;
|
|
|
left: 0;
|
|
|
right: 0;
|
|
|
bottom: -22rpx;
|
|
|
}
|
|
|
.bkg {
|
|
|
|
|
|
position: absolute;
|
|
|
top: 0;
|
|
|
left: 0;
|
|
|
right: 0;
|
|
|
bottom: 0;
|
|
|
}
|
|
|
|
|
|
.content {
|
|
|
|
|
|
padding-top: 143rpx;
|
|
|
position: relative;
|
|
|
|
|
|
.container {
|
|
|
|
|
|
z-index: 2;
|
|
|
margin-top: 23rpx;
|
|
|
position: relative;
|
|
|
&__jiangbei {
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
|
|
|
z-index: 3;
|
|
|
position: relative;
|
|
|
}
|
|
|
&__bkg {
|
|
|
|
|
|
z-index: 1;
|
|
|
position: absolute;
|
|
|
top: 103rpx;
|
|
|
bottom: 0;
|
|
|
left: 0;
|
|
|
right: 0;
|
|
|
}
|
|
|
|
|
|
|
|
|
&__text {
|
|
|
|
|
|
z-index: 4;
|
|
|
padding: 61rpx 63rpx 0 104rpx;
|
|
|
position: relative;
|
|
|
&--title {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
font-weight: 400;
|
|
|
color: #6F6F6F;
|
|
|
font-size: 28rpx;
|
|
|
line-height: 56rpx;
|
|
|
|
|
|
& > span {
|
|
|
color: #FD4949;
|
|
|
line-height: 56rpx;
|
|
|
text-decoration-color: #6F6F6F;
|
|
|
text-decoration: underline;
|
|
|
|
|
|
padding: 0 8rpx;
|
|
|
}
|
|
|
}
|
|
|
&--total {
|
|
|
text-indent: 56rpx;
|
|
|
font-weight: 400;
|
|
|
color: #6F6F6F;
|
|
|
font-size: 28rpx;
|
|
|
line-height: 56rpx;
|
|
|
|
|
|
& > span {
|
|
|
color: #FD4949;
|
|
|
line-height: 56rpx;
|
|
|
text-decoration-color: #6F6F6F;
|
|
|
text-decoration: underline;
|
|
|
|
|
|
padding: 0 4rpx;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.qrcode {
|
|
|
|
|
|
margin: 150rpx auto;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.share_cover {
|
|
|
background: rgba(0, 0, 0, 0.8);
|
|
|
position: fixed;
|
|
|
top: 0;
|
|
|
left: 0;
|
|
|
right: 0;
|
|
|
bottom: 0;
|
|
|
height: 100vh;
|
|
|
width: 100vw;
|
|
|
z-index: 100000;
|
|
|
|
|
|
.share_cover_word {
|
|
|
color: #FFFFFF;
|
|
|
font-size: 48rpx;
|
|
|
width: 60%;
|
|
|
margin: 400rpx auto;
|
|
|
text-align: center;
|
|
|
line-height: 40px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.share_cover_arrow {
|
|
|
position: absolute;
|
|
|
right: 0;
|
|
|
top: 0;
|
|
|
width: 300rpx;
|
|
|
height: 400rpx;
|
|
|
}
|
|
|
}
|
|
|
.share {
|
|
|
min-height: 100vh;
|
|
|
overflow-y: scroll;
|
|
|
|
|
|
padding: 278rpx 0;
|
|
|
z-index: 2;
|
|
|
position: fixed;
|
|
|
top: 0;
|
|
|
left: 0;
|
|
|
right: 0;
|
|
|
|
|
|
&-mask {
|
|
|
background: rgba(0, 0, 0, 0.4);
|
|
|
|
|
|
position: fixed;
|
|
|
top: 0;
|
|
|
left: 0;
|
|
|
right: 0;
|
|
|
bottom: 0;
|
|
|
}
|
|
|
|
|
|
&-page {
|
|
|
width: fit-content;
|
|
|
overflow: scroll;
|
|
|
|
|
|
transform: translate(-50%, -50%);
|
|
|
position: absolute;
|
|
|
top: 50%;
|
|
|
left: 50%;
|
|
|
right: 0;
|
|
|
|
|
|
&>image {
|
|
|
width: 520rpx;
|
|
|
height: auto;
|
|
|
display: block;
|
|
|
border: 6rpx solid #F8E3CF;
|
|
|
box-shadow: 0rpx 4rpx 20rpx 0rpx rgba(19, 1, 2, 0.71);
|
|
|
|
|
|
margin: auto;
|
|
|
}
|
|
|
|
|
|
&__btn {
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
|
|
|
padding-top: 52rpx;
|
|
|
|
|
|
&>view {
|
|
|
width: 230rpx;
|
|
|
height: 66rpx;
|
|
|
background: linear-gradient(0deg, #EFC495, #E9BC8A);
|
|
|
border-radius: 34rpx;
|
|
|
text-align: center;
|
|
|
font-weight: 400;
|
|
|
line-height: 66rpx;
|
|
|
font-size: 26rpx;
|
|
|
letter-spacing: 8rpx;
|
|
|
color: #C93E31;
|
|
|
}
|
|
|
|
|
|
&--share {
|
|
|
|
|
|
margin-right: 60rpx;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
.fade-in {
|
|
|
animation: fade-in 1s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
|
|
|
}
|
|
|
|
|
|
@keyframes fade-in {
|
|
|
0% {
|
|
|
opacity: 0;
|
|
|
}
|
|
|
|
|
|
100% {
|
|
|
opacity: 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.fade-out {
|
|
|
animation: fade-out .8s ease-out both;
|
|
|
}
|
|
|
|
|
|
@keyframes fade-out {
|
|
|
0% {
|
|
|
opacity: 1;
|
|
|
}
|
|
|
|
|
|
100% {
|
|
|
opacity: 0;
|
|
|
}
|
|
|
}
|
|
|
</style>
|