Browse Source

pms 设备分类BOM批量添加物料

zhangcl 2 tháng trước cách đây
mục cha
commit
f3314c4bc4

+ 2 - 1
src/config/axios/service.ts

@@ -181,7 +181,8 @@ service.interceptors.response.use(
       const requestUrl = response.config.url || ''
       // 判断是否包含rq/iot路径
       if (requestUrl.includes('rq/')||requestUrl.includes('system/dict')||requestUrl.includes('system/auth/get-permission-info')||requestUrl.includes('system/dept/list')
-        ||requestUrl.includes('system/menu/simple-list')||requestUrl.includes('system/menu/list')||requestUrl.includes('system/dept/simple-list')) {
+        ||requestUrl.includes('system/menu/simple-list')||requestUrl.includes('system/menu/list')||requestUrl.includes('system/dept/simple-list')
+        ||requestUrl.includes('pms/')) {
         const localeStore = useLocaleStore()
         const lang = localeStore.getCurrentLocale.lang
         if (data&& data.data) {

+ 79 - 12
src/views/pms/bom/MaterialList.vue

@@ -1,5 +1,6 @@
 <template>
-  <Dialog v-model="dialogVisible" :title="t('iotMaintain.selectMaterials')" style="width: 1300px; min-height: 300px">
+  <Dialog v-model="dialogVisible" :title="t('iotMaintain.selectMaterials')"
+          style="width: 1300px; min-height: 300px" :close-on-click-modal="false" @close="handleClose">
     <ContentWrap>
       <el-form
         class="-mb-15px"
@@ -26,6 +27,7 @@
             class="!w-200px"
           />
         </el-form-item>
+        <!--
         <el-form-item :label="t('workOrderMaterial.materialGroup')" prop="materialGroupId" style="margin-left: 5px">
           <el-tree-select
             filterable
@@ -38,22 +40,28 @@
             class="!w-220px"
             clearable
           />
-        </el-form-item>
+        </el-form-item> -->
         <el-form-item>
           <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" />
             {{ t('workOrderMaterial.search') }}</el-button>
           <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" />
             {{ t('workOrderMaterial.reset') }}</el-button>
+          <el-button @click="handleConfirm" class="custom-green-button"><Icon icon="ep:check" class="mr-5px" /> {{ t('workOrderMaterial.confirm') }}</el-button>
         </el-form-item>
       </el-form>
     </ContentWrap>
     <ContentWrap>
-      <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true" @row-click="handleRowClick">
+      <el-table
+        ref="tableRef"
+        v-loading="loading"
+                :data="list"
+                :stripe="true"
+                :show-overflow-tooltip="true"
+                @row-click="handleRowClick">
         <el-table-column width="80" :label="t('workOrderMaterial.select')">
           <template #default="{ row }">
-            <el-radio
-
-              :label="row.id"
+            <el-checkbox
+              :model-value="selectedRows.some(item => item.id === row.id)"
               @click.stop="selectRow(row)"
               class="no-label-radio"
             />
@@ -63,7 +71,7 @@
         <el-table-column :label="t('workOrderMaterial.materialCode')" align="center" prop="code" />
         <!-- <el-table-column :label="t('deviceForm.model')" align="center" prop="model" /> -->
         <el-table-column :label="t('workOrderMaterial.unit')" align="center" prop="unit" />
-        <el-table-column :label="t('form.remark')" align="center" prop="remark" show-overflow-tooltip />
+        <!-- <el-table-column :label="t('form.remark')" align="center" prop="remark" show-overflow-tooltip /> -->
         <el-table-column
           :label="t('deviceList.createTime')"
           align="center"
@@ -95,12 +103,20 @@ defineOptions({
 })
 const { t } = useI18n() // 国际化
 const materialGroupList = ref<Tree[]>([]) // 物料组树形结构
-const emit = defineEmits(['choose']) // 定义 success 事件,用于操作成功后的回调
+
+const emit = defineEmits<{
+  (e: 'choose', value: MaterialApi.MaterialVO[]): void
+  (e: 'close'): void
+}>()
+
 const dialogVisible = ref(false) // 弹窗的是否展示
 const loading = ref(true) // 列表的加载中
 const queryFormRef = ref() // 搜索的表单
 const list = ref<DictDataVO[]>([]) // 列表的数据
 const total = ref(0) // 列表的总页数
+const selectedRows = ref<MaterialApi.MaterialVO[]>([]); // 多选数据(存储所有选中行的数组)
+const tableRef = ref();
+
 const queryParams = reactive({
   pageNo: 1,
   pageSize: 10,
@@ -115,9 +131,15 @@ const selectedRow = ref(null);
 
 // 处理单选逻辑
 const selectRow = (row) => {
-  selectedRow.value = selectedRow.value?.id === row.id ? null : row;
-  emit('choose', row)
-  dialogVisible.value = false
+  // selectedRow.value = selectedRow.value?.id === row.id ? null : row;
+  // emit('choose', row)
+  const index = selectedRows.value.findIndex(item => item.id === row.id);
+  if (index > -1) {
+    selectedRows.value.splice(index, 1); // 取消选中
+  } else {
+    selectedRows.value.push(row); // 选中
+  }
+  // dialogVisible.value = false
 };
 
 // 点击整行选中
@@ -141,6 +163,30 @@ const getList = async () => {
   }
 }
 
+// 关闭时清空选择
+const handleClose = () => {
+  tableRef.value?.clearSelection();
+  selectedRows.value = []
+  emit('close')
+};
+
+// 确认选择
+const handleConfirm = () => {
+  if (selectedRows.value.length === 0) {
+    ElMessage.warning('请至少选择一个物料')
+    return
+  }
+  emit('choose', selectedRows.value.map(row => ({
+    ...row,
+    // 确保返回必要字段
+    code: row.code,
+    name: row.name,
+    unit: row.unit
+  })))
+  dialogVisible.value = false;
+  handleClose()
+};
+
 /** 搜索按钮操作 */
 const handleQuery = () => {
   queryParams.pageNo = 1
@@ -161,11 +207,32 @@ onMounted(async () => {
   await getList()
 })
 </script>
-<style lang="scss">
+<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) {
+  background-color: #e1f3d8;
+  border-color: #e1f3d8;
+  color: #67c23a;
+}
+
+/* 悬停效果 */
+:deep(.custom-green-button:hover) {
+  background-color: #d1e8c0;
+  border-color: #d1e8c0;
+  color: #5daf34;
+}
+
+/* 点击效果 */
+:deep(.custom-green-button:active) {
+  background-color: #c2dca8;
+  border-color: #c2dca8;
+}
+
 </style>

+ 26 - 1
src/views/pms/bom/index.vue

@@ -256,7 +256,7 @@ const handleView = async (nodeId) => {
   await showDrawer.value.loadMaterials(nodeId)
 }
 
-const chooseMaterial = async(row) => {
+const chooseSingleMaterial = async(row) => {
   // 将物料关联到bom节点
   try {
     // CommonBomMaterialData.value.deviceCategoryId = row.deviceCategoryId
@@ -275,6 +275,31 @@ const chooseMaterial = async(row) => {
   }
 }
 
+const chooseMaterial = async(selectedMaterials) => {
+  // 将物料关联到bom节点
+  try {
+    // 转换数据结构(根据你的接口定义调整)
+    const materialsData = selectedMaterials.map(material => ({
+      deviceCategoryId: CommonBomMaterialData.value.deviceCategoryId,
+      bomNodeId: currentBomNodeId.value,
+      materialId: material.id,
+      name: material.name,
+      code: material.code,
+    }))
+
+    // 调用批量添加接口
+    const resultCount = await CommonBomMaterialApi.addMaterials(materialsData)
+    message.success(`成功添加物料数量:` + resultCount)
+
+    // message.success(t('common.createSuccess'))
+    // 保存成功后立即刷新抽屉数据
+    showDrawer.value.loadMaterials(currentBomNodeId.value)
+    await getList()
+  } catch (error) {
+    message.error('添加物料失败!')
+  }
+}
+
 /** 搜索按钮操作 */
 const handleQuery = () => {
   queryParams.pageNo = 1

+ 0 - 1
src/views/pms/iotmaterialrequisition/IotMaterialRequisitionAdd.vue

@@ -133,7 +133,6 @@ import { ref } from 'vue'
 import { IotMaterialRequisitionApi, IotMaterialRequisitionVO } from '@/api/pms/iotmaterialrequisition'
 import { IotMaterialRequisitionDetailApi, IotMaterialRequisitionDetailVO } from '@/api/pms/iotmaterialrequisitiondetail'
 import { useTagsViewStore } from '@/store/modules/tagsView'
-import {CACHE_KEY, useCache} from "@/hooks/web/useCache";
 import SelectLocalStock from "@/views/pms/iotmaterialrequisition/SelectLocalStock.vue";
 import * as DeptApi from "@/api/system/dept";
 import {erpPriceTableColumnFormatter} from "@/utils";

+ 0 - 4
src/views/pms/iotmaterialrequisition/SelectLocalStock.vue

@@ -110,12 +110,8 @@
 
 <script setup lang="ts">
 import { DictDataVO } from '@/api/system/dict/dict.data'
-import { dateFormatter } from '@/utils/formatTime'
 import * as MaterialApi from '@/api/pms/material'
-import * as SapStockApi from '@/api/pms/iotsapstock'
-import {DICT_TYPE} from "@/utils/dict";
 import {ContentWrap} from "@/components/ContentWrap";
-import {IotSapStockApi, IotSapStockVO} from "@/api/pms/iotsapstock";
 import {IotLockStockApi, IotLockStockVO} from "@/api/pms/iotlockstock";
 import {useUserStore} from "@/store/modules/user";
 const { t } = useI18n() // 国际化