采购退货,入库单子显示货位;采购入库,增加拆分按钮
parent
dddde5bdc6
commit
27611a4b01
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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} 行的退货数量和码的数量不同`)
|
||||
|
|
|
|||
Loading…
Reference in New Issue