同步用户数据
This commit is contained in:
@@ -29,6 +29,7 @@ import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.utils.SecurityUtils;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.common.utils.poi.ExcelUtil;
|
||||
import com.bms.system.orgsync.OrgSyncService;
|
||||
import com.bms.system.service.ISysDeptService;
|
||||
import com.bms.system.service.ISysPostService;
|
||||
import com.bms.system.service.ISysRoleService;
|
||||
@@ -55,6 +56,9 @@ public class SysUserController extends BaseController
|
||||
@Autowired
|
||||
private ISysPostService postService;
|
||||
|
||||
@Autowired
|
||||
private OrgSyncService orgSyncService;
|
||||
|
||||
/**
|
||||
* 获取用户列表
|
||||
*/
|
||||
@@ -67,6 +71,19 @@ public class SysUserController extends BaseController
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从老系统(Oracle)同步部门/角色/用户。
|
||||
* 覆盖式迁移:除内置超级管理员外,现有演示部门、角色、用户将被替换。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:user:add')")
|
||||
@Log(title = "用户管理-老系统组织同步", businessType = BusinessType.IMPORT)
|
||||
@PostMapping("/syncFromOracle")
|
||||
public AjaxResult syncFromOracle()
|
||||
{
|
||||
Map<String, Object> result = orgSyncService.syncFromOracle();
|
||||
return AjaxResult.success(String.valueOf(result.get("summary")), result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户下拉选项(业务员/客服/采购员等选择用)。
|
||||
* 不加 @PreAuthorize:登录即可访问,只返回 id/账号/姓名/部门等展示字段,
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.bms.system.orgsync;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.bms.common.annotation.DataSource;
|
||||
import com.bms.common.enums.DataSourceType;
|
||||
import com.bms.system.orgsync.mapper.OracleOrgSyncMapper;
|
||||
|
||||
/**
|
||||
* Oracle 组织/用户/角色读取器。
|
||||
* 走 SLAVE(Oracle 只读账号)数据源;必须独立 Bean,
|
||||
* 否则 @DataSource 切面在同类自调用时不生效。
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@Service
|
||||
public class OracleOrgReader
|
||||
{
|
||||
@Autowired
|
||||
private OracleOrgSyncMapper oracleOrgSyncMapper;
|
||||
|
||||
@DataSource(DataSourceType.SLAVE)
|
||||
public List<Map<String, Object>> readAllDept()
|
||||
{
|
||||
try
|
||||
{
|
||||
PageHelper.clearPage();
|
||||
return oracleOrgSyncMapper.selectAllTabDept();
|
||||
}
|
||||
finally
|
||||
{
|
||||
PageHelper.clearPage();
|
||||
}
|
||||
}
|
||||
|
||||
@DataSource(DataSourceType.SLAVE)
|
||||
public List<Map<String, Object>> readAllEmployee()
|
||||
{
|
||||
try
|
||||
{
|
||||
PageHelper.clearPage();
|
||||
return oracleOrgSyncMapper.selectAllTabEmployee();
|
||||
}
|
||||
finally
|
||||
{
|
||||
PageHelper.clearPage();
|
||||
}
|
||||
}
|
||||
|
||||
@DataSource(DataSourceType.SLAVE)
|
||||
public List<Map<String, Object>> readAllRole()
|
||||
{
|
||||
try
|
||||
{
|
||||
PageHelper.clearPage();
|
||||
return oracleOrgSyncMapper.selectAllSysRole();
|
||||
}
|
||||
finally
|
||||
{
|
||||
PageHelper.clearPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,350 @@
|
||||
package com.bms.system.orgsync;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.bms.common.core.domain.entity.SysDept;
|
||||
import com.bms.common.core.domain.entity.SysRole;
|
||||
import com.bms.common.core.domain.entity.SysUser;
|
||||
|
||||
/**
|
||||
* 老系统组织架构(Oracle)-> BMS(MySQL)覆盖式迁移。
|
||||
*
|
||||
* 部门:TAB_DEPT 11 个部门统一挂到根节点“威狮国际”(dept_id=200)下,子部门 201 起顺序编号;
|
||||
* 角色:T_SYS_ROLE 有效内部角色原样迁入,role_id 沿用 Oracle ID,不带菜单权限;
|
||||
* 用户:TAB_EMPLOYEE 全量迁入,EMPLOYEE_CODE 作登录账号;user_id 取 Oracle USER_ID,
|
||||
* USER_ID 为空时取 EMP_ID;默认密码 123456;不分配角色。
|
||||
* 内置超级管理员 admin(user_id=1)/超级管理员角色(role_id=1)保留,仅将 admin 调到根部门。
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@Service
|
||||
public class OrgSyncService
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(OrgSyncService.class);
|
||||
|
||||
/** 根部门 ID(威狮国际) */
|
||||
public static final long ROOT_DEPT_ID = 200L;
|
||||
private static final long FIRST_CHILD_DEPT_ID = 201L;
|
||||
private static final String ROOT_DEPT_NAME = "威狮国际";
|
||||
|
||||
/** 写库人标记 */
|
||||
public static final String SYNC_MARKER = "oracle-sync";
|
||||
|
||||
/** 新用户默认密码(BCrypt,明文 123456) */
|
||||
private static final String DEFAULT_PASSWORD =
|
||||
"$2a$10$gAOzrNJaYLM2m85.9ykkLO0IPvQktxqee8RVpAu1e3.J0Ujiv4Z0G";
|
||||
|
||||
/** 老系统内置 admin 账号不迁移,避免覆盖 BMS 超级管理员 */
|
||||
private static final String BUILTIN_ADMIN = "admin";
|
||||
|
||||
@Autowired
|
||||
private OracleOrgReader oracleOrgReader;
|
||||
|
||||
@Autowired
|
||||
private OrgSyncWriter orgSyncWriter;
|
||||
|
||||
/**
|
||||
* 执行一次全量迁移
|
||||
*/
|
||||
public Map<String, Object> syncFromOracle()
|
||||
{
|
||||
long t0 = System.currentTimeMillis();
|
||||
|
||||
List<Map<String, Object>> deptRows = oracleOrgReader.readAllDept();
|
||||
List<Map<String, Object>> roleRows = oracleOrgReader.readAllRole();
|
||||
List<Map<String, Object>> empRows = oracleOrgReader.readAllEmployee();
|
||||
|
||||
// ---- 部门 ----
|
||||
List<SysDept> depts = buildDepts(deptRows);
|
||||
Map<String, Long> deptIdByCode = new HashMap<>();
|
||||
for (SysDept d : depts)
|
||||
{
|
||||
if (d.getParentId() == ROOT_DEPT_ID)
|
||||
{
|
||||
deptIdByCode.put(d.getDeptName(), d.getDeptId());
|
||||
}
|
||||
}
|
||||
|
||||
// ---- 角色 ----
|
||||
List<SysRole> roles = buildRoles(roleRows);
|
||||
|
||||
// ---- 用户 ----
|
||||
List<SysUser> users = buildUsers(empRows, deptIdByCode);
|
||||
|
||||
orgSyncWriter.writeAll(depts, roles, users, ROOT_DEPT_ID);
|
||||
|
||||
long disabled = users.stream().filter(u -> "1".equals(u.getStatus())).count();
|
||||
long cost = System.currentTimeMillis() - t0;
|
||||
String summary = String.format(
|
||||
"老系统组织同步完成:部门 %d 个(含根节点“%s”),角色 %d 个(不含权限),用户 %d 个(启用 %d/停用 %d,默认密码 123456),耗时 %dms",
|
||||
depts.size(), ROOT_DEPT_NAME, roles.size(), users.size(), users.size() - disabled, disabled, cost);
|
||||
log.info(summary);
|
||||
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("deptCount", depts.size());
|
||||
result.put("roleCount", roles.size());
|
||||
result.put("userCount", users.size());
|
||||
result.put("enabledUserCount", users.size() - disabled);
|
||||
result.put("disabledUserCount", disabled);
|
||||
result.put("costMs", cost);
|
||||
result.put("summary", summary);
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<SysDept> buildDepts(List<Map<String, Object>> rows)
|
||||
{
|
||||
List<SysDept> list = new ArrayList<>();
|
||||
SysDept root = newDept(ROOT_DEPT_ID, 0L, "0", ROOT_DEPT_NAME, 0);
|
||||
list.add(root);
|
||||
long id = FIRST_CHILD_DEPT_ID;
|
||||
int order = 1;
|
||||
Set<String> seen = new HashSet<>();
|
||||
for (Map<String, Object> row : rows)
|
||||
{
|
||||
String code = clean(str(row, "DEPT_CODE"));
|
||||
String name = clean(str(row, "DEPT_NAME"));
|
||||
String deptName = name != null ? name : code;
|
||||
if (code == null || !seen.add(code))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
list.add(newDept(id++, ROOT_DEPT_ID, "0," + ROOT_DEPT_ID, deptName, order++));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private SysDept newDept(long id, long parentId, String ancestors, String name, int order)
|
||||
{
|
||||
SysDept d = new SysDept();
|
||||
d.setDeptId(id);
|
||||
d.setParentId(parentId);
|
||||
d.setAncestors(ancestors);
|
||||
d.setDeptName(name);
|
||||
d.setOrderNum(order);
|
||||
d.setStatus("0");
|
||||
d.setDelFlag("0");
|
||||
d.setCreateBy(SYNC_MARKER);
|
||||
d.setCreateTime(new Date());
|
||||
return d;
|
||||
}
|
||||
|
||||
private List<SysRole> buildRoles(List<Map<String, Object>> rows)
|
||||
{
|
||||
List<SysRole> list = new ArrayList<>();
|
||||
Set<Long> seenIds = new HashSet<>();
|
||||
int sort = 1;
|
||||
for (Map<String, Object> row : rows)
|
||||
{
|
||||
Long rid = lng(row, "ID");
|
||||
String name = clean(str(row, "ROLE_NAME"));
|
||||
if (rid == null || name == null || !seenIds.add(rid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
SysRole r = new SysRole();
|
||||
r.setRoleId(rid);
|
||||
r.setRoleName(truncate(name, 30));
|
||||
r.setRoleKey("ORA_" + rid);
|
||||
r.setRoleSort(sort++);
|
||||
r.setDataScope("1");
|
||||
r.setMenuCheckStrictly(true);
|
||||
r.setDeptCheckStrictly(true);
|
||||
r.setStatus("0");
|
||||
r.setDelFlag("0");
|
||||
r.setCreateBy(SYNC_MARKER);
|
||||
r.setCreateTime(new Date());
|
||||
r.setRemark(truncate(clean(str(row, "ROLE_DESC")), 500));
|
||||
list.add(r);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<SysUser> buildUsers(List<Map<String, Object>> rows, Map<String, Long> deptIdByCode)
|
||||
{
|
||||
List<SysUser> list = new ArrayList<>();
|
||||
Set<Long> seenIds = new HashSet<>();
|
||||
Set<String> seenNames = new HashSet<>();
|
||||
int skipped = 0;
|
||||
for (Map<String, Object> row : rows)
|
||||
{
|
||||
String code = clean(str(row, "EMPLOYEE_CODE"));
|
||||
String name = clean(str(row, "EMPLOYEE_NAME"));
|
||||
if (code == null || name == null)
|
||||
{
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
if (BUILTIN_ADMIN.equalsIgnoreCase(code))
|
||||
{
|
||||
// 保留 BMS 内置超级管理员,不被老系统 admin 覆盖
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
// ID:优先 USER_ID,为空取 EMP_ID
|
||||
Long uid = lng(row, "USER_ID");
|
||||
if (uid == null)
|
||||
{
|
||||
uid = lng(row, "EMP_ID");
|
||||
}
|
||||
if (uid == null || !seenIds.add(uid) || !seenNames.add(code))
|
||||
{
|
||||
log.warn("用户同步跳过:{}({}),ID 缺失或重复", code, name);
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
SysUser u = new SysUser();
|
||||
u.setUserId(uid);
|
||||
String deptCode = clean(str(row, "DEPT_CODE"));
|
||||
Long deptId = deptCode == null ? null : deptIdByCode.get(deptCode);
|
||||
u.setDeptId(deptId != null ? deptId : ROOT_DEPT_ID);
|
||||
u.setUserName(code);
|
||||
u.setNickName(truncate(name, 30));
|
||||
u.setPassword(DEFAULT_PASSWORD);
|
||||
u.setStatus("1".equals(clean(str(row, "BL_OPEN"))) ? "0" : "1");
|
||||
u.setSex(mapSex(clean(str(row, "SEX"))));
|
||||
u.setEmail(cleanEmail(str(row, "EMAIL")));
|
||||
u.setPhonenumber(cleanPhone(str(row, "MOBILE_PHONE")));
|
||||
u.setRemark(truncate(clean(str(row, "REMARK")), 500));
|
||||
Object createDate = row.get("CREATE_DATE");
|
||||
if (createDate instanceof Date)
|
||||
{
|
||||
u.setCreateTime((Date) createDate);
|
||||
}
|
||||
else
|
||||
{
|
||||
u.setCreateTime(new Date());
|
||||
}
|
||||
u.setCreateBy(SYNC_MARKER);
|
||||
list.add(u);
|
||||
}
|
||||
if (skipped > 0)
|
||||
{
|
||||
log.warn("用户同步共跳过 {} 条(内置 admin / 编码或ID重复 / 关键字段为空)", skipped);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/** Oracle:1男 0女;BMS:0男 1女 2未知 */
|
||||
private static String mapSex(String sex)
|
||||
{
|
||||
if ("1".equals(sex))
|
||||
{
|
||||
return "0";
|
||||
}
|
||||
if ("0".equals(sex))
|
||||
{
|
||||
return "1";
|
||||
}
|
||||
return "2";
|
||||
}
|
||||
|
||||
/** 老系统手机号存在加密脏值,仅接收纯号码/短横线/加号格式且不超过 11 位 */
|
||||
private static String cleanPhone(String v)
|
||||
{
|
||||
String s = clean(v);
|
||||
if (s == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
s = s.replace(" ", "");
|
||||
if (s.length() > 11 || !s.matches("[0-9+\\-]{6,11}"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
private static String cleanEmail(String v)
|
||||
{
|
||||
String s = clean(v);
|
||||
if (s == null || s.length() > 50 || !s.contains("@"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
private static String truncate(String v, int max)
|
||||
{
|
||||
if (v == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return v.length() > max ? v.substring(0, max) : v;
|
||||
}
|
||||
|
||||
private static String clean(String v)
|
||||
{
|
||||
if (v == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String s = v.trim();
|
||||
return s.isEmpty() ? null : s;
|
||||
}
|
||||
|
||||
private static String str(Map<String, Object> row, String key)
|
||||
{
|
||||
Object v = getIgnoreCase(row, key);
|
||||
return v == null ? null : String.valueOf(v);
|
||||
}
|
||||
|
||||
/** Oracle NUMBER 经 JDBC 多为 BigDecimal */
|
||||
private static Long lng(Map<String, Object> row, String key)
|
||||
{
|
||||
Object v = getIgnoreCase(row, key);
|
||||
if (v == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (v instanceof Number)
|
||||
{
|
||||
return ((Number) v).longValue();
|
||||
}
|
||||
String s = String.valueOf(v).trim();
|
||||
if (s.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
int dot = s.indexOf('.');
|
||||
if (dot >= 0)
|
||||
{
|
||||
s = s.substring(0, dot);
|
||||
}
|
||||
try
|
||||
{
|
||||
return Long.parseLong(s);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Object getIgnoreCase(Map<String, Object> row, String key)
|
||||
{
|
||||
if (row.containsKey(key))
|
||||
{
|
||||
return row.get(key);
|
||||
}
|
||||
for (Map.Entry<String, Object> e : row.entrySet())
|
||||
{
|
||||
if (e.getKey() != null && e.getKey().equalsIgnoreCase(key))
|
||||
{
|
||||
return e.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.bms.system.orgsync;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import com.bms.common.core.domain.entity.SysDept;
|
||||
import com.bms.common.core.domain.entity.SysRole;
|
||||
import com.bms.common.core.domain.entity.SysUser;
|
||||
import com.bms.system.orgsync.mapper.SysOrgSyncWriterMapper;
|
||||
|
||||
/**
|
||||
* 组织迁移写库。独立 Bean:保证 @Transactional 经代理生效,且与 SLAVE 读连接隔离。
|
||||
* 单个事务内覆盖式重建:除内置超级管理员(user_id=1 / role_id=1)外全部替换。
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
@Service
|
||||
public class OrgSyncWriter
|
||||
{
|
||||
/** 用户批量插入每批条数 */
|
||||
private static final int USER_BATCH = 200;
|
||||
|
||||
@Autowired
|
||||
private SysOrgSyncWriterMapper writerMapper;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void writeAll(List<SysDept> depts, List<SysRole> roles, List<SysUser> users, Long adminDeptId)
|
||||
{
|
||||
// 1. 清关联(保留 admin <-> 超级管理员角色)
|
||||
writerMapper.deleteAllRoleDept();
|
||||
writerMapper.deleteRoleMenuKeepAdmin();
|
||||
writerMapper.deleteUserRoleKeepAdmin();
|
||||
writerMapper.deleteUserPostKeepAdmin();
|
||||
|
||||
// 2. 清用户/角色/部门
|
||||
writerMapper.deleteUsersKeepAdmin();
|
||||
writerMapper.deleteRolesKeepAdmin();
|
||||
writerMapper.deleteAllDept();
|
||||
|
||||
// 3. 重建部门
|
||||
for (SysDept d : depts)
|
||||
{
|
||||
writerMapper.insertDept(d);
|
||||
}
|
||||
|
||||
// 4. 重建角色(不带任何菜单权限)
|
||||
for (SysRole r : roles)
|
||||
{
|
||||
writerMapper.insertRole(r);
|
||||
}
|
||||
|
||||
// 5. 重建用户(分批,避免单条 SQL 过长)
|
||||
for (int i = 0; i < users.size(); i += USER_BATCH)
|
||||
{
|
||||
writerMapper.batchInsertUser(users.subList(i, Math.min(i + USER_BATCH, users.size())));
|
||||
}
|
||||
|
||||
// 6. 超级管理员挂到根部门
|
||||
writerMapper.updateUserDept(1L, adminDeptId);
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.bms.system.orgsync.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 老系统 Oracle 组织/用户/角色只读查询(SLAVE 数据源,账号只读)
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
public interface OracleOrgSyncMapper
|
||||
{
|
||||
/** TAB_DEPT 全部部门(扁平结构,DEPT_CODE=DEPT_NAME) */
|
||||
List<Map<String, Object>> selectAllTabDept();
|
||||
|
||||
/** TAB_EMPLOYEE 全部员工 */
|
||||
List<Map<String, Object>> selectAllTabEmployee();
|
||||
|
||||
/** T_SYS_ROLE 有效角色(REC_FLAG=1,内部角色 ROLE_TYPE=100) */
|
||||
List<Map<String, Object>> selectAllSysRole();
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package com.bms.system.orgsync.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.bms.common.core.domain.entity.SysDept;
|
||||
import com.bms.common.core.domain.entity.SysRole;
|
||||
import com.bms.common.core.domain.entity.SysUser;
|
||||
|
||||
/**
|
||||
* 组织架构老系统数据迁移写库(MASTER 数据源)。
|
||||
* 覆盖式迁移:除内置超级管理员(user_id=1 / role_id=1)外,
|
||||
* 现有演示部门、角色、用户全部清空后按 Oracle 数据重建。
|
||||
*
|
||||
* @author bms
|
||||
*/
|
||||
public interface SysOrgSyncWriterMapper
|
||||
{
|
||||
/** 清空角色-部门(自定义数据范围)关联 */
|
||||
int deleteAllRoleDept();
|
||||
|
||||
/** 清空全部部门 */
|
||||
int deleteAllDept();
|
||||
|
||||
/** 新增部门 */
|
||||
int insertDept(SysDept dept);
|
||||
|
||||
/** 清空除超级管理员角色(role_id=1)以外角色的菜单、用户关联 */
|
||||
int deleteRoleMenuKeepAdmin();
|
||||
int deleteUserRoleKeepAdmin();
|
||||
|
||||
/** 删除除超级管理员角色外的全部角色 */
|
||||
int deleteRolesKeepAdmin();
|
||||
|
||||
/** 新增角色 */
|
||||
int insertRole(SysRole role);
|
||||
|
||||
/** 删除除超级管理员(user_id=1)以外用户的岗位关联与用户 */
|
||||
int deleteUserPostKeepAdmin();
|
||||
int deleteUsersKeepAdmin();
|
||||
|
||||
/** 新增用户(批量) */
|
||||
int batchInsertUser(@Param("list") List<SysUser> list);
|
||||
|
||||
/** 将指定用户挂到根部门 */
|
||||
int updateUserDept(@Param("userId") Long userId, @Param("deptId") Long deptId);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.bms.system.orgsync.mapper.OracleOrgSyncMapper">
|
||||
|
||||
<!-- TAB_DEPT:老系统部门,扁平表,仅 11 个部门;迁移时统一挂到“威狮国际”根节点下 -->
|
||||
<select id="selectAllTabDept" resultType="java.util.HashMap" fetchSize="500">
|
||||
SELECT DEPT_CODE, DEPT_NAME
|
||||
FROM WEISHI_USER.TAB_DEPT
|
||||
ORDER BY DEPT_CODE
|
||||
</select>
|
||||
|
||||
<!-- TAB_EMPLOYEE:员工;EMPLOYEE_CODE 作为登录账号,USER_ID 为空时用 EMP_ID 作为新库用户ID -->
|
||||
<select id="selectAllTabEmployee" resultType="java.util.HashMap" fetchSize="500">
|
||||
SELECT EMPLOYEE_CODE, EMPLOYEE_NAME, DEPT_CODE, PHONE, MOBILE_PHONE,
|
||||
SEX, BL_OPEN, EMAIL, REMARK, CREATE_DATE, USER_ID, EMP_ID
|
||||
FROM WEISHI_USER.TAB_EMPLOYEE
|
||||
ORDER BY EMPLOYEE_CODE
|
||||
</select>
|
||||
|
||||
<!-- T_SYS_ROLE:只迁有效内部角色;角色菜单权限(sys_role_menu)不迁移 -->
|
||||
<select id="selectAllSysRole" resultType="java.util.HashMap" fetchSize="500">
|
||||
SELECT ID, ROLE_NAME, ROLE_DESC
|
||||
FROM WEISHI_USER.T_SYS_ROLE
|
||||
WHERE REC_FLAG = 1 AND ROLE_TYPE = '100'
|
||||
ORDER BY ID
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.bms.system.orgsync.mapper.SysOrgSyncWriterMapper">
|
||||
|
||||
<delete id="deleteAllRoleDept">
|
||||
delete from sys_role_dept
|
||||
</delete>
|
||||
|
||||
<delete id="deleteAllDept">
|
||||
delete from sys_dept
|
||||
</delete>
|
||||
|
||||
<insert id="insertDept" parameterType="com.bms.common.core.domain.entity.SysDept">
|
||||
insert into sys_dept(dept_id, parent_id, ancestors, dept_name, order_num, leader, phone, email,
|
||||
status, del_flag, create_by, create_time)
|
||||
values(#{deptId}, #{parentId}, #{ancestors}, #{deptName}, #{orderNum}, #{leader}, #{phone}, #{email},
|
||||
#{status}, '0', #{createBy}, sysdate())
|
||||
</insert>
|
||||
|
||||
<delete id="deleteRoleMenuKeepAdmin">
|
||||
delete from sys_role_menu where role_id <> 1
|
||||
</delete>
|
||||
|
||||
<delete id="deleteUserRoleKeepAdmin">
|
||||
delete from sys_user_role where role_id <> 1
|
||||
</delete>
|
||||
|
||||
<delete id="deleteRolesKeepAdmin">
|
||||
delete from sys_role where role_id <> 1
|
||||
</delete>
|
||||
|
||||
<insert id="insertRole" parameterType="com.bms.common.core.domain.entity.SysRole">
|
||||
insert into sys_role(role_id, role_name, role_key, role_sort, data_scope,
|
||||
menu_check_strictly, dept_check_strictly, status, del_flag,
|
||||
create_by, create_time, remark)
|
||||
values(#{roleId}, #{roleName}, #{roleKey}, #{roleSort}, #{dataScope},
|
||||
1, 1, '0', '0', #{createBy}, sysdate(), #{remark})
|
||||
</insert>
|
||||
|
||||
<delete id="deleteUserPostKeepAdmin">
|
||||
delete from sys_user_post where user_id <> 1
|
||||
</delete>
|
||||
|
||||
<delete id="deleteUsersKeepAdmin">
|
||||
delete from sys_user where user_id <> 1
|
||||
</delete>
|
||||
|
||||
<insert id="batchInsertUser" parameterType="java.util.List">
|
||||
insert into sys_user(user_id, dept_id, user_name, nick_name, user_type, email, phonenumber, sex,
|
||||
password, status, del_flag, create_by, create_time, remark)
|
||||
values
|
||||
<foreach collection="list" item="u" separator=",">
|
||||
(#{u.userId}, #{u.deptId}, #{u.userName}, #{u.nickName}, '00', #{u.email}, #{u.phonenumber},
|
||||
#{u.sex}, #{u.password}, #{u.status}, '0', #{u.createBy},
|
||||
<choose><when test="u.createTime != null">#{u.createTime}</when><otherwise>sysdate()</otherwise></choose>,
|
||||
#{u.remark})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<update id="updateUserDept">
|
||||
update sys_user set dept_id = #{deptId} where user_id = #{userId}
|
||||
</update>
|
||||
</mapper>
|
||||
@@ -35,6 +35,15 @@ export function addUser(data) {
|
||||
})
|
||||
}
|
||||
|
||||
// 从老系统(Oracle)同步部门/角色/用户(覆盖式迁移)
|
||||
export function syncUsersFromOracle() {
|
||||
return request({
|
||||
url: '/system/user/syncFromOracle',
|
||||
method: 'post',
|
||||
timeout: 120000
|
||||
})
|
||||
}
|
||||
|
||||
// 修改用户
|
||||
export function updateUser(data) {
|
||||
return request({
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:user:export']">导出</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Refresh" :loading="syncLoading" @click="handleSyncFromOracle" v-hasPermi="['system:user:add']">TMS系统同步用户数据</el-button>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<template #col-userName="{ row }">
|
||||
@@ -160,7 +163,7 @@ import TreePanel from "@/components/TreePanel"
|
||||
import ExcelImportDialog from "@/components/ExcelImportDialog"
|
||||
import UserViewDrawer from "./view"
|
||||
import { usePasswordRule } from "@/utils/passwordRule"
|
||||
import { changeUserStatus, listUser, resetUserPwd, delUser, getUser, updateUser, addUser, deptTreeSelect } from "@/api/system/user"
|
||||
import { changeUserStatus, listUser, resetUserPwd, delUser, getUser, updateUser, addUser, deptTreeSelect, syncUsersFromOracle } from "@/api/system/user"
|
||||
import { nextTick } from "vue"
|
||||
|
||||
const router = useRouter()
|
||||
@@ -169,6 +172,7 @@ const { pwdValidator, pwdPromptValidator } = usePasswordRule()
|
||||
const { sys_normal_disable, sys_user_sex } = useDict("sys_normal_disable", "sys_user_sex")
|
||||
|
||||
const tableRef = ref()
|
||||
const syncLoading = ref(false)
|
||||
const open = ref(false)
|
||||
const title = ref("")
|
||||
const deptId = ref(undefined)
|
||||
@@ -257,6 +261,22 @@ function handleDelete(userIds) {
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
/** 从老系统(Oracle)同步部门/角色/用户 */
|
||||
function handleSyncFromOracle() {
|
||||
proxy.$modal.confirm(
|
||||
'将从老系统同步部门(威狮国际及其下级部门)、角色、用户数据。注意:同步为覆盖式迁移,除超级管理员外,系统现有部门、角色、用户将被老系统数据替换(角色权限需另行配置,新用户默认密码 123456)。是否继续?'
|
||||
).then(() => {
|
||||
syncLoading.value = true
|
||||
return syncUsersFromOracle()
|
||||
}).then(res => {
|
||||
proxy.$modal.msgSuccess(res.msg || '同步成功')
|
||||
getDeptTree()
|
||||
tableRef.value.refresh()
|
||||
}).catch(() => {}).finally(() => {
|
||||
syncLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
function handleExport() {
|
||||
proxy.download("system/user/export", {
|
||||
|
||||
Reference in New Issue
Block a user