@@ -8,7 +8,10 @@ import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.CommonDownloadUtil ;
import com.budwk.app.sys.models.* ;
import com.budwk.app.sys.services.SysDictService ;
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.SecurityUtil ;
import lombok.extern.slf4j.Slf4j ;
import org.apache.poi.ss.usermodel.* ;
import org.apache.poi.xssf.usermodel.XSSFWorkbook ;
@@ -17,6 +20,9 @@ import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject ;
import org.nutz.ioc.loader.annotation.IocBean ;
import org.nutz.lang.util.NutMap ;
import org.nutz.lang.random.R ;
import org.nutz.trans.Atom ;
import org.nutz.trans.Trans ;
import org.nutz.mvc.annotation.AdaptBy ;
import org.nutz.mvc.annotation.At ;
import org.nutz.mvc.annotation.Ok ;
@@ -26,9 +32,15 @@ import org.nutz.mvc.upload.UploadAdaptor;
import javax.servlet.http.HttpServletResponse ;
import java.io.InputStream ;
import java.sql.SQLException ;
import java.util.ArrayList ;
import java.util.Arrays ;
import java.util.Date ;
import java.util.HashSet ;
import java.util.List ;
import java.util.Map ;
import java.util.Set ;
import java.util.function.Function ;
import java.util.stream.Collectors ;
@Slf4j
@@ -45,6 +57,10 @@ public class SysUnionCadreImportController {
private SysDictService sysDictService ;
@Inject
private SysUnionController sysUnionController ;
@Inject
private SysRoleService sysRoleService ;
@Inject
private SysUserService sysUserService ;
@SuppressWarnings ( " unchecked " )
private List < NutMap > roleOptions ( ) {
@@ -72,7 +88,7 @@ public class SysUnionCadreImportController {
append ( notes , " 届次编码(选填) " , " 可留空;填写时使用届次对照表中的编码,与单个添加一致。 " ) ;
append ( notes , " 所属单位编码(书记必填) " , " 仅二级党委书记填写,多个单位用英文逗号分隔,必须为当前分工会的二级单位;其他角色留空。 " ) ;
append ( notes , " 重复记录 " , " 普通干部按人员和角色跳过;二级党委书记按人员、角色和工会跳过。禁用的已有关系也跳过,不覆盖。 " ) ;
append ( notes , " 保存方式 " , " 系统管理员直接授权,写入 干部及角色记录并 清理权限缓存,不发起审批。逐行保存,失败行不影响其他行 。 " ) ;
append ( notes , " 保存方式 " , " 系统管理员直接授权,批量校验并保存 干部及角色记录,统一 清理权限缓存,不发起审批。校验失败行不写入;保存异常时拆分定位失败行,其他有效行继续导入 。 " ) ;
append ( notes , " 已有干部记录 " , " 已有在任或待审核干部记录但未分配角色时跳过,避免重复创建或绕过已有审批。 " ) ;
Sheet unions = createSheet ( workbook , " 工会对照 " , " 工会编码 " , " 工会名称 " ) ;
List < Sys_union > unionList = dao . query ( Sys_union . class , Cnd . NEW ( ) . asc ( " unionCode " ) ) ;
@@ -145,101 +161,271 @@ public class SysUnionCadreImportController {
if ( rows . isEmpty ( ) ) {
return Result . error ( " 文件中没有需要导入的数据 " ) ;
}
List < String > roleCodes = roleOptions ( ) . stream ( ) . map ( item - > item . getString ( " code " ) ) . toList ( ) ;
List < String > terms = sysDictService . getSubListByCode ( " TEACHER_CONGRESS_J " ) . stream ( )
. map ( Sys_dict : : getCode ) . toList ( ) ;
int success = 0 ;
int skipped = 0 ;
Set < String > roleCodes = sysDictService . getSubListByCode ( " BRANCH_UNION_ROLES " ) . stream ( )
. map ( Sys_dict : : getCode ) . collect ( Collectors . toSet ( ) ) ;
roleCodes . add ( RoleConstant . UNIT_PARTY_SECRETARY . name ( ) ) ;
Set < String > terms = sysDictService . getSubListByCode ( " TEACHER_CONGRESS_J " ) . stream ( )
. map ( Sys_dict : : getCode ) . collect ( Collectors . toSet ( ) ) ;
List < String > unionCodes = values ( rows , " unionCode " ) ;
List < String > loginnames = values ( rows , " loginname " ) ;
List < String > inputRoleCodes = values ( rows , " roleCode " ) ;
List < String > unitCodes = rows . stream ( ) . flatMap ( row - > splitUnitCodes ( row . getString ( " unitCodes " ) ) . stream ( ) )
. distinct ( ) . toList ( ) ;
// 各类基础数据及已有关系按表一次查询,逐行校验时不再访问数据库。
Map < String , List < Sys_union > > unions = group ( unionCodes . isEmpty ( ) ? List . of ( )
: dao . query ( Sys_union . class , Cnd . where ( " unionCode " , " in " , unionCodes ) ) , Sys_union : : getUnionCode ) ;
Map < String , List < View_user > > users = group ( loginnames . isEmpty ( ) ? List . of ( )
: dao . query ( View_user . class , Cnd . where ( " loginname " , " in " , loginnames ) ) , View_user : : getLoginname ) ;
Map < String , List < Sys_role > > roles = group ( inputRoleCodes . isEmpty ( ) ? List . of ( )
: dao . query ( Sys_role . class , Cnd . where ( " code " , " in " , inputRoleCodes ) ) , Sys_role : : getCode ) ;
Map < String , List < Sys_unit > > units = group ( unitCodes . isEmpty ( ) ? List . of ( )
: dao . query ( Sys_unit . class , Cnd . where ( " unitcode " , " in " , unitCodes ) ) , Sys_unit : : getUnitcode ) ;
List < String > userIds = users . values ( ) . stream ( ) . flatMap ( List : : stream ) . map ( View_user : : getId ) . distinct ( ) . toList ( ) ;
List < String > roleIds = roles . values ( ) . stream ( ) . flatMap ( List : : stream ) . map ( Sys_role : : getId ) . distinct ( ) . toList ( ) ;
Set < List < String > > existingRoles = new HashSet < > ( ) ;
if ( ! userIds . isEmpty ( ) & & ! roleIds . isEmpty ( ) ) {
for ( Sys_user_role relation : dao . query ( Sys_user_role . class ,
Cnd . where ( " userId " , " in " , userIds ) . and ( " roleId " , " in " , roleIds ) ) ) {
existingRoles . add ( roleKey ( relation . getUserId ( ) , relation . getRoleId ( ) , relation . getUnionId ( ) ,
roles . getOrDefault ( RoleConstant . UNIT_PARTY_SECRETARY . name ( ) , List . of ( ) ) . stream ( )
. anyMatch ( role - > role . getId ( ) . equals ( relation . getRoleId ( ) ) ) ) ) ;
}
}
Set < List < String > > existingCadres = new HashSet < > ( ) ;
if ( ! userIds . isEmpty ( ) & & ! inputRoleCodes . isEmpty ( ) & & ! unionCodes . isEmpty ( ) ) {
List < String > unionIds = unions . values ( ) . stream ( ) . flatMap ( List : : stream ) . map ( Sys_union : : getId ) . distinct ( ) . toList ( ) ;
if ( ! unionIds . isEmpty ( ) ) {
for ( Sys_union_cadre cadre : dao . query ( Sys_union_cadre . class , Cnd . where ( " userId " , " in " , userIds )
. and ( " roleCode " , " in " , inputRoleCodes ) . and ( " unionId " , " in " , unionIds ) . and ( " isServing " , " = " , true ) ) ) {
existingCadres . add ( Arrays . asList ( cadre . getUserId ( ) , cadre . getRoleCode ( ) , cadre . getUnionId ( ) ) ) ;
}
}
}
List < ImportEntry > entries = new ArrayList < > ( ) ;
Map < List < String > , Integer > fileRoles = new java . util . HashMap < > ( ) ;
String operator = SecurityUtil . getUserId ( ) ;
for ( NutMap row : rows ) {
try {
importRow ( row , roleCodes , terms ) ;
} catch ( Exception e ) {
log . error ( " 导入分工会干部失败,行号:{} " , row . getInt ( " rowNumber " ) , e ) ;
outcome ( row , " 失败 " , " 保存失败,请检查该行数据或联系管理员 " ) ;
}
if ( " 成功 " . equals ( row . getString ( " status " ) ) ) {
success + + ;
} else if ( " 跳过 " . equals ( row . getString ( " status " ) ) ) {
skipped + + ;
ImportEntry entry = prepareRow ( row , roleCodes , terms , unions , users , roles , units ,
existingRoles , existingCadres , fileRoles , operator ) ;
if ( entry ! = null ) {
entries . add ( entry ) ;
}
}
saveBatch ( entries ) ;
int success = ( int ) rows . stream ( ) . filter ( row - > " 成功 " . equals ( row . getString ( " status " ) ) ) . count ( ) ;
int skipped = ( int ) rows . stream ( ) . filter ( row - > " 跳过 " . equals ( row . getString ( " status " ) ) ) . count ( ) ;
if ( success > 0 ) {
sysRoleService . clearCache ( ) ;
sysUserService . clearCache ( ) ;
}
return Result . success ( NutMap . NEW ( ) . addv ( " success " , success ) . addv ( " skipped " , skipped )
. addv ( " failed " , rows . size ( ) - success - skipped ) . addv ( " rows " , rows ) ) ;
}
private void importRow ( NutMap row , List < String > roleCodes , List < String > terms ) {
private List < String > values ( List < NutMap > rows , String field ) {
return rows . stream ( ) . map ( row - > row . getString ( field ) ) . filter ( StrUtil : : isNotBlank ) . distinct ( ) . toList ( ) ;
}
private List < String > splitUnitCodes ( String codes ) {
return Arrays . stream ( codes . split ( " [,, ] " ) ) . map ( String : : trim ) . filter ( StrUtil : : isNotBlank ) . distinct ( ) . toList ( ) ;
}
private < T > Map < String , List < T > > group ( List < T > items , Function < T , String > key ) {
return items . stream ( ) . collect ( Collectors . groupingBy ( key ) ) ;
}
private List < String > roleKey ( String userId , String roleId , String unionId , boolean secretary ) {
return Arrays . asList ( userId , roleId , secretary ? unionId : " " ) ;
}
private < T > T unique ( Map < String , List < T > > records , String code , String label , List < String > errors ) {
if ( StrUtil . isBlank ( code ) ) {
errors . add ( label + " 不能为空 " ) ;
return null ;
}
List < T > matches = records . getOrDefault ( code , List . of ( ) ) ;
if ( matches . isEmpty ( ) ) {
errors . add ( label + " 【 " + code + " 】不存在 " ) ;
return null ;
}
if ( matches . size ( ) > 1 ) {
errors . add ( label + " 【 " + code + " 】匹配到 " + matches . size ( ) + " 条记录,需先处理系统中的重复编码 " ) ;
return null ;
}
return matches . get ( 0 ) ;
}
private ImportEntry prepareRow ( NutMap row , Set < String > roleCodes , Set < String > terms ,
Map < String , List < Sys_union > > unions , Map < String , List < View_user > > users ,
Map < String , List < Sys_role > > roles , Map < String , List < Sys_unit > > units ,
Set < List < String > > existingRoles , Set < List < String > > existingCadres ,
Map < List < String > , Integer > fileRoles , String operator ) {
String unionCode = row . getString ( " unionCode " ) ;
String loginname = row . getString ( " loginname " ) ;
String roleCode = row . getString ( " roleCode " ) ;
String j = row . getString ( " j " ) ;
if ( StrUtil . isBlank ( unionCode ) | | StrUtil . isBlank ( loginname ) | | StrUtil . isBlank ( roleCode ) ) {
outcome ( row , " 失败 " , " 工会编码、工号、角色编码不能为空 " ) ;
return ;
List < String > errors = new ArrayList < > ( ) ;
Sys_union union = unique ( unions , unionCode , " 工会编码 " , errors ) ;
View_user user = unique ( users , loginname , " 工号 " , errors ) ;
Sys_role role = unique ( roles , roleCode , " 角色编码 " , errors ) ;
if ( StrUtil . isNotBlank ( roleCode ) & & ! roleCodes . contains ( roleCode ) ) {
errors . add ( " 角色编码【 " + roleCode + " 】不在允许导入的分工会干部角色范围内,请参照角色对照表 " ) ;
}
List < Sys_union > unions = dao . query ( Sys_union . class , Cnd . where ( " unionCode " , " = " , unionCode ) ) ;
List < View_user > users = dao . query ( View_user . class , Cnd . where ( " loginname " , " = " , loginname ) ) ;
List < Sys_role > roles = dao . query ( Sys_role . class , Cnd . where ( " code " , " = " , roleCode ) ) ;
if ( unions . size ( ) ! = 1 | | users . size ( ) ! = 1 | | roles . size ( ) ! = 1 | | ! roleCodes . contains ( roleCode ) ) {
outcome ( row , " 失败 " , " 工会、工号或分工会角色编码不存在或不唯一,请按模板对照表填写 " ) ;
return ;
if ( ! errors . isEmpty ( ) ) {
outcome ( row , " 失败 " , String . join ( " ; " , errors ) ) ;
return null ;
}
Sys_union union = unions . get ( 0 ) ;
View_user user = users . get ( 0 ) ;
Sys_role role = roles . get ( 0 ) ;
boolean secretary = RoleConstant . UNIT_PARTY_SECRETARY . name ( ) . equals ( roleCode ) ;
Cnd existing = Cnd . where ( " userId " , " = " , user . getId ( ) ) . and ( " roleId " , " = " , role . getId ( ) ) ;
if ( secretary ) {
existing . and ( " unionId " , " = " , union . getId ( ) ) ;
}
if ( dao . count ( Sys_user_role . class , existing ) > 0 ) {
outcome ( row , " 跳过 " , " 已分配该角色,保留原有记录(含禁用关系) " ) ;
return ;
List < String > key = roleKey ( user . getId ( ) , role . getId ( ) , union . getId ( ) , secretary ) ;
if ( existingRoles . contains ( key ) ) {
outcome ( row , " 跳过 " , " 工号【 " + loginname + " 】已分配角色【 " + roleCode + " 】 "
+ ( secretary ? " (工会编码【 " + unionCode + " 】) " : " " ) + " ,保留原有记录(含禁用关系) " ) ;
return null ;
}
if ( ! union . getId ( ) . equals ( user . getUnionId ( ) ) ) {
outcome ( row , " 失败 " , " 所选人员不属于该分 工会" ) ;
return ;
errors . add ( " 工号【 " + loginname + " 】所属工会为【 " + StrUtil . blankToDefault ( user . getUnionName ( ) , " 未分配 工会" )
+ " 】,与填写的工会【 " + union . getName ( ) + " ( " + unionCode + " )】不一致 " ) ;
}
if ( StrUtil . isNotBlank ( j ) & & ! terms . contains ( j ) ) {
outcome ( row , " 失败 " , " 届次编码 不存在,请参照届次对照表或留空" ) ;
return ;
errors . add ( " 届次编码【 " + j + " 】 不存在,请参照届次对照表或留空" ) ;
}
if ( dao . count ( Sys_union_cadre . class , Cnd . where ( " userId " , " = " , user . getId ( ) )
. and ( " roleCode " , " = " , roleCode ) . and ( " unionId " , " = " , union . getId ( ) ) . and ( " isServing " , " = " , true ) ) > 0 ) {
outcome ( row , " 跳过 " , " 已有 在任或待审核干部记录,请通过原记录处理" ) ;
return ;
if ( existingCadres . contains ( Arrays . asList ( user . getId ( ) , roleCode , union . getId ( ) ) ) ) {
outcome ( row , " 跳过 " , " 工号【 " + loginname + " 】在工会【 " + unionCode + " 】已有角色【 " + roleCode
+ " 】的 在任或待审核干部记录,请通过原记录处理" ) ;
return null ;
}
List < String > unitIds = new ArrayList < > ( ) ;
String unitCodes = row . getString ( " unitCodes " ) ;
if ( secretary ) {
List < String > codes = Arrays . stream ( unitCodes . split ( " [,, ] " ) )
. map ( String : : trim ) . filter ( StrUtil : : isNotBlank ) . distinct ( ) . collect ( Collectors . toList ( ) ) ;
List < String > codes = splitUnitCodes ( unitCodes ) ;
if ( codes . isEmpty ( ) ) {
outcome ( row , " 失败 " , " 二级党委书记必须填写所属单位编码 " ) ;
return ;
errors . add ( " 角色【 二级党委书记】 必须填写所属单位编码,请参照所属单位对照表 " ) ;
}
for ( String code : codes ) {
List < Sys_unit > units = dao . query ( Sys_unit . class , Cnd . where ( " unitcode " , " = " , code )
. and ( " unionId " , " = " , union . getId ( ) ) . and ( " unitLevel " , " = " , 2 ) ) ;
if ( units . size ( ) ! = 1 ) {
outcome ( row , " 失败 " , " 所属单位编码不存在、不唯一或不是该分工会的二级单位: " + code ) ;
return ;
List < Sys_unit > matches = units . getOrDefault ( code , List . of ( ) ) ;
List < Sys_unit > valid = matches . stream ( ) . filter ( unit - > union . getId ( ) . equals ( unit . getUnionId ( ) )
& & Integer . valueOf ( 2 ) . equals ( unit . getUnitLevel ( ) ) ) . toList ( ) ;
if ( matches . isEmpty ( ) ) {
errors . add ( " 所属单位编码【 " + code + " 】不存在 " ) ;
} else if ( valid . isEmpty ( ) ) {
boolean inUnion = matches . stream ( ) . anyMatch ( unit - > union . getId ( ) . equals ( unit . getUnionId ( ) ) ) ;
errors . add ( inUnion ? " 所属单位编码【 " + code + " 】属于工会【 " + unionCode + " 】,但单位级别不是二级 "
: " 所属单位编码【 " + code + " 】不属于填写的工会【 " + union . getName ( ) + " ( " + unionCode + " )】 " ) ;
} else if ( valid . size ( ) > 1 ) {
errors . add ( " 所属单位编码【 " + code + " 】在工会【 " + unionCode + " 】下匹配到 " + valid . size ( ) + " 个二级单位,编码不唯一 " ) ;
} else {
unitIds . add ( valid . get ( 0 ) . getId ( ) ) ;
}
unitIds . add ( units . get ( 0 ) . getId ( ) ) ;
}
} else if ( StrUtil . isNotBlank ( unitCodes ) ) {
outcome ( row , " 失败 " , " 普通干部角色的所属单位编码 应留空" ) ;
errors . add ( " 角色【 " + roleCode + " 】不是二级党委书记,所属单位编码【 " + unitCodes + " 】 应留空" ) ;
}
if ( ! errors . isEmpty ( ) ) {
outcome ( row , " 失败 " , String . join ( " ; " , errors ) ) ;
return null ;
}
Integer previousRow = fileRoles . putIfAbsent ( key , row . getInt ( " rowNumber " ) ) ;
if ( previousRow ! = null ) {
outcome ( row , " 跳过 " , " 与本文件第 " + previousRow + " 行的人员角色授权重复 " ) ;
return null ;
}
Sys_union_cadre cadre = new Sys_union_cadre ( ) ;
cadre . setId ( R . UU32 ( ) ) ;
cadre . setUserId ( user . getId ( ) ) ;
cadre . setUnionId ( union . getId ( ) ) ;
cadre . setMobile ( user . getMobile ( ) ) ;
cadre . setUnionName ( user . getUnionName ( ) ) ;
cadre . setLoginName ( user . getLoginname ( ) ) ;
cadre . setUserName ( user . getUsername ( ) ) ;
cadre . setRoleCode ( roleCode ) ;
cadre . setJ ( j ) ;
cadre . setApplyDate ( new Date ( ) ) ;
cadre . setIsServing ( true ) ;
cadre . setIsJoin ( true ) ;
// fastInsert不执行实体插入拦截器,显式补齐主键及审计字段。
cadre . setCreatedBy ( operator ) ;
cadre . setUpdatedBy ( operator ) ;
cadre . setCreatedAt ( System . currentTimeMillis ( ) ) ;
cadre . setUpdatedAt ( cadre . getCreatedAt ( ) ) ;
cadre . setDelFlag ( false ) ;
List < Sys_user_role > relations = new ArrayList < > ( ) ;
for ( String unitId : secretary ? unitIds : java . util . Collections . singletonList ( ( String ) null ) ) {
Sys_user_role relation = new Sys_user_role ( ) ;
relation . setUserId ( user . getId ( ) ) ;
relation . setRoleId ( role . getId ( ) ) ;
relation . setUnionId ( union . getId ( ) ) ;
relation . setUnitId ( unitId ) ;
relations . add ( relation ) ;
}
return new ImportEntry ( row , cadre , relations ) ;
}
private void saveBatch ( List < ImportEntry > entries ) {
if ( entries . isEmpty ( ) ) {
return ;
}
// 经由注入的原控制器代理调用,保留单行事务、直接授权及缓存清理逻辑。
Result result = secretary
? sysUnionController . insertBranchUnionPartySecretaryRole ( user . getId ( ) , union . getId ( ) , unitIds . toArray ( new String [ 0 ] ) , j )
: sysUnionController . insertBranchUnionUserRole ( user . getId ( ) , roleCode , union . getId ( ) , j ) ;
if ( result . isSuccess ( ) ) {
outcome ( row , " 成功 " , " 添加成功 " ) ;
} else if ( " 请勿重复添加 " . equals ( result . getMsg ( ) ) | | " 该人员已设置二级党委书记,请先删除后再重新设置 " . equals ( result . getMsg ( ) ) ) {
outcome ( row , " 跳过 " , result . getMsg ( ) ) ;
} else {
outcome ( row , " 失败 " , result . getMsg ( ) ) ;
try {
// 两张表各批量写入一次,同一事务保证干部记录和角色授权同时生效。
Trans . exec ( ( Atom ) ( ) - > {
dao . fastInsert ( entries . stream ( ) . map ( entry - > entry . cadre ) . toList ( ) ) ;
dao . fastInsert ( entries . stream ( ) . flatMap ( entry - > entry . relations . stream ( ) ) . toList ( ) ) ;
} ) ;
entries . forEach ( entry - > outcome ( entry . row , " 成功 " , " 添加成功 " ) ) ;
} catch ( Exception e ) {
if ( entries . size ( ) > 1 ) {
// 仅保存异常时拆分批次定位坏行,正常导入不产生逐行写入。
int middle = entries . size ( ) / 2 ;
saveBatch ( entries . subList ( 0 , middle ) ) ;
saveBatch ( entries . subList ( middle , entries . size ( ) ) ) ;
} else {
NutMap row = entries . get ( 0 ) . row ;
log . error ( " 导入分工会干部保存失败,行号:{},工号:{},角色编码:{} " ,
row . getInt ( " rowNumber " ) , row . getString ( " loginname " ) , row . getString ( " roleCode " ) , e ) ;
outcome ( row , " 失败 " , saveFailure ( e ) ) ;
}
}
}
private String saveFailure ( Exception error ) {
for ( Throwable cause = error ; cause ! = null ; cause = cause . getCause ( ) ) {
if ( cause instanceof SQLException ) {
SQLException sql = ( SQLException ) cause ;
String state = sql . getSQLState ( ) ;
if ( " 23505 " . equals ( state ) | | sql . getErrorCode ( ) = = 1062 ) {
return " 保存时发生唯一键冲突,可能已有相同干部或角色授权记录;本行已回滚 " ;
}
if ( " 22001 " . equals ( state ) | | sql . getErrorCode ( ) = = 1406 ) {
return " 干部信息字段超出数据库长度限制,请检查工号、姓名、手机号、工会名称及届次长度;本行已回滚 " ;
}
if ( " 23502 " . equals ( state ) | | sql . getErrorCode ( ) = = 1048 | | sql . getErrorCode ( ) = = 1364 ) {
return " 干部记录或角色授权缺少数据库要求的必填值,请检查该人员的基础信息及干部表必填字段;本行已回滚 " ;
}
if ( " 23503 " . equals ( state ) | | sql . getErrorCode ( ) = = 1452 ) {
return " 人员、工会、角色或所属单位的关联记录已不存在,请核对对应系统数据;本行已回滚 " ;
}
if ( state ! = null & & state . startsWith ( " 23 " ) ) {
return " 干部记录或角色授权违反数据库必填、关联或唯一性约束,请核对人员、工会和角色数据;本行已回滚 " ;
}
if ( state ! = null & & state . startsWith ( " 08 " ) ) {
return " 保存干部及角色授权时数据库连接异常,本行未完成导入,可稍后重新导入 " ;
}
if ( state ! = null & & state . startsWith ( " 40 " ) ) {
return " 保存干部及角色授权时发生事务冲突,本行已回滚,可重新导入 " ;
}
}
}
return " 干部记录或角色授权写入异常,本行未完成导入;请管理员按Excel行号、工号及角色编码查看导入日志 " ;
}
private static class ImportEntry {
private final NutMap row ;
private final Sys_union_cadre cadre ;
private final List < Sys_user_role > relations ;
private ImportEntry ( NutMap row , Sys_union_cadre cadre , List < Sys_user_role > relations ) {
this . row = row ;
this . cadre = cadre ;
this . relations = relations ;
}
}