// 公开门户 API import request from '@/utils/request' // 首页:项目公示 + 公示公告 + 资源 export const getPublicIndex = () => request.get('/business/public/index') // 项目公示分页 export const listPublicProjects = (params) => request.get('/business/public/announcements', { params }) // 公示详情 export const getPublicAnnouncement = (annId) => request.get(`/business/public/announcement/${annId}`) // 支持函详情 export const getPublicSupportLetter = (annId) => request.get(`/business/public/supportLetter/${annId}`) // 邀请函详情(参会邀请) export const getPublicInvitation = (annId) => request.get(`/business/public/invitation/${annId}`) // 业务字典 export const getDictTypes = () => request.get('/business/dict/types') export const getDictData = (dictType) => request.get('/business/dict/data', { params: { dictType } }) // 业务认证 export const bizLogin = (data) => request.post('/business/auth/login', data) export const registerExpert = (data) => request.post('/business/auth/registerExpert', data) export const registerExecutor = (data) => request.post('/business/auth/registerExecutor', data) export const registerSponsor = (data) => request.post('/business/auth/registerSponsor', data) // 业务 CRUD(generic) // announcement 后端接口未实现, 已改为调 RuoYi 系统通知接口 /system/notice/list const STUB_ENTITIES = new Set(['announcement']) export const bizList = (entity, params) => { if (STUB_ENTITIES.has(entity)) { return Promise.resolve({ code: 200, msg: 'ok', data: { rows: [], total: 0 } }) } return request.get(`/business/${entity}/list`, { params }) } // 系统通知(RuoYi sys_notice 表) // 返回 {id, title, category, text, time, read, type, content} export const listNotices = async (params = { pageNum: 1, pageSize: 5 }) => { const { data } = await request.get('/system/notice/list', { params }) const rows = data?.rows || [] return rows.map(n => { // notice_content 是 longblob HTML, 提取纯文本 const html = String(n.noticeContent || '') const text = html.replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ').trim().slice(0, 200) return { id: n.noticeId, title: n.noticeTitle, category: n.noticeType === '2' ? '公告' : '通知', text: text || (n.remark || '请查看通知内容'), time: n.createTime ? new Date(n.createTime.replace(/-/g, '/')).toLocaleString('zh-CN') : '', read: !!n.isRead, type: n.noticeType, content: html, } }) } // 个人通知 (biz_message 表) — 给当前用户发 // 返回 {rows: [{id, title, text, time, read, type, content, bizType, bizId}], unread, total} const MSG_TYPE_LABEL = { '1': '通知', '2': '待办', '3': '系统' } export const listMyMessages = async (params = { limit: 5 }) => { const { data } = await request.get('/business/message/my', { params }) const rows = data?.rows || [] return { rows: rows.map(m => ({ id: m.msgId, title: m.title, category: MSG_TYPE_LABEL[m.msgType] || '通知', text: String(m.content || '').replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ').trim().slice(0, 200), time: m.createTime ? new Date(m.createTime.replace(/-/g, '/')).toLocaleString('zh-CN') : '', read: m.isRead === '1', type: m.msgType, content: m.content, bizType: m.bizType, bizId: m.bizId, })), unread: data?.unread || 0, total: data?.total || 0, } } // 标记单条已读 export const markMessageRead = (msgId) => request.put(`/business/message/read/${msgId}`) // 全部标记已读 export const markAllMessagesRead = () => request.put('/business/message/readAll') export const bizGet = (entity, id) => request.get(`/business/${entity}/${id}`) // opts 透传给 request (例如 { __silentError: true } 让拦截器不自动 toast, 由调用方控制) export const bizAdd = (entity, data, opts) => request.post(`/business/${entity}`, data, opts) export const bizUpdate = (entity, data, opts) => request.put(`/business/${entity}`, data, opts) export const bizDelete = (entity, ids) => request.delete(`/business/${entity}/${ids}`) // 人员批量导入 (unitType: 'sponsor' | 'executor') export const importPerson = (unitType, file) => { const form = new FormData() form.append('file', file) return request.post(`/business/person/${unitType}Import`, form, { headers: { 'Content-Type': 'multipart/form-data' } }) } // 人员导入模板下载 export const downloadImportTemplate = (unitType) => request.get(`/business/person/${unitType}ImportTemplate`, { responseType: 'blob' }) // 专家导入模板下载 export const downloadExpertTemplate = () => request.get('/business/expert/importTemplate', { responseType: 'blob' })