搜索结果列表页面开发

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,31 @@
TS接口文档可以查看同文件夹下的types.ts
### Props
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|----------------|-------------------------|-------------------------------|-----------|-------|
| data | 邀请列表数据 | Array<InvitationItemData> | — | [] |
| statusOptions? | 用户身份下拉数据项 | {label: string; value: string | number}[] | — | [] |
| isHandling? | 是否处于事务处理中设为true会禁用右边操作 | boolean | — | false |
### Emits
注意:以下事件都是组件内部对应的按钮点击触发,如果用插槽自定义对应区域的内容的话,事件自行监听即可
| 方法 | 说明 | 返回值 |
|-----------|--------|-----------------------|
| statusChange | 人员身份变化 | { data: InvitationItemData; index: number } |
| edit | 编辑 | { data: InvitationItemData; index: number } |
| delete | 删除 | { data: InvitationItemData; index: number } |
### Slots
| 名称 | 说明 |
|--------------|----------------------|
| header | 组件标题、tag和复制功能按钮所在的区域 |
| title | 组件标题区域插槽 |
| tags | 组件标签区域插槽 |
| info-action | 组件复制功能区域插槽 |
| bottom | 组件左下角区域插槽 |
| status | 组件成员身份选择区域插槽 |
| actions | 组件右边动作区域插槽 |

View File

@@ -0,0 +1,184 @@
<template>
<section class="g-invitation-list">
<div
v-for="(item, index) in data"
:key="`${item.id}_${index}`"
class="g-invitation-list-item">
<div class="g-invitation-list-item-messages">
<div class="g-invitation-list-item-header">
<slot name="header" :data="item" :index="index">
<slot name="title" :data="item" :index="index">
<h3 class="g-invitation-list-item-title">{{ item.title }}</h3>
</slot>
<slot v-if="item.needReview" name="tags" :data="item" :index="index">
<custom-tag class="g-invitation-list-item-tag" border-color="#D3D3D3">需要审核</custom-tag>
</slot>
<slot name="info-action" :data="item" :index="index">
<copy :show-text="false">{{ item.link }}</copy>
</slot>
</slot>
</div>
<div class="g-invitation-list-item-bottom">
<slot name="bottom" :data="item" :index="index">
<div class="g-invitation-list-item-effect-range">
<span>有效期</span> <span>{{ item.beginDate }}</span> <span>-</span> <span>{{ item.endDate }}</span>
</div>
</slot>
</div>
</div>
<div class="g-invitation-list-item-actions">
<slot name="status" :data="item" :index="index">
<div class="g-invitation-list-item-status">
<d-editable-select
class="g-invitation-list-item-status-select"
v-model="item.status"
:options="statusOptions"
:width="70"
:disabled="isHandling"
size="sm"
placeholder="身份"
@change="emits('statusChange', { data: item, index })"
>
</d-editable-select>
</div>
</slot>
<slot name="actions" :data="item" :index="index">
<div class="g-invitation-list-item-buttons">
<d-button
icon="edit"
variant="text"
:loading="isHandling"
class="g-invitation-list-item-button"
@click="emits('edit', { data: item, index })"
>
编辑
</d-button>
<d-button
icon="close"
variant="text"
:loading="isHandling"
class="g-invitation-list-item-button"
@click="emits('delete', { data: item, index })"
>
删除
</d-button>
</div>
</slot>
</div>
</div>
</section>
</template>
<script lang="ts">
export default {
name: 'invitation-list'
};
</script>
<script setup lang="ts">
import type { InvitationItemData } from '@/components/InvitationList/types';
import CustomTag from '@/components/CustomTag/index.vue';
import Copy from '@/components/Copy/index.vue';
withDefaults(defineProps<{
data: InvitationItemData[];
statusOptions: {label: string; value: string | number}[]
isHandling: boolean;
}>(), {
data: () => [],
statusOptions: () => [
{
label: '开发者',
value: 1
},
{
label: '管理员',
value: 2
},
{
label: '浏览者',
value: 3
}
],
isHandling: false
});
const emits = defineEmits<{(e: 'statusChange', data: { data: InvitationItemData; index: number }): void;
(e: 'edit', data: { data: InvitationItemData; index: number }): void;
(e: 'delete', data: { data: InvitationItemData; index: number }): void;
}>();
</script>
<style scoped lang="scss">
$g-invitation-border-radius: 4px;
$g-invitation-border-color: #D3D3D3;
$g-invitation-text-color: #000000;
$g-invitation-text-color-second: #606060;
.g-invitation-list {
border: 1px solid $g-invitation-border-color;
border-radius: $g-invitation-border-radius;
&-item {
border-bottom: 1px solid $g-invitation-border-color;
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
&:last-child {
border-bottom: none;
}
&-status {
&-select {
:deep(.devui-editable-select-input__wrapper) {
border: none;
}
:deep(.devui-editable-select-input__inner) {
color: $g-invitation-text-color-second;
}
:deep(.devui-editable-select__inner) {
padding: 0;
}
}
}
&-header {
display: flex;
align-items: center;
}
&-bottom {
margin-top: 8px;
display: flex;
align-items: center;
}
&-title {
font-size: 16px;
font-weight: 400;
line-height: normal;
color: $g-invitation-text-color;
margin-right: 24px;
}
&-tag {
margin-right: 24px;
}
&-bottom {
padding: 2px 0;
}
&-effect-range {
font-weight: 400;
line-height: normal;
font-size: 12px;
color: $g-invitation-text-color-second;
}
&-actions {
display: flex;
align-items: center;
}
&-button {
margin-left: 16px;
&.devui-button--text.devui-button__icon-wrap {
color: $g-invitation-text-color-second;
}
}
}
}
</style>

View File

@@ -0,0 +1,16 @@
export type InvitationItemData = {
// 邀请名称
title: string;
// 是否需要审核
needReview: boolean;
// 有效期
beginDate: string;
endDate: string;
// 链接地址
link?: string;
// id
id: string | number;
// 身份
status: string | number;
[propName: string]: any;
}