254 lines
7.1 KiB
JavaScript
254 lines
7.1 KiB
JavaScript
const api = require('../../utils/api')
|
|
|
|
const PAGE_SIZE = 10
|
|
let usageStatsLoadSeq = 0
|
|
let keywordSearchTimer = null
|
|
|
|
const pad2 = value => String(value).padStart(2, '0')
|
|
|
|
const formatDate = date => `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}`
|
|
|
|
const defaultDateRange = () => {
|
|
const today = new Date()
|
|
return {
|
|
startDate: `${today.getFullYear()}-${pad2(today.getMonth() + 1)}-01`,
|
|
endDate: formatDate(today),
|
|
}
|
|
}
|
|
|
|
const metricLabel = metricKind => (metricKind === 'quantity' ? '数量' : '时长')
|
|
|
|
const valueLabel = row => {
|
|
if (row.metricKind === 'quantity') {
|
|
return `${Number(row.value || 0)} 件`
|
|
}
|
|
return api.formatDurationAllUnits(row.value)
|
|
}
|
|
|
|
const openDocumentFile = filePath => new Promise((resolve, reject) => {
|
|
wx.openDocument({
|
|
filePath,
|
|
fileType: 'xlsx',
|
|
showMenu: true,
|
|
success: resolve,
|
|
fail: () => reject(new Error('打开文件失败')),
|
|
})
|
|
})
|
|
|
|
Page({
|
|
data: {
|
|
...defaultDateRange(),
|
|
category: 'device',
|
|
sortBy: 'value',
|
|
attendancePoints: [],
|
|
attendancePointLabels: ['全部考勤点'],
|
|
attendancePointIndex: 0,
|
|
attendancePointName: '',
|
|
keyword: '',
|
|
rows: [],
|
|
page: 1,
|
|
pageInput: '1',
|
|
totalPages: 1,
|
|
loading: false,
|
|
exporting: false,
|
|
refreshing: false,
|
|
scrollTop: 0,
|
|
},
|
|
onLoad() {
|
|
this.init()
|
|
},
|
|
onUnload() {
|
|
if (keywordSearchTimer) {
|
|
clearTimeout(keywordSearchTimer)
|
|
keywordSearchTimer = null
|
|
}
|
|
},
|
|
async init() {
|
|
await this.loadAttendancePoints()
|
|
await this.load(1)
|
|
},
|
|
async loadAttendancePoints() {
|
|
try {
|
|
const points = await api.listAccessibleAttendancePoints()
|
|
const attendancePoints = points || []
|
|
this.setData({
|
|
attendancePoints,
|
|
attendancePointLabels: ['全部考勤点'].concat(attendancePoints.map(item => item.name)),
|
|
})
|
|
} catch (error) {
|
|
wx.showToast({ title: error.message || '加载考勤点失败', icon: 'none' })
|
|
}
|
|
},
|
|
async load(page = this.data.page) {
|
|
const loadSeq = usageStatsLoadSeq + 1
|
|
usageStatsLoadSeq = loadSeq
|
|
this.setData({ loading: true })
|
|
try {
|
|
const result = await api.listUsageStats({
|
|
category: this.data.category,
|
|
sortBy: this.data.sortBy,
|
|
startDate: this.data.startDate,
|
|
endDate: this.data.endDate,
|
|
attendancePointName: this.data.attendancePointName,
|
|
keyword: this.data.keyword,
|
|
page,
|
|
pageSize: PAGE_SIZE,
|
|
})
|
|
if (loadSeq !== usageStatsLoadSeq) {
|
|
return
|
|
}
|
|
const rows = result.rows || []
|
|
const maxValue = Math.max(1, ...rows.map(item => Number(item.value || 0)))
|
|
this.setData({
|
|
rows: rows.map(item => ({
|
|
...item,
|
|
metricLabel: metricLabel(item.metricKind),
|
|
valueText: valueLabel(item),
|
|
barPercent: Math.max(4, Math.round(Number(item.value || 0) / maxValue * 100)),
|
|
uniqueKey: `${item.category || ''}-${item.id || ''}-${item.metricKind || ''}-${item.name || ''}`,
|
|
})),
|
|
page: result.page || 1,
|
|
pageInput: String(result.page || 1),
|
|
totalPages: result.totalPages || 1,
|
|
scrollTop: 0,
|
|
})
|
|
} catch (error) {
|
|
if (loadSeq === usageStatsLoadSeq) {
|
|
wx.showToast({ title: error.message || '加载统计失败', icon: 'none' })
|
|
}
|
|
} finally {
|
|
if (loadSeq === usageStatsLoadSeq) {
|
|
this.setData({ loading: false })
|
|
}
|
|
}
|
|
},
|
|
async onPullDownRefresh() {
|
|
this.setData({ refreshing: true })
|
|
try {
|
|
await this.load(1)
|
|
} finally {
|
|
this.setData({ refreshing: false })
|
|
if (wx.stopPullDownRefresh) {
|
|
wx.stopPullDownRefresh()
|
|
}
|
|
}
|
|
},
|
|
chooseCategory(e) {
|
|
const category = e.currentTarget.dataset.category
|
|
if (category === this.data.category) {
|
|
return
|
|
}
|
|
this.setData({ category, page: 1 })
|
|
this.load(1)
|
|
},
|
|
chooseSort(e) {
|
|
const sortBy = e.currentTarget.dataset.sort
|
|
if (sortBy === this.data.sortBy) {
|
|
return
|
|
}
|
|
this.setData({ sortBy, page: 1 })
|
|
this.load(1)
|
|
},
|
|
onStartChange(e) {
|
|
this.setData({ startDate: e.detail.value, page: 1 })
|
|
this.load(1)
|
|
},
|
|
onEndChange(e) {
|
|
this.setData({ endDate: e.detail.value, page: 1 })
|
|
this.load(1)
|
|
},
|
|
onAttendancePointChange(e) {
|
|
const attendancePointIndex = Number(e.detail.value)
|
|
const point = attendancePointIndex > 0 ? this.data.attendancePoints[attendancePointIndex - 1] : null
|
|
this.setData({
|
|
attendancePointIndex,
|
|
attendancePointName: point ? point.name : '',
|
|
page: 1,
|
|
})
|
|
this.load(1)
|
|
},
|
|
onKeywordInput(e) {
|
|
this.setData({ keyword: e.detail.value, page: 1 })
|
|
if (keywordSearchTimer) {
|
|
clearTimeout(keywordSearchTimer)
|
|
}
|
|
keywordSearchTimer = setTimeout(() => {
|
|
keywordSearchTimer = null
|
|
this.load(1)
|
|
}, 350)
|
|
},
|
|
searchKeyword() {
|
|
if (keywordSearchTimer) {
|
|
clearTimeout(keywordSearchTimer)
|
|
keywordSearchTimer = null
|
|
}
|
|
this.setData({ page: 1 })
|
|
this.load(1)
|
|
},
|
|
openDetail(e) {
|
|
const row = this.data.rows[Number(e.currentTarget.dataset.index)]
|
|
if (!row) {
|
|
return
|
|
}
|
|
const attendancePointName = this.data.attendancePointName || row.attendancePointName || ''
|
|
const params = [
|
|
['category', row.category || this.data.category],
|
|
['id', row.id || ''],
|
|
['metricKind', row.metricKind || ''],
|
|
['startDate', this.data.startDate],
|
|
['endDate', this.data.endDate],
|
|
['attendancePointName', attendancePointName],
|
|
['name', row.name || ''],
|
|
['productName', row.productName || ''],
|
|
['processName', row.processName || ''],
|
|
['stampingMethod', row.stampingMethod || ''],
|
|
].map(pair => `${pair[0]}=${encodeURIComponent(pair[1])}`).join('&')
|
|
wx.navigateTo({ url: `/pages/usageStatsDetail/usageStatsDetail?${params}` })
|
|
},
|
|
async exportFile() {
|
|
if (this.data.exporting) {
|
|
return
|
|
}
|
|
this.setData({ exporting: true })
|
|
wx.showLoading({ title: '导出中' })
|
|
let filePath = ''
|
|
try {
|
|
filePath = await api.exportUsageStats({
|
|
startDate: this.data.startDate,
|
|
endDate: this.data.endDate,
|
|
attendancePointName: this.data.attendancePointName,
|
|
keyword: this.data.keyword,
|
|
})
|
|
await openDocumentFile(filePath)
|
|
} catch (error) {
|
|
wx.showToast({ title: error.message || (filePath ? '打开文件失败' : '导出失败'), icon: 'none' })
|
|
} finally {
|
|
wx.hideLoading()
|
|
this.setData({ exporting: false })
|
|
}
|
|
},
|
|
onPageInput(e) {
|
|
this.setData({ pageInput: e.detail.value })
|
|
},
|
|
jumpToPage(e) {
|
|
wx.hideKeyboard()
|
|
const inputValue = e && e.detail && e.detail.value !== undefined ? e.detail.value : this.data.pageInput
|
|
const target = Math.max(1, Math.min(Number(inputValue) || this.data.page, this.data.totalPages))
|
|
if (target === this.data.page) {
|
|
this.setData({ pageInput: String(this.data.page || 1) })
|
|
return
|
|
}
|
|
this.load(target)
|
|
},
|
|
prevPage() {
|
|
if (this.data.page > 1) {
|
|
this.load(this.data.page - 1)
|
|
}
|
|
},
|
|
nextPage() {
|
|
if (this.data.page < this.data.totalPages) {
|
|
this.load(this.data.page + 1)
|
|
}
|
|
},
|
|
})
|