工料机、定额基价、定额费率、定额取费

This commit is contained in:
2026-01-03 14:54:15 +08:00
parent 638a87f919
commit 27904a9257
120 changed files with 6744 additions and 2715 deletions

View File

@@ -1,222 +0,0 @@
package com.yhy.module.core.controller.admin.quota;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import com.yhy.module.core.controller.admin.quota.vo.*;
import com.yhy.module.core.convert.quota.QuotaAdjustmentConvert;
import com.yhy.module.core.dal.dataobject.quota.QuotaAdjustmentDO;
import com.yhy.module.core.service.quota.QuotaAdjustmentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 定额调整设置")
@RestController
@RequestMapping("/core/quota/adjustment")
@Validated
public class QuotaAdjustmentController {
@Resource
private QuotaAdjustmentService quotaAdjustmentService;
@PostMapping("/create")
@Operation(summary = "创建定额调整设置")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:create')")
public CommonResult<Long> createQuotaAdjustment(@Valid @RequestBody QuotaAdjustmentSaveReqVO createReqVO) {
return success(quotaAdjustmentService.createQuotaAdjustment(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新定额调整设置")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:update')")
public CommonResult<Boolean> updateQuotaAdjustment(@Valid @RequestBody QuotaAdjustmentSaveReqVO updateReqVO) {
quotaAdjustmentService.updateQuotaAdjustment(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除定额调整设置")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:delete')")
public CommonResult<Boolean> deleteQuotaAdjustment(@RequestParam("id") Long id) {
quotaAdjustmentService.deleteQuotaAdjustment(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得定额调整设置")
@Parameter(name = "id", description = "编号", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:query')")
public CommonResult<QuotaAdjustmentRespVO> getQuotaAdjustment(@RequestParam("id") Long id) {
QuotaAdjustmentDO adjustment = quotaAdjustmentService.getQuotaAdjustment(id);
return success(QuotaAdjustmentConvert.INSTANCE.convert(adjustment));
}
@GetMapping("/list")
@Operation(summary = "获得定额调整设置列表")
@Parameter(name = "quotaItemId", description = "定额子目ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:query')")
public CommonResult<List<QuotaAdjustmentRespVO>> getQuotaAdjustmentList(@RequestParam("quotaItemId") Long quotaItemId) {
List<QuotaAdjustmentDO> list = quotaAdjustmentService.getQuotaAdjustmentList(quotaItemId);
return success(QuotaAdjustmentConvert.INSTANCE.convertList(list));
}
@PostMapping("/swap-sort")
@Operation(summary = "交换排序")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:update')")
public CommonResult<Boolean> swapSort(@Valid @RequestBody QuotaAdjustmentSwapSortReqVO reqVO) {
quotaAdjustmentService.swapSort(reqVO.getId1(), reqVO.getId2());
return success(true);
}
@PostMapping("/save-material-items")
@Operation(summary = "保存材料调整明细")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:update')")
public CommonResult<Boolean> saveMaterialItems(@Valid @RequestBody QuotaAdjustmentMaterialItemsReqVO reqVO) {
List<Map<String, Object>> items = new java.util.ArrayList<>();
for (QuotaAdjustmentMaterialItemVO item : reqVO.getItems()) {
Map<String, Object> itemMap = new java.util.HashMap<>();
itemMap.put("sortOrder", item.getSortOrder());
itemMap.put("resourceCode", item.getResourceCode());
itemMap.put("resourceName", item.getResourceName());
itemMap.put("adjustValue", item.getAdjustValue());
itemMap.put("remark", item.getRemark());
items.add(itemMap);
}
quotaAdjustmentService.saveMaterialItems(reqVO.getAdjustmentId(), items);
return success(true);
}
@GetMapping("/get-material-items")
@Operation(summary = "获取材料调整明细")
@Parameter(name = "adjustmentId", description = "调整设置ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:query')")
public CommonResult<List<Map<String, Object>>> getMaterialItems(@RequestParam("adjustmentId") Long adjustmentId) {
return success(quotaAdjustmentService.getMaterialItems(adjustmentId));
}
@GetMapping("/get-available-categories")
@Operation(summary = "获取可配置的类别列表")
@Parameter(name = "quotaItemId", description = "定额子目ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:query')")
public CommonResult<List<Map<String, Object>>> getAvailableCategories(@RequestParam("quotaItemId") Long quotaItemId) {
return success(quotaAdjustmentService.getAvailableCategories(quotaItemId));
}
@PostMapping("/save-dynamic-config")
@Operation(summary = "保存动态调整配置")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:update')")
public CommonResult<Boolean> saveDynamicConfig(@Valid @RequestBody QuotaAdjustmentDynamicConfigReqVO reqVO) {
List<Map<String, Object>> categories = new java.util.ArrayList<>();
for (QuotaAdjustmentDynamicCategoryVO category : reqVO.getCategories()) {
Map<String, Object> categoryMap = new java.util.HashMap<>();
categoryMap.put("categoryId", category.getCategoryId());
categoryMap.put("categoryName", category.getCategoryName());
categoryMap.put("categoryType", category.getCategoryType());
categoryMap.put("coefficient", category.getCoefficient());
categoryMap.put("minValue", category.getMinValue());
categoryMap.put("maxValue", category.getMaxValue());
categoryMap.put("denominator", category.getDenominator());
categoryMap.put("baseValue", category.getBaseValue());
categoryMap.put("roundingRule", category.getRoundingRule());
categories.add(categoryMap);
}
quotaAdjustmentService.saveDynamicConfig(reqVO.getAdjustmentId(), categories);
return success(true);
}
@GetMapping("/get-dynamic-config")
@Operation(summary = "获取动态调整配置")
@Parameter(name = "adjustmentId", description = "调整设置ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:query')")
public CommonResult<List<Map<String, Object>>> getDynamicConfig(@RequestParam("adjustmentId") Long adjustmentId) {
return success(quotaAdjustmentService.getDynamicConfig(adjustmentId));
}
@PostMapping("/calculate-dynamic")
@Operation(summary = "计算动态调整结果")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:query')")
public CommonResult<Map<String, BigDecimal>> calculateDynamic(@Valid @RequestBody QuotaAdjustmentDynamicCalculateReqVO reqVO) {
return success(quotaAdjustmentService.calculateDynamic(reqVO.getAdjustmentId(), reqVO.getInputValues()));
}
@PostMapping("/save-coefficient-config")
@Operation(summary = "保存系数调整配置")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:update')")
public CommonResult<Boolean> saveCoefficientConfig(@Valid @RequestBody QuotaAdjustmentCoefficientConfigReqVO reqVO) {
List<Map<String, Object>> categories = new java.util.ArrayList<>();
for (QuotaAdjustmentCoefficientCategoryVO category : reqVO.getCategories()) {
Map<String, Object> categoryMap = new java.util.HashMap<>();
categoryMap.put("categoryId", category.getCategoryId());
categoryMap.put("categoryName", category.getCategoryName());
categoryMap.put("categoryType", category.getCategoryType());
categoryMap.put("coefficient", category.getCoefficient());
categories.add(categoryMap);
}
quotaAdjustmentService.saveCoefficientConfig(reqVO.getAdjustmentId(), categories);
return success(true);
}
@GetMapping("/get-coefficient-config")
@Operation(summary = "获取系数调整配置")
@Parameter(name = "adjustmentId", description = "调整设置ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:query')")
public CommonResult<List<Map<String, Object>>> getCoefficientConfig(@RequestParam("adjustmentId") Long adjustmentId) {
return success(quotaAdjustmentService.getCoefficientConfig(adjustmentId));
}
@GetMapping("/get-available-resources")
@Operation(summary = "获取可选的工料机列表")
@Parameter(name = "quotaItemId", description = "定额子目ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:query')")
public CommonResult<List<Map<String, Object>>> getAvailableResources(@RequestParam("quotaItemId") Long quotaItemId) {
return success(quotaAdjustmentService.getAvailableResources(quotaItemId));
}
@PostMapping("/save-merge-config")
@Operation(summary = "保存动态合并配置")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:update')")
public CommonResult<Boolean> saveMergeConfig(@Valid @RequestBody QuotaAdjustmentMergeConfigReqVO reqVO) {
List<Map<String, Object>> resources = new java.util.ArrayList<>();
for (QuotaAdjustmentMergeResourceVO resource : reqVO.getResources()) {
Map<String, Object> resourceMap = new java.util.HashMap<>();
resourceMap.put("resourceId", resource.getResourceId());
resourceMap.put("resourceCode", resource.getResourceCode());
resourceMap.put("resourceName", resource.getResourceName());
resourceMap.put("coefficient", resource.getCoefficient());
resourceMap.put("minValue", resource.getMinValue());
resourceMap.put("maxValue", resource.getMaxValue());
resourceMap.put("denominator", resource.getDenominator());
resourceMap.put("baseValue", resource.getBaseValue());
resourceMap.put("roundingRule", resource.getRoundingRule());
resources.add(resourceMap);
}
quotaAdjustmentService.saveMergeConfig(reqVO.getAdjustmentId(), resources);
return success(true);
}
@GetMapping("/get-merge-config")
@Operation(summary = "获取动态合并配置")
@Parameter(name = "adjustmentId", description = "调整设置ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:query')")
public CommonResult<List<Map<String, Object>>> getMergeConfig(@RequestParam("adjustmentId") Long adjustmentId) {
return success(quotaAdjustmentService.getMergeConfig(adjustmentId));
}
@PostMapping("/calculate-merge")
@Operation(summary = "计算动态合并结果")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment:query')")
public CommonResult<Map<String, BigDecimal>> calculateMerge(@Valid @RequestBody QuotaAdjustmentMergeCalculateReqVO reqVO) {
return success(quotaAdjustmentService.calculateMerge(reqVO.getAdjustmentId(), reqVO.getInputValues()));
}
}

View File

@@ -0,0 +1,108 @@
package com.yhy.module.core.controller.admin.quota;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import com.yhy.module.core.controller.admin.quota.vo.QuotaAdjustmentCombinedRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaAdjustmentDetailRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaAdjustmentDetailSaveReqVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaAdjustmentDetailSwapSortReqVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaAdjustmentSettingRespVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaAdjustmentDetailDO;
import com.yhy.module.core.dal.dataobject.quota.QuotaAdjustmentSettingDO;
import com.yhy.module.core.service.quota.QuotaAdjustmentDetailService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import javax.annotation.Resource;
import javax.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "管理后台 - 定额调整明细")
@RestController
@RequestMapping("/core/quota/adjustment-detail")
@Validated
public class QuotaAdjustmentDetailController {
@Resource
private QuotaAdjustmentDetailService quotaAdjustmentDetailService;
@PostMapping("/create")
@Operation(summary = "创建定额调整明细")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment-detail:create')")
public CommonResult<Long> createQuotaAdjustmentDetail(@Valid @RequestBody QuotaAdjustmentDetailSaveReqVO createReqVO) {
return success(quotaAdjustmentDetailService.createQuotaAdjustmentDetail(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新定额调整明细")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment-detail:update')")
public CommonResult<Boolean> updateQuotaAdjustmentDetail(@Valid @RequestBody QuotaAdjustmentDetailSaveReqVO updateReqVO) {
quotaAdjustmentDetailService.updateQuotaAdjustmentDetail(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除定额调整明细")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('core:quota:adjustment-detail:delete')")
public CommonResult<Boolean> deleteQuotaAdjustmentDetail(@RequestParam("id") Long id) {
quotaAdjustmentDetailService.deleteQuotaAdjustmentDetail(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得定额调整明细")
@Parameter(name = "id", description = "编号", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment-detail:query')")
public CommonResult<QuotaAdjustmentDetailRespVO> getQuotaAdjustmentDetail(@RequestParam("id") Long id) {
QuotaAdjustmentDetailDO detail = quotaAdjustmentDetailService.getQuotaAdjustmentDetail(id);
return success(BeanUtils.toBean(detail, QuotaAdjustmentDetailRespVO.class));
}
@GetMapping("/list")
@Operation(summary = "获得定额调整明细列表")
@Parameter(name = "quotaItemId", description = "定额子目ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment-detail:query')")
public CommonResult<List<QuotaAdjustmentDetailRespVO>> getQuotaAdjustmentDetailList(@RequestParam("quotaItemId") Long quotaItemId) {
List<QuotaAdjustmentDetailDO> list = quotaAdjustmentDetailService.getQuotaAdjustmentDetailListByQuotaItem(quotaItemId);
return success(BeanUtils.toBean(list, QuotaAdjustmentDetailRespVO.class));
}
@PostMapping("/swap-sort")
@Operation(summary = "交换排序")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment-detail:update')")
public CommonResult<Boolean> swapSort(@Valid @RequestBody QuotaAdjustmentDetailSwapSortReqVO reqVO) {
quotaAdjustmentDetailService.swapSort(reqVO.getId1(), reqVO.getId2());
return success(true);
}
@GetMapping("/available-settings")
@Operation(summary = "获取可引用的调整设置列表")
@Parameter(name = "adjustmentSettingId", description = "当前调整设置ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment-detail:query')")
public CommonResult<List<QuotaAdjustmentSettingRespVO>> getAvailableSettings(@RequestParam("adjustmentSettingId") Long adjustmentSettingId) {
List<QuotaAdjustmentSettingDO> list = quotaAdjustmentDetailService.getAvailableSettings(adjustmentSettingId);
return success(BeanUtils.toBean(list, QuotaAdjustmentSettingRespVO.class));
}
@GetMapping("/combined-list")
@Operation(summary = "获取调整设置与明细的组合列表")
@Parameter(name = "quotaItemId", description = "定额子目ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment-detail:query')")
public CommonResult<List<QuotaAdjustmentCombinedRespVO>> getCombinedList(@RequestParam("quotaItemId") Long quotaItemId) {
return success(quotaAdjustmentDetailService.getCombinedList(quotaItemId));
}
}

View File

@@ -0,0 +1,88 @@
package com.yhy.module.core.controller.admin.quota;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import com.yhy.module.core.controller.admin.quota.vo.QuotaAdjustmentSettingRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaAdjustmentSettingSaveReqVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaAdjustmentSettingSwapSortReqVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaAdjustmentSettingDO;
import com.yhy.module.core.service.quota.QuotaAdjustmentSettingService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import javax.annotation.Resource;
import javax.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "管理后台 - 定额调整设置")
@RestController
@RequestMapping("/core/quota/adjustment-setting")
@Validated
public class QuotaAdjustmentSettingController {
@Resource
private QuotaAdjustmentSettingService quotaAdjustmentSettingService;
@PostMapping("/create")
@Operation(summary = "创建定额调整设置")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment-setting:create')")
public CommonResult<Long> createQuotaAdjustmentSetting(@Valid @RequestBody QuotaAdjustmentSettingSaveReqVO createReqVO) {
return success(quotaAdjustmentSettingService.createQuotaAdjustmentSetting(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新定额调整设置")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment-setting:update')")
public CommonResult<Boolean> updateQuotaAdjustmentSetting(@Valid @RequestBody QuotaAdjustmentSettingSaveReqVO updateReqVO) {
quotaAdjustmentSettingService.updateQuotaAdjustmentSetting(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除定额调整设置")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('core:quota:adjustment-setting:delete')")
public CommonResult<Boolean> deleteQuotaAdjustmentSetting(@RequestParam("id") Long id) {
quotaAdjustmentSettingService.deleteQuotaAdjustmentSetting(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得定额调整设置")
@Parameter(name = "id", description = "编号", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment-setting:query')")
public CommonResult<QuotaAdjustmentSettingRespVO> getQuotaAdjustmentSetting(@RequestParam("id") Long id) {
QuotaAdjustmentSettingDO setting = quotaAdjustmentSettingService.getQuotaAdjustmentSetting(id);
return success(BeanUtils.toBean(setting, QuotaAdjustmentSettingRespVO.class));
}
@GetMapping("/list")
@Operation(summary = "获得定额调整设置列表")
@Parameter(name = "quotaItemId", description = "定额子目ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment-setting:query')")
public CommonResult<List<QuotaAdjustmentSettingRespVO>> getQuotaAdjustmentSettingList(@RequestParam("quotaItemId") Long quotaItemId) {
List<QuotaAdjustmentSettingDO> list = quotaAdjustmentSettingService.getQuotaAdjustmentSettingList(quotaItemId);
return success(BeanUtils.toBean(list, QuotaAdjustmentSettingRespVO.class));
}
@PostMapping("/swap-sort")
@Operation(summary = "交换排序")
@PreAuthorize("@ss.hasPermission('core:quota:adjustment-setting:update')")
public CommonResult<Boolean> swapSort(@Valid @RequestBody QuotaAdjustmentSettingSwapSortReqVO reqVO) {
quotaAdjustmentSettingService.swapSort(reqVO.getId1(), reqVO.getId2());
return success(true);
}
}

View File

@@ -1,20 +1,33 @@
package com.yhy.module.core.controller.admin.quota;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import com.yhy.module.core.controller.admin.quota.vo.*;
import com.yhy.module.core.controller.admin.quota.vo.QuotaCatalogItemBindSpecialtyReqVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaCatalogItemRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaCatalogItemSaveReqVO;
import com.yhy.module.core.controller.admin.resource.vo.ResourceCategoryFullRespVO;
import com.yhy.module.core.service.quota.QuotaCatalogItemService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 定额目录条目 Controller
@@ -55,26 +68,36 @@ public class QuotaCatalogItemController {
}
@GetMapping("/get")
@Operation(summary = "获得定额目录条目")
@Operation(summary = "获得定额专业节点")
@Parameter(name = "id", description = "编号", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:query')")
public CommonResult<QuotaCatalogItemRespVO> getQuotaCatalogItem(@RequestParam("id") Long id) {
return success(quotaCatalogItemService.getQuotaCatalogItemList(id).stream().findFirst().orElse(null));
return success(convertToVO(quotaCatalogItemService.getQuotaCatalogItem(id)));
}
@GetMapping("/list")
@Operation(summary = "获得定额目录条目列表")
@Parameter(name = "parentId", description = "父节点ID", example = "1")
@Operation(summary = "获得定额专业节点列表(第一层)")
@PreAuthorize("@ss.hasPermission('core:quota:query')")
public CommonResult<List<QuotaCatalogItemRespVO>> getQuotaCatalogItemList(@RequestParam(value = "parentId", required = false) Long parentId) {
return success(quotaCatalogItemService.getQuotaCatalogItemList(parentId));
public CommonResult<List<QuotaCatalogItemRespVO>> getQuotaCatalogItemList() {
return success(quotaCatalogItemService.getQuotaCatalogItemList());
}
@GetMapping("/tree")
@Operation(summary = "获得定额目录树")
@Operation(summary = "获得定额专业树结构(第一层)")
@PreAuthorize("@ss.hasPermission('core:quota:query')")
public CommonResult<List<QuotaCatalogItemRespVO>> getQuotaCatalogItemTree() {
return success(quotaCatalogItemService.getQuotaCatalogItemTree());
public CommonResult<List<QuotaCatalogItemRespVO>> getQuotaCatalogItemTree(
@RequestParam(value = "exclude", required = false)
@Parameter(description = "Exclude node types (comma-separated or repeated)", example = "specialty,rate_mode")
List<String> exclude) {
return success(quotaCatalogItemService.getQuotaCatalogItemTree(normalizeExcludeTypes(exclude)));
}
@PostMapping("/swap-sort")
@Operation(summary = "交换两个节点的排序")
@PreAuthorize("@ss.hasPermission('core:quota:update')")
public CommonResult<Boolean> swapSort(@Valid @RequestBody com.yhy.module.core.controller.admin.quota.vo.QuotaCatalogItemSwapSortReqVO reqVO) {
quotaCatalogItemService.swapSort(reqVO.getNodeId1(), reqVO.getNodeId2());
return success(true);
}
@PostMapping("/bind-specialty")
@@ -85,17 +108,46 @@ public class QuotaCatalogItemController {
return success(true);
}
@PostMapping("/add-directory")
@Operation(summary = "添加目录节点")
@PreAuthorize("@ss.hasPermission('core:quota:create')")
public CommonResult<Long> addDirectory(@Valid @RequestBody QuotaCatalogItemSaveReqVO createReqVO) {
return success(quotaCatalogItemService.addDirectory(createReqVO));
@GetMapping("/{catalogItemId}/categories")
@Operation(summary = "通过费率模式节点获取工料机类别字典(含价格代码)")
@Parameter(name = "catalogItemId", description = "定额目录节点ID费率模式节点或定额专业节点", required = true, example = "2005272359865745410")
@PreAuthorize("@ss.hasPermission('core:quota:query')")
public CommonResult<List<ResourceCategoryFullRespVO>> getCategoriesByCatalogItem(@PathVariable("catalogItemId") Long catalogItemId) {
return success(quotaCatalogItemService.getCategoriesByCatalogItem(catalogItemId));
}
@PostMapping("/add-content")
@Operation(summary = "添加内容节点")
@PreAuthorize("@ss.hasPermission('core:quota:create')")
public CommonResult<Long> addContent(@Valid @RequestBody QuotaCatalogItemSaveReqVO createReqVO) {
return success(quotaCatalogItemService.addContent(createReqVO));
// ========== 私有方法 ==========
private QuotaCatalogItemRespVO convertToVO(com.yhy.module.core.dal.dataobject.quota.QuotaCatalogItemDO catalogItem) {
if (catalogItem == null) {
return null;
}
QuotaCatalogItemRespVO vo = new QuotaCatalogItemRespVO();
vo.setId(catalogItem.getId());
vo.setParentId(catalogItem.getParentId());
vo.setCategoryTreeId(catalogItem.getCategoryTreeId());
vo.setCode(catalogItem.getCode());
vo.setName(catalogItem.getName());
vo.setUnit(catalogItem.getUnit());
vo.setPath(catalogItem.getPath());
vo.setSortOrder(catalogItem.getSortOrder());
vo.setAttributes(catalogItem.getAttributes());
vo.setCreateTime(catalogItem.getCreateTime());
vo.setUpdateTime(catalogItem.getUpdateTime());
vo.setNodeType(catalogItem.getNodeType());
vo.setSpecialtyLocked(catalogItem.isSpecialtyLocked());
return vo;
}
private List<String> normalizeExcludeTypes(List<String> exclude) {
if (exclude == null || exclude.isEmpty()) {
return null;
}
return exclude.stream()
.flatMap(value -> Arrays.stream(value.split(",")))
.map(String::trim)
.filter(StringUtils::hasText)
.distinct()
.collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,113 @@
package com.yhy.module.core.controller.admin.quota;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import com.yhy.module.core.controller.admin.quota.vo.QuotaCatalogTreeRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaCatalogTreeSaveReqVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaCatalogTreeSwapSortReqVO;
import com.yhy.module.core.service.quota.QuotaCatalogTreeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import javax.annotation.Resource;
import javax.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "管理后台 - 定额子目树")
@RestController
@RequestMapping("/core/quota/catalog-tree")
@Validated
public class QuotaCatalogTreeController {
@Resource
private QuotaCatalogTreeService quotaCatalogTreeService;
@PostMapping("/create")
@Operation(summary = "创建定额子目树节点")
@PreAuthorize("@ss.hasPermission('core:quota:catalog-tree:create')")
public CommonResult<Long> createCatalogTree(@Valid @RequestBody QuotaCatalogTreeSaveReqVO createReqVO) {
return success(quotaCatalogTreeService.createCatalogTree(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新定额子目树节点")
@PreAuthorize("@ss.hasPermission('core:quota:catalog-tree:update')")
public CommonResult<Boolean> updateCatalogTree(@Valid @RequestBody QuotaCatalogTreeSaveReqVO updateReqVO) {
quotaCatalogTreeService.updateCatalogTree(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除定额子目树节点")
@Parameter(name = "id", description = "节点ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:catalog-tree:delete')")
public CommonResult<Boolean> deleteCatalogTree(@RequestParam("id") Long id) {
quotaCatalogTreeService.deleteCatalogTree(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获取定额子目树节点详情")
@Parameter(name = "id", description = "节点ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:catalog-tree:query')")
public CommonResult<QuotaCatalogTreeRespVO> getCatalogTree(@RequestParam("id") Long id) {
return success(quotaCatalogTreeService.getCatalogTree(id));
}
@GetMapping("/list")
@Operation(summary = "获取定额子目树节点列表")
@Parameter(name = "catalogItemId", description = "定额专业节点ID", required = true, example = "1")
@Parameter(name = "parentId", description = "父节点ID", example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:catalog-tree:query')")
public CommonResult<List<QuotaCatalogTreeRespVO>> getCatalogTreeList(
@RequestParam("catalogItemId") Long catalogItemId,
@RequestParam(value = "parentId", required = false) Long parentId) {
return success(quotaCatalogTreeService.getCatalogTreeList(catalogItemId, parentId));
}
@GetMapping("/tree")
@Operation(summary = "获取定额子目树结构")
@Parameter(name = "catalogItemId", description = "定额专业节点ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:catalog-tree:query')")
public CommonResult<List<QuotaCatalogTreeRespVO>> getCatalogTreeTree(
@RequestParam("catalogItemId") Long catalogItemId) {
return success(quotaCatalogTreeService.getCatalogTreeTree(catalogItemId));
}
@PostMapping("/swap-sort")
@Operation(summary = "交换排序")
@PreAuthorize("@ss.hasPermission('core:quota:catalog-tree:update')")
public CommonResult<Boolean> swapSort(@Valid @RequestBody QuotaCatalogTreeSwapSortReqVO swapReqVO) {
quotaCatalogTreeService.swapSort(swapReqVO.getNodeId1(), swapReqVO.getNodeId2());
return success(true);
}
@GetMapping("/list-by-rate-item")
@Operation(summary = "根据费率项ID查询绑定的定额子目树")
@Parameter(name = "rateItemId", description = "费率项ID", required = true, example = "3011")
@PreAuthorize("@ss.hasPermission('core:quota:catalog-tree:query')")
public CommonResult<List<QuotaCatalogTreeRespVO>> getCatalogTreeByRateItem(
@RequestParam("rateItemId") Long rateItemId) {
return success(quotaCatalogTreeService.getCatalogTreeByRateItem(rateItemId));
}
@GetMapping("/list-by-rate-mode-node")
@Operation(summary = "根据费率模式节点ID查询所属定额专业的子目录树")
@Parameter(name = "rateModeNodeId", description = "费率模式节点ID", required = true, example = "1002")
@PreAuthorize("@ss.hasPermission('core:quota:catalog-tree:query')")
public CommonResult<List<QuotaCatalogTreeRespVO>> getCatalogTreeByRateModeNode(
@RequestParam("rateModeNodeId") Long rateModeNodeId) {
return success(quotaCatalogTreeService.getCatalogTreeByRateModeNode(rateModeNodeId));
}
}

View File

@@ -1,24 +1,31 @@
package com.yhy.module.core.controller.admin.quota;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import com.yhy.module.core.controller.admin.quota.vo.QuotaFeeItemRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaFeeItemSaveReqVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaFeeItemSwapSortReqVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaFeeItemWithRateRespVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaFeeItemDO;
import com.yhy.module.core.service.quota.QuotaFeeItemService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "管理后台 - 定额取费项")
@RestController
@@ -71,6 +78,15 @@ public class QuotaFeeItemController {
return success(BeanUtils.toBean(list, QuotaFeeItemRespVO.class));
}
@GetMapping("/list-with-rate")
@Operation(summary = "获取取费项与费率项合并列表")
@Parameter(name = "catalogItemId", description = "模式节点ID", required = true, example = "1002")
@PreAuthorize("@ss.hasPermission('core:quota:fee:query')")
public CommonResult<List<QuotaFeeItemWithRateRespVO>> getFeeItemWithRateList(@RequestParam("catalogItemId") Long catalogItemId) {
List<QuotaFeeItemWithRateRespVO> list = quotaFeeItemService.getFeeItemWithRateList(catalogItemId);
return success(list);
}
@PostMapping("/swap-sort")
@Operation(summary = "交换排序")
@PreAuthorize("@ss.hasPermission('core:quota:fee:update')")

View File

@@ -1,5 +1,7 @@
package com.yhy.module.core.controller.admin.quota;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import com.yhy.module.core.controller.admin.quota.vo.QuotaItemRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaItemSaveReqVO;
@@ -7,15 +9,20 @@ import com.yhy.module.core.service.quota.QuotaItemService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Collections;
import java.util.List;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 定额子目 Controller
@@ -65,9 +72,12 @@ public class QuotaItemController {
@GetMapping("/list")
@Operation(summary = "获得定额子目列表")
@Parameter(name = "catalogItemId", description = "定额条目ID", required = true, example = "1")
@Parameter(name = "catalogItemId", description = "定额条目ID", required = false, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:query')")
public CommonResult<List<QuotaItemRespVO>> getQuotaItemList(@RequestParam("catalogItemId") Long catalogItemId) {
public CommonResult<List<QuotaItemRespVO>> getQuotaItemList(@RequestParam(value = "catalogItemId", required = false) Long catalogItemId) {
if (catalogItemId == null) {
return success(Collections.emptyList());
}
return success(quotaItemService.getQuotaItemList(catalogItemId));
}

View File

@@ -1,5 +1,7 @@
package com.yhy.module.core.controller.admin.quota;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateFieldRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateFieldSaveReqVO;
@@ -7,14 +9,17 @@ import com.yhy.module.core.service.quota.QuotaRateFieldService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 定额费率字段绑定 Controller
@@ -43,32 +48,32 @@ public class QuotaRateFieldController {
}
@GetMapping("/list")
@Operation(summary = "获取费率的字段绑定列表")
@Parameter(name = "rateItemId", description = "费率ID", required = true)
@Operation(summary = "获取费率模式节点的字段绑定列表")
@Parameter(name = "catalogItemId", description = "费率模式节点ID", required = true)
public CommonResult<List<QuotaRateFieldRespVO>> getRateFieldList(
@RequestParam("rateItemId") Long rateItemId) {
return success(rateFieldService.getRateFieldList(rateItemId));
@RequestParam("catalogItemId") Long catalogItemId) {
return success(rateFieldService.getRateFieldList(catalogItemId));
}
@PostMapping("/update-binding")
@Operation(summary = "更新字段绑定")
@Parameter(name = "rateItemId", description = "费率ID", required = true)
@Parameter(name = "catalogItemId", description = "费率模式节点ID", required = true)
@Parameter(name = "fieldIndex", description = "字段索引", required = true)
public CommonResult<Boolean> updateBinding(
@RequestParam("rateItemId") Long rateItemId,
@RequestParam("catalogItemId") Long catalogItemId,
@RequestParam("fieldIndex") Integer fieldIndex,
@RequestBody Long[] bindingIds) {
rateFieldService.updateBinding(rateItemId, fieldIndex, bindingIds);
rateFieldService.updateBinding(catalogItemId, fieldIndex, bindingIds);
return success(true);
}
@PostMapping("/batch-save")
@Operation(summary = "批量保存字段绑定")
@Parameter(name = "rateItemId", description = "费率ID", required = true)
@Parameter(name = "catalogItemId", description = "费率模式节点ID", required = true)
public CommonResult<Boolean> batchSaveRateFields(
@RequestParam("rateItemId") Long rateItemId,
@RequestParam("catalogItemId") Long catalogItemId,
@RequestBody List<QuotaRateFieldSaveReqVO> fields) {
rateFieldService.batchSaveRateFields(rateItemId, fields);
rateFieldService.batchSaveRateFields(catalogItemId, fields);
return success(true);
}
}

View File

@@ -0,0 +1,93 @@
package com.yhy.module.core.controller.admin.quota;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateFieldLabelRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateFieldLabelSaveReqVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaRateFieldLabelDO;
import com.yhy.module.core.service.quota.QuotaRateFieldLabelService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 定额费率字段标签字典 Controller
*
* @author yhy
*/
@Tag(name = "管理后台 - 定额费率字段标签字典")
@RestController
@RequestMapping("/core/quota/rate-field-label")
@RequiredArgsConstructor
@Validated
public class QuotaRateFieldLabelController {
private final QuotaRateFieldLabelService fieldLabelService;
@PostMapping("/create")
@Operation(summary = "创建字段标签")
@PreAuthorize("@ss.hasPermission('core:quota:rate:write')")
public CommonResult<Long> createFieldLabel(@Valid @RequestBody QuotaRateFieldLabelSaveReqVO createReqVO) {
return success(fieldLabelService.createFieldLabel(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新字段标签")
@PreAuthorize("@ss.hasPermission('core:quota:rate:write')")
public CommonResult<Boolean> updateFieldLabel(@Valid @RequestBody QuotaRateFieldLabelSaveReqVO updateReqVO) {
fieldLabelService.updateFieldLabel(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除字段标签")
@Parameter(name = "id", description = "标签ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:rate:write')")
public CommonResult<Boolean> deleteFieldLabel(@RequestParam("id") Long id) {
fieldLabelService.deleteFieldLabel(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获取字段标签详情")
@Parameter(name = "id", description = "标签ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:rate:read')")
public CommonResult<QuotaRateFieldLabelRespVO> getFieldLabel(@RequestParam("id") Long id) {
QuotaRateFieldLabelDO label = fieldLabelService.getFieldLabel(id);
return success(BeanUtils.toBean(label, QuotaRateFieldLabelRespVO.class));
}
@GetMapping("/list")
@Operation(summary = "获取字段标签列表")
@Parameter(name = "catalogItemId", description = "模式节点ID", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:quota:rate:read')")
public CommonResult<List<QuotaRateFieldLabelRespVO>> getFieldLabelList(@RequestParam("catalogItemId") Long catalogItemId) {
return success(fieldLabelService.getFieldLabelList(catalogItemId));
}
@PostMapping("/swap-sort")
@Operation(summary = "交换排序")
@PreAuthorize("@ss.hasPermission('core:quota:rate:write')")
public CommonResult<Boolean> swapSort(
@RequestParam("labelId1") Long labelId1,
@RequestParam("labelId2") Long labelId2) {
fieldLabelService.swapSort(labelId1, labelId2);
return success(true);
}
}

View File

@@ -1,23 +1,31 @@
package com.yhy.module.core.controller.admin.quota;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateItemRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateItemSaveReqVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateItemSwapSortReqVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateModeNodeSaveReqVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateValueRulesReqVO;
import com.yhy.module.core.service.quota.QuotaRateItemService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 定额费率项 Controller
@@ -31,15 +39,21 @@ public class QuotaRateItemController {
private final QuotaRateItemService rateItemService;
@PostMapping("/create-mode-node")
@Operation(summary = "创建费率模式节点")
public CommonResult<Long> createRateModeNode(@Valid @RequestBody QuotaRateModeNodeSaveReqVO createReqVO) {
return success(rateItemService.createRateModeNode(createReqVO));
}
@PostMapping("/create")
@Operation(summary = "创建费率项")
public CommonResult<Long> createRateItem(@Valid @RequestBody QuotaRateItemSaveReqVO createReqVO) {
public CommonResult<Long> createRateItem(@Validated(QuotaRateItemSaveReqVO.CreateGroup.class) @RequestBody QuotaRateItemSaveReqVO createReqVO) {
return success(rateItemService.createRateItem(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新费率项")
public CommonResult<Boolean> updateRateItem(@Valid @RequestBody QuotaRateItemSaveReqVO updateReqVO) {
public CommonResult<Boolean> updateRateItem(@Validated(QuotaRateItemSaveReqVO.UpdateGroup.class) @RequestBody QuotaRateItemSaveReqVO updateReqVO) {
rateItemService.updateRateItem(updateReqVO);
return success(true);
}
@@ -79,26 +93,30 @@ public class QuotaRateItemController {
@PostMapping("/swap-sort")
@Operation(summary = "同级交换排序")
@Parameter(name = "nodeId1", description = "节点1 ID", required = true)
@Parameter(name = "nodeId2", description = "节点2 ID", required = true)
public CommonResult<Boolean> swapSort(
@RequestParam("nodeId1") Long nodeId1,
@RequestParam("nodeId2") Long nodeId2) {
rateItemService.swapSort(nodeId1, nodeId2);
public CommonResult<Boolean> swapSort(@Valid @RequestBody QuotaRateItemSwapSortReqVO swapReqVO) {
rateItemService.swapSort(swapReqVO.getNodeId1(), swapReqVO.getNodeId2());
return success(true);
}
@PostMapping("/move-node")
@Operation(summary = "移动节点到指定位置", description = "将节点移动到目标节点之前,自动重新计算所有受影响节点的排序值")
public CommonResult<Boolean> moveNode(@Valid @RequestBody QuotaRateItemSwapSortReqVO moveReqVO) {
rateItemService.moveNode(moveReqVO.getNodeId1(), moveReqVO.getNodeId2());
return success(true);
}
@PostMapping("/config-value-rules")
@Operation(summary = "配置动态取值规则")
@Operation(summary = "配置动态取值规则", description = "阶梯规则tiers必填增量规则increments可选")
public CommonResult<Boolean> configValueRules(@Valid @RequestBody QuotaRateValueRulesReqVO reqVO) {
rateItemService.configValueRules(reqVO);
return success(true);
}
@GetMapping("/calculate-fields")
@Operation(summary = "计算动态字段值")
@Operation(summary = "计算动态字段值(默认使用阶梯规则)",
description = "根据基数值匹配阶梯规则获取字段值,如果配置了增量规则则在基础上叠加")
@Parameter(name = "rateItemId", description = "费率项ID", required = true)
@Parameter(name = "baseValue", description = "基数值", required = true)
@Parameter(name = "baseValue", description = "基数值(万元)", required = true)
public CommonResult<Map<Integer, BigDecimal>> calculateDynamicFields(
@RequestParam("rateItemId") Long rateItemId,
@RequestParam("baseValue") BigDecimal baseValue) {

View File

@@ -1,5 +1,7 @@
package com.yhy.module.core.controller.admin.quota;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import com.yhy.module.core.controller.admin.quota.vo.QuotaResourceRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaResourceSaveReqVO;
@@ -8,15 +10,19 @@ import com.yhy.module.core.service.quota.QuotaResourceService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 定额工料机组成 Controller
@@ -73,10 +79,22 @@ public class QuotaResourceController {
}
@GetMapping("/available-list")
@Operation(summary = "获取可选的工料机列表(已过滤范围)")
@Operation(summary = "获取可选的工料机列表(已过滤范围,支持模糊查询")
@Parameter(name = "quotaItemId", description = "定额子目ID", required = true, example = "1")
@Parameter(name = "code", description = "编码(模糊查询)", required = false, example = "C001")
@Parameter(name = "name", description = "名称(模糊查询)", required = false, example = "水泥")
@Parameter(name = "spec", description = "型号规格(模糊查询)", required = false, example = "P.O 42.5")
@PreAuthorize("@ss.hasPermission('core:quota:query')")
public CommonResult<List<ResourceItemRespVO>> getAvailableResourceItems(@RequestParam("quotaItemId") Long quotaItemId) {
return success(quotaResourceService.getAvailableResourceItems(quotaItemId));
public CommonResult<List<ResourceItemRespVO>> getAvailableResourceItems(
@RequestParam("quotaItemId") Long quotaItemId,
@RequestParam(value = "code", required = false) String code,
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "spec", required = false) String spec) {
// 如果没有任何查询条件,使用原方法(性能更好)
if (code == null && name == null && spec == null) {
return success(quotaResourceService.getAvailableResourceItems(quotaItemId));
}
// 有查询条件时使用带过滤的方法
return success(quotaResourceService.getAvailableResourceItemsWithFilter(quotaItemId, code, name, spec));
}
}

View File

@@ -1,21 +0,0 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 可配置的类别 VO")
@Data
public class QuotaAdjustmentAvailableCategoryVO {
@Schema(description = "类别ID", example = "1")
private Long categoryId;
@Schema(description = "类别名称", example = "人工")
private String categoryName;
@Schema(description = "类别类型", example = "labor")
private String categoryType;
@Schema(description = "类别编码", example = "RG")
private String categoryCode;
}

View File

@@ -1,26 +0,0 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
@Schema(description = "管理后台 - 系数调整类别配置 VO")
@Data
public class QuotaAdjustmentCoefficientCategoryVO {
@Schema(description = "类别ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "类别ID不能为空")
private Long categoryId;
@Schema(description = "类别名称", example = "人工")
private String categoryName;
@Schema(description = "类别类型", example = "labor")
private String categoryType;
@Schema(description = "系数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.2")
@NotNull(message = "系数不能为空")
private BigDecimal coefficient;
}

View File

@@ -1,23 +0,0 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
@Schema(description = "管理后台 - 保存系数调整配置 Request VO")
@Data
public class QuotaAdjustmentCoefficientConfigReqVO {
@Schema(description = "调整设置ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "调整设置ID不能为空")
private Long adjustmentId;
@Schema(description = "类别配置列表", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "类别配置列表不能为空")
@Valid
private List<QuotaAdjustmentCoefficientCategoryVO> categories;
}

View File

@@ -0,0 +1,67 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import lombok.Data;
@Schema(description = "管理后台 - 定额调整设置与明细组合 Response VO")
@Data
public class QuotaAdjustmentCombinedRespVO {
@Schema(description = "调整设置ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "定额子目ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long quotaItemId;
@Schema(description = "调整名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "人工费调整")
private String name;
@Schema(description = "定额值", example = "100.00")
private BigDecimal quotaValue;
@Schema(description = "调整内容", example = "冬季施工增加10%")
private String adjustmentContent;
@Schema(description = "调整类型(字典)", requiredMode = Schema.RequiredMode.REQUIRED, example = "percentage")
private String adjustmentType;
@Schema(description = "调整规则JSON")
private Map<String, Object> adjustmentRules;
@Schema(description = "排序", example = "1")
private Integer sortOrder;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
@Schema(description = "调整明细列表")
private List<DetailItem> details;
@Schema(description = "调整明细项")
@Data
public static class DetailItem {
@Schema(description = "明细ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "调整设置ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long adjustmentSettingId;
@Schema(description = "定额调整编号引用其他调整设置ID", example = "2")
private Long adjustmentCode;
@Schema(description = "调整内容", example = "增加10%")
private String adjustment;
@Schema(description = "排序", example = "1")
private Integer sortOrder;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}
}

View File

@@ -0,0 +1,29 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import lombok.Data;
@Schema(description = "管理后台 - 定额调整明细 Response VO")
@Data
public class QuotaAdjustmentDetailRespVO {
@Schema(description = "主键ID", example = "1")
private Long id;
@Schema(description = "调整设置ID", example = "1")
private Long adjustmentSettingId;
@Schema(description = "定额调整编号引用其他调整设置ID", example = "2")
private Long adjustmentCode;
@Schema(description = "调整内容", example = "增加10%")
private String adjustment;
@Schema(description = "排序", example = "1")
private Integer sortOrder;
@Schema(description = "创建时间")
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,27 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - 定额调整明细创建/更新 Request VO")
@Data
public class QuotaAdjustmentDetailSaveReqVO {
@Schema(description = "主键ID", example = "1")
private Long id;
@Schema(description = "调整设置ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "调整设置ID不能为空")
private Long adjustmentSettingId;
@Schema(description = "定额调整编号引用其他调整设置ID", example = "2")
private Long adjustmentCode;
@Schema(description = "调整内容", example = "增加10%")
private String adjustment;
@Schema(description = "排序", example = "1")
private Integer sortOrder;
}

View File

@@ -0,0 +1,19 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - 定额调整明细交换排序 Request VO")
@Data
public class QuotaAdjustmentDetailSwapSortReqVO {
@Schema(description = "第一个调整明细ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "第一个调整明细ID不能为空")
private Long id1;
@Schema(description = "第二个调整明细ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "第二个调整明细ID不能为空")
private Long id2;
}

View File

@@ -1,23 +0,0 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.Map;
@Schema(description = "管理后台 - 计算动态调整结果 Request VO")
@Data
public class QuotaAdjustmentDynamicCalculateReqVO {
@Schema(description = "调整设置ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "调整设置ID不能为空")
private Long adjustmentId;
@Schema(description = "输入值映射类别ID: 输入值)", requiredMode = Schema.RequiredMode.REQUIRED,
example = "{\"1\": 250, \"2\": 150}")
@NotEmpty(message = "输入值映射不能为空")
private Map<String, BigDecimal> inputValues;
}

View File

@@ -1,46 +0,0 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
@Schema(description = "管理后台 - 动态调整类别配置 VO")
@Data
public class QuotaAdjustmentDynamicCategoryVO {
@Schema(description = "类别ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "类别ID不能为空")
private Long categoryId;
@Schema(description = "类别名称", example = "人工")
private String categoryName;
@Schema(description = "类别类型", example = "labor")
private String categoryType;
@Schema(description = "系数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.2")
@NotNull(message = "系数不能为空")
private BigDecimal coefficient;
@Schema(description = "最小值", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
@NotNull(message = "最小值不能为空")
private BigDecimal minValue;
@Schema(description = "最大值", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
@NotNull(message = "最大值不能为空")
private BigDecimal maxValue;
@Schema(description = "分母值", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
@NotNull(message = "分母值不能为空")
private BigDecimal denominator;
@Schema(description = "基础值", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
@NotNull(message = "基础值不能为空")
private BigDecimal baseValue;
@Schema(description = "取值规则", requiredMode = Schema.RequiredMode.REQUIRED, example = "round_up")
@NotNull(message = "取值规则不能为空")
private String roundingRule;
}

View File

@@ -1,23 +0,0 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
@Schema(description = "管理后台 - 保存动态调整配置 Request VO")
@Data
public class QuotaAdjustmentDynamicConfigReqVO {
@Schema(description = "调整设置ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "调整设置ID不能为空")
private Long adjustmentId;
@Schema(description = "类别配置列表", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "类别配置列表不能为空")
@Valid
private List<QuotaAdjustmentDynamicCategoryVO> categories;
}

View File

@@ -1,31 +0,0 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
@Schema(description = "管理后台 - 定额调整材料明细 VO")
@Data
public class QuotaAdjustmentMaterialItemVO {
@Schema(description = "序号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "序号不能为空")
private Integer sortOrder;
@Schema(description = "工料机编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "C001")
@NotBlank(message = "工料机编码不能为空")
private String resourceCode;
@Schema(description = "工料机名称", example = "水泥 P.O 42.5")
private String resourceName;
@Schema(description = "增减定额消耗量数值", requiredMode = Schema.RequiredMode.REQUIRED, example = "2.5")
@NotNull(message = "增减定额消耗量数值不能为空")
private BigDecimal adjustValue;
@Schema(description = "备注", example = "增加损耗")
private String remark;
}

View File

@@ -1,23 +0,0 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
@Schema(description = "管理后台 - 保存定额调整材料明细 Request VO")
@Data
public class QuotaAdjustmentMaterialItemsReqVO {
@Schema(description = "调整设置ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "调整设置ID不能为空")
private Long adjustmentId;
@Schema(description = "材料明细列表", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "材料明细列表不能为空")
@Valid
private List<QuotaAdjustmentMaterialItemVO> items;
}

View File

@@ -1,23 +0,0 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.Map;
@Schema(description = "管理后台 - 计算动态合并结果 Request VO")
@Data
public class QuotaAdjustmentMergeCalculateReqVO {
@Schema(description = "调整设置ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "调整设置ID不能为空")
private Long adjustmentId;
@Schema(description = "输入值映射工料机ID: 输入值)", requiredMode = Schema.RequiredMode.REQUIRED,
example = "{\"100\": 250, \"101\": 150}")
@NotEmpty(message = "输入值映射不能为空")
private Map<String, BigDecimal> inputValues;
}

View File

@@ -1,23 +0,0 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
@Schema(description = "管理后台 - 保存动态合并配置 Request VO")
@Data
public class QuotaAdjustmentMergeConfigReqVO {
@Schema(description = "调整设置ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "调整设置ID不能为空")
private Long adjustmentId;
@Schema(description = "工料机配置列表", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "工料机配置列表不能为空")
@Valid
private List<QuotaAdjustmentMergeResourceVO> resources;
}

View File

@@ -1,46 +0,0 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
@Schema(description = "管理后台 - 动态合并工料机配置 VO")
@Data
public class QuotaAdjustmentMergeResourceVO {
@Schema(description = "工料机ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
@NotNull(message = "工料机ID不能为空")
private Long resourceId;
@Schema(description = "工料机编码", example = "C001")
private String resourceCode;
@Schema(description = "工料机名称", example = "水泥 P.O 42.5")
private String resourceName;
@Schema(description = "系数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.2")
@NotNull(message = "系数不能为空")
private BigDecimal coefficient;
@Schema(description = "最小值", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
@NotNull(message = "最小值不能为空")
private BigDecimal minValue;
@Schema(description = "最大值", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
@NotNull(message = "最大值不能为空")
private BigDecimal maxValue;
@Schema(description = "分母值", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
@NotNull(message = "分母值不能为空")
private BigDecimal denominator;
@Schema(description = "基础值", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
@NotNull(message = "基础值不能为空")
private BigDecimal baseValue;
@Schema(description = "取值规则", requiredMode = Schema.RequiredMode.REQUIRED, example = "round_up")
@NotNull(message = "取值规则不能为空")
private String roundingRule;
}

View File

@@ -1,14 +1,14 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;
import lombok.Data;
@Schema(description = "管理后台 - 定额调整设置 Response VO")
@Data
public class QuotaAdjustmentRespVO {
public class QuotaAdjustmentSettingRespVO {
@Schema(description = "主键ID", example = "1")
private Long id;
@@ -16,19 +16,19 @@ public class QuotaAdjustmentRespVO {
@Schema(description = "定额子目ID", example = "1")
private Long quotaItemId;
@Schema(description = "调整名称", example = "高温季节调整")
@Schema(description = "调整名称", example = "人工费调整")
private String name;
@Schema(description = "调整内容", example = "夏季高温施工增加人工费用")
private String content;
@Schema(description = "定额值", example = "100.00")
private BigDecimal quotaValue;
@Schema(description = "调整类型", example = "percentage")
@Schema(description = "调整内容", example = "冬季施工增加10%")
private String adjustmentContent;
@Schema(description = "调整类型(字典)", example = "percentage")
private String adjustmentType;
@Schema(description = "调整类型名称", example = "百分比调整")
private String adjustmentTypeName;
@Schema(description = "调整规则", example = "{\"value\": 10, \"operator\": \"increase\"}")
@Schema(description = "调整规则JSON")
private Map<String, Object> adjustmentRules;
@Schema(description = "排序", example = "1")
@@ -37,6 +37,4 @@ public class QuotaAdjustmentRespVO {
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
}

View File

@@ -1,15 +1,15 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Map;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Map;
import lombok.Data;
@Schema(description = "管理后台 - 定额调整设置创建/更新 Request VO")
@Data
public class QuotaAdjustmentSaveReqVO {
public class QuotaAdjustmentSettingSaveReqVO {
@Schema(description = "主键ID", example = "1")
private Long id;
@@ -18,20 +18,24 @@ public class QuotaAdjustmentSaveReqVO {
@NotNull(message = "定额子目ID不能为空")
private Long quotaItemId;
@Schema(description = "调整名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "高温季节调整")
@Schema(description = "调整名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "人工费调整")
@NotBlank(message = "调整名称不能为空")
private String name;
@Schema(description = "调整内容", example = "夏季高温施工增加人工费用")
private String content;
@Schema(description = "定额值", example = "100.00")
private BigDecimal quotaValue;
@Schema(description = "调整类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "percentage")
@Schema(description = "调整内容", example = "冬季施工增加10%")
private String adjustmentContent;
@Schema(description = "调整类型(字典)", requiredMode = Schema.RequiredMode.REQUIRED, example = "percentage")
@NotBlank(message = "调整类型不能为空")
private String adjustmentType;
@Schema(description = "调整规则", example = "{\"value\": 10, \"operator\": \"increase\"}")
@Schema(description = "调整规则JSON")
private Map<String, Object> adjustmentRules;
@Schema(description = "排序", example = "1")
private Integer sortOrder;
}

View File

@@ -0,0 +1,19 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - 定额调整设置交换排序 Request VO")
@Data
public class QuotaAdjustmentSettingSwapSortReqVO {
@Schema(description = "第一个调整设置ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "第一个调整设置ID不能为空")
private Long id1;
@Schema(description = "第二个调整设置ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "第二个调整设置ID不能为空")
private Long id2;
}

View File

@@ -1,19 +0,0 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - 定额调整设置交换排序 Request VO")
@Data
public class QuotaAdjustmentSwapSortReqVO {
@Schema(description = "调整设置ID1", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "调整设置ID1不能为空")
private Long id1;
@Schema(description = "调整设置ID2", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "调整设置ID2不能为空")
private Long id2;
}

View File

@@ -37,6 +37,9 @@ public class QuotaCatalogItemSaveReqVO {
@Schema(description = "排序", example = "1")
private Integer sortOrder;
@Schema(description = "节点类型region/specialty/rate_mode不传则尝试从 attributes.node_type 读取", example = "region")
private String nodeType;
@Schema(description = "扩展属性", example = "{\"node_type\":\"specialty\"}")
private Map<String, Object> attributes;
}

View File

@@ -0,0 +1,23 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.NotNull;
import lombok.Data;
/**
* 定额目录条目交换排序 Request VO
*
* @author yhy
*/
@Schema(description = "管理后台 - 定额目录条目交换排序 Request VO")
@Data
public class QuotaCatalogItemSwapSortReqVO {
@Schema(description = "节点1的ID", required = true, example = "1")
@NotNull(message = "节点1的ID不能为空")
private Long nodeId1;
@Schema(description = "节点2的ID", required = true, example = "2")
@NotNull(message = "节点2的ID不能为空")
private Long nodeId2;
}

View File

@@ -0,0 +1,60 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import lombok.Data;
@Schema(description = "管理后台 - 定额子目树 Response VO")
@Data
public class QuotaCatalogTreeRespVO {
@Schema(description = "主键", example = "1")
private Long id;
@Schema(description = "租户ID", example = "1")
private Long tenantId;
@Schema(description = "关联定额专业节点ID", example = "1")
private Long catalogItemId;
@Schema(description = "父节点ID", example = "1")
private Long parentId;
@Schema(description = "编码", example = "01")
private String code;
@Schema(description = "名称", example = "土石方工程")
private String name;
@Schema(description = "单位", example = "")
private String unit;
@Schema(description = "内容类型directory-目录content-内容", example = "directory")
private String contentType;
@Schema(description = "是否允许添加子节点", example = "true")
private Boolean allowChildren;
@Schema(description = "排序", example = "1")
private Integer sortOrder;
@Schema(description = "树路径")
private String[] path;
@Schema(description = "层级", example = "1")
private Integer level;
@Schema(description = "扩展属性")
private Map<String, Object> attributes;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "已被绑定的字段索引列表(用于前端禁用)", example = "[1, 2, 3]")
private List<Integer> boundFieldIndexes;
@Schema(description = "子节点列表")
private List<QuotaCatalogTreeRespVO> children;
}

View File

@@ -0,0 +1,64 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.Map;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - 定额子目树保存 Request VO")
@Data
public class QuotaCatalogTreeSaveReqVO {
@Schema(description = "主键", example = "1")
private Long id;
@Schema(description = "关联定额专业节点ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "关联定额专业节点ID不能为空")
private Long catalogItemId;
@Schema(description = "父节点ID", example = "1")
private Long parentId;
@Schema(description = "编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "01")
@NotBlank(message = "编码不能为空")
private String code;
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "土石方工程")
@NotBlank(message = "名称不能为空")
private String name;
@Schema(description = "单位", example = "")
private String unit;
@Schema(description = "内容类型directory-目录content-内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "directory")
@NotBlank(message = "内容类型不能为空")
private String contentType;
@Schema(description = "排序", example = "1")
private Integer sortOrder;
/**
* 自定义 setter 处理前端传递的无效值
*/
@com.fasterxml.jackson.annotation.JsonSetter("sortOrder")
public void setSortOrderSafe(Object value) {
if (value == null) {
this.sortOrder = null;
} else if (value instanceof Number) {
// 如果是数字类型,尝试转换为 Integer
long longValue = ((Number) value).longValue();
// 如果值超出 Integer 范围,设置为 null让后端自动计算
if (longValue > Integer.MAX_VALUE || longValue < Integer.MIN_VALUE) {
this.sortOrder = null;
} else {
this.sortOrder = (int) longValue;
}
} else {
this.sortOrder = null;
}
}
@Schema(description = "扩展属性")
private Map<String, Object> attributes;
}

View File

@@ -0,0 +1,18 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - 定额子目树交换排序 Request VO")
@Data
public class QuotaCatalogTreeSwapSortReqVO {
@Schema(description = "节点1 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "节点1 ID不能为空")
private Long nodeId1;
@Schema(description = "节点2 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "节点2 ID不能为空")
private Long nodeId2;
}

View File

@@ -1,10 +1,9 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Map;
import lombok.Data;
@Schema(description = "管理后台 - 定额取费项 Response VO")
@Data
@@ -19,6 +18,9 @@ public class QuotaFeeItemRespVO {
@Schema(description = "模式节点ID", example = "1002")
private Long catalogItemId;
@Schema(description = "关联的费率项ID任意层级节点", example = "5001")
private Long rateItemId;
@Schema(description = "自定义序号", example = "")
private String customCode;
@@ -43,6 +45,12 @@ public class QuotaFeeItemRespVO {
@Schema(description = "排序字段", example = "1")
private Integer sortOrder;
@Schema(description = "是否隐藏", example = "false")
private Boolean hidden;
@Schema(description = "是否为变量", example = "false")
private Boolean variable;
@Schema(description = "创建时间")
private LocalDateTime createTime;

View File

@@ -1,11 +1,10 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Map;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Map;
import lombok.Data;
@Schema(description = "管理后台 - 定额取费项创建/更新 Request VO")
@Data
@@ -18,6 +17,9 @@ public class QuotaFeeItemSaveReqVO {
@NotNull(message = "模式节点ID不能为空")
private Long catalogItemId;
@Schema(description = "关联的费率项ID任意层级节点可为空", example = "5001")
private Long rateItemId;
@Schema(description = "自定义序号", example = "")
private String customCode;
@@ -42,4 +44,10 @@ public class QuotaFeeItemSaveReqVO {
@Schema(description = "排序字段", example = "1")
private Integer sortOrder;
@Schema(description = "是否隐藏", example = "false")
private Boolean hidden;
@Schema(description = "是否为变量", example = "false")
private Boolean variable;
}

View File

@@ -0,0 +1,91 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import lombok.Data;
/**
* 定额取费项(含费率项信息)响应 VO
*
* 用于展示费率项一级节点与取费项的一对一关系
*/
@Schema(description = "管理后台 - 定额取费项(含费率项信息)响应")
@Data
public class QuotaFeeItemWithRateRespVO {
// ==================== 费率项信息 ====================
@Schema(description = "费率项ID任意层级节点", example = "5001")
private Long rateItemId;
@Schema(description = "费率项名称", example = "分部分项工程费")
private String rateItemName;
@Schema(description = "费率项自定义序号", example = "1")
private String rateItemCustomCode;
@Schema(description = "费率代号", example = "FBFX")
private String rateCode;
@Schema(description = "父节点ID", example = "5000")
private Long parentId;
@Schema(description = "节点类型", example = "directory")
private String nodeType;
@Schema(description = "子节点列表")
private List<QuotaFeeItemWithRateRespVO> children;
// ==================== 取费项信息 ====================
@Schema(description = "取费项ID", example = "6001")
private Long feeItemId;
@Schema(description = "取费项名称", example = "企业管理费")
private String feeItemName;
@Schema(description = "取费项自定义序号", example = "")
private String feeItemCustomCode;
@Schema(description = "计算基数")
private Map<String, Object> calcBase;
@Schema(description = "费率百分比", example = "15")
private String ratePercentage;
@Schema(description = "代号", example = "QYGLF")
private String code;
@Schema(description = "费用归属", example = "间接费")
private String feeCategory;
@Schema(description = "基数说明", example = "按除税基价和含税基价之和计算")
private String baseDescription;
@Schema(description = "排序字段", example = "1")
private Integer sortOrder;
@Schema(description = "是否隐藏", example = "false")
private Boolean hidden;
@Schema(description = "是否为变量", example = "false")
private Boolean variable;
// ==================== 关联信息 ====================
@Schema(description = "模式节点ID", example = "1002")
private Long catalogItemId;
@Schema(description = "是否已配置取费项", example = "true")
private Boolean hasFeeItem;
// ==================== 时间信息 ====================
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,29 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import lombok.Data;
@Schema(description = "管理后台 - 定额费率字段标签 Response VO")
@Data
public class QuotaRateFieldLabelRespVO {
@Schema(description = "标签ID", example = "1")
private Long id;
@Schema(description = "模式节点ID", example = "1")
private Long catalogItemId;
@Schema(description = "标签名称", example = "土石方工程")
private String labelName;
@Schema(description = "排序字段", example = "1")
private Integer sortOrder;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,26 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - 定额费率字段标签保存 Request VO")
@Data
public class QuotaRateFieldLabelSaveReqVO {
@Schema(description = "标签ID更新时必填", example = "1")
private Long id;
@Schema(description = "模式节点ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "模式节点ID不能为空")
private Long catalogItemId;
@Schema(description = "标签名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "土石方工程")
@NotBlank(message = "标签名称不能为空")
private String labelName;
@Schema(description = "排序字段", example = "1")
private Integer sortOrder;
}

View File

@@ -1,11 +1,11 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import lombok.Data;
/**
* 定额费率字段响应 VO
@@ -23,11 +23,14 @@ public class QuotaRateFieldRespVO {
@Schema(description = "字段索引")
private Integer fieldIndex;
@Schema(description = "字段值")
private Integer fieldValue;
@Schema(description = "字段值(支持小数)")
private BigDecimal fieldValue;
@Schema(description = "字段标签")
private String fieldLabel;
@Schema(description = "字段标签ID", example = "1")
private Long fieldLabelId;
@Schema(description = "字段标签名称(关联查询)", example = "土石方工程")
private String fieldLabelName;
@Schema(description = "绑定的节点ID数组")
private Long[] bindingIds;

View File

@@ -1,9 +1,9 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import javax.validation.constraints.NotNull;
import lombok.Data;
/**
* 定额费率字段保存请求 VO
@@ -15,19 +15,22 @@ public class QuotaRateFieldSaveReqVO {
@Schema(description = "主键ID更新时必填")
private Long id;
@Schema(description = "关联费率ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "费率ID不能为空")
@Schema(description = "关联费率模式节点ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "费率模式节点ID不能为空")
private Long catalogItemId;
@Schema(description = "关联费率项ID保存字段值时必填")
private Long rateItemId;
@Schema(description = "字段索引", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "字段索引不能为空")
private Integer fieldIndex;
@Schema(description = "字段值", example = "1")
private Integer fieldValue;
@Schema(description = "字段值(支持小数)", example = "0.01")
private BigDecimal fieldValue;
@Schema(description = "字段标签", example = "1")
private String fieldLabel;
@Schema(description = "字段标签ID", example = "1")
private Long fieldLabelId;
@Schema(description = "绑定的节点ID数组")
private Long[] bindingIds;

View File

@@ -1,12 +1,11 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.Map;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.Data;
/**
* 定额费率项保存请求 VO
@@ -18,8 +17,8 @@ public class QuotaRateItemSaveReqVO {
@Schema(description = "主键ID更新时必填")
private Long id;
@Schema(description = "关联模式节点ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "模式节点ID不能为空")
@Schema(description = "关联模式节点ID(创建时必填)", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "模式节点ID不能为空", groups = {CreateGroup.class})
private Long catalogItemId;
@Schema(description = "父节点ID")
@@ -28,8 +27,8 @@ public class QuotaRateItemSaveReqVO {
@Schema(description = "自定义序号", example = "1.1")
private String customCode;
@Schema(description = "费率项名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "人工费")
@NotBlank(message = "费率项名称不能为空")
@Schema(description = "费率项名称(创建时必填)", requiredMode = Schema.RequiredMode.REQUIRED, example = "人工费")
@NotBlank(message = "费率项名称不能为空", groups = {CreateGroup.class})
private String name;
@Schema(description = "费率代号", example = "A")
@@ -47,10 +46,20 @@ public class QuotaRateItemSaveReqVO {
@Schema(description = "扩展设置")
private Map<String, Object> settings;
@Schema(description = "节点类型directory-目录value-数值", requiredMode = Schema.RequiredMode.REQUIRED, example = "value")
@NotBlank(message = "节点类型不能为空")
@Schema(description = "节点类型(创建时必填)directory-目录value-数值", requiredMode = Schema.RequiredMode.REQUIRED, example = "value")
@NotBlank(message = "节点类型不能为空", groups = {CreateGroup.class})
private String nodeType;
@Schema(description = "排序值")
private Integer sortOrder;
/**
* 创建分组
*/
public interface CreateGroup {}
/**
* 更新分组
*/
public interface UpdateGroup {}
}

View File

@@ -0,0 +1,18 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - 定额费率项交换排序 Request VO")
@Data
public class QuotaRateItemSwapSortReqVO {
@Schema(description = "节点1 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "节点1 ID不能为空")
private Long nodeId1;
@Schema(description = "节点2 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "节点2 ID不能为空")
private Long nodeId2;
}

View File

@@ -0,0 +1,28 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.Data;
/**
* 定额费率模式节点保存请求 VO
*/
@Schema(description = "管理后台 - 定额费率模式节点保存请求")
@Data
public class QuotaRateModeNodeSaveReqVO {
@Schema(description = "父节点ID定额专业节点ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "父节点ID不能为空")
private Long parentId;
@Schema(description = "节点编码", example = "MODE_001")
private String code;
@Schema(description = "节点名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "一般计税模式")
@NotBlank(message = "节点名称不能为空")
private String name;
@Schema(description = "排序值", example = "1")
private Integer sortOrder;
}

View File

@@ -1,12 +1,11 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import javax.validation.constraints.NotNull;
import lombok.Data;
/**
* 定额费率动态取值规则请求 VO

View File

@@ -1,11 +1,11 @@
package com.yhy.module.core.controller.admin.quota.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import lombok.Data;
/**
* 定额工料机组成 Response VO
@@ -54,9 +54,91 @@ public class QuotaResourceRespVO {
@Schema(description = "资源单位快照", example = "kg")
private String resourceUnit;
@Schema(description = "资源型号规格快照", example = "P.O 42.5")
private String resourceSpec;
@Schema(description = "资源类别ID", example = "1")
private Long resourceCategoryId;
@Schema(description = "资源类型", example = "material")
private String resourceType;
@Schema(description = "税率", example = "0.13")
private BigDecimal resourceTaxRate;
@Schema(description = "除税基价", example = "450.00")
private BigDecimal resourceTaxExclBasePrice;
@Schema(description = "含税基价", example = "508.50")
private BigDecimal resourceTaxInclBasePrice;
@Schema(description = "除税编制价", example = "460.00")
private BigDecimal resourceTaxExclCompilePrice;
@Schema(description = "含税编制价", example = "519.80")
private BigDecimal resourceTaxInclCompilePrice;
@Schema(description = "计算基数", example = "{\"formula\":\"人机 + 材\",\"variables\":{\"人机\":2,\"\":3}}")
private Map<String, Object> calcBase;
@Schema(description = "实际消耗量(含损耗)", example = "357.00")
private BigDecimal actualDosage;
@Schema(description = "金额", example = "17850.00")
private BigDecimal amount;
@Schema(description = "是否复合工料机", example = "false")
private Boolean isMerged;
@Schema(description = "复合工料机子数据列表")
private List<MergedResourceItemVO> mergedItems;
/**
* 复合工料机子数据 VO
*/
@Schema(description = "复合工料机子数据")
@Data
public static class MergedResourceItemVO {
@Schema(description = "子数据ID", example = "1")
private Long id;
@Schema(description = "源工料机ID", example = "100")
private Long resourceItemId;
@Schema(description = "源工料机编码", example = "C001")
private String resourceCode;
@Schema(description = "源工料机名称", example = "水泥")
private String resourceName;
@Schema(description = "源工料机单位", example = "t")
private String resourceUnit;
@Schema(description = "源工料机型号规格", example = "P.O 42.5")
private String resourceSpec;
@Schema(description = "源工料机类别ID", example = "1")
private Long resourceCategoryId;
@Schema(description = "源工料机类型", example = "material")
private String resourceType;
@Schema(description = "税率", example = "0.13")
private BigDecimal resourceTaxRate;
@Schema(description = "地区代码", example = "GD")
private String regionCode;
@Schema(description = "定额消耗量", example = "1.5")
private BigDecimal dosage;
@Schema(description = "除税市场价", example = "450.00")
private BigDecimal price;
@Schema(description = "实际消耗量(含损耗)", example = "1.53")
private BigDecimal actualDosage;
@Schema(description = "金额", example = "688.50")
private BigDecimal amount;
}
}

View File

@@ -1,7 +1,10 @@
package com.yhy.module.core.controller.admin.resource;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import com.yhy.module.core.controller.admin.resource.vo.CatalogItemSaveReqVO;
import com.yhy.module.core.controller.admin.resource.vo.ResourceCatalogItemTreeNodeVO;
import com.yhy.module.core.controller.admin.resource.vo.ResourceCategorySimpleRespVO;
import com.yhy.module.core.controller.admin.resource.vo.SwapSortOrderReqVO;
import com.yhy.module.core.dal.dataobject.resource.ResourceCatalogItemDO;
@@ -9,14 +12,18 @@ import com.yhy.module.core.service.resource.ResourceCatalogItemService;
import com.yhy.module.core.service.resource.ResourceCategoryTreeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "管理后台 - 工料机分类/条目")
@RestController
@@ -31,8 +38,14 @@ public class ResourceCatalogItemController {
private ResourceCategoryTreeService categoryTreeService;
@GetMapping("/{catalogId}/tree")
@Operation(summary = "获取分类/条目树")
public CommonResult<List<ResourceCatalogItemDO>> tree(@PathVariable("catalogId") Long catalogId) {
@Operation(summary = "获取分类/条目树(树形结构)")
public CommonResult<List<ResourceCatalogItemTreeNodeVO>> tree(@PathVariable("catalogId") Long catalogId) {
return success(itemService.getTreeByCatalog(catalogId));
}
@GetMapping("/{catalogId}/list")
@Operation(summary = "获取分类/条目列表(扁平结构)")
public CommonResult<List<ResourceCatalogItemDO>> list(@PathVariable("catalogId") Long catalogId) {
return success(itemService.listByCatalog(catalogId));
}

View File

@@ -1,23 +1,30 @@
package com.yhy.module.core.controller.admin.resource;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import com.yhy.module.core.controller.admin.resource.vo.ResourceItemQueryReqVO;
import com.yhy.module.core.controller.admin.resource.vo.ResourceItemRespVO;
import com.yhy.module.core.controller.admin.resource.vo.ResourceItemSaveReqVO;
import com.yhy.module.core.controller.admin.resource.vo.ResourceItemWithPricesRespVO;
import com.yhy.module.core.controller.admin.resource.vo.ResourcePriceSaveReqVO;
import com.yhy.module.core.dal.dataobject.resource.ResourcePriceDO;
import com.yhy.module.core.service.resource.ResourceItemService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "管理后台 - 工料机项与价格")
@RestController
@@ -54,6 +61,12 @@ public class ResourceItemController {
return success(true);
}
@GetMapping("/{id}/with-prices")
@Operation(summary = "获取工料机项及价格列表(包含完整信息)")
public CommonResult<ResourceItemWithPricesRespVO> getWithPrices(@PathVariable("id") Long id) {
return success(resourceItemService.getItemWithPrices(id));
}
// 价格相关
@GetMapping("/{id}/prices")
@Operation(summary = "查询工料机价格列表")

View File

@@ -0,0 +1,76 @@
package com.yhy.module.core.controller.admin.resource;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import com.yhy.module.core.controller.admin.resource.vo.ResourceMergedPageReqVO;
import com.yhy.module.core.controller.admin.resource.vo.ResourceMergedRespVO;
import com.yhy.module.core.controller.admin.resource.vo.ResourceMergedSaveReqVO;
import com.yhy.module.core.service.resource.ResourceMergedService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import javax.annotation.Resource;
import javax.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "管理后台 - 复合工料机")
@RestController
@RequestMapping("/core/resource/merged")
@Validated
public class ResourceMergedController {
@Resource
private ResourceMergedService resourceMergedService;
@PostMapping("/create")
@Operation(summary = "创建复合工料机")
@PreAuthorize("@ss.hasPermission('core:resource:create')")
public CommonResult<Long> createResourceMerged(@Valid @RequestBody ResourceMergedSaveReqVO createReqVO) {
return success(resourceMergedService.createResourceMerged(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新复合工料机")
@PreAuthorize("@ss.hasPermission('core:resource:update')")
public CommonResult<Boolean> updateResourceMerged(@Valid @RequestBody ResourceMergedSaveReqVO updateReqVO) {
resourceMergedService.updateResourceMerged(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除复合工料机")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('core:resource:delete')")
public CommonResult<Boolean> deleteResourceMerged(@RequestParam("id") Long id) {
resourceMergedService.deleteResourceMerged(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得复合工料机")
@Parameter(name = "id", description = "编号", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('core:resource:query')")
public CommonResult<ResourceMergedRespVO> getResourceMerged(@RequestParam("id") Long id) {
ResourceMergedRespVO respVO = resourceMergedService.getResourceMerged(id);
return success(respVO);
}
@GetMapping("/page")
@Operation(summary = "获得复合工料机分页")
@PreAuthorize("@ss.hasPermission('core:resource:query')")
public CommonResult<PageResult<ResourceMergedRespVO>> getResourceMergedPage(@Valid ResourceMergedPageReqVO pageReqVO) {
PageResult<ResourceMergedRespVO> pageResult = resourceMergedService.getResourceMergedPage(pageReqVO);
return success(pageResult);
}
}

View File

@@ -1,12 +1,11 @@
package com.yhy.module.core.controller.admin.resource.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.Data;
@Data
public class CatalogItemSaveReqVO {
@@ -29,9 +28,15 @@ public class CatalogItemSaveReqVO {
@Schema(description = "单位")
private String unit;
@Schema(description = "路径(不含自身编码),如 ['RM','Concrete']")
@Schema(description = "节点ID可选如果提供则自动查询父路径")
private Long parentId;
@Schema(description = "父路径(不含自身编码),如 ['RM','Concrete']如果提供了parentId则可以不传")
private List<String> parentPath;
@Schema(description = "排序号")
private Integer sortOrder;
@Schema(description = "扩展属性")
private Map<String, Object> attributes;
}

View File

@@ -0,0 +1,38 @@
package com.yhy.module.core.controller.admin.resource.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import java.util.Map;
import lombok.Data;
@Schema(description = "工料机目录树节点(树形结构)")
@Data
public class ResourceCatalogItemTreeNodeVO {
@Schema(description = "节点ID", example = "1")
private Long id;
@Schema(description = "工料机机类树节点ID", example = "1")
private Long categoryTreeId;
@Schema(description = "条目编码", example = "01")
private String code;
@Schema(description = "条目名称", example = "材料")
private String name;
@Schema(description = "计量单位", example = "t")
private String unit;
@Schema(description = "层级路径", example = "[\"01\", \"0101\"]")
private String[] path;
@Schema(description = "排序", example = "1")
private Integer sortOrder;
@Schema(description = "扩展属性")
private Map<String, Object> attributes;
@Schema(description = "子节点")
private List<ResourceCatalogItemTreeNodeVO> children;
}

View File

@@ -0,0 +1,38 @@
package com.yhy.module.core.controller.admin.resource.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 工料机类别完整响应VO包含价格代码
*
* @author yihuiyong
*/
@Schema(description = "工料机类别完整响应(含价格代码)")
@Data
public class ResourceCategoryFullRespVO {
@Schema(description = "类别ID", example = "1")
private Long id;
@Schema(description = "类别代码", example = "")
private String code;
@Schema(description = "类别名称", example = "人工费")
private String name;
@Schema(description = "除税基价代码", example = "DRGF")
private String taxExclBaseCode;
@Schema(description = "含税基价代码", example = "HDRGF")
private String taxInclBaseCode;
@Schema(description = "除税编制代码", example = "RGF")
private String taxExclCompileCode;
@Schema(description = "含税编制代码", example = "HRGF")
private String taxInclCompileCode;
@Schema(description = "排序", example = "1")
private Integer sortOrder;
}

View File

@@ -0,0 +1,32 @@
package com.yhy.module.core.controller.admin.resource.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.math.BigDecimal;
import java.time.OffsetDateTime;
import lombok.Data;
@Schema(description = "管理后台 - 工料机价格响应 VO")
@Data
public class ResourceItemPriceRespVO {
@Schema(description = "价格ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "地区码", example = "BJ")
private String regionCode;
@Schema(description = "有效期开始时间")
private OffsetDateTime periodStart;
@Schema(description = "有效期结束时间")
private OffsetDateTime periodEnd;
@Schema(description = "不含税价格", example = "450.00")
private BigDecimal priceTaxExcl;
@Schema(description = "含税价格", example = "508.50")
private BigDecimal priceTaxIncl;
@Schema(description = "价格来源", example = "市场价")
private String source;
}

View File

@@ -16,6 +16,9 @@ public class ResourceItemQueryReqVO extends PageParam {
@Schema(description = "分类节点ID查询该节点及其子节点下的工料机", example = "2")
private Long catalogItemId;
@Schema(description = "是否包含子节点(仅当 catalogItemId 不为空时有效)", example = "true")
private Boolean includeChildren;
@Schema(description = "类型 labor/material/machine")
private String type;

View File

@@ -1,10 +1,9 @@
package com.yhy.module.core.controller.admin.resource.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Map;
import lombok.Data;
@Schema(description = "工料机项响应")
@Data
@@ -16,9 +15,15 @@ public class ResourceItemRespVO {
@Schema(description = "库条目ID")
private Long catalogItemId;
@Schema(description = "编码(来自目录树)")
private String code;
@Schema(description = "工料机名称")
private String name;
@Schema(description = "型号规格")
private String spec;
@Schema(description = "类别ID")
private Long categoryId;

View File

@@ -1,11 +1,10 @@
package com.yhy.module.core.controller.admin.resource.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Map;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Map;
import lombok.Data;
@Data
public class ResourceItemSaveReqVO {
@@ -17,10 +16,17 @@ public class ResourceItemSaveReqVO {
@NotNull
private Long catalogItemId;
@Schema(description = "工料机编码", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank
private String code;
@Schema(description = "工料机名称", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank
private String name;
@Schema(description = "型号规格")
private String spec;
@Schema(description = "类别ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull
private Long categoryId;

View File

@@ -0,0 +1,50 @@
package com.yhy.module.core.controller.admin.resource.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.math.BigDecimal;
import java.util.List;
import lombok.Data;
@Schema(description = "管理后台 - 工料机项及价格列表响应 VO")
@Data
public class ResourceItemWithPricesRespVO {
@Schema(description = "工料机项ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "编码(来自目录树)", requiredMode = Schema.RequiredMode.REQUIRED, example = "C001")
private String code;
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "水泥 P.O 42.5")
private String name;
@Schema(description = "型号规格", example = "袋装 50kg")
private String spec;
@Schema(description = "类别ID", example = "1")
private Long categoryId;
@Schema(description = "类别名称", example = "水泥")
private String categoryName;
@Schema(description = "单位", example = "t")
private String unit;
@Schema(description = "税率", example = "0.13")
private BigDecimal taxRate;
@Schema(description = "除税基价", example = "450.00")
private BigDecimal taxExclBasePrice;
@Schema(description = "含税基价", example = "508.50")
private BigDecimal taxInclBasePrice;
@Schema(description = "除税编制价", example = "460.00")
private BigDecimal taxExclCompilePrice;
@Schema(description = "含税编制价", example = "519.80")
private BigDecimal taxInclCompilePrice;
@Schema(description = "价格历史列表")
private List<ResourceItemPriceRespVO> prices;
}

View File

@@ -0,0 +1,23 @@
package com.yhy.module.core.controller.admin.resource.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 复合工料机分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ResourceMergedPageReqVO extends PageParam {
@Schema(description = "复合工料机ID可选按复合工料机查询", example = "1000")
private Long mergedId;
@Schema(description = "数据源ID可选按数据源查询", example = "101")
private Long sourceId;
@Schema(description = "地区编码", example = "GD")
private String regionCode;
}

View File

@@ -0,0 +1,88 @@
package com.yhy.module.core.controller.admin.resource.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;
import lombok.Data;
@Schema(description = "管理后台 - 复合工料机 Response VO")
@Data
public class ResourceMergedRespVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "复合工料机ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
private Long mergedId;
@Schema(description = "数据源ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "101")
private Long sourceId;
@Schema(description = "地区编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "GD")
private String regionCode;
@Schema(description = "定额消耗量", example = "1.0")
private BigDecimal quotaConsumption;
@Schema(description = "除税市场价", example = "52.00")
private BigDecimal taxExclMarketPrice;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
// ========== 第四层工料机信息JOIN 查询) ==========
@Schema(description = "编码来自catalog_item", example = "0001")
private String code;
@Schema(description = "名称来自catalog_item", example = "综合人工")
private String name;
@Schema(description = "目录树节点ID来自resource_item", example = "1001")
private Long catalogItemId;
@Schema(description = "型号规格来自resource_item", example = "技术要求高的工种")
private String spec;
@Schema(description = "类别ID来自resource_item", example = "1")
private Long categoryId;
@Schema(description = "类别名称来自resource_category", example = "人工费")
private String categoryName;
@Schema(description = "单位来自catalog_item", example = "工日")
private String unit;
@Schema(description = "税率来自resource_item", example = "0.09")
private BigDecimal taxRate;
@Schema(description = "除税基价来自resource_item", example = "50.00")
private BigDecimal taxExclBasePrice;
@Schema(description = "含税基价来自resource_item", example = "54.50")
private BigDecimal taxInclBasePrice;
@Schema(description = "除税编制价来自resource_item", example = "55.00")
private BigDecimal taxExclCompilePrice;
@Schema(description = "含税编制价来自resource_item", example = "59.95")
private BigDecimal taxInclCompilePrice;
@Schema(description = "计算基数来自resource_item")
private Map<String, Object> calcBase;
// ========== 虚拟字段(计算合价) ==========
@Schema(description = "除税基价合价(虚拟字段)", example = "50.00")
private BigDecimal taxExclBaseTotal;
@Schema(description = "含税基价合价(虚拟字段)", example = "54.50")
private BigDecimal taxInclBaseTotal;
@Schema(description = "除税编制价合价(虚拟字段)", example = "55.00")
private BigDecimal taxExclCompileTotal;
@Schema(description = "含税编制价合价(虚拟字段)", example = "59.95")
private BigDecimal taxInclCompileTotal;
}

View File

@@ -0,0 +1,31 @@
package com.yhy.module.core.controller.admin.resource.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.math.BigDecimal;
import javax.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - 复合工料机新增/修改 Request VO")
@Data
public class ResourceMergedSaveReqVO {
@Schema(description = "主键(更新时必填)", example = "1")
private Long id;
@Schema(description = "复合工料机ID引用第四层的复合工料机项is_merged=1", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
@NotNull(message = "复合工料机ID不能为空")
private Long mergedId;
@Schema(description = "数据源ID引用真实的第四层工料机项ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "101")
@NotNull(message = "数据源ID不能为空")
private Long sourceId;
@Schema(description = "地区编码(可选)", example = "GD")
private String regionCode;
@Schema(description = "定额消耗量(可选)", example = "1.0")
private BigDecimal quotaConsumption;
@Schema(description = "除税市场价(可选)", example = "52.00")
private BigDecimal taxExclMarketPrice;
}

View File

@@ -1,41 +0,0 @@
package com.yhy.module.core.convert.quota;
import com.yhy.module.core.controller.admin.quota.vo.QuotaAdjustmentRespVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaAdjustmentDO;
import com.yhy.module.core.enums.quota.QuotaAdjustmentTypeEnum;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface QuotaAdjustmentConvert {
QuotaAdjustmentConvert INSTANCE = Mappers.getMapper(QuotaAdjustmentConvert.class);
default QuotaAdjustmentRespVO convert(QuotaAdjustmentDO bean) {
if (bean == null) {
return null;
}
QuotaAdjustmentRespVO vo = new QuotaAdjustmentRespVO();
vo.setId(bean.getId());
vo.setQuotaItemId(bean.getQuotaItemId());
vo.setName(bean.getName());
vo.setContent(bean.getContent());
vo.setAdjustmentType(bean.getAdjustmentType());
vo.setAdjustmentRules(bean.getAdjustmentRules());
vo.setSortOrder(bean.getSortOrder());
vo.setCreateTime(bean.getCreateTime());
vo.setUpdateTime(bean.getUpdateTime());
// 设置调整类型名称
QuotaAdjustmentTypeEnum typeEnum = QuotaAdjustmentTypeEnum.valueOfCode(bean.getAdjustmentType());
if (typeEnum != null) {
vo.setAdjustmentTypeName(typeEnum.getName());
}
return vo;
}
List<QuotaAdjustmentRespVO> convertList(List<QuotaAdjustmentDO> list);
}

View File

@@ -0,0 +1,54 @@
package com.yhy.module.core.dal.dataobject.quota;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* 定额调整明细 DO
*
* @author 芋道源码
*/
@TableName("yhy_quota_adjustment_detail")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class QuotaAdjustmentDetailDO extends TenantBaseDO {
/**
* 主键ID
*/
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
* 调整设置ID
*/
private Long adjustmentSettingId;
/**
* 定额调整编号引用其他调整设置ID
*/
private Long adjustmentCode;
/**
* 调整内容
*/
private String adjustment;
/**
* 排序
*/
private Integer sortOrder;
}

View File

@@ -1,10 +1,12 @@
package com.yhy.module.core.dal.dataobject.quota;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yhy.module.core.dal.typehandler.PostgreSQLJsonbTypeHandler;
import java.math.BigDecimal;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
@@ -15,20 +17,22 @@ import lombok.ToString;
/**
* 定额调整设置 DO
*
* @author 芋道源码
*/
@TableName(value = "yhy_quota_adjustment", autoResultMap = true)
@TableName(value = "yhy_quota_adjustment_setting", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class QuotaAdjustmentDO extends TenantBaseDO {
public class QuotaAdjustmentSettingDO extends TenantBaseDO {
/**
* 主键ID标准库使用自增ID
* 主键ID
*/
@TableId
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
@@ -42,17 +46,22 @@ public class QuotaAdjustmentDO extends TenantBaseDO {
private String name;
/**
* 调整内容纯文本
* 定额值
*/
private String content;
private BigDecimal quotaValue;
/**
* 调整类型
* 调整内容
*/
private String adjustmentContent;
/**
* 调整类型字典
*/
private String adjustmentType;
/**
* 调整规则JSON结构
* 调整规则JSON
*/
@TableField(typeHandler = PostgreSQLJsonbTypeHandler.class)
private Map<String, Object> adjustmentRules;
@@ -61,4 +70,5 @@ public class QuotaAdjustmentDO extends TenantBaseDO {
* 排序
*/
private Integer sortOrder;
}

View File

@@ -1,31 +1,30 @@
package com.yhy.module.core.dal.dataobject.quota;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yhy.module.core.dal.typehandler.PostgreSQLJsonbTypeHandler;
import com.yhy.module.core.framework.mybatis.typehandler.StringArrayTypeHandler;
import java.util.Map;
import lombok.AccessLevel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Map;
import lombok.Getter;
/**
* 定额目录条目 DO
* 定额基价第一层 - 定额专业树 DO
*
* 对应表 yhy_catalog_item复用资源库条目表)
* 对应表 yhy_quota_catalog_item独立表)
*
* 三层结构:
* - 第一层:定额目录树(省市/定额专业),通过 attributes.node_type 区分
* - 第二层:工料机专业节点(通过 categoryTreeId 绑定
* - 第三层:定额子目树(目录/内容),通过 attributes.content_type 区分
* 树形结构:
* - 地区节点node_type='region'
* - 定额专业节点node_type='specialty'
*
* @author yhy
*/
@TableName(value = "yhy_catalog_item", autoResultMap = true)
@KeySequence("yhy_catalog_item_id_seq")
@TableName(value = "yhy_quota_catalog_item", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
public class QuotaCatalogItemDO extends TenantBaseDO {
@@ -33,7 +32,7 @@ public class QuotaCatalogItemDO extends TenantBaseDO {
/**
* 主键
*/
@TableId
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
@@ -44,7 +43,7 @@ public class QuotaCatalogItemDO extends TenantBaseDO {
/**
* 工料机机类树节点ID引用yhy_resource_category_tree
*
* 只有第一层的"定额专业"节点才会绑定此字段
* 只有"定额专业"节点才会绑定此字段
*/
private Long categoryTreeId;
@@ -74,17 +73,19 @@ public class QuotaCatalogItemDO extends TenantBaseDO {
*/
private Integer sortOrder;
/**
* 节点类型region-地区节点, specialty-定额专业节点)
*/
private String nodeType;
/**
* 定额专业是否已绑定工料机专业(绑定后不可修改)
*/
@Getter(AccessLevel.NONE)
private Boolean specialtyLocked;
/**
* 扩展属性JSONB
*
* 第一层属性:
* - node_type: "province"(省市)| "specialty"(定额专业)
* - specialty_locked: true/false是否已绑定工料机专业
* - bind_time: "2024-12-08T10:30:00Z"(绑定时间)
*
* 第三层属性:
* - content_type: "directory"(目录)| "content"(内容)
* - allow_children: true/false是否允许添加子节点
*/
@TableField(typeHandler = PostgreSQLJsonbTypeHandler.class)
private Map<String, Object> attributes;
@@ -92,70 +93,24 @@ public class QuotaCatalogItemDO extends TenantBaseDO {
// ========== 便捷方法 ==========
/**
* 获取节点类型(第一层)
*/
public String getNodeType() {
return attributes != null ? (String) attributes.get("node_type") : null;
}
/**
* 设置节点类型(第一层)
*/
public void setNodeType(String nodeType) {
if (attributes == null) {
attributes = new java.util.HashMap<>();
}
attributes.put("node_type", nodeType);
}
/**
* 是否已绑定工料机专业(第一层)
* 是否已绑定工料机专业
*/
public Boolean isSpecialtyLocked() {
return attributes != null ? (Boolean) attributes.get("specialty_locked") : false;
return Boolean.TRUE.equals(specialtyLocked);
}
/**
* 设置绑定状态(第一层)
*/
public void setSpecialtyLocked(Boolean locked) {
if (attributes == null) {
attributes = new java.util.HashMap<>();
}
attributes.put("specialty_locked", locked);
}
/**
* 获取内容类型(第三层)
*/
public String getContentType() {
return attributes != null ? (String) attributes.get("content_type") : null;
}
/**
* 设置内容类型(第三层)
*/
public void setContentType(String contentType) {
if (attributes == null) {
attributes = new java.util.HashMap<>();
}
attributes.put("content_type", contentType);
}
/**
* 是否允许添加子节点(第三层)
* 是否允许添加子节点
*/
public Boolean isAllowChildren() {
return attributes != null ? (Boolean) attributes.get("allow_children") : true;
// 所有节点都可以添加子节点
return true;
}
/**
* 设置是否允许子节点(第三层
* 获取内容类型(定额专业树没有此概念
*/
public void setAllowChildren(Boolean allow) {
if (attributes == null) {
attributes = new java.util.HashMap<>();
}
attributes.put("allow_children", allow);
public String getContentType() {
return null;
}
}

View File

@@ -0,0 +1,100 @@
package com.yhy.module.core.dal.dataobject.quota;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yhy.module.core.dal.typehandler.PostgreSQLJsonbTypeHandler;
import com.yhy.module.core.dal.typehandler.PostgreSQLTextArrayTypeHandler;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* 定额子目树 DO
* 第二层:定额子目树(目录/内容)
*
* @author yhy
*/
@TableName(value = "yhy_quota_catalog_tree", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class QuotaCatalogTreeDO extends BaseDO {
/**
* 主键
*/
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
* 租户ID
*/
private Long tenantId;
/**
* 关联定额专业节点ID第一层
*/
private Long catalogItemId;
/**
* 父节点ID自关联
*/
private Long parentId;
/**
* 编码
*/
private String code;
/**
* 名称
*/
private String name;
/**
* 单位
*/
private String unit;
/**
* 内容类型directory-目录content-内容
*/
private String contentType;
/**
* 是否允许添加子节点
*/
private Boolean allowChildren;
/**
* 排序
*/
private Integer sortOrder;
/**
* 树路径
*/
@TableField(typeHandler = PostgreSQLTextArrayTypeHandler.class)
private String[] path;
/**
* 层级
*/
private Integer level;
/**
* 扩展属性
*/
@TableField(typeHandler = PostgreSQLJsonbTypeHandler.class)
private Map<String, Object> attributes;
}

View File

@@ -1,13 +1,14 @@
package com.yhy.module.core.dal.dataobject.quota;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yhy.module.core.dal.typehandler.PostgreSQLJsonbTypeHandler;
import java.util.Map;
import lombok.Data;
import lombok.EqualsAndHashCode;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import java.util.Map;
/**
* 定额取费项 DO
@@ -24,6 +25,7 @@ public class QuotaFeeItemDO extends BaseDO {
/**
* 主键ID
*/
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
@@ -36,6 +38,12 @@ public class QuotaFeeItemDO extends BaseDO {
*/
private Long catalogItemId;
/**
* 关联的费率项ID任意层级节点可为空
* 用于与定额费率项建立一对一关系
*/
private Long rateItemId;
/**
* 自定义序号(字符串,显示用,不参与排序)
* 如:"一"、"1.1"、"(1)"
@@ -52,20 +60,32 @@ public class QuotaFeeItemDO extends BaseDO {
*
* 格式:
* {
* "formula": "除税基价 + 含税基价 - 除税编制 * 含税编制",
* "formula": "DRGF+HDRGF/DCLF-(DRGF*DCLF+12)",
* "variables": {
* "除税基价": "tax_excl_base_price",
* "含税基价": "tax_incl_base_price",
* "除税编制": "tax_excl_compile_price",
* "含税编制": "tax_incl_compile_price"
* "DRGF": {
* "categoryId": 1,
* "priceField": "tax_excl_base_price"
* },
* "HDRGF": {
* "categoryId": 1,
* "priceField": "tax_incl_base_price"
* },
* "DCLF": {
* "categoryId": 3,
* "priceField": "tax_excl_base_price"
* }
* }
* }
*
* 价格代码说明:
* 价格字段类型说明:
* - tax_excl_base_price: 除税基价
* - tax_incl_base_price: 含税基价
* - tax_excl_compile_price: 除税编制价
* - tax_incl_compile_price: 含税编制价
*
* variables 中的每个变量包含:
* - categoryId: 类别ID对应 yhy_resource_category 表的 id
* - priceField: 价格字段类型上述4个值之一
*/
@TableField(typeHandler = PostgreSQLJsonbTypeHandler.class)
private Map<String, Object> calcBase;
@@ -97,6 +117,16 @@ public class QuotaFeeItemDO extends BaseDO {
*/
private Integer sortOrder;
/**
* 是否隐藏true=隐藏false=显示)
*/
private Boolean hidden;
/**
* 是否为变量true=变量false=非变量)
*/
private Boolean variable;
// ==================== 便捷方法 ====================
/**
@@ -118,14 +148,14 @@ public class QuotaFeeItemDO extends BaseDO {
}
/**
* 获取变量映射
* 获取 calcBase 中的变量映射(兼容旧数据)
*/
@SuppressWarnings("unchecked")
public Map<String, String> getVariables() {
public Map<String, Object> getCalcBaseVariables() {
if (calcBase == null) {
return null;
}
return (Map<String, String>) calcBase.get("variables");
return (Map<String, Object>) calcBase.get("variables");
}
// ==================== 常量 ====================

View File

@@ -6,11 +6,10 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yhy.module.core.dal.typehandler.PostgreSQLJsonbTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Map;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 定额子目/基价 DO
@@ -34,7 +33,7 @@ public class QuotaItemDO extends TenantBaseDO {
private Long id;
/**
* 定额条目ID关联 yhy_catalog_item
* 定额子目树节点ID关联 yhy_quota_catalog_tree
*
* 只能关联 content_type='content' 的节点
*/

View File

@@ -1,17 +1,20 @@
package com.yhy.module.core.dal.dataobject.quota;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yhy.module.core.dal.typehandler.PostgreSQLBigintArrayTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 定额费率字段绑定 DO
*
* 存储费率与定额基价节点的绑定关系
* 每个费率可以有多个字段field_1, field_2, ...),每个字段可以绑定多个定额基价节点
* 存储费率模式节点与定额基价节点的绑定关系
* 每个费率模式节点可以有多个字段field_1, field_2, ...),每个字段可以绑定多个定额基价节点
* 绑定关系影响该费率模式节点下的所有费率项
*/
@TableName(value = "yhy_quota_rate_field", autoResultMap = true)
@Data
@@ -21,6 +24,7 @@ public class QuotaRateFieldDO extends BaseDO {
/**
* 主键ID
*/
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
@@ -29,9 +33,9 @@ public class QuotaRateFieldDO extends BaseDO {
private Long tenantId;
/**
* 关联费率项ID
* 关联费率模式节点IDyhy_quota_catalog_item
*/
private Long rateItemId;
private Long catalogItemId;
/**
* 字段索引1, 2, 3...
@@ -40,16 +44,16 @@ public class QuotaRateFieldDO extends BaseDO {
private Integer fieldIndex;
/**
* 字段值(用于标识)
* 字段值(用于标识,支持小数
* 如1, 2, 3 分别代表 1区, 2区, 3区
* 或0.01, 0.224 等小数值
*/
private Integer fieldValue;
private java.math.BigDecimal fieldValue;
/**
* 字段标签(显示用
* 如:"1区"、"2区"、"3区"
* 字段标签ID引用yhy_quota_rate_field_label
*/
private String fieldLabel;
private Long fieldLabelId;
/**
* 绑定的定额基价节点ID数组

View File

@@ -0,0 +1,47 @@
package com.yhy.module.core.dal.dataobject.quota;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 定额费率字段标签字典 DO
*
* @author yhy
*/
@TableName("yhy_quota_rate_field_label")
@KeySequence("yhy_quota_rate_field_label_id_seq")
@Data
@EqualsAndHashCode(callSuper = true)
public class QuotaRateFieldLabelDO extends BaseDO {
/**
* 主键
*/
@TableId
private Long id;
/**
* 租户ID
*/
private Long tenantId;
/**
* 关联模式节点ID
*/
private Long catalogItemId;
/**
* 字段标签名称
*/
private String labelName;
/**
* 排序字段
*/
private Integer sortOrder;
}

View File

@@ -1,15 +1,16 @@
package com.yhy.module.core.dal.dataobject.quota;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yhy.module.core.dal.typehandler.PostgreSQLJsonbTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 定额费率项 DO
@@ -26,6 +27,7 @@ public class QuotaRateItemDO extends BaseDO {
/**
* 主键ID
*/
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
@@ -87,18 +89,23 @@ public class QuotaRateItemDO extends BaseDO {
* "remark": "备注"
* }
*
* 动态模式:
* 动态模式(默认使用阶梯规则)
* {
* "valueRules": {
* "tiers": [
* "tiers": [ // 阶梯规则(必填)
* {"seq": 1, "threshold": 50, "compareType": "lte", "fieldValues": {"1": 0.224, "2": 0}},
* {"seq": 2, "threshold": 100, "compareType": "lte", "fieldValues": {"1": 0.301, "2": 0}},
* ...
* ],
* "increments": [
* "increments": [ // 增量规则(可选,在阶梯基础上叠加)
* {"seq": 7, "step": 100, "baseThreshold": 1000, "fieldIncrements": {"1": 0.036, "2": 0.002}}
* ]
* }
* }
*
* 计算逻辑:
* 1. 根据基数值匹配阶梯规则,获取基础字段值
* 2. 如果配置了增量规则,在基础值上叠加增量
*/
@TableField(typeHandler = PostgreSQLJsonbTypeHandler.class)
private Map<String, Object> settings;

View File

@@ -6,11 +6,10 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yhy.module.core.dal.typehandler.PostgreSQLJsonbTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Map;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 定额子目工料机组成 DO
@@ -161,6 +160,23 @@ public class QuotaResourceDO extends TenantBaseDO {
attributes.put("resource_unit", resourceUnit);
}
/**
* 获取资源型号规格快照
*/
public String getResourceSpec() {
return attributes != null ? (String) attributes.get("resource_spec") : null;
}
/**
* 设置资源型号规格快照
*/
public void setResourceSpec(String resourceSpec) {
if (attributes == null) {
attributes = new java.util.HashMap<>();
}
attributes.put("resource_spec", resourceSpec);
}
/**
* 计算实际消耗量(含损耗)
*

View File

@@ -1,16 +1,16 @@
package com.yhy.module.core.dal.dataobject.resource;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yhy.module.core.dal.typehandler.PostgreSQLJsonbTypeHandler;
import java.util.Map;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Map;
/**
* 工料机项 DO对应 yhy_resource_item。
*/
@@ -31,11 +31,21 @@ public class ResourceItemDO extends TenantBaseDO {
*/
private Long catalogItemId;
/**
* 工料机编码(独立唯一值)
*/
private String code;
/**
* 工料机名称
*/
private String name;
/**
* 型号规格
*/
private String spec;
/**
* 类别ID引用 yhy_resource_category.id
*/
@@ -84,7 +94,9 @@ public class ResourceItemDO extends TenantBaseDO {
/**
* 复合数据标识符0=普通1=复合)
* 注意:此字段由数据库触发器自动维护,应用层不应修改
*/
@TableField(insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
private Integer isMerged;
/**

View File

@@ -4,17 +4,16 @@ import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.math.BigDecimal;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
/**
* 复合工料机第五层存储多地区价格DO
*
* @author yihuiyong
*/
@TableName(value = "yhy_resource_merged", autoResultMap = true)
@TableName(value = "yhy_resource_merged")
@KeySequence("yhy_resource_merged_id_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@@ -27,10 +26,15 @@ public class ResourceMergedDO extends TenantBaseDO {
private Long id;
/**
* 工料机ID引用yhy_resource_item.id
* 复合工料机ID引用第四层的复合工料机项is_merged=1
*/
private Long mergedId;
/**
* 数据源ID引用真实的第四层工料机项ID
*/
private Long sourceId;
/**
* 地区编码
*/

View File

@@ -0,0 +1,46 @@
package com.yhy.module.core.dal.mysql.quota;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.yhy.module.core.dal.dataobject.quota.QuotaAdjustmentDetailDO;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
/**
* 定额调整明细 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface QuotaAdjustmentDetailMapper extends BaseMapperX<QuotaAdjustmentDetailDO> {
default List<QuotaAdjustmentDetailDO> selectListBySettingId(Long adjustmentSettingId) {
return selectList(new LambdaQueryWrapperX<QuotaAdjustmentDetailDO>()
.eq(QuotaAdjustmentDetailDO::getAdjustmentSettingId, adjustmentSettingId)
.orderByAsc(QuotaAdjustmentDetailDO::getSortOrder));
}
default List<QuotaAdjustmentDetailDO> selectListBySettingIds(List<Long> adjustmentSettingIds) {
return selectList(new LambdaQueryWrapperX<QuotaAdjustmentDetailDO>()
.in(QuotaAdjustmentDetailDO::getAdjustmentSettingId, adjustmentSettingIds)
.orderByAsc(QuotaAdjustmentDetailDO::getAdjustmentSettingId)
.orderByAsc(QuotaAdjustmentDetailDO::getSortOrder));
}
default QuotaAdjustmentDetailDO selectByIdForUpdate(Long id) {
return selectOne(new LambdaQueryWrapperX<QuotaAdjustmentDetailDO>()
.eq(QuotaAdjustmentDetailDO::getId, id)
.last("FOR UPDATE"));
}
default Long countBySettingId(Long adjustmentSettingId) {
return selectCount(new LambdaQueryWrapperX<QuotaAdjustmentDetailDO>()
.eq(QuotaAdjustmentDetailDO::getAdjustmentSettingId, adjustmentSettingId));
}
default Long countByAdjustmentCode(Long adjustmentCode) {
return selectCount(new LambdaQueryWrapperX<QuotaAdjustmentDetailDO>()
.eq(QuotaAdjustmentDetailDO::getAdjustmentCode, adjustmentCode));
}
}

View File

@@ -1,27 +0,0 @@
package com.yhy.module.core.dal.mysql.quota;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.yhy.module.core.dal.dataobject.quota.QuotaAdjustmentDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 定额调整设置 Mapper
*/
@Mapper
public interface QuotaAdjustmentMapper extends BaseMapperX<QuotaAdjustmentDO> {
default List<QuotaAdjustmentDO> selectListByQuotaItemId(Long quotaItemId) {
return selectList(new LambdaQueryWrapperX<QuotaAdjustmentDO>()
.eq(QuotaAdjustmentDO::getQuotaItemId, quotaItemId)
.orderByAsc(QuotaAdjustmentDO::getSortOrder));
}
default QuotaAdjustmentDO selectByIdForUpdate(Long id) {
return selectOne(new LambdaQueryWrapperX<QuotaAdjustmentDO>()
.eq(QuotaAdjustmentDO::getId, id)
.last("FOR UPDATE"));
}
}

View File

@@ -0,0 +1,29 @@
package com.yhy.module.core.dal.mysql.quota;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.yhy.module.core.dal.dataobject.quota.QuotaAdjustmentSettingDO;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
/**
* 定额调整设置 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface QuotaAdjustmentSettingMapper extends BaseMapperX<QuotaAdjustmentSettingDO> {
default List<QuotaAdjustmentSettingDO> selectListByQuotaItemId(Long quotaItemId) {
return selectList(new LambdaQueryWrapperX<QuotaAdjustmentSettingDO>()
.eq(QuotaAdjustmentSettingDO::getQuotaItemId, quotaItemId)
.orderByAsc(QuotaAdjustmentSettingDO::getSortOrder));
}
default QuotaAdjustmentSettingDO selectByIdForUpdate(Long id) {
return selectOne(new LambdaQueryWrapperX<QuotaAdjustmentSettingDO>()
.eq(QuotaAdjustmentSettingDO::getId, id)
.last("FOR UPDATE"));
}
}

View File

@@ -1,12 +1,12 @@
package com.yhy.module.core.dal.mysql.quota;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.yhy.module.core.dal.dataobject.quota.QuotaCatalogItemDO;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 定额目录条目 Mapper
*
@@ -33,7 +33,8 @@ public interface QuotaCatalogItemMapper extends BaseMapperX<QuotaCatalogItemDO>
* 查询根节点列表parentId 为 null
*/
default List<QuotaCatalogItemDO> selectRootList() {
return selectList("parent_id", null);
return selectList(new LambdaQueryWrapperX<QuotaCatalogItemDO>()
.isNull(QuotaCatalogItemDO::getParentId));
}
/**
@@ -57,4 +58,16 @@ public interface QuotaCatalogItemMapper extends BaseMapperX<QuotaCatalogItemDO>
* @return 所有子孙节点
*/
List<QuotaCatalogItemDO> selectDescendants(@Param("id") Long id);
/**
* 使用行锁查询节点(用于排序交换)
*
* @param id 节点ID
* @return 节点信息
*/
default QuotaCatalogItemDO selectByIdForUpdate(Long id) {
return selectOne(new LambdaQueryWrapperX<QuotaCatalogItemDO>()
.eq(QuotaCatalogItemDO::getId, id)
.last("FOR UPDATE"));
}
}

View File

@@ -0,0 +1,42 @@
package com.yhy.module.core.dal.mysql.quota;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import com.yhy.module.core.dal.dataobject.quota.QuotaCatalogTreeDO;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* 定额子目树 Mapper
*
* @author yhy
*/
@Mapper
public interface QuotaCatalogTreeMapper extends BaseMapperX<QuotaCatalogTreeDO> {
/**
* 查询指定定额专业下的所有节点
*/
default List<QuotaCatalogTreeDO> selectListByCatalogItemId(Long catalogItemId) {
return selectList(QuotaCatalogTreeDO::getCatalogItemId, catalogItemId);
}
/**
* 查询指定父节点下的子节点
*/
default List<QuotaCatalogTreeDO> selectListByParentId(Long parentId) {
return selectList(QuotaCatalogTreeDO::getParentId, parentId);
}
/**
* 查询同级节点(用于排序)
*/
default List<QuotaCatalogTreeDO> selectSiblings(@Param("catalogItemId") Long catalogItemId,
@Param("parentId") Long parentId) {
return selectList(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<QuotaCatalogTreeDO>()
.eq(QuotaCatalogTreeDO::getCatalogItemId, catalogItemId)
.eq(parentId != null, QuotaCatalogTreeDO::getParentId, parentId)
.isNull(parentId == null, QuotaCatalogTreeDO::getParentId)
.orderByAsc(QuotaCatalogTreeDO::getSortOrder));
}
}

View File

@@ -0,0 +1,55 @@
package com.yhy.module.core.dal.mysql.quota;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.yhy.module.core.dal.dataobject.quota.QuotaRateFieldLabelDO;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
/**
* 定额费率字段标签字典 Mapper
*
* @author yhy
*/
@Mapper
public interface QuotaRateFieldLabelMapper extends BaseMapperX<QuotaRateFieldLabelDO> {
/**
* 根据模式节点ID查询标签列表
*/
default List<QuotaRateFieldLabelDO> selectListByCatalogItemId(Long catalogItemId) {
return selectList(new LambdaQueryWrapperX<QuotaRateFieldLabelDO>()
.eq(QuotaRateFieldLabelDO::getCatalogItemId, catalogItemId)
.orderByAsc(QuotaRateFieldLabelDO::getSortOrder));
}
/**
* 根据模式节点ID和标签名称查询
*/
default QuotaRateFieldLabelDO selectByCatalogItemIdAndName(Long catalogItemId, String labelName) {
return selectOne(new LambdaQueryWrapperX<QuotaRateFieldLabelDO>()
.eq(QuotaRateFieldLabelDO::getCatalogItemId, catalogItemId)
.eq(QuotaRateFieldLabelDO::getLabelName, labelName));
}
/**
* 查询最大排序值
*/
default Integer selectMaxSortOrder(Long catalogItemId) {
QuotaRateFieldLabelDO label = selectOne(new LambdaQueryWrapperX<QuotaRateFieldLabelDO>()
.eq(QuotaRateFieldLabelDO::getCatalogItemId, catalogItemId)
.orderByDesc(QuotaRateFieldLabelDO::getSortOrder)
.last("LIMIT 1"));
return label != null ? label.getSortOrder() : 0;
}
/**
* 更新排序值
*/
default void updateSortOrder(Long id, Integer sortOrder) {
QuotaRateFieldLabelDO updateObj = new QuotaRateFieldLabelDO();
updateObj.setId(id);
updateObj.setSortOrder(sortOrder);
updateById(updateObj);
}
}

View File

@@ -3,11 +3,10 @@ package com.yhy.module.core.dal.mysql.quota;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.yhy.module.core.dal.dataobject.quota.QuotaRateFieldDO;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Collections;
import java.util.List;
import org.apache.ibatis.annotations.Select;
/**
* 定额费率字段绑定 Mapper
@@ -16,29 +15,29 @@ import java.util.List;
public interface QuotaRateFieldMapper extends BaseMapperX<QuotaRateFieldDO> {
/**
* 根据费率ID查询字段列表
* 根据费率模式节点ID查询字段列表
*/
default List<QuotaRateFieldDO> selectListByRateItemId(Long rateItemId) {
default List<QuotaRateFieldDO> selectListByCatalogItemId(Long catalogItemId) {
return selectList(new LambdaQueryWrapperX<QuotaRateFieldDO>()
.eq(QuotaRateFieldDO::getRateItemId, rateItemId)
.eq(QuotaRateFieldDO::getCatalogItemId, catalogItemId)
.orderByAsc(QuotaRateFieldDO::getFieldIndex));
}
/**
* 根据费率ID和字段索引查询
* 根据费率模式节点ID和字段索引查询
*/
default QuotaRateFieldDO selectByRateItemIdAndFieldIndex(Long rateItemId, Integer fieldIndex) {
default QuotaRateFieldDO selectByCatalogItemIdAndFieldIndex(Long catalogItemId, Integer fieldIndex) {
return selectOne(new LambdaQueryWrapperX<QuotaRateFieldDO>()
.eq(QuotaRateFieldDO::getRateItemId, rateItemId)
.eq(QuotaRateFieldDO::getCatalogItemId, catalogItemId)
.eq(QuotaRateFieldDO::getFieldIndex, fieldIndex));
}
/**
* 删除费率的所有字段
* 删除费率模式节点的所有字段
*/
default int deleteByRateItemId(Long rateItemId) {
default int deleteByCatalogItemId(Long catalogItemId) {
return delete(new LambdaQueryWrapperX<QuotaRateFieldDO>()
.eq(QuotaRateFieldDO::getRateItemId, rateItemId));
.eq(QuotaRateFieldDO::getCatalogItemId, catalogItemId));
}
/**
@@ -51,22 +50,29 @@ public interface QuotaRateFieldMapper extends BaseMapperX<QuotaRateFieldDO> {
}
/**
* 根据费率项ID列表查询所有字段
* 统计费率模式节点的字段数量
*/
default List<QuotaRateFieldDO> selectListByRateItemIds(@Param("rateItemIds") List<Long> rateItemIds) {
if (rateItemIds == null || rateItemIds.isEmpty()) {
return Collections.emptyList();
}
return selectList(new LambdaQueryWrapperX<QuotaRateFieldDO>()
.in(QuotaRateFieldDO::getRateItemId, rateItemIds)
.orderByAsc(QuotaRateFieldDO::getFieldIndex));
default Long countByCatalogItemId(Long catalogItemId) {
return selectCount(new LambdaQueryWrapperX<QuotaRateFieldDO>()
.eq(QuotaRateFieldDO::getCatalogItemId, catalogItemId));
}
/**
* 统计费率项的字段数量
* 查询所有包含指定绑定节点的字段(排除指定字段索引)
* 用于检查节点是否已被其他虚拟字段绑定
*
* @param catalogItemId 费率模式节点ID
* @param bindingId 要检查的绑定节点ID
* @param excludeFieldIndex 要排除的字段索引(当前正在更新的字段)
* @return 包含该绑定节点的字段列表
*/
default Long countByRateItemId(Long rateItemId) {
return selectCount(new LambdaQueryWrapperX<QuotaRateFieldDO>()
.eq(QuotaRateFieldDO::getRateItemId, rateItemId));
}
@Select("SELECT * FROM yhy_quota_rate_field " +
"WHERE catalog_item_id = #{catalogItemId} " +
"AND field_index != #{excludeFieldIndex} " +
"AND binding_ids @> ARRAY[#{bindingId}]::bigint[] " +
"AND deleted = 0")
List<QuotaRateFieldDO> selectByBindingIdExcludeFieldIndex(
@Param("catalogItemId") Long catalogItemId,
@Param("bindingId") Long bindingId,
@Param("excludeFieldIndex") Integer excludeFieldIndex);
}

View File

@@ -3,13 +3,12 @@ package com.yhy.module.core.dal.mysql.quota;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.yhy.module.core.dal.dataobject.quota.QuotaRateItemDO;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
/**
* 定额费率项 Mapper
*/
@@ -57,8 +56,8 @@ public interface QuotaRateItemMapper extends BaseMapperX<QuotaRateItemDO> {
*/
@Select("SELECT COALESCE(MAX(sort_order), 0) FROM yhy_quota_rate_item " +
"WHERE catalog_item_id = #{catalogItemId} " +
"AND (parent_id = #{parentId} OR (#{parentId} IS NULL AND parent_id IS NULL)) " +
"AND deleted = false")
"AND (parent_id = #{parentId} OR (#{parentId}::bigint IS NULL AND parent_id IS NULL)) " +
"AND deleted = 0")
Integer selectMaxSortOrder(@Param("catalogItemId") Long catalogItemId, @Param("parentId") Long parentId);
/**

View File

@@ -3,7 +3,28 @@ package com.yhy.module.core.dal.mysql.resource;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import com.yhy.module.core.dal.dataobject.resource.ResourceCatalogItemDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface ResourceCatalogItemMapper extends BaseMapperX<ResourceCatalogItemDO> {
/**
* 检查是否存在子节点
* 使用PostgreSQL数组切片语法path[1:array_length(path,1)-1] 表示去掉最后一个元素
* 使用 CAST 函数进行类型转换,确保类型匹配
*
* @param categoryTreeId 机类树ID
* @param path 父节点路径
* @param tenantId 租户ID
* @return 子节点数量
*/
@Select("SELECT COUNT(*) FROM yhy_catalog_item " +
"WHERE category_tree_id = #{categoryTreeId} " +
"AND path[1:array_length(path,1)-1]::varchar[] = #{path} " +
"AND tenant_id = #{tenantId} " +
"AND deleted = 0")
Long countChildNodes(@Param("categoryTreeId") Long categoryTreeId,
@Param("path") String[] path,
@Param("tenantId") Long tenantId);
}

View File

@@ -2,9 +2,12 @@ package com.yhy.module.core.dal.mysql.resource;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import com.yhy.module.core.dal.dataobject.resource.ResourceItemDO;
import org.apache.ibatis.annotations.Mapper;
import java.math.BigDecimal;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
@Mapper
public interface ResourceItemMapper extends BaseMapperX<ResourceItemDO> {
@@ -13,8 +16,77 @@ public interface ResourceItemMapper extends BaseMapperX<ResourceItemDO> {
* 根据工料机机类树节点ID查询工料机列表
*
* 用于定额子目工料机的范围过滤
* 通过 catalog_item_id 关联 yhy_catalog_item 表,再过滤 category_tree_id
*/
default List<ResourceItemDO> selectByCategoryTreeId(Long categoryTreeId) {
return selectList("category_tree_id", categoryTreeId);
@Select("SELECT ri.* FROM yhy_resource_item ri " +
"INNER JOIN yhy_catalog_item rci ON ri.catalog_item_id = rci.id " +
"WHERE rci.category_tree_id = #{categoryTreeId} " +
"AND ri.deleted = 0 " +
"AND rci.deleted = 0 " +
"ORDER BY ri.id")
List<ResourceItemDO> selectByCategoryTreeId(@Param("categoryTreeId") Long categoryTreeId);
/**
* 根据工料机机类树节点ID和查询条件查询工料机列表支持模糊查询
*
* @param categoryTreeId 工料机机类树节点ID
* @param code 编码(模糊查询)
* @param name 名称(模糊查询)
* @param spec 型号规格(模糊查询)
* @return 工料机列表
*/
@Select("<script>" +
"SELECT ri.* FROM yhy_resource_item ri " +
"INNER JOIN yhy_catalog_item rci ON ri.catalog_item_id = rci.id " +
"WHERE rci.category_tree_id = #{categoryTreeId} " +
"AND ri.deleted = 0 " +
"AND rci.deleted = 0 " +
"<if test='code != null and code != \"\"'>" +
"AND ri.code LIKE CONCAT('%', #{code}, '%') " +
"</if>" +
"<if test='name != null and name != \"\"'>" +
"AND ri.name LIKE CONCAT('%', #{name}, '%') " +
"</if>" +
"<if test='spec != null and spec != \"\"'>" +
"AND ri.spec LIKE CONCAT('%', #{spec}, '%') " +
"</if>" +
"ORDER BY ri.id" +
"</script>")
List<ResourceItemDO> selectByCategoryTreeIdWithFilter(
@Param("categoryTreeId") Long categoryTreeId,
@Param("code") String code,
@Param("name") String name,
@Param("spec") String spec);
/**
* 批量查询工料机项根据ID列表
*
* @param ids ID列表
* @return 工料机项列表
*/
default List<ResourceItemDO> selectBatchIds(List<Long> ids) {
return selectList("id", ids);
}
/**
* 更新工料机的4个价格字段
*
* @param id 工料机ID
* @param taxExclBasePrice 除税基价
* @param taxInclBasePrice 含税基价
* @param taxExclCompilePrice 除税编制价
* @param taxInclCompilePrice 含税编制价
*/
@Update("UPDATE yhy_resource_item SET " +
"tax_excl_base_price = #{taxExclBasePrice}, " +
"tax_incl_base_price = #{taxInclBasePrice}, " +
"tax_excl_compile_price = #{taxExclCompilePrice}, " +
"tax_incl_compile_price = #{taxInclCompilePrice}, " +
"update_time = now() " +
"WHERE id = #{id} AND deleted = 0")
void updatePrices(@Param("id") Long id,
@Param("taxExclBasePrice") BigDecimal taxExclBasePrice,
@Param("taxInclBasePrice") BigDecimal taxInclBasePrice,
@Param("taxExclCompilePrice") BigDecimal taxExclCompilePrice,
@Param("taxInclCompilePrice") BigDecimal taxInclCompilePrice);
}

View File

@@ -1,8 +1,14 @@
package com.yhy.module.core.dal.mysql.resource;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.yhy.module.core.controller.admin.resource.vo.ResourceMergedPageReqVO;
import com.yhy.module.core.controller.admin.resource.vo.ResourceMergedRespVO;
import com.yhy.module.core.dal.dataobject.resource.ResourceMergedDO;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
/**
* 复合工料机 Mapper
@@ -11,4 +17,94 @@ import org.apache.ibatis.annotations.Mapper;
*/
@Mapper
public interface ResourceMergedMapper extends BaseMapperX<ResourceMergedDO> {
/**
* 根据ID查询复合工料机JOIN 第四层数据)
*
* @param id 主键
* @return 复合工料机(包含第四层信息)
*/
@Select("SELECT " +
" rm.id, rm.tenant_id, rm.merged_id, rm.source_id, rm.region_code, " +
" rm.quota_consumption, rm.tax_excl_market_price, " +
" rm.creator, rm.create_time, rm.updater, rm.update_time, " +
" ri.code, ri.name, ri.unit, ri.spec, " +
" ri.catalog_item_id, ri.category_id, ri.tax_rate, " +
" ri.tax_excl_base_price, ri.tax_incl_base_price, " +
" ri.tax_excl_compile_price, ri.tax_incl_compile_price, " +
" ri.calc_base, " +
" rc.name AS category_name, " +
" ROUND(COALESCE(ri.tax_excl_base_price, 0) * COALESCE(rm.quota_consumption, 0) / 100, 4) AS tax_excl_base_total, " +
" ROUND(COALESCE(ri.tax_incl_base_price, 0) * COALESCE(rm.quota_consumption, 0) / 100, 4) AS tax_incl_base_total, " +
" ROUND(COALESCE(ri.tax_excl_compile_price, 0) * COALESCE(rm.quota_consumption, 0) / 100, 4) AS tax_excl_compile_total, " +
" ROUND(COALESCE(ri.tax_incl_compile_price, 0) * COALESCE(rm.quota_consumption, 0) / 100, 4) AS tax_incl_compile_total " +
"FROM yhy_resource_merged rm " +
"LEFT JOIN yhy_resource_item ri ON rm.source_id = ri.id AND ri.deleted = 0 " +
"LEFT JOIN yhy_resource_category rc ON ri.category_id = rc.id AND rc.deleted = 0 " +
"WHERE rm.id = #{id} AND rm.deleted = 0")
ResourceMergedRespVO selectByIdWithDetails(@Param("id") Long id);
/**
* 查询复合工料机分页JOIN 第四层数据)
*
* @param pageReqVO 分页查询条件
* @return 复合工料机列表(包含第四层信息)
*/
@Select("<script>" +
"SELECT " +
" rm.id, rm.tenant_id, rm.merged_id, rm.source_id, rm.region_code, " +
" rm.quota_consumption, rm.tax_excl_market_price, " +
" rm.creator, rm.create_time, rm.updater, rm.update_time, " +
" ri.code, ri.name, ri.unit, ri.spec, " +
" ri.catalog_item_id, ri.category_id, ri.tax_rate, " +
" ri.tax_excl_base_price, ri.tax_incl_base_price, " +
" ri.tax_excl_compile_price, ri.tax_incl_compile_price, " +
" ri.calc_base, " +
" rc.name AS category_name, " +
" ROUND(COALESCE(ri.tax_excl_base_price, 0) * COALESCE(rm.quota_consumption, 0) / 100, 4) AS tax_excl_base_total, " +
" ROUND(COALESCE(ri.tax_incl_base_price, 0) * COALESCE(rm.quota_consumption, 0) / 100, 4) AS tax_incl_base_total, " +
" ROUND(COALESCE(ri.tax_excl_compile_price, 0) * COALESCE(rm.quota_consumption, 0) / 100, 4) AS tax_excl_compile_total, " +
" ROUND(COALESCE(ri.tax_incl_compile_price, 0) * COALESCE(rm.quota_consumption, 0) / 100, 4) AS tax_incl_compile_total " +
"FROM yhy_resource_merged rm " +
"LEFT JOIN yhy_resource_item ri ON rm.source_id = ri.id AND ri.deleted = 0 " +
"LEFT JOIN yhy_resource_category rc ON ri.category_id = rc.id AND rc.deleted = 0 " +
"WHERE rm.deleted = 0 " +
"<if test='pageReqVO.mergedId != null'>" +
" AND rm.merged_id = #{pageReqVO.mergedId} " +
"</if>" +
"<if test='pageReqVO.sourceId != null'>" +
" AND rm.source_id = #{pageReqVO.sourceId} " +
"</if>" +
"<if test='pageReqVO.regionCode != null and pageReqVO.regionCode != \"\"'>" +
" AND rm.region_code = #{pageReqVO.regionCode} " +
"</if>" +
"ORDER BY rm.merged_id ASC, rm.source_id ASC, rm.region_code ASC " +
"LIMIT #{pageReqVO.pageSize} OFFSET #{offset}" +
"</script>")
List<ResourceMergedRespVO> selectPageWithDetails(@Param("pageReqVO") ResourceMergedPageReqVO pageReqVO,
@Param("offset") int offset);
/**
* 查询复合工料机总数
*
* @param pageReqVO 查询条件
* @return 总数
*/
default Long selectCountWithDetails(ResourceMergedPageReqVO pageReqVO) {
return selectCount(new LambdaQueryWrapperX<ResourceMergedDO>()
.eqIfPresent(ResourceMergedDO::getMergedId, pageReqVO.getMergedId())
.eqIfPresent(ResourceMergedDO::getSourceId, pageReqVO.getSourceId())
.eqIfPresent(ResourceMergedDO::getRegionCode, pageReqVO.getRegionCode()));
}
/**
* 查询指定 merged_id 的所有第五层数据
*
* @param mergedId 复合工料机ID
* @return 第五层数据列表
*/
default List<ResourceMergedDO> selectByMergedId(Long mergedId) {
return selectList(new LambdaQueryWrapperX<ResourceMergedDO>()
.eq(ResourceMergedDO::getMergedId, mergedId));
}
}

View File

@@ -23,147 +23,193 @@ public interface ErrorCodeConstants {
// ========== 工料机机类树模块 1-010-004-000 ==========
ErrorCode RESOURCE_CATEGORY_TREE_NOT_EXISTS = new ErrorCode(1_010_004_000, "工料机机类树节点不存在");
ErrorCode RESOURCE_CATEGORY_TREE_NOT_TYPE = new ErrorCode(1_010_004_001, "该节点不是工程类型节点");
ErrorCode RESOURCE_CATEGORY_TREE_NOT_SPECIALTY = new ErrorCode(1_010_004_002, "该节点不是工料机专业节点");
// ========== 定额目录模块 1-010-005-000 ==========
ErrorCode QUOTA_CATALOG_ITEM_NOT_EXISTS = new ErrorCode(1_010_005_000, "定额目录条目不存在");
ErrorCode QUOTA_CATALOG_ITEM_HAS_CHILDREN = new ErrorCode(1_010_005_001, "该节点存在子节点,无法删除");
ErrorCode QUOTA_CATALOG_ITEM_NOT_SPECIALTY = new ErrorCode(1_010_005_002, "该节点不是定额专业节点");
ErrorCode QUOTA_CATALOG_ITEM_ALREADY_BOUND = new ErrorCode(1_010_005_003, "该定额专业已绑定工料机专业,不可修改");
ErrorCode QUOTA_CATALOG_ITEM_CONTENT_NO_CHILDREN = new ErrorCode(1_010_005_004, "内容节点不允许添加子节点");
ErrorCode QUOTA_CATALOG_ITEM_CONTENT_NEED_PARENT = new ErrorCode(1_010_005_005, "内容节点必须有父节点");
ErrorCode QUOTA_CATALOG_ITEM_PARENT_NOT_DIRECTORY = new ErrorCode(1_010_005_006, "节点必须是目录节点");
ErrorCode QUOTA_CATALOG_ITEM_TYPE_MISMATCH = new ErrorCode(1_010_005_007, "节点类型不匹配");
ErrorCode QUOTA_CATALOG_ITEM_NOT_SAME_LEVEL = new ErrorCode(1_010_005_003, "两个节点不在同一层级,无法交换排序");
ErrorCode QUOTA_CATALOG_ITEM_ALREADY_BOUND = new ErrorCode(1_010_005_004, "该定额专业已绑定工料机专业,无法重复绑定");
ErrorCode QUOTA_CATALOG_ITEM_CONTENT_NO_CHILDREN = new ErrorCode(1_010_005_005, "内容节点不允许添加子节点");
ErrorCode QUOTA_CATALOG_ITEM_CONTENT_NEED_PARENT = new ErrorCode(1_010_005_006, "内容节点必须有父节点");
ErrorCode QUOTA_CATALOG_ITEM_PARENT_NOT_DIRECTORY = new ErrorCode(1_010_005_007, "节点必须是目录节点");
ErrorCode QUOTA_CATALOG_ITEM_TYPE_MISMATCH = new ErrorCode(1_010_005_008, "节点类型不匹配");
ErrorCode QUOTA_CATALOG_ITEM_PARENT_NOT_EXISTS = new ErrorCode(1_010_005_009, "父节点不存在");
ErrorCode QUOTA_CATALOG_ITEM_SPECIALTY_NOT_FOUND = new ErrorCode(1_010_005_010, "未找到定额专业节点");
// ========== 定额子目模块 1-010-006-000 ==========
ErrorCode QUOTA_ITEM_NOT_EXISTS = new ErrorCode(1_010_006_000, "定额子目不存在");
ErrorCode QUOTA_ITEM_HAS_RESOURCES = new ErrorCode(1_010_006_001, "定额子目存在工料机组成,无法删除");
ErrorCode QUOTA_CATALOG_ITEM_NOT_CONTENT = new ErrorCode(1_010_006_002, "只有内容节点才能添加定额子目");
ErrorCode QUOTA_SPECIALTY_NOT_BOUND = new ErrorCode(1_010_006_003, "定额专业尚未绑定工料机专业");
ErrorCode QUOTA_SPECIALTY_NOT_FOUND = new ErrorCode(1_010_006_004, "未找到定额专业节点");
// ========== 定额子目模块 1-010-006-000 ==========
ErrorCode QUOTA_CATALOG_TREE_NOT_EXISTS = new ErrorCode(1_010_006_000, "定额子目树节点不存在");
ErrorCode QUOTA_CATALOG_TREE_HAS_CHILDREN = new ErrorCode(1_010_006_001, "节点存在子节点,无法删除");
ErrorCode QUOTA_CATALOG_TREE_PARENT_NOT_EXISTS = new ErrorCode(1_010_006_002, "父节点不存在");
ErrorCode QUOTA_CATALOG_TREE_PARENT_NOT_ALLOW_CHILDREN = new ErrorCode(1_010_006_003, "父节点不允许添加子节点");
ErrorCode QUOTA_CATALOG_TREE_NOT_SAME_LEVEL = new ErrorCode(1_010_006_004, "两个节点不在同一层级");
// ========== 定额工料机组成模块 1-010-007-000 ==========
ErrorCode QUOTA_RESOURCE_NOT_EXISTS = new ErrorCode(1_010_007_000, "定额工料机组成不存在");
ErrorCode QUOTA_RESOURCE_OUT_OF_SCOPE = new ErrorCode(1_010_007_001, "工料机不在定额专业的数据范围内");
// ========== 定额子目模块 1-010-007-000 ==========
ErrorCode QUOTA_ITEM_NOT_EXISTS = new ErrorCode(1_010_007_000, "定额子目不存在");
ErrorCode QUOTA_ITEM_HAS_RESOURCES = new ErrorCode(1_010_007_001, "定额子目存在工料机组成,无法删除");
ErrorCode QUOTA_CATALOG_ITEM_NOT_CONTENT = new ErrorCode(1_010_007_002, "只有内容节点才能添加定额子目");
ErrorCode QUOTA_SPECIALTY_NOT_BOUND = new ErrorCode(1_010_007_003, "定额专业尚未绑定工料机专业");
ErrorCode QUOTA_SPECIALTY_NOT_FOUND = new ErrorCode(1_010_007_004, "未找到定额专业节点");
// ========== 定额工料机组成模块 1-010-008-000 ==========
ErrorCode QUOTA_RESOURCE_NOT_EXISTS = new ErrorCode(1_010_008_000, "定额工料机组成不存在");
ErrorCode QUOTA_RESOURCE_OUT_OF_SCOPE = new ErrorCode(1_010_008_001, "该工料机不在定额专业的数据范围内");
ErrorCode RESOURCE_CATALOG_ITEM_NOT_EXISTS = new ErrorCode(1_010_007_002, "工料机目录条目不存在");
// ========== 定额费率项模块 1-010-008-000 ==========
ErrorCode QUOTA_RATE_ITEM_NOT_EXISTS = new ErrorCode(1_010_008_000, "定额费率项不存在");
ErrorCode QUOTA_RATE_ITEM_HAS_CHILDREN = new ErrorCode(1_010_008_001, "该费率项存在子节点,无法删除");
ErrorCode QUOTA_RATE_ITEM_LEVEL_EXCEED = new ErrorCode(1_010_008_002, "费率项层级不能超过3级");
ErrorCode QUOTA_RATE_ITEM_NOT_SAME_LEVEL = new ErrorCode(1_010_008_003, "只能在同级节点间交换排序");
ErrorCode QUOTA_RATE_ITEM_NOT_SAME_MODE = new ErrorCode(1_010_008_004, "只能在同一模式下交换排序");
ErrorCode QUOTA_RATE_ITEM_NOT_VALUE_NODE = new ErrorCode(1_010_008_005, "只有数值节点才能配置取值规则");
ErrorCode QUOTA_RATE_ITEM_PARENT_NOT_EXISTS = new ErrorCode(1_010_008_006, "父节点不存在");
ErrorCode QUOTA_RATE_ITEM_PARENT_NOT_SAME_MODE = new ErrorCode(1_010_008_007, "父节点不属于同一模式");
ErrorCode QUOTA_RATE_ITEM_PARENT_NOT_DIRECTORY = new ErrorCode(1_010_008_008, "父节点必须是目录节点");
ErrorCode QUOTA_CATALOG_ITEM_SPECIALTY_NOT_FOUND = new ErrorCode(1_010_008_009, "未找到定额专业节点");
ErrorCode QUOTA_RATE_ITEM_CATALOG_NOT_RATE_MODE = new ErrorCode(1_010_008_010, "catalogItemId 必须指向 rate_mode 类型的节点");
// ========== 定额费率项模块 1-010-009-000 ==========
ErrorCode QUOTA_RATE_ITEM_NOT_EXISTS = new ErrorCode(1_010_009_000, "定额费率项不存在");
ErrorCode QUOTA_RATE_ITEM_HAS_CHILDREN = new ErrorCode(1_010_009_001, "该费率项存在子节点,无法删除");
ErrorCode QUOTA_RATE_ITEM_LEVEL_EXCEED = new ErrorCode(1_010_009_002, "费率项层级不能超过3级");
ErrorCode QUOTA_RATE_ITEM_NOT_SAME_LEVEL = new ErrorCode(1_010_009_003, "只能在同级节点间交换排序");
ErrorCode QUOTA_RATE_ITEM_NOT_SAME_MODE = new ErrorCode(1_010_009_004, "只能在同一模式下交换排序");
ErrorCode QUOTA_RATE_ITEM_NOT_VALUE_NODE = new ErrorCode(1_010_009_005, "只有数值节点才能配置取值规则");
ErrorCode QUOTA_RATE_ITEM_PARENT_NOT_EXISTS = new ErrorCode(1_010_009_006, "父节点不存在");
ErrorCode QUOTA_RATE_ITEM_PARENT_NOT_SAME_MODE = new ErrorCode(1_010_009_007, "父节点不属于同一模式");
ErrorCode QUOTA_RATE_ITEM_PARENT_NOT_DIRECTORY = new ErrorCode(1_010_009_008, "父节点必须是目录节点");
ErrorCode QUOTA_RATE_ITEM_NOT_DIRECTORY_CANNOT_SET_EDITABLE = new ErrorCode(1_010_009_009, "只有目录节点才能设置填写属性");
ErrorCode QUOTA_RATE_ITEM_CATALOG_NOT_RATE_MODE = new ErrorCode(1_010_009_010, "catalogItemId 必须指向 rate_mode 类型的节点");
ErrorCode QUOTA_RATE_MODE_PARENT_REQUIRED = new ErrorCode(1_010_009_011, "创建费率模式节点必须指定父节点");
ErrorCode QUOTA_RATE_MODE_PARENT_NOT_SPECIALTY = new ErrorCode(1_010_009_012, "费率模式节点的父节点必须是定额专业节点");
// 阶梯规则验证错误码
ErrorCode QUOTA_RATE_TIER_SEQ_DUPLICATE = new ErrorCode(1_010_009_020, "阶梯规则序号 [{}] 重复");
ErrorCode QUOTA_RATE_TIER_THRESHOLD_INVALID = new ErrorCode(1_010_009_021, "阶梯规则 [{}] 的阈值必须为正数");
ErrorCode QUOTA_RATE_TIER_COMPARE_TYPE_INVALID = new ErrorCode(1_010_009_022, "阶梯规则 [{}] 的比较类型无效");
ErrorCode QUOTA_RATE_TIER_FIELD_VALUES_EMPTY = new ErrorCode(1_010_009_023, "阶梯规则 [{}] 的字段值不能为空");
ErrorCode QUOTA_RATE_TIER_THRESHOLD_NOT_ASCENDING = new ErrorCode(1_010_009_024, "阶梯规则 [{}] 和 [{}] 的阈值必须递增");
ErrorCode QUOTA_RATE_TIER_COMPARE_TYPE_MIXED = new ErrorCode(1_010_009_025, "阶梯规则 [{}] 和 [{}] 不能混用不同的比较类型(小于等于/小于 与 大于等于/大于)");
// 增量规则验证错误码
ErrorCode QUOTA_RATE_INCREMENT_SEQ_DUPLICATE = new ErrorCode(1_010_009_030, "增量规则序号 [{}] 重复");
ErrorCode QUOTA_RATE_INCREMENT_BASE_THRESHOLD_INVALID = new ErrorCode(1_010_009_031, "增量规则 [{}] 的基准阈值必须为正数");
ErrorCode QUOTA_RATE_INCREMENT_STEP_INVALID = new ErrorCode(1_010_009_032, "增量规则 [{}] 的步长必须为正数");
ErrorCode QUOTA_RATE_INCREMENT_FIELD_INCREMENTS_EMPTY = new ErrorCode(1_010_009_033, "增量规则 [{}] 的字段增量不能为空");
ErrorCode QUOTA_RATE_INCREMENT_BASE_THRESHOLD_NOT_ASCENDING = new ErrorCode(1_010_009_034, "增量规则 [{}] 和 [{}] 的基准阈值必须递增");
// ========== 定额费率字段模块 1-010-009-000 ==========
ErrorCode QUOTA_RATE_FIELD_NOT_EXISTS = new ErrorCode(1_010_009_000, "定额费率字段不存在");
ErrorCode QUOTA_RATE_FIELD_BINDING_OUT_OF_RANGE = new ErrorCode(1_010_009_001, "绑定的节点不在当前定额专业范围内");
// ========== 定额费率字段模块 1-010-010-000 ==========
ErrorCode QUOTA_RATE_FIELD_NOT_EXISTS = new ErrorCode(1_010_010_000, "定额费率字段不存在");
ErrorCode QUOTA_RATE_FIELD_BINDING_OUT_OF_RANGE = new ErrorCode(1_010_010_001, "绑定的节点不在当前定额专业范围内");
ErrorCode QUOTA_RATE_FIELD_NODE_ALREADY_BOUND = new ErrorCode(1_010_010_002, "该节点已被其他虚拟字段绑定");
// ========== 定额取费项模块 1-010-010-000 ==========
ErrorCode QUOTA_FEE_ITEM_NOT_EXISTS = new ErrorCode(1_010_010_000, "定额取费项不存在");
ErrorCode QUOTA_FEE_ITEM_CATALOG_NOT_RATE_MODE = new ErrorCode(1_010_010_001, "catalogItemId 必须指向 rate_mode 类型的节点");
ErrorCode QUOTA_FEE_ITEM_CUSTOM_CODE_DUPLICATE = new ErrorCode(1_010_010_002, "自定义序号 [{}] 已存在");
ErrorCode QUOTA_FEE_ITEM_NOT_SAME_CATALOG = new ErrorCode(1_010_010_003, "只能在同一模式下交换排序");
ErrorCode QUOTA_FEE_CALC_BASE_FORMULA_EMPTY = new ErrorCode(1_010_010_004, "计算基数公式不能为空");
ErrorCode QUOTA_FEE_CALC_BASE_VARIABLES_EMPTY = new ErrorCode(1_010_010_005, "计算基数变量不能为空");
// ========== 定额费率字段标签模块 1-010-010-100 ==========
ErrorCode QUOTA_RATE_FIELD_LABEL_NOT_EXISTS = new ErrorCode(1_010_010_100, "定额费率字段标签不存在");
ErrorCode QUOTA_RATE_FIELD_LABEL_NAME_DUPLICATE = new ErrorCode(1_010_010_101, "字段标签名称已存在");
ErrorCode QUOTA_RATE_FIELD_LABEL_IN_USE = new ErrorCode(1_010_010_102, "字段标签正在使用中,无法删除");
ErrorCode QUOTA_RATE_FIELD_LABEL_NOT_SAME_MODE = new ErrorCode(1_010_010_103, "两个标签不属于同一模式节点");
// ========== 定额取费项模块 1-010-011-000 ==========
ErrorCode QUOTA_FEE_ITEM_NOT_EXISTS = new ErrorCode(1_010_011_000, "定额取费项不存在");
ErrorCode QUOTA_FEE_ITEM_CATALOG_NOT_RATE_MODE = new ErrorCode(1_010_011_001, "catalogItemId 必须指向 rate_mode 类型的节点");
ErrorCode QUOTA_FEE_ITEM_CUSTOM_CODE_DUPLICATE = new ErrorCode(1_010_011_002, "自定义序号 [{}] 已存在");
ErrorCode QUOTA_FEE_ITEM_NOT_SAME_CATALOG = new ErrorCode(1_010_011_003, "只能在同一模式下交换排序");
ErrorCode QUOTA_FEE_CALC_BASE_FORMULA_EMPTY = new ErrorCode(1_010_011_004, "计算基数公式不能为空");
ErrorCode QUOTA_FEE_CALC_BASE_VARIABLES_EMPTY = new ErrorCode(1_010_011_005, "计算基数变量不能为空");
ErrorCode QUOTA_FEE_CALC_BASE_INVALID_PRICE_CODE = new ErrorCode(1_010_010_006, "无效的价格代码: {}");
ErrorCode QUOTA_FEE_CALC_BASE_FORMULA_BRACKET_MISMATCH = new ErrorCode(1_010_010_007, "公式括号不匹配");
ErrorCode QUOTA_FEE_CALC_BASE_FORMULA_INVALID_CHAR = new ErrorCode(1_010_010_008, "公式包含非法字符");
ErrorCode QUOTA_FEE_CALC_BASE_FORMULA_INVALID_CHAR = new ErrorCode(1_010_010_008, "公式包含非法字符: {}");
// ========== 定额调整设置模块 1-010-011-000 ==========
ErrorCode QUOTA_ADJUSTMENT_NOT_EXISTS = new ErrorCode(1_010_011_000, "定额调整设置不存在");
ErrorCode QUOTA_ADJUSTMENT_NOT_SAME_QUOTA_ITEM = new ErrorCode(1_010_011_001, "只能在同一定额子目下交换排序");
ErrorCode QUOTA_ADJUSTMENT_TYPE_INVALID = new ErrorCode(1_010_011_002, "无效的调整类型");
ErrorCode QUOTA_ADJUSTMENT_RULES_INVALID = new ErrorCode(1_010_011_003, "调整规则格式不正确");
ErrorCode QUOTA_ADJUSTMENT_MATERIAL_CODE_DUPLICATE = new ErrorCode(1_010_011_004, "工料机编码 [{}] 重复");
ErrorCode QUOTA_ADJUSTMENT_CATEGORY_DUPLICATE = new ErrorCode(1_010_011_005, "类别ID [{}] 重复");
ErrorCode QUOTA_ADJUSTMENT_COEFFICIENT_INVALID = new ErrorCode(1_010_011_006, "系数必须大于0");
ErrorCode QUOTA_ADJUSTMENT_MIN_MAX_INVALID = new ErrorCode(1_010_011_007, "最小值必须小于最大值");
ErrorCode QUOTA_ADJUSTMENT_DENOMINATOR_ZERO = new ErrorCode(1_010_011_008, "分母不能为0");
ErrorCode QUOTA_ADJUSTMENT_BASE_VALUE_OUT_OF_RANGE = new ErrorCode(1_010_011_009, "基础值必须在最小值和最大值之间");
ErrorCode QUOTA_ADJUSTMENT_ROUNDING_RULE_INVALID = new ErrorCode(1_010_011_010, "无效的取值规则");
ErrorCode QUOTA_ADJUSTMENT_INPUT_VALUE_OUT_OF_RANGE = new ErrorCode(1_010_011_011, "输入值 [{}] 超出范围 [{}, {}]");
ErrorCode QUOTA_ADJUSTMENT_RESOURCE_DUPLICATE = new ErrorCode(1_010_011_012, "工料机ID [{}] 重复");
// ========== 定额调整设置模块(第五层)1-010-011-000 ==========
ErrorCode QUOTA_ADJUSTMENT_SETTING_NOT_EXISTS = new ErrorCode(1_010_011_000, "定额调整设置不存在");
ErrorCode QUOTA_ADJUSTMENT_SETTING_QUOTA_ITEM_NOT_EXISTS = new ErrorCode(1_010_011_001, "定额子目不存在");
ErrorCode QUOTA_ADJUSTMENT_SETTING_NAME_DUPLICATE = new ErrorCode(1_010_011_002, "调整设置名称重复");
ErrorCode QUOTA_ADJUSTMENT_SETTING_TYPE_INVALID = new ErrorCode(1_010_011_003, "调整类型无效");
ErrorCode QUOTA_ADJUSTMENT_SETTING_RULES_INVALID = new ErrorCode(1_010_011_004, "调整规则格式无效");
ErrorCode QUOTA_ADJUSTMENT_SETTING_HAS_DETAILS = new ErrorCode(1_010_011_005, "调整设置下存在明细,无法删除");
ErrorCode QUOTA_ADJUSTMENT_SETTING_REFERENCED = new ErrorCode(1_010_011_006, "调整设置被其他明细引用,无法删除");
ErrorCode QUOTA_ADJUSTMENT_SETTING_NOT_SAME_QUOTA_ITEM = new ErrorCode(1_010_011_007, "只能在同一定额子目下交换排序");
// ========== 清单配置目录树模块 1-010-012-000 ==========
ErrorCode BOQ_CATALOG_ITEM_NOT_EXISTS = new ErrorCode(1_010_012_000, "清单配置目录树节点不存在");
ErrorCode BOQ_CATALOG_ITEM_CODE_DUPLICATE = new ErrorCode(1_010_012_001, "编码 [{}] 已存在");
ErrorCode BOQ_CATALOG_ITEM_INVALID_NODE_TYPE = new ErrorCode(1_010_012_002, "无效的节点类型");
ErrorCode BOQ_CATALOG_ITEM_SPECIALTY_LOCKED = new ErrorCode(1_010_012_003, "该清单专业已绑定,不可修改或删除");
ErrorCode BOQ_CATALOG_ITEM_HAS_CHILDREN = new ErrorCode(1_010_012_004, "该节点存在子节点,无法删除");
ErrorCode BOQ_CATALOG_ITEM_NOT_SPECIALTY = new ErrorCode(1_010_012_005, "该节点不是清单专业节点");
ErrorCode BOQ_CATALOG_ITEM_ALREADY_BOUND = new ErrorCode(1_010_012_006, "该清单专业已绑定定额基价");
ErrorCode BOQ_CATALOG_ITEM_QUOTA_NOT_FIRST_LEVEL = new ErrorCode(1_010_012_007, "只能绑定定额基价第一层节点");
ErrorCode BOQ_CATALOG_ITEM_PARENT_NOT_EXISTS = new ErrorCode(1_010_012_008, "父节点不存在");
ErrorCode BOQ_CATALOG_ITEM_NOT_SAME_LEVEL = new ErrorCode(1_010_012_009, "只能在同级节点间交换排序");
ErrorCode BOQ_CATALOG_ITEM_NOT_BOUND_QUOTA = new ErrorCode(1_010_012_010, "该清单专业尚未绑定定额基价");
// ========== 定额调整明细模块(第六层)1-010-012-000 ==========
ErrorCode QUOTA_ADJUSTMENT_DETAIL_NOT_EXISTS = new ErrorCode(1_010_012_000, "定额调整明细不存在");
ErrorCode QUOTA_ADJUSTMENT_DETAIL_SETTING_NOT_EXISTS = new ErrorCode(1_010_012_001, "调整设置不存在");
ErrorCode QUOTA_ADJUSTMENT_DETAIL_CODE_NOT_EXISTS = new ErrorCode(1_010_012_002, "引用的调整设置不存在");
ErrorCode QUOTA_ADJUSTMENT_DETAIL_CODE_NOT_SAME_SPECIALTY = new ErrorCode(1_010_012_003, "引用的调整设置不在同一定额专业");
ErrorCode QUOTA_ADJUSTMENT_DETAIL_CODE_CIRCULAR = new ErrorCode(1_010_012_004, "调整明细引用形成循环");
ErrorCode QUOTA_ADJUSTMENT_DETAIL_NOT_SAME_SETTING = new ErrorCode(1_010_012_005, "只能在同一调整设置下交换排序");
// ========== 清单树模块 1-010-013-000 ==========
ErrorCode BOQ_ITEM_TREE_NOT_EXISTS = new ErrorCode(1_010_013_000, "清单树节点不存在");
ErrorCode BOQ_ITEM_TREE_CODE_DUPLICATE = new ErrorCode(1_010_013_001, "编码 [{}] 已存在");
ErrorCode BOQ_ITEM_TREE_HAS_CHILDREN = new ErrorCode(1_010_013_002, "该节点存在子节点,无法删除");
ErrorCode BOQ_ITEM_TREE_PARENT_NOT_EXISTS = new ErrorCode(1_010_013_003, "父节点不存在");
ErrorCode BOQ_ITEM_TREE_NOT_SAME_LEVEL = new ErrorCode(1_010_013_004, "只能在同级节点间交换排序");
// ========== 清单配置目录树模块 1-010-013-000 ==========
ErrorCode BOQ_CATALOG_ITEM_NOT_EXISTS = new ErrorCode(1_010_013_000, "清单配置目录树节点不存在");
ErrorCode BOQ_CATALOG_ITEM_CODE_DUPLICATE = new ErrorCode(1_010_013_001, "编码 [{}] 已存在");
ErrorCode BOQ_CATALOG_ITEM_INVALID_NODE_TYPE = new ErrorCode(1_010_013_002, "无效的节点类型");
ErrorCode BOQ_CATALOG_ITEM_SPECIALTY_LOCKED = new ErrorCode(1_010_013_003, "该清单专业已绑定,不可修改或删除");
ErrorCode BOQ_CATALOG_ITEM_HAS_CHILDREN = new ErrorCode(1_010_013_004, "该节点存在子节点,无法删除");
ErrorCode BOQ_CATALOG_ITEM_NOT_SPECIALTY = new ErrorCode(1_010_013_005, "该节点不是清单专业节点");
ErrorCode BOQ_CATALOG_ITEM_ALREADY_BOUND = new ErrorCode(1_010_013_006, "该清单专业已绑定定额基价");
ErrorCode BOQ_CATALOG_ITEM_QUOTA_NOT_FIRST_LEVEL = new ErrorCode(1_010_013_007, "只能绑定定额基价第一层节点");
ErrorCode BOQ_CATALOG_ITEM_PARENT_NOT_EXISTS = new ErrorCode(1_010_013_008, "父节点不存在");
ErrorCode BOQ_CATALOG_ITEM_NOT_SAME_LEVEL = new ErrorCode(1_010_013_009, "只能在同级节点间交换排序");
ErrorCode BOQ_CATALOG_ITEM_NOT_BOUND_QUOTA = new ErrorCode(1_010_013_010, "该清单专业尚未绑定定额基价");
// ========== 清单项模块 1-010-014-000 ==========
ErrorCode BOQ_SUB_ITEM_NOT_EXISTS = new ErrorCode(1_010_014_000, "清单项不存在");
ErrorCode BOQ_SUB_ITEM_CODE_DUPLICATE = new ErrorCode(1_010_014_001, "编码 [{}] 已存在");
ErrorCode BOQ_SUB_ITEM_NOT_SAME_TREE = new ErrorCode(1_010_014_002, "只能在同一清单项树下交换排序");
// ========== 清单项模块 1-010-014-000 ==========
ErrorCode BOQ_ITEM_TREE_NOT_EXISTS = new ErrorCode(1_010_014_000, "清单项树节点不存在");
ErrorCode BOQ_ITEM_TREE_CODE_DUPLICATE = new ErrorCode(1_010_014_001, "编码 [{}] 已存在");
ErrorCode BOQ_ITEM_TREE_HAS_CHILDREN = new ErrorCode(1_010_014_002, "该节点存在子节点,无法删除");
ErrorCode BOQ_ITEM_TREE_PARENT_NOT_EXISTS = new ErrorCode(1_010_014_003, "父节点不存在");
ErrorCode BOQ_ITEM_TREE_NOT_SAME_LEVEL = new ErrorCode(1_010_014_004, "只能在同级节点间交换排序");
// ========== 清单明细树模块 1-010-015-000 ==========
ErrorCode BOQ_DETAIL_TREE_NOT_EXISTS = new ErrorCode(1_010_015_000, "清单明细树节点不存在");
ErrorCode BOQ_DETAIL_TREE_CODE_DUPLICATE = new ErrorCode(1_010_015_001, "编码 [{}] 已存在");
ErrorCode BOQ_DETAIL_TREE_HAS_CHILDREN = new ErrorCode(1_010_015_002, "该节点存在子节点,无法删除");
ErrorCode BOQ_DETAIL_TREE_PARENT_NOT_DIRECTORY = new ErrorCode(1_010_015_003, "父节点必须是目录类型");
ErrorCode BOQ_DETAIL_TREE_INVALID_NODE_TYPE = new ErrorCode(1_010_015_004, "无效的节点类型");
ErrorCode BOQ_DETAIL_TREE_CONTENT_NEED_QUOTA = new ErrorCode(1_010_015_005, "内容节点必须关联定额");
ErrorCode BOQ_DETAIL_TREE_DIRECTORY_NO_QUOTA = new ErrorCode(1_010_015_006, "目录节点不能关联定额");
ErrorCode BOQ_DETAIL_TREE_QUOTA_NOT_IN_RANGE = new ErrorCode(1_010_015_007, "该定额不在绑定的定额专业范围内");
ErrorCode BOQ_DETAIL_TREE_QUOTA_NOT_CONTENT_TYPE = new ErrorCode(1_010_015_008, "只能关联定额基价第三层的内容节点");
ErrorCode BOQ_DETAIL_TREE_NOT_SAME_LEVEL = new ErrorCode(1_010_015_009, "只能在同级节点间交换排序");
// ========== 清单子项模块 1-010-015-000 ==========
ErrorCode BOQ_SUB_ITEM_NOT_EXISTS = new ErrorCode(1_010_015_000, "清单子项不存在");
ErrorCode BOQ_SUB_ITEM_CODE_DUPLICATE = new ErrorCode(1_010_015_001, "编码 [{}] 已存在");
ErrorCode BOQ_SUB_ITEM_NOT_SAME_TREE = new ErrorCode(1_010_015_002, "只能在同一清单项树下交换排序");
// ========== 信息价树结构模块 1-010-016-000 ==========
ErrorCode INFO_PRICE_TREE_NOT_EXISTS = new ErrorCode(1_010_016_000, "信息价树节点不存在");
ErrorCode INFO_PRICE_TREE_CODE_DUPLICATE = new ErrorCode(1_010_016_001, "编码 [{}] 已存在");
ErrorCode INFO_PRICE_TREE_HAS_CHILDREN = new ErrorCode(1_010_016_002, "该节点存在子节点,无法删除");
ErrorCode INFO_PRICE_TREE_HAS_BOOKS = new ErrorCode(1_010_016_003, "节点存在信息价册,无法删除");
ErrorCode INFO_PRICE_TREE_PARENT_NOT_EXISTS = new ErrorCode(1_010_016_004, "父节点不存在");
ErrorCode INFO_PRICE_TREE_NOT_SAME_LEVEL = new ErrorCode(1_010_016_005, "只能在同级节点间交换排序");
ErrorCode INFO_PRICE_TREE_NOT_SAME_ENUM_TYPE = new ErrorCode(1_010_016_006, "只能在同一枚举类型下交换排序");
ErrorCode INFO_PRICE_TREE_INVALID_ENUM_TYPE = new ErrorCode(1_010_016_007, "无效的枚举类型");
// ========== 清单明细树模块 1-010-016-000 ==========
ErrorCode BOQ_DETAIL_TREE_NOT_EXISTS = new ErrorCode(1_010_016_000, "清单明细树节点不存在");
ErrorCode BOQ_DETAIL_TREE_CODE_DUPLICATE = new ErrorCode(1_010_016_001, "编码 [{}] 已存在");
ErrorCode BOQ_DETAIL_TREE_HAS_CHILDREN = new ErrorCode(1_010_016_002, "该节点存在子节点,无法删除");
ErrorCode BOQ_DETAIL_TREE_PARENT_NOT_DIRECTORY = new ErrorCode(1_010_016_003, "节点必须是目录类型");
ErrorCode BOQ_DETAIL_TREE_INVALID_NODE_TYPE = new ErrorCode(1_010_016_004, "无效的节点类型");
ErrorCode BOQ_DETAIL_TREE_CONTENT_NEED_QUOTA = new ErrorCode(1_010_016_005, "内容节点必须关联定额");
ErrorCode BOQ_DETAIL_TREE_DIRECTORY_NO_QUOTA = new ErrorCode(1_010_016_006, "目录节点不能关联定额");
ErrorCode BOQ_DETAIL_TREE_QUOTA_NOT_IN_RANGE = new ErrorCode(1_010_016_007, "该定额不在绑定的定额专业范围内");
ErrorCode BOQ_DETAIL_TREE_QUOTA_NOT_CONTENT_TYPE = new ErrorCode(1_010_016_008, "只能关联定额基价第三层的内容节点");
ErrorCode BOQ_DETAIL_TREE_NOT_SAME_LEVEL = new ErrorCode(1_010_016_009, "只能在同级节点间交换排序");
// ========== 信息价模块 1-010-017-000 ==========
ErrorCode INFO_PRICE_BOOK_NOT_EXISTS = new ErrorCode(1_010_017_000, "信息价不存在");
ErrorCode INFO_PRICE_BOOK_TIME_OVERLAP = new ErrorCode(1_010_017_001, "时间段与已有数据重叠");
ErrorCode INFO_PRICE_BOOK_TIME_INVALID = new ErrorCode(1_010_017_002, "结束时间必须大于等于开始时间");
ErrorCode INFO_PRICE_BOOK_INVALID_PUBLISH_STATUS = new ErrorCode(1_010_017_003, "无效的发布状态");
ErrorCode INFO_PRICE_BOOK_HAS_ITEMS = new ErrorCode(1_010_017_004, "该信息价册存在条目,无法删除");
// ========== 信息价树结构模块 1-010-017-000 ==========
ErrorCode INFO_PRICE_TREE_NOT_EXISTS = new ErrorCode(1_010_017_000, "信息价树节点不存在");
ErrorCode INFO_PRICE_TREE_CODE_DUPLICATE = new ErrorCode(1_010_017_001, "编码 [{}] 已存在");
ErrorCode INFO_PRICE_TREE_HAS_CHILDREN = new ErrorCode(1_010_017_002, "该节点存在子节点,无法删除");
ErrorCode INFO_PRICE_TREE_HAS_BOOKS = new ErrorCode(1_010_017_003, "该节点存在信息价册,无法删除");
ErrorCode INFO_PRICE_TREE_PARENT_NOT_EXISTS = new ErrorCode(1_010_017_004, "父节点不存在");
ErrorCode INFO_PRICE_TREE_NOT_SAME_LEVEL = new ErrorCode(1_010_017_005, "只能在同级节点间交换排序");
ErrorCode INFO_PRICE_TREE_NOT_SAME_ENUM_TYPE = new ErrorCode(1_010_017_006, "只能在同一枚举类型下交换排序");
ErrorCode INFO_PRICE_TREE_INVALID_ENUM_TYPE = new ErrorCode(1_010_017_007, "无效的枚举类型");
// ========== 信息价分类树模块 1-010-018-000 ==========
ErrorCode INFO_PRICE_CATEGORY_TREE_NOT_EXISTS = new ErrorCode(1_010_018_000, "信息价分类树节点不存在");
ErrorCode INFO_PRICE_CATEGORY_TREE_CODE_DUPLICATE = new ErrorCode(1_010_018_001, "编码 [{}] 已存在");
ErrorCode INFO_PRICE_CATEGORY_TREE_HAS_CHILDREN = new ErrorCode(1_010_018_002, "该节点存在子节点,无法删除");
ErrorCode INFO_PRICE_CATEGORY_TREE_HAS_RESOURCES = new ErrorCode(1_010_018_003, "该节点存在工料机信息,无法删除");
ErrorCode INFO_PRICE_CATEGORY_TREE_PARENT_NOT_EXISTS = new ErrorCode(1_010_018_004, "父节点不存在");
ErrorCode INFO_PRICE_CATEGORY_TREE_NOT_SAME_LEVEL = new ErrorCode(1_010_018_005, "只能在同级节点间交换排序");
ErrorCode INFO_PRICE_CATEGORY_TREE_CONTENT_NO_CHILDREN = new ErrorCode(1_010_018_006, "内容节点不允许添加子节点");
ErrorCode INFO_PRICE_CATEGORY_TREE_INVALID_NODE_TYPE = new ErrorCode(1_010_018_007, "无效的节点类型");
// ========== 信息价模块 1-010-018-000 ==========
ErrorCode INFO_PRICE_BOOK_NOT_EXISTS = new ErrorCode(1_010_018_000, "信息价不存在");
ErrorCode INFO_PRICE_BOOK_TIME_OVERLAP = new ErrorCode(1_010_018_001, "时间段与已有数据重叠");
ErrorCode INFO_PRICE_BOOK_TIME_INVALID = new ErrorCode(1_010_018_002, "结束时间必须大于等于开始时间");
ErrorCode INFO_PRICE_BOOK_INVALID_PUBLISH_STATUS = new ErrorCode(1_010_018_003, "无效的发布状态");
ErrorCode INFO_PRICE_BOOK_HAS_ITEMS = new ErrorCode(1_010_018_004, "该信息价册存在条目,无法删除");
// ========== 信息价工料机信息模块 1-010-019-000 ==========
ErrorCode INFO_PRICE_RESOURCE_NOT_EXISTS = new ErrorCode(1_010_019_000, "信息价工料机信息不存在");
ErrorCode INFO_PRICE_RESOURCE_CODE_DUPLICATE = new ErrorCode(1_010_019_001, "编码 [{}] 已存在");
ErrorCode INFO_PRICE_RESOURCE_ONLY_UNDER_CONTENT_NODE = new ErrorCode(1_010_019_002, "只有内容节点才能添加工料机信息");
ErrorCode INFO_PRICE_RESOURCE_HAS_PRICES = new ErrorCode(1_010_019_003, "该工料机信息存在价格历史,无法删除");
ErrorCode INFO_PRICE_RESOURCE_NOT_SAME_CATEGORY = new ErrorCode(1_010_019_004, "只能在同一分类节点下交换排序");
// ========== 信息价分类树模块 1-010-019-000 ==========
ErrorCode INFO_PRICE_CATEGORY_TREE_NOT_EXISTS = new ErrorCode(1_010_019_000, "信息价分类树节点不存在");
ErrorCode INFO_PRICE_CATEGORY_TREE_CODE_DUPLICATE = new ErrorCode(1_010_019_001, "编码 [{}] 已存在");
ErrorCode INFO_PRICE_CATEGORY_TREE_HAS_CHILDREN = new ErrorCode(1_010_019_002, "该节点存在子节点,无法删除");
ErrorCode INFO_PRICE_CATEGORY_TREE_HAS_RESOURCES = new ErrorCode(1_010_019_003, "节点存在工料机信息,无法删除");
ErrorCode INFO_PRICE_CATEGORY_TREE_PARENT_NOT_EXISTS = new ErrorCode(1_010_019_004, "父节点不存在");
ErrorCode INFO_PRICE_CATEGORY_TREE_NOT_SAME_LEVEL = new ErrorCode(1_010_019_005, "只能在同级节点间交换排序");
ErrorCode INFO_PRICE_CATEGORY_TREE_CONTENT_NO_CHILDREN = new ErrorCode(1_010_019_006, "内容节点不允许添加子节点");
ErrorCode INFO_PRICE_CATEGORY_TREE_INVALID_NODE_TYPE = new ErrorCode(1_010_019_007, "无效的节点类型");
// ========== 信息价工料机价格历史模块 1-010-020-000 ==========
ErrorCode INFO_PRICE_RESOURCE_PRICE_NOT_EXISTS = new ErrorCode(1_010_020_000, "信息价工料机价格历史不存在");
ErrorCode INFO_PRICE_RESOURCE_PRICE_TIME_OVERLAP = new ErrorCode(1_010_020_001, "时间段与已有数据重叠");
ErrorCode INFO_PRICE_RESOURCE_PRICE_TIME_INVALID = new ErrorCode(1_010_020_002, "结束时间必须大于等于开始时间");
ErrorCode INFO_PRICE_RESOURCE_PRICE_TIME_NOT_CONTINUOUS = new ErrorCode(1_010_020_003, "时间段必须与前一条记录连续,期望开始时间为 [{}]");
// ========== 信息价工料机信息模块 1-010-020-000 ==========
ErrorCode INFO_PRICE_RESOURCE_NOT_EXISTS = new ErrorCode(1_010_020_000, "信息价工料机信息不存在");
ErrorCode INFO_PRICE_RESOURCE_CODE_DUPLICATE = new ErrorCode(1_010_020_001, "编码 [{}] 已存在");
ErrorCode INFO_PRICE_RESOURCE_ONLY_UNDER_CONTENT_NODE = new ErrorCode(1_010_020_002, "只有内容节点才能添加工料机信息");
ErrorCode INFO_PRICE_RESOURCE_HAS_PRICES = new ErrorCode(1_010_020_003, "该工料机信息存在价格历史,无法删除");
ErrorCode INFO_PRICE_RESOURCE_NOT_SAME_CATEGORY = new ErrorCode(1_010_020_004, "只能在同一分类节点下交换排序");
// ========== 信息价工料机价格历史模块 1-010-021-000 ==========
ErrorCode INFO_PRICE_RESOURCE_PRICE_NOT_EXISTS = new ErrorCode(1_010_021_000, "信息价工料机价格历史不存在");
ErrorCode INFO_PRICE_RESOURCE_PRICE_TIME_OVERLAP = new ErrorCode(1_010_021_001, "时间段与已有数据重叠");
ErrorCode INFO_PRICE_RESOURCE_PRICE_TIME_INVALID = new ErrorCode(1_010_021_002, "结束时间必须大于等于开始时间");
ErrorCode INFO_PRICE_RESOURCE_PRICE_TIME_NOT_CONTINUOUS = new ErrorCode(1_010_021_003, "时间段必须与前一条记录连续,期望开始时间为 [{}]");
// ========== 复合工料机模块 1-010-021-000 ==========
ErrorCode RESOURCE_MERGED_NOT_EXISTS = new ErrorCode(1_010_021_000, "复合工料机不存在");
ErrorCode RESOURCE_MERGED_SOURCE_NOT_EXISTS = new ErrorCode(1_010_021_001, "复合工料机引用的数据源不存在");
ErrorCode RESOURCE_MERGED_CALC_BASE_INVALID = new ErrorCode(1_010_021_002, "计算基数配置无效");
ErrorCode RESOURCE_MERGED_CALC_BASE_CATEGORY_NOT_FOUND = new ErrorCode(1_010_021_003, "计算基数引用的类别在同组中未找到");
ErrorCode RESOURCE_MERGED_FORMULA_PARSE_ERROR = new ErrorCode(1_010_021_004, "公式解析失败");
ErrorCode RESOURCE_MERGED_SELF_REFERENCE = new ErrorCode(1_010_021_005, "不允许自己关联自己");
}

View File

@@ -1,41 +0,0 @@
package com.yhy.module.core.enums.quota;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 定额调整类型枚举
*/
@Getter
@AllArgsConstructor
public enum QuotaAdjustmentTypeEnum {
PERCENTAGE(1, "percentage", "百分比调整"),
FIXED_VALUE(2, "fixed_value", "固定值调整"),
FORMULA(3, "formula", "公式计算"),
CONDITIONAL(4, "conditional", "条件调整"),
MATERIAL_ADJUSTMENT(5, "material_adjustment", "增减材料消耗量"),
DYNAMIC_ADJUSTMENT(6, "dynamic_adjustment", "动态调整人才机消耗量"),
COEFFICIENT_ADJUSTMENT(7, "coefficient_adjustment", "调整人才机消耗量"),
DYNAMIC_MERGE_QUOTA(8, "dynamic_merge_quota", "动态合并定额");
private final Integer type;
private final String code;
private final String name;
public static QuotaAdjustmentTypeEnum valueOf(Integer type) {
return Arrays.stream(values())
.filter(e -> e.getType().equals(type))
.findFirst()
.orElse(null);
}
public static QuotaAdjustmentTypeEnum valueOfCode(String code) {
return Arrays.stream(values())
.filter(e -> e.getCode().equals(code))
.findFirst()
.orElse(null);
}
}

View File

@@ -0,0 +1,87 @@
package com.yhy.module.core.service.quota;
import com.yhy.module.core.controller.admin.quota.vo.QuotaAdjustmentCombinedRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaAdjustmentDetailSaveReqVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaAdjustmentDetailDO;
import com.yhy.module.core.dal.dataobject.quota.QuotaAdjustmentSettingDO;
import java.util.List;
import javax.validation.Valid;
/**
* 定额调整明细 Service 接口
*
* @author 芋道源码
*/
public interface QuotaAdjustmentDetailService {
/**
* 创建定额调整明细
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createQuotaAdjustmentDetail(@Valid QuotaAdjustmentDetailSaveReqVO createReqVO);
/**
* 更新定额调整明细
*
* @param updateReqVO 更新信息
*/
void updateQuotaAdjustmentDetail(@Valid QuotaAdjustmentDetailSaveReqVO updateReqVO);
/**
* 删除定额调整明细
*
* @param id 编号
*/
void deleteQuotaAdjustmentDetail(Long id);
/**
* 获得定额调整明细
*
* @param id 编号
* @return 定额调整明细
*/
QuotaAdjustmentDetailDO getQuotaAdjustmentDetail(Long id);
/**
* 获得定额调整明细列表按定额子目ID
*
* @param quotaItemId 定额子目ID
* @return 定额调整明细列表
*/
List<QuotaAdjustmentDetailDO> getQuotaAdjustmentDetailListByQuotaItem(Long quotaItemId);
/**
* 获得定额调整明细列表按调整设置ID
*
* @param adjustmentSettingId 调整设置ID
* @return 定额调整明细列表
*/
List<QuotaAdjustmentDetailDO> getQuotaAdjustmentDetailList(Long adjustmentSettingId);
/**
* 交换排序
*
* @param id1 第一个调整明细ID
* @param id2 第二个调整明细ID
*/
void swapSort(Long id1, Long id2);
/**
* 获取可引用的调整设置列表(同一定额专业)
*
* @param adjustmentSettingId 当前调整设置ID
* @return 可引用的调整设置列表
*/
List<QuotaAdjustmentSettingDO> getAvailableSettings(Long adjustmentSettingId);
/**
* 获取调整设置与明细的组合列表按定额子目ID
*
* @param quotaItemId 定额子目ID
* @return 调整设置与明细的组合列表
*/
List<QuotaAdjustmentCombinedRespVO> getCombinedList(Long quotaItemId);
}

View File

@@ -1,178 +0,0 @@
package com.yhy.module.core.service.quota;
import com.yhy.module.core.controller.admin.quota.vo.QuotaAdjustmentSaveReqVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaAdjustmentDO;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
* 定额调整设置 Service 接口
*/
public interface QuotaAdjustmentService {
/**
* 创建定额调整设置
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createQuotaAdjustment(@Valid QuotaAdjustmentSaveReqVO createReqVO);
/**
* 更新定额调整设置
*
* @param updateReqVO 更新信息
*/
void updateQuotaAdjustment(@Valid QuotaAdjustmentSaveReqVO updateReqVO);
/**
* 删除定额调整设置
*
* @param id 编号
*/
void deleteQuotaAdjustment(Long id);
/**
* 获得定额调整设置
*
* @param id 编号
* @return 定额调整设置
*/
QuotaAdjustmentDO getQuotaAdjustment(Long id);
/**
* 获得定额调整设置列表
*
* @param quotaItemId 定额子目ID
* @return 定额调整设置列表
*/
List<QuotaAdjustmentDO> getQuotaAdjustmentList(Long quotaItemId);
/**
* 交换排序
*
* @param id1 调整设置ID1
* @param id2 调整设置ID2
*/
void swapSort(Long id1, Long id2);
/**
* 计算调整后的消耗量
*
* @param quotaItemId 定额子目ID
* @param originalConsumeQty 原始消耗量
* @return 调整后的消耗量
*/
BigDecimal calculateAdjustedConsumeQty(Long quotaItemId, BigDecimal originalConsumeQty);
/**
* 计算指定工料机的调整后消耗量
*
* @param quotaItemId 定额子目ID
* @param resourceCode 工料机编码
* @param originalDosage 原始定额消耗量
* @return 调整后的消耗量
*/
BigDecimal calculateAdjustedDosage(Long quotaItemId, String resourceCode, BigDecimal originalDosage);
/**
* 保存材料调整明细
*
* @param adjustmentId 调整设置ID
* @param items 材料明细列表
*/
void saveMaterialItems(Long adjustmentId, List<Map<String, Object>> items);
/**
* 获取材料调整明细
*
* @param adjustmentId 调整设置ID
* @return 材料明细列表
*/
List<Map<String, Object>> getMaterialItems(Long adjustmentId);
/**
* 获取可配置的类别列表
*
* @param quotaItemId 定额子目ID
* @return 类别列表
*/
List<Map<String, Object>> getAvailableCategories(Long quotaItemId);
/**
* 保存动态调整配置
*
* @param adjustmentId 调整设置ID
* @param categories 类别配置列表
*/
void saveDynamicConfig(Long adjustmentId, List<Map<String, Object>> categories);
/**
* 获取动态调整配置
*
* @param adjustmentId 调整设置ID
* @return 类别配置列表
*/
List<Map<String, Object>> getDynamicConfig(Long adjustmentId);
/**
* 计算动态调整结果
*
* @param adjustmentId 调整设置ID
* @param inputValues 输入值映射类别ID: 输入值)
* @return 调整结果映射类别ID: 调整结果)
*/
Map<String, BigDecimal> calculateDynamic(Long adjustmentId, Map<String, BigDecimal> inputValues);
/**
* 保存系数调整配置
*
* @param adjustmentId 调整设置ID
* @param categories 类别配置列表
*/
void saveCoefficientConfig(Long adjustmentId, List<Map<String, Object>> categories);
/**
* 获取系数调整配置
*
* @param adjustmentId 调整设置ID
* @return 类别配置列表
*/
List<Map<String, Object>> getCoefficientConfig(Long adjustmentId);
/**
* 获取可选的工料机列表
*
* @param quotaItemId 定额子目ID
* @return 工料机列表
*/
List<Map<String, Object>> getAvailableResources(Long quotaItemId);
/**
* 保存动态合并配置
*
* @param adjustmentId 调整设置ID
* @param resources 工料机配置列表
*/
void saveMergeConfig(Long adjustmentId, List<Map<String, Object>> resources);
/**
* 获取动态合并配置
*
* @param adjustmentId 调整设置ID
* @return 工料机配置列表
*/
List<Map<String, Object>> getMergeConfig(Long adjustmentId);
/**
* 计算动态合并结果
*
* @param adjustmentId 调整设置ID
* @param inputValues 输入值映射工料机ID: 输入值)
* @return 调整结果映射工料机ID: 调整结果)
*/
Map<String, BigDecimal> calculateMerge(Long adjustmentId, Map<String, BigDecimal> inputValues);
}

View File

@@ -0,0 +1,61 @@
package com.yhy.module.core.service.quota;
import com.yhy.module.core.controller.admin.quota.vo.QuotaAdjustmentSettingSaveReqVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaAdjustmentSettingDO;
import java.util.List;
import javax.validation.Valid;
/**
* 定额调整设置 Service 接口
*
* @author 芋道源码
*/
public interface QuotaAdjustmentSettingService {
/**
* 创建定额调整设置
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createQuotaAdjustmentSetting(@Valid QuotaAdjustmentSettingSaveReqVO createReqVO);
/**
* 更新定额调整设置
*
* @param updateReqVO 更新信息
*/
void updateQuotaAdjustmentSetting(@Valid QuotaAdjustmentSettingSaveReqVO updateReqVO);
/**
* 删除定额调整设置
*
* @param id 编号
*/
void deleteQuotaAdjustmentSetting(Long id);
/**
* 获得定额调整设置
*
* @param id 编号
* @return 定额调整设置
*/
QuotaAdjustmentSettingDO getQuotaAdjustmentSetting(Long id);
/**
* 获得定额调整设置列表
*
* @param quotaItemId 定额子目ID
* @return 定额调整设置列表
*/
List<QuotaAdjustmentSettingDO> getQuotaAdjustmentSettingList(Long quotaItemId);
/**
* 交换排序
*
* @param id1 第一个调整设置ID
* @param id2 第二个调整设置ID
*/
void swapSort(Long id1, Long id2);
}

View File

@@ -2,10 +2,10 @@ package com.yhy.module.core.service.quota;
import com.yhy.module.core.controller.admin.quota.vo.QuotaCatalogItemRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaCatalogItemSaveReqVO;
import com.yhy.module.core.controller.admin.resource.vo.ResourceCategoryFullRespVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaCatalogItemDO;
import javax.validation.Valid;
import java.util.List;
import javax.validation.Valid;
/**
* 定额目录条目 Service 接口
@@ -45,26 +45,18 @@ public interface QuotaCatalogItemService {
QuotaCatalogItemDO getQuotaCatalogItem(Long id);
/**
* 获得定额目录条目列表
* 获得定额专业节点列表(第一层)
*
* @param parentId 父节点ID
* @return 定额目录条目列表
* @return 定额专业节点列表
*/
List<QuotaCatalogItemRespVO> getQuotaCatalogItemList(Long parentId);
/**
* 获得定额目录树
*
* @return 定额目录树
*/
List<QuotaCatalogItemRespVO> getQuotaCatalogItemTree();
List<QuotaCatalogItemRespVO> getQuotaCatalogItemList();
/**
* 绑定工料机专业
*
* 业务规则:
* 1. 只有 node_type='specialty' 的节点才能绑定
* 2. 只能绑定 node_type='type' 的机类树节点
* 2. 只能绑定 node_type='specialty' 的机类树节点
* 3. 绑定后不可修改specialty_locked=true
*
* @param catalogItemId 定额专业节点ID
@@ -72,30 +64,6 @@ public interface QuotaCatalogItemService {
*/
void bindResourceSpecialty(Long catalogItemId, Long categoryTreeId);
/**
* 添加目录节点
*
* 业务规则:
* 1. 父节点必须是 content_type='directory' 或根节点
* 2. 自动设置 content_type='directory', allow_children=true
*
* @param createReqVO 创建信息
* @return 编号
*/
Long addDirectory(@Valid QuotaCatalogItemSaveReqVO createReqVO);
/**
* 添加内容节点
*
* 业务规则:
* 1. 父节点必须是 content_type='directory'
* 2. 自动设置 content_type='content', allow_children=false
*
* @param createReqVO 创建信息
* @return 编号
*/
Long addContent(@Valid QuotaCatalogItemSaveReqVO createReqVO);
/**
* 验证节点类型
*
@@ -105,10 +73,31 @@ public interface QuotaCatalogItemService {
void validateNodeType(Long id, String expectedType);
/**
* 检查节点是否有子节点
* 获取定额专业树结构(第一层)
*
* @param id 节点ID
* @return 是否有子节点
* @param excludeNodeTypes 要排除的节点类型列表
* @return 树形结构
*/
boolean hasChildren(Long id);
List<QuotaCatalogItemRespVO> getQuotaCatalogItemTree(List<String> excludeNodeTypes);
/**
* 交换两个节点的排序
*
* @param nodeId1 节点1的ID
* @param nodeId2 节点2的ID
*/
void swapSort(Long nodeId1, Long nodeId2);
/**
* 通过费率模式节点获取关联的工料机类别字典(含价格代码)
*
* 业务逻辑:
* 1. 如果传入的是费率模式节点,向上查找定额专业节点
* 2. 获取定额专业节点绑定的 category_tree_id
* 3. 查询该工料机专业下的所有类别字典(含价格代码)
*
* @param catalogItemId 定额目录节点ID可以是费率模式节点或定额专业节点
* @return 类别字典列表(含价格代码)
*/
List<ResourceCategoryFullRespVO> getCategoriesByCatalogItem(Long catalogItemId);
}

View File

@@ -0,0 +1,70 @@
package com.yhy.module.core.service.quota;
import com.yhy.module.core.controller.admin.quota.vo.QuotaCatalogTreeRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaCatalogTreeSaveReqVO;
import java.util.List;
import javax.validation.Valid;
/**
* 定额子目树 Service 接口
*
* @author yhy
*/
public interface QuotaCatalogTreeService {
/**
* 创建定额子目树节点
*/
Long createCatalogTree(@Valid QuotaCatalogTreeSaveReqVO createReqVO);
/**
* 更新定额子目树节点
*/
void updateCatalogTree(@Valid QuotaCatalogTreeSaveReqVO updateReqVO);
/**
* 删除定额子目树节点
*/
void deleteCatalogTree(Long id);
/**
* 获取定额子目树节点详情
*/
QuotaCatalogTreeRespVO getCatalogTree(Long id);
/**
* 获取定额子目树节点列表
*/
List<QuotaCatalogTreeRespVO> getCatalogTreeList(Long catalogItemId, Long parentId);
/**
* 获取定额子目树结构
*/
List<QuotaCatalogTreeRespVO> getCatalogTreeTree(Long catalogItemId);
/**
* 交换排序
*/
void swapSort(Long nodeId1, Long nodeId2);
/**
* 根据费率项ID查询绑定的定额子目树
*
* @param rateItemId 费率项ID
* @return 绑定的定额子目树列表
*/
List<QuotaCatalogTreeRespVO> getCatalogTreeByRateItem(Long rateItemId);
/**
* 根据费率模式节点ID查询所属定额专业的子目录树
*
* 业务逻辑:
* 1. 验证传入的节点是 rate_mode 类型
* 2. 向上追溯找到所属的定额专业节点node_type='specialty'
* 3. 查询该定额专业节点下的所有子目录树(第二层)
*
* @param rateModeNodeId 费率模式节点ID
* @return 子目录树列表
*/
List<QuotaCatalogTreeRespVO> getCatalogTreeByRateModeNode(Long rateModeNodeId);
}

View File

@@ -1,10 +1,10 @@
package com.yhy.module.core.service.quota;
import com.yhy.module.core.controller.admin.quota.vo.QuotaFeeItemSaveReqVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaFeeItemWithRateRespVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaFeeItemDO;
import javax.validation.Valid;
import java.util.List;
import javax.validation.Valid;
/**
* 定额取费项 Service 接口
@@ -36,6 +36,16 @@ public interface QuotaFeeItemService {
*/
List<QuotaFeeItemDO> getFeeItemList(Long catalogItemId);
/**
* 获取取费项与费率项合并列表
*
* 将费率项树的一级节点与取费项进行一对一关联展示
*
* @param catalogItemId 模式节点ID
* @return 合并后的列表
*/
List<QuotaFeeItemWithRateRespVO> getFeeItemWithRateList(Long catalogItemId);
/**
* 交换排序
*/

View File

@@ -0,0 +1,70 @@
package com.yhy.module.core.service.quota;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateFieldLabelRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateFieldLabelSaveReqVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaRateFieldLabelDO;
import java.util.List;
import javax.validation.Valid;
/**
* 定额费率字段标签字典 Service 接口
*
* @author yhy
*/
public interface QuotaRateFieldLabelService {
/**
* 创建字段标签
*
* @param createReqVO 创建信息
* @return 标签ID
*/
Long createFieldLabel(@Valid QuotaRateFieldLabelSaveReqVO createReqVO);
/**
* 更新字段标签
*
* @param updateReqVO 更新信息
*/
void updateFieldLabel(@Valid QuotaRateFieldLabelSaveReqVO updateReqVO);
/**
* 删除字段标签
*
* @param id 标签ID
*/
void deleteFieldLabel(Long id);
/**
* 获取字段标签
*
* @param id 标签ID
* @return 字段标签
*/
QuotaRateFieldLabelDO getFieldLabel(Long id);
/**
* 获取字段标签列表
*
* @param catalogItemId 模式节点ID
* @return 字段标签列表
*/
List<QuotaRateFieldLabelRespVO> getFieldLabelList(Long catalogItemId);
/**
* 交换排序
*
* @param labelId1 标签ID1
* @param labelId2 标签ID2
*/
void swapSort(Long labelId1, Long labelId2);
/**
* 验证字段标签存在
*
* @param id 标签ID
* @return 字段标签
*/
QuotaRateFieldLabelDO validateFieldLabelExists(Long id);
}

View File

@@ -3,7 +3,6 @@ package com.yhy.module.core.service.quota;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateFieldRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateFieldSaveReqVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaRateFieldDO;
import java.util.List;
/**
@@ -22,9 +21,9 @@ public interface QuotaRateFieldService {
void deleteRateField(Long id);
/**
* 删除费率的所有字段绑定
* 删除费率模式节点的所有字段绑定
*/
void deleteByRateItemId(Long rateItemId);
void deleteByCatalogItemId(Long catalogItemId);
/**
* 获取字段绑定
@@ -32,19 +31,19 @@ public interface QuotaRateFieldService {
QuotaRateFieldDO getRateField(Long id);
/**
* 获取费率的字段绑定列表
* 获取费率模式节点的字段绑定列表
*/
List<QuotaRateFieldRespVO> getRateFieldList(Long rateItemId);
List<QuotaRateFieldRespVO> getRateFieldList(Long catalogItemId);
/**
* 更新字段绑定
*/
void updateBinding(Long rateItemId, Integer fieldIndex, Long[] bindingIds);
void updateBinding(Long catalogItemId, Integer fieldIndex, Long[] bindingIds);
/**
* 批量保存字段绑定
*/
void batchSaveRateFields(Long rateItemId, List<QuotaRateFieldSaveReqVO> fields);
void batchSaveRateFields(Long catalogItemId, List<QuotaRateFieldSaveReqVO> fields);
/**
* 验证绑定范围(只能绑定当前定额专业下的节点)

View File

@@ -2,9 +2,9 @@ package com.yhy.module.core.service.quota;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateItemRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateItemSaveReqVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateModeNodeSaveReqVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateValueRulesReqVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaRateItemDO;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
@@ -14,6 +14,11 @@ import java.util.Map;
*/
public interface QuotaRateItemService {
/**
* 创建费率模式节点(在定额专业下创建 rate_mode 节点)
*/
Long createRateModeNode(QuotaRateModeNodeSaveReqVO createReqVO);
/**
* 创建费率项
*/
@@ -54,13 +59,34 @@ public interface QuotaRateItemService {
*/
void swapSort(Long nodeId1, Long nodeId2);
/**
* 移动节点到指定位置(重新计算所有受影响节点的排序值)
*
* @param nodeId 要移动的节点ID
* @param targetNodeId 目标位置节点ID移动到该节点之前
*/
void moveNode(Long nodeId, Long targetNodeId);
/**
* 配置动态取值规则
*
* 支持两种规则:
* 1. 阶梯规则tiers必填根据基数值匹配阈值区间返回对应字段值
* 2. 增量规则increments可选在阶梯基础上叠加增量计算
*/
void configValueRules(QuotaRateValueRulesReqVO reqVO);
/**
* 计算动态字段值
* 计算动态字段值(默认使用阶梯规则)
*
* 计算逻辑:
* 1. 根据基数值匹配阶梯规则,获取基础字段值(必须配置)
* 2. 如果配置了增量规则,在基础值上叠加增量(可选)
*
* 示例:
* - 基数50万以内字段1=0.224%
* - 基数50-100万字段1=0.301%
* - 基数超过100万在0.301%基础上每增加100万增加0.036%
*
* @param rateItemId 费率项ID
* @param baseValue 基数值(用户输入)

View File

@@ -4,9 +4,8 @@ import com.yhy.module.core.controller.admin.quota.vo.QuotaResourceRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaResourceSaveReqVO;
import com.yhy.module.core.controller.admin.resource.vo.ResourceItemRespVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaResourceDO;
import javax.validation.Valid;
import java.util.List;
import javax.validation.Valid;
/**
* 定额工料机组成 Service 接口
@@ -67,6 +66,19 @@ public interface QuotaResourceService {
*/
List<ResourceItemRespVO> getAvailableResourceItems(Long quotaItemId);
/**
* 获取可选的工料机列表(已过滤范围,支持模糊查询)
*
* 只返回定额专业绑定的工料机专业下的工料机数据
*
* @param quotaItemId 定额子目ID
* @param code 编码(模糊查询,可选)
* @param name 名称(模糊查询,可选)
* @param spec 型号规格(模糊查询,可选)
* @return 可选的工料机列表
*/
List<ResourceItemRespVO> getAvailableResourceItemsWithFilter(Long quotaItemId, String code, String name, String spec);
/**
* 验证工料机是否在定额专业的数据范围内
*

View File

@@ -0,0 +1,291 @@
package com.yhy.module.core.service.quota.impl;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.yhy.module.core.enums.ErrorCodeConstants.QUOTA_ADJUSTMENT_DETAIL_CODE_NOT_EXISTS;
import static com.yhy.module.core.enums.ErrorCodeConstants.QUOTA_ADJUSTMENT_DETAIL_CODE_NOT_SAME_SPECIALTY;
import static com.yhy.module.core.enums.ErrorCodeConstants.QUOTA_ADJUSTMENT_DETAIL_NOT_EXISTS;
import static com.yhy.module.core.enums.ErrorCodeConstants.QUOTA_ADJUSTMENT_DETAIL_NOT_SAME_SETTING;
import static com.yhy.module.core.enums.ErrorCodeConstants.QUOTA_ADJUSTMENT_DETAIL_SETTING_NOT_EXISTS;
import static com.yhy.module.core.enums.ErrorCodeConstants.QUOTA_ADJUSTMENT_SETTING_NOT_EXISTS;
import static com.yhy.module.core.enums.ErrorCodeConstants.QUOTA_ADJUSTMENT_SETTING_QUOTA_ITEM_NOT_EXISTS;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import com.yhy.module.core.controller.admin.quota.vo.QuotaAdjustmentCombinedRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaAdjustmentDetailSaveReqVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaAdjustmentDetailDO;
import com.yhy.module.core.dal.dataobject.quota.QuotaAdjustmentSettingDO;
import com.yhy.module.core.dal.dataobject.quota.QuotaCatalogTreeDO;
import com.yhy.module.core.dal.dataobject.quota.QuotaItemDO;
import com.yhy.module.core.dal.mysql.quota.QuotaAdjustmentDetailMapper;
import com.yhy.module.core.dal.mysql.quota.QuotaAdjustmentSettingMapper;
import com.yhy.module.core.dal.mysql.quota.QuotaCatalogItemMapper;
import com.yhy.module.core.dal.mysql.quota.QuotaCatalogTreeMapper;
import com.yhy.module.core.dal.mysql.quota.QuotaItemMapper;
import com.yhy.module.core.service.quota.QuotaAdjustmentDetailService;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
/**
* 定额调整明细 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
@Slf4j
public class QuotaAdjustmentDetailServiceImpl implements QuotaAdjustmentDetailService {
@Resource
private QuotaAdjustmentDetailMapper quotaAdjustmentDetailMapper;
@Resource
private QuotaAdjustmentSettingMapper quotaAdjustmentSettingMapper;
@Resource
private QuotaItemMapper quotaItemMapper;
@Resource
private QuotaCatalogTreeMapper quotaCatalogTreeMapper;
@Resource
private QuotaCatalogItemMapper quotaCatalogItemMapper;
@Override
public Long createQuotaAdjustmentDetail(QuotaAdjustmentDetailSaveReqVO createReqVO) {
// 验证调整设置是否存在
validateAdjustmentSettingExists(createReqVO.getAdjustmentSettingId());
// 如果有引用编号,验证引用的调整设置
if (createReqVO.getAdjustmentCode() != null) {
validateAdjustmentCodeInSameSpecialty(createReqVO.getAdjustmentSettingId(), createReqVO.getAdjustmentCode());
}
// 插入
QuotaAdjustmentDetailDO detail = BeanUtils.toBean(createReqVO, QuotaAdjustmentDetailDO.class);
if (detail.getSortOrder() == null) {
detail.setSortOrder(0);
}
quotaAdjustmentDetailMapper.insert(detail);
return detail.getId();
}
@Override
public void updateQuotaAdjustmentDetail(QuotaAdjustmentDetailSaveReqVO updateReqVO) {
// 校验存在
validateQuotaAdjustmentDetailExists(updateReqVO.getId());
// 验证调整设置是否存在
validateAdjustmentSettingExists(updateReqVO.getAdjustmentSettingId());
// 如果有引用编号,验证引用的调整设置
if (updateReqVO.getAdjustmentCode() != null) {
validateAdjustmentCodeInSameSpecialty(updateReqVO.getAdjustmentSettingId(), updateReqVO.getAdjustmentCode());
}
// 更新
QuotaAdjustmentDetailDO updateObj = BeanUtils.toBean(updateReqVO, QuotaAdjustmentDetailDO.class);
quotaAdjustmentDetailMapper.updateById(updateObj);
}
@Override
public void deleteQuotaAdjustmentDetail(Long id) {
// 校验存在
validateQuotaAdjustmentDetailExists(id);
// 删除
quotaAdjustmentDetailMapper.deleteById(id);
}
@Override
public QuotaAdjustmentDetailDO getQuotaAdjustmentDetail(Long id) {
return quotaAdjustmentDetailMapper.selectById(id);
}
@Override
public List<QuotaAdjustmentDetailDO> getQuotaAdjustmentDetailListByQuotaItem(Long quotaItemId) {
// 1. 查询该定额子目下的所有调整设置
List<QuotaAdjustmentSettingDO> settings = quotaAdjustmentSettingMapper.selectListByQuotaItemId(quotaItemId);
if (settings.isEmpty()) {
return Collections.emptyList();
}
// 2. 查询这些调整设置下的所有明细
List<Long> settingIds = settings.stream()
.map(QuotaAdjustmentSettingDO::getId)
.collect(java.util.stream.Collectors.toList());
return quotaAdjustmentDetailMapper.selectListBySettingIds(settingIds);
}
@Override
public List<QuotaAdjustmentDetailDO> getQuotaAdjustmentDetailList(Long adjustmentSettingId) {
return quotaAdjustmentDetailMapper.selectListBySettingId(adjustmentSettingId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void swapSort(Long id1, Long id2) {
// 验证两个调整明细是否存在
QuotaAdjustmentDetailDO detail1 = quotaAdjustmentDetailMapper.selectByIdForUpdate(id1);
QuotaAdjustmentDetailDO detail2 = quotaAdjustmentDetailMapper.selectByIdForUpdate(id2);
if (detail1 == null) {
throw exception(QUOTA_ADJUSTMENT_DETAIL_NOT_EXISTS);
}
if (detail2 == null) {
throw exception(QUOTA_ADJUSTMENT_DETAIL_NOT_EXISTS);
}
// 验证是否在同一调整设置下
if (!detail1.getAdjustmentSettingId().equals(detail2.getAdjustmentSettingId())) {
throw exception(QUOTA_ADJUSTMENT_DETAIL_NOT_SAME_SETTING);
}
// 交换排序值
Integer tempSort = detail1.getSortOrder();
detail1.setSortOrder(detail2.getSortOrder());
detail2.setSortOrder(tempSort);
quotaAdjustmentDetailMapper.updateById(detail1);
quotaAdjustmentDetailMapper.updateById(detail2);
}
@Override
public List<QuotaAdjustmentSettingDO> getAvailableSettings(Long adjustmentSettingId) {
// 获取当前调整设置
QuotaAdjustmentSettingDO currentSetting = quotaAdjustmentSettingMapper.selectById(adjustmentSettingId);
if (currentSetting == null) {
throw exception(QUOTA_ADJUSTMENT_SETTING_NOT_EXISTS);
}
// 获取定额专业ID
Long specialtyId = getSpecialtyIdByQuotaItem(currentSetting.getQuotaItemId());
// 查询同一定额专业下的所有定额子目
List<QuotaCatalogTreeDO> catalogTrees = quotaCatalogTreeMapper.selectListByCatalogItemId(specialtyId);
// 查询这些定额子目下的所有调整设置
// 这里简化处理,返回所有调整设置,前端可以根据需要过滤
// 实际应该根据 catalogTrees 中的 ID 查询对应的 quotaItem再查询调整设置
return quotaAdjustmentSettingMapper.selectList();
}
@Override
public List<QuotaAdjustmentCombinedRespVO> getCombinedList(Long quotaItemId) {
// 1. 查询该定额子目下的所有调整设置(第五层)
List<QuotaAdjustmentSettingDO> settings = quotaAdjustmentSettingMapper.selectListByQuotaItemId(quotaItemId);
if (settings.isEmpty()) {
return Collections.emptyList();
}
// 2. 查询所有调整设置的明细(第六层)
List<Long> settingIds = settings.stream()
.map(QuotaAdjustmentSettingDO::getId)
.collect(java.util.stream.Collectors.toList());
List<QuotaAdjustmentDetailDO> allDetails = quotaAdjustmentDetailMapper.selectListBySettingIds(settingIds);
// 3. 按 adjustmentSettingId 分组
Map<Long, List<QuotaAdjustmentDetailDO>> detailsMap = allDetails.stream()
.collect(java.util.stream.Collectors.groupingBy(QuotaAdjustmentDetailDO::getAdjustmentSettingId));
// 4. 组装结果
return settings.stream()
.map(setting -> {
QuotaAdjustmentCombinedRespVO vo = new QuotaAdjustmentCombinedRespVO();
vo.setId(setting.getId());
vo.setQuotaItemId(setting.getQuotaItemId());
vo.setName(setting.getName());
vo.setQuotaValue(setting.getQuotaValue());
vo.setAdjustmentContent(setting.getAdjustmentContent());
vo.setAdjustmentType(setting.getAdjustmentType());
vo.setAdjustmentRules(setting.getAdjustmentRules());
vo.setSortOrder(setting.getSortOrder());
vo.setCreateTime(setting.getCreateTime());
// 获取该调整设置的明细列表
List<QuotaAdjustmentDetailDO> details = detailsMap.getOrDefault(setting.getId(), Collections.emptyList());
List<QuotaAdjustmentCombinedRespVO.DetailItem> detailItems = details.stream()
.map(detail -> {
QuotaAdjustmentCombinedRespVO.DetailItem item = new QuotaAdjustmentCombinedRespVO.DetailItem();
item.setId(detail.getId());
item.setAdjustmentSettingId(detail.getAdjustmentSettingId());
item.setAdjustmentCode(detail.getAdjustmentCode());
item.setAdjustment(detail.getAdjustment());
item.setSortOrder(detail.getSortOrder());
item.setCreateTime(detail.getCreateTime());
return item;
})
.collect(java.util.stream.Collectors.toList());
vo.setDetails(detailItems);
return vo;
})
.collect(java.util.stream.Collectors.toList());
}
private void validateQuotaAdjustmentDetailExists(Long id) {
if (quotaAdjustmentDetailMapper.selectById(id) == null) {
throw exception(QUOTA_ADJUSTMENT_DETAIL_NOT_EXISTS);
}
}
private void validateAdjustmentSettingExists(Long adjustmentSettingId) {
if (quotaAdjustmentSettingMapper.selectById(adjustmentSettingId) == null) {
throw exception(QUOTA_ADJUSTMENT_DETAIL_SETTING_NOT_EXISTS);
}
}
/**
* 验证 adjustment_code 是否在同一定额专业
*/
private void validateAdjustmentCodeInSameSpecialty(Long adjustmentSettingId, Long adjustmentCode) {
// 1. 查询当前调整设置
QuotaAdjustmentSettingDO currentSetting = quotaAdjustmentSettingMapper.selectById(adjustmentSettingId);
if (currentSetting == null) {
throw exception(QUOTA_ADJUSTMENT_SETTING_NOT_EXISTS);
}
// 2. 查询引用的调整设置
QuotaAdjustmentSettingDO referenceSetting = quotaAdjustmentSettingMapper.selectById(adjustmentCode);
if (referenceSetting == null) {
throw exception(QUOTA_ADJUSTMENT_DETAIL_CODE_NOT_EXISTS);
}
// 3. 获取两者的定额专业ID
Long currentSpecialtyId = getSpecialtyIdByQuotaItem(currentSetting.getQuotaItemId());
Long referenceSpecialtyId = getSpecialtyIdByQuotaItem(referenceSetting.getQuotaItemId());
// 4. 验证是否在同一定额专业
if (!currentSpecialtyId.equals(referenceSpecialtyId)) {
throw exception(QUOTA_ADJUSTMENT_DETAIL_CODE_NOT_SAME_SPECIALTY);
}
}
/**
* 通过定额子目追溯到定额专业
*/
private Long getSpecialtyIdByQuotaItem(Long quotaItemId) {
// 1. 查询定额子目(第三层)
QuotaItemDO quotaItem = quotaItemMapper.selectById(quotaItemId);
if (quotaItem == null) {
throw exception(QUOTA_ADJUSTMENT_SETTING_QUOTA_ITEM_NOT_EXISTS);
}
// 2. 查询定额子目树节点(第二层)
QuotaCatalogTreeDO catalogTree = quotaCatalogTreeMapper.selectById(quotaItem.getCatalogItemId());
if (catalogTree == null) {
throw exception(QUOTA_ADJUSTMENT_SETTING_QUOTA_ITEM_NOT_EXISTS);
}
// 3. 返回定额专业节点ID第一层
return catalogTree.getCatalogItemId();
}
}

View File

@@ -1,977 +0,0 @@
package com.yhy.module.core.service.quota.impl;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import com.yhy.module.core.controller.admin.quota.vo.QuotaAdjustmentSaveReqVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaAdjustmentDO;
import com.yhy.module.core.dal.dataobject.quota.QuotaItemDO;
import com.yhy.module.core.dal.dataobject.quota.QuotaCatalogItemDO;
import com.yhy.module.core.dal.dataobject.resource.ResourceCategoryDO;
import com.yhy.module.core.dal.dataobject.resource.ResourceCategoryTreeDO;
import com.yhy.module.core.dal.dataobject.resource.ResourceItemDO;
import com.yhy.module.core.dal.mysql.quota.QuotaAdjustmentMapper;
import com.yhy.module.core.dal.mysql.quota.QuotaCatalogItemMapper;
import com.yhy.module.core.dal.mysql.quota.QuotaItemMapper;
import com.yhy.module.core.dal.mysql.quota.QuotaResourceMapper;
import com.yhy.module.core.dal.mysql.resource.ResourceCategoryMapper;
import com.yhy.module.core.dal.mysql.resource.ResourceCategoryTreeMapper;
import com.yhy.module.core.dal.mysql.resource.ResourceCategoryTreeMappingMapper;
import com.yhy.module.core.dal.mysql.resource.ResourceItemMapper;
import com.yhy.module.core.dal.dataobject.resource.ResourceCategoryTreeMappingDO;
import com.yhy.module.core.dal.dataobject.quota.QuotaResourceDO;
import com.yhy.module.core.enums.quota.RoundingRuleEnum;
import com.yhy.module.core.enums.ErrorCodeConstants;
import com.yhy.module.core.enums.quota.QuotaAdjustmentTypeEnum;
import com.yhy.module.core.service.quota.QuotaAdjustmentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
/**
* 定额调整设置 Service 实现类
*/
@Service
@Validated
@Slf4j
public class QuotaAdjustmentServiceImpl implements QuotaAdjustmentService {
@Resource
private QuotaAdjustmentMapper quotaAdjustmentMapper;
@Resource
private QuotaItemMapper quotaItemMapper;
@Resource
private QuotaCatalogItemMapper quotaCatalogItemMapper;
@Resource
private ResourceCategoryTreeMapper resourceCategoryTreeMapper;
@Resource
private ResourceCategoryMapper resourceCategoryMapper;
@Resource
private ResourceCategoryTreeMappingMapper resourceCategoryTreeMappingMapper;
@Resource
private QuotaResourceMapper quotaResourceMapper;
@Resource
private ResourceItemMapper resourceItemMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createQuotaAdjustment(QuotaAdjustmentSaveReqVO createReqVO) {
// 验证定额子目是否存在
validateQuotaItemExists(createReqVO.getQuotaItemId());
// 验证调整类型
validateAdjustmentType(createReqVO.getAdjustmentType());
// 验证调整规则
validateAdjustmentRules(createReqVO.getAdjustmentType(), createReqVO.getAdjustmentRules());
// 插入
QuotaAdjustmentDO adjustment = QuotaAdjustmentDO.builder()
.quotaItemId(createReqVO.getQuotaItemId())
.name(createReqVO.getName())
.content(createReqVO.getContent())
.adjustmentType(createReqVO.getAdjustmentType())
.adjustmentRules(createReqVO.getAdjustmentRules())
.sortOrder(createReqVO.getSortOrder() != null ? createReqVO.getSortOrder() : 0)
.build();
quotaAdjustmentMapper.insert(adjustment);
return adjustment.getId();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateQuotaAdjustment(QuotaAdjustmentSaveReqVO updateReqVO) {
// 验证存在
validateQuotaAdjustmentExists(updateReqVO.getId());
// 验证定额子目是否存在
validateQuotaItemExists(updateReqVO.getQuotaItemId());
// 验证调整类型
validateAdjustmentType(updateReqVO.getAdjustmentType());
// 验证调整规则
validateAdjustmentRules(updateReqVO.getAdjustmentType(), updateReqVO.getAdjustmentRules());
// 更新
QuotaAdjustmentDO updateObj = QuotaAdjustmentDO.builder()
.id(updateReqVO.getId())
.quotaItemId(updateReqVO.getQuotaItemId())
.name(updateReqVO.getName())
.content(updateReqVO.getContent())
.adjustmentType(updateReqVO.getAdjustmentType())
.adjustmentRules(updateReqVO.getAdjustmentRules())
.sortOrder(updateReqVO.getSortOrder())
.build();
quotaAdjustmentMapper.updateById(updateObj);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteQuotaAdjustment(Long id) {
// 验证存在
validateQuotaAdjustmentExists(id);
// 删除
quotaAdjustmentMapper.deleteById(id);
}
@Override
public QuotaAdjustmentDO getQuotaAdjustment(Long id) {
return quotaAdjustmentMapper.selectById(id);
}
@Override
public List<QuotaAdjustmentDO> getQuotaAdjustmentList(Long quotaItemId) {
return quotaAdjustmentMapper.selectListByQuotaItemId(quotaItemId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void swapSort(Long id1, Long id2) {
// 验证两个调整设置是否存在
QuotaAdjustmentDO adjustment1 = quotaAdjustmentMapper.selectByIdForUpdate(id1);
QuotaAdjustmentDO adjustment2 = quotaAdjustmentMapper.selectByIdForUpdate(id2);
if (adjustment1 == null) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_NOT_EXISTS);
}
if (adjustment2 == null) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_NOT_EXISTS);
}
// 验证是否属于同一个定额子目
if (!adjustment1.getQuotaItemId().equals(adjustment2.getQuotaItemId())) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_NOT_SAME_QUOTA_ITEM);
}
// 交换排序值
Integer tempSort = adjustment1.getSortOrder();
adjustment1.setSortOrder(adjustment2.getSortOrder());
adjustment2.setSortOrder(tempSort);
quotaAdjustmentMapper.updateById(adjustment1);
quotaAdjustmentMapper.updateById(adjustment2);
}
@Override
public BigDecimal calculateAdjustedConsumeQty(Long quotaItemId, BigDecimal originalConsumeQty) {
if (originalConsumeQty == null) {
return BigDecimal.ZERO;
}
// 获取所有调整设置
List<QuotaAdjustmentDO> adjustments = getQuotaAdjustmentList(quotaItemId);
if (adjustments.isEmpty()) {
return originalConsumeQty;
}
// 依次应用调整规则
BigDecimal result = originalConsumeQty;
for (QuotaAdjustmentDO adjustment : adjustments) {
result = applyAdjustment(result, adjustment);
}
return result.setScale(6, RoundingMode.HALF_UP);
}
@Override
public BigDecimal calculateAdjustedDosage(Long quotaItemId, String resourceCode, BigDecimal originalDosage) {
if (originalDosage == null) {
return BigDecimal.ZERO;
}
if (resourceCode == null || resourceCode.trim().isEmpty()) {
return originalDosage;
}
// 获取所有调整设置
List<QuotaAdjustmentDO> adjustments = getQuotaAdjustmentList(quotaItemId);
if (adjustments.isEmpty()) {
return originalDosage;
}
// 查找材料调整类型的调整设置
BigDecimal result = originalDosage;
for (QuotaAdjustmentDO adjustment : adjustments) {
if ("material_adjustment".equals(adjustment.getAdjustmentType())) {
result = applyMaterialAdjustment(result, resourceCode, adjustment);
}
}
return result.setScale(6, RoundingMode.HALF_UP);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void saveMaterialItems(Long adjustmentId, List<Map<String, Object>> items) {
// 验证调整设置存在
QuotaAdjustmentDO adjustment = getQuotaAdjustment(adjustmentId);
if (adjustment == null) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_NOT_EXISTS);
}
// 验证调整类型
if (!"material_adjustment".equals(adjustment.getAdjustmentType())) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_TYPE_INVALID);
}
// 验证明细数据
validateMaterialItems(items);
// 更新调整规则
Map<String, Object> rules = adjustment.getAdjustmentRules();
if (rules == null) {
rules = new java.util.HashMap<>();
}
rules.put("items", items);
adjustment.setAdjustmentRules(rules);
quotaAdjustmentMapper.updateById(adjustment);
}
@Override
public List<Map<String, Object>> getMaterialItems(Long adjustmentId) {
QuotaAdjustmentDO adjustment = getQuotaAdjustment(adjustmentId);
if (adjustment == null) {
return new java.util.ArrayList<>();
}
Map<String, Object> rules = adjustment.getAdjustmentRules();
if (rules == null || !rules.containsKey("items")) {
return new java.util.ArrayList<>();
}
Object itemsObj = rules.get("items");
if (itemsObj instanceof List) {
return (List<Map<String, Object>>) itemsObj;
}
return new java.util.ArrayList<>();
}
/**
* 应用单个调整规则
*/
private BigDecimal applyAdjustment(BigDecimal value, QuotaAdjustmentDO adjustment) {
String type = adjustment.getAdjustmentType();
Map<String, Object> rules = adjustment.getAdjustmentRules();
if (rules == null || rules.isEmpty()) {
return value;
}
QuotaAdjustmentTypeEnum typeEnum = QuotaAdjustmentTypeEnum.valueOfCode(type);
if (typeEnum == null) {
log.warn("未知的调整类型: {}", type);
return value;
}
switch (typeEnum) {
case PERCENTAGE:
return applyPercentageAdjustment(value, rules);
case FIXED_VALUE:
return applyFixedValueAdjustment(value, rules);
case FORMULA:
return applyFormulaAdjustment(value, rules);
case CONDITIONAL:
return applyConditionalAdjustment(value, rules);
default:
return value;
}
}
/**
* 应用百分比调整
*/
private BigDecimal applyPercentageAdjustment(BigDecimal value, Map<String, Object> rules) {
Object valueObj = rules.get("value");
Object operatorObj = rules.get("operator");
if (valueObj == null || operatorObj == null) {
return value;
}
BigDecimal percentage = new BigDecimal(valueObj.toString());
String operator = operatorObj.toString();
if ("increase".equals(operator)) {
// 增加value * (1 + percentage/100)
return value.multiply(BigDecimal.ONE.add(percentage.divide(new BigDecimal("100"), 6, RoundingMode.HALF_UP)));
} else if ("decrease".equals(operator)) {
// 减少value * (1 - percentage/100)
return value.multiply(BigDecimal.ONE.subtract(percentage.divide(new BigDecimal("100"), 6, RoundingMode.HALF_UP)));
}
return value;
}
/**
* 应用固定值调整
*/
private BigDecimal applyFixedValueAdjustment(BigDecimal value, Map<String, Object> rules) {
Object valueObj = rules.get("value");
Object operatorObj = rules.get("operator");
if (valueObj == null || operatorObj == null) {
return value;
}
BigDecimal fixedValue = new BigDecimal(valueObj.toString());
String operator = operatorObj.toString();
if ("increase".equals(operator)) {
return value.add(fixedValue);
} else if ("decrease".equals(operator)) {
return value.subtract(fixedValue);
}
return value;
}
/**
* 应用公式调整(简化实现)
*/
private BigDecimal applyFormulaAdjustment(BigDecimal value, Map<String, Object> rules) {
// TODO: 实现复杂的公式计算逻辑
log.warn("公式调整暂未实现");
return value;
}
/**
* 应用条件调整(简化实现)
*/
private BigDecimal applyConditionalAdjustment(BigDecimal value, Map<String, Object> rules) {
// TODO: 实现条件判断逻辑
log.warn("条件调整暂未实现");
return value;
}
/**
* 应用材料调整
*/
private BigDecimal applyMaterialAdjustment(BigDecimal dosage, String resourceCode, QuotaAdjustmentDO adjustment) {
Map<String, Object> rules = adjustment.getAdjustmentRules();
if (rules == null || !rules.containsKey("items")) {
return dosage;
}
Object itemsObj = rules.get("items");
if (!(itemsObj instanceof List)) {
return dosage;
}
List<Map<String, Object>> items = (List<Map<String, Object>>) itemsObj;
for (Map<String, Object> item : items) {
String itemCode = (String) item.get("resourceCode");
if (resourceCode.equals(itemCode)) {
Object adjustValueObj = item.get("adjustValue");
if (adjustValueObj != null) {
BigDecimal adjustValue = new BigDecimal(adjustValueObj.toString());
return dosage.add(adjustValue);
}
}
}
return dosage;
}
/**
* 验证材料明细
*/
private void validateMaterialItems(List<Map<String, Object>> items) {
if (items == null || items.isEmpty()) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_RULES_INVALID);
}
// 检查重复的工料机编码
java.util.Set<String> codes = new java.util.HashSet<>();
for (Map<String, Object> item : items) {
String resourceCode = (String) item.get("resourceCode");
if (resourceCode == null || resourceCode.trim().isEmpty()) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_RULES_INVALID);
}
if (codes.contains(resourceCode)) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_MATERIAL_CODE_DUPLICATE, resourceCode);
}
codes.add(resourceCode);
// 验证调整值
Object adjustValueObj = item.get("adjustValue");
if (adjustValueObj == null) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_RULES_INVALID);
}
try {
new BigDecimal(adjustValueObj.toString());
} catch (NumberFormatException e) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_RULES_INVALID);
}
}
}
@Override
public List<Map<String, Object>> getAvailableCategories(Long quotaItemId) {
// 1. 获取定额子目
QuotaItemDO quotaItem = quotaItemMapper.selectById(quotaItemId);
if (quotaItem == null) {
throw exception(ErrorCodeConstants.QUOTA_ITEM_NOT_EXISTS);
}
// 2. 获取工料机专业ID
Long categoryTreeId = getCategoryTreeIdByQuotaItem(quotaItemId);
if (categoryTreeId == null) {
throw exception(ErrorCodeConstants.QUOTA_SPECIALTY_NOT_BOUND);
}
// 3. 获取工料机专业节点
ResourceCategoryTreeDO categoryTree = resourceCategoryTreeMapper.selectById(categoryTreeId);
if (categoryTree == null) {
throw exception(ErrorCodeConstants.RESOURCE_CATEGORY_TREE_NOT_EXISTS);
}
// 4. 获取类别列表(通过映射表)
List<ResourceCategoryTreeMappingDO> mappings = resourceCategoryTreeMappingMapper.selectList(
"category_tree_id", categoryTreeId
);
if (mappings == null || mappings.isEmpty()) {
return new java.util.ArrayList<>();
}
List<Long> categoryIds = mappings.stream()
.map(ResourceCategoryTreeMappingDO::getCategoryId)
.collect(java.util.stream.Collectors.toList());
List<ResourceCategoryDO> categories = resourceCategoryMapper.selectList(
"id", categoryIds
);
// 5. 转换为VO
List<Map<String, Object>> result = new java.util.ArrayList<>();
for (ResourceCategoryDO category : categories) {
Map<String, Object> map = new java.util.HashMap<>();
map.put("categoryId", category.getId());
map.put("categoryName", category.getName());
map.put("categoryType", getCategoryType(category.getCode()));
map.put("categoryCode", category.getCode());
result.add(map);
}
return result;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void saveDynamicConfig(Long adjustmentId, List<Map<String, Object>> categories) {
// 验证调整设置存在
QuotaAdjustmentDO adjustment = getQuotaAdjustment(adjustmentId);
if (adjustment == null) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_NOT_EXISTS);
}
// 验证调整类型
if (!"dynamic_adjustment".equals(adjustment.getAdjustmentType())) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_TYPE_INVALID);
}
// 验证配置数据
validateDynamicConfig(categories);
// 更新调整规则
Map<String, Object> rules = adjustment.getAdjustmentRules();
if (rules == null) {
rules = new java.util.HashMap<>();
}
rules.put("categories", categories);
adjustment.setAdjustmentRules(rules);
quotaAdjustmentMapper.updateById(adjustment);
}
@Override
public List<Map<String, Object>> getDynamicConfig(Long adjustmentId) {
QuotaAdjustmentDO adjustment = getQuotaAdjustment(adjustmentId);
if (adjustment == null) {
return new java.util.ArrayList<>();
}
Map<String, Object> rules = adjustment.getAdjustmentRules();
if (rules == null || !rules.containsKey("categories")) {
return new java.util.ArrayList<>();
}
Object categoriesObj = rules.get("categories");
if (categoriesObj instanceof List) {
return (List<Map<String, Object>>) categoriesObj;
}
return new java.util.ArrayList<>();
}
@Override
public Map<String, BigDecimal> calculateDynamic(Long adjustmentId, Map<String, BigDecimal> inputValues) {
// 获取动态调整配置
List<Map<String, Object>> categories = getDynamicConfig(adjustmentId);
if (categories.isEmpty()) {
return new java.util.HashMap<>();
}
Map<String, BigDecimal> results = new java.util.HashMap<>();
for (Map<String, Object> category : categories) {
String categoryId = category.get("categoryId").toString();
BigDecimal inputValue = inputValues.get(categoryId);
if (inputValue == null) {
continue;
}
// 计算调整结果
BigDecimal result = calculateDynamicForCategory(category, inputValue);
results.put(categoryId, result);
}
return results;
}
/**
* 计算单个类别的动态调整结果
*/
private BigDecimal calculateDynamicForCategory(Map<String, Object> category, BigDecimal inputValue) {
// 获取配置参数
BigDecimal coefficient = new BigDecimal(category.get("coefficient").toString());
BigDecimal minValue = new BigDecimal(category.get("minValue").toString());
BigDecimal maxValue = new BigDecimal(category.get("maxValue").toString());
BigDecimal denominator = new BigDecimal(category.get("denominator").toString());
BigDecimal baseValue = new BigDecimal(category.get("baseValue").toString());
String roundingRule = (String) category.get("roundingRule");
// 1. 验证输入值范围
if (inputValue.compareTo(minValue) < 0 || inputValue.compareTo(maxValue) > 0) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_INPUT_VALUE_OUT_OF_RANGE,
inputValue, minValue, maxValue);
}
// 2. 计算中间值:(输入值 - 基础值) / 分母
BigDecimal intermediate = inputValue.subtract(baseValue).divide(denominator, 6, RoundingMode.HALF_UP);
// 3. 应用取值规则
BigDecimal rounded = applyRoundingRule(intermediate, roundingRule);
// 4. 乘以系数
BigDecimal result = rounded.multiply(coefficient);
// 5. 负数结果视为0
if (result.compareTo(BigDecimal.ZERO) < 0) {
result = BigDecimal.ZERO;
}
return result.setScale(6, RoundingMode.HALF_UP);
}
/**
* 应用取值规则
*/
private BigDecimal applyRoundingRule(BigDecimal value, String ruleCode) {
RoundingRuleEnum rule = RoundingRuleEnum.valueOfCode(ruleCode);
if (rule == null) {
return value;
}
switch (rule) {
case ROUND_UP:
// 向上取整
return value.setScale(0, RoundingMode.UP);
case ROUND_DOWN:
// 向下取整
return value.setScale(0, RoundingMode.DOWN);
case ROUND_HALF_UP:
// 四舍五入
return value.setScale(0, RoundingMode.HALF_UP);
case NO_ROUNDING:
default:
// 不取整
return value;
}
}
/**
* 获取定额子目对应的工料机专业ID
*/
private Long getCategoryTreeIdByQuotaItem(Long quotaItemId) {
// 1. 查询定额子目
QuotaItemDO quotaItem = quotaItemMapper.selectById(quotaItemId);
if (quotaItem == null) {
return null;
}
// 2. 查询内容节点
QuotaCatalogItemDO contentNode = quotaCatalogItemMapper.selectById(quotaItem.getCatalogItemId());
if (contentNode == null) {
return null;
}
// 3. 向上追溯到定额专业节点
QuotaCatalogItemDO current = contentNode;
while (current != null) {
Map<String, Object> attributes = current.getAttributes();
if (attributes != null && "specialty".equals(attributes.get("node_type"))) {
return current.getCategoryTreeId();
}
if (current.getParentId() == null) {
break;
}
current = quotaCatalogItemMapper.selectById(current.getParentId());
}
return null;
}
/**
* 根据类别代码获取类别类型
*/
private String getCategoryType(String code) {
if (code == null) {
return "unknown";
}
// 简单映射,实际可能需要更复杂的逻辑
if (code.contains("") || code.equalsIgnoreCase("RG")) {
return "labor";
} else if (code.contains("") || code.equalsIgnoreCase("CL")) {
return "material";
} else if (code.contains("") || code.equalsIgnoreCase("JX")) {
return "machine";
}
return "other";
}
/**
* 验证动态调整配置
*/
private void validateDynamicConfig(List<Map<String, Object>> categories) {
if (categories == null || categories.isEmpty()) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_RULES_INVALID);
}
// 检查重复的类别ID
java.util.Set<String> categoryIds = new java.util.HashSet<>();
for (Map<String, Object> category : categories) {
String categoryId = category.get("categoryId").toString();
if (categoryIds.contains(categoryId)) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_CATEGORY_DUPLICATE, categoryId);
}
categoryIds.add(categoryId);
// 验证参数
validateDynamicCategoryParams(category);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void saveCoefficientConfig(Long adjustmentId, List<Map<String, Object>> categories) {
// 验证调整设置存在
QuotaAdjustmentDO adjustment = getQuotaAdjustment(adjustmentId);
if (adjustment == null) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_NOT_EXISTS);
}
// 验证调整类型
if (!"coefficient_adjustment".equals(adjustment.getAdjustmentType())) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_TYPE_INVALID);
}
// 验证配置数据
validateCoefficientConfig(categories);
// 更新调整规则
Map<String, Object> rules = adjustment.getAdjustmentRules();
if (rules == null) {
rules = new java.util.HashMap<>();
}
rules.put("categories", categories);
adjustment.setAdjustmentRules(rules);
quotaAdjustmentMapper.updateById(adjustment);
}
@Override
public List<Map<String, Object>> getCoefficientConfig(Long adjustmentId) {
QuotaAdjustmentDO adjustment = getQuotaAdjustment(adjustmentId);
if (adjustment == null) {
return new java.util.ArrayList<>();
}
Map<String, Object> rules = adjustment.getAdjustmentRules();
if (rules == null || !rules.containsKey("categories")) {
return new java.util.ArrayList<>();
}
Object categoriesObj = rules.get("categories");
if (categoriesObj instanceof List) {
return (List<Map<String, Object>>) categoriesObj;
}
return new java.util.ArrayList<>();
}
@Override
public List<Map<String, Object>> getAvailableResources(Long quotaItemId) {
// 1. 获取定额子目的所有工料机组成
List<QuotaResourceDO> quotaResources = quotaResourceMapper.selectListByQuotaItemId(quotaItemId);
if (quotaResources == null || quotaResources.isEmpty()) {
return new java.util.ArrayList<>();
}
// 2. 获取工料机详情
List<Long> resourceItemIds = quotaResources.stream()
.map(QuotaResourceDO::getResourceItemId)
.collect(java.util.stream.Collectors.toList());
List<ResourceItemDO> resourceItems = resourceItemMapper.selectList(
"id", resourceItemIds
);
// 3. 转换为VO从快照中获取编码和名称
List<Map<String, Object>> result = new java.util.ArrayList<>();
for (QuotaResourceDO quotaResource : quotaResources) {
Map<String, Object> map = new java.util.HashMap<>();
map.put("resourceId", quotaResource.getResourceItemId());
map.put("resourceCode", quotaResource.getResourceCode());
map.put("resourceName", quotaResource.getResourceName());
result.add(map);
}
return result;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void saveMergeConfig(Long adjustmentId, List<Map<String, Object>> resources) {
// 验证调整设置存在
QuotaAdjustmentDO adjustment = getQuotaAdjustment(adjustmentId);
if (adjustment == null) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_NOT_EXISTS);
}
// 验证调整类型
if (!"dynamic_merge_quota".equals(adjustment.getAdjustmentType())) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_TYPE_INVALID);
}
// 验证配置数据
validateMergeConfig(resources);
// 更新调整规则
Map<String, Object> rules = adjustment.getAdjustmentRules();
if (rules == null) {
rules = new java.util.HashMap<>();
}
rules.put("resources", resources);
adjustment.setAdjustmentRules(rules);
quotaAdjustmentMapper.updateById(adjustment);
}
@Override
public List<Map<String, Object>> getMergeConfig(Long adjustmentId) {
QuotaAdjustmentDO adjustment = getQuotaAdjustment(adjustmentId);
if (adjustment == null) {
return new java.util.ArrayList<>();
}
Map<String, Object> rules = adjustment.getAdjustmentRules();
if (rules == null || !rules.containsKey("resources")) {
return new java.util.ArrayList<>();
}
Object resourcesObj = rules.get("resources");
if (resourcesObj instanceof List) {
return (List<Map<String, Object>>) resourcesObj;
}
return new java.util.ArrayList<>();
}
@Override
public Map<String, BigDecimal> calculateMerge(Long adjustmentId, Map<String, BigDecimal> inputValues) {
// 获取动态合并配置
List<Map<String, Object>> resources = getMergeConfig(adjustmentId);
if (resources.isEmpty()) {
return new java.util.HashMap<>();
}
Map<String, BigDecimal> results = new java.util.HashMap<>();
for (Map<String, Object> resource : resources) {
String resourceId = resource.get("resourceId").toString();
BigDecimal inputValue = inputValues.get(resourceId);
if (inputValue == null) {
continue;
}
// 计算调整结果(复用动态调整的计算逻辑)
BigDecimal result = calculateDynamicForCategory(resource, inputValue);
results.put(resourceId, result);
}
return results;
}
/**
* 验证系数调整配置
*/
private void validateCoefficientConfig(List<Map<String, Object>> categories) {
if (categories == null || categories.isEmpty()) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_RULES_INVALID);
}
// 检查重复的类别ID
java.util.Set<String> categoryIds = new java.util.HashSet<>();
for (Map<String, Object> category : categories) {
String categoryId = category.get("categoryId").toString();
if (categoryIds.contains(categoryId)) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_CATEGORY_DUPLICATE, categoryId);
}
categoryIds.add(categoryId);
// 验证系数
try {
BigDecimal coefficient = new BigDecimal(category.get("coefficient").toString());
if (coefficient.compareTo(BigDecimal.ZERO) <= 0) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_COEFFICIENT_INVALID);
}
} catch (NumberFormatException e) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_RULES_INVALID);
}
}
}
/**
* 验证动态合并配置
*/
private void validateMergeConfig(List<Map<String, Object>> resources) {
if (resources == null || resources.isEmpty()) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_RULES_INVALID);
}
// 检查重复的工料机ID
java.util.Set<String> resourceIds = new java.util.HashSet<>();
for (Map<String, Object> resource : resources) {
String resourceId = resource.get("resourceId").toString();
if (resourceIds.contains(resourceId)) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_RESOURCE_DUPLICATE, resourceId);
}
resourceIds.add(resourceId);
// 验证参数(与动态调整相同)
validateDynamicCategoryParams(resource);
}
}
/**
* 验证动态调整类别参数
*/
private void validateDynamicCategoryParams(Map<String, Object> category) {
try {
BigDecimal coefficient = new BigDecimal(category.get("coefficient").toString());
BigDecimal minValue = new BigDecimal(category.get("minValue").toString());
BigDecimal maxValue = new BigDecimal(category.get("maxValue").toString());
BigDecimal denominator = new BigDecimal(category.get("denominator").toString());
BigDecimal baseValue = new BigDecimal(category.get("baseValue").toString());
String roundingRule = (String) category.get("roundingRule");
// 系数必须大于0
if (coefficient.compareTo(BigDecimal.ZERO) <= 0) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_COEFFICIENT_INVALID);
}
// 最小值必须小于最大值
if (minValue.compareTo(maxValue) >= 0) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_MIN_MAX_INVALID);
}
// 分母不能为0
if (denominator.compareTo(BigDecimal.ZERO) == 0) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_DENOMINATOR_ZERO);
}
// 基础值必须在范围内
if (baseValue.compareTo(minValue) < 0 || baseValue.compareTo(maxValue) > 0) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_BASE_VALUE_OUT_OF_RANGE);
}
// 验证取值规则
if (RoundingRuleEnum.valueOfCode(roundingRule) == null) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_ROUNDING_RULE_INVALID);
}
} catch (NumberFormatException e) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_RULES_INVALID);
}
}
private void validateQuotaAdjustmentExists(Long id) {
if (quotaAdjustmentMapper.selectById(id) == null) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_NOT_EXISTS);
}
}
private void validateQuotaItemExists(Long quotaItemId) {
QuotaItemDO quotaItem = quotaItemMapper.selectById(quotaItemId);
if (quotaItem == null) {
throw exception(ErrorCodeConstants.QUOTA_ITEM_NOT_EXISTS);
}
}
private void validateAdjustmentType(String adjustmentType) {
QuotaAdjustmentTypeEnum typeEnum = QuotaAdjustmentTypeEnum.valueOfCode(adjustmentType);
if (typeEnum == null) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_TYPE_INVALID);
}
}
private void validateAdjustmentRules(String adjustmentType, Map<String, Object> rules) {
if (rules == null || rules.isEmpty()) {
return;
}
QuotaAdjustmentTypeEnum typeEnum = QuotaAdjustmentTypeEnum.valueOfCode(adjustmentType);
if (typeEnum == null) {
return;
}
// 根据不同类型验证规则结构
switch (typeEnum) {
case PERCENTAGE:
case FIXED_VALUE:
if (!rules.containsKey("value") || !rules.containsKey("operator")) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_RULES_INVALID);
}
break;
case FORMULA:
if (!rules.containsKey("expression")) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_RULES_INVALID);
}
break;
case CONDITIONAL:
if (!rules.containsKey("conditions")) {
throw exception(ErrorCodeConstants.QUOTA_ADJUSTMENT_RULES_INVALID);
}
break;
}
}
}

View File

@@ -0,0 +1,140 @@
package com.yhy.module.core.service.quota.impl;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.yhy.module.core.enums.ErrorCodeConstants.QUOTA_ADJUSTMENT_SETTING_HAS_DETAILS;
import static com.yhy.module.core.enums.ErrorCodeConstants.QUOTA_ADJUSTMENT_SETTING_NOT_EXISTS;
import static com.yhy.module.core.enums.ErrorCodeConstants.QUOTA_ADJUSTMENT_SETTING_NOT_SAME_QUOTA_ITEM;
import static com.yhy.module.core.enums.ErrorCodeConstants.QUOTA_ADJUSTMENT_SETTING_QUOTA_ITEM_NOT_EXISTS;
import static com.yhy.module.core.enums.ErrorCodeConstants.QUOTA_ADJUSTMENT_SETTING_REFERENCED;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import com.yhy.module.core.controller.admin.quota.vo.QuotaAdjustmentSettingSaveReqVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaAdjustmentSettingDO;
import com.yhy.module.core.dal.mysql.quota.QuotaAdjustmentDetailMapper;
import com.yhy.module.core.dal.mysql.quota.QuotaAdjustmentSettingMapper;
import com.yhy.module.core.dal.mysql.quota.QuotaItemMapper;
import com.yhy.module.core.service.quota.QuotaAdjustmentSettingService;
import java.util.List;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
/**
* 定额调整设置 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
@Slf4j
public class QuotaAdjustmentSettingServiceImpl implements QuotaAdjustmentSettingService {
@Resource
private QuotaAdjustmentSettingMapper quotaAdjustmentSettingMapper;
@Resource
private QuotaAdjustmentDetailMapper quotaAdjustmentDetailMapper;
@Resource
private QuotaItemMapper quotaItemMapper;
@Override
public Long createQuotaAdjustmentSetting(QuotaAdjustmentSettingSaveReqVO createReqVO) {
// 验证定额子目是否存在
validateQuotaItemExists(createReqVO.getQuotaItemId());
// 插入
QuotaAdjustmentSettingDO setting = BeanUtils.toBean(createReqVO, QuotaAdjustmentSettingDO.class);
if (setting.getSortOrder() == null) {
setting.setSortOrder(0);
}
quotaAdjustmentSettingMapper.insert(setting);
return setting.getId();
}
@Override
public void updateQuotaAdjustmentSetting(QuotaAdjustmentSettingSaveReqVO updateReqVO) {
// 校验存在
validateQuotaAdjustmentSettingExists(updateReqVO.getId());
// 验证定额子目是否存在
validateQuotaItemExists(updateReqVO.getQuotaItemId());
// 更新
QuotaAdjustmentSettingDO updateObj = BeanUtils.toBean(updateReqVO, QuotaAdjustmentSettingDO.class);
quotaAdjustmentSettingMapper.updateById(updateObj);
}
@Override
public void deleteQuotaAdjustmentSetting(Long id) {
// 校验存在
validateQuotaAdjustmentSettingExists(id);
// 检查是否有明细
Long detailCount = quotaAdjustmentDetailMapper.countBySettingId(id);
if (detailCount > 0) {
throw exception(QUOTA_ADJUSTMENT_SETTING_HAS_DETAILS);
}
// 检查是否被其他明细引用
Long referenceCount = quotaAdjustmentDetailMapper.countByAdjustmentCode(id);
if (referenceCount > 0) {
throw exception(QUOTA_ADJUSTMENT_SETTING_REFERENCED);
}
// 删除
quotaAdjustmentSettingMapper.deleteById(id);
}
@Override
public QuotaAdjustmentSettingDO getQuotaAdjustmentSetting(Long id) {
return quotaAdjustmentSettingMapper.selectById(id);
}
@Override
public List<QuotaAdjustmentSettingDO> getQuotaAdjustmentSettingList(Long quotaItemId) {
return quotaAdjustmentSettingMapper.selectListByQuotaItemId(quotaItemId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void swapSort(Long id1, Long id2) {
// 验证两个调整设置是否存在
QuotaAdjustmentSettingDO setting1 = quotaAdjustmentSettingMapper.selectByIdForUpdate(id1);
QuotaAdjustmentSettingDO setting2 = quotaAdjustmentSettingMapper.selectByIdForUpdate(id2);
if (setting1 == null) {
throw exception(QUOTA_ADJUSTMENT_SETTING_NOT_EXISTS);
}
if (setting2 == null) {
throw exception(QUOTA_ADJUSTMENT_SETTING_NOT_EXISTS);
}
// 验证是否在同一定额子目下
if (!setting1.getQuotaItemId().equals(setting2.getQuotaItemId())) {
throw exception(QUOTA_ADJUSTMENT_SETTING_NOT_SAME_QUOTA_ITEM);
}
// 交换排序值
Integer tempSort = setting1.getSortOrder();
setting1.setSortOrder(setting2.getSortOrder());
setting2.setSortOrder(tempSort);
quotaAdjustmentSettingMapper.updateById(setting1);
quotaAdjustmentSettingMapper.updateById(setting2);
}
private void validateQuotaAdjustmentSettingExists(Long id) {
if (quotaAdjustmentSettingMapper.selectById(id) == null) {
throw exception(QUOTA_ADJUSTMENT_SETTING_NOT_EXISTS);
}
}
private void validateQuotaItemExists(Long quotaItemId) {
if (quotaItemMapper.selectById(quotaItemId) == null) {
throw exception(QUOTA_ADJUSTMENT_SETTING_QUOTA_ITEM_NOT_EXISTS);
}
}
}

Some files were not shown because too many files have changed in this diff Show More