Commit 8eaf66bb by qinjianhui

Merge branch 'release' into dev

parents 7d5b27b1 0fdc9778
......@@ -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 }[]>>(
......
......@@ -246,9 +246,9 @@ export function productionQueryApi(id: number, podJomallOrderCnId: number) {
},
)
}
export function printProductionOrderApi(orderIds: number[]) {
export function printProductionOrderApi(url: string, orderIds: number[]) {
return axios.post<never, BaseRespData<string>>(
'factory/podJomallOrderProductCn/printProducePdf',
url,
orderIds,
)
}
......@@ -639,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 },
)
}
......@@ -791,3 +791,11 @@ export function updateProductOutOfStockApi(params: {
params,
)
}
// 打印普胚生产单
export function printNormalProducePdf(orderIds: number[]) {
return axios.post<never, BaseRespData<string>>(
'factory/podJomallOrderProductCn/printNormalProducePdf',
orderIds,
)
}
......@@ -179,9 +179,9 @@ export function productionQueryApi(id: number, podJomallOrderUsId: number) {
},
)
}
export function printProductionOrderApi(orderIds: number[]) {
export function printProductionOrderApi(url: string, orderIds: number[]) {
return axios.post<never, BaseRespData<string>>(
'factory/podJomallOrderProductUs/printProducePdf',
url,
orderIds,
)
}
......
......@@ -121,11 +121,7 @@
style="display: flex; margin-left: 10px"
>
<div class="text-green">
{{
statisticData?.compareYesterdayShipmentOrderNum.toFixed(
2,
)
}}
{{ statisticData?.compareYesterdayShipmentOrderNum }}
</div>
<div class="up-icon-green"></div>
</div>
......@@ -134,7 +130,7 @@
{{
Math.abs(
statisticData?.compareYesterdayShipmentOrderNum || 0,
).toFixed(2)
)
}}
</div>
<div class="down-icon-red"></div>
......
......@@ -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> {
......
<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>
......@@ -1984,7 +1984,7 @@
class="operate-box-vertical"
>
<el-link
:disabled="row.isUpload"
:disabled="row.isUpload || row.enableArrange === false"
underline="never"
type="success"
@click="uploadFile(row)"
......@@ -1998,7 +1998,7 @@
<Loading />
</el-icon>
<el-link
:disabled="!row.prnUrl"
:disabled="!row.prnUrl || row.enableArrange === false"
style="margin-left: 8px"
underline="never"
:title="fileName(row)"
......@@ -2052,7 +2052,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)"
......@@ -2065,7 +2067,7 @@
</span>
<span class="operate-item">
<ElButton
:disabled="row.productNum > 50"
:disabled="row.productNum > 50 || row.enableArrange === false"
link
title="重新排版"
type="warning"
......@@ -2337,6 +2339,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(
......@@ -3265,7 +3278,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'
......@@ -4825,37 +4838,6 @@ const assignOrder = async () => {
currentOrderIds.value = selection.value.map((item) => item.id)
exceptionDialogVisible.value = true
}
// const handleExceptionOrder = async () => {
// if (selection.value.length === 0) {
// return ElMessage.warning('请选择数据')
// }
// try {
// await showConfirm('确定处理异常吗?', {
// confirmButtonText: '确认',
// cancelButtonText: '取消',
// type: 'warning',
// })
// } catch {
// return
// }
// const orderIds = selection.value.map((item) => item.id)
// const loading = ElLoading.service({
// fullscreen: true,
// text: '操作中...',
// background: 'rgba(0, 0, 0, 0.3)',
// })
// try {
// const res = await handleExceptionOrderApi(orderIds)
// if (res.code !== 200) return
// ElMessage.success('操作成功')
// search()
// loadTabData()
// } catch (e) {
// console.error(e)
// } finally {
// loading.close()
// }
// }
const printProductionOrder = async (
type: 1 | 2,
item: PodUsOrderListData | null,
......@@ -4871,8 +4853,12 @@ const printProductionOrder = async (
text: '操作中...',
background: 'rgba(0, 0, 0, 0.3)',
})
const url =
status.value === 'TO_BE_REPLENISHMENT'
? 'factory/podJomallOrderProductUs/replenishmentPrintProducePdf'
: 'factory/podJomallOrderProductUs/printProducePdf'
try {
const res = await printProductionOrderApi(orderIds)
const res = await printProductionOrderApi(url, orderIds)
if (res.code !== 200) return
ElMessage.success('操作成功')
window.open(filePath + res.message)
......@@ -5318,44 +5304,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,
......@@ -6566,6 +6576,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