477 lines
16 KiB
Vue
477 lines
16 KiB
Vue
<template>
|
||
<view class="container">
|
||
<!-- 搜索框区域 -->
|
||
<view class="search-box">
|
||
<view class="input-box">
|
||
<input type="text" v-model="searchCode" placeholder="请输入或扫码" placeholder-class="placeholder"
|
||
@confirm="getToolInfo" />
|
||
<view class="scan-btn" @tap="openScan">
|
||
<u-icon name="scan" size="40" color="#333"></u-icon>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 设备信息展示区域 -->
|
||
<view class="tool-list">
|
||
<view v-for="(tool, index) in toolList" :key="index" class="tool-info">
|
||
<view class="title">设备信息</view>
|
||
<view class="divider"></view>
|
||
|
||
<view class="info-item">
|
||
<text class="label">设备编号:</text>
|
||
<text class="value">{{ tool.eqmtNo }}</text>
|
||
</view>
|
||
|
||
<view class="info-item">
|
||
<text class="label">设备名称:</text>
|
||
<text class="value">{{ tool.eqmtName }}</text>
|
||
</view>
|
||
|
||
<view class="info-item">
|
||
<text class="label">设备型号:</text>
|
||
<text class="value">{{ tool.specName }}</text>
|
||
</view>
|
||
|
||
<view class="info-item">
|
||
<text class="label">磨刀次数:</text>
|
||
<text class="value">{{ tool.shareNum }}</text>
|
||
</view>
|
||
|
||
<view class="info-item">
|
||
<text class="label">使用时间:</text>
|
||
<text class="value">{{ tool.useDtime }}H</text>
|
||
</view>
|
||
|
||
<view class="info-item status-row">
|
||
<view class="status-wrapper">
|
||
<text class="label">当前状态:</text>
|
||
<text class="value">{{ statusMapping[tool.status] }}</text>
|
||
</view>
|
||
<u-button type="primary" size="mini" @click="handleOperate(tool)">操作</u-button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 底部弹出窗体 -->
|
||
<u-popup v-model="showPopup" mode="bottom" :border-radius="10" :closeable="true" @close="closePopup"
|
||
height="800rpx">
|
||
<view class="popup-content">
|
||
<view class="popup-title">操作</view>
|
||
|
||
<!-- 表单内容 -->
|
||
<u-form :model="formData" :rules="rules" ref="formData" label-width="200rpx">
|
||
<u-form-item label="当前状态" prop="status">
|
||
<text>{{ currentTool && statusMapping[currentTool.status] }}</text>
|
||
</u-form-item>
|
||
|
||
<u-form-item label="确认去向" prop="status" required>
|
||
<text @click="show = true">{{ currentTool && statusMapping[formData.status] || '请选择去向' }}</text>
|
||
<u-select v-model="show" :list="getStatusOptions" placeholder="请选择去向" @confirm="confirm"
|
||
@cancel="show = false" confirm-text="确定" cancel-text="取消"></u-select>
|
||
</u-form-item>
|
||
|
||
<template v-if="currentTool && statusMapping[currentTool.status] === '上机'">
|
||
<u-form-item label="切片数量" prop="cutNum" required>
|
||
<u-input v-model="formData.cutNum" type="number" placeholder="请输入切片数量"></u-input>
|
||
</u-form-item>
|
||
|
||
<u-form-item label="下机时间" prop="downDtime" required>
|
||
<jnpf-date-time type="datetime" v-model="formData.downDtime"></jnpf-date-time>
|
||
</u-form-item>
|
||
|
||
<u-form-item label="使用时间(h)" prop="useDtime">
|
||
<!-- 强制数值化,默认/回退为 0 -->
|
||
<u-input v-model="formData.useDtime" type="number" placeholder="使用时间"
|
||
@input="onUseDtimeInput"></u-input>
|
||
</u-form-item>
|
||
</template>
|
||
</u-form>
|
||
|
||
<!-- 底部按钮 -->
|
||
<view class="popup-footer">
|
||
<u-button @click="showPopup = false" :custom-style="{ marginRight: '20rpx' }">取消</u-button>
|
||
<u-button type="primary" @click="saveOperation">保存</u-button>
|
||
</view>
|
||
</view>
|
||
</u-popup>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
getEqmtBaseList,
|
||
saveEqmtBase
|
||
} from '@/api/yys/EqmtBase.js';
|
||
export default {
|
||
data() {
|
||
return {
|
||
showPopup: false, // 控制弹出层显示
|
||
searchCode: '',
|
||
toolList: [], // 替换原来的 toolInfo
|
||
currentTool: null, // 当前操作的设备
|
||
showTimePicker: false, // 控制时间选择器显示
|
||
formData: {
|
||
status: "",
|
||
cutNum: 0,
|
||
downDtime: "",
|
||
useDtime: 0, // 默认数字 0
|
||
},
|
||
go: {
|
||
'上机': ['下机', '磨光', '入库'],
|
||
'下机': ['上机', '磨光', '入库'],
|
||
'磨光': ['上机', '入库'],
|
||
'入库': ['上机', '磨光']
|
||
},
|
||
statusMapping: {
|
||
10: "上机",
|
||
11: "下机",
|
||
20: "磨光",
|
||
30: "入库",
|
||
50: "报废"
|
||
},
|
||
show: false, // 控制状态选择弹出层
|
||
rules: {
|
||
targetStatus: [{
|
||
required: true,
|
||
message: '请选择确认去向',
|
||
trigger: 'change'
|
||
}],
|
||
sliceCount: [{
|
||
required: true,
|
||
message: '请输入切片数量',
|
||
trigger: 'blur'
|
||
}],
|
||
offTime: [{
|
||
required: true,
|
||
message: '请选择下机时间',
|
||
trigger: 'change'
|
||
}]
|
||
},
|
||
}
|
||
},
|
||
computed: {
|
||
getStatusOptions() {
|
||
const currentStatus = this.currentTool?.status || '';
|
||
const currentStatusText = this.statusMapping[currentStatus] || "";
|
||
console.log('options:', currentStatusText, this.go[currentStatusText]);
|
||
|
||
return this.go[currentStatusText] && this.go[currentStatusText].map(item => ({
|
||
label: item,
|
||
value: this.getStatusKey(item)
|
||
})) || [];
|
||
}
|
||
},
|
||
methods: {
|
||
// 打开扫码
|
||
openScan() {
|
||
uni.scanCode({
|
||
scanType: ['qrCode', 'barCode'],
|
||
success: (res) => {
|
||
this.searchCode = res.result;
|
||
this.getToolInfo();
|
||
|
||
}
|
||
});
|
||
},
|
||
|
||
// 获取设备信息
|
||
async getToolInfo() {
|
||
try {
|
||
const params = {
|
||
eqmtNo: this.searchCode,
|
||
currentPage: 1,
|
||
pageSize: 10
|
||
};
|
||
const res = await getEqmtBaseList(params);
|
||
console.log('设备信息:', res);
|
||
|
||
if (res.code === 200 && res.data.list.length > 0) {
|
||
this.toolList = res.data.list;
|
||
console.log('设备列表:', this.toolList);
|
||
} else {
|
||
uni.showToast({
|
||
title: '未找到设备信息',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
} catch (error) {
|
||
console.error('获取设备信息失败:', error);
|
||
uni.showToast({
|
||
title: '获取设备信息失败',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
},
|
||
isOnMachine() {
|
||
const raw = this.currentTool?.status;
|
||
const text = this.statusMapping[raw];
|
||
return text === '上机';
|
||
},
|
||
// 操作按钮点击
|
||
handleOperate(tool) {
|
||
this.$set(this, 'currentTool', tool);
|
||
this.showPopup = true;
|
||
|
||
if (this.isOnMachine()) {
|
||
// 下机时间默认当前时间戳
|
||
this.formData.downDtime = Date.now();
|
||
// 使用时间按上机时间计算(小时,向下取整),不可解析则回退为 0 取整
|
||
const upTime = Number(this.currentTool.upDtime);
|
||
const downTime = Number(this.formData.downDtime);
|
||
const hours = (downTime - upTime) / (1000 * 60 * 60);
|
||
|
||
this.formData.useDtime = Number.isFinite(hours) ? Math.floor(hours) : 0;
|
||
}
|
||
},
|
||
|
||
closePopup() {
|
||
if (this.isClosing) return;
|
||
this.isClosing = true;
|
||
this.showPopup = false;
|
||
this.resetForm();
|
||
this.currentTool = null;
|
||
|
||
// 统一在关闭时刷新一次列表(保存成功、手动关闭都走这里)
|
||
this.getToolInfo();
|
||
|
||
this.$nextTick(() => {
|
||
this.isClosing = false;
|
||
});
|
||
},
|
||
|
||
|
||
|
||
statusConfirm(value) {
|
||
this.formData.targetStatus = value;
|
||
},
|
||
|
||
timeConfirm(value) {
|
||
this.formData.offTime = value;
|
||
},
|
||
|
||
resetForm() {
|
||
this.formData = {
|
||
status: "",
|
||
cutNum: "",
|
||
downDtime: "",
|
||
useDtime: 0, // 重置为数字 0
|
||
};
|
||
// 移除这里的查询,避免重复
|
||
},
|
||
getStatusKey(label) {
|
||
const entry = Object.entries(this.statusMapping).find(([key, val]) => val === label);
|
||
return entry ? Number(entry[0]) : null;
|
||
},
|
||
confirm(value) {
|
||
// u-select 返回的数组,取首个选中项
|
||
const selected = value[0]?.value;
|
||
// 若是文本,转换为数值 key;若已是数值,直接使用
|
||
this.formData.status = typeof selected === 'number' ? selected : this.getStatusKey(selected);
|
||
this.show = false;
|
||
console.log('value:', value, 'selected status key:', this.formData.status);
|
||
},
|
||
formatDate(dateString) {
|
||
if (!dateString) return "";
|
||
const date = new Date(dateString);
|
||
const year = date.getFullYear();
|
||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||
const day = String(date.getDate()).padStart(2, '0');
|
||
const hours = String(date.getHours()).padStart(2, '0');
|
||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||
},
|
||
// 保存操作
|
||
async saveOperation() {
|
||
try {
|
||
if(!this.formData.status) {
|
||
uni.showToast({
|
||
title: '请选择去向',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
// await this.$refs.formData.validate();
|
||
// 构造保存参数
|
||
const params = {
|
||
id: this.currentTool.id,
|
||
status: this.formData.status, // 去向
|
||
useDtime: this.formData.useDtime,
|
||
cutNum: this.formData.cutNum,
|
||
downDtime: this.formData.downDtime,//当前为时间戳
|
||
eqmtNo: this.currentTool.eqmtNo
|
||
};
|
||
console.log('保存参数:', params);
|
||
const res = await saveEqmtBase(params);
|
||
if (res.code === 200) {
|
||
uni.showToast({
|
||
title: res.msg || '保存成功',
|
||
icon: 'success'
|
||
});
|
||
// 仅关闭弹窗,查询在 @close -> closePopup 中统一触发一次
|
||
this.showPopup = false;
|
||
} else {
|
||
uni.showToast({
|
||
title: res.msg || '保存失败',
|
||
icon: 'error'
|
||
});
|
||
}
|
||
} catch (error) {
|
||
console.error('保存操作失败:', error);
|
||
// uni.showToast({
|
||
// title: '保存失败',
|
||
// icon: 'none'
|
||
// });
|
||
}
|
||
}
|
||
},
|
||
async mounted() {
|
||
// 页面加载时可以初始化数据
|
||
|
||
},
|
||
watch: {
|
||
'formData.downDtime'(newVal) {
|
||
if (this.isOnMachine()) {
|
||
// 使用时间按上机时间计算(小时,向下取整),不可解析则回退为 0 取整
|
||
const upTime = Number(this.currentTool.upDtime);
|
||
const downTime = Number(this.formData.downDtime);
|
||
const hours = (downTime - upTime) / (1000 * 60 * 60);
|
||
|
||
this.formData.useDtime = Number.isFinite(hours) ? Math.floor(hours) : 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.container {
|
||
padding: 20rpx;
|
||
background-color: #F8F8F8;
|
||
min-height: 100vh;
|
||
}
|
||
|
||
.search-box {
|
||
padding: 20rpx;
|
||
background-color: #fff;
|
||
border-radius: 8rpx;
|
||
|
||
.input-box {
|
||
display: flex;
|
||
align-items: center;
|
||
background-color: #F5F5F5;
|
||
padding: 10rpx 20rpx;
|
||
border-radius: 8rpx;
|
||
|
||
input {
|
||
flex: 1;
|
||
height: 60rpx;
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
.scan-btn {
|
||
padding-left: 20rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
}
|
||
}
|
||
|
||
.tool-list {
|
||
.tool-info {
|
||
margin-bottom: 20rpx;
|
||
background-color: #fff;
|
||
border-radius: 8rpx;
|
||
padding: 30rpx;
|
||
|
||
.title {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.info-item {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 16rpx;
|
||
font-size: 28rpx;
|
||
|
||
.label {
|
||
color: #666;
|
||
width: 160rpx;
|
||
}
|
||
|
||
.value {
|
||
color: #333;
|
||
flex: 1;
|
||
}
|
||
|
||
&.status-row {
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
|
||
.status-wrapper {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.u-button {
|
||
margin-left: 20rpx;
|
||
width: 140rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.placeholder {
|
||
color: #999;
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
.popup-content {
|
||
padding: 30rpx;
|
||
max-height: 80vh;
|
||
overflow-y: auto;
|
||
|
||
.popup-title {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
text-align: center;
|
||
margin-bottom: 30rpx;
|
||
}
|
||
|
||
.time-trigger {
|
||
width: 100%;
|
||
height: 70rpx;
|
||
line-height: 70rpx;
|
||
padding: 0 20rpx;
|
||
background-color: #F5F5F5;
|
||
border-radius: 4rpx;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.popup-footer {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-top: 40rpx;
|
||
padding-bottom: env(safe-area-inset-bottom);
|
||
|
||
.u-button {
|
||
flex: 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 调整单选框组样式
|
||
/deep/ .u-radio-group {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
|
||
.u-radio {
|
||
margin-right: 30rpx;
|
||
margin-bottom: 10rpx;
|
||
}
|
||
}
|
||
</style> |