FeiShuEventController.java 17.7 KB
package com.pipihelper.project.feishu.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.pipihelper.project.core.Result;
import com.pipihelper.project.core.ResultGenerator;
import com.pipihelper.project.feishu.bo.PushPainBO;
import com.pipihelper.project.feishu.dto.FeiShuConfig;
import com.pipihelper.project.feishu.dto.FeiShuEventDTO;
import com.pipihelper.project.feishu.dto.FeiShuMsgCardEventDTO;
import com.pipihelper.project.feishu.dto.chat.FeiShuChatDTO;
import com.pipihelper.project.feishu.dto.department.FeiShuDepartmentDTO;
import com.pipihelper.project.feishu.dto.employee.FeiShuEmployeeDTO;
import com.pipihelper.project.feishu.dto.msg.FeiShuMsgDTO;
import com.pipihelper.project.feishu.entity.Employee;
import com.pipihelper.project.feishu.entity.LastMaxPain;
import com.pipihelper.project.feishu.entity.Pain;
import com.pipihelper.project.feishu.service.ChatMessageService;
import com.pipihelper.project.feishu.service.EmployeeService;
import com.pipihelper.project.feishu.service.FeiShuApiService;
import com.pipihelper.project.feishu.service.FeiShuEventService;
import com.pipihelper.project.feishu.service.LastMaxPainService;
import com.pipihelper.project.feishu.service.PainService;
import com.pipihelper.project.feishu.service.massage.MassageMsgCardSerivce;
import com.pipihelper.project.feishu.service.massage.MassageService;
import com.pipihelper.project.feishu.utils.FeiShuEventDataDecrypter;
import com.pipihelper.project.utils.CacheUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Description: TODO
 * @author: charles
 * @date: 2022年03月30日 17:39
 */
@Slf4j
@RestController
@RequestMapping("/pipitest/feishu")
public class FeiShuEventController {

    @Resource
    private FeiShuConfig feiShuConfig;

    @Resource
    private FeiShuEventService feiShuEventService;

    @Autowired
    private FeiShuApiService feiShuApiService;
    @Autowired
    private MassageMsgCardSerivce massageMsgCardSerivce;
    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private ChatMessageService chatMessageService;
    @Autowired
    private LastMaxPainService lastMaxPainService;
    @Autowired
    private PainService painService;
    @Autowired
    private MassageService massageService;


    @PostMapping("/event")
    public JSONObject event(@RequestBody String s) throws Exception {
        JSONObject reqJsonObject = JSON.parseObject(s);
        log.info("接收到事件,密文:{}", s);
        FeiShuEventDataDecrypter d = new FeiShuEventDataDecrypter(feiShuConfig.getEncryptKey());
        JSONObject encryptJsonObject = JSON.parseObject(d.decrypt(reqJsonObject.getString("encrypt")));
        log.info("接收到事件,明文:{}", encryptJsonObject);
        if (encryptJsonObject.containsKey("challenge")) {
            return encryptJsonObject;
        }

        FeiShuEventDTO feiShuEventDTO = encryptJsonObject.toJavaObject(FeiShuEventDTO.class);
        if (!feiShuEventDTO.getHeader().getToken().equalsIgnoreCase(feiShuConfig.getVerificationToken())) {
            return null;
        }
        if ("im.message.receive_v1".equalsIgnoreCase(feiShuEventDTO.getHeader().getEvent_type())) {
            log.info("处理单聊事件:{}", feiShuEventDTO);
            feiShuEventService.imMessageReceiveV1(feiShuEventDTO);
        }
        return null;
    }

    @PostMapping("/msg_card")
    public JSONObject msgCardEvent(@RequestBody String s) throws Exception {
        JSONObject reqJsonObject = JSON.parseObject(s);
        System.out.println(s);
        if (reqJsonObject.containsKey("challenge")) {
            return reqJsonObject;
        }
        FeiShuMsgCardEventDTO feiShuMsgCardEventDTO = reqJsonObject.toJavaObject(FeiShuMsgCardEventDTO.class);
        String actionType = feiShuMsgCardEventDTO.getAction().getValue().getKey().split("\\.")[0];
        String actionTypeSecond = feiShuMsgCardEventDTO.getAction().getValue().getKey().split("\\.")[1];

        switch (actionType) {
            case "massage-singel":
                // 都需要返回 不能点击的卡片json
                if ("revice".equals(actionTypeSecond)) {
                    // 接受按摩
                    String fileName = String.format("/templates/massage-singel-msg-card-end.json");

                    return getInteractiveCardStr(fileName, "您已接受啦~");
                } else if ("giveUp".equals(actionTypeSecond)) {
                    // 放弃 - 往大群中发送抢按摩机会卡片
                    FeiShuMsgDTO feiShuMsgDTO = new FeiShuMsgDTO();
                    feiShuMsgDTO.setMsgType("interactive");
                    feiShuMsgDTO.setReceiveId(feiShuConfig.getChatId());
                    String fileName = String.format("/templates/massage-msg-card-rob.json");
                    String msgCardContent = String.format(massageMsgCardSerivce.getInteractiveCardStr(fileName), feiShuMsgCardEventDTO.getOpen_id());
                    feiShuMsgDTO.setContent(msgCardContent);
                    feiShuApiService.sendMsg(feiShuMsgDTO, "chat_id");
                    String fileName1 = String.format("/templates/massage-singel-msg-card-end.json");

                    return getInteractiveCardStr(fileName1, "怕疼的家伙~");
                } else if ("wait".equals(actionTypeSecond)) {
                    // 推迟 将当前用户放到队列最后 -  掉延迟更新卡片接口 更新大群、按摩群的按摩时间安排卡片
                    String waitUserId = feiShuMsgCardEventDTO.getOpen_id();
                    painService.waitPain(waitUserId);
                    //更新大群
                    massageService.updateMassageMsgCardToPiPiChat(feiShuConfig.getChatId());
                    //更新按摩群
                    massageService.updateMassageMsgCardToPiPiChat((String) CacheUtil.get("chatId"));
                    String fileName1 = String.format("/templates/massage-singel-msg-card-end.json");
                    return getInteractiveCardStr(fileName1, "已为你推迟到队尾");
                } else if ("rob".equals(actionTypeSecond)) {
                    // 抢名额 -   掉延迟更新卡片接口 更新大群、按摩群的按摩时间安排卡片
                    return rob(feiShuMsgCardEventDTO);
                } else if ("next".equals(actionTypeSecond)) {
                    // 当前按完,有请下一位
                    String endUserId = feiShuMsgCardEventDTO.getOpen_id();
                    Pain oldPain = painService.findByOpenId(endUserId);
                    oldPain.setStatus(2);
                    painService.update(oldPain);
                    List<Pain> painList = painService.findBackIndex(oldPain.getPindex(), 1);
                    if (CollectionUtil.isNotEmpty(painList)) {
                        Pain noticePain = CollectionUtil.getFirst(painList);
                        noticePain.setStatus(1);
                        painService.update(noticePain);
                        massageService.updateSingleMassageMsgCardWhenBegin(noticePain.getMessageId());
                        //按摩群中同步发送按摩进度信息
                        FeiShuMsgDTO feiShuMsgDTO = new FeiShuMsgDTO();
                        String msg = "当前按摩进度:" + String.format("<at user_id=\\\"%s\\\">%s</at>", noticePain.getOpenId(), noticePain.getName());
                        JSONObject content = new JSONObject();
                        content.put("text", msg);
                        feiShuMsgDTO.setMsgType("text");
                        feiShuMsgDTO.setContent(content.toString());
                        feiShuMsgDTO.setReceiveId((String) CacheUtil.get("chatId"));
                        feiShuApiService.sendMsg(feiShuMsgDTO, "chat_id");
                    }
                    String fileName1 = String.format("/templates/massage-singel-msg-card-end.json");
                    return getInteractiveCardStr(fileName1, "您本次的massage之旅已结束~");
                }
            default:
        }
        return null;
    }

    public synchronized JSONObject rob(FeiShuMsgCardEventDTO feiShuMsgCardEventDTO) {
        String oldUserId = feiShuMsgCardEventDTO.getAction().getValue().getKey().split("\\.")[2];
        String robUserId = feiShuMsgCardEventDTO.getOpen_id();
        Employee employee = employeeService.findByOpenId(robUserId);

        massageService.robSingle(robUserId, oldUserId, employee.getName());
        String fileName1 = String.format("/templates/massage-msg-card-rob-end.json");
        return getInteractiveCardStr(fileName1, "已经被" + employee.getName() + "抢啦,啦啦~");
    }


    /**
     * 读取模板文件
     *
     * @return
     */
    public JSONObject getInteractiveCardStr(String fileName, String msg) {
        try {
            InputStream in = this.getClass().getResourceAsStream(fileName);
            InputStreamReader inputStreamReader = new InputStreamReader(in);
            Stream<String> streamOfString = new BufferedReader(inputStreamReader).lines();
            String streamToString = streamOfString.collect(Collectors.joining());
            String msgCardContent = String.format(streamToString, msg);
            return JSON.parseObject(msgCardContent);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @PostMapping("/delete-chat-list")
    public Object deleteChat(String chatId) {
        if (StringUtils.isBlank(chatId)) {
            chatId = (String) CacheUtil.get("chatId");
        }
        log.info("删除群组id:{}", chatId);
        feiShuApiService.deleteChatList(chatId);
        return null;
    }

    @PostMapping("/employee-list")
    public Object event() {
        employeeService.uprsetAllEmployee();

        chatMessageService.deleteAll();
        for (Integer floor : Lists.newArrayList(14)) {
            LastMaxPain maxPain = lastMaxPainService.findByFloor(floor);
            int startEmployeeId = 0;
            if (maxPain != null) {
                startEmployeeId = maxPain.getEmployeeId();
            }
            int countByFloor = employeeService.findCountByFloor(floor);
            int limit = 2;
            if (countByFloor < 2) {
                limit = countByFloor;
            }
            List<Employee> employeeList = employeeService.findStartList(startEmployeeId, floor, limit);
            Integer maxEmploeeId = 0;
            if (employeeList.size() == limit) {
                maxEmploeeId = employeeList.stream().map(Employee::getId).max(Comparator.comparing(x -> x)).orElse(0);
            } else {
                List<Employee> employees = employeeService.findStartList(0, floor, limit - employeeList.size());
                maxEmploeeId = employees.stream().map(Employee::getId).max(Comparator.comparing(x -> x)).orElse(0);
                employeeList.addAll(employees);
            }

            Map<String, FeiShuDepartmentDTO> departmentMap = new HashMap<>();
            List<String> departmentIdList = employeeList.stream().map(Employee::getDepartmentId).distinct().collect(Collectors.toList());
            departmentIdList.forEach(it -> {
                FeiShuDepartmentDTO department = feiShuApiService.getDepartment(it);
                departmentMap.put(it, department);
            });

            painService.deleteAllByFloor(floor);
            List<PushPainBO> pushPainBOList = new ArrayList<>();
            String[] userIdList = new String[employeeList.size()];
            AtomicInteger i = new AtomicInteger(1);
            employeeList.forEach(it -> {
                Pain pain = new Pain();
                pain.setOpenId(it.getOpenId());
                pain.setStatus(0);
                pain.setFloor(Optional.ofNullable(it.getFloor()).orElse(floor));
                int increment = i.getAndIncrement();
                pain.setPindex(increment);
                pain.setName(it.getName());
                String departMentName = departmentMap.getOrDefault(it.getDepartmentId(), new FeiShuDepartmentDTO()).getName();
                pain.setDepartMentName(departMentName);
                painService.create(pain);

                PushPainBO pushPainBO = new PushPainBO();
                pushPainBO.setIndex(increment);
                pushPainBO.setName(it.getName());
                pushPainBO.setDepartMentName(departMentName);
                pushPainBO.setOpenId(it.getOpenId());
                pushPainBO.setTimeRange(painService.getTimeRange(increment, floor));
                pushPainBOList.add(pushPainBO);
                userIdList[increment - 1] = it.getOpenId();
            });

            FeiShuChatDTO feiShuChatDTO = new FeiShuChatDTO();
            feiShuChatDTO.setName("按摩群 " + DateUtil.today());
            feiShuChatDTO.setOwnerId(pushPainBOList.get(0).getOpenId());
            feiShuChatDTO.setUserIdList(userIdList);
            String chatId = feiShuApiService.createChatList(feiShuChatDTO);
            massageService.sendMassageMsgCardToPiPiChat(pushPainBOList, chatId);
            massageService.sendMassageMsgCardToPiPiChat(pushPainBOList, feiShuConfig.getChatId());

            if (maxPain != null) {
                maxPain.setEmployeeId(maxEmploeeId);
                lastMaxPainService.update(maxPain);
            } else {
                maxPain = new LastMaxPain();
                maxPain.setEmployeeId(maxEmploeeId);
                maxPain.setFloor(floor);
                lastMaxPainService.create(maxPain);
            }
        }
        List<FeiShuEmployeeDTO> dtos = feiShuApiService.getEmployeeList();
        return dtos;
    }

    @PostMapping("/department-user")
    public Object departmentUser(String department) {

        return feiShuApiService.getUser(department);
    }


    @PostMapping("/department")
    public Object department(String department) {

        return feiShuApiService.getDepartment(department);
    }

    @PostMapping("/create-chart")
    public Object createChatList(String department) {

        FeiShuChatDTO feiShuChatDTO = new FeiShuChatDTO();
        feiShuChatDTO.setName("按摩群");
        feiShuChatDTO.setOwnerId("ou_5d72916b0a0b800b0fff6861eb52cf13");
        ArrayList<String> strings = Lists.newArrayList("ou_5d72916b0a0b800b0fff6861eb52cf13", "ou_59498f75298812fbbed4de46fc5462e3"
                , "ou_aa066da071443aefb2351ee248190583", "ou_5f30c2076fc2c5a5225bfdbb2da1ea6f", "ou_c902848a93e19928043a7fa38bef295b");
        String[] userIds = new String[strings.size()];
        for (int i = 0; i < strings.size(); i++) {
            userIds[i] = strings.get(i);
        }
        feiShuChatDTO.setUserIdList(userIds);
        return feiShuApiService.createChatList(feiShuChatDTO);
    }

    @PostMapping("/join-chart")
    public Object joinChatList(String openId) {

        FeiShuChatDTO feiShuChatDTO = new FeiShuChatDTO();
        feiShuChatDTO.setChatId("oc_398c8c0b88421980d840db157c14ec20");
        feiShuChatDTO.setIdList(new String[]{openId});
        return feiShuApiService.joinChatList(feiShuChatDTO);
    }

    @PostMapping("/start")
    public Result start() {
        List<Pain> pains = painService.findListAsc(3);
        StringBuilder userString = new StringBuilder();

        for (Pain pain : pains) {
            String messageId = pain.getMessageId();
            massageService.updateSingleMassageMsgCardWhenBegin(messageId);
            userString.append(String.format("<at user_id=\"%s\">%s</at>", pain.getOpenId(), pain.getName()));

            //1代表正在按
            pain.setStatus(1);
            painService.update(pain);
            JSONObject noticeMsg = new JSONObject();
            noticeMsg.put("user_id_list", Arrays.asList(pain.getOpenId()));
            //发送应用内提醒
            log.info("发送应用内容消息提醒");
            feiShuApiService.patchUrgentApp(messageId, noticeMsg);
        }
        //按摩群中同步发送按摩进度信息
        FeiShuMsgDTO feiShuMsgDTO = new FeiShuMsgDTO();
        String msg = "当前按摩进度:" + userString;
        JSONObject content = new JSONObject();
        content.put("text", msg);
        feiShuMsgDTO.setMsgType("text");
        feiShuMsgDTO.setContent(content.toString());
        feiShuMsgDTO.setReceiveId((String) CacheUtil.get("chatId"));
        feiShuApiService.sendMsg(feiShuMsgDTO, "chat_id");
        return ResultGenerator.genSuccessResult();
    }

    @PostMapping("/send-msg")
    public Result sendMsg(String receiveId, String msg, String receiveIdType) {
        FeiShuMsgDTO feiShuMsgDTO = new FeiShuMsgDTO();
        JSONObject content = new JSONObject();
        content.put("text", msg);
        feiShuMsgDTO.setMsgType("text");
        feiShuMsgDTO.setContent(content.toString());
        if (receiveId.equals("-1")) {
            receiveId = (String) CacheUtil.get("chatId");
        }
        feiShuMsgDTO.setReceiveId(receiveId);
        log.info("已机器人身份发送消息:{}", feiShuMsgDTO.toString());
        feiShuApiService.sendMsg(feiShuMsgDTO, receiveIdType);
        return ResultGenerator.genSuccessResult();
    }

}