Browse Source

Merge pull request '```' (#94) from cjl-new into master

Reviewed-on: http://120.26.116.243:3000/root/alert-front/pulls/94
pull/101/head
chenjiale 3 weeks ago
parent
commit
1776ac265d
  1. 339
      src/views/model/list/ModelCard.vue
  2. 2
      src/views/model/list/data.tsx

339
src/views/model/list/ModelCard.vue

@ -62,6 +62,8 @@ function normalizeCards(modelList: any[] = []): ModelItem[] {
const card: ModelItem = { const card: ModelItem = {
id: modelCard.id, id: modelCard.id,
title: modelCard.name, title: modelCard.name,
unitName: modelCard.unitName,
systemName: modelCard.systemName,
version: modelCard.version, version: modelCard.version,
icon: statusIcons[statusIndex], icon: statusIcons[statusIndex],
value: 1, value: 1,
@ -81,6 +83,12 @@ function normalizeCards(modelList: any[] = []): ModelItem[] {
return cardList return cardList
} }
function getSubtitle(item: ModelItem) {
const unitText = item.unitName ? `${item.unitName}` : (props.unitId != null ? `${props.unitId}号机组` : '未选择机组')
const systemText = item.systemName || (props.systemId != null ? `系统${props.systemId}` : '未选择系统')
return `${unitText} · ${systemText}`
}
async function fetchModelList(queryParams: ModelCardQueryParams, append: boolean) { async function fetchModelList(queryParams: ModelCardQueryParams, append: boolean) {
if (listLoading.value) if (listLoading.value)
return return
@ -196,37 +204,62 @@ onBeforeUnmount(() => {
:loading="loading || (listLoading && !modelCardList.length)" :loading="loading || (listLoading && !modelCardList.length)"
:hoverable="true" :hoverable="true"
class="model-card" class="model-card"
:style="{ borderLeft: `6px solid ${item.statusColor}` }"
@click="changeModel(item.id, item.version)" @click="changeModel(item.id, item.version)"
> >
<div class="card-top"> <div class="model-card__inner">
<div class="card-title" :title="item.title"> <header class="model-card__header">
{{ item.title }} <div>
<div class="model-card__title" :title="item.title">
{{ item.title }}
</div>
<div class="model-card__subtitle">
{{ getSubtitle(item) }}
</div>
</div>
<div class="model-card__header-right">
<span class="lock-icon">
<Icon :icon="item.status === '已下装' ? 'ant-design:lock-outlined' : 'ant-design:unlock-outlined'" :size="18" />
</span>
</div>
</header>
<div class="model-card__tag-row">
<span class="tag-pill tag-pill--blue">{{ item.algorithm || '未知算法' }}</span>
<span class="tag-pill tag-pill--green">{{ item.version || 'v-test' }}</span>
<span class="tag-pill">{{ item.createTime || '--' }}</span>
</div> </div>
<div class="card-tags">
<span class="status-icon" :style="{ color: item.statusColor }"> <div class="model-card__meta-row">
<Icon :icon="item.icon" :size="20" /> <div class="meta-line">
</span> <div class="meta-item">
<span class="meta-label">创建人</span>
<span>{{ item.creator || '未知' }}</span>
</div>
<div class="meta-item">
<span class="meta-label">创建时间</span>
<span>{{ item.createTime || '--' }}</span>
</div>
</div>
</div>
<div class="model-card__divider" />
<div class="model-card__bottom">
<div class="deploy-info">
<div class="deploy-info__line">
<span :class="item.status === '已下装' ? 'dot dot--success' : 'dot dot--muted'" />
<span>{{ item.status === '已下装' ? '最近已校验' : '未校验' }}</span>
</div>
</div>
<div class="model-card__actions">
<button class="btn btn--ghost" @click.stop="changeModel(item.id, item.version)">
查看详情
</button>
<button class="btn btn--primary" @click.stop="changeModel(item.id, item.version)">
进入诊断
</button>
</div>
</div> </div>
</div>
<div class="card-meta">
<span class="meta-item">
<Icon icon="ic:baseline-person" :size="16" class="meta-icon" />
{{ item.creator || '未知' }}
</span>
<span class="meta-item">
<Icon icon="ant-design:calendar-outlined" :size="16" class="meta-icon" />
{{ item.createTime || '--' }}
</span>
</div>
<div class="card-divider" />
<div class="card-footer">
<span class="algo-pill">
{{ item.algorithm || '未知' }}
</span>
<span class="tag version" :style="{ backgroundColor: item.statusColor, color: '#fff' }">
{{ item.version || 'v-test' }}
</span>
</div> </div>
</Card> </Card>
<template #overlay> <template #overlay>
@ -269,140 +302,227 @@ onBeforeUnmount(() => {
} }
.model-card { .model-card {
padding: 14px 14px 12px; position: relative;
background: linear-gradient(180deg, #fdfdfd 0%, #f7f8fa 100%); width: 100%;
border: 1px solid #d0d7de; border-radius: 20px;
border-radius: 8px; background: #ffffff;
box-shadow: 0 6px 16px rgb(15 23 42 / 8%); border: 1px solid #e5e7eb;
transition: transform 0.18s ease, box-shadow 0.18s ease; box-shadow: 0 6px 20px rgb(17 24 39 / 8%);
overflow: hidden;
display: block;
transition: transform 0.18s ease-out, box-shadow 0.18s ease-out;
} }
.model-card:hover { .model-card:hover {
box-shadow: 0 12px 32px rgb(15 23 42 / 12%);
transform: translateY(-2px); transform: translateY(-2px);
box-shadow: 0 10px 30px rgb(17 24 39 / 16%);
} }
.card-top { .icon-card {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center;
min-height: 180px;
width: 100%;
background-color: #f3f4f6;
border: 1px dashed #d1d5db;
border-radius: 12px;
transition: border-color 0.2s ease, background 0.2s ease;
}
.icon-card:hover {
background-color: #eef2ff;
border-color: #4c7af0;
}
.model-card__inner {
flex: 1;
padding: 20px 24px 18px;
}
.model-card__header {
display: flex;
justify-content: space-between; justify-content: space-between;
margin-bottom: 8px; align-items: flex-start;
gap: 12px;
} }
.card-title { .model-card__title {
padding-right: 8px;
overflow: hidden;
font-size: 18px; font-size: 18px;
font-weight: 600; font-weight: 600;
line-height: 1.4; color: #111827;
color: #1f2937; margin-bottom: 4px;
text-overflow: ellipsis;
word-break: keep-all;
white-space: nowrap;
} }
.card-tags { .model-card__subtitle {
display: inline-flex; font-size: 13px;
gap: 8px; color: #6b7280;
align-items: center;
} }
.tag.version { .model-card__header-right {
display: inline-flex; display: flex;
align-items: center; flex-direction: column;
padding: 4px 10px; align-items: flex-end;
font-size: 12px; gap: 6px;
font-weight: 600; margin-top: 6px;
line-height: 1;
text-transform: uppercase;
letter-spacing: 0.3px;
border-radius: 999px;
} }
.status-icon { .lock-icon {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 32px; width: 28px;
height: 32px; height: 28px;
background-color: rgb(0 0 0 / 6%); border-radius: 999px;
border: 1px solid rgb(0 0 0 / 8%); background: #f3f4f6;
border-radius: 8px; color: #9ca3af;
} }
.card-meta { .model-card__tag-row {
margin-top: 14px;
display: flex; display: flex;
gap: 8px; gap: 8px;
align-items: center; flex-wrap: wrap;
justify-content: space-between; }
margin-bottom: 8px;
.tag-pill {
padding: 4px 12px;
border-radius: 999px;
font-size: 12px; font-size: 12px;
border: 1px solid #e5e7eb;
background: #f9fafb;
color: #4b5563;
}
.tag-pill--blue {
background: #eef3ff;
border-color: #c7d2fe;
color: #2454e6;
}
.tag-pill--green {
background: #e8f7ef;
border-color: #b7e4c7;
color: #13804c;
}
.model-card__meta-row {
margin-top: 10px;
font-size: 13px;
color: #6b7280; color: #6b7280;
display: flex;
flex-direction: column;
gap: 6px;
} }
.meta-item { .meta-item {
display: inline-flex; display: flex;
gap: 6px; align-items: center;
gap: 4px;
}
.meta-line {
display: flex;
align-items: center; align-items: center;
min-width: 0; justify-content: space-between;
gap: 16px;
} }
.meta-icon { .meta-label {
color: #9ca3af; color: #9ca3af;
margin-right: 6px;
} }
.card-footer { .model-card__divider {
height: 1px;
margin: 12px 0 12px;
background: linear-gradient(to right, transparent, #e5e7eb 20%, #e5e7eb 80%, transparent);
}
.model-card__bottom {
display: flex; display: flex;
justify-content: space-between;
align-items: center;
gap: 12px; gap: 12px;
}
.deploy-info {
font-size: 13px;
color: #4b5563;
}
.deploy-info__line {
display: flex;
align-items: center; align-items: center;
justify-content: space-between; gap: 6px;
padding-top: 6px; }
.model-card__actions {
display: flex;
gap: 8px;
flex-shrink: 0;
}
.btn {
padding: 6px 16px;
border-radius: 999px;
font-size: 13px; font-size: 13px;
border: 1px solid transparent;
cursor: pointer;
white-space: nowrap;
transition: all 0.15s ease-out;
}
.btn--ghost {
background: #ffffff;
border-color: #e5e7eb;
color: #4b5563; color: #4b5563;
box-shadow: 0 2px 6px rgb(15 23 42 / 6%);
} }
.card-divider { .btn--ghost:hover {
height: 1px; background: #f3f4f6;
margin: 4px 0 8px;
border-top: 1px dashed #e5e7eb;
} }
.footer-text.strong { .btn--primary {
font-weight: 600; background: #2463f4;
border-color: #2463f4;
color: #ffffff;
box-shadow: 0 6px 14px rgb(37 99 235 / 30%);
} }
.footer-divider { .btn--primary:hover {
flex: 1; background: #1d4fd8;
height: 1px; border-color: #1d4fd8;
border-top: 1px dashed #e5e7eb;
} }
.algo-pill { .dot {
display: inline-flex; width: 8px;
align-items: center; height: 8px;
padding: 4px 10px; border-radius: 999px;
font-weight: 700;
color: #1d4ed8;
letter-spacing: 0.3px;
background: #e0e7ff;
border: 1px solid #c7d2fe;
border-radius: 10px;
} }
.icon-card { .dot--success {
display: flex; background: #22c55e;
align-items: center;
justify-content: center;
min-height: 180px;
background-color: #f3f4f6;
border: 1px dashed #d1d5db;
border-radius: 12px;
transition: border-color 0.2s ease, background 0.2s ease;
} }
.icon-card:hover { .dot--muted {
background-color: #eef2ff; background: #d1d5db;
border-color: #4c7af0; }
@media (max-width: 640px) {
.model-card {
width: 100%;
}
.model-card__bottom {
flex-direction: column;
align-items: flex-start;
}
.model-card__actions {
align-self: flex-end;
}
} }
.load-status { .load-status {
@ -419,4 +539,9 @@ onBeforeUnmount(() => {
.load-more-trigger { .load-more-trigger {
height: 1px; height: 1px;
} }
:deep(.ant-card-body) {
padding: 0;
width: 100%;
}
</style> </style>

2
src/views/model/list/data.tsx

@ -4,6 +4,8 @@ export interface ModelItem {
id: number id: number
icon: string icon: string
title: string title: string
unitName?: string
systemName?: string
value: number value: number
total: number total: number
color: string color: string

Loading…
Cancel
Save