You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

472 lines
10 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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>