Taro小程序react 开发gpt 会话经验踩坑
行内样式兼容,style = {{height:"100px"}} 中100px要写成 Taro.pxTransform(100)
taro-ui 中 AtDrawer一直频繁切换打开和关闭drawer 解决:onclose方法要写好控制开关,
react-toolkit 同步写法async 方法 await dispatch,编辑器中报await不起作用,实质是起作用的;或者用callback(res) 传入action方法
小程序获取头像和昵称:需要在新页面通过特定type去触发,
头像生成base64 方法:
在开发者工具中获取昵称,点击获取之后e.detail.value为空,为开发者工具bug,真机上能获取到;获取头像获取到的是微信临时路径,想保存到服务器可以生成base64获取上传到服务器。
头像生成base64 方法:
const onChooseAvatar =async (e) => {
const base64Url = await getImageBase64_readFile(e.detail.avatarUrl);
setAvatar(base64Url);
};
const getImageBase64_readFile = async (tempFilePath) => { const base64 = await new Promise((resolve) => { //获取全局唯一的文件管理器 Taro.getFileSystemManager().readFile({ //读取本地文件内容 filePath: tempFilePath, // 文件路径 encoding: "base64", // 返回格式 success: ({ data }) => { return resolve("data:image/png;base64," + data); }, fail(res) { console.log("fail", res); }, }); }); return base64; };
textArea 自动高度autoHeight在真机上高度不对,需要手动在style中设置height,此方法也需要再真机上调试,因高度受字体大小影响和line-height控制,不同字体大小需在真机上测试;可以设置line-height和height相同(此方法文字间距太小)
另外发现,动态渲染textarea之后 组件抛出的onlinechange方法不会触发(暂未找到解决办法)
函数式组件全局增加分享
Taro.showShareMenu({ withShareTicket: true, // @ts-ignore menus: ["shareAppMessage", "shareTimeline"], showShareItems: ["shareAppMessage", "shareTimeline"], }); const page = Taro.getCurrentInstance().page; if (page && !page.onShareAppMessage) { page.onShareAppMessage = () => { return { title: "发送给好友", path: `pages/index/index?shareCode=${ loginUserInfo?.memberLoginUserDTO?.memberUser?.shareCode || "" }`, imageUrl: shareFriendIcon, }; }; page.onShareTimeline = () => { return { title: "分享朋友圈", query: `shareCode=${loginUserInfo?.memberLoginUserDTO?.memberUser?.shareCode} || ''`, //页面携带参数 imageUrl: shareFriendIcon, }; }; }
socket连接封装:多个socket 用chatId区分,保存连接,注意保存全局对象window上,socket全局保存
export const sendHeartBeat = (task) => {
heartTimer = setInterval(() => {
task.send({ data: HEARTBEAT });
}, 5000);
};
export const socketInit = async ({ chatId, onMessageNewDialog, reConnect, callback, }) => { try { let curChatId = chatId || Taro.getStorageSync("chatId"); if (Object.keys(window.socketObjs).length) { for (let chat_Id in window.socketObjs) { window.socketObjs[chat_Id]?.close(); } window.socketObjs = {}; } if (!curChatId) return; const token = Taro.getStorageSync("userToken") || Taro.getStorageSync("touristToken"); const url = `${wsBaseUrl}/ws/newChatGpt?abc=${token}&chat_id=${curChatId}&model=${Taro.getStorageSync( "chatModal" )}`; await Taro.connectSocket({ url, success: function () { console.log("connect success"); }, }).then((task) => { task.onOpen(function () { if (task.readyState === 1) { window.socketObjs[curChatId] = task; sendHeartBeat(task); callback && callback(task); } }); task.onMessage(function (msg) { // onMessageNewDialog(msg.data, hasClickSend); onMessageNewDialog(msg.data); }); task.onError(function (e) { reConnect && reConnect(curChatId); console.log("onError", e); }); task.onClose(function (e) { socketOnClose(curChatId); console.log("onClose: ", e); }); }); } catch (e) { console.log(e); } };
使用
const onMessageNewDialog = (str) => { //状态都带【】 if (str.indexOf("[") === -1) { resultStr += str; setOnMessageResult(resultStr); scrollToBottom({}); setScrollTop(resultStr.length + 10000); } if (str === "[done]") { //完成展示菜单 setShowMenus(true); resultStr = ""; setIsNewDialog(false); if (!hasMakeTitle) { hasMakeTitle = true; let newMakeTitleNum = makeTitleNum + 1; setMakeTitleNum(newMakeTitleNum); } } else if (str.indexOf("noTokens") > -1) { //游客 if (loginUserInfo?.memberLoginUserDTO?.memberType == "0") { const newData = JSON.parse(JSON.stringify(loginUserInfo)); newData.memberLoginUserDTO.memberType = "0"; dispatch(setLoginUserInfo(newData)); Taro.removeStorageSync({ key: "userToken", }); Taro.showModal({ content: "积分已用完免费注册赠送积分", success: (res) => { if (res.confirm) { Taro.switchTab({ url: "/pages/my/index", }); } else if (res.cancel) { // console.log("用户点击取消"); } }, }); } else { Taro.showModal({ content: "去个人中心进行充值", success: (res) => { if (res.confirm) { //用户去购买 Taro.navigateTo({ url: "/pages/my/rightslist/index", }); } else if (res.cancel) { // console.log("用户点击取消"); } }, }); } } };
toSetSocketInit(resChatId, () => {
window.socketObjs[resChatId].send({
data: JSON.stringify(param),
});
})
获取分享页面参数
获取分享页面参数
Taro.getCurrentInstance().router.params?.shareCode
聊天页面滚动到底部,滚动到顶部
聊天页面滚动到底部,滚动到顶部
Taro.pageScrollTo({
scrollTop: 10000 || 0.2(避免真机上问题),
duration: duration,
});
协议问题引入链接用webview更改url即可
微信支付
协议问题引入链接用webview更改url即可
微信支付
const toPay = (type = "text") => { dispatch( orderPay({ packageSpecificationId: packageInfo?.packageSpecificationVOList[activeTabIndex] .packageSpecificationId, openId: loginUserInfo?.memberLoginUserDTO?.memberUser?.openId, callback: (result) => { // 调取后端接口success result const { timeStamp, nonceStr, signType, paySign, prepay_id } = result?.jsapiPayVO; Taro.requestPayment({ timeStamp, nonceStr, package: `prepay_id=` + prepay_id, //这里要加prepay_id,否则会报订单错误 signType, paySign, success: (res) => { Taro.showToast({ title: "支付成功", success: () => { Taro.navigateTo({ url: "/pages/my/rights/index", }); }, }); }, fail: (res) => { Taro.showToast({ title: "支付失败", }); }, }); ƒ; }, tokenFail: () => { const newData = JSON.parse(JSON.stringify(loginUserInfo)); newData.memberLoginUserDTO.memberType = "0"; dispatch(setLoginUserInfo(newData)); Taro.removeStorageSync({ key: "userToken", }); Taro.switchTab({ url: "/pages/my/index", }); }, }) ); };
绑定手机号(必须通过按钮点击的方式获取)
const getPhoneNumber = async (e) => { if (!checkBoxValue.length) { Taro.showModal({ content: "请同意并勾选协议", showCancel: false, }); return; } const { iv, encryptedData, code, errMsg } = e.detail; if (!errMsg.indexOf("ok")) { Taro.showModal({ content: "您点击了拒绝", showCancel: false, }); return; } const params = { code, tokenFail: () => { const newData = JSON.parse(JSON.stringify(loginUserInfo)); newData.memberLoginUserDTO.memberType = "0"; dispatch(setLoginUserInfo(newData)); Taro.removeStorageSync({ key: "userToken", }); Taro.switchTab({ url: "/pages/my/index", }); }, }; const wxCode = await wxLogin(); await dispatch(ac_login(wxCode)); dispatch(bindPhone(params)); };