| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611 |
- <template>
- <!-- 页面主体内容 -->
- <view class="common_page adffc" :style="{'min-height':h+'px', 'padding-top':mt+'px'}">
- <cus-header title="申领社会实践记录" bgColor="#FFFFFF"></cus-header>
- <!-- 证书部分 -->
- <view class="prove adffcac">
- <image class="prove-logo" mode="widthFix" :src="certificateData.logoUrl"></image>
- <image class="prove-title" mode="widthFix" :src="certificateData.titleUrl"></image>
- <image class="prove-line" mode="widthFix" :src="certificateData.lineUrl"></image>
- <view class="prove-no">证书编号:{{ certificateData.certificateNumber }}</view>
- <view class="prove-info">
- <view class="prove-info-pre adf">
- <view class="prove-info-pre-left">
- <view class="prove-info-pre-left-text">义工服务姓名:</view>
- <view class="prove-info-pre-left-tip">Volunteer service Name</view>
- </view>
- <view class="prove-info-pre-right">{{ certificateData.memberName }}</view>
- </view>
- <view class="prove-info-pre adf">
- <view class="prove-info-pre-left">
- <view class="prove-info-pre-left-text space">所属学校:</view>
- <view class="prove-info-pre-left-tip">Affiliated school</view>
- </view>
- <view class="prove-info-pre-right">{{ certificateData.currentSchool }}</view>
- </view>
- <view class="prove-info-pre adf">
- <view class="prove-info-pre-left">
- <view class="prove-info-pre-left-text space">证件类型:</view>
- <view class="prove-info-pre-left-tip">Type of ID</view>
- </view>
- <view class="prove-info-pre-right">{{ certificateData.idType }}</view>
- </view>
- <view class="prove-info-pre adf">
- <view class="prove-info-pre-left">
- <view class="prove-info-pre-left-text space">证件号码:</view>
- <view class="prove-info-pre-left-tip">IdCard No</view>
- </view>
- <view class="prove-info-pre-right">{{ certificateData.idCard }}</view>
- </view>
- <view class="prove-info-pre adf">
- <view class="prove-info-pre-left">
- <view class="prove-info-pre-left-text">义工服务时长:</view>
- <view class="prove-info-pre-left-tip">Volunteer service Time</view>
- </view>
- <view class="prove-info-pre-right">{{ certificateData.volunteerHours }}小时</view>
- </view>
- </view>
- <view class="prove-memo">
- 您累计参与了 <span>{{ certificateData.welfareCount }}</span> 场活动,捐赠了 <span>{{ certificateData.loveValue }}</span> 爱心值。向您践行志愿精神,为社会进步奉献力量致以最崇高的敬意。
- </view>
- <view class="prove-memo" style="margin-top: 30rpx;">特发此证!</view>
- <view class="prove-bottom">
- <view class="prove-bottom-pre">证明单位:{{ certificateData.issuer }}</view>
- <view class="prove-bottom-pre">发证日期:{{ certificateData.createDate }}</view>
- </view>
- <image class="prove-seal" mode="widthFix" :src="certificateData.sealUrl"></image>
- </view>
- <!-- 列表部分 -->
- <view class="list">
- <view class="list-box" v-for="(item,index) in activityList" :key="index">
- <view class="title">{{ item.activityName||'' }}</view>
- <view class="content adf">
- <view class="right">
- <view class="right-pre adf">
- <view class="tip">活动时间:</view>
- <view class="text">{{ item.activityStartTime||'' }}</view>
- </view>
- <view class="right-pre adf">
- <template v-if="item.activityLimit==2">
- <view class="tip">专享券贡献:</view>
- <view class="text">{{ item.valueLimit||0 }}张</view>
- </template>
- <template v-else>
- <view class="tip">爱心值贡献:</view>
- <view class="text">{{ item.valueLimit||0 }}</view>
- </template>
- </view>
- <view class="right-pre adf">
- <view class="tip">义工时长:</view>
- <view class="text">{{ item.serviceHours||0 }}小时</view>
- </view>
- <view class="right-pre adf">
- <view class="tip">公益合作:</view>
- <view class="text">{{ item.channelName||'' }}</view>
- </view>
- </view>
- </view>
- </view>
- </view>
- <!-- 下载按钮 -->
- <view class="btn" @click="handleDownload">
- {{ isLoading ? '生成中...' : '下载' }}
- </view>
- </view>
- <canvas canvas-id="pdf-canvas" :style="'width:' + canvasWidth + 'px; height:' + canvasHeight + 'px; position: fixed; left: -9999px; top: -9999px;'"></canvas>
- </template>
- <script setup>
- import CusHeader from '@/components/CusHeader/index.vue'
- import { onLoad } from '@dcloudio/uni-app'
- import { ref, computed, getCurrentInstance } from 'vue'
- const { proxy } = getCurrentInstance()
- // 页面数据,实际项目中这些数据应该是动态获取的
- const certificateData = ref({
- logoUrl: 'https://transcend.ringzle.com/xiaozhi-app/profile/2025/11/20/965dc74b-fc45-4409-aa09-56877e75d2bc.png',
- titleUrl: 'https://transcend.ringzle.com/xiaozhi-app/profile/2025/11/20/7c341572-58b7-4afb-801f-93bf9890fa76.png',
- lineUrl: 'https://transcend.ringzle.com/xiaozhi-app/profile/2025/11/20/c21e680c-e83a-4f54-948c-19c49141ae99.png',
- backgroundUrl: 'https://transcend.ringzle.com/xiaozhi-app/profile/2025/11/20/57b2f49c-beac-49e7-8840-777ec860ae59.png',
- sealUrl: 'https://transcend.ringzle.com/xiaozhi-app/profile/2025/11/20/8ad6323d-f6a0-4057-8063-7eec97ec93f4.png',
- certificateNumber: '',
- memberName: '',
- currentSchool: '',
- idType: '居民身份证',
- idCard: '',
- volunteerHours: 0,
- welfareCount: 0,
- loveValue: 0,
- issuer: '善行少年服务基金会',
- createDate: ''
- });
- const activityList = ref([]);
- const isLoading = ref(false);
- const canvasWidth = ref(0);
- const canvasHeight = ref(0);
-
- // rpx转px的工具函数
- const rpxToPx = (rpx) => {
- const screenWidth = uni.getSystemInfoSync().windowWidth;
- return (screenWidth / 750) * rpx;
- };
-
- // 文本换行绘制函数
- const drawWrappedText = (ctx, text, x, y, maxWidth, lineHeight) => {
- const words = text.split('');
- let line = '';
- let currentY = y;
- for (let n = 0; n < words.length; n++) {
- const testLine = line + words[n];
- const metrics = ctx.measureText(testLine);
- const testWidth = metrics.width;
- if (testWidth > maxWidth && n > 0) {
- ctx.fillText(line, x, currentY);
- line = words[n];
- currentY += lineHeight;
- } else {
- line = testLine;
- }
- }
- ctx.fillText(line, x, currentY);
- return currentY - y + lineHeight; // 返回这段文本所占的总高度
- };
-
- // 获取网络图片信息,返回一个Promise
- const getImageInfo = (url) => {
- return new Promise((resolve, reject) => {
- uni.getImageInfo({
- src: url,
- success: (res) => resolve(res),
- fail: (err) => reject(err),
- });
- });
- };
-
- // 主下载处理函数
- // 主下载处理函数
- const handleDownload = async () => {
- if (isLoading.value) return;
- isLoading.value = true;
- uni.showLoading({ title: '正在生成图片...', mask: true });
-
- try {
- // 1. 动态计算Canvas尺寸
- const proveHeight = rpxToPx(945);
- const pagePaddingTop = rpxToPx(20); // prove-margin-top
- const pagePaddingBottom = rpxToPx(184); // 页面底部到按钮的距离
-
- // 估算一个列表项的高度: 上下padding(36*2) + 标题(32) + 标题margin(30) + 4行内容(4*50) + 列表项间距(20)
- // 这里的 4*50 是一个估算值,基于你的CSS
- const singleListHeight = rpxToPx(36 * 2 + 32 + 30 + (20 + 24) * 4 + 20); // 估算每行高度(margin-top + font-size)
-
- canvasWidth.value = uni.getSystemInfoSync().windowWidth;
- // 总高度 = 证书高度 + 列表总高度 + 页面顶部边距 + 底部空白区域
- canvasHeight.value = proveHeight + (singleListHeight * activityList.value.length) + pagePaddingTop + pagePaddingBottom;
-
- // 2. 预加载所有图片
- const imagesToLoad = [
- certificateData.value.backgroundUrl,
- certificateData.value.logoUrl,
- certificateData.value.titleUrl,
- certificateData.value.lineUrl,
- certificateData.value.sealUrl
- ];
- const imageInfos = await Promise.all(imagesToLoad.map(url => getImageInfo(url)));
-
- const [
- bgImg, logoImg, titleImg, lineImg, sealImg
- ] = imageInfos.map(info => info.path);
-
- // 3. 开始绘制
- const ctx = uni.createCanvasContext('pdf-canvas', proxy); // 传入 proxy
-
- // 绘制白色背景
- ctx.setFillStyle('#F5F5F5');
- ctx.fillRect(0, 0, canvasWidth.value, canvasHeight.value);
-
- let currentY = rpxToPx(20); // 从顶部20rpx的margin开始
-
- // ---- 3.1 绘制证书 (这部分逻辑基本正确,无需大改) ----
- const proveX = 0;
- const proveWidth = canvasWidth.value;
-
- // 绘制证书背景
- ctx.drawImage(bgImg, proveX, currentY, proveWidth, proveHeight);
-
- // 绘制Logo
- ctx.drawImage(logoImg, rpxToPx(72), currentY + rpxToPx(58), rpxToPx(133), rpxToPx(40));
- // 绘制标题
- ctx.drawImage(titleImg, (proveWidth - rpxToPx(363)) / 2, currentY + rpxToPx(101), rpxToPx(363), rpxToPx(40));
- // 绘制线条
- ctx.drawImage(lineImg, (proveWidth - rpxToPx(400)) / 2, currentY + rpxToPx(101 + 40 + 7), rpxToPx(400), rpxToPx(5));
-
- // 绘制证书编号
- ctx.setFontSize(rpxToPx(20));
- ctx.setFillStyle('#9F793F');
- ctx.setTextAlign('center');
- ctx.fillText(`证书编号:${certificateData.value.certificateNumber}`, proveWidth / 2, currentY + rpxToPx(190));
-
- // 绘制个人信息
- ctx.setTextAlign('left');
- const infoStartX = (proveWidth - rpxToPx(135 + 188)) / 2;
- const infoStartY = currentY + rpxToPx(244);
- const infoItems = [
- { label: '义工服务姓名:', value: certificateData.value?.memberName||'', tip: 'Volunteer service Name' },
- { label: '所属学校:', value: certificateData.value?.currentSchool||'', tip: 'Affiliated school' },
- { label: '证件类型:', value: certificateData.value?.idType, tip: 'Type of ID' },
- { label: '证件号码:', value: certificateData.value?.idCard||'', tip: 'IdCard No' },
- { label: '义工服务时长:', value: `${certificateData.value?.volunteerHours||0}小时`, tip: 'Volunteer service Time' }
- ];
- infoItems.forEach((item, index) => {
- const itemY = infoStartY + index * rpxToPx(40);
- ctx.setFillStyle('#252525');
- ctx.setFontSize(rpxToPx(17));
- ctx.fillText(item.label, infoStartX, itemY);
- ctx.setFontSize(rpxToPx(10));
- ctx.fillText(item.tip, infoStartX, itemY + rpxToPx(13));
-
- const valueX = infoStartX + rpxToPx(135);
- ctx.setFontSize(rpxToPx(17));
- ctx.fillText(item.value, valueX, itemY);
-
- ctx.setStrokeStyle('#DDCEAF');
- ctx.setLineWidth(rpxToPx(1)); // 1px的线在高清屏下更清晰
- ctx.beginPath();
- ctx.moveTo(valueX, itemY + rpxToPx(8));
- ctx.lineTo(valueX + rpxToPx(188), itemY + rpxToPx(8));
- ctx.stroke();
- });
-
- // 绘制memo
- ctx.setFontSize(rpxToPx(20));
- ctx.setFillStyle('#252525');
- // Canvas无法识别<span>,需要分段绘制或在JS中处理颜色
- const memoText1 = `您累计参与了 `;
- const memoText2 = `${certificateData.value.welfareCount}`;
- const memoText3 = ` 场活动,捐赠了 `;
- const memoText4 = `${certificateData.value.loveValue}`;
- const memoText5 = ` 爱心值。向您践行志愿精神,为社会进步奉献力量致以最崇高的敬意。`;
- const memoY = currentY + rpxToPx(500);
- const memoX = rpxToPx(80);
-
- ctx.fillText(memoText1, memoX, memoY);
- let currentX = memoX + ctx.measureText(memoText1).width;
- ctx.setFillStyle('#C9A771'); // 设置高亮颜色
- ctx.fillText(memoText2, currentX, memoY);
- currentX += ctx.measureText(memoText2).width;
- ctx.setFillStyle('#252525'); // 恢复默认颜色
- ctx.fillText(memoText3, currentX, memoY);
- currentX += ctx.measureText(memoText3).width;
- ctx.setFillStyle('#C9A771'); // 设置高亮颜色
- ctx.fillText(memoText4, currentX, memoY);
- currentX += ctx.measureText(memoText4).width;
- ctx.setFillStyle('#252525'); // 恢复默认颜色
- // 后续文本太长,需要换行处理,这里简化为直接绘制,实际可能需要drawWrappedText
- drawWrappedText(ctx, memoText5, currentX, memoY, proveWidth - rpxToPx(160) - (currentX-memoX), rpxToPx(31));
-
- ctx.fillText('特发此证!', rpxToPx(80), currentY + rpxToPx(600));
-
- // 绘制证明单位和日期
- ctx.setFontSize(rpxToPx(17));
- ctx.fillText(`证明单位:${certificateData.value.issuer}`, rpxToPx(80), currentY + rpxToPx(700));
- ctx.fillText(`发证日期:${certificateData.value.createDate}`, rpxToPx(80), currentY + rpxToPx(730));
-
- // 绘制印章
- ctx.drawImage(sealImg, proveWidth - rpxToPx(73 + 131), currentY + proveHeight - rpxToPx(69 + 131), rpxToPx(131), rpxToPx(131));
-
- currentY += proveHeight; // 更新Y坐标到证书底部
-
- // ---- 3.2 绘制活动列表 ----
- for (const item of activityList.value) {
- currentY += rpxToPx(20); // 列表项间距
-
- const boxX = rpxToPx(24);
- const boxWidth = canvasWidth.value - rpxToPx(48);
-
- let itemContentHeight = 0; // 动态计算每个item的高度
-
- // 预计算高度
- const titleHeight = rpxToPx(32);
- const contentPaddingTop = rpxToPx(36);
- const titleMarginBottom = rpxToPx(30);
- const contentPaddingBottom = rpxToPx(36);
- const rightItemLineHeight = rpxToPx(50); // 估算行高(包含margin)
- itemContentHeight = contentPaddingTop + titleHeight + titleMarginBottom + (rightItemLineHeight * 4) + contentPaddingBottom;
-
- // 绘制列表项背景
- ctx.setFillStyle('#FFFFFF');
- ctx.setShadow(0, rpxToPx(5), rpxToPx(10), 'rgba(0,0,0,0.05)'); // 可选:添加阴影使其更逼真
- ctx.fillRect(boxX, currentY, boxWidth, itemContentHeight);
- ctx.setShadow(0, 0, 0, 'rgba(0,0,0,0)'); // 清除阴影
-
- const contentPaddingX = rpxToPx(20);
- let itemInnerY = currentY + contentPaddingTop;
-
- // 绘制标题
- ctx.setFontSize(rpxToPx(32));
- ctx.setFillStyle('#252525');
- ctx.font = `bold ${rpxToPx(32)}px sans-serif`;
- ctx.fillText(item.activityName || '', boxX + contentPaddingX, itemInnerY + rpxToPx(16)); // Y微调
-
- itemInnerY += titleHeight + titleMarginBottom;
-
- // 绘制右侧文字
- const textStartX = boxX + contentPaddingX;
- ctx.setFontSize(rpxToPx(24));
- ctx.font = `normal ${rpxToPx(24)}px sans-serif`;
-
- const rightItems = [
- { tip: '活动时间:', text: item.activityStartTime || '' },
- { tip: `${item.activityLimit == 2 ? '专享券贡献:' : '爱心值贡献:'}`, text: `${item.valueLimit || 0}${item.activityLimit == 2 ? '张' : ''}` },
- { tip: '义工时长:', text: `${item.serviceHours || 0}小时` },
- { tip: '公益合作:', text: item.channelName || '' },
- ];
-
- rightItems.forEach((rightItem, idx) => {
- const textY = itemInnerY + (idx * rightItemLineHeight);
- ctx.setFillStyle('#676775');
- ctx.fillText(rightItem.tip, textStartX, textY);
-
- const tipWidth = ctx.measureText(rightItem.tip).width;
- ctx.setFillStyle('#252525');
- ctx.font = `bold ${rpxToPx(24)}px sans-serif`;
- // 绘制文本,这里不使用换行函数,因为内容一般不长
- ctx.fillText(rightItem.text, textStartX + tipWidth, textY);
- ctx.font = `normal ${rpxToPx(24)}px sans-serif`; // 重置字体
- });
-
- currentY += itemContentHeight;
- }
-
- // 4. 执行绘制并生成图片
- ctx.draw(false, () => {
- uni.canvasToTempFilePath({
- canvasId: 'pdf-canvas',
- destWidth: canvasWidth.value * 2, // 提高图片清晰度
- destHeight: canvasHeight.value * 2,
- fileType: 'png',
- quality: 1,
- success: (res) => {
- // 5. 保存图片到相册
- uni.saveImageToPhotosAlbum({
- filePath: res.tempFilePath,
- success: () => {
- uni.showToast({ title: '已保存到相册', icon: 'success' });
- },
- fail: (err) => {
- console.log(err);
- if (err.errMsg && err.errMsg.includes('auth deny')) {
- uni.showModal({
- title: '提示',
- content: '需要您授权保存相册',
- showCancel: false,
- success: () => uni.openSetting()
- });
- } else {
- uni.showToast({ title: '保存失败,请稍后重试', icon: 'none' });
- }
- }
- });
- },
- fail: (err) => {
- console.error('canvasToTempFilePath failed:', err);
- uni.showToast({ title: '图片生成失败', icon: 'none' });
- },
- complete: () => {
- uni.hideLoading();
- isLoading.value = false;
- }
- }, proxy); // 传入 proxy
- });
-
- } catch (error) {
- console.error('handleDownload error:', error);
- uni.hideLoading();
- isLoading.value = false;
- uni.showToast({
- title: '生成失败,请检查网络或资源链接', // 提示更具体
- icon: 'none'
- });
- }
- };
- onLoad((options)=>{
- proxy.$api.get(`/core/social/practice/record/${options?.id||''}`).then(({data:res})=>{
- if(res.code!==0) return proxy.$showToast(res.msg)
- certificateData.value = {...certificateData.value,...res.data};
- certificateData.value.idCard = certificateData.value.idCard&&certificateData.value.idCard.replace(/^(\d{6})(\d{8})(\d{3}[\dX])$/i,'$1********$3');
- activityList.value = res.data?.activityVos||[];
- })
- })
- </script>
- <style scoped lang="scss">
- .common_page {
- background-color: #F5F5F5;
- padding: 0 0 184rpx;
-
- .prove{
- margin: 20rpx 24rpx 0; // 改为外边距,避免影响全屏截图
- width: calc(100% - 40rpx);
- background: url('https://transcend.ringzle.com/xiaozhi-app/profile/2025/11/20/57b2f49c-beac-49e7-8840-777ec860ae59.png') no-repeat;
- background-size: 100% 100%;
- height: 945rpx;
- position: relative;
- &-logo{
- width: 133rpx;
- position: absolute;
- top: 58rpx;
- left: 72rpx;
- }
- &-title{
- width: 363rpx;
- margin-top: 101rpx;
- }
- &-line{
- width: 400rpx;
- margin-top: 7rpx;
- }
- &-seal{
- width: 131rpx;
- border-radius: 50%;
- position: absolute;
- bottom: 69rpx;
- right: 73rpx;
- }
-
- &-no{
- font-family: SourceHanSerifSC, SourceHanSerifSC;
- font-weight: bold;
- font-size: 20rpx;
- color: #9F793F;
- line-height: 20rpx;
- letter-spacing: 1px;
- margin-top: 9rpx;
- }
-
- &-info{
- margin-top: 27rpx;
- overflow: auto;
- &-pre{
- margin-top: 22rpx;
- &-left{
- width: 135rpx;
- &-text{
- font-family: PingFangSC, PingFang SC;
- font-weight: 400;
- font-size: 17rpx;
- color: #252525;
- line-height: 17rpx;
- letter-spacing: 1px;
- &.space{
- letter-spacing: 10rpx;
- }
- }
- &-tip{
- font-family: PingFangSC, PingFang SC;
- font-weight: 400;
- font-size: 10rpx;
- color: #252525;
- line-height: 10rpx;
- margin-top: 3rpx;
- }
- }
- &-right{
- width: 188rpx;
- font-family: PingFangSC, PingFang SC;
- font-weight: 400;
- font-size: 17rpx;
- color: #252525;
- line-height: 17rpx;
- padding-bottom: 8rpx;
- border-bottom: 2rpx solid #DDCEAF;
- }
- }
- }
- &-memo{
- width: 100%;
- padding: 0 80rpx;
- box-sizing: border-box;
- margin-top: 79rpx;
- font-family: PingFangSC, PingFang SC;
- font-weight: 400;
- font-size: 20rpx;
- color: #252525;
- line-height: 31rpx;
- label{ // canvas无法直接渲染span,颜色在js中处理
- color: #C9A771;
- margin: 0 5rpx;
- }
- }
- &-bottom{
- width: 100%;
- padding: 0 80rpx;
- box-sizing: border-box;
- margin-top: 89rpx;
- overflow: hidden;
- &-pre{
- margin-top: 16rpx;
- font-family: PingFangSC, PingFang SC;
- font-weight: 400;
- font-size: 17rpx;
- color: #252525;
- line-height: 20rpx;
- }
- }
- }
-
- .list{
- margin: 0 24rpx;
- &-box{
- margin-top: 20rpx;
- padding: 36rpx 20rpx;
- background: #FFFFFF;
- .title{
- font-family: PingFang-SC, PingFang-SC;
- font-weight: bold;
- font-size: 32rpx;
- color: #252525;
- line-height: 32rpx;
- }
- .content{
- margin-top: 30rpx;
- // .left{
- // width: 182rpx;
- // height: 240rpx;
- // image{
- // width: 100%;
- // height: 100%;
- // }
- // }
- .right{
- width: 100%;
- // width: calc(100% - 182rpx);
- // padding-left: 20rpx;
- // box-sizing: border-box;
- &-pre{
- margin-top: 20rpx;
- &:first-child{
- margin-top: 12rpx;
- }
- .tip{
- width: 150rpx;
- font-family: PingFangSC, PingFang SC;
- font-weight: 400;
- font-size: 24rpx;
- color: #676775;
- }
- .text{
- width: calc(100% - 150rpx);
- font-family: PingFang-SC, PingFang-SC;
- font-weight: bold;
- font-size: 24rpx;
- color: #252525;
- }
- }
- }
- }
- }
- }
-
- .btn{
- width: calc(100% - 210rpx);
- height: 90rpx;
- background: #B7F358;
- border-radius: 45rpx;
- font-family: PingFang-SC, PingFang-SC;
- font-weight: bold;
- font-size: 32rpx;
- color: #151B29;
- line-height: 90rpx;
- text-align: center;
- letter-spacing: 2rpx;
- position: fixed;
- left: 105rpx;
- bottom: 64rpx;
- z-index: 10;
- }
- }
- </style>
|