Skip to content

Commit 75236a4

Browse files
committed
fix(ui): 修复任务列表下拉选框文字截断问题和dock栏选中效果
1 parent b3297ab commit 75236a4

6 files changed

Lines changed: 136 additions & 13 deletions

File tree

src/frontEnd/src/components/CommandLinePreview.vue

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,41 @@ const highlightedCommand = computed(() => {
4040
if (!props.highlight) {
4141
return props.command
4242
}
43-
44-
// 简单的语法高亮
45-
return props.command
46-
.replace(/(--[a-zA-Z0-9-]+)/g, '<span class="param">$1</span>')
47-
.replace(/(-[a-zA-Z0-9])/g, '<span class="flag">$1</span>')
48-
.replace(/(".*?")/g, '<span class="string">$1</span>')
49-
.replace(/(\d+)/g, '<span class="number">$1</span>')
43+
44+
const escapeHtml = (str: string) =>
45+
str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;')
46+
47+
// 单次扫描正则:按优先级匹配各类 token,避免级联替换污染
48+
const tokenRegex = /("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')|(--[a-zA-Z][a-zA-Z0-9-]*)|(?<=\s|^)(-[a-zA-Z0-9])(?=\s|=|$)|(?<=[\s=])(\d+)(?=[\s,]|$)/g
49+
50+
const cmd = props.command
51+
let result = ''
52+
let lastIndex = 0
53+
54+
let match: RegExpExecArray | null
55+
while ((match = tokenRegex.exec(cmd)) !== null) {
56+
if (match.index > lastIndex) {
57+
result += escapeHtml(cmd.slice(lastIndex, match.index))
58+
}
59+
60+
if (match[1]) {
61+
result += `<span class="string">${escapeHtml(match[1])}</span>`
62+
} else if (match[2]) {
63+
result += `<span class="param">${escapeHtml(match[2])}</span>`
64+
} else if (match[3]) {
65+
result += `<span class="flag">${escapeHtml(match[3])}</span>`
66+
} else if (match[4]) {
67+
result += `<span class="number">${escapeHtml(match[4])}</span>`
68+
}
69+
70+
lastIndex = match.index + match[0].length
71+
}
72+
73+
if (lastIndex < cmd.length) {
74+
result += escapeHtml(cmd.slice(lastIndex))
75+
}
76+
77+
return result
5078
})
5179
5280
async function copyCommand() {

src/frontEnd/src/components/TaskFilter.vue

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,14 @@ function resetFilters() {
404404
height: 36px;
405405
}
406406
407+
// Select 组件内部 label 样式调整,防止文字被截断
408+
:deep(.p-select .p-select-label) {
409+
padding: 4px 8px;
410+
line-height: 20px;
411+
display: flex;
412+
align-items: center;
413+
}
414+
407415
// DatePicker 输入框
408416
:deep(.p-datepicker) {
409417
input.p-datepicker-input {

src/frontEnd/src/views/Layout.vue

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,9 @@ onUnmounted(() => {
263263
gap: 0.375rem;
264264
padding: 0.5rem 1rem;
265265
color: var(--p-text-secondary-color);
266+
border-radius: 12px;
267+
position: relative;
268+
overflow: hidden;
266269
}
267270
268271
.nav-item i {
@@ -277,13 +280,85 @@ onUnmounted(() => {
277280
color: var(--p-primary-color);
278281
}
279282
283+
/* 科幻蓝选中效果 */
280284
.nav-item.active {
281-
color: var(--p-primary-color);
282-
background: var(--p-surface-100);
285+
color: #fff;
286+
background: linear-gradient(135deg, #0ea5e9 0%, #3b82f6 50%, #6366f1 100%);
287+
box-shadow:
288+
0 0 20px rgba(59, 130, 246, 0.5),
289+
0 0 40px rgba(59, 130, 246, 0.3),
290+
0 0 60px rgba(59, 130, 246, 0.1),
291+
inset 0 1px 0 rgba(255, 255, 255, 0.3);
292+
transform: translateY(-2px);
293+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
283294
}
284295
296+
/* 跑马灯边框效果 - 从左上角单向射线式 */
297+
.nav-item.active::before {
298+
content: '';
299+
position: absolute;
300+
inset: 0;
301+
border-radius: 12px;
302+
padding: 2px;
303+
background: conic-gradient(from 0deg at 0% 0%, transparent 0deg, #60a5fa 30deg, #a78bfa 60deg, #60a5fa 90deg, transparent 120deg, transparent 360deg);
304+
animation: borderGlowRay 2s linear infinite;
305+
-webkit-mask:
306+
linear-gradient(#fff 0 0) content-box,
307+
linear-gradient(#fff 0 0);
308+
mask:
309+
linear-gradient(#fff 0 0) content-box,
310+
linear-gradient(#fff 0 0);
311+
-webkit-mask-composite: xor;
312+
mask-composite: exclude;
313+
}
314+
315+
/* 内部光效 */
316+
.nav-item.active::after {
317+
content: '';
318+
position: absolute;
319+
inset: 2px;
320+
border-radius: 10px;
321+
background: linear-gradient(135deg, rgba(255,255,255,0.2) 0%, transparent 50%, rgba(255,255,255,0.1) 100%);
322+
pointer-events: none;
323+
}
324+
325+
@keyframes borderGlowRay {
326+
0% {
327+
background: conic-gradient(from 0deg at 0% 0%, transparent 0deg, transparent 360deg);
328+
}
329+
10% {
330+
background: conic-gradient(from 0deg at 0% 0%, transparent 0deg, #60a5fa 10deg, #a78bfa 30deg, #60a5fa 50deg, transparent 70deg, transparent 360deg);
331+
}
332+
30% {
333+
background: conic-gradient(from 0deg at 0% 0%, transparent 0deg, transparent 20deg, #60a5fa 40deg, #a78bfa 70deg, #60a5fa 100deg, transparent 130deg, transparent 360deg);
334+
}
335+
50% {
336+
background: conic-gradient(from 0deg at 0% 0%, transparent 0deg, transparent 50deg, #60a5fa 80deg, #a78bfa 110deg, #60a5fa 140deg, transparent 170deg, transparent 360deg);
337+
}
338+
70% {
339+
background: conic-gradient(from 0deg at 0% 0%, transparent 0deg, transparent 80deg, #60a5fa 110deg, #a78bfa 140deg, #60a5fa 170deg, transparent 200deg, transparent 360deg);
340+
}
341+
90% {
342+
background: conic-gradient(from 0deg at 0% 0%, transparent 0deg, transparent 110deg, #60a5fa 140deg, #a78bfa 170deg, #60a5fa 200deg, transparent 230deg, transparent 360deg);
343+
}
344+
100% {
345+
background: conic-gradient(from 0deg at 0% 0%, transparent 0deg, transparent 360deg);
346+
}
347+
}
348+
349+
/* 暗色模式科幻效果 */
285350
:deep(.app-dark) .nav-item.active {
286-
background: var(--p-surface-800);
351+
background: linear-gradient(135deg, #0284c7 0%, #2563eb 50%, #4f46e5 100%);
352+
box-shadow:
353+
0 0 30px rgba(37, 99, 235, 0.6),
354+
0 0 60px rgba(37, 99, 235, 0.4),
355+
0 0 90px rgba(37, 99, 235, 0.2),
356+
inset 0 1px 0 rgba(255, 255, 255, 0.2);
357+
}
358+
359+
:deep(.app-dark) .nav-item.active::before {
360+
background: linear-gradient(90deg, transparent, #3b82f6, #8b5cf6, #3b82f6, transparent);
361+
background-size: 200% 100%;
287362
}
288363
289364
/* 路由过渡动画 */

src/frontEnd/src/views/TaskDetail/components/TaskHttpRequest.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ const copyHttpRequest = async () => {
390390
min-height: 0;
391391
overflow-y: auto;
392392
overflow-x: auto;
393-
border: 1px solid var(--p-surface-200);
393+
border: 1px solid var(--p-content-border-color);
394394
border-radius: 8px;
395395
background: var(--p-surface-900);
396396
line-height: 0.9;

src/frontEnd/src/views/TaskDetail/components/TaskOptions.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
:value="filteredOptions"
4141
striped-rows
4242
show-gridlines
43+
scrollable
44+
scroll-height="flex"
4345
class="options-table"
4446
>
4547
<Column field="name" header="配置项" sortable />
@@ -162,6 +164,8 @@ function getOptionDescription(name: string): string {
162164
display: flex;
163165
flex-direction: column;
164166
gap: 1rem;
167+
height: 100%;
168+
overflow: hidden;
165169
}
166170
167171
.view-toggle {
@@ -173,6 +177,7 @@ function getOptionDescription(name: string): string {
173177
display: flex;
174178
gap: 0.5rem;
175179
align-items: center;
180+
padding: 0 1rem;
176181
}
177182
178183
.search-bar :deep(.p-icon-field) {
@@ -181,6 +186,8 @@ function getOptionDescription(name: string): string {
181186
182187
.options-table {
183188
margin-top: 0.5rem;
189+
flex: 1;
190+
min-height: 0;
184191
}
185192
186193
.empty-state {

src/frontEnd/src/views/TaskDetail/styles/taskDetail.scss

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
bottom: 0;
1414
background:
1515
radial-gradient(circle at 25% 25%, rgba(99, 102, 241, 0.05) 0%, transparent 50%),
16-
radial-gradient(circle at 75% 75%, rgba(16, 185, 129, 0.05) 0%, transparent 50%),
17-
url("data:image/svg+xml,%3Csvg width='40' height='40' viewBox='0 0 40 40' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23f1f5f9' fill-opacity='0.2'%3E%3Cpath d='M20 20.5V18H0v-2h20v2.5zm0 2.5v2.5H0V23h20zm2 0h18v2H22v-2zm0-2.5h18V18H22v2.5z'/%3E%3C/g%3E%3C/svg%3E");
16+
radial-gradient(circle at 75% 75%, rgba(16, 185, 129, 0.05) 0%, transparent 50%);
1817
pointer-events: none;
1918
z-index: 0;
2019
}
@@ -137,6 +136,10 @@
137136
margin-left: 0;
138137
}
139138

139+
:deep(.p-tablist-tab-list) {
140+
border-bottom: none;
141+
}
142+
140143
:deep(.p-tab) {
141144
margin: 0;
142145
background: transparent;
@@ -196,6 +199,7 @@
196199
:deep(.p-tabpanels) {
197200
background: var(--p-content-background);
198201
border: 1px solid var(--p-content-border-color);
202+
border-top: none;
199203
border-radius: 0 0 16px 16px;
200204
box-shadow:
201205
0 8px 12px -2px rgba(0, 0, 0, 0.1),
@@ -305,6 +309,7 @@
305309
:deep(.p-tabpanels) {
306310
background: linear-gradient(145deg, #334155 0%, #1e293b 100%);
307311
border: 1px solid rgba(255, 255, 255, 0.1);
312+
border-top: none;
308313
}
309314
}
310315
}

0 commit comments

Comments
 (0)