feat(saledelivery): 完善销售出库单功能实现

This commit is contained in:
zxy 2026-05-18 10:23:16 +08:00
parent 3dcf935e1c
commit 4924139b89
7 changed files with 109 additions and 53 deletions

View File

@ -1,10 +1,8 @@
package com.ningxia.yunxi.chemmes.module.biz.controller.admin.saledeliverydetail.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
import java.util.*;
import lombok.Data;
import java.math.BigDecimal;
@Schema(description = "管理后台 - 销售出库单子新增/修改 Request VO")
@ -53,4 +51,6 @@ public class SaleDeliveryDetailSaveReqVO {
@Schema(description = "发货袋数")
private Integer deliveriedBagQty;
private String unit;
}

View File

@ -80,7 +80,7 @@ public class SaleDeliveryDO extends BaseDO {
/**
* 出库人id
*/
private Integer deliveryEmpId;
private String deliveryEmpId;
/**
* 出库人名称
*/

View File

@ -9,6 +9,8 @@ import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.saledelivery.SaleDeli
import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.saledeliverydetail.SaleDeliveryDetailDO;
import com.ningxia.yunxi.chemmes.module.biz.dal.mysql.saledelivery.SaleDeliveryMapper;
import com.ningxia.yunxi.chemmes.module.biz.dal.mysql.saledeliverydetail.SaleDeliveryDetailMapper;
import com.ningxia.yunxi.chemmes.module.system.dal.dataobject.user.AdminUserDO;
import com.ningxia.yunxi.chemmes.module.system.dal.mysql.user.AdminUserMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@ -19,6 +21,7 @@ import java.time.format.DateTimeFormatter;
import java.util.List;
import static com.ningxia.yunxi.chemmes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.ningxia.yunxi.chemmes.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
/**
* 销售出库单主 Service 实现类
@ -35,6 +38,9 @@ public class SaleDeliveryServiceImpl implements SaleDeliveryService {
@Resource
private SaleDeliveryDetailMapper saleDeliveryDetailMapper;
@Resource
private AdminUserMapper adminUserMapper;
@Override
@Transactional(rollbackFor = Exception.class)
@ -43,6 +49,14 @@ public class SaleDeliveryServiceImpl implements SaleDeliveryService {
createReqVO.setSaleDeliveryNo(saleDeliveryNo);
// 插入
SaleDeliveryDO saleDelivery = BeanUtils.toBean(createReqVO, SaleDeliveryDO.class);
//出库人
// 获取当前登录用户信息
Long userId = getLoginUserId();
AdminUserDO adminUserDO = adminUserMapper.selectById(userId);
saleDelivery.setDeliveryEmpId(String.valueOf(adminUserDO.getId()));
saleDelivery.setDeliveryEmpName(adminUserDO.getNickname());
saleDeliveryMapper.insert(saleDelivery);
createSaleDeliveryDetailList(saleDelivery.getId(), createReqVO.getDetailList());

View File

@ -249,8 +249,10 @@ const handleSave = () => {
const selectData = selectedRows.map(row => ({
id: row.id,
storeHouseId: row.storeHouseId,
storeHouseCd: row.storeHouseCd,
storeHouseName: row.storeHouseName,
storeAreaId: row.storeAreaId,
storeAreCd: row.storeAreCd,
storeAreaName: row.storeAreaName,
lotNo: row.lotNo,
packQty: row.packQty,
@ -288,6 +290,6 @@ watch(dialogVisible, (val) => {
<style scoped>
.pagination-container {
margin-bottom: 16px;
margin-bottom: 60px;
}
</style>

View File

@ -263,7 +263,7 @@ watch(dialogVisible, (val) => {
<style scoped>
.pagination-container {
margin-bottom: 16px;
margin-bottom: 60px;
}
.radio-btn {

View File

@ -85,12 +85,11 @@
</el-col>
<el-col :span="6">
<el-form-item label="发货数量" prop="deliveriedQty">
<MoneyInput
v-model="formData.deliveriedQty"
:decimal-places="0"
:allow-negative="false"
:show-prefix="false"
/>
<el-input
v-model.number="formData.deliveriedQty"
type="number"
placeholder="请输入发货数量"
/>
</el-form-item>
</el-col>
</el-row>
@ -361,34 +360,49 @@ const formRules = reactive({
saleDeliveryNo: [{ required: true, message: '出库单号不能为空', trigger: 'change' }],
ordQty: [{ required: true, message: '订单数量不能为空', trigger: 'change' }],
remaimQty: [{ required: true, message: '剩余数量不能为空', trigger: 'change' }],
deliveriedQty: [{ required: true, message: '发货数量不能为空', trigger: 'change' }],
})
const formRef = ref()
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
//
resetForm()
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
//
if (id) {
formLoading.value = true
try {
const data = await SaleDeliveryApi.getSaleDelivery(id)
Object.assign(formData, data)
// -
// -
let itemsData = []
if (data.items && data.items.length > 0) {
productList.value = data.items
itemsData = data.items
} else if (data.detailList && data.detailList.length > 0) {
productList.value = data.detailList
itemsData = data.detailList
} else if (data.products && data.products.length > 0) {
productList.value = data.products
} else {
productList.value = []
itemsData = data.products
}
//
productList.value = itemsData.map((item: any) => ({
id: item.id,
storeHouseId: item.storeHouseId,
storeHouseCd: item.storeHouseCd || '',
storeAreaId: item.storeAreaId,
storeAreCd: item.storeAreCd || '',
warehouse: item.storeHouseName || '',
warehouseArea: item.storeAreaName || '',
batchNo: item.lotNo || '',
bagSpec: item.bagSpec || '',
deliveriedBag: item.deliveriedBagQty || '',
deliveriedQty: item.deliveriedQty || '',
remark: item.remark || '',
}))
} finally {
formLoading.value = false
}
@ -396,6 +410,9 @@ const open = async (type: string, id?: number) => {
//
await loadSaleOrderOptions()
}
//
dialogVisible.value = true
}
defineExpose({ open })
@ -547,7 +564,9 @@ const handleInventorySelect = (data: any[]) => {
productList.value.push({
inventoryId: inventory.id, // ID
storeHouseId: inventory.storeHouseId, // ID
storeHouseCd: inventory.storeHouseCd, //
storeAreaId: inventory.storeAreaId, // ID
storeAreCd: inventory.storeAreCd, //
warehouse: inventory.storeHouseName, //
warehouseArea: inventory.storeAreaName, //
batchNo: inventory.lotNo, //
@ -597,19 +616,18 @@ const submitForm = async () => {
//
formLoading.value = true
try {
// detailList
// detailList
const detailList = productList.value.map(item => ({
id: item.id,
inventoryId: item.inventoryId,
twmStorageDetailId: item.id,
storeHouseId: item.storeHouseId,
storeHouseName: item.warehouse,
storeHouseCd: item.storeHouseCd,
storeAreaId: item.storeAreaId,
warehouse: item.warehouse,
warehouseArea: item.warehouseArea,
batchNo: item.batchNo,
stockQty: item.stockQty,
stockBag: item.stockBag,
storeAreaName: item.warehouseArea,
storeAreCd: item.storeAreCd,
lotNo: item.batchNo,
bagSpec: item.bagSpec,
deliveriedBag: item.deliveriedBag,
deliveriedBagQty: item.deliveriedBag,
deliveriedQty: item.deliveriedQty,
remark: item.remark,
}))
@ -646,19 +664,18 @@ const submitAudit = async () => {
//
formLoading.value = true
try {
// detailList
// detailList
const detailList = productList.value.map(item => ({
id: item.id,
inventoryId: item.inventoryId,
storeHouseId: item.storeHouseId,
storeHouseName: item.warehouse,
storeHouseCd: item.storeHouseCd,
storeAreaId: item.storeAreaId,
warehouse: item.warehouse,
warehouseArea: item.warehouseArea,
batchNo: item.batchNo,
stockQty: item.stockQty,
stockBag: item.stockBag,
storeAreCd: item.storeAreCd,
storeAreaName: item.warehouseArea,
lotNo: item.batchNo,
bagSpec: item.bagSpec,
deliveriedBag: item.deliveriedBag,
deliveriedBagQty: item.deliveriedBag,
deliveriedQty: item.deliveriedQty,
remark: item.remark,
}))

View File

@ -89,19 +89,26 @@
<el-table-column label="订单数量" align="center" prop="ordQty" width="100px" />
<el-table-column label="剩余数量" align="center" prop="remaimQty" width="100px" />
<el-table-column label="发货数量" align="center" prop="deliveriedQty" width="100px" />
<el-table-column label="单位" align="center" prop="unit" width="80px" />
<el-table-column label="单位" align="center" width="80px">
<template #default="scope">
<dict-tag v-if="scope.row.unit" :type="DICT_TYPE.UNIT" :value="scope.row.unit" />
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="出库人" align="center" prop="deliveryEmpName" width="100px" />
<el-table-column label="交货方式" align="center" prop="deliveryType" width="100px">
<template #default="scope">
<dict-tag :type="DICT_TYPE.DELIVERY_METHOD" :value="scope.row.deliveryType" />
<span>{{ scope.row.deliveryType === '1' ? '发货' : (scope.row.deliveryType === '2' ? '自提' : '-') }}</span>
</template>
</el-table-column>
<el-table-column label="联系人" align="center" prop="contact" width="100px" />
<el-table-column label="联系电话" align="center" prop="conPhone" width="120px" />
<el-table-column label="联系电话" align="center" prop="conPhone" width="130px" />
<el-table-column label="联系地址" align="center" prop="conAddress" width="180px" />
<el-table-column label="单据状态" align="center" prop="deliveryStatus" width="100px" fixed="right">
<template #default="scope">
<dict-tag :type="DICT_TYPE.BILL_STATUS" :value="scope.row.deliveryStatus" />
<el-tag :type="scope.row.deliveryStatus === '1' ? 'info' : 'success'">
{{ scope.row.deliveryStatus === '1' ? '已创建' : (scope.row.deliveryStatus === '2' ? '已确认' : '-') }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="170px" fixed="right">
@ -109,7 +116,7 @@
<el-button
link
type="primary"
@click="openForm('update', scope.row.id)"
@click.stop="openForm('update', scope.row.id)"
v-hasPermi="['tso:sale-delivery:update']"
>
编辑
@ -117,7 +124,7 @@
<el-button
link
type="danger"
@click="handleDelete(scope.row.id)"
@click.stop="handleDelete(scope.row.id)"
v-hasPermi="['tso:sale-delivery:delete']"
>
删除
@ -125,7 +132,7 @@
<el-button
link
type="primary"
@click="viewDetail(scope.row)"
@click.stop="viewDetail(scope.row)"
v-hasPermi="['tso:sale-delivery:query']"
>
详情
@ -145,15 +152,20 @@
<!-- 明细表格 -->
<div style="flex: 1; min-height: 0;" >
<div style="font-weight: bold; margin-bottom: 8px;">出库单明细</div>
<el-table v-loading="detailLoading" :data="detailList" :stripe="true" :show-overflow-tooltip="true" border :summary-method="getDetailSummary" show-summary style="width: 50%">
<el-table v-loading="detailLoading" :data="detailList" :stripe="true" :show-overflow-tooltip="true" :summary-method="getDetailSummary" show-summary border style="width: 50%">
<el-table-column label="序号" align="center" type="index" width="60px"/>
<el-table-column label="库区" align="center" prop="warehouseArea" width="120px" />
<el-table-column label="库位" align="center" prop="warehouseLoc" width="120px" />
<el-table-column label="库位" align="center" prop="storeHouseName" width="120px" />
<el-table-column label="批次号" align="center" prop="batchNo" width="120px" />
<el-table-column label="发货数量" align="center" prop="deliveriedQty" width="120px" />
<el-table-column label="发货袋数" align="center" prop="deliveriedBag" width="120px" />
<el-table-column label="单据规格" align="center" prop="spec" width="120px" />
<el-table-column label="单位" align="center" prop="unit" width="80px" />
<el-table-column label="单据规格" align="center" prop="bagSpec" width="120px" />
<el-table-column label="单位" align="center" width="80px">
<template #default="scope">
<dict-tag v-if="scope.row.unit" :type="DICT_TYPE.UNIT" :value="scope.row.unit" />
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" />
</el-table>
</div>
@ -283,8 +295,19 @@ const viewDetail = async (row: any) => {
try {
const data = await SaleDeliveryApi.getSaleDelivery(row.id)
selectedRow.value = data
// 使 detailList
detailList.value = data.items || data.detailList || []
// 使 detailList
const itemsData = data.items || data.detailList || []
const mainUnit = data.unit || '' //
detailList.value = itemsData.map((item: any) => ({
warehouseArea: item.storeAreaName || '',
storeHouseName: item.storeHouseName || '',
batchNo: item.lotNo || '',
deliveriedQty: item.deliveriedQty || '',
deliveriedBag: item.deliveriedBagQty || '',
bagSpec: item.bagSpec || '',
unit: mainUnit, // 使
remark: item.remark || '',
}))
} catch (e) {
console.error('获取详情失败', e)
detailList.value = []