Compare commits
2 Commits
0dfb05fe97
...
f1f148d8a1
| Author | SHA1 | Date | |
|---|---|---|---|
| f1f148d8a1 | |||
| 00478235e7 |
10
.env.production
Normal file
10
.env.production
Normal file
@ -0,0 +1,10 @@
|
||||
MP_API_BASE_URL=https://ytk.youcan365.com
|
||||
MP_IMAGE_URL=https://ytk.youcan365.com
|
||||
MP_CACHE_PREFIX=production
|
||||
MP_WX_APP_ID=wx1d8337a40c11d66c
|
||||
MP_CORP_ID=wpLgjyawAA8N0gWmXgyJq8wpjGcOT7fg
|
||||
MP_TIM_SDK_APP_ID=1600123876
|
||||
MP_INVITE_TEAMMATE_QRCODE=https://ykt.youcan365.com/invite-teammate
|
||||
MP_INVITE_PATIENT_QRCODE=https://ykt.youcan365.com/invite-patient
|
||||
MP_PATIENT_PAGE_BASE_URL= 'https://www.youcan365.com/h5/#/'
|
||||
MP_SURVEY_URL= 'https://www.youcan365.com/surveyDev/#/pages/survey/survey'
|
||||
473
pages/case/ai-medical-case-form.vue
Normal file
473
pages/case/ai-medical-case-form.vue
Normal file
@ -0,0 +1,473 @@
|
||||
<template>
|
||||
<view class="medical-case-form">
|
||||
<view class="form-container">
|
||||
<!-- 动态渲染表单字段 -->
|
||||
<view
|
||||
v-for="field in currentFields"
|
||||
:key="field.key"
|
||||
class="form-item"
|
||||
:class="{ required: field.required }"
|
||||
>
|
||||
<view class="item-label">{{ field.label }}</view>
|
||||
|
||||
<!-- 日期选择器 -->
|
||||
<picker
|
||||
v-if="field.type === 'date'"
|
||||
mode="date"
|
||||
:value="formData[field.key]"
|
||||
@change="onDateChange(field.key, $event)"
|
||||
:disabled="!isEditing"
|
||||
>
|
||||
<view class="picker-value">
|
||||
{{ formData[field.key] || "暂无" }}
|
||||
</view>
|
||||
</picker>
|
||||
|
||||
<!-- 多行文本 -->
|
||||
<textarea
|
||||
v-else-if="field.type === 'textarea'"
|
||||
class="item-textarea"
|
||||
v-model="formData[field.key]"
|
||||
placeholder="请输入"
|
||||
:disabled="!isEditing"
|
||||
/>
|
||||
|
||||
<!-- 单行文本 -->
|
||||
<input
|
||||
v-else
|
||||
class="item-input"
|
||||
v-model="formData[field.key]"
|
||||
placeholder="暂无"
|
||||
:disabled="!isEditing"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="footer-buttons">
|
||||
<view class="btn-regenerate" @click="handleRegenerate">
|
||||
<text class="btn-text">重新生成</text>
|
||||
</view>
|
||||
<view class="btn-save" @click="handleSave">
|
||||
<text class="btn-text">保存至档案</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from "vue";
|
||||
import { storeToRefs } from "pinia";
|
||||
import useAccountStore from "@/store/account";
|
||||
import api from "@/utils/api.js";
|
||||
const caseType = ref("");
|
||||
const formData = ref({});
|
||||
const isEditing = ref(true);
|
||||
const customerId = ref("");
|
||||
const groupId = ref("");
|
||||
const accountStore = useAccountStore();
|
||||
const { doctorInfo } = storeToRefs(accountStore);
|
||||
// 病历类型名称
|
||||
const CASE_TYPE_NAMES = {
|
||||
outpatient: "门诊病历",
|
||||
inhospital: "住院病历",
|
||||
physicalExaminationTemplate: "体检记录",
|
||||
preConsultation: "预问诊记录",
|
||||
};
|
||||
|
||||
// 字段标签
|
||||
const FIELD_LABELS = {
|
||||
// 门诊病历
|
||||
visitTime: "就诊日期",
|
||||
chiefComplaint: "主诉",
|
||||
medicalHistorySummary: "病史概要",
|
||||
examination: "检查",
|
||||
diagnosisName: "门诊诊断",
|
||||
// 住院病历
|
||||
inhosDate: "入院日期",
|
||||
operation: "手术记录",
|
||||
operationDate: "手术日期",
|
||||
treatmentPlan: "治疗方案",
|
||||
// 体检记录
|
||||
inspectTime: "体检日期",
|
||||
inspectSummary: "体检小结",
|
||||
positiveFind: "阳性发现及处理意见",
|
||||
// 预问诊记录
|
||||
presentIllnessHistory: "现病史",
|
||||
pastMedicalHistory: "既往史",
|
||||
};
|
||||
|
||||
// 字段配置:根据病历类型定义字段
|
||||
const FIELD_CONFIG = {
|
||||
outpatient: [
|
||||
{
|
||||
key: "visitTime",
|
||||
label: FIELD_LABELS.visitTime,
|
||||
type: "date",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: "diagnosisName",
|
||||
label: FIELD_LABELS.diagnosisName,
|
||||
type: "textarea",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: "chiefComplaint",
|
||||
label: FIELD_LABELS.chiefComplaint,
|
||||
type: "textarea",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: "medicalHistorySummary",
|
||||
label: FIELD_LABELS.medicalHistorySummary,
|
||||
type: "textarea",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: "examination",
|
||||
label: FIELD_LABELS.examination,
|
||||
type: "textarea",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: "treatmentPlan",
|
||||
label: "治疗方案",
|
||||
type: "textarea",
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
inhospital: [
|
||||
{
|
||||
key: "inhosDate",
|
||||
label: FIELD_LABELS.inhosDate,
|
||||
type: "date",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: "diagnosisName",
|
||||
label: "住院主诊断",
|
||||
type: "textarea",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: "operation",
|
||||
label: FIELD_LABELS.operation,
|
||||
type: "textarea",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: "operationDate",
|
||||
label: FIELD_LABELS.operationDate,
|
||||
type: "date",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: "treatmentPlan",
|
||||
label: FIELD_LABELS.treatmentPlan,
|
||||
type: "textarea",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: "chiefComplaint",
|
||||
label: FIELD_LABELS.chiefComplaint,
|
||||
type: "textarea",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: "medicalHistorySummary",
|
||||
label: FIELD_LABELS.medicalHistorySummary,
|
||||
type: "textarea",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: "examination",
|
||||
label: FIELD_LABELS.examination,
|
||||
type: "textarea",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: "treatmentPlan",
|
||||
label: "治疗方案",
|
||||
type: "textarea",
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
physicalExaminationTemplate: [
|
||||
{
|
||||
key: "inspectTime",
|
||||
label: FIELD_LABELS.inspectTime,
|
||||
type: "date",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: "inspectSummary",
|
||||
label: FIELD_LABELS.inspectSummary,
|
||||
type: "textarea",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: "positiveFind",
|
||||
label: FIELD_LABELS.positiveFind,
|
||||
type: "textarea",
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
preConsultation: [
|
||||
{
|
||||
key: "chiefComplaint",
|
||||
label: FIELD_LABELS.chiefComplaint,
|
||||
type: "textarea",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: "presentIllnessHistory",
|
||||
label: FIELD_LABELS.presentIllnessHistory,
|
||||
type: "textarea",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
key: "pastMedicalHistory",
|
||||
label: FIELD_LABELS.pastMedicalHistory,
|
||||
type: "textarea",
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// 当前病历类型的字段配置
|
||||
const currentFields = computed(() => {
|
||||
return FIELD_CONFIG[caseType.value] || [];
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
const pages = getCurrentPages();
|
||||
const currentPage = pages[pages.length - 1];
|
||||
const options = currentPage.options;
|
||||
|
||||
caseType.value = options.caseType || "";
|
||||
customerId.value = options.patientId || "";
|
||||
groupId.value = options.groupId || "";
|
||||
// 从 options 中解析表单数据
|
||||
if (options.formData) {
|
||||
try {
|
||||
formData.value = JSON.parse(decodeURIComponent(options.formData));
|
||||
} catch (e) {
|
||||
console.error("解析表单数据失败:", e);
|
||||
}
|
||||
}
|
||||
|
||||
// 设置页面标题
|
||||
const title = CASE_TYPE_NAMES[caseType.value]
|
||||
? `添加${CASE_TYPE_NAMES[caseType.value]}`
|
||||
: "添加病历";
|
||||
uni.setNavigationBarTitle({ title });
|
||||
});
|
||||
|
||||
const onDateChange = (field, event) => {
|
||||
formData.value[field] = event.detail.value;
|
||||
};
|
||||
|
||||
const handleRegenerate = () => {
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "确定要重新生成吗?当前编辑的内容将被覆盖",
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 返回上一页并触发重新生成
|
||||
uni.navigateBack({
|
||||
success: () => {
|
||||
uni.$emit("regenerateMedicalCase", {
|
||||
caseType: caseType.value,
|
||||
customerId: customerId.value,
|
||||
groupId: groupId.value,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleSave = async () => {
|
||||
// 验证必填项
|
||||
const requiredFields = getRequiredFields();
|
||||
const missingFields = requiredFields.filter(
|
||||
(field) => !formData.value[field.key]
|
||||
);
|
||||
|
||||
if (missingFields.length > 0) {
|
||||
uni.showToast({
|
||||
title: `请填写${missingFields[0].label}`,
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
uni.showLoading({ title: "保存中..." });
|
||||
const result = await api("addMedicalRecord", {
|
||||
medicalType: caseType.value,
|
||||
memberId: customerId.value,
|
||||
creator: doctorInfo.value.userid,
|
||||
...formData.value,
|
||||
});
|
||||
|
||||
uni.hideLoading();
|
||||
|
||||
if (result.success) {
|
||||
uni.showToast({
|
||||
title: "保存成功",
|
||||
icon: "success",
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 1500);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result.message || "保存失败",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
uni.hideLoading();
|
||||
console.error("保存病历失败:", error);
|
||||
uni.showToast({
|
||||
title: "保存失败,请重试",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const getRequiredFields = () => {
|
||||
return currentFields.value.filter((field) => field.required);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.medical-case-form {
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
padding-bottom: 120rpx;
|
||||
|
||||
.form-container {
|
||||
background-color: #ffffff;
|
||||
padding: 32rpx;
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 32rpx;
|
||||
|
||||
&.required .item-label::before {
|
||||
content: "*";
|
||||
color: #ff4d4f;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.item-label {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.item-input,
|
||||
.picker-value {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
padding: 0 24rpx;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 8rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
|
||||
&[disabled] {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.picker-value {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.item-textarea {
|
||||
width: 100%;
|
||||
min-height: 100rpx;
|
||||
padding: 20rpx 24rpx;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 8rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
height: 100px;
|
||||
&[disabled] {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tips-box {
|
||||
margin-top: 32rpx;
|
||||
padding: 24rpx;
|
||||
background-color: #fffbe6;
|
||||
border-radius: 8rpx;
|
||||
|
||||
.tips-text {
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 8rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer-buttons {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
gap: 24rpx;
|
||||
padding: 24rpx 32rpx;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||||
|
||||
.btn-regenerate,
|
||||
.btn-save {
|
||||
flex: 1;
|
||||
height: 88rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 44rpx;
|
||||
|
||||
.btn-text {
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-regenerate {
|
||||
background-color: #ffffff;
|
||||
border: 2rpx solid #1890ff;
|
||||
|
||||
.btn-text {
|
||||
color: #1890ff;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-save {
|
||||
background-color: #1890ff;
|
||||
|
||||
.btn-text {
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -348,7 +348,7 @@ const handleNextFromProgress = (data) => {
|
||||
|
||||
// 跳转到病历填写页面
|
||||
uni.navigateTo({
|
||||
url: `/pages/case/medical-case-form?caseType=${data.caseType}&patientId=${
|
||||
url: `/pages/case/ai-medical-case-form?caseType=${data.caseType}&patientId=${
|
||||
props.patientId
|
||||
}&groupId=${props.groupId}&formData=${encodeURIComponent(
|
||||
JSON.stringify(extractedData)
|
||||
|
||||
@ -769,6 +769,13 @@ onShow(() => {
|
||||
checkLoginAndInitTIM();
|
||||
} else if (timChatManager.tim && !timChatManager.isLoggedIn) {
|
||||
timChatManager.ensureIMConnection();
|
||||
} else if (timChatManager.tim && timChatManager.isLoggedIn && chatInfo.value.conversationID) {
|
||||
// 页面从后台返回时,重新加载消息列表
|
||||
console.log("页面从后台返回,重新加载消息列表");
|
||||
messageList.value = [];
|
||||
isCompleted.value = false;
|
||||
lastFirstMessageId.value = "";
|
||||
loadMessageList();
|
||||
}
|
||||
|
||||
startIMMonitoring(30000);
|
||||
|
||||
@ -67,10 +67,7 @@
|
||||
<text class="empty-text">医生信息未获取,请稍后重试</text>
|
||||
</view>
|
||||
<view
|
||||
v-else-if="
|
||||
!loading &&
|
||||
filteredConversationList.length === 0
|
||||
"
|
||||
v-else-if="!loading && filteredConversationList.length === 0"
|
||||
class="empty-container"
|
||||
>
|
||||
<image class="empty-image" src="/static/empty.svg" mode="aspectFit" />
|
||||
@ -165,12 +162,78 @@ const handleAddPatient = withInfo(() => {
|
||||
});
|
||||
});
|
||||
|
||||
// 立即更新未读徽章
|
||||
const updateUnreadBadgeImmediately = async () => {
|
||||
try {
|
||||
if (!globalTimChatManager || !globalTimChatManager.tim) {
|
||||
console.warn("TIM实例不存在,无法更新徽章");
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await globalTimChatManager.tim.getConversationList();
|
||||
|
||||
if (!response || !response.data || !response.data.conversationList) {
|
||||
console.warn("获取会话列表返回数据异常");
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算群聊总未读数
|
||||
const totalUnreadCount = response.data.conversationList
|
||||
.filter(
|
||||
(conv) => conv.conversationID && conv.conversationID.startsWith("GROUP")
|
||||
)
|
||||
.reduce((sum, conv) => sum + (conv.unreadCount || 0), 0);
|
||||
|
||||
// 更新 tabBar 徽章 - 添加错误处理,防止在非TabBar页面调用时出错
|
||||
try {
|
||||
if (totalUnreadCount > 0) {
|
||||
uni.setTabBarBadge({
|
||||
index: 1,
|
||||
text: totalUnreadCount > 99 ? "99+" : String(totalUnreadCount),
|
||||
});
|
||||
console.log("已更新 tabBar 徽章:", totalUnreadCount);
|
||||
} else {
|
||||
uni.removeTabBarBadge({
|
||||
index: 1,
|
||||
});
|
||||
console.log("已移除 tabBar 徽章");
|
||||
}
|
||||
} catch (badgeError) {
|
||||
// 在非TabBar页面上调用时会出错,这是正常的,不需要处理
|
||||
if (badgeError.errMsg && badgeError.errMsg.includes("not TabBar page")) {
|
||||
console.log("当前不是TabBar页面,跳过徽章更新");
|
||||
} else {
|
||||
console.error("更新TabBar徽章失败:", badgeError);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("更新未读徽章失败:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化IM
|
||||
const initIM = async () => {
|
||||
if (!isIMInitialized.value) {
|
||||
// 关键修复:不仅检查 isIMInitialized,还要检查实际连接状态
|
||||
const needsInit =
|
||||
!isIMInitialized.value ||
|
||||
!globalTimChatManager ||
|
||||
!globalTimChatManager.isLoggedIn;
|
||||
|
||||
if (needsInit) {
|
||||
uni.showLoading({
|
||||
title: "连接中...",
|
||||
});
|
||||
|
||||
// 如果已初始化但连接断开,先清理旧实例
|
||||
if (
|
||||
isIMInitialized.value &&
|
||||
globalTimChatManager &&
|
||||
!globalTimChatManager.isLoggedIn
|
||||
) {
|
||||
console.log("IM已初始化但连接已断开,清理旧实例后重新初始化");
|
||||
await globalTimChatManager.cleanupOldInstance();
|
||||
}
|
||||
|
||||
const success = await initIMAfterLogin();
|
||||
uni.hideLoading();
|
||||
|
||||
@ -191,30 +254,6 @@ const initIM = async () => {
|
||||
});
|
||||
return false;
|
||||
}
|
||||
} else if (globalTimChatManager && !globalTimChatManager.isLoggedIn) {
|
||||
uni.showLoading({
|
||||
title: "重连中...",
|
||||
});
|
||||
const reconnected = await globalTimChatManager.ensureIMConnection();
|
||||
uni.hideLoading();
|
||||
|
||||
if (!reconnected) {
|
||||
// 显示重试提示
|
||||
uni.showModal({
|
||||
title: "IM连接失败",
|
||||
content:
|
||||
"连接失败,请检查网络后重试。如果IM连接失败,请重新登陆IM再连接",
|
||||
confirmText: "重新登陆",
|
||||
cancelText: "取消",
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 重新登陆
|
||||
handleReloginIM();
|
||||
}
|
||||
},
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
@ -281,7 +320,7 @@ const loadConversationList = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否已登录
|
||||
// 检查是否已登录 - 这是关键检查
|
||||
if (!globalTimChatManager.isLoggedIn) {
|
||||
console.warn("IM未登录,尝试重新连接");
|
||||
const reconnected = await globalTimChatManager.ensureIMConnection();
|
||||
@ -294,7 +333,19 @@ const loadConversationList = async () => {
|
||||
throw new Error("IM管理器方法不可用");
|
||||
}
|
||||
|
||||
const result = await globalTimChatManager.getGroupList();
|
||||
// 添加超时控制,防止永久等待
|
||||
const timeoutPromise = new Promise((_, reject) => {
|
||||
setTimeout(
|
||||
() => reject(new Error("加载会话列表超时,请检查网络连接")),
|
||||
35000
|
||||
);
|
||||
});
|
||||
|
||||
const result = await Promise.race([
|
||||
globalTimChatManager.getGroupList(),
|
||||
timeoutPromise,
|
||||
]);
|
||||
|
||||
if (result && result.success && result.groupList) {
|
||||
// 合并后端群组详细信息(已包含格式化和排序)
|
||||
conversationList.value = await mergeConversationWithGroupDetails(
|
||||
@ -317,17 +368,26 @@ const loadConversationList = async () => {
|
||||
);
|
||||
} else {
|
||||
console.error("加载群聊列表失败:", result);
|
||||
uni.showToast({
|
||||
title: "加载失败,请重试",
|
||||
icon: "none",
|
||||
});
|
||||
throw new Error(result?.message || "加载失败,请重试");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("加载会话列表失败:", error);
|
||||
|
||||
// 如果是超时或连接错误,提示用户重试
|
||||
if (
|
||||
error.message &&
|
||||
(error.message.includes("超时") || error.message.includes("连接"))
|
||||
) {
|
||||
uni.showToast({
|
||||
title: "网络连接不稳定,请重试",
|
||||
icon: "none",
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: error.message || "加载失败,请重试",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
@ -605,7 +665,7 @@ onShow(async () => {
|
||||
// 加载团队列表
|
||||
await getTeams();
|
||||
|
||||
// 初始化IM
|
||||
// 初始化IM - 关键修复:确保IM连接状态正确
|
||||
const imReady = await initIM();
|
||||
if (!imReady) {
|
||||
console.error("IM初始化失败");
|
||||
|
||||
@ -17,7 +17,8 @@
|
||||
加入我的团队,协同开展患者管理服务
|
||||
</view>
|
||||
<view class="mt-10 flex px-15 leading-normal text-center">
|
||||
<button class="mr-10 border-auto rounded py-5 text-base text-primary flex-grow" @click="saveImage('save')">
|
||||
<button class="mr-10 border-auto rounded py-5 text-base text-primary flex-grow"
|
||||
@click="saveImage('save')">
|
||||
保存图片
|
||||
</button>
|
||||
<button class="bg-primary rounded py-5 text-base text-white flex-grow" open-type="share">分享微信</button>
|
||||
@ -29,39 +30,61 @@
|
||||
</view>
|
||||
</template>
|
||||
<script setup>
|
||||
import { computed, ref } from "vue";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { onLoad, onShareAppMessage } from "@dcloudio/uni-app";
|
||||
import useGuard from "@/hooks/useGuard.js";
|
||||
import useAccountStore from "@/store/account.js";
|
||||
import api from '@/utils/api';
|
||||
import { toast } from "@/utils/widget";
|
||||
import { getInviteMatePoster } from './base-poster-data';
|
||||
import {
|
||||
computed,
|
||||
ref
|
||||
} from "vue";
|
||||
import {
|
||||
storeToRefs
|
||||
} from "pinia";
|
||||
import {
|
||||
onLoad,
|
||||
onShareAppMessage
|
||||
} from "@dcloudio/uni-app";
|
||||
import useGuard from "@/hooks/useGuard.js";
|
||||
import useAccountStore from "@/store/account.js";
|
||||
import api from '@/utils/api';
|
||||
import {
|
||||
toast
|
||||
} from "@/utils/widget";
|
||||
import {
|
||||
getInviteMatePoster
|
||||
} from './base-poster-data';
|
||||
|
||||
const env = __VITE_ENV__;
|
||||
const inviteQrcode = env.MP_INVITE_TEAMMATE_QRCODE;
|
||||
const env = __VITE_ENV__;
|
||||
const inviteQrcode = env.MP_INVITE_TEAMMATE_QRCODE;
|
||||
|
||||
const options = { margin: 10 };
|
||||
const team = ref(null);
|
||||
const teamId = ref('');
|
||||
const painterRef = ref()
|
||||
const poster = ref({})
|
||||
const options = {
|
||||
margin: 10
|
||||
};
|
||||
const team = ref(null);
|
||||
const teamId = ref('');
|
||||
const painterRef = ref()
|
||||
const poster = ref({})
|
||||
|
||||
const { useLoad, useShow } = useGuard();
|
||||
const { account } = storeToRefs(useAccountStore());
|
||||
const {
|
||||
useLoad,
|
||||
useShow
|
||||
} = useGuard();
|
||||
const {
|
||||
account
|
||||
} = storeToRefs(useAccountStore());
|
||||
|
||||
const qrcode = computed(() => `${inviteQrcode}?type=inviteTeam&teamId=${teamId.value}`)
|
||||
const qrcode = computed(() => `${inviteQrcode}?type=inviteTeam&teamId=${teamId.value}`)
|
||||
|
||||
async function getTeam() {
|
||||
const res = await api('getTeamData', { teamId: teamId.value, corpId: account.value.corpId });
|
||||
async function getTeam() {
|
||||
const res = await api('getTeamData', {
|
||||
teamId: teamId.value,
|
||||
corpId: account.value.corpId
|
||||
});
|
||||
if (res && res.data) {
|
||||
team.value = res.data;
|
||||
} else {
|
||||
toast(res?.message || '获取团队信息失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function saveImage(action = 'save') {
|
||||
async function saveImage(action = 'save') {
|
||||
const data = getInviteMatePoster(team.value.name, qrcode.value)
|
||||
try {
|
||||
await painterRef.value.render(data);
|
||||
@ -75,7 +98,7 @@ async function saveImage(action = 'save') {
|
||||
if (action === 'save') {
|
||||
uni.saveImageToPhotosAlbum({
|
||||
filePath: res.tempFilePath,
|
||||
success: function () {
|
||||
success: function() {
|
||||
console.log('save success');
|
||||
}
|
||||
});
|
||||
@ -90,29 +113,29 @@ async function saveImage(action = 'save') {
|
||||
} catch (e) {
|
||||
toast(e?.message)
|
||||
}
|
||||
}
|
||||
useLoad(options => {
|
||||
}
|
||||
useLoad(options => {
|
||||
teamId.value = options.teamId;
|
||||
})
|
||||
})
|
||||
|
||||
useShow(() => {
|
||||
useShow(() => {
|
||||
getTeam()
|
||||
});
|
||||
});
|
||||
|
||||
onShareAppMessage(() => {
|
||||
onShareAppMessage(() => {
|
||||
return {
|
||||
title: '邀请团队成员',
|
||||
path: `pages/login/redirect-page?type=inviteTeam&teamId=${teamId.value}`
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
.canvas-box {
|
||||
.canvas-box {
|
||||
top: 10000rpx;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
width: 0;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1032,6 +1032,8 @@ class TimChatManager {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 检查userId是否存在,不存在则不需要初始化
|
||||
if (!this.currentUserID) {
|
||||
console.error('currentUserID不存在,无法获取群聊列表')
|
||||
reject(new Error('用户ID不存在'))
|
||||
return
|
||||
}
|
||||
|
||||
@ -1076,12 +1078,13 @@ class TimChatManager {
|
||||
if (timeoutHandle) clearTimeout(timeoutHandle)
|
||||
this.getGroupListInternal().then(resolve).catch(reject)
|
||||
} else if (waitTime >= maxWaitTime) {
|
||||
console.error('等待SDK就绪超时')
|
||||
console.error('等待SDK就绪超时,当前isLoggedIn:', this.isLoggedIn)
|
||||
if (timeoutHandle) clearTimeout(timeoutHandle)
|
||||
// 超时时返回错误而不是继续等待
|
||||
reject(new Error('SDK初始化超时,请检查网络连接'))
|
||||
} else {
|
||||
waitTime += checkInterval
|
||||
console.log(`等待SDK就绪... (${Math.floor(waitTime / 1000)}/${Math.floor(maxWaitTime / 1000)}秒)`)
|
||||
console.log(`等待SDK就绪... (${Math.floor(waitTime / 1000)}/${Math.floor(maxWaitTime / 1000)}秒, isLoggedIn: ${this.isLoggedIn})`)
|
||||
timeoutHandle = setTimeout(checkSDKReady, checkInterval)
|
||||
}
|
||||
}
|
||||
@ -2758,6 +2761,7 @@ class TimChatManager {
|
||||
|
||||
// 标记会话为已读
|
||||
markConversationAsRead(conversationID) {
|
||||
|
||||
if (!this.tim || !this.isLoggedIn) {
|
||||
console.log('⚠️ TIM未初始化或未登录,无法标记会话已读');
|
||||
return;
|
||||
@ -2777,6 +2781,7 @@ class TimChatManager {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 更新会话列表
|
||||
updateConversationListOnNewMessage(message) {
|
||||
try {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user