refactor(audit): reuse list shells and split models
This commit is contained in:
@@ -1,191 +1,166 @@
|
||||
<template>
|
||||
<article class="skill-list panel">
|
||||
<nav class="status-tabs" aria-label="能力类型">
|
||||
<button
|
||||
v-for="tab in tabs"
|
||||
:key="tab.id"
|
||||
type="button"
|
||||
:class="{ active: activeType === tab.id }"
|
||||
@click="emit('update:activeType', tab.id)"
|
||||
>
|
||||
{{ tab.label }}
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
<div class="list-toolbar">
|
||||
<div class="filter-set">
|
||||
<label class="search-filter">
|
||||
<i class="mdi mdi-magnify"></i>
|
||||
<input
|
||||
:value="keyword"
|
||||
type="search"
|
||||
:placeholder="searchPlaceholder"
|
||||
@input="emit('update:keyword', $event.target.value)"
|
||||
/>
|
||||
</label>
|
||||
|
||||
<AuditPickerFilter
|
||||
id="domain"
|
||||
title="选择业务域"
|
||||
close-label="关闭业务域选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedDomainLabel"
|
||||
:options="domainOptions"
|
||||
:selected-value="selectedDomain"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('domain', $event)"
|
||||
<EnterpriseListPage
|
||||
variant="skill-list"
|
||||
:tabs="shellTabs"
|
||||
:active-tab="activeType"
|
||||
tabs-label="能力类型"
|
||||
:loading="loading"
|
||||
:error="errorMessage"
|
||||
:empty="!visibleSkills.length"
|
||||
:empty-state="auditEmptyState"
|
||||
:loading-title="`${activeTabLabel}资产同步中`"
|
||||
:loading-message="`正在加载${activeTabLabel}资产`"
|
||||
loading-icon="mdi mdi-view-list-outline"
|
||||
:hint="hintText"
|
||||
@update:active-tab="emit('update:activeType', $event)"
|
||||
@empty-action="emit('empty-action')"
|
||||
>
|
||||
<template #filters>
|
||||
<label class="search-filter">
|
||||
<i class="mdi mdi-magnify"></i>
|
||||
<input
|
||||
:value="keyword"
|
||||
type="search"
|
||||
:placeholder="searchPlaceholder"
|
||||
@input="emit('update:keyword', $event.target.value)"
|
||||
/>
|
||||
</label>
|
||||
|
||||
<AuditPickerFilter
|
||||
v-if="showOwnerFilter"
|
||||
id="owner"
|
||||
title="选择负责人"
|
||||
close-label="关闭负责人选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedOwnerLabel"
|
||||
:options="ownerOptions"
|
||||
:selected-value="selectedOwner"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('owner', $event)"
|
||||
/>
|
||||
|
||||
<AuditPickerFilter
|
||||
v-if="showRiskLevelFilter"
|
||||
id="riskLevel"
|
||||
title="选择风险等级"
|
||||
close-label="关闭风险等级选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedRiskLevelLabel"
|
||||
:options="riskLevelOptions"
|
||||
:selected-value="selectedRiskLevel"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('riskLevel', $event)"
|
||||
/>
|
||||
|
||||
<AuditPickerFilter
|
||||
v-if="showRiskScenarioFilter"
|
||||
id="riskScenario"
|
||||
title="选择使用场景"
|
||||
close-label="关闭使用场景选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedRiskScenarioLabel"
|
||||
:options="riskScenarioOptions"
|
||||
:selected-value="selectedRiskScenario"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('riskScenario', $event)"
|
||||
/>
|
||||
|
||||
<AuditPickerFilter
|
||||
v-if="showOnlineFilter"
|
||||
id="online"
|
||||
title="选择上线状态"
|
||||
close-label="关闭上线状态选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedOnlineStateLabel"
|
||||
:options="onlineStateOptions"
|
||||
:selected-value="selectedOnlineState"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('online', $event)"
|
||||
/>
|
||||
|
||||
<AuditPickerFilter
|
||||
v-if="showEnabledFilter"
|
||||
id="enabled"
|
||||
title="选择启用状态"
|
||||
close-label="关闭启用状态选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedEnabledStateLabel"
|
||||
:options="enabledStateOptions"
|
||||
:selected-value="selectedEnabledState"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('enabled', $event)"
|
||||
/>
|
||||
|
||||
<AuditPickerFilter
|
||||
v-if="showStatusFilter"
|
||||
id="status"
|
||||
title="选择状态"
|
||||
close-label="关闭状态选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedStatusLabel"
|
||||
:options="statusOptions"
|
||||
:selected-value="selectedStatus"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('status', $event)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="toolbar-actions">
|
||||
<button
|
||||
v-if="activeFilterTokens.length"
|
||||
class="ghost-filter-btn"
|
||||
type="button"
|
||||
@click="emit('reset-filters')"
|
||||
>
|
||||
<i class="mdi mdi-filter-remove-outline"></i>
|
||||
<span>清空筛选</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="create-btn"
|
||||
type="button"
|
||||
:disabled="!canCreateRiskRule"
|
||||
@click="emit('create-risk-rule')"
|
||||
>
|
||||
<i class="mdi mdi-plus"></i>
|
||||
<span>{{ createButtonLabel }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="hint"><i class="mdi mdi-information-outline"></i> {{ hintText }}</p>
|
||||
|
||||
<div v-if="activeFilterTokens.length" class="active-filter-strip">
|
||||
<span v-for="token in activeFilterTokens" :key="token" class="active-filter-chip">
|
||||
{{ token }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="table-wrap"
|
||||
:class="{ 'is-empty': !loading && !errorMessage && !visibleSkills.length }"
|
||||
>
|
||||
<div v-if="loading" class="table-state">
|
||||
<TableLoadingState
|
||||
variant="panel"
|
||||
:title="`${activeTabLabel}资产同步中`"
|
||||
:message="`正在加载${activeTabLabel}资产`"
|
||||
icon="mdi mdi-view-list-outline"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-else-if="errorMessage" class="table-state error">
|
||||
<i class="mdi mdi-alert-circle-outline"></i>
|
||||
<p>{{ errorMessage }}</p>
|
||||
</div>
|
||||
|
||||
<TableEmptyState
|
||||
v-else-if="!visibleSkills.length"
|
||||
:eyebrow="auditEmptyState.eyebrow"
|
||||
:title="auditEmptyState.title"
|
||||
:description="auditEmptyState.desc"
|
||||
:icon="auditEmptyState.icon"
|
||||
:action-label="auditEmptyState.actionLabel"
|
||||
:action-icon="auditEmptyState.actionIcon"
|
||||
:tone="auditEmptyState.tone"
|
||||
:art-label="auditEmptyState.artLabel"
|
||||
:tips="auditEmptyState.tips"
|
||||
@action="emit('empty-action')"
|
||||
<AuditPickerFilter
|
||||
id="domain"
|
||||
title="选择业务域"
|
||||
close-label="关闭业务域选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedDomainLabel"
|
||||
:options="domainOptions"
|
||||
:selected-value="selectedDomain"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('domain', $event)"
|
||||
/>
|
||||
|
||||
<table v-else>
|
||||
<AuditPickerFilter
|
||||
v-if="showOwnerFilter"
|
||||
id="owner"
|
||||
title="选择负责人"
|
||||
close-label="关闭负责人选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedOwnerLabel"
|
||||
:options="ownerOptions"
|
||||
:selected-value="selectedOwner"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('owner', $event)"
|
||||
/>
|
||||
|
||||
<AuditPickerFilter
|
||||
v-if="showRiskLevelFilter"
|
||||
id="riskLevel"
|
||||
title="选择风险等级"
|
||||
close-label="关闭风险等级选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedRiskLevelLabel"
|
||||
:options="riskLevelOptions"
|
||||
:selected-value="selectedRiskLevel"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('riskLevel', $event)"
|
||||
/>
|
||||
|
||||
<AuditPickerFilter
|
||||
v-if="showRiskScenarioFilter"
|
||||
id="riskScenario"
|
||||
title="选择使用场景"
|
||||
close-label="关闭使用场景选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedRiskScenarioLabel"
|
||||
:options="riskScenarioOptions"
|
||||
:selected-value="selectedRiskScenario"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('riskScenario', $event)"
|
||||
/>
|
||||
|
||||
<AuditPickerFilter
|
||||
v-if="showOnlineFilter"
|
||||
id="online"
|
||||
title="选择上线状态"
|
||||
close-label="关闭上线状态选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedOnlineStateLabel"
|
||||
:options="onlineStateOptions"
|
||||
:selected-value="selectedOnlineState"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('online', $event)"
|
||||
/>
|
||||
|
||||
<AuditPickerFilter
|
||||
v-if="showEnabledFilter"
|
||||
id="enabled"
|
||||
title="选择启用状态"
|
||||
close-label="关闭启用状态选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedEnabledStateLabel"
|
||||
:options="enabledStateOptions"
|
||||
:selected-value="selectedEnabledState"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('enabled', $event)"
|
||||
/>
|
||||
|
||||
<AuditPickerFilter
|
||||
v-if="showStatusFilter"
|
||||
id="status"
|
||||
title="选择状态"
|
||||
close-label="关闭状态选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedStatusLabel"
|
||||
:options="statusOptions"
|
||||
:selected-value="selectedStatus"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('status', $event)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #actions>
|
||||
<button
|
||||
v-if="activeFilterTokens.length"
|
||||
class="ghost-filter-btn"
|
||||
type="button"
|
||||
@click="emit('reset-filters')"
|
||||
>
|
||||
<i class="mdi mdi-filter-remove-outline"></i>
|
||||
<span>清空筛选</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="create-btn"
|
||||
type="button"
|
||||
:disabled="!canCreateRiskRule"
|
||||
@click="emit('create-risk-rule')"
|
||||
>
|
||||
<i class="mdi mdi-plus"></i>
|
||||
<span>{{ createButtonLabel }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<template #meta>
|
||||
<div v-if="activeFilterTokens.length" class="active-filter-strip">
|
||||
<span v-for="token in activeFilterTokens" :key="token" class="active-filter-chip">
|
||||
{{ token }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #error>
|
||||
<i class="mdi mdi-alert-circle-outline"></i>
|
||||
<p>{{ errorMessage }}</p>
|
||||
</template>
|
||||
|
||||
<template #table>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ tableColumns.name }}</th>
|
||||
@@ -245,24 +220,27 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<footer v-if="!loading && !errorMessage && visibleSkills.length" class="list-foot">
|
||||
<span class="page-summary">当前展示 {{ visibleSkills.length }} 条资产</span>
|
||||
</footer>
|
||||
</article>
|
||||
<template #footer>
|
||||
<footer v-if="!loading && !errorMessage && visibleSkills.length" class="list-foot">
|
||||
<span class="page-summary">当前展示 {{ visibleSkills.length }} 条资产</span>
|
||||
</footer>
|
||||
</template>
|
||||
</EnterpriseListPage>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
import AuditPickerFilter from './AuditPickerFilter.vue'
|
||||
import TableEmptyState from '../shared/TableEmptyState.vue'
|
||||
import TableLoadingState from '../shared/TableLoadingState.vue'
|
||||
import EnterpriseListPage from '../shared/EnterpriseListPage.vue'
|
||||
|
||||
defineOptions({
|
||||
name: 'AuditAssetList'
|
||||
})
|
||||
|
||||
defineProps({
|
||||
const props = defineProps({
|
||||
tabs: { type: Array, default: () => [] },
|
||||
activeType: { type: String, default: '' },
|
||||
activeTabLabel: { type: String, default: '' },
|
||||
@@ -325,6 +303,13 @@ const emit = defineEmits([
|
||||
'open-asset-detail'
|
||||
])
|
||||
|
||||
const shellTabs = computed(() =>
|
||||
props.tabs.map((tab) => ({
|
||||
value: tab.id,
|
||||
label: tab.label
|
||||
}))
|
||||
)
|
||||
|
||||
function selectFilter(type, value) {
|
||||
emit('select-filter', type, value)
|
||||
}
|
||||
|
||||
@@ -1,120 +1,103 @@
|
||||
<template>
|
||||
<section class="digital-employee-list-panel">
|
||||
<div class="list-toolbar">
|
||||
<div class="filter-set">
|
||||
<label class="search-filter">
|
||||
<i class="mdi mdi-magnify"></i>
|
||||
<input
|
||||
:value="keyword"
|
||||
type="search"
|
||||
placeholder="搜索数字员工技能、编号、执行计划或维护人"
|
||||
@input="emit('update:keyword', $event.target.value)"
|
||||
/>
|
||||
</label>
|
||||
|
||||
<AuditPickerFilter
|
||||
id="status"
|
||||
title="选择资产状态"
|
||||
close-label="关闭资产状态选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedStatusLabel"
|
||||
:options="statusOptions"
|
||||
:selected-value="selectedStatus"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('status', $event)"
|
||||
<EnterpriseListPage
|
||||
variant="digital-employee-list-panel"
|
||||
:panel="false"
|
||||
:loading="loading"
|
||||
:error="errorMessage"
|
||||
:empty="!visibleEmployees.length"
|
||||
:empty-state="emptyState"
|
||||
loading-title="数字员工资产同步中"
|
||||
loading-message="正在加载数字员工资产"
|
||||
loading-icon="mdi mdi-view-list-outline"
|
||||
hint="归集后台自动执行的数字员工技能,可查看技能内容、执行计划、启动状态和最近版本。"
|
||||
>
|
||||
<template #filters>
|
||||
<label class="search-filter">
|
||||
<i class="mdi mdi-magnify"></i>
|
||||
<input
|
||||
:value="keyword"
|
||||
type="search"
|
||||
placeholder="搜索数字员工技能、编号、执行计划或维护人"
|
||||
@input="emit('update:keyword', $event.target.value)"
|
||||
/>
|
||||
</label>
|
||||
|
||||
<AuditPickerFilter
|
||||
id="enabled"
|
||||
title="选择启动状态"
|
||||
close-label="关闭启动状态选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedEnabledLabel"
|
||||
:options="enabledStateOptions"
|
||||
:selected-value="selectedEnabledState"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('enabled', $event)"
|
||||
/>
|
||||
|
||||
<AuditPickerFilter
|
||||
id="executionMode"
|
||||
title="选择执行方式"
|
||||
close-label="关闭执行方式选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedExecutionModeLabel"
|
||||
:options="executionModeOptions"
|
||||
:selected-value="selectedExecutionMode"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('executionMode', $event)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="toolbar-actions">
|
||||
<button
|
||||
v-if="keyword || activeFilterTokens.length"
|
||||
class="ghost-filter-btn"
|
||||
type="button"
|
||||
@click="emit('reset-filters')"
|
||||
>
|
||||
<i class="mdi mdi-filter-remove-outline"></i>
|
||||
<span>清空筛选</span>
|
||||
</button>
|
||||
<button
|
||||
class="create-btn digital-refresh-action"
|
||||
type="button"
|
||||
:disabled="loading"
|
||||
@click="emit('load-employees')"
|
||||
>
|
||||
<i class="mdi mdi-refresh"></i>
|
||||
<span>{{ loading ? '刷新中...' : '刷新' }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="hint">
|
||||
<i class="mdi mdi-information-outline"></i>
|
||||
归集后台自动执行的数字员工技能,可查看技能内容、执行计划、启动状态和最近版本。
|
||||
</p>
|
||||
|
||||
<div v-if="activeFilterTokens.length" class="active-filter-strip">
|
||||
<span v-for="token in activeFilterTokens" :key="token" class="active-filter-chip">
|
||||
{{ token }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="table-wrap digital-table-wrap"
|
||||
:class="{ 'is-empty': !loading && !errorMessage && !visibleEmployees.length }"
|
||||
>
|
||||
<div v-if="loading" class="table-state">
|
||||
<TableLoadingState
|
||||
variant="panel"
|
||||
title="数字员工资产同步中"
|
||||
message="正在加载数字员工资产"
|
||||
icon="mdi mdi-view-list-outline"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-else-if="errorMessage" class="table-state error">
|
||||
<i class="mdi mdi-alert-circle-outline"></i>
|
||||
<p>{{ errorMessage }}</p>
|
||||
</div>
|
||||
|
||||
<TableEmptyState
|
||||
v-else-if="!visibleEmployees.length"
|
||||
eyebrow="数字员工"
|
||||
title="暂无匹配的数字员工"
|
||||
description="当前没有符合搜索条件的后台执行技能。"
|
||||
icon="mdi mdi-account-cog-outline"
|
||||
tone="theme"
|
||||
art-label="STAFF"
|
||||
:tips="['数字员工已从规则中心拆出为独立入口', '运行与定时操作统一进入详情后处理']"
|
||||
<AuditPickerFilter
|
||||
id="status"
|
||||
title="选择资产状态"
|
||||
close-label="关闭资产状态选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedStatusLabel"
|
||||
:options="statusOptions"
|
||||
:selected-value="selectedStatus"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('status', $event)"
|
||||
/>
|
||||
|
||||
<table v-else class="digital-employees-table">
|
||||
<AuditPickerFilter
|
||||
id="enabled"
|
||||
title="选择启动状态"
|
||||
close-label="关闭启动状态选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedEnabledLabel"
|
||||
:options="enabledStateOptions"
|
||||
:selected-value="selectedEnabledState"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('enabled', $event)"
|
||||
/>
|
||||
|
||||
<AuditPickerFilter
|
||||
id="executionMode"
|
||||
title="选择执行方式"
|
||||
close-label="关闭执行方式选择"
|
||||
:active-filter-popover="activeFilterPopover"
|
||||
:label="selectedExecutionModeLabel"
|
||||
:options="executionModeOptions"
|
||||
:selected-value="selectedExecutionMode"
|
||||
@toggle="emit('toggle-filter-popover', $event)"
|
||||
@close="emit('close-filter-popover')"
|
||||
@select="selectFilter('executionMode', $event)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #actions>
|
||||
<button
|
||||
v-if="keyword || activeFilterTokens.length"
|
||||
class="ghost-filter-btn"
|
||||
type="button"
|
||||
@click="emit('reset-filters')"
|
||||
>
|
||||
<i class="mdi mdi-filter-remove-outline"></i>
|
||||
<span>清空筛选</span>
|
||||
</button>
|
||||
<button
|
||||
class="create-btn digital-refresh-action"
|
||||
type="button"
|
||||
:disabled="loading"
|
||||
@click="emit('load-employees')"
|
||||
>
|
||||
<i class="mdi mdi-refresh"></i>
|
||||
<span>{{ loading ? '刷新中...' : '刷新' }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<template #meta>
|
||||
<div v-if="activeFilterTokens.length" class="active-filter-strip">
|
||||
<span v-for="token in activeFilterTokens" :key="token" class="active-filter-chip">
|
||||
{{ token }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #error>
|
||||
<i class="mdi mdi-alert-circle-outline"></i>
|
||||
<p>{{ errorMessage }}</p>
|
||||
</template>
|
||||
|
||||
<template #table>
|
||||
<table class="digital-employees-table">
|
||||
<colgroup>
|
||||
<col class="col-skill">
|
||||
<col class="col-skill-type">
|
||||
@@ -164,38 +147,39 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<footer v-if="!loading && !errorMessage && visibleEmployees.length" class="list-foot digital-employee-pagination">
|
||||
<span class="page-summary">共 {{ visibleEmployees.length }} 条,目前第 {{ currentPage }} / {{ totalPages }} 页</span>
|
||||
<div class="pager" aria-label="员工技能分页">
|
||||
<button class="page-nav" type="button" :disabled="currentPage === 1" @click="currentPage--">
|
||||
<i class="mdi mdi-chevron-left"></i>
|
||||
</button>
|
||||
<button
|
||||
v-for="page in pageNumbers"
|
||||
:key="page"
|
||||
class="page-number"
|
||||
:class="{ active: currentPage === page }"
|
||||
type="button"
|
||||
@click="currentPage = page"
|
||||
>
|
||||
{{ page }}
|
||||
</button>
|
||||
<button class="page-nav" type="button" :disabled="currentPage === totalPages" @click="currentPage++">
|
||||
<i class="mdi mdi-chevron-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</footer>
|
||||
</section>
|
||||
<template #footer>
|
||||
<footer v-if="!loading && !errorMessage && visibleEmployees.length" class="list-foot digital-employee-pagination">
|
||||
<span class="page-summary">共 {{ visibleEmployees.length }} 条,目前第 {{ currentPage }} / {{ totalPages }} 页</span>
|
||||
<div class="pager" aria-label="员工技能分页">
|
||||
<button class="page-nav" type="button" :disabled="currentPage === 1" @click="currentPage--">
|
||||
<i class="mdi mdi-chevron-left"></i>
|
||||
</button>
|
||||
<button
|
||||
v-for="page in pageNumbers"
|
||||
:key="page"
|
||||
class="page-number"
|
||||
:class="{ active: currentPage === page }"
|
||||
type="button"
|
||||
@click="currentPage = page"
|
||||
>
|
||||
{{ page }}
|
||||
</button>
|
||||
<button class="page-nav" type="button" :disabled="currentPage === totalPages" @click="currentPage++">
|
||||
<i class="mdi mdi-chevron-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
</EnterpriseListPage>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
import AuditPickerFilter from './AuditPickerFilter.vue'
|
||||
import TableEmptyState from '../shared/TableEmptyState.vue'
|
||||
import TableLoadingState from '../shared/TableLoadingState.vue'
|
||||
import EnterpriseListPage from '../shared/EnterpriseListPage.vue'
|
||||
|
||||
defineOptions({
|
||||
name: 'DigitalEmployeeListPanel'
|
||||
@@ -244,6 +228,15 @@ const pageNumbers = computed(() => {
|
||||
const start = Math.max(1, Math.min(currentPage.value - 3, total - 6))
|
||||
return Array.from({ length: 7 }, (_, index) => start + index)
|
||||
})
|
||||
const emptyState = {
|
||||
eyebrow: '数字员工',
|
||||
title: '暂无匹配的数字员工',
|
||||
description: '当前没有符合搜索条件的后台执行技能。',
|
||||
icon: 'mdi mdi-account-cog-outline',
|
||||
tone: 'theme',
|
||||
artLabel: 'STAFF',
|
||||
tips: ['数字员工已从规则中心拆出为独立入口', '运行与定时操作统一进入详情后处理']
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [props.keyword, props.selectedStatus, props.selectedEnabledState, props.selectedExecutionMode],
|
||||
@@ -279,7 +272,7 @@ function selectFilter(type, value) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.digital-employee-list-panel .digital-table-wrap {
|
||||
.digital-employee-list-panel :deep(.table-wrap) {
|
||||
flex: 1 1 0;
|
||||
min-height: 0;
|
||||
}
|
||||
@@ -302,7 +295,7 @@ function selectFilter(type, value) {
|
||||
gap: 6px;
|
||||
padding: 4px;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 12px;
|
||||
border-radius: 4px;
|
||||
background: #f8fafc;
|
||||
}
|
||||
|
||||
@@ -310,7 +303,7 @@ function selectFilter(type, value) {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border: 0;
|
||||
border-radius: 9px;
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
color: #334155;
|
||||
font-size: 14px;
|
||||
@@ -321,7 +314,7 @@ function selectFilter(type, value) {
|
||||
.digital-employee-list-panel .pager button:hover:not(.active):not(:disabled) {
|
||||
background: #fff;
|
||||
color: var(--theme-primary-active);
|
||||
box-shadow: 0 1px 4px rgba(15, 23, 42, .08);
|
||||
box-shadow: 0 1px 4px rgba(15, 23, 42, 0.08);
|
||||
}
|
||||
|
||||
.digital-employee-list-panel .pager button.active {
|
||||
|
||||
Reference in New Issue
Block a user