diff --git a/frontend/src/views/OilReference.vue b/frontend/src/views/OilReference.vue
index df6d129..2ab510c 100644
--- a/frontend/src/views/OilReference.vue
+++ b/frontend/src/views/OilReference.vue
@@ -110,6 +110,14 @@
+
+
+
@@ -468,6 +476,56 @@ const activeCard = ref(null)
// Add oil form
const addType = ref('oil')
+const showSmartPaste = ref(false)
+const smartPasteText = ref('')
+const OIL_VOLUMES = new Set(['2.5', '5', '10', '15', '115'])
+
+function runSmartPaste() {
+ const raw = smartPasteText.value || ''
+ if (!raw.trim()) return
+ const text = raw.replace(/[::]/g, ':').replace(/[¥¥]/g, '')
+
+ const memberMatch = text.match(/(?:优惠顾客价|会员价|批发价)\s*:?\s*(\d+(?:\.\d+)?)/)
+ const retailMatch = text.match(/零售价\s*:?\s*(\d+(?:\.\d+)?)/)
+ const specMatch = text.match(/规格\s*:?\s*(\d+(?:\.\d+)?)\s*(毫升|ml|ML|克|g|G|颗|粒|片)/)
+
+ let cn = '', en = ''
+ for (const line of raw.split(/\r?\n/)) {
+ const s = line.trim()
+ if (!s) continue
+ if (/优惠顾客价|会员价|零售价|点数|规格|PT\s*:|批发价/i.test(s)) continue
+ const m = s.match(/^([^A-Za-z]+?)\s+([A-Za-z].*)$/)
+ if (m) { cn = m[1].trim(); en = m[2].trim() } else { cn = s }
+ break
+ }
+
+ if (memberMatch) newBottlePrice.value = Number(memberMatch[1])
+ if (retailMatch) newRetailPrice.value = Number(retailMatch[1])
+ if (cn) newOilName.value = cn
+ if (en) newOilEnName.value = en
+
+ if (specMatch) {
+ const amount = specMatch[1]
+ const unitRaw = specMatch[2].toLowerCase()
+ const isMl = unitRaw === '毫升' || unitRaw === 'ml'
+ if (isMl && OIL_VOLUMES.has(String(Number(amount)))) {
+ addType.value = 'oil'
+ newVolume.value = String(Number(amount))
+ newCustomDrops.value = null
+ } else {
+ addType.value = 'product'
+ newProductAmount.value = Number(amount)
+ newProductUnit.value = (unitRaw === '克' || unitRaw === 'g') ? 'g'
+ : (unitRaw === '颗' || unitRaw === '粒' || unitRaw === '片') ? 'capsule'
+ : 'ml'
+ }
+ } else {
+ addType.value = 'product'
+ }
+
+ ui.showToast('已识别并填入,请检查后点添加')
+}
+
const newOilName = ref('')
const newOilEnName = ref('')
const newBottlePrice = ref(null)