个人中心,证书界面

master
xy 2 years ago
parent 304cb2a796
commit b038f4240f

@ -1,13 +1,111 @@
{ {
"name": "xietang-answer-h5", "name": "xietang-answer-h5",
"version": "1.0.0", "version": "1.0.0",
"lockfileVersion": 1, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": {
"": {
"name": "xietang-answer-h5",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"html2canvas": "^1.4.1",
"jweixin-module": "^1.6.0"
}
},
"node_modules/base64-arraybuffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/css-line-break": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
"dependencies": {
"utrie": "^1.0.2"
}
},
"node_modules/html2canvas": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
"dependencies": {
"css-line-break": "^2.1.0",
"text-segmentation": "^1.0.3"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/jweixin-module": {
"version": "1.6.0",
"resolved": "https://registry.npmmirror.com/jweixin-module/-/jweixin-module-1.6.0.tgz",
"integrity": "sha512-dGk9cf+ipipHmtzYmKZs5B2toX+p4hLyllGLF6xuC8t+B05oYxd8fYoaRz0T30U2n3RUv8a4iwvjhA+OcYz52w=="
},
"node_modules/text-segmentation": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
"dependencies": {
"utrie": "^1.0.2"
}
},
"node_modules/utrie": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
"dependencies": {
"base64-arraybuffer": "^1.0.2"
}
}
},
"dependencies": { "dependencies": {
"base64-arraybuffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ=="
},
"css-line-break": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
"requires": {
"utrie": "^1.0.2"
}
},
"html2canvas": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
"requires": {
"css-line-break": "^2.1.0",
"text-segmentation": "^1.0.3"
}
},
"jweixin-module": { "jweixin-module": {
"version": "1.6.0", "version": "1.6.0",
"resolved": "https://registry.npmmirror.com/jweixin-module/-/jweixin-module-1.6.0.tgz", "resolved": "https://registry.npmmirror.com/jweixin-module/-/jweixin-module-1.6.0.tgz",
"integrity": "sha512-dGk9cf+ipipHmtzYmKZs5B2toX+p4hLyllGLF6xuC8t+B05oYxd8fYoaRz0T30U2n3RUv8a4iwvjhA+OcYz52w==" "integrity": "sha512-dGk9cf+ipipHmtzYmKZs5B2toX+p4hLyllGLF6xuC8t+B05oYxd8fYoaRz0T30U2n3RUv8a4iwvjhA+OcYz52w=="
},
"text-segmentation": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
"requires": {
"utrie": "^1.0.2"
}
},
"utrie": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
"requires": {
"base64-arraybuffer": "^1.0.2"
}
} }
} }
} }

@ -10,6 +10,7 @@
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"html2canvas": "^1.4.1",
"jweixin-module": "^1.6.0" "jweixin-module": "^1.6.0"
} }
} }

@ -21,13 +21,19 @@
"style": { "style": {
"navigationStyle": "custom" "navigationStyle": "custom"
} }
},
{
"path": "pages/certificate/certificate",
"style": {
"navigationStyle": "custom"
}
} }
], ],
"globalStyle": { "globalStyle": {
"navigationBarTextStyle": "black", "navigationBarTextStyle": "black",
"navigationBarTitleText": "百步芳草·与理同行", "navigationBarTitleText": "百步芳草·与理同行",
"navigationBarBackgroundColor": "#F8F8F8", "navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8", "backgroundColor": "#F8F8F8",
"navigationStyle": "custom" "navigationStyle": "custom"
} }
} }

@ -0,0 +1,399 @@
<template>
<view class="page" :style="isRotate ? { 'background': '#333' } : ''">
<view ref="certificate"
id="certificate"
class="certificate"
:style="isRotate ? { 'transform': 'rotate(90deg)' + 'scale(' + scale + ',' + scale + ')' } : ''"
@click="imgClick">
<template v-if="imgData">
<img class="bkg" :src="imgData" alt="">
</template>
<template v-else>
<img class="bkg" src="/static/certificate/certificate.png" alt="">
<img class="icon1" src="/static/certificate/icon1.png" alt="">
<img class="title" src="/static/certificate/title.png" alt="">
<view class="no">
<view>
证书编号
</view>
<view>
{{ no }}
</view>
</view>
<view class="text">
<view class="text__name">{{ userInfo.name || 'xx' }} 同志:</view>
<view class="text__content">
在2023-2024年度斜塘街道基层党员冬训答题活动中表现优异特发此证
</view>
<view class="text__date">
中共苏州工业园区斜塘街道工作委员会 <br>{{ nowDate }}
</view>
</view>
</template>
</view>
<view class="operate" :style="isRotate ? { 'opacity': 0 } : ''">
<view class="operate-item" @click="isShare = true">
<u-icon name="share-square" color="#000" size="50rpx"></u-icon>
<view class="operate-item__text">分享</view>
</view>
<view class="operate-item">
<u-icon name="download" color="#000" size="50rpx"></u-icon>
<view class="operate-item__text" @click="save"></view>
</view>
</view>
<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>
</template>
<script>
import html2canvas from "html2canvas";
export default {
data() {
return {
isShare: false,
userInfo: {},
isRotate: false,
scale: 1,
imgData: ''
};
},
methods: {
getUserInfo () {
this.util.request({
api: '/api/mobile/user/show',
method: 'GET',
utilSuccess: (res) => {
console.log(res)
this.userInfo = res;
this.$nextTick(() => {
this.domToImg()
})
},
utilFail: (res) => {
this.util.toast(res)
}
})
},
imgClick () {
if (this.scale === 1) {
this.getScaleRat()
}
this.isRotate = !this.isRotate
},
domToImg () {
const dom = document.querySelector('#certificate')
html2canvas(dom, {
width: dom.clientWidth, //dom
height: dom.clientHeight,
scrollY: 0,
scrollX: 0,
useCORS: true,
}).then(cnv => {
this.imgData = cnv.toDataURL('image/png', 1)
})
},
getScaleRat () {
this.$nextTick(() => {
const { width, height } = this.$refs['certificate']?.$el?.getBoundingClientRect()
const { innerWidth, innerHeight } = window
console.log(innerWidth, height)
this.scale = innerWidth / height
})
},
converToDate (date) {
let chinese = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
let y = date.getFullYear().toString();
let m = date.getMonth().toString();
let d = date.getDate().toString();
let result = "";
for (let i = 0; i < y.length; i++) {
result += chinese[y.charAt(i)];
}
result += "年";
if (m.length === 2) {
if (m.charAt(0) === "1") {
result += ("十" + chinese[m.charAt(1)] + "月");
}
} else {
result += (chinese[m.charAt(0)] + "月");
}
if (d.length === 2) {
result += (chinese[d.charAt(0)] + "十" + chinese[m.charAt(1)] + "日");
} else {
result += (chinese[d.charAt(0)] + "日");
}
return result;
},
save() {
uni.showToast({
title: "请长按分享图片进行保存或者分享",
icon: "none"
})
}
},
computed: {
nowDate () {
return this.converToDate(new Date())
},
no () {
return `${new Date().getFullYear()}${this.userInfo.id ? this.userInfo.id.toString().padStart(6, '0') : '000000'}`
}
},
onLoad() {
this.getUserInfo()
}
}
</script>
<style lang="scss">
.page {
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
transition: all 1s;
}
.certificate {
width: 100%;
transition: all 1s;
background: #fbe6e8;
position: relative;
.bkg {
width: 100%;
object-fit: contain;
z-index: 0;
position: relative;
}
.icon1 {
width: 47rpx;
object-fit: contain;
position: absolute;
z-index: 1;
top: 12.6%;
left: calc(50% - 47rpx / 2);
}
.title {
width: 202rpx;
object-fit: contain;
z-index: 1;
position: absolute;
top: 24.8%;
left: calc(50% - 202rpx / 2);
}
.no {
display: flex;
word-break: keep-all;
font-size: 20rpx;
color: #6b4e22;
z-index: 1;
position: absolute;
right: 75rpx;
top: 14.2%;
}
.text {
color: #6b4e22;
font-weight: 500;
z-index: 1;
position: absolute;
top: 42%;
left: 94rpx;
right: 89rpx;
&__name {
font-size: 32rpx;
line-height: 38rpx;
}
&__content {
font-size: 24rpx;
text-indent: 48rpx;
padding-top: 3.5%;
}
&__date {
font-size: 20rpx;
line-height: 30rpx;
word-break: keep-all;
text-align: right;
padding-top: 6.8%;
}
}
}
.operate {
width: 100%;
display: flex;
justify-content: center;
transition: all 1s;
position: fixed;
bottom: 30rpx;
&-item {
display: flex;
flex-direction: column;
align-items: center;
&__text {
font-size: 26rpx;
}
}
.operate-item + .operate-item {
margin-left: 80rpx;
}
}
.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>

@ -5,9 +5,83 @@
<svg xmlns="http://www.w3.org/2000/svg" <svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 750 320" viewBox="0 0 750 320"
preserveAspectRatio="xMinYMin meet"> preserveAspectRatio="xMinYMin meet">
<path d="m 0 0 L 0 254 C 264 172 ,590 404, 750 282 L 750 0 z" fill="red"></path> <defs>
<linearGradient id="bkg-color" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color: rgb(222, 89, 75);" />
<stop offset="100%" style="stop-color:rgb(185,48,40);" />
</linearGradient>
<linearGradient id="bkg-cir" x1="44%" y1="0%" x2="56%" y2="100%">
<stop offset="0%" style="stop-color: rgb(231,145,141, 0.3);" />
<stop offset="60%" style="stop-color:rgb(185, 48, 40, 0);" />
</linearGradient>
</defs>
<path d="m 0 0 L 0 254 C 264 172 ,460 454, 750 200 L 750 0 z" fill="url(#bkg-color)"></path>
<circle r="118" cx="536" cy="238" fill="url(#bkg-cir)"></circle>
</svg> </svg>
</view> </view>
<img class="stage" src="/static/me/bkg-back.png" alt="">
<img class="grass1" src="/static/me/grass1.png" alt="">
<img class="grass2" src="/static/me/grass2.png" alt="">
<img class="cloud1" src="/static/me/cloud1.png" alt="">
<img class="cloud2" src="/static/me/cloud2.png" alt="">
<img class="shuibaxian" src="/static/me/shuibaxian.png" alt="">
</view>
<view class="container">
<view class="user-info">
<img class="avatar" :src="userInfo.headimgurl ? userInfo.headimgurl : '/static/index/logo.png'" alt="">
<view class="user-info__text">
<view class="name">
{{ userInfo.name || 'xx' }}
</view>
<view class="club">
{{ userInfo.study_audio_department ? userInfo.study_audio_department.name : '' }}
</view>
</view>
</view>
<view class="panel1">
<view class="left">
<view class="num">1</view>
<view class="text">已答次数</view>
</view>
<view class="right">
<view class="num">100</view>
<view class="text">最高得分</view>
</view>
</view>
<view class="panel2">
<view class="top">
<view>
<img src="/static/me/pencil.png" alt="">
<view class="text">参与答题</view>
</view>
<view>
<img src="/static/me/record.png" alt="">
<view class="text">答题记录</view>
</view>
<view>
<img src="/static/me/collect.png" alt="">
<view class="text">我的证书</view>
</view>
</view>
<view class="bottom">
<view class="row">
<u-icon name="info-circle-fill" color="#de242f" size="40rpx"></u-icon>
<view class="text">活动须知</view>
<u-icon name="arrow-right" color="#333" size="38rpx"></u-icon>
</view>
<view class="row">
<u-icon name="gift-fill" color="#999999" size="40rpx"></u-icon>
<view class="text">中奖情况</view>
<text>暂未开始</text>
</view>
</view>
</view>
</view> </view>
</view> </view>
</template> </template>
@ -15,20 +89,259 @@
<script> <script>
export default { export default {
data() { data() {
return {}; return {
} src: "http://pic2.sc.chinaz.com/Files/pic/pic9/202002/hpic2119_s.jpg",
userInfo: {}
};
},
methods: {
getUserInfo () {
this.util.request({
api: '/api/mobile/user/show',
method: 'GET',
utilSuccess: (res) => {
console.log(res)
this.userInfo = res;
this.$nextTick(() => {
this.domToImg()
})
},
utilFail: (res) => {
this.util.toast(res)
}
})
},
},
onLoad() {
this.getUserInfo()
},
} }
</script> </script>
<style lang="scss"> <style lang="scss">
.bkg { .bkg {
background: #fdf5f5;
z-index: 0;
position: fixed; position: fixed;
inset: 0 0 0 0; inset: 0 0 0 0;
.top { .top {
height: 24vh; height: 30vh;
width: 100%; width: 100%;
svg {
height: 100%;
}
}
.stage {
width: 100vw;
position: absolute;
bottom: 0;
left: 0;
}
.grass1 {
width: 110rpx;
object-fit: contain;
position: absolute;
bottom: 0;
right: 0;
}
.grass2 {
width: 110rpx;
object-fit: contain;
position: absolute;
bottom: 0;
left: 0;
}
.cloud1 {
width: 92rpx;
object-fit: contain;
position: absolute;
right: 0;
bottom: 407rpx;
}
.cloud2 {
width: 78rpx;
object-fit: contain;
position: absolute;
left: 0;
bottom: 304rpx;
}
.shuibaxian {
width: 86vw;
object-fit: cover;
position: absolute;
bottom: 50rpx;
left: 7vw;
}
}
.container {
position: relative;
z-index: 1;
.user-info {
display: flex;
align-items: center;
padding: 82rpx 0 0 54rpx;
.avatar {
width: 121rpx;
height: 121rpx;
border-radius: 100%;
object-fit: contain;
border: 1rpx solid #fff;
box-sizing: border-box;
}
&__text {
color: #fff;
margin-left: 32rpx;
.name {
font-size: 36rpx;
font-weight: 500;
word-break: keep-all;
line-height: 42rpx;
}
.club {
font-size: 24rpx;
font-weight: 400;
margin-top: 13rpx;
}
}
}
@mixin panel {
width: 658rpx;
background: #fff;
box-sizing: border-box;
border-radius: 40rpx;
filter: drop-shadow(0 0 7.5px rgba(226,54,50,0.1));
margin: auto;
.num {
font-size: 52rpx;
text-transform: uppercase;
color: #ff0000;
font-weight: bold;
}
.text {
font-size: 28rpx;
text-transform: uppercase;
color: #666666;
}
}
.panel1 {
@include panel;
height: 164rpx;
display: flex;
align-items: center;
margin: 73rpx auto 0 auto;
& > view {
flex: 1;
text-align: center;
&:nth-child(1) {
position: relative;
&::after {
content: "";
height: 91rpx;
width: 2rpx;
background: #989898;
opacity: 0.302;
transform: translateY(-50%);
position: absolute;
right: 0;
top: 50%;
}
}
}
}
.panel2 {
@include panel;
height: 689rpx;
margin-top: 30rpx;
padding: 0 46rpx 0 42rpx;
.top {
display: flex;
align-items: center;
padding-top: 50rpx;
padding-bottom: 46rpx;
position: relative;
& > view {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
img {
height: 60rpx;
object-fit: contain;
margin-bottom: 24rpx;
}
}
&::after {
content: "";
background: #989898;
opacity: 0.302;
height: 2rpx;
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
}
.bottom {
.row {
display: flex;
align-items: center;
padding: 34rpx 4rpx 34rpx 23rpx;
position: relative;
&::after {
content: "";
height: 2rpx;
background: #989898;
opacity: 0.302;
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
.text {
flex: 1;
padding-left: 20rpx;
}
text {
font-size: 20rpx;
text-transform: uppercase;
color: #666666;
}
}
}
} }
} }
</style> </style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 825 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 903 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1003 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Loading…
Cancel
Save