alipay-emulator/pages/other/game/honor-of-kings.vue

829 lines
24 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="honor-of-kings">
<nav-bar title="王者主页" bgColor="#F5F5F5" isRightButton :rightButtonText="rightButtonText"
@right-click="onRightClick">
</nav-bar>
<view style="padding: 8px;box-sizing: border-box;">
<view class="painter-container" @click="handlePreview"
:style="`width:calc(100vw - 16px) ; height: ${posterContainerHeight}px; overflow: hidden; position: relative; transform: translateZ(0);`">
<!-- 运用 js 算出的无误差纯数字 scale 来实现高清画板的等比缩小彻底兼容所有老旧内核不再被截断 -->
<view
:style="`width: 750px; transform: scale(${posterScaleRatio}); transform-origin: left top; position: absolute; left: 0; top: 0;`">
<l-painter isCanvasToTempFilePath @success="onPainterSuccess" :css="`width:750px;`">
<l-painter-view :css="`width: 750.0px; position: relative;`">
<!-- 直接使用主背景图撑开父容器移除不必要的 opacity: 0 占位图避免在大屏渲染时产生黑块 -->
<l-painter-image :src="`/static/image/other/game/wangzhe/style-${honorData.type}.jpg`"
css="width: 750.0px; display: block;"></l-painter-image>
<!-- 头像 (纯百分比绝对定位完美适配所有大屏分辨率) -->
<l-painter-image :src="honorData.avatar"
css="position: absolute; left: 117.0px; top: 76.8px; width: 66px; height: 66px; border-radius: 200px; object-fit: cover; display: block;"></l-painter-image>
<!-- 头像框 (压在头像上方) -->
<l-painter-image
:src="`/static/image/other/game/wangzhe/avatar-frame-${honorData.type}.png`"
css="position: absolute; left: 0; top: 0; width: 183px; height: 141px"></l-painter-image>
<!-- 性别图标 -->
<l-painter-image :src="`/static/image/other/game/wangzhe/${honorData.gender}.png`"
:css="`position: absolute; left: ${honorData.type == 3 ? '217.5px' : '202.5px'}; top: 87.0px; width: 11.8px; height: 11.7px;`"></l-painter-image>
<!-- 昵称渐变图片 -->
<l-painter-image v-if="nicknameImage" :src="nicknameImage"
:css="`position: absolute; left: ${honorData.type == 3 ? '230.3px' : '215.3px'}; top: ${$system == 'iOS' ? '83px' : '85.6px'}; width: ${honorData.nickname.length * 14.9}px;`"></l-painter-image>
<!-- 收到花束 -->
<l-painter-text :text="honorData.receivedFlowers"
css="position: absolute; left: 358.5px; top: 131.4px; font-size: 9px; color: #DAF2FF;transform: translateX(-50%);font-family: WangZheFont2;"></l-painter-text>
<!-- 热度数 -->
<l-painter-text :text="honorData.popularityCount"
css="position: absolute; left: 386.3px; top: 131.4px; font-size: 9px; color: #DAF2FF;transform: translateX(-50%);font-family: WangZheFont2;"></l-painter-text>
<!-- 点赞数 -->
<l-painter-text :text="honorData.likeCount"
css="position: absolute; left: 414.0px; top: 131.4px; font-size: 9px; color: #DAF2FF;transform: translateX(-50%);font-family: WangZheFont2;"></l-painter-text>
<!-- 荣誉一 -->
<l-painter-text :text="honorData.honor1"
css="position: absolute; left: 247.5px; top: 145.6px; font-size: 9px; color: #71B1D3;transform: translateX(-50%);"></l-painter-text>
<!-- 荣誉二 -->
<l-painter-text :text="honorData.honor2"
css="position: absolute; left: 465.6px; top: 173.6px; font-size: 8px; color: #71B1D3;transform: scale(0.85),translateX(-50%);"></l-painter-text>
<!-- 巅峰万强 -->
<l-painter-text v-if="honorData.type == 4" :text="honorData.peakStrong"
css="position: absolute; left: 257.3px; top: 192.8px; font-size: 8px; color: #E9F5FB;transform: translateX(-50%);"></l-painter-text>
<!-- 对战场次 -->
<l-painter-text :text="honorData.matchCount"
css="position: absolute; left: 138.0px; top: 242.3px; font-size: 12px; color: #71B1D3;transform: translateX(-50%);"></l-painter-text>
<!-- 对战被赞 -->
<l-painter-text :text="honorData.matchLikeCount"
css="position: absolute; left: 199.5px; top: 242.3px; font-size: 12px; color: #71B1D3;transform: translateX(-50%);"></l-painter-text>
<!-- 图鉴等级 -->
<l-painter-text :text="honorData.pokedexLevel"
css="position: absolute; left: 319.5px; top: 238.8px; font-size:9px; color: #71B1D3;transform: translateX(-50%);"></l-painter-text>
<!-- 皮肤数 -->
<l-painter-text :text="honorData.skinCount"
css="position: absolute; left: 377.3px; top: 238.8px; font-size:9px; color: #71B1D3;transform: translateX(-50%);"></l-painter-text>
<!-- 游戏天数 -->
<l-painter-text v-if="honorData.type == 1 || honorData.type == 2" :text="honorData.gameDays"
css="position: absolute; left: 202.1px; top: 282.2px; font-size:10px; color: #71B1D3;transform: translateX(-50%);"></l-painter-text>
<!-- 峡谷对战局数 -->
<l-painter-text v-if="honorData.type == 1 || honorData.type == 2"
:text="honorData.riftMatchCount"
css="position: absolute; left: 322.2px; top: 282.2px; font-size:10px; color: #71B1D3;transform: translateX(-50%);"></l-painter-text>
<!-- 大乱斗对战局数 -->
<l-painter-text v-if="honorData.type == 1 || honorData.type == 2"
:text="honorData.aramMatchCount"
css="position: absolute; left: 379.9px; top: 282.2px; font-size:10px; color: #71B1D3;transform: translateX(-50%);"></l-painter-text>
<!-- 亲密度 -->
<l-painter-text v-if="honorData.type == 3 || honorData.type == 4" :text="honorData.intimacy"
css="position: absolute; left: 348.0px; top: 296.2px; font-size:10px; color: #71B1D3;transform: translateX(-50%);font-family: WangZheFont2;"></l-painter-text>
<!-- 水印 -->
<l-painter-image v-if="$isVip()" src="/static/image/other/shuiying.png"
:css="`position: absolute; left: 18.8px; bottom: 17.1px; width: 145.38px;height:42.76px`"></l-painter-image>
</l-painter-view>
</l-painter>
</view>
</view>
</view>
<!-- 水印 -->
<view v-if="$isVip()">
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark', 'uni_alipay_other_wangzhe')">
<c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie>
</liu-drag-button>
</view>
<view class="save-action">
<button class="save-btn" @click="handleSave">保存</button>
</view>
<!-- 主题选择区域 -->
<view class="theme-selector">
<scroll-view scroll-x="true" class="theme-scroll" :show-scrollbar="false">
<view class="theme-list">
<view class="theme-item" v-for="(item, index) in ['样式一', '样式二', '样式三', '样式四']" :key="index + 1"
:class="{ active: honorData.type == index + 1 }" @click="handleChangeTheme(index + 1)">
<text class="theme-text">{{ item }}</text>
</view>
</view>
</scroll-view>
</view>
<!-- 数据编辑弹窗 -->
<uni-popup ref="editPopup" type="center">
<view class="edit-popup-content">
<view class="popup-header">
<text class="title">编辑主页数据</text>
</view>
<scroll-view scroll-y class="popup-scroll">
<!-- <view class="form-item">
<text class="label">样式类型</text>
<input class="input" type="number" v-model="tempData.type" placeholder="1-4" />
</view> -->
<view class="form-item avatar-form-item">
<text class="label">头像</text>
<view class="avatar-uploader">
<view class="avatar-preview" v-if="tempData.avatar">
<image class="preview-img" :src="tempData.avatar" mode="aspectFill"></image>
<view class="delete-icon" @click="handleDeleteAvatar">
<text>×</text>
</view>
</view>
<view class="upload-btn" v-else @click="handleChooseAvatar">
<text class="plus">+</text>
</view>
</view>
</view>
<view class="form-item">
<text class="label">昵称</text>
<input class="input" type="text" v-model="tempData.nickname" />
</view>
<view class="form-item">
<text class="label">性别</text>
<view class="radio-group">
<view class="radio-item" @click="tempData.gender = 'man'">
<view class="radio-icon" :class="{ active: tempData.gender === 'man' }"></view>
<text class="radio-text" :class="{ active: tempData.gender === 'man' }">男</text>
</view>
<view class="radio-item" @click="tempData.gender = 'female'">
<view class="radio-icon" :class="{ active: tempData.gender === 'female' }"></view>
<text class="radio-text" :class="{ active: tempData.gender === 'female' }">女</text>
</view>
</view>
</view>
<view class="form-item">
<text class="label">荣誉一</text>
<input class="input" type="text" v-model="tempData.honor1" />
</view>
<view class="form-item">
<text class="label">荣誉二</text>
<input class="input" type="text" v-model="tempData.honor2" />
</view>
<view class="form-item">
<text class="label">巅峰万强</text>
<input class="input" type="text" v-model="tempData.peakStrong" />
</view>
<view class="form-item">
<text class="label">收到花束</text>
<input class="input" type="text" v-model="tempData.receivedFlowers" />
</view>
<view class="form-item">
<text class="label">热度</text>
<input class="input" type="text" v-model="tempData.popularityCount" />
</view>
<view class="form-item">
<text class="label">点赞数</text>
<input class="input" type="text" v-model="tempData.likeCount" />
</view>
<view class="form-item">
<text class="label">对战场次</text>
<input class="input" type="number" v-model="tempData.matchCount" />
</view>
<view class="form-item">
<text class="label">对战被赞</text>
<input class="input" type="number" v-model="tempData.matchLikeCount" />
</view>
<view class="form-item">
<text class="label">图鉴等级</text>
<input class="input" type="number" v-model="tempData.pokedexLevel" />
</view>
<view class="form-item">
<text class="label">皮肤数</text>
<input class="input" type="number" v-model="tempData.skinCount" />
</view>
<view class="form-item">
<text class="label">游戏天数</text>
<input class="input" type="number" v-model="tempData.gameDays" />
</view>
<view class="form-item">
<text class="label">峡谷对战局数</text>
<input class="input" type="number" v-model="tempData.riftMatchCount" />
</view>
<view class="form-item">
<text class="label">大乱斗局数</text>
<input class="input" type="number" v-model="tempData.aramMatchCount" />
</view>
<view class="form-item">
<text class="label">亲密度</text>
<input class="input" type="number" v-model="tempData.intimacy" />
</view>
</scroll-view>
<view class="popup-footer">
<button class="cancel-btn" @click="closeEditPopup">取消</button>
<button class="confirm-btn" @click="confirmEdit">确定</button>
</view>
</view>
</uni-popup>
<!-- 隐藏的画布:用于原生绘制带有纯正渐变色的文本,再转成图片给到海报插件 -->
<view style="position: absolute; left: -9999px; top: -9999px; width: 0; height: 0; overflow: hidden;">
<canvas canvas-id="gradientTextCanvas" id="gradientTextCanvas" style="width: 300px; height: 60px;"></canvas>
</view>
<!-- 横向全屏放大预览层 -->
<view class="preview-overlay" v-if="showPreview" @click="showPreview = false">
<image class="preview-image" :src="finalPosterPath" mode="aspectFill"></image>
</view>
</view>
</template>
<script setup>
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
import { onLoad, onReady } from '@dcloudio/uni-app'
const rightButtonText = ref("编辑");
const instance = getCurrentInstance();
const { proxy } = getCurrentInstance();
const nicknameImage = ref('');
const showPreview = ref(false); // 控制全屏预览
const isMountedReady = ref(false);
const isFontLoaded = ref(false);
// 获取系统宽度计算海报缩放比例,代替容易失效的 css calc(),确保全端兼容防截断
const sysInfo = uni.getSystemInfoSync();
const windowWidth = sysInfo.windowWidth || 375;
const posterScaleRatio = windowWidth / 750;
const posterContainerHeight = 342 * posterScaleRatio;
// 页面表单数据字段
const honorData = reactive({
type: 1, // 样式类型 1.2.3.4
avatar: '/static/image/shopping/pdd/avatars/avatars1.jpg', // 头像
nickname: '甜喵小贝', // 昵称
gender: 'female', // 性别
region: '重庆市两江新区', // 地区
honor1: '国服第一小乔', // 荣誉1
honor2: '888级大师收藏家·珍耀无双', // 荣誉2
matchCount: 58965, // 对战场次
matchLikeCount: 9746, // 对战被赞数
gameDays: 3127, // 游戏天数
pokedexLevel: 104, // 图鉴等级
skinCount: 444, // 皮肤数
riftMatchCount: 7368, // 峡谷对战局数
aramMatchCount: 5193, // 大乱斗对战局数
receivedFlowers: 520, // 收到花束
popularityCount: '6.0W', // 热度数
likeCount: 4883, // 点赞数
intimacy: '25147',//亲密度
peakStrong: '5632'
})
onLoad(() => {
const cachedData = uni.getStorageSync('wangzheHonorData');
if (cachedData) {
Object.assign(honorData, cachedData);
}
// 进入页面埋点
proxy.$apiUserEvent('all', {
type: 'click',
key: 'wangzhe',
prefix: '.uni.other.',
value: "王者主页"
})
const config = uni.getStorageSync('config')
console.log("---config---", config);
let fontConfig = config.config['client.uniapp.font'];
try {
if (typeof fontConfig === 'string') {
fontConfig = JSON.parse(fontConfig);
}
} catch (e) {
console.error('字体配置解析失败', e);
}
console.log("字体地址信息", fontConfig?.wangzhe);
// Font loading logic
const fontUrl = fontConfig?.wangzhe;
const fontUrl2 = fontConfig?.wangzhe2;
let loadedCount = 0;
const totalFonts = 2;
const checkAllLoaded = () => {
loadedCount++;
if (loadedCount >= totalFonts) {
isFontLoaded.value = true;
if (isMountedReady.value) drawGradientText();
}
};
const loadSingleFont = (url, name, storageKey, onComplete) => {
if (!url) {
console.warn(`未获取到 ${name} 字体地址,回退使用系统默认字体`);
onComplete && onComplete();
return;
}
const doLoad = (path) => {
uni.loadFontFace({
family: name,
source: `url("${path}")`,
success() {
console.log(`${name} 字体加载成功`);
onComplete && onComplete();
},
fail(err) {
console.error(`${name} 字体加载失败`, err);
onComplete && onComplete();
}
});
};
// #ifdef H5
// H5 环境直接从 URL 加载字体
doLoad(url);
// #endif
// #ifndef H5
// 非 H5 环境使用下载和保存逻辑
const savedPath = uni.getStorageSync(storageKey);
if (savedPath) {
doLoad(savedPath);
} else {
uni.downloadFile({
url: url,
success: (res) => {
if (res.statusCode === 200) {
uni.saveFile({
tempFilePath: res.tempFilePath,
success: (saveRes) => {
const saved = saveRes.savedFilePath;
uni.setStorageSync(storageKey, saved);
console.log(`${name} 字体保存路径`, saved);
doLoad(saved);
},
fail: (err) => {
console.error(`保存 ${name} 文件失败`, err);
// Fallback: 尝试加载临时路径
doLoad(res.tempFilePath);
}
});
} else {
onComplete && onComplete();
}
},
fail: (err) => {
console.error(`下载 ${name} 字体失败`, err);
onComplete && onComplete();
}
});
}
// #endif
};
loadSingleFont(fontUrl, 'WangZheFont', 'wangzhe_font_path', checkAllLoaded);
loadSingleFont(fontUrl2, 'WangZheFont2', 'wangzhe_font2_path', checkAllLoaded);
})
const finalPosterPath = ref('');
const editPopup = ref(null);
const tempData = reactive({});
const newAvatars = ref([]);
function handleChangeTheme(typeIndex) {
// 切换主题时,先清空旧海报,触发界面“加载中”提示
finalPosterPath.value = '';
honorData.type = typeIndex;
uni.setStorageSync('wangzheHonorData', honorData);
}
function onRightClick() {
Object.assign(tempData, honorData);
newAvatars.value = [];
editPopup.value.open();
}
const handleChooseAvatar = () => {
uni.chooseImage({
count: 1,
crop: {
quality: 100,
width: 400,
height: 400
},
success: (res) => {
const tempPath = res.tempFilePaths[0];
// #ifndef H5
uni.saveFile({
tempFilePath: tempPath,
success: (saveRes) => {
tempData.avatar = saveRes.savedFilePath;
newAvatars.value.push(saveRes.savedFilePath);
}
});
// #endif
// #ifdef H5
tempData.avatar = tempPath;
// #endif
}
});
};
const handleDeleteAvatar = () => {
tempData.avatar = '';
};
function closeEditPopup() {
// #ifndef H5
newAvatars.value.forEach(path => {
uni.removeSavedFile({ filePath: path });
});
// #endif
editPopup.value.close();
}
function confirmEdit() {
const isNicknameChanged = honorData.nickname !== tempData.nickname;
// #ifndef H5
// 删除多余的新上传文件
newAvatars.value.forEach(path => {
if (path !== tempData.avatar) {
uni.removeSavedFile({ filePath: path });
}
});
// 删除被替换掉的原本地头像
if (honorData.avatar !== tempData.avatar && honorData.avatar && !honorData.avatar.startsWith('/static/')) {
uni.removeSavedFile({ filePath: honorData.avatar });
}
// #endif
Object.assign(honorData, tempData);
uni.setStorageSync('wangzheHonorData', honorData);
editPopup.value.close();
// 数据修改后,清空旧海报触发“加载中”提示,等待重新生成
finalPosterPath.value = '';
// 如果昵称改变了,需要重新绘制原生的渐变文字
if (isNicknameChanged && isFontLoaded.value) {
drawGradientText();
}
}
// 点击画布触发横向预览
const handlePreview = () => {
if (!finalPosterPath.value) {
uni.showToast({ title: '海报仍在生成中,请稍候', icon: 'none' });
return;
}
showPreview.value = true;
}
// 画布生成成功后触发,保存最终的海报路径
const onPainterSuccess = (path) => {
finalPosterPath.value = path;
}
// 点击保存按钮,将带有渐变字体的最终图片存入相册
const handleSave = () => {
if (!finalPosterPath.value) {
uni.showToast({ title: '图片仍在生成中,请稍候', icon: 'none' })
return
}
uni.saveImageToPhotosAlbum({
filePath: finalPosterPath.value,
success: () => {
uni.showToast({ title: '保存成功', icon: 'success' })
},
fail: () => {
uni.showToast({ title: '保存失败', icon: 'none' })
}
})
}
onMounted(() => {
isMountedReady.value = true;
if (isFontLoaded.value) {
drawGradientText();
}
})
// 原生 Canvas 绘制渐变文本导出为图片
const drawGradientText = () => {
// 以较大的像素绘制以保证生成的图片清晰
const fontSize = 40;
const textLen = honorData.nickname.length;
// 文本的实际像素宽度
const canvasWidth = fontSize * textLen;
const ctx = uni.createCanvasContext('gradientTextCanvas', instance.proxy);
ctx.clearRect(0, 0, 300, 60);
// 设置粗体与字号,使用指定的 WangZheFont 字体
ctx.font = `${fontSize}px "WangZheFont", sans-serif`;
// 原生创建横向线性渐变
const grd = ctx.createLinearGradient(0, 0, canvasWidth, 0);
grd.addColorStop(0, '#F9D577');
grd.addColorStop(1, '#FFF5C4');
ctx.setFillStyle(grd);
ctx.setTextBaseline('top');
// 绘制文字
ctx.fillText(honorData.nickname, 0, 0);
ctx.draw(false, () => {
// 稍微延迟确保绘制完毕
setTimeout(() => {
uni.canvasToTempFilePath({
canvasId: 'gradientTextCanvas',
x: 0,
y: 0,
width: canvasWidth,
height: fontSize + 10,
destWidth: canvasWidth * 2, // 2倍图保证海报中的清晰度
destHeight: (fontSize + 10) * 2,
success: (res) => {
nicknameImage.value = res.tempFilePath;
}
}, instance.proxy)
}, 200)
})
}
</script>
<style lang="less" scoped>
.preview-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #000;
z-index: 99999;
/* 抛弃 flex 布局,防止 width: 100vh 被父级限制而发生坍缩 */
}
.preview-overlay .preview-image {
position: absolute;
top: 50%;
left: 50%;
width: 100vh;
height: 100vw;
/* 先拉回自身中心点,再围绕中心点旋转 90 度 */
transform: translate(-50%, -50%) rotate(90deg);
}
.honor-of-kings {
width: 100%;
overflow-x: hidden;
}
.painter-container {
/* 强制画板缩放到设备屏幕宽度,避免物理 px 超出屏幕 */
padding: 8px;
zoom: calc(100vw / 798);
width: 100%;
max-width: 1000px;
/* 限制PC/iPad端的最大宽度 */
margin: 0 auto;
}
.save-action {
margin-top: 60rpx;
display: flex;
flex-direction: column;
align-items: center;
padding-bottom: 220rpx;
/* 留出底部主题固定栏的安全空间 */
.save-btn {
margin-top: 60rpx;
width: 316rpx;
background: #1777FF;
color: #fff;
border-radius: 56rpx;
}
}
.theme-selector {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
padding-top: 20rpx;
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
z-index: 99;
.theme-scroll {
width: 100%;
white-space: nowrap;
::-webkit-scrollbar {
display: none;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
}
}
.theme-list {
display: inline-block;
padding: 0 20rpx;
.theme-item {
display: inline-flex;
vertical-align: top;
margin: 0 10rpx;
padding: 0 40rpx;
height: 84rpx;
border-radius: 12rpx;
background-color: #FFFFFF;
justify-content: center;
align-items: center;
border: 2rpx solid transparent;
box-sizing: border-box;
transition: all 0.3s;
&.active {
background-color: #fff;
border-color: #3B7BFF;
.theme-text {
color: #3B7BFF;
font-weight: bold;
}
}
.theme-text {
font-size: 28rpx;
color: #666;
}
}
}
}
.edit-popup-content {
background-color: #fff;
border-radius: 20rpx;
width: 85vw;
.popup-header {
display: flex;
justify-content: center;
align-items: center;
padding: 40rpx 0 20rpx 0;
.title {
font-size: 34rpx;
font-weight: bold;
color: #333;
}
}
.popup-scroll {
height: 55vh;
padding: 20rpx 40rpx;
box-sizing: border-box;
}
.form-item {
display: flex;
align-items: center;
margin-bottom: 16rpx;
padding-bottom: 16rpx;
.label {
width: 200rpx;
font-size: 28rpx;
color: #333;
}
.avatar-uploader {
display: flex;
align-items: center;
.upload-btn {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
background-color: #999DA7;
display: flex;
justify-content: center;
align-items: center;
.plus {
font-size: 60rpx;
color: #fff;
font-weight: 300;
margin-top: -6rpx;
}
}
.avatar-preview {
position: relative;
width: 100rpx;
height: 100rpx;
.preview-img {
width: 100%;
height: 100%;
border-radius: 50%;
}
.delete-icon {
position: absolute;
top: -4rpx;
right: -4rpx;
width: 32rpx;
height: 32rpx;
background-color: red;
color: #fff;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
font-size: 30rpx;
line-height: 28rpx;
}
}
}
.input {
flex: 1;
font-size: 28rpx;
background-color: #F7F7F7;
border-radius: 12rpx;
height: 70rpx;
line-height: 70rpx;
padding: 0 20rpx;
color: #333;
}
.radio-group {
display: flex;
align-items: center;
gap: 40rpx;
.radio-item {
display: flex;
align-items: center;
cursor: pointer;
.radio-icon {
width: 28rpx;
height: 28rpx;
border-radius: 50%;
border: 2rpx solid #d9d9d9;
margin-right: 12rpx;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
&.active {
border-color: #3B7BFF;
&::after {
content: '';
width: 14rpx;
height: 14rpx;
border-radius: 50%;
background-color: #3B7BFF;
}
}
}
.radio-text {
font-size: 28rpx;
color: #666;
&.active {
color: #3B7BFF;
}
}
}
}
}
.popup-footer {
display: flex;
justify-content: space-between;
padding: 20rpx 40rpx 40rpx;
button {
width: 46%;
height: 76rpx;
line-height: 76rpx;
font-size: 30rpx;
border-radius: 12rpx;
margin: 0;
&::after {
border: none;
}
}
.cancel-btn {
background-color: #F4F4F4;
color: #666;
}
.confirm-btn {
background-color: #3B7BFF;
color: #fff;
}
}
}
</style>