From ea9535be7b314618a226665b2025e78f76074e0d Mon Sep 17 00:00:00 2001
From: wangdongbo <>
Date: Fri, 7 Aug 2026 09:35:21 +0800
Subject: [PATCH 1/7] =?UTF-8?q?=E5=92=A8=E8=AF=A2=E5=8A=A9=E7=90=86?=
=?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=BC=80=E5=8F=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pages.json | 30 +++++--
pages/ai-consult/chat.vue | 158 +++++++++++++++++++++++++++++++++++++
pages/ai-consult/entry.vue | 12 +++
pages/ai-consult/list.vue | 40 ++++++++++
pages/home/consult.vue | 37 +++++++--
utils/api.js | 7 ++
6 files changed, 270 insertions(+), 14 deletions(-)
create mode 100644 pages/ai-consult/chat.vue
create mode 100644 pages/ai-consult/entry.vue
create mode 100644 pages/ai-consult/list.vue
diff --git a/pages.json b/pages.json
index b2d702d..e47d85e 100644
--- a/pages.json
+++ b/pages.json
@@ -136,8 +136,8 @@
}
]
},
- {
- "root": "pages/rate",
+ {
+ "root": "pages/rate",
"name": "rate",
"pages": [
{
@@ -154,10 +154,28 @@
"disableScroll": true
}
}
- ]
- },
- {
- "root": "pages/archive",
+ ]
+ },
+ {
+ "root": "pages/ai-consult",
+ "name": "ai-consult",
+ "pages": [
+ {
+ "path": "list",
+ "style": { "navigationBarTitleText": "AI咨询记录", "disableScroll": true }
+ },
+ {
+ "path": "chat",
+ "style": { "navigationBarTitleText": "AI咨询助理", "disableScroll": true }
+ },
+ {
+ "path": "entry",
+ "style": { "navigationBarTitleText": "AI咨询助理", "disableScroll": true }
+ }
+ ]
+ },
+ {
+ "root": "pages/archive",
"name": "archive",
"pages": [
{
diff --git a/pages/ai-consult/chat.vue b/pages/ai-consult/chat.vue
new file mode 100644
index 0000000..ba7793f
--- /dev/null
+++ b/pages/ai-consult/chat.vue
@@ -0,0 +1,158 @@
+
+
+
+
+
+ {{ formatMessageTime(item.createTime) }}
+ {{ displayContent(item) }}
+
+
+ AI
+
+ {{ session?.assistantName || 'AI咨询助理' }}
+
+ {{ displayContent(item) }}
+
+ 发送失败,请重试
+
+ 我
+
+
+
+ AI{{ session?.assistantName || 'AI咨询助理' }}
+
+
+
+
+
+
+
+
+ 本次AI咨询已结束
+
+
+
+
+
+
diff --git a/pages/ai-consult/entry.vue b/pages/ai-consult/entry.vue
new file mode 100644
index 0000000..22a2352
--- /dev/null
+++ b/pages/ai-consult/entry.vue
@@ -0,0 +1,12 @@
+请选择本次咨询档案{{item.name || '未命名'}}{{ item.age ? item.age + '岁' : '' }}正在进入AI咨询...
+
diff --git a/pages/ai-consult/list.vue b/pages/ai-consult/list.vue
new file mode 100644
index 0000000..ea7768c
--- /dev/null
+++ b/pages/ai-consult/list.vue
@@ -0,0 +1,40 @@
+
+
+
+
+ {{ item.name }}
+
+
+
+
+
+ {{ item.assistantName }}{{ statusText(item) }}
+ 团队:{{ item.teamName || item.teamId || '-' }}
+ 档案:{{ item.customerName || '-' }}
+ 最近互动:{{ format(item.lastActiveTime) }}
+ 已触发敏感词
+
+
+
+
+
+
diff --git a/pages/home/consult.vue b/pages/home/consult.vue
index 5941631..55171e2 100644
--- a/pages/home/consult.vue
+++ b/pages/home/consult.vue
@@ -49,6 +49,7 @@ const props = defineProps({
const { account } = storeToRefs(useAccount());
const consultantPopup = ref(null);
const badgeMap = ref({});
+const aiConsultEnabled = ref(false);
let loading = false;
const consultItems = ref([
@@ -80,6 +81,12 @@ const consultItems = ref([
path: "/pages/rate/rate-list",
badge: 'rate'
},
+ {
+ id: "aiConsultRecord",
+ label: "AI咨询记录",
+ icon: "/static/home/chat-consult.png",
+ path: "/pages/ai-consult/list",
+ },
]);
const hideMenus = computed(() => {
const result = {};
@@ -87,6 +94,7 @@ const hideMenus = computed(() => {
if (!(props.team && props.team.createSource === 'yzs')) {
result.chat = true;
}
+ if (!aiConsultEnabled.value) result.aiConsultRecord = true;
return result;
})
@@ -191,8 +199,15 @@ async function getBadgeCount() {
loading = false;
}
+async function loadAiConsultPermission() {
+ if (!props.corpId) return;
+ const res = await api('getAiConsultPermission', { corpId: props.corpId }, false);
+ aiConsultEnabled.value = Boolean(res?.success && res?.data?.enabled);
+}
+
watch(() => [props.customers, props.teamId, props.corpId], n => {
getBadgeCount()
+ loadAiConsultPermission()
}, { immediate: true })
defineExpose({
@@ -216,23 +231,26 @@ defineExpose({
}
.consult-grid {
- height: 208rpx;
+ min-height: 208rpx;
box-sizing: border-box;
background: #fff;
border-radius: 16rpx;
- padding: 24rpx 30rpx;
+ padding: 26rpx 22rpx;
display: grid;
grid-template-columns: repeat(4, 1fr);
- align-items: center;
- gap: 32rpx;
+ grid-auto-rows: 120rpx;
+ align-items: start;
+ column-gap: 0;
+ row-gap: 24rpx;
box-shadow: 0 8rpx 10rpx 0 rgba(60, 169, 145, 0.06);
}
.consult-item {
+ min-width: 0;
display: flex;
flex-direction: column;
align-items: center;
- gap: 12rpx;
+ gap: 10rpx;
cursor: pointer;
}
@@ -242,7 +260,7 @@ defineExpose({
.item-icon {
width: 80rpx;
- height: 80;
+ height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
@@ -270,9 +288,12 @@ defineExpose({
}
.item-label {
- font-size: 30rpx;
- color: #666d76;
+ max-width: 100%;
+ color: #596273;
+ font-size: 26rpx;
+ line-height: 36rpx;
text-align: center;
font-weight: 400;
+ white-space: nowrap;
}
diff --git a/utils/api.js b/utils/api.js
index 727f007..1daba3e 100644
--- a/utils/api.js
+++ b/utils/api.js
@@ -20,6 +20,13 @@ const urlsConfig = {
recordBusinessCardBehavior: 'recordBusinessCardBehavior',
getJoinedTeams: 'getJoinedTeams',
getCorpBusinessCardStatus: 'getCorpBusinessCardStatus',
+ getAiConsultPermission: 'getAiConsultPermission',
+ getAiConsultAssistants: 'getAiConsultAssistants',
+ getAiConsultSessions: 'getAiConsultSessions',
+ getAiConsultSessionDetail: 'getAiConsultSessionDetail',
+ openAiConsultSession: 'openAiConsultSession',
+ sendAiConsultMessage: 'sendAiConsultMessage',
+ closeAiConsultSession: 'closeAiConsultSession',
},
knowledgeBase: {
From 1654b4267eff4eea3583ff637a79c54a536d5d39 Mon Sep 17 00:00:00 2001
From: wangdongbo <>
Date: Fri, 7 Aug 2026 10:10:32 +0800
Subject: [PATCH 2/7] no message
---
pages/home/consult.vue | 2 +-
static/home/ai-consult-assistant.png | Bin 0 -> 7278 bytes
2 files changed, 1 insertion(+), 1 deletion(-)
create mode 100644 static/home/ai-consult-assistant.png
diff --git a/pages/home/consult.vue b/pages/home/consult.vue
index 55171e2..5103aa8 100644
--- a/pages/home/consult.vue
+++ b/pages/home/consult.vue
@@ -84,7 +84,7 @@ const consultItems = ref([
{
id: "aiConsultRecord",
label: "AI咨询记录",
- icon: "/static/home/chat-consult.png",
+ icon: "/static/home/ai-consult-assistant.png",
path: "/pages/ai-consult/list",
},
]);
diff --git a/static/home/ai-consult-assistant.png b/static/home/ai-consult-assistant.png
new file mode 100644
index 0000000000000000000000000000000000000000..e1dfc8d47fe1f09652020705569490b3c63b7b72
GIT binary patch
literal 7278
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
IM6N<$f==8wq5uE@
literal 0
HcmV?d00001
From dace2bb2dab94c18eaef2ece67892e8560f65c1c Mon Sep 17 00:00:00 2001
From: wangdongbo <>
Date: Fri, 7 Aug 2026 18:15:14 +0800
Subject: [PATCH 3/7] =?UTF-8?q?ai=E5=92=A8=E8=AF=A2=E6=9C=8D=E5=8A=A1?=
=?UTF-8?q?=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pages/ai-consult/chat.vue | 20 ++++++++--------
.../components/special-message/evaluation.vue | 24 ++++++++++++-------
.../components/special-message/index.vue | 7 +++++-
3 files changed, 32 insertions(+), 19 deletions(-)
diff --git a/pages/ai-consult/chat.vue b/pages/ai-consult/chat.vue
index ba7793f..d8d1181 100644
--- a/pages/ai-consult/chat.vue
+++ b/pages/ai-consult/chat.vue
@@ -4,9 +4,9 @@
{{ formatMessageTime(item.createTime) }}
- {{ displayContent(item) }}
-
-
+ {{ displayContent(item) }}
+
+
AI
{{ session?.assistantName || 'AI咨询助理' }}
@@ -25,8 +25,8 @@
-
-
+
+
本次AI咨询已结束
@@ -46,7 +46,7 @@ const sessionId = ref('');
const session = ref(null);
const messages = ref([]);
const content = ref('');
-const sending = ref(false);
+const pendingRequestCount = ref(0);
const waitingAi = ref(false);
const bottomId = ref('');
const active = ref(false);
@@ -92,12 +92,12 @@ async function detail() {
await scrollToBottom();
}
async function send() {
- if (!active.value || sending.value || !content.value.trim()) return;
+ if (!active.value || !content.value.trim()) return;
const value = content.value.trim();
const localMessage = { _id: `local-${Date.now()}`, sender: 'patient', content: value, messageType: 'text', createTime: Date.now(), _sendStatus: 'pending' };
messages.value.push(localMessage);
content.value = '';
- sending.value = true;
+ pendingRequestCount.value += 1;
waitingAi.value = true;
await scrollToBottom();
try {
@@ -112,8 +112,8 @@ async function send() {
localMessage._sendStatus = 'failed';
uni.showToast({ title: '发送失败,请重试', icon: 'none' });
} finally {
- sending.value = false;
- waitingAi.value = false;
+ pendingRequestCount.value -= 1;
+ waitingAi.value = pendingRequestCount.value > 0;
await scrollToBottom();
}
}
diff --git a/pages/message/components/special-message/evaluation.vue b/pages/message/components/special-message/evaluation.vue
index 72054c1..a7738c5 100644
--- a/pages/message/components/special-message/evaluation.vue
+++ b/pages/message/components/special-message/evaluation.vue
@@ -85,7 +85,7 @@
\ No newline at end of file
+
From 68c6db7422c5b76e6bdd0fbe079bf42745a55b68 Mon Sep 17 00:00:00 2001
From: wangdongbo <>
Date: Mon, 10 Aug 2026 14:00:23 +0800
Subject: [PATCH 4/7] =?UTF-8?q?=E5=92=A8=E8=AF=A2=E5=8A=A9=E6=89=8B?=
=?UTF-8?q?=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pages/ai-consult/entry.vue | 6 ++++--
pages/archive/edit-archive.vue | 8 +++++++-
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/pages/ai-consult/entry.vue b/pages/ai-consult/entry.vue
index 22a2352..a3a468c 100644
--- a/pages/ai-consult/entry.vue
+++ b/pages/ai-consult/entry.vue
@@ -1,4 +1,4 @@
-请选择本次咨询档案{{item.name || '未命名'}}{{ item.age ? item.age + '岁' : '' }}正在进入AI咨询...
+请选择本次咨询档案{{item.name || '未命名'}}{{ item.age ? item.age + '岁' : '' }}正在前往建档...
diff --git a/pages/archive/edit-archive.vue b/pages/archive/edit-archive.vue
index 8b666a1..367c8fa 100644
--- a/pages/archive/edit-archive.vue
+++ b/pages/archive/edit-archive.vue
@@ -59,6 +59,7 @@ const visible = ref(false);
const referenceCustomer = ref(null)
const healthTypes = ref([]);
const enableHis = ref(false);
+const redirectUrl = ref('');
const formData = computed(() => {
return { ...customer.value, ...form.value, mobile: account.value?.mobile }
@@ -166,6 +167,10 @@ async function addArchive() {
set('home-invite-team-info', { teamId: teamId.value })
if (res && res.success) {
uni.$emit('reloadTeamCustomers')
+ if (redirectUrl.value) {
+ uni.redirectTo({ url: redirectUrl.value });
+ return;
+ }
// getTeam(corpId.value, teamId.value, res.data.id);
if (healthTypes.value.length) {
const nextType = healthTypes.value[0];
@@ -307,6 +312,7 @@ onLoad(options => {
customerId.value = options.id || '';
corpUserId.value = options.corpUserId || '';
referenceCustomerId.value = options.referenceCustomerId || '';
+ redirectUrl.value = options.redirectUrl || '';
if (referenceCustomerId.value) {
getReferenceCustomer();
}
@@ -318,4 +324,4 @@ useLoad(options => {
})
-
\ No newline at end of file
+
From bbf9e81f1f7a9ee7727c012d02c05d200ac7dbe7 Mon Sep 17 00:00:00 2001
From: wangdongbo <>
Date: Tue, 11 Aug 2026 09:21:20 +0800
Subject: [PATCH 5/7] no message
---
pages.json | 2 +-
pages/ai-consult/list.vue | 22 +++++++----
pages/home/consult.vue | 15 --------
pages/message/message.vue | 80 ++++++++++++++++++++++++++++++++++-----
utils/api.js | 1 +
5 files changed, 86 insertions(+), 34 deletions(-)
diff --git a/pages.json b/pages.json
index e47d85e..8d0fb05 100644
--- a/pages.json
+++ b/pages.json
@@ -162,7 +162,7 @@
"pages": [
{
"path": "list",
- "style": { "navigationBarTitleText": "AI咨询记录", "disableScroll": true }
+ "style": { "navigationBarTitleText": "咨询记录", "disableScroll": true }
},
{
"path": "chat",
diff --git a/pages/ai-consult/list.vue b/pages/ai-consult/list.vue
index ea7768c..b7ac116 100644
--- a/pages/ai-consult/list.vue
+++ b/pages/ai-consult/list.vue
@@ -2,13 +2,17 @@
+ {{ item.name }}
+
+
{{ item.name }}
-
-
- {{ item.assistantName }}{{ statusText(item) }}
+
+
+ {{ item.assistantName }}{{ item.statusLabel }}
+ {{ item.sourceLabel }}
团队:{{ item.teamName || item.teamId || '-' }}
档案:{{ item.customerName || '-' }}
最近互动:{{ format(item.lastActiveTime) }}
@@ -26,15 +30,17 @@ import { storeToRefs } from 'pinia';
import FullPage from '@/components/full-page.vue';
import EmptyData from '@/components/empty-data.vue';
const { openid } = storeToRefs(useAccountStore());
-const corpId = ref(''); const customerId = ref(''); const customers = ref([{ name: '全部档案', value: '' }]);
+const corpId = ref(''); const customerId = ref(''); const source = ref('');
+const sources = [{ name: '全部咨询', value: '' }, { name: 'AI咨询', value: 'ai' }, { name: 'IM咨询', value: 'im' }];
+const customers = ref([{ name: '全部档案', value: '' }]);
const list = ref([]); const page = ref(1); const pages = ref(0); const loading = ref(false);
const format = value => value ? new Date(value).toLocaleString('zh-CN', { hour12: false }) : '-';
-const statusText = item => item.status === 'active' ? '咨询中' : item.endReason === 'sensitive_word' ? '敏感词结束' : '已结束';
async function loadCustomers() { const res = await api('getMiniAppCustomers', { corpId: corpId.value, miniAppId: openid.value || uni.getStorageSync('openid') }, false); if (res?.success) customers.value = [customers.value[0], ...(res.data || []).map(item => ({ name: item.name || '未命名', value: item._id }))]; }
-async function load(reset = false) { if (loading.value) return; if (reset) { page.value = 1; list.value = []; } loading.value = true; const res = await api('getAiConsultSessions', { corpId: corpId.value, customerId: customerId.value, miniAppId: openid.value || uni.getStorageSync('openid'), page: page.value, pageSize: 20 }, false); if (res?.success) { list.value = page.value === 1 ? res.list : [...list.value, ...res.list]; pages.value = res.pages || 0; } loading.value = false; }
+async function load(reset = false) { if (loading.value) return; if (reset) { page.value = 1; list.value = []; } loading.value = true; const res = await api('getUnifiedConsultSessions', { corpId: corpId.value, customerId: customerId.value, miniAppId: openid.value || uni.getStorageSync('openid'), source: source.value, page: page.value, pageSize: 20 }, false); if (res?.success) { list.value = page.value === 1 ? res.list : [...list.value, ...res.list]; pages.value = res.pages || 0; } loading.value = false; }
function selectCustomer(value) { if (customerId.value === value) return; customerId.value = value; load(true); }
+function selectSource(value) { if (source.value === value) return; source.value = value; load(true); }
function loadMore() { if (!loading.value && page.value < pages.value) { page.value += 1; load(); } }
-function openChat(item) { uni.navigateTo({ url: `/pages/ai-consult/chat?corpId=${item.corpId}&sessionId=${item._id}` }); }
+function openChat(item) { const url = item.source === 'im' ? `/pages/message/index?conversationID=GROUP${item.groupId}&groupID=${item.groupId}` : `/pages/ai-consult/chat?corpId=${item.corpId}&sessionId=${item.id}`; uni.navigateTo({ url }); }
onLoad(async opts => { corpId.value = opts.corpId || ''; await loadCustomers(); await load(true); });
-
+
diff --git a/pages/home/consult.vue b/pages/home/consult.vue
index 5103aa8..bc60135 100644
--- a/pages/home/consult.vue
+++ b/pages/home/consult.vue
@@ -49,7 +49,6 @@ const props = defineProps({
const { account } = storeToRefs(useAccount());
const consultantPopup = ref(null);
const badgeMap = ref({});
-const aiConsultEnabled = ref(false);
let loading = false;
const consultItems = ref([
@@ -81,12 +80,6 @@ const consultItems = ref([
path: "/pages/rate/rate-list",
badge: 'rate'
},
- {
- id: "aiConsultRecord",
- label: "AI咨询记录",
- icon: "/static/home/ai-consult-assistant.png",
- path: "/pages/ai-consult/list",
- },
]);
const hideMenus = computed(() => {
const result = {};
@@ -94,7 +87,6 @@ const hideMenus = computed(() => {
if (!(props.team && props.team.createSource === 'yzs')) {
result.chat = true;
}
- if (!aiConsultEnabled.value) result.aiConsultRecord = true;
return result;
})
@@ -199,15 +191,8 @@ async function getBadgeCount() {
loading = false;
}
-async function loadAiConsultPermission() {
- if (!props.corpId) return;
- const res = await api('getAiConsultPermission', { corpId: props.corpId }, false);
- aiConsultEnabled.value = Boolean(res?.success && res?.data?.enabled);
-}
-
watch(() => [props.customers, props.teamId, props.corpId], n => {
getBadgeCount()
- loadAiConsultPermission()
}, { immediate: true })
defineExpose({
diff --git a/pages/message/message.vue b/pages/message/message.vue
index 571b47d..2bded82 100644
--- a/pages/message/message.vue
+++ b/pages/message/message.vue
@@ -8,10 +8,11 @@
加载中...
-
-
+
+
{{
conversation.unreadCount > 99 ? "99+" : conversation.unreadCount
@@ -21,13 +22,14 @@
+ AI咨询
咨询人 | {{ conversation.patientName }}
@@ -72,6 +74,7 @@ import { mergeConversationWithGroupDetails } from "@/utils/conversation-merger.j
import { globalUnreadListenerManager } from "@/utils/global-unread-listener.js";
import { get } from "@/utils/cache";
import { normalizeCorpId } from "@/utils/api-base-config";
+import api from "@/utils/api";
import useGroupAvatars from "./hooks/use-group-avatars.js";
import GroupAvatar from "@/components/group-avatar.vue";
import {
@@ -229,9 +232,10 @@ const loadConversationList = async () => {
const result = await globalTimChatManager.getGroupList();
if (result && result.success && result.groupList) {
// 合并后端群组详细信息(已包含格式化和排序)
- conversationList.value = await mergeConversationWithGroupDetails(
+ const imConversations = await mergeConversationWithGroupDetails(
result.groupList
);
+ conversationList.value = mergeConsultationList(imConversations);
console.log(
"群聊列表加载成功,共",
conversationList.value.length,
@@ -250,6 +254,46 @@ const loadConversationList = async () => {
}
};
+function mergeConsultationList(imConversations) {
+ const aiConversations = conversationList.value.filter((item) => item.source === "ai");
+ return [...imConversations, ...aiConversations].sort(
+ (left, right) => (right.lastMessageTime || 0) - (left.lastMessageTime || 0)
+ );
+}
+
+const loadAiConsultationList = async () => {
+ const corpId = getCurrentTeamCorpId();
+ const miniAppId = openid.value || account.value?.openid || "";
+ if (!corpId || !miniAppId) return;
+ try {
+ const result = await api("getUnifiedConsultSessions", {
+ corpId,
+ miniAppId,
+ source: "ai",
+ page: 1,
+ pageSize: 100,
+ }, false);
+ if (!result?.success) return;
+ const imConversations = conversationList.value.filter((item) => item.source !== "ai");
+ const aiConversations = (result.list || []).map((item) => ({
+ source: "ai",
+ sessionId: item.id,
+ corpId: item.corpId,
+ displayName: item.assistantName || "AI咨询助理",
+ teamName: item.teamName || "",
+ patientName: item.customerName || "未命名患者",
+ lastMessage: item.statusLabel || "AI咨询",
+ lastMessageTime: item.lastActiveTime || 0,
+ unreadCount: 0,
+ }));
+ conversationList.value = [...imConversations, ...aiConversations].sort(
+ (left, right) => (right.lastMessageTime || 0) - (left.lastMessageTime || 0)
+ );
+ } catch (error) {
+ console.log("加载AI咨询记录异常:", error.message);
+ }
+};
+
// 防抖更新定时器
let updateTimer = null;
@@ -438,6 +482,13 @@ const formatMessageTime = (timestamp) => {
const handleClickConversation = async (conversation) => {
console.log("点击会话:", conversation);
+ if (conversation.source === "ai") {
+ uni.navigateTo({
+ url: `/pages/ai-consult/chat?corpId=${conversation.corpId}&sessionId=${conversation.sessionId}`,
+ });
+ return;
+ }
+
// 立即清除本地未读数显示
const conversationIndex = conversationList.value.findIndex(
(conv) => conv.conversationID === conversation.conversationID
@@ -480,11 +531,11 @@ const handleLoadMore = () => {
// 下拉刷新
const handleRefresh = async () => {
- if (!hasImCorpId.value) return;
refreshing.value = true;
try {
- await loadConversationList();
+ if (hasImCorpId.value) await loadConversationList();
+ await loadAiConsultationList();
} finally {
refreshing.value = false;
}
@@ -499,7 +550,8 @@ async function init() {
console.log("IM初始化失败,继续加载列表");
}
// 先加载初始会话列表
- await loadConversationList();
+ if (imReady) await loadConversationList();
+ await loadAiConsultationList();
// 再设置监听器,后续通过事件更新列表
setupConversationListener();
} catch (error) {
@@ -580,9 +632,7 @@ onHide(() => {
});
watch(hasImCorpId, (n, o) => {
- if (n && !o) {
- init();
- }
+ if (n || !o) init();
}, { immediate: true })
// 页面卸载
onUnmounted(() => {
@@ -783,6 +833,16 @@ onUnmounted(() => {
padding-bottom: 10rpx;
}
+.source-tag {
+ display: inline-block;
+ margin-right: 10rpx;
+ padding: 1rpx 8rpx;
+ border-radius: 6rpx;
+ color: #0877f1;
+ background: #e8f3ff;
+ font-size: 22rpx;
+}
+
.subscribe-entry {
position: fixed;
right: 32rpx;
diff --git a/utils/api.js b/utils/api.js
index 1daba3e..c30e12c 100644
--- a/utils/api.js
+++ b/utils/api.js
@@ -23,6 +23,7 @@ const urlsConfig = {
getAiConsultPermission: 'getAiConsultPermission',
getAiConsultAssistants: 'getAiConsultAssistants',
getAiConsultSessions: 'getAiConsultSessions',
+ getUnifiedConsultSessions: 'getUnifiedConsultSessions',
getAiConsultSessionDetail: 'getAiConsultSessionDetail',
openAiConsultSession: 'openAiConsultSession',
sendAiConsultMessage: 'sendAiConsultMessage',
From 3770881c923dc8dd61d677ef277f772402b3cbc0 Mon Sep 17 00:00:00 2001
From: wangdongbo <>
Date: Thu, 13 Aug 2026 09:47:38 +0800
Subject: [PATCH 6/7] =?UTF-8?q?ai=E5=92=A8=E8=AF=A2=E5=8A=A9=E6=89=8B?=
=?UTF-8?q?=E8=B0=83=E6=95=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pages/login/login.vue | 5 ++++-
pages/login/redirect-page.vue | 15 ++++++++++++---
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/pages/login/login.vue b/pages/login/login.vue
index caac2c2..2b2ce5b 100644
--- a/pages/login/login.vue
+++ b/pages/login/login.vue
@@ -132,6 +132,9 @@ async function bindTeam() {
return toast("关联团队失败");
}
await syncExternalUserRelation();
+ if (redirectUrl.value) {
+ return attempToPage(redirectUrl.value);
+ }
const res1 = await api('getWxAppCustomerCount', { miniAppId: account.value.openid, corpId: team.value.corpId, teamId: team.value.teamId });
if (res1 && res1.data > 0) {
toHome();
@@ -166,7 +169,7 @@ async function attempToPage(url) {
onLoad((opts) => {
if (opts.source === "teamInvite") {
team.value = get("invite-team-info");
- redirectUrl.value = `/pages/archive/edit-archive?corpUserId=${team.value.corpUserId || ''}&teamId=${team.value.teamId}&corpId=${team.value.corpId}`;
+ redirectUrl.value = team.value.redirectUrl || `/pages/archive/edit-archive?corpUserId=${team.value.corpUserId || ''}&teamId=${team.value.teamId}&corpId=${team.value.corpId}`;
return;
}
redirectUrl.value = opts.redirectUrl || "";
diff --git a/pages/login/redirect-page.vue b/pages/login/redirect-page.vue
index 472ae95..17bc8df 100644
--- a/pages/login/redirect-page.vue
+++ b/pages/login/redirect-page.vue
@@ -75,8 +75,13 @@ async function syncExternalUserRelation({ corpId, externalUserId, corpUserId })
}
}
-async function changeTeam({ teamId, corpId, corpUserId, externalUserId, qrid, referenceCustomerId }) {
+function getAiConsultEntryUrl({ teamId, corpId, qrid }) {
+ return `/pages/ai-consult/entry?teamId=${teamId || ''}&corpId=${corpId || ''}&qrid=${qrid || ''}`;
+}
+
+async function changeTeam({ teamId, corpId, corpUserId, externalUserId, qrid, referenceCustomerId, type }) {
const normalizedCorpId = normalizeCorpId(corpId);
+ const redirectUrl = type === 'aiConsult' ? getAiConsultEntryUrl({ teamId, corpId: normalizedCorpId, qrid }) : '';
loading.value = true;
const res = await api("getTeamData", { teamId, corpId: normalizedCorpId, withCorpName: true });
loading.value = false;
@@ -96,13 +101,14 @@ async function changeTeam({ teamId, corpId, corpUserId, externalUserId, qrid, re
});
await login('', { forceVerify: true })
if (account.value && account.value.mobile) {
- bindTeam({ corpUserId, externalUserId })
+ bindTeam({ corpUserId, externalUserId, redirectUrl })
} else {
set("invite-team-info", {
corpUserId,
externalUserId,
qrid,
referenceCustomerId,
+ redirectUrl,
corpId: team.value.corpId,
teamId: team.value.teamId,
corpName: team.value.corpName,
@@ -121,7 +127,7 @@ async function changeTeam({ teamId, corpId, corpUserId, externalUserId, qrid, re
}
}
-async function bindTeam({ corpUserId, externalUserId }) {
+async function bindTeam({ corpUserId, externalUserId, redirectUrl = '' }) {
const res = await api('bindWxappWithTeam', { appid, corpId: team.value.corpId, teamId: team.value.teamId, openid: account.value.openid });
if (!res || !res.success) {
return toast("关联团队失败");
@@ -131,6 +137,9 @@ async function bindTeam({ corpUserId, externalUserId }) {
externalUserId,
corpUserId,
});
+ if (redirectUrl) {
+ return uni.redirectTo({ url: redirectUrl });
+ }
const res1 = await api('getWxAppCustomerCount', { miniAppId: account.value.openid, corpId: team.value.corpId, teamId: team.value.teamId });
if (res1 && res1.data > 0) {
uni.switchTab({
From fdf9428f36f64c6dc69aa586209395b3cdaf8bc4 Mon Sep 17 00:00:00 2001
From: wangdongbo <>
Date: Fri, 14 Aug 2026 10:13:46 +0800
Subject: [PATCH 7/7] no message
---
pages/ai-consult/chat.vue | 4 +-
pages/ai-consult/entry.vue | 102 ++++++++++++++++++++++++++++++++++---
2 files changed, 96 insertions(+), 10 deletions(-)
diff --git a/pages/ai-consult/chat.vue b/pages/ai-consult/chat.vue
index d8d1181..3942999 100644
--- a/pages/ai-consult/chat.vue
+++ b/pages/ai-consult/chat.vue
@@ -4,8 +4,8 @@
{{ formatMessageTime(item.createTime) }}
- {{ displayContent(item) }}
-
+
+ {{ displayContent(item) }}
AI
diff --git a/pages/ai-consult/entry.vue b/pages/ai-consult/entry.vue
index a3a468c..13974e0 100644
--- a/pages/ai-consult/entry.vue
+++ b/pages/ai-consult/entry.vue
@@ -1,14 +1,100 @@
-请选择本次咨询档案{{item.name || '未命名'}}{{ item.age ? item.age + '岁' : '' }}正在前往建档...
+
+
+
+ 请选择本次咨询档案
+
+
+
+
+ {{ item.sex }}
+ /
+ {{ item.age }}岁
+ ,
+ {{ item.mobile }}
+
+ 证件号:{{ item.idCard || '--' }}
+
+
+
+
+ 正在前往建档...
+
+
+
+
+const { account, openid } = storeToRefs(useAccountStore());
+const corpId = ref('');
+const teamId = ref('');
+const assistantId = ref('');
+const qrid = ref('');
+const customers = ref([]);
+const enableHis = ref(false);
+const loaded = ref(false);
+
+function getEntryUrl() {
+ return `/pages/ai-consult/entry?corpId=${corpId.value}&teamId=${teamId.value}&assistantId=${assistantId.value}&qrid=${qrid.value}`;
+}
+
+function toLogin() {
+ uni.redirectTo({ url: `/pages/login/login?redirectUrl=${encodeURIComponent(getEntryUrl())}` });
+}
+
+function toCreateArchive() {
+ uni.redirectTo({ url: `/pages/archive/edit-archive?corpId=${corpId.value}&teamId=${teamId.value}&redirectUrl=${encodeURIComponent(getEntryUrl())}` });
+}
+
+async function load() {
+ const miniAppId = openid.value || uni.getStorageSync('openid');
+ const res = await api('getMiniAppCustomers', { corpId: corpId.value, miniAppId }, false);
+ loaded.value = true;
+ if (!res?.success) return uni.showToast({ title: res?.message || '查询档案失败', icon: 'none' });
+ customers.value = res.data || [];
+ enableHis.value = res.enableHis === true;
+ if (!customers.value.length) toCreateArchive();
+}
+
+async function open(customer) {
+ const res = await api('openAiConsultSession', { corpId: corpId.value, teamId: teamId.value, assistantId: assistantId.value, qrid: qrid.value, customerId: customer?._id || '', miniAppId: openid.value || uni.getStorageSync('openid') });
+ if (!res?.success) return uni.showToast({ title: res?.message || '创建失败', icon: 'none' });
+ uni.redirectTo({ url: `/pages/ai-consult/chat?corpId=${corpId.value}&sessionId=${res.data.session._id}` });
+}
+
+onLoad((opts) => {
+ corpId.value = opts.corpId || '';
+ teamId.value = opts.teamId || '';
+ assistantId.value = opts.assistantId || '';
+ qrid.value = opts.qrid || '';
+ if (!account.value?.mobile) return toLogin();
+ load();
+});
+
+
+