邹方成 8ebe968b1b fix(contact): 替换用户授权弹窗为静默登录提示
将用户授权弹窗改为静默登录提示,优化登录流程。同时更新API基础URL配置,移除废弃代码。
2025-10-22 03:57:38 +08:00

439 lines
13 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// pages/contact/index.js
const request = require('../../api/request.js');
Page({
/**
* 页面的初始数据
*/
data: {
messages: [],
inputText: '',
scrollToId: '',
// 使用本地头像
userAvatar: '/static/user.png',
serviceAvatar: '/static/contact.png',
showGetUser: false,
userInfo: {},
appid: '',
page: 1,
page_size: 100,
openid: '',
total: 0,
// 是否滚动在底部
isAtBottom: true,
// 正在加载更多(顶部分页)
loadingMore: false,
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
const accountInfo = wx.getAccountInfoSync();
console.log(accountInfo.miniProgram);
this.setData({
appid: accountInfo.miniProgram.appId,
});
console.log('contact page onLoad, options:', options);
// 检查是否已有用户信息
if (wx.getStorageSync('user_info')) {
this.setData({
showGetUser: false,
userInfo: wx.getStorageSync('user_info'),
});
this.getMessages()
// start polling when page loads and user is present
this.startPolling();
} else {
// 直接进行静默登录,不显示授权弹窗
this.silentLogin();
}
},
// onShow() {
// this.getMessages()
// },
getMessages() {
const userInfo = wx.getStorageSync('user_info');
const that = this;
request('app/messages', 'get', {
app_id: that.data.appid,
user_id: userInfo.openid,
page: that.data.page,
page_size: that.data.page_size,
}).then(res => {
console.log('res', res);
// generate stable ids across pages so we can prepend without collisions
const base = (that.data.page - 1) * that.data.page_size;
const list = res.list.map((item, index) => {
item.id = 'm' + (base + index);
item.content = JSON.parse(item.content);
return item;
});
that.setData({
messages: list,
total: res.total,
// only auto-scroll if user is at bottom
scrollToId: that.data.isAtBottom ? (list[list.length - 1] ? list[list.length - 1].id : '') : that.data.scrollToId
});
console.log('messages', list);
})
},
// Load older messages (previous pages) and prepend them to the top
loadMoreAtTop() {
if (this.data.loadingMore) return;
// if we've loaded all messages, skip
const already = this.data.messages.length || 0;
if (already >= this.data.total) return;
// compute next page to fetch
const nextPage = this.data.page + 1;
this.setData({ loadingMore: true });
const userInfo = wx.getStorageSync('user_info');
const that = this;
// capture current top-most visible message id to preserve scroll position
const prevTopId = this.data.messages[0] ? this.data.messages[0].id : null;
request('app/messages', 'get', {
app_id: this.data.appid,
user_id: userInfo.openid,
page: nextPage,
page_size: this.data.page_size,
}).then(res => {
// map with stable ids based on nextPage
const base = (nextPage - 1) * that.data.page_size;
const newList = res.list.map((item, index) => {
item.id = 'm' + (base + index);
item.content = JSON.parse(item.content);
return item;
});
// prepend older messages
const combined = newList.concat(that.data.messages);
that.setData({
messages: combined,
page: nextPage,
total: res.total,
}, () => {
// after render, keep the previous top message in view
if (prevTopId) {
// scroll-into-view to the previous top id so viewport doesn't jump
that.setData({ scrollToId: prevTopId });
}
that.setData({ loadingMore: false });
});
}).catch(() => {
that.setData({ loadingMore: false });
});
},
// 静默登录方法只需要appid和js_code
silentLogin() {
const that = this;
const accountInfo = wx.getAccountInfoSync();
wx.login({
success: function (res) {
request('wechat/miniprogram/login', 'post', {
"app_id": accountInfo.miniProgram.appId,
"js_code": res.code
}).then(resp => {
wx.setStorageSync('user_info', resp);
that.setData({
showGetUser: false,
userInfo: resp
});
request('app/user/create', 'post', {
"app_id": accountInfo.miniProgram.appId,
"user_avatar": resp.user_avatar || '/static/user.png',
"user_id": resp.openid,
"user_name": resp.user_name || '微信用户'
}).then(resp => {
that.getMessages()
// start polling once user info exists
that.startPolling();
});
}).catch(err => {
console.error('静默登录失败:', err);
// 如果静默登录失败,可以选择显示授权弹窗或其他处理
that.setData({
showGetUser: true
});
});
},
fail: function(err) {
console.error('wx.login失败:', err);
}
});
},
// Start polling messages every 1 second. Ensures only one interval exists.
startPolling() {
if (this.poller) return; // already polling
// immediate fetch then periodic
this.getMessages();
this.poller = setInterval(() => {
this.getMessages();
}, 1000);
},
// Stop polling and clear interval
stopPolling() {
if (this.poller) {
clearInterval(this.poller);
this.poller = null;
}
},
// Scroll handlers: stop polling when user scrolls up, resume when reach bottom
onScroll(e) {
// e.detail.scrollTop increases when scrolling down. We want to detect upward scroll.
const scrollTop = e.detail.scrollTop || 0;
const last = this._lastScrollTop || 0;
// If user scrolls up (new scrollTop < last), pause polling
if (scrollTop < last) {
// user scrolled up
if (this.data.isAtBottom) {
// only act if we were previously at bottom
this.setData({ isAtBottom: false });
this.stopPolling();
}
}
// detect reaching near top to load more
if (scrollTop <= 2) {
// if there are more messages to load and not already loading
if (!this.data.loadingMore && this.data.messages.length < this.data.total) {
this.loadMoreAtTop();
}
}
// update lastScrollTop for next event
this._lastScrollTop = scrollTop;
},
onScrollToLower() {
// user scrolled to bottom (or very near). resume polling if needed
if (!this.data.isAtBottom) {
this.setData({ isAtBottom: true });
this.startPolling();
// also ensure we scroll to latest message next render
const lastId = this.data.messages[this.data.messages.length - 1] ? this.data.messages[this.data.messages.length - 1].id : '';
if (lastId) {
this.setData({ scrollToId: lastId });
}
}
},
onReady() {
// 初始化欢迎消息,带时间分割线
const now = new Date();
const timeStr = this.formatTime(now);
this.setData({
messages: [],
scrollToId: 'm1'
});
},
onInput(e) {
this.setData({
inputText: e.detail.value
});
},
sendText() {
const text = this.data.inputText && this.data.inputText.trim();
if (!text) return;
const now = new Date();
const id = 'u' + Date.now();
// const timeStr = this.formatTime(now);
// // 判断是否需要显示时间分割线
// let showTime = false;
// const lastMsg = this.data.messages.length ? this.data.messages[this.data.messages.length - 1] : null;
// if (!lastMsg || now - (lastMsg._ts || now) > 5 * 60 * 1000) showTime = true;
const msg = {
id,
content: {
messages: text
},
"msg_type": 1,
receiver_id: '',
send_time: "刚刚",
sender_id: this.data.userInfo.openid,
sender_name: this.data.userInfo.user_name
};
const newMessages = this.data.messages.concat(msg);
this.setData({
messages: newMessages,
inputText: ''
});
const accountInfo = wx.getAccountInfoSync();
const userInfo = wx.getStorageSync('user_info')
request('app/send_message', 'POST', {
"app_id": accountInfo.miniProgram.appId,
"content": JSON.stringify({
messages: text
}),
"from_user_id": userInfo.openid,
"from_user_name": userInfo.user_name,
"msg_type": 1
})
// 等待渲染,确保 scroll-into-view 生效
setTimeout(() => {
this.setData({
scrollToId: id
});
}, 50);
// 模拟客服回复(延迟)
// setTimeout(() => {
// const replyNow = new Date();
// const replyTimeStr = this.formatTime(replyNow);
// const reply = {
// id: 's' + Date.now(),
// from: 'service',
// type: 'text',
// content: '收到,客服正在处理中...',
// showTime: false,
// timeStr: replyTimeStr,
// _ts: replyNow
// };
// this.setData({
// messages: this.data.messages.concat(reply),
// scrollToId: reply.id
// });
// }, 800);
},
chooseImage() {
const that = this;
wx.chooseImage({
count: 1, // 选择图片的数量
mediaType: ['image'], // 仅选择图片
sizeType: ['compressed', 'original'],
sourceType: ['album', 'camera'],
success(res) {
const tempFilePaths = res.tempFilePaths;
console.log('选择的图片路径:', res);
if (tempFilePaths && tempFilePaths.length) {
const userInfo = wx.getStorageSync('user_info')
// const now = new Date();
const id = 'u' + Date.now();
// const timeStr = that.formatTime(now);
// let showTime = false;
// const lastMsg = that.data.messages.length ? that.data.messages[that.data.messages.length - 1] : null;
// if (!lastMsg || now - (lastMsg._ts || now) > 5 * 60 * 1000) showTime = true;
const msg = {
id,
msg_type: '2',
receiver_id: '',
content: {
messages: tempFilePaths[0]
},
sender_id: userInfo.openid,
sender_name: userInfo.user_name,
receiver_id: '',
send_time: "刚刚",
};
const list = that.data.messages
list.push(msg);
that.setData({
messages: list
});
setTimeout(() => {
that.setData({
scrollToId: id
});
}, 50);
wx.uploadFile({
filePath: tempFilePaths[0], // 图片临时文件路径
name: 'file', // 服务器接收文件的字段名,需与后端对应
url: 'https://mini-chat.1024tool.vip/admin/upload/image', // 服务器接收图片的接口地址
success: (res) => {
const data = JSON.parse(res.data);
console.log('上传成功', data);
const accountInfo = wx.getAccountInfoSync();
request('app/send_message', 'POST', {
"app_id": accountInfo.miniProgram.appId,
"content": JSON.stringify({
messages: 'https://mini-chat.1024tool.vip/'+ data.preview_image_url
}),
"from_user_id": userInfo.openid,
"from_user_name": userInfo.user_name,
"msg_type": 2
})
},
fail: (err) => {
console.error('上传失败', err);
}
});
// 模拟客服返回图片确认
// setTimeout(() => {
// const replyNow = new Date();
// const replyTimeStr = that.formatTime(replyNow);
// const reply = {
// id: 's' + Date.now(),
// from: 'service',
// type: 'text',
// content: '已收到图片,感谢!',
// showTime: false,
// timeStr: replyTimeStr,
// _ts: replyNow
// };
// that.setData({
// messages: that.data.messages.concat(reply)
// });
// setTimeout(() => {
// that.setData({
// scrollToId: reply.id
// });
// }, 50);
// }, 1200);
}
}
});
},
// 时间格式化
formatTime(date) {
const y = date.getFullYear();
const m = (date.getMonth() + 1).toString().padStart(2, '0');
const d = date.getDate().toString().padStart(2, '0');
const h = date.getHours().toString().padStart(2, '0');
const min = date.getMinutes().toString().padStart(2, '0');
return `${y}${m}${d}${h}:${min}`;
},
previewImage(e) {
const src = e.currentTarget.dataset.src;
if (!src) return;
wx.previewImage({
urls: [src],
current: src
});
},
onShow() {
// resume polling when page becomes visible
if (wx.getStorageSync('user_info')) {
this.startPolling();
}
},
onHide() {
// stop polling when leaving page
this.stopPolling();
},
onUnload() {
// cleanup
this.stopPolling();
},
onPullDownRefresh() { },
onReachBottom() { },
onShareAppMessage() { }
});