import { request } from '@/api/request.js' import { getBaseURL } from '@/api/config.js' import { getToken } from '@/utils/auth.js' /** * OA 工作日程(日历待办)接口封装,对应后端 /api/oa/schedule/*。 * 数据表 yz_backend_oa_schedule,与「日程提醒」(/api/schedule/*, * yz_backend_schedule)是两个独立功能,不要混用。 */ /** 优先级选项(与 Web 后台一致:0 普通 / 1 重要 / 2 紧急) */ export const OA_SCHEDULE_PRIORITY_OPTIONS = [ { value: 0, label: '普通' }, { value: 1, label: '重要' }, { value: 2, label: '紧急' } ] /** 归一化单条日程:补齐端上排序/分组用的时间戳与派生字段 */ export function normalizeOaSchedule(item) { const date = String(item.schedule_date || '').slice(0, 10) const startTime = item.start_time || '' // 拼一个 Date 时间戳便于日历分组与时间排序(全天事件按 00:00) let timestamp = 0 if (date) { const [y, m, d] = date.split('-').map(Number) const [hh = 0, mm = 0] = startTime ? startTime.split(':').map(Number) : [0, 0] timestamp = new Date(y, m - 1, d, hh, mm).getTime() } return { ...item, schedule_date: date, completed: item.status === 1, allDay: item.all_day === 1, timestamp } } /** * 获取工作日程列表(支持日期区间 / 分类筛选) * 返回 { list, total, counts },counts 为各分类数量角标 */ export async function fetchOaSchedules(params = {}) { const data = await request({ url: '/api/oa/schedule/list', data: { page: params.page || 1, pageSize: params.pageSize || 500, keyword: params.keyword || '', status: params.status || '', priority: params.priority || '', start_date: params.startDate || '', end_date: params.endDate || '', category: params.category || 'all' } }) const list = (data.list || []).map(normalizeOaSchedule) return { list, total: data.total || 0, counts: data.counts || {} } } /** * 获取单条日程详情 */ export async function getOaSchedule(id) { const data = await request({ url: `/api/oa/schedule/detail/${id}` }) if (!data || !data.item) return null return { ...normalizeOaSchedule(data.item), images: data.images || [] } } /** * 新建日程 */ export async function createOaSchedule(payload) { return request({ url: '/api/oa/schedule/create', method: 'POST', data: buildOaSchedulePayload(payload) }) } /** * 更新日程 */ export async function updateOaSchedule(id, payload) { return request({ url: `/api/oa/schedule/update/${id}`, method: 'POST', data: buildOaSchedulePayload(payload) }) } /** * 删除日程(软删除) */ export async function deleteOaSchedule(id) { await request({ url: `/api/oa/schedule/delete/${id}`, method: 'DELETE' }) return true } /** * 切换完成状态(待办 <-> 已完成) */ export async function toggleOaScheduleComplete(id) { const res = await request({ url: `/api/oa/schedule/finish/${id}`, method: 'POST' }) return { status: res?.status ?? 0, completed: res?.status === 1 } } /** * 上传日程资料图片(multipart,单张 ≤10MB) * 文件落入租户文件管理,返回 { id, url, name } 引用信息 */ export function uploadOaScheduleImage(filePath) { return new Promise((resolve, reject) => { uni.uploadFile({ url: `${getBaseURL().replace(/\/$/, '')}/api/oa/schedule/upload`, filePath, name: 'file', header: { Authorization: `Bearer ${getToken()}` }, success(res) { let body = {} try { body = JSON.parse(res.data || '{}') } catch (e) { // 非 JSON 响应按失败处理 } if (res.statusCode >= 200 && res.statusCode < 300 && body.code === 200 && body.data) { resolve(body.data) } else { const msg = body.msg || `上传失败(${res.statusCode})` uni.showToast({ title: msg, icon: 'none' }) reject(new Error(msg)) } }, fail(err) { uni.showToast({ title: '网络异常,上传失败', icon: 'none' }) reject(err) } }) }) } /** * 保存日程资料图片引用列表(整体覆盖) */ export async function setOaScheduleImages(id, images) { const res = await request({ url: `/api/oa/schedule/images/${id}`, method: 'POST', data: { images: (images || []).map(img => ({ id: Number(img.id) || 0, url: img.url, name: img.name || '' })) } }) return res?.images || [] } /** 组装后端要求的请求体(提醒绑定暂不在小程序端开放) */ function buildOaSchedulePayload(p) { return { title: p.title, content: p.content || '', schedule_date: p.scheduleDate, start_time: p.allDay ? '' : p.startTime || '', end_time: p.allDay ? '' : p.endTime || '', all_day: p.allDay ? 1 : 0, priority: p.priority || 0, color: p.color || '#409EFF', reminder_enabled: false } } export function getOaPriorityLabel(priority) { return ( OA_SCHEDULE_PRIORITY_OPTIONS.find(item => item.value === Number(priority))?.label || '普通' ) }