"虽千万人吾往矣"出处

《孟子》中提到,只要自己站在正义的一方,即使面对强大的敌人也应勇往直前。此引言强调了正义和个人勇气的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<孟子>:“自反而不缩,虽褐宽博,吾不惴焉。自反而缩,虽千万人吾往矣”
“自反而缩,虽千万人吾往矣”意思是:反躬自问,正义确实在我手里,就算对方有千军万马,我也要勇往直前

以下mreditor.vue從MRInfo/?format=json獲得的mrorigin(醫案出處)及mrdoctor(醫案醫者)字段給予輸入欄位,比照mrname的功能式樣, mreditor.vue: <template> <div> <div> <div class=&quot;wangeditor&quot;> <WangEditor v-model=&quot;content&quot; @response=&quot;(msg) => content = msg&quot; /> </div> <div class=&quot;up-panel&quot;> <div class=&quot;tag-panel&quot;> <mrdncrud v-if=&quot;showDnCrud&quot; @tag-updated=&quot;handleDnTagUpdated&quot; /> <mrmncrud v-if=&quot;showMnCrud&quot; @tag-updated=&quot;handleMnTagUpdated&quot; /> <mrsncrud v-if=&quot;showSnCrud&quot; @tag-updated=&quot;handleSnTagUpdated&quot; /> <mrpncrud v-if=&quot;showPnCrud&quot; @tag-updated=&quot;handlePnTagUpdated&quot; /> <!-- 新增物编辑面板 --> <mrfncrud v-if=&quot;showFnCrud&quot; @tag-updated=&quot;handleFnTagUpdated&quot; /> </div> <div class=&quot;crud-buttons&quot;> <button @click=&quot;toggleDnCrud&quot; class=&quot;fixed-dncrud-btn&quot;> {{ showDnCrud ? '病態編輯' : '病態編輯' }} </button> <button @click=&quot;toggleMnCrud&quot; class=&quot;fixed-mncrud-btn&quot;> {{ showMnCrud ? '本草編輯' : '本草編輯' }} </button> <button @click=&quot;toggleSnCrud&quot; class=&quot;fixed-sncrud-btn&quot;> {{ showSnCrud ? '典籍編輯' : '典籍編輯' }} </button> <button @click=&quot;togglePnCrud&quot; class=&quot;fixed-pncrud-btn&quot;> {{ showPnCrud ? '方劑編輯' : '方劑編輯' }} </button> <!-- 新增物编辑按钮 --> <button @click=&quot;toggleFnCrud&quot; class=&quot;fixed-fncrud-btn&quot;> {{ showFnCrud ? '物編輯' : '物編輯' }} </button> </div> </div> <div class=&quot;right-panel&quot;> <!-- 病态名称显示区域(带颜色) --> <div class=&quot;dntag-display&quot; v-if=&quot;currentDnTags.length&quot;> <div class=&quot;field-name&quot;>相關病態:</div> <div class=&quot;dntag-value&quot;> <span v-for=&quot;(tag, index) in currentDnTags&quot; :key=&quot;'dn-'+index&quot; class=&quot;dn-tag&quot; style=&quot;color: rgb(212, 107, 8);&quot;> {{ tag }}<span v-if=&quot;index < currentDnTags.length - 1&quot;>;</span> </span> </div> </div> <div class=&quot;dntag-display&quot; v-else> <div class=&quot;field-name&quot;>相關病態:</div> <div class=&quot;dntag-value&quot;>無關聯病態名稱</div> </div> <!-- 草本名称显示区域(带颜色) --> <div class=&quot;mntag-display&quot; v-if=&quot;currentMnTags.length&quot;> <div class=&quot;field-name&quot;>相關本草:</div> <div class=&quot;mntag-value&quot;> <span v-for=&quot;(tag, index) in currentMnTags&quot; :key=&quot;'mn-'+index&quot; class=&quot;mn-tag&quot; style=&quot;color: rgb(0, 128, 0);&quot;> {{ tag }}<span v-if=&quot;index < currentMnTags.length - 1&quot;>;</span> </span> </div> </div> <div class=&quot;mntag-display&quot; v-else> <div class=&quot;field-name&quot;>相關本草:</div> <div class=&quot;mntag-value&quot;>無關聯本草名稱</div> </div> <!-- 出处名称显示区域(带颜色) --> <div class=&quot;sntag-display&quot; v-if=&quot;currentSnTags.length&quot;> <div class=&quot;field-name&quot;>相關典籍:</div> <div class=&quot;sntag-value&quot;> <span v-for=&quot;(tag, index) in currentSnTags&quot; :key=&quot;'sn-'+index&quot; class=&quot;sn-tag&quot; style=&quot;color: rgb(51, 102, 255);&quot;> {{ tag }}<span v-if=&quot;index < currentSnTags.length - 1&quot;>;</span> </span> </div> </div> <div class=&quot;sntag-display&quot; v-else> <div class=&quot;field-name&quot;>相關典籍:</div> <div class=&quot;sntag-value&quot;>無關聯典籍名稱</div> </div> <!-- 方剂名称显示区域(带颜色) --> <div class=&quot;pntag-display&quot; v-if=&quot;currentPnTags.length&quot;> <div class=&quot;field-name&quot;>相關方劑:</div> <div class=&quot;pntag-value&quot;> <span v-for=&quot;(tag, index) in currentPnTags&quot; :key=&quot;'pn-'+index&quot; class=&quot;pn-tag&quot; style=&quot;color: rgb(138, 43, 226);&quot;> {{ tag }}<span v-if=&quot;index < currentPnTags.length - 1&quot;>;</span> </span> </div> </div> <div class=&quot;pntag-display&quot; v-else> <div class=&quot;field-name&quot;>相關方劑:</div> <div class=&quot;pntag-value&quot;>無關聯方劑名稱</div> </div> <!-- 新增物名称显示区域(带颜色) --> <div class=&quot;fntag-display&quot; v-if=&quot;currentFnTags.length&quot;> <div class=&quot;field-name&quot;>相關物:</div> <div class=&quot;fntag-value&quot;> <span v-for=&quot;(tag, index) in currentFnTags&quot; :key=&quot;'fn-'+index&quot; class=&quot;fn-tag&quot; style=&quot;color: rgb(139, 69, 19);&quot;> {{ tag }}<span v-if=&quot;index < currentFnTags.length - 1&quot;>;</span> </span> </div> </div> <div class=&quot;fntag-display&quot; v-else> <div class=&quot;field-name&quot;>相關物:</div> <div class=&quot;fntag-value&quot;>無關聯物名稱</div> </div> </div> </div> <div class=&quot;content-display&quot; v-html=&quot;displayContent&quot;></div> <footer class=&quot;sticky-footer&quot;> <!-- 医案命名和提交者输入框 --> <span class=&quot;form-input&quot;> <input v-model=&quot;formData.mrname&quot; placeholder=&quot;醫案命名&quot; class=&quot;name-input&quot; /> </span> <span class=&quot;form-input&quot;> <input v-model=&quot;formData.mrposter&quot; placeholder=&quot;提交者姓名&quot; class=&quot;poster-input&quot; /> </span> <span><button @click=&quot;toggleDisplayFormat&quot;>{{ displayButtonText }}</button></span> <span><button @click=&quot;resetAll&quot; class=&quot;reset-btn&quot;>輸入新醫案</button></span> <span class=&quot;id-input&quot;> <input v-model=&quot;fetchId&quot; placeholder=&quot;輸入醫案ID&quot; type=&quot;number&quot; min=&quot;1&quot; /> <button @click=&quot;fetchById&quot;>載入醫案</button> </span> <span v-if=&quot;submittedId&quot;> <button @click=&quot;updateContent&quot; class=&quot;update-btn&quot;>更新醫案</button> <button @click=&quot;deleteContent&quot; class=&quot;delete-btn&quot;>刪除醫案</button> </span> <span v-else> <button @click=&quot;submitContent&quot; class=&quot;submit-btn&quot;>提交醫案</button> </span> <span v-if=&quot;submittedId&quot; class=&quot;submitted-id&quot;>醫案 ID: {{ submittedId }}</span> <span>醫案編輯器</span> </footer> </div> </template> <script> import WangEditor from './WangEditor.vue'; import mrdncrud from './mrdncrud.vue'; import mrmncrud from './mrmncrud.vue'; import mrsncrud from './mrsncrud.vue'; import mrpncrud from './mrpncrud.vue'; // 导入新增的物编辑组件 import mrfncrud from './mrfncrud.vue'; import LZString from 'lz-string'; export default { name: 'mreditor', components: { WangEditor, mrdncrud, mrmncrud, mrsncrud, mrpncrud, mrfncrud // 注册新组件 }, data() { return { content: '', submittedId: null, fetchId: null, dnTags: [], mnTags: [], snTags: [], pnTags: [], fnTags: [], // 新增:物标签 showRawHtml: false, stateVersion: '1.5', // 更新版本号(因为数据结构有变) autoSaveTimer: null, autoSaveInterval: 30000, currentDnTags: [], currentMnTags: [], currentSnTags: [], currentPnTags: [], currentFnTags: [], // 新增:当前物标签 dnTagMap: {}, mnTagMap: {}, snTagMap: {}, pnTagMap: {}, fnTagMap: {}, // 新增:物标签映射 showDnCrud: false, showMnCrud: false, showSnCrud: false, showPnCrud: false, showFnCrud: false, // 新增:控制物编辑面板显示 formData: { mrname: &quot;&quot;, mrposter: &quot;&quot; } }; }, computed: { highlightedContent() { if (!this.dnTags.length && !this.mnTags.length && !this.snTags.length && !this.pnTags.length && !this.fnTags.length) return this.content; const tempEl = document.createElement('div'); tempEl.innerHTML = this.content; // 第一阶段:处理病态标签(橙色) if (this.dnTags.length) { 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( this.escapeRegExp(tag), 'g' ); newHtml = newHtml.replace( regex, `<span style=&quot;color: rgb(212, 107, 8); font-weight: bold;&quot;>${tag}</span>` ); }); if (newHtml !== text) { const span = document.createElement('span'); span.innerHTML = newHtml; node.parentNode.replaceChild(span, node); } }); } // 第二阶段:处理草本标签(绿色) if (this.mnTags.length) { const mnWalker = document.createTreeWalker( tempEl, NodeFilter.SHOW_TEXT ); const mnNodes = []; while (mnWalker.nextNode()) mnNodes.push(mnWalker.currentNode); mnNodes.forEach(node => { let text = node.nodeValue; let newHtml = text; this.mnTags .slice() .sort((a, b) => b.length - a.length) .forEach(tag => { const regex = new RegExp(this.escapeRegExp(tag), 'g'); newHtml = newHtml.replace( regex, `<span style=&quot;color: rgb(0, 128, 0); font-weight: bold;&quot;>${tag}</span>` ); }); if (newHtml !== text) { const span = document.createElement('span'); span.innerHTML = newHtml; node.parentNode.replaceChild(span, node); } }); } // 第三阶段:处理出处标签(蓝色) if (this.snTags.length) { const snWalker = document.createTreeWalker( tempEl, NodeFilter.SHOW_TEXT ); const snNodes = []; while (snWalker.nextNode()) snNodes.push(snWalker.currentNode); snNodes.forEach(node => { let text = node.nodeValue; let newHtml = text; this.snTags .slice() .sort((a, b) => b.length - a.length) .forEach(tag => { const regex = new RegExp(this.escapeRegExp(tag), 'g'); newHtml = newHtml.replace( regex, `<span style=&quot;color: rgb(51, 102, 255); font-weight: bold;&quot;>${tag}</span>` ); }); if (newHtml !== text) { const span = document.createElement('span'); span.innerHTML = newHtml; node.parentNode.replaceChild(span, node); } }); } // 第四阶段:处理方剂标签(紫色) if (this.pnTags.length) { const pnWalker = document.createTreeWalker( tempEl, NodeFilter.SHOW_TEXT ); const pnNodes = []; while (pnWalker.nextNode()) pnNodes.push(pnWalker.currentNode); pnNodes.forEach(node => { let text = node.nodeValue; let newHtml = text; this.pnTags .slice() .sort((a, b) => b.length - a.length) .forEach(tag => { const regex = new RegExp(this.escapeRegExp(tag), 'g'); newHtml = newHtml.replace( regex, `<span style=&quot;color: rgb(138, 43, 226); font-weight: bold;&quot;>${tag}</span>` ); }); if (newHtml !== text) { const span = document.createElement('span'); span.innerHTML = newHtml; node.parentNode.replaceChild(span, node); } }); } // 第五阶段:处理物标签(棕色) - 新增 if (this.fnTags.length) { const fnWalker = document.createTreeWalker( tempEl, NodeFilter.SHOW_TEXT ); const fnNodes = []; while (fnWalker.nextNode()) fnNodes.push(fnWalker.currentNode); fnNodes.forEach(node => { let text = node.nodeValue; let newHtml = text; this.fnTags .slice() .sort((a, b) => b.length - a.length) .forEach(tag => { const regex = new RegExp(this.escapeRegExp(tag), 'g'); newHtml = newHtml.replace( regex, `<span style=&quot;color: rgb(139, 69, 19); font-weight: bold;&quot;>${tag}</span>` ); }); if (newHtml !== text) { const span = document.createElement('span'); span.innerHTML = newHtml; node.parentNode.replaceChild(span, node); } }); } return tempEl.innerHTML; }, displayContent() { if (this.showRawHtml) { return this.escapeHtml(this.content); } return this.highlightedContent; }, displayButtonText() { return this.showRawHtml ? '病態渲染格式' : '病態原始標籤'; } }, watch: { content: { handler() { this.debouncedSaveState(); }, deep: true } }, async mounted() { await this.fetchDNTags(); await this.fetchMNTags(); await this.fetchSNTags(); await this.fetchPNTags(); await this.fetchFNTags(); // 新增:获取物标签 this.restoreState(); this.setupAutoSave(); }, activated() { console.log('醫案編輯器被激活'); this.restoreState(); this.setupAutoSave(); }, deactivated() { console.log('醫案編輯器被停用'); this.saveState(); this.clearAutoSave(); }, beforeDestroy() { this.clearAutoSave(); }, methods: { toggleDnCrud() { this.showDnCrud = !this.showDnCrud; this.showMnCrud = false; this.showSnCrud = false; this.showPnCrud = false; this.showFnCrud = false; // 新增 this.updatePanelDisplay(); }, toggleMnCrud() { this.showMnCrud = !this.showMnCrud; this.showDnCrud = false; this.showSnCrud = false; this.showPnCrud = false; this.showFnCrud = false; // 新增 this.updatePanelDisplay(); }, toggleSnCrud() { this.showSnCrud = !this.showSnCrud; this.showDnCrud = false; this.showMnCrud = false; this.showPnCrud = false; this.showFnCrud = false; // 新增 this.updatePanelDisplay(); }, togglePnCrud() { this.showPnCrud = !this.showPnCrud; this.showDnCrud = false; this.showMnCrud = false; this.showSnCrud = false; this.showFnCrud = false; // 新增 this.updatePanelDisplay(); }, // 新增:切换物编辑面板 toggleFnCrud() { this.showFnCrud = !this.showFnCrud; this.showDnCrud = false; this.showMnCrud = false; this.showSnCrud = false; this.showPnCrud = false; this.updatePanelDisplay(); }, updatePanelDisplay() { const panel = document.querySelector('.tag-panel'); if (this.showDnCrud || this.showMnCrud || this.showSnCrud || this.showPnCrud || this.showFnCrud) { panel.style.display = 'block'; } else { panel.style.display = 'none'; } }, handleDnTagUpdated() { console.log('病态标签已更新,刷新数据'); this.fetchDNTags(); }, handleMnTagUpdated() { console.log('本草标签已更新,刷新数据'); this.fetchMNTags(); }, handleSnTagUpdated() { console.log('典籍标签已更新,刷新数据'); this.fetchSNTags(); }, handlePnTagUpdated() { console.log('方剂标签已更新,刷新数据'); this.fetchPNTags(); }, // 新增:物标签更新处理 handleFnTagUpdated() { console.log('物标签已更新,刷新数据'); this.fetchFNTags(); }, // 获取方剂标签数据 async fetchPNTags() { try { const response = await fetch('PNTag/?format=json'); const data = await response.json(); this.pnTags = data .map(item => item.pnname) .filter(name => name && name.trim().length > 0); this.pnTagMap = {}; data.forEach(item => { if (item.id && item.pnname) { this.pnTagMap[item.id] = item.pnname; } }); } catch (error) { console.error('获取方剂标签失败:', error); alert('方剂标签数据加载失败,高亮功能不可用'); } }, // 获取出处标签数据 async fetchSNTags() { try { const response = await fetch('SNTag/?format=json'); const data = await response.json(); this.snTags = data .map(item => item.snname) .filter(name => name && name.trim().length > 0); this.snTagMap = {}; data.forEach(item => { if (item.id && item.snname) { this.snTagMap[item.id] = item.snname; } }); } catch (error) { console.error('获取典籍标签失败:', error); alert('典籍标签数据加载失败,高亮功能不可用'); } }, // 新增:获取物标签数据 async fetchFNTags() { try { const response = await fetch('FNTag/?format=json'); const data = await response.json(); this.fnTags = data .map(item => item.fnname) .filter(name => name && name.trim().length > 0); this.fnTagMap = {}; data.forEach(item => { if (item.id && item.fnname) { this.fnTagMap[item.id] = item.fnname; } }); } catch (error) { console.error('获取物标签失败:', error); alert('物标签数据加载失败,高亮功能不可用'); } }, escapeHtml(unsafe) { if (!unsafe) return ''; return unsafe .replace(/&/g, &quot;&&quot;) .replace(/</g, &quot;<&quot;) .replace(/>/g, &quot;>&quot;) .replace(/&quot;/g, &quot;&quot;&quot;) .replace(/'/g, &quot;'&quot;); }, escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }, setupAutoSave() { this.clearAutoSave(); this.autoSaveTimer = setInterval(() => { if (this.content || this.submittedId) { console.log('自动保存状态...'); this.saveState(); } }, this.autoSaveInterval); }, clearAutoSave() { if (this.autoSaveTimer) { clearInterval(this.autoSaveTimer); this.autoSaveTimer = null; } }, debouncedSaveState() { this.clearAutoSave(); this.autoSaveTimer = setTimeout(() => { this.saveState(); this.setupAutoSave(); }, 2000); }, saveState() { const state = { version: this.stateVersion, content: this.content, submittedId: this.submittedId, formData: this.formData, showRawHtml: this.showRawHtml, currentDnTags: this.currentDnTags, currentMnTags: this.currentMnTags, currentSnTags: this.currentSnTags, currentPnTags: this.currentPnTags, currentFnTags: this.currentFnTags, // 新增 timestamp: new Date().getTime() }; if (this.content.length > 2000) { try { state.compressed = true; state.content = LZString.compressToUTF16(this.content); } catch (e) { console.error('压缩失败,使用原始数据', e); state.compressed = false; } } sessionStorage.setItem('medicalRecordState', JSON.stringify(state)); }, restoreState() { const savedState = sessionStorage.getItem('medicalRecordState'); if (!savedState) return; try { const state = JSON.parse(savedState); if (state.version !== this.stateVersion) { console.warn('状态版本不匹配,跳过恢复'); return; } let content = state.content; if (state.compressed) { try { content = LZString.decompressFromUTF16(content); } catch (e) { console.error('解压失败,使用原始数据', e); } } this.content = content; this.submittedId = state.submittedId; this.showRawHtml = state.showRawHtml; this.currentDnTags = state.currentDnTags || []; this.currentMnTags = state.currentMnTags || []; this.currentSnTags = state.currentSnTags || []; this.currentPnTags = state.currentPnTags || []; this.currentFnTags = state.currentFnTags || []; // 新增 this.formData = state.formData || { mrname: &quot;&quot;, mrposter: &quot;&quot; }; console.log('医案状态已恢复'); } catch (e) { console.error('状态恢复失败', e); sessionStorage.removeItem('medicalRecordState'); } }, clearState() { sessionStorage.removeItem('medicalRecordState'); }, toggleDisplayFormat() { this.showRawHtml = !this.showRawHtml; this.saveState(); }, 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); this.dnTagMap = {}; data.forEach(item => { if (item.id && item.dnname) { this.dnTagMap[item.id] = item.dnname; } }); } catch (error) { console.error('获取标签失败:', error); alert('标签数据加载失败,高亮功能不可用'); } }, async fetchMNTags() { try { const response = await fetch('MNTag/?format=json'); const data = await response.json(); this.mnTags = data .map(item => item.mnname) .filter(name => name && name.trim().length > 0); this.mnTagMap = {}; data.forEach(item => { if (item.id && item.mnname) { this.mnTagMap[item.id] = item.mnname; } }); } catch (error) { console.error('获取草本标签失败:', error); alert('草本标签数据加载失败,高亮功能不可用'); } }, 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.formData.mrname = data.mrname || ''; this.formData.mrposter = data.mrposter || ''; this.content = data.mrcase || ''; this.submittedId = data.id; this.fetchId = null; // 病态标签处理 if (data.dntag && Array.isArray(data.dntag)) { this.currentDnTags = data.dntag.map(id => this.dnTagMap[id] || `未知標籤(${id})` ); } else { this.currentDnTags = []; } // 草本标签处理 if (data.mntag && Array.isArray(data.mntag)) { this.currentMnTags = data.mntag.map(id => this.mnTagMap[id] || `未知草本(${id})` ); } else { this.currentMnTags = []; } // 出处标签处理 if (data.sntag && Array.isArray(data.sntag)) { this.currentSnTags = data.sntag.map(id => this.snTagMap[id] || `未知典籍(${id})` ); } else { this.currentSnTags = []; } // 方剂标签处理 if (data.pntag && Array.isArray(data.pntag)) { this.currentPnTags = data.pntag.map(id => this.pnTagMap[id] || `未知方劑(${id})` ); } else { this.currentPnTags = []; } // 新增:物标签处理 if (data.fntag && Array.isArray(data.fntag)) { this.currentFnTags = data.fntag.map(id => this.fnTagMap[id] || `未知物(${id})` ); } else { this.currentFnTags = []; } await this.fetchDNTags(); await this.fetchMNTags(); await this.fetchSNTags(); await this.fetchPNTags(); await this.fetchFNTags(); // 新增 this.saveState(); alert('醫案數據加載成功!'); } else if (response.status === 404) { alert('未找到該ID的醫案'); } else { throw new Error('獲取醫案失敗'); } } catch (error) { console.error('Error:', error); alert(`獲取醫案失敗: ${error.message}`); } }, async submitContent() { const postData = { mrcase: this.content, mrname: this.formData.mrname, mrposter: this.formData.mrposter }; 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; // 病态标签处理 if (data.dntag && Array.isArray(data.dntag)) { this.currentDnTags = data.dntag.map(id => this.dnTagMap[id] || `未知標籤(${id})` ); } else { this.currentDnTags = []; } // 草本标签处理 if (data.mntag && Array.isArray(data.mntag)) { this.currentMnTags = data.mntag.map(id => this.mnTagMap[id] || `未知草本(${id})` ); } else { this.currentMnTags = []; } // 出处标签处理 if (data.sntag && Array.isArray(data.sntag)) { this.currentSnTags = data.sntag.map(id => this.snTagMap[id] || `未知典籍(${id})` ); } else { this.currentSnTags = []; } // 方剂标签处理 if (data.pntag && Array.isArray(data.pntag)) { this.currentPnTags = data.pntag.map(id => this.pnTagMap[id] || `未知方劑(${id})` ); } else { this.currentPnTags = []; } // 新增:物标签处理 if (data.fntag && Array.isArray(data.fntag)) { this.currentFnTags = data.fntag.map(id => this.fnTagMap[id] || `未知物(${id})` ); } else { this.currentFnTags = []; } this.saveState(); alert('醫案提交成功!'); } else { throw new Error('提交失败'); } } catch (error) { console.error('Error:', error); alert(`提交失败: ${error.message}`); } }, async updateContent() { if (!this.submittedId) return; const postData = { mrcase: this.content, mrname: this.formData.mrname, mrposter: this.formData.mrposter }; try { const response = await fetch(`MRInfo/${this.submittedId}/?format=json`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(postData), }); if (response.ok) { const data = await response.json(); // 病态标签处理 if (data.dntag && Array.isArray(data.dntag)) { this.currentDnTags = data.dntag.map(id => this.dnTagMap[id] || `未知標籤(${id})` ); } // 草本标签处理 if (data.mntag && Array.isArray(data.mntag)) { this.currentMnTags = data.mntag.map(id => this.mnTagMap[id] || `未知草本(${id})` ); } // 出处标签处理 if (data.sntag && Array.isArray(data.sntag)) { this.currentSnTags = data.sntag.map(id => this.snTagMap[id] || `未知典籍(${id})` ); } // 方剂标签处理 if (data.pntag && Array.isArray(data.pntag)) { this.currentPnTags = data.pntag.map(id => this.pnTagMap[id] || `未知方劑(${id})` ); } // 新增:物标签处理 if (data.fntag && Array.isArray(data.fntag)) { this.currentFnTags = data.fntag.map(id => this.fnTagMap[id] || `未知物(${id})` ); } this.saveState(); 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.clearState(); 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.showRawHtml = false; this.currentDnTags = []; this.currentMnTags = []; this.currentSnTags = []; this.currentPnTags = []; this.currentFnTags = []; // 新增 this.showDnCrud = false; this.showMnCrud = false; this.showSnCrud = false; this.showPnCrud = false; this.showFnCrud = false; // 新增 this.formData = { mrname: &quot;&quot;, mrposter: &quot;&quot; }; document.querySelector('.tag-panel').style.display = 'none'; } } }; </script> <style scoped> .wangeditor { flex: 1; padding: 10px; overflow-y: auto; } .up-panel { position: fixed; top: 55px; right: 0; width: 50%; height: 45%; /* 调整高度以适应新按钮 */ padding: 0; overflow: hidden; background: #ffe6d4; display: block; } .tag-panel { width: 80%; height: 100%; background: lightyellow; padding: 10px; overflow-y: auto; display: none; z-index: 100; } .crud-buttons { position: absolute; top: 0; right: 0; display: flex; flex-direction: column; z-index: 101; gap: 5px; } .fixed-dncrud-btn { background-color: #EF6C00; color: white; border: none; padding: 8px 15px; border-radius: 4px; cursor: pointer; width: 120px; text-align: center; } .fixed-dncrud-btn:hover { background-color: #E65100; } .fixed-mncrud-btn { background-color: #2E7D32; color: white; border: none; padding: 8px 15px; border-radius: 4px; cursor: pointer; width: 120px; text-align: center; } .fixed-mncrud-btn:hover { background-color: #1B5E20; } .fixed-sncrud-btn { background-color: #1976D2; color: white; border: none; padding: 8px 15px; border-radius: 4px; cursor: pointer; width: 120px; text-align: center; } .fixed-sncrud-btn:hover { background-color: #0D47A1; } .fixed-pncrud-btn { background-color: #8A2BE2; color: white; border: none; padding: 8px 15px; border-radius: 4px; cursor: pointer; width: 120px; text-align: center; } .fixed-pncrud-btn:hover { background-color: #6A1B9A; } /* 新增物按钮样式 */ .fixed-fncrud-btn { background-color: #8B4513; color: white; border: none; padding: 8px 15px; border-radius: 4px; cursor: pointer; width: 120px; text-align: center; } .fixed-fncrud-btn:hover { background-color: #654321; } .right-panel { position: fixed; bottom: 45px; right: 0; width: 50%; height: 43%; /* 调整高度以适应新标签 */ background: lightblue; padding: 1px; z-index: 100; overflow-y: auto; } .dntag-display { display: flex; margin-top: 1px; padding: 10px; background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 5px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); } .mntag-display { display: flex; margin-top: 10px; padding: 10px; background: #f0f9eb; border: 1px solid #e1f3d8; border-radius: 5px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); } .sntag-display { display: flex; margin-top: 10px; padding: 10px; background: #e3f2fd; border: 1px solid #bbdefb; border-radius: 5px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); } .pntag-display { display: flex; margin-top: 10px; padding: 10px; background: #f3e5f5; border: 1px solid #e1bee7; border-radius: 5px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); } /* 新增物标签显示区域 */ .fntag-display { display: flex; margin-top: 10px; padding: 10px; background: #f5f0e6; border: 1px solid #d2b48c; border-radius: 5px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); } .field-name { font-weight: bold; min-width: 80px; color: #495057; font-size: 1rem; } .dntag-value, .mntag-value, .sntag-value, .pntag-value, .fntag-value { flex-grow: 1; padding-left: 10px; } .dntag-value { border-left: 2px solid #ffc107; } .mntag-value { border-left: 2px solid #4CAF50; } .sntag-value { border-left: 2px solid #2196F3; } .pntag-value { border-left: 2px solid #8A2BE2; } .fntag-value { border-left: 2px solid #8B4513; } .dn-tag { color: rgb(212, 107, 8); font-weight: bold; margin-right: 2px; } .mn-tag { color: rgb(0, 128, 0); font-weight: bold; margin-right: 2px; } .sn-tag { color: rgb(51, 102, 255); font-weight: bold; margin-right: 2px; } .pn-tag { color: rgb(138, 43, 226); font-weight: bold; margin-right: 2px; } .fn-tag { color: rgb(139, 69, 19); font-weight: bold; margin-right: 2px; } .content-display { position: fixed; top: 350px; left: 0; width: 50%; height: 60%; bottom: 45px; z-index: 999; background-color: white; overflow-y: auto; padding: 10px; border: 1px solid #eee; white-space: pre-wrap; } .sticky-footer { display: flex; justify-content: flex-start; 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; border: none; color: white; border-radius: 4px; cursor: pointer; } .reset-btn:hover { background-color: #c82333; } .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; } .form-input { margin-right: 10px; } .name-input, .poster-input { padding: 5px 8px; border: 1px solid #ccc; border-radius: 4px; width: 150px; } </style>
08-01
<think>我们有一个Vue组件mreditor.vue,它目前从后端获取医案信息,包括医案内容(mrcase)、医案名称(mrname)和提交者(mrposter)。现在需要根据新的需求,从MRInfo的API中获取两个新字段:mrorigin(医案出处)和mrdoctor(医案医者),并添加对应的输入栏位。要求参照mrname的样式。 具体步骤: 1. 在模板中,找到mrname和mrposter的输入框位置,在它们附近添加两个新的输入框,分别用于mrorigin和mrdoctor。 2. 在data的formData中添加两个新字段:mrorigin和mrdoctor,初始值为空字符串。 3. 在提交和更新医案时,将这两个新字段包含在发送的数据中(即postData和updateData中)。 4. 在通过ID获取医案数据(fetchById方法)时,将获取到的mrorigin和mrdoctor赋值给formData的对应字段。 5. 在resetAll方法中,重置这两个字段为空字符串。 6. 在保存状态(saveState)和恢复状态(restoreState)时,也要包含这两个新字段。 注意:样式上要与现有的输入框保持一致。 修改点: 1. 模板部分:在footer的sticky-footer中,mrname和mrposter输入框的后面,添加两个新的输入框,分别用于mrorigin和mrdoctor。 2. data中的formData对象添加两个属性:mrorigin和mrdoctor,初始值为空字符串。 3. 在fetchById方法中,将获取到的数据中的mrorigin和mrdoctor赋值给this.formData.mrorigin和this.formData.mrdoctor。 4. 在submitContent和updateContent方法中,将这两个字段加入postData和putData中。 5. 在resetAll方法中,将formData的这两个属性重置为空字符串。 6. 在saveState方法中,formData已经包含这两个新字段(因为formData是一个对象,我们在恢复状态时也会恢复整个formData)。在restoreState方法中,我们不需要单独处理,因为整个formData都会被恢复。 另外,由于新增了两个输入框,可能需要调整一下footer的布局,确保它们能在一行显示或者换行显示合理。考虑到footer使用了flex布局且可以换行(flex-wrap: wrap),所以直接添加两个新的输入框应该可以。 模板修改示例: 在现有mrposter输入框的后面添加: <span class=&quot;form-input&quot;> <input v-model=&quot;formData.mrorigin&quot; placeholder=&quot;醫案出處&quot; class=&quot;origin-input&quot; /> </span> <span class=&quot;form-input&quot;> <input v-model=&quot;formData.mrdoctor&quot; placeholder=&quot;醫案醫者&quot; class=&quot;doctor-input&quot; /> </span> 注意:class可以复用已有的form-input,也可以单独添加,但为了保持样式一致,这里使用相同的form-input类。 由于新增了两个输入框,可能会使footer区域过长,但因为有flex-wrap,所以当空间不足时会自动换行。 下面开始修改代码。</think>根据您的需求,我将分析并提供修改后的`mreditor.vue`代码,添加`mrorigin`(医案出处)和`mrdoctor`(医案医者)字段输入栏位: ### 修改方案: 1. **模板部分**:在`<footer>`中添加两个新的输入框 2. **数据模型**:在`formData`中添加`mrorigin`和`mrdoctor`字段 3. **方法更新**:在提交/更新/获取数据时处理新字段 ### 修改后的代码片段: ```vue <!-- 在<footer>部分添加新字段 --> <footer class=&quot;sticky-footer&quot;> <!-- 医案命名 --> <span class=&quot;form-input&quot;> <input v-model=&quot;formData.mrname&quot; placeholder=&quot;醫案命名&quot; class=&quot;name-input&quot; /> </span> <!-- 医案出处(新增) --> <span class=&quot;form-input&quot;> <input v-model=&quot;formData.mrorigin&quot; placeholder=&quot;醫案出處&quot; class=&quot;origin-input&quot; /> </span> <!-- 医案医者(新增) --> <span class=&quot;form-input&quot;> <input v-model=&quot;formData.mrdoctor&quot; placeholder=&quot;醫案醫者&quot; class=&quot;doctor-input&quot; /> </span> <!-- 提交者姓名 --> <span class=&quot;form-input&quot;> <input v-model=&quot;formData.mrposter&quot; placeholder=&quot;提交者姓名&quot; class=&quot;poster-input&quot; /> </span> <!-- 其余按钮保持不变 --> ... </footer> ``` ```js // 在data()中添加新字段 data() { return { // ...其他数据 formData: { mrname: &quot;&quot;, mrorigin: &quot;&quot;, // 新增字段 mrdoctor: &quot;&quot;, // 新增字段 mrposter: &quot;&quot; } }; }, ``` ```js // 更新fetchById方法(添加字段赋值) async fetchById() { try { const response = await fetch(`MRInfo/${this.fetchId}/?format=json`); if (response.ok) { const data = await response.json(); this.formData = { mrname: data.mrname || '', mrorigin: data.mrorigin || '', // 新增字段 mrdoctor: data.mrdoctor || '', // 新增字段 mrposter: data.mrposter || '' }; // ...其余代码不变 } } catch (error) { /* ... */ } } ``` ```js // 更新submitContent和updateContent方法 async submitContent() { const postData = { mrcase: this.content, ...this.formData // 包含所有formData字段 }; // ...发送请求 } async updateContent() { const postData = { mrcase: this.content, ...this.formData // 包含所有formData字段 }; // ...发送请求 } ``` ```js // 更新resetAll方法 resetAll() { // ...其他重置 this.formData = { mrname: &quot;&quot;, mrorigin: &quot;&quot;, // 重置新增字段 mrdoctor: &quot;&quot;, // 重置新增字段 mrposter: &quot;&quot; }; } ``` ### 样式调整建议: ```css /* 确保新输入框样式一致 */ .form-input input { padding: 5px 8px; border: 1px solid #ccc; border-radius: 4px; width: 150px; /* 与其他输入框保持一致 */ } ``` ### 修改说明: 1. **字段位置**:将新字段放在`mrname`和`mrposter`之间,符合中医案信息逻辑顺序 2. **数据流**: - 新增字段通过`v-model`双向绑定 - 在获取/提交/重置时自动处理字段 - 使用对象展开符`...this.formData`确保所有字段同步 3. **兼容性**:保留原有功能不变,仅扩展字段 4. **错误处理**:使用`|| ''`防止未定义值导致报错
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值