feat: 小程序展示报工超额快照

This commit is contained in:
souplearn 2026-07-25 21:01:43 +08:00
parent 25ed4e2da8
commit 4003625fb1
6 changed files with 280 additions and 33 deletions

122
app.wxss
View File

@ -709,11 +709,32 @@ scroll-view.page {
pointer-events: none; pointer-events: none;
} }
.over-limit-watermark {
position: absolute;
right: 28rpx;
top: 18rpx;
z-index: 4;
padding: 8rpx 18rpx;
border: 2rpx solid rgba(197, 34, 31, 0.72);
border-radius: 12rpx;
color: rgba(148, 27, 23, 0.92);
background: rgba(255, 238, 238, 0.94);
font-size: 30rpx;
font-weight: 900;
line-height: 1.2;
transform: rotate(10deg);
pointer-events: none;
}
.lower-watermark, .lower-watermark,
.misc-watermark.lower-watermark, .misc-watermark.lower-watermark,
.cleaning-watermark.lower-watermark, .cleaning-watermark.lower-watermark,
.multi-person-watermark.lower-watermark, .multi-person-watermark.lower-watermark,
.continuous-die-watermark.lower-watermark { .continuous-die-watermark.lower-watermark,
.timeout-watermark.lower-watermark,
.voided-watermark.lower-watermark,
.modified-watermark.lower-watermark,
.over-limit-watermark.lower-watermark {
top: 78rpx; top: 78rpx;
} }
@ -721,10 +742,50 @@ scroll-view.page {
.misc-watermark.third-watermark, .misc-watermark.third-watermark,
.cleaning-watermark.third-watermark, .cleaning-watermark.third-watermark,
.multi-person-watermark.third-watermark, .multi-person-watermark.third-watermark,
.continuous-die-watermark.third-watermark { .continuous-die-watermark.third-watermark,
.timeout-watermark.third-watermark,
.voided-watermark.third-watermark,
.modified-watermark.third-watermark,
.over-limit-watermark.third-watermark {
top: 138rpx; top: 138rpx;
} }
.fourth-watermark,
.misc-watermark.fourth-watermark,
.cleaning-watermark.fourth-watermark,
.multi-person-watermark.fourth-watermark,
.continuous-die-watermark.fourth-watermark,
.timeout-watermark.fourth-watermark,
.voided-watermark.fourth-watermark,
.modified-watermark.fourth-watermark,
.over-limit-watermark.fourth-watermark {
top: 198rpx;
}
.fifth-watermark,
.misc-watermark.fifth-watermark,
.cleaning-watermark.fifth-watermark,
.multi-person-watermark.fifth-watermark,
.continuous-die-watermark.fifth-watermark,
.timeout-watermark.fifth-watermark,
.voided-watermark.fifth-watermark,
.modified-watermark.fifth-watermark,
.over-limit-watermark.fifth-watermark {
top: 258rpx;
}
.sixth-watermark,
.misc-watermark.sixth-watermark,
.cleaning-watermark.sixth-watermark,
.multi-person-watermark.sixth-watermark,
.continuous-die-watermark.sixth-watermark,
.timeout-watermark.sixth-watermark,
.voided-watermark.sixth-watermark,
.modified-watermark.sixth-watermark,
.over-limit-watermark.sixth-watermark {
top: 318rpx;
}
.timeout-watermark { .timeout-watermark {
position: absolute; position: absolute;
right: 24rpx; right: 24rpx;
@ -832,6 +893,63 @@ scroll-view.page {
line-height: 1.35; line-height: 1.35;
} }
.over-limit-panel {
margin-top: 16rpx;
padding: 16rpx;
border-radius: 14rpx;
display: flex;
flex-direction: column;
gap: 8rpx;
box-sizing: border-box;
}
.over-limit-panel.danger {
border: 2rpx solid rgba(197, 34, 31, 0.28);
background: rgba(255, 239, 239, 0.78);
}
.over-limit-panel.warn {
border: 2rpx solid rgba(217, 119, 6, 0.28);
background: rgba(255, 247, 232, 0.78);
}
.over-limit-title {
color: #9f1c19;
font-size: 24rpx;
font-weight: 900;
line-height: 1.35;
}
.over-limit-panel.warn .over-limit-title {
color: #9a4a05;
}
.over-limit-text {
color: #7a271a;
font-size: 23rpx;
font-weight: 700;
line-height: 1.45;
word-break: break-all;
}
.over-limit-panel.warn .over-limit-text {
color: #7a4a12;
}
.over-limit-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 6rpx 14rpx;
color: #7a271a;
font-size: 22rpx;
font-weight: 700;
line-height: 1.4;
}
.over-limit-panel.warn .over-limit-grid {
color: #7a4a12;
}
.filter-bar { .filter-bar {
display: grid; display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));

View File

@ -37,13 +37,14 @@
<view wx:if="{{!rows.length}}" class="list-empty">暂无已审核报工</view> <view wx:if="{{!rows.length}}" class="list-empty">暂无已审核报工</view>
<view wx:for="{{rows}}" wx:key="id" class="card dashboard-card {{item.isSystemAutoSubmitted ? 'system-auto' : ''}} {{item.isVoided ? 'voided' : ''}}"> <view wx:for="{{rows}}" wx:key="id" class="card dashboard-card {{item.isSystemAutoSubmitted ? 'system-auto' : ''}} {{item.isVoided ? 'voided' : ''}}">
<text wx:if="{{item.isVoided}}" class="voided-watermark">作废</text> <text wx:if="{{item.hasOverLimit}}" class="over-limit-watermark {{item.watermarkClasses.overLimit}}">超额</text>
<text wx:elif="{{item.correctionPairs.length}}" class="modified-watermark">更改</text> <text wx:if="{{item.isVoided}}" class="voided-watermark {{item.watermarkClasses.state}}">作废</text>
<text wx:if="{{item.isSystemAutoSubmitted}}" class="timeout-watermark">超时-系统自动提交</text> <text wx:elif="{{item.correctionPairs.length}}" class="modified-watermark {{item.watermarkClasses.state}}">更改</text>
<text wx:if="{{item.isCleaning}}" class="cleaning-watermark {{item.isSystemAutoSubmitted || item.isVoided || item.correctionPairs.length ? 'lower-watermark' : ''}}">清洗</text> <text wx:if="{{item.isSystemAutoSubmitted}}" class="timeout-watermark {{item.watermarkClasses.timeout}}">超时-系统自动提交</text>
<text wx:if="{{item.isMisc}}" class="misc-watermark {{item.isSystemAutoSubmitted || item.isVoided || item.correctionPairs.length ? 'lower-watermark' : ''}}">包含杂活</text> <text wx:if="{{item.isCleaning}}" class="cleaning-watermark {{item.watermarkClasses.cleaning}}">清洗</text>
<text wx:if="{{item.isMultiPerson}}" class="multi-person-watermark {{item.isSystemAutoSubmitted || item.isVoided || item.correctionPairs.length || item.isMisc || item.isCleaning ? 'lower-watermark' : ''}}">多人协作</text> <text wx:if="{{item.isMisc}}" class="misc-watermark {{item.watermarkClasses.misc}}">包含杂活</text>
<text wx:if="{{item.isContinuousDie}}" class="continuous-die-watermark {{item.isSystemAutoSubmitted || item.isVoided || item.correctionPairs.length || item.isMisc || item.isCleaning || item.isMultiPerson ? 'lower-watermark' : ''}} {{item.isMultiPerson && (item.isSystemAutoSubmitted || item.isVoided || item.correctionPairs.length || item.isMisc || item.isCleaning) ? 'third-watermark' : ''}}">连续模</text> <text wx:if="{{item.isMultiPerson}}" class="multi-person-watermark {{item.watermarkClasses.multiPerson}}">多人协作</text>
<text wx:if="{{item.isContinuousDie}}" class="continuous-die-watermark {{item.watermarkClasses.continuousDie}}">连续模</text>
<view class="row"> <view class="row">
<view class="row-left"> <view class="row-left">
<text class="value">{{item.employeeName}} · {{item.reportDate}}</text> <text class="value">{{item.employeeName}} · {{item.reportDate}}</text>
@ -118,6 +119,10 @@
<text class="label">备注</text> <text class="label">备注</text>
<text class="value">{{item.reviewRemark}}</text> <text class="value">{{item.reviewRemark}}</text>
</view> </view>
<view wx:if="{{item.hasOverLimitNotice}}" class="over-limit-panel {{item.hasOverLimit ? 'danger' : 'warn'}}">
<text class="over-limit-title">{{item.overLimitSummary || (item.hasOverLimit ? '超额' : '无法校验')}}</text>
<text wx:if="{{item.overLimitReasons}}" class="over-limit-text">{{item.overLimitReasons}}</text>
</view>
<view class="salary-divider"></view> <view class="salary-divider"></view>
<view class="salary-row"> <view class="salary-row">
<text class="label">参考工资</text> <text class="label">参考工资</text>

View File

@ -63,13 +63,14 @@
data-id="{{item.id}}" data-id="{{item.id}}"
bindtap="toggleRecordDetail" bindtap="toggleRecordDetail"
> >
<text wx:if="{{item.isVoided}}" class="voided-watermark">作废</text> <text wx:if="{{item.hasOverLimit}}" class="over-limit-watermark {{item.watermarkClasses.overLimit}}">超额</text>
<text wx:elif="{{item.isModified}}" class="modified-watermark">更改</text> <text wx:if="{{item.isVoided}}" class="voided-watermark {{item.watermarkClasses.state}}">作废</text>
<text wx:if="{{item.isSystemAutoSubmitted}}" class="timeout-watermark">{{item.autoSubmitReason || '超时-系统自动提交'}}</text> <text wx:elif="{{item.isModified}}" class="modified-watermark {{item.watermarkClasses.state}}">更改</text>
<text wx:if="{{item.isCleaning}}" class="cleaning-watermark {{item.isSystemAutoSubmitted || item.isVoided || item.isModified ? 'lower-watermark' : ''}}">清洗</text> <text wx:if="{{item.isSystemAutoSubmitted}}" class="timeout-watermark {{item.watermarkClasses.timeout}}">{{item.autoSubmitReason || '超时-系统自动提交'}}</text>
<text wx:if="{{item.hasMisc}}" class="misc-watermark {{item.isSystemAutoSubmitted || item.isVoided || item.isModified ? 'lower-watermark' : ''}}">包含杂活</text> <text wx:if="{{item.isCleaning}}" class="cleaning-watermark {{item.watermarkClasses.cleaning}}">清洗</text>
<text wx:if="{{item.hasMultiPerson}}" class="multi-person-watermark {{item.isSystemAutoSubmitted || item.isVoided || item.isModified || item.hasMisc || item.isCleaning ? 'lower-watermark' : ''}}">多人协作</text> <text wx:if="{{item.hasMisc}}" class="misc-watermark {{item.watermarkClasses.misc}}">包含杂活</text>
<text wx:if="{{item.hasContinuousDie}}" class="continuous-die-watermark {{item.isSystemAutoSubmitted || item.isVoided || item.isModified || item.hasMisc || item.isCleaning || item.hasMultiPerson ? 'lower-watermark' : ''}} {{item.hasMultiPerson && (item.isSystemAutoSubmitted || item.isVoided || item.isModified || item.hasMisc || item.isCleaning) ? 'third-watermark' : ''}}">连续模</text> <text wx:if="{{item.hasMultiPerson}}" class="multi-person-watermark {{item.watermarkClasses.multiPerson}}">多人协作</text>
<text wx:if="{{item.hasContinuousDie}}" class="continuous-die-watermark {{item.watermarkClasses.continuousDie}}">连续模</text>
<view class="row"> <view class="row">
<view class="row-left"> <view class="row-left">
<text class="value">{{item.employeeName}} · {{item.reportDate}}</text> <text class="value">{{item.employeeName}} · {{item.reportDate}}</text>
@ -149,6 +150,16 @@
<text class="value">{{detail.changeoverCount || 0}}</text> <text class="value">{{detail.changeoverCount || 0}}</text>
</view> </view>
</view> </view>
<view wx:if="{{detail.hasOverLimitNotice}}" class="over-limit-panel {{detail.hasOverLimit ? 'danger' : 'warn'}}">
<text class="over-limit-title">{{detail.hasOverLimit ? '超额' : '无法校验'}}</text>
<text class="over-limit-text">{{detail.overLimitReason || '-'}}</text>
<view class="over-limit-grid">
<text>本次消耗 {{detail.overLimitCurrentReportQtyText}}</text>
<text>累计消耗 {{detail.overLimitCurrentCumulativeQtyText}}</text>
<text wx:if="{{detail.hasOverLimitMaxReportableQty}}">最大可报 {{detail.overLimitMaxReportableQtyText}}</text>
<text wx:if="{{detail.hasOverLimitPreviousGoodQty}}">前序可用 {{detail.overLimitPreviousGoodQtyText}}</text>
</view>
</view>
<view wx:if="{{detail.correctionPairs.length}}" class="correction-list detail-corrections"> <view wx:if="{{detail.correctionPairs.length}}" class="correction-list detail-corrections">
<view wx:for="{{detail.correctionPairs}}" wx:key="key" wx:for-item="pair" class="correction-pair"> <view wx:for="{{detail.correctionPairs}}" wx:key="key" wx:for-item="pair" class="correction-pair">
<text>{{pair.label}} </text> <text>{{pair.label}} </text>

View File

@ -326,6 +326,26 @@ Page({
changeoverCount: detail.changeoverCount || 0, changeoverCount: detail.changeoverCount || 0,
changeoverCountError: false, changeoverCountError: false,
remark: detail.remark || '', remark: detail.remark || '',
overLimitStatus: detail.overLimitStatus || 'not_checked',
overLimitType: detail.overLimitType || '',
overLimitReason: detail.overLimitReason || '',
overLimitCheckedAt: detail.overLimitCheckedAt || '',
overLimitCheckSource: detail.overLimitCheckSource || '',
overLimitBatchNo: detail.overLimitBatchNo || '',
overLimitProductGrossWeightKg: detail.overLimitProductGrossWeightKg ?? '',
overLimitIssuedWeightKg: detail.overLimitIssuedWeightKg ?? '',
overLimitMaxReportableQty: detail.overLimitMaxReportableQty ?? '',
overLimitPreviousGoodQty: detail.overLimitPreviousGoodQty ?? '',
overLimitCurrentCumulativeQty: detail.overLimitCurrentCumulativeQty ?? '',
overLimitCurrentReportQty: detail.overLimitCurrentReportQty ?? '',
overLimitMaxReportableQtyText: detail.overLimitMaxReportableQtyText || '-',
overLimitPreviousGoodQtyText: detail.overLimitPreviousGoodQtyText || '-',
overLimitCurrentCumulativeQtyText: detail.overLimitCurrentCumulativeQtyText || '-',
overLimitCurrentReportQtyText: detail.overLimitCurrentReportQtyText || '-',
hasOverLimitMaxReportableQty: !!detail.hasOverLimitMaxReportableQty,
hasOverLimitPreviousGoodQty: !!detail.hasOverLimitPreviousGoodQty,
hasOverLimit: !!detail.hasOverLimit,
hasOverLimitNotice: !!detail.hasOverLimitNotice,
deviceError: false, deviceError: false,
deviceNo: detail.deviceNo, deviceNo: detail.deviceNo,
deviceIndex, deviceIndex,

View File

@ -38,13 +38,14 @@
data-id="{{item.id}}" data-id="{{item.id}}"
bindtap="toggleReportDetail" bindtap="toggleReportDetail"
> >
<text wx:if="{{item.isVoided}}" class="voided-watermark">作废</text> <text wx:if="{{item.hasOverLimit}}" class="over-limit-watermark {{item.watermarkClasses.overLimit}}">超额</text>
<text wx:elif="{{item.isModified}}" class="modified-watermark">更改</text> <text wx:if="{{item.isVoided}}" class="voided-watermark {{item.watermarkClasses.state}}">作废</text>
<text wx:if="{{item.isSystemAutoSubmitted}}" class="timeout-watermark">{{item.autoSubmitReason || '超时-系统自动提交'}}</text> <text wx:elif="{{item.isModified}}" class="modified-watermark {{item.watermarkClasses.state}}">更改</text>
<text wx:if="{{item.isCleaning}}" class="cleaning-watermark {{item.isSystemAutoSubmitted || item.isVoided || item.isModified ? 'lower-watermark' : ''}}">清洗</text> <text wx:if="{{item.isSystemAutoSubmitted}}" class="timeout-watermark {{item.watermarkClasses.timeout}}">{{item.autoSubmitReason || '超时-系统自动提交'}}</text>
<text wx:if="{{item.hasMisc}}" class="misc-watermark {{item.isSystemAutoSubmitted || item.isVoided || item.isModified ? 'lower-watermark' : ''}}">包含杂活</text> <text wx:if="{{item.isCleaning}}" class="cleaning-watermark {{item.watermarkClasses.cleaning}}">清洗</text>
<text wx:if="{{item.hasMultiPerson}}" class="multi-person-watermark {{item.isSystemAutoSubmitted || item.isVoided || item.isModified || item.hasMisc || item.isCleaning ? 'lower-watermark' : ''}}">多人协作</text> <text wx:if="{{item.hasMisc}}" class="misc-watermark {{item.watermarkClasses.misc}}">包含杂活</text>
<text wx:if="{{item.hasContinuousDie}}" class="continuous-die-watermark {{item.isSystemAutoSubmitted || item.isVoided || item.isModified || item.hasMisc || item.isCleaning || item.hasMultiPerson ? 'lower-watermark' : ''}} {{item.hasMultiPerson && (item.isSystemAutoSubmitted || item.isVoided || item.isModified || item.hasMisc || item.isCleaning) ? 'third-watermark' : ''}}">连续模</text> <text wx:if="{{item.hasMultiPerson}}" class="multi-person-watermark {{item.watermarkClasses.multiPerson}}">多人协作</text>
<text wx:if="{{item.hasContinuousDie}}" class="continuous-die-watermark {{item.watermarkClasses.continuousDie}}">连续模</text>
<view class="row"> <view class="row">
<view class="row-left"> <view class="row-left">
<text class="value">{{item.employeeName}} · {{item.reportDate}}</text> <text class="value">{{item.employeeName}} · {{item.reportDate}}</text>
@ -158,6 +159,17 @@
</view> </view>
</view> </view>
<view wx:if="{{detail.hasOverLimitNotice}}" class="over-limit-panel {{detail.hasOverLimit ? 'danger' : 'warn'}}">
<text class="over-limit-title">{{detail.hasOverLimit ? '超额' : '无法校验'}}</text>
<text class="over-limit-text">{{detail.overLimitReason || '-'}}</text>
<view class="over-limit-grid">
<text>本次消耗 {{detail.overLimitCurrentReportQtyText}}</text>
<text>累计消耗 {{detail.overLimitCurrentCumulativeQtyText}}</text>
<text wx:if="{{detail.hasOverLimitMaxReportableQty}}">最大可报 {{detail.overLimitMaxReportableQtyText}}</text>
<text wx:if="{{detail.hasOverLimitPreviousGoodQty}}">前序可用 {{detail.overLimitPreviousGoodQtyText}}</text>
</view>
</view>
<view wx:if="{{detail.isMisc && !item.isVoided && item.canEdit}}" class="review-edit-panel misc-remark-panel"> <view wx:if="{{detail.isMisc && !item.isVoided && item.canEdit}}" class="review-edit-panel misc-remark-panel">
<text class="panel-title">杂活事项备注</text> <text class="panel-title">杂活事项备注</text>
<textarea <textarea

View File

@ -544,6 +544,34 @@ const formatWorkTime = minutes => {
return `${Math.round(safeMinutes * 100) / 100}分钟` return `${Math.round(safeMinutes * 100) / 100}分钟`
} }
const snapshotValueText = value => (
value === null || value === undefined || value === '' ? '-' : String(value)
)
const hasSnapshotValue = value => (
value !== null && value !== undefined && value !== ''
)
const watermarkClassAt = index => (
['', 'lower-watermark', 'third-watermark', 'fourth-watermark', 'fifth-watermark', 'sixth-watermark'][index] || 'sixth-watermark'
)
const buildWatermarkClasses = flags => {
const classes = {}
let index = 0
const assign = (key, enabled) => {
classes[key] = enabled ? watermarkClassAt(index++) : ''
}
assign('overLimit', flags.hasOverLimit)
assign('state', flags.hasState)
assign('timeout', flags.isSystemAutoSubmitted)
assign('cleaning', flags.isCleaning)
assign('misc', flags.hasMisc)
assign('multiPerson', flags.hasMultiPerson)
assign('continuousDie', flags.hasContinuousDie)
return classes
}
const toCamelAllocation = row => ({ const toCamelAllocation = row => ({
allocationDate: row.allocation_date || '', allocationDate: row.allocation_date || '',
dayMinutes: Number(row.day_minutes || 0), dayMinutes: Number(row.day_minutes || 0),
@ -577,6 +605,7 @@ const toCamelReportItem = row => {
const beatComparison = noOutputMetric ? classifyBeat(0, 0) : classifyBeat(actualBeat, standardBeat) const beatComparison = noOutputMetric ? classifyBeat(0, 0) : classifyBeat(actualBeat, standardBeat)
const workloadComparison = noOutputMetric ? classifyWorkload(0, 0) : classifyWorkload(goodQty, standardWorkload) const workloadComparison = noOutputMetric ? classifyWorkload(0, 0) : classifyWorkload(goodQty, standardWorkload)
const corrections = row.corrections || {} const corrections = row.corrections || {}
const overLimitStatus = row.over_limit_status || 'not_checked'
const correctionPairs = [ const correctionPairs = [
correctionPair(corrections, 'device_no', '设备号', row.device_no), correctionPair(corrections, 'device_no', '设备号', row.device_no),
correctionPair(corrections, 'project_no', '项目号', row.project_no), correctionPair(corrections, 'project_no', '项目号', row.project_no),
@ -630,6 +659,26 @@ const toCamelReportItem = row => {
workloadCompareClass: workloadComparison.className, workloadCompareClass: workloadComparison.className,
workloadReason: workloadComparison.reason, workloadReason: workloadComparison.reason,
remark: row.remark || '', remark: row.remark || '',
overLimitStatus,
overLimitType: row.over_limit_type || '',
overLimitReason: row.over_limit_reason || '',
overLimitCheckedAt: row.over_limit_checked_at || '',
overLimitCheckSource: row.over_limit_check_source || '',
overLimitBatchNo: row.over_limit_batch_no || '',
overLimitProductGrossWeightKg: row.over_limit_product_gross_weight_kg ?? '',
overLimitIssuedWeightKg: row.over_limit_issued_weight_kg ?? '',
overLimitMaxReportableQty: row.over_limit_max_reportable_qty ?? '',
overLimitPreviousGoodQty: row.over_limit_previous_good_qty ?? '',
overLimitCurrentCumulativeQty: row.over_limit_current_cumulative_qty ?? '',
overLimitCurrentReportQty: row.over_limit_current_report_qty ?? '',
overLimitMaxReportableQtyText: snapshotValueText(row.over_limit_max_reportable_qty),
overLimitPreviousGoodQtyText: snapshotValueText(row.over_limit_previous_good_qty),
overLimitCurrentCumulativeQtyText: snapshotValueText(row.over_limit_current_cumulative_qty),
overLimitCurrentReportQtyText: snapshotValueText(row.over_limit_current_report_qty),
hasOverLimitMaxReportableQty: hasSnapshotValue(row.over_limit_max_reportable_qty),
hasOverLimitPreviousGoodQty: hasSnapshotValue(row.over_limit_previous_good_qty),
hasOverLimit: overLimitStatus === 'exceeded',
hasOverLimitNotice: overLimitStatus === 'exceeded' || overLimitStatus === 'uncheckable',
corrections, corrections,
correctionPairs, correctionPairs,
hasCorrections: correctionPairs.length > 0, hasCorrections: correctionPairs.length > 0,
@ -673,6 +722,7 @@ const toCamelReport = row => {
const hasMisc = items.some(item => item.isMisc) const hasMisc = items.some(item => item.isMisc)
const hasContinuousDie = items.some(item => item.isContinuousDie) const hasContinuousDie = items.some(item => item.isContinuousDie)
const hasMultiPerson = items.some(item => item.isMultiPerson) const hasMultiPerson = items.some(item => item.isMultiPerson)
const hasOverLimit = !!row.has_over_limit || items.some(item => item.hasOverLimit)
const totalDefect = Math.round(items.reduce((sum, item) => sum + Number(item.defectQty || 0), 0) * 100) / 100 const totalDefect = Math.round(items.reduce((sum, item) => sum + Number(item.defectQty || 0), 0) * 100) / 100
const corrections = row.corrections || {} const corrections = row.corrections || {}
const reportCorrectionPairs = [ const reportCorrectionPairs = [
@ -690,6 +740,15 @@ const toCamelReport = row => {
label: `${segment.displayName} ${pair.label}`, label: `${segment.displayName} ${pair.label}`,
})) }))
))) )))
const watermarkClasses = buildWatermarkClasses({
hasOverLimit,
hasState: !!row.is_voided || !!row.is_modified,
isSystemAutoSubmitted: !!row.is_system_auto_submitted,
isCleaning,
hasMisc,
hasMultiPerson,
hasContinuousDie,
})
return { return {
id: row.id, id: row.id,
attendancePointName: row.attendance_point_name || '', attendancePointName: row.attendance_point_name || '',
@ -715,6 +774,8 @@ const toCamelReport = row => {
submittedAtText: util.formatTime(row.submitted_at), submittedAtText: util.formatTime(row.submitted_at),
isSystemAutoSubmitted: !!row.is_system_auto_submitted, isSystemAutoSubmitted: !!row.is_system_auto_submitted,
autoSubmitReason: row.auto_submit_reason || '超时-系统自动提交', autoSubmitReason: row.auto_submit_reason || '超时-系统自动提交',
hasOverLimit,
overLimitSummary: row.over_limit_summary || '',
isMultiPersonAssistant: !!row.is_multi_person_assistant, isMultiPersonAssistant: !!row.is_multi_person_assistant,
multiPersonSourceReportId: row.multi_person_source_report_id || null, multiPersonSourceReportId: row.multi_person_source_report_id || null,
isVoided: !!row.is_voided, isVoided: !!row.is_voided,
@ -735,6 +796,7 @@ const toCamelReport = row => {
hasMisc, hasMisc,
hasContinuousDie, hasContinuousDie,
hasMultiPerson, hasMultiPerson,
watermarkClasses,
metrics: { metrics: {
...toCamelMetrics(row.metrics || {}), ...toCamelMetrics(row.metrics || {}),
totalDefect, totalDefect,
@ -1543,9 +1605,28 @@ const listDashboard = async (filters = {}) => {
}) })
return toCamelPage(data, row => { return toCamelPage(data, row => {
const isMisc = !!row.is_misc || isMiscRow(row) const isMisc = !!row.is_misc || isMiscRow(row)
const noOutputMetric = isMisc || isCleaningRow(row) const isCleaning = isCleaningRow(row)
const isContinuousDie = isContinuousDieRow(row)
const isMultiPerson = isMultiPersonRow(row)
const hasOverLimit = !!row.has_over_limit
const correctionPairs = (row.correction_pairs || []).map(pair => ({
key: pair.key,
label: pair.label,
oldValue: correctionDisplayValue(pair.old_value),
newValue: correctionDisplayValue(pair.new_value),
}))
const noOutputMetric = isMisc || isCleaning
const beatComparison = noOutputMetric ? classifyBeat(0, 0) : classifyBeat(row.actual_beat, row.standard_beat) const beatComparison = noOutputMetric ? classifyBeat(0, 0) : classifyBeat(row.actual_beat, row.standard_beat)
const workloadComparison = noOutputMetric ? classifyWorkload(0, 0) : classifyWorkload(row.total_good_qty, row.expected_workload) const workloadComparison = noOutputMetric ? classifyWorkload(0, 0) : classifyWorkload(row.total_good_qty, row.expected_workload)
const watermarkClasses = buildWatermarkClasses({
hasOverLimit,
hasState: !!row.is_voided || correctionPairs.length > 0,
isSystemAutoSubmitted: !!row.is_system_auto_submitted,
isCleaning,
hasMisc: isMisc,
hasMultiPerson: isMultiPerson,
hasContinuousDie: isContinuousDie,
})
return { return {
id: row.id, id: row.id,
attendancePointName: row.attendance_point_name || '', attendancePointName: row.attendance_point_name || '',
@ -1558,13 +1639,13 @@ const listDashboard = async (filters = {}) => {
processDisplayName: moldDisplayName(row.product_name, row.process_name, row.stamping_method), processDisplayName: moldDisplayName(row.product_name, row.process_name, row.stamping_method),
rawMaterialBatchNo: row.raw_material_batch_no || '', rawMaterialBatchNo: row.raw_material_batch_no || '',
stampingMethod: row.stamping_method || '', stampingMethod: row.stamping_method || '',
isCleaning: isCleaningRow(row), isCleaning,
isContinuousDie: isContinuousDieRow(row), isContinuousDie,
changeoverCount: row.changeover_count || 0, changeoverCount: row.changeover_count || 0,
isMisc, isMisc,
isSystemAutoSubmitted: !!row.is_system_auto_submitted, isSystemAutoSubmitted: !!row.is_system_auto_submitted,
isVoided: !!row.is_voided, isVoided: !!row.is_voided,
isMultiPerson: isMultiPersonRow(row), isMultiPerson,
isMultiPersonAssistant: !!row.is_multi_person_assistant, isMultiPersonAssistant: !!row.is_multi_person_assistant,
workerType: row.worker_type || '正式工', workerType: row.worker_type || '正式工',
reportCount: row.report_count, reportCount: row.report_count,
@ -1584,6 +1665,11 @@ const listDashboard = async (filters = {}) => {
standardBeat: row.standard_beat, standardBeat: row.standard_beat,
processUnitPriceYuan: row.process_unit_price_yuan || 0, processUnitPriceYuan: row.process_unit_price_yuan || 0,
referenceWage: round2(row.reference_wage || 0), referenceWage: round2(row.reference_wage || 0),
hasOverLimit,
overLimitSummary: row.over_limit_summary || '',
overLimitReasons: row.over_limit_reasons || '',
hasOverLimitNotice: !!(row.over_limit_summary || row.over_limit_reasons),
watermarkClasses,
expectedWorkload: row.expected_workload, expectedWorkload: row.expected_workload,
paceRate: row.pace_rate, paceRate: row.pace_rate,
workloadRate: row.workload_rate, workloadRate: row.workload_rate,
@ -1594,12 +1680,7 @@ const listDashboard = async (filters = {}) => {
workloadCompareClass: workloadComparison.className, workloadCompareClass: workloadComparison.className,
workloadReason: workloadComparison.reason, workloadReason: workloadComparison.reason,
reviewRemark: row.review_remark || '', reviewRemark: row.review_remark || '',
correctionPairs: (row.correction_pairs || []).map(pair => ({ correctionPairs,
key: pair.key,
label: pair.label,
oldValue: correctionDisplayValue(pair.old_value),
newValue: correctionDisplayValue(pair.new_value),
})),
} }
}) })
} }