feat: 用户积分管理
This commit is contained in:
+114
@@ -0,0 +1,114 @@
|
||||
package com.budwk.app.zhgh.pointsmall.points.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.zhgh.pointsmall.points.param.PointsMallUserPointsBatchParam;
|
||||
import com.budwk.app.zhgh.pointsmall.points.param.PointsMallUserPointsChangeParam;
|
||||
import com.budwk.app.zhgh.pointsmall.points.param.PointsMallUserPointsLogPageParam;
|
||||
import com.budwk.app.zhgh.pointsmall.points.param.PointsMallUserPointsPageParam;
|
||||
import com.budwk.app.zhgh.pointsmall.points.service.PointsMallUserPointsService;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@IocBean
|
||||
@Ok("json:full")
|
||||
@At("/platform/zhgh/points-mall/points")
|
||||
public class PointsMallUserPointsController {
|
||||
|
||||
@Inject
|
||||
private PointsMallUserPointsService pointsMallUserPointsService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/zhgh/points-mall/points/index.html")
|
||||
@SaCheckPermission("points.mall.points")
|
||||
public void index() {
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("points.mall.points")
|
||||
public Result pageData(PointsMallUserPointsPageParam param) {
|
||||
return Result.success(pointsMallUserPointsService.page(param));
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("points.mall.points")
|
||||
public Result logPage(PointsMallUserPointsLogPageParam param) {
|
||||
if (StrUtil.isBlank(param.getUserId())) {
|
||||
return Result.error("用户ID不能为空");
|
||||
}
|
||||
return Result.success(pointsMallUserPointsService.logPage(param));
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("points.mall.points")
|
||||
public Result userIds(PointsMallUserPointsPageParam param) {
|
||||
return Result.success(pointsMallUserPointsService.userIds(param));
|
||||
}
|
||||
|
||||
@At
|
||||
@SLog(tag = "用户积分管理", msg = "增加积分")
|
||||
@SaCheckPermission("points.mall.points")
|
||||
public Result doGrant(PointsMallUserPointsChangeParam param) {
|
||||
try {
|
||||
pointsMallUserPointsService.grant(param);
|
||||
return Result.success();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@At
|
||||
@SLog(tag = "用户积分管理", msg = "扣减积分")
|
||||
@SaCheckPermission("points.mall.points")
|
||||
public Result doDeduction(PointsMallUserPointsChangeParam param) {
|
||||
try {
|
||||
pointsMallUserPointsService.deduction(param);
|
||||
return Result.success();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@At
|
||||
@SLog(tag = "用户积分管理", msg = "批量增加积分")
|
||||
@SaCheckPermission("points.mall.points")
|
||||
public Result batchGrant(PointsMallUserPointsBatchParam param) {
|
||||
try {
|
||||
pointsMallUserPointsService.batchGrant(param);
|
||||
return Result.success();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@At
|
||||
@SLog(tag = "用户积分管理", msg = "批量扣减积分")
|
||||
@SaCheckPermission("points.mall.points")
|
||||
public Result batchDeduction(PointsMallUserPointsBatchParam param) {
|
||||
try {
|
||||
pointsMallUserPointsService.batchDeduction(param);
|
||||
return Result.success();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@At
|
||||
@SLog(tag = "用户积分管理", msg = "删除积分记录")
|
||||
@SaCheckPermission("points.mall.points")
|
||||
public Result doDelete(@Param("ids") String ids) {
|
||||
List<String> idList = StrUtil.split(ids, ',');
|
||||
if (idList.isEmpty()) {
|
||||
return Result.error("请选择需要删除的数据");
|
||||
}
|
||||
pointsMallUserPointsService.deleteByIds(idList);
|
||||
return Result.success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.budwk.app.zhgh.pointsmall.points.models;
|
||||
|
||||
import com.budwk.app.base.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.nutz.dao.entity.annotation.ColDefine;
|
||||
import org.nutz.dao.entity.annotation.ColType;
|
||||
import org.nutz.dao.entity.annotation.Column;
|
||||
import org.nutz.dao.entity.annotation.Comment;
|
||||
import org.nutz.dao.entity.annotation.Default;
|
||||
import org.nutz.dao.entity.annotation.Name;
|
||||
import org.nutz.dao.entity.annotation.Table;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Table("points_mall_user_points")
|
||||
@Comment("积分商城用户积分")
|
||||
public class PointsMallUserPoints extends BaseModel implements Serializable {
|
||||
|
||||
@Name
|
||||
@Column
|
||||
@Comment("ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
@Comment("用户ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||
private String userId;
|
||||
|
||||
@Column
|
||||
@Comment("总积分")
|
||||
@Default("0")
|
||||
@ColDefine(customType = "decimal(18,2)")
|
||||
private BigDecimal totalPoints;
|
||||
|
||||
@Column
|
||||
@Comment("已用积分")
|
||||
@Default("0")
|
||||
@ColDefine(customType = "decimal(18,2)")
|
||||
private BigDecimal usedPoints;
|
||||
|
||||
@Column
|
||||
@Comment("可用积分")
|
||||
@Default("0")
|
||||
@ColDefine(customType = "decimal(18,2)")
|
||||
private BigDecimal availablePoints;
|
||||
|
||||
@Column
|
||||
@Comment("锁定积分")
|
||||
@Default("0")
|
||||
@ColDefine(customType = "decimal(18,2)")
|
||||
private BigDecimal lockPoints;
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.budwk.app.zhgh.pointsmall.points.models;
|
||||
|
||||
import com.budwk.app.base.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.nutz.dao.entity.annotation.ColDefine;
|
||||
import org.nutz.dao.entity.annotation.ColType;
|
||||
import org.nutz.dao.entity.annotation.Column;
|
||||
import org.nutz.dao.entity.annotation.Comment;
|
||||
import org.nutz.dao.entity.annotation.Default;
|
||||
import org.nutz.dao.entity.annotation.Name;
|
||||
import org.nutz.dao.entity.annotation.Table;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Table("points_mall_user_points_log")
|
||||
@Comment("积分商城用户积分流水")
|
||||
public class PointsMallUserPointsLog extends BaseModel implements Serializable {
|
||||
|
||||
@Name
|
||||
@Column
|
||||
@Comment("ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
@Comment("用户ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||
private String userId;
|
||||
|
||||
@Column
|
||||
@Comment("变动积分")
|
||||
@Default("0")
|
||||
@ColDefine(customType = "decimal(18,2)")
|
||||
private BigDecimal changeAmount;
|
||||
|
||||
@Column
|
||||
@Comment("变动类型")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String changeType;
|
||||
|
||||
@Column
|
||||
@Comment("子订单ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||
private String subOrderId;
|
||||
|
||||
@Column
|
||||
@Comment("消息模板ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String templateId;
|
||||
|
||||
@Column
|
||||
@Comment("备注")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 1000)
|
||||
private String remark;
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.budwk.app.zhgh.pointsmall.points.param;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
public class PointsMallUserPointsBatchParam {
|
||||
|
||||
private String userIds;
|
||||
private BigDecimal points;
|
||||
private String remark;
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.budwk.app.zhgh.pointsmall.points.param;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
public class PointsMallUserPointsChangeParam {
|
||||
|
||||
private String userId;
|
||||
private BigDecimal points;
|
||||
private String remark;
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.budwk.app.zhgh.pointsmall.points.param;
|
||||
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class PointsMallUserPointsLogPageParam extends PageForm {
|
||||
|
||||
private String userId;
|
||||
private String changeType;
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.budwk.app.zhgh.pointsmall.points.param;
|
||||
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class PointsMallUserPointsPageParam extends PageForm {
|
||||
|
||||
private String account;
|
||||
private String realName;
|
||||
private String mobile;
|
||||
private String unitId;
|
||||
private Boolean member;
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.budwk.app.zhgh.pointsmall.points.service;
|
||||
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.zhgh.pointsmall.points.models.PointsMallUserPoints;
|
||||
import com.budwk.app.zhgh.pointsmall.points.param.PointsMallUserPointsBatchParam;
|
||||
import com.budwk.app.zhgh.pointsmall.points.param.PointsMallUserPointsChangeParam;
|
||||
import com.budwk.app.zhgh.pointsmall.points.param.PointsMallUserPointsLogPageParam;
|
||||
import com.budwk.app.zhgh.pointsmall.points.param.PointsMallUserPointsPageParam;
|
||||
import org.nutz.dao.entity.Record;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface PointsMallUserPointsService extends BaseService<PointsMallUserPoints> {
|
||||
|
||||
Pagination<Record> page(PointsMallUserPointsPageParam param);
|
||||
|
||||
Pagination<Record> logPage(PointsMallUserPointsLogPageParam param);
|
||||
|
||||
List<String> userIds(PointsMallUserPointsPageParam param);
|
||||
|
||||
void grant(PointsMallUserPointsChangeParam param);
|
||||
|
||||
void deduction(PointsMallUserPointsChangeParam param);
|
||||
|
||||
void batchGrant(PointsMallUserPointsBatchParam param);
|
||||
|
||||
void batchDeduction(PointsMallUserPointsBatchParam param);
|
||||
|
||||
void deleteByIds(List<String> ids);
|
||||
}
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
package com.budwk.app.zhgh.pointsmall.points.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.zhgh.pointsmall.points.models.PointsMallUserPoints;
|
||||
import com.budwk.app.zhgh.pointsmall.points.models.PointsMallUserPointsLog;
|
||||
import com.budwk.app.zhgh.pointsmall.points.param.PointsMallUserPointsBatchParam;
|
||||
import com.budwk.app.zhgh.pointsmall.points.param.PointsMallUserPointsChangeParam;
|
||||
import com.budwk.app.zhgh.pointsmall.points.param.PointsMallUserPointsLogPageParam;
|
||||
import com.budwk.app.zhgh.pointsmall.points.param.PointsMallUserPointsPageParam;
|
||||
import com.budwk.app.zhgh.pointsmall.points.service.PointsMallUserPointsService;
|
||||
import org.nutz.dao.Chain;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.entity.Record;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.trans.Atom;
|
||||
import org.nutz.trans.Trans;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class PointsMallUserPointsServiceImpl extends BaseServiceImpl<PointsMallUserPoints> implements PointsMallUserPointsService {
|
||||
|
||||
public PointsMallUserPointsServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pagination<Record> page(PointsMallUserPointsPageParam param) {
|
||||
Sql sql = Sqls.create("""
|
||||
select
|
||||
p.id,
|
||||
u.id as userId,
|
||||
u.loginname as account,
|
||||
u.username as realName,
|
||||
u.sex as gender,
|
||||
u.mobile,
|
||||
u.member,
|
||||
u.unitid as unitId,
|
||||
n.name as unitName,
|
||||
ifnull(p.totalPoints, 0) as totalPoints,
|
||||
ifnull(p.usedPoints, 0) as usedPoints,
|
||||
ifnull(p.availablePoints, 0) as availablePoints,
|
||||
ifnull(p.lockPoints, 0) as lockPoints
|
||||
from sys_user u
|
||||
left join points_mall_user_points p on p.userId = u.id and p.delFlag = false
|
||||
left join sys_unit n on n.id = u.unitid
|
||||
$condition
|
||||
""");
|
||||
sql.setCondition(userCondition(param).asc("u.loginname"));
|
||||
return listPageMap(param.getPageNumber(), param.getPageSize(), sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pagination<Record> logPage(PointsMallUserPointsLogPageParam param) {
|
||||
Cnd cnd = Cnd.where("l.delFlag", "=", false);
|
||||
cnd.and("l.userId", "=", param.getUserId());
|
||||
if (StrUtil.isNotBlank(param.getChangeType())) {
|
||||
cnd.and("l.changeType", "=", param.getChangeType());
|
||||
}
|
||||
cnd.desc("l.createdAt");
|
||||
Sql sql = Sqls.create("""
|
||||
select
|
||||
l.*,
|
||||
u.loginname as account,
|
||||
u.username as realName
|
||||
from points_mall_user_points_log l
|
||||
left join sys_user u on u.id = l.userId
|
||||
$condition
|
||||
""");
|
||||
sql.setCondition(cnd);
|
||||
return listPageMap(param.getPageNumber(), param.getPageSize(), sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> userIds(PointsMallUserPointsPageParam param) {
|
||||
Sql sql = Sqls.create("select u.id from sys_user u $condition");
|
||||
sql.setCallback(Sqls.callback.strList());
|
||||
sql.setCondition(userCondition(param).asc("u.loginname"));
|
||||
dao().execute(sql);
|
||||
return sql.getList(String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void grant(PointsMallUserPointsChangeParam param) {
|
||||
BigDecimal points = checkedPoints(param.getPoints());
|
||||
Trans.exec((Atom) () -> change(param.getUserId(), points, "GRANT", param.getRemark()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deduction(PointsMallUserPointsChangeParam param) {
|
||||
BigDecimal points = checkedPoints(param.getPoints()).negate();
|
||||
Trans.exec((Atom) () -> change(param.getUserId(), points, "DEDUCTION", param.getRemark()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void batchGrant(PointsMallUserPointsBatchParam param) {
|
||||
List<String> userIds = splitUserIds(param.getUserIds());
|
||||
BigDecimal points = checkedPoints(param.getPoints());
|
||||
Trans.exec((Atom) () -> userIds.forEach(userId -> change(userId, points, "GRANT", param.getRemark())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void batchDeduction(PointsMallUserPointsBatchParam param) {
|
||||
List<String> userIds = splitUserIds(param.getUserIds());
|
||||
BigDecimal points = checkedPoints(param.getPoints()).negate();
|
||||
Trans.exec((Atom) () -> userIds.forEach(userId -> change(userId, points, "DEDUCTION", param.getRemark())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByIds(List<String> ids) {
|
||||
if (CollUtil.isEmpty(ids)) {
|
||||
return;
|
||||
}
|
||||
dao().update(PointsMallUserPoints.class, Chain.make("delFlag", true), Cnd.where("id", "in", ids));
|
||||
}
|
||||
|
||||
private Cnd userCondition(PointsMallUserPointsPageParam param) {
|
||||
Cnd cnd = Cnd.where("u.delFlag", "=", false).and("u.disabled", "=", false);
|
||||
if (StrUtil.isNotBlank(param.getAccount())) {
|
||||
cnd.and("u.loginname", "like", "%" + param.getAccount() + "%");
|
||||
}
|
||||
if (StrUtil.isNotBlank(param.getRealName())) {
|
||||
cnd.and("u.username", "like", "%" + param.getRealName() + "%");
|
||||
}
|
||||
if (StrUtil.isNotBlank(param.getMobile())) {
|
||||
cnd.and("u.mobile", "=", param.getMobile());
|
||||
}
|
||||
if (StrUtil.isNotBlank(param.getUnitId())) {
|
||||
cnd.and("u.unitid", "=", param.getUnitId());
|
||||
}
|
||||
if (param.getMember() != null) {
|
||||
cnd.and("u.member", "=", param.getMember());
|
||||
}
|
||||
return cnd;
|
||||
}
|
||||
|
||||
private void change(String userId, BigDecimal amount, String changeType, String remark) {
|
||||
if (StrUtil.isBlank(userId)) {
|
||||
throw new IllegalArgumentException("用户ID不能为空");
|
||||
}
|
||||
PointsMallUserPoints points = fetch(Cnd.where("userId", "=", userId).and("delFlag", "=", false));
|
||||
if (points == null && amount.signum() < 0) {
|
||||
throw new IllegalArgumentException("积分记录不存在");
|
||||
}
|
||||
if (points == null) {
|
||||
points = new PointsMallUserPoints();
|
||||
points.setUserId(userId);
|
||||
points.setTotalPoints(amount);
|
||||
points.setUsedPoints(BigDecimal.ZERO);
|
||||
points.setAvailablePoints(amount);
|
||||
points.setLockPoints(BigDecimal.ZERO);
|
||||
insert(points);
|
||||
} else {
|
||||
BigDecimal total = nvl(points.getTotalPoints()).add(amount);
|
||||
BigDecimal available = nvl(points.getAvailablePoints()).add(amount);
|
||||
if (amount.signum() < 0 && available.signum() < 0) {
|
||||
throw new IllegalArgumentException("积分不足,无法扣减");
|
||||
}
|
||||
Chain chain = Chain.make("totalPoints", total).add("availablePoints", available);
|
||||
update(chain, Cnd.where("id", "=", points.getId()));
|
||||
}
|
||||
|
||||
PointsMallUserPointsLog log = new PointsMallUserPointsLog();
|
||||
log.setUserId(userId);
|
||||
log.setChangeAmount(amount.abs());
|
||||
log.setChangeType(changeType);
|
||||
log.setRemark(remark);
|
||||
dao().insert(log);
|
||||
}
|
||||
|
||||
private BigDecimal checkedPoints(BigDecimal points) {
|
||||
if (points == null || points.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
throw new IllegalArgumentException("请输入有效的积分数量");
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
private BigDecimal nvl(BigDecimal value) {
|
||||
return value == null ? BigDecimal.ZERO : value;
|
||||
}
|
||||
|
||||
private List<String> splitUserIds(String userIds) {
|
||||
List<String> list = Arrays.stream(StrUtil.blankToDefault(userIds, "").split(","))
|
||||
.map(String::trim)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.distinct()
|
||||
.toList();
|
||||
if (list.isEmpty()) {
|
||||
throw new IllegalArgumentException("请选择用户");
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="工号">
|
||||
<el-input clearable placeholder="请输入工号" v-model="pageForm.account"></el-input>
|
||||
</search-item>
|
||||
<search-item label="姓名">
|
||||
<el-input clearable placeholder="请输入姓名" v-model="pageForm.realName"></el-input>
|
||||
</search-item>
|
||||
<search-item label="手机号">
|
||||
<el-input clearable placeholder="请输入手机号" v-model="pageForm.mobile"></el-input>
|
||||
</search-item>
|
||||
<search-item label="会员">
|
||||
<el-select clearable placeholder="请选择" v-model="pageForm.member">
|
||||
<el-option :value="true" label="是"></el-option>
|
||||
<el-option :value="false" label="否"></el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card class="mt10" shadow="never">
|
||||
<table-tool label="用户积分管理">
|
||||
<el-button @click="openBatch('grant')" icon="el-icon-plus" size="small" type="primary">批量增加积分</el-button>
|
||||
<el-button @click="openBatch('deduction')" icon="el-icon-minus" size="small" type="danger">批量扣减积分</el-button>
|
||||
<el-button @click="deleteSelected" icon="el-icon-delete" size="small" type="danger">删除积分记录</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" @selection-change="handleSelectionChange" border size="small" style="width:100%" v-loading="tableLoading">
|
||||
<el-table-column type="selection" width="50"></el-table-column>
|
||||
<el-table-column :index="indexMethod" align="center" label="序号" type="index" width="70"></el-table-column>
|
||||
<el-table-column align="center" label="工号" prop="account" width="120"></el-table-column>
|
||||
<el-table-column align="center" label="姓名" prop="realName" width="120"></el-table-column>
|
||||
<el-table-column align="center" label="性别" prop="gender" width="70"></el-table-column>
|
||||
<el-table-column align="center" label="联系方式" prop="mobile" width="130"></el-table-column>
|
||||
<el-table-column align="center" label="组织名称" min-width="180" prop="unitName" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column align="center" label="总分配积分" prop="totalPoints" width="120"></el-table-column>
|
||||
<el-table-column align="center" label="当前可用积分" prop="availablePoints" width="130"></el-table-column>
|
||||
<el-table-column align="center" label="在途锁定积分" prop="lockPoints" width="130"></el-table-column>
|
||||
<el-table-column align="center" fixed="right" label="操作" width="190">
|
||||
<template slot-scope="{row}">
|
||||
<el-button @click="openLog(row)" size="mini" type="text">查看</el-button>
|
||||
<el-button @click="openChange(row, 'grant')" size="mini" type="text">增加</el-button>
|
||||
<el-button @click="openChange(row, 'deduction')" size="mini" type="text">扣减</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination :current-page="pageForm.pageNumber" :page-size="pageForm.pageSize" :page-sizes="[10,20,30,50]" :total="pageForm.totalCount" @current-change="pageChange" @size-change="sizeChange" layout="total, sizes, prev, pager, next" style="margin-top:16px;text-align:right"></el-pagination>
|
||||
</el-card>
|
||||
|
||||
<el-dialog :close-on-click-modal="false" :title="changeType === 'grant' ? '增加积分' : '扣减积分'" :visible.sync="changeDialogVisible" width="520px">
|
||||
<el-form :model="changeForm" label-width="110px" ref="changeForm">
|
||||
<el-form-item label="用户">
|
||||
<el-input disabled :value="currentRow ? currentRow.realName + '(' + currentRow.account + ')' : ''"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="积分">
|
||||
<el-input-number :min="0.01" :precision="2" :step="1" controls-position="right" style="width:100%" v-model="changeForm.points"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input clearable placeholder="请输入备注" v-model="changeForm.remark"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer">
|
||||
<el-button @click="changeDialogVisible=false">取消</el-button>
|
||||
<el-button :loading="submitLoading" @click="submitChange" type="primary">保存</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :close-on-click-modal="false" :title="batchType === 'grant' ? '批量增加积分' : '批量扣减积分'" :visible.sync="batchDialogVisible" width="560px">
|
||||
<el-alert :closable="false" :title="'将对已选择的 ' + multipleSelection.length + ' 个用户执行操作'" show-icon type="warning"></el-alert>
|
||||
<el-form :model="batchForm" class="mt10" label-width="110px">
|
||||
<el-form-item label="积分">
|
||||
<el-input-number :min="0.01" :precision="2" :step="1" controls-position="right" style="width:100%" v-model="batchForm.points"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input clearable placeholder="请输入备注" v-model="batchForm.remark"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer">
|
||||
<el-button @click="batchDialogVisible=false">取消</el-button>
|
||||
<el-button :loading="submitLoading" @click="submitBatch" type="primary">确认</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="logTitle" :visible.sync="logDialogVisible" width="820px">
|
||||
<el-table :data="logData" border size="small" v-loading="logLoading">
|
||||
<el-table-column :index="logIndexMethod" align="center" label="序号" type="index" width="70"></el-table-column>
|
||||
<el-table-column align="center" label="变更积分" prop="changeAmount" width="120"></el-table-column>
|
||||
<el-table-column align="center" label="变更类型" prop="changeType" width="120">
|
||||
<template slot-scope="{row}">
|
||||
<el-tag :type="row.changeType === 'GRANT' ? 'success' : 'danger'" size="small">{{ row.changeType === 'GRANT' ? '增加' : '扣减' }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="备注" min-width="180" prop="remark" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column align="center" label="变更时间" prop="createdAt" width="170">
|
||||
<template slot-scope="{row}">{{ formatTime(row.createdAt) }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination :current-page="logPage.pageNumber" :page-size="logPage.pageSize" :total="logPage.totalCount" @current-change="logPageChange" layout="total, prev, pager, next" style="margin-top:16px;text-align:right"></el-pagination>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
data() {
|
||||
return {
|
||||
tableData: [],
|
||||
tableLoading: false,
|
||||
submitLoading: false,
|
||||
multipleSelection: [],
|
||||
currentRow: null,
|
||||
pageForm: {pageNumber: 1, pageSize: 10, totalCount: 0, account: "", realName: "", mobile: "", member: null},
|
||||
changeDialogVisible: false,
|
||||
changeType: "grant",
|
||||
changeForm: {points: 1, remark: ""},
|
||||
batchDialogVisible: false,
|
||||
batchType: "grant",
|
||||
batchForm: {points: 1, remark: ""},
|
||||
logDialogVisible: false,
|
||||
logLoading: false,
|
||||
logTitle: "积分详情",
|
||||
logData: [],
|
||||
logPage: {pageNumber: 1, pageSize: 10, totalCount: 0, userId: ""}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
indexMethod(index) {
|
||||
return index + 1 + (this.pageForm.pageNumber - 1) * this.pageForm.pageSize
|
||||
},
|
||||
logIndexMethod(index) {
|
||||
return index + 1 + (this.logPage.pageNumber - 1) * this.logPage.pageSize
|
||||
},
|
||||
formatTime(value) {
|
||||
if (!value) return ""
|
||||
return new Date(value).toLocaleString()
|
||||
},
|
||||
doSearch() {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageData()
|
||||
},
|
||||
async pageData() {
|
||||
this.tableLoading = true
|
||||
const res = await this.$axios.post("/platform/zhgh/points-mall/points/pageData", this.pageForm)
|
||||
this.tableLoading = false
|
||||
if (res.code === 0) {
|
||||
this.tableData = res.data.list || []
|
||||
this.pageForm.totalCount = res.data.totalCount || 0
|
||||
} else {
|
||||
this.$message.warning(res.msg)
|
||||
}
|
||||
},
|
||||
pageChange(value) {
|
||||
this.pageForm.pageNumber = value
|
||||
this.pageData()
|
||||
},
|
||||
sizeChange(value) {
|
||||
this.pageForm.pageSize = value
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageData()
|
||||
},
|
||||
handleSelectionChange(value) {
|
||||
this.multipleSelection = value
|
||||
},
|
||||
openChange(row, type) {
|
||||
if (type === "deduction" && Number(row.availablePoints || 0) <= 0) {
|
||||
this.$message.warning("可用积分为0,请勿继续扣减")
|
||||
return
|
||||
}
|
||||
this.currentRow = row
|
||||
this.changeType = type
|
||||
this.changeForm = {points: 1, remark: ""}
|
||||
this.changeDialogVisible = true
|
||||
},
|
||||
async submitChange() {
|
||||
if (!this.changeForm.points || this.changeForm.points <= 0) {
|
||||
this.$message.warning("请输入有效的积分数量")
|
||||
return
|
||||
}
|
||||
this.submitLoading = true
|
||||
const url = this.changeType === "grant" ? "/doGrant" : "/doDeduction"
|
||||
const res = await this.$axios.post("/platform/zhgh/points-mall/points" + url, {
|
||||
userId: this.currentRow.userId,
|
||||
points: this.changeForm.points,
|
||||
remark: this.changeForm.remark
|
||||
})
|
||||
this.submitLoading = false
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
this.changeDialogVisible = false
|
||||
this.pageData()
|
||||
} else {
|
||||
this.$message.warning(res.msg)
|
||||
}
|
||||
},
|
||||
openBatch(type) {
|
||||
if (!this.multipleSelection.length) {
|
||||
this.$message.warning("请至少选择一个用户")
|
||||
return
|
||||
}
|
||||
this.batchType = type
|
||||
this.batchForm = {points: 1, remark: ""}
|
||||
this.batchDialogVisible = true
|
||||
},
|
||||
async submitBatch() {
|
||||
if (!this.batchForm.points || this.batchForm.points <= 0) {
|
||||
this.$message.warning("请输入有效的积分数量")
|
||||
return
|
||||
}
|
||||
this.submitLoading = true
|
||||
const url = this.batchType === "grant" ? "/batchGrant" : "/batchDeduction"
|
||||
const res = await this.$axios.post("/platform/zhgh/points-mall/points" + url, {
|
||||
userIds: this.multipleSelection.map(item => item.userId).join(","),
|
||||
points: this.batchForm.points,
|
||||
remark: this.batchForm.remark
|
||||
})
|
||||
this.submitLoading = false
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
this.batchDialogVisible = false
|
||||
this.pageData()
|
||||
} else {
|
||||
this.$message.warning(res.msg)
|
||||
}
|
||||
},
|
||||
deleteSelected() {
|
||||
const rows = this.multipleSelection.filter(item => item.id)
|
||||
if (!rows.length) {
|
||||
this.$message.warning("请选择已有积分记录的数据")
|
||||
return
|
||||
}
|
||||
this.$confirm("确定删除选中的积分记录吗?", "提示", {
|
||||
type: "warning",
|
||||
callback: async action => {
|
||||
if (action === "confirm") {
|
||||
const res = await this.$axios.post("/platform/zhgh/points-mall/points/doDelete", {ids: rows.map(item => item.id).join(",")})
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
this.pageData()
|
||||
} else {
|
||||
this.$message.warning(res.msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
openLog(row) {
|
||||
this.currentRow = row
|
||||
this.logTitle = "积分详情 - " + row.realName + "(" + row.account + ")"
|
||||
this.logPage = {pageNumber: 1, pageSize: 10, totalCount: 0, userId: row.userId}
|
||||
this.logDialogVisible = true
|
||||
this.logPageData()
|
||||
},
|
||||
async logPageData() {
|
||||
this.logLoading = true
|
||||
const res = await this.$axios.post("/platform/zhgh/points-mall/points/logPage", this.logPage)
|
||||
this.logLoading = false
|
||||
if (res.code === 0) {
|
||||
this.logData = res.data.list || []
|
||||
this.logPage.totalCount = res.data.totalCount || 0
|
||||
} else {
|
||||
this.$message.warning(res.msg)
|
||||
}
|
||||
},
|
||||
logPageChange(value) {
|
||||
this.logPage.pageNumber = value
|
||||
this.logPageData()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
Reference in New Issue
Block a user