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. 331
      src/views/model/list/ModelCard.vue
  2. 2
      src/views/model/list/data.tsx

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

@ -62,6 +62,8 @@ function normalizeCards(modelList: any[] = []): ModelItem[] {
const card: ModelItem = {
id: modelCard.id,
title: modelCard.name,
unitName: modelCard.unitName,
systemName: modelCard.systemName,
version: modelCard.version,
icon: statusIcons[statusIndex],
value: 1,
@ -81,6 +83,12 @@ function normalizeCards(modelList: any[] = []): ModelItem[] {
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) {
if (listLoading.value)
return
@ -196,37 +204,62 @@ onBeforeUnmount(() => {
:loading="loading || (listLoading && !modelCardList.length)"
:hoverable="true"
class="model-card"
:style="{ borderLeft: `6px solid ${item.statusColor}` }"
@click="changeModel(item.id, item.version)"
>
<div class="card-top">
<div class="card-title" :title="item.title">
<div class="model-card__inner">
<header class="model-card__header">
<div>
<div class="model-card__title" :title="item.title">
{{ item.title }}
</div>
<div class="card-tags">
<span class="status-icon" :style="{ color: item.statusColor }">
<Icon :icon="item.icon" :size="20" />
</span>
<div class="model-card__subtitle">
{{ getSubtitle(item) }}
</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 || '--' }}
<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>
<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>
</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 class="model-card__meta-row">
<div class="meta-line">
<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>
</Card>
<template #overlay>
@ -269,140 +302,227 @@ onBeforeUnmount(() => {
}
.model-card {
padding: 14px 14px 12px;
background: linear-gradient(180deg, #fdfdfd 0%, #f7f8fa 100%);
border: 1px solid #d0d7de;
border-radius: 8px;
box-shadow: 0 6px 16px rgb(15 23 42 / 8%);
transition: transform 0.18s ease, box-shadow 0.18s ease;
position: relative;
width: 100%;
border-radius: 20px;
background: #ffffff;
border: 1px solid #e5e7eb;
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 {
box-shadow: 0 12px 32px rgb(15 23 42 / 12%);
transform: translateY(-2px);
box-shadow: 0 10px 30px rgb(17 24 39 / 16%);
}
.card-top {
.icon-card {
display: flex;
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;
margin-bottom: 8px;
align-items: flex-start;
gap: 12px;
}
.card-title {
padding-right: 8px;
overflow: hidden;
.model-card__title {
font-size: 18px;
font-weight: 600;
line-height: 1.4;
color: #1f2937;
text-overflow: ellipsis;
word-break: keep-all;
white-space: nowrap;
color: #111827;
margin-bottom: 4px;
}
.card-tags {
display: inline-flex;
gap: 8px;
align-items: center;
.model-card__subtitle {
font-size: 13px;
color: #6b7280;
}
.tag.version {
display: inline-flex;
align-items: center;
padding: 4px 10px;
font-size: 12px;
font-weight: 600;
line-height: 1;
text-transform: uppercase;
letter-spacing: 0.3px;
border-radius: 999px;
.model-card__header-right {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 6px;
margin-top: 6px;
}
.status-icon {
.lock-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
background-color: rgb(0 0 0 / 6%);
border: 1px solid rgb(0 0 0 / 8%);
border-radius: 8px;
width: 28px;
height: 28px;
border-radius: 999px;
background: #f3f4f6;
color: #9ca3af;
}
.card-meta {
.model-card__tag-row {
margin-top: 14px;
display: flex;
gap: 8px;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
flex-wrap: wrap;
}
.tag-pill {
padding: 4px 12px;
border-radius: 999px;
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;
display: flex;
flex-direction: column;
gap: 6px;
}
.meta-item {
display: inline-flex;
gap: 6px;
display: flex;
align-items: center;
min-width: 0;
gap: 4px;
}
.meta-icon {
.meta-line {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
}
.meta-label {
color: #9ca3af;
margin-right: 6px;
}
.model-card__divider {
height: 1px;
margin: 12px 0 12px;
background: linear-gradient(to right, transparent, #e5e7eb 20%, #e5e7eb 80%, transparent);
}
.card-footer {
.model-card__bottom {
display: flex;
justify-content: space-between;
align-items: center;
gap: 12px;
}
.deploy-info {
font-size: 13px;
color: #4b5563;
}
.deploy-info__line {
display: flex;
align-items: center;
justify-content: space-between;
padding-top: 6px;
gap: 6px;
}
.model-card__actions {
display: flex;
gap: 8px;
flex-shrink: 0;
}
.btn {
padding: 6px 16px;
border-radius: 999px;
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;
box-shadow: 0 2px 6px rgb(15 23 42 / 6%);
}
.card-divider {
height: 1px;
margin: 4px 0 8px;
border-top: 1px dashed #e5e7eb;
.btn--ghost:hover {
background: #f3f4f6;
}
.footer-text.strong {
font-weight: 600;
.btn--primary {
background: #2463f4;
border-color: #2463f4;
color: #ffffff;
box-shadow: 0 6px 14px rgb(37 99 235 / 30%);
}
.footer-divider {
flex: 1;
height: 1px;
border-top: 1px dashed #e5e7eb;
.btn--primary:hover {
background: #1d4fd8;
border-color: #1d4fd8;
}
.algo-pill {
display: inline-flex;
align-items: center;
padding: 4px 10px;
font-weight: 700;
color: #1d4ed8;
letter-spacing: 0.3px;
background: #e0e7ff;
border: 1px solid #c7d2fe;
border-radius: 10px;
.dot {
width: 8px;
height: 8px;
border-radius: 999px;
}
.icon-card {
display: flex;
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;
.dot--success {
background: #22c55e;
}
.icon-card:hover {
background-color: #eef2ff;
border-color: #4c7af0;
.dot--muted {
background: #d1d5db;
}
@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 {
@ -419,4 +539,9 @@ onBeforeUnmount(() => {
.load-more-trigger {
height: 1px;
}
:deep(.ant-card-body) {
padding: 0;
width: 100%;
}
</style>

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

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

Loading…
Cancel
Save