Parcourir la source

Merge branch 'refs/heads/master' into 工单统计添加部门筛选

yusm il y a 2 semaines
Parent
commit
cc8ed027cb
24 fichiers modifiés avec 1228 ajouts et 73 suppressions
  1. 23 1
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/home/index.vue
  2. 230 0
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/my/index copy 2.vue
  3. 14 10
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/my/index.vue
  4. 9 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ExcelParserService.java
  5. 66 28
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  6. 204 5
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/AlertTimeController.java
  7. 21 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/ApplyFormController.java
  8. 2 2
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/AttendanceStaffController.java
  9. 7 2
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/HighTemperatureSetController.java
  10. 7 2
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/SpecialDateSetController.java
  11. 10 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/UserController.java
  12. 99 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/entity/ApplyForm.java
  13. 6 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/entity/AttendanceStaff.java
  14. 16 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/mapper/ApplyFormMapper.java
  15. 16 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/ApplyFormService.java
  16. 1 1
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/AttendanceStaffService.java
  17. 20 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/ApplyFormServiceImpl.java
  18. 13 3
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/AttendanceStaffServiceImpl.java
  19. 377 1
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/task/TimingTask.java
  20. 24 0
      fhKeeper/formulahousekeeper/management-workshop/src/main/resources/mapper/ApplyFormMapper.xml
  21. 1 1
      fhKeeper/formulahousekeeper/octopus/src/views/customer/list.vue
  22. 21 7
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  23. 32 6
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue
  24. 9 2
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/weekEdit.vue

+ 23 - 1
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/home/index.vue

@@ -3,6 +3,7 @@
     <template v-slot:headerLeft>
       <div class="homeheaderleft">
         <img src="/src/assets/image/home_logo.png">
+        <!-- <div class="text-white">客户管家<ww-open-data :openid="useInfo.userInfo.name" type="userName"></ww-open-data></div> -->
         <div class="text-white">客户管家</div>
       </div>
     </template>
@@ -10,6 +11,7 @@
     <template v-slot:body>
       <div class="home-theBack"></div>
       <div class="home-theContent">
+        <div class="hoPlaceholderSymbol"><ww-open-data :openid="useInfo.userInfo.name" type="userName"></ww-open-data></div>
         <!-- 固定头部 -->
         <div class="home-theContent-title">
           <div class="item" v-for="(item, index) in addQuickList" :key="index">
@@ -218,7 +220,21 @@ function obtainEnterpriseWeChatParameters(data = {}) {
           jsApiList: ['selectExternalContact', 'openThirdAppServiceChat', 'openAppManage'], //必填,传入需要使用的接口名称
           success: function (result) {
             //  wx.agentConfig成功回调后,WWOpenData 才会注入到 window 对象上面
-            window.WWOpenData.bind(document.querySelector('ww-open-data'))
+            // window.WWOpenData.bind(document.querySelector('ww-open-data'))
+            setTimeout(() => {
+              const el = document.querySelector('ww-open-data');
+              console.log(el, '<======= el')
+              if (el) {
+                try {
+                  window.WWOpenData.bind(el);
+                  console.log('WWOpenData.bind 成功执行');
+                } catch (e) {
+                  console.error('WWOpenData.bind 执行出错:', e);
+                }
+              } else {
+                console.warn('ww-open-data 元素不存在');
+              }
+            }, 1000)
           },
           fail: function (res) {
             if (res.errMsg.indexOf('function not exist') > -1) {
@@ -388,4 +404,10 @@ useLifecycle({
 .block-div {
   padding: 14px 0;
 }
+
+.hoPlaceholderSymbol {
+  position: absolute;
+  left: -500vw;
+  top: -200vh;
+}
 </style>

+ 230 - 0
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/my/index copy 2.vue

@@ -0,0 +1,230 @@
+<template>
+  <div class="personalCenter">
+    <div class="personalCenter-top flex flex-col">
+      <div class="px-4 flex justify-between items-center avatarSection">
+        <div class="flex items-center">
+          <div
+            class="bg-[#fff] text-[#333] flex items-center justify-center profilePicture"
+          >
+            <TranslationComponent :openId="userInfo.userInfo.name" />
+          </div>
+          <div class="ml-8 profilePicture-text">
+            <TranslationComponent :openId="userInfo.userInfo.name" /> <br />
+            <div class="jobIdEtc">工号:{{ userInfo.userInfo.jobNumber ? userInfo.userInfo.jobNumber : '待配置' }}</div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="flex-1 overflow-y-auto personalCenter-content">
+      <div class="flex flex-row items-center justify-between">
+        <div class="list-tile flex">
+          <img src="../../../assets/image/dqbb.png" alt="" />
+          <div class="list-tile-text">当前版本</div>
+        </div>
+        <div class="list-text">{{ ['', '专业版本', '旗舰版本'][userInfo.userInfo?.company?.versionControl] }}</div>
+      </div>
+      <div class="flex flex-row items-center justify-between" v-if="userInfo.userInfo.userNameNeedTranslate != '1' && (isCorpWX || isWX)" @click="bindWeiXin">
+        <div class="list-tile flex">
+          <img src="../../../assets/image/dqbb.png" alt="" />
+          <div class="list-tile-text">{{ `绑定${isCorpWX ? '企业' : ''}微信` }}</div>
+        </div>
+        <div class="list-text">
+          (
+            <span v-if="(isCorpWX && userInfo.userInfo.corpwxUserid == null) || (isWX && userInfo.userInfo.wxOpenid == null)">未绑定</span>
+            <span v-if="(isCorpWX && userInfo.userInfo.corpwxUserid != null) || (isWX && userInfo.userInfo.wxOpenid != null)">已绑定</span>
+          )
+        </div>
+      </div>
+      <div class="flex flex-row items-center justify-between mt-3">
+        <div class="list-tile flex">
+          <img src="../../../assets/image/gsmc.png" alt="" />
+          <div class="list-tile-text">公司名称</div>
+        </div>
+        <div class="list-text">{{ userInfo.userInfo?.company?.companyName }}</div>
+      </div>
+      <div class="flex flex-row items-center justify-between mt-3">
+        <div class="list-tile flex">
+          <img src="../../../assets/image/dqzh.png" alt="" />
+          <div class="list-tile-text">账号角色</div>
+        </div>
+        <div class="list-text">{{ userInfo.userInfo?.roleName }}</div>
+      </div>
+      <div class="flex flex-row items-center justify-between mt-3">
+        <div class="list-tile flex">
+          <img src="../../../assets/image/yxrq.png" alt="" />
+          <div class="list-tile-text">有效日期</div>
+        </div>
+        <div class="list-text">{{ userInfo.userInfo?.company?.expirationDate }}</div>
+      </div>
+      <div class="flex flex-row items-center justify-between mt-3" @click="instructions()">
+        <div class="list-tile flex">
+          <img src="../../../assets/image/sysm.png" alt="" />
+          <div class="list-tile-text">使用说明</div>
+        </div>
+        <img src="../../../assets/image/rightArrow.png" class="list-text-img"></img>
+      </div>
+      <div class="flex flex-row items-center justify-between mt-3" @click="applicationMarket()">
+        <div class="list-tile flex">
+          <img src="../../../assets/image/yysc.png" alt="" />
+          <div class="list-tile-text">应用市场</div>
+        </div>
+        <img src="../../../assets/image/rightArrow.png" class="list-text-img"></img>
+      </div>
+    </div>
+    <div><Footer /></div>
+  </div>
+</template>
+
+<script setup>
+import { ref } from "vue";
+import { useLifecycle } from "@hooks/useCommon.js";
+import useRouterStore from "@store/useRouterStore.js";
+import useInfoStore from "@store/useInfoStore.js";
+import Footer from "@components/page/footer.vue";
+
+const router = useRouterStore();
+const userInfo = useInfoStore();
+const isCorpWX = ref(false);
+const isWX = ref(false);
+
+function instructions() {
+  // router.navigateTo({
+  //   pathName: "pdfPreview",
+  // });
+  // 新窗口打开链接
+  window.open("https://crm.ttkuaiban.com/upload/mobileUserManual.pdf");
+}
+
+function bindWeiXin() {
+  //企业微信
+  if (isCorpWX.value && userInfo.userInfo.corpwxUserid != null) {
+    return;
+  }
+  //微信
+  else if (isWX.value && userInfo.userInfo.wxOpenid != null) {
+    return;
+  }
+
+  var appId = "wx1c1d8fc81bc073a8"; //智能客户管家公众号
+  var url =
+    "https://mobcrm.ttkuaiban.com/api/wechat/bindWeiXin2?userId=" +
+    userInfo.userInfo.id; //工时管家公众号授权回调页面
+  if (isCorpWX.value) {
+    appId = "ww4e237fd6abb635af"; //企业微信第三方的SUIT ID
+    url =
+      "https://crm.ttkuaiban.com/api/wxcorp/bindCorpWeiXin?userId=" +
+      userInfo.userInfo.id; //授权回调页面
+  }
+
+  var weixinUrl =
+    "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" +
+    appId +
+    "&redirect_uri=" +
+    encodeURI(url) +
+    "&response_type=code&scope=snsapi_base&state=0#wechat_redirect";
+  window.location.href = weixinUrl;
+}
+
+function signOut() {
+  router.redirectTo({
+    pathName: "login",
+    success: () => {
+      localStorage.clear();
+      sessionStorage.clear();
+      window.location.reload();
+    },
+  });
+}
+
+function judgingTheEnvironment() {
+  const currentEnvironment = navigator.userAgent.toLowerCase();
+  isCorpWX.value = currentEnvironment.indexOf("wxwork") > 0 ? true : false;
+  isWX.value = currentEnvironment.indexOf("micromessenger") > 0 ? true : false;
+}
+
+const applicationMarket = () => {
+  window.location.href = "https://www.ttkuaiban.com/appMarket.html";
+  // window.open('https://www.ttkuaiban.com/appMarket.html', '_blank');
+};
+
+useLifecycle({
+  load: () => {
+    judgingTheEnvironment();
+  },
+});
+</script>
+
+<style lang="scss" scoped>
+.profilePicture {
+  width: 70px;
+  height: 70px;
+  border-radius: 50%;
+  font-size: 16px;
+  font-weight: bold;
+}
+.profilePicture-text {
+  font-size: 18px;
+  color: #fff;
+}
+.profilePicture-img {
+  width: 24px;
+}
+.list-imgs {
+  width: 14px;
+}
+.personalCenter {
+  width: 100%;
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+  background-color: #fff;
+}
+.personalCenter-top {
+  width: 100%;
+  height: 180px;
+  background-image: url("../../../assets/image/grzxbjs.png");
+  background-size: cover;
+}
+.avatarSection {
+  padding: 52px 30px 0 30px;
+}
+.jobIdEtc {
+  font-size: 13px;
+  color: #92bdee;
+  margin-top: 4px;
+}
+.personalCenter-content {
+  width: 100%;
+  border-top-left-radius: 15px;
+  border-top-right-radius: 15px;
+  background-color: #fff;
+  position: relative;
+  padding: 20px 26px 0 26px;
+  top: -18px;
+}
+.list-text {
+  color: #A6A6A6;
+  font-weight: medium;
+  font-size: 12px;
+  position: relative;
+  top: -3px;
+}
+.list-tile {
+  color: #000000;
+  font-weight: medium;
+  font-size: 12px;
+}
+.list-tile img {
+  width: 28px;
+}
+.list-tile-text{
+  position: relative;
+  top: 2px;
+  margin-left: 10px;
+}
+.list-text-img {
+  width: 16px;
+  position: relative;
+  top: -3px;
+}
+</style>

+ 14 - 10
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/my/index.vue

@@ -161,6 +161,7 @@ useLifecycle({
   border-radius: 50%;
   font-size: 16px;
   font-weight: bold;
+  overflow: hidden; // iOS 裁剪问题
 }
 .profilePicture-text {
   font-size: 18px;
@@ -174,7 +175,7 @@ useLifecycle({
 }
 .personalCenter {
   width: 100%;
-  height: 100vh;
+  min-height: 100dvh; // 修复 iOS vh 问题
   display: flex;
   flex-direction: column;
   background-color: #fff;
@@ -198,35 +199,38 @@ useLifecycle({
   border-top-left-radius: 15px;
   border-top-right-radius: 15px;
   background-color: #fff;
-  position: relative;
   padding: 20px 26px 0 26px;
-  top: -18px;
+  margin-top: -18px; // 替代 top: -18px
+  flex: 1;
+  overflow-y: auto;
+  -webkit-overflow-scrolling: touch; // iOS 滚动优化
 }
 .list-text {
   color: #A6A6A6;
-  font-weight: medium;
-  font-size: 12px;
-  line-height: normal;
+  font-weight: 500; // 修复非法值
+  font-size: 14px;
   position: relative;
   top: -3px;
 }
 .list-tile {
   color: #000000;
-  font-weight: medium;
-  font-size: 12px;
-  line-height: normal;
+  font-weight: 500;
+  font-size: 14px;
 }
 .list-tile img {
   width: 28px;
+  display: block; // 修复 iOS 点击问题
 }
-.list-tile-text{
+.list-tile-text {
   position: relative;
   top: 2px;
   margin-left: 10px;
 }
 .list-text-img {
   width: 16px;
+  display: block;
   position: relative;
   top: -3px;
 }
+
 </style>

+ 9 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ExcelParserService.java

@@ -145,8 +145,8 @@ public class ExcelParserService {
     }
 
     public static void main(String[] args) {
-        String startTime = "08:30";
-        String endTime = "18:16";
+        String startTime = "08:29";
+        String endTime = "18:07";
         double workHours = calculateZhengBeiWorkHours(startTime, endTime);
 
         System.out.println("工作时长:" + workHours + "小时");
@@ -155,6 +155,13 @@ public class ExcelParserService {
     public static double calculateZhengBeiWorkHours(String startTime, String endTime) {
         // 简单计算工作时长(小时)
         // 实际应用中需要更精确的计算,考虑午休时间等
+        if (startTime.compareTo("08:30") < 0) {
+            startTime = "08:30";
+        }
+        // 12:00-13:00为午休,中间来的得从下午上班时间开始算
+        if (startTime.compareTo("12:00") > 0 && startTime.compareTo("13:00") < 0) {
+            startTime = "13:00";
+        }
         String[] startParts = startTime.split(":");
         boolean isEndNextDay = endTime.startsWith("次日");
         if (endTime.startsWith("次日")) {

+ 66 - 28
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -705,22 +705,34 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 }
                 Project project = allProjectList.stream().filter(p -> p.getId().equals(r.getProjectId())).findFirst().get();
                 //处理维度列表数据
-                if (timeTypeMapper.selectById(companyId).getCustomDegreeActive() == 1) {
-                    String associateDegrees = project.getAssociateDegrees();
-                    List<HashMap> degreeMapList = new ArrayList<>();
-                    if (associateDegrees != null) {
-                        String[] split = associateDegrees.split("\\,");
-                        for (int i=0;i<split.length; i++) {
-                            HashMap map = new HashMap();
-                            if (!StringUtils.isEmpty(split[i])) {
-                                Integer id = Integer.parseInt(split[i]);
-                                map.put("id", id);
-                                map.put("name", degreeList.stream().filter(d->d.getId().equals(id)).findFirst().get().getName());
-                                degreeMapList.add(map);
+                if (timeType.getCustomDegreeActive() == 1) {
+                    if (timeType.getCustomDegreeWithPro() == 1) {
+                        String associateDegrees = project.getAssociateDegrees();
+                        List<HashMap> degreeMapList = new ArrayList<>();
+                        if (associateDegrees != null) {
+                            String[] split = associateDegrees.split("\\,");
+                            for (int i=0;i<split.length; i++) {
+                                HashMap map = new HashMap();
+                                if (!StringUtils.isEmpty(split[i])) {
+                                    Integer id = Integer.parseInt(split[i]);
+                                    map.put("id", id);
+                                    map.put("name", degreeList.stream().filter(d->d.getId().equals(id)).findFirst().get().getName());
+                                    degreeMapList.add(map);
+                                }
                             }
                         }
+                        r.setDegreeList(degreeMapList);
+                    } else {
+                        //不关联项目
+                        List<HashMap> degreeMapList = new ArrayList<>();
+                        for (int i=0;i<degreeList.size(); i++) {
+                            HashMap map = new HashMap();
+                            map.put("id", degreeList.get(i).getId());
+                            map.put("name", degreeList.get(i).getName());
+                            degreeMapList.add(map);
+                        }
+                        r.setDegreeList(degreeMapList);
                     }
-                    r.setDegreeList(degreeMapList);
                 }
                 //检查是否是按照任务分组负责人审核
                 int reportAuditType = timeTypeMapper.selectById(companyId).getReportAuditType();
@@ -8798,7 +8810,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     reports.add(recentFillReport);
                 }
             } else {
-                msg.setError("请先设置参与的项目");
+                msg.setError("您尚未填写过日报,无法实现智能填报");
                 return msg;
             }
         }
@@ -8835,23 +8847,37 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 }
 
                 //处理维度列表数据
-                if (timeTypeMapper.selectById(companyId).getCustomDegreeActive() == 1) {
-                    Project project = allProjectList.stream().filter(p -> p.getId().equals(r.getProjectId())).findFirst().get();
-                    String associateDegrees = project.getAssociateDegrees();
-                    List<HashMap> degreeMapList = new ArrayList<>();
-                    if (associateDegrees != null) {
-                        String[] split = associateDegrees.split("\\,");
-                        for (int i=0;i<split.length; i++) {
-                            HashMap map = new HashMap();
-                            if (!StringUtils.isEmpty(split[i])) {
-                                Integer id = Integer.parseInt(split[i]);
-                                map.put("id", id);
-                                map.put("name", degreeList.stream().filter(d->d.getId().equals(id)).findFirst().get().getName());
-                                degreeMapList.add(map);
+                TimeType timeType = timeTypeMapper.selectById(companyId);
+                if (timeType.getCustomDegreeActive() == 1) {
+                    if (timeType.getCustomDegreeWithPro() == 1) {
+                        //和项目绑定的自定义维度
+                        Project project = allProjectList.stream().filter(p -> p.getId().equals(r.getProjectId())).findFirst().get();
+                        String associateDegrees = project.getAssociateDegrees();
+                        List<HashMap> degreeMapList = new ArrayList<>();
+                        if (associateDegrees != null) {
+                            String[] split = associateDegrees.split("\\,");
+                            for (int i=0;i<split.length; i++) {
+                                HashMap map = new HashMap();
+                                if (!StringUtils.isEmpty(split[i])) {
+                                    Integer id = Integer.parseInt(split[i]);
+                                    map.put("id", id);
+                                    map.put("name", degreeList.stream().filter(d->d.getId().equals(id)).findFirst().get().getName());
+                                    degreeMapList.add(map);
+                                }
                             }
                         }
+                        r.setDegreeList(degreeMapList);
+                    } else {
+                        //不关联项目
+                        List<HashMap> degreeMapList = new ArrayList<>();
+                        for (int i=0;i<degreeList.size(); i++) {
+                            HashMap map = new HashMap();
+                            map.put("id", degreeList.get(i).getId());
+                            map.put("name", degreeList.get(i).getName());
+                            degreeMapList.add(map);
+                        }
+                        r.setDegreeList(degreeMapList);
                     }
-                    r.setDegreeList(degreeMapList);
                 }
                 int reportAuditType = timeTypeMapper.selectById(companyId).getReportAuditType();
                 //分组
@@ -8957,6 +8983,18 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 } else {
                     //4和5是所属BU负责人审核和部门负责人审核,不需要前端页面显示审核人
                 }
+
+                //解析自定义多选数组
+                if (!StringUtils.isEmpty(r.getMultiDegrId())) {
+                    String multi = r.getMultiDegrId().replace("@", ",");
+                    JSONArray array = JSONArray.parseArray(multi);
+                    List<Integer> list = new ArrayList<>();
+                    for (int i=0;i<array.size(); i++) {
+                        Integer id = array.getInteger(i);
+                        list.add(id);
+                    }
+                    r.setMultiDegrIdList(list);
+                }
             });
             msg.data = reports;
         } catch (NullPointerException e) {

Fichier diff supprimé car celui-ci est trop grand
+ 204 - 5
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/AlertTimeController.java


+ 21 - 0
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/ApplyFormController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-06-19
+ */
+@RestController
+@RequestMapping("/apply-form")
+public class ApplyFormController {
+
+}
+

+ 2 - 2
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/AttendanceStaffController.java

@@ -38,8 +38,8 @@ public class AttendanceStaffController {
 
     //考勤列表
     @RequestMapping("/getListData")
-    private HttpRespMsg getListData(String month) {
-        return attendanceStaffService.getListData(month);
+    private HttpRespMsg getListData(String month,String userId,Integer pageIndex ,Integer pageSize) {
+        return attendanceStaffService.getListData(month,userId,pageIndex,pageSize);
     }
 
 

+ 7 - 2
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/HighTemperatureSetController.java

@@ -6,11 +6,13 @@ import com.management.platform.entity.HighTemperatureSet;
 import com.management.platform.entity.SpecialDateSet;
 import com.management.platform.service.HighTemperatureSetService;
 import com.management.platform.util.HttpRespMsg;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
 
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -67,9 +69,12 @@ public class HighTemperatureSetController {
     }
 
     @RequestMapping("/deleteHigh")
-    private HttpRespMsg deleteHigh(Integer id){
+    private HttpRespMsg deleteHigh(String ids){
         HttpRespMsg httpRespMsg = new HttpRespMsg();
-        highTemperatureSetService.removeById(id);
+        if (StringUtils.isNotEmpty(ids)){
+            String[] idArray = ids.split(",");
+            highTemperatureSetService.removeByIds(Arrays.asList(idArray));
+        }
         return httpRespMsg;
     }
 

+ 7 - 2
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/SpecialDateSetController.java

@@ -5,11 +5,13 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.management.platform.entity.SpecialDateSet;
 import com.management.platform.service.SpecialDateSetService;
 import com.management.platform.util.HttpRespMsg;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
 
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -64,9 +66,12 @@ public class SpecialDateSetController {
     }
 
     @RequestMapping("/deleteSpecial")
-    private HttpRespMsg deleteSpecial(Integer id){
+    private HttpRespMsg deleteSpecial(String ids){
         HttpRespMsg httpRespMsg = new HttpRespMsg();
-        specialDateSetService.removeById(id);
+        if (StringUtils.isNotEmpty(ids)){
+            String[] idArray = ids.split(",");
+            specialDateSetService.removeByIds(Arrays.asList(idArray));
+        }
         return httpRespMsg;
     }
 

+ 10 - 0
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/UserController.java

@@ -341,5 +341,15 @@ public class UserController {
         return allList.stream().filter(all->all.getDepartmentId().intValue() == id).findFirst().get();
     }
 
+    @RequestMapping("/getAllUserList")
+    private HttpRespMsg getAllUserList(HttpServletRequest request){
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("Token");
+        User user = userService.getById(token);
+        List<User> userList = userService.list(new QueryWrapper<User>().eq("company_id", user.getCompanyId()).eq("is_active", 1));
+        msg.setData(userList);
+        return msg;
+    }
+
 }
 

+ 99 - 0
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/entity/ApplyForm.java

@@ -0,0 +1,99 @@
+package com.management.platform.entity;
+
+import java.math.BigDecimal;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-06-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class ApplyForm extends Model<ApplyForm> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 3:请假单;4:加班申请;(存在一张单据多人请假的情况)5:车间提前下班申请单  6考勤证明补卡单
+     */
+    @TableField("type")
+    private Integer type;
+
+    /**
+     * 申请单类型名称
+     */
+    @TableField("type_name")
+    private String typeName;
+
+    /**
+     * 申请单申请名称
+     */
+    @TableField("apply_bill_name")
+    private String applyBillName;
+
+    /**
+     * 申请人的关键信息,(员工工号)
+     */
+    @TableField("apply_id")
+    private String applyId;
+
+    /**
+     * 申请单单号
+     */
+    @TableField("sp_no")
+    private String spNo;
+
+    /**
+     * 申请单内容
+     */
+    @TableField("content")
+    private String content;
+
+    /**
+     * 开始时间
+     */
+    @TableField("start_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime startTime;
+
+    /**
+     * 结束时间
+     */
+    @TableField("end_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime endTime;
+
+    /**
+     * 总时长
+     */
+    @TableField("sum_time")
+    private BigDecimal sumTime;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 6 - 0
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/entity/AttendanceStaff.java

@@ -98,6 +98,12 @@ public class AttendanceStaff extends Model<AttendanceStaff> {
     @TableField("attendance_type")
     private Integer attendanceType;
 
+    @TableField(exist = false)
+    private String attendanceTypeName; //考勤状态名称
+
+    @TableField(exist = false)
+    private String color;//针对考勤状态对应的颜色
+
     @TableField(exist = false)
     private List<HashMap<String,Object>> maplist;
 

+ 16 - 0
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/mapper/ApplyFormMapper.java

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.ApplyForm;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-06-19
+ */
+public interface ApplyFormMapper extends BaseMapper<ApplyForm> {
+
+}

+ 16 - 0
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/ApplyFormService.java

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.ApplyForm;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-06-19
+ */
+public interface ApplyFormService extends IService<ApplyForm> {
+
+}

+ 1 - 1
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/AttendanceStaffService.java

@@ -18,7 +18,7 @@ public interface AttendanceStaffService extends IService<AttendanceStaff> {
 
     HttpRespMsg refreshData(String month);
 
-    HttpRespMsg getListData(String month);
+    HttpRespMsg getListData(String month,String userId,Integer pageIndex ,Integer pageSize);
 
     HttpRespMsg getAttendanceUserData(String month, String date, String userId, HttpServletRequest request);
 }

+ 20 - 0
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/ApplyFormServiceImpl.java

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.ApplyForm;
+import com.management.platform.mapper.ApplyFormMapper;
+import com.management.platform.service.ApplyFormService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-06-19
+ */
+@Service
+public class ApplyFormServiceImpl extends ServiceImpl<ApplyFormMapper, ApplyForm> implements ApplyFormService {
+
+}

+ 13 - 3
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/AttendanceStaffServiceImpl.java

@@ -1,6 +1,8 @@
 package com.management.platform.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.management.platform.entity.Attendance;
 import com.management.platform.entity.AttendanceStaff;
 import com.management.platform.entity.DayInfo;
@@ -192,10 +194,18 @@ public class AttendanceStaffServiceImpl extends ServiceImpl<AttendanceStaffMappe
     }
 
     @Override
-    public HttpRespMsg getListData(String month) {
+    public HttpRespMsg getListData(String month,String userId,Integer pageIndex ,Integer pageSize) {
         HttpRespMsg msg = new HttpRespMsg();
-        List<AttendanceStaff> list = list(new QueryWrapper<AttendanceStaff>().eq("month", month));
-        msg.setData(list);
+        QueryWrapper<AttendanceStaff> wrapper = new QueryWrapper<AttendanceStaff>().eq("month", month);
+        if (StringUtils.isNotBlank(userId)) {
+            User user = userService.getById(userId);
+            wrapper.eq("job_number", user.getJobNumber());
+        }
+        IPage<Attendance> iPage = page(new Page(pageIndex, pageSize), wrapper);
+        HashMap<String, Object> map = new HashMap<>();
+        map.put("total", iPage.getTotal());
+        map.put("records", iPage.getRecords());
+        msg.setData(map);
         return msg;
     }
 

+ 377 - 1
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/task/TimingTask.java

@@ -10,7 +10,7 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.injector.methods.SelectById;
 import com.management.platform.controller.WeiXinCorpController;
 import com.management.platform.entity.*;
-import com.management.platform.entity.vo.TokenVo;
+import com.management.platform.entity.vo.*;
 import com.management.platform.mapper.*;
 import com.management.platform.service.*;
 import com.management.platform.service.impl.WxCorpInfoServiceImpl;
@@ -113,6 +113,8 @@ public class TimingTask {
     private ReportService reportService;
     @Resource
     private PlanExtraInfoService extraInfoService;
+    @Resource
+    private ApplyFormService applyFormService;
 
     private static final List<Integer> VALID_TOKEN_CHARS = new ArrayList<>();
     static {
@@ -1415,4 +1417,378 @@ public class TimingTask {
 
     }
 
+    public void temporarilyApplyFormData(String endDate, String startDate, Integer templateType) throws Exception {
+        JSONArray jsonArrayFilter = new JSONArray();
+        JSONObject filter1 = new JSONObject();
+        WxCorpTemplate template = wxCorpTemplateService.getOne(new QueryWrapper<WxCorpTemplate>().eq("company_id",7).eq("type",templateType));//3:请假单;4:加班申请;(存在一张单据多人请假的情况)5:车间提前下班申请单  6考勤证明补卡单
+        filter1.put("key","template_id");
+        filter1.put("value",template.getTemplateId());
+        jsonArrayFilter.add(filter1);
+        JSONObject filter2 = new JSONObject();
+        filter2.put("key","sp_status");
+        filter2.put("value","2");
+        jsonArrayFilter.add(filter2);
+        List<String> approvalInfo = wxCorpInfoService.getApprovalInfo(7, startDate, endDate, "", jsonArrayFilter);
+
+        if(approvalInfo!=null&& !approvalInfo.isEmpty()){
+            for (int j = 0; j < approvalInfo.size(); j++) {
+                String codeNum = approvalInfo.get(j);
+                String approvalInfoDetailResp = wxCorpInfoService.getApprovalInfoDetail(7, codeNum);
+                JSONObject jsonObject = JSONObject.parseObject(approvalInfoDetailResp);
+
+                if (templateType==3){
+                    JSONObject info = jsonObject.getJSONObject("info");
+                    String spNo = info.getString("sp_no");
+                    ApplyForm applyForm = new ApplyForm();
+                    int count = applyFormService.count(new QueryWrapper<ApplyForm>().eq("sp_no", spNo));
+                    if (count==0){
+                        String spName = info.getString("sp_name");
+                        applyForm.setType(3);
+                        applyForm.setTypeName(spName);
+                        applyForm.setSpNo(spNo);
+                        JSONObject applyer = info.getJSONObject("applyer");
+                        String applyerId = applyer.getString("userid");
+                        applyForm.setApplyId(applyerId);
+                        JSONObject apply_data = info.getJSONObject("apply_data");
+                        JSONArray contents = apply_data.getJSONArray("contents");
+
+                        for (int i = 0; i < contents.size(); i++) {
+                            JSONObject contentsJSONObject = contents.getJSONObject(i);
+                            JSONArray title = contentsJSONObject.getJSONArray("title");
+                            JSONObject value = contentsJSONObject.getJSONObject("value");
+                            String control = contentsJSONObject.getString("control");
+
+
+                            if (title.getJSONObject(0).getString("text").equals("请假类型")) {
+                                if (control.equals("Vacation")) {
+                                    JSONObject selector = value.getJSONObject("vacation").getJSONObject("selector");
+                                    String type = selector.getString("type");
+
+                                    if (type.equals("single")) {
+                                        JSONObject leaveComment = selector.getJSONArray("options").getJSONObject(0).getJSONArray("value").getJSONObject(0);
+                                        String leaveName = leaveComment.getString("text");
+                                        applyForm.setApplyBillName(leaveName);
+                                    }
+
+                                    JSONObject attendance = value.getJSONObject("vacation").getJSONObject("attendance");
+                                    long begin = attendance.getJSONObject("date_range").getLongValue("new_begin");
+                                    long end = attendance.getJSONObject("date_range").getLongValue("new_end");
+                                    long duration = attendance.getJSONObject("date_range").getLongValue("new_duration");
+
+                                    LocalDateTime startTime = Instant.ofEpochSecond(begin)
+                                            .atZone(ZoneId.systemDefault())
+                                            .toLocalDateTime();
+
+                                    LocalDateTime endTime = Instant.ofEpochSecond(end)
+                                            .atZone(ZoneId.systemDefault())
+                                            .toLocalDateTime();
+                                    // 1. 计算小时(秒 → 小时)
+                                    BigDecimal hours = BigDecimal.valueOf(duration)
+                                            .divide(BigDecimal.valueOf(3600), 1, RoundingMode.HALF_UP);
+                                    applyForm.setStartTime(startTime);
+                                    applyForm.setEndTime(endTime);
+                                    applyForm.setSumTime(hours);
+
+                                }
+                            }
+
+                            if (title.getJSONObject(0).getString("text").equals("请假事由")) {
+                                if (control.equals("Textarea")) {
+                                    String leaveContent = value.getString("text");
+                                    applyForm.setContent(leaveContent);
+                                }
+                            }
+                        }
+
+                        applyFormService.save(applyForm);
+                    }
+                }
+                else if (templateType==4){
+                    OverTimeVo overTimeVo = new OverTimeVo();
+                    ArrayList<DeptVo> deptVoList = new ArrayList<>();
+                    ArrayList<WorkVo> workVoList = new ArrayList<>();
+
+                    JSONObject info = jsonObject.getJSONObject("info");
+                    String spNo = info.getString("sp_no");
+                    Integer spStatus = info.getInteger("sp_status");
+                    String spName = info.getString("sp_name");
+                    Long applyTime = info.getLongValue("apply_time");
+
+                    overTimeVo.setSpNo(spNo);
+                    int count = applyFormService.count(new QueryWrapper<ApplyForm>().eq("sp_no", spNo));
+                    if (count>0){
+                        continue;
+                    }
+                    overTimeVo.setSpName(spName);
+                    overTimeVo.setApplyTime(applyTime);
+                    overTimeVo.setSpStatus(spStatus);
+
+                    JSONObject applyer = info.getJSONObject("applyer");
+                    String applyerId = applyer.getString("userid");
+
+                    overTimeVo.setApplyId(applyerId);
+
+
+                    JSONObject apply_data = info.getJSONObject("apply_data");
+                    JSONArray contents = apply_data.getJSONArray("contents");
+
+                    for (int i = 0; i < contents.size(); i++) {
+                        JSONObject contentsJSONObject = contents.getJSONObject(i);
+                        JSONArray title = contentsJSONObject.getJSONArray("title");
+                        JSONObject value = contentsJSONObject.getJSONObject("value");
+                        String control = contentsJSONObject.getString("control");
+
+
+                        if(title.getJSONObject(0).getString("text").equals("部门(工位)")){
+                            if(control.equals("Contact")){
+                                JSONArray departmentJsons = value.getJSONArray("departments");
+                                for (int i1 = 0; i1 < departmentJsons.size(); i1++) {
+                                    DeptVo deptVo = new DeptVo();
+                                    String dept_openapId = departmentJsons.getJSONObject(i1).getString("openapi_id");
+                                    String name = departmentJsons.getJSONObject(i1).getString("name");
+                                    deptVo.setDeptName(name);
+                                    deptVo.setDeptOpenapId(dept_openapId);
+                                    deptVoList.add(deptVo);
+                                }
+                                overTimeVo.setDeptList(deptVoList);
+                            }
+                        }
+
+                        if(title.getJSONObject(0).getString("text").equals("填报日期")){
+                            if(control.equals("Date")){
+                                JSONObject dateJson = value.getJSONObject("date");
+                                Long submitTime = dateJson.getLongValue("s_timestamp");
+                                overTimeVo.setSubmitTime(submitTime);
+                            }
+                        }
+
+                        if(title.getJSONObject(0).getString("text").equals("明细")){
+                            if(control.equals("Table")){
+                                JSONArray childrens = value.getJSONArray("children");
+                                for (int i1 = 0; i1 < childrens.size(); i1++) {
+                                    JSONArray list = childrens.getJSONObject(i1).getJSONArray("list");
+                                    WorkVo workVo = new WorkVo();
+                                    for (int i2 = 0; i2 < list.size(); i2++) {
+                                        JSONObject workMember = list.getJSONObject(i2);
+                                        //加班成员
+                                        if (workMember.getString("control").equals("Contact")&&workMember.getJSONArray("title").getJSONObject(0).getString("text").equals("加班成员")){
+                                            JSONObject workMemberJSONObjectValue = workMember.getJSONObject("value");
+                                            JSONArray members = workMemberJSONObjectValue.getJSONArray("members");
+                                            ArrayList<MemberVo> memberList = new ArrayList<>();
+                                            for (int i3 = 0; i3 < members.size(); i3++) {
+                                                MemberVo memberVo = new MemberVo();
+                                                String name = members.getJSONObject(i3).getString("name");
+                                                String userid = members.getJSONObject(i3).getString("userid");
+                                                memberVo.setMemberName(name);
+                                                memberVo.setMemberUserId(userid);
+                                                memberList.add(memberVo);
+                                            }
+                                            workVo.setMemberList(memberList);
+                                        }
+                                        //加班事由
+                                        if (workMember.getString("control").equals("Text")&&workMember.getJSONArray("title").getJSONObject(0).getString("text").equals("加班事由")){
+                                            JSONObject workMemberJSONObjectValue = workMember.getJSONObject("value");
+                                            String workCotent = workMemberJSONObjectValue.getString("text");
+                                            workVo.setWorkCotent(workCotent);
+                                        }
+                                        //加班时长
+                                        if (workMember.getString("control").equals("DateRange")&&workMember.getJSONArray("title").getJSONObject(0).getString("text").equals("加班时长")){
+                                            JSONObject workMemberJSONObjectValue = workMember.getJSONObject("value");
+                                            JSONObject workTime = workMemberJSONObjectValue.getJSONObject("date_range");
+                                            workVo.setDuration(workTime.getLongValue("new_duration"));
+                                            workVo.setBeginTime(workTime.getLongValue("new_begin"));
+                                            workVo.setEndTime(workTime.getLongValue("new_end"));
+                                        }
+                                    }
+                                    workVoList.add(workVo);
+                                    overTimeVo.setWorkVoList(workVoList);
+
+                                    List<WorkVo> workVos = overTimeVo.getWorkVoList();
+                                    ArrayList<ApplyForm> applyForms = new ArrayList<>();
+                                    for (WorkVo vo : workVos) {
+                                        String workCotent = vo.getWorkCotent();
+                                        Long beginTime = vo.getBeginTime();
+                                        Long endTime = vo.getEndTime();
+                                        Long duration = vo.getDuration();
+                                        LocalDateTime startTime = Instant.ofEpochSecond(beginTime)
+                                                .atZone(ZoneId.systemDefault())
+                                                .toLocalDateTime();
+
+                                        LocalDateTime end = Instant.ofEpochSecond(endTime)
+                                                .atZone(ZoneId.systemDefault())
+                                                .toLocalDateTime();
+                                        // 1. 计算小时(秒 → 小时)
+                                        BigDecimal hours = BigDecimal.valueOf(duration)
+                                                .divide(BigDecimal.valueOf(3600), 1, RoundingMode.HALF_UP);
+
+                                        List<MemberVo> memberList = vo.getMemberList();
+                                        for (MemberVo memberVo : memberList) {
+                                            ApplyForm applyForm = new ApplyForm();
+                                            applyForm.setStartTime(startTime);
+                                            applyForm.setEndTime(end);
+                                            applyForm.setSumTime(hours);
+                                            applyForm.setApplyId(memberVo.getMemberUserId());
+                                            applyForm.setContent(workCotent);
+                                            applyForm.setApplyBillName(overTimeVo.getLeaveName());
+                                            applyForm.setTypeName(spName);
+                                            applyForm.setSpNo(spNo);
+                                            applyForm.setType(4);
+                                            applyForms.add(applyForm);
+                                        }
+                                    }
+                                    applyFormService.saveBatch(applyForms);
+                                }
+                            }
+                        }
+                    }
+                }
+                else if (templateType == 5) {
+                    JSONObject info = jsonObject.getJSONObject("info");
+                    String spNo = info.getString("sp_no");
+                    int count = applyFormService.count(new QueryWrapper<ApplyForm>().eq("sp_no", spNo));
+                    if (count>0){
+                        continue;
+                    }
+                    Integer spStatus = info.getInteger("sp_status");
+                    String spName = info.getString("sp_name");
+                    Long applyTime = info.getLongValue("apply_time");
+
+                    JSONObject apply_data = info.getJSONObject("apply_data");
+                    JSONArray contents = apply_data.getJSONArray("contents");
+
+                    ArrayList<String> applyIds = new ArrayList<>();//参与人的工号
+                    StringJoiner joiner = new StringJoiner(",");//提前下班原因
+                    long newDuration=0;
+                    long newBegin=0;
+                    long newEnd=0;
+
+                    for (int i = 0; i < contents.size(); i++) {
+                        JSONObject contentsJSONObject = contents.getJSONObject(i);
+                        JSONArray title = contentsJSONObject.getJSONArray("title");
+                        JSONObject value = contentsJSONObject.getJSONObject("value");
+                        String control = contentsJSONObject.getString("control");
+
+                        if (control.equals("Contact")&&title.getJSONObject(0).getString("text").contains("申请人")){
+                            JSONArray members = value.getJSONArray("members");
+                            for (int i1 = 0; i1 < members.size(); i1++) {
+                                String userid = members.getJSONObject(i1).getString("userid");
+                                applyIds.add(userid);
+                            }
+                        }
+
+                        if (control.equals("Selector")&&title.getJSONObject(0).getString("text").contains("提前下班原因")){
+                            JSONArray jsonArray = value.getJSONObject("selector").getJSONArray("options");
+                            for (int i1 = 0; i1 < jsonArray.size(); i1++) {
+                                JSONArray jsonArray1 = jsonArray.getJSONObject(i1).getJSONArray("value");
+                                for (int i2 = 0; i2 < jsonArray1.size(); i2++) {
+                                    joiner.add(jsonArray1.getJSONObject(i2).getString("text"));
+                                }
+                            }
+                        }
+                        if (control.equals("DateRange")&&title.getJSONObject(0).getString("text").contains("提前下班时长")){
+                            JSONObject jsonObject1 = value.getJSONObject("date_range");
+                             newDuration = jsonObject1.getLongValue("new_duration");
+                             newBegin = jsonObject1.getLongValue("new_begin");
+                             newEnd = jsonObject1.getLongValue("new_end");
+                        }
+                    }
+                    ArrayList<ApplyForm> list = new ArrayList<>();
+                    for (String applyId : applyIds) {
+                        ApplyForm applyForm = new ApplyForm();
+                        applyForm.setType(5);
+                        applyForm.setTypeName(spName);
+                        applyForm.setApplyId(applyId);
+                        applyForm.setSpNo(spNo);
+                        applyForm.setContent(joiner.toString());
+                        LocalDateTime startTime = Instant.ofEpochSecond(newBegin)
+                                .atZone(ZoneId.systemDefault())
+                                .toLocalDateTime();
+
+                        LocalDateTime end = Instant.ofEpochSecond(newEnd)
+                                .atZone(ZoneId.systemDefault())
+                                .toLocalDateTime();
+                        // 1. 计算小时(秒 → 小时)
+                        BigDecimal hours = BigDecimal.valueOf(newDuration)
+                                .divide(BigDecimal.valueOf(3600), 1, RoundingMode.HALF_UP);
+                        applyForm.setStartTime(startTime);
+                        applyForm.setEndTime(end);
+                        applyForm.setSumTime(hours);
+                        list.add(applyForm);
+                    }
+                    applyFormService.saveBatch(list);
+                }
+                else if (templateType == 6) {
+                    JSONObject info = jsonObject.getJSONObject("info");
+                    String spNo = info.getString("sp_no");
+                    int count = applyFormService.count(new QueryWrapper<ApplyForm>().eq("sp_no", spNo));
+                    if (count>0){
+                        continue;
+                    }
+
+                    String spName = info.getString("sp_name");
+                    JSONObject apply_data = info.getJSONObject("apply_data");
+                    JSONArray contents = apply_data.getJSONArray("contents");
+
+                    ArrayList<ApplyForm> list = new ArrayList<>();
+
+                    for (int i = 0; i < contents.size(); i++) {
+                        JSONObject contentsJSONObject = contents.getJSONObject(i);
+                        JSONArray title = contentsJSONObject.getJSONArray("title");
+                        JSONObject value = contentsJSONObject.getJSONObject("value");
+                        String control = contentsJSONObject.getString("control");
+
+
+                        if (control.equals("Table")&&title.getJSONObject(0).getString("text").equals("明细")){
+                            JSONArray children = value.getJSONArray("children");
+                            for (int i1 = 0; i1 < children.size(); i1++) {
+                                JSONArray jsonArray = children.getJSONObject(i1).getJSONArray("list");
+                                ArrayList<ApplyForm> subList = new ArrayList<>();
+                                long longValue=0;
+                                String content="";
+                                for (int i2 = 0; i2 < jsonArray.size(); i2++) {
+                                    JSONObject jsonObject1 = jsonArray.getJSONObject(i2);
+                                    if (jsonObject1.getString("control").equals("Contact")&&jsonObject1.getJSONArray("title").getJSONObject(0).getString("text").equals("缺勤人员")){
+                                        JSONArray jsonArray1 = jsonObject1.getJSONObject("value").getJSONArray("members");
+                                        for (int i3 = 0; i3 < jsonArray1.size(); i3++) {
+                                            ApplyForm applyForm = new ApplyForm();
+                                            applyForm.setApplyId(jsonArray1.getJSONObject(i3).getString("userid"));
+                                            subList.add(applyForm);
+                                        }
+                                    }
+                                    if (jsonObject1.getString("control").equals("Date")&&jsonObject1.getJSONArray("title").getJSONObject(0).getString("text").equals("缺勤日期")){
+                                        JSONObject jsonObject2 = jsonObject1.getJSONObject("value").getJSONObject("date");
+                                        longValue = jsonObject2.getLongValue("s_timestamp");
+                                    }
+                                    if (jsonObject1.getString("control").equals("Text")&&jsonObject1.getJSONArray("title").getJSONObject(0).getString("text").equals("缺勤原因")){
+                                        content = jsonObject1.getJSONObject("value").getString("text");
+                                    }
+                                    for (ApplyForm applyForm : subList) {
+                                        applyForm.setContent(content);
+                                        LocalDateTime startTime = Instant.ofEpochSecond(longValue)
+                                                .atZone(ZoneId.systemDefault())
+                                                .toLocalDateTime();
+                                        applyForm.setStartTime(startTime);
+                                        applyForm.setEndTime(startTime);
+
+                                    }
+
+                                }
+                                list.addAll(subList);
+                            }
+
+                        }
+
+                    }
+                    for (ApplyForm applyForm : list) {
+                        applyForm.setType(6);
+                        applyForm.setTypeName(spName);
+                        applyForm.setSpNo(spNo);
+                    }
+                    applyFormService.saveBatch(list);
+                }
+
+            }
+
+        }
+    }
 }

+ 24 - 0
fhKeeper/formulahousekeeper/management-workshop/src/main/resources/mapper/ApplyFormMapper.xml

@@ -0,0 +1,24 @@
+<?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="com.management.platform.mapper.ApplyFormMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.ApplyForm">
+        <id column="id" property="id" />
+        <result column="type" property="type" />
+        <result column="type_name" property="typeName" />
+        <result column="apply_bill_name" property="applyBillName" />
+        <result column="apply_id" property="applyId" />
+        <result column="sp_no" property="spNo" />
+        <result column="content" property="content" />
+        <result column="start_time" property="startTime" />
+        <result column="end_time" property="endTime" />
+        <result column="sum_time" property="sumTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, type, type_name, apply_bill_name, apply_id, sp_no, content, start_time, end_time, sum_time
+    </sql>
+
+</mapper>

+ 1 - 1
fhKeeper/formulahousekeeper/octopus/src/views/customer/list.vue

@@ -80,7 +80,7 @@
                     <el-button size="mini"  @click="editClick('D', scope.row)">{{scope.row.setMeal ? '设为未签约' : '设为已签约'}}</el-button>
                     <el-button size="mini"  @click="editClick('G', scope.row)">其他设置</el-button>
                     <el-button size="mini"  @click="editClick('H', scope.row)">报表配置</el-button>
-                    <el-button size="mini"  @click="editClick('K', scope.row)" v-if="user.phone=='15895914665'">登录系统</el-button>
+                    <el-button size="mini"  @click="editClick('K', scope.row)">登录系统</el-button>
                     <el-button size="mini"  @click="editClick('I', scope.row)"  v-if="scope.row.canDelete">删除企业</el-button>
                     <el-button size="mini"  @click="editClick('E', scope.row)" v-loading="dingdingSync" v-if="scope.row.dingdingCorpid">同步钉钉人员</el-button>
                 </template>

+ 21 - 7
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -5128,9 +5128,7 @@
                             this.workForm.domains[index].extraField4 = ''
                             this.workForm.domains[index].extraField5 = ''
                         }
-                        if((res.data.orderIds || []).length > 0) {
-                            this.workForm.domains[index].extraField4 = res.data.orderIds[0]
-                        }
+
                         this.workForm.domains[index].reportExtraField4List = res.data.orderIds || []
                         this.workForm.domains[index].reportExtraField5List = res.data.lines || []
                         this.$forceUpdate();
@@ -6514,7 +6512,7 @@
                                     multiWorktime: aiReportData[i].multiWorktime || 0,
                                     worktimeList: [{}],
                                     degreeId: aiReportData[i].degreeId==-1?null:aiReportData[i].degreeId,
-                                    multiDegrIdArray: aiReportData[i].multiDegrId?JSON.parse(aiReportData[i].multiDegrId):null,
+                                    multiDegrIdArray: aiReportData[i].multiDegrIdList,
                                     wuduList: aiReportData[i].degreeList,
                                     taskGroups:aiReportData[i].taskGroups,
                                     customData: aiReportData[i].customData,//自定义的数值
@@ -7082,9 +7080,9 @@
                     if (res.code == "ok") {
                         this.zhoBao.reportExtraField4List = res.data.orderIds || []
                         this.zhoBao.reportExtraField5List = res.data.lines || []
-                        if((res.data.orderIds || []).length > 0) {
-                            this.zhoBao.extraField4 = res.data.orderIds[0]
-                        }
+                        // if((res.data.orderIds || []).length > 0) {
+                        //     this.zhoBao.extraField4 = res.data.orderIds[0]
+                        // }
                         console.log(this.zhoBao, '<===== this.zhoBao')
                         this.$forceUpdate();
                     } 
@@ -7183,6 +7181,14 @@
                         });
                         return
                     }
+
+                    if(taskGroupRow.name.indexOf('出差工时') != '-1' && extraField4) {
+                        this.$message({
+                            message: `出差项目不能关联工单`,
+                            type: "error"
+                        });
+                        return
+                    }
                 }
                 
                 this.tianxieDialogVisible = false
@@ -9000,6 +9006,14 @@
                                     });
                                     return
                                 }
+
+                                if(taskGroupRow.name.indexOf('出差工时') != '-1' && extraField4) {
+                                    this.$message({
+                                        message: `出差项目不能关联工单`,
+                                        type: "error"
+                                    });
+                                    return
+                                }
                             }
                         }
 

+ 32 - 6
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue

@@ -185,7 +185,7 @@
                     <template v-if="item.projectId && doYouWantToDisplayTheWorkOrder">
                         <!-- 工单号 -->
                         <van-field readonly name="stage" :disabled="!item.canEdit"
-                        v-if="user.timeType.reportExtraField4Name"
+                        v-if="user.timeType.reportExtraField4Name && doYouWantToDisplayTheWorkOrderGongdan"
                         clickable :value="item.extraField4" :label="user.timeType.reportExtraField4Name" :placeholder="!item.canEdit ? '' : `请选择`" :right-icon="!item.canEdit ? '' : 'close'"
                         @click-right-icon.stop="clearClickPickExtraField4(index, item)"
                         @focus="clickPickExtraField4(index, item)" />
@@ -763,6 +763,7 @@ export default {
             showAddMore: false,
             businessTripsArray: [],
             doYouWantToDisplayTheWorkOrder: true,
+            doYouWantToDisplayTheWorkOrderGongdan: true,
             hideWorkingHours: false,
 
             reportSettingsRow: {},
@@ -1241,9 +1242,9 @@ export default {
                             this.form.domains[index == null ? this.clickIndex : index].extraField4 = ''
                             this.form.domains[index == null ? this.clickIndex : index].extraField5 = ''
                         }
-                        if((res.data.orderIds || []).length > 0) {
-                            this.form.domains[index == null ? this.clickIndex : index].extraField4 = res.data.orderIds[0]
-                        }
+                        // if((res.data.orderIds || []).length > 0) {
+                        //     this.form.domains[index == null ? this.clickIndex : index].extraField4 = res.data.orderIds[0]
+                        // }
                         this.form.domains[index == null ? this.clickIndex : index].reportExtraField4List = res.data.orderIds || []
                         this.form.domains[index == null ? this.clickIndex : index].reportExtraField5List = res.data.lines || []
                     }
@@ -1747,7 +1748,24 @@ export default {
                                 subProjectName = list[i].subProjectList.filter(s => s.id == list[i].subProjectId)[0].name;
                             }
                             var projectName = list[i].projectName;
-                            arr.push({
+                            var t = this.user.timeType;
+                            let mmm = !t.customDegreeMultiple ? list[i].degreeId : (list[i].multiDegrIdList || [])
+                            let sss = list[i].degreeList || []
+                            let radioPickDegree = ''
+                            let wuduName = ''
+                            if(!t.customDegreeMultiple) {
+                                for (var s in sss) {
+                                    if (sss[s].id == mmm) {
+                                        wuduName = sss[s].name
+                                    }
+                                }
+                                radioPickDegree = sss.filter(s => s.id == mmm)[0]
+                            } else {
+                                let arr = sss.filter(s => mmm.includes(s.id)).map(s => s.name);
+                                radioPickDegree = sss.filter(s => mmm.includes(s.id))
+                                wuduName = arr.join(',')
+                            }
+                            let copyReport = {
                                 projectId: list[i].projectId,
                                 projectName: projectName,
                                 workingTime: String(list[i].workingTime),
@@ -1767,6 +1785,7 @@ export default {
                                 multiWorktime: list[i].multiWorktime,
                                 worktimeList: list[i].worktimeList,
                                 wuduList: list[i].degreeList,
+                                weiduName: wuduName,
                                 degreeId: list[i].degreeId==-1?null:list[i].degreeId,
                                 subProjectId: list[i].subProjectId,
                                 subProjectName: subProjectName,
@@ -1802,7 +1821,8 @@ export default {
                                 userReportDeptName: list[i].userReportDeptName,
                                 reportTargetDeptId: list[i].deptId,
                                 content: list[i].content
-                            })
+                            }
+                            arr.push(copyReport)
                         }
                         this.form.domains = arr;
                     } else {
@@ -2368,6 +2388,12 @@ export default {
                 } else {
                     this.doYouWantToDisplayTheWorkOrder = true
                 }
+
+                if(value.name.indexOf('出差工时') != -1) {
+                   this.doYouWantToDisplayTheWorkOrderGongdan = false 
+                } else {
+                    this.doYouWantToDisplayTheWorkOrderGongdan = true
+                }
             }
             
 

+ 9 - 2
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/weekEdit.vue

@@ -104,7 +104,7 @@
                         <template v-if="item.projectId && doYouWantToDisplayTheWorkOrder">
                             <!-- 工单号 -->
                             <van-field readonly name="stage" :disabled="item.state<=1"
-                            v-if="user.timeType.reportExtraField4Name"
+                            v-if="user.timeType.reportExtraField4Name && doYouWantToDisplayTheWorkOrderGongdan"
                             clickable :value="item.extraField4" :label="user.timeType.reportExtraField4Name" placeholder="请选择"
                             @click="clickPickExtraField4(index, item)" />
                             <van-popup v-model="item.showPickerExtraField4" position="bottom" :close-on-click-overlay="false">
@@ -614,7 +614,8 @@
                 temporaryStorage: false, // 是否开启暂存
 
                 wuqiId: '1071',
-                doYouWantToDisplayTheWorkOrder: true
+                doYouWantToDisplayTheWorkOrder: true,
+                doYouWantToDisplayTheWorkOrderGongdan: true,
             };
         },
         methods: {
@@ -1825,6 +1826,12 @@
                     } else {
                         this.doYouWantToDisplayTheWorkOrder = true
                     }
+
+                    if(value.name.indexOf('出差工时') != -1) {
+                        this.doYouWantToDisplayTheWorkOrderGongdan = false 
+                    } else {
+                        this.doYouWantToDisplayTheWorkOrderGongdan = true
+                    }
                 }
 
                 this.getGroupStages(this.currentForm.domains[this.clickIndex], index, flag);