Explorar o código

条形管理接口调试&物资调度申报样式和接口修改

zhangyihao hai 3 meses
pai
achega
3c0ccb5433

+ 24 - 0
src/api/comprehensiveGuarantee/materialReserveManagement/BarcodeManagement.ts

@@ -7,3 +7,27 @@ export function getBarcodeManagementList(params?: any) {
     params: params
   });
 }
+// 禁用接口
+export function changeStatus(data) {
+  return request({
+    url: '/api/resource_provison/material/material/barcode/changeStatus',
+    method: 'put',
+    data: data
+  });
+}
+// 禁用接口
+export function changeStatus(data) {
+  return request({
+    url: '/api/resource_provison/material/material/barcode/changeStatus',
+    method: 'put',
+    data: data
+  });
+}
+// 禁用接口
+export function changeStatus(data) {
+  return request({
+    url: '/api/resource_provison/material/material/barcode/changeStatus',
+    method: 'put',
+    data: data
+  });
+}

+ 1 - 1
src/api/comprehensiveGuarantee/materialReserveManagement/materialsDistribution.ts

@@ -26,7 +26,7 @@ export function createDispatch(data) {
 // 查询物资id和仓库id
 export function getMaterialList(params?: any) {
   return request({
-    url: '/api/resource_provison/material/material/list',
+    url: '/api/resource_provison/material/warehouse/list',
     method: 'get',
     params: params
   });

+ 0 - 7
src/types/components.d.ts

@@ -36,8 +36,6 @@ declare module 'vue' {
     ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
     ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
     ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
-    ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
-    ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
     ElDialog: typeof import('element-plus/es')['ElDialog']
     ElDivider: typeof import('element-plus/es')['ElDivider']
     ElDrawer: typeof import('element-plus/es')['ElDrawer']
@@ -58,9 +56,6 @@ declare module 'vue' {
     ElRow: typeof import('element-plus/es')['ElRow']
     ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
     ElSelect: typeof import('element-plus/es')['ElSelect']
-    ElSkeleton: typeof import('element-plus/es')['ElSkeleton']
-    ElSkeletonItem: typeof import('element-plus/es')['ElSkeletonItem']
-    ElSlider: typeof import('element-plus/es')['ElSlider']
     ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
     ElSwitch: typeof import('element-plus/es')['ElSwitch']
     ElTable: typeof import('element-plus/es')['ElTable']
@@ -69,8 +64,6 @@ declare module 'vue' {
     ElTabs: typeof import('element-plus/es')['ElTabs']
     ElTag: typeof import('element-plus/es')['ElTag']
     ElText: typeof import('element-plus/es')['ElText']
-    ElTimeline: typeof import('element-plus/es')['ElTimeline']
-    ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
     ElTooltip: typeof import('element-plus/es')['ElTooltip']
     ElTree: typeof import('element-plus/es')['ElTree']
     ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']

+ 13 - 3
src/views/comprehensiveGuarantee/MaterialReserveManagement/BarcodeManagement.vue

@@ -45,8 +45,8 @@
           <el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
             <template #default="scope">
               <div>
-                <span v-if="Number(scope.row.status) === 1" class="common-btn-text-primary">禁用</span>
-                <span v-if="Number(scope.row.status) === 0" class="common-btn-text-primary">启用</span>
+                <span v-if="Number(scope.row.status) === 1" class="common-btn-text-primary" @click="toggleStatus(scope.row, 0)">禁用</span>
+                <span v-if="Number(scope.row.status) === 0" class="common-btn-text-primary" @click="toggleStatus(scope.row, 1)">启用</span>
               </div>
             </template>
           </el-table-column>
@@ -70,7 +70,7 @@
 
 <script setup lang="ts">
 import { ref, reactive, onMounted, onBeforeUnmount } from 'vue';
-import { getBarcodeManagementList } from '@/api/comprehensiveGuarantee/materialReserveManagement/BarcodeManagement';
+import { getBarcodeManagementList, changeStatus } from '@/api/comprehensiveGuarantee/materialReserveManagement/BarcodeManagement';
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const baseUrl = import.meta.env.VITE_APP_BASE_API;
 const downLoadApi = import.meta.env.VITE_APP_BASE_DOWNLOAD_API;
@@ -130,7 +130,17 @@ const handleSelectionChange = (selection) => {
   single.value = selection.length != 1;
   multiple.value = !selection.length;
 };
+const toggleStatus = (row, newStatus) => {
+  const payload = {
+    id: row.id,
+    status: String(newStatus)
+  };
 
+  changeStatus(payload).then((response) => {
+    // 更新成功后重新获取列表数据以刷新页面
+    fetchListData();
+  });
+};
 onMounted(() => {
   window.addEventListener('resize', handleResize);
   fetchListData();

+ 1 - 1
src/views/comprehensiveGuarantee/materialReserves/materialsDeclarationAdd.vue

@@ -79,7 +79,7 @@ import {
   updateProcurement
 } from '@/api/comprehensiveGuarantee/materialReserveManagement/materialsDeclaration';
 import BigNumber from 'bignumber.js';
-import materialTreeSelect from './materialTreeSelect'
+import materialTreeSelect from './materialTreeSelect';
 import { formatToTwoDecimalPlaces, isNumericString } from '@/utils';
 import { getMaterialWarehouseList } from '@/api/comprehensiveGuarantee/materialReserveManagement/godownManagement';
 

+ 173 - 220
src/views/comprehensiveGuarantee/materialReserves/materialsDistributionAdd.vue

@@ -1,264 +1,217 @@
 <template>
   <div class="common-dialog">
     <div class="common-dialog-content">
-      <el-row :gutter="20">
-        <div class="common-dialog-title-box">
-          <i class="common-dialog-title-icon" />
-          <div>新增物资调度</div>
+      <div class="common-dialog-title-box">
+        <i class="common-dialog-title-icon" />
+        <div>新增物资调度</div>
+      </div>
+      <div class="common-dialog-box">
+        <div class="text-box">
+          <div class="text1">调度目的:</div>
+          <el-input v-model="dispatch_purpose" class="text2" type="textarea" autosize placeholder="请输入" :style="{ width: '500px' }" />
         </div>
-        <el-col :lg="24" :xs="24">
-          <div class="common-dialog-box">
-            <el-table :data="tableData" border height="400">
-              <el-table-column label="序号" prop="seqNo" width="80">
-                <template #default="{ $index }">
-                  <span>{{ $index + 1 }}</span>
-                </template>
-              </el-table-column>
-              <el-table-column label="仓库名称" prop="warehouse_id">
-                <template #default="{ row, $index }">
-                  <el-select v-model="row.warehouse_id" placeholder="请选择仓库">
-                    <el-option
-                      v-for="item in warehouseOptions"
-                      :key="item.warehouse_id"
-                      :label="item.warehouse_name"
-                      :value="item.warehouse_id"
-                    ></el-option>
-                  </el-select>
-                </template>
-              </el-table-column>
-              <el-table-column label="物资类型" prop="materialType">
-                <template #default="{ row, $index }">
-                  <el-select v-model="row.materialType" placeholder="请选择物资类型">
-                    <el-option
-                      v-for="item in materialTypeOptions"
-                      :key="item.material_type_id"
-                      :label="item.material_type_name"
-                      :value="item.material_type_name"
-                    ></el-option>
-                  </el-select>
-                </template>
-              </el-table-column>
-              <el-table-column label="物资名称" prop="materialCode">
-                <template #default="{ row, $index }">
-                  <el-select v-model="row.materialCode" placeholder="请选择物资">
-                    <el-option
-                      v-for="item in materialOptions"
-                      :key="item.material_id"
-                      :label="item.material_name"
-                      :value="item.material_id"
-                    ></el-option>
-                  </el-select>
-                </template>
-              </el-table-column>
-              <el-table-column label="物资数量(件)" prop="quantity">
-                <template #default="{ row, $index }">
-                  <span
-                    class="editable-span"
-                    contenteditable="true"
-                    @blur="saveEdit($index, 'quantity', $event.target.innerText)"
-                    v-text="row.quantity || ''"
-                  ></span>
-                </template>
-              </el-table-column>
-              <el-table-column label="物资用途" prop="material_purpose">
-                <template #default="{ row, $index }">
-                  <span
-                    class="editable-span"
-                    contenteditable="true"
-                    @blur="saveEdit($index, 'material_purpose', $event.target.innerText)"
-                    v-text="row.material_purpose || ''"
-                  ></span>
-                </template>
-              </el-table-column>
-              <el-table-column label="调度目的" prop="dispatch_purpose">
-                <template #default="{ row, $index }">
-                  <span
-                    class="editable-span"
-                    contenteditable="true"
-                    @blur="saveEdit($index, 'dispatch_purpose', $event.target.innerText)"
-                    v-text="row.dispatch_purpose || ''"
-                  ></span>
-                </template>
-              </el-table-column>
-            </el-table>
-          </div>
-        </el-col>
-        <div class="common-dialog-footer" style="width: 100%; justify-content: center; display: flex">
-          <el-row :gutter="10" class="mb8">
+        <el-form ref="formRef" :model="detailData" style="width: 100%">
+          <el-table :data="detailData.detail" border :height="height">
+            <el-table-column label="序号" width="80" align="center">
+              <template #default="{ $index }">
+                <span>{{ $index + 1 }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="物资名称" prop="material_name" align="center">
+              <template #default="scope">
+                <el-form-item :prop="'detail.' + scope.$index + '.material_type'" :rules="rules.material_name">
+                  <el-input v-model="scope.row.material_name" readonly>
+                    <template #append>
+                      <el-button @click="handleShowSelect(scope.$index)">选择</el-button>
+                    </template>
+                  </el-input>
+                </el-form-item>
+              </template>
+            </el-table-column>
+            <el-table-column label="仓库" prop="warehouse_name" align="center" />
+            <el-table-column label="物资类型" prop="material_type" align="center" />
+            <el-table-column label="物资数量(件)" prop="material_quantity" align="center">
+              <template #default="scope">
+                <el-form-item :prop="`detail.${scope.$index}.material_quantity`" :rules="rules.material_quantity">
+                  <el-input v-model="scope.row.material_quantity" type="number" placeholder="请输入" @input="calcTotalAmount" />
+                </el-form-item>
+              </template>
+            </el-table-column>
+            <el-table-column label="物资用途" prop="material_purpose" align="center">
+              <template #default="scope">
+                <el-form-item :prop="'detail.' + scope.$index + '.material_purpose'" :rules="rules.material_purpose">
+                  <el-input v-model="scope.row.material_purpose" type="textarea" autosize placeholder="请输入" />
+                </el-form-item>
+              </template>
+            </el-table-column>
+            <el-table-column label="调度目的" prop="dispatch_purpose" align="center">
+              <template #default="scope">
+                <el-form-item :prop="'detail.' + scope.$index + '.dispatch_purpose'" :rules="rules.dispatch_purpose">
+                  <el-input v-model="scope.row.dispatch_purpose" type="textarea" autosize placeholder="请输入" />
+                </el-form-item>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-form>
+        <div class="common-dialog-footer" style="margin-top: 18px">
+          <el-row :span="24" :gutter="10" class="mb8">
             <el-col :span="1.5">
-              <el-button type="primary" @click="handleAddRow">新增一项</el-button>
+              <el-button @click="handleReturn">取消</el-button>
             </el-col>
             <el-col :span="1.5">
-              <el-button type="primary" @click="handleSave">提交</el-button>
+              <el-button type="primary" @click="handleAddRow">新增一项</el-button>
             </el-col>
             <el-col :span="1.5">
-              <el-button type="danger" @click="handleReturn">取消</el-button>
+              <el-button :loading="buttonLoading" type="primary" @click="submitForm(formRef)">确定</el-button>
             </el-col>
           </el-row>
         </div>
-      </el-row>
+      </div>
     </div>
+    <materialTreeSelect v-model="showSelect" @confirm="handleSelectChange" />
   </div>
 </template>
 
 <script setup lang="ts">
-import { ref, onMounted } from 'vue';
-import { getMaterialList, createDispatch } from '@/api/comprehensiveGuarantee/materialReserveManagement/materialsDistribution'; // 确保路径和导入语句是正确的
+import { createDispatch } from '@/api/comprehensiveGuarantee/materialReserveManagement/materialsDistribution';
+import materialTreeSelect from './materialTreeSelect';
+import { getMaterialWarehouseList } from '@/api/comprehensiveGuarantee/materialReserveManagement/godownManagement';
 
 const props = defineProps({
-  eventId: String
+  id: String
 });
 
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const emits = defineEmits(['close']);
 
-const tableData = ref<any[]>([]);
-const warehouseOptions = ref<{ warehouse_id: string; warehouse_name: string }[]>([]);
-const materialOptions = ref<{ material_id: number; material_name: string }[]>([]);
-const materialTypeOptions = ref<{ material_type_id: string; material_type_name: string }[]>([]);
+const formRef = ref();
+let detailData = reactive({
+  dispatch_purpose: '',
+  detail: []
+});
+const rules = reactive({
+  material_name: [{ required: true, message: '请选择物资名称', trigger: 'change' }],
+  material_quantity: [{ required: true, message: '请输入物资数量', trigger: 'blur' }],
+  dispatch_purpose: [{ required: true, message: '请输入调度目的', trigger: 'blur' }],
+  material_purpose: [{ required: true, message: '请输入物资用途', trigger: 'blur' }]
+});
+let buttonLoading = ref(false);
+let warehouseList = ref([]);
 
-// 添加默认行
-const addDefaultRow = () => {
+const handleAddRow = () => {
   const newRow = {
-    warehouse_id: '',
-    materialTypeId: '',
-    materialType: '',
-    materialCode: '',
-    quantity: '',
-    material_purpose: '',
-    dispatch_purpose: ''
+    id: '',
+    warehouse_name: '',
+    material_name: '',
+    material_type: '',
+    material_code: '',
+    material_quantity: '',
+    material_unit_price: '',
+    material_purpose: ''
   };
-  tableData.value.push(newRow);
-};
-
-// 获取仓库、物资和物资类型列表
-const fetchMaterialList = async () => {
-  try {
-    const response = await getMaterialList();
-    if (response.code === 200) {
-      // 去重逻辑
-      const uniqueWarehouseOptions = Array.from(new Set(response.data.map(item => JSON.stringify(item)))).map(item => JSON.parse(item));
-      warehouseOptions.value = uniqueWarehouseOptions.map((item) => ({
-        warehouse_id: item.warehouse_id,
-        warehouse_name: item.warehouse_name
-      }));
-
-      const uniqueMaterialTypeOptions = Array.from(new Set(response.data.map(item => JSON.stringify({material_type_id: item.material_type_id, material_type_name: item.material_type_name})))).map(item => JSON.parse(item));
-      materialTypeOptions.value = uniqueMaterialTypeOptions.map((item) => ({
-        material_type_id: item.material_type_id,
-        material_type_name: item.material_type_name
-      }));
-
-      const uniqueMaterialOptions = Array.from(new Set(response.data.map(item => JSON.stringify({material_id: item.material_id, material_name: item.material_name})))).map(item => JSON.parse(item));
-      materialOptions.value = uniqueMaterialOptions.map((item) => ({
-        material_id: item.material_id,
-        material_name: item.material_name
-      }));
-    }
-  } catch (error) {
-    console.error('获取仓库和物资列表失败:', error);
-  }
-};
-
-// 保存编辑内容到本地存储
-const saveEdit = (index: number, key: string, value: string) => {
-  tableData.value[index][key] = value;
-  localStorage.setItem('tableData', JSON.stringify(tableData.value));
+  detailData.detail.push(newRow);
 };
 
-// 处理添加新行
-const handleAddRow = () => addDefaultRow();
-
-// 处理返回
 const handleReturn = () => {
   emits('close');
 };
 
-// 方法:转换表格数据为后端期望的格式
-const transformTableData = (): any => {
-  return {
-    dispatch_purpose: tableData.value[0].dispatch_purpose || '', // 根据实际业务逻辑填写或从其他地方获取
-    detail: tableData.value.map((row, index) => ({
-      serial_number: (index + 1).toString(),
-      warehouse_id: row.warehouse_id || null,
-      material_type_id: row.materialTypeId || null,
-      material_type: row.materialType || null,
-      material_code: row.materialCode || null,
-      material_quantity: parseInt(row.quantity, 10),
-      material_purpose: row.material_purpose || null
-    }))
-  };
+const submitForm = async (formEl) => {
+  if (!formEl) return;
+  await formEl.validate((valid) => {
+    if (valid) {
+      createDispatch(detailData).then(() => {
+        proxy.$modal.msgSuccess('新增成功');
+        emits('close', true);
+      });
+    } else {
+      nextTick(() => {
+        let isError = document.getElementsByClassName('is-error');
+        isError[0].scrollIntoView({
+          // 滚动到指定节点
+          // 值有start,center,end,nearest,当前显示在视图区域中间
+          block: 'center',
+          // 值有auto、instant,smooth,缓动动画(当前是慢速的)
+          behavior: 'smooth'
+        });
+      });
+      proxy.$modal.msgError('表单校验失败');
+      return false;
+    }
+  });
 };
 
-// 方法:处理保存操作
-const handleSave = async () => {
-  console.log('Handle Save Called'); // 调试信息
-
-  const requestData = transformTableData();
-
-  // 验证必填字段
-  if (!validateRequiredFields(requestData)) {
-    console.error('Validation failed');
-    return;
-  }
-
-  try {
-    console.log('Request Data:', requestData); // 打印请求数据
-    const response = await createDispatch(requestData);
-    console.log('Dispatch created successfully:', response);
-    // 可选:关闭对话框或其他操作
-    emits('close'); // 如果需要的话
-    emits('refresh');
-  } catch (error) {
-    console.error('物资调度创建失败:', error);
+let showSelect = ref(false);
+let selectIndex = ref('');
+const handleShowSelect = (index) => {
+  selectIndex.value = index;
+  showSelect.value = true;
+};
+const handleSelectChange = (data) => {
+  detailData.detail[selectIndex.value].material_code = data.id;
+  detailData.detail[selectIndex.value].material_name = data.label;
+  detailData.detail[selectIndex.value].warehouse_name = data.warehouse_name;
+  detailData.detail[selectIndex.value].material_type = data.type;
+};
 
-    // 提示用户关于具体的错误信息,比如哪个字段为空
-    if (error.response && error.response.data.detail) {
-      alert(error.response.data.detail); // 或者使用更友好的方式展示给用户
-    }
-  }
+let height = ref(300);
+// 计算表格高度
+const calcHeight = () => {
+  const el = document.getElementsByClassName('common-dialog-content')[0];
+  height.value = el && el.clientHeight - 173 > 400 ? el.clientHeight - 173 : 300;
 };
-// 示例验证函数实现
-const validateRequiredFields = (requestData) => {
-  if (!requestData.detail.every(item => item.warehouse_id && item.material_code && item.material_quantity > 0)) {
-    return false;
+onMounted(() => {
+  if (props.id) {
+    getDeclarationDetail(props.id).then((res) => {
+      detailData.dispatch_purpose = res.data.dispatch_purpose;
+      detailData.detail = res.data.detail;
+    });
+  } else {
+    handleAddRow();
   }
-  return true;
-};
-onMounted(async () => {
-  await fetchMaterialList();
-  addDefaultRow();
+  getMaterialWarehouseList().then((res) => {
+    warehouseList.value = res.data;
+  });
+  // getMaterialList().then((res) => {
+  //   materialList.value = res.data;
+  // });
+  calcHeight();
+  window.addEventListener('resize', calcHeight);
+});
+onUnmounted(() => {
+  window.removeEventListener('resize', calcHeight);
 });
 </script>
 
-<style scoped>
-.app-container {
-  font-family: Avenir, Helvetica, Arial, sans-serif;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-  text-align: center;
-  color: #2c3e50;
-}
-.report-period {
-  margin-top: 10px;
-  font-size: 14px;
-  color: #606266;
-}
-.editable-span {
-  cursor: pointer;
-  display: inline-block;
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-.editable-span[contenteditable='true'] {
-  white-space: normal;
-  outline: none; /* 移除编辑时的焦点边框 */
+<style lang="scss" scoped>
+.text-box {
+  width: 100%;
+  display: flex;
+  align-items: center;
+  padding-bottom: 10px;
+  color: rgba(0, 0, 0, 0.85);
+  .text1 {
+    font-size: 18px;
+    font-weight: bold;
+  }
+  .text2 {
+    font-size: 18px;
+  }
 }
-.editable-span[contenteditable='true']:empty::before {
-  content: attr(data-placeholder); /* 可选:为空时显示占位符 */
-  color: #999;
+.el-form-item {
+  margin: 18px 0;
 }
-.common-dialog-footer {
-  margin-top: 20px;
+:deep(.custom-disabled) {
+  .el-select__wrapper.is-disabled,
+  .el-input__wrapper,
+  .el-textarea__inner {
+    background-color: #ffffff !important;
+  }
+  .el-select__wrapper.is-disabled .el-select__selected-item,
+  .el-input__inner,
+  .el-textarea__inner {
+    color: rgba(0, 0, 0, 0.85) !important;
+    -webkit-text-fill-color: rgba(0, 0, 0, 0.85) !important;
+  }
 }
 </style>