add
This commit is contained in:
parent
f8f3e7985e
commit
3432b1af79
|
@ -7,11 +7,18 @@ import {
|
||||||
VisitType,
|
VisitType,
|
||||||
} from '@nice/common';
|
} from '@nice/common';
|
||||||
export async function updateTotalCourseViewCount(type: VisitType) {
|
export async function updateTotalCourseViewCount(type: VisitType) {
|
||||||
const courses = await db.post.findMany({
|
const posts = await db.post.findMany({
|
||||||
where: { type: PostType.COURSE },
|
where: {
|
||||||
select: { id: true },
|
type: { in: [PostType.COURSE, PostType.LECTURE] },
|
||||||
|
deletedAt: null,
|
||||||
|
},
|
||||||
|
select: { id: true, type: true },
|
||||||
});
|
});
|
||||||
const courseIds = courses.map((course) => course.id);
|
|
||||||
|
const courseIds = posts
|
||||||
|
.filter((post) => post.type === PostType.COURSE)
|
||||||
|
.map((course) => course.id);
|
||||||
|
const lectures = posts.filter((post) => post.type === PostType.LECTURE);
|
||||||
const totalViews = await db.visit.aggregate({
|
const totalViews = await db.visit.aggregate({
|
||||||
_sum: {
|
_sum: {
|
||||||
views: true,
|
views: true,
|
||||||
|
@ -30,6 +37,10 @@ export async function updateTotalCourseViewCount(type: VisitType) {
|
||||||
meta: true,
|
meta: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const staffs = await db.staff.count({
|
||||||
|
where: { deletedAt: null },
|
||||||
|
});
|
||||||
|
|
||||||
const baseSeting = appConfig.meta as BaseSetting;
|
const baseSeting = appConfig.meta as BaseSetting;
|
||||||
await db.appConfig.update({
|
await db.appConfig.update({
|
||||||
where: {
|
where: {
|
||||||
|
@ -38,7 +49,15 @@ export async function updateTotalCourseViewCount(type: VisitType) {
|
||||||
data: {
|
data: {
|
||||||
meta: {
|
meta: {
|
||||||
...baseSeting,
|
...baseSeting,
|
||||||
reads: totalViews._sum.views,
|
appConfig: {
|
||||||
|
...(baseSeting?.appConfig || {}),
|
||||||
|
statistics: {
|
||||||
|
reads: totalViews._sum.views || 0,
|
||||||
|
courses: courseIds?.length || 0,
|
||||||
|
staffs: staffs || 0,
|
||||||
|
lectures: lectures?.length || 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -45,16 +45,16 @@ const carouselItems: CarouselItem[] = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const platformStats: PlatformStat[] = [
|
|
||||||
{ icon: <TeamOutlined />, value: "50,000+", label: "注册学员" },
|
|
||||||
{ icon: <BookOutlined />, value: "1,000+", label: "精品课程" },
|
|
||||||
// { icon: <StarOutlined />, value: '98%', label: '好评度' },
|
|
||||||
{ icon: <EyeOutlined />, value: "100万+", label: "观看次数" },
|
|
||||||
];
|
|
||||||
|
|
||||||
const HeroSection = () => {
|
const HeroSection = () => {
|
||||||
const carouselRef = useRef<CarouselRef>(null);
|
const carouselRef = useRef<CarouselRef>(null);
|
||||||
|
const { statistics, baseSetting } = useAppConfig();
|
||||||
|
|
||||||
|
const platformStats: PlatformStat[] = [
|
||||||
|
{ icon: <TeamOutlined />, value: "50,000+", label: "注册学员" },
|
||||||
|
{ icon: <BookOutlined />, value: "1,000+", label: "精品课程" },
|
||||||
|
// { icon: <StarOutlined />, value: '98%', label: '好评度' },
|
||||||
|
{ icon: <EyeOutlined />, value: "4552", label: "观看次数" },
|
||||||
|
];
|
||||||
const handlePrev = useCallback(() => {
|
const handlePrev = useCallback(() => {
|
||||||
carouselRef.current?.prev();
|
carouselRef.current?.prev();
|
||||||
}, []);
|
}, []);
|
||||||
|
@ -74,8 +74,8 @@ const HeroSection = () => {
|
||||||
dots={{
|
dots={{
|
||||||
className: "carousel-dots !bottom-32 !z-20",
|
className: "carousel-dots !bottom-32 !z-20",
|
||||||
}}>
|
}}>
|
||||||
{Array.isArray(carouselItems)?
|
{Array.isArray(carouselItems) ? (
|
||||||
(carouselItems.map((item, index) => (
|
carouselItems.map((item, index) => (
|
||||||
<div key={index} className="relative h-[600px]">
|
<div key={index} className="relative h-[600px]">
|
||||||
<div
|
<div
|
||||||
className="absolute inset-0 bg-cover bg-center transform transition-[transform,filter] duration-[2000ms] group-hover:scale-105 group-hover:brightness-110 will-change-[transform,filter]"
|
className="absolute inset-0 bg-cover bg-center transform transition-[transform,filter] duration-[2000ms] group-hover:scale-105 group-hover:brightness-110 will-change-[transform,filter]"
|
||||||
|
@ -93,11 +93,10 @@ const HeroSection = () => {
|
||||||
{/* Content Container */}
|
{/* Content Container */}
|
||||||
<div className="relative h-full max-w-7xl mx-auto px-6 lg:px-8"></div>
|
<div className="relative h-full max-w-7xl mx-auto px-6 lg:px-8"></div>
|
||||||
</div>
|
</div>
|
||||||
)))
|
))
|
||||||
:(
|
) : (
|
||||||
<div></div>
|
<div></div>
|
||||||
)
|
)}
|
||||||
}
|
|
||||||
</Carousel>
|
</Carousel>
|
||||||
|
|
||||||
{/* Navigation Buttons */}
|
{/* Navigation Buttons */}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React, { ReactNode } from "react";
|
||||||
export interface MenuItemType {
|
export interface MenuItemType {
|
||||||
icon: React.;
|
icon: ReactNode;
|
||||||
label: string;
|
label: string;
|
||||||
action: () => void;
|
action: () => void;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import {
|
||||||
SkeletonItem,
|
SkeletonItem,
|
||||||
SkeletonSection,
|
SkeletonSection,
|
||||||
} from "@web/src/components/presentation/Skeleton";
|
} from "@web/src/components/presentation/Skeleton";
|
||||||
|
import { api } from "packages/client/dist";
|
||||||
|
|
||||||
export const CourseDetailSkeleton = () => {
|
export const CourseDetailSkeleton = () => {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -15,7 +15,7 @@ export function useTusUpload() {
|
||||||
>({});
|
>({});
|
||||||
const [isUploading, setIsUploading] = useState(false);
|
const [isUploading, setIsUploading] = useState(false);
|
||||||
const [uploadError, setUploadError] = useState<string | null>(null);
|
const [uploadError, setUploadError] = useState<string | null>(null);
|
||||||
|
|
||||||
const getFileId = (url: string) => {
|
const getFileId = (url: string) => {
|
||||||
const parts = url.split("/");
|
const parts = url.split("/");
|
||||||
const uploadIndex = parts.findIndex((part) => part === "upload");
|
const uploadIndex = parts.findIndex((part) => part === "upload");
|
||||||
|
|
|
@ -10,6 +10,7 @@ export function useAppConfig() {
|
||||||
api.app_config.findFirst.useQuery({
|
api.app_config.findFirst.useQuery({
|
||||||
where: { slug: AppConfigSlug.BASE_SETTING },
|
where: { slug: AppConfigSlug.BASE_SETTING },
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleMutationSuccess = useCallback(() => {
|
const handleMutationSuccess = useCallback(() => {
|
||||||
utils.app_config.invalidate();
|
utils.app_config.invalidate();
|
||||||
}, [utils]);
|
}, [utils]);
|
||||||
|
@ -26,7 +27,8 @@ export function useAppConfig() {
|
||||||
});
|
});
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data?.meta) {
|
if (data?.meta) {
|
||||||
setBaseSetting(JSON.parse(data?.meta));
|
// console.log(JSON.parse(data?.meta));
|
||||||
|
setBaseSetting(data?.meta);
|
||||||
}
|
}
|
||||||
}, [data, isLoading]);
|
}, [data, isLoading]);
|
||||||
const splashScreen = useMemo(() => {
|
const splashScreen = useMemo(() => {
|
||||||
|
@ -38,6 +40,16 @@ export function useAppConfig() {
|
||||||
const slides = useMemo(() => {
|
const slides = useMemo(() => {
|
||||||
return baseSetting?.appConfig?.slides || [];
|
return baseSetting?.appConfig?.slides || [];
|
||||||
}, [baseSetting]);
|
}, [baseSetting]);
|
||||||
|
const statistics = useMemo(() => {
|
||||||
|
return (
|
||||||
|
baseSetting?.appConfig?.statistics || {
|
||||||
|
reads: 0,
|
||||||
|
staffs: 0,
|
||||||
|
courses: 0,
|
||||||
|
lectures: 0,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}, [baseSetting]);
|
||||||
return {
|
return {
|
||||||
create,
|
create,
|
||||||
deleteMany,
|
deleteMany,
|
||||||
|
@ -47,5 +59,6 @@ export function useAppConfig() {
|
||||||
devDept,
|
devDept,
|
||||||
isLoading,
|
isLoading,
|
||||||
slides,
|
slides,
|
||||||
|
statistics,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,12 @@ export interface BaseSetting {
|
||||||
splashScreen?: string;
|
splashScreen?: string;
|
||||||
devDept?: string;
|
devDept?: string;
|
||||||
slides?: [];
|
slides?: [];
|
||||||
reads?: number;
|
statistics?: {
|
||||||
|
reads?: number;
|
||||||
|
courses?: number;
|
||||||
|
lectures?: number;
|
||||||
|
staffs?: number;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
export type RowModelResult = {
|
export type RowModelResult = {
|
||||||
|
|
Loading…
Reference in New Issue