HUD姓名板

using UnityEngine;
using System.Collections;

public class HUDInfobox : MonoBehaviour
{
    public FightObj fObj;
    private Vector3 hOffset = Vector3.zero;
    private Vector3 tVec = Vector3.zero;
    void LateUpdate()
    {
        if( fObj == null && fObj.IsHide() )
        {
            return;
        }
        tVec = fObj.Trans.position + fObj.Trans.localRotation * hOffset;//跟随人物rotation
        //tVec = fObj.Trans.position;
        tVec = Camera.main.WorldToScreenPoint(tVec);
        tVec = UICamera.ScreenToWorldPoint(tVec);
        transform.position = tVec;
    }
}


以下代碼更改,將mreditor.vue上編輯病態的切換按鈕改到mreditor1.vue上,而功能不變;而mreditor1.vue上的醫案命名及醫案提交者的功能改到mreditor.vue的footer上, mreditor.vue: <template> <div> <div> <div class="wangeditor"> <WangEditor v-model="content" @response="(msg) => content = msg" /> </div> <div class="right-panel"> <!-- 病态名称显示区域 --> <div class="dntag-display" v-if="currentDnTags.length"> <div class="field-name">相關病態:</div> <div class="dntag-value">{{ currentDnTags.join(';') }}</div> </div> <div class="dntag-display" v-else> <div class="field-name">相關病態:</div> <div class="dntag-value">無關聯病態名稱</div> </div> <mreditor1 ref="mreditor1" /> </div> </div> <div class="tag-panel"> <!-- 病态编辑面 --> <mrdncrud v-if="showDnCrud" @tag-updated="handleTagUpdated" /> </div> <div class="content-display" v-html="displayContent"></div> <footer class="sticky-footer"> <span><button @click="toggleDisplayFormat">{{ displayButtonText }}</button></span> <span><button @click="resetAll" class="reset-btn">輸入新醫案</button></span> <!-- 新增病态编辑切换按钮 --> <span> <button @click="toggleDnCrud" class="dncrud-btn"> {{ showDnCrud ? '隱藏病態編輯' : '編輯病態' }} </button> </span> <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'; import mrdncrud from './mrdncrud.vue'; // 导入病态编辑组件 import LZString from 'lz-string'; export default { name: 'mreditor', components: { WangEditor, mreditor1, mrdncrud }, data() { return { content: '', submittedId: null, fetchId: null, dnTags: [], showRawHtml: false, stateVersion: '1.0', autoSaveTimer: null, autoSaveInterval: 30000, currentDnTags: [], // 存储当前医案的病态名称 dnTagMap: {}, // 标签ID到名称的映射 showDnCrud: false // 控制病态编辑面显示 }; }, computed: { highlightedContent() { if (!this.dnTags.length || !this.content) return this.content; 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( this.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; }, 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(); 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; if (this.showDnCrud) { // 调整布局以显示编辑面 document.querySelector('.tag-panel').style.display = 'block'; } else { document.querySelector('.tag-panel').style.display = 'none'; } }, // 处理标签更新事件 handleTagUpdated() { console.log('病态标签已更新,刷新数据'); this.fetchDNTags(); // 刷新标签数据 }, escapeHtml(unsafe) { if (!unsafe) return ''; return unsafe .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, """) .replace(/'/g, "'"); }, 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 formData = this.$refs.mreditor1 ? this.$refs.mreditor1.getFormData() : { }; const state = { version: this.stateVersion, content: this.content, submittedId: this.submittedId, formData: formData, showRawHtml: this.showRawHtml, currentDnTags: this.currentDnTags, // 保存病态名称 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 || []; // 恢复病态名称 if (this.$refs.mreditor1 && state.formData) { this.$refs.mreditor1.setFormData(state.formData); } 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); // 构建ID到名称的映射 this.dnTagMap = {}; data.forEach(item => { if (item.id && item.dnname) { this.dnTagMap[item.id] = item.dnname; } }); } 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(); if (this.$refs.mreditor1) { 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; // 处理病态名称显示 if (data.dntag && Array.isArray(data.dntag)) { this.currentDnTags = data.dntag.map(id => this.dnTagMap[id] || `未知標籤(${id})` ); } else { this.currentDnTags = []; } await this.fetchDNTags(); 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() { if (!this.$refs.mreditor1) return; 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; // 处理返回的病态名称 if (data.dntag && Array.isArray(data.dntag)) { this.currentDnTags = data.dntag.map(id => this.dnTagMap[id] || `未知標籤(${id})` ); } else { this.currentDnTags = []; } this.saveState(); alert('醫案提交成功!'); } else { throw new Error('提交失败'); } } catch (error) { console.error('Error:', error); alert(`提交失败: ${error.message}`); } }, async updateContent() { if (!this.submittedId || !this.$refs.mreditor1) 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) { const data = await response.json(); // 更新病态名称显示 if (data.dntag && Array.isArray(data.dntag)) { this.currentDnTags = data.dntag.map(id => this.dnTagMap[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.showDnCrud = false; // 隐藏病态编辑面 if (this.$refs.mreditor1) { this.$refs.mreditor1.resetForm(); } this.clearState(); // 确保隐藏编辑面 document.querySelector('.tag-panel').style.display = 'none'; } } }; </script> <style scoped> .wangeditor { flex: 1; padding: 10px; overflow-y: auto; } .right-panel { position: fixed; top: 55px; bottom: 45px; right: 0; width: 30%; 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); } .field-name { font-weight: bold; min-width: 80px; color: #495057; font-size: 1rem; } .dntag-value { flex-grow: 1; color: #212529; font-weight: 500; padding-left: 10px; border-left: 2px solid #ffc107; } .tag-panel { position: fixed; top: 400px; bottom: 45px; right: 0; width: 30%; background: lightyellow; padding: 10px; z-index: 100; overflow-y: auto; display: none; /*默认隐藏 */ } .content-display { position: fixed; top: 490px; left: 0; width: 70%; 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-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; } /* 新增病态编辑按钮样式 */ .dncrud-btn { background-color: #9c27b0; color: white; border: none; padding: 2px 8px; border-radius: 4px; cursor: pointer; margin-left: 10px; } .dncrud-btn:hover { background-color: #7b1fa2; } .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; } </style> mreditor1.vue: <!-- mreditor1.vue --> <template> <div class="editor-container"> <div v-if="submitStatus" class="submit-status" :class="{ 'error': isError }"> {{ submitStatus }} </div> <div class="form-group"> <label for="mrname">醫案命名:</label> <input id="mrname" v-model="formData.mrname" type="text" class="form-control" placeholder="請輸入醫案命名..." /> </div> <div class="form-group"> <label for="mrposter">醫案提交者:</label> <input id="mrposter" v-model="formData.mrposter" type="text" class="form-control" placeholder="請輸入提交者姓名..." /> </div> </div> </template> <script> export default { data() { return { formData: { mrname: "", mrposter: "", }, submitStatus: "", isError: false, }; }, methods: { getFormData() { return { mrname: this.formData.mrname, mrposter: this.formData.mrposter, }; }, resetForm() { this.formData = { mrname: "", mrposter: "", }; this.submitStatus = ""; }, }, }; </script> <style scoped> /* 原有样式保持不变 */ .editor-container { max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #ddd; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } .submit-status { margin-bottom: 15px; padding: 10px; border-radius: 4px; background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; } .submit-status.error { background-color: #f8d7da; color: #721c24; border-color: #f5c6cb; } .form-group { margin-bottom: 15px; } .form-control { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; } </style>
07-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值