mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-08-06 02:47:29 +08:00
fix(buyer): 未登录联系客服时提示登录
- 将登录提示由 Message 改为 Modal - 新增 promptLogin 方法处理登录跳转 - IMService 增加 accessToken 校验,未登录时提示登录 - 改进用户信息获取的错误处理 - 重构 IM 链接 URL 拼接,提升可读性
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Message } from "@/utils/message";
|
||||
import { Modal } from "@/utils/message";
|
||||
import { getIMDetail } from "@/api/common";
|
||||
import Storage from "@/plugins/storage";
|
||||
import { getMemberMsg } from "@/api/login";
|
||||
@@ -15,28 +15,52 @@ export default {
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
promptLogin() {
|
||||
Modal.confirm({
|
||||
title: "温馨提示",
|
||||
content: "请登录后执行此操作",
|
||||
okText: "立即登录",
|
||||
cancelText: "取消",
|
||||
onOk: () => {
|
||||
this.$router.push({
|
||||
path: "/login",
|
||||
query: {
|
||||
rePath: this.$route.path,
|
||||
query: JSON.stringify(this.$route.query || {}),
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
// 跳转im客服
|
||||
async IMService(id, goodsId, skuId) {
|
||||
if (!Storage.getItem("accessToken")) {
|
||||
this.promptLogin();
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取访问Token
|
||||
let accessToken = Storage.getItem("accessToken");
|
||||
await this.getIMDetailMethods();
|
||||
const userInfo = await getMemberMsg();
|
||||
if (userInfo.success) {
|
||||
//携带商品Id,在IM可以发送商品信息
|
||||
if(goodsId && skuId){
|
||||
window.open(
|
||||
this.IMLink + "?token=" + accessToken + "&id=" + (id || this.storeMsg.storeId) + "&goodsId=" + goodsId + "&skuId=" + skuId
|
||||
);
|
||||
}else{
|
||||
window.open(
|
||||
this.IMLink + "?token=" + accessToken + "&id=" + (id || this.storeMsg.storeId)
|
||||
);
|
||||
try {
|
||||
await this.getIMDetailMethods();
|
||||
const userInfo = await getMemberMsg();
|
||||
if (!userInfo.success) {
|
||||
this.promptLogin();
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
Message.error("请登录后再联系客服");
|
||||
return;
|
||||
const accessToken = Storage.getItem("accessToken");
|
||||
const storeId = id || this.storeMsg?.storeId;
|
||||
const baseUrl = `${this.IMLink}?token=${accessToken}&id=${storeId}`;
|
||||
|
||||
if (goodsId && skuId) {
|
||||
window.open(`${baseUrl}&goodsId=${goodsId}&skuId=${skuId}`);
|
||||
} else {
|
||||
window.open(baseUrl);
|
||||
}
|
||||
} catch {
|
||||
// token 过期等场景由 request 拦截器处理;未登录时避免未捕获异常
|
||||
if (!Storage.getItem("accessToken")) {
|
||||
this.promptLogin();
|
||||
}
|
||||
}
|
||||
},
|
||||
// 获取im信息
|
||||
|
||||
@@ -284,7 +284,7 @@ export default {
|
||||
// 跳转店铺首页
|
||||
goShopPage(id) {
|
||||
let routeUrl = this.$router.resolve({
|
||||
path: "/Merchant",
|
||||
path: "/merchant",
|
||||
query: { id },
|
||||
});
|
||||
window.open(routeUrl.href, "_blank");
|
||||
|
||||
@@ -177,7 +177,7 @@ export default {
|
||||
let url
|
||||
if (this.params.type === 'STORE') {
|
||||
url = this.$router.resolve({
|
||||
path: '/Merchant',
|
||||
path: '/merchant',
|
||||
query: { 'id': storeId }
|
||||
})
|
||||
} else {
|
||||
|
||||
@@ -198,7 +198,7 @@ export default {
|
||||
// 跳转店铺首页
|
||||
shopPage(id) {
|
||||
let routeUrl = this.$router.resolve({
|
||||
path: '/Merchant',
|
||||
path: '/merchant',
|
||||
query: {id: id}
|
||||
});
|
||||
window.open(routeUrl.href, '_blank');
|
||||
|
||||
@@ -265,7 +265,7 @@ export default {
|
||||
// 跳转店铺首页
|
||||
shopPage (id) {
|
||||
let routeUrl = this.$router.resolve({
|
||||
path: '/Merchant',
|
||||
path: '/merchant',
|
||||
query: { id: id }
|
||||
});
|
||||
window.open(routeUrl.href, '_blank');
|
||||
|
||||
@@ -424,7 +424,7 @@ export default {
|
||||
// 跳转店铺首页
|
||||
shopPage(id) {
|
||||
let routeUrl = this.$router.resolve({
|
||||
path: "/Merchant",
|
||||
path: "/merchant",
|
||||
query: { id: id },
|
||||
});
|
||||
window.open(routeUrl.href, "_blank");
|
||||
|
||||
@@ -71,7 +71,7 @@ export default {
|
||||
// 跳转店铺首页
|
||||
shopPage(id) {
|
||||
let routeUrl = this.$router.resolve({
|
||||
path: "/Merchant",
|
||||
path: "/merchant",
|
||||
query: { id: id },
|
||||
});
|
||||
window.open(routeUrl.href, "_blank");
|
||||
|
||||
@@ -794,7 +794,7 @@ export default {
|
||||
// 跳转店铺首页
|
||||
goShopPage(id) {
|
||||
let routeUrl = this.$router.resolve({
|
||||
path: "/Merchant",
|
||||
path: "/merchant",
|
||||
query: { id: id },
|
||||
});
|
||||
window.open(routeUrl.href, "_blank");
|
||||
|
||||
@@ -17,31 +17,35 @@ export const ServeGetUserDetail = (memberId) => {
|
||||
};
|
||||
|
||||
// 获取店铺相关设置信息
|
||||
export const ServeGetStoreDetail = (storeId) => {
|
||||
return get(`${config.BASE_BUYER}/buyer/store/store/store/${storeId}`);
|
||||
export const ServeGetStoreDetail = (storeId, options = {}) => {
|
||||
return get(`${config.BASE_BUYER}/buyer/store/store/store/${storeId}`, {}, options);
|
||||
};
|
||||
|
||||
// 获取用户历史足迹
|
||||
export const ServeGetFootPrint = (params) => {
|
||||
return get(`${config.BASE_BUYER}/buyer/member/footprint`, params);
|
||||
export const ServeGetFootPrint = (params, options = {}) => {
|
||||
return get(`${config.BASE_BUYER}/buyer/member/footprint`, params, options);
|
||||
};
|
||||
|
||||
// 商家获取用户历史足迹
|
||||
export const ServeStoreGetFootPrint = (params) => {
|
||||
return get(`${config.BASE_SELLER}/store/member/footprint`, params);
|
||||
export const ServeStoreGetFootPrint = (params, options = {}) => {
|
||||
return get(`${config.BASE_SELLER}/store/member/footprint`, params, options);
|
||||
};
|
||||
|
||||
// 获取用户订单列表信息
|
||||
export const ServeGetOrderPrint = (params) => {
|
||||
return get(`${config.BASE_BUYER}/buyer/order/order`, params);
|
||||
export const ServeGetOrderPrint = (params, options = {}) => {
|
||||
return get(`${config.BASE_BUYER}/buyer/order/order`, params, options);
|
||||
};
|
||||
|
||||
// 商家获取用户订单列表信息
|
||||
export const ServeStoreGetOrderPrint = (params) => {
|
||||
return get(`${config.BASE_SELLER}/store/order/order`, params);
|
||||
export const ServeStoreGetOrderPrint = (params, options = {}) => {
|
||||
return get(`${config.BASE_SELLER}/store/order/order`, params, options);
|
||||
};
|
||||
|
||||
// 获取商品信息
|
||||
export const ServeGetGoodsDetail = (data) => {
|
||||
return get(`${config.BASE_BUYER}/buyer/goods/goods/sku/${data.goodsId}/${data.skuId}`);
|
||||
export const ServeGetGoodsDetail = (data, options = {}) => {
|
||||
return get(
|
||||
`${config.BASE_BUYER}/buyer/goods/goods/sku/${data.goodsId}/${data.skuId}`,
|
||||
{},
|
||||
options
|
||||
);
|
||||
};
|
||||
|
||||
@@ -17,17 +17,29 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ServeGetStoreDetail, ServeGetUserDetail, ServeGetFootPrint, ServeGetOrderPrint, ServeGetGoodsDetail, ServeStoreGetFootPrint,ServeStoreGetOrderPrint } from '@/api/user'
|
||||
import {
|
||||
ServeGetStoreDetail,
|
||||
ServeGetFootPrint,
|
||||
ServeGetOrderPrint,
|
||||
ServeGetGoodsDetail,
|
||||
ServeStoreGetFootPrint,
|
||||
ServeStoreGetOrderPrint,
|
||||
} from "@/api/user";
|
||||
import StoreDetail from "@/components/chat/panel/template/storeDetail.vue";
|
||||
import FootPrint from "@/components/chat/panel/template/footPrint.vue";
|
||||
import GoodsLink from "@/components/chat/panel/template/goodsLink.vue";
|
||||
import SocketInstance from "@/im-server/socket-instance";
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
import { getToken } from "@/utils/auth";
|
||||
import { isBuyerImMode } from "@/utils/im-mode";
|
||||
|
||||
const SIDE_REQUEST_OPTIONS = { skipAuthDialog: true };
|
||||
|
||||
export default {
|
||||
components: {
|
||||
StoreDetail,
|
||||
FootPrint,
|
||||
GoodsLink
|
||||
GoodsLink,
|
||||
},
|
||||
props: {
|
||||
toUser: {
|
||||
@@ -36,7 +48,7 @@ export default {
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
default: "",
|
||||
},
|
||||
goodsParams: {
|
||||
type: Object,
|
||||
@@ -48,167 +60,173 @@ export default {
|
||||
...mapState({
|
||||
index_name: (state) => state.dialogue.index_name,
|
||||
}),
|
||||
isBuyerImMode() {
|
||||
return isBuyerImMode(this.$route);
|
||||
},
|
||||
},
|
||||
watch:{
|
||||
toUser(){
|
||||
localStorage.setItem('storeFlag', this.toUser.storeFlag)
|
||||
this.footPrintList = []
|
||||
this.orderPrintList = []
|
||||
this.footPrintParams.pageNumber = 1
|
||||
watch: {
|
||||
toUser() {
|
||||
this.syncStoreFlagCache();
|
||||
this.resetSidePanelData();
|
||||
if (this.toUser.storeFlag) {
|
||||
this.getStoreDetail()
|
||||
}
|
||||
// else {
|
||||
// this.getMemberDetail()
|
||||
// }
|
||||
this.getFootPrint()
|
||||
if (this.goodsParams && this.toUser.storeFlag == true) {
|
||||
this.getGoodsDetail()
|
||||
this.getStoreDetail();
|
||||
}
|
||||
}
|
||||
this.getFootPrint();
|
||||
if (this.goodsParams && this.toUser.storeFlag) {
|
||||
this.getGoodsDetail();
|
||||
}
|
||||
},
|
||||
},
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
activeName: 'history',
|
||||
storeInfo: {}, //店铺信息
|
||||
memberInfo: {}, //会员信息
|
||||
activeName: "history",
|
||||
storeInfo: {},
|
||||
memberInfo: {},
|
||||
footPrintParams: {
|
||||
pageSize: 20,
|
||||
pageNumber: 1,
|
||||
memberId: '',
|
||||
storeId: '',
|
||||
memberId: "",
|
||||
storeId: "",
|
||||
},
|
||||
goodsDetail: {},
|
||||
footPrintList: [], // 商品
|
||||
orderPrintList: []// 订单
|
||||
}
|
||||
footPrintList: [],
|
||||
orderPrintList: [],
|
||||
};
|
||||
},
|
||||
mounted () {
|
||||
localStorage.setItem('storeFlag', this.toUser.storeFlag)
|
||||
mounted() {
|
||||
this.syncStoreFlagCache();
|
||||
if (this.toUser.storeFlag) {
|
||||
this.getStoreDetail()
|
||||
}
|
||||
// else {
|
||||
// this.getMemberDetail()
|
||||
// }
|
||||
this.getFootPrint()
|
||||
if (this.goodsParams && this.toUser.storeFlag == true) {
|
||||
this.getGoodsDetail()
|
||||
this.getStoreDetail();
|
||||
}
|
||||
this.getFootPrint();
|
||||
if (this.goodsParams && this.toUser.storeFlag) {
|
||||
this.getGoodsDetail();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getStoreDetail () {
|
||||
ServeGetStoreDetail(this.toUser.userId).then(res => {
|
||||
if (res.success) {
|
||||
this.storeInfo = res.result
|
||||
}
|
||||
})
|
||||
syncStoreFlagCache() {
|
||||
localStorage.setItem(
|
||||
"storeFlag",
|
||||
this.isBuyerImMode ? "true" : "false"
|
||||
);
|
||||
},
|
||||
loadMoreFootPrint (e) {
|
||||
//触底再次调接口
|
||||
this.footPrintParams.pageNumber++
|
||||
this.getFootPrint()
|
||||
resetSidePanelData() {
|
||||
this.footPrintList = [];
|
||||
this.orderPrintList = [];
|
||||
this.footPrintParams.pageNumber = 1;
|
||||
},
|
||||
handleClick () { },
|
||||
// getMemberDetail () {
|
||||
// ServeGetUserDetail(this.toUser.userId).then(res => {
|
||||
// if (res.success) {
|
||||
// this.memberInfo = res.result
|
||||
// }
|
||||
// })
|
||||
// },
|
||||
getGoodsDetail () {
|
||||
// 检查必要参数是否存在
|
||||
getStoreDetail() {
|
||||
ServeGetStoreDetail(this.toUser.userId, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.storeInfo = res.result;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
loadMoreFootPrint() {
|
||||
this.footPrintParams.pageNumber++;
|
||||
this.getFootPrint();
|
||||
},
|
||||
handleClick() {},
|
||||
getGoodsDetail() {
|
||||
if (!this.toUser.storeFlag) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.goodsParams || !this.goodsParams.goodsId) {
|
||||
console.warn('getGoodsDetail: goodsParams 或 goodsId 参数缺失')
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
ServeGetGoodsDetail(this.goodsParams).then(res => {
|
||||
if (res.success) {
|
||||
this.goodsDetail = res.result.data
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error('获取商品详情失败:', error)
|
||||
})
|
||||
ServeGetGoodsDetail(this.goodsParams, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.goodsDetail = res.result.data;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
normalizeFootPrintRecords(records = []) {
|
||||
const goodsId = this.goodsParams?.goodsId;
|
||||
return records
|
||||
.filter((item) => item != null)
|
||||
.filter((item) => !goodsId || item.goodsId !== goodsId)
|
||||
.map((item) => ({
|
||||
...item,
|
||||
btnHide: localStorage.getItem(item.goodsId) ? 0 : 1,
|
||||
}));
|
||||
},
|
||||
normalizeOrderRecords(records = []) {
|
||||
return records.map((item) => ({
|
||||
...item,
|
||||
btnHide: 1,
|
||||
}));
|
||||
},
|
||||
getFootPrint() {
|
||||
if (this.toUser.storeFlag) {
|
||||
this.footPrintParams.memberId = this.id
|
||||
this.footPrintParams.storeId = this.toUser.userId
|
||||
ServeGetFootPrint(this.footPrintParams).then(res => {
|
||||
res.result.records=res.result.records.filter((item)=>{
|
||||
return item!=null
|
||||
})
|
||||
res.result.records.forEach((item, index) => {
|
||||
if (localStorage.getItem(item.goodsId)) {
|
||||
item.btnHide = 0
|
||||
} else {
|
||||
item.btnHide = 1
|
||||
}
|
||||
if (item.goodsId === this.goodsParams.goodsId) {
|
||||
res.result.records.splice(index, 1)
|
||||
}
|
||||
});
|
||||
this.footPrintList.push(...res.result.records)
|
||||
})
|
||||
// 订单列表
|
||||
ServeGetOrderPrint(this.footPrintParams).then((res) => {
|
||||
if (res.code == 200) {
|
||||
res.result.records.forEach((item) => {
|
||||
this.orderPrintList.push({
|
||||
...item,
|
||||
btnHide: 1
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
if (!getToken()) {
|
||||
return;
|
||||
}
|
||||
if (!this.toUser?.userId || !this.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isBuyerImMode) {
|
||||
this.footPrintParams.memberId = this.id;
|
||||
this.footPrintParams.storeId = this.toUser.userId;
|
||||
this.fetchBuyerSideData();
|
||||
} else {
|
||||
this.footPrintParams.memberId = this.toUser.userId
|
||||
this.footPrintParams.storeId = this.id
|
||||
ServeStoreGetFootPrint(this.footPrintParams).then(res => {
|
||||
res.result.records=res.result.records.filter((item)=>{
|
||||
return item!=null
|
||||
})
|
||||
res.result.records.forEach((item, index) => {
|
||||
if (localStorage.getItem(item.goodsId)) {
|
||||
item.btnHide = 0
|
||||
} else {
|
||||
item.btnHide = 1
|
||||
}
|
||||
if (item.goodsId === this.goodsParams.goodsId) {
|
||||
res.result.records.splice(index, 1)
|
||||
}
|
||||
});
|
||||
this.footPrintList.push(...res.result.records)
|
||||
})
|
||||
ServeStoreGetOrderPrint(this.footPrintParams).then((res) => {
|
||||
if (res.code == 200) {
|
||||
res.result.records.forEach((item) => {
|
||||
this.orderPrintList.push({
|
||||
...item,
|
||||
btnHide: 1
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
this.footPrintParams.memberId = this.toUser.userId;
|
||||
this.footPrintParams.storeId = this.id;
|
||||
this.fetchStoreSideData();
|
||||
}
|
||||
},
|
||||
fetchBuyerSideData() {
|
||||
ServeGetFootPrint(this.footPrintParams, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res?.result?.records) {
|
||||
this.footPrintList.push(
|
||||
...this.normalizeFootPrintRecords(res.result.records)
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
|
||||
// 发送消息回调事件
|
||||
submitSendMessage (record, context, messageType) {
|
||||
ServeGetOrderPrint(this.footPrintParams, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res?.code === 200 && res?.result?.records) {
|
||||
this.orderPrintList.push(
|
||||
...this.normalizeOrderRecords(res.result.records)
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
fetchStoreSideData() {
|
||||
ServeStoreGetFootPrint(this.footPrintParams, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res?.result?.records) {
|
||||
this.footPrintList.push(
|
||||
...this.normalizeFootPrintRecords(res.result.records)
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
|
||||
ServeStoreGetOrderPrint(this.footPrintParams, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res?.code === 200 && res?.result?.records) {
|
||||
this.orderPrintList.push(
|
||||
...this.normalizeOrderRecords(res.result.records)
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
|
||||
submitSendMessage(record, context, messageType) {
|
||||
SocketInstance.emit("event_talk", record);
|
||||
this.$store.commit("UPDATE_TALK_ITEM", {
|
||||
index_name: this.index_name,
|
||||
draft_text: "",
|
||||
});
|
||||
/**
|
||||
* 插入数据
|
||||
*/
|
||||
const insterChat = {
|
||||
createTime: this.formateDateAndTimeToString(new Date()),
|
||||
fromUser: this.id,
|
||||
@@ -219,11 +237,8 @@ export default {
|
||||
float: "right",
|
||||
};
|
||||
|
||||
// 插入对话记录
|
||||
this.$store.commit("PUSH_DIALOGUE", insterChat);
|
||||
// 获取聊天面板元素节点
|
||||
let el = document.getElementById("lumenChatPanel");
|
||||
// 判断的滚动条是否在底部
|
||||
let isBottom =
|
||||
Math.ceil(el.scrollTop) + el.clientHeight >= el.scrollHeight;
|
||||
|
||||
@@ -233,14 +248,13 @@ export default {
|
||||
});
|
||||
} else {
|
||||
this.$store.commit("SET_TLAK_UNREAD_MESSAGE", {
|
||||
content: content,
|
||||
content: context,
|
||||
nickname: record.name,
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
formateDateAndTimeToString (date) {
|
||||
formateDateAndTimeToString(date) {
|
||||
var hours = date.getHours();
|
||||
var mins = date.getMinutes();
|
||||
var secs = date.getSeconds();
|
||||
@@ -254,7 +268,7 @@ export default {
|
||||
);
|
||||
},
|
||||
|
||||
formatDateToString (date) {
|
||||
formatDateToString(date) {
|
||||
var year = date.getFullYear();
|
||||
var month = date.getMonth() + 1;
|
||||
var day = date.getDate();
|
||||
@@ -262,15 +276,11 @@ export default {
|
||||
if (day < 10) day = "0" + day;
|
||||
return year + "-" + month + "-" + day;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
// :deep(.el-tabs__nav.is-top ) {
|
||||
// }
|
||||
|
||||
:deep(.el-tabs__nav ) {
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
|
||||
@@ -284,6 +284,9 @@ export default {
|
||||
|
||||
// 置底按钮是否显示
|
||||
tipsBoard: false,
|
||||
|
||||
// 防止并发请求导致 loading 状态错乱
|
||||
recordsRequestId: 0,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -301,22 +304,15 @@ export default {
|
||||
}),
|
||||
},
|
||||
watch: {
|
||||
// 监听面板传递参数
|
||||
params () {
|
||||
this.loadRecord.minRecord = 0;
|
||||
this.tipsBoard = false;
|
||||
this.multiSelect = {
|
||||
isOpen: false,
|
||||
items: [],
|
||||
mode: 0,
|
||||
};
|
||||
this.loadChatRecords();
|
||||
|
||||
// 监听面板传递参数(含首次挂载)
|
||||
params: {
|
||||
handler () {
|
||||
this.resetRecordState();
|
||||
this.loadChatRecords();
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.loadChatRecords();
|
||||
},
|
||||
methods: {
|
||||
parseTime,
|
||||
sendTime: formatTime,
|
||||
@@ -496,27 +492,49 @@ export default {
|
||||
|
||||
|
||||
|
||||
resetRecordState () {
|
||||
this.loadRecord.minRecord = 0;
|
||||
this.loadRecord.pageNumber = 0;
|
||||
this.tipsBoard = false;
|
||||
this.multiSelect = {
|
||||
isOpen: false,
|
||||
items: [],
|
||||
mode: 0,
|
||||
};
|
||||
},
|
||||
|
||||
// 加载用户聊天详情信息
|
||||
loadChatRecords () {
|
||||
if (this.loadRecord.pageNumber === 0 || this.params.clickFlag) {
|
||||
this.loadRecord.pageNumber = 1
|
||||
this.params.clickFlag = false
|
||||
} else {
|
||||
this.loadRecord.pageNumber = this.loadRecord.pageNumber + 1
|
||||
if (!this.params.talkId) {
|
||||
this.loadRecord.status = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
const isFirstPage = this.loadRecord.pageNumber === 0;
|
||||
if (isFirstPage) {
|
||||
this.loadRecord.pageNumber = 1;
|
||||
} else {
|
||||
this.loadRecord.pageNumber = this.loadRecord.pageNumber + 1;
|
||||
}
|
||||
|
||||
const user_id = this.id;
|
||||
const data = {
|
||||
pageNumber: this.loadRecord.pageNumber,
|
||||
pageSize: this.loadChatRecords.pageSize,
|
||||
pageSize: this.loadRecord.pageSize,
|
||||
talkId: this.params.talkId,
|
||||
};
|
||||
this.loadRecord.status = 0;
|
||||
|
||||
let el = document.getElementById('lumenChatPanel')
|
||||
let scrollHeight = el.scrollHeight
|
||||
const requestId = ++this.recordsRequestId;
|
||||
let el = document.getElementById('lumenChatPanel');
|
||||
let scrollHeight = el ? el.scrollHeight : 0;
|
||||
|
||||
ServeTalkRecords(data).then((res) => {
|
||||
// 防止点击切换过快消息返回延迟,导致信息错误
|
||||
// console.log("读取历史数据", res);
|
||||
if (requestId !== this.recordsRequestId) return;
|
||||
if (res.code !== 200 || !Array.isArray(res.result)) {
|
||||
this.loadRecord.status = 2;
|
||||
return;
|
||||
}
|
||||
const records = res.result.map((item) => {
|
||||
let key = new Date().getTime();
|
||||
item.float = "center";
|
||||
@@ -524,28 +542,26 @@ export default {
|
||||
item.float = item.fromUser == user_id ? "right" : "left";
|
||||
}
|
||||
if (item.messageType == 'GOODS') {
|
||||
item.text = JSON.parse(item.text)
|
||||
item.text = JSON.parse(item.text);
|
||||
}
|
||||
// if (item.messageType == 'MESSAGE"') {
|
||||
// item.text = this.textReplaceEmoji(item.text)
|
||||
// }
|
||||
if (item.messageType == 'ORDER') {
|
||||
item.text = JSON.parse(item.text)
|
||||
item.text = JSON.parse(item.text);
|
||||
}
|
||||
return { ...item, [key]: key };
|
||||
});
|
||||
this.$store.commit("UNSHIFT_DIALOGUE", records);
|
||||
records.length
|
||||
? (this.loadRecord.status = 1)
|
||||
: (this.loadRecord.status = 2);
|
||||
this.loadRecord.status = records.length ? 1 : 2;
|
||||
this.$nextTick(() => {
|
||||
// if (data.record_id == 0 || !data.record_id) {
|
||||
if (data.record_id == 0 || data.pageNumber == 1) {
|
||||
el.scrollTop = el.scrollHeight
|
||||
if (!el) return;
|
||||
if (isFirstPage) {
|
||||
el.scrollTop = el.scrollHeight;
|
||||
} else {
|
||||
el.scrollTop = el.scrollHeight - scrollHeight
|
||||
el.scrollTop = el.scrollHeight - scrollHeight;
|
||||
}
|
||||
})
|
||||
});
|
||||
}).catch(() => {
|
||||
if (requestId !== this.recordsRequestId) return;
|
||||
this.loadRecord.status = 2;
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
@confirm="confirmCodeBlock" />
|
||||
|
||||
<!-- 文件上传管理器 -->
|
||||
<MeEditorFileManage ref="filesManager" v-model:show="filesManager.isShow" />
|
||||
<MeEditorFileManage ref="fileManageRef" v-model:show="filesManager.isShow" />
|
||||
|
||||
<MeEditorVote v-if="vote.isShow" @close="
|
||||
() => {
|
||||
@@ -133,7 +133,7 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
talkUser (n_index_name) {
|
||||
this.$refs.filesManager.clear();
|
||||
this.$refs.fileManageRef?.clear();
|
||||
this.editorText = this.getDraftText(n_index_name);
|
||||
},
|
||||
},
|
||||
@@ -251,7 +251,7 @@ export default {
|
||||
|
||||
this.filesManager.isShow = true;
|
||||
this.$refs.restFile2.value = null;
|
||||
this.$refs.filesManager.upload(file);
|
||||
this.$refs.fileManageRef?.upload(file);
|
||||
},
|
||||
|
||||
// 打开图片查看器
|
||||
|
||||
@@ -48,7 +48,7 @@ app.config.globalProperties.linkToGoods = function (goodsId, skuId) {
|
||||
);
|
||||
};
|
||||
app.config.globalProperties.linkToStore = function (storeId) {
|
||||
window.open(`${config.PC_URL}/Merchant?id=${storeId}`, "_blank");
|
||||
window.open(`${config.PC_URL}merchant?id=${storeId}`, "_blank");
|
||||
};
|
||||
app.config.globalProperties.linkToOrders = function (sn) {
|
||||
if (localStorage.getItem("storeFlag") == "false") {
|
||||
|
||||
@@ -20,7 +20,7 @@ export default {
|
||||
//标识没有值,获取用户信息
|
||||
|
||||
if(this.$route.query.id){
|
||||
ServeGetUserSetting().then(async ({ code, result }) => {
|
||||
return ServeGetUserSetting().then(async ({ code, result }) => {
|
||||
// 如果result有值说明用户创建成功
|
||||
if (result) {
|
||||
store.commit("UPDATE_USER_INFO", {
|
||||
@@ -28,15 +28,17 @@ export default {
|
||||
face: result.face,
|
||||
name: result.nickName,
|
||||
});
|
||||
console.log(result.nickName)
|
||||
/**
|
||||
* 用户像商家进行聊天,商家进行刷新好友列表
|
||||
*/
|
||||
// 判断如果是有id说明是 用户像商家进行聊天。
|
||||
if (this.$route.query.id) {
|
||||
await this.createTalk(this.$route.query.id);
|
||||
if (typeof this.createTalk === "function") {
|
||||
await this.createTalk(this.$route.query.id);
|
||||
} else if (typeof this.loadChatList === "function") {
|
||||
await this.loadChatList();
|
||||
}
|
||||
}
|
||||
if(this.$route.query.goodsId && this.$route.query.skuId){
|
||||
if(this.$route.query.goodsId && this.$route.query.skuId && this.goodsParams){
|
||||
this.goodsParams.goodsId = this.$route.query.goodsId
|
||||
this.goodsParams.skuId = this.$route.query.skuId
|
||||
}
|
||||
@@ -48,7 +50,7 @@ export default {
|
||||
});
|
||||
}else{
|
||||
//标识有值代表是店铺
|
||||
ServeGetStoreSetting().then(async ({ code, result }) => {
|
||||
return ServeGetStoreSetting().then(async ({ code, result }) => {
|
||||
if (result) {
|
||||
store.commit("UPDATE_USER_INFO", {
|
||||
id: result.id,
|
||||
@@ -56,7 +58,9 @@ export default {
|
||||
name: result.storeName,
|
||||
});
|
||||
//获取店铺聊天列表
|
||||
await this.loadStoreChatList()
|
||||
if (typeof this.loadStoreChatList === "function") {
|
||||
await this.loadStoreChatList()
|
||||
}
|
||||
}else if (code === 200 && !result) {
|
||||
setTimeout(() => {
|
||||
this.loadUserSetting();
|
||||
@@ -91,8 +95,8 @@ export default {
|
||||
//获取商家聊天记录
|
||||
loadStoreChatList() {
|
||||
this.loadStatus = this.talkNum == 0 ? 0 : 1;
|
||||
ServeGetStoreTalkList().then(({ code, result }) => {
|
||||
if (code !== 200) return false;
|
||||
return ServeGetStoreTalkList().then(({ code, result }) => {
|
||||
if (code !== 200 || !Array.isArray(result)) return false;
|
||||
this.$store.commit("SET_UNREAD_NUM", 0);
|
||||
this.$store.commit("SET_TALK_ITEMS", {
|
||||
items: result.map((item) => formatTalkItem(item)),
|
||||
@@ -101,7 +105,6 @@ export default {
|
||||
// 判断
|
||||
if (this.$route.query.id) {
|
||||
let takeData, takeIndex;
|
||||
console.log(result)
|
||||
result.forEach((take, index) => {
|
||||
if (take.id == this.$route.query.id) {
|
||||
takeData = take;
|
||||
|
||||
@@ -10,6 +10,9 @@ const USER_SETTING = 'LILI-SETTING'
|
||||
* @param {String} token
|
||||
*/
|
||||
export function setToken (token) {
|
||||
if (token == null || token === '' || token === 'undefined' || token === 'null') {
|
||||
return
|
||||
}
|
||||
return localStorage.setItem(
|
||||
USER_TOKEN,
|
||||
token
|
||||
|
||||
19
im/src/utils/im-mode.js
Normal file
19
im/src/utils/im-mode.js
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* IM 身份判断(与 main-mixin.loadUserSetting 一致)
|
||||
* - 买家从商城「联系客服」进入:URL 带 ?id=店铺ID
|
||||
* - 商家从商家后台进入:URL 无 id
|
||||
*/
|
||||
export function isBuyerImMode(route) {
|
||||
return !!route?.query?.id;
|
||||
}
|
||||
|
||||
export function isStoreImMode(route) {
|
||||
return !isBuyerImMode(route);
|
||||
}
|
||||
|
||||
export function syncImTokenFromRoute(route, setTokenFn) {
|
||||
const token = route?.query?.token;
|
||||
if (token) {
|
||||
setTokenFn(token);
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,9 @@ const errorHandler = (error) => {
|
||||
removeAll();
|
||||
location.reload();
|
||||
} else if (error.response.status == 403) {
|
||||
if (error.config?.skipAuthDialog) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
if(!isRefreshing){
|
||||
|
||||
/**
|
||||
@@ -80,8 +83,8 @@ request.interceptors.request.use((config) => {
|
||||
|
||||
if (token) {
|
||||
config.headers["accessToken"] = `${token}`;
|
||||
return config;
|
||||
}
|
||||
return config;
|
||||
}, errorHandler);
|
||||
|
||||
// 响应拦截器
|
||||
|
||||
@@ -46,6 +46,8 @@ export function formatTalkItem (params) {
|
||||
};
|
||||
|
||||
Object.assign(options, params);
|
||||
options.talk_type = options.talk_type || 1;
|
||||
options.receiver_id = options.receiver_id || options.userId;
|
||||
options.index_name = `${options.talk_type}_${options.receiver_id}`;
|
||||
|
||||
return options;
|
||||
|
||||
@@ -48,9 +48,9 @@
|
||||
</el-header>
|
||||
|
||||
<!-- 对话列表栏 -->
|
||||
<el-scrollbar tag="section" ref="menusScrollbar" class="full-height" :native="false">
|
||||
<el-scrollbar tag="section" ref="menusScrollbar" class="full-height" :native="false" @scroll="onMenusScroll">
|
||||
<el-main class="main">
|
||||
<p v-show="loadStatus === 0" class="empty-data">
|
||||
<p v-show="loadStatus === 0 && userTalkItem.length === 0" class="empty-data">
|
||||
<legacy-el-icon name="el-icon-loading" /> 数据加载中...
|
||||
</p>
|
||||
|
||||
@@ -168,6 +168,7 @@ import { ServeDeleteContact, ServeEditContactRemark } from "@/api/contacts";
|
||||
import { beautifyTime } from "@/utils/functions";
|
||||
import { formatTalkItem, findTalkIndex, getCacheIndexName } from "@/utils/talk";
|
||||
import { setToken } from "@/utils/auth";
|
||||
import { syncImTokenFromRoute } from "@/utils/im-mode";
|
||||
|
||||
const title = document.title;
|
||||
|
||||
@@ -286,6 +287,7 @@ export default {
|
||||
},
|
||||
|
||||
beforeRouteUpdate (to, from, next) {
|
||||
syncImTokenFromRoute(to, setToken);
|
||||
let index_name = getCacheIndexName();
|
||||
if (index_name) this.clickTab(index_name);
|
||||
// 更新商品参数
|
||||
@@ -293,7 +295,7 @@ export default {
|
||||
next();
|
||||
},
|
||||
beforeCreate () {
|
||||
setToken(this.$route.query.token);
|
||||
syncImTokenFromRoute(this.$route, setToken);
|
||||
},
|
||||
async created () {
|
||||
await this.initialize();
|
||||
@@ -308,9 +310,6 @@ export default {
|
||||
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.scrollEvent();
|
||||
},
|
||||
beforeUnmount () {
|
||||
document.title = title;
|
||||
clearInterval(this.interval);
|
||||
@@ -368,40 +367,34 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
// 监听自定义滚动条事件
|
||||
scrollEvent () {
|
||||
let scrollbarEl = this.$refs.menusScrollbar.wrap;
|
||||
scrollbarEl.onscroll = () => {
|
||||
this.subHeaderShadow = scrollbarEl.scrollTop > 0;
|
||||
};
|
||||
// 左侧会话列表滚动时,控制置顶栏阴影
|
||||
onMenusScroll ({ scrollTop }) {
|
||||
this.subHeaderShadow = scrollTop > 0;
|
||||
},
|
||||
// 获取用户对话列表
|
||||
loadChatList () {
|
||||
this.loadStatus = this.talkNum == 0 ? 0 : 1;
|
||||
|
||||
ServeGetTalkList()
|
||||
return ServeGetTalkList()
|
||||
.then(({ code, result }) => {
|
||||
if (code !== 200) return false;
|
||||
if (code !== 200 || !Array.isArray(result)) return false;
|
||||
this.$store.commit("SET_UNREAD_NUM", 0);
|
||||
this.$store.commit("SET_TALK_ITEMS", {
|
||||
items: result.map((item) => formatTalkItem(item)),
|
||||
});
|
||||
|
||||
// 判断
|
||||
if (this.$route.query.id) {
|
||||
let takeData, takeIndex;
|
||||
console.log("用户result", result)
|
||||
this.talkItems.forEach((take, index) => {
|
||||
if (take.userId == this.$route.query.id) {
|
||||
takeData = take;
|
||||
takeIndex = index;
|
||||
}
|
||||
});
|
||||
this.$nextTick(() =>
|
||||
this.clickTab(this.$route.query.id, takeData, takeIndex)
|
||||
const targetId = this.$route.query.id;
|
||||
const takeIndex = this.talkItems.findIndex(
|
||||
(take) => take.userId == targetId
|
||||
);
|
||||
const takeData = takeIndex >= 0 ? this.talkItems[takeIndex] : null;
|
||||
if (takeData) {
|
||||
this.clickTab(targetId, takeData, takeIndex);
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
this.loadStatus = 1;
|
||||
});
|
||||
@@ -414,18 +407,21 @@ export default {
|
||||
let item =
|
||||
this.talks.find((item) => {
|
||||
return item.userId == id;
|
||||
}) || {};
|
||||
}) || val || {};
|
||||
// 点击当前栏目存储当前用户的信息
|
||||
this.$store.state.user.toUser = val;
|
||||
this.$store.state.user.toUser = val || item;
|
||||
|
||||
let nickname = item.name;
|
||||
const talkId = item.id || val?.id;
|
||||
|
||||
if (!talkId) return;
|
||||
|
||||
this.params = {
|
||||
talk_type: 1,
|
||||
receiver_id: item.userId,
|
||||
receiver_id: item.userId || id,
|
||||
nickname,
|
||||
is_robot: item.is_robot,
|
||||
talkId: item.id, //聊天对话的id
|
||||
talkId,
|
||||
clickFlag: true
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user