Commit eac36f02 by wusiyi

feat: 等待补货界面调整 #1012100

parent e193f6ab
...@@ -359,6 +359,14 @@ export function getRestockListApi( ...@@ -359,6 +359,14 @@ export function getRestockListApi(
) )
} }
// 等待补货统计 导出
export function exportPodOrderOutOfStockApi(data: Record<string, unknown>) {
return axios.post<never, BaseRespData<never>>(
'factory/podOrder/outOfStock/exportPodOrderOutOfStock',
data,
)
}
export function getBatchManageListApi( export function getBatchManageListApi(
data: Record<string, unknown>, data: Record<string, unknown>,
currentPage: number, currentPage: number,
......
<template> <template>
<ElDialog
v-model="visible"
title="等待补货统计"
width="1500px"
:close-on-click-modal="false"
>
<div class="waiting-restock"> <div class="waiting-restock">
<div class="restock-filter"> <div class="restock-filter">
<ElForm <ElForm
...@@ -7,10 +13,26 @@ ...@@ -7,10 +13,26 @@
size="default" size="default"
class="search-form" class="search-form"
> >
<ElFormItem label="仓库">
<ElSelect
v-model="filterForm.warehouseId"
placeholder="请选择仓库"
style="width: 180px"
filterable
clearable
>
<ElOption
v-for="item in warehouseList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</ElSelect>
</ElFormItem>
<ElFormItem label="库存SKU"> <ElFormItem label="库存SKU">
<ElInput <ElInput
v-model="filterForm.warehouseSku" v-model="filterForm.warehouseSku"
placeholder="库存SKU" placeholder="请输入库存SKU"
clearable clearable
style="width: 150px" style="width: 150px"
/> />
...@@ -18,7 +40,7 @@ ...@@ -18,7 +40,7 @@
<ElFormItem label="款号"> <ElFormItem label="款号">
<ElInput <ElInput
v-model="filterForm.productNo" v-model="filterForm.productNo"
placeholder="款号" placeholder="请输入款号"
clearable clearable
style="width: 150px" style="width: 150px"
/> />
...@@ -26,6 +48,7 @@ ...@@ -26,6 +48,7 @@
<ElFormItem> <ElFormItem>
<ElButton type="primary" @click="handleSearch">查询</ElButton> <ElButton type="primary" @click="handleSearch">查询</ElButton>
<ElButton @click="handleReset">重置</ElButton> <ElButton @click="handleReset">重置</ElButton>
<ElButton type="success" @click="handleExport">导出</ElButton>
</ElFormItem> </ElFormItem>
</ElForm> </ElForm>
</div> </div>
...@@ -57,21 +80,64 @@ ...@@ -57,21 +80,64 @@
@current-change="onCurrentPageChange" @current-change="onCurrentPageChange"
/> />
</div> </div>
</ElDialog>
</template> </template>
<script setup lang="tsx"> <script setup lang="tsx">
import { reactive } from 'vue' import { reactive, ref } from 'vue'
import { ElMessage } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { getRestockListApi, restockCheckApi } from '@/api/factoryOrderNew' import { loadWarehouseListApi } from '@/api/common'
import {
getRestockListApi,
restockCheckApi,
exportPodOrderOutOfStockApi,
} from '@/api/factoryOrderNew'
import { filePath } from '@/api/axios'
import type { WarehouseListData } from '@/types'
import type { RestockData } from '@/types/api/factoryOrderNew' import type { RestockData } from '@/types/api/factoryOrderNew'
import TableView from '@/components/TableView.vue' import TableView from '@/components/TableView.vue'
import usePageList from '@/utils/hooks/usePageList' import usePageList from '@/utils/hooks/usePageList'
const props = defineProps<{
visible: boolean
}>()
const emit = defineEmits<{
(e: 'update:visible', value: boolean): void
}>()
const visible = computed({
get() {
return props.visible
},
set(value: boolean) {
emit('update:visible', value)
},
})
const warehouseList = ref<WarehouseListData[]>([])
const filterForm = reactive({ const filterForm = reactive({
warehouseId: undefined as number | undefined,
warehouseSku: '', warehouseSku: '',
productNo: '', productNo: '',
}) })
const loadWarehouseList = async () => {
try {
const res = await loadWarehouseListApi()
if (res.code !== 200) return
warehouseList.value = res.data || []
} catch (e) {
console.error(e)
}
}
const buildQueryParams = () => ({
warehouseId: filterForm.warehouseId || undefined,
warehouseSku: filterForm.warehouseSku || undefined,
productNo: filterForm.productNo || undefined,
})
const { const {
loading, loading,
currentPage, currentPage,
...@@ -83,27 +149,26 @@ const { ...@@ -83,27 +149,26 @@ const {
refresh, refresh,
} = usePageList<RestockData>({ } = usePageList<RestockData>({
initPageSize: 50, initPageSize: 50,
initLoad: false,
query: async (current, size) => { query: async (current, size) => {
const res = await getRestockListApi( const res = await getRestockListApi(buildQueryParams(), current, size)
{
warehouseSku: filterForm.warehouseSku || undefined,
productNo: filterForm.productNo || undefined,
},
current,
size,
)
return res.data return res.data
}, },
}) })
watch(visible, async (newVal) => {
if (newVal) {
filterForm.warehouseId = undefined
filterForm.warehouseSku = ''
filterForm.productNo = ''
await loadWarehouseList()
refresh()
}
})
const columns = [ const columns = [
{ {
prop: 'warehouseName', label: '图片',
label: '仓库名称',
width: 160,
},
{
label: 'SKU图片',
width: 100, width: 100,
align: 'center', align: 'center',
render: (row: RestockData) => { render: (row: RestockData) => {
...@@ -118,18 +183,32 @@ const columns = [ ...@@ -118,18 +183,32 @@ const columns = [
}, },
}, },
{ {
prop: 'skuName', prop: 'warehouseName',
label: '商品名称', label: '仓库名称',
minWidth: 140, width: 160,
showOverflowTooltip: true, align: 'center',
},
{
prop: 'locationCode',
label: '库位',
width: 160,
align: 'center',
}, },
{ prop: 'productNo', label: '款号', width: 130, align: 'center' },
{ {
prop: 'warehouseSku', prop: 'warehouseSku',
label: '库存SKU', label: '库存SKU',
width: 200, width: 200,
align: 'center', align: 'center',
}, },
{ prop: 'productNo', label: '款号', width: 130, align: 'center' },
{
prop: 'skuName',
label: '商品名称',
minWidth: 180,
showOverflowTooltip: true,
},
{ {
prop: 'usableInventory', prop: 'usableInventory',
label: '缺货数量', label: '缺货数量',
...@@ -174,10 +253,13 @@ const handleSearch = () => { ...@@ -174,10 +253,13 @@ const handleSearch = () => {
refresh() refresh()
} }
const handleReset = () => { const handleExport = async () => {
filterForm.warehouseSku = '' try {
filterForm.productNo = '' await exportPodOrderOutOfStockApi(buildQueryParams())
refresh() ElMessage.success('请求成功,请稍后到右上角[我的下载]中查看')
} catch (e) {
console.error(e)
}
} }
const handleRestockCheck = async (row: RestockData) => { const handleRestockCheck = async (row: RestockData) => {
...@@ -204,14 +286,19 @@ const handleRestockCheck = async (row: RestockData) => { ...@@ -204,14 +286,19 @@ const handleRestockCheck = async (row: RestockData) => {
} }
} }
defineExpose({ refresh }) const handleReset = () => {
filterForm.warehouseId = undefined
filterForm.warehouseSku = ''
filterForm.productNo = ''
refresh()
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.waiting-restock { .waiting-restock {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 68vh;
overflow: hidden; overflow: hidden;
} }
......
...@@ -25,7 +25,7 @@ export function useOrderStatusTree(options: UseOrderStatusTreeOptions) { ...@@ -25,7 +25,7 @@ export function useOrderStatusTree(options: UseOrderStatusTreeOptions) {
'IN_PRODUCTION', 'IN_PRODUCTION',
'PENDING_PACKING', 'PENDING_PACKING',
] ]
const specialLayoutStatuses = ['BATCH_MANAGE', 'AWAITING_RESTOCK'] const specialLayoutStatuses = ['BATCH_MANAGE']
/** 左侧状态栏数量单位 */ /** 左侧状态栏数量单位 */
const STATUS_QUANTITY_UNIT: Record<string, string> = { const STATUS_QUANTITY_UNIT: Record<string, string> = {
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
:inline="true" :inline="true"
label-width="70px" label-width="70px"
> >
<ElFormItem v-if="status === 'ALL'" label="订单状态"> <ElFormItem v-if="showOrderStatusSelect" label="订单状态">
<ElTreeSelect <ElTreeSelect
v-model="searchFormStatusSelect" v-model="searchFormStatusSelect"
:data="statusTreeChildren" :data="statusTreeChildren"
...@@ -74,7 +74,7 @@ ...@@ -74,7 +74,7 @@
children: 'children', children: 'children',
}" }"
node-key="status" node-key="status"
placeholder="请选择" placeholder="请选择订单状态"
collapse-tags collapse-tags
multiple multiple
clearable clearable
...@@ -136,20 +136,7 @@ ...@@ -136,20 +136,7 @@
/> />
</ElFormItem> </ElFormItem>
<ElFormItem <ElFormItem label="操作单号">
v-if="
cardLayoutStatuses.includes(status) ||
[
'ALL',
'PICKING',
'PENDING_DELIVERY',
'COMPLETED',
'SUSPEND',
'CANCELLED',
].includes(status)
"
label="操作单号"
>
<ElInput <ElInput
v-model.trim="searchForm.operationNo" v-model.trim="searchForm.operationNo"
placeholder="多个操作单号,分隔" placeholder="多个操作单号,分隔"
...@@ -763,6 +750,17 @@ ...@@ -763,6 +750,17 @@
>订单库存明细</ElButton >订单库存明细</ElButton
> >
</span> </span>
<!-- 等待补货 -->
<span v-if="['AWAITING_RESTOCK'].includes(status)" class="item">
<ElButton type="primary" @click="handleDeliveryComplete">
补货校验
</ElButton>
</span>
<span v-if="['AWAITING_RESTOCK'].includes(status)" class="item">
<ElButton type="success" @click="handleWaitingRestockStatistics">
等待补货统计
</ElButton>
</span>
</div> </div>
<div v-if="status === 'SUSPEND'" class="status-subtabs"> <div v-if="status === 'SUSPEND'" class="status-subtabs">
<div <div
...@@ -812,10 +810,7 @@ ...@@ -812,10 +810,7 @@
<BatchManageTable v-if="status === 'BATCH_MANAGE'" ref="batchManageRef" /> <BatchManageTable v-if="status === 'BATCH_MANAGE'" ref="batchManageRef" />
<!-- 等待补货 --> <!-- 等待补货 -->
<WaitingRestockTable <WaitingRestockDialog v-model:visible="waitingRestockVisible" />
v-if="status === 'AWAITING_RESTOCK'"
ref="waitingRestockRef"
/>
<!-- 到派单、配货中子状态 --> <!-- 到派单、配货中子状态 -->
<div v-if="isCardLayout" :key="status" class="card-content"> <div v-if="isCardLayout" :key="status" class="card-content">
...@@ -1343,7 +1338,7 @@ import PickCompleteDialog from './component/PickCompleteDialog.vue' ...@@ -1343,7 +1338,7 @@ import PickCompleteDialog from './component/PickCompleteDialog.vue'
import PickFailDialog from './component/PickFailDialog.vue' import PickFailDialog from './component/PickFailDialog.vue'
import CardLayout from './component/CardLayout.vue' import CardLayout from './component/CardLayout.vue'
import BatchManageTable from './component/BatchManageTable.vue' import BatchManageTable from './component/BatchManageTable.vue'
import WaitingRestockTable from './component/WaitingRestockTable.vue' import WaitingRestockDialog from './component/WaitingRestockDialog.vue'
import ArrangeDialog from './component/ArrangeDialog.vue' import ArrangeDialog from './component/ArrangeDialog.vue'
import OperateDetailsDialog from './component/OperateDetailsDialog.vue' import OperateDetailsDialog from './component/OperateDetailsDialog.vue'
import CreateLogisticDialog from '@/views/order/components/CreateLogisticDialog.vue' import CreateLogisticDialog from '@/views/order/components/CreateLogisticDialog.vue'
...@@ -1381,8 +1376,8 @@ const toggleStatusSidebar = () => { ...@@ -1381,8 +1376,8 @@ const toggleStatusSidebar = () => {
statusSidebarCollapsed.value = !statusSidebarCollapsed.value statusSidebarCollapsed.value = !statusSidebarCollapsed.value
} }
const orderInventoryDetailVisible = ref(false) const orderInventoryDetailVisible = ref(false)
const waitingRestockVisible = ref(false)
const batchManageRef = ref<InstanceType<typeof BatchManageTable>>() const batchManageRef = ref<InstanceType<typeof BatchManageTable>>()
const waitingRestockRef = ref<InstanceType<typeof WaitingRestockTable>>()
const cardLayoutRef = ref<InstanceType<typeof CardLayout>>() const cardLayoutRef = ref<InstanceType<typeof CardLayout>>()
const exportVisible = ref(false) const exportVisible = ref(false)
const exportForm = ref({ const exportForm = ref({
...@@ -1462,12 +1457,15 @@ const { ...@@ -1462,12 +1457,15 @@ const {
currentPage: statusCurrentPageRef, currentPage: statusCurrentPageRef,
pageSize: statusPageSizeRef, pageSize: statusPageSizeRef,
}) })
const ORDER_STATUS_SELECT_TABS = ['ALL', 'AWAITING_RESTOCK']
const showOrderStatusSelect = computed(() =>
ORDER_STATUS_SELECT_TABS.includes(status.value),
)
// 查询状态树 // 查询状态树
const statusTreeChildren = computed((): StatusTreeNode[] => { const statusTreeChildren = computed((): StatusTreeNode[] => {
const tree = JSON.parse(JSON.stringify(statusTree.value?.[0]?.children)) as const children = statusTree.value?.[0]?.children
| StatusTreeNode[] if (!children?.length) return []
| undefined const tree = JSON.parse(JSON.stringify(children)) as StatusTreeNode[]
if (!tree) return []
tree.forEach((item) => { tree.forEach((item) => {
if (item.status === 'PICKING') item.children = [] if (item.status === 'PICKING') item.children = []
}) })
...@@ -1500,13 +1498,13 @@ const searchFormOperationStatusSelect = computed({ ...@@ -1500,13 +1498,13 @@ const searchFormOperationStatusSelect = computed({
}, },
}) })
getFactoryOrderSearchVisibilityContext = () => ({ getFactoryOrderSearchVisibilityContext = () => ({
status: searchForm.value.status ?? status.value, status: status.value,
isCardLayout: isCardLayout.value, isCardLayout: isCardLayout.value,
}) })
// 全部状态下列表/导出请求status参数 // 全部状态下列表/导出请求status参数
const listQueryStatus = computed(() => { const listQueryStatus = computed(() => {
if (status.value === 'ALL' && searchForm.value.status) { if (showOrderStatusSelect.value && searchForm.value.status) {
return searchForm.value.status return searchForm.value.status
} }
return status.value return status.value
...@@ -1514,7 +1512,7 @@ const listQueryStatus = computed(() => { ...@@ -1514,7 +1512,7 @@ const listQueryStatus = computed(() => {
const getListQueryPayload = () => { const getListQueryPayload = () => {
const payload = { ...getQueryPayload() } const payload = { ...getQueryPayload() }
if (status.value === 'ALL' && searchForm.value.status) { if (showOrderStatusSelect.value && searchForm.value.status) {
payload.status = searchForm.value.status payload.status = searchForm.value.status
} else { } else {
delete payload.status delete payload.status
...@@ -1630,7 +1628,6 @@ const refreshCurrentView = (options?: { isRefreshTree?: boolean }) => { ...@@ -1630,7 +1628,6 @@ const refreshCurrentView = (options?: { isRefreshTree?: boolean }) => {
if (options?.isRefreshTree) void loadStatusTreeCounts() if (options?.isRefreshTree) void loadStatusTreeCounts()
if (isSpecialLayout.value) { if (isSpecialLayout.value) {
if (status.value === 'BATCH_MANAGE') batchManageRef.value?.refresh() if (status.value === 'BATCH_MANAGE') batchManageRef.value?.refresh()
if (status.value === 'AWAITING_RESTOCK') waitingRestockRef.value?.refresh()
return return
} }
if (isCardLayout.value) { if (isCardLayout.value) {
...@@ -1742,6 +1739,9 @@ const handleRefreshReceiverAddress = async (row: FactoryOrderNewListData) => { ...@@ -1742,6 +1739,9 @@ const handleRefreshReceiverAddress = async (row: FactoryOrderNewListData) => {
} }
const handleStatusNodeClick = (node: { status: string }) => { const handleStatusNodeClick = (node: { status: string }) => {
if (!ORDER_STATUS_SELECT_TABS.includes(node.status)) {
searchForm.value.status = undefined
}
status.value = node.status status.value = node.status
if (node.status !== 'PENDING_RECEIVE') { if (node.status !== 'PENDING_RECEIVE') {
pendingAcceptSubTab.value = 'PENDING_RECEIVE' pendingAcceptSubTab.value = 'PENDING_RECEIVE'
...@@ -3575,6 +3575,9 @@ const handleInterceptionFail = async (row?: FactoryOrderNewListData) => { ...@@ -3575,6 +3575,9 @@ const handleInterceptionFail = async (row?: FactoryOrderNewListData) => {
const handleGetOrderInventoryDetail = async () => { const handleGetOrderInventoryDetail = async () => {
orderInventoryDetailVisible.value = true orderInventoryDetailVisible.value = true
} }
const handleWaitingRestockStatistics = () => {
waitingRestockVisible.value = true
}
const isEnableSorting = ref(false) const isEnableSorting = ref(false)
// 获取功能开关 // 获取功能开关
const getFunctionSwitch = async () => { const getFunctionSwitch = async () => {
......
...@@ -5,16 +5,6 @@ export const FACTORY_ORDER_LIST_SEARCH_FIELD_RULES: Record< ...@@ -5,16 +5,6 @@ export const FACTORY_ORDER_LIST_SEARCH_FIELD_RULES: Record<
(ctx: FactoryOrderSearchQueryVisibilityContext) => boolean (ctx: FactoryOrderSearchQueryVisibilityContext) => boolean
> = { > = {
batchArrangeNumber: (c) => c.isCardLayout, batchArrangeNumber: (c) => c.isCardLayout,
operationNo: (c) =>
c.isCardLayout ||
[
'ALL',
'PICKING',
'PENDING_DELIVERY',
'COMPLETED',
'SUSPEND',
'CANCELLED',
].includes(c.status),
receiverCountry: (c) => !c.isCardLayout, receiverCountry: (c) => !c.isCardLayout,
logisticsWayId: (c) => c.status === 'ALL', logisticsWayId: (c) => c.status === 'ALL',
customerNo: (c) => c.status === 'ALL', customerNo: (c) => c.status === 'ALL',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment