Commit ec6e09e1 by qinjianhui

Merge branch 'dev_tiktok_bill' into 'dev'

feat:TIKTOK配货打单#ID1009947

See merge request !244
parents b4edcbe2 a067cc23
......@@ -23,7 +23,6 @@ declare module 'vue' {
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDivider: typeof import('element-plus/es')['ElDivider']
ElDrawer: typeof import('element-plus/es')['ElDrawer']
ElDropdown: typeof import('element-plus/es')['ElDropdown']
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
......@@ -36,8 +35,6 @@ declare module 'vue' {
ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElLink: typeof import('element-plus/es')['ElLink']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
......@@ -46,7 +43,6 @@ declare module 'vue' {
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElRow: typeof import('element-plus/es')['ElRow']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
......@@ -55,10 +51,8 @@ declare module 'vue' {
ElTag: typeof import('element-plus/es')['ElTag']
ElTimeline: typeof import('element-plus/es')['ElTimeline']
ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTree: typeof import('element-plus/es')['ElTree']
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
ElUpload: typeof import('element-plus/es')['ElUpload']
Icon: typeof import('./src/components/Icon.vue')['default']
ImageView: typeof import('./src/components/ImageView.vue')['default']
......
......@@ -9,6 +9,7 @@ import {
LogisticsData,
ExportParams,
InterceptStateGroupData,
DataItem,
} from '@/types/api/podUsOrder'
import axios from './axios'
import { PodMakeOrderData } from '@/types/api/podMakeOrder'
......@@ -116,6 +117,11 @@ export function updatePRNDownloadStatus(id: number) {
`/factory/podBatchDownload/updatePRNDownloadStatus?id=${id}`,
)
}
export function tiktokPrintOrderApi(shopNumber: string | number) {
return axios.get<never, BaseRespData<DataItem[]>>(
`/factory/podJomallOrderUs/tiktok-print-order?shopNumber=${shopNumber}`,
)
}
export function confirmOrderApi(
data: number[],
productionClient: string,
......@@ -166,6 +172,17 @@ export function cancelOrderApi(ids: number[], value: string) {
},
)
}
export function pendingOrderTobeWeighedApi(
orderId:number,
) {
return axios.post<never, BaseRespData<never>>(
`factory/podJomallOrderUs/podPrintOrderComplete`,
{
orderId: orderId,
},
)
}
export function getOperationLogApi(id: number) {
return axios.get<never, BaseRespData<LogListData[]>>(
`factory/podJomallOrderUsLog/getPodJomallOrderUsLog?id=${id}`,
......
......@@ -11,8 +11,8 @@ export interface PodMakeOrderData {
export interface OrderData {
shipmentsNote?: string
filePath?: string
fileData?: string
filePath?: string | null
fileData?: string | null
logisticsWayName?: string | null
company?: string | null
orderStatus?: number
......@@ -29,7 +29,7 @@ export interface OrderData {
trackingNumber?: string
productList?: ProductList[]
purchaseNumber?: number
pickingNumber?: number
pickingNumber?: number | null
printResult?: string
remark?: string
version?: number
......
......@@ -241,3 +241,52 @@ export interface IAllList {
name: string
warehouseName?: string
}
export interface DataItem {
printOrder: PrintOrderItem
pickingVerify: PickingVerifyItem
}
// 打印订单信息
interface PrintOrderItem {
filePath: string
shopNumber: string
id: number
trackingNumber: string
platform: string
fileData: string
}
// 产品项
export interface ProductItem {
id: number
productName: string
variantSku: string
variantImage: string
baseSku: string
thirdSkuCode: string
purchaseNumber: number
podJomallUsNo: string
numberMap: null
count: number | null
imageAry: string
passNum: number
productMark: string
putPackingTime: null
subShopNumber: string
power: boolean
pickingNumber: number | null
}
// 拣货验证信息
export interface PickingVerifyItem {
id: number
shopNumber: string
factoryOrderNumber: string
podOrderUsStatus: string
trackingNumber: string
pickingNumber: null
purchaseNumber: number
filePath: null
fileData: null
version: number
productList: ProductItem[]
}
\ No newline at end of file
<template>
<ElDialog
v-model="visible"
title="TIKTOK配货打单"
class="temuCheck"
fullscreen
:close-on-click-modal="false"
:close-on-press-escape="false"
:before-close="handleClose"
style="top: 60px"
modal-class="pod-make-order-dialog"
@opened="handleOpened"
@close="onClose"
>
<div style="display: flex">
<el-form :inline="true" @submit.prevent>
<div style="display: flex">
<div>
<div style="marin-right: -10px">
<el-form-item label="">
<el-select
v-model="sheetPrinter"
placeholder="打印机"
clearable
style="width: 382px"
filterable
@change="handlePrinterChange"
>
<el-option
v-for="(item, index) in printDeviceList"
:key="index"
:label="item"
:value="item"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-input
ref="testingInputRef"
v-model="barcode"
style="width: 390px"
placeholder="请输入店铺单号"
clearable
@keyup.enter="barcodeInput"
></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="barcodeInput">
查询
</el-button>
</el-form-item>
</div>
<div>
<el-form-item label-width="90px" label="物流跟踪号:">
<span style="width: 340px; display: inline-block">
{{ testingData.trackingNumber }}
</span>
</el-form-item>
<el-form-item label-width="90px" label="店铺单号:">
<span style="width: 340px; display: inline-block">
{{ testingData.shopNumber }}
</span>
</el-form-item>
<br />
<el-form-item label-width="90px" label="商品总数量:">
<span style="width: 340px; display: inline-block">
{{ testingData.purchaseNumber }}
</span>
</el-form-item>
<el-form-item label-width="90px" label="配货数量:">
<span style="width: 340px; display: inline-block">
{{ testingData.pickingNumber }}
</span>
</el-form-item>
<br />
<el-form-item label-width="90px" label="物流类型:">
<span style="width: 340px; display: inline-block">
{{
testingData.shipmentType == 0 &&
testingData.replaceShipment == 0
? '自提'
: testingData.shipmentType !== undefined
? ['自有物流', '九猫统筹物流'][
testingData.shipmentType
] || ''
: ''
}}
</span>
</el-form-item>
<el-form-item label-width="90px" label="订单号:">
<span
:title="testingData.factoryOrderNumber"
style="color: red; display: inline-block"
>
{{ testingData.factoryOrderNumber }}
</span>
</el-form-item>
<br />
</div>
<div>
<TableView
ref="tableRef"
:paginated-data="testingData.productList || []"
:columns="podOrderDetailsColumns"
highlight-current-row
@row-click="handleRowClick"
>
<template #image="{ row }">
<img v-if="row.variantImage" :src="row.variantImage" alt="" />
</template>
<template #verifyResult="{ row }">
<el-icon
v-if="row.count === row.purchaseNumber"
style="color: #00cc00; font-size: 24px; font-weight: 900"
><Check
/></el-icon>
</template>
</TableView>
</div>
</div>
<div style="margin-left: 10px">
<div
style="
position: relative;
width: 520px;
border: 1px solid #ddd;
background: rgb(50 50 50);
border-radius: 5px;
padding: 10px 15px;
box-sizing: border-box;
font-size: 16px;
color: #fff;
overflow: hidden;
"
>
<span
v-if="
testingData.productList && testingData.productList.length > 1
"
style="font-size: 16px; color: #666"
class="multiple_pieces"
>
<span
style="
position: absolute;
z-index: 2;
color: #fff;
left: -20px;
"
>
</span>
</span>
<p
style="
display: flex;
height: 80px;
align-items: center;
margin-bottom: 10px;
"
>
<strong
style="
font-size: 60px;
color: red;
text-align: center;
width: 120px;
"
>
{{ boxIndex }}
</strong>
<span style="margin-right: 15px; font-size: 30px"> 号箱 </span>
<template
v-if="
testingData.pickingNumber &&
testingData.purchaseNumber &&
testingData.pickingNumber === testingData.purchaseNumber
"
>
<strong
style="
font-size: 60px;
color: #00ff00;
display: inline-block;
text-align: center;
width: 90px;
"
>
{{ testingData.purchaseNumber }}
</strong>
<span style="font-size: 30px">件已配齐</span>
</template>
<template v-else>
<span style="font-size: 30px">放入第</span>
<strong
style="
font-size: 60px;
color: red;
display: inline-block;
text-align: center;
width: 90px;
"
>
{{ testingData.pickingNumber }}
</strong>
<span style="font-size: 30px">件商品</span>
</template>
</p>
<p style="margin-bottom: 15px">
<span
v-if="
testingData.pickingNumber &&
testingData.purchaseNumber &&
testingData.pickingNumber === testingData.purchaseNumber
"
>
<span v-if="testingData.printResult">
面单{{ testingData.printResult }}
</span>
<span v-else>面单打印中。。。</span>
</span>
<span v-else>验货中。。。</span>
</p>
<p>
<el-button
v-if="
testingData.pickingNumber &&
testingData.purchaseNumber &&
testingData.pickingNumber === testingData.purchaseNumber
"
type="primary"
@click="print(testingData)"
>
手动打印
</el-button>
<el-button type="success" @click="orderCompleted">
打单完成
</el-button>
<el-button type="danger" @click="clearBox">
清空箱子
</el-button>
</p>
</div>
<div class="order-image">
<img
:src="getNewImageFn(coverImage)"
alt=""
style="cursor: pointer"
/>
</div>
</div>
</div>
</el-form>
<ul ref="boxListWrapRef" class="box_list">
<li
v-for="(item, index) in boxList"
:key="index"
:class="{
active: item.box && boxIndex == item.box,
isNull: !item.data,
}"
@click="getBoxContent(item)"
>
<span style="font-weight: bold" :title="index + 1 + '号箱'">
{{ index + 1 }}
</span>
<span v-if="item.data" class="number">
{{ item.data && item.data.pickingNumber }}/{{
item.data && item.data.purchaseNumber
}}
</span>
</li>
</ul>
</div>
</ElDialog>
</template>
<script setup lang="tsx">
import { ref, computed, watch, nextTick } from 'vue'
import { ElMessage, ElMessageBox, ElLoading, ElDialog } from 'element-plus'
import { Check } from '@element-plus/icons-vue'
import {
tiktokPrintOrderApi,
pendingOrderTobeWeighedApi,
} from '@/api/podUsOrder'
import useLodop from '@/utils/hooks/useLodop'
import TableView from '@/components/TableView.vue'
import {
DataItem,
ProductItem,
PickingVerifyItem,
} from '@/types/api/podUsOrder'
import type { OrderData } from '@/types/api/podMakeOrder'
interface PrintCallback {
(status: boolean): void
}
type TestingDataItem = Partial<
Omit<PickingVerifyItem, 'pickingNumber' | 'filePath' | 'fileData'>
> & {
pickingNumber?: number | null
filePath?: string | null
fileData?: string | null
printResult?: string
shipmentType?: number
replaceShipment?: number
[key: string]: unknown
}
type boxListItem = {
box?: number | null
data?: TestingDataItem
}
type PrintOrderFn = (data: OrderData, callback: PrintCallback) => void
const props = withDefaults(
defineProps<{
modelValue: boolean
printOrder?: PrintOrderFn
}>(),
{
printOrder: () => {},
},
)
const emit = defineEmits<{
'update:modelValue': [value: boolean]
'set-printer': [value: string]
refresh: []
}>()
const { getCLodop } = useLodop()
const barcode = ref<string>('')
const testingData = ref<TestingDataItem>({})
const boxNumber = ref<string>('')
const coverImage = ref<string>('')
const printResult = ref<string>('')
const sheetPrinter = ref<string>('')
const boxIndex = ref<number | null>(null)
const renderLock = ref<boolean>(false)
const boxList = ref<boxListItem[]>([])
const currentCode = ref<string>('')
const isLock = ref<boolean>(false)
const boxChange = ref<boolean>(false)
const printDeviceList = ref<string[]>([])
const testingInputRef = ref()
const productTableRef = ref()
const boxListWrapRef = ref<HTMLElement | null>(null)
const tableRef = ref()
// 初始化打印机设备
const initPrintDevice = () => {
const lodop = getCLodop(null, null)
if (!lodop) return
const arr: string[] = []
const length = lodop.GET_PRINTER_COUNT()
for (let i = 0; i < length; i++) {
const name = lodop.GET_PRINTER_NAME(i)
arr.push(name)
}
// console.log('arr', arr, lodop.GET_PRINTER_NAME(1))
sheetPrinter.value = lodop.GET_PRINTER_NAME(0)
printDeviceList.value = arr
}
const handlePrinterChange = (value: string) => {
emit('set-printer', value)
}
const getNewImageFn = (img: string) => {
try {
if (img.startsWith('http')) return img
if (img.startsWith('/')) return `https://img.jomalls.com/upload/erp${img}`
return `https://image.jomalls.com/${img}`
} catch (error) {
console.log(error)
}
}
const podOrderDetailsColumns = computed(() => [
{
label: '图片',
prop: 'variantImage',
width: 80,
slot: 'image',
align: 'center',
},
{
label: '店铺单号',
prop: 'subShopNumber',
width: 180,
align: 'center',
},
{
label: '库存SKU',
prop: 'thirdSkuCode',
width: 180,
align: 'center',
},
{
label: '变体SKU',
prop: 'variantSku',
width: 180,
align: 'center',
},
{
label: 'SKU名称',
prop: 'productName',
minWidth: 230,
align: 'center',
},
{
label: '购买数量',
prop: 'purchaseNumber',
width: 90,
align: 'center',
fixed: 'right',
},
{
label: '配货数量',
prop: 'count',
width: 90,
align: 'center',
fixed: 'right',
},
{
label: '验证结果',
slot: 'verifyResult',
width: 90,
align: 'center',
fixed: 'right',
},
])
const visible = computed({
get() {
return props.modelValue
},
set() {
emit('update:modelValue', false)
},
})
const playAudio = (key: string) => {
const audio = new Audio()
const audioPath = new URL(`../../../assets/audio/${key}.mp3`, import.meta.url)
.href
audio.src = audioPath
audio.play()
}
const inputActive = () => {
nextTick(() => {
testingInputRef.value && testingInputRef.value.focus()
})
}
const scrollTo = (index: number) => {
const listWrap = boxListWrapRef.value
if (!listWrap) return
nextTick(() => {
if (index > 10) {
const li = listWrap.children[index] as HTMLElement | undefined
if (!li) return
const height = li.offsetTop
if (height > 160) {
listWrap.scrollTop = height - 80
}
} else {
nextTick(() => {
listWrap.scrollTop = 0
})
}
})
}
const handleRowClick = (row: ProductItem) => {
coverImage.value = row.variantImage || ''
inputActive()
}
const handleOpened = () => {
// 弹窗打开后聚焦输入框
nextTick(() => {
testingInputRef.value && testingInputRef.value.focus()
})
}
const onClose = () => {
emit('refresh')
}
const handleClose = async () => {
if (boxNumber.value) {
try {
await ElMessageBox.confirm(
'你是否配完了' + boxNumber.value + '中的全部商品?',
'配货确认',
{
distinguishCancelAndClose: true,
closeOnClickModal: false,
confirmButtonText: '是的',
cancelButtonText: '没有',
},
)
} catch (e) {
console.error(e)
}
}
nextStep(() => {
boxIndex.value = null
emit('update:modelValue', false)
})
}
// 渲染当前箱子数据
const renderItem = () => {
if (boxList.value.length === 0 || !boxIndex.value) return
if (renderLock.value) return
renderLock.value = true
let item = boxList.value.find((b: boxListItem) => b.box === boxIndex.value)
if (!item) item = {} as boxListItem
let { data } = item
if (!data) {
currentCode.value = ''
testingData.value = {}
renderLock.value = false
data = {} as TestingDataItem
}
const productList = data?.productList || []
const pickingNumber = productList.reduce((prev: number, p: ProductItem) => {
if (p.count) return prev + p.count
return prev
}, 0)
data.pickingNumber = pickingNumber
coverImage.value = ''
if (currentCode.value) {
for (const iterator of productList) {
if (iterator.subShopNumber === currentCode.value) {
coverImage.value = iterator.variantImage
nextTick(() => {
productTableRef.value && productTableRef.value.setCurrentRow(iterator)
})
break
}
if (
iterator.podJomallUsNo &&
iterator.podJomallUsNo.indexOf(currentCode.value) !== -1
) {
coverImage.value = iterator.variantImage
nextTick(() => {
productTableRef.value && productTableRef.value.setCurrentRow(iterator)
})
break
}
}
currentCode.value = ''
testingData.value = data
if (pickingNumber === data.purchaseNumber) {
print(data)
}
} else {
coverImage.value = productList[0] ? productList[0].variantImage : ''
testingData.value = data
}
renderLock.value = false
}
const nextStep = (callback?: () => void) => {
if (
testingData.value?.productList?.every(
(item: ProductItem) => item.count === item.purchaseNumber,
) &&
(testingData.value?.printResult === '打印成功' ||
testingData.value?.printResult === '未能获取打印状态')
) {
submitInspection(() => {
callback && callback()
})
} else {
callback && callback()
}
}
const getBoxContent = ({ box, data }: boxListItem) => {
nextStep(() => {
if (!data) {
ElMessage.warning('暂无数据')
return
}
boxChange.value = true
boxIndex.value = box ?? null
})
inputActive()
}
const clearBox = () => {
const boxIdx = boxIndex.value
if (!boxIdx || boxIdx < 1) {
ElMessage.warning('请选择要清空的箱子')
return
}
ElMessageBox.confirm('确认清空当前的箱子?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
localStorage.removeItem('tt_order_box_' + boxIdx)
boxList.value.splice(boxIdx - 1, 1, {})
testingData.value = {}
boxIndex.value = null
isLock.value = false
inputActive()
coverImage.value = ''
})
.catch(() => {
isLock.value = false
inputActive()
})
}
const submitInspection = async (callback?: () => void) => {
const boxIdx = boxIndex.value
if (!boxIdx || boxIdx < 1) {
isLock.value = false
ElMessage.warning('请先选择要提交的箱子')
return
}
const loading = ElLoading.service({ background: 'rgba(0, 0, 0, 0.3)' })
try {
const res = await pendingOrderTobeWeighedApi(testingData.value.id!)
if (res.code === 200) {
ElMessage.success(res.message)
}
} catch (e) {
console.error(e)
} finally {
localStorage.removeItem('tt_order_box_' + boxIdx)
boxList.value.splice(boxIdx - 1, 1, {})
boxIndex.value = null
coverImage.value = ''
testingData.value = {}
isLock.value = false
loading.close()
callback && callback()
}
}
const setBox = (code: string, params: DataItem) => {
if (!params || !params.pickingVerify || !params.printOrder) {
ElMessage.warning(code + '没有匹配到订单。')
playAudio('picking_warning')
return
}
const { pickingVerify, printOrder } = params
const data = {
...pickingVerify,
filePath: printOrder.filePath,
fileData: printOrder.fileData,
} as unknown as TestingDataItem
for (const iterator of data.productList || []) {
if (iterator.subShopNumber === code) {
iterator.count = iterator.purchaseNumber
iterator.power = true
}
}
const index = boxList.value.findIndex((item: boxListItem) => !item.data)
let element: boxListItem
if (index === -1) {
element = { data, box: boxList.value.length + 1 }
boxList.value.push(element)
boxIndex.value = boxList.value.length
} else {
element = boxList.value[index]
element.data = data
element.box = index + 1
if (!boxIndex.value) boxIndex.value = index + 1
if (boxIndex.value === index + 1) {
renderItem()
} else {
boxIndex.value = index + 1
}
}
localStorage.setItem('tt_box_length', String(boxList.value.length))
localStorage.setItem('tt_order_box_' + element.box, JSON.stringify(element))
isLock.value = false
}
const putSkuIntoBox = (code: string, index: number): boolean => {
const item = boxList.value[index]
if (!item.data) return false
const { data } = item
let matched = false
let allMatchedCompleted = true
for (const iterator of data.productList || []) {
if (iterator.subShopNumber === code) {
matched = true
if (iterator.purchaseNumber === iterator.count) continue
allMatchedCompleted = false
iterator.count = iterator.purchaseNumber
iterator.power = true
}
}
if (matched) {
localStorage.setItem('tt_order_box_' + (index + 1), JSON.stringify(item))
if (boxIndex.value === index + 1) {
renderItem()
} else {
boxIndex.value = index + 1
}
isLock.value = false
if (allMatchedCompleted) {
ElMessage.warning('该订单已在' + (index + 1) + '号箱中,请勿重复扫描!')
playAudio('picking_check_success')
return true
}
playAudio('picking_check_success')
return true
}
return false
}
const getPackingData = async (code: string) => {
currentCode.value = code
const length = boxList.value.length
for (let index = 0; index < length; index++) {
if (putSkuIntoBox(code, index)) return
}
const loading = ElLoading.service({ background: 'rgba(0, 0, 0, 0.3)' })
try {
const res = await tiktokPrintOrderApi(code)
if (res.code === 200) {
if (res.data && res.data.length > 0) {
const validData = res.data.find(
(item: DataItem) => item && item.pickingVerify && item.printOrder,
)
if (validData) {
playAudio('picking_check_success')
setBox(code, validData)
} else {
playAudio('picking_search_error')
ElMessage.error(code + '没有匹配到订单。')
}
}
} else {
playAudio('picking_search_error')
isLock.value = false
}
} catch (e) {
playAudio('picking_search_error')
isLock.value = false
console.error(e)
} finally {
loading.close()
}
}
const barcodeInput = async () => {
const code = barcode.value
if (!code) {
ElMessage.warning('请录入店铺单号')
playAudio('picking_warning')
return
}
if (isLock.value) {
barcode.value = ''
return
}
barcode.value = ''
isLock.value = true
if (
testingData.value?.productList?.every(
(item: ProductItem) => item.count === item.purchaseNumber,
)
) {
if (testingData.value.printResult === '打印成功') {
submitInspection(() => {
getPackingData(code)
})
} else {
ElMessage.warning('未获取到打印结果')
playAudio('picking_warning')
isLock.value = false
}
} else {
getPackingData(code)
}
}
const orderCompleted = () => {
ElMessageBox.confirm('确定打单完成?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
})
.then(() => {
submitInspection(() => {
inputActive()
})
})
.catch(() => {
inputActive()
})
}
const print = (data: TestingDataItem) => {
const boxIdx = boxIndex.value
props.printOrder(data as unknown as OrderData, (status: boolean) => {
const item = boxList.value.find((b: boxListItem) => b.box === boxIdx)
if (item && item.data) {
item.data.printResult = status ? '打印成功' : '打印失败'
}
inputActive()
})
}
onMounted(() => {
window.addEventListener('keydown', keyDown)
})
onUnmounted(() => {
window.removeEventListener('keydown', keyDown)
})
const keyDown = (e: KeyboardEvent) => {
const e1 = e || window.event
if (![37, 38, 39, 40].includes(e1.keyCode)) return
e1.stopPropagation()
e1.preventDefault()
let idx = boxIndex.value
const length = boxList.value.length
if (e1.keyCode === 37) {
idx = (idx ?? 0) - 1
if (idx < 1) return
} else if (e1.keyCode === 38) {
idx = (idx ?? 0) - 10
if (idx < 1) return
} else if (e1.keyCode === 39) {
idx = (idx ?? 0) + 1
if (idx > length) return
} else if (e1.keyCode === 40) {
idx = (idx ?? 0) + 10
if (idx > length) return
}
boxIndex.value = idx
boxChange.value = true
}
watch(visible, async (v: boolean) => {
if (v) {
currentCode.value = ''
testingData.value = {}
barcode.value = ''
printResult.value = ''
coverImage.value = ''
initPrintDevice()
const locaclPrinter = localStorage.getItem('sheetPrinter')
if (locaclPrinter) sheetPrinter.value = JSON.parse(locaclPrinter)
emit('set-printer', sheetPrinter.value)
isLock.value = false
renderLock.value = false
const tt_box_length = localStorage.getItem('tt_box_length')
boxNumber.value = ''
if (tt_box_length) {
const boxLength = Number(tt_box_length)
const arr: boxListItem[] = []
let idx: number | undefined
for (let index = 0; index < boxLength; index++) {
const raw = localStorage.getItem('tt_order_box_' + (index + 1))
if (raw) {
const item = JSON.parse(raw) as boxListItem
const pickingNumber = (item.data?.productList || []).reduce(
(prev: number, p: ProductItem) => {
if (p.count) return prev + p.count
return prev
},
0,
)
;(item.data as unknown as { pickingNumber: number }).pickingNumber =
pickingNumber
arr.push(item)
if (!idx) idx = index + 1
} else {
arr.push({} as boxListItem)
}
}
boxList.value = arr.some((item) => item.data) ? arr : [{} as boxListItem]
const arr1 = boxList.value.filter((item: boxListItem) =>
(item.data?.productList || []).every(
(v: ProductItem) => v.count === v.purchaseNumber,
),
)
const boxIndexs = arr1.map((item: boxListItem) => item.box)
// 当前没有选中的箱子时,不弹提醒(用户刚开弹窗准备扫新单,不应被旧箱提醒打断)
if (boxIndexs.length > 0 && boxIndex.value) {
nextTick(() => {
ElMessageBox.alert(
`检测到${boxIndexs.join('、')}号箱验货完成,请及时处理`,
'提示',
{ type: 'warning' },
)
})
}
boxIndex.value = idx ?? null
} else {
boxList.value = [{} as boxListItem]
}
nextTick(() => {
testingInputRef.value && testingInputRef.value.focus()
})
}
})
// 监听 boxIndex
watch(boxIndex, (index: number | null) => {
if (!index) return
boxChange.value = false
renderItem()
scrollTo(index - 1)
})
</script>
<style scoped lang="scss">
.box_list {
margin-left: 10px;
height: calc(100vh - 130px);
overflow: auto;
padding: 5px;
position: relative;
}
.box_list li {
float: left;
border: 1px solid #ddd;
cursor: pointer;
width: 50px;
font-size: 18px;
line-height: 30px;
height: 46px;
text-align: center;
box-sizing: border-box;
border-radius: 5px;
position: relative;
}
.box_list li:not(.isNull) {
background: #819aff;
color: #fff;
}
.box_list li.active {
background: #ff9900;
color: #fff;
transform: scale(1.2);
}
.box_list li {
margin-right: 10px;
margin-bottom: 8px;
}
.box_list .number {
position: absolute;
bottom: 3px;
right: 0;
left: 0;
text-align: center;
font-size: 12px;
line-height: 14px;
color: #ddd;
}
.multiple_pieces {
position: absolute;
top: 0;
right: 0;
color: #fff;
}
.multiple_pieces::after {
position: absolute;
top: -31px;
right: -30px;
content: '';
border-width: 30px;
border-style: solid;
border-color: transparent transparent red transparent;
transform: rotate(45deg);
}
.el-form-item {
margin-bottom: 0px;
}
.order-image {
width: 520px;
flex: 1;
overflow: auto;
border: 1px solid #ddd;
background: #eee;
}
</style>
......@@ -982,7 +982,10 @@
</span>
</ElFormItem>
<ElFormItem
v-if="['WAIT_TRACK'].includes(status) && [1,2,5].includes(waitTrackStatus)"
v-if="
['WAIT_TRACK'].includes(status) &&
[1, 2, 5].includes(waitTrackStatus)
"
>
<span class="item">
<ElButton type="success" @click="reissueOrder">补发</ElButton>
......@@ -995,6 +998,13 @@
>
</span>
</ElFormItem>
<ElFormItem v-if="status === 'WAIT_SHIPMENT'">
<span class="item">
<ElButton type="success" @click="distributionBillBtn"
>TIKTOK配货打单</ElButton
>
</span>
</ElFormItem>
</ElForm>
</div>
<div class="header-filter-tab">
......@@ -2782,6 +2792,14 @@
@set-warehouse-id="handleWarehouseIdChange"
@refresh="onFastRefresh"
/>
<DistributionBillOrder
v-model="distributionBillVisible"
:print-order="printOrder"
:warehouse-list="warehouseList"
@set-printer="handlePrinterChange"
@set-warehouse-id="handleWarehouseIdChange"
@refresh="onFastRefresh"
/>
<InspPackagOrder
ref="InspPackagOrderRef"
@refresh="onFastRefresh"
......@@ -3282,6 +3300,7 @@ import { computed, onMounted, ref, nextTick, reactive, h } from 'vue'
import FastProduction from './FastProduction.vue'
import { filePath } from '@/api/axios'
import PodMakeOrder from './PodMakeOrder.vue'
import DistributionBillOrder from './DistributionBillOrder.vue'
import InspPackagOrder from './InspPackagOrder.vue'
import { OrderData } from '@/types/api/podMakeOrder'
import useLodop, { LODOPObject } from '@/utils/hooks/useLodop'
......@@ -3759,7 +3778,6 @@ const handleBatchDelete = async (type: string, id?: string) => {
loading.close()
}
}
const shipmentList = ref(['自有物流', '九猫统筹物流'])
// 批量下载 重新排版
......@@ -4041,7 +4059,6 @@ const rightClick = (e: MouseEvent) => {
y: e.clientY,
})
}
const handleSelectionChange = (val: PodUsOrderListData[]) => {
selection.value = val
// 当清空选择时,清除补货校验成功的状态
......@@ -5509,7 +5526,14 @@ const printPodOrder = async () => {
sheetPrinter.value = lodop.GET_PRINTER_NAME(0)
podOrderVisible.value = true
}
const distributionBillVisible = ref(false)
const distributionBillBtn = async () => {
const lodop = getCLodop(null, null)
if (!lodop) return
sheetPrinter.value = lodop.GET_PRINTER_NAME(0)
distributionBillVisible.value = true
}
const InspPackagOrderRef = ref()
// const inspPackagOrder = async () => {
......
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