Przeglądaj źródła

安及乙不需要校验考勤超支情况
timeType增加通知部门主管上周漏填人员的通知

QuYueTing 1 tydzień temu
rodzic
commit
de06fcd08d

+ 3 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/constant/Constant.java

@@ -62,4 +62,7 @@ public class Constant {
     public static final int ZHE_ZHONG_COMPANY_ID=4811;
     //泓浒
     public static final int HONG_HU_COMPANY_ID=7536;
+
+    //安及乙实业
+    public static final int AN_JI_YI_COMPANY_ID=3511;
 }

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

@@ -2295,7 +2295,7 @@ public class ReportController {
         }
 
 
-        if (createDate[0].contains("@")) {
+        if (createDate[0].contains("@") && company.getId() != Constant.AN_JI_YI_COMPANY_ID) {
             //个人批量填报,判断是否需要考勤校验
             boolean syncCardTime = comTimeType.getSyncCorpwxTime() == 1 || comTimeType.getSyncDingding() == 1 || comTimeType.getSyncFanwei() == 1;
             if (syncCardTime && targetUids == null) {

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

@@ -38,8 +38,8 @@ public class ProjectApprovalLog extends Model<ProjectApprovalLog> {
     private String userName;
 
     @TableField("create_time")
-    @DateTimeFormat(pattern = "yyyy-MM-dd")
-    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
     private LocalDateTime createTime;
 
     /**

+ 12 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/TimeType.java

@@ -704,6 +704,18 @@ public class TimeType extends Model<TimeType> {
     @TableField("finance_twice_assign")
     private Boolean financeTwiceAssign;
 
+    /**
+     * 通知部门主管上周填报情况
+     */
+    @TableField("notify_last_week_fill")
+    private Boolean notifyLastWeekFill;
+
+    /**
+     * 周几通知上周填报情况
+     */
+    @TableField("notify_last_week_on_weekday")
+    private Integer notifyLastWeekOnWeekday;
+
 
     @TableField(exist = false)
     private List<User> userList;

+ 0 - 720
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/TimeType.java~

@@ -1,720 +0,0 @@
-package com.management.platform.entity;
-
-import java.math.BigDecimal;
-import com.baomidou.mybatisplus.extension.activerecord.Model;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableField;
-import java.io.Serializable;
-import java.util.List;
-
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.experimental.Accessors;
-
-/**
- * <p>
- * 
- * </p>
- *
- * @author Seyason
- * @since 2026-03-10
- */
-@Data
-@EqualsAndHashCode(callSuper = false)
-@Accessors(chain = true)
-public class TimeType extends Model<TimeType> {
-
-    private static final long serialVersionUID=1L;
-
-    /**
-     * 公司id
-     */
-    @TableId("company_id")
-    private Integer companyId;
-
-    /**
-     * 全天时长
-     */
-    @TableField("allday")
-    private Float allday;
-
-    /**
-     * 上午时长
-     */
-    @TableField("am")
-    private Float am;
-
-    /**
-     * 下午时长
-     */
-    @TableField("pm")
-    private Float pm;
-
-    /**
-     * 每月工作天数
-     */
-    @TableField("month_days")
-    private BigDecimal monthDays;
-
-    /**
-     * 时薪录入方式:0-按月薪计算,1-直接输入时薪
-     */
-    @TableField("hour_cost_input_type")
-    private Integer hourCostInputType;
-
-    /**
-     * 时长上报方式
-     */
-    @TableField("type")
-    private Integer type;
-
-    /**
-     * 是否计算加班工时工资
-     */
-    @TableField("pay_overtime")
-    private Boolean payOvertime;
-
-    /**
-     * 填报提醒时间
-     */
-    @TableField("alert_time")
-    private String alertTime;
-
-    /**
-     * 支持同个项目多个时间事项录入
-     */
-    @TableField("multi_worktime")
-    private Integer multiWorktime;
-
-    /**
-     * 强制固定月薪
-     */
-    @TableField("fix_monthcost")
-    private Integer fixMonthcost;
-
-    /**
-     * 可补填几个月的, 0-不限制,1-本月,2-上个月,3-上上月,4- 7天内 ,5- 前一天
-     */
-    @TableField("fill_months")
-    private Integer fillMonths;
-
-    /**
-     * 工时填报自定义维度是否启用
-     */
-    @TableField("custom_degree_active")
-    private Integer customDegreeActive;
-
-    /**
-     * 工时填报自定义维度名称
-     */
-    @TableField("custom_degree_name")
-    private String customDegreeName;
-
-    /**
-     * 工时填报自定义维度是否必填 0-否 1-是
-     */
-    @TableField("custom_degree_status")
-    private Integer customDegreeStatus;
-
-    /**
-     * 工时填报自定义维度是否绑定项目 0-否 1-是
-     */
-    @TableField("custom_degree_with_pro")
-    private Integer customDegreeWithPro;
-
-    /**
-     * 提醒内容
-     */
-    @TableField("alert_msg")
-    private String alertMsg;
-
-    /**
-     * 同步企业微信的考勤记录
-     */
-    @TableField("sync_corpwx_time")
-    private Integer syncCorpwxTime;
-
-    /**
-     * 是否需要部门上级审核日报
-     */
-    @TableField("need_dept_audit")
-    private Integer needDeptAudit;
-
-    /**
-     * 是否开启自定义审批流
-     */
-    @TableField("report_workflow")
-    private Integer reportWorkflow;
-
-    /**
-     * 工时填报数值收集开关
-     */
-    @TableField("custom_data_active")
-    private Integer customDataActive;
-
-    /**
-     * 工时填报数值收集字段名称
-     */
-    @TableField("custom_data_name")
-    private String customDataName;
-
-    /**
-     * 工时填报数值收集字段是否必填 0-否 1-是
-     */
-    @TableField("custom_data_status")
-    private Integer customDataStatus;
-
-    /**
-     * 工时填报数值收集字段最大值是否限制 0-否 1-是
-     */
-    @TableField("custom_data_max_status")
-    private Integer customDataMaxStatus;
-
-    /**
-     * 工时填报数值收集字段最大值限制
-     */
-    @TableField("custom_data_max_value")
-    private Integer customDataMaxValue;
-
-    /**
-     * 财务成本导入是否需要审核
-     */
-    @TableField("finance_audit")
-    private Integer financeAudit;
-
-    /**
-     * 加班倍数
-     */
-    @TableField("overtime_ratio")
-    private Double overtimeRatio;
-
-    /**
-     * 是否同步钉钉考勤打卡和出差
-     */
-    @TableField("sync_dingding")
-    private Integer syncDingding;
-
-    /**
-     * 是否是药研行业
-     */
-    @TableField("is_cro")
-    private Integer isCro;
-
-    /**
-     * 只使用导入功能,不要项目审核
-     */
-    @TableField("only_importreport")
-    private Integer onlyImportreport;
-
-    /**
-     * 填写日报显示钉钉打卡时长
-     */
-    @TableField("show_dd_cardtime")
-    private Integer showDdCardtime;
-
-    /**
-     * 填写日报显示企业微信打卡时长
-     */
-    @TableField("show_corpwx_cardtime")
-    private Integer showCorpwxCardtime;
-
-    /**
-     * 自定义文本信息是否开启
-     */
-    @TableField("custom_text_active")
-    private Integer customTextActive;
-
-    /**
-     * 自定义文本信息字段名称
-     */
-    @TableField("custom_text_name")
-    private String customTextName;
-
-    /**
-     * 自定义文本信息是否必填 0-否 1-是
-     */
-    @TableField("custom_text_status")
-    private Integer customTextStatus;
-
-    /**
-     * 是否锁定每日填报时长
-     */
-    @TableField("lock_worktime")
-    private Integer lockWorktime;
-
-    /**
-     * 填报是否填报加班
-     */
-    @TableField("fill_overtime")
-    private Integer fillOvertime;
-
-    /**
-     * 是否显示填报和审核的时间
-     */
-    @TableField("show_fillaudit_time")
-    private Integer showFillauditTime;
-
-    /**
-     * 是否秘薪处理,即任何人的薪资都显示*
-     */
-    @TableField("is_secret_salary")
-    private Integer isSecretSalary;
-
-    /**
-     * 采用三位组合,第一位代表周六,第二位代表周日,第三位代表其他节假日,0代表不提醒,1代表提醒
-     */
-    @TableField("alert_non_workday")
-    private Integer alertNonWorkday;
-
-    /**
-     * 0-每日提醒当天漏填 1-每日提醒昨天漏填
-     */
-    @TableField("alert_type")
-    private Integer alertType;
-
-    /**
-     * 0-工作内容非必填 1-工作内容必填
-     */
-    @TableField("work_content_state")
-    private Integer workContentState;
-
-    /**
-     * 0-不可提前填报 1-可提前填报
-     */
-    @TableField("fill_ahead")
-    private Integer fillAhead;
-
-    /**
-     * 0-当天 1-第二天 2-第三天
-     */
-    @TableField("timeliness")
-    private Integer timeliness;
-
-    /**
-     * 0-未开启 1-开启
-     */
-    @TableField("main_project_state")
-    private Integer mainProjectState;
-
-    /**
-     * 日报的审核类型, 0-项目审核人审核,1-分组负责人审核,2-先分组负责人审核再项目负责人(PM)审核;3-员工自由选择审批人 4-项目所属BU审核 5-直属审核人或部门负责人审核,6-直属或部门负责人审核->项目日报审核人审核,7-项目和部门并行审核;8-项目设置复审人;9-分组负责人审核->项目日报审核人审核;10-普通员工到项目经理,项目经理到单独审核人
-     */
-    @TableField("report_audit_type")
-    private Integer reportAuditType;
-
-    /**
-     * 0-未开启 1-开启
-     */
-    @TableField("project_level_state")
-    private Integer projectLevelState;
-
-    /**
-     * 0-未开启 1-开启
-     */
-    @TableField("need_evaluate")
-    private Integer needEvaluate;
-
-    /**
-     * 产值  0-未开启 1-开启
-     */
-    @TableField("output_value_status")
-    private Integer outputValueStatus;
-
-    /**
-     * 0-未开启 1-开启
-     */
-    @TableField("user_custom_static")
-    private Integer userCustomStatic;
-
-    /**
-     * 批量填报是否包含节假日;0-不包含,1-包含
-     */
-    @TableField("include_weekends")
-    private Integer includeWeekends;
-
-    /**
-     * 从相册选择图片 0-未开启 1-开启
-     */
-    @TableField("chose_from_album")
-    private Integer choseFromAlbum;
-
-    /**
-     * 项目相关部门 0-未开启 1-开启
-     */
-    @TableField("project_with_dept")
-    private Integer projectWithDept;
-
-    /**
-     * 财务核算成本导入是否含工号:0-不含,1-含
-     */
-    @TableField("finance_jobnum_enabled")
-    private Integer financeJobnumEnabled;
-
-    /**
-     * 日报审核通过消息推送 0-未开启 1-开启
-     */
-    @TableField("report_approve_msgpush")
-    private Integer reportApproveMsgpush;
-
-    /**
-     * 日报自动审核 0-未开启 1-开启
-     */
-    @TableField("report_auto_approve")
-    private Integer reportAutoApprove;
-
-    /**
-     * 日报自动审核天数
-     */
-    @TableField("report_auto_approve_days")
-    private Integer reportAutoApproveDays;
-
-    /**
-     * 日报填报时长上限,默认12小时
-     */
-    @TableField("max_report_time")
-    private Float maxReportTime;
-
-    /**
-     * 填报工作时长下限
-     */
-    @TableField("min_report_time")
-    private Float minReportTime;
-
-    /**
-     * 是否同步泛微考勤打卡和出差
-     */
-    @TableField("sync_fanwei")
-    private Integer syncFanwei;
-
-    /**
-     * 员工自由选择审核人的方式下的审核层级:默认为2
-     */
-    @TableField("audit_level")
-    private Integer auditLevel;
-
-    /**
-     * 任务列表是否有预估工时功能
-     */
-    @TableField("stage_has_evtime")
-    private Integer stageHasEvtime;
-
-    /**
-     * 无考勤记录无法填报
-     */
-    @TableField("not_allowed_no_attendance")
-    private Integer notAllowedNoAttendance;
-
-    /**
-     * 1为需要同步企业微信请假,0为不需要同步企业微信请假
-     */
-    @TableField("wx_leave")
-    private Integer wxLeave;
-
-    /**
-     * 是否开通【推送工时数据】 0-否 1-是
-     */
-    @TableField("push_report_data")
-    private Integer pushReportData;
-
-    /**
-     * 推送工时数据URL
-     */
-    @TableField("push_report_url")
-    private String pushReportUrl;
-
-    /**
-     * 0-否 1-是
-     */
-    @TableField("restart_task_need_reason")
-    private Integer restartTaskNeedReason;
-
-    /**
-     * 0-否 1-是  子项目是否必填
-     */
-    @TableField("sub_pro_must_fill")
-    private Integer subProMustFill;
-
-    /**
-     * 0-否 1-是  加班时长是否需要校验
-     */
-    @TableField("work_overtime_need_check")
-    private Integer workOvertimeNeedCheck;
-
-    /**
-     * 0-否 1-是  是否开启项目人天校验功能
-     */
-    @TableField("project_man_day")
-    private Integer projectManDay;
-
-    /**
-     * 0-否 1-是  是否开启项目表单自定义
-     */
-    @TableField("project_custom")
-    private Integer projectCustom;
-
-    /**
-     * 待审核提醒时间
-     */
-    @TableField("wait_check_alert_time")
-    private String waitCheckAlertTime;
-
-    /**
-     * 0-否 1-是  是否开启简易费用报销
-     */
-    @TableField("easy_expense")
-    private Integer easyExpense;
-
-    /**
-     * 是否同步AD
-     */
-    @TableField("sync_ad")
-    private Integer syncAd;
-
-    /**
-     * 是否日报审核人变为日报抄送人,当report_audit_type=5时,可以设置该字段为1
-     */
-    @TableField("report_cc")
-    private Integer reportCc;
-
-    /**
-     * 非工作日是否禁止填报
-     */
-    @TableField("not_allowed_on_non_workday")
-    private Integer notAllowedOnNonWorkday;
-
-    /**
-     * 关闭工时填报
-     */
-    @TableField("stop_report")
-    private Integer stopReport;
-
-    /**
-     * 是否启用新的按周填报模式
-     */
-    @TableField("enable_new_weeklyfill")
-    private Integer enableNewWeeklyfill;
-
-    /**
-     * 默认每月1号提醒上个月
-     */
-    @TableField("alert_day")
-    private Integer alertDay;
-
-    /**
-     * 默认每月3号前可补填上个月日报
-     */
-    @TableField("fill_month_on_day")
-    private Integer fillMonthOnDay;
-
-    /**
-     * 同步对接sap系统 0-否 1-是
-     */
-    @TableField("sync_sap")
-    private Integer syncSap;
-
-    /**
-     * 项目超期不可填报
-     */
-    @TableField("not_allowed_expired_project")
-    private Integer notAllowedExpiredProject;
-
-    /**
-     * 按时间段填报时,时间是否可重叠
-     */
-    @TableField("time_can_overlap")
-    private Integer timeCanOverlap;
-
-    /**
-     * 自定义维度是否填报是可多选
-     */
-    @TableField("custom_degree_multiple")
-    private Boolean customDegreeMultiple;
-
-    /**
-     * 任务分组是否必填
-     */
-    @TableField("task_group_required")
-    private Integer taskGroupRequired;
-
-    /**
-     * 任务是否必填 0-否 1-是
-     */
-    @TableField("task_required")
-    private Integer taskRequired;
-
-    /**
-     * 日报填报隐藏阶段项
-     */
-    @TableField("hide_stages")
-    private Integer hideStages;
-
-    /**
-     * 日报填报隐藏任务项
-     */
-    @TableField("hide_task")
-    private Integer hideTask;
-
-    /**
-     * 项目隐藏子项目功能按钮
-     */
-    @TableField("hide_subproject")
-    private Integer hideSubproject;
-
-    /**
-     * 开启日报审批流的本部门负责人由上级部门负责人审核
-     */
-    @TableField("report_audit_flow_enable_super_dept_aduit")
-    private Integer reportAuditFlowEnableSuperDeptAduit;
-
-    /**
-     * 是否开启设置可填报部门 0-否 1-是
-     */
-    @TableField("user_with_multi_dept")
-    private Integer userWithMultiDept;
-
-    /**
-     * 提醒审核日,默认周一
-     */
-    @TableField("alert_check_day")
-    private Integer alertCheckDay;
-
-    /**
-     * 提醒审核的文字消息
-     */
-    @TableField("alert_check_msg")
-    private String alertCheckMsg;
-
-    /**
-     * 导入的日报,按照正常审批来处理,非单独设置的部门直属领导审核
-     */
-    @TableField("import_report_audit_normal")
-    private Integer importReportAuditNormal;
-
-    /**
-     * 日报第二审核人;在reportAuditType5时有效
-     */
-    @TableField("second_auditor")
-    private String secondAuditor;
-
-    /**
-     * 日报第三审核人;在reportAuditType5时有效
-     */
-    @TableField("third_auditor")
-    private String thirdAuditor;
-
-    /**
-     * 工时报告页面,查看时仅显示比例;
-     */
-    @TableField("only_show_percent")
-    private Integer onlyShowPercent;
-
-    /**
-     * 是否校验考勤数据的加班时长
-     */
-    @TableField("verify_card_overtime")
-    private Integer verifyCardOvertime;
-
-    /**
-     * 驳回日报原因是否必填
-     */
-    @TableField("force_reject_reason")
-    private Integer forceRejectReason;
-
-    /**
-     * 任务文件审核 0不启用 1启用
-     */
-    @TableField("task_file_charge")
-    private Integer taskFileCharge;
-
-    /**
-     * 任务预估成本功能是否开启,0-不启用,1-启用
-     */
-    @TableField("task_plan_cost")
-    private Integer taskPlanCost;
-
-    /**
-     * 项目进度判断依据,0-默认字段,1-根据任务工时
-     */
-    @TableField("project_progress_check")
-    private Integer projectProgressCheck;
-
-    /**
-     * 按周审核日报过滤功能,0-不开启,1-开启
-     */
-    @TableField("weekly_charge_filter")
-    private Integer weeklyChargeFilter;
-
-    /**
-     * 对已通过的日报进行撤销操作时是否发送企微消息功能,0-不发送,1-发送
-     */
-    @TableField("report_charge_msg")
-    private Integer reportChargeMsg;
-
-    /**
-     * 项目审核人是自己时自动审核通过
-     */
-    @TableField("auto_project_approve")
-    private Boolean autoProjectApprove;
-
-    /**
-     * 日报定制字段4名称
-     */
-    @TableField("report_extra_field4_name")
-    private String reportExtraField4Name;
-
-    /**
-     * 日报定制字段5名称
-     */
-    @TableField("report_extra_field5_name")
-    private String reportExtraField5Name;
-
-    /**
-     * 审核提醒方式:0-定时提醒,1-实时提醒
-     */
-    @TableField("alert_audit_mode")
-    private Integer alertAuditMode;
-
-    /**
-     * 部门负责人接收抄送提醒
-     */
-    @TableField("cc_dept_manager")
-    private Boolean ccDeptManager;
-
-    /**
-     * 代填不校验考勤
-     */
-    @TableField("not_check_cardtime")
-    private Boolean notCheckCardtime;
-
-    /**
-     * 工时填报隐藏分组
-     */
-    @TableField("hide_group")
-    private Boolean hideGroup;
-
-    /**
-     * 工时填报隐藏工作内容
-     */
-    @TableField("hide_content")
-    private Boolean hideContent;
-
-    /**
-     * 财务分摊二次分配功能
-     */
-    @TableField("finance_twice_assign")
-    private Boolean financeTwiceAssign;
-    
-
-    @TableField(exist = false)
-    private List<User> userList;
-    @TableField(exist = false)
-    private List<TimeAutoExclude> excludeTimeList;
-    @TableField(exist = false)
-    private Integer saasSyncContact;
-
-    @Override
-    protected Serializable pkVal() {
-        return this.companyId;
-    }
-
-}

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

@@ -8123,6 +8123,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     map.put("feishuUserid", curUser.getFeishuUserid());
                     map.put("id", curUser.getId());
                     map.put("name", curUser.getName());
+                    map.put("deptId", curUser.getDepartmentId());
                     map.put("days", 1);
                     map.put("daysTxt", date.format(DateTimeFormatter.ofPattern("MM/dd")));
                     if (!noReportDataList.stream().anyMatch(noItem->noItem.get("id").equals(curUser.getId()))) {

+ 3 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java

@@ -125,6 +125,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
     public static final int TEXT_CARD_MSG_PROJECT_CREATE = 30;//立项待审核
     public static final int TEXT_CARD_MSG_PROJECT_REJECTED = 31;
     public static final int TEXT_CARD_MSG_PROJECT_APPROVED = 32;
+    public static final int TEXT_CARD_MSG_MEMB_MISS_REPORT = 33;
     private static Object userLock = new Object();
 
     @Value("${suitId}")
@@ -383,6 +384,8 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                     title = "任务文件审核";
                 } else if (msgType.equals(TEXT_CARD_MSG_REPORT_SUBMIT)) {
                     title = "日报提交提醒";
+                } else if (msgType.equals(TEXT_CARD_MSG_MEMB_MISS_REPORT)) {
+                    title = "员工漏填提醒";
                 }
             } else {
                 jumpUrl = jumpUrl.replace("STATE", pageRouter);

+ 47 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java

@@ -48,6 +48,8 @@ import java.util.concurrent.Executors;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
+import static com.management.platform.service.impl.WxCorpInfoServiceImpl.TEXT_CARD_MSG_MEMB_MISS_REPORT;
+
 /**
  * Author: 吴涛涛
  * Date : 2019 - 12 - 31 16:04
@@ -1383,6 +1385,51 @@ public class TimingTask {
         }
     }
 
+    //发送上周工时填报情况给部门主管
+    @Scheduled(cron = "0 55 8 ? * *")
+    private void lastWeekFillStatisticsToManager() {
+        if (isDev) return;
+        LocalDate curDay = LocalDate.now();
+        int dayOfWeek = curDay.getDayOfWeek().getValue();
+        List<TimeType> timeTypeList = timeTypeMapper.selectList(new LambdaQueryWrapper<TimeType>().select(TimeType::getCompanyId).eq(TimeType::getNotifyLastWeekFill, true).eq(TimeType::getNotifyLastWeekOnWeekday, dayOfWeek));
+        if (!timeTypeList.isEmpty()) {
+            //获取公司员工漏填/未提交的进行提醒
+            //计算上周的日期范围
+            LocalDate lastWeek = curDay.minusWeeks(1);
+            int weekDay = lastWeek.getDayOfWeek().getValue();
+            LocalDate startDate = lastWeek.minusDays(weekDay - 1);
+            LocalDate endDate = startDate.plusDays(6);
+            for (TimeType timeType : timeTypeList) {
+                Integer companyId = timeType.getCompanyId();
+                Company company = companyMapper.selectById(companyId);
+                if (company.getExpirationDate().isBefore(LocalDateTime.now())) continue;//跳过过期的公司
+                //
+                List<Map<String, Object>> userList = reportService.getNotFullReportUserList(companyId, startDate, endDate);
+
+                List<Department> departmentList = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id", companyId).isNotNull("manager_id"));
+                for (Department d : departmentList) {
+                    //取上周下属员工的日报漏填,未提交的
+                    int curDeptUserCount = 0;
+                    for (Map<String, Object> user : userList) {
+                        if (d.getDepartmentId().intValue() == (Integer)user.get("deptId")) {
+                            curDeptUserCount++;
+                        }
+                    }
+                    if (curDeptUserCount > 0) {
+                        WxCorpInfo corpInfo = wxCorpInfoService.getOne(new QueryWrapper<WxCorpInfo>().eq("company_id", companyId));
+                        if (corpInfo != null) {
+                            //发送提醒给主管
+                            User targetUser = userMapper.selectById(d.getManagerId());
+                            wxCorpInfoService.sendWXCorpMsg(corpInfo, targetUser.getCorpwxUserid(), "您上周有" + curDeptUserCount + "名下属员工未填报工时", null, (Integer)TEXT_CARD_MSG_MEMB_MISS_REPORT);
+                        }
+//                        pushLastWeekReportFillToManager(company, d, curDeptUserCount);
+                    }
+                }
+
+            }
+        }
+    }
+
     //发送关联出差的提醒
     @Scheduled(cron = "0 5 9 ? * *")
     private void linkBusinessTripAlert() {

Plik diff jest za duży
+ 14349 - 184883
fhKeeper/formulahousekeeper/management-platform/workTime.log


+ 198 - 243
fhKeeper/formulahousekeeper/timesheet/src/views/projectApproval/projectApproval.vue

@@ -1069,251 +1069,135 @@
           customClass="customWidth"
           width="800px"
         >
-          <el-row :gutter="10" class="detail-row">
-            <el-col :span="5"
-              ><div class="gray_label">{{ "项目编号:" }}</div></el-col
-            >
-            <el-col :span="7"
-              ><div class="gray_label">
-                {{ projectApprocalDetail.projectCode }}
-              </div></el-col
-            >
-            <el-col :span="5"
-              ><div class="gray_label">{{ "项目名称:" }}</div></el-col
-            >
-            <el-col :span="7"
-              ><div class="gray_label">
-                {{ projectApprocalDetail.projectName }}
-              </div></el-col
-            >
-          </el-row>
-          <el-row :gutter="10" class="detail-row">
-            <el-col :span="5"
-              ><div class="gray_label">{{ "项目分类:" }}</div></el-col
-            >
-            <el-col :span="7"
-              ><div class="gray_label">
-                {{ projectApprocalDetail.categoryName }}
-              </div></el-col
-            >
-            <el-col :span="5"
-              ><div class="gray_label">{{ "项目类型:" }}</div></el-col
-            >
-            <el-col :span="7"
-              ><div class="gray_label">
-                {{
-                  projectApprocalDetail.isPublic == 0 ? "正式项目" : "非项目"
-                }}
-              </div></el-col
-            >
-          </el-row>
-          <el-row :gutter="10" class="detail-row">
-            <el-col :span="3"
-              ><div class="gray_label">{{ "项目描述:" }}</div></el-col
-            >
-            <el-col :span="21"
-              ><div class="gray_label">
-                {{ projectApprocalDetail.projectDesc }}
-              </div></el-col
-            >
-          </el-row>
-          <el-row :gutter="10" class="detail-row">
-            <el-col :span="3"
-              ><div class="gray_label">{{ "全部参与人:" }}</div></el-col
-            >
-            <el-col :span="21"
-              ><div class="gray_label">
-                <span
-                  v-for="(
-                    par, index
-                  ) in projectApprocalDetail.participationApprovalList"
-                  :key="par.userId"
-                >
-                  <span v-if="user.userNameNeedTranslate != 1">
-                    {{ par.userName }}
-                  </span>
-                  <span v-if="user.userNameNeedTranslate == 1">
-                    <TranslationOpenDataText
-                      type="userName"
-                      :openid="par.userName"
-                    ></TranslationOpenDataText>
+          <div class="detail-container">
+            <!-- 两列布局 -->
+            <div class="detail-grid">
+              <div class="detail-cell">
+                <span class="detail-label">项目编号:</span>
+                <span class="detail-value">{{ projectApprocalDetail.projectCode }}</span>
+              </div>
+              <div class="detail-cell">
+                <span class="detail-label">项目名称:</span>
+                <span class="detail-value">{{ projectApprocalDetail.projectName }}</span>
+              </div>
+              <div class="detail-cell">
+                <span class="detail-label">项目分类:</span>
+                <span class="detail-value">{{ projectApprocalDetail.categoryName }}</span>
+              </div>
+              <div class="detail-cell">
+                <span class="detail-label">项目类型:</span>
+                <span class="detail-value">{{ projectApprocalDetail.isPublic == 0 ? "正式项目" : "非项目" }}</span>
+              </div>
+              <div class="detail-cell">
+                <span class="detail-label">项目经理:</span>
+                <span class="detail-value">
+                  <span v-if="user.userNameNeedTranslate != 1">{{ projectApprocalDetail.inchargerName }}</span>
+                  <span v-if="user.userNameNeedTranslate == 1 && projectApprocalDetail.inchargerName">
+                    <TranslationOpenDataText type="userName" :openid="projectApprocalDetail.inchargerName"></TranslationOpenDataText>
                   </span>
-                  <span
-                    v-if="
-                      index <
-                      projectApprocalDetail.participationApprovalList.length - 1
-                    "
-                    >,</span
-                  >
                 </span>
-              </div></el-col
-            >
-          </el-row>
-          <el-row :gutter="10" class="detail-row">
-            <el-col :span="5"
-              ><div class="gray_label">{{ "项目经理:" }}</div></el-col
-            >
-            <el-col :span="7"
-              ><div class="gray_label">
-                <span v-if="user.userNameNeedTranslate != 1">{{
-                  projectApprocalDetail.inchargerName
-                }}</span>
-                <span
-                  v-if="
-                    user.userNameNeedTranslate == 1 &&
-                    projectApprocalDetail.inchargerName
-                  "
-                  ><TranslationOpenDataText
-                    type="userName"
-                    :openid="projectApprocalDetail.inchargerName"
-                  ></TranslationOpenDataText
-                ></span>
               </div>
-            </el-col>
-            <el-col :span="5"
-              ><div class="gray_label">{{ "日报审核人:" }}</div></el-col
-            >
-            <el-col :span="7"
-              ><div class="gray_label">
-                <span
-                  v-for="(
-                    par, index
-                  ) in projectApprocalDetail.projectApprovalAuditorList"
-                  :key="par.auditorId"
-                >
-                  <span v-if="user.userNameNeedTranslate != 1">
-                    {{ par.auditorName }}
-                  </span>
-                  <span v-if="user.userNameNeedTranslate == 1">
-                    <TranslationOpenDataText
-                      type="userName"
-                      :openid="par.auditorName"
-                    ></TranslationOpenDataText>
+              <div class="detail-cell">
+                <span class="detail-label">日报审核人:</span>
+                <span class="detail-value">
+                  <span v-for="(par, index) in projectApprocalDetail.projectApprovalAuditorList" :key="par.auditorId">
+                    <span v-if="user.userNameNeedTranslate != 1">{{ par.auditorName }}</span>
+                    <span v-if="user.userNameNeedTranslate == 1">
+                      <TranslationOpenDataText type="userName" :openid="par.auditorName"></TranslationOpenDataText>
+                    </span>
+                    <span v-if="index < projectApprocalDetail.projectApprovalAuditorList.length - 1">,</span>
                   </span>
-                  <span
-                    v-if="
-                      index <
-                      projectApprocalDetail.projectApprovalAuditorList.length -
-                        1
-                    "
-                    >,</span
-                  >
                 </span>
-              </div></el-col
-            >
-          </el-row>
-          <el-row :gutter="10" class="detail-row">
-            <el-col :span="5"
-              ><div class="gray_label">{{ "级别:" }}</div></el-col
-            >
-            <el-col :span="7"
-              ><div class="gray_label">
-                {{ importanceListLable[projectApprocalDetail.level - 1] }}
-              </div></el-col
-            >
-            <el-col :span="5"
-              ><div class="gray_label">{{ "合同金额:" }}</div></el-col
-            >
-            <el-col :span="7"
-              ><div class="gray_label">
-                {{ projectApprocalDetail.contractAmount }}
-              </div></el-col
-            >
-          </el-row>
-          <el-row :gutter="10" class="detail-row">
-            <el-col :span="5"
-              ><div class="gray_label">{{ "计划开始日期:" }}</div></el-col
-            >
-            <el-col :span="7"
-              ><div class="gray_label">
-                {{ projectApprocalDetail.planStartDate }}
-              </div></el-col
-            >
-            <el-col :span="5"
-              ><div class="gray_label">{{ "计划结束日期:" }}</div></el-col
-            >
-            <el-col :span="7"
-              ><div class="gray_label">
-                {{ projectApprocalDetail.planEndDate }}
-              </div></el-col
-            >
-          </el-row>
+              </div>
+              <div class="detail-cell">
+                <span class="detail-label">级别:</span>
+                <span class="detail-value">{{ importanceListLable[projectApprocalDetail.level - 1] }}</span>
+              </div>
+              <div class="detail-cell">
+                <span class="detail-label">合同金额:</span>
+                <span class="detail-value">{{ projectApprocalDetail.contractAmount }}</span>
+              </div>
+              <div class="detail-cell">
+                <span class="detail-label">计划开始日期:</span>
+                <span class="detail-value">{{ projectApprocalDetail.planStartDate }}</span>
+              </div>
+              <div class="detail-cell">
+                <span class="detail-label">计划结束日期:</span>
+                <span class="detail-value">{{ projectApprocalDetail.planEndDate }}</span>
+              </div>
+            </div>
 
-          <el-divider></el-divider>
-          <el-row :gutter="10" class="detail-row">
-            <el-col :span="24"
-              ><div class="gray_label section-title">
-                {{ "成本基线" }}
-              </div></el-col
-            >
-          </el-row>
+            <!-- 全宽字段 -->
+            <div class="detail-fullwidth">
+              <div class="detail-cell-full">
+                <span class="detail-label">项目描述:</span>
+                <span class="detail-value">{{ projectApprocalDetail.projectDesc }}</span>
+              </div>
+              <div class="detail-cell-full">
+                <span class="detail-label">全部参与人:</span>
+                <span class="detail-value">
+                  <span v-for="(par, index) in projectApprocalDetail.participationApprovalList" :key="par.userId">
+                    <span v-if="user.userNameNeedTranslate != 1">{{ par.userName }}</span>
+                    <span v-if="user.userNameNeedTranslate == 1">
+                      <TranslationOpenDataText type="userName" :openid="par.userName"></TranslationOpenDataText>
+                    </span>
+                    <span v-if="index < projectApprocalDetail.participationApprovalList.length - 1">,</span>
+                  </span>
+                </span>
+              </div>
+            </div>
 
-          <div
-            class="gray_label detail-item"
-            v-for="(
-              item, index
-            ) in projectApprocalDetail.projectApprovalBasecostList"
-            :key="index"
-          >
-            <span>{{ item.baseName + ":" }}</span
-            ><span>{{ item.baseAmount }}</span>
-          </div>
-          <el-divider></el-divider>
+            <el-divider></el-divider>
 
-          <el-row :gutter="10" class="detail-row">
-            <el-col :span="24"
-              ><div class="gray_label section-title">{{ "附件" }}</div></el-col
-            >
-          </el-row>
-          <div
-            class="gray_label detail-item"
-            v-for="(
-              item, index
-            ) in projectApprocalDetail.projectApprovalDocumentList || []"
-            :key="item.id"
-          >
-            <span>{{ index + 1 }}. {{ item.documentName }}</span>
-            <el-link
-              style="margin-left: 10px"
-              type="primary"
-              @click="fileDownload(item)"
-              >下载</el-link
-            >
-          </div>
-          <el-divider></el-divider>
+            <div class="detail-section">
+              <div class="detail-section-title">{{ "成本基线" }}</div>
+              <div class="detail-section-grid">
+                <div
+                  class="detail-section-grid-item"
+                  v-for="(item, index) in projectApprocalDetail.projectApprovalBasecostList"
+                  :key="index"
+                >
+                  <span class="detail-label-inline">{{ item.baseName }}</span>
+                  <span class="detail-value-inline">{{ item.baseAmount }} 元</span>
+                </div>
+              </div>
+            </div>
+            <el-divider></el-divider>
 
-          <el-row :gutter="10" class="detail-row">
-            <el-col :span="24"
-              ><div class="gray_label section-title">
-                {{ "操作记录" }}
-              </div></el-col
-            >
-          </el-row>
+            <div class="detail-section">
+              <div class="detail-section-title">{{ "附件" }}</div>
+              <div
+                class="detail-section-row"
+                v-for="(item, index) in projectApprocalDetail.projectApprovalDocumentList || []"
+                :key="item.id"
+              >
+                <span class="detail-value">{{ index + 1 }}. {{ item.documentName }}</span>
+                <el-link style="margin-left: 10px" type="primary" @click="fileDownload(item)">下载</el-link>
+              </div>
+            </div>
+            <el-divider></el-divider>
 
-          <div
-            class="gray_label detail-item"
-            v-for="(item, index) in approvalLogData"
-            :key="index"
-          >
-            <span v-if="user.userNameNeedTranslate != 1"
-              >{{ item.userName }} {{ item.createTime }}
-              {{ approvalTypeStr[item.type] }}{{ $t("leRiBao") }}</span
-            >
-            <span v-if="user.userNameNeedTranslate == 1"
-              ><TranslationOpenDataText
-                type="userName"
-                :openid="item.userName"
-              ></TranslationOpenDataText>
-              {{ item.createTime }}{{ approvalTypeStr[item.type]
-              }}{{ $t("leRiBao") }}</span
-            >
+            <div class="detail-section">
+              <div class="detail-section-title">{{ "操作记录" }}</div>
+              <el-timeline>
+                <el-timeline-item
+                  v-for="(item, index) in approvalLogData"
+                  :key="index"
+                  :timestamp="item.createTime"
+                >
+                  <span v-if="user.userNameNeedTranslate != 1">
+                    {{ item.userName }}{{ approvalTypeStr[item.type] }}了立项申请
+                  </span>
+                  <span v-if="user.userNameNeedTranslate == 1">
+                    <TranslationOpenDataText type="userName" :openid="item.userName"></TranslationOpenDataText>
+                    {{ approvalTypeStr[item.type] }}了立项申请
+                  </span>
+                </el-timeline-item>
+              </el-timeline>
+            </div>
           </div>
           <div slot="footer" class="dialog-footer">
-            <el-button
-              type="primary"
-              @click="projectApprovalDetailVisible = false"
-              >{{ "关闭" }}</el-button
-            >
+            <el-button type="primary" @click="projectApprovalDetailVisible = false">{{ "关闭" }}</el-button>
           </div>
         </el-dialog>
         <el-dialog
@@ -2900,23 +2784,94 @@ export default {
 .on {
   @include font_color("color");
 }
-.gray_label {
-  color: #999 !important;
-  min-height: 20px;
+
+/* 查看详情弹窗布局优化 */
+.detail-container {
+  max-height: 65vh;
+  overflow-y: auto;
+  padding: 0 5px;
+}
+
+.detail-grid {
+  display: grid;
+  grid-template-columns: 1fr 2fr;
+  gap: 10px 16px;
+}
+
+.detail-cell {
+  display: flex;
+  align-items: flex-start;
   line-height: 1.8;
 }
 
-.detail-row {
-  margin-bottom: 10px;
+.detail-fullwidth {
+  margin-top: 12px;
 }
 
-.detail-item {
-  padding: 8px 0;
-  line-height: 2;
+.detail-cell-full {
+  display: flex;
+  align-items: flex-start;
+  line-height: 1.8;
+  margin-bottom: 8px;
 }
 
-.section-title {
+.detail-label {
+  color: #999;
+  font-size: 14px;
+  white-space: nowrap;
+  flex-shrink: 0;
+  min-width: 95px;
+  padding-right: 8px;
+}
+
+.detail-value {
+  color: #333;
+  font-size: 14px;
+  word-break: break-all;
+  flex: 1;
+}
+
+.detail-section {
+  margin-top: 15px;
+  margin-bottom: 15px;
+}
+
+.detail-section-title {
   font-weight: 600;
+  color: #333;
   margin-bottom: 8px;
+  padding-bottom: 4px;
+}
+
+.detail-section-row {
+  display: flex;
+  align-items: center;
+  margin-bottom: 6px;
+  line-height: 1.8;
+}
+
+.detail-section-grid {
+  display: grid;
+  grid-template-columns: 1fr 1fr;
+  gap: 6px 16px;
+}
+
+.detail-section-grid-item {
+  display: flex;
+  align-items: center;
+  line-height: 1.8;
+}
+
+.detail-label-inline {
+  color: #999;
+  font-size: 14px;
+  display: inline-block;
+  width: 100px;
+  flex-shrink: 0;
+}
+
+.detail-value-inline {
+  color: #333;
+  font-size: 14px;
 }
-</style>
+</style>

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

@@ -8573,7 +8573,7 @@
                             overcorp += zhi[n].zhoDataTime + ','
                         }
                     }
-                    if(this.user.companyId != 5978 && this.user.companyId != 7536 && overcorp != ''){
+                    if(this.user.companyId != 5978 && this.user.companyId != 7536 && this.user.companyId != 3511 && overcorp != ''){
                         overcorp = overcorp.substring(0,overcorp.length - 1)
                         this.$message({
                             message: this.$t('weekDay.date')+'[' + overcorp + ']'+this.$t('message.cannotexceedtotal'),
@@ -8701,10 +8701,8 @@
                                     var pName = pItem.projectName;
                                     var j = pName;
                                     var pid = pItem.id;
-                                    console.log('j==周报中的项目='+j);
                                     if(zhoD[j].time && zhoD[j].time != 'null') {
                                         flgs = true
-                                        // formData.append("degreeId", "-1");
                                         formData.append("id", zhoD[j].id==null?'-1':zhoD[j].id);
                                         if (this.isSubstitude) {
                                             formData.append('targetUids',this.workForm.userId[0]);
@@ -9500,8 +9498,8 @@
                                 }
                             }
                         }
-                        //针对凡己和景昱,苏州博海,泓浒(暂时) 此处不校验考勤时长
-                        if (this.user.companyId != 3918 && this.user.companyId != 5978 && this.user.companyId != 4281 && this.user.companyId != 7536 && this.reportTimeType.type == 1 && this.workForm.time) {
+                        //针对凡己和景昱,苏州博海,泓浒(暂时),安及义实业 此处不校验考勤时长
+                        if (this.user.companyId != 3918 && this.user.companyId != 5978 && this.user.companyId != 4281 && this.user.companyId != 7536 && this.user.companyId != 3511 && this.reportTimeType.type == 1 && this.workForm.time) {
                             if (this.workForm.time.workHours && totalTime > parseFloat(this.workForm.time.workHours)) {
                                 this.$message({
                                         message: this.$t('message.Fillinthesumofworkinghours')+(totalTime)+"h"+this.$t('message.Cannotexceedthetotalworkinghoursofattendance')+"("+this.workForm.time.workHours.toFixed(1)+"h)",

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

@@ -3067,7 +3067,7 @@ export default {
                 }
             }
             //针对凡己,不校验考勤时长
-            if (!this.substitute && this.user.companyId != 3918 && this.user.companyId != 5978 && this.user.companyId != 4281 && this.user.companyId != 7536 && this.reportTimeType.type == 1 && this.report.time) {
+            if (!this.substitute && this.user.companyId != 3918 && this.user.companyId != 5978 && this.user.companyId != 4281 && this.user.companyId != 7536 && this.user.companyId != 3511 && this.reportTimeType.type == 1 && this.report.time) {
                 var totalTime = 0;
                 for (var t = 0; t < this.form.domains.length; t++) {
                     totalTime += parseFloat(this.form.domains[t].workingTime);

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

@@ -2439,7 +2439,7 @@
                     }
                 }
                 //针对凡己,不校验考勤时长
-                if(this.user.companyId != 3918 && this.user.companyId != 5978 && this.user.companyId != 4281 && this.user.companyId != 7536 && (this.user.timeType.showDdCardtime == 1 || this.user.timeType.showCorpwxCardtime == 1) && this.reportTimeType.type == 1){
+                if(this.user.companyId != 3918 && this.user.companyId != 5978 && this.user.companyId != 4281 && this.user.companyId != 7536 && this.user.companyId != 3511 && (this.user.timeType.showDdCardtime == 1 || this.user.timeType.showCorpwxCardtime == 1) && this.reportTimeType.type == 1){
                     let tips = ''
                     for(let m in this.form){
                         let allhours = 0