feat: 部门管理 - 积分更正

This commit is contained in:
yys 2026-04-20 14:38:57 +08:00
parent db2052b9fd
commit 460cbc2a38
6 changed files with 254 additions and 1 deletions

View File

@ -59,3 +59,12 @@ export function chargeRefundDept(data) {
data: data
})
}
// 部门积分更正
export function editScore(data) {
return request({
url: '/system/dept/edit-score',
method: 'post',
data: data
})
}

View File

@ -82,6 +82,13 @@
@click="handleChargeRefund(scope.row)"
v-hasPermi="['system:dept:chargeRefund']"
>充值/退款</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-s-operation"
@click="handleEditScore(scope.row)"
v-hasPermi="['system:dept:chargeRefund']"
>积分更正</el-button>
<el-button
size="mini"
type="text"
@ -275,6 +282,43 @@
<el-button @click="chargeRefundOpen = false"> </el-button>
</div>
</el-dialog>
<el-dialog
:title="'积分更正 — ' + (editScoreForm.deptName || '')"
:visible.sync="editScoreOpen"
width="520px"
append-to-body
@close="resetEditScore"
>
<el-form ref="editScoreFormRef" :model="editScoreForm" :rules="editScoreRules" label-width="88px">
<el-form-item label="积分" prop="score">
<el-input-number
v-model="editScoreForm.score"
:precision="0"
:step="1"
:min="-100000000"
:max="100000000"
controls-position="right"
class="edit-score-input-number"
placeholder="正数增加负数扣减不能为0"
/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
v-model="editScoreForm.remark"
type="textarea"
:rows="2"
maxlength="50"
show-word-limit
placeholder="必填最多50字"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitEditScore"> </el-button>
<el-button @click="editScoreOpen = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
@ -301,10 +345,13 @@
color: #909399;
line-height: 1.5;
}
.edit-score-input-number {
width: 100%;
}
</style>
<script>
import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild, chargeRefundDept } from "@/api/system/dept"
import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild, chargeRefundDept, editScore } from "@/api/system/dept"
import {
WESTERN_MONEY_MAX,
sanitizeMoneyDigits,
@ -375,6 +422,48 @@ export default {
{ max: 50, message: "备注不能超过50个字符", trigger: "blur" }
]
},
editScoreOpen: false,
editScoreForm: {
deptId: undefined,
deptName: "",
score: undefined,
remark: ""
},
editScoreRules: {
score: [
{ required: true, message: "积分不能为空", trigger: "blur" },
{
validator(rule, value, callback) {
if (value === undefined || value === null || value === "") {
callback(new Error("积分不能为空"))
} else if (!Number.isInteger(Number(value))) {
callback(new Error("积分须为整数"))
} else if (Number(value) === 0) {
callback(new Error("积分不能为0"))
} else if (Number(value) < -100000000 || Number(value) > 100000000) {
callback(new Error("积分须在 -100000000100000000 之间不含0"))
} else {
callback()
}
},
trigger: "blur"
}
],
remark: [
{ required: true, message: "备注不能为空", trigger: "blur" },
{
validator(rule, value, callback) {
if (!value || String(value).trim() === "") {
callback(new Error("备注不能为空"))
} else {
callback()
}
},
trigger: "blur"
},
{ max: 50, message: "备注不能超过50个字符", trigger: "blur" }
]
},
//
rules: {
parentId: [
@ -645,6 +734,51 @@ export default {
})
})
},
resetEditScore() {
this.editScoreForm = {
deptId: undefined,
deptName: "",
score: undefined,
remark: ""
}
this.$nextTick(() => {
if (this.$refs.editScoreFormRef) {
this.$refs.editScoreFormRef.clearValidate()
}
})
},
handleEditScore(row) {
this.editScoreForm = {
deptId: row.deptId,
deptName: row.deptName,
score: undefined,
remark: ""
}
this.editScoreOpen = true
this.$nextTick(() => {
if (this.$refs.editScoreFormRef) {
this.$refs.editScoreFormRef.clearValidate()
}
})
},
submitEditScore() {
this.$refs["editScoreFormRef"].validate(valid => {
if (!valid) {
return
}
const remark = (this.editScoreForm.remark || "").trim()
const data = {
deptId: this.editScoreForm.deptId,
score: this.editScoreForm.score,
remark: remark
}
editScore(data).then(() => {
this.$modal.msgSuccess("操作成功")
this.editScoreOpen = false
this.getList()
})
})
},
/** 删除按钮操作 */
handleDelete(row) {
this.$modal.confirm('是否确认删除名称为"' + row.deptName + '"的数据项?').then(function() {

View File

@ -20,6 +20,7 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.request.system.DeptChargeRefundRequest;
import com.ruoyi.common.core.request.system.DeptPointsCorrectionRequest;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysDeptService;
@ -148,4 +149,18 @@ public class SysDeptController extends BaseController
deptChargeRefundService.chargeOrRefund(request);
return success();
}
/**
* 部门积分更正更新部门积分余额并记流水无订单
* 需具备 {@code system:dept:chargeRefund}且目标部门须通过数据权限校验
*/
@PreAuthorize("@ss.hasPermi('system:dept:chargeRefund')")
@Log(title = "部门管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit-score")
public AjaxResult editScore(@Validated @RequestBody DeptPointsCorrectionRequest request)
{
deptService.checkDeptDataScope(request.getDeptId());
deptService.editScore(request);
return success();
}
}

View File

@ -0,0 +1,31 @@
package com.ruoyi.common.core.request.system;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import lombok.Data;
/**
* 部门积分更正请求仅更新余额与流水不产生充值/退款订单
*/
@Data
public class DeptPointsCorrectionRequest {
/** 目标部门 */
@NotNull(message = "部门不能为空")
private Long deptId;
/**
* 积分变动量可正可负不可为 0 {@code sys_dept.balance} 增减一致
*/
@NotNull(message = "积分不能为空")
@Min(value = -100_000_000, message = "积分不能小于-100000000")
@Max(value = 100_000_000, message = "积分不能超过100000000")
private Long score;
@NotBlank(message = "备注不能为空")
@Size(max = 50, message = "备注不能超过50个字符")
private String remark;
}

View File

@ -4,6 +4,7 @@ import java.math.BigDecimal;
import java.util.List;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.request.system.DeptPointsCorrectionRequest;
/**
* 部门管理 服务层
@ -138,4 +139,9 @@ public interface ISysDeptService
* @param amount 积分减量正数
*/
int subtractDeptBalance(Long deptId, BigDecimal amount);
/**
* 积分更正更新部门余额并写入集团流水手动修改类型不产生充值/退款订单
*/
void editScore(DeptPointsCorrectionRequest request);
}

View File

@ -2,21 +2,28 @@ package com.ruoyi.system.service.impl;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
import com.ruoyi.ai.domain.AiGroupBalanceChangeRecord;
import com.ruoyi.ai.service.IAiGroupBalanceChangeRecordService;
import com.ruoyi.common.EncryptionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.request.system.DeptPointsCorrectionRequest;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.GroupBalanceChangeType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
@ -42,6 +49,9 @@ public class SysDeptServiceImpl implements ISysDeptService
@Resource
private EncryptionService encryptionService;
@Autowired
private IAiGroupBalanceChangeRecordService aiGroupBalanceChangeRecordService;
/**
* 查询部门管理数据
*
@ -339,6 +349,54 @@ public class SysDeptServiceImpl implements ISysDeptService
return deptMapper.subtractDeptBalance(deptId, amount);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void editScore(DeptPointsCorrectionRequest request)
{
Long score = request.getScore();
if (score == null || score == 0L)
{
throw new ServiceException("积分不能为0");
}
SysDept dept = selectDeptById(request.getDeptId());
if (dept == null)
{
throw new ServiceException("部门不存在");
}
BigDecimal delta = BigDecimal.valueOf(score);
int rows;
if (delta.signum() > 0)
{
rows = addDeptBalance(request.getDeptId(), delta);
}
else
{
rows = subtractDeptBalance(request.getDeptId(), delta.abs());
}
if (rows == 0)
{
if (delta.signum() < 0)
{
throw new ServiceException("余额不足或部门不存在");
}
throw new ServiceException("部门不存在或已删除");
}
AiGroupBalanceChangeRecord record = new AiGroupBalanceChangeRecord();
record.setRelationOrderNo(null);
record.setDeptId(request.getDeptId());
record.setType(GroupBalanceChangeType.MANUAL_ADJUST.getCode());
record.setChangeAmount(delta);
record.setResultAmount(dept.getBalance());
record.setRemark(request.getRemark());
record.setCreateBy(SecurityUtils.getUserId());
aiGroupBalanceChangeRecordService.insert(record);
}
/**
* 递归列表
*/