Commit f63df5c5 by wusiyi

feat: podus添加dtf排版

parent 1775baac
...@@ -301,9 +301,45 @@ ...@@ -301,9 +301,45 @@
<ElButton type="primary" @click="search">查询</ElButton> <ElButton type="primary" @click="search">查询</ElButton>
</span> </span>
</ElFormItem> </ElFormItem>
<ElFormItem
v-if="
status === 'PICKING' ||
status === 'TO_BE_REPLENISHMENT' ||
status === 'IN_PRODUCTION'
"
>
<ElDropdown>
<el-button type="primary">
DTF排版<el-icon class="el-icon--right"><ArrowDown /></el-icon>
</el-button>
<template #dropdown>
<ElDropdownMenu>
<ElDropdownItem
:loading="tifDownloadLoading"
@click="downloadTif('tiff', 40)"
>TIF(40cm)</ElDropdownItem
>
<ElDropdownItem
:loading="tifDownloadLoading"
@click="downloadTif('tiff', 60)"
>TIF(60cm)</ElDropdownItem
>
<ElDropdownItem
:loading="pngDownloadLoading"
@click="downloadTif('png', 40)"
>PNG(40cm)</ElDropdownItem
>
<ElDropdownItem
:loading="pngDownloadLoading"
@click="downloadTif('png', 60)"
>PNG(60cm)</ElDropdownItem
>
</ElDropdownMenu></template
></ElDropdown
>
</ElFormItem>
<ElFormItem> <ElFormItem>
<span <!-- <span
v-if=" v-if="
status === 'PICKING' || status === 'PICKING' ||
status === 'TO_BE_REPLENISHMENT' || status === 'TO_BE_REPLENISHMENT' ||
...@@ -334,7 +370,7 @@ ...@@ -334,7 +370,7 @@
> >
PNG排版 PNG排版
</ElButton> </ElButton>
</span> </span> -->
<span v-if="status === 'TO_BE_CONFIRMED'" class="item"> <span v-if="status === 'TO_BE_CONFIRMED'" class="item">
<ElButton type="success" @click="confirmProduct"> <ElButton type="success" @click="confirmProduct">
确认生产 确认生产
...@@ -504,7 +540,7 @@ ...@@ -504,7 +540,7 @@
<ElButton type="success" @click="toBePicking"> 转至生产 </ElButton> <ElButton type="success" @click="toBePicking"> 转至生产 </ElButton>
</span> </span>
<span v-if="status === 'TO_BE_ARRANGE'" class="item"> <span v-if="status === 'TO_BE_ARRANGE'" class="item">
<ElButton type="warning" @click="arrangeFinish">排单完成</ElButton> <ElButton type="warning" @click="showArrange(2)">排单完成</ElButton>
</span> </span>
<span <span
v-if="status !== 'BATCH_DOWNLOAD' && status !== 'WAIT_SHIPMENT'" v-if="status !== 'BATCH_DOWNLOAD' && status !== 'WAIT_SHIPMENT'"
...@@ -1070,6 +1106,15 @@ ...@@ -1070,6 +1106,15 @@
> >
{{ item.weight }}g {{ item.weight }}g
</span> </span>
<el-button
v-if="status === 'WAIT_SHIPMENT'"
link
size="small"
type="warning"
style="height: 23px; margin: 0"
@click="showArrange(3, item)"
>排版
</el-button>
</div> </div>
</div> </div>
</div> </div>
...@@ -1350,6 +1395,16 @@ ...@@ -1350,6 +1395,16 @@
{{ row.finishTime?.replace('T', ' ') }} {{ row.finishTime?.replace('T', ' ') }}
</div> </div>
</template> </template>
<template #automaticComposing="{ row }">
<div style="white-space: pre-line">
{{ row.automaticComposing ? '是' : '否' }}
</div>
</template>
<template #composingParam="{ row }">
<div style="white-space: pre-line">
{{ row.composingParam?.split(';').join('\n') }}
</div>
</template>
<template #failTime="{ row }"> <template #failTime="{ row }">
<div style="white-space: pre-line"> <div style="white-space: pre-line">
{{ row.failTime?.replace('T', ' ') }} {{ row.failTime?.replace('T', ' ') }}
...@@ -1365,15 +1420,15 @@ ...@@ -1365,15 +1420,15 @@
> >
<span class="operate-item"> <span class="operate-item">
<ElButton <ElButton
:disabled="!row.url" :disabled="!row.url && !row.tiffUrl"
link link
type="primary" type="primary"
@click="handleDownload(row, 'png')" @click="handleDownload(row)"
> >
PNG下载 下载
</ElButton> </ElButton>
</span> </span>
<span class="operate-item"> <!-- <span class="operate-item">
<ElButton <ElButton
:disabled="!row.tiffUrl" :disabled="!row.tiffUrl"
link link
...@@ -1382,13 +1437,32 @@ ...@@ -1382,13 +1437,32 @@
> >
TIF下载 TIF下载
</ElButton> </ElButton>
</span> -->
<span class="operate-item">
<ElButton
link
type="primary"
@click="printPickingOrderItem(row, 1)"
>
打印拣货单
</ElButton>
</span> </span>
<span class="operate-item"> <span class="operate-item">
<ElButton <ElButton
link link
type="primary"
@click="printPickingOrderItem(row, 2)"
>
打印生产单
</ElButton>
</span>
<span class="operate-item">
<ElButton
link
type="warning" type="warning"
:loading="reComposingLoadingMap[row.id]" :loading="reComposingLoadingMap[row.id]"
@click="handleReComposingDesign(row)" @click="showArrange(1, row)"
> >
重新排版 重新排版
</ElButton> </ElButton>
...@@ -2110,6 +2184,56 @@ ...@@ -2110,6 +2184,56 @@
</span> </span>
</template> </template>
</ElDialog> </ElDialog>
<ElDialog
v-model="typesettingVisible"
title="选择排版类型和宽度"
width="500px"
:close-on-click-modal="false"
>
<el-form :model="typesettingForm">
<el-form-item
v-if="typesettingType == 2"
label="自动排版 (烫画工艺推荐自动排版)"
prop="bool"
>
<el-switch
v-model="isAuto"
class="ml-2"
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
inline-prompt
active-text="是"
inactive-text="否"
@change="changeSwitch"
/>
</el-form-item>
<div v-if="isAuto">
<el-form-item label="排版类型:" prop="type">
<el-radio-group v-model="typesettingForm.type">
<el-radio label="tiff">tiff排版</el-radio>
<el-radio label="png">png排版</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="排版宽度:" prop="type">
<el-radio-group v-model="typesettingForm.templateWidth">
<el-radio :value="40">40cm</el-radio>
<el-radio :value="60">60cm</el-radio>
</el-radio-group>
</el-form-item>
</div>
</el-form>
<template #footer>
<el-button
@click="
() => {
isAuto = true
typesettingVisible = false
}
"
>取消</el-button
>
<el-button type="primary" @click="submitTypesetting">确认</el-button>
</template>
</ElDialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { getUserMarkList } from '@/api/common' import { getUserMarkList } from '@/api/common'
...@@ -2153,7 +2277,6 @@ import { ...@@ -2153,7 +2277,6 @@ import {
batchDownloadApi, batchDownloadApi,
batchDownloadDownloadApi, batchDownloadDownloadApi,
batchDownloadDeleteApi, batchDownloadDeleteApi,
batchDownloadCnRecomposingApi,
updateToWaitShipmentApi, updateToWaitShipmentApi,
exportPodCnInfo, exportPodCnInfo,
createLogisticsOrdersApi, createLogisticsOrdersApi,
...@@ -2169,6 +2292,9 @@ import { ...@@ -2169,6 +2292,9 @@ import {
completeDeliveryApi, completeDeliveryApi,
updateSelfLogistics, updateSelfLogistics,
uploadExpressSheet, uploadExpressSheet,
printPickPdfByBatchNumberApi,
printProductionPdfByBatchNumberApi,
batchDownloadRecomposingApi,
} from '@/api/podCnOrder' } from '@/api/podCnOrder'
import { BaseRespData } from '@/types/api' import { BaseRespData } from '@/types/api'
...@@ -2230,6 +2356,8 @@ declare global { ...@@ -2230,6 +2356,8 @@ declare global {
} }
} }
const tabsNav = ref<Tab[]>() const tabsNav = ref<Tab[]>()
const isAuto = ref(true)
const calculatedPrice = (item: ProductList) => { const calculatedPrice = (item: ProductList) => {
const templatePrice = new BigNumber(item.templatePrice || 0) const templatePrice = new BigNumber(item.templatePrice || 0)
const craftPrice = new BigNumber(item.craftPrice || 0) const craftPrice = new BigNumber(item.craftPrice || 0)
...@@ -2744,7 +2872,7 @@ const handleInterceptionCommand = (current: number, command: number) => { ...@@ -2744,7 +2872,7 @@ const handleInterceptionCommand = (current: number, command: number) => {
loadTabData() loadTabData()
} }
// 批量下载 下载 // 批量下载 下载
const handleDownload = async (row: PodCnOrderListData, type: string) => { const handleDownload = async (row: PodCnOrderListData) => {
try { try {
await showConfirm('确定下载吗?', { await showConfirm('确定下载吗?', {
confirmButtonText: '确认', confirmButtonText: '确认',
...@@ -2759,6 +2887,8 @@ const handleDownload = async (row: PodCnOrderListData, type: string) => { ...@@ -2759,6 +2887,8 @@ const handleDownload = async (row: PodCnOrderListData, type: string) => {
text: '操作中...', text: '操作中...',
background: 'rgba(0, 0, 0, 0.3)', background: 'rgba(0, 0, 0, 0.3)',
}) })
const type = row.url && row.tiffUrl ? 'tiff' : row.url ? 'png' : 'tiff'
try { try {
const url = const url =
type === 'png' type === 'png'
...@@ -2876,20 +3006,26 @@ const refreshProductInformation = async () => { ...@@ -2876,20 +3006,26 @@ const refreshProductInformation = async () => {
} }
} }
// 批量下载 重新排版 // 批量下载 重新排版
const handleReComposingDesign = async (row: PodCnOrderListData) => { const handleReComposingDesign = async () => {
try { const row = { ...(typesettingRow.value as PodCnOrderListData) }
await showConfirm('确定重新排版吗?', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
})
} catch {
return
}
reComposingLoadingMap[row.id] = true reComposingLoadingMap[row.id] = true
typesettingVisible.value = false
const params: {
id: number
templateWidth?: number
type?: string
} = {
id: row.id,
}
const { templateWidth, type } = typesettingForm.value
if (templateWidth && type) {
params.templateWidth = templateWidth
params.type = type
}
try { try {
const res = await batchDownloadCnRecomposingApi({ id: row.id }) const res = await batchDownloadRecomposingApi(params)
if (res.code !== 200) return if (res.code !== 200) return
ElMessage.success(res.message) ElMessage.success(res.message)
search() search()
...@@ -2898,6 +3034,8 @@ const handleReComposingDesign = async (row: PodCnOrderListData) => { ...@@ -2898,6 +3034,8 @@ const handleReComposingDesign = async (row: PodCnOrderListData) => {
console.error(e) console.error(e)
} finally { } finally {
reComposingLoadingMap[row.id] = false reComposingLoadingMap[row.id] = false
typesettingRow.value = undefined
} }
} }
const tableColumns = computed(() => { const tableColumns = computed(() => {
...@@ -2906,66 +3044,73 @@ const tableColumns = computed(() => { ...@@ -2906,66 +3044,73 @@ const tableColumns = computed(() => {
{ {
label: '批次号', label: '批次号',
prop: 'batchArrangeNum', prop: 'batchArrangeNum',
width: 150, width: 120,
align: 'center', align: 'center',
}, },
{ {
label: '下载状态', label: '下载状态',
slot: 'downloadStatus', slot: 'downloadStatus',
width: 100, width: 90,
prop: 'downloadStatus', prop: 'downloadStatus',
align: 'center', align: 'center',
}, },
{ {
label: '订单数量', label: '订单数量',
prop: 'productNum', prop: 'productNum',
width: 100, width: 85,
align: 'center', align: 'center',
}, },
{ {
label: '素材数量', label: '素材数量',
width: 120, width: 85,
prop: 'materialNum', prop: 'materialNum',
align: 'center', align: 'center',
}, },
{ {
label: '创建人', label: '创建人',
width: 100, width: 85,
prop: 'employeeAccount', prop: 'employeeAccount',
align: 'center', align: 'center',
}, },
{ {
label: '失败原因', label: '失败原因',
minWidth: 300, minWidth: 250,
prop: 'failReason', prop: 'failReason',
slot: 'failReason', slot: 'failReason',
align: 'left', align: 'left',
}, },
{ {
label: '创建时间', label: '创建时间',
width: 200, width: 180,
prop: 'createTime', prop: 'createTime',
slot: 'createTime', slot: 'createTime',
align: 'center', align: 'center',
}, },
{ {
label: '完成时间', label: '完成时间',
width: 200, width: 180,
prop: 'finishTime', prop: 'finishTime',
slot: 'finishTime', slot: 'finishTime',
align: 'center', align: 'center',
}, },
// { {
// label: '失败时间', label: '自动下载',
// width: 250, width: 85,
// prop: 'failTime', prop: 'automaticComposing',
// slot: 'failTime', slot: 'automaticComposing',
// align: 'center', align: 'center',
// }, },
{
label: '排版参数',
width: 140,
prop: 'composingParam',
slot: 'composingParam',
align: 'center',
},
{ {
label: '操作', label: '操作',
slot: 'operate', slot: 'operate',
width: 300, width: 350,
align: 'center', align: 'center',
fixed: 'right', fixed: 'right',
prop: 'operate', prop: 'operate',
...@@ -3368,7 +3513,7 @@ const productionClientVisible = ref(false) ...@@ -3368,7 +3513,7 @@ const productionClientVisible = ref(false)
// productionClientVisible.value = true // productionClientVisible.value = true
// } // }
const downloadTif = async (type: string) => { const downloadTif = async (type: string, templateWidth: number) => {
if (!cardSelection.value.length) { if (!cardSelection.value.length) {
return ElMessage.warning('请选择数据') return ElMessage.warning('请选择数据')
} }
...@@ -3377,10 +3522,16 @@ const downloadTif = async (type: string) => { ...@@ -3377,10 +3522,16 @@ const downloadTif = async (type: string) => {
} else { } else {
pngDownloadLoading.value = true pngDownloadLoading.value = true
} }
const loading = ElLoading.service({
fullscreen: true,
text: '操作中...',
background: 'rgba(0, 0, 0, 0.3)',
})
try { try {
const res = await composingDesignImages( const res = await composingDesignImages(
cardSelection.value.map((el) => el.id), cardSelection.value.map((el) => el.id),
type, type,
templateWidth,
) )
const url = const url =
type === 'tiff' type === 'tiff'
...@@ -3421,6 +3572,97 @@ const downloadTif = async (type: string) => { ...@@ -3421,6 +3572,97 @@ const downloadTif = async (type: string) => {
} else { } else {
pngDownloadLoading.value = false pngDownloadLoading.value = false
} }
} finally {
loading.close()
}
}
const downloadTifItem = async () => {
const row = { ...(typesettingRow.value as PodCnOrderListData) }
const loading = ElLoading.service({
fullscreen: true,
text: '操作中...',
background: 'rgba(0, 0, 0, 0.3)',
})
try {
const { templateWidth, type } = typesettingForm.value
typesettingVisible.value = false
// // 处理下载逻辑
// if ((type as string[]).length > 1) {
// // 并行处理多个类型
// await Promise.allSettled(
// (type as string[]).map((el) =>
// downloadSingleType(row.id, el, templateWidth),
// ),
// )
// } else {
// 处理单个类型
await downloadSingleType(row.id, type as string, templateWidth)
// }
} catch (error) {
console.error('下载过程中出错:', error)
} finally {
typesettingRow.value = undefined
loading.close()
}
}
// 提取下载单个类型的逻辑为独立函数
const downloadSingleType = async (
id: number,
type: string,
templateWidth?: number,
) => {
try {
const res = await composingDesignImages([id], type, templateWidth)
const isTiff = type === 'tiff'
const url = isTiff
? `https://ps.jomalls.com/tiff/${res.message}`
: `${filePath}${res.message}`
if (isTiff) {
// 对于tiff类型,直接在新窗口打开
window.open(url, '_blank')
} else {
// 对于其他类型,使用下载方式
await downloadFile(url, res.message as string)
}
} catch (error) {
console.error(`下载类型 ${type} 时出错:`, error)
throw error // 重新抛出错误以便外部捕获
}
}
// 提取文件下载逻辑为独立函数
const downloadFile = async (url: string, message: string) => {
try {
const response = await fetch(url)
const blob = await response.blob()
const filename = message.split('/').pop() || 'download'
// 创建下载链接
const a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = filename
a.target = '_blank'
// 模拟点击下载
document.body.appendChild(a)
a.click()
// 清理
setTimeout(() => {
document.body.removeChild(a)
URL.revokeObjectURL(a.href)
}, 100)
} catch (error) {
console.error('下载文件时出错:', error)
throw error // 重新抛出错误
} finally {
pngDownloadLoading.value = false
} }
} }
...@@ -3469,6 +3711,38 @@ const printProductionOrder = async () => { ...@@ -3469,6 +3711,38 @@ const printProductionOrder = async () => {
loading.close() loading.close()
} }
} }
// 打印拣货单
const printPickingOrderItem = async (
row: { batchArrangeNum: string },
type: number,
) => {
const loading = ElLoading.service({
fullscreen: true,
text: '操作中...',
background: 'rgba(0, 0, 0, 0.3)',
})
try {
let res
if (type === 1) {
res = await printPickPdfByBatchNumberApi({
batchArrangeNumber: row.batchArrangeNum,
})
} else if (type === 2) {
res = await printProductionPdfByBatchNumberApi({
batchArrangeNumber: row.batchArrangeNum,
})
}
if (res?.code !== 200) return
ElMessage.success('操作成功')
window.open(filePath + res?.message)
} catch (e) {
console.error(e)
} finally {
loading.close()
}
}
const printPickingOrder = async () => { const printPickingOrder = async () => {
if (cardSelection.value.length === 0) { if (cardSelection.value.length === 0) {
return ElMessage.warning('请选择数据') return ElMessage.warning('请选择数据')
...@@ -3699,31 +3973,28 @@ const downloadMaterial = async () => { ...@@ -3699,31 +3973,28 @@ const downloadMaterial = async () => {
// 排单完成 // 排单完成
const arrangeFinish = async () => { const arrangeFinish = async () => {
const selectedIds = cardSelection.value.map((item) => item.id)
if (selectedIds.length === 0) {
return ElMessage({
message: '请选择订单',
type: 'warning',
offset: window.innerHeight / 2,
})
}
try {
await ElMessageBox.confirm('确定排单完成吗?', '提示', {
cancelButtonText: '取消',
confirmButtonText: '确认',
type: 'warning',
})
} catch {
return
}
const loading = ElLoading.service({ const loading = ElLoading.service({
fullscreen: true, fullscreen: true,
text: '操作中...', text: '操作中...',
background: 'rgba(0, 0, 0, 0.3)', background: 'rgba(0, 0, 0, 0.3)',
}) })
const selectedIds = cardSelection.value.map((item) => item.id)
const params: {
productIdList: number[]
templateWidth?: number
type?: string
} = {
productIdList: selectedIds,
}
const { templateWidth, type } = typesettingForm.value
if (templateWidth && type) {
params.templateWidth = templateWidth
params.type = type
}
typesettingVisible.value = false
try { try {
const res = await arrangeFinishApi(selectedIds) const res = await arrangeFinishApi(params)
if (res.code !== 200) return if (res.code !== 200) return
ElMessage.success('操作成功') ElMessage.success('操作成功')
search() search()
...@@ -3734,6 +4005,110 @@ const arrangeFinish = async () => { ...@@ -3734,6 +4005,110 @@ const arrangeFinish = async () => {
loading.close() loading.close()
} }
} }
// 重新排版
const typesettingForm = ref<{
typeArr?: string[]
type?: string
templateWidth?: number
}>({})
const typesettingVisible = ref(false)
const typesettingType = ref<number>()
const typesettingRow = ref<PodCnOrderListData>()
const showArrange = async (type: number, data?: PodCnOrderListData) => {
typesettingType.value = type
typesettingForm.value = {}
if (type === 1 || type === 3) {
typesettingRow.value = data
} else if (type === 2) {
const selectedIds = cardSelection.value.map((item) => item.id)
if (selectedIds.length === 0) {
return ElMessage({
message: '请选择订单',
type: 'warning',
offset: window.innerHeight / 2,
})
}
const bool = hasDifferentCraftCodeWithSet(cardSelection.value)
if (bool) {
try {
await ElMessageBox.confirm(
'选中排单的生产单存在多个工艺, 是否继续排单?',
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
},
)
typesettingVisible.value = true
} catch (error) {
return (typesettingVisible.value = false)
}
}
}
typesettingVisible.value = true
}
function hasDifferentCraftCodeWithSet(items: ProductList[]) {
if (items.length <= 1) return false
const seen = new Set()
for (const item of items) {
if (seen.has(item.craftCode)) {
if (seen.size > 1) return true
} else {
seen.add(item.craftCode)
if (seen.size > 1) return true
}
}
return false
}
const submitTypesetting = () => {
const { templateWidth, type } = typesettingForm.value
// 如果是自动排版且没有填必选项
if (isAuto.value && (!templateWidth || !type)) {
return ElMessage.warning('排版类型和排版宽度为必选项')
}
// 针对排版宽度和类型分别判断
if (!templateWidth && type) {
return ElMessage.warning('请选择排版宽度')
}
if (templateWidth && !type) {
return ElMessage.warning('请选择排版类型')
}
// 针对类型 3 的特殊判断
if (typesettingType.value === 3 && (!templateWidth || !type)) {
return ElMessage.warning('排版类型和排版宽度为必选项')
}
// 设置为自动排版
isAuto.value = true
// 根据排版类型执行相应的操作
switch (typesettingType.value) {
case 1:
return handleReComposingDesign()
case 2:
return arrangeFinish()
default:
return downloadTifItem()
}
}
const changeSwitch = () => {
typesettingForm.value = {}
}
const logList = ref<LogListData[]>([]) const logList = ref<LogListData[]>([])
const logVisible = ref(false) const logVisible = ref(false)
const operationLog = async (id: number, e: MouseEvent | null) => { const operationLog = async (id: number, e: MouseEvent | null) => {
......
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