| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- import dayjs from "dayjs";
- import { message } from "@/utils/message";
- import { addDialog } from "@/components/ReDialog";
- import type { PaginationProps } from "@pureadmin/table";
- import { deviceDetection } from "@pureadmin/utils";
- import {
- getInventoryList,
- increaseStock,
- adjustStock
- } from "@/api/inventory";
- import { getProductList } from "@/api/product";
- import { getDeviceList } from "@/api/device";
- import { type Ref, ref, toRaw, reactive, onMounted } from "vue";
- import {
- ElForm,
- ElFormItem,
- ElInput,
- ElInputNumber,
- ElSelect,
- ElOption
- } from "element-plus";
- import type { InventoryItem, InventorySearchForm, StockInForm, StockAdjustForm } from "./types";
- export function useInventory(tableRef: Ref) {
- const form = reactive<InventorySearchForm>({
- deviceId: "",
- productId: "",
- lowStock: false
- });
- const formRef = ref();
- const ruleFormRef = ref();
- const dataList = ref([]);
- const loading = ref(true);
- const deviceOptions = ref([]);
- const productOptions = ref([]);
- const pagination = reactive<PaginationProps>({
- total: 0,
- pageSize: 10,
- currentPage: 1,
- background: true
- });
- const columns: TableColumnList = [
- {
- label: "设备ID",
- prop: "deviceId",
- minWidth: 120
- },
- {
- label: "设备名称",
- prop: "deviceName",
- minWidth: 120
- },
- {
- label: "商品编码",
- prop: "productCode",
- minWidth: 120
- },
- {
- label: "商品名称",
- prop: "productName",
- minWidth: 150
- },
- {
- label: "库存数量",
- prop: "stock",
- minWidth: 100,
- cellRenderer: ({ row }) => (
- <el-tag type={row.stock <= 5 ? "danger" : row.stock <= 10 ? "warning" : "success"}>
- {row.stock}
- </el-tag>
- )
- },
- {
- label: "货架号",
- prop: "shelfNum",
- minWidth: 80
- },
- {
- label: "位置",
- prop: "position",
- minWidth: 80
- },
- {
- label: "更新时间",
- prop: "lastUpdateTime",
- minWidth: 160,
- formatter: ({ lastUpdateTime }) =>
- lastUpdateTime ? dayjs(lastUpdateTime).format("YYYY-MM-DD HH:mm:ss") : "-"
- },
- {
- label: "操作",
- fixed: "right",
- width: 150,
- slot: "operation"
- }
- ];
- // 搜索
- async function onSearch() {
- loading.value = true;
- try {
- const searchParams: any = {
- page: pagination.currentPage,
- pageSize: pagination.pageSize
- };
-
- // 只添加非空的搜索条件
- if (form.deviceId) searchParams.deviceId = form.deviceId;
- if (form.productId) searchParams.productId = form.productId;
- if (form.lowStock) searchParams.lowStock = form.lowStock;
-
- const { data } = await getInventoryList(searchParams);
- if (data) {
- dataList.value = data.list || [];
- pagination.total = Number(data.total) || 0;
- }
- } catch (error) {
- console.error("获取库存列表失败:", error);
- } finally {
- setTimeout(() => {
- loading.value = false;
- }, 300);
- }
- }
- // 重置表单
- const resetForm = formEl => {
- if (!formEl) return;
- formEl.resetFields();
- pagination.currentPage = 1;
- onSearch();
- };
- // 分页
- function handleSizeChange(val: number) {
- pagination.pageSize = val;
- onSearch();
- }
- function handleCurrentChange(val: number) {
- pagination.currentPage = val;
- onSearch();
- }
- // 上货
- const stockInForm = reactive<StockInForm>({
- deviceId: "",
- productId: 0,
- productCode: "",
- productName: "",
- quantity: 1,
- shelfNum: 1,
- position: ""
- });
- function handleStockIn() {
- addDialog({
- title: "上货",
- width: "40%",
- draggable: true,
- fullscreen: deviceDetection(),
- closeOnClickModal: false,
- contentRenderer: () => (
- <ElForm ref={ruleFormRef} model={stockInForm} label-width="100px">
- <ElFormItem label="设备" prop="deviceId" rules={[{ required: true, message: "请选择设备", trigger: "change" }]}>
- <ElSelect v-model={stockInForm.deviceId} placeholder="请选择设备" class="w-full!">
- {deviceOptions.value.map(item => (
- <ElOption key={item.deviceId} label={item.deviceName} value={item.deviceId} />
- ))}
- </ElSelect>
- </ElFormItem>
- <ElFormItem label="商品" prop="productId" rules={[{ required: true, message: "请选择商品", trigger: "change" }]}>
- <ElSelect v-model={stockInForm.productId} placeholder="请选择商品" class="w-full!">
- {productOptions.value.map(item => (
- <ElOption key={item.id} label={item.name} value={item.id} />
- ))}
- </ElSelect>
- </ElFormItem>
- <ElFormItem label="数量" prop="quantity" rules={[{ required: true, message: "请输入数量", trigger: "blur" }]}>
- <ElInputNumber v-model={stockInForm.quantity} min={1} class="w-full!" />
- </ElFormItem>
- <ElFormItem label="货架号" prop="shelfNum">
- <ElInputNumber v-model={stockInForm.shelfNum} min={1} class="w-full!" />
- </ElFormItem>
- <ElFormItem label="位置" prop="position">
- <ElInput v-model={stockInForm.position} placeholder="请输入位置" clearable />
- </ElFormItem>
- </ElForm>
- ),
- beforeSure: async (done) => {
- const valid = await ruleFormRef.value.validate().catch(() => false);
- if (!valid) return;
- try {
- const res = await increaseStock(toRaw(stockInForm));
- if (res.code === 200) {
- message("上货成功", { type: "success" });
- done();
- onSearch();
- } else {
- message(res.message || "上货失败", { type: "error" });
- }
- } catch (error) {
- message("上货失败", { type: "error" });
- }
- }
- });
- }
- // 库存调整
- const adjustForm = reactive<StockAdjustForm>({
- deviceId: "",
- productId: 0,
- newStock: 0,
- remark: ""
- });
- function handleAdjust(row: InventoryItem) {
- adjustForm.deviceId = row.deviceId;
- adjustForm.productId = row.productId;
- adjustForm.newStock = row.stock;
- adjustForm.remark = "";
- addDialog({
- title: "库存调整",
- width: "30%",
- draggable: true,
- fullscreen: deviceDetection(),
- closeOnClickModal: false,
- contentRenderer: () => (
- <ElForm ref={ruleFormRef} model={adjustForm} label-width="100px">
- <ElFormItem label="当前库存">{row.stock}</ElFormItem>
- <ElFormItem label="调整后库存" prop="newStock" rules={[{ required: true, message: "请输入调整后库存", trigger: "blur" }]}>
- <ElInputNumber v-model={adjustForm.newStock} min={0} class="w-full!" />
- </ElFormItem>
- <ElFormItem label="备注" prop="remark">
- <ElInput v-model={adjustForm.remark} type="textarea" placeholder="请输入备注" rows={3} />
- </ElFormItem>
- </ElForm>
- ),
- beforeSure: async (done) => {
- const valid = await ruleFormRef.value.validate().catch(() => false);
- if (!valid) return;
- try {
- const res = await adjustStock(toRaw(adjustForm));
- if (res.code === 200) {
- message("库存调整成功", { type: "success" });
- done();
- onSearch();
- } else {
- message(res.message || "调整失败", { type: "error" });
- }
- } catch (error) {
- message("调整失败", { type: "error" });
- }
- }
- });
- }
- // 获取设备列表
- async function fetchDeviceOptions() {
- try {
- const { data } = await getDeviceList({ page: 1, pageSize: 1000 });
- deviceOptions.value = data.list || [];
- } catch (error) {
- console.error("获取设备列表失败:", error);
- }
- }
- // 获取商品列表
- async function fetchProductOptions() {
- try {
- const { data } = await getProductList({ page: 1, pageSize: 1000 });
- productOptions.value = data.list || [];
- } catch (error) {
- console.error("获取商品列表失败:", error);
- }
- }
- onMounted(async () => {
- await Promise.all([fetchDeviceOptions(), fetchProductOptions()]);
- onSearch();
- });
- return {
- form,
- loading,
- columns,
- dataList,
- pagination,
- deviceOptions,
- productOptions,
- onSearch,
- resetForm,
- handleStockIn,
- handleAdjust,
- handleSizeChange,
- handleCurrentChange
- };
- }
|