소스 검색

Merge branch 'master' of http://47.100.37.243:10191/wutt/manHourHousekeeper

zhouyy 5 달 전
부모
커밋
e078966557
25개의 변경된 파일278개의 추가작업 그리고 165개의 파일을 삭제
  1. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/login_logo.png
  2. 38 12
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/login.vue
  3. 8 2
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/my/index.vue
  4. 5 1
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/visitorProgram/visitorDetails.vue
  5. 4 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/components/TaskModal/index.vue
  6. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/index.vue
  7. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/index.vue
  8. 14 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/corpreport/index.vue
  9. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/index.vue
  10. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/index.vue
  11. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/index.vue
  12. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/index.vue
  13. 36 11
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ExcelExportServiceImpl.java
  14. 5 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/AuthRedirectController.java
  15. 44 10
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  16. 2 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserController.java
  17. 9 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WeiXinCorpController.java
  18. 2 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ReportService.java
  19. 10 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ExcelExportServiceImpl.java
  20. 2 6
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  21. 6 13
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  22. 8 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java
  23. 11 7
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/ExcelUtil.java
  24. 63 36
      fhKeeper/formulahousekeeper/timesheet/src/views/team/index.vue
  25. 5 52
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/login_logo.png


+ 38 - 12
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/login.vue

@@ -1,16 +1,26 @@
 <template>
   <div class="loginPage w-full h-full bg-white">
-    <van-form show-error :show-error-message="false" @submit="onSubmit">
-      <van-cell-group inset>
-        <van-field v-model="username" name="username" label="用户名" placeholder="用户名" :rules="rules" />
-        <van-field v-model="password" type="password" name="password" label="密码" placeholder="密码" :rules="rules" />
-      </van-cell-group>
-      <div style="margin: 16px">
-        <van-button round block type="primary" native-type="submit">
-          提交
-        </van-button>
+    <template v-if="!isCorpWX">
+      <div class="flex justify-center">
+        <div class="logo-image">
+          <img src="/src/assets/image/login_logo.png" class="w-full h-full" />
+        </div>
       </div>
-    </van-form>
+      <van-form show-error :show-error-message="false" @submit="onSubmit">
+        <van-cell-group inset>
+          <van-field v-model="username" name="username" label="用户名" placeholder="用户名" :rules="rules" />
+          <van-field v-model="password" type="password" name="password" label="密码" placeholder="密码" :rules="rules" />
+        </van-cell-group>
+        <div class="login-btn">
+          <van-button round block type="primary" native-type="submit">
+            提交
+          </van-button>
+        </div>
+      </van-form>
+    </template>
+    <template v-else>
+      <div class="flex justify-center getInto">正在进入系统中...</div>
+    </template>
   </div>
 </template>
 
@@ -89,7 +99,7 @@ function onSubmit(fromVal) {
 function loginByUserId(userId) {
   toastLoading('登陆中...', 0)
   // requests.post(USER_ID_LOGIN, { params: { userId } }).then(({ data }) => {
-  requests.post(USER_ID_LOGIN, {  userId }).then(({ data }) => {
+  requests.post(USER_ID_LOGIN, { userId }).then(({ data }) => {
     loginProcessing(data)
   })
 }
@@ -170,4 +180,20 @@ function separateRouting(list = []) {
 
 </script>
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+.logo-image {
+  width: 150px;
+  height: 150px;
+  margin: 100px 0 50px 0;
+}
+
+.getInto {
+  padding-top: 100px;
+  font-size: 24px;
+  color: #999;
+}
+
+.login-btn {
+  margin: 24px 16px 16px 16px;
+}
+</style>

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

@@ -15,7 +15,7 @@
           </div>
         </div>
         
-        <div class="w-full mb-40 px-24">
+        <div class="w-full mb-40 px-24" v-if="!isCorpWX">
           <van-button type="primary" @click="signOut" class="w-full">退出登录</van-button>
         </div>
       </div>
@@ -37,6 +37,7 @@ import Footer from "@components/page/footer.vue";
 
 const router = useRouterStore()
 const userInfo = useInfoStore()
+const isCorpWX = ref(false)
 function signOut() {
   router.redirectTo({
     pathName: 'login',
@@ -48,9 +49,14 @@ function signOut() {
   })
 }
 
+function judgingTheEnvironment() {
+  const currentEnvironment = navigator.userAgent.toLowerCase();
+  isCorpWX.value = currentEnvironment.indexOf("wxwork") > 0 ? true : false
+}
+
 useLifecycle({
   load: () => {
-
+    judgingTheEnvironment()
   }
 });
 </script>

+ 5 - 1
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/visitorProgram/visitorDetails.vue

@@ -26,7 +26,11 @@
       <van-cell-group>
         <van-cell title="计划名称" :value="detailedData.planName" />
         <van-cell title="客户姓名" :value="detailedData.customName" />
-        <van-cell title="负责人" :value="detailedData.inchargerName" />
+        <van-cell title="负责人">
+          <template #title>
+            <TranslationComponent :openId="detailedData.inchargerName" />
+          </template>
+        </van-cell>
         <van-cell title="拜访目的" :value="detailedData.visitGoalName" />
         <van-cell title="拜访时间" :value="detailedData.visitTime" />
         <van-cell title="提醒" :value="detailedData.remindTypeName" />

+ 4 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/components/TaskModal/index.vue

@@ -118,7 +118,10 @@
         <el-form-item label="操作记录" label-width="7em">
           <div class="w-full">
             <div v-for="item in form.taskLogs" class=" border-b-2 w-full pl-3">
-              {{ `${dayjs(item.modTime).format('YYYY-MM-DD HH:mm:ss')} ${item.userName} ${item.content}` }}
+              <!-- {{ `${dayjs(item.modTime).format('YYYY-MM-DD HH:mm:ss')} ${item.userName} ${item.content}` }} -->
+              {{ dayjs(item.modTime).format('YYYY-MM-DD HH:mm:ss') }}
+              <TextTranslation translationTypes="userName" :translationValue="item.userName" />
+              {{ item.content }}
             </div>
           </div>
         </el-form-item>

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/index.vue

@@ -85,7 +85,7 @@
                   <div class="table-text-textnowrap" v-if="item.eventName"
                     @click="dealWithTableColumn(scope.row, item.eventName)">{{ scope.row[item.prop] }}</div>
                   <template v-else-if="['inchargerName', 'creatorName'].includes(item.prop)">
-                    <TextTranslation translationTypes="userName" :translationValue="scope.row[item.prop]">
+                    <TextTranslation translationTypes="userName" :translationValue="scope.row[item.prop]" v-if="scope.row[item.prop]">
                     </TextTranslation>
                   </template>
                   <template v-else>{{ scope.row[item.prop] }}</template>

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/index.vue

@@ -46,7 +46,7 @@
                   }}</el-button>
                 </template>
                 <template v-if="['creatorName', 'ownerName'].includes(column.prop)">
-                  <TextTranslation translationTypes="userName" :translationValue="scope.row[column.prop]"></TextTranslation>
+                  <TextTranslation translationTypes="userName" :translationValue="scope.row[column.prop]" v-if="scope.row[column.prop]"></TextTranslation>
                 </template>
                 <template v-if="column.event === 'getSex'">
                   {{ getSex(scope.row.sex) }}

+ 14 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/corpreport/index.vue

@@ -151,10 +151,23 @@ const queryConversion = async (payload?: RequestProps) => {
 
   // @ts-ignore
   chartOptions.series = [{ type: 'bar', barWidth: 20 }];
+
+  if(userInfo && userInfo.value.userNameNeedTranslate == 1) {
+    dealWithTranslation(sourceDataTypes, sourceData).then((res: any) => {
+      // @ts-ignore
+      chartOptions.dataset.dimensions = ['name', '客户转化率(%)'];
+      // @ts-ignore
+      chartOptions.dataset.source = res
+      chartOptions.legend = undefined;
+    })
+
+    return
+  }
+
   // @ts-ignore
   chartOptions.dataset.dimensions = ['name', '客户转化率(%)'];
   // @ts-ignore
-  chartOptions.dataset.source = userInfo.userNameNeedTranslate == 1 ? dealWithTranslation(sourceDataTypes, sourceData) : sourceData
+  chartOptions.dataset.source = sourceData
   // chartOptions.dataset.source = data.map((d) => ({
   //   name: form.type === 1 ? d.name : d.departmentName,
   //   ['客户转化率(%)']: d.dealRate * 100

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/index.vue

@@ -82,7 +82,7 @@
             <el-table-column prop="customerLevelValue" label="客户级别" width="180" sortable="custom"></el-table-column>
             <el-table-column prop="inchargerName" label="负责人" width="190">
               <template #default="scope">
-                <TextTranslation translationTypes="userName" :translationValue="scope.row.inchargerName"></TextTranslation>
+                <TextTranslation translationTypes="userName" :translationValue="scope.row.inchargerName" v-if="scope.row.inchargerName"></TextTranslation>
               </template>
             </el-table-column>
             <el-table-column prop="creatorName" label="创建人" width="180">

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/index.vue

@@ -60,7 +60,7 @@
                   <div class="table-text-textnowrap" @click.prevent="toDetali(scope.row)">{{ scope.row[column.prop] }}</div>
                 </template>
                 <template v-if="['customSignerName', 'companySignerName', 'inchargerName', 'creatorName'].includes(column.prop)">
-                  <TextTranslation translationTypes="userName" :translationValue="scope.row[column.prop]"></TextTranslation>
+                  <TextTranslation translationTypes="userName" :translationValue="scope.row[column.prop]" v-if="scope.row[column.prop]"></TextTranslation>
                 </template>
                 <template v-if="column.prop === 'receivedStatus'">
                   <div>{{ selectData.RemittanceStatus[scope.row.receivedStatus].name }}</div>

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/index.vue

@@ -75,7 +75,7 @@
             </el-table-column>
             <el-table-column prop="inchargerName" label="负责人" width="190">
               <template #default="scope">
-                <TextTranslation translationTypes="userName" :translationValue="scope.row.inchargerName"></TextTranslation>
+                <TextTranslation translationTypes="userName" :translationValue="scope.row.inchargerName" v-if="scope.row.inchargerName"></TextTranslation>
               </template>
             </el-table-column>
             <el-table-column prop="creatorName" label="创建人" width="180">

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/index.vue

@@ -76,7 +76,7 @@
             <el-table-column prop="customerLevelValue" label="客户级别" width="180" sortable="custom"></el-table-column>
             <el-table-column prop="inchargerName" label="负责人" width="190">
               <template #default="scope">
-                <TextTranslation translationTypes="userName" :translationValue="scope.row.inchargerName"></TextTranslation>
+                <TextTranslation translationTypes="userName" :translationValue="scope.row.inchargerName" v-if="scope.row.inchargerName"</TextTranslation>
               </template>
             </el-table-column>
             <el-table-column prop="createName" label="创建人" width="180">

+ 36 - 11
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ExcelExportServiceImpl.java

@@ -1,5 +1,7 @@
 package com.management.platform.service.impl;
 
+import com.management.platform.controller.TaskController;
+import com.management.platform.controller.UserController;
 import com.management.platform.entity.CorpwxJobResult;
 import com.management.platform.entity.WxCorpInfo;
 import com.management.platform.mapper.CorpwxJobResultMapper;
@@ -10,6 +12,9 @@ import com.management.platform.service.WxCorpInfoService;
 import com.management.platform.util.ExcelUtil;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.MessageUtils;
+import com.management.platform.util.RedisUtil;
+import org.json.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.core.io.FileSystemResource;
 import org.springframework.stereotype.Service;
@@ -41,6 +46,8 @@ public class ExcelExportServiceImpl implements ExcelExportService {
     private CorpwxJobResultMapper corpwxJobResultMapper;
     @Value("${upload.path}")
     private String path;
+    @Autowired
+    private RedisUtil redisUtil;
 
     @Transactional(isolation = Isolation.READ_COMMITTED)
     public void testRead(String jobId) {
@@ -126,18 +133,36 @@ public class ExcelExportServiceImpl implements ExcelExportService {
                     Thread.sleep(3000);
                 }
                 System.out.println("i=="+i+", "+LocalDateTime.now());
-                CorpwxJobResult corpwxJobResult = corpwxJobCenter.get(jobId);
-                if (corpwxJobResult != null) {
-                    if (corpwxJobResult.getErrCode() == 0) {
-                        syncTranslationResult = wxCorpInfoService.getSyncTranslationResult(jobId);
-                        corpwxJobCenter.remove(jobId);
-                    } else {
-                        long t2 = System.currentTimeMillis();
-                        System.out.println("222企业微信转译报错:"+corpwxJobResult.getErrMsg()+",耗时:" + (t2 - t) + "ms");
-                        httpRespMsg.setError(corpwxJobResult.getErrMsg());
-                        return httpRespMsg;
+                //直接循环调用接口,后面需要改成通过redis获取jobId对应的消息,再去调用接口
+                Object map = redisUtil.getString("corpwxJobCenter"+jobId);
+                if (map != null) {
+                    JSONObject jsonObject = new JSONObject(map.toString());
+                    System.out.println("通过redis获取到企业微信上传回调的数据=="+jsonObject);
+                    String infoType = jsonObject.getString("InfoType");
+                    if ("batch_job_result".equals(infoType)) {
+                        org.json.JSONObject batchJob = jsonObject.getJSONObject("BatchJob");
+                        String jobType = batchJob.getString("JobType");
+                        String authCorpId = jsonObject.getString("AuthCorpId");
+                        CorpwxJobResult corpwxJobResult = new CorpwxJobResult();
+                        corpwxJobResult.setAuthCorpId(authCorpId);
+                        corpwxJobResult.setErrCode(batchJob.getInt("ErrCode"));
+                        corpwxJobResult.setErrMsg(batchJob.getString("ErrMsg"));
+                        corpwxJobResult.setJobId(jobId);
+                        corpwxJobResult.setJobType(jobType);
+                        corpwxJobResultMapper.insert(corpwxJobResult);
+                        if (corpwxJobResult != null) {
+                            if (corpwxJobResult.getErrCode() == 0) {
+                                syncTranslationResult = wxCorpInfoService.getSyncTranslationResult(jobId);
+                                corpwxJobCenter.remove(jobId);
+                            } else {
+                                long t2 = System.currentTimeMillis();
+                                System.out.println("222企业微信转译报错:"+corpwxJobResult.getErrMsg()+",耗时:" + (t2 - t) + "ms");
+                                httpRespMsg.setError(corpwxJobResult.getErrMsg());
+                                return httpRespMsg;
+                            }
+                            break;
+                        }
                     }
-                    break;
                 }
                 i++;
             }

+ 5 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/AuthRedirectController.java

@@ -148,6 +148,11 @@ public class AuthRedirectController {
         } else {
             redirecUrl = "https://worktime.ttkuaiban.com/#/" + router;
         }
+        //定制化风格
+        if (corpId.equals("wpy9TkCAAAvjmvQuz0IH9iosxBXrqcdA")) {
+            //中辰华典
+            reqParam.put("style", "new");
+        }
         ModelAndView modelAndView = new ModelAndView(
                 new RedirectView(redirecUrl), reqParam);
 

+ 44 - 10
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java

@@ -476,16 +476,23 @@ public class ReportController {
                 customData[i] = 0.0;
             }
         }
-        if (projectAuditorId == null) {
+        System.out.println("projectAuditorId:"+(projectAuditorId == null?"为Null":"Length="+projectAuditorId.length));
+        if (projectAuditorId == null || projectAuditorId.length == 0) {
             projectAuditorId = new String[projectId.length];
             for(int i=0;i<projectAuditorId.length; i++) {
                 projectAuditorId[i] = null;
             }
-        } else if (projectAuditorId.length < projectId.length) {
-            //数组大小不对,后端无法确定项目和审核人的对应关系,必须前端全部传递过来
-            HttpRespMsg msg = new HttpRespMsg();
-            msg.setError("请检查每个项目的审核人是否设置");
-            return msg;
+        }
+        else if (projectAuditorId.length < projectId.length) {
+            if (comTimeType.getReportAuditType() <= 1) {
+                //数组大小不对,后端无法确定项目和审核人的对应关系,必须前端全部传递过来
+                HttpRespMsg msg = new HttpRespMsg();
+                msg.setError("请检查每个项目的审核人是否设置");
+                return msg;
+            } else {
+                //自动扩充数组大小
+                projectAuditorId = Arrays.copyOf(projectAuditorId, projectId.length);
+            }
         }
 
         if (overtimeHours == null) {
@@ -2396,13 +2403,13 @@ public class ReportController {
     }
 
     @RequestMapping("/getNoReportUserList")
-    public HttpRespMsg getNoReportUserList(HttpServletRequest request, String startDate, String endDate,Integer noReportDeptId) {
-        return reportService.getNoReportUserList(request, startDate, endDate,noReportDeptId);
+    public HttpRespMsg getNoReportUserList(HttpServletRequest request, String startDate, String endDate,Integer noReportDeptId, @RequestParam(required = false, defaultValue = "0") Integer onlyHaveAttendance) {
+        return reportService.getNoReportUserList(request, startDate, endDate,noReportDeptId, onlyHaveAttendance);
     }
 
     @RequestMapping("/exportNoReportUserList")
-    public HttpRespMsg exportNoReportUserList(HttpServletRequest request, String startDate, String endDate,Integer noReportDeptId) {
-        return reportService.exportNoReportUserList(request, startDate, endDate,noReportDeptId);
+    public HttpRespMsg exportNoReportUserList(HttpServletRequest request, String startDate, String endDate,Integer noReportDeptId, @RequestParam(required = false, defaultValue = "0") Integer onlyHaveAttendance) {
+        return reportService.exportNoReportUserList(request, startDate, endDate,noReportDeptId, onlyHaveAttendance);
     }
 
     @RequestMapping("/exportUserDailyWorkTime")
@@ -2958,6 +2965,33 @@ public class ReportController {
         return msg;
     }
 
+    @RequestMapping("/transferReportAuditor")
+    public HttpRespMsg transferReportAuditor(String userId, String targetAuditorId){
+        HttpRespMsg msg=new HttpRespMsg();
+        Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
+        LambdaQueryWrapper<Report> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(Report::getState,0);
+        queryWrapper.eq(Report::getCompanyId,companyId);
+        queryWrapper.and(wrapper->wrapper.and(wr->wr.eq(Report::getAuditDeptManagerid,userId).eq(Report::getIsDeptAudit,1)).or(wr1->wr1.eq(Report::getProjectAuditorId,userId).eq(Report::getIsDeptAudit,0)));
+        List<Report> reportList = reportMapper.selectList(queryWrapper);
+        reportList.forEach(r->{
+            if (r.getIsDeptAudit() == 1) {
+                r.setAuditDeptManagerid(targetAuditorId);
+            } else {
+                r.setProjectAuditorId(targetAuditorId);
+            }
+        });
+        if(!reportService.updateBatchById(reportList)){
+            msg.setError("验证失败");
+            return msg;
+        }
+        User user = userMapper.selectById(userId);
+        user.setIsActive(0);
+        userMapper.updateById(user);
+        participationMapper.delete(new LambdaQueryWrapper<Participation>().eq(Participation::getUserId,user.getId()));
+        return msg;
+    }
+
     @RequestMapping("/changeReminder")
     public HttpRespMsg changeReminder(String createDate,String userId,String startDate,String endDate) throws Exception {
         return reportService.changeReminder(request,createDate,userId,startDate,endDate);

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

@@ -752,14 +752,14 @@ public class UserController {
         HttpRespMsg msg = new HttpRespMsg();
         Integer companyId = userService.getById(request.getHeader("token")).getCompanyId();
         //针对美莱德,飞锐特,湾创在对人员进行停用操作时,需要检查待他审核的日报
-        if(companyId==876||companyId==877||companyId==878){
+        if(companyId==876||companyId==877||companyId==878 || companyId==10){
             LambdaQueryWrapper<Report> queryWrapper = new LambdaQueryWrapper<>();
             queryWrapper.eq(Report::getState,0);
             queryWrapper.eq(Report::getCompanyId,companyId);
             queryWrapper.and(wrapper->wrapper.and(wr->wr.eq(Report::getAuditDeptManagerid,user.getId()).eq(Report::getIsDeptAudit,1)).or(wr1->wr1.eq(Report::getProjectAuditorId,user.getId()).eq(Report::getIsDeptAudit,0)));
             Integer count = reportMapper.selectCount(queryWrapper);
             if(count>0){
-                msg.setError("当前员工有待审核日报,确认停用并驳回日报吗?");
+                msg.setError("当前员工有待审核日报,请确认处理方式?");
                 return msg;
             }
         }

+ 9 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WeiXinCorpController.java

@@ -20,6 +20,7 @@ import org.json.XML;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.ReactiveRedisOperations;
 import org.springframework.http.*;
 import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.*;
@@ -191,6 +192,10 @@ public class WeiXinCorpController {
     String timestamp = Sha1Util.getTimeStamp();
 
     public static Map<String, Item> corpTicketMap = new HashMap<String,Item>();
+
+    @Resource
+    private RedisUtil redisUtil;
+
     public class Item {
         public String jsTicket = null;
         public LocalDateTime expireTime = null;
@@ -803,8 +808,9 @@ public class WeiXinCorpController {
                     org.json.JSONObject batchJob = jsonObject.getJSONObject("BatchJob");
                     String jobId = batchJob.getString("JobId");
                     String jobType = batchJob.getString("JobType");
+                    String authCorpId = jsonObject.getString("AuthCorpId");
                     CorpwxJobResult result = new CorpwxJobResult();
-                    result.setAuthCorpId(jsonObject.getString("AuthCorpId"));
+                    result.setAuthCorpId(authCorpId);
                     result.setErrCode(batchJob.getInt("ErrCode"));
                     result.setErrMsg(batchJob.getString("ErrMsg"));
                     result.setJobId(jobId);
@@ -814,6 +820,8 @@ public class WeiXinCorpController {
                     ReportServiceImpl.corpwxJobCenter.put(jobId, result);
                     UserController.corpwxJobCenter.put(jobId, result);
                     TaskController.corpwxJobCenter.put(jobId, result);
+                    //注册到redis,其他系统可能需要用
+                    redisUtil.setString("corpwxJobCenter"+jobId, jsonObject.toString(), 600);
                 } else if ("auto_activate".equals(infoType)) {
                     //被邀请的同事自动激活使用
                     //{"xml":{"Scene":1,"InfoType":"auto_activate",

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

@@ -82,11 +82,11 @@ public interface ReportService extends IService<Report> {
 
     HttpRespMsg getlastWeekFillTime(String userId);
 
-    HttpRespMsg getNoReportUserList(HttpServletRequest request, String startDate, String endDate,Integer noReportDeptId);
+    HttpRespMsg getNoReportUserList(HttpServletRequest request, String startDate, String endDate,Integer noReportDeptId, Integer onlyHaveAttendance);
 
     List<Map<String, Object>> getNotFullReportUserList(Integer companyId, LocalDate startDate, LocalDate endDate);
 
-    HttpRespMsg exportNoReportUserList(HttpServletRequest request, String startDate, String endDate,Integer noReportDeptId);
+    HttpRespMsg exportNoReportUserList(HttpServletRequest request, String startDate, String endDate,Integer noReportDeptId, Integer onlyHaveAttendance);
 
     HttpRespMsg approveAllImport(HttpServletRequest request);
 

+ 10 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ExcelExportServiceImpl.java

@@ -20,6 +20,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
+import java.io.File;
 import java.time.LocalDateTime;
 import java.util.HashMap;
 import java.util.List;
@@ -740,7 +741,16 @@ public class ExcelExportServiceImpl implements ExcelExportService {
             //文件名不能含有路径,得替换掉
             title = title.replace("\\", "@");
         }
+
+
         String fileUrlSuffix = title + ".xlsx";
+        //检查文件是否存在
+        File file = new File(downloadPath + fileUrlSuffix);
+        if (!file.exists()) {
+            httpRespMsg.setError("数据存在问题,文件生成失败");
+            System.err.println("数据存在问题,文件生成失败:"+downloadPath + fileUrlSuffix);
+            return httpRespMsg;
+        }
         if(wxCorpInfo != null && wxCorpInfo.getSaasSyncContact() == 1){
             String mediaId = wxCorpInfoService.getTranslationMediaId(fileUrlSuffix);
             String jobId = wxCorpInfoService.syncTranslation(wxCorpInfo.getCorpid(),mediaId,fileUrlSuffix, null);

+ 2 - 6
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java

@@ -671,12 +671,8 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             String[] sheetNames = new String[2];
             sheetNames[0] = "项目统计表";
             sheetNames[1] = "人员统计表";
-
-
-
-//            return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,dingding,"月度工时统计表" , allList, path);
-//            return excelExportService.exportMultiSheetGeneralExcelByTitleAndList(wxCorpInfo,dingding,"月度工时统计表" , totalList, path,sheetNames);
-            return excelExportService.exportMultiSheetGeneralExcelByTitleAndListNew(wxCorpInfo,dingding,"月度工时统计表" , totalList, path,sheetNames);
+            String fileName = year + "年" + month + "月工时统计表_"+System.currentTimeMillis();
+            return excelExportService.exportMultiSheetGeneralExcelByTitleAndListNew(wxCorpInfo,dingding,fileName , totalList, path,sheetNames);
         } catch (NullPointerException e) {
             e.printStackTrace();
             //httpRespMsg.setError("验证失败");

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

@@ -5889,10 +5889,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     public HttpRespMsg exportReport(@RequestParam String startDate, @RequestParam String endDate,Integer exportType, Integer projectId,Integer stateKey,String departmentIds, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         DateFormat timeDf = new SimpleDateFormat("yyyy-MM-dd");
-        long t0 = System.currentTimeMillis();
-        long fetchDataTime = 0;
         try {
-            long downloadCountStart = System.currentTimeMillis();
             String userId = request.getHeader("Token");
             User user = userMapper.selectById(userId);
             //检查模式,是否是一个项目多个工作事项的情况
@@ -6096,15 +6093,11 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             }
             else {
                 //看公司所有人的
-                long t1 = System.currentTimeMillis();
                 if (exportType == 0 && timeType.getShowFillauditTime() == 1) {
                     allReportByDate = reportMapper.getAllReportByDateWithReportLog(startDate, user.getCompanyId(), null, endDate, projectId,stateKey,branchDepartment);
                 } else {
                     allReportByDate = reportMapper.getAllReportByDate(startDate, user.getCompanyId(), null, endDate, projectId,stateKey,branchDepartment);
                 }
-                long t2 = System.currentTimeMillis();
-                fetchDataTime = (t2-t1);
-                System.out.println("查数据库耗时:"+(t2-t1)/1000+"s");
             }
             //获取企业微信考勤数据
             List<UserCorpwxTime> userCorpwxTimeList = new ArrayList<>();
@@ -6191,7 +6184,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             if (companyId == 4281) {
                 //苏州博海,需要导出未填写的记录
                 //allReportByDate针对每一个员工,列表中没有的工作日要补上
-                HttpRespMsg noReportMsg = getNoReportUserList(request, startDate, endDate, null);
+                HttpRespMsg noReportMsg = getNoReportUserList(request, startDate, endDate, null, 0);
                 List<UserDailyWorkItem> noReportUserList = (List<UserDailyWorkItem>)noReportMsg.data;
                 //追加到最后
                 for (UserDailyWorkItem item : noReportUserList) {
@@ -6815,7 +6808,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
 
     @Override
-    public HttpRespMsg getNoReportUserList(HttpServletRequest request, String startDate, String endDate,Integer noReportDeptId) {
+    public HttpRespMsg getNoReportUserList(HttpServletRequest request, String startDate, String endDate,Integer noReportDeptId, Integer onlyHaveAttendance) {
         HttpRespMsg msg = new HttpRespMsg();
         User user = userMapper.selectById(request.getHeader("TOKEN"));
         List<User> allRangeUserList = new ArrayList<>();
@@ -6987,8 +6980,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 }
             }
         }
-        //如果开启也企业微信考勤同步,没有企微考勤打卡记录的就不算未提交
-        if (timeType.getSyncCorpwxTime() == 1) {
+        //如果开启也企业微信考勤同步,仅仅显示有考勤记录的人员
+        if (timeType.getSyncCorpwxTime() == 1 && onlyHaveAttendance == 1) {
             noReportDataList = noReportDataList.stream().filter(item -> !(item.cardTime == null && item.status.equals(MessageUtils.message("leave.notFill")))).collect(Collectors.toList());
         }
 
@@ -7086,8 +7079,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
 
     @Override
-    public HttpRespMsg exportNoReportUserList(HttpServletRequest request, String startDate, String endDate,Integer noReportDeptId) {
-        HttpRespMsg msg = getNoReportUserList(request, startDate, endDate,noReportDeptId);
+    public HttpRespMsg exportNoReportUserList(HttpServletRequest request, String startDate, String endDate,Integer noReportDeptId, Integer onlyHaveAttendance) {
+        HttpRespMsg msg = getNoReportUserList(request, startDate, endDate,noReportDeptId, onlyHaveAttendance);
         String token = request.getHeader("TOKEN");
         TimeType timeType = timeTypeMapper.selectById(userMapper.selectById(token).getCompanyId());
         Integer companyId = userMapper.selectById(token).getCompanyId();

+ 8 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java

@@ -692,8 +692,14 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
         } else {
             //指定获取员工
             User user = userMapper.selectById(userId);
-            corpwxUserIds.add(user.getCorpwxUserid());
-            System.out.println("获取corpwxuserid==" + user.getCorpwxUserid() + "的考勤记录");
+            String corpwxUserid = user.getCorpwxUserid();
+            if (corpwxUserid != null) {
+                corpwxUserIds.add(corpwxUserid);
+                System.out.println("获取corpwxuserid==" + corpwxUserid + "的考勤记录");
+            } else {
+                msg.setError("该员工未绑定企业微信,无法获取考勤记录");
+                return msg;
+            }
         }
         //按批调用
         for (int i = 0; i < batchCount; i++) {

+ 11 - 7
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/ExcelUtil.java

@@ -1247,6 +1247,7 @@ public class ExcelUtil {
 
                 if(multiSheetList[sheetIndex].size() > 0) {
                     int start = 0;
+                    Row row0 = null;
                     for(List<String> rowList : multiSheetList[sheetIndex]) {
                         Row row = sheetOne.createRow(start);
                         row.setHeightInPoints(24);
@@ -1259,13 +1260,15 @@ public class ExcelUtil {
                             }
                             cell.setCellValue(rowList.get(i));
                         }
+                        if (start == 0) {
+                            //先拿第一行,后面需要用到。 不能等for循环结束再拿,因为for循环结束后可能数据超过100行。 SXSSFWorkbook 会通过一个内部缓冲区管理内存中保留的行数。
+                            // 默认情况下,它只会在内存中保留最近的 100 行。如果行数超过这个限制,它会将早期的行写入磁盘并将它们从内存中删除。
+                            // 因此,当你尝试获取 sheetOne.getRow(0) 时,返回的行对象为空,因为那一行已经被丢弃到磁盘。
+                            row0 = row;
+                        }
                         start++;
                     }
                     if (sheetIndex==1){
-                        Row row0 = sheetOne.getRow(0);
-                        for (int i = 0; i < 4; i++) {
-                            sheetOne.addMergedRegion(new CellRangeAddress(0, 1, i,i));
-                        }
                         int numberOfCells = row0.getPhysicalNumberOfCells();
                         int index=-1;
                         for (int i = 0; i < numberOfCells; i++) {
@@ -1274,6 +1277,10 @@ public class ExcelUtil {
                                 break;
                             }
                         }
+
+                        for (int i = 0; i < 4; i++) {
+                            sheetOne.addMergedRegion(new CellRangeAddress(0, 1, i,i));
+                        }
                         if (index!=-1){
                             sheetOne.addMergedRegion(new CellRangeAddress(0, 0, 4,index-1));
                         }
@@ -1281,9 +1288,6 @@ public class ExcelUtil {
                         if (index!=-1&&index<lastCellNum-1){
                             sheetOne.addMergedRegion(new CellRangeAddress(0, 0, index,lastCellNum-1));
                         }
-
-
-
                     }
                 }
             }

+ 63 - 36
fhKeeper/formulahousekeeper/timesheet/src/views/team/index.vue

@@ -649,6 +649,33 @@
                 <el-button type="primary" @click="confirmDeactive">{{ $t('btn.determine') }}</el-button>
             </span>
         </el-dialog>
+
+        <el-dialog title="转移日报审核人" :visible.sync="reportAuditorSelectDialog" width="500px" >
+            <p>*该用户尚有需要审核的日报,请确认处理方式</p>
+            <el-form :model="userInActiveForm" label-width="120px">
+                <el-form-item prop="name">
+                    <el-radio-group v-model="userInActiveForm.way">
+                      <el-radio :label="0">驳回日报</el-radio>
+                      <el-radio :label="1">转移审核人</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+
+                <!-- 主要负责人 -->
+                <el-form-item label="选择新的审核人" v-if="userInActiveForm.way">
+                    <el-select v-model="userInActiveForm.targetAuditorId" filterable v-if="user.userNameNeedTranslate != '1'" clearable  :placeholder="$t('defaultText.pleaseChoose')" style="width: 200px">
+                        <el-option v-for="item in users" :key="item.id" :label="item.name" :value="item.id">
+                          <span style="float: left">{{ item.name }}</span>
+                          <span style="float: right; color: #8492a6; font-size: 13px">{{ item.jobNumber }}</span>
+                        </el-option>
+                    </el-select>
+                    <selectCat :size="'medium'" :filterable="true" :clearable="true" :widthStr="'360'" v-if="user.userNameNeedTranslate == '1'" :subject="users" :subjectId="userInActiveForm.targetAuditorId" :distinction="'30'" @selectCal="selectCal"></selectCat>
+                </el-form-item>
+            </el-form>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="reportAuditorSelectDialog = false">{{ $t('btn.cancel') }}</el-button>
+                <el-button type="primary" @click="confirmInactiveWay" >{{ $t('btn.submit') }}</el-button>
+            </span>
+        </el-dialog>
         <!-- 管理专业证书 -->
         <el-dialog :title="$t('professionalCertificate inManagement')" :visible.sync="managementDiolog" width="500px" :before-close="handleClose">
             <div>
@@ -947,6 +974,8 @@ export default {
   },
   data() {
     return {
+      reportAuditorSelectDialog: false,
+      userInActiveForm:{way:0,targetAuditorId:null},
       isExporting: false,
       isSyncContact: false,
       showSyncDDDialog: false,
@@ -2272,42 +2301,10 @@ export default {
             });
             this.getUser();
           } else {
-            if(this.user.companyId==876||this.user.companyId==877||this.user.companyId==878){
-                this.$confirm(this.$t('dangQianYuanGongYouDaiShenHeRiBaoQueRenTingYongBingBoHuiRiBaoMa'), this.$t('other.prompts'), {
-                confirmButtonText: this.$t('btn.determine'),
-                cancelButtonText: this.$t('btn.cancel'),
-                type: 'warning'
-                }).then(() => {
-                  this.http.post(
-                    "/report/denyByCheckId",
-                    { userId:this.deactiveUser.id },
-                    (res) => {
-                      if (res.code == "ok") {
-                        this.$message({
-                          message: this.$t('stopsuccess'),
-                          type: "success",
-                        });
-                      } else {
-                        this.$message({
-                          message: res.msg,
-                          type: "error",
-                        });
-                      }
-                    },
-                    (error) => {
-                      this.listLoading = false;
-                      this.$message({
-                        message: error,
-                        type: "error",
-                      });
-                    }
-                  );
-                }).catch(() => {
-                  this.$message({
-                    type: 'info',
-                    message: this.$t('yiQuXiao')
-                  });          
-              });
+            if(this.user.companyId==876||this.user.companyId==877||this.user.companyId==878 || this.user.companyId == 10){
+              //新的模式
+              this.userInActiveForm.userId = this.deactiveUser.id;
+              this.reportAuditorSelectDialog = true;
             }else{
               this.$message({
                 message: error,
@@ -2324,6 +2321,36 @@ export default {
         }
       );
     },
+
+    confirmInactiveWay() {
+      var url = this.userInActiveForm.way?'/report/transferReportAuditor':'/report/denyByCheckId'
+      this.http.post(
+          url,
+          this.userInActiveForm,
+          (res) => {
+            if (res.code == "ok") {
+              this.$message({
+                message: this.$t('stopsuccess'),
+                type: "success",
+              });
+              this.reportAuditorSelectDialog = false;
+              this.deactiveDialog = false;
+            } else {
+              this.$message({
+                message: res.msg,
+                type: "error",
+              });
+            }
+          },
+          (error) => {
+            this.listLoading = false;
+            this.$message({
+              message: error,
+              type: "error",
+            });
+          }
+        );
+    },
     showDeactiveDialog(item) {
       this.deactiveDialog = true;
       this.deactiveUser = item;

+ 5 - 52
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -1649,7 +1649,7 @@
                         <el-button slot="append" @click="searchScreen(1)" icon="el-icon-search"></el-button>
                     </el-input>
                     <selectCat v-if="user.userNameNeedTranslate == '1'" :filterable="true" :searchBoxTop="'1'" :size="'small'" :subject="usersList" :subjectId="usersListId" :distinction="'13'" :clearable="true" @selectCal="selectCal"></selectCat>
-
+                    <el-checkbox v-model="onlyHaveAttendance" v-if="user.timeType.syncCorpwxTime == 1" style="margin-left:10px;" @change="showMonthNotWorkTime">仅显示有考勤的记录</el-checkbox>
                     <el-link
                         type="primary"
                         style="float: right; vertical-align: middle;height:32px"
@@ -1989,11 +1989,9 @@
         <el-dialog :title="$t('other.Batchimportofworkinghours')" v-if="importWxDialog" :visible.sync="importWxDialog" customClass="customWidth" width="1100px">
             <el-steps :active="active" finish-status="success" style="margin-left:50px;">
             <el-step :title="$t('other.selectadaterangetoimporthours')">
-                
             </el-step>
             <el-step :title="$t('other.downloadTemplateithattendancedata')"></el-step>
             <el-step :title="$t('other.filloutthetemplateanduploaddata')"></el-step>
-
             </el-steps>
             
                 
@@ -2296,6 +2294,7 @@
         },
         data() {
             return {
+                onlyHaveAttendance: false,
                 notFullData:[],
                 notFullOriginList:[],
                 singleDate:1,
@@ -4239,6 +4238,7 @@
           // month: this.date,
           startDate: this.WorktimeDatepickValue[0],
           endDate: this.WorktimeDatepickValue[1],
+          onlyHaveAttendance: this.onlyHaveAttendance?1:0
         },
         (res) => {
           if (res.code == "ok") {
@@ -4374,27 +4374,6 @@
         }
       );
     },
-    // tableListener(){
-    //   let that = this;
-    //   let dom = that.$refs.hasworkTbl.bodyWrapper;
-    //   	  // 添加scroll监听事件
-    //       dom.addEventListener("scroll", function () {
-    //         const scrollDistance = dom.scrollHeight - dom.scrollTop - dom.clientHeight;
-    //         if (scrollDistance < 2) {
-    //           if (that.monthWorkDataS.length < that.monthWorkDataS1.length) {
-    //             that.monthTotalPage++; //当前页数自增
-    //             console.log(that.monthWorkDataS1.length, that.monthWorkDataS.length, that.monthTotalPage, that.monthTotalLages, that.monthTotalPage * that.monthTotalLages)
-    //             var arrList = JSON.parse(JSON.stringify(that.monthWorkDataS1))
-    //             var infoList = arrList.splice(
-    //               that.monthTotalPage * that.monthTotalLages,
-    //               that.monthTotalLages
-    //             );
-    //             // 数据添加
-    //             that.monthWorkDataS = that.monthWorkDataS.concat(infoList);
-    //           }
-    //         }
-    //       })
-    // },
     showMonthNotWorkTime() {
       this.monthTotalPage = 0,
       this.tbload = true,
@@ -4403,27 +4382,20 @@
         {
           startDate: this.WorktimeDatepickValue[0],
           endDate: this.WorktimeDatepickValue[1],
-          noReportDeptId:this.deptIdForNoReport.length>0?this.deptIdForNoReport[this.deptIdForNoReport.length-1]:null
+          noReportDeptId:this.deptIdForNoReport.length>0?this.deptIdForNoReport[this.deptIdForNoReport.length-1]:null,
+          onlyHaveAttendance:this.onlyHaveAttendance?1:0
         },
         (res) => {
           if (res.code == "ok") {
               this.tbload = false
             this.monthNotWorkDate = res.data;
-            // this.monthNotWorkDateS1 = res.data
             this.monthnotTotal = res.data.length
-            // 2222111
             if (this.monthNotWorkDate.length > 50) {
                 this.monthNotWorkDateS = this.monthNotWorkDate.slice(0,50);
             } else {
                 this.monthNotWorkDateS = this.monthNotWorkDate
             }
             this.searchScreen(1)
-            // 判断
-            // if (this.monthnotworkDateS1.length > 0) {
-            //     setTimeout(() => {
-            //         this.tableListenernot()
-            //     }, 1000);
-            // }
             this.$nextTick(function(){
                 this.$refs.hasworkTbl2.doLayout();
             });
@@ -4438,25 +4410,6 @@
         }
       );
     },
-    // tableListenernot(){
-    //   let that = this;
-    //   let dom = that.$refs.hasworkTbl2.bodyWrapper;
-    //       dom.addEventListener("scroll", function () {
-    //       // scrollHeight-scrollTop-clientHeight=0 用来判断滚动条到底部
-    //         const scrollDistance2 = dom.scrollHeight - dom.scrollTop - dom.clientHeight;
-    //         if (scrollDistance2 < 2) {
-    //           if (that.monthNotWorkDateS.length < that.monthNotWorkDateS1.length) {
-    //             that.monthnotTotalPage++; //当前页数自增
-    //             var arrList = JSON.parse(JSON.stringify(that.monthNotWorkDateS1))
-    //             var infoList = arrList.splice(
-    //               that.monthnotTotalPage * that.monthnotTotalLages,
-    //               that.monthnotTotalLages
-    //             );
-    //             that.monthNotWorkDateS = that.monthNotWorkDateS.concat(infoList);
-    //           }
-    //         }
-    //       })
-    // },
     listScroll(){
         if(this.monthWorkDataS.length == this.monthWorkDataS1.length){
             this.isMore = true