commit
This commit is contained in:
@@ -22,7 +22,7 @@ import java.util.List;
|
|||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@Table("sys_user")
|
@Table("")
|
||||||
@TableMeta("{'mysql-charset':'utf8mb4'}")
|
@TableMeta("{'mysql-charset':'utf8mb4'}")
|
||||||
@TableIndexes({@Index(name = "INDEX_SYS_USER_LOGINNAMAE", fields = {"loginname"})})
|
@TableIndexes({@Index(name = "INDEX_SYS_USER_LOGINNAMAE", fields = {"loginname"})})
|
||||||
public class Sys_user extends BaseModel implements Serializable {
|
public class Sys_user extends BaseModel implements Serializable {
|
||||||
|
|||||||
@@ -67,10 +67,15 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
|
|||||||
private static Map<String, String> unitIdNameMap;
|
private static Map<String, String> unitIdNameMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新人员数据时仅按在职状态增加会员,不因状态不匹配取消已有会员。
|
* 全量更新时,以下在职状态会自动设置为会员。
|
||||||
*/
|
*/
|
||||||
private static final Set<String> MEMBER_USER_STATES = Set.of("在岗", "切线", "免职", "驻村", "援疆(藏)");
|
private static final Set<String> MEMBER_USER_STATES = Set.of("在岗", "切线", "免职", "驻村", "援疆(藏)");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全量更新时,以下在职状态会自动取消会员身份和会员角色。
|
||||||
|
*/
|
||||||
|
private static final Set<String> REMOVE_MEMBER_USER_STATES = Set.of("离退休", "离世", "离校");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字段映射类,用于缓存反射结果
|
* 字段映射类,用于缓存反射结果
|
||||||
*/
|
*/
|
||||||
@@ -152,6 +157,24 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
|
|||||||
return StrUtil.isNotBlank(userState) && MEMBER_USER_STATES.contains(userState);
|
return StrUtil.isNotBlank(userState) && MEMBER_USER_STATES.contains(userState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断本次人员状态是否需要取消会员身份。
|
||||||
|
*/
|
||||||
|
private boolean shouldRemoveMember(String userState) {
|
||||||
|
return StrUtil.isNotBlank(userState) && REMOVE_MEMBER_USER_STATES.contains(userState);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人员源数据只负责基础人员信息,会员缴费及会费类字段由会员业务维护。
|
||||||
|
* 更新已有人员时置空这些字段,配合 updateIgnoreNull 避免把已维护的数据覆盖为空或默认值。
|
||||||
|
*/
|
||||||
|
private void ignoreMemberBusinessFields(Sys_user user) {
|
||||||
|
user.setMemberFeePaid(null);
|
||||||
|
user.setMemberTime(null);
|
||||||
|
user.setPreparationMemberFee(null);
|
||||||
|
user.setContractMemberFee(null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量补充指定角色,已存在该角色的用户不重复插入。
|
* 批量补充指定角色,已存在该角色的用户不重复插入。
|
||||||
*/
|
*/
|
||||||
@@ -190,6 +213,26 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
|
|||||||
return insertCount;
|
return insertCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量取消会员身份并删除会员角色,仅用于全量更新中明确需要退会的人员状态。
|
||||||
|
*/
|
||||||
|
private int removeMemberAndRole(List<String> userIds, Sys_role memberRole) {
|
||||||
|
if (Lang.isEmpty(userIds) || memberRole == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
List<String> distinctUserIds = userIds.stream().filter(Objects::nonNull).distinct().toList();
|
||||||
|
if (distinctUserIds.isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int removeRoleCount = 0;
|
||||||
|
for (List<String> userIdBatch : ListUtil.split(distinctUserIds, 500)) {
|
||||||
|
dao.update(Sys_user.class, Chain.make("member", false), Cnd.where("id", "in", userIdBatch));
|
||||||
|
removeRoleCount += dao.clear(Sys_user_role.class,
|
||||||
|
Cnd.where("roleId", "=", memberRole.getId()).and("userId", "in", userIdBatch));
|
||||||
|
}
|
||||||
|
return removeRoleCount;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全量更新用户数据
|
* 全量更新用户数据
|
||||||
*
|
*
|
||||||
@@ -241,6 +284,7 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
|
|||||||
Sys_user u = new Sys_user();
|
Sys_user u = new Sys_user();
|
||||||
BeanUtils.copyProperties(source, u);
|
BeanUtils.copyProperties(source, u);
|
||||||
boolean addMember = shouldAddMember(source.getUserState());
|
boolean addMember = shouldAddMember(source.getUserState());
|
||||||
|
boolean removeMember = shouldRemoveMember(source.getUserState());
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
// 新增用户,初始化数据
|
// 新增用户,初始化数据
|
||||||
@@ -250,20 +294,23 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
|
|||||||
String salt = R.UU32();
|
String salt = R.UU32();
|
||||||
u.setSalt(salt);
|
u.setSalt(salt);
|
||||||
u.setPassword(PwdUtil.getPassword(PwdUtil.generate(12), salt));
|
u.setPassword(PwdUtil.getPassword(PwdUtil.generate(12), salt));
|
||||||
// 更新人员数据只增加会员,不因状态不匹配取消已有会员。
|
|
||||||
if (addMember) {
|
if (addMember) {
|
||||||
u.setMember(true);
|
u.setMember(true);
|
||||||
addMemberUserIds.add(u.getId());
|
addMemberUserIds.add(u.getId());
|
||||||
|
} else if (removeMember) {
|
||||||
|
u.setMember(false);
|
||||||
}
|
}
|
||||||
needInitUserList.add(u);
|
needInitUserList.add(u);
|
||||||
} else {
|
} else {
|
||||||
// 修改现有用户 - 根据工号判断是原有的人
|
// 修改现有用户 - 根据工号判断是原有的人
|
||||||
u.setId(user.getId());
|
u.setId(user.getId());
|
||||||
// 保持原有会员身份不变
|
ignoreMemberBusinessFields(u);
|
||||||
// 更新人员数据只增加会员,不因状态不匹配取消已有会员。
|
|
||||||
if (addMember) {
|
if (addMember) {
|
||||||
u.setMember(true);
|
u.setMember(true);
|
||||||
addMemberUserIds.add(user.getId());
|
addMemberUserIds.add(user.getId());
|
||||||
|
} else if (removeMember) {
|
||||||
|
u.setMember(false);
|
||||||
|
removeMemberUserIds.add(user.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
needDoUpdateList.add(u);
|
needDoUpdateList.add(u);
|
||||||
@@ -362,7 +409,10 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
|
|||||||
return "更新失败: " + e.getMessage();
|
return "更新失败: " + e.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 全量更新后统一补齐角色:所有人补公共角色,所有会员补会员角色;仅新增缺失角色,不删除、不重复插入。
|
int memberRoleRemoveCount = removeMemberAndRole(removeMemberUserIds, memberRole);
|
||||||
|
log.info("全量更新取消会员完成,取消会员{}个,删除会员角色{}个", removeMemberUserIds.stream().filter(Objects::nonNull).distinct().count(), memberRoleRemoveCount);
|
||||||
|
|
||||||
|
// 全量更新后统一补齐角色:所有人补公共角色,所有会员补会员角色;仅新增缺失角色,不重复插入。
|
||||||
List<Sys_user> latestUsers = dao.query(Sys_user.class, Cnd.NEW());
|
List<Sys_user> latestUsers = dao.query(Sys_user.class, Cnd.NEW());
|
||||||
List<String> allUserIds = latestUsers.stream().map(Sys_user::getId).filter(Objects::nonNull).toList();
|
List<String> allUserIds = latestUsers.stream().map(Sys_user::getId).filter(Objects::nonNull).toList();
|
||||||
List<String> memberUserIds = latestUsers.stream()
|
List<String> memberUserIds = latestUsers.stream()
|
||||||
@@ -435,6 +485,8 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
|
|||||||
log.info("全量更新用户数据完成,耗时: {} 毫秒", (endTime - startTime));
|
log.info("全量更新用户数据完成,耗时: {} 毫秒", (endTime - startTime));
|
||||||
|
|
||||||
return "更新完成: 新增用户 " + needInitUserList.size() + " 个, 更新用户 " + needDoUpdateList.size()
|
return "更新完成: 新增用户 " + needInitUserList.size() + " 个, 更新用户 " + needDoUpdateList.size()
|
||||||
|
+ " 个, 取消会员 " + removeMemberUserIds.stream().filter(Objects::nonNull).distinct().count()
|
||||||
|
+ " 个, 删除会员角色 " + memberRoleRemoveCount
|
||||||
+ " 个, 新增公共角色 " + publicRoleAddCount + " 个, 新增会员角色 " + memberRoleAddCount + " 个";
|
+ " 个, 新增公共角色 " + publicRoleAddCount + " 个, 新增会员角色 " + memberRoleAddCount + " 个";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -196,7 +196,8 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
|
|||||||
// 特殊处理 根据身份证号获取性别和出生年月
|
// 特殊处理 根据身份证号获取性别和出生年月
|
||||||
switch (mapping.field.getName()) {
|
switch (mapping.field.getName()) {
|
||||||
case "idCard" -> {
|
case "idCard" -> {
|
||||||
// 设置出生年月
|
// 保存证件号码,并尝试根据身份证号解析出生年月;解析失败只影响生日字段。
|
||||||
|
mapping.field.set(sysUser, value);
|
||||||
if (StrUtil.isNotBlank(value)) {
|
if (StrUtil.isNotBlank(value)) {
|
||||||
try {
|
try {
|
||||||
sysUser.setBirthday(IdcardUtil.getBirthDate(value));
|
sysUser.setBirthday(IdcardUtil.getBirthDate(value));
|
||||||
|
|||||||
+5
-3
@@ -53,7 +53,7 @@ public class MemberInfoBoardController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return 今年会员数、未缴费会员数和去年的会员数
|
* @return 今年职工数、缴费会员数、未缴费会员数和去年的会员数
|
||||||
*/
|
*/
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission(value = {"member.info.board", "h5.member.info.board"}, mode = SaMode.OR)
|
@SaCheckPermission(value = {"member.info.board", "h5.member.info.board"}, mode = SaMode.OR)
|
||||||
@@ -111,7 +111,7 @@ public class MemberInfoBoardController {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 各工会会员数
|
* 各工会职工数及缴费会员数
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -123,7 +123,9 @@ public class MemberInfoBoardController {
|
|||||||
un.name as unionname,
|
un.name as unionname,
|
||||||
un.unionCode,
|
un.unionCode,
|
||||||
( SELECT count( 1 ) FROM vw_user WHERE member = 1 and unionId = un.id ) `value`,
|
( SELECT count( 1 ) FROM vw_user WHERE member = 1 and unionId = un.id ) `value`,
|
||||||
( SELECT count( 1 ) FROM vw_user u LEFT JOIN sys_user su ON su.id = u.id WHERE u.member = 1 and u.unionId = un.id and (su.memberFeePaid = 0 or su.memberFeePaid is null) ) unpaidValue
|
( SELECT count( 1 ) FROM vw_user u LEFT JOIN sys_user su ON su.id = u.id WHERE u.member = 1 and u.unionId = un.id and (su.memberFeePaid = 0 or su.memberFeePaid is null) ) unpaidValue,
|
||||||
|
( SELECT count( 1 ) FROM vw_user WHERE member = 1 and unionId = un.id )
|
||||||
|
- ( SELECT count( 1 ) FROM vw_user u LEFT JOIN sys_user su ON su.id = u.id WHERE u.member = 1 and u.unionId = un.id and (su.memberFeePaid = 0 or su.memberFeePaid is null) ) paidValue
|
||||||
FROM
|
FROM
|
||||||
sys_union un
|
sys_union un
|
||||||
ORDER BY
|
ORDER BY
|
||||||
|
|||||||
+5
@@ -1,6 +1,7 @@
|
|||||||
package com.budwk.app.zhgh.staffmanage.member.controller.info;
|
package com.budwk.app.zhgh.staffmanage.member.controller.info;
|
||||||
|
|
||||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckRole;
|
||||||
import cn.dev33.satoken.annotation.SaMode;
|
import cn.dev33.satoken.annotation.SaMode;
|
||||||
import cn.hutool.core.util.DesensitizedUtil;
|
import cn.hutool.core.util.DesensitizedUtil;
|
||||||
import com.alibaba.excel.EasyExcel;
|
import com.alibaba.excel.EasyExcel;
|
||||||
@@ -104,6 +105,7 @@ public class MemberInfoGroupController {
|
|||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission("member.info.group")
|
@SaCheckPermission("member.info.group")
|
||||||
|
@SaCheckRole(value = {"SYSADMIN", "SCHOOL_UNION_ADMIN", "SCHOOL_UNION_CHAIRMAN"}, mode = SaMode.OR)
|
||||||
public Result toggleMemberFeePaid(String userId) {
|
public Result toggleMemberFeePaid(String userId) {
|
||||||
try {
|
try {
|
||||||
return Result.success(memberInfoService.toggleMemberFeePaid(userId));
|
return Result.success(memberInfoService.toggleMemberFeePaid(userId));
|
||||||
@@ -115,6 +117,7 @@ public class MemberInfoGroupController {
|
|||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission("member.info.group")
|
@SaCheckPermission("member.info.group")
|
||||||
|
@SaCheckRole(value = {"SYSADMIN", "SCHOOL_UNION_ADMIN", "SCHOOL_UNION_CHAIRMAN"}, mode = SaMode.OR)
|
||||||
public Result batchSetMemberFeePaid(MemberInfoPageForm pageForm) {
|
public Result batchSetMemberFeePaid(MemberInfoPageForm pageForm) {
|
||||||
try {
|
try {
|
||||||
return Result.success(memberInfoService.batchSetMemberFeePaid(pageForm));
|
return Result.success(memberInfoService.batchSetMemberFeePaid(pageForm));
|
||||||
@@ -128,6 +131,7 @@ public class MemberInfoGroupController {
|
|||||||
@At
|
@At
|
||||||
@Ok("void")
|
@Ok("void")
|
||||||
@SaCheckPermission("member.info.group")
|
@SaCheckPermission("member.info.group")
|
||||||
|
@SaCheckRole(value = {"SYSADMIN", "SCHOOL_UNION_ADMIN", "SCHOOL_UNION_CHAIRMAN"}, mode = SaMode.OR)
|
||||||
public void downloadMemberTemplate(HttpServletResponse response) {
|
public void downloadMemberTemplate(HttpServletResponse response) {
|
||||||
try {
|
try {
|
||||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
@@ -147,6 +151,7 @@ public class MemberInfoGroupController {
|
|||||||
@At
|
@At
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
@SaCheckPermission("member.info.group")
|
@SaCheckPermission("member.info.group")
|
||||||
|
@SaCheckRole(value = {"SYSADMIN", "SCHOOL_UNION_ADMIN", "SCHOOL_UNION_CHAIRMAN"}, mode = SaMode.OR)
|
||||||
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
|
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
|
||||||
public Result importMember(TempFile file, Boolean isFlag) {
|
public Result importMember(TempFile file, Boolean isFlag) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public interface MemberInfoService extends BaseService<Sys_user> {
|
|||||||
/**
|
/**
|
||||||
* 获取会员看板会员数统计数据
|
* 获取会员看板会员数统计数据
|
||||||
*
|
*
|
||||||
* @return memberNum 会员总数、unpaidMemberNum 未缴费会员数、lastYearMemberNum 去年会员数
|
* @return memberNum 会员总数、paidMemberNum 缴费会员数、unpaidMemberNum 未缴费会员数、lastYearMemberNum 去年会员数
|
||||||
*/
|
*/
|
||||||
NutMap getBoardMemberNumber();
|
NutMap getBoardMemberNumber();
|
||||||
|
|
||||||
|
|||||||
+3
@@ -275,9 +275,12 @@ public class MemberInfoServiceImpl extends BaseServiceImpl<Sys_user> implements
|
|||||||
int memberNum = count(Sqls.create("select count(1) from sys_user where member = 1"));
|
int memberNum = count(Sqls.create("select count(1) from sys_user where member = 1"));
|
||||||
// 空值按未缴费处理,保持会员列表中“是否缴费”的展示口径一致。
|
// 空值按未缴费处理,保持会员列表中“是否缴费”的展示口径一致。
|
||||||
int unpaidMemberNum = count(Sqls.create("select count(1) from sys_user where member = 1 and (memberFeePaid = 0 or memberFeePaid is null)"));
|
int unpaidMemberNum = count(Sqls.create("select count(1) from sys_user where member = 1 and (memberFeePaid = 0 or memberFeePaid is null)"));
|
||||||
|
// 缴费会员数用于会员看板展示,口径为当前会员总数减去未缴费会员数。
|
||||||
|
int paidMemberNum = memberNum - unpaidMemberNum;
|
||||||
int lastYearMemberNum = count(Sqls.create("select count(1) from member_history where year = year(now()) -1 "));
|
int lastYearMemberNum = count(Sqls.create("select count(1) from member_history where year = year(now()) -1 "));
|
||||||
return NutMap.NEW()
|
return NutMap.NEW()
|
||||||
.addv("memberNum", memberNum)
|
.addv("memberNum", memberNum)
|
||||||
|
.addv("paidMemberNum", paidMemberNum)
|
||||||
.addv("unpaidMemberNum", unpaidMemberNum)
|
.addv("unpaidMemberNum", unpaidMemberNum)
|
||||||
.addv("lastYearMemberNum", lastYearMemberNum);
|
.addv("lastYearMemberNum", lastYearMemberNum);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -292,9 +292,9 @@ layout("/layouts/platform.html"){
|
|||||||
<div class="dashboard">
|
<div class="dashboard">
|
||||||
<!-- 顶部四个统计卡片 - 高度固定200px -->
|
<!-- 顶部四个统计卡片 - 高度固定200px -->
|
||||||
<div class="card stats-card">
|
<div class="card stats-card">
|
||||||
<div class="card-title">会员数/未缴费人数</div>
|
<div class="card-title">职工数/会员数</div>
|
||||||
<div class="stat-value" v-loading="loading.memberNumber">
|
<div class="stat-value" v-loading="loading.memberNumber">
|
||||||
{{memberNumberData.memberNum}} / {{memberNumberData.unpaidMemberNum}}
|
{{memberNumberData.memberNum}} / {{memberNumberData.paidMemberNum}}
|
||||||
<span style="font-size: 14px"> 人</span>
|
<span style="font-size: 14px"> 人</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="stat-meta" v-loading="loading.memberNumber">-->
|
<!-- <div class="stat-meta" v-loading="loading.memberNumber">-->
|
||||||
@@ -322,7 +322,7 @@ layout("/layouts/platform.html"){
|
|||||||
<div class="content-left">
|
<div class="content-left">
|
||||||
<!-- 工会会员数图表 -->
|
<!-- 工会会员数图表 -->
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-title">工会会员数/未缴费数</div>
|
<div class="card-title">工会职工数/会员数</div>
|
||||||
<div class="chart-container" id="unionMemberChart" v-loading="loading.unionMember"></div>
|
<div class="chart-container" id="unionMemberChart" v-loading="loading.unionMember"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -356,7 +356,7 @@ layout("/layouts/platform.html"){
|
|||||||
align="center"
|
align="center"
|
||||||
header-align="center"
|
header-align="center"
|
||||||
label="会员人数"
|
label="会员人数"
|
||||||
prop="value"
|
prop="paidValue"
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
sortable
|
sortable
|
||||||
width="120px"
|
width="120px"
|
||||||
@@ -392,6 +392,7 @@ layout("/layouts/platform.html"){
|
|||||||
},
|
},
|
||||||
memberNumberData: {
|
memberNumberData: {
|
||||||
memberNum: "--",
|
memberNum: "--",
|
||||||
|
paidMemberNum: "--",
|
||||||
unpaidMemberNum: "--",
|
unpaidMemberNum: "--",
|
||||||
lastYearMemberNum: "--",
|
lastYearMemberNum: "--",
|
||||||
ratio: "0.0%",
|
ratio: "0.0%",
|
||||||
@@ -412,11 +413,13 @@ layout("/layouts/platform.html"){
|
|||||||
this.$axios.post("/platform/member/info/board/memberNumber").then((resp) => {
|
this.$axios.post("/platform/member/info/board/memberNumber").then((resp) => {
|
||||||
if (resp.code === 0) {
|
if (resp.code === 0) {
|
||||||
const {
|
const {
|
||||||
data: { memberNum, unpaidMemberNum, lastYearMemberNum }
|
data: { memberNum, paidMemberNum, unpaidMemberNum, lastYearMemberNum }
|
||||||
} = resp
|
} = resp
|
||||||
const diff = memberNum - lastYearMemberNum
|
const diff = memberNum - lastYearMemberNum
|
||||||
const ratio = (lastYearMemberNum ? (Math.abs(diff) / lastYearMemberNum) * 100 : (diff / 1) * 10).toFixed(2) + " %"
|
const ratio = (lastYearMemberNum ? (Math.abs(diff) / lastYearMemberNum) * 100 : (diff / 1) * 10).toFixed(2) + " %"
|
||||||
this.$set(this, "memberNumberData", { memberNum, unpaidMemberNum, lastYearMemberNum, diff, ratio })
|
// 兼容旧接口未返回 paidMemberNum 的情况,会员数按总会员数减未缴费人数计算。
|
||||||
|
const paidMemberCount = paidMemberNum !== undefined ? paidMemberNum : memberNum - unpaidMemberNum
|
||||||
|
this.$set(this, "memberNumberData", { memberNum, paidMemberNum: paidMemberCount, unpaidMemberNum, lastYearMemberNum, diff, ratio })
|
||||||
this.loading.memberNumber = false
|
this.loading.memberNumber = false
|
||||||
} else {
|
} else {
|
||||||
this.$message.warning(resp.msg)
|
this.$message.warning(resp.msg)
|
||||||
@@ -577,23 +580,26 @@ layout("/layouts/platform.html"){
|
|||||||
const unpaidValue = item.unpaidValue || item.unpaidvalue || 0
|
const unpaidValue = item.unpaidValue || item.unpaidvalue || 0
|
||||||
return Number(unpaidValue) || 0
|
return Number(unpaidValue) || 0
|
||||||
},
|
},
|
||||||
formatUnionMemberValue(item) {
|
getUnionPaidValue(item) {
|
||||||
const unpaidValue = this.getUnionUnpaidValue(item)
|
// 缴费会员数优先使用后端返回字段,旧数据则按职工数减未缴费数兜底。
|
||||||
if (unpaidValue > 0) {
|
const paidValue = item.paidValue !== undefined && item.paidValue !== null ? item.paidValue : item.paidvalue
|
||||||
return item.value + "/" + unpaidValue
|
if (paidValue !== undefined && paidValue !== null) {
|
||||||
|
return Number(paidValue) || 0
|
||||||
}
|
}
|
||||||
return item.value
|
return (Number(item.value) || 0) - this.getUnionUnpaidValue(item)
|
||||||
|
},
|
||||||
|
formatUnionMemberValue(item) {
|
||||||
|
return item.value + "/" + this.getUnionPaidValue(item)
|
||||||
},
|
},
|
||||||
buildUnionMemberTooltip(title, items) {
|
buildUnionMemberTooltip(title, items) {
|
||||||
if (!items || !items.length) {
|
if (!items || !items.length) {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
const data = items[0].data || {}
|
const data = items[0].data || {}
|
||||||
const unpaidValue = this.getUnionUnpaidValue(data)
|
|
||||||
return '<div style="padding:8px 4px">' +
|
return '<div style="padding:8px 4px">' +
|
||||||
'<div style="font-weight:600;margin-bottom:4px">' + title + '</div>' +
|
'<div style="font-weight:600;margin-bottom:4px">' + title + '</div>' +
|
||||||
'<div><span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:#217050;margin-right:6px"></span>会员数:' + data.value + '</div>' +
|
'<div><span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:#217050;margin-right:6px"></span>职工数:' + data.value + '</div>' +
|
||||||
'<div><span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:#217050;margin-right:6px"></span>未缴费数:' + unpaidValue + '</div>' +
|
'<div><span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:#217050;margin-right:6px"></span>会员数:' + this.getUnionPaidValue(data) + '</div>' +
|
||||||
'</div>'
|
'</div>'
|
||||||
},
|
},
|
||||||
async getUnionMember() {
|
async getUnionMember() {
|
||||||
@@ -602,8 +608,11 @@ layout("/layouts/platform.html"){
|
|||||||
this.loading.unionMember = false
|
this.loading.unionMember = false
|
||||||
if (resp.code === 0) {
|
if (resp.code === 0) {
|
||||||
const { chartData, tableData } = resp.data
|
const { chartData, tableData } = resp.data
|
||||||
|
// 标准化缴费会员数字段,避免后端 Record 字段大小写影响表格绑定和排序。
|
||||||
|
chartData.forEach((item) => this.$set(item, "paidValue", this.getUnionPaidValue(item)))
|
||||||
|
tableData.forEach((item) => this.$set(item, "paidValue", this.getUnionPaidValue(item)))
|
||||||
|
|
||||||
this.unionMember = tableData
|
this.$set(this, "unionMember", tableData)
|
||||||
|
|
||||||
if (chart.unionMemberChart) {
|
if (chart.unionMemberChart) {
|
||||||
chart.unionMemberChart.changeData(chartData)
|
chart.unionMemberChart.changeData(chartData)
|
||||||
@@ -685,7 +694,7 @@ layout("/layouts/platform.html"){
|
|||||||
alias: "类型"
|
alias: "类型"
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
alias: "会员数"
|
alias: "职工数"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -10,8 +10,20 @@ layout("/layouts/platform.html"){
|
|||||||
|
|
||||||
<el-card shadow="never" class="mt10">
|
<el-card shadow="never" class="mt10">
|
||||||
<table-tool label="会员列表">
|
<table-tool label="会员列表">
|
||||||
<el-button type="primary" size="small" icon="el-icon-check" @click="batchSetMemberFeePaid">一键设置已缴费</el-button>
|
<el-button
|
||||||
<el-button type="primary" size="small" icon="el-icon-upload2" @click="openImport">导入会员</el-button>
|
v-if="$auth.hasRoleOr(['SYSADMIN','SCHOOL_UNION_ADMIN','SCHOOL_UNION_CHAIRMAN'])"
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
icon="el-icon-check"
|
||||||
|
@click="batchSetMemberFeePaid"
|
||||||
|
>一键设置已缴费</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="$auth.hasRoleOr(['SYSADMIN','SCHOOL_UNION_ADMIN','SCHOOL_UNION_CHAIRMAN'])"
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
icon="el-icon-upload2"
|
||||||
|
@click="openImport"
|
||||||
|
>导入会员</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
v-if="$auth.hasRoleOr(['SYSADMIN','SCHOOL_UNION_ADMIN'])"
|
v-if="$auth.hasRoleOr(['SYSADMIN','SCHOOL_UNION_ADMIN'])"
|
||||||
@@ -83,6 +95,7 @@ layout("/layouts/platform.html"){
|
|||||||
<template scope="scope">
|
<template scope="scope">
|
||||||
<el-button size="mini" type="primary" @click="openView(scope.row.id)">查看</el-button>
|
<el-button size="mini" type="primary" @click="openView(scope.row.id)">查看</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
|
v-if="$auth.hasRoleOr(['SYSADMIN','SCHOOL_UNION_ADMIN','SCHOOL_UNION_CHAIRMAN'])"
|
||||||
size="mini"
|
size="mini"
|
||||||
:type="isMemberFeePaid(scope.row) ? 'success' : 'info'"
|
:type="isMemberFeePaid(scope.row) ? 'success' : 'info'"
|
||||||
@click="toggleMemberFeePaid(scope.row)"
|
@click="toggleMemberFeePaid(scope.row)"
|
||||||
|
|||||||
@@ -3,15 +3,9 @@ const filterUser = {
|
|||||||
<el-dialog title="选择用户生成福利名单" :visible.sync="visible" width="80%">
|
<el-dialog title="选择用户生成福利名单" :visible.sync="visible" width="80%">
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<search @search="doSearch">
|
<search @search="doSearch">
|
||||||
<search-item label="姓名">
|
<search-item label="姓名/工号">
|
||||||
<el-input @keyup.enter.native="doSearch" clearable placeholder="请输入姓名"
|
<el-input @keyup.enter.native="doSearch" clearable placeholder="请输入姓名/工号"
|
||||||
style="width: 100%" v-model="pageForm.userName">
|
style="width: 100%" v-model="pageForm.searchKeyword">
|
||||||
</el-input>
|
|
||||||
</search-item>
|
|
||||||
|
|
||||||
<search-item label="工号">
|
|
||||||
<el-input @keyup.enter.native="doSearch" clearable placeholder="请输入工号"
|
|
||||||
style="width: 100%" v-model="pageForm.loginName">
|
|
||||||
</el-input>
|
</el-input>
|
||||||
</search-item>
|
</search-item>
|
||||||
|
|
||||||
@@ -107,6 +101,13 @@ const filterUser = {
|
|||||||
<el-option label="否" :value="false"></el-option>
|
<el-option label="否" :value="false"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</search-item>
|
</search-item>
|
||||||
|
<search-item label="是否缴费会员">
|
||||||
|
<el-select clearable placeholder="请选择是否缴费会员" style="width: 100%"
|
||||||
|
v-model="pageForm.memberFeePaid">
|
||||||
|
<el-option label="是" :value="true"></el-option>
|
||||||
|
<el-option label="否" :value="false"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</search-item>
|
||||||
</search>
|
</search>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
@@ -159,7 +160,8 @@ const filterUser = {
|
|||||||
userStates: [],
|
userStates: [],
|
||||||
personTypes: [],
|
personTypes: [],
|
||||||
preparedBys: [],
|
preparedBys: [],
|
||||||
unitIds: []
|
unitIds: [],
|
||||||
|
memberFeePaid: null
|
||||||
},
|
},
|
||||||
sexOptions: ["男", "女"],
|
sexOptions: ["男", "女"],
|
||||||
unionOptions: [],
|
unionOptions: [],
|
||||||
@@ -188,8 +190,7 @@ const filterUser = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
resetPageForm() {
|
resetPageForm() {
|
||||||
this.$set(this.pageForm, "userName", null)
|
this.$set(this.pageForm, "searchKeyword", null)
|
||||||
this.$set(this.pageForm, "loginName", null)
|
|
||||||
this.$set(this.pageForm, "sex", null)
|
this.$set(this.pageForm, "sex", null)
|
||||||
this.$set(this.pageForm, "birthday", null)
|
this.$set(this.pageForm, "birthday", null)
|
||||||
this.$set(this.pageForm, "birthMonths", [])
|
this.$set(this.pageForm, "birthMonths", [])
|
||||||
@@ -199,6 +200,7 @@ const filterUser = {
|
|||||||
this.$set(this.pageForm, "preparedBys", [])
|
this.$set(this.pageForm, "preparedBys", [])
|
||||||
this.$set(this.pageForm, "userStates", [])
|
this.$set(this.pageForm, "userStates", [])
|
||||||
this.$set(this.pageForm, "isMember", null)
|
this.$set(this.pageForm, "isMember", null)
|
||||||
|
this.$set(this.pageForm, "memberFeePaid", null)
|
||||||
},
|
},
|
||||||
|
|
||||||
pageData() {
|
pageData() {
|
||||||
|
|||||||
Reference in New Issue
Block a user