插活
This commit is contained in:
parent
060d627cba
commit
181dc83d4e
@ -98,6 +98,7 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode PLAN_SUB_NOT_EXISTS = new ErrorCode(1_007_002, "生产计划子项目不存在");
|
||||
ErrorCode PLAN_TASK_NOT_EXISTS = new ErrorCode(1_007_003, "生产计划任务不存在");
|
||||
ErrorCode PLAN_TASK_BOM_NOT_EXISTS = new ErrorCode(1_007_004, "生产计划任务Bom不存在");
|
||||
//1_007_005已被占用
|
||||
/************采购管理***********/
|
||||
ErrorCode MATERIAL_PLAN_NOT_EXISTS = new ErrorCode(1_008_001, "物料需求计划不存在");
|
||||
ErrorCode MATERIAL_PLAN_DETAIL_NOT_EXISTS = new ErrorCode(1_008_002, "物料需求计划物料详情不存在");
|
||||
|
||||
@ -94,7 +94,12 @@ public class PlanSubController {
|
||||
public CommonResult<Long> createPlanSub(@Valid @RequestBody PlanSubSaveReqVO createReqVO) {
|
||||
return success(planSubService.createPlanSub(createReqVO));
|
||||
}
|
||||
|
||||
@PostMapping("/operate")
|
||||
@Operation(summary = "创建生产计划子项目")
|
||||
@PreAuthorize("@ss.hasPermission('heli:plan-sub:create')")
|
||||
public void operate(@RequestBody List<PlanSubSaveReqVO> list) {
|
||||
planSubService.operate(list);
|
||||
}
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新生产计划子项目")
|
||||
@PreAuthorize("@ss.hasPermission('heli:plan-sub:update')")
|
||||
|
||||
@ -147,5 +147,7 @@ public class PlanSubRespVO {
|
||||
|
||||
@Schema(description = "设计类型")
|
||||
private int type;
|
||||
|
||||
private boolean hasSaveInBlankDetail;
|
||||
private boolean hasSaveIn2DDetail;
|
||||
private boolean hasSaveIn3DDetail;
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ import static com.chanko.yunxi.mes.framework.common.util.date.DateUtils.FORMAT_Y
|
||||
@Data
|
||||
public class PlanSubSaveReqVO {
|
||||
|
||||
@Schema(description = "自增字段,唯一", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "自增字段,唯一")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "计划id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ -27,7 +27,7 @@ public class PlanSubSaveReqVO {
|
||||
|
||||
@Schema(description = "子项目id")
|
||||
private Long projectSubId;
|
||||
|
||||
private String name;
|
||||
@Schema(description = "子项目简称")
|
||||
private String projectSubShortName;
|
||||
|
||||
@ -80,5 +80,7 @@ public class PlanSubSaveReqVO {
|
||||
|
||||
@Schema(description = "3D负责人")
|
||||
private String threeDimOwner;
|
||||
|
||||
private boolean hasSaveInBlankDetail;
|
||||
private boolean hasSaveIn2DDetail;
|
||||
private boolean hasSaveIn3DDetail;
|
||||
}
|
||||
|
||||
@ -70,6 +70,8 @@ public class PlanSubDetailController {
|
||||
return success(BeanUtils.toBean(planSubDetail, PlanSubDetailRespVO.class));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得生产计划子项目设计时间明细分页")
|
||||
@PreAuthorize("@ss.hasPermission('heli:plan-sub-detail:query')")
|
||||
@ -77,7 +79,13 @@ public class PlanSubDetailController {
|
||||
PageResult<PlanSubDetailDO> pageResult = planSubDetailService.getPlanSubDetailPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, PlanSubDetailRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/queryMaxDetail")
|
||||
@Operation(summary = "获得生产计划子项目设计时间明细分页")
|
||||
@PreAuthorize("@ss.hasPermission('heli:plan-sub-detail:query')")
|
||||
public CommonResult<PlanSubDetailRespVO> queryMaxDetail(@Valid PlanSubDetailPageReqVO pageReqVO) {
|
||||
PlanSubDetailDO pageResult = planSubDetailService.queryMaxDetail(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, PlanSubDetailRespVO.class));
|
||||
}
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出生产计划子项目设计时间明细 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('heli:plan-sub-detail:export')")
|
||||
@ -102,6 +110,33 @@ public class PlanSubDetailController {
|
||||
public CommonResult modification(@Valid @RequestBody PlanSubDetailSaveReqVO updateReqVO) {
|
||||
return planSubDetailService.modification(updateReqVO);
|
||||
}
|
||||
@GetMapping("/pageAddList")
|
||||
@Operation(summary = "获得生产计划子项目设计时间明细分页")
|
||||
@PreAuthorize("@ss.hasPermission('heli:plan-sub-detail:query')")
|
||||
public CommonResult<PageResult<PlanSubDetailRespVO>> pageAddList(@Valid PlanSubDetailPageReqVO pageReqVO) {
|
||||
PageResult<PlanSubDetailDO> pageResult = planSubDetailService.getPlanList(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, PlanSubDetailRespVO.class));
|
||||
}
|
||||
@PostMapping("/chahuo")
|
||||
@Operation(summary = "插活排程")
|
||||
public CommonResult chahuo(@RequestBody PlanSubDetailSaveReqVO updateReqVO) {
|
||||
return planSubDetailService.chahuoList(updateReqVO);
|
||||
}
|
||||
@PostMapping("/savechahuo")
|
||||
@Operation(summary = "保存插活结果")
|
||||
public CommonResult savechahuo(@RequestBody PlanSubDetailSaveReqVO updateReqVO) {
|
||||
return planSubDetailService.savechahuoList(updateReqVO);
|
||||
}
|
||||
|
||||
@PostMapping("/operate")
|
||||
@Operation(summary = "操作页面总体数据")
|
||||
public CommonResult operate(@RequestBody PlanSubDetailSaveReqVO updateReqVO) {
|
||||
return planSubDetailService.operate(updateReqVO);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@PostMapping("/insertWork")
|
||||
@Operation(summary = "插活")
|
||||
public CommonResult insertWork(@Valid @RequestBody PlanSubDetailSaveReqVO updateReqVO) {
|
||||
|
||||
@ -62,7 +62,18 @@ public class PlanSubDetailPageReqVO extends PageParam {
|
||||
@Schema(description = "子项目名称,唯一", example = "张三")
|
||||
private String name;
|
||||
@Schema(description = "开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime startTime;
|
||||
@Schema(description = "是否是最大时间段")
|
||||
private Integer flag;
|
||||
}
|
||||
private String queryDate;
|
||||
|
||||
@Schema(description = "项目编码", example = "26785")
|
||||
private Long projectCode;
|
||||
@Schema(description = "子项目名称" ,example = "s")
|
||||
private String projectSubName;
|
||||
|
||||
private String customerBrief;
|
||||
private String projectName;
|
||||
private String planNo;
|
||||
}
|
||||
|
||||
@ -16,11 +16,11 @@ public class PlanSubDetailRespVO {
|
||||
@Schema(description = "自增字段,唯一", requiredMode = Schema.RequiredMode.REQUIRED, example = "6922")
|
||||
@ExcelProperty("自增字段,唯一")
|
||||
private Long id;
|
||||
|
||||
private Integer flag;
|
||||
@Schema(description = "计划id", requiredMode = Schema.RequiredMode.REQUIRED, example = "13863")
|
||||
@ExcelProperty("计划id")
|
||||
private Long projectPlanId;
|
||||
|
||||
private Long projectPlanSubId;
|
||||
@Schema(description = "项目id", requiredMode = Schema.RequiredMode.REQUIRED, example = "11384")
|
||||
@ExcelProperty("项目id")
|
||||
private Long projectId;
|
||||
@ -56,7 +56,7 @@ public class PlanSubDetailRespVO {
|
||||
@Schema(description = "结束( 默认0 1结束)")
|
||||
@ExcelProperty("结束( 默认0 1结束)")
|
||||
private Boolean isOverProcess;
|
||||
|
||||
private Boolean userFlag = false;
|
||||
@Schema(description = "时间段顺序")
|
||||
@ExcelProperty("时间段顺序")
|
||||
private Long seqNo;
|
||||
@ -72,5 +72,12 @@ public class PlanSubDetailRespVO {
|
||||
@Schema(description = "子项目名称,唯一", example = "张三")
|
||||
@ExcelProperty("子项目名称,唯一")
|
||||
private String name;
|
||||
private LocalDateTime maxTime;
|
||||
|
||||
}
|
||||
|
||||
private String customerBrief;
|
||||
private String projectName;
|
||||
private String projectCode;
|
||||
private String planNo;
|
||||
private String projectSubName ;
|
||||
}
|
||||
|
||||
@ -13,14 +13,14 @@ import java.time.LocalDateTime;
|
||||
@Data
|
||||
public class PlanSubDetailSaveReqVO {
|
||||
|
||||
@Schema(description = "自增字段,唯一", requiredMode = Schema.RequiredMode.REQUIRED, example = "6922")
|
||||
@Schema(description = "自增字段,唯一", example = "6922")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "计划id", requiredMode = Schema.RequiredMode.REQUIRED, example = "13863")
|
||||
@Schema(description = "计划id", example = "13863")
|
||||
@NotNull(message = "计划id不能为空")
|
||||
private Long projectPlanId;
|
||||
|
||||
@Schema(description = "项目id", requiredMode = Schema.RequiredMode.REQUIRED, example = "11384")
|
||||
@Schema(description = "项目id", example = "11384")
|
||||
@NotNull(message = "项目id不能为空")
|
||||
private Long projectId;
|
||||
|
||||
@ -44,7 +44,7 @@ public class PlanSubDetailSaveReqVO {
|
||||
|
||||
@Schema(description = "结束( 默认0 1结束)")
|
||||
private Boolean isOverProcess;
|
||||
|
||||
private Long projectPlanSubId;
|
||||
@Schema(description = "时间段顺序")
|
||||
private Long seqNo;
|
||||
|
||||
@ -60,4 +60,5 @@ public class PlanSubDetailSaveReqVO {
|
||||
private String isAdd;
|
||||
@Schema(description = "是否新增")
|
||||
private List<PlanSubDetailDO> list;
|
||||
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import com.chanko.yunxi.mes.framework.common.pojo.PageResult;
|
||||
import com.chanko.yunxi.mes.framework.common.util.object.BeanUtils;
|
||||
import com.chanko.yunxi.mes.framework.excel.core.util.ExcelUtils;
|
||||
import com.chanko.yunxi.mes.framework.operatelog.core.annotations.OperateLog;
|
||||
import com.chanko.yunxi.mes.framework.tenant.core.aop.TenantIgnore;
|
||||
import com.chanko.yunxi.mes.module.heli.controller.admin.screen.vo.ScreenPageReqVO;
|
||||
import com.chanko.yunxi.mes.module.heli.controller.admin.screen.vo.ScreenRespVO;
|
||||
import com.chanko.yunxi.mes.module.heli.controller.admin.screen.vo.ScreenSaveReqVO;
|
||||
|
||||
@ -52,7 +52,12 @@ public class ShopCalendarController {
|
||||
PageResult<ShopCalendarDO> pageResult = shopCalendarService.searchRl(shopCalendarPageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, ShopCalendarRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/searchHoliday")
|
||||
@Operation(summary = "查询是否节假日")
|
||||
@PreAuthorize("@ss.hasPermission('heli:material:query')")
|
||||
public CommonResult<Boolean> searchHoliday(@Valid ShopCalendarPageReqVO shopCalendarPageReqVO) {
|
||||
return success(shopCalendarService.searchHoliday(shopCalendarPageReqVO));
|
||||
}
|
||||
@PostMapping("/insert")
|
||||
@Operation(summary = "新增日历")
|
||||
@Parameter(name = "dates", description = "年月", required = true)
|
||||
|
||||
@ -31,6 +31,8 @@ public class ShopCalendarPageReqVO extends PageParam {
|
||||
@Schema(description = "是否节假日")
|
||||
private String ifjiejiari;
|
||||
|
||||
private String queryDate;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@ -213,5 +213,10 @@ public class PlanSubDO extends BaseDO {
|
||||
private String businessLine;
|
||||
@TableField(exist = false)
|
||||
private int projectMonth;
|
||||
|
||||
@TableField(exist = false)
|
||||
private boolean hasSaveInBlankDetail;
|
||||
@TableField(exist = false)
|
||||
private boolean hasSaveIn3DDetail;
|
||||
@TableField(exist = false)
|
||||
private boolean hasSaveIn2DDetail;
|
||||
}
|
||||
|
||||
@ -87,5 +87,17 @@ public class PlanSubDetailDO extends BaseDO {
|
||||
private String isCha;
|
||||
@TableField(exist = false)
|
||||
private Integer flag;
|
||||
|
||||
}
|
||||
private Long projectPlanSubId;
|
||||
@TableField(exist = false)
|
||||
private LocalDateTime maxTime;
|
||||
@TableField(exist = false)
|
||||
private String twoDimOwnerName;
|
||||
@TableField(exist = false)
|
||||
private String projectSubName;
|
||||
@TableField(exist = false)
|
||||
private String customerBrief;
|
||||
@TableField(exist = false)
|
||||
private String projectName;
|
||||
@TableField(exist = false)
|
||||
private String planNo;
|
||||
}
|
||||
|
||||
@ -6,15 +6,19 @@ import cn.hutool.core.util.ObjectUtil;
|
||||
import com.chanko.yunxi.mes.framework.common.pojo.PageResult;
|
||||
import com.chanko.yunxi.mes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.chanko.yunxi.mes.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.chanko.yunxi.mes.framework.mybatis.core.query.MPJLambdaWrapperX;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.dataobject.customer.CustomerDO;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.dataobject.plan.PlanDO;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.dataobject.plansub.PlanSubDO;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.dataobject.plansubdetail.PlanSubDetailDO;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.dataobject.projectorder.ProjectOrderDO;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.dataobject.projectorder.ProjectOrderSubDO;
|
||||
import com.chanko.yunxi.mes.module.heli.enums.ProcessDesignTypeEnum;
|
||||
import com.chanko.yunxi.mes.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import com.chanko.yunxi.mes.module.heli.controller.admin.plansubdetail.vo.*;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@ -25,6 +29,16 @@ import org.springframework.util.StringUtils;
|
||||
@Mapper
|
||||
public interface PlanSubDetailMapper extends BaseMapperX<PlanSubDetailDO> {
|
||||
|
||||
default PageResult<PlanSubDetailDO> getPlanList(PlanSubDetailPageReqVO reqVO) {
|
||||
MPJLambdaWrapper<PlanSubDetailDO> query = new MPJLambdaWrapper<>();
|
||||
query.selectAll(PlanSubDetailDO.class)
|
||||
.leftJoin(PlanDO.class,"pl",PlanDO::getId,PlanSubDetailDO::getProjectPlanId)
|
||||
.select("pl.brief as customerBrief,pl.project_name as projectName,pl.code as projectCode,pl.plan_no as planNo")
|
||||
.eq(ObjectUtil.isNotEmpty(reqVO.getProjectCode()), PlanDO::getCode, reqVO.getProjectCode())
|
||||
.eq(ObjectUtil.isNotEmpty(reqVO.getProjectSubName()), PlanSubDetailDO::getName, reqVO.getProjectSubName());
|
||||
|
||||
return selectPage(reqVO, query);
|
||||
}
|
||||
default PageResult<PlanSubDetailDO> selectPage(PlanSubDetailPageReqVO reqVO) {
|
||||
MPJLambdaWrapper<PlanSubDetailDO> query = new MPJLambdaWrapper<>();
|
||||
|
||||
@ -34,12 +48,24 @@ public interface PlanSubDetailMapper extends BaseMapperX<PlanSubDetailDO> {
|
||||
.like(ObjectUtil.isNotEmpty(reqVO.getCode()), PlanSubDetailDO::getCode, reqVO.getCode())
|
||||
.like(ObjectUtil.isNotEmpty(reqVO.getName()), PlanSubDetailDO::getName, reqVO.getName())
|
||||
.eq(ObjectUtil.isNotEmpty(reqVO.getSubType()), PlanSubDetailDO::getSubType, reqVO.getSubType())
|
||||
.and(QueryWrapper -> QueryWrapper.gt(PlanSubDetailDO::getStartTwoDimDate, reqVO.getStartTime())
|
||||
.and(ObjectUtil.isNotEmpty(reqVO.getStartTime()),QueryWrapper -> QueryWrapper.ge(PlanSubDetailDO::getStartTwoDimDate, reqVO.getStartTime())
|
||||
.or()
|
||||
.lt( PlanSubDetailDO::getTwoDimDate, reqVO.getStartTime()))
|
||||
.ge( PlanSubDetailDO::getTwoDimDate, reqVO.getStartTime()))
|
||||
.in(PlanSubDetailDO::getIsOverProcess,0,2);
|
||||
|
||||
return selectPage(reqVO, query);
|
||||
}
|
||||
|
||||
}
|
||||
default List<PlanSubDetailDO> selectExistList(HashSet<String> ownerList) {
|
||||
MPJLambdaWrapper<PlanSubDetailDO> query = new MPJLambdaWrapper<>();
|
||||
query.selectAll(PlanSubDetailDO.class)
|
||||
.select("psub.name as name")
|
||||
.select("ad.nickname as twoDimOwnerName")
|
||||
.leftJoin(PlanSubDO.class,"psub",PlanSubDO::getId,PlanSubDetailDO::getProjectPlanSubId)
|
||||
.leftJoin(AdminUserDO.class,"ad",AdminUserDO::getId,PlanSubDetailDO::getTwoDimOwner)
|
||||
.in(PlanSubDetailDO::getTwoDimOwner,ownerList)
|
||||
.in(PlanSubDetailDO::getIsOverProcess,0,2);
|
||||
return selectList(query);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -23,6 +23,8 @@ public interface PlanSubService {
|
||||
*/
|
||||
Long createPlanSub(@Valid PlanSubSaveReqVO createReqVO);
|
||||
|
||||
|
||||
void operate(List<PlanSubSaveReqVO> list);
|
||||
/**
|
||||
* 更新生产计划子项目
|
||||
*
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
package com.chanko.yunxi.mes.module.heli.service.plansub;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.chanko.yunxi.mes.framework.common.exception.ErrorCode;
|
||||
import com.chanko.yunxi.mes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.chanko.yunxi.mes.module.heli.controller.admin.shopCalendar.vo.ShopCalendarPageReqVO;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.dataobject.plansubdetail.PlanSubDetailDO;
|
||||
@ -12,6 +14,7 @@ import com.chanko.yunxi.mes.module.heli.dal.dataobject.shopCalendar.ShopCalendar
|
||||
import com.chanko.yunxi.mes.module.heli.dal.mysql.plansubdetail.PlanSubDetailMapper;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.mysql.processbom.ProcessBomMapper;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.mysql.projectorder.ProjectOrderMapper;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.mysql.projectorder.ProjectOrderSubMapper;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.mysql.shopCalendar.ShopCalendarMapper;
|
||||
import jodd.util.StringUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -62,6 +65,218 @@ public class PlanSubServiceImpl implements PlanSubService {
|
||||
return planSub.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void operate(List<PlanSubSaveReqVO> list) {
|
||||
HashSet<String> userIds = new HashSet<>();
|
||||
List<PlanSubSaveReqVO> inserList = new ArrayList<>();
|
||||
for (PlanSubSaveReqVO planSubSaveReqVO : list) {
|
||||
|
||||
if (planSubSaveReqVO.isHasSaveInBlankDetail() && planSubSaveReqVO.isHasSaveIn2DDetail() && planSubSaveReqVO.isHasSaveIn3DDetail()){
|
||||
|
||||
}else{
|
||||
inserList.add(planSubSaveReqVO);
|
||||
}
|
||||
if (planSubSaveReqVO.getTwoDimOwner() != null) {
|
||||
userIds.add(planSubSaveReqVO.getTwoDimOwner());
|
||||
}
|
||||
if (planSubSaveReqVO.getThreeDimOwner() != null) {
|
||||
userIds.add(planSubSaveReqVO.getThreeDimOwner());
|
||||
}
|
||||
if (planSubSaveReqVO.getBlankOwner() != null) {
|
||||
userIds.add(planSubSaveReqVO.getBlankOwner());
|
||||
}
|
||||
}
|
||||
List<PlanSubDetailDO> planSubDetailDOS = planSubDetailMapper.selectExistList(userIds);
|
||||
List<PlanSubDetailDO> insertList = new ArrayList<>();
|
||||
//检查冲突
|
||||
checkForConflicts(list,planSubDetailDOS);
|
||||
List<PlanSubDO> bean = BeanUtils.toBean(list, PlanSubDO.class);
|
||||
planSubMapper.updateBatch(bean);
|
||||
if (CollUtil.isNotEmpty(inserList)){
|
||||
for (PlanSubSaveReqVO planSubSaveReqVO : inserList) {
|
||||
ProjectOrderDO projectOrderDO = projectOrderMapper.selectById(planSubSaveReqVO.getProjectId());
|
||||
List<PlanSubDetailDO> details = new ArrayList<>();
|
||||
if (planSubSaveReqVO.getBlankDate() != null && !planSubSaveReqVO.isHasSaveInBlankDetail()){
|
||||
//判断存不存在
|
||||
PlanSubDetailDO inBlankDO = new PlanSubDetailDO();
|
||||
inBlankDO.setProjectPlanId(planSubSaveReqVO.getProjectPlanId());
|
||||
inBlankDO.setProjectId(planSubSaveReqVO.getProjectId());
|
||||
inBlankDO.setProjectPlanSubId(planSubSaveReqVO.getId());
|
||||
inBlankDO.setProjectSubCode(planSubSaveReqVO.getProjectSubCode());
|
||||
inBlankDO.setTwoDimDate(planSubSaveReqVO.getBlankDate());
|
||||
inBlankDO.setProjectSubId(planSubSaveReqVO.getProjectSubId());
|
||||
inBlankDO.setStartTwoDimDate(planSubSaveReqVO.getStartBlankDate());
|
||||
inBlankDO.setTwoDimOwner(Long.valueOf(planSubSaveReqVO.getBlankOwner()));
|
||||
inBlankDO.setProjectPlanId(planSubSaveReqVO.getProjectPlanId());
|
||||
inBlankDO.setSubType("BLUEPRINT_WORKBLANK");
|
||||
inBlankDO.setSeqNo(1L);
|
||||
inBlankDO.setDesignNum(Long.valueOf(planSubSaveReqVO.getBlankNum()));
|
||||
inBlankDO.setName(planSubSaveReqVO.getName());
|
||||
inBlankDO.setCode(projectOrderDO.getCode());
|
||||
details.add(inBlankDO);
|
||||
}
|
||||
if (planSubSaveReqVO.getTwoDimDate() != null && !planSubSaveReqVO.isHasSaveIn2DDetail()){
|
||||
PlanSubDetailDO in2DDO = new PlanSubDetailDO();
|
||||
in2DDO.setProjectPlanId(planSubSaveReqVO.getProjectPlanId());
|
||||
in2DDO.setProjectId(planSubSaveReqVO.getProjectId());
|
||||
in2DDO.setProjectSubId(planSubSaveReqVO.getProjectSubId());
|
||||
in2DDO.setProjectPlanSubId(planSubSaveReqVO.getId());
|
||||
in2DDO.setProjectSubCode(planSubSaveReqVO.getProjectSubCode());
|
||||
in2DDO.setTwoDimDate(planSubSaveReqVO.getTwoDimDate());
|
||||
in2DDO.setProjectPlanId(planSubSaveReqVO.getProjectPlanId());
|
||||
in2DDO.setStartTwoDimDate(planSubSaveReqVO.getStartTwoDimDate());
|
||||
in2DDO.setTwoDimOwner(Long.valueOf(planSubSaveReqVO.getBlankOwner()));
|
||||
in2DDO.setSubType("BLUEPRINT_2D");
|
||||
in2DDO.setSeqNo(1L);
|
||||
in2DDO.setDesignNum(Long.valueOf(planSubSaveReqVO.getBlankNum()));
|
||||
in2DDO.setName(planSubSaveReqVO.getName());
|
||||
in2DDO.setCode(projectOrderDO.getCode());
|
||||
details.add(in2DDO);
|
||||
}
|
||||
|
||||
if (planSubSaveReqVO.getThreeDimDate() != null && !planSubSaveReqVO.isHasSaveIn3DDetail()){
|
||||
PlanSubDetailDO in3DDO = new PlanSubDetailDO();
|
||||
in3DDO.setProjectPlanId(planSubSaveReqVO.getProjectPlanId());
|
||||
in3DDO.setProjectId(planSubSaveReqVO.getProjectId());
|
||||
in3DDO.setProjectPlanSubId(planSubSaveReqVO.getId());
|
||||
in3DDO.setProjectPlanId(planSubSaveReqVO.getProjectPlanId());
|
||||
in3DDO.setProjectSubId(planSubSaveReqVO.getProjectSubId());
|
||||
in3DDO.setProjectSubCode(planSubSaveReqVO.getProjectSubCode());
|
||||
in3DDO.setTwoDimDate(planSubSaveReqVO.getThreeDimDate());
|
||||
in3DDO.setStartTwoDimDate(planSubSaveReqVO.getStartThreeDimDate());
|
||||
in3DDO.setTwoDimOwner(Long.valueOf(planSubSaveReqVO.getBlankOwner()));
|
||||
in3DDO.setSubType("BLUEPRINT_3D");
|
||||
in3DDO.setSeqNo(1L);
|
||||
in3DDO.setDesignNum(Long.valueOf(planSubSaveReqVO.getBlankNum()));
|
||||
in3DDO.setName(planSubSaveReqVO.getName());
|
||||
in3DDO.setCode(projectOrderDO.getCode());
|
||||
details.add(in3DDO);
|
||||
}
|
||||
//把这个底下的都查出来
|
||||
planSubDetailMapper.insertOrUpdateBatch(details);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查任务冲突
|
||||
* @param processTasks list1, 新的工艺任务列表
|
||||
* @param existingTasks list2, 已存在的任务列表
|
||||
* @throws RuntimeException 如果发现任何时间冲突
|
||||
*/
|
||||
public void checkForConflicts(List<PlanSubSaveReqVO> processTasks, List<PlanSubDetailDO> existingTasks) {
|
||||
// 为了提高查询效率,将 list2 按 Owner 转换为 Map
|
||||
Map<Long, List<PlanSubDetailDO>> tasksByOwner = new HashMap<>();
|
||||
for (PlanSubDetailDO task : existingTasks) {
|
||||
tasksByOwner.computeIfAbsent(task.getTwoDimOwner(), k -> new ArrayList<>()).add(task);
|
||||
}
|
||||
|
||||
// 1. 检查 list1 内部的时间冲突
|
||||
checkInternalConflicts(processTasks);
|
||||
|
||||
// 2. 检查 list1 与 list2 之间的时间冲突
|
||||
checkExternalConflicts(processTasks, tasksByOwner);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查 list1 内部,同一责任人负责的工艺时间是否有交集
|
||||
*/
|
||||
private void checkInternalConflicts(List<PlanSubSaveReqVO> processTasks) {
|
||||
// 将每个工艺任务拆分成独立的任务项,方便统一检查
|
||||
List<TaskItem> allNewItems = new ArrayList<>();
|
||||
for (PlanSubSaveReqVO task : processTasks) {
|
||||
if (!task.isHasSaveInBlankDetail() && task.getBlankOwner() != null && task.getStartBlankDate() != null && task.getBlankDate() != null) {
|
||||
allNewItems.add(new TaskItem(Long.valueOf(task.getBlankOwner()), task.getStartBlankDate(), task.getBlankDate(), "毛坯",task.getProjectNameSim()));
|
||||
}
|
||||
if (!task.isHasSaveIn2DDetail() && task.getTwoDimOwner() != null && task.getStartTwoDimDate() != null && task.getTwoDimDate() != null) {
|
||||
allNewItems.add(new TaskItem(Long.valueOf(task.getTwoDimOwner()), task.getStartTwoDimDate(), task.getTwoDimDate(), "2D",task.getProjectSubShortName()));
|
||||
}
|
||||
if (!task.isHasSaveIn3DDetail() && task.getThreeDimOwner() != null && task.getStartThreeDimDate() != null && task.getThreeDimDate() != null) {
|
||||
allNewItems.add(new TaskItem(Long.valueOf(task.getThreeDimOwner()), task.getStartThreeDimDate(), task.getThreeDimDate(), "3D",task.getProjectSubShortName()));
|
||||
}
|
||||
}
|
||||
|
||||
// 对所有新任务项进行两两比较
|
||||
for (int i = 0; i < allNewItems.size(); i++) {
|
||||
TaskItem item1 = allNewItems.get(i);
|
||||
for (int j = i + 1; j < allNewItems.size(); j++) {
|
||||
TaskItem item2 = allNewItems.get(j);
|
||||
// 只检查同一个责任人负责的任务
|
||||
if (item1.owner.equals(item2.owner)) {
|
||||
if (hasOverlap(item1.start, item1.end, item2.start, item2.end)) {
|
||||
throw exception(new ErrorCode(1_007_006,"当前插入:"+item1.type+item1.start.toString().substring(0,10)+" -"+item1.end.toString().substring(0,10)+"跟"+item2.type+item2.start.toString().substring(0,10)+item2.end.toString().substring(0,10)+"存在交集,请确认!"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查 list1 的新任务是否与 list2 中已存在的任务冲突
|
||||
*/
|
||||
private void checkExternalConflicts(List<PlanSubSaveReqVO> processTasks, Map<Long, List<PlanSubDetailDO>> tasksByOwner) {
|
||||
for (PlanSubSaveReqVO newTask : processTasks) {
|
||||
// 检查毛坯任务
|
||||
if (!newTask.isHasSaveInBlankDetail() && newTask.getBlankOwner() != null){
|
||||
checkTaskAgainstExisting(Long.valueOf(newTask.getBlankOwner()), newTask.getStartBlankDate(), newTask.getBlankDate(), "BLUEPRINT_WORKBLANK", tasksByOwner);
|
||||
}
|
||||
// 检查2D任务
|
||||
if (!newTask.isHasSaveIn2DDetail() && newTask.getTwoDimOwner() != null){
|
||||
checkTaskAgainstExisting(Long.valueOf(newTask.getTwoDimOwner()), newTask.getStartTwoDimDate(), newTask.getTwoDimDate(), "BLUEPRINT_2D", tasksByOwner);
|
||||
|
||||
}
|
||||
// 检查3D任务
|
||||
if (!newTask.isHasSaveIn3DDetail() && newTask.getThreeDimOwner() != null){
|
||||
checkTaskAgainstExisting(Long.valueOf(newTask.getThreeDimOwner()), newTask.getStartThreeDimDate(), newTask.getThreeDimDate(), "BLUEPRINT_3D", tasksByOwner);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 辅助方法:检查单个新任务与已存在任务的冲突
|
||||
*/
|
||||
private void checkTaskAgainstExisting(Long owner, LocalDateTime start, LocalDateTime end, String taskType, Map<Long, List<PlanSubDetailDO>> tasksByOwner) {
|
||||
if (owner == null || start == null || end == null) {
|
||||
return; // 如果责任人或时间为空,则无需检查
|
||||
}
|
||||
|
||||
List<PlanSubDetailDO> existingTasksForOwner = tasksByOwner.get(owner);
|
||||
if (existingTasksForOwner == null) {
|
||||
return; // 如果该责任人没有已存在的任务,则无需检查
|
||||
}
|
||||
String typeName = "";
|
||||
if (taskType.equals("BLUEPRINT_3D")){
|
||||
typeName = "3D";
|
||||
}else if (taskType.equals("BLUEPRINT_2D")){
|
||||
typeName = "2D";
|
||||
}else if (taskType.equals("BLUEPRINT_WORKBLANK")){
|
||||
typeName = "毛坯";
|
||||
}
|
||||
for (PlanSubDetailDO existingTask : existingTasksForOwner) {
|
||||
if (hasOverlap(start, end, existingTask.getStartTwoDimDate(), existingTask.getTwoDimDate())) {
|
||||
throw exception(new ErrorCode(1_007_006,"当前插入"+start.toString().substring(0,10)+" -"+end.toString().substring(0,10)+"跟"+existingTask.getName()+"-"+typeName+existingTask.getStartTwoDimDate().toString().substring(0,10)+existingTask.getTwoDimDate().toString().substring(0,10)+"存在交集,请确认!"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 内部辅助类,用于简化任务处理
|
||||
private static class TaskItem {
|
||||
final String projectName;
|
||||
final Long owner;
|
||||
final LocalDateTime start;
|
||||
final LocalDateTime end;
|
||||
final String type; // "毛坯", "2D", "3D"
|
||||
|
||||
TaskItem(Long owner, LocalDateTime start, LocalDateTime end, String type,String projectName) {
|
||||
this.owner = owner;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.type = type;
|
||||
this.projectName = projectName;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void updatePlanSub(PlanSubSaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
@ -239,9 +454,6 @@ public class PlanSubServiceImpl implements PlanSubService {
|
||||
}
|
||||
//将所有信息查完之后,根据createTime进行排序
|
||||
planSubDOSs.sort(Comparator.comparing(PlanSubDO::getCreateTime));
|
||||
// 输出排序后的结果
|
||||
System.out.println("输出排序后结果");
|
||||
planSubDOSs.forEach(System.out::println);
|
||||
//用来获取日历时间段
|
||||
|
||||
String endTimes = null;//tableData.get(tableData.size()-1).getBlankDate().format(formatter);
|
||||
@ -355,7 +567,14 @@ public class PlanSubServiceImpl implements PlanSubService {
|
||||
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
|
||||
return dateTime;
|
||||
}
|
||||
|
||||
public static boolean hasOverlap(LocalDateTime start1, LocalDateTime end1, LocalDateTime start2, LocalDateTime end2) {
|
||||
// 处理 null 值,如果任一时间为 null,则认为该时间范围无效,不产生交集
|
||||
if (start1 == null || end1 == null || start2 == null || end2 == null) {
|
||||
return false;
|
||||
}
|
||||
// 核心判断逻辑
|
||||
return start1.compareTo(end2) <= 0 && start2.compareTo(end1) <= 0;
|
||||
}
|
||||
/*
|
||||
* 转换日期方法
|
||||
* */
|
||||
@ -392,7 +611,27 @@ public class PlanSubServiceImpl implements PlanSubService {
|
||||
|
||||
@Override
|
||||
public PageResult<PlanSubDO> getPlanSubPage(PlanSubPageReqVO pageReqVO) {
|
||||
return planSubMapper.selectPage(pageReqVO);
|
||||
PageResult<PlanSubDO> planSubDOPageResult = planSubMapper.selectPage(pageReqVO);
|
||||
List<PlanSubDO> list = planSubDOPageResult.getList();
|
||||
for (PlanSubDO planSubDO : list) {
|
||||
List<PlanSubDetailDO> planSubDetailDOS1 = planSubDetailMapper.selectList(new LambdaQueryWrapperX<PlanSubDetailDO>().eq(PlanSubDetailDO::getProjectPlanSubId, planSubDO.getId())
|
||||
.eq(PlanSubDetailDO::getSubType,"BLUEPRINT_WORKBLANK"));
|
||||
List<PlanSubDetailDO> planSubDetailDOS2 = planSubDetailMapper.selectList(new LambdaQueryWrapperX<PlanSubDetailDO>().eq(PlanSubDetailDO::getProjectPlanSubId, planSubDO.getId())
|
||||
.eq(PlanSubDetailDO::getSubType,"BLUEPRINT_2D"));
|
||||
List<PlanSubDetailDO> planSubDetailDOS3 = planSubDetailMapper.selectList(new LambdaQueryWrapperX<PlanSubDetailDO>().eq(PlanSubDetailDO::getProjectPlanSubId, planSubDO.getId())
|
||||
.eq(PlanSubDetailDO::getSubType,"BLUEPRINT_3D"));
|
||||
|
||||
if (CollUtil.isNotEmpty(planSubDetailDOS1)) {
|
||||
planSubDO.setHasSaveInBlankDetail(true);
|
||||
}
|
||||
if (CollUtil.isNotEmpty(planSubDetailDOS2)) {
|
||||
planSubDO.setHasSaveIn2DDetail(true);
|
||||
}
|
||||
if (CollUtil.isNotEmpty(planSubDetailDOS3)) {
|
||||
planSubDO.setHasSaveIn3DDetail(true);
|
||||
}
|
||||
}
|
||||
return planSubDOPageResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -54,9 +54,14 @@ public interface PlanSubDetailService {
|
||||
*/
|
||||
PageResult<PlanSubDetailDO> getPlanSubDetailPage(PlanSubDetailPageReqVO pageReqVO);
|
||||
|
||||
PageResult<PlanSubDetailDO> getPlanList(PlanSubDetailPageReqVO pageReqVO);
|
||||
|
||||
PlanSubDetailDO queryMaxDetail(PlanSubDetailPageReqVO pageReqVO);
|
||||
|
||||
Integer getSearchRlTs(String startDateTime);
|
||||
|
||||
CommonResult chahuoList(PlanSubDetailSaveReqVO updateReqVO);
|
||||
CommonResult savechahuoList(PlanSubDetailSaveReqVO updateReqVO);
|
||||
CommonResult modification(PlanSubDetailSaveReqVO updateReqVO);
|
||||
|
||||
CommonResult operate(PlanSubDetailSaveReqVO updateReqVO);
|
||||
CommonResult insertWork(PlanSubDetailSaveReqVO updateReqVO);
|
||||
}
|
||||
|
||||
@ -1,21 +1,29 @@
|
||||
package com.chanko.yunxi.mes.module.heli.service.plansubdetail;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.chanko.yunxi.mes.framework.common.pojo.CommonResult;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.dataobject.plan.PlanDO;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.dataobject.plansub.PlanSubDO;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.dataobject.purchaseordernodetail.PurchaseOrderNoDetailDO;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.dataobject.shopCalendar.ShopCalendarDO;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.mysql.plansub.PlanSubMapper;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.mysql.processdesign.ProcessDesignMapper;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.mysql.shopCalendar.ShopCalendarMapper;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -45,6 +53,8 @@ public class PlanSubDetailServiceImpl implements PlanSubDetailService {
|
||||
private ShopCalendarMapper shopCalendarMapper;
|
||||
@Resource
|
||||
private PlanSubMapper planSubMapper;
|
||||
@Resource
|
||||
private ProcessDesignMapper processDesignMapper;
|
||||
|
||||
@Override
|
||||
public Long createPlanSubDetail(PlanSubDetailSaveReqVO createReqVO) {
|
||||
@ -71,11 +81,10 @@ public class PlanSubDetailServiceImpl implements PlanSubDetailService {
|
||||
PlanSubDetailDO planSubDetailDO = planSubDetailMapper.selectById(id);
|
||||
// 获取当前日期时间
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
// 判断 当前时间是否在startTwoDimDate之后
|
||||
boolean isGreaterThanCurrent = now.isAfter(planSubDetailDO.getStartTwoDimDate());
|
||||
if (isGreaterThanCurrent) return CommonResult.error(400,"当前日期>开始日期,不允许删除");
|
||||
if (ObjectUtil.isNotEmpty(planSubDetailDO.getIsOverProcess())&& planSubDetailDO.getIsOverProcess()==1&&planSubDetailDO.getSeqNo()==1){
|
||||
if (ObjectUtil.isNotEmpty(planSubDetailDO.getIsOverProcess()) && planSubDetailDO.getIsOverProcess() == 2 && planSubDetailDO.getSeqNo()==1){
|
||||
return CommonResult.error(400,"该设计已报工,不允许删除");
|
||||
}
|
||||
LambdaQueryWrapper<PlanSubDetailDO> wrapper = new LambdaQueryWrapper<>();
|
||||
@ -166,6 +175,73 @@ public class PlanSubDetailServiceImpl implements PlanSubDetailService {
|
||||
return planSubDetailDOPageResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<PlanSubDetailDO> getPlanList(PlanSubDetailPageReqVO pageReqVO) {
|
||||
|
||||
return planSubDetailMapper.getPlanList(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlanSubDetailDO queryMaxDetail(PlanSubDetailPageReqVO pageReqVO) {
|
||||
//判断一下
|
||||
//twoDimOwner是设计责任人
|
||||
PlanSubDetailDO planSubDetailDO = planSubDetailMapper.selectOne(new LambdaQueryWrapper<PlanSubDetailDO>()
|
||||
.eq(PlanSubDetailDO::getTwoDimOwner, pageReqVO.getTwoDimOwner())
|
||||
.in(PlanSubDetailDO::getIsOverProcess,Arrays.asList(0,2))
|
||||
.ne(PlanSubDetailDO::getProjectId,pageReqVO.getProjectId())
|
||||
.orderByDesc(PlanSubDetailDO::getTwoDimDate).last("limit 1"));
|
||||
if (planSubDetailDO != null){
|
||||
if (pageReqVO.getQueryDate() != null){
|
||||
//如果日期不为空,查询最大日期
|
||||
Long l = Long.valueOf(pageReqVO.getQueryDate());
|
||||
Instant instant = Instant.ofEpochMilli(l);
|
||||
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
|
||||
LocalDateTime startDate = localDateTime.with(LocalTime.MIN);
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
now = now.with(LocalTime.MIN);
|
||||
//比较一下日期哪个大
|
||||
if (planSubDetailDO.getTwoDimDate().compareTo(startDate) > 0){
|
||||
startDate = planSubDetailDO.getTwoDimDate();
|
||||
}
|
||||
if (now.compareTo(startDate)>0){
|
||||
startDate = now;
|
||||
}
|
||||
ShopCalendarDO maxShopCalendar = shopCalendarMapper.selectOne(new LambdaQueryWrapper<ShopCalendarDO>().ge(ShopCalendarDO::getDates, startDate)
|
||||
.eq(ShopCalendarDO::getIfjiejiari, "false").orderByAsc(ShopCalendarDO::getDates).last("limit 1"));
|
||||
if (maxShopCalendar != null){
|
||||
planSubDetailDO.setMaxTime(maxShopCalendar.getDates());
|
||||
}else{
|
||||
planSubDetailDO.setMaxTime(startDate.plusDays(1));
|
||||
}
|
||||
}else{
|
||||
planSubDetailDO.setMaxTime(planSubDetailDO.getTwoDimDate().plusDays(1));
|
||||
}
|
||||
}else{
|
||||
if (pageReqVO.getQueryDate() != null){
|
||||
PlanSubDetailDO planSubDetailDO1 = new PlanSubDetailDO();
|
||||
//如果日期不为空,查询最大日期
|
||||
Long l = Long.valueOf(pageReqVO.getQueryDate());
|
||||
Instant instant = Instant.ofEpochMilli(l);
|
||||
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
|
||||
LocalDateTime startDate = localDateTime.with(LocalTime.MIN);
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
now = now.with(LocalTime.MIN);
|
||||
if (now.compareTo(startDate)>0){
|
||||
startDate = now;
|
||||
}
|
||||
ShopCalendarDO maxShopCalendar = shopCalendarMapper.selectOne(new LambdaQueryWrapper<ShopCalendarDO>().ge(ShopCalendarDO::getDates, startDate)
|
||||
.eq(ShopCalendarDO::getIfjiejiari, "false").orderByAsc(ShopCalendarDO::getDates).last("limit 1"));
|
||||
if (maxShopCalendar != null){
|
||||
planSubDetailDO1.setMaxTime(maxShopCalendar.getDates());
|
||||
}else{
|
||||
planSubDetailDO1.setMaxTime(startDate.plusDays(1));
|
||||
}
|
||||
planSubDetailDO = planSubDetailDO1;
|
||||
}
|
||||
}
|
||||
return planSubDetailDO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getSearchRlTs(String startDateTime) {
|
||||
List<ShopCalendarDO> shopCalendarDOS =shopCalendarMapper.getSearchRlT(startDateTime);
|
||||
@ -194,7 +270,7 @@ public class PlanSubDetailServiceImpl implements PlanSubDetailService {
|
||||
LocalDateTime existStart = planSubDetailDO.getStartTwoDimDate();
|
||||
LocalDateTime existEnd = planSubDetailDO.getTwoDimDate();
|
||||
// 判断请求时间段是否与已有时间段有重叠
|
||||
boolean hasOverlap = !reqEnd.isBefore(existStart) && !reqStart.isAfter(existEnd);
|
||||
boolean hasOverlap = !(reqEnd.compareTo(existStart) < 0) && !(reqStart.compareTo(existEnd) > 0);
|
||||
if (hasOverlap) {
|
||||
return CommonResult.error(400, "该子项目设计时间存在交叉,请确认!");
|
||||
}
|
||||
@ -205,18 +281,27 @@ public class PlanSubDetailServiceImpl implements PlanSubDetailService {
|
||||
wrapper1.eq(PlanSubDetailDO::getProjectSubId,updateReqVO.getProjectSubId());
|
||||
wrapper1.eq(PlanSubDetailDO::getSubType,updateReqVO.getSubType());
|
||||
String type="BLUEPRINT_WORKBLANK".equals(updateReqVO.getSubType())?"毛坯":"BLUEPRINT_2D".equals(updateReqVO.getSubType())?"2D":"3D";
|
||||
if (planSubDetailMapper.selectCount(wrapper1)>0) return CommonResult.error(400,"该子项目"+updateReqVO.getName()+" 设计类型"+type+" 存在派工数据,请确认!");
|
||||
if (planSubDetailMapper.selectCount(wrapper1)> 0 ) return CommonResult.error(400,"该子项目"+updateReqVO.getName()+" 设计类型"+type+" 存在派工数据,请确认!");
|
||||
}
|
||||
|
||||
|
||||
LambdaQueryWrapper<PlanSubDetailDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
lambdaQueryWrapper.in(PlanSubDetailDO::getIsOverProcess,0,2);
|
||||
lambdaQueryWrapper.eq(PlanSubDetailDO::getTwoDimOwner,updateReqVO.getTwoDimOwner());
|
||||
lambdaQueryWrapper.ge(PlanSubDetailDO::getStartTwoDimDate,updateReqVO.getStartTwoDimDate());
|
||||
lambdaQueryWrapper.ge(PlanSubDetailDO::getTwoDimDate,updateReqVO.getStartTwoDimDate());
|
||||
lambdaQueryWrapper.orderByAsc(PlanSubDetailDO::getStartTwoDimDate);
|
||||
if (ObjectUtil.isNotEmpty(updateReqVO.getId())){
|
||||
lambdaQueryWrapper.ne(PlanSubDetailDO::getId,updateReqVO.getId());
|
||||
}
|
||||
// if (ObjectUtil.isNotEmpty(updateReqVO.getId())){
|
||||
// lambdaQueryWrapper.ne(PlanSubDetailDO::getId,updateReqVO.getId());
|
||||
// }
|
||||
List<PlanSubDetailDO> list = planSubDetailMapper.selectList(lambdaQueryWrapper);
|
||||
if (ObjectUtil.isEmpty( list) ||updateReqVO.getTwoDimDate().isBefore(list.get(0).getStartTwoDimDate())){
|
||||
List<PlanSubDetailDO> noSelfList = new ArrayList<>();
|
||||
for (PlanSubDetailDO planSubDetailDO : list) {
|
||||
if (!planSubDetailDO.getId().equals(updateReqVO.getId())){
|
||||
noSelfList.add(planSubDetailDO);
|
||||
}
|
||||
}
|
||||
|
||||
if (ObjectUtil.isEmpty( noSelfList) && ((updateReqVO.getStartTwoDimDate().compareTo(noSelfList.get(0).getTwoDimDate()) <=0 )&& (updateReqVO.getTwoDimDate().compareTo(noSelfList.get(0).getStartTwoDimDate()) >= 0))){
|
||||
if (ObjectUtil.isNotEmpty(updateReqVO.getId())){
|
||||
planSubDetailMapper.delete(PlanSubDetailDO::getId,updateReqVO.getId());
|
||||
}
|
||||
@ -233,12 +318,495 @@ public class PlanSubDetailServiceImpl implements PlanSubDetailService {
|
||||
planSubDetailDO.setSeqNo(1L);
|
||||
planSubDetailDO.setDesignNum(updateReqVO.getDesignNum());
|
||||
planSubDetailDO.setCode(updateReqVO.getCode());
|
||||
list.add(planSubDetailDO);
|
||||
list.sort(Comparator.comparing(PlanSubDetailDO::getStartTwoDimDate, Comparator.nullsLast(Comparator.naturalOrder())));
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
list.get(i).setSeqNo(Long.valueOf(i + 1)); // 设置顺序为 1, 2, 3
|
||||
}
|
||||
planSubDetailMapper.insertOrUpdateBatch(list);
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
updateReqVO.setList( list);
|
||||
return CommonResult.success(updateReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult operate(PlanSubDetailSaveReqVO updateReqVO) {
|
||||
List<PlanSubDetailDO> list = updateReqVO.getList();
|
||||
HashSet<Long> ownerSet = new HashSet<>();
|
||||
for (PlanSubDetailDO planSubDetailDO : list) {
|
||||
if (planSubDetailDO.getId() == null){
|
||||
String type="BLUEPRINT_WORKBLANK".equals(planSubDetailDO.getSubType())?"毛坯":"BLUEPRINT_2D".equals(planSubDetailDO.getSubType())?"2D":"3D";
|
||||
//该项目名称+子项目名称+类型没有保存,请先修改!
|
||||
return CommonResult.error(400, "该子项目"+planSubDetailDO.getName()+" 设计类型"+type+" ,没有保存请确认!");
|
||||
}else {
|
||||
|
||||
planSubDetailDO.setDesignNum(calculateWorkDays(planSubDetailDO.getStartTwoDimDate(),planSubDetailDO.getTwoDimDate()));
|
||||
ownerSet.add(planSubDetailDO.getTwoDimOwner());
|
||||
}
|
||||
}
|
||||
|
||||
if (ownerSet.size() > 1){
|
||||
return CommonResult.error(400, "项目存在多个负责人,不允许保存。请单条修改!");
|
||||
}
|
||||
for (PlanSubDetailDO planSubDetailDO : list) {
|
||||
for (PlanSubDetailDO subDetailDO : list) {
|
||||
if(!planSubDetailDO.getId().equals(subDetailDO.getId())){
|
||||
//判断时间交叉
|
||||
LocalDateTime reqStart = subDetailDO.getStartTwoDimDate();
|
||||
LocalDateTime reqEnd = subDetailDO.getTwoDimDate();
|
||||
LocalDateTime existStart = planSubDetailDO.getStartTwoDimDate();
|
||||
LocalDateTime existEnd = planSubDetailDO.getTwoDimDate();
|
||||
// 判断请求时间段是否与已有时间段有重叠
|
||||
boolean hasOverlap = !(reqEnd.compareTo(existStart) < 0) && !(reqStart.compareTo(existEnd) > 0);
|
||||
if (hasOverlap) {
|
||||
return CommonResult.error(400, "该子项目设计时间存在交叉,请确认!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
planSubDetailMapper.updateBatch(list);
|
||||
//更新表pro_process_design
|
||||
Map<Long, List<PlanSubDetailDO>> collect = list.stream().collect(Collectors.groupingBy(PlanSubDetailDO::getProjectPlanSubId));
|
||||
|
||||
return CommonResult.success(true);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommonResult savechahuoList(PlanSubDetailSaveReqVO updateReqVO){
|
||||
List<PlanSubDetailDO> list = updateReqVO.getList();
|
||||
list.sort(Comparator.comparing(PlanSubDetailDO::getStartTwoDimDate, Comparator.nullsLast(Comparator.naturalOrder())));
|
||||
Map<Long, List<PlanSubDetailDO>> collect = list.stream().filter(item -> item.getId() != null ).collect(Collectors.groupingBy(PlanSubDetailDO::getId));
|
||||
HashSet<Long> deleteId = new HashSet<>();
|
||||
for (Long id : collect.keySet()) {
|
||||
List<PlanSubDetailDO> planSubDetailDOS = collect.get(id);
|
||||
if (collect.get(id).size() > 1){
|
||||
deleteId.add(id);
|
||||
for (PlanSubDetailDO planSubDetailDO : collect.get(id)) {
|
||||
planSubDetailDO.setId(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<Long, List<PlanSubDetailDO>> collect1 = list.stream().collect(Collectors.groupingBy(PlanSubDetailDO::getProjectSubId));
|
||||
collect1.forEach((id,detailList) -> {
|
||||
Map<String, List<PlanSubDetailDO>> collect2 = detailList.stream().collect(Collectors.groupingBy(PlanSubDetailDO::getSubType));
|
||||
collect2.forEach((type,list2) ->{
|
||||
int i = 1;
|
||||
for (PlanSubDetailDO planSubDetailDO : list2) {
|
||||
planSubDetailDO.setSeqNo(Long.valueOf(i++));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
planSubDetailMapper.deleteBatchIds(deleteId);
|
||||
planSubDetailMapper.insertOrUpdateBatch(list);
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommonResult chahuoList(PlanSubDetailSaveReqVO updateReqVO) {
|
||||
List<PlanSubDetailDO> list = updateReqVO.getList();
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return CommonResult.error(400, "列表为空,请刷新页面后重试!");
|
||||
}
|
||||
|
||||
// 1. 拿到整个list最大的twoDimDate时间
|
||||
LocalDateTime minDate = list.stream()
|
||||
.map(PlanSubDetailDO::getStartTwoDimDate)
|
||||
.min(LocalDateTime::compareTo)
|
||||
.orElse(null);
|
||||
LocalDateTime maxDate = list.stream()
|
||||
.map(PlanSubDetailDO::getTwoDimDate)
|
||||
.max(LocalDateTime::compareTo)
|
||||
.orElse(null);
|
||||
|
||||
// 2. 查询最大时间往后90天内的节假日
|
||||
LocalDateTime endDate = maxDate.plusDays(90);
|
||||
List<ShopCalendarDO> shopCalendarDOList = shopCalendarMapper.selectList(new LambdaQueryWrapper<ShopCalendarDO>().eq(ShopCalendarDO::getIfjiejiari, "true")
|
||||
.between(ShopCalendarDO::getDates, minDate, endDate).orderByAsc(ShopCalendarDO::getDates));
|
||||
List<LocalDateTime> holidayList = new ArrayList<>();
|
||||
for (ShopCalendarDO shopCalendarDO : shopCalendarDOList) {
|
||||
holidayList.add(shopCalendarDO.getDates());
|
||||
}
|
||||
|
||||
// 3. 将id为空的数据拿出来进行插活
|
||||
List<PlanSubDetailDO> insertList = list.stream()
|
||||
.filter(item -> item.getId() == null)
|
||||
.collect(Collectors.toList());
|
||||
for (PlanSubDetailDO planSubDetailDO : insertList) {
|
||||
planSubDetailDO.setIsCha("Y");
|
||||
}
|
||||
// 4. 将id不为空的按startTwoDimDate进行升序排序,形成baseList
|
||||
List<PlanSubDetailDO> baseList = list.stream()
|
||||
.filter(item -> item.getId() != null)
|
||||
.sorted(Comparator.comparing(PlanSubDetailDO::getStartTwoDimDate))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 5. 执行插活逻辑
|
||||
List<PlanSubDetailDO> resultList = performInsertLogic(baseList, insertList, holidayList);
|
||||
|
||||
// 6. 保存结果
|
||||
updateReqVO.setList(resultList);
|
||||
return CommonResult.success(updateReqVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行插活逻辑
|
||||
*/
|
||||
private List<PlanSubDetailDO> performInsertLogic(List<PlanSubDetailDO> baseList,
|
||||
List<PlanSubDetailDO> insertList,
|
||||
List<LocalDateTime> holidayList) {
|
||||
List<PlanSubDetailDO> resultList = new ArrayList<>();
|
||||
|
||||
// 1. 先处理插活数据,按节假日分段
|
||||
List<PlanSubDetailDO> processedInsertList = new ArrayList<>();
|
||||
for (PlanSubDetailDO insertItem : insertList) {
|
||||
LocalDateTime startDate = insertItem.getStartTwoDimDate();
|
||||
LocalDateTime endDate = insertItem.getTwoDimDate();
|
||||
|
||||
// 检查该时间段内是否有节假日
|
||||
List<LocalDateTime> holidaysInRange = getHolidaysInRange(startDate, endDate, holidayList);
|
||||
|
||||
if (holidaysInRange.isEmpty()) {
|
||||
// 没有节假日,直接添加
|
||||
processedInsertList.add(insertItem);
|
||||
} else {
|
||||
// 有节假日,需要分段处理
|
||||
List<PlanSubDetailDO> segments = splitByHolidays(insertItem, holidaysInRange);
|
||||
processedInsertList.addAll(segments);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 如果没有插活数据,直接返回baseList
|
||||
if (processedInsertList.isEmpty()) {
|
||||
return new ArrayList<>(baseList);
|
||||
}
|
||||
|
||||
// 3. 获取插活数据的开始时间
|
||||
LocalDateTime insertStartTime = processedInsertList.stream()
|
||||
.map(PlanSubDetailDO::getStartTwoDimDate)
|
||||
.min(LocalDateTime::compareTo)
|
||||
.orElse(null);
|
||||
|
||||
// 4. 分离baseList:在插活数据之前的、被打断的、在插活数据之后的
|
||||
List<PlanSubDetailDO> beforeInsertList = new ArrayList<>();
|
||||
List<PlanSubDetailDO> interruptedList = new ArrayList<>();
|
||||
List<PlanSubDetailDO> afterInsertList = new ArrayList<>();
|
||||
List<PlanSubDetailDO> remainingBaseList = new ArrayList<>();
|
||||
|
||||
if (insertStartTime != null) {
|
||||
for (PlanSubDetailDO baseItem : baseList) {
|
||||
if (baseItem.getTwoDimDate().isBefore(insertStartTime)) {
|
||||
// 完全在插活数据之前
|
||||
beforeInsertList.add(baseItem);
|
||||
} else if (baseItem.getStartTwoDimDate().isBefore(insertStartTime) &&
|
||||
baseItem.getTwoDimDate().isAfter(insertStartTime.minusDays(1))) {
|
||||
// 被插活数据打断
|
||||
interruptedList.add(baseItem);
|
||||
} else {
|
||||
// 在插活数据之后
|
||||
afterInsertList.add(baseItem);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
beforeInsertList.addAll(baseList);
|
||||
}
|
||||
|
||||
// 5. 处理插活数据之前的baseList(保持原样)
|
||||
resultList.addAll(beforeInsertList);
|
||||
|
||||
// 6. 处理被打断的baseList
|
||||
for (PlanSubDetailDO interruptedItem : interruptedList) {
|
||||
// 计算插活数据开始前的天数
|
||||
long daysBeforeInsert = ChronoUnit.DAYS.between(interruptedItem.getStartTwoDimDate(), insertStartTime);
|
||||
|
||||
if (daysBeforeInsert > 0) {
|
||||
// 创建插活前的段落
|
||||
LocalDateTime segmentEnd = interruptedItem.getStartTwoDimDate().plusDays(daysBeforeInsert - 1);
|
||||
PlanSubDetailDO beforeSegment = createBaseItem(interruptedItem, interruptedItem.getStartTwoDimDate(), segmentEnd);
|
||||
beforeSegment.setDesignNum(daysBeforeInsert);
|
||||
resultList.add(beforeSegment);
|
||||
|
||||
// 保存剩余的designNum
|
||||
Long remainingDesignNum = interruptedItem.getDesignNum() - daysBeforeInsert;
|
||||
if (remainingDesignNum > 0) {
|
||||
// 创建剩余的baseItem,稍后处理
|
||||
PlanSubDetailDO remainingItem = new PlanSubDetailDO();
|
||||
// 复制属性
|
||||
remainingItem.setId(interruptedItem.getId());
|
||||
remainingItem.setProjectPlanId(interruptedItem.getProjectPlanId());
|
||||
remainingItem.setProjectId(interruptedItem.getProjectId());
|
||||
remainingItem.setProjectPlanSubId(interruptedItem.getProjectPlanSubId());
|
||||
remainingItem.setProjectSubCode(interruptedItem.getProjectSubCode());
|
||||
remainingItem.setTwoDimOwner(interruptedItem.getTwoDimOwner());
|
||||
remainingItem.setProjectSubId(interruptedItem.getProjectSubId());
|
||||
remainingItem.setSubType(interruptedItem.getSubType());
|
||||
remainingItem.setName(interruptedItem.getName());
|
||||
remainingItem.setCode(interruptedItem.getCode());
|
||||
remainingItem.setDesignNum(remainingDesignNum);
|
||||
remainingBaseList.add(remainingItem);
|
||||
}
|
||||
} else {
|
||||
// 整个被打断,全部加入剩余列表
|
||||
remainingBaseList.add(interruptedItem);
|
||||
}
|
||||
}
|
||||
|
||||
// 7. 添加插活数据
|
||||
resultList.addAll(processedInsertList);
|
||||
|
||||
// 8. 处理剩余的baseList(被打断的剩余部分 + 原本在插活数据之后的)
|
||||
List<PlanSubDetailDO> allRemainingList = new ArrayList<>();
|
||||
allRemainingList.addAll(remainingBaseList);
|
||||
allRemainingList.addAll(afterInsertList);
|
||||
|
||||
if (!allRemainingList.isEmpty()) {
|
||||
// 获取插活数据的最后结束时间
|
||||
LocalDateTime lastInsertEndTime = processedInsertList.stream()
|
||||
.map(PlanSubDetailDO::getTwoDimDate)
|
||||
.max(LocalDateTime::compareTo)
|
||||
.orElse(null);
|
||||
|
||||
// 从插活数据的下一天开始顺延
|
||||
LocalDateTime baseStartTime = lastInsertEndTime.plusDays(1);
|
||||
|
||||
for (PlanSubDetailDO baseItem : allRemainingList) {
|
||||
// 按照原有的designNum计算新的时间段
|
||||
LocalDateTime newStartTime = baseStartTime;
|
||||
LocalDateTime newEndTime = newStartTime.plusDays(baseItem.getDesignNum() - 1);
|
||||
|
||||
// 检查新的时间段内是否有节假日
|
||||
List<LocalDateTime> holidaysInRange = getHolidaysInRange(newStartTime, newEndTime, holidayList);
|
||||
|
||||
if (holidaysInRange.isEmpty()) {
|
||||
// 没有节假日,直接添加
|
||||
PlanSubDetailDO newBaseItem = createBaseItem(baseItem, newStartTime, newEndTime);
|
||||
resultList.add(newBaseItem);
|
||||
baseStartTime = newEndTime.plusDays(1);
|
||||
} else {
|
||||
// 有节假日,需要分段处理
|
||||
List<PlanSubDetailDO> segments = splitBaseItemByHolidays(baseItem, newStartTime, newEndTime, holidaysInRange);
|
||||
resultList.addAll(segments);
|
||||
|
||||
// 更新下一个baseItem的开始时间
|
||||
LocalDateTime lastSegmentEndTime = segments.stream()
|
||||
.map(PlanSubDetailDO::getTwoDimDate)
|
||||
.max(LocalDateTime::compareTo)
|
||||
.orElse(newEndTime);
|
||||
baseStartTime = lastSegmentEndTime.plusDays(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 9. 按开始时间排序
|
||||
resultList.sort(Comparator.comparing(PlanSubDetailDO::getStartTwoDimDate));
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
private List<PlanSubDetailDO> splitByHolidays(PlanSubDetailDO original, List<LocalDateTime> holidaysInRange) {
|
||||
List<PlanSubDetailDO> segments = new ArrayList<>();
|
||||
LocalDateTime currentStart = original.getStartTwoDimDate();
|
||||
LocalDateTime originalEnd = original.getTwoDimDate();
|
||||
|
||||
for (LocalDateTime holiday : holidaysInRange) {
|
||||
// 修复:只有当currentStart在节假日前时才创建节假日前的一段
|
||||
if (currentStart.isBefore(holiday)) {
|
||||
LocalDateTime segmentEnd = holiday.minusDays(1);
|
||||
if (currentStart.isBefore(segmentEnd) || currentStart.isEqual(segmentEnd)) {
|
||||
// 节假日前的段落
|
||||
PlanSubDetailDO beforeHoliday = createSegment(original, currentStart, segmentEnd);
|
||||
segments.add(beforeHoliday);
|
||||
}
|
||||
}
|
||||
// 跳过节假日,从节假日后一天开始
|
||||
currentStart = holiday.plusDays(1);
|
||||
}
|
||||
|
||||
// 最后一段:确保还有剩余时间
|
||||
if (!currentStart.isAfter(originalEnd)) {
|
||||
PlanSubDetailDO lastSegment = createSegment(original, currentStart, originalEnd);
|
||||
segments.add(lastSegment);
|
||||
}
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按节假日分段(带时间控制,用于插活数据)
|
||||
*/
|
||||
private List<PlanSubDetailDO> splitByHolidaysWithTime(PlanSubDetailDO original,
|
||||
LocalDateTime startTime,
|
||||
LocalDateTime endTime,
|
||||
List<LocalDateTime> holidaysInRange) {
|
||||
List<PlanSubDetailDO> segments = new ArrayList<>();
|
||||
LocalDateTime currentStart = startTime;
|
||||
|
||||
for (LocalDateTime holiday : holidaysInRange) {
|
||||
if (currentStart.isBefore(holiday)) {
|
||||
LocalDateTime segmentEnd = holiday.minusDays(1);
|
||||
if (currentStart.isBefore(segmentEnd) || currentStart.isEqual(segmentEnd)) {
|
||||
PlanSubDetailDO beforeHoliday = createSegment(original, currentStart, segmentEnd);
|
||||
segments.add(beforeHoliday);
|
||||
}
|
||||
}
|
||||
currentStart = holiday.plusDays(1);
|
||||
}
|
||||
|
||||
// 最后一段
|
||||
if (!currentStart.isAfter(endTime)) {
|
||||
PlanSubDetailDO lastSegment = createSegment(original, currentStart, endTime);
|
||||
segments.add(lastSegment);
|
||||
}
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private List<PlanSubDetailDO> splitBaseItemByHolidays(PlanSubDetailDO original,
|
||||
LocalDateTime startTime,
|
||||
LocalDateTime endTime,
|
||||
List<LocalDateTime> holidaysInRange) {
|
||||
List<PlanSubDetailDO> segments = new ArrayList<>();
|
||||
LocalDateTime currentStart = startTime;
|
||||
Long totalDesignNum = original.getDesignNum();
|
||||
Long usedDesignNum = 0L;
|
||||
|
||||
for (LocalDateTime holiday : holidaysInRange) {
|
||||
if (currentStart.isBefore(holiday)) {
|
||||
// 计算到节假日前一天的天数
|
||||
long daysToHoliday = ChronoUnit.DAYS.between(currentStart, holiday);
|
||||
|
||||
if (daysToHoliday > 0) {
|
||||
long segmentDays = Math.min(daysToHoliday, totalDesignNum - usedDesignNum);
|
||||
|
||||
if (segmentDays > 0) {
|
||||
// 节假日前的段落
|
||||
LocalDateTime segmentEnd = currentStart.plusDays(segmentDays - 1);
|
||||
PlanSubDetailDO beforeHoliday = createBaseItem(original, currentStart, segmentEnd);
|
||||
beforeHoliday.setDesignNum(segmentDays); // 设置实际的designNum
|
||||
segments.add(beforeHoliday);
|
||||
usedDesignNum += segmentDays;
|
||||
currentStart = holiday.plusDays(1);
|
||||
}
|
||||
} else {
|
||||
currentStart = holiday.plusDays(1);
|
||||
}
|
||||
|
||||
// 如果已经用完了designNum,直接返回
|
||||
if (usedDesignNum >= totalDesignNum) {
|
||||
return segments;
|
||||
}
|
||||
} else {
|
||||
currentStart = holiday.plusDays(1);
|
||||
}
|
||||
}
|
||||
|
||||
// 最后一段
|
||||
if (usedDesignNum < totalDesignNum) {
|
||||
long remainingDays = totalDesignNum - usedDesignNum;
|
||||
LocalDateTime lastSegmentEnd = currentStart.plusDays(remainingDays - 1);
|
||||
PlanSubDetailDO lastSegment = createBaseItem(original, currentStart, lastSegmentEnd);
|
||||
lastSegment.setDesignNum(remainingDays); // 设置实际的designNum
|
||||
segments.add(lastSegment);
|
||||
}
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建分段对象(用于插活数据)
|
||||
*/
|
||||
private PlanSubDetailDO createSegment(PlanSubDetailDO original, LocalDateTime startDate, LocalDateTime endDate) {
|
||||
PlanSubDetailDO segment = new PlanSubDetailDO();
|
||||
segment.setId(null); // 新分段id为空
|
||||
segment.setProjectPlanId(original.getProjectPlanId());
|
||||
segment.setProjectId(original.getProjectId());
|
||||
segment.setProjectPlanSubId(original.getId());
|
||||
segment.setProjectSubCode(original.getProjectSubCode());
|
||||
segment.setTwoDimOwner(Long.valueOf(original.getTwoDimOwner()));
|
||||
segment.setProjectSubId(original.getProjectSubId());
|
||||
segment.setSubType(original.getSubType());
|
||||
segment.setName(original.getName());
|
||||
segment.setCode(original.getCode());
|
||||
segment.setStartTwoDimDate(startDate);
|
||||
segment.setTwoDimDate(endDate);
|
||||
// 只有id为空的才重新计算designNum
|
||||
segment.setDesignNum(calculateWorkDays(startDate, endDate));
|
||||
return segment;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建baseItem对象(用于baseList顺延)
|
||||
*/
|
||||
private PlanSubDetailDO createBaseItem(PlanSubDetailDO original, LocalDateTime startDate, LocalDateTime endDate) {
|
||||
PlanSubDetailDO baseItem = new PlanSubDetailDO();
|
||||
// 复制原有属性
|
||||
baseItem.setId(original.getId());
|
||||
baseItem.setProjectPlanId(original.getProjectPlanId());
|
||||
baseItem.setProjectId(original.getProjectId());
|
||||
baseItem.setProjectPlanSubId(original.getProjectPlanSubId());
|
||||
baseItem.setProjectSubCode(original.getProjectSubCode());
|
||||
baseItem.setTwoDimOwner(original.getTwoDimOwner());
|
||||
baseItem.setProjectSubId(original.getProjectSubId());
|
||||
baseItem.setSubType(original.getSubType());
|
||||
baseItem.setName(original.getName());
|
||||
baseItem.setCode(original.getCode());
|
||||
baseItem.setDesignNum(calculateWorkDays(startDate, endDate));
|
||||
baseItem.setStartTwoDimDate(startDate);
|
||||
baseItem.setTwoDimDate(endDate);
|
||||
return baseItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取时间段内的节假日
|
||||
*/
|
||||
private List<LocalDateTime> getHolidaysInRange(LocalDateTime startDate, LocalDateTime endDate,
|
||||
List<LocalDateTime> holidayList) {
|
||||
return holidayList.stream()
|
||||
.filter(holiday -> !holiday.isBefore(startDate) && !holiday.isAfter(endDate))
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算工作天数(排除节假日)
|
||||
*/
|
||||
private Long calculateWorkDays(LocalDateTime startDate, LocalDateTime endDate) {
|
||||
long workDays = 0;
|
||||
LocalDateTime current = startDate.toLocalDate().atStartOfDay();
|
||||
LocalDateTime end = endDate.toLocalDate().atStartOfDay();
|
||||
|
||||
while (!current.isAfter(end)) {
|
||||
// 检查是否是工作日
|
||||
workDays++;
|
||||
current = current.plusDays(1);
|
||||
}
|
||||
|
||||
return workDays;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存计划子明细
|
||||
*/
|
||||
private void savePlanSubDetails(List<PlanSubDetailDO> resultList) {
|
||||
for (PlanSubDetailDO item : resultList) {
|
||||
if (item.getId() == null) {
|
||||
// 新增
|
||||
planSubDetailMapper.insert(item);
|
||||
} else {
|
||||
// 更新
|
||||
planSubDetailMapper.updateById(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CommonResult insertWork(PlanSubDetailSaveReqVO updateReqVO) {
|
||||
List<PlanSubDetailDO> list = updateReqVO.getList();
|
||||
|
||||
@ -676,7 +676,7 @@ public class ProcessBomServiceImpl implements ProcessBomService {
|
||||
// if(vo.getMemo()!=null){
|
||||
// vo.setMemo(vo.getMemo()+"→物料名称由"+po.getMaterialName()+"变为"+vo.getMaterialName());
|
||||
// }else{
|
||||
change = true;
|
||||
change = true;
|
||||
changeContent += "→物料名称由"+po.getMaterialName()+"变为"+vo.getMaterialName();
|
||||
// }
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ public interface ShopCalendarService {
|
||||
* @return 物料
|
||||
*/
|
||||
PageResult<ShopCalendarDO> searchRl(ShopCalendarPageReqVO shopCalendarPageReqVO);
|
||||
|
||||
Boolean searchHoliday(ShopCalendarPageReqVO shopCalendarPageReqVO);
|
||||
Boolean insert(String dates);
|
||||
|
||||
Boolean updateRl(String ifjiejiari,String dates,String times);
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
package com.chanko.yunxi.mes.module.heli.service.shopCalendar;
|
||||
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.chanko.yunxi.mes.framework.common.pojo.PageResult;
|
||||
import com.chanko.yunxi.mes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.chanko.yunxi.mes.module.heli.controller.admin.shopCalendar.vo.ShopCalendarPageReqVO;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.dataobject.shopCalendar.ShopCalendarDO;
|
||||
import com.chanko.yunxi.mes.module.heli.dal.mysql.shopCalendar.ShopCalendarMapper;
|
||||
@ -9,9 +13,7 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.YearMonth;
|
||||
import java.time.*;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.TextStyle;
|
||||
import java.util.*;
|
||||
@ -40,6 +42,21 @@ public class ShopCalendarServiceImpl implements ShopCalendarService {
|
||||
return shopCalendarMapper.searchRl(shopCalendarPageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean searchHoliday(ShopCalendarPageReqVO shopCalendarPageReqVO) {
|
||||
String queryDate = shopCalendarPageReqVO.getQueryDate();
|
||||
Long l = Long.valueOf(queryDate);
|
||||
Instant instant = Instant.ofEpochMilli(l);
|
||||
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
|
||||
LocalDateTime startDate = localDateTime.with(LocalTime.MIN);
|
||||
List<ShopCalendarDO> aTrue = shopCalendarMapper.selectList(new LambdaQueryWrapperX<ShopCalendarDO>().eq(ShopCalendarDO::getDates, startDate).eq(ShopCalendarDO::getIfjiejiari, "true"));
|
||||
if (CollUtil.isNotEmpty(aTrue)){
|
||||
return false;
|
||||
}else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*重置当月节假日*/
|
||||
@Override
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// const devBaseURL = 'http://localhost:5281'
|
||||
const devBaseURL = 'http://localhost:8080'
|
||||
// const devBaseURL = 'http://5a35a48943.wicp.vip:40709'
|
||||
// const proBaseURL = 'http://5a35a48943.wicp.vip:40709'
|
||||
// const devBaseURL = 'http://124.221.23.100:9003'
|
||||
@ -7,8 +7,8 @@
|
||||
// const proBaseURL = 'http://118.195.155.9:9002/'
|
||||
// const devBaseURL = 'http://192.168.0.169:9002/'
|
||||
// const proBaseURL = 'http://192.168.0.169:9002/'
|
||||
const devBaseURL = 'http://218.75.46.166:8889/'
|
||||
const proBaseURL = 'http://218.75.46.166:8889/'
|
||||
// const devBaseURL = 'http://218.75.46.166:8889/'
|
||||
// const proBaseURL = 'http://218.75.46.166:8889/'
|
||||
export const BASE_URL = process.env.NODE_ENV === 'development' ? devBaseURL : proBaseURL
|
||||
|
||||
export const TIMEOUT = 5000
|
||||
|
||||
@ -28,6 +28,13 @@ export const getPlanSub = async (id: number) => {
|
||||
return await request.get({ url: `/heli/plan-sub/get?id=` + id })
|
||||
}
|
||||
|
||||
|
||||
export const operate = async (data) => {
|
||||
return await request.post({ url: `/heli/plan-sub/operate`, data })
|
||||
}
|
||||
|
||||
|
||||
|
||||
//插活保存
|
||||
export const getOwnderPlanChaHuo = async (data) => {
|
||||
//return await request.post({ url: `/heli/plan-sub/postOwnderChaHuo`,data})
|
||||
|
||||
@ -22,6 +22,13 @@ export const getPlanSubDetailPage = async (params) => {
|
||||
return await request.get({ url: `/heli/plan-sub-detail/page`, params })
|
||||
}
|
||||
|
||||
export const pageAddList = async (params) => {
|
||||
return await request.get({ url: `/heli/plan-sub-detail/pageAddList`, params })
|
||||
}
|
||||
export const queryMaxDetail = async (params) => {
|
||||
return await request.get({ url: `/heli/plan-sub-detail/queryMaxDetail`, params })
|
||||
}
|
||||
|
||||
// 查询生产计划子项目设计时间明细详情
|
||||
export const getPlanSubDetail = async (id: number) => {
|
||||
return await request.get({ url: `/heli/plan-sub-detail/get?id=` + id })
|
||||
@ -36,7 +43,20 @@ export const createPlanSubDetail = async (data: PlanSubDetailVO) => {
|
||||
export const updatePlanSubDetail = async (data: PlanSubDetailVO) => {
|
||||
return await request.put({ url: `/heli/plan-sub-detail/update`, data })
|
||||
}
|
||||
export const modificationPlanSubDetail = async (data: PlanSubDetailVO) => {
|
||||
return await request.post({ url: `/heli/plan-sub-detail/modification`, data })
|
||||
}
|
||||
export const chahuoPlanSubDetail = async (data) => {
|
||||
return await request.post({ url: `/heli/plan-sub-detail/chahuo`, data })
|
||||
}
|
||||
|
||||
export const savechahuoPlanSubDetail = async (data) => {
|
||||
return await request.post({ url: `/heli/plan-sub-detail/savechahuo`, data })
|
||||
}
|
||||
|
||||
export const operate = async (data) => {
|
||||
return await request.post({ url: `/heli/plan-sub-detail/operate`, data })
|
||||
}
|
||||
// 删除生产计划子项目设计时间明细
|
||||
export const deletePlanSubDetail = async (id: number) => {
|
||||
return await request.delete({ url: `/heli/plan-sub-detail/delete?id=` + id })
|
||||
|
||||
@ -12,7 +12,10 @@ export interface ShopCalendarVO {
|
||||
export const getShopCalendarPage = async (params) => {
|
||||
return await request.get({ url: `/heli/shopCalendar/searchRl`, params })
|
||||
}
|
||||
|
||||
// 查询日历
|
||||
export const isHoliday= async (params) => {
|
||||
return await request.get({ url: `/heli/shopCalendar/searchHoliday`, params })
|
||||
}
|
||||
// 新增日历
|
||||
export const createShopCalendarPlan = async (dates: string) => {
|
||||
return await request.post({ url: `/heli/shopCalendar/insert?dates=` + dates })
|
||||
|
||||
@ -106,7 +106,7 @@
|
||||
<span>制单人:{{ `` }}</span>
|
||||
<span>-客户联-</span>
|
||||
</div>
|
||||
<div class="divide_line" style="margin: 20px 0"></div>
|
||||
<div class="divide_line" style="margin: 10px 0"></div>
|
||||
<!-- 回单联 -->
|
||||
<table border="2" cellspacing="0" id="table1" style="position: relative !important">
|
||||
<!-- <img
|
||||
|
||||
@ -46,13 +46,10 @@ const gitlist = async () => {
|
||||
userList.value = []
|
||||
userSelectList.value = []
|
||||
userList.value = [...userList.value, ...data.list]
|
||||
console.log(propsmodelValue.value)
|
||||
// 设置初始值
|
||||
if (propsmodelValue.value) {
|
||||
valueName.value = propsmodelValue.value
|
||||
const initialUser = await UserApi.getUser(valueName.value)
|
||||
console.log(valueName.value)
|
||||
console.log(initialUser)
|
||||
if (initialUser){
|
||||
if (initialUser.status == 1) {
|
||||
status1.value = true
|
||||
|
||||
@ -13,22 +13,25 @@
|
||||
label-width="110px"
|
||||
>
|
||||
<el-form-item label="负责人" prop="twoDimOwner">
|
||||
<el-select class="!w-265px" v-model="queryParams.twoDimOwner" clearable filterable>
|
||||
<el-select class="!w-265px" v-model="queryParams.twoDimOwner" clearable filterable>
|
||||
<el-option
|
||||
v-for="dict in userInit" :key="dict.id"
|
||||
:label="dict.nickname" :value="dict.id" />
|
||||
v-for="dict in userInit"
|
||||
:key="dict.id"
|
||||
:label="dict.nickname"
|
||||
:value="dict.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始日期" prop="startTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.startTime"
|
||||
value-format="YYYY-MM-DD"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
class="!w-280px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始日期" prop="beginTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.beginTime"
|
||||
value-format="YYYY-MM-DD"
|
||||
type="date"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
class="!w-280px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="项目编号" prop="code">
|
||||
<el-input
|
||||
v-model="queryParams.code"
|
||||
@ -50,86 +53,120 @@
|
||||
|
||||
<el-form-item label="设计类型" prop="subType">
|
||||
<el-select v-model="queryParams.subType" placeholder="类型" clearable class="!w-240px">
|
||||
<el-option v-for="dict in getIntDictOptions(DICT_TYPE.HELI_CH_PROCESS_TYPE)" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
<el-option
|
||||
v-for="dict in getStrDictOptions(DICT_TYPE.HELI_CH_PROCESS_TYPE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery" type="primary"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||
<el-button @click="handleQuery" type="primary"
|
||||
><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button
|
||||
>
|
||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||
|
||||
<el-button @click="saveForm" type="warning">保存</el-button>
|
||||
<el-button @click="addForm" type="success">新增</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" class="hl-table" border>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="list"
|
||||
:show-overflow-tooltip="true"
|
||||
class="hl-table"
|
||||
border
|
||||
>
|
||||
<el-table-column fixed label="序号" type="index" width="70" align="center" />
|
||||
<el-table-column fixed label="项目编码" align="center" prop="code" min-width="120" />
|
||||
<el-table-column fixed label="子项目名称" align="center" prop="name" min-width="250" />
|
||||
<el-table-column min-width="200px" align="center" >
|
||||
<el-table-column min-width="200px" align="center">
|
||||
<template #header>设计类型</template>
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.subType`" class="mb-0px!" >
|
||||
<el-select class="!w-265px" v-model="row.subType" clearable filterable :disabled="row.flag==0">
|
||||
<el-form-item :prop="`${$index}.subType`" class="mb-0px!">
|
||||
<el-select class="!w-265px" v-model="row.subType" clearable filterable :disabled="row.userFlag == false">
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.HELI_CH_PROCESS_TYPE)" :key="dict.value"
|
||||
:label="dict.label" :value="dict.value" />
|
||||
v-for="dict in getStrDictOptions(DICT_TYPE.HELI_CH_PROCESS_TYPE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200px" align="center" >
|
||||
<template #header>负责人</template>
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.twoDimOwner`" class="mb-0px!" >
|
||||
<el-select class="!w-265px" v-model="row.twoDimOwner" clearable filterable :disabled="row.flag==0">
|
||||
<el-option
|
||||
v-for="dict in userInit" :key="dict.id"
|
||||
:label="dict.username+' '+dict.nickname" :value="dict.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200px" align="center" >
|
||||
<el-table-column min-width="200px" align="center">
|
||||
<template #header>负责人</template>
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.twoDimOwner`" class="mb-0px!">
|
||||
<el-select
|
||||
class="!w-265px"
|
||||
v-model="row.twoDimOwner"
|
||||
clearable
|
||||
filterable
|
||||
:disabled="row.flag == 0 "
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in userInit"
|
||||
:key="dict.id"
|
||||
:label="dict.username + ' ' + dict.nickname"
|
||||
:value="dict.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200px" align="center">
|
||||
<template #header>开始日期</template>
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.startTwoDimDate`" class="mb-0px!" >
|
||||
<el-date-picker class="!w-265px" v-model="row.startTwoDimDate" type="date" @change="change1(row,0)" value-format="x" placeholder="开始日期" :disabled="row.flag==0" :disabled-date="disabledFutureDates"
|
||||
<el-form-item :prop="`${$index}.startTwoDimDate`" class="mb-0px!">
|
||||
<el-date-picker
|
||||
class="!w-265px"
|
||||
v-model="row.startTwoDimDate"
|
||||
type="date"
|
||||
@change="change1(row, 0)"
|
||||
value-format="x"
|
||||
placeholder="开始日期"
|
||||
:disabled="row.flag == 0 "
|
||||
:disabled-date="disabledFutureDates"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200px" align="center" >
|
||||
<el-table-column min-width="200px" align="center">
|
||||
<template #header>结束日期</template>
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.twoDimDate`" class="mb-0px!" >
|
||||
<el-date-picker class="!w-265px" v-model="row.twoDimDate" type="date" @change="change1(row,1)" value-format="x" placeholder="结束日期" :disabled="row.flag==0" :disabled-date="disabledFutureDates"/>
|
||||
<el-form-item :prop="`${$index}.twoDimDate`" class="mb-0px!">
|
||||
<el-date-picker
|
||||
class="!w-265px"
|
||||
v-model="row.twoDimDate"
|
||||
type="date"
|
||||
@change="change1(row, 1)"
|
||||
value-format="x"
|
||||
placeholder="结束日期"
|
||||
:disabled="row.flag == 0 "
|
||||
:disabled-date="disabledFutureDates"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="设计天数" align="center" prop="designNum" min-width="120"/>
|
||||
<el-table-column label="时间段顺序" align="center" prop="seqNo" min-width="120"/>
|
||||
<el-table-column label="是否新增" align="center" prop="seqNo" min-width="120">
|
||||
<el-table-column label="设计天数" align="center" prop="designNum" min-width="120" />
|
||||
<el-table-column label="时间段顺序" align="center" prop="seqNo" min-width="120" />
|
||||
<el-table-column label="是否新增" align="center" prop="seqNo" min-width="120">
|
||||
<template #default="scope">
|
||||
{{ scope.row.isAdd==1?"是":"否" }}
|
||||
{{ scope.row.isAdd == 1 ? '是' : '否' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" fixed="right" min-width="120">
|
||||
<!-- <template #default="scope">-->
|
||||
<!-- <el-button link type="primary" @click="modification(scope.row)" >-->
|
||||
<!-- 修改-->
|
||||
<!-- </el-button>-->
|
||||
<!-- <el-button-->
|
||||
<!-- link-->
|
||||
<!-- type="danger"-->
|
||||
<!-- >-->
|
||||
<!-- 删除-->
|
||||
<!-- </el-button>-->
|
||||
<!-- <el-button link type="primary" >-->
|
||||
<!-- 新增-->
|
||||
<!-- </el-button>-->
|
||||
<!-- </template>-->
|
||||
<el-table-column label="操作" align="center" fixed="right" min-width="190">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="addItemRow(scope.row)"> 新增 </el-button>
|
||||
<el-button link type="success" @click="modification(scope.row)"> 修改 </el-button>
|
||||
<el-button link @click="handleDelete(scope.row)" type="danger"> 删除 </el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
@ -141,45 +178,385 @@
|
||||
/>
|
||||
</ContentWrap>
|
||||
</el-card>
|
||||
|
||||
<!----插活弹框-->
|
||||
<!-- 插活弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" width="80%" :close-on-click-modal="false">
|
||||
<div class="dialog-content">
|
||||
<!-- 第一排:当前日期信息 -->
|
||||
<!-- 第二排:状态标题 -->
|
||||
<div class="status-title">
|
||||
<h3>{{
|
||||
dialogTitle +
|
||||
'(当前:' +
|
||||
formatDate(currentRow?.startTwoDimDate, 'YYYY-MM-DD') +
|
||||
'至' +
|
||||
formatDate(currentRow?.twoDimDate, 'YYYY-MM-DD') +
|
||||
')'
|
||||
}}</h3>
|
||||
</div>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
v-loading="loading2"
|
||||
:data="insertList"
|
||||
:show-overflow-tooltip="true"
|
||||
class="hl-table"
|
||||
border
|
||||
max-height="400"
|
||||
>
|
||||
<el-table-column fixed label="序号" type="index" width="70" align="center" />
|
||||
<el-table-column fixed label="项目编码" align="center" prop="code" min-width="120" />
|
||||
<el-table-column fixed label="子项目名称" align="center" prop="name" min-width="250" />
|
||||
<el-table-column min-width="200px" align="center">
|
||||
<template #header>设计类型</template>
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.subType`" class="mb-0px!">
|
||||
<el-select class="!w-265px" v-model="row.subType" clearable filterable disabled>
|
||||
<el-option
|
||||
v-for="dict in getStrDictOptions(DICT_TYPE.HELI_CH_PROCESS_TYPE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200px" align="center">
|
||||
<template #header>负责人</template>
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.twoDimOwner`" class="mb-0px!">
|
||||
<el-select class="!w-265px" v-model="row.twoDimOwner" clearable filterable disabled>
|
||||
<el-option
|
||||
v-for="dict in userInit"
|
||||
:key="dict.id"
|
||||
:label="dict.username + ' ' + dict.nickname"
|
||||
:value="dict.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200px" align="center">
|
||||
<template #header>开始日期</template>
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.startTwoDimDate`" class="mb-0px!">
|
||||
<el-date-picker
|
||||
class="!w-265px"
|
||||
v-model="row.startTwoDimDate"
|
||||
type="date"
|
||||
@change="change1(row, 0)"
|
||||
value-format="x"
|
||||
placeholder="开始日期"
|
||||
disabled
|
||||
:disabled-date="disabledFutureDates"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200px" align="center">
|
||||
<template #header>结束日期</template>
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.twoDimDate`" class="mb-0px!">
|
||||
<el-date-picker
|
||||
class="!w-265px"
|
||||
v-model="row.twoDimDate"
|
||||
type="date"
|
||||
@change="change1(row, 1)"
|
||||
value-format="x"
|
||||
placeholder="结束日期"
|
||||
disabled
|
||||
:disabled-date="disabledFutureDates"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="设计天数" align="center" prop="designNum" min-width="120" />
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleCancelDialog">取消</el-button>
|
||||
<el-button v-if="dialogTitle == '插活前'" type="warning" @click="handleInsert"
|
||||
>插活</el-button
|
||||
>
|
||||
<el-button v-else type="primary" @click="handleConfirm">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="addDialogVisible" title="新增" width="80%">
|
||||
<!-- 查询条件 -->
|
||||
<el-form inline class="mb-4">
|
||||
<el-form-item label="项目编码">
|
||||
<el-input v-model="addQueryParams.projectCode" placeholder="请输入项目编码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="子项目名称">
|
||||
<el-input v-model="addQueryParams.projectSubName" placeholder="请输入子项目名称" />
|
||||
</el-form-item>
|
||||
<el-button type="primary" @click="handleAddQuery">查询</el-button>
|
||||
</el-form>
|
||||
|
||||
<!-- 新增 -->
|
||||
<el-table
|
||||
:data="addList"
|
||||
v-loading="loading3"
|
||||
highlight-current-row
|
||||
ref="multipleTableRef" @select="handlerSelect"
|
||||
|
||||
@selection-change="handleSelectionChange"
|
||||
@row-click="rowClickHandle"
|
||||
:row-key="row => row.id"
|
||||
>
|
||||
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column type="index" label="序号" width="70" align="center" />
|
||||
<el-table-column prop="projectName" label="项目名称" min-width="180" />
|
||||
<el-table-column prop="code" label="项目编码" min-width="150" />
|
||||
<el-table-column prop="name" label="子项目名称" min-width="180" />
|
||||
<el-table-column prop="customerBrief" label="客户简称" min-width="150" />
|
||||
<el-table-column prop="planNo" label="生产计划" min-width="150" />
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="addtotal"
|
||||
v-model:page="addQueryParams.pageNo"
|
||||
v-model:limit="addQueryParams.pageSize"
|
||||
@pagination="handleAddQuery"
|
||||
/>
|
||||
<!-- 底部按钮 -->
|
||||
<template #footer>
|
||||
<div class="dialog-footer" style="margin-left: 20%;">
|
||||
<el-button @click="handleAddCancel">取消</el-button>
|
||||
<el-button type="primary" @click="handleAddConfirm">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
<script setup lang="ts">
|
||||
defineOptions({ name: 'interrupt' })
|
||||
defineOptions({ name: 'Interrupt' })
|
||||
import * as PlansubdetailApi from '@/api/heli/plansubdetail'
|
||||
import {DICT_TYPE, getIntDictOptions} from "@/utils/dict";
|
||||
import {ref, reactive, onMounted} from "vue"; // 确保导入 onMounted
|
||||
import * as UserApi from "@/api/system/user";
|
||||
import {formatDate} from "@/utils/formatTime";
|
||||
import { DICT_TYPE, getIntDictOptions, getStrDictOptions } from '@/utils/dict'
|
||||
import { ref, reactive, onMounted } from 'vue' // 确保导入 onMounted
|
||||
import * as UserApi from '@/api/system/user'
|
||||
|
||||
import * as PlanSubApi from '@/api/heli/plansub'
|
||||
import { formatDate } from '@/utils/formatTime'
|
||||
import * as shopCalendarApi from '@/api/heli/shopCalendar'
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n() // 国际化
|
||||
|
||||
const reload = inject('reload')
|
||||
const userInit = ref()
|
||||
const loading = ref(false)
|
||||
const loading2 = ref(false)
|
||||
const loading3 = ref(false)
|
||||
const list = ref([])
|
||||
const total = ref(0)
|
||||
const multipleTableRef = ref()
|
||||
const addtotal = ref(0)
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
twoDimOwner: undefined,
|
||||
subType: undefined,
|
||||
beginTime: undefined,
|
||||
startTime: undefined,
|
||||
code: undefined,
|
||||
name: undefined
|
||||
})
|
||||
const queryFormRef = ref()
|
||||
|
||||
//弹框新增逻辑:
|
||||
const addDialogVisible = ref(false)
|
||||
const addList = ref([])
|
||||
const addQueryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
projectCode: '',
|
||||
projectSubName: ''
|
||||
})
|
||||
const selectedAddRow = ref([])
|
||||
const rowClickHandle = (row) => {
|
||||
const selectData = selectedAddRow.value
|
||||
multipleTableRef.value.clearSelection()
|
||||
// if( selectData.length == 1 ) {
|
||||
// selectData.forEach(item => {
|
||||
// // 判断 如果当前的一行被勾选, 再次点击的时候就会取消选中
|
||||
// if (item == row) {
|
||||
// multipleTableRef.value.toggleRowSelection(row, false);
|
||||
// }
|
||||
// // 不然就让当前的一行勾选
|
||||
// else {
|
||||
// multipleTableRef.value.toggleRowSelection(row, true);
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// else {
|
||||
// multipleTableRef.value.toggleRowSelection(row, true);
|
||||
// }
|
||||
if (selectData && selectData.length == 1) {
|
||||
const [item] = selectData;
|
||||
const shouldSelect = item !== row;
|
||||
multipleTableRef.value.toggleRowSelection(row, shouldSelect);
|
||||
} else {
|
||||
multipleTableRef.value.toggleRowSelection(row, true);
|
||||
}
|
||||
}
|
||||
// 当用户手动勾选数据行的 Checkbox 时触发的事件
|
||||
const handlerSelect = (selection, row) => {
|
||||
// 清除 所有勾选项
|
||||
multipleTableRef.value.clearSelection()
|
||||
if(selection.length == 0) return
|
||||
multipleTableRef.value.toggleRowSelection(row,true)
|
||||
}
|
||||
// 当选择项发生变化时会触发该事件
|
||||
const handleSelectionChange = (val) => {
|
||||
console.log('表格的选中 可以获得当前选中的数据',val);
|
||||
selectedAddRow.value = val
|
||||
}
|
||||
// 新增按钮方法
|
||||
const addForm = () => {
|
||||
resetAddForm()
|
||||
getAddList()
|
||||
addDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 重置新增表单
|
||||
const resetAddForm = () => {
|
||||
addQueryParams.projectCode = ''
|
||||
addQueryParams.projectSubName = ''
|
||||
selectedAddRow.value = null
|
||||
}
|
||||
|
||||
// 获取可选项目列表
|
||||
const getAddList = async () => {
|
||||
try {
|
||||
loading3.value = true;
|
||||
const params = {
|
||||
projectCode: addQueryParams.projectCode,
|
||||
projectSubName: addQueryParams.projectSubName
|
||||
}
|
||||
const res = await PlansubdetailApi.pageAddList(params)
|
||||
console.log(res)
|
||||
addList.value = res.list;
|
||||
addtotal.value = res.total;
|
||||
} catch (error) {
|
||||
message.error('获取项目列表失败:' + error.message)
|
||||
}finally{
|
||||
loading3.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 行选择处理
|
||||
const handleRowSelect = (row) => {
|
||||
selectedAddRow.value = row
|
||||
}
|
||||
|
||||
// 取消新增
|
||||
const handleAddCancel = () => {
|
||||
ElMessageBox.confirm('是否退出新增?', '提示', {
|
||||
confirmButtonText: '是',
|
||||
cancelButtonText: '否',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
addDialogVisible.value = false
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
|
||||
// 确认新增
|
||||
const handleAddConfirm = () => {
|
||||
for(var i = 0 ; i < list.value.length ; i++ ){
|
||||
var item = list.value[i];
|
||||
if(!item.id){
|
||||
message.warning('列表中存在未保存数据,请确认!');
|
||||
return
|
||||
}
|
||||
}
|
||||
if (!selectedAddRow.value) {
|
||||
message.warning('请先选择要添加的项目')
|
||||
return
|
||||
}
|
||||
selectedAddRow.value[0].twoDimDate = null;
|
||||
selectedAddRow.value[0].startTwoDimDate = null;
|
||||
selectedAddRow.value[0].twoDimOwner = null;
|
||||
selectedAddRow.value[0].subType = null;
|
||||
selectedAddRow.value[0].designNum = null;
|
||||
selectedAddRow.value[0].seqNo = null;
|
||||
selectedAddRow.value[0].isAdd = 1;
|
||||
selectedAddRow.value[0].flag = 1;
|
||||
selectedAddRow.value[0].userFlag = true;
|
||||
selectedAddRow.value[0].id = null;
|
||||
list.value.push(selectedAddRow.value[0])
|
||||
addDialogVisible.value = false
|
||||
message.success('项目添加成功')
|
||||
}
|
||||
|
||||
// 查询按钮操作
|
||||
const handleAddQuery = () => {
|
||||
getAddList()
|
||||
}
|
||||
|
||||
// 添加一个标志位防止无限循环
|
||||
let isProcessingChange = false
|
||||
// 检查是否为新增行
|
||||
const isNewRow = (row) => {
|
||||
return row.isAdd === 1
|
||||
}
|
||||
const saveForm = async () => {
|
||||
try {
|
||||
if (list.value) {
|
||||
loading.value = true
|
||||
for(var i = 0 ; i < list.value.length ;i++){
|
||||
var item = list.value[i]
|
||||
if (item.isOverProcess) {
|
||||
item.isOverProcess = 1
|
||||
} else {
|
||||
item.isOverProcess = 0
|
||||
}
|
||||
if(!item.id){
|
||||
console.log(item)
|
||||
var type = ("BLUEPRINT_WORKBLANK" == (item.subType))?"毛坯":("BLUEPRINT_2D" == (item.subType))?"2D":("BLUEPRINT_3D" == (item.subType))?'3D':'新增数据';
|
||||
|
||||
message.error('该子项目'+item.name+(type == '新增数据'?'新增数据':'设计类型:'+type)+' ,没有保存请确认!')
|
||||
return
|
||||
}
|
||||
}
|
||||
// 调用后端接口
|
||||
const updateReqVO = {
|
||||
list: list.value
|
||||
}
|
||||
const res = await PlansubdetailApi.operate(updateReqVO)
|
||||
if (res) {
|
||||
message.success('保存成功')
|
||||
}
|
||||
} else {
|
||||
message.error('失败:当前页面无数据可供保存')
|
||||
}
|
||||
reload() // 刷新列表
|
||||
} catch (error) {
|
||||
message.error('失败:' + error.message)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
if (queryParams.beginTime) {
|
||||
queryParams.startTime = queryParams.beginTime + ' 00:00:00'
|
||||
}
|
||||
const data = await PlansubdetailApi.getPlanSubDetailPage(queryParams)
|
||||
list.value = data.list
|
||||
list.value.forEach(item => {
|
||||
list.value.forEach((item) => {
|
||||
item.isAdd = 0
|
||||
})
|
||||
total.value = data.total
|
||||
@ -187,18 +564,175 @@ const getList = async () => {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
// 添加弹窗相关变量
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('插活前')
|
||||
const currentRow = ref(null)
|
||||
const insertList = ref([])
|
||||
|
||||
const modification = (row) => {
|
||||
console.log(row)
|
||||
const modification = async (row) => {
|
||||
var data = row as unknown as PlansubdetailApi.PlanSubDetailVO
|
||||
const res = await PlansubdetailApi.modificationPlanSubDetail(data)
|
||||
if (res.list) {
|
||||
//弹框
|
||||
currentRow.value = row
|
||||
insertList.value = res.list
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = '插活前'
|
||||
} else {
|
||||
message.success('成功')
|
||||
}
|
||||
}
|
||||
|
||||
// 新增行方法
|
||||
const addItemRow = (row) => {
|
||||
if(row.id){
|
||||
// 创建新行数据,复制当前行的所有属性
|
||||
const newRow = {
|
||||
...row,
|
||||
// 清空或重置特定字段
|
||||
id: null, // 新增行id为空
|
||||
startTwoDimDate: undefined, // 开始日期为空
|
||||
twoDimDate: undefined, // 结束日期为空
|
||||
designNum: undefined, // 设计天数为空
|
||||
seqNo: undefined, // 时间段顺序为空
|
||||
isAdd: 1, // 标记为新增行
|
||||
flag: 1, // 标记为可编辑状态
|
||||
userFlag: true
|
||||
}
|
||||
|
||||
// 获取当前行在列表中的索引
|
||||
const currentIndex = list.value.findIndex((item) => item === row)
|
||||
|
||||
// 在当前行后面插入新行
|
||||
if (currentIndex !== -1) {
|
||||
list.value.splice(currentIndex + 1, 0, newRow)
|
||||
} else {
|
||||
// 如果找不到当前行,添加到末尾
|
||||
list.value.push(newRow)
|
||||
}
|
||||
|
||||
//message.success('新增行成功')
|
||||
}else{
|
||||
message.error('该数据未保存,请确认')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const getSearchRlTs = async (row, startDateTime: string, endDateTime: string) => {
|
||||
let data = await PlanSubApi.getSearchRlTsS(
|
||||
formatDate(startDateTime, 'YYYY-MM-DD'),
|
||||
formatDate(endDateTime, 'YYYY-MM-DD')
|
||||
)
|
||||
row.designNum = data
|
||||
}
|
||||
|
||||
const handleCancelDialog = () => {
|
||||
ElMessageBox.confirm('是否退出插活?', '提示', {
|
||||
confirmButtonText: '是',
|
||||
cancelButtonText: '否',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
dialogVisible.value = false
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户点击否,不做任何操作
|
||||
})
|
||||
}
|
||||
const handleInsert = async () => {
|
||||
loading2.value = true
|
||||
// 这里可以添加插活后的逻辑
|
||||
if (currentRow.value) {
|
||||
const newRow = { ...currentRow.value }
|
||||
newRow.id = null // 设置id为空
|
||||
insertList.value.push(newRow)
|
||||
insertList.value.forEach((item) => {
|
||||
if (item.isOverProcess) {
|
||||
item.isOverProcess = 1
|
||||
} else {
|
||||
item.isOverProcess = 0
|
||||
}
|
||||
})
|
||||
try {
|
||||
const updateReqVO = {
|
||||
list: insertList.value
|
||||
}
|
||||
// 调用后端接口
|
||||
const res = await PlansubdetailApi.chahuoPlanSubDetail(updateReqVO)
|
||||
insertList.value = res.list
|
||||
dialogTitle.value = '插活后'
|
||||
// if (res) {
|
||||
// message.success('插活成功')
|
||||
// dialogVisible.value = false
|
||||
// reload() // 刷新列表
|
||||
// }
|
||||
} catch (error) {
|
||||
message.error('插活失败:' + error.message)
|
||||
} finally {
|
||||
loading2.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 确认操作
|
||||
const handleConfirm = async () => {
|
||||
// 这里添加确认逻辑
|
||||
try {
|
||||
loading2.value = true
|
||||
const updateReqVO = {
|
||||
list: insertList.value
|
||||
}
|
||||
// 调用后端接口
|
||||
const res = await PlansubdetailApi.savechahuoPlanSubDetail(updateReqVO)
|
||||
if (res) {
|
||||
message.success('插活成功')
|
||||
dialogVisible.value = false
|
||||
}
|
||||
} catch (error) {
|
||||
message.error('插活失败:' + error.message)
|
||||
} finally {
|
||||
loading2.value = false
|
||||
reload() // 刷新列表
|
||||
}
|
||||
|
||||
dialogVisible.value = false
|
||||
message.success('插活成功')
|
||||
}
|
||||
// 禁用过去日期
|
||||
const disabledFutureDates = (time) => {
|
||||
const today = new Date()
|
||||
today.setHours(0, 0, 0, 0)
|
||||
return time.getTime() < today.getTime()
|
||||
}
|
||||
// 修改删除方法,处理新增行的删除
|
||||
const handleDelete = async (row) => {
|
||||
if (row.isAdd === 1) {
|
||||
// 新增行直接从列表中移除
|
||||
const index = list.value.findIndex((item) => item === row)
|
||||
if (index !== -1) {
|
||||
list.value.splice(index, 1)
|
||||
message.success('删除成功')
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 原有行的删除逻辑
|
||||
var today = new Date().toLocaleDateString('en-CA')
|
||||
var startDate = new Date(row.startTwoDimDate).toLocaleDateString('en-CA')
|
||||
if (today > startDate) {
|
||||
message.error('当前日期>开始日期,不允许删除')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await PlansubdetailApi.deletePlanSubDetail(row.id)
|
||||
message.success('删除成功')
|
||||
reload() // 刷新列表
|
||||
} catch (e) {
|
||||
console.error('删除失败:', e)
|
||||
}
|
||||
}
|
||||
const change1 = async (row: any, type: number) => {
|
||||
if (isProcessingChange) return // 防止重复处理
|
||||
isProcessingChange = true
|
||||
@ -207,11 +741,11 @@ const change1 = async (row: any, type: number) => {
|
||||
if (row.startTwoDimDate && row.twoDimDate) {
|
||||
const startTime = new Date(row.startTwoDimDate).getTime()
|
||||
const endTime = new Date(row.twoDimDate).getTime()
|
||||
|
||||
getSearchRlTs(row, row.startTwoDimDate, row.twoDimDate)
|
||||
if (startTime > endTime) {
|
||||
// 使用 setTimeout 避免在渲染过程中直接调用 message.error
|
||||
setTimeout(() => {
|
||||
message.error("开始日期不能大于结束日期,请确认!")
|
||||
message.error('开始日期不能大于结束日期,请确认!')
|
||||
}, 100)
|
||||
|
||||
if (type === 0) {
|
||||
@ -230,7 +764,7 @@ const change1 = async (row: any, type: number) => {
|
||||
|
||||
if (data <= 0) {
|
||||
setTimeout(() => {
|
||||
message.error("选择的日期是节假日,请确认!")
|
||||
message.error('选择的日期是节假日,请确认!')
|
||||
}, 100)
|
||||
|
||||
if (type === 0) {
|
||||
@ -249,7 +783,7 @@ const handleQuery = () => {
|
||||
if (queryParams.twoDimOwner == null) {
|
||||
// 使用 setTimeout 避免渲染过程中直接调用 message.error
|
||||
setTimeout(() => {
|
||||
message.error("负责人为空,请确认")
|
||||
message.error('负责人为空,请确认')
|
||||
}, 100)
|
||||
return // 添加 return 防止继续执行
|
||||
}
|
||||
@ -276,13 +810,48 @@ const resetQuery = () => {
|
||||
onMounted(async () => {
|
||||
try {
|
||||
// 取消注释并正确初始化
|
||||
userInit.value = await UserApi.getDeptName("设计部")
|
||||
userInit.value = await UserApi.getDeptName('设计部')
|
||||
await getList()
|
||||
} catch (error) {
|
||||
console.error('初始化失败:', error)
|
||||
setTimeout(() => {
|
||||
message.error("初始化数据失败")
|
||||
message.error('初始化数据失败')
|
||||
}, 100)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style scoped>
|
||||
.dialog-content {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.date-info {
|
||||
margin-bottom: 20px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.status-title {
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.status-title h3 {
|
||||
margin: 0;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.dialog-footer .el-button {
|
||||
margin: 0 10px;
|
||||
min-width: 100px;
|
||||
}
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -18,7 +18,7 @@
|
||||
<el-button @click="outopen">取消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
<printFinalDialog ref="printref" :minAmount="minAmount" :formData="formData" />
|
||||
<printFinalDialog ref="printref" :minAmount="minAmount" :formData="formData" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -31,7 +31,7 @@ const startPageNum = ref(0);
|
||||
const endPageNum = ref(0);
|
||||
const printref = ref()
|
||||
const onPrint = () => {
|
||||
printref.value.open(cnenList.value)
|
||||
printref.value.open(cnenList.value)
|
||||
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ const cnenList = ref([])
|
||||
const bomCodes = ref('')
|
||||
|
||||
const open = async (vals) => {
|
||||
const sortedVals = [...vals].sort((a, b) => {
|
||||
const sortedVals = [...vals].sort((a, b) => {
|
||||
return b.id - a.id;
|
||||
});
|
||||
|
||||
@ -78,8 +78,8 @@ const open = async (vals) => {
|
||||
|
||||
const formattedDate = `物料编码:${item.code},规格:${item.spec},简称:${item.name},库区:${item.rg},库位:${item.pg}`;
|
||||
const qrCodeData = await QRCode.toDataURL(formattedDate ,{
|
||||
errorCorrectionLevel: 'H'
|
||||
})
|
||||
errorCorrectionLevel: 'H'
|
||||
})
|
||||
const qrCodeElement = document.getElementById('qrCodeContainer')
|
||||
if (qrCodeElement) {
|
||||
(qrCodeElement.innerHTML +=
|
||||
@ -130,12 +130,12 @@ const open = async (vals) => {
|
||||
</div>
|
||||
</div>
|
||||
</div>`)
|
||||
if(printCodeName.value.length > 1 && i < printCodeName.value.length - 1){
|
||||
qrCodeElement.innerHTML +=
|
||||
`<div style="height:3mm; background-color: white; color: white;width:103mm;margin-left:-3mm">
|
||||
if(printCodeName.value.length > 1 && i < printCodeName.value.length - 1){
|
||||
qrCodeElement.innerHTML +=
|
||||
`<div style="height:3mm; background-color: white; color: white;width:103mm;margin-left:-3mm">
|
||||
|
||||
</div>`
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
@ -127,11 +127,11 @@ const viewClick = async (item) => {
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
};
|
||||
const handleScan = () => {
|
||||
const handleScan = async() => {
|
||||
uni.scanCode({
|
||||
success: (res) => {
|
||||
success: async(res) => {
|
||||
searchVal.value = res.result
|
||||
handleSearch({ inputValue: res.result })
|
||||
await handleSearch({ inputValue: res.result })
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({ title: '扫码失败', icon: 'none' })
|
||||
|
||||
@ -9,5 +9,5 @@
|
||||
// export const serviceDomain = 'https://nxhs.cjyx.cc'
|
||||
// export const serviceDomain = 'https://star.hz-hl.com'
|
||||
// export const serviceDomain = 'http://222.71.165.187:9010'
|
||||
// export const serviceDomain = 'http://localhost:8080'
|
||||
// export const serviceDomain = 'http://localhost:8080'
|
||||
export const serviceDomain = 'https://nxhs.cjyx.cc'
|
||||
|
||||
BIN
mes-ui/mini-app/src/static/images/loudou.jpeg
Normal file
BIN
mes-ui/mini-app/src/static/images/loudou.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<view class="picker-view">
|
||||
<scroll-view
|
||||
v-for="(num,index) in colNum"
|
||||
:key="index"
|
||||
:style="{
|
||||
width:`${1/colNum*100}%`,
|
||||
height:'100%',
|
||||
backgroundColor:index===0?'#F6F6F6':'#FFFFFF'
|
||||
}"
|
||||
scroll-y>
|
||||
<view
|
||||
:class="['picker-view-item',modelValue[index]==item.value&&'picker-view-item-active']"
|
||||
v-for="(item,indexs) in colList[index]"
|
||||
:key="indexs"
|
||||
@click="onSelect(index,item,indexs)"
|
||||
>
|
||||
{{item.label}}
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
computed
|
||||
} from "vue";
|
||||
const props = defineProps({
|
||||
// 双向绑定
|
||||
modelValue: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
// 展示的列数
|
||||
colNum: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
// options 数据
|
||||
options: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
// 自定义节点 label、value、children 的字段
|
||||
fieldNames: {
|
||||
type: Object,
|
||||
default: ()=>{
|
||||
return {
|
||||
label: 'label',
|
||||
value: 'value',
|
||||
children: 'children',
|
||||
}
|
||||
}
|
||||
},
|
||||
// 是否全联动,默认为true,为false时,只会返回当前所选的层级
|
||||
isFullLinkage: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
})
|
||||
const emits = defineEmits(["update:modelValue","onChange"])
|
||||
const colList = computed(() => {
|
||||
const arr = [];
|
||||
let option = props.options;
|
||||
for(let i=0;i<props.colNum;i++){
|
||||
if ((props.modelValue[i] != undefined&&option)||(props.modelValue[i-1]&&option)||(i===0&&option)) {
|
||||
arr.push(funOptions(option))
|
||||
const index = option?.findIndex(item=>item[props.fieldNames.value]==props.modelValue[i])
|
||||
option = (option[index]&&option[index]?.[props.fieldNames.children])||[];
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
})
|
||||
const funOptions = (data) => {
|
||||
return data.map((item) => {
|
||||
return {
|
||||
label: item[props.fieldNames.label],
|
||||
value: item[props.fieldNames.value],
|
||||
children:item[props.fieldNames.children]||[]
|
||||
}
|
||||
})
|
||||
}
|
||||
const onSelect = (index,item,indexs) => {
|
||||
const modelValue = JSON.parse(JSON.stringify(props.modelValue))
|
||||
if(modelValue[index]!=item.value||!props.isFullLinkage){
|
||||
modelValue[index] = item.value;
|
||||
let option = item[props.fieldNames.children]||[]
|
||||
for(let i=index+1;i<props.colNum;i++){
|
||||
if(option[0]){
|
||||
if(props.isFullLinkage){
|
||||
modelValue[i] = option[0][props.fieldNames.value]
|
||||
}else{
|
||||
modelValue.splice(i,modelValue.length)
|
||||
}
|
||||
option = option[0]?.[props.fieldNames.children]||[]
|
||||
}else if(modelValue[i]){
|
||||
modelValue.splice(i,modelValue.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
emits("update:modelValue",modelValue)
|
||||
emits("onChange")
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.picker-view {
|
||||
width: 100%;
|
||||
// height: 600rpx;
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
.picker-view-item{
|
||||
padding: 30rpx 0;
|
||||
text-align: center;
|
||||
font-size:24rpx;
|
||||
color:#333333;
|
||||
}
|
||||
.picker-view-item-active{
|
||||
color:var(--dropdownThemeColor);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,629 @@
|
||||
<template>
|
||||
<view :class="['le-dropdown',isCeiling&&'le-dropdown-ceiling']"
|
||||
:style="`--dropdownThemeColor:${themeColor};--dropdownThemeColorRgb:${hexToRgb(themeColor)}`">
|
||||
<!-- 导航 -->
|
||||
<view class="le-dropdown-menu">
|
||||
<view class="le-dropdown-menu-item" v-for="(item, index) in menuList" :key="index"
|
||||
@tap.stop="menuClick(index)">
|
||||
<view class="le-flex">
|
||||
<text class="le-dropdown-menu-item-text" :style="{
|
||||
color: index === current ? themeColor : inactiveColor
|
||||
}">{{item.title}}</text>
|
||||
<view v-if="item.type==='sort'"
|
||||
:class="['le-dropdown-menu-item-arrow',item.value==='asc'&&'le-dropdown-menu-item-arrow_top',item.value==='desc'&&'le-dropdown-menu-item-arrow_bottom']">
|
||||
</view>
|
||||
<view v-if="item.type!=='sort'"
|
||||
:class="['le-dropdown-menu-item-basicarrow',index === current&&'le-dropdown-menu-item-basicarrow_rotate']">
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 展示的内容 -->
|
||||
<view class="le-dropdown-content" :style="[
|
||||
{
|
||||
transition: `opacity ${duration / 1000}s linear`,
|
||||
top:'auto',
|
||||
bottom:`calc(100vh - ${contentHeight + windowTop}px)`,
|
||||
height:`calc(100vh - ${contentHeight + windowTop}px)`
|
||||
},
|
||||
contentStyle
|
||||
]" @tap="close">
|
||||
<view ref="leDropdownContentPopupRef" class="le-dropdown-content-popup" :style="[popupStyle]"
|
||||
@tap.stop.prevent>
|
||||
<block v-for="(item,index) in menuList" :key="index">
|
||||
<!-- 单选列表 -->
|
||||
<view class="le-dropdown-popup-content le-dropdown-cell"
|
||||
v-if="item.type==='cell'&&index === current">
|
||||
<view :class="['le-dropdown-cell-item',item.value===sItem.value&&'le-dropdown-cell-active']"
|
||||
v-for="(sItem,sIndex) in item.options" :key="sIndex" @click="onSelectCell(sItem,index)">
|
||||
<view class="le-dropdown-cell-active-text">{{sItem.label}}</view>
|
||||
<view v-show="item.value===sItem.value" class="le-dropdown-cell-active-icon"></view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 级联动选择 -->
|
||||
<view class="le-dropdown-popup-content le-dropdown-picker"
|
||||
v-if="item.type==='picker'&&index === current">
|
||||
<le-dropdown-picker class="le-dropdown-picker-content" v-model="item.value" v-bind="item.componentProps"
|
||||
@onChange="onPickerChange(item,index)">
|
||||
</le-dropdown-picker>
|
||||
<view class="le-dropdown-footer">
|
||||
<view class="le-dropdown-confirm" @click="onFilterConfirm(item,index)">
|
||||
{{item.confirmText||'确定'}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 筛选 -->
|
||||
<view class="le-dropdown-popup-content le-dropdown-filter"
|
||||
v-if="item.type==='filter'&&index === current">
|
||||
<view class="le-dropdown-filter-scroll">
|
||||
<view class="le-dropdown-filter-item" v-for="(sItem,sIndex) in item.children" :key="sIndex">
|
||||
<view class="le-dropdown-filter-title">
|
||||
{{sItem.title}}
|
||||
<text class="le-dropdown-filter-subtitle"
|
||||
v-if="sItem.type==='slider'">{{sItem.value}}{{sItem.suffix}}</text>
|
||||
</view>
|
||||
<view class="le-dropdown-filter-content">
|
||||
<!-- 单选类型 -->
|
||||
<block v-if="sItem.type==='radio'">
|
||||
<view v-for="(ssItem,ssIndex) in sItem.options"
|
||||
:class="['le-dropdown-filter-box',sItem.value===ssItem.value&&'le-dropdown-filter-box-active']"
|
||||
:key="ssIndex" @click="onRadioFilter(sIndex,ssItem,index)">
|
||||
{{ssItem.label}}
|
||||
</view>
|
||||
</block>
|
||||
<!-- 多选类型 -->
|
||||
<block v-else-if="sItem.type==='checkbox'">
|
||||
<view v-for="(ssItem,ssIndex) in sItem.options"
|
||||
:class="['le-dropdown-filter-box',sItem.value.includes(ssItem.value)&&'le-dropdown-filter-box-active']"
|
||||
:key="ssIndex" @click="onCheckboxFilter(sIndex,ssItem,index)">
|
||||
{{ssItem.label}}
|
||||
</view>
|
||||
</block>
|
||||
<!-- 滑块类型 -->
|
||||
<block v-else-if="sItem.type==='slider'">
|
||||
<slider style="width: 100%;" :activeColor="themeColor" :value="sItem.value"
|
||||
:min="sItem.componentProps.min||0" :max="sItem.componentProps.max||100"
|
||||
:step="sItem.componentProps.step||1"
|
||||
:show-value="sItem.componentProps['show-value']||true"
|
||||
@change="onSliderChange($event,sIndex,ssItem,index)" />
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="le-dropdown-footer">
|
||||
<view class="le-dropdown-reset" @click="onFilterReset(item,index)">重置</view>
|
||||
<view class="le-dropdown-confirm" @click="onFilterConfirm(item,index)">
|
||||
{{item.confirmText||'确定'}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="le-dropdown-content-mask"></view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
/**
|
||||
* menuList 导航数据
|
||||
* @property {String} title 导航名称
|
||||
* @property {String} type =[cell|picker|sort|click|filter] 导航点击展示的类型
|
||||
* @value cell 下拉选择(单选)
|
||||
* @value picker 级联动
|
||||
* @value sort 排序
|
||||
* @value click 点击
|
||||
* @value filter 复杂筛选
|
||||
* @property {String} value 导航当前选中的值
|
||||
* @property {Array} options 导航展示可选的数据值
|
||||
* */
|
||||
import {
|
||||
ref,
|
||||
computed,
|
||||
getCurrentInstance,
|
||||
onMounted
|
||||
} from "vue";
|
||||
import cloneDeep from './utils/cloneDeep.js';
|
||||
import hexToRgb from './utils/hexToRgb.js';
|
||||
import LeDropdownPicker from "./components/le-picker.vue";
|
||||
const props = defineProps({
|
||||
// 导航数据
|
||||
menuList: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [
|
||||
|
||||
]
|
||||
}
|
||||
},
|
||||
// 主题的颜色
|
||||
themeColor: {
|
||||
type: String,
|
||||
default: "#3185FF"
|
||||
},
|
||||
// 没选中的颜色
|
||||
inactiveColor: {
|
||||
type: String,
|
||||
default: "#333333"
|
||||
},
|
||||
// 过渡时间
|
||||
duration: {
|
||||
type: [Number, String],
|
||||
default: 300
|
||||
},
|
||||
// 是否吸顶
|
||||
isCeiling: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
})
|
||||
|
||||
const emits = defineEmits(["open", "close", "update:menuList", "onConfirm", "onChange"])
|
||||
// 初始化数据用于重置使用
|
||||
const initMenuList = cloneDeep(props.menuList)
|
||||
const instance = getCurrentInstance(); // 获取组件实例
|
||||
// 下拉出来部分的样式
|
||||
const popupStyle = computed(() => {
|
||||
let style = {};
|
||||
// 进行Y轴位移,展开状态时,恢复原位。收齐状态时,往上位移100%,进行隐藏
|
||||
style.transform = `translateY(${active.value ? 0 : '-100%'})`
|
||||
style['transition-duration'] = props.duration / 1000 + 's';
|
||||
return style;
|
||||
})
|
||||
// 当前是第几个菜单处于激活状态
|
||||
const current = ref(99999);
|
||||
// 外层内容的样式,初始时处于底层,且透明
|
||||
const contentStyle = ref({
|
||||
zIndex: -1,
|
||||
opacity: 0
|
||||
})
|
||||
const active = ref(false) // 下拉菜单的状态
|
||||
const contentHeight = ref(0)
|
||||
const leDropdownContentPopupRef = ref(null)
|
||||
const windowTop = ref(0)
|
||||
uni.getSystemInfo({
|
||||
success(e) {
|
||||
windowTop.value = e.windowTop;
|
||||
}
|
||||
})
|
||||
// 点击菜单
|
||||
const menuClick = (index) => {
|
||||
getContentHeight()
|
||||
switch (props.menuList[index].type) {
|
||||
case 'sort':
|
||||
onSort(index);
|
||||
break;
|
||||
case 'click':
|
||||
onClick(index);
|
||||
break;
|
||||
default:
|
||||
// 如果点击时的索引和当前激活项索引相同,意味着点击了激活项,需要收起下拉菜单
|
||||
if (index === current.value) {
|
||||
close();
|
||||
return;
|
||||
}
|
||||
open(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 打开当前筛选窗
|
||||
const open = (index) => {
|
||||
// 展开时,设置下拉内容的样式
|
||||
active.value = true;
|
||||
contentStyle.value.zIndex = 11;
|
||||
contentStyle.value.opacity = 1;
|
||||
contentStyle.value.bottom = `0px`;
|
||||
contentStyle.value.top = `80rpx`;
|
||||
// 标记展开状态以及当前展开项的索引
|
||||
current.value = index;
|
||||
emits("open", current.value)
|
||||
}
|
||||
// 关闭当前筛选窗
|
||||
const close = () => {
|
||||
active.value = false;
|
||||
contentStyle.value.opacity = 0;
|
||||
// 等动画结束后,再移除下拉菜单中的内容,否则直接移除,也就没有下拉菜单收起的效果了
|
||||
setTimeout(() => {
|
||||
contentStyle.value.zIndex = -1;
|
||||
current.value = 99999;
|
||||
contentStyle.value.bottom = `calc(100vh - ${contentHeight.value + windowTop.value}px)`
|
||||
contentStyle.value.top = 'auto';
|
||||
}, props.duration)
|
||||
emits("close", current.value)
|
||||
}
|
||||
// 获取下拉菜单内容的高度
|
||||
const getContentHeight = () => {
|
||||
uni.createSelectorQuery()
|
||||
.in(instance)
|
||||
.selectAll('.le-dropdown-menu')
|
||||
.boundingClientRect()
|
||||
.exec(data => {
|
||||
contentHeight.value = data[0][0].bottom
|
||||
});
|
||||
}
|
||||
// 点击排序
|
||||
const onSort = (index) => {
|
||||
const type = current.value === 99999 ? current.value : props.menuList[current.value].type
|
||||
switch (type) {
|
||||
case 'sort':
|
||||
case 'click':
|
||||
case 99999:
|
||||
start()
|
||||
break;
|
||||
default:
|
||||
close();
|
||||
setTimeout(() => {
|
||||
start()
|
||||
}, props.duration)
|
||||
break;
|
||||
}
|
||||
|
||||
function start() {
|
||||
const menuList = cloneDeep(props.menuList);
|
||||
current.value = index;
|
||||
menuList[index].value = !menuList[index].value ? 'asc' : menuList[index].value == 'asc' ? 'desc' :
|
||||
null;
|
||||
emits("update:menuList", menuList)
|
||||
emits("onConfirm", menuList[index], index)
|
||||
}
|
||||
}
|
||||
// 点击按钮
|
||||
const onClick = (index) => {
|
||||
const type = current.value === 99999 ? current.value : props.menuList[current.value].type
|
||||
switch (type) {
|
||||
case 'sort':
|
||||
case 'click':
|
||||
case 99999:
|
||||
start()
|
||||
break;
|
||||
default:
|
||||
close();
|
||||
setTimeout(() => {
|
||||
start()
|
||||
}, props.duration)
|
||||
break;
|
||||
}
|
||||
|
||||
function start() {
|
||||
const menuList = cloneDeep(props.menuList);
|
||||
current.value = index;
|
||||
emits("onConfirm", menuList[index], index)
|
||||
}
|
||||
|
||||
}
|
||||
// 单选列表选中事件
|
||||
const onSelectCell = (sItem, index) => {
|
||||
const menuList = cloneDeep(props.menuList);
|
||||
if (menuList[index].autoTitle) {
|
||||
menuList[index].title = sItem.label;
|
||||
}
|
||||
menuList[index].value = sItem.value;
|
||||
emits("update:menuList", menuList)
|
||||
close();
|
||||
emits("onConfirm", menuList[index], index)
|
||||
}
|
||||
// 筛选单选选中事件
|
||||
const onRadioFilter = (sIndex, ssItem, index) => {
|
||||
const menuList = cloneDeep(props.menuList);
|
||||
menuList[index].children[sIndex].value = ssItem.value;
|
||||
emits("update:menuList", menuList)
|
||||
emits("onChange", menuList[index], sIndex, index)
|
||||
}
|
||||
// 筛选多选选中事件
|
||||
const onCheckboxFilter = (sIndex, ssItem, index) => {
|
||||
const menuList = cloneDeep(props.menuList);
|
||||
const indexs = menuList[index].children[sIndex].value.indexOf(ssItem.value)
|
||||
if (indexs != -1) {
|
||||
menuList[index].children[sIndex].value.splice(indexs, 1)
|
||||
} else {
|
||||
menuList[index].children[sIndex].value.push(ssItem.value)
|
||||
}
|
||||
emits("update:menuList", menuList)
|
||||
emits("onChange", menuList[index], sIndex, index)
|
||||
}
|
||||
// 滑块值的变化事件
|
||||
const onSliderChange = (event, sIndex, ssItem, index) => {
|
||||
const menuList = cloneDeep(props.menuList);
|
||||
menuList[index].children[sIndex].value = event.detail.value;
|
||||
emits("update:menuList", menuList)
|
||||
emits("onChange", menuList[index], sIndex, index)
|
||||
}
|
||||
// 筛选选中事件
|
||||
const onSelectFilter = (sIndex, ssItem, index) => {
|
||||
const menuList = cloneDeep(props.menuList);
|
||||
menuList[index].active[sIndex] = ssItem.value;
|
||||
emits("update:menuList", menuList)
|
||||
emits("onChange", menuList[index], sIndex, index)
|
||||
}
|
||||
// 重置筛选
|
||||
const onFilterReset = (item, index) => {
|
||||
const menuList = cloneDeep(props.menuList);
|
||||
menuList[index].children.forEach((items, indexs) => {
|
||||
items.value = initMenuList[index].children[indexs].value
|
||||
})
|
||||
emits("update:menuList", menuList)
|
||||
// close();
|
||||
// emits("onConfirm",menuList[index])
|
||||
}
|
||||
// 确定筛选
|
||||
const onFilterConfirm = (item, index) => {
|
||||
close();
|
||||
const menuList = cloneDeep(props.menuList);
|
||||
emits("onConfirm", menuList[index], index)
|
||||
}
|
||||
// 级联变化
|
||||
const onPickerChange = (item, index) => {
|
||||
const menuList = cloneDeep(props.menuList);
|
||||
emits("onChange", menuList[index], null, index)
|
||||
}
|
||||
const bindFun = (data) => {
|
||||
return data
|
||||
}
|
||||
onMounted(() => {
|
||||
getContentHeight()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.le-flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.le-dropdown {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
||||
.le-dropdown-menu {
|
||||
display: flex;
|
||||
position: relative;
|
||||
z-index: 11;
|
||||
height: 80rpx;
|
||||
|
||||
.le-dropdown-menu-item {
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.le-dropdown-menu-item-text {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.le-dropdown-menu-item-arrow {
|
||||
margin-left: 6rpx;
|
||||
transition: transform .3s;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 10rpx;
|
||||
height: 100%;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: calc(50% - 8rpx);
|
||||
right: -2rpx;
|
||||
transform: translateY(-50%);
|
||||
border: 6rpx solid transparent;
|
||||
border-bottom-color: #C1C1C1;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: calc(50% + 8rpx);
|
||||
right: -2rpx;
|
||||
transform: translateY(-50%);
|
||||
border: 6rpx solid transparent;
|
||||
border-top-color: #C1C1C1;
|
||||
}
|
||||
}
|
||||
|
||||
.le-dropdown-menu-item-arrow_top {
|
||||
&::before {
|
||||
border-bottom-color: var(--dropdownThemeColor);
|
||||
}
|
||||
}
|
||||
|
||||
.le-dropdown-menu-item-arrow_bottom {
|
||||
&::after {
|
||||
border-top-color: var(--dropdownThemeColor);
|
||||
}
|
||||
}
|
||||
|
||||
.le-dropdown-menu-item-basicarrow {
|
||||
margin-left: 6rpx;
|
||||
transition: transform .3s;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
position: relative;
|
||||
border: 6rpx solid transparent;
|
||||
border-bottom: 0rpx solid transparent;
|
||||
border-top-color: #C1C1C1;
|
||||
}
|
||||
|
||||
.le-dropdown-menu-item-basicarrow_rotate {
|
||||
transform: rotate(180deg);
|
||||
border-top-color: var(--dropdownThemeColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.le-dropdown-content {
|
||||
position: absolute;
|
||||
z-index: 8;
|
||||
width: 100%;
|
||||
left: 0px;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
|
||||
|
||||
.le-dropdown-content-mask {
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
background: rgba(0, 0, 0, .3);
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.le-dropdown-content-popup {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
overflow: auto;
|
||||
overscroll-behavior: contain;
|
||||
z-index: 10;
|
||||
transition: all 0.3s;
|
||||
transform: translate3D(0, -100%, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.le-dropdown-ceiling {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.le-dropdown-popup-content {
|
||||
font-size: 28rpx;
|
||||
border-radius: 0 0 20rpx 20rpx;
|
||||
background-color: #ffffff;
|
||||
|
||||
}
|
||||
|
||||
// 单选列表
|
||||
.le-dropdown-cell {
|
||||
padding: 0 30rpx;
|
||||
|
||||
.le-dropdown-cell-item {
|
||||
padding: 20rpx 0;
|
||||
color: #333333;
|
||||
font-size: 28rpx;
|
||||
border-bottom: 1rpx solid #D5D5D5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.le-dropdown-cell-active-text {
|
||||
flex: 1;
|
||||
padding-right: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.le-dropdown-cell-item:last-child {
|
||||
border-bottom: 0rpx solid #D5D5D5;
|
||||
}
|
||||
|
||||
.le-dropdown-cell-active {
|
||||
color: var(--dropdownThemeColor);
|
||||
|
||||
.le-dropdown-cell-active-icon {
|
||||
width: 12rpx;
|
||||
height: 28rpx;
|
||||
margin-right: 10rpx;
|
||||
border-color: var(--dropdownThemeColor);
|
||||
border-style: solid;
|
||||
border-width: 0 4rpx 4rpx 0;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 筛选
|
||||
.le-dropdown-filter {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.le-dropdown-filter-item {
|
||||
padding: 0 26rpx;
|
||||
}
|
||||
|
||||
.le-dropdown-filter-title {
|
||||
padding-top: 34rpx;
|
||||
margin-bottom: 18rpx;
|
||||
color: #333333;
|
||||
font-size: 24rpx;
|
||||
|
||||
.le-dropdown-filter-subtitle {
|
||||
margin-left: 10rpx;
|
||||
color: var(--dropdownThemeColor);
|
||||
}
|
||||
}
|
||||
|
||||
.le-dropdown-filter-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.le-dropdown-filter-box {
|
||||
width: 200rpx;
|
||||
margin-right: 30rpx;
|
||||
margin-bottom: 14rpx;
|
||||
padding: 18rpx 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
background-color: #F5F5F5;
|
||||
border-radius: 999rpx;
|
||||
}
|
||||
|
||||
.le-dropdown-filter-box-active {
|
||||
color: var(--dropdownThemeColor);
|
||||
background-color: rgba(var(--dropdownThemeColorRgb), 0.04);
|
||||
}
|
||||
}
|
||||
.le-dropdown-filter-scroll{
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
// 级联
|
||||
.le-dropdown-picker{
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.le-dropdown-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 14rpx;
|
||||
|
||||
.le-dropdown-reset {
|
||||
flex: 1;
|
||||
margin: 26rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 68rpx;
|
||||
font-size: 28rpx;
|
||||
background-color: #FFFFFF;
|
||||
color: var(--dropdownThemeColor);
|
||||
border: 2rpx solid var(--dropdownThemeColor);
|
||||
border-radius: 999rpx;
|
||||
}
|
||||
|
||||
.le-dropdown-confirm {
|
||||
flex: 1;
|
||||
margin: 26rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 68rpx;
|
||||
font-size: 28rpx;
|
||||
background-color: var(--dropdownThemeColor);
|
||||
border: 2rpx solid var(--dropdownThemeColor);
|
||||
color: #ffffff;
|
||||
border-radius: 999rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,23 @@
|
||||
export default function(hexStr){
|
||||
//十六进制颜色值的正则表达式
|
||||
let reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
|
||||
let sColor = hexStr.toLowerCase();
|
||||
if (sColor && reg.test(sColor)) {
|
||||
if (sColor.length === 4) {
|
||||
let sColorNew = "#";
|
||||
for (let i = 1; i < 4; i += 1) {
|
||||
sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
|
||||
}
|
||||
sColor = sColorNew;
|
||||
}
|
||||
//处理六位的颜色值f
|
||||
let sColorChange = [];
|
||||
for (let i = 1; i < 7; i += 2) {
|
||||
sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`));
|
||||
}
|
||||
let rgbText = sColorChange.join(",")
|
||||
return rgbText;
|
||||
} else {
|
||||
return sColor;
|
||||
}
|
||||
}
|
||||
@ -86,6 +86,7 @@ export const http = <T>(options: UniApp.RequestOptions) => {
|
||||
...options,
|
||||
// 响应成功
|
||||
success(res) {
|
||||
console.log(res)
|
||||
// 状态码 2xx, axios 就是这样设计的
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
if (res.data?.code == 0) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user