Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
angel-angel-mini-game
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
杜洋
angel-angel-mini-game
Commits
ea5bbe9a
Commit
ea5bbe9a
authored
Jan 24, 2026
by
Hantao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
优化写法
parent
434bda5c
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
1102 additions
and
1046 deletions
+1102
-1046
BottomActionBar.vue
src/pages/third/components/BottomActionBar.vue
+25
-31
TabsInstructionsPanel.vue
src/pages/third/components/TabsInstructionsPanel.vue
+805
-738
beaker.vue
src/pages/third/components/beaker.vue
+138
-131
index.vue
src/pages/third/index.vue
+134
-146
No files found.
src/pages/third/components/BottomActionBar.vue
View file @
ea5bbe9a
<
template
>
<view
class=
"bottom-bar"
>
<image
src=
"https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/5d0f462d13ec4cbcb6eee7080c637897Group%20348447439.webp
"
<image
:src=
"IMAGES.testing
"
style=
"width:0;height:0;opacity:0;position:absolute;pointer-events:none;"
></image>
<image
class=
"bar-bg"
src=
"https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/a681444d883d4fe29851d702703302b0Rectangle%203597.webp
"
mode=
"scaleToFill"
></image>
<image
class=
"bar-bg"
:src=
"IMAGES.background
"
mode=
"scaleToFill"
></image>
<text
class=
"test-status"
>
当前测试:
<text
class=
"highlight"
>
{{
statusText
}}
</text></text>
<view
class=
"start-btn-wrapper"
@
click=
"handleStartTest"
:class=
"
{ 'disabled': isDisabled }">
<image
class=
"start-btn-img"
:src=
"btnImage"
mode=
"scaleToFill"
></image>
...
...
@@ -12,7 +12,14 @@
</
template
>
<
script
setup
>
import
{
computed
,
ref
,
watch
}
from
'vue'
;
import
{
computed
}
from
'vue'
;
const
IMAGES
=
{
background
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/a681444d883d4fe29851d702703302b0Rectangle%203597.webp'
,
start
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/51e1fc432e2b406d9d00f1028213221bGroup%20348447439.webp'
,
testing
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/5d0f462d13ec4cbcb6eee7080c637897Group%20348447439.webp'
,
finish
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/f8df9974d93a478f8c6b760fd32e15aaGroup%20348447439.webp'
};
const
props
=
defineProps
({
isTesting
:
{
...
...
@@ -35,47 +42,34 @@ const props = defineProps({
const
emit
=
defineEmits
([
'startTest'
,
'restartTest'
,
'showFinalCard'
,
'showCompletionPopup'
]);
const
isDisabled
=
ref
(
false
);
const
statusText
=
computed
(()
=>
{
if
(
props
.
isSecondTest
)
return
'2/2'
;
return
props
.
isTesting
?
'1/2'
:
'0/2'
;
});
const
isDisabled
=
computed
(()
=>
{
return
props
.
isTesting
&&
!
props
.
isProgressFinished
&&
!
props
.
isResultShown
;
});
const
btnImage
=
computed
(()
=>
{
if
(
props
.
isSecondTest
)
{
if
(
props
.
isResultShown
)
{
return
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/f8df9974d93a478f8c6b760fd32e15aaGroup%20348447439.webp'
;
return
IMAGES
.
finish
;
}
if
(
props
.
isTesting
)
{
return
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/5d0f462d13ec4cbcb6eee7080c637897Group%20348447439.webp'
;
return
IMAGES
.
testing
;
}
return
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/51e1fc432e2b406d9d00f1028213221bGroup%20348447439.webp'
;
}
if
(
props
.
isTesting
&&
props
.
isProgressFinished
&&
!
props
.
isResultShown
)
{
return
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/5d0f462d13ec4cbcb6eee7080c637897Group%20348447439.webp'
;
}
return
props
.
isTesting
?
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/5d0f462d13ec4cbcb6eee7080c637897Group%20348447439.webp'
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/51e1fc432e2b406d9d00f1028213221bGroup%20348447439.webp'
;
});
watch
(()
=>
props
.
isTesting
,
(
newVal
)
=>
{
if
(
newVal
)
{
isDisabled
.
value
=
true
;
return
IMAGES
.
start
;
}
});
watch
(()
=>
props
.
isProgressFinished
,
(
newVal
)
=>
{
if
(
newVal
)
{
isDisabled
.
value
=
false
;
}
});
watch
(()
=>
props
.
isResultShown
,
(
newVal
)
=>
{
if
(
newVal
)
{
isDisabled
.
value
=
false
;
if
(
props
.
isTesting
)
{
if
(
props
.
isProgressFinished
&&
!
props
.
isResultShown
)
{
return
IMAGES
.
testing
;
}
return
IMAGES
.
testing
;
}
return
IMAGES
.
start
;
});
const
handleStartTest
=
()
=>
{
...
...
src/pages/third/components/TabsInstructionsPanel.vue
View file @
ea5bbe9a
<
template
>
<view
class=
"tabs-instructions-container"
>
<view
class=
"tabs-row"
>
<template
v-if=
"!isSecondTest"
>
<view
class=
"tab-container"
>
<image
class=
"tab-btn-active tds-active-tab"
:src=
"activeTabImage"
mode=
"scaleToFill"
></image>
</view>
<view
class=
"tab-container"
>
<image
class=
"tab-btn"
:src=
"inactiveTabImage"
mode=
"scaleToFill"
></image>
</view>
</
template
>
<
template
v-else
>
<view
class=
"tab-container"
>
<image
class=
"tab-btn ph-inactive-tab"
:src=
"inactiveTabImage"
mode=
"scaleToFill"
></image>
</view>
<view
class=
"tab-container"
>
<image
class=
"tab-btn-active ph-active-tab"
:src=
"activeTabImage"
mode=
"scaleToFill"
></image>
</view>
</
template
>
<view
class=
"tabs-instructions-container"
>
<view
class=
"tabs-row"
>
<template
v-if=
"!isSecondTest"
>
<view
class=
"tab-container"
>
<image
class=
"tab-btn-active tds-active-tab"
:src=
"activeTabImage"
mode=
"scaleToFill"
/>
</view>
<view
class=
"tab-container"
>
<image
class=
"tab-btn"
:src=
"inactiveTabImage"
mode=
"scaleToFill"
/>
</view>
</
template
>
<
template
v-else
>
<view
class=
"tab-container"
>
<image
class=
"tab-btn ph-inactive-tab"
:src=
"inactiveTabImage"
mode=
"scaleToFill"
/>
</view>
<view
class=
"tab-container"
>
<image
class=
"tab-btn-active ph-active-tab"
:src=
"activeTabImage"
mode=
"scaleToFill"
/>
</view>
</
template
>
</view>
<view
class=
"instructions-card"
v-if=
"!isTesting"
>
<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"
>
{{ instructionText }}
</text>
<image
class=
"ppm-icon"
:class=
"{ 'ph-icon': isSecondTest }"
:src=
"instructionIcon"
:mode=
"iconMode"
v-if=
"instructionIcon"
@
error=
"handleImageError"
></image>
<image
class=
"ph-label-img"
src=
"https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/536133e8a44f4482b2848016385d79cbPH.webp"
mode=
"aspectFit"
v-if=
"isSecondTest"
></image>
</view>
</view>
<view
class=
"instructions-card"
v-if=
"!isTesting"
>
<image
class=
"card-bg"
:src=
"IMAGES.cardBg"
mode=
"scaleToFill"
/>
<view
class=
"card-content"
>
<view
class=
"card-title"
>
操作说明
</view>
<view
class=
"card-body"
>
<text
class=
"instruction-text"
>
{{ instructionText }}
</text>
<image
class=
"ppm-icon"
:class=
"{ 'ph-icon': isSecondTest }"
:src=
"instructionIcon"
:mode=
"iconMode"
v-if=
"instructionIcon"
@
error=
"handleImageError"
/>
<image
class=
"ph-label-img"
:src=
"IMAGES.phLabel"
mode=
"aspectFit"
v-if=
"isSecondTest"
/>
</view>
</view>
</view>
<view
class=
"progress-panel"
v-else
>
<view
class=
"progress-bar-container"
v-if=
"!showFinalCard"
>
<image
class=
"progress-bar-bg result-img"
src=
"https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/45cebdfeb99a44049d18ab3b04024ac2Group%20348447442.webp"
mode=
"scaleToFill"
v-if=
"showResults"
></image>
<image
class=
"progress-bar-bg initial-img"
src=
"https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/7b21b166605d4c7c9bb4377280202da7Group%20348447442.webp"
mode=
"scaleToFill"
v-if=
"!showResults"
></image>
<view
class=
"progress-panel"
v-else
>
<view
class=
"progress-bar-container"
v-if=
"!showFinalCard"
>
<image
class=
"progress-bar-bg result-img"
:src=
"IMAGES.progressResult"
mode=
"scaleToFill"
v-if=
"showResults"
/>
<image
class=
"progress-bar-bg initial-img"
:src=
"IMAGES.progressInitial"
mode=
"scaleToFill"
v-if=
"!showResults"
/>
</view>
<view
class=
"result-card"
v-if=
"showFinalCard"
>
<image
class=
"card-bg"
:src=
"IMAGES.cardBg"
mode=
"scaleToFill"
/>
<view
class=
"card-content"
>
<view
class=
"card-title"
>
检测结果
</view>
<view
class=
"card-body result-body"
v-if=
"!isSecondTest"
>
<view
class=
"comparison-section"
>
<text
class=
"section-title"
>
TDS值对比
</text>
<view
class=
"comparison-row"
>
<view
class=
"value-badge before"
>
<text>
前: 450ppm
</text>
</view>
<text
class=
"arrow"
>
→
</text>
<view
class=
"value-badge after"
>
<text>
后: 15ppm
</text>
</view>
</view>
<view
class=
"rate-row"
>
<text
class=
"rate-label"
>
净化率:
</text>
<text
class=
"rate-value"
>
96.7%
</text>
<view
class=
"rate-bar"
>
<view
class=
"rate-fill"
:style=
"{ width: '93.7%' }"
></view>
</view>
</view>
</view>
<view
class=
"result-card"
v-if=
"showFinalCard"
>
<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 result-body"
v-if=
"!isSecondTest"
>
<view
class=
"comparison-section"
>
<text
class=
"section-title"
>
TDS值对比
</text>
<view
class=
"comparison-row"
>
<view
class=
"value-badge before"
>
<text>
前: 450ppm
</text>
</view>
<text
class=
"arrow"
>
→
</text>
<view
class=
"value-badge after"
>
<text>
后: 15ppm
</text>
</view>
</view>
<view
class=
"rate-row"
>
<text
class=
"rate-label"
>
净化率:
</text>
<text
class=
"rate-value"
>
96.7%
</text>
<view
class=
"rate-bar"
>
<view
class=
"rate-fill"
:style=
"{ width: '93.7%' }"
></view>
</view>
</view>
</view>
<view
class=
"chart-section"
>
<view
class=
"chart-container"
>
<view
class=
"bar-group red"
>
<text
class=
"bar-label"
>
450ppm
</text>
<view
class=
"bar"
></view>
</view>
<view
class=
"bar-group green"
>
<text
class=
"bar-label"
>
15ppm
</text>
<view
class=
"bar"
></view>
</view>
</view>
<image
class=
"badge-icon"
src=
"https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/44463cae0882429ebd84049240ff5330Group%20348447451.webp"
mode=
"aspectFit"
></image>
</view>
</view>
<view
class=
"card-body ph-result-body"
v-else
>
<view
class=
"ph-comparison-row"
>
<view
class=
"ph-value-group"
>
<text
class=
"label"
>
前:
</text>
<text
class=
"value highlight-green"
>
8.5
</text>
<view
class=
"ph-tag alkaline"
>
<text>
偏碱性
</text>
</view>
</view>
<image
class=
"ph-warning-icon"
src=
"https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/0c6358f526fd4a72a098e5e46c9a8759Frame%2017.webp"
mode=
"aspectFit"
></image>
<text
class=
"ph-arrow"
>
→
</text>
<view
class=
"ph-value-group"
>
<text
class=
"label"
>
后:
</text>
<text
class=
"value highlight-lime"
>
7.0
</text>
<view
class=
"ph-tag neutral"
>
<text>
中性
</text>
</view>
</view>
<image
class=
"ph-success-icon"
src=
"https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/dd15bc1646cb4fcb86670b2b1ae04809Group%20348447459.webp"
mode=
"aspectFit"
></image>
</view>
<view
class=
"ph-chart-container"
>
<image
class=
"ph-chart-img"
src=
"https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/3df0383e2218465c83af9aeeae10e1baGroup%20348447462.webp"
mode=
"widthFix"
></image>
</view>
<view
class=
"ph-footer-row"
>
<text
class=
"ph-footer-label"
>
酸碱度:
<text
class=
"highlight"
>
已优化
</text></text>
<view
class=
"ph-badge"
>
适合饮用
</view>
</view>
</view>
<view
class=
"chart-section"
>
<view
class=
"chart-container"
>
<view
class=
"bar-group red"
>
<text
class=
"bar-label"
>
450ppm
</text>
<view
class=
"bar"
></view>
</view>
<view
class=
"bar-group green"
>
<text
class=
"bar-label"
>
15ppm
</text>
<view
class=
"bar"
></view>
</view>
</view>
<image
class=
"badge-icon"
:src=
"IMAGES.badgeIcon"
mode=
"aspectFit"
/>
</view>
<view
class=
"result-boxes"
v-if=
"!showFinalCard"
>
<view
class=
"result-box"
>
<text
class=
"box-title"
>
污染水
</text
>
<text
class=
"box-value"
:style=
"{ color: showResults ? '#FF3300' : '#25334D' }"
>
{{ resultLabel }}:{{ pollutedValue }}
</text
>
<image
class=
"status-icon"
src=
"https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/0c6358f526fd4a72a098e5e46c9a8759Frame%2017.webp"
alt=
"警告"
v-if=
"showResults"
></image
>
</view>
<view
class=
"card-body ph-result-body"
v-else
>
<view
class=
"ph-comparison-row"
>
<view
class=
"ph-value-group"
>
<text
class=
"label"
>
前:
</text>
<text
class=
"value highlight-green"
>
8.5
</text>
<view
class=
"ph-tag alkaline"
>
<text>
偏碱性
</text
>
</view>
<view
class=
"result-box"
>
<text
class=
"box-title"
>
净化水
</text>
<text
class=
"box-value"
:style=
"{ color: showResults ? '#00CC99' : '#25334D' }"
>
{{ resultLabel }}:{{ purifiedValue }}
</text>
<image
class=
"status-icon"
src=
"https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/e7e6a286a568480fada2cafab781cc3cFrame.webp"
alt=
"通过"
v-if=
"showResults"
></image>
</view>
<image
class=
"ph-warning-icon"
:src=
"IMAGES.warningIcon"
mode=
"aspectFit"
/>
<text
class=
"ph-arrow"
>
→
</text>
<view
class=
"ph-value-group"
>
<text
class=
"label"
>
后:
</text>
<text
class=
"value highlight-lime"
>
7.0
</text>
<view
class=
"ph-tag neutral"
>
<text>
中性
</text>
</view>
</view>
<image
class=
"ph-success-icon"
:src=
"IMAGES.successIcon"
mode=
"aspectFit"
/>
</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
class=
"ph-chart-container"
>
<image
class=
"ph-chart-img"
:src=
"IMAGES.phChart"
mode=
"widthFix"
/>
</view>
<view
class=
"tips-body"
>
<text>
{{ tipsText }}
</text>
<view
class=
"ph-footer-row"
>
<text
class=
"ph-footer-label"
>
酸碱度:
<text
class=
"highlight"
>
已优化
</text></text
>
<view
class=
"ph-badge"
>
适合饮用
</view>
</view>
</view>
</view>
</view>
<view
class=
"result-boxes"
v-if=
"!showFinalCard"
>
<view
class=
"result-box"
>
<text
class=
"box-title"
>
污染水
</text>
<text
class=
"box-value"
:style=
"{ color: showResults ? '#FF3300' : '#25334D' }"
>
{{ resultLabel }}:{{ pollutedValue }}
</text
>
<image
class=
"status-icon"
:src=
"IMAGES.warningIcon"
alt=
"警告"
v-if=
"showResults"
/>
</view>
<view
class=
"result-box"
>
<text
class=
"box-title"
>
净化水
</text>
<text
class=
"box-value"
:style=
"{ color: showResults ? '#00CC99' : '#25334D' }"
>
{{ resultLabel }}:{{ purifiedValue }}
</text
>
<image
class=
"status-icon"
:src=
"IMAGES.successIconFrame"
alt=
"通过"
v-if=
"showResults"
/>
</view>
</view>
</view>
<view
class=
"tips-card"
>
<view
class=
"tips-header"
>
<image
class=
"bulb-icon"
:src=
"IMAGES.bulbIcon"
mode=
"widthFix"
/>
<text
class=
"tips-title"
>
你知道吗?
</text>
</view>
<view
class=
"tips-body"
>
<text>
{{ tipsText }}
</text>
</view>
</view>
</view>
</template>
<
script
setup
>
import
{
computed
,
ref
,
watch
}
from
'vue'
;
const
props
=
defineProps
({
isTesting
:
{
type
:
Boolean
,
default
:
false
},
isSecondTest
:
{
type
:
Boolean
,
default
:
false
},
triggerShowFinalCard
:
{
type
:
Boolean
,
default
:
false
}
isTesting
:
{
type
:
Boolean
,
default
:
false
,
},
isSecondTest
:
{
type
:
Boolean
,
default
:
false
,
},
triggerShowFinalCard
:
{
type
:
Boolean
,
default
:
false
,
},
});
const
emit
=
defineEmits
([
'resultShown'
,
'progressFinished'
]);
...
...
@@ -184,695 +219,726 @@ const emit = defineEmits(['resultShown', 'progressFinished']);
const
showResults
=
ref
(
false
);
const
showFinalCard
=
ref
(
false
);
const
IMAGES
=
{
// 两个选项图片
tabActiveTds
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/b91478ab6f2d4c2186a948ae9b614f45Group%20348447426.webp'
,
tabActivePh
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/b9c5667e95ea48a1b4c10f2d9ee84db6Group%20348447426.webp'
,
tabInactiveTds
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/a4bd654c5fd4401bb4d09ce1a8e08aa3Group%20348447427.webp'
,
tabInactivePh
:
'/static/1.webp'
,
// 介绍内部图片
instructionTds
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/1a62746fad3743d19f01e8b612ed8d42Group%20348447435.webp'
,
instructionPh
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/32ac38db03994072aca53ae518b996eeGroup%20348447450.webp'
,
phLabel
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/536133e8a44f4482b2848016385d79cbPH.webp'
,
cardBg
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/87e28ba2f4764f33a36b0d1cfd47d74aRectangle%203589.webp'
,
// 进度条
progressResult
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/45cebdfeb99a44049d18ab3b04024ac2Group%20348447442.webp'
,
progressInitial
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/7b21b166605d4c7c9bb4377280202da7Group%20348447442.webp'
,
// 结果内部图片
warningIcon
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/0c6358f526fd4a72a098e5e46c9a8759Frame%2017.webp'
,
successIcon
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/dd15bc1646cb4fcb86670b2b1ae04809Group%20348447459.webp'
,
successIconFrame
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/e7e6a286a568480fada2cafab781cc3cFrame.webp'
,
badgeIcon
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/44463cae0882429ebd84049240ff5330Group%20348447451.webp'
,
phChart
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/3df0383e2218465c83af9aeeae10e1baGroup%20348447462.webp'
,
// 灯泡
bulbIcon
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/d2a7b1b81bff44c2b9099a8d48d9d6f1Frame%282%29.webp'
,
};
const
activeTabImage
=
computed
(()
=>
{
return
props
.
isSecondTest
?
'/static/1.webp'
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/b91478ab6f2d4c2186a948ae9b614f45Group%20348447426.webp'
;
return
props
.
isSecondTest
?
IMAGES
.
tabInactivePh
:
IMAGES
.
tabActiveTds
;
});
const
inactiveTabImage
=
computed
(()
=>
{
return
props
.
isSecondTest
?
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/b9c5667e95ea48a1b4c10f2d9ee84db6Group%20348447426.webp'
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/a4bd654c5fd4401bb4d09ce1a8e08aa3Group%20348447427.webp'
;
return
props
.
isSecondTest
?
IMAGES
.
tabActivePh
:
IMAGES
.
tabInactiveTds
;
});
const
instructionText
=
computed
(()
=>
{
return
props
.
isSecondTest
?
"点击‘开始检测’测试水的酸碱度"
:
'点击"开始检测"按钮测试TDS值'
;
return
props
.
isSecondTest
?
"点击‘开始检测’测试水的酸碱度"
:
'点击"开始检测"按钮测试TDS值'
;
});
const
instructionIcon
=
computed
(()
=>
{
return
props
.
isSecondTest
?
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/32ac38db03994072aca53ae518b996eeGroup%20348447450.webp'
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/1a62746fad3743d19f01e8b612ed8d42Group%20348447435.webp'
;
return
props
.
isSecondTest
?
IMAGES
.
instructionPh
:
IMAGES
.
instructionTds
;
});
const
iconMode
=
computed
(()
=>
{
return
props
.
isSecondTest
?
'aspectFit'
:
'heightFix'
;
return
props
.
isSecondTest
?
'aspectFit'
:
'heightFix'
;
});
const
handleImageError
=
(
e
)
=>
{
console
.
error
(
'Image load failed:'
,
e
.
detail
.
errMsg
);
};
const
tipsText
=
computed
(()
=>
{
if
(
props
.
isSecondTest
)
{
if
(
props
.
isTesting
)
{
return
'pH试纸通过颜色变化判断酸碱性'
;
}
return
'理想饮用水pH值应在6.5-8.5之间'
;
if
(
props
.
isSecondTest
)
{
if
(
showFinalCard
.
value
)
{
return
'中性水(pH 7.0)对人体最温和,是理想的饮用水'
;
}
if
(
!
props
.
isTesting
)
{
return
'TDS代表总溶解固体,数值越低水质越纯净
'
;
if
(
props
.
isTesting
)
{
return
'pH试纸通过颜色变化判断酸碱性
'
;
}
return
showFinalCard
.
value
?
'优质饮用水TDS值应低于50ppm'
:
'安吉尔RO反渗透技术可将TDS降至15以下'
;
return
'理想饮用水pH值应在6.5-8.5之间'
;
}
if
(
!
props
.
isTesting
)
{
return
'TDS代表总溶解固体,数值越低水质越纯净'
;
}
return
showFinalCard
.
value
?
'优质饮用水TDS值应低于50ppm'
:
'安吉尔RO反渗透技术可将TDS降至15以下'
;
});
const
resultLabel
=
computed
(()
=>
{
return
props
.
isSecondTest
?
'PH值'
:
'TDS值'
;
return
props
.
isSecondTest
?
'PH值'
:
'TDS值'
;
});
const
pollutedValue
=
computed
(()
=>
{
if
(
!
showResults
.
value
)
return
'???'
;
return
props
.
isSecondTest
?
'8.5'
:
'450'
;
if
(
!
showResults
.
value
)
return
'???'
;
return
props
.
isSecondTest
?
'8.5'
:
'450'
;
});
const
purifiedValue
=
computed
(()
=>
{
if
(
!
showResults
.
value
)
return
'???'
;
return
props
.
isSecondTest
?
'7.0'
:
'15'
;
if
(
!
showResults
.
value
)
return
'???'
;
return
props
.
isSecondTest
?
'7.0'
:
'15'
;
});
watch
(()
=>
props
.
isTesting
,
(
newVal
)
=>
{
const
handleImageError
=
(
e
)
=>
{
console
.
error
(
'Image load failed:'
,
e
.
detail
.
errMsg
);
};
watch
(
()
=>
props
.
isTesting
,
(
newVal
)
=>
{
if
(
newVal
)
{
showResults
.
value
=
false
;
showFinalCard
.
value
=
false
;
setTimeout
(()
=>
{
showResults
.
value
=
true
;
emit
(
'progressFinished'
);
},
1000
);
showResults
.
value
=
false
;
showFinalCard
.
value
=
false
;
setTimeout
(()
=>
{
showResults
.
value
=
true
;
emit
(
'progressFinished'
);
},
1000
);
}
else
{
showResults
.
value
=
false
;
showFinalCard
.
value
=
false
;
showResults
.
value
=
false
;
showFinalCard
.
value
=
false
;
}
});
}
);
watch
(()
=>
props
.
triggerShowFinalCard
,
(
newVal
)
=>
{
watch
(
()
=>
props
.
triggerShowFinalCard
,
(
newVal
)
=>
{
if
(
newVal
)
{
showFinalCard
.
value
=
true
;
emit
(
'resultShown'
);
showFinalCard
.
value
=
true
;
emit
(
'resultShown'
);
}
});
}
);
</
script
>
<
style
scoped
lang=
"scss"
>
.tabs-instructions-container
{
width
:
100%
;
max-width
:
100%
;
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
width
:
100%
;
max-width
:
100%
;
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
}
.tabs-row
{
display
:
flex
;
justify-content
:
center
;
gap
:
60
rpx
;
margin-bottom
:
0.5vh
;
.tab-container
{
position
:
relative
;
display
:
flex
;
justify-content
:
center
;
gap
:
60
rpx
;
margin-bottom
:
0.5vh
;
align-items
:
center
;
}
.tab-container
{
position
:
relative
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
.tab-btn-active
{
width
:
280
rpx
;
height
:
84
rpx
;
//
Specific
style
for
TDS
test
active
image
(...426.webp)
&.tds-active-tab
{
width
:
280
rpx
;
height
:
124
rpx
;
}
.tab-btn-active
{
width
:
280
rpx
;
height
:
84
rpx
;
//
Specific
style
for
PH
test
active
image
(..
.426.webp
)
&
.ph-active-tab
{
width
:
274
rpx
;
height
:
128
rpx
;
margin-top
:
10
rpx
;
}
}
&.tds-active-tab
{
width
:
280
rpx
;
height
:
124
rpx
;
}
.tab-btn
{
width
:
240
rpx
;
height
:
84
rpx
;
&
.ph-active-tab
{
width
:
274
rpx
;
height
:
128
rpx
;
margin-top
:
10
rpx
;
}
//
Specific
style
for
PH
test
inactive
image
(/static/1.webp)
&.ph-inactive-tab
{
width
:
242
rpx
;
height
:
94
rpx
;
margin-left
:
20
rpx
;
}
}
}
.instructions-card
{
position
:
relative
;
width
:
120%
;
max-width
:
710
rpx
;
height
:
224
rpx
;
margin
:
1vh
0
;
border-radius
:
24
rpx
;
border
:
4
rpx
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
:
34
rpx
;
font-weight
:
600
;
color
:
#25334D
;
}
.tab-btn
{
width
:
240
rpx
;
.card-body
{
flex
:
1
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
padding
:
0
20
rpx
;
.instruction-text
{
font-size
:
30
rpx
;
color
:
#25334D
;
font-weight
:
600
;
}
.ppm-icon
{
height
:
84
rpx
;
margin-left
:
10
rpx
;
}
&.ph-inactive-tab
{
width
:
242
rpx
;
height
:
94
rpx
;
margin-left
:
20
rpx
;
}
.ph-icon
{
width
:
112
rpx
;
height
:
160
rpx
;
margin-top
:
0
;
position
:
absolute
;
right
:
12
rpx
;
top
:
50%
;
transform
:
translateY
(
-50%
);
}
.ph-label-img
{
position
:
absolute
;
right
:
96
rpx
;
top
:
28%
;
transform
:
translateY
(
-50%
);
width
:
50
rpx
;
height
:
28
rpx
;
}
}
}
}
.instructions-card
{
.progress-panel
{
width
:
120%
;
max-width
:
710
rpx
;
margin
:
1vh
0
0
;
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
flex-shrink
:
0
;
box-sizing
:
border-box
;
.progress-bar-container
{
width
:
100%
;
height
:
64
rpx
;
margin-bottom
:
24
rpx
;
position
:
relative
;
.progress-bar-bg
{
width
:
100%
;
height
:
100%
;
position
:
absolute
;
top
:
0
;
left
:
0
;
}
.result-img
{
z-index
:
1
;
}
.initial-img
{
z-index
:
2
;
}
}
.result-card
{
position
:
relative
;
width
:
120%
;
max-width
:
710
rpx
;
height
:
224
rpx
;
margin
:
1vh
0
;
width
:
100%
;
height
:
226
rpx
;
margin-bottom
:
24
rpx
;
border-radius
:
24
rpx
;
border
:
4
rpx
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
;
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%
;
position
:
relative
;
z-index
:
1
;
width
:
100%
;
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
center
;
.card-title
{
text-align
:
center
;
font-size
:
34
rpx
;
font-weight
:
600
;
color
:
#25334D
;
}
.card-body
{
flex
:
1
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
center
;
.card-title
{
text-align
:
center
;
font-size
:
34
rpx
;
font-weight
:
600
;
color
:
#25334D
;
align-items
:
center
;
padding
:
0
20
rpx
;
.instruction-text
{
font-size
:
30
rpx
;
color
:
#25334D
;
}
.card-body
{
flex
:
1
;
&
.result-body
{
justify-content
:
flex-start
;
align-items
:
flex-start
;
padding
:
10
rpx
40
rpx
;
.comparison-section
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
padding
:
0
20
rpx
;
.instruction-text
{
flex-direction
:
column
;
gap
:
12
rpx
;
.section-title
{
font-size
:
30
rpx
;
color
:
#25334D
;
font-weight
:
600
;
}
.comparison-row
{
display
:
flex
;
align-items
:
center
;
gap
:
16
rpx
;
.value-badge
{
padding
:
6
rpx
14
rpx
;
border-radius
:
16
rpx
;
font-size
:
24
rpx
;
color
:
#FFFFFF
;
font-weight
:
600
;
&.before
{
background
:
#D93A12
;
border
:
3
rpx
solid
#9D341A
;
}
&
.after
{
background
:
#0FA983
;
border
:
3
rpx
solid
#1F8F73
;
}
}
.arrow
{
color
:
#457AAB
;
font-weight
:
bold
;
font-size
:
28
rpx
;
}
}
.rate-row
{
display
:
flex
;
align-items
:
center
;
margin-top
:
4
rpx
;
.rate-label
{
font-size
:
30
rpx
;
color
:
#25334D
;
font-weight
:
600
;
}
.ppm-icon
{
height
:
84
rpx
;
}
.rate-value
{
font-size
:
32
rpx
;
color
:
#00CC99
;
font-weight
:
bold
;
margin-left
:
10
rpx
;
}
}
.ph-icon
{
width
:
112
rpx
;
height
:
160
rpx
;
margin-top
:
0
;
.rate-bar
{
width
:
192
rpx
;
height
:
28
rpx
;
background
:
#8FB2CE
;
border-radius
:
22
rpx
;
border
:
1px
solid
rgba
(
69
,
122
,
171
,
0.8
);
box-shadow
:
0
3
rpx
4
rpx
0
rgba
(
90
,
108
,
122
,
0.4
)
inset
;
margin-left
:
20
rpx
;
overflow
:
hidden
;
position
:
relative
;
.rate-fill
{
height
:
100%
;
background
:
#00CC99
;
border-radius
:
22
rpx
;
box-shadow
:
0
0
4
rpx
0
rgba
(
255
,
255
,
255
,
0.7
)
inset
;
}
}
}
}
.chart-section
{
width
:
186
rpx
;
height
:
138
rpx
;
background
:
#BEDCF3
;
border
:
2
rpx
solid
rgba
(
69
,
122
,
171
,
0.5
);
border-radius
:
12
rpx
;
position
:
absolute
;
right
:
20
rpx
;
top
:
60%
;
transform
:
translateY
(
-50%
);
box-sizing
:
border-box
;
z-index
:
10
;
.chart-container
{
width
:
100%
;
height
:
100%
;
position
:
relative
;
display
:
flex
;
align-items
:
flex-end
;
padding
:
0
20
rpx
10
rpx
;
box-sizing
:
border-box
;
gap
:
30
rpx
;
.bar-group
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
gap
:
4
rpx
;
position
:
absolute
;
right
:
12
rpx
;
top
:
50%
;
transform
:
translateY
(
-50%
);
bottom
:
3
rpx
;
.bar-label
{
font-size
:
20
rpx
;
font-weight
:
600
;
white-space
:
nowrap
;
}
.bar
{
width
:
32
rpx
;
border-radius
:
4
rpx
4
rpx
0
0
;
}
&
.red
{
left
:
15
rpx
;
.bar-label
{
color
:
#D93A12
;
}
.bar
{
height
:
80
rpx
;
background
:
linear-gradient
(
180deg
,
#EE6E4E
0%
,
#D93A12
100%
);
border
:
1
rpx
solid
#9D341A
;
}
}
&
.green
{
right
:
20
rpx
;
.bar-label
{
color
:
#0FA983
;
margin-bottom
:
4
rpx
;
}
.bar
{
height
:
16
rpx
;
background
:
linear-gradient
(
180deg
,
#36E6BB
0%
,
#0FA983
100%
);
border
:
1
rpx
solid
#1F8F73
;
}
}
}
}
.
ph-label-img
{
position
:
absolute
;
right
:
96
rpx
;
top
:
28%
;
transform
:
translateY
(
-50%
)
;
width
:
50
rpx
;
height
:
28
rpx
;
.
badge-icon
{
position
:
absolute
;
top
:
10
rpx
;
right
:
10
rpx
;
width
:
68
rpx
;
height
:
68
rpx
;
z-index
:
2
;
}
}
}
}
}
.progress-panel
{
width
:
120%
;
max-width
:
710
rpx
;
margin
:
1vh
0
0
;
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
flex-shrink
:
0
;
box-sizing
:
border-box
;
&
.ph-result-body
{
flex-direction
:
column
;
justify-content
:
space-between
;
padding
:
10
rpx
30
rpx
!important
;
.progress-bar-container
{
width
:
100%
;
height
:
64
rpx
;
margin-bottom
:
24
rpx
;
position
:
relative
;
.progress-bar-bg
{
.ph-comparison-row
{
display
:
flex
;
align-items
:
center
;
width
:
100%
;
height
:
100%
;
position
:
absolute
;
top
:
0
;
left
:
0
;
}
justify-content
:
center
;
gap
:
16
rpx
;
.result-img
{
z-index
:
1
;
}
.ph-value-group
{
display
:
flex
;
align-items
:
center
;
gap
:
8
rpx
;
.initial-img
{
z-index
:
2
;
}
}
.label
{
color
:
#25334D
;
font-size
:
30
rpx
;
font-weight
:
600
;
}
.result-card
{
position
:
relative
;
width
:
100%
;
height
:
226
rpx
;
margin-bottom
:
24
rpx
;
border-radius
:
24
rpx
;
border
:
4
rpx
solid
#457AAB
;
background
:
#BEDCF3
;
box-sizing
:
border-box
;
.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
:
34
rpx
;
.value
{
font-size
:
30
rpx
;
font-weight
:
600
;
color
:
#25334D
;
}
.card-body
{
flex
:
1
;
&.highlight-green
{
color
:
#4C9F6A
;
}
&
.highlight-lime
{
color
:
#B2C849
;
}
}
.ph-tag
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
padding
:
0
20
rpx
;
.instruction-text
{
font-size
:
30
rpx
;
color
:
#25334D
;
text
{
color
:
#fff
;
font-size
:
20
rpx
;
font-weight
:
600
;
line-height
:
1
;
}
&
.result-body
{
justify-content
:
flex-start
;
align-items
:
flex-start
;
padding
:
10
rpx
40
rpx
;
.comparison-section
{
display
:
flex
;
flex-direction
:
column
;
gap
:
12
rpx
;
.section-title
{
font-size
:
30
rpx
;
color
:
#25334D
;
font-weight
:
600
;
}
.comparison-row
{
display
:
flex
;
align-items
:
center
;
gap
:
16
rpx
;
.value-badge
{
padding
:
6
rpx
14
rpx
;
border-radius
:
16
rpx
;
font-size
:
24
rpx
;
color
:
#FFFFFF
;
font-weight
:
600
;
&.before
{
background
:
#D93A12
;
border
:
3
rpx
solid
#9D341A
;
}
&
.after
{
background
:
#0FA983
;
border
:
3
rpx
solid
#1F8F73
;
}
}
.arrow
{
color
:
#457AAB
;
font-weight
:
bold
;
font-size
:
28
rpx
;
}
}
.rate-row
{
display
:
flex
;
align-items
:
center
;
margin-top
:
4
rpx
;
.rate-label
{
font-size
:
30
rpx
;
color
:
#25334D
;
font-weight
:
600
;
}
.rate-value
{
font-size
:
32
rpx
;
color
:
#00CC99
;
font-weight
:
bold
;
margin-left
:
10
rpx
;
}
.rate-bar
{
width
:
192
rpx
;
height
:
28
rpx
;
background
:
#8FB2CE
;
border-radius
:
22
rpx
;
border
:
1px
solid
rgba
(
69
,
122
,
171
,
0.8
);
box-shadow
:
0
3
rpx
4
rpx
0
rgba
(
90
,
108
,
122
,
0.4
)
inset
;
margin-left
:
20
rpx
;
overflow
:
hidden
;
position
:
relative
;
.rate-fill
{
height
:
100%
;
background
:
#00CC99
;
border-radius
:
22
rpx
;
box-shadow
:
0
0
4
rpx
0
rgba
(
255
,
255
,
255
,
0.7
)
inset
;
}
}
}
}
.chart-section
{
width
:
186
rpx
;
height
:
138
rpx
;
background
:
#BEDCF3
;
border
:
2
rpx
solid
rgba
(
69
,
122
,
171
,
0.5
);
border-radius
:
12
rpx
;
position
:
absolute
;
right
:
20
rpx
;
top
:
60%
;
transform
:
translateY
(
-50%
);
box-sizing
:
border-box
;
z-index
:
10
;
.chart-container
{
width
:
100%
;
height
:
100%
;
position
:
relative
;
display
:
flex
;
align-items
:
flex-end
;
padding
:
0
20
rpx
10
rpx
;
box-sizing
:
border-box
;
gap
:
30
rpx
;
.bar-group
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
gap
:
4
rpx
;
position
:
absolute
;
bottom
:
3
rpx
;
.bar-label
{
font-size
:
20
rpx
;
font-weight
:
600
;
white-space
:
nowrap
;
}
.bar
{
width
:
32
rpx
;
border-radius
:
4
rpx
4
rpx
0
0
;
}
&
.red
{
left
:
15
rpx
;
.bar-label
{
color
:
#D93A12
;
}
.bar
{
height
:
80
rpx
;
background
:
linear-gradient
(
180deg
,
#EE6E4E
0%
,
#D93A12
100%
);
border
:
1
rpx
solid
#9D341A
;
}
}
&
.green
{
right
:
20
rpx
;
.bar-label
{
color
:
#0FA983
;
margin-bottom
:
4
rpx
;
}
.bar
{
height
:
16
rpx
;
background
:
linear-gradient
(
180deg
,
#36E6BB
0%
,
#0FA983
100%
);
border
:
1
rpx
solid
#1F8F73
;
}
}
}
}
.badge-icon
{
position
:
absolute
;
top
:
10
rpx
;
right
:
10
rpx
;
width
:
68
rpx
;
height
:
68
rpx
;
z-index
:
2
;
}
}
&
.alkaline
{
width
:
72
rpx
;
height
:
30
rpx
;
border-radius
:
26
rpx
;
border
:
2
rpx
solid
#0E692E
;
background
:
#4C9F6A
;
}
&
.ph-result-body
{
flex-direction
:
column
;
justify-content
:
space-between
;
padding
:
10
rpx
30
rpx
!important
;
.ph-comparison-row
{
display
:
flex
;
align-items
:
center
;
width
:
100%
;
justify-content
:
center
;
gap
:
16
rpx
;
margin-top
:
18
rpx
;
.ph-value-group
{
display
:
flex
;
align-items
:
center
;
gap
:
8
rpx
;
.label
{
color
:
#25334D
;
font-size
:
30
rpx
;
font-weight
:
600
;
}
.value
{
font-size
:
30
rpx
;
font-weight
:
600
;
&.highlight-green
{
color
:
#4C9F6A
;
}
&
.highlight-lime
{
color
:
#B2C849
;
}
}
.ph-tag
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
text
{
color
:
#fff
;
font-size
:
16
rpx
;
font-weight
:
500
;
line-height
:
1
;
}
&
.alkaline
{
width
:
72
rpx
;
height
:
30
rpx
;
border-radius
:
26
rpx
;
border
:
2
rpx
solid
#0E692E
;
background
:
#4C9F6A
;
}
&
.neutral
{
width
:
56
rpx
;
height
:
30
rpx
;
border-radius
:
26
rpx
;
border
:
2
rpx
solid
#748A08
;
background
:
#B2C849
;
}
}
}
.ph-warning-icon
,
.ph-success-icon
{
width
:
36
rpx
;
height
:
36
rpx
;
}
.ph-success-icon
{
width
:
32
rpx
;
height
:
32
rpx
;
}
.ph-arrow
{
color
:
#457AAB
;
font-weight
:
bold
;
font-size
:
32
rpx
;
margin
:
0
10
rpx
;
}
}
.ph-chart-container
{
width
:
100%
;
margin
:
10
rpx
0
;
display
:
flex
;
justify-content
:
center
;
.ph-chart-img
{
width
:
95%
;
}
}
.ph-footer-row
{
width
:
100%
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
padding
:
0
10
rpx
;
.ph-footer-label
{
font-size
:
30
rpx
;
color
:
#25334D
;
font-weight
:
600
;
.highlight
{
color
:
#B2C849
;
}
}
.ph-badge
{
background
:
#B2C849
;
color
:
#fff
;
font-size
:
24
rpx
;
padding
:
6
rpx
16
rpx
;
border-radius
:
36
rpx
;
font-weight
:
600
;
border
:
2
rpx
solid
#748A08
;
}
}
&
.neutral
{
width
:
56
rpx
;
height
:
30
rpx
;
border-radius
:
26
rpx
;
border
:
2
rpx
solid
#748A08
;
background
:
#B2C849
;
}
}
}
}
}
.result-boxes
{
width
:
100%
;
display
:
flex
;
justify-content
:
center
;
gap
:
32
rpx
;
.result-box
{
flex
:
1
;
height
:
140
rpx
;
border-radius
:
24
rpx
;
border
:
2
rpx
solid
#FFF
;
background
:
linear-gradient
(
180deg
,
#FAFBFD
0%
,
#DCEEFD
100%
);
box-sizing
:
border-box
;
.ph-warning-icon
,
.ph-success-icon
{
width
:
36
rpx
;
height
:
36
rpx
;
}
.ph-success-icon
{
width
:
32
rpx
;
height
:
32
rpx
;
}
.ph-arrow
{
color
:
#457AAB
;
font-weight
:
bold
;
font-size
:
32
rpx
;
margin
:
0
10
rpx
;
}
}
.ph-chart-container
{
width
:
100%
;
margin
:
10
rpx
0
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
center
;
align-items
:
flex-start
;
padding-left
:
32
rpx
;
gap
:
10
rpx
;
position
:
relative
;
.box-title,
.box-value
{
font-size
:
32
rpx
;
color
:
#25334D
;
line-height
:
1.2
;
.ph-chart-img
{
width
:
95%
;
}
}
.status-icon
{
position
:
absolute
;
right
:
20
rpx
;
top
:
53%
;
transform
:
translateY
(
-50%
);
width
:
92
rpx
;
height
:
92
rpx
;
.ph-footer-row
{
width
:
100%
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
padding
:
0
10
rpx
;
.ph-footer-label
{
font-size
:
30
rpx
;
color
:
#25334D
;
font-weight
:
600
;
.highlight
{
color
:
#8CC24A
;
}
}
.ph-badge
{
background
:
#8CC24A
;
color
:
#fff
;
font-size
:
24
rpx
;
padding
:
6
rpx
16
rpx
;
border-radius
:
20
rpx
;
font-weight
:
600
;
border
:
2
rpx
solid
#6B9C35
;
}
}
}
}
}
}
.result-boxes
{
width
:
100%
;
display
:
flex
;
justify-content
:
center
;
gap
:
32
rpx
;
.result-box
{
flex
:
1
;
height
:
140
rpx
;
border-radius
:
24
rpx
;
border
:
2
rpx
solid
#FFF
;
background
:
linear-gradient
(
180deg
,
#FAFBFD
0%
,
#DCEEFD
100%
);
box-sizing
:
border-box
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
center
;
align-items
:
flex-start
;
padding-left
:
32
rpx
;
gap
:
10
rpx
;
position
:
relative
;
.box-title,
.box-value
{
font-size
:
32
rpx
;
color
:
#25334D
;
line-height
:
1.2
;
}
.status-icon
{
position
:
absolute
;
right
:
20
rpx
;
top
:
53%
;
transform
:
translateY
(
-50%
);
width
:
92
rpx
;
height
:
92
rpx
;
}
}
}
}
.tips-card
{
width
:
120%
;
max-width
:
710
rpx
;
height
:
116
rpx
;
background
:
#BEDCF3
;
border-radius
:
24
rpx
;
border
:
4
rpx
solid
#457AAB
;
padding
:
20
rpx
;
position
:
relative
;
width
:
120%
;
max-width
:
710
rpx
;
height
:
116
rpx
;
background
:
#BEDCF3
;
border-radius
:
24
rpx
;
border
:
4
rpx
solid
#457AAB
;
padding
:
20
rpx
;
position
:
relative
;
box-sizing
:
border-box
;
margin-top
:
2vh
;
flex-shrink
:
0
;
.tips-header
{
position
:
absolute
;
top
:
-24
rpx
;
left
:
0
;
width
:
220
rpx
;
height
:
58
rpx
;
background
:
linear-gradient
(
180deg
,
#52A5D7
0%
,
#3E83CE
100%
);
border-radius
:
48
rpx
;
border
:
4
rpx
solid
#1B5CA3
;
box-shadow
:
0
0
8
rpx
0
#FFF
inset
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
box-sizing
:
border-box
;
margin-top
:
2vh
;
flex-shrink
:
0
;
.tips-header
{
position
:
absolute
;
top
:
-24
rpx
;
left
:
0
;
width
:
220
rpx
;
height
:
58
rpx
;
background
:
linear-gradient
(
180deg
,
#52A5D7
0%
,
#3E83CE
100%
);
border-radius
:
48
rpx
;
border
:
4
rpx
solid
#1B5CA3
;
box-shadow
:
0
0
8
rpx
0
#FFF
inset
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
box-sizing
:
border-box
;
z-index
:
10
;
.bulb-icon
{
position
:
absolute
;
left
:
-25
rpx
;
bottom
:
-10
rpx
;
width
:
80
rpx
;
height
:
80
rpx
;
z-index
:
12
;
}
.tips-title
{
color
:
#fff
;
font-size
:
32
rpx
;
font-weight
:
600
;
margin-left
:
28
rpx
;
}
z-index
:
10
;
.bulb-icon
{
position
:
absolute
;
left
:
-25
rpx
;
bottom
:
-10
rpx
;
width
:
80
rpx
;
height
:
80
rpx
;
z-index
:
12
;
}
.tips-body
{
position
:
absolute
;
top
:
10
rpx
;
left
:
13
rpx
;
font-size
:
30
rpx
;
color
:
#25334D
;
padding
:
20
rpx
16
rpx
10
rpx
46
rpx
;
border-radius
:
24
rpx
;
background
:
linear-gradient
(
180deg
,
#FFF
0%
,
#D9EBF7
100%
);
width
:
96%
;
height
:
80%
;
box-sizing
:
border-box
;
z-index
:
5
;
display
:
flex
;
align-items
:
center
;
font-weight
:
600
;
.tips-title
{
color
:
#fff
;
font-size
:
32
rpx
;
font-weight
:
600
;
margin-left
:
28
rpx
;
}
}
.tips-body
{
position
:
absolute
;
top
:
10
rpx
;
left
:
13
rpx
;
font-size
:
30
rpx
;
color
:
#25334D
;
padding
:
20
rpx
16
rpx
10
rpx
46
rpx
;
border-radius
:
24
rpx
;
background
:
linear-gradient
(
180deg
,
#FFF
0%
,
#D9EBF7
100%
);
width
:
96%
;
height
:
80%
;
box-sizing
:
border-box
;
z-index
:
5
;
display
:
flex
;
align-items
:
center
;
font-weight
:
600
;
}
}
</
style
>
</
style
>
\ No newline at end of file
src/pages/third/components/beaker.vue
View file @
ea5bbe9a
<
template
>
<view
class=
"main-content"
>
<view
class=
"beaker-section"
>
<view
class=
"beaker-item polluted-beaker"
:class=
"
{ 'no-transform': isSecondTest }">
<view
class=
"beaker-img-wrapper"
>
<image
class=
"beaker-img"
:class=
"
{ 'img-hidden': isTesting }"
:src="pollutedImageDefault"
mode="aspectFit">
</image>
<image
class=
"beaker-img beaker-img-overlay"
:class=
"
{ 'img-visible': isTesting }"
:src="pollutedImageTesting"
mode="aspectFit">
</image>
</view>
<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"
>
<view
class=
"beaker-img-wrapper"
>
<image
class=
"beaker-img"
:class=
"
{ 'img-hidden': isTesting }"
:src="purifiedImageDefault"
mode="aspectFit">
</image>
<image
class=
"beaker-img beaker-img-overlay"
:class=
"
{ 'img-visible': isTesting }"
:src="purifiedImageTesting"
mode="aspectFit">
</image>
</view>
<view
class=
"beaker-label purified"
>
净化水
</view>
</view>
<view
class=
"main-content"
>
<view
class=
"beaker-section"
>
<view
class=
"beaker-item polluted-beaker"
:class=
"
{ 'no-transform': isSecondTest }">
<view
class=
"beaker-img-wrapper"
>
<image
class=
"beaker-img"
:class=
"
{ 'img-hidden': isTesting }"
:src="IMAGES.pollutedDefault"
mode="aspectFit"
/>
<image
class=
"beaker-img beaker-img-overlay"
:class=
"
{ 'img-visible': isTesting }"
:src="pollutedImageTesting"
mode="aspectFit"
/>
</view>
<view
class=
"beaker-label polluted"
>
污染水
</view>
</view>
<image
class=
"vs-icon"
:src=
"IMAGES.vsIcon"
mode=
"widthFix"
/>
<view
class=
"beaker-item"
>
<view
class=
"beaker-img-wrapper"
>
<image
class=
"beaker-img"
:class=
"
{ 'img-hidden': isTesting }"
:src="IMAGES.purifiedDefault"
mode="aspectFit"
/>
<image
class=
"beaker-img beaker-img-overlay"
:class=
"
{ 'img-visible': isTesting }"
:src="purifiedImageTesting"
mode="aspectFit"
/>
</view>
<view
class=
"beaker-label purified"
>
净化水
</view>
</view>
</view>
</view>
</
template
>
<
script
setup
>
import
{
computed
}
from
'vue'
;
const
props
=
defineProps
({
isTesting
:
{
type
:
Boolean
,
default
:
false
},
isSecondTest
:
{
type
:
Boolean
,
default
:
false
}
isTesting
:
{
type
:
Boolean
,
default
:
false
,
},
isSecondTest
:
{
type
:
Boolean
,
default
:
false
,
},
});
const
pollutedImageDefault
=
'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'
;
const
purifiedImageDefault
=
'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'
;
//烧杯图片
const
IMAGES
=
{
pollutedDefault
:
'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'
,
purifiedDefault
:
'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'
,
vsIcon
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/8678ceab4c7b41ac80cc1982054c45f4VS.webp'
,
pollutedPh
:
'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'
,
pollutedTds
:
'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'
,
purifiedPh
:
'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'
,
purifiedTds
:
'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'
,
};
const
pollutedImageTesting
=
computed
(()
=>
{
return
props
.
isSecondTest
?
'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/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'
;
return
props
.
isSecondTest
?
IMAGES
.
pollutedPh
:
IMAGES
.
pollutedTds
;
});
const
purifiedImageTesting
=
computed
(()
=>
{
return
props
.
isSecondTest
?
'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'
:
'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'
;
return
props
.
isSecondTest
?
IMAGES
.
purifiedPh
:
IMAGES
.
purifiedTds
;
});
</
script
>
<
style
scoped
lang=
"scss"
>
.main-content
{
flex
:
1
;
padding
:
0
40
rpx
;
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
overflow
:
hidden
;
justify-content
:
center
;
flex
:
1
;
padding
:
0
40
rpx
;
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
overflow
:
hidden
;
justify-content
:
center
;
}
.beaker-section
{
width
:
100%
;
width
:
100%
;
display
:
flex
;
justify-content
:
center
;
align-items
:
flex-end
;
position
:
relative
;
flex-shrink
:
1
;
.beaker-item
{
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-wrapper
{
width
:
364
rpx
;
height
:
541
rpx
;
position
:
relative
;
}
.beaker-img
{
width
:
364
rpx
;
height
:
541
rpx
;
position
:
absolute
;
bottom
:
0
;
left
:
0
;
opacity
:
1
;
transition
:
opacity
0.15s
ease-in-out
;
&.img-hidden
{
opacity
:
0
;
}
}
.beaker-img-overlay
{
opacity
:
0
;
&.img-visible
{
opacity
:
1
;
}
}
&
.polluted-beaker
:not
(
.no-transform
)
.beaker-img-overlay
{
transform
:
scale
(
1.03
)
translateY
(
25
rpx
);
transform-origin
:
center
bottom
;
}
.beaker-label
{
padding
:
8
rpx
32
rpx
;
border-radius
:
48
rpx
;
color
:
#fff
;
font-size
:
34
rpx
;
position
:
relative
;
top
:
-60
rpx
;
z-index
:
1
;
&.polluted
{
background
:
linear-gradient
(
180deg
,
#B79669
0%
,
#8C6B46
100%
);
border
:
4
rpx
solid
#503F34
;
}
&
.purified
{
background
:
linear-gradient
(
180deg
,
#4CAAE4
0%
,
#3F80D2
100%
);
border
:
4
rpx
solid
#3060AD
;
}
}
flex-direction
:
column
;
align-items
:
center
;
.beaker-img-wrapper
{
width
:
364
rpx
;
height
:
541
rpx
;
position
:
relative
;
}
.beaker-img
{
width
:
364
rpx
;
height
:
541
rpx
;
position
:
absolute
;
bottom
:
0
;
left
:
0
;
opacity
:
1
;
transition
:
opacity
0.15s
ease-in-out
;
&.img-hidden
{
opacity
:
0
;
}
}
.beaker-img-overlay
{
opacity
:
0
;
&.img-visible
{
opacity
:
1
;
}
}
&
.polluted-beaker
:not
(
.no-transform
)
.beaker-img-overlay
{
transform
:
scale
(
1.03
)
translateY
(
25
rpx
);
transform-origin
:
center
bottom
;
}
.vs-icon
{
width
:
108
rpx
;
position
:
absolute
;
left
:
50%
;
top
:
50%
;
transform
:
translate
(
-50%
,
-50%
);
z-index
:
99
;
.beaker-label
{
padding
:
8
rpx
32
rpx
;
border-radius
:
48
rpx
;
color
:
#fff
;
font-size
:
34
rpx
;
position
:
relative
;
top
:
-60
rpx
;
z-index
:
1
;
&.polluted
{
background
:
linear-gradient
(
180deg
,
#b79669
0%
,
#8c6b46
100%
);
border
:
4
rpx
solid
#503f34
;
}
&
.purified
{
background
:
linear-gradient
(
180deg
,
#4caae4
0%
,
#3f80d2
100%
);
border
:
4
rpx
solid
#3060ad
;
}
}
}
.vs-icon
{
width
:
108
rpx
;
position
:
absolute
;
left
:
50%
;
top
:
50%
;
transform
:
translate
(
-50%
,
-50%
);
z-index
:
99
;
}
}
</
style
>
</
style
>
\ No newline at end of file
src/pages/third/index.vue
View file @
ea5bbe9a
<
template
>
<view
class=
"container"
>
<image
class=
"bg"
src=
"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"
mode=
"aspectFill"
></image>
<view
class=
"header"
:style=
"
{ paddingTop: statusBarHeight + 'px' }">
<image
class=
"title"
src=
"https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/e9ddd6b498fe452b9254e86c04596df3Group%20348447251.webp"
mode=
"heightFix"
></image>
</view>
<Beaker
:isTesting=
"isTesting"
:isSecondTest=
"isSecondTest"
/>
<view
class=
"bottom-panel"
>
<TabsInstructionsPanel
:isTesting=
"isTesting"
:isSecondTest=
"isSecondTest"
:triggerShowFinalCard=
"triggerShowFinalCard"
@
resultShown=
"handleResultShown"
@
progressFinished=
"handleProgressFinished"
/>
<BottomActionBar
:isTesting=
"isTesting"
:isSecondTest=
"isSecondTest"
:isResultShown=
"isResultShown"
:isProgressFinished=
"isProgressFinished"
@
startTest=
"startTest"
@
restartTest=
"restartTest"
@
showFinalCard=
"handleShowFinalCard"
@
showCompletionPopup=
"handleShowCompletion"
/>
</view>
<view
class=
"completion-overlay"
v-if=
"showCompletion"
@
click=
"closeCompletion"
>
<image
class=
"completion-img"
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"
@
click
.
stop=
"closeCompletion"
></image>
</view>
</view>
<view
class=
"container"
>
<image
class=
"bg"
:src=
"assets.bg"
mode=
"aspectFill"
/>
<view
class=
"header"
:style=
"
{ paddingTop: statusBarHeight + 'px' }">
<image
class=
"title"
:src=
"assets.title"
mode=
"heightFix"
/>
</view>
<Beaker
:isTesting=
"isTesting"
:isSecondTest=
"isSecondTest"
/>
<view
class=
"bottom-panel"
>
<TabsInstructionsPanel
:isTesting=
"isTesting"
:isSecondTest=
"isSecondTest"
:triggerShowFinalCard=
"triggerShowFinalCard"
@
resultShown=
"handleResultShown"
@
progressFinished=
"handleProgressFinished"
/>
<BottomActionBar
:isTesting=
"isTesting"
:isSecondTest=
"isSecondTest"
:isResultShown=
"isResultShown"
:isProgressFinished=
"isProgressFinished"
@
startTest=
"startTest"
@
restartTest=
"restartTest"
@
showFinalCard=
"handleShowFinalCard"
@
showCompletionPopup=
"handleShowCompletion"
/>
</view>
<view
class=
"completion-overlay"
v-if=
"showCompletion"
@
click=
"closeCompletion"
>
<image
class=
"completion-img"
:src=
"assets.completionPopup"
mode=
"scaleToFill"
@
click
.
stop=
"closeCompletion"
/>
</view>
</view>
</
template
>
<
script
setup
>
...
...
@@ -28,6 +47,12 @@ import Beaker from './components/beaker.vue';
import
TabsInstructionsPanel
from
'./components/TabsInstructionsPanel.vue'
;
import
BottomActionBar
from
'./components/BottomActionBar.vue'
;
const
assets
=
{
bg
:
'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'
,
title
:
'https://userone-oss-cdn.angelgroup.com.cn/static/2026-01-23/e9ddd6b498fe452b9254e86c04596df3Group%20348447251.webp'
,
completionPopup
:
'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'
};
const
statusBarHeight
=
ref
(
20
);
const
isTesting
=
ref
(
false
);
const
isSecondTest
=
ref
(
false
);
...
...
@@ -37,154 +62,116 @@ const triggerShowFinalCard = ref(false);
const
showCompletion
=
ref
(
false
);
onLoad
(()
=>
{
const
systemInfo
=
uni
.
getSystemInfoSync
();
statusBarHeight
.
value
=
systemInfo
.
statusBarHeight
||
20
;
const
systemInfo
=
uni
.
getSystemInfoSync
();
statusBarHeight
.
value
=
systemInfo
.
statusBarHeight
||
20
;
});
const
goBack
=
()
=>
{
uni
.
navigateBack
({
fail
:
()
=>
{
uni
.
reLaunch
({
url
:
'/pages/index/index'
});
}
});
};
const
startTest
=
()
=>
{
console
.
log
(
'Start detection'
);
isTesting
.
value
=
true
;
isProgressFinished
.
value
=
false
;
triggerShowFinalCard
.
value
=
false
;
console
.
log
(
'Start detection'
);
isTesting
.
value
=
true
;
isProgressFinished
.
value
=
false
;
triggerShowFinalCard
.
value
=
false
;
};
const
handleResultShown
=
()
=>
{
isResultShown
.
value
=
true
;
isResultShown
.
value
=
true
;
};
const
handleProgressFinished
=
()
=>
{
isProgressFinished
.
value
=
true
;
isProgressFinished
.
value
=
true
;
};
const
handleShowFinalCard
=
()
=>
{
triggerShowFinalCard
.
value
=
true
;
triggerShowFinalCard
.
value
=
true
;
};
const
restartTest
=
()
=>
{
console
.
log
(
'Restart detection'
);
isTesting
.
value
=
false
;
isResultShown
.
value
=
false
;
isProgressFinished
.
value
=
false
;
triggerShowFinalCard
.
value
=
false
;
isSecondTest
.
value
=
true
;
console
.
log
(
'Restart detection'
);
isTesting
.
value
=
false
;
isResultShown
.
value
=
false
;
isProgressFinished
.
value
=
false
;
triggerShowFinalCard
.
value
=
false
;
isSecondTest
.
value
=
true
;
};
const
handleShowCompletion
=
()
=>
{
showCompletion
.
value
=
true
;
showCompletion
.
value
=
true
;
};
const
closeCompletion
=
()
=>
{
showCompletion
.
value
=
false
;
showCompletion
.
value
=
false
;
};
</
script
>
<
style
lang=
"scss"
scoped
>
.container
{
width
:
100vw
;
height
:
100vh
;
position
:
relative
;
display
:
flex
;
flex-direction
:
column
;
color
:
#333
;
overflow
:
hidden
;
box-sizing
:
border-box
;
}
.bg
{
position
:
absolute
;
top
:
0
;
left
:
0
;
width
:
100%
;
height
:
100%
;
z-index
:
-1
;
object-fit
:
cover
;
}
.header
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
padding-bottom
:
2vh
;
flex-shrink
:
0
;
.nav-bar
{
width
:
100%
;
height
:
44px
;
display
:
flex
;
align-items
:
center
;
padding
:
0
20
rpx
;
box-sizing
:
border-box
;
.back-btn
{
display
:
flex
;
align-items
:
center
;
background
:
rgba
(
255
,
255
,
255
,
0.6
);
padding
:
8
rpx
16
rpx
;
border-radius
:
30
rpx
;
.back-arrow
{
font-size
:
32
rpx
;
margin-right
:
6
rpx
;
line-height
:
1
;
}
.back-text
{
font-size
:
24
rpx
;
font-weight
:
500
;
}
}
}
.title
{
height
:
120
rpx
;
width
:
54
rpx
;
}
}
.completion-overlay
{
position
:
fixed
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
z-index
:
9999
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
.completion-img
{
width
:
100%
;
height
:
100%
;
}
}
.bottom-panel
{
width
:
100%
;
height
:
48vh
;
flex-shrink
:
0
;
border-radius
:
24
rpx
24
rpx
0
0
;
border-top
:
4
rpx
solid
#728FAF
;
background
:
linear-gradient
(
180deg
,
#E0EBF6
0%
,
#C3D3E4
100%
);
box-shadow
:
0
10
rpx
0
0
#FFF
inset
;
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
padding-top
:
3vh
;
box-sizing
:
border-box
;
position
:
absolute
;
bottom
:
0
;
left
:
0
;
z-index
:
10
;
padding-bottom
:
env
(
safe-area-inset-bottom
);
}
</
style
>
.container
{
width
:
100vw
;
height
:
100vh
;
position
:
relative
;
display
:
flex
;
flex-direction
:
column
;
color
:
#333
;
overflow
:
hidden
;
box-sizing
:
border-box
;
}
.bg
{
position
:
absolute
;
top
:
0
;
left
:
0
;
width
:
100%
;
height
:
100%
;
z-index
:
-1
;
object-fit
:
cover
;
}
.header
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
padding-bottom
:
2vh
;
flex-shrink
:
0
;
.title
{
height
:
120
rpx
;
width
:
54
rpx
;
}
}
.completion-overlay
{
position
:
fixed
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
z-index
:
9999
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
.completion-img
{
width
:
100%
;
height
:
100%
;
}
}
.bottom-panel
{
width
:
100%
;
height
:
48vh
;
flex-shrink
:
0
;
border-radius
:
24
rpx
24
rpx
0
0
;
border-top
:
4
rpx
solid
#728FAF
;
background
:
linear-gradient
(
180deg
,
#E0EBF6
0%
,
#C3D3E4
100%
);
box-shadow
:
0
10
rpx
0
0
#FFF
inset
;
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
padding-top
:
3vh
;
box-sizing
:
border-box
;
position
:
absolute
;
bottom
:
0
;
left
:
0
;
z-index
:
10
;
padding-bottom
:
env
(
safe-area-inset-bottom
);
}
</
style
>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment