diff --git a/.DS_Store b/.DS_Store index 802ccbe..009bef8 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/@babel/runtime/helpers/typeof.js b/@babel/runtime/helpers/typeof.js index b677947..abfe713 100644 --- a/@babel/runtime/helpers/typeof.js +++ b/@babel/runtime/helpers/typeof.js @@ -1 +1,20 @@ -function _typeof(o){return module.exports=_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o},_typeof(o)}module.exports=_typeof; \ No newline at end of file +function _typeof2(o) { + "@babel/helpers - typeof"; + return (_typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) { + return typeof o; + } : function(o) { + return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; + })(o); +} + + +function _typeof(o) { + return "function" == typeof Symbol && "symbol" === _typeof2(Symbol.iterator) ? module.exports = _typeof = function(o) { + return _typeof2(o); + } : module.exports = _typeof = function(o) { + return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : _typeof2(o); + }, _typeof(o); +} + + +module.exports = _typeof; \ No newline at end of file diff --git a/api/request.js b/api/request.js index 44820f7..5541a8c 100644 --- a/api/request.js +++ b/api/request.js @@ -1,5 +1,21 @@ -const baseUrl = 'https://mini-chat.1024tool.vip/api/'; -// const baseUrl = 'https://dsjhd9s.tbmw.cn/api/' +const baseUrl = 'https://mini-chat.1024tool.vip/api/' +/** + * 发送 HTTP 请求到后端接口 + * + * 功能描述: + * - 封装 wx.request,统一设置 JSON 请求头与基础地址 + * - 成功时返回后端 res.data(已由微信自动 JSON.parse) + * - 业务错误(res.data.code 存在)统一弹 Toast 并 reject + * - 网络错误或服务器异常走 fail 并直接 reject + * + * 参数说明: + * @param {string} url - 相对接口路径,例如 'app/send_message' + * @param {string} [method='GET'] - HTTP 方法,支持 'GET'、'POST' 等 + * @param {Object} [data={}] - 请求参数对象,将作为请求体/查询参数发送 + * + * 返回值: + * @returns {Promise} - 成功时 resolve 为后端返回的数据对象,失败时 reject 错误信息 + */ function request(url, method = 'GET', data = {}) { const header = { @@ -40,5 +56,5 @@ function request(url, method = 'GET', data = {}) { }); } -// 导出请求和服务地址(CommonJS 兼容) +// 导出请求函数(CommonJS 导出,兼容微信小程序解析环境) module.exports = request; \ No newline at end of file diff --git a/api/upload.js b/api/upload.js index 91156e6..41f66fb 100644 --- a/api/upload.js +++ b/api/upload.js @@ -1,31 +1,106 @@ +const request = require('./request.js') + +const uploadFile = async (file, callback) => { -function uploadFile(filePath) { - return new Promise((resolve, reject) => { - if (!filePath) { - const err = new Error('uploadFile requires a filePath parameter'); - console.error('上传失败:未提供文件路径', err); - return reject(err); - } + const policyData = await request('admin/policy_token', 'post') + const res = JSON.parse(policyData.token) - wx.uploadFile({ - filePath: filePath, // 图片临时文件路径(由调用方传入) - name: 'file', // 服务器接收文件的字段名,需与后端对应 - url: 'https://mini-chat.1024tool.vip/api/admin/upload/image', // 服务器接收图片的接口地址 - success: (res) => { - const data = JSON.parse(res.data); - resolve('https://mini-chat.1024tool.vip/' + data.preview_image_url); - - }, - fail: (err) => { - console.error('上传失败', err); - reject(err); + const fileName = file.tempFilePath.split('/').pop(); // hello.png + // const fileName = fileNameWithExt.split('.').slice(0, -1).join('.'); // hello + + const formData = { + key: 'upload_file/' + fileName, //上传文件名称 + policy: res.policy, //表单域 + 'x-oss-signature-version': res.x_oss_signature_version, //指定签名的版本和算法 + 'x-oss-credential': res.x_oss_credential, //指明派生密钥的参数集 + 'x-oss-date': res.x_oss_date, //请求的时间 + 'x-oss-signature': res.signature, //签名认证描述信息 + 'x-oss-security-token': res.security_token, //安全令牌 + success_action_status: "200" //上传成功后响应状态码 + }; + // console.log(filePath) + // return + // 发送请求上传文件 + wx.uploadFile({ + url: 'https://image-fudan.oss-cn-beijing.aliyuncs.com/', + method: 'put', + filePath: file.tempFilePath, + name: 'file', //固定值为file + formData: formData, + success(res) { + console.log('上传响应:', res); + if (res.statusCode === 200) { + callback(null, 'https://image-fudan.oss-cn-beijing.aliyuncs.com/upload_file/' + fileName); // 上传成功 + } else { + console.error('上传失败,状态码:', res.statusCode); + console.error('失败响应:', res); + callback(res); // 上传失败,返回响应 } - }); - }) + }, + fail(err) { + console.error('上传失败:', err); // 输出错误信息 + wx.showToast({ + title: '上传失败,请重试!', + icon: 'none' + }); + callback(err); // 调用回调处理错误 + } + }); } -// 导出请求和服务地址(CommonJS 兼容) -module.exports = uploadFile; \ No newline at end of file +const uploadFileToOSS = () => { + + return new Promise((resolve, reject) => { + + wx.chooseMedia({ + count: 1, // 选择一个文件 + mediaType: ['image'], + sourceType: ['album', 'camera'], + // type: 'all', // 支持所有类型的文件 + success: (res) => { + wx.showToast({ + title: '文件上传中,请稍等!', + icon: 'none' + }); + console.log('选择的文件:', res.tempFiles); // 输出选择的文件信息 + if (res.tempFiles.length > 0) { + const tempFilePath = res.tempFiles[0]; + console.log('选择的文件路径:', tempFilePath); // 输出文件路径 + uploadFile(tempFilePath, (error, data) => { + if (error) { + wx.showToast({ + title: '上传失败!', + icon: 'none' + }); + console.error('上传失败:', error); // 输出具体的错误信息 + reject(error) + } else { + resolve(data) + console.log('上传成功:', data); // 输出上传成功后的数据 + } + }); + } else { + wx.showToast({ + title: '未选择文件!', + icon: 'none' + }); + reject('未选择文件!') + } + }, + fail: (err) => { + wx.showToast({ + title: '选择文件失败!', + icon: 'none' + }); + console.error('选择文件失败:', err); // 输出选择文件的错误信息 + reject('选择文件失败!') + } + }); + }); +}; + +// CommonJS 导出,适配微信开发者工具当前解析能力 +module.exports = uploadFileToOSS; \ No newline at end of file diff --git a/app.js b/app.js index 0779014..879261c 100644 --- a/app.js +++ b/app.js @@ -1,10 +1,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" -});var common_vendor = require("./common/vendor.js");if (!Math) { - "./pages/index/index.js"; - "./pages/index/detail.js"; - "./pages/ming/index.js"; -}var _sfc_main = { +}); +var common_vendor = require("./common/vendor.js"); + +var _sfc_main = { onLaunch: function onLaunch() { common_vendor.index.__f__("log", "at App.vue:4", "App Launch"); }, @@ -14,9 +13,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { onHide: function onHide() { common_vendor.index.__f__("log", "at App.vue:10", "App Hide"); } -};function createApp() { +}; +function createApp() { var app = common_vendor.createSSRApp(_sfc_main); return { app: app }; -}createApp().app.mount("#app");exports.createApp = createApp; \ No newline at end of file +} +createApp().app.mount("#app"); +exports.createApp = createApp; \ No newline at end of file diff --git a/common/vendor.js b/common/vendor.js index 40d7a3f..3143115 100644 --- a/common/vendor.js +++ b/common/vendor.js @@ -6320,9 +6320,14 @@ extend( /* @__PURE__ */Object.create(null), { console.log = value; return isWritable; }function initRuntimeSocketService() { - var hosts = "127.0.0.1,192.168.1.88"; - var port = "8090"; - var id = "mp-weixin_s4ko-M"; + // 禁用开发模式下的日志 WebSocket 连接(按需关闭 ws 功能) + var hosts = ""; + var port = ""; + var id = ""; + // 若未配置 socket 参数,直接跳过所有处理,避免与开发者工具内部机制冲突 + if (!hosts || !port || !id) { + return Promise.resolve(false); + } var lazy = typeof swan !== "undefined"; var restoreError = lazy ? function () {} : initOnError(); var restoreConsole = lazy ? function () {} : rewriteConsole(); @@ -6333,13 +6338,9 @@ extend( /* @__PURE__ */Object.create(null), { } return initRuntimeSocket(hosts, port, id).then(function (socket) { if (!socket) { + // 禁用 ws 功能时,直接恢复错误与控制台并安静返回,不打印 ws 相关错误日志 restoreError(); restoreConsole(); - originalConsole.error(wrapError("开发模式下日志通道建立 socket 连接失败。")); - { - originalConsole.error(wrapError("小程序平台,请勾选不校验合法域名配置。")); - } - originalConsole.error(wrapError("如果是运行到真机,请确认手机与电脑处于同一网络。")); return false; } { diff --git a/pages/.DS_Store b/pages/.DS_Store deleted file mode 100644 index f2dbd2e..0000000 Binary files a/pages/.DS_Store and /dev/null differ diff --git a/pages/contact/index.js b/pages/contact/index.js index b8ae3e0..74d4953 100644 --- a/pages/contact/index.js +++ b/pages/contact/index.js @@ -1,7 +1,7 @@ // pages/contact/index.js const request = require('../../api/request.js'); -const uploadFile = require('../../api/upload.js'); + Page({ /** * 页面的初始数据 @@ -73,18 +73,18 @@ Page({ }).then(res => { // 处理消息列表,使用统一的消息处理函数 const list = that.processMessages(res.list); - + // 根据ID进行排序,确保ID最大的(最新的)消息在最后 const sortedList = that.sortMessagesByID(list); - + // 智能滚动逻辑:用户在底部时自动滚动,在上方时保持位置 const updateData = { messages: sortedList, total: res.total }; - + that.setData(updateData); - + // 如果用户在底部,延迟设置滚动ID确保滚动生效 if (that.data.isAtBottom && sortedList.length > 0) { const lastMessageId = sortedList[sortedList.length - 1].id; @@ -98,7 +98,7 @@ Page({ } else { console.log('用户不在底部或无消息,保持当前位置。isAtBottom:', that.data.isAtBottom, '消息数量:', sortedList.length); } - + return res; // 返回结果以支持链式调用 }); }, @@ -131,7 +131,7 @@ Page({ // 合并新消息和现有消息 const combined = newList.concat(that.data.messages); - + // 根据ID进行排序,确保ID最大的(最新的)消息在最后 const sortedCombined = that.sortMessagesByID(combined); @@ -165,44 +165,41 @@ Page({ // 兜底方案:使用当前时间戳 + 索引 item.id = 'm' + (Date.now() + index); } - + // 解析消息内容 if (typeof item.content === 'string') { try { - const text = JSON.parse(item.content) - item.content = { - message: text.message || text.messages - }; + item.content = JSON.parse(item.content); } catch (e) { console.warn('消息内容解析失败:', item.content); - item.content = { message: item.content }; + item.content = { messages: item.content }; } } - + return item; }); // 检测新消息并显示提醒 this.checkNewMessages(processedMessages); - + return processedMessages; }, // 检测新消息的函数 checkNewMessages(newMessages) { if (newMessages.length === 0) return; - + const currentMessages = this.data.messages; const currentLastMessageId = this.data.lastMessageId; const sortedNewMessages = this.sortMessagesByID(newMessages); const latestNewMessage = sortedNewMessages[sortedNewMessages.length - 1]; - + // 如果不在底部且有新消息 if (!this.data.isAtBottom && currentMessages.length > 0) { // 找出真正的新消息(在当前消息列表中不存在的消息) const currentMessageIds = new Set(currentMessages.map(msg => msg.id)); const realNewMessages = sortedNewMessages.filter(msg => !currentMessageIds.has(msg.id)); - + if (realNewMessages.length > 0) { // 累加新消息数量(而不是重置) const currentCount = this.data.newMessageCount || 0; @@ -212,7 +209,7 @@ Page({ }); } } - + // 更新最后一条消息ID if (latestNewMessage) { this.setData({ @@ -242,7 +239,7 @@ Page({ } return 0; }; - + const idA = getNumericId(a.id); const idB = getNumericId(b.id); return idA - idB; @@ -285,7 +282,7 @@ Page({ }); }); }, - fail: function (err) { + fail: function(err) { console.error('wx.login失败:', err); } }); @@ -340,7 +337,7 @@ Page({ // user scrolled to bottom (or very near). update state and ensure polling is active console.log('用户滚动到底部,当前isAtBottom状态:', this.data.isAtBottom); if (!this.data.isAtBottom) { - this.setData({ + this.setData({ isAtBottom: true, showNewMessageTip: false, newMessageCount: 0 @@ -395,7 +392,7 @@ Page({ // 使用用户ID作为标记,检查是否已经发送过欢迎消息 const welcomeKey = `welcome_sent_${this.data.userInfo.openid}`; const hasWelcomeSent = wx.getStorageSync(welcomeKey); - + if (hasWelcomeSent) { console.log('该用户的欢迎消息已发送过,跳过'); this.setData({ hasWelcomeMessageSent: true }); @@ -405,11 +402,11 @@ Page({ const welcomeText = '你好'; const now = new Date(); const id = 'welcome_' + Date.now(); - + const msg = { id, content: { - message: welcomeText + messages: welcomeText }, "msg_type": 1, receiver_id: '', @@ -417,11 +414,11 @@ Page({ sender_id: this.data.userInfo.openid, sender_name: this.data.userInfo.user_name }; - + // 添加新消息并重新排序 const newMessages = this.data.messages.concat(msg); const sortedMessages = this.sortMessagesByID(newMessages); - + this.setData({ messages: sortedMessages, hasWelcomeMessageSent: true // 标记已发送欢迎消息 @@ -429,14 +426,14 @@ Page({ const accountInfo = wx.getAccountInfoSync(); const userInfo = wx.getStorageSync('user_info'); - + console.log('发送欢迎消息:', welcomeText); - + // 发送到服务器 request('app/send_message', 'POST', { "app_id": accountInfo.miniProgram.appId, "content": JSON.stringify({ - message: welcomeText + messages: welcomeText }), "from_user_id": userInfo.openid, "from_user_name": userInfo.user_name, @@ -473,7 +470,7 @@ Page({ const msg = { id, content: { - message: text + messages: text }, "msg_type": 1, receiver_id: '', @@ -481,11 +478,11 @@ Page({ sender_id: this.data.userInfo.openid, sender_name: this.data.userInfo.user_name }; - + // 添加新消息并重新排序 const newMessages = this.data.messages.concat(msg); const sortedMessages = this.sortMessagesByID(newMessages); - + this.setData({ messages: sortedMessages, inputText: '' @@ -495,7 +492,7 @@ Page({ request('app/send_message', 'POST', { "app_id": accountInfo.miniProgram.appId, "content": JSON.stringify({ - message: text + messages: text }), "from_user_id": userInfo.openid, "from_user_name": userInfo.user_name, @@ -553,7 +550,7 @@ Page({ msg_type: '2', receiver_id: '', content: { - message: tempFilePaths[0] + messages: tempFilePaths[0] }, sender_id: userInfo.openid, sender_name: userInfo.user_name, @@ -570,41 +567,30 @@ Page({ scrollToId: id }); }, 50); - uploadFile(tempFilePaths[0]).then((res) => { - const accountInfo = wx.getAccountInfoSync(); - - request('app/send_message', 'POST', { - "app_id": accountInfo.miniProgram.appId, - "content": JSON.stringify({ - message: res - }), - "from_user_id": userInfo.openid, - "from_user_name": userInfo.user_name, - "msg_type": 2 - }).catch((err) => { - wx.showToast({ - title: '图片发送失败', - icon: 'none' - }); - }); - }).catch((err) => { - wx.showToast({ - title: '图片发送失败', - icon: 'none' - }); + wx.uploadFile({ + filePath: tempFilePaths[0], // 图片临时文件路径 + name: 'file', // 服务器接收文件的字段名,需与后端对应 + url: 'https://dsjhd9s.tbmw.cn/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://dsjhd9s.tbmw.cn/'+ data.preview_image_url + }), + "from_user_id": userInfo.openid, + "from_user_name": userInfo.user_name, + "msg_type": 2 + }) + }, + fail: (err) => { + console.error('上传失败', err); + } }); - // wx.uploadFile({ - // filePath: tempFilePaths[0], // 图片临时文件路径 - // name: 'file', // 服务器接收文件的字段名,需与后端对应 - // url: 'https://mini-chat.1024tool.vip/api/admin/upload/image', // 服务器接收图片的接口地址 - // success: (res) => { - - // }, - // fail: (err) => { - // console.error('上传失败', err); - // } - // }); // 模拟客服返回图片确认 // setTimeout(() => { @@ -620,7 +606,7 @@ Page({ // _ts: replyNow // }; // that.setData({ - // message: that.data.messages.concat(reply) + // messages: that.data.messages.concat(reply) // }); // setTimeout(() => { // that.setData({ @@ -688,14 +674,14 @@ Page({ if (messages.length > 0) { const sortedMessages = this.sortMessagesByID(messages); const latestMessage = sortedMessages[sortedMessages.length - 1]; - + this.setData({ scrollToId: latestMessage.id, showNewMessageTip: false, newMessageCount: 0, isAtBottom: true }); - + // 延迟一下确保滚动完成 setTimeout(() => { this.setData({ @@ -707,4 +693,4 @@ Page({ onReachBottom() { }, onShareAppMessage() { } -}); \ No newline at end of file +}); diff --git a/pages/contact/index.wxml b/pages/contact/index.wxml index c89bcfc..6ea8533 100644 --- a/pages/contact/index.wxml +++ b/pages/contact/index.wxml @@ -20,10 +20,10 @@ - {{item.content.message}} + {{item.content.messages}} - + diff --git a/pages/index/detail.js b/pages/index/detail.js index 3329ec4..1aca8cc 100644 --- a/pages/index/detail.js +++ b/pages/index/detail.js @@ -166,4 +166,4 @@ Page({ }) } -}); \ No newline at end of file +}); diff --git a/project.config.json b/project.config.json index 5f47c1b..4342157 100644 --- a/project.config.json +++ b/project.config.json @@ -3,16 +3,16 @@ "__compileDebugInfo__": { "useSummer": true }, - "appid": "wx26ad074017e1e63f", + "appid": "wx75596d627154f6d0", "libVersion": "3.10.3", "setting": { - "es6": true, + "es6": false, "postcss": false, "compileWorklet": false, "minified": false, "uglifyFileName": false, "uploadWithSourceMap": true, - "enhance": true, + "enhance": false, "packNpmManually": false, "packNpmRelationList": [], "minifyWXSS": true,