搜索结果列表页面开发

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,102 @@
<template>
<d-tooltip :position="['top']" class="g-commit-item-header-info-tooltip">
<!-- 如果没有开启GPG验证和没有使用GPG验证的数据不出 实际上也不会存在开启了没有使用的数据但是需要符合测试 -->
<div v-if="(open_gpg_verified && (isPass !== ''))" class="flex g-commit-item-text">
<d-tag color="#10A35C" v-if="isPass">已验证</d-tag>
<d-tag color="#9C9DB4" v-if="!isPass">未验证</d-tag>
</div>
<template #content>
<div class="verified-tooltip-box">
<div class="verified-tooltip-box-top">
<div><span class="verified-tooltip-box-top-left">{{ statusObj[verification_status] }}</span>
<Icon name="gt-plane-ok-green1" size="14px" v-if="isPass" />
<Icon name="gt-plane-Fail" size="14px" v-if="!isPass" />
</div>
</div>
<div class="verified-tooltip-box-bottom">
GPG Key lD: {{ gpg_primary_key_id }}
</div>
<div class="verified-tooltip-box-bottom-a">
如何<a class="devui-link-light" target="_blank" href="https://docs.gitcode.com/docs/users/gpg">生成 GPG
公钥并将其添加到您的帐户</a>
</div>
</div>
</template>
</d-tooltip>
</template>
<script setup lang="ts" name="gpgTag">
import { computed, ref } from 'vue';
export interface GPGtest {
open_gpg_verified: boolean; // 是否需要验证
gpg_primary_key_id: string; // 密钥id
verification_status: number; // 验证状态
name: string; // 名称
}
const props = withDefaults(defineProps<GPGtest>(), {
open_gpg_verified: false,
gpg_primary_key_id: '', // 密钥id
verification_status: 5,
name: ''
});
// 枚举对象
const statusObj = ref<any>({
0: '提交内容与签名不符本次提交没有通过GPG签名校验',
1: props.name !== 'gitcode.com' ? '由提交者的已验证签名签署本次提交' : '此提交是在gitcode.com上创建并使用Gitcode 的已验证签名进行签名',
4: '签名证书邮箱与GitCode内已绑定的邮箱不一致本次提交没有通过GPG签名校验。',
5: '签名证书未在GitCode平台注册本次提交没有通过GPG签名校验。',
6: '签名证书邮箱与GitCode提交邮箱不一致本次提交没有通过GPG签名校验。'
})
// isPass true是现在已验证 false是未验证 空串是不出现
const isPass = computed(() => {
if (props?.verification_status === 6 || props?.verification_status === 0 || props?.verification_status === 4 || props?.verification_status === 5) {
return false;
}
if (props?.verification_status === 1) {
return true;
}
// 本身没值或者null 不展示
return ''
})
</script>
<style lang="scss" scoped>
.verified-tooltip-box {
padding: 16px;
max-width: 320px;
display: flex;
flex-direction: column;
.verified-tooltip-box-top {
display: flex;
align-items: center;
flex-wrap: wrap;
line-height: 1;
font-size: 14px;
color: var(--devui-light-text, #ffffff);
line-height: 22px;
.verified-tooltip-box-top-left {
padding-right: 8px;
}
margin-bottom: 8px;
}
.verified-tooltip-box-bottom {
margin-bottom: 8px;
}
.verified-tooltip-box-bottom,
.verified-tooltip-box-bottom-a {
line-height: 1;
font-size: 14px;
line-height: 22px;
color: var(--devui-placeholder, #9C9DB4);
a {
color: #96adfa;
}
}
}
</style>

View File

@@ -0,0 +1,22 @@
# CommitItem
### 说明
- Commit信息卡片用于分支详情页-commit记录等
``` js
import CommitItem from '@/components/CommitItem/index.vue';
<CommitItem id="xxx" message="xxx" .... />
```
### Props
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|-----------|------------------------|----------------------------|----------|-----------|
| id | commit id | string | - | - |
| message | commit描述信息 | string | - | - |
| repoId | commit对应的仓库id | string | - | - |
| namespace | commit对应的用户命名空间 | string | - | - |
| statusText | commit状态描述 | string | - | - |
| createTime | 创建时间 | string | - | - |
| userAvatar | 用户头像src | string | - | - |
| username | 用户名称 | string | - | - |

View File

@@ -0,0 +1,234 @@
<template>
<div class="g-commit-item">
<div class="g-commit-item-header">
<div class="g-commit-item-width">
<GLink @click.stop class="g-commit-item-header-message flex-shrink-0" :to="commitLink">{{ title }}</GLink>
<GIcon
v-if="messageText && messageText !== title"
name="gt-line-down"
class="g-commit-item-header-down flex-auto hover:bg-CG200"
:class="{ 'arrow-down': !showDesc, 'arrow-up': showDesc }"
@click.stop="showMore"
/>
</div>
<div class="g-commit-item-header-info">
<GpgTag v-if="verification_status" :open_gpg_verified="open_gpg_verified" :gpg_primary_key_id="gpg_primary_key_id" :verification_status="verification_status" :name="name"></GpgTag>
<d-tooltip :content="id">
{{ shortHashId }}
</d-tooltip>
<Copy
v-if="shortHashId"
:showText="false"
tooltip="复制CommitID"
class="g-commit-item-header-info-copy"
:content="id"
always
></Copy>
<d-tooltip content="查看源码">
<GLink :to="codeLink" target="_blank">
<Icon name="gt-code2" color="#707A87" class="custom-icon-container"/>
</GLink>
</d-tooltip>
</div>
</div>
<Transition name="g-commit-item-panel">
<div v-if="showDesc" v-html="messageText" class="text-CG600 whitespace-pre-line overflow-auto g-commit-item-description"></div>
</Transition>
<div class="g-commit-item-footer">
<UserLink
class="text-xs mr-2"
:userImg="userAvatar"
:imgSize="16"
:userName="username"
:goTo="userRouter"
:disabled="!author_user_name"
></UserLink>
<span class="text-CG600 text-xs">提交于 <Time :time="createTime" /> </span>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue';
import type { Commit } from './type';
import { useRoute, useRouter } from 'vue-router';
import { xssPurify } from '@/utils';
import { useOrgId } from '@/utils/hooks/useOrgId';
import UserLink from '@/components/UserLInk/UserLink.vue';
import GpgTag from '@/components/CommitItem/GpgTag.vue';
const { orgId } = useOrgId('/');
const props = defineProps<Commit>();
const messageText = computed(() => xssPurify(props.message?.trim() || ''));
const route = useRoute();
const router = useRouter();
const codeLink = computed(() =>
router
.resolve({
name: 'repoDir',
params: {
...route.params,
branchName: props.id,
namespace: orgId.value
}
})
.href.replace(/%2F/g, '/')
);
const commitLink = computed(() =>
router
.resolve({
name: 'repoCommitDetail',
params: {
commitId: props.id,
repoName: props.repoId,
namespace: orgId.value || props.namespace
},
query: {
ref: props.branch
}
})
.href.replace(/%2F/g, '/')
);
const shortHashId = computed(() => props.id?.slice(0, 8));
const userRouter = computed(() => ({
name: 'homepage',
params: {
namespace: props.author_user_name
}
}));
const showDesc = ref(false);
const showMore = () => {
showDesc.value = !showDesc.value;
};
// const isCheckUser = ref(true);
// const checkUser = async () => {
// const res = await checkUsername(props.username || '');
// if (!res.error) {
// if (res.data.data.result === false) {
// isCheckUser.value = false;
// }
// } else {
// isCheckUser.value = false;
// }
// };
</script>
<style lang="scss" scoped>
.g-commit-item {
position: relative;
padding: 12px 20px 12px 56px;
border-top: 1px solid var(--color-border-light);
&-text {
color: var(--color-CG500);
:deep(.icon) {
align-self: center;
margin-right: 4px;
opacity: 0.2;
}
}
&-width {
display: flex;
align-items: center;
max-width: 50%;
}
&-header {
display: flex;
overflow: hidden;
&-message {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-all;
flex: auto;
font-weight: 500;
line-height: 20px;
font-size: 14px;
}
&-down {
margin-left: 10px;
width: 20px;
height: 16px;
border-radius: 3px;
text-align: center;
flex-shrink: 0;
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
:deep(i) {
width: auto;
}
}
&-info {
display: flex;
gap: 20px;
align-items: center;
position: absolute;
top: 20px;
right: 20px;
color: var(--color-light);
&-copy {
display: flex;
cursor: pointer;
:deep(.g-copy-trigger-border) {
margin-left: 0;
border: unset;
}
}
i.icon {
cursor: pointer;
color: var(--color-CG500);
}
}
}
&-panel-leave-active{
transition: all 0.3s ease-in-out;
animation: panelUpOut 0.3s ease-in-out;
animation-fill-mode: both;
}
&-panel-enter-active{
transition: all 0.3s ease-in-out;
animation: panelUpIn 0.3s ease-in-out;
animation-fill-mode: both;
}
&-description {
margin-top: 4px;
width: 80%;
}
&-footer {
display: flex;
align-items: center;
line-height: 20px;
margin-top: 4px;
&-author {
font-weight: 500;
color: var(--color-CG600) !important;
margin-right: 12px;
&[disabled='true'] {
color: var(--color-CG600) !important;
}
}
}
.hover-style {
&:hover {
opacity: 0.7;
}
}
}
</style>

View File

@@ -0,0 +1,18 @@
export interface Commit {
id: string;
message?: string;
repoId?: string;
namespace: string;
statusText?: string;
createTime: string;
userAvatar?: string;
username?: string;
author_user_name: string;
title?: string;
open_gpg_verified: boolean; // 是否需要验证
gpg_primary_key_id: string; // 密钥id
verification_status: number; // 验证状态
branch?: string;
[propName: string]: any;
name: string; // 名称
}