公会组织管理:基层干部审核,以及届次整改,新增离任按钮和审核界面新增分工会搜索项。移除删除基层干部相关角色的审核流程;允许系统管理员和校工会管理员免审核添加基层干部相关角色;

This commit is contained in:
2026-10-20 21:35:06 +08:00
parent 24f6b50304
commit bf433727b9
6 changed files with 216 additions and 21 deletions
@@ -13,10 +13,12 @@ import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.util.List;
import java.util.stream.Collectors;
/**
* 基层干部审核
@@ -71,7 +73,7 @@ public class UnionCadreAuditController {
@At
@ViReturn
public Object pageData(PageForm pageForm) {
public Object pageData(PageForm pageForm, boolean audit, String workersCongressSession, String unionId) {
Sql sql = Sqls.create("""
SELECT
uc.*,
@@ -93,11 +95,33 @@ public class UnionCadreAuditController {
pageForm.defaultSortDesc("uc.workersCongressSession");
CndPlus cnd = CndPlus.create();
cnd.and("uc.auditStateId", "=", UnionCadreAuditState.SCHOOL_UNION);
if (audit) {
cnd.and("uc.auditStateId", "in", Lang.array(
UnionCadreAuditState.SCHOOL_UNION_FAIL,
UnionCadreAuditState.SUCCESS
));
} else {
cnd.and("uc.auditStateId", "=", UnionCadreAuditState.SCHOOL_UNION);
}
cnd.andEX("uc.workersCongressSession", "=", workersCongressSession);
cnd.andEX("uc.unionId", "=", unionId);
cnd.and(pageForm);
sql.setCondition(cnd);
return cadreService.list(pageForm, sql);
}
@At
@ViReturn
public Object usedSessions(String unionId) {
Cnd cnd = Cnd.NEW();
cnd.andEX("unionId", "=", unionId);
List<String> sessions = cadreService.query(cnd).stream()
.map(UnionCadre::getWorkersCongressSession)
.filter(session -> session != null && !session.isBlank())
.distinct()
.collect(Collectors.toList());
return sessions;
}
}
@@ -6,19 +6,27 @@ import io.v.nutz.base.utils.PageUtil;
import io.v.nutz.base.dao.CndPlus;
import io.v.nutz.base.query.PageForm;
import io.v.nutz.sys.models.Sys_role;
import io.v.nutz.sys.models.Sys_user_role;
import io.v.nutz.sys.models.UnionCadre;
import io.v.nutz.sys.services.SysDictService;
import io.v.nutz.sys.services.SysRoleService;
import io.v.nutz.sys.services.SysUserRoleService;
import io.v.nutz.sys.services.SysUserService;
import io.v.nutz.sys.services.UnionCadreService;
import io.v.nutz.web.commons.utils.ShiroUtil;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.util.Date;
/**
* 基层干部
*
@@ -40,6 +48,12 @@ public class UnionCadreController {
@Inject
private SysDictService sysDictService;
@Inject
private SysUserRoleService userRoleService;
@Inject
private SysUserService userService;
@At
@ViReturn
public Object pageData(PageForm pageForm, String unionid) {
@@ -64,7 +78,7 @@ public class UnionCadreController {
CndPlus cnd = CndPlus.create();
cnd.and(pageForm);
cnd.andEx("u.unionid", "=", unionid);
cnd.andEx("uc.unionId", "=", unionid);
if (Strings.isNotBlank(pageForm.getPageOrderName()) && Strings.isNotBlank(pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
} else {
@@ -77,30 +91,79 @@ public class UnionCadreController {
@At
@ViReturn
@Aop(TransAop.READ_COMMITTED)
public Object createCadre(UnionCadre cadre, String roleCode) {
Sys_role role = roleService.fetch(Cnd.where("code", "=", roleCode));
Cnd cnd = Cnd.where("userId", "=", cadre.getUserId()).and("roleId", "=", role.getId()).and("unionId", "=", cadre.getUnionId()).and("workersCongressSession", "=", cadre.getWorkersCongressSession());
Cnd roleCnd = Cnd.where("userId", "=", cadre.getUserId()).and("roleId", "=", role.getId()).and("unionid", "=", cadre.getUnionId());
Cnd pendingCnd = Cnd.where("userId", "=", cadre.getUserId()).and("roleId", "=", role.getId()).and("unionId", "=", cadre.getUnionId())
.and("joining", "=", true).and("auditStateId", "=", UnionCadreAuditState.SCHOOL_UNION).and("leaveDate", "is", null);
if (unionCadreService.count(cnd) > 0) {
if (userRoleService.count(roleCnd) > 0 || unionCadreService.count(pendingCnd) > 0) {
return Result.error("此操作重复!");
}
cadre.setJoining(true).setRoleId(role.getId()).setAuditStateId(UnionCadreAuditState.SCHOOL_UNION);
// 校工会管理员和系统管理员直接授权,不进入审核。
boolean isAdmin = ShiroUtil.hasAnyRoles("sysadmin,SchoolUnionAdmin");
cadre.setJoining(true).setRoleId(role.getId()).setAuditStateId(isAdmin
? UnionCadreAuditState.SUCCESS
: UnionCadreAuditState.SCHOOL_UNION);
unionCadreService.insert(cadre);
if (isAdmin) {
Sys_user_role userRole = new Sys_user_role();
userRole.setUserId(cadre.getUserId());
userRole.setRoleId(role.getId());
userRole.setUnionid(cadre.getUnionId());
userRoleService.insert(userRole);
userService.deleteCache(cadre.getUserId());
}
return null;
}
@At
@ViReturn
@Aop(TransAop.READ_COMMITTED)
public Object removeCadre(String id) {
UnionCadre cadre = unionCadreService.fetch(id);
if (UnionCadreAuditState.SUCCESS != cadre.getAuditStateId() && cadre.isJoining()) {
unionCadreService.delete(id);
} else {
cadre.setJoining(false).setAuditStateId(UnionCadreAuditState.SCHOOL_UNION);
unionCadreService.update(cadre);
if (cadre == null) {
return Result.error("未找到对应干部记录!");
}
if (cadre.getLeaveDate() != null) {
unionCadreService.delete(id);
return null;
}
// 删除在任干部时直接移除角色,不发起退出审核。
userRoleService.clear(Cnd.where("userId", "=", cadre.getUserId()).and("roleId", "=", cadre.getRoleId()).and("unionid", "=", cadre.getUnionId()));
unionCadreService.delete(id);
userService.deleteCache(cadre.getUserId());
return null;
}
@At
@ViReturn
@Aop(TransAop.READ_COMMITTED)
public Object leaveCadre(String id, Date leaveDate) {
if (leaveDate == null) {
return Result.error("请选择离任时间!");
}
UnionCadre cadre = unionCadreService.fetch(id);
if (cadre == null) {
return Result.error("未找到对应干部记录!");
}
if (cadre.getLeaveDate() != null) {
return Result.error("该干部已离任!");
}
if (UnionCadreAuditState.SUCCESS != cadre.getAuditStateId() || !cadre.isJoining()) {
return Result.error("仅已审核通过的在任干部可办理离任!");
}
cadre.setLeaveDate(leaveDate);
unionCadreService.update(cadre);
userRoleService.clear(Cnd.where("userId", "=", cadre.getUserId()).and("roleId", "=", cadre.getRoleId()).and("unionid", "=", cadre.getUnionId()));
userService.deleteCache(cadre.getUserId());
return null;
}
@@ -5,6 +5,8 @@ import lombok.Data;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import java.util.Date;
/**
* 基层干部
*
@@ -48,6 +50,11 @@ public class UnionCadre {
@ColDefine(type = ColType.BOOLEAN)
private boolean joining;
@Column
@Comment("离任时间")
@ColDefine(type = ColType.DATETIME)
private Date leaveDate;
@Column
@Comment("审核状态id")
@ColDefine(type = ColType.INT, width = 8)
@@ -4,10 +4,26 @@
<el-card shadow="never" class="mt10">
<table-tool label="基层干部" :app="this">
<template #func>
<el-button size="small" @click="audit(true)" :disabled="!multipleSelection.length" type="primary"
<el-radio-group v-model="pageForm.audit" size="small" class="mr5" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group>
<el-select v-model="pageForm.workersCongressSession" clearable size="small" placeholder="届次" class="mr5"
style="width: 110px" @change="doSearch">
<el-option v-for="item in sessionOptions" :key="item.code" :label="item.name" :value="item.code">
<span>{{ item.name }}</span>
<span v-if="hasSessionData(item.code)" class="used-session-mark">*</span>
</el-option>
</el-select>
<el-select v-model="pageForm.unionId" clearable filterable size="small" placeholder="分工会" class="mr5"
style="width: 180px" @change="unionChange">
<el-option v-for="item in unionOptions" :key="item.id" :label="item.unionname"
:value="item.id"></el-option>
</el-select>
<el-button v-if="!pageForm.audit" size="small" @click="audit(true)" :disabled="!multipleSelection.length" type="primary"
icon="el-icon-check">通过
</el-button>
<el-button size="small" @click="audit(false)" :disabled="!multipleSelection.length" type="danger"
<el-button v-if="!pageForm.audit" size="small" @click="audit(false)" :disabled="!multipleSelection.length" type="danger"
icon="el-icon-check">拒绝
</el-button>
</template>
@@ -18,6 +34,7 @@
@selection-change="handleSelectionChange">
<el-table-column
v-if="!pageForm.audit"
type="selection"
width="55">
</el-table-column>
@@ -71,6 +88,11 @@ module.exports = {
},
data() {
return {
pageForm: {
audit: false,
workersCongressSession: '',
unionId: ''
},
tableColumns: [
{prop: 'username', label: '姓名'},
{prop: 'loginname', label: '工号'},
@@ -79,11 +101,27 @@ module.exports = {
{prop: 'rolename', label: '职务'},
{prop: 'workersCongressSession', label: '届次'},
{prop: 'joining', label: '申请类型'},
{prop: 'stateName', label: '审核状态'},
],
multipleSelection: [],
sessionOptions: [],
usedSessionCodes: [],
unionOptions: [],
}
},
methods: {
hasSessionData(code) {
return this.usedSessionCodes.includes(code)
},
async loadUsedSessionCodes() {
const {code, data} = await $.get('/platform/union/cadre/audit/usedSessions', {
unionId: this.pageForm.unionId
})
this.usedSessionCodes = code === 0 ? (data || []) : []
},
unionChange() {
this.doSearch()
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
@@ -105,6 +143,7 @@ module.exports = {
})
},
pageData() {
this.loadUsedSessionCodes()
sublime.showLoadingbar();
this.tableLoading = true
$.post("/platform/union/cadre/audit/pageData", this.pageForm, (data) => {
@@ -124,12 +163,18 @@ module.exports = {
this.doSearch()
}
},
created() {
async created() {
this.sessionOptions = await getDictOptions('jc')
this.unionOptions = await getUnions(null)
this.doSearch()
}
}
</script>
<style scoped>
.used-session-mark {
color: #f56c6c;
margin-left: 4px;
font-weight: 700;
}
</style>
@@ -87,7 +87,8 @@
align="center" show-overflow-tooltip
>
<template scope="{row}">
<vi-table-state :state="row"></vi-table-state>
<el-tag v-if="row.leaveDate" type="info">离任</el-tag>
<vi-table-state v-else :state="row"></vi-table-state>
</template>
</el-table-column>
@@ -98,11 +99,15 @@
align="center"
width="150">
<template scope="{row}">
<el-button v-if="row.auditStateId === 1300 && row.joining && !row.leaveDate"
size="mini" type="warning" icon="el-icon-switch-button"
@click="openLeave(row)">
</el-button>
<el-popconfirm
title="确定要移除吗?"
title="确定要删除该干部角色吗?"
@confirm="doDelete(row)"
>
<el-button slot="reference" :disabled="!row.can" size="mini" :loading="row.delLoading" type="danger"
<el-button slot="reference" size="mini" :loading="row.delLoading" type="danger"
icon="el-icon-delete">
</el-button>
</el-popconfirm>
@@ -174,6 +179,26 @@
</span>
</el-dialog>
<el-dialog
title="离任"
:visible.sync="leaveDialogVisible" width="420px">
<el-form :model="leaveForm" label-width="90px">
<el-form-item label="离任时间" required>
<el-date-picker
v-model="leaveForm.leaveDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择离任时间"
style="width: 100%">
</el-date-picker>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="leaveDialogVisible = false" :disabled="leaveSubmitLoading">取 消</el-button>
<el-button type="primary" :loading="leaveSubmitLoading" @click="doLeave">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
@@ -211,7 +236,10 @@ module.exports = {
roleCode: [{required: true, message: '必选', trigger: ['blur', 'change']}],
userId: [{required: true, message: '必选', trigger: ['blur', 'change']}],
},
submitLoading: false
submitLoading: false,
leaveDialogVisible: false,
leaveForm: {},
leaveSubmitLoading: false
}
},
watch: {
@@ -282,6 +310,34 @@ module.exports = {
this.$set(row, "delLoading", false)
},
openLeave(row) {
this.leaveForm = {
id: row.id,
leaveDate: ''
}
this.leaveDialogVisible = true
},
async doLeave() {
if (!this.leaveForm.leaveDate) {
this.$message.error('请选择离任时间')
return
}
this.leaveSubmitLoading = true
const {code, msg} = await $.post('/platform/union/cadre/leaveCadre', this.leaveForm)
if (code === 0) {
this.leaveDialogVisible = false
this.pageData()
}
this.$notify({
title: code === 0 ? '成功' : '失败',
type: code === 0 ? 'success' : 'error',
message: msg,
})
this.leaveSubmitLoading = false
},
async userRemoteMethod(query) {
if (!query) {
this.userOptions = []
@@ -1129,8 +1129,8 @@ layout("/layouts/platform.html"){
'tree-layout': httpVueLoader('/components/plugins/TreeLayout.vue'),
'dict-select': httpVueLoader('/components/plugins/DictSelect.vue'),
'union-cadre': httpVueLoader('/components/sys/union/UnionCadreMange.vue?v=1.0.89'),
'union-cadre-mange': httpVueLoader('/components/sys/union/cadre/Mange.vue?v=1.0.5'),
'union-cadre-audit': httpVueLoader('/components/sys/union/cadre/Audit.vue?v=1.0.5'),
'union-cadre-mange': httpVueLoader('/components/sys/union/cadre/Mange.vue?v=1.0.9'),
'union-cadre-audit': httpVueLoader('/components/sys/union/cadre/Audit.vue?v=1.0.7'),
},
watch: {
filterText(val) {