Merge branch 'main' of https://dd3skj.picp.vip/JyuHsin/zhgh_cug_v4
This commit is contained in:
@@ -11,6 +11,8 @@ import com.budwk.app.flow.engine.event.ProcessPublisher;
|
||||
import com.budwk.app.flow.entity.ProcessInstance;
|
||||
import com.budwk.app.flow.entity.ProcessTask;
|
||||
import com.budwk.app.flow.enums.*;
|
||||
import com.budwk.app.sys.models.Sys_unit;
|
||||
import com.budwk.app.sys.views.View_user;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.Chain;
|
||||
@@ -22,6 +24,7 @@ import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.json.Json;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@IocBean
|
||||
public class FlowCommonService {
|
||||
@@ -61,11 +64,13 @@ public class FlowCommonService {
|
||||
|
||||
args.put(FlowConst.SUBMIT_TYPE, submitType);
|
||||
|
||||
Sys_unit sysUnit = dao.fetch(Sys_unit.class, Cnd.where("id", "=", SecurityUtil.getUnitId()));
|
||||
|
||||
// 设置办理人信息到表单参数
|
||||
args.put(FlowConst.TASK_FORM_DATA_PREFIX + "userName", SecurityUtil.getUserUsername());
|
||||
args.put(FlowConst.TASK_FORM_DATA_PREFIX + "loginName", SecurityUtil.getUserLoginname());
|
||||
args.put(FlowConst.TASK_FORM_DATA_PREFIX + "unitId", SecurityUtil.getUnitId());
|
||||
args.put(FlowConst.TASK_FORM_DATA_PREFIX + "unitName", SecurityUtil.getUnitId());
|
||||
args.put(FlowConst.TASK_FORM_DATA_PREFIX + "unitName", Optional.of(sysUnit).map(Sys_unit::getName).orElse(""));
|
||||
args.put(FlowConst.TASK_FORM_DATA_PREFIX + "unionId", SecurityUtil.getUnionId());
|
||||
|
||||
if (ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.ROLLBACK.getCode())) {
|
||||
|
||||
@@ -4,7 +4,6 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.constant.RedisConstant;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.utils.PageUtil;
|
||||
import com.budwk.app.sys.models.Sys_config;
|
||||
import com.budwk.app.sys.services.SysConfigService;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
@@ -139,17 +138,18 @@ public class SysConfController {
|
||||
@At
|
||||
@Ok("json:full")
|
||||
@SaCheckPermission("sys.manager.conf")
|
||||
public Object data(@Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
|
||||
public Object data(@Param("pageNumber") int pageNumber,
|
||||
@Param("pageSize") int pageSize,
|
||||
@Param("pageOrderName") String pageOrderName,
|
||||
@Param("pageOrderBy") String pageOrderBy,
|
||||
@Param("configKey") String configKey) {
|
||||
try {
|
||||
ensureAppImageConfig("AppHomeImg", "PC首页轮播图");
|
||||
ensureAppImageConfig("H5AppHomeImg", "移动端首页轮播图");
|
||||
ensureAppImageConfig("AppFeaturedActivityImg", "精彩活动页顶部图片");
|
||||
ensureAppImageConfig("AppFestivalBenefitImg", "节日福利页顶部图片");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (Strings.isNotBlank(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
|
||||
cnd.orderBy(pageOrderName, PageUtil.getOrder(pageOrderBy));
|
||||
}
|
||||
return Result.success().addData(sysConfigService.listPage(pageNumber, pageSize, cnd));
|
||||
return Result.success().addData(sysConfigService.pageData(
|
||||
pageNumber, pageSize, pageOrderName, pageOrderBy, configKey));
|
||||
} catch (Exception e) {
|
||||
return Result.error();
|
||||
}
|
||||
|
||||
@@ -419,14 +419,13 @@ public class SysRoleController {
|
||||
public Object user(@Param("roleId") String roleId, @Param("searchName") String searchName, @Param("searchKeyword") String searchKeyword,
|
||||
@Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
|
||||
try {
|
||||
Sql sql = Sqls.create("SELECT a.*,c.name as unitname FROM sys_user a,sys_user_role b,sys_unit c WHERE a.unitid=c.id and a.id=b.userId and b.roleId=@roleId $s $o");
|
||||
Sql sql = Sqls.create("SELECT a.*,c.name as unitname FROM sys_user a,sys_user_role b,sys_unit c WHERE a.unitid=c.id and a.id=b.userId and enable='1' and b.roleId=@roleId $s $o");
|
||||
sql.params().set("roleId", roleId);
|
||||
if (Strings.isNotBlank(searchName) && Strings.isNotBlank(searchKeyword)) {
|
||||
sql.vars().set("s", " and a." + searchName + " like '%" + searchKeyword + "%'");
|
||||
}
|
||||
if (Strings.isNotBlank(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
|
||||
sql.vars().set("o", " order by a." + pageOrderName + " " + PageUtil.getOrder(pageOrderBy));
|
||||
|
||||
}
|
||||
return Result.success().addData(sysUserService.listPage(pageNumber, pageSize, sql));
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -456,10 +456,16 @@ public class SysUnionController {
|
||||
unionCadre.setIsJoin(true);
|
||||
dao.insert(unionCadre);
|
||||
|
||||
// 去走工作流
|
||||
// 校级管理员新增普通干部时直接授权,不生成无实际审核意义的流程数据。
|
||||
boolean isAdmin = AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name());
|
||||
if (isAdmin) {
|
||||
sysUnionService.assignBranchUnionRole(userId, role.getId(), unionId, List.of());
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
// 非校级管理员仍按原业务发起基层干部授权审核流程。
|
||||
Dict args = Dict.create();
|
||||
args.set("submit", isAdmin ? "admin" : "branch");
|
||||
args.set("submit", "branch");
|
||||
args.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode());
|
||||
args.set(FlowConst.FORM_DATA, unionCadre);
|
||||
|
||||
@@ -470,20 +476,12 @@ public class SysUnionController {
|
||||
flowEngine.executeProcessTask(task.getId(), SecurityUtil.getUserId(), args);
|
||||
}
|
||||
|
||||
if (isAdmin) {
|
||||
// 如果是管理员,直接加角色
|
||||
sysRoleService.clear("sys_user_role", Cnd.where("roleId", "=", role.getId()).and("userId", "=", userId).and("unionId", "=", unionId));
|
||||
sysRoleService.insert("sys_user_role", Chain.make("roleId", role.getId()).add("userId", userId).add("unionId", unionId));
|
||||
sysRoleService.clearCache();
|
||||
sysUserService.clearCache();
|
||||
}
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起二级党委书记授权审批。一个审批申请可关联当前分工会下的多个单位。
|
||||
* 审核通过后由流程拦截器按单位写入角色,避免影响普通分工会角色的授权方式。
|
||||
* 新增二级党委书记授权。校级管理员直接按单位授权,其他用户发起审批,
|
||||
* 审核通过后由流程拦截器按单位写入角色。
|
||||
*
|
||||
* @param userId 人员ID
|
||||
* @param unionId 分工会ID
|
||||
@@ -536,11 +534,18 @@ public class SysUnionController {
|
||||
unionCadre.setIsJoin(true);
|
||||
dao.insert(unionCadre);
|
||||
|
||||
boolean isAdmin = AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name());
|
||||
if (isAdmin) {
|
||||
// 校级管理员直接按所选单位授权,不创建 JCGHWY 流程实例和审核任务。
|
||||
sysUnionService.assignBranchUnionRole(userId, role.getId(), unionId, distinctUnitIds);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
// 非校级管理员保留原审批流程,并将所选单位随表单传给审核通过拦截器。
|
||||
JSONObject formData = JSONUtil.parseObj(unionCadre);
|
||||
formData.set("unitIds", distinctUnitIds);
|
||||
Dict args = Dict.create();
|
||||
boolean isAdmin = AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name());
|
||||
args.set("submit", isAdmin ? "admin" : "branch");
|
||||
args.set("submit", "branch");
|
||||
args.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode());
|
||||
args.set(FlowConst.FORM_DATA, formData.toString());
|
||||
ProcessInstance instance = flowEngine.startProcessInstanceByKey("JCGHWY", unionCadre.getId(), SecurityUtil.getUserId(), args);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.budwk.app.sys.services;
|
||||
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.sys.models.Sys_config;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
|
||||
@@ -16,4 +17,17 @@ public interface SysConfigService extends BaseService<Sys_config> {
|
||||
List<Sys_config> getAllList();
|
||||
|
||||
Sys_config getValueByKey(String key);
|
||||
|
||||
/**
|
||||
* 分页查询系统参数,支持按参数名模糊查询和安全排序。
|
||||
*
|
||||
* @param pageNumber 页码
|
||||
* @param pageSize 每页条数
|
||||
* @param pageOrderName 排序字段
|
||||
* @param pageOrderBy 排序方向
|
||||
* @param configKey 参数名关键字
|
||||
* @return 系统参数分页数据
|
||||
*/
|
||||
Pagination<Sys_config> pageData(int pageNumber, int pageSize, String pageOrderName,
|
||||
String pageOrderBy, String configKey);
|
||||
}
|
||||
|
||||
@@ -3,5 +3,18 @@ package com.budwk.app.sys.services;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.sys.models.Sys_union;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SysUnionService extends BaseService<Sys_union> {
|
||||
|
||||
/**
|
||||
* 直接分配分工会干部角色。普通干部传空单位集合时按分工会写入一条角色关系;
|
||||
* 二级党委书记传单位集合时按单位分别写入角色关系。
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param roleId 角色ID
|
||||
* @param unionId 分工会ID
|
||||
* @param unitIds 授权单位ID集合,普通干部角色传空集合
|
||||
*/
|
||||
void assignBranchUnionRole(String userId, String roleId, String unionId, List<String> unitIds);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
package com.budwk.app.sys.services.impl;
|
||||
|
||||
import com.budwk.app.base.exception.BaseException;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.base.utils.PageUtil;
|
||||
import com.budwk.app.sys.models.Sys_config;
|
||||
import com.budwk.app.sys.services.SysConfigService;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Lang;
|
||||
import org.nutz.lang.Strings;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by wizzer on 2016/12/23.
|
||||
@@ -32,4 +36,32 @@ public class SysConfigServiceImpl extends BaseServiceImpl<Sys_config> implements
|
||||
}
|
||||
return sys_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询系统参数。参数名使用模糊匹配,排序字段限定在列表可展示字段内,
|
||||
* 防止未经校验的前端字段直接进入排序 SQL。
|
||||
*
|
||||
* @param pageNumber 页码
|
||||
* @param pageSize 每页条数
|
||||
* @param pageOrderName 排序字段
|
||||
* @param pageOrderBy 排序方向
|
||||
* @param configKey 参数名关键字
|
||||
* @return 系统参数分页数据
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Pagination<Sys_config> pageData(int pageNumber, int pageSize, String pageOrderName,
|
||||
String pageOrderBy, String configKey) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (Strings.isNotBlank(configKey)) {
|
||||
cnd.where().andLike("configKey", configKey.trim());
|
||||
}
|
||||
Set<String> sortableColumns = Set.of("configKey", "configValue", "note");
|
||||
if (sortableColumns.contains(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
|
||||
cnd.orderBy(pageOrderName, PageUtil.getOrder(pageOrderBy));
|
||||
} else {
|
||||
cnd.asc("configKey");
|
||||
}
|
||||
return listPage(pageNumber, pageSize, cnd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,65 @@ package com.budwk.app.sys.services.impl;
|
||||
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.sys.models.Sys_union;
|
||||
import com.budwk.app.sys.models.Sys_user_role;
|
||||
import com.budwk.app.sys.services.SysRoleService;
|
||||
import com.budwk.app.sys.services.SysUnionService;
|
||||
import com.budwk.app.sys.services.SysUserService;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class SysUnionServiceImpl extends BaseServiceImpl<Sys_union> implements SysUnionService {
|
||||
|
||||
@Inject
|
||||
private SysRoleService sysRoleService;
|
||||
|
||||
@Inject
|
||||
private SysUserService sysUserService;
|
||||
|
||||
public SysUnionServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接分配分工会干部角色,并在授权完成后统一清理权限缓存。
|
||||
* 普通角色按分工会授权一次,包含单位的角色按每个单位分别授权。
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param roleId 角色ID
|
||||
* @param unionId 分工会ID
|
||||
* @param unitIds 授权单位ID集合,普通干部角色传空集合
|
||||
*/
|
||||
@Override
|
||||
public void assignBranchUnionRole(String userId, String roleId, String unionId, List<String> unitIds) {
|
||||
// 先清理同一用户在当前分工会下的相同角色,保证重新授权后不存在重复关系。
|
||||
dao().clear(Sys_user_role.class, Cnd.where(Sys_user_role::getRoleId, "=", roleId)
|
||||
.and(Sys_user_role::getUserId, "=", userId)
|
||||
.and(Sys_user_role::getUnionId, "=", unionId));
|
||||
|
||||
if (unitIds == null || unitIds.isEmpty()) {
|
||||
Sys_user_role userRole = new Sys_user_role();
|
||||
userRole.setRoleId(roleId);
|
||||
userRole.setUserId(userId);
|
||||
userRole.setUnionId(unionId);
|
||||
dao().insert(userRole);
|
||||
} else {
|
||||
// 二级党委书记按选中的单位分别生成角色关系,供后续单位级权限判断使用。
|
||||
for (String unitId : unitIds) {
|
||||
Sys_user_role userRole = new Sys_user_role();
|
||||
userRole.setRoleId(roleId);
|
||||
userRole.setUserId(userId);
|
||||
userRole.setUnionId(unionId);
|
||||
userRole.setUnitId(unitId);
|
||||
dao().insert(userRole);
|
||||
}
|
||||
}
|
||||
|
||||
sysRoleService.clearCache();
|
||||
sysUserService.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.budwk.app.zhgh.dayofficework.outlay.outlayManage.service;
|
||||
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
/**
|
||||
* 分工会预算统计服务。
|
||||
*
|
||||
* <p>统一封装分工会预算使用情况和经费收支情况的全量汇总查询,
|
||||
* 汇总口径与列表查询保持一致,不受分页参数影响。</p>
|
||||
*/
|
||||
public interface OutlayManageUnionStatisticsService extends BaseService {
|
||||
|
||||
/**
|
||||
* 查询分工会预算使用情况的全量合计。
|
||||
*
|
||||
* @param year 统计年度
|
||||
* @param unionId 分工会主键,管理员可为空查询全部
|
||||
* @return 包含 totalQuota、usedQuota、surplusQuota 的合计数据
|
||||
*/
|
||||
NutMap queryUseDetailSummary(Integer year, String unionId);
|
||||
|
||||
/**
|
||||
* 查询分工会经费收支使用情况的全量合计。
|
||||
*
|
||||
* @param year 统计年度
|
||||
* @param unionId 分工会主键,管理员可为空查询全部
|
||||
* @return 包含各项收入、支出和余额字段的合计数据
|
||||
*/
|
||||
NutMap queryIncomeExpenseSummary(Integer year, String unionId);
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
package com.budwk.app.zhgh.dayofficework.outlay.outlayManage.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.service.OutlayManageUnionStatisticsService;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
/**
|
||||
* 分工会预算统计服务实现。
|
||||
*
|
||||
* <p>汇总查询在数据库端完成,避免只汇总当前分页数据,
|
||||
* 同时复用列表的年度、分工会和权限过滤条件。</p>
|
||||
*/
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class OutlayManageUnionStatisticsServiceImpl extends BaseServiceImpl implements OutlayManageUnionStatisticsService {
|
||||
|
||||
public OutlayManageUnionStatisticsServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NutMap queryUseDetailSummary(Integer year, String unionId) {
|
||||
Cnd cnd = buildUnionManageCondition(year, unionId, false);
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
COALESCE(SUM(totalQuota), 0) AS totalQuota,
|
||||
COALESCE(SUM(usedQuota), 0) AS usedQuota,
|
||||
COALESCE(SUM(COALESCE(totalQuota, 0) - COALESCE(usedQuota, 0)), 0) AS surplusQuota
|
||||
FROM outlay_manage_union mu $condition
|
||||
""");
|
||||
sql.setCondition(cnd);
|
||||
return executeMap(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NutMap queryIncomeExpenseSummary(Integer year, String unionId) {
|
||||
Cnd cnd = buildUnionManageCondition(year, unionId, true);
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
COALESCE(SUM(t.beginMoney), 0) AS beginMoney,
|
||||
COALESCE(SUM(t.feeJanApr), 0) AS feeJanApr,
|
||||
COALESCE(SUM(t.feeMayAug), 0) AS feeMayAug,
|
||||
COALESCE(SUM(t.feeSepDec), 0) AS feeSepDec,
|
||||
COALESCE(SUM(t.awardMoney), 0) AS awardMoney,
|
||||
COALESCE(SUM(t.usedMoney), 0) AS usedMoney,
|
||||
COALESCE(SUM(t.remainMoney), 0) AS remainMoney
|
||||
FROM (
|
||||
SELECT
|
||||
mu.unionId,
|
||||
COALESCE(SUM(CASE WHEN au.quarterly = 1 THEN au.allocateHeadMoney ELSE 0 END), 0) AS beginMoney,
|
||||
COALESCE(SUM(CASE WHEN au.quarterly = 1 THEN au.allocateMoney ELSE 0 END), 0) AS feeJanApr,
|
||||
COALESCE(SUM(CASE WHEN au.quarterly = 2 THEN au.allocateMoney ELSE 0 END), 0) AS feeMayAug,
|
||||
COALESCE(SUM(CASE WHEN au.quarterly = 3 THEN au.allocateMoney ELSE 0 END), 0) AS feeSepDec,
|
||||
COALESCE(SUM(CASE WHEN au.quarterly = 4 THEN au.allocateMoney ELSE 0 END), 0) AS awardMoney,
|
||||
COALESCE(mu.usedQuota, 0) AS usedMoney,
|
||||
COALESCE(mu.totalQuota, 0) - COALESCE(mu.usedQuota, 0) AS remainMoney
|
||||
FROM outlay_manage_union mu
|
||||
LEFT JOIN outlay_allocate_union au ON au.year = mu.year
|
||||
AND au.unionId = mu.unionId
|
||||
AND au.delFlag = 0
|
||||
LEFT JOIN sys_union su ON su.id = mu.unionId
|
||||
$condition
|
||||
GROUP BY mu.year, mu.unionId, mu.usedQuota, mu.totalQuota
|
||||
) t
|
||||
""");
|
||||
sql.setCondition(cnd);
|
||||
return executeMap(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造两个列表共用的预算主表过滤条件,保证汇总和分页列表权限口径一致。
|
||||
*/
|
||||
private Cnd buildUnionManageCondition(Integer year, String unionId, boolean includeDelFlag) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (includeDelFlag) {
|
||||
cnd.and("mu.delFlag", "=", false);
|
||||
}
|
||||
cnd.and("mu.year", "=", year == null ? DateUtil.thisYear() : year);
|
||||
cnd.and("mu.totalQuota", "IS NOT", null);
|
||||
cnd.andEX("mu.unionId", "=", unionId);
|
||||
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
|
||||
cnd.and("mu.unionId", "=", SecurityUtil.getUnionId());
|
||||
}
|
||||
return cnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行单行统计查询,并在无数据时返回各字段为零的结果,方便前端直接展示。
|
||||
*/
|
||||
private NutMap executeMap(Sql sql) {
|
||||
sql.setCallback(Sqls.callback.map());
|
||||
dao().execute(sql);
|
||||
NutMap result = (NutMap) sql.getResult();
|
||||
return result == null ? NutMap.NEW() : result;
|
||||
}
|
||||
}
|
||||
+13
@@ -14,6 +14,7 @@ import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.service.OutlayManageUnionStatisticsService;
|
||||
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.union.vo.OutlayUnionIncomeExpenseVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@@ -44,6 +45,8 @@ public class OutlayManageUnionIncomeExpenseController {
|
||||
|
||||
@Inject
|
||||
private BaseService baseService;
|
||||
@Inject
|
||||
private OutlayManageUnionStatisticsService outlayManageUnionStatisticsService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/zhgh/dayofficework/outlay/outlayManage/union/incomeExpense/index.html")
|
||||
@@ -60,6 +63,16 @@ public class OutlayManageUnionIncomeExpenseController {
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前筛选范围内全部分工会经费收支合计,不受分页参数影响。
|
||||
*/
|
||||
@At
|
||||
@ApiOperation("查询经费收支合计")
|
||||
@SaCheckPermission("outlay.outlayManage.union.incomeExpense")
|
||||
public Result summary(Integer year, String unionId) {
|
||||
return Result.success(outlayManageUnionStatisticsService.queryIncomeExpenseSummary(year, unionId));
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
@ApiOperation("导出")
|
||||
|
||||
+13
@@ -12,6 +12,7 @@ import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.model.OutlayUseDetail;
|
||||
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.service.OutlayUseDetailService;
|
||||
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.service.OutlayManageUnionStatisticsService;
|
||||
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.union.model.OutLayAllocateUnion;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@@ -46,6 +47,8 @@ public class OutlayManageUnionUseDetailController {
|
||||
private BaseService baseService;
|
||||
@Inject
|
||||
private OutlayUseDetailService outlayUseDetailService;
|
||||
@Inject
|
||||
private OutlayManageUnionStatisticsService outlayManageUnionStatisticsService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/zhgh/dayofficework/outlay/outlayManage/union/useDetail/index.html")
|
||||
@@ -81,6 +84,16 @@ public class OutlayManageUnionUseDetailController {
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前筛选范围内全部分工会预算使用情况合计,不受分页参数影响。
|
||||
*/
|
||||
@At
|
||||
@ApiOperation("查询预算使用情况合计")
|
||||
@SaCheckPermission("outlay.outlayManage.union.useDetail")
|
||||
public Result summary(Integer year, String unionId) {
|
||||
return Result.success(outlayManageUnionStatisticsService.queryUseDetailSummary(year, unionId));
|
||||
}
|
||||
|
||||
|
||||
@At
|
||||
@ApiOperation("某个分工会预算使用详情")
|
||||
|
||||
+2
-62
@@ -197,34 +197,7 @@ public class TeacherCongressDelegateManageController {
|
||||
@At
|
||||
@SaCheckPermission("tc.delegate.manage")
|
||||
public Result publicUser(@Valid TeacherCongressDelegateManagePublicUserParam param) {
|
||||
List<Teacher_congress_delegation_unit> units = dao.query(Teacher_congress_delegation_unit.class, Cnd.where("sessionId", "=", param.getSessionId()).and("delegationId", "=", param.getDelegationId()));
|
||||
List<String> unitIds = units.stream().map(Teacher_congress_delegation_unit::getUnitId).toList();
|
||||
if (ObjectUtil.isEmpty(unitIds)) {
|
||||
return Result.error("代表团没有组成单位");
|
||||
}
|
||||
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
t1.id,
|
||||
t1.username AS userName,
|
||||
t1.loginName AS loginName,
|
||||
t2.NAME AS unitName
|
||||
FROM
|
||||
`sys_user` t1
|
||||
LEFT JOIN sys_unit t2 ON t2.id = t1.unitId
|
||||
WHERE
|
||||
t1.id NOT IN ( SELECT userId FROM teacher_congress_delegate WHERE sessionId = @sessionId AND delegationId = @delegationId )
|
||||
AND
|
||||
t1.unitId in (@unitIds)
|
||||
AND
|
||||
(t1.loginname like @keyWord or username like @keyWord)
|
||||
""");
|
||||
sql.setParam("sessionId", param.getSessionId());
|
||||
sql.setParam("delegationId", param.getDelegationId());
|
||||
sql.setParam("unitIds", unitIds);
|
||||
sql.setParam("keyWord", "%" + param.getKeyWord() + "%");
|
||||
Pagination pagination = sysUserService.listPageMap(1, 50, sql);
|
||||
return Result.success(pagination.getList());
|
||||
return Result.success(teacherDelegateService.listPublicUsers(param));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -497,40 +470,7 @@ public class TeacherCongressDelegateManageController {
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SaCheckPermission("tc.delegate.manage")
|
||||
public Result doAllocateDelegation(String sessionId) {
|
||||
List<Teacher_congress_delegate> delegateList = dao.query(Teacher_congress_delegate.class,
|
||||
Cnd.where(Teacher_congress_delegate::getSessionId, "=", sessionId)
|
||||
.and(Teacher_congress_delegate::getDelegationId, "is", null));
|
||||
|
||||
for (Teacher_congress_delegate delegate : delegateList) {
|
||||
Teacher_congress_delegation_unit delegation_unit = dao.fetch(Teacher_congress_delegation_unit.class,
|
||||
Cnd.where(Teacher_congress_delegation_unit::getUnitId, "=", delegate.getUnitId())
|
||||
.and(Teacher_congress_delegation_unit::getSessionId, "=", sessionId));
|
||||
if (ObjectUtil.isNotEmpty(delegation_unit)) {
|
||||
delegate.setDelegationId(delegation_unit.getDelegationId());
|
||||
dao.update(delegate);
|
||||
Sys_user_role userRole = new Sys_user_role();
|
||||
userRole.setTcDelegationId(delegation_unit.getDelegationId());
|
||||
userRole.setUserId(delegate.getUserId());
|
||||
userRole.setTcSessionId(sessionId);
|
||||
Sys_role sys_role = dao.fetch(Sys_role.class, Cnd.where(Sys_role::getCode, "=", RoleConstant.TEACHER_CONGRESS_DELEGATE_FORMAL.name()));
|
||||
|
||||
if (sys_role.getId().equals(delegate.getRoleId())) {
|
||||
delegate.setRoleId(sys_role.getId());
|
||||
userRole.setRoleId(sys_role.getId());
|
||||
}
|
||||
|
||||
Sys_role sys_role2 = dao.fetch(Sys_role.class, Cnd.where(Sys_role::getCode, "=", RoleConstant.TEACHER_CONGRESS_DELEGATE_ATTENDANCE.name()));
|
||||
if (sys_role2.getId().equals(delegate.getRoleId())) {
|
||||
delegate.setRoleId(sys_role2.getId());
|
||||
userRole.setRoleId(sys_role2.getId());
|
||||
}
|
||||
userRole.setTcDelegationId(delegate.getDelegationId());
|
||||
teacherCongressSessionService.prepareSessionRole(userRole);
|
||||
dao.insert(userRole);
|
||||
}
|
||||
sysUserService.clearCache();
|
||||
}
|
||||
return Result.success();
|
||||
return Result.success(teacherDelegateService.allocateDelegations(sessionId));
|
||||
}
|
||||
|
||||
|
||||
|
||||
+9
-85
@@ -1,28 +1,14 @@
|
||||
package com.budwk.app.zhgh.democratic.teachercongress.delegate.listener;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.event.user.SysUserEvent;
|
||||
import com.budwk.app.base.event.user.SysUserEventListener;
|
||||
import com.budwk.app.sys.models.Sys_role;
|
||||
import com.budwk.app.sys.models.Sys_user_role;
|
||||
import com.budwk.app.sys.services.SysRoleService;
|
||||
import com.budwk.app.sys.services.SysUserService;
|
||||
import com.budwk.app.sys.views.View_user;
|
||||
import com.budwk.app.zhgh.democratic.proposal.models.ProposalConfig;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_congress_delegate;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation_unit;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.prepare.models.Teacher_congress_session;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.prepare.service.TeacherCongressSessionService;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegate.service.TeacherCongressDelegateService;
|
||||
import com.budwk.app.zhgh.staffmanage.member.constant.MemberChangeType;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nutz.aop.interceptor.async.Async;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author zzr
|
||||
@@ -31,16 +17,11 @@ import java.util.List;
|
||||
* @注释
|
||||
*/
|
||||
@IocBean
|
||||
@Slf4j
|
||||
public class TeacherCongressDelegateListener implements SysUserEventListener {
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
@Inject
|
||||
private SysUserService sysUserService;
|
||||
@Inject
|
||||
private SysRoleService sysRoleService;
|
||||
@Inject
|
||||
private TeacherCongressSessionService teacherCongressSessionService;
|
||||
private TeacherCongressDelegateService teacherCongressDelegateService;
|
||||
|
||||
@Override
|
||||
@Async
|
||||
@@ -49,68 +30,11 @@ public class TeacherCongressDelegateListener implements SysUserEventListener {
|
||||
return;
|
||||
}
|
||||
|
||||
// 人员单位变更只同步当前开启届次,防止误修改历史届次代表及角色关系。
|
||||
Teacher_congress_session session = dao.fetch(Teacher_congress_session.class,
|
||||
Cnd.where(Teacher_congress_session::getEnable, "=", true)
|
||||
.desc(Teacher_congress_session::getStartDate));
|
||||
if (session == null) {
|
||||
return;
|
||||
try {
|
||||
// 保持原有事件范围,仅将监听器内部归团逻辑下沉到事务服务。
|
||||
teacherCongressDelegateService.refreshCurrentDelegateOrganization(event.getUserId());
|
||||
} catch (Exception e) {
|
||||
log.error("刷新教代会代表组织信息失败,userId={}", event.getUserId(), e);
|
||||
}
|
||||
String userId = event.getUserId();
|
||||
//查询校领导的单位
|
||||
ProposalConfig config = dao.fetch(ProposalConfig.class, Cnd.NEW());
|
||||
List<String> schoolLeaderUnitIds = config.getSchoolLeaderUnitIds();
|
||||
|
||||
View_user user = dao.fetch(View_user.class, Cnd.where(View_user::getId, "=", userId));
|
||||
|
||||
//校领导排除在外
|
||||
if (StrUtil.isNotBlank(user.getUnitId()) && schoolLeaderUnitIds.contains(user.getUnitId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
//查询当前代表的信息
|
||||
Teacher_congress_delegate currentDelegate = dao.fetch(Teacher_congress_delegate.class, Cnd.where(Teacher_congress_delegate::getSessionId, "=", session.getId()));
|
||||
if(currentDelegate == null){
|
||||
return;
|
||||
}
|
||||
|
||||
//查询当前分配的单位属于哪个代表团
|
||||
String unitId = user.getUnitId();
|
||||
Teacher_congress_delegation_unit unit = dao.fetch(Teacher_congress_delegation_unit.class, Cnd.where(Teacher_congress_delegation_unit::getSessionId, "=", session)
|
||||
.and(Teacher_congress_delegation_unit::getUnitId, "=", unitId));
|
||||
String delegationId = unit.getDelegationId();
|
||||
|
||||
currentDelegate.setDelegationId(delegationId);
|
||||
currentDelegate.setUnitId(user.getUnitId());
|
||||
currentDelegate.setUnitName(user.getUnitName());
|
||||
currentDelegate.setUnionId(user.getUnionId());
|
||||
currentDelegate.setUnionName(user.getUnionName());
|
||||
dao.updateIgnoreNull(currentDelegate);
|
||||
|
||||
|
||||
//角色数据
|
||||
Sys_role delegateFormalRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_DELEGATE_FORMAL.name());
|
||||
Sys_role delegateAttendanceRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_DELEGATE_ATTENDANCE.name());
|
||||
Sys_role delegateSpeciallyInviteRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_DELEGATE_SPECIALLY_INVITE.name());
|
||||
Sys_role delegationHeadRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_DELEGATION_HEAD.name());
|
||||
|
||||
//删除权限
|
||||
//删除角色数据
|
||||
dao.clear(Sys_user_role.class, Cnd.where(Sys_user_role::getUserId, "=", userId)
|
||||
.and(Sys_user_role::getRoleId, "in", List.of(delegateFormalRole.getId(), delegateAttendanceRole.getId(), delegateSpeciallyInviteRole.getId(), delegationHeadRole.getId()))
|
||||
.and(Sys_user_role::getTcSessionId, "=", session.getId())
|
||||
);
|
||||
|
||||
//再加权限
|
||||
Sys_user_role sysUserRole = new Sys_user_role();
|
||||
sysUserRole.setUserId(userId);
|
||||
sysUserRole.setTcSessionId(session.getId());
|
||||
sysUserRole.setTcDelegationId(currentDelegate.getDelegationId());
|
||||
sysUserRole.setRoleId(currentDelegate.getRoleId());
|
||||
teacherCongressSessionService.prepareSessionRole(sysUserRole);
|
||||
dao.insert(sysUserRole);
|
||||
|
||||
sysUserService.clearCache();
|
||||
sysRoleService.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
+25
@@ -4,6 +4,8 @@ import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_congress_delegate;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegate.param.TeacherCongressDelegateManagePageParam;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegate.param.TeacherCongressDelegateManagePublicUserParam;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
@@ -20,4 +22,27 @@ public interface TeacherCongressDelegateService extends BaseService<Teacher_cong
|
||||
void exportXlsx(TeacherCongressDelegateManagePageParam pageForm, HttpServletResponse response);
|
||||
|
||||
void exportDocx(TeacherCongressDelegateManagePageParam pageForm, HttpServletResponse response);
|
||||
|
||||
/**
|
||||
* 查询当前代表团组成范围内、尚未成为本届代表的人员。
|
||||
*
|
||||
* @param param 届次、代表团及关键字参数
|
||||
* @return 候选人员列表
|
||||
*/
|
||||
List<NutMap> listPublicUsers(TeacherCongressDelegateManagePublicUserParam param);
|
||||
|
||||
/**
|
||||
* 根据系统配置的单位或分工会组成关系,为尚未归团的代表自动分配代表团。
|
||||
*
|
||||
* @param sessionId 届次ID
|
||||
* @return 已分配、未分配数量及未分配人员名称
|
||||
*/
|
||||
NutMap allocateDelegations(String sessionId);
|
||||
|
||||
/**
|
||||
* 人员组织变化后,按当前组成模式刷新其当前届次代表及角色归团信息。
|
||||
*
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
void refreshCurrentDelegateOrganization(String userId);
|
||||
}
|
||||
|
||||
+148
@@ -12,13 +12,24 @@ import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||
import com.budwk.app.base.utils.PageUtil;
|
||||
import com.budwk.app.base.utils.SysOfficeTemplateUtil;
|
||||
import com.budwk.app.sys.models.Sys_role;
|
||||
import com.budwk.app.sys.models.Sys_user_role;
|
||||
import com.budwk.app.sys.services.SysRoleService;
|
||||
import com.budwk.app.sys.services.SysUserService;
|
||||
import com.budwk.app.sys.views.View_user;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_congress_delegate;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegate.param.TeacherCongressDelegateManagePageParam;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegate.param.TeacherCongressDelegateManagePublicUserParam;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegate.vo.TeacherCongressDelegateExcelVO;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.prepare.models.Teacher_congress_session;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.prepare.service.TeacherCongressSessionService;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegation.constant.TeacherCongressDelegationCompositionMode;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation_union;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation_unit;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegation.service.TeacherCongressDelegationService;
|
||||
import com.budwk.app.zhgh.democratic.proposal.models.ProposalConfig;
|
||||
import com.budwk.app.base.exception.BaseException;
|
||||
import com.deepoove.poi.XWPFTemplate;
|
||||
import com.deepoove.poi.config.Configure;
|
||||
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
|
||||
@@ -30,6 +41,8 @@ import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
@@ -39,6 +52,8 @@ import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class TeacherCongressDelegateServiceImpl extends BaseServiceImpl<Teacher_congress_delegate> implements TeacherCongressDelegateService {
|
||||
@@ -52,6 +67,139 @@ public class TeacherCongressDelegateServiceImpl extends BaseServiceImpl<Teacher_
|
||||
private SysOfficeTemplateUtil sysOfficeTemplateUtil;
|
||||
@Inject
|
||||
private ProposalCommonService proposalCommonService;
|
||||
@Inject
|
||||
private SysUserService sysUserService;
|
||||
@Inject
|
||||
private TeacherCongressSessionService teacherCongressSessionService;
|
||||
@Inject
|
||||
private TeacherCongressDelegationService teacherCongressDelegationService;
|
||||
|
||||
/**
|
||||
* 查询当前组成模式覆盖的候选人员,并按整个届次排除已存在代表,防止一人重复加入多个代表团。
|
||||
*/
|
||||
@Override
|
||||
public List<NutMap> listPublicUsers(TeacherCongressDelegateManagePublicUserParam param) {
|
||||
TeacherCongressDelegationCompositionMode mode = teacherCongressDelegationService.getCompositionMode();
|
||||
List<String> organizationIds;
|
||||
if (mode == TeacherCongressDelegationCompositionMode.UNION) {
|
||||
organizationIds = dao().query(Teacher_congress_delegation_union.class,
|
||||
Cnd.where(Teacher_congress_delegation_union::getSessionId, "=", param.getSessionId())
|
||||
.and(Teacher_congress_delegation_union::getDelegationId, "=", param.getDelegationId()))
|
||||
.stream().map(Teacher_congress_delegation_union::getUnionId).toList();
|
||||
} else {
|
||||
organizationIds = dao().query(Teacher_congress_delegation_unit.class,
|
||||
Cnd.where(Teacher_congress_delegation_unit::getSessionId, "=", param.getSessionId())
|
||||
.and(Teacher_congress_delegation_unit::getDelegationId, "=", param.getDelegationId()))
|
||||
.stream().map(Teacher_congress_delegation_unit::getUnitId).toList();
|
||||
}
|
||||
if (organizationIds.isEmpty()) {
|
||||
throw new BaseException("代表团没有组成" + mode.getLabel());
|
||||
}
|
||||
|
||||
String organizationColumn = mode == TeacherCongressDelegationCompositionMode.UNION ? "u.unionId" : "u.unitId";
|
||||
Sql sql = Sqls.create("SELECT u.id,u.username AS userName,u.loginname AS loginName,u.unitName,u.unionName " +
|
||||
"FROM vw_user u WHERE u.id NOT IN (SELECT userId FROM teacher_congress_delegate WHERE sessionId=@sessionId) " +
|
||||
"AND " + organizationColumn + " IN (@organizationIds) " +
|
||||
"AND (u.loginname LIKE @keyword OR u.username LIKE @keyword) ORDER BY u.loginname LIMIT 50");
|
||||
sql.setParam("sessionId", param.getSessionId());
|
||||
sql.setParam("organizationIds", organizationIds);
|
||||
sql.setParam("keyword", "%" + param.getKeyWord() + "%");
|
||||
return listMap(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为当前届次未归团代表批量解析代表团,同时刷新其届次代表角色,避免重复生成角色关系。
|
||||
*/
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public NutMap allocateDelegations(String sessionId) {
|
||||
List<Teacher_congress_delegate> delegates = query(Cnd.where(Teacher_congress_delegate::getSessionId, "=", sessionId)
|
||||
.and(Teacher_congress_delegate::getDelegationId, "is", null));
|
||||
List<String> unassignedNames = new ArrayList<>();
|
||||
int assignedCount = 0;
|
||||
for (Teacher_congress_delegate delegate : delegates) {
|
||||
String delegationId = teacherCongressDelegationService.resolveDelegationId(sessionId, delegate.getUnitId(), delegate.getUnionId());
|
||||
if (StrUtil.isBlank(delegationId)) {
|
||||
unassignedNames.add(delegate.getUserName() + "(" + delegate.getLoginName() + ")");
|
||||
continue;
|
||||
}
|
||||
delegate.setDelegationId(delegationId);
|
||||
updateIgnoreNull(delegate);
|
||||
replaceDelegateRole(delegate);
|
||||
assignedCount++;
|
||||
}
|
||||
sysUserService.clearCache();
|
||||
return NutMap.NEW().addv("assignedCount", assignedCount)
|
||||
.addv("unassignedCount", unassignedNames.size()).addv("unassignedNames", unassignedNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* 人员组织变更事件只处理当前开启届次;代表身份保留,代表团负责人角色在跨团时清理。
|
||||
*/
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void refreshCurrentDelegateOrganization(String userId) {
|
||||
Teacher_congress_session session = dao().fetch(Teacher_congress_session.class,
|
||||
Cnd.where(Teacher_congress_session::getEnable, "=", true).desc(Teacher_congress_session::getStartDate));
|
||||
if (session == null) {
|
||||
return;
|
||||
}
|
||||
View_user user = dao().fetch(View_user.class, Cnd.where(View_user::getId, "=", userId));
|
||||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
ProposalConfig config = dao().fetch(ProposalConfig.class, Cnd.NEW());
|
||||
if (config != null && config.getSchoolLeaderUnitIds() != null
|
||||
&& StrUtil.isNotBlank(user.getUnitId()) && config.getSchoolLeaderUnitIds().contains(user.getUnitId())) {
|
||||
return;
|
||||
}
|
||||
Teacher_congress_delegate delegate = fetch(Cnd.where(Teacher_congress_delegate::getSessionId, "=", session.getId())
|
||||
.and(Teacher_congress_delegate::getUserId, "=", userId));
|
||||
if (delegate == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String oldDelegationId = delegate.getDelegationId();
|
||||
String newDelegationId = teacherCongressDelegationService.resolveDelegationId(session.getId(), user.getUnitId(), user.getUnionId());
|
||||
delegate.setDelegationId(newDelegationId);
|
||||
delegate.setUnitId(user.getUnitId());
|
||||
delegate.setUnitName(user.getUnitName());
|
||||
delegate.setUnionId(user.getUnionId());
|
||||
delegate.setUnionName(user.getUnionName());
|
||||
delegate.setMobile(user.getMobile());
|
||||
update(delegate);
|
||||
replaceDelegateRole(delegate);
|
||||
if (!java.util.Objects.equals(oldDelegationId, newDelegationId)) {
|
||||
clearDelegationManagerRoles(userId, session.getId());
|
||||
}
|
||||
sysUserService.clearCache();
|
||||
sysRoleService.clearCache();
|
||||
}
|
||||
|
||||
/** 替换代表本届次的同一身份角色,确保角色中的代表团ID与代表表一致。 */
|
||||
private void replaceDelegateRole(Teacher_congress_delegate delegate) {
|
||||
dao().clear(Sys_user_role.class, Cnd.where(Sys_user_role::getUserId, "=", delegate.getUserId())
|
||||
.and(Sys_user_role::getRoleId, "=", delegate.getRoleId())
|
||||
.and(Sys_user_role::getTcSessionId, "=", delegate.getSessionId()));
|
||||
Sys_user_role role = new Sys_user_role();
|
||||
role.setUserId(delegate.getUserId());
|
||||
role.setRoleId(delegate.getRoleId());
|
||||
role.setTcSessionId(delegate.getSessionId());
|
||||
role.setTcDelegationId(delegate.getDelegationId());
|
||||
teacherCongressSessionService.prepareSessionRole(role);
|
||||
dao().insert(role);
|
||||
}
|
||||
|
||||
/** 跨代表团后清理团长、副团长及联络人角色,避免保留原代表团管理权限。 */
|
||||
private void clearDelegationManagerRoles(String userId, String sessionId) {
|
||||
Set<String> roleIds = new HashSet<>();
|
||||
roleIds.add(sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_DELEGATION_HEAD).getId());
|
||||
roleIds.add(sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_VICE_DELEGATION_HEAD).getId());
|
||||
roleIds.add(sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_DELEGATION_CONTACT).getId());
|
||||
dao().clear(Sys_user_role.class, Cnd.where(Sys_user_role::getUserId, "=", userId)
|
||||
.and(Sys_user_role::getTcSessionId, "=", sessionId)
|
||||
.and(Sys_user_role::getRoleId, "in", roleIds));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pagination<Teacher_congress_delegate> pageData(TeacherCongressDelegateManagePageParam pageForm) {
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.budwk.app.zhgh.democratic.teachercongress.delegation.constant;
|
||||
|
||||
/**
|
||||
* 代表团组成模式。
|
||||
*
|
||||
* <p>系统参数 {@code dbtzc} 为 {@code unit} 时按单位组成,
|
||||
* 为 {@code union} 时按分工会组成;空值或非法值统一兼容为单位模式。</p>
|
||||
*/
|
||||
public enum TeacherCongressDelegationCompositionMode {
|
||||
UNIT("unit", "单位"),
|
||||
UNION("union", "分工会");
|
||||
|
||||
private final String code;
|
||||
private final String label;
|
||||
|
||||
TeacherCongressDelegationCompositionMode(String code, String label) {
|
||||
this.code = code;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将系统参数转换为组成模式,非法配置按历史默认行为使用单位模式。
|
||||
*
|
||||
* @param value 系统参数值
|
||||
* @return 有效组成模式
|
||||
*/
|
||||
public static TeacherCongressDelegationCompositionMode from(String value) {
|
||||
if (UNION.code.equalsIgnoreCase(value)) {
|
||||
return UNION;
|
||||
}
|
||||
return UNIT;
|
||||
}
|
||||
}
|
||||
+35
-51
@@ -170,45 +170,18 @@ public class TeacherCongressDelegationController {
|
||||
@At
|
||||
@SaCheckPermission("tc.delegation")
|
||||
public Result partUnitTransferData(@Valid String delegationId, @Valid String sessionId) {
|
||||
//找出本届次已经设置了代表团的所有单位
|
||||
List<Teacher_congress_delegation_unit> delegationUnits = dao.query(Teacher_congress_delegation_unit.class, Cnd.where("sessionId", "=", sessionId));
|
||||
List<String> unitIds = delegationUnits.stream().map(Teacher_congress_delegation_unit::getUnitId).toList();
|
||||
|
||||
//找出本代表团的单位
|
||||
List<String> selectUnitIds = delegationUnits.stream().filter(unit -> unit.getDelegationId().equals(delegationId)).map(Teacher_congress_delegation_unit::getUnitId).toList();
|
||||
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
seg.orEX("id", "not in", unitIds);
|
||||
seg.orEX("id", "in", selectUnitIds);
|
||||
|
||||
// Cnd cnd = Cnd.where("unitLevel", "=", 2);
|
||||
Cnd cnd = Cnd.where("unitTypeCode", "=", "1");
|
||||
if (!seg.isEmpty()) {
|
||||
cnd.and(seg);
|
||||
}
|
||||
cnd.asc("unitcode");
|
||||
|
||||
List<Sys_unit> units = dao.query(Sys_unit.class, cnd);
|
||||
|
||||
NutMap transferData = NutMap.NEW().addv("selectUnitIds", selectUnitIds).addv("allUnits", units);
|
||||
return Result.success(transferData);
|
||||
NutMap data = teacherCongressDelegationService.getCompositionTransferData(sessionId, delegationId);
|
||||
// 保留旧接口字段,兼容未同步更新的历史页面调用。
|
||||
data.put("selectUnitIds", data.get("selectedIds"));
|
||||
data.put("allUnits", data.get("allItems"));
|
||||
return Result.success(data);
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("tc.delegation")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public Result partUnitSet(@Valid String delegationId, @Valid String sessionId, @Param("unitIds") String[] unitIds) {
|
||||
dao.clear(Teacher_congress_delegation_unit.class, Cnd.where("delegationId", "=", delegationId).and("sessionId", "=", sessionId));
|
||||
|
||||
List<Teacher_congress_delegation_unit> insertData = Arrays.stream(unitIds).map(unitId -> {
|
||||
Teacher_congress_delegation_unit delegationUnit = new Teacher_congress_delegation_unit();
|
||||
delegationUnit.setUnitId(unitId);
|
||||
delegationUnit.setDelegationId(delegationId);
|
||||
delegationUnit.setSessionId(sessionId);
|
||||
return delegationUnit;
|
||||
}).toList();
|
||||
|
||||
dao.insert(insertData);
|
||||
teacherCongressDelegationService.saveComposition(sessionId, delegationId, unitIds);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@@ -222,24 +195,35 @@ public class TeacherCongressDelegationController {
|
||||
@At
|
||||
@SaCheckPermission("tc.delegation")
|
||||
public Result partUnitPageData(@Valid PageForm pageForm, @Valid String sessionId, @Valid String delegationId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
t2.id,
|
||||
t2.`name`
|
||||
FROM
|
||||
teacher_congress_delegation_unit t1
|
||||
LEFT JOIN sys_unit t2 ON t2.id = t1.unitId
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.and("t1.delegationId", "=", delegationId);
|
||||
cnd.and("t1.sessionId", "=", sessionId);
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
cnd.where().andLike("t2.name", pageForm.getSearchKeyword());
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
return Result.success(pagination);
|
||||
return Result.success(teacherCongressDelegationService.pageComposition(pageForm, sessionId, delegationId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前配置模式下的代表团组成选择数据。
|
||||
*/
|
||||
@At
|
||||
@SaCheckPermission("tc.delegation")
|
||||
public Result compositionTransferData(@Valid String delegationId, @Valid String sessionId) {
|
||||
return Result.success(teacherCongressDelegationService.getCompositionTransferData(sessionId, delegationId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存当前配置模式下的代表团组成关系。
|
||||
*/
|
||||
@At
|
||||
@SaCheckPermission("tc.delegation")
|
||||
public Result compositionSet(@Valid String delegationId, @Valid String sessionId, @Param("itemIds") String[] itemIds) {
|
||||
teacherCongressDelegationService.saveComposition(sessionId, delegationId, itemIds);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询当前配置模式下的代表团组成关系。
|
||||
*/
|
||||
@At
|
||||
@SaCheckPermission("tc.delegation")
|
||||
public Result compositionPageData(@Valid PageForm pageForm, @Valid String sessionId, @Valid String delegationId) {
|
||||
return Result.success(teacherCongressDelegationService.pageComposition(pageForm, sessionId, delegationId));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+49
-1
@@ -1,6 +1,9 @@
|
||||
package com.budwk.app.zhgh.democratic.teachercongress.delegation.service;
|
||||
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegation.constant.TeacherCongressDelegationCompositionMode;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
@@ -11,6 +14,51 @@ import java.util.List;
|
||||
*/
|
||||
public interface TeacherCongressDelegationService extends BaseService<Teacher_congress_delegation> {
|
||||
|
||||
/**
|
||||
* 获取当前代表团组成模式。
|
||||
*
|
||||
* @return 单位或分工会模式
|
||||
*/
|
||||
TeacherCongressDelegationCompositionMode getCompositionMode();
|
||||
|
||||
/**
|
||||
* 获取代表团组成选择器数据,已被其他代表团占用的数据不会返回。
|
||||
*
|
||||
* @param sessionId 届次ID
|
||||
* @param delegationId 代表团ID
|
||||
* @return 组成模式、当前选中ID及可选项
|
||||
*/
|
||||
NutMap getCompositionTransferData(String sessionId, String delegationId);
|
||||
|
||||
/**
|
||||
* 保存当前模式下的代表团组成关系。
|
||||
*
|
||||
* @param sessionId 届次ID
|
||||
* @param delegationId 代表团ID
|
||||
* @param itemIds 单位ID或分工会ID
|
||||
*/
|
||||
void saveComposition(String sessionId, String delegationId, String[] itemIds);
|
||||
|
||||
/**
|
||||
* 分页查询当前模式下的代表团组成数据。
|
||||
*
|
||||
* @param pageForm 分页查询参数
|
||||
* @param sessionId 届次ID
|
||||
* @param delegationId 代表团ID
|
||||
* @return 组成数据分页结果
|
||||
*/
|
||||
Pagination pageComposition(PageForm pageForm, String sessionId, String delegationId);
|
||||
|
||||
/**
|
||||
* 按当前组成模式解析人员所属代表团。
|
||||
*
|
||||
* @param sessionId 届次ID
|
||||
* @param unitId 人员单位ID
|
||||
* @param unionId 人员分工会ID
|
||||
* @return 代表团ID,未配置时返回空
|
||||
*/
|
||||
String resolveDelegationId(String sessionId, String unitId, String unionId);
|
||||
|
||||
/**
|
||||
* 按角色查询代表团负责人信息。
|
||||
*
|
||||
@@ -41,4 +89,4 @@ public interface TeacherCongressDelegationService extends BaseService<Teacher_co
|
||||
* @param type 负责人角色编码
|
||||
*/
|
||||
void deleteHeadUser(String sessionId, String delegationId, String userId, String type);
|
||||
}
|
||||
}
|
||||
|
||||
+209
@@ -3,15 +3,23 @@ package com.budwk.app.zhgh.democratic.teachercongress.delegation.service.impl;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.exception.BaseException;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.sys.models.Sys_role;
|
||||
import com.budwk.app.sys.models.Sys_union;
|
||||
import com.budwk.app.sys.models.Sys_unit;
|
||||
import com.budwk.app.sys.models.Sys_user_role;
|
||||
import com.budwk.app.sys.services.SysRoleService;
|
||||
import com.budwk.app.sys.services.SysUserService;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_congress_delegate;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation_union;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation_unit;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegation.constant.TeacherCongressDelegationCompositionMode;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegation.service.TeacherCongressDelegationService;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.prepare.service.TeacherCongressSessionService;
|
||||
import com.budwk.app.web.commons.base.Globals;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.Chain;
|
||||
import org.nutz.dao.Cnd;
|
||||
@@ -24,6 +32,8 @@ import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -47,6 +57,205 @@ public class TeacherCongressDelegationServiceImpl extends BaseServiceImpl<Teache
|
||||
super(dao);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取代表团组成配置;配置缺失或异常时沿用单位模式,保证历史环境可正常使用。
|
||||
*
|
||||
* @return 当前代表团组成模式
|
||||
*/
|
||||
@Override
|
||||
public TeacherCongressDelegationCompositionMode getCompositionMode() {
|
||||
return TeacherCongressDelegationCompositionMode.from(Globals.MyConfig.getString("dbtzc"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前代表团可选择的单位或分工会,排除本届次中已归属其他代表团的数据。
|
||||
*/
|
||||
@Override
|
||||
public NutMap getCompositionTransferData(String sessionId, String delegationId) {
|
||||
validateDelegation(sessionId, delegationId);
|
||||
TeacherCongressDelegationCompositionMode mode = getCompositionMode();
|
||||
List<String> occupiedIds = new ArrayList<>();
|
||||
List<String> selectedIds = new ArrayList<>();
|
||||
List<NutMap> allItems = new ArrayList<>();
|
||||
|
||||
if (mode == TeacherCongressDelegationCompositionMode.UNION) {
|
||||
List<Teacher_congress_delegation_union> relations = dao().query(Teacher_congress_delegation_union.class,
|
||||
Cnd.where(Teacher_congress_delegation_union::getSessionId, "=", sessionId));
|
||||
relations.forEach(relation -> {
|
||||
occupiedIds.add(relation.getUnionId());
|
||||
if (delegationId.equals(relation.getDelegationId())) {
|
||||
selectedIds.add(relation.getUnionId());
|
||||
}
|
||||
});
|
||||
Cnd cnd = buildAvailableCondition(occupiedIds, selectedIds);
|
||||
cnd.asc(Sys_union::getUnionCode);
|
||||
dao().query(Sys_union.class, cnd).forEach(item -> allItems.add(NutMap.NEW()
|
||||
.addv("id", item.getId()).addv("name", item.getName()).addv("code", item.getUnionCode())));
|
||||
} else {
|
||||
List<Teacher_congress_delegation_unit> relations = dao().query(Teacher_congress_delegation_unit.class,
|
||||
Cnd.where(Teacher_congress_delegation_unit::getSessionId, "=", sessionId));
|
||||
relations.forEach(relation -> {
|
||||
occupiedIds.add(relation.getUnitId());
|
||||
if (delegationId.equals(relation.getDelegationId())) {
|
||||
selectedIds.add(relation.getUnitId());
|
||||
}
|
||||
});
|
||||
Cnd cnd = Cnd.where(Sys_unit::getUnitTypeCode, "=", "1");
|
||||
appendAvailableCondition(cnd, occupiedIds, selectedIds);
|
||||
cnd.asc(Sys_unit::getUnitcode);
|
||||
dao().query(Sys_unit.class, cnd).forEach(item -> allItems.add(NutMap.NEW()
|
||||
.addv("id", item.getId()).addv("name", item.getName()).addv("code", item.getUnitcode())));
|
||||
}
|
||||
return NutMap.NEW().addv("mode", mode.getCode()).addv("label", mode.getLabel())
|
||||
.addv("selectedIds", selectedIds).addv("allItems", allItems);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存当前组成模式对应的关联表,并在写入前校验跨代表团重复占用。
|
||||
*/
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void saveComposition(String sessionId, String delegationId, String[] itemIds) {
|
||||
validateDelegation(sessionId, delegationId);
|
||||
List<String> normalizedIds = itemIds == null ? Collections.emptyList() : Arrays.stream(itemIds)
|
||||
.filter(StrUtil::isNotBlank).distinct().toList();
|
||||
TeacherCongressDelegationCompositionMode mode = getCompositionMode();
|
||||
if (mode == TeacherCongressDelegationCompositionMode.UNION) {
|
||||
validateUnionIds(normalizedIds);
|
||||
int occupied = normalizedIds.isEmpty() ? 0 : dao().count(Teacher_congress_delegation_union.class,
|
||||
Cnd.where(Teacher_congress_delegation_union::getSessionId, "=", sessionId)
|
||||
.and(Teacher_congress_delegation_union::getDelegationId, "!=", delegationId)
|
||||
.and(Teacher_congress_delegation_union::getUnionId, "in", normalizedIds));
|
||||
if (occupied > 0) {
|
||||
throw new BaseException("所选分工会已被其他代表团使用,请刷新后重试");
|
||||
}
|
||||
dao().clear(Teacher_congress_delegation_union.class, Cnd.where(Teacher_congress_delegation_union::getSessionId, "=", sessionId)
|
||||
.and(Teacher_congress_delegation_union::getDelegationId, "=", delegationId));
|
||||
normalizedIds.forEach(itemId -> {
|
||||
Teacher_congress_delegation_union relation = new Teacher_congress_delegation_union();
|
||||
relation.setSessionId(sessionId);
|
||||
relation.setDelegationId(delegationId);
|
||||
relation.setUnionId(itemId);
|
||||
dao().insert(relation);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
validateUnitIds(normalizedIds);
|
||||
int occupied = normalizedIds.isEmpty() ? 0 : dao().count(Teacher_congress_delegation_unit.class,
|
||||
Cnd.where(Teacher_congress_delegation_unit::getSessionId, "=", sessionId)
|
||||
.and(Teacher_congress_delegation_unit::getDelegationId, "!=", delegationId)
|
||||
.and(Teacher_congress_delegation_unit::getUnitId, "in", normalizedIds));
|
||||
if (occupied > 0) {
|
||||
throw new BaseException("所选单位已被其他代表团使用,请刷新后重试");
|
||||
}
|
||||
dao().clear(Teacher_congress_delegation_unit.class, Cnd.where(Teacher_congress_delegation_unit::getSessionId, "=", sessionId)
|
||||
.and(Teacher_congress_delegation_unit::getDelegationId, "=", delegationId));
|
||||
normalizedIds.forEach(itemId -> {
|
||||
Teacher_congress_delegation_unit relation = new Teacher_congress_delegation_unit();
|
||||
relation.setSessionId(sessionId);
|
||||
relation.setDelegationId(delegationId);
|
||||
relation.setUnitId(itemId);
|
||||
dao().insert(relation);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询当前模式下的组成关系,统一向前端返回 id、name、code 字段。
|
||||
*/
|
||||
@Override
|
||||
public Pagination pageComposition(PageForm pageForm, String sessionId, String delegationId) {
|
||||
validateDelegation(sessionId, delegationId);
|
||||
boolean unionMode = getCompositionMode() == TeacherCongressDelegationCompositionMode.UNION;
|
||||
String sqlText = unionMode
|
||||
? "SELECT t2.id,t2.name,t2.unionCode AS code FROM teacher_congress_delegation_union t1 LEFT JOIN sys_union t2 ON t2.id=t1.unionId $condition"
|
||||
: "SELECT t2.id,t2.name,t2.unitcode AS code FROM teacher_congress_delegation_unit t1 LEFT JOIN sys_unit t2 ON t2.id=t1.unitId $condition";
|
||||
Sql sql = Sqls.create(sqlText);
|
||||
Cnd cnd = Cnd.where("t1.sessionId", "=", sessionId).and("t1.delegationId", "=", delegationId);
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
cnd.where().andLike("t2.name", pageForm.getSearchKeyword());
|
||||
}
|
||||
cnd.asc("code");
|
||||
sql.setCondition(cnd);
|
||||
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按当前模式精确解析代表团;同一组织存在多条关系时拒绝随机匹配,避免代表被错误归团。
|
||||
*/
|
||||
@Override
|
||||
public String resolveDelegationId(String sessionId, String unitId, String unionId) {
|
||||
TeacherCongressDelegationCompositionMode mode = getCompositionMode();
|
||||
if (mode == TeacherCongressDelegationCompositionMode.UNION) {
|
||||
if (StrUtil.isBlank(unionId)) {
|
||||
return null;
|
||||
}
|
||||
List<Teacher_congress_delegation_union> relations = dao().query(Teacher_congress_delegation_union.class,
|
||||
Cnd.where(Teacher_congress_delegation_union::getSessionId, "=", sessionId)
|
||||
.and(Teacher_congress_delegation_union::getUnionId, "=", unionId));
|
||||
return resolveUniqueDelegation(relations.stream().map(Teacher_congress_delegation_union::getDelegationId).toList(), "分工会");
|
||||
}
|
||||
if (StrUtil.isBlank(unitId)) {
|
||||
return null;
|
||||
}
|
||||
List<Teacher_congress_delegation_unit> relations = dao().query(Teacher_congress_delegation_unit.class,
|
||||
Cnd.where(Teacher_congress_delegation_unit::getSessionId, "=", sessionId)
|
||||
.and(Teacher_congress_delegation_unit::getUnitId, "=", unitId));
|
||||
return resolveUniqueDelegation(relations.stream().map(Teacher_congress_delegation_unit::getDelegationId).toList(), "单位");
|
||||
}
|
||||
|
||||
private Cnd buildAvailableCondition(List<String> occupiedIds, List<String> selectedIds) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
appendAvailableCondition(cnd, occupiedIds, selectedIds);
|
||||
return cnd;
|
||||
}
|
||||
|
||||
/** 当前代表团已选项允许继续显示,其余已占用项从选择器中排除。 */
|
||||
private void appendAvailableCondition(Cnd cnd, List<String> occupiedIds, List<String> selectedIds) {
|
||||
if (occupiedIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (selectedIds.isEmpty()) {
|
||||
cnd.and("id", "not in", occupiedIds);
|
||||
return;
|
||||
}
|
||||
cnd.and(Cnd.exps("id", "not in", occupiedIds).or("id", "in", selectedIds));
|
||||
}
|
||||
|
||||
/** 校验代表团确实属于当前届次,防止跨届次写入组成关系。 */
|
||||
private void validateDelegation(String sessionId, String delegationId) {
|
||||
if (dao().count(Teacher_congress_delegation.class, Cnd.where(Teacher_congress_delegation::getId, "=", delegationId)
|
||||
.and(Teacher_congress_delegation::getSessionId, "=", sessionId)) != 1) {
|
||||
throw new BaseException("代表团或届次参数错误");
|
||||
}
|
||||
}
|
||||
|
||||
/** 校验提交的分工会ID均真实存在。 */
|
||||
private void validateUnionIds(List<String> ids) {
|
||||
if (!ids.isEmpty() && dao().count(Sys_union.class, Cnd.where(Sys_union::getId, "in", ids)) != ids.size()) {
|
||||
throw new BaseException("所选分工会数据不存在,请刷新后重试");
|
||||
}
|
||||
}
|
||||
|
||||
/** 校验提交的单位ID均真实存在且属于代表团可用的单位类型。 */
|
||||
private void validateUnitIds(List<String> ids) {
|
||||
if (!ids.isEmpty() && dao().count(Sys_unit.class, Cnd.where(Sys_unit::getId, "in", ids)
|
||||
.and(Sys_unit::getUnitTypeCode, "=", "1")) != ids.size()) {
|
||||
throw new BaseException("所选单位数据不存在,请刷新后重试");
|
||||
}
|
||||
}
|
||||
|
||||
/** 对组织与代表团关系执行唯一性校验。 */
|
||||
private String resolveUniqueDelegation(List<String> delegationIds, String label) {
|
||||
if (delegationIds.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (delegationIds.size() > 1) {
|
||||
throw new BaseException(label + "存在重复代表团关系,请先检查代表团组成配置");
|
||||
}
|
||||
return delegationIds.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按角色查询代表团负责人信息,副团长允许返回多条记录以兼容V3多副团长数据。
|
||||
*
|
||||
|
||||
+6
-16
@@ -22,6 +22,7 @@ import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_con
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation_union;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation_unit;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegation.service.TeacherCongressDelegationService;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.institution.models.Teacher_congress_institution;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.institution.models.Teacher_congress_institution_user;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.meetings.models.Teacher_congress_meeting;
|
||||
@@ -57,6 +58,8 @@ public class TeacherCongressSessionServiceImpl extends BaseServiceImpl<Teacher_c
|
||||
private SysRoleService sysRoleService;
|
||||
@Inject
|
||||
private SysUserService sysUserService;
|
||||
@Inject
|
||||
private TeacherCongressDelegationService teacherCongressDelegationService;
|
||||
|
||||
public TeacherCongressSessionServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
@@ -237,22 +240,9 @@ public class TeacherCongressSessionServiceImpl extends BaseServiceImpl<Teacher_c
|
||||
newDelegate.setSex(vwUser.getSex());
|
||||
newDelegate.setMobile(vwUser.getMobile());
|
||||
|
||||
//去查询他当前所处的单位、分工会处于哪个代表团
|
||||
if (StrUtil.isNotBlank(vwUser.getUnionId())) {
|
||||
Teacher_congress_delegation_union delegationUnion = dao().fetch(Teacher_congress_delegation_union.class, Cnd.where(Teacher_congress_delegation_union::getSessionId, "=", session.getId())
|
||||
.and(Teacher_congress_delegation_union::getUnionId, "=", vwUser.getUnionId()));
|
||||
if (ObjectUtil.isNotEmpty(delegationUnion)) {
|
||||
newDelegate.setDelegationId(delegationUnion.getDelegationId());
|
||||
}
|
||||
}
|
||||
|
||||
if (StrUtil.isNotBlank(vwUser.getUnitId())) {
|
||||
Teacher_congress_delegation_unit delegationUnit = dao().fetch(Teacher_congress_delegation_unit.class, Cnd.where(Teacher_congress_delegation_unit::getSessionId, "=", session.getId())
|
||||
.and(Teacher_congress_delegation_unit::getUnitId, "=", vwUser.getUnitId()));
|
||||
if (ObjectUtil.isNotEmpty(delegationUnit)) {
|
||||
newDelegate.setDelegationId(delegationUnit.getDelegationId());
|
||||
}
|
||||
}
|
||||
// 延用代表时严格按 dbtzc 当前模式归团,避免单位关系覆盖分工会关系。
|
||||
newDelegate.setDelegationId(teacherCongressDelegationService.resolveDelegationId(
|
||||
session.getId(), vwUser.getUnitId(), vwUser.getUnionId()));
|
||||
}
|
||||
|
||||
// 以代表团编码判断是否发生代表团异动,并完整保存延用前后的组织信息。
|
||||
|
||||
+25
-4
@@ -5,6 +5,7 @@ import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.DesensitizedUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@@ -16,10 +17,13 @@ import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||
import com.budwk.app.sys.models.Sys_role;
|
||||
import com.budwk.app.sys.models.Sys_user;
|
||||
import com.budwk.app.sys.models.Sys_user_history;
|
||||
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.SecurityUtil;
|
||||
import com.budwk.app.zhgh.staffmanage.member.constant.MemberChangeOrigin;
|
||||
import com.budwk.app.zhgh.staffmanage.member.constant.MemberChangeType;
|
||||
import com.budwk.app.zhgh.staffmanage.member.param.MemberBatchMakeParam;
|
||||
import com.budwk.app.zhgh.staffmanage.member.param.pageform.MemberInfoPageForm;
|
||||
import com.budwk.app.zhgh.staffmanage.member.param.pageform.MemberStatisticsPageForm;
|
||||
@@ -42,11 +46,9 @@ import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
@@ -132,6 +134,25 @@ public class MemberBatchMakeController {
|
||||
}).toList();
|
||||
dao.insert(roleList);
|
||||
|
||||
// 添加人员变更记录
|
||||
String MemberChangeTypeName = MemberChangeType.RESTORE.name();
|
||||
final Date date = new Date();
|
||||
List<Sys_user> sysUsers = dao.query(Sys_user.class, Cnd.where("id", "in", userIds));
|
||||
List<Sys_user_history> sysUserHistoryStream = sysUsers.stream().map(e -> {
|
||||
Sys_user_history sysUserHistory = new Sys_user_history();
|
||||
BeanUtil.copyProperties(e, sysUserHistory);
|
||||
sysUserHistory.setChangeTypes(List.of(MemberChangeTypeName));
|
||||
sysUserHistory.setChangeTime(date);
|
||||
NutMap change = NutMap.NEW();
|
||||
change.put("fieldName", "会员状态");
|
||||
change.put("field", "member");
|
||||
change.put("sourceValue", "否");
|
||||
change.put("newValue", "是");
|
||||
sysUserHistory.setChangeInfos(List.of(change));
|
||||
sysUserHistory.setChangeOrigin(MemberChangeOrigin.HAND_MOVEMENT.name());
|
||||
return sysUserHistory;
|
||||
}).collect(Collectors.toList());
|
||||
dao.insert(sysUserHistoryStream);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,54 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style>
|
||||
/* 系统参数页面固定占满平台内容区,避免页面主体产生纵向滚动条。 */
|
||||
#app .sys-conf-layout {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
height: calc(100vh - 82px);
|
||||
overflow: hidden;
|
||||
}
|
||||
#app .sys-conf-query-card {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
/* 列表卡片占用剩余空间,数据超出时仅由 Element 表格内部滚动。 */
|
||||
#app .sys-conf-list-card {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
#app .sys-conf-list-card > .el-card__body {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
#app .sys-conf-list-card .ele-table-tool,
|
||||
#app .sys-conf-list-card .el-pagination-container {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
</style>
|
||||
<div id="app" v-cloak>
|
||||
<guava>
|
||||
<el-card shadow="never">
|
||||
<el-row type="flex" justify="end">
|
||||
<el-button @click="openAdd" size="medium" type="primary">
|
||||
<i class="ti-plus"></i>
|
||||
添加配置项
|
||||
</el-button>
|
||||
</el-row>
|
||||
<div class="sys-conf-layout">
|
||||
<el-card class="sys-conf-query-card" shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="参数名">
|
||||
<el-input v-model="pageForm.configKey" clearable placeholder="请输入参数名"
|
||||
@keyup.enter.native="doSearch"></el-input>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
<el-card class="mt10" shadow="never">
|
||||
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%">
|
||||
<el-card class="mt10 sys-conf-list-card" shadow="never">
|
||||
<table-tool label="系统参数">
|
||||
<el-button @click="openAdd" size="small" type="primary" icon="el-icon-plus">新增</el-button>
|
||||
</table-tool>
|
||||
<el-table v-loading="tableLoading" :data="tableData" :height="tableHeight"
|
||||
@sort-change="pageOrder" header-align="center" ref="tableRef" style="width: 100%">
|
||||
<el-table-column header-align="center" label="参数名" prop="configKey" sortable
|
||||
width="200"></el-table-column>
|
||||
<el-table-column :show-overflow-tooltip="true" header-align="center" label="参数值" prop="configValue"
|
||||
@@ -40,6 +76,7 @@ layout("/layouts/platform.html"){
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</div>
|
||||
</guava>
|
||||
|
||||
<el-dialog title="新增参数" :visible.sync="addDialogVisible" :close-on-click-modal="false" width="40%">
|
||||
@@ -183,13 +220,18 @@ layout("/layouts/platform.html"){
|
||||
return {
|
||||
addDialogVisible: false,
|
||||
editDialogVisible: false,
|
||||
tableLoading: false,
|
||||
tableHeight: 300,
|
||||
tableResizeObserver: null,
|
||||
pageRequestSequence: 0,
|
||||
tableData: [],
|
||||
pageForm: {
|
||||
pageSize: 10,
|
||||
pageNumber: 1,
|
||||
pageOrderName: "",
|
||||
pageOrderBy: "",
|
||||
totalCount: 0
|
||||
totalCount: 0,
|
||||
configKey: ""
|
||||
},
|
||||
formData: {
|
||||
configKey: "",
|
||||
@@ -203,6 +245,10 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doSearch: function () {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageData()
|
||||
},
|
||||
openAdd: function () {
|
||||
this.addDialogVisible = true
|
||||
this.formData = {} //打开新增窗口,表单先清空
|
||||
@@ -317,24 +363,60 @@ layout("/layouts/platform.html"){
|
||||
this.pageData()
|
||||
},
|
||||
pageData: function () {
|
||||
//加载分页数据
|
||||
// 查询期间清空旧页并显示加载状态,快速连续查询时仅接收最后一次响应。
|
||||
var self = this
|
||||
$.post(
|
||||
base + "/platform/sys/conf/data",
|
||||
self.pageForm,
|
||||
function (data) {
|
||||
if (data.code == 0) {
|
||||
self.tableData = data.data.list
|
||||
self.pageForm.totalCount = data.data.totalCount
|
||||
} else {
|
||||
self.$message({
|
||||
message: data.msg,
|
||||
type: "error"
|
||||
})
|
||||
var requestSequence = ++self.pageRequestSequence
|
||||
self.tableData = []
|
||||
self.tableLoading = true
|
||||
$.post(base + "/platform/sys/conf/data", self.pageForm).then(function (data) {
|
||||
if (requestSequence != self.pageRequestSequence) {
|
||||
return
|
||||
}
|
||||
if (data.code == 0) {
|
||||
self.tableData = data.data.list || []
|
||||
self.pageForm.totalCount = data.data.totalCount || 0
|
||||
self.updateTableHeight()
|
||||
} else {
|
||||
self.$message({
|
||||
message: data.msg,
|
||||
type: "error"
|
||||
})
|
||||
}
|
||||
}).always(function () {
|
||||
if (requestSequence == self.pageRequestSequence) {
|
||||
self.tableLoading = false
|
||||
}
|
||||
})
|
||||
},
|
||||
updateTableHeight: function () {
|
||||
var self = this
|
||||
this.$nextTick(function () {
|
||||
var cardBody = self.$el.querySelector(".sys-conf-list-card > .el-card__body")
|
||||
if (!cardBody || cardBody.clientHeight <= 0) {
|
||||
return
|
||||
}
|
||||
var getOuterHeight = function (element) {
|
||||
if (!element) {
|
||||
return 0
|
||||
}
|
||||
},
|
||||
"json"
|
||||
)
|
||||
var style = window.getComputedStyle(element)
|
||||
return element.offsetHeight
|
||||
+ (parseFloat(style.marginTop) || 0)
|
||||
+ (parseFloat(style.marginBottom) || 0)
|
||||
}
|
||||
var bodyStyle = window.getComputedStyle(cardBody)
|
||||
var bodyPadding = (parseFloat(bodyStyle.paddingTop) || 0)
|
||||
+ (parseFloat(bodyStyle.paddingBottom) || 0)
|
||||
var tableTool = cardBody.querySelector(".ele-table-tool")
|
||||
var pagination = cardBody.querySelector(".el-pagination-container")
|
||||
var reservedHeight = bodyPadding + getOuterHeight(tableTool) + getOuterHeight(pagination)
|
||||
self.tableHeight = Math.max(1, Math.floor(cardBody.clientHeight - reservedHeight))
|
||||
self.$nextTick(function () {
|
||||
if (self.$refs.tableRef) {
|
||||
self.$refs.tableRef.doLayout()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
dropdownCommand: function (command) {
|
||||
//监听下拉框事件
|
||||
@@ -392,6 +474,29 @@ layout("/layouts/platform.html"){
|
||||
},
|
||||
created: function () {
|
||||
this.pageData()
|
||||
},
|
||||
mounted: function () {
|
||||
var self = this
|
||||
this.updateTableHeight()
|
||||
if (window.ResizeObserver) {
|
||||
this.tableResizeObserver = new ResizeObserver(function () {
|
||||
self.updateTableHeight()
|
||||
})
|
||||
this.tableResizeObserver.observe(this.$el)
|
||||
} else {
|
||||
this.resizeHandler = function () {
|
||||
self.updateTableHeight()
|
||||
}
|
||||
window.addEventListener("resize", this.resizeHandler)
|
||||
}
|
||||
},
|
||||
beforeDestroy: function () {
|
||||
if (this.tableResizeObserver) {
|
||||
this.tableResizeObserver.disconnect()
|
||||
}
|
||||
if (this.resizeHandler) {
|
||||
window.removeEventListener("resize", this.resizeHandler)
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -9,10 +9,124 @@ layout("/layouts/platform.html"){
|
||||
padding: 1px 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* 关联用户弹窗固定占用可视区域,数据过多时仅表格内部滚动。 */
|
||||
.role-user-dialog {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 90vh;
|
||||
margin-bottom: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.role-user-dialog .el-dialog__header {
|
||||
flex: 0 0 auto;
|
||||
padding: 22px 30px 18px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
.role-user-dialog .el-dialog__title {
|
||||
color: #1f2d3d;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.role-user-dialog .el-dialog__body {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
padding: 8px 30px 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.role-user-dialog .el-dialog__footer {
|
||||
flex: 0 0 auto;
|
||||
padding: 14px 30px 18px;
|
||||
border-top: 1px solid #ebeef5;
|
||||
}
|
||||
.role-user-layout {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.role-user-tip {
|
||||
flex: 0 0 auto;
|
||||
padding: 13px 16px;
|
||||
color: #1677ff;
|
||||
background: #f0f7ff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.role-user-tip i {
|
||||
margin-right: 8px;
|
||||
}
|
||||
.role-user-toolbar {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin: 16px 0;
|
||||
}
|
||||
.role-user-add-area,
|
||||
.role-user-search-area {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.role-user-remove-button {
|
||||
margin-left: auto;
|
||||
}
|
||||
.role-user-table-wrap {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.role-user-pagination {
|
||||
flex: 0 0 auto;
|
||||
margin-top: 16px;
|
||||
}
|
||||
.role-user-status-dot {
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
margin-right: 7px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.role-user-status-dot.is-success {
|
||||
background: #21c77a;
|
||||
}
|
||||
.role-user-status-dot.is-danger {
|
||||
background: #f56c6c;
|
||||
}
|
||||
|
||||
/* 角色管理列表固定占满平台内容区,避免页面主体出现纵向滚动条。 */
|
||||
#app .role-manage-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - 82px);
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
#app .role-manage-query-card {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
#app .role-manage-list-card {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
#app .role-manage-list-card > .el-card__body {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
#app .role-manage-list-card .el-pagination-container {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never">
|
||||
<div class="role-manage-page">
|
||||
<el-card class="role-manage-query-card" shadow="never">
|
||||
<el-row type="flex" style="column-gap: 10px">
|
||||
<el-select v-model="pageForm.moduleId" style="width: 180px" filterable clearable
|
||||
placeholder="请选择所属模块">
|
||||
@@ -61,9 +175,11 @@ layout("/layouts/platform.html"){
|
||||
<!-- </el-button>-->
|
||||
<!-- </div>-->
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mt10">
|
||||
<el-card shadow="never" class="mt10 role-manage-list-card">
|
||||
<el-table
|
||||
:data="tableData"
|
||||
ref="roleTableRef"
|
||||
:height="roleTableHeight"
|
||||
@sort-change="pageOrder"
|
||||
header-align="center"
|
||||
:default-sort="{prop: 'serialNumber', order: 'ascending'}"
|
||||
@@ -123,6 +239,7 @@ layout("/layouts/platform.html"){
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<el-dialog append-to-body title="新建角色" :visible.sync="addDialogVisible" :close-on-click-modal="false"
|
||||
width="70%">
|
||||
@@ -274,71 +391,89 @@ layout("/layouts/platform.html"){
|
||||
</span>
|
||||
</el-dialog>
|
||||
<el-dialog append-to-body :title="userDialogTitle" :visible.sync="userDialogVisible" :close-on-click-modal="false"
|
||||
width="70%">
|
||||
<div class="block mb10">
|
||||
<el-select
|
||||
size="small"
|
||||
style="width: 60%"
|
||||
class="span_n"
|
||||
v-model="selUsers"
|
||||
multiple
|
||||
filterable
|
||||
remote
|
||||
default-first-option
|
||||
reserve-keyword
|
||||
:remote-method="remoteMethod"
|
||||
:loading="loading"
|
||||
placeholder="请输入用户名或姓名"
|
||||
>
|
||||
<el-option v-for="item in dbUsers" :key="item.value" :label="item.label"
|
||||
:value="item.value"></el-option>
|
||||
</el-select>
|
||||
<el-button size="small" @click="userAddRole">将用户加入角色</el-button>
|
||||
<div class="pull-right offscreen-right">
|
||||
<el-button size="small" type="danger" @click="userDelRole">从角色中移除</el-button>
|
||||
custom-class="role-user-dialog" top="5vh" width="82%" @opened="updateUserTableHeight">
|
||||
<div class="role-user-layout">
|
||||
<div class="role-user-toolbar">
|
||||
<div class="role-user-add-area">
|
||||
<el-select
|
||||
size="small"
|
||||
style="width: 360px"
|
||||
v-model="selUsers"
|
||||
multiple
|
||||
filterable
|
||||
remote
|
||||
default-first-option
|
||||
reserve-keyword
|
||||
:remote-method="remoteMethod"
|
||||
:loading="loading"
|
||||
placeholder="请输入用户工号或姓名"
|
||||
>
|
||||
<el-option v-for="item in dbUsers" :key="item.value" :label="item.label"
|
||||
:value="item.value"></el-option>
|
||||
</el-select>
|
||||
<el-button size="small" type="primary" plain icon="el-icon-circle-plus-outline"
|
||||
@click="userAddRole">将用户加入角色</el-button>
|
||||
</div>
|
||||
<div class="role-user-search-area">
|
||||
<el-input v-model="userForm.searchKeyword" clearable size="small" style="width: 280px"
|
||||
placeholder="请输入查询内容" @clear="doUserSearch"
|
||||
@keyup.enter.native="doUserSearch">
|
||||
<el-select v-model="userForm.searchName" slot="prepend" style="width: 100px">
|
||||
<el-option label="工号" value="loginname"></el-option>
|
||||
<el-option label="姓名" value="username"></el-option>
|
||||
</el-select>
|
||||
</el-input>
|
||||
<el-button size="small" type="primary" icon="el-icon-search" @click="doUserSearch">查询</el-button>
|
||||
</div>
|
||||
<el-button class="role-user-remove-button" size="small" type="danger" plain
|
||||
icon="el-icon-delete" @click="userDelRole">从角色中移除</el-button>
|
||||
</div>
|
||||
<div class="role-user-table-wrap">
|
||||
<el-table
|
||||
ref="userTableRef"
|
||||
:data="userTableData"
|
||||
:height="userTableHeight"
|
||||
@sort-change="userPageOrder"
|
||||
size="small"
|
||||
border
|
||||
header-align="center"
|
||||
style="width: 100%"
|
||||
@selection-change="userSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center"></el-table-column>
|
||||
<el-table-column sortable prop="loginname" label="用户工号" header-align="center" align="center"></el-table-column>
|
||||
<el-table-column prop="username" label="姓名" header-align="center" align="center"
|
||||
:show-overflow-tooltip="true"></el-table-column>
|
||||
<el-table-column prop="unitname" label="所属单位" header-align="center" align="center"
|
||||
:show-overflow-tooltip="true"></el-table-column>
|
||||
<el-table-column sortable prop="disabled" label="账号状态" header-align="center" align="center"
|
||||
:show-overflow-tooltip="true">
|
||||
<template slot-scope="scope">
|
||||
<span class="role-user-status-dot" :class="scope.row.disabled ? 'is-danger' : 'is-success'"></span>
|
||||
<span>{{ scope.row.disabled ? '禁用' : '正常' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column sortable prop="useronline" label="在线状态" header-align="center" align="center"
|
||||
:show-overflow-tooltip="true">
|
||||
<template slot-scope="scope">
|
||||
<span :class="scope.row.useronline ? 'text-success' : 'text-danger'">
|
||||
{{ scope.row.useronline ? '在线' : '离线' }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-pagination
|
||||
class="role-user-pagination"
|
||||
@size-change="userPageSizeChange"
|
||||
@current-change="userPageNumberChange"
|
||||
:current-page="userForm.pageNumber"
|
||||
:page-sizes="[10, 20, 30, 50]"
|
||||
:page-size="userForm.pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="userForm.totalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
<el-table
|
||||
:data="userTableData"
|
||||
@sort-change="userPageOrder"
|
||||
size="small"
|
||||
header-align="center"
|
||||
style="width: 100%"
|
||||
@selection-change="userSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="35"></el-table-column>
|
||||
<el-table-column sortable prop="loginname" label="用户名" header-align="center"></el-table-column>
|
||||
<el-table-column prop="username" label="姓名" header-align="center"
|
||||
:show-overflow-tooltip="true"></el-table-column>
|
||||
<el-table-column prop="unitname" label="所属单位" header-align="center" align="center"
|
||||
:show-overflow-tooltip="true"></el-table-column>
|
||||
<el-table-column sortable prop="disabled" label="帐号状态" header-align="center" align="center"
|
||||
:show-overflow-tooltip="true">
|
||||
<template slot-scope="scope">
|
||||
<i v-if="scope.row.disabled" class="fa fa-circle text-danger ml5"></i>
|
||||
<i v-if="!scope.row.disabled" class="fa fa-circle text-success ml5"></i>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column sortable prop="useronline" label="在线状态" header-align="center" align="center"
|
||||
:show-overflow-tooltip="true">
|
||||
<template slot-scope="scope">
|
||||
<i v-if="scope.row.useronline" class="text-success ml5">在线</i>
|
||||
<i v-if="!scope.row.useronline" class="text-danger ml5">离线</i>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
@size-change="userPageSizeChange"
|
||||
@current-change="userPageNumberChange"
|
||||
:current-page="userForm.pageNumber"
|
||||
:page-sizes="[10, 20, 30, 50]"
|
||||
:page-size="userForm.pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="userForm.totalCount"
|
||||
></el-pagination>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="userDialogVisible = false">关 闭</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<sort ref="sortRef" @refresh="doSearch"></sort>
|
||||
@@ -388,6 +523,9 @@ layout("/layouts/platform.html"){
|
||||
isLeaf: "leaf"
|
||||
},
|
||||
tableData: [],
|
||||
roleTableHeight: 300,
|
||||
roleTableResizeObserver: null,
|
||||
roleTableResizeHandler: null,
|
||||
moduleOptions: [],
|
||||
options: [],
|
||||
parentUnit: [],
|
||||
@@ -447,6 +585,8 @@ layout("/layouts/platform.html"){
|
||||
doCmsForm: {},
|
||||
userForm: {
|
||||
roleId: "",
|
||||
searchName: "loginname",
|
||||
searchKeyword: "",
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
@@ -454,6 +594,7 @@ layout("/layouts/platform.html"){
|
||||
pageOrderBy: ""
|
||||
},
|
||||
userTableData: [],
|
||||
userTableHeight: 360,
|
||||
loading: false,
|
||||
dbUsers: [], //分配用户
|
||||
selUsers: [], //分配选中的用户
|
||||
@@ -575,6 +716,31 @@ layout("/layouts/platform.html"){
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageData()
|
||||
},
|
||||
// 根据角色列表卡片的剩余空间设置表格高度,分页区域始终保持可见。
|
||||
updateRoleTableHeight() {
|
||||
this.$nextTick(() => {
|
||||
const cardBody = this.$el.querySelector('.role-manage-list-card > .el-card__body')
|
||||
if (!cardBody || cardBody.clientHeight <= 0) {
|
||||
return
|
||||
}
|
||||
const pagination = cardBody.querySelector('.el-pagination-container')
|
||||
const bodyStyle = window.getComputedStyle(cardBody)
|
||||
const bodyPadding = (parseFloat(bodyStyle.paddingTop) || 0)
|
||||
+ (parseFloat(bodyStyle.paddingBottom) || 0)
|
||||
const paginationStyle = pagination ? window.getComputedStyle(pagination) : null
|
||||
const paginationHeight = pagination
|
||||
? pagination.offsetHeight
|
||||
+ (parseFloat(paginationStyle.marginTop) || 0)
|
||||
+ (parseFloat(paginationStyle.marginBottom) || 0)
|
||||
: 0
|
||||
this.roleTableHeight = Math.max(1, Math.floor(cardBody.clientHeight - bodyPadding - paginationHeight))
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.roleTableRef) {
|
||||
this.$refs.roleTableRef.doLayout()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
// 加载可选 PC 模块,创建、编辑和列表筛选共用同一数据源。
|
||||
loadModuleOptions() {
|
||||
this.$axios.post("/platform/sys/role/listModule").then((res) => {
|
||||
@@ -624,6 +790,26 @@ layout("/layouts/platform.html"){
|
||||
this.userForm.pageSize = val
|
||||
this.doUserLoad()
|
||||
},
|
||||
// 查询当前角色已关联用户,查询时从第一页重新加载。
|
||||
doUserSearch() {
|
||||
this.userForm.pageNumber = 1
|
||||
this.doUserLoad()
|
||||
},
|
||||
// 根据弹窗内表格容器的剩余空间计算高度,确保仅表格内部产生滚动条。
|
||||
updateUserTableHeight() {
|
||||
this.$nextTick(() => {
|
||||
const tableWrap = document.querySelector('.role-user-dialog .role-user-table-wrap')
|
||||
if (!tableWrap || tableWrap.clientHeight <= 0) {
|
||||
return
|
||||
}
|
||||
this.userTableHeight = Math.max(180, Math.floor(tableWrap.clientHeight))
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.userTableRef) {
|
||||
this.$refs.userTableRef.doLayout()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
remoteMethod(query) {
|
||||
if (query !== "") {
|
||||
this.loading = true
|
||||
@@ -763,6 +949,7 @@ layout("/layouts/platform.html"){
|
||||
this.userDialogVisible = true
|
||||
this.roleId = command.id
|
||||
this.userForm.roleId = command.id
|
||||
this.userForm.pageNumber = 1
|
||||
this.doUserLoad()
|
||||
}
|
||||
if ("enable" === command.type || "disable" === command.type) {
|
||||
@@ -903,6 +1090,31 @@ layout("/layouts/platform.html"){
|
||||
this.loadModuleOptions()
|
||||
this.pageData()
|
||||
// await this.getMenuOptions()
|
||||
},
|
||||
mounted() {
|
||||
this.updateRoleTableHeight()
|
||||
window.addEventListener("resize", this.updateUserTableHeight)
|
||||
const page = this.$el.querySelector('.role-manage-page')
|
||||
if (window.ResizeObserver && page) {
|
||||
this.roleTableResizeObserver = new ResizeObserver(() => {
|
||||
this.updateRoleTableHeight()
|
||||
})
|
||||
this.roleTableResizeObserver.observe(page)
|
||||
} else {
|
||||
this.roleTableResizeHandler = () => {
|
||||
this.updateRoleTableHeight()
|
||||
}
|
||||
window.addEventListener("resize", this.roleTableResizeHandler)
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener("resize", this.updateUserTableHeight)
|
||||
if (this.roleTableResizeObserver) {
|
||||
this.roleTableResizeObserver.disconnect()
|
||||
}
|
||||
if (this.roleTableResizeHandler) {
|
||||
window.removeEventListener("resize", this.roleTableResizeHandler)
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -6,7 +6,7 @@ const branchUnionManage = {
|
||||
<el-input placeholder="请输入分工会名称" clearable size="small" style="width: 300px" v-model="pageForm.searchKeyword"></el-input>
|
||||
|
||||
<el-button type="primary" class="ml5" size="small" icon="el-icon-search" @click="doSearch"></el-button>
|
||||
<el-button @click="openAudit" icon="el-icon-s-check" type="primary" style="margin-left: auto" size="small">基层干部审核</el-button>
|
||||
<el-button @click="openAudit" icon="el-icon-s-check" type="primary" style="margin-left: auto" size="small" v-if="$auth.hasRoleOr(['SYSADMIN','SCHOOL_UNION_ADMIN'])">基层干部审核</el-button>
|
||||
<el-button @click="openAdd" icon="ti-plus" type="primary" size="small" v-if="$auth.hasPermission('sys.manager.union.add')">新建分工会</el-button>
|
||||
</el-row>
|
||||
</el-card>
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style></style>
|
||||
<style>
|
||||
<!--#include("../fixedListLayout.css"){}#-->
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<div class="club-info-fixed-list-page">
|
||||
<el-card class="club-info-fixed-query-card" shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度">
|
||||
<el-date-picker
|
||||
@@ -30,14 +33,14 @@ layout("/layouts/platform.html"){
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card class="mt10" shadow="never">
|
||||
<el-card class="mt10 club-info-fixed-list-card" shadow="never">
|
||||
<table-tool label="申请列表">
|
||||
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
||||
<el-radio-button :label="true">已审核</el-radio-button>
|
||||
<el-radio-button :label="false">未审核</el-radio-button>
|
||||
</el-radio-group>
|
||||
</table-tool>
|
||||
<el-table :data="tableData">
|
||||
<el-table :data="tableData" :height="tableHeight" ref="tableRef">
|
||||
<el-table-column :index="indexMethod" label="序号" type="index" width="80px"></el-table-column>
|
||||
<el-table-column label="社团名称" prop="clubName" sortable show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="申请人" prop="userName" sortable show-overflow-tooltip></el-table-column>
|
||||
@@ -66,6 +69,7 @@ layout("/layouts/platform.html"){
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #edit>
|
||||
@@ -95,9 +99,10 @@ layout("/layouts/platform.html"){
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include("../change/info.js"){}#-->
|
||||
<!--#include("../fixedListLayout.js"){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
mixins: [initTableMixins],
|
||||
mixins: [initTableMixins, CLUB_INFO_FIXED_LIST_MIXIN],
|
||||
components: {
|
||||
"info": clubManagerInfo,
|
||||
},
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style></style>
|
||||
<style>
|
||||
<!--#include("../fixedListLayout.css"){}#-->
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<div class="club-info-fixed-list-page">
|
||||
<el-card class="club-info-fixed-query-card" shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度">
|
||||
<el-date-picker
|
||||
@@ -30,14 +33,14 @@ layout("/layouts/platform.html"){
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card class="mt10" shadow="never">
|
||||
<el-card class="mt10 club-info-fixed-list-card" shadow="never">
|
||||
<table-tool label="申请列表">
|
||||
<el-button type="primary" size="small" @click="openAdd">
|
||||
<i class="ti-plus"></i>
|
||||
变更成员
|
||||
</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData">
|
||||
<el-table :data="tableData" :height="tableHeight" ref="tableRef">
|
||||
<el-table-column :index="indexMethod" label="序号" type="index" width="80px"></el-table-column>
|
||||
<el-table-column label="社团名称" prop="clubName" sortable show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="申请人" prop="userName" sortable show-overflow-tooltip></el-table-column>
|
||||
@@ -64,6 +67,7 @@ layout("/layouts/platform.html"){
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #edit_func>
|
||||
@@ -106,13 +110,13 @@ layout("/layouts/platform.html"){
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="身份" prop="nowRoleCode">
|
||||
<el-checkbox-group v-model="formData.nowRoleCode">
|
||||
<el-checkbox-group v-model="formData.nowRoleCode" @change="handleRoleChange">
|
||||
<el-checkbox label="CLUB_PRESIDENT">社团会长</el-checkbox>
|
||||
<el-checkbox label="CLUB_VICE_PRESIDENT">社团副会长</el-checkbox>
|
||||
<el-checkbox label="CLUB_SECRETARY">社团秘书长</el-checkbox>
|
||||
<el-checkbox label="CLUB_VICE_SECRETARY">社团副秘书长</el-checkbox>
|
||||
<el-checkbox label="CLUB_OPERATOR">社团操作员</el-checkbox>
|
||||
<el-checkbox label="CLUB_MEMBER">社团会员</el-checkbox>
|
||||
<el-checkbox label="CLUB_MEMBER" :disabled="memberRoleDisabled">社团会员</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@@ -131,9 +135,10 @@ layout("/layouts/platform.html"){
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include("info.js"){}#-->
|
||||
<!--#include("../fixedListLayout.js"){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
mixins: [initTableMixins],
|
||||
mixins: [initTableMixins, CLUB_INFO_FIXED_LIST_MIXIN],
|
||||
components: {
|
||||
"info": clubManagerInfo
|
||||
},
|
||||
@@ -155,6 +160,13 @@ layout("/layouts/platform.html"){
|
||||
viewData: {},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 选择任意理事机构身份后,社团会员身份不可再选,避免互斥身份同时提交。
|
||||
memberRoleDisabled() {
|
||||
const roleCodes = Array.isArray(this.formData.nowRoleCode) ? this.formData.nowRoleCode : []
|
||||
return roleCodes.some(roleCode => roleCode !== 'CLUB_MEMBER')
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
clubChange(key) {
|
||||
if(!key) {
|
||||
@@ -169,10 +181,20 @@ layout("/layouts/platform.html"){
|
||||
},
|
||||
userChange(key) {
|
||||
const user = this.userList.find(o => o.userId === key)
|
||||
this.$set(this.formData, 'nowRoleCode', user?.roleCode)
|
||||
const roleCodes = user && Array.isArray(user.roleCode) ? user.roleCode.slice() : []
|
||||
this.$set(this.formData, 'nowRoleCode', roleCodes)
|
||||
this.handleRoleChange(roleCodes)
|
||||
this.$set(this.formData, 'changeUserId', key)
|
||||
this.$set(this.formData, 'changeUserName', user?.userName)
|
||||
},
|
||||
// 身份发生变化时,只要存在非社团会员身份,就取消社团会员身份的选中状态。
|
||||
handleRoleChange(roleCodes) {
|
||||
const selectedRoleCodes = Array.isArray(roleCodes) ? roleCodes : []
|
||||
const hasNonMemberRole = selectedRoleCodes.some(roleCode => roleCode !== 'CLUB_MEMBER')
|
||||
if (hasNonMemberRole && selectedRoleCodes.includes('CLUB_MEMBER')) {
|
||||
this.$set(this.formData, 'nowRoleCode', selectedRoleCodes.filter(roleCode => roleCode !== 'CLUB_MEMBER'))
|
||||
}
|
||||
},
|
||||
openAdd() {
|
||||
this.id = ''
|
||||
this.taskId = ''
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style></style>
|
||||
<style>
|
||||
<!--#include("../fixedListLayout.css"){}#-->
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<div class="club-info-fixed-list-page">
|
||||
<el-card class="club-info-fixed-query-card" shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="所属社团">
|
||||
<el-select v-model="pageForm.clubId" placeholder="请选择社团" clearable filterable style="width: 100%">
|
||||
@@ -25,9 +28,9 @@ layout("/layouts/platform.html"){
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card class="mt10" shadow="never">
|
||||
<el-card class="mt10 club-info-fixed-list-card" shadow="never">
|
||||
<table-tool label="退会人员列表"></table-tool>
|
||||
<el-table :data="tableData">
|
||||
<el-table :data="tableData" :height="tableHeight" ref="tableRef">
|
||||
<el-table-column :index="indexMethod" label="序号" type="index" width="70"></el-table-column>
|
||||
<el-table-column label="工号" prop="loginName" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="姓名" prop="userName" show-overflow-tooltip></el-table-column>
|
||||
@@ -53,6 +56,7 @@ layout("/layouts/platform.html"){
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #view>
|
||||
@@ -63,9 +67,10 @@ layout("/layouts/platform.html"){
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include("info.js"){}#-->
|
||||
<!--#include("../fixedListLayout.js"){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
mixins: [initTableMixins],
|
||||
mixins: [initTableMixins, CLUB_INFO_FIXED_LIST_MIXIN],
|
||||
components: {
|
||||
"info": clubExitInfo,
|
||||
},
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/* 社团信息维护列表页固定占满平台内容区,禁止页面主体产生纵向滚动条。 */
|
||||
#app .club-info-fixed-list-page {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - 82px);
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#app .club-info-fixed-query-card {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
#app .club-info-fixed-list-card {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#app .club-info-fixed-list-card > .el-card__body {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#app .club-info-fixed-list-card .ele-table-tool,
|
||||
#app .club-info-fixed-list-card .el-pagination-container {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 社团信息维护列表页共用高度计算逻辑。
|
||||
* 查询卡片保持原始高度,列表表格占用工具栏与分页之外的全部剩余空间。
|
||||
*/
|
||||
const CLUB_INFO_FIXED_LIST_MIXIN = {
|
||||
data() {
|
||||
return {
|
||||
tableHeight: 300,
|
||||
clubInfoListResizeObserver: null,
|
||||
clubInfoListResizeHandler: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateClubInfoListTableHeight() {
|
||||
this.$nextTick(() => {
|
||||
const page = this.$el.querySelector('.club-info-fixed-list-page')
|
||||
const cardBody = this.$el.querySelector('.club-info-fixed-list-card > .el-card__body')
|
||||
if (!page || !cardBody || cardBody.clientHeight <= 0) {
|
||||
return
|
||||
}
|
||||
const getOuterHeight = element => {
|
||||
if (!element) {
|
||||
return 0
|
||||
}
|
||||
const style = window.getComputedStyle(element)
|
||||
return element.offsetHeight
|
||||
+ (parseFloat(style.marginTop) || 0)
|
||||
+ (parseFloat(style.marginBottom) || 0)
|
||||
}
|
||||
const bodyStyle = window.getComputedStyle(cardBody)
|
||||
const bodyPadding = (parseFloat(bodyStyle.paddingTop) || 0)
|
||||
+ (parseFloat(bodyStyle.paddingBottom) || 0)
|
||||
const tableTool = cardBody.querySelector('.ele-table-tool')
|
||||
const pagination = cardBody.querySelector('.el-pagination-container')
|
||||
const reservedHeight = bodyPadding + getOuterHeight(tableTool) + getOuterHeight(pagination)
|
||||
const nextHeight = Math.max(1, Math.floor(cardBody.clientHeight - reservedHeight))
|
||||
if (this.tableHeight !== nextHeight) {
|
||||
this.tableHeight = nextHeight
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.tableRef) {
|
||||
this.$refs.tableRef.doLayout()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.updateClubInfoListTableHeight()
|
||||
const page = this.$el.querySelector('.club-info-fixed-list-page')
|
||||
if (window.ResizeObserver && page) {
|
||||
this.clubInfoListResizeObserver = new ResizeObserver(() => {
|
||||
this.updateClubInfoListTableHeight()
|
||||
})
|
||||
this.clubInfoListResizeObserver.observe(page)
|
||||
} else {
|
||||
this.clubInfoListResizeHandler = () => {
|
||||
this.updateClubInfoListTableHeight()
|
||||
}
|
||||
window.addEventListener('resize', this.clubInfoListResizeHandler)
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.clubInfoListResizeObserver) {
|
||||
this.clubInfoListResizeObserver.disconnect()
|
||||
}
|
||||
if (this.clubInfoListResizeHandler) {
|
||||
window.removeEventListener('resize', this.clubInfoListResizeHandler)
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
const CLUB_INFO_MANAGE_TEMPLATE = {
|
||||
template: `
|
||||
<div>
|
||||
<el-card shadow="never">
|
||||
<div class="club-manage-panel">
|
||||
<el-card class="club-manage-query-card" shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="姓名/工号">
|
||||
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.searchKeyword"></el-input>
|
||||
@@ -15,7 +15,7 @@
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt10">
|
||||
<el-card shadow="never" class="mt10 club-manage-list-card">
|
||||
<table-tool label="会员信息">
|
||||
<template v-if="$auth.hasRoleOr(['SYSADMIN', 'SCHOOL_UNION_ADMIN'])">
|
||||
<el-button size="small" type="primary" icon="el-icon-download" @click="exportRegistrationDoc">导出登记表</el-button>
|
||||
@@ -29,7 +29,8 @@
|
||||
<el-radio-button label="1">理事机构</el-radio-button>
|
||||
</el-radio-group>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" row-key="id" @sort-change='pageOrder'>
|
||||
<el-table v-loading="tableLoading" :data="tableData" :height="tableHeight"
|
||||
row-key="id" ref="tableRef" @sort-change='pageOrder'>
|
||||
<el-table-column :index="indexMethod" label="序号" type="index" width="70"></el-table-column>
|
||||
<el-table-column label="工号" prop="loginName" show-overflow-tooltip sortable></el-table-column>
|
||||
<el-table-column label="姓名" prop="userName" show-overflow-tooltip sortable></el-table-column>
|
||||
@@ -147,7 +148,7 @@
|
||||
</el-dialog>
|
||||
</div>
|
||||
`,
|
||||
mixins: [initTableMixins],
|
||||
mixins: [initTableMixins, CLUB_FIXED_TABLE_MIXIN],
|
||||
props: {
|
||||
parentNode: {
|
||||
type: Object,
|
||||
@@ -339,20 +340,33 @@
|
||||
})
|
||||
},
|
||||
|
||||
async pageData() {
|
||||
pageData() {
|
||||
this.pageForm.clubId = this.parentNode.currentTreeData.id
|
||||
const resp = await this.$axios.post("/platform/club/infoManage/manage/userPageData", this.pageForm)
|
||||
if (resp.code === 0) {
|
||||
this.tableData = resp.data.list
|
||||
this.pageForm.totalCount = resp.data.totalCount
|
||||
} else {
|
||||
this.$message.warning(resp.msg)
|
||||
}
|
||||
// 切换树节点或分页时清空旧数据,避免新请求完成前显示上一社团的成员。
|
||||
const requestSequence = ++this.pageRequestSequence
|
||||
this.tableData = []
|
||||
this.tableLoading = true
|
||||
return this.$axios.post("/platform/club/infoManage/manage/userPageData", this.pageForm).then((resp) => {
|
||||
if (requestSequence !== this.pageRequestSequence) {
|
||||
return
|
||||
}
|
||||
if (resp.code === 0) {
|
||||
this.tableData = resp.data.list || []
|
||||
this.pageForm.totalCount = resp.data.totalCount || 0
|
||||
this.updateFixedTableHeight()
|
||||
} else {
|
||||
this.$message.warning(resp.msg)
|
||||
}
|
||||
}).finally(() => {
|
||||
if (requestSequence === this.pageRequestSequence) {
|
||||
this.tableLoading = false
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
created() {
|
||||
this.$set(this.pageForm, "radioType", "3")
|
||||
await this.pageData()
|
||||
this.pageData()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,74 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style></style>
|
||||
<style>
|
||||
/* 社团信息页面固定占满平台内容区,避免页面主体出现纵向滚动条。 */
|
||||
#app .club-manage-layout {
|
||||
height: calc(100vh - 82px);
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
#app .club-tree-column,
|
||||
#app .club-content-column {
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
#app .club-tree-card {
|
||||
height: 100%;
|
||||
}
|
||||
#app .club-tree-card > .el-card__body {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
#app .club-tree-scroll {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
margin-top: 10px;
|
||||
overflow: auto;
|
||||
}
|
||||
/* 右侧查询卡片固定,列表卡片占满剩余空间。 */
|
||||
#app .club-manage-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
#app .club-manage-query-card {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
#app .club-manage-list-card {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
#app .club-manage-list-card > .el-card__body {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
#app .club-manage-list-card .ele-table-tool,
|
||||
#app .club-manage-list-card .el-pagination-container {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-row type="flex" :gutter="10" style="height: calc(100vh - 126px)">
|
||||
<el-col :span="4" style="height: 100%">
|
||||
<el-card shadow="never" style="height: 100%" body-style="{ height: '100%' }">
|
||||
<el-row class="club-manage-layout" type="flex" :gutter="10">
|
||||
<el-col class="club-tree-column" :span="4">
|
||||
<el-card class="club-tree-card" shadow="never">
|
||||
<el-input placeholder="输入关键字进行查找" v-model="filterText" clearable></el-input>
|
||||
<div style="max-height: calc(100vh - 200px); overflow-y: auto">
|
||||
<div class="club-tree-scroll">
|
||||
<el-tree
|
||||
:data="treeData"
|
||||
ref="treeRef"
|
||||
@@ -32,7 +90,7 @@ layout("/layouts/platform.html"){
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="20" style="height: 100%">
|
||||
<el-col class="club-content-column" :span="20">
|
||||
<template v-if="currentTreeNode==null || currentTreeNode.level===1">
|
||||
<school-club-manage :parent-node="this"></school-club-manage>
|
||||
</template>
|
||||
@@ -57,6 +115,69 @@ layout("/layouts/platform.html"){
|
||||
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
/* 右侧列表共享固定高度计算逻辑,工具栏和分页不参与数据滚动。 */
|
||||
const CLUB_FIXED_TABLE_MIXIN = {
|
||||
data() {
|
||||
return {
|
||||
tableHeight: 300,
|
||||
tableResizeObserver: null,
|
||||
pageRequestSequence: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateFixedTableHeight() {
|
||||
this.$nextTick(() => {
|
||||
const cardBody = this.$el.querySelector(".club-manage-list-card > .el-card__body")
|
||||
if (!cardBody || cardBody.clientHeight <= 0) {
|
||||
return
|
||||
}
|
||||
const getOuterHeight = (element) => {
|
||||
if (!element) {
|
||||
return 0
|
||||
}
|
||||
const style = window.getComputedStyle(element)
|
||||
return element.offsetHeight
|
||||
+ (parseFloat(style.marginTop) || 0)
|
||||
+ (parseFloat(style.marginBottom) || 0)
|
||||
}
|
||||
const bodyStyle = window.getComputedStyle(cardBody)
|
||||
const bodyPadding = (parseFloat(bodyStyle.paddingTop) || 0)
|
||||
+ (parseFloat(bodyStyle.paddingBottom) || 0)
|
||||
const tableTool = cardBody.querySelector(".ele-table-tool")
|
||||
const pagination = cardBody.querySelector(".el-pagination-container")
|
||||
const reservedHeight = bodyPadding + getOuterHeight(tableTool) + getOuterHeight(pagination)
|
||||
this.tableHeight = Math.max(1, Math.floor(cardBody.clientHeight - reservedHeight))
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.tableRef) {
|
||||
this.$refs.tableRef.doLayout()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.updateFixedTableHeight()
|
||||
if (window.ResizeObserver) {
|
||||
this.tableResizeObserver = new ResizeObserver(() => {
|
||||
this.updateFixedTableHeight()
|
||||
})
|
||||
this.tableResizeObserver.observe(this.$el)
|
||||
} else {
|
||||
this.resizeHandler = () => {
|
||||
this.updateFixedTableHeight()
|
||||
}
|
||||
window.addEventListener("resize", this.resizeHandler)
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.tableResizeObserver) {
|
||||
this.tableResizeObserver.disconnect()
|
||||
}
|
||||
if (this.resizeHandler) {
|
||||
window.removeEventListener("resize", this.resizeHandler)
|
||||
}
|
||||
}
|
||||
}
|
||||
<!--#include("../../register/apply/clubRegisterForm.js"){}#-->
|
||||
<!--#include("../../common/clubInfoComponent.js"){}#-->
|
||||
<!--#include("../../common/clubRoleConstant.js"){}#-->
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const SCHOOL_CLUB_MANAGE_TEMPLATE = {
|
||||
template: `
|
||||
<div>
|
||||
<el-card shadow="never">
|
||||
<div class="club-manage-panel">
|
||||
<el-card class="club-manage-query-card" shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="社团名称">
|
||||
<el-input
|
||||
@@ -19,13 +19,14 @@ const SCHOOL_CLUB_MANAGE_TEMPLATE = {
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mt10">
|
||||
<el-card shadow="never" class="mt10 club-manage-list-card">
|
||||
<table-tool label="社团列表">
|
||||
<template>
|
||||
|
||||
</template>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" row-key="id">
|
||||
<el-table v-loading="tableLoading" :data="tableData" :height="tableHeight"
|
||||
row-key="id" ref="tableRef">
|
||||
<el-table-column :index="indexMethod" label="序号" type="index" width="70"></el-table-column>
|
||||
<el-table-column label="社团编码" sortable prop="clubCode"></el-table-column>
|
||||
<el-table-column label="社团名称" prop="clubName" sortable></el-table-column>
|
||||
@@ -69,7 +70,7 @@ const SCHOOL_CLUB_MANAGE_TEMPLATE = {
|
||||
</el-card>
|
||||
</div>
|
||||
`,
|
||||
mixins: [initTableMixins],
|
||||
mixins: [initTableMixins, CLUB_FIXED_TABLE_MIXIN],
|
||||
props: {
|
||||
parentNode: {
|
||||
type: Object,
|
||||
@@ -118,17 +119,30 @@ const SCHOOL_CLUB_MANAGE_TEMPLATE = {
|
||||
}
|
||||
},
|
||||
openImport() {},
|
||||
async pageData() {
|
||||
const resp = await this.$axios.post("/platform/club/infoManage/manage/pageData", this.pageForm)
|
||||
if (resp.code === 0) {
|
||||
this.tableData = resp.data.list
|
||||
this.pageForm.totalCount = resp.data.totalCount
|
||||
} else {
|
||||
this.$message.warning(resp.msg)
|
||||
}
|
||||
pageData() {
|
||||
// 查询期间清空旧页并显示加载状态,快速连续操作时只接收最后一次响应。
|
||||
const requestSequence = ++this.pageRequestSequence
|
||||
this.tableData = []
|
||||
this.tableLoading = true
|
||||
return this.$axios.post("/platform/club/infoManage/manage/pageData", this.pageForm).then((resp) => {
|
||||
if (requestSequence !== this.pageRequestSequence) {
|
||||
return
|
||||
}
|
||||
if (resp.code === 0) {
|
||||
this.tableData = resp.data.list || []
|
||||
this.pageForm.totalCount = resp.data.totalCount || 0
|
||||
this.updateFixedTableHeight()
|
||||
} else {
|
||||
this.$message.warning(resp.msg)
|
||||
}
|
||||
}).finally(() => {
|
||||
if (requestSequence === this.pageRequestSequence) {
|
||||
this.tableLoading = false
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
await this.pageData()
|
||||
created() {
|
||||
this.pageData()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style>
|
||||
<!--#include("../fixedListLayout.css"){}#-->
|
||||
.el-tooltip__popper {
|
||||
line-height: 20px;
|
||||
}
|
||||
@@ -13,7 +14,8 @@ layout("/layouts/platform.html"){
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<div class="club-info-fixed-list-page">
|
||||
<el-card class="club-info-fixed-query-card" shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度">
|
||||
<el-date-picker
|
||||
@@ -54,13 +56,13 @@ layout("/layouts/platform.html"){
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card class="mt10" shadow="never">
|
||||
<el-card class="mt10 club-info-fixed-list-card" shadow="never">
|
||||
<table-tool label="缴费记录">
|
||||
<el-button @click="batchOperatePay" size="small" type="primary">
|
||||
批量设置
|
||||
</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" row-key="id" @selection-change="handleSelectionChange" ref="tableRef">
|
||||
<el-table :data="tableData" :height="tableHeight" row-key="id" @selection-change="handleSelectionChange" ref="tableRef">
|
||||
<el-table-column
|
||||
:reserve-selection="true"
|
||||
type="selection"
|
||||
@@ -122,6 +124,7 @@ layout("/layouts/platform.html"){
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #view>
|
||||
@@ -156,9 +159,10 @@ layout("/layouts/platform.html"){
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include("../fixedListLayout.js"){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
mixins: [initTableMixins],
|
||||
mixins: [initTableMixins, CLUB_INFO_FIXED_LIST_MIXIN],
|
||||
components: {
|
||||
|
||||
},
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style></style>
|
||||
<style>
|
||||
<!--#include("../fixedListLayout.css"){}#-->
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<div class="club-info-fixed-list-page">
|
||||
<el-card class="club-info-fixed-query-card" shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度">
|
||||
<el-date-picker
|
||||
@@ -30,14 +33,14 @@ layout("/layouts/platform.html"){
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card class="mt10" shadow="never">
|
||||
<el-card class="mt10 club-info-fixed-list-card" shadow="never">
|
||||
<table-tool label="申请列表">
|
||||
<el-button type="primary" size="small" @click="openAdd">
|
||||
<i class="ti-plus"></i>
|
||||
上传报告
|
||||
</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData">
|
||||
<el-table :data="tableData" :height="tableHeight" ref="tableRef">
|
||||
<el-table-column :index="indexMethod" label="序号" type="index" width="80px"></el-table-column>
|
||||
<el-table-column label="社团名称" prop="clubName" sortable show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="申请人" prop="userName" sortable show-overflow-tooltip></el-table-column>
|
||||
@@ -61,6 +64,7 @@ layout("/layouts/platform.html"){
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #edit_func>
|
||||
@@ -141,9 +145,10 @@ layout("/layouts/platform.html"){
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include("info.js"){}#-->
|
||||
<!--#include("../fixedListLayout.js"){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
mixins: [initTableMixins],
|
||||
mixins: [initTableMixins, CLUB_INFO_FIXED_LIST_MIXIN],
|
||||
components: {
|
||||
"info": clubRefreshInfo,
|
||||
},
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style></style>
|
||||
<style>
|
||||
<!--#include("../fixedListLayout.css"){}#-->
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<div class="club-info-fixed-list-page">
|
||||
<el-card class="club-info-fixed-query-card" shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度">
|
||||
<el-date-picker
|
||||
@@ -30,14 +33,14 @@ layout("/layouts/platform.html"){
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card class="mt10" shadow="never">
|
||||
<el-card class="mt10 club-info-fixed-list-card" shadow="never">
|
||||
<table-tool label="申请列表">
|
||||
<el-button type="primary" size="small" @click="openAdd">
|
||||
<i class="ti-plus"></i>
|
||||
章程修订
|
||||
</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData">
|
||||
<el-table :data="tableData" :height="tableHeight" ref="tableRef">
|
||||
<el-table-column :index="indexMethod" label="序号" type="index" width="80px"></el-table-column>
|
||||
<el-table-column label="社团名称" prop="clubName" sortable show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="申请人" prop="userName" sortable show-overflow-tooltip></el-table-column>
|
||||
@@ -61,6 +64,7 @@ layout("/layouts/platform.html"){
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #edit_func>
|
||||
@@ -99,9 +103,10 @@ layout("/layouts/platform.html"){
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include("info.js"){}#-->
|
||||
<!--#include("../fixedListLayout.js"){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
mixins: [initTableMixins],
|
||||
mixins: [initTableMixins, CLUB_INFO_FIXED_LIST_MIXIN],
|
||||
components: {
|
||||
"info": clubRuleInfo,
|
||||
},
|
||||
|
||||
+10
-5
@@ -1,12 +1,15 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style></style>
|
||||
<style>
|
||||
<!--#include("../fixedListLayout.css"){}#-->
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<div class="club-info-fixed-list-page">
|
||||
<el-card class="club-info-fixed-query-card" shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度">
|
||||
<el-date-picker
|
||||
@@ -30,7 +33,7 @@ layout("/layouts/platform.html"){
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card class="mt10" shadow="never">
|
||||
<el-card class="mt10 club-info-fixed-list-card" shadow="never">
|
||||
<table-tool label="申请列表">
|
||||
<el-button size="small" type="primary" @click="exportRefreshReportZip">导出换届报告Zip</el-button>
|
||||
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
||||
@@ -38,7 +41,7 @@ layout("/layouts/platform.html"){
|
||||
<el-radio-button :label="false">未审核</el-radio-button>
|
||||
</el-radio-group>
|
||||
</table-tool>
|
||||
<el-table :data="tableData">
|
||||
<el-table :data="tableData" :height="tableHeight" ref="tableRef">
|
||||
<el-table-column :index="indexMethod" label="序号" type="index" width="80px"></el-table-column>
|
||||
<el-table-column label="社团名称" prop="clubName" sortable show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="申请人" prop="userName" sortable show-overflow-tooltip></el-table-column>
|
||||
@@ -64,6 +67,7 @@ layout("/layouts/platform.html"){
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #edit>
|
||||
@@ -93,9 +97,10 @@ layout("/layouts/platform.html"){
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include("../refreshReport/info.js"){}#-->
|
||||
<!--#include("../fixedListLayout.js"){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
mixins: [initTableMixins],
|
||||
mixins: [initTableMixins, CLUB_INFO_FIXED_LIST_MIXIN],
|
||||
components: {
|
||||
"info": clubRefreshInfo,
|
||||
},
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style></style>
|
||||
<style>
|
||||
<!--#include("../fixedListLayout.css"){}#-->
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<div class="club-info-fixed-list-page">
|
||||
<el-card class="club-info-fixed-query-card" shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度">
|
||||
<el-date-picker
|
||||
@@ -30,14 +33,14 @@ layout("/layouts/platform.html"){
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card class="mt10" shadow="never">
|
||||
<el-card class="mt10 club-info-fixed-list-card" shadow="never">
|
||||
<table-tool label="申请列表">
|
||||
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
||||
<el-radio-button :label="true">已审核</el-radio-button>
|
||||
<el-radio-button :label="false">未审核</el-radio-button>
|
||||
</el-radio-group>
|
||||
</table-tool>
|
||||
<el-table :data="tableData">
|
||||
<el-table :data="tableData" :height="tableHeight" ref="tableRef">
|
||||
<el-table-column :index="indexMethod" label="序号" type="index" width="80px"></el-table-column>
|
||||
<el-table-column label="社团名称" prop="clubName" sortable show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="申请人" prop="userName" sortable show-overflow-tooltip></el-table-column>
|
||||
@@ -63,6 +66,7 @@ layout("/layouts/platform.html"){
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #edit>
|
||||
@@ -92,9 +96,10 @@ layout("/layouts/platform.html"){
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include("../ruleUpdate/info.js"){}#-->
|
||||
<!--#include("../fixedListLayout.js"){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
mixins: [initTableMixins],
|
||||
mixins: [initTableMixins, CLUB_INFO_FIXED_LIST_MIXIN],
|
||||
components: {
|
||||
"info": clubRuleInfo,
|
||||
},
|
||||
|
||||
+14
-8
@@ -1,11 +1,15 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style>
|
||||
<!--#include("../fixedListLayout.css"){}#-->
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<div class="outlay-union-fixed-list-page">
|
||||
<el-card class="outlay-union-fixed-query-card" shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度">
|
||||
<el-date-picker
|
||||
@@ -38,7 +42,7 @@ layout("/layouts/platform.html"){
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt10">
|
||||
<el-card class="outlay-union-fixed-list-card mt10" shadow="never">
|
||||
<table-tool label="预算分配">
|
||||
<el-button @click="showBatchAllocateDialog" size="small" type="primary" :loading="formLoading">一键分配
|
||||
</el-button>
|
||||
@@ -51,7 +55,7 @@ layout("/layouts/platform.html"){
|
||||
<el-button @click="deleteAllocateRecord" size="small" type="danger" :loading="formLoading">重置分配记录
|
||||
</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" style="width: 100%" row-key="id"
|
||||
<el-table ref="tableRef" :data="tableData" :height="tableHeight" style="width: 100%" row-key="id"
|
||||
v-loading="tableLoading" :size="tableSize" class="vi-table">
|
||||
|
||||
<el-table-column type="index" :index="indexMethod" label="序号"
|
||||
@@ -100,6 +104,7 @@ layout("/layouts/platform.html"){
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<el-dialog title="一键分配所有工会额度" :visible.sync="batchAllocateDialogVisible" width="700px">
|
||||
<el-form :model="batchAllocateForm" label-width="120px">
|
||||
@@ -137,8 +142,8 @@ layout("/layouts/platform.html"){
|
||||
<el-table-column type="index" label="序号" width="60"></el-table-column>
|
||||
<el-table-column prop="unionCode" label="工会编码" min-width="120"></el-table-column>
|
||||
<el-table-column prop="unionName" label="工会名称" min-width="160"></el-table-column>
|
||||
<el-table-column prop="allocateMoney" label="分配额度" min-width="120"></el-table-column>
|
||||
<el-table-column prop="errMsg" label="校验结果" min-width="180">
|
||||
<el-table-column prop="allocateMoney" label="年初数" min-width="120"></el-table-column>
|
||||
<el-table-column prop="errMsg" label="经费余额" min-width="180">
|
||||
<template slot-scope="{row}">
|
||||
<span class="text-danger" v-if="row.errMsg">{{row.errMsg}}</span>
|
||||
<span class="text-success" v-else>通过</span>
|
||||
@@ -193,10 +198,11 @@ layout("/layouts/platform.html"){
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include("../fixedListLayout.js"){}#-->
|
||||
new Vue({
|
||||
el: '#app',
|
||||
store,
|
||||
mixins: [initTableMixins],
|
||||
mixins: [initTableMixins, OUTLAY_UNION_FIXED_LIST_MIXIN],
|
||||
dicts: ["OUTLAY_QUARTERLY"],
|
||||
data() {
|
||||
return {
|
||||
@@ -208,8 +214,8 @@ layout("/layouts/platform.html"){
|
||||
{prop: 'year', label: '年度'},
|
||||
{prop: 'quarterly', label: '分配项目'},
|
||||
{prop: 'unionName', label: '工会名称'},
|
||||
{prop: 'allocateHeadMoney', label: '分配前额度'},
|
||||
{prop: 'allocateMoney', label: '分配额度'},
|
||||
{prop: 'allocateHeadMoney', label: '年初数'},
|
||||
{prop: 'allocateMoney', label: '经费额度'},
|
||||
],
|
||||
periodList: [],
|
||||
batchAllocateDialogVisible: false,
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 分工会预算列表页统一布局:页面固定占满平台内容区,
|
||||
* 查询区和工具栏保持原高度,超出的数据仅在表格内部滚动。
|
||||
*/
|
||||
#app .outlay-union-fixed-list-page {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - 82px);
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#app .outlay-union-fixed-query-card {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
#app .outlay-union-fixed-list-card {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#app .outlay-union-fixed-list-card > .el-card__body {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#app .outlay-union-fixed-list-card .ele-table-tool,
|
||||
#app .outlay-union-fixed-list-card .el-pagination-container,
|
||||
#app .outlay-union-fixed-list-card .outlay-union-summary-table {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
#app .outlay-union-fixed-list-card .outlay-union-summary-table {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#app .outlay-union-fixed-list-card .outlay-union-summary-table .el-table__body-wrapper {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
/* 合计行单独展示时不显示单元格网格线,避免与上方数据表格的边框重复。 */
|
||||
#app .outlay-union-fixed-list-card .outlay-union-summary-table,
|
||||
#app .outlay-union-fixed-list-card .outlay-union-summary-table::before,
|
||||
#app .outlay-union-fixed-list-card .outlay-union-summary-table::after,
|
||||
#app .outlay-union-fixed-list-card .outlay-union-summary-table .el-table__body,
|
||||
#app .outlay-union-fixed-list-card .outlay-union-summary-table .el-table__body tr,
|
||||
#app .outlay-union-fixed-list-card .outlay-union-summary-table .el-table__body td {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
/* 合计标签单元格保留完整边框,突出汇总行的起始位置。 */
|
||||
#app .outlay-union-fixed-list-card .outlay-union-summary-table .el-table__body td:first-child {
|
||||
border: 1px solid #ebeef5 !important;
|
||||
}
|
||||
|
||||
#app .outlay-union-fixed-list-card .outlay-union-fixed-table {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 分工会预算列表页统一高度逻辑:表格高度按列表卡片剩余空间动态计算,
|
||||
* 窗口尺寸或平台内容区变化时重新布局,保证分页始终可见。
|
||||
*/
|
||||
const OUTLAY_UNION_FIXED_LIST_MIXIN = {
|
||||
data() {
|
||||
return {
|
||||
tableHeight: 300,
|
||||
outlayUnionResizeObserver: null,
|
||||
outlayUnionResizeHandler: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateOutlayUnionTableHeight() {
|
||||
this.$nextTick(() => {
|
||||
const page = this.$el.querySelector('.outlay-union-fixed-list-page')
|
||||
const cardBody = this.$el.querySelector('.outlay-union-fixed-list-card > .el-card__body')
|
||||
if (!page || !cardBody || cardBody.clientHeight <= 0) {
|
||||
return
|
||||
}
|
||||
const getOuterHeight = (element) => {
|
||||
if (!element) {
|
||||
return 0
|
||||
}
|
||||
const style = window.getComputedStyle(element)
|
||||
return element.offsetHeight
|
||||
+ (parseFloat(style.marginTop) || 0)
|
||||
+ (parseFloat(style.marginBottom) || 0)
|
||||
}
|
||||
const bodyStyle = window.getComputedStyle(cardBody)
|
||||
const bodyPadding = (parseFloat(bodyStyle.paddingTop) || 0)
|
||||
+ (parseFloat(bodyStyle.paddingBottom) || 0)
|
||||
const tableTool = cardBody.querySelector('.ele-table-tool')
|
||||
const summaryTable = cardBody.querySelector('.outlay-union-summary-table')
|
||||
const pagination = cardBody.querySelector('.el-pagination-container')
|
||||
const reservedHeight = bodyPadding
|
||||
+ getOuterHeight(tableTool)
|
||||
+ getOuterHeight(summaryTable)
|
||||
+ getOuterHeight(pagination)
|
||||
const nextHeight = Math.max(1, Math.floor(cardBody.clientHeight - reservedHeight))
|
||||
if (this.tableHeight !== nextHeight) {
|
||||
this.tableHeight = nextHeight
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.tableRef) {
|
||||
this.$refs.tableRef.doLayout()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.updateOutlayUnionTableHeight()
|
||||
const page = this.$el.querySelector('.outlay-union-fixed-list-page')
|
||||
if (window.ResizeObserver && page) {
|
||||
this.outlayUnionResizeObserver = new ResizeObserver(() => {
|
||||
this.updateOutlayUnionTableHeight()
|
||||
})
|
||||
this.outlayUnionResizeObserver.observe(page)
|
||||
} else {
|
||||
this.outlayUnionResizeHandler = () => {
|
||||
this.updateOutlayUnionTableHeight()
|
||||
}
|
||||
window.addEventListener('resize', this.outlayUnionResizeHandler)
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.outlayUnionResizeObserver) {
|
||||
this.outlayUnionResizeObserver.disconnect()
|
||||
}
|
||||
if (this.outlayUnionResizeHandler) {
|
||||
window.removeEventListener('resize', this.outlayUnionResizeHandler)
|
||||
}
|
||||
},
|
||||
}
|
||||
+78
-5
@@ -1,12 +1,16 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style>
|
||||
<!--#include("../fixedListLayout.css"){}#-->
|
||||
</style>
|
||||
|
||||
|
||||
<div class="platform" id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<div class="outlay-union-fixed-list-page">
|
||||
<el-card class="outlay-union-fixed-query-card" shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度">
|
||||
<el-date-picker
|
||||
@@ -33,11 +37,11 @@ layout("/layouts/platform.html"){
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mt10">
|
||||
<el-card class="outlay-union-fixed-list-card mt10" shadow="never">
|
||||
<table-tool label="经费收支使用情况表">
|
||||
<el-button size="mini" type="primary" @click="doExport">导出</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" style="width: 100%" row-key="unionId"
|
||||
<el-table ref="tableRef" :data="tableData" :height="tableHeight" style="width: 100%" row-key="unionId"
|
||||
v-loading="tableLoading" :size="tableSize" class="vi-table"
|
||||
border>
|
||||
<el-table-column
|
||||
@@ -120,27 +124,95 @@ layout("/layouts/platform.html"){
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-table
|
||||
:data="[summaryData]"
|
||||
:show-header="false"
|
||||
v-loading="summaryLoading"
|
||||
class="vi-table outlay-union-summary-table"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
align="center"
|
||||
header-align="center"
|
||||
label="单位"
|
||||
prop="unionName"
|
||||
min-width="140">
|
||||
<template v-slot>合计</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" header-align="center" label="年初数" prop="beginMoney" min-width="120">
|
||||
<template v-slot="{row}">{{summaryValue('beginMoney', row)}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" header-align="center" label="1-4月会费" prop="feeJanApr" min-width="120">
|
||||
<template v-slot="{row}">{{summaryValue('feeJanApr', row)}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" header-align="center" label="5-8月会费" prop="feeMayAug" min-width="120">
|
||||
<template v-slot="{row}">{{summaryValue('feeMayAug', row)}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" header-align="center" label="9-12月会费" prop="feeSepDec" min-width="120">
|
||||
<template v-slot="{row}">{{summaryValue('feeSepDec', row)}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" header-align="center" label="评优奖励" prop="awardMoney" min-width="120">
|
||||
<template v-slot="{row}">{{summaryValue('awardMoney', row)}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" header-align="center" label="1-12月支出" prop="usedMoney" min-width="120">
|
||||
<template v-slot="{row}">{{summaryValue('usedMoney', row)}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" header-align="center" label="经费余额" prop="remainMoney" min-width="120">
|
||||
<template v-slot="{row}">{{summaryValue('remainMoney', row)}}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
</guava>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include("../fixedListLayout.js"){}#-->
|
||||
const vue = new Vue({
|
||||
el: '#app',
|
||||
store,
|
||||
mixins: [initTableMixins],
|
||||
mixins: [initTableMixins, OUTLAY_UNION_FIXED_LIST_MIXIN],
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
year: this.$moment().format("YYYY"),
|
||||
unionId: ""
|
||||
},
|
||||
unions: []
|
||||
unions: [],
|
||||
summaryData: {},
|
||||
summaryLoading: false,
|
||||
summaryLoaded: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doSearch() {
|
||||
this.tableKey = new Date().getTime()
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageData()
|
||||
this.querySummary()
|
||||
},
|
||||
querySummary() {
|
||||
this.summaryLoaded = false
|
||||
this.summaryLoading = true
|
||||
this.$axios.post(loc() + "/summary", {
|
||||
year: this.pageForm.year,
|
||||
unionId: this.pageForm.unionId || ""
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.summaryData = res.data || {}
|
||||
this.summaryLoaded = true
|
||||
}
|
||||
}).finally(() => {
|
||||
this.summaryLoading = false
|
||||
})
|
||||
},
|
||||
summaryValue(prop, row) {
|
||||
if (!this.summaryLoaded) {
|
||||
return ""
|
||||
}
|
||||
return this.formatMoney(row[prop])
|
||||
},
|
||||
formatMoney(value) {
|
||||
return Number(value || 0).toFixed(2)
|
||||
},
|
||||
@@ -154,6 +226,7 @@ layout("/layouts/platform.html"){
|
||||
this.unions = data
|
||||
})
|
||||
this.pageData()
|
||||
this.querySummary()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
+8
-5
@@ -2,13 +2,14 @@
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style>
|
||||
|
||||
<!--#include("../fixedListLayout.css"){}#-->
|
||||
</style>
|
||||
|
||||
<div class="platform" id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<div class="outlay-union-fixed-list-page">
|
||||
<el-card class="outlay-union-fixed-query-card" shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度">
|
||||
<el-date-picker
|
||||
@@ -34,7 +35,7 @@ layout("/layouts/platform.html"){
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mt10">
|
||||
<el-card class="outlay-union-fixed-list-card mt10" shadow="never">
|
||||
<table-tool label="预算分配">
|
||||
<template v-if="pageForm.year===$moment().format('YYYY')">
|
||||
<el-button @click="issuedOutlay" size="small" type="primary" v-if="!isAllocation">年度分配
|
||||
@@ -44,7 +45,7 @@ layout("/layouts/platform.html"){
|
||||
</el-button>
|
||||
</template>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" style="width: 100%" row-key="id"
|
||||
<el-table ref="tableRef" :data="tableData" :height="tableHeight" style="width: 100%" row-key="id"
|
||||
v-loading="tableLoading" :size="tableSize" class="vi-table">
|
||||
|
||||
<el-table-column align="center" header-align="center" type="index"
|
||||
@@ -95,15 +96,17 @@ layout("/layouts/platform.html"){
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
</guava>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include("../fixedListLayout.js"){}#-->
|
||||
const vue = new Vue({
|
||||
el: '#app',
|
||||
store,
|
||||
mixins: [initTableMixins],
|
||||
mixins: [initTableMixins, OUTLAY_UNION_FIXED_LIST_MIXIN],
|
||||
data() {
|
||||
return {
|
||||
tableColumns: [
|
||||
|
||||
+71
-6
@@ -2,13 +2,14 @@
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style>
|
||||
|
||||
<!--#include("../fixedListLayout.css"){}#-->
|
||||
</style>
|
||||
|
||||
<div class="platform" id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<div class="outlay-union-fixed-list-page">
|
||||
<el-card class="outlay-union-fixed-query-card" shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度">
|
||||
<el-date-picker
|
||||
@@ -35,11 +36,11 @@ layout("/layouts/platform.html"){
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mt10">
|
||||
<el-card class="outlay-union-fixed-list-card mt10" shadow="never">
|
||||
<table-tool label="预算使用情况">
|
||||
|
||||
</table-tool>
|
||||
<el-table :data="tableData" style="width: 100%" row-key="id"
|
||||
<el-table ref="tableRef" :data="tableData" :height="tableHeight" style="width: 100%" row-key="id"
|
||||
v-loading="tableLoading" :size="tableSize" class="vi-table">
|
||||
|
||||
<el-table-column align="center" header-align="center" type="index"
|
||||
@@ -71,8 +72,34 @@ layout("/layouts/platform.html"){
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-table
|
||||
:data="[summaryData]"
|
||||
:show-header="false"
|
||||
v-loading="summaryLoading"
|
||||
class="vi-table outlay-union-summary-table"
|
||||
style="width: 100%">
|
||||
<el-table-column align="center" header-align="center" label="合计" width="80">
|
||||
<template v-slot>合计</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
header-align="center"
|
||||
v-for="column in tableColumns"
|
||||
:label="column.label"
|
||||
:prop="column.prop"
|
||||
:width="column.width"
|
||||
min-width="50">
|
||||
<template v-slot="{row}">
|
||||
{{summaryValue(column.prop, row)}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" header-align="center" label="操作" width="250">
|
||||
<template v-slot></template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #view>
|
||||
@@ -89,10 +116,11 @@ layout("/layouts/platform.html"){
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include("detailInfo.js"){}#-->
|
||||
<!--#include("quarterlyOutlayAllocate.js"){}#-->
|
||||
<!--#include("../fixedListLayout.js"){}#-->
|
||||
const vue = new Vue({
|
||||
el: '#app',
|
||||
store,
|
||||
mixins: [initTableMixins],
|
||||
mixins: [initTableMixins, OUTLAY_UNION_FIXED_LIST_MIXIN],
|
||||
data() {
|
||||
return {
|
||||
tableColumns: [
|
||||
@@ -106,7 +134,10 @@ layout("/layouts/platform.html"){
|
||||
pageForm: {
|
||||
year: this.$moment().format("YYYY")
|
||||
},
|
||||
unions: []
|
||||
unions: [],
|
||||
summaryData: {},
|
||||
summaryLoading: false,
|
||||
summaryLoaded: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
@@ -114,6 +145,39 @@ layout("/layouts/platform.html"){
|
||||
"outlay-manage-union-quarterly-allocate": OUTLAY_MANAGE_UNION_QUARTERLY_ALLOCATE
|
||||
},
|
||||
methods: {
|
||||
doSearch() {
|
||||
this.tableKey = new Date().getTime()
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageData()
|
||||
this.querySummary()
|
||||
},
|
||||
querySummary() {
|
||||
this.summaryLoaded = false
|
||||
this.summaryLoading = true
|
||||
this.$axios.post(loc() + "/summary", {
|
||||
year: this.pageForm.year,
|
||||
unionId: this.pageForm.unionId || ""
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.summaryData = res.data || {}
|
||||
this.summaryLoaded = true
|
||||
}
|
||||
}).finally(() => {
|
||||
this.summaryLoading = false
|
||||
})
|
||||
},
|
||||
summaryValue(prop, row) {
|
||||
if (!this.summaryLoaded) {
|
||||
return ""
|
||||
}
|
||||
if (["totalQuota", "usedQuota", "surplusQuota"].indexOf(prop) < 0) {
|
||||
return ""
|
||||
}
|
||||
return this.formatMoney(row[prop])
|
||||
},
|
||||
formatMoney(value) {
|
||||
return Number(value || 0).toFixed(2)
|
||||
},
|
||||
openAllocateView(row) {
|
||||
this.$refs.guava.edit(() => {
|
||||
this.$refs.quarterlyAllocate.open(row)
|
||||
@@ -129,6 +193,7 @@ layout("/layouts/platform.html"){
|
||||
async created() {
|
||||
this.unions = await this.$businessTool.listUnion()
|
||||
this.pageData()
|
||||
this.querySummary()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
+2
-2
@@ -13,8 +13,8 @@ let OUTLAY_MANAGE_UNION_QUARTERLY_ALLOCATE = {
|
||||
:value="row.quarterly"></dict-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="分配前额度" prop="allocateHeadMoney"></el-table-column>
|
||||
<el-table-column label="分配额度" prop="allocateMoney"></el-table-column>
|
||||
<el-table-column label="年初数" prop="allocateHeadMoney"></el-table-column>
|
||||
<el-table-column label="经费额度" prop="allocateMoney"></el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
+19
-4
@@ -39,7 +39,7 @@ layout("/layouts/platform.html"){
|
||||
<el-card shadow="never">
|
||||
<table-tool>
|
||||
<el-button size="small" type="primary" icon="el-icon-plus" @click="doAllocateDelegation">
|
||||
根据单位分配代表团
|
||||
{{ allocateButtonText }}
|
||||
</el-button>
|
||||
<el-button size="small" type="primary" icon="el-icon-plus" @click="excelImportDialog = true">导入代表</el-button>
|
||||
<el-button size="small" type="primary" icon="el-icon-plus" @click="$refs.addFormRef.onOpen(pageForm.sessionId,pageForm.delegationId)">新增代表</el-button>
|
||||
@@ -138,19 +138,34 @@ layout("/layouts/platform.html"){
|
||||
roleOptions: [],
|
||||
formRules: {},
|
||||
|
||||
excelImportDialog: false
|
||||
excelImportDialog: false,
|
||||
compositionMode: "${config.dbtzc!'unit'}"
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
compositionLabel() {
|
||||
return this.compositionMode === "union" ? "分工会" : "单位"
|
||||
},
|
||||
allocateButtonText() {
|
||||
return "根据" + this.compositionLabel + "分配代表团"
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doAllocateDelegation() {
|
||||
this.$confirm("确定要一键给没有代表团的代表,根据单位所在代表团设置代表团吗?", "提示", {
|
||||
this.$confirm("确定要给尚未归团的代表,根据" + this.compositionLabel + "组成关系设置代表团吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "info"
|
||||
}).then(() => {
|
||||
this.$axios.post(loc() + "/doAllocateDelegation", {sessionId: this.pageForm.sessionId}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
let message = "已分配" + res.data.assignedCount + "人"
|
||||
if (res.data.unassignedCount > 0) {
|
||||
message += ",另有" + res.data.unassignedCount + "人未找到对应代表团"
|
||||
this.$message.warning(message)
|
||||
} else {
|
||||
this.$message.success(message)
|
||||
}
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
|
||||
+17
-4
@@ -35,7 +35,7 @@ layout("/layouts/platform.html"){
|
||||
设置团长
|
||||
</el-link>
|
||||
<el-link @click="$refs.partUnitRef.onOpen(scope.row.id,scope.row.sessionId)" size="mini" type="primary">
|
||||
设置组成单位
|
||||
{{ compositionButtonText }}
|
||||
</el-link>
|
||||
<el-link @click="doDelete(scope.row.id)" size="mini" type="danger">删除</el-link>
|
||||
</template>
|
||||
@@ -46,11 +46,12 @@ layout("/layouts/platform.html"){
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-tabs v-model="secondLevelTabActive">
|
||||
<el-tab-pane label="组成单位" name="partUnitTable">
|
||||
<el-tab-pane :label="compositionTabLabel" name="partUnitTable">
|
||||
<el-card class="mt10" shadow="never" style="border: 1px solid var(--border-color-lighter)">
|
||||
<part-unit-table
|
||||
:delegation_id="currentTreeData.id"
|
||||
:session_id="pageForm.sessionId"
|
||||
:composition_mode="compositionMode"
|
||||
@open="(delegation_id,session_id)=>{$refs.partUnitRef.onOpen(delegation_id,session_id)}"
|
||||
ref="partUnitTableRef"
|
||||
></part-unit-table>
|
||||
@@ -73,7 +74,7 @@ layout("/layouts/platform.html"){
|
||||
</el-row>
|
||||
|
||||
<au-form @refresh="refresh" ref="auFormRef"></au-form>
|
||||
<part-unit @refresh="refresh" ref="partUnitRef"></part-unit>
|
||||
<part-unit :composition_mode="compositionMode" @refresh="refresh" ref="partUnitRef"></part-unit>
|
||||
<head-form @refresh="refresh" ref="headFormRef"></head-form>
|
||||
</div>
|
||||
|
||||
@@ -95,7 +96,19 @@ layout("/layouts/platform.html"){
|
||||
currentTreeData: null,
|
||||
currentTreeSessionId: null,
|
||||
|
||||
secondLevelTabActive: "partUnitTable"
|
||||
secondLevelTabActive: "partUnitTable",
|
||||
compositionMode: "${config.dbtzc!'unit'}"
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
compositionLabel() {
|
||||
return this.compositionMode === "union" ? "分工会" : "单位"
|
||||
},
|
||||
compositionButtonText() {
|
||||
return "设置组成" + this.compositionLabel
|
||||
},
|
||||
compositionTabLabel() {
|
||||
return "组成" + this.compositionLabel
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
||||
+37
-27
@@ -1,35 +1,45 @@
|
||||
const PART_UNIT_TEMPLATE = {
|
||||
template: `
|
||||
<el-dialog title="设置组成单位" :visible.sync="partUnitDialogFormVisible" width="1000px" :close-on-click-modal="false">
|
||||
<el-transfer
|
||||
ref="transferRef"
|
||||
:titles="['可选二级单位', '当前成员单位']"
|
||||
filterable
|
||||
:props="{
|
||||
key: 'id',
|
||||
label: 'name'
|
||||
}"
|
||||
:filter-method="(query,item)=>{return item.name.indexOf(query) > -1}"
|
||||
v-model="selectUnitsIds"
|
||||
:data="allUnits"
|
||||
></el-transfer>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="partUnitDialogFormVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="doSubmitPartUnit">确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
`,
|
||||
template: [
|
||||
'<el-dialog :title="dialogTitle" :visible.sync="partUnitDialogFormVisible" width="1000px" :close-on-click-modal="false">',
|
||||
'<el-transfer ref="transferRef" :titles="transferTitles" filterable ',
|
||||
':props="{key: \'id\', label: \'name\'}" ',
|
||||
':filter-method="filterItem" v-model="selectedIds" :data="allItems"></el-transfer>',
|
||||
'<div slot="footer" class="dialog-footer">',
|
||||
'<el-button @click="partUnitDialogFormVisible = false">取 消</el-button>',
|
||||
'<el-button type="primary" @click="doSubmitPartUnit">确 定</el-button>',
|
||||
'</div><slot></slot></el-dialog>'
|
||||
].join(''),
|
||||
props: {
|
||||
composition_mode: {
|
||||
type: String,
|
||||
default: "unit"
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
partUnitDialogFormVisible: false,
|
||||
selectUnitsIds: [],
|
||||
allUnits: [],
|
||||
selectedIds: [],
|
||||
allItems: [],
|
||||
|
||||
delegationId: null,
|
||||
sessionId: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
compositionLabel() {
|
||||
return this.composition_mode === "union" ? "分工会" : "单位"
|
||||
},
|
||||
dialogTitle() {
|
||||
return "设置组成" + this.compositionLabel
|
||||
},
|
||||
transferTitles() {
|
||||
return ["可选" + this.compositionLabel, "当前组成" + this.compositionLabel]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
filterItem(query, item) {
|
||||
return item.name.indexOf(query) > -1
|
||||
},
|
||||
onOpen(delegationId, sessionId) {
|
||||
if (!delegationId || !sessionId) {
|
||||
return
|
||||
@@ -43,21 +53,21 @@ const PART_UNIT_TEMPLATE = {
|
||||
}
|
||||
|
||||
this.$axios
|
||||
.post("/platform/teacherCongress/delegation/partUnitTransferData", {
|
||||
.post("/platform/teacherCongress/delegation/compositionTransferData", {
|
||||
delegationId,
|
||||
sessionId
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.selectUnitsIds = res.data.selectUnitIds
|
||||
this.allUnits = res.data.allUnits
|
||||
this.selectedIds = res.data.selectedIds
|
||||
this.allItems = res.data.allItems
|
||||
}
|
||||
})
|
||||
},
|
||||
doSubmitPartUnit() {
|
||||
this.$axios
|
||||
.post(loc() + "/partUnitSet", {
|
||||
unitIds: JSON.stringify(this.selectUnitsIds),
|
||||
.post(loc() + "/compositionSet", {
|
||||
itemIds: JSON.stringify(this.selectedIds),
|
||||
delegationId: this.delegationId,
|
||||
sessionId: this.sessionId
|
||||
})
|
||||
|
||||
+24
-13
@@ -1,16 +1,18 @@
|
||||
const PART_UNIT_TABLE_TEMPLATE = {
|
||||
template: `
|
||||
<div>
|
||||
<table-tool>
|
||||
<el-button size="small" type="primary" icon="el-icon-edit" @click="open">设置组成单位</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" border>
|
||||
<el-table-column type="index" label="序号" width="100px"></el-table-column>
|
||||
<el-table-column prop="name" label="名称"></el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</div>
|
||||
`,
|
||||
template: [
|
||||
'<div><table-tool>',
|
||||
'<el-button size="small" type="primary" icon="el-icon-edit" @click="open">{{ buttonText }}</el-button>',
|
||||
'</table-tool><el-table :data="tableData" border>',
|
||||
'<el-table-column type="index" label="序号" width="100px"></el-table-column>',
|
||||
'<el-table-column prop="code" label="编码"></el-table-column>',
|
||||
'<el-table-column prop="name" label="名称"></el-table-column>',
|
||||
'</el-table><el-row class="el-pagination-container" style="margin-top: 20px">',
|
||||
'<el-pagination @size-change="pageSizeChange" @current-change="pageNumberChange" ',
|
||||
':current-page="pageForm.pageNumber" :page-sizes="[5,10,20,30,50]" ',
|
||||
':page-size="pageForm.pageSize" layout="total, sizes, prev, pager, next" ',
|
||||
':total="pageForm.totalCount"></el-pagination>',
|
||||
'</el-row><slot></slot></div>'
|
||||
].join(''),
|
||||
mixins: [initTableMixins],
|
||||
props: {
|
||||
session_id: {
|
||||
@@ -20,6 +22,15 @@ const PART_UNIT_TABLE_TEMPLATE = {
|
||||
delegation_id: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
composition_mode: {
|
||||
type: String,
|
||||
default: "unit"
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
buttonText() {
|
||||
return "设置组成" + (this.composition_mode === "union" ? "分工会" : "单位")
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -49,7 +60,7 @@ const PART_UNIT_TABLE_TEMPLATE = {
|
||||
methods: {
|
||||
pageData() {
|
||||
this.$axios
|
||||
.post("/platform/teacherCongress/delegation/partUnitPageData", {
|
||||
.post("/platform/teacherCongress/delegation/compositionPageData", {
|
||||
...this.pageForm,
|
||||
sessionId: this.session_id,
|
||||
delegationId: this.delegation_id
|
||||
|
||||
Reference in New Issue
Block a user