343 lines
9.5 KiB
JavaScript
343 lines
9.5 KiB
JavaScript
const api = require('../../utils/api')
|
||
|
||
const emptyForm = {
|
||
phone: '',
|
||
name: '',
|
||
role: 'worker',
|
||
attendancePointNames: [],
|
||
}
|
||
|
||
const allRoleOptions = [
|
||
{ label: '冲压工人', value: 'worker' },
|
||
{ label: '管理员', value: 'admin' },
|
||
{ label: '经理', value: 'manager' },
|
||
]
|
||
|
||
const workerRoleOptions = [
|
||
{ label: '冲压工人', value: 'worker' },
|
||
]
|
||
|
||
Page({
|
||
data: {
|
||
readonly: false,
|
||
keyword: '',
|
||
rows: [],
|
||
page: 1,
|
||
pageInput: '1',
|
||
totalPages: 1,
|
||
form: { ...emptyForm },
|
||
formVisible: false,
|
||
formTitle: '新增人员',
|
||
importFileName: '',
|
||
refreshing: false,
|
||
currentUser: null,
|
||
attendancePoints: [],
|
||
roleOptions: allRoleOptions,
|
||
roleIndex: 0,
|
||
},
|
||
onLoad(options) {
|
||
this.setData({
|
||
readonly: options.readonly === '1',
|
||
})
|
||
},
|
||
onShow() {
|
||
this.init()
|
||
},
|
||
async init() {
|
||
const currentUser = api.getCurrentUser()
|
||
const roleOptions = this.roleOptionsForUser(currentUser)
|
||
this.setData({ currentUser, roleOptions })
|
||
await this.loadAttendancePoints()
|
||
await this.load()
|
||
},
|
||
roleOptionsForUser(user = this.data.currentUser) {
|
||
return user && user.role === 'admin' ? workerRoleOptions : allRoleOptions
|
||
},
|
||
async loadAttendancePoints() {
|
||
try {
|
||
const attendancePoints = await api.listAccessibleAttendancePoints()
|
||
this.setData({ attendancePoints: attendancePoints || [] })
|
||
} catch (error) {
|
||
wx.showToast({ title: error.message || '加载考勤点失败', icon: 'none' })
|
||
}
|
||
},
|
||
async load(page = this.data.page) {
|
||
try {
|
||
const result = await api.listPeople({
|
||
keyword: this.data.keyword,
|
||
page,
|
||
pageSize: 8,
|
||
})
|
||
this.setData({
|
||
rows: result.rows,
|
||
page: result.page,
|
||
pageInput: String(result.page || 1),
|
||
totalPages: result.totalPages,
|
||
})
|
||
} 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()
|
||
}
|
||
}
|
||
},
|
||
onKeywordInput(e) {
|
||
this.setData({ keyword: e.detail.value, page: 1 })
|
||
this.load(1)
|
||
},
|
||
onInput(e) {
|
||
const field = e.currentTarget.dataset.field
|
||
this.setData({
|
||
[`form.${field}`]: e.detail.value,
|
||
})
|
||
},
|
||
onRoleChange(e) {
|
||
const roleIndex = Number(e.detail.value)
|
||
const role = this.data.roleOptions[roleIndex].value
|
||
const updates = {
|
||
roleIndex,
|
||
'form.role': role,
|
||
}
|
||
if (role === 'manager') {
|
||
if (!this.data.form.originalPhone) {
|
||
updates['form.attendancePointNames'] = []
|
||
updates.attendancePoints = this.checkedPointMap([])
|
||
}
|
||
} else if (!(this.data.form.attendancePointNames || []).length && this.data.attendancePoints[0]) {
|
||
const defaultPointNames = [this.data.attendancePoints[0].name]
|
||
updates['form.attendancePointNames'] = defaultPointNames
|
||
updates.attendancePoints = this.checkedPointMap(defaultPointNames)
|
||
}
|
||
this.setData({
|
||
...updates,
|
||
})
|
||
},
|
||
onPointCheckboxChange(e) {
|
||
const names = e.detail.value || []
|
||
this.setData({
|
||
'form.attendancePointNames': names,
|
||
attendancePoints: this.checkedPointMap(names),
|
||
})
|
||
},
|
||
checkedPointMap(names = []) {
|
||
const selected = new Set(names || [])
|
||
return this.data.attendancePoints.map(point => ({
|
||
...point,
|
||
checked: selected.has(point.name),
|
||
}))
|
||
},
|
||
noop() {},
|
||
openCreate() {
|
||
const defaultPointNames = this.data.attendancePoints[0] ? [this.data.attendancePoints[0].name] : []
|
||
this.setData({
|
||
form: { ...emptyForm, attendancePointNames: defaultPointNames },
|
||
attendancePoints: this.checkedPointMap(defaultPointNames),
|
||
roleIndex: 0,
|
||
formTitle: '新增人员',
|
||
formVisible: true,
|
||
})
|
||
},
|
||
closeForm() {
|
||
this.setData({
|
||
formVisible: false,
|
||
form: { ...emptyForm },
|
||
attendancePoints: this.checkedPointMap([]),
|
||
roleOptions: this.roleOptionsForUser(),
|
||
roleIndex: 0,
|
||
})
|
||
},
|
||
async save() {
|
||
try {
|
||
const form = { ...this.data.form }
|
||
if (form.role !== 'manager' && !(form.attendancePointNames || []).length) {
|
||
wx.showToast({ title: '请选择考勤点', icon: 'none' })
|
||
return
|
||
}
|
||
await api.savePerson(form)
|
||
wx.showToast({ title: '已保存', icon: 'success' })
|
||
this.setData({
|
||
form: { ...emptyForm },
|
||
attendancePoints: this.checkedPointMap([]),
|
||
roleOptions: this.roleOptionsForUser(),
|
||
roleIndex: 0,
|
||
formVisible: false,
|
||
})
|
||
await this.load(1)
|
||
} catch (error) {
|
||
wx.showToast({ title: error.message, icon: 'none' })
|
||
}
|
||
},
|
||
edit(e) {
|
||
const index = e.currentTarget.dataset.index
|
||
const person = this.data.rows[index]
|
||
const roleIndex = Math.max(0, this.data.roleOptions.findIndex(item => item.value === person.role))
|
||
const pointNames = person.attendancePointNames || []
|
||
this.setData({
|
||
form: {
|
||
phone: person.phone,
|
||
originalPhone: person.phone,
|
||
name: person.name,
|
||
role: person.role,
|
||
attendancePointNames: pointNames,
|
||
},
|
||
attendancePoints: this.checkedPointMap(pointNames),
|
||
roleIndex,
|
||
roleOptions: this.roleOptionsForUser(),
|
||
formTitle: '编辑人员',
|
||
formVisible: true,
|
||
})
|
||
},
|
||
addRole(e) {
|
||
const index = e.currentTarget.dataset.index
|
||
const person = this.data.rows[index]
|
||
if (!person) {
|
||
return
|
||
}
|
||
const existingRoles = new Set(person.roles || [])
|
||
const roleOptions = this.roleOptionsForUser().filter(item => !existingRoles.has(item.value))
|
||
if (!roleOptions.length) {
|
||
wx.showToast({ title: '该人员已拥有全部可添加角色', icon: 'none' })
|
||
return
|
||
}
|
||
const role = roleOptions[0].value
|
||
const pointNames = person.attendancePointNames || []
|
||
this.setData({
|
||
form: {
|
||
phone: person.phone,
|
||
originalPhone: person.phone,
|
||
name: person.name,
|
||
role,
|
||
attendancePointNames: role === 'manager' ? pointNames : pointNames,
|
||
},
|
||
attendancePoints: this.checkedPointMap(pointNames),
|
||
roleOptions,
|
||
roleIndex: 0,
|
||
formTitle: '添加角色',
|
||
formVisible: true,
|
||
})
|
||
},
|
||
removeRole(e) {
|
||
const phone = e.currentTarget.dataset.phone
|
||
const role = e.currentTarget.dataset.role
|
||
const roleName = e.currentTarget.dataset.roleName
|
||
wx.showModal({
|
||
title: '删除角色',
|
||
content: `${phone} · ${roleName}`,
|
||
success: async res => {
|
||
if (res.confirm) {
|
||
try {
|
||
await api.deletePerson(phone, role)
|
||
await this.load(1)
|
||
} catch (error) {
|
||
wx.showToast({ title: error.message, icon: 'none' })
|
||
}
|
||
}
|
||
},
|
||
})
|
||
},
|
||
removePerson(e) {
|
||
const index = e.currentTarget.dataset.index
|
||
const person = this.data.rows[index]
|
||
if (!person) {
|
||
return
|
||
}
|
||
const currentUser = api.getCurrentUser()
|
||
if (currentUser && currentUser.phone === person.phone) {
|
||
wx.showToast({ title: '不能删除当前登录账号', icon: 'none' })
|
||
return
|
||
}
|
||
wx.showModal({
|
||
title: '删除人员',
|
||
content: `确定删除 ${person.name}(${person.phone})?历史报工记录会保留。`,
|
||
confirmText: '删除',
|
||
confirmColor: '#d92d20',
|
||
success: async res => {
|
||
if (res.confirm) {
|
||
try {
|
||
await api.deletePerson(person.phone)
|
||
wx.showToast({ title: '已删除', icon: 'success' })
|
||
await this.load(1)
|
||
} catch (error) {
|
||
wx.showToast({ title: error.message, icon: 'none' })
|
||
}
|
||
}
|
||
},
|
||
})
|
||
},
|
||
clearForm() {
|
||
this.setData({
|
||
form: { ...emptyForm },
|
||
attendancePoints: this.checkedPointMap([]),
|
||
roleOptions: this.roleOptionsForUser(),
|
||
roleIndex: 0,
|
||
})
|
||
},
|
||
chooseFile() {
|
||
wx.chooseMessageFile({
|
||
count: 1,
|
||
type: 'file',
|
||
extension: ['xlsx', 'xls'],
|
||
success: async res => {
|
||
const file = res.tempFiles[0]
|
||
this.setData({ importFileName: file.name })
|
||
wx.showLoading({ title: '导入中' })
|
||
try {
|
||
const result = await api.importPeople(file.path)
|
||
wx.showToast({ title: `导入${result.imported}条`, icon: 'success' })
|
||
await this.load(1)
|
||
} catch (error) {
|
||
wx.showToast({ title: error.message, icon: 'none' })
|
||
} finally {
|
||
wx.hideLoading()
|
||
}
|
||
},
|
||
})
|
||
},
|
||
async exportFile() {
|
||
wx.showLoading({ title: '导出中' })
|
||
try {
|
||
const filePath = await api.exportPeople()
|
||
wx.openDocument({
|
||
filePath,
|
||
fileType: 'xlsx',
|
||
showMenu: true,
|
||
})
|
||
} catch (error) {
|
||
wx.showToast({ title: error.message, icon: 'none' })
|
||
} finally {
|
||
wx.hideLoading()
|
||
}
|
||
},
|
||
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)
|
||
},
|
||
})
|