|
|
|
|
@ -56,10 +56,14 @@
|
|
|
|
|
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['wcs:taskQueue:add']">新增</el-button>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="1.5">
|
|
|
|
|
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['wcs:taskQueue:edit']">修改</el-button>
|
|
|
|
|
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['wcs:taskQueue:edit']"
|
|
|
|
|
>修改</el-button
|
|
|
|
|
>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="1.5">
|
|
|
|
|
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['wcs:taskQueue:remove']">删除</el-button>
|
|
|
|
|
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['wcs:taskQueue:remove']"
|
|
|
|
|
>删除</el-button
|
|
|
|
|
>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="1.5">
|
|
|
|
|
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['wcs:taskQueue:export']">导出</el-button>
|
|
|
|
|
@ -109,8 +113,11 @@
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="创建人" align="center" prop="createByName" width="100" />
|
|
|
|
|
<el-table-column label="更新人" align="center" prop="updateByName" width="100" />
|
|
|
|
|
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width" width="120">
|
|
|
|
|
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width" width="160">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<el-tooltip content="明细" placement="top">
|
|
|
|
|
<el-button link type="primary" icon="Tickets" @click="handleDetail(scope.row)" v-hasPermi="['wcs:taskDetail:list']">明细</el-button>
|
|
|
|
|
</el-tooltip>
|
|
|
|
|
<el-tooltip content="修改" placement="top">
|
|
|
|
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['wcs:taskQueue:edit']"></el-button>
|
|
|
|
|
</el-tooltip>
|
|
|
|
|
@ -138,7 +145,12 @@
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="物料编号" prop="materialCode">
|
|
|
|
|
<el-select v-model="form.materialCode" placeholder="请选择物料" clearable filterable class="w-full" @change="handleMaterialChange">
|
|
|
|
|
<el-option v-for="item in materialList" :key="item.objId" :label="`${item.materialCode} / ${item.materialName}`" :value="item.materialCode" />
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="item in materialList"
|
|
|
|
|
:key="item.objId"
|
|
|
|
|
:label="`${item.materialCode} / ${item.materialName}`"
|
|
|
|
|
:value="item.materialCode"
|
|
|
|
|
/>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
@ -222,8 +234,20 @@
|
|
|
|
|
<el-table border :data="detailList" size="small">
|
|
|
|
|
<el-table-column label="物料编号" align="center" prop="materialCode" min-width="130">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<el-select v-model="scope.row.materialCode" placeholder="物料" clearable filterable size="small" @change="handleDetailMaterialChange(scope.row)">
|
|
|
|
|
<el-option v-for="item in materialList" :key="item.objId" :label="`${item.materialCode} / ${item.materialName}`" :value="item.materialCode" />
|
|
|
|
|
<el-select
|
|
|
|
|
v-model="scope.row.materialCode"
|
|
|
|
|
placeholder="物料"
|
|
|
|
|
clearable
|
|
|
|
|
filterable
|
|
|
|
|
size="small"
|
|
|
|
|
@change="handleDetailMaterialChange(scope.row)"
|
|
|
|
|
>
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="item in materialList"
|
|
|
|
|
:key="item.objId"
|
|
|
|
|
:label="`${item.materialCode} / ${item.materialName}`"
|
|
|
|
|
:value="item.materialCode"
|
|
|
|
|
/>
|
|
|
|
|
</el-select>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
@ -314,11 +338,46 @@
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
<el-drawer v-model="detailDrawer.visible" :title="detailDrawer.title" size="68%" append-to-body>
|
|
|
|
|
<el-table v-loading="detailLoading" border :data="taskDetailDrawerList" height="calc(100vh - 150px)">
|
|
|
|
|
<el-table-column label="序号" align="center" type="index" width="60" />
|
|
|
|
|
<el-table-column label="物料编号" align="center" prop="materialCode" min-width="110" />
|
|
|
|
|
<el-table-column label="物料名称" align="center" prop="materialName" min-width="110" />
|
|
|
|
|
<el-table-column label="托盘条码" align="center" prop="palletBarcode" min-width="120" />
|
|
|
|
|
<el-table-column label="物料数量" align="center" prop="materialCount" width="90" />
|
|
|
|
|
<el-table-column label="任务类型" align="center" prop="taskType" width="100">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<dict-tag :options="wcs_task_type" :value="scope.row.taskType" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="任务类别" align="center" prop="taskCategory" width="100">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<dict-tag :options="wcs_task_category" :value="scope.row.taskCategory" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="起始位置" align="center" prop="startPoint" min-width="120" />
|
|
|
|
|
<el-table-column label="结束位置" align="center" prop="endPoint" min-width="120" />
|
|
|
|
|
<el-table-column label="路径编号" align="center" prop="pathCode" min-width="110" />
|
|
|
|
|
<el-table-column label="路径名称" align="center" prop="pathName" min-width="110" />
|
|
|
|
|
<el-table-column label="任务状态" align="center" prop="taskStatus" width="100">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<dict-tag :options="wcs_task_status" :value="scope.row.taskStatus" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="是否标识" align="center" prop="isFlag" width="90">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<dict-tag :options="wcs_is_flag" :value="scope.row.isFlag" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table>
|
|
|
|
|
</el-drawer>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup name="TaskQueue" lang="ts">
|
|
|
|
|
import { listTaskQueue, getTaskQueue, delTaskQueue, addTaskQueue, updateTaskQueue } from '@/api/wcs/taskQueue';
|
|
|
|
|
import { listTaskDetail } from '@/api/wcs/taskDetail';
|
|
|
|
|
import { TaskQueueVO, TaskQueueQuery, TaskQueueForm } from '@/api/wcs/taskQueue/types';
|
|
|
|
|
import { TaskDetailForm, TaskDetailVO } from '@/api/wcs/taskDetail/types';
|
|
|
|
|
import { getMaterialInfoList } from '@/api/wcs/materialInfo';
|
|
|
|
|
@ -339,10 +398,12 @@ const { wcs_is_flag, wcs_task_category, wcs_task_type, wcs_task_status } = toRef
|
|
|
|
|
|
|
|
|
|
const taskQueueList = ref<TaskQueueVO[]>([]);
|
|
|
|
|
const detailList = ref<TaskDetailForm[]>([]);
|
|
|
|
|
const taskDetailDrawerList = ref<TaskDetailVO[]>([]);
|
|
|
|
|
const materialList = ref<MaterialInfoVO[]>([]);
|
|
|
|
|
const pathList = ref<PathInfoVO[]>([]);
|
|
|
|
|
const buttonLoading = ref(false);
|
|
|
|
|
const loading = ref(true);
|
|
|
|
|
const detailLoading = ref(false);
|
|
|
|
|
const showSearch = ref(true);
|
|
|
|
|
const activeTab = ref('basic');
|
|
|
|
|
const ids = ref<Array<string | number>>([]);
|
|
|
|
|
@ -360,6 +421,10 @@ const dialog = reactive<DialogOption>({
|
|
|
|
|
visible: false,
|
|
|
|
|
title: ''
|
|
|
|
|
});
|
|
|
|
|
const detailDrawer = reactive<DialogOption>({
|
|
|
|
|
visible: false,
|
|
|
|
|
title: ''
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const initFormData: TaskQueueForm = {
|
|
|
|
|
objId: undefined,
|
|
|
|
|
@ -379,7 +444,7 @@ const initFormData: TaskQueueForm = {
|
|
|
|
|
remark: undefined,
|
|
|
|
|
createTime: undefined,
|
|
|
|
|
details: []
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const data = reactive<PageData<TaskQueueForm, TaskQueueQuery>>({
|
|
|
|
|
form: { ...initFormData },
|
|
|
|
|
queryParams: {
|
|
|
|
|
@ -401,9 +466,7 @@ const data = reactive<PageData<TaskQueueForm, TaskQueueQuery>>({
|
|
|
|
|
params: {}
|
|
|
|
|
},
|
|
|
|
|
rules: {
|
|
|
|
|
taskCode: [
|
|
|
|
|
{ required: true, message: "任务编号不能为空", trigger: "blur" }
|
|
|
|
|
],
|
|
|
|
|
taskCode: [{ required: true, message: '任务编号不能为空', trigger: 'blur' }]
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
@ -419,99 +482,119 @@ const getList = async () => {
|
|
|
|
|
} finally {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getMaterialList = async () => {
|
|
|
|
|
// 下拉接口只取启用的业务主数据,避免把分页查询形态强塞进免分页接口。
|
|
|
|
|
const res = await getMaterialInfoList({ isFlag: 1, params: {} });
|
|
|
|
|
materialList.value = res.data || [];
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getPathList = async () => {
|
|
|
|
|
// 路径下拉仅需要启用状态过滤,保持与后端 getPathInfoList 契约一致。
|
|
|
|
|
const res = await getPathInfoList({ isFlag: 1, params: {} });
|
|
|
|
|
pathList.value = res.data || [];
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const loadFormOptions = async () => {
|
|
|
|
|
await Promise.all([getMaterialList(), getPathList()]);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleMaterialChange = (materialCode?: string) => {
|
|
|
|
|
const material = materialList.value.find(item => item.materialCode === materialCode);
|
|
|
|
|
const material = materialList.value.find((item) => item.materialCode === materialCode);
|
|
|
|
|
// 物料条码来自物料主数据,只能随物料选择同步,避免现场手工改出编码与条码不一致的数据。
|
|
|
|
|
form.value.materialBarcode = material?.materialBarcode;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleDetailMaterialChange = (row: TaskDetailForm) => {
|
|
|
|
|
const material = materialList.value.find(item => item.materialCode === row.materialCode);
|
|
|
|
|
const material = materialList.value.find((item) => item.materialCode === row.materialCode);
|
|
|
|
|
// 明细物料条码同样由主数据带出,清空物料时同步清空派生条码,避免残留旧值。
|
|
|
|
|
row.materialBarcode = material?.materialBarcode;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const cancel = () => {
|
|
|
|
|
reset();
|
|
|
|
|
dialog.visible = false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const reset = () => {
|
|
|
|
|
form.value = { ...initFormData, isFlag: 1, details: [] };
|
|
|
|
|
detailList.value = [];
|
|
|
|
|
activeTab.value = 'basic';
|
|
|
|
|
taskQueueFormRef.value?.resetFields();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleQuery = () => {
|
|
|
|
|
queryParams.value.pageNum = 1;
|
|
|
|
|
getList();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const resetQuery = () => {
|
|
|
|
|
queryFormRef.value?.resetFields();
|
|
|
|
|
// 重置后恢复当天完整范围,避免刚新增的数据落在旧结束时间之后。
|
|
|
|
|
dateRange.value = getTodayCreatedTimeRange();
|
|
|
|
|
handleQuery();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleSelectionChange = (selection: TaskQueueVO[]) => {
|
|
|
|
|
ids.value = selection.map(item => item.objId);
|
|
|
|
|
ids.value = selection.map((item) => item.objId);
|
|
|
|
|
single.value = selection.length != 1;
|
|
|
|
|
multiple.value = !selection.length;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleAdd = async () => {
|
|
|
|
|
reset();
|
|
|
|
|
await loadFormOptions();
|
|
|
|
|
dialog.visible = true;
|
|
|
|
|
dialog.title = "添加实时任务队列";
|
|
|
|
|
}
|
|
|
|
|
dialog.title = '添加实时任务队列';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleUpdate = async (row?: TaskQueueVO) => {
|
|
|
|
|
reset();
|
|
|
|
|
await loadFormOptions();
|
|
|
|
|
const _objId = row?.objId || ids.value[0]
|
|
|
|
|
const _objId = row?.objId || ids.value[0];
|
|
|
|
|
const res = await getTaskQueue(_objId);
|
|
|
|
|
Object.assign(form.value, res.data);
|
|
|
|
|
detailList.value = res.data.details ? res.data.details.map((d: TaskDetailVO) => ({
|
|
|
|
|
objId: d.objId,
|
|
|
|
|
taskCode: d.taskCode,
|
|
|
|
|
materialCode: d.materialCode,
|
|
|
|
|
palletBarcode: d.palletBarcode,
|
|
|
|
|
materialBarcode: d.materialBarcode,
|
|
|
|
|
materialCount: d.materialCount,
|
|
|
|
|
taskType: d.taskType,
|
|
|
|
|
taskCategory: d.taskCategory,
|
|
|
|
|
startPoint: d.startPoint,
|
|
|
|
|
endPoint: d.endPoint,
|
|
|
|
|
isValidate: d.isValidate,
|
|
|
|
|
pathCode: d.pathCode,
|
|
|
|
|
taskStatus: d.taskStatus,
|
|
|
|
|
isFlag: d.isFlag,
|
|
|
|
|
remark: d.remark
|
|
|
|
|
})) : [];
|
|
|
|
|
detailList.value = res.data.details
|
|
|
|
|
? res.data.details.map((d: TaskDetailVO) => ({
|
|
|
|
|
objId: d.objId,
|
|
|
|
|
taskCode: d.taskCode,
|
|
|
|
|
materialCode: d.materialCode,
|
|
|
|
|
palletBarcode: d.palletBarcode,
|
|
|
|
|
materialBarcode: d.materialBarcode,
|
|
|
|
|
materialCount: d.materialCount,
|
|
|
|
|
taskType: d.taskType,
|
|
|
|
|
taskCategory: d.taskCategory,
|
|
|
|
|
startPoint: d.startPoint,
|
|
|
|
|
endPoint: d.endPoint,
|
|
|
|
|
isValidate: d.isValidate,
|
|
|
|
|
pathCode: d.pathCode,
|
|
|
|
|
taskStatus: d.taskStatus,
|
|
|
|
|
isFlag: d.isFlag,
|
|
|
|
|
remark: d.remark
|
|
|
|
|
}))
|
|
|
|
|
: [];
|
|
|
|
|
dialog.visible = true;
|
|
|
|
|
dialog.title = "修改实时任务队列";
|
|
|
|
|
}
|
|
|
|
|
dialog.title = '修改实时任务队列';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleDetail = async (row: TaskQueueVO) => {
|
|
|
|
|
detailDrawer.visible = true;
|
|
|
|
|
detailDrawer.title = `任务明细 - ${row.taskCode}`;
|
|
|
|
|
taskDetailDrawerList.value = [];
|
|
|
|
|
detailLoading.value = true;
|
|
|
|
|
try {
|
|
|
|
|
const res = await listTaskDetail({
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
pageSize: 999,
|
|
|
|
|
taskCode: row.taskCode,
|
|
|
|
|
params: {}
|
|
|
|
|
});
|
|
|
|
|
taskDetailDrawerList.value = res.rows || [];
|
|
|
|
|
} finally {
|
|
|
|
|
detailLoading.value = false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleAddDetail = () => {
|
|
|
|
|
detailList.value.push({
|
|
|
|
|
@ -531,11 +614,11 @@ const handleAddDetail = () => {
|
|
|
|
|
isFlag: 1,
|
|
|
|
|
remark: ''
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleDelDetail = (index: number) => {
|
|
|
|
|
detailList.value.splice(index, 1);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const buildSubmitData = (): TaskQueueForm => ({
|
|
|
|
|
objId: form.value.objId,
|
|
|
|
|
@ -554,7 +637,7 @@ const buildSubmitData = (): TaskQueueForm => ({
|
|
|
|
|
isFlag: form.value.isFlag,
|
|
|
|
|
remark: form.value.remark,
|
|
|
|
|
// 明细与主表通过任务编号关联,提交前只保留业务字段,避免把展示名称等派生字段回传。
|
|
|
|
|
details: detailList.value.map(item => ({
|
|
|
|
|
details: detailList.value.map((item) => ({
|
|
|
|
|
objId: item.objId,
|
|
|
|
|
taskCode: form.value.taskCode || '',
|
|
|
|
|
materialCode: item.materialCode,
|
|
|
|
|
@ -579,36 +662,40 @@ const submitForm = () => {
|
|
|
|
|
buttonLoading.value = true;
|
|
|
|
|
const submitData = buildSubmitData();
|
|
|
|
|
if (submitData.objId) {
|
|
|
|
|
await updateTaskQueue(submitData).finally(() => buttonLoading.value = false);
|
|
|
|
|
await updateTaskQueue(submitData).finally(() => (buttonLoading.value = false));
|
|
|
|
|
} else {
|
|
|
|
|
await addTaskQueue(submitData).finally(() => buttonLoading.value = false);
|
|
|
|
|
await addTaskQueue(submitData).finally(() => (buttonLoading.value = false));
|
|
|
|
|
}
|
|
|
|
|
proxy?.$modal.msgSuccess("操作成功");
|
|
|
|
|
proxy?.$modal.msgSuccess('操作成功');
|
|
|
|
|
dialog.visible = false;
|
|
|
|
|
await getList();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleDelete = async (row?: TaskQueueVO) => {
|
|
|
|
|
const _objIds = row?.objId || ids.value;
|
|
|
|
|
try {
|
|
|
|
|
await proxy?.$modal.confirm('是否确认删除实时任务队列编号为"' + _objIds + '"的数据项?');
|
|
|
|
|
await delTaskQueue(_objIds);
|
|
|
|
|
proxy?.$modal.msgSuccess("删除成功");
|
|
|
|
|
proxy?.$modal.msgSuccess('删除成功');
|
|
|
|
|
await getList();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
if (e !== 'cancel' && e !== 'close') {
|
|
|
|
|
proxy?.$modal.msgError("删除实时任务队列失败");
|
|
|
|
|
proxy?.$modal.msgError('删除实时任务队列失败');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleExport = () => {
|
|
|
|
|
proxy?.download('wcs/taskQueue/export', {
|
|
|
|
|
...queryParams.value
|
|
|
|
|
}, `taskQueue_${new Date().getTime()}.xlsx`)
|
|
|
|
|
}
|
|
|
|
|
proxy?.download(
|
|
|
|
|
'wcs/taskQueue/export',
|
|
|
|
|
{
|
|
|
|
|
...queryParams.value
|
|
|
|
|
},
|
|
|
|
|
`taskQueue_${new Date().getTime()}.xlsx`
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
getList();
|
|
|
|
|
|