解决uui 冲突

feature/pay-0615-ch
ch 3 years ago
commit f6fb143a69

@ -0,0 +1,4 @@
VUE_APP_BASE_URL = https://k8s-horse-gateway.mashibing.cn
VUE_APP_STATIC_URL = https://k8s-shop-app.mashibing.cn
#VUE_APP_IM_URL = ws://192.168.10.94:8090
VUE_APP_IM_URL = wss://k8s-horse-gateway.mashibing.cn

@ -0,0 +1,3 @@
VUE_APP_BASE_URL = https://you-gateway.mashibing.com
VUE_APP_STATIC_URL = https://you-gateway.mashibing.com
VUE_APP_IM_URL = wss://you-gateway.mashibing.com

@ -0,0 +1,3 @@
VUE_APP_BASE_URL = https://you-gateway.mashibing.com
VUE_APP_STATIC_URL = https://you-gateway.mashibing.com
VUE_APP_IM_URL = wss://you-gateway.mashibing.com

@ -0,0 +1,3 @@
VUE_APP_BASE_URL = https://k8s-horse-gateway.mashibing.com
VUE_APP_STATIC_URL = https://k8s-shop-app.mashibing.com
VUE_APP_IM_URL = wss://k8s-horse-gateway.mashibing.cn

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-05-05 14:40:00
* @LastEditors: ch
* @LastEditTime: 2022-05-26 19:04:26
* @LastEditTime: 2022-06-09 11:25:44
* @Description: 根据git分支生成对应环境的环境变量
* 开发时如果环境变量换了可以不用重启服务直接运行node env.config.js即可
*/
@ -13,6 +13,7 @@ const envConfig = {
dev : {
baseUrl: 'https://k8s-horse-gateway.mashibing.cn',
staticUrl : 'https://k8s-shop-app.mashibing.cn',
// imUrl : 'ws://192.168.10.94:8090'
imUrl : 'wss://k8s-horse-gateway.mashibing.cn'
},
test : {

@ -1,48 +1,16 @@
// /*
// * @Author: ch
// * @Date: 2022-05-18 15:21:10
// * @LastEditors: ch
// * @LastEditTime: 2022-05-18 17:24:37
// * @Description: file content
// */
// import { MsbSkt } from "../utils/webSkt";
// import { CreateUUID } from '@/common/utils';
/*
* @Author: ch
* @Date: 2022-05-27 17:44:36
* @LastEditors: ch
* @LastEditTime: 2022-06-09 11:34:36
* @Description: file content
*/
import {ToAsyncAwait, MsbRequestTk} from '@/common/utils';
const BASE_URL = '/mall/im';
// /**
// * 系统消息心跳
// */
// export const ApiSktSysHeart = () => MsbSkt.send({
// traceId: CreateUUID(),
// traceType: '0',
// content: { text: "ping" }
// });
// /**
// * 获取系统通知会话
// * @param {*} content
// */
// export const ApiSktSysGetSession = (content) => MsbSkt.send({
// traceId: CreateUUID(),
// traceType: '1',
// content
// });
// /**
// * 获取系统消息历史消息
// * @param {*} content
// */
// export const ApiSktSysGetHistory = (content) => MsbSkt.send({
// traceId: CreateUUID(),
// traceType: '2',
// content
// });
// /**
// * 系统消息已读
// * @param {*} content
// */
// export const ApiSktSysGetHistory = (content) => MsbSkt.send({
// traceId: CreateUUID(),
// traceType: '6',
// content
// });
/**
* 获取soket登录秘钥
*/
export const ApiGetSoketTicket = () => ToAsyncAwait(MsbRequestTk.get(`${BASE_URL}/ticket`, {
ticketType: 'CONNECT_TICKET'
}));

@ -2,83 +2,130 @@
* @Author: ch
* @Date: 2022-05-18 14:54:47
* @LastEditors: ch
* @LastEditTime: 2022-05-24 22:51:47
* @LastEditTime: 2022-06-14 17:24:14
* @Description: file content
*/
import { CreateUUID, FormatDate, ToAsyncAwait } from "@/common/utils";
const connect = Symbol('connect'),
send = Symbol('send'),
onResponse = Symbol('onResponse'),
onMessage = Symbol('onMessage'),
updateData = Symbol('updateData')
;
export default class MsbIm {
option = {
ioKey : 'traceId',
import './potoReq';
import './protoRsp'
const connect = Symbol('connect');
const send = Symbol('send');
const onMessage = Symbol('onMessage');
const fromatPotoReq = (traceId, traceType, content) => {
let messageModel = new proto.ReqModel();
messageModel.setTraceid(traceId);
messageModel.setTracetype(traceType);
content && messageModel.setContent(JSON.stringify(content));
return messageModel.serializeBinary();
},
fromatPotoRsp = (data) => {
const res = proto.RspModel.deserializeBinary(new Uint8Array(data));
let ctx = res.getContent();
ctx = ctx ? JSON.parse(ctx) : {};
if (ctx.payload) {
ctx.payload = JSON.parse(ctx.payload);
}
return {
content: ctx,
traceId: res.getTraceid(),
traceType: res.getTracetype(),
code: res.getCode(),
message: res.getMessage(),
};
};
class MsbIm {
defaultOption = {
ioKey: 'traceId',
reconnect: true,
logout : false
}
};
socket = null;
isOpen = false;
queue = {};
interceptors = {
dataChangeBefore: null,
dataChangeAfter: null,
onLogout : null,
onMessage: null
onClose: null,
onMessage: null,
};
sessionData = [];
curSessionId = null;
constructor(option) {
this.option = {
...this.option,
...option
}
...this.defaultOption,
...option,
};
}
/**
* 创建连接返回一个Promise 创建成功并成功打开连接算连接成功
* @param {*} option
*/
[connect](option) {
return new Promise((resolve, reject) => {
this.socket = uni.connectSocket({
...option,
fail(e){
reject(e);
}
});
this.socket.onOpen(() => {
this.socket.onMessage(async (res) => {
const result = JSON.parse(res.data);
if (result.content?.payload) {
result.content.payload = JSON.parse(result.content.payload);
}
// 401主动退出
if (result.code === 401) {
this.logout();
return false;
}
const open = () => {
console.log('[im] open');
this.isOpen = true;
resolve(this.socket);
};
const message = async (res) => {
const result = fromatPotoRsp(res.data);
this.interceptors.onMessage && this.interceptors.onMessage(result);
// 处理服务端主动推送的消息
this[onMessage](result);
// 如果再消息堆里有此消息回调,则执行回调,并删除
const cbk = this.queue[result[this.option.ioKey]];
if (cbk) {
cbk(result.code !== 200 ? {error:result} : {result:result});
cbk(result.code !== 200 ? { error: result } : { result: result });
delete this.queue[result[this.option.ioKey]];
}
})
resolve(this.socket);
};
const close = () => {
console.log('[im] close');
this.interceptors.onClose && this.interceptors.onClose();
};
let isUni = false;
try {
isUni = uni;
} catch (e) {
isUni = false;
}
if (isUni) {
this.socket = uni.connectSocket({
...this.option,
fail(e) {
reject(e);
},
});
this.socket.onOpen(() => {
open();
this.socket.onMessage((res) => {
message(res);
});
});
this.socket.onClose(() => {
if (this.option.reconnect && !this.option.logout) {
this[connect]();
}
this.option.logout = false;
close();
});
} else if (WebSocket) {
try {
this.socket = new WebSocket(this.option.url);
this.socket.binaryType = 'arraybuffer';
this.socket.onopen = () => {
open();
};
this.socket.onmessage = (res) => {
message(res);
};
this.socket.onclose = () => {
close();
};
} catch (e) {
reject(e);
}
}
});
}
/**
@ -87,20 +134,36 @@ export default class MsbIm {
*/
[send](data) {
return new Promise((resolve, reject) => {
this.queue[data[this.option.ioKey]] = ({result, error}) => {
if (!this.isOpen) {
return reject('连接未打开');
}
this.queue[data[this.option.ioKey]] = ({ result, error }) => {
if (result) {
resolve(result);
} else {
reject(error);
}
};
const par = fromatPotoReq(data.traceId, data.traceType, data.content);
let isUni = false;
try {
isUni = uni;
} catch (e) {
isUni = false;
}
if (isUni) {
this.socket.send({
data : JSON.stringify(data),
data: par,
fail(e) {
reject({error : e});
reject({ error: e });
},
});
} else if (WebSocket) {
this.socket.send(par);
}
});
})
}
/**
* 服务端推送消息只处理服务端主动推送的消息
@ -111,67 +174,81 @@ export default class MsbIm {
if (data[this.option.ioKey] || data.code !== 200) {
return false;
}
console.log('[im] 主动接收的消息', data);
let ctx = data.content;
let historyData = [...this.sessionData],
newData = [];
const hisIndex = historyData.findIndex(i => i.id === ctx.sessionId);
if(hisIndex >= 0){
const hisIndex = historyData.findIndex((i) => i.id === ctx.sessionId);
if (hisIndex >= 0) {
// 存在会话往现有会话增加一条消息,并修改最后一条消息为当前消息
const curHisData = historyData[hisIndex];
curHisData.messageList.push(ctx);
curHisData.lastMessage = ctx;
// 不在当前会话窗口则向会话消息加1条未读
if(ctx.sessionId !== this.curSessionId){
if (ctx.sessionId !== this.curSessionId) {
curHisData.unreadCount++;
} else {
this.setRead({
content: {
sessionId: this.curSessionId,
},
});
}
newData = historyData;
}else{
} else {
// 会话列表不存在,则创建一个会话
newData = [...historyData, {
fromAvatar : ctx.fromAvatar,
fromId : ctx.fromId,
fromNickname : ctx.fromNickname,
id : ctx.id,
lastMessage : ctx,
messageList : [ctx],
unreadCount : 1
}]
}
this.setSessionData(newData)
newData = [
...historyData,
{
fromAvatar: ctx.session.fromAvatar,
fromId: ctx.session.fromId,
fromNickname: ctx.session.fromNickname,
id: ctx.sessionId,
lastMessage: ctx,
messageList: [ctx],
updateTimeStamp: ctx.createTimeStamp,
unreadCount: 1,
},
];
}
init (config) {
this.setSessionData(newData);
}
init(config) {
return new Promise((resolve, reject) => {
const heart = () => {
// 要优化 心跳没回复需要重连
setTimeout(async () => {
if (this.isOpen) {
await this[send]({
traceId: CreateUUID(),
traceType: '0',
content: { text: "ping" }
}).catch((e)=>{});
heart();
},5000)
traceType: 0,
content: { text: 'ping' },
});
}
this[connect]({
heart();
}, 1000);
};
this.option = {
...this.option,
...config,
}).then(() => {
};
this[connect]()
.then((res) => {
resolve(res);
heart();
resolve(this);
}).catch((e)=>{});
})
}
logout() {
this.option.logout = true;
this.socket.close();
this.interceptors.onLogout && this.interceptors.onLogout();
.catch((e) => {
console.log('eeeee', e);
});
});
}
/**
* 设置数据
*/
setSessionData(data) {
this.interceptors.dataChangeBefore && this.interceptors.dataChangeBefore(data, this.sessionData);
this.sessionData = data;
let newData = JSON.parse(JSON.stringify(data));
this.interceptors.dataChangeBefore && this.interceptors.dataChangeBefore(newData, this.sessionData);
this.sessionData = newData;
this.interceptors.dataChangeAfter && this.interceptors.dataChangeAfter(this.sessionData);
}
/**
@ -187,71 +264,93 @@ export default class MsbIm {
* @param {*} params
*/
async getSessionList(params) {
let {error, result} = await ToAsyncAwait(this[send]({
const par = {
traceId: CreateUUID(),
traceType : 1,
...params
}));
traceType: 1,
...params,
};
console.log('[im] 获取会话列表--start', par);
let { error, result } = await ToAsyncAwait(this[send](par));
console.log('[im] 获取会话列表--end', result, error);
if (error) {
return Promise.reject(error);
}
const { content } = result;
content.sessionVOS.forEach(item => {
// let newData = [];
content.sessionVOS.forEach((item) => {
if (item.lastMessage) {
item.lastMessage.payload = JSON.parse(item.lastMessage.payload || {});
}
let historyData = this.sessionData;
let hisIndex = historyData.findIndex(i => i.id === item.id);
if(hisIndex >= 0){
historyData[hisIndex].lastMessage = item.lastMessage;
historyData[hisIndex].unreadCount++;
this.setSessionData(historyData)
}else{
let hisIndex = historyData.findIndex((i) => i.id === item.id);
if (hisIndex < 0) {
item.messageList = [];
const newData = [...historyData, item]
this.setSessionData(newData);
}
// let historyData = this.sessionData;
// let hisIndex = historyData.findIndex((i) => i.id === item.id);
// if (hisIndex >= 0) {
// historyData[hisIndex].lastMessage = item.lastMessage;
// historyData[hisIndex].unreadCount++;
// newData.push(historyData[hisIndex]);
// } else {
// item.messageList = [];
// newData = [...newData, item];
// }
});
this.setSessionData(content.sessionVOS);
return Promise.resolve(result);
}
/**
* 获取会话的历史消息记录
* @param {*} params
*/
async getHistoryMsg(params) {
const {error, result} = await ToAsyncAwait(this[send]({
async getHistoryMsg() {
const curSessionIdx = this.sessionData.findIndex((i) => i.id === this.curSessionId);
const curSession = this.sessionData[curSessionIdx];
console.log(curSession, this.curSessionId, 'this.curSessionId');
const msgList = curSession.messageList || [];
const par = {
traceId: CreateUUID(),
traceType: 23,
...params
}));
traceType: 2,
content: {
sessionId: this.curSessionId,
topMessageId: msgList.length ? msgList[0].id : null,
},
};
console.log('[im] 获取会话历史消息--start', par);
const { error, result } = await ToAsyncAwait(this[send](par));
console.log('[im] 获取会话历史消息--end', result, error);
if (error) {
return Promise.reject(error);
}
const { content } = result;
if (content.length) {
let newData = this.sessionData;
const hisIdx = newData.findIndex(i => i.id === content[0].sessionId);
content.forEach(item => {
item.payload = JSON.parse(item.payload)
})
newData[hisIdx].messageList = newData[hisIdx].messageList.concat(content);
content.forEach((item) => {
item.payload = JSON.parse(item.payload);
});
newData[curSessionIdx].messageList = content.concat(newData[curSessionIdx].messageList);
this.setSessionData(newData);
}
return Promise.resolve(result);
}
/**
* 会话已读
* @param {*} params
*/
async setRead (params){
await this[send]({
traceId : CreateUUID(),
traceType : "6",
...params
});
let newData = this.sessionData.map(item => {
async setRead(params) {
const par = {
traceId: CreateUUID(),
traceType: '6',
...params,
};
console.log('[im] 会话已读--start', par);
const { error, result } = await this[send](par);
console.log('[im] 会话已读--end', result, error);
let newData = this.sessionData.map((item) => {
if (item.id == params.content.sessionId) {
item.unreadCount = 0;
}
@ -265,28 +364,36 @@ export default class MsbIm {
* @param {*} params
*/
async sendMsg(params) {
const index = this.sessionData.findIndex(i => i.id === this.curSessionId)
const index = this.sessionData.findIndex((i) => i.id === this.curSessionId);
let curSession = this.sessionData[index];
// 临时消息体
let par = {
...params,
traceId: CreateUUID(),
traceType: 20,
}
traceType: 3,
};
let msgCtx = {
...params.content,
...par,
fromId: params.fromId,
createTimeStamp : (new Date()).getTime(),
sendStatus : 'loading'
createTimeStamp: new Date().getTime(),
sendStatus: 'loading',
};
if (typeof msgCtx.payload === 'string') {
msgCtx.payload = JSON.parse(msgCtx.payload);
}
// 点发送,立即把消息加入消息列表,标记为发送中状态
curSession.lastMessage = msgCtx;
curSession.messageList.push(msgCtx);
this.setSessionData(this.sessionData);
// 超过时间未返回视为发送失败
this.timerStatus(msgCtx);
console.log('[im] 发送消息--start', par);
const { error, result } = await ToAsyncAwait(this[send](par));
console.log('[im] 发送消息--end', result, error);
// 接到通知,标记消息是否发送成功
for (let i = curSession.messageList.length; i--;) {
for (let i = curSession.messageList.length; i--; ) {
const item = curSession.messageList[i];
if (item[this.option.ioKey] === par[this.option.ioKey]) {
curSession.messageList[i].sendStatus = msgCtx.sendStatus = error ? 'fail' : 'success';
@ -294,6 +401,7 @@ export default class MsbIm {
}
}
let newData = [...this.sessionData];
curSession.lastMessage = msgCtx;
newData[index] = curSession;
this.setSessionData(newData);
if (error) {
@ -308,12 +416,17 @@ export default class MsbIm {
*/
async resend(params) {
params.sendStatus = 'loading';
this.timerStatus(params)
const { error, result } = await ToAsyncAwait(this[send]({
this.timerStatus(params);
console.log('[im] 重新发送消息--start', params);
const { error, result } = await ToAsyncAwait(
this[send]({
traceId: params.traceId,
traceType: params.traceType,
content : params.content
}));
content: params.content,
})
);
console.log('[im] 重新发送消息--end', result, error);
params.createTimeStamp = result.createTimeStamp;
if (error) {
params.sendStatus = 'fail';
@ -323,7 +436,6 @@ export default class MsbIm {
return Promise.resolve(result);
}
timerStatus(msg) {
setTimeout(() => {
if (msg.sendStatus === 'loading') {
msg.sendStatus = 'fail';
@ -335,29 +447,37 @@ export default class MsbIm {
* 主动创建会话
* @param {*} params
*/
async createSession (params){
const { result, error } = await ToAsyncAwait(this[send]({
traceId : CreateUUID(),
traceType : 21,
...params
}));
async createSession(params) {
const par = {
traceId: CreateUUID(),
traceType: 9,
...params,
};
console.log('[im] 主动创建会话--start', par);
const { result, error } = await ToAsyncAwait(this[send](par));
console.log('[im] 主动创建会话--end', result, error);
if (error) {
return Promise.reject(error);
}
const { content } = result;
let historyData = this.sessionData;
let curSession = historyData.find(i => i.id === content.id);
let curSession = historyData.find((i) => i.id === content.id);
if (!curSession) {
curSession = {
...content,
unreadCount: 0,
messageList : []
}
messageList: [],
};
const newData = [...historyData, curSession];
this.setSessionData(newData);
}
return Promise.resolve(result);
}
close() {
this.socket.close();
this.socket = null;
this.isOpen = false;
this.setSessionData([]);
}
}
export default MsbIm;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-22 18:28:52
* @LastEditors: ch
* @LastEditTime: 2022-06-10 16:51:08
* @LastEditTime: 2022-06-14 17:33:42
* @Description: file content
*/
import Vue from 'vue'

@ -2,13 +2,14 @@
* @Author: ch
* @Date: 2022-05-20 11:00:07
* @LastEditors: ch
* @LastEditTime: 2022-05-23 14:54:50
* @LastEditTime: 2022-06-13 10:11:33
* @Description: file content
*/
import MsbIm from '@/common/plugins/msbIm' ;
import { ToAsyncAwait } from '@/common/utils';
import { ToAsyncAwait, FormatJsonSearch } from '@/common/utils';
import { ApiGetCurrentUser } from '@/common/api/account';
import { ApiGetSoketTicket } from '@/common/api/im';
import $store from '@/common/store';
import ENV from '@/common/config/env';
@ -16,13 +17,21 @@ const Im = new MsbIm({
reconnect: true,
});
const ImInit = async () => {
const { error } = await ApiGetCurrentUser();
const { error, result } = await ApiGetSoketTicket();
if (error) {
return false;
}
const par = FormatJsonSearch({
client: result.client,
ticket: result.ticket,
// 1普通用户 2客服链接
connect: 1,
user: $store.state.userInfo.id,
nickname: $store.state.userInfo.nickname,
avatar : $store.state.userInfo.avatar
})
await ToAsyncAwait(Im.init({
// url: `wss://k8s-horse-gateway.mashibing.cn/ws?client=${$store.state.token}&type=1`
url: `${ENV.imUrl}/ws?client=${$store.state.token}&type=1`
url: `${ENV.imUrl}/ws${par}`
}))
};
@ -32,11 +41,10 @@ Im.interceptors.dataChangeAfter = () => {
Im.sessionData.forEach(i => {
msgCount += i.unreadCount;
})
console.log(Im.sessionData)
$store.commit('SET_IM_MSG_COUNT', msgCount);
}
Im.interceptors.onLogout = () => {
Im.interceptors.onClose = () => {
Im.setSessionData([]);
Im.setCurSessionId(null);
$store.commit('SET_IM_DATA', []);

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-17 17:42:32
* @LastEditors: ch
* @LastEditTime: 2022-06-10 16:52:26
* @LastEditTime: 2022-06-14 17:33:14
* @Description: 项目接口请求统一处理器返回一个需要token和不需要token的请求封装方法
*/
@ -82,6 +82,7 @@ const clearRepeat = (option) =>{
// 不需要token的接口封装
const MsbRequest = new MsbUniRequest();
console.log(process.env,'process.envprocess.envprocess.env');
MsbRequest.baseUrl = ENV.baseUrl;
MsbRequest.use('request', (option) => {

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-17 19:15:10
* @LastEditors: ch
* @LastEditTime: 2022-05-31 17:36:08
* @LastEditTime: 2022-06-02 14:55:45
* @Description: 一些无法归类的公共方法容器
*/
@ -11,7 +11,8 @@ import {
isPhone as IsPhone,
formatDate as FormatDate,
creatUuid as CreateUUID,
formatSearchJson as FormatSearchJson
formatSearchJson as FormatSearchJson,
formatJsonSearch as FormatJsonSearch
} from "js-util-all";
import ENV from '@/common/config/env';
@ -79,6 +80,7 @@ export {
// 时间格式化
FormatDate,
FormatSearchJson,
FormatJsonSearch,
CreateUUID,
// 防抖函数
Debounce,

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2021-07-26 23:22:16
* @LastEditors: ch
* @LastEditTime: 2022-05-23 20:55:47
* @LastEditTime: 2022-06-13 10:15:03
* @Description: file content
*/
import Vue from 'vue';
@ -16,14 +16,22 @@ import {ApiGetOpenId, ApiGetAuthUrl} from '@/common/api/wx';
import {Im, ImInit} from '@/common/utils';
import { ApiSktSysGetSession, ApiSktSysHeart } from './common/api/im';
if (store.state.token) {
const socketInit = () => {
if (!store.state.userInfo.id) {
setTimeout(() => {
socketInit();
},10000)
return false;
}
// 初始化IM
ImInit().then(() => {
// 获取到会话列表
Im.getSessionList({
content: { sysId : 1 }
});
Im.getSessionList();
});
}
if (store.state.token) {
socketInit();
}

@ -1,75 +0,0 @@
{
"name": "",
"appid": "",
"description": "",
"versionName": "1.0.0",
"versionCode": "100",
"transformPx": false,
"app-plus": { /* 5+App */
"usingComponents": true,
"splashscreen": {
"alwaysShowBeforeRender": true,
"waiting": true,
"autoclose": true,
"delay": 0
},
"modules": { /* */
},
"distribute": { /* */
"android": { /* android */
"permissions": ["<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
"ios": { /* ios */
},
"sdkConfigs": { /* SDK */
}
}
},
"quickapp": { /* */
},
"mp-weixin": { /* */
"appid": "",
"setting": {
"urlCheck": false
},
"usingComponents": true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"mp-qq" : {
"usingComponents" : true
}
}

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-26 14:32:03
* @LastEditors: ch
* @LastEditTime: 2022-05-30 17:49:28
* @LastEditTime: 2022-06-14 17:13:17
* @Description: file content
-->
<template>
@ -11,6 +11,7 @@
<view class="send" :key="item.id" v-if="item.fromId == $store.state.userInfo.id">
<text class="send--status" v-if="item.sendStatus === 'loading'"></text>
<text class="send--status send--status__fail" v-if="item.sendStatus === 'fail'" @click="resend(item)"></text>
<template v-if="item.type == MSG_TYPE.CUSTOM">
<GoodsInfo class="send--box" position="msg" v-if="item.payload.id" :goodsInfo="item.payload"/>
<OrderInfo class="send--box" position="msg" v-if="item.payload.orderId" :orderInfo="item.payload"/>
@ -26,6 +27,9 @@
<view class="tips" :key="item.id" v-else-if="item.type == MSG_TYPE.TIP">
<view class="tips--box">{{item.payload.text}}</view>
</view>
<view class="tips" :key="item.id" v-else-if="item.type === MSG_TYPE.CUSTOM && item.payload.customType == 'transferWaiterSession'">
<view class="tips--box">现在由客服{{item.payload.toNickname}}为您服务</view>
</view>
<view class="receive" :key="item.id" v-else>
<image class="avatar" :src="item.fromAvatar || require('@/static/message/xt.png')" mode="widthFix"/>
<view>
@ -80,6 +84,9 @@ export default {
return this.curSessionData ? this.curSessionData.messageList : [];
}
},
destroyed(){
Im.setCurSessionId(null);
},
watch:{
msgData(){
this.$nextTick(()=>{
@ -108,12 +115,7 @@ export default {
this.orderId = this.$Route.query.orderId;
this.sessionId = this.$Route.query.sessionId;
if(this.sessionId){
this.getHistoryMsg();
this.readMsg();
}else{
this.createSessionMain();
}
this.socketInit();
if(this.goodsId){
this.getGoodsInfo();
}
@ -129,14 +131,35 @@ export default {
},
methods:{
socketInit(){
if(!Im.isOpen){
setTimeout(()=>{
this.socketInit();
}, 100)
return false;
}
if(this.sessionId){
if(!this.msgData?.length){
this.getHistoryMsg();
}
this.readMsg();
}else{
this.createSessionMain();
}
},
/**
* 创建会话主体
* 如果是从商品或订单进来需要创建会话
*/
async createSessionMain(){
if(!Im.isOpen){
setTimeout(()=>this.createSessionMain(),1000);
return false;
}
const {error, result} = await ToAsyncAwait(Im.createSession({
content : {
storeId : 1
sessionType : 3
}
}));
@ -144,23 +167,24 @@ export default {
uni.$u.toast(error.message);
return false;
}
this.sessionId = result.content.id
this.sessionId = result.content.id;
Im.setCurSessionId(this.sessionId);
this.getHistoryMsg();
this.readMsg();
// this.readMsg();
},
/**
* 获取历史消息
*/
async getHistoryMsg(){
this.loading = true;
const lastMsg = this.msgData?.length ? this.msgData[0] : {};
const {error, result} = await ToAsyncAwait(Im.getHistoryMsg({
content : {
sessionId : this.sessionId,
topMessageId : lastMsg.id || null
if(!this.curSessionData.id){
setTimeout(()=>{
this.getHistoryMsg();
}, 500)
return false;
}
}));
this.loading = true;
const {error, result} = await ToAsyncAwait(Im.getHistoryMsg());
if(error){
uni.$u.toast(error.errMsg || error.message);
return false
@ -178,6 +202,7 @@ export default {
}));
if(error){
uni.$u.toast(error.errMsg || error.message);
console.log(error);
return false
}
@ -252,6 +277,7 @@ page{
color: #333;
font-size: 32rpx;
line-height: 40rpx;
word-break: break-all;
}
&__img{
height: 140rpx;

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-05-11 11:45:08
* @LastEditors: ch
* @LastEditTime: 2022-05-24 22:54:29
* @LastEditTime: 2022-06-14 12:55:27
* @Description: file content
-->
<template>
@ -158,11 +158,11 @@ export default {
this.msgCtx += str;
},
sendGoods(){
this.send(this.simpleGoods, MSG_TYPE.CUSTOM);
this.send({...this.simpleGoods, customType:'goodsInfo'}, MSG_TYPE.CUSTOM);
this.goodsShow = false;
},
sendOrder(){
this.send(this.simpleOrder, MSG_TYPE.CUSTOM);
this.send({...this.simpleOrder, customType : 'orderInfo'}, MSG_TYPE.CUSTOM);
this.orderShow = false;
},
uploadImg(val){

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-22 16:13:00
* @LastEditors: ch
* @LastEditTime: 2022-05-27 15:32:18
* @LastEditTime: 2022-06-14 17:12:37
* @Description: file content
-->
<template>
@ -18,11 +18,14 @@
<text class="msgItem--text" v-if="item.lastMessage">
<template v-if="item.lastMessage.type == msgType.TXT">{{item.lastMessage.payload.content || item.lastMessage.payload.text}}</template>
<template v-if="item.lastMessage.type == msgType.CUSTOM">
<template v-if="item.lastMessage.payload.customType === 'orderAutoDelivery'">
<template v-if="['returnLogistics','orderAutoDelivery'].includes(item.lastMessage.payload.customType)">
{{item.lastMessage.payload.content}}
</template>
<template v-else>
[链接]
<template v-if="item.lastMessage.payload.customType === 'app_push'">
{{item.lastMessage.payload.link ? '[链接]' : item.lastMessage.payload.content}}
</template>
<template v-if="item.lastMessage.payload.customType === 'transferWaiterSession'">
[客服转移]
</template>
</template>
<template v-if="item.lastMessage.type == msgType.IMG">[]</template>
@ -40,7 +43,7 @@
<script>
import BsEmpty from '../../../components/BsEmpty.vue';
import {MSG_TYPE} from '@/common/dicts/im';
import {FormatDate} from '@/common/utils';
import {FormatDate, Im} from '@/common/utils';
export default {
components: { BsEmpty },
data (){
@ -56,18 +59,20 @@ export default {
},
computed:{
sessionData (){
return this.$store.state.imData;
return this.$store.state.imData.sort((a,b) => b.updateTimeStamp - a.updateTimeStamp);
}
},
methods:{
FormatDate,
openMsg(item){
if(item.type === 3){
this.$Router.push(`/messageChat?sessionId=${item.id}`);
}else{
Im.setCurSessionId(item.id);
if(item.type === 4){
if(JSON.parse(item.payload).type === 'system'){
this.$Router.push(`/messageSystem?sessionId=${item.id}`);
return false;
}
}
this.$Router.push(`/messageChat?sessionId=${item.id}`);
}
}
}
@ -107,6 +112,7 @@ export default {
display:-webkit-box;
-webkit-box-orient:vertical;
-webkit-line-clamp:2;
}
&--right{
text-align: right;

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-26 14:32:03
* @LastEditors: ch
* @LastEditTime: 2022-05-27 17:02:59
* @LastEditTime: 2022-06-02 18:07:09
* @Description: file content
-->
<template>
@ -21,7 +21,6 @@
<text class="msg-item--desc-link" v-if="i.shipType === 1" @click="openLink(i)" :key="i.shipContent">[]</text>
<text v-else :key="i.shipContent">{{i.shipContent}}</text>
</template>
</template>
</view>
</view>
@ -78,13 +77,7 @@ export default {
},
async getHistoryMsg(){
this.loading = true;
const lastMsg = this.msgData?.length ? this.msgData[this.msgData.length - 1] : {};
await ToAsyncAwait(Im.getHistoryMsg({
content : {
sessionId : this.$route.query.sessionId,
topMessageId : lastMsg.id || null
}
}));
await ToAsyncAwait(Im.getHistoryMsg());
},
/**
* 把当前会话消息置为已读

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-22 15:09:06
* @LastEditors: ch
* @LastEditTime: 2022-05-24 17:24:35
* @LastEditTime: 2022-06-12 13:46:04
* @Description: file content
-->
<template>
@ -43,7 +43,7 @@ export default {
return false;
}
this.$store.commit('SET_TOKEN');
Im.logout();
Im.close();
this.$Router.replace('/login');
}
}

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-28 15:38:23
* @LastEditors: ch
* @LastEditTime: 2022-05-17 11:44:50
* @LastEditTime: 2022-06-13 20:49:32
* @Description: file content
-->
<template>
@ -38,7 +38,7 @@ export default {
nickname : this.userInfo.nickname
});
if(error){
ui.$u.totas(error.message);
uni.$u.toast(error.message);
return false;
}
this.$store.commit('SET_USER_INFO', {...this.userInfo});

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-28 15:38:23
* @LastEditors: ch
* @LastEditTime: 2022-05-24 09:57:14
* @LastEditTime: 2022-06-13 20:59:54
* @Description: file content
-->
<template>
@ -106,7 +106,7 @@ export default {
const avatar = `${oss.host}/${oss.dir}${fileName}`;
const {error, result} = await ApiPutUser({avatar});
if(error){
ui.$u.totas(error.message);
uni.$u.toast(error.message);
return false
}
this.$store.commit('SET_USER_INFO', {...this.userInfo, avatar});

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-23 17:27:21
* @LastEditors: ch
* @LastEditTime: 2022-05-30 17:44:24
* @LastEditTime: 2022-06-02 14:39:30
* @Description: file content
-->
<template>
@ -169,10 +169,7 @@ page {
width: 50rpx;
height: 50rpx;
left: 40rpx;
/* #ifdef H5 */
top: 40rpx;
/* #endif */
/* #ifndef H5 */
top: 128rpx;
/* #endif */

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2019-08-22 19:41:20
* @LastEditors: ch
* @LastEditTime: 2022-05-31 17:35:15
* @LastEditTime: 2022-06-13 14:25:25
* @Description: file content
-->
<template>
@ -113,7 +113,7 @@ export default {
async getSeckillList(){
const {error, result} = await ApiGetHomeSeckill();
if(result){
this.seckillData = result
this.seckillData = result;
}
},
AdJump

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-22 15:36:46
* @LastEditors: ch
* @LastEditTime: 2022-05-24 09:57:06
* @LastEditTime: 2022-06-13 10:20:21
* @Description: file content
-->
<template>
@ -119,9 +119,7 @@ export default {
// IM
ImInit().then(() => {
//
Im.getSessionList({
content: { sysId : 1 }
});
Im.getSessionList();
});
this.goBack();

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-21 18:08:07
* @LastEditors: ch
* @LastEditTime: 2022-05-05 10:52:27
* @LastEditTime: 2022-06-13 14:25:12
* @Description: file content
-->
<template>

Loading…
Cancel
Save