Files
EmailBill/Web/src/components/Bill/OneLineBillAdd.vue

136 lines
2.6 KiB
Vue
Raw Normal View History

<template>
<div>
2026-01-27 15:29:25 +08:00
<div
v-if="!parseResult"
class="input-section"
style="margin: 12px 12px 0 16px"
>
<van-field
v-model="text"
type="textarea"
rows="4"
placeholder="例如1月3日 晚餐 45.5 美团"
class="bill-input"
:disabled="parsing || saving"
/>
<div class="actions">
2026-01-16 11:15:44 +08:00
<van-button
type="primary"
round
block
:loading="parsing"
:disabled="!text.trim()"
@click="handleParse"
>
智能解析
</van-button>
</div>
</div>
2026-01-27 15:29:25 +08:00
<div
v-if="parseResult"
class="result-section"
>
<BillForm
:initial-data="parseResult"
:loading="saving"
submit-text="确认保存"
@submit="handleSave"
>
<template #actions>
2026-01-27 15:29:25 +08:00
<van-button
plain
round
block
class="mt-2"
@click="parseResult = null"
>
重新输入
</van-button>
</template>
</BillForm>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { showToast } from 'vant'
import BillForm from './BillForm.vue'
import { createTransaction, parseOneLine } from '@/api/transactionRecord'
const emit = defineEmits(['success'])
const text = ref('')
const parsing = ref(false)
const saving = ref(false)
const parseResult = ref(null)
const handleParse = async () => {
2026-01-16 11:15:44 +08:00
if (!text.value.trim()) {
return
}
parsing.value = true
parseResult.value = null
2026-01-16 11:15:44 +08:00
try {
const res = await parseOneLine(text.value)
2026-01-16 11:15:44 +08:00
if (!res.success) {
throw new Error(res.message || '解析失败')
}
2026-01-16 11:15:44 +08:00
parseResult.value = res.data
} catch (err) {
console.error(err)
showToast('解析失败:' + err.message)
} finally {
parsing.value = false
}
}
const handleSave = async (payload) => {
saving.value = true
try {
const res = await createTransaction(payload)
2026-01-16 11:15:44 +08:00
if (!res.success) {
throw new Error(res.message || '保存失败')
}
2026-01-16 11:15:44 +08:00
showToast('保存成功')
text.value = ''
parseResult.value = null
emit('success')
} catch (err) {
console.error(err)
showToast('保存失败:' + err.message)
} finally {
saving.value = false
}
}
</script>
<style scoped>
.bill-input {
background-color: var(--van-background-2);
border-radius: 8px;
margin-bottom: 16px;
}
.actions {
margin-top: 16px;
}
.mt-2 {
margin-top: 8px;
}
.preview-card {
margin-bottom: 16px;
border-radius: 8px;
overflow: hidden;
2026-01-13 17:00:44 +08:00
border: 1px solid var(--van-border-color);
}
</style>