Compare commits

...

4 Commits

Author SHA1 Message Date
826924db78 小程序进行苹果端显示优化 2026-08-17 17:39:18 +08:00
3e56f21e5f bug修复 2026-08-14 16:49:54 +08:00
1514dc606a no message 2026-08-11 17:28:46 +08:00
e3631a61a7 页面优化 2026-08-11 10:24:25 +08:00
10 changed files with 2678 additions and 1332 deletions

View File

@ -110,6 +110,13 @@
"disableScroll": true
}
},
{
"path": "benefit-entry",
"style": {
"navigationBarTitleText": "权益录入",
"disableScroll": true
}
},
{
"path": "index",
"style": {

File diff suppressed because it is too large Load Diff

View File

@ -338,6 +338,18 @@ $primary-color: #0877F1;
border-top: 10rpx solid transparent;
}
.custom-bubble,
.benefit-bubble {
padding: 0;
border-radius: 0;
background: transparent;
overflow: visible;
}
.benefit-bubble {
max-width: 100%;
}
/* 医生发送的蓝色气泡(用于消息卡片) */
.doctor-bubble-blue {
background-color: #0877F1;

View File

@ -4,22 +4,20 @@
<view class="ai-assistant-slot">
<slot name="ai-assistant"></slot>
</view>
<view class="input-toolbar">
<view @click="toggleVoiceInput" class="voice-toggle-btn">
<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" />
</view>
<view class="input-area">
<!-- :hold-keyboard="true" -->
<textarea v-if="!showVoiceInput" class="text-input" v-model="inputText" placeholder="我来说两句..."
@confirm="sendTextMessage" @focus="handleInputFocus" @input="handleInput"
:auto-height="true" :show-confirm-bar="false" :cursor-spacing="40"
ref="textareaRef"
/>
<!-- :hold-keyboard="true" -->
<textarea v-if="!showVoiceInput" class="text-input" v-model="inputText" placeholder="我来说两句..."
@confirm="sendTextMessage" @focus="handleInputFocus" @input="handleInput" :auto-height="true"
:show-confirm-bar="false" :cursor-spacing="40" ref="textareaRef" />
<input v-else class="voice-input-btn" :class="{ recording: isRecording }" @touchstart="startRecord"
@touchmove="onRecordTouchMove" @touchend="stopRecord" @touchcancel="cancelRecord" :placeholder="isRecording ? '松开发送' : '按住说话'" disabled>
</input>
@touchmove="onRecordTouchMove" @touchend="stopRecord" @touchcancel="cancelRecord"
:placeholder="isRecording ? '松开发送' : '按住说话'" disabled />
</view>
<button v-if="inputText.trim() && !props.isGenerating" class="send-btn" @click="sendTextMessage">
发送
@ -87,6 +85,7 @@ const props = defineProps({
groupId: { type: String, default: "" },
userId: { type: String, default: "" },
teamId: { type: String, default: "" },
teamName: { type: String, default: "" },
patientId: { type: String, default: "" },
corpId: { type: String, default: "" },
orderStatus: { type: String, default: "" },
@ -409,6 +408,14 @@ const goToArticleList = () => {
});
};
//
const goToBenefitEntry = () => {
showMorePanel.value = false;
uni.navigateTo({
url: `/pages/message/benefit-entry?groupId=${encodeURIComponent(props.groupId)}&patientId=${encodeURIComponent(props.patientId)}&patientName=${encodeURIComponent(props.patientInfo.name || "")}&teamId=${encodeURIComponent(props.teamId)}&teamName=${encodeURIComponent(props.teamName)}&corpId=${encodeURIComponent(props.corpId)}`,
});
};
//
const goToSurveyList = () => {
uni.navigateTo({
@ -474,6 +481,11 @@ const morePanelButtons = computed(() => {
icon: "/static/icon/xuanjiaowenzhang.png",
action: goToArticleList,
},
{
text: "权益录入",
icon: "/static/icon/quanyi.svg",
action: goToBenefitEntry,
},
{
text: "问卷",
icon: "/static/icon/wenjuan.png",

View File

@ -37,7 +37,7 @@
</view>
<!-- 自定义消息卡片 -->
<template v-else-if="message.type === 'TIMCustomElem'">
<block v-else-if="message.type === 'TIMCustomElem'">
<!-- 文章消息 -->
<view v-if="customMessageType === 'article'" class="article-card" @click="handleArticleClick(message)">
<view class="article-content">
@ -56,6 +56,28 @@
<image v-if="surveyData.imgUrl" class="survey-image" :src="surveyData.imgUrl" mode="aspectFill" />
</view>
<!-- 权益消息 -->
<view v-else-if="customMessageType === 'benefit'" class="benefit-card">
<view class="benefit-title">{{ benefitData.title }}</view>
<view class="benefit-content">
<view v-for="(item, index) in benefitData.items" :key="`${item.projectId}-${index}`" class="benefit-item">
<view class="benefit-project-row">
<text v-if="index === 0" class="benefit-label">项目</text>
<text v-else class="benefit-label-placeholder"></text>
<text class="benefit-project-name">{{ item.projectName }}</text>
<text class="benefit-count">X{{ item.usageCount }}</text>
</view>
<view class="benefit-valid-row">
<text class="benefit-valid-label">有效期</text>
<text class="benefit-valid-value">{{ item.validTimeText || '无限期' }}</text>
</view>
</view>
<view class="benefit-detail-button" @click.stop="handleBenefitClick">
<text class="benefit-detail-text">查看详情</text>
</view>
</view>
</view>
<!-- 其他自定义消息 -->
<!-- <view
v-else
@ -69,7 +91,7 @@
@viewDetail="$emit('viewDetail', $event)"
/>
</view> -->
</template>
</block>
</template>
<script setup>
@ -124,6 +146,19 @@ const surveyData = computed(() => ({
imgUrl: payloadData.value.imgUrl || "",
}))
const benefitData = computed(() => ({
title: payloadData.value.title || "医生为您录入专属权益",
patientId: payloadData.value.patientId || "",
items: Array.isArray(payloadData.value.items) ? payloadData.value.items : [],
}))
const handleBenefitClick = () => {
if (!benefitData.value.patientId) return;
uni.navigateTo({
url: `/pages/case/archive-detail?id=${encodeURIComponent(String(benefitData.value.patientId))}`,
});
}
//
const getImageStyle = (imageInfo) => {
// 使
@ -264,4 +299,95 @@ function isWechatChannels(data) {
width: 480rpx;
height: 320rpx;
}
.benefit-card {
width: 520rpx;
max-width: 100%;
box-sizing: border-box;
border-radius: 10rpx;
padding: 22rpx 18rpx 18rpx;
background: linear-gradient(180deg, #0b75f2 0%, #0067df 100%);
}
.benefit-title {
color: #fff;
font-size: 32rpx;
font-weight: 600;
line-height: 1.3;
margin-bottom: 18rpx;
}
.benefit-content {
border: 4rpx solid rgba(255, 255, 255, 0.28);
border-radius: 8rpx;
padding: 24rpx 24rpx 28rpx;
background: #fff;
}
.benefit-item + .benefit-item {
margin-top: 18rpx;
}
.benefit-project-row {
display: flex;
align-items: center;
min-width: 0;
}
.benefit-label,
.benefit-label-placeholder {
flex-shrink: 0;
width: 104rpx;
color: #8b8f96;
font-size: 28rpx;
line-height: 1.4;
}
.benefit-project-name {
flex: 1;
min-width: 0;
color: #111827;
font-size: 30rpx;
line-height: 1.4;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.benefit-count {
flex-shrink: 0;
margin-left: 16rpx;
color: #111827;
font-size: 30rpx;
line-height: 1.4;
}
.benefit-valid-row {
display: flex;
margin-left: 104rpx;
margin-top: 8rpx;
}
.benefit-valid-label,
.benefit-valid-value {
color: #8b8f96;
font-size: 26rpx;
line-height: 1.4;
}
.benefit-detail-button {
height: 82rpx;
margin-top: 28rpx;
border-radius: 8rpx;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(180deg, #0b75f2 0%, #0067df 100%);
}
.benefit-detail-text {
color: #fff;
font-size: 32rpx;
font-weight: 600;
}
</style>

File diff suppressed because it is too large Load Diff

BIN
static/icon/quanyi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

9
static/icon/quanyi.svg Normal file
View File

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="104" height="104" viewBox="0 0 104 104">
<rect width="104" height="104" fill="#ffffff"/>
<g fill="none" stroke="#7d8e9e" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round">
<path d="M33 31.5h27.5a3 3 0 0 1 3 3v29a3 3 0 0 1-3 3H33a3 3 0 0 1-3-3v-29a3 3 0 0 1 3-3Z"/>
<path d="M39 42h15M39 49h15M39 56h8"/>
<circle cx="62.5" cy="63" r="12.5" fill="#ffffff"/>
<path d="m62.5 56.8 1.8 3.7 4.1.6-3 2.9.7 4.1-3.6-1.9-3.7 1.9.7-4.1-3-2.9 4.1-.6 1.8-3.7Z" fill="#7d8e9e" stroke="none"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 575 B

View File

@ -17,6 +17,7 @@ const urlsConfig = {
getTemplateListByTemptype: 'getTemplateListByTemptype',
wxAppLogin: 'wxAppLogin',
getDeptList: 'getRealDeptList',
getTreatmentDeptList: "getDeptList",
getHospitalList: 'getRealHospital',
addCorpMember: 'addCorpMember',
getCorpMemberData: 'getCorpMemberData',
@ -26,6 +27,7 @@ const urlsConfig = {
submitCertProfile: 'submitCertProfile',
getMemberVerifyStatus: "getMemberVerifyStatus",
getJoinedTeams: "getJoinedTeams",
getProjectList: "getProjectList",
updateTeamInfo: "updateTeamInfo",
createOwnTeam: 'createOwnTeam',
removeTeammate: "removeTeammate",
@ -91,6 +93,7 @@ const urlsConfig = {
unbindMiniAppArchive: 'unbindMiniAppArchive',
// 健康档案相关接口
addMedicalRecord: 'addMedicalRecord',
addTreatmentRecord: "addTreatmentRecord",
getMedicalRecordById: 'getMedicalRecordById',
updateMedicalRecord: 'updateMedicalRecord',
removeMedicalRecord: 'removeMedicalRecord',
@ -104,7 +107,6 @@ const urlsConfig = {
im: {
getUserSig: 'getUserSig',
sendSystemMessage: "sendSystemMessage",
getChatRecordsByGroupId: "getChatRecordsByGroupId",
sendConsultRejectedMessage: "sendConsultRejectedMessage",
endConsultation: "endConsultation",
openConsultation: "openConsultation",

View File

@ -402,6 +402,45 @@ function buildSurveyMessage(survey, surveyLink) {
};
}
export async function sendBenefitMessage(benefit, options = {}) {
if (!benefit || !Array.isArray(benefit.items) || !benefit.items.length) {
toast('权益信息不完整');
return false;
}
try {
if (!globalTimChatManager?.isLoggedIn) {
toast('IM系统未就绪请稍后重试');
return false;
}
const customMessageData = {
type: 'benefit',
messageType: 'benefit',
title: benefit.title || '医生为您录入专属权益',
desc: benefit.desc || '点击查看详情',
patientId: benefit.patientId || options.customerId || '',
patientName: benefit.patientName || options.customerName || '',
corpId: benefit.corpId || options.corpId || '',
teamId: benefit.teamId || options.teamId || '',
items: benefit.items.map((item) => ({
projectId: item.projectId || '',
projectName: item.projectName || '',
usageCount: Number(item.usageCount || 0),
validTime: item.validTime || null,
validTimeText: item.validTimeText || '无限期',
})),
};
const result = await globalTimChatManager.sendCustomMessage(customMessageData);
return Boolean(result?.success);
} catch (error) {
console.error('发送权益消息异常:', error);
toast('发送权益消息失败');
return false;
}
}
/**
* 处理回访任务消息发送
* @param {Object} messages - 消息数组
@ -439,6 +478,14 @@ export async function handleFollowUpMessages(messages, context = {}) {
customerName: context.customerName,
corpId: context.corpId
});
} else if (msg.type === 'benefit') {
success = await sendBenefitMessage(msg.content, {
userId: context.userId,
customerId: context.customerId,
customerName: context.customerName,
corpId: context.corpId,
teamId: context.teamId,
});
}
if (!success) {