Files

179 lines
4.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 || '普通'
)
}