Commit 7e51f76f by Hantao

feat(second): 添加拼图状态持久化与步骤进度显示

- 新增四个步骤信息图片,替换原有的单一图片
- 在 second/index 页面根据存储的步骤进度显示对应信息图片
- 为拼图游戏添加本地存储功能,保存拼图块状态
- 拼图完成后自动跳转并记录完成状态,避免重复完成
- 添加 pinia 依赖用于后续状态管理
parent c762df6f
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
"@dcloudio/uni-quickapp-webview": "3.0.0-3090620231104001", "@dcloudio/uni-quickapp-webview": "3.0.0-3090620231104001",
"clipboard": "^2.0.11", "clipboard": "^2.0.11",
"dayjs": "^1.11.19", "dayjs": "^1.11.19",
"pinia": "^3.0.4",
"uview-plus": "^3.7.0", "uview-plus": "^3.7.0",
"vue": "^3.2.45", "vue": "^3.2.45",
"vue-i18n": "^9.1.9" "vue-i18n": "^9.1.9"
......
<script setup> <script setup>
import navBar from '@/components/navBar.vue'; import navBar from '@/components/navBar.vue';
import { ref } from 'vue';
import { onShow } from '@dcloudio/uni-app';
const ASSETS = Object.freeze({ const ASSETS = Object.freeze({
bg: '/static/second/bg.webp', bg: '/static/second/bg.webp',
info: '/static/second/info.webp', info1: '/static/second/info1.webp',
info2: '/static/second/info2.webp',
info3: '/static/second/info3.webp',
info4: '/static/second/info4.webp',
title: '/static/second/title.webp', title: '/static/second/title.webp',
jdt: '/static/second/jdt.webp', jdt: '/static/second/jdt.webp',
next: '/static/second/next.webp', next: '/static/second/next.webp',
}); });
const INFO_MAP = [ASSETS.info1, ASSETS.info2, ASSETS.info3, ASSETS.info4];
const currentInfo = ref(ASSETS.info1);
onShow(() => {
const step = uni.getStorageSync('second_part1_completed') || 0;
currentInfo.value = INFO_MAP[step] || ASSETS.info1;
});
const handleNext = () => { const handleNext = () => {
uni.navigateTo({ uni.navigateTo({
url: '/pages/second/part1' url: '/pages/second/part1'
...@@ -31,7 +45,7 @@ const handleNext = () => { ...@@ -31,7 +45,7 @@ const handleNext = () => {
<!-- 右侧信息区域 --> <!-- 右侧信息区域 -->
<view class="info-area"> <view class="info-area">
<image class="info-img" :src="ASSETS.info" mode="scaleToFill" /> <image class="info-img" :src="currentInfo" mode="scaleToFill" />
</view> </view>
<!-- 底部区域 --> <!-- 底部区域 -->
...@@ -174,4 +188,4 @@ const handleNext = () => { ...@@ -174,4 +188,4 @@ const handleNext = () => {
} }
} }
} }
</style> </style>
\ No newline at end of file
...@@ -77,14 +77,24 @@ const PUZZLE_DIMENSIONS = { ...@@ -77,14 +77,24 @@ const PUZZLE_DIMENSIONS = {
} }
}; };
const trayItems = ref([ const STORAGE_KEY = 'second_part1_puzzle_status';
{ id: 1, type: 'puzzle1', status: 'default' },
{ id: 2, type: 'puzzle2', status: 'default' }, const getInitialItems = () => {
{ id: 3, type: 'puzzle3', status: 'default' }, const savedStatus = uni.getStorageSync(STORAGE_KEY);
{ id: 4, type: 'puzzle4', status: 'default' }, if (savedStatus) {
{ id: 5, type: 'puzzle5', status: 'default' }, return savedStatus;
{ id: 6, type: 'puzzle6', status: 'default' }, }
]); return [
{ id: 1, type: 'puzzle1', status: 'default' },
{ id: 2, type: 'puzzle2', status: 'default' },
{ id: 3, type: 'puzzle3', status: 'default' },
{ id: 4, type: 'puzzle4', status: 'default' },
{ id: 5, type: 'puzzle5', status: 'default' },
{ id: 6, type: 'puzzle6', status: 'default' },
];
};
const trayItems = ref(getInitialItems());
const placedCount = computed(() => { const placedCount = computed(() => {
return trayItems.value.filter(item => item.status === 'placed').length; return trayItems.value.filter(item => item.status === 'placed').length;
...@@ -124,16 +134,26 @@ const currentProgressImgStyle = computed(() => { ...@@ -124,16 +134,26 @@ const currentProgressImgStyle = computed(() => {
}); });
const showCompletion = ref(false); const showCompletion = ref(false);
const hasCompletedBefore = ref(!!uni.getStorageSync('second_part1_completed'));
const handleReset = () => { const handleReset = () => {
trayItems.value.forEach(item => { trayItems.value.forEach(item => {
item.status = 'default'; item.status = 'default';
}); });
uni.removeStorageSync(STORAGE_KEY);
}; };
const handleComplete = () => { const handleComplete = () => {
if (isComplete.value) { if (isComplete.value) {
showCompletion.value = true; if (hasCompletedBefore.value) {
uni.redirectTo({
url: '/pages/second/index'
});
} else {
hasCompletedBefore.value = true;
uni.setStorageSync('second_part1_completed', 1);
showCompletion.value = true;
}
} }
}; };
...@@ -175,6 +195,7 @@ const { ...@@ -175,6 +195,7 @@ const {
// 简单的碰撞检测 // 简单的碰撞检测
if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) { if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
item.status = 'placed'; item.status = 'placed';
uni.setStorageSync(STORAGE_KEY, trayItems.value);
} }
} }
} }
...@@ -231,7 +252,7 @@ const getCenterItemStyle = (index) => { ...@@ -231,7 +252,7 @@ const getCenterItemStyle = (index) => {
class="drag-ghost" class="drag-ghost"
:style="{ left: dragPosition.x + 'px', top: dragPosition.y + 'px' }" :style="{ left: dragPosition.x + 'px', top: dragPosition.y + 'px' }"
> >
<image :src="getGhostIcon()" :style="getGhostStyle()" mode="scaleToFill" class="ghost-icon" /> <image :src="getGhostIcon()" :style="getGhostStyle()" mode="scaleToFill"/>
</view> </view>
<!-- 顶部标题 --> <!-- 顶部标题 -->
...@@ -386,11 +407,6 @@ const getCenterItemStyle = (index) => { ...@@ -386,11 +407,6 @@ const getCenterItemStyle = (index) => {
z-index: 9999; z-index: 9999;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
pointer-events: none; pointer-events: none;
.ghost-icon {
/* width: 200rpx; removed fixed size */
/* height: auto; */
}
} }
.puzzle-zones { .puzzle-zones {
...@@ -552,4 +568,4 @@ const getCenterItemStyle = (index) => { ...@@ -552,4 +568,4 @@ const getCenterItemStyle = (index) => {
height: 100%; height: 100%;
} }
} }
</style> </style>
\ No newline at end of file
...@@ -92,6 +92,11 @@ const handleStart = () => { ...@@ -92,6 +92,11 @@ const handleStart = () => {
url: '/pages/first/index' url: '/pages/first/index'
}); });
} }
if (progressImgs.value === 1 && badgeImgs.value === 1) {
uni.navigateTo({
url: '/pages/second/index'
});
}
}; };
const handleRestart = () => { const handleRestart = () => {
......
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