huminmin
2 天以前 76b797028fb7a68754d0d4f3074fa8df47cc5b93
仓储物流-入库管理列表;仓储物流-库存管理-列表、新增、领用;
已添加4个文件
已修改2个文件
已删除2个文件
1939 ■■■■ 文件已修改
src/api/inventoryManagement/stockInRecord.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/inventoryManagement/stockInventory.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/receiptManagement/components/formDia.vue 400 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue 302 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/receiptManagement/index.vue 498 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/New.vue 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/Subtract.vue 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/index.vue 342 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/inventoryManagement/stockInRecord.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
import request from "@/utils/request";
// æŸ¥è¯¢å…¥åº“信息列表
export const getStockInRecordListPage = (params) => {
    return request({
        url: "/stockInRecord/listPage",
        method: "get",
        params,
    });
};
export const updateStockInRecord = (id, data) => {
    return request({
        url: "/stockInRecord/" + id,
        method: "put",
        data: data,
    });
};
export const batchDeleteStockInRecords = (ids) => {
    return request({
        url: "/stockInRecord",
        method: "delete",
        data: ids,
    });
};
src/api/inventoryManagement/stockInventory.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
import request from "@/utils/request.js";
// åˆ†é¡µæŸ¥è¯¢åº“存记录列表
export const getStockInventoryListPage = (params) => {
    return request({
        url: "/stockInventory/pagestockInventory",
        method: "get",
        params,
    });
};
// åˆ›å»ºåº“存记录
export const createStockInventory = (params) => {
    return request({
        url: "/stockInventory/addstockInventory",
        method: "post",
        params,
    });
};
// å‡å°‘库存记录
export const subtractStockInventory = (params) => {
    return request({
        url: "/stockInventory/subtractStockInventory",
        method: "post",
        params,
    });
};
src/views/inventoryManagement/receiptManagement/components/formDia.vue
ÎļþÒÑɾ³ý
src/views/inventoryManagement/receiptManagement/components/formDiaProduct.vue
ÎļþÒÑɾ³ý
src/views/inventoryManagement/receiptManagement/index.vue
@@ -1,300 +1,81 @@
<template>
  <div class="app-container">
    <el-tabs v-model="activeTab"
             @tab-change="handleTabChange">
      <el-tab-pane label="成品入库"
                   name="production">
        <div class="search_form">
          <div>
            <span class="search_title ml10">入库日期:</span>
            <el-date-picker v-model="searchForm.timeStr"
                            type="date"
                            placeholder="请选择日期"
                            value-format="YYYY-MM-DD"
                            format="YYYY-MM-DD"
                            clearable
                            @change="handleQuery"/>
            <span class="search_title ml10">产品大类:</span>
            <el-input v-model="searchForm.productCategory"
                      style="width: 240px"
                      placeholder="请输入"
                      clearable/>
            <el-button type="primary"
                       @click="handleQuery"
                       style="margin-left: 10px">搜索
            </el-button>
          </div>
          <div>
            <el-button @click="handleOut">导出</el-button>
            <el-button type="danger"
                       plain
                       @click="handleDelete">删除
            </el-button>
          </div>
        </div>
        <div class="table_list">
          <el-table :data="tableData"
                    border
                    v-loading="tableLoading"
                    @selection-change="handleSelectionChange"
                    :expand-row-keys="expandedRowKeys"
                    :row-key="row => row.id"
                    show-summary
                    style="width: 100%"
                    :summary-method="summarizeMainTable"
                    height="calc(100vh - 18.5em)">
            <el-table-column align="center"
                             type="selection"
                             width="55"/>
            <el-table-column align="center"
                             label="序号"
                             type="index"
                             width="60"/>
            <el-table-column label="入库时间"
                             prop="createTime"
                             show-overflow-tooltip/>
            <el-table-column label="销售合同号"
                             prop="salesContractNo"
                             width="180"
                             show-overflow-tooltip/>
            <el-table-column label="产品大类"
                             prop="productCategory"
                             show-overflow-tooltip/>
            <el-table-column label="规格型号"
                             prop="specificationModel"
                             show-overflow-tooltip/>
            <el-table-column label="单位"
                             prop="unit"
                             width="70"
                             show-overflow-tooltip/>
            <el-table-column label="入库数量"
                             prop="inboundNum"
                             width="100"
                             show-overflow-tooltip/>
            <el-table-column label="单价(元)"
                             prop="unitPrice"
                             width="150"></el-table-column>
            <el-table-column label="总价(元)"
                             prop="totalPrice"
                             width="150"></el-table-column>
            <!-- <el-table-column fixed="right"
                             label="操作"
                             min-width="60"
                             align="center">
              <template #default="scope">
                <el-button link
                           type="primary"
                           size="small"
                           @click="openForm('edit', scope.row, 'production');">编辑</el-button>
              </template>
            </el-table-column> -->
          </el-table>
          <pagination v-show="total > 0"
                      :total="total"
                      layout="total, sizes, prev, pager, next, jumper"
                      :page="page.current"
                      :limit="page.size"
                      @pagination="paginationChange"/>
        </div>
      </el-tab-pane>
      <el-tab-pane label="原料入库"
                   name="purchase">
        <div class="search_form">
          <div>
            <span class="search_title ml10">入库日期:</span>
            <el-date-picker v-model="searchForm.timeStr"
                            type="date"
                            placeholder="请选择日期"
                            value-format="YYYY-MM-DD"
                            format="YYYY-MM-DD"
                            clearable
                            @change="handleQuery"/>
            <span class="search_title ml10">产品大类:</span>
            <el-input v-model="searchForm.productCategory"
                      style="width: 240px"
                      placeholder="请输入"
                      clearable/>
            <el-button type="primary"
                       @click="handleQuery"
                       style="margin-left: 10px">搜索
            </el-button>
          </div>
          <div>
            <el-button type="primary"
                       @click="openForm('add', 'purchase')">新增入库
            </el-button>
            <el-button @click="handleOut">导出</el-button>
            <el-button type="danger"
                       plain
                       @click="handleDelete">删除
            </el-button>
          </div>
        </div>
        <div class="table_list">
          <el-table :data="tableData"
                    border
                    v-loading="tableLoading"
                    @selection-change="handleSelectionChange"
                    :expand-row-keys="expandedRowKeys"
                    :row-key="row => row.id"
                    show-summary
                    style="width: 100%"
                    :summary-method="summarizeMainTable"
                    height="calc(100vh - 18.5em)">
            <el-table-column align="center"
                             type="selection"
                             width="55"/>
            <el-table-column align="center"
                             label="序号"
                             type="index"
                             width="60"/>
            <el-table-column label="入库时间"
                             prop="createTime"
                             width="100"
                             show-overflow-tooltip/>
            <el-table-column label="采购合同号"
                             prop="purchaseContractNumber"
                             width="180"
                             show-overflow-tooltip/>
            <el-table-column label="供应商名称"
                             prop="supplierName"
                             width="240"
                             show-overflow-tooltip/>
            <el-table-column label="产品大类"
                             prop="productCategory"
                             show-overflow-tooltip/>
            <el-table-column label="规格型号"
                             prop="specificationModel"
                             show-overflow-tooltip/>
            <el-table-column label="单位"
                             prop="unit"
                             width="70"
                             show-overflow-tooltip/>
            <el-table-column label="入库数量"
                             prop="inboundNum"
                             width="100"
                             show-overflow-tooltip/>
            <el-table-column label="含税单价(元)"
                             prop="taxInclusiveUnitPrice"
                             width="150"></el-table-column>
            <el-table-column label="含税总价(元)"
                             prop="taxInclusiveTotalPrice"
                             width="150"></el-table-column>
            <el-table-column label="入库人"
                             prop="createBy"
                             width="80"
                             show-overflow-tooltip/>
            <el-table-column fixed="right"
                             label="操作"
                             min-width="60"
                             align="center">
              <template #default="scope">
                <el-button link
                           :disabled="scope.row.type == 1"
                           type="primary"
                           size="small"
                           @click="openForm('edit', scope.row, 'purchase');">编辑
                </el-button>
              </template>
            </el-table-column>
          </el-table>
          <pagination v-show="total > 0"
                      :total="total"
                      layout="total, sizes, prev, pager, next, jumper"
                      :page="page.current"
                      :limit="page.size"
                      @pagination="paginationChange"/>
        </div>
      </el-tab-pane>
      <el-tab-pane label="生产入库"
                   name="product">
        <div class="search_form">
          <div>
            <span class="search_title ml10">入库日期:</span>
            <el-date-picker v-model="searchForm.timeStr"
                            type="date"
                            placeholder="请选择日期"
                            value-format="YYYY-MM-DD"
                            format="YYYY-MM-DD"
                            clearable
                            @change="handleQuery"/>
            <span class="search_title ml10">产品大类:</span>
            <el-input v-model="searchForm.productCategory"
                      style="width: 240px"
                      placeholder="请输入"
                      clearable/>
            <el-button type="primary"
                       @click="handleQuery"
                       style="margin-left: 10px">搜索
            </el-button>
          </div>
          <div>
            <el-button type="primary"
                       @click="openForm('add', 'purchase')">新增入库
            </el-button>
            <el-button @click="handleOut">导出</el-button>
            <el-button type="danger"
                       plain
                       @click="handleDelete">删除
            </el-button>
          </div>
        </div>
        <div class="table_list">
          <el-table :data="tableData"
                    border
                    v-loading="tableLoading"
                    @selection-change="handleSelectionChange"
                    :expand-row-keys="expandedRowKeys"
                    :row-key="row => row.id"
                    show-summary
                    style="width: 100%"
                    :summary-method="summarizeMainTable"
                    height="calc(100vh - 18.5em)">
            <el-table-column align="center"
                             type="selection"
                             width="55"/>
            <el-table-column align="center"
                             label="序号"
                             type="index"
                             width="60"/>
            <el-table-column label="入库时间"
                             prop="createTime"
                             width="100"
                             show-overflow-tooltip/>
            <el-table-column label="产品大类"
                             prop="productCategory"
                             show-overflow-tooltip/>
            <el-table-column label="规格型号"
                             prop="specificationModel"
                             show-overflow-tooltip/>
            <el-table-column label="单位"
                             prop="unit"
                             width="220"
                             show-overflow-tooltip/>
            <el-table-column label="入库数量"
                             prop="inboundNum"
                             width="220"
                             show-overflow-tooltip/>
            <el-table-column label="入库人"
                             prop="createBy"
                             width="220"
                             show-overflow-tooltip/>
          </el-table>
          <pagination v-show="total > 0"
                      :total="total"
                      layout="total, sizes, prev, pager, next, jumper"
                      :page="page.current"
                      :limit="page.size"
                      @pagination="pageProductChange"/>
        </div>
      </el-tab-pane>
    </el-tabs>
    <form-dia ref="formDia"
              @close="handleQuery"
              @success="handleQuery"></form-dia>
    <form-dia-product ref="formDiaProduct"
                      @close="handleQuery"
                      @success="handleQuery"></form-dia-product>
    <div class="search_form">
      <div>
        <span class="search_title ml10">入库日期:</span>
        <el-date-picker v-model="searchForm.timeStr"
                        type="date"
                        placeholder="请选择日期"
                        value-format="YYYY-MM-DD"
                        format="YYYY-MM-DD"
                        clearable
                        @change="handleQuery"/>
        <span class="search_title ml10">产品大类:</span>
        <el-input v-model="searchForm.productName"
                  style="width: 240px"
                  placeholder="请输入"
                  clearable/>
        <el-button type="primary"
                   @click="handleQuery"
                   style="margin-left: 10px">搜索
        </el-button>
      </div>
      <div>
        <el-button @click="handleOut">导出</el-button>
        <el-button type="danger"
                   plain
                   @click="handleDelete">删除
        </el-button>
      </div>
    </div>
    <div class="table_list">
      <el-table :data="tableData"
                border
                v-loading="tableLoading"
                @selection-change="handleSelectionChange"
                :expand-row-keys="expandedRowKeys"
                :row-key="row => row.id"
                show-summary
                style="width: 100%"
                :summary-method="summarizeMainTable"
                height="calc(100vh - 18.5em)">
        <el-table-column align="center"
                         type="selection"
                         width="55"/>
        <el-table-column align="center"
                         label="序号"
                         type="index"
                         width="60"/>
        <el-table-column label="入库批次"
                         prop="inboundBatches"
                         width="280"
                         show-overflow-tooltip/>
        <el-table-column label="入库时间"
                         prop="createTime"
                         show-overflow-tooltip/>
        <el-table-column label="产品大类"
                         prop="productName"
                         show-overflow-tooltip/>
        <el-table-column label="规格型号"
                         prop="model"
                         show-overflow-tooltip/>
        <el-table-column label="单位"
                         prop="unit"
                         show-overflow-tooltip/>
        <el-table-column label="入库数量"
                         prop="stockInNum"
                         show-overflow-tooltip/>
        <el-table-column label="入库人"
                         prop="createBy"
                         show-overflow-tooltip/>
      </el-table>
      <pagination v-show="total > 0"
                  :total="total"
                  layout="total, sizes, prev, pager, next, jumper"
                  :page="page.current"
                  :limit="page.size"
                  @pagination="pageProductChange"/>
    </div>
  </div>
</template>
@@ -309,29 +90,16 @@
  nextTick,
} from "vue";
import {ElMessageBox} from "element-plus";
import useUserStore from "@/store/modules/user";
import dayjs from "dayjs";
import {
  getStockInPage,
  getStockInPageByProduction,
  getStockInPageByProductProduction,
  delStockIn,
} from "@/api/inventoryManagement/stockIn.js";
import FormDia from "./components/formDia.vue";
import FormDiaProduct from "./components/formDiaProduct.vue";
// èŽ·å–å½“å‰æ—¥æœŸ
function getCurrentDate() {
  return dayjs().format("YYYY-MM-DD");
}
  getStockInRecordListPage,
  batchDeleteStockInRecords,
} from "@/api/inventoryManagement/stockInRecord.js";
const {proxy} = getCurrentInstance();
const tableData = ref([]);
const selectedRows = ref([]);
const tableLoading = ref(false);
const formDia = ref();
const formDiaProduct = ref();
const activeTab = ref("production"); // å½“前激活的 tab
const page = reactive({
@@ -342,9 +110,7 @@
const data = reactive({
  searchForm: {
    supplierName: "",
    customerName: "",
    productCategory: "",
    productName: "",
    timeStr: "",
  },
});
@@ -365,89 +131,18 @@
  page.size = obj.limit;
  getList();
};
const getList = () => {
  tableLoading.value = true;
  const params = {...page};
  // æ ¹æ®ä¸åŒçš„ tab ç±»åž‹ä¼ é€’不同的查询参数
  if (activeTab.value === "production") {
    params.customerName = searchForm.value.customerName;
    params.timeStr = searchForm.value.timeStr;
  } else {
    params.supplierName = searchForm.value.supplierName;
    params.timeStr = searchForm.value.timeStr;
  }
  params.productCategory = searchForm.value.productCategory;
  if (activeTab.value === "product") {
    getStockInPageByProductProduction(params)
        .then(res => {
          tableLoading.value = false;
          tableData.value = res.data.records;
        });
  }else {
    // æ ¹æ®ä¸åŒçš„ tab ç±»åž‹è°ƒç”¨ä¸åŒçš„æŽ¥å£
    const apiCall =
        activeTab.value === "production"
            ? getStockInPageByProduction(params)
            : getStockInPage(params);
    apiCall
        .then(res => {
          tableLoading.value = false;
          tableData.value = res.data.records;
          // å‰ç«¯è®¡ç®—总价:总价 = unitPrice * inboundNum
          tableData.value = tableData.value.map(item => {
            // ä½¿ç”¨å…¥åº“数量计算总价
            const inboundNum = Number(item.inboundNum) || 0;
            const unitPrice = Number(item.unitPrice) || 0;
            const taxInclusiveUnitPrice = Number(item.taxInclusiveUnitPrice) || 0;
            // æ ¹æ®æ ‡ç­¾é¡µç±»åž‹è®¡ç®—不同的总价
            if (activeTab.value === "production") {
              // æˆå“åº“存:总价 = unitPrice * å…¥åº“数量
              item.totalPrice = (unitPrice * inboundNum).toFixed(2);
            } else {
              // åŽŸæ–™å’Œææ–™åº“å­˜ï¼šå«ç¨Žæ€»ä»· = taxInclusiveUnitPrice * å…¥åº“数量
              item.taxInclusiveTotalPrice = (
                  taxInclusiveUnitPrice * inboundNum
              ).toFixed(2);
            }
            return item;
          });
          total.value = res.data.total;
        })
        .catch(() => {
          tableLoading.value = false;
        });
  }
};
// åˆ‡æ¢ tab
const handleTabChange = tabName => {
  page.current = 1;
  // åˆ‡æ¢ tab æ—¶æ¸…空搜索条件
  searchForm.value.supplierName = "";
  searchForm.value.customerName = "";
  searchForm.value.timeStr = "";
  searchForm.value.productCategory = "";
  getList();
};
// æ‰“开弹框
const openForm = async (type, row, tabType) => {
  const currentTab = tabType || activeTab.value;
  await nextTick(() => {
    if (currentTab === "production") {
      formDiaProduct.value?.openDialog(type, row);
    } else {
      formDia.value?.openDialog(type, row);
    }
  });
  params.timeStr = searchForm.value.timeStr;
  params.productName = searchForm.value.productName;
  getStockInRecordListPage(params)
      .then(res => {
        tableData.value = res.data.records;
      }).finally(() => {
        tableLoading.value = false;
  })
};
// è¡¨æ ¼é€‰æ‹©æ•°æ®
@@ -500,20 +195,7 @@
    type: "warning",
  })
      .then(() => {
        // æ ¹æ®å½“前 tab ç±»åž‹é€‰æ‹©ä¸åŒçš„删除接口和type参数
        let deleteApi, deleteParams;
        if (activeTab.value === "production") {
          // æˆå“åˆ é™¤ï¼Œtypeä¼ 2
          deleteApi = delStockIn;
          deleteParams = {ids, type: 2};
        } else {
          // åŽŸæ–™åˆ é™¤ï¼Œtypeä¼ 1
          deleteApi = delStockIn;
          deleteParams = {ids, type: 1};
        }
        deleteApi(deleteParams)
        batchDeleteStockInRecords(ids)
            .then(() => {
              proxy.$modal.msgSuccess("删除成功");
              getList();
src/views/inventoryManagement/stockManagement/New.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,163 @@
<template>
  <div>
    <el-dialog
        v-model="isShow"
        title="新增库存"
        width="800"
        @close="closeModal"
    >
      <el-form label-width="140px" :model="formState" label-position="top" ref="formRef">
        <el-form-item
            label="产品名称"
            prop="productModelId"
            :rules="[
                {
                required: true,
                message: '请选择产品',
                trigger: 'change',
              }
            ]"
        >
          <el-button type="primary" @click="showProductSelectDialog = true">
            {{ formState.productName ? formState.productName : '选择产品' }}
          </el-button>
        </el-form-item>
        <el-form-item
            label="规格"
            prop="productModelName"
        >
          <el-input v-model="formState.productModelName"  disabled />
        </el-form-item>
        <el-form-item
            label="单位"
            prop="unit"
        >
          <el-input v-model="formState.unit"  disabled />
        </el-form-item>
        <el-form-item
            label="数量"
            prop="qualitity"
        >
          <el-input-number v-model="formState.qualitity" :step="1" :min="0" style="width: 100%" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="formState.remark" type="textarea" />
        </el-form-item>
      </el-form>
      <!-- äº§å“é€‰æ‹©å¼¹çª— -->
      <ProductSelectDialog
          v-model="showProductSelectDialog"
          @confirm="handleProductSelect"
          single
      />
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="handleSubmit">确认</el-button>
          <el-button @click="closeModal">取消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import {ref, computed, getCurrentInstance} from "vue";
import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
import {createStockInventory} from "@/api/inventoryManagement/stockInventory.js";
const props = defineProps({
  visible: {
    type: Boolean,
    required: true,
  },
});
const emit = defineEmits(['update:visible', 'completed']);
// å“åº”式数据(替代选项式的 data)
const formState = ref({
  productId: undefined,
  productModelId: undefined,
  productName: "",
  productModelName: "",
  unit: "",
  qualitity: 0,
  remark: '',
});
const isShow = computed({
  get() {
    return props.visible;
  },
  set(val) {
    emit('update:visible', val);
  },
});
const showProductSelectDialog = ref(false);
let { proxy } = getCurrentInstance()
const closeModal = () => {
  // é‡ç½®è¡¨å•数据
  formState.value = {
    productId: undefined,
    productModelId: undefined,
    productName: "",
    productModelName: "",
    description: '',
  };
  isShow.value = false;
};
// äº§å“é€‰æ‹©å¤„理
const handleProductSelect = async (products) => {
  if (products && products.length > 0) {
    const product = products[0];
    console.log(product)
    formState.value.productId = product.productId;
    formState.value.productName = product.productName;
    formState.value.productModelName = product.model;
    formState.value.productModelId = product.id;
    formState.value.unit = product.unit;
    showProductSelectDialog.value = false;
    // è§¦å‘表单验证更新
    proxy.$refs["formRef"]?.validateField('productModelId');
  }
};
const handleSubmit = () => {
  proxy.$refs["formRef"].validate(valid => {
    if (valid) {
      // éªŒè¯æ˜¯å¦é€‰æ‹©äº†äº§å“å’Œè§„æ ¼
      if (!formState.value.productModelId) {
        proxy.$modal.msgError("请选择产品");
        return;
      }
      if (!formState.value.productModelId) {
        proxy.$modal.msgError("请选择规格");
        return;
      }
      createStockInventory(formState.value).then(res => {
        // å…³é—­æ¨¡æ€æ¡†
        isShow.value = false;
        // å‘ŠçŸ¥çˆ¶ç»„件已完成
        emit('completed');
        proxy.$modal.msgSuccess("提交成功");
      })
    }
  })
};
defineExpose({
  closeModal,
  handleSubmit,
  isShow,
});
</script>
src/views/inventoryManagement/stockManagement/Subtract.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,180 @@
<template>
  <div>
    <el-dialog
        v-model="isShow"
        title="领用"
        width="800"
        @close="closeModal"
    >
      <el-form label-width="140px" :model="formState" label-position="top" ref="formRef">
        <el-form-item
            label="产品名称"
            prop="productModelId"
            :rules="[
                {
                required: true,
                message: '请选择产品',
                trigger: 'change',
              }
            ]"
        >
          <el-button type="primary" @click="showProductSelectDialog = true" disabled>
            {{ formState.productName ? formState.productName : '选择产品' }}
          </el-button>
        </el-form-item>
        <el-form-item
            label="规格"
            prop="productModelName"
        >
          <el-input v-model="formState.model"  disabled />
        </el-form-item>
        <el-form-item
            label="单位"
            prop="unit"
        >
          <el-input v-model="formState.unit"  disabled />
        </el-form-item>
        <el-form-item
            label="数量"
            prop="qualitity"
        >
          <el-input-number v-model="formState.qualitity" :step="1" :min="0" style="width: 100%" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="formState.remark" type="textarea" />
        </el-form-item>
      </el-form>
      <!-- äº§å“é€‰æ‹©å¼¹çª— -->
      <ProductSelectDialog
          v-model="showProductSelectDialog"
          @confirm="handleProductSelect"
          single
      />
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="handleSubmit">确认</el-button>
          <el-button @click="closeModal">取消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import {ref, computed, getCurrentInstance} from "vue";
import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
import {subtractStockInventory} from "@/api/inventoryManagement/stockInventory.js";
const props = defineProps({
  visible: {
    type: Boolean,
    required: true,
  },
  record: {
    type: Object,
    default: () => {},
  }
});
const emit = defineEmits(['update:visible', 'completed']);
onMounted(() => {
  initFormData()
})
const initFormData = () => {
  if (props.record) {
    formState.value = {
      ...formState.value,
      ...props.record,
    }
  }
}
// å“åº”式数据(替代选项式的 data)
const formState = ref({
  productId: undefined,
  productModelId: undefined,
  productName: "",
  model: "",
  unit: "",
  qualitity: 0,
  remark: '',
});
const isShow = computed({
  get() {
    return props.visible;
  },
  set(val) {
    emit('update:visible', val);
  },
});
const showProductSelectDialog = ref(false);
let { proxy } = getCurrentInstance()
const closeModal = () => {
  // é‡ç½®è¡¨å•数据
  formState.value = {
    productId: undefined,
    productModelId: undefined,
    productName: "",
    productModelName: "",
    description: '',
  };
  isShow.value = false;
};
// äº§å“é€‰æ‹©å¤„理
const handleProductSelect = async (products) => {
  if (products && products.length > 0) {
    const product = products[0];
    console.log(product)
    formState.value.productId = product.productId;
    formState.value.productName = product.productName;
    formState.value.productModelName = product.model;
    formState.value.productModelId = product.id;
    formState.value.unit = product.unit;
    showProductSelectDialog.value = false;
    // è§¦å‘表单验证更新
    proxy.$refs["formRef"]?.validateField('productModelId');
  }
};
const handleSubmit = () => {
  proxy.$refs["formRef"].validate(valid => {
    if (valid) {
      // éªŒè¯æ˜¯å¦é€‰æ‹©äº†äº§å“å’Œè§„æ ¼
      if (!formState.value.productModelId) {
        proxy.$modal.msgError("请选择产品");
        return;
      }
      if (!formState.value.productModelId) {
        proxy.$modal.msgError("请选择规格");
        return;
      }
      subtractStockInventory(formState.value).then(res => {
        // å…³é—­æ¨¡æ€æ¡†
        isShow.value = false;
        // å‘ŠçŸ¥çˆ¶ç»„件已完成
        emit('completed');
        proxy.$modal.msgSuccess("提交成功");
      })
    }
  })
};
defineExpose({
  closeModal,
  handleSubmit,
  isShow,
});
</script>
src/views/inventoryManagement/stockManagement/index.vue
@@ -2,150 +2,48 @@
  <div class="app-container">
    <div class="search_form">
      <div>
        <span class="search_title">供应商名称:</span>
        <el-input v-model="searchForm.supplierName" style="width: 240px" placeholder="请输入" @change="handleQuery"
          clearable prefix-icon="Search" />
                <span class="search_title ml10">入库日期:</span>
                <el-date-picker
                    v-model="searchForm.timeStr"
                    type="date"
                    placeholder="请选择日期"
                    value-format="YYYY-MM-DD"
                    format="YYYY-MM-DD"
                    clearable
                    @change="handleQuery"
                />
        <span class="search_title ml10">产品大类:</span>
        <el-input v-model="searchForm.productName"
                  style="width: 240px"
                  placeholder="请输入"
                  clearable/>
        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button>
      </div>
      <div>
        <!-- <el-button type="primary" @click="openForm('add')">新增</el-button> -->
         <el-button type="primary" @click="isShowNewModal = true">新增库存</el-button>
        <el-button @click="handleOut">导出</el-button>
        <el-button type="danger" plain @click="handleDelete">删除</el-button>
      </div>
    </div>
    <div class="table_list">
      <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
        :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%"
        :row-class-name="tableRowClassName"
        :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)">
        :expand-row-keys="expandedRowKeys" :row-key="row => row.id" style="width: 100%"
        :row-class-name="tableRowClassName" height="calc(100vh - 18.5em)">
        <el-table-column align="center" type="selection" width="55" />
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column label="入库日期" prop="createTime" width="100" show-overflow-tooltip />
        <el-table-column label="供应商名称" prop="supplierName" width="240" show-overflow-tooltip />
        <el-table-column label="产品大类" prop="productCategory" width="100" show-overflow-tooltip />
        <el-table-column label="规格型号" prop="specificationModel" width="200" show-overflow-tooltip />
        <el-table-column label="单位" prop="unit" width="80" show-overflow-tooltip />
        <el-table-column label="库存数量" prop="inboundNum0" width="100" show-overflow-tooltip />
        <el-table-column label="库存预警数量" prop="warnNum" width="130" show-overflow-tooltip />
        <el-table-column label="含税单价" prop="taxInclusiveUnitPrice" width="100" show-overflow-tooltip />
        <el-table-column label="含税总价" prop="taxInclusiveTotalPrice" width="100" show-overflow-tooltip />
        <el-table-column label="税率(%)" prop="taxRate" width="100" show-overflow-tooltip />
        <el-table-column label="不含税总价" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />
        <el-table-column label="入库人" prop="createBy" width="80" show-overflow-tooltip />
        <el-table-column label="入库日期" prop="createTime" show-overflow-tooltip />
        <el-table-column label="产品大类" prop="productName" show-overflow-tooltip />
        <el-table-column label="规格型号" prop="model" show-overflow-tooltip />
        <el-table-column label="单位" prop="unit" show-overflow-tooltip />
        <el-table-column label="库存数量" prop="qualitity" show-overflow-tooltip />
        <el-table-column label="库存预警数量" prop="warnNum"  show-overflow-tooltip />
        <el-table-column label="最近更新时间" prop="updateTime" show-overflow-tooltip />
        <el-table-column fixed="right" label="操作" min-width="60" align="center">
          <template #default="scope">
            <el-button link type="primary" size="small" @click="openForm('edit', scope.row);">编辑</el-button>
            <el-button link type="primary" size="small" @click="showSubtractModal(scope.row)" :disabled="scope.row.qualitity > 0">领用</el-button>
          </template>
        </el-table-column>
      </el-table>
      <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
        :page="page.current" :limit="page.size" @pagination="paginationChange" />
    </div>
    <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '新增库存' : '编辑库存'" width="70%"
      @close="closeDia">
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="供应商名称:" prop="supplierName">
              <el-input disabled v-model="form.supplierName" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="产品大类:" prop="productId">
              <el-select disabled v-model="form.productCategory" placeholder="请选择" clearable filterable>
                <el-option v-for="item in productList" :key="item.id" :label="item.productName"
                           :value="item.productName" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="规格型号:" prop="productManageId">
              <el-select disabled v-model="form.specificationModel" placeholder="请先选择产品大类" clearable filterable :disabled="!form.productCategory">
                <el-option v-for="item in productModelList" :key="item.id" :label="item.model"
                           :value="item.id" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item  label="单位:" prop="customerId">
              <el-input disabled v-model="form.unit" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="库存时间:" prop="projectName">
              <el-date-picker style="width: 100%" v-model="form.updateTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
                type="date" placeholder="请选择" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="入库时间:" prop="projectName">
              <el-date-picker style="width: 100%" v-model="form.createTime" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
                type="date" placeholder="请选择" clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
    <new-stock-inventory v-if="isShowNewModal"
                 v-model:visible="isShowNewModal"
                 @completed="handleQuery" />
          <el-col :span="12">
            <el-form-item  label="含税单价:" prop="customerId">
              <el-input disabled v-model="form.taxInclusiveUnitPrice" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item  label="含税总价:" prop="customerContractNo">
              <el-input disabled v-model="form.taxInclusiveTotalPrice" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item  label="税率:" prop="customerId">
              <el-input disabled v-model="form.taxRate" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="不含税总价:" prop="entryDate">
              <el-input disabled v-model="form.taxExclusiveTotalPrice" placeholder="请输入" clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="出库人:" prop="entryPerson">
              <el-select v-model="form.createUser" placeholder="请选择" clearable>
                <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
              </el-select>
            </el-form-item>
          </el-col>
<!--          <el-col :span="12">-->
<!--          <el-form-item label="库存预警数量:" prop="warnNum">-->
<!--            <el-input v-model="form.warnNum" placeholder="请输入最低库存" clearable />-->
<!--          </el-form-item>-->
<!--        </el-col>-->
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确认</el-button>
          <el-button @click="closeDia">取消</el-button>
        </div>
      </template>
    </el-dialog>
    <subtract-stock-inventory v-if="isShowSubtractModal"
                 v-model:visible="isShowSubtractModal"
                 :record="record"
                 @completed="handleQuery" />
  </div>
</template>
@@ -153,84 +51,30 @@
import pagination from '@/components/PIMTable/Pagination.vue'
import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue'
import { ElMessageBox } from "element-plus";
import useUserStore from '@/store/modules/user'
import { userListNoPageByTenantId } from "@/api/system/user.js";
import { productTreeList,modelList } from "@/api/basicData/product.js"
import { getCurrentDate } from "@/utils/index.js";
import {
  getStockManagePage,
  delStockManage,
} from "@/api/inventoryManagement/stockManage.js";
import {
  updateManagement,updateStockIn
} from "@/api/inventoryManagement/stockIn.js";
import { getStockInventoryListPage } from "@/api/inventoryManagement/stockInventory.js";
const NewStockInventory = defineAsyncComponent(() => import("@/views/inventoryManagement/stockManagement/New.vue"));
const SubtractStockInventory = defineAsyncComponent(() => import("@/views/inventoryManagement/stockManagement/Subtract.vue"));
const userStore = useUserStore()
const { proxy } = getCurrentInstance()
const tableData = ref([])
const productData = ref([])
const selectedRows = ref([])
const userList = ref([])
const productList = ref([])
const productModelList = ref([])
// const customerOption = ref([])
const record = ref({})
const tableLoading = ref(false)
const page = reactive({
  current: 1,
  size: 100,
})
const total = ref(0)
const fileList = ref([])
const loading = ref(false);
// ç”¨æˆ·ä¿¡æ¯è¡¨å•弹框数据
const operationType = ref('')
const dialogFormVisible = ref(false)
// æ˜¯å¦æ˜¾ç¤ºæ–°å¢žå¼¹æ¡†
const isShowNewModal = ref(false)
// æ˜¯å¦æ˜¾ç¤ºé¢†ç”¨å¼¹æ¡†
const isShowSubtractModal = ref(false)
const data = reactive({
  searchForm: {
    supplierName: '',
        timeStr: '',
  },
  form: {
    supplierId: null,
    supplierName: '',
    productId: null,
    productName: '',
    userId: userStore.userId,
    nickName: '',
    productModelId: null,
    model: '',
    unit: '',
    productrecordId: null,
    taxInclusiveUnitPrice: '',
    taxInclusiveTotalPrice: '',
    taxRate: '',
    taxExclusiveTotalPrice: '',
    inboundTime: '',
    inboundBatch: '',
    stockQuantity: '',
    boundTime: '',
        warnNum: '', // æ–°å¢žæœ€ä½Žåº“存字段
    salesLedgerProductId: null,
  },
  rules: {
    supplierName: [{ required: true, message: '请输入供应商名称', trigger: 'blur' }],
    productCategory: [{ required: true, message: '请选择产品大类', trigger: 'change' }],
    specificationModel: [{ required: true, message: '请输入规格型号', trigger: 'blur' }],
    unit: [{ required: true, message: '请输入单位', trigger: 'blur' }],
    stockQuantity: [{ required: true, message: '请输入出库数量', trigger: 'blur' }],
    taxInclusiveUnitPrice: [{ required: true, message: '请输入含税单价', trigger: 'blur' }],
    taxInclusiveTotalPrice: [{ required: true, message: '请输入含税总价', trigger: 'blur' }],
    taxRate: [{ required: true, message: '请输入税率', trigger: 'blur' }],
    taxExclusiveTotalPrice: [{ required: true, message: '请输入不含税总价', trigger: 'blur' }],
    boundTime: [{ required: true, message: '请选择库存时间', trigger: 'change' }],
    inboundTime: [{ required: true, message: '请选择入库时间', trigger: 'change' }],
    inboundPerson: [{ required: true, message: '请选择出库人', trigger: 'change' }],
        warnNum: [{ required: true, message: '请输入最低库存', trigger: 'blur' }],
  }
})
const { searchForm, form, rules } = toRefs(data)
const { searchForm } = toRefs(data)
// æŸ¥è¯¢åˆ—表
/** æœç´¢æŒ‰é’®æ“ä½œ */
@@ -245,7 +89,7 @@
}
const getList = () => {
  tableLoading.value = true
  getStockManagePage({ ...searchForm.value, ...page }).then(res => {
  getStockInventoryListPage({ ...searchForm.value, ...page }).then(res => {
    tableLoading.value = false
    tableData.value = res.data.records
    total.value = res.data.total
@@ -256,19 +100,19 @@
  })
}
// ç‚¹å‡»é¢†ç”¨
const showSubtractModal = (row) => {
  record.value = row
  isShowSubtractModal.value = true
}
// è¡¨æ ¼é€‰æ‹©æ•°æ®
const handleSelectionChange = (selection) => {
  // è¿‡æ»¤æŽ‰å­æ•°æ®
  selectedRows.value = selection.filter(item => item.id);
  console.log('selection', selectedRows.value)
}
const expandedRowKeys = ref([])
// ä¸»è¡¨åˆè®¡æ–¹æ³•
const summarizeMainTable = (param) => {
  return proxy.summarizeTable(param, ['contractAmount', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']);
};
// è¡¨æ ¼è¡Œç±»å
const tableRowClassName = ({ row }) => {
@@ -279,74 +123,6 @@
  }
  return stock < warn ? 'row-low-stock' : '';
};
// æ‰“开弹框
const openForm = async (type, row) => {
  operationType.value = type
  form.value = {}
  productData.value = []
  let userLists = await userListNoPageByTenantId()
  userList.value = userLists.data
  if (type === 'edit') {
    form.value = { ...row }
    productTreeList().then(res =>{
      productList.value = res
      productList.value.forEach(i =>{
        if (i.label === row.productCategory) {
          modelList({ id: i.id }).then((res) => {
            productModelList.value = res;
          });
        }
      })
    })
  }
  form.value.entryDate = getCurrentDate() // è®¾ç½®é»˜è®¤å½•入日期为当前日期
  dialogFormVisible.value = true
}
// æäº¤è¡¨å•
const submitForm = () => {
  console.log(form.value)
  proxy.$refs["formRef"].validate(valid => {
    if (valid) {
      updateManagement(form.value).then(res => {
        proxy.$modal.msgSuccess("提交成功")
        closeDia()
        getList()
        // æäº¤åŽæ£€æŸ¥åº“存并尝试创建请购单
        // checkStockAndCreatePurchase();
      })
    }
  })
}
// æ£€æŸ¥åº“存并创建请购单
// const checkStockAndCreatePurchase = async () => {
//   const stockList = tableData.value;
//   // handList()
//   for (const item of stockList) {
//     if (item.inboundNum0 < item.warnNum) {
//       try {
//                 const stockInData = {
//                     id: item.id,
//                     quantityStock: item.warnNum + item.totalInboundNum,// ä½¿ç”¨æ–°æ ¼å¼åŒ–函数
//                 };
//                 loading.value = true
//                 await updateStockIn(stockInData)
//                 proxy.$modal.msgSuccess(`产品 ${item.productCategory} ä¿®æ”¹å…¥åº“成功`)
//                 loading.value = false
//       } catch (error) {
//         proxy.$modal.msgError(`产品 ${item.productCategory} ç”Ÿæˆè¯·è´­å•失败,请手动处理`);
//
//       }
//     }
//   }
// };
// å…³é—­å¼¹æ¡†
const closeDia = () => {
  proxy.resetForm("formRef")
  dialogFormVisible.value = false
}
// å¯¼å‡º
const handleOut = () => {
@@ -363,47 +139,9 @@
    proxy.$modal.msg("已取消")
  })
}
// åˆ é™¤
const handleDelete = () => {
  let ids = []
  if (selectedRows.value.length > 0) {
        // æ£€æŸ¥æ˜¯å¦æœ‰ä»–人维护的数据
        const unauthorizedData = selectedRows.value.filter(item => item.createUser !== userStore.id);
        if (unauthorizedData.length > 0) {
            proxy.$modal.msgWarning("不可删除他人维护的数据");
            return;
        }
    ids = selectedRows.value.map(item => item.id);
  } else {
    proxy.$modal.msgWarning('请选择数据')
    return
  }
  ElMessageBox.confirm(
    '选中的内容将被删除,是否确认删除?',
    '导出', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning',
  }
  ).then(() => {
    delStockManage({ids:ids}).then(res => {
      proxy.$modal.msgSuccess("删除成功")
      getList()
    })
  }).catch(() => {
    proxy.$modal.msg("已取消")
  })
}
onMounted(() => {
  getList()
  // checkStockAndCreatePurchase();
    // æ¯å°æ—¶æ£€æŸ¥ä¸€æ¬¡åº“å­˜
    // const intervalId = setInterval(checkStockAndCreatePurchase, 60 * 60 * 1000);
// onUnmounted(() => {
//   // ç»„件卸载时清除定时器
//   clearInterval(intervalId);
// });
})
</script>