Commit 54e79062 by qinjianhui

feat: 单件打单功能开发

parent 554ca8ff
...@@ -13,6 +13,7 @@ import type { ...@@ -13,6 +13,7 @@ import type {
StatusTreeNode, StatusTreeNode,
} from '@/types/api/factoryOrderNew' } from '@/types/api/factoryOrderNew'
import { ResultInfoDataItem } from '@/types/api/order/common' import { ResultInfoDataItem } from '@/types/api/order/common'
import type { OrderData } from '@/types/api/podMakeOrder'
export function getPodOrderStateGroupListApi() { export function getPodOrderStateGroupListApi() {
return axios.get<never, BaseRespData<StatusTreeNode[]>>( return axios.get<never, BaseRespData<StatusTreeNode[]>>(
'factory/podOrder/findStateGroupList', 'factory/podOrder/findStateGroupList',
...@@ -420,3 +421,39 @@ export function orderWeighingPodOrderApi( ...@@ -420,3 +421,39 @@ export function orderWeighingPodOrderApi(
}, },
) )
} }
// 单件打单:根据 SKU/单号查询明细
export function getSingleQueryPodOrderApi(
code: string,
factoryNo: number,
warehouseId: number | string,
) {
return axios.get<never, BaseRespData<OrderData>>(
'factory/podOrder/getDetailsBySkuOrNo',
{
params: {
podOrderNo: code,
factoryNo,
warehouseId,
},
},
)
}
// 单件打单完成
export function submitPodPrintOrderCompleteApi(
data: { orderParamList: { id: number }[] },
warehouseId: number | string,
boxIndex: number | null = 0,
) {
const params = new URLSearchParams()
params.set('warehouseId', String(warehouseId))
if (boxIndex !== undefined && boxIndex !== null) {
params.set('box', String(boxIndex))
}
return axios.post<never, BaseRespData<never>>(
`factory/podOrderPacking/podPrintOrderComplete?${params.toString()}`,
data,
)
}
...@@ -861,6 +861,18 @@ ...@@ -861,6 +861,18 @@
@set-warehouse-id="handleWarehouseIdChange" @set-warehouse-id="handleWarehouseIdChange"
@refresh="() => refreshCurrentView({ isRefreshTree: true })" @refresh="() => refreshCurrentView({ isRefreshTree: true })"
/> />
<PodDistributionOrder
v-model="podDistributionOrderVisible"
:print-order="printOrder"
:warehouse-list="warehouseList"
:query-api="getSingleQueryPodOrderApi"
:submit-complete-api="submitPodPrintOrderComplete"
:print-label-api="getPrintLogisticLabelFactory"
:map-order-param-list-to-submit-items="mapOrderParamListToSubmitItems"
warehouse-session-key="locaclFactorySingel"
@set-printer="handlePrinterChange"
@refresh="() => refreshCurrentView({ isRefreshTree: true })"
/>
<ResultInfo <ResultInfo
ref="resultRefs" ref="resultRefs"
:list="resultInfo" :list="resultInfo"
...@@ -907,6 +919,8 @@ import { ...@@ -907,6 +919,8 @@ import {
getByOperationNoLogApi, getByOperationNoLogApi,
listByNoPodOrderApi, listByNoPodOrderApi,
orderWeighingPodOrderApi, orderWeighingPodOrderApi,
getSingleQueryPodOrderApi,
submitPodPrintOrderCompleteApi,
} from '@/api/factoryOrderNew' } from '@/api/factoryOrderNew'
import { filePath } from '@/api/axios' import { filePath } from '@/api/axios'
import { OrderData } from '@/types/api/podMakeOrder' import { OrderData } from '@/types/api/podMakeOrder'
...@@ -929,6 +943,7 @@ import UpdateCustomDeclarationInfoDialog from '@/views/order/components/UpdateCu ...@@ -929,6 +943,7 @@ import UpdateCustomDeclarationInfoDialog from '@/views/order/components/UpdateCu
import WeightDialog from '@/views/order/components/WeightDialog.vue' import WeightDialog from '@/views/order/components/WeightDialog.vue'
import FastProduction from '@/views/order/components/FastProduction.vue' import FastProduction from '@/views/order/components/FastProduction.vue'
import PodMakeOrder from '@/views/order/podUs/PodMakeOrder.vue' import PodMakeOrder from '@/views/order/podUs/PodMakeOrder.vue'
import PodDistributionOrder from '@/views/order/podCN/PodDistributionOrder.vue'
import { ResultInfoDataItem } from '@/types/api/order/common' import { ResultInfoDataItem } from '@/types/api/order/common'
import { useOrderDictionaries } from './hooks/useOrderDictionaries' import { useOrderDictionaries } from './hooks/useOrderDictionaries'
import { useOrderSearchForm } from './hooks/useOrderSearchForm' import { useOrderSearchForm } from './hooks/useOrderSearchForm'
...@@ -1501,6 +1516,7 @@ const handleSingleConfirmOrder = (row: FactoryOrderNewListData) => { ...@@ -1501,6 +1516,7 @@ const handleSingleConfirmOrder = (row: FactoryOrderNewListData) => {
confirmOrderDialogRef.value?.open([row.id]) confirmOrderDialogRef.value?.open([row.id])
} }
const podOrderVisible = ref(false) const podOrderVisible = ref(false)
const podDistributionOrderVisible = ref(false)
const sheetPrinter = ref('') const sheetPrinter = ref('')
const handlePrinterChange = (value: string) => { const handlePrinterChange = (value: string) => {
sheetPrinter.value = value sheetPrinter.value = value
...@@ -1509,6 +1525,25 @@ const handlePrinterChange = (value: string) => { ...@@ -1509,6 +1525,25 @@ const handlePrinterChange = (value: string) => {
const handleWarehouseIdChange = (value: string) => { const handleWarehouseIdChange = (value: string) => {
localStorage.setItem('localNewWarehouseId', JSON.stringify(value)) localStorage.setItem('localNewWarehouseId', JSON.stringify(value))
} }
// 复用 podCN 的单件打单组件:为 factoryOrderNew 注入差异部分
const mapOrderParamListToSubmitItems = (
orderParamList: { id: number; dataVersion?: number }[],
) => orderParamList.map((item) => ({ id: item.id }))
const submitPodPrintOrderComplete = (
data: { id: number; version?: number }[],
warehouseId: number | string,
) =>
submitPodPrintOrderCompleteApi(
{
orderParamList: data.map((item) => ({ id: item.id })),
},
warehouseId,
)
const getPrintLogisticLabelFactory = (id?: number) =>
getfaceSimplexFileApi([id ?? 0])
const { getCLodop } = useLodop() const { getCLodop } = useLodop()
const handleSeedingWall = () => { const handleSeedingWall = () => {
const lodop = getCLodop(null, null) const lodop = getCLodop(null, null)
...@@ -1714,8 +1749,7 @@ const handleQuickProduction = () => { ...@@ -1714,8 +1749,7 @@ const handleQuickProduction = () => {
detailData.value = {} detailData.value = {}
} }
const handleSinglePrint = () => { const handleSinglePrint = () => {
if (!ensureSelection()) return podDistributionOrderVisible.value = true
ElMessage.info('单件打单功能待集成')
} }
const handleGetTrackingNumber = async () => { const handleGetTrackingNumber = async () => {
await executeBatchAction({ await executeBatchAction({
...@@ -1732,6 +1766,9 @@ const handleStatusPush = () => { ...@@ -1732,6 +1766,9 @@ const handleStatusPush = () => {
onMounted(() => { onMounted(() => {
loadStatusTreeCounts() loadStatusTreeCounts()
loadAllDictionaries() loadAllDictionaries()
// 仅用于消除 TS 插件的 unused-vars 警告:template refs 会绑定这两个变量
void treeRef.value
void tableRef.value
if (status.value === 'PENDING_RECEIVE') { if (status.value === 'PENDING_RECEIVE') {
getPendingReceiveCounts() getPendingReceiveCounts()
} }
......
...@@ -273,7 +273,7 @@ import { computed, nextTick, ref, watch } from 'vue' ...@@ -273,7 +273,7 @@ import { computed, nextTick, ref, watch } from 'vue'
import useLodop from '@/utils/hooks/useLodop' import useLodop from '@/utils/hooks/useLodop'
import TableView from '@/components/TableView.vue' import TableView from '@/components/TableView.vue'
import { OrderData, ProductList, IorderItem } from '@/types/api/podMakeOrder' import { OrderData, ProductList, IorderItem } from '@/types/api/podMakeOrder'
import { PackingData } from '@/types/api/podCnOrder' // import { PackingData } from '@/types/api/podCnOrder'
import useUserStore from '@/store/user' import useUserStore from '@/store/user'
import { import {
getSingleQueryApi, getSingleQueryApi,
...@@ -344,7 +344,7 @@ const podOrderDetailsColumns = computed(() => [ ...@@ -344,7 +344,7 @@ const podOrderDetailsColumns = computed(() => [
// ] // ]
// : []), // : []),
]) ])
const noObj = reactive<Record<string, any>>({}) const noObj = ref<Record<string, OrderData>>({})
const checked = ref<boolean>(false) const checked = ref<boolean>(false)
const autoPrint = ref<boolean>(false) const autoPrint = ref<boolean>(false)
const ttChecked = ref<boolean>(false) const ttChecked = ref<boolean>(false)
...@@ -363,6 +363,41 @@ const props = defineProps<{ ...@@ -363,6 +363,41 @@ const props = defineProps<{
printOrder: (data: OrderData, callback: (status: boolean) => void) => void printOrder: (data: OrderData, callback: (status: boolean) => void) => void
// printOrderOne?: () => void // 单个打印 // printOrderOne?: () => void // 单个打印
warehouseList: WarehouseListData[] warehouseList: WarehouseListData[]
/**
* 可复用注入:单件打单查询接口
* - 默认:CN 的 getSingleQueryApi
*/
queryApi?: (
code: string,
factoryNo: number,
warehouseId: number | string,
) => Promise<{ code: number; data: OrderData }>
/**
* 可复用注入:单件打单完成接口
* - 默认:CN 的 submitInspectionApi
* - 入参 data 与 CN 组件内部 orderParamList 映射保持一致({id, version?}数组)
*/
submitCompleteApi?: (
data: { id: number; version?: number }[],
warehouseId: number | string,
) => Promise<{ code: number; message?: string }>
/**
* 可复用注入:获取打印面单(返回 data.filePath 或 data.fileData,或直接返回字符串路径)
* - 默认:CN 的 getPrintLogisticLabelApi
*/
printLabelApi?: (id?: number) => Promise<{ code: number; data: unknown }>
/**
* 可复用注入:orderParamList 映射成提交给接口的数组
* - 默认:包含 version(dataVersion)
*/
mapOrderParamListToSubmitItems?: (
orderParamList: IorderItem[],
) => { id: number; version?: number }[]
/**
* 仓库选择的 sessionStorage key
* - 默认:locaclCnSingel
*/
warehouseSessionKey?: string
}>() }>()
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'update:modelValue', v: boolean): void (e: 'update:modelValue', v: boolean): void
...@@ -391,7 +426,8 @@ watch(visible, async (value: boolean) => { ...@@ -391,7 +426,8 @@ watch(visible, async (value: boolean) => {
testingData.value = {} testingData.value = {}
noObj.value = {} noObj.value = {}
checked.value = false checked.value = false
const localRaw = sessionStorage.getItem('locaclCnSingel') const sessionKey = props.warehouseSessionKey ?? 'locaclCnSingel'
const localRaw = sessionStorage.getItem(sessionKey)
const localId = localRaw ? JSON.parse(localRaw) : '' const localId = localRaw ? JSON.parse(localRaw) : ''
/* 先找一次,确认本地值是否存在于列表 */ /* 先找一次,确认本地值是否存在于列表 */
const hit = props.warehouseList.find((w) => w.id === localId) const hit = props.warehouseList.find((w) => w.id === localId)
...@@ -433,7 +469,8 @@ const initPrintDevice = () => { ...@@ -433,7 +469,8 @@ const initPrintDevice = () => {
deviceList.value = arr deviceList.value = arr
} }
const handleWarehouseChange = (value: string) => { const handleWarehouseChange = (value: string) => {
sessionStorage.setItem('locaclCnSingel', JSON.stringify(value)) const sessionKey = props.warehouseSessionKey ?? 'locaclCnSingel'
sessionStorage.setItem(sessionKey, JSON.stringify(value))
} }
function keyDown(e: KeyboardEvent) { function keyDown(e: KeyboardEvent) {
const e1 = e || (window.event as KeyboardEvent) const e1 = e || (window.event as KeyboardEvent)
...@@ -513,12 +550,16 @@ async function submitInspection(objs?: OrderData, callback?: () => void) { ...@@ -513,12 +550,16 @@ async function submitInspection(objs?: OrderData, callback?: () => void) {
if (!factoryNo) { if (!factoryNo) {
return return
} }
const data = (result?.orderParamList ?? []).map((item: IorderItem) => ({ const orderParamList = result?.orderParamList ?? []
const data = props.mapOrderParamListToSubmitItems
? props.mapOrderParamListToSubmitItems(orderParamList as IorderItem[])
: (orderParamList as IorderItem[]).map((item) => ({
id: item.id, id: item.id,
version: item.dataVersion, version: item.dataVersion,
})) }))
try { try {
const res = await submitInspectionApi(data, warehouseId.value) const submitFn = props.submitCompleteApi ?? submitInspectionApi
const res = await submitFn(data, warehouseId.value)
if (res.code !== 200) return if (res.code !== 200) return
ElMessage.success(res.message) ElMessage.success(res.message)
coverImage.value = '' coverImage.value = ''
...@@ -533,19 +574,20 @@ async function submitInspection(objs?: OrderData, callback?: () => void) { ...@@ -533,19 +574,20 @@ async function submitInspection(objs?: OrderData, callback?: () => void) {
const userStore = useUserStore() const userStore = useUserStore()
const productTable = ref() const productTable = ref()
async function getPackingData(code: string) { async function getPackingData(code: string) {
const data: PackingData = {} // const data: PackingData = {}
const arr = code.split('_') const arr = code.split('_')
if (arr.length >= 4) code = arr[3] if (arr.length >= 4) code = arr[3]
if (code.startsWith('PSCD')) data.podProductionNo = code // if (code.startsWith('PSCD')) data.podProductionNo = code
else if (/^\d{16}$/.test(code)) data.jomallCustomNo = code // 16 位数字 // else if (/^\d{16}$/.test(code)) data.jomallCustomNo = code // 16 位数字
else if (code.startsWith('JMSC') || code.startsWith('GCSC')) // else if (code.startsWith('JMSC') || code.startsWith('GCSC'))
data.jomallPsdCustomNo = code // data.jomallPsdCustomNo = code
else if (code.startsWith('S-')) data.jomallCustomNo = code // else if (code.startsWith('S-')) data.jomallCustomNo = code
else if (code.includes('JMPSC') || code.startsWith('GCPS')) { if (code.includes('JMPSC') || code.startsWith('GCPS')) {
code = code.replace(/^([A-Z]+-)*([A-Z]+-[\d-]+)$/, (_, __, p) => p) code = code.replace(/^([A-Z]+-)*([A-Z]+-[\d-]+)$/, (_, __, p) => p)
data.podJomallNo = code }
} else data.sku = code // data.podJomallNo = code
// } else data.sku = code
const loading = ElLoading.service({ background: 'rgba(0, 0, 0, 0.3)' }) const loading = ElLoading.service({ background: 'rgba(0, 0, 0, 0.3)' })
currentCode.value = code currentCode.value = code
...@@ -556,7 +598,8 @@ async function getPackingData(code: string) { ...@@ -556,7 +598,8 @@ async function getPackingData(code: string) {
return return
} }
try { try {
const res = await getSingleQueryApi(code, factoryNo, warehouseId.value) const queryFn = props.queryApi ?? getSingleQueryApi
const res = await queryFn(code, factoryNo, warehouseId.value)
if (res.code === 200) { if (res.code === 200) {
testingData.value = res.data testingData.value = res.data
const { productList = [] } = res.data const { productList = [] } = res.data
...@@ -604,18 +647,27 @@ function printOrderOne(item: OrderData): Promise<void> { ...@@ -604,18 +647,27 @@ function printOrderOne(item: OrderData): Promise<void> {
/* 无文件 → 先拉取再打印 */ /* 无文件 → 先拉取再打印 */
const loading = ElLoading.service({ background: 'rgba(0,0,0,.3)' }) const loading = ElLoading.service({ background: 'rgba(0,0,0,.3)' })
getPrintLogisticLabelApi(item.id) const printFn = props.printLabelApi ?? getPrintLogisticLabelApi
printFn(item.id)
.then((res) => { .then((res) => {
loading.close() loading.close()
const data = res.data ?? {} const payload = res.data ?? {}
if (data.filePath) { if (typeof payload === 'string') {
item.filePath = data.filePath item.filePath = payload
} else if (data.fileData) { } else {
item.fileData = data.fileData const filePayload = payload as {
filePath?: string
fileData?: string
}
if (typeof filePayload.filePath === 'string') {
item.filePath = filePayload.filePath
} else if (typeof filePayload.fileData === 'string') {
item.fileData = filePayload.fileData
} else { } else {
ElMessage.error('获取打印面单失败') ElMessage.error('获取打印面单失败')
return return
} }
}
props.printOrder(item, (v) => { props.printOrder(item, (v) => {
// item.printStatus = v // item.printStatus = v
console.log('printOrder', v) console.log('printOrder', v)
......
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