From 97c82746d8cb99e439ee433da2415100abac67b2 Mon Sep 17 00:00:00 2001
From: pfewmlupo <3097217416@qq.com>
Date: Sun, 17 Nov 2024 20:53:17 +0800
Subject: [PATCH] =?UTF-8?q?Add=20=E6=B3=A8=E9=87=8A=EF=BC=884=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
注释(4) | 442 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 442 insertions(+)
create mode 100644 注释(4)
diff --git a/注释(4) b/注释(4)
new file mode 100644
index 0000000..8428340
--- /dev/null
+++ b/注释(4)
@@ -0,0 +1,442 @@
+poetizepoetize-im-uisrcApp.vue
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+poetizepoetize-im-uisrcutilstiows.js
+
+// 导入reconnecting-websocket库,这是一个会自动重连的WebSocket实现
+import ReconnectingWebSocket from 'reconnecting-websocket';
+
+/**
+ * 创建一个WebSocket连接的构造函数
+ * @param {string} ws_protocol - WebSocket协议,'wss'用于加密连接,'ws'用于非加密连接
+ * @param {string} ip - WebSocket服务器的IP地址
+ * @param {string|number} port - WebSocket服务器的端口号,如果为空字符串则不使用端口号
+ * @param {string} paramStr - 附加在WebSocket URL后面的请求参数,例如:'name=张三&id=12'
+ * @param {string} binaryType - WebSocket接收二进制数据的类型,'blob'或'arraybuffer'
+ */
+export default function (ws_protocol, ip, port, paramStr, binaryType) {
+ // 将传入的参数赋值给当前对象的属性
+ this.ws_protocol = ws_protocol;
+ this.ip = ip;
+ this.port = port;
+ this.paramStr = paramStr;
+ this.binaryType = binaryType;
+
+ // 根据传入的参数构建WebSocket的URL
+ if (port === "") {
+ // 如果端口号为空字符串,则URL不包括端口号
+ this.url = ws_protocol + '://' + ip + '/socket';
+ } else {
+ // 否则,URL包括端口号
+ this.url = ws_protocol + '://' + ip + ":" + port + '/socket';
+ }
+ // 如果存在请求参数,则将它们添加到URL的末尾
+ if (paramStr) {
+ this.url += '?' + paramStr;
+ }
+
+ // 定义一个方法用于建立WebSocket连接
+ this.connect = () => {
+ // 创建一个新的ReconnectingWebSocket实例,并传入构建的URL
+ let ws = new ReconnectingWebSocket(this.url);
+ // 将创建的WebSocket实例保存到当前对象的ws属性中
+ this.ws = ws;
+ // 设置WebSocket接收二进制数据的类型
+ ws.binaryType = this.binaryType;
+
+ // 定义WebSocket连接打开时的回调函数
+ ws.onopen = function (event) {
+ // 在这里可以添加获取离线消息的逻辑,但当前为空实现
+ }
+
+ // 定义WebSocket连接关闭时的回调函数
+ ws.onclose = function (event) {
+ // 当前为空实现,可以在这里添加处理连接关闭的逻辑
+ }
+
+ // 定义WebSocket发生错误时的回调函数
+ ws.onerror = function (event) {
+ // 当前为空实现,可以在这里添加处理错误的逻辑
+ }
+ }
+
+ // 定义一个方法用于通过WebSocket发送数据
+ this.send = (data) => {
+ // 使用当前对象的ws属性(即WebSocket实例)的send方法发送数据
+ this.ws.send(data);
+ }
+}
+
+
+poetizepoetize-im-uisrcutilsrequest.js
+
+// 导入axios库,用于发送HTTP请求
+import axios from "axios";
+// 导入constant模块,该模块可能包含一些全局常量,如API的基础URL
+import constant from "./constant";
+// 导入qs库,用于处理URL参数序列化/反序列化
+import qs from "qs";
+
+// 导入Vuex的store实例,用于全局状态管理
+import store from "../store";
+
+// 设置axios的默认基础URL
+axios.defaults.baseURL = constant.baseURL;
+
+// 添加请求拦截器
+axios.interceptors.request.use(
+ function (config) {
+ // 在请求发送之前,可以在这里添加一些配置或处理逻辑
+ // 比如添加token到请求头中(但在这个例子中,token是在每个请求中单独添加的)
+ return config; // 返回配置对象,继续请求
+ },
+ function (error) {
+ // 请求发生错误时的处理逻辑
+ // 比如显示错误提示、记录日志等
+ return Promise.reject(error); // 返回Promise.reject,中断请求
+ }
+);
+
+// 添加响应拦截器
+axios.interceptors.response.use(
+ function (response) {
+ // 响应成功时的处理逻辑
+ // 检查响应数据中的code,如果不等于200,则视为错误处理
+ if (
+ response.data !== null &&
+ response.data.hasOwnProperty("code") &&
+ response.data.code !== 200
+ ) {
+ if (response.data.code === 300) {
+ // 特定错误码处理,比如用户未登录或token过期
+ store.commit("loadCurrentUser", {}); // 清除Vuex中的用户信息
+ localStorage.removeItem("userToken"); // 移除本地存储中的token
+ window.location.href = constant.webBaseURL + "/user"; // 重定向到登录页面
+ }
+ return Promise.reject(new Error(response.data.message)); // 返回Promise.reject,中断请求链,并携带错误信息
+ } else {
+ return response; // 返回响应对象,继续后续处理
+ }
+ },
+ function (error) {
+ // 响应发生错误时的处理逻辑
+ // 比如显示错误提示、记录日志等
+ return Promise.reject(error); // 返回Promise.reject,中断请求链
+ }
+);
+
+// 导出HTTP请求工具集
+export default {
+ // 发送POST请求的方法
+ post(url, params = {}, json = true) {
+ let config = {
+ headers: { "Authorization": localStorage.getItem("userToken") } // 添加token到请求头
+ };
+
+ return new Promise((resolve, reject) => {
+ axios
+ .post(
+ url,
+ json ? params : qs.stringify(params), // 根据json参数决定发送的数据格式
+ config
+ )
+ .then(res => {
+ resolve(res.data); // 请求成功,解析并返回响应数据
+ })
+ .catch(err => {
+ reject(err); // 请求失败,返回错误信息
+ });
+ });
+ },
+
+ // 发送GET请求的方法
+ get(url, params = {}) {
+ let headers = { "Authorization": localStorage.getItem("userToken") }; // 添加token到请求头
+
+ return new Promise((resolve, reject) => {
+ axios.get(url, { params: params, headers: headers }) // 发送GET请求,携带参数和请求头
+ .then(res => {
+ resolve(res.data); // 请求成功,解析并返回响应数据
+ })
+ .catch(err => {
+ reject(err); // 请求失败,返回错误信息
+ });
+ });
+ },
+
+ // 发送文件上传请求的方法
+ upload(url, param, option) {
+ let config = {
+ headers: {
+ "Authorization": localStorage.getItem("userToken"),
+ "Content-Type": "multipart/form-data" // 设置内容类型为文件上传
+ },
+ timeout: 60000 // 设置请求超时时间
+ };
+ if (typeof option !== "undefined") {
+ // 如果提供了上传进度回调,则添加onUploadProgress监听器
+ config.onUploadProgress = progressEvent => {
+ if (progressEvent.total > 0) {
+ progressEvent.percent = progressEvent.loaded / progressEvent.total * 100; // 计算上传进度百分比
+ }
+ option.onProgress(progressEvent); // 调用传入的回调,传递进度信息
+ };
+ }
+
+ return new Promise((resolve, reject) => {
+ axios
+ .post(url, param, config) // 发送POST请求,上传文件
+ .then(res => {
+ resolve(res.data); // 请求成功,解析并返回响应数据
+ })
+ .catch(err => {
+ reject(err); // 请求失败,返回错误信息
+ });
+ });
+ },
+
+ // 发送七牛云文件上传请求的方法(可能不需要token,因为七牛云上传通常通过临时凭证)
+ uploadQiniu(url, param) {
+ let config = {
+ headers: { "Content-Type": "multipart/form-data" }, // 设置内容类型为文件上传
+ timeout: 60000 // 设置请求超时时间
+ };
+
+ return new Promise((resolve, reject) => {
+ axios
+ .post(url, param, config) // 发送POST请求,上传文件到七牛云
+ .then(res => {
+ resolve(res.data); // 请求成功,解析并返回响应数据
+ })
+ .catch(err => {
+ reject(err); // 请求失败,返回错误信息
+ });
+ });
+ }
+};
+
+
+poetizepoetize-im-uisrcutilsim.js
+
+// 引入常量配置文件
+import constant from "./constant";
+// 引入CryptoJS库,用于加密和解密操作
+import CryptoJS from 'crypto-js';
+// 引入Vuex的store实例,用于全局状态管理
+import store from '../store';
+// 引入Element Plus库的ElMessage组件,用于显示消息提示
+import {ElMessage} from "element-plus";
+
+// 导出一个包含多个工具函数的对象
+export default {
+ /**
+ * 判断当前设备是否为移动设备
+ * @returns {boolean} 如果是移动设备返回true,否则返回false
+ */
+ mobile() {
+ // 使用正则表达式匹配userAgent字符串,判断是否为移动设备
+ let flag = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i);
+ // 如果匹配到且匹配结果数组长度大于0,则返回true,表示是移动设备
+ return flag && flag.length > 0;
+ },
+
+ /**
+ * 判断一个值是否为空
+ * @param {any} value - 要判断的值
+ * @returns {boolean} 如果值为空返回true,否则返回false
+ */
+ isEmpty(value) {
+ // 判断值是否为undefined、null、空字符串、空数组或空对象
+ if (typeof value === "undefined" || value === null ||
+ (typeof value === "string" && value.trim() === "") ||
+ (Array.isArray(value) && value.length === 0) ||
+ (value.constructor === Object && Object.keys(value).length === 0)) {
+ return true;
+ } else {
+ return false;
+ }
+ },
+
+ /**
+ * 使用AES算法加密明文
+ * @param {string} plaintText - 要加密的明文
+ * @returns {string} 加密后的密文,经过Base64编码并替换特定字符
+ */
+ encrypt(plaintText) {
+ // 设置加密选项,使用ECB模式和Pkcs7填充
+ let options = {
+ mode: CryptoJS.mode.ECB,
+ padding: CryptoJS.pad.Pkcs7
+ };
+ // 从常量配置中获取加密密钥,并转换为Utf8编码
+ let key = CryptoJS.enc.Utf8.parse(constant.cryptojs_key);
+ // 使用AES算法加密明文,并转换为字符串,同时替换特定字符以适应某些场景
+ let encryptedData = CryptoJS.AES.encrypt(plaintText, key, options);
+ return encryptedData.toString().replace(/\//g, "_").replace(/\+/g, "-");
+ },
+
+ /**
+ * 使用AES算法解密密文
+ * @param {string} encryptedBase64Str - 要解密的密文,经过Base64编码并可能包含特定替换字符
+ * @returns {string} 解密后的明文
+ */
+ decrypt(encryptedBase64Str) {
+ // 将密文中的特定替换字符还原为Base64编码的字符
+ let val = encryptedBase64Str.replace(/\-/g, '+').replace(/_/g, '/');
+ // 设置解密选项,与加密时相同
+ let options = {
+ mode: CryptoJS.mode.ECB,
+ padding: CryptoJS.pad.Pkcs7
+ };
+ // 从常量配置中获取加密密钥,并转换为Utf8编码
+ let key = CryptoJS.enc.Utf8.parse(constant.cryptojs_key);
+ // 使用AES算法解密密文,并转换为Utf8编码的字符串
+ let decryptedData = CryptoJS.AES.decrypt(val, key, options);
+ return CryptoJS.enc.Utf8.stringify(decryptedData);
+ },
+
+ /**
+ * 将文本中的表情符号转换为对应的图片标签
+ * @param {string} content - 包含表情符号的文本
+ * @returns {string} 表情符号被替换为图片标签后的文本
+ */
+ faceReg(content) {
+ // 使用正则表达式匹配文本中的表情符号,并替换为对应的图片标签
+ content = content.replace(/
+$$
+[^\[^
+$$
+]+\]/g, (word) => {
+ // 从常量配置的表情符号列表中查找匹配的索引
+ let index = constant.emojiList.indexOf(word.replace("[", "").replace("]", ""));
+ if (index > -1) {
+ // 根据索引构造图片URL,并返回图片标签
+ let url = store.state.sysConfig['webStaticResourcePrefix'] + "emoji/q" + (index + 1) + ".gif";
+ return '
';
+ } else {
+ // 如果没有找到匹配的表情符号,则原样返回
+ return word;
+ }
+ });
+ return content;
+ },
+
+ /**
+ * 将文本中的图片链接转换为图片标签
+ * @param {string} content - 包含图片链接的文本
+ * @returns {string} 图片链接被替换为图片标签后的文本
+ */
+ pictureReg(content) {
+ // 使用正则表达式匹配文本中的图片链接,并替换为对应的图片标签
+ content = content.replace(/
+$$
+[^\[^
+$$
+]+\]/g, (word) => {
+ // 查找图片链接中的逗号分隔符,以获取图片描述和链接
+ let index = word.indexOf(",");
+ if (index > -1) {
+ let arr = word.replace("[", "").replace("]", "").split(",");
+ // 返回图片标签,包含描述作为title属性
+ return '
';
+ } else {
+ // 如果没有找到逗号分隔符,则原样返回
+ return word;
+ }
+ });
+ return content;
+ },
+
+ /**
+ * 将日期字符串转换为时间戳
+ * @param {string} dateStr - 日期字符串,格式为YYYY-MM-DD或YYYY-MM-DD HH:mm:ss
+ * @returns {number} 转换后的时间戳(毫秒)
+ */
+ getDateTimeStamp(dateStr) {
+ // 将日期字符串中的短横线替换为斜杠,以适应Date.parse方法的格式要求
+ return Date.parse(dateStr.replace(/-/gi, "/"));
+ },
+
+ /**
+ * 计算两个日期之间的时间差,并返回友好的时间差字符串
+ * @param {string} dateStr - 要比较的日期字符串,格式为YYYY-MM-DD HH:mm:ss
+ * @returns {string} 友好的时间差字符串,如“3天前”、“2小时前”等
+ */
+ getDateDiff(dateStr) {
+ // 将日期字符串转换为时间戳(秒),并获取当前时间的时间戳(秒)
+ let publishTime = Date.parse(dateStr.replace(/-/gi, "/")) / 1000,
+ timeNow = Math.floor(new Date().getTime() / 1000),
+ d = timeNow - publishTime, // 计算时间差(秒)
+ // ...(省略了部分代码,包括日期格式化和时间差计算的详细逻辑)
+ // 根据时间差返回不同的友好时间差字符串
+ if (d_days > 0 && d_days < 3) {
+ return d_days + '天前';
+ } else if (d_days <= 0 && d_hours > 0) {
+ return d_hours + '小时前';
+ } else if (d_hours <= 0 && d_minutes > 0) {
+ return d_minutes + '分钟前';
+ } else if (d_seconds < 60) {
+ if (d_seconds <= 0) {
+ return '刚刚发表';
+ } else {
+ return d_seconds + '秒前';
+ }
+ } else if (d_days >= 3 && d_days < 30) {
+ return M + '-' + D + ' ' + H + ':' + m;
+ } else if (d_days >= 30) {
+ return Y + '-' + M + '-' + D + ' ' + H + ':' + m;
+ }
+ },
+
+ /**
+ * 保存资源信息到服务器
+ * @param {Vue组件实例} that - 调用此方法的Vue组件实例
+ * @param {string} type - 资源类型
+ * @param {string} path - 资源路径
+ * @param {number} size - 资源大小(字节)
+ * @param {string} mimeType - 资源MIME类型
+ * @param {string} originalName - 资源原始名称
+ * @param {string} storeType - 存储类型
+ */