瀏覽代碼

Merge remote-tracking branch 'origin/master'

yurk 2 年之前
父節點
當前提交
775defc749
共有 16 個文件被更改,包括 629 次插入126 次删除
  1. 7 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Department.java
  2. 19 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/TempDuser.java
  3. 1 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/DepartmentVO.java
  4. 3 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/DepartmentMapper.java
  5. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DepartmentServiceImpl.java
  6. 203 108
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DingDingServiceImpl.java
  7. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/DepartmentMapper.xml
  8. 5 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TempDuserMapper.xml
  9. 258 5
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/demo_index.html
  10. 47 3
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.css
  11. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.js
  12. 77 0
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.json
  13. 二進制
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.ttf
  14. 二進制
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.woff
  15. 二進制
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.woff2
  16. 4 4
      fhKeeper/formulahousekeeper/timesheet/src/views/team/index.vue

+ 7 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Department.java

@@ -16,7 +16,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2022-07-14
+ * @since 2023-01-17
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -75,6 +75,12 @@ public class Department extends Model<Department> {
     @TableField("corpwx_deptpid")
     private Integer corpwxDeptpid;
 
+    /**
+     * 钉钉的部门id
+     */
+    @TableField("dd_deptid")
+    private Integer ddDeptid;
+
 
     @Override
     protected Serializable pkVal() {

+ 19 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/TempDuser.java

@@ -15,7 +15,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2022-05-31
+ * @since 2023-01-17
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -33,6 +33,24 @@ public class TempDuser extends Model<TempDuser> {
     @TableField("name")
     private String name;
 
+    /**
+     * 钉钉的部门id
+     */
+    @TableField("dd_deptid")
+    private Integer ddDeptid;
+
+    @TableField("corpid")
+    private String corpid;
+
+    @TableField("dingding_unionid")
+    private String dingdingUnionid;
+
+    /**
+     * 工号
+     */
+    @TableField("job_number")
+    private String jobNumber;
+
 
     @Override
     protected Serializable pkVal() {

+ 1 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/DepartmentVO.java

@@ -20,4 +20,5 @@ public class DepartmentVO {
     private List<DepartmentVO> children;
     private List<HashMap> userList;
     private List<String> otherManagerIds;
+    private Integer ddDeptid;
 }

+ 3 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/DepartmentMapper.java

@@ -28,4 +28,7 @@ public interface DepartmentMapper extends BaseMapper<Department> {
     void updateNullLeader(Integer departmentId);
 
     List<Map<String, Object>> getDeptCustomDataStatistic(String startDate, String endDate, List departmentIds, Integer companyId);
+
+    @Update("update department set superior_id = null where department_id = #{departmentId}")
+    void updateNullSuperior(Integer departmentId);
 }

+ 2 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DepartmentServiceImpl.java

@@ -435,7 +435,8 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
                 .setLabel(department.getDepartmentName())
                 .setParentId(department.getSuperiorId())
                 .setOtherManagerIds(collect)
-                .setReportAuditUserid(department.getReportAuditUserid());
+                .setReportAuditUserid(department.getReportAuditUserid())
+                .setDdDeptid(department.getDdDeptid());
     }
 
     //获取某个项目下的统计

+ 203 - 108
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DingDingServiceImpl.java

@@ -30,6 +30,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
+import java.math.BigInteger;
 import java.math.RoundingMode;
 import java.text.DecimalFormat;
 import java.text.SimpleDateFormat;
@@ -59,6 +60,8 @@ public class DingDingServiceImpl implements DingDingService {
 
     @Resource
     TempDuserMapper tempDuserMapper;
+    @Resource
+    TempDuserService tempDuserService;
 
     public static String PRE_AUTH_CODE = null;
     public static long expireTime = 0L;
@@ -603,25 +606,35 @@ public class DingDingServiceImpl implements DingDingService {
             System.out.println("获取通讯录授权范围:"+rsp.getBody());
             JSONObject json = JSONObject.parseObject(rsp.getBody());
             if (json.getInteger("errcode") == 0) {
+                //删除临时库中的人员
+                tempDuserMapper.delete(new QueryWrapper<TempDuser>().eq("corpid", dingding.getCorpid()));
+                List<TempDuser> addTempUserList = new ArrayList<>();
                 JSONArray deptArray = json.getJSONObject("auth_org_scopes").getJSONArray("authed_dept");
                 //如果授权的是全部公司部门,则递归获取子部门和人员
                 if (deptArray.size() == 1 && deptArray.getLong(0) == 1L) {
-                    getDepartmentList(roleId, roleName, dingding.getCompanyId(), dingding.getCorpid(), accessToken, 1L, null);
+                    getDepartmentList(roleId, roleName, dingding.getCompanyId(), dingding.getCorpid(), accessToken, 1L, addTempUserList);
                 } else {
                     for (int i=0;i<deptArray.size(); i++) {
                         long deptId = deptArray.getLongValue(i);
-                        getDepartmentDetailAndUserList(roleId, roleName, dingding.getCompanyId(), dingding.getCorpid(), accessToken, deptId);
+                        getDepartmentDetailAndUserList(roleId, roleName, dingding.getCompanyId(), dingding.getCorpid(), accessToken, deptId, addTempUserList);
                     }
                 }
 
-
                 //直接授权的人员,没有部门
                 JSONArray userArray = json.getJSONObject("auth_org_scopes").getJSONArray("authed_user");
                 for (int i=0;i<userArray.size(); i++) {
                     String userdingId = userArray.getString(i);
                     //获取人员详情
-                    getUserDetail(roleId, roleName, dingding.getCompanyId(), 0, userdingId, accessToken);
+                    getUserDetail(dingding.getCorpid(), userdingId, accessToken, addTempUserList);
                 }
+                //存储到临时表
+                if (addTempUserList.size() > 0) {
+                    tempDuserService.saveBatch(addTempUserList);
+                }
+                //同步部门数据
+                adjustDepartment(dingding);
+                //从temp表调整人员到user表
+                adjustUserFromTemp(dingding);
             } else {
                 System.err.println("获取通讯录范围出错:" + json.toJSONString());
             }
@@ -630,6 +643,138 @@ public class DingDingServiceImpl implements DingDingService {
         }
     }
 
+    //调整系统的部门表,与department_dingding同步
+    private void adjustDepartment(CompanyDingding dingding) {
+        //钉钉有的,系统没有的,要新增
+        List<Department> allDeptList = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id", dingding.getCompanyId()));
+        List<DepartmentDingding> dingdingDeptList = departmentDingdingMapper.selectList(new QueryWrapper<DepartmentDingding>().eq("corpid", dingding.getCorpid()));
+        List<Department> newDeptList = new ArrayList<>();
+        for (DepartmentDingding departmentDingding : dingdingDeptList) {
+            Optional<Department> first = allDeptList.stream().filter(old -> old.getDdDeptid() != null && old.getDdDeptid().equals(departmentDingding.getDdDeptid())).findFirst();
+            if (!first.isPresent()) {
+                //无匹配的,新增
+                Department newDept = new Department();
+                newDept.setDdDeptid(departmentDingding.getDdDeptid());
+                newDept.setDepartmentName(departmentDingding.getName());
+                newDept.setCompanyId(dingding.getCompanyId());
+                newDeptList.add(newDept);
+            }
+        }
+        if (newDeptList.size() > 0) {
+            departmentService.saveBatch(newDeptList);
+            System.out.println("批量保存后, departmentId=" +newDeptList.get(0).getDepartmentId());
+            //重新查一遍,这次没有新的部门了
+            int beforeSize = allDeptList.size();
+            allDeptList.addAll(newDeptList);
+            int afterSize = allDeptList.size();
+            System.out.println("变更部门前后:"+beforeSize+"--"+afterSize);
+        }
+
+        //调整部门的层级关系
+        List<Department> changeList = new ArrayList<>();
+        for (Department dept : allDeptList) {
+            if (dept.getDdDeptid() != null) {
+                Optional<DepartmentDingding> first = dingdingDeptList.stream().filter(ddpt -> ddpt.getDdDeptid().equals(dept.getDdDeptid())).findFirst();
+                if (first.isPresent()) {
+                    boolean changed = false;
+                    DepartmentDingding departmentDingding = first.get();
+                    if (departmentDingding.getDdParentid() == 1) {
+                        //在根部门
+                        if (dept.getSuperiorId() != null) {
+                            //强制设置为null
+                            departmentMapper.updateNullSuperior(dept.getDepartmentId());
+                        }
+                    } else {
+                        Optional<Department> parentDept = allDeptList.stream().filter(ex -> ex.getDdDeptid() != null && ex.getDdDeptid().equals(departmentDingding.getDdParentid())).findFirst();
+                        if (parentDept.isPresent()) {
+                            Integer parentDeptId = parentDept.get().getDepartmentId();
+                            //父部门发生变化
+                            if (!parentDeptId.equals(dept.getSuperiorId())) {
+                                dept.setSuperiorId(parentDeptId);
+                                changed = true;
+                            }
+                        }
+                    }
+
+                    if (!departmentDingding.getName().equals(dept.getDepartmentName())) {
+                        dept.setDepartmentName(departmentDingding.getName());
+                        changed = true;
+                    }
+                    if (changed) {
+                        changeList.add(dept);
+                    }
+                }
+            }
+        }
+        if (changeList.size() > 0) {
+            departmentService.updateBatchById(changeList);
+        }
+    }
+
+    private void adjustUserFromTemp(CompanyDingding dingding) {
+        SysRole defaultRole = null;
+        List<SysRole> droleList = sysRoleMapper.selectList(new QueryWrapper<SysRole>().eq("company_id", dingding.getCompanyId()).eq("is_default", 1));
+        if (droleList.size() > 0) {
+            defaultRole = droleList.get(0);
+        }
+        List<TempDuser> tempDuserList = tempDuserMapper.selectList(new QueryWrapper<TempDuser>().eq("corpid", dingding.getCorpid()));
+        List<User> oldUserList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", dingding.getCompanyId()));
+        List<User> newUserList = new ArrayList<>();
+        List<User> updateUserList = new ArrayList<>();
+        List<Department> allDeptList = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id", dingding.getCompanyId()));
+        for (TempDuser duser : tempDuserList) {
+            Optional<User> findUser = oldUserList.stream().filter(user -> user.getDingdingUserid().equals(duser.getDingdingUserid())).findFirst();
+            if (!findUser.isPresent()) {
+                //不存在的新用户
+                User user = new User();
+                user.setId(SnowFlake.nextId()+"")
+                        .setRoleId(defaultRole.getId())
+                        .setRoleName(defaultRole.getRolename())
+                        .setCompanyId(dingding.getCompanyId())
+                        .setName(duser.getName())
+                        .setDingdingUserid(duser.getDingdingUserid())
+                        .setDingdingUnionid(duser.getDingdingUnionid())
+                        .setJobNumber(duser.getJobNumber())
+                        .setColor(ColorUtil.randomColor());
+                //设置部门
+                Optional<Department> first = allDeptList.stream().filter(item -> item.getDdDeptid() != null && item.getDdDeptid().equals(duser.getDdDeptid())).findFirst();
+                if (first.isPresent()) {
+                    Department department = first.get();
+                    user.setDepartmentId(department.getDepartmentId());
+                    user.setDepartmentCascade(convertDepartmentIdToCascade(department.getDepartmentId()));
+                    newUserList.add(user);
+                }
+            } else {
+                //已存在,对比是否需要更新
+                //可能需要更新姓名
+                User oldUser = findUser.get();
+                User upUser = new User();
+                upUser.setId(oldUser.getId());
+                boolean changed = false;
+                if (oldUser.getName() == null || !oldUser.getName().equals(duser.getName())) {
+                    upUser.setName(duser.getName());
+                    System.out.println("更新用户姓名==" + oldUser.getName());
+                    changed = true;
+                }
+                //可能需要更新工号
+                if (!StringUtils.isEmpty(duser.getJobNumber()) && (oldUser.getJobNumber() == null || !oldUser.getJobNumber().equals(duser.getJobNumber()))) {
+                    upUser.setJobNumber(duser.getJobNumber());
+                    changed = true;
+                }
+                if (changed) {
+                    updateUserList.add(oldUser);
+                }
+                //TODO: 所属部门的变更,需要用户自行确认
+            }
+        }
+        if (newUserList.size() > 0) {
+            userService.saveBatch(newUserList);
+        }
+        if (updateUserList.size() > 0) {
+            userService.updateBatchById(updateUserList);
+        }
+    }
+
 //    private void getUserDetailInfo(User user, String accessToken) throws ApiException {
 //        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
 //        OapiV2UserGetRequest req = new OapiV2UserGetRequest();
@@ -1143,13 +1288,13 @@ public class DingDingServiceImpl implements DingDingService {
     }
 
     //获取部门详情和部门下的人员
-    public void getDepartmentDetailAndUserList(int roleId, String roleName, Integer companyId, String corpid, String accessToken, long deptId) {
+    public void getDepartmentDetailAndUserList(int roleId, String roleName, Integer companyId, String corpid, String accessToken, long deptId, List<TempDuser> addTempUserList) {
         try {
             DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/get");
             OapiV2DepartmentGetRequest req = new OapiV2DepartmentGetRequest();
             req.setDeptId(deptId);
             OapiV2DepartmentGetResponse rsp = client.execute(req, accessToken);
-//            System.out.println("获取部门返回="+rsp.getBody());
+            System.out.println("获取部门返回="+rsp.getBody());
             JSONObject json = JSONObject.parseObject(rsp.getBody());
             if (json.getInteger("errcode") == 0) {
                 JSONObject dept = json.getJSONObject("result");
@@ -1165,45 +1310,37 @@ public class DingDingServiceImpl implements DingDingService {
                 if (departmentDingding.getDdDeptid() != 1) {
                     department.setDepartmentName(dept.getString("name"));
                     synchronized (deptLock) {
-                        int cnt = departmentDingdingMapper.selectCount(new QueryWrapper<DepartmentDingding>()
+                        List<DepartmentDingding> departmentDingdings = departmentDingdingMapper.selectList(new QueryWrapper<DepartmentDingding>()
                                 .eq("corpid", corpid)
                                 .eq("dd_deptid", departmentDingding.getDdDeptid()));
                         //检查该部门是否已经创建,但是重名的可能是多个父部门下的同名子部门,所以不能用
-                        if (cnt > 0) {
-                            List<DepartmentDingding> departmentDingdings = departmentDingdingMapper.selectList(new QueryWrapper<DepartmentDingding>()
-                                    .eq("corpid", corpid)
-                                    .eq("dd_deptid", departmentDingding.getDdDeptid()));
-                            DepartmentDingding ddd = departmentDingdings.get(0);
-                            Integer sysDeptid = ddd.getSysDeptid();
-                            Department oldDept = departmentMapper.selectById(sysDeptid);
-                            //已经被删除了,忽略
-                            if (oldDept != null) {
-                                department = oldDept;
-//                                departmentMapper.insert(department);
-//                                //更新一下之前的记录,设置刚生成的这个部门id
-//                                ddd.setSysDeptid(department.getDepartmentId());
-//                                departmentDingdingMapper.updateById(ddd);
+                        if (departmentDingdings.size() > 0) {
+                            DepartmentDingding old = departmentDingdings.get(0);
+                            departmentDingding.setId(old.getId());
+                            //检查名称是否发生变化
+                            System.out.println(departmentDingding.getName()+" -- 已存在:"+departmentDingding.getDdDeptid());
+                            if (!old.getName().equals(departmentDingding.getName()) || !old.getDdParentid().equals(departmentDingding.getDdParentid())) {
+                                departmentDingdingMapper.updateById(departmentDingding);
+                                System.out.println("更新该部门");
                             }
                         } else {
-                            departmentMapper.insert(department);
-                            departmentDingding.setSysDeptid(department.getDepartmentId());
                             departmentDingdingMapper.insert(departmentDingding);
                         }
                     }
                 }
 
                 //获取该部门下的人员, 如果是根部门,不会创建,人员的部门id会使用数据库默认的0
-                getDeptUserIdList(roleId, roleName, companyId, deptId, department.getDepartmentId(), accessToken);
+                getDeptUserIdList(corpid, deptId, accessToken, addTempUserList);
                 //获取子部门
-                getDepartmentList(roleId, roleName, companyId, corpid, accessToken, departmentDingding.getDdDeptid(), department.getDepartmentId());
+                getDepartmentList(roleId, roleName, companyId, corpid, accessToken, departmentDingding.getDdDeptid(), addTempUserList);
             }
         } catch (ApiException e) {
             e.printStackTrace();
         }
     }
 
-    //获取该部门下的人员和子部门列表,递归下一级子部门
-    public  String getDepartmentList(int roleId, String roleName, Integer companyId, String corpid, String access_token, long parentDeptId, Integer parentSysDeptId) throws ApiException {
+    //获取该部门下的子部门列表,递归下一级子部门
+    public  String getDepartmentList(int roleId, String roleName, Integer companyId, String corpid, String access_token, long parentDeptId, List<TempDuser> addTempUserList) throws ApiException {
         DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
         OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
         req.setDeptId(parentDeptId);
@@ -1221,27 +1358,30 @@ public class DingDingServiceImpl implements DingDingService {
                 departmentDingding.setDdDeptid(dept.getInteger("dept_id"));
                 departmentDingding.setName(dept.getString("name"));
                 departmentDingding.setDdParentid(dept.getInteger("parent_id"));
-                Department department = new Department();
-                department.setDepartmentName(dept.getString("name"));
-                department.setCompanyId(companyId);
-                department.setSuperiorId(parentSysDeptId);
 
                 synchronized (deptLock) {
-                    //检查该部门是否已经创建,以钉钉deptid为唯一身份, 加上同步锁,防止递归请求的子部门和一级请求是同一个部门
-                    int cnt = departmentDingdingMapper.selectCount(new QueryWrapper<DepartmentDingding>()
+                    List<DepartmentDingding> departmentDingdings = departmentDingdingMapper.selectList(new QueryWrapper<DepartmentDingding>()
                             .eq("corpid", corpid)
                             .eq("dd_deptid", departmentDingding.getDdDeptid()));
-                    if (cnt == 0) {
-                        departmentMapper.insert(department);
-                        departmentDingding.setSysDeptid(department.getDepartmentId());
+                    //检查该部门是否已经创建,但是重名的可能是多个父部门下的同名子部门,所以不能用
+                    if (departmentDingdings.size() > 0) {
+                        DepartmentDingding old = departmentDingdings.get(0);
+                        departmentDingding.setId(old.getId());
+                        //检查名称是否发生变化
+                        System.out.println(departmentDingding.getName()+" -- 已存在:"+departmentDingding.getDdDeptid());
+                        if (!old.getName().equals(departmentDingding.getName()) || !old.getDdParentid().equals(departmentDingding.getDdParentid())) {
+                            departmentDingdingMapper.updateById(departmentDingding);
+                            System.out.println("更新该部门");
+                        }
+                    } else {
                         departmentDingdingMapper.insert(departmentDingding);
                     }
                 }
                 //获取子部门的数据
-                getDepartmentList(roleId, roleName, companyId, corpid, access_token, departmentDingding.getDdDeptid(), department.getDepartmentId());
+                getDepartmentList(roleId, roleName, companyId, corpid, access_token, departmentDingding.getDdDeptid(), addTempUserList);
             }
             //获取部门下的人员列表
-            getDeptUserIdList(roleId, roleName, companyId, parentDeptId, parentSysDeptId, access_token);
+            getDeptUserIdList(corpid, parentDeptId, access_token, addTempUserList);
         } else {
             return json.toJSONString();
         }
@@ -1249,7 +1389,7 @@ public class DingDingServiceImpl implements DingDingService {
     }
 
     //获取部门下的人员ids
-    public void getDeptUserIdList(int roleId, String roleName, int companyId, long ddDeptId,Integer sysDeptId, String access_token) throws ApiException {
+    public void getDeptUserIdList(String corpid, long ddDeptId, String access_token, List<TempDuser> addTempUserList) throws ApiException {
         DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listid");
         OapiUserListidRequest req = new OapiUserListidRequest();
         req.setDeptId(ddDeptId);
@@ -1260,7 +1400,7 @@ public class DingDingServiceImpl implements DingDingService {
             JSONArray jsonArray = resp.getJSONObject("result").getJSONArray("userid_list");
             for (int i=0;i<jsonArray.size(); i++) {
                 String dduid = jsonArray.getString(i);
-                getUserDetail(roleId, roleName, companyId, sysDeptId, dduid, access_token);
+                getUserDetail(corpid, dduid, access_token, addTempUserList);
             }
         }
     }
@@ -1332,8 +1472,10 @@ public class DingDingServiceImpl implements DingDingService {
     }
 
 
+
+
     //获取人员详情
-    private void getUserDetail(int roleId, String roleName, Integer companyId, Integer departmentId, String dingdingUserid, String access_token) throws ApiException {
+    private void getUserDetail(String corpid,String dingdingUserid, String access_token, List<TempDuser> addTempUserList) throws ApiException {
         DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
         OapiV2UserGetRequest req = new OapiV2UserGetRequest();
         req.setUserid(dingdingUserid);
@@ -1343,74 +1485,18 @@ public class DingDingServiceImpl implements DingDingService {
         JSONObject resp = JSONObject.parseObject(rsp.getBody());
         if (resp.getInteger("errcode") == 0) {
             JSONObject userJson = resp.getJSONObject("result");
-            User user = new User();
-            user.setId(SnowFlake.nextId()+"")
-                    .setRoleId(roleId)
-                    .setRoleName(roleName)
-                    .setCompanyId(companyId)
-                    .setDepartmentId(departmentId)
-                    .setName(userJson.getString("name"))
-                    .setDingdingUserid(dingdingUserid)
-                    .setDingdingUnionid(userJson.getString("unionid"))
-                    .setJobNumber(userJson.getString("job_number"))
-                    .setColor(ColorUtil.randomColor());
-
-            if (departmentId != null) {
-                user.setDepartmentCascade(convertDepartmentIdToCascade(departmentId));
-            }
+            JSONArray deptIdList = userJson.getJSONArray("dept_id_list");
+            int ddDeptId = getMaxDeptId(deptIdList);
             //检查用户是否已经存在
-            synchronized (userLock) {
-                if (isDev) {
-                    long existsCount = tempDuserMapper.selectCount(new QueryWrapper<TempDuser>().eq("dingding_userid", dingdingUserid));
-                    if (existsCount == 0) {
-                        TempDuser duser = new TempDuser();
-                        duser.setDingdingUserid(user.getDingdingUserid());
-                        duser.setName(user.getName());
-                        tempDuserMapper.insert(duser);
-                    }
-                }
-
-                List<User> oldList = userMapper.selectList(new QueryWrapper<User>().eq("dingding_userid", dingdingUserid).eq("company_id", companyId));
-                if (oldList.size() == 0) {
-//                    Integer employeeCnt = userMapper.selectCount(new QueryWrapper<User>().eq("company_id", companyId).eq("is_active",1));
-//                    Company company = companyMapper.selectOne(new QueryWrapper<Company>().eq("id", companyId));
-//                    ContactSyncLog contactSyncLog = new ContactSyncLog();
-//                    contactSyncLog.setCompanyId(companyId);
-//                    if (employeeCnt + 1 > company.getStaffCountMax()){
-//                        contactSyncLog.setResult(0);
-//                        //contactSyncLog.setMsg("公司人员已达上限,请联系客服提高人数上限。");
-//                        contactSyncLog.setMsg(MessageUtils.message("wx.employeeFull"));
-//                        contactSyncLogMapper.insert(contactSyncLog);
-//                    }else {
-//                        System.out.println("新增钉钉用户==" + user.getName());
-//                        userMapper.insert(user);
-//                        contactSyncLog.setResult(1);
-//                        //contactSyncLog.setMsg("同步成功");
-//                        contactSyncLog.setMsg(MessageUtils.message("wx.synSuccess"));
-//                        contactSyncLogMapper.insert(contactSyncLog);
-//                    }
-                    System.out.println("新增钉钉用户==" + user.getName());
-                    userMapper.insert(user);
-                } else {
-                    //可能需要更新姓名
-                    User oldUser = oldList.get(0);
-                    if (oldUser.getName() == null || !oldUser.getName().equals(userJson.getString("name"))) {
-                        oldUser.setName(userJson.getString("name"));
-                        oldUser.setDingdingUnionid(userJson.getString("unionid"));
-                        userMapper.updateById(oldUser);
-                        System.out.println("更新用户姓名==" + oldUser.getName());
-                    }
-                    //可能需要更新工号
-                    if (!StringUtils.isEmpty(userJson.getString("job_number")) && (oldUser.getJobNumber() == null || !oldUser.getJobNumber().equals(userJson.getString("job_number")))) {
-                        oldUser.setJobNumber(userJson.getString("job_number"));
-                        userMapper.updateById(oldUser);
-                    }
-
-
-                    if (oldList.size() > 1) {
-                        System.err.println("Exception 存在重复用户 dingdingUserId="+oldUser.getDingdingUserid()+", name="+oldUser.getName()+", companyId"+oldUser.getCompanyId());
-                    }
-                }
+            if (!addTempUserList.stream().anyMatch(add->add.getDingdingUserid().equals(dingdingUserid))) {
+                TempDuser duser = new TempDuser();
+                duser.setDingdingUserid(dingdingUserid);
+                duser.setName(userJson.getString("name"));
+                duser.setDdDeptid(ddDeptId);
+                duser.setCorpid(corpid);
+                duser.setJobNumber(userJson.getString("job_number"));
+                duser.setDingdingUnionid(userJson.getString("unionid"));
+                addTempUserList.add(duser);
             }
         }
     }
@@ -2254,4 +2340,13 @@ public class DingDingServiceImpl implements DingDingService {
         int cnt = projectAuditorMapper.selectCount(new QueryWrapper<ProjectAuditor>().eq("auditor_id", userId));
         return cnt>0;
     }
+
+    private Integer getMaxDeptId(JSONArray array) {
+        int deptId = 0;
+        for (int i=0;i<array.size(); i++) {
+            int bigInteger = array.getInteger(i);
+            if (deptId < bigInteger) deptId = bigInteger;
+        }
+        return deptId;
+    }
 }

+ 2 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/DepartmentMapper.xml

@@ -12,11 +12,12 @@
         <result column="report_audit_userid" property="reportAuditUserid" />
         <result column="corpwx_deptid" property="corpwxDeptid" />
         <result column="corpwx_deptpid" property="corpwxDeptpid" />
+        <result column="dd_deptid" property="ddDeptid" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        department_id, department_name, superior_id, company_id, manager_id, report_audit_userid, corpwx_deptid, corpwx_deptpid
+        department_id, department_name, superior_id, company_id, manager_id, report_audit_userid, corpwx_deptid, corpwx_deptpid, dd_deptid
     </sql>
     <!--根据部门获取成本-->
     <select id="getCostByDepartment" resultType="java.util.Map">

+ 5 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TempDuserMapper.xml

@@ -7,11 +7,15 @@
         <id column="id" property="id" />
         <result column="dingding_userid" property="dingdingUserid" />
         <result column="name" property="name" />
+        <result column="dd_deptid" property="ddDeptid" />
+        <result column="corpid" property="corpid" />
+        <result column="dingding_unionid" property="dingdingUnionid" />
+        <result column="job_number" property="jobNumber" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, dingding_userid, name
+        id, dingding_userid, name, dd_deptid, corpid, dingding_unionid, job_number
     </sql>
 
 </mapper>

+ 258 - 5
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/demo_index.html

@@ -3,8 +3,8 @@
 <head>
   <meta charset="utf-8"/>
   <title>iconfont Demo</title>
-  <link rel="shortcut icon" href="//img.alicdn.com/imgextra/i2/O1CN01ZyAlrn1MwaMhqz36G_!!6000000001499-73-tps-64-64.ico" type="image/x-icon"/>
-  <link rel="icon" type="image/svg+xml" href="//img.alicdn.com/imgextra/i4/O1CN01EYTRnJ297D6vehehJ_!!6000000008020-55-tps-64-64.svg"/>
+  <link rel="shortcut icon" href="//img.alicdn.com/imgextra/i4/O1CN01Z5paLz1O0zuCC7osS_!!6000000001644-55-tps-83-82.svg" type="image/x-icon"/>
+  <link rel="icon" type="image/svg+xml" href="//img.alicdn.com/imgextra/i4/O1CN01Z5paLz1O0zuCC7osS_!!6000000001644-55-tps-83-82.svg"/>
   <link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
   <link rel="stylesheet" href="demo.css">
   <link rel="stylesheet" href="iconfont.css">
@@ -54,6 +54,72 @@
       <div class="content unicode" style="display: block;">
           <ul class="icon_lists dib-box">
           
+            <li class="dib">
+              <span class="icon iconfont">&#xe772;</span>
+                <div class="name">钉钉</div>
+                <div class="code-name">&amp;#xe772;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe625;</span>
+                <div class="name">推送</div>
+                <div class="code-name">&amp;#xe625;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe675;</span>
+                <div class="name">合同7</div>
+                <div class="code-name">&amp;#xe675;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6ca;</span>
+                <div class="name">sync</div>
+                <div class="code-name">&amp;#xe6ca;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe700;</span>
+                <div class="name">流程</div>
+                <div class="code-name">&amp;#xe700;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6e1;</span>
+                <div class="name">打卡记录</div>
+                <div class="code-name">&amp;#xe6e1;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe674;</span>
+                <div class="name">关联</div>
+                <div class="code-name">&amp;#xe674;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe70a;</span>
+                <div class="name">users</div>
+                <div class="code-name">&amp;#xe70a;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe615;</span>
+                <div class="name">权限</div>
+                <div class="code-name">&amp;#xe615;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe616;</span>
+                <div class="name">系统</div>
+                <div class="code-name">&amp;#xe616;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe67e;</span>
+                <div class="name">客户</div>
+                <div class="code-name">&amp;#xe67e;</div>
+              </li>
+          
             <li class="dib">
               <span class="icon iconfont">&#xe70e;</span>
                 <div class="name">文件-请假单</div>
@@ -432,9 +498,9 @@
 <pre><code class="language-css"
 >@font-face {
   font-family: 'iconfont';
-  src: url('iconfont.woff2?t=1639190324165') format('woff2'),
-       url('iconfont.woff?t=1639190324165') format('woff'),
-       url('iconfont.ttf?t=1639190324165') format('truetype');
+  src: url('iconfont.woff2?t=1673910639274') format('woff2'),
+       url('iconfont.woff?t=1673910639274') format('woff'),
+       url('iconfont.ttf?t=1673910639274') format('truetype');
 }
 </code></pre>
           <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@@ -460,6 +526,105 @@
       <div class="content font-class">
         <ul class="icon_lists dib-box">
           
+          <li class="dib">
+            <span class="icon iconfont firerock-icondingding"></span>
+            <div class="name">
+              钉钉
+            </div>
+            <div class="code-name">.firerock-icondingding
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont firerock-icontuisong"></span>
+            <div class="name">
+              推送
+            </div>
+            <div class="code-name">.firerock-icontuisong
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont firerock-iconhetong7"></span>
+            <div class="name">
+              合同7
+            </div>
+            <div class="code-name">.firerock-iconhetong7
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont firerock-iconsync"></span>
+            <div class="name">
+              sync
+            </div>
+            <div class="code-name">.firerock-iconsync
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont firerock-iconliucheng1"></span>
+            <div class="name">
+              流程
+            </div>
+            <div class="code-name">.firerock-iconliucheng1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont firerock-icondakajilu"></span>
+            <div class="name">
+              打卡记录
+            </div>
+            <div class="code-name">.firerock-icondakajilu
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont firerock-iconguanlian"></span>
+            <div class="name">
+              关联
+            </div>
+            <div class="code-name">.firerock-iconguanlian
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont firerock-iconusers"></span>
+            <div class="name">
+              users
+            </div>
+            <div class="code-name">.firerock-iconusers
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont firerock-iconquanxian1"></span>
+            <div class="name">
+              权限
+            </div>
+            <div class="code-name">.firerock-iconquanxian1
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont firerock-iconxitong-"></span>
+            <div class="name">
+              系统
+            </div>
+            <div class="code-name">.firerock-iconxitong-
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont firerock-iconkehu"></span>
+            <div class="name">
+              客户
+            </div>
+            <div class="code-name">.firerock-iconkehu
+            </div>
+          </li>
+          
           <li class="dib">
             <span class="icon iconfont firerock-iconwj-qjd"></span>
             <div class="name">
@@ -1027,6 +1192,94 @@
       <div class="content symbol">
           <ul class="icon_lists dib-box">
           
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#firerock-icondingding"></use>
+                </svg>
+                <div class="name">钉钉</div>
+                <div class="code-name">#firerock-icondingding</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#firerock-icontuisong"></use>
+                </svg>
+                <div class="name">推送</div>
+                <div class="code-name">#firerock-icontuisong</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#firerock-iconhetong7"></use>
+                </svg>
+                <div class="name">合同7</div>
+                <div class="code-name">#firerock-iconhetong7</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#firerock-iconsync"></use>
+                </svg>
+                <div class="name">sync</div>
+                <div class="code-name">#firerock-iconsync</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#firerock-iconliucheng1"></use>
+                </svg>
+                <div class="name">流程</div>
+                <div class="code-name">#firerock-iconliucheng1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#firerock-icondakajilu"></use>
+                </svg>
+                <div class="name">打卡记录</div>
+                <div class="code-name">#firerock-icondakajilu</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#firerock-iconguanlian"></use>
+                </svg>
+                <div class="name">关联</div>
+                <div class="code-name">#firerock-iconguanlian</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#firerock-iconusers"></use>
+                </svg>
+                <div class="name">users</div>
+                <div class="code-name">#firerock-iconusers</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#firerock-iconquanxian1"></use>
+                </svg>
+                <div class="name">权限</div>
+                <div class="code-name">#firerock-iconquanxian1</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#firerock-iconxitong-"></use>
+                </svg>
+                <div class="name">系统</div>
+                <div class="code-name">#firerock-iconxitong-</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#firerock-iconkehu"></use>
+                </svg>
+                <div class="name">客户</div>
+                <div class="code-name">#firerock-iconkehu</div>
+            </li>
+          
             <li class="dib">
                 <svg class="icon svg-icon" aria-hidden="true">
                   <use xlink:href="#firerock-iconwj-qjd"></use>

+ 47 - 3
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 2390497 */
-  src: url('iconfont.woff2?t=1639190324165') format('woff2'),
-       url('iconfont.woff?t=1639190324165') format('woff'),
-       url('iconfont.ttf?t=1639190324165') format('truetype');
+  src: url('iconfont.woff2?t=1673910639274') format('woff2'),
+       url('iconfont.woff?t=1673910639274') format('woff'),
+       url('iconfont.ttf?t=1673910639274') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,50 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.firerock-icondingding:before {
+  content: "\e772";
+}
+
+.firerock-icontuisong:before {
+  content: "\e625";
+}
+
+.firerock-iconhetong7:before {
+  content: "\e675";
+}
+
+.firerock-iconsync:before {
+  content: "\e6ca";
+}
+
+.firerock-iconliucheng1:before {
+  content: "\e700";
+}
+
+.firerock-icondakajilu:before {
+  content: "\e6e1";
+}
+
+.firerock-iconguanlian:before {
+  content: "\e674";
+}
+
+.firerock-iconusers:before {
+  content: "\e70a";
+}
+
+.firerock-iconquanxian1:before {
+  content: "\e615";
+}
+
+.firerock-iconxitong-:before {
+  content: "\e616";
+}
+
+.firerock-iconkehu:before {
+  content: "\e67e";
+}
+
 .firerock-iconwj-qjd:before {
   content: "\e70e";
 }

文件差異過大導致無法顯示
+ 1 - 1
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.js


+ 77 - 0
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.json

@@ -5,6 +5,83 @@
   "css_prefix_text": "firerock-icon",
   "description": "",
   "glyphs": [
+    {
+      "icon_id": "20375943",
+      "name": "钉钉",
+      "font_class": "dingding",
+      "unicode": "e772",
+      "unicode_decimal": 59250
+    },
+    {
+      "icon_id": "10936691",
+      "name": "推送",
+      "font_class": "tuisong",
+      "unicode": "e625",
+      "unicode_decimal": 58917
+    },
+    {
+      "icon_id": "774469",
+      "name": "合同7",
+      "font_class": "hetong7",
+      "unicode": "e675",
+      "unicode_decimal": 58997
+    },
+    {
+      "icon_id": "5832808",
+      "name": "sync",
+      "font_class": "sync",
+      "unicode": "e6ca",
+      "unicode_decimal": 59082
+    },
+    {
+      "icon_id": "6970024",
+      "name": "流程",
+      "font_class": "liucheng1",
+      "unicode": "e700",
+      "unicode_decimal": 59136
+    },
+    {
+      "icon_id": "15673407",
+      "name": "打卡记录",
+      "font_class": "dakajilu",
+      "unicode": "e6e1",
+      "unicode_decimal": 59105
+    },
+    {
+      "icon_id": "5651484",
+      "name": "关联",
+      "font_class": "guanlian",
+      "unicode": "e674",
+      "unicode_decimal": 58996
+    },
+    {
+      "icon_id": "14949575",
+      "name": "users",
+      "font_class": "users",
+      "unicode": "e70a",
+      "unicode_decimal": 59146
+    },
+    {
+      "icon_id": "736503",
+      "name": "权限",
+      "font_class": "quanxian1",
+      "unicode": "e615",
+      "unicode_decimal": 58901
+    },
+    {
+      "icon_id": "7987507",
+      "name": "系统",
+      "font_class": "xitong-",
+      "unicode": "e616",
+      "unicode_decimal": 58902
+    },
+    {
+      "icon_id": "11111002",
+      "name": "客户",
+      "font_class": "kehu",
+      "unicode": "e67e",
+      "unicode_decimal": 59006
+    },
     {
       "icon_id": "6517457",
       "name": "文件-请假单",

二進制
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.ttf


二進制
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.woff


二進制
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.woff2


+ 4 - 4
fhKeeper/formulahousekeeper/timesheet/src/views/team/index.vue

@@ -16,13 +16,12 @@
                 <!-- <el-tree :data="data" :props="defaultProps" node-key="id" :expand-on-click-node="false" accordion @node-click="handleNodeClick" :default-expanded-keys="jDarr" @node-expand="jieDian" @node-collapse="shutDown" @current-change="chufa"> -->
                 <el-tree :data="data" :props="defaultProps" :expand-on-click-node="false" accordion @node-click="handleNodeClick" :default-expanded-keys="jDarr" @node-expand="jieDian" @node-collapse="shutDown" @current-change="chufa">
                     <span class="custom-tree-node" style="position: relative;box-sizing: border-box;width: 10%;" slot-scope="{ node }" @mouseleave= mouseleave(data,$event) @mouseover= mouseover(data,$event)>
-
                         <span style="padding-right: 50px;box-sizing: border-box;overflow:hidden;text-overflow:ellipsis;line-height: 36px; display: inline-block;">
                           <span v-if="user.userNameNeedTranslate == '1'">
                             <ww-open-data type='departmentName' :openid='node.label'></ww-open-data>
                           </span>
                           <span v-else>
-                            {{ node.label }}
+                            {{ node.label }} <i v-if="node.data.ddDeptid != null" class="iconfont firerock-icondingding"></i>
                           </span>
 
                           <!-- <span v-if="user.userNameNeedTranslate == '1'">
@@ -83,6 +82,7 @@
                             <span v-if="translation == '2' && user.userNameNeedTranslate == '1'"><ww-open-data type='departmentName' :openid='depData.label'></ww-open-data></span>
                             <span v-if="translation == '3' && user.userNameNeedTranslate == '1'"><ww-open-data type='userName' :openid='depData.label'></ww-open-data></span>
                             <span v-if="user.userNameNeedTranslate != '1'">{{depData != null ?depData.label:""}}</span>
+                            <!-- <i class="iconfont firerock-icondingding"></i> -->
                             <!-- {{translation}} -->
                         </div>
                     </el-form-item>
@@ -99,7 +99,7 @@
                     <el-form-item style="float:right;" v-if="permissions.structureExport">
                         <el-link type="primary" :underline="false" @click="showExportDialog">{{ $t('exportpersonnel') }}</el-link>
                     </el-form-item>
-                    <el-form-item style="float:right;" v-if="user.timeType.syncDingding == 0 && permissions.structureAdd && user.userNameNeedTranslate != '1'">
+                    <el-form-item style="float:right;" v-if="user.timeType.syncDingding == 0 && permissions.structureAdd && user.userNameNeedTranslate != '1' && user.dingdingUserid == null">
                         <el-link type="primary" :underline="false" @click="openInsertDialog(null)">{{ $t('addpersonnel') }}</el-link>
                     </el-form-item>
                     <!--导入薪资-->
@@ -107,7 +107,7 @@
                         <el-link type="primary" :underline="false" @click="importUserSalary(null)">{{ $t('importSalary') }}</el-link>
                     </el-form-item>
                     
-                    <el-form-item style="float:right;" v-if="user.timeType.syncDingding == 0 && permissions.structureImport && user.userNameNeedTranslate != '1'">
+                    <el-form-item style="float:right;" v-if="user.timeType.syncDingding == 0 && permissions.structureImport && user.userNameNeedTranslate != '1' && user.dingdingUserid == null">
                         <el-link type="primary" :underline="false" @click="importUserC">{{ $t('bulkimport') }}</el-link>
                     </el-form-item>
                     <el-form-item style="float:right;" v-if="user.corpwxUserid != null && permissions.structureImport && user.companyId==469">