采购退货,入库单子显示货位;采购入库,增加拆分按钮

pull/744/head
ouhuangzhiguang 2025-03-20 17:28:49 +08:00
parent dddde5bdc6
commit 27611a4b01
2 changed files with 363 additions and 287 deletions

View File

@ -48,7 +48,6 @@
clearable
filterable
placeholder="请选择货位"
>
<el-option
v-for="item in locationList"
@ -102,11 +101,7 @@
</el-form-item>
</template>
</el-table-column>
<el-table-column
label="码"
fixed="right"
min-width="40"
>
<el-table-column label="码" fixed="right" min-width="40">
<template #default="{ row, $index }">
<el-form-item class="mb-0px!">
<el-button :disabled="row.ifQr" @click="openQrDialog($index)" link>
@ -121,7 +116,8 @@
<el-input-number
v-model="row.count"
controls-position="right"
:min="0.001"
:min="1"
:max="row.totalCount"
:precision="3"
class="!w-100%"
/>
@ -188,40 +184,53 @@
</el-form-item>
</template>
</el-table-column>
<el-table-column align="center" fixed="right" label="操作" width="60">
<el-table-column label="操作" align="center" fixed="right" width="120">
<template #default="{ $index }">
<el-button :disabled="formData.length === 1" @click="handleDelete($index)" link>
<span v-show="formData.length > 1 && !disabled" style="color: red;"></span>
<span v-show="formData.length === 1 || disabled"></span>
<span v-show="formData.length > 1 && !disabled" style="color: red"></span>
<span v-show="formData.length === 1 || disabled"></span>
</el-button>
<el-button
:disabled="formData[$index].count <= 1"
@click="openSplitDialog($index)"
link
style="color: blue"
>
拆分
</el-button>
</template>
</el-table-column>
</el-table>
</el-form>
</div>
<div>
<div>
<!-- 一物一码扫码弹窗 -->
<Dialog
:title="productName"
v-model="qrDialogVisible"
:appendToBody="true"
>
<Dialog :title="productName" v-model="qrDialogVisible" :appendToBody="true">
<!-- 显示有效行数 -->
<div>输入的有效行数: {{ qrCodeLineCount }}</div>
<div>需要扫描数: {{ qrNeedCount }}</div>
<el-input type="textarea" v-model="qrCodes" :rows="10" @input="onQrCodeChange" />
<template #footer>
<el-button @click="submitQr" type="primary">
</el-button>
<el-button @click="submitQr" type="primary"> </el-button>
<el-button @click="qrDialogVisible = false"> </el-button>
</template>
</Dialog>
</div>
</div>
<!-- 拆分弹窗 -->
<Dialog title="拆分" v-model="splitDialogVisible" :appendToBody="true">
<el-input-number
v-model="splitCount"
:min="1"
:max="currentRow.count"
controls-position="right"
/>
<template #footer>
<el-button @click="splitItem" type="primary"> </el-button>
<el-button @click="splitDialogVisible = false"> </el-button>
</template>
</Dialog>
</div>
</template>
<script setup lang="ts">
@ -258,82 +267,82 @@ const qrDialogVisible = ref(false)
//
const qrCodes = ref('')
//
const currentRow = ref<typeof props.items[0]>(undefined)
const currentRow = ref<(typeof props.items)[0]>(undefined)
//
const currentRowIndex = ref(-1)
//
const productName = ref('')
//
const qrCodeLineCount = ref(0);
const qrCodeLineCount = ref(0)
const message = useMessage() //
//
const qrNeedCount = computed(() => {
return currentRow.value?.count
})
//
const onQrCodeChange = () => {
// qrCode.value undefined null
if (qrCodes.value) {
const lines = qrCodes.value.split('\n');
const lines = qrCodes.value.split('\n')
//
const trimmedLines = lines.map(line => line.trim());
const validLines = trimmedLines.filter(line =>{
const trimmedLines = lines.map((line) => line.trim())
const validLines = trimmedLines.filter((line) => {
return matchRulesFromDictOptions(line)
});
})
//
const uniqueLines = [...new Set(validLines)];
qrCodeLineCount.value = uniqueLines.length;
const uniqueLines = [...new Set(validLines)]
qrCodeLineCount.value = uniqueLines.length
// row.count
if (currentRow.value && qrCodeLineCount.value > currentRow.value.count) {
message.warning('输入的有效行数不能超过该产品的数量!');
message.warning('输入的有效行数不能超过该产品的数量!')
//
qrCodes.value = validLines.slice(0, currentRow.value.count).join('\n');
qrCodeLineCount.value = currentRow.value.count;
qrCodes.value = validLines.slice(0, currentRow.value.count).join('\n')
qrCodeLineCount.value = currentRow.value.count
}
} else {
qrCodeLineCount.value = 0;
qrCodeLineCount.value = 0
}
}
};
//
const openQrDialog = (index: number) => {
// currentRow
currentRow.value = formData.value[index] ; // 使
currentRowIndex.value = index;
currentRow.value = formData.value[index] // 使
currentRowIndex.value = index
//
if (currentRow.value.qrcodes) {
qrCodes.value = currentRow.value.qrcodes;
qrCodes.value = currentRow.value.qrcodes
} else {
qrCodes.value = ''; //
qrCodes.value = '' //
}
//
productName.value = currentRow.value.productName;
productName.value = currentRow.value.productName
//
onQrCodeChange();
onQrCodeChange()
//
qrDialogVisible.value = true;
};
qrDialogVisible.value = true
}
/** 提交扫码 */
const submitQr = async () => {
//
if (qrCodes.value == null || qrCodes.value == undefined || qrCodes.value === '') {
return;
return
}
// formData
const index = currentRowIndex.value; //
if (index !== -1 && formData.value[index]) { //
const index = currentRowIndex.value //
if (index !== -1 && formData.value[index]) {
//
// formData qrcode
formData.value[index].qrcodes = qrCodes.value;
formData.value[index].qrcodes = qrCodes.value
//
formData.value[index].qrCodeLineCount = qrCodeLineCount.value;
formData.value[index].qrCodeLineCount = qrCodeLineCount.value
}
//
qrDialogVisible.value = false;
};
qrDialogVisible.value = false
}
/** 初始化设置入库项 */
watch(
@ -419,37 +428,49 @@ const queryLocationParams = reactive({
})
//
const onChangeWarehouse = async (row: typeof props.items[0]) => {
queryLocationParams.warehouseId = row.warehouseId;
const onChangeWarehouse = async (row: (typeof props.items)[0]) => {
queryLocationParams.warehouseId = row.warehouseId
try {
const response = await WarehouseLocactionApi.getWarehouseLocationPage(queryLocationParams);
const response = await WarehouseLocactionApi.getWarehouseLocationPage(queryLocationParams)
if (response) {
if (response.list.length !== 0) {
locationList.value = response.list;
locationList.value = response.list
} else {
console.error('获取货位列表失败,错误码:', response.code, ',错误信息:', response.msg);
console.error('获取货位列表失败,错误码:', response.code, ',错误信息:', response.msg)
}
} else {
console.error('获取货位列表失败,响应为空');
console.error('获取货位列表失败,响应为空')
}
} catch (error: any) {
if (error.response) {
// Axios
console.error('获取货位列表失败HTTP错误码:', error.response.status, ',错误信息:', error.response.data);
console.error(
'获取货位列表失败HTTP错误码:',
error.response.status,
',错误信息:',
error.response.data
)
} else if (error.request) {
//
console.error('获取货位列表失败,没有收到响应');
console.error('获取货位列表失败,没有收到响应')
} else {
//
console.error('获取货位列表时发生错误:', error.message);
console.error('获取货位列表时发生错误:', error.message)
}
}
}
};
/** 删除按钮操作 */
const handleDelete = (index: number) => {
formData.value.splice(index, 1)
const deletedRow = formData.value.splice(index, 1)[0]
const deletedCount = deletedRow.count
const productId = deletedRow.productId
formData.value.forEach((row) => {
if (row.productId === productId) {
row.totalCount += deletedCount // totalCount
}
})
}
/** 加载库存 */
@ -471,6 +492,42 @@ defineExpose({ validate })
onMounted(async () => {
warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
defaultWarehouse.value = warehouseList.value.find((item) => item.defaultStatus)
locationList.value = onChangeWarehouse({pageNo: 1,pageSize: 100,warehouseId: defaultWarehouse.value?.id})
locationList.value = onChangeWarehouse({
pageNo: 1,
pageSize: 100,
warehouseId: defaultWarehouse.value?.id
})
})
//
const splitDialogVisible = ref(false)
const splitCount = ref(1)
//
const openSplitDialog = (index: number) => {
currentRow.value = formData.value[index]
currentRowIndex.value = index
splitCount.value = 1
splitDialogVisible.value = true
}
//
const splitItem = () => {
if (splitCount.value >= currentRow.value.count) {
message.warning('拆分数量不能大于或等于当前数量!')
return
}
currentRow.value.count -= splitCount.value
currentRow.value.totalCount = currentRow.value.count // totalCount
const newRow = {
...currentRow.value,
count: splitCount.value,
inCount: 0,
totalCount: currentRow.value.totalCount // totalCount
}
formData.value.splice(currentRowIndex.value + 1, 0, newRow)
splitDialogVisible.value = false
}
</script>

View File

@ -174,6 +174,7 @@ import { erpPriceInputFormatter, erpPriceMultiply } from '@/utils'
import PurchaseOrderReturnEnableList from '@/views/erp/purchase/order/components/PurchaseOrderReturnEnableList.vue'
import { PurchaseOrderVO } from '@/api/erp/purchase/order'
import * as UserApi from '@/api/system/user'
import { PurchaseInApi } from '@/api/erp/purchase/in'
/** ERP 采购退货表单 */
defineOptions({ name: 'PurchaseReturnForm' })
@ -214,6 +215,12 @@ const userList = ref<UserApi.UserVO[]>([]) // 用户列表
const subTabsName = ref('item')
const itemFormRef = ref()
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
orderNo: undefined
}) //
/** 计算 discountPrice、totalPrice 价格 */
watch(
() => formData.value,
@ -270,7 +277,7 @@ const openPurchaseOrderReturnEnableList = () => {
purchaseOrderReturnEnableListRef.value.open()
}
const handlePurchaseOrderChange = (order: PurchaseOrderVO) => {
const handlePurchaseOrderChange = async (order: PurchaseOrderVO) => {
// 退
formData.value.orderId = order.id
formData.value.orderNo = order.no
@ -279,13 +286,25 @@ const handlePurchaseOrderChange = (order: PurchaseOrderVO) => {
formData.value.discountPercent = order.discountPercent
formData.value.remark = order.remark
formData.value.fileUrl = order.fileUrl
// 退
order.items.forEach((item) => {
item.count = item.inCount - item.returnCount
item.orderItemId = item.id
item.id = undefined
//
const data = await PurchaseInApi.getPurchaseInPage(queryParams)
const purchaseInList = data.list
const items: { productId: any; count: any; orderItemId: any; id: undefined }[] = []
purchaseInList.forEach((purchaseIn) => {
purchaseIn.items.forEach((item) => {
if (item.count > 0) {
items.push({
...item,
count: item.count,
orderItemId: item.id,
id: undefined
})
formData.value.items = order.items.filter((item) => item.count > 0)
}
})
})
// items
formData.value.items = items
}
/** 提交表单 */
@ -300,7 +319,7 @@ const submitForm = async () => {
const item = items[i]
//
if (item.ifQr) {
continue;
continue
}
if (item.qrcodes.split('\n').length !== item.count) {
message.error(`${i + 1} 行的退货数量和码的数量不同`)