style: 全局 UI 主题皮肤重构与样式模块化
引入 Element Plus 主题定制和主题皮肤 composable,将全局 样式拆分为组件级独立 CSS 文件(侧边栏、顶栏、工作台等), 统一色彩变量和间距规范,重构所有视图和组件样式以适配新 主题系统,优化图表和知识图谱组件视觉表现,提取审计和差 旅报销相关子组件。
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import TableLoadingState from '../../components/shared/TableLoadingState.vue'
|
||||
import TableEmptyState from '../../components/shared/TableEmptyState.vue'
|
||||
@@ -102,7 +102,6 @@ export default {
|
||||
const activeTypeFilter = ref(ARCHIVE_FILTER_ALL)
|
||||
const activeDepartmentFilter = ref(ARCHIVE_FILTER_ALL)
|
||||
const activeArchiveMonthFilter = ref(ARCHIVE_FILTER_ALL)
|
||||
const openFilterKey = ref('')
|
||||
const selectedClaimId = ref('')
|
||||
const listKeyword = ref('')
|
||||
const rows = ref([])
|
||||
@@ -118,7 +117,7 @@ export default {
|
||||
const departmentFilterLabel = computed(() => resolveFilterLabel(departmentFilterOptions.value, activeDepartmentFilter.value, '所属部门'))
|
||||
const archiveMonthFilterLabel = computed(() => resolveFilterLabel(archiveMonthFilterOptions.value, activeArchiveMonthFilter.value, '归档月份'))
|
||||
|
||||
const filterDropdowns = computed(() => [
|
||||
const filterMenus = computed(() => [
|
||||
{
|
||||
key: 'risk',
|
||||
label: riskFilterLabel.value,
|
||||
@@ -210,7 +209,6 @@ export default {
|
||||
activeDepartmentFilter.value = ARCHIVE_FILTER_ALL
|
||||
activeArchiveMonthFilter.value = ARCHIVE_FILTER_ALL
|
||||
listKeyword.value = ''
|
||||
openFilterKey.value = ''
|
||||
}
|
||||
|
||||
function handleEmptyAction() {
|
||||
@@ -222,10 +220,6 @@ export default {
|
||||
resetListFilters()
|
||||
}
|
||||
|
||||
function toggleFilterDropdown(key) {
|
||||
openFilterKey.value = openFilterKey.value === key ? '' : key
|
||||
}
|
||||
|
||||
function selectFilterValue(key, value) {
|
||||
if (key === 'risk') {
|
||||
activeRiskFilter.value = value
|
||||
@@ -237,18 +231,6 @@ export default {
|
||||
activeArchiveMonthFilter.value = value
|
||||
}
|
||||
|
||||
openFilterKey.value = ''
|
||||
}
|
||||
|
||||
function handleDocumentClick(event) {
|
||||
const target = event.target
|
||||
if (!(target instanceof Element)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!target.closest('.archive-dropdown-filter')) {
|
||||
openFilterKey.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
function closeSelectedDetail() {
|
||||
@@ -278,14 +260,6 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
document.addEventListener('click', handleDocumentClick)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
document.removeEventListener('click', handleDocumentClick)
|
||||
})
|
||||
|
||||
void reload()
|
||||
|
||||
return {
|
||||
@@ -293,11 +267,10 @@ export default {
|
||||
archiveEmptyState,
|
||||
closeSelectedDetail,
|
||||
error,
|
||||
filterDropdowns,
|
||||
filterMenus,
|
||||
handleEmptyAction,
|
||||
listKeyword,
|
||||
loading,
|
||||
openFilterKey,
|
||||
reload,
|
||||
resetListFilters,
|
||||
rows,
|
||||
@@ -305,7 +278,6 @@ export default {
|
||||
selectedRow,
|
||||
showEmpty,
|
||||
tabs,
|
||||
toggleFilterDropdown,
|
||||
visibleRows
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
|
||||
import ConfirmDialog from '../../components/shared/ConfirmDialog.vue'
|
||||
import AuditAssetList from '../../components/audit/AuditAssetList.vue'
|
||||
import AuditJsonRiskRuleDetail from '../../components/audit/AuditJsonRiskRuleDetail.vue'
|
||||
import AuditRuleDialogs from '../../components/audit/AuditRuleDialogs.vue'
|
||||
import AuditSpreadsheetChangeDrawer from '../../components/audit/AuditSpreadsheetChangeDrawer.vue'
|
||||
import AuditSpreadsheetRuleDetail from '../../components/audit/AuditSpreadsheetRuleDetail.vue'
|
||||
import AuditVersionTimelineDrawer from '../../components/audit/AuditVersionTimelineDrawer.vue'
|
||||
import { fetchEmployees } from '../../services/employees.js'
|
||||
import RiskRuleFlowDiagram from '../../components/shared/RiskRuleFlowDiagram.vue'
|
||||
import RiskRuleTestDialog from '../../components/shared/RiskRuleTestDialog.vue'
|
||||
import TableLoadingState from '../../components/shared/TableLoadingState.vue'
|
||||
import TableEmptyState from '../../components/shared/TableEmptyState.vue'
|
||||
import { useSystemState } from '../../composables/useSystemState.js'
|
||||
import { useToast } from '../../composables/useToast.js'
|
||||
import {
|
||||
@@ -77,11 +79,13 @@ import {
|
||||
export default {
|
||||
name: 'AuditView',
|
||||
components: {
|
||||
ConfirmDialog,
|
||||
RiskRuleFlowDiagram,
|
||||
RiskRuleTestDialog,
|
||||
TableLoadingState,
|
||||
TableEmptyState
|
||||
AuditAssetList,
|
||||
AuditJsonRiskRuleDetail,
|
||||
AuditRuleDialogs,
|
||||
AuditSpreadsheetChangeDrawer,
|
||||
AuditSpreadsheetRuleDetail,
|
||||
AuditVersionTimelineDrawer,
|
||||
TableLoadingState
|
||||
},
|
||||
emits: ['detail-open-change'],
|
||||
setup(_, { emit }) {
|
||||
@@ -115,6 +119,10 @@ export default {
|
||||
const reviewSubmitReviewer = ref('')
|
||||
const reviewSubmitReviewerLoading = ref(false)
|
||||
const reviewSubmitReviewerOptions = ref([])
|
||||
const riskRuleAttachmentOptions = [
|
||||
{ label: '是', value: true },
|
||||
{ label: '否', value: false }
|
||||
]
|
||||
const riskRuleCreateOpen = ref(false)
|
||||
const riskRuleCreateForm = ref(createDefaultRiskRuleForm())
|
||||
const riskRuleTestOpen = ref(false)
|
||||
@@ -466,7 +474,7 @@ export default {
|
||||
icon: hasFilters ? 'mdi mdi-tune-variant' : 'mdi mdi-view-grid-outline',
|
||||
actionLabel: hasFilters ? '清空筛选' : '',
|
||||
actionIcon: hasFilters ? 'mdi mdi-filter-remove-outline' : '',
|
||||
tone: hasFilters ? 'emerald' : 'slate',
|
||||
tone: hasFilters ? 'primary' : 'slate',
|
||||
artLabel: hasFilters ? 'FILTER' : 'QUEUE',
|
||||
tips: hasFilters
|
||||
? [
|
||||
@@ -956,7 +964,7 @@ export default {
|
||||
if (!canUploadSpreadsheet.value) {
|
||||
return
|
||||
}
|
||||
spreadsheetUploadInput.value?.click()
|
||||
spreadsheetUploadInput.value?.click?.()
|
||||
}
|
||||
|
||||
async function downloadSpreadsheetFile() {
|
||||
@@ -1003,9 +1011,7 @@ export default {
|
||||
toast(error?.message || '规则表内容导入失败,请稍后重试。')
|
||||
} finally {
|
||||
actionState.value = ''
|
||||
if (spreadsheetUploadInput.value) {
|
||||
spreadsheetUploadInput.value.value = ''
|
||||
}
|
||||
spreadsheetUploadInput.value?.reset?.()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1916,6 +1922,7 @@ export default {
|
||||
reviewSubmitReviewer,
|
||||
reviewSubmitReviewerLoading,
|
||||
reviewSubmitReviewerOptions,
|
||||
riskRuleAttachmentOptions,
|
||||
riskRuleCreateOpen,
|
||||
riskRuleCreateForm,
|
||||
riskRuleCreateBusy,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { computed, onMounted, ref, watch } from 'vue'
|
||||
|
||||
import BudgetTrendChart from '../../components/charts/BudgetTrendChart.vue'
|
||||
import ConfirmDialog from '../../components/shared/ConfirmDialog.vue'
|
||||
import EnterpriseSelect from '../../components/shared/EnterpriseSelect.vue'
|
||||
import { createBudgetAllocation, fetchBudgetSummary } from '../../services/budgets.js'
|
||||
import { fetchEmployeeMeta } from '../../services/employees.js'
|
||||
import {
|
||||
@@ -177,7 +178,8 @@ export default {
|
||||
},
|
||||
components: {
|
||||
BudgetTrendChart,
|
||||
ConfirmDialog
|
||||
ConfirmDialog,
|
||||
EnterpriseSelect
|
||||
},
|
||||
setup(props) {
|
||||
const departments = ref(FALLBACK_DEPARTMENTS)
|
||||
@@ -215,6 +217,14 @@ export default {
|
||||
const isDepartmentBudgetMonitor = computed(
|
||||
() => isBudgetMonitorUser(props.currentUser) && !canSwitchDepartments.value && !isExecutiveUser(props.currentUser)
|
||||
)
|
||||
const yearOptions = BUDGET_YEAR_OPTIONS.map((year) => ({ label: `${year}年度`, value: year }))
|
||||
const budgetPageSizeOptions = BUDGET_PAGE_SIZE_OPTIONS.map((size) => ({ label: `${size} 条/页`, value: size }))
|
||||
const departmentOptions = computed(() =>
|
||||
departments.value.map((department) => ({
|
||||
label: department.name,
|
||||
value: department.code
|
||||
}))
|
||||
)
|
||||
|
||||
const activeDepartment = computed(() =>
|
||||
departments.value.find((item) => item.code === activeDepartmentCode.value) || departments.value[0]
|
||||
@@ -273,7 +283,7 @@ export default {
|
||||
value: `¥${currency(totals.value.total)}`,
|
||||
yoy: comparison('+8.42%', 'up'),
|
||||
mom: comparison('+2.16%', 'up'),
|
||||
tone: 'green',
|
||||
tone: 'primary',
|
||||
icon: 'mdi mdi-wallet-outline'
|
||||
},
|
||||
{
|
||||
@@ -281,7 +291,7 @@ export default {
|
||||
value: `¥${currency(totals.value.used)}`,
|
||||
yoy: comparison('+12.68%', 'up'),
|
||||
mom: comparison('+4.35%', 'up'),
|
||||
tone: 'blue',
|
||||
tone: 'info',
|
||||
icon: 'mdi mdi-chart-line'
|
||||
},
|
||||
{
|
||||
@@ -289,7 +299,7 @@ export default {
|
||||
value: `¥${currency(totals.value.occupied)}`,
|
||||
yoy: comparison('+6.37%', 'up'),
|
||||
mom: comparison('-1.84%', 'down'),
|
||||
tone: 'orange',
|
||||
tone: 'warning',
|
||||
icon: 'mdi mdi-briefcase-check-outline'
|
||||
},
|
||||
{
|
||||
@@ -297,7 +307,7 @@ export default {
|
||||
value: `¥${currency(totals.value.left)}`,
|
||||
yoy: comparison('-3.26%', 'down'),
|
||||
mom: comparison('-2.08%', 'down'),
|
||||
tone: 'green',
|
||||
tone: 'primary',
|
||||
icon: 'mdi mdi-cash'
|
||||
}
|
||||
])
|
||||
@@ -612,7 +622,7 @@ export default {
|
||||
budgetPage: currentBudgetPage,
|
||||
budgetPageNumbers,
|
||||
budgetPageSize,
|
||||
budgetPageSizeOptions: BUDGET_PAGE_SIZE_OPTIONS,
|
||||
budgetPageSizeOptions,
|
||||
canEditBudget,
|
||||
canSwitchDepartments,
|
||||
closeBudgetEditDialog,
|
||||
@@ -633,6 +643,7 @@ export default {
|
||||
confirmDeleteRow,
|
||||
cancelDeleteRow,
|
||||
cancelSaveBudget,
|
||||
departmentOptions,
|
||||
requestSaveBudget,
|
||||
statusOptions: BUDGET_STATUS_OPTIONS,
|
||||
statuses: ['全部', '正常', '预警', '管控'],
|
||||
@@ -645,6 +656,7 @@ export default {
|
||||
visibleDepartments,
|
||||
warningOptions: BUDGET_WARNING_OPTIONS,
|
||||
warnings,
|
||||
yearOptions,
|
||||
years: BUDGET_YEAR_OPTIONS
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
|
||||
import ConfirmDialog from '../../components/shared/ConfirmDialog.vue'
|
||||
import EnterpriseSelect from '../../components/shared/EnterpriseSelect.vue'
|
||||
import TableLoadingState from '../../components/shared/TableLoadingState.vue'
|
||||
import TableEmptyState from '../../components/shared/TableEmptyState.vue'
|
||||
import { useToast } from '../../composables/useToast.js'
|
||||
@@ -438,6 +439,7 @@ export default {
|
||||
name: 'EmployeeManagementView',
|
||||
components: {
|
||||
ConfirmDialog,
|
||||
EnterpriseSelect,
|
||||
TableLoadingState,
|
||||
TableEmptyState
|
||||
},
|
||||
@@ -457,7 +459,7 @@ export default {
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(10)
|
||||
const pageSizes = [10, 20, 50]
|
||||
const pageSizeOpen = ref(false)
|
||||
const pageSizeOptions = pageSizes.map((size) => ({ label: `${size} 条/页`, value: size }))
|
||||
const actionState = ref('')
|
||||
const loading = ref(false)
|
||||
const errorMessage = ref('')
|
||||
@@ -713,7 +715,7 @@ export default {
|
||||
icon: hasEmployeeFilters.value ? 'mdi mdi-account-search-outline' : 'mdi mdi-badge-account-horizontal-outline',
|
||||
actionLabel: hasEmployeeFilters.value ? '清空筛选' : '查看全部员工',
|
||||
actionIcon: hasEmployeeFilters.value ? 'mdi mdi-filter-remove-outline' : 'mdi mdi-format-list-bulleted',
|
||||
tone: hasEmployeeFilters.value ? 'emerald' : 'slate',
|
||||
tone: hasEmployeeFilters.value ? 'primary' : 'slate',
|
||||
artLabel: hasEmployeeFilters.value ? 'FILTER' : 'STATUS',
|
||||
tips: hasEmployeeFilters.value
|
||||
? ['关键词、部门、职级和角色条件会叠加生效', '也可以直接搜索姓名、工号或岗位']
|
||||
@@ -791,7 +793,6 @@ export default {
|
||||
|
||||
watch(filteredEmployees, () => {
|
||||
currentPage.value = 1
|
||||
pageSizeOpen.value = false
|
||||
})
|
||||
|
||||
function resetFilters() {
|
||||
@@ -801,7 +802,6 @@ export default {
|
||||
selectedRole.value = ''
|
||||
activeTab.value = DEFAULT_STATUS_TABS[0]
|
||||
activeFilterPopover.value = ''
|
||||
pageSizeOpen.value = false
|
||||
}
|
||||
|
||||
function handleEmployeeEmptyAction() {
|
||||
@@ -815,14 +815,9 @@ export default {
|
||||
|
||||
function changePageSize(size) {
|
||||
pageSize.value = size
|
||||
pageSizeOpen.value = false
|
||||
currentPage.value = 1
|
||||
}
|
||||
|
||||
function togglePageSizeOpen() {
|
||||
pageSizeOpen.value = !pageSizeOpen.value
|
||||
}
|
||||
|
||||
function toggleFilterPopover(name) {
|
||||
activeFilterPopover.value = activeFilterPopover.value === name ? '' : name
|
||||
}
|
||||
@@ -852,7 +847,6 @@ export default {
|
||||
|
||||
if (!(target instanceof Element)) {
|
||||
closeFilterPopover()
|
||||
pageSizeOpen.value = false
|
||||
return
|
||||
}
|
||||
|
||||
@@ -868,13 +862,8 @@ export default {
|
||||
closeDepartmentPicker()
|
||||
}
|
||||
|
||||
if (!target.closest('.page-size-wrap')) {
|
||||
pageSizeOpen.value = false
|
||||
}
|
||||
|
||||
if (
|
||||
target.closest('.picker-filter') ||
|
||||
target.closest('.page-size-wrap') ||
|
||||
target.closest('.manager-picker') ||
|
||||
target.closest('.department-picker')
|
||||
) {
|
||||
@@ -1437,7 +1426,7 @@ export default {
|
||||
currentPage,
|
||||
pageSize,
|
||||
pageSizes,
|
||||
pageSizeOpen,
|
||||
pageSizeOptions,
|
||||
departmentOptions,
|
||||
gradeOptions,
|
||||
roleFilterOptions,
|
||||
@@ -1475,7 +1464,6 @@ export default {
|
||||
disableDialogOpen,
|
||||
disableEmployeeAccount,
|
||||
changePageSize,
|
||||
togglePageSizeOpen,
|
||||
toggleFilterPopover,
|
||||
closeFilterPopover,
|
||||
selectFilter,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ref } from 'vue'
|
||||
import { testModelConnectivity } from '../../services/settings.js'
|
||||
import { useToast } from '../../composables/useToast.js'
|
||||
import EnterpriseSelect from '../../components/shared/EnterpriseSelect.vue'
|
||||
|
||||
const MODEL_SECRET_MASK = '********'
|
||||
|
||||
@@ -101,6 +102,9 @@ function isModelSecretMask(value) {
|
||||
|
||||
export default {
|
||||
name: 'LlmSettingsPanel',
|
||||
components: {
|
||||
EnterpriseSelect
|
||||
},
|
||||
props: {
|
||||
llmForm: {
|
||||
type: Object,
|
||||
|
||||
@@ -11,7 +11,7 @@ export default {
|
||||
const showPassword = ref(false)
|
||||
|
||||
const features = [
|
||||
{ title: '智能审单', desc: 'AI 自动识别票据与规则,提升准确率与效率', icon: 'mdi mdi-file-document-outline', tone: 'green' },
|
||||
{ title: '智能审单', desc: 'AI 自动识别票据与规则,提升准确率与效率', icon: 'mdi mdi-file-document-outline', tone: 'primary' },
|
||||
{ title: '异常预警', desc: '多维风险识别与预警,主动防控风险', icon: 'mdi mdi-bell-outline', tone: 'red' },
|
||||
{ title: 'SLA 监控', desc: '实时监控服务水平协议,保障审批及时性', icon: 'mdi mdi-sync', tone: 'blue' }
|
||||
]
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useRouter } from 'vue-router'
|
||||
|
||||
import LogTrendChart from '../../components/charts/LogTrendChart.vue'
|
||||
import DonutChart from '../../components/charts/DonutChart.vue'
|
||||
import EnterpriseSelect from '../../components/shared/EnterpriseSelect.vue'
|
||||
import TableLoadingState from '../../components/shared/TableLoadingState.vue'
|
||||
import { fetchAgentRuns } from '../../services/agentAssets.js'
|
||||
import { fetchSystemLogEntries } from '../../services/systemLogs.js'
|
||||
@@ -221,6 +222,7 @@ export default {
|
||||
components: {
|
||||
LogTrendChart,
|
||||
DonutChart,
|
||||
EnterpriseSelect,
|
||||
TableLoadingState
|
||||
},
|
||||
emits: ['summary-change'],
|
||||
@@ -237,20 +239,28 @@ export default {
|
||||
const systemLevelFilter = ref('')
|
||||
const systemEventTypeFilter = ref('')
|
||||
const systemLogEntries = ref([])
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(10)
|
||||
const pageSizes = [10, 20, 50]
|
||||
const pageSizeOpen = ref(false)
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(10)
|
||||
const pageSizes = [10, 20, 50]
|
||||
const pageSizeOptions = pageSizes.map((size) => ({ label: `${size} 条/页`, value: size }))
|
||||
let pollTimer = 0
|
||||
|
||||
const isAdmin = computed(() => isManagerUser(currentUser.value))
|
||||
const filteredHermesRuns = computed(() => hermesRuns.value)
|
||||
const systemLevelOptions = computed(() =>
|
||||
Array.from(new Set(systemLogEntries.value.map((entry) => entry.level).filter(Boolean)))
|
||||
)
|
||||
const systemEventTypeOptions = computed(() =>
|
||||
Array.from(new Set(systemLogEntries.value.map((entry) => entry.event_type).filter(Boolean)))
|
||||
)
|
||||
const systemLevelOptions = computed(() =>
|
||||
Array.from(new Set(systemLogEntries.value.map((entry) => entry.level).filter(Boolean)))
|
||||
)
|
||||
const systemEventTypeOptions = computed(() =>
|
||||
Array.from(new Set(systemLogEntries.value.map((entry) => entry.event_type).filter(Boolean)))
|
||||
)
|
||||
const systemLevelFilterOptions = computed(() => [
|
||||
{ label: '全部', value: '' },
|
||||
...systemLevelOptions.value
|
||||
])
|
||||
const systemEventTypeFilterOptions = computed(() => [
|
||||
{ label: '全部', value: '' },
|
||||
...systemEventTypeOptions.value
|
||||
])
|
||||
const filteredSystemLogEntries = computed(() => {
|
||||
const keyword = systemSearchKeyword.value.trim().toLowerCase()
|
||||
return systemLogEntries.value.filter((entry) => {
|
||||
@@ -330,11 +340,10 @@ export default {
|
||||
return filteredSystemLogEntries.value.slice(start, start + pageSize.value)
|
||||
})
|
||||
|
||||
function changePageSize(size) {
|
||||
pageSize.value = size
|
||||
pageSizeOpen.value = false
|
||||
currentPage.value = 1
|
||||
}
|
||||
function changePageSize(size) {
|
||||
pageSize.value = size
|
||||
currentPage.value = 1
|
||||
}
|
||||
|
||||
async function loadHermesRuns() {
|
||||
if (!isAdmin.value) {
|
||||
@@ -456,8 +465,8 @@ export default {
|
||||
loadSystemLogs,
|
||||
currentPage,
|
||||
pageSize,
|
||||
pageSizeOpen,
|
||||
pageSizes,
|
||||
pageSizes,
|
||||
pageSizeOptions,
|
||||
resolveLevelTone,
|
||||
resolveRunLevel,
|
||||
resolveRunModuleLabel,
|
||||
@@ -472,10 +481,12 @@ export default {
|
||||
runningRunCount,
|
||||
selectRun,
|
||||
selectSystemLog,
|
||||
systemEventTypeFilter,
|
||||
systemEventTypeOptions,
|
||||
systemLevelFilter,
|
||||
systemLevelOptions,
|
||||
systemEventTypeFilter,
|
||||
systemEventTypeFilterOptions,
|
||||
systemEventTypeOptions,
|
||||
systemLevelFilter,
|
||||
systemLevelFilterOptions,
|
||||
systemLevelOptions,
|
||||
systemLogEntries,
|
||||
systemLogLoading,
|
||||
systemSearchKeyword,
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import EnterpriseSelect from '../../components/shared/EnterpriseSelect.vue'
|
||||
|
||||
export default {
|
||||
name: 'MailSettingsPanel',
|
||||
components: {
|
||||
EnterpriseSelect
|
||||
},
|
||||
props: {
|
||||
mailForm: {
|
||||
type: Object,
|
||||
@@ -7,6 +12,12 @@ export default {
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
const encryptionOptions = [
|
||||
{ label: 'SSL/TLS', value: 'SSL/TLS' },
|
||||
{ label: 'STARTTLS', value: 'STARTTLS' },
|
||||
{ label: '无', value: 'None' }
|
||||
]
|
||||
|
||||
function toggleField(field) {
|
||||
if (props.mailForm) {
|
||||
props.mailForm[field] = !props.mailForm[field]
|
||||
@@ -14,6 +25,7 @@ export default {
|
||||
}
|
||||
|
||||
return {
|
||||
encryptionOptions,
|
||||
toggleField
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,11 +36,11 @@ export default {
|
||||
}
|
||||
|
||||
const demoDepartments = [
|
||||
{ name: '销售部', amount: 182000, color: '#10b981' },
|
||||
{ name: '研发中心', amount: 146000, color: '#3b82f6' },
|
||||
{ name: '市场部', amount: 96000, color: '#f59e0b' },
|
||||
{ name: '运营部', amount: 68600, color: '#8b5cf6' },
|
||||
{ name: '行政部', amount: 48300, color: '#3b82f6' }
|
||||
{ name: '销售部', amount: 182000, color: 'var(--theme-primary)' },
|
||||
{ name: '研发中心', amount: 146000, color: 'var(--chart-blue)' },
|
||||
{ name: '市场部', amount: 96000, color: 'var(--chart-amber)' },
|
||||
{ name: '运营部', amount: 68600, color: 'var(--chart-purple)' },
|
||||
{ name: '行政部', amount: 48300, color: 'var(--chart-blue)' }
|
||||
]
|
||||
|
||||
const formatCompact = (value) => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
|
||||
import ConfirmDialog from '../../components/shared/ConfirmDialog.vue'
|
||||
import EnterpriseSelect from '../../components/shared/EnterpriseSelect.vue'
|
||||
import TableLoadingState from '../../components/shared/TableLoadingState.vue'
|
||||
import { useSystemState } from '../../composables/useSystemState.js'
|
||||
import { useToast } from '../../composables/useToast.js'
|
||||
@@ -86,6 +87,7 @@ export default {
|
||||
name: 'PoliciesView',
|
||||
components: {
|
||||
ConfirmDialog,
|
||||
EnterpriseSelect,
|
||||
TableLoadingState
|
||||
},
|
||||
emits: ['summary-change'],
|
||||
@@ -95,13 +97,13 @@ export default {
|
||||
|
||||
const documentSearch = ref('')
|
||||
const activeFolder = ref('')
|
||||
const folders = ref([])
|
||||
const documents = ref([])
|
||||
const selectedDocument = ref(null)
|
||||
const pageSizeOpen = ref(false)
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(10)
|
||||
const pageSizes = [10, 20, 50]
|
||||
const folders = ref([])
|
||||
const documents = ref([])
|
||||
const selectedDocument = ref(null)
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(10)
|
||||
const pageSizes = [10, 20, 50]
|
||||
const pageSizeOptions = pageSizes.map((size) => ({ label: `${size} 条/页`, value: size }))
|
||||
const loading = ref(false)
|
||||
const uploadInput = ref(null)
|
||||
const uploading = ref(false)
|
||||
@@ -558,11 +560,10 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
function changePageSize(size) {
|
||||
pageSize.value = size
|
||||
pageSizeOpen.value = false
|
||||
currentPage.value = 1
|
||||
}
|
||||
function changePageSize(size) {
|
||||
pageSize.value = size
|
||||
currentPage.value = 1
|
||||
}
|
||||
|
||||
function closePreview() {
|
||||
selectedDocument.value = null
|
||||
@@ -586,12 +587,11 @@ export default {
|
||||
currentPreviewPageIndex.value = index
|
||||
}
|
||||
|
||||
watch(filteredDocuments, () => {
|
||||
currentPage.value = 1
|
||||
pageSizeOpen.value = false
|
||||
|
||||
if (selectedDocument.value && !filteredDocuments.value.some((doc) => doc.id === selectedDocument.value.id)) {
|
||||
closePreview()
|
||||
watch(filteredDocuments, () => {
|
||||
currentPage.value = 1
|
||||
|
||||
if (selectedDocument.value && !filteredDocuments.value.some((doc) => doc.id === selectedDocument.value.id)) {
|
||||
closePreview()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -650,9 +650,9 @@ export default {
|
||||
knowledgeSyncButtonLabel,
|
||||
knowledgeSyncHint,
|
||||
loading,
|
||||
pageSize,
|
||||
pageSizeOpen,
|
||||
pageSizes,
|
||||
pageSize,
|
||||
pageSizeOptions,
|
||||
pageSizes,
|
||||
onlyOfficeError,
|
||||
onlyOfficeHostId,
|
||||
onlyOfficeLoading,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
import EnterpriseSelect from '../../components/shared/EnterpriseSelect.vue'
|
||||
import TableLoadingState from '../../components/shared/TableLoadingState.vue'
|
||||
import TableEmptyState from '../../components/shared/TableEmptyState.vue'
|
||||
import { normalizeRequestForUi } from '../../utils/requestViewModel.js'
|
||||
@@ -12,6 +13,7 @@ function extractRowDate(value) {
|
||||
export default {
|
||||
name: 'RequestsView',
|
||||
components: {
|
||||
EnterpriseSelect,
|
||||
TableLoadingState,
|
||||
TableEmptyState
|
||||
},
|
||||
@@ -61,11 +63,10 @@ export default {
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(10)
|
||||
const pageSizes = [10, 20, 50]
|
||||
const pageSizeOpen = ref(false)
|
||||
const pageSizeOptions = pageSizes.map((size) => ({ label: `${size} 条/页`, value: size }))
|
||||
|
||||
function changePageSize(size) {
|
||||
pageSize.value = size
|
||||
pageSizeOpen.value = false
|
||||
currentPage.value = 1
|
||||
}
|
||||
|
||||
@@ -132,7 +133,7 @@ export default {
|
||||
icon: 'mdi mdi-receipt-text-plus-outline',
|
||||
actionLabel: '',
|
||||
actionIcon: '',
|
||||
tone: 'emerald',
|
||||
tone: 'theme',
|
||||
artLabel: 'CLAIM',
|
||||
tips: ['保存草稿后会自动回到这里', '支持草稿、待提交、审批中和已完成全流程管理']
|
||||
}
|
||||
@@ -163,7 +164,6 @@ export default {
|
||||
rangeEnd.value = ''
|
||||
appliedStart.value = ''
|
||||
appliedEnd.value = ''
|
||||
pageSizeOpen.value = false
|
||||
currentPage.value = 1
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ export default {
|
||||
currentPage,
|
||||
pageSize,
|
||||
pageSizes,
|
||||
pageSizeOpen,
|
||||
pageSizeOptions,
|
||||
changePageSize,
|
||||
filteredRows,
|
||||
totalCount,
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import HermesEmployeeSettingsPanel from '../HermesEmployeeSettingsPanel.vue'
|
||||
import LlmSettingsPanel from '../LlmSettingsPanel.vue'
|
||||
import MailSettingsPanel from '../MailSettingsPanel.vue'
|
||||
import EnterpriseSelect from '../../components/shared/EnterpriseSelect.vue'
|
||||
import { useSettings } from '../../composables/useSettings.js'
|
||||
|
||||
export default {
|
||||
name: 'SettingsView',
|
||||
components: {
|
||||
HermesEmployeeSettingsPanel,
|
||||
EnterpriseSelect,
|
||||
LlmSettingsPanel,
|
||||
MailSettingsPanel
|
||||
},
|
||||
@@ -18,4 +20,3 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import ConfirmDialog from '../../components/shared/ConfirmDialog.vue'
|
||||
import TravelReimbursementInsightPanel from '../../components/travel/TravelReimbursementInsightPanel.vue'
|
||||
import TravelReimbursementMessageItem from '../../components/travel/TravelReimbursementMessageItem.vue'
|
||||
import { useSystemState } from '../../composables/useSystemState.js'
|
||||
import { useToast } from '../../composables/useToast.js'
|
||||
import { useTravelReimbursementFlow } from './useTravelReimbursementFlow.js'
|
||||
@@ -501,7 +503,9 @@ function buildReviewMainMessageText(message) {
|
||||
export default {
|
||||
name: 'TravelReimbursementCreateView',
|
||||
components: {
|
||||
ConfirmDialog
|
||||
ConfirmDialog,
|
||||
TravelReimbursementInsightPanel,
|
||||
TravelReimbursementMessageItem
|
||||
},
|
||||
props: {
|
||||
initialPrompt: {
|
||||
@@ -2109,8 +2113,126 @@ export default {
|
||||
await handleSaveDraftDirectly(message, 'save_draft')
|
||||
}
|
||||
|
||||
const messageItemUi = computed(() => ({
|
||||
ASSISTANT_DISPLAY_NAME,
|
||||
aiAvatar,
|
||||
userAvatar,
|
||||
submitting: submitting.value,
|
||||
reviewActionBusy: reviewActionBusy.value,
|
||||
sessionSwitchBusy: sessionSwitchBusy.value,
|
||||
applicationPreviewEditor: applicationPreviewEditor.value,
|
||||
buildMessageBubbleClass,
|
||||
buildReviewMainMessageText,
|
||||
renderMarkdown,
|
||||
handleAssistantMarkdownClick,
|
||||
resolveApplicationPreviewRows,
|
||||
resolveApplicationPreviewEditorControl,
|
||||
resolveApplicationPreviewEditorOptions,
|
||||
isApplicationPreviewEditing,
|
||||
openApplicationPreviewEditor,
|
||||
commitApplicationPreviewEditor,
|
||||
handleApplicationPreviewEditorKeydown,
|
||||
buildApplicationPreviewFooterText,
|
||||
runWelcomeQuickAction: runShortcut,
|
||||
handleSuggestedAction,
|
||||
isSuggestedActionSelected,
|
||||
buildExpenseQueryWindowLabel,
|
||||
buildExpenseQueryHint,
|
||||
getExpenseQueryActivePage,
|
||||
getExpenseQueryTotalPages,
|
||||
getExpenseQueryVisibleRecords,
|
||||
handleExpenseQueryRecordClick,
|
||||
appendExpenseQueryRiskToConversation,
|
||||
shiftExpenseQueryPage,
|
||||
setExpenseQueryPage,
|
||||
buildReviewPlainFollowupForMessage,
|
||||
canUseInlineSaveDraft,
|
||||
handleInlineSaveDraft,
|
||||
buildReviewNextStepRichCopyForMessage,
|
||||
resolveReviewFooterActions,
|
||||
handleReviewAction,
|
||||
buildReviewPrimaryButtonLabel
|
||||
}))
|
||||
|
||||
const insightPanelUi = computed(() => ({
|
||||
showInsightPanel: showInsightPanel.value,
|
||||
isKnowledgeSession: isKnowledgeSession.value,
|
||||
activeReviewPayload: activeReviewPayload.value,
|
||||
isReviewFlowDrawer: isReviewFlowDrawer.value,
|
||||
currentInsight: currentInsight.value,
|
||||
currentIntentLabel: currentIntentLabel.value,
|
||||
reviewDrawerTitle: reviewDrawerTitle.value,
|
||||
reviewOverviewDrawerAvailable: reviewOverviewDrawerAvailable.value,
|
||||
isReviewOverviewDrawer: isReviewOverviewDrawer.value,
|
||||
submitting: submitting.value,
|
||||
reviewActionBusy: reviewActionBusy.value,
|
||||
switchToReviewOverviewDrawer,
|
||||
reviewDocumentDrawerAvailable: reviewDocumentDrawerAvailable.value,
|
||||
isReviewDocumentDrawer: isReviewDocumentDrawer.value,
|
||||
toggleReviewDocumentDrawer,
|
||||
reviewDocumentDrawerIcon: reviewDocumentDrawerIcon.value,
|
||||
reviewRiskDrawerAvailable: reviewRiskDrawerAvailable.value,
|
||||
isReviewRiskDrawer: isReviewRiskDrawer.value,
|
||||
toggleReviewRiskDrawer,
|
||||
reviewRiskDrawerIcon: reviewRiskDrawerIcon.value,
|
||||
reviewFlowDrawerAvailable: reviewFlowDrawerAvailable.value,
|
||||
flowOverallStatusTone: flowOverallStatusTone.value,
|
||||
toggleReviewFlowDrawer,
|
||||
reviewFlowDrawerIcon: reviewFlowDrawerIcon.value,
|
||||
activeSessionType: activeSessionType.value,
|
||||
reviewDrawerMode: reviewDrawerMode.value,
|
||||
hotKnowledgeQuestions,
|
||||
deleteSessionBusy: deleteSessionBusy.value,
|
||||
sessionSwitchBusy: sessionSwitchBusy.value,
|
||||
askHotKnowledgeQuestion,
|
||||
resolveKnowledgeRankTone,
|
||||
resolveKnowledgeRankLabel,
|
||||
flowOverallStatusText: flowOverallStatusText.value,
|
||||
flowTotalDurationText: flowTotalDurationText.value,
|
||||
flowRunId: flowRunId.value,
|
||||
flowRefreshBusy: flowRefreshBusy.value,
|
||||
refreshFlowRunDetail,
|
||||
flowSteps: flowSteps.value,
|
||||
resolveFlowStepStatusLabel,
|
||||
formatFlowStepDuration,
|
||||
resolveFlowStepDetail,
|
||||
reviewIntentText: reviewIntentText.value,
|
||||
reviewFactCards: reviewFactCards.value,
|
||||
reviewInlineEditorKey: reviewInlineEditorKey.value,
|
||||
reviewInlineErrors: reviewInlineErrors.value,
|
||||
reviewInlineForm: reviewInlineForm.value,
|
||||
DATE_INPUT_FORMAT,
|
||||
REVIEW_SCENE_OPTIONS,
|
||||
REVIEW_SCENE_OTHER_OPTION,
|
||||
clearInlineReviewFieldError,
|
||||
commitInlineReviewEditor,
|
||||
selectInlineScene,
|
||||
reviewInlinePendingFiles: reviewInlinePendingFiles.value,
|
||||
openInlineReviewEditor,
|
||||
reviewPanelConfidence: reviewPanelConfidence.value,
|
||||
reviewCategoryOptions: reviewCategoryOptions.value,
|
||||
selectReviewCategory,
|
||||
reviewSelectedOtherCategory: reviewSelectedOtherCategory.value,
|
||||
reviewOtherCategoryOpen: reviewOtherCategoryOpen.value,
|
||||
reviewOtherCategoryOptions: reviewOtherCategoryOptions.value,
|
||||
selectReviewOtherCategory,
|
||||
activeReviewDocumentIndex: activeReviewDocumentIndex.value,
|
||||
reviewDocumentCount: reviewDocumentCount.value,
|
||||
goReviewDocument,
|
||||
activeReviewDocument: activeReviewDocument.value,
|
||||
activeReviewDocumentPreview: activeReviewDocumentPreview.value,
|
||||
canPreviewActiveReviewDocument: canPreviewActiveReviewDocument.value,
|
||||
openActiveReviewDocumentPreview,
|
||||
reviewRiskSummary: reviewRiskSummary.value,
|
||||
reviewRiskItems: reviewRiskItems.value,
|
||||
appendReviewRiskBriefToConversation,
|
||||
reviewRiskEmpty: reviewRiskEmpty.value,
|
||||
reviewHasUnsavedChanges: reviewHasUnsavedChanges.value,
|
||||
saveInlineReviewChanges
|
||||
}))
|
||||
|
||||
return {
|
||||
emit, ASSISTANT_DISPLAY_NAME, aiAvatar, userAvatar, fileInputRef, composerTextareaRef, messageListRef, composerDraft, composerDatePickerOpen, composerDateMode, composerSingleDate, composerRangeStartDate, composerRangeEndDate, composerBusinessTimeTags, composerCanApplyDateSelection,
|
||||
emit, messageItemUi, insightPanelUi, ASSISTANT_DISPLAY_NAME, aiAvatar, userAvatar, fileInputRef, composerTextareaRef, messageListRef, composerDraft, composerDatePickerOpen, composerDateMode, composerSingleDate, composerRangeStartDate, composerRangeEndDate, composerBusinessTimeTags, composerCanApplyDateSelection,
|
||||
toggleComposerDatePicker, closeComposerDatePicker, setComposerDateMode, handleComposerDateInputChange, removeComposerBusinessTimeTag, flowSteps, flowRunId, flowRefreshBusy, completedFlowStepCount, flowOverallStatusTone, flowOverallStatusText, flowTotalDurationText,
|
||||
attachedFiles, composerFilesExpanded, visibleAttachedFiles, hiddenAttachedFileCount, submitting, sessionSwitchBusy, messages, currentInsight, linkedRequest, canSubmit, activeSessionType, isKnowledgeSession, hotKnowledgeQuestions,
|
||||
hasInsightPanelContent, showInsightPanel, insightPanelToggleLabel, assistantHeaderTitle, assistantHeaderDescription, composerPlaceholder, currentIntentLabel, canDeleteCurrentSession, latestReviewMessage, activeReviewPayload, activeReviewPanelScope, activeReviewFilePreviews, reviewDrawerMode, isReviewOverviewDrawer, isReviewDocumentDrawer, isReviewRiskDrawer, isReviewFlowDrawer,
|
||||
|
||||
@@ -2,8 +2,11 @@ import { computed, onBeforeUnmount, reactive, ref, watch } from 'vue'
|
||||
|
||||
import { useSystemState } from '../../composables/useSystemState.js'
|
||||
import { useToast } from '../../composables/useToast.js'
|
||||
import EnterpriseSelect from '../../components/shared/EnterpriseSelect.vue'
|
||||
import ConfirmDialog from '../../components/shared/ConfirmDialog.vue'
|
||||
import ReturnReasonDialog from '../../components/shared/ReturnReasonDialog.vue'
|
||||
import TravelRequestApprovalDialog from '../../components/travel/TravelRequestApprovalDialog.vue'
|
||||
import TravelRequestDeleteDialog from '../../components/travel/TravelRequestDeleteDialog.vue'
|
||||
import TravelRequestReturnDialog from '../../components/travel/TravelRequestReturnDialog.vue'
|
||||
import {
|
||||
approveExpenseClaim,
|
||||
createExpenseClaimItem,
|
||||
@@ -358,7 +361,10 @@ export default {
|
||||
name: 'TravelRequestDetailView',
|
||||
components: {
|
||||
ConfirmDialog,
|
||||
ReturnReasonDialog
|
||||
EnterpriseSelect,
|
||||
TravelRequestApprovalDialog,
|
||||
TravelRequestDeleteDialog,
|
||||
TravelRequestReturnDialog
|
||||
},
|
||||
props: {
|
||||
request: {
|
||||
|
||||
@@ -71,7 +71,7 @@ export const TAB_META = {
|
||||
tableColumns: RULE_TABLE_COLUMNS,
|
||||
showRuntimeColumn: false,
|
||||
showStatusColumn: false,
|
||||
badgeTone: 'emerald'
|
||||
badgeTone: 'primary'
|
||||
},
|
||||
riskRules: {
|
||||
assetType: 'rule',
|
||||
|
||||
@@ -346,7 +346,7 @@ export function resolveTabMeta(tabId, typeKey) {
|
||||
return {
|
||||
...TYPE_META.rules,
|
||||
typeKey: 'rules',
|
||||
badgeTone: 'emerald'
|
||||
badgeTone: 'primary'
|
||||
}
|
||||
}
|
||||
return TAB_META[typeKey]
|
||||
|
||||
Reference in New Issue
Block a user