feat(sxsy80): 外部用户 UID 筛选与积分明细展示

User list API accepts uid; admin external pages tighten filters and
integral log maps self-bonus rows via wa_selfbonus_log for display.

Made-with: Cursor
This commit is contained in:
apple
2026-04-27 13:30:05 +08:00
parent 5c4450c417
commit 708bf9af48
7 changed files with 73 additions and 14 deletions

View File

@@ -45,7 +45,7 @@
<div class="container mb10"> <div class="container mb10">
<el-form inline size="small" :model="searchForm" label-width="96px"> <el-form inline size="small" :model="searchForm" label-width="96px">
<el-row> <el-row>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6"> <el-col :xs="24" :sm="12" :md="8" :lg="5" :xl="5">
<el-form-item label="用户ID"> <el-form-item label="用户ID">
<el-input <el-input
v-model="searchForm.uidStr" v-model="searchForm.uidStr"
@@ -56,7 +56,7 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6"> <el-col :xs="24" :sm="12" :md="8" :lg="5" :xl="5">
<el-form-item label="用户名称:"> <el-form-item label="用户名称:">
<el-input <el-input
v-model="searchForm.nickName" v-model="searchForm.nickName"
@@ -67,7 +67,7 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6"> <el-col :xs="24" :sm="12" :md="8" :lg="5" :xl="5">
<el-form-item label="手机号:"> <el-form-item label="手机号:">
<el-input <el-input
v-model="searchForm.phone" v-model="searchForm.phone"
@@ -78,7 +78,7 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6"> <el-col :xs="24" :sm="12" :md="10" :lg="8" :xl="8">
<el-form-item label="时间选择:"> <el-form-item label="时间选择:">
<el-date-picker <el-date-picker
v-model="timeVal" v-model="timeVal"
@@ -90,11 +90,12 @@
range-separator="" range-separator=""
start-placeholder="开始日期" start-placeholder="开始日期"
end-placeholder="结束日期" end-placeholder="结束日期"
class="date-range-width"
@change="onchangeTime" @change="onchangeTime"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6"> <el-col :xs="24" :sm="12" :md="6" :lg="4" :xl="4">
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button> <el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>
<el-button @click="handleReset">重置</el-button> <el-button @click="handleReset">重置</el-button>
@@ -119,7 +120,6 @@
<span>{{ scope.row.nickName || '-' }}</span> <span>{{ scope.row.nickName || '-' }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="title" label="标题" min-width="150" show-overflow-tooltip />
<el-table-column label="积分变动" min-width="100"> <el-table-column label="积分变动" min-width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag :type="scope.row.type === 1 ? 'success' : 'danger'" size="small"> <el-tag :type="scope.row.type === 1 ? 'success' : 'danger'" size="small">
@@ -356,7 +356,10 @@ export default {
text-align: right; text-align: right;
} }
.filter-input { .filter-input {
width: 180px; width: 150px;
}
.date-range-width {
width: 350px;
} }
.overview-card--all .hint-text { .overview-card--all .hint-text {
display: block; display: block;

View File

@@ -5,7 +5,7 @@
<div class="container"> <div class="container">
<el-form inline size="small" :model="userFrom" label-width="90px"> <el-form inline size="small" :model="userFrom" label-width="90px">
<el-row> <el-row>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6"> <el-col :xs="24" :sm="12" :md="6" :lg="5" :xl="5">
<el-form-item label="用户搜索:"> <el-form-item label="用户搜索:">
<el-input <el-input
v-model="userFrom.keywords" v-model="userFrom.keywords"
@@ -16,7 +16,19 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6"> <el-col :xs="24" :sm="12" :md="6" :lg="5" :xl="5">
<el-form-item label="用户ID">
<el-input-number
v-model="userFrom.uid"
:min="1"
:controls="false"
placeholder="请输入用户ID"
class="selWidth"
@keyup.enter.native="seachList"
/>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="10" :lg="8" :xl="8">
<el-form-item label="时间选择:"> <el-form-item label="时间选择:">
<el-date-picker <el-date-picker
v-model="timeVal" v-model="timeVal"
@@ -27,11 +39,12 @@
range-separator="" range-separator=""
start-placeholder="开始日期" start-placeholder="开始日期"
end-placeholder="结束日期" end-placeholder="结束日期"
class="date-range-width"
@change="onchangeTime" @change="onchangeTime"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6"> <el-col :xs="24" :sm="12" :md="6" :lg="5" :xl="5">
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" size="small" @click="seachList">搜索</el-button> <el-button type="primary" icon="el-icon-search" size="small" @click="seachList">搜索</el-button>
<el-button size="small" @click="handleReset">重置</el-button> <el-button size="small" @click="handleReset">重置</el-button>
@@ -114,6 +127,7 @@ export default {
}, },
userFrom: { userFrom: {
keywords: '', keywords: '',
uid: null,
dateLimit: '', dateLimit: '',
page: 1, page: 1,
limit: 15, limit: 15,
@@ -129,6 +143,7 @@ export default {
this.listLoading = true; this.listLoading = true;
const params = { ...this.userFrom }; const params = { ...this.userFrom };
if (!params.keywords) delete params.keywords; if (!params.keywords) delete params.keywords;
if (!params.uid) delete params.uid;
if (!params.dateLimit) delete params.dateLimit; if (!params.dateLimit) delete params.dateLimit;
getExternalUserList(params) getExternalUserList(params)
@@ -146,7 +161,7 @@ export default {
this.getList(); this.getList();
}, },
handleReset() { handleReset() {
this.userFrom = { keywords: '', dateLimit: '', page: 1, limit: 15 }; this.userFrom = { keywords: '', uid: null, dateLimit: '', page: 1, limit: 15 };
this.timeVal = []; this.timeVal = [];
this.getList(); this.getList();
}, },
@@ -201,6 +216,9 @@ export default {
text-align: right; text-align: right;
} }
.selWidth { .selWidth {
width: 200px; width: 160px;
}
.date-range-width {
width: 350px;
} }
</style> </style>

View File

@@ -37,6 +37,9 @@ public class UserSearchRequest implements Serializable {
@ApiModelProperty(value = "关键字") @ApiModelProperty(value = "关键字")
private String keywords; private String keywords;
@ApiModelProperty(value = "用户uid")
private Integer uid;
@ApiModelProperty(value = "时间") @ApiModelProperty(value = "时间")
private String dateLimit; private String dateLimit;

View File

@@ -10,6 +10,7 @@ import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
/** /**
@@ -51,7 +52,7 @@ public class UserIntegralRecordResponse implements Serializable {
private String title; private String title;
@ApiModelProperty(value = "积分") @ApiModelProperty(value = "积分")
private Integer integral; private BigDecimal integral;
@ApiModelProperty(value = "剩余") @ApiModelProperty(value = "剩余")
private Integer balance; private Integer balance;

View File

@@ -19,9 +19,11 @@ import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import com.zbkj.common.utils.CrmebDateUtil; import com.zbkj.common.utils.CrmebDateUtil;
import com.zbkj.common.vo.DateLimitUtilVo; import com.zbkj.common.vo.DateLimitUtilVo;
import com.zbkj.common.model.consignment.WaSelfbonusLog;
import com.zbkj.common.model.user.User; import com.zbkj.common.model.user.User;
import com.zbkj.common.model.user.UserIntegralRecord; import com.zbkj.common.model.user.UserIntegralRecord;
import com.zbkj.service.dao.UserIntegralRecordDao; import com.zbkj.service.dao.UserIntegralRecordDao;
import com.zbkj.service.dao.consignment.WaSelfbonusLogDao;
import com.zbkj.service.service.UserIntegralRecordService; import com.zbkj.service.service.UserIntegralRecordService;
import com.zbkj.service.service.UserService; import com.zbkj.service.service.UserService;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -33,7 +35,9 @@ 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.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -62,6 +66,9 @@ public class UserIntegralRecordServiceImpl extends ServiceImpl<UserIntegralRecor
@Autowired @Autowired
private UserService userService; private UserService userService;
@Autowired
private WaSelfbonusLogDao waSelfbonusLogDao;
@Autowired @Autowired
private TransactionTemplate transactionTemplate; private TransactionTemplate transactionTemplate;
@@ -155,7 +162,8 @@ public class UserIntegralRecordServiceImpl extends ServiceImpl<UserIntegralRecor
LambdaQueryWrapper<UserIntegralRecord> lqw = Wrappers.lambdaQuery(); LambdaQueryWrapper<UserIntegralRecord> lqw = Wrappers.lambdaQuery();
lqw.select(UserIntegralRecord::getId, UserIntegralRecord::getTitle, UserIntegralRecord::getBalance, UserIntegralRecord::getIntegral, lqw.select(UserIntegralRecord::getId, UserIntegralRecord::getTitle, UserIntegralRecord::getBalance, UserIntegralRecord::getIntegral,
UserIntegralRecord::getMark, UserIntegralRecord::getUid, UserIntegralRecord::getUpdateTime, UserIntegralRecord::getMark, UserIntegralRecord::getUid, UserIntegralRecord::getUpdateTime,
UserIntegralRecord::getType, UserIntegralRecord::getLinkType, UserIntegralRecord::getStatus, UserIntegralRecord::getCreateTime); UserIntegralRecord::getType, UserIntegralRecord::getLinkType, UserIntegralRecord::getStatus, UserIntegralRecord::getCreateTime,
UserIntegralRecord::getWaSelfbonusLogid);
lqw.eq(UserIntegralRecord::getStatus, IntegralRecordConstants.INTEGRAL_RECORD_STATUS_COMPLETE); lqw.eq(UserIntegralRecord::getStatus, IntegralRecordConstants.INTEGRAL_RECORD_STATUS_COMPLETE);
String nameKey = StrUtil.isNotBlank(request.getNickName()) ? request.getNickName() : request.getKeywords(); String nameKey = StrUtil.isNotBlank(request.getNickName()) ? request.getNickName() : request.getKeywords();
@@ -213,9 +221,28 @@ public class UserIntegralRecordServiceImpl extends ServiceImpl<UserIntegralRecor
if (CollUtil.isEmpty(list)) { if (CollUtil.isEmpty(list)) {
return CommonPage.copyPageInfo(page, CollUtil.newArrayList()); return CommonPage.copyPageInfo(page, CollUtil.newArrayList());
} }
List<Integer> selfBonusLogIds = list.stream()
.map(UserIntegralRecord::getWaSelfbonusLogid)
.filter(ObjectUtil::isNotNull)
.distinct()
.collect(Collectors.toList());
Map<Integer, BigDecimal> selfBonusIntegralMap = new HashMap<>();
if (CollUtil.isNotEmpty(selfBonusLogIds)) {
waSelfbonusLogDao.selectBatchIds(selfBonusLogIds).forEach(log -> {
if (ObjectUtil.isNotNull(log) && ObjectUtil.isNotNull(log.getMoney())) {
selfBonusIntegralMap.put(log.getId(), log.getMoney().multiply(new BigDecimal("0.5")).setScale(3, RoundingMode.DOWN));
}
});
}
List<UserIntegralRecordResponse> responseList = list.stream().map(i -> { List<UserIntegralRecordResponse> responseList = list.stream().map(i -> {
UserIntegralRecordResponse response = new UserIntegralRecordResponse(); UserIntegralRecordResponse response = new UserIntegralRecordResponse();
BeanUtils.copyProperties(i, response); BeanUtils.copyProperties(i, response);
if (ObjectUtil.isNotNull(i.getWaSelfbonusLogid())) {
BigDecimal convertedIntegral = selfBonusIntegralMap.get(i.getWaSelfbonusLogid());
if (ObjectUtil.isNotNull(convertedIntegral)) {
response.setIntegral(convertedIntegral);
}
}
// 获取用户昵称 // 获取用户昵称
User user = userService.getById(i.getUid()); User user = userService.getById(i.getUid());
if (ObjectUtil.isNotNull(user)) { if (ObjectUtil.isNotNull(user)) {

View File

@@ -142,6 +142,10 @@ public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserS
map.put("isPromoter", request.getIsPromoter() ? 1 : 0); map.put("isPromoter", request.getIsPromoter() ? 1 : 0);
} }
if (request.getUid() != null) {
map.put("uid", request.getUid());
}
if (StrUtil.isNotBlank(request.getGroupId())) { if (StrUtil.isNotBlank(request.getGroupId())) {
List<Integer> groupIdList = CrmebUtil.stringToArray(request.getGroupId()); List<Integer> groupIdList = CrmebUtil.stringToArray(request.getGroupId());
map.put("groupIdList", groupIdList); map.put("groupIdList", groupIdList);

View File

@@ -29,6 +29,9 @@
<if test="isPromoter != null and isPromoter !='' or isPromoter == 0 "> <if test="isPromoter != null and isPromoter !='' or isPromoter == 0 ">
and u.is_promoter = #{isPromoter} and u.is_promoter = #{isPromoter}
</if> </if>
<if test="uid != null">
and u.uid = #{uid}
</if>
<if test="groupId != null and groupId !='' "> <if test="groupId != null and groupId !='' ">
and u.group_id in and u.group_id in
<foreach item="group_id" collection="groupIdList" open="(" separator="," close=")"> <foreach item="group_id" collection="groupIdList" open="(" separator="," close=")">