搜索结果列表页面开发

This commit is contained in:
付民康
2025-03-12 18:41:20 +08:00
commit 7cebe8fc00
739 changed files with 88149 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
TS接口文档可以查看同文件夹下的types.ts
### Props
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|-------------|-------------------------------|-----------|-----------|--------------|
| ssh | SSH数据 | SSHData | — | — |
| gpg | GPG数据 | GPGData | — | - |
| visit | 访问数据 | VisitData | — | - |
| isLast | 是否为最后一个item如果是会把底部的border补齐 | boolean | — | false |
| icon? | 左边key对应图标 | string | — | 'locked-key' |
| deleteIcon? | 删除按钮对应图标 | string | — | 'delete' |
| size? | 左边key图标尺寸 | string | — | '32px' |
| deleteSize? | 删除按钮图标尺寸 | string | — | '24px' |
### Emits
注意:以下事件都是组件内部对应的按钮点击触发,如果用插槽自定义对应区域的内容的话,事件自行监听即可
| 方法 | 说明 | 返回值 |
|--------|--------|-----------------------|
| delete | item删除 | SSHData | GPGData | VisitData |
### Slots
| 名称 | 说明 |
|----------|------------------------------|
| icon | key图标对应位置 |
| type | 左边SSH和GPG密钥类型对应位置 |
| email | 邮箱对应位置 |
| name | 访问令牌时名称对应位置 |
| auth | 访问令牌时权限对应位置 |
| key | 密钥对应位置 |
| messages | 中间内容区域倒数第二行内容插槽对应GPG的子公钥区域 |
| info | 中间内容区域最后一行内容插槽 |
| actions | 操作区域插槽 |

View File

@@ -0,0 +1,222 @@
<template>
<div class="g-secret-key-item px-5 py-4 border border-G200 rounded-sm" :class="{ 'is-last': isLast }">
<div v-if="!visit" class="g-secret-key-item-type">
<div class="g-secret-key-item-icon">
<slot name="icon">
<d-icon :name="icon" :size="size"></d-icon>
</slot>
</div>
<!-- <div class="g-secret-key-item-key-type">
<span class="g-secret-key-item-tag">
<slot name="type">{{ ssh ? 'SSH' : 'GPG' }}</slot>
</span>
</div> -->
</div>
<div class="g-secret-key-item-content">
<template v-if="ssh">
<div class="g-secret-key-item-email">
<slot name="email" :data="{ ssh }">{{ ssh.email }}</slot>
</div>
<div class="g-secret-key-item-key">
<slot name="key" :data="{ ssh }">{{ ssh.key }}</slot>
</div>
<div class="g-secret-key-item-messages">
<slot name="messages" :data="{ ssh }">
<span>创建于{{ formatTimeFromNow(ssh.createdTime) }}</span>
<span class="g-secret-key-item-split"></span>
<span v-if="ssh.expireTime">将于{{ formatTime(ssh.expireTime, 'YYYY/MM/DD') }}过期</span>
<span v-else>永不过期</span>
<span class="g-secret-key-item-split"></span>
<span>{{ ssh.last_used_at ? `${formatTimeFromNow(ssh.last_used_at)}被使用` : '从未被使用' }}</span>
<span>{{ ssh.authority }}</span>
</slot>
</div>
<!-- <div class="g-secret-key-item-info">
<slot name="info" :data="{ ssh }">
<span>{{ ssh.hasBeenUsed ? '已被使用' : '从未被使用' }}</span>
<span class="g-secret-key-item-split">·</span>
<span>{{ ssh.authority }}</span>
</slot>
</div> -->
</template>
<template v-if="gpg">
<div class="g-secret-key-item-email">
<slot name="email" :data="{ gpg }">
<span>{{ gpg.email }}</span>
</slot>
<slot name="status" :data="{ gpg }">
<div class="g-secret-key-item-status">
<custom-tag v-if="gpg.validated" color="#0C974F" border-color="#0C974F">已验证</custom-tag>
<custom-tag v-else color="#606060" border-color="#D3D3D3">未验证</custom-tag>
</div>
</slot>
</div>
<div class="g-secret-key-item-key">
<slot name="key" :data="{ gpg }">{{ gpg.key }}</slot>
</div>
<div class="g-secret-key-item-messages">
<slot name="message" :data="{ gpg }">
<span>子公钥{{ gpg.childKey }}</span>
</slot>
</div>
<div class="g-secret-key-item-info">
<slot name="info" :data="{ gpg }">
<span>创建于{{ formatTimeFromNow(gpg.createdTime) }}</span>
</slot>
</div>
</template>
<template v-if="visit">
<div class="g-secret-key-item-email">
<slot name="name" :data="{ visit }">{{ visit.name }}</slot>
</div>
<div class="g-secret-key-item-key">
<slot name="auth" :data="{ visit }">{{ visit.authority }}</slot>
</div>
<div class="g-secret-key-item-messages">
<slot name="messages" :data="{ visit }">
<span>创建于{{ formatTimeFromNow(visit.createdTime) }}</span>
<span class="g-secret-key-item-split">·</span>
<span v-if="visit.expireTime">将于{{ formatTimeFromNow(visit.expireTime) }}过期</span>
<span v-else>永不过期</span>
<span v-if="visit.lastUsedTime">{{ formatTimeFromNow(visit.lastUsedTime) }}使用过</span>
<span v-else>从未被使用</span>
</slot>
</div>
<!-- <div class="g-secret-key-item-info">
<slot name="info" :data="{ visit }">
<span v-if="visit.lastUsedTime">{{ formatTimeFromNow(visit.lastUsedTime) }}使用过</span>
<span v-else>从未被使用</span>
</slot>
</div> -->
</template>
</div>
<div class="g-secret-key-item-actions">
<slot name="actions" :data="{ gpg }">
<!-- <div class="g-secret-key-item-delete" @click="emits('delete', visit || ssh || gpg)">
<d-icon :name="deleteIcon" :size="deleteSize"></d-icon>
</div> -->
<MoreList :moreOpts="moreOpts" :item="item"></MoreList>
</slot>
</div>
</div>
</template>
<script lang="ts">
export default {
name: 'secret-key-item'
};
</script>
<script setup lang="ts">
import type { SSHData, GPGData, VisitData } from '@/components/SecretKeyItem/types';
import { useTimeFormat } from '@/utils/hooks/useTimeFormat';
import CustomTag from '@/components/CustomTag/index.vue';
import MoreList from '@/components/MoreList/index.vue';
withDefaults(
defineProps<{
icon?: string;
size?: string;
deleteIcon?: string;
deleteSize?: string;
ssh?: SSHData;
gpg?: GPGData;
visit?: VisitData;
isLast?: boolean;
moreOpts?: any;
item?: any;
}>(),
{
icon: 'locked-key',
size: '32px',
deleteIcon: 'delete',
deleteSize: '24px',
isLast: false,
moreOpts: () => [],
item: () => ({})
}
);
const emits = defineEmits<{ (e: 'delete', data: SSHData | GPGData | VisitData): void }>();
const { formatTimeFromNow, formatTime } = useTimeFormat();
</script>
<style scoped lang="scss">
$g-secret-key-item-border-color: #d3d3d3;
$g-secret-key-item-border-radius: 3px;
$g-secret-key-item-color: #606060;
$g-secret-key-item-color-second: var(--color-CG600);
.g-secret-key-item {
display: flex;
margin-bottom: 12px;
&.is-last {
border-bottom: 1px solid var(--color-G200);
}
&-type {
margin-right: 24px;
display: flex;
align-items: center;
}
&-key-type {
margin-top: 8px;
}
&-tag {
display: inline-block;
padding: 2px 4px;
border: 1px solid $g-secret-key-item-border-color;
border-radius: $g-secret-key-item-border-radius;
margin-left: -2px;
font-size: 12px;
font-weight: 400;
color: $g-secret-key-item-color;
}
&-content {
flex: 1;
}
&-email {
font-size: 14px;
font-weight: 500;
color: var(--color-G900);
margin-top: -4px;
margin-bottom: 4px;
display: flex;
align-items: center;
}
&-key {
font-size: 14px;
color: $g-secret-key-item-color-second;
margin-bottom: 6px;
}
&-messages {
font-size: 12px;
display: flex;
align-items: center;
color: $g-secret-key-item-color-second;
}
&-info {
font-size: 12px;
display: flex;
align-items: center;
color: $g-secret-key-item-color-second;
}
&-split {
margin: 0 8px;
font-weight: bolder;
width: 1px;
height: 12px;
background-color: var(--color-G400);
}
&-actions {
align-self: center;
}
&-status {
margin-left: 8px;
}
&-delete {
&:hover {
cursor: pointer;
opacity: 0.9;
}
}
}
</style>

View File

@@ -0,0 +1,24 @@
export interface SSHData{
title: string;
key: string;
createdTime: string;
expireTime?: string;
hasBeenUsed?: boolean;
authority?: string;
id?: string | number;
[propName: string]: any;
}
export interface GPGData extends SSHData{
childKey: string;
validated: boolean;
}
export type VisitData = {
name: string;
authority: string;
createdTime: string;
expireTime: string;
lastUsedTime: string;
[propName: string]: any;
}