|
|
|
@ -1,22 +1,22 @@ |
|
|
|
<script setup lang="ts"> |
|
|
|
import { reactive } from "vue"; |
|
|
|
import { ElButton } from "element-plus"; |
|
|
|
import { Search } from "@element-plus/icons-vue"; |
|
|
|
import DataForm from "@/components/data-form/DataForm.vue"; |
|
|
|
import type { FormField } from "@/components/data-form/DataFormTypes.ts"; |
|
|
|
import { AgGridVue } from "ag-grid-vue3"; |
|
|
|
import { type GridOptions, type IServerSideGetRowsParams } from "ag-grid-enterprise"; |
|
|
|
import type { GridApi, GridReadyEvent } from "ag-grid-community"; |
|
|
|
import { localeText as localeTextCn } from "@/components/yvTable/yv-aggrid-cn.locale"; |
|
|
|
import { Request } from "@ease-forge/shared"; |
|
|
|
import lodash from "lodash"; |
|
|
|
import { reactive, ref, watch, useTemplateRef } from 'vue' |
|
|
|
import { ElButton } from 'element-plus' |
|
|
|
import { Delete, Search, Plus } from '@element-plus/icons-vue' |
|
|
|
import DataForm from '@/components/data-form/DataForm.vue' |
|
|
|
import type { FormField } from '@/components/data-form/DataFormTypes.ts' |
|
|
|
import { AgGridVue } from 'ag-grid-vue3' |
|
|
|
import { type GridOptions, type IServerSideGetRowsParams } from 'ag-grid-enterprise' |
|
|
|
import type { GridApi, GridReadyEvent } from 'ag-grid-community' |
|
|
|
import { localeText as localeTextCn } from '@/components/yvTable/yv-aggrid-cn.locale' |
|
|
|
import { Request } from '@ease-forge/shared' |
|
|
|
import lodash from 'lodash' |
|
|
|
|
|
|
|
// 定义 Props 类型 |
|
|
|
interface ComponentProps { |
|
|
|
} |
|
|
|
|
|
|
|
// 读取组件 props 属性 |
|
|
|
const props = withDefaults(defineProps<ComponentProps>(), {}); |
|
|
|
const props = withDefaults(defineProps<ComponentProps>(), {}) |
|
|
|
|
|
|
|
// 定义 State 类型 |
|
|
|
interface ComponentState { |
|
|
|
@ -28,9 +28,11 @@ interface ComponentState { |
|
|
|
// state 属性 |
|
|
|
const state = reactive<ComponentState>({ |
|
|
|
loading: false, |
|
|
|
queryData: {}, |
|
|
|
grid1Data: [], |
|
|
|
}); |
|
|
|
queryData: { |
|
|
|
envId: '10' |
|
|
|
}, |
|
|
|
grid1Data: [] |
|
|
|
}) |
|
|
|
|
|
|
|
// 定义 Data 类型 |
|
|
|
interface ComponentData { |
|
|
|
@ -43,110 +45,267 @@ interface ComponentData { |
|
|
|
const data: ComponentData = { |
|
|
|
formFields: [ |
|
|
|
{ |
|
|
|
dataPath: 'envId', label: '环境', input: 'SelectV2', |
|
|
|
inputProps: { |
|
|
|
placeholder: '选择环境', |
|
|
|
clearable: true, |
|
|
|
options: [ |
|
|
|
{ value: '10', label: '(10)物理环境' }, |
|
|
|
{ value: '13', label: '(13)虚拟环境1' } |
|
|
|
] |
|
|
|
} |
|
|
|
}, |
|
|
|
{ |
|
|
|
dataPath: 'lpn', label: '托盘条码', input: 'Input', |
|
|
|
inputProps: { |
|
|
|
placeholder: '托盘条码', |
|
|
|
clearable: true, |
|
|
|
clearable: true |
|
|
|
} |
|
|
|
}, |
|
|
|
{ |
|
|
|
dataPath: 'locCode', label: '库存位置', input: 'Input', |
|
|
|
inputProps: { |
|
|
|
placeholder: '库存位置', |
|
|
|
clearable: true, |
|
|
|
clearable: true |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
], |
|
|
|
gridSetting: { |
|
|
|
localeText: localeTextCn, |
|
|
|
// suppressNoRowsOverlay: true, |
|
|
|
// suppressLoadingOverlay: true, |
|
|
|
// 选择行配置 |
|
|
|
rowSelection: "single", |
|
|
|
rowModelType: "serverSide", |
|
|
|
rowSelection: 'single', |
|
|
|
rowModelType: 'serverSide', |
|
|
|
columnDefs: [ |
|
|
|
{ field: 'id', headerName: 'id', editable: false, hide: true }, |
|
|
|
{ field: 'loc_code', headerName: '库位编号', editable: false }, |
|
|
|
{ field: 'lpn', headerName: '容器编码', editable: false }, |
|
|
|
{ field: 'container_type', headerName: '容器类型', editable: false }, |
|
|
|
{ field: 'rack', headerName: '货位名', editable: false }, |
|
|
|
{ field: 'bay', headerName: '货位列', editable: false }, |
|
|
|
{ field: 'level', headerName: '货位层', editable: false }, |
|
|
|
{ field: 'cell', headerName: '货位格', editable: false }, |
|
|
|
{ field: 'catalog_code', headerName: '仓库楼层', editable: false }, |
|
|
|
{ field: 'way_point', headerName: '地标名', editable: false }, |
|
|
|
{ field: 'loc_direction', headerName: '地标方位', editable: false }, |
|
|
|
{ field: 'loc_code', headerName: '库位编号', editable: false, width: 120 }, |
|
|
|
{ field: 'lpn', headerName: '容器编码', editable: false, width: 120 }, |
|
|
|
{ field: 'container_type', headerName: '容器类型', editable: false, width: 120 }, |
|
|
|
{ field: 'rack', headerName: '货位名', editable: false, width: 120 }, |
|
|
|
{ field: 'bay', headerName: '货位列', editable: false, width: 100 }, |
|
|
|
{ field: 'level', headerName: '货位层', editable: false, width: 100 }, |
|
|
|
{ field: 'cell', headerName: '货位格', editable: false, width: 100 }, |
|
|
|
{ field: 'catalog_code', headerName: '仓库楼层', editable: false, width: 110 }, |
|
|
|
{ field: 'way_point', headerName: '地标名', editable: false, width: 100 }, |
|
|
|
{ field: 'loc_direction', headerName: '地标方位', editable: false, width: 110 }, |
|
|
|
{ |
|
|
|
field: 'is_lock', headerName: '是否锁定', editable: false, |
|
|
|
valueFormatter: params => lodash.toString(params.value) === "0" ? "否" : "是", |
|
|
|
field: 'is_lock', headerName: '是否锁定', editable: false, width: 110, |
|
|
|
valueFormatter: params => lodash.toString(params.value) === '0' ? '否' : '是' |
|
|
|
}, |
|
|
|
{ |
|
|
|
field: 'is_frozen', headerName: '是否冻结', editable: false, |
|
|
|
valueFormatter: params => lodash.toString(params.value) === "0" ? "否" : "是", |
|
|
|
field: 'is_frozen', headerName: '是否冻结', editable: false, width: 110, |
|
|
|
valueFormatter: params => lodash.toString(params.value) === '0' ? '否' : '是' |
|
|
|
}, |
|
|
|
{ field: 'create_at', headerName: '创建时间', editable: false }, |
|
|
|
{ field: 'create_by', headerName: '创建人', editable: false }, |
|
|
|
{ field: 'update_at', headerName: '最后更新时间', editable: false }, |
|
|
|
{ field: 'update_by', headerName: '更新人', editable: false }, |
|
|
|
{ field: 'create_at', headerName: '创建时间', editable: false, width: 160 }, |
|
|
|
{ field: 'create_by', headerName: '创建人', editable: false, width: 100 }, |
|
|
|
{ field: 'update_at', headerName: '最后更新时间', editable: false, width: 160 }, |
|
|
|
{ field: 'update_by', headerName: '更新人', editable: false, width: 100 } |
|
|
|
], |
|
|
|
pagination: true, |
|
|
|
paginationPageSize: 50, |
|
|
|
// cacheBlockSize: 50, |
|
|
|
// suppressPaginationPanel |
|
|
|
onGridReady(event: GridReadyEvent) { |
|
|
|
data.api = event.api; |
|
|
|
data.api.setServerSideDatasource({ getRows: serverSideDatasource }); |
|
|
|
}, |
|
|
|
}, |
|
|
|
}; |
|
|
|
data.api = event.api |
|
|
|
data.api.setServerSideDatasource({ getRows: serverSideDatasource }) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
const grid = useTemplateRef<InstanceType<typeof AgGridVue>>('gridRef') |
|
|
|
|
|
|
|
function reload() { |
|
|
|
data.api.paginationGoToPage(0); |
|
|
|
data.api.setServerSideDatasource({ getRows: serverSideDatasource }); |
|
|
|
data.api.paginationGoToPage(0) |
|
|
|
data.api.setServerSideDatasource({ getRows: serverSideDatasource }) |
|
|
|
} |
|
|
|
|
|
|
|
function serverSideDatasource(params: IServerSideGetRowsParams) { |
|
|
|
const { startRow, endRow } = params.request; |
|
|
|
console.log("startRow, endRow ", params.request); |
|
|
|
const pageSize = endRow - startRow; |
|
|
|
const pageNo = Math.floor(startRow / pageSize) + 1; |
|
|
|
state.loading = true; |
|
|
|
const { startRow, endRow } = params.request |
|
|
|
console.log('startRow, endRow ', params.request) |
|
|
|
const pageSize = endRow - startRow |
|
|
|
const pageNo = Math.floor(startRow / pageSize) + 1 |
|
|
|
state.loading = true |
|
|
|
Request.request.get<PageData>( |
|
|
|
"/api/workbench/DeviceManager@queryInvLpn", |
|
|
|
'/api/workbench/DeviceManager@queryInvLpn', |
|
|
|
{ |
|
|
|
params: { |
|
|
|
...state.queryData, |
|
|
|
pageSize, |
|
|
|
pageNo, |
|
|
|
}, |
|
|
|
}, |
|
|
|
pageNo |
|
|
|
} |
|
|
|
} |
|
|
|
).then(page => { |
|
|
|
params.success({ rowData: page.records, rowCount: page.total }) |
|
|
|
}).finally(() => state.loading = false); |
|
|
|
}).finally(() => state.loading = false) |
|
|
|
} |
|
|
|
|
|
|
|
const lpnList = ref([]) |
|
|
|
const locationList = ref([]) |
|
|
|
const addInvDialogVisible = ref(false) |
|
|
|
const addInvFormRef = useTemplateRef<InstanceType<any>>('addInvFormRef') |
|
|
|
const addInvForm = reactive({ |
|
|
|
env_id: 10, |
|
|
|
lpn: '', |
|
|
|
loc_code: '', |
|
|
|
layer_index: 0, |
|
|
|
qty: 1 |
|
|
|
}) |
|
|
|
|
|
|
|
// 追踪 addInvForm 的 env_id 变化, 请求 getLpnLocations, 并且立即执行 |
|
|
|
watch(() => [addInvDialogVisible.value, addInvForm.env_id], (newVal) => { |
|
|
|
if (!addInvDialogVisible.value) { |
|
|
|
return |
|
|
|
} |
|
|
|
getLpnLocations() |
|
|
|
}, { immediate: true }) |
|
|
|
|
|
|
|
function showInvDialog() { |
|
|
|
addInvDialogVisible.value = true |
|
|
|
addInvForm.env_id = 10 |
|
|
|
addInvForm.lpn = '' |
|
|
|
addInvForm.loc_code = '' |
|
|
|
addInvForm.layer_index = 0 |
|
|
|
addInvForm.qty = 1 |
|
|
|
} |
|
|
|
|
|
|
|
function addInvCommit() { |
|
|
|
|
|
|
|
addInvFormRef.value.validate((valid) => { |
|
|
|
if (valid) { |
|
|
|
system.showLoading() |
|
|
|
Request.request.post('/api/workbench/LccController@addInvCommit', |
|
|
|
{ |
|
|
|
envId: addInvForm.env_id, |
|
|
|
lpn: addInvForm.lpn, |
|
|
|
locCode: addInvForm.loc_code, |
|
|
|
qty: Number(addInvForm.qty), |
|
|
|
layerIndex: Number(addInvForm.layer_index) |
|
|
|
} |
|
|
|
).then(res => { |
|
|
|
if (res.success) { |
|
|
|
addInvDialogVisible.value = false |
|
|
|
system.msg('添加成功', 'success') |
|
|
|
reload() |
|
|
|
|
|
|
|
} else { |
|
|
|
system.showErrorDialog(res.msg) |
|
|
|
} |
|
|
|
|
|
|
|
}).finally(() => { |
|
|
|
system.clearLoading() |
|
|
|
}) |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
function getLpnLocations() { |
|
|
|
if (!addInvForm.env_id) { |
|
|
|
lpnList.value = [] |
|
|
|
locationList.value = [] |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
system.showLoading() |
|
|
|
Request.request.post('/api/workbench/LccController@getLpnLocations', |
|
|
|
{ |
|
|
|
envId: addInvForm.env_id |
|
|
|
} |
|
|
|
).then(res => { |
|
|
|
if (res.success) { |
|
|
|
lpnList.value = res.data.lpnList || [] |
|
|
|
locationList.value = res.data.locationList || [] |
|
|
|
|
|
|
|
} else { |
|
|
|
system.showErrorDialog(res.msg) |
|
|
|
} |
|
|
|
|
|
|
|
}).finally(() => { |
|
|
|
system.clearLoading() |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
function delInvLpn() { |
|
|
|
const row = data.api?.getSelectedRows()?.[0] |
|
|
|
console.log('row', row) |
|
|
|
system.confirm('确定删除 lpn=' + row.lpn + ', locCode=' + row.loc_code + ', envId=' + row.env_id + ', 这一行?').then(res => { |
|
|
|
Request.request.get('/api/workbench/DeviceManager@delInvLpn', { |
|
|
|
params: { |
|
|
|
lpn: row.lpn, |
|
|
|
locCode: row.loc_code, |
|
|
|
envId: row.env_id |
|
|
|
} |
|
|
|
}).then(res => reload()).finally() |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
// qty 必须大于0,layer_index 必须大于等于0 |
|
|
|
const validateRule = { |
|
|
|
env_id: [{ required: true, message: '请选择环境', trigger: 'change' }], |
|
|
|
lpn: [{ required: true, message: '请选择容器编码', trigger: 'change' }], |
|
|
|
loc_code: [{ required: true, message: '请选择货位编码', trigger: 'change' }], |
|
|
|
qty: [ |
|
|
|
{ required: true, message: '请输入数量', trigger: 'change' }, |
|
|
|
{ |
|
|
|
validator: (rule, value, callback) => { |
|
|
|
if (value <= 0) { |
|
|
|
callback(new Error('数量必须大于0')) |
|
|
|
} |
|
|
|
callback() |
|
|
|
}, trigger: 'change' |
|
|
|
} |
|
|
|
], |
|
|
|
layer_index: [{ required: true, message: '请输入码垛层数', trigger: 'change' } |
|
|
|
] |
|
|
|
} |
|
|
|
</script> |
|
|
|
|
|
|
|
<template> |
|
|
|
<div class="common-layout dashboard flex-column-container"> |
|
|
|
<div class="flex-item-fixed toolbar"> |
|
|
|
<ElButton :icon="Search" :loading="state.loading" @click="reload" type="warning" plain>查询</ElButton> |
|
|
|
<ElButton :icon="Search" :loading="state.loading" @click="reload" type="primary" plain>查询</ElButton> |
|
|
|
<ElButton :icon="Plus" :loading="state.loading" @click="showInvDialog" type="warning" plain>添加库存</ElButton> |
|
|
|
<ElButton :icon="Delete" @click="delInvLpn" type="danger" plain>删除</ElButton> |
|
|
|
</div> |
|
|
|
<DataForm |
|
|
|
class="query-form flex-item-fixed" |
|
|
|
:data="state.queryData" |
|
|
|
:formFields="data.formFields" |
|
|
|
:columnCount="4" |
|
|
|
layout="bothFixed" |
|
|
|
labelWidth="85px" |
|
|
|
inputWidth="200px" |
|
|
|
:inline="true" |
|
|
|
/> |
|
|
|
<AgGridVue |
|
|
|
ref="gridRef" |
|
|
|
:class="['ag-theme-alpine', 'yv-table', 'hi-light-selected-row','allow-vertical-line', 'flex-item-fill']" |
|
|
|
v-bind="{...data.gridSetting}" |
|
|
|
> |
|
|
|
<DataForm class="query-form flex-item-fixed" :data="state.queryData" :formFields="data.formFields" :columnCount="4" |
|
|
|
layout="bothFixed" labelWidth="85px" inputWidth="200px" :inline="true" /> |
|
|
|
<AgGridVue ref="gridRef" |
|
|
|
:class="['ag-theme-alpine', 'yv-table', 'hi-light-selected-row', 'allow-vertical-line', 'flex-item-fill']" |
|
|
|
v-bind="{ ...data.gridSetting }"> |
|
|
|
</AgGridVue> |
|
|
|
<el-dialog title="添加库存" v-model="addInvDialogVisible" :width="500" draggable> |
|
|
|
<el-form ref="addInvFormRef" :model="addInvForm" label-width="80px" :rules="validateRule"> |
|
|
|
<el-form-item label="环境"> |
|
|
|
<el-select v-model="addInvForm.env_id" placeholder="请选择"> |
|
|
|
<el-option label="(10)物理环境" :value="10" /> |
|
|
|
<el-option label="(13)虚拟环境1" :value="13" /> |
|
|
|
</el-select> |
|
|
|
</el-form-item> |
|
|
|
<el-form-item label="容器编码"> |
|
|
|
<el-select :disabled="!lpnList || lpnList.length <= 0" v-model="addInvForm.lpn" placeholder="请选择" clearable filterable> |
|
|
|
<el-option v-for="item in lpnList" :key="item.lpn" :label="item.lpn" :value="item.lpn"> |
|
|
|
</el-option> |
|
|
|
</el-select> |
|
|
|
</el-form-item> |
|
|
|
<el-form-item label="货位编码"> |
|
|
|
<el-select :disabled="!lpnList || lpnList.length <= 0" v-model="addInvForm.loc_code" placeholder="请选择" clearable filterable> |
|
|
|
<el-option v-for="item in locationList" :key="item.loc_code" :label="item.loc_code" :value="item.loc_code"> |
|
|
|
</el-option> |
|
|
|
</el-select> |
|
|
|
</el-form-item> |
|
|
|
<el-form-item label="数量"> |
|
|
|
<el-input :disabled="!lpnList || lpnList.length <= 0" v-model="addInvForm.qty" placeholder="请输入数量"></el-input> |
|
|
|
</el-form-item> |
|
|
|
<el-form-item label="码垛层数"> |
|
|
|
<el-input :disabled="!lpnList || lpnList.length <= 0" v-model="addInvForm.layer_index" |
|
|
|
placeholder="请输入数量"></el-input> |
|
|
|
</el-form-item> |
|
|
|
</el-form> |
|
|
|
<template #footer> |
|
|
|
<el-button @click="addInvDialogVisible = false">取消</el-button> |
|
|
|
<el-button type="primary" @click="addInvCommit">确定</el-button> |
|
|
|
</template> |
|
|
|
</el-dialog> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
@ -154,8 +313,8 @@ function serverSideDatasource(params: IServerSideGetRowsParams) { |
|
|
|
.dashboard { |
|
|
|
height: 100%; |
|
|
|
} |
|
|
|
|
|
|
|
.query-form { |
|
|
|
height: unset; |
|
|
|
} |
|
|
|
</style> |
|
|
|
|
|
|
|
|