浏览代码

fix:
工时统计double计算精度丢失

caozixuan 1 年之前
父节点
当前提交
35cf9e5e13

+ 6 - 1
sop-business/src/main/java/com/qmth/sop/business/service/impl/TBDingSubmitServiceImpl.java

@@ -22,6 +22,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -90,7 +91,11 @@ public class TBDingSubmitServiceImpl extends ServiceImpl<TBDingSubmitMapper, TBD
         Integer willSubmitCount = Math.toIntExact(dingSubmitResultList.stream().filter(e -> e.getSubmitStatus().getSubmitDesc().equals("待提交")).count());
         Integer submitCount = Math.toIntExact(dingSubmitResultList.stream().filter(e -> e.getSubmitStatus().getSubmitDesc().equals("已提交")).count());
         Integer totalActualDays = dingSubmitResultList.stream().mapToInt(DingSubmitResult::getActualDays).sum();
-        Double totalWorkHours = dingSubmitResultList.stream().mapToDouble(DingSubmitResult::getWorkHours).sum();
+        Double totalWorkHours = dingSubmitResultList.stream()
+                .map(e -> new BigDecimal(String.valueOf(e.getWorkHours())))
+                .reduce(BigDecimal::add)
+                .orElse(BigDecimal.ZERO)
+                .doubleValue();
         DingSubmitSubTotalResult dingSubmitSubTotalResult = new DingSubmitSubTotalResult();
         dingSubmitSubTotalResult.setDingCount(dingCount);
         dingSubmitSubTotalResult.setWillSubmitCount(willSubmitCount);

+ 63 - 0
sop-business/src/main/java/com/qmth/sop/business/sync/CommonUtils.java

@@ -0,0 +1,63 @@
+package com.qmth.sop.business.sync;
+
+import com.qmth.sop.common.enums.ExceptionResultEnum;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.Objects;
+
+/**
+ * @Description: 同步共用方法
+ * @Author: CaoZixuan
+ * @Date: 2023-11-14
+ */
+@Component
+public class CommonUtils {
+
+    /**
+     * 校验参数值并返回(字符型)
+     *
+     * @param value        参数值
+     * @param defaultValue 默认值
+     * @param require      是否必填(true:是,false:否)
+     * @param name         参数名称
+     */
+    public String validParam(String value, String defaultValue, boolean require, String name) {
+        if (require && StringUtils.isAllBlank(value, defaultValue)) {
+            throw ExceptionResultEnum.ERROR.exception((StringUtils.isBlank(name) ? "" : name) + "值必填");
+        }
+        return StringUtils.isBlank(value) ? defaultValue : value;
+
+    }
+
+    /**
+     * 校验参数值并返回(Long型)
+     *
+     * @param value        参数值
+     * @param defaultValue 默认值
+     * @param require      是否必填(true:是,false:否)
+     * @param name         参数名称
+     */
+    public Long validParam(Long value, Long defaultValue, boolean require, String name) {
+        if (require && Objects.isNull(value) && Objects.isNull(defaultValue)) {
+            throw ExceptionResultEnum.ERROR.exception((StringUtils.isBlank(name) ? "" : name) + "值必填");
+        }
+        return Objects.isNull(value) ? defaultValue : value;
+    }
+
+    /**
+     * 校验参数值并返回 (布尔型)
+     *
+     * @param value        参数值
+     * @param defaultValue 默认值
+     * @param require      是否必填
+     * @param name         描述
+     */
+    public Boolean validParam(Boolean value, Boolean defaultValue, Boolean require, String name) {
+        if (require && value == null && defaultValue == null) {
+            throw ExceptionResultEnum.ERROR.exception((StringUtils.isBlank(name) ? "" : name) + "值必填");
+        }
+        return value == null ? defaultValue : value;
+    }
+}

+ 11 - 57
sop-business/src/main/java/com/qmth/sop/business/sync/FxxkApiUtils.java

@@ -12,7 +12,6 @@ import com.qmth.sop.common.enums.ExceptionResultEnum;
 import com.qmth.sop.common.enums.ProductTypeEnum;
 import com.qmth.sop.common.util.HttpUtil;
 import com.qmth.sop.common.util.JacksonUtil;
-import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Value;
@@ -30,6 +29,8 @@ import java.util.*;
 public class FxxkApiUtils {
     @Resource
     private SysConfigService sysConfigService;
+    @Resource
+    private CommonUtils commonUtils;
 
     private static final Logger log = LoggerFactory.getLogger(FxxkApiUtils.class);
 
@@ -60,9 +61,9 @@ public class FxxkApiUtils {
         String postUrl = sysConfigService.findByConfigKey(SystemConstant.FXXK_APP_AUTH_URL).getConfigValue();
         try {
             Map<String, Object> map = new HashMap<>();
-            map.put("appId", validParam(fxxkAppId, null, true, "纷享销客AppID"));
-            map.put("appSecret", validParam(fxxkAppSecrete, null, true, "纷享销客APPSecret"));
-            map.put("permanentCode", validParam(fxxkPermanentCode, null, true, "纷享销客永久授权码"));
+            map.put("appId", commonUtils.validParam(fxxkAppId, null, true, "纷享销客AppID"));
+            map.put("appSecret", commonUtils.validParam(fxxkAppSecrete, null, true, "纷享销客APPSecret"));
+            map.put("permanentCode", commonUtils.validParam(fxxkPermanentCode, null, true, "纷享销客永久授权码"));
             String requestJson = JacksonUtil.parseJson(map);
 
             String result = HttpUtil.postJson(postUrl, requestJson, null, null, false);
@@ -95,9 +96,9 @@ public class FxxkApiUtils {
             String corpId = fxxkAppAuthInfo.getCorpId();
 
             Map<String, Object> map = new HashMap<>();
-            map.put("corpAccessToken", validParam(corpAccessToken, null, true, "企业应用访问公司合法性凭证"));
-            map.put("corpId", validParam(corpId, null, true, "开放平台公司帐号"));
-            map.put("mobile", validParam(mobile, null, true, "员工手机号"));
+            map.put("corpAccessToken", commonUtils.validParam(corpAccessToken, null, true, "企业应用访问公司合法性凭证"));
+            map.put("corpId", commonUtils.validParam(corpId, null, true, "开放平台公司帐号"));
+            map.put("mobile", commonUtils.validParam(mobile, null, true, "员工手机号"));
             String requestJson = JacksonUtil.parseJson(map);
 
             String result = HttpUtil.postJson(postUrl, requestJson, null, null, false);
@@ -126,9 +127,9 @@ public class FxxkApiUtils {
             String corpId = fxxkAppAuthInfo.getCorpId();
 
             Map<String, Object> map = new HashMap<>();
-            map.put("corpAccessToken", validParam(corpAccessToken, null, true, "企业应用访问公司合法性凭证"));
-            map.put("corpId", validParam(corpId, null, true, "开放平台公司帐号"));
-            map.put("currentOpenUserId", validParam(fxxkCurrenOpenUserId, null, true, "当前操作人OpenUserID"));
+            map.put("corpAccessToken", commonUtils.validParam(corpAccessToken, null, true, "企业应用访问公司合法性凭证"));
+            map.put("corpId", commonUtils.validParam(corpId, null, true, "开放平台公司帐号"));
+            map.put("currentOpenUserId", commonUtils.validParam(fxxkCurrenOpenUserId, null, true, "当前操作人OpenUserID"));
 
             Map<String, Object> dataMap = new HashMap<>();
             dataMap.put("dataObjectApiName", fxxkApiNameCrm);
@@ -263,51 +264,4 @@ public class FxxkApiUtils {
             throw ExceptionResultEnum.ERROR.exception(e.getMessage());
         }
     }
-
-
-    /**
-     * 校验参数值并返回(字符型)
-     *
-     * @param value        参数值
-     * @param defaultValue 默认值
-     * @param require      是否必填(true:是,false:否)
-     * @param name         参数名称
-     */
-    private String validParam(String value, String defaultValue, boolean require, String name) {
-        if (require && StringUtils.isAllBlank(value, defaultValue)) {
-            throw ExceptionResultEnum.ERROR.exception((StringUtils.isBlank(name) ? "" : name) + "值必填");
-        }
-        return StringUtils.isBlank(value) ? defaultValue : value;
-
-    }
-
-    /**
-     * 校验参数值并返回(Long型)
-     *
-     * @param value        参数值
-     * @param defaultValue 默认值
-     * @param require      是否必填(true:是,false:否)
-     * @param name         参数名称
-     */
-    private Long validParam(Long value, Long defaultValue, boolean require, String name) {
-        if (require && Objects.isNull(value) && Objects.isNull(defaultValue)) {
-            throw ExceptionResultEnum.ERROR.exception((StringUtils.isBlank(name) ? "" : name) + "值必填");
-        }
-        return Objects.isNull(value) ? defaultValue : value;
-    }
-
-    /**
-     * 校验参数值并返回 (布尔型)
-     *
-     * @param value        参数值
-     * @param defaultValue 默认值
-     * @param require      是否必填
-     * @param name         描述
-     */
-    private Boolean validParam(Boolean value, Boolean defaultValue, Boolean require, String name) {
-        if (require && value == null && defaultValue == null) {
-            throw ExceptionResultEnum.ERROR.exception((StringUtils.isBlank(name) ? "" : name) + "值必填");
-        }
-        return value == null ? defaultValue : value;
-    }
 }

+ 93 - 2
sop-business/src/main/java/com/qmth/sop/business/sync/RtzfApiUtils.java

@@ -1,12 +1,25 @@
 package com.qmth.sop.business.sync;
 
+import com.alibaba.fastjson.JSONObject;
+import com.qmth.sop.business.entity.SysUser;
 import com.qmth.sop.business.service.SysConfigService;
 import com.qmth.sop.business.sync.been.rtzf.LoginTypeEnum;
+import com.qmth.sop.business.sync.been.rtzf.RtzfResult;
+import com.qmth.sop.business.sync.been.rtzf.RtzfToken;
+import com.qmth.sop.business.sync.been.rtzf.RtzfUserInfo;
+import com.qmth.sop.common.enums.ExceptionResultEnum;
+import com.qmth.sop.common.util.HttpUtil;
+import com.qmth.sop.common.util.JacksonUtil;
+import io.swagger.annotations.ApiModelProperty;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 
 /**
  * @Description: 软通智服开放接口工具类
@@ -17,10 +30,88 @@ import javax.annotation.Resource;
 public class RtzfApiUtils {
     @Resource
     private SysConfigService sysConfigService;
+    @Resource
+    private CommonUtils commonUtils;
 
     private static final Logger log = LoggerFactory.getLogger(RtzfApiUtils.class);
 
-    public String getRtzfToken(LoginTypeEnum loginType) {
-        return "";
+    @ApiModelProperty("用户登录 url")
+    final String loginUrl = "/tenant/login/password/or/code/login";
+
+    @ApiModelProperty("接口访问默认账号")
+    final String defaultAccount = "?";
+
+    @ApiModelProperty("接口访问默认密码")
+    final String defaultPassword = "";
+
+    @ApiModelProperty("租户id")
+    final String tenantId = "";
+
+    /**
+     * 获取软通token
+     *
+     * @param requestUser 当前请求用户
+     * @param loginType   登录方式
+     * @return token
+     */
+    public String getRtzfToken(SysUser requestUser, LoginTypeEnum loginType) {
+        try {
+            String account = null;
+            String password = null;
+            switch (loginType) {
+                case API_LOGIN:
+                    account = defaultAccount;
+                    password = defaultPassword;
+                    break;
+                case SSO_LOGIN:
+                    account = requestUser.getRealName();
+                    password = requestUser.getPassword();
+                    break;
+            }
+
+            Map<String, Object> map = new HashMap<>();
+            map.put("account", commonUtils.validParam(account, null, true, "账号"));
+            map.put("password", commonUtils.validParam(password, null, true, "密码"));
+            map.put("loginType", commonUtils.validParam(0L, 0L, true, "登录方式"));
+            String requestJson = JacksonUtil.parseJson(map);
+
+            String result = HttpUtil.postJson(loginUrl, requestJson, null, null, false);
+            RtzfResult rtzfResult = JSONObject.parseObject(result, RtzfResult.class);
+            if (Objects.isNull(rtzfResult) || !"0".equals(rtzfResult.getCode())) {
+                throw ExceptionResultEnum.ERROR.exception("用户登录获取token失败 : " + rtzfResult.getMsg());
+            }
+            RtzfToken rtzfToken = (RtzfToken) rtzfResult.getData();
+            if (Objects.isNull(rtzfToken) || rtzfToken.getToken() == null || rtzfToken.getToken().length() == 0) {
+                throw ExceptionResultEnum.ERROR.exception("用户登录获取token为空");
+            }
+            return rtzfToken.getToken();
+        } catch (Exception e) {
+            throw ExceptionResultEnum.ERROR.exception(e.getMessage());
+        }
+    }
+
+    /**
+     * 批量推送用户
+     *
+     * @param requestUser      请求用户
+     * @param rtzfUserInfoList 用户信息集合
+     */
+    public void pushUserBatch(SysUser requestUser, List<RtzfUserInfo> rtzfUserInfoList) {
+        try {
+            String token = this.getRtzfToken(requestUser, LoginTypeEnum.API_LOGIN);
+
+            Map<String, Object> map = new HashMap<>();
+            map.put("tenantId", commonUtils.validParam(tenantId, null, true, "租户 ID"));
+            map.put("userList", rtzfUserInfoList);
+            String requestJson = JacksonUtil.parseJson(map);
+
+            String result = HttpUtil.postJson(loginUrl, requestJson, token, null, false);
+            RtzfResult rtzfResult = JSONObject.parseObject(result, RtzfResult.class);
+            if (Objects.isNull(rtzfResult) || !"0".equals(rtzfResult.getCode())) {
+                throw ExceptionResultEnum.ERROR.exception("账号信息批量同步失败 : " + rtzfResult.getMsg());
+            }
+        } catch (Exception e) {
+            throw ExceptionResultEnum.ERROR.exception(e.getMessage());
+        }
     }
 }

+ 6 - 5
sop-business/src/main/java/com/qmth/sop/business/sync/been/rtzf/RtzfTokenResult.java → sop-business/src/main/java/com/qmth/sop/business/sync/been/rtzf/RtzfResult.java

@@ -9,12 +9,12 @@ import io.swagger.annotations.ApiModelProperty;
  * @Author: CaoZixuan
  * @Date: 2023-11-07
  */
-public class RtzfTokenResult {
+public class RtzfResult {
     @ApiModelProperty("返回码:成功:0,异常:非 0")
     private String code;
 
-    @ApiModelProperty("token信息")
-    private RtzfToken data;
+    @ApiModelProperty("数据")
+    private Object data;
 
     @ApiModelProperty("返回信息")
     private String msg;
@@ -23,6 +23,7 @@ public class RtzfTokenResult {
     @JsonSerialize(using = ToStringSerializer.class)
     private Long currentTime;
 
+
     public String getCode() {
         return code;
     }
@@ -31,11 +32,11 @@ public class RtzfTokenResult {
         this.code = code;
     }
 
-    public RtzfToken getData() {
+    public Object getData() {
         return data;
     }
 
-    public void setData(RtzfToken data) {
+    public void setData(Object data) {
         this.data = data;
     }
 

+ 171 - 0
sop-business/src/main/java/com/qmth/sop/business/sync/been/rtzf/RtzfUserInfo.java

@@ -0,0 +1,171 @@
+package com.qmth.sop.business.sync.been.rtzf;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.List;
+
+/**
+ * @Description: 软通智服用户信息
+ * @Author: CaoZixuan
+ * @Date: 2023-11-14
+ */
+public class RtzfUserInfo {
+    @ApiModelProperty("账号名称")
+    private String userName;
+
+    @ApiModelProperty("邮箱")
+    private String email;
+
+    @ApiModelProperty("公司名称")
+    private String companyName;
+
+    @ApiModelProperty("部门 ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long deptId;
+
+    @ApiModelProperty("电话号码")
+    private String phoneNo;
+
+    @ApiModelProperty("密码")
+    private String password;
+
+    @ApiModelProperty("确认密码")
+    private String verifyPassword;
+
+    @ApiModelProperty("性别")
+    private Integer sex;
+
+    @ApiModelProperty("工号")
+    private String workNo;
+
+    @ApiModelProperty("状态")
+    private Integer state;
+
+    @ApiModelProperty("工作状态")
+    private Integer workState;
+
+    @ApiModelProperty("角色 ID 集合")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private List<Long> roleIds;
+
+    @ApiModelProperty("岗位 ID 集合")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private List<Long> stationIds;
+
+    @ApiModelProperty("扩展信息")
+    private String ext;
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getCompanyName() {
+        return companyName;
+    }
+
+    public void setCompanyName(String companyName) {
+        this.companyName = companyName;
+    }
+
+    public Long getDeptId() {
+        return deptId;
+    }
+
+    public void setDeptId(Long deptId) {
+        this.deptId = deptId;
+    }
+
+    public String getPhoneNo() {
+        return phoneNo;
+    }
+
+    public void setPhoneNo(String phoneNo) {
+        this.phoneNo = phoneNo;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getVerifyPassword() {
+        return verifyPassword;
+    }
+
+    public void setVerifyPassword(String verifyPassword) {
+        this.verifyPassword = verifyPassword;
+    }
+
+    public Integer getSex() {
+        return sex;
+    }
+
+    public void setSex(Integer sex) {
+        this.sex = sex;
+    }
+
+    public String getWorkNo() {
+        return workNo;
+    }
+
+    public void setWorkNo(String workNo) {
+        this.workNo = workNo;
+    }
+
+    public Integer getState() {
+        return state;
+    }
+
+    public void setState(Integer state) {
+        this.state = state;
+    }
+
+    public Integer getWorkState() {
+        return workState;
+    }
+
+    public void setWorkState(Integer workState) {
+        this.workState = workState;
+    }
+
+    public List<Long> getRoleIds() {
+        return roleIds;
+    }
+
+    public void setRoleIds(List<Long> roleIds) {
+        this.roleIds = roleIds;
+    }
+
+    public List<Long> getStationIds() {
+        return stationIds;
+    }
+
+    public void setStationIds(List<Long> stationIds) {
+        this.stationIds = stationIds;
+    }
+
+    public String getExt() {
+        return ext;
+    }
+
+    public void setExt(String ext) {
+        this.ext = ext;
+    }
+}

+ 4 - 0
sop-business/src/main/resources/db/log/caozixuan_update_log.sql

@@ -363,3 +363,7 @@ ALTER TABLE `sys_custom` DROP COLUMN `manager_id`;
 -- 2023-11-10
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('2052', '出入库登记查询-查询登记人列表', '/api/admin/device/in/out/registrant_list', 'URL', '64', '33', 'SYS', '1', '1', '0');
 
+-- 2023-11-14
+ALTER TABLE t_b_ding_submit
+    CHANGE COLUMN approach_time approach_time BIGINT NULL COMMENT '进场时间' ,
+    CHANGE COLUMN departure_time departure_time BIGINT NULL COMMENT '出场时间' ;

+ 0 - 2
sop-common/src/main/java/com/qmth/sop/common/util/DateDisposeUtils.java

@@ -177,7 +177,6 @@ public class DateDisposeUtils extends DateUtils {
         tempStart.set(Calendar.MINUTE, 0);
         tempStart.set(Calendar.SECOND, 0);
         tempStart.set(Calendar.MILLISECOND, 0);
-        long x1 = tempStart.getTimeInMillis();
 
         Calendar tempEnd = Calendar.getInstance();
         tempEnd.setTime(end);
@@ -185,7 +184,6 @@ public class DateDisposeUtils extends DateUtils {
         tempEnd.set(Calendar.MINUTE, 0);
         tempEnd.set(Calendar.SECOND, 0);
         tempEnd.set(Calendar.MILLISECOND, 0);
-        long x2 = tempEnd.getTimeInMillis();
 
         while (tempStart.before(tempEnd) || tempStart.equals(tempEnd)) {
             days.add(dateFormat.format(tempStart.getTime()));