采购退货,入库单子显示货位;采购入库,增加拆分按钮
parent
dddde5bdc6
commit
27611a4b01
|
|
@ -48,7 +48,6 @@
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
placeholder="请选择货位"
|
placeholder="请选择货位"
|
||||||
|
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in locationList"
|
v-for="item in locationList"
|
||||||
|
|
@ -102,11 +101,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column label="码" fixed="right" min-width="40">
|
||||||
label="码"
|
|
||||||
fixed="right"
|
|
||||||
min-width="40"
|
|
||||||
>
|
|
||||||
<template #default="{ row, $index }">
|
<template #default="{ row, $index }">
|
||||||
<el-form-item class="mb-0px!">
|
<el-form-item class="mb-0px!">
|
||||||
<el-button :disabled="row.ifQr" @click="openQrDialog($index)" link>
|
<el-button :disabled="row.ifQr" @click="openQrDialog($index)" link>
|
||||||
|
|
@ -121,7 +116,8 @@
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-model="row.count"
|
v-model="row.count"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
:min="0.001"
|
:min="1"
|
||||||
|
:max="row.totalCount"
|
||||||
:precision="3"
|
:precision="3"
|
||||||
class="!w-100%"
|
class="!w-100%"
|
||||||
/>
|
/>
|
||||||
|
|
@ -188,40 +184,53 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</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 }">
|
<template #default="{ $index }">
|
||||||
<el-button :disabled="formData.length === 1" @click="handleDelete($index)" link>
|
<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" style="color: red">删除</span>
|
||||||
<span v-show="formData.length === 1 || disabled">—</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>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<!-- 一物一码扫码弹窗 -->
|
<!-- 一物一码扫码弹窗 -->
|
||||||
<Dialog
|
<Dialog :title="productName" v-model="qrDialogVisible" :appendToBody="true">
|
||||||
:title="productName"
|
|
||||||
v-model="qrDialogVisible"
|
|
||||||
:appendToBody="true"
|
|
||||||
>
|
|
||||||
<!-- 显示有效行数 -->
|
<!-- 显示有效行数 -->
|
||||||
<div>输入的有效行数: {{ qrCodeLineCount }}</div>
|
<div>输入的有效行数: {{ qrCodeLineCount }}</div>
|
||||||
<div>需要扫描数: {{ qrNeedCount }}</div>
|
<div>需要扫描数: {{ qrNeedCount }}</div>
|
||||||
|
|
||||||
<el-input type="textarea" v-model="qrCodes" :rows="10" @input="onQrCodeChange" />
|
<el-input type="textarea" v-model="qrCodes" :rows="10" @input="onQrCodeChange" />
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="submitQr" type="primary">
|
<el-button @click="submitQr" type="primary"> 确 定 </el-button>
|
||||||
确 定
|
|
||||||
</el-button>
|
|
||||||
<el-button @click="qrDialogVisible = false">取 消</el-button>
|
<el-button @click="qrDialogVisible = false">取 消</el-button>
|
||||||
</template>
|
</template>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
@ -258,82 +267,82 @@ const qrDialogVisible = ref(false)
|
||||||
// 扫码内容
|
// 扫码内容
|
||||||
const qrCodes = ref('')
|
const qrCodes = ref('')
|
||||||
// 当前点击行
|
// 当前点击行
|
||||||
const currentRow = ref<typeof props.items[0]>(undefined)
|
const currentRow = ref<(typeof props.items)[0]>(undefined)
|
||||||
// 当前行号
|
// 当前行号
|
||||||
const currentRowIndex = ref(-1)
|
const currentRowIndex = ref(-1)
|
||||||
// 一物一码弹窗名
|
// 一物一码弹窗名
|
||||||
const productName = ref('')
|
const productName = ref('')
|
||||||
// 记录二维码文本域中的有效行数
|
// 记录二维码文本域中的有效行数
|
||||||
const qrCodeLineCount = ref(0);
|
const qrCodeLineCount = ref(0)
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
// 需要扫描二维码个数
|
// 需要扫描二维码个数
|
||||||
const qrNeedCount = computed(() => {
|
const qrNeedCount = computed(() => {
|
||||||
return currentRow.value?.count
|
return currentRow.value?.count
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// 监听二维码文本域内容的变化
|
// 监听二维码文本域内容的变化
|
||||||
const onQrCodeChange = () => {
|
const onQrCodeChange = () => {
|
||||||
// 检查 qrCode.value 是否为 undefined 或 null
|
// 检查 qrCode.value 是否为 undefined 或 null
|
||||||
if (qrCodes.value) {
|
if (qrCodes.value) {
|
||||||
const lines = qrCodes.value.split('\n');
|
const lines = qrCodes.value.split('\n')
|
||||||
// 先将每一行去除首尾空格
|
// 先将每一行去除首尾空格
|
||||||
const trimmedLines = lines.map(line => line.trim());
|
const trimmedLines = lines.map((line) => line.trim())
|
||||||
const validLines = trimmedLines.filter(line =>{
|
const validLines = trimmedLines.filter((line) => {
|
||||||
return matchRulesFromDictOptions(line)
|
return matchRulesFromDictOptions(line)
|
||||||
});
|
})
|
||||||
// 去重
|
// 去重
|
||||||
const uniqueLines = [...new Set(validLines)];
|
const uniqueLines = [...new Set(validLines)]
|
||||||
qrCodeLineCount.value = uniqueLines.length;
|
qrCodeLineCount.value = uniqueLines.length
|
||||||
|
|
||||||
// 检查有效行数是否超过 row.count
|
// 检查有效行数是否超过 row.count
|
||||||
if (currentRow.value && qrCodeLineCount.value > currentRow.value.count) {
|
if (currentRow.value && qrCodeLineCount.value > currentRow.value.count) {
|
||||||
message.warning('输入的有效行数不能超过该产品的数量!');
|
message.warning('输入的有效行数不能超过该产品的数量!')
|
||||||
// 截取多余的行数
|
// 截取多余的行数
|
||||||
qrCodes.value = validLines.slice(0, currentRow.value.count).join('\n');
|
qrCodes.value = validLines.slice(0, currentRow.value.count).join('\n')
|
||||||
qrCodeLineCount.value = currentRow.value.count;
|
qrCodeLineCount.value = currentRow.value.count
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qrCodeLineCount.value = 0;
|
qrCodeLineCount.value = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// 控制一物一码弹窗
|
// 控制一物一码弹窗
|
||||||
const openQrDialog = (index: number) => {
|
const openQrDialog = (index: number) => {
|
||||||
// 确保 currentRow 更新为当前点击的行
|
// 确保 currentRow 更新为当前点击的行
|
||||||
currentRow.value = formData.value[index] ; // 使用解构赋值确保创建一个新对象
|
currentRow.value = formData.value[index] // 使用解构赋值确保创建一个新对象
|
||||||
currentRowIndex.value = index;
|
currentRowIndex.value = index
|
||||||
// 检查当前行是否有二维码数据
|
// 检查当前行是否有二维码数据
|
||||||
if (currentRow.value.qrcodes) {
|
if (currentRow.value.qrcodes) {
|
||||||
qrCodes.value = currentRow.value.qrcodes;
|
qrCodes.value = currentRow.value.qrcodes
|
||||||
} else {
|
} 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 () => {
|
const submitQr = async () => {
|
||||||
// 扫码内容不能为空
|
// 扫码内容不能为空
|
||||||
if (qrCodes.value == null || qrCodes.value == undefined || qrCodes.value === '') {
|
if (qrCodes.value == null || qrCodes.value == undefined || qrCodes.value === '') {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
// 找到当前行在 formData 中的索引
|
// 找到当前行在 formData 中的索引
|
||||||
const index = currentRowIndex.value; // 获取当前行的索引
|
const index = currentRowIndex.value // 获取当前行的索引
|
||||||
if (index !== -1 && formData.value[index]) { // 确保索引有效且对应行存在
|
if (index !== -1 && formData.value[index]) {
|
||||||
|
// 确保索引有效且对应行存在
|
||||||
// 更新 formData 中对应行的 qrcode 值
|
// 更新 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(
|
watch(
|
||||||
|
|
@ -419,37 +428,49 @@ const queryLocationParams = reactive({
|
||||||
})
|
})
|
||||||
|
|
||||||
//仓库变更,同步变更货位列表
|
//仓库变更,同步变更货位列表
|
||||||
const onChangeWarehouse = async (row: typeof props.items[0]) => {
|
const onChangeWarehouse = async (row: (typeof props.items)[0]) => {
|
||||||
queryLocationParams.warehouseId = row.warehouseId;
|
queryLocationParams.warehouseId = row.warehouseId
|
||||||
try {
|
try {
|
||||||
const response = await WarehouseLocactionApi.getWarehouseLocationPage(queryLocationParams);
|
const response = await WarehouseLocactionApi.getWarehouseLocationPage(queryLocationParams)
|
||||||
if (response) {
|
if (response) {
|
||||||
if (response.list.length !== 0) {
|
if (response.list.length !== 0) {
|
||||||
locationList.value = response.list;
|
locationList.value = response.list
|
||||||
} else {
|
} else {
|
||||||
console.error('获取货位列表失败,错误码:', response.code, ',错误信息:', response.msg);
|
console.error('获取货位列表失败,错误码:', response.code, ',错误信息:', response.msg)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error('获取货位列表失败,响应为空');
|
console.error('获取货位列表失败,响应为空')
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (error.response) {
|
if (error.response) {
|
||||||
// Axios错误,有响应体
|
// Axios错误,有响应体
|
||||||
console.error('获取货位列表失败,HTTP错误码:', error.response.status, ',错误信息:', error.response.data);
|
console.error(
|
||||||
|
'获取货位列表失败,HTTP错误码:',
|
||||||
|
error.response.status,
|
||||||
|
',错误信息:',
|
||||||
|
error.response.data
|
||||||
|
)
|
||||||
} else if (error.request) {
|
} else if (error.request) {
|
||||||
// 发出了请求,但没有收到响应
|
// 发出了请求,但没有收到响应
|
||||||
console.error('获取货位列表失败,没有收到响应');
|
console.error('获取货位列表失败,没有收到响应')
|
||||||
} else {
|
} else {
|
||||||
// 其他错误
|
// 其他错误
|
||||||
console.error('获取货位列表时发生错误:', error.message);
|
console.error('获取货位列表时发生错误:', error.message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** 删除按钮操作 */
|
/** 删除按钮操作 */
|
||||||
const handleDelete = (index: number) => {
|
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 () => {
|
onMounted(async () => {
|
||||||
warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
|
warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
|
||||||
defaultWarehouse.value = warehouseList.value.find((item) => item.defaultStatus)
|
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>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,7 @@ import { erpPriceInputFormatter, erpPriceMultiply } from '@/utils'
|
||||||
import PurchaseOrderReturnEnableList from '@/views/erp/purchase/order/components/PurchaseOrderReturnEnableList.vue'
|
import PurchaseOrderReturnEnableList from '@/views/erp/purchase/order/components/PurchaseOrderReturnEnableList.vue'
|
||||||
import { PurchaseOrderVO } from '@/api/erp/purchase/order'
|
import { PurchaseOrderVO } from '@/api/erp/purchase/order'
|
||||||
import * as UserApi from '@/api/system/user'
|
import * as UserApi from '@/api/system/user'
|
||||||
|
import { PurchaseInApi } from '@/api/erp/purchase/in'
|
||||||
|
|
||||||
/** ERP 采购退货表单 */
|
/** ERP 采购退货表单 */
|
||||||
defineOptions({ name: 'PurchaseReturnForm' })
|
defineOptions({ name: 'PurchaseReturnForm' })
|
||||||
|
|
@ -214,6 +215,12 @@ const userList = ref<UserApi.UserVO[]>([]) // 用户列表
|
||||||
const subTabsName = ref('item')
|
const subTabsName = ref('item')
|
||||||
const itemFormRef = ref()
|
const itemFormRef = ref()
|
||||||
|
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
orderNo: undefined
|
||||||
|
}) //获取采购入库单号
|
||||||
|
|
||||||
/** 计算 discountPrice、totalPrice 价格 */
|
/** 计算 discountPrice、totalPrice 价格 */
|
||||||
watch(
|
watch(
|
||||||
() => formData.value,
|
() => formData.value,
|
||||||
|
|
@ -270,7 +277,7 @@ const openPurchaseOrderReturnEnableList = () => {
|
||||||
purchaseOrderReturnEnableListRef.value.open()
|
purchaseOrderReturnEnableListRef.value.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePurchaseOrderChange = (order: PurchaseOrderVO) => {
|
const handlePurchaseOrderChange = async (order: PurchaseOrderVO) => {
|
||||||
// 将订单设置到退货单
|
// 将订单设置到退货单
|
||||||
formData.value.orderId = order.id
|
formData.value.orderId = order.id
|
||||||
formData.value.orderNo = order.no
|
formData.value.orderNo = order.no
|
||||||
|
|
@ -279,13 +286,25 @@ const handlePurchaseOrderChange = (order: PurchaseOrderVO) => {
|
||||||
formData.value.discountPercent = order.discountPercent
|
formData.value.discountPercent = order.discountPercent
|
||||||
formData.value.remark = order.remark
|
formData.value.remark = order.remark
|
||||||
formData.value.fileUrl = order.fileUrl
|
formData.value.fileUrl = order.fileUrl
|
||||||
// 将订单项设置到退货单项
|
|
||||||
order.items.forEach((item) => {
|
// 获取与采购订单号相关的采购入库单号列表
|
||||||
item.count = item.inCount - item.returnCount
|
const data = await PurchaseInApi.getPurchaseInPage(queryParams)
|
||||||
item.orderItemId = item.id
|
const purchaseInList = data.list
|
||||||
item.id = undefined
|
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]
|
const item = items[i]
|
||||||
//先判断本行是否需要一物一码
|
//先判断本行是否需要一物一码
|
||||||
if (item.ifQr) {
|
if (item.ifQr) {
|
||||||
continue;
|
continue
|
||||||
}
|
}
|
||||||
if (item.qrcodes.split('\n').length !== item.count) {
|
if (item.qrcodes.split('\n').length !== item.count) {
|
||||||
message.error(`第 ${i + 1} 行的退货数量和码的数量不同`)
|
message.error(`第 ${i + 1} 行的退货数量和码的数量不同`)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue