Compare commits
2 Commits
1c62867cd2
...
5c863de337
| Author | SHA1 | Date | |
|---|---|---|---|
| 5c863de337 | |||
| 83001cfda9 |
@ -184,20 +184,6 @@
|
||||
<text class="label">算法版本</text>
|
||||
<text class="value mono">{{ receipt.algo_version }}</text>
|
||||
</view>
|
||||
<view class="info-row" v-if="receipt.server_seed_hash">
|
||||
<text class="label">服务端种子哈希</text>
|
||||
<view class="value-wrap">
|
||||
<text class="value mono seed-text">{{ receipt.server_seed_hash }}</text>
|
||||
<view class="copy-btn" @tap="copyText(receipt.server_seed_hash)">复制</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="info-row" v-if="receipt.server_sub_seed">
|
||||
<text class="label">子种子</text>
|
||||
<view class="value-wrap">
|
||||
<text class="value mono seed-text">{{ receipt.server_sub_seed }}</text>
|
||||
<view class="copy-btn" @tap="copyText(receipt.server_sub_seed)">复制</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="info-row" v-if="receipt.client_seed">
|
||||
<text class="label">客户端种子</text>
|
||||
<text class="value mono">{{ receipt.client_seed }}</text>
|
||||
@ -219,6 +205,11 @@
|
||||
<text class="notice-icon">🔒</text>
|
||||
<text class="notice-text">以上数据可用于验证抽奖结果的公正性</text>
|
||||
</view>
|
||||
<!-- 复制验证凭据JSON按钮 -->
|
||||
<view class="export-receipt-btn" @tap="exportReceipt">
|
||||
<text class="btn-icon">📋</text>
|
||||
<text class="btn-text">复制验证凭据</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -445,6 +436,92 @@ function showProofHelp() {
|
||||
showCancel: false
|
||||
})
|
||||
}
|
||||
|
||||
// 导出验证凭据JSON
|
||||
function exportReceipt() {
|
||||
if (!order.value || !order.value.draw_receipts || order.value.draw_receipts.length === 0) {
|
||||
uni.showToast({ title: '无抽奖凭据', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
// 构建验证凭据JSON
|
||||
const receipts = order.value.draw_receipts.map((r, idx) => {
|
||||
// 解析items_snapshot
|
||||
let weightsStr = ''
|
||||
let rewardsStr = ''
|
||||
let salt = ''
|
||||
let randValue = 0
|
||||
|
||||
if (r.items_snapshot) {
|
||||
try {
|
||||
const snapshot = typeof r.items_snapshot === 'string'
|
||||
? JSON.parse(r.items_snapshot)
|
||||
: r.items_snapshot
|
||||
|
||||
// 从snapshot中提取salt和rand(后端存储的实际值)
|
||||
if (snapshot.salt) {
|
||||
salt = snapshot.salt
|
||||
}
|
||||
if (snapshot.rand !== undefined) {
|
||||
randValue = snapshot.rand
|
||||
}
|
||||
|
||||
// 提取并排序items
|
||||
let items = []
|
||||
if (Array.isArray(snapshot)) {
|
||||
items = snapshot
|
||||
} else if (snapshot.items && Array.isArray(snapshot.items)) {
|
||||
items = snapshot.items
|
||||
}
|
||||
|
||||
if (items.length > 0) {
|
||||
// 必须按ID排序以匹配后端计算逻辑
|
||||
items.sort((a, b) => {
|
||||
const idA = Number(a.id || a.ID || 0)
|
||||
const idB = Number(b.id || b.ID || 0)
|
||||
return idA - idB
|
||||
})
|
||||
|
||||
weightsStr = items.map(item => `${item.id || item.ID}:${item.weight || item.Weight || item.count || 1}`).join(',')
|
||||
rewardsStr = items.map(item => `${item.id || item.ID}:${item.count || item.Count || 1}`).join(',')
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('items_snapshot解析失败:', e)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
mode: r.selected_index > 0 ? 'ichiban' : 'unlimited',
|
||||
version: r.algo_version || 'v1.0',
|
||||
seed: r.server_sub_seed || '',
|
||||
issue_id: r.round_id || 0,
|
||||
user_id: r.client_id || 0,
|
||||
salt: salt, // 使用items_snapshot中的salt
|
||||
rand_value: randValue, // 实际随机数(用于验证比对)
|
||||
slot_index: r.selected_index || 0,
|
||||
weights: weightsStr,
|
||||
rewards: rewardsStr,
|
||||
weights_total: r.weights_total || 0,
|
||||
timestamp: r.timestamp || 0,
|
||||
draw_index: idx + 1,
|
||||
items_snapshot: r.items_snapshot
|
||||
}
|
||||
})
|
||||
|
||||
// 如果只有一条凭据,直接导出单个对象;否则导出数组
|
||||
const exportData = receipts.length === 1 ? receipts[0] : receipts
|
||||
const jsonStr = JSON.stringify(exportData, null, 2)
|
||||
|
||||
uni.setClipboardData({
|
||||
data: jsonStr,
|
||||
success: () => {
|
||||
uni.showToast({ title: '凭据已复制', icon: 'success' })
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({ title: '复制失败', icon: 'none' })
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -916,5 +993,32 @@ function showProofHelp() {
|
||||
color: $text-sub;
|
||||
}
|
||||
}
|
||||
|
||||
.export-receipt-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12rpx;
|
||||
margin-top: $spacing-lg;
|
||||
padding: 20rpx 32rpx;
|
||||
background: linear-gradient(135deg, #6366F1 0%, #8B5CF6 100%);
|
||||
border-radius: 40rpx;
|
||||
box-shadow: 0 8rpx 24rpx rgba(99, 102, 241, 0.3);
|
||||
|
||||
&:active {
|
||||
transform: scale(0.96);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user