feat(web): update Vue components and composables
- PersonalWorkbench.vue: update personal workbench component - useAppShell.js: update app shell composable - useChat.js: update chat composable with new features - AppShellRouteView.vue: update route view - ChatView.vue: update chat view with enhanced UI - TravelReimbursementCreateView.vue: update travel reimbursement form - ChatView.js: update chat view script logic - TravelReimbursementCreateView.js: update travel form script logic
This commit is contained in:
@@ -1,21 +1,30 @@
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
|
||||
import { useSystemState } from '../../composables/useSystemState.js'
|
||||
import { fetchOntologyParse } from '../../services/ontology.js'
|
||||
|
||||
export default {
|
||||
name: 'ChatView',
|
||||
props: {
|
||||
documents: { type: Array, required: true },
|
||||
docSearch: { type: String, default: '' },
|
||||
messages: { type: Array, required: true },
|
||||
uploadedFiles: { type: Array, required: true },
|
||||
activeCase: { type: Object, default: null },
|
||||
quickPrompts: { type: Array, required: true },
|
||||
draft: { type: String, default: '' },
|
||||
messageList: { type: Object, default: null }
|
||||
},
|
||||
emits: ['send', 'upload', 'draft', 'approveCase', 'rejectCase', 'selectCase'] ,
|
||||
documents: { type: Array, required: true },
|
||||
docSearch: { type: String, default: '' },
|
||||
messages: { type: Array, required: true },
|
||||
uploadedFiles: { type: Array, required: true },
|
||||
activeCase: { type: Object, default: null },
|
||||
quickPrompts: { type: Array, required: true },
|
||||
draft: { type: String, default: '' },
|
||||
sending: { type: Boolean, default: false },
|
||||
messageList: { type: Object, default: null }
|
||||
},
|
||||
emits: ['send', 'upload', 'draft', 'approveCase', 'rejectCase', 'selectCase'],
|
||||
setup(props, { emit }) {
|
||||
const { currentUser } = useSystemState()
|
||||
const localMessageList = ref(null)
|
||||
const promptPage = ref(0)
|
||||
const semanticDraft = ref('查一下本周报销超标风险')
|
||||
const semanticLoading = ref(false)
|
||||
const semanticError = ref('')
|
||||
const semanticResult = ref(null)
|
||||
|
||||
const sessions = [
|
||||
{ title: '北京出差,酒店超标报销怎么处理?', time: '10:32', active: true },
|
||||
@@ -69,12 +78,107 @@ export default {
|
||||
{ text: '借款冲销逾期会影响报销吗?', score: '76%' }
|
||||
]
|
||||
|
||||
const semanticExamples = [
|
||||
'查一下本周报销超标风险',
|
||||
'客户 A 这个月还有多少应收',
|
||||
'帮我直接付款给供应商B'
|
||||
]
|
||||
|
||||
const semanticConfidenceLabel = computed(() =>
|
||||
semanticResult.value ? `${Math.round((semanticResult.value.confidence || 0) * 100)}%` : '未解析'
|
||||
)
|
||||
const semanticEntitiesText = computed(() => {
|
||||
const items = semanticResult.value?.entities || []
|
||||
return items.length
|
||||
? items.map((item) => `${item.type}:${item.normalized_value}`).join(' / ')
|
||||
: '未识别'
|
||||
})
|
||||
const semanticTimeRangeText = computed(() => {
|
||||
const value = semanticResult.value?.time_range
|
||||
if (!value?.start_date || !value?.end_date) {
|
||||
return '未识别'
|
||||
}
|
||||
return `${value.start_date} ~ ${value.end_date}${value.granularity ? ` · ${value.granularity}` : ''}`
|
||||
})
|
||||
const semanticMetricsText = computed(() => {
|
||||
const items = semanticResult.value?.metrics || []
|
||||
return items.length
|
||||
? items
|
||||
.map((item) => {
|
||||
const suffix = item.top_n ? ` top_${item.top_n}` : ''
|
||||
return `${item.name}${suffix}`
|
||||
})
|
||||
.join(' / ')
|
||||
: '未识别'
|
||||
})
|
||||
const semanticConstraintsText = computed(() => {
|
||||
const items = semanticResult.value?.constraints || []
|
||||
return items.length
|
||||
? items.map((item) => `${item.field}${item.operator}${item.value}`).join(' / ')
|
||||
: '未识别'
|
||||
})
|
||||
const semanticRiskFlagsText = computed(() => {
|
||||
const items = semanticResult.value?.risk_flags || []
|
||||
return items.length ? items.join(' / ') : '未识别'
|
||||
})
|
||||
const semanticClarificationText = computed(() => {
|
||||
if (!semanticResult.value) {
|
||||
return '未解析'
|
||||
}
|
||||
if (!semanticResult.value.clarification_required) {
|
||||
return '无需澄清'
|
||||
}
|
||||
return semanticResult.value.clarification_question || '需要补充更多上下文'
|
||||
})
|
||||
const semanticResultJson = computed(() =>
|
||||
semanticResult.value ? JSON.stringify(semanticResult.value, null, 2) : ''
|
||||
)
|
||||
|
||||
function rotatePrompts() {
|
||||
promptPage.value += 1
|
||||
}
|
||||
|
||||
function applyPrompt(text) {
|
||||
emit('draft', text)
|
||||
semanticDraft.value = text
|
||||
}
|
||||
|
||||
function applySemanticExample(text) {
|
||||
semanticDraft.value = text
|
||||
}
|
||||
|
||||
function useDraftAsSemanticInput() {
|
||||
semanticDraft.value = props.draft || semanticDraft.value
|
||||
}
|
||||
|
||||
async function parseSemanticQuery() {
|
||||
const query = String(semanticDraft.value || '').trim()
|
||||
if (!query) {
|
||||
semanticError.value = '请输入要解析的问题。'
|
||||
semanticResult.value = null
|
||||
return
|
||||
}
|
||||
|
||||
semanticLoading.value = true
|
||||
semanticError.value = ''
|
||||
|
||||
try {
|
||||
semanticResult.value = await fetchOntologyParse({
|
||||
query,
|
||||
user_id: currentUser.value?.username || currentUser.value?.name || 'anonymous',
|
||||
context_json: {
|
||||
role_codes: currentUser.value?.roleCodes || [],
|
||||
is_admin: Boolean(currentUser.value?.isAdmin),
|
||||
name: currentUser.value?.name || '',
|
||||
role: currentUser.value?.role || ''
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
semanticResult.value = null
|
||||
semanticError.value = error.message || '语义解析失败,请稍后重试。'
|
||||
} finally {
|
||||
semanticLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
@@ -94,7 +198,23 @@ export default {
|
||||
hotQuestions,
|
||||
similarQuestions,
|
||||
rotatePrompts,
|
||||
applyPrompt
|
||||
applyPrompt,
|
||||
semanticDraft,
|
||||
semanticLoading,
|
||||
semanticError,
|
||||
semanticResult,
|
||||
semanticExamples,
|
||||
semanticConfidenceLabel,
|
||||
semanticEntitiesText,
|
||||
semanticTimeRangeText,
|
||||
semanticMetricsText,
|
||||
semanticConstraintsText,
|
||||
semanticRiskFlagsText,
|
||||
semanticClarificationText,
|
||||
semanticResultJson,
|
||||
applySemanticExample,
|
||||
useDraftAsSemanticInput,
|
||||
parseSemanticQuery
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user