This commit is contained in:
JiXinHui 2026-01-21 11:56:09 +08:00
commit d854f4dbe0
7 changed files with 158 additions and 118 deletions

View File

@ -14,3 +14,36 @@ export const Debounce = (fn, wait) => {
if (callNow) fn.apply(this, args) if (callNow) fn.apply(this, args)
} }
} }
/**
* 处理头像/图片 URL
* @param {String} url 图片路径
* @param {String} baseUrl 基础路径
* @param {String} defaultUrl 默认图片路径
*/
export const getHeadImgUrl = (url, baseUrl, defaultUrl = "/static/common/images/avatar_default2.png") => {
if (!url) return defaultUrl;
if (url.startsWith('http') || url.startsWith('https') || url.startsWith('blob:')) return url;
// 统一处理反斜杠:将所有的 \ 替换为 /
let cleanUrl = url.replace(/\\/g, '/');
// 处理 baseUrl: 替换反斜杠并去除末尾斜杠
let cleanBaseUrl = '';
if (baseUrl) {
cleanBaseUrl = baseUrl.replace(/\\/g, '/').replace(/\/$/, '');
}
// 情况三headSculptureUrl = "/UploadImages/tx.jpg"
if (cleanUrl.startsWith('/')) {
return cleanBaseUrl + cleanUrl;
}
// 情况二headSculptureUrl = "UploadImages/tx.jpg"
if (cleanUrl.includes('/')) {
return cleanBaseUrl + '/' + cleanUrl;
}
// 情况一headSculptureUrl = "tx.jpg"
return cleanBaseUrl + '/UploadImages/' + cleanUrl;
}

View File

@ -2,6 +2,7 @@ import Vue from 'vue';
import App from './App'; import App from './App';
import "./static/common/css/font.css" import "./static/common/css/font.css"
import common from './static/common/js/common' import common from './static/common/js/common'
import { getHeadImgUrl } from '@/common/utils.js';
import jweixin from 'jweixin-module' import jweixin from 'jweixin-module'
import { import {
HubConnectionBuilder, HubConnectionBuilder,
@ -27,6 +28,13 @@ var tips = function(title, type, time) {
// 导入公用js // 导入公用js
Vue.prototype.$tips = tips Vue.prototype.$tips = tips
Vue.prototype.common = common Vue.prototype.common = common
Vue.prototype.$getHeadImgUrl = function (url, defaultUrl) {
let baseUrl = '';
if (this.$u && this.$u.http && this.$u.http.config && this.$u.http.config.baseUrl) {
baseUrl = this.$u.http.config.baseUrl;
}
return getHeadImgUrl(url, baseUrl, defaultUrl);
}
// 导入微信sdk // 导入微信sdk
Vue.prototype.jweixin = jweixin Vue.prototype.jweixin = jweixin
// 引入全局uView // 引入全局uView

View File

@ -21,12 +21,44 @@
> >
<view class="chat-content"> <view class="chat-content">
<!-- 教师信息 --> <!-- 教师信息 -->
<div class="teacher-info-card"> <div class="teacher-info-card" v-if="vuex_userType == 0">
<image <image
class="teacher-avatar" class="teacher-avatar"
:src="receiverHeadSculptureUrl" :src="receiverHeadSculptureUrl"
></image> ></image>
<div class="teacher-info"> <div class="teacher-info" >
<div>{{vuex_userType}}</div>
<div class="teacher-header">
<div class="teacher-name">{{ vuex_msgUser.name }}</div>
<div class="reply-tag">
<image
class="reply-icon"
src="/static/common/images/icon_chat3.png"
></image>
<text
>今日已回复{{
vuex_msgUser.todayNumberOfReplies || 0
}}</text
>
</div>
</div>
<!-- <div class="teacher-school">
<image
class="school-icon"
src="/static/common/images/icon_college.png"
></image>
<!--= 后端让先写死 -->
<!-- <text class="school-text">{{ vuex_msgUser.collegeName }}</text> -->
<text class="school-text">江西新能源科技职业学院</text>
</div>
</div>
<div class="teacher-info-card" v-if="vuex_userType ==1">
<image
class="teacher-avatar"
:src="receiverHeadSculptureUrl"
></image>
<div class="teacher-info" v-if="vuex_userType == 1">
<div class="teacher-name-row"> <div class="teacher-name-row">
<div class="teacher-name">{{ vuex_msgUser.name }}</div> <div class="teacher-name">{{ vuex_msgUser.name }}</div>
<image <image
@ -47,22 +79,6 @@
归属地 <span style="font-weight: bold;">{{vuex_msgUser.shen}}</span> 归属地 <span style="font-weight: bold;">{{vuex_msgUser.shen}}</span>
</text> </text>
</div> </div>
<!-- <div class="teacher-school">
<image
class="school-icon"
src="/static/common/images/icon_college.png"
></image>
<text class="school-text">{{ vuex_msgUser.collegeName }}</text>
</div> -->
<!-- <div class="teacher-college">
<image
class="college-icon"
src="/static/common/images/icon_major.png"
></image>
<text class="college-text">{{ vuex_msgUser.collegeName }}</text>
</div> -->
</div> </div>
</div> </div>
@ -231,19 +247,11 @@ export default {
}, },
receiverHeadSculptureUrl() { receiverHeadSculptureUrl() {
if (this.vuex_msgUser.headSculptureUrl) { return this.$getHeadImgUrl(this.vuex_msgUser.headSculptureUrl);
return this.baseUrl + "/" + this.vuex_msgUser.headSculptureUrl;
}
return "/static/common/images/avatar_default2.png";
}, },
headSculptureUrl() { headSculptureUrl() {
if (this.vuex_user.HeadSculptureUrl) { return this.$getHeadImgUrl(this.vuex_user.HeadSculptureUrl);
return this.baseUrl + "/" + this.vuex_user.HeadSculptureUrl;
}
return "/static/common/images/avatar_default2.png";
}, },
}, },
@ -469,11 +477,44 @@ export default {
gap: 16rpx; gap: 16rpx;
flex: 1; flex: 1;
.teacher-name { .teacher-header {
font-family: PingFang SC; display: flex;
font-weight: bold; align-items: center;
font-size: 36rpx;
color: #333333; .teacher-name {
font-family: PingFang SC;
font-weight: bold;
font-size: 36rpx;
color: #333333;
height: 52rpx;
line-height: 50rpx;
margin-right: 20rpx;
}
.reply-tag {
display: flex;
align-items: center;
background-color: #eaedfc;
border-radius: 24rpx;
padding: 10rpx 24rpx;
// height: 48rpx;
box-sizing: border-box;
.reply-icon {
width: 24rpx;
height: 24rpx;
margin-right: 8rpx;
}
text {
font-size: 24rpx;
color: #4f6aff;
line-height: 1;
letter-spacing: 1rpx;
}
}
} }
.teacher-name-row { .teacher-name-row {
display: flex; display: flex;

View File

@ -26,7 +26,7 @@
> >
<image <image
class="teacher-avatar" class="teacher-avatar"
src="/static/common/images/avatar.png" :src="$getHeadImgUrl(teacher.headSculptureUrl)"
></image> ></image>
<view class="teacher-info"> <view class="teacher-info">
<view class="teacher-detail"> <view class="teacher-detail">

View File

@ -193,10 +193,7 @@
</view> </view>
<view <view
class="transfer-card-status" class="transfer-card-status"
v-if=" v-if="isTransferSubmitting || !!message.transferTipText"
isTransferSubmitting ||
!!message.transferTipText
"
> >
{{ getTransferCardTip(message) }} {{ getTransferCardTip(message) }}
</view> </view>
@ -321,7 +318,7 @@
class="tab-item" class="tab-item"
v-for="(tab, index) in floatingTabs" v-for="(tab, index) in floatingTabs"
:key="index" :key="index"
@click="handleFeatureClick({ title: tab.title })" @click="handleFeatureClick({ title: tab.title, path: tab.path })"
> >
<image class="tab-icon" :src="tab.icon" mode="scaleToFill" /> <image class="tab-icon" :src="tab.icon" mode="scaleToFill" />
<text>{{ tab.title }}</text> <text>{{ tab.title }}</text>
@ -445,6 +442,7 @@ export default {
{ {
title: "招生在线", title: "招生在线",
icon: "/static/common/images/icon_admissions2.png", icon: "/static/common/images/icon_admissions2.png",
path: "/pages/home/admissions/index",
}, },
{ {
title: "转人工", title: "转人工",
@ -506,23 +504,10 @@ export default {
computed: { computed: {
headSculptureUrl() { headSculptureUrl() {
if (this.vuex_user.HeadSculptureUrl) { return this.$getHeadImgUrl(this.vuex_user.HeadSculptureUrl);
return this.baseUrl + "/" + this.vuex_user.HeadSculptureUrl;
}
return "/static/common/images/avatar.png";
}, },
receiverHeadSculptureUrl() { receiverHeadSculptureUrl() {
const url = return this.$getHeadImgUrl(this.vuex_msgUser.headSculptureUrl);
(this.vuex_msgUser &&
(this.vuex_msgUser.headSculptureUrl ||
this.vuex_msgUser.HeadSculptureUrl)) ||
"";
if (url) {
return this.baseUrl + "/" + url;
}
return "/static/common/images/avatar_default2.png";
}, },
aiMessageGroups() { aiMessageGroups() {
return Array.isArray(this.vuex_aiMessageGroups) return Array.isArray(this.vuex_aiMessageGroups)
@ -544,7 +529,8 @@ export default {
isLiveAgentChat() { isLiveAgentChat() {
if (!this.vuex_isTransferChat) return false; if (!this.vuex_isTransferChat) return false;
const current = this.currentDMid || ""; const current = this.currentDMid || "";
const active = this.vuex_msgUser && this.vuex_msgUser.dialogueManagementId; const active =
this.vuex_msgUser && this.vuex_msgUser.dialogueManagementId;
return !!(current && active && String(active) === String(current)); return !!(current && active && String(active) === String(current));
}, },
}, },
@ -677,7 +663,6 @@ export default {
this.resetChatState({ isChat: false }); this.resetChatState({ isChat: false });
return; return;
} }
if (item.title === "转人工") { if (item.title === "转人工") {
this.handleTransferEntryClick(); this.handleTransferEntryClick();
return; return;
@ -746,7 +731,7 @@ export default {
this.isTransferSubmitting = false; this.isTransferSubmitting = false;
const nextList = this.aiMessageGroups.filter( const nextList = this.aiMessageGroups.filter(
(m) => !(m && m.customType === "transferCard") (m) => !(m && m.customType === "transferCard"),
); );
nextList.push(this.createLocalUserTextMessage("转人工")); nextList.push(this.createLocalUserTextMessage("转人工"));
@ -767,14 +752,10 @@ export default {
const cardId = this.activeTransferCardId; const cardId = this.activeTransferCardId;
const findCardIndex = (list) => { const findCardIndex = (list) => {
if (cardId) { if (cardId) {
const byId = list.findIndex( const byId = list.findIndex((m) => m && m.id === cardId);
(m) => m && m.id === cardId
);
if (byId >= 0) return byId; if (byId >= 0) return byId;
} }
return list.findIndex( return list.findIndex((m) => m && m.customType === "transferCard");
(m) => m && m.customType === "transferCard"
);
}; };
const updateTransferCard = (patch) => { const updateTransferCard = (patch) => {
const list = this.aiMessageGroups; const list = this.aiMessageGroups;
@ -792,7 +773,8 @@ export default {
if (idx < 0) return; if (idx < 0) return;
const current = list[idx] || {}; const current = list[idx] || {};
if (this.isTransferSubmitting || current.transferStatus === "done") return; if (this.isTransferSubmitting || current.transferStatus === "done")
return;
updateTransferCard({ updateTransferCard({
transferStatus: "idle", transferStatus: "idle",
@ -815,7 +797,8 @@ export default {
.TransferToALiveAgentApi(params) .TransferToALiveAgentApi(params)
.then((res) => { .then((res) => {
const succeed = res && res.succeed !== false; const succeed = res && res.succeed !== false;
const serverTip = (res && res.data && res.data.message) || (res && res.error) || ""; const serverTip =
(res && res.data && res.data.message) || (res && res.error) || "";
if (!succeed) { if (!succeed) {
updateTransferCard({ updateTransferCard({
transferStatus: "idle", transferStatus: "idle",
@ -940,15 +923,11 @@ export default {
this.currentDMid = data.dmid; this.currentDMid = data.dmid;
// //
const baseList = this.aiMessageGroups.filter( const baseList = this.aiMessageGroups.filter((msg) => !msg.isLoading);
(msg) => !msg.isLoading
);
// AI // AI
const aiMessage = { const aiMessage = {
id: id: data.messageId || Math.random().toString(36).substring(2, 15),
data.conversationId ||
Math.random().toString(36).substring(2, 15),
message: data.content, message: data.content,
sendDate: "", sendDate: "",
isSend: true, isSend: true,
@ -966,9 +945,7 @@ export default {
console.error("API请求失败:", error); console.error("API请求失败:", error);
// //
const baseList = this.aiMessageGroups.filter( const baseList = this.aiMessageGroups.filter((msg) => !msg.isLoading);
(msg) => !msg.isLoading
);
// //
const errorMessage = { const errorMessage = {
@ -983,10 +960,7 @@ export default {
displayTime: "", displayTime: "",
}; };
this.$store.commit( this.$store.commit("push_AiMsgList", baseList.concat([errorMessage]));
"push_AiMsgList",
baseList.concat([errorMessage])
);
}); });
}, },
@ -1058,7 +1032,7 @@ export default {
// //
const baseList = this.aiMessageGroups.filter( const baseList = this.aiMessageGroups.filter(
(msg) => !msg.isLoading (msg) => !msg.isLoading,
); );
// AI // AI
@ -1077,15 +1051,12 @@ export default {
}; };
// //
this.$store.commit( this.$store.commit("push_AiMsgList", baseList.concat([aiMessage]));
"push_AiMsgList",
baseList.concat([aiMessage])
);
} else { } else {
// //
this.$store.commit( this.$store.commit(
"push_AiMsgList", "push_AiMsgList",
this.aiMessageGroups.filter((msg) => !msg.isLoading) this.aiMessageGroups.filter((msg) => !msg.isLoading),
); );
} }
}) })
@ -1093,9 +1064,7 @@ export default {
console.error("API请求失败:", error); console.error("API请求失败:", error);
// //
const baseList = this.aiMessageGroups.filter( const baseList = this.aiMessageGroups.filter((msg) => !msg.isLoading);
(msg) => !msg.isLoading
);
// //
const errorMessage = { const errorMessage = {
@ -1110,10 +1079,7 @@ export default {
displayTime: "", displayTime: "",
}; };
this.$store.commit( this.$store.commit("push_AiMsgList", baseList.concat([errorMessage]));
"push_AiMsgList",
baseList.concat([errorMessage])
);
}); });
}, },
@ -1167,10 +1133,7 @@ export default {
const currentList = res.item2 || []; const currentList = res.item2 || [];
// sendDate(interactMode=0) // sendDate(interactMode=0)
this.$store.commit( this.$store.commit("push_AiMsgList", this.sortMessages(currentList));
"push_AiMsgList",
this.sortMessages(currentList)
);
}) })
.finally(() => { .finally(() => {
// //
@ -1207,14 +1170,14 @@ export default {
const prevList = res3?.item2 || []; const prevList = res3?.item2 || [];
this.$store.commit( this.$store.commit(
"push_AiMsgList", "push_AiMsgList",
this.sortMessages(prevList) this.sortMessages(prevList),
); );
this.pageQuery.PageIndex = prevIndex; this.pageQuery.PageIndex = prevIndex;
}); });
} else { } else {
this.$store.commit( this.$store.commit(
"push_AiMsgList", "push_AiMsgList",
this.sortMessages(currentList) this.sortMessages(currentList),
); );
} }
}); });
@ -1277,10 +1240,7 @@ export default {
// sendDate(interactMode=0) // sendDate(interactMode=0)
const nextPageMessageGroups = sortChatMessages(res.item2 || []); const nextPageMessageGroups = sortChatMessages(res.item2 || []);
this.$store.commit( this.$store.commit("prepend_AiMsgList", nextPageMessageGroups);
"prepend_AiMsgList",
nextPageMessageGroups
);
}) })
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {

View File

@ -251,7 +251,7 @@ export default {
this.imageUrl = ""; this.imageUrl = "";
this.imageValue = [ this.imageValue = [
{ {
url: "/static/common/images/avatar_default.jpg", url: "/static/common/images/avatar_default2.png",
extname: "jpg", extname: "jpg",
name: "", name: "",
}, },

View File

@ -499,9 +499,13 @@ const store = new Vuex.Store({
dialogueManagementId !== "00000000-0000-0000-0000-000000000000" dialogueManagementId !== "00000000-0000-0000-0000-000000000000"
) { ) {
// 有会话ID直接进入会话 // 有会话ID直接进入会话
commit("set_MsgUser", { ...user }); Vue.prototype.$u.api.GetReceiverUserInfoApi({ Id: id }).then((res) => {
uni.navigateTo({ if (res.succeed && res.data) {
url: `/pages/chat/index`, commit("set_MsgUser", { ...res.data, dialogueManagementId });
uni.navigateTo({
url: `/pages/chat/index`,
});
}
}); });
return; return;
} }
@ -515,19 +519,13 @@ const store = new Vuex.Store({
const resId = res1.data?.dialogueManagementId || ""; const resId = res1.data?.dialogueManagementId || "";
if (res1 && res1.succeed) { if (res1 && res1.succeed) {
// 获取接收者信息,这里没啥用(先注释) Vue.prototype.$u.api.GetReceiverUserInfoApi({ Id: id }).then((res) => {
// Vue.prototype.$u.api.GetReceiverUserInfoApi({ Id: id }).then((res) => { if (res.succeed && res.data) {
// if (res.succeed && res.data) { commit("set_MsgUser", { ...res.data, dialogueManagementId: resId });
// commit("set_MsgUser", { ...res.data, dialogueManagementId }); uni.navigateTo({
// uni.navigateTo({ url: `/pages/chat/index`,
// url: `/pages/chat/index`, });
// }); }
// return;
// }
// });
commit("set_MsgUser", { ...user, dialogueManagementId: resId });
uni.navigateTo({
url: `/pages/chat/index`,
}); });
return; return;
} }