Files
X-Financial/web/src/components/business/workbench-ai/WorkbenchAiComposer.vue
2026-06-22 11:58:53 +08:00

174 lines
6.0 KiB
Vue

<template>
<form
class="workbench-ai-composer"
:class="{ 'workbench-ai-composer--inline': inline }"
@submit.prevent="runtime.submitAiModePrompt"
>
<div class="workbench-ai-composer-field">
<div v-if="runtime.workbenchDateTagLabel" class="workbench-ai-date-chip">
<i class="mdi mdi-calendar-check-outline"></i>
<span>{{ runtime.workbenchDateTagLabel }}</span>
<button
type="button"
aria-label="移除日期"
:disabled="runtime.isAiModeInputLocked"
@click="runtime.removeWorkbenchDateTag"
>
<i class="mdi mdi-close"></i>
</button>
</div>
<textarea
:ref="runtime.setAssistantInputRef"
v-model="runtime.assistantDraft"
maxlength="1000"
rows="3"
:placeholder="runtime.isAiModeInputLocked ? '费用测算中,请稍等...' : placeholder"
:disabled="runtime.isAiModeInputLocked"
@keydown.enter.exact.prevent="runtime.submitAiModePrompt"
></textarea>
</div>
<div class="workbench-ai-composer-toolbar">
<div class="workbench-ai-tool-buttons">
<div class="workbench-date-anchor workbench-ai-date-anchor">
<button
type="button"
class="workbench-ai-icon-btn"
:class="{ active: runtime.workbenchDatePickerOpen || runtime.workbenchDateTagLabel }"
title="选择日期"
aria-label="选择日期"
:aria-expanded="runtime.workbenchDatePickerOpen"
:disabled="runtime.isAiModeInputLocked"
@click.stop="runtime.toggleWorkbenchDatePicker"
>
<i class="mdi mdi-calendar-range"></i>
</button>
<div
v-if="runtime.workbenchDatePickerOpen"
class="workbench-ai-date-popover"
role="dialog"
aria-label="选择业务日期"
@click.stop
>
<div class="workbench-ai-date-tabs" role="tablist" aria-label="日期模式">
<button
type="button"
:class="{ active: runtime.workbenchDateMode === 'single' }"
:disabled="runtime.isAiModeInputLocked"
@click="runtime.setWorkbenchDateMode('single')"
>
单日
</button>
<button
type="button"
:class="{ active: runtime.workbenchDateMode === 'range' }"
:disabled="runtime.isAiModeInputLocked"
@click="runtime.setWorkbenchDateMode('range')"
>
范围
</button>
</div>
<label v-if="runtime.workbenchDateMode === 'single'" class="workbench-ai-date-field">
<span>业务日期</span>
<input
v-model="runtime.workbenchSingleDate"
type="date"
:disabled="runtime.isAiModeInputLocked"
@change="runtime.handleWorkbenchDateInputChange('single')"
/>
</label>
<div v-else class="workbench-ai-date-range">
<label class="workbench-ai-date-field">
<span>开始日期</span>
<input
v-model="runtime.workbenchRangeStartDate"
type="date"
:disabled="runtime.isAiModeInputLocked"
@change="runtime.handleWorkbenchDateInputChange('range-start')"
/>
</label>
<label class="workbench-ai-date-field">
<span>结束日期</span>
<input
v-model="runtime.workbenchRangeEndDate"
type="date"
:disabled="runtime.isAiModeInputLocked"
@change="runtime.handleWorkbenchDateInputChange('range-end')"
/>
</label>
</div>
<div class="workbench-ai-date-actions">
<button
type="button"
class="ghost"
:disabled="runtime.isAiModeInputLocked"
@click="runtime.clearWorkbenchDateSelection"
>
清除
</button>
<button
type="button"
class="primary"
:disabled="!runtime.workbenchCanApplyDateSelection || runtime.isAiModeInputLocked"
@click="runtime.applyWorkbenchDateSelection"
>
完成
</button>
</div>
</div>
</div>
<button
type="button"
class="workbench-ai-icon-btn"
title="上传附件"
aria-label="上传附件"
:disabled="runtime.isAiModeInputLocked"
@click="runtime.triggerAiModeFileUpload"
>
<i class="mdi mdi-paperclip"></i>
</button>
<button
type="button"
class="workbench-ai-icon-btn"
title="语音输入"
aria-label="语音输入"
:disabled="runtime.isAiModeInputLocked"
@click="runtime.handleVoiceInput"
>
<i class="mdi mdi-microphone-outline"></i>
</button>
</div>
<div class="workbench-ai-composer-right">
<div class="workbench-ai-model-selector" :title="runtime.modelSelectorTitle">
<span>{{ runtime.displayModelName }}</span>
<i class="mdi mdi-chevron-down"></i>
</div>
<button
type="submit"
class="workbench-ai-send-btn"
:disabled="!runtime.canSubmitAiModePrompt || runtime.sending || runtime.isAiModeInputLocked"
aria-label="发送给小财管家"
>
<i class="mdi mdi-arrow-up"></i>
</button>
</div>
</div>
</form>
</template>
<script setup>
defineProps({
inline: { type: Boolean, default: false },
placeholder: { type: String, required: true },
runtime: { type: Object, required: true }
})
</script>
<style scoped src="../../../assets/styles/components/personal-workbench-ai-mode.css"></style>