Merge branch 'dev-wdb' of http://175.27.226.205:3000/huxuejian/ykt-wxapp into dev-wdb
This commit is contained in:
commit
dae3b4d125
@ -6,14 +6,11 @@ $text-color-sub: #999;
|
|||||||
$primary-color: #0877F1;
|
$primary-color: #0877F1;
|
||||||
|
|
||||||
.chat-page {
|
.chat-page {
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 患者信息栏样式 */
|
/* 患者信息栏样式 */
|
||||||
@ -90,6 +87,7 @@ $primary-color: #0877F1;
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-content-compressed {
|
.chat-content-compressed {
|
||||||
@ -359,6 +357,7 @@ $primary-color: #0877F1;
|
|||||||
position: relative;
|
position: relative;
|
||||||
z-index: 200;
|
z-index: 200;
|
||||||
padding-bottom: env(safe-area-inset-bottom);
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-toolbar {
|
.input-toolbar {
|
||||||
@ -378,6 +377,14 @@ $primary-color: #0877F1;
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.voice-toggle-icon {
|
||||||
|
width: 56rpx;
|
||||||
|
height: 56rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
.plus-btn {
|
.plus-btn {
|
||||||
width: 56rpx;
|
width: 56rpx;
|
||||||
height: 56rpx;
|
height: 56rpx;
|
||||||
|
|||||||
@ -2,13 +2,13 @@
|
|||||||
<view class="input-section">
|
<view class="input-section">
|
||||||
<view class="input-toolbar">
|
<view class="input-toolbar">
|
||||||
<view @click="toggleVoiceInput" class="voice-toggle-btn">
|
<view @click="toggleVoiceInput" class="voice-toggle-btn">
|
||||||
<uni-icons v-if="showVoiceInput" fontFamily="keyboard" :size="28">{{ '' }}</uni-icons>
|
<image v-if="showVoiceInput" src="/static/jianpan.png" class="voice-toggle-icon" mode="aspectFit"></image>
|
||||||
<uni-icons v-else type="mic" size="28" color="#666" />
|
<uni-icons v-else type="mic" size="28" color="#666" />
|
||||||
</view>
|
</view>
|
||||||
<view class="input-area">
|
<view class="input-area">
|
||||||
<textarea v-if="!showVoiceInput" class="text-input" v-model="inputText" placeholder="我来说两句..."
|
<textarea v-if="!showVoiceInput" class="text-input" v-model="inputText" placeholder="我来说两句..."
|
||||||
@confirm="sendTextMessage" @focus="handleInputFocus" @input="handleInput"
|
@confirm="sendTextMessage" @focus="handleInputFocus" @input="handleInput"
|
||||||
:auto-height="true" :show-confirm-bar="false" :adjust-position="true" :cursor-spacing="40"
|
:auto-height="true" :show-confirm-bar="false" :adjust-position="true" :cursor-spacing="60"
|
||||||
/>
|
/>
|
||||||
<input v-else class="voice-input-btn" :class="{ recording: isRecording }" @touchstart="startRecord"
|
<input v-else class="voice-input-btn" :class="{ recording: isRecording }" @touchstart="startRecord"
|
||||||
@touchmove="onRecordTouchMove" @touchend="stopRecord" @touchcancel="cancelRecord" :placeholder="isRecording ? '松开发送' : '按住说话'" disabled>
|
@touchmove="onRecordTouchMove" @touchend="stopRecord" @touchcancel="cancelRecord" :placeholder="isRecording ? '松开发送' : '按住说话'" disabled>
|
||||||
@ -463,7 +463,7 @@ const morePanelButtons = computed(() => {
|
|||||||
// 已结束状态:显示"开启会话"按钮
|
// 已结束状态:显示"开启会话"按钮
|
||||||
buttons.push({
|
buttons.push({
|
||||||
text: "开启会话",
|
text: "开启会话",
|
||||||
icon: "/static/icon/kaiqihuihua.png",
|
icon: "/static/icon/openChat.png",
|
||||||
action: handleOpenConsult,
|
action: handleOpenConsult,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -10,13 +10,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from 'vue';
|
import { computed } from "vue";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
message: {
|
message: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({}),
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const payload = computed(() => props.message?.payload || {});
|
const payload = computed(() => props.message?.payload || {});
|
||||||
@ -26,16 +26,17 @@ const systemMessageData = computed(() => {
|
|||||||
try {
|
try {
|
||||||
// 尝试从 payload.data 解析系统消息
|
// 尝试从 payload.data 解析系统消息
|
||||||
if (payload.value.data) {
|
if (payload.value.data) {
|
||||||
const data = typeof payload.value.data === 'string'
|
const data =
|
||||||
|
typeof payload.value.data === "string"
|
||||||
? JSON.parse(payload.value.data)
|
? JSON.parse(payload.value.data)
|
||||||
: payload.value.data;
|
: payload.value.data;
|
||||||
|
|
||||||
if (data.type === 'system_message') {
|
if (data.type === "system_message") {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('解析系统消息失败:', e);
|
console.error("解析系统消息失败:", e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
@ -44,12 +45,12 @@ const systemMessageData = computed(() => {
|
|||||||
const extension = computed(() => {
|
const extension = computed(() => {
|
||||||
try {
|
try {
|
||||||
if (payload.value.extension) {
|
if (payload.value.extension) {
|
||||||
return typeof payload.value.extension === 'string'
|
return typeof payload.value.extension === "string"
|
||||||
? JSON.parse(payload.value.extension)
|
? JSON.parse(payload.value.extension)
|
||||||
: payload.value.extension;
|
: payload.value.extension;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('解析扩展信息失败:', e);
|
console.error("解析扩展信息失败:", e);
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
});
|
});
|
||||||
@ -65,20 +66,20 @@ const text = computed(() => {
|
|||||||
if (systemMessageData.value?.messageType) {
|
if (systemMessageData.value?.messageType) {
|
||||||
const messageType = systemMessageData.value.messageType;
|
const messageType = systemMessageData.value.messageType;
|
||||||
switch (messageType) {
|
switch (messageType) {
|
||||||
case 'consult_pending':
|
case "consult_pending":
|
||||||
return '患者已发起咨询申请,请及时接诊';
|
return "患者已发起咨询申请,请及时接诊";
|
||||||
case 'consult_accepted':
|
case "consult_accepted":
|
||||||
return '医生已接诊';
|
return "医生已接诊";
|
||||||
case 'consult_rejected':
|
case "consult_rejected":
|
||||||
return '医生暂时无法接诊';
|
return "医生暂时无法接诊";
|
||||||
case 'consult_ended':
|
case "consult_ended":
|
||||||
return '问诊已结束';
|
return "问诊已结束";
|
||||||
case 'consult_timeout':
|
case "consult_timeout":
|
||||||
return '问诊已超时';
|
return "问诊已超时";
|
||||||
case 'consult_reopened':
|
case "consult_reopened":
|
||||||
return '会话已重新开启';
|
return "会话已重新开启";
|
||||||
default:
|
default:
|
||||||
return systemMessageData.value.content || '[系统消息]';
|
return systemMessageData.value.content || "[系统消息]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +89,7 @@ const text = computed(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 兼容旧格式:直接从 payload.data 获取
|
// 兼容旧格式:直接从 payload.data 获取
|
||||||
if (payload.value.data && typeof payload.value.data === 'string') {
|
if (payload.value.data && typeof payload.value.data === "string") {
|
||||||
// 如果 data 不是 JSON 格式,直接显示
|
// 如果 data 不是 JSON 格式,直接显示
|
||||||
try {
|
try {
|
||||||
JSON.parse(payload.value.data);
|
JSON.parse(payload.value.data);
|
||||||
@ -97,7 +98,7 @@ const text = computed(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return '[系统消息]';
|
return "[系统消息]";
|
||||||
});
|
});
|
||||||
|
|
||||||
// 通知文本(红色提示)
|
// 通知文本(红色提示)
|
||||||
@ -111,24 +112,23 @@ const notifyText = computed(() => {
|
|||||||
if (systemMessageData.value) {
|
if (systemMessageData.value) {
|
||||||
const messageType = systemMessageData.value.messageType;
|
const messageType = systemMessageData.value.messageType;
|
||||||
switch (messageType) {
|
switch (messageType) {
|
||||||
case 'consult_pending':
|
case "consult_pending":
|
||||||
return '待接诊';
|
return "待接诊";
|
||||||
case 'consult_rejected':
|
case "consult_rejected":
|
||||||
return '已拒绝';
|
return "已拒绝";
|
||||||
case 'consult_timeout':
|
case "consult_timeout":
|
||||||
return '已超时';
|
return "已超时";
|
||||||
case 'consult_accepted':
|
case "consult_accepted":
|
||||||
return '已接诊';
|
return "已接诊";
|
||||||
case 'consult_ended':
|
case "consult_ended":
|
||||||
return '已结束';
|
return "已结束";
|
||||||
default:
|
default:
|
||||||
return '';
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return "";
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@ -886,7 +886,7 @@ const handleRejectReasonConfirm = async (reason) => {
|
|||||||
const currentGroupId = chatInfo.value.conversationID.replace("GROUP", "");
|
const currentGroupId = chatInfo.value.conversationID.replace("GROUP", "");
|
||||||
|
|
||||||
// 调用后端接口发送拒绝消息
|
// 调用后端接口发送拒绝消息
|
||||||
const result = await api("sendConsultRejectedMessage", {
|
const result = await api("rejectConsultation", {
|
||||||
groupId: currentGroupId,
|
groupId: currentGroupId,
|
||||||
memberName,
|
memberName,
|
||||||
reason,
|
reason,
|
||||||
|
|||||||
BIN
static/icon/openChat.png
Normal file
BIN
static/icon/openChat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 752 B |
BIN
static/jianpan.png
Normal file
BIN
static/jianpan.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
@ -24,8 +24,8 @@ export default defineStore("accountStore", () => {
|
|||||||
// IM 相关
|
// IM 相关
|
||||||
const openid = ref(cache.get(CACHE_KEYS.OPENID, ""));
|
const openid = ref(cache.get(CACHE_KEYS.OPENID, ""));
|
||||||
const isIMInitialized = ref(false);
|
const isIMInitialized = ref(false);
|
||||||
// 医生信息
|
// 医生信息 - 不做缓冲处理,每次都重新获取
|
||||||
const doctorInfo = ref(cache.get(CACHE_KEYS.DOCTOR_INFO, null));
|
const doctorInfo = ref(null);
|
||||||
|
|
||||||
function getLoginPromise(phoneCode = '') {
|
function getLoginPromise(phoneCode = '') {
|
||||||
if (loginPromise.value) return loginPromise.value;
|
if (loginPromise.value) return loginPromise.value;
|
||||||
@ -87,12 +87,19 @@ export default defineStore("accountStore", () => {
|
|||||||
weChatOpenId: account.value.openid,
|
weChatOpenId: account.value.openid,
|
||||||
});
|
});
|
||||||
doctorInfo.value = res?.data || null;
|
doctorInfo.value = res?.data || null;
|
||||||
if (doctorInfo.value.accountState && doctorInfo.value.accountState == "disable") {
|
|
||||||
|
// 检查账号是否被禁用
|
||||||
|
if (doctorInfo.value?.accountState === "disable") {
|
||||||
|
uni.showModal({
|
||||||
|
title: '账号被禁用',
|
||||||
|
content: '您的账号已被禁用,请联系管理员',
|
||||||
|
showCancel: false,
|
||||||
|
confirmText: '确定',
|
||||||
|
success: () => {
|
||||||
uni.redirectTo({ url: "/pages/login/login" });
|
uni.redirectTo({ url: "/pages/login/login" });
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (res?.data) {
|
});
|
||||||
cache.set(CACHE_KEYS.DOCTOR_INFO, res.data);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -137,7 +144,6 @@ export default defineStore("accountStore", () => {
|
|||||||
// 清空缓存
|
// 清空缓存
|
||||||
cache.remove(CACHE_KEYS.ACCOUNT);
|
cache.remove(CACHE_KEYS.ACCOUNT);
|
||||||
cache.remove(CACHE_KEYS.OPENID);
|
cache.remove(CACHE_KEYS.OPENID);
|
||||||
cache.remove(CACHE_KEYS.DOCTOR_INFO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return { account, openid, isIMInitialized, doctorInfo, login, getDoctorInfo, initIMAfterLogin, logout }
|
return { account, openid, isIMInitialized, doctorInfo, login, getDoctorInfo, initIMAfterLogin, logout }
|
||||||
|
|||||||
@ -104,7 +104,8 @@ const urlsConfig = {
|
|||||||
getChatRecordsByGroupId: "getChatRecordsByGroupId",
|
getChatRecordsByGroupId: "getChatRecordsByGroupId",
|
||||||
getGroupList: "getGroupList",
|
getGroupList: "getGroupList",
|
||||||
followUpInquiry: "followUpInquiry",
|
followUpInquiry: "followUpInquiry",
|
||||||
supplementMedicalCase: "supplementMedicalCase"
|
supplementMedicalCase: "supplementMedicalCase",
|
||||||
|
rejectConsultation: "rejectConsultation"
|
||||||
},
|
},
|
||||||
todo: {
|
todo: {
|
||||||
getCustomerTodos: 'getCustomerTodos',
|
getCustomerTodos: 'getCustomerTodos',
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
import { globalTimChatManager } from './tim-chat.js';
|
import { globalTimChatManager } from './tim-chat.js';
|
||||||
import api from './api.js';
|
import api from './api.js';
|
||||||
import { toast } from './widget.js';
|
import { toast } from './widget.js';
|
||||||
|
const env = __VITE_ENV__;
|
||||||
/**
|
/**
|
||||||
* 发送文字消息
|
* 发送文字消息
|
||||||
* @param {string} content - 文字内容
|
* @param {string} content - 文字内容
|
||||||
@ -137,7 +137,7 @@ export async function sendArticleMessage(article, options = {}) {
|
|||||||
/**
|
/**
|
||||||
* 发送问卷消息
|
* 发送问卷消息
|
||||||
* @param {Object} survey - 问卷对象 { _id, name, surveryId, url, createBy }
|
* @param {Object} survey - 问卷对象 { _id, name, surveryId, url, createBy }
|
||||||
* @param {Object} options - 额外选项 { userId, customerId, customerName, corpId, env }
|
* @param {Object} options - 额外选项 { userId, customerId, customerName, corpId }
|
||||||
* @returns {Promise<boolean>} 发送是否成功
|
* @returns {Promise<boolean>} 发送是否成功
|
||||||
*/
|
*/
|
||||||
export async function sendSurveyMessage(survey, options = {}) {
|
export async function sendSurveyMessage(survey, options = {}) {
|
||||||
@ -186,8 +186,7 @@ export async function sendSurveyMessage(survey, options = {}) {
|
|||||||
sendSurveyId,
|
sendSurveyId,
|
||||||
{
|
{
|
||||||
corpId: options.corpId,
|
corpId: options.corpId,
|
||||||
userId: options.userId,
|
userId: options.userId
|
||||||
env: options.env,
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -235,10 +234,10 @@ function generateRandomString(length) {
|
|||||||
* @returns {string} 问卷链接
|
* @returns {string} 问卷链接
|
||||||
*/
|
*/
|
||||||
function generateSendLink(survey, answerId, customerId, customerName, sendSurveyId, context = {}) {
|
function generateSendLink(survey, answerId, customerId, customerName, sendSurveyId, context = {}) {
|
||||||
const { corpId, userId, env } = context;
|
const { corpId, userId } = context;
|
||||||
const isSystem = survey.createBy === 'system';
|
const isSystem = survey.createBy === 'system';
|
||||||
let url = '';
|
let url = '';
|
||||||
|
debugger
|
||||||
if (isSystem) {
|
if (isSystem) {
|
||||||
// 系统问卷:使用 VITE_SURVEY_URL
|
// 系统问卷:使用 VITE_SURVEY_URL
|
||||||
url = `${env?.MP_SURVEY_URL}?corpId=${corpId}&surveryId=${survey.surveryId}&memberId=${customerId}&sendSurveyId=${sendSurveyId}&userId=${userId}`;
|
url = `${env?.MP_SURVEY_URL}?corpId=${corpId}&surveryId=${survey.surveryId}&memberId=${customerId}&sendSurveyId=${sendSurveyId}&userId=${userId}`;
|
||||||
@ -318,8 +317,7 @@ export async function handleFollowUpMessages(messages, context = {}) {
|
|||||||
userId: context.userId,
|
userId: context.userId,
|
||||||
customerId: context.customerId,
|
customerId: context.customerId,
|
||||||
customerName: context.customerName,
|
customerName: context.customerName,
|
||||||
corpId: context.corpId,
|
corpId: context.corpId
|
||||||
env: context.env,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2728,21 +2728,10 @@ class TimChatManager {
|
|||||||
if (!conversationID.startsWith('GROUP')) {
|
if (!conversationID.startsWith('GROUP')) {
|
||||||
formattedConversationID = `GROUP${conversationID}`
|
formattedConversationID = `GROUP${conversationID}`
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('📖 标记会话为已读:', formattedConversationID);
|
|
||||||
|
|
||||||
this.tim.setMessageRead({
|
|
||||||
conversationID: formattedConversationID
|
|
||||||
}).then(() => {
|
|
||||||
console.log('✓ 会话已标记为已读:', formattedConversationID);
|
|
||||||
// 触发会话列表更新回调,通知消息列表页面清空未读数
|
|
||||||
this.triggerCallback('onConversationListUpdated', {
|
this.triggerCallback('onConversationListUpdated', {
|
||||||
conversationID: formattedConversationID,
|
conversationID: formattedConversationID,
|
||||||
unreadCount: 0
|
unreadCount: 0
|
||||||
})
|
})
|
||||||
}).catch(error => {
|
|
||||||
console.error('✗ 标记会话已读失败:', error)
|
|
||||||
})
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('✗ 标记会话已读异常:', error)
|
console.error('✗ 标记会话已读异常:', error)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user