JhHardwareWRS/pages/records/records.js
2026-06-24 15:19:14 +08:00

273 lines
7.2 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.

const api = require('../../utils/api')
const util = require('../../utils/util')
Page({
data: {
user: null,
mode: 'mine',
title: '我的报工记录',
startDate: '',
endDate: '',
status: '',
showStatusFilter: true,
rows: [],
page: 1,
pageInput: '1',
totalPages: 1,
refreshing: false,
scrollTop: 0,
expandedRecordId: '',
detailExpandedAll: false,
filterVoided: true,
statusOptions: [
{ label: '全部', value: '' },
{ label: '待审核', value: 'pending' },
{ label: '已通过', value: 'approved' },
],
},
onLoad(options) {
const mode = options.mode || 'mine'
const defaultDate = util.today()
const startDate = mode === 'pending' ? (options.startDate || '') : (options.startDate || defaultDate)
const endDate = mode === 'pending' ? (options.endDate || '') : (options.endDate || defaultDate)
const titleMap = {
audit: '审核记录',
pending: '待审核清单',
mine: '我的报工记录',
}
this.setData({
mode,
title: titleMap[mode] || '我的报工记录',
startDate,
endDate,
status: mode === 'pending' ? 'pending' : (options.status || ''),
showStatusFilter: mode !== 'pending',
})
},
onShow() {
this.load()
},
toggleDetails() {
this.setData({
detailExpandedAll: !this.data.detailExpandedAll,
expandedRecordId: '',
})
},
onScroll(e) {
this.currentScrollTop = e.detail.scrollTop || 0
},
queryRecordTop(id) {
return new Promise(resolve => {
this.createSelectorQuery()
.select(`#record-${id}`)
.boundingClientRect(rect => {
resolve(rect ? rect.top : null)
})
.exec()
})
},
restoreRecordPosition(id, beforeTop) {
if (beforeTop === null || beforeTop === undefined) {
return
}
wx.nextTick(() => {
this.queryRecordTop(id).then(afterTop => {
if (afterTop === null || afterTop === undefined) {
return
}
const nextScrollTop = Math.max(
0,
(this.currentScrollTop || 0) + afterTop - beforeTop,
)
this.currentScrollTop = nextScrollTop
this.setData({ scrollTop: nextScrollTop })
})
})
},
toggleRecordDetail(e) {
const id = String(e.currentTarget.dataset.id || '')
const switchingRecord = this.data.detailExpandedAll
|| (!!this.data.expandedRecordId && this.data.expandedRecordId !== id)
this.queryRecordTop(id).then(beforeTop => {
this.setData({
detailExpandedAll: false,
expandedRecordId: this.data.expandedRecordId === id ? '' : id,
}, () => {
if (switchingRecord) {
this.restoreRecordPosition(id, beforeTop)
}
})
})
},
async load(page = this.data.page) {
const user = api.getCurrentUser()
if (!user) {
this.setData({ rows: [], user })
return
}
const filters = {
startDate: this.data.startDate,
endDate: this.data.endDate,
status: this.data.status,
page,
pageSize: 8,
includeVoided: !this.data.filterVoided,
}
if (this.data.mode === 'audit') {
filters.reviewerPhone = user.phone
} else if (this.data.mode === 'pending') {
filters.status = 'pending'
} else {
filters.employeePhone = user.phone
}
try {
const result = await api.listReports(filters)
this.setData({
user,
rows: result.rows,
page: result.page,
pageInput: String(result.page || 1),
totalPages: result.totalPages,
expandedRecordId: '',
detailExpandedAll: false,
})
} catch (error) {
wx.showToast({ title: error.message, icon: 'none' })
}
},
async onPullDownRefresh() {
this.setData({ refreshing: true })
try {
await this.load(1)
} finally {
this.setData({ refreshing: false })
if (wx.stopPullDownRefresh) {
wx.stopPullDownRefresh()
}
}
},
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)
},
shiftRangeDate(field, days) {
const otherField = field === 'startDate' ? 'endDate' : 'startDate'
const current = this.data[field]
const other = this.data[otherField]
const base = current || other || util.today()
const updates = {
[field]: util.addDays(base, days),
page: 1,
}
if (!current && !other) {
updates[otherField] = base
}
this.setData(updates)
this.load(1)
},
decreaseStartDate() {
this.shiftRangeDate('startDate', -1)
},
increaseEndDate() {
this.shiftRangeDate('endDate', 1)
},
chooseStatus(e) {
this.setData({
status: e.currentTarget.dataset.value,
page: 1,
})
this.load(1)
},
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)
}
},
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)
},
openPendingReview(e) {
const id = e.currentTarget.dataset.id
wx.navigateTo({
url: `/pages/review/review?reportId=${id}`,
})
},
toggleFilterVoided() {
this.setData({ filterVoided: !this.data.filterVoided, page: 1 })
this.load(1)
},
onFilterVoidedChange(e) {
this.setData({ filterVoided: !!e.detail.value, page: 1 })
this.load(1)
},
async voidReport(e) {
const id = e.currentTarget.dataset.id
wx.showModal({
title: '确认作废',
content: '作废的记录将在30天后被系统彻底删除彻底删除前可随时撤销作废是否确定删除',
cancelText: '否',
confirmText: '是',
confirmColor: '#c5221f',
success: async res => {
if (!res.confirm) {
return
}
wx.showLoading({ title: '处理中' })
try {
await api.voidReport(id)
wx.showToast({ title: '已作废', icon: 'success' })
await this.load(this.data.page)
} catch (error) {
wx.showToast({ title: error.message || '作废失败', icon: 'none' })
} finally {
wx.hideLoading()
}
},
})
},
async unvoidReport(e) {
const id = e.currentTarget.dataset.id
wx.showLoading({ title: '处理中' })
try {
await api.unvoidReport(id)
wx.showToast({ title: '已撤销作废', icon: 'success' })
await this.load(this.data.page)
} catch (error) {
wx.showToast({ title: error.message || '撤销失败', icon: 'none' })
} finally {
wx.hideLoading()
}
},
openEditReview(e) {
if (this.data.mode === 'mine') {
return
}
const id = e.currentTarget.dataset.id
wx.navigateTo({
url: `/pages/review/review?reportId=${id}`,
})
},
})