From 0390807e6aec54c980abb652b49baaa3f0b28b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=AF=E8=BE=89?= Date: Wed, 8 Jul 2026 21:32:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=BF=E7=AD=96=E4=B8=8B=E8=BD=BD=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/proxy.ts | 4 +- src/pages/JobPortal/Policy/index.tsx | 76 ++++++++++++++++++- .../Policy/Mgmt/components/DetailModal.tsx | 1 + .../Policy/Mgmt/components/EditModal.tsx | 25 ++++++ src/pages/Policy/Mgmt/index.tsx | 14 ++++ src/services/cms/policyInfo.ts | 9 +++ src/types/cms/policyInfo.d.ts | 2 + 7 files changed, 127 insertions(+), 4 deletions(-) diff --git a/config/proxy.ts b/config/proxy.ts index e7ab963..d897363 100644 --- a/config/proxy.ts +++ b/config/proxy.ts @@ -17,8 +17,8 @@ export default { // localhost:8000/api/** -> https://preview.pro.ant.design/api/** '/api/': { // 要代理的地址 - target: localBackendUrl, - // target: 'http://39.98.44.136:6024/api/shihezi/', // 线上环境 + // target: localBackendUrl, // 本地环境 + target: 'http://39.98.44.136:6024/api/shihezi/', // 线上环境 // target: 'http://wykj.cdwsx.com/api',// 后端 // target: 'http://ks.zhaopinzao8dian.com/api/ks', // 配置了这个可以从 http 代理到 https diff --git a/src/pages/JobPortal/Policy/index.tsx b/src/pages/JobPortal/Policy/index.tsx index 5aa7cb2..a2997c4 100644 --- a/src/pages/JobPortal/Policy/index.tsx +++ b/src/pages/JobPortal/Policy/index.tsx @@ -18,7 +18,7 @@ import { } from '@ant-design/icons'; import { history } from '@umijs/max'; import JobPortalHeader from '@/components/JobPortalHeader'; -import { getPortalPolicyList } from '@/services/cms/policyInfo'; +import { getPortalPolicyList, exportPolicy } from '@/services/cms/policyInfo'; import { getDictValueEnum } from '@/services/system/dict'; import type { DictValueEnumObj } from '@/components/DictTag'; import './index.less'; @@ -34,7 +34,9 @@ const PolicyListPage: React.FC = () => { const [searchValue, setSearchValue] = useState(''); const [keyword, setKeyword] = useState(''); const [selectedPolicyTag, setSelectedPolicyTag] = useState('__recommended__'); + const [selectedPolicyCategory, setSelectedPolicyCategory] = useState(''); const [userTypeEnum, setUserTypeEnum] = useState({}); + const [policyCategoryEnum, setPolicyCategoryEnum] = useState({}); /** 从 localStorage 读取当前用户的 personnel type */ const currentUserType = (() => { @@ -56,6 +58,9 @@ const PolicyListPage: React.FC = () => { setSelectedPolicyTag(''); } }); + getDictValueEnum('policy_category', false, true).then((data) => { + setPolicyCategoryEnum(data); + }); }, []); /** 将字典枚举转为标签数组,按 value 排序 */ @@ -63,6 +68,11 @@ const PolicyListPage: React.FC = () => { .map((item) => ({ label: item.label, value: item.value })) .sort((a, b) => Number(a.value) - Number(b.value)); + /** 将政策分类字典转为标签数组 */ + const policyCategoryTags = Object.values(policyCategoryEnum) + .map((item) => ({ label: item.label, value: String(item.value) })) + .sort((a, b) => Number(a.value) - Number(b.value)); + /** 将内部标记转为实际 API 参数 */ const resolvePolicyTag = (tag: string): string | undefined => { if (tag === '__recommended__') { @@ -79,6 +89,7 @@ const PolicyListPage: React.FC = () => { pageSize, searchValue: keyword || undefined, policyTag: resolvePolicyTag(selectedPolicyTag), + policyCategory: selectedPolicyCategory || undefined, }); if (response?.code === 200) { setList(response.rows || []); @@ -92,7 +103,7 @@ const PolicyListPage: React.FC = () => { } finally { setLoading(false); } - }, [pageNum, pageSize, keyword, selectedPolicyTag]); + }, [pageNum, pageSize, keyword, selectedPolicyTag, selectedPolicyCategory]); useEffect(() => { fetchList(); @@ -113,6 +124,16 @@ const PolicyListPage: React.FC = () => { } }; + /** 点击政策分类标签:选中/取消选中 */ + const handlePolicyCategoryClick = (tagValue: string) => { + setPageNum(1); + if (selectedPolicyCategory === tagValue) { + setSelectedPolicyCategory(''); + } else { + setSelectedPolicyCategory(tagValue); + } + }; + const handleItemClick = (item: API.PolicyInfo.PolicyInfoItem) => { history.push(`/job-portal/policy/detail?id=${item.id}`); }; @@ -131,6 +152,31 @@ const PolicyListPage: React.FC = () => { document.body.removeChild(link); }; + /** 导出政策 */ + const handleExport = async (e: React.MouseEvent, item: API.PolicyInfo.PolicyInfoItem) => { + e.stopPropagation(); + try { + const blob = await exportPolicy(item.id); + // 如果后端返回 JSON 错误(如 401),blob 可能仍是 JSON 格式 + if (blob.type === 'application/json') { + const text = await blob.text(); + const err = JSON.parse(text); + message.error(err.msg || '导出失败'); + return; + } + const url = window.URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = url; + link.download = `${item.zcmc || '政策'}.docx`; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + window.URL.revokeObjectURL(url); + } catch (err: any) { + message.error(err?.message || '导出失败'); + } + }; + return (
@@ -188,6 +234,24 @@ const PolicyListPage: React.FC = () => {
)} + {policyCategoryTags.length > 0 && ( +
+ 政策分类: +
+ {policyCategoryTags.map((tag) => ( + handlePolicyCategoryClick(tag.value)} + > + {tag.label} + + ))} +
+
+ )} {list.length > 0 ? ( <> { )} + handleExport(e, item)} + > + + 导出 + {item.fileUrl && ( = ({ open, data, onCancel }) => { {data?.zcmc} {data?.zclx} + {data?.policyCategory || '-'} {data?.zcLevel} {data?.sourceUnit} {data?.acceptUnit} diff --git a/src/pages/Policy/Mgmt/components/EditModal.tsx b/src/pages/Policy/Mgmt/components/EditModal.tsx index 38937ca..d5b5f9a 100644 --- a/src/pages/Policy/Mgmt/components/EditModal.tsx +++ b/src/pages/Policy/Mgmt/components/EditModal.tsx @@ -23,11 +23,15 @@ const EditModal: React.FC = ({ open, values, onCancel, onSubmit const [fileList, setFileList] = useState([]); const [uploading, setUploading] = useState(false); const [userTypeEnum, setUserTypeEnum] = useState({}); + const [policyCategoryEnum, setPolicyCategoryEnum] = useState({}); useEffect(() => { getDictValueEnum('user_type', false, true).then((data) => { setUserTypeEnum(data); }); + getDictValueEnum('policy_category', false, true).then((data) => { + setPolicyCategoryEnum(data); + }); }, []); useEffect(() => { @@ -59,6 +63,13 @@ const EditModal: React.FC = ({ open, values, onCancel, onSubmit } }, [open, values, form]); + // 字典选项加载完成后,重新回填 policyCategory 确保 Select 正确显示 + useEffect(() => { + if (open && values?.policyCategory && Object.keys(policyCategoryEnum).length > 0) { + form.setFieldsValue({ policyCategory: values.policyCategory }); + } + }, [open, policyCategoryEnum, values, form]); + const handleUpload = async (file: File) => { setUploading(true); try { @@ -113,6 +124,11 @@ const EditModal: React.FC = ({ open, values, onCancel, onSubmit value: item.value, })); + const policyCategoryOptions = Object.values(policyCategoryEnum).map((item) => ({ + label: item.label, + value: item.value, + })); + return ( = ({ open, values, onCancel, onSubmit + + + { const [currentRow, setCurrentRow] = useState(); const [selectedRowKeys, setSelectedRowKeys] = useState([]); const [userTypeEnum, setUserTypeEnum] = useState({}); + const [policyCategoryEnum, setPolicyCategoryEnum] = useState({}); useEffect(() => { getDictValueEnum('user_type', false, true).then((data) => { setUserTypeEnum(data); }); + getDictValueEnum('policy_category', false, true).then((data) => { + setPolicyCategoryEnum(data); + }); }, []); const handleDelete = async (ids: string) => { @@ -103,6 +107,16 @@ const PolicyMgmt: React.FC = () => { ); }, }, + { + title: '政策分类', + dataIndex: 'policyCategory', + hideInSearch: true, + width: 120, + render: (_, record) => { + if (!record.policyCategory) return '-'; + return ; + }, + }, { title: '发文单位', dataIndex: 'sourceUnit', diff --git a/src/services/cms/policyInfo.ts b/src/services/cms/policyInfo.ts index aef2a9d..afd7d26 100644 --- a/src/services/cms/policyInfo.ts +++ b/src/services/cms/policyInfo.ts @@ -71,3 +71,12 @@ export async function uploadPolicyFile(file: File) { data: formData, }); } + +// 导出/下载政策 +export async function exportPolicy(id: number | string) { + return request('/api/cms/policyInfo/exportUtil', { + method: 'GET', + params: { id }, + responseType: 'blob', + }); +} diff --git a/src/types/cms/policyInfo.d.ts b/src/types/cms/policyInfo.d.ts index 96f2b64..a45da8f 100644 --- a/src/types/cms/policyInfo.d.ts +++ b/src/types/cms/policyInfo.d.ts @@ -25,6 +25,7 @@ declare namespace API.PolicyInfo { export interface PolicyInfoItem { id: number; policyTag?: string; + policyCategory?: string; zcmc: string; zclx: string; zcLevel: string; @@ -51,5 +52,6 @@ declare namespace API.PolicyInfo { pageSize?: number; searchValue?: string; policyTag?: string; + policyCategory?: string; } }