You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
591 lines
17 KiB
Vue
591 lines
17 KiB
Vue
<template>
|
|
<div>
|
|
<my-card title="搜索条件" search>
|
|
<n-form inline>
|
|
<!-- <n-form-item label="筛选">
|
|
<n-button class="mr-10px" :type="searchForm.type === '1' ? 'primary' : 'default'" @click="selectCondition()">
|
|
线盘
|
|
</n-button>
|
|
</n-form-item> -->
|
|
<n-form-item label="型号">
|
|
<n-input v-model:value="searchForm.model" placeholder="请输入型号" />
|
|
</n-form-item>
|
|
<n-form-item label="规格">
|
|
<n-input v-model:value="searchForm.specification" placeholder="请输入规格" />
|
|
</n-form-item>
|
|
<!-- <n-form-item v-show="searchForm.type === '1'" label="线盘">
|
|
<n-input v-model:value="searchForm.wireDisc" placeholder="请输入线盘" />
|
|
</n-form-item> -->
|
|
<n-form-item label="预警状态">
|
|
<n-select
|
|
v-model:value="searchForm.warningValue"
|
|
placeholder="请选择预警状态"
|
|
class="w-180px"
|
|
:options="warningStatusList"
|
|
></n-select>
|
|
</n-form-item>
|
|
<n-form-item label="同步时间">
|
|
<n-input :value="data[0]?.updateTime" :disabled="true" />
|
|
</n-form-item>
|
|
<n-form-item>
|
|
<n-button class="mr-5px" type="primary" @click="handleSearch">
|
|
<icon-tdesign-search class="mr-2px" />
|
|
搜索
|
|
</n-button>
|
|
<n-button @click="handleReset">
|
|
<icon-ic-round-refresh class="mr-4px text-20px" />
|
|
重置
|
|
</n-button>
|
|
</n-form-item>
|
|
</n-form>
|
|
</my-card>
|
|
<my-card title="成品库存列表">
|
|
<template #right>
|
|
<!-- <n-button size="small" type="error" style="margin-right: 10px" :disabled="data.length === 0" @click="clearData">
|
|
<icon-mdi-delete />
|
|
重置成品数据
|
|
</n-button> -->
|
|
<CxColumns v-model:columns="columns" />
|
|
</template>
|
|
<n-data-table
|
|
:loading="loading"
|
|
:columns="showColumns"
|
|
:data="data"
|
|
:max-height="dataTableConfig.maxHeight"
|
|
:scroll-x="dataTableConfig.scrollWidth(columns)"
|
|
></n-data-table>
|
|
<my-pagination v-model:search-form="searchForm" @init="init"></my-pagination>
|
|
</my-card>
|
|
|
|
<my-dialog v-model:show="show" title="设置预警值" width="800px" @cancel="show = false" @submit="submit">
|
|
<template #content>
|
|
<n-form
|
|
ref="formRef"
|
|
style="width: 700px"
|
|
:model="addForm"
|
|
label-placement="left"
|
|
label-width="120px"
|
|
:rules="rules"
|
|
>
|
|
<n-grid :x-gap="12" :cols="2">
|
|
<n-form-item-grid-item label="型号: ">
|
|
<n-space>{{ addForm.model }}</n-space>
|
|
</n-form-item-grid-item>
|
|
<n-form-item-grid-item label="规格: ">
|
|
<n-space>{{ addForm.specification }}</n-space>
|
|
</n-form-item-grid-item>
|
|
<n-form-item-grid-item label="颜色: ">
|
|
<n-space>{{ addForm.wireDisc }}</n-space>
|
|
</n-form-item-grid-item>
|
|
<!-- <n-form-item-grid-item label="当前数量: ">
|
|
<n-space>{{ showDialogForm.totalNetWeight }}</n-space>
|
|
</n-form-item-grid-item> -->
|
|
<n-form-item-grid-item label="当前箱数: ">
|
|
<n-space>{{ getNum(showDialogForm.totalNumber) }}</n-space>
|
|
</n-form-item-grid-item>
|
|
<n-form-item-grid-item :span="12">
|
|
<n-divider title-placement="center"></n-divider>
|
|
</n-form-item-grid-item>
|
|
<n-form-item-grid-item required label="预警最低箱数: " path="warningNumberMin">
|
|
<n-input-number v-model:value="addForm.warningNumberMin"></n-input-number>
|
|
</n-form-item-grid-item>
|
|
<n-form-item-grid-item required label="预警最高箱数: " path="warningNumberMax">
|
|
<n-input-number v-model:value="addForm.warningNumberMax"></n-input-number>
|
|
</n-form-item-grid-item>
|
|
</n-grid>
|
|
</n-form>
|
|
</template>
|
|
</my-dialog>
|
|
|
|
<my-dialog
|
|
:title="'新增销售订单'"
|
|
:show="showAddSaleOrder"
|
|
width="750px"
|
|
@cancel="() => (showAddSaleOrder = false)"
|
|
@submit="handleSubmit"
|
|
>
|
|
<template #content>
|
|
<div>
|
|
<n-form
|
|
ref="addFormRef"
|
|
label-placement="left"
|
|
label-width="100px"
|
|
label-align="left"
|
|
:model="addSaleOrderForm"
|
|
:rules="saleOrderRules"
|
|
>
|
|
<n-grid :cols="24" :x-gap="20">
|
|
<n-form-item-grid-item label="订单类型" :span="11" path="orderType">
|
|
<n-select
|
|
v-model:value="addSaleOrderForm.orderType"
|
|
placeholder="请选择订单类型"
|
|
:options="typeOption"
|
|
:disabled="true"
|
|
clearable
|
|
/>
|
|
</n-form-item-grid-item>
|
|
<n-form-item-grid-item label="关联产品" :span="11" path="productId">
|
|
<n-select
|
|
v-model:value="addSaleOrderForm.productId"
|
|
:options="productOptions"
|
|
filterable
|
|
placeholder="请选择关联的产品"
|
|
:disabled="true"
|
|
@update-value="
|
|
(val, item : any ) => {
|
|
addForm.model = item.label;
|
|
}
|
|
"
|
|
/>
|
|
</n-form-item-grid-item>
|
|
<n-form-item-grid-item label="数量" :span="11" path="weight">
|
|
<n-input-number v-model:value="addSaleOrderForm.weight" placeholder="请输入数量"></n-input-number>
|
|
</n-form-item-grid-item>
|
|
<n-form-item-grid-item label="单位" :span="11" path="measureId">
|
|
<n-select
|
|
v-model:value="addSaleOrderForm.measureId"
|
|
filterable
|
|
:options="unitOptions"
|
|
placeholder="请选择单位"
|
|
:disabled="true"
|
|
/>
|
|
</n-form-item-grid-item>
|
|
<n-form-item-grid-item :span="11" label="交付日期" path="payTime">
|
|
<n-date-picker v-model:value="addSaleOrderForm.payTime" type="date" placeholder="请选择交付日期" />
|
|
</n-form-item-grid-item>
|
|
</n-grid>
|
|
</n-form>
|
|
</div>
|
|
</template>
|
|
</my-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="tsx">
|
|
import type { Ref } from 'vue';
|
|
import { ref, onMounted, watch } from 'vue';
|
|
import type { DataTableColumns, FormInst } from 'naive-ui';
|
|
// import { useDialog } from 'naive-ui';
|
|
import { createRequiredFormRule } from '@/utils';
|
|
import {
|
|
getFinishedProductInventory,
|
|
// deleteFinishedProductInventory,
|
|
setWmsProductWarning
|
|
} from '@/service/api/storage/finishedProductInventory';
|
|
import { dataTableConfig } from '@/config/dataTableConfig';
|
|
import { getUserList } from '@/service/api/sale/userManage';
|
|
import { getAllProductList } from '@/service/api/md/list/index';
|
|
import { getAllUnit } from '@/service/api/md/unit/index';
|
|
import { addSaleOrder } from '@/service/api/sale/order';
|
|
import { useLoading } from '~/src/hooks';
|
|
import { useResetSearch } from '~/src/utils/common/searchReset';
|
|
const { loading, startLoading, endLoading } = useLoading();
|
|
|
|
const { searchForm, reset } = useResetSearch({
|
|
pageNum: 1,
|
|
pageSize: 10,
|
|
total: 0,
|
|
model: '',
|
|
specification: '',
|
|
type: '1',
|
|
machineNumber: '',
|
|
wireDisc: '',
|
|
warningValue: null
|
|
});
|
|
|
|
const addForm = ref<finishedProductInventory.addForm>({
|
|
model: '',
|
|
specification: '',
|
|
wireDisc: '',
|
|
warningNumberMin: 0,
|
|
warningNumberMax: 0
|
|
});
|
|
|
|
const showDialogForm = ref<finishedProductInventory.showDialogForm>({
|
|
totalNumber: 0,
|
|
totalNetWeight: 0
|
|
});
|
|
|
|
const rules = {
|
|
warningNumberMin: createRequiredFormRule('请设置预警最低箱数'),
|
|
warningNumberMax: createRequiredFormRule('请设置预警最高箱数')
|
|
};
|
|
|
|
const saleOrderRules = {
|
|
orderType: createRequiredFormRule('请选择订单类型'),
|
|
productId: createRequiredFormRule('请选择关联的产品'),
|
|
weight: createRequiredFormRule('请输入数量'),
|
|
measureId: createRequiredFormRule('请选择单位'),
|
|
payTime: createRequiredFormRule('请选择交付日期')
|
|
};
|
|
|
|
const warningStatusList = ref<Array<{ label: string; value: string }>>([
|
|
{ label: '未设置', value: '0' },
|
|
{ label: '正常', value: '1' },
|
|
{ label: '低于预警', value: '2' },
|
|
{ label: '高于预警', value: '3' }
|
|
]);
|
|
const typeOption = ref<Array<{ label: string; value: string }>>([
|
|
{
|
|
label: `备库订单`,
|
|
value: '1'
|
|
}
|
|
]);
|
|
const customerOptions = ref<{ value: string; label: string }[]>([]);
|
|
const productOptions = ref<{ value: string; label: string }[]>([]);
|
|
const unitOptions = ref<{ value: string; label: string }[]>([]);
|
|
const formRef = ref<FormInst | null>(null);
|
|
const addFormRef = ref<FormInst | null>(null);
|
|
const searchRequestComplete = ref<boolean>(true);
|
|
|
|
const show = ref<boolean>(false);
|
|
|
|
const showAddSaleOrder = ref<boolean>(false);
|
|
|
|
const data = ref<Array<finishedProductInventory.tableList>>([]);
|
|
|
|
const addSaleOrderForm = ref<finishedProductInventory.addSaleOrderForm>({
|
|
orderType: '1',
|
|
productId: null,
|
|
specification: '',
|
|
model: '',
|
|
weight: 0,
|
|
measureId: 28,
|
|
payTime: null
|
|
});
|
|
|
|
// const dialog = useDialog();
|
|
|
|
const columns: Ref<DataTableColumns<finishedProductInventory.tableList>> = ref([
|
|
{
|
|
title: '序号',
|
|
key: 'index',
|
|
width: 100,
|
|
align: 'center',
|
|
render: (_row, index) => (searchForm.value.pageNum - 1) * searchForm.value.pageSize + index + 1
|
|
},
|
|
{
|
|
title: '型号',
|
|
key: 'model',
|
|
width: 200,
|
|
align: 'center'
|
|
},
|
|
{
|
|
title: '规格',
|
|
key: 'specification',
|
|
width: 100,
|
|
align: 'center'
|
|
},
|
|
{
|
|
title: '颜色',
|
|
key: 'wireDisc',
|
|
width: 200,
|
|
align: 'center'
|
|
},
|
|
{
|
|
title: '付',
|
|
key: 'totalNumber',
|
|
width: 100,
|
|
align: 'center',
|
|
render: row => getNum(row.totalNumber)
|
|
},
|
|
// {
|
|
// title: '净重(kg)',
|
|
// key: 'totalNetWeight',
|
|
// width: 120,
|
|
// align: 'center'
|
|
// },
|
|
// {
|
|
// title: '毛重(kg)',
|
|
// key: 'totalGrossWeight',
|
|
// width: 120,
|
|
// align: 'center'
|
|
// },
|
|
{
|
|
title: '预警状态',
|
|
key: '',
|
|
width: 120,
|
|
align: 'center',
|
|
render: row => {
|
|
const resultStatus = warningStatus(row.warningValue);
|
|
return <n-tag type={resultStatus.type}>{resultStatus.text}</n-tag>;
|
|
}
|
|
},
|
|
{
|
|
title: '操作',
|
|
key: 'action',
|
|
width: 100,
|
|
align: 'center',
|
|
render: row => {
|
|
return (
|
|
<n-space>
|
|
<n-button
|
|
type="info"
|
|
size="small"
|
|
v-show={searchForm.value.type === '1' && row.warningValue === '0'}
|
|
onClick={() => {
|
|
setEarlyWarningValue(row);
|
|
}}
|
|
>
|
|
设置预警值
|
|
</n-button>
|
|
<n-button
|
|
type="warning"
|
|
size="small"
|
|
v-show={searchForm.value.type === '1' && row.warningValue === '2'}
|
|
onClick={() => {
|
|
handleAddSaleOrder(row);
|
|
}}
|
|
>
|
|
生成销售订单
|
|
</n-button>
|
|
</n-space>
|
|
);
|
|
}
|
|
}
|
|
]);
|
|
|
|
const showColumns: Ref<DataTableColumns<finishedProductInventory.tableList>> = ref([]);
|
|
|
|
function getNum(num: number) {
|
|
if (Math.floor(Number(num) / 10) > 40) {
|
|
return Math.floor(Number(num) / 100);
|
|
}
|
|
return Math.floor(Number(num) / 10) || 1;
|
|
}
|
|
|
|
function setEarlyWarningValue(row: finishedProductInventory.tableList) {
|
|
show.value = true;
|
|
showDialogForm.value.totalNumber = 0;
|
|
showDialogForm.value.totalNetWeight = 0;
|
|
for (const key in showDialogForm.value) {
|
|
if (row[key]) {
|
|
showDialogForm.value[key] = row[key];
|
|
}
|
|
}
|
|
|
|
addForm.value.model = row.model;
|
|
addForm.value.specification = row.specification;
|
|
addForm.value.wireDisc = row.wireDisc;
|
|
addForm.value.warningNumberMin = 0;
|
|
addForm.value.warningNumberMax = 0;
|
|
}
|
|
|
|
function handleAddSaleOrder(row: finishedProductInventory.tableList) {
|
|
showAddSaleOrder.value = true;
|
|
addSaleOrderForm.value = {
|
|
orderType: '1',
|
|
productId: null,
|
|
specification: '',
|
|
model: '',
|
|
weight: 0,
|
|
measureId: 28,
|
|
payTime: null
|
|
};
|
|
const model = `${row.specification?.trim()} (${row.model?.trim()})`;
|
|
const productItem = productOptions.value.find(item => item.label === model);
|
|
addSaleOrderForm.value.productId = productItem?.value || null;
|
|
if (!addSaleOrderForm.value.productId) {
|
|
window.$message?.warning('请去产品列表页面添加该型号和规格');
|
|
}
|
|
}
|
|
function handleSubmit() {
|
|
if (!addSaleOrderForm.value.productId) {
|
|
window.$message?.warning('请去产品列表页面添加该型号和规格');
|
|
return;
|
|
}
|
|
addFormRef.value?.validate(errors => {
|
|
if (errors) return;
|
|
if (addSaleOrderForm.value.weight <= 0) {
|
|
window.$message?.warning('数量需要超过0');
|
|
return;
|
|
}
|
|
const modelItem = productOptions.value.find(item => item.value === addSaleOrderForm.value.productId);
|
|
addSaleOrderForm.value.model = modelItem?.label || '';
|
|
addSaleOrder(addSaleOrderForm.value).then((res: any) => {
|
|
if (res.code === 200) {
|
|
window.$message?.success('添加成功');
|
|
showAddSaleOrder.value = false;
|
|
init();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function submit() {
|
|
formRef.value?.validate(errors => {
|
|
if (!errors) {
|
|
if (addForm.value.warningNumberMax <= 0 || addForm.value.warningNumberMin <= 0) {
|
|
window.$message?.warning('预警数要大于0');
|
|
return;
|
|
}
|
|
if (addForm.value.warningNumberMax <= addForm.value.warningNumberMin) {
|
|
window.$message?.warning('预警最高箱数要比预警最低箱数多');
|
|
return;
|
|
}
|
|
setWmsProductWarning(addForm.value).then(res => {
|
|
if (res.code === 200) {
|
|
window.$message?.success('设置成功');
|
|
init();
|
|
show.value = false;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
function warningStatus(status: string) {
|
|
switch (status) {
|
|
case '0':
|
|
return { text: '未设置', type: 'info' };
|
|
case '1':
|
|
return { text: '正常', type: 'success' };
|
|
case '2':
|
|
return { text: '低于预警', type: 'error' };
|
|
case '3':
|
|
return { text: '高于预警', type: 'warning' };
|
|
default:
|
|
return { text: '未设置', type: 'info' };
|
|
}
|
|
}
|
|
|
|
// function selectCondition() {
|
|
// if (!searchRequestComplete.value) {
|
|
// window.$message?.warning('搜索中请稍等');
|
|
// return;
|
|
// }
|
|
// if (searchForm.value.type === '1') {
|
|
// searchForm.value.type = '0';
|
|
// } else {
|
|
// searchForm.value.type = '1';
|
|
// }
|
|
|
|
// init();
|
|
// }
|
|
|
|
// function clearData() {
|
|
// const d = dialog.warning({
|
|
// title: '提示',
|
|
// content: '此操作需要较长时间进行同步数据,确认要重置成品数据吗?',
|
|
// positiveText: '确认',
|
|
// negativeText: '取消',
|
|
// onPositiveClick: () => {
|
|
// d.loading = true;
|
|
// return new Promise(resolve => {
|
|
// deleteFinishedProductInventory().then(res => {
|
|
// if (res.code === 200) {
|
|
// window.$message?.success('重置成功,请等待一段时间刷新');
|
|
// init();
|
|
// }
|
|
// resolve(true);
|
|
// });
|
|
// });
|
|
// }
|
|
// });
|
|
// }
|
|
|
|
function handleSearch() {
|
|
searchForm.value.pageNum = 1;
|
|
init();
|
|
}
|
|
|
|
function handleReset() {
|
|
reset();
|
|
showColumns.value = columns.value.map(item => item);
|
|
init();
|
|
}
|
|
|
|
function init() {
|
|
if (!searchRequestComplete.value) {
|
|
window.$message?.warning('搜索中请稍等');
|
|
return;
|
|
}
|
|
searchRequestComplete.value = false;
|
|
startLoading();
|
|
getFinishedProductInventory(searchForm.value).then(res => {
|
|
searchRequestComplete.value = true;
|
|
endLoading();
|
|
searchForm.value.total = res.total;
|
|
if (res.code === 200 && res.rows?.length > 0) {
|
|
data.value = res.rows;
|
|
} else {
|
|
data.value = [];
|
|
}
|
|
});
|
|
}
|
|
|
|
function getList() {
|
|
getUserList(null).then(res => {
|
|
if (res.code === 200) {
|
|
customerOptions.value = [];
|
|
res.rows.forEach((item: any) => {
|
|
customerOptions.value.push({
|
|
label: item.clientName,
|
|
value: item.id
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
getAllUnit().then(res => {
|
|
if (res.code === 200) {
|
|
unitOptions.value = [];
|
|
res.data.forEach((item: any) => {
|
|
unitOptions.value.push({
|
|
label: item.measureName,
|
|
value: item.id
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
getAllProductList().then(res => {
|
|
if (res.code === 200) {
|
|
productOptions.value = [];
|
|
res.data.forEach((item: any) => {
|
|
productOptions.value.push({
|
|
label: `${item.specification} (${item.productSize})`,
|
|
value: item.id
|
|
});
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
watch(
|
|
() => searchForm.value.type,
|
|
newValue => {
|
|
if (newValue === '1') {
|
|
showColumns.value = columns.value.map(item => item);
|
|
} else {
|
|
showColumns.value = columns.value.filter((item: any) => item.key !== 'wireDisc');
|
|
searchForm.value.wireDisc = '';
|
|
}
|
|
}
|
|
);
|
|
|
|
onMounted(() => {
|
|
init();
|
|
getList();
|
|
showColumns.value = columns.value.map(item => item);
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
:deep(.n-space) {
|
|
justify-content: flex-end !important;
|
|
}
|
|
|
|
:deep(.n-base-selection-input) {
|
|
color: #000 !important;
|
|
}
|
|
|
|
:deep(.n-base-selection-overlay__wrapper) {
|
|
color: #000 !important;
|
|
}
|
|
|
|
:deep(.n-input__input-el) {
|
|
color: black !important;
|
|
}
|
|
</style>
|