gaoluyang
2 天以前 cd8b52bdf89a4d1101f72e0ece9f4df22a3d3f7a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<script setup lang="ts">
import type { SparePart } from '#/api/mes/dv/spare';
import { onMounted, reactive, ref } from 'vue';
import { Page, useVbenModal } from '@vben/common-ui';
import { Alert, Button, Checkbox, Form, Input, Popconfirm, Select, Space, Table, Tag } from 'ant-design-vue';
import { deleteSpare, getSparePage } from '#/api/mes/dv/spare';
import SpareForm from './modules/form.vue';
import Action from './modules/action.vue';
import Records from './modules/records.vue';
const rows=ref<SparePart[]>([]),loading=ref(false),error=ref('');
const page=ref(1),size=ref(10),total=ref(0),selected=ref<SparePart>();
const filters=reactive<{code?:string;name?:string;status?:number;shortageOnly:boolean}>({shortageOnly:false});
const [FormModal,formApi]=useVbenModal({connectedComponent:SpareForm,destroyOnClose:true});
const [ActionModal,actionApi]=useVbenModal({connectedComponent:Action,destroyOnClose:true});
const [RecordsModal,recordsApi]=useVbenModal({showConfirmButton:false});
let seq=0;
const columns=[{title:'备件编码',dataIndex:'code',width:140},{title:'备件名称',dataIndex:'name',width:180},
 {title:'规格型号',dataIndex:'specification',width:160},{title:'单位',dataIndex:'unit',width:80},
 {title:'可用库存',dataIndex:'stockQuantity',key:'stock',width:130},{title:'安全库存',dataIndex:'safetyQuantity',width:110},
 {title:'存放位置',dataIndex:'location',width:150},{title:'状态',dataIndex:'status',key:'status',width:90},
 {title:'操作',key:'action',width:290,fixed:'right' as const}];
async function load(reset=false) {
 if(reset)page.value=1;const current=++seq;loading.value=true;error.value='';
 try{const result=await getSparePage({pageNo:page.value,pageSize:size.value,...filters});if(current===seq){rows.value=result.list;total.value=result.total;}}
 catch{if(current===seq){rows.value=[];total.value=0;error.value='备件加载失败,请点击查询重试';}}
 finally{if(current===seq)loading.value=false;}
}
function reset(){Object.assign(filters,{code:undefined,name:undefined,status:undefined,shortageOnly:false});void load(true);}
function changePage(p:{current?:number;pageSize?:number}){page.value=p.current||1;size.value=p.pageSize||10;void load();}
function showForm(part?:SparePart){formApi.setData({id:part?.id}).open();}
function action(type:'issue'|'receive',part:SparePart){actionApi.setData({type,part}).open();}
function history(part:SparePart){selected.value=part;recordsApi.open();}
async function remove(part:SparePart){await deleteSpare(part.id);await load(true);}
onMounted(()=>load());
</script>
<template>
 <Page>
  <FormModal @success="load(true)" /><ActionModal @success="load(true)" />
  <RecordsModal :title="selected ? selected.name+' · 库存与领用记录' : '库存与领用记录'" class="w-full lg:w-4/5"><Records v-if="selected" :key="selected.id" :spare-part-id="selected.id" /></RecordsModal>
  <div class="mb-4 flex flex-wrap items-center justify-between gap-3"><h2 class="text-lg font-semibold">备件台账</h2><Button v-access:code="['mes:dv-spare:create']" type="primary" @click="showForm()">新增备件</Button></div>
  <Form layout="inline" class="mb-4 flex flex-wrap gap-y-3">
   <Form.Item label="备件编码"><Input v-model:value="filters.code" placeholder="完整备件编码" allow-clear @press-enter="load(true)" /></Form.Item>
   <Form.Item label="备件名称"><Input v-model:value="filters.name" placeholder="输入备件名称" allow-clear @press-enter="load(true)" /></Form.Item>
   <Form.Item label="状态"><Select v-model:value="filters.status" class="w-28" allow-clear :options="[{label:'启用',value:0},{label:'停用',value:1}]" /></Form.Item>
   <Form.Item><Checkbox v-model:checked="filters.shortageOnly">仅看低于安全库存</Checkbox></Form.Item>
   <Form.Item><Space><Button type="primary" :loading="loading" @click="load(true)">查询</Button><Button @click="reset">重置</Button></Space></Form.Item>
  </Form>
  <Alert v-if="error" class="mb-3" type="error" :message="error" />
  <Table :columns="columns" :data-source="rows" :loading="loading" row-key="id" :scroll="{x:1330}" :pagination="{current:page,pageSize:size,total,showSizeChanger:true}" @change="changePage">
   <template #bodyCell="{column,record}">
    <template v-if="column.key==='stock'"><span>{{ record.stockQuantity }}</span><Tag v-if="Number(record.stockQuantity)<Number(record.safetyQuantity)" color="warning" class="ml-2">不足</Tag></template>
    <template v-else-if="column.key==='status'"><Tag :color="record.status===0?'success':'default'">{{ record.status===0?'启用':'停用' }}</Tag></template>
    <template v-else-if="column.key==='action'"><Space :size="0" wrap>
     <Button v-access:code="['mes:dv-spare:update']" type="link" @click="showForm(record as SparePart)">编辑</Button>
     <Button v-access:code="['mes:dv-spare:receive']" type="link" :disabled="record.status!==0" @click="action('receive',record as SparePart)">入库</Button>
     <Button v-access:code="['mes:dv-spare:issue']" type="link" :disabled="record.status!==0 || Number(record.stockQuantity)<=0" @click="action('issue',record as SparePart)">领用</Button>
     <Button v-access:code="['mes:dv-spare:record']" type="link" @click="history(record as SparePart)">记录</Button>
     <Popconfirm title="确认删除备件?仅无库存且无流水的备件可删除。" @confirm="remove(record as SparePart)"><Button v-access:code="['mes:dv-spare:delete']" type="link" danger>删除</Button></Popconfirm>
    </Space></template>
   </template>
  </Table>
 </Page>
</template>