搜索结果列表页面开发

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,51 @@
# InfoCard
### 说明
- 适用于组织、个人的信息卡片
- 卡片地步的信息会自适应展示User和Repo信息
``` js
import InfoCard from '@/components/InfoCard/index.vue';
const info = ref({
name: mock('@first'),
namespace: mock('@first'),
description: mock('@paragraph'),
maxLines: 2,
avatar: '/src/assets/imgs/avatar/male.png',
isRound: mock('@boolean'),
avatarSize: 80,
tenant: 'CSDN',
location: mock('@city'),
});
<InfoCard v-bind="info">
<d-button variant="solid">点击关注</d-button>
</InfoCard>
```
### Props
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|-----------|------------------------|----------------------------|----------|-----------|
| name | title部分 | string | - | - |
| namespace | @后面的namespace | string | - | - |
| description | 描述 | string | - | - |
| maxLines? | 描述的最大行数 | number | - | 3 |
| avatar | 图片url | string | - | - |
| avatarSize? | 左侧头像尺寸 | number | - | 80 |
| isRound? | 头像是否为圆形同d-avatar| boolean | - | true |
| hideFooter? | 是否展示footer | boolean | - | false |
| tenant? | 用户信息卡片的公司名称 | string | - | - |
| location? | 地址信息 | string | - | - |
| projectCount? | 组织卡片的项目个数 | number | - | - |
| memberCount? | 成员个数 | number | - | - |
### Slots
| 名称 | 说明 |
|---------------------|---------------------------------------------|
| default | 定制右侧的交互 |
| footer | 底部信息插槽。需要确保hideFooter未设置为true |

View File

@@ -0,0 +1,127 @@
<template>
<div class="g-info-card" :class="{ 'g-info-card-no-footer': hideFooter }">
<div class="g-info-card-main">
<div class="g-info-card-avatar">
<GAvatar :src="avatar" :name="name" :width="avatarSize" :height="avatarSize" :is_round="isRound"></GAvatar>
</div>
<div class="g-info-card-body">
<div class="g-info-card-body-name">
<GLink :to="userLink" v-if="isOrganization">{{ name }}</GLink>
<template v-else>
<GLink :to="userLink">{{ name }}</GLink>@{{ namespace }}
</template>
</div>
<div class="g-info-card-body-description" :style="{ lineClamp: maxLines }">
{{ description }}
</div>
<div class="g-info-card-body-bottom" v-if="!hideFooter">
<slot name="footer">
<span v-if="tenant">
<i class="icon icon-base-info" /> {{ tenant }}
</span>
<span v-if="location">
<i class="icon icon-domain" /> {{ location }}
</span>
<span v-if="projectCount">
{{ projectCount }} 项目
</span>
<span v-if="memberCount">
{{ memberCount }} 成员
</span>
</slot>
</div>
</div>
</div>
<slot></slot>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue';
interface IProps {
name: string,
namespace?: string,
description: string,
maxLines?: number, // 描述最大行数
avatar: string,
isRound?: boolean,
avatarSize?: number,
tenant?: string,
location?: string,
projectCount?: number,
memberCount?: number,
hideFooter?: boolean,
isOrganization?: boolean
}
const props = withDefaults(defineProps<IProps>(), {
isRound: true,
maxLines: 3,
avatarSize: 80,
hideFooter: false
});
const userLink = computed(() => ({
name: 'homepage',
params: {
namespace: props.namespace
}
}));
</script>
<style lang="scss" scoped>
.g-info-card {
display: flex;
align-items: center;
padding: 16px;
gap: 16px;
border-radius: var(--border-radius, 4px);
border: 1px solid var(--border-gray, #D3D3D3);
&-main {
display: flex;
align-items: flex-start;
gap: 16px;
}
&-avatar {
line-height: 0;
}
&-body {
flex: 1;
&-name {
span {
font-weight: 500;
font-size: 18px;
color: var(--black, #000);
}
}
&-description {
display: -webkit-box;
-webkit-box-orient: vertical;
line-height: normal;
overflow: hidden;
margin: 16px 0;
color: var(--button-gray, #808080);
}
&-bottom {
color: var(--black-60, #606060);
span {
i {
margin-right: 4px;
}
& + span {
margin-left: 16px;
}
}
}
}
&-no-footer {
.g-info-card-body-description {
margin-bottom: 0;
}
}
}
</style>