|
@@ -0,0 +1,122 @@
|
|
|
|
|
+import {serverGet, serverPost} from "@/utils/request"
|
|
|
|
|
+import {DollarSign, MapPin, Phone, Tag, User, Users} from "lucide-react"
|
|
|
|
|
+import Link from "next/link"
|
|
|
|
|
+import {Breadcrumb} from "antd";
|
|
|
|
|
+
|
|
|
|
|
+export const dynamicParams = true
|
|
|
|
|
+
|
|
|
|
|
+export async function generateStaticParams() {
|
|
|
|
|
+ const res = await serverPost<Page<RecruitmentInfo>, { pageNum: number; pageSize: number }>(
|
|
|
|
|
+ "webSite/getRecruitmentInfoByPage",
|
|
|
|
|
+ { pageNum: 1, pageSize: 20 }
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ return res.data.records.map((item) => ({
|
|
|
|
|
+ id: item.id,
|
|
|
|
|
+ }))
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export default async function RecruitmentDetailPage({
|
|
|
|
|
+ params,
|
|
|
|
|
+ }: {
|
|
|
|
|
+ params: Promise<{ id: string }>
|
|
|
|
|
+}) {
|
|
|
|
|
+ const { id } = await params
|
|
|
|
|
+ const detail = await serverGet<RecruitmentInfo, { id: string }>(
|
|
|
|
|
+ "webSite/getRecruitmentInfoById",
|
|
|
|
|
+ { id }
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ if (!detail) {
|
|
|
|
|
+ return (
|
|
|
|
|
+ <div className="w-4/5 mx-auto py-20 text-center text-gray-500">
|
|
|
|
|
+ 暂无该岗位信息
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return (
|
|
|
|
|
+
|
|
|
|
|
+ <>
|
|
|
|
|
+ <div className="w-4/5 mx-auto">
|
|
|
|
|
+ <div className="pt-10 ml-20 flex gap-2">
|
|
|
|
|
+ <span className="text-sm">您当前的所在位置:</span>
|
|
|
|
|
+ <Breadcrumb
|
|
|
|
|
+ separator=">"
|
|
|
|
|
+ items={[
|
|
|
|
|
+ {title: "关于我们", href: "/about"},
|
|
|
|
|
+ {title: "招聘列表", href: "/about/recruitList"},
|
|
|
|
|
+ {title: detail.data.jobOpenings},
|
|
|
|
|
+ ]}
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className="w-11/12 lg:w-4/5 mx-auto py-12">
|
|
|
|
|
+ {/* 卡片 */}
|
|
|
|
|
+ <div className="bg-white shadow-2xl rounded-2xl p-6 sm:p-10 relative overflow-hidden">
|
|
|
|
|
+ {/* 蓝色渐变背景 */}
|
|
|
|
|
+ <div
|
|
|
|
|
+ className="absolute inset-0 bg-gradient-to-r from-blue-100 via-blue-200 to-blue-300 opacity-50 rounded-2xl -z-10"></div>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 标题 */}
|
|
|
|
|
+ <h1
|
|
|
|
|
+ className="text-2xl sm:text-4xl font-extrabold mb-8 bg-gradient-to-r from-blue-600 to-blue-800 bg-clip-text text-transparent">
|
|
|
|
|
+ {detail.data.jobOpenings}
|
|
|
|
|
+ </h1>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 信息列表 */}
|
|
|
|
|
+ <div className="grid gap-5 sm:grid-cols-2">
|
|
|
|
|
+ <InfoItem icon={<MapPin className="w-5 h-5 text-blue-600"/>} label="工作地址"
|
|
|
|
|
+ value={detail.data.workLocation}/>
|
|
|
|
|
+ <InfoItem icon={<Users className="w-5 h-5 text-blue-600"/>} label="招聘人数"
|
|
|
|
|
+ value={detail.data.numberRecruits}/>
|
|
|
|
|
+ <InfoItem icon={<DollarSign className="w-5 h-5 text-blue-600"/>} label="薪资" value={detail.data.salary}/>
|
|
|
|
|
+ <InfoItem icon={<User className="w-5 h-5 text-blue-600"/>} label="联系人" value={detail.data.contact}/>
|
|
|
|
|
+ <InfoItem icon={<Phone className="w-5 h-5 text-blue-600"/>} label="联系方式"
|
|
|
|
|
+ value={detail.data.contactInformation}/>
|
|
|
|
|
+ {detail.data.keyTerms && (
|
|
|
|
|
+ <InfoItem icon={<Tag className="w-5 h-5 text-blue-600"/>} label="关键词" value={detail.data.keyTerms}/>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 岗位描述 */}
|
|
|
|
|
+ <div className="mt-10">
|
|
|
|
|
+ <h2 className="text-xl sm:text-2xl font-semibold mb-4 text-gray-800">岗位要求</h2>
|
|
|
|
|
+ <p className="leading-relaxed text-gray-700 text-sm sm:text-base">{detail.data.jobRequirements}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 备注:独立框,空时不渲染 */}
|
|
|
|
|
+ {detail.data.remarks?.trim() && (
|
|
|
|
|
+ <div
|
|
|
|
|
+ className="mt-8 bg-blue-50 border border-blue-200 rounded-xl p-4 sm:p-6 min-h-[100px] flex items-center">
|
|
|
|
|
+ <p className="text-gray-700 text-sm sm:text-base">{detail.data.remarks}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )}
|
|
|
|
|
+
|
|
|
|
|
+ {/* 返回按钮 */}
|
|
|
|
|
+ <div className="mt-10 text-center">
|
|
|
|
|
+ <Link
|
|
|
|
|
+ href="/about/recruitList"
|
|
|
|
|
+ className="inline-block px-6 py-3 bg-gradient-to-r from-blue-500 to-blue-700 text-white rounded-full shadow-lg hover:scale-105 transition-transform text-sm sm:text-base"
|
|
|
|
|
+ >
|
|
|
|
|
+ 返回招聘列表
|
|
|
|
|
+ </Link>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </>
|
|
|
|
|
+ )
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 信息展示子组件
|
|
|
|
|
+function InfoItem({icon, label, value}: { icon: React.ReactNode; label: string; value: any }) {
|
|
|
|
|
+ return (
|
|
|
|
|
+ <div className="flex items-center space-x-3 bg-gray-50 rounded-xl p-3 sm:p-4 shadow-sm hover:shadow-md transition">
|
|
|
|
|
+ {icon}
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <p className="text-xs sm:text-sm text-gray-500">{label}</p>
|
|
|
|
|
+ <p className="text-sm sm:text-base font-medium text-gray-800 break-words">{value}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )
|
|
|
|
|
+}
|