292 lines
7.1 KiB
JavaScript
292 lines
7.1 KiB
JavaScript
import { defineStore } from 'pinia'
|
||
import * as api from '@/api'
|
||
|
||
export const useLogsStore = defineStore('logs', {
|
||
state: () => ({
|
||
logs: [], // 记录列表
|
||
total: 0, // 总条数
|
||
page: 1, // 当前页
|
||
pageSize: 20, // 每页数量
|
||
hasMore: true, // 是否有更多
|
||
loading: false, // 加载状态
|
||
refreshing: false, // 刷新状态
|
||
queryType: 'all' // 当前筛选类型
|
||
}),
|
||
|
||
getters: {
|
||
// 按日期分组
|
||
groupedByDate: (state) => {
|
||
const groups = {}
|
||
state.logs.forEach(log => {
|
||
const date = log.smoke_time?.split('T')[0] || ''
|
||
if (!groups[date]) {
|
||
groups[date] = []
|
||
}
|
||
groups[date].push(log)
|
||
})
|
||
return groups
|
||
},
|
||
|
||
// 抽烟记录数量
|
||
smokeCount: (state) => {
|
||
return state.logs.filter(log => normalizeLogType(log) === 'smoke').length
|
||
},
|
||
|
||
// 忍住记录数量
|
||
resistedCount: (state) => {
|
||
return state.logs.filter(log => normalizeLogType(log) === 'resisted').length
|
||
},
|
||
|
||
// 格式化记录列表(按时间倒序,最新的在前)
|
||
formattedLogs: (state) => {
|
||
if (!state.logs || state.logs.length === 0) {
|
||
return []
|
||
}
|
||
|
||
// 获取时间戳的辅助函数
|
||
const getTime = (log) => {
|
||
if (log.smoke_at) {
|
||
return new Date(log.smoke_at).getTime()
|
||
}
|
||
if (log.smoke_time) {
|
||
return new Date(log.smoke_time).getTime()
|
||
}
|
||
if (log.createtime) {
|
||
return typeof log.createtime === 'number' ? log.createtime * 1000 : new Date(log.createtime).getTime()
|
||
}
|
||
return 0
|
||
}
|
||
|
||
// 先按时间倒序排序
|
||
const sortedLogs = [...state.logs].sort((a, b) => {
|
||
const timeA = getTime(a)
|
||
const timeB = getTime(b)
|
||
return timeB - timeA // 倒序:最新的在前
|
||
})
|
||
|
||
return sortedLogs.map((log, index) => {
|
||
const type = normalizeLogType(log)
|
||
|
||
// 计算间隔时间:当前记录与上一条记录的间隔(上一条是 index-1,因为已倒序)
|
||
let interval = ''
|
||
if (index > 0) {
|
||
const currentTime = getTime(log)
|
||
const prevTime = getTime(sortedLogs[index - 1])
|
||
const diff = prevTime - currentTime // 上一条时间 - 当前时间(因为已倒序)
|
||
|
||
if (diff > 0) {
|
||
const hours = Math.floor(diff / (1000 * 60 * 60))
|
||
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60))
|
||
|
||
if (hours > 0) {
|
||
interval = `${hours}小时${minutes}分`
|
||
} else if (minutes > 0) {
|
||
interval = `${minutes}分钟`
|
||
} else {
|
||
interval = '刚刚'
|
||
}
|
||
}
|
||
}
|
||
|
||
// 获取显示日期
|
||
let displayDate = ''
|
||
if (log.smoke_time) {
|
||
displayDate = log.smoke_time.split('T')[0]
|
||
} else if (log.createtime) {
|
||
const date = typeof log.createtime === 'number'
|
||
? new Date(log.createtime * 1000)
|
||
: new Date(log.createtime)
|
||
displayDate = date.toISOString().split('T')[0]
|
||
}
|
||
|
||
return {
|
||
...log,
|
||
type,
|
||
interval,
|
||
displayTime: formatLogTime(log.smoke_at || log.smoke_time || log.createtime),
|
||
displayDate
|
||
}
|
||
})
|
||
}
|
||
},
|
||
|
||
actions: {
|
||
// 获取记录列表
|
||
async fetchLogs(refresh = false, type) {
|
||
if (this.loading) return
|
||
|
||
this.loading = true
|
||
if (refresh) {
|
||
this.refreshing = true
|
||
this.page = 1
|
||
this.logs = []
|
||
this.queryType = type || 'all'
|
||
}
|
||
|
||
try {
|
||
const res = await api.getLogs({
|
||
page: this.page,
|
||
page_size: this.pageSize,
|
||
type: this.queryType
|
||
})
|
||
|
||
if (res.data) {
|
||
let newLogs = res.data.items || []
|
||
|
||
// 按时间倒序排序(最新的在前)
|
||
newLogs = newLogs.sort((a, b) => {
|
||
const timeA = new Date(a.smoke_at || a.smoke_time || (a.createtime ? a.createtime * 1000 : 0)).getTime()
|
||
const timeB = new Date(b.smoke_at || b.smoke_time || (b.createtime ? b.createtime * 1000 : 0)).getTime()
|
||
return timeB - timeA
|
||
})
|
||
|
||
if (refresh) {
|
||
this.logs = newLogs
|
||
} else {
|
||
// 合并并去重(按 id)
|
||
const existingIds = new Set(this.logs.map(log => log.id))
|
||
const uniqueNewLogs = newLogs.filter(log => !existingIds.has(log.id))
|
||
this.logs = [...this.logs, ...uniqueNewLogs]
|
||
// 再次排序确保顺序
|
||
this.logs.sort((a, b) => {
|
||
const timeA = new Date(a.smoke_at || a.smoke_time || (a.createtime ? a.createtime * 1000 : 0)).getTime()
|
||
const timeB = new Date(b.smoke_at || b.smoke_time || (b.createtime ? b.createtime * 1000 : 0)).getTime()
|
||
return timeB - timeA
|
||
})
|
||
}
|
||
|
||
this.total = res.data.total || 0
|
||
this.hasMore = newLogs.length >= this.pageSize
|
||
}
|
||
} catch (e) {
|
||
console.error('fetchLogs error:', e)
|
||
uni.showToast({
|
||
title: '加载失败',
|
||
icon: 'none'
|
||
})
|
||
} finally {
|
||
this.loading = false
|
||
this.refreshing = false
|
||
}
|
||
},
|
||
|
||
// 加载更多
|
||
async loadMore() {
|
||
if (!this.hasMore || this.loading) return
|
||
|
||
this.page++
|
||
await this.fetchLogs(false)
|
||
},
|
||
|
||
// 删除记录
|
||
async deleteLog(id) {
|
||
try {
|
||
await api.deleteLog(id)
|
||
|
||
// 乐观更新:先从列表中移除
|
||
const index = this.logs.findIndex(log => log.id === id)
|
||
if (index > -1) {
|
||
this.logs.splice(index, 1)
|
||
this.total--
|
||
}
|
||
|
||
uni.showToast({
|
||
title: '删除成功',
|
||
icon: 'success'
|
||
})
|
||
|
||
return true
|
||
} catch (e) {
|
||
console.error('deleteLog error:', e)
|
||
uni.showToast({
|
||
title: '删除失败',
|
||
icon: 'none'
|
||
})
|
||
|
||
// 失败时刷新列表恢复数据
|
||
await this.fetchLogs(true)
|
||
return false
|
||
}
|
||
},
|
||
|
||
// 更新记录
|
||
async updateLog(id, data) {
|
||
try {
|
||
await api.updateLog(id, data)
|
||
|
||
// 更新本地数据
|
||
const index = this.logs.findIndex(log => log.id === id)
|
||
if (index > -1) {
|
||
this.logs[index] = {
|
||
...this.logs[index],
|
||
...data
|
||
}
|
||
}
|
||
|
||
uni.showToast({
|
||
title: '更新成功',
|
||
icon: 'success'
|
||
})
|
||
|
||
return true
|
||
} catch (e) {
|
||
console.error('updateLog error:', e)
|
||
uni.showToast({
|
||
title: '更新失败',
|
||
icon: 'none'
|
||
})
|
||
return false
|
||
}
|
||
},
|
||
|
||
// 清空列表
|
||
clearLogs() {
|
||
this.logs = []
|
||
this.total = 0
|
||
this.page = 1
|
||
this.hasMore = true
|
||
this.queryType = 'all'
|
||
}
|
||
}
|
||
})
|
||
|
||
// 辅助函数:格式化时间
|
||
function formatLogTime(timeStr) {
|
||
if (!timeStr) return '--:--'
|
||
|
||
let date
|
||
if (typeof timeStr === 'number') {
|
||
// 如果是时间戳(秒)
|
||
date = new Date(timeStr * 1000)
|
||
} else if (typeof timeStr === 'string') {
|
||
// 如果是字符串
|
||
date = new Date(timeStr)
|
||
} else {
|
||
return '--:--'
|
||
}
|
||
|
||
// 检查日期是否有效
|
||
if (isNaN(date.getTime())) {
|
||
return '--:--'
|
||
}
|
||
|
||
const hours = String(date.getHours()).padStart(2, '0')
|
||
const minutes = String(date.getMinutes()).padStart(2, '0')
|
||
return `${hours}:${minutes}`
|
||
}
|
||
|
||
function normalizeLogType(log) {
|
||
const rawType = log?.type
|
||
if (typeof rawType === 'string') {
|
||
const value = rawType.toLowerCase()
|
||
if (value === 'resisted' || value === 'resist') return 'resisted'
|
||
if (value === 'smoke' || value === 'log_smoke') return 'smoke'
|
||
}
|
||
if (typeof rawType === 'number') {
|
||
if (rawType === 0) return 'resisted'
|
||
if (rawType === 1) return 'smoke'
|
||
}
|
||
if (log?.num === 0) return 'resisted'
|
||
return 'smoke'
|
||
}
|