feat(home/chat): 列表骨架屏、聊天室己方头像与协议/医生详情优化

- 新增分包组件 ListSkeleton(doctor/message/product/article/category/zone)
- 首页/消息/资讯首次加载改用骨架屏,刷新不再清空旧数据避免闪空
  · 去掉 home getList、消息 onShow 中的数组清空
  · 三页 pages.json 增加 easycom 与 componentPlaceholder 主包异步引用
- 聊天室己方头像改为读取本地 userinfo.avatarurl(登录后微信头像),
  mycollection 上传头像成功后同步写回 storage
- 修复协议抽屉点不开:page-container 改为 v-if + :show;
  协议名单独可点节点,匹配放宽 name/desc 双向 includes
- 医生气泡头像可点击进入 doctor-detail?readonly=1 只读医生详情,
  隐藏预约挂号区
This commit is contained in:
李琦
2026-07-19 16:08:04 +08:00
parent 2c739324d6
commit 2d2a8abfd4
21 changed files with 1657 additions and 466 deletions

View File

@@ -1,7 +1,7 @@
<template>
<view class="bubble-container" :class="{ 'mine': isMine, 'other': !isMine }">
<!-- 头像 -->
<image class="avatar" :src="avatar" mode="aspectFill"></image>
<!-- 头像非己方可点进医生详情 -->
<image class="avatar" :src="avatar" mode="aspectFill" @click.stop="onAvatarClick"></image>
<!-- 消息内容包裹 -->
<view class="content-wrapper">
@@ -146,13 +146,22 @@
<text class="block-label">主诉</text>
<text class="block-content">{{ parsedContent.chief_complaint }}</text>
</view>
<view class="info-row" v-if="registerCardDrugNamesLine">
<text class="label">所选药品</text>
<text class="value">{{ registerCardDrugNamesLine }}</text>
</view>
<view class="info-row" v-if="parsedContent.number != null && parsedContent.number !== ''">
<text class="label">数量</text>
<text class="value"> {{ parsedContent.number }} </text>
<view v-if="registerCardDrugRows.length" class="drug-list-block">
<text class="block-label">所选药品</text>
<view v-for="row in registerCardDrugRows" :key="row._wxKey" class="info-row drug-spec-row">
<image
v-if="row.image"
class="drug-thumb"
:src="row.image"
mode="aspectFill"
@click.stop="$emit('previewImage', row.image)"
/>
<view class="drug-name-wrap">
<text class="label">{{ row.name || '药品' }}</text>
<text v-if="row.specification" class="spec-text">{{ row.specification }}</text>
</view>
<text class="value">×{{ row.quantity }}</text>
</view>
</view>
</view>
<view class="card-footer"><button class="action-btn" @click="$emit('viewRegister', parsedContent.id)">查看详情</button></view>
@@ -314,17 +323,38 @@ export default {
}
return message_content;
},
/** 挂号卡片:多选西药名称串联,无则单药 drug.name */
registerCardDrugNamesLine() {
if (this.msg.message_type !== 10) return '';
/**
* 预约挂号卡片药品行:药名 + 规格 + 数量(与医生端一致,去掉底部「各 X 盒」)
*/
registerCardDrugRows() {
if (this.msg.message_type !== 10) return [];
const pc = this.parsedContent;
if (!pc || typeof pc !== 'object') return '';
if (!pc || typeof pc !== 'object') return [];
const fallbackQty = pc.number != null && pc.number !== '' ? Number(pc.number) : 1;
const arr = pc.selected_western_drugs;
if (Array.isArray(arr) && arr.length) {
return arr.map((d) => d && d.name).filter(Boolean).join('、');
return arr.map((d, idx) => {
const q = d && d.quantity != null ? Number(d.quantity) : fallbackQty;
const id = d && (d.drug_id || d.id);
return {
_wxKey: 'rd-' + (id != null ? id : idx),
name: (d && d.name) || '',
specification: (d && (d.specification || d.spec || d.drug_spec)) || '',
image: (d && (d.image || d.drug_image)) || '',
quantity: q >= 1 ? q : 1,
};
});
}
if (pc.drug && pc.drug.name) return pc.drug.name;
return '';
if (pc.drug && pc.drug.name) {
return [{
_wxKey: 'rd-' + (pc.drug.drug_id || pc.drug.id || 0),
name: pc.drug.name,
specification: pc.drug.specification || pc.drug.spec || '',
image: pc.drug.image || pc.drug.drug_image || '',
quantity: fallbackQty >= 1 ? fallbackQty : 1,
}];
}
return [];
},
followUpAnsweredLabel() {
const pc = this.parsedContent;
@@ -336,6 +366,13 @@ export default {
}
},
methods: {
/**
* 非己方头像点击:通知父页跳转医生详情;己方头像不响应
*/
onAvatarClick() {
if (this.isMine) return;
this.$emit('avatarClick');
},
// 计算语音条宽度 (Min: 100rpx, Max: 350rpx, Unit: 10rpx/sec)
getAudioWidth(duration) {
const min = 120;
@@ -609,6 +646,40 @@ $success-color: #059669;
.price { color: #ef4444; font-size: 28rpx; font-weight: bold; }
.small { font-size: 22rpx; color: #999; }
}
.drug-spec-row {
align-items: flex-start;
.drug-thumb {
width: 64rpx;
height: 64rpx;
border-radius: 8rpx;
background: #f3f4f6;
flex-shrink: 0;
margin-right: 12rpx;
}
.drug-name-wrap {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 4rpx;
flex: 1;
min-width: 0;
}
.spec-text {
display: block;
font-size: 22rpx;
color: #9ca3af;
font-weight: 400;
text-align: left;
}
}
.drug-list-block {
.block-label {
display: block;
font-size: 22rpx;
color: #888;
margin-bottom: 8rpx;
}
}
.desc-text { font-size: 26rpx; color: #333; }
.text-block {
background: #f5f5f5; padding: 16rpx; border-radius: 8rpx;