搜索结果列表页面开发

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,93 @@
<template>
<div class="status-btn flex items-center cursor-pointer px-3.5" @click.stop.prevent="toggleStar(showActiveStatus)">
<Star :active="showActiveStatus" :run-animation="showAnim" @animEnd="animCb" class="mr-2"></Star>
<span v-if="showText" class="font-normal font-color-t1 mr-2">{{
showActiveStatus ? 'Starred' : 'Star'
}}</span>
<span v-if="hasNumber" class="hover:text-link status-btn-number" @click.stop="handleStarList">
<Number :number="number" />
</span>
</div>
</template>
<script setup lang="ts">
import Star from '@/components/Star/index.vue';
import type { IStarBtn } from '@/components/StarBtn/types';
import { computed, onMounted, ref, watch } from 'vue';
import { useAccountStore } from '@/stores/user';
import { emitEvent } from '@/utils/eventBus';
import { useRepoId } from '@/utils/hooks/useRepoId';
const { isLogin } = useAccountStore();
const CHANGE_EVENT = 'starChange';
const props = withDefaults(defineProps<IStarBtn>(), {
showText: true
});
const emits = defineEmits<{ (event: typeof CHANGE_EVENT, value: boolean, count: number): void }>();
const showAnim = ref(false);
const showActiveStatus = ref(false);
const hasNumber = computed(() => props.number !== undefined && !Number.isNaN(props.number));
onMounted(() => {
showActiveStatus.value = props.active;
});
watch(() => props.active, (newValue) => {
if (showAnim.value) {
return;
}
showActiveStatus.value = newValue;
});
const btnLoading = ref(false);
let resolve:(value: void) => void;
let animEnd: Promise<void>;
async function toggleStar(curActive: boolean) {
if (!isLogin) {
emitEvent('login', { triggerType: 'Star' });
return;
}
if (showAnim.value || btnLoading.value) {
return;
}
btnLoading.value = true;
let result;
animEnd = new Promise((res) => {
resolve = res;
});
if (curActive) {
result = await props.interface.unStar().finally(() => btnLoading.value = false);
} else {
showAnim.value = !curActive;
result = await props.interface.star().finally(() => btnLoading.value = false);
await animEnd;
}
showActiveStatus.value = !curActive;
btnLoading.value = false;
emits(CHANGE_EVENT, !curActive, result?.star_count);
}
const handleStarList = () => {
const repoPath = useRepoId("/");
const routePath = `/${repoPath.repoId.value}/star`;
window.open(routePath, "_self");
};
function animCb() {
showAnim.value = false;
resolve();
}
</script>
<style scoped lang="scss">
.status-btn {
height: 32px;
border-radius: 4px;
border: 1px solid var(--devui-btn-common-border-color);
background: var(--devui-btn-common-bg);
&:hover {
background: linear-gradient(0deg, rgba(188, 188, 208, 0.10) 0%, rgba(188, 188, 208, 0.10) 100%), var(--White, #FFF);
}
&-number {
padding: 0 4px;
color: var(--devui-aide-text);
}
}
</style>

View File

@@ -0,0 +1,13 @@
import type { IStarOriginSource } from '@/components/StarBtn/types';
import { starRepo, unstarRepo } from '@/api/repo';
export function starInterface(repoId: string): IStarOriginSource {
return {
async unStar() {
return unstarRepo({ repoId }).then(res => res.data);
},
async star() {
return starRepo({ repoId }).then(res => res.data);
}
}
}

View File

@@ -0,0 +1,12 @@
export interface IStarOriginSource{
unStar: () => Promise<{star_count: number}>;
star: () => Promise<{star_count: number}>;
}
export interface IStarBtn {
active: boolean;
interface: IStarOriginSource;
showText: boolean;
number?: number;
}