chore: initialize mini program frontend
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
const api = require('../../utils/api')
|
||||
|
||||
Page({
|
||||
data: {
|
||||
report: null,
|
||||
},
|
||||
async onLoad(options) {
|
||||
try {
|
||||
const report = await api.getReport(options.reportId)
|
||||
this.setData({
|
||||
report: {
|
||||
...report,
|
||||
itemResults: this.buildItemResults(report),
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
wx.showToast({ title: error.message, icon: 'none' })
|
||||
}
|
||||
},
|
||||
round1(value) {
|
||||
return Math.round(Number(value || 0) * 10) / 10
|
||||
},
|
||||
round2(value) {
|
||||
return Math.round(Number(value || 0) * 100) / 100
|
||||
},
|
||||
buildCompareText(rate, fastLabel, slowLabel) {
|
||||
return `${rate > 0 ? slowLabel : fastLabel}${Math.abs(this.round1(rate))}%`
|
||||
},
|
||||
buildWorkloadText(rate) {
|
||||
return `${rate >= 0 ? '工作量大于标准工作量' : '工作量小于标准工作量'}${Math.abs(this.round1(rate))}%`
|
||||
},
|
||||
buildItemResults(report) {
|
||||
return (report.items || []).map((item, index) => {
|
||||
if (item.isMisc) {
|
||||
return {
|
||||
key: `${item.id || index}`,
|
||||
title: '处理杂活',
|
||||
subtitle: `考勤点 ${item.attendancePointName || report.attendancePointName || '-'} · 工序 ${item.process || '-'} · 冲压方式 ${item.stampingMethod || '-'}`,
|
||||
goodQty: 0,
|
||||
defectQty: 0,
|
||||
workTimeText: item.workTimeText || '-',
|
||||
resultText: '处理杂活工时已提交管理员审核,杂活事项由管理员备注留痕',
|
||||
goodResult: true,
|
||||
isMisc: true,
|
||||
isMultiPerson: !!item.isMultiPerson,
|
||||
isContinuousDie: !!item.isContinuousDie,
|
||||
changeoverCount: item.changeoverCount || 0,
|
||||
}
|
||||
}
|
||||
if (item.isCleaning) {
|
||||
return {
|
||||
key: `${item.id || index}`,
|
||||
title: `清洗 · ${item.displayName || item.productName || '-'}`,
|
||||
subtitle: `考勤点 ${item.attendancePointName || report.attendancePointName || '-'} · 项目 ${item.projectNo || '-'} · 工序 ${item.process || '-'} · 冲压方式 ${item.stampingMethod || '-'}`,
|
||||
goodQty: this.round2(item.goodQty || 0),
|
||||
defectQty: 0,
|
||||
resultText: `清洗数量 ${this.round2(item.goodQty || 0)},已提交管理员审核`,
|
||||
goodResult: true,
|
||||
isCleaning: true,
|
||||
isMultiPerson: !!item.isMultiPerson,
|
||||
isContinuousDie: !!item.isContinuousDie,
|
||||
changeoverCount: item.changeoverCount || 0,
|
||||
}
|
||||
}
|
||||
const goodQty = Number(item.goodQty || 0)
|
||||
const defectQty = Number(item.defectQty || 0)
|
||||
const outputQty = goodQty + defectQty
|
||||
const actualBeat = outputQty > 0 ? Number(item.allocatedMinutes || 0) * 60 / outputQty : 0
|
||||
const standardBeat = Number(item.standardBeat || 0)
|
||||
const standardWorkload = api.calculateStandardWorkload(item.allocatedMinutes, standardBeat) || Number(item.standardWorkload || 0)
|
||||
const paceRate = standardBeat > 0 ? (actualBeat - standardBeat) / standardBeat * 100 : 0
|
||||
const workloadRate = standardWorkload > 0 ? (goodQty - standardWorkload) / standardWorkload * 100 : 0
|
||||
const paceText = this.buildCompareText(paceRate, '节拍快于标准节拍', '节拍慢于标准节拍')
|
||||
const workloadText = this.buildWorkloadText(workloadRate)
|
||||
const overStandardAbnormal = paceRate < -30 || workloadRate > 30
|
||||
const underStandardAbnormal = paceRate > 0 || workloadRate < 0
|
||||
const abnormal = overStandardAbnormal || underStandardAbnormal
|
||||
const goodResult = !abnormal
|
||||
const suffix = overStandardAbnormal
|
||||
? '数据明显超出标准,请自我核对一下是不是报工时填错。'
|
||||
: (goodResult ? '今天真的很棒呢!' : '后续需要加油喽!')
|
||||
return {
|
||||
key: `${item.id || index}`,
|
||||
title: `${item.deviceNo || '-'} · ${item.displayName || item.productName || '-'}`,
|
||||
subtitle: `考勤点 ${item.attendancePointName || report.attendancePointName || '-'} · 项目 ${item.projectNo || '-'} · 工序 ${item.process || '-'} · 冲压方式 ${item.stampingMethod || '-'}`,
|
||||
actualBeat: this.round2(actualBeat),
|
||||
standardBeat: this.round2(standardBeat),
|
||||
goodQty: this.round2(goodQty),
|
||||
defectQty: this.round2(defectQty),
|
||||
standardWorkload: this.round1(standardWorkload),
|
||||
resultText: `今日${paceText},今日${workloadText},${suffix}`,
|
||||
goodResult,
|
||||
overStandardAbnormal: abnormal,
|
||||
isMultiPerson: !!item.isMultiPerson,
|
||||
isContinuousDie: !!item.isContinuousDie,
|
||||
changeoverCount: item.changeoverCount || 0,
|
||||
}
|
||||
})
|
||||
},
|
||||
goRecords() {
|
||||
wx.redirectTo({
|
||||
url: '/pages/records/records',
|
||||
})
|
||||
},
|
||||
goHome() {
|
||||
wx.reLaunch({
|
||||
url: '/pages/index/index',
|
||||
})
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"navigationStyle": "custom",
|
||||
"disableSwipeBack": true
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<view class="page safe-bottom result-page">
|
||||
<view class="result-nav">
|
||||
<text class="result-nav-title">报工结果</text>
|
||||
</view>
|
||||
|
||||
<view class="header">
|
||||
<text class="title">报工成功</text>
|
||||
<text class="subtitle">已提交管理员审核</text>
|
||||
</view>
|
||||
|
||||
<block wx:if="{{report}}">
|
||||
<view class="card">
|
||||
<text wx:if="{{report.hasMisc}}" class="misc-watermark">包含杂活</text>
|
||||
<text wx:if="{{report.hasMultiPerson}}" class="multi-person-watermark {{report.hasMisc ? 'lower-watermark' : ''}}">多人协作</text>
|
||||
<text wx:if="{{report.hasContinuousDie}}" class="continuous-die-watermark {{report.hasMisc || report.hasMultiPerson ? 'lower-watermark' : ''}} {{report.hasMisc && report.hasMultiPerson ? 'third-watermark' : ''}}">连续模</text>
|
||||
<text class="label">报工日期</text>
|
||||
<text class="value">{{report.reportDate}}</text>
|
||||
<text class="subtitle">考勤点 {{report.attendancePointName || '-'}}</text>
|
||||
<text class="subtitle">{{report.metrics.shiftDistributionText}}</text>
|
||||
<view class="divider"></view>
|
||||
<view
|
||||
wx:for="{{report.itemResults}}"
|
||||
wx:key="key"
|
||||
wx:for-item="result"
|
||||
class="result-item {{result.goodResult ? 'good' : (result.overStandardAbnormal ? 'danger' : 'warn')}} {{result.isMultiPerson || result.isContinuousDie ? 'marked-result' : ''}} {{result.isMultiPerson && result.isContinuousDie ? 'stacked-result' : ''}}"
|
||||
>
|
||||
<text wx:if="{{result.isMultiPerson}}" class="result-multi-stamp">多人协作</text>
|
||||
<text wx:if="{{result.isContinuousDie}}" class="result-continuous-stamp {{result.isMultiPerson ? 'lower-result-stamp' : ''}}">连续模</text>
|
||||
<text class="result-title">{{result.title}}</text>
|
||||
<text class="result-subtitle">{{result.subtitle}}</text>
|
||||
<text class="result-text">{{result.resultText}}</text>
|
||||
<view wx:if="{{result.isMisc}}" class="result-metrics">
|
||||
<view>
|
||||
<text class="label">工时</text>
|
||||
<text class="value">{{result.workTimeText}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view wx:elif="{{result.isCleaning}}" class="result-metrics">
|
||||
<view>
|
||||
<text class="label">清洗数量</text>
|
||||
<text class="value">{{result.goodQty}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view wx:else class="result-metrics">
|
||||
<view>
|
||||
<text class="label">实际节拍</text>
|
||||
<text class="value">{{result.actualBeat}} 秒/件</text>
|
||||
</view>
|
||||
<view>
|
||||
<text class="label">标准节拍</text>
|
||||
<text class="value">{{result.standardBeat}} 秒/件</text>
|
||||
</view>
|
||||
<view>
|
||||
<text class="label">成品数量</text>
|
||||
<text class="value">{{result.goodQty}}</text>
|
||||
</view>
|
||||
<view>
|
||||
<text class="label">标准工作量</text>
|
||||
<text class="value">{{result.standardWorkload}}</text>
|
||||
</view>
|
||||
<view wx:if="{{result.isContinuousDie}}">
|
||||
<text class="label">换料次数</text>
|
||||
<text class="value">{{result.changeoverCount || 0}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="button-row">
|
||||
<button class="btn secondary full" bindtap="goRecords">查看记录</button>
|
||||
<button class="btn primary full" bindtap="goHome">返回首页</button>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
@@ -0,0 +1,125 @@
|
||||
.result-page {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.result-nav {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 176rpx;
|
||||
margin: 0 -24rpx 22rpx;
|
||||
padding-top: 88rpx;
|
||||
border-bottom: 1rpx solid rgba(213, 222, 235, 0.9);
|
||||
background: rgba(247, 248, 250, 0.96);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.result-nav-title {
|
||||
color: #111827;
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.result-item {
|
||||
position: relative;
|
||||
display: block;
|
||||
margin-top: 18rpx;
|
||||
padding: 20rpx;
|
||||
border-radius: 16rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.result-item.marked-result {
|
||||
padding-top: 62rpx;
|
||||
}
|
||||
|
||||
.result-item.stacked-result {
|
||||
padding-top: 104rpx;
|
||||
}
|
||||
|
||||
.result-item .result-multi-stamp {
|
||||
position: absolute;
|
||||
right: 16rpx;
|
||||
top: 14rpx;
|
||||
padding: 6rpx 12rpx;
|
||||
border: 2rpx solid rgba(217, 119, 6, 0.62);
|
||||
border-radius: 10rpx;
|
||||
color: rgba(154, 74, 5, 0.88);
|
||||
background: rgba(255, 247, 232, 0.92);
|
||||
font-size: 22rpx;
|
||||
font-weight: 900;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.result-continuous-stamp {
|
||||
position: absolute;
|
||||
right: 16rpx;
|
||||
top: 14rpx;
|
||||
padding: 6rpx 12rpx;
|
||||
border: 2rpx solid rgba(217, 119, 6, 0.62);
|
||||
border-radius: 10rpx;
|
||||
color: rgba(154, 74, 5, 0.88);
|
||||
background: rgba(255, 247, 232, 0.92);
|
||||
font-size: 22rpx;
|
||||
font-weight: 900;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.result-continuous-stamp.lower-result-stamp {
|
||||
top: 56rpx;
|
||||
}
|
||||
|
||||
.result-item.good {
|
||||
border: 1rpx solid #bfe8d4;
|
||||
background: #eefaf4;
|
||||
color: #087443;
|
||||
}
|
||||
|
||||
.result-item.warn {
|
||||
border: 1rpx solid #f7d7a8;
|
||||
background: #fff7e8;
|
||||
color: #9a4a05;
|
||||
}
|
||||
|
||||
.result-item.danger {
|
||||
border: 1rpx solid #f1b4b2;
|
||||
background: #fff1f0;
|
||||
color: #b42318;
|
||||
}
|
||||
|
||||
.result-title {
|
||||
display: block;
|
||||
color: #162232;
|
||||
font-size: 28rpx;
|
||||
font-weight: 800;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.result-subtitle {
|
||||
display: block;
|
||||
margin-top: 8rpx;
|
||||
color: #667085;
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.result-text {
|
||||
display: block;
|
||||
margin-top: 16rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.result-metrics {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 14rpx 18rpx;
|
||||
margin-top: 18rpx;
|
||||
padding-top: 18rpx;
|
||||
border-top: 1rpx solid rgba(102, 112, 133, 0.16);
|
||||
}
|
||||
Reference in New Issue
Block a user