feat: 新增数字员工管理页面与工作台首页重构
后端优化 agent 资产种子初始化和常量配置,前端新增数字员工 视图和调度对话框组件,重构个人工作台首页布局和洞察面板, 完善审计页面数字员工详情和运行时模型,优化侧边栏导航和图 标配置,新增工作台摘要和工作台数据模块,补充单元测试。
This commit is contained in:
@@ -1,224 +1,230 @@
|
||||
<template>
|
||||
<div class="app" :class="{ 'sidebar-collapsed': sidebarCollapsed }">
|
||||
<div class="app-sidebar">
|
||||
<SidebarRail
|
||||
:nav-items="filteredNavItems"
|
||||
:active-view="activeView"
|
||||
:company-name="companyProfile.name"
|
||||
:company-logo="companyProfile.logo"
|
||||
:current-user="currentUser"
|
||||
:collapsed="sidebarCollapsed"
|
||||
@navigate="handleNavigate"
|
||||
@open-chat="openSmartEntry"
|
||||
@logout="handleLogout"
|
||||
@toggle-collapse="toggleSidebarCollapsed"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<main
|
||||
class="main"
|
||||
:class="{
|
||||
<template>
|
||||
<div class="app" :class="{ 'sidebar-collapsed': sidebarCollapsed }">
|
||||
<div class="app-sidebar">
|
||||
<SidebarRail
|
||||
:nav-items="filteredNavItems"
|
||||
:active-view="activeView"
|
||||
:company-name="companyProfile.name"
|
||||
:company-logo="companyProfile.logo"
|
||||
:current-user="currentUser"
|
||||
:collapsed="sidebarCollapsed"
|
||||
@navigate="handleNavigate"
|
||||
@open-chat="openSmartEntry"
|
||||
@logout="handleLogout"
|
||||
@toggle-collapse="toggleSidebarCollapsed"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<main
|
||||
class="main"
|
||||
:class="{
|
||||
'overview-main': activeView === 'overview',
|
||||
'workbench-main': activeView === 'workbench',
|
||||
'documents-main': activeView === 'documents',
|
||||
'budget-main': activeView === 'budget',
|
||||
'policies-main': activeView === 'policies',
|
||||
'audit-main': activeView === 'audit',
|
||||
'audit-detail-main': activeView === 'audit' && auditDetailOpen,
|
||||
'logs-main': activeView === 'logs',
|
||||
'employees-main': activeView === 'employees',
|
||||
'settings-main': activeView === 'settings'
|
||||
}"
|
||||
>
|
||||
<TopBar
|
||||
v-if="activeView !== 'settings' && !(activeView === 'audit' && auditDetailOpen)"
|
||||
:current-view="topBarView"
|
||||
:search="search"
|
||||
:active-view="activeView"
|
||||
:ranges="ranges"
|
||||
:active-range="activeRange"
|
||||
:employee-summary="employeeSummary"
|
||||
:knowledge-summary="knowledgeSummary"
|
||||
:logs-summary="logsSummary"
|
||||
:request-summary="requestSummary"
|
||||
:document-summary="documentSummary"
|
||||
:workbench-summary="workbenchSummary"
|
||||
:detail-mode="detailMode"
|
||||
:log-detail-mode="logDetailMode"
|
||||
:detail-alerts="detailAlerts"
|
||||
:custom-range="customRange"
|
||||
@update:search="search = $event"
|
||||
@update:active-range="activeRange = $event"
|
||||
@update:custom-range="customRange = $event"
|
||||
@batch-approve="toast('已批量通过 23 条审批任务。')"
|
||||
@new-application="openExpenseApplicationCreate"
|
||||
/>
|
||||
|
||||
<FilterBar
|
||||
v-if="activeView !== 'overview' && activeView !== 'workbench' && activeView !== 'documents' && activeView !== 'budget' && activeView !== 'policies' && activeView !== 'audit' && activeView !== 'logs' && activeView !== 'employees' && activeView !== 'settings'"
|
||||
:compact="activeView === 'overview'"
|
||||
:filters="filters"
|
||||
:ranges="ranges"
|
||||
:active-range="activeRange"
|
||||
@update:active-range="activeRange = $event"
|
||||
/>
|
||||
|
||||
<section
|
||||
class="workarea"
|
||||
:class="{
|
||||
'audit-main': activeView === 'audit',
|
||||
'audit-detail-main': activeView === 'audit' && auditDetailOpen,
|
||||
'digital-employees-main': activeView === 'digitalEmployees',
|
||||
'logs-main': activeView === 'logs',
|
||||
'employees-main': activeView === 'employees',
|
||||
'settings-main': activeView === 'settings'
|
||||
}"
|
||||
>
|
||||
<TopBar
|
||||
v-if="activeView !== 'settings' && !(activeView === 'audit' && auditDetailOpen)"
|
||||
:current-view="topBarView"
|
||||
:search="search"
|
||||
:active-view="activeView"
|
||||
:ranges="ranges"
|
||||
:active-range="activeRange"
|
||||
:employee-summary="employeeSummary"
|
||||
:knowledge-summary="knowledgeSummary"
|
||||
:logs-summary="logsSummary"
|
||||
:request-summary="requestSummary"
|
||||
:document-summary="documentSummary"
|
||||
:workbench-summary="workbenchSummary"
|
||||
:detail-mode="detailMode"
|
||||
:log-detail-mode="logDetailMode"
|
||||
:detail-alerts="detailAlerts"
|
||||
:custom-range="customRange"
|
||||
@update:search="search = $event"
|
||||
@update:active-range="activeRange = $event"
|
||||
@update:custom-range="customRange = $event"
|
||||
@batch-approve="toast('已批量通过 23 条审批任务。')"
|
||||
@new-application="openExpenseApplicationCreate"
|
||||
/>
|
||||
|
||||
<FilterBar
|
||||
v-if="activeView !== 'overview' && activeView !== 'workbench' && activeView !== 'documents' && activeView !== 'budget' && activeView !== 'policies' && activeView !== 'audit' && activeView !== 'digitalEmployees' && activeView !== 'logs' && activeView !== 'employees' && activeView !== 'settings'"
|
||||
:compact="activeView === 'overview'"
|
||||
:filters="filters"
|
||||
:ranges="ranges"
|
||||
:active-range="activeRange"
|
||||
@update:active-range="activeRange = $event"
|
||||
/>
|
||||
|
||||
<section
|
||||
class="workarea"
|
||||
:class="{
|
||||
'documents-workarea': activeView === 'documents',
|
||||
'workbench-workarea': activeView === 'workbench',
|
||||
'budget-workarea': activeView === 'budget',
|
||||
'policies-workarea': activeView === 'policies',
|
||||
'audit-workarea': activeView === 'audit',
|
||||
'logs-workarea': activeView === 'logs',
|
||||
'employees-workarea': activeView === 'employees',
|
||||
'settings-workarea': activeView === 'settings'
|
||||
}"
|
||||
>
|
||||
<OverviewView
|
||||
v-if="activeView === 'overview'"
|
||||
:filtered-requests="filteredRequests"
|
||||
@approve="handleApprove"
|
||||
@reject="handleReject"
|
||||
/>
|
||||
|
||||
<PersonalWorkbenchView
|
||||
v-else-if="activeView === 'workbench'"
|
||||
:assistant-modal-open="smartEntryOpen"
|
||||
@open-assistant="openSmartEntry"
|
||||
/>
|
||||
|
||||
'audit-workarea': activeView === 'audit',
|
||||
'digital-employees-workarea': activeView === 'digitalEmployees',
|
||||
'logs-workarea': activeView === 'logs',
|
||||
'employees-workarea': activeView === 'employees',
|
||||
'settings-workarea': activeView === 'settings'
|
||||
}"
|
||||
>
|
||||
<OverviewView
|
||||
v-if="activeView === 'overview'"
|
||||
:filtered-requests="filteredRequests"
|
||||
@approve="handleApprove"
|
||||
@reject="handleReject"
|
||||
/>
|
||||
|
||||
<PersonalWorkbenchView
|
||||
v-else-if="activeView === 'workbench'"
|
||||
:assistant-modal-open="smartEntryOpen"
|
||||
:workbench-summary="workbenchSummary"
|
||||
@open-assistant="openSmartEntry"
|
||||
/>
|
||||
|
||||
<TravelRequestDetailView
|
||||
v-else-if="activeView === 'documents' && detailMode && selectedRequest"
|
||||
:request="selectedRequest"
|
||||
back-label="返回单据中心"
|
||||
@back-to-requests="closeRequestDetail"
|
||||
@open-assistant="openSmartEntry"
|
||||
@request-updated="handleRequestUpdated"
|
||||
@request-deleted="handleRequestDeleted"
|
||||
/>
|
||||
|
||||
<DocumentsCenterView
|
||||
v-else-if="activeView === 'documents'"
|
||||
:filtered-requests="filteredRequests"
|
||||
:has-data="requests.length > 0"
|
||||
:loading="requestsLoading"
|
||||
:error="requestsError"
|
||||
@open-document="openRequestDetail"
|
||||
@create-request="openTravelCreate"
|
||||
@create-application="openExpenseApplicationCreate"
|
||||
@reload="reloadRequests"
|
||||
@summary-change="documentSummary = $event"
|
||||
/>
|
||||
|
||||
@open-assistant="openSmartEntry"
|
||||
@request-updated="handleRequestUpdated"
|
||||
@request-deleted="handleRequestDeleted"
|
||||
/>
|
||||
|
||||
<DocumentsCenterView
|
||||
v-else-if="activeView === 'documents'"
|
||||
:filtered-requests="filteredRequests"
|
||||
:has-data="requests.length > 0"
|
||||
:loading="requestsLoading"
|
||||
:error="requestsError"
|
||||
@open-document="openRequestDetail"
|
||||
@create-request="openTravelCreate"
|
||||
@create-application="openExpenseApplicationCreate"
|
||||
@reload="reloadRequests"
|
||||
@summary-change="documentSummary = $event"
|
||||
/>
|
||||
|
||||
<BudgetCenterView
|
||||
v-else-if="activeView === 'budget'"
|
||||
:current-user="currentUser"
|
||||
@open-assistant="openSmartEntry"
|
||||
/>
|
||||
<PoliciesView v-else-if="activeView === 'policies'" @summary-change="knowledgeSummary = $event" />
|
||||
<AuditView v-else-if="activeView === 'audit'" @detail-open-change="auditDetailOpen = $event" />
|
||||
<LogDetailView v-else-if="activeView === 'logs' && logDetailMode" />
|
||||
<LogsView v-else-if="activeView === 'logs'" @summary-change="logsSummary = $event" />
|
||||
<EmployeeManagementView v-else-if="activeView === 'employees'" @overview-change="employeeSummary = $event" />
|
||||
<SettingsView v-else />
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<TravelReimbursementCreateView
|
||||
v-if="smartEntryOpen"
|
||||
:key="smartEntrySessionId"
|
||||
:initial-prompt="smartEntryContext.prompt"
|
||||
:initial-files="smartEntryContext.files"
|
||||
:initial-conversation="smartEntryContext.conversation"
|
||||
<AuditView v-else-if="activeView === 'audit'" @detail-open-change="auditDetailOpen = $event" />
|
||||
<DigitalEmployeesView v-else-if="activeView === 'digitalEmployees'" />
|
||||
<LogDetailView v-else-if="activeView === 'logs' && logDetailMode" />
|
||||
<LogsView v-else-if="activeView === 'logs'" @summary-change="logsSummary = $event" />
|
||||
<EmployeeManagementView v-else-if="activeView === 'employees'" @overview-change="employeeSummary = $event" />
|
||||
<SettingsView v-else />
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<TravelReimbursementCreateView
|
||||
v-if="smartEntryOpen"
|
||||
:key="smartEntrySessionId"
|
||||
:initial-prompt="smartEntryContext.prompt"
|
||||
:initial-files="smartEntryContext.files"
|
||||
:initial-conversation="smartEntryContext.conversation"
|
||||
:entry-source="smartEntryContext.source"
|
||||
:request-context="smartEntryContext.request"
|
||||
:invalidated-draft-claim-id="smartEntryInvalidatedDraftClaimId"
|
||||
:reopen-token="smartEntryRevealToken"
|
||||
@close="closeSmartEntry"
|
||||
@draft-saved="handleDraftSaved"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import SidebarRail from '../components/layout/SidebarRail.vue'
|
||||
import TopBar from '../components/layout/TopBar.vue'
|
||||
import FilterBar from '../components/layout/FilterBar.vue'
|
||||
import OverviewView from './OverviewView.vue'
|
||||
import PersonalWorkbenchView from './PersonalWorkbenchView.vue'
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import SidebarRail from '../components/layout/SidebarRail.vue'
|
||||
import TopBar from '../components/layout/TopBar.vue'
|
||||
import FilterBar from '../components/layout/FilterBar.vue'
|
||||
import OverviewView from './OverviewView.vue'
|
||||
import PersonalWorkbenchView from './PersonalWorkbenchView.vue'
|
||||
import TravelReimbursementCreateView from './TravelReimbursementCreateView.vue'
|
||||
import TravelRequestDetailView from './TravelRequestDetailView.vue'
|
||||
import DocumentsCenterView from './DocumentsCenterView.vue'
|
||||
import BudgetCenterView from './BudgetCenterView.vue'
|
||||
import PoliciesView from './PoliciesView.vue'
|
||||
import AuditView from './AuditView.vue'
|
||||
import LogsView from './LogsView.vue'
|
||||
import LogDetailView from './LogDetailView.vue'
|
||||
import EmployeeManagementView from './EmployeeManagementView.vue'
|
||||
import SettingsView from './SettingsView.vue'
|
||||
|
||||
import { useAppShell } from '../composables/useAppShell.js'
|
||||
import { useSystemState } from '../composables/useSystemState.js'
|
||||
import { filterNavItemsByAccess } from '../utils/accessControl.js'
|
||||
|
||||
const employeeSummary = ref(null)
|
||||
const knowledgeSummary = ref(null)
|
||||
const logsSummary = ref(null)
|
||||
const documentSummary = ref(null)
|
||||
const auditDetailOpen = ref(false)
|
||||
const sidebarCollapsed = ref(true)
|
||||
|
||||
function toggleSidebarCollapsed() {
|
||||
sidebarCollapsed.value = !sidebarCollapsed.value
|
||||
}
|
||||
|
||||
const {
|
||||
activeRange,
|
||||
activeView,
|
||||
closeRequestDetail,
|
||||
closeSmartEntry,
|
||||
customRange,
|
||||
detailAlerts,
|
||||
detailMode,
|
||||
logDetailMode,
|
||||
filteredRequests,
|
||||
filters,
|
||||
handleApprove,
|
||||
handleDraftSaved,
|
||||
handleNavigate,
|
||||
handleReject,
|
||||
handleRequestDeleted,
|
||||
handleRequestUpdated,
|
||||
navItems,
|
||||
openExpenseApplicationCreate,
|
||||
openRequestDetail,
|
||||
openSmartEntry,
|
||||
openTravelCreate,
|
||||
ranges,
|
||||
requestSummary,
|
||||
workbenchSummary,
|
||||
requestsError,
|
||||
requestsLoading,
|
||||
reloadRequests,
|
||||
requests,
|
||||
search,
|
||||
selectedRequest,
|
||||
smartEntryContext,
|
||||
import AuditView from './AuditView.vue'
|
||||
import DigitalEmployeesView from './DigitalEmployeesView.vue'
|
||||
import LogsView from './LogsView.vue'
|
||||
import LogDetailView from './LogDetailView.vue'
|
||||
import EmployeeManagementView from './EmployeeManagementView.vue'
|
||||
import SettingsView from './SettingsView.vue'
|
||||
|
||||
import { useAppShell } from '../composables/useAppShell.js'
|
||||
import { useSystemState } from '../composables/useSystemState.js'
|
||||
import { filterNavItemsByAccess } from '../utils/accessControl.js'
|
||||
|
||||
const employeeSummary = ref(null)
|
||||
const knowledgeSummary = ref(null)
|
||||
const logsSummary = ref(null)
|
||||
const documentSummary = ref(null)
|
||||
const auditDetailOpen = ref(false)
|
||||
const sidebarCollapsed = ref(false)
|
||||
|
||||
function toggleSidebarCollapsed() {
|
||||
sidebarCollapsed.value = !sidebarCollapsed.value
|
||||
}
|
||||
|
||||
const {
|
||||
activeRange,
|
||||
activeView,
|
||||
closeRequestDetail,
|
||||
closeSmartEntry,
|
||||
customRange,
|
||||
detailAlerts,
|
||||
detailMode,
|
||||
logDetailMode,
|
||||
filteredRequests,
|
||||
filters,
|
||||
handleApprove,
|
||||
handleDraftSaved,
|
||||
handleNavigate,
|
||||
handleReject,
|
||||
handleRequestDeleted,
|
||||
handleRequestUpdated,
|
||||
navItems,
|
||||
openExpenseApplicationCreate,
|
||||
openRequestDetail,
|
||||
openSmartEntry,
|
||||
openTravelCreate,
|
||||
ranges,
|
||||
requestSummary,
|
||||
workbenchSummary,
|
||||
requestsError,
|
||||
requestsLoading,
|
||||
reloadRequests,
|
||||
requests,
|
||||
search,
|
||||
selectedRequest,
|
||||
smartEntryContext,
|
||||
smartEntryInvalidatedDraftClaimId,
|
||||
smartEntryOpen,
|
||||
smartEntryRevealToken,
|
||||
smartEntrySessionId,
|
||||
toast,
|
||||
topBarView
|
||||
} = useAppShell()
|
||||
|
||||
const { companyProfile, currentUser, logout } = useSystemState()
|
||||
const filteredNavItems = computed(() => filterNavItemsByAccess(navItems, currentUser.value))
|
||||
|
||||
function handleLogout() {
|
||||
logout('manual')
|
||||
}
|
||||
</script>
|
||||
toast,
|
||||
topBarView
|
||||
} = useAppShell()
|
||||
|
||||
const { companyProfile, currentUser, logout } = useSystemState()
|
||||
const filteredNavItems = computed(() => filterNavItemsByAccess(navItems, currentUser.value))
|
||||
|
||||
function handleLogout() {
|
||||
logout('manual')
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user