489 lines
13 KiB
Vue
489 lines
13 KiB
Vue
<template>
|
|
<view class="consult-page">
|
|
<!-- 顶部导航与标签 -->
|
|
<navBar title="公益咨询" />
|
|
<view class="tabs">
|
|
<view :class="['tab', activeTab==='new' ? 'active' : '']" @tap="switchTab('new')">新的咨询</view>
|
|
<view :class="['tab', activeTab==='mine' ? 'active' : '']" @tap="switchTab('mine')">我已回答</view>
|
|
</view>
|
|
<view class="tabs-spacer"></view>
|
|
|
|
<!-- 列表 -->
|
|
<scroll-view
|
|
scroll-y
|
|
class="list-scroll"
|
|
refresher-enabled
|
|
:refresher-triggered="isRefreshing"
|
|
@refresherrefresh="onRefresh"
|
|
@scrolltolower="onReachBottom"
|
|
lower-threshold="80"
|
|
>
|
|
<view v-for="(item, idx) in displayList" :key="idx" class="consult-card" @click="goDetail(item.id,item.patientUuid)">
|
|
<view class="card-head">
|
|
<text class="user-name">{{ item.maskName }}</text>
|
|
<text class="date">{{ item.date }}</text>
|
|
</view>
|
|
<view class="card-body">
|
|
<text class="content">{{ item.content }}</text>
|
|
</view>
|
|
<view class="card-foot" v-if="bottomActive==='multi'">
|
|
<text class="reply-count">{{ item.answer_num }}位医生已回答</text>
|
|
<view v-if="item.tag" class="tag">{{ item.tag }}</view>
|
|
</view>
|
|
<view class="card-foot" v-else>
|
|
<view class="left">
|
|
<view class="detail">问题详情</view>
|
|
<view v-if="item.tag" class="tag">{{ item.tag }}</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<empty v-if="displayList.length===0" />
|
|
<view v-if="isLoading" style="text-align:center;color:#9aa0a6;padding:10px 0;">加载中...</view>
|
|
<view v-else-if="!hasMore && displayList.length>0" style="text-align:center;color:#9aa0a6;padding:10px 0;">没有更多了</view>
|
|
</scroll-view>
|
|
|
|
<!-- 底部操作条:双按钮 Tab -->
|
|
<view class="bottom-bar" :style="{height: bottomBarHeight+'px'}">
|
|
<view :class="['bottom-tab', bottomActive==='quick' ? 'active' : '']" @click="switchBottomTab('quick')">快速问医生</view>
|
|
<view :class="['bottom-tab', bottomActive==='multi' ? 'active' : '']" @click="switchBottomTab('multi')">多对一解惑</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed } from 'vue'
|
|
import { onShow } from '@dcloudio/uni-app'
|
|
import navBar from '@/components/navBar/navBar.vue'
|
|
import empty from '@/components/empty/empty.vue'
|
|
import api from '@/api/api.js'
|
|
import navTo from '@/utils/navTo.js'
|
|
|
|
const activeTab = ref('new');
|
|
const bottomBarHeight = 56
|
|
const page=ref(1)
|
|
const pageSize=ref(10)
|
|
const hasMore = ref(true)
|
|
const isLoading = ref(false)
|
|
const isRefreshing = ref(false)
|
|
const goDetail=async(uuid,patientUuid)=>{
|
|
if(bottomActive.value==='quick'){
|
|
if(activeTab.value==='new'){
|
|
navTo({
|
|
url:'/pages_app/freeDetail/freeDetail?uuid='+uuid
|
|
})
|
|
}else{
|
|
let userId=uni.getStorageSync('userInfo').uuid.toLowerCase();
|
|
let conversationId=userId+'|1|'+patientUuid.toLowerCase();
|
|
await uni.$UIKitStore.uiStore.selectConversation(conversationId)
|
|
navTo({
|
|
url:'/pages_chat/chat/index?from=consult&&patientUuid='+patientUuid+'&&uuid='+uuid
|
|
})
|
|
}
|
|
|
|
}else{
|
|
let status=0;
|
|
if(activeTab.value==='new'){
|
|
status=0;
|
|
}else{
|
|
status=1;
|
|
}
|
|
navTo({
|
|
url:'/pages_app/consultDetail/consultDetail?uuid='+uuid+'&status='+status
|
|
})
|
|
}
|
|
};
|
|
function maskName(name){
|
|
if(!name) return '**'
|
|
const first = name.slice(0,1)
|
|
return `${first}**`
|
|
}
|
|
const newConsultList=async(isRefresh=false)=>{
|
|
if(isLoading.value) return
|
|
isLoading.value = true
|
|
if(isRefresh){
|
|
page.value = 1
|
|
hasMore.value = true
|
|
listNew.value = []
|
|
}
|
|
const res=await api.newConsultList({
|
|
page:page.value,
|
|
pageSize:pageSize.value
|
|
})
|
|
console.log(res)
|
|
if(res && res.code===200 && res.data && res.data.consult_list){
|
|
const list = Array.isArray(res.data.consult_list.list) ? res.data.consult_list.list : []
|
|
const mapped = list.map(item=>({
|
|
maskName: maskName(item.realName || ''),
|
|
date: (item.createDate || '').slice(0,10),
|
|
content: item.content || '',
|
|
replyCount: 0,
|
|
tag: item.diseaseName || '',
|
|
id:item.uuid || '',
|
|
patientUuid:item.patientUuid || ''
|
|
}))
|
|
if(isRefresh){
|
|
listNew.value = mapped
|
|
}else{
|
|
listNew.value = page.value===1 ? mapped : [...listNew.value, ...mapped]
|
|
}
|
|
const totalPage = Number(res.data.consult_list.totalPage || 1)
|
|
hasMore.value = page.value < totalPage
|
|
}
|
|
isLoading.value = false
|
|
if(isRefresh){
|
|
isRefreshing.value = false
|
|
}
|
|
}
|
|
const consultListHis=async(isRefresh=false)=>{
|
|
if(isLoading.value) return
|
|
isLoading.value = true
|
|
if(isRefresh){
|
|
page.value = 1
|
|
hasMore.value = true
|
|
listMine.value = []
|
|
}
|
|
const res=await api.consultListHis({
|
|
page:page.value,
|
|
pageSize:pageSize.value
|
|
})
|
|
console.log(res)
|
|
if(res.code==200){
|
|
const list = Array.isArray(res.data.list) ? res.data.list : []
|
|
const mapped = list.map(item=>({
|
|
maskName: maskName(item.realName || ''),
|
|
date: (item.createDate || '').slice(0,10),
|
|
content: item.content || '',
|
|
replyCount: 0,
|
|
tag: item.diseaseName || '',
|
|
id:item.uuid || '',
|
|
patientUuid:item.patientUuid || ''
|
|
}))
|
|
if(isRefresh){
|
|
listMine.value = mapped
|
|
}else{
|
|
listMine.value = page.value===1 ? mapped : [...listMine.value, ...mapped]
|
|
}
|
|
const totalPage = Number(res.data.totalPage || 1)
|
|
hasMore.value = page.value < totalPage
|
|
}
|
|
isLoading.value = false
|
|
if(isRefresh){
|
|
isRefreshing.value = false
|
|
}
|
|
}
|
|
const listNewInterrogation=async(isRefresh=false)=>{
|
|
if(isLoading.value) return
|
|
isLoading.value = true
|
|
if(isRefresh){
|
|
page.value = 1
|
|
hasMore.value = true
|
|
listNew.value = []
|
|
}
|
|
const res=await api.listNewInterrogation({
|
|
page:page.value,
|
|
pageSize:pageSize.value
|
|
})
|
|
if(res.code ==200){
|
|
const list =res.data.list;
|
|
console.log(1111)
|
|
console.log(list)
|
|
const mapped = list.map(item=>({
|
|
maskName: maskName(item.name || ''),
|
|
date: (item.create_date || '').slice(0,10),
|
|
content: item.your_question || '',
|
|
disease_describe:item.your_question || '',
|
|
answer_num: item.answer_num || 0,
|
|
tag: item.disease_name || '',
|
|
id:item.step1_uuid || ''
|
|
}))
|
|
if(isRefresh){
|
|
listNew.value = mapped
|
|
}else{
|
|
listNew.value = page.value===1 ? mapped : [...listNew.value, ...mapped]
|
|
}
|
|
const totalPage = Number(res.data.pages || 1)
|
|
hasMore.value = page.value < totalPage
|
|
}
|
|
isLoading.value = false
|
|
if(isRefresh){
|
|
isRefreshing.value = false
|
|
}
|
|
}
|
|
const listMyAnsweredInterrogation=async(isRefresh=false)=>{
|
|
if(isLoading.value) return
|
|
isLoading.value = true
|
|
if(isRefresh){
|
|
page.value = 1
|
|
hasMore.value = true
|
|
listMine.value = []
|
|
}
|
|
const res=await api.listMyAnsweredInterrogation({
|
|
page:page.value,
|
|
pageSize:pageSize.value
|
|
})
|
|
console.log(res)
|
|
if(res.code==200){
|
|
const list = Array.isArray(res.data.list) ? res.data.list : []
|
|
const mapped = list.map(item=>({
|
|
maskName: maskName(item.name || ''),
|
|
date: (item.create_date || '').slice(0,10),
|
|
content: item.your_question || '',
|
|
disease_describe:item.disease_describe || '',
|
|
answer_num: item.answer_num || 0,
|
|
tag: item.disease_name || '',
|
|
id:item.step1_uuid || ''
|
|
}))
|
|
if(isRefresh){
|
|
listMine.value = mapped
|
|
}else{
|
|
listMine.value = page.value===1 ? mapped : [...listMine.value, ...mapped]
|
|
}
|
|
const totalPage = Number(res.data.pages || 1)
|
|
hasMore.value = page.value < totalPage
|
|
}
|
|
isLoading.value = false
|
|
if(isRefresh){
|
|
isRefreshing.value = false
|
|
}
|
|
};
|
|
onShow(()=>{
|
|
page.value = 1
|
|
hasMore.value = true;
|
|
if(bottomActive.value==='quick'){
|
|
if(activeTab.value==='new'){
|
|
newConsultList(true)
|
|
}else{
|
|
consultListHis(true)
|
|
}
|
|
}else{
|
|
if(activeTab.value==='new'){
|
|
listNewInterrogation(true)
|
|
}else{
|
|
listMyAnsweredInterrogation(true)
|
|
}
|
|
|
|
}
|
|
})
|
|
|
|
const listNew = ref([])
|
|
|
|
const listMine = ref([])
|
|
|
|
const displayList = computed(() => (activeTab.value === 'new' ? listNew.value : listMine.value))
|
|
|
|
function switchTab(key) {
|
|
activeTab.value = key;
|
|
isLoading.value = false;
|
|
listNew.value = [];
|
|
listMine.value=[];
|
|
if(bottomActive.value==='quick'){
|
|
if(activeTab.value==='new'){
|
|
newConsultList(true)
|
|
}else{
|
|
consultListHis(true)
|
|
}
|
|
|
|
}else{
|
|
if(activeTab.value==='new'){
|
|
listNewInterrogation(true)
|
|
}else{
|
|
listMyAnsweredInterrogation(true)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
function goBack() {
|
|
// #ifdef H5
|
|
history.back()
|
|
// #endif
|
|
// #ifndef H5
|
|
uni.navigateBack({ delta: 1 })
|
|
// #endif
|
|
}
|
|
|
|
// 底部tab交互
|
|
const bottomActive = ref('quick')
|
|
const switchBottomTab=(key)=>{
|
|
isLoading.value = false;
|
|
bottomActive.value = key;
|
|
listNew.value = [];
|
|
listMine.value=[];
|
|
if(key=='quick'){
|
|
if(activeTab.value==='new'){
|
|
newConsultList(true)
|
|
}else{
|
|
consultListHis(true)
|
|
}
|
|
|
|
}else{
|
|
if(activeTab.value==='new'){
|
|
console.log('listNewInterrogation')
|
|
listNewInterrogation(true);
|
|
}else{
|
|
listMyAnsweredInterrogation(true)
|
|
}
|
|
}
|
|
}
|
|
// 下拉刷新
|
|
function onRefresh(){
|
|
if(isRefreshing.value) return
|
|
isRefreshing.value = true
|
|
page.value = 1
|
|
hasMore.value = true
|
|
if(bottomActive.value==='quick'){
|
|
if(activeTab.value==='new'){
|
|
newConsultList(true)
|
|
}else{
|
|
consultListHis(true)
|
|
}
|
|
|
|
}else{
|
|
if(activeTab.value==='new'){
|
|
listNewInterrogation(true)
|
|
}else{
|
|
listMyAnsweredInterrogation(true)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// 触底加载
|
|
function onReachBottom(){
|
|
if(!hasMore.value || isLoading.value) return
|
|
page.value += 1
|
|
if(bottomActive.value==='quick'){
|
|
if(activeTab.value==='new'){
|
|
newConsultList(false)
|
|
}else{
|
|
consultListHis(false)
|
|
}
|
|
|
|
}else{
|
|
if(activeTab.value==='new'){
|
|
listNewInterrogation(false)
|
|
}else{
|
|
listMyAnsweredInterrogation(false)
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.consult-page {
|
|
background-color: #f7f7f7;
|
|
height: 100vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.tabs {
|
|
display: flex;
|
|
justify-content: space-around;
|
|
align-items: center;
|
|
height: 44px;
|
|
padding: 0 16px;
|
|
position: fixed;
|
|
top: 180rpx;
|
|
left: 0;
|
|
right: 0;
|
|
z-index: 10;
|
|
background-color: #ffffff;
|
|
box-shadow: 0 1px 0 rgba(0,0,0,0.06);
|
|
.tab {
|
|
flex: 1;
|
|
text-align: center;
|
|
font-size: 16px;
|
|
color: #7a7a7a;
|
|
padding: 10px 0;
|
|
&.active { color: #8B2316; position: relative; }
|
|
&.active::after { content: ''; position: absolute; left: 25%; right: 25%; bottom: 2px; height: 3px; background-color: #8B2316; border-radius: 2px; }
|
|
}
|
|
}
|
|
.tabs-spacer { height: 44px; }
|
|
.list-scroll {
|
|
flex: 1;
|
|
position: fixed;
|
|
top: 228rpx;
|
|
bottom: 136rpx;
|
|
padding: 8px 0px 0 0px;
|
|
margin: 20rpx 30rpx 0;
|
|
box-sizing: border-box;
|
|
width:auto;
|
|
}
|
|
|
|
.consult-card {
|
|
background-color: #ffffff;
|
|
border-radius: 8px;
|
|
padding: 12px;
|
|
margin-bottom: 12px;
|
|
.card-head {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
.user-name { font-size: 16px; color: #a31712; }
|
|
.date { font-size: 14px; color: #9aa0a6; }
|
|
}
|
|
.card-body {
|
|
background: #efefef;
|
|
padding: 20rpx;
|
|
margin: 10px 0;
|
|
.content {
|
|
word-break: break-all;
|
|
font-size: 15px; color: #2b2f33; line-height: 1.6;
|
|
} }
|
|
.card-foot {
|
|
.left{
|
|
display: flex;
|
|
.detail{
|
|
font-size: 28rpx;
|
|
background: #a31712;
|
|
color:#fff;
|
|
border-radius: 14rpx;
|
|
margin-right: 10rpx;
|
|
padding: 8rpx 16rpx;
|
|
border-radius: 28rpx;
|
|
font-size: 28rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border:2rpx solid #a31712;
|
|
}
|
|
}
|
|
display: flex; align-items: center; justify-content: space-between; margin-top: 8px;
|
|
.reply-count { font-size:28rpx; color: #8B2316; }
|
|
.tag {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 8rpx 16rpx; background: #fff5f5; color: #a31712; border-radius: 28rpx; font-size: 24rpx; border:2rpx solid #a31712;}
|
|
}
|
|
}
|
|
|
|
.bottom-bar {
|
|
position: fixed;
|
|
left: 0; right: 0; bottom: 0;
|
|
background-color: #ffffff;
|
|
box-shadow: 0 -2px 8px rgba(0,0,0,0.06);
|
|
display: flex; align-items: center; justify-content: center;
|
|
padding: 8px 12px;
|
|
gap: 12px;
|
|
.bottom-tab {
|
|
flex: 1;
|
|
height: 40px;
|
|
line-height: 40px;
|
|
text-align: center;
|
|
border-radius: 6px;
|
|
font-size: 16px;
|
|
color: #a31712;
|
|
background-color: #fff5f5;
|
|
}
|
|
.bottom-tab.active {
|
|
background-color: #a31712;
|
|
color: #ffffff;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
|