会员管理-积分余额:支持小数点后3位,修复用户列表积分不显示

- 后台:UserOperateIntegralMoneyRequest.integralValue 改为 BigDecimal,支持3位小数
- 后台:UserServiceImpl 积分操作逻辑改为 BigDecimal,支持小数
- 后台:UserResponse.integral 改为 BigDecimal,修复 BeanUtils 复制导致列表积分不显示
- 前端:积分输入框增加 precision=3、step=0.001,支持3位小数输入

Made-with: Cursor
This commit is contained in:
apple
2026-03-12 15:40:02 +08:00
parent 5432904bcb
commit 31c5426641
4 changed files with 30 additions and 25 deletions

View File

@@ -41,10 +41,11 @@ public class UserOperateIntegralMoneyRequest implements Serializable {
@Range(min = 1, max = 2, message = "请选择正确的类型, 【1 = 增加, 2 = 减少】") @Range(min = 1, max = 2, message = "请选择正确的类型, 【1 = 增加, 2 = 减少】")
private Integer integralType; private Integer integralType;
@ApiModelProperty(value = "积分") @ApiModelProperty(value = "积分支持小数点后3位")
@Min(value = 0) @DecimalMin(value = "0", message = "积分不能小于0")
@Max(value = 999999) @DecimalMax(value = "999999.999", message = "积分不能大于999999.999")
private Integer integralValue; @Digits(integer = 6, fraction = 3, message = "积分最多保留小数点后3位")
private BigDecimal integralValue;
@ApiModelProperty(value = "余额类型, 1 = 增加, 2 = 减少") @ApiModelProperty(value = "余额类型, 1 = 增加, 2 = 减少")
@NotNull @NotNull

View File

@@ -89,8 +89,8 @@ public class UserResponse {
@ApiModelProperty(value = "佣金金额") @ApiModelProperty(value = "佣金金额")
private BigDecimal brokeragePrice; private BigDecimal brokeragePrice;
@ApiModelProperty(value = "用户剩余积分") @ApiModelProperty(value = "用户剩余积分支持小数点后3位")
private Integer integral; private BigDecimal integral;
@ApiModelProperty(value = "用户剩余经验") @ApiModelProperty(value = "用户剩余经验")
private Integer experience; private Integer experience;

View File

@@ -40,6 +40,7 @@ import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -227,11 +228,13 @@ public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserS
*/ */
@Override @Override
public Boolean updateIntegralMoney(UserOperateIntegralMoneyRequest request) { public Boolean updateIntegralMoney(UserOperateIntegralMoneyRequest request) {
if (ObjectUtil.isNull(request.getMoneyValue()) || ObjectUtil.isNull(request.getIntegralValue())) { if (ObjectUtil.isNull(request.getMoneyValue()) && ObjectUtil.isNull(request.getIntegralValue())) {
throw new CrmebException("至少输入一个金额"); throw new CrmebException("至少输入一个金额");
} }
if (request.getMoneyValue().compareTo(BigDecimal.ZERO) < 1 && request.getIntegralValue() <= 0) { boolean moneyValid = request.getMoneyValue() != null && request.getMoneyValue().compareTo(BigDecimal.ZERO) > 0;
throw new CrmebException("修改值不能等小于等于0"); boolean integralValid = request.getIntegralValue() != null && request.getIntegralValue().compareTo(BigDecimal.ZERO) > 0;
if (!moneyValid && !integralValid) {
throw new CrmebException("修改值不能小于等于0");
} }
User user = getById(request.getUid()); User user = getById(request.getUid());
@@ -250,16 +253,16 @@ public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserS
} }
} }
if (request.getIntegralType().equals(2) && request.getIntegralValue() != 0) { if (request.getIntegralType().equals(2) && request.getIntegralValue() != null && request.getIntegralValue().compareTo(BigDecimal.ZERO) > 0) {
BigDecimal integral = user.getIntegral() != null ? user.getIntegral() : BigDecimal.ZERO; BigDecimal integral = user.getIntegral() != null ? user.getIntegral() : BigDecimal.ZERO;
if (integral.subtract(BigDecimal.valueOf(request.getIntegralValue())).compareTo(BigDecimal.ZERO) < 0) { if (integral.subtract(request.getIntegralValue()).compareTo(BigDecimal.ZERO) < 0) {
throw new CrmebException("积分扣减后不能小于0"); throw new CrmebException("积分扣减后不能小于0");
} }
} }
if (request.getIntegralType().equals(1) && request.getIntegralValue() != 0) { if (request.getIntegralType().equals(1) && request.getIntegralValue() != null && request.getIntegralValue().compareTo(BigDecimal.ZERO) > 0) {
BigDecimal integral = user.getIntegral() != null ? user.getIntegral() : BigDecimal.ZERO; BigDecimal integral = user.getIntegral() != null ? user.getIntegral() : BigDecimal.ZERO;
if (integral.add(BigDecimal.valueOf(request.getIntegralValue())).compareTo(BigDecimal.valueOf(99999999)) > 0) { if (integral.add(request.getIntegralValue()).compareTo(new BigDecimal("99999999.999")) > 0) {
throw new CrmebException("积分添加后不能大于99999999"); throw new CrmebException("积分添加后不能大于99999999.999");
} }
} }
@@ -295,28 +298,29 @@ public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserS
} }
} }
// 处理积分 // 处理积分支持小数点后3位
if (request.getIntegralValue() > 0) { if (request.getIntegralValue() != null && request.getIntegralValue().compareTo(BigDecimal.ZERO) > 0) {
BigDecimal integralValue = request.getIntegralValue().setScale(3, RoundingMode.HALF_UP);
// 生成记录 // 生成记录
UserIntegralRecord integralRecord = new UserIntegralRecord(); UserIntegralRecord integralRecord = new UserIntegralRecord();
integralRecord.setUid(user.getUid()); integralRecord.setUid(user.getUid());
integralRecord.setLinkType(IntegralRecordConstants.INTEGRAL_RECORD_LINK_TYPE_SYSTEM); integralRecord.setLinkType(IntegralRecordConstants.INTEGRAL_RECORD_LINK_TYPE_SYSTEM);
integralRecord.setTitle(IntegralRecordConstants.BROKERAGE_RECORD_TITLE_SYSTEM); integralRecord.setTitle(IntegralRecordConstants.BROKERAGE_RECORD_TITLE_SYSTEM);
integralRecord.setIntegral(BigDecimal.valueOf(request.getIntegralValue())); integralRecord.setIntegral(integralValue);
integralRecord.setStatus(IntegralRecordConstants.INTEGRAL_RECORD_STATUS_COMPLETE); integralRecord.setStatus(IntegralRecordConstants.INTEGRAL_RECORD_STATUS_COMPLETE);
if (request.getIntegralType() == 1) {// 增加 if (request.getIntegralType() == 1) {// 增加
integralRecord.setType(IntegralRecordConstants.INTEGRAL_RECORD_TYPE_ADD); integralRecord.setType(IntegralRecordConstants.INTEGRAL_RECORD_TYPE_ADD);
BigDecimal userIntegral = user.getIntegral() != null ? user.getIntegral() : BigDecimal.ZERO; BigDecimal userIntegral = user.getIntegral() != null ? user.getIntegral() : BigDecimal.ZERO;
integralRecord.setBalance(userIntegral.add(BigDecimal.valueOf(request.getIntegralValue())).intValue()); integralRecord.setBalance(userIntegral.add(integralValue).setScale(0, RoundingMode.HALF_UP).intValue());
integralRecord.setMark(StrUtil.format("后台操作增加了{}积分", request.getIntegralValue())); integralRecord.setMark(StrUtil.format("后台操作增加了{}积分", integralValue));
operationIntegral(user.getUid(), BigDecimal.valueOf(request.getIntegralValue()), user.getIntegral(), "add"); operationIntegral(user.getUid(), integralValue, user.getIntegral(), "add");
} else { } else {
integralRecord.setType(IntegralRecordConstants.INTEGRAL_RECORD_TYPE_SUB); integralRecord.setType(IntegralRecordConstants.INTEGRAL_RECORD_TYPE_SUB);
BigDecimal userIntegral = user.getIntegral() != null ? user.getIntegral() : BigDecimal.ZERO; BigDecimal userIntegral = user.getIntegral() != null ? user.getIntegral() : BigDecimal.ZERO;
integralRecord.setBalance(userIntegral.subtract(BigDecimal.valueOf(request.getIntegralValue())).intValue()); integralRecord.setBalance(userIntegral.subtract(integralValue).setScale(0, RoundingMode.HALF_UP).intValue());
integralRecord.setMark(StrUtil.format("后台操作减少了{}积分", request.getIntegralValue())); integralRecord.setMark(StrUtil.format("后台操作减少了{}积分", integralValue));
operationIntegral(user.getUid(), BigDecimal.valueOf(request.getIntegralValue()), user.getIntegral(), "sub"); operationIntegral(user.getUid(), integralValue, user.getIntegral(), "sub");
} }
userIntegralRecordService.save(integralRecord); userIntegralRecordService.save(integralRecord);
} }

View File

@@ -345,8 +345,8 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="积分" required> <el-form-item label="积分" required>
<el-input-number type="text" step-strictly v-model="PointValidateForm.integralValue" :min="0" <el-input-number type="text" v-model="PointValidateForm.integralValue" :precision="3" :step="0.001"
:max="999999"></el-input-number> :min="0" :max="999999.999"></el-input-number>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">