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

2395 lines
60 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>
<z-paging
ref="paging"
inside-more
loading-more-no-more-text="咱也是有底线的"
:auto-show-back-to-top="false"
v-model="dataList"
:refresher-out-rate="0.8"
:empty-view-super-style="{'paddingBottom':'140rpx'}"
:refresher-title-style="{'paddingBottom':'60rpx','paddingTop':'10rpx'}"
:refresher-img-style="{'paddingBottom':'60rpx','paddingTop':'10rpx'}"
@query="queryList"
>
<template #top>
<backDetailNav :navName="type=='exchange'?'肝胆相照病例交流园地':'肝胆相照临床病例库'"></backDetailNav>
</template>
<template #bottom>
<view class="bottom">
<view class="iptbox" @click="open">
<up--image
:src="chatImg"
width="46rpx"
height="46rpx"
radius="50%"
></up--image>
<view class="iptcon" @click="open">
<view class="maskipt" @click="open"></view>
<up-input
@click="open"
disabled
:focus="false"
type="text"
placeholderClass="placeholderClass"
placeholder="对病例发表您的看法"
class="ipt"
/>
</view>
</view>
<view class="right">
<up--image
@click="toggleCollect"
:src="info.is_collect ? collectonImg : collectImg"
width="70rpx"
height="70rpx"
></up--image>
<view class="imgboxshang" @click="openGivePop">
<up--image
:src="shangImg"
mode="widthFix"
width="169rpx"
height="77rpx"
></up--image>
</view>
</view>
</view>
</template>
<view class="box">
<view class="title" v-if="type == 'video'">{{ info.video_title }}</view>
<view class="title" v-else-if="type == 'article'">{{
info.article_title
}}</view>
<view class="title" v-else>{{ info.exchange_title }}</view>
<view class="content" >
<view class="info" v-for="item in info.author" :key ="item" v-if="type == 'video' || type == 'article'">
<up--image
:src="item.avatar?item.avatar:headImg"
class="headImg"
width="46rpx"
height="46rpx"
radius="50%"
></up--image>
<view class="name"
>{{ item.doctor_name }} · {{ item.hospital_name }}</view
>
</view>
<view class="info" v-else>
<up--image
:src="info.avatar?info.avatar:headImg"
class="headImg"
width="46rpx"
height="46rpx"
radius="50%"
></up--image>
<view class="name"
>{{ info.user_name }} · {{ info.hospital_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">{{ info.read_num }}</view>
</view>
<view class="collect">
<up-icon
:name="info.is_collect ? 'heart-fill' : 'heart'"
:color="info.is_collect ? 'red' : '#6B7280'"
size="28rpx"
></up-icon>
<view class="num">{{ info.collect_num }}</view>
</view>
</view>
<view class="time">
<up-icon name="clock" color="#6B7280" size="28rpx"></up-icon>
<view class="num">{{ formatDay(info.push_date) }}</view>
</view>
</view>
</view>
<view class="bar"></view>
<canvas
v-if="showCanvas"
type="2d"
id="watermarkCanvas"
style="width: 200px; height: 200px; position: fixed; top: -9999px"
/>
</view>
<view class="desc">
<view class="videobox" v-if="type == 'video' && !isH5 ">
<!-- #ifdef MP-WEIXIN -->
<polyv-player
v-if="info.video_no"
:id="'playerContext'+info.video_no"
:playerId="'playerId'+info.video_no"
:vid="info.video_no"
height="500rpx"
autoplay="{{false}}"
>
</polyv-player>
<!-- #endif -->
</view>
<view class="videobox" v-if="type == 'video' && isH5">
<!-- #ifdef H5 -->
<baoliVideo :vid="info.video_no" ></baoliVideo>
<!-- #endif -->
</view>
<view class="videobox" v-else-if="type == 'article'" style="min-height:350rpx">
<view class="content">
<up-parse :content="fromatImg(info.article_content)"></up-parse>
</view>
</view>
<view class="videobox" v-else>
<view class="cloumn" v-if="info.exchange_content">
<view class="stitle">疾病信息</view>
<up-parse :content="fromatImg(info.exchange_content)" style="overflow-y: hidden;"></up-parse>
<!-- <view class="con" v-html="fromatImg(info.exchange_content)"></view> -->
</view>
<view class="cloumn" v-if="info.exchange_summary">
<view class="stitle">总结与讨论</view>
<up-parse :content="fromatImg(info.exchange_summary)"></up-parse>
<!-- <view class="con" v-html="fromatImg(info.exchange_summary)"></view> -->
</view>
<view class="bar" v-if="info.exchange_vote && info.exchange_vote.vote_title"></view>
<view class="detail" v-if="info.exchange_vote && info.exchange_vote.vote_title">
<view class="votebox" v-if="info.exchange_vote.is_have_voted==0 ">
<view class="name">在线投票</view>
<view class="title" >{{ info.exchange_vote.vote_title }}</view>
<view class="group">
<up-radio-group
v-model="option_id"
placement="column"
>
<view class="row" v-for="item in info.exchange_vote.case_exchange_vote_option" :key="item.option_id">
<up-radio
activeColor="#3CC7C0"
:label="item.option_value"
:name="item.option_id"
>
</up-radio>
</view>
</up-radio-group>
<view class="btn" @click="addVote()">投票</view>
</view>
</view>
<view class="votebox" v-if="info.exchange_vote.is_enabled==0 || info.exchange_vote.is_have_voted==1 ">
<view class="name">在线投票</view>
<view class="title">{{ info.exchange_vote.vote_title }}</view>
<view class="options">
<view class="option" v-for="item in info.exchange_vote.case_exchange_vote_option" :key="item.option_id">
<view class="row">
<view class="left">{{item.option_value }}</view>
<view class="num">{{item.proportion}}%</view>
</view>
<view class="line">
<view class="inner" :style="{width:proportion/100 }"></view>
</view>
</view>
</view>
</view>
</view>
<!-- <view class="detail" v-if="info.case_exchange_vote && info.case_exchange_vote.vote_title">
</view> -->
</view>
<view class="bar"></view>
<view class="comnum">
<view class="imgcon">
<up--image
:src="commentImg"
mode="widthFix"
width="50rpx"
height="50rpx"
></up--image>
</view>
<view class="num">全部评论{{ total }}</view>
</view>
<view class="commentcon">
<view
class="item"
v-for="(item, index) in dataList"
:key="item.comment_id"
>
<up--image
:src="item.avatar?item.avatar:headImg"
class="headImg"
width="86rpx"
height="86rpx"
radius="50%"
></up--image>
<view class="info">
<view class="user">
<view class="namebox">
<view class="name"> {{ item.user_name }}</view>
<up--image
v-if="doctor_id==item.doctor_id"
:src="selfImg"
class="selfImg"
width="69rpx"
height="31rpx"
></up--image>
</view>
<view
class="dot"
@click="
alertDeal(
item.comment_id,
item.comment_id,
item.user_name,
item.is_top,
2,
item.doctor_id
)
"
>...</view
>
</view>
<view class="question">{{ item.content }}</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"
v-if="item.sub_comment && item.sub_comment.length > 0"
>
<view
class="item"
v-for="(cell, index) in item.sub_comment.slice(0, 3)"
:key="cell.comment_id"
style="padding-left: 0;padding-right:0"
>
<up--image
:src="cell.avatar?cell.avatar:headImg"
class="headImg"
width="86rpx"
height="86rpx"
radius="50%"
></up--image>
<view class="info">
<view class="user">
<view class="namebox">
<view class="name"> {{ cell.user_name }}</view>
<up--image
v-if="doctor_id==cell.doctor_id"
:src="selfImg"
class="selfImg"
width="69rpx"
height="31rpx"
></up--image>
</view>
<view
class="dot"
@click="
alertDeal(
cell.comment_id,
cell.root_id,
cell.user_name,
cell.is_top,
3,
cell.doctor_id
)
"
>...</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>
</view>
<view
class="expand"
@click="openMorePop(item, item.sub_comment, index)"
v-if="item.sub_comment.length > 3"
>展开更多回复<view class="iconbox"><up-icon name="arrow-down" color="#3cc7c0" size="38rpx"></up-icon></view></view
>
</view>
</view>
</view>
</view>
</z-paging>
<!-- 评论框 -->
<up-popup
:zIndex="99"
:overlayStyle="{ zIndex: 98 }"
:closeOnClickOverlay="false"
:show="showCommentDialog"
:round="10"
closeable
mode="bottom"
@close="close"
@open="open"
>
<view class="poptitle"></view>
<view class="wraper">
<up--textarea
:focus="false"
ref="commentTextarea"
height="200"
:cursorSpacing="240"
adjustPosition
adjust-keyboard-to="bottom"
v-model="content"
:placeholder="placeholder"
></up--textarea>
</view>
<view class="imgbox" v-if="imgList.length > 0">
<view class="imgunit">
<up--image
:src="imgList[0]"
radius="6"
width="150rpx"
height="150rpx"
@click="previewImg(imgList[0])"
></up--image>
<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" :class="{disabled:imgList.length>=1}">
<up-upload
:disabled="imgList.length>=1"
:show-upload-list="false"
@afterRead="afterRead"
name="imgupload"
multiple
:maxCount="1"
width="40rpx"
height="77rpx"
>
<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 }"
:closeOnClickOverlay="false"
:show="showDeal"
:round="10"
mode="bottom"
@close="closeDeal"
@open="openDeal"
>
<view class="dealbox">
<view class="dealcell" @click="toggleTop" v-if="level == 2 && isArticleAuthor">{{
is_top ? "取消置顶" : "置顶"
}}</view>
<view class="dealcell" @click="openCommentDialog">回复</view>
<view class="dealcell" v-if="isArticleAuthor || doctor_id==comment_doctorId" @click="delComment">删除</view>
<view class="bar"></view>
<view class="dealcell" @click="closeDealPop">取消</view>
</view>
</up-popup>
<!-- 展开更多回复 -->
<up-popup
:zIndex="10"
:overlayStyle="{ zIndex: 9 }"
:closeOnClickOverlay="false"
:show="showMore"
:round="10"
mode="bottom"
@close="closeMore"
@open="openMore"
>
<view class="commentPop">
<view class="title">
回复
<view class="close" @click="closeMore">
<up-icon name="close" color="#666" size="20"></up-icon>
</view>
</view>
<scroll-view class="commentScroll" :scroll-top="scrollTop" @scroll="scroll" scroll-y="true" @scrolltolower="scrolltolower(mainCommentObj.comment_id)" >
<view class="unit commentcon">
<view class="item">
<up--image
:src="mainCommentObj.avatar?mainCommentObj.avatar:headImg"
class="headImg"
width="86rpx"
height="86rpx"
radius="50%"
></up--image>
<view class="info">
<view class="user">
<view class="namebox">
<view class="name"> {{ mainCommentObj.user_name}}</view>
<up--image
v-if="doctor_id==mainCommentObj.doctor_id"
:src="selfImg"
class="selfImg"
width="69rpx"
height="31rpx"
></up--image>
</view>
<view
class="dot"
@click="
alertDeal(
mainCommentObj.comment_id,
mainCommentObj.comment_id,
mainCommentObj.user_name,
mainCommentObj.is_top,
2,
mainCommentObj.doctor_id
)
"
>...</view
>
</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>
<view class="commentcon">
<view
class="item"
v-for="(cell, index) in childList"
:key="cell.comment_id"
>
<up--image
:src="cell.avatar?cell.avatar:headImg"
class="headImg"
width="86rpx"
height="86rpx"
radius="50%"
></up--image>
<view class="info">
<view class="user">
<view class="namebox">
<view class="name">{{ cell.user_name}}</view>
<up--image
v-if="doctor_id==cell.doctor_id"
:src="selfImg"
class="selfImg"
width="69rpx"
height="31rpx"
></up--image>
</view>
<view
class="dot"
@click="
alertDeal(
cell.comment_id,
cell.root_id,
cell.user_name,
cell.is_top,
3,
cell.doctor_id
)
"
>...</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>
</view>
</scroll-view>
<view class="bottom" @click="showReplyPop">
<up-input
readonly
:placeholder="'@' + mainCommentObj.user_name + ''"
border="surround"
v-model="value"
></up-input>
</view>
</view>
</up-popup>
<!-- 打赏 -->
<up-overlay :show="showGive" mask-click-able>
<view class="zanboxpop">
<view class="zanwraper">
<view class="title">打赏</view>
<view class="count">
积分余额
<text class="num">{{ point }}</text>积分
<!-- <text class="earn">去赚积分</text> -->
</view>
<view class="countbox">
<view class="minus" @click="changePoint('minus')">-</view>
<up-input
placeholder="请输入打赏积分"
type="number"
border="surround"
v-model="givePointValue"
></up-input>
<view class="add" @click="changePoint('add')">+</view>
</view>
<view class="btnbox">
<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>
<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 { nextTick, reactive, ref } from "vue";
import headImg from "@/static/headImg.png";
import collectonImg from "@/static/collectOn.png";
import collectImg from "@/static/collect.png";
import shangImg from "@/static/shang.png";
import chatImg from "@/static/chat.png";
import uploadImg from "@/static/uploadImg.png";
import backDetailNav from "@/components/backDetailNav/backDetailNav.vue";
import commentImg from "@/static/comment_icon.png";
import selfImg from "@/static/benren.png";
import list from "@/uni_modules/z-paging/components/z-paging/z-paging";
import api from "@/api/api";
import throttle from "@/utils/throttle"
import { onLoad } from "@dcloudio/uni-app";
import dayjs from "dayjs";
// #ifdef H5
import baoliVideo from "@/components/baoliVideo/baoliVideo.vue";
import { linkFlag } from "../../uni_modules/sv-editor/components/common/utils";
// #endif
const value=ref('');
const isArticleAuthor=ref(false)
const isH5=ref(process.env.UNI_PLATFORM =="h5");
const doctor_id=ref('');
const paging = ref(null);
const dataList = ref([]);
const total = ref(0);
const imgList = ref([]);
const showCanvas = ref(true);
const showCommentDialog = ref(false);
const givePointValue = ref(5);
const canvasWidth = ref(0);
const canvasHeight = ref(0);
const showModal = ref(false);
const content = ref("");
const type = ref("");
const info = reactive({});
const showDeal = ref(false);
const showMore = ref(false);
const showGive = ref(false);
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 option_id = ref("");
const point=ref(0)
const comment_doctorId=ref('');
const commentTextarea=ref(null)
const isLock=ref(false);
const confirmGive = () => {
//showGive.value = false;
givePoint();
};
const oldScrollTop=ref(0)
const scrollTop=ref(0)
const scroll=(e)=>{
oldScrollTop.value=e.detail.scrollTop
}
const toTop=()=>{
scrollTop.value=oldScrollTop.value
nextTick(()=>{
scrollTop.value=0
})
}
const openGivePop=()=>{
showGive.value=true;
getUserPoint();
}
const formatDay = (date) => {
return dayjs(date).format("YYYY-MM-DD");
};
const formatDate = (date) => {
return dayjs(date).format("YYYY-MM-DD HH:mm");
};
const scrolltolower=(rootId)=>{
console.log(isLock.value);
if(!isLock.value){
let page=mainCommentObj.sub_page+1;
mainCommentObj.sub_page=page;
let params = {
page: page,
page_size: 5,
};
if (type.value == "article") {
getArticleComment(params,rootId);
} else if (type.value == "video") {
getVideoComment(params,rootId);
} else {
getExchangeComment(params,rootId);
}
}
}
const changePoint = (type) => {
if (type == 'minus') {
if (givePointValue.value >5) {
givePointValue.value = givePointValue.value - 5
} else {
uni.showToast({
icon: "none",
title: "每次打赏积分必须大于0",
});
givePointValue.value =1;
}
}else{
givePointValue.value = givePointValue.value + 5
}
}
const openMorePop = (obj, list, index) => {
showMore.value = true;
childList.value = list;
isLock.value=false;
Object.assign(mainCommentObj, obj);
clickIndex.value = index;
mainCommentObj.sub_page=1;
};
const getArticleDetail = (id) => {
api.getArticleDetail(id).then((res) => {
let result = res.data.data;
Object.assign(info, result);
for (let i= 0; i< info.author.length; i++) {
if(info.author[i].doctor_id==doctor_id.value){
isArticleAuthor.value=true;
}
}
});
};
const getVideoDetail = (id) => {
api.getVideoDetail(id).then((res) => {
let result = res.data.data;
Object.assign(info, result);
for (let i= 0; i< info.author.length; i++) {
if(info.author[i].doctor_id==doctor_id.value){
isArticleAuthor.value=true;
}
}
});
};
const getExchangeDetail = (id) => {
api.getExchangeDetail(id).then((res) => {
let result = res.data.data;
Object.assign(info, result);
if(info.doctor_id==doctor_id.value){
isArticleAuthor.value=true;
}
});
};
const getUserPoint=()=>{
api.getUserPoint().then(res=>{
point.value=res.data.data
})
}
const givePoint=()=>{
if(givePointValue.value==null){
//givePointValue.value =1;
uni.showToast({
icon: "none",
title: "每次打赏积分必须大于0",
});
return false;
}
if (givePointValue.value <=1) {
givePointValue.value =1;
uni.showToast({
icon: "none",
title: "每次打赏积分必须大于0",
});
return false;
};
if(!(/^[1-9]\d*$/.test(givePointValue.value))){
uni.showToast({
icon: "none",
title: "每次打赏积分必须是大于0的整数",
});
givePointValue.value = null;
return false;
}
if(point.value<givePointValue.value){
uni.showToast({
icon:'none',
title:'积分不足'
})
return false
}
let giveType=1;
if(type.value=='article'){
giveType=1
}else if(type.value=='video'){
giveType=2
}else{
giveType=3
}
api.givePoint({
id:id.value,
type:giveType,
point:givePointValue.value,
}).then(res=>{
uni.showToast({
icon:'none',
title:'打赏成功!'
})
givePointValue.value = 5;
showGive.value=false;
})
}
const getQueryParam=(param,link)=>{
const url = link;
// 构造正则表达式,匹配 ? 或 & 后面跟随的参数名称和其值
const regex = new RegExp('[?&]' + param + '=([^&#]*)', 'i');
const result = regex.exec(url);
return result ? decodeURIComponent(result[1]) : null;
};
onLoad((options) => {
if(options.scene){
var decodedURL = decodeURIComponent(options.scene);
let idStr=getQueryParam('id',decodedURL);
let typeStr=getQueryParam('type',decodedURL);
if(idStr){
id.value=idStr;
}
if(typeStr){
if(typeStr==1){
type.value='article';
}else if(typeStr==2){
type.value='video';
}
}
}else{
id.value = options.id;
type.value = options.type;
}
readRecord()
let userInfo=uni.getStorageSync('userInfo');
if(userInfo.doctor_id){
doctor_id.value=userInfo.doctor_id;
}
});
const clearComment = () => {
parent_id.value = null;
imgList.value = [];
content.value = "";
root_id.value = null;
placeholder.value="请输入评论内容"
//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 alertDeal = (parentId, rootId, name, top, commentLevel,userId) => {
parent_id.value = parentId;
comment_doctorId.value=userId;
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;
};
const queryList = (pageNo, pageSize) => {
const params = {
page: pageNo,
page_size: pageSize,
};
// type.value == "article" ? getArticleComment(params) : getVideoComment(params);
if (type.value == "article") {
getArticleComment(params);
} else if (type.value == "video") {
getVideoComment(params);
} else {
getExchangeComment(params);
}
};
const getArticleComment = (params,rootId='') => {
const form = {
article_id: id.value,
root_id:rootId,
is_have_sub_comment: 1,
};
api
.getArticleComment({
...form,
...params,
})
.then((res) => {
if(!rootId){
paging.value.complete(res.data.data.data);
total.value = res.data.data.total;
is_author.value= res.data.data.is_author==1?true:false;
setTimeout(() => {
if (showMore.value) {
childList.value=[];
openMorePop(
dataList.value[clickIndex.value],
dataList.value[clickIndex.value].sub_comment,
clickIndex.value
);
toTop();
}
}, 1500);
}else{
if(res.data.data.data.length>0){
let arr=mainCommentObj.sub_comment;
mainCommentObj.sub_comment=mainCommentObj.sub_comment.concat(res.data.data.data);
childList.value=mainCommentObj.sub_comment;
if(res.data.data.data.length<5){
isLock.value=true;
}
}
}
})
.catch((res) => {
paging.value.complete(false);
});
};
const sub_list=ref([]);
const getVideoComment = (params,rootId='') => {
const form = {
video_id: id.value,
root_id:rootId,
is_have_sub_comment:1,
};
api
.getVideoComment({
...form,
...params,
})
.then((res) => {
if(!rootId){
paging.value.complete(res.data.data.data);
total.value = res.data.data.total;
is_author.value= res.data.data.is_author==1?true:false;
setTimeout(() => {
if (showMore.value) {
childList.value=[];
openMorePop(
dataList.value[clickIndex.value],
dataList.value[clickIndex.value].sub_comment,
clickIndex.value
);
toTop();
}
}, 1500);
}else{
if(res.data.data.data.length>0){
let arr=mainCommentObj.sub_comment;
mainCommentObj.sub_comment=mainCommentObj.sub_comment.concat(res.data.data.data);
childList.value=mainCommentObj.sub_comment;
if(res.data.data.data.length<5){
isLock.value=true;
}
}
}
})
.catch((res) => {
paging.value.complete(false);
});
};
const getExchangeComment = (params,rootId='') => {
const form = {
exchange_id: id.value,
root_id:rootId,
is_have_sub_comment: 1,
};
api
.getExchangeComment({
...form,
...params,
})
.then((res) => {
if(!rootId){
paging.value.complete(res.data.data.data);
total.value = res.data.data.total;
is_author.value= res.data.data.is_author==1?true:false;
setTimeout(() => {
if (showMore.value) {
childList.value=[];
openMorePop(
dataList.value[clickIndex.value],
dataList.value[clickIndex.value].sub_comment,
clickIndex.value
);
toTop();
}
}, 1500);
}else{
if(res.data.data.data.length>0){
let arr=mainCommentObj.sub_comment;
mainCommentObj.sub_comment=mainCommentObj.sub_comment.concat(res.data.data.data);
childList.value=mainCommentObj.sub_comment;
if(res.data.data.data.length<5){
isLock.value=true;
}
}
}
})
.catch((res) => {
paging.value.complete(false);
});
};
const open = () => {
showCommentDialog.value = true;
};
const close = () => {
showCommentDialog.value = false;
clearComment();
};
const openDeal = () => {
showDeal.value = true;
};
const closeDeal = () => {
showDeal.value = false;
};
const openMore = () => {
showMore.value = true;
};
const closeMore = () => {
showMore.value = false;
paging.value.refresh();
};
const previewImg = (url) => {
uni.previewImage({
current: url,
urls: [url],
});
};
const fillTextToImgWx = (base64) => {
let maskText = "@肝胆相照临床病例库";
return new Promise((resolve, reject) => {
wx.createSelectorQuery()
.select("#watermarkCanvas")
.fields({
node: true,
size: true,
})
.exec((res) => {
const canvas = res[0].node;
const ctx = canvas.getContext("2d");
let textMetrics = ctx.measureText(maskText);
//水印文字宽度
let {
width: textWidth,
actualBoundingBoxAscent,
actualBoundingBoxDescent,
} = textMetrics;
//水印文字高度
let textHeight = actualBoundingBoxAscent
? actualBoundingBoxAscent + actualBoundingBoxDescent
: textMetrics.fontBoundingBoxAscent +
textMetrics.fontBoundingBoxDescent;
let imgHeight, imgWidth;
let font = ""; //fontsize"px Arial";
let fontColor = "#fff";
let strokeWidth =10;
uni.getImageInfo({
src: base64,
success: (imageRes) => {
// 设置canvas宽高
//28;
let scale =(imageRes.width / 800) * 30 > 12
? (imageRes.width / 800) * 30
: 12;
font = scale + "px Arial";
canvas.width = imageRes.width;
canvas.height = imageRes.height;
imgHeight = imageRes.height;
imgWidth = imageRes.width;
// 创建目标图片对象
const image = canvas.createImage();
image.src = "";
image.src = base64;
image.onload = () => {
// 清除画布
//ctx.clearRect(0, 0, canvas.width, canvas.height);
// 将图片绘制到canvas上
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
let posXmargin =20; //this.data.posXmargin // 自定义离左/右边的距离
let posYmargin = 20; // this.data.posYmargin // 自定义离上/下边的距离
let randomNumber = 3; //Math.floor(Math.random() * (3 + 1));
switch (randomNumber) {
case 0: //左上角
let lt_x = posXmargin;
let lt_y = posYmargin + textHeight;
ctx.font = font;
ctx.storkStyle = "#000";
ctx.strokeWidth = strokeWidth;
ctx.fillStyle = "#fff";
ctx.fillText(maskText, lt_x, lt_y);
//ctx.restore()
//ctx.save()
break;
case 1: //左下角
let lb_x = posXmargin;
let lb_y = imgHeight - posYmargin;
ctx.font = font;
ctx.fillStyle = fontColor;
ctx.strokeStyle = "black";
ctx.strokeWidth = strokeWidth;
ctx.fillStyle = "#fff";
ctx.fillText(maskText, lb_x, lb_y);
//ctx.restore()
//ctx.save()
break;
case 2: //右上角
let rt_x =
imgWidth - textWidth * 2.9 - posXmargin <= 0
? 10
: imgWidth - textWidth * 2.9 - posXmargin;
let rt_y = posYmargin + textHeight * 2;
ctx.font = font;
ctx.fillStyle = fontColor;
ctx.strokeStyle = "#000";
ctx.strokeWidth = strokeWidth;
ctx.fillStyle = "#fff";
ctx.fillText(maskText, rt_x, rt_y);
ctx.restore();
ctx.save();
break;
case 3: //右下角
let rb_x =
imgWidth - scale*10 - posXmargin <= 0
? 10
: imgWidth - scale*10 - posXmargin;
let rb_y = imgHeight - posYmargin;
ctx.font = font;
ctx.fillStyle = fontColor;
ctx.strokeStyle = "#000";
//ctx.strokeWidth = strokeWidth;
ctx.fillStyle = "#fff";
ctx.strokeText(maskText,rb_x, rb_y);
ctx.fillText(maskText, rb_x, rb_y);
//ctx.restore()
//ctx.save()
break;
}
//ctx.restore()
// 将canvas转为图片
//setTimeout(() => {
wx.canvasToTempFilePath({
canvas: canvas,
success: function (res) {
// 输出生成的带水印的图片临时路径
resolve(res.tempFilePath);
//wx.previewImage({ urls: [res.tempFilePath] });
},
fail: function (res) {
// reject(res)
console.error(res);
},
});
//})
};
},
});
});
});
};
const fillTextToImg = (base64) => {
const img = new Image();
img.src = base64;
img.setAttribute("crossOrigin", "Anonymous");
return new Promise((resolve, reject) => {
img.onload = () => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = img.width;
canvas.height = img.height;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
const remFontSize = 30; //canvas.width / 35;
ctx.font = remFontSize + "px '微软雅黑'";
ctx.textAlign = "right";
ctx.strokeStyle = "#000";
ctx.fillStyle = "#fff";
const uploadTime = new Date();
const name = "@肝胆相照临床病例库";
const spaceH = remFontSize * 0.1;
let randomNumber = 3//Math.floor(Math.random() * (3 + 1));
let position = [
{
top: remFontSize,
left: name.length * 30 || 30,
},
{
top: remFontSize,
left: canvas.width - remFontSize * 0.1 - spaceH,
},
{
top: canvas.height - remFontSize * 0.5 - spaceH,
left: name.length * 30 || 30,
},
{
top: canvas.height - remFontSize * 0.5 - spaceH,
left: canvas.width - remFontSize * 0.1 - spaceH,
},
];
ctx.strokeText(
name,
position[randomNumber].left,
position[randomNumber].top
);
ctx.fillText(
name,
position[randomNumber].left,
position[randomNumber].top
);
resolve(canvas.toDataURL("image/jpeg"));
};
});
};
const base64ToFile = (base64Data, filename) => {
var arr = base64Data.split(",");
var type = arr[0].match(/:(.*?);/)[1];
var fileExt = type.split("/")[1];
var bstr = atob(arr[1]);
var n = bstr.length;
var u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {
type: type,
});
};
const generateUUID = () => {
let d = new Date().getTime();
if (
typeof performance !== "undefined" &&
typeof performance.now === "function"
) {
d += performance.now(); // 使用性能测量 APIperformance.now())获取更高精度的时间戳
}
const uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
/[xy]/g,
function (c) {
const r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == "x" ? r : (r & 0x3) | 0x8).toString(16);
}
);
return uuid;
};
const readImages = async (localIds) => {
let promiseFun = [];
for (var i = 0; i < localIds.length; i++) {
//let localData = await doreadImage(localIds[i]);
let img = null;
// #ifdef H5
let imgBase64 = await getImageBase64(localIds[i].url);
img = await fillTextToImg(imgBase64);
// #endif
// #ifdef MP-WEIXIN
img = await fillTextToImgWx(localIds[i].url);
// #endif
promiseFun.push(getOss(img))
}
Promise.all(promiseFun).then((res) => {
uni.showToast({
title: "上传成功",
icon:"none"
});
});
};
// 图片转64代
const getImageBase64 = (url) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "blob";
xhr.onload = function () {
if (this.status == 200) {
const fileReader = new FileReader();
fileReader.onloadend = function () {
resolve(fileReader.result); // Base64编码的字符串
};
fileReader.readAsDataURL(xhr.response); // 将blob转换为base64
} else {
reject("Could not fetch the file.");
}
};
xhr.onerror = function () {
reject("XHR error");
};
xhr.send();
});
};
const chooseImg = () => {
showCanvas.value = true;
uni.chooseImage({
count: 1, //默认9
sizeType: ["original", "compressed"], //可以指定是原图还是压缩图,默认二者都有
sourceType: ["album", "camera "], //从相册选择
success: function (res) {
uni.getFileSystemManager({
filePath: res.tempFilePaths[0], // 替换为你的临时文件路径
success: (res) => {
// 这里res.file就是File对象
// 接下来可以使用这个File对象进行上传等操作
},
fail: (err) => {
console.error("获取文件信息失败", err);
},
});
//readImages(res.tempFilePaths);
},
});
};
const getOss=(temurl)=>{
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(temurl);
return new Promise((resolve, reject) => {
uni.uploadFile({
url: host, // 仅为示例,非真实的接口地址
filePath:temurl,
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;
imgList.value = [url];
}
},
fail: (err) => {
},
});
});
}
});
}
const handleUpload = (file) => {
let File = file.file;
readImages(File)
};
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) => {
handleUpload(file);
};
const delImg = (index) => {
imgList.value = [];
};
const collectArticle = (id) => {
api.collectArticle(id).then((res) => {
uni.showToast({
icon: "none",
title: "收藏成功",
});
getArticleDetail(id);
});
};
const collectVideo = (id) => {
api.collectVideo(id).then((res) => {
uni.showToast({
icon: "none",
title: "收藏成功",
});
getVideoDetail(id);
});
};
const collectExchange = (id) => {
api.exchangeCollect(id).then((res) => {
uni.showToast({
icon: "none",
title: "收藏成功",
});
getExchangeDetail(id);
});
};
const cancelCollectArticle = (id) => {
api.cancelCollectArticle(id).then((res) => {
uni.showToast({
icon: "none",
title: "已取消收藏",
});
getArticleDetail(id);
});
};
const cancelCollectVideo = (id) => {
api.cancelCollectVideo(id).then((res) => {
uni.showToast({
icon: "none",
title: "已取消收藏",
});
getVideoDetail(id);
});
};
const cancelCollectExchange = (id) => {
api.cancelCollectExchange(id).then((res) => {
uni.showToast({
icon: "none",
title: "已取消收藏",
});
getExchangeDetail(id);
});
};
const toggleCollect = throttle(() => {
if (type.value == "video") {
info.is_collect ? cancelCollectVideo(id.value) : collectVideo(id.value);
} else if (type.value == "article") {
info.is_collect ? cancelCollectArticle(id.value) : collectArticle(id.value);
} else {
info.is_collect
? cancelCollectExchange(id.value)
: collectExchange(id.value);
}
});
const addArticleComment = (id, data) => {
api.addArticleComment(id, data).then((res) => {
if(res.data.data.status==1){
uni.showToast({
icon: "none",
title: "评论成功",
});
clearComment();
showCommentDialog.value = false;
paging.value.refresh();
}else if(res.data.data.status==2){
uni.showToast({
icon: "none",
title: "评论成功,积分+5",
});
clearComment();
showCommentDialog.value = false;
paging.value.refresh();
}else if(res.data.data.status==0){
uni.showToast({
icon: "none",
title: "评论失败",
});
}
});
};
const addVideoComment = (id, data) => {
api.addVideoComment(id, data).then((res) => {
if(res.data.data.status==1){
uni.showToast({
icon: "none",
title: "评论成功",
});
clearComment();
showCommentDialog.value = false;
paging.value.refresh();
}else if(res.data.data.status==2){
uni.showToast({
icon: "none",
title: "评论成功,积分+5",
});
clearComment();
showCommentDialog.value = false;
paging.value.refresh();
}else if(res.data.data.status==0){
uni.showToast({
icon: "none",
title: "评论失败",
});
}
});
};
const addExchangeComment = (id, data) => {
api.addExchangeComment(id, data).then((res) => {
if(res.data.data.status==1){
uni.showToast({
icon: "none",
title: "评论成功",
});
clearComment();
showCommentDialog.value = false;
paging.value.refresh();
}else if(res.data.data.status==2){
uni.showToast({
icon: "none",
title: "评论成功,积分+5",
});
clearComment();
showCommentDialog.value = false;
paging.value.refresh();
}else if(res.data.data.status==0){
uni.showToast({
icon: "none",
title: "评论失败",
});
}
});
};
const delArticleComment = (id) => {
api.delArticleComment(id).then((res) => {
uni.showToast({
icon: "none",
title: "删除成功",
});
paging.value.refresh();
});
};
const delVideoComment = (id) => {
api.delVideoComment(id).then((res) => {
uni.showToast({
icon: "none",
title: "删除成功",
});
paging.value.refresh();
});
};
const fromatImg = (val) => {
if(val){
return val.replace(/\<img|\<\s+img/gi, '<img class="imgstyle"');
}else{
return '';
}
};
const delExchangeComment = (id) => {
// 调用删除评论的API
api.delExchangeComment(id).then((res) => {
// 显示提示框,提示删除成功
uni.showToast({
icon: "none",
title: "删除成功",
});
// 刷新分页组件
paging.value.refresh();
});
};
const topArticleComment = (id) => {
api.topArticleComment(id).then((res) => {
uni.showToast({
icon: "none",
title: "置顶成功",
});
showDeal.value = false;
paging.value.refresh();
});
};
const topVideoComment = (id) => {
api.topVideoComment(id).then((res) => {
uni.showToast({
icon: "none",
title: "置顶成功",
});
showDeal.value = false;
paging.value.refresh();
});
};
const topExchangeComment = (id) => {
api.topExchangeComment(id).then((res) => {
uni.showToast({
icon: "none",
title: "置顶成功",
});
showDeal.value = false;
paging.value.refresh();
});
};
const cancelTopArticleComment = (id) => {
api.cancelTopArticleComment(id).then((res) => {
uni.showToast({
icon: "none",
title: "取消置顶成功",
});
showDeal.value = false;
paging.value.refresh();
});
};
const cancelTopVideoComment = (id) => {
api.cancelTopArticleComment(id).then((res) => {
uni.showToast({
icon: "none",
title: "取消置顶成功",
});
showDeal.value = false;
paging.value.refresh();
});
};
const cancelTopExchangeComment = (id) => {
api.cancelTopExchangeComment(id).then((res) => {
uni.showToast({
icon: "none",
title: "取消置顶成功",
});
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 if (type.value == "video") {
delVideoComment(parent_id.value);
} else {
delExchangeComment(parent_id.value);
}
showModal.value = false;
};
const toggleTop = () => {
if (type.value == "article") {
is_top.value
? cancelTopArticleComment(parent_id.value)
: topArticleComment(parent_id.value);
} else if (type.value == "video") {
is_top.value
? cancelTopVideoComment(parent_id.value)
: topVideoComment(parent_id.value);
} else {
is_top.value
? cancelTopExchangeComment(parent_id.value)
: topExchangeComment(parent_id.value);
}
};
const sendComment = throttle(() => {
if (!content.value) {
uni.showToast({
icon: "none",
title: "请输入评论内容",
});
return false;
}
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 (root_id.value !== null) {
postData.root_id = root_id.value;
}
if (type.value == "article") {
addArticleComment(id.value, postData);
} else if (type.value == "video") {
addVideoComment(id.value, postData);
} else {
addExchangeComment(id.value, postData);
}
});
const formatHtml = (val) => {
if (/^回复.+/.test(val)) {
return val.replace(
/[^回复]([^]+)/,
`<font style="color:#3CC7C0">$&</font>`
);
}
return val;
};
const addVote = () => {
if (!option_id.value) {
uni.showToast({
icon: "none",
title: "请选择投票选项!",
});
return false;
}
api
.addVote(id.value, {
option_id: option_id.value,
})
.then((res) => {
uni.showToast({
icon: "none",
title: "投票成功!",
});
getExchangeDetail(id.value);
});
};
const readRecord= async()=>{
let flag=1;
if(type.value=='article'){
flag=1;
}else if(type.value=='video'){
flag=2;
}else{
flag=3;
}
const res=api.readRecord({
type:flag,
id:id.value
})
if(res){
if (type.value == "article") {
getArticleDetail(id.value);
} else if (type.value == "video") {
getVideoDetail(id.value);
} else {
getExchangeDetail(id.value);
}
}
}
</script>
<style lang='scss' scoped>
.videobox {
padding: 20rpx 30rpx;
.cloumn{
padding-bottom: 30rpx;
.stitle{
font-size: 32rpx;
font-weight: bold;
}
}
:deep(.video) {
display: flex;
justify-content: center;
}
.con {
:deep(.img) {
width: 100%;
}
}
}
.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;
:deep(.imgstyle){
max-width: 100%!important;
}
:deep(._block){
text-align: left!important;
}
}
.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;
}
}
}
}
.commentPop {
height: calc(100vh - 400rpx);
display: flex;
flex-direction: column;
.commentScroll {
flex: 1;
overflow-y: scroll;
margin-bottom: 96rpx;
}
.bottom {
border-top: 2rpx solid #efefef;
height: 96rpx;
display: flex;
align-items: center;
justify-content: center;
background: #fff;
:deep(.u-input__content__field-wrapper__field) {
height: 50rpx;
}
:deep(.u-input) {
background: #f2f2f2;
}
:deep(.u-input--radius) {
border-radius: 40rpx;
}
}
.title {
height: 100rpx;
line-height: 100rpx;
text-align: center;
position: relative;
border-bottom: 2rpx solid #e7e7e7;
.close {
position: absolute;
right: 20rpx;
top: 30rpx;
}
}
.unit {
.item {
margin-top: 12rpx;
border-bottom: 2rpx solid rgb(231, 231, 231);
}
}
}
.dealbox {
.dealcell {
display: flex;
align-items: center;
justify-content: center;
height: 112rpx;
font-size: 32rpx;
color: rgba(0, 0, 0, 0.9);
border-bottom: 2rpx solid #efefef;
}
}
.expand {
display: flex;
font-size: 32rpx;
padding: 12rpx 0;
color: #3cc7c0;
}
.commentcon {
background-color: #fff;
.item {
display: flex;
padding: 30rpx 35rpx 16rpx;
.info {
margin-left: 24rpx;
flex: 1;
.user {
display: flex;
align-items: center;
justify-content: space-between;
.namebox{
display: flex;
align-items: center;
:deep(.u-image) {
background: none !important;
padding-bottom: 16rpx;
}
.selfImg{
padding-bottom: 6rpx;
}
.name {
margin-right: 6rpx;
font-size: 34rpx;
}
}
.dot {
font-size: 32rpx;
padding:0 14rpx;
}
}
.question {
margin-top: 15rpx;
font-size: 30rpx;
margin-bottom: 0px;
line-height: 54rpx;
color: #333;
white-space: pre-wrap;
word-wrap: break-word;
word-break: break-all;
}
.commentImg {
margin-top: 16rpx;
}
.date {
font-size: 30rpx;
color: #666666;
line-height: 34px;
}
}
}
}
.comnum {
padding: 0 30rpx;
background: #fff;
display: flex;
height: 100rpx;
align-items: center;
border-bottom: 1px solid #e7e7e7;
.imgcon {
margin-top: 10rpx;
}
:deep(.u-image) {
background: none !important;
}
.num {
margin-left: 10rpx;
font-size: 32rpx;
}
}
.content {
// padding: 30rpx;
background-color: #fff;
}
.votebox {
padding: 30rpx;
background: #fff;
:deep(.u-radio__label-wrap){
flex:1;
}
:deep(.u-radio){
padding: 16rpx;
}
.group{
margin-top: 20rpx;
.row{
border-radius: 20rpx;
border: 2rpx solid #B8B8B8;
background: #fff;
margin-bottom:24rpx;
}
}
.btn {
margin: 50rpx 40rpx 0;
height: 92rpx;
background: #3cc7c0;
border-radius: 46rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
color: #ffffff;
}
.name {
font-size: 32rpx;
color: #000000;
font-weight: bold;
line-height: 46rpx;
}
.title {
margin-top: 24rpx;
font-size: 30rpx;
color: #333333;
line-height: 46rpx;
}
.option {
margin-top: 26rpx;
.row {
font-size: 27rpx;
color: #4b5563;
display: flex;
align-items: center;
margin-bottom: 10rpx;
justify-content: space-between;
.left{
width:80%;
}
}
.line {
width: 100%;
height: 15rpx;
background: #f3f4f6;
border-radius: 19rpx;
overflow: hidden;
.inner {
height: 15rpx;
background: #3cc7c0;
border-radius: 19rpx;
}
}
}
}
.imgboxshang {
display: flex;
margin-left: 8rpx;
align-items: center;
}
.imgbox {
margin: 0 30rpx 30rpx;
.imgunit {
width: 150rpx;
height: 150rpx;
position: relative;
.close {
position: absolute;
top: 0rpx;
right: 0;
}
}
}
.poptitle {
height: 88rpx;
border-bottom: 1rpx solid #e7e7e7;
}
.sendbox {
display: flex;
justify-content: space-between;
margin: 0 30rpx 30rpx;
.left.disabled{
:deep(.u-image__image){
opacity: 0.5;
}
}
.btn {
width: 120rpx;
height: 58rpx;
display: flex;
align-items: center;
justify-content: center;
background: #3cc7c0;
font-weight: 400;
font-size: 30rpx;
color: #fff;
border-radius: 12rpx;
}
}
.wraper {
margin: 0rpx 12rpx;
}
.desc {
width:100%;
overflow-x:hidden;
padding-bottom: 80rpx;
:deep(.imgstyle){
max-width:100%;
position: relative;
left:50%;
transform: translateX(-50%);
}
:deep(._block){
text-align: left!important;
text-indent: 0px!important;
}
}
.bottom {
position: fixed;
display: flex;
width: 100%;
box-sizing: border-box;
padding: 40rpx 30rpx;
align-items: center;
z-index:999;
border-top: 2rpx solid #f9fafb;
background: #fff;
bottom: 0;
:deep(.u-image) {
background: none !important;
}
:deep(.placeholderClass) {
font-size: 30rpx;
color: #4b5563;
}
.right {
margin-left: 20rpx;
display: flex;
align-items: center;
background: #fff;
.imgbox {
margin-left: 20rpx;
}
}
.iptbox {
flex: 1;
padding-left: 30rpx;
background: #f3f4f6;
border-radius: 38px;
height: 77rpx;
display: flex;
overflow: hidden;
align-items: center;
.iptcon{
position: relative;
.maskipt{
position: absolute;
width:100%;
height:100%;
z-index:1
}
}
.ipt {
margin-left: 15rpx;
}
}
}
.bar {
width: 100%;
background: #f9fafb;
height: 20rpx;
}
.box {
background: #fff;
/* height: calc(100vh - 220rpx);
overflow-y: scroll;
-webkit-overflow-scrolling: touch; */
.title {
position: relative;
z-index: 1;
padding: 35rpx 30rpx 0;
background: #fff;
margin-top: -40rpx;
font-weight: 400;
font-size: 38rpx;
color: #111827;
line-height: 54rpx;
margin-bottom: 20rpx;
}
.info {
display: flex;
align-items: center;
/* #ifdef H5 */
margin-bottom: 8rpx;
/* #endif */
padding: 0 30rpx;
font-size: 28rpx;
color: #4b5563;
line-height: 28rpx;
:deep(.u-image) {
/* #ifdef MP-WEIXIN */
margin-top: 8rpx;
/* #endif */
}
.name {
margin-left: 15rpx;
}
}
}
.deal {
margin-top: 12rpx;
padding: 0 30rpx 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;
}
}
.iconbox{
margin-top: 5rpx;
}
:deep(._root){
overflow-x: hidden!important;
}
</style>