fix: 稀释比例/使用禁忌保存图片改用 ref 直接定位元素
Some checks failed
PR Preview / teardown-preview (pull_request) Has been skipped
Test / unit-test (push) Successful in 4s
Test / build-check (push) Successful in 3s
PR Preview / test (pull_request) Successful in 5s
PR Preview / deploy-preview (pull_request) Successful in 14s
Test / e2e-test (push) Failing after 54s

之前用 querySelector 找 modal 内元素,选择器匹配失败导致
手机端没有触发 navigator.share。现在用 Vue ref 直接引用
卡片 DOM 元素,传给 captureAndSave。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-09 09:04:11 +00:00
parent 029071dbab
commit fc16436ebd

View File

@@ -16,7 +16,7 @@
<!-- Dilution Ratio Modal -->
<div v-if="showDilution" class="modal-overlay" @click.self="showDilution = false">
<div style="position:relative;z-index:1;background:white;border-radius:20px;max-width:420px;width:100%;max-height:88vh;overflow-y:auto;box-shadow:0 16px 56px rgba(0,0,0,0.25)" @click.stop>
<div ref="dilutionCardRef" style="position:relative;z-index:1;background:white;border-radius:20px;max-width:420px;width:100%;max-height:88vh;overflow-y:auto;box-shadow:0 16px 56px rgba(0,0,0,0.25)" @click.stop>
<div style="background:linear-gradient(135deg,#2e7d32,#66bb6a);border-radius:20px 20px 0 0;padding:28px 24px;color:white;text-align:center;position:relative">
<button @click="showDilution = false" style="position:absolute;top:12px;right:16px;background:rgba(255,255,255,0.2);border:none;color:white;width:30px;height:30px;border-radius:50%;cursor:pointer;font-size:16px">×</button>
<div style="font-size:48px;margin-bottom:8px">💧</div>
@@ -45,7 +45,7 @@
<!-- Safety Cautions Modal -->
<div v-if="showContra" class="modal-overlay" @click.self="showContra = false">
<div style="position:relative;z-index:1;background:white;border-radius:20px;max-width:420px;width:100%;max-height:88vh;overflow-y:auto;box-shadow:0 16px 56px rgba(0,0,0,0.25)" @click.stop>
<div ref="contraCardRef" style="position:relative;z-index:1;background:white;border-radius:20px;max-width:420px;width:100%;max-height:88vh;overflow-y:auto;box-shadow:0 16px 56px rgba(0,0,0,0.25)" @click.stop>
<div style="background:linear-gradient(135deg,#e65100,#ff9800);border-radius:20px 20px 0 0;padding:28px 24px;color:white;text-align:center;position:relative">
<button @click="showContra = false" style="position:absolute;top:12px;right:16px;background:rgba(255,255,255,0.2);border:none;color:white;width:30px;height:30px;border-radius:50%;cursor:pointer;font-size:16px">×</button>
<div style="font-size:48px;margin-bottom:8px"></div>
@@ -360,6 +360,8 @@ const ui = useUiStore()
const showDilution = ref(false)
const showContra = ref(false)
const showAddForm = ref(false)
const dilutionCardRef = ref(null)
const contraCardRef = ref(null)
// Search & view
const searchQuery = ref('')
@@ -725,25 +727,29 @@ function exportPDF() {
setTimeout(() => w.print(), 500)
}
// Save modal as image (mobile: share to photos, desktop: download)
async function saveModalImage(name) {
const overlay = document.querySelector('.modal-overlay')
if (!overlay) return
const cardEl = overlay.querySelector('[style*="border-radius: 20px"], [style*="border-radius:20px"]') ||
overlay.querySelector('.oil-card-modal') || overlay.children[0]
if (!cardEl) return
// Save a specific element as image (mobile: share, desktop: download)
async function saveElementAsImage(el, name) {
if (!el) { ui.showToast('保存失败'); return }
try {
const { captureAndSave } = await import('../composables/useSaveImage')
const ok = await captureAndSave(cardEl, name || '精油知识卡')
const ok = await captureAndSave(el, name)
if (ok) ui.showToast('图片已保存')
} catch {
ui.showToast('保存失败')
}
}
function saveDilutionImage() { saveModalImage('精油稀释比例指南') }
function saveContraImage() { saveModalImage('精油使用禁忌') }
function saveCardImage(name) { saveModalImage(name + '_精油知识卡') }
function saveDilutionImage() {
saveElementAsImage(dilutionCardRef.value, '精油稀释比例指南')
}
function saveContraImage() {
saveElementAsImage(contraCardRef.value, '精油使用禁忌')
}
function saveCardImage(name) {
// Oil knowledge card modal
const el = document.querySelector('.oil-card-modal')
saveElementAsImage(el, name + '_精油知识卡')
}
</script>
<style scoped>