Files
gamegroup2/frontend/src/components/group/JoinGroupDialog.vue
T

178 lines
3.9 KiB
Vue
Raw Normal View History

<script setup lang="ts">
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { getGroup, joinGroup, createJoinRequest } from '@/api/groups'
import type { Group } from '@/types'
const props = defineProps<{
modelValue: boolean
}>()
const emit = defineEmits<{
'update:modelValue': [value: boolean]
}>()
const visible = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val)
})
const groupId = ref('')
const groupInfo = ref<Group | null>(null)
const loading = ref(false)
const joining = ref(false)
async function searchGroup() {
if (!groupId.value.trim()) {
ElMessage.warning('请输入群组 ID')
return
}
loading.value = true
try {
groupInfo.value = await getGroup(groupId.value.trim())
} catch {
groupInfo.value = null
ElMessage.error('未找到该群组')
} finally {
loading.value = false
}
}
async function handleJoin() {
if (!groupInfo.value) return
joining.value = true
try {
if (groupInfo.value.requireApproval) {
await createJoinRequest(groupInfo.value.id)
ElMessage.success('已提交加入申请,等待群主审核')
} else {
await joinGroup(groupInfo.value.id)
ElMessage.success('已成功加入群组')
}
visible.value = false
groupId.value = ''
groupInfo.value = null
} catch (error: any) {
ElMessage.error(error.message || '操作失败')
} finally {
joining.value = false
}
}
function reset() {
groupId.value = ''
groupInfo.value = null
}
</script>
<template>
<el-dialog v-model="visible" title="加入群组" width="440px" @close="reset">
<div class="join-form">
<div class="form-field">
<label>群组 ID</label>
<div class="search-row">
<el-input v-model="groupId" placeholder="输入群主分享的群组 ID" />
<el-button type="primary" :loading="loading" @click="searchGroup">查找</el-button>
</div>
</div>
<div v-if="groupInfo" class="group-preview">
<div class="preview-header">
<h3 class="preview-name">{{ groupInfo.name }}</h3>
<span class="preview-members">{{ groupInfo.members?.length || 0 }} / {{ groupInfo.maxMembers }} </span>
</div>
<p v-if="groupInfo.description" class="preview-desc">{{ groupInfo.description }}</p>
<div class="approval-tag">
<span v-if="groupInfo.requireApproval" class="tag-approval">需要审核</span>
<span v-else class="tag-direct">直接加入</span>
</div>
<el-button type="primary" :loading="joining" @click="handleJoin" style="width:100%; margin-top: 12px;">
{{ groupInfo.requireApproval ? '申请加入' : '加入群组' }}
</el-button>
</div>
</div>
</el-dialog>
</template>
<style scoped>
.join-form {
display: flex;
flex-direction: column;
gap: 20px;
}
.form-field {
display: flex;
flex-direction: column;
gap: 8px;
}
.form-field label {
font-size: 14px;
font-weight: 500;
}
.search-row {
display: flex;
gap: 8px;
}
.search-row .el-input {
flex: 1;
}
.group-preview {
padding: 16px;
background: var(--gg-bg-card);
border: 1px solid var(--gg-border);
border-radius: var(--gg-radius-md);
}
.preview-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.preview-name {
margin: 0;
font-size: 16px;
font-weight: 600;
}
.preview-members {
font-size: 13px;
color: var(--gg-text-secondary);
}
.preview-desc {
margin: 8px 0 0;
font-size: 14px;
color: var(--gg-text-secondary);
}
.approval-tag {
margin-top: 10px;
}
.tag-approval {
display: inline-block;
padding: 3px 10px;
border-radius: 6px;
font-size: 12px;
font-weight: 500;
background: rgba(245, 158, 11, 0.12);
color: #f59e0b;
}
.tag-direct {
display: inline-block;
padding: 3px 10px;
border-radius: 6px;
font-size: 12px;
font-weight: 500;
background: rgba(5, 150, 105, 0.12);
color: var(--gg-primary);
}
</style>