diff --git a/common/http.api.js b/common/http.api.js
index 0e468d4..73f5f29 100644
--- a/common/http.api.js
+++ b/common/http.api.js
@@ -41,11 +41,11 @@ const install = (Vue, vm) => {
let updateTeacherInfo = (params = {}) =>
vm.$u.post("api/BasicDataMaintenance/UpdateTeacher", params);
- let getData = (params = {}) =>
- vm.$u.get("api/BasicDataMaintenance/GetData", params);
- // 获取排班数据
- let getShiftSchedulingData = (params = {}) =>
- vm.$u.get("api/BasicDataMaintenance/GetShiftSchedulingData", params);
+ let getData = (params = {}) =>
+ vm.$u.get("api/BasicDataMaintenance/GetData", params);
+ // 获取排班数据
+ let getShiftSchedulingData = (params = {}) =>
+ vm.$u.get("api/BasicDataMaintenance/GetShiftSchedulingData", params);
// 登录
let LoginApp = (params = {}) => vm.$u.post("api/Token/LoginApp", params);
@@ -251,14 +251,17 @@ const install = (Vue, vm) => {
// 转人工服务
let TransferToALiveAgentApi = (params = {}) =>
vm.$u.post("api/Dialogue/TransferToALiveAgent", params);
+ // 结束人工服务
+ let EndLiveAgentApi = (params = {}) =>
+ vm.$u.post("api/Dialogue/EndLiveAgent", params);
// 将各个定义的接口名称,统一放进对象挂载到vm.$u.api(因为vm就是this,也即this.$u.api)下
- vm.$u.api = {
- UploadSingleImage,
- getTeacherInfo,
- getData,
- getShiftSchedulingData,
- updateTeacherInfo,
+ vm.$u.api = {
+ UploadSingleImage,
+ getTeacherInfo,
+ getData,
+ getShiftSchedulingData,
+ updateTeacherInfo,
LoginApp,
RegisterUser,
saveUserInfo,
@@ -322,6 +325,7 @@ const install = (Vue, vm) => {
ReadMessageApi,
DeleteDialogueApi,
TransferToALiveAgentApi,
+ EndLiveAgentApi,
};
};
diff --git a/components/AdvicePhone.vue b/components/AdvicePhone.vue
index bf6091b..c82b17f 100644
--- a/components/AdvicePhone.vue
+++ b/components/AdvicePhone.vue
@@ -10,11 +10,31 @@
>
@@ -48,6 +68,11 @@ export default {
},
},
methods: {
+ makeCall(phoneNumber) {
+ uni.makePhoneCall({
+ phoneNumber,
+ });
+ },
closePopup() {
this.showPopup = false;
this.$emit("update:show", false);
@@ -66,7 +91,6 @@ export default {
background-size: 630rpx 100rpx;
background-position: -20rpx 0;
-
.phone-title {
text-align: center;
font-family: DouyinSans;
@@ -76,19 +100,72 @@ export default {
margin-bottom: 40rpx;
}
- .phone-content {
- margin-bottom: 120rpx;
- text-align: center;
- font-family: PingFang SC;
- font-size: 32rpx;
- color: #333333;
+ .phone-card-list {
+ padding: 0 48rpx;
+ margin-bottom: 60rpx;
+
+ .phone-card {
+ display: flex;
+ align-items: center;
+ padding: 30rpx 40rpx;
+ margin-bottom: 24rpx;
+ background: #ffffff;
+ border: 1px solid #f0f0f0;
+ box-shadow: 0px 4rpx 12rpx rgba(0, 0, 0, 0.05);
+ border-radius: 16rpx;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ .icon-wrapper {
+ width: 80rpx;
+ height: 80rpx;
+ background: #5ac799;
+ border-radius: 50%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin-right: 30rpx;
+ flex-shrink: 0;
+ }
+
+ .info-wrapper {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ flex: 1;
+
+ .phone-number {
+ font-size: 36rpx;
+ font-weight: bold;
+ color: #333333;
+ letter-spacing: 2rpx;
+ margin-bottom: 10rpx;
+ }
+
+ .phone-desc {
+ font-size: 24rpx;
+ color: #999999;
+ }
+ }
+ }
}
.phone-button {
- padding: 0 40rpx;
+ padding: 0 48rpx;
- .cancel-button {
+ .cancel-btn {
+ width: 100%;
+ height: 88rpx;
+ line-height: 88rpx;
+ text-align: center;
+ background: #ffffff;
+ border: 1px solid #e5e5e5;
border-radius: 16rpx;
+ font-size: 32rpx;
+ color: #333333;
}
}
}
diff --git a/pages/home/index/index.vue b/pages/home/index/index.vue
index b3acb39..fc71d7c 100644
--- a/pages/home/index/index.vue
+++ b/pages/home/index/index.vue
@@ -2,9 +2,24 @@
+ >
+
+
+
+
@@ -61,10 +76,16 @@
:style="{
background: item.background,
}"
- @click="handleFeatureClick(item)"
>
- {{ item.title }}
+
+ {{ item.title }}
+ {{ item.tip }}
+
+
+ 去咨询
+
+
@@ -318,7 +339,7 @@
@@ -424,16 +445,17 @@ export default {
"我什么时候能推知道自己是否被录取?",
],
features: [
- {
- title: "在线咨询",
- icon: "/static/common/images/icon_admissions.png",
- path: "/pages/home/admissions/index",
- background: "linear-gradient(0deg, #F4FBFE 0%, #F4FBFE 100%)",
- },
+ // {
+ // title: "在线咨询",
+ // icon: "/static/common/images/icon_admissions.png",
+ // path: "/pages/home/admissions/index",
+ // background: "linear-gradient(0deg, #F4FBFE 0%, #F4FBFE 100%)",
+ // },
{
title: "电话咨询",
- icon: "/static/common/images/icon_phone.png",
- background: "linear-gradient(0deg, #F4FBF9 0%, #F4FBF9 100%)",
+ tip: "欢迎致电本校招生咨询热线",
+ icon: "/static/common/images/icon-phone1.png",
+ background: "#fff",
},
],
floatingTabs: [
@@ -441,11 +463,11 @@ export default {
title: "首页",
icon: "/static/common/images/icon_home.png",
},
- {
- title: "招生在线",
- icon: "/static/common/images/icon_admissions2.png",
- path: "/pages/home/admissions/index",
- },
+ // {
+ // title: "招生在线",
+ // icon: "/static/common/images/icon_admissions2.png",
+ // path: "/pages/home/admissions/index",
+ // },
{
title: "转人工",
icon: "/static/common/images/icon_conversation.png",
@@ -518,6 +540,10 @@ export default {
},
displayFeatures() {
const list = Array.isArray(this.features) ? this.features : [];
+ return list;
+ },
+ displayFloatingTabs() {
+ const list = Array.isArray(this.floatingTabs) ? this.floatingTabs : [];
return list.map((item) => {
if (item && item.title === "转人工") {
return {
@@ -578,6 +604,18 @@ export default {
this.handlePopupShow();
},
+ // 处理设置点击
+ handleSettingClick() {
+ uni.navigateTo({
+ url: "/pages/home/userSetting/index",
+ });
+ },
+
+ // 处理记录点击
+ // handleRecordClick() {
+ // console.log("点击了记录");
+ // },
+
// 重置对话状态
resetChatState({
conversationId = "",
@@ -660,38 +698,44 @@ export default {
extraOffset: 200,
});
},
+
+ // 处理功能点击
handleFeatureClick(item) {
- if (item.title === "首页") {
- this.resetChatState({ isChat: false });
- return;
- }
- if (item.title === "转人工") {
- this.handleTransferEntryClick();
- return;
- }
- if (item.title === "结束会话") {
- this.$store.commit("set_IsTransferChat", false);
- return;
- }
+ const actions = {
+ "首页": () => this.resetChatState({ isChat: false }),
+ "转人工": () => this.handleTransferEntryClick(),
+ "结束会话": () => this.handleEndConversation(),
+ "电话咨询": () => { this.advicePhoneShow = true; }
+ };
- if (item.title === "电话咨询") {
- this.advicePhoneShow = true;
- return;
+ const action = actions[item.title];
+ if (action) {
+ action();
} else if (item.path) {
- uni.navigateTo({
- url: item.path,
- });
- return;
+ uni.navigateTo({ url: item.path });
} else {
- this.$refs.uToast.show({
- title: "暂未开放",
- type: "warning",
- });
-
- return;
+ this.$refs.uToast.show({ title: "暂未开放", type: "warning" });
}
},
+ // 独立出结束会话逻辑
+ handleEndConversation() {
+ this.$u.api
+ .EndLiveAgentApi({
+ dialogueManagementId: this.vuex_msgUser?.dialogueManagementId,
+ teacherManagementId: this.vuex_msgUser?.receiverId,
+ })
+ .then((res) => {
+ if (res.succeed) {
+ this.$store.commit("set_IsTransferChat", false);
+ this.$u.toast("会话已结束");
+ } else {
+ this.$u.toast(res.error || "会话结束失败");
+ }
+ });
+ },
+
+ // 创建本地用户文本消息
createLocalUserTextMessage(messageText) {
return {
id: Math.random().toString(36).substring(2, 15),
@@ -706,6 +750,7 @@ export default {
};
},
+ // 创建转人工卡片消息
createTransferCardMessage() {
return {
id: "transfer_" + Math.random().toString(36).substring(2, 15),
@@ -724,6 +769,7 @@ export default {
};
},
+ // 处理转人工点击
handleTransferEntryClick() {
if (!this.isChat) {
this.resetChatState();
@@ -809,22 +855,14 @@ export default {
return;
}
+ // dialogueManagementId 结束转人工用
const dialogueManagementId =
- this.currentDMid ||
- (res &&
- res.data &&
- (res.data.dialogueManagementId ||
- res.data.DialogueManagementId)) ||
- "";
- const receiverId =
- (res &&
- res.data &&
- (res.data.receiverId ||
- res.data.ReceiverId ||
- res.data.liveAgentId ||
- res.data.agentId ||
- res.data.userId)) ||
- "";
+ (res && res.data && res.data.dialogueManagementId) || "";
+ // receiverId 接线老师
+ const receiverId = (res && res.data && res.data.receiverId) || "";
+
+ console.log(dialogueManagementId, "dialogueManagementId");
+ console.log(receiverId, "receiverId");
if (!this.currentDMid && dialogueManagementId) {
this.currentDMid = dialogueManagementId;
@@ -837,12 +875,17 @@ export default {
if (dialogueManagementId && receiverId) {
this.$store.commit("set_IsTransferChat", true);
+ this.$store.commit("update_MsgUser", {
+ dialogueManagementId,
+ receiverId,
+ });
this.$store.dispatch("selectTeacherChatItem", {
id: dialogueManagementId,
receiverId,
navigate: false,
});
}
+ console.log(this.vuex_msgUser, "vuex_msgUser");
})
.catch(() => {
updateTransferCard({
@@ -967,10 +1010,11 @@ export default {
},
// 点击热门问题
- handleQAClick(item) {
+ async handleQAClick(item) {
// 如果不在对话模式,切换到对话模式并初始化
if (!this.isChat) {
- this.resetChatState();
+ // this.resetChatState();
+ await this.handleStartChat(); // 切换到对话模式并初始化,加载历史数据
}
const sendMessage = item.content;
@@ -1122,11 +1166,11 @@ export default {
// 刷新当前对话的消息详情
handleGetConversationDetail() {
- if (!this.currentDMid) return;
+ // if (!this.currentDMid) return;
- this.$u.api
+ return this.$u.api
.GetConversationDetail({
- "Item1.Id": this.currentDMid,
+ // "Item1.Id": "08de2e31-4cdf-4b0c-8b83-d3185f604a5a",
PageIndex: this.pageQuery.PageIndex,
PageSize: this.pageQuery.PageSize,
})
@@ -1147,14 +1191,14 @@ export default {
// 刷新当前页数据;若当前页为空且页码>1,则自动回退上一页
refreshPageWithFallback() {
- if (!this.currentDMid) return;
+ // if (!this.currentDMid) return;
const currentIndex = this.pageQuery.PageIndex || 1;
const pageSize = this.pageQuery.PageSize;
return this.$u.api
.GetConversationDetail({
- "Item1.Id": this.currentDMid,
+ // "Item1.Id": this.currentDMid,
PageIndex: currentIndex,
PageSize: pageSize,
})
@@ -1164,7 +1208,7 @@ export default {
const prevIndex = currentIndex - 1;
return this.$u.api
.GetConversationDetail({
- "Item1.Id": this.currentDMid,
+ // "Item1.Id": this.currentDMid,
PageIndex: prevIndex,
PageSize: pageSize,
})
@@ -1195,6 +1239,9 @@ export default {
// 开始新对话
handleStartChat() {
this.resetChatState();
+
+ // 获取历史对话
+ return this.handleGetConversationDetail();
},
// 滚动到底部事件处理
@@ -1221,7 +1268,7 @@ export default {
this.pageQuery.PageIndex++;
this.$u.api
.GetConversationDetail({
- "Item1.Id": this.currentDMid,
+ // "Item1.Id": this.currentDMid,
PageIndex: this.pageQuery.PageIndex,
PageSize: this.pageQuery.PageSize,
})
@@ -1328,6 +1375,11 @@ export default {
/* Header样式移至HeaderBar组件 */
+ .header-icon {
+ width: 40rpx;
+ height: 40rpx;
+ }
+
.main-content {
padding: 30rpx;
padding-top: 60rpx;
@@ -1466,29 +1518,59 @@ export default {
border-radius: 16rpx;
padding: 30rpx;
display: flex;
+ flex-direction: column;
justify-content: space-between;
margin-top: 32rpx;
gap: 30rpx;
.feature-item {
- height: 150rpx;
+ height: 140rpx;
border-radius: 16rpx;
display: flex;
justify-content: flex-start;
align-items: center;
- padding-left: 30rpx;
- gap: 20rpx;
+ // padding-left: 30rpx;
+ gap: 30rpx;
flex: 1;
.feature-icon {
width: 80rpx;
height: 80rpx;
- margin-top: 16rpx;
}
- .feature-text {
- font-size: 26rpx;
- color: #333333;
+ .feature-text-wrapper {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ gap: 12rpx;
+ flex: 1;
+ .feature-title {
+ font-size: 28rpx;
+ color: #333333;
+ font-weight: bold;
+ }
+ .feature-tip {
+ font-size: 24rpx;
+ color: #999;
+ }
+ }
+
+ .feature-action-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 14rpx 20rpx 14rpx 24rpx;
+ gap: 10rpx;
+ // height: 56rpx;
+ background: linear-gradient(-33deg, #6079ff 0%, #418ded 100%);
+ box-shadow: 0px 4rpx 16rpx 0rpx rgba(62, 106, 255, 0.6);
+ border-radius: 28rpx;
+
+ text {
+ font-size: 24rpx;
+ color: #ffffff;
+ margin-right: 4rpx;
+ }
}
}
}
diff --git a/pages/home/messageBoard/index.vue b/pages/home/messageBoard/index.vue
index 8820a9b..2afb120 100644
--- a/pages/home/messageBoard/index.vue
+++ b/pages/home/messageBoard/index.vue
@@ -1,4 +1,5 @@
+
diff --git a/static/common/images/icon-phone1.png b/static/common/images/icon-phone1.png
new file mode 100644
index 0000000..cc603a0
Binary files /dev/null and b/static/common/images/icon-phone1.png differ
diff --git a/static/common/images/icon-phone2.png b/static/common/images/icon-phone2.png
new file mode 100644
index 0000000..169581d
Binary files /dev/null and b/static/common/images/icon-phone2.png differ
diff --git a/static/common/images/icon-userRecord.png b/static/common/images/icon-userRecord.png
new file mode 100644
index 0000000..5999030
Binary files /dev/null and b/static/common/images/icon-userRecord.png differ
diff --git a/static/common/images/icon-userSetting.png b/static/common/images/icon-userSetting.png
new file mode 100644
index 0000000..6047a16
Binary files /dev/null and b/static/common/images/icon-userSetting.png differ
diff --git a/store/index.js b/store/index.js
index 3e99122..add4ed5 100644
--- a/store/index.js
+++ b/store/index.js
@@ -149,6 +149,14 @@ const store = new Vuex.Store({
});
}
},
+ // 更新当前聊天用户的部分属性
+ update_MsgUser(state, payload) {
+ if (state.vuex_msgUser) {
+ state.vuex_msgUser = { ...state.vuex_msgUser, ...payload };
+ } else {
+ state.vuex_msgUser = payload;
+ }
+ },
// 现在没有id,先覆盖整个list
push_MsgList(state, list) {
state.vuex_msgList = list || [];
@@ -173,7 +181,7 @@ const store = new Vuex.Store({
// 注:现在的消息没有id,无法去重,暂时用push_MsgList
if (!msg || !msg.id) return;
const exists = (state.vuex_msgList || []).some(
- (item) => item && item.id === msg.id
+ (item) => item && item.id === msg.id,
);
if (!exists) {
state.vuex_msgList.push(msg);
@@ -198,15 +206,14 @@ const store = new Vuex.Store({
if (!msgId) return;
const exists = (state.vuex_aiMessageGroups || []).some(
- (item) => item && item.id === msgId
+ (item) => item && item.id === msgId,
);
if (exists) return;
const userId =
(state.vuex_user && (state.vuex_user.Id || state.vuex_user.id)) || "";
const senderId = msg.senderId || msg.SenderId || "";
- const isSelf =
- userId && senderId && String(userId) === String(senderId);
+ const isSelf = userId && senderId && String(userId) === String(senderId);
state.vuex_aiMessageGroups.push({
id: msgId,
@@ -243,7 +250,7 @@ const store = new Vuex.Store({
push_AiMsg(state, msg) {
if (!msg || !msg.id) return;
const exists = (state.vuex_aiMessageGroups || []).some(
- (item) => item && item.id === msg.id
+ (item) => item && item.id === msg.id,
);
if (!exists) {
state.vuex_aiMessageGroups.push(msg);
@@ -266,7 +273,7 @@ const store = new Vuex.Store({
// WebSocket 实时消息:更新会话列表的未读数、文案与时间
apply_RealtimeMessageToList(
state,
- { dialogueId, message, sendDate, senderId, receiverId }
+ { dialogueId, message, sendDate, senderId, receiverId },
) {
if (!dialogueId) return;
const activeId =
@@ -286,10 +293,7 @@ const store = new Vuex.Store({
found = true;
const currentUnread =
Number(
- item?.unReadCount ??
- item?.unreadCount ??
- item?.unread ??
- 0
+ item?.unReadCount ?? item?.unreadCount ?? item?.unread ?? 0,
) || 0;
const nextUnread = isActive ? 0 : currentUnread + 1;
return {
@@ -386,7 +390,7 @@ const store = new Vuex.Store({
// avatar: item.avatar,
unReadCount,
};
- }
+ },
);
commit("set_UserMsgList", list);
return list;
@@ -403,7 +407,7 @@ const store = new Vuex.Store({
// 获取聊天记录(私聊)——仅在进入聊天页时加载一次
async fetchChatRecord(
{ commit },
- { dialogueManagementId, PageIndex = 1, PageSize = 20 }
+ { dialogueManagementId, PageIndex = 1, PageSize = 20 },
) {
return Vue.prototype.$u.api
.GetChatHistoryDataApi({
@@ -412,11 +416,13 @@ const store = new Vuex.Store({
PageSize,
})
.then((res) => {
- const list =
- (res && res.data && Array.isArray(res.data.item1)
+ const list = (
+ res && res.data && Array.isArray(res.data.item1)
? res.data.item1
: []
- ).slice().reverse();
+ )
+ .slice()
+ .reverse();
commit("push_MsgList", list);
return list;
});
@@ -425,7 +431,7 @@ const store = new Vuex.Store({
// 获取下一页历史消息(滚动到顶部触发)
async fetchChatRecordNextPage(
{ commit },
- { dialogueManagementId, PageIndex = 1, PageSize = 20 }
+ { dialogueManagementId, PageIndex = 1, PageSize = 20 },
) {
return Vue.prototype.$u.api
.GetChatHistoryDataApi({
@@ -434,11 +440,13 @@ const store = new Vuex.Store({
PageSize,
})
.then((res) => {
- const list =
- (res && res.data && Array.isArray(res.data.item1)
+ const list = (
+ res && res.data && Array.isArray(res.data.item1)
? res.data.item1
: []
- ).slice().reverse();
+ )
+ .slice()
+ .reverse();
if (!list.length) return [];
commit("prepend_MsgList", list);
return list;
@@ -462,7 +470,7 @@ const store = new Vuex.Store({
// 点击聊天记录,切换到该会话
selectTeacherChatItem(
{ commit, dispatch },
- { id, receiverId, navigate = true } = {}
+ { id, receiverId, navigate = true } = {},
) {
if (!id || !receiverId) return;
// 清空消息列表,避免旧消息干扰
@@ -472,7 +480,7 @@ const store = new Vuex.Store({
.GetReceiverUserInfoApi({ Id: receiverId })
.then((res) => {
if (res.succeed && res.data) {
- commit("set_MsgUser", { ...res.data, dialogueManagementId: id });
+ commit("update_MsgUser", { ...res.data, dialogueManagementId: id });
if (navigate) {
uni.navigateTo({
url: `/pages/chat/index`,