Browse Source

更新消息排序规则

master
袁磊 8 months ago
parent
commit
9685b6648d
  1. 3
      App.vue
  2. 4
      uni_modules/vrapile-im/changelog.md
  3. 2
      uni_modules/vrapile-im/package.json
  4. 43
      utils/accessLog.js
  5. 194
      utils/nineTool.js
  6. 11
      utils/nodeId.js
  7. 175
      utils/request.js

3
App.vue

@ -2,8 +2,7 @@
import store from '@/store'
import socketStore from '@/uni_modules/vrapile-im/store'
import { getToken } from '@/utils/token'
import { setNodeId, getNodeId } from '@/utils/nodeId'
import { getLongRandom } from '@/utils/nineTool';
import { getNodeId } from '@/utils/nodeId'
export default {
globalData: {
// appId

4
uni_modules/vrapile-im/changelog.md

@ -1,3 +1,7 @@
## 1.1.13(2025-07-17)
更新消息排序规则
## 1.1.12(2025-07-17)
更新消息排序规则
## 1.1.11(2025-07-14)
更新readme说明文件
## 1.1.10(2025-04-11)

2
uni_modules/vrapile-im/package.json

@ -1,7 +1,7 @@
{
"id": "vrapile-im",
"displayName": "im页面组件",
"version": "1.1.11",
"version": "1.1.13",
"description": "实现WebSocket连接/好友/群组/新消息/历史消息,都是全局配置并本地化存储,已调试兼容H5/微信小程序/安卓App/PC多端同步通讯",
"keywords": [
"IM页面组件,websocket应用"

43
utils/accessLog.js

@ -1,30 +1,23 @@
import store from '@/store'
import { diyApi } from '@/utils/queryByDiy';
import { setNodeId, getNodeId } from '@/utils/nodeId'
import { getLongRandom } from '@/utils/nineTool';
import { getNodeId } from '@/utils/nodeId';
export function saveAccessLog(to, f) {
// 开发环境不保存日志
if(import.meta.env.VITE_APP_ENV == 'development'){
return;
}
// 生成一个nodeId,用于记录日志
let nodeId = getNodeId();
if(!nodeId){
nodeId = getLongRandom(24)
setNodeId(nodeId)
}
let flag = getApp().globalData.terminal + "_" + f;
let data = {
platform: getApp().globalData.appId,
terminal: getApp().globalData.terminal,
nodeId: nodeId,
flag: getApp().globalData.terminal + "_" + f,
fullPath: to.url.split("?")[0],
allPath: to.url,
menuName: to.tabBarText,
userId: store.state.user.userInfo.userId,
userName: store.state.user.userInfo.userName
}
diyApi("/system/log/insSysAccessLog", data);
// 开发环境不保存日志
if(import.meta.env.VITE_APP_ENV == 'development'){
return;
}
let flag = getApp().globalData.terminal + "_" + f;
let data = {
platform: getApp().globalData.appId,
terminal: getApp().globalData.terminal,
nodeId: getNodeId(),
flag: getApp().globalData.terminal + "_" + f,
fullPath: to.url.split("?")[0],
allPath: to.url,
menuName: to.tabBarText,
userId: store.state.user.userInfo.userId,
userName: store.state.user.userInfo.userName
}
diyApi("/system/log/insSysAccessLog", data);
}

194
utils/nineTool.js

@ -1,39 +1,39 @@
export function isNull(o) {
if(o === 0 || o === "0"){
return false;
}
if(o == "undefined" || o == null || o == ""){
return true;
}
return false;
if(o === 0 || o === "0"){
return false;
}
if(o == "undefined" || o == null || o == ""){
return true;
}
return false;
}
export function isPhone(o) {
if(/^1[23456789]\d{9}$/.test(o)){
return true;
}
return false;
if(/^1[23456789]\d{9}$/.test(o)){
return true;
}
return false;
}
export function isMail(o) {
if(/^([a-z0-9A-Z]+[-|\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\.)+[a-zA-Z]{2,}$/.test(o)){
return true;
}
return false;
if(/^([a-z0-9A-Z]+[-|\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\.)+[a-zA-Z]{2,}$/.test(o)){
return true;
}
return false;
}
export function isNumber(value) {
return !isNaN(parseFloat(value)) && isFinite(value)
}
export function isLetter(o) {
if(/^[A-Za-z]+$/.test(o)){
return true;
}
return false;
if(/^[A-Za-z]+$/.test(o)){
return true;
}
return false;
}
export function isNumberOrLetter(o) {
if(/^[A-Za-z0-9]+$/.test(o)){
return true;
}
return false;
if(/^[A-Za-z0-9]+$/.test(o)){
return true;
}
return false;
}
// 日期格式化
@ -65,7 +65,7 @@ export function parseTime(time, pattern) {
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
const time_str = format.replace(new RegExp(/{(y|m|d|h|i|s|a)+}/g), (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
@ -83,11 +83,11 @@ export function formatDate(time, option) {
} else {
time = +time
}
if (option) {
return parseTime(time, option)
}
if (option) {
return parseTime(time, option)
}
const d = new Date(time)
const now = Date.now()
@ -117,19 +117,19 @@ export function formatDate(time, option) {
}
if(diff < 3600 * 24 * 365) {
return (
(d.getMonth()*1 + 1) +
(d.getMonth()*1 + 1) +
'月' +
d.getDate() +
'日'
)
} else {
return (
d.getFullYear() +
'年' +
(d.getMonth()*1 + 1) +
'月'
)
}
return (
d.getFullYear() +
'年' +
(d.getMonth()*1 + 1) +
'月'
)
}
}
export function formatTime(time, option) {
@ -138,29 +138,38 @@ export function formatTime(time, option) {
} else {
time = +time
}
if (option) {
if (option) {
return parseTime(time, option)
}
const d = new Date(time)
const now = Date.now()
const diff = (now - d) / 1000
return (
d.getFullYear() +
'-' +
((d.getMonth()*1 + 1) + "").padStart(2,0) +
'-' +
(d.getDate() + '').padStart(2,0) +
' ' +
(d.getHours() + '').padStart(2,0) +
':' +
(d.getMinutes() + '').padStart(2,0) +
':' +
(d.getSeconds() + '').padStart(2,0)
)
return (
d.getFullYear() +
'-' +
((d.getMonth()*1 + 1) + "").padStart(2,0) +
'-' +
(d.getDate() + '').padStart(2,0) +
' ' +
(d.getHours() + '').padStart(2,0) +
':' +
(d.getMinutes() + '').padStart(2,0) +
':' +
(d.getSeconds() + '').padStart(2,0)
)
}
export function showRangeTime(date, start=1) {
if(start==1){
return date.replace(" 00:00:00", "")
}
if(start==2){
return date.replace(" 23:59:59", "")
}
}
// number:要格式化的数字,
@ -170,19 +179,19 @@ export function formatTime(time, option) {
// tail_add: 小数点后面数据是否添加0补足位数, 默认空字符
// null_default: 如果为空的值, 默认空字符
function numberFormat(number, decimals, tail_add="", thousands_sep, dec_point, null_default="") {
number = (number + '').replace(/[^0-9+-Ee.]/g, '');
var n = !isFinite(+number) ? 0 : +number,
prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
s = '',
toFixedFix = function (n, prec) {
var k = Math.pow(10, prec);
return '' + Math.round(n * k) / k;
};
number = (number + '').replace(new RegExp(/[^0-9+-Ee.]/g), '');
let n = !isFinite(+number) ? 0 : +number,
prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
s = '',
toFixedFix = function (n, prec) {
let k = Math.pow(10, prec);
return '' + Math.round(n * k) / k;
};
s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
var re = /(-?\d+)(\d{3})/;
let re = new RegExp(/(-?\d+)(\d{3})/g);
if(sep.length > 0){
while (re.test(s[0])) {
s[0] = s[0].replace(re, "$1" + sep + "$2");
@ -211,9 +220,10 @@ export function formatNumber(number, decimals, tail_add, thousands_sep, dec_poin
}
// thousands_sep:千分位符号 默认空字符
export function formatPercent(number, decimals, tail_add, thousands_sep="", dec_point, null_default) {
if(isNull(number) || isNull(String(number).trim().replaceAll(",", ""))){return null_default;}
if(!isNumber(String(number).trim().replaceAll(",", ""))){return number;}
number = String(number).trim().replaceAll(",", "");
let re = new RegExp(/,/g)
if(isNull(number) || isNull(String(number).trim().replace(re, ""))){return null_default;}
if(!isNumber(String(number).trim().replace(re, ""))){return number;}
number = String(number).trim().replace(re, "");
let value = numberFormat(number*100, decimals, tail_add, thousands_sep, dec_point, null_default);
if(value){
return value + "%";
@ -306,24 +316,24 @@ export function GetOs () {
}
export function getRandom(len){
let data = Math.random() + "";
let index = 2;
while(data[index] == 0){
index++;
}
return data.substr(index, len);
let data = Math.random() + "";
let index = 2;
while(data[index] == 0){
index++;
}
return data.substr(index, len);
}
export function getLongRandom(len){
if(len <= 16){
return getRandom(len)
}
let data = Math.random() + "";
let index = 2;
while(data[index] == 0){
index++;
}
return parseTime(Date.now(), '{y}{m}{d}{h}{i}{s}') + "" + data.substr(index, len-16);
if(len <= 16){
return getRandom(len)
}
let data = Math.random() + "";
let index = 2;
while(data[index] == 0){
index++;
}
return parseTime(Date.now(), '{y}{m}{d}{h}{i}{s}') + "" + data.substr(index, len-14);
}
export function moveInArray(array, fromIndex, toIndex) {
@ -332,17 +342,17 @@ export function moveInArray(array, fromIndex, toIndex) {
}
export function jsonCharBigInt(s){
if(typeof s !== 'string'){
return s
}
let re = /([\\]?['|"]{1})(\w+[\\]?['|"]{1}[ |\n|r|\t]*:[ |\n|r|\t]*)([-]?\d{15,})/g
return s.replaceAll(re, "$1$2$1$3$1")
if(typeof s !== 'string'){
return s
}
const re = new RegExp(/([\\]?['|"]{1})(\w+[\\]?['|"]{1}[ |\n|r|\t]*:[ |\n|r|\t]*)([-]?\d{15,})/gm);
return s.replace(re, "$1$2$1$3$1")
}
export function jsonParse(s){
if(typeof s !== 'string'){
return s
}
let re = /([\\]?['|"]{1})(\w+[\\]?['|"]{1}[ |\n|r|\t]*:[ |\n|r|\t]*)([-]?\d{15,})/g
return JSON.parse(s.replaceAll(re, "$1$2$1$3$1"))
if(typeof s !== 'string'){
return s
}
const re = new RegExp(/([\\]?['|"]{1})(\w+[\\]?['|"]{1}[ |\n|r|\t]*:[ |\n|r|\t]*)([-]?\d{15,})/gm);
return JSON.parse(s.replace(re, "$1$2$1$3$1"))
}

11
utils/nodeId.js

@ -1,7 +1,14 @@
import { getLongRandom } from '@/utils/nineTool';
const NodeIdKey = 'App-Node-Id'
export function getNodeId() {
return uni.getStorageSync(NodeIdKey)
export function getNodeId(len=18) {
let nodeId = uni.getStorageSync(NodeIdKey);
if(!nodeId){
nodeId = getLongRandom(len)
uni.setStorageSync(NodeIdKey, nodeId)
}
return nodeId
}
export function setNodeId(nodeId) {

175
utils/request.js

@ -1,7 +1,6 @@
import store from '@/store'
import { getToken } from '@/utils/token'
import { setNodeId, getNodeId } from '@/utils/nodeId'
import { getLongRandom } from '@/utils/nineTool';
import { getNodeId } from '@/utils/nodeId';
import errorCode from '@/utils/errorCode'
import { getSessionCache, setSessionCache } from '@/utils/cache'
import { toast, showConfirm, tansParams } from '@/utils/requestTool'
@ -12,22 +11,16 @@ const baseUrl = import.meta.env.VITE_APP_BASE_URL
const request = config => {
// 是否需要设置 token
const isToken = (config.headers || {}).isToken === false
// 是否需要防止数据重复提交
// 是否需要防止数据重复提交
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
config.header = config.header || {}
if (getToken() && !isToken) {
config.header['Authorization'] = 'Vrapile ' + getToken()
}
// 节点
let nodeId = getNodeId();
if(!nodeId){
nodeId = getLongRandom(24);
setNodeId(nodeId);
}
config.header["platform"] = getApp().globalData.appId;
config.header["terminal"] = getApp().globalData.terminal;
config.header["nodeId"] = nodeId;
config.header["nodeId"] = getNodeId();
// get请求映射params参数
if (config.params) {
@ -35,89 +28,89 @@ const request = config => {
url = url.slice(0, -1)
config.url = url
}
if (!isRepeatSubmit) {
const requestObj = {
url: config.url,
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
time: new Date().getTime()
}
const sessionObj = getSessionCache()
if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
setSessionCache(requestObj)
} else {
const s_url = sessionObj.url; // 请求地址
const s_data = sessionObj.data; // 请求数据
const s_time = sessionObj.time; // 请求时间
const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
const message = '数据正在处理,请勿重复提交:' + s_url;
console.warn(`[${s_url}]: ` + message)
return Promise.reject(new Error(message))
} else {
setSessionCache(requestObj)
}
}
}
if (!isRepeatSubmit) {
const requestObj = {
url: config.url,
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
time: new Date().getTime()
}
const sessionObj = getSessionCache()
if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
setSessionCache(requestObj)
} else {
const s_url = sessionObj.url; // 请求地址
const s_data = sessionObj.data; // 请求数据
const s_time = sessionObj.time; // 请求时间
const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
const message = '数据正在处理,请勿重复提交:' + s_url;
console.warn(`[${s_url}]: ` + message)
return Promise.reject(new Error(message))
} else {
setSessionCache(requestObj)
}
}
}
return new Promise((resolve, reject) => {
uni.request({
method: config.method || 'get',
timeout: config.timeout || timeout,
url: config.baseUrl || baseUrl + config.url,
data: config.data,
header: config.header,
dataType: 'json'
}).then(res => {
// let [error, res] = response
const code = res.data.code || res.data.status || 200
const msg = errorCode[code] || res.data.msg || errorCode['default']
// if (code != 200) {
// toast('后端接口连接异常')
// reject('后端接口连接异常')
// return
// }
if (code === 401) {
// 密码登录的,实现自动重新登录
let loginInfo = store.state.user.loginInfo;
if(loginInfo && loginInfo.loginType == 0){
store.dispatch('Login', {
loginType: loginInfo.loginType,
userName: loginInfo.userName,
password: loginInfo.password,
registerFlag: "N"
}).then(() => {
store.dispatch('GetInfo');
})
reject('无效的会话,或者会话已过期,已重新登录。')
}else{
showConfirm('登录状态已过期,您可以继续留在该页面,或者重新登录?').then(res => {
if (res.confirm) {
uni.reLaunch({ url: '/pages/user/login' })
}
})
reject('无效的会话,或者会话已过期,请重新登录。')
}
} else if (code === 500) {
toast(msg)
reject(res)
} else if (code !== 200) {
toast(msg)
reject(res)
}
resolve(res.data)
}).catch(error => {
let { message } = error
if (message && message === 'Network Error') {
message = '后端接口连接异常'
} else if (message && message.includes('timeout')) {
message = '系统接口请求超时'
} else if (message && message.includes('Request failed with status code')) {
message = '系统接口' + message.substr(message.length - 3) + '异常'
}else{
message = '系统繁忙'
}
toast(message)
reject(error)
})
method: config.method || 'get',
timeout: config.timeout || timeout,
url: config.baseUrl || baseUrl + config.url,
data: config.data,
header: config.header,
dataType: 'json'
}).then(res => {
// let [error, res] = response
const code = res.data.code || res.data.status || 200
const msg = errorCode[code] || res.data.msg || errorCode['default']
// if (code != 200) {
// toast('后端接口连接异常')
// reject('后端接口连接异常')
// return
// }
if (code === 401) {
// 密码登录的,实现自动重新登录
let loginInfo = store.state.user.loginInfo;
if(loginInfo && loginInfo.loginType == 0){
store.dispatch('Login', {
loginType: loginInfo.loginType,
userName: loginInfo.userName,
password: loginInfo.password,
registerFlag: "N"
}).then(() => {
store.dispatch('GetInfo');
})
reject('无效的会话,或者会话已过期,已重新登录。')
}else{
showConfirm('登录状态已过期,您可以继续留在该页面,或者重新登录?').then(res => {
if (res.confirm) {
uni.reLaunch({ url: '/pages/user/login' })
}
})
reject('无效的会话,或者会话已过期,请重新登录。')
}
} else if (code === 500) {
toast(msg)
reject(res)
} else if (code !== 200) {
toast(msg)
reject(res)
}
resolve(res.data)
}).catch(error => {
let { message } = error
if (message && message === 'Network Error') {
message = '后端接口连接异常'
} else if (message && message.includes('timeout')) {
message = '系统接口请求超时'
} else if (message && message.includes('Request failed with status code')) {
message = '系统接口' + message.substr(message.length - 3) + '异常'
}else{
message = '系统繁忙'
}
toast(message)
reject(error)
})
})
}

Loading…
Cancel
Save