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

1202 lines
30 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="top-fixed">
<nav-bar v-if="!selectedImage" title="京东" bgColor="#F0F4F9" :buttonGroup="buttonGroup"
@button-click="util.clickTitlePopupButton" tipLayerType="jingdong-shopping-list" isTipLayer
tipLayerText="添加订单信息">
<template v-slot:center>
<view class="search-box">
<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">
<image class="gift icon" src="/static/image/shopping/jingdong/gift.png" mode="aspectFit">
</image>
<image class="more icon" src="/static/image/shopping/jingdong/more.png" mode="aspectFit">
</image>
</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)">
<text class="title">{{ item.name }}</text>
<view class="line" v-if="currentTab === index"></view>
<image v-if="item.icon" class="badge-icon" :src="item.icon" mode="heightFix"></image>
</view>
</view>
<view class="filter-wrapper">
<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>
<text class="close-icon" v-if="currentFilter === index">×</text>
</view>
</view>
</scroll-view>
<view class="filter-btn">
<image class="filter-icon" src="/static/image/shopping/jingdong/shaixuan.png" mode="aspectFit"></image>
<text class="filter-text">筛选</text>
</view>
</view>
</view>
<view class="content" :style="{ paddingTop: contentPaddingTop }">
<shopping-card v-for="(item, index) in filteredOrderList" :key="index" :item="item" @longpress="handleLongPress"
@click="handleCardClick(item)"></shopping-card>
<view class="empty-state" v-if="filteredOrderList.length === 0">
<image class="empty-icon" src="/static/image/shopping/jingdong/null.png" mode="heightFix"></image>
<text class="empty-text">您还没有相关订单</text>
</view>
</view>
<view class="bottom-fixed" :style="{ height: bottomBoxHeight }">
<view class="bottom-item">
<image class="like-icon" src="/static/image/shopping/jingdong/weinituijian.png" mode="aspectFit"></image>
<text>为你推荐</text>
</view>
<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="upload-screenshot-content">
<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>
<!-- 长按操作气泡菜单 -->
<view v-if="showActionMenu" class="action-menu-mask" @click="showActionMenu = false">
<view class="action-menu-bubble" :style="{ left: actionMenuState.x + 'px', top: actionMenuState.y + 'px' }"
@click.stop>
<view class="menu-item" @click.stop="editOrder">修改</view>
<view class="menu-line"></view>
<view class="menu-item" @click.stop="handleDeleteOrder">删除</view>
<view class="bubble-arrow"></view>
</view>
</view>
<!-- 水印 -->
<view v-if="$isVip()">
<watermark dark="light" />
<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>
</template>
<script setup>
import { ref, computed, onMounted, getCurrentInstance } from 'vue';
import { onShow } from '@dcloudio/uni-app';
import ShoppingCard from '@/components/shopping/jingdong/shopping-card.vue';
import { util } from '@/utils/common.js';
const showActionMenu = ref(false);
const actionMenuState = ref({ x: 0, y: 0, item: null });
// 长按替换截图相关
const screenshotImage = ref('');
const selectedImage = ref('');
const scrollTop = ref(0);
let longPressTimer = null;
//导航栏菜单按钮
const buttonGroup = [
{
name: "新增购物订单",
click: () => {
uni.navigateTo({
url: '/pages/shopping/jingdong/add-order/add-order'
});
}
}, {
name: "新增秒送订单",
click: () => {
uni.showToast({
title: '开发中,敬请期待',
icon: 'none'
});
}
},
]
/**
* 长按弹出气泡菜单
* @param data
*/
const handleLongPress = (data) => {
console.log("长按", data);
const event = data.event;
let x = 0;
let y = 0;
// 兼容不同平台的坐标获取
if (event.touches && event.touches.length > 0) {
x = event.touches[0].clientX;
y = event.touches[0].clientY;
} else if (event.changedTouches && event.changedTouches.length > 0) {
x = event.changedTouches[0].clientX;
y = event.changedTouches[0].clientY;
} else {
// 兜底处理 (如模拟器点击或 detail 携带)
x = event.clientX || (event.detail && event.detail.x) || 0;
y = event.clientY || (event.detail && event.detail.y) || 0;
}
if (x || y) {
actionMenuState.value = {
x: x,
y: y,
item: data.item
};
showActionMenu.value = true;
} else {
console.warn("无法获取长按坐标");
}
};
/**
* 修改订单
*/
const editOrder = () => {
const item = actionMenuState.value.item;
if (!item) return;
showActionMenu.value = false;
uni.navigateTo({
url: '/pages/shopping/jingdong/add-order/add-order?id=' + item.id + '&type=' + item.shopType + '&isEdit=true'
});
};
/**
* 点击订单卡片
* @param item 订单项
*/
const handleCardClick = (item) => {
if (item.shopType !== "waimai") {
uni.navigateTo({
url: '/pages/shopping/jingdong/order-detail/order-detail?id=' + item.id
});
} else {
}
};
/**
* 删除订单
*/
const handleDeleteOrder = () => {
const itemToDel = actionMenuState.value.item;
// 1. 尝试删除本地持久化图片文件 (商品图 + 快递员头像)
const productImage = itemToDel?.products?.[0]?.image;
const courierImage = itemToDel?.courierImg;
const cleanupFile = (path) => {
if (path && (path.includes('_doc/') || path.includes('_downloads/') || path.includes('store_') || path.includes('at_'))) {
uni.removeSavedFile({
filePath: path,
success: () => console.log('文件删除成功:', path),
fail: (err) => console.error('文件删除失败:', err)
});
}
};
cleanupFile(productImage);
cleanupFile(courierImage);
// 2. 从列表中移除数据
const realIndex = mockOrderList.value.findIndex(item => item === itemToDel);
if (realIndex > -1) {
mockOrderList.value.splice(realIndex, 1);
// 同步更新缓存
uni.setStorageSync('jingdongShopping', mockOrderList.value);
}
showActionMenu.value = false;
uni.showToast({
title: '已删除',
icon: 'none'
});
};
const contentPaddingTop = ref('0px');
const instance = getCurrentInstance();
/**
* 底部盒子高度
*/
const bottomBoxHeight = computed(() => {
const { windowHeight } = uni.getSystemInfoSync();
return `calc(${windowHeight}px - ${contentPaddingTop.value} - 324rpx)`;
});
/**
* 初始化
*/
onMounted(() => {
setTimeout(() => {
const query = uni.createSelectorQuery().in(instance.proxy);
query.select('.top-fixed').boundingClientRect(data => {
if (data) {
contentPaddingTop.value = data.height + 'px';
}
}).exec();
}, 100);
});
onShow(() => {
const cachedData = uni.getStorageSync('jingdongShopping');
if (cachedData && Array.isArray(cachedData)) {
mockOrderList.value = cachedData;
}
// 读取缓存的截图
const cachedImage = uni.getStorageSync('jingdong_screenshot');
if (cachedImage) {
screenshotImage.value = cachedImage;
}
console.log('screenshotImage.value', screenshotImage.value)
console.log("mockOrderList", mockOrderList.value);
});
// 长按替换截图 - 选择图片
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.proxy);
// query.select('.image-box').boundingClientRect();
// query.select('.crop-image-target').boundingClientRect();
// query.exec(res => {
// if (!res[0] || !res[1]) {
// uni.hideLoading();
// return;
// }
// const container = res[0];
// const image = res[1];
//
// uni.getImageInfo({
// src: selectedImage.value,
// success: (imgInfo) => {
// const scale = imgInfo.width / image.width;
// const sTop = scrollTop.value * scale;
// const sHeight = container.height * scale;
// const sWidth = imgInfo.width;
// const canvasW = container.width;
// const canvasH = container.height;
//
// const ctx = uni.createCanvasContext('crop-canvas', instance.proxy);
// ctx.clearRect(0, 0, canvasW, canvasH);
// 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) => {
// uni.saveFile({
// tempFilePath: res.tempFilePath,
// success: (saveRes) => {
// screenshotImage.value = saveRes.savedFilePath;
// selectedImage.value = '';
// uni.setStorageSync('jingdong_screenshot', saveRes.savedFilePath);
// uni.hideLoading();
// uni.showToast({ title: '截图替换成功', icon: 'success' });
// },
// fail: () => {
// uni.hideLoading();
// uni.showToast({ title: '保存失败', icon: 'none' });
// }
// });
// },
// fail: () => {
// uni.hideLoading();
// uni.showToast({ title: '裁剪失败', icon: 'none' });
// }
// }, instance.proxy);
// });
// },
// fail: () => {
// uni.hideLoading();
// uni.showToast({ title: '图片加载失败', icon: 'none' });
// }
// });
// });
//};
// 确认图片裁剪
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('jingdong_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 = '';
};
const currentTab = ref(0);
const tabList = ref([
{ name: '全部' },
{ name: '购物' },
{ name: '秒送', icon: '/static/image/shopping/jingdong/waimai.png' },
{ name: '服务', icon: '/static/image/shopping/jingdong/jiazheng.png', disabled: true }
]);
/**
* 切换tab
* @param index
*/
const switchTab = (index) => {
if (tabList.value[index].disabled) return;
currentTab.value = index;
};
const currentFilter = ref(-1);
const filterList = ref([
{ name: '待付款' },
{ name: '待收货' },
{ name: '待使用', disabled: false },
{ name: '已完成' },
{ name: '待评价' },
{ name: '已取消' }
]);
/**
* 切换筛选
* @param index 索引
*/
const switchFilter = (index) => {
if (filterList.value[index].disabled) return;
if (currentFilter.value === index) {
currentFilter.value = -1;
} else {
currentFilter.value = index;
}
};
/**
* 提取订单的时间戳用于排序
*/
const getOrderTimestamp = (item) => {
let timeStr = "";
if (item.orderInfo) {
const target = item.orderInfo.find(i => i.label === '下单时间' || i.label === '支付时间');
if (target && target.value) timeStr = target.value;
}
if (!timeStr && item.trackingTime) {
timeStr = item.trackingTime;
}
return timeStr ? new Date(timeStr.replace(/-/g, '/')).getTime() : 0;
};
/**
* 筛选订单列表
*/
const filteredOrderList = computed(() => {
const tabName = tabList.value[currentTab.value].name;
let baseList = [...mockOrderList.value];
if (tabName === '购物') {
baseList = baseList.filter(item => item.shopType !== 'waimai');
} else if (tabName === '秒送') {
baseList = baseList.filter(item => item.shopType === 'waimai');
}
let result = [];
if (currentFilter.value === -1) {
result = baseList;
} else {
const filterName = filterList.value[currentFilter.value].name;
result = baseList.filter(item => {
if (filterName === '待付款') return item.status === '等待付款';
if (filterName === '待收货') return item.status === '正在出库' || item.status === '待收货' || item.status === '运输中' || item.status === '已发货' || item.status === '商家备餐中' || item.status === '骑手到店取餐中';
if (filterName === '待使用') return item.status === '待使用';
if (filterName === '已完成') return item.status === '完成' || item.status === '已完成' || item.status === '已签收';
if (filterName === '待评价') return item.status === '待评价' || item.status === '完成' || item.status === '已完成';
if (filterName === '已取消') return item.status === '已取消';
return true;
});
}
// 执行倒序排序
return result.sort((a, b) => getOrderTimestamp(b) - getOrderTimestamp(a));
});
/**
* 模拟订单列表
*/
const mockOrderList = ref([
// {
// id: 123211111,
// shopType: 'waimai',
// shopName: '安野屋 (AARYE) 京...',
// status: '等待付款',
// statusDesc: '29分钟',
// products: [
// {
// image: '/static/image/shopping/jingdong/product1.png',
// title: '超值哈哈哈哈哈哈哈哈哈哈哈哈哈哈好一人份',
// desc: '不支持7天无理由退货',
// service: "",
// price: '69.00',
// count: 1,
// }
// ],
// promoType: 'text',
// promoHighlight: '近90天600+人回购',
// },
// {
// id: 9632554,
// shopType: 'waimai',
// shopName: '安野屋 (AARYE) 京...',
// status: '骑手到店取餐中',
// trackingTitle: '10:22-10:55',
// trackingDesc: '骑手已到店,大王',
// trackingTime: '2026-03-10 15:14:30',
// products: [
// {
// image: '/static/image/shopping/jingdong/product1.png',
// title: '超值哈哈哈哈哈哈哈哈哈哈哈哈哈哈好热 少糖',
// desc: '不支持7天无理由退货',
// service: "",
// tags: [],
// price: '69.00',
// count: 1,
// }
// ]
// },
// {
// id: 63254112,
// shopType: 'waimai',
// shopName: '安野屋 (AARYE) 京...',
// status: '商家备餐中',
// trackingTitle: '10:22-10:55',
// trackingDesc: '商家已接单,商品备餐中',
// trackingTime: '2026-03-10 15:14:30',
// products: [
// {
// image: '/static/image/shopping/jingdong/product1.png',
// title: '超值哈哈哈哈哈哈哈哈哈哈哈哈哈哈好热 少糖',
// desc: '不支持7天无理由退货',
// service: "",
// tags: [],
// price: '69.00',
// count: 1,
// }
// ]
// },
// {
// id: 78456211,
// shopType: 'waimai',
// shopName: '瑞幸咖啡',
// status: '完成',
// statusColor: 'gray',
// products: [
// {
// image: '/static/image/shopping/jingdong/product1.png',
// title: '多肉桃桃哈哈哈哈哈哈哈哈哈哈好和和好',
// desc: '不支持7天无理由退货',
// service: "",
// tags: [],
// price: '69.00',
// count: 1,
// }
// ],
// promoType: 'coupon',
// promoText: '恭喜您获得3元京东购物券',
// promoAction: '去领券'
// },
// {
// id: 56322115,
// shopType: 'waimai',
// shopName: '瑞幸咖啡',
// status: '完成',
// statusColor: 'gray',
// products: [
// {
// image: '/static/image/shopping/jingdong/product1.png',
// },
// {
// image: '/static/image/shopping/jingdong/product1.png',
// },
// {
// image: '/static/image/shopping/jingdong/product1.png',
// }
// ],
// price: '17.00',
// count: 2,
// },
// {
// id: 52322221,
// shopType: 'waimai',
// shopName: '瑞幸咖啡',
// status: '已取消',
// statusColor: 'gray',
// products: [
// {
// image: '/static/image/shopping/jingdong/product1.png',
// title: '多肉桃桃哈哈哈哈哈哈哈哈哈哈好和和好',
// desc: '不支持7天无理由退货',
// tags: [],
// service: "",
// price: '69.00',
// count: 1,
// }
// ]
// },
// {
// id: 8562245551,
// shopType: 'self',
// shopName: '安野屋 (AARYE) 京联名哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈好梦',
// status: '等待付款',
// statusDesc: '20小时11分钟',
// products: [
// {
// image: '/static/image/shopping/jingdong/product1.png',
// title: '安野哈哈哈哈哈哈哈哈哈哈哈哈好好',
// desc: '联名哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈好梦',
// tags: ['无理由退货政策'],
// service: "无理由退货政策",
// price: '69.00',
// count: 1,
// }
// ],
// promoType: 'text',
// promoHighlight: '白条支付券0.5元优惠券',
// },
// {
// id: 5504455,
// shopType: 'none',
// shopName: '甜小南旗舰店',
// status: '正在出库',
// trackingTitle: '仓库处理中',
// trackingDesc: '预计 3月12日24:00 前发货3月15日 24:00 前送达',
// trackingTime: '2026-03-10 15:14:30',
// products: [
// {
// image: '/static/image/shopping/jingdong/product1.png',
// title: '安野哈哈哈哈哈哈哈哈哈哈哈哈好好',
// desc: '联名哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈好梦',
// tags: ['无理由退货政策'],
// service: "无理由退货政策",
// price: '69.00',
// count: 1,
// }
// ],
// promoType: 'plus',
// promoText: '告别凑单, 享免运优惠',
// },
// {
// id: 585552,
// shopType: 'self',
// shopName: '甜小南旗舰店',
// status: '完成',
// statusColor: 'gray',
// trackingTitle: '已签收',
// trackingDesc: '您的订单已签收,可对快递员的服务进行评价或打赏哦~',
// trackingTime: '2026-03-10 15:14:30',
// products: [
// {
// image: '/static/image/shopping/jingdong/product1.png',
// title: '安野哈哈哈哈哈哈哈哈哈哈哈哈好好',
// desc: '联名哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈好梦',
// tags: ['无理由退货政策'],
// service: "无理由退货政策",
// price: '69.00',
// count: 1,
// }
// ],
// promoType: 'plus',
// promoText: '告别凑单, 享免运优惠',
// hasMore: true,
// },
// {
// id: 4545451,
// shopType: 'jd',
// shopName: '甜小南旗舰店',
// status: '完成',
// statusColor: 'gray',
// products: [
// {
// image: '/static/image/shopping/jingdong/product1.png',
// title: '安野哈哈哈哈哈哈哈哈哈哈哈哈好好',
// desc: '联名哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈好梦',
// tags: ['无理由退货政策'],
// service: "无理由退货政策",
// price: '1669.00',
// count: 1,
// }
// ],
// hasMore: true,
// },
// {
// id: 1236524,
// shopType: 'self',
// shopName: '甜小南旗舰店',
// status: '已取消',
// statusColor: 'gray',
// products: [
// {
// image: '/static/image/shopping/jingdong/product1.png',
// title: '安野哈哈哈哈哈哈哈哈哈哈哈哈好好',
// desc: '联名哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈好梦',
// tags: ['无理由退货政策'],
// service: "无理由退货政策",
// price: '1669.00',
// count: 1,
// }
// ]
// }
]);
</script>
<style lang="less">
.top-fixed {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
background-color: #F0F4F9;
}
::v-deep .uni-navbar__header-btns {
width: auto !important;
}
::v-deep .uni-navbar__header-container {
padding-right: 0 !important;
}
.search-box {
width: 100%;
background-color: #fff;
border-radius: 12rpx;
padding: 0 16rpx;
height: 60rpx;
display: flex;
align-items: center;
border: 0.5px solid #E5E5E5;
.search-icon {
width: 36rpx;
height: 36rpx;
flex-shrink: 0;
margin-right: 14rpx;
}
::v-deep .input-placeholder {
font-size: 26rpx;
line-height: 26rpx;
color: #CCCCCC;
}
}
.right-box {
display: flex;
align-items: center;
.icon {
width: 40rpx;
height: 40rpx;
margin-left: 22rpx;
}
}
.tab-list {
display: flex;
align-items: center;
padding: 16rpx 36rpx 10rpx;
background-color: #F0F4F9;
.tab-item {
position: relative;
display: flex;
align-items: center;
margin-right: 58rpx;
.title {
font-size: 28rpx;
color: #1A1A1A;
font-weight: 700;
line-height: 28rpx;
}
&.active {
.title {
font-size: 28rpx;
color: #F51919;
font-weight: 700;
}
}
.line {
position: absolute;
bottom: -10rpx;
left: -5%;
transform: translateX(50%);
width: 30rpx;
height: 4rpx;
background-color: #F51919;
border-radius: 4rpx;
}
.badge-icon {
position: relative;
top: 0;
margin-left: 2rpx;
height: 32rpx;
}
}
}
.filter-wrapper {
display: flex;
align-items: center;
height: 64rpx;
padding: 0 0 0 24rpx;
background-color: #F0F4F9;
margin-top: 10rpx;
margin-bottom: 26rpx;
.filter-scroll {
flex: 1;
width: 0;
white-space: nowrap;
.filter-list {
height: 88rpx;
line-height: 88rpx;
padding-right: 24rpx;
}
.filter-item {
display: inline-flex;
align-items: center;
justify-content: center;
vertical-align: middle;
height: 56rpx;
padding: 0 24rpx;
background-color: #FFFFFF;
border-radius: 8rpx;
margin-right: 16rpx;
border: 2rpx solid transparent;
box-sizing: border-box;
.text {
font-size: 26rpx;
color: #1A1A1A;
}
.close-icon {
font-size: 18px;
color: #E40C24;
margin-top: -10rpx;
line-height: 14px;
margin-left: 6rpx;
font-weight: 400;
}
&.active {
background-color: #FFECF5;
border-color: #E40C24;
.text {
color: #E40C24;
}
}
// &.disabled {
// background-color: #F8F8F8;
// border-color: transparent;
// .text {
// color: #CCCCCC;
// }
// }
}
}
.filter-btn {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 82rpx;
height: 64rpx;
background-color: #F0F4F9;
position: relative;
z-index: 10;
box-shadow: -10rpx 0 10rpx -10rpx rgba(0, 0, 0, 0.1);
.filter-icon {
width: 28rpx;
height: 28rpx;
margin-bottom: 4rpx;
}
.filter-text {
font-size: 20rpx;
line-height: 20rpx;
color: #575757;
}
}
}
.content {
padding: 0 20rpx;
}
.bottom-fixed {
display: flex;
flex-direction: column;
}
.bottom-item {
display: flex;
align-items: center;
justify-content: center;
color: #1A1A1A;
font-size: 28rpx;
line-height: 26rpx;
font-weight: 500;
margin-bottom: 22rpx;
}
.like-icon {
width: 32rpx;
height: 32rpx;
margin-right: 8rpx;
}
.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 {
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;
}
}
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40rpx 0 64rpx;
.empty-icon {
height: 220rpx;
margin-bottom: 12rpx;
}
.empty-text {
font-size: 22rpx;
color: #999A9E;
line-height: 24rpx;
}
}
.action-menu-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
}
.action-menu-bubble {
position: fixed;
background-color: #3B3C3E;
border-radius: 12rpx;
width: 200rpx;
transform: translate(-50%, calc(-100% - 15px));
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.2);
display: flex;
flex-direction: column;
.menu-item {
color: #FFFFFF;
font-size: 26rpx;
text-align: center;
padding: 24rpx 0;
line-height: 26rpx;
}
.menu-line {
height: 0.5px;
background-color: rgba(255, 255, 255, 0.1);
margin: 0 24rpx;
}
.bubble-arrow {
position: absolute;
bottom: -12rpx;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 12rpx solid transparent;
border-right: 12rpx solid transparent;
border-top: 14rpx solid #3B3C3E;
}
}
</style>