Commit 489f08f1 by qinjianhui

feat: 质检功能

parent e51ef8ae
......@@ -3,11 +3,13 @@ import axios from './axios'
import {
LogListData,
OrderData,
QaData,
SearchForm,
SendOrderData,
ShipmentForm,
ShipmentOrderRes,
Tab,
InspectionData
} from '@/types/api/order'
export function getOrderList(
......@@ -58,14 +60,14 @@ export function printOrder(ids: number[]) {
}
// 导出生产单
export function exportOrder(status?:string | number) {
export function exportOrder(status?: string | number) {
return axios.get<never, BaseRespData<never>>(
'factory/customJomallOrder/exportData',
{
params:{
status
}
}
params: {
status,
},
},
)
}
......@@ -80,6 +82,23 @@ export function getOrderBySubOrderNumber(orderNumber: string) {
},
)
}
export function getQaOrderBySubOrderNumber(orderNumber: string) {
return axios.get<never, BaseRespData<QaData[]>>(
'factory/customJomallOrder/inspectionQuery',
{
params: {
subOrderNumber: orderNumber,
},
},
)
}
// 质检完成
export function qaFinishedApi(data:InspectionData[]) {
return axios.post<never, BaseRespData<never>>(
'factory/customJomallOrder/inspection',
data
)
}
// 发货保存
export function saveOrder(
......@@ -145,6 +164,6 @@ export function cancelOrderApi(id: number) {
export function refreshProductInfo(data: number[]) {
return axios.post<never, BaseRespData<never>>(
'factory/customJomallOrder/refreshProductInfo',
data,
data,
)
}
......@@ -65,7 +65,6 @@ img {
margin-right: 6px;
}
::-webkit-scrollbar {
width: 5px;
height: 5px;
......@@ -86,3 +85,9 @@ img {
outline: none;
background-color: rgba(0, 0, 0, 0);
}
.icon {
vertical-align: middle;
margin-left: 5px;
font-size: 16px;
cursor: pointer;
}
......@@ -16,8 +16,6 @@ export interface Tab {
quantity: number
}
export interface OrderData {
id: number
namespace?: string
......@@ -61,7 +59,6 @@ export interface OrderData {
sourceType?: string
moreable?: boolean
manuscriptStatus?: number
}
export interface ProductList {
id: number
......@@ -174,3 +171,42 @@ export interface LogListData {
description?: string
createTime?: string
}
export interface QaData {
orderNumber?: string
namespace?: string
billNumber?: string
subOrderNumber?: string
baseSku?: string
variantSku?: string
variantImage?: string
num?: number
shipmentNum?: number
productName?: string
logisticsTracking?: string
lanshouName?: string
lanshouPhone?: string
lanshouRegion?: string
lanshouAddress?: string
lanshouPost?: string
passNum?: number
notPassNum?: number
version?: number
factorySubOrderNumber?: string
shippingWay?: string
inspectionStatus?: boolean
source?: string
sourceType?: string
isCheck?: boolean
erpSubOrderNumber?: string
}
export interface InspectionData {
notPassCount: number | string
subOrderNumber: string
namespace: string
erpSubOrderNumber: string
billNumber: string
version: number | string
passCount: number | string
}
......@@ -14,7 +14,9 @@ export function showError(err: unknown, options?: ElMessageBoxOptions) {
if (!message) return
return ElMessageBox.alert(
'<div style="max-height:500px;overflow:auto">' + message + '</div>',
'<div style="max-height:500px;overflow:auto;overflow-wrap:break-word;max-width:360px;">' +
message +
'</div>',
'错误提示',
{
type: 'error',
......
......@@ -19,27 +19,38 @@
</div>
<div class="order-list-expand_item_info_title">
<span class="order-list-expand_item_label">Base SKU:</span>
<span class="order-list-expand_item_value">{{
item.baseSku || '--'
}}</span>
<span class="order-list-expand_item_value"
>{{ item.baseSku || '--'
}}<el-icon class="icon" @click="copy(item.baseSku || '')"
><DocumentCopy /></el-icon
></span>
</div>
<div class="order-list-expand_item_info_title">
<span class="order-list-expand_item_label">Variant SKU:</span>
<span class="order-list-expand_item_value">{{
item.variantSku || '--'
}}</span>
<span class="order-list-expand_item_value"
>{{ item.variantSku || '--' }}
<el-icon class="icon" @click="copy(item.variantSku || '')"
><DocumentCopy
/></el-icon>
</span>
</div>
<div class="order-list-expand_item_info_title">
<span class="order-list-expand_item_label">店铺单号:</span>
<span class="order-list-expand_item_value">{{
item.shopNumber || '--'
}}</span>
<span class="order-list-expand_item_value"
>{{ item.shopNumber || '--' }}
<el-icon class="icon" @click="copy(item.shopNumber || '')"
><DocumentCopy
/></el-icon>
</span>
</div>
<div class="order-list-expand_item_info_title">
<span class="order-list-expand_item_label">生产单号:</span>
<span class="order-list-expand_item_value">{{
item.subOrderNumber || '--'
}}</span>
<span class="order-list-expand_item_value"
>{{ item.subOrderNumber || '--'
}}<el-icon class="icon" @click="copy(item.subOrderNumber || '')"
><DocumentCopy
/></el-icon>
</span>
</div>
<div class="order-list-expand_item_info_title">
<span class="order-list-expand_item_label">发货状态:</span>
......@@ -127,6 +138,7 @@
</div>
</template>
<script setup lang="ts">
import { DocumentCopy } from '@element-plus/icons-vue'
import { filePath } from '@/api/axios'
import { downloadOrder } from '@/api/order'
import { OrderData, ProductList } from '@/types/api/order'
......@@ -154,6 +166,10 @@ const downloadManuscriptBySubOrder = async (item: ProductList) => {
showError(e)
}
}
const copy = (text: string) => {
navigator.clipboard.writeText(text)
ElMessage.success('复制成功')
}
</script>
<style lang="scss" scoped>
.order-list-expand_item {
......
import { getQaOrderBySubOrderNumber, qaFinishedApi } from '@/api/order'
import { InspectionData, QaData } from '@/types/api/order'
import { useValue } from '@/utils/hooks/useValue'
import { showConfirm, showError } from '@/utils/ui'
import { computed, ref } from 'vue'
export default function useQuarantine() {
const [sourceData, resetOrderList] = useValue<QaData[]>([])
const [currentRow, resetCurrentRow] = useValue<QaData>({})
const quarantineVisible = ref(false)
const qaCode = ref('')
const qaInputRef = ref()
const isLock = ref(false)
const cloneRow = ref<QaData>({} as QaData)
const activeTab = ref('all')
const _sourceData = ref<QaData[]>([] as QaData[])
const allTotal = ref(0)
const dzjTotal = ref(0)
const yzjTotal = ref(0)
const confirmCheck = () => {
quarantineVisible.value = true
resetOrderList()
resetCurrentRow()
dzjTotal.value = 0
yzjTotal.value = 0
allTotal.value = 0
}
const isQaed = computed(() => {
if (sourceData.value.length == 0) return false
return sourceData.value.some((item) => item.isCheck)
})
const searchQaByOrderNumber = () => {
const code = qaCode.value
if (!code) {
isLock.value = false
return ElMessage({
message: '请录入质检单号',
type: 'warning',
offset: window.innerHeight / 2,
})
}
if (isLock.value) {
qaInputRef.value.focus()
qaCode.value = ''
return
}
isLock.value = true
const code1 = code?.split('_')[0]
// 如果扫单号没有包含当前的生产单号
const isIncluned = sourceData.value.some(
(item) =>
item.factorySubOrderNumber == code1 || item.subOrderNumber == code1,
)
if (isQaed.value && !isIncluned) {
saveQuarantine(() => {
loadShipmentOrderByCode(code)
})
} else {
// 如果质检未完成
// 查找是否已经存在
const row = sourceData.value.find(
(item) =>
item.factorySubOrderNumber == code1 || item.subOrderNumber == code1,
)
if (row) {
// 质检数量不能大于发货数量
const num = (row.passNum || 0) + (row.notPassNum || 0)
if (num > (row.shipmentNum || 0)) {
qaInputRef.value.focus()
isLock.value = false
qaCode.value = ''
return ElMessage({
message: '质检数量不能大于发货数量',
type: 'warning',
offset: window.innerHeight / 2,
})
}
// row.passNum = row.shipmentNum
qaInputRef.value.focus()
currentRow.value = row
cloneRow.value = JSON.parse(JSON.stringify(currentRow.value))
isLock.value = false
qaCode.value = ''
} else {
loadShipmentOrderByCode(code)
}
}
}
const loadShipmentOrderByCode = async (code: string) => {
try {
const res = await getQaOrderBySubOrderNumber(code)
const code1 = code?.split('_')[0]
res.data.forEach((el) => {
el.isCheck = el.inspectionStatus
})
activeTab.value = 'all'
sourceData.value = res.data
_sourceData.value = res.data
allTotal.value = _sourceData.value.length
dzjTotal.value = res.data.filter(
(e) =>
Number(e.shipmentNum || 0) !==
Number(e.passNum || 0) + Number(e.notPassNum || 0),
).length
yzjTotal.value = res.data.filter(
(e) =>
Number(e.shipmentNum || 0) ===
Number(e.passNum || 0) + Number(e.notPassNum || 0),
).length
const row = sourceData.value.find(
(item) =>
item.factorySubOrderNumber == code1 || item.subOrderNumber == code1,
)
if (row) {
// row.passNum += 1
currentRow.value = row
cloneRow.value = JSON.parse(JSON.stringify(currentRow.value))
}
qaInputRef.value.focus()
isLock.value = false
qaCode.value = ''
} catch (e) {
qaInputRef.value.focus()
isLock.value = false
qaCode.value = ''
showError(e)
}
}
// 质检完成
const saveQuarantine = async (callback?: () => void) => {
try {
const data: InspectionData[] = _sourceData.value
.filter((e) => e.isCheck)
.map((item) => ({
notPassCount: item.notPassNum || 0,
subOrderNumber: item.subOrderNumber || '',
namespace: item.namespace || '',
erpSubOrderNumber: item.erpSubOrderNumber || '',
billNumber: item.billNumber || '',
version: item.version || '',
passCount: item.passNum || 0,
}))
await qaFinishedApi(data)
sourceData.value = []
isLock.value = false
qaInputRef.value.focus()
qaCode.value = ''
currentRow.value = {}
cloneRow.value = JSON.parse(JSON.stringify(currentRow.value))
allTotal.value = 0
yzjTotal.value = 0
dzjTotal.value = 0
callback && callback()
} catch (e) {
showError(e)
}
}
const onQaDialogOpened = () => {
qaInputRef.value.focus()
}
const onChangeTab = (key: string) => {
activeTab.value = key
if (key == 'all') {
sourceData.value = _sourceData.value
} else if (key === 'dzj') {
sourceData.value = _sourceData.value.filter((item) => !item.isCheck)
} else if (key === 'yzj') {
sourceData.value = _sourceData.value.filter((item) => item.isCheck)
}
const row = sourceData.value.find(
(item) => item.subOrderNumber == cloneRow.value.subOrderNumber,
)
if (row) {
currentRow.value = row
} else {
currentRow.value = {}
}
}
const onRowClick = (row: QaData) => {
currentRow.value = row
cloneRow.value = JSON.parse(JSON.stringify(row))
}
const onSuccessQc = async () => {
if (
(currentRow.value.passNum || 0) + (currentRow.value.notPassNum || 0) >=
(currentRow.value.shipmentNum || 0)
) {
return ElMessage({
message: '已质检',
type: 'warning',
offset: window.innerHeight / 2,
})
}
try {
await showConfirm(`该产品${currentRow.value.shipmentNum}件`, {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
} catch {
return
}
currentRow.value.passNum = currentRow.value.shipmentNum
_sourceData.value.forEach((item) => {
if (item.subOrderNumber === currentRow.value.subOrderNumber) {
item.isCheck = true
}
})
sourceData.value = _sourceData.value
allTotal.value = _sourceData.value.length
dzjTotal.value = _sourceData.value.filter((item) => !item.isCheck).length
yzjTotal.value = allTotal.value - dzjTotal.value
qaInputRef.value.focus()
}
const onReissue = () => {
ElMessageBox.prompt('请输入重量', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputPattern: /\d+/,
inputErrorMessage: '请输入数字',
}).then(({ value }) => {
if (Number(value) > (currentRow.value.shipmentNum || 0)) {
return ElMessage({
message: '重发数量不能大于发货数量',
type: 'warning',
offset: window.innerHeight / 2,
})
}
currentRow.value.notPassNum = Number(value)
currentRow.value.passNum =
(currentRow.value.shipmentNum || 0) - Number(value)
_sourceData.value.forEach((item) => {
if (item.subOrderNumber === currentRow.value.subOrderNumber) {
item.isCheck = true
}
})
sourceData.value = _sourceData.value
allTotal.value = _sourceData.value.length
dzjTotal.value = _sourceData.value.filter((item) => !item.isCheck).length
yzjTotal.value = allTotal.value - dzjTotal.value
})
}
return {
quarantineVisible,
qaCode,
qaInputRef,
allTotal,
dzjTotal,
yzjTotal,
currentRow,
sourceData,
activeTab,
confirmCheck,
searchQaByOrderNumber,
saveQuarantine,
onQaDialogOpened,
onChangeTab,
onSuccessQc,
onReissue,
onRowClick,
}
}
......@@ -134,6 +134,9 @@
<span v-if="statusCode === 3 || statusCode === 4" class="item">
<ElButton type="success" @click="confirmDelivery">发货</ElButton>
</span>
<span v-if="statusCode === 6" class="item">
<ElButton type="success" @click="confirmCheck">质检</ElButton>
</span>
</div>
<div
ref="tableWrapperRef"
......@@ -483,6 +486,39 @@
>
<LogList :log-list="logList" />
</el-dialog>
<el-dialog
v-model="quarantineVisible"
title="质检"
width="1600px"
:close-on-click-modal="false"
@opened="onQaDialogOpened"
@close="onClose"
>
<div class="header-search">
<el-input
ref="qaInputRef"
v-model="qaCode"
clearable
size="large"
placeholder="请输入生产单号"
@keyup.enter="searchQaByOrderNumber"
/>
<el-button type="primary" size="large" @click="searchQaByOrderNumber"
>查询
</el-button>
</div>
<Quarantine :quarantine="quarantine" />
<template #footer>
<div class="dialog-footer">
<el-button size="large" @click="quarantineVisible = false"
>取消
</el-button>
<el-button size="large" type="primary" @click="() => saveQuarantine()"
>质检完成
</el-button>
</div>
</template>
</el-dialog>
<ElDrawer
v-model="orderDetailDialogVisible"
title="生产订单详情"
......@@ -534,6 +570,8 @@ import SendOrder from './SendOrder.vue'
import LogList from '@/components/LogList.vue'
import OrderDetail from './OrderDetail.vue'
import useShipment from './hook/useShipment'
import useQuarantine from './hook/useQuarantine'
import Quarantine from './Quarantine.vue'
const [searchForm, resetSearchForm] = useValue<SearchForm>({
mainSku: '',
......@@ -614,10 +652,26 @@ const {
loadTabData()
search()
})
const quarantine = useQuarantine()
// 质检
const {
quarantineVisible,
qaInputRef,
qaCode,
searchQaByOrderNumber,
saveQuarantine,
confirmCheck,
onQaDialogOpened,
} = quarantine
onMounted(() => {
loadTabData()
getLogisticsList()
})
const onClose = () => {
loadTabData()
search()
}
// 获取物流公司
const getLogisticsList = async () => {
try {
......
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