Эх сурвалжийг харах

Merge remote-tracking branch 'origin/test-merge' into test-merge

LHB 1 сар өмнө
parent
commit
7e0a76e60f
18 өөрчлөгдсөн 914 нэмэгдсэн , 63 устгасан
  1. 2 0
      blade-common/src/main/java/org/springblade/common/constant/LauncherConstant.java
  2. 4 1
      blade-ops/blade-swagger/src/main/resources/application-dev.yml
  3. 35 0
      blade-service/blade-dingding/pom.xml
  4. 23 0
      blade-service/blade-dingding/src/main/java/org/springblade/DingDingApplication.java
  5. 30 0
      blade-service/blade-dingding/src/main/java/org/springblade/dingding/controller/MeetingController.java
  6. 9 0
      blade-service/blade-dingding/src/main/java/org/springblade/dingding/service/MeetingService.java
  7. 595 0
      blade-service/blade-dingding/src/main/java/org/springblade/dingding/service/impl/MeetingServiceImpl.java
  8. 15 0
      blade-service/blade-dingding/src/main/java/org/springblade/dingding/vo/MeetingSchedule.java
  9. 24 0
      blade-service/blade-dingding/src/main/java/org/springblade/dingding/vo/MeetingVo.java
  10. 14 0
      blade-service/blade-dingding/src/main/java/org/springblade/dingding/vo/ScheduleItem.java
  11. 10 0
      blade-service/blade-dingding/src/main/resources/application-dev.yml
  12. 10 0
      blade-service/blade-dingding/src/main/resources/application-prod.yml
  13. 10 0
      blade-service/blade-dingding/src/main/resources/application-test.yml
  14. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ExcelTabMapper.xml
  15. 69 41
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsFormElementServiceImpl.java
  16. 49 19
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java
  17. 13 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java
  18. 1 0
      pom.xml

+ 2 - 0
blade-common/src/main/java/org/springblade/common/constant/LauncherConstant.java

@@ -80,6 +80,8 @@ public interface LauncherConstant {
 
     String  APPLICATION_REPAIR_NAME = APPLICATION_NAME_PREFIX + "repair";
 
+    String  APPLICATION_DingDing_NAME = APPLICATION_NAME_PREFIX + "dingding";
+
 
     /**
      * nacos dev 地址 215==172.31.222.127   192.168.0.109     127.0.0.1  210-=-172.30.224.81

+ 4 - 1
blade-ops/blade-swagger/src/main/resources/application-dev.yml

@@ -30,4 +30,7 @@ knife4j:
         location: /blade-land/v2/api-docs
       - name: 计量接口
         uri: 127.0.0.1:8090
-        location: /blade-meter/v2/api-docs
+        location: /blade-meter/v2/api-docs
+      - name: 钉钉接口
+        uri: 127.0.0.1:8090
+        location: /blade-dingding/v2/api-docs

+ 35 - 0
blade-service/blade-dingding/pom.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springblade</groupId>
+        <artifactId>BladeX</artifactId>
+        <version>2.9.1.RELEASE</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>blade-dingding</artifactId>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-core-boot</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-starter-swagger</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 23 - 0
blade-service/blade-dingding/src/main/java/org/springblade/DingDingApplication.java

@@ -0,0 +1,23 @@
+package org.springblade;
+
+
+import org.springblade.common.constant.LauncherConstant;
+import org.springblade.core.cloud.feign.EnableBladeFeign;
+import org.springblade.core.launch.BladeApplication;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cloud.client.SpringCloudApplication;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+
+/**
+ * 客户端启动类
+ */
+@EnableBladeFeign
+@SpringCloudApplication
+@EnableAsync
+@EnableCaching
+public class DingDingApplication {
+    public static void main(String[] args) {
+        BladeApplication.run(LauncherConstant.APPLICATION_DingDing_NAME, DingDingApplication.class, args);
+    }
+}

+ 30 - 0
blade-service/blade-dingding/src/main/java/org/springblade/dingding/controller/MeetingController.java

@@ -0,0 +1,30 @@
+package org.springblade.dingding.controller;
+
+import io.swagger.annotations.Api;
+import lombok.AllArgsConstructor;
+import lombok.extern.java.Log;
+import org.springblade.core.boot.ctrl.BladeController;
+import org.springblade.core.tool.api.R;
+import org.springblade.dingding.service.MeetingService;
+import org.springblade.dingding.vo.MeetingVo;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@AllArgsConstructor
+@RequestMapping("/meeting")
+@Api(value = "钉钉会议接口", tags = "钉钉会议接口")
+public class MeetingController extends BladeController {
+
+  private final MeetingService meetingService;
+
+  @GetMapping("/getMeetingInfo")
+  public R<List<MeetingVo>> getMeetingInfo(){
+    return R.data(meetingService.getMeetingInfo());
+  }
+
+}

+ 9 - 0
blade-service/blade-dingding/src/main/java/org/springblade/dingding/service/MeetingService.java

@@ -0,0 +1,9 @@
+package org.springblade.dingding.service;
+
+import org.springblade.dingding.vo.MeetingVo;
+
+import java.util.List;
+
+public interface MeetingService {
+    List<MeetingVo> getMeetingInfo();
+}

+ 595 - 0
blade-service/blade-dingding/src/main/java/org/springblade/dingding/service/impl/MeetingServiceImpl.java

@@ -0,0 +1,595 @@
+package org.springblade.dingding.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.nacos.shaded.com.google.gson.JsonElement;
+import com.alibaba.nacos.shaded.com.google.gson.JsonObject;
+import com.alibaba.nacos.shaded.com.google.gson.JsonParser;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.dingding.service.MeetingService;
+import org.springblade.dingding.vo.MeetingSchedule;
+import org.springblade.dingding.vo.MeetingVo;
+import org.springblade.dingding.vo.ScheduleItem;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.HttpServerErrorException;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.TextStyle;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+public class MeetingServiceImpl implements MeetingService {
+
+    private static final String DINGTALK_API_BASE = "https://api.dingtalk.com/v1.0/";
+    private static final String APP_KEY = "ding6mvrzcxcbdggel0h";
+    private static final String APP_SECRET = "TctTp-Qmyh9r20bdeHcLWZ8qfxSEP8R29qo53GZH2elWV-yDZMqgqFKEjp5PtlXZ";
+    private static final String USER_ID = "01141506681633389467";
+
+
+
+    @Override
+    public  List<MeetingVo> getMeetingInfo() {
+        List<MeetingVo> vos=new ArrayList<>();
+        String accessToken = getAccessToken();
+        String unionId = (String) getUserInfo(accessToken,"unionid",USER_ID);
+        String meetingsJson = getMeetings(accessToken, unionId);
+        try {
+            // 解析JSON字符串
+            com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(meetingsJson);
+            // 获取result数组
+            JSONArray resultArray = jsonObject.getJSONArray("result");
+            // 遍历数组,提取roomId和roomName
+            for (int i = 0; i < resultArray.size(); i++) {
+                MeetingVo vo=new MeetingVo();
+                JSONObject roomObject = resultArray.getJSONObject(i);
+                String roomId = roomObject.getString("roomId");
+                String roomName = roomObject.getString("roomName");
+                vo.setRoomId(roomId);
+                vo.setFixedData(roomName);
+                vos.add(vo);
+            }
+            LocalDateTime startOfDay = LocalDateTime.now().with(LocalTime.MIDNIGHT);
+            ZonedDateTime startOfDayZoned = startOfDay.atZone(ZoneId.systemDefault());
+            String startTime=startOfDayZoned.withZoneSameInstant(ZoneId.of("UTC"))
+                    .format(DateTimeFormatter.ISO_INSTANT);
+            LocalDateTime endOfDay = LocalDateTime.now().with(LocalTime.MAX);
+            ZonedDateTime endOfDayZoned = endOfDay.atZone(ZoneId.systemDefault());
+            String endTime= endOfDayZoned.withZoneSameInstant(ZoneId.of("UTC"))
+                    .format(DateTimeFormatter.ISO_INSTANT);
+            for (MeetingVo vo : vos) {
+                String[] roomIds = new String[]{vo.getRoomId()};
+                String meetingHistory = getMeetingHistory(accessToken, unionId,roomIds,startTime,endTime);
+                List<ScheduleItem> scheduleItems = parseScheduleItemsWithStream(meetingHistory);
+                List<MeetingSchedule>list=new ArrayList<>();
+                if(!scheduleItems.isEmpty()){
+                    //循环查出预定的会议是否正在进行
+                    for (ScheduleItem item : scheduleItems) {
+                        String stringStartDateTime = extractTimeFromDateTime(item.getStartDateTime());
+                        String stringEndDateTime = extractTimeFromDateTime(item.getEndDateTime());
+                        //正在进行的会议
+                        if(isCurrentTimeInRange(item.getStartDateTime(),item.getEndDateTime())){
+                            String meetingList = getMeetingList(item.getOrganizerId(), accessToken);
+                            JSONObject meetingListjsonObject = JSON.parseObject(meetingList);
+                            JSONArray onGoingConfIdList = meetingListjsonObject.getJSONArray("onGoingConfIdList");
+                            String tatil = getMeetingDetail(accessToken, onGoingConfIdList.getString(0));
+                            String userID = getUserID(accessToken, item.getOrganizerId());
+                            Object o = getUserInfo(accessToken, "dept_id_list", userID);
+                            List<String> deptIdList = JSON.parseArray(o.toString(), String.class);
+                            String departmentInfo = getDepartmentInfo(accessToken, deptIdList.get(0));
+                            vo.setStatus(2);
+                            vo.setMeetingTheme(tatil);
+                            vo.setMeetingDept(departmentInfo);
+                            String name = (String)getUserInfo(accessToken, "name", userID);
+                            vo.setMeetingBooker(name);
+                            vo.setMeetingTime(formatDateTimeRangeWithFormatter(item.getStartDateTime(),item.getEndDateTime()));
+                            String allUser = getAllUser(onGoingConfIdList.getString(0), accessToken);
+                            vo.setParticipants(allUser);
+                            break;
+                        }
+                        //今日预约的会议
+                        MeetingSchedule schedule = new MeetingSchedule();
+                        String userID = getUserID(accessToken, item.getOrganizerId());
+                        Object o = getUserInfo(accessToken, "dept_id_list", userID);
+                        List<String> deptIdList = JSON.parseArray(o.toString(), String.class);
+                        String departmentInfo = getDepartmentInfo(accessToken, deptIdList.get(0));
+                        schedule.setReservationTime(stringStartDateTime+"~"+stringEndDateTime);
+                        schedule.setReservationDept(departmentInfo);
+                        vo.setStatus(1);
+                        list.add(schedule);
+                    }
+                }else {
+                    vo.setStatus(1);
+                }
+                vo.setMeetingSession(list.size());
+                vo.setMeetings(list);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return vos;
+    }
+
+   public String getAllUser(String CONFERENCE_ID,String ACCESS_TOKEN){
+       CloseableHttpClient httpClient = HttpClients.createDefault();
+       try {
+           // 构建请求 URL
+           StringBuilder urlBuilder = new StringBuilder("https://api.dingtalk.com/v1.0/conference/videoConferences/")
+                   .append(CONFERENCE_ID)
+                   .append("/members");
+           HttpGet httpGet = new HttpGet(new URI(urlBuilder.toString()));
+           // 设置 Header 参数
+           httpGet.setHeader("x-acs-dingtalk-access-token", ACCESS_TOKEN);
+           httpGet.setHeader("Content-Type", "application/json");
+           // 发送请求并获取响应
+           CloseableHttpResponse response = httpClient.execute(httpGet);
+           try {
+               // 解析响应实体为字符串
+               String responseString = EntityUtils.toString(response.getEntity(), "UTF-8");
+               JSONObject jsonObject = JSON.parseObject(responseString);
+               // 获取memberModelMap
+               JSONArray memberModels = jsonObject.getJSONArray("memberModels");
+               Set<String> set=new HashSet<>();
+               for (int i = 0; i < memberModels.size(); i++) {
+                   JSONObject memberModel = memberModels.getJSONObject(i);
+                   String userNick = memberModel.getString("userNick");
+                   set.add(userNick);
+               }
+               return String.join(",",set);
+           } finally {
+               response.close();
+           }
+       } catch (IOException | URISyntaxException e) {
+          return "";
+       }
+   }
+
+    public String formatDateTimeRangeWithFormatter(String startDateTime, String endDateTime) {
+        try {
+            ZonedDateTime startTime = ZonedDateTime.parse(startDateTime);
+            ZonedDateTime endTime = ZonedDateTime.parse(endDateTime);
+
+            // 手动构建格式
+            String startFormatted = String.format("%d年%d月%d日 %s %02d:%02d",
+                    startTime.getYear(),
+                    startTime.getMonthValue(),
+                    startTime.getDayOfMonth(),
+                    startTime.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.CHINESE),
+                    startTime.getHour(),
+                    startTime.getMinute());
+
+            String endFormatted = String.format("%d年%d月%d日 %s %02d:%02d",
+                    endTime.getYear(),
+                    endTime.getMonthValue(),
+                    endTime.getDayOfMonth(),
+                    endTime.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.CHINESE),
+                    endTime.getHour(),
+                    endTime.getMinute());
+
+            return startFormatted + " ~ " + endFormatted;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return "时间格式错误";
+        }
+    }
+
+    public boolean isCurrentTimeInRange(String startDateTime, String endDateTime) {
+        try {
+            // 解析开始时间和结束时间
+            ZonedDateTime startTime = ZonedDateTime.parse(startDateTime);
+            ZonedDateTime endTime = ZonedDateTime.parse(endDateTime);
+
+            // 获取当前时间(使用相同时区)
+            ZonedDateTime now = ZonedDateTime.now(startTime.getZone());
+
+            // 检查当前时间是否在范围内(包含边界)
+            return !now.isBefore(startTime) && !now.isAfter(endTime);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    public String getMeetingList(String UNION_ID, String ACCESS_TOKEN){
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        try {
+            // 构建请求 URL
+            String url = "https://api.dingtalk.com/v1.0/conference/users/lists?unionId=" + UNION_ID;
+            HttpGet httpGet = new HttpGet(url);
+            // 设置请求头中的 access token
+            httpGet.setHeader("x-acs-dingtalk-access-token", ACCESS_TOKEN);
+            httpGet.setHeader("Content-Type", "application/json");
+
+            // 发送请求并获取响应
+            CloseableHttpResponse response = httpClient.execute(httpGet);
+            try {
+                org.apache.http.HttpEntity entity = response.getEntity();
+                if (entity != null) {
+                    // 将响应实体转换为字符串
+                    return EntityUtils.toString(entity, "UTF-8");
+                }
+            } finally {
+                response.close();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public String getMeetingDetail(String ACCESS_TOKEN,String CONFERENCE_ID){
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        try {
+            // 构建请求 URL,包含会议 ID
+            String url = "https://api.dingtalk.com/v1.0/conference/videoConferences/" + CONFERENCE_ID;
+            HttpGet httpGet = new HttpGet(url);
+
+            // 设置 Header 参数
+            httpGet.setHeader("x-acs-dingtalk-access-token", ACCESS_TOKEN);
+            httpGet.setHeader("Content-Type", "application/json");
+
+            // 发送请求并获取响应
+            CloseableHttpResponse response = httpClient.execute(httpGet);
+            try {
+                // 解析响应实体为字符串
+                String responseString = EntityUtils.toString(response.getEntity(), "UTF-8");
+                JSONObject jsonObject = JSON.parseObject(responseString);
+                JSONObject confInfo = jsonObject.getJSONObject("confInfo");
+                if (confInfo != null) {
+                    return confInfo.getString("title");
+                }
+            } finally {
+                response.close();
+            }
+        } catch (IOException e) {
+
+        }
+        return null;
+    }
+
+    public  String getUserID(String ACCESS_TOKEN,String UNION_ID) throws Exception {
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        try {
+            // 构建请求 URL,包含 access_token 和 unionid 参数
+            String url = "https://oapi.dingtalk.com/user/getUseridByUnionid?access_token=" + ACCESS_TOKEN + "&unionid=" + UNION_ID;
+            HttpGet httpGet = new HttpGet(url);
+
+            // 发送请求并获取响应
+            CloseableHttpResponse response = httpClient.execute(httpGet);
+            try {
+                // 解析响应实体为字符串
+                String responseString = EntityUtils.toString(response.getEntity(), "UTF-8");
+                // 解析 JSON 响应
+                JSONObject jsonObject = JSONObject.parseObject(responseString);
+
+                // 检查是否调用成功(errcode 为 0 表示成功)
+                if (jsonObject.getInteger("errcode") == 0) {
+                    // 获取 userId
+                    String userId = jsonObject.getString("userid");
+                    return userId;
+                } else {
+                   throw new Exception("获取userId失败");
+                }
+            } finally {
+                response.close();
+            }
+        } catch (Exception e) {
+            throw new Exception("获取userId失败");
+        }
+    }
+
+    public  int compareDateTimeWithNow(String stringStartDateTime) {
+        try {
+            // 解析输入的时间字符串
+            ZonedDateTime inputTime = ZonedDateTime.parse(stringStartDateTime);
+
+            // 获取当前时间(使用相同时区)
+            ZonedDateTime now = ZonedDateTime.now(inputTime.getZone());
+
+            // 比较时间
+            if (inputTime.isAfter(now)) {
+                return 1; // 输入时间大于当前时间
+            } else {
+                return 2; // 输入时间小于或等于当前时间
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 2; // 默认返回2(过去时间)
+        }
+    }
+
+    /**
+     * 查询部门信息
+     */
+    public String getDepartmentInfo(String accessToken, String deptId) throws Exception {
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        String url = "https://oapi.dingtalk.com/topapi/v2/department/get?access_token=" + accessToken;
+
+        HttpPost httpPost = new HttpPost(url);
+        httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
+
+        // 构建请求体
+        JSONObject requestBody = new JSONObject();
+        requestBody.put("dept_id", deptId);
+        httpPost.setEntity(new StringEntity(requestBody.toString(), "UTF-8"));
+
+        // 发送请求并获取响应
+        try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
+            // 使用Apache HttpClient的HttpEntity
+            org.apache.http.HttpEntity entity = response.getEntity();  // 不要强制转换
+            if (entity != null) {
+                String string = EntityUtils.toString(entity, "UTF-8");
+                JSONObject jsonObject = JSON.parseObject(string);
+                JSONObject resultObj = jsonObject.getJSONObject("result");
+                return resultObj.getString("name");  // 使用getString更安全
+            }
+        } finally {
+            httpClient.close();
+        }
+        return null;
+    }
+    public  String extractTimeFromDateTime(String dateTimeString) {
+        try {
+            // 解析带时区的时间字符串
+            ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateTimeString);
+
+            // 只提取小时和分钟
+            DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");
+            return zonedDateTime.format(timeFormatter);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return "00:00"; // 返回默认值如果解析失败
+        }
+    }
+
+    public  List<ScheduleItem> parseScheduleItemsWithStream(String meetingHistoryJson) {
+        try {
+            JSONObject jsonObject = JSON.parseObject(meetingHistoryJson);
+            JSONArray scheduleInfoArray = jsonObject.getJSONArray("scheduleInformation");
+
+            if (scheduleInfoArray != null) {
+                return scheduleInfoArray.stream()
+                        .map(obj -> (JSONObject) obj)
+                        .flatMap(scheduleInfo -> {
+                            JSONArray items = scheduleInfo.getJSONArray("scheduleItems");
+                            return items != null ? items.stream().map(item -> (JSONObject) item) : java.util.stream.Stream.empty();
+                        })
+                        .map(this::convertToScheduleItem)
+                        .collect(java.util.stream.Collectors.toList());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return new ArrayList<>();
+    }
+
+    private  ScheduleItem convertToScheduleItem(JSONObject scheduleItemObj) {
+        ScheduleItem item = new ScheduleItem();
+
+        item.setEventId(scheduleItemObj.getString("eventId"));
+        item.setStatus(scheduleItemObj.getString("status"));
+
+        JSONObject organizerObj = scheduleItemObj.getJSONObject("organizer");
+        if (organizerObj != null) {
+            item.setOrganizerId(organizerObj.getString("id"));
+        }
+
+        JSONObject startObj = scheduleItemObj.getJSONObject("start");
+        if (startObj != null) {
+            item.setStartDateTime(startObj.getString("dateTime"));
+            item.setStartTimeZone(startObj.getString("timeZone"));
+        }
+
+        JSONObject endObj = scheduleItemObj.getJSONObject("end");
+        if (endObj != null) {
+            item.setEndDateTime(endObj.getString("dateTime"));
+            item.setEndTimeZone(endObj.getString("timeZone"));
+        }
+
+        return item;
+    }
+
+    //解析json字符串
+    private  String parseFromJson(String json,String key) {
+        try {
+            JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
+            JsonElement result = jsonObject.get("result");
+            return result.getAsJsonObject().get(key).getAsString();
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    //获取AccessToken
+    public  String getAccessToken() {
+        // 实现获取AccessToken逻辑
+        String url = DINGTALK_API_BASE + "oauth2/accessToken";
+        RestTemplate restTemplate = new RestTemplate();
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        // 构造请求体
+        String requestBody = "{\n" +
+                "    \"appKey\": \"" + APP_KEY + "\",\n" +
+                "    \"appSecret\": \"" + APP_SECRET + "\"\n" +
+                "}";
+        HttpEntity<String> entity = new HttpEntity<>(requestBody, headers);
+        try {
+            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);
+            JSONObject jsonObject = JSON.parseObject(response.getBody());
+            return jsonObject.getString("accessToken");
+        } catch (Exception e) {
+            throw new ServiceException("获取AccessToken失败");
+        }
+    }
+
+    /**
+     * 获取unionId 操作人id
+     * @return
+     */
+    public  Object getUserInfo(String accessToken,String key,String userid){
+        String url = "https://oapi.dingtalk.com/topapi/v2/user/get?access_token="+accessToken;
+        RestTemplate restTemplate = new RestTemplate();
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        Map<String, String> requestBody = new HashMap<>();
+        requestBody.put("language", "zh_CN");
+        requestBody.put("userid", userid);
+        ObjectMapper objectMapper = new ObjectMapper();
+        try {
+            String jsonString = objectMapper.writeValueAsString(requestBody);
+            HttpEntity<String> entity = new HttpEntity<>(jsonString, headers);
+            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);
+            JSONObject jsonObject = JSON.parseObject(response.getBody());
+            JSONObject result = jsonObject.getJSONObject("result");
+            return result.get(key);
+        } catch (Exception e) {
+            throw new ServiceException("获取用户信息失败");
+        }
+    }
+
+    //获取会议室列表
+    public  String getMeetings(String accessToken,String unionId) {
+        if (accessToken == null || accessToken.isEmpty()) {
+            System.out.println("获取accessToken失败");
+            return null;
+        }
+        // 构建请求URL,包含必要的查询参数
+        String baseUrl = DINGTALK_API_BASE + "rooms/meetingRoomLists";
+        UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(baseUrl)
+                .queryParam("unionId", unionId);
+        RestTemplate restTemplate = new RestTemplate();
+        HttpHeaders headers = new HttpHeaders();
+        // 设置必要的请求头
+        headers.set("x-acs-dingtalk-access-token", accessToken);
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<?> entity = new HttpEntity<>(headers);
+        try {
+            // 使用GET方法发送请求
+            ResponseEntity<String> response = restTemplate.exchange(
+                    uriBuilder.toUriString(),
+                    HttpMethod.GET,
+                    entity,
+                    String.class
+            );
+            if (response.getStatusCode().is2xxSuccessful()) {
+                return response.getBody();
+            } else {
+                throw new SecurityException("获取会议室列表异常");
+            }
+        } catch (Exception e) {
+            throw new SecurityException("获取会议室列表异常");
+        }
+    }
+
+//    //获取会议室详情
+//    public  String getMeetingDetail(String accessToken,String roomId,String unionId) {
+//        // 构建请求URL(注意是meetingRooms单个资源路径,不是列表接口)
+//        String baseUrl = DINGTALK_API_BASE + "rooms/meetingRooms/" + roomId;
+//        UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(baseUrl)
+//                .queryParam("unionId", unionId);
+//
+//        // 创建REST模板并设置请求头
+//        RestTemplate restTemplate = new RestTemplate();
+//        HttpHeaders headers = new HttpHeaders();
+//        headers.set("x-acs-dingtalk-access-token", accessToken);
+//        headers.setContentType(MediaType.APPLICATION_JSON);
+//        // 添加User-Agent头,模拟浏览器请求
+//        headers.set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");
+//        HttpEntity<?> entity = new HttpEntity<>(headers);
+//        try {
+//            // 发送GET请求
+//            ResponseEntity<String> response = restTemplate.exchange(
+//                    uriBuilder.toUriString(),
+//                    HttpMethod.GET,
+//                    entity,
+//                    String.class
+//            );
+//            // 处理响应
+//            if (response.getStatusCode().is2xxSuccessful()) {
+//                return response.getBody();
+//            } else {
+//                throw new ServiceException("获取会议室详情异常");
+//            }
+//        } catch (Exception e) {
+//           throw new ServiceException("获取会议室详情失败");
+//        }
+//    }
+
+
+    public  String getMeetingHistory(String accessToken, String unionId,String[] roomIds, String startTime, String endTime) {
+        // 构建请求 URL,包含 Path 参数 userId
+        String baseUrl = DINGTALK_API_BASE + "calendar/users/{userId}/meetingRooms/schedules/query";
+        Map<String, Object> paramMap = new HashMap<>();
+        paramMap.put("userId", unionId);
+        UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(baseUrl)
+                .uriVariables(paramMap);
+        RestTemplate restTemplate = new RestTemplate();
+        HttpHeaders headers = new HttpHeaders();
+        // 设置请求头
+        headers.set("x-acs-dingtalk-access-token", accessToken);
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        // 构建请求体参数(Body 参数)
+        Map<String, Object> requestBody = new HashMap<>();
+        // 替换为实际的会议室 roomId 列表,建议不超过 5 个
+        requestBody.put("roomIds", roomIds);
+        // 替换为实际的查询开始时间,需符合 iso8601 格式,如 "2025-08-30T00:00:00Z"
+        requestBody.put("startTime", startTime);
+        // 替换为实际的查询结束时间,需符合 iso8601 格式,如 "2025-08-31T00:00:00Z"
+        requestBody.put("endTime", endTime);
+        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);
+        try {
+            // 使用 POST 方法发送请求
+            ResponseEntity<String> response = restTemplate.exchange(
+                    uriBuilder.toUriString(),
+                    HttpMethod.POST,
+                    entity,
+                    String.class
+            );
+            if (response.getStatusCode().is2xxSuccessful()) {
+                return response.getBody();
+            } else {
+                throw new ServiceException("获取会议室历史异常");
+            }
+        } catch (Exception e) {
+            throw new ServiceException("获取会议室历史异常");
+        }
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}

+ 15 - 0
blade-service/blade-dingding/src/main/java/org/springblade/dingding/vo/MeetingSchedule.java

@@ -0,0 +1,15 @@
+package org.springblade.dingding.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+//今日预定场次
+public class MeetingSchedule {
+    private String meetingId;
+    private String reservationTime; //预约时间
+    private String reservationDept; //预约部门
+}

+ 24 - 0
blade-service/blade-dingding/src/main/java/org/springblade/dingding/vo/MeetingVo.java

@@ -0,0 +1,24 @@
+package org.springblade.dingding.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class MeetingVo {
+    private String roomId;
+    private String fixedData; //固定数据
+    private String meetingTheme; //会议主题
+    private String meetingDept;  //召开部门
+    private String meetingBooker;//会议预定者,主持人
+    private String participants; //参会人员
+    private String meetingTime; //会议时间
+    private Integer status; //会议时间 1空闲中 2会议中
+    private Integer meetingSession; //今日会议场次
+    private List<MeetingSchedule> meetings; //今日预定会议场次详情
+
+}

+ 14 - 0
blade-service/blade-dingding/src/main/java/org/springblade/dingding/vo/ScheduleItem.java

@@ -0,0 +1,14 @@
+package org.springblade.dingding.vo;
+
+import lombok.Data;
+
+@Data
+public class ScheduleItem {
+    private String eventId;
+    private String status;
+    private String organizerId;
+    private String startDateTime;
+    private String startTimeZone;
+    private String endDateTime;
+    private String endTimeZone;
+}

+ 10 - 0
blade-service/blade-dingding/src/main/resources/application-dev.yml

@@ -0,0 +1,10 @@
+#服务器端口
+server:
+  port: 9120
+
+#数据源配置
+spring:
+  datasource:
+    url: ${blade.datasource.dev.url}
+    username: ${blade.datasource.dev.username}
+    password: ${blade.datasource.dev.password}

+ 10 - 0
blade-service/blade-dingding/src/main/resources/application-prod.yml

@@ -0,0 +1,10 @@
+#服务器端口
+server:
+  port: 9120
+
+#数据源配置
+spring:
+  datasource:
+    url: ${blade.datasource.dev.url}
+    username: ${blade.datasource.dev.username}
+    password: ${blade.datasource.dev.password}

+ 10 - 0
blade-service/blade-dingding/src/main/resources/application-test.yml

@@ -0,0 +1,10 @@
+#服务器端口
+server:
+  port: 9120
+
+#数据源配置
+spring:
+  datasource:
+    url: ${blade.datasource.dev.url}
+    username: ${blade.datasource.dev.username}
+    password: ${blade.datasource.dev.password}

+ 1 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ExcelTabMapper.xml

@@ -169,6 +169,7 @@
         dept.parent_id,
         dept.name,
         dept.file_type,
+        dept.tab_id,
         (
         SELECT
         CASE WHEN count(1) > 0 THEN 1 ELSE 0 END

+ 69 - 41
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsFormElementServiceImpl.java

@@ -585,18 +585,29 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
 
                         //String eTypeFiled = getInitTableFiledType(wbsFormElementInfo.getEType());
                         //int eLengthFiled = Integer.parseInt(setDefaultElementLength(wbsFormElementInfo.getEType()));
-
-                        //判断是否存在该Key字段
-                        int row1 = wbsTreeMapper.isThereAField(wbsTree.getInitTableName(), key);
-                        if (row1 == 0) {
-                            //追加字段到实体表中
-                            wbsTreeMapper.alterTableFiled(wbsTree.getInitTableName(), key, "varchar", DEFAULT_ELEMENT_LENGTH_VARCHAR);
-                            //判断是否追加成功
-                            int row2 = wbsTreeMapper.isThereAField(wbsTree.getInitTableName(), key);
-                            if (row2 != 1) {
-                                //追加失败,删除元素,跳过
-                                baseMapper.deleteElementByfId2(wbsFormElementInfo.getId());
-                                continue;
+                        if (newKeyNumber > 80) {
+                            //判断是否存在该Key字段
+                            int row1 = wbsTreeMapper.isThereAField(wbsTree.getInitTableName(), "key_201");
+                            if (row1 == 0) {
+                                try {
+                                    jdbcTemplate.execute("alter table " + wbsTree.getInitTableName() + " add key_201 text");
+                                } catch (Exception e) {
+                                    e.printStackTrace();
+                                }
+                            }
+                        } else {
+                            //判断是否存在该Key字段
+                            int row1 = wbsTreeMapper.isThereAField(wbsTree.getInitTableName(), key);
+                            if (row1 == 0) {
+                                //追加字段到实体表中
+                                wbsTreeMapper.alterTableFiled(wbsTree.getInitTableName(), key, "varchar", DEFAULT_ELEMENT_LENGTH_VARCHAR);
+                                //判断是否追加成功
+                                int row2 = wbsTreeMapper.isThereAField(wbsTree.getInitTableName(), key);
+                                if (row2 != 1) {
+                                    //追加失败,删除元素,跳过
+                                    baseMapper.deleteElementByfId2(wbsFormElementInfo.getId());
+                                    continue;
+                                }
                             }
                         }
                         newKeyNumber++;
@@ -661,18 +672,29 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
 
                     //String eTypeFiled = getInitTableFiledType(wbsFormElementInfo.getEType());
                     //int eLengthFiled = Integer.parseInt(setDefaultElementLength(wbsFormElementInfo.getEType()));
-
-                    //判断是否存在该Key字段
-                    int row1 = wbsTreeMapper.isThereAField(wbsTree.getInitTableName(), key);
-                    if (row1 == 0) {
-                        //追加字段到实体表中
-                        wbsTreeMapper.alterTableFiled(wbsTree.getInitTableName(), key, "varchar", DEFAULT_ELEMENT_LENGTH_VARCHAR);
-                        //判断是否追加成功
-                        int row2 = wbsTreeMapper.isThereAField(wbsTree.getInitTableName(), key);
-                        if (row2 != 1) {
-                            //追加失败,删除元素,跳过
-                            baseMapper.deleteElementByfId2(wbsFormElementInfo.getId());
-                            continue;
+                    if (newKeyNumber > 80) {
+                        //判断是否存在该Key字段
+                        int row1 = wbsTreeMapper.isThereAField(wbsTree.getInitTableName(), "key_201");
+                        if (row1 == 0) {
+                            try {
+                                jdbcTemplate.execute("alter table " + wbsTree.getInitTableName() + " add key_201 text");
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                            }
+                        }
+                    } else {
+                        //判断是否存在该Key字段
+                        int row1 = wbsTreeMapper.isThereAField(wbsTree.getInitTableName(), key);
+                        if (row1 == 0) {
+                            //追加字段到实体表中
+                            wbsTreeMapper.alterTableFiled(wbsTree.getInitTableName(), key, "varchar", DEFAULT_ELEMENT_LENGTH_VARCHAR);
+                            //判断是否追加成功
+                            int row2 = wbsTreeMapper.isThereAField(wbsTree.getInitTableName(), key);
+                            if (row2 != 1) {
+                                //追加失败,删除元素,跳过
+                                baseMapper.deleteElementByfId2(wbsFormElementInfo.getId());
+                                continue;
+                            }
                         }
                     }
                     newKeyNumber++;
@@ -740,18 +762,29 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
 
                     //String eTypeFiled = getInitTableFiledType(wbsFormElementInfo.getEType());
                     //int eLengthFiled = Integer.parseInt(setDefaultElementLength(wbsFormElementInfo.getEType()));
-
-                    //判断是否存在该Key字段
-                    int row1 = wbsTreeMapper.isThereAField(wbsTree.getInitTableName(), key);
-                    if (row1 == 0) {
-                        //追加字段到实体表中
-                        wbsTreeMapper.alterTableFiled(wbsTree.getInitTableName(), key, "varchar", DEFAULT_ELEMENT_LENGTH_VARCHAR);
-                        //判断是否追加成功
-                        int row2 = wbsTreeMapper.isThereAField(wbsTree.getInitTableName(), key);
-                        if (row2 == 0) {
-                            //追加失败,删除元素,跳过
-                            baseMapper.deleteElementByfId2(wbsFormElementInfo.getId());
-                            continue;
+                    if (newKeyNumber > 80) {
+                        //判断是否存在该Key字段
+                        int row1 = wbsTreeMapper.isThereAField(wbsTree.getInitTableName(), "key_201");
+                        if (row1 == 0) {
+                            try {
+                                jdbcTemplate.execute("alter table " + wbsTree.getInitTableName() + " add key_201 text");
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                            }
+                        }
+                    } else {
+                        //判断是否存在该Key字段
+                        int row1 = wbsTreeMapper.isThereAField(wbsTree.getInitTableName(), key);
+                        if (row1 == 0) {
+                            //追加字段到实体表中
+                            wbsTreeMapper.alterTableFiled(wbsTree.getInitTableName(), key, "varchar", DEFAULT_ELEMENT_LENGTH_VARCHAR);
+                            //判断是否追加成功
+                            int row2 = wbsTreeMapper.isThereAField(wbsTree.getInitTableName(), key);
+                            if (row2 == 0) {
+                                //追加失败,删除元素,跳过
+                                baseMapper.deleteElementByfId2(wbsFormElementInfo.getId());
+                                continue;
+                            }
                         }
                     }
                     newKeyNumber++;
@@ -996,11 +1029,6 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
                     log.error("新增字段异常:", e);
                 }
             }
-            //判断是否追加成功
-            int row2 = wbsTreeMapper.isThereAField(initTableName, "key_201");
-            if (row2 != 1) {
-                throw new ServiceException("新增字段异常, 请联系后台管理员处理");
-            }
         }
     }
 }

+ 49 - 19
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -65,6 +65,7 @@ import org.springblade.manager.mapper.*;
 import org.springblade.manager.service.INodeBaseInfoService;
 import org.springblade.manager.service.ITableFileService;
 import org.springblade.manager.service.IWbsTreeContractService;
+import org.springblade.manager.util.DataStructureFormatUtils;
 import org.springblade.manager.utils.CompositeKey;
 import org.springblade.manager.vo.*;
 import org.springblade.system.cache.ParamCache;
@@ -894,32 +895,32 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                     break;
                 }
             }
-
-            if (DataMap != null && DataMap.size() >= 1) {
-                String dataCol = "";
+            String dataCol = "";
+            for (int j = 0; j < dataSize; j++) {
+                if (j == dataSize - 1) {
+                    dataCol = dataCol + moreData.get(j) + "_^_" + excLenght[j];
+                } else {
+                    dataCol = dataCol + moreData.get(j) + "_^_" + excLenght[j] + "☆";
+                }
+            }
+            boolean flag = isSaveKey201(info, wbsInfo, dataCol);
+            if (!DataMap.isEmpty()) {
                 String updateSql = "update " + wbsInfo.getInitTableName() + " set " + info.getKey() + "=";
-                for (int j = 0; j < dataSize; j++) {
-                    if (j == dataSize - 1) {
-                        dataCol = dataCol + moreData.get(j) + "_^_" + excLenght[j];
-                    } else {
-                        dataCol = dataCol + moreData.get(j) + "_^_" + excLenght[j] + "☆";
-                    }
+                if (flag) {
+                    updateSql = "update " + wbsInfo.getInitTableName() + " set key_201 = concat(key_201,'$$'," + "'" + info.getKey() + ":" + dataCol + "') where p_key_id= " + wbsTreeContract.getPKeyId() + ";";
+                } else {
+                    updateSql = updateSql + "'" + dataCol + "' where p_key_id=" + wbsTreeContract.getPKeyId() + " ;";
                 }
-                updateSql = updateSql + "'" + dataCol + "' where p_key_id=" + wbsTreeContract.getPKeyId() + " ;";
                 moreData = moreData.stream().skip(excLenght.length).map(com.mixsmart.utils.StringUtils::handleNull).collect(Collectors.toList());
                 addSql.append(updateSql);
             } else {
                 long dataId = SnowFlakeUtil.getId();
                 String insertSql = "insert into " + wbsInfo.getInitTableName() + "(id,p_key_id," + info.getKey() + ") VALUES (" + dataId + "," + wbsTreeContract.getPKeyId() + ",'";
-                String dataCol = "";
-                for (int j = 0; j < dataSize; j++) {
-                    if (j == dataSize - 1) {
-                        dataCol = dataCol + moreData.get(j) + "_^_" + excLenght[j];
-                    } else {
-                        dataCol = dataCol + moreData.get(j) + "_^_" + excLenght[j] + "☆";
-                    }
+                if (flag) {
+                    insertSql = "insert into " + wbsInfo.getInitTableName() + "(id,p_key_id,key_201) values (" + dataId + "," + wbsTreeContract.getPKeyId() + ",'" + info.getKey() + ":" + dataCol + "');";
+                } else {
+                    insertSql = insertSql + dataCol + "');";
                 }
-                insertSql = insertSql + dataCol + "');";
                 moreData = moreData.stream().skip(excLenght.length).map(com.mixsmart.utils.StringUtils::handleNull).collect(Collectors.toList());
                 addSql.append(insertSql);
             }
@@ -984,7 +985,11 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                         dataCol = dataCol + moreData.get(j) + "_^_" + excLenght[j] + "☆";
                     }
                 }
-                insertSql = insertSql + dataCol + "');";
+                if (isSaveKey201(info, wbsInfo, dataCol)) {
+                    insertSql = "insert into " + wbsInfo.getInitTableName() + "(id,p_key_id,key_201) values (" + dataId + "," + wbsTreeContract.getPKeyId() + ",'" + info.getKey() + ":" + dataCol + "');";
+                } else {
+                    insertSql = insertSql + dataCol + "');";
+                }
                 moreData = moreData.stream().skip(excLenght.length).map(com.mixsmart.utils.StringUtils::handleNull).collect(Collectors.toList());
                 addSql.append(insertSql);
             }
@@ -1003,6 +1008,31 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         return false;
     }
 
+    private boolean isSaveKey201(RangeInfo info, WbsTreeContract wbsInfo, String dataCol) {
+        boolean flag = false;
+        try {
+            String[] split = info.getKey().split("_");
+            flag = split.length > 1 && StringUtil.isNumeric(split[1]) && Integer.parseInt(split[1]) > 80;
+            if (!flag) {
+                List<Map<String, Object>> fieldMap = jdbcTemplate.queryForList("select distinct COLUMN_NAME as fieldName, CHARACTER_MAXIMUM_LENGTH as fieldLength from information_schema.COLUMNS where  TABLE_NAME = '" + wbsInfo.getInitTableName() +
+                        "' and COLUMN_NAME in ('" + info.getKey() + "', 'key_201" + "')");
+                if (!fieldMap.isEmpty()) {
+                    Map<String, Object> map1 = fieldMap.stream().filter(map -> map.get("fieldName") != null).collect(Collectors.toMap(map -> map.get("fieldName") + "", map -> map.get("fieldLength")));
+                    Object length = map1.get(info.getKey());
+                    if (length != null && Integer.parseInt(length.toString()) > dataCol.length()) {
+                        flag = true;
+                        if (map1.get("key_201") == null) {
+                            jdbcTemplate.execute("alter table " + wbsInfo.getInitTableName() + " add column key_201 text ");
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return flag;
+    }
+
     @Override
     public void syncCurrentFormToAllContract(WbsTreePrivate wbsTreePrivate) {
         baseMapper.syncCurrentFormToAllContract(wbsTreePrivate);

+ 13 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java

@@ -308,8 +308,19 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
                             wbsFormElement.setRemark(map.get("备注"));
 
                             wbsFormElementService.save(wbsFormElement);
-
-                            baseMapper.alterTableFiled(initTableName, wbsFormElement.getEKey(), "varchar", WbsFormElementServiceImpl.DEFAULT_ELEMENT_LENGTH_VARCHAR);
+                            if (keyNumb[0] > 80) {
+                                //判断是否存在该Key字段
+                                int row1 = wbsTreeMapper.isThereAField(wbsTree.getInitTableName(), "key_201");
+                                if (row1 == 0) {
+                                    try {
+                                        jdbcTemplate.execute("alter table " + wbsTree.getInitTableName() + " add key_201 text");
+                                    } catch (Exception e) {
+                                        e.printStackTrace();
+                                    }
+                                }
+                            } else {
+                                baseMapper.alterTableFiled(initTableName, wbsFormElement.getEKey(), "varchar", WbsFormElementServiceImpl.DEFAULT_ELEMENT_LENGTH_VARCHAR);
+                            }
                         }
 
                     });

+ 1 - 0
pom.xml

@@ -41,6 +41,7 @@
         <module>blade-service</module>
         <module>blade-service-api</module>
         <module>blade-service/blade-repair</module>
+        <module>blade-service/blade-dingding</module>
     </modules>
 
     <dependencyManagement>