🎈 perf: 修改社团列表
This commit is contained in:
parent
b71228e061
commit
07e215bdc9
@ -9,31 +9,12 @@
|
||||
>
|
||||
<template #default="{ data }">
|
||||
<div class="flex gap-10px">
|
||||
<div
|
||||
<club-list-item
|
||||
v-for="club of data"
|
||||
class="flex flex-col items-center"
|
||||
:class="itemClass"
|
||||
:key="club.id"
|
||||
@click="onItemClick(club)"
|
||||
>
|
||||
<el-avatar
|
||||
shape="square"
|
||||
class="select-none"
|
||||
:size="100"
|
||||
:src="getAvatarURL(club.avatar)"
|
||||
>
|
||||
<div class="text-black">暂无图片</div>
|
||||
</el-avatar>
|
||||
<div class="text-5 font-bold">{{ club.name }}</div>
|
||||
<el-text
|
||||
v-if="userStore.userInfo?.club?.id === club.id"
|
||||
type="success"
|
||||
class="flex items-center"
|
||||
>
|
||||
<icon-ep-success-filled />
|
||||
<b>已加入</b>
|
||||
</el-text>
|
||||
</div>
|
||||
:club="club"
|
||||
:click="click"
|
||||
@click="click && $emit('click', club)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #empty>
|
||||
@ -42,22 +23,19 @@
|
||||
</paged-wrapper>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { getAvatarURL } from '@/api';
|
||||
import PagedWrapper from '@/components/PagedWrapper.vue';
|
||||
import { clubListRespSchema, type Club } from '@/schemas/response';
|
||||
import { useUserStore } from '@/stores/user';
|
||||
import type { ComponentProps } from 'vue-component-type-helpers';
|
||||
import ClubListItem from './ClubListItem.vue';
|
||||
const userStore = useUserStore();
|
||||
const { brief = false } = defineProps<{
|
||||
const { click = false, brief = false } = defineProps<{
|
||||
brief?: boolean;
|
||||
itemClass?: string;
|
||||
click?: boolean;
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
click: [club: Club];
|
||||
}>();
|
||||
function onItemClick(club: Club) {
|
||||
emit('click', club);
|
||||
}
|
||||
const getClubListRequestOptions: ComponentProps<typeof PagedWrapper>['getRequestOptions'] = (
|
||||
page,
|
||||
num,
|
||||
|
44
src/components/club/ClubListItem.vue
Normal file
44
src/components/club/ClubListItem.vue
Normal file
@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<div
|
||||
class="flex"
|
||||
:class="{
|
||||
'cursor-pointer': click,
|
||||
'flex-col items-center': mode === 'v',
|
||||
'gap-10px': mode === 'h',
|
||||
}"
|
||||
:key="club.id"
|
||||
@click="click && $emit('click', club)"
|
||||
>
|
||||
<el-avatar shape="square" class="select-none" :size="100" :src="getAvatarURL(club.avatar)">
|
||||
<div class="text-black">暂无图片</div>
|
||||
</el-avatar>
|
||||
<div class="flex flex-col" :class="{ 'items-center': mode === 'v' }">
|
||||
<div class="text-black font-bold" :class="mode === 'v' ? 'text-5' : 'text-7'">
|
||||
{{ club.name }}
|
||||
</div>
|
||||
<div>
|
||||
<el-text
|
||||
v-if="userStore.userInfo?.club?.id === club.id"
|
||||
class="flex items-center gap-5px"
|
||||
:size="mode === 'h' ? 'large' : 'default'"
|
||||
type="success"
|
||||
>
|
||||
<icon-ep-success-filled />
|
||||
<b>已加入</b>
|
||||
</el-text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { getAvatarURL } from '@/api';
|
||||
import type { Club } from '@/schemas/response';
|
||||
import { useUserStore } from '@/stores/user';
|
||||
const userStore = useUserStore();
|
||||
const { click = false, mode = 'v' } = defineProps<{
|
||||
club: Club;
|
||||
click?: boolean;
|
||||
mode?: 'h' | 'v';
|
||||
}>();
|
||||
defineEmits<{ click: [club: Club] }>();
|
||||
</script>
|
@ -127,6 +127,7 @@ const routes: RouteRecordRaw[] = [
|
||||
userPermission: {
|
||||
id: UserPermissionId.MANAGE_PAGE,
|
||||
},
|
||||
breadcrumb: '社团管理',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { REQUEST_BASE_URL } from '@/env';
|
||||
|
||||
export namespace Neusoft {
|
||||
export type BaseResp<T extends Record<string, unknown>> = {
|
||||
code: number;
|
||||
@ -30,6 +32,6 @@ export namespace Neusoft.SmartParty {
|
||||
export type GalleryResp = PagedResp<Gallery>;
|
||||
}
|
||||
export namespace Neusoft {
|
||||
export const SMART_PARTY_BASE_URL = 'http://124.93.196.45:10091/Neusoft/party';
|
||||
export const SMART_PARTY_BASE_URL = `${REQUEST_BASE_URL}/neusoft`;
|
||||
export const isSucceed = (resp: BaseResp<{}>) => resp.code >= 200 && resp.code < 300;
|
||||
}
|
||||
|
@ -11,8 +11,8 @@ const createRespSchema = <T extends z.ZodTypeAny>(data: T) =>
|
||||
.extend({ data: data })
|
||||
.transform((raw) =>
|
||||
Object.assign(raw, {
|
||||
type: 'success',
|
||||
} as const),
|
||||
type: 'success' as const,
|
||||
}),
|
||||
),
|
||||
z
|
||||
.object({
|
||||
@ -22,10 +22,18 @@ const createRespSchema = <T extends z.ZodTypeAny>(data: T) =>
|
||||
})
|
||||
.transform((raw) =>
|
||||
Object.assign(raw, {
|
||||
type: 'error',
|
||||
} as const),
|
||||
type: 'error' as const,
|
||||
}),
|
||||
),
|
||||
]);
|
||||
export const createPagedRespSchema = <T extends z.ZodTypeAny>(data: T) =>
|
||||
createRespSchema(
|
||||
z.object({
|
||||
data: data.array(),
|
||||
total: z.number(),
|
||||
}),
|
||||
);
|
||||
export type AnyPagedRespSchema = ReturnType<typeof createPagedRespSchema>;
|
||||
export type SucceedRespOf<T> = Extract<T, { type: 'success' }>;
|
||||
export type AnyRespSchema = ReturnType<typeof createRespSchema>;
|
||||
export type ErrorResp = Extract<z.infer<AnyRespSchema>, { type: 'error' }>;
|
||||
@ -38,14 +46,16 @@ export const idAndNameSchema = z.object({
|
||||
const authSchema = idAndNameSchema.extend({
|
||||
permissions: idAndNameSchema.array(),
|
||||
});
|
||||
export const clubSchema = idAndNameSchema.extend({
|
||||
avatar: z.optional(z.string()),
|
||||
commit: z.string(),
|
||||
});
|
||||
export type Club = z.infer<typeof clubSchema>;
|
||||
export const clubListRespSchema = createPagedRespSchema(clubSchema);
|
||||
const userInfoDataSchema = idAndNameSchema.extend({
|
||||
avatar: z.optional(z.string()),
|
||||
auth: authSchema,
|
||||
club: z.optional(
|
||||
idAndNameSchema.extend({
|
||||
commit: z.string(),
|
||||
}),
|
||||
),
|
||||
club: z.optional(clubSchema),
|
||||
clubAuth: z.optional(authSchema),
|
||||
});
|
||||
export const userInfoRespSchema = createRespSchema(userInfoDataSchema);
|
||||
@ -65,17 +75,3 @@ export const verifyRespSchema = createRespSchema(
|
||||
}),
|
||||
);
|
||||
export const uploadAvatarRespSchema = createRespSchema(z.string());
|
||||
export const clubSchema = idAndNameSchema.extend({
|
||||
avatar: z.optional(z.string()),
|
||||
commit: z.string(),
|
||||
});
|
||||
export type Club = z.infer<typeof clubSchema>;
|
||||
export const createPagedRespSchema = <T extends z.ZodTypeAny>(data: T) =>
|
||||
createRespSchema(
|
||||
z.object({
|
||||
data: data.array(),
|
||||
total: z.number(),
|
||||
}),
|
||||
);
|
||||
export type AnyPagedRespSchema = ReturnType<typeof createPagedRespSchema>;
|
||||
export const clubListRespSchema = createPagedRespSchema(clubSchema);
|
||||
|
@ -5,15 +5,34 @@
|
||||
<template #header>
|
||||
<b>社团列表</b>
|
||||
</template>
|
||||
<club-list item-class="cursor-pointer" @click="onClubClick" />
|
||||
<club-list click @click="onClubClick" />
|
||||
</el-card>
|
||||
</div>
|
||||
<el-dialog v-model="showClubDialog">
|
||||
<template #title>社团信息</template>
|
||||
<template v-if="showClubDialog"></template>
|
||||
<el-dialog :class="$style['el-dialog']" v-model="showClubDialog" align-center>
|
||||
<template #title><b>社团信息</b></template>
|
||||
<div class="flex flex-col" v-if="showingClub">
|
||||
<club-list-item :club="showingClub" mode="h" />
|
||||
<div>简介:{{ showingClub.commit }}</div>
|
||||
<template v-if="userStore.logined && userInfo">
|
||||
<el-button
|
||||
v-if="userInfo.club && userInfo.club.id === showingClub.id"
|
||||
class="self-end"
|
||||
type="primary"
|
||||
>
|
||||
进入主页
|
||||
</el-button>
|
||||
<el-button v-else class="self-end" type="success">加入社团</el-button>
|
||||
</template>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-main>
|
||||
</template>
|
||||
<style lang="scss" module>
|
||||
.el-dialog {
|
||||
position: relative;
|
||||
--el-text-color-regular: black;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.el-card {
|
||||
--el-card-padding: 15px;
|
||||
@ -21,11 +40,13 @@
|
||||
</style>
|
||||
<script lang="ts" setup>
|
||||
import ClubList from '@/components/club/ClubList.vue';
|
||||
import { UserPermissionId } from '@/router/permissions';
|
||||
import ClubListItem from '@/components/club/ClubListItem.vue';
|
||||
import type { Club } from '@/schemas/response';
|
||||
import { useUserStore } from '@/stores/user';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { ref } from 'vue';
|
||||
const userStore = useUserStore();
|
||||
const { userInfo } = storeToRefs(userStore);
|
||||
const showingClub = ref<Club>();
|
||||
const showClubDialog = ref(false);
|
||||
function onClubClick(club: Club) {
|
||||
|
@ -1,3 +1,8 @@
|
||||
<template>
|
||||
<div>123</div>
|
||||
<el-main>
|
||||
<manage-breadcrumb />
|
||||
</el-main>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import ManageBreadcrumb from '@/components/manage/ManageBreadcrumb.vue';
|
||||
</script>
|
||||
|
Loading…
x
Reference in New Issue
Block a user