From bff1768d0a287e7be7a9e7a17690ab44a8729d26 Mon Sep 17 00:00:00 2001
From: Houjie <714924425@qq.com>
Date: 星期一, 11 八月 2025 17:26:12 +0800
Subject: [PATCH] 飞书同步用户/安灯获取产线  用户表增加 飞书用户open_id(后期发送消息标识)

---
 src/main/java/org/jeecg/modules/andon/controller/AndonButtonConfigController.java |   33 +++
 src/main/java/org/jeecg/modules/mes/job/FeishuUserService.java                    |  324 ++++++++++++++++++++++++++++++++++++
 src/main/java/org/jeecg/modules/base/model/FactoryModel.java                      |   33 +++
 src/main/java/org/jeecg/modules/mes/entity/FeishuUser.java                        |   26 ++
 src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java       |    5 
 src/main/java/org/jeecg/modules/system/entity/SysUser.java                        |    6 
 src/main/java/org/jeecg/modules/mes/job/FeishuSyncTask.java                       |   40 ++++
 src/main/java/org/jeecg/modules/system/service/ISysUserService.java               |    2 
 src/main/java/org/jeecg/modules/base/controller/FactoryController.java            |   25 ++
 9 files changed, 494 insertions(+), 0 deletions(-)

diff --git a/src/main/java/org/jeecg/modules/andon/controller/AndonButtonConfigController.java b/src/main/java/org/jeecg/modules/andon/controller/AndonButtonConfigController.java
index be0c78d..a589c4b 100644
--- a/src/main/java/org/jeecg/modules/andon/controller/AndonButtonConfigController.java
+++ b/src/main/java/org/jeecg/modules/andon/controller/AndonButtonConfigController.java
@@ -6,10 +6,12 @@
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.SecurityUtils;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.aspect.annotation.AutoLog;
 import org.jeecg.common.system.base.controller.JeecgController;
 import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.system.vo.LoginUser;
 import org.jeecg.modules.andon.entity.AndonButtonConfig;
 import org.jeecg.modules.andon.service.IAndonButtonConfigService;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -56,6 +58,37 @@
        return Result.OK(pageList);
    }
 
+
+
+    /**
+     * APP鍒嗛〉鍒楄〃鏌ヨ
+     *
+     * @param andonButtonConfig
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @ApiOperation(value="瀹夌伅鎸夐挳閰嶇疆-鍒嗛〉鍒楄〃鏌ヨ", notes="瀹夌伅鎸夐挳閰嶇疆-鍒嗛〉鍒楄〃鏌ヨ")
+    @GetMapping(value = "/App/list")
+    public Result<IPage<AndonButtonConfig>> queryPageAppList(AndonButtonConfig andonButtonConfig,
+                                                             @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+                                                             @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+                                                             HttpServletRequest req) {
+        QueryWrapper<AndonButtonConfig> queryWrapper = QueryGenerator.initQueryWrapper(andonButtonConfig, req.getParameterMap());
+
+        // 鑾峰彇褰撳墠鐧诲綍鐢ㄦ埛
+        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+        if (sysUser != null) {
+            // 澧炲姞閫氳繃绯荤粺鐧诲綍浜鸿繘琛岃繃婊�
+            queryWrapper.eq("create_by", sysUser.getUsername());
+        }
+
+        Page<AndonButtonConfig> page = new Page<AndonButtonConfig>(pageNo, pageSize);
+        IPage<AndonButtonConfig> pageList = andonButtonConfigService.page(page, queryWrapper);
+        return Result.OK(pageList);
+    }
+
    /**
     *   娣诲姞
     *
diff --git a/src/main/java/org/jeecg/modules/base/controller/FactoryController.java b/src/main/java/org/jeecg/modules/base/controller/FactoryController.java
index 75efb57..dc46151 100644
--- a/src/main/java/org/jeecg/modules/base/controller/FactoryController.java
+++ b/src/main/java/org/jeecg/modules/base/controller/FactoryController.java
@@ -13,6 +13,7 @@
 import org.jeecg.common.util.oConvertUtils;
 import org.jeecg.modules.base.entity.Factory;
 import org.jeecg.modules.base.model.FactoryIdModel;
+import org.jeecg.modules.base.model.FactoryModel;
 import org.jeecg.modules.base.service.IFactoryService;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -220,6 +221,30 @@
 		 return result;
 	 }
 
+	 @ApiOperation(value = "浜х嚎琛ㄩ泦鍚�", notes = "浜х嚎琛ㄩ泦鍚�")
+	 @GetMapping(value = "/queryTreeAppList")
+	 public Result<List<FactoryModel>> queryTreeAppList() {
+		 Result<List<FactoryModel>> result = new Result<>();
+		 try {
+			 List<Factory> factoryList = factoryService.list(new LambdaQueryWrapper<Factory>()
+					 .eq(Factory::getDelFlag, CommonConstant.DEL_FLAG_0)
+					 .orderByAsc(Factory::getSorter));
+
+			 List<FactoryModel> factoryModels = factoryList.stream()
+					 .map(factory -> new FactoryModel(factory.getId(), factory.getFactoryName()))
+					 .collect(Collectors.toList());
+
+			 result.setSuccess(true);
+			 result.setResult(factoryModels);
+		 } catch (Exception e) {
+			 log.error(e.getMessage(), e);
+		 }
+		 return result;
+	 }
+
+
+
+
 	 //@AutoLog(value = "浜х嚎琛�-鏌ヨ鏍戝舰缁撴瀯鎵�鏈変骇绾垮悕绉�")
 	 @ApiOperation(value = "浜х嚎琛�-鏌ヨ鏍戝舰缁撴瀯鎵�鏈変骇绾垮悕绉�", notes = "浜х嚎琛�-鏌ヨ鏍戝舰缁撴瀯鎵�鏈変骇绾垮悕绉�")
 	 @GetMapping(value = "/queryIdTree")
diff --git a/src/main/java/org/jeecg/modules/base/model/FactoryModel.java b/src/main/java/org/jeecg/modules/base/model/FactoryModel.java
new file mode 100644
index 0000000..dbef147
--- /dev/null
+++ b/src/main/java/org/jeecg/modules/base/model/FactoryModel.java
@@ -0,0 +1,33 @@
+package org.jeecg.modules.base.model;
+
+import lombok.Data;
+
+@Data
+public class FactoryModel {
+    private String value;  // 浜х嚎ID
+    private String text;   // 浜х嚎鍚嶇О
+
+    public FactoryModel() {}
+
+    public FactoryModel(String value, String text) {
+        this.value = value;
+        this.text = text;
+    }
+
+    // getter鍜宻etter鏂规硶
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+}
diff --git a/src/main/java/org/jeecg/modules/mes/entity/FeishuUser.java b/src/main/java/org/jeecg/modules/mes/entity/FeishuUser.java
new file mode 100644
index 0000000..90ea6d9
--- /dev/null
+++ b/src/main/java/org/jeecg/modules/mes/entity/FeishuUser.java
@@ -0,0 +1,26 @@
+package org.jeecg.modules.mes.entity;
+
+import lombok.Data;
+
+@Data
+public class FeishuUser {
+    private String openId;
+    private String name;
+    private String username;
+    private String realname;
+    private String workNo;
+    private String password;
+    private String userId;      // 瀵瑰簲 open_id
+    private String unionId;     // 瀵瑰簲 union_id
+    private String enName;      // 瀵瑰簲 en_name
+    private String description; // 瀵瑰簲 description
+    private String avatar240;   // 瀵瑰簲 avatar.avatar_240
+    private String avatar640;   // 瀵瑰簲 avatar.avatar_640
+    private String avatar72;    // 瀵瑰簲 avatar.avatar_72
+    private String avatarOrigin;// 瀵瑰簲 avatar.avatar_origin
+    private String email;
+    private String mobile;
+    private String employeeNo;
+    private Integer status;
+    private Boolean mobileVisible; // 瀵瑰簲 mobile_visible
+}
diff --git a/src/main/java/org/jeecg/modules/mes/job/FeishuSyncTask.java b/src/main/java/org/jeecg/modules/mes/job/FeishuSyncTask.java
new file mode 100644
index 0000000..36e816a
--- /dev/null
+++ b/src/main/java/org/jeecg/modules/mes/job/FeishuSyncTask.java
@@ -0,0 +1,40 @@
+
+package org.jeecg.modules.mes.job;
+
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * 椋炰功鐢ㄦ埛鍚屾瀹氭椂浠诲姟
+ */
+@Component
+@Slf4j
+public class FeishuSyncTask implements Job {
+
+    @Autowired
+    private org.jeecg.modules.mes.job.FeishuUserService feishuUserService;
+
+    @Value("${feishu.sync.departmentId:0}")
+    private String departmentId;
+
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        log.info("寮�濮嬫墽琛岄涔︾敤鎴峰悓姝ヤ换鍔�");
+        try {
+            if (departmentId != null && !"0".equals(departmentId)) {
+                feishuUserService.syncFeishuDepartmentUsers(departmentId);
+                log.info("椋炰功鐢ㄦ埛鍚屾浠诲姟鎵ц瀹屾垚");
+            } else {
+                log.warn("鏈厤缃涔﹀悓姝ラ儴闂↖D锛岃烦杩囧悓姝ヤ换鍔�");
+            }
+        } catch (Exception e) {
+            log.error("椋炰功鐢ㄦ埛鍚屾浠诲姟鎵ц澶辫触", e);
+            throw new JobExecutionException(e);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/jeecg/modules/mes/job/FeishuUserService.java b/src/main/java/org/jeecg/modules/mes/job/FeishuUserService.java
new file mode 100644
index 0000000..138a910
--- /dev/null
+++ b/src/main/java/org/jeecg/modules/mes/job/FeishuUserService.java
@@ -0,0 +1,324 @@
+package org.jeecg.modules.mes.job;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.util.PasswordUtil;
+import org.jeecg.common.util.RestUtil;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.mes.entity.FeishuUser;
+import org.jeecg.modules.system.entity.SysUser;
+import org.jeecg.modules.system.service.ISysUserService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+@Slf4j
+public class FeishuUserService {
+
+    @Resource
+    private ISysUserService sysUserService;
+
+    @Resource
+    private RestTemplate restTemplate;  // 鏂板RestTemplate渚濊禆娉ㄥ叆
+
+    @Value("${feishu.appId:}")
+    private String appId;
+
+    @Value("${feishu.appSecret:}")
+    private String appSecret;
+
+    /**
+     * 鍚屾椋炰功閮ㄩ棬鐢ㄦ埛鍒扮郴缁熺敤鎴疯〃
+     * @param departmentId 椋炰功閮ㄩ棬ID
+     */
+    public void syncFeishuDepartmentUsers(String departmentId) {
+        try {
+            log.info("寮�濮嬪悓姝ラ涔﹂儴闂ㄧ敤鎴凤紝閮ㄩ棬ID: {}", departmentId);
+
+            // 1. 鑾峰彇椋炰功璁块棶浠ょ墝
+            String accessToken = getFeishuAccessToken();
+            if (oConvertUtils.isEmpty(accessToken)) {
+                log.error("鑾峰彇椋炰功璁块棶浠ょ墝澶辫触锛岀粓姝㈠悓姝ユ祦绋�");
+                return;  // 浠ょ墝鑾峰彇澶辫触鐩存帴杩斿洖锛岄伩鍏嶅悗缁棤鏁堟搷浣�
+            }
+
+            // 2. 鑾峰彇閮ㄩ棬涓嬬殑鐢ㄦ埛鍒楄〃
+            List<FeishuUser> feishuUsers = getDepartmentUsers(accessToken, departmentId);
+            log.info("鑾峰彇鍒伴涔﹂儴闂ㄧ敤鎴锋暟閲�: {}", feishuUsers.size());
+
+            // 3. 鍚屾鍒扮郴缁熺敤鎴疯〃
+            int successCount = 0;
+            int updateCount = 0;
+            int addCount = 0;
+
+            for (FeishuUser feishuUser : feishuUsers) {
+                try {
+                    boolean isUpdated = syncFeishuUserToSystem(feishuUser);
+                    successCount++;
+                    if (isUpdated) {
+                        updateCount++;
+                    } else {
+                        addCount++;
+                    }
+                } catch (Exception e) {
+                    log.error("鍚屾椋炰功鐢ㄦ埛澶辫触锛岀敤鎴稩D: {}", feishuUser.getUserId(), e);
+                }
+            }
+
+            log.info("椋炰功鐢ㄦ埛鍚屾瀹屾垚锛屾�诲鐞�: {}锛屾柊澧�: {}锛屾洿鏂�: {}", successCount, addCount, updateCount);
+        } catch (Exception e) {
+            log.error("鍚屾椋炰功閮ㄩ棬鐢ㄦ埛澶辫触锛岄儴闂↖D: {}", departmentId, e);
+            throw new RuntimeException("鍚屾椋炰功鐢ㄦ埛澶辫触: " + e.getMessage());
+        }
+    }
+
+    private String getFeishuAccessToken() {
+        try {
+            String url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal";
+
+            log.info("寮�濮嬭幏鍙栭涔﹁闂护鐗岋紝AppId: {}",
+                    appId != null ? appId.substring(0, Math.min(appId.length(), 10)) + "..." : "null");
+
+            JSONObject params = new JSONObject();
+            params.put("app_id", appId);
+            params.put("app_secret", appSecret);
+
+            log.debug("鑾峰彇浠ょ墝璇锋眰鍙傛暟: {}", params.toJSONString());
+
+            JSONObject result = RestUtil.post(url, params);
+
+            log.info("鑾峰彇椋炰功璁块棶浠ょ墝鍝嶅簲: {}", result != null ? result.toJSONString() : "null");
+
+            if (result != null && result.getInteger("code") == 0) {
+                String accessToken = result.getString("tenant_access_token");
+                log.info("鎴愬姛鑾峰彇椋炰功璁块棶浠ょ墝锛屼护鐗岄暱搴�: {}", accessToken != null ? accessToken.length() : 0);
+                return accessToken;
+            } else {
+                log.error("鑾峰彇椋炰功璁块棶浠ょ墝澶辫触锛屽搷搴�: {}", result != null ? result.toJSONString() : "null");
+                if (result != null) {
+                    log.error("閿欒鐮�: {}, 閿欒淇℃伅: {}", result.getInteger("code"), result.getString("msg"));
+                }
+                return null;
+            }
+        } catch (Exception e) {
+            log.error("鑾峰彇椋炰功璁块棶浠ょ墝寮傚父", e);
+            return null;
+        }
+    }
+
+    /**
+     * 鑾峰彇閮ㄩ棬鐢ㄦ埛鍒楄〃锛堢洿灞炲憳宸ワ級
+     */
+    private List<FeishuUser> getDepartmentUsers(String accessToken, String departmentId) {
+        List<FeishuUser> userList = new ArrayList<>();
+        try {
+            log.info("寮�濮嬭幏鍙栭涔﹂儴闂ㄧ敤鎴峰垪琛紝閮ㄩ棬ID: {}", departmentId);
+
+            // 楠岃瘉璁块棶浠ょ墝
+            if (accessToken == null || accessToken.isEmpty()) {
+                log.error("璁块棶浠ょ墝涓虹┖锛屾棤娉曠户缁墽琛�");
+                return userList;
+            }
+            log.info("浣跨敤鐨勮闂护鐗屽墠缂�: Bearer {}", accessToken.substring(0, Math.min(20, accessToken.length())) + "...");
+
+            // 椋炰功API绔偣
+            String url = "https://open.feishu.cn/open-apis/contact/v3/users/find_by_department";
+
+            String pageToken = null;
+            int pageNumber = 1;
+
+            do {
+                // 鏋勫缓璇锋眰URL鍜屽弬鏁�
+                StringBuilder urlBuilder = new StringBuilder(url);
+                urlBuilder.append("?department_id=").append(departmentId);
+                urlBuilder.append("&department_id_type=open_department_id");
+                urlBuilder.append("&page_size=50");
+                urlBuilder.append("&user_id_type=open_id");
+
+                if (pageToken != null && !pageToken.isEmpty()) {
+                    urlBuilder.append("&page_token=").append(pageToken);
+                }
+
+                log.info("璇锋眰绗瑊}椤垫暟鎹紝URL: {}", pageNumber, urlBuilder.toString());
+
+                // 璁剧疆璇锋眰澶� - 鍏抽敭淇鐐癸細浣跨敤HttpHeaders纭繚澶翠俊鎭纭缃�
+                HttpHeaders headers = new HttpHeaders();
+                String authHeader = "Bearer " + accessToken;
+                headers.add("Authorization", authHeader);
+                headers.add("Content-Type", "application/json; charset=utf-8");
+                log.info("璁剧疆璇锋眰澶�: Authorization = {}", authHeader.substring(0, Math.min(30, authHeader.length())) + "...");
+
+                // 浣跨敤RestTemplate鍙戦�佽姹傦紝纭繚澶翠俊鎭姝g‘浼犻��
+                HttpEntity<String> requestEntity = new HttpEntity<>(headers);
+                ResponseEntity<String> response = restTemplate.exchange(
+                        urlBuilder.toString(),
+                        HttpMethod.GET,
+                        requestEntity,
+                        String.class
+                );
+
+                // 瑙f瀽鍝嶅簲
+                JSONObject result = JSONObject.parseObject(response.getBody());
+                log.debug("绗瑊}椤礎PI鍝嶅簲: {}", pageNumber, result != null ? result.toJSONString() : "null");
+
+                if (result != null && result.getInteger("code") == 0) {
+                    JSONObject data = result.getJSONObject("data");
+                    if (data != null) {
+                        // 瑙f瀽鐢ㄦ埛鍒楄〃
+                        Object items = data.get("items");
+                        log.info("绗瑊}椤靛師濮嬬敤鎴锋暟鎹暟閲�: {}", pageNumber, items instanceof List ? ((List<?>) items).size() : 0);
+
+                        if (items != null) {
+                            List<FeishuUser> pageUsers = parseUsers(items);
+                            userList.addAll(pageUsers);
+                            log.info("绗瑊}椤佃В鏋愬悗鐢ㄦ埛鏁伴噺: {}", pageNumber, pageUsers.size());
+                        }
+
+                        // 妫�鏌ユ槸鍚︽湁涓嬩竴椤�
+                        pageToken = data.getString("page_token");
+                        boolean hasMore = data.getBooleanValue("has_more");
+                        log.info("绗瑊}椤礹as_more: {}, page_token: {}", pageNumber, hasMore, pageToken);
+                        pageNumber++;
+                    } else {
+                        log.warn("绗瑊}椤礵ata涓虹┖", pageNumber);
+                        break;
+                    }
+                } else {
+                    log.error("鑾峰彇椋炰功閮ㄩ棬鐢ㄦ埛鍒楄〃澶辫触锛屽搷搴�: {}", result != null ? result.toJSONString() : "null");
+                    if (result != null) {
+                        log.error("閿欒鐮�: {}, 閿欒淇℃伅: {}", result.getInteger("code"), result.getString("msg"));
+                    }
+                    break;
+                }
+            } while (pageToken != null && !pageToken.isEmpty());
+
+            log.info("鑾峰彇椋炰功閮ㄩ棬鐢ㄦ埛瀹屾垚锛屾�荤敤鎴锋暟閲�: {}", userList.size());
+
+        } catch (Exception e) {
+            log.error("鑾峰彇椋炰功閮ㄩ棬鐢ㄦ埛鍒楄〃寮傚父", e);
+        }
+        return userList;
+    }
+
+    /**
+     * 瑙f瀽鐢ㄦ埛鏁版嵁
+     */
+    /**
+     * 瑙f瀽鐢ㄦ埛鏁版嵁
+     */
+    @SuppressWarnings("unchecked")
+    private List<FeishuUser> parseUsers(Object items) {
+        Logger log = LoggerFactory.getLogger(FeishuUserService.class);
+        List<FeishuUser> userList = new ArrayList<>();
+        if (!(items instanceof List)) {
+            log.warn("瑙f瀽鐢ㄦ埛鏁版嵁澶辫触锛宨tems涓嶆槸鍒楄〃绫诲瀷: {}", items);
+            return userList;
+        }
+        List<?> userItems = (List<?>) items;
+        log.info("寮�濮嬭В鏋愰涔︾敤鎴峰垪琛紝鍏眥}鏉¤褰�", userItems.size());
+        for (Object item : userItems) {
+            if (item == null || !(item instanceof Map)) {
+                log.warn("璺宠繃鏃犳晥鐢ㄦ埛鏁版嵁椤癸紝绫诲瀷涓嶅尮閰�: {}", item != null ? item.getClass() : "null");
+                continue;
+            }
+            Map<String, Object> userMap = (Map<String, Object>) item;
+            FeishuUser user = new FeishuUser();
+            // 瑙f瀽open_id
+            user.setOpenId((String) userMap.getOrDefault("open_id", ""));
+            // 瑙f瀽name骞舵媶鍒�
+            String name = (String) userMap.getOrDefault("name", "");
+            if (name.contains(" ")) {
+                String[] parts = name.split(" ");
+                if (parts.length == 2) {
+                    user.setUsername(parts[0].trim()); // 宸ュ彿閮ㄥ垎瀛樺埌username
+                    user.setRealname(parts[1].trim()); // 濮撳悕閮ㄥ垎瀛樺埌realname
+                    user.setWorkNo(parts[0].trim());   // 宸ュ彿涔熷瓨鍒皐orkNo
+                } else {
+                    // 鎷嗗垎寮傚父鏃讹紝榛樿澶勭悊
+                    user.setUsername(name);
+                    user.setRealname(name);
+                    user.setWorkNo("");
+                    log.warn("椋炰功鐢ㄦ埛name瀛楁鏍煎紡寮傚父锛屾棤娉曟媶鍒嗭紝鍘熷鍊硷細{}", name);
+                }
+            } else {
+                user.setUsername(name);
+                user.setRealname(name);
+                user.setWorkNo("");
+                log.warn("椋炰功鐢ㄦ埛name瀛楁鏃犵┖鏍煎垎闅旓紝鏃犳硶鎷嗗垎锛屽師濮嬪�硷細{}", name);
+            }
+            // 瑙f瀽鍏朵粬鍩烘湰淇℃伅
+            user.setEnName((String) userMap.getOrDefault("en_name", ""));
+            user.setDescription((String) userMap.getOrDefault("description", ""));
+            Object mobileVisibleObj = userMap.get("mobile_visible");
+            user.setMobileVisible(mobileVisibleObj instanceof Boolean ? (Boolean) mobileVisibleObj : false);
+            // 瑙f瀽澶村儚淇℃伅
+            Object avatarObj = userMap.get("avatar");
+            if (avatarObj instanceof Map) {
+                Map<String, Object> avatarMap = (Map<String, Object>) avatarObj;
+                user.setAvatar240((String) avatarMap.getOrDefault("avatar_240", ""));
+                user.setAvatar640((String) avatarMap.getOrDefault("avatar_640", ""));
+                user.setAvatar72((String) avatarMap.getOrDefault("avatar_72", ""));
+                user.setAvatarOrigin((String) avatarMap.getOrDefault("avatar_origin", ""));
+            } else {
+                log.info("鐢ㄦ埛[{}]鏈缃ご鍍忔垨澶村儚鏍煎紡寮傚父", user.getRealname());
+            }
+            // 璁剧疆榛樿鍔犲瘑瀵嗙爜锛堣繖閲屽亣璁惧瘑鐮佹槸绠�鍗曞姞瀵嗗瓨鍌紝瀹為檯寤鸿鐢ㄦ洿瀹夊叏鐨勫姞瀵嗘柟寮忥級
+            user.setPassword("123456"); // 浣犺姹傜殑榛樿瀵嗙爜
+            // 灏唎pen_id瀛樺埌瀵瑰簲鐨勫瓧娈碉紙鏍规嵁浣犵殑鐢ㄦ埛琛ㄧ粨鏋勶紝鍋囪鐢ㄦ埛琛ㄦ湁open_id瀛楁锛�
+            user.setOpenId((String) userMap.getOrDefault("open_id", ""));
+            userList.add(user);
+        }
+
+        return userList;
+    }
+
+    /**
+     * 鍚屾鍗曚釜椋炰功鐢ㄦ埛鍒扮郴缁�
+     * @param feishuUser 椋炰功鐢ㄦ埛
+     * @return true琛ㄧず鏇存柊锛宖alse琛ㄧず鏂板
+     *
+     * 鍚庢湡澧炲姞锛� 鐢ㄦ埛鍚屾瀵规瘮锛岄涔︾鑱屽憳宸ラ渶瑕佸湪鏈湴鐢ㄦ埛琛ㄩ噷闈㈠皢璇ョ敤鎴风姸鎬佺鐢�
+     */
+    private boolean syncFeishuUserToSystem(FeishuUser feishuUser) {
+        // 杩欓噷鏍规嵁鎷嗗垎鍚庣殑username锛堝伐鍙凤級鍘绘煡璇㈢郴缁熺敤鎴�
+        String username = feishuUser.getUsername();
+        SysUser existUser = sysUserService.getUserByName(username);
+        SysUser sysUser = new SysUser();
+        sysUser.setUsername(username);
+        sysUser.setStatus(1);
+        sysUser.setDelFlag(0);
+        sysUser.setAvatar(feishuUser.getAvatar640());
+        sysUser.setRealname(feishuUser.getRealname());
+        sysUser.setWorkNo(feishuUser.getWorkNo());
+        String password = "123456", salt = oConvertUtils.randomGen(8);
+        String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), password, salt);
+        sysUser.setSalt(salt);
+        sysUser.setPassword(passwordEncode);
+        sysUser.setOpenId(feishuUser.getOpenId());
+
+        if (existUser == null) {
+
+            sysUserService.addUserWithRole(sysUser, "5");
+            log.info("鏂板鐢ㄦ埛: {}", username);
+            return false;
+        } else {
+            sysUser.setId(existUser.getId());
+            sysUserService.editUser(sysUser);
+            log.info("鏇存柊鐢ㄦ埛: {}", username);
+            return true;
+        }
+    }
+}
diff --git a/src/main/java/org/jeecg/modules/system/entity/SysUser.java b/src/main/java/org/jeecg/modules/system/entity/SysUser.java
index 233d20b..3d2db93 100644
--- a/src/main/java/org/jeecg/modules/system/entity/SysUser.java
+++ b/src/main/java/org/jeecg/modules/system/entity/SysUser.java
@@ -125,6 +125,12 @@
     @Excel(name = "宸ュ彿", width = 15)
     private String workNo;
 
+
+    /**
+     * 椋炰功id锛屽敮涓�閿�
+     */
+    @Excel(name = "椋炰功id", width = 15)
+    private String openId;
     /**
      * 鑱屽姟锛屽叧鑱旇亴鍔¤〃
      */
diff --git a/src/main/java/org/jeecg/modules/system/service/ISysUserService.java b/src/main/java/org/jeecg/modules/system/service/ISysUserService.java
index 3ab96db..f70dfa9 100644
--- a/src/main/java/org/jeecg/modules/system/service/ISysUserService.java
+++ b/src/main/java/org/jeecg/modules/system/service/ISysUserService.java
@@ -363,4 +363,6 @@
 	 * @return
 	 */
 	IPage<SysUser> getUserByFactoryId(Page<SysUser> page, String factoryId, String username);
+
+    void editUser(SysUser sysUser);
 }
diff --git a/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java b/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java
index 1fd0c21..d605ced 100644
--- a/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java
+++ b/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java
@@ -832,4 +832,9 @@
 	public IPage<SysUser> getUserByFactoryId(Page<SysUser> page, String factoryId, String username) {
 		return userMapper.getUserByFactoryId(page,factoryId,username);
 	}
+
+	@Override
+	public void editUser(SysUser sysUser) {
+		userMapper.updateById(sysUser);
+	}
 }

--
Gitblit v1.9.3