Commit d840ce93 by wusiyi

Merge branch 'dev_pod_us_process' into release

parents 49f9fd79 d75893ba
......@@ -70,6 +70,15 @@ export interface ILogisticsCompany {
basicType: number // int(11)
}
export interface LogisticsWayData {
id: number
name: string
code: string
status: boolean
createTime: string
updateTime: string
}
interface ILogisticsParams {
logType: string
relaId: number | string
......@@ -148,6 +157,15 @@ export function getUniuniList() {
},
)
}
// 根据物流公司筛选物流方式
export function getLogisticsWayListByCompanyId(companyId: number) {
return axios.get<never, BaseRespData<LogisticsWayData[]>>(
'logisticsWay/getUsableWaysByCompanyId',
{
params: { companyId },
},
)
}
// 获取tictok物流承运商
export function getTiktokCarrier() {
return axios.get<never, BaseRespData<{ name: string; id: string,typeCode:string,label:string }[]>>(
......
......@@ -483,12 +483,13 @@ export function refreshProductInformationApi(data: {
}
// 设计图排版
export function composingDesignImages(
url: string,
data: number[],
type?: string,
templateWidth?: number,
) {
return axios.post<never, BaseRespData<never>>(
`factory/podJomallOrderCn/composingDesignImages?type=${type}&templateWidth=${templateWidth}`,
`${url}?type=${type}&templateWidth=${templateWidth}`,
data,
)
}
......@@ -638,10 +639,10 @@ export function updateToWaitShipmentApi(params: {
}
//创建物流订单
export function createLogisticsOrdersApi(orderIds: (string | number)[]) {
export function createLogisticsOrdersApi(orderIdList: (string | number)[], logisticsWayId: number | null) {
return axios.post<never, BaseRespData<never>>(
`factory/podJomallOrderCn/createLogisticsOrders`,
orderIds,
{ orderIdList, logisticsWayId },
)
}
......@@ -790,3 +791,11 @@ export function updateProductOutOfStockApi(params: {
params,
)
}
// 打印普胚生产单
export function printNormalProducePdf(orderIds: number[]) {
return axios.post<never, BaseRespData<string>>(
'factory/podJomallOrderProductCn/printNormalProducePdf',
orderIds,
)
}
......@@ -263,14 +263,14 @@ export function getPodBoxListApi(
}
export function submitInspectionApi(
data: { id: number; version?: number }[],
orderId: number | undefined,
boxIndex: number | null,
warehouseId: number | string,
) {
return axios.post<never, BaseRespData<never>>(
`factory/podJomallOrderUs/podPrintOrderComplete?box=${boxIndex}&warehouseId=${warehouseId}`,
{
orderParamList: data,
orderId,
},
)
}
......@@ -397,12 +397,13 @@ export function updateSelfLogistics(params: {
// 更改物流
export function composingDesignImages(
url: string,
data: number[],
type?: string,
templateWidth?: number,
) {
return axios.post<never, BaseRespData<never>>(
`factory/podJomallOrderUs/composingDesignImages?type=${type}&templateWidth=${templateWidth}`,
`${url}?type=${type}&templateWidth=${templateWidth}`,
data,
)
}
......
......@@ -142,7 +142,7 @@
style="width: 125px"
></ElInput>
</ElFormItem>
<ElFormItem label="排序">
<ElFormItem label="排序方式">
<el-select
v-model="searchForm.order"
clearable
......
......@@ -106,7 +106,7 @@
style="width: 150px"
></ElInput>
</ElFormItem>
<ElFormItem label="排序">
<ElFormItem label="排序方式">
<el-select
v-model="searchForm.order"
clearable
......
......@@ -269,7 +269,7 @@
</template>
<script setup lang="ts">
import { computed, nextTick, ref, watch, defineProps, defineEmits } from 'vue'
import { computed, nextTick, ref, watch } from 'vue'
import useLodop from '@/utils/hooks/useLodop'
import TableView from '@/components/TableView.vue'
import { OrderData, ProductList, IorderItem } from '@/types/api/podMakeOrder'
......@@ -499,14 +499,12 @@ async function barcodeInput() {
console.log('pending', pending)
await submitInspection(pending, async () => {
await inputActive()
await getPackingData(code)
noObj.value = {}
})
} else {
await inputActive()
await getPackingData(code)
}
await inputActive()
await getPackingData(code)
isLock.value = false
}
async function submitInspection(objs?: OrderData, callback?: () => void) {
......@@ -525,12 +523,10 @@ async function submitInspection(objs?: OrderData, callback?: () => void) {
ElMessage.success(res.message)
coverImage.value = ''
testingData.value = {}
await inputActive()
isLock.value = false
callback?.()
} catch (e) {
console.error(e)
await inputActive()
isLock.value = false
}
}
......@@ -591,7 +587,7 @@ async function getPackingData(code: string) {
async function printFile(data: OrderData) {
// await props.printOrderOne(data)
await printOrderOne(data)
noObj.value[data.id!] = data
noObj.value[data.id as number] = data
await inputActive()
}
function printOrderOne(item: OrderData): Promise<void> {
......
......@@ -16,6 +16,15 @@
<span>播种墙配货</span>
<span v-if="socketConnect === 'online'" class="online">[在线]</span>
<span v-else class="offline">[离线]</span>
<ElButton
v-if="socketConnect === 'offline'"
type="success"
size="small"
:icon="Refresh"
@click="reconnectWebSocket"
>
刷新
</ElButton>
</div>
</template>
<div class="pod-make-order-content">
......@@ -268,7 +277,7 @@ import {
printNormalPdf,
} from '@/api/podCnOrder'
import useUserStore from '@/store/user'
import { Check } from '@element-plus/icons-vue'
import { Check, Refresh } from '@element-plus/icons-vue'
import socket from '@/utils/cnWebsocket'
import { WarehouseListData } from '@/types/api/podUsOrder'
import { ElMessage } from 'element-plus'
......@@ -1086,6 +1095,27 @@ const handleWarehouseChange = (value: string | number) => {
_warehouseId.value = value
initOrderDetailBox()
}
const reconnectWebSocket = async () => {
if (!userStore.user?.factory.id) return
try {
await socket.init(
{
account: userStore.user?.account.toString(),
factoryNo: userStore.user?.factory.id.toString(),
},
messageChange,
)
socket.send({
code: 'STARTORDERCN',
factoryNo: userStore.user?.factory.id,
warehouseId: warehouseId.value,
})
} catch (error) {
console.error('WebSocket 重连失败:', error)
ElMessage.error('WebSocket 重连失败,请稍后重试')
}
}
</script>
<style scoped lang="scss">
......
......@@ -16,6 +16,15 @@
<span>超级播种墙配货</span>
<span v-if="socketConnect === 'online'" class="online">[在线]</span>
<span v-else class="offline">[离线]</span>
<ElButton
v-if="socketConnect === 'offline'"
type="success"
size="small"
:icon="Refresh"
@click="reconnectWebSocket"
>
刷新
</ElButton>
</div>
</template>
<div class="pod-make-order-content">
......@@ -241,7 +250,7 @@ import {
printNormalPdf,
} from '@/api/podCnOrder'
import useUserStore from '@/store/user'
import { Check } from '@element-plus/icons-vue'
import { Check, Refresh } from '@element-plus/icons-vue'
import socket from '@/utils/cnSuperWebsocket'
import { ElMessage } from 'element-plus'
import { filePath } from '@/api/axios.ts'
......@@ -969,6 +978,25 @@ const handleCurrentChange = (url: string) => {
coverImage.value = url || ''
}
}
const reconnectWebSocket = async () => {
if (userStore.user?.factory.id) {
try {
await socket.init(
{
account: userStore.user?.account.toString(),
factoryNo: userStore.user?.factory.id.toString(),
},
messageChange,
)
socket.send({
code: 'SUPERFACTORYSTARTORDER',
factoryNo: userStore.user?.factory.id,
})
} catch (error) {
console.error(error)
}
}
}
</script>
<style scoped lang="scss">
......
<template>
<el-dialog
v-model="createLogisticDialogVisible"
:close-on-click-modal="false"
title="创建物流订单"
>
<div style="display: flex; align-items: center; gap: 20px">
<span style="font-weight: 500">是否自动匹配物流方式</span>
<el-radio-group v-model="isAutoMatch">
<el-radio :value="false"></el-radio>
<el-radio :value="true"></el-radio>
</el-radio-group>
</div>
<div
v-if="!isAutoMatch && logisticCompanyList.length > 0"
style="margin: 10px; border: 1px solid #e0e0e0; display: flex"
>
<div
style="
display: flex;
flex-direction: column;
width: 200px;
font-weight: 500;
"
>
<div
v-for="item in logisticCompanyList"
:key="item.id"
class="logistic-company-item"
:class="{
'selected-logistic-company':
selectedLogisticCompany?.id === item.id,
}"
@click="selectLogisticCompany(item)"
>
{{ item.name }}
</div>
</div>
<div
style="
width: 100%;
min-height: 220px;
display: flex;
justify-content: center;
align-items: flex-start;
"
>
<div
v-if="logisticsWayList.length > 0"
style="
padding: 0 10px;
width: 100%;
display: flex;
align-items: center;
"
>
<el-radio-group v-model="logisticsWayId">
<el-radio
v-for="item in logisticsWayList"
:key="item.id"
:value="item.id"
style="width: 200px; height: 40px"
>
{{ item.name }}
</el-radio>
</el-radio-group>
</div>
<el-empty v-else description="暂无数据" :image-size="80" />
</div>
</div>
<template #footer>
<el-button @click="cancelDialog"> 取消 </el-button>
<el-button type="primary" @click="confirmDialog"> 确定 </el-button>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import {
getLogisticsCompanyList,
ILogisticsCompany,
getLogisticsWayListByCompanyId,
LogisticsWayData,
} from '@/api/logistics'
import { createLogisticsOrdersApi } from '@/api/podCnOrder'
const createLogisticDialogVisible = ref(false)
const isAutoMatch = ref(false)
const logisticCompanyList = ref<ILogisticsCompany[]>([])
const selectedLogisticCompany = ref<ILogisticsCompany | null>(null)
const logisticsWayList = ref<LogisticsWayData[]>([])
const logisticsWayId = ref<number | null>(null)
const orderIdList = ref<(string | number)[]>([])
const cancelDialog = () => {
logisticsWayList.value = []
logisticCompanyList.value = []
selectedLogisticCompany.value = null
logisticsWayId.value = null
orderIdList.value = []
isAutoMatch.value = false
createLogisticDialogVisible.value = false
}
// 获取物流公司列表
const getLogisticsCompanyListFn = async () => {
const { data } = await getLogisticsCompanyList()
logisticCompanyList.value = data as unknown as ILogisticsCompany[]
if (logisticCompanyList.value.length > 0) {
selectedLogisticCompany.value = logisticCompanyList.value[0]
await getLogisticsWayListFn(selectedLogisticCompany.value.id)
}
}
// 获取物流方式列表
const getLogisticsWayListFn = async (id: number) => {
const { data } = await getLogisticsWayListByCompanyId(id)
logisticsWayList.value = data
}
// 选择物流公司
const selectLogisticCompany = async (item: ILogisticsCompany) => {
selectedLogisticCompany.value = item
await getLogisticsWayListFn(item.id)
}
const confirmDialog = async () => {
await createLogisticsOrdersApi(orderIdList.value, logisticsWayId.value)
.then((res) => {
emits('show-result', res.data)
})
.finally(() => {
logisticsWayList.value = []
logisticCompanyList.value = []
selectedLogisticCompany.value = null
logisticsWayId.value = null
orderIdList.value = []
isAutoMatch.value = false
createLogisticDialogVisible.value = false
})
}
const showDialog = async (ids: (string | number)[]) => {
await getLogisticsCompanyListFn()
orderIdList.value = ids
createLogisticDialogVisible.value = true
}
const emits = defineEmits<{
(
e: 'show-result',
data: Array<{
id: string | number
status: boolean
factoryOrderNumber?: string
message: string
}>,
): void
}>()
defineExpose({
showDialog,
})
watch(isAutoMatch, (newVal) => {
if (newVal) {
getLogisticsCompanyListFn()
}
})
</script>
<style lang="scss" scoped>
.logistic-company-item {
padding: 10px 10px;
cursor: pointer;
&:hover {
background-color: #f0f0f0;
}
}
.selected-logistic-company {
background-color: #f0f0f0;
}
</style>
......@@ -11,7 +11,7 @@
label-width="70px"
>
<!-- 批量下载 -->
<ElFormItem label="创建时间" v-if="status === 'BATCH_DOWNLOAD'">
<ElFormItem v-if="status === 'BATCH_DOWNLOAD'" label="创建时间">
<el-date-picker
v-model="timeRange"
:teleported="false"
......@@ -29,7 +29,7 @@
>
</el-date-picker>
</ElFormItem>
<ElFormItem label="创建人" v-if="status === 'BATCH_DOWNLOAD'">
<ElFormItem v-if="status === 'BATCH_DOWNLOAD'" label="创建人">
<ElSelect
v-model="searchForm.employeeId"
placeholder="请选择"
......@@ -45,7 +45,7 @@
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem label="工艺类型" v-if="status === 'BATCH_DOWNLOAD'">
<ElFormItem v-if="status === 'BATCH_DOWNLOAD'" label="工艺类型">
<ElSelect
v-model="searchForm.craftType"
placeholder="请选择"
......@@ -62,7 +62,7 @@
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem label="下载状态" v-if="status === 'BATCH_DOWNLOAD'">
<ElFormItem v-if="status === 'BATCH_DOWNLOAD'" label="下载状态">
<ElSelect
v-model="searchForm.downloadStatus"
placeholder="下载状态"
......@@ -78,7 +78,7 @@
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem label="排版状态" v-if="status === 'BATCH_DOWNLOAD'">
<ElFormItem v-if="status === 'BATCH_DOWNLOAD'" label="排版状态">
<ElSelect
v-model="searchForm.syntheticStatus"
placeholder="排版状态"
......@@ -94,7 +94,7 @@
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem label="自动排版" v-if="status === 'BATCH_DOWNLOAD'">
<ElFormItem v-if="status === 'BATCH_DOWNLOAD'" label="自动排版">
<ElSelect
v-model="searchForm.automaticComposing"
placeholder="自动排版"
......@@ -111,7 +111,7 @@
</ElSelect>
</ElFormItem>
<ElFormItem label="仓库" v-if="status !== 'BATCH_DOWNLOAD'">
<ElFormItem v-if="status !== 'BATCH_DOWNLOAD'" label="仓库">
<ElSelect
v-model="searchForm.warehouseId"
clearable
......@@ -127,7 +127,7 @@
></el-option>
</ElSelect>
</ElFormItem>
<ElFormItem label="平台" v-if="status !== 'BATCH_DOWNLOAD'">
<ElFormItem v-if="status !== 'BATCH_DOWNLOAD'" label="平台">
<ElSelect
v-model="searchForm.platform"
value-key=""
......@@ -153,7 +153,7 @@
</ElSelect>
</ElFormItem>
<ElFormItem label="工艺" v-if="status !== 'BATCH_DOWNLOAD'">
<ElFormItem v-if="status !== 'BATCH_DOWNLOAD'" label="工艺">
<LogisticsWaySelect
v-model="searchForm.craftCode"
:company-list="craftList"
......@@ -162,7 +162,7 @@
start-placeholder="请选择工艺名称"
></LogisticsWaySelect>
</ElFormItem>
<ElFormItem label="库存SKU" v-if="status !== 'BATCH_DOWNLOAD'">
<ElFormItem v-if="status !== 'BATCH_DOWNLOAD'" label="库存SKU">
<ElInput
v-model.trim="searchForm.thirdSkuCode"
placeholder="库存SKU"
......@@ -170,7 +170,7 @@
style="width: 180px"
></ElInput>
</ElFormItem>
<ElFormItem label="款号" v-if="status !== 'BATCH_DOWNLOAD'">
<ElFormItem v-if="status !== 'BATCH_DOWNLOAD'" label="款号">
<ElInput
v-model.trim="searchForm.supplierProductNo"
placeholder="款号"
......@@ -186,7 +186,7 @@
style="width: 150px"
/>
</ElFormItem>
<ElFormItem label="生产单号" v-if="status !== 'BATCH_DOWNLOAD'">
<ElFormItem v-if="status !== 'BATCH_DOWNLOAD'" label="生产单号">
<ElInput
v-model.trim="searchForm.factorySubOrderNumber"
placeholder="生产单号"
......@@ -194,7 +194,7 @@
style="width: 150px"
/>
</ElFormItem>
<ElFormItem label="店铺单号" v-if="status !== 'BATCH_DOWNLOAD'">
<ElFormItem v-if="status !== 'BATCH_DOWNLOAD'" label="店铺单号">
<ElInput
v-model.trim="searchForm.shopNumber"
placeholder="店铺单号"
......@@ -202,7 +202,7 @@
style="width: 150px"
/>
</ElFormItem>
<ElFormItem label="尺码类型" v-if="status !== 'BATCH_DOWNLOAD'">
<ElFormItem v-if="status !== 'BATCH_DOWNLOAD'" label="尺码类型">
<ElSelect
v-model="searchForm.sizeType"
clearable
......@@ -218,7 +218,7 @@
></el-option>
</ElSelect>
</ElFormItem>
<ElFormItem label="排序" v-if="status !== 'BATCH_DOWNLOAD'">
<ElFormItem v-if="status !== 'BATCH_DOWNLOAD'" label="排序方式">
<el-select
v-model="searchForm.order"
clearable
......@@ -229,7 +229,7 @@
<el-option value="asc" label="按创建时间从旧到新"></el-option>
</el-select>
</ElFormItem>
<ElFormItem label="印刷" v-if="status !== 'BATCH_DOWNLOAD'">
<ElFormItem v-if="status !== 'BATCH_DOWNLOAD'" label="印刷">
<el-radio-group
v-model="searchForm.customizedQuantity"
@click.stop="(e: Event) => handleRadioGroupClick(e)"
......@@ -239,7 +239,7 @@
<el-radio-button label="normal">普品</el-radio-button>
</el-radio-group>
</ElFormItem>
<ElFormItem label="数量" v-if="status !== 'BATCH_DOWNLOAD'">
<ElFormItem v-if="status !== 'BATCH_DOWNLOAD'" label="数量">
<el-radio-group
v-model="searchForm.multi"
@click.stop="(e: Event) => handleMultiRadioGroupClick(e)"
......@@ -253,8 +253,8 @@
</el-radio-group>
</ElFormItem>
<ElFormItem
label="标签"
v-if="status == 'TO_BE_REPLENISHMENT' || status == 'PICKING'"
label="标签"
>
<ElSelect
v-model="searchForm.outOfStock"
......@@ -612,38 +612,6 @@
</ElDropdown>
</ElFormItem>
<ElFormItem>
<!-- <span
v-if="
status === 'PICKING' ||
status === 'TO_BE_REPLENISHMENT' ||
status === 'IN_PRODUCTION'
"
class="item"
>
<ElButton
:loading="tifDownloadLoading"
type="warning"
@click="downloadTif('tiff')"
>
TIF排版
</ElButton>
</span>
<span
v-if="
status === 'PICKING' ||
status === 'TO_BE_REPLENISHMENT' ||
status === 'IN_PRODUCTION'
"
class="item"
>
<ElButton
:loading="pngDownloadLoading"
type="warning"
@click="downloadTif('png')"
>
PNG排版
</ElButton>
</span> -->
<span v-if="status === 'TO_BE_CONFIRMED'" class="item">
<ElButton type="success" @click="confirmProduct">
确认生产
......@@ -734,14 +702,14 @@
单件打单
</ElButton>
</span>
<span
<!-- <span
v-if="status === 'WAIT_SHIPMENT' && isSuperFactory"
class="item"
>
<ElButton type="danger" @click="printSuperPodOrder">
超级播种墙配货
</ElButton>
</span>
</span> -->
<span v-if="status === 'CREATE_LOGISTICS'" class="item">
<ElButton type="warning" @click="logisticsToPicking">
转至待排单
......@@ -785,7 +753,7 @@
selection.length === 0 ||
selection.some((item) => item.shipmentType !== 1)
"
@click="getOrderByIdApi('createLogisticsOrder')"
@click="handleCreateLogistic()"
>创建物流订单</ElDropdownItem
>
<ElDropdownItem
......@@ -879,6 +847,11 @@
<span v-if="['WAIT_SHIPMENT'].includes(status)" class="item">
<ElButton type="primary" @click="printNormal"> 普货拣货 </ElButton>
</span>
<span v-if="['WAIT_SHIPMENT'].includes(status)" class="item">
<ElButton type="primary" @click="printNormalProductionOrder">
打印普胚生产单
</ElButton>
</span>
<span
v-if="
status === 'STOCK_OUT' ||
......@@ -963,6 +936,13 @@
</template>
</ElDropdown>
</span>
<span v-if="['COMPLETE'].includes(status)" class="item">
<ElButton
type="warning"
@click="getOrderByIdApi('getTrackingNumber')"
>获取跟踪号</ElButton
>
</span>
<span
v-if="['WAIT_TRACK', 'COMPLETE', 'IN_TRANSIT'].includes(status)"
class="item"
......@@ -1829,7 +1809,9 @@
>
<span class="operate-item">
<ElButton
:disabled="!row.url && !row.tiffUrl"
:disabled="
(!row.url && !row.tiffUrl) || row.enableArrange === false
"
link
type="primary"
@click="handleDownload(row)"
......@@ -1853,7 +1835,7 @@
type="primary"
@click="printPickingOrderItem(row, 1)"
>
打印拣货单
拣货单
</ElButton>
</span>
<span class="operate-item">
......@@ -1862,19 +1844,19 @@
type="primary"
@click="printPickingOrderItem(row, 2)"
>
打印生产单
生产单
</ElButton>
</span>
<span class="operate-item">
<ElButton
:disabled="row.productNum > 50"
:disabled="row.productNum > 50 || row.enableArrange === false"
link
type="warning"
:loading="reComposingLoadingMap[row.id]"
@click="showArrange(1, row)"
>
新排版
</ElButton>
</span>
<span class="operate-item">
......@@ -2105,6 +2087,17 @@
</template>
<template #operations>
<div
v-if="
(cardItem?.productMark === 'custom_normal' ||
cardItem?.productMark === 'normal') &&
(status == 'TO_BE_ARRANGE' || status == 'PICKING')
"
class="customizedQuantity"
:title="`类型:${getProductMarkt(cardItem?.productMark)}面`"
>
{{ getProductMarkt(cardItem?.productMark) }}
</div>
<div
v-if="cardItem?.customizedQuantity"
class="customizedQuantity"
:title="`类型:${getQuantityText(
......@@ -2797,6 +2790,11 @@
}
"
></ChangeWayDialog>
<CreateLogisticDialog
ref="createLogisticDialogRef"
:row-data="currentItem"
@show-result="handleShowResult"
/>
<print-warehouse-sku-tag ref="printWarehouseSkuDialogRef" />
<weight-dialog
ref="weightDialogRef"
......@@ -2880,6 +2878,7 @@ import {
batchDownloadRecomposingApi,
getCustomTagListCnApi,
printNormalPdf,
printNormalProducePdf,
changeLogisticsApi,
getEmployeeListApi,
allErpCodeListApi,
......@@ -2889,6 +2888,7 @@ import {
// import { logisticsCompanyAllCodelist } from '@/api/logistics.ts'
import { BaseRespData } from '@/types/api'
import ChangeWayDialog from './components/ChangeWayDialog.vue'
import CreateLogisticDialog from './components/CreateLogisticDialog.vue'
import UpdateAddress from './components/updateAddress.vue'
import { useEnterKeyTrigger } from '@/utils/hooks/useEnterKeyTrigger.ts'
......@@ -2928,7 +2928,7 @@ import RightClickMenu from '@/components/RightClickMenu.vue'
import ResultInfo from './components/ResultInfo.vue'
import { isArray, isString } from '@/utils/validate'
import platformJson from '../../../json/platform.json'
import useUserStore from '@/store/user'
// import useUserStore from '@/store/user'
import BigNumber from 'bignumber.js'
import {
useRouter,
......@@ -2952,9 +2952,9 @@ declare global {
}
}
const userStore = useUserStore()
// const userStore = useUserStore()
const isSuperFactory: boolean = userStore.user?.factory.dropShipping || false
// const isSuperFactory: boolean = userStore.user?.factory.dropShipping || false
const tabsNav = ref<Tab[]>()
const isAuto = ref(true)
......@@ -2962,6 +2962,7 @@ const printWarehouseSkuDialogRef = ref()
const weightDialogRef = ref()
const updateCustomDeclarationInfoDialogRef = ref()
const updateCustomDeclarationInfoDialogVisible = ref(false)
const createLogisticDialogRef = ref()
const calculatedPrice = (item: ProductList) => {
const templatePrice = new BigNumber(item.templatePrice || 0)
const craftPrice = new BigNumber(item.craftPrice || 0)
......@@ -3327,6 +3328,42 @@ const printNormal = async () => {
window.open(filePath + res.message)
}
const printNormalProductionOrder = async () => {
const orderIds: number[] = []
if (!selection.value.length) {
return ElMessage.warning('请选择订单')
}
selection.value.forEach((s) => {
s.productList &&
s.productList.forEach((p) => {
if (p.productMark === 'normal' || p.productMark === 'custom_normal') {
orderIds.push(p.id)
}
})
})
if (!orderIds.length) {
ElMessage.warning('暂无可打印的普胚生产单')
return
}
const loading = ElLoading.service({
fullscreen: true,
text: '操作中...',
background: 'rgba(0, 0, 0, 0.3)',
})
try {
const res = await printNormalProducePdf(orderIds)
if (res.code !== 200) return
ElMessage.success('操作成功')
window.open(filePath + res.message)
} catch (e) {
console.error(e)
} finally {
loading.close()
}
}
const completeDelivery = async () => {
if (selection.value.length === 0) {
return ElMessage.warning('请选择订单')
......@@ -3835,7 +3872,7 @@ const tableColumns = computed(() => {
{
label: '操作',
slot: 'operate',
width: 350,
width: 260,
align: 'center',
fixed: 'right',
prop: 'operate',
......@@ -4259,13 +4296,18 @@ const downloadTif = async (type: string, templateWidth: number) => {
text: '操作中...',
background: 'rgba(0, 0, 0, 0.3)',
})
const url =
status.value === 'TO_BE_REPLENISHMENT'
? 'factory/podJomallOrderCn/replenishmentComposingDesignImages'
: 'factory/podJomallOrderCn/composingDesignImages'
try {
const res = await composingDesignImages(
url,
cardSelection.value.map((el) => el.id),
type,
templateWidth,
)
const url =
const filePathUrl =
type === 'tiff'
? res.message?.startsWith('/temp')
? `https://factory.jomalls.com/upload/factory` + res.message
......@@ -4273,10 +4315,10 @@ const downloadTif = async (type: string, templateWidth: number) => {
: filePath + res.message
if (type === 'tiff') {
window.open(url, '_blank')
window.open(filePathUrl, '_blank')
tifDownloadLoading.value = false
} else {
fetch(url)
fetch(filePathUrl)
.then((response) => {
// 确保响应是 OK
if (!response.ok) {
......@@ -4352,9 +4394,13 @@ const downloadSingleType = async (
templateWidth?: number,
) => {
try {
const res = await composingDesignImages([id], type, templateWidth)
const url =
status.value === 'TO_BE_REPLENISHMENT'
? 'factory/podJomallOrderCn/replenishmentComposingDesignImages'
: 'factory/podJomallOrderCn/composingDesignImages'
const res = await composingDesignImages(url, [id], type, templateWidth)
const isTiff = type === 'tiff'
const url = isTiff
const filePathUrl = isTiff
? res.message?.startsWith('/temp')
? `https://factory.jomalls.com/upload/factory` + res.message
: `https://ps.jomalls.com/tiff/` + res.message
......@@ -4362,10 +4408,10 @@ const downloadSingleType = async (
if (isTiff) {
// 对于tiff类型,直接在新窗口打开
window.open(url, '_blank')
window.open(filePathUrl, '_blank')
} else {
// 对于其他类型,使用下载方式
await downloadFile(url, res.message as string)
await downloadFile(filePathUrl, res.message as string)
}
} catch (error) {
console.error(`下载类型 ${type} 时出错:`, error)
......@@ -4830,7 +4876,33 @@ const showArrange = async (type: number, data?: PodCnOrderListData) => {
if (type === 1 || type === 3) {
typesettingRow.value = data
} else if (type === 2) {
const ALLOWED_PRODUCT_MARKS = ['custom_normal', 'normal']
const selectedIds = cardSelection.value.map((item) => item.id)
const isProductMark = cardSelection.value.find((item) =>
ALLOWED_PRODUCT_MARKS.includes(item.productMark as string),
)
if (isProductMark) {
const bool = cardSelection.value.every((item) =>
ALLOWED_PRODUCT_MARKS.includes(item.productMark as string),
)
if (!bool) {
return await ElMessageBox.confirm(
'无法排单,你选择的生产单包含多种商品类型,排单不支持多种商品类型混排,请选择同一类型的商品对应的生产单后再试!',
'错误提示',
{
confirmButtonText: '确定',
type: 'warning',
},
)
} else {
await ElMessageBox.confirm('确认对所选择的生产单进行排单?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
return arrangeFinish()
}
}
if (selectedIds.length === 0) {
return ElMessage({
......@@ -4950,13 +5022,13 @@ const podDistributionOrderShow = async () => {
podDistributionOrderVisible.value = true
}
const superPodOrderVisible = ref(false)
const printSuperPodOrder = async () => {
const lodop = getCLodop(null, null)
if (!lodop) return
// const printSuperPodOrder = async () => {
// const lodop = getCLodop(null, null)
// if (!lodop) return
sheetPrinter.value = lodop.GET_PRINTER_NAME(0)
superPodOrderVisible.value = true
}
// sheetPrinter.value = lodop.GET_PRINTER_NAME(0)
// superPodOrderVisible.value = true
// }
/**
* @description: 创建物流、获取跟踪号、获取打印面单、更改物流、取消物流订单
......@@ -4973,10 +5045,7 @@ const getOrderByIdApi = async (type: string) => {
Fn: (orderIds: (string | number)[]) => Promise<BaseRespData<never>>
}
} = {
createLogisticsOrder: {
message: '创建物流订单',
Fn: createLogisticsOrdersApi,
},
getTrackingNumber: {
message: '获取跟踪号',
Fn: getTrackingNumberApi,
......@@ -5815,6 +5884,12 @@ function getQuantityText(qty: number) {
if (!qty || qty <= 0) return ''
return Math.floor(qty) === 1 ? '单' : '多'
}
function getProductMarkt(productMark: string) {
if (!productMark) return ''
if (productMark === 'custom_normal') return 'CB'
if (productMark === 'normal') return 'G'
return ''
}
const handleMark = (mark: string) => {
switch (mark) {
......@@ -5908,6 +5983,26 @@ const handleStockOut = async (row: PodCnOrderListData) => {
})
}
// 创建物流订单
const handleCreateLogistic = () => {
const ids = selection.value.map((item) => item.id)
nextTick(() => {
createLogisticDialogRef.value?.showDialog(ids)
})
}
const handleShowResult = (data: Array<{
id: string | number
status: boolean
factoryOrderNumber?: string
message: string
}>) => {
resultInfo.value = data || []
if (resultInfo.value.length > 0) {
resultRefs.value?.showDialog()
}
}
const getNewImageFn = (img: string) => {
try {
if (img.startsWith('http')) return img
......
......@@ -16,6 +16,15 @@
<span>播种墙配货</span>
<span v-if="socketConnect === 'online'" class="online">[在线]</span>
<span v-else class="offline">[离线]</span>
<ElButton
v-if="socketConnect === 'offline'"
type="success"
size="small"
:icon="Refresh"
@click="reconnectWebSocket"
>
刷新
</ElButton>
</div>
</template>
<div class="pod-make-order-content">
......@@ -146,13 +155,14 @@
<span class="box-top-item-box-index-text">号箱</span>
<span style="font-size: 30px">放入第</span>
<div class="box-top-item-box-index-number">
<div class="box-top-item-box-index-number" :style="{color:podOrderDetailsData?.pickingNumber ===
podOrderDetailsData?.purchaseNumber ? 'rgb(0, 255, 0)' : ''}">
{{ podOrderDetailsData?.pickingNumber }}
</div>
<span style="font-size: 30px">件商品</span>
</div>
<div v-else class="box-top-item-box-index-text">
单件商品订单,不占用播种墙
单件商品<span style="color: rgb(0, 255, 0)">(配齐)</span>,不占用播种墙
</div>
<div class="box-top-item-status">
<span
......@@ -180,7 +190,7 @@
<ElButton type="success" @click="handlePrintFinish"
>打单完成</ElButton
>
<ElButton type="danger" @click="handleClearBox">清空箱子</ElButton>
<ElButton :disabled="boxIndex === 0" type="danger" @click="handleClearBox">清空箱子</ElButton>
</div>
<div
v-if="
......@@ -255,10 +265,11 @@ import {
printNormalPickPdfApi,
} from '@/api/podUsOrder'
import useUserStore from '@/store/user'
import { Check } from '@element-plus/icons-vue'
import { Check, Refresh } from '@element-plus/icons-vue'
import socket from '@/utils/websocket'
import { WarehouseListData } from '@/types/api/podUsOrder'
import { filePath } from '@/api/axios.ts'
import { ElButton, ElIcon } from 'element-plus'
const { getCLodop } = useLodop()
......@@ -467,7 +478,7 @@ const renderItemBox = (bool: boolean) => {
renderLock = true
let boxItem = podBoxList.value?.find((item) => item.box === boxIndex.value)
console.log(boxItem,'boxItem')
console.log(boxItem, 'boxItem')
if (!boxItem) boxItem = { data: { productList: [] } }
const { data } = boxItem
data?.productList?.forEach((el) => {
......@@ -529,7 +540,7 @@ const renderItemBox = (bool: boolean) => {
console.log(408, data)
if (productList.every((item) => item.power)) {
if(userStore.user?.id!==boxItem.fromUser) return
if (userStore.user?.id !== boxItem.fromUser) return
print(data, false, () => {
renderLock = false
})
......@@ -561,7 +572,7 @@ const messageChange = (data: WebSocketMessage) => {
}
}
const setPodBoxList = (data: WebSocketMessage) => {
console.log(data,'datatatata')
console.log(data, 'datatatata')
const obj = data.txt
if (obj && typeof obj === 'string') {
const parsedData = JSON.parse(obj)
......@@ -646,6 +657,9 @@ const getPackingData = async (code: string) => {
productionOrder.value = ''
return
}
if(!warehouseId.value){
return ElMessage.warning('请选择仓库')
}
const res = await getPackingDataApi(
code,
factoryNo,
......@@ -702,17 +716,9 @@ const submitInspection = async (callback: () => void) => {
if (!factoryNo) {
return
}
const data = podOrderDetailsData.value?.id
? [
{
id: podOrderDetailsData.value.id,
version: podOrderDetailsData.value?.version,
},
]
: []
try {
const res = await submitInspectionApi(
data,
podOrderDetailsData.value?.id,
boxIndex.value,
warehouseId.value,
)
......@@ -749,7 +755,7 @@ const initOrderDetailBox = async () => {
}
orderStore.setPodBoxList({
boxList: res.data,
fromUser: userStore.user?userStore.user.id : 0,
fromUser: userStore.user ? userStore.user.id : 0,
factoryNo,
warehouseId: warehouseId.value,
})
......@@ -903,6 +909,10 @@ const handleBoxClick = (item: PodMakeOrderData) => {
}
const handleClearBox = async () => {
try {
if(!boxIndex.value){
ElMessage.warning('请选择箱子')
return
}
await ElMessageBox.alert('确定清空当前箱子吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
......@@ -914,6 +924,7 @@ const handleClearBox = async () => {
if (!factoryNo) {
return
}
try {
const res = await clearBoxApi(
factoryNo,
......@@ -1012,7 +1023,7 @@ const print = (data: OrderData, forcePrint = false, callback?: () => void) => {
const factoryNo = userStore.user?.factory.id
if (!factoryNo) return
orderStore.setPodBoxList({
fromUser:userStore.user?userStore.user.id:0,
fromUser: userStore.user ? userStore.user.id : 0,
boxList: item ? (item.data as PodMakeOrderData[]) : null,
factoryNo,
box: _boxIndex || undefined,
......@@ -1031,7 +1042,10 @@ const clearAllBox = async () => {
return
}
try {
const res = await clearAllBoxApi(warehouseId.value,userStore.user?.factory.id)
const res = await clearAllBoxApi(
warehouseId.value,
userStore.user?.factory.id,
)
if (res.code !== 200) return
// orderStore.setPodBoxList({
// boxList: res.data,
......@@ -1103,6 +1117,28 @@ const printNormal = async () => {
ElMessage.success('操作成功')
window.open(filePath + res.message)
}
const reconnectWebSocket = async () => {
if (!userStore.user?.factory.id) return
try {
await socket.init(
{
account: userStore.user?.account.toString(),
factoryNo: userStore.user?.factory.id.toString(),
},
messageChange,
)
socket.send({
code: 'STARTORDER',
factoryNo: userStore.user?.factory.id,
warehouseId: warehouseId.value,
})
} catch (error) {
console.error('WebSocket 重连失败:', error)
ElMessage.error('WebSocket 重连失败,请稍后重试')
}
}
</script>
<style scoped lang="scss">
......
......@@ -577,40 +577,6 @@
</template>
</ElDropdown>
</ElFormItem>
<!-- <ElFormItem
v-if="
status === 'PICKING' ||
status === 'TO_BE_REPLENISHMENT' ||
status === 'IN_PRODUCTION'
"
>
<span class="item">
<ElButton
:loading="tifDownloadLoading"
type="warning"
@click="downloadTif('tiff')"
>
TIF排版
</ElButton>
</span>
</ElFormItem>
<ElFormItem
v-if="
status === 'PICKING' ||
status === 'TO_BE_REPLENISHMENT' ||
status === 'IN_PRODUCTION'
"
>
<span class="item">
<ElButton
:loading="pngDownloadLoading"
type="warning"
@click="downloadTif('png')"
>
PNG排版
</ElButton>
</span>
</ElFormItem> -->
<ElFormItem v-if="status === 'TO_BE_CONFIRMED'">
<span class="item">
<ElButton type="success" @click="confirmProduct">
......@@ -2017,7 +1983,7 @@
class="operate-box-vertical"
>
<el-link
:disabled="row.isUpload"
:disabled="row.isUpload || row.enableArrange === false"
underline="never"
type="success"
@click="uploadFile(row)"
......@@ -2031,7 +1997,7 @@
<Loading />
</el-icon>
<el-link
:disabled="!row.prnUrl"
:disabled="!row.prnUrl || row.enableArrange === false"
style="margin-left: 8px"
underline="never"
:title="fileName(row)"
......@@ -2085,7 +2051,9 @@
</span>
<span class="operate-item">
<ElButton
:disabled="!row.url && !row.tiffUrl"
:disabled="
(!row.url && !row.tiffUrl) || row.enableArrange === false
"
link
type="primary"
@click="handleDownload(row)"
......@@ -2098,7 +2066,7 @@
</span>
<span class="operate-item">
<ElButton
:disabled="row.productNum > 50"
:disabled="row.productNum > 50 || row.enableArrange === false"
link
title="重新排版"
type="warning"
......@@ -2370,6 +2338,17 @@
</template>
<template #operations>
<div
v-if="
(cardItem?.productMark === 'custom_normal' ||
cardItem?.productMark === 'normal') &&
(status == 'TO_BE_ARRANGE' || status == 'PICKING')
"
class="customizedQuantity"
:title="`类型:${getProductMarkt(cardItem?.productMark)}面`"
>
{{ getProductMarkt(cardItem?.productMark) }}
</div>
<div
v-if="cardItem?.customizedQuantity"
class="customizedQuantity"
:title="`类型:${getQuantityText(
......@@ -3298,7 +3277,7 @@ import {
CircleCheckFilled,
} from '@element-plus/icons-vue'
import { Column, ElFormItem, ElMessage } from 'element-plus'
import { computed, onMounted, ref, nextTick, reactive } from 'vue'
import { computed, onMounted, ref, nextTick, reactive, h } from 'vue'
import FastProduction from './FastProduction.vue'
import { filePath } from '@/api/axios'
import PodMakeOrder from './PodMakeOrder.vue'
......@@ -4600,23 +4579,28 @@ const downloadTif = async (type: string, templateWidth: number) => {
text: '操作中...',
background: 'rgba(0, 0, 0, 0.3)',
})
const url =
status.value === 'TO_BE_REPLENISHMENT'
? 'factory/podJomallOrderUs/replenishmentComposingDesignImages'
: 'factory/podJomallOrderUs/composingDesignImages'
try {
const res = await composingDesignImages(
url,
cardSelection.value.map((el) => el.id),
type,
templateWidth,
)
const url =
const filePathUrl =
type === 'tiff'
? res.message?.startsWith('/temp')
? `https://factory.jomalls.com/upload/factory` + res.message
: `https://ps.jomalls.com/tiff/` + res.message
: filePath + res.message
if (type === 'tiff') {
window.open(url, '_blank')
window.open(filePathUrl, '_blank')
tifDownloadLoading.value = false
} else {
fetch(url)
fetch(filePathUrl)
.then((response) => {
// 确保响应是 OK
if (!response.ok) {
......@@ -4691,9 +4675,13 @@ const downloadSingleType = async (
templateWidth?: number,
) => {
try {
const res = await composingDesignImages([id], type, templateWidth)
const url =
status.value === 'TO_BE_REPLENISHMENT'
? 'factory/podJomallOrderUs/replenishmentComposingDesignImages'
: 'factory/podJomallOrderUS/composingDesignImages'
const res = await composingDesignImages(url, [id], type, templateWidth)
const isTiff = type === 'tiff'
const url = isTiff
const filePathUrl = isTiff
? res.message?.startsWith('/temp')
? `https://factory.jomalls.com/upload/factory` + res.message
: `https://ps.jomalls.com/tiff/` + res.message
......@@ -4701,10 +4689,10 @@ const downloadSingleType = async (
if (isTiff) {
// 对于tiff类型,直接在新窗口打开
window.open(url, '_blank')
window.open(filePathUrl, '_blank')
} else {
// 对于其他类型,使用下载方式
await downloadFile(url, res.message as string)
await downloadFile(filePathUrl, res.message as string)
}
} catch (error) {
console.error(`下载类型 ${type} 时出错:`, error)
......@@ -4778,95 +4766,6 @@ const handleMultiRadioGroupClick = (event: Event) => {
}
}
}
// const downloadTifItem = async () => {
// const row = { ...(typesettingRow.value as PodUsOrderListData) }
// const loading = ElLoading.service({
// fullscreen: true,
// text: '操作中...',
// background: 'rgba(0, 0, 0, 0.3)',
// })
// const { templateWidth, typeArr } = typesettingForm.value
// const type = (typeArr?.join(',') as string) || ''
// typesettingVisible.value = false
// try {
// if ((typeArr as string[]).length > 1) {
// typeArr?.forEach(async (el) => {
// const res = await composingDesignImages([row.id], el, templateWidth)
// const url =
// type === 'tiff'
// ? `https://ps.jomalls.com/tiff/` + res.message
// : filePath + res.message
// if (el === 'tiff') {
// window.open(url, '_blank')
// } else {
// fetch(url)
// .then((response) => {
// // 确保响应是 OK
// if (!response.ok) {
// throw new Error('网络响应错误')
// }
// // 返回图片的二进制数据(Blob)
// return response.blob()
// })
// .then((blob) => {
// const a = document.createElement('a')
// a.href = window.URL.createObjectURL(blob)
// a.target = '_blank'
// a.download = (res.message as string).split('/')[
// (res.message as string).split('/').length - 1
// ]
// a.click()
// pngDownloadLoading.value = false
// })
// .catch((error) => {
// console.error('下载图片时出错:', error)
// pngDownloadLoading.value = false
// })
// }
// })
// } else {
// const res = await composingDesignImages([row.id], type, templateWidth)
// const url =
// type === 'tiff'
// ? `https://ps.jomalls.com/tiff/` + res.message
// : filePath + res.message
// if (type === 'tiff') {
// window.open(url, '_blank')
// } else {
// fetch(url)
// .then((response) => {
// // 确保响应是 OK
// if (!response.ok) {
// throw new Error('网络响应错误')
// }
// // 返回图片的二进制数据(Blob)
// return response.blob()
// })
// .then((blob) => {
// const a = document.createElement('a')
// a.href = window.URL.createObjectURL(blob)
// a.target = '_blank'
// a.download = (res.message as string).split('/')[
// (res.message as string).split('/').length - 1
// ]
// a.click()
// pngDownloadLoading.value = false
// })
// .catch((error) => {
// console.error('下载图片时出错:', error)
// pngDownloadLoading.value = false
// })
// }
// }
// } catch (e) {
// console.log(e)
// } finally {
// typesettingRow.value = undefined
// loading.close()
// }
// }
const loadProductionClient = async () => {
try {
const res = await getProductionClientApi()
......@@ -5431,44 +5330,68 @@ const showArrange = async (type: number, data?: PodUsOrderListData) => {
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
}
// 是否全是cb和g类
const allCBOrG = cardSelection.value.every(
(item) =>
item.productMark === 'custom_normal' || item.productMark === 'normal',
)
function hasDifferentCraftCodeWithSet(items: ProductList[]) {
if (items.length <= 1) return false
// 是否全是cp类
const allCP = cardSelection.value.every(
(item) =>
item.productMark !== 'custom_normal' && item.productMark !== 'normal',
)
const seen = new Set()
for (const item of items) {
if (seen.has(item.craftType)) {
if (seen.size > 1) return true
// cb和g类排单
if (allCBOrG) {
ElMessageBox.confirm('确认对所选择生产单进行排单?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
isAuto.value = false
submitTypesetting()
})
} else if (allCP) {
typesettingVisible.value = true
} else {
seen.add(item.craftType)
if (seen.size > 1) return true
// 不支持混排
await ElMessageBox.alert(
h('p', null, [
h('span', null, '无法排单。'),
h('br'),
h(
'span',
null,
'原因:你选择的生产单包含多种商品类型,排单不支持多种商品类型混排,请选择同一类型的商品对应的生产单后再试!',
),
]),
'提示',
{
confirmButtonText: '确定',
},
)
return
}
}
return false
}
// function hasDifferentCraftCodeWithSet(items: ProductList[]) {
// if (items.length <= 1) return false
// const seen = new Set()
// for (const item of items) {
// if (seen.has(item.craftType)) {
// if (seen.size > 1) return true
// } else {
// seen.add(item.craftType)
// if (seen.size > 1) return true
// }
// }
// return false
// }
const arrangeFinish = async () => {
const loading = ElLoading.service({
fullscreen: true,
......@@ -6665,6 +6588,12 @@ function getQuantityText(qty: number) {
if (!qty || qty <= 0) return ''
return Math.floor(qty) === 1 ? '单' : '多'
}
function getProductMarkt(productMark: string) {
if (!productMark) return ''
if (productMark === 'custom_normal') return 'CB'
if (productMark === 'normal') return 'G'
return ''
}
const dialogVisible = ref(false)
const dialogImageUrl = ref('')
......
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