feat: 数字员工财务报告体系与定时提醒及看板快照调度
- 新增数字员工财务报告生成、邮件投递与渲染调度器 - 引入员工画像扫描调度与定时提醒任务 - 完善财务看板快照、排行口径与部门人员占比计算 - 优化数字员工工作看板仪表盘与技能目录 - 增强前端总览页图表、工作台摘要与顶部导航栏交互 - 新增差旅申请规划推动提醒与报销创建会话状态管理 - 补充财务报告、看板调度、数字员工工作记录测试覆盖
This commit is contained in:
@@ -191,41 +191,6 @@
|
||||
</div>
|
||||
|
||||
<div class="workbench-content-grid">
|
||||
<article class="panel workbench-card todo-panel">
|
||||
<div class="section-head">
|
||||
<div class="title-with-badge">
|
||||
<h2>我的待办</h2>
|
||||
<span class="soft-badge">{{ todoAlertCount }}</span>
|
||||
</div>
|
||||
<button type="button" class="link-action">全部待办 <i class="mdi mdi-chevron-right"></i></button>
|
||||
</div>
|
||||
|
||||
<div class="todo-list">
|
||||
<button
|
||||
v-for="item in visibleTodoItems"
|
||||
:key="item.title"
|
||||
type="button"
|
||||
class="todo-row"
|
||||
@click="openPromptAssistant(`帮我处理:${item.title},${item.description}`)"
|
||||
>
|
||||
<WorkbenchListIcon
|
||||
:icon-key="item.iconKey"
|
||||
:color="item.color"
|
||||
:accent="item.accent"
|
||||
/>
|
||||
<span class="todo-copy">
|
||||
<strong>{{ item.title }}</strong>
|
||||
<small>{{ item.description }}</small>
|
||||
</span>
|
||||
<span class="todo-meta">
|
||||
<span class="todo-status" :class="`todo-status--${item.statusTone}`">{{ item.status }}</span>
|
||||
<small>{{ item.due }}</small>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</article>
|
||||
|
||||
<article class="panel workbench-card progress-panel">
|
||||
<div class="section-head">
|
||||
<h2>费用进度</h2>
|
||||
@@ -238,7 +203,7 @@
|
||||
:key="item.id"
|
||||
type="button"
|
||||
class="progress-row"
|
||||
@click="openPromptAssistant(`查询 ${item.id} 的费用进度`)"
|
||||
@click="openWorkbenchTarget(item)"
|
||||
>
|
||||
<span class="progress-identity">
|
||||
<strong>{{ item.id }}</strong>
|
||||
@@ -247,17 +212,17 @@
|
||||
|
||||
<span class="progress-steps" aria-hidden="true">
|
||||
<span
|
||||
v-for="(step, index) in progressSteps"
|
||||
:key="step"
|
||||
v-for="step in item.steps"
|
||||
:key="step.label"
|
||||
class="progress-step"
|
||||
:class="{
|
||||
'is-done': index < item.activeStep,
|
||||
'is-current': index === item.activeStep,
|
||||
'is-future': index > item.activeStep
|
||||
'is-done': step.done,
|
||||
'is-current': step.current,
|
||||
'is-future': !step.done && !step.current
|
||||
}"
|
||||
>
|
||||
<i :class="index <= item.activeStep ? 'mdi mdi-check' : 'mdi mdi-minus'"></i>
|
||||
<small>{{ step }}</small>
|
||||
<i :class="step.done || step.current ? 'mdi mdi-check' : 'mdi mdi-minus'"></i>
|
||||
<small>{{ step.label }}</small>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
@@ -357,7 +322,6 @@
|
||||
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
import PanelHead from '../shared/PanelHead.vue'
|
||||
import ExpenseProfileDetailModal from './ExpenseProfileDetailModal.vue'
|
||||
import WorkbenchListIcon from '../shared/WorkbenchListIcon.vue'
|
||||
import workbenchHeroBackground from '../../assets/personal-workbench-hero-bg-theme-base.webp'
|
||||
import { useSystemState } from '../../composables/useSystemState.js'
|
||||
import { useToast } from '../../composables/useToast.js'
|
||||
@@ -365,11 +329,8 @@ import { useWorkbenchComposerDate } from '../../composables/useWorkbenchComposer
|
||||
import {
|
||||
buildExpenseStatItems,
|
||||
filterAssistantCapabilitiesForUser,
|
||||
progressItems,
|
||||
progressSteps,
|
||||
quickPromptItems,
|
||||
resolveWorkbenchCapabilityGridClass,
|
||||
todoItems,
|
||||
} from '../../data/personalWorkbench.js'
|
||||
import { fetchAgentRuns } from '../../services/agentAssets.js'
|
||||
import { clearUserConversations, fetchLatestConversation } from '../../services/orchestrator.js'
|
||||
@@ -394,7 +355,7 @@ const props = defineProps({
|
||||
workbenchSummary: { type: Object, default: () => ({}) }
|
||||
})
|
||||
|
||||
const emit = defineEmits(['open-assistant'])
|
||||
const emit = defineEmits(['open-assistant', 'open-document'])
|
||||
const { currentUser } = useSystemState()
|
||||
const { toast } = useToast()
|
||||
const assistantDraft = ref('')
|
||||
@@ -494,9 +455,12 @@ const currentUserProfileKey = computed(() => {
|
||||
user.employee_no
|
||||
].map((item) => String(item || '').trim()).filter(Boolean).join('|')
|
||||
})
|
||||
const visibleTodoItems = computed(() => todoItems.slice(0, 5))
|
||||
const visibleProgressItems = computed(() => progressItems.slice(0, 5))
|
||||
const todoAlertCount = computed(() => visibleTodoItems.value.length)
|
||||
const visibleProgressItems = computed(() => {
|
||||
const rows = Array.isArray(props.workbenchSummary.progressItems)
|
||||
? props.workbenchSummary.progressItems
|
||||
: []
|
||||
return rows.slice(0, 5)
|
||||
})
|
||||
|
||||
function buildSelectedFileKey(file) {
|
||||
return [file?.name, file?.size, file?.lastModified, file?.type].join('__')
|
||||
@@ -625,6 +589,20 @@ function openPromptAssistant(prompt) {
|
||||
emitAssistant(payload)
|
||||
}
|
||||
|
||||
function openWorkbenchTarget(item) {
|
||||
const target = item?.target || {}
|
||||
if (target.type === 'document' && (target.id || target.claimNo)) {
|
||||
emit('open-document', {
|
||||
claimId: target.id,
|
||||
id: target.id || target.claimNo,
|
||||
claimNo: target.claimNo
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
openPromptAssistant(item?.prompt || `查询 ${item?.id || ''} 的费用进度`)
|
||||
}
|
||||
|
||||
function openCapabilityAssistant(item) {
|
||||
if (pendingAction.value) {
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user