This commit is contained in:
zoujiandong 2025-06-10 17:40:29 +08:00
parent db955ff4f3
commit e25eb25063
11 changed files with 1342 additions and 676 deletions

View File

@ -94,9 +94,12 @@ const api = {
getExchangeStaticUser(id){
return request('/exchange/stats/user/'+id,{}, 'get', false);
},
searchExchage(){
searchExchage(data){
return request('/exchange/search', data, 'post',true,'application/json');
},
searchExchageGood(data){
return request('/exchange/list', data, 'post',true,'application/json');
},
getExchangeDetail(id){
return request('/exchange/'+id,{}, 'get', false);
},
@ -122,10 +125,22 @@ const api = {
return request('/exchange/comment/top/'+id, {}, 'delete',false);
},
getExchangeComment(data){
return request('/exchange/comment/page', data, 'post',false);
return request('/exchange/comment/page', data, 'post',false,'application/json');
},
getExchangeCommentUser(data){
return request('/exchange/user/comment/page', data, 'post',false);
return request('/exchange/user/comment/page', data, 'post',false,'application/json');
},
addExchange(data){
return request('/exchange', data, 'post',false,'application/json');
},
getDraftList(data){
return request('/exchange/draft/search', data, 'post',false,'application/json');
},
getVideoCommentUser(data){
return request('/clinical/video/user/comment/page', data, 'post',false,'application/json');
},
getArticleCommentUser(data){
return request('/clinical/article/user/comment/page', data, 'post',false,'application/json');
},
getMyCollect(data){
return request('/user/collect/search',data, 'post',false,'application/json');
@ -133,6 +148,13 @@ const api = {
getMyRead(data){
return request('/user/case/read/search',data, 'post',false,'application/json');
},
getOss(data){
return request('/sign/oss',data, 'get', false);
},
ossUpload(url,data){
return request(url,data,'post','multipart/form-data')
},
queryList(data) {
const listCount = 24;
return _queryList(data, listCount);

View File

@ -0,0 +1,106 @@
<template>
<view class="navbox">
<view class="bg"></view>
<view class="namebox">
<view class="back" @click="goBack">
<u-icon name="arrow-left" color="#000" size="24"></u-icon>
</view>
<view class="logo">
<up--image
:src="logoImg"
width="62rpx"
height="62rpx"
radius="50%"
></up--image>
</view>
<view class="name">{{ navName }}</view>
</view>
</view>
</template>
<script setup>
import logoImg from "@/static/logo.png";
const props = defineProps({
navName: {
type: String,
default: "我的",
}
});
const goBack = () => {
uni.navigateBack({
delta: 1,
});
};
</script>
<style lang="scss" scoped>
.navbox {
padding-bottom: 20rpx;
background-color: #f9fafb;
position: relative;
height:200rpx;
background: radial-gradient(
60% 90% at 4% 2%,
#43c9c3 0%,
rgba(255, 255, 255, 0) 100%
);
}
.bg {
z-index: 0;
top: 0;
bottom: 0;
width: 100%;
position: absolute;
background: radial-gradient(
43% 90% at 84% 6%,
#ffd6c9 0%,
rgba(255, 255, 255, 0) 100%
);
}
.namebox {
padding-top: 102rpx;
margin: 0rpx 30rpx 0rpx;
display: flex;
align-items: center;
display: flex;
align-items: center;
.logo{
margin-left: 35rpx;
}
.back{
position: absolute;
left: 0;
}
.name {
margin-left: 16rpx;
font-size: 30rpx;
color: #111827;
}
}
.search {
margin: 40rpx 30rpx 0rpx;
display: flex;
align-items: center;
justify-content: space-between;
.searchwrap {
display: flex;
align-items: center;
flex: 1;
padding-left: 28rpx;
margin-right: 23rpx;
height: 80rpx;
background: #fbfbfb;
box-shadow: 0px 4rpx 10rpx 0px rgba(153, 153, 153, 0.5);
border-radius: 40rpx;
.ipt {
margin-left: 15rpx;
font-size: 28rpx;
}
}
}
</style>

View File

@ -42,7 +42,7 @@ const props=defineProps({
},
type:{
type:String,
default:'',
default:'home',
},
navName:{
type:String,
@ -50,12 +50,13 @@ const props=defineProps({
}
})
const emit = defineEmits(['changeWord'])
const placeholder = ref("输入疾病名称、标题、作者搜索");
watch(()=>props.type,(newVal)=>{
if(newVal==='doctor'){
placeholder.value='输入医生姓名'
}else if(newVal==='hospital'){
placeholder.value='输入医院名称'
if(newVal==='home'){
//placeholder.value=''
}else if(newVal==='caseTalk'){
//placeholder.value=''
}
},{immediate: true })
@ -68,6 +69,15 @@ const goMy=()=>{
})
}
const search=()=>{
if(props.type=='home'){
uni.navigateTo({
url: `/pages/search/search?keyWord=${keyWord.value}`,
});
}else if(props.type=='caseTalk'){
uni.navigateTo({
url: `/pages/specialList/specialList?keyWord=${keyWord.value}`,
});
}
// if (!keyWord.value) {
// return uni.showToast({
// title: "",
@ -75,9 +85,7 @@ const search=()=>{
// });
// }
uni.navigateTo({
url: `/pages/search/search?keyWord=${keyWord.value}`,
});
}
</script>

View File

@ -16,91 +16,126 @@
</view>
</view>
<view class="bar"></view>
<view class="box">
<view class="special">
<view class="titlebox">
<view class="title">精选病例</view>
<view class="more" @click="goList('read')">
<view class="morename">查看更多</view>
<u-icon name="arrow-right" size="16" color="#3CC7C0"></u-icon>
<view class="box">
<view class="special mostread" v-if="most_read_articles.length>0">
<view class="titlebox">
<view class="title">精选病例</view>
<view class="more" @click="goList('read')">
<view class="morename">查看更多</view>
<u-icon name="arrow-right" size="16" color="#3CC7C0"></u-icon>
</view>
</view>
<view class="list">
<view class="cell" v-for="item in most_read_articles" :key="item.exchange_id">
<view class="circle"></view>
<view class="title ellipsis-two-lines">{{ item.exchange_title }}</view>
</view>
</view>
</view>
<view class="list">
<view class="cell" v-for="item in most_read_articles" :key="item.article_id">
<view class="circle"></view>
<view class="title">{{ item.article_title }}</view>
<view class="bar"></view>
<view class="record special">
<view class="titlebox">
<view class="title">最新收录</view>
<view class="more" @click="goList('mew')">
<view class="morename">查看更多</view>
<u-icon name="arrow-right" size="16" color="#3CC7C0"></u-icon>
</view>
</view>
</view>
</view>
<view class="bar"></view>
<view class="record">
<view class="titlebox">
<view class="title">最新收录</view>
<view class="more" @click="goList('mew')">
<view class="morename">查看更多</view>
<u-icon name="arrow-right" size="16" color="#3CC7C0"></u-icon>
<view class="list">
<view
class="cell"
v-for="(item) in new_articles"
:key="item.exchange_id"
>
<view class="title ellipsis-two-lines">{{
item.exchange_title
}}</view>
<view class="doctor">
<up--image
:src="item.avatar ? item.avatar : headImg"
width="46rpx"
height="46rpx"
radius="50%"
></up--image>
<view class="name"
>{{ item.user_name }}{{ item.hospital_name }}</view
>
</view>
</view>
<view class="list">
<view class="cell" v-for="item in new_articles" :key="item.article_id">
<view class="title">{{ item.article_title }}</view>
<view class="doctor" v-for="cell in item.autor">
<up--image :src="headImg" width="46rpx" height="46rpx" radius="50%"></up--image>
<view class="name">{{cell.doctor_name}}{{cell.hospital_name}}</view>
<view class="content"> {{ item.exchange_content }} </view>
<view
class="imgbox"
v-if="
item.exchange_content_images &&
item.exchange_content_images.length > 0
"
>
<view
class="imgcell"
v-if="unit in item.exchange_content_images"
>
<up--image
:src="unit"
radius="10"
width="220rpx"
height="220rpx"
>
<view slot="error" style="font-size: 24rpx">加载失败</view>
</up--image>
</view>
<view class="content">
嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎XXXXX
</view>
<view class="videocon">
<view
class="imgbox"
v-if="
item.exchange_content_video &&
item.exchange_content_video.length > 0
"
>
<video
:key="index"
v-for="(videoCell, index) in item.exchange_content_video"
class="myVideo"
:src="videoCell"
@error="videoErrorCallback"
controls
></video>
</view>
<view class="imgbox">
<view class="imgcell">
<up--image src="https://cdn.uviewui.com/uview/album/1.jpg" radius="10" width="220rpx"
height="220rpx">
<view slot="error" style="font-size: 24rpx;">加载失败</view>
</up--image>
</view>
<view class="imgcell">
<up--image src="https://cdn.uviewui.com/uview/album/1.jpg" radius="10" width="220rpx"
height="220rpx">
<view slot="error" style="font-size: 24rpx;">加载失败</view>
</up--image>
</view>
<view class="imgcell">
<up--image src="https://cdn.uviewui.com/uview/album/1.jpg" radius="10" width="220rpx"
height="220rpx">
<view slot="error" style="font-size: 24rpx;">加载失败</view>
</up--image>
</view>
</view>
<view class="tagbox" v-if="item.label && item.label.length > 0">
<view
class="tag"
v-for="cell in item.label"
:key="cell.exchange_label_id"
>{{ cell.label_name }}</view
>
</view>
<view class="deal">
<view class="left">
<view class="eyebox item">
<up-icon name="eye" color="#4B5563" size="28rpx"></up-icon>
<view class="num">{{ item.read_num }}</view>
</view>
<view class="imgbox">
<video class="myVideo" src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4"
@error="videoErrorCallback" controls></video>
<view class="collect item">
<up-icon
name="heart"
color="#4B5563"
size="28rpx"
></up-icon>
<view class="num">{{ item.collect_num }}</view>
</view>
<view class="tagbox">
<view class="tag">标签</view>
<view class="chat item">
<up-icon name="chat" color="#4B5563" size="28rpx"></up-icon>
<view class="num">{{ item.comment_num }}</view>
</view>
</view>
<view class="time">
<up-icon name="clock" color="#4B5563" size="28rpx"></up-icon>
<view class="num">{{ formatdate(item.push_date) }}</view>
</view>
<view class="deal">
<view class="left">
<view class="eyebox item">
<up-icon name="eye" color="#4B5563" size="28rpx"></up-icon>
<view class="num">{{ item.read_num }}</view>
</view>
<view class="collect item">
<up-icon :name="item.is_collect?'heart-fill':'heart'" :color="item.is_collect?'red':'#4B5563'" size="28rpx"></up-icon>
<view class="num">{{item.collect_num }}</view>
</view>
<view class="chat item">
<up-icon name="chat" color="#4B5563" size="28rpx"></up-icon>
<view class="num">{{item.comment_num }}</view>
</view>
</view>
<view class="time">
<up-icon name="clock" color="#4B5563" size="28rpx"></up-icon>
<view class="num">{{formatdate(item.push_date) }}</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
@ -129,9 +164,16 @@
// })
// };
const goList=(type)=>{
uni.navigateTo({
url:'/pages/search/search?order='+type
})
if(type=='read'){
uni.navigateTo({
url:'/pages/specialList/specialList?is_selected=1'
})
}else{
uni.navigateTo({
url:'/pages/specialList/specialList'
})
}
};
const getStatic=()=>{
api.getExchangeStatic().then(res=>{
@ -139,24 +181,50 @@
Object.assign(numInfo,result);
})
}
const getData = async() => {
const {data}=await api.getHomeData();
if(data.code==200){
most_read_articles.value=data.data.most_read_articles;
new_articles.value=data.data.new_articles;
}
};
const videoErrorCallback = (e) => {
uni.showModal({
content: e.target.errMsg,
showCancel: false
})
};
onLoad(()=>{
console.log('onLoad')
const searchList = async () => {
let searchForm = {
page: 1,
page_size: 10
};
api.searchExchage({
...searchForm
})
.then((res) => {
new_articles.value=res.data.data.data;
})
.catch((err) => {
});
};
const goodList=()=>{
api.searchExchageGood({
is_selected:1,
limit:5
}).then(res=>{
most_read_articles.value=res.data.data
})
}
const hotList=()=>{
api.searchExchageHot({
is_selected:0,
limit:5,
page:1,
page_size:5
}).then(res=>{
})
}
onLoad(()=>{
getStatic();
getData();
goodList();
searchList();
})
</script>
@ -166,7 +234,14 @@
flex-direction: column;
height: calc(100vh - 100rpx);
}
.mostread{
.cell{
padding: 22rpx 0rpx!important;
margin:0 30rpx;
display: flex;
}
}
.box {
flex: 1;
padding-bottom: 30rpx;
@ -224,6 +299,7 @@
padding: 0 28rpx;
background: #ECFAF9;
border-radius: 30rpx;
margin-right: 12rpx;
font-size: 27rpx;
color: #3CC7C0;
display: flex;
@ -277,12 +353,10 @@
padding-top: 30rpx;
.list {
margin: 8rpx 30rpx 0;
margin: 8rpx 0rpx 0;
.cell {
padding: 22rpx 0;
display: flex;
border-bottom: 2rpx solid #f3f4f6;
padding: 22rpx 30rpx;
border-bottom: 2rpx solid #f3f4f6;
.circle {
margin-top: 15rpx;

View File

@ -43,7 +43,7 @@
</view>
<view class="time">
<up-icon name="clock" color="#6B7280" size="28rpx"></up-icon>
<view class="num">{{formatDay(info.updated_at)}}</view>
<view class="num">{{ formatDay(info.updated_at) }}</view>
</view>
</view>
</view>
@ -111,7 +111,7 @@
</view>
</view>
</template>
<view class="desc">
<view class="videobox" v-if="type == 'video'">
<polyv-player
@ -136,7 +136,7 @@
></up--image>
</view>
<view class="num">全部评论{{total}}</view>
<view class="num">全部评论{{ total }}</view>
</view>
<view class="commentcon">
<view
@ -154,12 +154,31 @@
<view class="info">
<view class="user">
<view class="name">{{ item.user_name }}</view>
<view class="dot" @click="alertDeal(item.comment_id,item.comment_id,item.is_author,item.user_name,item.is_top,2)">...</view>
<view
class="dot"
@click="
alertDeal(
item.comment_id,
item.comment_id,
item.is_author,
item.user_name,
item.is_top,
2
)
"
>...</view
>
</view>
<view class="question">{{ item.content }}</view>
<view class="commentImg">
<up-image src="https://cdn.uviewui.com/uview/album/1.jpg" radius="16rpx" width="150rpx" height="150rpx"></up-image>
</view>
<view class="commentImg" v-if="item.comment_image">
<up-image
:src="(item.comment_image)"
radius="16rpx"
width="150rpx"
height="150rpx"
@click="previewImg(item.comment_image)"
></up-image>
</view>
<view class="date">{{ formatDate(item.created_at) }}</view>
<view
class="commentcon"
@ -167,7 +186,7 @@
>
<view
class="item"
v-for="(cell, index) in item.sub_comment.slice(0,3)"
v-for="(cell, index) in item.sub_comment.slice(0, 3)"
:key="cell.comment_id"
style="padding-left: 0"
>
@ -181,30 +200,53 @@
<view class="info">
<view class="user">
<view class="name">{{ cell.user_name }}</view>
<view class="dot" @click="alertDeal(cell.comment_id,cell.root_id,cell.is_author,cell.user_name,cell.is_top,3)">...</view>
<view
class="dot"
@click="
alertDeal(
cell.comment_id,
cell.root_id,
cell.is_author,
cell.user_name,
cell.is_top,
3
)
"
>...</view
>
</view>
<view class="question" v-html="formatHtml(cell.content )"></view>
<view class="commentImg">
<up-image src="https://cdn.uviewui.com/uview/album/1.jpg" radius="16rpx" width="150rpx" height="150rpx"></up-image>
<view
class="question"
v-html="formatHtml(cell.content)"
></view>
<view class="commentImg" v-if="cell.comment_image">
<up-image
:src="(cell.comment_image)"
radius="16rpx"
width="150rpx"
height="150rpx"
@click="previewImg(cell.comment_image)"
></up-image>
</view>
<view class="date">{{ formatDate(cell.created_at) }}</view>
</view>
</view>
</view>
<view class="expand" @click="openMorePop(item,item.sub_comment,index)" v-if="item.sub_comment.length > 3"
<view
class="expand"
@click="openMorePop(item, item.sub_comment, index)"
v-if="item.sub_comment.length > 3"
>展开更多回复</view
>
</view>
</view>
</view>
</view>
</z-paging>
<!-- 评论框 -->
<up-popup
:zIndex="99"
:overlayStyle="{ zIndex:98 }"
:overlayStyle="{ zIndex: 98 }"
:closeOnClickOverlay="false"
:show="showCommentDialog"
:round="10"
@ -221,37 +263,47 @@
:placeholder="placeholder"
></up--textarea>
</view>
<view class="imgbox">
<view class="imgbox" v-if="imgList.length>0">
<view class="imgunit">
<up--image
:src="shangImg"
:src="imgList[0]"
radius="6"
width="150rpx"
height="150rpx"
@click="previewImg"
@click="previewImg(imgList[0])"
></up--image>
<view class="close">
<view class="close" @click="delImg">
<up-icon name="close-circle" color="#666" size="16"></up-icon>
</view>
</view>
</view>
<view class="sendbox">
<view class="left"
><up--image
:src="uploadImg"
mode="widthFix"
<view class="left">
<up-upload
:show-upload-list="false"
@afterRead="afterRead"
name="imgupload"
multiple
:maxCount="1"
width="40rpx"
height="77rpx"
@click="chooseImg"
></up--image
></view>
>
<up--image
:src="uploadImg"
mode="widthFix"
width="40rpx"
height="77rpx"
></up--image>
</up-upload>
</view>
<view class="btn" @click="sendComment">发送</view>
</view>
</up-popup>
<!-- 底部操作 -->
<up-popup
:zIndex="60"
:overlayStyle="{ zIndex:59 }"
:overlayStyle="{ zIndex: 59 }"
:closeOnClickOverlay="false"
:show="showDeal"
:round="10"
@ -260,7 +312,9 @@
@open="openDeal"
>
<view class="dealbox">
<view class="dealcell" @click="toggleTop" v-if="level==2">{{is_top?'取消置顶':'置顶'}}</view>
<view class="dealcell" @click="toggleTop" v-if="level == 2">{{
is_top ? "取消置顶" : "置顶"
}}</view>
<view class="dealcell" @click="openCommentDialog">回复</view>
<view class="dealcell" v-if="is_author" @click="delComment">删除</view>
<view class="bar"></view>
@ -298,13 +352,34 @@
<view class="info">
<view class="user">
<view class="name">{{ mainCommentObj.user_name }}</view>
<view class="dot" @click="alertDeal(mainCommentObj.comment_id,mainCommentObj.comment_id,mainCommentObj.is_author,mainCommentObj.user_name,mainCommentObj.is_top,2)">...</view>
<view
class="dot"
@click="
alertDeal(
mainCommentObj.comment_id,
mainCommentObj.comment_id,
mainCommentObj.is_author,
mainCommentObj.user_name,
mainCommentObj.is_top,
2
)
"
>...</view
>
</view>
<view class="question" >{{ mainCommentObj.content}}</view>
<view class="commentImg">
<up-image src="https://cdn.uviewui.com/uview/album/1.jpg" radius="16rpx" width="150rpx" height="150rpx"></up-image>
</view>
<view class="date">{{formatDate(mainCommentObj.created_at) }}</view>
<view class="question">{{ mainCommentObj.content }}</view>
<view class="commentImg" v-if="mainCommentObj.comment_image">
<up-image
:src="mainCommentObj.comment_image"
radius="16rpx"
width="150rpx"
height="150rpx"
@click="previewImg(mainCommentObj.comment_image)"
></up-image>
</view>
<view class="date">{{
formatDate(mainCommentObj.created_at)
}}</view>
</view>
</view>
</view>
@ -312,7 +387,8 @@
<view
class="item"
v-for="(cell, index) in childList"
:key="cell.comment_id">
:key="cell.comment_id"
>
<up--image
:src="headImg"
class="headImg"
@ -323,9 +399,31 @@
<view class="info">
<view class="user">
<view class="name">{{ cell.user_name }}</view>
<view class="dot" @click="alertDeal(cell.comment_id,cell.root_id,cell.is_author,cell.user_name,cell.is_top,3)">...</view>
<view
class="dot"
@click="
alertDeal(
cell.comment_id,
cell.root_id,
cell.is_author,
cell.user_name,
cell.is_top,
3
)
"
>...</view
>
</view>
<view class="question" v-html="formatHtml(cell.content)"></view>
<view class="commentImg" v-if="cell.comment_image">
<up-image
:src="cell.comment_image"
radius="16rpx"
width="150rpx"
height="150rpx"
@click="previewImg(cell.comment_image)"
></up-image>
</view>
<view class="date">{{ formatDate(cell.created_at) }}</view>
</view>
</view>
@ -333,10 +431,9 @@
</view>
<view class="bottom" @click="showReplyPop">
<up-input
readonly
:placeholder="'@'+mainCommentObj.user_name+''"
readonly
:placeholder="'@' + mainCommentObj.user_name + ''"
border="surround"
v-model="value"
></up-input>
</view>
@ -362,23 +459,21 @@
<view class="add">+</view>
</view>
<view class="btnbox">
<view class="cancle" @click="showGive=false">取消</view>
<view class="cancle" @click="showGive = false">取消</view>
<view class="ok" @click="confirmGive">确定</view>
</view>
</view>
</view>
</up-overlay>
<up-overlay :show="showModal" mask-click-able>
<up-overlay :show="showModal" mask-click-able>
<view class="zanboxpop">
<view class="zanwraper">
<view class="title">提示</view>
<view class="content">
是否删除该评论
</view>
<view class="content"> 是否删除该评论 </view>
<view class="btnbox">
<view class="cancle" @click="showModal=false">取消</view>
<view class="cancle" @click="showModal = false">取消</view>
<view class="ok" @click="confirmDel">确定</view>
</view>
</view>
@ -387,7 +482,7 @@
</template>
<script setup>
import {reactive, ref } from "vue";
import { reactive, ref } from "vue";
import headImg from "@/static/headImg.png";
import collectonImg from "@/static/collectOn.png";
import collectImg from "@/static/collect.png";
@ -403,7 +498,7 @@ import dayjs from "dayjs";
const paging = ref(null);
const dataList = ref([]);
const total = ref(0);
const imgList = ref([]);
const showCanvas = ref(false);
const showCommentDialog = ref(false);
const canvasWidth = ref(0);
@ -419,30 +514,29 @@ const id = ref("");
const parent_id = ref(null);
const root_id = ref(null);
const is_author = ref(false);
const reply_name=ref('');
const level=ref(1);
const placeholder=ref("请输入评论内容");
const mainCommentObj=reactive({});
const childList=ref([]);
const clickIndex=ref(0);
const is_top=ref(false);
const reply_name = ref("");
const level = ref(1);
const placeholder = ref("请输入评论内容");
const mainCommentObj = reactive({});
const childList = ref([]);
const clickIndex = ref(0);
const is_top = ref(false);
const confirmGive = () => {
showGive.value = false;
showGive.value = false;
};
const formatDay = (date) => {
return dayjs(date).format("YYYY-MM-DD");
};
const formatDay=(date)=>{
return dayjs(date).format('YYYY-MM-DD')
}
const formatDate = (date) => {
return dayjs(date).format("YYYY-MM-DD HH:mm");
};
const openMorePop=(obj,list,index)=>{
showMore.value=true;
childList.value=list;
Object.assign(mainCommentObj,obj);
clickIndex.value=index;
}
const openMorePop = (obj, list, index) => {
showMore.value = true;
childList.value = list;
Object.assign(mainCommentObj, obj);
clickIndex.value = index;
};
const getArticleDetail = (id) => {
api.getArticleDetail(id).then((res) => {
let result = res.data.data;
@ -464,48 +558,45 @@ onLoad((options) => {
getVideoDetail(options.id);
}
});
const clearComment=()=>{
parent_id.value=null;
content.value="";
root_id.value=null;
is_author.value=false;
reply_name.value="";
level.value=1;
}
const closeDealPop=()=>{
showDeal.value=false;
clearComment();
}
const showReplyPop=()=>{
parent_id.value=mainCommentObj.comment_id;
root_id.value=mainCommentObj.comment_id;
is_author.value=mainCommentObj.is_author==1?true:false;
reply_name.value=mainCommentObj.user_name;
level.value=2;
if(level.value==2 || level.value==3){
placeholder.value="回复"+reply_name.value+"";
}
showCommentDialog.value=true;
const clearComment = () => {
parent_id.value = null;
imgList.value = [];
content.value = "";
root_id.value = null;
is_author.value = false;
reply_name.value = "";
level.value = 1;
};
const alertDeal=(parentId,rootId,isAuthor,name,top,commentLevel)=>{
parent_id.value=parentId;
root_id.value=rootId;
is_author.value=isAuthor==1?true:false;
reply_name.value=name;
level.value=commentLevel;
is_top.value=top==1?true:false;
if(level.value==2 || level.value==3){
placeholder.value="回复"+name+"";
const closeDealPop = () => {
showDeal.value = false;
clearComment();
};
const showReplyPop = () => {
parent_id.value = mainCommentObj.comment_id;
root_id.value = mainCommentObj.comment_id;
is_author.value = mainCommentObj.is_author == 1 ? true : false;
reply_name.value = mainCommentObj.user_name;
level.value = 2;
if (level.value == 2 || level.value == 3) {
placeholder.value = "回复" + reply_name.value + "";
}
showDeal.value=true;
showCommentDialog.value = true;
};
const alertDeal = (parentId, rootId, isAuthor, name, top, commentLevel) => {
parent_id.value = parentId;
root_id.value = rootId;
is_author.value = isAuthor == 1 ? true : false;
reply_name.value = name;
level.value = commentLevel;
is_top.value = top == 1 ? true : false;
if (level.value == 2 || level.value == 3) {
placeholder.value = "回复" + name + "";
}
showDeal.value = true;
};
const openCommentDialog = () => {
showCommentDialog.value = true;
showDeal.value = false;
showDeal.value = false;
};
const queryList = (pageNo, pageSize) => {
const params = {
@ -526,13 +617,17 @@ const getArticleComment = (params) => {
...params,
})
.then((res) => {
paging.value.complete(res.data.data.data);
total.value= res.data.data.total;
setTimeout(()=>{
if(showMore.value){
openMorePop(mainCommentObj,(dataList.value[clickIndex.value]).sub_comment,clickIndex.value)
}
},1500)
paging.value.complete(res.data.data.data);
total.value = res.data.data.total;
setTimeout(() => {
if (showMore.value) {
openMorePop(
mainCommentObj,
dataList.value[clickIndex.value].sub_comment,
clickIndex.value
);
}
}, 1500);
})
.catch((res) => {
paging.value.complete(false);
@ -545,12 +640,16 @@ const getVideoComment = (params) => {
})
.then((res) => {
paging.value.complete(res.data.data.data);
total.value= res.data.data.total;
setTimeout(()=>{
if(showMore.value){
openMorePop(mainCommentObj,(dataList.value[clickIndex.value]).sub_comment,clickIndex.value)
}
},1500)
total.value = res.data.data.total;
setTimeout(() => {
if (showMore.value) {
openMorePop(
mainCommentObj,
dataList.value[clickIndex.value].sub_comment,
clickIndex.value
);
}
}, 1500);
})
.catch((res) => {
paging.value.complete(false);
@ -580,10 +679,10 @@ const openMore = () => {
const closeMore = () => {
showMore.value = false;
};
const previewImg = () => {
const previewImg = (url) => {
uni.previewImage({
current: "https://example.com/image1.jpg",
urls: ["https://example.com/image1.jpg", "https://example.com/image2.jpg"],
current: url,
urls: [url],
});
};
@ -879,10 +978,85 @@ const chooseImg = () => {
sourceType: ["album", "camera "], //
success: function (res) {
console.log(333);
readImages(res.tempFilePaths);
uni.getFileSystemManager({
filePath: res.tempFilePaths[0], //
success: (res) => {
console.log(res); // res.fileFile
// 使File
},
fail: (err) => {
console.error("获取文件信息失败", err);
},
});
console.log(res.tempFilePaths);
//readImages(res.tempFilePaths);
},
});
};
const handleUpload = (file) => {
let File = file.file;
//
api
.getOss({
scene: 1,
})
.then((rep) => {
let result = rep.data;
if (result.code == 200) {
let { access_id, dir, policy, signature, host } = result.data;
let time = dayjs().format("YYYYMMDDHHmmss");
let random = generateRandomNumber();
let filename = time + random;
let imgType ="."+getImageFormat(File[0].url);
return new Promise((resolve, reject) => {
uni.uploadFile({
url: host, //
filePath: File[0].url,
name: "file",
formData: {
OSSAccessKeyId: access_id,
policy,
key: dir + time + random + imgType,
signature,
},
success(res) {
if (res.statusCode === 204) {
let url = host + "/" + dir + filename + imgType;
console.log(url);
imgList.value=[url]
}
},
fail: (err) => {
console.log(err);
},
});
});
}
});
};
const generateRandomNumber = () => {
let randomNumber = Math.floor(1000 + Math.random() * 9000);
return randomNumber;
};
const getImageFormat=(imageUrl)=>{
const lastDotIndex = imageUrl.lastIndexOf('.');
if (lastDotIndex !== -1) {
return imageUrl.substring(lastDotIndex + 1);
}
return 'unknown';
};
const afterRead = (file, lists, name) => {
console.log(lists);
console.log(name);
handleUpload(file);
};
const delImg = (index) => {
imgList.value=[];
};
const collectArticle = (id) => {
api.collectArticle(id).then((res) => {
uni.showToast({
@ -934,8 +1108,7 @@ const addArticleComment = (id, data) => {
});
clearComment();
showCommentDialog.value = false;
paging.value.refresh();
paging.value.refresh();
});
};
const addVideoComment = (id, data) => {
@ -944,10 +1117,9 @@ const addVideoComment = (id, data) => {
icon: "none",
title: "评论成功",
});
clearComment()
clearComment();
showCommentDialog.value = false;
paging.value.refresh();
});
};
const delArticleComment = (id) => {
@ -957,7 +1129,6 @@ const delArticleComment = (id) => {
title: "删除成功",
});
paging.value.refresh();
});
};
const delVideoComment = (id) => {
@ -967,7 +1138,6 @@ const delVideoComment = (id) => {
title: "删除成功",
});
paging.value.refresh();
});
};
const topArticleComment = (id) => {
@ -978,7 +1148,7 @@ const topArticleComment = (id) => {
});
});
showDeal.value = false;
paging.value.refresh();
paging.value.refresh();
};
const topVideoComment = (id) => {
api.topVideoComment(id).then((res) => {
@ -987,8 +1157,8 @@ const topVideoComment = (id) => {
title: "置顶成功",
});
});
showDeal.value = false;
paging.value.refresh();
showDeal.value = false;
paging.value.refresh();
};
const cancelTopArticleComment = (id) => {
api.cancelTopArticleComment(id).then((res) => {
@ -997,8 +1167,8 @@ const cancelTopArticleComment = (id) => {
title: "取消置顶成功",
});
});
showDeal.value = false;
paging.value.refresh();
showDeal.value = false;
paging.value.refresh();
};
const cancelTopVideoComment = (id) => {
api.cancelTopArticleComment(id).then((res) => {
@ -1007,59 +1177,71 @@ const cancelTopVideoComment = (id) => {
title: "取消置顶成功",
});
});
showDeal.value = false;
paging.value.refresh();
showDeal.value = false;
paging.value.refresh();
};
const delComment=()=>{
showModal.value=true;
showDeal.value=false;
}
const confirmDel=()=>{
if(type.value=='article'){
delArticleComment(parent_id.value)
}else{
delVideoComment(parent_id.value)
const delComment = () => {
showModal.value = true;
showDeal.value = false;
};
const confirmDel = () => {
if (type.value == "article") {
delArticleComment(parent_id.value);
} else {
delVideoComment(parent_id.value);
}
showModal.value=false;
}
showModal.value = false;
};
const toggleTop=()=>{
if(type.value=='article'){
is_top.value?cancelTopArticleComment(parent_id.value):topArticleComment(parent_id.value)
}else{
is_top.value?cancelTopVideoComment(parent_id.value):topVideoComment(parent_id.value)
const toggleTop = () => {
if (type.value == "article") {
is_top.value
? cancelTopArticleComment(parent_id.value)
: topArticleComment(parent_id.value);
} else {
is_top.value
? cancelTopVideoComment(parent_id.value)
: topVideoComment(parent_id.value);
}
}
const sendComment=()=>{
if(!content.value) {
};
const sendComment = () => {
if (!content.value) {
uni.showToast({
icon: "none",
title: "请输入评论内容",
});
return false;
}
const postData={
content:level.value==3?'回复'+reply_name.value+''+content.value:content.value
const postData = {
content:
level.value == 3
? "回复" + reply_name.value + "" + content.value
: content.value,
};
if(imgList.value.length>0){
postData.comment_image = imgList.value[0]
}
if(parent_id.value !==null){
postData.parent_id=parent_id.value;
if (parent_id.value !== null) {
postData.parent_id = parent_id.value;
}
if(root_id.value!==null){
postData.root_id=root_id.value;
if (root_id.value !== null) {
postData.root_id = root_id.value;
}
if(type.value=='article'){
addArticleComment(id.value,postData)
}else{
addVideoComment(id.value,postData)
if (type.value == "article") {
addArticleComment(id.value, postData);
} else {
addVideoComment(id.value, postData);
}
}
const formatHtml=(val)=>{
if(/^回复.+/.test(val)){
return val.replace(/[^回复]([^]+)/,`<font style="color:#3CC7C0">$&</font>`)
};
return val
}
};
const formatHtml = (val) => {
if (/^回复.+/.test(val)) {
return val.replace(
/[^回复]([^]+)/,
`<font style="color:#3CC7C0">$&</font>`
);
}
return val;
};
</script>
<style lang='scss' scoped>
@ -1081,10 +1263,10 @@ const formatHtml=(val)=>{
font-size: 36rpx;
color: rgba(0, 0, 0, 0.85);
}
.content{
padding:30rpx 0 ;
background: #f5f6f9;
text-align: center;
.content {
padding: 30rpx 0;
background: #f5f6f9;
text-align: center;
}
.count {
margin-top: 24rpx;
@ -1142,14 +1324,14 @@ const formatHtml=(val)=>{
}
:deep(.u-input__content__field-wrapper__field) {
height: 60rpx;
font-size: 34rpx!important;
text-align: center!important;
font-size: 34rpx !important;
text-align: center !important;
}
:deep(.u-input) {
background: #f2f2f2;
width: 200rpx!important;
flex:none;
width: 200rpx !important;
flex: none;
}
:deep(.u-input--radius) {
border-radius: 24rrpx;
@ -1173,11 +1355,11 @@ const formatHtml=(val)=>{
justify-content: center;
align-items: center;
}
.ok{
color:#fff;
.ok {
color: #fff;
width: 256rpx;
height: 88rpx;
background: #3cc7c0;
background: #3cc7c0;
border-radius: 25px;
border: 2rpx solid #3cc7c0;
font-weight: 500;
@ -1280,7 +1462,7 @@ const formatHtml=(val)=>{
word-wrap: break-word;
word-break: break-all;
}
.commentImg{
.commentImg {
margin-top: 16rpx;
}
.date {

View File

@ -140,7 +140,7 @@ const goHospital=(id,name)=>{
}
const mySpecial=()=>{
uni.navigateTo({
url:'/pages/specialList/specialList'
url:'/pages/specialList/specialList?userId='+userInfo.user_id
})
}
const goJoin=()=>{

View File

@ -9,7 +9,7 @@
@query="queryList"
>
<template #top>
<navBarSearch :searchWord="keyWord" :navName="navName"></navBarSearch>
<backLogoNav :searchWord="keyWord" :navName="navName"></backLogoNav>
<view class="tabcon">
<up-tabs
:activeStyle="{
@ -30,22 +30,22 @@
class="item"
v-for="(item, index) in dataList"
:key="index"
@click="isArticle ? goDetail(item.article_id) : goDetail(item.video_id)"
>
<view class="title ellipsis">{{
isArticle ? item.article_title : item.video_title
}}</view>
<view class="title">{{item.content}}</view>
<view class="deal">
<view class="time">
<up-icon name="clock" color="#6B7280" size="28rpx"></up-icon>
<view class="num">{{ formatdate(item.push_date) }}</view>
<view class="num">{{ formatdate(item.created_at) }}</view>
</view>
<view class="dot">...</view>
<view class="dot" @click="isDel(item.comment_id)">...</view>
</view>
<view class="casecontent">
<view class="author">段钟平(首都医科大学附属北京佑安医院教授</view>
<view class="content">肝胆相照临床病例库肝胆相照临床病例库肝胆相照临床病例库肝胆相照临床病例库</view>
<view class="author" v-if="tab==0">{{item.author_name}}({{item.author_hospital_name}})</view>
<view class="content" v-if="tab==0">{{ item.exchange_title }}</view>
<view class="content" v-else-if="tab==1">{{ item.article_title }}</view>
<view class="content" v-else-if="tab==2">{{ item.video_title }}</view>
</view>
</view>
</z-paging>
@ -62,17 +62,32 @@
@open="openDeal"
>
<view class="dealbox">
<view class="dealcell">收藏</view>
<view class="dealcell">删除</view>
<!-- <view class="dealcell">收藏</view> -->
<view class="dealcell" @click="alertPop">删除</view>
<view class="bar"></view>
<view class="dealcell" @click="closeDeal">取消</view>
</view>
</up-popup>
<up-overlay :show="showModal" mask-click-able>
<view class="zanboxpop">
<view class="zanwraper">
<view class="title">提示</view>
<view class="content">
是否删除该评论
</view>
<view class="btnbox">
<view class="cancle" @click="showModal=false">取消</view>
<view class="ok" @click="confirmDel">确定</view>
</view>
</view>
</view>
</up-overlay>
</template>
<script setup>
import { ref, reactive } from "vue";
import navBarSearch from "@/components/navBarSearch/navBarSearch.vue";
import backLogoNav from "@/components/backLogoNav/backLogoNav.vue";
import list from "@/uni_modules/z-paging/components/z-paging/z-paging";
import api from "@/api/api";
import { onLoad } from "@dcloudio/uni-app";
@ -83,23 +98,40 @@ const paging = ref(null);
const uDropdownRef = ref(null);
const dataList = ref([]);
const total = ref(0);
const value = ref("");
const delId = ref("");
const keyWord = ref("");
const page = ref(1);
const isArticle = ref(true);
const hospital_id = ref("");
const hospital_name = ref("");
const doctor_id = ref("");
const doctor_name = ref("");
const numInfo = reactive({});
const navName = ref("肝胆相照临床病例库");
const showDeal = ref(true);
const showDeal = ref(false);
const showModal = ref(false);
const tab=ref(0);
const closeDeal=()=>{
showDeal.value = false;
};
const alertPop=()=>{
showModal.value = true;
showDeal.value = false;
};
const confirmDel=()=>{
if(tab.value==0){
delExchangeComment(delId.value);
}else if(tab.value==1){
delArticleComment(delId.value);
}else if(tab.value==2){
delVideoComment(delId.value);
}
showModal.value = false;
};
const openDeal=()=>{
showDeal.value = true;
};
const isDel=(id)=>{
delId.value=id;
showDeal.value = true;
};
const options = ref([
{
label: "正序",
@ -121,104 +153,58 @@ const tabList = ref([
name: "视频病例库",
},
]);
const order = reactive({
read_num: "",
push_date: "",
});
const switchTab = (index) => {
console.log("item", index);
const delArticleComment = (id) => {
api.delArticleComment(id).then((res) => {
uni.showToast({
icon: "none",
title: "删除成功",
});
paging.value.refresh();
});
};
onLoad((options) => {
if (options.keyWord) {
keyWord.value = options.keyWord;
}
if (options.order == "new") {
order.push_date = "asc";
}
if (options.order == "read") {
order.read_num = "desc";
}
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 + "临床病例库";
getStaticDoctor(hospital_id.value);
}
});
const change = (e) => {
const delVideoComment = (id) => {
api.delVideoComment(id).then((res) => {
uni.showToast({
icon: "none",
title: "删除成功",
});
paging.value.refresh();
});
};
const delExchangeComment = (id) => {
api.delExchangeComment(id).then((res) => {
uni.showToast({
icon: "none",
title: "删除成功",
});
paging.value.refresh();
});
};
const switchTab = (item) => {
tab.value=item.index;
paging.value.reload();
};
onLoad((options) => {
});
const formatdate = (date) => {
return dayjs(date).format("YYYY-MM-DD");
};
const goDetail = (id) => {
console.log(11111);
console.log(id);
let type = isArticle.value ? "article" : "video";
uni.navigateTo({
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,
doctor_id: doctor_id.value,
hospital_id: hospital_id.value,
};
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;
})
.catch((err) => {
paging.value.complete(false);
});
};
const searchVideo = async (params) => {
let searchForm = {
keyword: keyWord.value,
};
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({
const getExchangeCommentUser = async (params) => {
api.getExchangeCommentUser({
...params,
})
.then((res) => {
@ -229,30 +215,175 @@ const searchVideo = async (params) => {
paging.value.complete(false);
});
};
const getStaticDoctor = (id) => {
api.getStaticDoctor(id).then((res) => {
let result = res.data.data;
Object.assign(numInfo, result);
});
const getArticleCommentUser = async (params) => {
api.getArticleCommentUser({
...params,
})
.then((res) => {
paging.value.complete(res.data.data.data);
total.value = res.data.data.total;
})
.catch((err) => {
paging.value.complete(false);
});
};
const getStaticHospital = (id) => {
api.getStaticHospital(id).then((res) => {
let result = res.data.data;
Object.assign(numInfo, result);
});
const getVideoCommentUser = async (params) => {
api.getVideoCommentUser({
...params,
})
.then((res) => {
paging.value.complete(res.data.data.data);
total.value = res.data.data.total;
})
.catch((err) => {
paging.value.complete(false);
});
};
const queryList = (pageNo, pageSize) => {
console.log(666666);
const params = {
page: pageNo,
page_size: pageSize,
};
isArticle.value ? searchArticle(params) : searchVideo(params);
if(tab.value==0){
getExchangeCommentUser(params);
}else if(tab.value==1){
getArticleCommentUser(params);
}else{
getVideoCommentUser(params);
}
};
</script>
<style lang="scss" scoped>
.zanboxpop {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
.zanwraper {
width: 630rpx;
margin: 0 auto;
padding-bottom: 50rpx;
background: #f5f6f9;
border-radius: 16rpx;
.title {
margin-top: 48rpx;
text-align: center;
font-weight: 500;
font-size: 36rpx;
color: rgba(0, 0, 0, 0.85);
}
.content{
padding:30rpx 0 ;
background: #f5f6f9;
text-align: center;
}
.count {
margin-top: 24rpx;
display: flex;
align-items: center;
text-align: center;
justify-content: center;
font-weight: 400;
font-size: 28rpx;
color: rgba(0, 0, 0, 0.65);
.num {
color: #ff0000;
font-size: 32rpx;
}
.earn {
font-size: 32rpx;
color: #3cc7c0;
}
}
.countbox {
display: flex;
width: 100%;
margin: 30rpx 0px 40rpx;
padding: 0 40rpx;
justify-content: center;
box-sizing: border-box;
.minus {
flex-shrink: 0;
margin-left: 10rp;
width: 90rpx;
height: 90rpx;
font-size: 60rpx;
color: #333;
display: flex;
justify-content: center;
align-items: center;
background: #ffffff;
border-radius: 12rpx;
border: 2rpx solid #e9e9e9;
}
.add {
flex-shrink: 0;
width: 90rpx;
margin-left: 10rpx;
height: 90rpx;
font-size: 60rpx;
color: #333;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
background: #3cc7c0;
border-radius: 12rpx;
border: 2rpx solid #3cc7c0;
}
:deep(.u-input__content__field-wrapper__field) {
height: 60rpx;
font-size: 34rpx!important;
text-align: center!important;
}
:deep(.u-input) {
background: #f2f2f2;
width: 200rpx!important;
flex:none;
}
:deep(.u-input--radius) {
border-radius: 24rrpx;
}
}
.btnbox {
margin: 0px 40rpx 0px;
display: flex;
justify-content: space-between;
.cancle {
color: rgba(0, 0, 0, 0.3);
width: 256rpx;
height: 88rpx;
background: #f5f6f9;
border-radius: 25px;
border: 2rpx solid rgba(0, 0, 0, 0.15);
font-weight: 500;
font-size: 32rpx;
color: rgba(0, 0, 0, 0.85);
display: flex;
justify-content: center;
align-items: center;
}
.ok{
color:#fff;
width: 256rpx;
height: 88rpx;
background: #3cc7c0;
border-radius: 25px;
border: 2rpx solid #3cc7c0;
font-weight: 500;
font-size: 32rpx;
display: flex;
justify-content: center;
align-items: center;
}
}
}
}
.bar {
width: 100%;
background: #f9fafb;
@ -270,7 +401,7 @@ const queryList = (pageNo, pageSize) => {
}
}
.tabcon {
margin: 0 20rpx;
margin: -20rpx 20rpx 0;
}
.databox {
height: 162rpx;

View File

@ -17,74 +17,18 @@
</view>
</view>
<view class="textcon">
<view class="textcell">
<view class="title">患者信息</view>
<view class="iptbox">
<up--textarea
maxlength="-1"
autoHeight
v-model="form.title"
placeholder="请输入患者信息"
></up--textarea>
</view>
</view>
<view class="textcell">
<view class="title">主诉</view>
<view class="iptbox">
<up--textarea
maxlength="-1"
autoHeight
v-model="form.title"
placeholder="请输入主诉"
></up--textarea>
</view>
</view>
<view class="textcell">
<view class="title">现病史及既往史</view>
<view class="iptbox">
<up--textarea
maxlength="-1"
autoHeight
v-model="form.title"
placeholder="请输入现病史及既往史"
></up--textarea>
</view>
</view>
<view class="textcell">
<view class="title">检查</view>
<view class="iptbox">
<up--textarea
maxlength="-1"
autoHeight
v-model="form.title"
placeholder="请输入检查内容"
></up--textarea>
</view>
</view>
<view class="textcell">
<view class="title">临床诊断</view>
<view class="iptbox">
<up--textarea
maxlength="-1"
autoHeight
v-model="form.title"
placeholder="请输入临床诊断"
></up--textarea>
</view>
</view>
<view class="textcell">
<view class="title">治疗经过及结果</view>
<view class="iptbox">
<up--textarea
maxlength="-1"
autoHeight
v-model="form.title"
placeholder="请输入治疗经过及结果"
></up--textarea>
</view>
</view>
<editor
id="editor"
placeholder="写点什么吧~~"
show-img-resize
show-img-toolbar
show-img-size
@ready="onEditorReady"
@focus="OnFocus"
@statuschange="statuschange"
></editor>
</view>
<view class="textcon">
<view class="textcon" style="border: none;">
<view class="row">
<view class="left">
总结与讨论 <text class="tip">(可不填)</text>
@ -101,7 +45,7 @@
</view>
</view>
</view>
<view class="textcon">
<view class="textcon" >
<view class="sickbox">
<view class="sick">
治疗经过及结果
@ -114,87 +58,8 @@
添加疾病
</view>
</view>
<view class="toolbox">
<view class="cell">
<u-upload
:fileList="imgList"
@afterRead="afterRead"
@delete="deletePic"
name="imgupload"
multiple
:maxCount="1"
width="32rpx"
height="32rpx"
>
<view class="cell">
<up--image
:src="photoImg"
class="headImg"
width="32rpx"
height="32rpx"
></up--image>
<view class="name">添加图片</view>
</view>
</u-upload>
</view>
<view class="cell">
<u-upload
:fileList="videoList"
@afterRead="afterRead"
accept="video"
name="videoupload"
multiple
maxDuration="3600"
:maxCount="1"
width="32rpx"
height="32rpx"
>
<view class="cell">
<up--image
:src="videoImg"
class="headImg"
width="32rpx"
height="32rpx"
></up--image>
<view class="name">添加视频</view>
</view>
</u-upload>
</view>
<view class="cell">
<up--image
:src="addImg"
class="headImg"
width="32rpx"
height="32rpx"
></up--image>
<view class="name">添加小标题</view>
</view>
</view>
<view class="imgbox">
<view class="imgunit">
<up--image
src="https://cdn.uviewui.com/uview/album/1.jpg"
radius="6"
width="150rpx"
height="150rpx"
@click="previewImg"
></up--image>
<view class="close">
<up-icon name="close-circle" color="#666" size="18"></up-icon>
</view>
</view>
</view>
<view class="imgbox">
<view class="close">
<up-icon name="close-circle" color="red" size="30"></up-icon>
</view>
<video
class="myVideo"
src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4"
@error="videoErrorCallback"
controls
></video>
</view>
<view class="textcell" v-if="showMinTitle">
<view class="titlebox">
<view class="title">小标题</view>
@ -218,7 +83,42 @@
</view>
</view>
<view class="bottom">
<view class="left">
<view class="toolbox">
<view class="cell">
<view class="cell">
<up--image
:src="photoImg"
class="headImg"
width="32rpx"
height="32rpx"
@click="insertImage"
></up--image>
<view class="name">添加图片</view>
</view>
</view>
<view class="cell">
<view class="cell">
<up--image
:src="videoImg"
class="headImg"
width="32rpx"
height="32rpx"
></up--image>
<view class="name">添加视频</view>
</view>
</view>
<view class="cell">
<up--image
:src="addImg"
class="headImg"
width="32rpx"
height="32rpx"
></up--image>
<view class="name">添加小标题</view>
</view>
</view>
<view class="bottombtn">
<view class="left">
<view class="draft">存草稿</view>
<view class="vote">
投票
@ -231,6 +131,7 @@
</view>
</view>
<view class="right">发布</view>
</view>
</view>
<up-popup
@ -345,7 +246,6 @@
</up-popup>
</div>
</template>
<script setup>
import { reactive, ref } from "vue";
import backNav from "@/components/backNav/backNav";
@ -353,14 +253,42 @@ import photoImg from "@/static/photo.png";
import addImg from "@/static/add.png";
import videoImg from "@/static/videoicon.png";
import voteImg from "@/static/vote.png";
import api from "@/api/api";
import dayjs from "dayjs";
import actionSheet from "uview-plus/components/u-action-sheet/actionSheet";
const form = reactive({
title: "",
exchange_title: "",
exchange_content:'',
exchange_summary:'',
case_exchange_vote:{
vote_title:'',
valid_day:null,
case_exchange_vote_option:[],
},
case_exchange_label:[],
case_exchange_img:[],
case_exchange_video:[]
});
const value = ref("");
const showVote = ref(false);
const showDraft = ref(true);
const showDraft = ref(false);
const showMinTitle = ref(false);
const draftList=ref([]);
const imgList = ref([]);
const videoList = ref([]);
const editorCtx = ref(null);
const onEditorReady=()=>{
uni.createSelectorQuery().select('#editor').context((res) => {
editorCtx.value = res.context;
editorCtx.value.setContents({
html:'<p>【患者信息】:</p><br/><br/><p>【主诉】:</p><br/><br/><p>【现病史及既往史】:</p><br/><br/><p>【检查】:</p><br/><br/><p>【临床诊断】:</p><br/><br/><p>【治疗经过及结果】:</p><br/><br/>'
});
}).exec()
}
const closeVote = () => {
showVote.value = false;
};
@ -376,7 +304,99 @@ const delTitle = () => {
const openDraft = () => {
showDraft.value = true;
};
const afterRead=(file) => {
const pFun=(files)=>{
let promiseFun = [];
for(let i=0;i<files.length;i++){
promiseFun.push(handleUpload(files[i]));
}
Promise.all(promiseFun).then((res)=>{
uni.showToast({
title: "图片上传成功",
icon: "none",
duration: 1000
})
})
}
const addExchange=()=>{
api.addExchange(form).then(res=>{
uni.showToast({
title: "发布成功",
icon: "none",
duration: 2000
})
})
};
const handleUpload = (file) => {
api.getOss({
scene: 1,
})
.then((rep) => {
let result = rep.data;
if (result.code == 200) {
let { access_id, dir, policy, signature, host } = result.data;
let time = dayjs().format("YYYYMMDDHHmmss");
let random = generateRandomNumber();
let filename = time + random;
let imgType ="."+getImageFormat(file);
return new Promise((resolve, reject) => {
uni.uploadFile({
url: host, //
filePath: file,
name: "file",
formData: {
OSSAccessKeyId: access_id,
policy,
key: dir + time + random + imgType,
signature,
},
success(res) {
if (res.statusCode === 204) {
let url = host + "/" + dir + filename + imgType;
editorCtx.value.insertImage({
src: url
});
//imgList.value=[url]
}
},
fail: (err) => {
console.log(err);
},
});
});
}
});
};
const generateRandomNumber = () => {
let randomNumber = Math.floor(1000 + Math.random() * 9000);
return randomNumber;
};
const getImageFormat=(imageUrl)=>{
const lastDotIndex = imageUrl.lastIndexOf('.');
if (lastDotIndex !== -1) {
return imageUrl.substring(lastDotIndex + 1);
}
return 'unknown';
};
const insertImage=(file) => {
uni.chooseImage({
count: 9, //9
sizeType: ['original', 'compressed'], //
sourceType: ['album'], //
extension:['jpg','png','jpeg'],
success: function (res) {
pFun(res.tempFilePaths)
}
});
}
const getList=()=>{
actionSheet.getDraftList().then(res=>{
draftList.value=res.data.data;
})
}
const previewImg = () => {
uni.previewImage({
@ -387,6 +407,10 @@ const previewImg = () => {
</script>
<style lang='scss' scoped>
#editor{
padding:0 30rpx;
height:calc(100vh - 600rpx);
}
.myVideo {
width: 100%;
border-radius: 15rpx;
@ -619,18 +643,39 @@ const previewImg = () => {
display: flex;
flex-direction: column;
height: 100vh;
:deep(.u-image) {
background: transparent !important;
}
}
.toolbox {
border-top: 2rpx solid #f3f4f6;
padding: 22rpx 30rpx;
display: flex;
align-items: center;
.cell {
margin-right: 20rpx;
display: flex;
align-items: center;
.name {
font-size: 25rpx;
margin-left: 4rpx;
color: #4b5563;
}
}
}
.bottom {
position: fixed;
bottom: 0;
border-top: 2rpx solid #e5e7eb;
width: 100%;
align-items: center;
z-index: 3;
height: 133rpx;
background: #ffffff;
display: flex;
.bottombtn{
display: flex;
align-items: center;
border-top: 2rpx solid #e5e7eb;
height: 133rpx;
}
.right {
margin-right: 30rpx;
@ -675,24 +720,8 @@ const previewImg = () => {
height: calc(100vh - 133rpx);
margin: -20rpx 0rpx 134rpx;
overflow-y: scroll;
:deep(.u-image) {
background: transparent !important;
}
.toolbox {
padding: 22rpx 30rpx;
display: flex;
align-items: center;
.cell {
margin-right: 20rpx;
display: flex;
align-items: center;
.name {
font-size: 25rpx;
margin-left: 4rpx;
color: #4b5563;
}
}
}
.sickbox {
display: flex;
padding: 25rpx 25rpx 0;

View File

@ -211,13 +211,33 @@ const searchVideo = async(params) => {
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 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,
});
}
})
}

View File

@ -49,7 +49,7 @@
</view>
</template>
<view class="listbox">
<view class="item" v-for="(item, index) in dataList" :key="index" @click="type=='hospital'?goDetail(item.basic_hospital.hospital_id):goDetail(item.case_clinical_doctor.doctor_id)">
<view class="item" v-for="(item, index) in dataList" :key="index" @click="type=='hospital'?goDetail(item.basic_hospital.hospital_id,item.basic_hospital.hospital_name):goDetail(item.case_clinical_doctor.doctor_id,item.case_clinical_doctor.doctor_name)">
<view class="title ellipsis" v-if="type=='hospital'">{{ item.basic_hospital.hospital_name}}</view>
<view class="title ellipsis" v-else>{{ item.case_clinical_doctor.doctor_name}}({{ item.case_clinical_doctor.hospital_name }})</view>
<view class="tagsbox">
@ -237,11 +237,22 @@ const queryList = (pageNo, pageSize) => {
};
type.value=='hospital'?searchHospital(params):searchDoctor(params)
};
const goDetail=(id)=>{
const goDetail=(id,name)=>{
let url=''
if(type.value=='doctor'){
url=`/pages/search/search?doctor_id=${id}&doctor_name=${name}`
}else{
url=`/pages/search/search?hospital_id=${id}&hospital_name=${name}`
}
uni.navigateTo({
url: `/pages/detail/detail?id=${id}&type=${type.value}`,
url:url,
});
}
/**
* 修改关键词并更新界面
*
* @param value 输入的关键词
*/
const changeWord=(value)=>{
console.log(value);
if(value){

View File

@ -8,96 +8,121 @@
v-model="dataList"
@query="queryList"
>
<template #top>
<navBarSearch :navName="'肝胆相照精选病例交流'"></navBarSearch>
<view class="bar"></view>
</template>
<view class="box">
<view class="bar"></view>
<view class="record">
<view class="list">
<view class="cell">
<view class="title">肝胆相照临床病例库肝胆相照临床病例库肝胆</view>
<view class="doctor">
<up--image
:src="headImg"
width="46rpx"
height="46rpx"
radius="50%"
></up--image>
<view class="name">陈XX首都医科大学附属北京**医院</view>
</view>
<view class="content"> 嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎XXXXX </view>
<view class="imgbox">
<view class="imgcell">
<template #top>
<navBarSearch
:navName="'肝胆相照精选病例交流'"
@changeWord="changeWord"
></navBarSearch>
<!-- <view class="bar"></view> -->
<view class="detail" v-if="total > 0 && showNum">
<view class="desc"
>检索到<text class="red">{{ total }}个病例</text></view
>
<view class="desc" v-if="keyWord"
>检索词<text class="red">{{ keyWord }}</text></view
>
</view>
</template>
<view class="box">
<!-- <view class="bar"></view> -->
<view class="record">
<view class="list">
<view
class="cell"
v-for="(item) in dataList"
:key="item.exchange_id"
>
<view class="title ellipsis-two-lines">{{
item.exchange_title
}}</view>
<view class="doctor">
<up--image
src="https://cdn.uviewui.com/uview/album/1.jpg"
radius="10"
width="220rpx"
height="220rpx"
:src="item.avatar ? item.avatar : headImg"
width="46rpx"
height="46rpx"
radius="50%"
></up--image>
<view class="name"
>{{ item.user_name }}{{ item.hospital_name }}</view
>
<view slot="error" style="font-size: 24rpx">加载失败</view>
</up--image>
</view>
<view class="imgcell">
<up--image
src="https://cdn.uviewui.com/uview/album/1.jpg"
radius="10"
width="220rpx"
height="220rpx"
<view class="content"> {{ item.exchange_content }} </view>
<view
class="imgbox"
v-if="
item.exchange_content_images &&
item.exchange_content_images.length > 0
"
>
<view
class="imgcell"
v-if="unit in item.exchange_content_images"
>
<view slot="error" style="font-size: 24rpx">加载失败</view>
</up--image>
</view>
<view class="imgcell">
<up--image
src="https://cdn.uviewui.com/uview/album/1.jpg"
radius="10"
width="220rpx"
height="220rpx"
>
<view slot="error" style="font-size: 24rpx">加载失败</view>
</up--image>
</view>
</view>
<view class="imgbox">
<video
class="myVideo"
src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4"
@error="videoErrorCallback"
controls
></video>
</view>
<view class="tagbox">
<view class="tag">标签</view>
</view>
<view class="deal">
<view class="left">
<view class="eyebox item">
<up-icon name="eye" color="#4B5563" size="28rpx"></up-icon>
<view class="num">11</view>
</view>
<view class="collect item">
<up-icon name="heart" color="#4B5563" size="28rpx"></up-icon>
<view class="num">22</view>
</view>
<view class="chat item">
<up-icon name="chat" color="#4B5563" size="28rpx"></up-icon>
<view class="num">22</view>
<up--image
:src="unit"
radius="10"
width="220rpx"
height="220rpx"
>
<view slot="error" style="font-size: 24rpx">加载失败</view>
</up--image>
</view>
</view>
<view class="time">
<up-icon name="clock" color="#4B5563" size="28rpx"></up-icon>
<view class="num">{{ formatdate("2022-10-23") }}</view>
<view class="videocon">
<view
class="imgbox"
v-if="
item.exchange_content_video &&
item.exchange_content_video.length > 0
"
>
<video
:key="index"
v-for="(videoCell, index) in item.exchange_content_video"
class="myVideo"
:src="videoCell"
@error="videoErrorCallback"
controls
></video>
</view>
</view>
<view class="tagbox" v-if="item.label && item.label.length > 0">
<view
class="tag"
v-for="cell in item.label"
:key="cell.exchange_label_id"
>{{ cell.label_name }}</view
>
</view>
<view class="deal">
<view class="left">
<view class="eyebox item">
<up-icon name="eye" color="#4B5563" size="28rpx"></up-icon>
<view class="num">{{ item.read_num }}</view>
</view>
<view class="collect item">
<up-icon
name="heart"
color="#4B5563"
size="28rpx"
></up-icon>
<view class="num">{{ item.collect_num }}</view>
</view>
<view class="chat item">
<up-icon name="chat" color="#4B5563" size="28rpx"></up-icon>
<view class="num">{{ item.comment_num }}</view>
</view>
</view>
<view class="time">
<up-icon name="clock" color="#4B5563" size="28rpx"></up-icon>
<view class="num">{{ formatdate(item.push_date) }}</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</z-paging>
</view>
<!-- <tabBar :value="2"></tabBar> -->
@ -110,33 +135,91 @@ import tabBar from "@/components/tabBar/tabBar.vue";
import headImg from "@/static/headImg.png";
import dayjs from "dayjs";
import api from "@/api/api";
import { onLoad } from "@dcloudio/uni-app";
import list from "@/uni_modules/z-paging/components/z-paging/z-paging";
const user_id = ref("");
const is_selected = ref(0);
const paging = ref(null);
const dataList = ref([]);
const total = ref(0);
const keyWord = ref("");
const showNum = ref(false);
const formatdate = (date) => {
return dayjs(date).format("YYYY-MM-DD");
};
onLoad((options) => {
if (options.keyWord) {
keyWord.value = options.keyWord;
}
if (options.userId) {
user_id.value = options.userId;
}
if(options.is_selected){
is_selected.value = options.is_selected;
}
});
const videoErrorCallback = (e) => {
uni.showModal({
content: e.target.errMsg,
showCancel: false,
});
};
const changeWord = (val) => {
if (!val) return false;
showNum.value = true;
keyWord.value = val;
paging.value.reload();
};
const queryList = (pageNo, pageSize) => {
console.log(666666);
const params = {
page: pageNo,
page_size: pageSize,
};
api.queryList(params).then((res) => {
paging.value.complete(res.data.data);
})
searchList(params);
};
const searchList = async (params) => {
let searchForm = {
keyword: keyWord.value,
user_id: user_id.value,
is_selected: Number(is_selected.value)
};
// 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.searchExchage({
...searchForm,
...params,
})
.then((res) => {
paging.value.complete(res.data.data.data);
total.value = res.data.data.total;
})
.catch((err) => {
paging.value.complete(false);
});
};
</script>
<style lang='scss' scoped>
.detail {
background: #f9f9f9;
padding: 12rpx 30rpx;
.desc {
font-size: 26rpx;
color: #4b5563;
line-height: 40rpx;
}
.red {
color: #ff0000;
}
}
.upage {
display: flex;
flex-direction: column;
@ -202,6 +285,7 @@ const queryList = (pageNo, pageSize) => {
border-radius: 30rpx;
font-size: 27rpx;
color: #3cc7c0;
margin-right: 12rpx;
display: flex;
align-items: center;
justify-content: center;
@ -248,17 +332,16 @@ const queryList = (pageNo, pageSize) => {
}
}
.special {
.record {
padding-top: 30rpx;
.list {
margin: 8rpx 30rpx 0;
margin: 8rpx 0rpx 0;
.cell {
padding: 22rpx 0;
display: flex;
padding: 22rpx 30rpx;
// display: flex;
border-bottom: 2rpx solid #f3f4f6;
.circle {
margin-top: 15rpx;
width: 15rpx;