Commit bc2d1dc3 by qinjianhui

feat: 质检

parent 8b7564ca
...@@ -49,6 +49,10 @@ img { ...@@ -49,6 +49,10 @@ img {
.flex-1 { .flex-1 {
flex: 1; flex: 1;
} }
.font-bold {
font-weight: bold;
}
.margin-top-10 { .margin-top-10 {
margin-top: 10px; margin-top: 10px;
} }
......
...@@ -58,6 +58,7 @@ export interface OrderData { ...@@ -58,6 +58,7 @@ export interface OrderData {
shipmentList?: string shipmentList?: string
sourceType?: string sourceType?: string
moreable?: boolean moreable?: boolean
} }
export interface ProductList { export interface ProductList {
id: number id: number
...@@ -81,6 +82,8 @@ export interface ProductList { ...@@ -81,6 +82,8 @@ export interface ProductList {
createTime?: string createTime?: string
updateTime?: string updateTime?: string
version?: string | number version?: string | number
passNum?: number
notPassNum?: number
} }
export interface MemoList { export interface MemoList {
...@@ -156,6 +159,8 @@ export interface DetailList { ...@@ -156,6 +159,8 @@ export interface DetailList {
notShipmentNum?: number notShipmentNum?: number
productName?: string productName?: string
facotoryNo?: string facotoryNo?: string
notPassNum?: number
passNum?: number
} }
export interface LogListData { export interface LogListData {
......
...@@ -44,13 +44,16 @@ ...@@ -44,13 +44,16 @@
<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 <span
v-if="item.shipmentNum === item.num" v-if="(item.shipmentNum || 0) - (item.notPassNum || 0) === item.num"
class="order-list-expand_item_value" class="order-list-expand_item_value"
> >
<el-tag effect="dark" type="success"> 已发货 </el-tag> <el-tag effect="dark" type="success"> 已发货 </el-tag>
</span> </span>
<span <span
v-if="item.num !== item.shipmentNum && item.shipmentNum !== 0" v-if="
item.num !== (item.shipmentNum || 0) - (item.notPassNum || 0) &&
(item.shipmentNum || 0) > 0
"
class="order-list-expand_item_value" class="order-list-expand_item_value"
> >
<el-tag effect="dark"> 部分发货 </el-tag> <el-tag effect="dark"> 部分发货 </el-tag>
...@@ -72,18 +75,36 @@ ...@@ -72,18 +75,36 @@
</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">{{ item.num || '--' }}</span> <span class="order-list-expand_item_value">{{ item.num || 0 }}</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.shipmentNum || '--' item.shipmentNum || 0
}}</span> }}</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.num || 0) - (item.shipmentNum || 0) (item.num || 0) - ((item.shipmentNum || 0) - (item.notPassNum || 0))
}}</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.shipmentNum || 0) - ((item.passNum || 0) + (item.notPassNum || 0))
}}</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.passNum || 0
}}</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.notPassNum || 0
}}</span> }}</span>
</div> </div>
<div class="order-list-expand_item_info_title"> <div class="order-list-expand_item_info_title">
......
...@@ -18,7 +18,11 @@ ...@@ -18,7 +18,11 @@
:key="i" :key="i"
class="send-order-prop-list" class="send-order-prop-list"
> >
<div v-for="pi in p" :key="pi.key" class="send-order-prop-item"> <div
v-for="(pi, index) in p"
:key="index"
class="send-order-prop-item"
>
{{ pi.label }}{{ val(od, pi.key) }} {{ pi.label }}{{ val(od, pi.key) }}
</div> </div>
</div> </div>
...@@ -42,7 +46,7 @@ ...@@ -42,7 +46,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { val } from '@/utils' import { val } from '@/utils'
import type { SendOrderData } from '@/types/api/order' import type { DetailList, SendOrderData } from '@/types/api/order'
import type { PropType } from 'vue' import type { PropType } from 'vue'
defineProps({ defineProps({
...@@ -60,12 +64,23 @@ const productProps = [ ...@@ -60,12 +64,23 @@ const productProps = [
], ],
[ [
{ label: '生产单号', key: 'subOrderNumber' }, { label: '生产单号', key: 'subOrderNumber' },
{ label: '工厂', key: 'facotoryNo' },
], ],
[ [
{ label: '生产数', key: 'productionNum' }, { label: '生产数', key: 'productionNum' },
{ label: '发货数', key: 'shipmentNum' }, { label: '发货数', key: 'shipmentNum' },
{ label: '未发数', key: 'notShipmentNum' }, {
label: '未发数',
key: (data: DetailList) =>
(data.productionNum || 0) -
((data.shipmentNum || 0) - (data.notPassNum || 0)),
},
{
label: '待质检',
key: (data: DetailList) =>
(data.shipmentNum || 0) - ((data.passNum || 0) + (data.notPassNum || 0)),
},
{ label: '质检(通过)', key: 'passNum' },
{ label: '质检(不通过)', key: 'notPassNum' },
], ],
] ]
......
<template> <template>
<div v-if="orderList.length" class="shipment-info" > <div v-if="orderList.length" class="shipment-order">
<div ref="shipmentOrderRef" class="shipment-info">
<div v-for="o in orderList" :key="o.id" class="shipment-info-item"> <div v-for="o in orderList" :key="o.id" class="shipment-info-item">
<div class="shipment-info-item-header"> <div class="shipment-info-item-header">
<div class="shipment-info-item-header--title"> <div class="shipment-info-item-header--title">
...@@ -25,8 +26,12 @@ ...@@ -25,8 +26,12 @@
<div <div
v-for="item in o.productList" v-for="item in o.productList"
:key="item.id" :key="item.id"
:class="{ 'active-row': item.subOrderNumber === orderNumber }" :data-id="item.id"
:class="{
'active-row': item.subOrderNumber === currentRow.subOrderNumber,
}"
class="shipment-info-item-content-item" class="shipment-info-item-content-item"
@click="onRowClick(item)"
> >
<div class="image"> <div class="image">
<img :src="item.variantImage" /> <img :src="item.variantImage" />
...@@ -44,21 +49,24 @@ ...@@ -44,21 +49,24 @@
style="width: 90px; flex: none" style="width: 90px; flex: none"
> >
<span class="label">购买数:</span> <span class="label">购买数:</span>
<span class="value">{{ item.num || '--' }}</span> <span class="value">{{ item.num || 0 }}</span>
</div> </div>
<div <div
class="shipment-info-item-content-item--info" class="shipment-info-item-content-item--info"
style="width: 90px; flex: none" style="width: 90px; flex: none"
> >
<span class="label">已发数:</span> <span class="label">已发数:</span>
<span class="value">{{ item.shipmentNum || '--' }}</span> <span class="value">{{ item.shipmentNum || 0 }}</span>
</div> </div>
<div <div
class="shipment-info-item-content-item--info" class="shipment-info-item-content-item--info"
style="width: 90px; flex: none" style="width: 90px; flex: none"
> >
<span class="label">未发数:</span> <span class="label">未发数:</span>
<span class="value">{{ (item.num || 0) - (item.shipmentNum || 0) }}</span> <span class="value">{{
(item.num || 0) -
((item.shipmentNum || 0) - (item.notPassNum || 0))
}}</span>
</div> </div>
<div <div
class="shipment-info-item-content-item--info" class="shipment-info-item-content-item--info"
...@@ -70,32 +78,90 @@ ...@@ -70,32 +78,90 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<ElEmpty v-else class="shipment-info"></ElEmpty> <div class="shipment-order-detail_info">
<div class="shipment-order-detail_info_image">
<img :src="currentRow.variantImage" style="width: 100%" />
</div>
<div class="shipment-order-detail_info_other">
<div class="order-norm">
<span class="order-norm-label" style="margin-right: 6px">
规格:
</span>
<span class="order-norm-value" :title="currentRow.variantSku">
{{ currentRow.variantSku }}
</span>
</div>
<div class="order-count" style="line-height: 26px">
<span class="order-count-label" style="margin-right: 6px">
拣货数:
</span>
<span
class="order-count-value"
style="font-size: 16px; font-weight: bold; color: red"
>
{{ currentRow.count }}
</span>
</div>
</div>
</div>
</div>
<ElEmpty v-else class="shipment-order"></ElEmpty>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { OrderData } from '@/types/api/order'; import { OrderData, ProductList } from '@/types/api/order'
import { PropType } from 'vue'; import { PropType } from 'vue'
import useShipment from './hook/useShipment'
const emit = defineEmits<{
(e: 'changeCurrentRow', v: ProductList): void
}>()
defineProps({ defineProps({
orderList: { orderList: {
type: Array as PropType<OrderData[]>, type: Array as PropType<OrderData[]>,
default: () => [], default: () => [],
}, },
orderNumber: { currentRow: {
type: String, type: Object as PropType<ProductList>,
default: () => '', default: () => {},
}, },
}) })
const { shipmentOrderRef } = useShipment()
const onRowClick = (item: ProductList) => {
emit('changeCurrentRow', item)
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.shipment-info { .shipment-order {
height: 600px; overflow: hidden;
margin-top: 20px; margin-top: 20px;
height: 600px;
display: flex;
gap: 10px;
}
.shipment-info {
width: 50%;
border: 1px solid #eee; border: 1px solid #eee;
overflow: auto; overflow: auto;
font-size: 13px;
}
.shipment-order-detail_info {
width: 50%;
display: flex;
gap: 6px;
}
.shipment-order-detail_info_image {
flex: 1;
overflow: hidden;
border: 1px solid #eee;
}
.shipment-order-detail_info_other {
width: 200px;
} }
.image { .image {
...@@ -114,7 +180,6 @@ defineProps({ ...@@ -114,7 +180,6 @@ defineProps({
padding: 10px; padding: 10px;
} }
.shipment-info-item-content-item { .shipment-info-item-content-item {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
......
import { getOrderBySubOrderNumber, saveOrder } from '@/api/order' import { getOrderBySubOrderNumber, saveOrder } from '@/api/order'
import { OrderData, ShipmentForm, ShipmentOrderRes } from '@/types/api/order' import {
OrderData,
ProductList,
ShipmentForm,
ShipmentOrderRes,
} from '@/types/api/order'
import { useValue } from '@/utils/hooks/useValue' import { useValue } from '@/utils/hooks/useValue'
import { showError } from '@/utils/ui' import { showError } from '@/utils/ui'
import { ref } from 'vue' import { ref } from 'vue'
...@@ -17,8 +22,9 @@ export default function useShipment(callback?: () => void) { ...@@ -17,8 +22,9 @@ export default function useShipment(callback?: () => void) {
const shipmentVisible = ref(false) const shipmentVisible = ref(false)
const isLock = ref(false) const isLock = ref(false)
const inputRef = ref() const inputRef = ref()
const orderNumber = ref('') const currentRow = ref<ProductList>()
const shipmentLoading = ref(false) const shipmentLoading = ref(false)
const shipmentOrderRef = ref()
const searchShipmentByOrderNumber = async () => { const searchShipmentByOrderNumber = async () => {
const code = productionOrderNumber.value const code = productionOrderNumber.value
shipmentVisible.value = true shipmentVisible.value = true
...@@ -37,12 +43,19 @@ export default function useShipment(callback?: () => void) { ...@@ -37,12 +43,19 @@ export default function useShipment(callback?: () => void) {
if (rowData) break if (rowData) break
} }
if (rowData) { if (rowData) {
orderNumber.value = code currentRow.value = rowData
const unShipmentNum = (rowData.num || 0) - (rowData.shipmentNum || 0) const unShipmentNum =
(rowData.num || 0) -
(rowData.shipmentNum || 0) +
(rowData.notPassNum || 0)
if (unShipmentNum > (rowData.count || 0)) { if (unShipmentNum > (rowData.count || 0)) {
rowData.count || rowData.count === 0 rowData.count = unShipmentNum
? (rowData.count += 1) if (+rowData.count > 1) {
: (rowData.count = 0) ElMessageBox.confirm(`该产品未发数为${rowData.count}件`, '重要提示', {
confirmButtonText: '确定',
type: 'warning',
}).catch(() => {})
}
} else { } else {
ElMessage({ ElMessage({
message: '拣货数不能大于未发数', message: '拣货数不能大于未发数',
...@@ -50,9 +63,18 @@ export default function useShipment(callback?: () => void) { ...@@ -50,9 +63,18 @@ export default function useShipment(callback?: () => void) {
offset: window.innerHeight / 2, offset: window.innerHeight / 2,
}) })
} }
inputRef.value.focus()
productionOrderNumber.value = '' productionOrderNumber.value = ''
isLock.value = false isLock.value = false
inputRef.value.focus()
if (shipmentOrderRef.value) {
const rowEl = shipmentOrderRef.value.querySelector(
`div[data-id="${rowData.id}"]`,
)
if (!rowEl) return
rowEl.scrollIntoView()
}
} else { } else {
getPackingData(code) getPackingData(code)
} }
...@@ -63,13 +85,30 @@ export default function useShipment(callback?: () => void) { ...@@ -63,13 +85,30 @@ export default function useShipment(callback?: () => void) {
const res = await getOrderBySubOrderNumber(code) const res = await getOrderBySubOrderNumber(code)
if (res.data) { if (res.data) {
for (const item of res.data.productList || []) { for (const item of res.data.productList || []) {
if (item.num) {
item.count = 0 item.count = 0
}
if (item.subOrderNumber === code) { if (item.subOrderNumber === code) {
item.count || item.count === 0 item.count =
? (item.count += 1) (item.num || 0) -
: (item.count = 0) ((item.shipmentNum || 0) - (item.notPassNum || 0))
if (+item.count > 1) {
ElMessageBox.confirm(
`该产品未发数为${item.count}件`,
'重要提示',
{
confirmButtonText: '确定',
type: 'warning',
},
).catch(() => {})
}
currentRow.value = item
if (shipmentOrderRef.value) {
const rowEl = shipmentOrderRef.value.querySelector(
`div[data-id="${item.id}"]`,
)
if (!rowEl) return
rowEl.scrollIntoView()
}
} }
} }
const index = orderList.value.findIndex( const index = orderList.value.findIndex(
...@@ -79,10 +118,9 @@ export default function useShipment(callback?: () => void) { ...@@ -79,10 +118,9 @@ export default function useShipment(callback?: () => void) {
orderList.value.unshift(res.data) orderList.value.unshift(res.data)
} }
} }
orderNumber.value = code inputRef.value.focus()
productionOrderNumber.value = '' productionOrderNumber.value = ''
isLock.value = false isLock.value = false
inputRef.value.focus()
} catch (e) { } catch (e) {
productionOrderNumber.value = '' productionOrderNumber.value = ''
isLock.value = false isLock.value = false
...@@ -127,7 +165,7 @@ export default function useShipment(callback?: () => void) { ...@@ -127,7 +165,7 @@ export default function useShipment(callback?: () => void) {
erpSubOrderNumber: jj.erpSubOrderNumber, erpSubOrderNumber: jj.erpSubOrderNumber,
subOrderNumber: jj.subOrderNumber, subOrderNumber: jj.subOrderNumber,
sendOutQuantity: jj.count, sendOutQuantity: jj.count,
version: jj.version version: jj.version,
} }
order.push(subOrder) order.push(subOrder)
} }
...@@ -156,16 +194,17 @@ export default function useShipment(callback?: () => void) { ...@@ -156,16 +194,17 @@ export default function useShipment(callback?: () => void) {
} }
return { return {
shipmentFormRef, shipmentFormRef,
shipmentOrderRef,
productionOrderNumber, productionOrderNumber,
shipmentVisible, shipmentVisible,
inputRef, inputRef,
shipmentForm, shipmentForm,
orderNumber, currentRow,
shipmentLoading, shipmentLoading,
orderList, orderList,
searchShipmentByOrderNumber, searchShipmentByOrderNumber,
saveShipment, saveShipment,
confirmDelivery, confirmDelivery,
onShipmentDialogOpened onShipmentDialogOpened,
} }
} }
...@@ -43,10 +43,10 @@ ...@@ -43,10 +43,10 @@
style="width: 160px" style="width: 160px"
></ElInput> ></ElInput>
</ElFormItem> </ElFormItem>
<ElFormItem label="内部便签"> <ElFormItem label="内部签">
<ElInput <ElInput
v-model="searchForm.internalMemo" v-model="searchForm.internalMemo"
placeholder="内部便签" placeholder="内部签"
clearable clearable
style="width: 160px" style="width: 160px"
></ElInput> ></ElInput>
...@@ -80,24 +80,25 @@ ...@@ -80,24 +80,25 @@
<span v-if="statusCode === 2" class="item"> <span v-if="statusCode === 2" class="item">
<ElButton type="success" @click="confirmProduce">确认生产</ElButton> <ElButton type="success" @click="confirmProduce">确认生产</ElButton>
</span> </span>
<span v-if="statusCode === 3 || statusCode === 4" class="item">
<ElButton type="success" @click="confirmDelivery">发货</ElButton> <span v-if="statusCode === 2 || statusCode === 3" class="item">
</span>
<span class="item">
<ElButton type="warning" is-dark @click="downloadManuscript" <ElButton type="warning" is-dark @click="downloadManuscript"
>下载稿件</ElButton >下载稿件</ElButton
> >
</span> </span>
<span class="item"> <span v-if="statusCode === 2 || statusCode === 3" class="item">
<ElButton type="primary" dark @click="printManuscript" <ElButton type="primary" dark @click="printManuscript"
>打印生产单</ElButton >打印生产单</ElButton
> >
</span> </span>
<span class="item"> <span class="item">
<ElButton type="success" @click="addInternalTag" <ElButton type="warning" @click="addInternalTag"
>添加内部标签</ElButton >添加内部标签</ElButton
> >
</span> </span>
<span v-if="statusCode === 3 || statusCode === 4" class="item">
<ElButton type="success" @click="confirmDelivery">发货</ElButton>
</span>
</div> </div>
<div <div
ref="tableWrapperRef" ref="tableWrapperRef"
...@@ -227,7 +228,7 @@ ...@@ -227,7 +228,7 @@
> >
</div> </div>
<div <div
v-if="statusCode == 4 || statusCode == 5" v-if="statusCode !== 2 && statusCode !== 3"
class="order-list-expand_item_info_title" class="order-list-expand_item_info_title"
> >
<ElButton <ElButton
...@@ -300,7 +301,7 @@ ...@@ -300,7 +301,7 @@
header-align="center" header-align="center"
></ElTableColumn> ></ElTableColumn>
<ElTableColumn <ElTableColumn
label="内部便签" label="内部签"
width="350" width="350"
header-align="center" header-align="center"
></ElTableColumn> ></ElTableColumn>
...@@ -330,7 +331,8 @@ ...@@ -330,7 +331,8 @@
v-model="shipmentVisible" v-model="shipmentVisible"
title="发货" title="发货"
:close-on-click-modal="false" :close-on-click-modal="false"
width="1300px" width="1600px"
top="6vh"
@opened="onShipmentDialogOpened" @opened="onShipmentDialogOpened"
> >
<div class="header-search"> <div class="header-search">
...@@ -339,7 +341,7 @@ ...@@ -339,7 +341,7 @@
v-model="productionOrderNumber" v-model="productionOrderNumber"
clearable clearable
size="large" size="large"
placeholder="这里是扫码输入框" placeholder="请输入生产单号"
@keyup.enter="searchShipmentByOrderNumber" @keyup.enter="searchShipmentByOrderNumber"
/> />
<el-button <el-button
...@@ -352,7 +354,8 @@ ...@@ -352,7 +354,8 @@
<Shipment <Shipment
v-loading="shipmentLoading" v-loading="shipmentLoading"
:order-list="orderList" :order-list="orderList"
:order-number="orderNumber" :current-row="currentRow"
@change-current-row="onChangeCurrentRow"
/> />
<div class="shipment-logistics-info margin-top-20"> <div class="shipment-logistics-info margin-top-20">
<ElForm ref="shipmentFormRef" :model="shipmentForm" :rules="rules"> <ElForm ref="shipmentFormRef" :model="shipmentForm" :rules="rules">
...@@ -459,6 +462,7 @@ import type { ...@@ -459,6 +462,7 @@ import type {
LogisticsData, LogisticsData,
SendOrderData, SendOrderData,
LogListData, LogListData,
ProductList,
} from '@/types/api/order' } from '@/types/api/order'
import { onMounted, reactive, ref } from 'vue' import { onMounted, reactive, ref } from 'vue'
import useElTableColumnWidth from '@/utils/hooks/useElTableColumnWidth' import useElTableColumnWidth from '@/utils/hooks/useElTableColumnWidth'
...@@ -492,7 +496,7 @@ const [searchForm, resetSearchForm] = useValue<SearchForm>({ ...@@ -492,7 +496,7 @@ const [searchForm, resetSearchForm] = useValue<SearchForm>({
shopNumber: '', shopNumber: '',
internalMemo: '', internalMemo: '',
erpOrderNumber: '', erpOrderNumber: '',
subOrderNumber: '' subOrderNumber: '',
}) })
const tabsNav = ref<Tab[]>([]) const tabsNav = ref<Tab[]>([])
...@@ -554,7 +558,7 @@ const { ...@@ -554,7 +558,7 @@ const {
shipmentVisible, shipmentVisible,
inputRef, inputRef,
shipmentForm, shipmentForm,
orderNumber, currentRow,
shipmentLoading, shipmentLoading,
orderList, orderList,
searchShipmentByOrderNumber, searchShipmentByOrderNumber,
...@@ -771,6 +775,10 @@ const cancelOrder = async (id: number) => { ...@@ -771,6 +775,10 @@ const cancelOrder = async (id: number) => {
showError(e) showError(e)
} }
} }
const onChangeCurrentRow = (item: ProductList) => {
currentRow.value = item
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.header-filter-form { .header-filter-form {
...@@ -780,7 +788,7 @@ const cancelOrder = async (id: number) => { ...@@ -780,7 +788,7 @@ const cancelOrder = async (id: number) => {
} }
} }
.header-filter-tab { .header-filter-tab {
margin-top: 20px; margin-top: 10px;
} }
.tabs { .tabs {
...@@ -810,11 +818,11 @@ const cancelOrder = async (id: number) => { ...@@ -810,11 +818,11 @@ const cancelOrder = async (id: number) => {
} }
.order-content { .order-content {
margin-top: 20px; margin-top: 10px;
} }
.order-list { .order-list {
margin-top: 20px; margin-top: 10px;
flex: 1; flex: 1;
:deep(.el-table__expand-icon > .el-icon) { :deep(.el-table__expand-icon > .el-icon) {
display: none; display: none;
......
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