Commit 489f08f1 by qinjianhui

feat: 质检功能

parent e51ef8ae
...@@ -3,11 +3,13 @@ import axios from './axios' ...@@ -3,11 +3,13 @@ import axios from './axios'
import { import {
LogListData, LogListData,
OrderData, OrderData,
QaData,
SearchForm, SearchForm,
SendOrderData, SendOrderData,
ShipmentForm, ShipmentForm,
ShipmentOrderRes, ShipmentOrderRes,
Tab, Tab,
InspectionData
} from '@/types/api/order' } from '@/types/api/order'
export function getOrderList( export function getOrderList(
...@@ -58,14 +60,14 @@ export function printOrder(ids: number[]) { ...@@ -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>>( return axios.get<never, BaseRespData<never>>(
'factory/customJomallOrder/exportData', 'factory/customJomallOrder/exportData',
{ {
params:{ params: {
status status,
} },
} },
) )
} }
...@@ -80,6 +82,23 @@ export function getOrderBySubOrderNumber(orderNumber: string) { ...@@ -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( export function saveOrder(
...@@ -145,6 +164,6 @@ export function cancelOrderApi(id: number) { ...@@ -145,6 +164,6 @@ export function cancelOrderApi(id: number) {
export function refreshProductInfo(data: number[]) { export function refreshProductInfo(data: number[]) {
return axios.post<never, BaseRespData<never>>( return axios.post<never, BaseRespData<never>>(
'factory/customJomallOrder/refreshProductInfo', 'factory/customJomallOrder/refreshProductInfo',
data, data,
) )
} }
...@@ -65,7 +65,6 @@ img { ...@@ -65,7 +65,6 @@ img {
margin-right: 6px; margin-right: 6px;
} }
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 5px; width: 5px;
height: 5px; height: 5px;
...@@ -86,3 +85,9 @@ img { ...@@ -86,3 +85,9 @@ img {
outline: none; outline: none;
background-color: rgba(0, 0, 0, 0); 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 { ...@@ -16,8 +16,6 @@ export interface Tab {
quantity: number quantity: number
} }
export interface OrderData { export interface OrderData {
id: number id: number
namespace?: string namespace?: string
...@@ -61,7 +59,6 @@ export interface OrderData { ...@@ -61,7 +59,6 @@ export interface OrderData {
sourceType?: string sourceType?: string
moreable?: boolean moreable?: boolean
manuscriptStatus?: number manuscriptStatus?: number
} }
export interface ProductList { export interface ProductList {
id: number id: number
...@@ -174,3 +171,42 @@ export interface LogListData { ...@@ -174,3 +171,42 @@ export interface LogListData {
description?: string description?: string
createTime?: 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) { ...@@ -14,7 +14,9 @@ export function showError(err: unknown, options?: ElMessageBoxOptions) {
if (!message) return if (!message) return
return ElMessageBox.alert( 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', type: 'error',
......
...@@ -19,27 +19,38 @@ ...@@ -19,27 +19,38 @@
</div> </div>
<div class="order-list-expand_item_info_title"> <div class="order-list-expand_item_info_title">
<span class="order-list-expand_item_label">Base SKU:</span> <span class="order-list-expand_item_label">Base SKU:</span>
<span class="order-list-expand_item_value">{{ <span class="order-list-expand_item_value"
item.baseSku || '--' >{{ item.baseSku || '--'
}}</span> }}<el-icon class="icon" @click="copy(item.baseSku || '')"
><DocumentCopy /></el-icon
></span>
</div> </div>
<div class="order-list-expand_item_info_title"> <div class="order-list-expand_item_info_title">
<span class="order-list-expand_item_label">Variant SKU:</span> <span class="order-list-expand_item_label">Variant SKU:</span>
<span class="order-list-expand_item_value">{{ <span class="order-list-expand_item_value"
item.variantSku || '--' >{{ item.variantSku || '--' }}
}}</span> <el-icon class="icon" @click="copy(item.variantSku || '')"
><DocumentCopy
/></el-icon>
</span>
</div> </div>
<div class="order-list-expand_item_info_title"> <div class="order-list-expand_item_info_title">
<span class="order-list-expand_item_label">店铺单号:</span> <span class="order-list-expand_item_label">店铺单号:</span>
<span class="order-list-expand_item_value">{{ <span class="order-list-expand_item_value"
item.shopNumber || '--' >{{ item.shopNumber || '--' }}
}}</span> <el-icon class="icon" @click="copy(item.shopNumber || '')"
><DocumentCopy
/></el-icon>
</span>
</div> </div>
<div class="order-list-expand_item_info_title"> <div class="order-list-expand_item_info_title">
<span class="order-list-expand_item_label">生产单号:</span> <span class="order-list-expand_item_label">生产单号:</span>
<span class="order-list-expand_item_value">{{ <span class="order-list-expand_item_value"
item.subOrderNumber || '--' >{{ item.subOrderNumber || '--'
}}</span> }}<el-icon class="icon" @click="copy(item.subOrderNumber || '')"
><DocumentCopy
/></el-icon>
</span>
</div> </div>
<div class="order-list-expand_item_info_title"> <div class="order-list-expand_item_info_title">
<span class="order-list-expand_item_label">发货状态:</span> <span class="order-list-expand_item_label">发货状态:</span>
...@@ -127,6 +138,7 @@ ...@@ -127,6 +138,7 @@
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { DocumentCopy } from '@element-plus/icons-vue'
import { filePath } from '@/api/axios' import { filePath } from '@/api/axios'
import { downloadOrder } from '@/api/order' import { downloadOrder } from '@/api/order'
import { OrderData, ProductList } from '@/types/api/order' import { OrderData, ProductList } from '@/types/api/order'
...@@ -154,6 +166,10 @@ const downloadManuscriptBySubOrder = async (item: ProductList) => { ...@@ -154,6 +166,10 @@ const downloadManuscriptBySubOrder = async (item: ProductList) => {
showError(e) showError(e)
} }
} }
const copy = (text: string) => {
navigator.clipboard.writeText(text)
ElMessage.success('复制成功')
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.order-list-expand_item { .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 @@ ...@@ -134,6 +134,9 @@
<span v-if="statusCode === 3 || statusCode === 4" class="item"> <span v-if="statusCode === 3 || statusCode === 4" class="item">
<ElButton type="success" @click="confirmDelivery">发货</ElButton> <ElButton type="success" @click="confirmDelivery">发货</ElButton>
</span> </span>
<span v-if="statusCode === 6" class="item">
<ElButton type="success" @click="confirmCheck">质检</ElButton>
</span>
</div> </div>
<div <div
ref="tableWrapperRef" ref="tableWrapperRef"
...@@ -483,6 +486,39 @@ ...@@ -483,6 +486,39 @@
> >
<LogList :log-list="logList" /> <LogList :log-list="logList" />
</el-dialog> </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 <ElDrawer
v-model="orderDetailDialogVisible" v-model="orderDetailDialogVisible"
title="生产订单详情" title="生产订单详情"
...@@ -534,6 +570,8 @@ import SendOrder from './SendOrder.vue' ...@@ -534,6 +570,8 @@ import SendOrder from './SendOrder.vue'
import LogList from '@/components/LogList.vue' import LogList from '@/components/LogList.vue'
import OrderDetail from './OrderDetail.vue' import OrderDetail from './OrderDetail.vue'
import useShipment from './hook/useShipment' import useShipment from './hook/useShipment'
import useQuarantine from './hook/useQuarantine'
import Quarantine from './Quarantine.vue'
const [searchForm, resetSearchForm] = useValue<SearchForm>({ const [searchForm, resetSearchForm] = useValue<SearchForm>({
mainSku: '', mainSku: '',
...@@ -614,10 +652,26 @@ const { ...@@ -614,10 +652,26 @@ const {
loadTabData() loadTabData()
search() search()
}) })
const quarantine = useQuarantine()
// 质检
const {
quarantineVisible,
qaInputRef,
qaCode,
searchQaByOrderNumber,
saveQuarantine,
confirmCheck,
onQaDialogOpened,
} = quarantine
onMounted(() => { onMounted(() => {
loadTabData() loadTabData()
getLogisticsList() getLogisticsList()
}) })
const onClose = () => {
loadTabData()
search()
}
// 获取物流公司 // 获取物流公司
const getLogisticsList = async () => { const getLogisticsList = async () => {
try { 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