From de339b5b2b2875d709041f6c6abadb642efa7a1b Mon Sep 17 00:00:00 2001 From: zxy Date: Tue, 19 May 2026 15:09:30 +0800 Subject: [PATCH] =?UTF-8?q?feat(biz):=20=E4=BC=98=E5=8C=96=E9=94=80?= =?UTF-8?q?=E5=94=AE=E5=87=BA=E5=BA=93=E5=8D=95=E5=8A=9F=E8=83=BD=E5=B9=B6?= =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=BA=93=E5=AD=98=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/prostorage/vo/ProStorageRespVO.java | 4 +- .../vo/SaleDeliveryPageReqVO.java | 8 +- .../storehouse/StoreHouseController.java | 49 ++-- .../admin/storehouse/vo/StoreHouseRespVO.java | 17 +- .../saledelivery/SaleDeliveryMapper.java | 2 +- .../mysql/storehouse/StoreHouseMapper.java | 18 +- .../service/storehouse/StoreHouseService.java | 13 +- .../storehouse/StoreHouseServiceImpl.java | 4 +- .../src/api/biz/storehouse/index.ts | 4 +- .../mes-ui-admin-vue3/src/utils/formatTime.ts | 7 + .../ProStorageInventorySelectDialog.vue | 61 +++-- .../biz/saledelivery/SaleDeliveryDetail.vue | 41 +-- .../biz/saledelivery/SaleDeliveryForm.vue | 259 ++++++++++++++---- .../src/views/biz/saledelivery/index.vue | 24 +- 14 files changed, 338 insertions(+), 173 deletions(-) diff --git a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/prostorage/vo/ProStorageRespVO.java b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/prostorage/vo/ProStorageRespVO.java index a49c699..9e3a81d 100644 --- a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/prostorage/vo/ProStorageRespVO.java +++ b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/prostorage/vo/ProStorageRespVO.java @@ -2,6 +2,7 @@ package com.ningxia.yunxi.chemmes.module.biz.controller.admin.prostorage.vo; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; +import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -43,7 +44,8 @@ public class ProStorageRespVO { @Schema(description = "业务日期") @ExcelProperty("业务日期") - private LocalDate billDate; + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate billDate; @Schema(description = "操作人id", example = "21958") @ExcelProperty("操作人id") diff --git a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/saledelivery/vo/SaleDeliveryPageReqVO.java b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/saledelivery/vo/SaleDeliveryPageReqVO.java index fb5a576..b0e5cab 100644 --- a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/saledelivery/vo/SaleDeliveryPageReqVO.java +++ b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/saledelivery/vo/SaleDeliveryPageReqVO.java @@ -9,9 +9,8 @@ import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; import java.time.LocalDate; -import java.time.LocalDateTime; -import static com.ningxia.yunxi.chemmes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; +import static com.ningxia.yunxi.chemmes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; @Schema(description = "管理后台 - 销售出库单主分页 Request VO") @Data @@ -19,15 +18,12 @@ import static com.ningxia.yunxi.chemmes.framework.common.util.date.DateUtils.FOR @ToString(callSuper = true) public class SaleDeliveryPageReqVO extends PageParam { - @Schema(description = "创建时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] createTime; @Schema(description = "销售出库单号(SC+年份+月份+3位流水号)") private String saleDeliveryNo; @Schema(description = "单据日期") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) private LocalDate[] deliveryDate; @Schema(description = "客户id", example = "11842") diff --git a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/storehouse/StoreHouseController.java b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/storehouse/StoreHouseController.java index 2ac87fd..ade3650 100644 --- a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/storehouse/StoreHouseController.java +++ b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/storehouse/StoreHouseController.java @@ -1,33 +1,31 @@ package com.ningxia.yunxi.chemmes.module.biz.controller.admin.storehouse; -import org.springframework.web.bind.annotation.*; -import javax.annotation.Resource; -import org.springframework.validation.annotation.Validated; -import org.springframework.security.access.prepost.PreAuthorize; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Operation; - -import javax.validation.constraints.*; -import javax.validation.*; -import javax.servlet.http.*; -import java.util.*; -import java.io.IOException; - +import com.ningxia.yunxi.chemmes.framework.common.pojo.CommonResult; import com.ningxia.yunxi.chemmes.framework.common.pojo.PageParam; import com.ningxia.yunxi.chemmes.framework.common.pojo.PageResult; -import com.ningxia.yunxi.chemmes.framework.common.pojo.CommonResult; import com.ningxia.yunxi.chemmes.framework.common.util.object.BeanUtils; -import static com.ningxia.yunxi.chemmes.framework.common.pojo.CommonResult.success; - import com.ningxia.yunxi.chemmes.framework.excel.core.util.ExcelUtils; - import com.ningxia.yunxi.chemmes.framework.operatelog.core.annotations.OperateLog; -import static com.ningxia.yunxi.chemmes.framework.operatelog.core.enums.OperateTypeEnum.*; - -import com.ningxia.yunxi.chemmes.module.biz.controller.admin.storehouse.vo.*; +import com.ningxia.yunxi.chemmes.module.biz.controller.admin.storehouse.vo.StoreHousePageReqVO; +import com.ningxia.yunxi.chemmes.module.biz.controller.admin.storehouse.vo.StoreHouseRespVO; +import com.ningxia.yunxi.chemmes.module.biz.controller.admin.storehouse.vo.StoreHouseSaveReqVO; import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.storehouse.StoreHouseDO; import com.ningxia.yunxi.chemmes.module.biz.service.storehouse.StoreHouseService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.List; + +import static com.ningxia.yunxi.chemmes.framework.common.pojo.CommonResult.success; +import static com.ningxia.yunxi.chemmes.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; @Tag(name = "管理后台 - 仓储主数据") @RestController @@ -84,19 +82,20 @@ public class StoreHouseController { @PreAuthorize("@ss.hasPermission('biz:store-house:export')") @OperateLog(type = EXPORT) public void exportStoreHouseExcel(@Valid StoreHousePageReqVO pageReqVO, - HttpServletResponse response) throws IOException { + HttpServletResponse response) throws IOException { pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); List list = storeHouseService.getStoreHousePage(pageReqVO).getList(); // 导出 Excel ExcelUtils.write(response, "仓储主数据.xls", "数据", StoreHouseRespVO.class, - BeanUtils.toBean(list, StoreHouseRespVO.class)); + BeanUtils.toBean(list, StoreHouseRespVO.class)); } + @GetMapping("/get-store-house-select") @Operation(summary = "获得仓储下拉框数据") @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('biz:store-house:query')") - public CommonResult> getStoreHouseSelect() { - List list = storeHouseService.getStoreHouseSelect(); + public CommonResult> getStoreHouseSelect(@RequestParam(value = "storeType", required = false, defaultValue = "") String storeType) { + List list = storeHouseService.getStoreHouseSelect(storeType); return success(BeanUtils.toBean(list, StoreHouseRespVO.class)); } diff --git a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/storehouse/vo/StoreHouseRespVO.java b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/storehouse/vo/StoreHouseRespVO.java index 0281d79..375eb47 100644 --- a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/storehouse/vo/StoreHouseRespVO.java +++ b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/storehouse/vo/StoreHouseRespVO.java @@ -1,14 +1,14 @@ package com.ningxia.yunxi.chemmes.module.biz.controller.admin.storehouse.vo; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; -import java.util.*; -import java.util.*; -import org.springframework.format.annotation.DateTimeFormat; -import java.time.LocalDateTime; -import com.alibaba.excel.annotation.*; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import com.fasterxml.jackson.annotation.JsonFormat; import com.ningxia.yunxi.chemmes.framework.excel.core.annotations.DictFormat; import com.ningxia.yunxi.chemmes.framework.excel.core.convert.DictConvert; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; @Schema(description = "管理后台 - 仓储主数据 Response VO") @Data @@ -21,6 +21,7 @@ public class StoreHouseRespVO { @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("创建时间") + @JsonFormat(pattern = "yyyy-MM-dd") private LocalDateTime createTime; @Schema(description = "仓储编码") @@ -45,4 +46,4 @@ public class StoreHouseRespVO { @DictFormat("warehouse_type") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 private String storeType; -} \ No newline at end of file +} diff --git a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/mysql/saledelivery/SaleDeliveryMapper.java b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/mysql/saledelivery/SaleDeliveryMapper.java index a9c53c2..359d0db 100644 --- a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/mysql/saledelivery/SaleDeliveryMapper.java +++ b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/mysql/saledelivery/SaleDeliveryMapper.java @@ -17,8 +17,8 @@ public interface SaleDeliveryMapper extends BaseMapperX { default PageResult selectPage(SaleDeliveryPageReqVO reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX() - .betweenIfPresent(SaleDeliveryDO::getCreateTime, reqVO.getCreateTime()) .likeIfPresent(SaleDeliveryDO::getSaleDeliveryNo, reqVO.getSaleDeliveryNo()) + .likeIfPresent(SaleDeliveryDO::getCustName, reqVO.getCustName()) .betweenIfPresent(SaleDeliveryDO::getDeliveryDate, reqVO.getDeliveryDate()) .eqIfPresent(SaleDeliveryDO::getDeliveryStatus, reqVO.getDeliveryStatus()) .eqIfPresent(SaleDeliveryDO::getDeliveryType, reqVO.getDeliveryType()) diff --git a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/mysql/storehouse/StoreHouseMapper.java b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/mysql/storehouse/StoreHouseMapper.java index c6c38b9..78ab4de 100644 --- a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/mysql/storehouse/StoreHouseMapper.java +++ b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/dal/mysql/storehouse/StoreHouseMapper.java @@ -1,14 +1,14 @@ package com.ningxia.yunxi.chemmes.module.biz.dal.mysql.storehouse; -import java.util.*; - import cn.hutool.core.util.ObjectUtil; import com.ningxia.yunxi.chemmes.framework.common.pojo.PageResult; -import com.ningxia.yunxi.chemmes.framework.mybatis.core.query.LambdaQueryWrapperX; import com.ningxia.yunxi.chemmes.framework.mybatis.core.mapper.BaseMapperX; +import com.ningxia.yunxi.chemmes.framework.mybatis.core.query.LambdaQueryWrapperX; +import com.ningxia.yunxi.chemmes.module.biz.controller.admin.storehouse.vo.StoreHousePageReqVO; import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.storehouse.StoreHouseDO; import org.apache.ibatis.annotations.Mapper; -import com.ningxia.yunxi.chemmes.module.biz.controller.admin.storehouse.vo.*; + +import java.util.List; /** * 仓储主数据 Mapper @@ -26,13 +26,15 @@ public interface StoreHouseMapper extends BaseMapperX { .orderByDesc(StoreHouseDO::getId)); } - default Long selectByStoreHouseCodeCount(String storeHouseCd,Integer id){ + default Long selectByStoreHouseCodeCount(String storeHouseCd, Integer id) { return selectCount(new LambdaQueryWrapperX() - .eq(StoreHouseDO::getStoreHouseCd, storeHouseCd).ne(ObjectUtil.isNotEmpty(id),StoreHouseDO::getId,id)); + .eq(StoreHouseDO::getStoreHouseCd, storeHouseCd).ne(ObjectUtil.isNotEmpty(id), StoreHouseDO::getId, id)); } - default List getStoreHouseSelect(){ + default List getStoreHouseSelect(String storeType) { return selectList(new LambdaQueryWrapperX() - .eq(StoreHouseDO::getEnabledStatus, 0)); + .eq(StoreHouseDO::getEnabledStatus, 0) + .eqIfPresent(StoreHouseDO::getStoreType, storeType)); + } } diff --git a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/service/storehouse/StoreHouseService.java b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/service/storehouse/StoreHouseService.java index d2d25f2..295d698 100644 --- a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/service/storehouse/StoreHouseService.java +++ b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/service/storehouse/StoreHouseService.java @@ -1,11 +1,12 @@ package com.ningxia.yunxi.chemmes.module.biz.service.storehouse; -import java.util.*; -import javax.validation.*; -import com.ningxia.yunxi.chemmes.module.biz.controller.admin.storehouse.vo.*; -import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.storehouse.StoreHouseDO; import com.ningxia.yunxi.chemmes.framework.common.pojo.PageResult; -import com.ningxia.yunxi.chemmes.framework.common.pojo.PageParam; +import com.ningxia.yunxi.chemmes.module.biz.controller.admin.storehouse.vo.StoreHousePageReqVO; +import com.ningxia.yunxi.chemmes.module.biz.controller.admin.storehouse.vo.StoreHouseSaveReqVO; +import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.storehouse.StoreHouseDO; + +import javax.validation.Valid; +import java.util.List; /** * 仓储主数据 Service 接口 @@ -52,5 +53,5 @@ public interface StoreHouseService { */ PageResult getStoreHousePage(StoreHousePageReqVO pageReqVO); - List getStoreHouseSelect(); + List getStoreHouseSelect(String storeType); } diff --git a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/service/storehouse/StoreHouseServiceImpl.java b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/service/storehouse/StoreHouseServiceImpl.java index f4bf1c8..39c67c5 100644 --- a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/service/storehouse/StoreHouseServiceImpl.java +++ b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/service/storehouse/StoreHouseServiceImpl.java @@ -79,8 +79,8 @@ public class StoreHouseServiceImpl implements StoreHouseService { } @Override - public List getStoreHouseSelect() { - return storeHouseMapper.getStoreHouseSelect(); + public List getStoreHouseSelect(String storeType) { + return storeHouseMapper.getStoreHouseSelect(storeType); } } diff --git a/mes-ui/mes-ui-admin-vue3/src/api/biz/storehouse/index.ts b/mes-ui/mes-ui-admin-vue3/src/api/biz/storehouse/index.ts index 70367c8..be4cbe8 100644 --- a/mes-ui/mes-ui-admin-vue3/src/api/biz/storehouse/index.ts +++ b/mes-ui/mes-ui-admin-vue3/src/api/biz/storehouse/index.ts @@ -39,6 +39,6 @@ export const exportStoreHouse = async (params) => { return await request.download({ url: `/biz/store-house/export-excel`, params }) } //获取仓储主数据下拉列表 -export const getStoreHouseSelect = async () => { - return await request.get({ url: `/biz/store-house/get-store-house-select`}) +export const getStoreHouseSelect = async (storeType?: string) => { + return await request.get({ url: `/biz/store-house/get-store-house-select`, params: { storeType }}) } diff --git a/mes-ui/mes-ui-admin-vue3/src/utils/formatTime.ts b/mes-ui/mes-ui-admin-vue3/src/utils/formatTime.ts index f252ee0..38ec2a4 100644 --- a/mes-ui/mes-ui-admin-vue3/src/utils/formatTime.ts +++ b/mes-ui/mes-ui-admin-vue3/src/utils/formatTime.ts @@ -355,6 +355,13 @@ export function getCurrentMonthRange(): [string, string] { now.endOf('day').format('YYYY-MM-DD HH:mm:ss') ] } +export function getCurrentSimMonthRange(): [string, string] { + const now = dayjs() + return [ + now.startOf('month').format('YYYY-MM-DD'), + now.endOf('day').format('YYYY-MM-DD') + ] +} /** * 获取日期范围 diff --git a/mes-ui/mes-ui-admin-vue3/src/views/biz/prostorageinventory/ProStorageInventorySelectDialog.vue b/mes-ui/mes-ui-admin-vue3/src/views/biz/prostorageinventory/ProStorageInventorySelectDialog.vue index c52a688..9b5d53b 100644 --- a/mes-ui/mes-ui-admin-vue3/src/views/biz/prostorageinventory/ProStorageInventorySelectDialog.vue +++ b/mes-ui/mes-ui-admin-vue3/src/views/biz/prostorageinventory/ProStorageInventorySelectDialog.vue @@ -58,11 +58,16 @@ - + - + + + + @@ -90,9 +95,23 @@ import * as InventoryApi from '@/api/biz/prostorageinventory' import * as StoreHouseApi from '@/api/biz/storehouse' import * as StoreAreaApi from '@/api/biz/storearea' import { useMessage } from '@/hooks/web/useMessage' +import { getDictOptions } from '@/utils/dict' const message = useMessage() +// 单位数据字典 +const unitOptions = ref([]) + +// 获取单位名称 +const getUnitName = (unit: string | number) => { + if (!unit && unit !== 0) return '-' + const item = unitOptions.value.find(opt => String(opt.value) === String(unit)) + return item ? item.label : unit +} + +// 初始化单位字典 +unitOptions.value = getDictOptions('mat_unit') + const dialogVisible = ref(false) const loading = ref(false) const inventoryList = ref([]) @@ -114,27 +133,20 @@ const queryParams = reactive({ pageSize: 10, storeHouseId: undefined, storeAreaId: undefined, - matName: undefined, - spec: undefined, }) -// 仓储列表(条件:store_type = '3' and enabled_status = 1) +// 仓储列表(条件:store_type = '3' ) const storeHouseList = ref([]) -// 库区列表(条件:store_house_id = 选中的仓储ID and enabled_status = 1) +// 库区列表(条件:store_house_id = 选中的仓储ID ) const storeAreaList = ref([]) /** 获取仓储列表 */ const getStoreHouseList = async () => { try { - // 使用分页接口,传入条件:store_type = '3' and enabled_status = 1 - const data = await StoreHouseApi.getStoreHousePage({ - storeType: '3', - enabledStatus: 1, - pageNo: 1, - pageSize: 100, - }) - storeHouseList.value = data.list || [] + // 使用专用下拉接口:get-store-house-select,条件:store_type = '3' + const data = await StoreHouseApi.getStoreHouseSelect('3') + storeHouseList.value = data || [] } catch (error) { console.error('获取仓储列表失败:', error) storeHouseList.value = [] @@ -147,14 +159,9 @@ const getStoreAreaList = async (storeHouseId?: number) => { if (!storeHouseId) return try { - // 使用分页接口,传入条件:store_house_id = 选中的仓储ID and enabled_status = 1 - const data = await StoreAreaApi.getStoreAreaPage({ - storeHouseId, - enabledStatus: 1, - pageNo: 1, - pageSize: 100, - }) - storeAreaList.value = data.list || [] + // 使用专用下拉接口:get-store-area-select,条件:store_house_id = 选中的仓储ID and enabled_status = 1 + const data = await StoreAreaApi.getStoreAreaSelect(storeHouseId) + storeAreaList.value = data || [] } catch (error) { console.error('获取库区列表失败:', error) storeAreaList.value = [] @@ -175,13 +182,6 @@ const getList = async () => { ...queryParams } - // 根据用户需求添加模糊查询条件 - if (queryParams.storeHouseId) { - params.storeHouseName = { like: '%仓库%' } - } - if (queryParams.storeAreaId) { - params.storeAreaName = { like: '%库区%' } - } const data = await InventoryApi.getProStorageInventoryPage(params) // 按批次号升序排列 @@ -230,6 +230,9 @@ const resetQuery = () => { queryParams.spec = undefined queryParams.pageNo = 1 storeAreaList.value = [] + // 重置时不自动查询,需手动点击搜索 + inventoryList.value = [] + total.value = 0 getList() } diff --git a/mes-ui/mes-ui-admin-vue3/src/views/biz/saledelivery/SaleDeliveryDetail.vue b/mes-ui/mes-ui-admin-vue3/src/views/biz/saledelivery/SaleDeliveryDetail.vue index 25c8e33..b70aafc 100644 --- a/mes-ui/mes-ui-admin-vue3/src/views/biz/saledelivery/SaleDeliveryDetail.vue +++ b/mes-ui/mes-ui-admin-vue3/src/views/biz/saledelivery/SaleDeliveryDetail.vue @@ -13,28 +13,30 @@ - + - - - {{ formData.deliveryStatus === '1' ? '已创建' : '已确认' }} - + + @@ -43,39 +45,39 @@ - + - + - + - + - + - + - + @@ -85,7 +87,7 @@ @@ -100,17 +102,17 @@ - + - + - + @@ -186,6 +188,9 @@ const totalQty = computed(() => { const deliveryTypeText = computed(() => { return formData.deliveryType === '1' ? '发货' : (formData.deliveryType === '2' ? '自提' : '-') }) +const deliveryStatusText = computed(() => { + return formData.deliveryStatus === '1' ? '已创建' : (formData.deliveryStatus === '2' ? '已确认' : '-') +}) const getSummary = (param: any) => { const { columns, data } = param diff --git a/mes-ui/mes-ui-admin-vue3/src/views/biz/saledelivery/SaleDeliveryForm.vue b/mes-ui/mes-ui-admin-vue3/src/views/biz/saledelivery/SaleDeliveryForm.vue index 443d667..e2df283 100644 --- a/mes-ui/mes-ui-admin-vue3/src/views/biz/saledelivery/SaleDeliveryForm.vue +++ b/mes-ui/mes-ui-admin-vue3/src/views/biz/saledelivery/SaleDeliveryForm.vue @@ -115,7 +115,20 @@ - + + + @@ -143,17 +156,17 @@ @@ -232,6 +245,7 @@ import { ref, reactive, computed } from 'vue' import * as SaleDeliveryApi from '@/api/biz/saledelivery' import * as OrderApi from '@/api/biz/tsoorder' import * as CustomerApi from '@/api/biz/customer' +import * as InventoryApi from '@/api/biz/prostorageinventory' import { watch } from 'vue' import OrderSelectDialog from './OrderSelectDialog.vue' import ProStorageInventorySelectDialog from '../prostorageinventory/ProStorageInventorySelectDialog.vue' @@ -274,6 +288,12 @@ const formData = reactive({ contact: undefined, conPhone: undefined, conAddress: undefined, + contact1: undefined, + conPhone1: undefined, + conAddress1: undefined, + contact2: undefined, + conPhone2: undefined, + conAddress2: undefined, remark: undefined, saleOrdId: undefined, saleOrdNo: undefined, @@ -289,6 +309,41 @@ const formData = reactive({ deliveriedQty: undefined, }) +// 联系人选项列表 +const contactOptions = computed(() => { + const options = [] + if (formData.contact1) { + options.push({ + label: formData.contact1, + value: '1', + phone: formData.conPhone1, + address: formData.conAddress1 + }) + } + if (formData.contact2) { + options.push({ + label: formData.contact2, + value: '2', + phone: formData.conPhone2, + address: formData.conAddress2 + }) + } + return options +}) + +// 联系人选择变更处理 +const handleContactChange = (value: string) => { + if (value === '1') { + formData.contact = formData.contact1 + formData.conPhone = formData.conPhone1 + formData.conAddress = formData.conAddress1 + } else if (value === '2') { + formData.contact = formData.contact2 + formData.conPhone = formData.conPhone2 + formData.conAddress = formData.conAddress2 + } +} + // 产品列表 const productList = ref([]) @@ -359,16 +414,6 @@ const formRules = reactive({ deliveryStatus: [{ required: true, message: '单据状态不能为空', trigger: 'change' }], deliveriedQty: [ { required: true, message: '发货数量不能为空', trigger: 'change' }, - { - validator: (rule, value, callback) => { - if (value && formData.remaimQty !== undefined && Number(value) > Number(formData.remaimQty)) { - callback(new Error(`发货数量不能大于剩余数量(${formData.remaimQty})`)) - } else { - callback() - } - }, - trigger: ['change', 'blur'] - } ], custName: [{ required: true, message: '客户名称不能为空', trigger: 'change' }], materialName: [{ required: true, message: '产品名称不能为空', trigger: 'change' }], @@ -394,6 +439,40 @@ const open = async (type: string, id?: number) => { try { const data = await SaleDeliveryApi.getSaleDelivery(id) Object.assign(formData, data) + + // 保存两个联系人的信息 + formData.contact1 = data.contact1 + formData.conPhone1 = data.conPhone1 + formData.conAddress1 = data.conAddress1 + formData.contact2 = data.contact2 + formData.conPhone2 = data.conPhone2 + formData.conAddress2 = data.conAddress2 + + // 判断当前选择的联系人 + // 注意:后端返回的 contact 可能是联系人名称,也可能是 '1' 或 '2' + const originalContact = data.contact + if (originalContact === '1' || (data.contact1 && originalContact === data.contact1)) { + formData.contact = '1' + formData.conPhone = data.conPhone1 || data.conPhone + formData.conAddress = data.conAddress1 || data.conAddress + } else if (originalContact === '2' || (data.contact2 && originalContact === data.contact2)) { + formData.contact = '2' + formData.conPhone = data.conPhone2 || data.conPhone + formData.conAddress = data.conAddress2 || data.conAddress + } else { + // 如果都不匹配,且有contact1,则默认选择contact1 + if (data.contact1) { + formData.contact = '1' + formData.conPhone = data.conPhone1 + formData.conAddress = data.conAddress1 + } + } + + // 如果客户ID存在,从客户信息获取联系人(如果发货单数据中没有联系人信息) + if (data.custId && (!data.contact1 && !data.contact2)) { + await loadCustomerContact(data.custId) + } + // 加载产品列表 - 支持多种字段名,并映射字段 let itemsData = [] if (data.items && data.items.length > 0) { @@ -481,7 +560,6 @@ const openOrderSelect = () => { /** 处理订单选择 */ const handleOrderSelect = async (data: any) => { - console.log('handleOrderSelect data:', data) formData.saleOrdId = data.saleOrdId formData.saleOrdNo = data.saleOrdNo formData.custId = data.custId @@ -495,28 +573,6 @@ const handleOrderSelect = async (data: any) => { formData.deliveriedQty = data.remaimQty formData.unit = data.unit - // 将订单日期带入到单据日期 - if (data.ordDate) { - // 确保日期格式为 YYYY-MM-DD 字符串类型 - const ordDateStr = String(data.ordDate).trim() - if (/^\d{4}-\d{2}-\d{2}$/.test(ordDateStr)) { - formData.deliveryDate = ordDateStr - } else { - try { - const date = new Date(data.ordDate) - if (!isNaN(date.getTime())) { - formData.deliveryDate = date.toISOString().split('T')[0] - } - } catch (e) { - console.warn('日期转换失败:', e) - } - } - } else { - // 如果没有订单日期,清空单据日期 - formData.deliveryDate = null - } - console.log('formData after set:', formData) - // 添加到选项列表以便显示 if (!saleOrderOptions.value.find(item => item.id === data.saleOrdId)) { saleOrderOptions.value.push({ @@ -531,8 +587,20 @@ const handleOrderSelect = async (data: any) => { }) } - // 只有在新增模式下才查询客户联系人信息(编辑模式下已有数据) - if (data.custId && formType.value === 'create') { + // 先清空联系人信息,然后查询客户联系人信息 + if (data.custId) { + // 清空之前的联系人信息 + formData.contact1 = undefined + formData.conPhone1 = undefined + formData.conAddress1 = undefined + formData.contact2 = undefined + formData.conPhone2 = undefined + formData.conAddress2 = undefined + formData.contact = undefined + formData.conPhone = undefined + formData.conAddress = undefined + + // 查询客户联系人信息 await loadCustomerContact(data.custId) } } @@ -542,10 +610,24 @@ const loadCustomerContact = async (custId: number) => { try { const customer = await CustomerApi.getCustomer(custId) if (customer) { + // 保存两个联系人的信息 + formData.contact1 = customer.contact1 + formData.conPhone1 = customer.conPhone1 + formData.conAddress1 = customer.conAddress1 + formData.contact2 = customer.contact2 + formData.conPhone2 = customer.conPhone2 + formData.conAddress2 = customer.conAddress2 + // 优先使用contact1,如果为空则使用contact2 - formData.contact = customer.contact1 || customer.contact2 - formData.conPhone = customer.conPhone1 || customer.conPhone2 - formData.conAddress = customer.conAddress1 || customer.conAddress2 + if (customer.contact1) { + formData.contact = '1' + formData.conPhone = customer.conPhone1 + formData.conAddress = customer.conAddress1 + } else if (customer.contact2) { + formData.contact = '2' + formData.conPhone = customer.conPhone2 + formData.conAddress = customer.conAddress2 + } } } catch (error) { console.error('查询客户联系人信息失败', error) @@ -609,15 +691,14 @@ const removeProductItem = (index: number) => { const emit = defineEmits(['success', 'close']) /** 验证发货数量 */ -const validateDeliveryQty = () => { - const remaimQty = parseInt(formData.remaimQty) || 0 +const validateDeliveryQty = async () => { const totalDeliveriedQty = totalQty.value // 验证每个产品项的发货袋数和发货数量不能为空且必须大于0 for (let i = 0; i < productList.value.length; i++) { const item = productList.value[i] - const deliveriedBag = parseInt(item.deliveriedBag) || 0 - const deliveriedQty = parseInt(item.deliveriedQty) || 0 + const deliveriedBag = parseFloat(item.deliveriedBag) || 0 + const deliveriedQty = parseFloat(item.deliveriedQty) || 0 if (!item.deliveriedBag || deliveriedBag <= 0) { message.warning(`第${i + 1}行:发货袋数不能为空且必须大于0`) @@ -630,16 +711,76 @@ const validateDeliveryQty = () => { } } - if (totalDeliveriedQty > remaimQty) { - message.warning(`发货总数量(${totalDeliveriedQty})不能超过剩余数量(${remaimQty})`) + // 1. 验证订单剩余数量:ord_qty - deliveried_qty >= 发货数量 + if (formData.saleOrdId && formData.materialName) { + try { + const orderDetail = await OrderApi.getOrder(formData.saleOrdId) + if (orderDetail && orderDetail.items) { + const item = orderDetail.items.find(i => + i.materialName === formData.materialName && + (!formData.spec || i.spec === formData.spec) + ) + if (item) { + const ordQty = parseFloat(item.ordQty) || 0 + const deliveriedQty = parseFloat(item.deliveriedQty) || 0 + const remainQty = ordQty - deliveriedQty + + if (isNaN(remainQty) || remainQty < totalDeliveriedQty) { + message.warning(`该订单产品剩余数量小于发货数量,请确认!`) + return false + } + } + } + } catch (error) { + console.error('查询订单剩余数量失败:', error) + } + } + + // 2. 验证明细表发货合计数量必须等于表单发货数量 + const formDeliveriedQty = parseFloat(formData.deliveriedQty) || 0 + if (totalDeliveriedQty !== formDeliveriedQty) { + message.warning(`产品发货数量跟出库单数量不一致,请确认!`) return false } - // 验证明细表发货合计数量必须等于表单发货数量 - const formDeliveriedQty = parseInt(formData.deliveriedQty) || 0 - if (totalDeliveriedQty !== formDeliveriedQty) { - message.warning(`明细表发货合计(${totalDeliveriedQty})必须等于表单发货数量(${formDeliveriedQty})`) - return false + // 3. 验证库存袋数:循环检查每个仓库、库区、批次号的库存袋数是否大于等于发货袋数 + const groupedByLot = {} + productList.value.forEach(item => { + const key = `${item.storeHouseId}-${item.storeAreaId}-${item.batchNo}` + if (!groupedByLot[key]) { + groupedByLot[key] = { + storeHouseName: item.warehouse, + storeAreaName: item.warehouseArea, + batchNo: item.batchNo, + totalDeliveriedBag: 0 + } + } + groupedByLot[key].totalDeliveriedBag += parseFloat(item.deliveriedBag) || 0 + }) + + for (const key in groupedByLot) { + const group = groupedByLot[key] + try { + const inventoryData = await InventoryApi.getProStorageInventoryPage({ + storeHouseId: key.split('-')[0], + storeAreaId: key.split('-')[1], + lotNo: group.batchNo, + pageNo: 1, + pageSize: 1 + }) + + const inventory = inventoryData.list && inventoryData.list[0] + const stockPackQty = inventory ? parseFloat(inventory.packQty) || 0 : 0 + + if (stockPackQty < group.totalDeliveriedBag) { + message.warning(`${group.storeHouseName} + ${group.storeAreaName} ${group.batchNo}库存袋数小于发货袋数,请确认!`) + return false + } + } catch (error) { + console.error('查询库存袋数失败:', error) + message.warning(`查询${group.storeHouseName} ${group.storeAreaName} ${group.batchNo}库存失败,请确认!`) + return false + } } return true @@ -647,7 +788,7 @@ const validateDeliveryQty = () => { const submitForm = async () => { // 校验发货数量 - if (!validateDeliveryQty()) { + if (!(await validateDeliveryQty())) { return } @@ -695,7 +836,7 @@ const submitForm = async () => { /** 提交确认 */ const submitAudit = async () => { // 校验发货数量 - if (!validateDeliveryQty()) { + if (!(await validateDeliveryQty())) { return } @@ -754,6 +895,14 @@ const resetForm = () => { contact: undefined, conPhone: undefined, conAddress: undefined, + // 清空联系人1信息 + contact1: undefined, + conPhone1: undefined, + conAddress1: undefined, + // 清空联系人2信息 + contact2: undefined, + conPhone2: undefined, + conAddress2: undefined, remark: undefined, saleOrdId: undefined, saleOrdNo: undefined, diff --git a/mes-ui/mes-ui-admin-vue3/src/views/biz/saledelivery/index.vue b/mes-ui/mes-ui-admin-vue3/src/views/biz/saledelivery/index.vue index 552eeb4..881f7df 100644 --- a/mes-ui/mes-ui-admin-vue3/src/views/biz/saledelivery/index.vue +++ b/mes-ui/mes-ui-admin-vue3/src/views/biz/saledelivery/index.vue @@ -156,21 +156,21 @@
出库单明细
- + - - - - - - + + + + + + - +
@@ -184,8 +184,7 @@