|
@@ -24,20 +24,48 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <el-table :data="materials" style="width: 100%">
|
|
|
- <el-table-column prop="name" :label="t('workOrderMaterial.materialName')" width="180" />
|
|
|
- <el-table-column prop="code" :label="t('workOrderMaterial.materialCode')" width="180" />
|
|
|
- <!-- <el-table-column prop="model" :label="t('deviceForm.model')" width="180" /> -->
|
|
|
- <el-table-column prop="unit" :label="t('workOrderMaterial.unit')" width="180" />
|
|
|
+ <el-table :data="materials" style="width: 100%" fit :row-style="{ height: '38px' }">
|
|
|
+ <el-table-column prop="name" :label="t('workOrderMaterial.materialName')" min-width="150" show-overflow-tooltip/>
|
|
|
+ <el-table-column prop="code" :label="t('workOrderMaterial.materialCode')" min-width="80" />
|
|
|
+ <el-table-column prop="quantity" :label="t('route.quantity')" min-width="70" align="center">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-form
|
|
|
+ :model="scope.row"
|
|
|
+ :rules="quantityRules"
|
|
|
+ ref="quantityFormRef"
|
|
|
+ @submit.prevent
|
|
|
+ >
|
|
|
+ <el-form-item prop="quantity" :error="scope.row.quantityError">
|
|
|
+ <el-input
|
|
|
+ v-model.number="scope.row.quantity"
|
|
|
+ type="number"
|
|
|
+ size="small"
|
|
|
+ placeholder="请输入数量"
|
|
|
+ @blur="clearQuantityError(scope.row)"
|
|
|
+ @keyup.enter="handleUpdate(scope.row)"
|
|
|
+ :class="{ 'error-input': scope.row.quantityError }"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="unit" :label="t('workOrderMaterial.unit')" min-width="50" />
|
|
|
<el-table-column
|
|
|
:label="t('deviceList.createTime')"
|
|
|
align="center"
|
|
|
prop="createTime"
|
|
|
- width="180"
|
|
|
+ min-width="110"
|
|
|
:formatter="dateFormatter"
|
|
|
/>
|
|
|
- <el-table-column :label="t('maintain.operation')" align="right">
|
|
|
+ <el-table-column :label="t('maintain.operation')" width="180" fixed="right">
|
|
|
<template #default="scope">
|
|
|
+ <el-button
|
|
|
+ size="small"
|
|
|
+ type="success"
|
|
|
+ :loading="scope.row.updating"
|
|
|
+ @click="handleUpdate(scope.row)"
|
|
|
+ >{{ t('iotDevice.update') }}</el-button>
|
|
|
+
|
|
|
<el-button size="small" type="danger" @click="handleDelete(scope.row)"
|
|
|
>{{ t('info.delete') }}</el-button
|
|
|
>
|
|
@@ -60,6 +88,7 @@ import { defineEmits, defineOptions, ref, watch } from 'vue'
|
|
|
import { ElMessage } from 'element-plus'
|
|
|
import * as DeviceMaterialApi from '@/api/pms/iotdevicematerial'
|
|
|
import { dateFormatter } from '@/utils/formatTime'
|
|
|
+import {IotDeviceMaterialApi, IotDeviceMaterialVO} from "@/api/pms/iotdevicematerial";
|
|
|
const { t } = useI18n() // 国际化
|
|
|
const drawerVisible = ref<boolean>(false)
|
|
|
const emit = defineEmits(['update:modelValue', 'add', 'delete', 'refresh'])
|
|
@@ -80,6 +109,24 @@ const queryParams = reactive({
|
|
|
code: ''
|
|
|
})
|
|
|
|
|
|
+const quantityRules: FormRules = {
|
|
|
+ quantity: [
|
|
|
+ { required: true, message: '数量不能为空', trigger: 'blur' },
|
|
|
+ {
|
|
|
+ validator: (rule, value, callback) => {
|
|
|
+ if (isNaN(value)) {
|
|
|
+ callback(new Error('请输入有效数字'));
|
|
|
+ } else if (value <= 0) {
|
|
|
+ callback(new Error('数量必须大于0'));
|
|
|
+ } else {
|
|
|
+ callback();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ trigger: 'blur'
|
|
|
+ }
|
|
|
+ ]
|
|
|
+};
|
|
|
+
|
|
|
const windowWidth = ref(window.innerWidth)
|
|
|
// 动态计算百分比
|
|
|
const computedSize = computed(() => {
|
|
@@ -122,7 +169,11 @@ const loadMaterials = async (nodeId) => {
|
|
|
loading.value = true
|
|
|
// API调用
|
|
|
const data = await DeviceMaterialApi.IotDeviceMaterialApi.getIotDeviceMaterialPage(queryParams)
|
|
|
- materials.value = data.list
|
|
|
+ materials.value = data.list.map(item => ({
|
|
|
+ ...item,
|
|
|
+ updating: false, // 更新状态标记
|
|
|
+ quantityError: '' // 错误状态标记
|
|
|
+ }))
|
|
|
total.value = data.total
|
|
|
} catch (error) {
|
|
|
ElMessage.error('数据加载失败')
|
|
@@ -131,6 +182,52 @@ const loadMaterials = async (nodeId) => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/** 清除数量错误状态 */
|
|
|
+const clearQuantityError = (row: IotDeviceMaterialVO) => {
|
|
|
+ // 延迟清除错误状态,避免在验证过程中清除
|
|
|
+ setTimeout(() => {
|
|
|
+ row.quantityError = '';
|
|
|
+ }, 100);
|
|
|
+}
|
|
|
+
|
|
|
+/** 更新物料数据 */
|
|
|
+const handleUpdate = async (row: IotDeviceMaterialVO) => {
|
|
|
+ try {
|
|
|
+ if (isNaN(row.quantity)) {
|
|
|
+ row.quantityError = '请输入有效数字';
|
|
|
+ ElMessage.warning('请输入有效的数字');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (row.quantity <= 0) {
|
|
|
+ row.quantityError = '数量必须大于0';
|
|
|
+ ElMessage.warning('数量必须大于0');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 清除错误状态
|
|
|
+ row.quantityError = '';
|
|
|
+
|
|
|
+ // 设置更新状态
|
|
|
+ row.updating = true
|
|
|
+ // 构造更新参数
|
|
|
+ const updateParams = {
|
|
|
+ ...row,
|
|
|
+ bomNodeId: props.nodeId
|
|
|
+ }
|
|
|
+ // 调用更新接口
|
|
|
+ await DeviceMaterialApi.IotDeviceMaterialApi.updateIotDeviceMaterial(updateParams)
|
|
|
+ // 更新成功反馈
|
|
|
+ message.success('数量更新成功')
|
|
|
+ // 可选:刷新父组件数据
|
|
|
+ // emit('refresh')
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('更新失败')
|
|
|
+ } finally {
|
|
|
+ row.updating = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
// 打开抽屉
|
|
|
const openDrawer = () => {
|
|
|
drawerVisible.value = true
|
|
@@ -165,6 +262,58 @@ defineExpose({ openDrawer, closeDrawer, loadMaterials }) // 暴露方法给父
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
+
|
|
|
+/* 添加表格样式优化 */
|
|
|
+.el-table {
|
|
|
+ :deep(.cell) {
|
|
|
+ white-space: nowrap; /* 防止单元格内容换行 */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 表头样式 */
|
|
|
+ :deep(th.el-table__cell) {
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #606266;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 优化输入框样式 */
|
|
|
+.el-input {
|
|
|
+ width: 80px;
|
|
|
+
|
|
|
+ :deep(.el-input__inner) {
|
|
|
+ text-align: center;
|
|
|
+ padding: 0 5px;
|
|
|
+ }
|
|
|
+ &.error-input :deep(.el-input__inner) {
|
|
|
+ border-color: #f56c6c;
|
|
|
+ background-color: #fff6f7;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 错误提示样式 */
|
|
|
+:deep(.el-form-item__error) {
|
|
|
+ position: absolute;
|
|
|
+ top: 100%;
|
|
|
+ left: 0;
|
|
|
+ padding-top: 2px;
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 1;
|
|
|
+ color: #f56c6c;
|
|
|
+ white-space: nowrap;
|
|
|
+}
|
|
|
+
|
|
|
+/* 更新按钮自定义样式 */
|
|
|
+.el-button--success {
|
|
|
+ background-color: #e8f5e9;
|
|
|
+ border-color: #c8e6c9;
|
|
|
+ color: #2e7d32;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background-color: #c8e6c9;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
.info-header {
|
|
|
display: flex;
|
|
|
align-items: center;
|