Files
soul-yongping/miniprogram/pages/scan/scan.js

158 lines
4.4 KiB
JavaScript
Raw Normal View History

/**
* Soul创业派对 - 扫码解析页
* 扫描二维码/条形码展示解析内容
*/
const app = getApp()
Page({
data: {
statusBarHeight: 44,
// 最近一次解析结果
lastResult: null,
scanType: '',
charSet: '',
// 小程序码解析(路径、参数)
parsedPath: null,
parsedQuery: [],
canNavigate: false,
// 历史记录
history: []
},
onLoad() {
this.setData({
statusBarHeight: app.globalData.statusBarHeight || 44
})
this.loadHistory()
},
loadHistory() {
try {
const history = wx.getStorageSync('scanHistory') || []
this.setData({ history })
} catch (e) {
console.log('加载扫码历史失败:', e)
}
},
saveToHistory(result, scanType, charSet) {
const item = { result, scanType, charSet, time: new Date().toLocaleString() }
let history = wx.getStorageSync('scanHistory') || []
history = [item, ...history].slice(0, 10)
wx.setStorageSync('scanHistory', history)
this.setData({ history })
},
// 解析小程序码内容path?key=val 或 path
parseMiniProgramCode(result) {
if (!result || typeof result !== 'string') return { path: null, query: [], canNavigate: false }
const idx = result.indexOf('?')
let path = idx >= 0 ? result.slice(0, idx) : result
const qs = idx >= 0 ? result.slice(idx + 1) : ''
path = path.replace(/^\//, '').trim()
const query = []
if (qs) {
qs.split('&').forEach(pair => {
const eq = pair.indexOf('=')
const k = eq >= 0 ? pair.slice(0, eq) : pair
const v = eq >= 0 ? pair.slice(eq + 1) : ''
try {
if (k) query.push({ key: decodeURIComponent(k), value: decodeURIComponent(v) })
} catch (_) {
if (k) query.push({ key: k, value: v })
}
})
}
const isMiniProgramPath = /^pages\/[\w-]+\/[\w-]+$/.test(path)
return { path: path || null, query, canNavigate: isMiniProgramPath }
},
// 发起扫码(支持小程序码)
doScan() {
wx.scanCode({
onlyFromCamera: false,
scanType: ['qrCode', 'barCode'],
success: (res) => {
const { result, scanType, charSet } = res
const parsed = this.parseMiniProgramCode(result)
this.setData({
lastResult: result,
scanType: scanType || '未知',
charSet: charSet || '',
parsedPath: parsed.path,
parsedQuery: parsed.query,
canNavigate: parsed.canNavigate
})
this.saveToHistory(result, scanType, charSet)
},
fail: (err) => {
if (err.errMsg && err.errMsg.includes('cancel')) {
return
}
wx.showToast({ title: err.errMsg || '扫码失败', icon: 'none' })
}
})
},
// 复制内容
copyResult() {
const { lastResult } = this.data
if (!lastResult) {
wx.showToast({ title: '暂无解析内容', icon: 'none' })
return
}
wx.setClipboardData({
data: lastResult,
success: () => wx.showToast({ title: '已复制', icon: 'success' })
})
},
// 清空当前结果
clearResult() {
this.setData({
lastResult: null, scanType: '', charSet: '',
parsedPath: null, parsedQuery: [], canNavigate: false
})
},
// 打开解析出的小程序页面
openParsedPage() {
const { parsedPath, parsedQuery } = this.data
if (!parsedPath || !this.data.canNavigate) {
wx.showToast({ title: '非本小程序页面', icon: 'none' })
return
}
const queryStr = parsedQuery.length
? '?' + parsedQuery.map(q => `${encodeURIComponent(q.key)}=${encodeURIComponent(q.value)}`).join('&')
: ''
const url = `/${parsedPath}${queryStr}`
const tabPages = ['pages/index/index', 'pages/chapters/chapters', 'pages/match/match', 'pages/my/my']
if (tabPages.includes(parsedPath)) {
wx.switchTab({ url: `/${parsedPath}` })
} else {
wx.navigateTo({ url })
}
},
// 清空历史
clearHistory() {
wx.setStorageSync('scanHistory', [])
this.setData({ history: [], lastResult: null, scanType: '', charSet: '' })
wx.showToast({ title: '已清空', icon: 'success' })
},
// 点击历史项复制
onHistoryItemTap(e) {
const result = e.currentTarget.dataset.result
if (!result) return
wx.setClipboardData({
data: result,
success: () => wx.showToast({ title: '已复制', icon: 'success' })
})
},
goBack() {
wx.navigateBack()
}
})