case-data/pages/search/search.vue
2025-08-15 09:18:09 +08:00

1025 lines
23 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="u-page">
<z-paging
ref="paging"
inside-more
loading-more-no-more-text="咱也是有底线的"
:auto-show-back-to-top="true"
v-model="dataList"
@query="queryList"
>
<template #top>
<navBarSearch :searchWord="keyWord" :navName="navName" @changeWord="changeWord" :type="navType"></navBarSearch>
<view class="databox" v-if="hospital_id || doctor_id || (label_iden && !canOpenCase)">
<view class="cell">
<view class="num">{{ numInfo.article_num }}</view>
<view class="name">文章</view>
</view>
<view class="cell">
<view class="num">{{ numInfo.video_num }}</view>
<view class="name">视频</view>
</view>
<view class="cell">
<view class="num">{{ numInfo.video_read_num+numInfo.article_read_num }}</view>
<view class="name">阅读量</view>
</view>
</view>
<view class="bar"></view>
<view class="detail" v-if="isSearch">
<view class="desc" >检索到:<text class="red">{{searchInfo.search_article_num}}篇文章</text></view>
<view class="desc" v-if="!hideType">检索到:<text class="red">{{searchInfo.search_video_num}}个视频</text></view>
<view class="desc" v-if="keyWord">检索词:<text class="red">{{ keyWord }}</text></view>
</view>
<view class="filterbox" :class="{active:canOpenCase,'on':hideType,'isCase':isCase}">
<view class="type" v-if="!hideType && !isCase" @click="swicthType">{{!isArticle?'视频':'文章'}}<up--image :src="switchImg" width="31rpx" height="31rpx"></up--image></view>
<view class="casesdown" :class="{active:label_iden}" @click="openCase" v-if="canOpenCase">筛选<up--image :src="caseImg" width="31rpx" height="31rpx"></up--image></view>
<up-dropdown class="u-dropdown" ref="uDropdownRef">
<up-dropdown-item
:title="dropTitle"
>
<view class="dropcontent">
<up-radio-group
@change="changeDate"
v-model="orderFilter"
iconPlacement="right"
placement="column"
>
<view
class="column"
v-for="item in options"
:key="item.value"
:class="[orderFilter==item.value?'active':'']"
>
<up-radio
activeColor="#3CC7C0"
:label="item.label"
:name="item.value"
></up-radio>
</view>
</up-radio-group>
</view>
</up-dropdown-item>
<!-- <up-dropdown-item
v-model="order.read_num"
title="阅读量"
@change="changeRead"
:options="options"
></up-dropdown-item> -->
</up-dropdown>
</view>
</template>
<view class="item" v-for="(item, index) in dataList" :key="index" @click="isArticle?goDetail(item.article_id,item.is_link,item.is_link_url):goDetail(item.video_id,item.is_link,item.is_link_url)">
<view class="title ellipsis-two-lines">{{isArticle?item.article_title:item.video_title }}</view>
<view class="tagsbox">
<view class="tag" v-for="tag in item.author" :key="tag.author_id">{{ tag.doctor_name }}</view>
</view>
<view class="deal">
<view class="left">
<view class="eyebox">
<up-icon name="eye" color="#6B7280" size="28rpx"></up-icon>
<view class="num">{{item.read_num }}</view>
</view>
<view class="collect" v-if="item.collect_num>0">
<up-icon name="heart" color="#6B7280" size="28rpx"></up-icon>
<view class="num" >{{item.collect_num }}</view>
</view>
</view>
<view class="time">
<up-icon name="clock" color="#6B7280" size="28rpx"></up-icon>
<view class="num">{{formatdate(item.push_date) }}</view>
</view>
</view>
</view>
</z-paging>
</view>
<up-popup
:round="10"
zIndex="9"
:closeOnClickOverlay="false"
:show="showCase"
mode="bottom"
@close="closeCase"
>
<view class="votepop casepop">
<view class="titlebox">
<view class="left" @click="closeCase">取消</view>
<view class="right" @click="confirmCase">确定</view>
</view>
<view class="stepbox">
<up-steps :current="level-1" direction="column" :key="freshKey">
<up-steps-item >
<template v-slot:content>
<view class="slot-content" @click="openCaseLevel('1')">
<view class="left">{{!caseValue1.name?'请选择选项':caseValue1.name}}</view>
<u-icon name="arrow-right"></u-icon>
</view>
</template>
</up-steps-item>
<up-steps-item v-if="caseValue1.name && labelObj.list2.length>0">
<template v-slot:content>
<view class="slot-content" @click="openCaseLevel('2')">
<view class="left">{{!caseValue2.name?'请选择选项':caseValue2.name}}</view>
<u-icon name="arrow-right"></u-icon>
</view>
</template>
</up-steps-item>
<up-steps-item v-if="caseValue2.name && labelObj.list3.length>0">
<template v-slot:content>
<view class="slot-content" @click="openCaseLevel('3')">
<view class="left">{{!caseValue3.name?'请选择选项':caseValue3.name}}</view>
<u-icon name="arrow-right"></u-icon>
</view>
</template>
</up-steps-item>
</up-steps>
</view>
<scroll-view class="casecon" scroll-y="true">
<view v-show="level == 1" >
<up-radio-group
v-model="caseValue1.value"
name="group1"
iconPlacement="right"
placement="column"
@change="groupChange1"
>
<view
class="column"
v-for="item in labelObj.list1"
:key="item.app_iden"
v-show="item.label_name!='热门话题'"
>
<up-radio
activeColor="#3CC7C0 "
:label="item.label_name"
:name="item.app_iden"
></up-radio>
</view>
</up-radio-group>
</view>
<view v-show="level == 2" >
<up-radio-group
name="group2"
@change="groupChange2"
v-model="caseValue2.value"
iconPlacement="right"
placement="column"
>
<view
class="column"
v-for="item in labelObj.list2"
:key="item.app_iden"
>
<up-radio
activeColor="#3CC7C0 "
:label="item.label_name"
:name="item.app_iden"
></up-radio>
</view>
</up-radio-group>
</view>
<view v-show="level == 3" >
<up-radio-group
name="group3"
@change="groupChange3"
v-model="caseValue3.value"
iconPlacement="right"
placement="column"
>
<view
class="column"
v-for="item in labelObj.list3"
:key="item.app_iden"
>
<up-radio
activeColor="#3CC7C0 "
:label="item.label_name"
:name="item.app_iden"
></up-radio>
</view>
</up-radio-group>
</view>
</scroll-view>
</view>
</up-popup>
</template>
<script setup>
import { ref, reactive } from "vue";
import navBarSearch from "@/components/navBarSearch/navBarSearch.vue";
import list from "@/uni_modules/z-paging/components/z-paging/z-paging";
import api from "@/api/api";
import { onLoad,onShow} from "@dcloudio/uni-app";
import dayjs from "dayjs";
import switchImg from "@/static/switch.png";
import caseImg from "@/static/caseIcon.png";
import navTo from "@/utils/navTo.js";
const dataList = ref([]);
const total = ref(0);
const keyWord = ref("");
const label_iden = ref("");
const isArticle=ref(true);
const hospital_id=ref('');
const hospital_name=ref('');
const doctor_id=ref('');
const doctor_name=ref('');
const numInfo=reactive({});
const searchInfo=reactive({});
const freshKey=ref(0);
const navType=ref('')
const navName=ref('肝胆相照临床病例库')
const paging = ref(null);
const hideType=ref(false)
const dropTitle=ref('发布时间');
const orderFilter=ref('1')
const uDropdownRef=ref(null);
const isCase=ref(false);
const options= ref([
{
label: "发布时间",
value: '1',
},
{
label: "阅读次数",
value: '2',
},
]);
const isSearch=ref(false);
const order=reactive({
read_num:'',
push_date:'desc'
})
const showCase = ref(false);
const canOpenCase = ref(false);
const caseValue1 = reactive({
value:'',
name:'',
});
const caseValue2 = reactive({
value:'',
name:'',
});
const caseValue3 = reactive({
value:'',
name:'',
});
const level = ref(1);
const labelObj = reactive({
list1: [],
list2: [],
list3: []
});
const openCaseLevel=(lev)=>{
freshKey.value++;
level.value=lev;
if(lev==1){
caseValue2.name='';
caseValue2.value='';
labelObj.list2=[]
}else if(lev==2){
labelObj.list3=[];
caseValue3.name='';
caseValue3.value=''
}
};
const groupChange1=(e)=>{
caseValue1.value=e;
for (var i = 0; i <labelObj.list1.length; i++) {
if(labelObj.list1[i].app_iden==caseValue1.value){
caseValue1.name=labelObj.list1[i].label_name;
break;
}
}
getCaseLabel(2,e)
}
const groupChange2=(e)=>{
caseValue2.value=e;
for (var i = 0; i <labelObj.list2.length; i++) {
if(labelObj.list2[i].app_iden==caseValue2.value){
caseValue2.name=labelObj.list2[i].label_name;
break;
}
}
getCaseLabel(3,e)
}
const groupChange3=(e)=>{
caseValue3.value=e;
level.value =3
for (var i = 0; i <labelObj.list3.length; i++) {
if(labelObj.list3[i].app_iden==caseValue3.value){
caseValue3.name=labelObj.list3[i].label_name;
break;
}
}
}
const getCaseLabel = (lev,pid=0) => {
api.getCaseLabel({
pId:pid
}).then((res) => {
level.value = lev;
if (lev == 1) {
labelObj.list1 = res.data.data;
//label_iden.value = caseValue1.value;
} else if (lev == 2) {
labelObj.list2 = res.data.data;
if(res.data.data.length==0){
level.value = 1
}
//label_iden.value = caseValue2.value;
} else if (lev == 3) {
labelObj.list3 = res.data.data;
if(res.data.data.length==0){
level.value = 2
}
//label_iden.value = caseValue3.value;
}
});
};
const openCase=()=>{
showCase.value = true;
}
const cancelCase=()=>{
showCase.value=false;
level.value=1;
caseValue1.name='';
caseValue1.value='';
caseValue2.name='';
caseValue2.value='';
caseValue3.name='';
caseValue3.value='';
//labelObj.list1=[];
labelObj.list2=[];
labelObj.list3=[];
}
const confirmCase = () => {
if (level.value == 1 && caseValue1.value == "") {
uni.showToast({ title: "请选择疾病选项", icon: "none" });
return false;
};
if(level.value == 1){
label_iden.value = caseValue1.value;
}
if(level.value == 2 ){
if(!caseValue2.value){
label_iden.value = caseValue1.value;
}else{
label_iden.value = caseValue2.value;
}
}
if(level.value == 3 ){
if(!caseValue3.value){
label_iden.value = caseValue2.value;
}else{
label_iden.value = caseValue3.value;
}
}
paging.value.reload();
showCase.value=false;
//cancelCase();
};
const closeCase = () => {
showCase.value = false;
};
const changeWord=(value)=>{
keyWord.value=value;
isSearch.value=true;
paging.value.reload()
}
onLoad((options) => {
if(options.from=='home'){
isSearch.value=true;
}else if(options.from=="myCase"){
navType.value="myCase"
}
if(options.keyWord){
keyWord.value = options.keyWord;
};
if(options.order=='new'){
order.push_date='desc';
hideType.value=true;
navName.value='文章临床病例库'
};
if(options.order=='read'){
order.push_date='desc';
hideType.value=true;
navName.value='文章临床病例库'
};
if(options.order=='video'){
isArticle.value=false;
}
if(options.doctor_id){
doctor_id.value=options.doctor_id;
doctor_name.value=options.doctor_name
navName.value= doctor_name.value+'临床病例库'
getStaticDoctor(doctor_id.value)
}
if(options.hospital_id){
hospital_id.value=options.hospital_id;
hospital_name.value=options.hospital_name;
navName.value= hospital_name.value+'临床病例库'
getStaticHospital(hospital_id.value)
}
if(options.case_id){
label_iden.value=options.case_id;
navName.value= options.case_name+'临床病例库'
getStaticSick(label_iden.value);
//isCase.value=true;
//console.log(111113)
}else{
canOpenCase.value = true;
}
getCaseLabel(1,0)
});
onShow(()=>{
paging.value?.refresh();
})
const changeDate=(e)=>{
if(e==1){
order.push_date='desc';
order.read_num='';
dropTitle.value="发布时间"
}else{
order.push_date='';
order.read_num="desc";
dropTitle.value="阅读次数"
}
orderFilter.value=e;
uDropdownRef.value.close();
paging.value.reload();
}
const changeRead=(e)=>{
console.log(e);
order.push_date=''
paging.value.reload();
}
const formatdate=(date)=>{
return dayjs(date).format('YYYY-MM-DD')
}
const goDetail=(id,isLink,src)=>{
console.log(isLink)
if(isLink==1){
api.readRecord({
type:isArticle.value?1:2,
id:id
}).then(res=>{
})
// #ifdef MP-WEIXIN
navTo({
url: `/pages/web/web?src=${src}`,
});
// #endif
// #ifdef H5
window.location.href=`${src}`
// #endif
}else{
let type=isArticle.value?'article':'video'
navTo({
url: `/pages/detail/detail?id=${id}&type=${type}`
})
}
}
const swicthType=()=>{
isArticle.value=!isArticle.value;
dataList.value=[];
// order.read_num='';
// order.push_date='';
paging.value.reload();
}
const searchArticle =(params) => {
let searchForm={
keyword: keyWord.value,
hospital_id:hospital_id.value,
doctor_id:doctor_id.value,
label_iden:label_iden.value
}
if(label_iden.value===''){
delete searchForm.label_iden
}
if(isSearch.value){
searchForm.is_need_num=1;
}
if(!order.read_num){
delete order.read_num
}
if(!order.push_date){
delete order.push_date
}
if(order.read_num || order.push_date){
searchForm.order=order
}
api.searchArticle({
...searchForm,
...params
}).then((res)=>{
paging.value.complete(res.data.data.data);
total.value=res.data.data.total;
searchInfo.search_video_num=res.data.data.search_video_num;
searchInfo.search_article_num=res.data.data.search_article_num;
}).catch(err=>{
paging.value.complete(false);
})
}
const searchVideo = async(params) => {
let searchForm={
keyword: keyWord.value,
hospital_id:hospital_id.value,
doctor_id:doctor_id.value,
label_iden:label_iden.value
}
if(label_iden.value===''){
delete searchForm.label_iden
}
if(isSearch.value){
searchForm.is_need_num=1;
}
if(!order.read_num){
delete order.read_num
}
if(!order.push_date){
delete order.push_date
}
if(order.read_num || order.push_date){
searchForm.order=order
}
api.searchVideo({
...searchForm,
...params
}).then((res)=>{
paging.value.complete(res.data.data.data);
total.value=res.data.data.total;
searchInfo.search_video_num=res.data.data.search_video_num;
searchInfo.search_article_num=res.data.data.search_article_num;
}).catch(err=>{
paging.value.complete(false);
})
}
const getStaticDoctor=(id)=>{
api.getStaticDoctor(id).then((res)=>{
let result=res.data.data;
if(result){
Object.assign(numInfo,result);
}else{
Object.assign(numInfo,{
article_num: 0,
article_read_num: 0,
video_collect_num: 0,
video_num: 0,
video_read_num: 0,
});
}
})
}
const getStaticSick=(id)=>{
api.getStaticSick({
label_iden:id
}).then((res)=>{
let result=res.data.data;
if(result){
Object.assign(numInfo,result);
}else{
Object.assign(numInfo,{
article_num: 0,
article_read_num: 0,
video_collect_num: 0,
video_num: 0,
video_read_num: 0,
});
}
})
}
const getStaticHospital=(id)=>{
api.getStaticHospital(id).then((res)=>{
let result=res.data.data;
if(result){
Object.assign(numInfo,result);
}else{
Object.assign(numInfo,{
article_num: 0,
article_read_num: 0,
video_collect_num: 0,
video_num: 0,
video_read_num: 0,
});
}
})
}
const queryList = (pageNo, pageSize) => {
console.log(666666);
const params = {
page: pageNo,
page_size: pageSize,
};
isArticle.value?searchArticle(params):searchVideo(params)
};
</script>
<style lang="scss" scoped>
.dropcontent{
padding-top: 40rpx;
padding-bottom: 20rpx;
background-color: #fff;
:deep(.u-radio){
margin-bottom: 6px!important;
margin-top: 16px!important;
}
.column {
padding: 0 30rpx;
border-top: 2rpx solid #e5e7eb;
:deep(.u-radio__text){
color: #333 !important;
}
}
.column.active{
:deep(.u-radio__text){
color: #3CC7C0 !important;
}
}
}
.stepbox{
padding:15rpx 30rpx;
border-bottom: 2rpx dotted #f3f4f6;
:deep(.u-steps-item__content){
margin-top: -5rpx!important;
}
.slot-content{
width:100%;
margin-bottom: 25rpx;
justify-content: space-between;
align-items: center;
display: flex;
}
}
.bar {
width: 100%;
background: #f9fafb;
height: 20rpx;
}
.votepop {
.confirm {
margin: 39rpx 30rpx 0;
height: 92rpx;
background: #3cc7c0;
border-radius: 15rpx;
display: flex;
align-items: center;
font-size: 31rpx;
color: #ffffff;
justify-content: center;
}
.del {
margin: 30rpx 30rpx 30rpx;
height: 92rpx;
background: #fff;
border-radius: 15rpx;
font-size: 31rpx;
color: #666666;
display: flex;
align-items: center;
justify-content: center;
}
.tips {
margin-top: 30rpx;
font-size: 27rpx;
color: #9ca3af;
line-height: 38rpx;
padding: 0 30rpx;
}
.add {
margin: 0 30rpx;
display: flex;
align-items: center;
height: 92rpx;
justify-content: center;
background: #f5f5f5;
border-radius: 15rpx;
font-size: 31rpx;
color: #4b5563;
.desc {
margin-left: 10rpx;
}
}
.titlebox {
padding: 0 30rpx;
height: 86rpx;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 2rpx solid #f3f4f6;
.left {
font-size: 31rpx;
color: #4b5563;
}
.right {
font-size: 31rpx;
color: #3cc7c0;
}
}
.votecon {
max-height: calc(100vh - 530rpx);
overflow-y: scroll;
.row {
display: flex;
align-items: center;
.iconbox {
margin-left: 15rpx;
align-items: center;
}
}
.titlebox {
border: none;
margin: 30rpx 0 20rpx;
.title {
font-size: 31rpx;
color: #111827;
}
.desc {
font-size: 27rpx;
color: #9ca3af;
}
}
}
}
.casepop{
display: flex;
flex-direction: column;
max-height: calc(100vh - 400rpx);
.continue{
color: #2878ff !important;
}
}
.casecon{
flex:1;
max-height: calc(100vh - 800rpx);
overflow-y: scroll;
padding-top: 22rpx;
padding-bottom: 20rpx;
min-height: 350rpx;
:deep(.u-radio){
margin-bottom: 10px!important;
margin-top: 0px!important;
}
.column {
padding: 0 30rpx;
border-bottom: 2rpx solid #e5e7eb;
}
}
.databox {
height: 162rpx;
background: #ffffff;
display: flex;
margin-bottom: 20rpx;
// padding: 0 30rpx;
justify-content: space-between;
.cell {
flex: 1;
padding: 35rpx 0;
text-align: center;
.num {
font-size: 38rpx;
color: #3cc7c0;
}
.name {
margin-top: 18rpx;
font-size: 28rpx;
color: #4b5563;
}
}
}
.filterbox{
background:#fff;
:deep(.u-flex) {
display: flex;
flex-direction:row;
overflow: hidden;
}
:deep(.u-dropdown__menu){
background: #fff;
z-index:1;
margin-left: 150rpx;
}
:deep(.u-dropdown__menu__item__text){
font-size: 14px!important;
color:#3CC7C0!important;
}
:deep(.u-dropdown__menu__item){
height:74rpx;
padding:0 20rpx;
background: #F3F4F6;
border-radius: 15rpx;
flex:none;
margin-left: 60rpx;
}
display: flex;
height:128rpx;
align-items: center;
position: relative;
.type{
position: absolute;
left:30rpx;
top:24rpx;
color: #606266;
font-size:14px;
display: flex;
justify-content: center;
align-items: center;
background: #F3F4F6;
border-radius: 15rpx;
height: 74rpx;
padding:0 25rpx;
z-index:2;
}
.casesdown{
font-size:14px;
color: #606266;
position: absolute;
left:190rpx;
top:24rpx;
display: flex;
justify-content: center;
align-items: center;
background: #F3F4F6;
border-radius: 15rpx;
height: 74rpx;
padding:0 25rpx;
z-index:2;
}
}
.filterbox.active{
:deep(.u-flex) {
display: flex;
flex-direction:row;
overflow: hidden;
}
:deep(.u-dropdown__menu){
background: #fff;
z-index:1;
margin-left: 330rpx;
}
:deep(.u-dropdown__menu__item__text){
font-size: 14px!important;
}
:deep(.u-dropdown__menu__item){
height:74rpx;
padding:0 20rpx;
background: #F3F4F6;
border-radius: 15rpx;
flex:none;
margin-left: 20rpx;
}
display: flex;
height:128rpx;
align-items: center;
position: relative;
.type{
position: absolute;
left:30rpx;
top:24rpx;
color: #606266;
font-size: 14px;
display: flex;
justify-content: center;
align-items: center;
background: #F3F4F6;
border-radius: 15rpx;
height: 74rpx;
padding:0 25rpx;
z-index:2;
}
.casesdown{
font-size: 14px;
color: #606266;
position: absolute;
left:190rpx;
top:24rpx;
display: flex;
justify-content: center;
align-items: center;
background: #F3F4F6;
border-radius: 15rpx;
height: 74rpx;
padding:0 25rpx;
z-index:2;
}
}
.filterbox.on{
.casesdown{
left:30rpx;
}
:deep(.u-dropdown__menu){
background: #fff;
z-index:1;
margin-left: 170rpx;
}
}
.filterbox.isCase{
:deep(.u-dropdown__menu){
background: #fff;
z-index:1;
margin-left: -30rpx;
}
}
.u-page {
.deal {
margin-top: 20rpx;
display: flex;
color: #6b7280;
font-size: 24rpx;
justify-content: space-between;
.left {
display: flex;
align-items: center;
}
.collect {
display: flex;
align-items: center;
}
.eyebox {
width: 160rpx;
display: flex;
align-items: center;
}
.time {
display: flex;
align-items: center;
}
.num {
margin-left: 8rpx;
}
}
.item {
border-bottom: 1rpx solid #f3f4f6;
background-color: #fff;
padding: 30rpx;
.title {
font-size: 30rpx;
color: #111827;
line-height: 46rpx;
}
}
.tagsbox {
margin-top: 20rpx;
display: flex;
flex-wrap: wrap;
.tag {
padding: 0 10rpx;
margin-right: 16rpx;
height: 46rpx;
line-height: 46rpx;
text-align: center;
background: rgba(60, 199, 192, 0.1);
border-radius: 8rpx;
font-weight: 400;
font-size: 24rpx;
color: #3cc7c0;
}
}
}
.detail {
background: #f9f9f9;
padding: 12rpx 30rpx;
.desc {
font-size: 26rpx;
color: #4b5563;
line-height: 40rpx;
}
.red{
color: #FF0000;
}
}
</style>