Merge remote-tracking branch 'origin/main'

ck
liutao 3 weeks ago
commit 00f5b71f27

@ -455,7 +455,7 @@ public class PlanController {
return success(planRespVOList); return success(planRespVOList);
} else if (status == 2) { } else if (status == 2) {
List<Integer> statusList = new ArrayList<>(); List<Integer> statusList = new ArrayList<>();
statusList.add(PlanStatusEnum..getValue()); statusList.add(PlanStatusEnum..getValue());
List<PlanDO> proList = planService.getPlanByStatus(statusList); List<PlanDO> proList = planService.getPlanByStatus(statusList);
List<PlanRespVO> planRespVOList = planService.buildVOList(proList); List<PlanRespVO> planRespVOList = planService.buildVOList(proList);
return success(planRespVOList); return success(planRespVOList);

@ -120,4 +120,7 @@ public class PlanSaveReqVO {
@Schema(description = "最晚开工时间") @Schema(description = "最晚开工时间")
private LocalDateTime latestStartTime; private LocalDateTime latestStartTime;
} @Schema(description = "是否计算损耗,默认是")
private Boolean isCalculateLoss;
}

@ -194,24 +194,24 @@ public class ZjSchemaController {
return null; return null;
} }
ZjSchemaRespVO respVO = BeanUtils.toBean(zjSchema, ZjSchemaRespVO.class); ZjSchemaRespVO respVO = BeanUtils.toBean(zjSchema, ZjSchemaRespVO.class);
List<Long> productIds = parseIds(zjSchema.getProduct()); // List<Long> productIds = parseIds(zjSchema.getProduct());
respVO.setProductIds(productIds); // respVO.setProductIds(productIds);
if (CollUtil.isNotEmpty(productIds)) { // if (CollUtil.isNotEmpty(productIds)) {
respVO.setProducts(erpProductService.getProductVOList(productIds)); // respVO.setProducts(erpProductService.getProductVOList(productIds));
} else { // } else {
respVO.setProducts(Collections.emptyList()); // respVO.setProducts(Collections.emptyList());
} // }
return respVO; return respVO;
} }
//
private List<Long> parseIds(String ids) { // private List<Long> parseIds(String ids) {
if (ids == null || ids.trim().isEmpty()) { // if (ids == null || ids.trim().isEmpty()) {
return Collections.emptyList(); // return Collections.emptyList();
} // }
return Arrays.stream(ids.split(",")) // return Arrays.stream(ids.split(","))
.map(String::trim) // .map(String::trim)
.filter(str -> !str.isEmpty()) // .filter(str -> !str.isEmpty())
.map(Long::valueOf) // .map(Long::valueOf)
.collect(Collectors.toList()); // .collect(Collectors.toList());
} // }
} }

@ -52,6 +52,9 @@ public class ZjSchemaRespVO {
@Schema(description = "关联产品列表") @Schema(description = "关联产品列表")
private List<ErpProductRespVO> products; private List<ErpProductRespVO> products;
@Schema(description = "关联产品")
private String product;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间") @ExcelProperty("创建时间")
@ColumnWidth(20) @ColumnWidth(20)

@ -36,4 +36,6 @@ public class ZjSchemaSaveReqVO {
@Schema(description = "关联产品 ID 列表", example = "[1,2,3]") @Schema(description = "关联产品 ID 列表", example = "[1,2,3]")
private List<Long> productIds; private List<Long> productIds;
@Schema(description = "关联产品 ID 列表", example = "1,2,3")
private String product;
} }

@ -8,6 +8,7 @@ import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ -57,4 +58,7 @@ public class ZjTaskQueryByTicketPageReqVO extends PageParam {
@Schema(description = "执行时间") @Schema(description = "执行时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] executeTime; private LocalDateTime[] executeTime;
@Schema(description = "id集合")
private List<Long> ids;
} }

@ -8,6 +8,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.common.dal.dataobject.moldrepair.MoldRepairDO; import cn.iocoder.yudao.module.common.dal.dataobject.moldrepair.MoldRepairDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.zjtask.ZjTaskDO; import cn.iocoder.yudao.module.mes.dal.dataobject.zjtask.ZjTaskDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.zjtaskresults.ZjTaskResultsDO;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.mes.controller.admin.zjtask.vo.*; import cn.iocoder.yudao.module.mes.controller.admin.zjtask.vo.*;
@ -86,7 +87,7 @@ public interface ZjTaskMapper extends BaseMapperX<ZjTaskDO> {
default PageResult<ZjTaskDO> selectPageByTicket(ZjTaskQueryByTicketPageReqVO reqVO) { default PageResult<ZjTaskDO> selectPageByTicket(ZjTaskQueryByTicketPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ZjTaskDO>() return selectPage(reqVO, new LambdaQueryWrapperX<ZjTaskDO>()
.eqIfPresent(ZjTaskDO::getTicket, reqVO.getTicket()) // .eqIfPresent(ZjTaskDO::getTicket, reqVO.getTicket())
.likeIfPresent(ZjTaskDO::getName, reqVO.getName()) .likeIfPresent(ZjTaskDO::getName, reqVO.getName())
.eqIfPresent(ZjTaskDO::getType, reqVO.getType()) .eqIfPresent(ZjTaskDO::getType, reqVO.getType())
.eqIfPresent(ZjTaskDO::getSchemaId, reqVO.getSchemaId()) .eqIfPresent(ZjTaskDO::getSchemaId, reqVO.getSchemaId())
@ -99,6 +100,7 @@ public interface ZjTaskMapper extends BaseMapperX<ZjTaskDO> {
.eqIfPresent(ZjTaskDO::getResult, reqVO.getResult()) .eqIfPresent(ZjTaskDO::getResult, reqVO.getResult())
.betweenIfPresent(ZjTaskDO::getCreateTime, reqVO.getCreateTime()) .betweenIfPresent(ZjTaskDO::getCreateTime, reqVO.getCreateTime())
.betweenIfPresent(ZjTaskDO::getExecuteTime, reqVO.getExecuteTime()) .betweenIfPresent(ZjTaskDO::getExecuteTime, reqVO.getExecuteTime())
.inIfPresent(ZjTaskDO::getId,reqVO.getIds())
.orderByDesc(ZjTaskDO::getId)); .orderByDesc(ZjTaskDO::getId));
} }
@ -116,5 +118,12 @@ public interface ZjTaskMapper extends BaseMapperX<ZjTaskDO> {
ZjTaskDO selectByNo(@Param("code") String code); ZjTaskDO selectByNo(@Param("code") String code);
default List<ZjTaskDO> selectListByTaskIds(Collection<Long> taskIds) {
return selectList(new LambdaQueryWrapperX<ZjTaskDO>()
.inIfPresent(ZjTaskDO::getTicket, taskIds)
.orderByDesc(ZjTaskDO::getId));
}
} }

@ -21,6 +21,8 @@ import cn.iocoder.yudao.module.mes.controller.admin.itemrequisition.vo.ItemRequi
import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.*; import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.*;
import cn.iocoder.yudao.module.mes.controller.admin.planrecord.vo.PlanRecordRespVO; import cn.iocoder.yudao.module.mes.controller.admin.planrecord.vo.PlanRecordRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.task.vo.TaskStatusEnum; import cn.iocoder.yudao.module.mes.controller.admin.task.vo.TaskStatusEnum;
import cn.iocoder.yudao.module.mes.dal.dataobject.bom.BomDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.bom.BomDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.deviceledger.DeviceLedgerDO; import cn.iocoder.yudao.module.mes.dal.dataobject.deviceledger.DeviceLedgerDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.itemrequisition.ItemRequisitionDetailDO; import cn.iocoder.yudao.module.mes.dal.dataobject.itemrequisition.ItemRequisitionDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.organization.OrganizationDO; import cn.iocoder.yudao.module.mes.dal.dataobject.organization.OrganizationDO;
@ -30,6 +32,8 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.planrecord.PlanRecordDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.task.TaskDO; import cn.iocoder.yudao.module.mes.dal.dataobject.task.TaskDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.task.TaskDetailDO; import cn.iocoder.yudao.module.mes.dal.dataobject.task.TaskDetailDO;
import cn.iocoder.yudao.module.mes.dal.mysql.deviceledger.DeviceLedgerMapper; import cn.iocoder.yudao.module.mes.dal.mysql.deviceledger.DeviceLedgerMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.bom.BomMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.bom.BomDetailMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.paigongrecord.PaigongRecordMapper; import cn.iocoder.yudao.module.mes.dal.mysql.paigongrecord.PaigongRecordMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.plan.PlanMapper; import cn.iocoder.yudao.module.mes.dal.mysql.plan.PlanMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.planrecord.PlanRecordMapper; import cn.iocoder.yudao.module.mes.dal.mysql.planrecord.PlanRecordMapper;
@ -59,6 +63,7 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
@ -120,6 +125,10 @@ public class PlanServiceImpl implements PlanService {
@Resource @Resource
private PlanRecordMapper planRecordMapper; private PlanRecordMapper planRecordMapper;
@Resource
private BomMapper bomMapper;
@Resource
private BomDetailMapper bomDetailMapper;
@ -145,6 +154,9 @@ public class PlanServiceImpl implements PlanService {
} }
if (plan.getIsEnable() == null) plan.setIsEnable(true); if (plan.getIsEnable() == null) plan.setIsEnable(true);
if(plan.getPriorityNum()==null) plan.setPriorityNum(1L); if(plan.getPriorityNum()==null) plan.setPriorityNum(1L);
if (createReqVO.getIsCalculateLoss() == null) {
createReqVO.setIsCalculateLoss(true);
}
// todo // todo
// planMapper.insert(plan); // planMapper.insert(plan);
// 返回 // 返回
@ -154,12 +166,13 @@ public class PlanServiceImpl implements PlanService {
taskService.updateTask(taskDO); taskService.updateTask(taskDO);
} }
List<ItemRequisitionAndStock> list = analysisService.getItemAnalysis(plan); // 产品 num List<ItemRequisitionAndStock> list = analysisService.getItemAnalysis(plan); // 产品 num
Map<Long, BigDecimal> bomYieldRateMap = buildBomYieldRateMap(plan.getProductId(), createReqVO.getIsCalculateLoss());
List<ItemRequisitionDetailDO> itemRequisitionDetails = new ArrayList<>(); List<ItemRequisitionDetailDO> itemRequisitionDetails = new ArrayList<>();
for (ItemRequisitionAndStock item : list) { for (ItemRequisitionAndStock item : list) {
ItemRequisitionDetailDO detailDO = new ItemRequisitionDetailDO() ItemRequisitionDetailDO detailDO = new ItemRequisitionDetailDO()
.setProductId(item.getItemId()) .setProductId(item.getItemId())
.setUnitId(item.getUnitId()) .setUnitId(item.getUnitId())
.setNumber(item.getNumber()) .setNumber(calculateLossNumber(item.getItemId(), item.getNumber(), bomYieldRateMap, createReqVO.getIsCalculateLoss()))
.setIsEnable(true); .setIsEnable(true);
itemRequisitionDetails.add(detailDO); itemRequisitionDetails.add(detailDO);
} }
@ -257,7 +270,7 @@ public class PlanServiceImpl implements PlanService {
ErpStockOutSaveReqVO.Item item = new ErpStockOutSaveReqVO.Item(); ErpStockOutSaveReqVO.Item item = new ErpStockOutSaveReqVO.Item();
item.setWarehouseId(warehouse.getId()); item.setWarehouseId(warehouse.getId());
item.setProductId(requisition.getItemId()); item.setProductId(requisition.getItemId());
item.setCount(requisition.getNumber()); item.setCount(calculateLossNumber(requisition.getItemId(), requisition.getNumber(), bomYieldRateMap, createReqVO.getIsCalculateLoss()));
itemList.add(item); itemList.add(item);
} }
stockOut.setItems(itemList); stockOut.setItems(itemList);
@ -266,6 +279,45 @@ public class PlanServiceImpl implements PlanService {
return plan.getId(); return plan.getId();
} }
private Map<Long, BigDecimal> buildBomYieldRateMap(Long productId, Boolean isCalculateLoss) {
if (!Boolean.TRUE.equals(isCalculateLoss) || productId == null) {
return Collections.emptyMap();
}
BomDO bomDO = bomMapper.selectByProductId(productId);
if (bomDO == null || bomDO.getId() == null) {
return Collections.emptyMap();
}
List<BomDetailDO> bomDetails = bomDetailMapper.selectList(
Wrappers.<BomDetailDO>lambdaQuery()
.eq(BomDetailDO::getBomId, bomDO.getId())
.eq(BomDetailDO::getIsEnable, true)
);
if (CollUtil.isEmpty(bomDetails)) {
return Collections.emptyMap();
}
return bomDetails.stream()
.filter(detail -> detail.getProductId() != null)
.collect(Collectors.toMap(
BomDetailDO::getProductId,
BomDetailDO::getYieldRate,
(first, second) -> first
));
}
private BigDecimal calculateLossNumber(Long itemId, BigDecimal originalNumber,
Map<Long, BigDecimal> bomYieldRateMap,
Boolean isCalculateLoss) {
if (!Boolean.TRUE.equals(isCalculateLoss) || itemId == null || originalNumber == null) {
return originalNumber;
}
BigDecimal yieldRate = bomYieldRateMap.get(itemId);
if (yieldRate == null) {
return originalNumber;
}
BigDecimal rate = yieldRate.divide(BigDecimal.valueOf(100), 8, RoundingMode.HALF_UP);
return originalNumber.multiply(BigDecimal.ONE.add(rate)).stripTrailingZeros();
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void createPlanStockIn(PlanStatusUpdateVO statusUpdateVO,PlanDO planDO) { public void createPlanStockIn(PlanStatusUpdateVO statusUpdateVO,PlanDO planDO) {

@ -31,7 +31,6 @@ public class ZjSchemaServiceImpl implements ZjSchemaService {
@Override @Override
public Long createZjSchema(ZjSchemaSaveReqVO createReqVO) { public Long createZjSchema(ZjSchemaSaveReqVO createReqVO) {
ZjSchemaDO zjSchema = BeanUtils.toBean(createReqVO, ZjSchemaDO.class); ZjSchemaDO zjSchema = BeanUtils.toBean(createReqVO, ZjSchemaDO.class);
zjSchema.setProduct(joinProductIds(createReqVO.getProductIds()));
zjSchemaMapper.insert(zjSchema); zjSchemaMapper.insert(zjSchema);
return zjSchema.getId(); return zjSchema.getId();
} }
@ -40,7 +39,6 @@ public class ZjSchemaServiceImpl implements ZjSchemaService {
public void updateZjSchema(ZjSchemaSaveReqVO updateReqVO) { public void updateZjSchema(ZjSchemaSaveReqVO updateReqVO) {
validateZjSchemaExists(updateReqVO.getId()); validateZjSchemaExists(updateReqVO.getId());
ZjSchemaDO updateObj = BeanUtils.toBean(updateReqVO, ZjSchemaDO.class); ZjSchemaDO updateObj = BeanUtils.toBean(updateReqVO, ZjSchemaDO.class);
updateObj.setProduct(joinProductIds(updateReqVO.getProductIds()));
zjSchemaMapper.updateById(updateObj); zjSchemaMapper.updateById(updateObj);
} }
@ -82,14 +80,5 @@ public class ZjSchemaServiceImpl implements ZjSchemaService {
return list == null || list.isEmpty() ? zjSchemaMapper.selectList() : list; return list == null || list.isEmpty() ? zjSchemaMapper.selectList() : list;
} }
private String joinProductIds(List<Long> productIds) {
if (productIds == null || productIds.isEmpty()) {
return null;
}
return productIds.stream().filter(Objects::nonNull)
.map(String::valueOf)
.distinct()
.collect(Collectors.joining(","));
}
} }

@ -14,6 +14,7 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.zjitem.ZjItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.zjschema.ZjSchemaDO; import cn.iocoder.yudao.module.mes.dal.dataobject.zjschema.ZjSchemaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.zjtaskresults.ZjTaskResultsDO; import cn.iocoder.yudao.module.mes.dal.dataobject.zjtaskresults.ZjTaskResultsDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.zjtype.ZjTypeDO; import cn.iocoder.yudao.module.mes.dal.dataobject.zjtype.ZjTypeDO;
import cn.iocoder.yudao.module.mes.dal.mysql.plan.PlanMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.zjitem.ZjItemMapper; import cn.iocoder.yudao.module.mes.dal.mysql.zjitem.ZjItemMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.zjschema.ZjSchemaMapper; import cn.iocoder.yudao.module.mes.dal.mysql.zjschema.ZjSchemaMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.zjtaskresults.ZjTaskResultsMapper; import cn.iocoder.yudao.module.mes.dal.mysql.zjtaskresults.ZjTaskResultsMapper;
@ -65,7 +66,8 @@ public class ZjTaskServiceImpl implements ZjTaskService {
@Resource @Resource
private ZjItemMapper zjItemMapper; // 检验项目Mapper用于关联查询方案下的项目 private ZjItemMapper zjItemMapper; // 检验项目Mapper用于关联查询方案下的项目
@Resource
private PlanMapper planMapper; // 检验项目Mapper用于关联查询方案下的项目
@Resource @Resource
private PlanService planService; private PlanService planService;
@Resource @Resource
@ -227,6 +229,19 @@ public class ZjTaskServiceImpl implements ZjTaskService {
@Override @Override
public PageResult<ZjTaskDO> getZjTaskPageByTicket(ZjTaskQueryByTicketPageReqVO pageReqVO) { public PageResult<ZjTaskDO> getZjTaskPageByTicket(ZjTaskQueryByTicketPageReqVO pageReqVO) {
List<PlanDO> planDOS = planMapper.selectList(Wrappers.<PlanDO>lambdaQuery().eq(PlanDO::getTaskId, pageReqVO.getTicket()));
List<Long> idList = planDOS.stream()
.map(PlanDO::getId)
.collect(Collectors.toList());
if(idList.isEmpty()){
return new PageResult<>();
}
List<ZjTaskDO> zjTaskDOList = zjTaskMapper.selectListByTaskIds(idList);
List<Long> taskList = zjTaskDOList.stream()
.map(ZjTaskDO::getId)
.collect(Collectors.toList());
pageReqVO.setIds(taskList);
PageResult<ZjTaskDO> pageResult = zjTaskMapper.selectPageByTicket(pageReqVO); PageResult<ZjTaskDO> pageResult = zjTaskMapper.selectPageByTicket(pageReqVO);
Map<Long, PlanDO> planMap = planService.getPlanMap(convertSet(pageResult.getList(), ZjTaskDO::getTicket)); Map<Long, PlanDO> planMap = planService.getPlanMap(convertSet(pageResult.getList(), ZjTaskDO::getTicket));
return BeanUtils.toBean(pageResult, ZjTaskDO.class, zjTaskDO -> { return BeanUtils.toBean(pageResult, ZjTaskDO.class, zjTaskDO -> {

@ -1,11 +1,20 @@
package cn.iocoder.yudao.module.mes.service.zjtaskresults; package cn.iocoder.yudao.module.mes.service.zjtaskresults;
import cn.iocoder.yudao.module.mes.dal.dataobject.plan.PlanDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.zjtask.ZjTaskDO;
import cn.iocoder.yudao.module.mes.dal.mysql.plan.PlanMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.task.TaskMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.zjtask.ZjTaskMapper;
import cn.iocoder.yudao.module.mes.service.task.TaskService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
import cn.iocoder.yudao.module.mes.controller.admin.zjtaskresults.vo.*; import cn.iocoder.yudao.module.mes.controller.admin.zjtaskresults.vo.*;
import cn.iocoder.yudao.module.mes.dal.dataobject.zjtaskresults.ZjTaskResultsDO; import cn.iocoder.yudao.module.mes.dal.dataobject.zjtaskresults.ZjTaskResultsDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
@ -29,6 +38,15 @@ public class ZjTaskResultsServiceImpl implements ZjTaskResultsService {
@Resource @Resource
private ZjTaskResultsMapper zjTaskResultsMapper; private ZjTaskResultsMapper zjTaskResultsMapper;
@Resource
private ZjTaskMapper zjTaskMapper;
@Resource
private TaskMapper taskMapper;
@Resource
private PlanMapper planMapper;
@Override @Override
public Long createZjTaskResults(ZjTaskResultsSaveReqVO createReqVO) { public Long createZjTaskResults(ZjTaskResultsSaveReqVO createReqVO) {
// 插入 // 插入

Loading…
Cancel
Save