Ver Fonte

瑞都新增日报选择施工队伍调整,选择物料,调整字段顺序

Zimo há 19 horas atrás
pai
commit
b3ca3317aa

+ 171 - 116
src/views/pms/iotmainworkorder/WorkOrderMaterial.vue

@@ -1,45 +1,63 @@
 <template>
-  <Dialog v-model="dialogVisible" title="选择物料" style="width: 1400px; padding: 0px 0px 0px 0px; min-height: 300px">
-
-    <div ref="measureSpan"
-         style="position:absolute;left:-9999px;top:-9999px;visibility:hidden;
-         white-space:nowrap;padding:0 12px;font:13px Arial, PingFang SC, Microsoft YaHei, sans-serif;">
+  <Dialog
+    v-model="dialogVisible"
+    title="选择物料"
+    style="width: 1400px; min-height: 300px; padding: 0"
+  >
+    <div
+      ref="measureSpan"
+      style="
+        position: absolute;
+        top: -9999px;
+        left: -9999px;
+        padding: 0 12px;
+        font:
+          13px Arial,
+          'PingFang SC',
+          'Microsoft YaHei',
+          sans-serif;
+        white-space: nowrap;
+        visibility: hidden;
+      "
+    >
     </div>
 
     <!-- 设备分类和BOM节点信息显示 -->
-    <div style="margin: 0 0px 0px; background: #f5f7fa; padding: 5px 15px; border-radius: 4px;">
+    <div style="padding: 5px 15px; margin: 0; background: #f5f7fa; border-radius: 4px">
       <el-row>
         <el-col :span="8">
-          <span style="font-weight: bold; margin-right: 8px; font-size: 13px;">设备编码:</span>
-          <span style="font-size: 13px;">{{ deviceCode }}</span>
+          <span style="margin-right: 8px; font-size: 13px; font-weight: bold">设备编码:</span>
+          <span style="font-size: 13px">{{ deviceCode }}</span>
         </el-col>
         <el-col :span="8">
-          <span style="font-weight: bold; margin-right: 8px; font-size: 13px;">设备名称:</span>
-          <span style="font-size: 13px;">{{ deviceName }}</span>
+          <span style="margin-right: 8px; font-size: 13px; font-weight: bold">设备名称:</span>
+          <span style="font-size: 13px">{{ deviceName }}</span>
         </el-col>
         <el-col :span="8">
-          <span style="font-weight: bold; margin-right: 8px; font-size: 13px;">{{bomNodeLabel}}:</span>
-          <span style="font-size: 13px;">{{ bomNodeName }}</span>
+          <span style="margin-right: 8px; font-size: 13px; font-weight: bold"
+            >{{ bomNodeLabel }}:</span
+          >
+          <span style="font-size: 13px">{{ bomNodeName }}</span>
         </el-col>
       </el-row>
     </div>
 
     <!-- 可折叠的区域 展示当前保养项 已经绑定的物料-->
-    <div v-if="showFoldArea" style="margin-bottom: 2px;">
+    <div v-if="showFoldArea" style="margin-bottom: 2px">
       <el-button
         type="text"
         @click="showMaterialArea = !showMaterialArea"
-        style="padding-left: 8px; margin-bottom: 2px; font-size: 13px;"
+        style="padding-left: 8px; margin-bottom: 2px; font-size: 13px"
       >
         {{ showMaterialArea ? '隐藏保养项物料' : '显示保养项物料' }}
       </el-button>
 
       <div
         v-show="showMaterialArea"
-        style="background: #f5f7fa; padding: 5px 8px; border-radius: 4px;"
+        style="padding: 5px 8px; background: #f5f7fa; border-radius: 4px"
       >
         <template v-if="deviceBomMaterials.length === 0">
-          <div style="text-align: center; padding: 8px; color: #999; font-size: 13px;">
+          <div style="padding: 8px; font-size: 13px; color: #999; text-align: center">
             无绑定物料
           </div>
         </template>
@@ -47,15 +65,15 @@
           <!-- 表头 -->
           <div
             style="
-            display: grid;
-            grid-template-columns: 1fr 1fr 1fr 1fr;
-            gap: 12px;
-            margin-bottom: 8px;
-            font-weight: bold;
-            border-bottom: 1px solid #e4e7ed;
-            padding-bottom: 6px;
-            font-size: 13px;
-          "
+              display: grid;
+              padding-bottom: 6px;
+              margin-bottom: 8px;
+              font-size: 13px;
+              font-weight: bold;
+              border-bottom: 1px solid #e4e7ed;
+              grid-template-columns: 1fr 1fr 1fr 1fr;
+              gap: 12px;
+            "
           >
             <div>物料编码</div>
             <div>物料名称</div>
@@ -67,58 +85,68 @@
             v-for="(item, index) in deviceBomMaterials"
             :key="index"
             style="
-            display: grid;
-            grid-template-columns: 1fr 1fr 1fr 1fr;
-            gap: 8px;
-            padding: 6px 0;
-            border-bottom: 1px dashed #ebeef5;
-            font-size: 13px;
-          "
+              display: grid;
+              padding: 6px 0;
+              font-size: 13px;
+              border-bottom: 1px dashed #ebeef5;
+              grid-template-columns: 1fr 1fr 1fr 1fr;
+              gap: 8px;
+            "
           >
-            <div style="word-break: break-all;">{{ item.code || '-' }}</div>
-            <div style="word-break: break-all;">{{ item.name || '-' }}</div>
+            <div style="word-break: break-all">{{ item.code || '-' }}</div>
+            <div style="word-break: break-all">{{ item.name || '-' }}</div>
             <div>{{ item.quantity !== undefined ? item.quantity : '-' }}</div>
-            <div style="word-break: break-all;">{{ item.unit || '-' }}</div>
+            <div style="word-break: break-all">{{ item.unit || '-' }}</div>
           </div>
         </template>
       </div>
     </div>
 
-    <ContentWrap style="padding: 0px 0;">
+    <ContentWrap style="padding: 0">
       <el-form
         class="-mb-5px"
         :model="queryParams"
         ref="queryFormRef"
         :inline="true"
         label-width="68px"
-        style="font-size: 13px;"
+        style="font-size: 13px"
       >
-        <el-form-item :label="t('workOrderMaterial.materialCode')" prop="materialCode" style="margin-bottom: 2px;">
+        <el-form-item
+          :label="t('workOrderMaterial.materialName')"
+          prop="materialName"
+          style="margin-bottom: 2px"
+        >
           <el-input
-            v-model="queryParams.materialCode"
-            :placeholder="t('workOrderMaterial.codeHolder')"
+            v-model="queryParams.materialName"
+            :placeholder="t('workOrderMaterial.nameHolder')"
             clearable
             @keyup.enter="handleQuery"
             size="small"
           />
         </el-form-item>
-        <el-form-item :label="t('workOrderMaterial.materialName')" prop="materialName" style="margin-bottom: 2px;">
+        <el-form-item
+          :label="t('workOrderMaterial.materialCode')"
+          prop="materialCode"
+          style="margin-bottom: 2px"
+        >
           <el-input
-            v-model="queryParams.materialName"
-            :placeholder="t('workOrderMaterial.nameHolder')"
+            v-model="queryParams.materialCode"
+            :placeholder="t('workOrderMaterial.codeHolder')"
             clearable
             @keyup.enter="handleQuery"
             size="small"
           />
         </el-form-item>
-        <el-form-item style="margin-bottom: 2px;">
-          <el-button @click="handleQuery" size="small"><Icon icon="ep:search" class="mr-5px" />
-            {{ t('workOrderMaterial.search') }}</el-button>
-          <el-button @click="resetQuery" size="small"><Icon icon="ep:refresh" class="mr-5px" />
-            {{ t('workOrderMaterial.reset') }}</el-button>
+
+        <el-form-item style="margin-bottom: 2px">
+          <el-button @click="handleQuery" size="small"
+            ><Icon icon="ep:search" class="mr-5px" /> {{ t('workOrderMaterial.search') }}</el-button
+          >
+          <el-button @click="resetQuery" size="small"
+            ><Icon icon="ep:refresh" class="mr-5px" /> {{ t('workOrderMaterial.reset') }}</el-button
+          >
           <el-button @click="handleConfirm" class="custom-green-button" size="small"
-            ><Icon icon="ep:check" class="mr-5px" />
-            {{ t('workOrderMaterial.confirm') }}</el-button
+            ><Icon icon="ep:check" class="mr-5px" /> {{ t('workOrderMaterial.confirm') }}</el-button
           >
           <!-- <el-button @click="handleView" type="warning" size="small"
             ><Icon icon="ep:plus" class="mr-5px" />
@@ -127,7 +155,7 @@
         </el-form-item>
       </el-form>
     </ContentWrap>
-    <ContentWrap style="padding: 0px 0px 0px 0px; margin-bottom: 0px">
+    <ContentWrap style="padding: 0; margin-bottom: 0">
       <el-table
         v-loading="loading"
         :data="list"
@@ -141,12 +169,15 @@
         <el-table-column width="60" :label="t('workOrderMaterial.select')">
           <template #default="{ row }">
             <el-checkbox
-              :model-value="selectedRows.some(item =>
-                item.factoryId === row.factoryId &&
-                item.costCenterId === row.costCenterId &&
-                item.storageLocationId === row.storageLocationId &&
-                item.materialCode === row.materialCode
-              )"
+              :model-value="
+                selectedRows.some(
+                  (item) =>
+                    item.factoryId === row.factoryId &&
+                    item.costCenterId === row.costCenterId &&
+                    item.storageLocationId === row.storageLocationId &&
+                    item.materialCode === row.materialCode
+                )
+              "
               @click.stop="toggleRow(row)"
               class="no-label-radio"
             />
@@ -204,8 +235,12 @@
           :class-name="'material-name-cell'"
           :width="materialNameWidth"
         />
-        <el-table-column :label="t('workOrderMaterial.ConsumptionQuantity')" align="center" prop="quantity"
-                         :width="flexColumnWidth('quantity', t('workOrderMaterial.ConsumptionQuantity'), 20)">
+        <el-table-column
+          :label="t('workOrderMaterial.ConsumptionQuantity')"
+          align="center"
+          prop="quantity"
+          :width="flexColumnWidth('quantity', t('workOrderMaterial.ConsumptionQuantity'), 20)"
+        >
           <template #default="scope">
             <el-input
               type="number"
@@ -218,15 +253,30 @@
             />
           </template>
         </el-table-column>
-        <el-table-column :label="t('workOrderMaterial.unit')" align="center" prop="unit"
-                         :width="flexColumnWidth('unit', t('workOrderMaterial.unit'))"/>
-        <el-table-column :label="t('workOrderMaterial.unitPrice')" align="center" prop="unitPrice"
-                         :width="flexColumnWidth('unitPrice', t('workOrderMaterial.unitPrice'))"/>
-        <el-table-column :label="t('workOrderMaterial.total')" align="center" prop="totalInventoryQuantity"
-                         :width="flexColumnWidth('totalInventoryQuantity', t('workOrderMaterial.total'))"/>
-        <el-table-column :label="t('workOrderMaterial.source')" align="center" prop="materialSource"
-                         :width="flexColumnWidth('materialSource', t('workOrderMaterial.source'))"/>
-
+        <el-table-column
+          :label="t('workOrderMaterial.unit')"
+          align="center"
+          prop="unit"
+          :width="flexColumnWidth('unit', t('workOrderMaterial.unit'))"
+        />
+        <el-table-column
+          :label="t('workOrderMaterial.unitPrice')"
+          align="center"
+          prop="unitPrice"
+          :width="flexColumnWidth('unitPrice', t('workOrderMaterial.unitPrice'))"
+        />
+        <el-table-column
+          :label="t('workOrderMaterial.total')"
+          align="center"
+          prop="totalInventoryQuantity"
+          :width="flexColumnWidth('totalInventoryQuantity', t('workOrderMaterial.total'))"
+        />
+        <el-table-column
+          :label="t('workOrderMaterial.source')"
+          align="center"
+          prop="materialSource"
+          :width="flexColumnWidth('materialSource', t('workOrderMaterial.source'))"
+        />
       </el-table>
       <!-- 分页 -->
       <Pagination
@@ -234,7 +284,7 @@
         v-model:page="queryParams.pageNo"
         v-model:limit="queryParams.pageSize"
         @pagination="getList"
-        style="margin-bottom: 5px; padding: 0px 0px 5px 0px;"
+        style="padding: 0 0 5px; margin-bottom: 5px"
       />
     </ContentWrap>
   </Dialog>
@@ -281,9 +331,9 @@ const showMaterialArea = ref(false) // 控制A区域显示状态
 const deviceBomMaterials = ref<any[]>([]) // 存储绑定物料数据
 
 const deviceName = ref('') // 设备名称
-const deviceCode = ref('')    // 设备编码
-const bomNodeName = ref('')   // 保养项 or 维修项 名称
-const bomNodeLabel = ref('')   // 保养项 or 维修项 名称
+const deviceCode = ref('') // 设备编码
+const bomNodeName = ref('') // 保养项 or 维修项 名称
+const bomNodeLabel = ref('') // 保养项 or 维修项 名称
 
 // 控制折叠区域的响应式变量
 const showFoldArea = ref(false)
@@ -297,7 +347,7 @@ const queryParams = reactive({
   name: '',
   code: '',
   materialCode: '',
-  materialName: '',
+  materialName: ''
 })
 
 // 保存初始查询参数用于重置
@@ -305,7 +355,7 @@ const defaultQueryParams = {
   materialName: '',
   materialCode: '',
   pageNo: 1,
-  pageSize: 10,
+  pageSize: 10
 }
 
 const drawerVisible = ref<boolean>(false)
@@ -318,19 +368,19 @@ const addMaterial = ref(null)
 
 const handleChildSubmit = (formData) => {
   const modified = removeOnesFromKeys(formData)
-  modified.materialName = modified.name;
-  modified.materialCode = modified.code;
-  modified.materialSource = '手动添加';
-  modified.quantity = modified.depleteCount;
-  modified.unitPrice = modified.price;
-  addMaterial.value = modified;
+  modified.materialName = modified.name
+  modified.materialCode = modified.code
+  modified.materialSource = '手动添加'
+  modified.quantity = modified.depleteCount
+  modified.unitPrice = modified.price
+  addMaterial.value = modified
   list.value.unshift(modified)
-  total.value = total.value+1
+  total.value = total.value + 1
 
   // 将新添加的行添加到选中列表
   selectedRows.value.push(modified)
   // 设置新添加行的索引
-  lastAddedIndex.value = 0;
+  lastAddedIndex.value = 0
 }
 
 const removeOnesFromKeys = (obj: Record<string, any>) => {
@@ -359,7 +409,7 @@ const open = async (deptId: number, bomNodeId: number, row: any, type: string) =
   queryParams.deptId = deptId
   queryParams.bomNodeId = bomNodeId
   queryParams.deviceId = row.deviceId
-  if(type === 'repair'){
+  if (type === 'repair') {
     queryParams.deviceId = row.deviceId
   }
   deviceName.value = row.deviceName
@@ -392,14 +442,14 @@ const flexColumnWidth = (prop: string, label: string, extra: number = 0) => {
     return getTextWidth(label) + extra
   }
 
-  const contentList = list.value.map(item => {
+  const contentList = list.value.map((item) => {
     const value = item[prop]
     if (value == null) return ' '
     return typeof value === 'number' ? value.toString() : value
   })
 
   contentList.push(label)
-  const maxWidth = Math.max(...contentList.map(text => getTextWidth(text)))
+  const maxWidth = Math.max(...contentList.map((text) => getTextWidth(text)))
   return Math.min(maxWidth + extra, 400)
 }
 
@@ -478,21 +528,23 @@ const getList = async () => {
 // 确认选择
 const handleConfirm = () => {
   // 检查是否有未通过校验的行
-  const invalidRows = selectedRows.value.filter(row => {
-    const quantity = parseFloat(row.quantity);
-    return isNaN(quantity) || quantity <= 0;
-  });
+  const invalidRows = selectedRows.value.filter((row) => {
+    const quantity = parseFloat(row.quantity)
+    return isNaN(quantity) || quantity <= 0
+  })
 
   if (invalidRows.length > 0) {
-    ElMessage.error('存在无效的 消耗数量,请检查');
-    return;
+    ElMessage.error('存在无效的 消耗数量,请检查')
+    return
   }
 
   if (selectedRows.value.length === 0) {
     ElMessage.warning('请至少选择一个物料')
     return
   }
-  const filters = selectedRows.value.filter((item) => item.quantity === null||item.quantity === undefined)
+  const filters = selectedRows.value.filter(
+    (item) => item.quantity === null || item.quantity === undefined
+  )
   if (filters.length > 0) {
     message.error('消耗数量必填')
     return
@@ -522,8 +574,8 @@ const handleClose = () => {
 }
 
 const rowClassName = ({ row }: { row: any }) => {
-  let className = '';
-  if(row.bomMaterialFlag === 'Y'){
+  let className = ''
+  if (row.bomMaterialFlag === 'Y') {
     className = ''
   }
   if (row.materialSource === '本地库存' && row.bomMaterialFlag != 'Y') {
@@ -543,9 +595,7 @@ const toggleRow = (row) => {
   }
 
   const currentKey = getRowUniqueKey(row)
-  const index = selectedRows.value.findIndex(item =>
-    getRowUniqueKey(item) === currentKey
-  )
+  const index = selectedRows.value.findIndex((item) => getRowUniqueKey(item) === currentKey)
 
   if (index > -1) {
     selectedRows.value.splice(index, 1) // 取消选中
@@ -556,21 +606,21 @@ const toggleRow = (row) => {
 
 // 处理 消耗数量 quantity 输入框失焦事件
 const handleQuantityBlur = (event: Event, row: any) => {
-  const inputValue = (event.target as HTMLInputElement).value;
-  let num = parseFloat(inputValue);
+  const inputValue = (event.target as HTMLInputElement).value
+  let num = parseFloat(inputValue)
   // 处理无效值
   if (isNaN(num)) {
-    row.quantity = 0;
-    return;
+    row.quantity = 0
+    return
   }
   // 处理小于等于0的情况
   if (num <= 0) {
-    row.quantity = 0;
-    return;
+    row.quantity = 0
+    return
   }
   // 保留两位小数
-  row.quantity = parseFloat(num.toFixed(4));
-};
+  row.quantity = parseFloat(num.toFixed(4))
+}
 
 // 处理输入框焦点事件(自动选中当前行)
 const handleInputFocus = (row: WorkOrderBomMaterialApi.IotMainWorkOrderBomMaterialVO) => {
@@ -579,7 +629,7 @@ const handleInputFocus = (row: WorkOrderBomMaterialApi.IotMainWorkOrderBomMateri
   }
   const currentKey = getRowUniqueKey(row)
   // 如果未选中则添加到选中列表
-  const exists = selectedRows.value.some(item => getRowUniqueKey(item) === currentKey)
+  const exists = selectedRows.value.some((item) => getRowUniqueKey(item) === currentKey)
   if (!exists) {
     selectedRows.value.push(row)
   }
@@ -617,28 +667,28 @@ onUnmounted(() => {
   // 移除窗口大小变化监听器
   window.removeEventListener('resize', handleResize)
 })
-
 </script>
 <style lang="scss" scoped>
 .no-label-radio .el-radio__label {
   display: none;
 }
+
 .no-label-radio .el-radio__inner {
   margin-right: 0;
 }
 
 /* 自定义淡绿色按钮 */
 :deep(.custom-green-button) {
+  color: #67c23a;
   background-color: #e1f3d8;
   border-color: #e1f3d8;
-  color: #67c23a;
 }
 
 /* 悬停效果 */
 :deep(.custom-green-button:hover) {
+  color: #5daf34;
   background-color: #d1e8c0;
   border-color: #d1e8c0;
-  color: #5daf34;
 }
 
 /* 点击效果 */
@@ -659,21 +709,24 @@ onUnmounted(() => {
 :deep(.adaptive-table) {
   width: 100%;
   font-size: 13px;
+
   .el-table__cell {
     padding: 4px 0;
+
     .cell {
-      white-space: nowrap; /* 禁止换行 */
       overflow: hidden;
       text-overflow: ellipsis;
+      white-space: nowrap; /* 禁止换行 */
     }
   }
   // 确保基准列使用可用空间
   .material-name-cell .cell {
     display: block;
+    max-width: 100%;
     overflow: hidden;
     text-overflow: ellipsis;
-    max-width: 100%;
   }
+
   .el-table__row {
     height: 36px;
   }
@@ -688,9 +741,10 @@ onUnmounted(() => {
 :deep(.adaptive-table .el-table__header) {
   th {
     padding: 6px 0;
+
     .cell {
-      font-weight: bold;
       font-size: 13px;
+      font-weight: bold;
     }
   }
 }
@@ -699,9 +753,11 @@ onUnmounted(() => {
 :deep(.el-pagination) {
   padding: 8px 0;
 
-  .btn-prev, .btn-next, .number {
-    min-width: 28px;
+  .btn-prev,
+  .btn-next,
+  .number {
     height: 28px;
+    min-width: 28px;
     line-height: 28px;
   }
 }
@@ -719,9 +775,8 @@ onUnmounted(() => {
 
 // 调整表单标签样式
 :deep(.el-form-item__label) {
-  font-size: 13px;
   height: 28px;
+  font-size: 13px;
   line-height: 28px;
 }
-
 </style>

+ 2 - 0
src/views/pms/iotrddailyreport/create-rd-form.vue

@@ -122,6 +122,7 @@ interface UserOptions {
   label: string
   value: number
   raw: any
+  disabled: boolean
 }
 
 const userOptions = ref<UserOptions[]>([])
@@ -143,6 +144,7 @@ async function loadDept() {
       })
 
       sortedNodes.forEach((node) => {
+        node.disabled = (node as any).type !== '3'
         if (node.children && Array.isArray(node.children)) {
           node.children = sortTreeBySort(node.children)
         }

+ 1 - 0
types/global.d.ts

@@ -50,6 +50,7 @@ declare global {
     name: string
     sort?: number
     children?: Tree[] | any[]
+    disabled?: boolean
   }
   // 分页数据公共返回
   interface PageResult<T> {