185 lines
5.0 KiB
Vue
185 lines
5.0 KiB
Vue
|
|
<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>
|