Prechádzať zdrojové kódy

Merge branch 'master' of http://47.100.37.243:10080/wutt/manHourHousekeeper into master

seyason 2 rokov pred
rodič
commit
b99eec052f

+ 9 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/TimeType.java

@@ -17,7 +17,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2022-10-17
+ * @since 2022-12-06
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -390,11 +390,18 @@ public class TimeType extends Model<TimeType> {
     private Integer notAllowedNoAttendance;
 
     /**
-     * 是否需要微信请假
+     * 1为需要同步企业微信请假,0为不需要同步企业微信请假
      */
     @TableField("wx_leave")
     private Integer wxLeave;
 
+    /**
+     * 是否开通【推送工时数据】 0-否 1-是
+     */
+    @TableField("push_report_data")
+    private Integer pushReportData;
+
+
     @Override
     protected Serializable pkVal() {
         return this.companyId;

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

@@ -3830,7 +3830,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 titles.add(MessageUtils.message("excel.attDuration"));
             }
             //titles.add("审核流程状态");
-            titles.add(MessageUtils.message("excel.auditProcess"));
+            titles.add(MessageUtils.message("excel.reviewProcessStatus"));
             //创建表头
             HSSFRow headRow = sheet.createRow(0);
             //设置列宽 setColumnWidth的第二个参数要乘以256 这个参数的单位是1/256个字符宽度

+ 101 - 19
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java

@@ -29,6 +29,7 @@ import org.springframework.util.StringUtils;
 import org.springframework.web.client.RestTemplate;
 
 import javax.annotation.Resource;
+import java.math.BigDecimal;
 import java.security.SecureRandom;
 import java.sql.Timestamp;
 import java.text.DecimalFormat;
@@ -55,10 +56,12 @@ public class TimingTask {
     //是否是开发环境
     @Value("${configEnv.isDev}")
     boolean isDev;
+    @Value("${privateDeployURL.pcUrl}")
+    private String pcUrl;
     //是否是私有化部署
     @Value("${configEnv.isPrivateDeploy}")
     boolean isPrivateDeploy;
-
+    private final static Executor executor = Executors.newFixedThreadPool(3);//启用多线程
 
     @Value("${wx.template_report_fill}")
     public String TEMPLATE_REPORT_FILL;
@@ -68,6 +71,8 @@ public class TimingTask {
     public String appId;
     @Value("${wx.app_secret}")
     public String appSecret;
+    @Value("${corpId}")
+    public String corpId;
     @Autowired
     private RedisUtil redisUtil;
     @Autowired
@@ -85,6 +90,8 @@ public class TimingTask {
     @Resource
     private ReportMapper reportMapper;
     @Resource
+    private TimeAutoExcludeMapper timeAutoExcludeMapper;
+    @Resource
     private WxCorpInfoService wxCorpInfoService;
     @Resource
     private WxCorpInfoMapper wxCorpInfoMapper;
@@ -195,19 +202,66 @@ public class TimingTask {
     }
 
     //每个月五号推送日报信息
-    @Scheduled(cron = "0 0 2 2 * ?")
+    @Scheduled(cron = "0 0 1 5 * ?")
     private void pushReportListByToken(){
         if(isDev) return;
         HttpRespMsg msg=new HttpRespMsg();
         LocalDate now=LocalDate.now().minusMonths(1);
+        DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
         now.with(TemporalAdjusters.lastDayOfMonth());
         LocalDate start=now.with(TemporalAdjusters.firstDayOfMonth());
         LocalDate end=now.with(TemporalAdjusters.lastDayOfMonth());
+        List<TimeType> timeTypeList = timeTypeMapper.selectList(new QueryWrapper<TimeType>().eq("push_report_data", 1));
+        for (TimeType timeType : timeTypeList) {
+            List<ReportLog> reportLogList = reportLogMapper.selectList(new QueryWrapper<ReportLog>().eq("company_id", timeType.getCompanyId()).ge("operate_date",start.atTime(LocalTime.now())).orderByAsc("operate_date"));
+            List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", timeType.getCompanyId()));
+                List<HashMap<String, Object>> allReportByDate = reportMapper.getAllReportByDate(start.format(df),timeType.getCompanyId(), null, end.format(df), null, 1, null);
+                final CountDownLatch latch=new CountDownLatch(allReportByDate.size());
+                for (HashMap<String, Object> map : allReportByDate) {
+                    java.sql.Date sqlCreateDate= (java.sql.Date) map.get("createDate");
+                    java.sql.Timestamp sqlProjectAuditTime= (Timestamp) map.get("projectAuditTime");
+                    java.sql.Timestamp sqlTime= (Timestamp) map.get("time");
+                    if(sqlCreateDate!=null){
+                        LocalDate createDate = sqlCreateDate.toLocalDate();
+                        map.put("createDate",df.format(createDate));
+                    }
+                    if(sqlProjectAuditTime!=null){
+                        LocalDateTime projectAuditTime = sqlProjectAuditTime.toLocalDateTime();
+                        map.put("projectAuditTime",projectAuditTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+                    }
+                    if(sqlTime!=null){
+                        LocalDateTime time = sqlTime.toLocalDateTime();
+                        map.put("time",time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+                    }
+                    executor.execute(new Runnable(){
+                        @Override
+                        public void run() {
+                            List<ReportLog> item=new ArrayList<>();
+                            Integer reportId = (Integer) map.get("id");
+                            for (ReportLog reportLog : reportLogList) {
+                                List<String> list = Arrays.asList(reportLog.getReportIds().split(","));
+                                reportLog.setCreatorName(!userList.stream().filter(
+                                        ul->ul.getId().equals(reportLog.getCreatorId())).findFirst().isPresent()?"":userList.stream().filter(
+                                        ul->ul.getId().equals(reportLog.getCreatorId())).findFirst().get().getName());
+                                reportLog.setOperateName(!userList.stream().filter(
+                                        ul->ul.getId().equals(reportLog.getOperatorId())).findFirst().isPresent()?"":userList.stream().filter(
+                                        ul->ul.getId().equals(reportLog.getOperatorId())).findFirst().get().getName());
+                                if(list.contains(String.valueOf(reportId))&&!reportLog.getMsg().contains("提交")){
+                                    item.add(reportLog);
+                                }
+                            }
+                            map.put("checkLog",item);
+                            latch.countDown();
+                        }
+                    });
+                }
+                msg.data=allReportByDate;
+        }
     }
 
 
     //每天2:11 同步钉钉用户前2天到未来30天时间段的打卡,请假,出差数据
-    @Scheduled(cron = "0 48 17 ? * *")
+    @Scheduled(cron = "0 53 15 ? * *")
     private void synFanWeiWorkData() {
         /*if (isDev) return;*/
         List<TimeType> timeTypeList = timeTypeMapper.selectList(new QueryWrapper<TimeType>().eq("sync_fanwei", 1));
@@ -235,24 +289,50 @@ public class TimingTask {
         //Todo: 获取打卡数据
         HttpRespMsg workDataMsg = dockWithMLD.getResult("http://10.1.10.51:20175/api/cube/restful/interface/getModeDataPageList/getWorkData", jsonString);
         List<Map<String,Object>> workDataList= (List<Map<String, Object>>) workDataMsg.data;
-        for (Map<String, Object> map : workDataList) {
-            UserFvTime userFvTime=new UserFvTime();
-            User user = userMapper.selectOne(new QueryWrapper<User>().eq("job_number", map.get("userId")));
-            if(user==null){
-                continue;
+        List<String> userIds = workDataList.stream().map(map -> String.valueOf(map.get("userId"))).collect(Collectors.toList());
+        List<User> userList = userMapper.selectList(new QueryWrapper<User>().in("job_number", userIds));
+        for (User user : userList) {
+            System.out.println("需要同步的用户列表-----"+userList);
+            LocalTime startTime=null;
+            LocalTime endTime=null;
+            LocalDate workDate=null;
+            for (Map<String, Object> map : workDataList) {
+                if (map.get("userId").equals(user.getJobNumber())) {
+                    if(String.valueOf(map.get("signtype")).equals("签到")){
+                        startTime=LocalTime.parse(String.valueOf(map.get("signtime")), dtf2);
+                        workDate= LocalDate.parse(String.valueOf(map.get("workDate")), dtf);
+                    }
+                    if(String.valueOf(map.get("signtype")).equals("签退")){
+                        endTime=LocalTime.parse(String.valueOf(map.get("signtime")), dtf2);
+                        workDate=LocalDate.parse(String.valueOf(map.get("workDate")),dtf);
+                    }
+                }
             }
+            UserFvTime userFvTime=new UserFvTime();
+            //获取休息设置
+            TimeAutoExclude timeAutoExclude = timeAutoExcludeMapper.selectOne(new QueryWrapper<TimeAutoExclude>().eq("company_id", user.getCompanyId()));
+            System.out.println("泛微同步人员打卡数据----"+user.getName());
             if(compIds.contains(user.getCompanyId())){
-                userFvTime.setWorkDate(LocalDate.parse(String.valueOf(map.get("workDate")),dtf));
-                LocalTime startTime = LocalTime.parse(String.valueOf(map.get("startTime")), dtf2);
-                LocalTime endTime = LocalTime.parse(String.valueOf(map.get("endTime")), dtf2);
-                LocalDateTime time1= LocalDate.now().atTime(startTime);
-                LocalDateTime time2 = LocalDate.now().atTime(endTime);
-                Duration between = Duration.between(time1, time2);
-                userFvTime.setStartTime((String) map.get("startTime"));
-                userFvTime.setEndTime((String) map.get("endTime"));
+                if(startTime==null||endTime==null){
+                    System.out.println("缺少上班或者下班打卡时间----"+user.getName());
+                    continue;
+                }
+                userFvTime.setWorkDate(workDate);
+                Duration between = Duration.between(startTime, endTime);
+                userFvTime.setStartTime(startTime.format(dtf2));
+                userFvTime.setEndTime(endTime.format(dtf2));
                 userFvTime.setCompanyId(user.getCompanyId());
                 userFvTime.setUserId(user.getId());
-                userFvTime.setWorkHours((float)between.toHours());
+                long workHours = between.toHours();
+                long restHours;
+                if(startTime.isBefore(LocalTime.parse(timeAutoExclude.getStartTime(),dtf2))
+                        &&endTime.isAfter(LocalTime.parse(timeAutoExclude.getEndTime(),dtf2))){
+                    Duration bt = Duration.between(LocalTime.parse(timeAutoExclude.getStartTime(),dtf2), LocalTime.parse(timeAutoExclude.getEndTime(),dtf2));
+                    restHours=bt.toHours();
+                }else {
+                    restHours=0;
+                }
+                userFvTime.setWorkHours(BigDecimal.valueOf(workHours).subtract(BigDecimal.valueOf(restHours)).floatValue());
                 Optional<UserFvTime> first = oldUserFvTimeList.stream().filter(ol -> ol.getWorkDate().isEqual(userFvTime.getWorkDate()) && ol.getUserId().equals(userFvTime.getUserId())).findFirst();
                 if(first.isPresent()){
                     userFvTime.setId(first.get().getId());
@@ -271,6 +351,7 @@ public class TimingTask {
             if(user==null){
                 continue;
             }
+            System.out.println("泛微同步人员请假数据----"+user.getName());
             if(compIds.contains(user.getCompanyId())){
                LeaveSheet leaveSheet=new LeaveSheet();
                leaveSheet.setCompanyId(user.getCompanyId());
@@ -278,7 +359,7 @@ public class TimingTask {
                leaveSheet.setOwnerId(user.getId());
                leaveSheet.setOwnerName(user.getName());
                leaveSheet.setStartDate(LocalDate.parse(String.valueOf(map.get("startDate")),dtf1));
-               leaveSheet.setEndDate(LocalDate.parse(String.valueOf(map.get("endtDate")),dtf1));
+               leaveSheet.setEndDate(LocalDate.parse(String.valueOf(map.get("endDate")),dtf1));
                Integer timeType=null;
                switch (String.valueOf(map.get("timeType"))){
                    case "小时":timeType=1;
@@ -336,6 +417,7 @@ public class TimingTask {
             if(user==null){
                 continue;
             }
+            System.out.println("泛微同步人员出差数据----"+user.getName());
             if(compIds.contains(user.getCompanyId())){
                 BusinessTrip businessTrip=new BusinessTrip();
                 businessTrip.setCompanyId(user.getCompanyId());
@@ -702,7 +784,7 @@ public class TimingTask {
                         jsonObj.put("value", StringUtils.isEmpty(t.getAlertMsg())?"":t.getAlertMsg());
                         dataJson.add(jsonObj);
                         if(isPrivateDeploy){
-                            json.put("content",StringUtils.isEmpty(t.getAlertMsg())?"":t.getAlertMsg()+"\\n<a href=\\\"https://open.weixin.qq.com/connect/oauth2/authorize?appid=ww4e237fd6abb635af&redirect_uri=http://worktime.ttkuaiban.com/api/corpWXAuth&response_type=code&scope=snsapi_base&state=0#wechat_redirect\\\">去填写</a>");
+                            json.put("content",StringUtils.isEmpty(t.getAlertMsg())?"":t.getAlertMsg()+"\\n<a href=\\\"https://open.weixin.qq.com/connect/oauth2/authorize?appid="+corpId+"&redirect_uri=http://"+pcUrl+"/api/corpInsideWXAuth&response_type=code&scope=snsapi_base&state=0#wechat_redirect\\\">去填写</a>");
                         }else {
                             json.put("template_id","tty9TkCAAAYoevY-40ciWD5lDncDfR5w");
                             json.put("url", "https://open.weixin.qq.com/connect/oauth2/authorize?appid=ww4e237fd6abb635af&redirect_uri=http://worktime.ttkuaiban.com/api/corpWXAuth&response_type=code&scope=snsapi_base&state=0#wechat_redirect");

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 3 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TimeTypeMapper.xml


+ 1 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/project/finance.vue

@@ -484,7 +484,7 @@
                 <el-button type="primary" @click="saveProjectSetting()" >{{ $t('btn.determine') }}</el-button>
             </div>
         </el-dialog>
-        <el-dialog title="$t('allocationdata')" v-if="intoAmortizationDialog" :visible.sync="intoAmortizationDialog" customClass="customWidth" width="500px">
+        <el-dialog :title="$t('allocationdata')" v-if="intoAmortizationDialog" :visible.sync="intoAmortizationDialog" customClass="customWidth" width="500px">
             <p>{{'1.' + $t('other.download')}}
             <el-link type="primary" style="margin-left:5px;" :underline="false" :href="'./upload/'+$t('allocationImporttemplates')+'.xlsx'" :download="$t('allocationImporttemplates') + '.xlsx'">{{$t('allocationImporttemplates')+'.xlsx'}}</el-link>
             </p>

+ 18 - 4
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/list.vue

@@ -64,10 +64,13 @@
             </el-form>
         </el-col>
         <!--列表-->
-        <el-table :data="list" ref="multipleTable" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;"
-            @selection-change="handleSelectionChange">
+        <el-table :data="list" ref="multipleTable" v-if="showTable" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;"
+            @selection-change="handleSelectionChange" :default-expand-all="defaultExpandAllFlg">
             <el-table-column type="selection" width="55"></el-table-column>
-            <el-table-column type="expand">
+            <el-table-column type="expand" :label="''">
+                <template slot="header">
+                    <i :class="defaultExpandAllFlg ? 'el-icon-arrow-down' : 'el-icon-arrow-right'" style="cursor: pointer;" @click="defaultExpandAllFlgCli()"></i>
+                </template>
                 <template slot-scope="props">
                     <el-timeline>
                         <el-timeline-item v-for="(item,index) in props.row.data" :key="index">
@@ -468,7 +471,9 @@
 
                 approveinData: null,
                 approveinDialog: false,
-                isbatch: false
+                isbatch: false,
+                defaultExpandAllFlg: false,
+                showTable: true
             };
         },
         filters: {
@@ -949,6 +954,15 @@
                 this.search.userIdArray = arr
                 console.log(this.search.userIdArray, '数据看看')
                 this.usersSearch(false)
+            },
+            defaultExpandAllFlgCli() {
+                this.defaultExpandAllFlg = !this.defaultExpandAllFlg
+                this.list = JSON.parse(JSON.stringify(this.list))
+                this.$nextTick(()=>{this.$refs.multipleTable.doLayout()})
+                this.showTable = false
+                this.$nextTick(() => {
+                    this.showTable = true
+                })
             }
         },
         created() {