feat: 管理端查看户外招聘会小程序码
Some checks failed
Node CI / build (14.x, macOS-latest) (push) Has been cancelled
Node CI / build (14.x, ubuntu-latest) (push) Has been cancelled
Node CI / build (14.x, windows-latest) (push) Has been cancelled
Node CI / build (16.x, macOS-latest) (push) Has been cancelled
Node CI / build (16.x, ubuntu-latest) (push) Has been cancelled
Node CI / build (16.x, windows-latest) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
coverage CI / build (push) Has been cancelled
Node pnpm CI / build (16.x, macOS-latest) (push) Has been cancelled
Node pnpm CI / build (16.x, ubuntu-latest) (push) Has been cancelled
Node pnpm CI / build (16.x, windows-latest) (push) Has been cancelled

This commit is contained in:
2026-07-23 15:57:47 +08:00
parent 95c31a359a
commit b937b189c2
2 changed files with 110 additions and 3 deletions

View File

@@ -18,6 +18,7 @@ import {
addOutdoorFairDictOption,
signupOutdoorFair,
getMyOutdoorFairQrCode,
getOutdoorFairMiniProgramQrCode,
} from '@/services/jobportal/outdoorFair';
import type {
OutdoorFairItem,
@@ -25,6 +26,7 @@ import type {
OutdoorFairForm,
OutdoorFairDictForm,
OutdoorFairCompanyQrCodeInfo,
OutdoorFairMiniProgramQrCodeInfo,
} from '@/services/jobportal/outdoorFair';
import { getParticipatingJobs } from '@/services/jobportal/outdoorFairDetail';
import { getDictSelectOption, getDictValueEnum } from '@/services/system/dict';
@@ -51,6 +53,10 @@ const OutdoorFairList: React.FC = () => {
const [jobEditModalOpen, setJobEditModalOpen] = useState(false);
const [qrModalOpen, setQrModalOpen] = useState(false);
const [qrInfo, setQrInfo] = useState<OutdoorFairCompanyQrCodeInfo | null>(null);
const [miniProgramQrModalOpen, setMiniProgramQrModalOpen] = useState(false);
const [miniProgramQrInfo, setMiniProgramQrInfo] =
useState<OutdoorFairMiniProgramQrCodeInfo | null>(null);
const [miniProgramQrLoadingFairId, setMiniProgramQrLoadingFairId] = useState<number>();
const [rejectReasonModalOpen, setRejectReasonModalOpen] = useState(false);
const [rejectReason, setRejectReason] = useState('');
const [companyDetailFair, setCompanyDetailFair] = useState<OutdoorFairItem | null>(null);
@@ -191,6 +197,23 @@ const OutdoorFairList: React.FC = () => {
}
};
const openMiniProgramQrCode = async (record: OutdoorFairItem) => {
setMiniProgramQrLoadingFairId(record.id);
try {
const res = await getOutdoorFairMiniProgramQrCode(record.id);
if (res.code === 200 && res.data?.imageData) {
setMiniProgramQrInfo(res.data);
setMiniProgramQrModalOpen(true);
} else {
message.error(res.msg || '小程序二维码加载失败');
}
} catch (error) {
message.error('小程序二维码加载失败,请稍后重试');
} finally {
setMiniProgramQrLoadingFairId(undefined);
}
};
const openJobList = (record: OutdoorFairItem) => {
setSelectedFair(record);
setJobListModalOpen(true);
@@ -374,7 +397,7 @@ const OutdoorFairList: React.FC = () => {
{
title: '操作',
valueType: 'option',
width: isEnterprise ? 520 : 160,
width: isEnterprise ? 520 : 260,
fixed: 'right',
render: (_, record) => [
isEnterprise && !record.signedUp ? (
@@ -410,12 +433,22 @@ const OutdoorFairList: React.FC = () => {
</Button>
) : null,
isEnterprise ? (
<Button key="companyDetail" type="link" size="small" onClick={() => openCompanyDetail(record)}>
<Button
key="companyDetail"
type="link"
size="small"
onClick={() => openCompanyDetail(record)}
>
</Button>
) : null,
isEnterprise && record.signedUp && record.reviewStatus === '1' ? (
<Button key="boothMap" type="link" size="small" onClick={() => openCompanyBoothMap(record)}>
<Button
key="boothMap"
type="link"
size="small"
onClick={() => openCompanyBoothMap(record)}
>
</Button>
) : null,
@@ -429,6 +462,17 @@ const OutdoorFairList: React.FC = () => {
>
</Button>,
<Button
key="miniProgramQrCode"
type="link"
size="small"
icon={<QrcodeOutlined />}
loading={miniProgramQrLoadingFairId === record.id}
hidden={isEnterprise || !access.hasPerms('cms:outdoorFair:qrcode')}
onClick={() => openMiniProgramQrCode(record)}
>
</Button>,
<Button
key="edit"
type="link"
@@ -552,6 +596,46 @@ const OutdoorFairList: React.FC = () => {
</div>
)}
</Modal>
<Modal
title="招聘会小程序二维码"
open={miniProgramQrModalOpen}
width={420}
footer={[
<Button
key="close"
type="primary"
onClick={() => {
setMiniProgramQrModalOpen(false);
setMiniProgramQrInfo(null);
}}
>
</Button>,
]}
destroyOnHidden
onCancel={() => {
setMiniProgramQrModalOpen(false);
setMiniProgramQrInfo(null);
}}
>
{miniProgramQrInfo?.imageData && (
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
<img
src={miniProgramQrInfo.imageData}
alt="招聘会小程序二维码"
style={{ width: 260, height: 260, objectFit: 'contain' }}
/>
<Typography.Text strong style={{ marginTop: 16, fontSize: 16 }}>
使
</Typography.Text>
{miniProgramQrInfo.permanent && (
<Typography.Text type="secondary" style={{ marginTop: 8 }}>
</Typography.Text>
)}
</div>
)}
</Modal>
<Modal
title="驳回原因"
open={rejectReasonModalOpen}

View File

@@ -134,6 +134,18 @@ export interface OutdoorFairCompanyQrCodeInfo {
qrCodeContent: string;
}
/** 管理端查看的招聘会微信小程序码。 */
export interface OutdoorFairMiniProgramQrCodeInfo {
fairId: number;
page: string;
scene: string;
imageData: string;
/** getUnlimitedQRCode 生成的小程序码长期有效。 */
permanent: boolean;
/** 小程序码本身是否需要周期轮换。 */
rotationRequired: boolean;
}
/** 企业审核通过后可读取的只读展位图。 */
export interface OutdoorFairCompanyBoothMap {
currentCompanyId: number;
@@ -307,6 +319,17 @@ export async function getMyOutdoorFairQrCode(fairId: number) {
);
}
/**
* 管理员获取招聘会微信小程序码
* GET /api/cms/outdoor-fair/{fairId}/mini-program-qrcode
*/
export async function getOutdoorFairMiniProgramQrCode(fairId: number) {
return request<{ code: number; msg?: string; data: OutdoorFairMiniProgramQrCodeInfo }>(
`${CMS_OUTDOOR_FAIR_BASE}/${fairId}/mini-program-qrcode`,
{ method: 'GET' },
);
}
/**
* 上传户外招聘会照片
* POST /api/common/upload