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

2083 lines
51 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>
<div class="upage">
<view class="navbox">
<view class="bg"></view>
<view class="namebox">
<view class="back" @click="alertSave">
<u-icon name="arrow-left" color="#000" size="24"></u-icon>
</view>
<!-- <view class="logo">logo</view> -->
<view class="name">发病例交流帖</view>
</view>
</view>
<!-- <backNav :navName="'发病例交流帖'"></backNav> -->
<scroll-view class="form" id="form" scroll-y="true" :style="{paddingBottom:bottomHeight+'rpx'}">
<view class="textbox">
<up--textarea
autoHeight
v-model="form.exchange_title"
placeholder="输入标题,可包含患者信息、主诉"
></up--textarea>
</view>
<view class="row">
<view class="left"> 病例信息 </view>
<view class="right" @click="clearMuBan">
<u-icon name="trash" color="#6B7280" size="18"></u-icon>
清除模板
</view>
</view>
<view class="textcon page-editor-container" id="editor">
<sv-editor
placeholder="患者基本情况,检查结果,诊疗图片或视频"
eid="editor-id"
@ready="ready"
pasteMode="origin"
@focus="focusInfo"
@blur="blurInfo"
@epaste="epaste"
></sv-editor>
<!-- <editor
id="editor"
placeholder="写点什么吧~~"
show-img-resize
show-img-toolbar
show-img-size
@ready="ready"
@focus="OnFocus"
@statuschange="statuschange"
></editor> -->
</view>
<view class="textcon" style="border: none">
<view class="row">
<view class="left">
总结与讨论 <text class="tip">(可不填)</text>
</view>
</view>
<view class="textcell">
<view class="iptbox" id="editorRes">
<sv-editor
placeholder="分享经验和心得,如:诊断与鉴别诊断易错点,治疗过程难点,病例的相关知识总结及讨论等"
eid="editorResult"
@ready="readyResult"
@focus="focusResult"
@blur="focusResult"
></sv-editor>
</view>
</view>
</view>
<view class="textcon" style="border: none">
<view class="sickbox">
<view class="sick" v-for="(item,index) in labelList" :key="item.app_iden">
{{ item.label_name }}
<view class="del" @click="delLabel(index)">
<up-icon name="close-circle" color="#3CC7C0" size="20"></up-icon>
</view>
</view>
<view class="add" @click="openLabelPop">
<up-icon name="plus" color="#3CC7C0" size="16"></up-icon>
添加疾病
</view>
</view>
<!-- <view class="imgbox">
<view class="imgcell">
<up--image src="https://cdn.uviewui.com/uview/album/1.jpg" mode="widthFix"></up--image>
</view>
</view> -->
</view>
</scroll-view>
<view class="bottom" :style="{height:bottomHeight+'rpx'}">
<view class="toolbox">
<view
class="cell"
@click="insertImage"
:class="{ active: !isFocusInfo && !isFocusResult }"
>
<up--image
:src="photoImg"
class="headImg"
width="32rpx"
height="32rpx"
></up--image>
<view class="name">添加图片</view>
</view>
<view
class="cell"
@click="insertVideo"
:class="{ active: !isFocusInfo && !isFocusResult }"
>
<up--image
:src="videoImg"
class="headImg"
width="32rpx"
height="32rpx"
></up--image>
<view class="name">添加视频</view>
</view>
<view
class="cell"
:class="{ active: !isFocusInfo }"
@click="alertTitle"
>
<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" @click="openDraftList">草稿箱</view>
<view class="vote" @click="alertVote">
投票
<up--image
:src="voteImg"
class="headImg"
width="47rpx"
height="47rpx"
></up--image>
</view>
</view>
<view class="right" @click="publish">发布</view>
</view>
</view>
<up-popup
:round="10"
:show="showVote"
mode="bottom"
@close="closeVote"
@open="openVote"
>
<view class="votepop">
<view class="titlebox">
<view class="left" @click="closeVote">取消</view>
<view class="right" @click="saveVote">保存</view>
</view>
<view class="votecon">
<view class="titlebox">
<view class="title">投票标题</view>
<view class="desc">(最多20字)</view>
</view>
<view class="row first">
<up-input
placeholder="请输入投票标题"
border="surround"
v-model="voteData.vote_title"
clearable
></up-input>
</view>
<view
class="row"
v-for="(item, index) in voteData.case_exchange_vote_option"
:key="index"
>
<up-input
placeholder="输入选项建议少于16个字"
border="surround"
v-model="item.option_value"
clearable
></up-input>
<view class="iconbox" @click="delOption(index)">
<u-icon name="minus-circle" color="red" size="28"></u-icon>
</view>
</view>
<!-- <view class="row">
<up-input
placeholder="输入选项建议少于16个字"
border="surround"
v-model="value"
clearable
></up-input>
</view>
<view class="row">
<up-input
placeholder="输入选项建议少于16个字"
border="surround"
v-model="value"
clearable
></up-input>
</view> -->
<view class="add" @click="addOption">
<up-icon name="plus" color="#4B5563" size="18"></up-icon>
<view class="desc">添加选项</view>
</view>
<view class="expire">
<view class="name">有效期(天)</view>
<view class="right">
<view class="minus" @click="changeDay('minus')">
<up-icon name="minus" color="#4B5563" size="30rpx" bold></up-icon>
</view>
<view class="day">{{ voteData.valid_day }}</view>
<view class="plus" @click="changeDay('plus')">
<up-icon name="plus" color="#4B5563" size="30rpx" bold></up-icon>
</view>
</view>
</view>
<view class="tips"
>友情提醒:为保证投票结果准确性,帖子发布后投票无法修改</view
>
</view>
<view class="confirm" @click="saveVote">确认</view>
<view class="del" @click="clearVote">删除投票</view>
</view>
</up-popup>
<up-popup
:round="10"
zIndex="9"
:show="showDraft"
mode="bottom"
@close="closeDraft"
@open="openDraft"
>
<view class="draftpop">
<view class="titlebox"
>草稿箱
<view class="close" @click="closeDraft"
><up-icon name="close" color="#4B5563" size="20"></up-icon
></view>
</view>
<view class="draftlist" v-if="draftList.length==0">
<div class="nodata">
<up-empty
marginTop="120rpx"
text="草稿箱为空"
mode="list"
:icon="draftImg"
>
</up-empty>
</div>
</view>
<view class="draftlist" v-if="draftList.length>0">
<view
class="cell"
v-for="(item, index) in draftList"
:key="item.draft_id"
>
<view class="title">{{
item.exchange_title ? item.exchange_title : "无标题"
}}</view>
<view class="row" v-if="item.exchange_content">
<view class="smalltitle">病例信息</view>
<view
class="con ellipsis-two-lines"
v-html="fromatImg(item.exchange_content)"
></view>
</view>
<view class="row" v-else-if="item.exchange_summary">
<view class="smalltitle"
>总结与讨论</view
>
<view
class="con ellipsis-two-lines"
v-if="item.exchange_summary"
v-html="fromatImg(item.exchange_summary)"
></view>
</view>
<view
class="sickbox"
v-else-if="item.exchange_label && item.exchange_label.length > 0"
>
<view class="smalltitle" v-if="item.exchange_summary"
>疾病标签</view
>
<view
class="sick"
v-for="cell in item.exchange_label"
:key="cell.label_name"
>{{ cell.label_name }}</view
>
</view>
<view class="row" v-else-if="item.exchange_vote">
<view class="smalltitle">投票</view>
<view class="con ellipsis-two-lines">{{
item.exchange_vote.vote_title
}}</view>
</view>
<view class="deal">
<view class="time">编辑于{{ fromatDay(item.updated_at) }}</view>
<view class="right">
<view class="del" @click="willDelDraft(item.draft_id)"
><up-icon name="trash" color="#4B5563" size="16"></up-icon
>删除</view
>
<view class="edit" @click="editDraft(index)"
><up-icon name="edit-pen" color="#fff" size="17"></up-icon
>编辑</view
>
</view>
</view>
</view>
</view>
</view>
</up-popup>
</div>
<up-popup
:round="10"
zIndex="9"
:show="showTitle"
mode="bottom"
@close="closeTitle"
@open="openTitle"
>
<view class="draftpop titlepop">
<view class="titlebox"
>添加小标题
<view class="close" @click="closeTitle"
><up-icon name="close" color="#4B5563" size="20"></up-icon
></view>
</view>
<view class="con">
<view class="top">
<up-icon
name="plus-circle"
color="#3CC7C0"
size="20"
@click="insertAllWord"
></up-icon>
<view class="desc" @click="insertAllWord">一键添加全部</view>
</view>
<view class="cellbox">
<view class="cell" @click="insertWord('患者信息')">患者信息</view>
<view class="cell" @click="insertWord('主诉')">主诉</view>
<view class="cell" @click="insertWord('现病史及既往史')"
>现病史及既往史</view
>
</view>
<view class="cellbox">
<view class="cell" @click="insertWord('检查')">检查</view>
<view class="cell" @click="insertWord('临床诊断')">临床诊断</view>
<view class="cell" @click="insertWord('治疗经过及结果')"
>治疗经过及结果</view
>
</view>
</view>
</view>
</up-popup>
<up-overlay :show="showModal" mask-click-able>
<view class="zanboxpop">
<view class="zanwraper">
<view class="title">提示</view>
<view class="content" v-if="delType == 'delDraft'">
是否删除该草稿?
</view>
<view class="content" v-else-if="delType == 'saveDraft'">
是否保存该草稿?
</view>
<view class="btnbox">
<view class="cancle" @click="cancelDel">取消</view>
<view class="ok" @click="confirmDel">确定</view>
</view>
</view>
</view>
</up-overlay>
<up-popup
:round="10"
zIndex="9"
:closeOnClickOverlay="false"
:show="showCase"
mode="bottom"
@close="closeCase"
>
<view class="votepop casepop">
<view class="titlebox">
<view class="left" @click="cancelCase">取消</view>
<view class="right" @click="confirmCase">确定</view>
</view>
<view class="stepbox">
<up-steps :current="level-1" direction="column" :key="freshKey">
<up-steps-item >
<template v-slot:content>
<view class="slot-content" @click="openCaseLevel('1')">
<view class="left">{{!caseValue1.label_name?'请选择选项':caseValue1.label_name}}</view>
<u-icon name="arrow-right"></u-icon>
</view>
</template>
</up-steps-item>
<up-steps-item v-if="caseValue1.label_name && labelObj.list2.length>0">
<template v-slot:content>
<view class="slot-content" @click="openCaseLevel('2')">
<view class="left">{{!caseValue2.label_name?'请选择选项':caseValue2.label_name}}</view>
<u-icon name="arrow-right"></u-icon>
</view>
</template>
</up-steps-item>
<up-steps-item v-if="caseValue2.label_name && labelObj.list3.length>0">
<template v-slot:content>
<view class="slot-content" @click="openCaseLevel('3')">
<view class="left">{{!caseValue3.label_name?'请选择选项':caseValue3.label_name}}</view>
<u-icon name="arrow-right"></u-icon>
</view>
</template>
</up-steps-item>
</up-steps>
</view>
<scroll-view class="casecon" scroll-y="true">
<view v-show="level == 1" >
<up-radio-group
v-model="caseValue1.app_iden"
name="group1"
iconPlacement="right"
placement="column"
@change="groupChange1"
>
<view
class="column"
v-for="item in labelObj.list1"
:key="item.app_iden"
>
<up-radio
activeColor="#3CC7C0 "
:label="item.label_name"
:name="item.app_iden"
></up-radio>
</view>
</up-radio-group>
</view>
<view v-show="level == 2" >
<up-radio-group
name="group2"
@change="groupChange2"
v-model="caseValue2.app_iden"
iconPlacement="right"
placement="column"
>
<view
class="column"
v-for="item in labelObj.list2"
:key="item.app_iden"
>
<up-radio
activeColor="#3CC7C0 "
:label="item.label_name"
:name="item.app_iden"
></up-radio>
</view>
</up-radio-group>
</view>
<view v-show="level == 3" >
<up-radio-group
name="group3"
@change="groupChange3"
v-model="caseValue3.app_iden"
iconPlacement="right"
placement="column"
>
<view
class="column"
v-for="item in labelObj.list3"
:key="item.app_iden"
>
<up-radio
activeColor="#3CC7C0 "
:label="item.label_name"
:name="item.app_iden"
></up-radio>
</view>
</up-radio-group>
</view>
</scroll-view>
</view>
</up-popup>
</template>
<script setup>
import { reactive, ref } from "vue";
import backNav from "@/components/backNav/backNav";
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 draftImg from "@/static/draft.png";
import api from "@/api/api";
import dayjs from "dayjs";
import { onLoad } from "@dcloudio/uni-app";
import throttle from "@/utils/throttle"
import svEditor from "@/uni_modules/sv-editor/components/sv-editor/sv-editor.vue";
//import SvEditorToolbar from "@/uni_modules/sv-editor/components/sv-editor/sv-editor-toolbar.vue";
import {
addImage,
addVideo,
addText,
} from "@/uni_modules/sv-editor/components/common/utils.js";
const isLock = ref(false);
const isFlag = ref(false);
const delId = ref("");
const showModal = ref(false);
const delType = ref("delDraft"); //delDraft saveDraft
const isPublish = ref(false);
const exchange_id=ref('');
const bottomHeight=ref(200);
const form = reactive({
exchange_title: "",
exchange_content: "",
exchange_summary: "",
case_exchange_vote: {},
case_exchange_label: [],
});
const voteData = reactive({
vote_title: "",
valid_day: 7,
case_exchange_vote_option: [
{
option_value: "",
},
],
});
const value = ref("");
const showVote = ref(false);
const showDraft = ref(false);
const showTitle = ref(false);
const draftList = ref([]);
const imgList = ref([]);
const videoList = ref([]);
const editorCtx = ref(null);
const editorCtxResult = ref(null);
const isFocusInfo = ref(false);
const isFocusResult = ref(false);
const labelList = ref([]);
const level = ref(1);
const freshKey=ref(0);
const showCase = ref(false);
const canOpenCase = ref(false);
const caseValue1 = reactive({
app_iden:'',
label_name:'',
});
const caseValue2 = reactive({
app_iden:'',
label_name:'',
});
const caseValue3 = reactive({
app_iden:'',
label_name:'',
});
const labelObj = reactive({
list1: [],
list2: [],
list3: []
});
const goBack = () => {
uni.navigateBack({
delta: 1,
});
};
const openDraftList=()=>{
getDraftList();
showDraft.value=true;
}
const epaste=(e)=>{
console.log(e)
}
const alertVote=()=>{
if(exchange_id.value){
uni.showToast({
title: "投票发布后不能编辑",
icon: "none",
})
return false;
}else{
showVote.value = true
}
}
const addOption = () => {
voteData.case_exchange_vote_option.push({
option_value: "",
});
};
const delOption = (index) => {
voteData.case_exchange_vote_option.splice(index, 1);
};
const changeDay = (type) => {
if (type === "minus") {
if (voteData.valid_day <= 1) return;
voteData.valid_day--;
} else if (type === "plus") {
voteData.valid_day++;
}
};
const clearVote = () => {
voteData.vote_title = "";
voteData.case_exchange_vote_option = [
{
option_value: "",
},
];
voteData.valid_day = 7;
form.case_exchange_vote.vote_title = "";
form.case_exchange_vote.case_exchange_vote_option = [
{
option_value: "",
},
];
form.case_exchange_vote.valid_day = 7;
};
const saveVote = () => {
if (voteData.vote_title == "") {
uni.showToast({
title: "请输入投票标题",
icon: "none",
});
return false;
}
if (voteData.vote_title.length > 20) {
uni.showToast({
title: "投票标题不能超过20个字符",
icon: "none",
});
return false;
}
if (voteData.case_exchange_vote_option.length == 0) {
uni.showToast({
title: "请添加投票选项",
icon: "none",
});
return false;
}
// for (let i = 0; i < voteData.case_exchange_vote_option.length; i++) {
// if (voteData.case_exchange_vote_option[i].option_value == "") {
// uni.showToast({
// title: "投票选项不能为空",
// icon: "none",
// });
// return false;
// }
// if (voteData.case_exchange_vote_option[i].option_value.length > 16) {
// uni.showToast({
// title: "第" + (i + 1) + "个投票选项超过16个字符",
// icon: "none",
// });
// return false;
// }
// }
// if (voteData.case_exchange_vote_option.length < 2) {
// uni.showToast({
// title: "至少添加两个选项",
// icon: "none",
// });
// return false;
// }
//Object.assign(form.case_exchange_vote, voteData);
form.case_exchange_vote=voteData
showVote.value = false;
};
const fromatDay = (value) => {
var date = new Date();
var year = date.getFullYear();
let Y = dayjs().format("YYYY");
if (year == Y) {
return dayjs(value).format("MM-DD");
} else {
return dayjs(value).format("YYYY-MM-DD");
}
};
const fromatImg = (val) => {
if(val){
return val.replace(/\<img/gi, '<img class="imgstyle"');
}else{
return '';
}
};
const ready = (e) => {
console.log(e);
editorCtx.value = e;
let html =
"<p>【患者信息】:</p><br/><p>【主诉】:</p><br/><p>【现病史及既往史】:</p><br/><p>【检查】:</p><br/><p>【临床诊断】:</p><br/><p>【治疗经过及结果】:</p><br/><br/>";
editorCtx.value.initHtml(html);
// setTimeout(()=>{
uni.hideKeyboard();
uni.pageScrollTo({
scrollTop:0,
selector:"#form"
// })
})
uni.hideLoading();
};
const readyResult = (e) => {
editorCtxResult.value = e;
setTimeout(()=>{
if(exchange_id.value){
getExchangeDetail(exchange_id.value);
}
})
//editorCtxResult.value.initHtml("")
};
const clearMuBan = () => {
console.log("清空模板");
editorCtx.value.initHtml("");
};
const focusInfo = () => {
isFocusInfo.value = true;
uni.onKeyboardHeightChange(res => {
console.log(res.height);
bottomHeight.value=res.height*2;
editorCtx.value.s
})
};
const blurInfo = () => {
// #ifdef MP-WEIXIN
isFocusInfo.value = false;
// #endif
// #ifdef H5
setTimeout(() => {
isFocusInfo.value = false;
},0)
// #endif
};
const focusResult = () => {
isFocusResult.value = true;
// uni.onKeyboardHeightChange(res => {
// console.log(res.height);
// bottomHeight.value=res.height*2;
// })
};
const blurResult = () => {
isFocusResult.value = false;
};
const closeVote = () => {
showVote.value = false;
};
const openVote = () => {
showVote.value = true;
};
const closeDraft = () => {
showDraft.value = false;
};
const openDraft = () => {
showDraft.value = true;
};
const closeTitle = () => {
showTitle.value = false;
};
const openTitle = () => {
showTitle.value = true;
};
const alertTitle = () => {
if (isFocusInfo.value) {
showTitle.value = true;
}
};
const pFun = (files) => {
uni.showLoading({
title: "正在上传图片...",
mask: true,
});
let promiseFun = [];
for (let i = 0; i < files.length; i++) {
promiseFun.push(handleUpload(files[i]));
}
Promise.all(promiseFun).then((res) => {
uni.hideLoading();
// setTimeout(()=>{
// console.log(imgList.value.length)
// addImage(imgList.value)
// })
});
};
const saveDraft = async () => {
if (isLock.value) return false;
isLock.value = true;
const res = await editorCtx.value.getLastContent();
form.exchange_content = res.html;
const resResult = await editorCtxResult.value.getLastContent();
form.exchange_summary = resResult.html;
if(labelList.value.length>0){
form.case_exchange_label = labelList.value;
}
api.saveDraft(form).then((res) => {
isLock.value = false;
uni.showToast({
title: "保存成功",
icon: "none",
});
getDraftList();
});
};
const getExchangeDetail = (id) => {
api.getExchangeDetail(id).then((res) => {
console.log(res.data.data);
let {
exchange_content,
exchange_title,
exchange_label,
exchange_summary,
exchange_vote,
} = res.data.data;
editorCtx.value.initHtml(exchange_content,async (videoUrl) => {
let res
// #ifdef APP || H5
// res = await this.editorCtx.createVideoThumbnail(videoUrl)
// #endif
const fox = 'https://cn.bing.com//th?id=OHR.FlamingosNamibia_ZH-CN3639748956_1920x1080.jpg'
res = await editorCtx.value.createCoverThumbnail(fox)
return res
});
form.exchange_content = exchange_content;
form.exchange_title = exchange_title;
form.case_exchange_label = exchange_label? exchange_label:[];
labelList.value = exchange_label?exchange_label:[];
form.exchange_summary = exchange_summary;
form.case_exchange_vote = exchange_vote;
editorCtxResult.value.initHtml(exchange_summary,async (videoUrl) => {
let res
// #ifdef APP || H5
// res = await this.editorCtx.createVideoThumbnail(videoUrl)
// #endif
const fox = 'https://cn.bing.com//th?id=OHR.FlamingosNamibia_ZH-CN3639748956_1920x1080.jpg'
res = await editorCtxResult.value.createCoverThumbnail(fox)
return res
});
Object.assign(voteData, exchange_vote);
});
};
const editDraft = (index) => {
let draft = draftList.value[index];
let {
exchange_content,
exchange_title,
exchange_label,
exchange_summary,
exchange_vote,
} = draft;
editorCtx.value.initHtml(exchange_content);
form.exchange_content = exchange_content;
form.exchange_title = exchange_title;
form.case_exchange_label = exchange_label;
labelList.value = exchange_label;
form.exchange_summary = exchange_summary;
form.case_exchange_vote = exchange_vote;
editorCtxResult.value.initHtml(exchange_summary);
Object.assign(voteData, exchange_vote);
showDraft.value = false;
};
const willDelDraft = (id) => {
delId.value = id;
delType.value = "delDraft";
showModal.value = true;
};
const confirmDel = () => {
showModal.value = false;
console.log(delType.value);
if (delType.value == "delDraft") {
delDraft(delId.value);
} else if (delType.value == "saveDraft") {
saveDraft();
}
};
const cancelDel = () => {
showModal.value = false;
if (delType.value == "saveDraft") {
goBack();
}
};
const delDraft = (id) => {
api.delDraft(id).then((res) => {
uni.showToast({
title: "删除成功",
icon: "none",
});
});
getDraftList();
};
const alertSave = async () => {
if(isPublish.value || exchange_id.value){
goBack()
}else{
const res = await editorCtx.value.getLastContent();
const initInfo =
"<p>【患者信息】:</p><br/><p>【主诉】:</p><br/><p>【现病史及既往史】:</p><br/><p>【检查】:</p><br/><p>【临床诊断】:</p><br/><p>【治疗经过及结果】:</p>";
//let html = editorCtx.value.exportHtml(res.html);
//const initInfo= "<p>【患者信息】:</p><br/><p>【主诉】:</p><br/><p>【现病史及既往史】:</p><br/><p>【检查】:</p><br/><p>【临床诊断】:</p><br/><p>【治疗经过及结果】:</p><br/><br/>";
const resContent = await editorCtxResult.value.getLastContent();
//let reshtml = editorCtxResult.value.exportHtml(resContent.html);
if (
form.exchange_title ||
res.html!=initInfo ||
resContent.text ||
(form.case_exchange_vote &&
form.case_exchange_vote.vote_title &&
form.case_exchange_label &&
form.case_exchange_label.length > 0)
) {
delType.value = "saveDraft";
showModal.value = true;
} else {
goBack();
}
}
};
const publish =throttle(async () => {
console.log(3333);
const initInfo =
"<p>【患者信息】:</p><br/><p>【主诉】:</p><br/><p>【现病史及既往史】:</p><br/><p>【检查】:</p><br/><p>【临床诊断】:</p><br/><p>【治疗经过及结果】:</p>";
if (form.exchange_title == "") {
uni.showToast({
title: "请输入标题",
icon: "none",
});
return false;
}
if(form.exchange_title.length>40){
uni.showToast({
title: "标题不超过40个字",
icon: "none",
});
return false;
}
const res = await editorCtx.value.getLastContent();
let html = editorCtx.value.exportHtml(res.html);
if (html == initInfo) {
uni.showToast({
title: "请编辑病例信息",
icon: "none",
});
return false;
}
if (!(form.case_exchange_vote && form.case_exchange_vote.vote_title)) {
delete form.case_exchange_vote;
}
if (
!form.case_exchange_label ||
(form.case_exchange_label && form.case_exchange_label.length == 0)
) {
delete form.case_exchange_label;
}
form.case_exchange_label = labelList.value;
if(isLock.value) return false;
isFlag.value = true;
form.exchange_content = html;
const resContent = await editorCtxResult.value.getLastContent();
let reshtml = editorCtxResult.value.exportHtml(resContent.html);
form.exchange_summary = reshtml=="<p><br></p>"?'':reshtml;
if(exchange_id.value){
api.updateExchange(exchange_id.value,form).then((res) => {
uni.showToast({
title: "修改成功",
icon: "none",
duration: 2000,
});
isFlag.value = false;
isPublish.value = true;
uni.navigateBack()
});
}else{
api.addExchange(form).then((res) => {
uni.showToast({
title: "发布成功",
icon: "none",
duration: 2000,
});
isFlag.value = false;
isPublish.value = true;
uni.navigateBack()
});
}
});
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;
imgList.value.push(url);
addImage([url]);
}
},
fail: (err) => {
console.log(err);
},
});
});
}
});
};
const insertWord = (word) => {
addText(word);
showTitle.value = false;
};
const insertAllWord = () => {
let word = [
"患者信息",
"主诉",
"现病史及既往史:",
"检查",
"临床诊断",
"治疗经过及结果",
];
word.forEach((item) => {
addText(item);
});
showTitle.value = false;
};
const generateRandomNumber = () => {
let randomNumber = Math.floor(1000 + Math.random() * 9000);
return randomNumber;
};
const getImageFormat = (imageUrl) => {
console.log(imageUrl);
const lastDotIndex = imageUrl.lastIndexOf(".");
if (lastDotIndex !== -1) {
return imageUrl.substring(lastDotIndex + 1);
}
return "unknown";
};
const insertImage = (file) => {
if (!(!isFocusInfo.value && !isFocusResult.value)) {
uni.chooseImage({
count: 9, //默认9
sizeType: ["original", "compressed"], //可以指定是原图还是压缩图,默认二者都有
sourceType: ["album"], //从相册选择
extension: [".jpg", ".png", ".jpeg"],
success: function (res) {
pFun(res.tempFilePaths);
},
});
}
};
const insertVideo = (file) => {
if (!(!isFocusInfo.value && !isFocusResult.value)) {
uni.chooseVideo({
count: 5, //默认9//可以指定是原图还是压缩图,默认二者都有
sourceType: ["album"], //从相册选择
extension: [".mp4", ".webm", ".ogg"],
success: function (res) {
console.log(res.tempFilePath);
HandleAddVideo(res.tempFilePath);
//pFun([res.tempFilePath], "video");
},
});
}
};
const HandleAddVideo = async (file) => {
uni.showLoading({
title: "正在上传视频...",
mask: true,
});
const videos = await addVideo(async (editorCtx) => {
return new Promise((resolve) => {
api
.getOss({
scene:2,
})
.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((res, reject) => {
uni.uploadFile({
url: host, // 仅为示例,非真实的接口地址
filePath: file,
name: "file",
formData: {
OSSAccessKeyId: access_id,
policy,
key: dir + time + random + imgType,
signature,
},
async success(res) {
if (res.statusCode === 204) {
let url = host + "/" + dir + filename + imgType;
console.log(editorCtx);
let imgUrl =
"https://cn.bing.com//th?id=OHR.FlamingosNamibia_ZH-CN3639748956_1920x1080.jpg";
const fileThumbnail = await editorCtx.createCoverThumbnail(
imgUrl
);
resolve([
{
videoUrl: url,
videoImg: fileThumbnail,
},
]);
}
},
fail: (err) => {
console.log(err);
},
});
});
}
});
});
});
if (videos) {
uni.showLoading();
uni.showToast({ title: "添加视频成功", icon: "success" });
} else {
uni.showToast({ title: "添加视频失败", icon: "error" });
}
};
const getDraftList = () => {
api.getDraftList().then((res) => {
draftList.value = res.data.data.data;
});
};
const openCaseLevel=(lev)=>{
freshKey.value++;
level.value=lev;
if(lev==1){
caseValue2.label_name='';
caseValue2.app_iden='';
labelObj.list2=[]
}else if(lev==2){
labelObj.list3=[];
caseValue3.label_name='';
caseValue3.app_iden=''
}
};
const groupChange1=(e)=>{
caseValue1.app_iden=e;
for (var i = 0; i <labelObj.list1.length; i++) {
if(labelObj.list1[i].app_iden==caseValue1.app_iden){
caseValue1.label_name=labelObj.list1[i].label_name;
break;
}
}
console.log(caseValue1);
getCaseLabel(2,e)
}
const groupChange2=(e)=>{
caseValue2.app_iden=e;
for (var i = 0; i <labelObj.list2.length; i++) {
if(labelObj.list2[i].app_iden==caseValue2.app_iden){
caseValue2.label_name=labelObj.list2[i].label_name;
break;
}
}
getCaseLabel(3,e)
}
const groupChange3=(e)=>{
caseValue3.app_iden=e;
level.value =3
for (var i = 0; i <labelObj.list3.length; i++) {
if(labelObj.list3[i].app_iden==caseValue3.app_iden){
caseValue3.label_name=labelObj.list3[i].label_name;
break;
}
}
}
const getCaseLabel = (lev,pid=0) => {
api.getCaseLabel({
pId:pid
}).then((res) => {
level.value = lev;
if (lev == 1) {
labelObj.list1 = res.data.data;
//label_iden.value = caseValue1.value;
} else if (lev == 2) {
labelObj.list2 = res.data.data;
if(res.data.data.length==0){
level.value = 1
}
//label_iden.value = caseValue2.value;
} else if (lev == 3) {
labelObj.list3 = res.data.data;
if(res.data.data.length==0){
level.value = 2
}
//label_iden.value = caseValue3.value;
}
});
};
const openCase=()=>{
showCase.value = true;
}
const cancelCase=()=>{
showCase.value = false;
}
const clearCase=()=>{
level.value=1;
caseValue1.app_iden='';
caseValue1.label_name='';
caseValue2.app_iden='';
caseValue2.label_name='';
caseValue3.app_iden='';
caseValue3.label_name='';
labelObj.list2=[];
labelObj.list3=[];
freshKey.value++;
}
const confirmCase = () => {
if (level.value == 1 && caseValue1.app_iden == "") {
uni.showToast({ title: "请选择疾病选项", icon: "none" });
return false;
};
if(level.value == 1){
let {app_iden,label_name}=caseValue1;
labelList.value.push({
app_iden,
label_name
});
}else if(level.value == 2 ){
if(!caseValue2.app_iden){
let {app_iden,label_name}=caseValue1;
labelList.value.push({
app_iden,
label_name
});
}else{
let {app_iden,label_name}=caseValue2;
labelList.value.push({
app_iden,
label_name
});
}
}else if(level.value == 3 ){
if(!caseValue3.app_iden){
let {app_iden,label_name}=caseValue2;
labelList.value.push({
app_iden,
label_name
});
}else{
let {app_iden,label_name}=caseValue3;
labelList.value.push({
app_iden,
label_name
});
}
}
labelList.value=labelList.value.filter((item, index) => labelList.value.findIndex(i => i.app_iden === item.app_iden) === index);
console.log(labelList.value);
showCase.value=false;
};
const closeCase = () => {
showCase.value = false;
};
const delLabel = (index) => {
labelList.value.splice(index, 1);
};
const openLabelPop=()=>{
if(labelList.value.length>=5){
uni.showToast({ title: "最多添加5个标签", icon: "none" });
return false;
}
clearCase();
showCase.value=true;
getCaseLabel(1,0);
}
onLoad((optoions) => {
uni.showLoading({
title: "正在加载中...",
mask: true,
});
if(optoions.exchange_id){
exchange_id.value=optoions.exchange_id;
console.log(1111)
console.log(exchange_id.value)
}
//getDraftList();
});
// const previewImg = () => {
// uni.previewImage({
// current: "https://example.com/image1.jpg",
// urls: ["https://example.com/image1.jpg", "https://example.com/image2.jpg"],
// });
// };
</script>
<style lang='scss' scoped>
.stepbox{
padding:15rpx 30rpx;
border-bottom: 2rpx dotted #f3f4f6;
:deep(.u-steps-item__content){
margin-top: -5rpx!important;
}
.slot-content{
width:100%;
margin-bottom: 25rpx;
justify-content: space-between;
align-items: center;
display: flex;
}
}
.casepop{
display: flex;
flex-direction: column;
max-height: calc(100vh - 400rpx);
.continue{
color: #2878ff !important;
}
}
.casecon {
flex:1;
overflow-y: scroll;
padding-top: 10rpx;
max-height: calc(100vh - 700rpx);
min-height: 350rpx;
padding-bottom: 20rpx;
:deep(.u-radio){
margin-bottom: 10px!important;
margin-top: 0px!important;
}
.casePadding{
padding-bottom: 0rpx;
}
.column {
padding: 0 30rpx;
border-bottom: 2rpx solid #e5e7eb;
}
}
.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;
justify-content: center;
margin: 0rpx 30rpx 0rpx;
position: relative;
display: flex;
.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;
}
}
}
}
.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;
}
}
}
}
.titlepop {
.top {
display: flex;
align-items: center;
justify-content: flex-end;
margin: 0 30rpx;
margin-bottom: 30rpx;
font-size: 30rpx;
color: #3cc7c0;
}
.con {
padding-bottom: 50rpx;
}
.cellbox {
margin: 20rpx 30rpx;
display: flex;
justify-content: space-between;
.cell {
width: 200rpx;
height: 60rpx;
border-radius: 25rpx;
display: flex;
justify-content: center;
align-items: center;
background: #e5e7eb78;
font-size: 24rpx;
}
}
}
#editor {
padding: 0 10rpx;
height: calc(100vh - 700rpx);
}
#editorRes {
height: 600rpx;
:deep(.sv-editor-wrapper) {
flex: 1;
min-height: 300rpx;
}
}
.myVideo {
width: 100%;
border-radius: 15rpx;
}
.imgbox {
margin: 0 30rpx 30rpx;
position: relative;
.close {
position: absolute;
top: 0rpx;
right: 0;
z-index: 9999;
}
.imgunit {
width: 150rpx;
height: 150rpx;
position: relative;
.close {
position: absolute;
top: 0rpx;
right: 0;
}
}
}
.draftpop {
.titlebox {
text-align: center;
padding: 30rpx;
font-size: 31rpx;
color: #111827;
position: relative;
.close {
position: absolute;
top: 20rpx;
right: 30rpx;
}
}
.draftlist {
height: calc(100vh - 500rpx);
overflow-y: scroll;
.cell {
padding-bottom: 34rpx;
border-bottom: 2rpx solid #e5e7eb;
.title {
margin: 15rpx 30rpx 0;
font-size: 36rpx;
color: #111827;
line-height: 46rpx;
}
.smalltitle {
margin: 4px 0rpx 0;
font-size: 30rpx;
color: #666666;
line-height: 38rpx;
}
.con {
font-size: 30rpx;
color: #666666;
line-height: 38rpx;
font-size: 30rpx;
color: #666666;
line-height: 38rpx;
}
.deal {
margin: 36rpx 30rpx 0;
display: flex;
justify-content: space-between;
align-items: center;
.time {
font-size: 26rpx;
color: #9ca3af;
}
.right {
display: flex;
align-items: center;
}
.del {
width: 138rpx;
height: 62rpx;
background: #f3f4f6;
display: flex;
border-radius: 20rpx;
align-items: center;
font-size: 27rpx;
color: #4b5563;
justify-content: center;
}
.edit {
margin-left: 23rpx;
display: flex;
align-items: center;
justify-content: center;
width: 192rpx;
height: 62rpx;
font-size: 27rpx;
color: #ffffff;
background: #3cc7c0;
border-radius: 20rpx;
}
}
}
}
}
.expire {
margin-top: 46rpx;
padding: 0 30rpx;
display: flex;
align-items: center;
justify-content: space-between;
.name {
font-size: 31rpx;
color: #111827;
}
.right {
display: flex;
align-items: center;
.day {
min-width: 50rpx;
text-align: center;
}
.minus {
width: 62rpx;
height: 62rpx;
display: flex;
align-items: center;
justify-content: center;
background: #f5f5f5;
border-radius: 50%;
font-size: 50rpx;
}
.plus {
display: flex;
align-items: center;
font-size: 50rpx;
justify-content: center;
width: 62rpx;
height: 62rpx;
background: #f5f5f5;
border-radius: 50%;
}
}
}
.row {
padding: 0 30rpx;
margin-bottom: 23rpx;
:deep(.u-input) {
background: #f5f5f5;
}
:deep(.u-input--radius) {
border-radius: 15rpx;
}
:deep(.u-input__content__field-wrapper__field) {
height: 92rpx;
}
}
.first {
margin-bottom: 47rpx;
}
.votepop {
.confirm {
margin: 39rpx 30rpx 0;
height: 92rpx;
background: #3cc7c0;
border-radius: 15rpx;
display: flex;
align-items: center;
font-size: 31rpx;
color: #ffffff;
justify-content: center;
}
.del {
margin: 30rpx 30rpx 30rpx;
height: 92rpx;
background: #fff;
border-radius: 15rpx;
font-size: 31rpx;
color: #666666;
display: flex;
align-items: center;
justify-content: center;
}
.tips {
margin-top: 30rpx;
font-size: 27rpx;
color: #9ca3af;
line-height: 38rpx;
padding: 0 30rpx;
}
.add {
margin: 0 30rpx;
display: flex;
align-items: center;
height: 92rpx;
justify-content: center;
background: #f5f5f5;
border-radius: 15rpx;
font-size: 31rpx;
color: #4b5563;
.desc {
margin-left: 10rpx;
}
}
.titlebox {
padding: 0 30rpx;
height: 86rpx;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 2rpx solid #f3f4f6;
.left {
font-size: 31rpx;
color: #4b5563;
}
.right {
font-size: 31rpx;
color: #3cc7c0;
}
}
.votecon {
max-height: calc(100vh - 530rpx);
overflow-y: scroll;
.row {
display: flex;
align-items: center;
.iconbox {
margin-left: 15rpx;
align-items: center;
}
}
.titlebox {
border: none;
margin: 30rpx 0 20rpx;
.title {
font-size: 31rpx;
color: #111827;
}
.desc {
font-size: 27rpx;
color: #9ca3af;
}
}
}
}
.upage {
display: flex;
flex-direction: column;
height: 100vh;
position: relative;
: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;
}
}
.cell.active {
opacity: 0.65;
}
}
.bottom {
position: fixed;
bottom: 0;
width: 100%;
z-index: 3;
background: #ffffff;
.bottombtn {
display: flex;
align-items: center;
border-top: 2rpx solid #e5e7eb;
height: 133rpx;
}
.right {
margin-right: 30rpx;
flex: 1;
margin-left: 32rpx;
height: 86rpx;
background: #3cc7c0;
border-radius: 23rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 31rpx;
color: #ffffff;
}
.left {
margin-left: 30rpx;
display: flex;
.draft {
width: 162rpx;
height: 86rpx;
background: rgba(0, 0, 0, 0);
border-radius: 16rpx;
border: 2rpx solid #e5e7eb;
display: flex;
align-items: center;
justify-content: center;
}
.vote {
margin-left: 25rpx;
width: 162rpx;
height: 86rpx;
background: rgba(0, 0, 0, 0);
border-radius: 16rpx;
border: 2rpx solid #e5e7eb;
display: flex;
align-items: center;
justify-content: center;
}
}
}
.form {
height: calc(100vh - 133rpx);
margin: -20rpx 0rpx 0rpx;
padding-bottom: 0rpx;
overflow-y: scroll;
.sickbox {
display: flex;
padding: 25rpx 25rpx 10rpx;
margin-bottom: 20rpx;
flex-wrap:wrap;
}
.add {
display: flex;
font-size: 26rpx;
justify-content: center;
align-items: center;
color: #3cc7c0;
margin-bottom: 10rpx;
margin-left: 18rpx;
}
.sick {
position: relative;
padding: 0 60rpx 0 30rpx;
height: 60rpx;
margin-bottom: 10rpx;
white-space: nowrap;
display: flex;
margin-right: 10rpx;
justify-content: center;
align-items: center;
background: #f9f9f9;
border-radius: 40rpx;
font-size: 25rpx;
color: #3cc7c0;
.del {
position: absolute;
right: 12rpx;
}
}
.textcon {
border-bottom: 2rpx solid #f3f4f6;
}
.textbox {
padding: 0 30rpx;
border-bottom: 2rpx solid #f3f4f6;
:deep(.u-textarea__field) {
min-height: 55rpx !important;
}
}
.textcell {
padding: 0 30rpx;
margin-top: 25rpx;
.titlebox {
display: flex;
align-items: center;
justify-content: space-between;
}
}
.row {
padding: 30rpx 30rpx 0;
display: flex;
justify-content: space-between;
align-items: center;
.left {
font-size: 38rpx;
color: #000000;
.tip {
color: #9ca3af;
font-size: 32rpx;
}
}
.right {
display: flex;
align-items: center;
color: #6b7280;
font-size: 31rpx;
}
}
}
:deep(.ql-container){
padding-bottom: 25rpx;
height: calc(100vh - 700rpx);
}
:deep(.ql-container) img{
max-width:100%;
position: relative;
left:50%;
transform: translateX(-50%);
}
:deep(.ql-container) image{
max-width:100%;
position: relative;
left:50%;
transform: translateX(-50%);
}
.con {
:deep(.imgstyle){
max-width: 100%;
}
}
/* #ifdef H5 */
:deep(.ql-editor){
position: absolute;
top: 0;
bottom: 0;
width:100%;
}
/* #endif */
</style>