- CSDN文库",
"datePublished": "2025-07-20",
"keywords": "以下代碼在content-display的部份在footer增加一個切換按鈕,除了原本顯示格式外,可切換成帶有html標籤的格式:
以下代碼在content-display的部份在footer增加一個切換按鈕,除了原本顯示格式外,可切換成帶有html標籤的格式:
<template>
<div>
<div>
<div class="wangeditor">
<WangEditor v-model="content" @response="(msg) => content = msg" />
</div>
<div class="right-panel">
<mreditor1 ref="mreditor1" />
</div>
</div>
<div v-if="isVisible" class="content-display" v-html="highlightedContent"></div>
<footer class="sticky-footer">
<span><button @click="toggleContent">顯示/隱藏標籤</button></span>
<span><button @click="resetAll" class="reset-btn">輸入新醫案</button></span>
<!-- 新增ID输入框和获取按钮 -->
<span class="id-input">
<input v-model="fetchId" placeholder="輸入醫案ID" type="number" min="1" />
<button @click="fetchById">獲取醫案</button>
</span>
<!-- 操作按钮组 -->
<span v-if="submittedId">
<button @click="updateContent" class="update-btn">更新醫案</button>
<button @click="deleteContent" class="delete-btn">刪除醫案</button>
</span>
<span v-else>
<button @click="submitContent" class="submit-btn">提交醫案</button>
</span>
<span v-if="submittedId" class="submitted-id">醫案 ID: {{ submittedId }}</span>
<span>醫案編輯器</span>
</footer>
</div>
</template>
<script>
import WangEditor from './WangEditor.vue';
import mreditor1 from './mreditor1.vue';
export default {
components: {
WangEditor,
mreditor1
},
data() {
return {
content: '',
isVisible: true,
submittedId: null,
fetchId: null,
dnTags: [] // 存储从API获取的标签数据
};
},
computed: {
// 计算高亮后的内容
highlightedContent() {
if (!this.dnTags.length || !this.content) return this.content;
// 创建临时DOM元素处理高亮
const tempEl = document.createElement('div');
tempEl.innerHTML = this.content;
// 遍历所有文本节点
const walker = document.createTreeWalker(
tempEl,
NodeFilter.SHOW_TEXT
);
const nodes = [];
while (walker.nextNode()) {
nodes.push(walker.currentNode);
}
// 对每个文本节点进行处理
nodes.forEach(node => {
let text = node.nodeValue;
let newHtml = text;
// 对每个标签进行高亮处理(按长度降序排序,避免短标签优先匹配)
this.dnTags
.slice()
.sort((a, b) => b.length - a.length)
.forEach(tag => {
const regex = new RegExp(
escapeRegExp(tag),
'g'
);
newHtml = newHtml.replace(
regex,
`<span style="color: rgb(212, 107, 8); font-weight: bold;">${tag}</span>`
);
});
// 如果内容有变化则替换节点
if (newHtml !== text) {
const span = document.createElement('span');
span.innerHTML = newHtml;
node.parentNode.replaceChild(span, node);
}
});
return tempEl.innerHTML;
}
},
async mounted() {
// 组件挂载时获取标签数据
await this.fetchDNTags();
},
methods: {
// 获取标签数据
async fetchDNTags() {
try {
const response = await fetch('DNTag/?format=json');
const data = await response.json();
this.dnTags = data
.map(item => item.dnname)
.filter(name => name && name.trim().length > 0);
} catch (error) {
console.error('获取标签失败:', error);
alert('标签数据加载失败,高亮功能不可用');
}
},
// 通过ID获取医案数据
async fetchById() {
if (!this.fetchId) {
alert('請輸入有效的醫案ID');
return;
}
try {
const response = await fetch(`MRInfo/${this.fetchId}/?format=json`);
if (response.ok) {
const data = await response.json();
// 填充表单数据
this.$refs.mreditor1.formData.mrname = data.mrname || '';
this.$refs.mreditor1.formData.mrposter = data.mrposter || '';
this.content = data.mrcase || '';
this.submittedId = data.id;
this.fetchId = null; // 清空输入框
// 刷新标签数据
await this.fetchDNTags();
alert('醫案數據加載成功!');
} else if (response.status === 404) {
alert('未找到該ID的醫案');
} else {
throw new Error('獲取醫案失敗');
}
} catch (error) {
console.error('Error:', error);
alert(`獲取醫案失敗: ${error.message}`);
}
},
// 提交医案
async submitContent() {
const formData = this.$refs.mreditor1.getFormData();
const postData = {
mrcase: this.content,
...formData
};
try {
const response = await fetch('MRInfo/?format=json', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(postData),
});
if(response.ok) {
const data = await response.json();
this.submittedId = data.id;
alert('醫案提交成功!');
} else {
throw new Error('提交失败');
}
} catch (error) {
console.error('Error:', error);
alert(`提交失败: ${error.message}`);
}
},
// 更新医案
async updateContent() {
if (!this.submittedId) return;
const formData = this.$refs.mreditor1.getFormData();
const postData = {
mrcase: this.content,
...formData
};
try {
const response = await fetch(`MRInfo/${this.submittedId}/?format=json`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(postData),
});
if (response.ok) {
alert('醫案更新成功!');
} else {
throw new Error('更新失败');
}
} catch (error) {
console.error('Error:', error);
alert(`更新失败: ${error.message}`);
}
},
// 删除医案
async deleteContent() {
if (!this.submittedId) return;
if (!confirm('確定要刪除這個醫案嗎?')) return;
try {
const response = await fetch(`MRInfo/${this.submittedId}/?format=json`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
}
});
if (response.ok) {
this.resetAll();
alert('醫案刪除成功!');
} else {
throw new Error('刪除失败');
}
} catch (error) {
console.error('Error:', error);
alert(`刪除失败: ${error.message}`);
}
},
// 重置表单
resetAll() {
this.content = '';
this.submittedId = null;
this.fetchId = null;
this.$refs.mreditor1.resetForm();
},
// 切换内容显示
toggleContent() {
this.isVisible = !this.isVisible;
}
}
};
// 辅助函数:转义正则特殊字符
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
</script>
<style scoped>
/* 原有样式保持不变 */
.wangeditor {
flex: 1;
padding: 10px;
overflow-y: auto;
}
.right-panel {
position: fixed;
top: 56px;
bottom: 45px;
right: 0;
width: 30%;
background: white;
padding: 10px;
z-index: 100;
overflow-y: auto;
}
.content-display {
position: fixed;
top: 570px;
left: 0;
width: 70%;
bottom: 45px;
z-index: 999;
background-color: white;
overflow-y: auto;
padding: 10px;
border: 1px solid #eee;
}
.sticky-footer {
display: flex;
justify-content: flex-end;
align-items: center;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
background-color: #ffd800ff;
z-index: 999;
padding: 10px 20px;
box-sizing: border-box;
flex-wrap: wrap;
}
.sticky-footer > span {
margin-left: 5px;
display: flex;
align-items: center;
}
.submitted-id {
padding: 2px;
background-color: #e2f0fd;
color: #004085;
border-radius: 4px;
}
.reset-btn {
margin-left: 10px;
padding: 2px;
background-color: #dc3545;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.reset-btn:hover {
background-color: #c82333;
}
/* 新增ID输入框样式 */
.id-input {
display: flex;
align-items: center;
}
.id-input input {
width: 100px;
padding: 2px 5px;
margin-right: 5px;
border: 1px solid #ccc;
border-radius: 4px;
}
/* 操作按钮样式 */
.submit-btn {
background-color: #28a745;
color: white;
border: none;
padding: 2px 8px;
border-radius: 4px;
cursor: pointer;
}
.update-btn {
background-color: #007bff;
color: white;
border: none;
padding: 2px 8px;
border-radius: 4px;
cursor: pointer;
}
.delete-btn {
background-color: #dc3545;
color: white;
border: none;
padding: 2px 8px;
border-radius: 4px;
cursor: pointer;
}
.submit-btn:hover {
background-color: #218838;
}
.update-btn:hover {
background-color: #0069d9;
}
.delete-btn:hover {
background-color: #c82333;
}
</style>