894 lines
21 KiB
Vue
894 lines
21 KiB
Vue
<template>
|
||
<!-- 水印 -->
|
||
<view v-if="$isVip()">
|
||
<watermark :dark="data.dark" />
|
||
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')">
|
||
<c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie>
|
||
</liu-drag-button>
|
||
</view>
|
||
<view class="page-container">
|
||
<view class="main-container">
|
||
<NavBar v-if="!selectedImage" title="花呗" :bgColor="data.navBar.bgColor" :buttonGroup="buttonGroup"
|
||
@button-click="clickTitlePopupButton">
|
||
<!-- 使用作用域插槽自定义按钮渲染,特别是switch的checked绑定 -->
|
||
<template #button="{ button }">
|
||
<view class="button flex-align-center flex-justify-center">
|
||
{{ button.name }}
|
||
<view @tap.stop>
|
||
<switch v-if="button.isSwitch" :checked="data.huabeiInfo.isOverdue" @change="button.click"
|
||
style="transform: scale(0.7);"></switch>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<view class="nav-bar flex-between w100" :class="{ 'ios-nav-bar': $system == 'iOS' }">
|
||
<view class="flex-align-center flex-1">
|
||
<view class="left flex-align-center" @click.stop="goBack">
|
||
<image class=" back-icon" src="/static/image/nav-bar/back-white.png" mode="">
|
||
</image>
|
||
</view>
|
||
<view class="title flex-align-center">
|
||
花呗
|
||
</view>
|
||
</view>
|
||
|
||
<view class="right">
|
||
<image class="icon" src="/static/image/ant-credit-pay/service.png"></image>
|
||
<image class="icon" src="/static/image/ant-credit-pay/setting.png"></image>
|
||
</view>
|
||
</view>
|
||
</NavBar>
|
||
<NavBar v-else title="拼图" bgColor="#EFEFEF" noBack @back="closeImage" isRightButton
|
||
@right-click="confirmImage">
|
||
</NavBar>
|
||
<view v-if="huabeiInfo.styleType == 1" class="current-month">{{ huabeiInfo.mouth }}月应还(元)</view>
|
||
<view v-else class="current-month">{{ huabeiInfo.mouth }}月账单累计中(元)</view>
|
||
<view class="money-box flex-align-center">
|
||
<text class="money alipay-font">{{ numberUtil.formatMoneyWithThousand(huabeiInfo.money) }}</text>
|
||
<uni-icons type="right" size="16" color="#B9D6FF"></uni-icons>
|
||
</view>
|
||
<!-- 样式一 按钮样式 -->
|
||
<view v-if="huabeiInfo.styleType == 1 || !huabeiInfo.styleType" class="style-1 button-group">
|
||
<view class="button-item second-button" :class="{ 'ios-button': $system == 'iOS' }">立即还款</view>
|
||
<view v-if="!huabeiInfo.isInstallment" class="button-item primary-button"
|
||
:class="{ 'ios-button': $system == 'iOS' }">
|
||
分期还款
|
||
<view v-if="huabeiInfo.installmentBadgeText" class="badge">{{ huabeiInfo.installmentBadgeText }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 样式二 纯气泡样式 -->
|
||
<view v-if="huabeiInfo.styleType == 2" class="style-2 bubble-container">
|
||
<view class="bubble-box">
|
||
<view class="arrow"></view>
|
||
<text class="text">{{ huabeiInfo.descText }}</text>
|
||
</view>
|
||
</view>
|
||
<!-- 样式三 气泡带箭头样式 -->
|
||
<view v-if="huabeiInfo.styleType == 3" class="style-3 bubble-container">
|
||
<view class="bubble-box">
|
||
<view class="arrow"></view>
|
||
<text class="text flex-align-center">{{ huabeiInfo.descText }}
|
||
<uni-icons type="right" size="16" color="#B9D6FF"></uni-icons>
|
||
</text>
|
||
</view>
|
||
</view>
|
||
<view class="total-info-box flex-align-center">
|
||
<view class="info-item">
|
||
<view class="label">总计账单</view>
|
||
<view class="value">还款日每月{{ huabeiInfo.dueDate }}日</view>
|
||
</view>
|
||
<view class="info-item">
|
||
<view class="label">总计额度</view>
|
||
<view class="value">{{
|
||
numberUtil.formatMoneyWithThousand(Number(huabeiInfo.totalAmount) - Number(huabeiInfo.money))
|
||
}}可用
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view v-if="!selectedImage" class="image-box flex-1 flex-align-center flex-column flex-justify-center"
|
||
@touchstart="handleTouchStart" @touchend="handleTouchEnd">
|
||
<view v-if="!huabeiInfo.image" class="flex-align-center flex-column">
|
||
<image style="width:92rpx; height: 92rpx;margin-top: 16rpx;"
|
||
src="/static/image/common/upload-screenshot.png">
|
||
</image>
|
||
<text style="font-size: 36rpx;color: #1777FF;">长按替换真实截图</text>
|
||
</view>
|
||
<view v-else class="w100 h100">
|
||
<image class="w100 h100" :src="huabeiInfo.image" mode="widthFix"></image>
|
||
</view>
|
||
</view>
|
||
<view v-else class="scroll-image-box flex-1">
|
||
<scroll-view class="image-box h100" style="width: 100%;" scroll-y :show-scrollbar="false"
|
||
@scroll="onImageScroll">
|
||
<image class="crop-image-target" style="width:100%;" :src="selectedImage" mode="widthFix"></image>
|
||
</scroll-view>
|
||
|
||
<view class="dashed-line-box">
|
||
<view class="dashed-line-text">我是分割线</view>
|
||
</view>
|
||
</view>
|
||
<canvas canvas-id="crop-canvas"
|
||
style="position: fixed; left: -9999px; width: 750rpx; height: 100vh; pointer-events: none;"></canvas>
|
||
<!-- 编辑弹窗 -->
|
||
<uni-popup ref="popup" type="center" :mask-click="false">
|
||
<view class="popup-content">
|
||
<view class="popup-title">编辑花呗数据</view>
|
||
<view class="form-item">
|
||
<text class="label">还款月份</text>
|
||
<picker :range="monthRange" :value="editHuabeiInfo.mouth - 1" @change="onMonthChange"
|
||
style="flex:1">
|
||
<view class="input">{{ editHuabeiInfo.mouth ? editHuabeiInfo.mouth + '月' : '请选择月份' }}</view>
|
||
</picker>
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="label">本月应还</text>
|
||
<input class="input" type="digit" v-model="editHuabeiInfo.money" placeholder="请输入金额" />
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="label">还款日</text>
|
||
<input class="input" type="number" v-model="editHuabeiInfo.dueDate" placeholder="请输入日期" />
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="label">总计额度</text>
|
||
<input class="input" type="digit" v-model="editHuabeiInfo.totalAmount" placeholder="请输入总计额度" />
|
||
</view>
|
||
<view v-if="huabeiInfo.styleType != 1" class="form-item">
|
||
<text class="label">气泡文本</text>
|
||
<input class="input" type="text" v-model="editHuabeiInfo.descText" placeholder="请输入描述文本" />
|
||
</view>
|
||
<view v-if="huabeiInfo.styleType == 1 && !editHuabeiInfo.isInstallment" class="form-item">
|
||
<text class="label">分期气泡</text>
|
||
<input class="input" type="text" v-model="editHuabeiInfo.installmentBadgeText"
|
||
placeholder="请输入分期还款气泡文案" />
|
||
</view>
|
||
<view v-if="huabeiInfo.styleType == 1" class="form-item flex-between">
|
||
<text class="label">是否分期</text>
|
||
<switch :checked="editHuabeiInfo.isInstallment" style="transform: scale(0.8);"
|
||
@change="e => editHuabeiInfo.isInstallment = e.detail.value" />
|
||
</view>
|
||
<view class="popup-btns">
|
||
<view class="btn cancel" @click="closeDialog">取消</view>
|
||
<view class="btn confirm" @click="confirmDialog">确定</view>
|
||
</view>
|
||
</view>
|
||
|
||
</uni-popup>
|
||
|
||
<!-- 样式选择弹窗 -->
|
||
<uni-popup ref="stylePopup" type="center">
|
||
<view class="popup-content">
|
||
<view class="popup-title">选择展示样式</view>
|
||
<view class="style-list">
|
||
<view class="style-item" v-for="(item, index) in styleList" :key="index"
|
||
@click="confirmStyleDialog(item.value)">
|
||
<text>{{ item.label }}</text>
|
||
<uni-icons v-if="huabeiInfo.styleType == item.value" type="checkmarkempty" size="20"
|
||
color="#1777FF"></uni-icons>
|
||
</view>
|
||
</view>
|
||
<view class="popup-btns">
|
||
<view class="btn cancel" @click="closeStyleDialog">取消</view>
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
<!-- 蒙层 -->
|
||
<view v-if="showMask" class="mask" @click="closeMask">
|
||
<image class="mask-icon" src="/static/image/common/mask-icon.png" mode="widthFix">
|
||
</image>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import NavBar from '@/components/nav-bar/nav-bar'
|
||
import {
|
||
numberUtil,
|
||
util
|
||
} from '@/utils/common.js'
|
||
import {
|
||
ref,
|
||
toRefs,
|
||
getCurrentInstance,
|
||
reactive
|
||
} from 'vue';
|
||
import {
|
||
onLoad,
|
||
onShow
|
||
} from '@dcloudio/uni-app';
|
||
|
||
const instance = getCurrentInstance();
|
||
const { proxy } = instance;
|
||
|
||
|
||
const buttonGroup = [{
|
||
name: "编辑花呗数据",
|
||
click: () => {
|
||
openDialog()
|
||
}
|
||
}, {
|
||
name: "切换展示样式",
|
||
click: () => {
|
||
openStyleDialog()
|
||
}
|
||
}, {
|
||
name: "删除当前底部图片",
|
||
click: () => {
|
||
data.huabeiInfo.image = ""
|
||
uni.setStorageSync(data.huabeiInfoStorageKey, data.huabeiInfo)
|
||
}
|
||
}, {
|
||
name: "花呗逾期",
|
||
isSwitch: true,
|
||
click: () => {
|
||
data.huabeiInfo.isOverdue = !data.huabeiInfo.isOverdue
|
||
uni.setStorageSync(data.huabeiInfoStorageKey, data.huabeiInfo)
|
||
if (data.huabeiInfo.isOverdue) {
|
||
uni.redirectTo({
|
||
url: '/pages/ant-credit-pay/overdue-payment/overdue-payment'
|
||
})
|
||
}
|
||
}
|
||
}]
|
||
|
||
const data = reactive({
|
||
navBar: {
|
||
bgColor: "#1777FF",
|
||
textColor: "#fff"
|
||
},
|
||
huabeiInfoStorageKey: 'huabei_info_storage',
|
||
huabeiInfo: {
|
||
mouth: 1,
|
||
money: 100,
|
||
dueDate: 15,
|
||
totalAmount: 200000,
|
||
descText: "当前账单进度已超出预期,花超了",
|
||
isInstallment: false,
|
||
styleType: 1,
|
||
installmentBadgeText: '4折起',
|
||
image: "",
|
||
isOverdue: false,
|
||
daysPastDue: 1
|
||
},
|
||
selectedImage: '',
|
||
showMask: false
|
||
})
|
||
|
||
let {
|
||
huabeiInfo,
|
||
selectedImage,
|
||
showMask
|
||
} = toRefs(data)
|
||
// 编辑表单数据
|
||
const editHuabeiInfo = ref({})
|
||
|
||
const popup = ref(null)
|
||
const stylePopup = ref(null)
|
||
|
||
const scrollTop = ref(0)
|
||
const onImageScroll = (e) => {
|
||
scrollTop.value = e.detail.scrollTop
|
||
}
|
||
|
||
const styleList = [{
|
||
label: '样式 1 (默认)',
|
||
value: 1
|
||
},
|
||
{
|
||
label: '样式 2 (纯气泡)',
|
||
value: 2
|
||
},
|
||
{
|
||
label: '样式 3 (带箭头气泡)',
|
||
value: 3
|
||
}
|
||
]
|
||
|
||
const monthRange = Array.from({
|
||
length: 12
|
||
}, (_, i) => i + 1)
|
||
const onMonthChange = (e) => {
|
||
editHuabeiInfo.value.mouth = monthRange[e.detail.value]
|
||
}
|
||
|
||
onLoad((option) => {
|
||
// 进入花呗页面埋点
|
||
proxy.$apiUserEvent('all', {
|
||
type: 'click',
|
||
key: 'huabei',
|
||
value: "花呗"
|
||
})
|
||
console.log(option)
|
||
// 读取缓存
|
||
let savedInfo = uni.getStorageSync(data.huabeiInfoStorageKey)
|
||
// savedInfo.image = ""
|
||
// uni.setStorageSync(data.huabeiInfoStorageKey, savedInfo)
|
||
console.log("savedInfo====", savedInfo)
|
||
if (savedInfo) {
|
||
// 合并默认值,防止旧数据缺少新字段
|
||
data.huabeiInfo = {
|
||
...data.huabeiInfo,
|
||
...savedInfo
|
||
}
|
||
}
|
||
})
|
||
|
||
onShow(() => {
|
||
// #ifdef APP-PLUS
|
||
util.setAndroidSystemBarColor('#ffffff')
|
||
setTimeout(() => {
|
||
plus.navigator.setStatusBarStyle("light");
|
||
}, 500)
|
||
// #endif
|
||
})
|
||
|
||
// 打开弹窗
|
||
const openDialog = () => {
|
||
// 深拷贝当前数据到编辑表单
|
||
editHuabeiInfo.value = JSON.parse(JSON.stringify(data.huabeiInfo))
|
||
popup.value.open()
|
||
}
|
||
|
||
// 关闭弹窗
|
||
const closeDialog = () => {
|
||
popup.value.close()
|
||
}
|
||
|
||
// 确认修改
|
||
const confirmDialog = () => {
|
||
// 校验数据: 本月应还不能大于总计额度
|
||
if (Number(editHuabeiInfo.value.money) > Number(editHuabeiInfo.value.totalAmount)) {
|
||
uni.showToast({
|
||
title: '本月应还不能大于总计额度',
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
data.huabeiInfo = JSON.parse(JSON.stringify(editHuabeiInfo.value))
|
||
// 保存到缓存
|
||
uni.setStorageSync(data.huabeiInfoStorageKey, data.huabeiInfo)
|
||
popup.value.close()
|
||
uni.showToast({
|
||
title: '保存成功',
|
||
icon: 'success'
|
||
})
|
||
}
|
||
|
||
// 打开样式选择弹窗
|
||
const openStyleDialog = () => {
|
||
stylePopup.value.open()
|
||
}
|
||
|
||
// 关闭样式选择弹窗
|
||
const closeStyleDialog = () => {
|
||
stylePopup.value.close()
|
||
}
|
||
|
||
// 确认图片裁剪
|
||
const confirmImage = () => {
|
||
uni.showLoading({
|
||
title: '处理中...'
|
||
})
|
||
const query = uni.createSelectorQuery().in(instance)
|
||
|
||
// 获取容器和图片信息
|
||
query.select('.image-box').boundingClientRect()
|
||
query.select('.crop-image-target').boundingClientRect()
|
||
query.exec(res => {
|
||
if (!res[0] || !res[1]) {
|
||
uni.hideLoading()
|
||
return
|
||
}
|
||
|
||
console.log('rects', res)
|
||
const container = res[0] // 容器
|
||
const image = res[1] // 图片实际渲染尺寸
|
||
|
||
// 计算缩放比例 (渲染宽度 / 实际宽度 不准确,应该反过来用 图片原始宽/渲染宽?)
|
||
// 这里更简单的方法是:canvas设为容器大小,把图片画进去
|
||
// canvas drawImage 参数: img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight
|
||
|
||
// 获取图片原始尺寸
|
||
uni.getImageInfo({
|
||
src: selectedImage.value,
|
||
success: (imgInfo) => {
|
||
const scale = imgInfo.width / image.width // 图片 原始宽 / 渲染宽
|
||
const sTop = scrollTop.value * scale // 原始图上的裁切起始Y
|
||
const sHeight = container.height * scale // 原始图上的裁切高度
|
||
|
||
// 因为是 widthFix,宽度就是原始图宽度(或裁切全宽)
|
||
const sWidth = imgInfo.width
|
||
|
||
// 设置画布尺寸 (使用像素值)
|
||
// 注意:canvasContext绘制使用的是逻辑像素还是物理像素?通常需要考虑到 pixelRatio,
|
||
// 但 uni-app canvas-id 方式通常对应逻辑像素(px)
|
||
// 我们把 canvas 大小设为和容器显示一致
|
||
const canvasW = container.width
|
||
const canvasH = container.height
|
||
|
||
const ctx = uni.createCanvasContext('crop-canvas', instance)
|
||
|
||
// 清除画布
|
||
ctx.clearRect(0, 0, canvasW, canvasH)
|
||
|
||
// 绘制
|
||
// drawImage(imageResource, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
|
||
ctx.drawImage(
|
||
imgInfo.path,
|
||
0, sTop, sWidth, sHeight, // 源图裁剪区域
|
||
0, 0, canvasW, canvasH // 画布绘制区域
|
||
)
|
||
ctx.draw(false, () => {
|
||
uni.canvasToTempFilePath({
|
||
canvasId: 'crop-canvas',
|
||
width: canvasW,
|
||
height: canvasH,
|
||
destWidth: sWidth, // 使用原图实际宽度,保持原图清晰度
|
||
destHeight: sHeight, // 使用原图实际高度,保持原图清晰度
|
||
success: (res) => {
|
||
console.log('crop success (temp)', res
|
||
.tempFilePath)
|
||
|
||
// 将临时路径保存为永久路径
|
||
uni.saveFile({
|
||
tempFilePath: res.tempFilePath,
|
||
success: (saveRes) => {
|
||
console.log('save success (saved)', saveRes.savedFilePath)
|
||
data.huabeiInfo.image = saveRes.savedFilePath
|
||
selectedImage.value = '' // 隐藏编辑模式
|
||
setTimeout(() => {
|
||
plus.navigator.setStatusBarStyle("light");
|
||
}, 200)
|
||
// 保存到缓存
|
||
uni.setStorageSync(data.huabeiInfoStorageKey, data.huabeiInfo)
|
||
uni.hideLoading()
|
||
},
|
||
fail: (err) => {
|
||
console.error('saveFile fail', err)
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: '保存失败',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
})
|
||
},
|
||
fail: (err) => {
|
||
console.error(err)
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: '裁剪失败',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
}, instance)
|
||
})
|
||
},
|
||
fail: () => {
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: '图片加载失败',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
})
|
||
|
||
})
|
||
}
|
||
|
||
// 确认样式选择
|
||
const confirmStyleDialog = (type) => {
|
||
data.huabeiInfo.styleType = type
|
||
// 保存到缓存
|
||
uni.setStorageSync(data.huabeiInfoStorageKey, data.huabeiInfo)
|
||
stylePopup.value.close()
|
||
}
|
||
|
||
const clickTitlePopupButton = (button) => {
|
||
button.click()
|
||
}
|
||
|
||
// 选择图片
|
||
const chooseImage = () => {
|
||
if (selectedImage.value) return
|
||
uni.chooseImage({
|
||
count: 1,
|
||
sourceType: ['album'],
|
||
success: (res) => {
|
||
selectedImage.value = res.tempFilePaths[0]
|
||
data.showMask = true
|
||
setTimeout(() => {
|
||
plus.navigator.setStatusBarStyle("dark");
|
||
}, 500)
|
||
}
|
||
})
|
||
}
|
||
|
||
// 长按事件定时器
|
||
let longPressTimer = null
|
||
const handleTouchStart = (e) => {
|
||
// 兼容iOS上滑HOME条,如果有底部安全区且触摸位置在底部安全区内,则不触发
|
||
const systemInfo = uni.getSystemInfoSync()
|
||
if (systemInfo.platform === 'ios' && systemInfo.safeAreaInsets?.bottom) {
|
||
const clientY = e.touches[0].clientY
|
||
const windowHeight = systemInfo.windowHeight
|
||
// 如果触摸点在底部安全区范围内(通常是34px),则忽略
|
||
if (clientY > windowHeight - systemInfo.safeAreaInsets.bottom) {
|
||
return
|
||
}
|
||
}
|
||
|
||
longPressTimer = setTimeout(() => {
|
||
uni.vibrateShort()
|
||
chooseImage()
|
||
}, 1200) // 长按时间大于1s
|
||
}
|
||
|
||
|
||
const handleTouchEnd = () => {
|
||
if (longPressTimer) {
|
||
clearTimeout(longPressTimer)
|
||
longPressTimer = null
|
||
}
|
||
}
|
||
|
||
const closeImage = () => {
|
||
selectedImage.value = ''
|
||
data.showMask = false
|
||
plus.navigator.setStatusBarStyle("light");
|
||
return false
|
||
}
|
||
|
||
const closeMask = () => {
|
||
data.showMask = false
|
||
}
|
||
|
||
const goBack = () => {
|
||
uni.navigateBack()
|
||
}
|
||
</script>
|
||
|
||
<style>
|
||
@import "/common/main.css";
|
||
</style>
|
||
|
||
<style lang="less" scoped>
|
||
.page-container {
|
||
position: relative;
|
||
display: flex;
|
||
flex-direction: column;
|
||
background-color: #ffffff;
|
||
height: 100vh;
|
||
overflow: hidden;
|
||
|
||
.nav-bar {
|
||
height: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 0 20rpx;
|
||
|
||
.left {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.title {
|
||
color: #ffffff;
|
||
font-size: 17px;
|
||
font-weight: 500;
|
||
text-align: center;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.right {
|
||
width: 80px;
|
||
}
|
||
|
||
.icon {
|
||
margin-left: 18rpx;
|
||
margin-right: 10rpx;
|
||
width: 24px;
|
||
height: 24px;
|
||
}
|
||
}
|
||
|
||
.ios-nav-bar {
|
||
.left {
|
||
width: 80px;
|
||
}
|
||
|
||
.title {
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.right {
|
||
width: 80px;
|
||
}
|
||
}
|
||
|
||
.main-container {
|
||
background-color: #1777FF;
|
||
padding-bottom: 32rpx;
|
||
// position: absolute;
|
||
// top: 0;
|
||
// left: 0;
|
||
// right: 0;
|
||
// z-index: 99;
|
||
|
||
.current-month {
|
||
margin-top: 12rpx;
|
||
color: #B9D6FF;
|
||
font-size: 24rpx;
|
||
text-align: center;
|
||
}
|
||
|
||
.money-box {
|
||
text-align: center;
|
||
justify-content: center;
|
||
|
||
.money {
|
||
font-size: 64rpx;
|
||
color: #ffffff;
|
||
}
|
||
}
|
||
|
||
.button-group {
|
||
margin-top: 18rpx;
|
||
display: flex;
|
||
justify-content: center;
|
||
justify-content: center;
|
||
|
||
.button-item {
|
||
height: 64rpx;
|
||
line-height: 64rpx;
|
||
border-radius: 8rpx;
|
||
color: #ffffff;
|
||
font-size: 30rpx;
|
||
padding: 0 24rpx;
|
||
}
|
||
|
||
.second-button {
|
||
border: 2rpx solid #66B2FD;
|
||
}
|
||
|
||
.primary-button {
|
||
background-color: #66B2FD;
|
||
margin: 0 22rpx;
|
||
position: relative;
|
||
|
||
.badge {
|
||
position: absolute;
|
||
top: -16rpx;
|
||
right: -10rpx;
|
||
background-color: #F34624;
|
||
color: #fff;
|
||
font-size: 20rpx;
|
||
padding: 0 10rpx;
|
||
height: 32rpx;
|
||
line-height: 32rpx;
|
||
border-radius: 16rpx 16rpx 16rpx 0;
|
||
z-index: 1;
|
||
}
|
||
}
|
||
|
||
.ios-button {
|
||
border-radius: 33rpx !important;
|
||
}
|
||
}
|
||
|
||
.style-1 {
|
||
margin-top: 18rpx;
|
||
display: flex;
|
||
justify-content: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.bubble-container {
|
||
margin-top: 10rpx;
|
||
display: flex;
|
||
justify-content: center;
|
||
|
||
.bubble-box {
|
||
position: relative;
|
||
border: 1px solid #75bcff;
|
||
border-radius: 30rpx;
|
||
padding: 12rpx 24rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.text {
|
||
color: #ffffff;
|
||
font-size: 26rpx;
|
||
line-height: 1.2;
|
||
}
|
||
|
||
.arrow {
|
||
position: absolute;
|
||
top: -5px;
|
||
left: 50%;
|
||
transform: translateX(-50%) rotate(45deg);
|
||
width: 8px;
|
||
height: 8px;
|
||
background-color: #1777FF;
|
||
border-left: 1px solid #75bcff;
|
||
border-top: 1px solid #75bcff;
|
||
z-index: 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
.total-info-box {
|
||
margin-top: 48rpx;
|
||
|
||
.info-item {
|
||
width: 50%;
|
||
text-align: center;
|
||
|
||
.label {
|
||
color: #ffffff;
|
||
font-size: 30rpx;
|
||
line-height: 42rpx;
|
||
}
|
||
|
||
.value {
|
||
color: #ffffff;
|
||
font-size: 26rpx;
|
||
line-height: 36rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.image-box {
|
||
width: 100%;
|
||
overflow: hidden; // scroll-view 需要
|
||
}
|
||
|
||
.scroll-image-box {
|
||
width: 100%;
|
||
min-height: 0; // 修复 flex一出问题
|
||
// overflow: hidden; // scroll-view 需要
|
||
position: relative;
|
||
}
|
||
|
||
.dashed-line-box {
|
||
width: 100%;
|
||
height: 100%;
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
border: 4rpx dashed #ffffff;
|
||
pointer-events: none;
|
||
|
||
.dashed-line-text {
|
||
height: 44rpx;
|
||
line-height: 44rpx;
|
||
width: 180rpx;
|
||
padding: 0 20rpx;
|
||
border-radius: 8rpx;
|
||
color: #1777FF;
|
||
font-size: 24rpx;
|
||
font-weight: 500;
|
||
background-color: #fff;
|
||
position: absolute;
|
||
top: 0;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
}
|
||
}
|
||
|
||
.mask {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background-color: rgba(0, 0, 0, 0.8);
|
||
z-index: 999;
|
||
|
||
.mask-icon {
|
||
position: absolute;
|
||
top: 50%;
|
||
right: 52rpx;
|
||
transform: translateY(-25%);
|
||
width: 360rpx;
|
||
height: 360rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.back-icon {
|
||
width: 24px;
|
||
height: 24px;
|
||
}
|
||
</style>
|
||
|
||
<style lang="scss" scoped>
|
||
.popup-content {
|
||
background-color: #fff;
|
||
width: 600rpx;
|
||
border-radius: 16rpx;
|
||
padding: 30rpx;
|
||
|
||
.popup-title {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
text-align: center;
|
||
margin-bottom: 30rpx;
|
||
}
|
||
|
||
.form-item {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 24rpx;
|
||
|
||
.label {
|
||
width: 140rpx;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.input {
|
||
flex: 1;
|
||
height: 72rpx;
|
||
line-height: 72rpx;
|
||
background-color: #f5f5f5;
|
||
border-radius: 8rpx;
|
||
padding: 0 20rpx;
|
||
font-size: 28rpx;
|
||
}
|
||
}
|
||
|
||
.flex-between {
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.popup-btns {
|
||
display: flex;
|
||
margin-top: 40rpx;
|
||
|
||
.btn {
|
||
flex: 1;
|
||
height: 80rpx;
|
||
line-height: 80rpx;
|
||
text-align: center;
|
||
border-radius: 12rpx;
|
||
font-size: 30rpx;
|
||
|
||
&.cancel {
|
||
background-color: #f5f5f5;
|
||
color: #666;
|
||
margin-right: 20rpx;
|
||
}
|
||
|
||
&.confirm {
|
||
background-color: #1777FF;
|
||
color: #fff;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
.style-list {
|
||
.style-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 30rpx 0;
|
||
border-bottom: 1px solid #f5f5f5;
|
||
font-size: 30rpx;
|
||
color: #333;
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
}
|
||
}
|
||
</style> |