alipay-emulator/pages/shopping/taobao/list-index.vue

1143 lines
27 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="page-container flex-column">
<view class="top-fixed">
<nav-bar v-if="!selectedImage" title="淘宝" bgColor="#ffffff" :buttonGroup="buttonGroup"
@button-click="util.clickTitlePopupButton" tipLayerType="jingdong-shopping-list" isTipLayer
tipLayerText="添加订单信息">
<template v-slot:left>
<image class="back-icon" src="/static/image/shopping/taobao/back.png" mode="aspectFit"
@click="util.goBack()"></image>
</template>
<template v-slot:center>
<view class="search-box flex-align-center">
<image class="search-icon" src="/static/image/shopping/jingdong/search-icon.png"
mode="aspectFit">
</image>
<input class="input" type="text" placeholder="搜索我的订单" />
</view>
</template>
<template v-slot:right>
<view class="right-box flex-align-center">
<view class="item flex-column flex-align-center">
<image class="icon" src="/static/image/shopping/taobao/shaixuan.png"></image>
<text class="text">筛选</text>
</view>
<view class="item flex-column flex-align-center">
<image class="icon" src="/static/image/shopping/taobao/guanli.png"></image>
<text class="text">管理</text>
</view>
<view class="item flex-column flex-align-center">
<image class="icon" src="/static/image/shopping/taobao/xiaoxi.png"></image>
<text class="text" style="opacity: 0;">消息</text>
</view>
</view>
</template>
</nav-bar>
<nav-bar v-else title="拼图" bgColor="#EFEFEF" noBack @back="closeImage" isRightButton
@right-click="confirmImage">
</nav-bar>
<view class="tab-list">
<view class="tab-item" v-for="(item, index) in tabList" :key="index"
:class="{ active: currentTab === index }" @click="switchTab(index)">
<view class="title">
<text>{{ item.name }}</text>
<view class="line" v-if="currentTab === index"></view>
</view>
<!-- <view class="line" v-if="currentTab === index"></view> -->
<image v-if="item.icon" class="badge-icon" :class="{ 'android-m-top': $system == 'Android' }"
:src="item.icon" mode="heightFix"></image>
</view>
</view>
<view class="filter-wrapper">
<view class="position-l">
<view class="filter-item" :class="{ active: currentFilter === 0 }" @click="switchFilter(0)">
<text class="text">全部</text>
</view>
</view>
<scroll-view class="filter-scroll" scroll-x="true" :show-scrollbar="false">
<view class="filter-list">
<view class="filter-item " v-for="(item, index) in filterList" :key="index"
:class="{ active: currentFilter === index, disabled: item.disabled }"
@click="switchFilter(index)">
<text class="text">{{ item.name }}</text>
</view>
</view>
</scroll-view>
</view>
</view>
<scroll-view class="flex-1" style="height: 100px;" scroll-y="true">
<view v-if="currentTab === 0 && currentFilter === 0"
class="shangou-tips flex-align-center flex-justify-between">
<view class="left flex-align-center">
<image style="width: 64rpx;height: 28rpx;margin-right: 8rpx;"
src="/static/image/shopping/taobao/shangou-logo.png"></image>
<text>暂无进行中订单</text>
</view>
<view class="right">
<text>查看全部</text>
<uni-icons type="right" size="14" color="#5E6367"></uni-icons>
</view>
</view>
<listCard v-if="displayList.length > 0" :list="displayList" @click-item="goDetail"
@longpress="onItemLongPress" />
<view v-else-if="displayList.length == 0 && currentTab != 2" class="null-data-box flex-center flex-column">
<image style="width: 254rpx;height: 200rpx;" src="/static/image/shopping/taobao/null.png"></image>
<text
style="font-size: 28rpx;color: #7C8495;line-height: 28rpx;margin-top: 16rpx;font-weight: 500;">您还没有相关的订单</text>
</view>
<view v-else-if="displayList.length == 0 && currentTab == 2"
class="null-data-box shangou flex-center flex-column">
<image style="width: 254rpx;height: 200rpx;" src="/static/image/shopping/taobao/waimai/null.png">
</image>
<text class="null-text">您还没有闪购订单</text>
<text class="tip-text">时机正好,去闪购逛逛还能抽免单!</text>
<view class="go-btn">去闪购逛逛</view>
</view>
<view class="bottom-fixed" style="height: 1000rpx;">
<view v-if="!selectedImage" class="upload-screenshot-box" @touchstart="handleTouchStart"
@touchend="handleTouchEnd">
<view v-if="!screenshotImage" class="upload-screenshot-content">
<image class="upload-screenshot" src="/static/image/common/upload-screenshot.png"
mode="aspectFit">
</image>
<view class="upload-screenshot-text">长按替换截图</view>
</view>
<view v-else class="screenshot-preview-box">
<image class="screenshot-preview" :src="screenshotImage" mode="widthFix"></image>
</view>
<!-- <image v-else class="w100 h100" :src="screenshotImage" mode="widthFix"></image> -->
</view>
<view v-else class="upload-screenshot-box scroll-image-box">
<scroll-view class="image-box" style="width: 100%;height: 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>
</view>
</scroll-view>
</view>
<!-- 自定义长按上下文菜单 -->
<view v-if="menuState.show" class="menu-mask" @click="menuState.show = false" @touchmove.stop.prevent>
<view class="menu-content" :style="{ top: menuState.y + 'px', left: menuState.x + 'px' }">
<view class="menu-item" @click.stop="handleMenuAction('edit')">
<uni-icons type="compose" size="18" color="#1A1A1A"></uni-icons>
<text>编辑</text>
</view>
<view class="menu-line"></view>
<view class="menu-item" @click.stop="handleMenuAction('delete')">
<uni-icons type="trash" size="18" color="#FF4D4F"></uni-icons>
<text style="color: #FF4D4F;">删除</text>
</view>
</view>
</view>
<!-- 切换底部图片弹窗 -->
<uni-popup ref="bottomImgPopup" type="center">
<view class="bottom-img-popup-card">
<view class="p-header">选择底部商品图</view>
<view class="p-content">
<view class="option-item" @click="selectBottomImg(1)">
<image class="preview-img" src="/static/image/shopping/taobao/bottom-bg-1.png" mode="aspectFill">
</image>
<view class="info">
<text class="name">商品图片 1</text>
<text class="desc">默认背景布局</text>
</view>
<uni-icons type="right" size="16" color="#C7C7CC"></uni-icons>
</view>
<view class="option-item" @click="selectBottomImg(2)">
<image class="preview-img" src="/static/image/shopping/taobao/bottom-bg-2.png" mode="aspectFill">
</image>
<view class="info">
<text class="name">商品图片 2</text>
<text class="desc">备选商品排列</text>
</view>
<uni-icons type="right" size="16" color="#C7C7CC"></uni-icons>
</view>
<text
style="color: #949494;font-size: 24rpx;text-align: center;display: block;">*长按底部商品图片区域可上传自定义图片*</text>
</view>
<view class="p-footer" @click="bottomImgPopup.close()">取消</view>
</view>
</uni-popup>
<!-- 水印 -->
<view v-if="$isVip()">
<watermark dark="light" source="uni_alipay_shopping_taobao" />
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark', 'uni_alipay_shopping_taobao')">
<c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie>
</liu-drag-button>
</view>
</template>
<script setup>
import { ref, computed, getCurrentInstance, reactive } from 'vue';
import { onShow, onLoad } from '@dcloudio/uni-app';
import { util } from '@/utils/common.js';
import listCard from './components/list-card/list-card.vue';
import { defualtData } from './json/order.json'
const { proxy } = getCurrentInstance();
const instance = getCurrentInstance();
const mockList = ref([]);
const menuState = reactive({
show: false,
x: 0,
y: 0,
target: null
});
const bottomImgPopup = ref(null);
const selectBottomImg = (type) => {
const path = `/static/image/shopping/taobao/bottom-bg-${type}.png`;
screenshotImage.value = path;
uni.setStorageSync('taobao_screenshot', path);
bottomImgPopup.value.close();
uni.showToast({
title: '切换成功',
icon: 'success'
});
};
onLoad(() => {
proxy.$apiUserEvent('all', {
type: 'event',
key: 'shopping',
prefix: '.uni.other.',
value: '淘宝'
})
})
onShow(() => {
// #ifdef APP-PLUS
util.setAndroidSystemBarColor('#FFFFFF')
setTimeout(() => {
plus.navigator.setStatusBarStyle("dark");
}, 500);
// #endif
// 加载缓存数据
let storageData = uni.getStorageSync('taobaoShopping');
// 如果缓存为空,则初始化默认数据
if (!storageData || (Array.isArray(storageData) && storageData.length === 0)) {
console.log('检测到淘宝订单缓存为空,注入初始默认数据');
storageData = JSON.parse(JSON.stringify(defualtData));
uni.setStorageSync('taobaoShopping', storageData);
}
mockList.value = storageData || [];
// 加载拼图截图缓存 (若不存在则初始化默认底图)
let savedScreenshot = uni.getStorageSync('taobao_screenshot');
if (!savedScreenshot) {
savedScreenshot = '/static/image/shopping/taobao/bottom-bg-1.png';
uni.setStorageSync('taobao_screenshot', savedScreenshot);
}
screenshotImage.value = savedScreenshot;
});
//导航栏菜单按钮
const buttonGroup = [
{
name: "新增购物订单",
click: () => {
uni.navigateTo({
url: '/pages/shopping/taobao/add-shopping-order/add-shopping-order'
});
}
}, {
name: "新增闪购订单",
click: () => {
uni.showToast({
title: '开发中,敬请期待',
icon: 'none'
});
}
}, {
name: "切换底部商品图片",
click: () => {
bottomImgPopup.value.open();
}
},
]
const displayList = computed(() => {
let list = JSON.parse(JSON.stringify(mockList.value));
// 1. 一级 Tab 过滤 (orderType)
if (currentTab.value === 1) { // 购物
list = list.filter(item => item.orderType === 'shopping');
} else if (currentTab.value === 2) { // 闪购
list = list.filter(item => item.orderType === 'waimai');
}
// 2. 二级分类过滤 (currentFilter)
if (currentFilter.value > 0) {
const filterName = filterList.value[currentFilter.value]?.name;
const statusMap = {
'待付款': ['wait_pay'],
'待发货': ['wait_send'],
'待收货': ['wait_recv'],
'退款/售后': ['refunding'],
'评价': ['success'],
'已关闭': ['closed']
};
const targetStatus = statusMap[filterName];
if (targetStatus) {
list = list.filter(item => targetStatus.includes(item.statusType));
}
}
// 3. 时间降序排列逻辑 (创建时间 || 申请时间)
list.sort((a, b) => {
const getTime = (order) => {
if (!order.orderInfo) return '';
const create = order.orderInfo.find(i => i.key === 'createTime')?.value;
const apply = order.orderInfo.find(i => i.key === 'applyTime')?.value;
return create || apply || '';
};
const timeA = getTime(a);
const timeB = getTime(b);
return timeB.localeCompare(timeA); // 降序
});
return list;
});
const currentFilter = ref(0);
const filterList = ref([
{ name: '全部' },
{ name: '待付款' },
{ name: '待发货' },
{ name: '待收货' },
{ name: '退款/售后' },
{ name: '评价' },
{ name: '已关闭' }
]);
const currentTab = ref(0);
const tabList = ref([
{ name: '全部订单' },
{ name: '购物' },
{ name: '闪购', icon: '/static/image/shopping/taobao/waimai.png' },
{ name: '飞猪', icon: '/static/image/shopping/taobao/lvxing.png', disabled: true }
]);
// 长按替换截图相关
const screenshotImage = ref('');
const selectedImage = ref('');
const scrollTop = ref(0);
let longPressTimer = null;
// 长按替换截图 - 选择图片
const chooseImage = () => {
if (selectedImage.value) return;
uni.chooseImage({
count: 1,
sourceType: ['album'],
success: (res) => {
selectedImage.value = res.tempFilePaths[0];
}
});
};
// 长按事件
const handleTouchStart = (e) => {
const systemInfo = uni.getSystemInfoSync();
if (systemInfo.platform === 'ios' && systemInfo.safeAreaInsets?.bottom) {
const clientY = e.touches[0].clientY;
const windowHeight = systemInfo.windowHeight;
if (clientY > windowHeight - systemInfo.safeAreaInsets.bottom) {
return;
}
}
longPressTimer = setTimeout(() => {
uni.vibrateShort();
chooseImage();
}, 1200);
};
const handleTouchEnd = () => {
if (longPressTimer) {
clearTimeout(longPressTimer);
longPressTimer = null;
}
};
// 图片滚动
const onImageScroll = (e) => {
scrollTop.value = e.detail.scrollTop;
};
// 确认图片裁剪
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)
screenshotImage.value = saveRes.savedFilePath
selectedImage.value = '' // 隐藏编辑模式
setTimeout(() => {
plus.navigator.setStatusBarStyle("light");
}, 200)
// 保存到缓存
uni.setStorageSync('taobao_screenshot', screenshotImage.value)
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 closeImage = () => {
selectedImage.value = '';
};
/**
* 切换tab
* @param index
*/
const switchTab = (index) => {
if (tabList.value[index].disabled) return;
currentTab.value = index;
// 重置筛选为“全部”
currentFilter.value = 0;
// 动态更新筛选项
updateFilterList();
};
/**
* 动态更新筛选项
*/
const updateFilterList = () => {
let sourceList = [];
// 根据tab切换不同的筛选项数据
switch (currentTab.value) {
case 0:
sourceList = ["全部", "待付款", "待发货", "待收货", "退款/售后", "评价", "已关闭"];
break;
case 1:
sourceList = ["全部", "待付款", "待发货", "待收货", "退款/售后", "评价", "已关闭"];
break;
case 2:
sourceList = ["全部", "待付款", "待发货", "待收货", "待评价", "已关闭"];
break;
case 3:
sourceList = ["全部", "全部行程", "已完成", "退款/售后"];
break;
}
filterList.value = sourceList.map((name, index) => ({
name,
disabled: false
}));
};
/**
* 切换筛选
* @param index 索引
*/
const switchFilter = (index) => {
if (filterList.value[index].disabled) return;
if (currentFilter.value === index) {
currentFilter.value = 0;
} else {
currentFilter.value = index;
}
};
const goDetail = (item) => {
util.goPage(`/pages/shopping/taobao/shopping-order-detail/shopping-order-detail?id=${item.id}`)
}
/**
* 长按管理订单 - 记录坐标并显示自定义菜单
*/
const onItemLongPress = (data) => {
const { item, x, y } = data;
menuState.target = item;
// 计算菜单位置,避免手指遮挡(向上偏移 60px向左偏移 40px
// 并简单处理边界溢出(示例:不超出右边界)
const screenWidth = uni.getSystemInfoSync().windowWidth;
let posX = x - 40;
if (posX + 120 > screenWidth) {
posX = screenWidth - 130;
}
menuState.x = Math.max(10, posX);
menuState.y = y - 80;
menuState.show = true;
};
/**
* 处理菜单点击
*/
const handleMenuAction = (action) => {
const item = menuState.target;
menuState.show = false;
if (!item) return;
if (action === 'edit') {
uni.navigateTo({
url: `/pages/shopping/taobao/add-shopping-order/add-shopping-order?id=${item.id}&isEdit=true`
});
} else if (action === 'delete') {
uni.showModal({
title: '提示',
content: '确定要删除该订单吗?',
confirmColor: '#FF7824',
success: (modalRes) => {
if (modalRes.confirm) {
deleteOrder(item.id);
}
}
});
}
};
/**
* 从缓存执行删除
*/
const deleteOrder = (id) => {
let list = uni.getStorageSync('taobaoShopping') || [];
// 1. 物理删除关联图片
const target = list.find(item => String(item.id) === String(id));
if (target) {
const imagesToClear = [];
if (target.goodsList?.[0]?.image) imagesToClear.push(target.goodsList[0].image);
if (target.productImgUrl) imagesToClear.push(target.productImgUrl);
imagesToClear.forEach(path => {
if (path && (path.includes('_doc') || path.includes('store_'))) {
uni.removeSavedFile({
filePath: path,
success: () => console.log('删除订单关联图片成功:', path),
fail: (err) => console.log('图片文件不存在或已删除:', path)
});
}
});
}
// 2. 移除缓存记录
list = list.filter(item => String(item.id) !== String(id));
// 同步缓存
uni.setStorageSync('taobaoShopping', list);
// 同步 UI
mockList.value = list;
uni.showToast({
title: '已删除',
icon: 'success'
});
};
</script>
<style lang="less" scoped>
.page-container {
height: 100vh;
overflow: hidden;
}
.top-fixed {
background-color: #ffffff;
::v-deep .uni-navbar__header-btns {
width: auto !important;
}
::v-deep .uni-navbar__header-container {
padding: 0 14rpx;
padding-left: 34rpx;
}
.back-icon {
width: 40rpx;
height: 40rpx;
}
.search-box {
background-color: #F1F5F8;
padding: 0 18rpx;
width: 100%;
border-radius: 16rpx;
.search-icon {
width: 26rpx;
height: 26rpx;
margin-right: 10rpx;
}
.input {
width: 100%;
height: 72rpx;
font-size: 26rpx;
::v-deep .input-placeholder {
color: #7E8C9D;
}
}
}
.right-box {
.item {
margin: 0 14rpx;
.icon {
width: 40rpx;
height: 40rpx;
}
.text {
font-size: 20rpx;
color: #1A1A1A;
line-height: 20rpx;
margin-top: 4rpx;
}
}
}
.tab-list {
display: flex;
align-items: center;
padding: 16rpx 36rpx 10rpx;
.tab-item {
display: flex;
align-items: center;
margin-right: 58rpx;
.title {
position: relative;
font-size: 30rpx;
color: #00032A;
font-weight: 500;
line-height: 16px !important;
}
&.active {
display: flex;
justify-content: center;
align-items: center;
.title {
color: #EF7518;
}
}
.line {
position: absolute;
bottom: -12rpx;
left: 50%;
transform: translateX(-50%);
width: 22rpx;
height: 4rpx;
background-color: #EF7518;
border-radius: 4rpx;
}
.badge-icon {
margin-left: 6rpx;
width: 52rpx;
height: 14px;
&.android-m-top {
margin-top: -3rpx;
}
}
}
}
.filter-wrapper {
position: relative;
display: flex;
align-items: center;
padding: 0 22rpx 0 30rpx;
margin-top: 28rpx;
padding-bottom: 16rpx;
.filter-scroll {
flex: 1;
width: 0;
white-space: nowrap;
.filter-list {
padding-right: 24rpx;
}
}
.position-l {
position: absolute;
left: 0;
padding-left: 30rpx;
background-color: #ffffff;
z-index: 1;
.filter-item {
margin-right: 10rpx;
}
}
.filter-item {
display: inline-flex;
align-items: center;
justify-content: center;
vertical-align: middle;
height: 56rpx;
padding: 0 22rpx;
background-color: #F1F4F9;
border-radius: 12rpx;
margin-right: 16rpx;
border: 2rpx solid transparent;
box-sizing: border-box;
.text {
font-size: 26rpx;
line-height: 26rpx;
color: #00032A;
}
.close-icon {
font-size: 18px;
color: #E40C24;
margin-top: -4rpx;
line-height: 14px;
margin-left: 6rpx;
font-weight: 400;
}
&.active {
background-color: #FFEEE6;
.text {
color: #EF7518;
}
}
// &.disabled {
// background-color: #F8F8F8;
// border-color: transparent;
// .text {
// color: #CCCCCC;
// }
// }
}
}
}
.shangou-tips {
padding: 28rpx 22rpx 36rpx 32rpx;
background-color: #ffffff;
.left {
height: 28rpx;
text {
font-size: 26rpx;
line-height: 28rpx;
color: #00032A;
font-weight: 500;
}
}
.right {
color: #5E6367;
font-size: 26rpx;
line-height: 28rpx;
text {
margin-right: 10rpx;
}
}
}
.menu-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9999;
background-color: transparent;
}
.menu-content {
position: absolute;
width: 240rpx;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: 16rpx;
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.12);
border: 1px solid rgba(255, 255, 255, 0.2);
overflow: hidden;
animation: menu-show 0.15s ease-out;
}
.menu-item {
display: flex;
align-items: center;
padding: 24rpx 32rpx;
transition: background 0.2s;
&:active {
background-color: #f5f5f5;
}
text {
font-size: 28rpx;
color: #1A1A1A;
margin-left: 16rpx;
font-weight: 500;
}
}
.menu-line {
height: 1px;
background-color: #EEEEEE;
margin: 0 20rpx;
}
@keyframes menu-show {
from {
opacity: 0;
transform: scale(0.9);
}
to {
opacity: 1;
transform: scale(1);
}
}
.null-data-box {
padding: 68rpx;
&.shangou {
.null-text {
font-size: 28rpx;
color: #7C8495;
line-height: 28rpx;
margin-top: 16rpx;
font-weight: 500;
}
.tip-text {
font-size: 30rpx;
color: #A5A8AE;
line-height: 30rpx;
margin-top: 32rpx;
}
.go-btn {
width: 198rpx;
height: 80rpx;
background-color: #FC620B;
border-radius: 12rpx;
color: #FFFFFF;
text-align: center;
line-height: 80rpx;
font-size: 30rpx;
font-weight: 500;
margin-top: 32rpx;
}
}
}
.bottom-fixed {
display: flex;
flex-direction: column;
.upload-screenshot-box {
width: 100%;
flex: 1;
min-height: 540rpx;
background-color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
position: relative;
.upload-screenshot {
width: 92rpx;
height: 92rpx;
}
.upload-screenshot-content {
width: 100%;
height: 100%;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
.upload-screenshot-text {
font-size: 36rpx;
color: #1777FF;
line-height: 50rpx;
margin-top: 16rpx;
}
}
.screenshot-preview-box {
width: 100%;
height: 100%;
display: flex;
align-items: flex-start;
// flex-direction: column;
justify-content: center;
.screenshot-preview {
width: 100%;
height: 100%;
}
}
.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;
}
}
}
}
.bottom-img-popup-card {
width: 600rpx;
background-color: #FFFFFF;
border-radius: 32rpx;
overflow: hidden;
box-shadow: 0 20rpx 40rpx rgba(0, 0, 0, 0.15);
.p-header {
padding: 40rpx 0 20rpx;
text-align: center;
font-size: 32rpx;
font-weight: 600;
color: #1A1A1A;
}
.p-content {
padding: 20rpx 30rpx;
.option-item {
display: flex;
align-items: center;
padding: 24rpx;
margin-bottom: 20rpx;
background-color: #F8F9FA;
border-radius: 20rpx;
transition: all 0.2s;
&:active {
background-color: #F0F2F5;
transform: scale(0.98);
}
.preview-img {
width: 100rpx;
height: 100rpx;
border-radius: 12rpx;
background-color: #EEE;
}
.info {
flex: 1;
margin: 0 24rpx;
display: flex;
flex-direction: column;
.name {
font-size: 28rpx;
font-weight: 500;
color: #1A1A1A;
}
.desc {
font-size: 22rpx;
color: #8E8E93;
margin-top: 4rpx;
}
}
}
}
.p-footer {
height: 100rpx;
line-height: 100rpx;
text-align: center;
border-top: 1rpx solid #F0F2F5;
font-size: 30rpx;
color: #8E8E93;
&:active {
background-color: #F8F9FA;
}
}
}
</style>
<style>
@import '@/common/main.css';
page {
background-color: #F1F5F8;
}
</style>