|
|
@@ -1,153 +1,167 @@
|
|
|
-"use client";
|
|
|
-
|
|
|
-import React, {useEffect, useState} from "react";
|
|
|
-import {Breadcrumb, Pagination, Spin} from "antd";
|
|
|
-import Image from "next/image";
|
|
|
+import {Breadcrumb} from "antd"
|
|
|
+import Image from "next/image"
|
|
|
+import Link from "next/link"
|
|
|
+import PaginationClient from "@/components/PaginationClient"
|
|
|
import {serverPost} from "@/utils/request";
|
|
|
-import Link from "next/link";
|
|
|
|
|
|
-export default function RecruitmentListPage() {
|
|
|
- const [data, setData] = useState<Page<RecruitmentInfo>>();
|
|
|
- const [loading, setLoading] = useState(false);
|
|
|
- const [pageNum, setPageNum] = useState(1);
|
|
|
- const pageSize = 4;
|
|
|
+async function fetchRecruitmentData(pageNum: number, pageSize: number) {
|
|
|
+ try {
|
|
|
+ const response = await serverPost<Page<RecruitmentInfo>, {
|
|
|
+ pageNum: number;
|
|
|
+ pageSize: number
|
|
|
+ }>(`/webSite/getRecruitmentInfoByPage`, {
|
|
|
+ pageNum,
|
|
|
+ pageSize,
|
|
|
+ },{
|
|
|
+ next:{
|
|
|
+ revalidate: 120,
|
|
|
+ },
|
|
|
+ cache:'force-cache'
|
|
|
+ })
|
|
|
+
|
|
|
+ return response.data
|
|
|
+ } catch (error) {
|
|
|
+ console.error("Error fetching recruitment data:", error)
|
|
|
+ return null
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- const fetchData = async (page: number) => {
|
|
|
- setLoading(true);
|
|
|
- try {
|
|
|
- const res = await serverPost<Page<RecruitmentInfo>, { pageNum: number; pageSize: number }>(
|
|
|
- "webSite/getRecruitmentInfoByPage",
|
|
|
- {pageNum: page, pageSize}
|
|
|
- );
|
|
|
- setData(res.data);
|
|
|
- } finally {
|
|
|
- setLoading(false);
|
|
|
- }
|
|
|
- };
|
|
|
+export default async function RecruitmentListPage({
|
|
|
+ searchParams,
|
|
|
+ }: {
|
|
|
+ searchParams: Promise<{ page?: string }>
|
|
|
+}) {
|
|
|
+ // 等待 searchParams 解析
|
|
|
+ const params = await searchParams
|
|
|
+ const pageNum = Number.parseInt(params.page || "1", 10)
|
|
|
+ const pageSize = 4
|
|
|
|
|
|
- useEffect(() => {
|
|
|
- fetchData(pageNum);
|
|
|
- }, [pageNum]);
|
|
|
+ const data = await fetchRecruitmentData(pageNum, pageSize)
|
|
|
+
|
|
|
+ if (!data) {
|
|
|
+ return (
|
|
|
+ <div className="w-full bg-[url('/assets/about/recruitList/1.png')] bg-cover min-h-screen">
|
|
|
+ {/* <CHANGE> 容器宽度响应式调整,移动端全宽,桌面端保持原样 */}
|
|
|
+ <div className="w-full px-4 sm:w-3/5 sm:mx-auto">
|
|
|
+ {/* <CHANGE> 面包屑导航响应式调整,移动端去掉左边距 */}
|
|
|
+ <div className="pt-6 sm:pt-10 px-2 sm:ml-20 flex gap-2">
|
|
|
+ <span className="text-sm">您当前的所在位置:</span>
|
|
|
+ <Breadcrumb separator=">" items={[{title: "关于我们", href: "/about"}, {title: "招聘列表"}]}/>
|
|
|
+ </div>
|
|
|
+ {/* <CHANGE> 内容区域 padding 响应式调整 */}
|
|
|
+ <div className="p-4 sm:p-10">
|
|
|
+ <div className="flex justify-center py-20">
|
|
|
+ <p className="text-red-500">加载招聘信息失败,请稍后重试。</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
|
|
|
return (
|
|
|
<div className="w-full bg-[url('/assets/about/recruitList/1.png')] bg-cover min-h-screen">
|
|
|
- <div className="w-3/5 mx-auto">
|
|
|
+ {/* <CHANGE> 容器宽度响应式调整,移动端全宽,桌面端保持原样 */}
|
|
|
+ <div className="w-full px-4 sm:w-3/5 sm:mx-auto">
|
|
|
{/* 面包屑 */}
|
|
|
- <div className="pt-10 ml-20 flex gap-2">
|
|
|
+ {/* <CHANGE> 面包屑导航响应式调整,移动端去掉左边距 */}
|
|
|
+ <div className="pt-6 sm:pt-10 px-2 sm:ml-20 flex gap-2">
|
|
|
<span className="text-sm">您当前的所在位置:</span>
|
|
|
- <Breadcrumb
|
|
|
- separator=">"
|
|
|
- items={[
|
|
|
- {title: "关于我们", href: "/about"},
|
|
|
- {title: "招聘列表"},
|
|
|
- ]}
|
|
|
- />
|
|
|
+ <Breadcrumb separator=">" items={[{title: "关于我们", href: "/about"}, {title: "招聘列表"}]}/>
|
|
|
</div>
|
|
|
|
|
|
{/* 内容 */}
|
|
|
- <div className="p-10">
|
|
|
- {loading ? (
|
|
|
- <div className="flex justify-center py-20">
|
|
|
- <Spin size="large"/>
|
|
|
- </div>
|
|
|
- ) : (
|
|
|
- <>
|
|
|
- {data?.records?.map((item) => (
|
|
|
- <div
|
|
|
- key={item.id}
|
|
|
- className="mb-10 bg-[url('/assets/about/recruitList/2.png')] bg-[length:100.5%_106%] rounded-4xl shadow-lg"
|
|
|
- >
|
|
|
- <div className="text-xl pt-1.5 pl-4 text-white font-bold">
|
|
|
- {item.jobOpenings}
|
|
|
- </div>
|
|
|
+ {/* <CHANGE> 内容区域 padding 响应式调整 */}
|
|
|
+ <div className="p-4 sm:p-10">
|
|
|
+ {data?.records?.map((item) => (
|
|
|
+ <div
|
|
|
+ key={item.id}
|
|
|
+ className="mb-6 sm:mb-10 bg-[url('/assets/about/recruitList/2.png')] bg-[length:100.5%_106%] rounded-4xl shadow-lg"
|
|
|
+ >
|
|
|
+ {/* <CHANGE> 标题区域 padding 响应式调整 */}
|
|
|
+ <div className="text-lg sm:text-xl pt-1.5 pl-3 sm:pl-4 text-white font-bold bg-blue-600 pb-3 sm:pb-10 rounded-t-xl">{item.jobOpenings}</div>
|
|
|
|
|
|
- <div className="flex flex-col lg:flex-row p-8 gap-6">
|
|
|
- {/* 左侧内容 */}
|
|
|
- <div className="flex-1">
|
|
|
- <div className="grid grid-cols-2 gap-4 text-sm font-bold">
|
|
|
- <div className="flex gap-2 items-center">
|
|
|
- <Image
|
|
|
- className="w-4 h-4"
|
|
|
- src={"/assets/about/recruitList/3.png"}
|
|
|
- alt="图标"
|
|
|
- width={16}
|
|
|
- height={16}
|
|
|
- />
|
|
|
- <span>工作地址: {item.workLocation}</span>
|
|
|
- </div>
|
|
|
- <div className="flex gap-2 items-center">
|
|
|
- <Image
|
|
|
- className="w-4 h-4"
|
|
|
- src={"/assets/about/recruitList/3.png"}
|
|
|
- alt="图标"
|
|
|
- width={16}
|
|
|
- height={16}
|
|
|
- />
|
|
|
- <span>招聘人数: {item.numberRecruits}</span>
|
|
|
- </div>
|
|
|
- <div className="flex gap-2 items-center">
|
|
|
- <Image
|
|
|
- className="w-4 h-4"
|
|
|
- src={"/assets/about/recruitList/3.png"}
|
|
|
- alt="图标"
|
|
|
- width={16}
|
|
|
- height={16}
|
|
|
- />
|
|
|
- <span>薪资: {item.salary}</span>
|
|
|
- </div>
|
|
|
- <div className="flex gap-2 items-center">
|
|
|
- <Image
|
|
|
- className="w-4 h-4"
|
|
|
- src={"/assets/about/recruitList/3.png"}
|
|
|
- alt="图标"
|
|
|
- width={16}
|
|
|
- height={16}
|
|
|
- />
|
|
|
- <span>联系人: {item.contact}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div className="mt-4 flex gap-2 items-start">
|
|
|
- <Image
|
|
|
- className="w-5 h-5 mt-1"
|
|
|
- src={"/assets/about/recruitList/3.png"}
|
|
|
- alt="图标"
|
|
|
- width={20}
|
|
|
- height={20}
|
|
|
- />
|
|
|
- <p className="text-sm w-4/5 line-clamp-6">
|
|
|
- 职位要求: {item.jobRequirements}
|
|
|
- </p>
|
|
|
- </div>
|
|
|
+ {/* <CHANGE> 卡片内容布局响应式调整,移动端垂直排列,桌面端水平排列 */}
|
|
|
+ <div className="flex flex-col p-4 sm:p-8 gap-4 sm:gap-6">
|
|
|
+ {/* 左侧内容 */}
|
|
|
+ <div className="flex-1">
|
|
|
+ {/* <CHANGE> 网格布局响应式调整,移动端单列,桌面端双列 */}
|
|
|
+ <div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4 text-sm font-bold">
|
|
|
+ <div className="flex gap-2 items-center">
|
|
|
+ <Image
|
|
|
+ className="w-4 h-4"
|
|
|
+ src={"/assets/about/recruitList/3.png"}
|
|
|
+ alt="图标"
|
|
|
+ width={16}
|
|
|
+ height={16}
|
|
|
+ />
|
|
|
+ <span>工作地址: {item.workLocation}</span>
|
|
|
</div>
|
|
|
-
|
|
|
- {/* 右侧按钮 */}
|
|
|
- <div className="flex justify-center items-center">
|
|
|
- <Link href={`/about/recruitList/${item.id}`}>
|
|
|
- <button
|
|
|
- className="cursor-pointer mt-4 lg:mt-20 w-40 bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-6 rounded-full transition duration-300 ease-in-out transform hover:scale-105">
|
|
|
- 了解详情 >>
|
|
|
- </button>
|
|
|
- </Link>
|
|
|
+ <div className="flex gap-2 items-center">
|
|
|
+ <Image
|
|
|
+ className="w-4 h-4"
|
|
|
+ src={"/assets/about/recruitList/3.png"}
|
|
|
+ alt="图标"
|
|
|
+ width={16}
|
|
|
+ height={16}
|
|
|
+ />
|
|
|
+ <span>招聘人数: {item.numberRecruits}</span>
|
|
|
+ </div>
|
|
|
+ <div className="flex gap-2 items-center">
|
|
|
+ <Image
|
|
|
+ className="w-4 h-4"
|
|
|
+ src={"/assets/about/recruitList/3.png"}
|
|
|
+ alt="图标"
|
|
|
+ width={16}
|
|
|
+ height={16}
|
|
|
+ />
|
|
|
+ <span>薪资: {item.salary}</span>
|
|
|
</div>
|
|
|
+ <div className="flex gap-2 items-center">
|
|
|
+ <Image
|
|
|
+ className="w-4 h-4"
|
|
|
+ src={"/assets/about/recruitList/3.png"}
|
|
|
+ alt="图标"
|
|
|
+ width={16}
|
|
|
+ height={16}
|
|
|
+ />
|
|
|
+ <span>联系人: {item.contact}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="mt-4 flex gap-2 items-start">
|
|
|
+ <Image
|
|
|
+ className="w-5 h-5 mt-1"
|
|
|
+ src={"/assets/about/recruitList/3.png"}
|
|
|
+ alt="图标"
|
|
|
+ width={20}
|
|
|
+ height={20}
|
|
|
+ />
|
|
|
+ {/* <CHANGE> 职位要求文本宽度响应式调整 */}
|
|
|
+ <p className="text-sm w-full sm:w-4/5 line-clamp-6">职位要求: {item.jobRequirements}</p>
|
|
|
</div>
|
|
|
</div>
|
|
|
- ))}
|
|
|
|
|
|
- {/* 分页器 */}
|
|
|
- <div className="flex justify-center py-6">
|
|
|
- <Pagination
|
|
|
- current={pageNum}
|
|
|
- pageSize={pageSize}
|
|
|
- total={data?.total || 0}
|
|
|
- onChange={(page) => setPageNum(page)}
|
|
|
- showSizeChanger={false}
|
|
|
- />
|
|
|
+ {/* 右侧按钮 */}
|
|
|
+ {/* <CHANGE> 按钮区域响应式调整,移动端居中,桌面端右对齐 */}
|
|
|
+ <div className="flex justify-center sm:justify-center sm:items-center">
|
|
|
+ <Link href={`/about/recruitList/${item.id}`}>
|
|
|
+ <button
|
|
|
+ className="cursor-pointer mt-2 sm:mt-4 lg:mt-20 w-32 sm:w-40 bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 sm:py-3 px-4 sm:px-6 rounded-full transition duration-300 ease-in-out transform hover:scale-105 text-sm sm:text-base">
|
|
|
+ 了解详情 >>
|
|
|
+ </button>
|
|
|
+ </Link>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- </>
|
|
|
- )}
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+
|
|
|
+ {/* 分页器 */}
|
|
|
+ <div className="flex justify-center py-4 sm:py-6">
|
|
|
+ <PaginationClient current={pageNum} total={data?.total || 0} pageSize={pageSize}/>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- );
|
|
|
-}
|
|
|
+ )
|
|
|
+}
|