src/main/java/org/jeecg/modules/andon/controller/AndonButtonConfigController.java
@@ -2,6 +2,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -12,7 +13,9 @@ 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.dto.AndonButtonDTO; import org.jeecg.modules.andon.entity.AndonButtonConfig; import org.jeecg.modules.andon.entity.AndonOrder; import org.jeecg.modules.andon.service.IAndonButtonConfigService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -21,6 +24,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Arrays; import java.util.List; /** * @Description: å®ç¯æé®é ç½® @@ -61,33 +65,21 @@ /** * APPå页å表æ¥è¯¢ * APPå®ç¯æé®å表æ¥è¯¢ * * @param andonButtonConfig * @param pageNo * @param pageSize * @param req * @param factoryId * @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()); @GetMapping(value = "/queryUserAndonButtonList") public Result<List<AndonButtonDTO>> queryUserAndonButtonList(@RequestParam("factoryId") String factoryId) { List<AndonButtonDTO> list = andonButtonConfigService.queryUserAndonButtonList(factoryId); return Result.OK(list); } Page<AndonButtonConfig> page = new Page<AndonButtonConfig>(pageNo, pageSize); IPage<AndonButtonConfig> pageList = andonButtonConfigService.page(page, queryWrapper); return Result.OK(pageList); } /** * æ·»å src/main/java/org/jeecg/modules/andon/controller/AndonOrderController.java
@@ -56,6 +56,8 @@ return Result.OK(pageList); } /** * æ·»å * @@ -64,13 +66,14 @@ */ @AutoLog(value = "å®ç¯å·¥å-æ·»å ") @ApiOperation(value="å®ç¯å·¥å-æ·»å ", notes="å®ç¯å·¥å-æ·»å ") //@RequiresPermissions("org.jeecg.modules:andon_order:add") @PostMapping(value = "/add") public Result<String> add(@RequestBody AndonOrder andonOrder) { andonOrderService.save(andonOrder); return Result.OK("æ·»å æåï¼"); } /** * ç¼è¾ * src/main/java/org/jeecg/modules/andon/controller/AndonResponseConfigController.java
@@ -10,6 +10,7 @@ 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.modules.andon.dto.AndonButtonDTO; import org.jeecg.modules.andon.entity.AndonResponseConfig; import org.jeecg.modules.andon.service.IAndonResponseConfigService; import org.springframework.beans.factory.annotation.Autowired; @@ -19,6 +20,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Arrays; import java.util.List; /** * @Description: å®ç¯ååºé ç½® @@ -56,6 +58,28 @@ return Result.OK(pageList); } /** * åéå®ç¯æ¶æ¯ * * @param andonButtonDTO * @return */ @AutoLog(value = "å®ç¯å·¥å-åéé£ä¹¦æ¶æ¯") @ApiOperation(value = "å®ç¯å·¥å-åéé£ä¹¦æ¶æ¯", notes = "å®ç¯å·¥å-åéé£ä¹¦æ¶æ¯") @PostMapping(value = "/sendMessage") public Result<String> sendMessage(@RequestBody AndonButtonDTO andonButtonDTO) { try { andonButtonDTO.setBlinkingFlag(1); // è°ç¨æå¡å±å¤çä¸å¡é»è¾ andonResponseConfigService.sendAndonNotification(andonButtonDTO); return Result.OK("æ·»å æåï¼"); } catch (Exception e) { log.error("å®ç¯å·¥å[{}]é£ä¹¦éç¥åé失败", andonButtonDTO.getId(), e); return Result.error("åéæ¶æ¯å¤±è´¥: " + e.getMessage()); } } /** * æ·»å * @@ -64,7 +88,6 @@ */ @AutoLog(value = "å®ç¯ååºé ç½®-æ·»å ") @ApiOperation(value="å®ç¯ååºé ç½®-æ·»å ", notes="å®ç¯ååºé ç½®-æ·»å ") //@RequiresPermissions("org.jeecg.modules:andon_response_config:add") @PostMapping(value = "/add") public Result<String> add(@RequestBody AndonResponseConfig andonResponseConfig) { andonResponseConfigService.save(andonResponseConfig); @@ -158,4 +181,18 @@ return super.importExcel(request, response, AndonResponseConfig.class); } /** * APPå®ç¯æé®å表æ¥è¯¢ * * @param factoryId * @return */ @ApiOperation(value = "å®ç¯æé®é ç½®-å表æ¥è¯¢", notes = "å®ç¯æé®é ç½®-å表æ¥è¯¢") @GetMapping(value = "/queryAndonButtonList") public Result<List<AndonButtonDTO>> queryAndonButtonList(@RequestParam("factoryId") String factoryId) { List<AndonButtonDTO> list = andonResponseConfigService.queryAndonButtonList(factoryId); return Result.OK(list); } } src/main/java/org/jeecg/modules/andon/dto/AndonButtonDTO.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,80 @@ package org.jeecg.modules.andon.dto; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.jeecg.common.aspect.annotation.Dict; import org.jeecgframework.poi.excel.annotation.Excel; @Data public class AndonButtonDTO { /** ååºID */ @ApiModelProperty(value = "ååºID") private String id; /** æé®ID */ @ApiModelProperty(value = " æé®ID ") private String buttonId; /**å®ç¯åç§°*/ @ApiModelProperty(value = "å®ç¯åç§°") private String buttonName; /**å®ç¯ç¼ç */ @ApiModelProperty(value = "å®ç¯ç¼ç ") private String buttonCode; /** ä¸çº§ååºäºº */ @ApiModelProperty(value = "ä¸çº§ååºäºº") private String responder; @ApiModelProperty(value = "äºçº§ååºäºº") private String secondResponder; /**产线åç§°*/ @ApiModelProperty(value = "产线åç§°") private String factoryName; /**产线åç§°*/ @ApiModelProperty(value = "å·¥ååç§°") private String parentFactoryName; /**ä¸çº§ååºæ¶é¿*/ @ApiModelProperty(value = "ä¸çº§ååºæ¶é¿") private Integer upgradeResponseDuration; /**äºçº§ååºæ¶é¿*/ @ApiModelProperty(value = "äºçº§ååºæ¶é¿") private Integer secondUpgradeResponseDuration; /**ä¸çº§çº§ååºæ¶é¿*/ @ApiModelProperty(value = "ä¸çº§ååºæ¶é¿") private Integer thirdUpgradeResponseDuration; /** * æ¯å¦éªç * å¯¹åºæ°æ®åºè¡¨ä¸ is_blinking åæ®µï¼å¤§äº0 æå¾ å¤ççå·¥åéªï¼ç¸åä¸éªçï¼ */ @ApiModelProperty(value = "æ è¯éªç") private Integer blinkingFlag; @ApiModelProperty(value = "ä¸çº§ååºäººopenId") private String responderOpenId; @ApiModelProperty(value = "äºçº§ååºäººopenId") private String secondResponderOpenId; @ApiModelProperty(value = "ä¸çº§ååºäººopenId") private String thirdResponderOpenId; @ApiModelProperty(value = "ä¸çº§ååºäºº") private String thirdResponder; @ApiModelProperty(value = "å·¥åID") private String orderIds; @ApiModelProperty(value = "å·¥åç¶æ") private String orderStatus; } src/main/java/org/jeecg/modules/andon/entity/AndonButtonConfig.java
@@ -1,12 +1,10 @@ package org.jeecg.modules.andon.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.*; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import liquibase.pro.packaged.B; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; @@ -89,4 +87,13 @@ @Excel(name = "夿³¨", width = 15) @ApiModelProperty(value = "夿³¨") private String remark; /** * æ¯å¦éªç * å¯¹åºæ°æ®åºè¡¨ä¸ is_blinking åæ®µï¼tinyintç±»åï¼é»è®¤å¼0ï¼ */ @ApiModelProperty(value = "æ è¯éªç") @TableField(exist = false) private boolean blinkingFlag; } src/main/java/org/jeecg/modules/andon/entity/AndonResponseConfig.java
@@ -78,4 +78,7 @@ @Excel(name = "ä¸çº§ååºäºº(å级两次)", width = 15) @ApiModelProperty(value = "ä¸çº§ååºäºº(å级两次)") private String thirdResponder; } src/main/java/org/jeecg/modules/andon/mapper/AndonButtonConfigMapper.java
@@ -2,7 +2,10 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Param; import org.jeecg.modules.andon.dto.AndonButtonDTO; import org.jeecg.modules.andon.entity.AndonButtonConfig; import java.util.List; /** * @Description: å®ç¯æé®é ç½® @@ -12,4 +15,10 @@ */ public interface AndonButtonConfigMapper extends BaseMapper<AndonButtonConfig> { AndonButtonConfig getAndonButtonById(@Param("id") String id); /** * å®ç¯æé®å表 * @param factoryId * @return */ List<AndonButtonDTO> queryUserAndonButtonList(String factoryId); } src/main/java/org/jeecg/modules/andon/mapper/AndonResponseConfigMapper.java
@@ -2,7 +2,10 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Param; import org.jeecg.modules.andon.dto.AndonButtonDTO; import org.jeecg.modules.andon.entity.AndonResponseConfig; import java.util.List; /** * @Description: å®ç¯ååºé ç½® @@ -12,4 +15,5 @@ */ public interface AndonResponseConfigMapper extends BaseMapper<AndonResponseConfig> { AndonResponseConfig getAndonResponseConfigByFactoryIdAndButtonId(@Param("factoryId") String factoryId, @Param("buttonId") String buttonId); } src/main/java/org/jeecg/modules/andon/mapper/xml/AndonButtonConfigMapper.xml
@@ -4,4 +4,24 @@ <select id="getAndonButtonById" resultType="org.jeecg.modules.andon.entity.AndonButtonConfig"> SELECT * FROM andon_button_config WHERE id = #{id} and del_flag = 0 and button_status = 'å¯ç¨' </select> <select id="queryUserAndonButtonList" resultType="org.jeecg.modules.andon.dto.AndonButtonDTO"> select arc.id, abc.id as button_id, abc.button_name, abc.button_code, (select count(1) from andon_order ao where ao.button_id = arc.button_id and ao.factory_id = arc.factory_id and ao.order_status != '3') as blinking_flag, STUFF((SELECT ',' + CAST(ao.id AS VARCHAR) FROM andon_order ao WHERE ao.button_id = arc.button_id and ao.factory_id = arc.factory_id FOR XML PATH('')), 1, 1, '') as order_ids from andon_response_config arc left join andon_button_config abc on arc.button_id = abc.id where arc.factory_id=#{factoryId}; </select> </mapper> src/main/java/org/jeecg/modules/andon/mapper/xml/AndonResponseConfigMapper.xml
@@ -1,7 +1,13 @@ <?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="org.jeecg.modules.andon.mapper.AndonResponseConfigMapper"> <select id="getAndonResponseConfigByFactoryIdAndButtonId" resultType="org.jeecg.modules.andon.entity.AndonResponseConfig"> SELECT * FROM andon_response_config WHERE factory_id = #{factoryId} AND button_id = #{buttonId} AND del_flag = 0 <select id="getAndonResponseConfigByFactoryIdAndButtonId" resultType="org.jeecg.modules.andon.entity.AndonResponseConfig"> SELECT * FROM andon_response_config WHERE factory_id = #{factoryId} AND button_id = #{buttonId} AND del_flag = 0 </select> </mapper> src/main/java/org/jeecg/modules/andon/service/IAndonButtonConfigService.java
@@ -1,7 +1,10 @@ package org.jeecg.modules.andon.service; import com.baomidou.mybatisplus.extension.service.IService; import org.jeecg.modules.andon.dto.AndonButtonDTO; import org.jeecg.modules.andon.entity.AndonButtonConfig; import java.util.List; /** * @Description: å®ç¯æé®é ç½® @@ -11,4 +14,11 @@ */ public interface IAndonButtonConfigService extends IService<AndonButtonConfig> { AndonButtonConfig getAndonButtonById(String id); /** * æ¥è¯¢ç¨æ·å®ç¯æé®å表 * @param factoryId * @return */ List<AndonButtonDTO> queryUserAndonButtonList(String factoryId); } src/main/java/org/jeecg/modules/andon/service/IAndonOrderService.java
@@ -14,4 +14,12 @@ public interface IAndonOrderService extends IService<AndonOrder> { //å·²å®æç¶æé¤å¤ List<AndonOrder> getAndonOrdersExceptYWC(); /** * è·åå·¥åçåå§ååºäºº * @param andonOrder * @return */ String getPrimaryResponder(AndonOrder andonOrder); } src/main/java/org/jeecg/modules/andon/service/IAndonResponseConfigService.java
@@ -1,7 +1,10 @@ package org.jeecg.modules.andon.service; import com.baomidou.mybatisplus.extension.service.IService; import org.jeecg.modules.andon.dto.AndonButtonDTO; import org.jeecg.modules.andon.entity.AndonResponseConfig; import java.util.List; /** * @Description: å®ç¯ååºé ç½® @@ -11,4 +14,19 @@ */ public interface IAndonResponseConfigService extends IService<AndonResponseConfig> { AndonResponseConfig getAndonResponseConfigByFactoryIdAndButtonId(String factoryId, String buttonId); /** * æ ¹æ®å·¥åidæ¥è¯¢æé®å表 * @param factoryId å·¥åid * @return */ List<AndonButtonDTO> queryAndonButtonList(String factoryId); /** * åéå®ç¯éç¥ * @param andonButtonDTO å®ç¯æé®DTO * @return ç»æ */ void sendAndonNotification(AndonButtonDTO andonButtonDTO); } src/main/java/org/jeecg/modules/andon/service/impl/AndonButtonConfigServiceImpl.java
@@ -1,10 +1,14 @@ package org.jeecg.modules.andon.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.jeecg.modules.andon.dto.AndonButtonDTO; import org.jeecg.modules.andon.entity.AndonButtonConfig; import org.jeecg.modules.andon.mapper.AndonButtonConfigMapper; import org.jeecg.modules.andon.service.IAndonButtonConfigService; import org.springframework.stereotype.Service; import java.util.Collections; import java.util.List; /** * @Description: å®ç¯æé®é ç½® @@ -19,4 +23,11 @@ public AndonButtonConfig getAndonButtonById(String id) { return baseMapper.getAndonButtonById(id); } @Override public List<AndonButtonDTO> queryUserAndonButtonList(String factoryId) { return baseMapper.queryUserAndonButtonList(factoryId); } } src/main/java/org/jeecg/modules/andon/service/impl/AndonOrderServiceImpl.java
@@ -1,9 +1,16 @@ package org.jeecg.modules.andon.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.jeecg.modules.andon.entity.AndonResponseConfig; import org.jeecg.modules.andon.mapper.AndonResponseConfigMapper; import org.jeecg.modules.andon.service.IAndonOrderService; import org.jeecg.modules.andon.entity.AndonOrder; import org.jeecg.modules.andon.mapper.AndonOrderMapper; import org.jeecg.modules.feishu.service.FeishuUserService; import org.jeecg.modules.system.service.ISysUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @@ -16,9 +23,41 @@ */ @Service public class AndonOrderServiceImpl extends ServiceImpl<AndonOrderMapper, AndonOrder> implements IAndonOrderService { @Autowired private FeishuUserService feishuService; @Autowired private ISysUserService sysUserService; @Autowired private AndonResponseConfigMapper andonResponseConfigMapper; @Override public List<AndonOrder> getAndonOrdersExceptYWC() { return baseMapper.getAndonOrdersExceptYWC(); } @Override public String getPrimaryResponder(AndonOrder andonOrder) { // 1. æ ¡éªå¿ è¦åæ° if (StringUtils.isBlank(andonOrder.getFactoryId()) || StringUtils.isBlank(andonOrder.getButtonId())) { return null; } // 2. æ¥è¯¢ååºäººé ç½®ï¼å设åå¨ååºäººé ç½®å®ä½åMapperï¼ // æå»ºæ¥è¯¢æ¡ä»¶ï¼å¹é 产线IDãå®ç¯ç±»åIDï¼ä¸é 置为å¯ç¨ç¶æ QueryWrapper<AndonResponseConfig> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("factory_id", andonOrder.getFactoryId()) .eq("button_id", andonOrder.getButtonId()) .eq("status", 1) // 1表示å¯ç¨ç¶æ .last("limit 1"); // åªå䏿¡ææé ç½® // 3. æ§è¡æ¥è¯¢ AndonResponseConfig config = andonResponseConfigMapper.selectOne(queryWrapper); if (config == null) { return null; } return config.getFirsterResponder(); } } src/main/java/org/jeecg/modules/andon/service/impl/AndonResponseConfigServiceImpl.java
@@ -1,10 +1,26 @@ package org.jeecg.modules.andon.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.apache.commons.lang.StringUtils; import org.jeecg.modules.andon.dto.AndonButtonDTO; import org.jeecg.modules.andon.entity.AndonButtonConfig; import org.jeecg.modules.andon.entity.AndonOrder; import org.jeecg.modules.andon.entity.AndonResponseConfig; import org.jeecg.modules.andon.mapper.AndonResponseConfigMapper; import org.jeecg.modules.andon.service.IAndonButtonConfigService; import org.jeecg.modules.andon.service.IAndonOrderService; import org.jeecg.modules.andon.service.IAndonResponseConfigService; import org.jeecg.modules.base.entity.Factory; import org.jeecg.modules.base.service.IFactoryService; import org.jeecg.modules.feishu.service.FeishuUserService; import org.jeecg.modules.system.entity.SysUser; import org.jeecg.modules.system.service.ISysUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Collections; import java.util.List; /** * @Description: å®ç¯ååºé ç½® @@ -14,9 +30,175 @@ */ @Service public class AndonResponseConfigServiceImpl extends ServiceImpl<AndonResponseConfigMapper, AndonResponseConfig> implements IAndonResponseConfigService { @Autowired private IFactoryService factoryService; @Autowired private ISysUserService iSysUserService; @Autowired private FeishuUserService feishuUserService; @Autowired private IAndonButtonConfigService andonButtonConfigService; @Autowired private IAndonOrderService andonOrderService; @Override public AndonResponseConfig getAndonResponseConfigByFactoryIdAndButtonId(String factoryId, String buttonId) { return baseMapper.getAndonResponseConfigByFactoryIdAndButtonId(factoryId,buttonId); } @Override public List<AndonButtonDTO> queryAndonButtonList(String factoryId) { return Collections.emptyList(); } @Override public void sendAndonNotification(AndonButtonDTO andonButtonDTO) { /** * 1. éªè¯å·¥åç¶æ */ if (andonButtonDTO == null) { log.warn("请æ±åæ°ä¸ºç©º"); throw new IllegalArgumentException("请æ±åæ°ä¸è½ä¸ºç©º"); } /** * 2. è·åååºé ç½® */ AndonResponseConfig andonResponseConfig = this.getById(andonButtonDTO.getId()); AndonOrder andonOrder = andonOrderService.getById(andonButtonDTO.getOrderIds()); if (andonOrder == null) { log.warn("æªæ¾å°ID为[{}]çå®ç¯è®¢å"); throw new IllegalArgumentException("æªæ¾å°å¯¹åºçå®ç¯è®¢å"); } String orderStatus = andonOrder.getOrderStatus(); andonButtonDTO.setOrderStatus(orderStatus); if (andonResponseConfig == null) { log.warn("æªæ¾å°ID为[{}]çååºé ç½®"); throw new IllegalArgumentException("æªæ¾å°å¯¹åºçååºé ç½®"); } /** * 3. 设置äºçº§ååºäºº */ String secondResponder = andonResponseConfig.getSecondResponder(); if (StringUtils.isNotBlank(secondResponder)) { andonButtonDTO.setSecondResponder(secondResponder); } /** * 4. è·åå·¥åä¿¡æ¯ */ String factoryId = andonResponseConfig.getFactoryId(); if (factoryId == null || factoryId.isEmpty()) { log.warn("ååºé ç½®[{}]æªè®¾ç½®å·¥åID"); throw new IllegalArgumentException("ååºé ç½®æªè®¾ç½®å·¥åä¿¡æ¯"); } Factory factory = factoryService.getOne(new QueryWrapper<Factory>() .eq("id", factoryId) .eq("del_flag", 0)); if (factory == null) { log.warn("æªæ¾å°ID为[{}]çå·¥å"); throw new IllegalArgumentException("æªæ¾å°å¯¹åºçå·¥åä¿¡æ¯"); } /** * è·å产线åç§° */ String factoryName = factory.getFactoryName(); andonButtonDTO.setFactoryName(factoryName); /** * 6. 设置工ååç§° */ String parentId = factory.getParentId(); if (parentId != null && !parentId.isEmpty()) { Factory parentFactory = factoryService.getOne(new QueryWrapper<Factory>() .eq("id", parentId) .eq("del_flag", 0)); if (parentFactory != null) { andonButtonDTO.setParentFactoryName(parentFactory.getFactoryName()); } } /** * 6. è·åå®ç¯æé®é ç½® */ AndonButtonConfig andonButtonById = andonButtonConfigService.getAndonButtonById(andonButtonDTO.getButtonId()); if (andonButtonById == null) { log.warn("æªæ¾å°ID为[{}]çå®ç¯æé®"); throw new IllegalArgumentException("æªæ¾å°å¯¹åºçå®ç¯æé®ä¿¡æ¯"); } /** * 7. 设置ååºæ¶é´ */ Integer upgradeResponseDuration = andonButtonById.getUpgradeResponseDuration(); andonButtonDTO.setUpgradeResponseDuration(upgradeResponseDuration); Integer secondUpgradeResponseDuration = andonButtonById.getSecondUpgradeResponseDuration(); andonButtonDTO.setSecondUpgradeResponseDuration(secondUpgradeResponseDuration); /** * 8. è·åååºäººä¿¡æ¯ */ String firstResponder = andonResponseConfig.getFirsterResponder(); String threeResponder = andonResponseConfig.getThirdResponder(); SysUser thirdUser = iSysUserService.getUserByName(threeResponder); SysUser userByName = iSysUserService.getUserByName(firstResponder); SysUser secondUser = null; if (StringUtils.isNotBlank(secondResponder)) { secondUser = iSysUserService.getUserByName(secondResponder); } /** * 9. éªè¯å¹¶è®¾ç½®ååºäººä¿¡æ¯ */ if (userByName == null) { log.warn("ç¨æ·[{}]æªæ¾å°ï¼æ æ³åééç¥"); throw new IllegalArgumentException("ç¨æ·[{}]æªæ¾å°ï¼æ æ³åééç¥"); } if (secondUser == null && StringUtils.isNotBlank(secondResponder)) { log.warn("ç¨æ·[{}]æªæ¾å°ï¼æ æ³åééç¥"); throw new IllegalArgumentException("ç¨æ·[{}]æªæ¾å°ï¼æ æ³åééç¥"); } if (threeResponder == null) { StringUtils.isNotBlank(null); } // /** * 10. 设置ååºäººç¸å ³ä¿¡æ¯ */ andonButtonDTO.setResponderOpenId(userByName.getOpenId()); andonButtonDTO.setResponder(userByName.getRealname()); log.warn("ç¨æ·[{}]å·²æ¾å°ï¼å¼å§åééç¥"); if (secondUser != null) { andonButtonDTO.setSecondResponderOpenId(secondUser.getOpenId()); andonButtonDTO.setSecondResponder(secondUser.getRealname()); log.warn("ç¨æ·[{}]å·²æ¾å°ï¼å¼å§åééç¥"); } if (thirdUser != null) { andonButtonDTO.setThirdResponderOpenId(thirdUser.getOpenId()); andonButtonDTO.setThirdResponder(thirdUser.getRealname()); log.warn("ç¨æ·[{}]å·²æ¾å°ï¼å¼å§åééç¥"); } /** * 11. åéé£ä¹¦éç¥ */ if (StringUtils.isNotBlank(firstResponder)) { String feishuAccessToken = feishuUserService.getFeishuAccessToken(); feishuUserService.sendAndonNotification(feishuAccessToken, andonButtonDTO); } else { log.warn("å·¥å[{}]æªæ¾å°å¯¹åºååºäººï¼æ æ³åééç¥"); } } } src/main/java/org/jeecg/modules/feishu/job/FeishuSyncTask.java
ÎļþÃû´Ó src/main/java/org/jeecg/modules/mes/job/FeishuSyncTask.java ÐÞ¸Ä @@ -1,7 +1,8 @@ package org.jeecg.modules.mes.job; package org.jeecg.modules.feishu.job; import lombok.extern.slf4j.Slf4j; import org.jeecg.modules.feishu.service.FeishuUserService; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; @@ -17,7 +18,7 @@ public class FeishuSyncTask implements Job { @Autowired private org.jeecg.modules.mes.job.FeishuUserService feishuUserService; private FeishuUserService feishuUserService; @Value("${feishu.sync.departmentId:0}") private String departmentId; src/main/java/org/jeecg/modules/feishu/service/FeishuUserService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,635 @@ package org.jeecg.modules.feishu.service; 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.andon.dto.AndonButtonDTO; 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.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @Service @Slf4j public class FeishuUserService { // ç±»ä¸å®ä¹æ¨¡æ¿å¸¸éï¼ä¾¿äºç»´æ¤ï¼ private static final String FIRST_LEVEL_TEMPLATE = "ãå·¥èºå®ç¯ã\n%s · %s åèµ·äºå·¥èºå®ç¯ï¼è¯·%dåéå å¨PDAä¸è¿è¡ååºå¤çï¼ï¼ï¼"; private static final String SECOND_LEVEL_TEMPLATE = "ãå·¥èºå®ç¯ã\n%s · %s åèµ·çå·¥èºå®ç¯ï¼%sæªå¨%dåéå ååºï¼è¯·å°½å¿«ç£ä¿è¿è¡ååºå¤çï¼ï¼ï¼"; @Resource private ISysUserService sysUserService; @Resource private RestTemplate restTemplate; @Value("${feishu.appId:}") private String appId; @Value("${feishu.appSecret:}") private String appSecret; @Value("${feishu.url:}") private String feishuUrl; // 宿¶ä»»å¡çº¿ç¨æ± ï¼æ¯æå¤çº§ååºè°åº¦ï¼ private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5); private final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); /** * 忥é£ä¹¦é¨é¨ç¨æ·å°ç³»ç»ç¨æ·è¡¨ */ 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("忥é£ä¹¦ç¨æ·å¤±è´¥ï¼ç¨æ·ID: {}", feishuUser.getUserId(), e); } } log.info("é£ä¹¦ç¨æ·åæ¥å®æï¼æ»å¤ç: {}ï¼æ°å¢: {}ï¼æ´æ°: {}", successCount, addCount, updateCount); } catch (Exception e) { log.error("忥é£ä¹¦é¨é¨ç¨æ·å¤±è´¥ï¼é¨é¨ID: {}", departmentId, e); throw new RuntimeException("忥é£ä¹¦ç¨æ·å¤±è´¥: " + e.getMessage()); } } public String getFeishuAccessToken() { try { String url = feishuUrl + "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; } } /** * åéå®ç¯éç¥æ¶æ¯ï¼æ¯æä¸ãäºãä¸çº§ååºï¼ * æµç¨ï¼ * 1. APPç¹å»åéä¸çº§ååºï¼å级ååºï¼ * 2. ä¸çº§ååºæ¶é¿åæ£æ¥ç¶æï¼æªå¤çååéäºçº§ * 3. äºçº§ååºæ¶é¿åæ£æ¥ç¶æï¼æªå¤çååéä¸çº§ */ public boolean sendAndonNotification(String accessToken, AndonButtonDTO andonOrde) { try { String currentTime = sdf.format(new Date()); log.info("ã{}ã触åä¸çº§ååºï¼å级ååºï¼ï¼å®ç¯ID: {}", currentTime, andonOrde.getId()); // 1. åæ°éªè¯ if (!validateNotificationParams(andonOrde)) { return false; } if (accessToken == null || accessToken.isEmpty()) { log.error("访é®ä»¤çä¸ºç©ºï¼æ æ³åéå®ç¯éç¥"); return false; } // 2. åéä¸çº§ååºéç¥ï¼å³æ¶åéï¼ boolean firstLevelResult = sendLevelNotification(accessToken, andonOrde, 1); // 3. è°åº¦äºçº§ååºéç¥ï¼å»¶è¿æ¶é´=ä¸çº§ååºæ¶é¿ï¼ if (firstLevelResult) { int secondDelay = andonOrde.getUpgradeResponseDuration(); String secondTime = sdf.format(new Date(System.currentTimeMillis() + secondDelay * 60 * 1000L)); log.info("ã{}ãä¸çº§ååºè°åº¦äºçº§éç¥ï¼å»¶è¿{}åéï¼é¢è®¡åéæ¶é´: {}", currentTime, secondDelay, secondTime); scheduleNextLevelNotification(accessToken, andonOrde, 1, secondDelay); } else { log.warn("ä¸çº§éç¥åé失败ï¼ç»æ¢åç»éç¥æµç¨ï¼å®ç¯ID: {}", andonOrde.getId()); } return firstLevelResult; } catch (Exception e) { log.error("å¤çå®ç¯éç¥å¼å¸¸ï¼å®ç¯ID: {}", andonOrde != null ? andonOrde.getId() : "æªç¥", e); return false; } } /** * åéæå®çº§å«çéç¥ * @param level 1-ä¸çº§ï¼2-äºçº§ï¼3-ä¸çº§ */ private boolean sendLevelNotification(String accessToken, AndonButtonDTO andonOrde, int level) { try { String levelDesc = getLevelDesc(level); String openId = getResponderOpenId(andonOrde, level); String currentTime = sdf.format(new Date()); log.info("ã{}ãå¼å§åé{}级å®ç¯éç¥ï¼æ¥æ¶äººopenId: {}, å®ç¯ID: {}", currentTime, levelDesc, openId, andonOrde.getId()); // æå»ºè¯·æ±URL String url = feishuUrl + "open-apis/im/v1/messages?receive_id_type=open_id"; log.info("{}级éç¥è¯·æ±URL: {}", levelDesc, url); // 设置请æ±å¤´ HttpHeaders headers = new HttpHeaders(); String authHeader = "Bearer " + accessToken; headers.add("Authorization", authHeader); headers.add("Content-Type", "application/json; charset=utf-8"); log.info("设置{}级éç¥è¯·æ±å¤´: Authorization = {}", levelDesc, authHeader.substring(0, Math.min(30, authHeader.length())) + "..."); // æå»ºæ¶æ¯å 容 JSONObject content = new JSONObject(); String notificationContent = buildNotificationContent(andonOrde, level); content.put("text", notificationContent); log.debug("ã{}ã{}级éç¥å 容: {}", currentTime, levelDesc, notificationContent); // æå»ºè¯·æ±ä½ JSONObject requestBody = new JSONObject(); requestBody.put("receive_id", openId); requestBody.put("msg_type", "text"); requestBody.put("content", content.toJSONString()); requestBody.put("uuid", "andon_" + andonOrde.getId() + "_level_" + level + "_" + System.currentTimeMillis()); // åéè¯·æ± HttpEntity<String> requestEntity = new HttpEntity<>(requestBody.toJSONString(), headers); ResponseEntity<String> response = restTemplate.exchange( url, HttpMethod.POST, requestEntity, String.class ); // è§£æååº JSONObject result = JSONObject.parseObject(response.getBody()); log.debug("{}级éç¥APIååº: {}", levelDesc, result != null ? result.toJSONString() : "null"); if (result != null && result.getInteger("code") == 0) { JSONObject data = result.getJSONObject("data"); if (data != null) { log.info("ã{}ã{}级å®ç¯éç¥åéæåï¼æ¶æ¯ID: {}, å®ç¯ID: {}", currentTime, levelDesc, data.getString("message_id"), andonOrde.getId()); return true; } else { log.warn("{}级éç¥ååºdata为空ï¼å®ç¯ID: {}", levelDesc, andonOrde.getId()); return false; } } else { log.error("åé{}级å®ç¯éç¥å¤±è´¥ï¼å®ç¯ID: {}", levelDesc, andonOrde.getId()); if (result != null) { log.error("é误ç : {}, é误信æ¯: {}", result.getInteger("code"), result.getString("msg")); } return false; } } catch (Exception e) { log.error("åé{}级å®ç¯éç¥å¼å¸¸ï¼å®ç¯ID: {}", getLevelDesc(level), andonOrde.getId(), e); return false; } } /** * è°åº¦ä¸ä¸çº§éç¥ï¼1â2â3ï¼ * @param currentLevel å½åçº§å« * @param delayMinutes å»¶è¿åéæ°ï¼ç±å½å级å«ååºæ¶é¿å³å®ï¼ */ private void scheduleNextLevelNotification(String accessToken, AndonButtonDTO andonOrde, int currentLevel, int delayMinutes) { int nextLevel = currentLevel + 1; if (nextLevel > 3) { log.info("å·²å°è¾¾æé«çº§å«éç¥ï¼æ éç»§ç»è°åº¦ï¼å®ç¯ID: {}", andonOrde.getId()); return; } String currentLevelDesc = getLevelDesc(currentLevel); String nextLevelDesc = getLevelDesc(nextLevel); String scheduleTime = sdf.format(new Date()); String executeTime = sdf.format(new Date(System.currentTimeMillis() + delayMinutes * 60 * 1000L)); log.info("ã{}ãè°åº¦{}éç¥ï¼å»¶è¿{}åéï¼å½å级å«{}æ¶é¿ï¼ï¼é¢è®¡æ§è¡æ¶é´: {}", scheduleTime, nextLevelDesc, delayMinutes, currentLevelDesc, executeTime); scheduler.schedule(() -> { try { String currentExecuteTime = sdf.format(new Date()); log.info("ã{}ãå¼å§æ§è¡{}éç¥æ£æ¥ï¼å®ç¯ID: {}", currentExecuteTime, nextLevelDesc, andonOrde.getId()); // æ£æ¥è®¢åç¶æï¼3表示已ååºï¼æ éåéä¸ä¸çº§ if (andonOrde.getOrderStatus() != null && "3".equals(andonOrde.getOrderStatus())) { log.info("ã{}ã订åå·²ååºï¼status=3ï¼ï¼åæ¶{}éç¥åéï¼å®ç¯ID: {}", currentExecuteTime, nextLevelDesc, andonOrde.getId()); return; } // æ£æ¥ä¸ä¸çº§ååºäººæ¯å¦ææ if (!hasValidResponder(andonOrde, nextLevel)) { log.warn("ã{}ã{}ååºäººä¿¡æ¯æ æï¼åæ¶éç¥åéï¼å®ç¯ID: {}", currentExecuteTime, nextLevelDesc, andonOrde.getId()); return; } // åéä¸ä¸çº§éç¥ boolean nextLevelResult = sendLevelNotification(accessToken, andonOrde, nextLevel); if (nextLevelResult && nextLevel < 3) { int nextDelay = getResponseDuration(andonOrde, nextLevel); String nextExecuteTime = sdf.format(new Date(System.currentTimeMillis() + nextDelay * 60 * 1000L)); log.info("ã{}ã{}éç¥è°åº¦ä¸çº§éç¥ï¼å»¶è¿{}åéï¼é¢è®¡åéæ¶é´: {}", currentExecuteTime, nextLevelDesc, nextDelay, nextExecuteTime); scheduleNextLevelNotification(accessToken, andonOrde, nextLevel, nextDelay); } else if (!nextLevelResult) { log.warn("ã{}ã{}éç¥åé失败ï¼ç»æ¢åç»è°åº¦ï¼å®ç¯ID: {}", currentExecuteTime, nextLevelDesc, andonOrde.getId()); } } catch (Exception e) { log.error("æ§è¡{}è°åº¦ä»»å¡å¼å¸¸ï¼å®ç¯ID: {}", nextLevelDesc, andonOrde.getId(), e); } }, delayMinutes, TimeUnit.MINUTES); } /** * æå»ºéç¥å 容ï¼ä¼ååéç¬¦ï¼æåå¯è¯»æ§ï¼ */ private String buildNotificationContent(AndonButtonDTO andonOrde, int level) { // è·åå·¥ååç§°å产线åç§°ï¼å空å¼ä¿æ¤ String parentFactoryName = andonOrde.getParentFactoryName() != null ? andonOrde.getParentFactoryName() : "æªç¥å·¥å"; String factoryName = andonOrde.getFactoryName() != null ? andonOrde.getFactoryName() : "æªç¥äº§çº¿"; String content; if (level == 1) { // ä¸çº§æ¨¡æ¿ï¼ä½¿ç¨"·"åéå·¥åå产线 int firstDuration = andonOrde.getUpgradeResponseDuration() != null ? andonOrde.getUpgradeResponseDuration() : 0; content = String.format(FIRST_LEVEL_TEMPLATE, parentFactoryName, factoryName, firstDuration); } else { // äºçº§æ¨¡æ¿ï¼ä¿æä¸è´çåé飿 ¼ String prevResponder = getResponderName(andonOrde, level - 1); int prevDuration = getResponseDuration(andonOrde, level - 1); prevResponder = oConvertUtils.isEmpty(prevResponder) ? "æªç¥äººå" : prevResponder; prevDuration = Math.max(prevDuration, 0); content = String.format(SECOND_LEVEL_TEMPLATE, parentFactoryName, factoryName, prevResponder, prevDuration); } log.debug("æå»º{}级éç¥å 容: {}", level, content); return content; } // /** // * æå»ºéç¥å å®¹ï¼æçº§å«ä½¿ç¨ä¸å模æ¿ï¼ // */ // private String buildNotificationContent(AndonButtonDTO andonOrde, int level) { // String factoryName = andonOrde.getFactoryName() != null ? andonOrde.getFactoryName() : "æªç¥äº§çº¿"; // // if (level == 1) { // // ä¸çº§æ¨¡æ¿ï¼ãå·¥èºå®ç¯ãXXX产线åèµ·äºå·¥èºå®ç¯ï¼è¯·xxåéå å¨PDAä¸è¿è¡ååºå¤çï¼ï¼ï¼ // return String.format("ãå·¥èºå®ç¯ã\n%s产线åèµ·äºå·¥èºå®ç¯ï¼è¯·%dåéå å¨PDAä¸è¿è¡ååºå¤çï¼ï¼ï¼", // factoryName, // andonOrde.getUpgradeResponseDuration()); // } else { // // äº/ä¸çº§æ¨¡æ¿ï¼ãå·¥èºå®ç¯ãXXXï¼äº§çº¿ï¼åèµ·çå·¥èºå®ç¯ï¼xxxï¼ä¸ä¸çº§ååºäººï¼æªå¨xxåéå ååºï¼è¯·å°½å¿«ç£ä¿è¿è¡ååºå¤çï¼ï¼ï¼ // String prevLevelDesc = getLevelDesc(level - 1); // String prevResponder = getResponderName(andonOrde, level - 1); // int prevDuration = getResponseDuration(andonOrde, level - 1); // // return String.format("ãå·¥èºå®ç¯ã\n%sï¼äº§çº¿ï¼åèµ·çå·¥èºå®ç¯ï¼%sï¼%sååºäººï¼æªå¨%dåéå ååºï¼è¯·å°½å¿«ç£ä¿è¿è¡ååºå¤çï¼ï¼ï¼", // factoryName, // prevResponder, // prevLevelDesc, // prevDuration); // } // } /** * éªè¯éç¥ç¸å ³åæ° */ private boolean validateNotificationParams(AndonButtonDTO andonOrde) { if (andonOrde == null) { log.error("å®ç¯è®¢åä¿¡æ¯ä¸ºç©º"); return false; } if (andonOrde.getId() == null) { log.error("å®ç¯ID为空"); return false; } // ä¸çº§ååºæ ¡éªï¼å¿ éï¼ if (andonOrde.getResponderOpenId() == null || andonOrde.getResponderOpenId().isEmpty() || andonOrde.getUpgradeResponseDuration() == null || andonOrde.getUpgradeResponseDuration() <= 0) { log.error("ä¸çº§ååºäººä¿¡æ¯æ æï¼openIdææ¶é¿ç¼ºå¤±ï¼ï¼å®ç¯ID: {}", andonOrde.getId()); return false; } // äºçº§ååºæ ¡éªï¼è¥åå¨åå¿ é宿´ï¼ if (andonOrde.getSecondResponderOpenId() != null && !andonOrde.getSecondResponderOpenId().isEmpty()) { if (andonOrde.getSecondUpgradeResponseDuration() == null || andonOrde.getSecondUpgradeResponseDuration() <= 0) { log.error("äºçº§ååºäººåå¨ä½æ¶é¿æ æï¼å®ç¯ID: {}", andonOrde.getId()); return false; } } // ä¸çº§ååºæ ¡éªï¼è¥åå¨åå¿ é宿´ï¼ if (andonOrde.getThirdResponderOpenId() != null && !andonOrde.getThirdResponderOpenId().isEmpty()) { if (andonOrde.getSecondUpgradeResponseDuration() == null || andonOrde.getSecondUpgradeResponseDuration() <= 0) { log.error("ä¸çº§ååºäººåå¨ä½äºçº§æ¶é¿æ æï¼ä¸çº§ä¾èµäºçº§æ¶é¿ï¼ï¼å®ç¯ID: {}", andonOrde.getId()); return false; } } return true; } // å·¥å ·æ¹æ³ï¼è·åçº§å«æè¿° private String getLevelDesc(int level) { switch (level) { case 1: return "ä¸çº§"; case 2: return "äºçº§"; case 3: return "ä¸çº§"; default: return "æªç¥çº§å«"; } } // å·¥å ·æ¹æ³ï¼è·åååºäººopenId private String getResponderOpenId(AndonButtonDTO andonOrde, int level) { switch (level) { case 1: return andonOrde.getResponderOpenId(); case 2: return andonOrde.getSecondResponderOpenId(); case 3: return andonOrde.getThirdResponderOpenId(); default: return null; } } // å·¥å ·æ¹æ³ï¼è·åååºäººåç§° private String getResponderName(AndonButtonDTO andonOrde, int level) { String name = null; switch (level) { case 1: name = andonOrde.getResponder(); break; case 2: name = andonOrde.getSecondResponder(); break; case 3: name = andonOrde.getThirdResponder(); break; default: name = null; } return name != null ? name : "æªç¥ååºäºº"; } // å·¥å ·æ¹æ³ï¼è·åååºæ¶é¿ï¼ä¸çº§=äºçº§å»¶è¿ï¼äºçº§=ä¸çº§å»¶è¿ï¼ private int getResponseDuration(AndonButtonDTO andonOrde, int level) { int duration = 0; switch (level) { case 1: duration = andonOrde.getUpgradeResponseDuration() != null ? andonOrde.getUpgradeResponseDuration() : 0; break; case 2: duration = andonOrde.getSecondUpgradeResponseDuration() != null ? andonOrde.getSecondUpgradeResponseDuration() : 0; break; case 3: duration = 0; // ä¸çº§æ¯æåä¸çº§ï¼æ éå»¶è¿ break; default: duration = 0; } return duration; } // å·¥å ·æ¹æ³ï¼å¤ææå®çº§å«ååºäººæ¯å¦ææ private boolean hasValidResponder(AndonButtonDTO andonOrde, int level) { String openId = getResponderOpenId(andonOrde, level); return openId != null && !openId.isEmpty(); } /** * è·åé¨é¨ç¨æ·å表ï¼ç´å±åå·¥ï¼ */ 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())) + "..."); String url = feishuUrl + "open-apis/contact/v3/users/find_by_department"; String pageToken = null; int pageNumber = 1; do { 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 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())) + "..."); HttpEntity<String> requestEntity = new HttpEntity<>(headers); ResponseEntity<String> response = restTemplate.exchange( urlBuilder.toString(), HttpMethod.GET, requestEntity, String.class ); JSONObject result = JSONObject.parseObject(response.getBody()); log.debug("第{}页APIååº: {}", pageNumber, result != null ? result.toJSONString() : "null"); if (result != null && result.getInteger("code") == 0) { JSONObject data = result.getJSONObject("data"); if (data != null) { 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("第{}页has_more: {}, page_token: {}", pageNumber, hasMore, pageToken); pageNumber++; } else { log.warn("第{}页data为空", 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; } /** * è§£æç¨æ·æ°æ® */ @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("è§£æç¨æ·æ°æ®å¤±è´¥ï¼items䏿¯å表类å: {}", 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(); user.setOpenId((String) userMap.getOrDefault("open_id", "")); String name = (String) userMap.getOrDefault("name", ""); if (name.contains(" ")) { String[] parts = name.split(" "); if (parts.length == 2) { user.setUsername(parts[0].trim()); user.setRealname(parts[1].trim()); user.setWorkNo(parts[0].trim()); } 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); } 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); 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"); user.setOpenId((String) userMap.getOrDefault("open_id", "")); userList.add(user); } return userList; } /** * 忥å个é£ä¹¦ç¨æ·å°ç³»ç» */ private boolean syncFeishuUserToSystem(FeishuUser feishuUser) { 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; } } } src/main/java/org/jeecg/modules/mes/entity/MessageResponse.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,12 @@ package org.jeecg.modules.mes.entity; import lombok.Data; @Data public class MessageResponse { private boolean success; private String message; private String messageId; private Long timestamp; } src/main/java/org/jeecg/modules/mes/job/FeishuUserService.java
ÎļþÒÑɾ³ý src/main/resources/application-dev.yml
@@ -126,9 +126,10 @@ connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000 datasource: master: url: jdbc:sqlserver://192.168.1.118:1433;databasename=LXZN_TEST_XHJ;nullCatalogMeansCurrent=true url: jdbc:sqlserver://127.0.0.1:1433;databasename=LXZN-TEXT-XHJ;nullCatalogMeansCurrent=true username: sa password: 123 password: 123456 driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver #redis é ç½® redis: