spring
4 小时以前 b6bf928d53681a459c47a05a482f1f9a1c90ca63
fix: 添加备件领用记录
已添加1个文件
已修改1个文件
309 ■■■■ 文件已修改
src/api/equipmentManagement/sparePartsUsage.js 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/spareParts/index.vue 273 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/equipmentManagement/sparePartsUsage.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
import request from "@/utils/request";
/**
 * å¤‡ä»¶é¢†ç”¨è®°å½• - åˆ†é¡µæŸ¥è¯¢
 * params: { current, size, sparePartId?, sparePartName?, source?, deviceId?, startTime?, endTime? }
 */
export const getSparePartsUsagePage = (params) => {
  return request({
    url: "/sparePartsUsage/listPage",
    method: "get",
    params,
  });
};
/**
 * å¤‡ä»¶é¢†ç”¨è®°å½• - æ–°å¢ž
 * data ç¤ºä¾‹ï¼š
 * {
 *   source: "repair" | "upkeep" | "manual",
 *   sourceId?: number | string,
 *   deviceId?: number | string,
 *   deviceName?: string,
 *   operatorId?: number | string,
 *   operator?: string,
 *   useTime?: string, // YYYY-MM-DD HH:mm:ss
 *   items: [{ sparePartId: number|string, qty: number }]
 * }
 */
export const addSparePartsUsage = (data) => {
  return request({
    url: "/sparePartsUsage/add",
    method: "post",
    data,
  });
};
src/views/equipmentManagement/spareParts/index.vue
@@ -1,83 +1,123 @@
<template>
  <div class="spare-part-category">
        <div class="search_form">
            <el-form :inline="true" :model="queryParams" class="search-form">
                <el-form-item label="备件名称">
                    <el-input
                        v-model="queryParams.name"
                        placeholder="请输入备件名称"
                        clearable
                        style="width: 240px"
                    />
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="handleQuery">查询</el-button>
                    <el-button @click="resetQuery">重置</el-button>
                </el-form-item>
            </el-form>
            <div>
                <el-button type="primary" @click="addCategory" >新增</el-button>
            </div>
        </div>
    <PIMTable
        rowKey="id"
        :column="columns"
        :tableData="renderTableData"
        :tableLoading="loading"
        :page="pagination"
        :isShowPagination="true"
        @pagination="handleSizeChange"
    >
      <template #status="{ row }">
        <el-tag type="success" size="small">{{ row.status }}</el-tag>
      </template>
    </PIMTable>
    <el-dialog title="分类管理" v-model="dialogVisible" width="60%">
      <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
        <el-form-item label="设备" prop="deviceLedgerIds">
          <el-select
            v-model="form.deviceLedgerIds"
            placeholder="请选择设备"
            filterable
            default-first-option
            :reserve-keyword="false"
            multiple
            style="width: 100%"
          >
            <el-option
              v-for="(item, index) in deviceOptions"
              :key="index"
              :label="item.deviceName"
              :value="item.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="备件名称" prop="name">
          <el-input v-model="form.name"></el-input>
        </el-form-item>
        <el-form-item label="备件编号" prop="sparePartsNo">
          <el-input v-model="form.sparePartsNo"></el-input>
        </el-form-item>
        <el-form-item label="数量" prop="quantity">
          <el-input type="number" v-model="form.quantity"></el-input>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-select v-model="form.status" placeholder="请选择状态">
            <el-option label="正常" value="正常"></el-option>
            <el-option label="禁用" value="禁用"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="描述" prop="description">
          <el-input v-model="form.description"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false" :disabled="formLoading">取消</el-button>
          <el-button type="primary" @click="submitForm" :loading="formLoading">确定</el-button>
        </span>
      </template>
    </el-dialog>
    <el-tabs v-model="activeTab" @tab-change="handleTabChange">
      <el-tab-pane label="备件列表" name="list">
        <div class="search_form">
          <el-form :inline="true" :model="queryParams" class="search-form">
            <el-form-item label="备件名称">
              <el-input
                v-model="queryParams.name"
                placeholder="请输入备件名称"
                clearable
                style="width: 240px"
              />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="handleQuery">查询</el-button>
              <el-button @click="resetQuery">重置</el-button>
            </el-form-item>
          </el-form>
          <div>
            <el-button type="primary" @click="addCategory">新增</el-button>
          </div>
        </div>
        <PIMTable
          rowKey="id"
          :column="columns"
          :tableData="renderTableData"
          :tableLoading="loading"
          :page="pagination"
          :isShowPagination="true"
          @pagination="handleSizeChange"
        >
          <template #status="{ row }">
            <el-tag type="success" size="small">{{ row.status }}</el-tag>
          </template>
        </PIMTable>
        <el-dialog title="分类管理" v-model="dialogVisible" width="60%">
          <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
            <el-form-item label="设备" prop="deviceLedgerIds">
              <el-select
                v-model="form.deviceLedgerIds"
                placeholder="请选择设备"
                filterable
                default-first-option
                :reserve-keyword="false"
                multiple
                style="width: 100%"
              >
                <el-option
                  v-for="(item, index) in deviceOptions"
                  :key="index"
                  :label="item.deviceName"
                  :value="item.id"
                ></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="备件名称" prop="name">
              <el-input v-model="form.name"></el-input>
            </el-form-item>
            <el-form-item label="备件编号" prop="sparePartsNo">
              <el-input v-model="form.sparePartsNo"></el-input>
            </el-form-item>
            <el-form-item label="数量" prop="quantity">
              <el-input type="number" v-model="form.quantity"></el-input>
            </el-form-item>
            <el-form-item label="状态" prop="status">
              <el-select v-model="form.status" placeholder="请选择状态">
                <el-option label="正常" value="正常"></el-option>
                <el-option label="禁用" value="禁用"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="描述" prop="description">
              <el-input v-model="form.description"></el-input>
            </el-form-item>
          </el-form>
          <template #footer>
            <span class="dialog-footer">
              <el-button @click="dialogVisible = false" :disabled="formLoading">取消</el-button>
              <el-button type="primary" @click="submitForm" :loading="formLoading">确定</el-button>
            </span>
          </template>
        </el-dialog>
      </el-tab-pane>
      <el-tab-pane label="备件领用记录" name="usage">
        <div class="search_form">
          <el-form :inline="true" :model="usageQuery" class="search-form">
            <el-form-item label="备件名称">
              <el-input
                v-model="usageQuery.sparePartName"
                placeholder="请输入备件名称"
                clearable
                style="width: 240px"
              />
            </el-form-item>
            <el-form-item label="来源">
              <el-select v-model="usageQuery.source" placeholder="请选择" clearable style="width: 200px">
                <el-option label="ç»´ä¿®" value="ç»´ä¿®" />
                <el-option label="保养" value="保养" />
                <el-option label="手工" value="手工" />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="handleUsageQuery">查询</el-button>
              <el-button @click="resetUsageQuery">重置</el-button>
            </el-form-item>
          </el-form>
        </div>
        <PIMTable
          rowKey="rowKey"
          :column="usageColumns"
          :tableData="usageTableData"
          :tableLoading="usageLoading"
          :page="usagePagination"
          :isShowPagination="true"
          @pagination="handleUsagePageChange"
        />
      </el-tab-pane>
    </el-tabs>
  </div>
</template>
@@ -87,10 +127,12 @@
import { getSparePartsList, addSparePart, editSparePart, delSparePart } from "@/api/equipmentManagement/spareParts";
import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
import PIMTable from "@/components/PIMTable/PIMTable.vue";
import { getSparePartsUsagePage } from "@/api/equipmentManagement/sparePartsUsage";
// åŠ è½½çŠ¶æ€
const loading = ref(false);
const formLoading = ref(false);
const activeTab = ref("list");
// å¯¹è¯æ¡†æ˜¾ç¤ºçŠ¶æ€
const dialogVisible = ref(false);
// ç¼–辑 ID
@@ -115,6 +157,35 @@
  size: 10,
  total: 0
});
// å¤‡ä»¶é¢†ç”¨è®°å½•
const usageLoading = ref(false);
const usageQuery = reactive({
  sparePartName: "",
  source: "",
});
const usagePagination = reactive({
  current: 1,
  size: 10,
  total: 0,
});
const usageTableData = ref([]);
const usageColumns = ref([
  { label: "来源", prop: "sourceText" },
  { label: "单据/记录ID", prop: "sourceId" },
  { label: "设备名称", prop: "deviceName" },
  { label: "备件名称", prop: "sparePartName" },
  { label: "领用数量", prop: "qty" },
  { label: "操作人", prop: "operator" },
  { label: "时间", prop: "useTime" },
]);
const handleTabChange = async (name) => {
  if (name === "usage") {
    usagePagination.current = 1;
    await fetchUsageData();
  }
};
// è¡¨å•数据
const form = reactive({
  id:'',
@@ -252,6 +323,52 @@
  }
}
const fetchUsageData = async () => {
  usageLoading.value = true;
  try {
    const res = await getSparePartsUsagePage({
      current: usagePagination.current,
      size: usagePagination.size,
      sparePartName: usageQuery.sparePartName || undefined,
      source: usageQuery.source || undefined,
    });
    if (res?.code === 200) {
      const records = res?.data?.records || [];
      usagePagination.total = res?.data?.total || 0;
      usageTableData.value = records.map((r, idx) => ({
        rowKey: r.id ?? `${usagePagination.current}-${idx}`,
        ...r,
        sourceText:
          r.source === "ç»´ä¿®" ? "ç»´ä¿®" :
          r.source === "保养" ? "保养" :
          r.source === "手工" ? "手工" :
          (r.source || "-"),
      }));
    } else {
      usagePagination.total = 0;
      usageTableData.value = [];
    }
  } finally {
    usageLoading.value = false;
  }
};
const handleUsageQuery = () => {
  usagePagination.current = 1;
  fetchUsageData();
};
const resetUsageQuery = () => {
  usageQuery.sparePartName = "";
  usageQuery.source = "";
  usagePagination.current = 1;
  fetchUsageData();
};
const handleUsagePageChange = (obj) => {
  usagePagination.current = obj.page;
  usagePagination.size = obj.limit;
  fetchUsageData();
};
// æŸ¥è¯¢
const handleQuery = () => {
  pagination.current = 1;