Merge branch 'release/test' of http://8.163.30.128:10082/html/admin-web into dev

This commit is contained in:
2026-09-14 17:07:27 +08:00
12 changed files with 258 additions and 122 deletions
@@ -203,7 +203,7 @@ describe('UnifiedOrdersView contract', () => {
it('counts detail in the three directly visible row actions', () => {
expect(source).toContain('unifiedOrderSecondaryActions(row).slice(0, 2)')
expect(source).toContain('unifiedOrderSecondaryActions(row).slice(2)')
expect(source).toContain('<Eye :size="15" />详情')
expect(source).toContain('@click="openDetail(row as UnifiedOrderResource)">详情</el-button>')
expect(source).toContain('v-if="moreUnifiedOrderActions(row as UnifiedOrderResource).length"')
})
@@ -652,9 +652,9 @@ describe('UnifiedOrdersView contract', () => {
it('uses outlined semantic buttons for row business actions while keeping detail navigation explicit', () => {
const rowActions = source.slice(source.indexOf('<template #actions'), source.indexOf('<template #inboundCode'))
expect(rowActions).toContain('size="small" plain :type="unifiedOrderActionType(action)"')
expect(rowActions).toContain('order-action-button')
expect(rowActions).not.toContain('v-for="action in directUnifiedOrderActions(row as UnifiedOrderResource)" :key="action" link')
expect(rowActions).toContain('<Eye :size="15" />详情')
expect(rowActions).toContain('@click="openDetail(row as UnifiedOrderResource)">详情</el-button>')
expect(source).toContain('<el-button link class="back-button"')
})
})
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, nextTick, onBeforeUnmount, onMounted, reactive, ref, watch, type Component } from 'vue'
import { computed, nextTick, onBeforeUnmount, onMounted, reactive, ref, watch } from 'vue'
import { ElMessage, ElMessageBox, type UploadFile } from 'element-plus'
import { ArrowLeft, ChevronDown, ChevronUp, CircleCheck, Download, Eye, FileUp, GitBranch, Link2, MoreHorizontal, PackageOpen, Printer, Ruler, Send, ShieldAlert, SlidersHorizontal, StickyNote, Undo2 } from '@lucide/vue'
import { ArrowLeft, ChevronDown, ChevronUp, CircleCheck, Download, FileUp, GitBranch, Link2, MoreHorizontal, PackageOpen, Printer, Send, ShieldAlert, SlidersHorizontal, StickyNote, Undo2 } from '@lucide/vue'
import { useRoute, useRouter } from 'vue-router'
import {
getPlatformUnifiedOrder,
@@ -1947,11 +1947,6 @@ function clearMeasurementOrder() {
}
type UnifiedOrderRowAction = 'note' | 'approve' | 'measurement'
const unifiedOrderRowActionIcons: Record<UnifiedOrderRowAction, Component> = {
note: StickyNote,
approve: CircleCheck,
measurement: Ruler,
}
function unifiedOrderSecondaryActions(row: UnifiedOrderResource): UnifiedOrderRowAction[] {
return [
...(canApprove(row) ? ['approve' as const] : []),
@@ -1973,9 +1968,6 @@ function unifiedOrderActionLabel(action: UnifiedOrderRowAction) {
if (action === 'approve') return '通过'
return '测量'
}
function unifiedOrderActionType(action: UnifiedOrderRowAction) {
return action === 'approve' ? 'success' : 'primary'
}
function runMoreAction(command: string | number | object, row: UnifiedOrderResource) {
if (command === 'note') openNoteDialog(row)
if (command === 'approve') openApproval(row)
@@ -2598,13 +2590,13 @@ onBeforeUnmount(() => {
</template>
<template #actions="{ row }">
<div class="row-actions">
<el-button size="small" plain type="primary" @click="openDetail(row as UnifiedOrderResource)"><Eye :size="15" />详情</el-button>
<el-button v-for="action in directUnifiedOrderActions(row as UnifiedOrderResource)" :key="action" size="small" plain :type="unifiedOrderActionType(action)" :loading="action === 'approve' && approvalLoadingId === String((row as UnifiedOrderResource).orderId)" @click="runMoreAction(action, row as UnifiedOrderResource)"><component :is="unifiedOrderRowActionIcons[action]" :size="15" />{{ unifiedOrderActionLabel(action) }}</el-button>
<el-button class="order-action-button" size="small" @click="openDetail(row as UnifiedOrderResource)">详情</el-button>
<el-button v-for="action in directUnifiedOrderActions(row as UnifiedOrderResource)" :key="action" :class="['order-action-button', `order-action-${action}`]" size="small" :loading="action === 'approve' && approvalLoadingId === String((row as UnifiedOrderResource).orderId)" @click="runMoreAction(action, row as UnifiedOrderResource)">{{ unifiedOrderActionLabel(action) }}</el-button>
<el-dropdown v-if="moreUnifiedOrderActions(row as UnifiedOrderResource).length" trigger="click" @command="runMoreAction($event, row as UnifiedOrderResource)">
<el-button size="small" plain type="primary" :aria-label="moreUnifiedOrderActionsLabel(row as UnifiedOrderResource)" :title="moreUnifiedOrderActionsLabel(row as UnifiedOrderResource)"><MoreHorizontal :size="17" /></el-button>
<el-button class="order-action-button" size="small" :aria-label="moreUnifiedOrderActionsLabel(row as UnifiedOrderResource)" :title="moreUnifiedOrderActionsLabel(row as UnifiedOrderResource)"><MoreHorizontal :size="17" aria-hidden="true" /></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-for="action in moreUnifiedOrderActions(row as UnifiedOrderResource)" :key="action" :command="action"><component :is="unifiedOrderRowActionIcons[action]" :size="15" />{{ unifiedOrderActionLabel(action) }}</el-dropdown-item>
<el-dropdown-item v-for="action in moreUnifiedOrderActions(row as UnifiedOrderResource)" :key="action" :command="action">{{ unifiedOrderActionLabel(action) }}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
@@ -2869,9 +2861,41 @@ onBeforeUnmount(() => {
.table-card :deep(.el-table td.el-table__cell) { height: 36px; padding: 4px 0; }
.table-card :deep(.el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell) { background: #fcfcfd; }
.table-card :deep(.el-table__body tr:hover > td.el-table__cell) { background: #f3f7fb; }
.row-actions { display: flex; align-items: center; gap: 4px; white-space: nowrap; }
.row-actions { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.row-actions :deep(.el-button) { margin-left: 0; }
.table-card :deep(.data-table__system-cell .row-actions .el-button) { height: 28px; margin-left: 0; padding: 4px 6px; font-size: 13px; }
.table-card :deep(.data-table__system-cell .row-actions .el-button) { height: 28px; margin-left: 0; padding: 4px 10px; font-size: 13px; }
.row-actions :deep(.order-action-button) {
--el-button-text-color: #52525b;
--el-button-bg-color: #fff;
--el-button-border-color: #dfe3ee;
--el-button-hover-text-color: #3f3f46;
--el-button-hover-bg-color: #f8fafc;
--el-button-hover-border-color: #b8c0d4;
--el-button-active-text-color: var(--el-button-hover-text-color);
--el-button-active-bg-color: var(--el-button-hover-bg-color);
--el-button-active-border-color: var(--el-button-hover-border-color);
--el-button-disabled-text-color: #a1a1aa;
--el-button-disabled-bg-color: #fff;
--el-button-disabled-border-color: #e5e7eb;
border-radius: 6px;
font-weight: 600;
box-shadow: none;
}
.row-actions :deep(.order-action-approve) {
--el-button-text-color: #c76500;
--el-button-border-color: #fed7aa;
--el-button-hover-text-color: #a34b00;
--el-button-hover-bg-color: #fff7ed;
--el-button-hover-border-color: #fb923c;
}
.row-actions :deep(.order-action-measurement) {
--el-button-text-color: #7c3aed;
--el-button-border-color: #ddd6fe;
--el-button-hover-text-color: #6d28d9;
--el-button-hover-bg-color: #f5f3ff;
--el-button-hover-border-color: #a78bfa;
}
.row-actions :deep(.order-action-button:focus-visible) { outline: 2px solid var(--el-button-text-color); outline-offset: 2px; }
.table-card :deep(.data-table__system-cell .row-actions .el-dropdown) { margin-left: 0; }
.planning-cell { display: grid; min-width: 0; gap: 4px; }
.planning-cell > small { color: var(--cc-muted); font-size: 11px; }