fix: 修复 VoiceController Map.of 兼容性 + ExploreController 参数不匹配

- VoiceController: Map.of() -> Collections.singletonMap() 兼容 Java 8
- ExploreController: 补齐 takeoutService.roll() 缺失的 taste/priceRange/allergies 参数

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
王鹏
2026-05-08 20:02:27 +08:00
commit 802b4ba229
98 changed files with 5761 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
const app = getApp();
const api = require('../../utils/api');
const loc = require('../../utils/location');
Page({
data: {
showAnimation: false,
dataReady: false,
result: null,
error: '',
distanceText: ''
},
onLoad() {
this.roll();
},
roll() {
this.setData({
showAnimation: true,
dataReady: false,
error: '',
result: null
});
loc.getLocation().then((pos) => {
return api.post('/api/explore/roll', {
latitude: pos.latitude,
longitude: pos.longitude,
openid: 'anonymous'
});
}).then((data) => {
this.setData({
result: data,
distanceText: ((data.distance || 0) / 1000).toFixed(1) + 'km',
dataReady: true
});
this.saveRecord(data);
}).catch((err) => {
this.setData({
showAnimation: false,
error: err.message || '附近暂无推荐好店,换片区域试试?'
});
});
},
onAnimationDone() {
this.setData({ showAnimation: false });
},
navigate() {
const shop = this.data.result;
if (!shop) return;
wx.openLocation({
latitude: shop.latitude || app.globalData.location.latitude,
longitude: shop.longitude || app.globalData.location.longitude,
name: shop.name,
address: shop.address,
scale: 16
});
},
retry() {
this.roll();
},
saveRecord(data) {
const history = wx.getStorageSync('box_history') || [];
history.push({
id: Date.now().toString(),
icon: '🍱',
name: data.name,
time: new Date().toLocaleString(),
typeName: '探店盲盒'
});
wx.setStorageSync('box_history', history);
}
});

View File

@@ -0,0 +1,7 @@
{
"usingComponents": {
"result-card": "/components/result-card/result-card",
"box-animation": "/components/box-animation/box-animation"
},
"navigationBarTitleText": "探店盲盒"
}

View File

@@ -0,0 +1,37 @@
<view class="explore-page">
<view class="empty" wx:if="{{error}}">
<view class="empty-icon">😿</view>
<view>{{error}}</view>
<button class="btn-primary" style="margin-top:32rpx" bind:tap="retry">换片区域试试</button>
</view>
<view class="result-area" wx:if="{{!showAnimation && result}}">
<view class="result-title">🎊 附近发现一家宝藏店</view>
<result-card
imageUrl="{{result.imageUrl}}"
name="{{result.name}}"
rating="{{result.rating}}"
avgPrice="{{result.avgPrice}}"
distance="{{distanceText}}"
recommendReason="{{result.recommendReason}}"
signatureDishes="{{result.signatureDishes}}"
/>
<view class="actions">
<button class="btn-primary btn-main" bind:tap="navigate">导航过去</button>
<view class="btn-retry" bind:tap="retry">再开一个</view>
</view>
</view>
<box-animation
show="{{showAnimation}}"
boxType="explore"
dataReady="{{dataReady}}"
bind:done="onAnimationDone"
>
<view class="animation-result-preview" wx:if="{{result}}">
<view class="preview-emoji">🍜</view>
<view class="preview-text">{{result.name}}</view>
<view class="preview-sub" wx:if="{{result.rating}}">⭐ {{result.rating}}</view>
</view>
</box-animation>
</view>

View File

@@ -0,0 +1,92 @@
/*
* 探店结果页
*/
.explore-page {
padding: var(--space-md);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
}
.result-area {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.result-title {
font-size: var(--text-subtitle);
font-weight: 600;
color: var(--color-text);
margin: var(--space-md) 0 var(--space-md);
text-align: center;
}
.actions {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
margin-top: var(--space-lg);
}
.btn-main {
width: 80%;
}
.btn-retry {
margin-top: var(--space-md);
font-size: var(--text-body-sm);
color: var(--color-text-muted);
padding: var(--space-sm);
}
.btn-retry:active {
color: var(--color-purple);
}
/* ── 错误 ── */
.empty {
display: flex;
flex-direction: column;
align-items: center;
padding-top: 200rpx;
text-align: center;
font-size: var(--text-body);
color: var(--color-text-secondary);
}
.empty-icon {
font-size: 80rpx;
margin-bottom: var(--space-md);
opacity: 0.6;
}
/* ── 动效预览 ── */
.animation-result-preview {
display: flex;
flex-direction: column;
align-items: center;
padding: 24rpx;
}
.preview-emoji {
font-size: 64rpx;
margin-bottom: 12rpx;
}
.preview-text {
font-size: var(--text-subtitle);
font-weight: 700;
color: #FFFFFF;
text-align: center;
}
.preview-sub {
font-size: var(--text-body-sm);
color: rgba(255, 255, 255, 0.8);
margin-top: 8rpx;
}