소스 검색

feat:添加海报和我的订单页面

wangsisi 22 시간 전
부모
커밋
96a1b6c791

+ 349 - 0
components/posterPopup/posterPopup.vue

@@ -0,0 +1,349 @@
+<template>
+	<up-popup :show="showPopup" @close="closePopup" mode="center" bgColor="transparent">
+		<view class="poster-popup" ref="contentDom">
+			<view class="date-wrap">
+				<view class="time">
+					<text class="month">{{ treeObj.year }}</text>
+					<view class="date">
+						<text>{{ treeObj.monthNumber }}</text>/{{ treeObj.day }}
+					</view>
+				</view>
+				<view class="qr-code">
+					<image :src="treeObj.qrCodeUrl" alt="" />
+					<view class="txt">
+						<text>{{ treeObj.age }}年 {{ treeObj.age > 9 ? "老树" : "树龄" }} {{ treeObj.pz }}</text>
+						<view>{{treeObj.phenology}} 气候适宜-{{ treeObj.howTxt || "果园采摘" }}</view>
+					</view>
+				</view>
+			</view>
+			<view class="image-wrap">
+				<image class="image" :src="treeObj.posterUrl" alt="" />
+				<view class="address common-bg">{{ treeObj.pz }}-{{ treeObj.countyName }}</view>
+				<view class="tag-image">
+					<view class="tag-content">
+						<view class="tag-name">【{{ treeName || '茜茜荔' }}】</view>
+						<view class="tag-user">
+							<text>{{ treeObj.nickname || treeObj.name || '12' }}</text>
+							<text class="date">{{ treeObj.year }}.{{
+	                                    treeObj.monthNumber >= 10 ? treeObj.monthNumber : "0" + treeObj.monthNumber
+	                                }}.{{ treeObj.day }}</text>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="info-wrap">
+				<view class="text">
+					<!-- <el-viewider class="viewider" /> -->
+					<view v-for="(text, textI) in treeObj.watermarkArr" :key="textI">{{ text }}</view>
+				</view>
+				<view class="nickname">
+					<image :src="`${config.BASIC_IMG}img/treePage/logo.png`" alt="" />
+					<view>飞鸟有味</view>
+				</view>
+			</view>
+		</view>
+		<view class="footer">
+			<view @click="handleDownload">保存图片</view>
+			<view class="share" @click="handleShare">去分享</view>
+		</view>
+		<up-icon class="close" name="close-circle-fill" size="30" @click="showPopup = false" color="rgba(255, 255, 255, 0.7)"></up-icon>
+	</up-popup>
+	<!-- 保存弹窗 -->
+	<!-- <save-photo-popup ref="savePhotoDom" height="480"></save-photo-popup> -->
+</template>
+
+<script setup>
+	import {
+		ref,
+		watch
+	} from "vue";
+	// import savePhotoPopup from "@/components/common/savePhotoPopup.vue";
+	import config from "@/api/config.js"
+	const resize = "?x-oss-process=image/resize,w_1000";
+
+	const props = defineProps({
+		farmBuyId: {
+			type: [Number, String],
+			defalut: "",
+		},
+		sampleId: {
+			type: [Number, String],
+			defalut: "",
+		},
+		treeName: {
+			type: String,
+			defalut: "",
+		},
+		showPoster: {
+			type: Boolean,
+			defalut: false,
+		},
+	});
+
+	watch(
+		() => props.farmBuyId,
+		(newValue) => {
+			if (newValue && userInfo?.tel && props.showPoster) {
+				getPosterData(newValue);
+			}
+		}
+	);
+
+	watch(
+		() => props.showPoster,
+		(newValue) => {
+			// if (newValue && userInfo?.tel && props.showPoster) {
+			// 	getPosterData(props.farmBuyId);
+			// }
+			getPosterData()
+		}
+	);
+
+	const handleShare = () => {
+		const params = {
+			sampleId: props.sampleId,
+			farmBuyId: props.farmBuyId,
+		};
+		// wx.miniProgram.navigateTo({
+		//     url: `/pages/subPages/share_page/index?type=treeExample&pageParams=${JSON.stringify(params)}`,
+		// });
+	};
+
+	const showPopup = ref(false);
+	// const userInfo = JSON.parse(localStorage.getItem("localUserInfo"));
+	function formatDate(dateStr) {
+		const date = new Date(dateStr);
+		return {
+			month: date.toLocaleString("en-US", {
+				month: "short"
+			}), // "Jun"
+			year: date.getFullYear(),
+			monthNumber: date.getMonth() + 1, // 6
+			day: date.getDate(), // 23
+		};
+	}
+
+	const treeObj = ref({});
+	const savePhotoDom = ref(null);
+	const contentDom = ref(null);
+
+	const handleDownload = () => {
+		savePhotoDom.value.handleDownload(contentDom.value);
+	};
+
+	const getPosterData = (farmBuyId) => {
+		// VE_API.lj_home.getPoster({ farmBuyId }).then((res) => {
+		//     if (res.code === 0) {
+		//         if(!props.isShow){
+		showPopup.value = true;
+		const data = {
+			"posterUrl": "https://birdseye-img-ali-cdn.sysuimars.com/562ba414-9517-4789-98f9-42fdae26cee4/bc27ee0c-8177-47fb-823c-c81d6f8b514c/DJI_202507281100_002_bc27ee0c-8177-47fb-823c-c81d6f8b514c/DJI_20250728110246_0016_Z_code-ws0y1mu3uwb2.jpeg",
+			"qrCodeUrl": "https://birdseye-img.sysuimars.com/birdseye-look-mini/temp/1751087233847.jpg",
+			"age": 2,
+			"countyName": "从化",
+			"pz": "井岗红糯",
+			"watermarkMsg": "山海皆可平,无处不风景",
+			"watermarkUrl": "",
+			"fosterCode": "LCJGHN-GZCH-LBY1003",
+			"countdown": -40,
+			"sampleId": 172055,
+			"posterId": "740994773711589376",
+			"ssDate": null,
+			"createDate": "2025-08-06",
+			"phenology": "秋梢期",
+			"howTxt": "梢期防虫"
+		}
+		treeObj.value = {
+			...data,
+			watermarkArr: data.watermarkMsg && data.watermarkMsg.split(","),
+			...formatDate(data.createDate)
+		};
+		//         }else{
+		//             closePopup()
+		//         }
+		//     }
+		// });
+	};
+
+	const closePopup = () => {
+		showPopup.value = false;
+		// VE_API.lj_home.posterRead({ posterId: treeObj.value.posterId });
+	};
+</script>
+
+<style lang="scss" scoped>
+	@import "@/static/style/mixin.scss";
+	.poster-popup {
+		width: 90vw;
+		box-sizing: border-box;
+		position: relative;
+		padding: 40rpx 30rpx;
+		background: #fff;
+		border-radius: 24rpx;
+		.date-wrap {
+			display: flex;
+			justify-content: space-between;
+
+			view {
+				font-family: "SweiSpringCJKtc";
+			}
+
+			.time {
+				line-height: 100rpx;
+				margin-top: -42rpx;
+
+				.date {
+					font-size: 48rpx;
+
+					text {
+						font-size: 172rpx;
+					}
+				}
+			}
+
+			.qr-code {
+				text-align: right;
+
+				image {
+					width: 112rpx;
+					height: 124rpx;
+				}
+
+				.txt {
+					font-size: 24rpx;
+					line-height: 36rpx;
+					margin-top: 12rpx;
+				}
+			}
+		}
+
+		.image-wrap {
+			width: 100%;
+			height: 480rpx;
+			position: relative;
+			margin: 30rpx 0 44rpx 0;
+			pointer-events: none;
+
+			image {
+				width: 100%;
+				height: 100%;
+				object-fit: cover;
+				border-radius: 10rpx;
+			}
+
+			.common-bg {
+				position: absolute;
+				background: rgba(0, 0, 0, 0.6);
+				font-size: 20rpx;
+				color: #fff;
+				padding: 8rpx 30rpx;
+				border-radius: 50rpx;
+			}
+
+			.address {
+				top: 20rpx;
+				right: 12rpx;
+				border: 1px solid rgba(255, 255, 255, 0.39);
+			}
+
+			.tag-image {
+				position: absolute;
+				z-index: 3;
+				left: 0;
+				bottom: 0;
+
+				.tag-content {
+					@include ossBg("treePage/tag-bg.png");
+					width: 276rpx;
+					height: 274rpx;
+					display: flex;
+					flex-direction: column;
+					align-items: center;
+					color: #fff;
+
+					.tag-name {
+						font-family: "jiangxizhuokai";
+						font-size: 36rpx;
+						padding-top: 56rpx;
+					}
+
+					.tag-user {
+						padding-top: 6rpx;
+						font-family: "jiangxizhuokai";
+						font-size: 16rpx;
+
+						.date {
+							padding-left: 10rpx;
+						}
+					}
+				}
+			}
+		}
+
+		.info-wrap {
+			display: flex;
+			align-items: flex-end;
+			justify-content: space-between;
+
+			.text {
+				font-size: 22rpx;
+
+				view {
+					font-family: "SweiSpringCJKtc";
+					line-height: 32rpx;
+				}
+
+				.viewider {
+					width: 60rpx;
+					border-top-color: #000;
+					margin: 12rpx 0;
+					height: 4rpx;
+				}
+			}
+
+			.nickname {
+				font-size: 24rpx;
+				text-align: center;
+
+				image {
+					width: 68rpx;
+					height: 72rpx;
+					margin-bottom: 8rpx;
+				}
+
+				view {
+					font-family: "SweiSpringCJKtc-Black";
+				}
+			}
+		}
+	}
+
+	.footer {
+		margin: 40rpx 0;
+		display: flex;
+		width: 100%;
+		box-sizing: border-box;
+
+		view {
+			flex: 1;
+			padding: 20rpx 0;
+			font-size: 32rpx;
+			border-radius: 50rpx;
+			border: 1px solid #fff;
+			background: #fff;
+			text-align: center;
+			color: #000;
+		}
+
+		.share {
+			margin-left: 20rpx;
+			color: #fff;
+			background-image: linear-gradient(120deg, #ffd887, #ed9e1e);
+		}
+	}
+
+	.close{
+		margin-top: 36rpx;
+		justify-content: center;
+	}
+</style>

+ 72 - 0
components/v-search/v-search.vue

@@ -0,0 +1,72 @@
+<template>
+	<view class="v-search">
+		<view class="search-wrap">
+			<up-search placeholder="搜索品种" v-model="searchVal" @clear="clear" @custom="searchFun" @search="searchFun"></up-search>
+		</view>
+	</view>
+</template>
+
+<script setup>
+	import {
+		ref
+	} from "vue"
+	
+	const searchVal = ref('')
+	const searchFun = (e)=>{
+		emit('searchCallback',e)
+	}
+	const clear = ()=>{
+		emit('clearCallback')
+	}
+	
+	const emit = defineEmits(['searchCallback','clearCallback'])
+</script>
+
+<style lang="scss" scoped>
+	.v-search {
+		display: flex;
+		align-items: center;
+		width: 100%;
+		border: 2rpx solid #FFD95E;
+		border-radius: 40rpx;
+
+		.search-wrap {
+			flex: 1;
+
+			::v-deep {
+				.u-search {
+					.u-search__content {
+						background-color: transparent !important;
+
+						.u-search__content__input {
+							background-color: transparent !important;
+
+						}
+					}
+
+					.u-search__action {
+						text-align: center;
+						line-height: 52rpx;
+						border-radius: 40rpx;
+						font-size: 28rpx;
+						background-color: #FFD95E;
+						margin: 6rpx 8rpx;
+						width: 112rpx;
+						height: 52rpx;
+					}
+				}
+			}
+		}
+
+		.search-btn {
+			text-align: center;
+			line-height: 52rpx;
+			border-radius: 40rpx;
+			font-size: 28rpx;
+			background-color: #FFD95E;
+			margin: 6rpx 8rpx;
+			width: 112rpx;
+			height: 52rpx;
+		}
+	}
+</style>

+ 7 - 0
pages.json

@@ -63,6 +63,13 @@
 			{
 				"navigationBarTitleText" : "守护礼物"
 			}
+		},
+		{
+			"path" : "pages/tabBar/mine/subPages/order",
+			"style" : 
+			{
+				"navigationBarTitleText" : "我的订单"
+			}
 		}
 	],
 	"globalStyle": {

+ 8 - 2
pages/tabBar/mine/mine.vue

@@ -32,7 +32,7 @@
 					</view>
 				</view>
 				<view class="card-cont flex-center">
-					<view class="cont-item" v-for="(item,index) in orderList" :key="index">
+					<view class="cont-item" v-for="(item,index) in orderList" :key="index" @click="handleItem(index)">
 						<image class="icon" :src="`${config.BASIC_IMG}img/order-icon-${index+1}.png`"></image>
 						<view>{{item}}</view>
 					</view>
@@ -69,7 +69,13 @@
 import config from "@/api/config.js"
 
 const orderList = ["待付款","待发货","待收货","待评价","退款/售后"]
-const imageList = []
+const imageList = []
+
+const handleItem = () =>{
+	uni.navigateTo({
+		url: `/pages/tabBar/mine/subPages/order`
+	});
+}
 </script>
 
 <style lang="scss" scoped>

+ 230 - 0
pages/tabBar/mine/subPages/order.vue

@@ -0,0 +1,230 @@
+<template>
+	<view class="sub-base-container">
+		<view class="search-box">
+			<v-search @searchCallback="searchCallback" @clearCallback="clearCallback"></v-search>
+		</view>
+		<view class="tabs">
+			<view :class="['tab-item',{active:active === index}]" v-for="(item,index) in tabsList" :key="index"
+				@click="handleTab(index)">{{item}}</view>
+		</view>
+		<view class="shop-list">
+			<view class="shop-item" v-for="(item,index) in 3" :key="index">
+				<view class="shop-head">
+					<view class="shop-title">
+						<text>从化荔博园店铺</text>
+						<up-icon class="icon" name="arrow-right" size="12" color="rgba(137, 137, 137, 0.69)"></up-icon>
+					</view>
+					<text class="status">{{statusStr[active]}}</text>
+				</view>
+				<view class="shop-cont">
+					<image class="shop-img" src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png">
+					</image>
+					<view class="shop-info">
+						<view class="shop-name flex">
+							<text>海南妃子笑荔枝新鲜采摘</text>
+							<text class="shop-price">¥25</text>
+						</view>
+						<view class="shop-text flex">
+							<text>3斤装规格</text>
+							<text>x1</text>
+						</view>
+						<up-text size="12" color="#AFAFAF" text="坏单包退 包邮"></up-text>
+						<view class="total">
+							<view v-if="active==3 || active==4">共优惠 <text class="num">¥10</text></view>
+							<view v-if="active!=0 || active!=1">实付款 <text class="num">¥25</text></view>
+						</view>
+					</view>
+				</view>
+				<view class="shop-foot flex">
+					<view class="more">更多</view>
+					<view class="shop-button" v-if="active==0 || active==1">
+						<view>取消订单</view>
+						<view>付款</view>
+					</view>
+					<view class="shop-button" v-else-if="active==2">
+						<view>删除订单</view>
+						<view>提醒发货</view>
+					</view>
+					<view class="shop-button" v-else-if="active==3">
+						<view>删除订单</view>
+						<view>查看物流</view>
+						<view class="confirm">确认收货</view>
+					</view>
+					<view class="shop-button" v-else="active==4">
+						<view>申请售后</view>
+						<view>去评价</view>
+						<view class="confirm">再买一单</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script setup>
+	import {
+		ref
+	} from "vue"
+
+	const searchCallback = (e) => {
+		console.log('搜索', e)
+	}
+	const clearCallback = () => {
+		console.log('clear')
+	}
+
+	const active = ref(0)
+	const tabsList = ["全部", "待付款", "待发货", "待收货", "待评价", "退款/售后"]
+	const handleTab = (index) => {
+		active.value = index
+	}
+	
+	const statusStr = {
+		0:"待付款",
+		1:"待付款",
+		2:"待发货",
+		3:"待收货",
+		4:"交易成功",
+		5:"退款/售后",
+	}
+	
+	// const shopList = [
+	// 	{
+	// 		status:0,
+	// 	}
+	// ]
+</script>
+
+<style lang="scss" scoped>
+	.sub-base-container {
+		padding: 0;
+		.search-box{
+			padding: 16rpx 24rpx 20rpx;
+			background: #fff;
+		}
+		.tabs {
+			width: 100%;
+			padding: 0 24rpx 16rpx;
+			box-sizing: border-box;
+			display: flex;
+			overflow-x: auto;
+			background: #fff;
+
+			.tab-item {
+				// flex: 1;
+				width: 150px;
+				text-align: center;
+				color: #000;
+				font-size: 28rpx;
+				padding: 10rpx 0;
+				white-space: nowrap;
+
+				&.active {
+					border-radius: 10rpx;
+					background: rgba(243, 193, 29, 0.2);
+				}
+			}
+		}
+
+		.shop-list {
+			font-size: 28rpx;
+			.flex {
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+			}
+
+			.shop-item {
+				background: #fff;
+				padding: 20rpx 24rpx;
+
+				.shop-head {
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
+
+					.shop-title {
+						font-weight: 500;
+						display: flex;
+						.icon{
+							margin-left: 2rpx;
+						}
+					}
+
+					.status {
+						color: #F3C11D;
+					}
+				}
+
+				.shop-cont {
+					width: 100%;
+					display: flex;
+					margin: 20rpx 0;
+
+					.shop-img {
+						width: 182rpx;
+						height: 182rpx;
+						margin-right: 10rpx;
+						border-radius: 10rpx;
+					}
+
+					.shop-info {
+						width: calc(100% - 182rpx - 10rpx);
+
+						.shop-name {
+							font-size: 28rpx;
+							font-weight: 500;
+
+							.shop-price {
+								font-weight: 400;
+							}
+						}
+
+						.shop-text {
+							color: #717070;
+						}
+
+						.total {
+							margin-top: 20rpx;
+							display: flex;
+							justify-content: flex-end;
+							.num{
+								font-weight: 500;
+								font-size: 34rpx;
+							}
+							view + view{
+								margin-left: 20rpx;
+							}
+						}
+					}
+				}
+				.shop-foot{
+					.more{
+						color: rgba(0, 0, 0, 0.5);
+					}
+					.shop-button{
+						display: flex;
+						align-items: center;
+						view{
+							width: 164rpx;
+							padding: 10rpx 0;
+							text-align: center;
+							border-radius: 50rpx;
+							border: 2rpx solid rgba(0, 0, 0, 0.3);
+						}
+						.confirm{
+							background: #FFD95E;
+							border: 2rpx solid transparent;
+						}
+						view + view{
+							margin-left: 20rpx;
+						}
+					}
+				}
+			}
+			.shop-item + .shop-item{
+				margin-top: 10rpx;
+			}
+		}
+	}
+</style>

+ 33 - 23
pages/tabBar/tree/subPages/gift.vue

@@ -9,22 +9,23 @@
 		</view>
 		<view class="gift-card energy-card">
 			<view class="gift-name">已打卡 <text>2</text>/7 天</view>
-			<div class="tips">
+			<view class="tips">
 				<text>再连续签到5天,获得</text>
-				<!-- <img src="@/assets/img/guard_tree/leaf-icon.png" alt="" /> -->
-				<text class="score">+30</text>
-			</div>
-			<div class="check-wrap">
-				<div :class="['check-day',{active:item.check}]" v-for="(item, index) in checkDay" :key="index">
+				<image class="icon" :src="`${config.BASIC_IMG}img/subTreePage/leaf-icon.png`" alt=""></image>
+				<view class="score"><up-icon name="plus" size="10" color="#D9AB14"></up-icon>30</view>
+			</view>
+			<view class="check-wrap">
+				<view :class="['check-day',{active:item.check}]" v-for="(item, index) in checkDay" :key="index">
 					<view class="leaf">
 						<image class="icon"
-							:src="`${config.BASIC_IMG}img/subTreePage/${item.check?'white-leaf':'leaf-icon'}.png`" alt="">
+							:src="`${config.BASIC_IMG}img/subTreePage/${item.check?'gray-leaf':'leaf-icon'}.png`" alt="">
 						</image>
 						<text>x20</text>
 					</view>
-					<div>第{{item.day}}天</div>
-				</div>
-			</div>
+					<view v-if="item.check">已领取</view>
+					<view v-else>第{{item.day}}天</view>
+				</view>
+			</view>
 		</view>
 		<view class="gift-card">
 			<view class="card-title">守护等级划分</view>
@@ -54,7 +55,7 @@
 		},
 		{
 			day: 2,
-			check: false
+			check: true
 		},
 		{
 			day: 3,
@@ -111,7 +112,7 @@
 
 	.sub-base-container {
 		@include ossBg("subTreePage/gift-bg.png");
-		padding: 12rpx 20rpx;
+		padding: 12rpx 20rpx 20rpx;
 
 		.gift-title {
 			display: flex;
@@ -149,12 +150,21 @@
 				}
 			}
 
-			.tips {
+			.tips {
+				display: flex;
+				align-items: center;
 				font-size: 24rpx;
-				color: rgba(0, 0, 0, 0.4);
+				color: rgba(0, 0, 0, 0.4);
+				.icon{
+					width: 24rpx;
+					height: 22rpx;
+					margin: 0 8rpx;
+				}
 
-				.score {
-					color: #D9AB14;
+				.score {
+					display: flex;
+					align-items: center;
+					color: #D9AB14;
 				}
 			}
 
@@ -164,16 +174,15 @@
 
 				.check-day {
 					flex: 1;
-					padding: 8px 0;
-					font-size: 12px;
+					padding: 20rpx 0;
+					font-size: 20rpx;
 					color: #F3B242;
 					background: rgba(185, 185, 185, 0.1);
-					border-radius: 5px;
+					border-radius: 10rpx;
 					text-align: center;
 
 					&.active {
-						background-image: linear-gradient(120deg, #FFD887, #ED9E1E);
-						color: #fff;
+						color: #BCBCBA;
 					}
 
 					.leaf {
@@ -182,15 +191,16 @@
 						justify-content: center;
 						align-items: center;
 						.icon{
-							width: 32rpx;
+							width: 28rpx;
 							height: 28rpx;
+							margin-right: 4rpx;
 							margin-bottom: 10rpx;
 						}
 					}
 				}
 
 				.check-day+.check-day {
-					margin-left: 5px;
+					margin-left: 10rpx;
 				}
 			}
 		}

+ 18 - 11
pages/tabBar/tree/tree.vue

@@ -2,9 +2,9 @@
 	<view class="base-container">
 		<member-level>
 			<view class="toogle" @click="handleShow">切换 {{name}}<up-icon class="icon" name="arrow-down" color="#fff"
-					size="12"></up-icon></view>
-		</member-level>
-		<view class="tree-cont">
+					size="12"></up-icon></view>
+		</member-level>
+		<view class="tree-cont">
 			<image class="drone-icon" :src="`${config.BASIC_IMG}img/treePage/drone-icon.png`"></image>
 			<view class="tool-wrap">
 				<view class="tool-left">
@@ -34,7 +34,8 @@
 	<up-picker :show="showPicker" :columns="columns" :defaultIndex="[0]" @cancel="handleCancel"
 		@confirm="handleConfirm"></up-picker>
 	<!-- 编辑树名称 -->
-	<editNamePopup></editNamePopup>
+	<editNamePopup></editNamePopup>
+	<posterPopup :showPoster="showPoster"></posterPopup>
 </template>
 
 <script setup>
@@ -70,7 +71,8 @@
 		},
 		{
 			name: "海报",
-			className: 'blue'
+			className: 'blue',
+			clickName:'poster'
 		},
 		{
 			name: "礼物",
@@ -95,13 +97,18 @@
 			path: 'dynamic'
 		}
 	]
-
+	
+	const showPoster = ref(false)
 	const handleToolItem = ({
-		path
-	}) => {
-		uni.navigateTo({
-			url: `/pages/tabBar/tree/subPages/${path}`
-		});
+		path,clickName
+	}) => {
+		if(clickName){
+			showPoster.value = !showPoster.value
+		}else{
+			uni.navigateTo({
+				url: `/pages/tabBar/tree/subPages/${path}`
+			});
+		}
 	}
 	const footerList = ["每日阳光", "送ta祝福", "分享转发", "水果订购"]
 </script>