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) }, })