Commit 7e51f76f by Hantao

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

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