Commit 5f0cf756 by CHEN\chenXi

第三关

parent 0d953ee4
{
"name": "angel-angel-mini-game",
"type": "module",
"private": true,
"version": "1.0.0",
"packageManager": "pnpm@10.11.0",
"description": "",
"author": "",
"license": "ISC",
"keywords": [],
"main": "index.js",
"scripts": {
"dev:app": "uni -p app",
"dev:app-android": "uni -p app-android",
"dev:app-ios": "uni -p app-ios",
"dev:custom": "uni -p",
"dev:h5": "uni",
"dev:h5:ssr": "uni --ssr",
"dev:mp-alipay": "uni -p mp-alipay",
"dev:mp-baidu": "uni -p mp-baidu",
"dev:mp-kuaishou": "uni -p mp-kuaishou",
"dev:mp-lark": "uni -p mp-lark",
"dev:mp-qq": "uni -p mp-qq",
"dev:mp-toutiao": "uni -p mp-toutiao",
"dev": "uni -p",
"build": "uni build",
"dev:mp-weixin": "uni -p mp-weixin",
"dev:quickapp-webview": "uni -p quickapp-webview",
"dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
"dev:quickapp-webview-union": "uni -p quickapp-webview-union",
"build:app": "uni build -p app",
"build:app-android": "uni build -p app-android",
"build:app-ios": "uni build -p app-ios",
"build:custom": "uni build -p",
"build:h5": "uni build",
"build:h5:ssr": "uni build --ssr",
"build:mp-alipay": "uni build -p mp-alipay",
"build:mp-baidu": "uni build -p mp-baidu",
"build:mp-kuaishou": "uni build -p mp-kuaishou",
"build:mp-lark": "uni build -p mp-lark",
"build:mp-qq": "uni build -p mp-qq",
"build:mp-toutiao": "uni build -p mp-toutiao",
"build:mp-weixin": "uni build -p mp-weixin",
"build:quickapp-webview": "uni build -p quickapp-webview",
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
"build:quickapp-webview-union": "uni build -p quickapp-webview-union"
"build:mp-weixin": "uni build mp-weixin",
"dev:h5": "uni -p h5",
"build:h5": "uni build h5"
},
"dependencies": {
"@dcloudio/uni-app": "3.0.0-3090620231104001",
"@dcloudio/uni-app-plus": "3.0.0-3090620231104001",
"@dcloudio/uni-components": "3.0.0-3090620231104001",
"@dcloudio/uni-h5": "3.0.0-3090620231104001",
"@dcloudio/uni-mp-alipay": "3.0.0-3090620231104001",
"@dcloudio/uni-mp-baidu": "3.0.0-3090620231104001",
"@dcloudio/uni-mp-kuaishou": "3.0.0-3090620231104001",
"@dcloudio/uni-mp-lark": "3.0.0-3090620231104001",
"@dcloudio/uni-mp-qq": "3.0.0-3090620231104001",
"@dcloudio/uni-mp-toutiao": "3.0.0-3090620231104001",
"@dcloudio/uni-mp-weixin": "3.0.0-3090620231104001",
"@dcloudio/uni-quickapp-webview": "3.0.0-3090620231104001",
"vue": "^3.2.45",
"vue-i18n": "^9.1.9"
"@dcloudio/uni-app": "^3.0.0",
"@dcloudio/uni-app-plus": "^3.0.0",
"vue": "^3.2.0"
},
"devDependencies": {
"@antfu/eslint-config": "^7.2.0",
"@dcloudio/types": "^3.3.2",
"@dcloudio/uni-automator": "3.0.0-3090620231104001",
"@dcloudio/uni-cli-shared": "3.0.0-3090620231104001",
"@dcloudio/uni-stacktracey": "3.0.0-3090620231104001",
"@dcloudio/vite-plugin-uni": "3.0.0-3090620231104001",
"eslint": "^9.39.2",
"sass": "^1.77.8",
"vite": "^4.0.3"
"@dcloudio/types": "^3.0.0",
"@dcloudio/uni-automator": "^3.0.0",
"@dcloudio/uni-cli-shared": "^3.0.0",
"@dcloudio/uni-components": "^3.0.0",
"@dcloudio/uni-h5": "^3.0.0",
"@dcloudio/uni-helper-json": "^3.0.0",
"@dcloudio/uni-i18n": "^3.0.0",
"@dcloudio/uni-mp-alipay": "^3.0.0",
"@dcloudio/uni-mp-baidu": "^3.0.0",
"@dcloudio/uni-mp-kuaishou": "^3.0.0",
"@dcloudio/uni-mp-lark": "^3.0.0",
"@dcloudio/uni-mp-qq": "^3.0.0",
"@dcloudio/uni-mp-toutiao": "^3.0.0",
"@dcloudio/uni-mp-weixin": "^3.0.0",
"@dcloudio/uni-stat": "^3.0.0",
"@dcloudio/vite-plugin-uni": "^3.0.0",
"@types/node": "^18.0.0",
"@vue/compiler-sfc": "^3.2.0",
"sass": "^1.32.0",
"vite": "^4.0.0"
}
}
}
\ No newline at end of file
......@@ -11,6 +11,12 @@
"style": {
"navigationStyle": "custom"
}
},
{
"path": "pages/miniGame-three/index",
"style": {
"navigationStyle": "custom"
}
}
],
"globalStyle": {
......
<template>
<view class="test-content">
<view class="tds-phContent">
<view class="contentTabs">
<view class="tabsItems">
<!-- TDS图片(已完成,灰色) -->
<image class="tds"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/b9c5667e95ea48a1b4c10f2d9ee84db6Group%20348447426.webp"
mode="widthFix"></image>
<!-- pH图片(当前测试) -->
<image class="ph"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/1b349b23af1d4546bb634defb0f0ace8TDS%E6%8C%89%E9%92%AE.webp"
mode="widthFix"></image>
</view>
</view>
</view>
<!-- 操作说明卡片 -->
<view class="instructions-card instructions-card-step0" v-if="props.currentStep === 0">
<image class="card-bg"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/87e28ba2f4764f33a36b0d1cfd47d74aRectangle%203589.webp"
mode="scaleToFill"></image>
<view class="card-content">
<view class="card-title">操作说明</view>
<view class="card-body">
<text class="instruction-text">点击"开始检测"按钮测试pH值</text>
<image class="ph-icon"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/32ac38db03994072aca53ae518b996eeGroup%20348447450.webp"
mode="heightFix"></image>
</view>
</view>
</view>
<!-- 检测中卡片 -->
<view class="instructions-card instructions-card-detecting"
v-else-if="props.currentStep === 1 && !showFinalResult">
<view class="card-content">
<view class="card-body">
<!-- 进度条 -->
<view class="progress-container">
<image class="progress-bg"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/7b21b166605d4c7c9bb4377280202da7Group%20348447442.webp"
mode="widthFix"></image>
<!-- 进度条填充动画 -->
<view class="progress-fill-container" :style="{ width: progressWidth + '%' }">
<image class="progress-fill"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/45cebdfeb99a44049d18ab3b04024ac2Group%20348447442.webp"
mode="heightFix"></image>
</view>
</view>
<!-- pH结果显示 -->
<view class="ph-display">
<!-- 污染水 -->
<view class="ph-item-box">
<view class="ph-item">
<view class="item">
<text class="water-type">污染水</text>
<text class="ph-value">
pH值:{{ showPartialResult ? beforePH : '???' }}
</text>
</view>
<!-- item-img在检测结果出来后才显示 -->
<view class="item-img" v-if="showPartialResult">
<image
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/0c6358f526fd4a72a098e5e46c9a8759Frame%2017.webp"
mode="aspectFit" />
</view>
</view>
</view>
<!-- 净化水 -->
<view class="ph-item-box">
<view class="ph-item">
<view class="item">
<text class="water-type">净化水</text>
<text class="ph-value">
pH值:{{ showPartialResult ? afterPH : '???' }}
</text>
</view>
<!-- item-img在检测结果出来后才显示 -->
<view class="item-img" v-if="showPartialResult">
<image
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/e7e6a286a568480fada2cafab781cc3cFrame.webp"
mode="aspectFit" />
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 检测完成卡片 -->
<view class="instructions-card instructions-card-step2" v-else-if="props.currentStep === 2">
<image class="card-bg"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/87e28ba2f4764f33a36b0d1cfd47d74aRectangle%203589.webp"
mode="scaleToFill"></image>
<view class="card-content">
<view class="card-title">检测结果</view>
<view class="card-body">
<view class="completion-content">
<view class="top">
<view class="beforeContent">
<view class="text">前:</view>
<view class="beforePHValue" :style="{ color: getPHColor(beforePH) }">{{ beforePH }}</view>
<view class="type" :style="{
background: getPHColor(beforePH),
borderColor: getPHBorderColor(beforePH)
}">{{ getPHType(beforePH) }}</view>
<image :src="getPHIcon(beforePH)" :style="{ width: '36rpx', height: '36rpx' }" />
</view>
<view class="jiantou">-></view>
<view class="afterContent">
<view class="text">后:</view>
<view class="afterPHValue" :style="{ color: getPHColor(afterPH) }">{{ afterPH }}</view>
<view class="type" :style="{
background: getPHColor(afterPH),
borderColor: getPHBorderColor(afterPH)
}">{{ getPHType(afterPH) }}</view>
<image :src="getPHIcon(afterPH)" :style="{ width: '32rpx', height: '32rpx' }" />
</view>
</view>
<view class="center">
<view class="centerTop">
<!-- 污染水pH值指示器 -->
<view class="topItem" :style="{ left: getPHIndicatorPosition(beforePH) }">
<image
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/8756b9fccb61450a96f34e2b0e938552Group%20348447464.webp"
mode="aspectFit" />
</view>
<!-- 净化水pH值指示器 -->
<view class="topItem" :style="{ left: getPHIndicatorPosition(afterPH) }">
<image
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/200ccfb61dce458799879093341107f9Group%20348447463.webp"
mode="aspectFit" />
</view>
</view>
<view class="centerCen">
<image src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/3df0383e2218465c83af9aeeae10e1baGroup%20348447462.webp" />
<!-- pH刻度值 -->
<view class="ph-scale">
<text class="scale-value" v-for="i in 15" :key="i"
:style="{ left: `${(i-1) * (100/14)}%` }">
{{ i-1 }}
</text>
</view>
</view>
</view>
<view class="bottom">
<view class="bottomLeft">酸碱度:<text class="phDegree" :style="{ color: improvementRate >= 80 ? '#b2c849' : '#ff6b35' }">{{ improvementRate >= 80 ? '已优化' : '需优化' }}</text></view>
<view class="bottomRight" :style="{
background: improvementRate >= 80 ? '#B2C849' : '#FF6B35',
borderColor: improvementRate >= 80 ? '#748A08' : '#D94A1B'
}">{{ improvementRate >= 80 ? '适合饮用' : '需净化' }}</view>
</view>
</view>
</view>
</view>
</view>
<view class="tips-card">
<view class="tips-header">
<image class="bulb-icon"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/d2a7b1b81bff44c2b9099a8d48d9d6f1Frame%282%29.webp"
mode="widthFix"></image>
<text class="tips-title">你知道吗?</text>
</view>
<view class="tips-body">
<text v-if="props.currentStep === 0">理想饮用水pH值应在6.5-8.5之间</text>
<text v-else-if="props.currentStep === 1">pH试纸通过颜色变化判断酸碱性</text>
<text v-else-if="props.currentStep === 2">pH值接近中性说明水质更适合人体饮用</text>
</view>
</view>
<!--底部-->
<view class="bottom-bar">
<view class="test-status">当前测试: <text class="test-status-text">{{ testStatusText }}/2</text></view>
<view class="start-btn-wrapper" @click="handleStartTest">
<image class="startBtn" :src="getButtonImage()" alt="" />
</view>
</view>
</view>
</template>
<script setup>
import { defineProps, defineEmits, ref, watch, onUnmounted, computed } from 'vue';
const props = defineProps({
currentStep: {
type: Number,
default: 0
},
isAllTestsCompleted: {
type: Boolean,
default: false
}
});
const emit = defineEmits(['next-step', 'test-completed', 'show-completion-modal']);
const progressWidth = ref(0);
const showPartialResult = ref(false);
const showFinalResult = ref(false);
const isTesting = ref(false);
const testStatusText = ref(2); // pH测试时显示2/2
// 定义pH值
const beforePH = ref(5.2); // 污染水pH值(酸性)
const afterPH = ref(7.2); // 净化水pH值(接近中性)
let progressTimer = null;
// pH值对应的颜色映射(根据pH试纸颜色)
const phColorMap = {
// 强酸性:红色系
0: { color: '#FF0000', border: '#CC0000', icon: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/0c6358f526fd4a72a098e5e46c9a8759Frame%2017.webp' },
1: { color: '#FF3300', border: '#CC2900', icon: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/0c6358f526fd4a72a098e5e46c9a8759Frame%2017.webp' },
2: { color: '#FF6600', border: '#CC5200', icon: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/0c6358f526fd4a72a098e5e46c9a8759Frame%2017.webp' },
3: { color: '#FF9933', border: '#CC7A29', icon: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/0c6358f526fd4a72a098e5e46c9a8759Frame%2017.webp' },
4: { color: '#FFCC00', border: '#CCA300', icon: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/0c6358f526fd4a72a098e5e46c9a8759Frame%2017.webp' },
5: { color: '#FFFF00', border: '#CCCC00', icon: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/0c6358f526fd4a72a098e5e46c9a8759Frame%2017.webp' },
// 弱酸性:橙黄色系
6: { color: '#FFFF66', border: '#CCCC52', icon: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/0c6358f526fd4a72a098e5e46c9a8759Frame%2017.webp' },
// 中性:绿色系
7: { color: '#00CC00', border: '#00A300', icon: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/dd15bc1646cb4fcb86670b2b1ae04809Group%20348447459.webp' },
8: { color: '#00CC00', border: '#00A300', icon: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/dd15bc1646cb4fcb86670b2b1ae04809Group%20348447459.webp' },
// 弱碱性:蓝色系
9: { color: '#0099FF', border: '#007ACC', icon: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/dd15bc1646cb4fcb86670b2b1ae04809Group%20348447459.webp' },
10: { color: '#0066FF', border: '#0052CC', icon: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/dd15bc1646cb4fcb86670b2b1ae04809Group%20348447459.webp' },
// 强碱性:紫色系
11: { color: '#6600CC', border: '#5200A3', icon: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/dd15bc1646cb4fcb86670b2b1ae04809Group%20348447459.webp' },
12: { color: '#9900FF', border: '#7A00CC', icon: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/dd15bc1646cb4fcb86670b2b1ae04809Group%20348447459.webp' },
13: { color: '#CC00FF', border: '#A300CC', icon: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/dd15bc1646cb4fcb86670b2b1ae04809Group%20348447459.webp' },
14: { color: '#FF00FF', border: '#CC00CC', icon: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/dd15bc1646cb4fcb86670b2b1ae04809Group%20348447459.webp' },
};
// 根据pH值获取颜色
const getPHColor = (ph) => {
const roundedPH = Math.round(ph);
return phColorMap[roundedPH]?.color || '#25334d';
};
// 根据pH值获取边框颜色
const getPHBorderColor = (ph) => {
const roundedPH = Math.round(ph);
return phColorMap[roundedPH]?.border || '#25334d';
};
// 根据pH值获取图标
const getPHIcon = (ph) => {
const roundedPH = Math.round(ph);
return phColorMap[roundedPH]?.icon || 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/dd15bc1646cb4fcb86670b2b1ae04809Group%20348447459.webp';
};
// 根据pH值获取类型文字
const getPHType = (ph) => {
if (ph < 6.5) return '偏酸性';
if (ph > 8.5) return '偏碱性';
return '中性';
};
// 根据pH值获取指示器位置(0-14对应0-100%)
const getPHIndicatorPosition = (ph) => {
// pH值0-14映射到0-100%
const position = (ph / 14) * 100;
// 确保在0-100%范围内
return `calc(${Math.min(Math.max(position, 0), 100)}% - 17rpx)`;
};
// 计算改善程度
const improvementRate = computed(() => {
// pH值从酸性(5.2)改善到接近中性(7.2)
const maxImprovement = 7.2 - 5.2; // 最大改善值2.0
const actualImprovement = afterPH.value - beforePH.value;
const rate = (actualImprovement / maxImprovement) * 100;
return Math.min(Math.round(rate * 10) / 10, 100); // 保留一位小数,不超过100%
});
// 按钮图片逻辑
const getButtonImage = () => {
if (props.currentStep === 0) {
return 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/51e1fc432e2b406d9d00f1028213221bGroup%20348447439.webp';
} else if (props.currentStep === 1 || props.currentStep === 2) {
// 在pH测试完成时,如果所有测试都已完成,显示完成按钮
if (props.currentStep === 2 && props.isAllTestsCompleted) {
return 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/f8df9974d93a478f8c6b760fd32e15aaGroup%20348447439.webp';
}
return 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/92306739e0774318bbfc4bbf0a69cba5Group%20348447439.webp';
} else {
return 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/92306739e0774318bbfc4bbf0a69cba5Group%20348447439.webp';
}
};
// 监听currentStep变化
watch(() => props.currentStep, (newStep) => {
console.log('pH currentStep变化:', newStep);
if (newStep === 1) {
// 进入步骤1,开始自动检测
startAutoDetection();
} else if (newStep === 2) {
// 进入步骤2,检测完成
showFinalResult.value = true;
resetDetection();
// 通知父组件pH测试已完成
emit('test-completed');
}
}, { immediate: true });
// 开始自动检测
const startAutoDetection = () => {
if (isTesting.value) return;
console.log('开始pH自动检测');
isTesting.value = true;
progressWidth.value = 0;
showPartialResult.value = false;
showFinalResult.value = false;
// 清除之前的定时器
if (progressTimer) {
clearInterval(progressTimer);
}
// 模拟检测过程
let currentProgress = 0;
const totalTime = 3000; // 总时长3秒
const interval = 50; // 更新间隔50ms
const increment = (interval / totalTime) * 100; // 每次增加的百分比
progressTimer = setInterval(() => {
currentProgress += increment;
progressWidth.value = Math.min(currentProgress, 100);
// 当进度达到50%时显示pH值
if (currentProgress >= 50 && !showPartialResult.value) {
console.log('显示pH部分结果');
showPartialResult.value = true;
}
// 当进度达到100%时显示完成状态
if (currentProgress >= 100) {
showFinalResult.value = true;
clearInterval(progressTimer);
isTesting.value = false;
console.log('pH检测完成');
// 检测完成后延迟1秒自动进入下一步
setTimeout(() => {
console.log('自动进入pH结果页面');
emit('next-step');
}, 1000);
}
}, interval);
};
// 重置检测状态
const resetDetection = () => {
isTesting.value = false;
progressWidth.value = 0;
showPartialResult.value = false;
showFinalResult.value = false;
if (progressTimer) {
clearInterval(progressTimer);
progressTimer = null;
}
};
// 处理按钮点击
const handleStartTest = () => {
console.log('pH按钮点击,当前步骤:', props.currentStep, '测试完成:', showFinalResult.value, '所有测试完成:', props.isAllTestsCompleted);
if (props.currentStep === 0) {
// 第一步:点击"开始检测"
console.log('开始pH检测');
emit('next-step');
} else if (props.currentStep === 1) {
// 第二步:检测中或检测完成
if (showFinalResult.value) {
// 检测已完成,可以点击按钮进入下一步
console.log('pH检测完成,进入结果页面');
emit('next-step');
} else {
console.log('pH检测中,点击无效');
}
} else if (props.currentStep === 2) {
// 第三步:检测完成后的操作
if (props.isAllTestsCompleted) {
// 所有测试都已完成,点击完成按钮
console.log('点击完成按钮,通知父组件显示弹窗');
// 触发按钮点击事件,让父组件处理
emit('handle-ph-button-click');
} else {
console.log('pH测试完成,但还有其他测试');
emit('test-completed');
}
}
};
// 组件卸载时清理定时器
onUnmounted(() => {
resetDetection();
});
</script>
<style scoped lang="scss">
.test-content {
width: 100%;
height: 45vh;
flex-shrink: 0;
border-radius: 24rpx 24rpx 0 0;
border-top: 4rpx solid #728FAF;
background: linear-gradient(180deg, #E0EBF6 0%, #C3D3E4 100%);
box-shadow: 0 10rpx 0 0 #FFF inset;
box-sizing: border-box;
position: relative;
z-index: 10;
padding-bottom: env(safe-area-inset-bottom);
.tds-phContent {
.contentTabs {
.tabsItems {
margin-top: 32rpx;
display: flex;
align-items: center;
justify-content: center;
.tds {
width: 254rpx;
height: 84rpx;
}
.ph {
width: 254rpx;
height: 84rpx;
margin-left: 40rpx;
}
}
}
}
// 步骤0的卡片样式(原始样式)
.instructions-card-step0 {
position: relative;
width: 95%;
height: 180rpx;
margin: 40rpx auto;
border-radius: 24rpx;
border: 4rpx solid #457AAB;
background: #BEDCF3;
box-sizing: border-box;
flex-shrink: 0;
.card-bg {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 98%;
height: 94%;
z-index: 0;
display: block;
}
.card-content {
position: relative;
z-index: 1;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
.card-title {
text-align: center;
font-size: 34rpx;
font-weight: bold;
color: #25334D;
}
.card-body {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
padding: 0 20rpx;
.instruction-text {
font-size: 30rpx;
color: #25334D;
font-weight: 500;
}
.ph-icon {
width: 53.72rpx;
height: 158.96rpx;
margin-left: 20rpx;
margin-top: -12rpx;
}
}
}
}
// 检测中卡片样式(无边框背景色)
.instructions-card-detecting {
width: 95%;
height: 240rpx;
margin: 40rpx auto;
box-sizing: border-box;
flex-shrink: 0;
background: transparent;
border: none;
.card-content {
position: relative;
z-index: 1;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
.card-body {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
padding: 0 20rpx;
// 进度条样式(使用切图)
.progress-container {
width: 90%;
height: 60rpx;
position: relative;
margin-bottom: 20rpx;
overflow: hidden;
border-radius: 10rpx;
.progress-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.progress-fill-container {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 0%;
overflow: hidden;
z-index: 2;
transition: width 0.1s linear;
.progress-fill {
height: 100%;
width: auto;
min-width: 100%;
}
}
}
// pH显示样式
.ph-display {
display: flex;
width: 100%;
justify-content: space-around;
align-items: center;
// pH项目盒子(带边框)
.ph-item-box {
background: linear-gradient(180deg, #FAFBFD 0%, #DCEEFD 100%);
border: 2rpx solid #FFF;
border-radius: 24rpx;
width: 328rpx;
height: 140rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
.ph-item {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
padding: 0 20rpx;
.item {
display: flex;
flex-direction: column;
align-items: flex-start;
.water-type {
font-size: 26rpx;
color: #25334D;
font-weight: 500;
margin-bottom: 8rpx;
}
.ph-value {
font-size: 32rpx;
color: #3481c8;
font-weight: bold;
}
}
.item-img {
width: 92rpx;
height: 92rpx;
display: flex;
align-items: center;
justify-content: center;
image {
width: 100%;
height: 100%;
}
}
}
}
}
}
}
}
// 检测完成卡片样式
.instructions-card-step2 {
position: relative;
width: 95%;
height: 280rpx;
margin: 40rpx auto;
border-radius: 24rpx;
border: 4rpx solid #457AAB;
background: #BEDCF3;
box-sizing: border-box;
flex-shrink: 0;
.card-bg {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 98%;
height: 94%;
z-index: 0;
display: block;
}
.card-content {
position: relative;
z-index: 1;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
.card-title {
text-align: center;
font-size: 34rpx;
font-weight: bold;
color: #25334D;
margin-top: 15rpx;
}
.card-body {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0 20rpx;
position: relative;
z-index: 99;
// 完成内容样式
.completion-content {
width: 100%;
padding: 12rpx 16rpx;
.top {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 40rpx;
.beforeContent {
display: flex;
align-items: center;
.text {
color: #25334d;
font-size: 30rpx;
font-weight: 600;
}
.beforePHValue {
font-size: 30rpx;
font-weight: 600;
margin: 0 8rpx;
}
.type {
border-radius: 26rpx;
color: #ffffff;
text-align: center;
font-size: 16rpx;
font-weight: 500;
padding: 4rpx 12rpx;
margin: 0 8rpx;
border: 2rpx solid;
}
>image {
width: 36rpx;
height: 36rpx;
}
}
.jiantou {
color: #25334d;
font-size: 24rpx;
font-weight: bold;
}
.afterContent {
display: flex;
align-items: center;
.text {
color: #25334d;
font-size: 30rpx;
font-weight: 600;
}
.afterPHValue {
font-size: 30rpx;
font-weight: 600;
margin: 0 8rpx;
}
.type {
border-radius: 26rpx;
color: #ffffff;
text-align: center;
font-size: 16rpx;
font-weight: 500;
padding: 4rpx 12rpx;
margin: 0 8rpx;
border: 2rpx solid;
}
>image {
width: 32rpx;
height: 32rpx;
}
}
}
.center {
position: relative;
.centerTop {
position: relative;
height: 40rpx;
width: 100%;
.topItem {
position: absolute;
top: 0;
width: 34rpx;
height: 34rpx;
transition: left 0.3s ease;
image {
width: 100%;
height: 100%;
}
}
}
.centerCen {
position: relative;
> image {
width: 100%;
height: 28rpx;
display: block;
}
.ph-scale {
position: absolute;
// bottom: -25rpx;
left: 0;
width: 100%;
display: flex;
justify-content: space-between;
.scale-value {
position: absolute;
transform: translateX(-50%);
font-size: 18rpx;
color: #25334d;
font-weight: 500;
white-space: nowrap;
&:nth-child(1) {
left: 0% !important;
transform: translateX(0);
}
&:nth-child(15) {
left: 100% !important;
transform: translateX(-100%);
}
}
}
}
}
.bottom {
padding: 15rpx 40rpx 5rpx;
margin-top: 20rpx;
display: flex;
align-items: center;
justify-content: space-between;
.bottomLeft {
color: #25334d;
font-size: 30rpx;
font-weight: 600;
.phDegree {
font-size: 30rpx;
font-weight: 600;
margin-left: 10rpx;
-webkit-text-stroke-width: 2rpx;
-webkit-text-stroke-color: transparent;
}
}
.bottomRight {
box-shadow: 0 0 8rpx 0 #FFF inset;
border-radius: 36rpx;
color: #ffffff;
-webkit-text-stroke-width: 2rpx;
-webkit-text-stroke-color: transparent;
font-size: 24rpx;
font-weight: 600;
text-align: center;
padding: 2rpx 20rpx;
border: 2rpx solid;
transition: all 0.3s ease;
}
}
}
}
}
}
.tips-card {
width: 95%;
height: 116rpx;
background: #BEDCF3;
border-radius: 24rpx;
border: 4rpx solid #457AAB;
padding: 20rpx;
position: relative;
box-sizing: border-box;
flex-shrink: 0;
margin: 0 auto;
.tips-header {
position: absolute;
top: -24rpx;
left: 20rpx;
width: 234rpx;
height: 56rpx;
background: linear-gradient(180deg, #52A5D7 0%, #3E83CE 100%);
border-radius: 48rpx;
border: 4rpx solid #1B5CA3;
box-shadow: 0 0 8rpx 0 #FFF inset;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
z-index: 10;
.bulb-icon {
position: absolute;
left: -20rpx;
bottom: -10rpx;
width: 80rpx;
height: 80rpx;
z-index: 12;
}
.tips-title {
color: #fff;
font-size: 34rpx;
font-weight: bold;
margin-left: 30rpx;
}
}
.tips-body {
position: absolute;
top: 0;
left: 0;
font-size: 30rpx;
color: #25334d;
line-height: 1.3;
padding: 30rpx 16rpx 10rpx 16rpx;
border-radius: 24rpx;
background: linear-gradient(180deg, #FFF 0%, #D9EBF7 100%);
width: 100%;
height: 100%;
box-sizing: border-box;
z-index: 5;
display: flex;
align-items: center;
justify-content: center;
}
}
.bottom-bar {
width: 100%;
position: absolute;
bottom: 0rpx;
left: 0;
background-image: url('https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/a681444d883d4fe29851d702703302b0Rectangle%203597.webp');
background-repeat: no-repeat;
background-size: 100% 105%;
padding: 30rpx 0;
box-sizing: border-box;
display: flex;
.test-status {
padding: 0 100rpx;
color: #000000;
font-size: 34rpx;
font-weight: 600;
margin-top: 50rpx;
.test-status-text {
color: #3481c8;
font-size: 34rpx;
}
}
.start-btn-wrapper {
position: absolute;
top: 30rpx;
right: 40rpx;
.startBtn {
width: 254rpx;
height: 99rpx;
}
}
}
}
</style>
\ No newline at end of file
<template>
<view class="test-content">
<view class="tds-phContent">
<view class="contentTabs">
<view class="tabsItems">
<image class="tds"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/b91478ab6f2d4c2186a948ae9b614f45Group%20348447426.webp"
mode="widthFix"></image>
<image class="ph"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/a4bd654c5fd4401bb4d09ce1a8e08aa3Group%20348447427.webp"
mode="widthFix"></image>
</view>
</view>
</view>
<!-- 操作说明卡片 -->
<view class="instructions-card instructions-card-step0" v-if="props.currentStep === 0">
<image class="card-bg"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/87e28ba2f4764f33a36b0d1cfd47d74aRectangle%203589.webp"
mode="scaleToFill"></image>
<view class="card-content">
<view class="card-title">操作说明</view>
<view class="card-body">
<text class="instruction-text">点击"开始检测"按钮测试TDS值</text>
<image class="ppm-icon"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/1a62746fad3743d19f01e8b612ed8d42Group%20348447435.webp"
mode="heightFix"></image>
</view>
</view>
</view>
<!-- 检测中卡片 -->
<view class="instructions-card instructions-card-detecting"
v-else-if="props.currentStep === 1 && !showFinalResult">
<view class="card-content">
<view class="card-body">
<!-- 进度条 -->
<view class="progress-container">
<image class="progress-bg"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/7b21b166605d4c7c9bb4377280202da7Group%20348447442.webp"
mode="widthFix"></image>
<!-- 进度条填充动画 -->
<view class="progress-fill-container" :style="{ width: progressWidth + '%' }">
<image class="progress-fill"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/45cebdfeb99a44049d18ab3b04024ac2Group%20348447442.webp"
mode="heightFix"></image>
</view>
</view>
<!-- TDS结果显示 -->
<view class="tds-display">
<!-- 污染水 -->
<view class="tds-item-box">
<view class="tds-item">
<view class="item">
<text class="water-type">污染水</text>
<text class="tds-value">
TDS值:{{ showPartialResult ? beforeTDS : '???' }}
</text>
</view>
<!-- item-img在检测结果出来后才显示 -->
<view class="item-img" v-if="showPartialResult">
<image src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/0c6358f526fd4a72a098e5e46c9a8759Frame%2017.webp"
mode="aspectFit" />
</view>
</view>
</view>
<!-- 净化水 -->
<view class="tds-item-box">
<view class="tds-item">
<view class="item">
<text class="water-type">净化水</text>
<text class="tds-value">
TDS值:{{ showPartialResult ? afterTDS : '???' }}
</text>
</view>
<!-- item-img在检测结果出来后才显示 -->
<view class="item-img" v-if="showPartialResult">
<image src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/e7e6a286a568480fada2cafab781cc3cFrame.webp"
mode="aspectFit" />
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 检测完成卡片 -->
<view class="instructions-card instructions-card-step2" v-else-if="props.currentStep === 2">
<image class="card-bg"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/87e28ba2f4764f33a36b0d1cfd47d74aRectangle%203589.webp"
mode="scaleToFill"></image>
<view class="card-content">
<view class="card-title">检测结果</view>
<view class="card-body">
<view class="completion-content">
<view class="contentLeft">
<view class="contentText">TDS值对比</view>
<view class="contentValue">
<!-- 前后TDS值 -->
<view class="beforeTDSValue">前:{{ beforeTDS }}ppm</view>
<view class="jiantou">-></view>
<view class="afterTDSValue">后:{{ afterTDS }}ppm</view>
</view>
<view class="purificationRateContent">
<view class="purificationTitle">净化率:</view>
<view class="purificationValue">{{ purificationRate }}%</view>
<view class="purificationLine">
<!-- 自定义进度条 -->
<view class="custom-progress">
<view class="progress-bg-line"></view>
<view
class="progress-fill-line"
:style="{ width: purificationRate + '%' }">
</view>
</view>
</view>
</view>
</view>
<view class="contentRight">
<!-- TDS柱形图对比 -->
<view class="tds-chart-container">
<!-- 污染水柱形图 -->
<view class="chart-column before-tds-column">
<!-- TDS值显示 -->
<text class="tds-chart-value">{{ beforeTDS }}ppm</text>
<!-- 柱形图 -->
<view class="chart-bar" :style="{ height: beforeTDSHeight + 'rpx' }"></view>
</view>
<!-- 净化水柱形图 -->
<view class="chart-column after-tds-column">
<!-- 上方图片 -->
<image class="tds-icon"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/44463cae0882429ebd84049240ff5330Group%20348447451.webp"
mode="widthFix" />
<!-- TDS值显示 -->
<text class="tds-chart-value">{{ afterTDS }}ppm</text>
<!-- 柱形图 -->
<view class="chart-bar" :style="{ height: afterTDSHeight + 'rpx' }"></view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="tips-card">
<view class="tips-header">
<image class="bulb-icon"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/d2a7b1b81bff44c2b9099a8d48d9d6f1Frame%282%29.webp"
mode="widthFix"></image>
<text class="tips-title">你知道吗?</text>
</view>
<view class="tips-body">
<text v-if="props.currentStep === 0">TDS代表总溶解固体,数值越低水质越纯净</text>
<text v-else-if="props.currentStep === 1">TDS值在0-50ppm为优质饮用水</text>
<text v-else-if="props.currentStep === 2">净化后TDS值显著降低,说明净水效果好</text>
</view>
</view>
<!--底部-->
<view class="bottom-bar">
<view class="test-status">当前测试: <text class="test-status-text">{{ testStatusText }}/2</text></view>
<view class="start-btn-wrapper" @click="handleStartTest">
<image class="startBtn" :src="getButtonImage()" alt="" />
</view>
</view>
</view>
</template>
<script setup>
import { defineProps, defineEmits, ref, watch, onUnmounted, computed } from 'vue';
const props = defineProps({
currentStep: {
type: Number,
default: 0
}
});
const emit = defineEmits(['next-step', 'test-completed']);
const progressWidth = ref(0);
const showPartialResult = ref(false);
const showFinalResult = ref(false);
const isTesting = ref(false);
const testStatusText = ref(1); // TDS测试时显示1/2
// 定义TDS值
const beforeTDS = ref(800); // 污染水TDS值
const afterTDS = ref(15); // 净化水TDS值
let progressTimer = null;
// 计算净化率
const purificationRate = computed(() => {
if (beforeTDS.value <= 0) return 0;
const rate = ((beforeTDS.value - afterTDS.value) / beforeTDS.value) * 100;
return Math.round(rate * 10) / 10; // 保留一位小数
});
// 计算柱形图高度
const maxChartHeight = 130; // 最大高度130rpx
const maxTDSValue = 1000; // 假设最大TDS值为1000,用于比例计算
// 计算污染水柱形图高度
const beforeTDSHeight = computed(() => {
const height = (beforeTDS.value / maxTDSValue) * maxChartHeight;
return Math.min(height, maxChartHeight); // 确保不超过最大高度
});
// 计算净化水柱形图高度
const afterTDSHeight = computed(() => {
const height = (afterTDS.value / maxTDSValue) * maxChartHeight;
return Math.min(height, maxChartHeight); // 确保不超过最大高度
});
// 按钮图片逻辑
const getButtonImage = () => {
if (props.currentStep === 0) {
return 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/51e1fc432e2b406d9d00f1028213221bGroup%20348447439.webp';
} else {
return 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/92306739e0774318bbfc4bbf0a69cba5Group%20348447439.webp';
}
};
// 监听currentStep变化
watch(() => props.currentStep, (newStep) => {
console.log('TDS currentStep变化:', newStep);
if (newStep === 1) {
// 进入步骤1,开始自动检测
testStatusText.value = 1;
startAutoDetection();
} else if (newStep === 2) {
// 进入步骤2,检测完成
showFinalResult.value = true;
resetDetection();
}
}, { immediate: true });
// 开始自动检测
const startAutoDetection = () => {
if (isTesting.value) return;
console.log('开始TDS自动检测');
isTesting.value = true;
progressWidth.value = 0;
showPartialResult.value = false;
showFinalResult.value = false;
// 清除之前的定时器
if (progressTimer) {
clearInterval(progressTimer);
}
// 模拟检测过程
let currentProgress = 0;
const totalTime = 3000; // 总时长3秒(为了快速测试)
const interval = 50; // 更新间隔50ms
const increment = (interval / totalTime) * 100; // 每次增加的百分比
progressTimer = setInterval(() => {
currentProgress += increment;
progressWidth.value = Math.min(currentProgress, 100);
// 当进度达到50%时显示TDS值
if (currentProgress >= 50 && !showPartialResult.value) {
console.log('显示TDS部分结果');
showPartialResult.value = true;
}
// 当进度达到100%时显示完成状态
if (currentProgress >= 100) {
showFinalResult.value = true;
clearInterval(progressTimer);
isTesting.value = false;
console.log('TDS检测完成');
// 检测完成后延迟1秒自动进入下一步
setTimeout(() => {
console.log('自动进入TDS结果页面');
emit('next-step');
}, 1000);
}
}, interval);
};
// 重置检测状态
const resetDetection = () => {
isTesting.value = false;
progressWidth.value = 0;
showPartialResult.value = false;
showFinalResult.value = false;
if (progressTimer) {
clearInterval(progressTimer);
progressTimer = null;
}
};
// 处理按钮点击
const handleStartTest = () => {
console.log('TDS按钮点击,当前步骤:', props.currentStep, '测试完成:', showFinalResult.value);
if (props.currentStep === 0) {
// 第一步:点击"开始检测"
console.log('开始TDS检测');
emit('next-step');
} else if (props.currentStep === 1) {
// 第二步:检测中或检测完成
if (showFinalResult.value) {
// 检测已完成,可以点击按钮进入下一步
console.log('TDS检测完成,进入结果页面');
testStatusText.value = 2;
emit('next-step');
} else {
console.log('TDS检测中,点击无效');
}
} else if (props.currentStep === 2) {
// 第三步:检测完成后的操作 - 点击"下一项检测"
console.log('点击"下一项检测",切换到pH测试');
// 触发测试完成事件,通知父组件切换到pH测试
emit('test-completed');
}
};
// 组件卸载时清理定时器
onUnmounted(() => {
resetDetection();
});
</script>
<style scoped lang="scss">
.test-content {
width: 100%;
height: 45vh;
flex-shrink: 0;
border-radius: 24rpx 24rpx 0 0;
border-top: 4rpx solid #728FAF;
background: linear-gradient(180deg, #E0EBF6 0%, #C3D3E4 100%);
box-shadow: 0 10rpx 0 0 #FFF inset;
box-sizing: border-box;
position: relative;
z-index: 10;
padding-bottom: env(safe-area-inset-bottom);
.tds-phContent {
.contentTabs {
.tabsItems {
margin-top: 32rpx;
display: flex;
align-items: center;
justify-content: center;
.tds {
width: 254rpx;
height: 84rpx;
}
.ph {
width: 254rpx;
height: 84rpx;
margin-left: 40rpx;
}
}
}
}
// 步骤0的卡片样式(原始样式)
.instructions-card-step0 {
position: relative;
width: 95%;
height: 180rpx;
margin: 40rpx auto;
border-radius: 24rpx;
border: 4rpx solid #457AAB;
background: #BEDCF3;
box-sizing: border-box;
flex-shrink: 0;
.card-bg {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 98%;
height: 94%;
z-index: 0;
display: block;
}
.card-content {
position: relative;
z-index: 1;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
.card-title {
text-align: center;
font-size: 34rpx;
font-weight: bold;
color: #25334D;
}
.card-body {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
padding: 0 20rpx;
.instruction-text {
font-size: 30rpx;
color: #25334D;
font-weight: 500;
}
.ppm-icon {
height: 60rpx;
margin-left: 20rpx;
}
}
}
}
// 检测中卡片样式(无边框背景色)
.instructions-card-detecting {
width: 95%;
height: 240rpx;
margin: 40rpx auto;
box-sizing: border-box;
flex-shrink: 0;
background: transparent;
border: none;
.card-content {
position: relative;
z-index: 1;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
.card-body {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
padding: 0 20rpx;
// 进度条样式(使用切图)
.progress-container {
width: 90%;
height: 60rpx;
position: relative;
margin-bottom: 20rpx;
overflow: hidden;
border-radius: 10rpx;
.progress-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.progress-fill-container {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 0%;
overflow: hidden;
z-index: 2;
transition: width 0.1s linear;
.progress-fill {
height: 100%;
width: auto;
min-width: 100%;
}
}
}
// TDS显示样式
.tds-display {
display: flex;
width: 100%;
justify-content: space-around;
align-items: center;
// TDS项目盒子(带边框)
.tds-item-box {
background: linear-gradient(180deg, #FAFBFD 0%, #DCEEFD 100%);
border: 2rpx solid #FFF;
border-radius: 24rpx;
width: 328rpx;
height: 140rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
.tds-item {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
padding: 0 20rpx;
.item {
display: flex;
flex-direction: column;
align-items: flex-start;
.water-type {
font-size: 26rpx;
color: #25334D;
font-weight: 500;
margin-bottom: 8rpx;
}
.tds-value {
font-size: 32rpx;
color: #3481c8;
font-weight: bold;
}
}
.item-img {
width: 92rpx;
height: 92rpx;
display: flex;
align-items: center;
justify-content: center;
image {
width: 100%;
height: 100%;
}
}
}
}
}
}
}
}
// 检测完成卡片样式
.instructions-card-step2 {
position: relative;
width: 95%;
height: 240rpx;
margin: 40rpx auto;
border-radius: 24rpx;
border: 4rpx solid #457AAB;
background: #BEDCF3;
box-sizing: border-box;
flex-shrink: 0;
.card-bg {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 98%;
height: 94%;
z-index: 0;
display: block;
}
.card-content {
position: relative;
z-index: 1;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
.card-title {
text-align: center;
font-size: 34rpx;
font-weight: bold;
color: #25334D;
margin-bottom: 15rpx;
}
.card-body {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0 20rpx;
position: relative;
z-index: 99;
// 完成内容样式
.completion-content {
width: 100%;
padding: 12rpx 16rpx;
display: flex;
align-items: center;
justify-content: space-between;
.contentLeft {
.contentText {
color: #25334d;
font-size: 30rpx;
font-weight: 600;
}
.contentValue {
margin: 12rpx 0;
display: flex;
align-items: center;
.beforeTDSValue {
color: #ffffff;
font-size: 24rpx;
font-weight: 600;
text-align: center;
border: 3rpx solid #9D341A;
background: #D93A12;
border-radius: 16rpx;
padding: 4rpx 12rpx;
}
.afterTDSValue {
color: #ffffff;
font-size: 24rpx;
font-weight: 600;
text-align: center;
border: 3rpx solid #1F8F73;
background: #0FA983;
border-radius: 16rpx;
padding: 4rpx 12rpx;
}
.jiantou {
margin: 0 15rpx;
color: #457AAB;
}
}
.purificationRateContent {
display: flex;
align-items: center;
margin-top: 10rpx;
.purificationTitle {
color: #25334d;
font-size: 30rpx;
font-weight: 600;
margin-right: 10rpx;
}
.purificationValue {
color: #00cc99;
font-size: 34rpx;
font-weight: 600;
margin-right: 20rpx;
min-width: 80rpx;
}
.purificationLine {
width: 192rpx;
height: 28rpx;
// 自定义进度条
.custom-progress {
position: relative;
width: 192rpx;
height: 28rpx;
border-radius: 14rpx;
overflow: hidden;
.progress-bg-line {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #E5E5E5;
border-radius: 14rpx;
}
.progress-fill-line {
position: absolute;
top: 0;
left: 0;
height: 100%;
background-color: #00CC99;
border-radius: 14rpx;
transition: width 0.5s ease-out;
max-width: 100%;
}
}
}
}
}
.contentRight {
width: 196rpx;
height: 142rpx;
border: 2rpx solid #457aab80;
background: #BEDCF3;
border-radius: 12rpx;
position: relative;
// TDS柱形图容器
.tds-chart-container {
position: absolute;
bottom: 0;
width: 100%;
height: 100%;
display: flex;
align-items: flex-end;
justify-content: center;
// 柱形图列样式
.chart-column {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
height: 100%;
// TDS值显示
.tds-chart-value {
font-size: 24rpx;
font-weight: 600;
margin-bottom: 6rpx;
}
// 柱形图
.chart-bar {
width: 42rpx;
min-height: 10rpx;
border-radius: 8rpx 8rpx 0 0;
transition: height 0.5s ease-out;
}
}
// 净化水柱形图
.after-tds-column {
align-items: center;
.tds-icon {
width: 68rpx;
height: 68rpx;
margin-bottom: 4rpx;
}
.tds-chart-value {
color: #0fa983;
font-weight: 700;
}
.chart-bar {
background: linear-gradient(180deg, #36E6BB 0%, #0FA983 100%);
border: 2rpx solid #1F8F73;
}
}
// 污染水柱形图
.before-tds-column {
align-items: center;
.tds-chart-value {
color: #D93A12;
font-weight: 700;
}
.chart-bar {
background: linear-gradient(180deg, #EE6E4E 0%, #D93A12 100%);
border: 2rpx solid #9D341A;
}
}
}
}
}
}
}
}
.tips-card {
width: 95%;
height: 116rpx;
background: #BEDCF3;
border-radius: 24rpx;
border: 4rpx solid #457AAB;
padding: 20rpx;
position: relative;
box-sizing: border-box;
flex-shrink: 0;
margin: 0 auto;
.tips-header {
position: absolute;
top: -24rpx;
left: 20rpx;
width: 234rpx;
height: 56rpx;
background: linear-gradient(180deg, #52A5D7 0%, #3E83CE 100%);
border-radius: 48rpx;
border: 4rpx solid #1B5CA3;
box-shadow: 0 0 8rpx 0 #FFF inset;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
z-index: 10;
.bulb-icon {
position: absolute;
left: -20rpx;
bottom: -10rpx;
width: 80rpx;
height: 80rpx;
z-index: 12;
}
.tips-title {
color: #fff;
font-size: 34rpx;
font-weight: bold;
margin-left: 30rpx;
}
}
.tips-body {
position: absolute;
top: 0;
left: 0;
font-size: 30rpx;
color: #25334d;
line-height: 1.3;
padding: 30rpx 16rpx 10rpx 16rpx;
border-radius: 24rpx;
background: linear-gradient(180deg, #FFF 0%, #D9EBF7 100%);
width: 100%;
height: 100%;
box-sizing: border-box;
z-index: 5;
display: flex;
align-items: center;
justify-content: center;
}
}
.bottom-bar {
width: 100%;
position: absolute;
bottom: 0rpx;
left: 0;
background-image: url('https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/a681444d883d4fe29851d702703302b0Rectangle%203597.webp');
background-repeat: no-repeat;
background-size: 100% 105%;
padding: 30rpx 0;
box-sizing: border-box;
display: flex;
.test-status {
padding: 0 100rpx;
color: #000000;
font-size: 34rpx;
font-weight: 600;
margin-top: 50rpx;
.test-status-text {
color: #3481c8;
font-size: 34rpx;
}
}
.start-btn-wrapper {
position: absolute;
top: 30rpx;
right: 40rpx;
.startBtn {
width: 254rpx;
height: 99rpx;
}
}
}
}
</style>
\ No newline at end of file
<template>
<view class="container">
<view class="top">
<image class="topTitle"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/e9ddd6b498fe452b9254e86c04596df3Group%20348447251.webp">
</image>
</view>
<view class="main-content">
<view class="beaker-section">
<!-- 污染水烧杯 -->
<view class="beaker-item">
<image class="beaker-img" mode="aspectFit"
:src="getBeakerImage('polluted')">
</image>
<view class="beaker-label polluted">污染水</view>
</view>
<image class="vs-icon"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/8678ceab4c7b41ac80cc1982054c45f4VS.webp"
mode="widthFix"></image>
<!-- 净化水烧杯 -->
<view class="beaker-item">
<image class="beaker-img" mode="aspectFit"
:src="getBeakerImage('purified')">
</image>
<view class="beaker-label purified">净化水</view>
</view>
</view>
</view>
<!-- TDS测试内容 -->
<TestContent
v-if="currentTest === 'tds'"
:currentStep="tdsCurrentStep"
@next-step="handleTdsNextStep"
@test-completed="handleTdsCompleted" />
<!-- pH值测试组件 -->
<phValueTest
v-else-if="currentTest === 'ph'"
:currentStep="phCurrentStep"
@next-step="handlePhNextStep"
@test-completed="handlePhCompleted"
@handle-ph-button-click="handlePhButtonClick"
:isAllTestsCompleted="isAllTestsCompleted" />
<!-- 完成弹窗 - 全屏覆盖 -->
<view class="completion-modal" v-if="showCompletionModal" @click="closeCompletionModal">
<image class="modal-image"
src="https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/d204d71cf2a54b18a6404e6132618cd6%E5%AE%8C%E6%88%90%E5%BC%B9%E7%AA%97.webp"
mode="scaleToFill" />
</view>
</view>
</template>
<script setup>
import TestContent from './components/testContent.vue';
import phValueTest from './components/phValueTest.vue';
import { ref, computed } from 'vue';
// 当前测试类型:tds 或 ph
const currentTest = ref('tds');
// TDS测试步骤
const tdsCurrentStep = ref(0);
// pH测试步骤
const phCurrentStep = ref(0);
// 是否显示完成弹窗
const showCompletionModal = ref(false);
// 是否所有测试都已完成
const isAllTestsCompleted = ref(false);
// 获取烧杯图片
const getBeakerImage = (type) => {
if (currentTest.value === 'tds') {
// TDS测试的图片逻辑
if (tdsCurrentStep.value === 0) {
// TDS准备阶段
return type === 'polluted'
? 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/d2729bd9ca6249728c29c66a6e7f1baf%E7%83%A7%E6%9D%AF_%E6%B1%A1%E6%9F%93%E6%B0%B4%E7%89%88%202.webp'
: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/048d81b1821442c3b80d312e4ef7c1e4%E7%83%A7%E6%9D%AF_%E6%B0%B4%E9%9D%A2%E5%B9%B3%E6%95%B4%E7%89%88%201.webp';
} else {
// TDS检测中或完成
return type === 'polluted'
? 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/d775e2166f2d426f857e69dc3d115d47%E7%83%A7%E6%9D%AF_%E6%97%A0%E6%B0%B4%E6%BB%B4%E5%9B%9B%E8%82%A2_%E5%9B%BE2%201.webp'
: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/c18364684a82445382105028ec6d8f44%E7%83%A7%E6%9D%AF_%E6%97%A0%E6%B0%B4%E6%BB%B4%E5%9B%9B%E8%82%A2_%E5%9B%BE1%201.webp';
}
} else {
// pH测试的图片逻辑
if (phCurrentStep.value === 0) {
// pH准备阶段
return type === 'polluted'
? 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/d2729bd9ca6249728c29c66a6e7f1baf%E7%83%A7%E6%9D%AF_%E6%B1%A1%E6%9F%93%E6%B0%B4%E7%89%88%202.webp'
: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/048d81b1821442c3b80d312e4ef7c1e4%E7%83%A7%E6%9D%AF_%E6%B0%B4%E9%9D%A2%E5%B9%B3%E6%95%B4%E7%89%88%201.webp';
} else if (phCurrentStep.value === 1) {
// pH检测中阶段
return type === 'polluted'
? 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/a277ce4fb175493c9cedd60f6aa788d1%E7%83%A7%E6%9D%AF_%E6%9C%AA%E4%BD%BF%E7%94%A8%E9%85%B8%E7%A2%B1%E8%AF%95%E7%BA%B8%201.webp'
: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/7b1c0214a1344946908e8de7ddaaea5e%E7%83%A7%E6%9D%AF_%E6%9C%AA%E4%BD%BF%E7%94%A8%E9%85%B8%E7%A2%B1%E8%AF%95%E7%BA%B8_%E5%87%80%E5%8C%96%E6%B0%B4%201.webp';
} else {
// pH检测完成阶段
return type === 'polluted'
? 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/241f4a3513ed4b22825202afc88aa0da%E7%83%A7%E6%9D%AF_%E7%BB%BF%E8%89%B2%E8%AF%95%E7%BA%B8%201.webp'
: 'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/337db7423769407c8628522d2a3ad51d%E7%83%A7%E6%9D%AF_%E9%BB%84%E7%BB%BF%E8%89%B2%E8%AF%95%E7%BA%B8%201.webp';
}
}
};
// 处理TDS下一步
const handleTdsNextStep = () => {
if (tdsCurrentStep.value < 2) {
tdsCurrentStep.value++;
}
console.log('TDS下一步,当前步骤:', tdsCurrentStep.value);
}
// 处理TDS测试完成
const handleTdsCompleted = () => {
console.log('TDS测试完成,切换到pH测试');
currentTest.value = 'ph';
tdsCurrentStep.value = 0; // 重置TDS步骤
}
// 处理pH下一步
const handlePhNextStep = () => {
if (phCurrentStep.value < 2) {
phCurrentStep.value++;
}
console.log('pH下一步,当前步骤:', phCurrentStep.value);
}
// 处理pH测试完成
const handlePhCompleted = () => {
console.log('pH测试完成,所有测试结束');
// 标记所有测试已完成
isAllTestsCompleted.value = true;
}
// 处理pH按钮点击
const handlePhButtonClick = () => {
console.log('收到pH按钮点击事件,当前所有测试完成状态:', isAllTestsCompleted.value);
if (isAllTestsCompleted.value && phCurrentStep.value === 2) {
console.log('显示完成弹窗');
showCompletionModal.value = true;
}
}
// 关闭完成弹窗
const closeCompletionModal = () => {
console.log('关闭完成弹窗');
showCompletionModal.value = false;
// 点击弹窗后重置所有状态
resetAllTests();
}
// 重置所有测试
const resetAllTests = () => {
console.log('重置所有测试');
currentTest.value = 'tds';
tdsCurrentStep.value = 0;
phCurrentStep.value = 0;
isAllTestsCompleted.value = false;
}
</script>
<style scoped lang="scss">
.container {
width: 100%;
min-height: 100vh;
background-image: url('https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/963079c98b914f349fe9ff5e600d0f65%E6%B0%B4%E8%B4%A8%E6%A3%80%E6%B5%8B%E7%AB%99_%E7%BA%AF%E8%83%8C%E6%99%AF%201.webp');
background-repeat: no-repeat;
background-size: 100% 100%;
position: relative;
.top {
width: 100%;
height: 320rpx;
display: flex;
justify-content: center;
align-items: center;
.topTitle {
width: 240rpx;
height: 108rpx;
text-align: center;
}
}
.main-content {
flex: 1;
padding: 0 40rpx;
display: flex;
flex-direction: column;
align-items: center;
overflow: hidden;
justify-content: center;
margin-top: -60rpx;
.beaker-section {
width: 100%;
display: flex;
justify-content: center;
align-items: flex-end;
position: relative;
flex-shrink: 1;
.beaker-item {
display: flex;
flex-direction: column;
align-items: center;
.beaker-img {
width: 364rpx;
height: 541rpx;
margin-bottom: 10rpx;
}
.beaker-label {
padding: 4rpx 26rpx;
border-radius: 48rpx;
color: #fff;
font-size: 30rpx;
margin-top: 10rpx;
position: relative;
top: -5vh;
z-index: 1;
&.polluted {
background: linear-gradient(180deg, #B79669 0%, #8C6B46 100%);
border: 4rpx solid #503F34;
}
&.purified {
background: linear-gradient(180deg, #4CAAE4 0%, #3F80D2 100%);
border: 4rpx solid #3060AD;
}
}
}
.vs-icon {
width: 108rpx;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 99;
}
}
}
// 完成弹窗样式 - 全屏覆盖最高级
.completion-modal {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 99999; // 最高层级
background: rgba(0, 0, 0, 0.6); // 半透明黑色背景
display: flex;
align-items: center;
justify-content: center;
.modal-image {
width: 100%;
height: 100%;
object-fit: cover; // 确保图片覆盖整个区域
display: block;
}
}
}
</style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment