This commit is contained in:
@jyuhsin
2025-09-24 20:00:07 +08:00
parent 45888897b4
commit 5730478c79
2 changed files with 389 additions and 61 deletions
@@ -2,20 +2,38 @@ package com.budwk.app.zhgh.staffmanage.member.controller.info;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result; import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil; import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.sys.models.Sys_role;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.models.Sys_user_role;
import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.dayofficework.meeting.model.MeetingInfo;
import com.budwk.app.zhgh.dayofficework.meeting.model.MeetingTimePeriodUser;
import com.budwk.app.zhgh.staffmanage.member.param.pageform.MemberInfoPageForm; import com.budwk.app.zhgh.staffmanage.member.param.pageform.MemberInfoPageForm;
import com.budwk.app.zhgh.staffmanage.member.service.MemberInfoService;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd; import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls; import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql; import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup; import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.List;
/** /**
* @version 1.0 * @version 1.0
@@ -29,62 +47,134 @@ import org.nutz.mvc.annotation.Ok;
@At("/platform/member/info/dataManage") @At("/platform/member/info/dataManage")
public class MemberDataManageController { public class MemberDataManageController {
@At("") @Inject
@SaCheckPermission("member.info.dataManage") private MemberInfoService memberInfoService;
@Ok("beetl:/platform/zhgh/staffmanage/member/info/datamanage/index.html") @Inject
public void index() {} private Dao dao;
@Inject
private SysRoleService roleService;
@At("")
@SaCheckPermission("member.info.dataManage")
@Ok("beetl:/platform/zhgh/staffmanage/member/info/datamanage/index.html")
public void index() {
}
@At @At
@ApiOperation("数据管理工具") @ApiOperation("数据管理工具")
@SaCheckPermission("member.info.dataManage") @SaCheckPermission("member.info.dataManage")
public Result pageData(MemberInfoPageForm pageForm) { public Result pageData(MemberInfoPageForm pageForm) {
Sql sql = Sqls.create(""" Sql sql = generateSql(pageForm, Cnd.NEW());
SELECT Pagination pagination = memberInfoService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
id, return Result.success(pagination);
loginname, }
username,
sex,
userState,
personType,
preparedBy,
unionName,
unitName,
mobile
from
`user`
$condition
""");
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("username", pageForm.getSearchKeyword());
seg.orLike("loginname", pageForm.getSearchKeyword());
cnd.and(seg);
}
// 权限判断 @At
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) { @ApiOperation("根据身份证号设置出生日期")
SqlExpressionGroup seg = new SqlExpressionGroup(); @Aop(TransAop.READ_COMMITTED)
seg.or("unionId", "=", SecurityUtil.getUnionId()); @SaCheckPermission("member.info.dataManage")
seg.or("unionId", "is", null); @SLog(tag = "会员管理-数据管理工具", msg = "根据身份证号设置出生日期")
seg.or("unionId", "=", ""); public Object setBirthdayByIdCard() {
cnd.and(seg); Sql sql = Sqls.create("""
} else { UPDATE sys_user
cnd.andEX("unionId", "=", pageForm.getUnionId()); SET birthday = STR_TO_DATE(SUBSTRING(idcard, 7, 8), '%Y%m%d')
cnd.andEX("unitId", "=", pageForm.getUnitId()); WHERE (birthday IS NULL OR birthday = '') AND length(idcard)=18
} """);
memberInfoService.execute(sql);
return Result.success();
}
cnd.andEX("userState", "in", pageForm.getUserStates()); @At
cnd.andEX("preparedBy", "in", pageForm.getPreparedBys()); @ApiOperation("批量设置会员")
cnd.andEX("personType", "in", pageForm.getPersonTypes()); @Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("member.info.dataManage")
@SLog(tag = "会员管理-数据管理工具", msg = "批量设置会员")
public Object setMemberByCnd(MemberInfoPageForm pageForm, boolean append) {
if (StrUtil.isAllNotBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) { Sys_role sysRole = roleService.getByCode(RoleConstant.MEMBER.name());
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy())); // 如果是先清空再追加
} else { if(!append) {
cnd.asc("unitcode").asc("loginname"); dao.update(Sys_user.class, Chain.make("member", false), Cnd.NEW());
} dao.clear(Sys_user_role.class, Cnd.where(Sys_user_role::getRoleId, "=", sysRole.getId()));
sql.setCondition(cnd); }
return Result.success();
} Cnd cnd = Cnd.NEW();
cnd.and(Cnd.exps("member", "=", false).or("member", "is", null));
Sql sql = generateSql(pageForm, cnd);
List<NutMap> listMap = memberInfoService.listMap(sql);
List<String> list = listMap.stream().map(o -> o.getString("id")).toList();
List<Sys_user_role> userRoles = list.stream().map(o -> {
Sys_user_role userRole = new Sys_user_role();
userRole.setRoleId(sysRole.getId());
userRole.setUserId(o);
return userRole;
}).toList();
dao.update(Sys_user.class, Chain.make("member", true), Cnd.where("id", "in", list));
dao.insert(userRoles);
return Result.success();
}
@At
@ApiOperation("批量设置福利会员")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("member.info.dataManage")
@SLog(tag = "会员管理-数据管理工具", msg = "批量设置福利会员")
public Object setWelfareMemberByCnd(MemberInfoPageForm pageForm, boolean append) {
// 如果是先清空再追加
if(!append) {
dao.update(Sys_user.class, Chain.make("welfareMember", false), Cnd.NEW());
}
Cnd cnd = Cnd.NEW();
cnd.and(Cnd.exps("welfareMember", "=", false).or("welfareMember", "is", null));
Sql sql = generateSql(pageForm, cnd);
List<NutMap> listMap = memberInfoService.listMap(sql);
List<String> list = listMap.stream().map(o -> o.getString("id")).toList();
dao.update(Sys_user.class, Chain.make("welfareMember", true), Cnd.where("id", "in", list));
return Result.success();
}
private Sql generateSql(MemberInfoPageForm pageForm, Cnd cnd) {
Sql sql = Sqls.create("""
SELECT
id,
loginname as loginName,
username as userName,
sex,
userState,
personType,
preparedBy,
unionName,
unitName,
mobile
from
`vw_user`
$condition
""");
pageForm.buildSearch(cnd, "");
if (StrUtil.isNotBlank(pageForm.getStartLoginNames())) {
String[] loginNames = pageForm.getStartLoginNames().split(",");
SqlExpressionGroup seg = new SqlExpressionGroup();
for (String loginName : loginNames) {
seg.orLikeL("loginname", loginName);
}
cnd.and(seg);
}
if (StrUtil.isNotBlank(pageForm.getEndLoginNames())) {
String[] loginNames = pageForm.getEndLoginNames().split(",");
SqlExpressionGroup seg = new SqlExpressionGroup();
for (String loginName : loginNames) {
seg.orLikeR("loginname", loginName);
}
cnd.and(seg);
}
sql.setCondition(cnd);
return sql;
}
} }
@@ -1,19 +1,167 @@
<!--# <!--#
layout("/layouts/platform.html"){ layout("/layouts/platform.html"){
#--> #-->
<style>
.search-other {
display: flex;
align-items: center;
margin-top: 20px;
}
.search-other-label {
width: 90px;
min-width: 90px;
color: rgb(100, 100, 100);
margin-right: 10px;
flex-shrink: 0;
}
.search-other > div {
display: flex;
flex-wrap: wrap;
align-items: center;
margin-bottom: -6px;
}
.search-other .el-tag {
margin-right: 10px;
margin-bottom: 6px;
cursor: pointer;
}
.search-other .el-link {
margin-bottom: 6px;
margin-right: 10px;
}
.popover-container {
display: flex;
align-items: center;
line-height: 22px;
}
.popover-icon {
margin-right: 6px;
}
.popover-icon-waning {
color: #e6a23c;
font-size: 24px !important;
font-family: element-icons !important;
}
.popover-icon-waning:before {
content: "\e7a3";
}
.popover-footer {
text-align: right;
margin-top: 20px;
}
.el-popover__reference:nth-of-type(1) {
margin-left: 10px;
margin-right: 5px;
}
</style>
<div id="app"> <div id="app">
<guava ref="guava"> <guava ref="guava">
<el-card shadow="never"> <el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query> <common-query ref="commonQueryRef" @search="search"></common-query>
</el-card> </el-card>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="工号开头">
<el-input v-model="pageForm.startLoginNames" maxLength="100"
placeholder="多个请用英文逗号分隔"></el-input>
</search-item>
<search-item label="工号结尾">
<el-input v-model="pageForm.endLoginNames" maxLength="100"
placeholder="多个请用英文逗号分隔"></el-input>
</search-item>
</search>
<div class="search-other mt20">
<div class="search-other-label">人员类型</div>
<div>
<el-tag
style="margin-right: 10px;cursor: pointer"
v-for="item in dict.type.USER_PERSON_TYPE"
:key="item.code"
:type="item.name"
:effect="pageForm.personTypes.includes(item.name)?'dark':'plain'"
@click="tagClick('personTypes',item.name)">
{{ item.name }}
</el-tag>
<el-link type="danger"
v-if="dict.type.USER_PERSON_TYPE?.length && pageForm.personTypes.length"
:underline="false"
@click="pageForm.personTypes=[]; doSearch()">清空
</el-link>
<el-link :underline="false"
@click="pageForm.personTypes = dict.type.USER_PERSON_TYPE?.map(p=>p.code); doSearch()"
type="success">全部
</el-link>
</div>
</div>
<div class="search-other mt20">
<div class="search-other-label">在职状态</div>
<div>
<el-tag
style="margin-right: 10px;cursor: pointer"
v-for="item in dict.type.USER_STATE"
:key="item.code"
:type="item.name"
:effect="pageForm.userStates.includes(item.name)?'dark':'plain'"
@click="tagClick('userStates',item.name)">
{{ item.name }}
</el-tag>
<el-link type="danger"
v-if="dict.type.USER_STATE?.length && pageForm.userStates.length"
:underline="false"
@click="pageForm.userStates=[]; doSearch()">清空
</el-link>
<el-link :underline="false"
@click="pageForm.userStates = dict.type.USER_STATE?.map(p=>p.code); doSearch()"
type="success">全部
</el-link>
</div>
</div>
</el-card>
<el-card shadow="never" class="mt10"> <el-card shadow="never" class="mt10">
<table-tool label="数据列表"></table-tool> <table-tool label="数据列表">
<el-button size="mini" icon="el-icon-s-tools" type="primary" @click="onBirthday">根据身份证设置生日</el-button>
<el-popover
v-for="item in popoverConfigs"
:key="item.text"
placement="left"
width="360"
title="温馨提醒"
v-model="item.visible">
<div class="popover-container">
<div class='popover-icon popover-icon-waning'></div>
<div>
<p>
<i class='el-icon-s-help' style='margin-right: 6px;'></i>
<span>如果先清空已有数据,后更新,请选择</span>
<span style='color: red'>更新</span>
<span style='font-weight: bolder'>(这将清空目前所有的会员,请谨慎操作!)</span>
</p>
<p class="mt5">
<i class='el-icon-s-help' style='margin-right: 6px;'></i>
<span>如果追加或更新数据,请选择</span>
<span style='color: red'>追加</span>
</p>
</div>
</div>
<div class="popover-footer">
<el-button size="mini" type="text" @click="item.visible = false">取消</el-button>
<el-button type="warning" size="mini" @click="handlePopoverAction(item, true)">追加</el-button>
<el-button type="primary" size="mini" @click="handlePopoverAction(item, false)">更新</el-button>
</div>
<el-button slot="reference" size="mini" icon="el-icon-s-tools" type="primary">{{ item.text }}</el-button>
</el-popover>
</table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder" ref="table" row-key="id" style="width: 100%"> <el-table :data="tableData" :size="tableSize" @sort-change="pageOrder" ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" align="center" header-align="center" <el-table-column :index="indexMethod" align="center" header-align="center"
label="序号" type="index" width="80px"></el-table-column> label="序号" type="index" width="80px"></el-table-column>
<el-table-column :label="column.label" <el-table-column :label="column.label"
:prop="column.prop" :prop="column.prop"
:key="column.prop"
:sortable="column.sortable" :sortable="column.sortable"
:width="column.width" :width="column.width"
header-align="center" header-align="center"
@@ -21,28 +169,39 @@ layout("/layouts/platform.html"){
show-overflow-tooltip show-overflow-tooltip
v-for="column in tableColumns"> v-for="column in tableColumns">
</el-table-column> </el-table-column>
<el-table-column label="操作" fixed="right" width="200px"> <el-table-column label="操作" fixed="right" width="100">
<template slot-scope="{row}"> <template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button> <el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
<el-button @click="singleMake(row)" size="mini" type="primary">设置为会员</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!--#include("/layouts/pagination.html"){}#--> <!--#include("/layouts/pagination.html"){}#-->
</el-card> </el-card>
<template #view>
<member-info ref="memberInfoRef"></member-info>
</template>
</guava> </guava>
</div> </div>
<script> <script>
<!--#include("../../common/info/memberInfo.js"){}#--> <!--#include("../../common/info/memberInfo.js"){}#-->
<!--#include("../common/commonQuery.js"){}#--> <!--#include("../common/commonQuery.js"){}#-->
new Vue({ new Vue({
el: "#app", el: "#app",
store, store,
mixins: [initTableMixins], mixins: [initTableMixins],
components: {
'member-info': MEMBER_INFO,
'common-query': COMMON_QUERY,
},
dicts: ['USER_PERSON_TYPE', 'USER_STATE'],
data() { data() {
return { return {
pageForm: {}, visible: false,
pageForm: {
personTypes: [],
userStates: [],
},
tableColumns: [ tableColumns: [
{ prop: "loginName", label: "工号", sortable: true }, { prop: "loginName", label: "工号", sortable: true },
{ prop: "userName", label: "姓名", sortable: true }, { prop: "userName", label: "姓名", sortable: true },
@@ -52,16 +211,95 @@ layout("/layouts/platform.html"){
{ prop: "preparedBy", label: "编制类型", sortable: true }, { prop: "preparedBy", label: "编制类型", sortable: true },
{ prop: "unionName", label: "所属工会", sortable: true }, { prop: "unionName", label: "所属工会", sortable: true },
{ prop: "unitName", label: "所属单位", sortable: true }, { prop: "unitName", label: "所属单位", sortable: true },
] ],
personTypeOptions: [],
popoverConfigs: [
{text: '设置会员', func: this.onMember, visible: false},
{text: '设置福利会员', func: this.onWelfare, visible: false},
],
} }
}, },
methods: { methods: {
handlePopoverAction(item, isAppend) {
item.func(isAppend)
item.visible = false
document.activeElement.blur()
},
onBirthday() {
this.$confirm("您确定要根据身份证号设置出生日期吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/member/info/dataManage/setBirthdayByIdCard").then((res) => {
if (res.code === 0) {
this.pageData()
this.$message.success(res.msg)
} else {
this.$message.error(res.msg)
}
})
})
},
onMember(append) {
const pageForm = clone(this.pageForm)
pageForm.personTypes = JSON.stringify(pageForm.personTypes)
pageForm.userStates = JSON.stringify(pageForm.userStates)
pageForm.append = append
this.$axios.post("/platform/member/info/dataManage/setMemberByCnd").then((res) => {
if (res.code === 0) {
this.pageData()
this.$message.success(res.msg)
} else {
this.$message.error(res.msg)
}
})
},
onWelfare(append) {
const pageForm = clone(this.pageForm)
pageForm.personTypes = JSON.stringify(pageForm.personTypes)
pageForm.userStates = JSON.stringify(pageForm.userStates)
pageForm.append = append
this.$axios.post("/platform/member/info/dataManage/setWelfareMemberByCnd").then((res) => {
if (res.code === 0) {
this.pageData()
this.$message.success(res.msg)
} else {
this.$message.error(res.msg)
}
})
},
onView(row) {
this.$refs.guava.view(() => {
this.$refs.memberInfoRef.onOpen(row.id)
})
},
tagClick(key, val) {
const index = this.pageForm[key]?.findIndex(v => v === val)
if (index > -1) {
this.pageForm[key].splice(index, 1)
} else {
this.pageForm[key].push(val)
}
this.doSearch()
},
search(pageForm) { search(pageForm) {
if (pageForm) { if (pageForm) {
this.pageForm = {...this.pageForm, ...pageForm} this.pageForm = {...this.pageForm, ...pageForm}
} }
this.doSearch() this.doSearch()
}, },
pageData() {
const pageForm = clone(this.pageForm)
pageForm.personTypes = JSON.stringify(pageForm.personTypes)
pageForm.userStates = JSON.stringify(pageForm.userStates)
this.$axios.post(loc() + "/pageData", pageForm).then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
},
}, },
created() { created() {
this.pageData() this.pageData()