瀏覽代碼

增加溯源第二阶段内容

yawuga 1 月之前
父節點
當前提交
8cd74289e1
共有 2 個文件被更改,包括 2138 次插入9 次删除
  1. 578 9
      pages/trace/detail.vue
  2. 1560 0
      佳友厚苑_溯源页第二阶段详细开发设计方案.md

+ 578 - 9
pages/trace/detail.vue

@@ -75,6 +75,20 @@
 		</view>
 
 		<scroll-view class="content" scroll-y>
+			<!-- 溯源结论卡:先给结论,再给证据 -->
+			<view v-if="traceDetail.batch?.exists && traceDetail.traceConclusionCard" class="card cardLevel1 cardConclusion">
+				<view class="sectionHeader">
+					<view class="sectionHeaderLeft">
+						<text class="sectionEn">Conclusion</text>
+						<text class="sectionTitle">溯源结论</text>
+					</view>
+				</view>
+				<view class="conclusionBody">
+					<text class="conclusionLead">{{ traceDetail.traceConclusionCard.conclusion }}</text>
+					<text class="conclusionDesc">{{ traceDetail.traceConclusionCard.desc }}</text>
+				</view>
+			</view>
+
 			<!-- 农场信息(合并为单卡:图片+名称+地区+介绍连续表达) -->
 			<view v-if="traceDetail.farm?.name" class="card cardLevel2 cardFarm">
 				<view class="sectionHeader">
@@ -104,6 +118,80 @@
 				</view>
 			</view>
 
+			<!-- 农事时间轴:关键种植过程 -->
+			<view v-if="traceDetail.batch?.exists && traceDetail.farmTimeline?.length" class="card cardLevel1 cardTimeline">
+				<view class="sectionHeader">
+					<view class="sectionHeaderLeft">
+						<text class="sectionEn">Process</text>
+						<text class="sectionTitle">种植过程记录</text>
+					</view>
+				</view>
+
+				<view class="timelineList">
+					<view
+						v-for="(item, index) in traceDetail.farmTimeline"
+						:key="`timeline-${index}`"
+						:class="{
+							'timelineItem': true,
+							'is-key': item.stage === 'test',
+							'is-current': item.stage === 'pack'
+						}"
+					>
+						<view class="timelineLeft">
+							<view class="timelineDot" />
+							<view v-if="index !== traceDetail.farmTimeline.length - 1" class="timelineLine" />
+						</view>
+
+						<view class="timelineRight">
+							<text v-if="item.time" class="timelineTime">{{ item.time }}</text>
+							<text class="timelineTitle">{{ item.title }}</text>
+							<text class="timelineDesc">{{ item.desc }}</text>
+						</view>
+					</view>
+				</view>
+
+				<view class="timelineFootnote">
+					<text>以上信息真实有效,可追溯验证</text>
+				</view>
+			</view>
+
+			<!-- 种植现场实时画面 -->
+			<view v-if="traceDetail.batch?.exists && traceDetail.camera" class="card cardLevel1 cardLive">
+				<view class="sectionHeader">
+					<view class="sectionHeaderLeft">
+						<text class="sectionEn">Live Scene</text>
+						<text class="sectionTitle">种植现场</text>
+					</view>
+				</view>
+
+				<view class="liveMediaWrap">
+					<image
+						v-if="traceDetail.camera.coverImage"
+						class="liveCover"
+						:src="traceDetail.camera.coverImage"
+						mode="aspectFill"
+					/>
+					<view v-else class="livePlaceholder">
+						<view class="livePlayIcon">
+							<view class="livePlayDot" />
+							<view class="livePlayDot dot2" />
+							<view class="livePlayDot dot3" />
+						</view>
+						<text class="livePlaceholderMain">实时画面接入中</text>
+						<text class="livePlaceholderSub">请稍候查看现场情况</text>
+					</view>
+
+					<view class="liveStatusPill" :class="cameraStatus.value">
+						<view class="liveStatusDot" />
+						<text>{{ cameraStatusText }}</text>
+					</view>
+				</view>
+
+				<view class="liveDesc">
+					<text>{{ traceDetail.camera.desc }}</text>
+				</view>
+			</view>
+
 			<!-- 批次信息(可选:batch 可能不存在) -->
 			<view v-if="traceDetail.batch?.exists" class="card cardLevel1 cardBatch">
 				<view class="sectionHeader">
@@ -336,12 +424,62 @@ const MOCK_TRACE_DETAILS = {
 			no: '',
 			fileUrl: '',
 			images: ['']
+		},
+		traceConclusionCard: {
+			title: '溯源结论',
+			conclusion: '本批次产品来源清晰,已完成安全检测,过程可查',
+			desc: '检测材料与溯源数据已展示,可继续查看',
+			passed: true
+		},
+		farmTimeline: [
+			{
+				time: '2026-03-01',
+				stage: 'planting',
+				title: '开始种植',
+				desc: '本批次产品进入种植管理阶段'
+			},
+			{
+				time: '2026-03-12',
+				stage: 'care',
+				title: '生长期养护',
+				desc: '已完成灌溉、营养管理等日常养护'
+			},
+			{
+				time: '2026-03-20',
+				stage: 'inspection',
+				title: '田间巡检',
+				desc: '已完成长势检查与种植环境巡检'
+			},
+			{
+				time: '2026-03-30',
+				stage: 'harvest',
+				title: '成熟采收',
+				desc: '本批次产品进入成熟采收阶段'
+			},
+			{
+				time: '2026-03-31',
+				stage: 'test',
+				title: '安全检测',
+				desc: '已完成安全检测,相关结果可查'
+			},
+			{
+				time: '2026-04-01',
+				stage: 'pack',
+				title: '包装出库',
+				desc: '已完成包装整理,进入销售流通环节'
+			}
+		],
+		camera: {
+			liveUrl: '',
+			coverImage: '',
+			status: 'online',
+			desc: '来自农场实景画面,种植环境真实呈现'
 		}
 	},
 	reportPending: {
 		product: {
 			name: '',
-			spec: '',			
+			spec: '',
 			image: '',
 			intro: ''
 		},
@@ -371,12 +509,19 @@ const MOCK_TRACE_DETAILS = {
 			no: '',
 			fileUrl: '',
 			images: []
-		}
+		},
+		traceConclusionCard: {
+			title: '溯源结论',
+			conclusion: '本批次产品来源清晰,已完成安全检测,过程可查',
+			desc: '检测材料与溯源数据已展示,可继续查看',
+			passed: true
+		},
+		farmTimeline: []
 	},
 	certificatePending: {
 		product: {
 			name: '',
-			spec: '',	
+			spec: '',
 			image: '',
 			intro: ''
 		},
@@ -408,7 +553,14 @@ const MOCK_TRACE_DETAILS = {
 			status: '',
 			statusBadge: { text: '', type: '' },
 			emptyMessage: ''
-		}
+		},
+		traceConclusionCard: {
+			title: '溯源结论',
+			conclusion: '本批次产品来源清晰,已完成安全检测,过程可查',
+			desc: '检测材料与溯源数据已展示,可继续查看',
+			passed: true
+		},
+		farmTimeline: []
 	},
 	batchNotFound: {
 		product: {
@@ -429,7 +581,14 @@ const MOCK_TRACE_DETAILS = {
 			emptyMessage: ''
 		},
 		report: null,
-		certificate: null
+		certificate: null,
+		traceConclusionCard: {
+			title: '溯源结论',
+			conclusion: '本批次产品来源清晰,已完成安全检测,过程可查',
+			desc: '检测材料与溯源数据已展示,可继续查看',
+			passed: true
+		},
+		farmTimeline: []
 	},
 	batchOfflined: {
 		product: {
@@ -450,7 +609,14 @@ const MOCK_TRACE_DETAILS = {
 			emptyMessage: ''
 		},
 		report: null,
-		certificate: null
+		certificate: null,
+		traceConclusionCard: {
+			title: '溯源结论',
+			conclusion: '本批次产品来源清晰,已完成安全检测,过程可查',
+			desc: '检测材料与溯源数据已展示,可继续查看',
+			passed: true
+		},
+		farmTimeline: []
 	}
 }
 
@@ -468,7 +634,7 @@ onLoad((opts) => {
 	const batchId = fullPath.split('/').filter(Boolean).pop()
 	
 	// 优先使用路由参数中的 id,其次使用 URL 路径中的 id
-	const finalId = batchId
+	const finalId = batchId || 1
 	loadData(finalId)
 	
 	routeOptions.value = opts || {}
@@ -592,9 +758,140 @@ const traceDetail = computed(() => {
 			fileUrl: certFiles.length > 0 ? certFiles[0].url : '',
 			images: certFiles.map(f => f.url),
 			emptyMessage: '合格证待补充,上传完成后可查看大图。'
+		},
+		traceConclusionCard: {
+			title: '溯源结论',
+			conclusion: '本批次产品来源清晰,已完成安全检测,过程可查',
+			desc: '检测材料与溯源数据已展示,可继续查看',
+			passed: true
+		},
+		// 时间轴逻辑:演示态使用 mock + 真实态使用真实数据
+		farmTimeline: (() => {
+			// 判断是否有真实时间轴数据
+			const hasRealTimeline = Array.isArray(data.farmTimeline) && data.farmTimeline.length > 0
+
+			let timeline = []
+
+			if (!hasRealTimeline) {
+				// 演示态:使用完整 mock 时间轴(用于页面展示验证)
+				timeline = [
+					{ time: '2026-03-01', stage: 'planting', title: '开始种植', desc: '本批次产品进入种植管理阶段' },
+					{ time: '2026-03-12', stage: 'care', title: '生长期养护', desc: '已完成灌溉、营养管理等日常养护' },
+					{ time: '2026-03-20', stage: 'inspection', title: '田间巡检', desc: '已完成长势检查与种植环境巡检' },
+					{ time: data.produceDate || '', stage: 'harvest', title: '成熟采收', desc: '本批次产品进入成熟采收阶段' },
+					{ time: (data.reports?.[0]?.reportDate) || '', stage: 'test', title: '安全检测', desc: '已完成安全检测,相关结果可查' },
+					{ time: data.packageDate || '', stage: 'pack', title: '包装出库', desc: '已完成包装整理,进入销售流通环节' }
+				]
+			} else {
+				// 真实态:使用真实数据 + 补充系统节点
+				timeline = [...data.farmTimeline]
+				const stageSet = new Set(timeline.map(n => n.stage))
+
+				// 成熟采收
+				if (data.produceDate && !stageSet.has('harvest')) {
+					timeline.push({
+						time: data.produceDate,
+						stage: 'harvest',
+						title: '成熟采收',
+						desc: '本批次产品进入成熟采收阶段'
+					})
+				}
+
+				// 安全检测
+				if (data.reports && data.reports.length > 0 && !stageSet.has('test')) {
+					const validDates = data.reports
+						.map(r => r.reportDate)
+						.filter(d => d && /^\d{4}-\d{2}-\d{2}/.test(d))
+						.sort()
+					if (validDates.length > 0) {
+						timeline.push({
+							time: validDates[0],
+							stage: 'test',
+							title: '安全检测',
+							desc: '已完成安全检测,相关结果可查'
+						})
+					}
+				}
+
+				// 包装出库
+				if (data.packageDate && !stageSet.has('pack')) {
+					timeline.push({
+						time: data.packageDate,
+						stage: 'pack',
+						title: '包装出库',
+						desc: '已完成包装整理,进入销售流通环节'
+					})
+				}
+			}
+
+			// stage 顺序权重
+			const stageOrder = {
+				planting: 1,
+				care: 2,
+				inspection: 3,
+				harvest: 4,
+				test: 5,
+				pack: 6
+			}
+
+			// 按业务阶段排序,同 stage 内再按时间
+			timeline.sort((a, b) => {
+				const orderA = stageOrder[a.stage] || 99
+				const orderB = stageOrder[b.stage] || 99
+
+				// 先按 stage 排序
+				if (orderA !== orderB) {
+					return orderA - orderB
+				}
+
+				// 同 stage 再按时间
+				if (!a.time) return -1
+				if (!b.time) return 1
+
+				return a.time > b.time ? 1 : -1
+			})
+
+			return timeline.slice(0, 6)
+		})(),
+		camera: {
+			liveUrl: data.camera?.liveUrl || '',
+			coverImage: data.camera?.coverImage || '',
+			status: data.camera?.status || 'online',
+			desc: data.camera?.liveUrl
+				? '当前为种植现场实时画面,现场环境与种植状态可见'
+				: '来自农场实景画面,种植环境真实呈现'
 		}
 	}
 })
+
+// 种植现场状态:三态逻辑
+const cameraStatus = computed(() => {
+	const camera = traceDetail.value?.camera
+	if (!camera) return 'offline'
+
+	const hasLiveUrl = !!camera.liveUrl
+
+	// 有 liveUrl 但无封面图 → loading(信号接入中)
+	// 有 liveUrl 且有封面图 → online(可播放)
+	// 无 liveUrl → offline
+	if (hasLiveUrl && !camera.coverImage) {
+		return 'loading'
+	}
+	if (hasLiveUrl || camera.coverImage) {
+		return 'online'
+	}
+	return 'offline'
+})
+
+const cameraStatusText = computed(() => {
+	const map = {
+		loading: '连接中',
+		online: '实时在线',
+		offline: '暂未连接'
+	}
+	return map[cameraStatus.value] || '暂未连接'
+})
+
 const reportImages = computed(() => {
 	const items = traceDetail.value?.report?.items
 	if (Array.isArray(items)) {
@@ -1033,6 +1330,273 @@ function previewDoc(kind, index) {
 	background: rgba(252, 248, 244, 0.74);
 }
 
+/* 检测结论卡:结论型卡片,比普通资料卡更有结论感 */
+.cardConclusion {
+	background: rgba(252, 250, 244, 0.82);
+}
+
+.conclusionBody {
+	padding-top: 6rpx;
+}
+
+.conclusionLead {
+	display: block;
+	font-size: 32rpx;
+	font-weight: 680;
+	line-height: 1.5;
+	letter-spacing: 0.01em;
+	color: rgba(24, 38, 30, 0.96);
+	margin-bottom: 14rpx;
+}
+
+.conclusionDesc {
+	display: block;
+	font-size: 20rpx;
+	font-weight: 400;
+	line-height: 1.9;
+	color: rgba(84, 106, 93, 0.5);
+}
+
+/* 农事时间轴:关键种植过程 */
+.cardTimeline {
+	background: rgba(252, 250, 244, 0.82);
+}
+
+.timelineList {
+	padding-top: 4rpx;
+}
+
+.timelineItem {
+	display: flex;
+	padding-bottom: 24rpx;
+}
+
+.timelineItem:last-child {
+	padding-bottom: 0;
+}
+
+.timelineLeft {
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	width: 40rpx;
+	flex-shrink: 0;
+}
+
+.timelineDot {
+	width: 12rpx;
+	height: 12rpx;
+	border-radius: 50%;
+	background: rgba(39, 113, 76, 0.5);
+	flex-shrink: 0;
+}
+
+.timelineLine {
+	width: 1rpx;
+	flex: 1;
+	background: rgba(39, 113, 76, 0.2);
+	margin-top: 8rpx;
+}
+
+.timelineRight {
+	flex: 1;
+	padding-left: 24rpx;
+}
+
+.timelineTime {
+	display: block;
+	font-size: 19rpx;
+	font-weight: 400;
+	color: rgba(84, 106, 93, 0.5);
+	margin-bottom: 6rpx;
+	letter-spacing: 0.02em;
+}
+
+.timelineTitle {
+	display: block;
+	font-size: 27rpx;
+	font-weight: 600;
+	color: rgba(27, 41, 33, 0.88);
+	margin-bottom: 6rpx;
+	line-height: 1.3;
+}
+
+.timelineDesc {
+	display: block;
+	font-size: 21rpx;
+	font-weight: 400;
+	line-height: 1.7;
+	color: rgba(84, 106, 93, 0.75);
+}
+
+/* 关键节点(安全检测):轻强调 */
+.timelineItem.is-key .timelineDot {
+	background: rgba(39, 113, 76, 0.7);
+}
+
+.timelineItem.is-key .timelineTitle {
+	font-weight: 600;
+	color: rgba(27, 41, 33, 0.9);
+}
+
+/* 当前节点(包装出库):主高亮 */
+.timelineItem.is-current .timelineDot {
+	background: #2f7d55;
+	box-shadow: 0 0 0 6rpx rgba(47, 125, 85, 0.12);
+}
+
+.timelineItem.is-current .timelineTitle {
+	font-weight: 700;
+	color: rgba(20, 60, 40, 0.95);
+}
+
+/* 底部可信来源说明 */
+.timelineFootnote {
+	margin-top: 20rpx;
+	font-size: 20rpx;
+	color: rgba(84, 106, 93, 0.45);
+	line-height: 1.6;
+}
+
+/* 种植现场实时画面模块 */
+.cardLive {
+	background: rgba(252, 250, 244, 0.82);
+}
+
+.liveMediaWrap {
+	position: relative;
+	width: 100%;
+	height: 380rpx;
+	border-radius: 20rpx;
+	overflow: hidden;
+	background: linear-gradient(
+		160deg,
+		rgba(39, 113, 76, 0.04) 0%,
+		rgba(39, 113, 76, 0.015) 50%,
+		rgba(39, 113, 76, 0.05) 100%
+	);
+	border: 1rpx solid rgba(39, 75, 57, 0.08);
+	box-shadow: inset 0 2rpx 12rpx rgba(39, 113, 76, 0.04);
+}
+
+.liveCover {
+	width: 100%;
+	height: 100%;
+}
+
+.livePlaceholder {
+	width: 100%;
+	height: 100%;
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+	background: transparent;
+}
+
+.livePlayIcon {
+	display: flex;
+	align-items: center;
+	gap: 8rpx;
+	margin-bottom: 20rpx;
+}
+
+.livePlayDot {
+	width: 8rpx;
+	height: 8rpx;
+	border-radius: 50%;
+	background: rgba(39, 113, 76, 0.35);
+	animation: livePulse 1.4s ease-in-out infinite;
+}
+
+.livePlayDot.dot2 {
+	animation-delay: 0.2s;
+}
+
+.livePlayDot.dot3 {
+	animation-delay: 0.4s;
+}
+
+@keyframes livePulse {
+	0%, 100% {
+		opacity: 0.3;
+		transform: scale(0.8);
+	}
+	50% {
+		opacity: 1;
+		transform: scale(1.1);
+	}
+}
+
+.livePlaceholderMain {
+	font-size: 26rpx;
+	font-weight: 500;
+	color: rgba(39, 113, 76, 0.5);
+	margin-bottom: 10rpx;
+}
+
+.livePlaceholderSub {
+	font-size: 20rpx;
+	color: rgba(84, 106, 93, 0.35);
+}
+
+.liveStatusPill {
+	position: absolute;
+	top: 20rpx;
+	right: 20rpx;
+	display: flex;
+	align-items: center;
+	gap: 8rpx;
+	padding: 8rpx 18rpx;
+	border-radius: 30rpx;
+	font-size: 20rpx;
+	font-weight: 600;
+}
+
+.liveStatusDot {
+	width: 10rpx;
+	height: 10rpx;
+	border-radius: 50%;
+	flex-shrink: 0;
+}
+
+.liveStatusPill.online {
+	background: rgba(47, 125, 85, 0.1);
+	color: #2f7d55;
+}
+
+.liveStatusPill.online .liveStatusDot {
+	background: #2f7d55;
+	animation: statusPulse 2s ease-in-out infinite;
+}
+
+@keyframes statusPulse {
+	0%, 100% {
+		opacity: 1;
+		box-shadow: 0 0 0 0 rgba(47, 125, 85, 0.4);
+	}
+	50% {
+		opacity: 0.7;
+		box-shadow: 0 0 0 4rpx rgba(47, 125, 85, 0);
+	}
+}
+
+.liveStatusPill.offline {
+	background: rgba(84, 106, 93, 0.08);
+	color: rgba(84, 106, 93, 0.55);
+}
+
+.liveStatusPill.offline .liveStatusDot {
+	background: rgba(84, 106, 93, 0.4);
+}
+
+.liveDesc {
+	margin-top: 16rpx;
+	font-size: 20rpx;
+	color: rgba(84, 106, 93, 0.5);
+	line-height: 1.6;
+}
+
 /* ================================================
    微动效:让页面"活起来"
    ================================================ */
@@ -1070,6 +1634,11 @@ function previewDoc(kind, index) {
 	animation: cardEnter 0.5s cubic-bezier(0.22, 0.78, 0.35, 1) 0.15s both;
 }
 
+/* 检测结论卡 */
+.cardConclusion {
+	animation: cardEnter 0.5s cubic-bezier(0.22, 0.78, 0.35, 1) 0.2s both;
+}
+
 /* 农场卡 */
 .cardFarm {
 	animation: cardEnter 0.5s cubic-bezier(0.22, 0.78, 0.35, 1) 0.25s both;
@@ -1264,8 +1833,8 @@ function previewDoc(kind, index) {
 
 .sectionTitle {
 	font-size: 27rpx;
-	font-weight: 680;
-	color: rgba(60, 72, 64, 0.82);
+	font-weight: 620;
+	color: rgba(60, 72, 64, 0.72);
 }
 
 .statusBadge {

+ 1560 - 0
佳友厚苑_溯源页第二阶段详细开发设计方案.md

@@ -0,0 +1,1560 @@
+# 佳友厚苑溯源页第二阶段详细开发设计方案
+
+## 1. 文档说明
+
+### 1.1 文档目的
+本文档用于指导 **佳友厚苑溯源页第二阶段** 的产品设计、前端开发、后端接口、数据结构补充与后续联调验收。  
+适用对象包括:
+
+- 产品经理
+- 前端开发
+- 后端开发
+- Cursor / AI 辅助开发
+- 测试与运营同事
+- 后续需求回顾与迭代参考
+
+### 1.2 当前阶段背景
+佳友厚苑溯源页第一阶段已完成并具备以下能力:
+
+- 商品信息展示
+- 农场信息展示
+- 批次信息展示
+- 检测报告查看
+- 合格证查看
+- 二维码标签生成与打印
+- 扫码进入 H5 溯源页
+
+第一阶段目标已实现:
+
+> 跑通溯源链路,做到“能看”。
+
+### 1.3 第二阶段目标
+第二阶段不再是简单增加模块,而是围绕以下目标展开:
+
+1. 在现有页面风格基础上,增强用户第一眼信任感
+2. 加入种植过程可视化内容,形成更完整的可信链路
+3. 引入农事时间轴、实时监控、环境状态等内容
+4. 将冰冷数据转化为用户可理解、可感知的信任表达
+5. 在不破坏当前第一阶段页面风格的前提下,完成信任升级
+
+### 1.4 第二阶段一句话目标
+> 从“资料完整的溯源页”,升级为“让消费者放心的信任页”。
+
+### 1.5 第二阶段范围边界
+
+- 首屏信任感优化(基于现有页头与 Hero 商品图,不额外新增 Hero 内重文案)
+- 溯源结论卡(以本批次综合溯源结论为主,不仅限于检测结果)
+- 关键农事时间轴
+- 实时监控画面展示
+- 当前环境状态展示
+- 检测报告与合格证作为证明层保留
+- 页面底部安心收口文案增强
+
+#### 本阶段不包含
+- 商城购买链路打通
+- 加购、下单、支付等交易能力
+- 复杂的多 Tab 页面重构
+- 大屏式设备监控看板
+- 监管报表、导出报表等后台能力
+- 复杂权限系统或内容审核流重构
+
+#### 实施原则
+第二阶段以“增强信任表达”为目标,不以增加功能数量为目标。
+
+---
+
+## 2. 用户与信任目标分析
+
+### 2.1 面向用户
+当前溯源页主要面向两类用户:
+
+1. 普通消费者
+2. 高端用户 / 送礼用户
+
+### 用户共性特征
+- 不具备专业农业知识
+- 不愿意阅读复杂报告和大量数据
+- 更关注结果而非过程细节
+- 对“真实性、安全性、新鲜度”敏感
+- 希望快速获得“可不可以买、可不可以放心吃”的判断
+
+### 2.2 用户核心关注点
+用户普遍会关心以下问题:
+
+- 是否安全,尤其是农药残留、重金属等问题
+- 是否真实产地
+- 是否真实种植,不是“包装出来的”
+- 是否新鲜,是否刚采摘、刚包装
+- 是否有检测与证明材料
+
+### 当前阶段优先聚焦的信任点
+第二阶段建议重点强化两个核心信任点:
+
+1. **安全**:农残、检测、合格证
+2. **真实新鲜**:种植过程、采收、实时现场、环境状态
+
+### 2.3 信任表达策略
+第二阶段的信任,不建议以“科技感”作为主导,而应以:
+
+- 真实可信
+- 官方可信
+
+为主,技术能力作为辅助支撑。
+
+### 推荐信任构成比例
+- 70% 真实可信
+- 30% 官方可信
+
+### 不建议作为主表达
+- 纯设备炫技
+- 纯技术指标堆砌
+- 大量术语和参数展示
+
+### 2.4 第二阶段信任表达原则
+第二阶段所有新增内容必须遵守以下原则:
+
+#### 原则 1:先给结论,再给证据
+错误方式:
+- 先给报告、参数、曲线,让用户自己判断
+
+正确方式:
+- 先告诉用户“这批产品来源清晰、检测完成、过程可查”
+- 再提供报告、证书、数据作为佐证
+
+#### 原则 2:少讲技术,多讲真实
+用户不关心:
+- 你用了几个传感器
+- 采集频率是多少
+- 设备品牌是什么
+
+用户关心:
+- 现场能不能看见
+- 种植过程是不是真的
+- 检测是否真实出具
+- 数据是否表明环境正常
+
+#### 原则 3:数据是证据,结论才是信任
+环境数据、农事数据、检测报告都不是目的,它们只是用于支撑以下结论:
+
+- 本批次产品安全可查
+- 本批次产品真实种植
+- 本批次产品过程可见
+- 本批次产品值得放心食用
+
+---
+
+## 3. 第二阶段页面整体策略
+
+### 3.1 总体策略
+第二阶段不推翻第一阶段页面风格与代码结构,而是在当前基础上进行:
+
+- 模块新增
+- 模块顺序优化
+- 文案升级
+- 数据展示策略升级
+
+### 不做的事
+- 不做整体视觉重构
+- 不引入复杂 tab 结构
+- 不把页面做成数据看板
+- 不做重后台化表达
+
+### 3.2 页面结构策略
+第二阶段页面结构由原来的“资料罗列型”调整为“信任递进型”。
+
+### 信任递进型逻辑
+1. 第一屏先建立安全感
+2. 第二屏再讲来源与过程
+3. 第三屏提供证明材料
+4. 最后做安心收口
+
+### 3.3 页面交互策略
+#### 建议
+- 继续采用单页纵向滚动结构
+- 不建议第二阶段上 tab
+- 如果后期内容特别多,可考虑“轻锚点导航”,而不是 tab
+
+#### 原因
+扫码页不是后台系统页,用户行为是:
+- 打开
+- 扫一眼
+- 往下确认
+- 看证明材料
+
+不是:
+- 切换 tab
+- 主动查不同模块
+
+---
+
+## 4. 第二阶段页面模块设计方案
+
+以下模块顺序为建议实施顺序,也是推荐最终页面展示顺序。
+
+### 4.1 模块一:首屏信任头图(Hero 升级)
+
+#### 4.1.1 模块目标
+确保首屏仍然具备“官方溯源页”的气质,但不通过在 Hero 图内叠加大段信任文案来实现。
+
+#### 4.1.2 当前判断
+经过页面实际验证后确认:
+- 当前顶部 `brandPageHeader` 已具备“官方溯源 / 品质可验”的定调作用
+- 当前 Hero 商品图本身已经具备较强的品牌感、品质感与送礼感
+- 若在 Hero 图内继续叠加大段信任文案,容易出现:
+  - 文案可读性差
+  - 遮挡商品主图
+  - 信息重复
+  - 破坏首屏高级感
+
+因此,第二阶段不建议继续在 Hero 图内新增额外的信任标签、重文案或多行结论文案。
+
+#### 4.1.3 最终策略
+模块一保留为“首屏信任感优化”目标,但当前版本的实现策略为:
+
+- 保留现有 `brandPageHeader`
+- 保留现有 Hero 商品图表现力
+- 保留现有商品信息面板结构
+- 不在 Hero 图内额外新增信任标签
+- 不在 Hero 图内新增主结论 / 副结论文案
+
+也就是说:
+
+> 首屏的“官方感”和“品质感”由现有页头 + Hero 商品图共同承担,
+> 第二阶段真正的信任表达重点下沉到“溯源结论卡”等后续模块。
+
+#### 4.1.4 实现要求
+当前版本中,模块一不新增以下内容:
+- `heroTrustBlock`
+- `heroTrustPill`
+- Hero 图内额外标签
+- Hero 图内多行信任文案
+
+允许的调整范围仅包括:
+- 保持现有 Hero 首屏结构不变
+- 如有必要,仅对现有首屏留白、间距、页头与 Hero 之间关系做极轻微优化
+
+#### 4.1.5 设计结论
+模块一不是取消,而是经过验证后确认:
+
+- 模块一的目标仍成立:首屏要有“可信的官方气质”
+- 但当前最优实现不是“继续加内容”
+- 而是“避免重复表达,保持首屏克制”
+
+这是一次经过验证后的设计收敛,而非方案遗漏。
+
+### 4.2 模块二:溯源结论卡(优先级最高)
+
+#### 4.2.1 模块目标
+用最短路径回答用户最关心的问题:
+
+> 这批产品值不值得信任?
+
+该模块不是只回答“是否检测通过”,而是对本批次产品的溯源信息做一个前置性的综合结论表达。
+
+#### 4.2.2 重要性说明
+当前页面虽然已有检测报告、合格证、批次信息等资料,但缺少一个面向消费者的“总括性结论”。  
+这会导致:
+
+- 用户需要自己从不同模块中拼凑判断
+- 页面虽然资料完整,但“第一眼可信”感不够强
+- 检测报告、合格证、后续农事时间轴、环境状态之间缺少一个统一的解释入口
+
+因此,第二阶段建议将原“检测结论卡”升级为“溯源结论卡”,让该模块承担:
+
+- 对本批次商品做总括性解释
+- 先告诉用户“来源清晰、检测完成、过程可查”
+- 再引导用户继续查看后方材料与过程数据
+
+#### 4.2.3 模块建议位置
+建议放在:
+- Hero 后
+- 商品信息后
+- 农场信息前
+
+推荐顺序:Hero → 溯源结论 → 商品信息 / 农场信息
+
+#### 4.2.4 模块内容建议
+标题建议:
+- 溯源结论
+- 本批次溯源结论
+
+推荐默认使用:
+- `溯源结论`
+
+主结论建议:
+- 本批次产品已完成安全检测,来源清晰、过程可查
+- 本批次产品溯源信息完整,可安心选购
+- 本批次产品已完成检测与记录归档,相关信息可查
+
+补充说明建议:
+- 本页面已同步展示农场信息、批次信息、检测材料及相关过程记录
+- 农残、重金属等关键指标均在安全范围内,相关信息可在下方查看
+- 相关检测结果、合格证及批次信息均已归档,可继续查看
+
+#### 4.2.5 视觉建议
+- 仍然采用“结论型卡片”
+- 不做成报告摘要卡
+- 不做成参数表格
+- 不做成警示提示条
+- 通过“标题 + 主结论 + 补充说明”三层结构表达
+
+信息层级建议:
+1. 中文标题(轻)
+2. 主结论(最强)
+3. 补充说明(最轻)
+
+#### 4.2.6 数据字段建议
+建议将字段命名从“检测结论”扩展为更适合整页总结的结构:
+
+| 字段名 | 类型 | 说明 |
+|---|---|---|
+| `traceConclusion` | string | 溯源主结论 |
+| `traceSummary` | string | 溯源补充说明 |
+| `testPassed` | boolean | 是否完成检测并通过,可选 |
+| `testOrganization` | string | 检测机构或检测来源说明,可选 |
+| `testSourceType` | string | 检测来源类型:如 `self_device` / `third_party` |
+
+前端推荐结构:
+
+```js
+traceConclusionCard: {
+  title: '溯源结论',
+  conclusion: '本批次产品已完成安全检测,来源清晰、过程可查',
+  desc: '本页面已同步展示农场信息、批次信息、检测材料及相关过程记录。',
+  testPassed: true,
+  testSourceType: 'self_device'
+}
+```
+
+#### 4.2.7 数据来源建议
+当前阶段检测大概率以“自采设备检测”为主,因此:
+
+- 不应在该模块中默认强调“第三方检测”
+- 不应把“第三方机构出具”作为固定文案
+- 应根据真实情况决定是否展示检测来源说明
+
+建议规则:
+- 若为自采设备检测,则以“已完成安全检测 / 关键指标在安全范围内”表达为主
+- 若后期接入第三方检测,可再动态补充“第三方检测结果”文案
+- 文案必须与真实检测来源一致,不能为提升信任感而写死第三方背书
+
+### 4.3 模块三:商品信息(保留,轻增强)
+
+#### 4.3.1 当前状态
+当前商品信息模块已较成熟:
+- 商品名称
+- 规格
+- 商品简介
+- 右上角状态徽章
+
+#### 4.3.2 第二阶段建议
+- 保留当前结构
+- 不做大改
+- 只增强与“检测结论卡”的配合关系
+
+#### 4.3.3 优化方向
+- 保持商品信息承担“正式介绍商品”的职责
+- 不要让商品信息承担“信任主表达”
+- 右上角检验合格徽章可继续保留,但做得更弱一点,避免重复抢戏
+
+### 4.4 模块四:农场信息升级为“真实源头背书卡”
+
+#### 4.4.1 当前问题
+当前农场信息更像普通资料卡,表达略偏中性。
+
+#### 4.4.2 业务真实情况
+当前农场信息不能一味往“高大上智慧农场”方向包装。  
+因为实际情况是:
+- 多为有机农场
+- 也可能来自普通农户或合作农户
+- 不一定都有特别强的规模化、示范化背书
+
+#### 4.4.3 第二阶段策略
+不强调“高大上基地”,强调:
+- 真实源头
+- 明确产地
+- 现场可见
+- 过程可追溯
+
+#### 4.4.4 推荐标题
+- 农场信息(可保留)
+- 产地来源
+- 源头农场
+
+#### 4.4.5 推荐文案方向
+- 产品来源于宿州·萧县种植区域
+- 产品来自真实种植农户与合作种植基地
+- 农场环境、种植过程及检测信息均可追溯
+
+#### 4.4.6 素材建议
+优先使用真实素材:
+- 田间实景
+- 大棚实景
+- 采收现场
+- 农户作业现场
+- 农场门头或识别图
+
+#### 4.4.7 数据字段建议
+现有字段基本够用:
+- `farmName`
+- `farmRegion`
+- `farmImage`
+- `farmIntro`
+
+可选补充:
+
+| 字段名 | 类型 | 说明 |
+|---|---|---|
+| `farmType` | string | 如:合作农户 / 自营基地 / 合作基地 |
+| `farmTag` | string[] | 如:有机种植 / 标准化管理 / 真实可追溯 |
+
+### 4.5 模块五:关键农事时间轴(第二阶段核心模块)
+
+#### 4.5.1 模块目标
+让用户感受到:
+
+> 这批产品是有过程、有管理、有记录地种出来的。
+
+#### 4.5.2 模块定位
+时间轴不是后台操作日志,而是消费者可理解的“成长过程”。
+
+#### 4.5.3 当前难点
+农事记录数据来自后台农事任务,存在:
+- 数据多
+- 任务碎
+- 类型复杂
+- 表达偏后台管理语义
+
+#### 4.5.4 正确策略
+主时间轴不直接展示原始农事记录,而是:
+
+> 将农事记录 + 批次信息 + 检测信息,组合为 4–6 个关键阶段节点。
+
+#### 4.5.5 关键时间轴阶段建议
+建议主时间轴最多展示以下 6 类阶段:
+
+1. 开始种植
+2. 生长期养护
+3. 田间巡检 / 健康管理
+4. 成熟采收
+5. 安全检测
+6. 包装出库
+
+如某阶段无数据,则可跳过。
+
+#### 4.5.6 农事记录 → 时间轴节点映射规则表
+
+##### 任务类型映射表
+
+| 后台任务类型 | 是否进入主时间轴 | 映射阶段 | 前端标题建议 | 前端说明建议 |
+|---|---:|---|---|---|
+| 施肥 | 是 | 生长期养护 | 营养管理 / 生长期养护 | 已完成生长期养分管理 |
+| 灌溉 | 是 | 生长期养护 | 水分管理 / 生长期养护 | 已完成日常灌溉养护 |
+| 巡检 | 是 | 田间巡检 / 日常管理 | 田间巡检 | 已完成长势检查与环境巡检 |
+| 采摘 | 是 | 成熟采收 | 成熟采收 | 本批次产品进入成熟采收阶段 |
+| 除草 | 视情况 | 田间养护 / 日常管理 | 田间养护 | 已完成田间环境整理与养护 |
+| 打药 | 谨慎展示 | 健康管理 / 病虫害防控 | 健康管理 | 已完成种植健康管理与病虫害防控 |
+| 其他 | 否 | 不建议直接进入主时间轴 | - | 仅在更多记录中展示 |
+| 测试 | 否 | 不展示 | - | 不进入消费者时间轴 |
+
+#### 4.5.7 时间轴节点生成规则
+
+规则 1:主时间轴只展示关键阶段,不按“每条农事记录 = 一个节点”,而是按阶段合并。
+
+规则 2:同类任务合并。  
+例如多次灌溉 / 施肥,可合并成一个“生长期养护”节点。
+
+规则 3:后台术语转译为消费者语言。  
+例如:
+- 施肥 → 营养管理
+- 打药 → 健康管理 / 病虫害防控
+- 巡检 → 田间巡检
+
+规则 4:优先保留高信任价值节点。  
+优先级顺序:
+1. 开始种植
+2. 生长期养护
+3. 田间巡检 / 健康管理
+4. 成熟采收
+5. 安全检测
+6. 包装出库
+
+#### 4.5.8 系统节点补充规则(非常重要)
+农事记录本身通常不包含“检测完成”“包装出库”这类高信任节点,因此这两个节点不能强依赖农事记录,而应由系统补充生成。
+
+##### 安全检测节点来源
+来源:
+- `report.items[].detectDate`
+
+生成节点示例:
+```json
+{
+  "time": "2026-03-31",
+  "stage": "test",
+  "title": "安全检测",
+  "desc": "已完成安全检测,相关结果可查"
+}
+```
+
+##### 包装节点来源
+来源:
+- `batch.packTime`(即 `data.packageDate`)
+
+生成节点示例:
+```json
+{
+  "time": "2026-04-01",
+  "stage": "pack",
+  "title": "包装出库",
+  "desc": "已完成包装整理,进入销售流通环节"
+}
+```
+
+##### 采收节点来源
+来源:
+- `batch.harvestTime`(即 `data.produceDate`)
+
+生成节点示例:
+```json
+{
+  "time": "2026-03-30",
+  "stage": "harvest",
+  "title": "成熟采收",
+  "desc": "本批次产品进入成熟采收阶段"
+}
+```
+
+#### 4.5.9 推荐前端展示数据结构
+```js
+timeline: [
+  {
+    time: '2026-03-01',
+    stage: 'planting',
+    title: '开始种植',
+    desc: '本批次产品进入种植管理阶段'
+  },
+  {
+    time: '2026-03-18',
+    stage: 'care',
+    title: '生长期养护',
+    desc: '已完成灌溉、营养管理等日常养护'
+  },
+  {
+    time: '2026-03-26',
+    stage: 'inspection',
+    title: '田间巡检',
+    desc: '已完成长势检查与种植环境巡检'
+  },
+  {
+    time: '2026-03-30',
+    stage: 'harvest',
+    title: '成熟采收',
+    desc: '本批次产品进入成熟采收阶段'
+  },
+  {
+    time: '2026-03-31',
+    stage: 'test',
+    title: '安全检测',
+    desc: '已完成安全检测,相关结果可查'
+  },
+  {
+    time: '2026-04-01',
+    stage: 'pack',
+    title: '包装出库',
+    desc: '已完成包装整理,进入销售流通环节'
+  }
+]
+```
+
+#### 4.5.10 更多农事记录
+主时间轴之外,建议保留“查看更多农事记录”入口。
+
+用途:
+- 满足查证
+- 不打断主页面节奏
+- 保留完整真实性
+
+展开内容建议:
+- 时间
+- 任务类型
+- 任务名称
+- 任务说明
+- 执行人(可选)
+
+#### 4.5.10.1 时间轴节点数量控制与排序规则
+
+为避免时间轴过长、过碎、不可读,主时间轴必须增加数量控制与排序规则。
+
+##### 数量控制
+- 主时间轴建议展示 4–6 个节点
+- 当原始农事记录与系统节点合并后超过 6 个时,按优先级裁剪
+- 优先保留的节点顺序为:
+  1. 开始种植
+  2. 生长期养护
+  3. 田间巡检 / 健康管理
+  4. 成熟采收
+  5. 安全检测
+  6. 包装出库
+
+##### 同阶段合并规则
+- 同阶段出现多条记录时,不逐条展示
+- 应合并为一个阶段节点,并提炼成一句消费者可理解的话术
+- 同阶段节点取“最能代表当前阶段”的时间点作为展示时间
+
+##### 排序规则
+- 主时间轴统一按时间升序排列
+- 当出现同一天多个节点时,建议排序优先级为:
+  1. 开始种植
+  2. 生长期养护
+  3. 田间巡检 / 健康管理
+  4. 成熟采收
+  5. 安全检测
+  6. 包装出库
+
+##### 缺失数据处理规则
+- 若无开始种植节点,可从最早一条有效农事记录开始展示
+- 若无检测结果日期或可用检测记录,则不生成“安全检测”节点
+- 若无包装时间,则不生成“包装出库”节点
+- 主时间轴不强行为凑满 6 个节点而制造虚假节点
+
+### 4.6 模块六:实时监控画面
+
+#### 4.6.1 模块目标
+把“真实种植现场”呈现出来,形成最直接的可信感。
+
+#### 4.6.2 为什么重要
+这是第二阶段最具差异化的模块之一,用户看到实时现场会明显增强真实感。
+
+#### 4.6.3 展示原则
+- 不强调“摄像头”,强调“现场可见”
+- 不讲技术术语,讲“当前画面”“实时可见”
+
+#### 4.6.4 推荐标题
+- 种植现场实时画面
+- 当前农场监控画面
+
+#### 4.6.5 推荐文案
+- 当前为农场种植区实时画面
+- 现场环境与种植状态可见
+
+#### 4.6.6 展示方式建议
+第一版推荐:
+- 视频窗口
+- 在线状态
+- 轻说明
+
+如果视频流接入稳定,可直接嵌实时视频。  
+如果考虑移动端性能,也可先使用封面图 + 点击播放。
+
+#### 4.6.7 数据字段建议
+
+| 字段名 | 类型 | 说明 |
+|---|---|---|
+| `camera.liveUrl` | string | 实时视频流地址 |
+| `camera.coverImage` | string | 封面图 |
+| `camera.status` | string | online / offline |
+| `camera.desc` | string | 辅助说明 |
+
+### 4.7 模块七:当前环境状态(数据转结论)
+
+#### 4.7.1 当前风险
+如果直接展示设备数据:
+- 温度 18℃
+- 湿度 65%
+- 土壤 PH 6.4
+
+会显得冰冷、看不懂、技术化。
+
+#### 4.7.2 正确策略
+环境模块必须遵循:
+
+> 先给结论,再给数据。
+
+#### 4.7.3 推荐展示形式
+标题:
+- 当前种植环境
+- 当前环境状态
+
+主结论:
+- 当前环境稳定,适宜草莓生长
+- 当前种植环境良好,生长状态正常
+
+辅助状态块:
+- 温度适宜
+- 湿度正常
+- 光照充足
+- 土壤墒情良好
+
+#### 4.7.4 是否加入折线图
+结论:可以加,但不能让线图成为主角。
+
+推荐方案:
+- 先做“环境结论 + 小趋势图”
+- 只做 1~2 张轻量趋势图
+- 不做大屏式复杂监控图表
+
+优先图表:
+- 近 24 小时温度趋势
+- 近 24 小时湿度趋势
+
+图表位置:
+环境结论下方,作为佐证信息,不抢视觉中心。
+
+#### 4.7.5 视觉建议
+- 趋势图轻量化
+- 线条细
+- 不做重坐标轴
+- 不做多图叠加
+- 不要超过 2 张图
+
+#### 4.7.6 数据结构建议
+```js
+environment: {
+  summary: '当前环境稳定,适宜草莓生长',
+  items: [
+    { label: '温度', value: '18℃', status: '适宜' },
+    { label: '湿度', value: '65%', status: '正常' },
+    { label: '光照', value: '充足', status: '正常' },
+    { label: '土壤', value: '墒情良好', status: '正常' }
+  ],
+  charts: [
+    { type: 'temperature', values: [] },
+    { type: 'humidity', values: [] }
+  ]
+}
+```
+
+#### 4.7.7 数据库 / 接口建议
+如果已有设备接口,无需改数据库,可由后端聚合后返回给溯源页接口。  
+若无聚合接口,可新增:
+
+| 字段名 | 类型 | 说明 |
+|---|---|---|
+| `environmentSummary` | string | 环境结论文案 |
+| `environmentItems` | json | 环境状态卡 |
+| `environmentCharts` | json | 趋势图数据 |
+
+### 4.8 模块八:批次信息(后置)
+
+#### 4.8.1 建议
+保留当前结构,不做大改。
+
+#### 4.8.2 位置调整
+放在:
+- 时间轴
+- 实时画面
+- 环境状态
+
+之后
+
+#### 4.8.3 原因
+批次信息属于查证层,不是信任起点。
+
+### 4.9 模块九:检测报告(证明层)
+
+#### 4.9.1 建议
+保留当前横向滑动卡片列表。
+
+#### 4.9.2 第二阶段定位
+检测报告是“证据层”,不是“主结论层”。
+
+#### 4.9.3 原则
+- 保留“点击查看大图”
+- 不再强调报告本身
+- 通过前面的检测结论卡,先让用户理解“结果”
+- 再通过这里让用户验证“材料”
+
+### 4.10 模块十:合格证(证明层)
+
+#### 4.10.1 建议
+保持当前单证小图模式,不放大,不复杂化。
+
+#### 4.10.2 目的
+作为信任补充证明材料,和检测报告共同构成证据层。
+
+### 4.11 模块十一:底部安心收口
+
+#### 4.11.1 当前问题
+当前 footer 已经有客服电话和品牌签名,但结束稍显平淡。
+
+#### 4.11.2 建议新增一行轻收口文案
+例如:
+- 本产品已完成全流程溯源记录,信息真实可查,请放心食用。
+
+#### 4.11.3 当前 footer 可继续保留
+- 联系客服
+- 电话
+- 品牌签名
+
+#### 4.11.4 推荐签名文案
+- 佳友厚苑 · 安心之选
+- 佳友厚苑 · 源头可见
+- 佳友厚苑 · 溯源可鉴
+
+---
+
+## 5. 第二阶段推荐模块顺序
+
+最终推荐页面顺序如下:
+
+1. 品牌页头
+2. Hero 首屏延续现状(不新增额外信任标签或重文案)
+3. 溯源结论卡
+4. 商品信息
+5. 农场信息
+6. 关键农事时间轴
+7. 种植现场实时画面
+8. 当前环境状态
+9. 批次信息
+10. 检测报告
+11. 合格证
+12. 收口说明 + footer
+
+---
+
+## 6. 数据结构与接口设计建议
+
+### 6.1 溯源页主接口建议
+建议继续使用一个聚合接口,例如:
+- `getTraceDetail(batchId)`
+
+但返回数据要扩展。
+
+#### 建议返回结构
+```json
+{
+  "product": {},
+  "farm": {},
+  "batch": {},
+  "report": {},
+  "certificate": {},
+  "timeline": [],
+  "farmTasks": [],
+  "camera": {},
+  "environment": {},
+  "traceConclusion": "",
+  "traceSummary": ""
+}
+```
+
+### 6.2 字段增补建议
+
+#### 新增字段:溯源结论
+| 字段名 | 类型 | 说明 |
+|---|---|---|
+| `traceConclusion` | string | 溯源主结论 |
+| `traceSummary` | string | 溯源补充说明 |
+| `testPassed` | boolean | 是否通过检测 |
+| `testOrganization` | string | 检测机构名称或检测来源说明 |
+| `testSourceType` | string | 检测来源类型,如 `self_device` / `third_party` |
+
+#### 新增字段:时间轴
+| 字段名 | 类型 | 说明 |
+|---|---|---|
+| `timeline` | json/array | 关键时间轴节点 |
+| `farmTasks` | json/array | 原始农事记录列表 |
+
+#### 新增字段:实时监控
+| 字段名 | 类型 | 说明 |
+|---|---|---|
+| `cameraLiveUrl` | string | 实时流地址 |
+| `cameraCover` | string | 封面图 |
+| `cameraStatus` | string | 在线状态 |
+
+#### 新增字段:环境状态
+| 字段名 | 类型 | 说明 |
+|---|---|---|
+| `environmentSummary` | string | 环境结论 |
+| `environmentItems` | json | 状态项 |
+| `environmentCharts` | json | 趋势图数据 |
+
+### 6.3 缺省数据与前端兜底策略
+
+第二阶段页面涉及多个新增模块,后端字段可能存在分阶段补齐的情况,因此前端必须设计缺省数据兜底策略。
+
+#### 溯源结论卡
+- 若 `traceConclusion` 为空,则该模块整体不展示
+- 不建议在前端写死“第三方检测”“已通过检测”等强结论文案
+
+#### 农事时间轴
+- 若无农事记录,但有采收 / 检测 / 包装等系统节点,则仍可展示简化版时间轴
+- 若农事记录与系统节点都为空,则隐藏时间轴模块
+- 真实接口场景下,若后端未返回时间轴或可用于生成时间轴的真实数据,前端不得直接回退展示 mock 农事过程
+
+#### 实时监控画面
+- 若 `camera.liveUrl` 为空但 `camera.coverImage` 有值,则展示封面图模式
+- 若监控数据整体为空,则隐藏该模块
+
+#### 当前环境状态
+- 若仅有 summary,无具体 items / charts,则只展示结论文案
+- 若 summary、items、charts 全为空,则隐藏该模块
+
+#### 检测报告 / 合格证
+- 延续第一阶段逻辑:无数据时展示“待补充”或直接隐藏,由产品最终确定
+
+#### 总体原则
+- 前端不得为了页面完整性伪造关键可信信息
+- 对于“检测通过”“实时在线”“环境正常”等结论性内容,必须以真实字段为准
+
+---
+
+## 7. 数据库字段增补建议
+
+> 目标:支持第二阶段页面展示,但避免一次性扩表过度。
+
+### 7.1 批次表(建议已有字段复用)
+建议确认并继续使用以下字段:
+
+| 字段名 | 类型 | 说明 |
+|---|---|---|
+| `batch_no` | varchar | 批次号 |
+| `produce_date` | datetime/date | 生产/采收时间 |
+| `package_date` | datetime/date | 包装时间 |
+| `status` | varchar | 批次状态 |
+| `product_name` | varchar | 商品名称 |
+| `product_spec` | varchar | 商品规格 |
+| `product_desc` | text | 商品简介 |
+| `product_image` | varchar | 商品图片 |
+| `farm_name` | varchar | 农场名称 |
+| `farm_region` | varchar | 农场地区 |
+| `farm_image` | varchar | 农场图片 |
+| `farm_intro` | text | 农场介绍 |
+
+### 7.2 溯源结论扩展表 / 扩展字段(建议新增)
+可新建扩展表,也可挂在批次表上。推荐扩展表:`trace_batch_extra`
+
+| 字段名 | 类型 | 说明 |
+|---|---|---|
+| `id` | bigint | 主键 |
+| `batch_id` | bigint | 批次 ID |
+| `trace_conclusion` | varchar(500) | 溯源主结论 |
+| `trace_summary` | varchar(500) | 溯源补充说明 |
+| `test_passed` | tinyint | 是否检测通过 |
+| `test_organization` | varchar(200) | 检测机构或检测来源说明 |
+| `test_source_type` | varchar(50) | 检测来源类型,如 self_device / third_party |
+| `camera_live_url` | varchar(500) | 实时视频流地址 |
+| `camera_cover` | varchar(500) | 监控封面图 |
+| `camera_status` | varchar(20) | 摄像头状态 |
+| `environment_summary` | varchar(500) | 环境总结 |
+| `environment_items` | text/json | 环境状态项 |
+| `environment_charts` | text/json | 环境趋势图数据 |
+| `footer_statement` | varchar(500) | 页底收口文案,可选 |
+
+### 7.3 农事记录表(优先复用)
+建议复用现有农事记录表,无需为第二阶段专门新建。
+
+建议前端所需字段至少包括:
+
+| 字段名 | 类型 | 说明 |
+|---|---|---|
+| `task_name` | varchar | 任务名称 |
+| `task_type` | varchar | 任务类型 |
+| `farm_id` | bigint | 所属农场 |
+| `plot_id` | bigint | 所属地块 |
+| `operator_name` | varchar | 执行人 |
+| `crop_name` | varchar | 作物名称 |
+| `task_status` | varchar | 任务状态 |
+| `plan_start_time` | datetime | 计划开始时间 |
+| `plan_end_time` | datetime | 计划完成时间 |
+| `task_desc` | text | 任务说明 |
+
+### 7.4 原始农事记录查询接口建议
+建议提供一个按批次/农场/作物过滤后的农事记录查询接口,供前端或聚合接口使用。
+
+例如:
+- 根据批次 ID 查询关联农事记录
+- 或根据农场 + 作物 + 时间范围查询
+
+---
+
+## 8. 开发实施建议
+
+### 8.1 开发优先级建议
+#### P1
+- 溯源结论卡
+- 时间轴模块
+
+#### P2
+- 实时监控画面
+- 环境状态卡
+
+#### P3
+- 小趋势图
+- 更多农事记录展开
+
+### 8.2 前端实施策略
+建议基于当前 `detail.vue`:
+
+- 继续复用 card 体系
+- 新增模块,不推翻结构
+- 通过 computed 对新字段做兼容
+- mock 数据先行,后续联调替换
+
+### 8.3 后端实施策略
+建议后端分两步:
+
+#### 第一步
+先补字段并返回 mock / 半真实数据:
+- traceConclusion
+- timeline
+- camera
+- environment
+
+#### 第二步
+再接入真实数据聚合:
+- 农事记录
+- 摄像头实时流
+- 设备环境状态
+- 溯源结论文案生成 / 检测结论解析
+
+### 8.4 联调建议
+
+#### 联调顺序建议
+1. 溯源结论卡
+2. 时间轴聚合逻辑
+3. 实时监控画面
+4. 当前环境状态
+5. 报告 / 合格证与第二阶段模块的顺序联调
+
+#### 联调原则
+- 先打通字段与接口,再优化文案与样式细节
+- 先保证“有无逻辑”正确,再优化“展示效果”
+- 时间轴联调时必须重点验证:
+  - 同类任务是否正确合并
+  - 系统节点是否正确拼入
+  - 节点顺序是否正确
+  - 超过 6 条时是否正确裁剪
+  - 无真实时间轴数据时是否正确隐藏模块,而不是回退展示 mock 节点
+
+### 8.5 开发推进策略(前端先行,但非原型)
+
+本项目第二阶段采用“前端先行”的开发策略,但需特别强调:
+
+> 本阶段前端不是原型开发,而是直接开发可上线的正式页面。
+
+#### 8.5.1 开发阶段划分
+
+##### 阶段一:前端页面落地开发(非原型)
+目标:
+- 完成第二阶段所有页面模块的真实开发(非原型)
+- 页面结构、样式、交互均按正式上线标准实现
+- 使用 mock 数据或前端示例数据填充
+
+本阶段重点:
+- 验证“信任感是否成立”
+- 验证模块组合是否合理
+- 验证页面节奏(是否冗长 / 是否跳跃 / 是否像后台)
+
+注意事项:
+- 不允许使用低保真原型结构(如占位框、简化布局)
+- 所有模块需按最终 UI 标准开发
+- 文案需接近最终运营版本(可后续微调)
+
+##### 阶段二:运营 & 老板评审
+目标:
+- 确认页面是否达到“第一眼可信”的目标
+- 确认内容表达是否符合运营使用习惯
+
+评审重点问题建议:
+- 第一屏是否让人产生安全感
+- 哪个模块最有信任感
+- 哪个模块显得多余或干扰
+- 文案是否过于技术化或不接地气
+- 页面是否有“真实感”而不是“系统感”
+
+##### 阶段三:方案冻结(非常关键)
+目标:
+- 确认最终模块结构
+- 确认字段需求
+- 确认展示逻辑
+
+原则:
+- 页面结构一旦确认,不再大改
+- 避免在联调阶段频繁调整页面结构
+
+##### 阶段四:后端接口开发
+目标:
+- 根据已确认页面补充字段与接口
+- 提供聚合数据结构
+
+开发重点:
+- 溯源结论字段
+- 时间轴聚合逻辑
+- 摄像头数据
+- 环境状态聚合
+
+##### 阶段五:前后端联调
+目标:
+- 数据与页面完全对齐
+- 校验所有兜底逻辑
+
+联调重点:
+- 时间轴节点是否正确合并与排序
+- 无数据时页面是否合理隐藏模块
+- 溯源结论与检测来源、报告材料是否一致
+- 实时监控状态是否真实反映
+
+---
+
+#### 8.5.2 前端开发数据策略
+
+为提高开发效率,建议前端阶段采用三套数据策略:
+
+##### 1. 理想数据(全量)
+用于展示最佳效果:
+- 完整时间轴
+- 有检测结论
+- 有实时视频
+- 有环境状态与趋势图
+
+##### 2. 常规数据(部分缺失)
+用于验证页面健壮性:
+- 无视频或无趋势图
+- 有时间轴 + 报告
+
+##### 3. 缺省数据(极端情况)
+用于验证兜底逻辑:
+- 无检测结论
+- 无时间轴
+- 无环境数据
+
+要求:
+- 三种状态页面都必须表现正常
+- 不允许出现“空白块”“占位尴尬”“结构断裂”
+
+---
+
+#### 8.5.3 本阶段核心目标再次强调
+
+第二阶段前端开发的核心目标不是“功能完成”,而是:
+
+- 是否让用户第一眼产生信任感
+- 是否让用户快速理解“安全 / 真实 / 新鲜”
+- 是否避免页面呈现为后台系统或数据面板
+
+最终标准:
+
+> 用户扫码打开页面后,不需要解释,就能感知“这批产品是可信的”。
+
+---
+
+## 9. 风险点与注意事项
+
+### 9.1 不要把页面做成数据看板
+重点是信任,而不是设备展示。
+
+### 9.2 不要直接展示过多原始农事记录
+主时间轴必须提炼,原始记录仅用于展开查证。
+
+### 9.3 不要把“打药”原词直接做主节点
+应转译为“健康管理 / 病虫害防控管理”。
+
+### 9.4 不要过度堆卡片
+内容多时优先靠模块层级和收纳,不先上 tab。
+
+### 9.5 不要打破第一阶段视觉风格
+第二阶段是在第一阶段上增强,而不是重做。
+
+---
+
+## 10. 验收标准
+
+第二阶段完成后,页面应满足以下验收标准:
+
+### 10.1 体验层
+- 用户打开页面后第一屏即可感知“安全、可信”
+- 页面整体不冗长、不杂乱
+- 所有新增模块都能自然融入现有风格
+
+### 10.2 内容层
+- 能看到溯源结论
+- 能看到关键种植过程
+- 能看到实时现场
+- 能理解环境状态
+- 能继续查看检测报告、合格证
+
+### 10.3 业务层
+- 支持普通消费者快速判断“能不能放心买”
+- 支持高端用户快速建立送礼信任感
+- 保持后续第三阶段“能卖”的承接空间
+
+### 10.4 数据真实性验收
+- 溯源结论文案必须与真实检测结果、检测来源及页面材料一致
+- 时间轴节点不得伪造不存在的种植过程
+- 未接入真实农事记录或系统节点时,不得以前端 mock 时间轴替代真实过程展示给用户
+- 实时监控若为封面图或非实时模式,前端文案不得误导为“实时”
+- 环境状态结论必须与真实设备数据或后端聚合结论一致
+- 产地、批次、检测报告、合格证之间的批次关联必须一致
+
+---
+
+## 11. 最终结论
+
+第二阶段不是简单加功能,而是围绕“安全、新鲜、真实”三件事,完成一次信任表达升级。
+
+### 第二阶段要做的本质
+- 把数据转成结论
+- 把功能转成场景
+- 把资料页升级成信任页
+
+### 最终目标
+> 让用户扫码打开页面后,不只是“看见很多资料”,而是“愿意相信这批产品”。
+
+---
+
+## 12. 第二阶段前端开发拆解清单
+
+> 本章节用于指导第二阶段前端页面的实际开发落地,适用于前端开发人员、Cursor 辅助开发以及后续联调前的自查。
+
+### 12.1 开发目标说明
+
+第二阶段前端开发不是做低保真原型,而是直接开发可上线的正式页面。  
+因此拆解清单不仅关注“做哪些模块”,也关注:
+
+- 模块顺序是否正确
+- 信息层级是否合理
+- 信任感是否成立
+- 缺省状态是否可用
+- 后续联调是否方便
+
+---
+
+## 12.2 页面模块开发顺序建议
+
+建议按以下顺序逐步开发,而不是一次性同时改完整个页面:
+
+### 第一批(优先落地,最快形成第二阶段效果)
+1. 溯源结论卡
+2. 关键农事时间轴
+3. 首屏与后续模块衔接细节校准
+
+### 第二批(强化真实感与差异化)
+4. 种植现场实时画面
+5. 当前环境状态
+
+### 第三批(整体验收与细节增强)
+6. 批次信息顺序调整
+7. 检测报告与合格证顺序校准
+8. 页脚安心收口增强
+9. 缺省状态与兜底逻辑处理
+
+---
+
+## 12.3 前端组件 / 模块拆解建议
+
+建议在当前 `detail.vue` 基础上按模块拆分开发思路推进,即使不立即拆成独立组件,也应按组件思维组织代码。
+
+### 模块 A:首屏信任感收敛优化
+
+#### 目标
+确保首屏具备“官方溯源页”的气质,但不通过在 Hero 图上继续叠加额外标签或文案来实现。
+
+#### 当前结论
+经过实际页面验证,已确认:
+- 顶部 `brandPageHeader` 已承担“官方溯源”的定调作用
+- Hero 商品图本身已承担品牌感、品质感与高端感表达
+- 继续在 Hero 图内增加额外标签或结论文案,会造成信息重复与视觉干扰
+
+#### 本模块当前需完成内容
+- 保持首屏现有结构不变
+- 不新增 `heroTrustBlock` / `heroTrustPill` 等额外元素
+- 如有必要,仅微调页头与 Hero 的节奏关系、留白、间距
+
+#### 开发检查点
+- 首屏是否仍然一眼能感知“官方感”
+- Hero 商品图是否仍然保持主视觉地位
+- 是否避免了重复表达“官方溯源”
+- 是否没有因为新增元素而破坏高级感
+
+### 模块 B:溯源结论卡
+
+#### 目标
+优先回答用户“这批产品值不值得信任”。
+
+#### 需完成内容
+- 新增溯源结论卡
+- 放置在 Hero 后的高优先级位置
+- 呈现主结论 + 补充说明
+- 结论不局限于“检测通过”,而是对整页溯源信息做总括表达
+
+#### 推荐前端数据字段
+```js
+traceConclusionCard: {
+  title: '溯源结论',
+  conclusion: '本批次产品已完成安全检测,来源清晰、过程可查',
+  desc: '本页面已同步展示农场信息、批次信息、检测材料及相关过程记录。',
+  testPassed: true,
+  testSourceType: 'self_device'
+}
+```
+
+#### 开发检查点
+- 模块应为“结论型卡片”,不能做成参数表格
+- 该模块为空时应整体隐藏
+- 不允许前端写死“第三方检测”作为长期方案
+- 结论应能承接后续时间轴、检测报告、合格证等模块,而不是只解释检测结果
+
+---
+
+### 模块 C:农场信息卡优化
+
+#### 目标
+将当前农场资料卡提升为“真实源头背书卡”。
+
+#### 需完成内容
+- 保留现有农场图片、名称、地址、简介结构
+- 优化简介表达,使其更偏“真实来源”而非“高大上基地宣传”
+- 必要时补充轻标签(如:真实产地 / 可追溯)
+
+#### 开发检查点
+- 避免过度包装为大型智慧农场
+- 图片优先体现“真实感”而不是“概念感”
+- 文案应更强调来源、产地、过程可查
+
+---
+
+### 模块 D:关键农事时间轴
+
+#### 目标
+将农事记录转化为消费者可理解的成长过程。
+
+#### 需完成内容
+- 新增时间轴卡片
+- 根据当前设计方案中的映射规则生成时间轴数据
+- 支持最多展示 4–6 个关键节点
+- 可预留“查看更多农事记录”入口
+
+#### 推荐前端数据结构
+```js
+timeline: [
+  {
+    time: '2026-03-01',
+    stage: 'planting',
+    title: '开始种植',
+    desc: '本批次产品进入种植管理阶段'
+  }
+]
+```
+
+#### 前端实现建议
+- 前期可先用 mock timeline 数据做页面展示验证
+- 后期联调时应由 `farmTasks + batch + report` 计算生成
+- 真实接口场景下,若缺少真实时间轴数据,不得直接回退展示 mock timeline
+- 若某些系统节点缺失,应按文档中的缺失规则隐藏或简化
+
+#### 开发检查点
+- 时间轴不能做成后台操作日志样式
+- 不允许逐条展示所有农事记录
+- 必须有数量控制与排序控制
+- 时间轴为空时应整体隐藏或显示简化版
+
+---
+
+### 模块 E:种植现场实时画面
+
+#### 目标
+用“现场可见”强化真实可信感。
+
+#### 需完成内容
+- 新增实时画面卡片
+- 支持视频流模式
+- 支持封面图兜底模式
+- 支持在线 / 离线状态展示
+
+#### 推荐前端数据结构
+```js
+camera: {
+  liveUrl: '',
+  coverImage: '',
+  status: 'online',
+  desc: '当前为农场种植区实时画面'
+}
+```
+
+#### 前端实现建议
+- 第一版先保证卡片结构正确
+- 如果视频能力已成熟,可直接接已有方案
+- 若 `liveUrl` 缺失,则自动回退为封面图模式
+
+#### 开发检查点
+- 文案不强调“摄像头”,强调“现场画面”
+- 不要把该模块做成监控控制台
+- 若为非实时模式,文案不得误导为实时
+
+---
+
+### 模块 F:当前环境状态
+
+#### 目标
+把设备数据转成用户可理解的环境结论。
+
+#### 需完成内容
+- 新增环境状态卡
+- 展示环境总结文案
+- 展示 4 个左右的状态项
+- 可预留 1–2 张轻量趋势图位置
+
+#### 推荐前端数据结构
+```js
+environment: {
+  summary: '当前环境稳定,适宜草莓生长',
+  items: [
+    { label: '温度', value: '18℃', status: '适宜' },
+    { label: '湿度', value: '65%', status: '正常' },
+    { label: '光照', value: '充足', status: '正常' },
+    { label: '土壤', value: '墒情良好', status: '正常' }
+  ],
+  charts: []
+}
+```
+
+#### 前端实现建议
+- 第一版可先不接图表,先完成 summary + items
+- 图表建议单独封装为轻趋势图子模块
+- 若仅有 summary,则只展示 summary
+
+#### 开发检查点
+- 不要让数值成为主角
+- 环境模块首先要给结论
+- 趋势图是佐证,不是主表达
+
+---
+
+### 模块 G:批次信息顺序与角色调整
+
+#### 目标
+保留批次信息,但将其放到“查证层”位置。
+
+#### 需完成内容
+- 不必大改样式
+- 调整模块在页面中的顺序
+- 确保在时间轴 / 监控 / 环境之后出现
+
+#### 开发检查点
+- 批次信息仍然清晰
+- 但不应继续作为前半页核心内容
+
+---
+
+### 模块 H:检测报告与合格证证明层整理
+
+#### 目标
+让检测报告与合格证作为证明材料存在,而不是抢主结论。
+
+#### 需完成内容
+- 保持当前报告横滑卡片与合格证单证模式
+- 校准两者在页面中的出现顺序
+- 确保前面已有检测结论卡后,材料层逻辑自然成立
+
+#### 开发检查点
+- 不要再次放大报告与合格证的视觉权重
+- 继续保持“点击查看大图”逻辑
+- 与第二阶段新模块之间的节奏要顺
+
+---
+
+### 模块 I:页脚安心收口
+
+#### 目标
+让页面结尾不突兀,形成“安心结束”的感觉。
+
+#### 需完成内容
+- 在现有 footer 上方新增一行轻收口文案
+- 保留客服电话与品牌签名
+- 校准页尾留白与整体节奏
+
+#### 推荐收口文案
+- 本产品已完成全流程溯源记录,信息真实可查,请放心食用。
+
+#### 开发检查点
+- 页尾不能突然结束
+- 不要做成重按钮区域
+- 应保持当前第一阶段的克制风格
+
+---
+
+## 12.4 前端开发文件级任务拆解建议
+
+建议以当前 `pages/trace/detail.vue` 为主文件推进,并视需要拆出子组件。
+
+### 推荐拆解方式(建议,但不强制)
+
+#### 方案 A:先在 `detail.vue` 内完成全部模块
+适合:
+- 先快速确认页面效果
+- 便于统一调整顺序和节奏
+
+#### 方案 B:边开发边提炼子组件
+推荐可拆分子组件如下:
+- `TraceHeroTrust.vue`
+- `TraceConclusionCard.vue`
+- `TraceTimeline.vue`
+- `TraceCameraCard.vue`
+- `TraceEnvironmentCard.vue`
+- `TraceFooterStatement.vue`
+
+### 建议优先
+先在 `detail.vue` 内完成版面,老板确认后再酌情抽组件,避免过早拆分影响迭代速度。
+
+---
+
+## 12.5 页面开发验收清单(前端阶段)
+
+### 第一屏验收
+- 是否一眼看出是品牌官方溯源页面
+- 首屏是否保持克制,而没有重复堆叠“官方溯源”信息
+- Hero 商品图是否仍然是首屏主视觉
+- 是否仍保持当前高级感
+
+### 模块层级验收
+- 是否先给结论,再给过程,再给证明
+- 是否避免了“信息一上来就太多”
+- 是否避免了后台感 / 数据面板感
+
+### 时间轴验收
+- 节点是否控制在 4–6 条
+- 是否能看懂而不是像日志
+- 是否包含采收 / 检测 / 包装等关键节点
+- 真实数据缺失时是否没有错误展示 mock 过程节点
+
+### 实时画面验收
+- 是否有真实感
+- 是否不显技术化
+- 封面图兜底是否自然
+
+### 环境状态验收
+- 是否先有环境结论
+- 状态块是否简洁
+- 图表是否克制,不抢戏
+
+### 页面完整性验收
+- 各模块间距是否协调
+- 页面是否过长
+- 页脚是否收得住
+- 无数据场景是否自然
+
+---
+
+## 12.6 前端阶段输出物要求
+
+第二阶段前端开发完成后,应至少形成以下输出物:
+
+1. 可运行的正式页面版本(非原型)
+2. 至少一套全量 mock 数据
+3. 一套部分缺失数据
+4. 一套缺省数据
+5. 页面截图 / 演示视频,用于老板与运营评审
+
+---
+
+## 12.7 本章节总结
+
+第二阶段前端开发不是为了“把功能都放上去”,而是为了验证:
+
+- 页面是否真的比第一阶段更可信
+- 第二阶段内容是否能被“溯源结论”自然串起来
+- 后续后端接口应该围绕哪些字段补齐
+
+前端先行的价值不在于“首屏不断加元素”,而在于:
+
+> 先把正确的页面表达验证清楚,再让后端围绕正确的目标补数据。