Files
happy-life-star/mini-program/src/services/lifeEvent.js
T
peanut dd11cfae73 feat: 人生事件和剧本收藏从 localStorage 切换为真实 API
- 后端:新增 t_event_favorite 表(UNIQUE KEY + MyBatis-Plus Entity)
- 后端:LifeEventController 新增 /favorite/toggle、/favorite/page、/favorite/check 三个真实端点
- 后端:EventFavoriteService 完整 CRUD,含 toggle/分页/批量查询/状态检查
- 后端:删除旧的 favorite-placeholder mock 端点
- 前端:life-event/detail.vue 从 localStorage 假收藏切换为真实 API + localStorage 缓存防闪烁
- 前端:ScriptLibraryView.vue 从 localFavorites 切换为 checkFavoriteScript 真实 API
- 前端:stores/app.js 新增 toggleEventFavorite / checkEventFavorite 方法
- 修复:审核发现的 UNIQUE 约束缺失、未使用 watch 导入、Controller 参数注解遗漏、Controller 委托 Service 构造 Response

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-19 23:23:40 +08:00

181 lines
4.2 KiB
JavaScript

/**
* 生命事件服务
* 处理生命事件的增删改查
*/
import { get, post, put, del } from './request.js'
import { streamAiScene } from './aiRuntime.js'
export const getEventList = async () => {
const response = await get('/lifeEvent/list')
return response
}
export const getEventPage = async ({ pageNum = 1, pageSize = 10 }) => {
const response = await get('/lifeEvent/page', { pageNum, pageSize })
return response
}
export const getEventById = async (id) => {
const response = await get('/lifeEvent/detail', { id })
return response
}
export const createEvent = async (eventData) => {
const requestData = transformToBackendFormat(eventData)
const response = await post('/lifeEvent/create', requestData)
return response
}
export const updateEvent = async (eventData) => {
const requestData = transformToBackendFormat(eventData)
const response = await put('/lifeEvent/update', requestData)
return response
}
export const deleteEvent = async (id) => {
const response = await del('/lifeEvent/delete', { id })
return response
}
export const assistEventWriting = async (eventData = {}, callbacks = {}) => {
const result = await streamAiScene({
sceneCode: 'life_healing',
inputs: {
mode: 'life_event_assist',
prompt: `请帮我优化这段人生事件记录,保留真实细节,让表达更清晰温柔。\n标题:${eventData.title || ''}\n时间:${eventData.time || eventData.eventDateText || ''}\n内容:${eventData.content || ''}`,
...eventData
},
...callbacks
})
return {
data: {
content: result.output,
tags: eventData.tags || []
}
}
}
export const chatAboutEvent = async (eventData = {}) => {
return post('/lifeEvent/chat-placeholder', eventData)
}
export const shareEvent = async (eventData = {}) => {
return post('/lifeEvent/share-placeholder', eventData)
}
/**
* 切换人生事件收藏状态(收藏/取消收藏)
* @param {string} eventId 事件ID
* @returns {Promise<{success: boolean, isFavorited: boolean}>}
*/
export const toggleFavoriteEvent = async (eventId) => {
const res = await post('/lifeEvent/favorite/toggle', { eventId })
return {
success: true,
isFavorited: res.data?.isFavorited ?? false,
favoriteTime: res.data?.favoriteTime ?? null
}
}
/**
* 检查人生事件是否已收藏
* @param {string} eventId 事件ID
* @returns {Promise<boolean>}
*/
export const checkFavoriteEvent = async (eventId) => {
const res = await get('/lifeEvent/favorite/check', { eventId })
return res.data?.isFavorited ?? false
}
const transformToBackendFormat = (frontendData) => {
const {
id,
title,
time,
timeMode = 'date',
eventDateText,
endTime,
content,
aiFeedback,
eventType = 'daily_log',
emotionType,
emotionScore,
tags
} = frontendData
return {
id,
title,
eventDate: time,
timeMode,
eventDateText: eventDateText || time,
eventEndDate: timeMode === 'range' ? endTime : null,
content,
aiReply: aiFeedback,
eventType,
emotionType,
emotionScore,
tags
}
}
export const transformToFrontendFormat = (backendData) => {
if (!backendData) return null
const {
id,
userId,
title,
eventDate,
timeMode,
eventDateText,
eventEndDate,
content,
aiReply,
eventType,
emotionType,
emotionScore,
tags,
createTime
} = backendData
return {
id,
userId,
title: title || '',
time: eventDate ? eventDate.split('T')[0] : '',
timeMode: timeMode || 'date',
eventDateText: eventDateText || (eventDate ? eventDate.split('T')[0] : ''),
endTime: eventEndDate ? eventEndDate.split('T')[0] : '',
content: content || '',
aiFeedback: aiReply || '',
eventType: eventType || 'daily_log',
emotionType,
emotionScore,
tags: tags || [],
createTime
}
}
export const transformListToFrontend = (backendList) => {
if (!Array.isArray(backendList)) return []
return backendList.map(transformToFrontendFormat)
}
export default {
getEventList,
getEventPage,
getEventById,
createEvent,
updateEvent,
deleteEvent,
assistEventWriting,
chatAboutEvent,
shareEvent,
toggleFavoriteEvent,
checkFavoriteEvent,
transformToFrontendFormat,
transformListToFrontend
}