2026-04-21 13:46:20 +08:00
|
|
|
|
// 首页逻辑 - 深色主题信息流
|
2026-03-16 15:47:55 +08:00
|
|
|
|
const app = getApp()
|
|
|
|
|
|
|
|
|
|
|
|
Page({
|
|
|
|
|
|
data: {
|
2026-04-21 13:46:20 +08:00
|
|
|
|
// 用户信息
|
2026-03-16 15:47:55 +08:00
|
|
|
|
hasUserInfo: false,
|
2026-04-21 13:46:20 +08:00
|
|
|
|
openId: '',
|
|
|
|
|
|
phoneNumber: '',
|
|
|
|
|
|
unionId: '',
|
|
|
|
|
|
locationInfo: null,
|
|
|
|
|
|
deviceInfo: null,
|
|
|
|
|
|
systemInfo: null,
|
|
|
|
|
|
networkType: '',
|
|
|
|
|
|
wxVersion: '',
|
|
|
|
|
|
accountInfo: null,
|
|
|
|
|
|
clipboardData: null,
|
|
|
|
|
|
|
|
|
|
|
|
// 时间显示
|
|
|
|
|
|
currentTime: '',
|
|
|
|
|
|
yesterdayTime: '',
|
|
|
|
|
|
|
|
|
|
|
|
// 轮播Banner数据 - 蓝色主题
|
|
|
|
|
|
banners: [
|
|
|
|
|
|
{ id: 1, tag: '健康科普', title: '在多才和多艺之间\n我选择了多肉~', desc: '医生,我喝水都要胖,咋个整?', image: '' },
|
|
|
|
|
|
{ id: 2, tag: '专家讲座', title: '春季养生指南:\n中医教你调理身体', desc: '', image: '' }
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
|
|
// 轮播Banner数据 - 红色喜报主题
|
|
|
|
|
|
redBanners: [
|
|
|
|
|
|
{ id: 1, title: '四川省人民医院高质量发展跃上新台阶,成功迈入全国公立医院第一方阵!', image: '' }
|
|
|
|
|
|
],
|
|
|
|
|
|
|
2026-03-16 15:47:55 +08:00
|
|
|
|
websocketConnected: false,
|
2026-04-21 13:46:20 +08:00
|
|
|
|
version: app.globalData.version || '1.0.0',
|
|
|
|
|
|
socketTask: null,
|
2026-03-16 15:47:55 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
onLoad() {
|
2026-04-21 13:46:20 +08:00
|
|
|
|
this.updateTimeDisplay()
|
|
|
|
|
|
this.loadStoredInfo()
|
|
|
|
|
|
this.initWebSocketSafe()
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
onShow() {
|
|
|
|
|
|
this.updateTimeDisplay()
|
|
|
|
|
|
this.setTabBarActive()
|
|
|
|
|
|
if (this.data.hasUserInfo) this.loadStoredInfo()
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// ==============================================
|
|
|
|
|
|
// 加载本地存储的信息
|
|
|
|
|
|
// ==============================================
|
|
|
|
|
|
loadStoredInfo() {
|
|
|
|
|
|
const openId = wx.getStorageSync('openId') || ''
|
|
|
|
|
|
const phoneNumber = wx.getStorageSync('phoneNumber') || ''
|
|
|
|
|
|
const deviceInfo = app.getDeviceInfo?.() || null
|
|
|
|
|
|
|
|
|
|
|
|
this.setData({ openId, phoneNumber, deviceInfo })
|
|
|
|
|
|
|
|
|
|
|
|
if (openId) {
|
|
|
|
|
|
this.setData({ hasUserInfo: true })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取网络状态
|
|
|
|
|
|
app.getNetworkType?.((networkType) => {
|
|
|
|
|
|
if (networkType) this.setData({ networkType })
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 获取位置(需要授权)
|
|
|
|
|
|
app.getLocation?.((locationInfo) => {
|
|
|
|
|
|
if (locationInfo) this.setData({ locationInfo })
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 获取小程序信息
|
|
|
|
|
|
try {
|
|
|
|
|
|
const accountInfo = wx.getAccountInfoSync()
|
|
|
|
|
|
this.setData({ accountInfo })
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取小程序信息失败:', error)
|
|
|
|
|
|
this.setData({ accountInfo: null })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取剪贴板信息(需要授权)
|
|
|
|
|
|
wx.getClipboardData({
|
|
|
|
|
|
success: (res) => {
|
|
|
|
|
|
this.setData({ clipboardData: res.data })
|
|
|
|
|
|
},
|
|
|
|
|
|
fail: (error) => {
|
|
|
|
|
|
console.error('获取剪贴板信息失败:', error)
|
|
|
|
|
|
this.setData({ clipboardData: null })
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 获取微信版本信息
|
|
|
|
|
|
try {
|
|
|
|
|
|
const systemInfo = wx.getSystemInfoSync()
|
|
|
|
|
|
this.setData({ wxVersion: systemInfo.version, systemInfo })
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取微信版本信息失败:', error)
|
|
|
|
|
|
this.setData({ wxVersion: null, systemInfo: null })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取UnionID(个人小程序无法获取)
|
|
|
|
|
|
this.setData({ unionId: '无法获取(需企业资质)' })
|
|
|
|
|
|
|
|
|
|
|
|
// 获取手机号(个人小程序无法获取)
|
|
|
|
|
|
if (!phoneNumber) {
|
|
|
|
|
|
this.setData({ phoneNumber: '无法获取(需企业资质)' })
|
2026-03-16 15:47:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2026-04-21 13:46:20 +08:00
|
|
|
|
// ==============================================
|
|
|
|
|
|
// 登录:通过 WebSocket 发 wechat_login,收到 openid 后存本地
|
|
|
|
|
|
// ==============================================
|
|
|
|
|
|
onLogin() {
|
|
|
|
|
|
// 确保 WebSocket 已连接
|
|
|
|
|
|
if (!this.data.socketTask || !this.data.websocketConnected) {
|
|
|
|
|
|
// 先重连
|
|
|
|
|
|
this.initWebSocketSafe()
|
|
|
|
|
|
setTimeout(() => this._doLogin(), 1500)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
this._doLogin()
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
_doLogin() {
|
|
|
|
|
|
if (!this.data.websocketConnected) {
|
|
|
|
|
|
wx.showToast({ title: '连接中...', icon: 'none' })
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
wx.login({
|
2026-03-16 15:47:55 +08:00
|
|
|
|
success: (res) => {
|
2026-04-21 13:46:20 +08:00
|
|
|
|
if (!res.code) {
|
|
|
|
|
|
wx.showToast({ title: '微信登录失败', icon: 'none' })
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
// 记录待处理登录(收到 wechat_login_ret 时判断)
|
|
|
|
|
|
this._pendingLogin = true
|
|
|
|
|
|
this.data.socketTask.send({
|
|
|
|
|
|
data: JSON.stringify({
|
|
|
|
|
|
type: 'wechat_login',
|
|
|
|
|
|
data: { code: res.code }
|
|
|
|
|
|
}),
|
|
|
|
|
|
fail: () => {
|
|
|
|
|
|
this._pendingLogin = false
|
|
|
|
|
|
wx.showToast({ title: '发送失败', icon: 'none' })
|
|
|
|
|
|
}
|
2026-03-16 15:47:55 +08:00
|
|
|
|
})
|
2026-04-21 13:46:20 +08:00
|
|
|
|
},
|
|
|
|
|
|
fail:
|
|
|
|
|
|
|
|
|
|
|
|
// ==============================================
|
|
|
|
|
|
// 获取手机号(button open-type="getPhoneNumber")
|
|
|
|
|
|
// ==============================================
|
|
|
|
|
|
onGetPhoneNumber(e) {
|
|
|
|
|
|
// 检查是否有加密数据(旧版方式,个人小程序可用)
|
|
|
|
|
|
const { encryptedData, iv, code } = e.detail
|
|
|
|
|
|
if (!encryptedData || !iv) {
|
|
|
|
|
|
wx.showToast({ title: '请允许授权', icon: 'none' })
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 必须先登录有 openid
|
|
|
|
|
|
const openid = this.data.openId || wx.getStorageSync('openId')
|
|
|
|
|
|
if (!openid) {
|
|
|
|
|
|
wx.showToast({ title: '请先登录', icon: 'none' })
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 确保 WebSocket 连接
|
|
|
|
|
|
if (!this.data.websocketConnected) {
|
|
|
|
|
|
wx.showToast({ title: '连接中...', icon: 'none' })
|
|
|
|
|
|
this.initWebSocketSafe()
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
this._sendPhoneDecrypt(openid, encryptedData, iv)
|
|
|
|
|
|
}, 1500)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this._sendPhoneDecrypt(openid, encryptedData, iv)
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
_sendPhoneDecrypt(openid, encryptedData, iv) {
|
|
|
|
|
|
if (!this.data.websocketConnected) {
|
|
|
|
|
|
wx.showToast({ title: 'WebSocket 未连接', icon: 'none' })
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
this._pendingPhone = true
|
|
|
|
|
|
this.data.socketTask.send({
|
|
|
|
|
|
data: JSON.stringify({
|
|
|
|
|
|
type: 'wechat_decrypt_phone',
|
|
|
|
|
|
data: { openid, encryptedData, iv }
|
|
|
|
|
|
}),
|
|
|
|
|
|
fail: () => {
|
|
|
|
|
|
this._pendingPhone = false
|
|
|
|
|
|
wx.showToast({ title: '发送失败', icon: 'none' })
|
2026-03-16 15:47:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2026-04-21 13:46:20 +08:00
|
|
|
|
// ==============================================
|
|
|
|
|
|
// 时间显示
|
|
|
|
|
|
// ==============================================
|
|
|
|
|
|
updateTimeDisplay() {
|
|
|
|
|
|
const now = new Date()
|
|
|
|
|
|
const m = now.getMonth() + 1
|
|
|
|
|
|
const d = now.getDate()
|
|
|
|
|
|
const h = now.getHours()
|
|
|
|
|
|
const mm = String(now.getMinutes()).padStart(2, '0')
|
|
|
|
|
|
const period = h >= 12 ? '下午' : '上午'
|
|
|
|
|
|
const displayH = h > 12 ? h - 12 : h
|
|
|
|
|
|
|
2026-03-16 15:47:55 +08:00
|
|
|
|
this.setData({
|
2026-04-21 13:46:20 +08:00
|
|
|
|
currentTime: `${m}月${d}日 ${period}${displayH}:${mm}`,
|
|
|
|
|
|
yesterdayTime: `昨天 晚上8:36`
|
2026-03-16 15:47:55 +08:00
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2026-04-21 13:46:20 +08:00
|
|
|
|
// ==============================================
|
|
|
|
|
|
// TabBar 选中
|
|
|
|
|
|
// ==============================================
|
|
|
|
|
|
setTabBarActive() {
|
|
|
|
|
|
if (this.getTabBar) this.getTabBar()?.setData({ currentTab: 0 })
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// ==============================================
|
|
|
|
|
|
// 新闻点击
|
|
|
|
|
|
// ==============================================
|
|
|
|
|
|
onNewsTap(e) {
|
|
|
|
|
|
const id = e.currentTarget.dataset.id
|
|
|
|
|
|
console.log('点击新闻:', id)
|
|
|
|
|
|
wx.showToast({ title: '加载中...', icon: 'none' })
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// ==============================================
|
|
|
|
|
|
// WebSocket 安全版(防重复连接、防崩溃)
|
|
|
|
|
|
// ==============================================
|
|
|
|
|
|
initWebSocketSafe() {
|
|
|
|
|
|
if (this.data.socketTask) return
|
|
|
|
|
|
|
|
|
|
|
|
const socket = wx.connectSocket({ url: app.globalData.websocketUrl })
|
|
|
|
|
|
this.setData({ socketTask: socket })
|
2026-03-16 15:47:55 +08:00
|
|
|
|
|
|
|
|
|
|
socket.onOpen(() => {
|
2026-04-21 13:46:20 +08:00
|
|
|
|
this.setData({ websocketConnected: true })
|
2026-03-16 15:47:55 +08:00
|
|
|
|
socket.send({
|
|
|
|
|
|
data: JSON.stringify({
|
|
|
|
|
|
type: 'auth',
|
2026-04-21 13:46:20 +08:00
|
|
|
|
userId: app.globalData.userInfo?.nickName || 'anonymous',
|
|
|
|
|
|
deviceId: app.globalData.systemInfo?.model || '',
|
2026-03-16 15:47:55 +08:00
|
|
|
|
timestamp: Date.now()
|
|
|
|
|
|
})
|
|
|
|
|
|
})
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2026-04-21 13:46:20 +08:00
|
|
|
|
socket.onMessage(msg => {
|
2026-03-16 15:47:55 +08:00
|
|
|
|
try {
|
2026-04-21 13:46:20 +08:00
|
|
|
|
const data = JSON.parse(msg.data)
|
2026-03-16 15:47:55 +08:00
|
|
|
|
this.handleWebSocketMessage(data)
|
2026-04-21 13:46:20 +08:00
|
|
|
|
} catch (e) {}
|
2026-03-16 15:47:55 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
socket.onClose(() => {
|
2026-04-21 13:46:20 +08:00
|
|
|
|
this.setData({ websocketConnected: false, socketTask: null })
|
|
|
|
|
|
setTimeout(() => this.initWebSocketSafe(), 3000)
|
2026-03-16 15:47:55 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
2026-04-21 13:46:20 +08:00
|
|
|
|
socket.onError(() => {
|
|
|
|
|
|
this.setData({ websocketConnected: false, socketTask: null })
|
2026-03-16 15:47:55 +08:00
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
handleWebSocketMessage(data) {
|
|
|
|
|
|
switch (data.type) {
|
2026-04-21 13:46:20 +08:00
|
|
|
|
case 'wechat_login_ret':
|
|
|
|
|
|
// 收到登录响应(可能比 send 回调更早或更晚到达)
|
|
|
|
|
|
if (data.data?.openid) {
|
|
|
|
|
|
wx.setStorageSync('openId', data.data.openid)
|
|
|
|
|
|
this.setData({ openId: data.data.openid, hasUserInfo: true })
|
|
|
|
|
|
wx.showToast({ title: '登录成功', icon: 'success' })
|
|
|
|
|
|
} else {
|
|
|
|
|
|
wx.showToast({ title: '登录失败:' + (data.data?.error || '未知'), icon: 'none' })
|
|
|
|
|
|
}
|
|
|
|
|
|
this._pendingLogin = false
|
2026-03-16 15:47:55 +08:00
|
|
|
|
break
|
2026-04-21 13:46:20 +08:00
|
|
|
|
case 'ai_message':
|
|
|
|
|
|
// AI 回复(聊天页使用)
|
|
|
|
|
|
if (this.handleAiMessage) this.handleAiMessage(data)
|
|
|
|
|
|
break
|
|
|
|
|
|
case 'wechat_decrypt_phone_ret':
|
|
|
|
|
|
// 手机号解密响应
|
|
|
|
|
|
if (data.data?.phone) {
|
|
|
|
|
|
wx.setStorageSync('phoneNumber', data.data.phone)
|
|
|
|
|
|
this.setData({ phoneNumber: data.data.phone })
|
|
|
|
|
|
wx.showToast({ title: '绑定成功', icon: 'success' })
|
|
|
|
|
|
} else {
|
|
|
|
|
|
wx.showToast({ title: '获取失败:' + (data.data?.error || '未知'), icon: 'none' })
|
|
|
|
|
|
}
|
|
|
|
|
|
this._pendingPhone = false
|
|
|
|
|
|
break
|
|
|
|
|
|
case 'pong':
|
2026-03-16 15:47:55 +08:00
|
|
|
|
break
|
|
|
|
|
|
default:
|
2026-04-21 13:46:20 +08:00
|
|
|
|
break
|
2026-03-16 15:47:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2026-04-21 13:46:20 +08:00
|
|
|
|
// ==============================================
|
|
|
|
|
|
// 跳转聊天页
|
|
|
|
|
|
// ==============================================
|
2026-03-16 15:47:55 +08:00
|
|
|
|
goToChat() {
|
2026-04-21 13:46:20 +08:00
|
|
|
|
wx.navigateTo({ url: '/pages/chat/chat' })
|
2026-03-16 15:47:55 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
2026-04-21 13:46:20 +08:00
|
|
|
|
// ==============================================
|
|
|
|
|
|
// 跳转任务页
|
|
|
|
|
|
// ==============================================
|
2026-03-16 15:47:55 +08:00
|
|
|
|
goToTask() {
|
2026-04-21 13:46:20 +08:00
|
|
|
|
wx.navigateTo({ url: '/pages/task/task' })
|
2026-03-16 15:47:55 +08:00
|
|
|
|
}
|
2026-04-21 13:46:20 +08:00
|
|
|
|
})
|