2026-05-07 11:50:10 +08:00
|
|
|
|
<template>
|
2026-05-05 18:22:47 +08:00
|
|
|
|
<section class="workbench">
|
|
|
|
|
|
<PanelHead
|
|
|
|
|
|
v-if="showHeader"
|
|
|
|
|
|
eyebrow="Personal Workspace"
|
|
|
|
|
|
title="个人工作台"
|
|
|
|
|
|
note="把今天要处理的待办、报销进度和制度更新集中到一个入口。"
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<article class="panel assistant-hero">
|
|
|
|
|
|
<div class="assistant-visual" aria-hidden="true">
|
2026-05-07 11:50:10 +08:00
|
|
|
|
<span class="assistant-glow"></span>
|
|
|
|
|
|
<img class="assistant-image" :src="robotAssistant" alt="" />
|
2026-05-05 18:22:47 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="assistant-copy">
|
|
|
|
|
|
<span class="assistant-tag">AI 报销助手</span>
|
|
|
|
|
|
<h3>描述费用或上传票据,AI 直接帮你判断怎么报</h3>
|
|
|
|
|
|
<p>自动识别报销类别、核对附件完整性,并生成可继续提交的报销草稿。</p>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="assistant-input">
|
2026-05-12 01:27:49 +00:00
|
|
|
|
<input
|
|
|
|
|
|
ref="fileInputRef"
|
|
|
|
|
|
class="assistant-file-input"
|
|
|
|
|
|
type="file"
|
|
|
|
|
|
multiple
|
|
|
|
|
|
accept=".pdf,.jpg,.jpeg,.png,.webp,.doc,.docx,.xls,.xlsx"
|
|
|
|
|
|
@change="handleWorkbenchFilesChange"
|
|
|
|
|
|
/>
|
2026-05-05 23:47:20 +08:00
|
|
|
|
<textarea
|
|
|
|
|
|
v-model="assistantDraft"
|
2026-05-06 11:00:38 +08:00
|
|
|
|
rows="1"
|
2026-05-05 23:47:20 +08:00
|
|
|
|
placeholder="例如:我昨天请客户吃饭花了 860 元,还打车去了客户公司"
|
2026-05-12 01:27:49 +00:00
|
|
|
|
@keydown.enter.prevent="handleWorkbenchEnter"
|
2026-05-05 23:47:20 +08:00
|
|
|
|
/>
|
2026-05-05 18:22:47 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-05-12 06:39:26 +00:00
|
|
|
|
<div v-if="selectedFiles.length" class="assistant-file-strip">
|
|
|
|
|
|
<span class="assistant-file-note">已带入 {{ selectedFiles.length }} 份附件</span>
|
|
|
|
|
|
<span v-for="file in selectedFiles" :key="file.name" class="assistant-file-chip">{{ file.name }}</span>
|
|
|
|
|
|
<button type="button" class="assistant-file-clear" @click="clearSelectedFiles">清空</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-05-05 18:22:47 +08:00
|
|
|
|
<div class="assistant-tools">
|
2026-05-12 06:39:26 +00:00
|
|
|
|
<button type="button" class="ghost-action" :disabled="Boolean(pendingAction) || confirmDialogBusy" @click="triggerFileUpload">
|
2026-05-05 18:22:47 +08:00
|
|
|
|
<i class="mdi mdi-upload-outline"></i>
|
|
|
|
|
|
<span>上传票据</span>
|
|
|
|
|
|
</button>
|
2026-05-12 06:39:26 +00:00
|
|
|
|
<button
|
|
|
|
|
|
type="button"
|
|
|
|
|
|
class="secondary-action"
|
|
|
|
|
|
:disabled="Boolean(pendingAction) || confirmDialogBusy"
|
|
|
|
|
|
@click="handleContinueConversation"
|
|
|
|
|
|
>
|
|
|
|
|
|
<i :class="pendingAction === 'continue' ? 'mdi mdi-loading mdi-spin' : 'mdi mdi-history'"></i>
|
|
|
|
|
|
<span>{{ pendingAction === 'continue' ? '恢复中...' : '继续会话' }}</span>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button
|
|
|
|
|
|
type="button"
|
|
|
|
|
|
class="hero-action"
|
|
|
|
|
|
:disabled="Boolean(pendingAction) || confirmDialogBusy"
|
|
|
|
|
|
@click="handleNewConversation"
|
|
|
|
|
|
>
|
|
|
|
|
|
<i :class="pendingAction === 'new' ? 'mdi mdi-loading mdi-spin' : 'mdi mdi-magnify-scan'"></i>
|
|
|
|
|
|
<span>{{ pendingAction === 'new' ? '处理中...' : '新建会话' }}</span>
|
2026-05-07 11:50:10 +08:00
|
|
|
|
</button>
|
2026-05-05 18:22:47 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</article>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="workbench-grid">
|
|
|
|
|
|
<article class="panel list-panel">
|
|
|
|
|
|
<div class="section-head">
|
2026-05-05 22:35:38 +08:00
|
|
|
|
<div class="title-with-badge">
|
|
|
|
|
|
<h3>今日待办</h3>
|
|
|
|
|
|
<span class="alert-badge">{{ todoAlertCount }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<button type="button" class="link-action">查看全部 <i class="mdi mdi-chevron-right"></i></button>
|
2026-05-05 18:22:47 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="list-body">
|
|
|
|
|
|
<div v-for="item in todoItems" :key="item.title" class="todo-row">
|
|
|
|
|
|
<div class="todo-icon" :style="{ '--icon-color': item.color }">
|
|
|
|
|
|
<i :class="item.icon"></i>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="todo-copy">
|
|
|
|
|
|
<strong>{{ item.title }}</strong>
|
2026-05-05 22:35:38 +08:00
|
|
|
|
<p class="todo-advice">
|
|
|
|
|
|
<span class="todo-advice-label">{{ item.tipLabel }}</span>
|
|
|
|
|
|
<span class="todo-advice-text">{{ item.suggestion }}</span>
|
|
|
|
|
|
</p>
|
2026-05-05 18:22:47 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<button type="button" class="row-action" @click="emit('openAssistant')">{{ item.action }}</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</article>
|
|
|
|
|
|
|
|
|
|
|
|
<article class="panel list-panel">
|
|
|
|
|
|
<div class="section-head">
|
2026-05-05 22:35:38 +08:00
|
|
|
|
<div class="title-with-badge">
|
|
|
|
|
|
<h3>报销进度</h3>
|
|
|
|
|
|
<span class="alert-badge">{{ progressAlertCount }}</span>
|
|
|
|
|
|
</div>
|
2026-05-05 18:22:47 +08:00
|
|
|
|
<button type="button" class="link-action">查看全部 <i class="mdi mdi-chevron-right"></i></button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="list-body">
|
|
|
|
|
|
<div v-for="item in progressItems" :key="item.id" class="progress-row">
|
|
|
|
|
|
<div class="todo-icon" :style="{ '--icon-color': item.color }">
|
|
|
|
|
|
<i :class="item.icon"></i>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="todo-copy progress-copy">
|
2026-05-05 22:35:38 +08:00
|
|
|
|
<strong>{{ item.title }}</strong>
|
2026-05-05 18:22:47 +08:00
|
|
|
|
<p>提交时间:{{ item.date }}</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-05-05 22:35:38 +08:00
|
|
|
|
<strong class="progress-amount">{{ item.amount }}</strong>
|
2026-05-05 18:22:47 +08:00
|
|
|
|
<span class="progress-status" :class="item.tone">{{ item.status }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</article>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<article class="panel policy-panel">
|
|
|
|
|
|
<div class="section-head">
|
|
|
|
|
|
<h3>最新报销制度</h3>
|
|
|
|
|
|
<button type="button" class="link-action">查看全部 <i class="mdi mdi-chevron-right"></i></button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="policy-table">
|
|
|
|
|
|
<div class="policy-head policy-row">
|
2026-05-05 22:35:38 +08:00
|
|
|
|
<span class="policy-title-cell">制度名称</span>
|
|
|
|
|
|
<span class="policy-summary-cell">摘要</span>
|
|
|
|
|
|
<span class="policy-date-cell">发布日期</span>
|
2026-05-05 18:22:47 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div v-for="item in policyItems" :key="item.name" class="policy-row">
|
2026-05-05 22:35:38 +08:00
|
|
|
|
<strong class="policy-title-cell">{{ item.name }}</strong>
|
|
|
|
|
|
<span class="policy-summary-cell">{{ item.summary }}</span>
|
|
|
|
|
|
<span class="policy-date-cell">{{ item.date }}</span>
|
2026-05-05 18:22:47 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</article>
|
|
|
|
|
|
</section>
|
2026-05-12 06:39:26 +00:00
|
|
|
|
|
2026-05-13 03:27:30 +00:00
|
|
|
|
<ConfirmDialog
|
|
|
|
|
|
:open="confirmDialogOpen"
|
|
|
|
|
|
badge="新建会话"
|
|
|
|
|
|
badge-tone="info"
|
|
|
|
|
|
title="开始新会话会清空当前历史对话"
|
|
|
|
|
|
description="检测到你还有未清除的会话记录。确认后会删除当前用户的全部历史对话,再开启新的智能体会话。"
|
|
|
|
|
|
cancel-text="取消"
|
|
|
|
|
|
confirm-text="确认删除并新建"
|
|
|
|
|
|
busy-text="清空中..."
|
|
|
|
|
|
confirm-tone="primary"
|
|
|
|
|
|
confirm-icon="mdi mdi-delete-sweep-outline"
|
|
|
|
|
|
:busy="confirmDialogBusy"
|
|
|
|
|
|
@close="closeConfirmDialog"
|
|
|
|
|
|
@confirm="confirmStartNewConversation"
|
|
|
|
|
|
/>
|
2026-05-05 18:22:47 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2026-05-05 23:47:20 +08:00
|
|
|
|
import { ref } from 'vue'
|
2026-05-05 18:22:47 +08:00
|
|
|
|
import PanelHead from '../shared/PanelHead.vue'
|
2026-05-13 03:27:30 +00:00
|
|
|
|
import ConfirmDialog from '../shared/ConfirmDialog.vue'
|
2026-05-07 11:50:10 +08:00
|
|
|
|
import robotAssistant from '../../assets/robot-helper.png'
|
2026-05-12 06:39:26 +00:00
|
|
|
|
import { useSystemState } from '../../composables/useSystemState.js'
|
2026-05-13 03:27:30 +00:00
|
|
|
|
import { useToast } from '../../composables/useToast.js'
|
2026-05-12 06:39:26 +00:00
|
|
|
|
import { clearUserConversations, fetchLatestConversation } from '../../services/orchestrator.js'
|
2026-05-05 18:22:47 +08:00
|
|
|
|
|
|
|
|
|
|
defineProps({
|
|
|
|
|
|
showHeader: { type: Boolean, default: true }
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const emit = defineEmits(['openAssistant'])
|
2026-05-12 06:39:26 +00:00
|
|
|
|
const { currentUser } = useSystemState()
|
2026-05-13 03:27:30 +00:00
|
|
|
|
const { toast } = useToast()
|
2026-05-05 23:47:20 +08:00
|
|
|
|
const assistantDraft = ref('')
|
2026-05-12 01:27:49 +00:00
|
|
|
|
const fileInputRef = ref(null)
|
2026-05-12 06:39:26 +00:00
|
|
|
|
const selectedFiles = ref([])
|
|
|
|
|
|
const pendingAction = ref('')
|
|
|
|
|
|
const confirmDialogOpen = ref(false)
|
|
|
|
|
|
const confirmDialogBusy = ref(false)
|
|
|
|
|
|
const pendingAssistantPayload = ref(null)
|
|
|
|
|
|
|
|
|
|
|
|
function resolveCurrentUserId() {
|
|
|
|
|
|
const user = currentUser.value || {}
|
|
|
|
|
|
return String(user.username || user.name || 'anonymous').trim() || 'anonymous'
|
|
|
|
|
|
}
|
2026-05-05 23:47:20 +08:00
|
|
|
|
|
2026-05-12 06:39:26 +00:00
|
|
|
|
function buildAssistantPayload() {
|
|
|
|
|
|
return {
|
2026-05-05 23:47:20 +08:00
|
|
|
|
prompt: assistantDraft.value.trim(),
|
2026-05-12 06:39:26 +00:00
|
|
|
|
source: 'workbench',
|
|
|
|
|
|
files: Array.from(selectedFiles.value)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function clearSelectedFiles() {
|
|
|
|
|
|
selectedFiles.value = []
|
|
|
|
|
|
if (fileInputRef.value) {
|
|
|
|
|
|
fileInputRef.value.value = ''
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function resetWorkbenchDraft() {
|
|
|
|
|
|
assistantDraft.value = ''
|
|
|
|
|
|
clearSelectedFiles()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function emitAssistant(payload) {
|
|
|
|
|
|
emit('openAssistant', payload)
|
|
|
|
|
|
resetWorkbenchDraft()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function loadLatestConversation() {
|
|
|
|
|
|
const payload = await fetchLatestConversation(resolveCurrentUserId())
|
|
|
|
|
|
return payload?.found ? payload.conversation || null : null
|
2026-05-05 23:47:20 +08:00
|
|
|
|
}
|
2026-05-05 18:22:47 +08:00
|
|
|
|
|
2026-05-12 01:27:49 +00:00
|
|
|
|
function handleWorkbenchEnter(event) {
|
|
|
|
|
|
if (event.isComposing) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-12 06:39:26 +00:00
|
|
|
|
handleContinueConversation()
|
2026-05-12 01:27:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function triggerFileUpload() {
|
|
|
|
|
|
fileInputRef.value?.click()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function handleWorkbenchFilesChange(event) {
|
2026-05-12 06:39:26 +00:00
|
|
|
|
selectedFiles.value = Array.from(event.target.files ?? [])
|
|
|
|
|
|
}
|
2026-05-12 01:27:49 +00:00
|
|
|
|
|
2026-05-12 06:39:26 +00:00
|
|
|
|
async function handleContinueConversation() {
|
|
|
|
|
|
if (pendingAction.value || confirmDialogBusy.value) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pendingAction.value = 'continue'
|
|
|
|
|
|
const nextPayload = buildAssistantPayload()
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const conversation = await loadLatestConversation()
|
|
|
|
|
|
emitAssistant({
|
|
|
|
|
|
...nextPayload,
|
|
|
|
|
|
conversation
|
|
|
|
|
|
})
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.warn('Failed to load latest conversation:', error)
|
|
|
|
|
|
emitAssistant(nextPayload)
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
pendingAction.value = ''
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-05-12 01:27:49 +00:00
|
|
|
|
|
2026-05-12 06:39:26 +00:00
|
|
|
|
async function handleNewConversation() {
|
|
|
|
|
|
if (pendingAction.value || confirmDialogBusy.value) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pendingAction.value = 'new'
|
|
|
|
|
|
const nextPayload = buildAssistantPayload()
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const conversation = await loadLatestConversation()
|
|
|
|
|
|
if (!conversation) {
|
|
|
|
|
|
emitAssistant(nextPayload)
|
|
|
|
|
|
pendingAction.value = ''
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pendingAssistantPayload.value = nextPayload
|
|
|
|
|
|
confirmDialogOpen.value = true
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.warn('Failed to inspect latest conversation before reset:', error)
|
|
|
|
|
|
emitAssistant(nextPayload)
|
|
|
|
|
|
pendingAction.value = ''
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function closeConfirmDialog() {
|
|
|
|
|
|
if (confirmDialogBusy.value) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
confirmDialogOpen.value = false
|
|
|
|
|
|
pendingAssistantPayload.value = null
|
|
|
|
|
|
pendingAction.value = ''
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function confirmStartNewConversation() {
|
|
|
|
|
|
if (confirmDialogBusy.value) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
confirmDialogBusy.value = true
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
await clearUserConversations(resolveCurrentUserId())
|
|
|
|
|
|
const nextPayload = pendingAssistantPayload.value || buildAssistantPayload()
|
|
|
|
|
|
confirmDialogOpen.value = false
|
|
|
|
|
|
pendingAssistantPayload.value = null
|
|
|
|
|
|
pendingAction.value = ''
|
|
|
|
|
|
emitAssistant(nextPayload)
|
|
|
|
|
|
} catch (error) {
|
2026-05-13 03:27:30 +00:00
|
|
|
|
toast(error?.message || '清空历史会话失败,请稍后重试。')
|
2026-05-12 06:39:26 +00:00
|
|
|
|
} finally {
|
|
|
|
|
|
confirmDialogBusy.value = false
|
|
|
|
|
|
}
|
2026-05-12 01:27:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 18:22:47 +08:00
|
|
|
|
const todoItems = [
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '业务招待报销建议补参与人员',
|
2026-05-05 22:35:38 +08:00
|
|
|
|
tipLabel: 'AI 建议',
|
|
|
|
|
|
suggestion: '补充客户单位、客户人数、我方陪同人员',
|
2026-05-05 18:22:47 +08:00
|
|
|
|
action: '去补充',
|
|
|
|
|
|
icon: 'mdi mdi-account-group-outline',
|
|
|
|
|
|
color: '#10b981'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '差旅报销单待提交',
|
2026-05-05 22:35:38 +08:00
|
|
|
|
tipLabel: 'AI 建议',
|
|
|
|
|
|
suggestion: '补齐出发交通,可直接生成报销单',
|
2026-05-05 18:22:47 +08:00
|
|
|
|
action: '继续填写',
|
|
|
|
|
|
icon: 'mdi mdi-briefcase-outline',
|
|
|
|
|
|
color: '#16a34a'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '有 5 张票据未关联报销单',
|
2026-05-05 22:35:38 +08:00
|
|
|
|
tipLabel: 'AI 建议',
|
|
|
|
|
|
suggestion: '其中 3 张疑似交通费,可合并生成交通报销',
|
2026-05-05 18:22:47 +08:00
|
|
|
|
action: '去整理',
|
|
|
|
|
|
icon: 'mdi mdi-receipt-text-outline',
|
|
|
|
|
|
color: '#3b82f6'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
|
2026-05-05 22:35:38 +08:00
|
|
|
|
const todoAlertCount = todoItems.length
|
|
|
|
|
|
|
2026-05-05 18:22:47 +08:00
|
|
|
|
const progressItems = [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'travel',
|
|
|
|
|
|
title: '差旅报销',
|
|
|
|
|
|
amount: '¥3,280',
|
|
|
|
|
|
date: '2026-05-03',
|
|
|
|
|
|
status: '主管审批中',
|
|
|
|
|
|
tone: 'success',
|
|
|
|
|
|
icon: 'mdi mdi-airplane',
|
|
|
|
|
|
color: '#10b981'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'transport',
|
|
|
|
|
|
title: '交通报销',
|
|
|
|
|
|
amount: '¥126',
|
|
|
|
|
|
date: '2026-05-02',
|
|
|
|
|
|
status: '财务复核中',
|
|
|
|
|
|
tone: 'info',
|
|
|
|
|
|
icon: 'mdi mdi-car-outline',
|
|
|
|
|
|
color: '#3b82f6'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'office',
|
|
|
|
|
|
title: '办公采购',
|
|
|
|
|
|
amount: '¥458',
|
|
|
|
|
|
date: '2026-05-01',
|
|
|
|
|
|
status: '已到账',
|
|
|
|
|
|
tone: 'mint',
|
|
|
|
|
|
icon: 'mdi mdi-cart-outline',
|
|
|
|
|
|
color: '#16a34a'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
|
2026-05-05 22:35:38 +08:00
|
|
|
|
const progressAlertCount = progressItems.filter((item) => item.status !== '已到账').length
|
|
|
|
|
|
|
2026-05-05 18:22:47 +08:00
|
|
|
|
const policyItems = [
|
|
|
|
|
|
{
|
|
|
|
|
|
name: '差旅报销管理办法(2026版)',
|
|
|
|
|
|
summary: '更新住宿标准与交通等级规则',
|
2026-05-05 22:35:38 +08:00
|
|
|
|
date: '2026-05-04'
|
2026-05-05 18:22:47 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: '业务招待费用报销规范',
|
|
|
|
|
|
summary: '明确参与人员与事由填写要求',
|
2026-05-05 22:35:38 +08:00
|
|
|
|
date: '2026-05-02'
|
2026-05-05 18:22:47 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: '交通费用报销细则',
|
|
|
|
|
|
summary: '补充网约车与停车费报销说明',
|
2026-05-05 22:35:38 +08:00
|
|
|
|
date: '2026-04-28'
|
2026-05-05 18:22:47 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: '票据与附件提交规范通知',
|
|
|
|
|
|
summary: '统一附件命名与上传要求',
|
2026-05-05 22:35:38 +08:00
|
|
|
|
date: '2026-04-25'
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.workbench {
|
2026-05-12 15:39:00 +00:00
|
|
|
|
min-width: 0;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
display: grid;
|
|
|
|
|
|
gap: 16px;
|
2026-05-12 15:39:00 +00:00
|
|
|
|
padding-bottom: 10px;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-hero {
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
display: grid;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
grid-template-columns: 228px minmax(0, 1fr);
|
|
|
|
|
|
gap: 18px;
|
|
|
|
|
|
padding: 20px 24px 20px 18px;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
border: 1px solid rgba(16, 185, 129, 0.12);
|
|
|
|
|
|
background:
|
|
|
|
|
|
radial-gradient(circle at top left, rgba(16, 185, 129, 0.12), transparent 34%),
|
|
|
|
|
|
radial-gradient(circle at right 20%, rgba(59, 130, 246, 0.07), transparent 28%),
|
|
|
|
|
|
linear-gradient(135deg, #f7fffb 0%, #ffffff 48%, #f5fbff 100%);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-hero::before,
|
|
|
|
|
|
.assistant-hero::after {
|
|
|
|
|
|
content: "";
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
border-radius: 999px;
|
|
|
|
|
|
background: rgba(16, 185, 129, 0.06);
|
|
|
|
|
|
pointer-events: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-hero::before {
|
|
|
|
|
|
right: -48px;
|
|
|
|
|
|
bottom: -58px;
|
|
|
|
|
|
width: 220px;
|
|
|
|
|
|
height: 220px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-hero::after {
|
|
|
|
|
|
right: 92px;
|
|
|
|
|
|
top: -44px;
|
|
|
|
|
|
width: 140px;
|
|
|
|
|
|
height: 140px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-visual {
|
|
|
|
|
|
position: relative;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
min-height: 196px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: flex-end;
|
|
|
|
|
|
justify-content: flex-start;
|
|
|
|
|
|
padding: 0 0 10px 8px;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-07 11:50:10 +08:00
|
|
|
|
.assistant-visual::before {
|
2026-05-05 18:22:47 +08:00
|
|
|
|
content: "";
|
|
|
|
|
|
position: absolute;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
inset: auto auto -78px -58px;
|
|
|
|
|
|
width: 264px;
|
|
|
|
|
|
height: 228px;
|
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
|
background: radial-gradient(circle at 48% 38%, rgba(255, 255, 255, 0.92) 0%, rgba(220, 252, 231, 0.84) 58%, rgba(220, 252, 231, 0) 100%);
|
|
|
|
|
|
pointer-events: none;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-07 11:50:10 +08:00
|
|
|
|
.assistant-visual::after {
|
|
|
|
|
|
content: "";
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
left: 52px;
|
|
|
|
|
|
bottom: 18px;
|
|
|
|
|
|
width: 132px;
|
|
|
|
|
|
height: 18px;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
border-radius: 999px;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
background: rgba(16, 185, 129, 0.14);
|
|
|
|
|
|
filter: blur(12px);
|
|
|
|
|
|
pointer-events: none;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-07 11:50:10 +08:00
|
|
|
|
.assistant-glow {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
left: 24px;
|
|
|
|
|
|
bottom: 22px;
|
|
|
|
|
|
width: 176px;
|
|
|
|
|
|
height: 176px;
|
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
|
background: radial-gradient(circle, rgba(255, 255, 255, 0.98) 0%, rgba(236, 253, 245, 0.9) 58%, rgba(236, 253, 245, 0) 100%);
|
|
|
|
|
|
box-shadow: 0 24px 48px rgba(16, 185, 129, 0.12);
|
|
|
|
|
|
pointer-events: none;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 22:35:38 +08:00
|
|
|
|
.assistant-image {
|
2026-05-07 11:50:10 +08:00
|
|
|
|
position: relative;
|
|
|
|
|
|
z-index: 1;
|
|
|
|
|
|
width: 184px;
|
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
|
height: auto;
|
2026-05-05 22:35:38 +08:00
|
|
|
|
object-fit: contain;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
object-position: left bottom;
|
|
|
|
|
|
filter: drop-shadow(0 22px 28px rgba(15, 23, 42, 0.16));
|
2026-05-05 22:35:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 18:22:47 +08:00
|
|
|
|
.assistant-copy {
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
z-index: 1;
|
|
|
|
|
|
display: grid;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
gap: 10px;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
align-content: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-tag {
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
width: fit-content;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
padding: 6px 12px;
|
|
|
|
|
|
border-radius: 999px;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
background: linear-gradient(135deg, rgba(16, 185, 129, 0.14), rgba(59, 130, 246, 0.12));
|
|
|
|
|
|
color: #0f766e;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
font-weight: 800;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6);
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-copy h3 {
|
|
|
|
|
|
color: #0f172a;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
font-size: 26px;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
line-height: 1.25;
|
|
|
|
|
|
font-weight: 800;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-copy p {
|
|
|
|
|
|
max-width: 760px;
|
|
|
|
|
|
color: #5b6b83;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
line-height: 1.6;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-input {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
min-height: 48px;
|
|
|
|
|
|
padding: 4px 14px;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
border: 1px solid rgba(148, 163, 184, 0.28);
|
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
|
background: rgba(255, 255, 255, 0.92);
|
|
|
|
|
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-12 01:27:49 +00:00
|
|
|
|
.assistant-file-input {
|
|
|
|
|
|
display: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 23:47:20 +08:00
|
|
|
|
.assistant-input textarea {
|
2026-05-05 18:22:47 +08:00
|
|
|
|
min-width: 0;
|
|
|
|
|
|
flex: 1;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
height: 22px;
|
|
|
|
|
|
min-height: 22px;
|
|
|
|
|
|
max-height: 22px;
|
2026-05-05 23:47:20 +08:00
|
|
|
|
resize: none;
|
|
|
|
|
|
border: 0;
|
2026-05-06 11:00:38 +08:00
|
|
|
|
padding: 1px 0;
|
2026-05-05 23:47:20 +08:00
|
|
|
|
background: transparent;
|
|
|
|
|
|
color: #0f172a;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
font-size: 15px;
|
2026-05-06 11:00:38 +08:00
|
|
|
|
line-height: 22px;
|
|
|
|
|
|
overflow: hidden;
|
2026-05-05 23:47:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-input textarea::placeholder {
|
|
|
|
|
|
color: #94a3b8;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-input textarea:focus {
|
|
|
|
|
|
outline: none;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.hero-action,
|
2026-05-12 06:39:26 +00:00
|
|
|
|
.secondary-action,
|
2026-05-05 18:22:47 +08:00
|
|
|
|
.ghost-action,
|
|
|
|
|
|
.row-action,
|
|
|
|
|
|
.link-action,
|
|
|
|
|
|
.row-link {
|
|
|
|
|
|
border: 0;
|
|
|
|
|
|
background: transparent;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.hero-action {
|
2026-05-07 11:50:10 +08:00
|
|
|
|
height: 40px;
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
padding: 0 16px;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
border-radius: 10px;
|
|
|
|
|
|
background: linear-gradient(135deg, #10b981, #059669);
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-weight: 800;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
box-shadow: 0 10px 22px rgba(16, 185, 129, 0.18);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-07 11:50:10 +08:00
|
|
|
|
.hero-action .mdi,
|
2026-05-12 06:39:26 +00:00
|
|
|
|
.secondary-action .mdi,
|
2026-05-07 11:50:10 +08:00
|
|
|
|
.ghost-action .mdi {
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
line-height: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.hero-action span,
|
2026-05-12 06:39:26 +00:00
|
|
|
|
.secondary-action span,
|
2026-05-07 11:50:10 +08:00
|
|
|
|
.ghost-action span {
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
line-height: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 18:22:47 +08:00
|
|
|
|
.assistant-tools {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
gap: 10px;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-12 06:39:26 +00:00
|
|
|
|
.assistant-file-strip {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-file-note,
|
|
|
|
|
|
.assistant-file-chip {
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
min-height: 30px;
|
|
|
|
|
|
padding: 0 12px;
|
|
|
|
|
|
border-radius: 999px;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-file-note {
|
|
|
|
|
|
background: rgba(16, 185, 129, 0.1);
|
|
|
|
|
|
color: #047857;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-file-chip {
|
|
|
|
|
|
max-width: 220px;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
border: 1px solid rgba(148, 163, 184, 0.24);
|
|
|
|
|
|
background: rgba(255, 255, 255, 0.9);
|
|
|
|
|
|
color: #475569;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-file-clear {
|
|
|
|
|
|
border: 0;
|
|
|
|
|
|
background: transparent;
|
|
|
|
|
|
color: #64748b;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 18:22:47 +08:00
|
|
|
|
.ghost-action {
|
|
|
|
|
|
height: 40px;
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
align-items: center;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
justify-content: center;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
gap: 8px;
|
|
|
|
|
|
padding: 0 16px;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
border: 1px solid rgba(15, 118, 110, 0.18);
|
2026-05-05 18:22:47 +08:00
|
|
|
|
border-radius: 10px;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
background: linear-gradient(180deg, rgba(255, 255, 255, 0.94), rgba(244, 250, 247, 0.88));
|
|
|
|
|
|
color: #0f766e;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-weight: 700;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
box-shadow:
|
|
|
|
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.9),
|
|
|
|
|
|
0 6px 14px rgba(15, 118, 110, 0.06);
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-07 11:50:10 +08:00
|
|
|
|
.ghost-action .mdi {
|
|
|
|
|
|
color: #10b981;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-12 06:39:26 +00:00
|
|
|
|
.secondary-action {
|
|
|
|
|
|
height: 40px;
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
padding: 0 16px;
|
|
|
|
|
|
border: 1px solid rgba(59, 130, 246, 0.18);
|
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
|
background: linear-gradient(180deg, rgba(244, 249, 255, 0.96), rgba(234, 244, 255, 0.9));
|
|
|
|
|
|
color: #1d4ed8;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
box-shadow:
|
|
|
|
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.92),
|
|
|
|
|
|
0 6px 14px rgba(37, 99, 235, 0.08);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.secondary-action .mdi {
|
|
|
|
|
|
color: #2563eb;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.hero-action:disabled,
|
|
|
|
|
|
.secondary-action:disabled,
|
|
|
|
|
|
.ghost-action:disabled {
|
|
|
|
|
|
cursor: not-allowed;
|
|
|
|
|
|
opacity: 0.68;
|
|
|
|
|
|
box-shadow: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 18:22:47 +08:00
|
|
|
|
.workbench-grid {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
|
|
|
|
gap: 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.list-panel,
|
|
|
|
|
|
.policy-panel {
|
|
|
|
|
|
padding: 20px 22px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.section-head {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
gap: 12px;
|
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.section-head h3 {
|
|
|
|
|
|
color: #0f172a;
|
|
|
|
|
|
font-size: 17px;
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 22:35:38 +08:00
|
|
|
|
.title-with-badge {
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.alert-badge {
|
|
|
|
|
|
min-width: 22px;
|
|
|
|
|
|
height: 22px;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
2026-05-05 22:35:38 +08:00
|
|
|
|
padding: 0 7px;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
border-radius: 999px;
|
2026-05-05 22:35:38 +08:00
|
|
|
|
background: #ef4444;
|
|
|
|
|
|
color: #fff;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
font-weight: 800;
|
2026-05-05 22:35:38 +08:00
|
|
|
|
line-height: 1;
|
|
|
|
|
|
box-shadow: 0 6px 14px rgba(239, 68, 68, 0.22);
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.link-action {
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 4px;
|
|
|
|
|
|
color: #10b981;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.list-body {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.todo-row,
|
|
|
|
|
|
.progress-row {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: 48px minmax(0, 1fr) auto;
|
|
|
|
|
|
gap: 14px;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
padding: 14px 0;
|
|
|
|
|
|
border-top: 1px solid #edf2f7;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.todo-row:first-child,
|
|
|
|
|
|
.progress-row:first-child {
|
|
|
|
|
|
padding-top: 4px;
|
|
|
|
|
|
border-top: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.todo-icon {
|
|
|
|
|
|
width: 48px;
|
|
|
|
|
|
height: 48px;
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
place-items: center;
|
|
|
|
|
|
border-radius: 14px;
|
|
|
|
|
|
background: color-mix(in srgb, var(--icon-color) 12%, white);
|
|
|
|
|
|
color: var(--icon-color);
|
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.todo-copy {
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.todo-copy strong {
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
color: #0f172a;
|
|
|
|
|
|
font-size: 15px;
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
line-height: 1.4;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.todo-copy p {
|
|
|
|
|
|
margin-top: 4px;
|
|
|
|
|
|
color: #6b7280;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
line-height: 1.5;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 22:35:38 +08:00
|
|
|
|
.todo-advice {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.todo-advice-label {
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
min-height: 22px;
|
|
|
|
|
|
padding: 0 8px;
|
|
|
|
|
|
border-radius: 999px;
|
|
|
|
|
|
background: #ecfdf5;
|
|
|
|
|
|
color: #059669;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
font-weight: 800;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.todo-advice-text {
|
|
|
|
|
|
color: #64748b;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 18:22:47 +08:00
|
|
|
|
.row-action {
|
|
|
|
|
|
height: 38px;
|
|
|
|
|
|
padding: 0 16px;
|
|
|
|
|
|
border: 1px solid rgba(16, 185, 129, 0.36);
|
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
|
color: #10b981;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 22:35:38 +08:00
|
|
|
|
.progress-row {
|
|
|
|
|
|
grid-template-columns: 48px minmax(0, 1fr) minmax(84px, auto) minmax(104px, auto);
|
|
|
|
|
|
gap: 14px 16px;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 22:35:38 +08:00
|
|
|
|
.progress-copy strong {
|
|
|
|
|
|
margin-bottom: 2px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.progress-amount {
|
|
|
|
|
|
color: #0f172a;
|
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
|
font-weight: 800;
|
|
|
|
|
|
line-height: 1;
|
|
|
|
|
|
text-align: right;
|
|
|
|
|
|
font-variant-numeric: tabular-nums;
|
|
|
|
|
|
white-space: nowrap;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.progress-status {
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
2026-05-05 22:35:38 +08:00
|
|
|
|
min-width: 104px;
|
|
|
|
|
|
min-height: 34px;
|
|
|
|
|
|
padding: 6px 14px;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
border-radius: 999px;
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
font-weight: 800;
|
|
|
|
|
|
white-space: nowrap;
|
2026-05-05 22:35:38 +08:00
|
|
|
|
justify-self: end;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.progress-status.success,
|
|
|
|
|
|
.policy-status.success {
|
|
|
|
|
|
background: #eafaf2;
|
|
|
|
|
|
color: #16935f;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.progress-status.info,
|
|
|
|
|
|
.policy-status.info {
|
|
|
|
|
|
background: #eff6ff;
|
|
|
|
|
|
color: #3b82f6;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.progress-status.mint {
|
|
|
|
|
|
background: #edfdf5;
|
|
|
|
|
|
color: #10b981;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.policy-table {
|
|
|
|
|
|
border: 1px solid #e7edf5;
|
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.policy-row {
|
|
|
|
|
|
display: grid;
|
2026-05-05 22:35:38 +08:00
|
|
|
|
grid-template-columns: 2.2fr 2.4fr 1fr;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
gap: 16px;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
min-height: 56px;
|
|
|
|
|
|
padding: 0 18px;
|
|
|
|
|
|
border-top: 1px solid #edf2f7;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.policy-head {
|
|
|
|
|
|
min-height: 44px;
|
|
|
|
|
|
background: #f8fbff;
|
|
|
|
|
|
color: #64748b;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
font-weight: 800;
|
|
|
|
|
|
border-top: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.policy-row strong,
|
|
|
|
|
|
.policy-row span {
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.policy-row strong {
|
|
|
|
|
|
color: #0f172a;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.policy-row span {
|
|
|
|
|
|
color: #64748b;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 22:35:38 +08:00
|
|
|
|
.policy-title-cell,
|
|
|
|
|
|
.policy-summary-cell {
|
|
|
|
|
|
justify-self: stretch;
|
|
|
|
|
|
text-align: left;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 22:35:38 +08:00
|
|
|
|
.policy-date-cell {
|
|
|
|
|
|
justify-self: center;
|
|
|
|
|
|
text-align: center;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@media (max-width: 1320px) {
|
|
|
|
|
|
.assistant-copy h3 {
|
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.policy-row {
|
2026-05-05 22:35:38 +08:00
|
|
|
|
grid-template-columns: 1.8fr 1.8fr 1fr;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-12 15:39:00 +00:00
|
|
|
|
@media (max-width: 1440px) {
|
|
|
|
|
|
.workbench {
|
|
|
|
|
|
gap: 14px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-hero {
|
|
|
|
|
|
gap: 16px;
|
|
|
|
|
|
padding: 18px 20px 18px 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-copy h3 {
|
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-visual {
|
|
|
|
|
|
min-height: 184px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-image {
|
|
|
|
|
|
width: 172px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.workbench-grid {
|
|
|
|
|
|
gap: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.list-panel,
|
|
|
|
|
|
.policy-panel {
|
|
|
|
|
|
padding: 18px 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.policy-row {
|
|
|
|
|
|
min-height: 52px;
|
|
|
|
|
|
padding: 0 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 18:22:47 +08:00
|
|
|
|
@media (max-width: 1080px) {
|
|
|
|
|
|
.assistant-hero {
|
|
|
|
|
|
grid-template-columns: 1fr;
|
2026-05-07 11:50:10 +08:00
|
|
|
|
gap: 8px;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-visual {
|
2026-05-07 11:50:10 +08:00
|
|
|
|
min-height: 188px;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
padding: 0 0 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-visual::before,
|
|
|
|
|
|
.assistant-visual::after,
|
|
|
|
|
|
.assistant-glow {
|
|
|
|
|
|
left: 50%;
|
|
|
|
|
|
transform: translateX(-50%);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-visual::before {
|
|
|
|
|
|
inset: auto auto -82px 50%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-image {
|
|
|
|
|
|
width: 176px;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.workbench-grid {
|
|
|
|
|
|
grid-template-columns: 1fr;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@media (max-width: 860px) {
|
|
|
|
|
|
.assistant-hero,
|
|
|
|
|
|
.list-panel,
|
|
|
|
|
|
.policy-panel {
|
|
|
|
|
|
padding: 18px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-input {
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: stretch;
|
|
|
|
|
|
padding: 14px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-07 11:50:10 +08:00
|
|
|
|
.assistant-visual {
|
|
|
|
|
|
min-height: 160px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-glow {
|
|
|
|
|
|
width: 148px;
|
|
|
|
|
|
height: 148px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.assistant-image {
|
|
|
|
|
|
width: 150px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 23:47:20 +08:00
|
|
|
|
.assistant-input textarea {
|
2026-05-06 11:00:38 +08:00
|
|
|
|
height: 40px;
|
|
|
|
|
|
min-height: 40px;
|
|
|
|
|
|
max-height: 40px;
|
|
|
|
|
|
line-height: 1.5;
|
2026-05-05 18:22:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.hero-action,
|
2026-05-12 06:39:26 +00:00
|
|
|
|
.secondary-action,
|
2026-05-05 18:22:47 +08:00
|
|
|
|
.ghost-action,
|
|
|
|
|
|
.row-action {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-12 06:39:26 +00:00
|
|
|
|
.assistant-file-chip {
|
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 18:22:47 +08:00
|
|
|
|
.todo-row,
|
|
|
|
|
|
.progress-row {
|
|
|
|
|
|
grid-template-columns: 48px minmax(0, 1fr);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 22:35:38 +08:00
|
|
|
|
.progress-amount {
|
|
|
|
|
|
grid-column: 2;
|
|
|
|
|
|
text-align: left;
|
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 18:22:47 +08:00
|
|
|
|
.row-action,
|
|
|
|
|
|
.progress-status {
|
|
|
|
|
|
grid-column: 2;
|
|
|
|
|
|
justify-self: start;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.policy-table {
|
|
|
|
|
|
border: 0;
|
|
|
|
|
|
border-radius: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.policy-head {
|
|
|
|
|
|
display: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.policy-row {
|
|
|
|
|
|
grid-template-columns: 1fr;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
padding: 16px 0;
|
|
|
|
|
|
border-top: 1px solid #edf2f7;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.policy-row strong,
|
|
|
|
|
|
.policy-row span {
|
|
|
|
|
|
white-space: normal;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|
2026-05-09 03:04:09 +00:00
|
|
|
|
|
|
|
|
|
|
|