273 lines
7.2 KiB
JavaScript
273 lines
7.2 KiB
JavaScript
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}`,
|
||
})
|
||
},
|
||
})
|