281 lines
8.7 KiB
JavaScript
281 lines
8.7 KiB
JavaScript
const api = require('../../utils/api')
|
|
const locationGuard = require('../../utils/locationGuard')
|
|
|
|
const decodeRepeated = value => {
|
|
let text = String(value || '').trim()
|
|
for (let index = 0; index < 3; index += 1) {
|
|
try {
|
|
const decoded = decodeURIComponent(text)
|
|
if (decoded === text) {
|
|
break
|
|
}
|
|
text = decoded
|
|
} catch (error) {
|
|
break
|
|
}
|
|
}
|
|
return text
|
|
}
|
|
|
|
const itemKey = item => `${item.attendancePointName || ''}||${item.moldName || item.productName || item.name}||${item.processName || ''}`
|
|
|
|
Page({
|
|
data: {
|
|
items: [],
|
|
attendancePointName: '',
|
|
equipmentOptions: [],
|
|
equipmentLabels: [],
|
|
filling: false,
|
|
submitting: false,
|
|
deviceModalVisible: false,
|
|
activeDeviceIndex: -1,
|
|
deviceSelectOptions: [],
|
|
pendingDeviceNos: [],
|
|
currentLocation: null,
|
|
},
|
|
onLoad(options) {
|
|
const user = api.getCurrentUser()
|
|
if (!user || user.role !== 'worker') {
|
|
wx.showToast({ title: '请先用冲压工人登录', icon: 'none' })
|
|
setTimeout(() => {
|
|
wx.reLaunch({ url: '/pages/index/index' })
|
|
}, 800)
|
|
return
|
|
}
|
|
const attendancePointName = decodeRepeated(options.attendancePointName || '')
|
|
this.setData({ attendancePointName })
|
|
this.loadCleaningEquipment(attendancePointName)
|
|
this.addResolvedItem({
|
|
attendancePointName,
|
|
moldName: decodeRepeated(options.moldName || ''),
|
|
processName: decodeRepeated(options.processName || ''),
|
|
stampingMethod: decodeRepeated(options.stampingMethod || ''),
|
|
isCleaning: options.isCleaning === '1',
|
|
displayName: decodeRepeated(options.displayName || ''),
|
|
})
|
|
},
|
|
addResolvedItem(raw) {
|
|
const item = {
|
|
attendancePointName: String(raw.attendancePointName || this.data.attendancePointName || '').trim(),
|
|
moldName: String(raw.moldName || raw.name || '').trim(),
|
|
processName: String(raw.processName || '').trim(),
|
|
stampingMethod: String(raw.stampingMethod || '').trim(),
|
|
isCleaning: !!raw.isCleaning || String(raw.stampingMethod || '').trim() === '清洗',
|
|
displayName: raw.displayName || api.moldDisplayName(raw.moldName || raw.name, raw.processName, raw.stampingMethod),
|
|
deviceNo: '',
|
|
deviceNos: [],
|
|
quantity: '',
|
|
}
|
|
if (!item.moldName) {
|
|
wx.showToast({ title: '未识别清洗产品', icon: 'none' })
|
|
return
|
|
}
|
|
if (!item.processName) {
|
|
wx.showToast({ title: '未识别工序', icon: 'none' })
|
|
return
|
|
}
|
|
if (!item.isCleaning) {
|
|
wx.showToast({ title: '只能添加冲压方式为清洗的二维码', icon: 'none' })
|
|
return
|
|
}
|
|
if (this.data.attendancePointName && item.attendancePointName !== this.data.attendancePointName) {
|
|
wx.showToast({ title: '只能添加同一考勤点的清洗产品', icon: 'none' })
|
|
return
|
|
}
|
|
const exists = this.data.items.some(existing => itemKey(existing) === itemKey(item))
|
|
if (exists) {
|
|
wx.showToast({ title: '该清洗产品已添加', icon: 'none' })
|
|
return
|
|
}
|
|
this.setData({
|
|
items: this.data.items.concat(item),
|
|
})
|
|
},
|
|
async loadCleaningEquipment(attendancePointName = this.data.attendancePointName) {
|
|
try {
|
|
const result = await api.listEquipment({
|
|
attendancePointName,
|
|
deviceType: '清洗设备',
|
|
page: 1,
|
|
pageSize: 100,
|
|
})
|
|
const equipmentOptions = result.rows || []
|
|
this.setData({
|
|
equipmentOptions,
|
|
equipmentLabels: equipmentOptions.map(item => item.displayName || item.deviceNo),
|
|
})
|
|
} catch (error) {
|
|
wx.showToast({ title: error.message || '加载清洗设备失败', icon: 'none' })
|
|
}
|
|
},
|
|
extractScene(scanResult) {
|
|
const raw = decodeRepeated(scanResult)
|
|
if (!raw) {
|
|
return ''
|
|
}
|
|
const patterns = [
|
|
/(?:^|[?&])scene=([^&]+)/i,
|
|
/(?:^|[?&])mold=([^&]+)/i,
|
|
]
|
|
for (let index = 0; index < patterns.length; index += 1) {
|
|
const matched = raw.match(patterns[index])
|
|
if (matched && matched[1]) {
|
|
const value = decodeRepeated(matched[1])
|
|
return value.startsWith('mold=') ? value : `mold=${value}`
|
|
}
|
|
}
|
|
return raw.startsWith('mold=') ? raw : ''
|
|
},
|
|
async addByScanResult(scanResult) {
|
|
const scene = this.extractScene(scanResult)
|
|
if (!scene) {
|
|
wx.showToast({ title: '未识别清洗二维码', icon: 'none' })
|
|
return
|
|
}
|
|
try {
|
|
const resolved = await api.resolveMoldScene(scene)
|
|
await locationGuard.ensureFactoryLocation(resolved.attendancePointName)
|
|
this.addResolvedItem(resolved)
|
|
} catch (error) {
|
|
wx.showToast({ title: error.message || '二维码解析失败', icon: 'none' })
|
|
}
|
|
},
|
|
startFill() {
|
|
if (!this.data.items.length) {
|
|
wx.showToast({ title: '请先添加清洗产品', icon: 'none' })
|
|
return
|
|
}
|
|
this.setData({ filling: true })
|
|
},
|
|
async continueAdd() {
|
|
try {
|
|
await locationGuard.ensureFactoryLocation(this.data.attendancePointName)
|
|
} catch (error) {
|
|
wx.showModal({
|
|
title: '无法继续扫码',
|
|
content: error.message || '当前位置不在允许范围内',
|
|
showCancel: false,
|
|
})
|
|
return
|
|
}
|
|
wx.scanCode({
|
|
onlyFromCamera: false,
|
|
success: res => {
|
|
const candidates = [res.path, res.result, res.rawData]
|
|
const raw = candidates.find(item => item) || ''
|
|
this.addByScanResult(raw)
|
|
},
|
|
})
|
|
},
|
|
abandon() {
|
|
wx.showModal({
|
|
title: '放弃报工',
|
|
content: '确认放弃本次清洗报工?',
|
|
confirmText: '放弃',
|
|
confirmColor: '#d92d20',
|
|
success: res => {
|
|
if (res.confirm) {
|
|
wx.reLaunch({ url: '/pages/index/index' })
|
|
}
|
|
},
|
|
})
|
|
},
|
|
onQuantityInput(e) {
|
|
const index = e.currentTarget.dataset.index
|
|
this.setData({
|
|
[`items[${index}].quantity`]: e.detail.value,
|
|
})
|
|
},
|
|
noop() {},
|
|
openDeviceSelector(e) {
|
|
const index = Number(e.currentTarget.dataset.index)
|
|
const item = this.data.items[index]
|
|
if (!item) {
|
|
return
|
|
}
|
|
if (!this.data.equipmentOptions.length) {
|
|
wx.showToast({ title: '暂无清洗设备', icon: 'none' })
|
|
return
|
|
}
|
|
const selected = new Set(item.deviceNos && item.deviceNos.length ? item.deviceNos : (item.deviceNo ? String(item.deviceNo).split('、') : []))
|
|
const deviceSelectOptions = this.data.equipmentOptions.map(equipment => ({
|
|
...equipment,
|
|
checked: selected.has(equipment.deviceNo),
|
|
}))
|
|
this.setData({
|
|
activeDeviceIndex: index,
|
|
pendingDeviceNos: Array.from(selected).filter(Boolean),
|
|
deviceSelectOptions,
|
|
deviceModalVisible: true,
|
|
})
|
|
},
|
|
closeDeviceSelector() {
|
|
this.setData({
|
|
deviceModalVisible: false,
|
|
activeDeviceIndex: -1,
|
|
deviceSelectOptions: [],
|
|
pendingDeviceNos: [],
|
|
})
|
|
},
|
|
onDeviceSelectionChange(e) {
|
|
const pendingDeviceNos = e.detail.value || []
|
|
const selected = new Set(pendingDeviceNos)
|
|
this.setData({
|
|
pendingDeviceNos,
|
|
deviceSelectOptions: this.data.deviceSelectOptions.map(item => ({
|
|
...item,
|
|
checked: selected.has(item.deviceNo),
|
|
})),
|
|
})
|
|
},
|
|
confirmDeviceSelection() {
|
|
const index = Number(this.data.activeDeviceIndex)
|
|
if (index < 0 || !this.data.items[index]) {
|
|
this.closeDeviceSelector()
|
|
return
|
|
}
|
|
if (!this.data.pendingDeviceNos.length) {
|
|
wx.showToast({ title: '请至少选择一台清洗设备', icon: 'none' })
|
|
return
|
|
}
|
|
const deviceNos = this.data.pendingDeviceNos
|
|
this.setData({
|
|
[`items[${index}].deviceNos`]: deviceNos,
|
|
[`items[${index}].deviceNo`]: deviceNos.join('、'),
|
|
deviceModalVisible: false,
|
|
activeDeviceIndex: -1,
|
|
deviceSelectOptions: [],
|
|
pendingDeviceNos: [],
|
|
})
|
|
},
|
|
async submit() {
|
|
if (this.data.submitting) {
|
|
return
|
|
}
|
|
const missingDevice = this.data.items.find(item => !item.deviceNo)
|
|
if (missingDevice) {
|
|
wx.showToast({ title: `${missingDevice.moldName}请选择清洗设备号`, icon: 'none' })
|
|
return
|
|
}
|
|
const invalid = this.data.items.find(item => Number(item.quantity || 0) <= 0)
|
|
if (invalid) {
|
|
wx.showToast({ title: `${invalid.moldName}请填写清洗数量`, icon: 'none' })
|
|
return
|
|
}
|
|
this.setData({ submitting: true })
|
|
wx.showLoading({ title: '提交中' })
|
|
try {
|
|
const locationResult = await locationGuard.ensureFactoryLocation(this.data.attendancePointName)
|
|
const report = await api.submitCleaningReport(this.data.items, locationResult.current)
|
|
wx.reLaunch({
|
|
url: `/pages/reportResult/reportResult?reportId=${report.id}`,
|
|
})
|
|
} catch (error) {
|
|
wx.showToast({ title: error.message || '提交失败', icon: 'none' })
|
|
} finally {
|
|
wx.hideLoading()
|
|
this.setData({ submitting: false })
|
|
}
|
|
},
|
|
})
|