feat(ai): add personal expense application memory

This commit is contained in:
caoxiaozhu
2026-07-14 17:16:23 +08:00
parent 211f85d981
commit 54754b5502
36 changed files with 3579 additions and 74 deletions

View File

@@ -0,0 +1,94 @@
<template>
<div v-if="appliedMemories.length || learningReceipts.length" class="application-memory-stack">
<section
v-if="appliedMemories.length"
class="application-memory-panel"
aria-label="本次申请使用的历史偏好"
>
<header class="application-memory-panel-head">
<span class="application-memory-panel-icon" aria-hidden="true">
<i class="mdi mdi-history"></i>
</span>
<span>
<strong>个性化填充</strong>
<small>以下内容来自已确认的历史偏好您仍可直接修改上方字段</small>
</span>
</header>
<div class="application-memory-list">
<article
v-for="memory in appliedMemories"
:key="`${message.id}-memory-${memory.memoryId}`"
class="application-memory-item"
>
<div class="application-memory-copy">
<span class="application-memory-status">
<i class="mdi mdi-check-circle-outline" aria-hidden="true"></i>
已按历史偏好填入
</span>
<strong>{{ memory.fieldLabel }}{{ memory.value }}</strong>
<small v-if="memory.message">{{ memory.message }}</small>
<em>{{ ui.resolveApplicationMemoryEvidenceText(memory) }}</em>
</div>
<button
type="button"
class="application-memory-forget-btn"
:disabled="ui.isForgettingApplicationMemory(memory)"
:aria-busy="ui.isForgettingApplicationMemory(memory)"
@click.stop="ui.forgetApplicationPreviewMemory(message, memory)"
>
<i
:class="ui.isForgettingApplicationMemory(memory) ? 'mdi mdi-loading mdi-spin' : 'mdi mdi-delete-outline'"
aria-hidden="true"
></i>
<span>{{ ui.isForgettingApplicationMemory(memory) ? '正在忘记' : '忘记此偏好' }}</span>
</button>
</article>
</div>
</section>
<section
v-if="learningReceipts.length"
class="application-learning-receipt-panel"
role="status"
aria-live="polite"
aria-label="本次申请的个性化学习结果"
>
<header>
<i class="mdi mdi-lightbulb-on-outline" aria-hidden="true"></i>
<strong>本次选择已记录</strong>
</header>
<article
v-for="receipt in learningReceipts"
:key="`${message.id}-learning-${receipt.memoryId}-${receipt.fieldKey}`"
class="application-learning-receipt"
:class="`is-${receipt.status}`"
>
<div>
<strong>{{ ui.resolveApplicationLearningReceiptTitle(receipt) }}</strong>
<span>{{ receipt.fieldLabel }}{{ receipt.value }}</span>
</div>
<small>{{ receipt.message || ui.resolveApplicationMemoryEvidenceText(receipt) }}</small>
</article>
</section>
</div>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
message: {
type: Object,
required: true
},
ui: {
type: Object,
required: true
}
})
const appliedMemories = computed(() => props.ui.resolveAppliedApplicationPreviewMemories(props.message))
const learningReceipts = computed(() => props.ui.resolveVisibleApplicationLearningReceipts(props.message))
</script>
<style scoped src="../../assets/styles/components/travel-reimbursement-message-memory.css"></style>

View File

@@ -225,6 +225,8 @@
</div>
</div>
<TravelReimbursementMemoryPanel :message="message" :ui="ui" />
<div
v-if="ui.resolveApplicationPreviewMissingFields(message)?.length"
class="application-preview-footer application-preview-footer-missing"
@@ -686,12 +688,14 @@
<script>
import BudgetAssistantReport from './BudgetAssistantReport.vue'
import EnterpriseSelect from '../shared/EnterpriseSelect.vue'
import TravelReimbursementMemoryPanel from './TravelReimbursementMemoryPanel.vue'
export default {
name: 'TravelReimbursementMessageItem',
components: {
BudgetAssistantReport,
EnterpriseSelect
EnterpriseSelect,
TravelReimbursementMemoryPanel
},
props: {
message: {