Compare commits
51
Commits
173eaa1b60
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
177e0e4d97 | ||
|
|
f74a2322e4 | ||
|
|
822cdbf539 | ||
|
|
d75f21c17e | ||
|
|
ffee8611fe | ||
|
|
0e8f5e7b14 | ||
|
|
115407026f | ||
|
|
9f545952e4 | ||
|
|
1988e031e5 | ||
|
|
44b0f6ca2b | ||
|
|
ae866f0791 | ||
|
|
4610ac4737 | ||
|
|
6d6920a2b3 | ||
|
|
c7041fa69e | ||
|
|
370f5e0089 | ||
|
|
a47f27967e | ||
|
|
6c08f5f141 | ||
|
|
690f688c6a | ||
|
|
63cc815022 | ||
|
|
8f00d07377 | ||
|
|
2e90ec71cc | ||
|
|
a43806c4e9 | ||
|
|
237df3ef38 | ||
|
|
bd9fece99c | ||
|
|
47cebd3392 | ||
|
|
61e049cc47 | ||
|
|
ad03177e50 | ||
|
|
3db3301fe3 | ||
|
|
fa9a186a5e | ||
|
|
3cea926a1e | ||
|
|
fe82afd934 | ||
|
|
96242b5c00 | ||
|
|
291f6a4eaa | ||
|
|
98dc17552d | ||
|
|
e9784f7957 | ||
|
|
175238e291 | ||
|
|
3c822d581c | ||
|
|
77d72d1d78 | ||
|
|
9dbdd911d9 | ||
|
|
0022497f64 | ||
|
|
9714e97a71 | ||
|
|
65f5755422 | ||
|
|
677b4d5080 | ||
|
|
49f316dd82 | ||
|
|
b6aecf4e64 | ||
|
|
cd7f5661de | ||
|
|
6e005f2f4e | ||
|
|
03f8be4c98 | ||
|
|
b2b96290bf | ||
|
|
80d1cebc0f | ||
|
|
e064e312da |
@@ -31,5 +31,5 @@ CREATE TABLE `sys_message_notice_scope` (
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_notice_id` (`notice_id`),
|
||||
KEY `idx_type` (`type`),
|
||||
KEY `idx_scope_id` (`scope_id`)
|
||||
KEY `idx_scope_notice` (`scope_id`, `notice_id`) COMMENT '联表查询复合索引,支持WHERE scope_id + JOIN notice_id'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='消息通知范围表';
|
||||
@@ -0,0 +1,10 @@
|
||||
-- QH_WAT_MONITOR_DATA 新增 EVENT_ID(事件ID)和 LOCATE_TIME(定位时间)字段
|
||||
-- 数据库:118-DM 达梦数据库,SQL 全大写规范
|
||||
ALTER TABLE "QH_WAT_MONITOR_DATA" ADD "EVENT_ID" VARCHAR(64) DEFAULT NULL;
|
||||
ALTER TABLE "QH_WAT_MONITOR_DATA" ADD "LOCATE_TIME" DATETIME DEFAULT NULL;
|
||||
|
||||
COMMENT ON COLUMN "QH_WAT_MONITOR_DATA"."EVENT_ID" IS '事件ID';
|
||||
COMMENT ON COLUMN "QH_WAT_MONITOR_DATA"."LOCATE_TIME" IS '定位时间';
|
||||
|
||||
CREATE INDEX "IDX_EVENT_ID" ON "QH_WAT_MONITOR_DATA"("EVENT_ID");
|
||||
CREATE INDEX "IDX_WATCH_NO_EVENT_ID" ON "QH_WAT_MONITOR_DATA"("WATCH_NO", "EVENT_ID");
|
||||
+1
-1
@@ -99,7 +99,7 @@ public enum AnYanApiEnum {
|
||||
/**
|
||||
* 18.查询关爱联络员信息及急救人员查询接口
|
||||
*/
|
||||
QUERY_EMPLOYEE_CARE_PERSON("/aygc-znhpt-sys/0/api/empCareEmp/findPageByIdNo", "", HttpMethod.POST),
|
||||
QUERY_EMPLOYEE_CARE_PERSON("/aygc-znhpt-sys/0/api/empCareEmp/findPage", "", HttpMethod.POST),
|
||||
|
||||
/**
|
||||
* 19.批量更新员工关键信息接口
|
||||
|
||||
+3
@@ -1,5 +1,6 @@
|
||||
package com.renkang.anyan.model.dto;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@@ -34,4 +35,6 @@ public class CareUserDetailsParam {
|
||||
|
||||
@Schema(title = "pageType")
|
||||
private String pageType = "plus";
|
||||
|
||||
private int year = DateUtil.thisYear();
|
||||
}
|
||||
|
||||
+1
-1
@@ -12,5 +12,5 @@ public interface HealthBankConstants {
|
||||
/**
|
||||
*积分变化-扣减积分
|
||||
*/
|
||||
Integer CHANGE_TYPE_DEDUCT_ = 2;
|
||||
Integer CHANGE_TYPE_DEDUCT = 2;
|
||||
}
|
||||
|
||||
+11
-1
@@ -9,7 +9,8 @@ import lombok.Getter;
|
||||
*/
|
||||
@Getter
|
||||
public enum PointsSourceEnum {
|
||||
TYPE_1_SURVEY(1, "积分打卡", "survey"),
|
||||
// 积分变更类型
|
||||
TYPE_1_SURVEY(1, "survey", "积分打卡"),
|
||||
TYPE_2_USE(2, "use", "礼品兑换"),
|
||||
TYPE_2_VIOLATION(2, "violation", "违规扣除"),
|
||||
TYPE_2_EXPIRED(2, "expired", "过期清除");
|
||||
@@ -31,4 +32,13 @@ public enum PointsSourceEnum {
|
||||
this.source = source;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public static PointsSourceEnum getBySource(String source) {
|
||||
for (PointsSourceEnum value : PointsSourceEnum.values()) {
|
||||
if (value.source.equals(source)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.renkang.bank.model.dto;
|
||||
|
||||
import com.renkang.bank.model.po.PointsRule;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.jeecg.base.PageInfo;
|
||||
|
||||
/**
|
||||
* @author pj
|
||||
* @version 1.0
|
||||
* @description: 积分规则分页dto
|
||||
* @date 2026/2/5 18:11
|
||||
*/
|
||||
@Data
|
||||
public class PointsRulePageDTO extends PageInfo<PointsRule> {
|
||||
|
||||
@Schema(title = "健康分类")
|
||||
private Integer ruleCategory;
|
||||
|
||||
@Schema(title = "健康行为")
|
||||
private String ruleDesc;
|
||||
|
||||
@Schema(title = "状态1-启用,2停用")
|
||||
private Integer status;
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.renkang.bank.model.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author pj
|
||||
* @version 1.0
|
||||
* @description: 更新用户积分DTO
|
||||
* @date 2026/2/6 9:00
|
||||
*/
|
||||
@Data
|
||||
public class UpdUserPointsDTO {
|
||||
|
||||
/**
|
||||
* 积分标识(积分打卡:survey,礼品兑换:use,违规扣除:violation,过期清除:expired)
|
||||
*/
|
||||
private String sourceType;
|
||||
|
||||
/**
|
||||
* 业务ID(积分任务id,兑换商品id等)
|
||||
*/
|
||||
private Long businessId;
|
||||
|
||||
/**
|
||||
* 操作积分(扣减)
|
||||
*/
|
||||
private BigDecimal points;
|
||||
|
||||
/**
|
||||
* 操作备注(扣减积分的说明等)
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 用户id(扣减的目标用户id)
|
||||
*/
|
||||
private String userId;
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.renkang.bank.model.dto;
|
||||
|
||||
import com.renkang.bank.model.po.PointsRule;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.jeecg.base.PageInfo;
|
||||
|
||||
/**
|
||||
* @author pj
|
||||
* @version 1.0
|
||||
* @description: 积分规则分页dto
|
||||
* @date 2026/2/5 18:11
|
||||
*/
|
||||
@Data
|
||||
public class UserPointsPageDTO extends PageInfo<PointsRule> {
|
||||
|
||||
@Schema(title = "姓名")
|
||||
private String realName;
|
||||
|
||||
@Schema(title = "员工编号")
|
||||
private String workNo;
|
||||
|
||||
@Schema(title = "所属单位")
|
||||
private String orgCode;
|
||||
|
||||
@Schema(title = "所属部门")
|
||||
private String deptCode;
|
||||
|
||||
@Schema(title = "1收入,2支出")
|
||||
private Integer changeType;
|
||||
|
||||
@Schema(title = "健康行为")
|
||||
private String ruleDesc;
|
||||
|
||||
@Schema(title = "打卡日期(开始)")
|
||||
private String startDate;
|
||||
|
||||
@Schema(title = "打卡日期(结束)")
|
||||
private String endDate;
|
||||
|
||||
private String userId;
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.renkang.bank.model.dto;
|
||||
|
||||
import com.renkang.bank.model.po.PointsRule;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.jeecg.base.PageInfo;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author pj
|
||||
* @version 1.0
|
||||
* @description: 积分规则分页dto
|
||||
* @date 2026/2/5 18:11
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class UserPointsRankingDTO extends PageInfo<PointsRule> {
|
||||
|
||||
@Schema(title = "榜单类型,0日榜,1周榜,2月榜,3季榜,4年榜,5选时排名,10总榜")
|
||||
private String rankType;
|
||||
|
||||
@Schema(title = "开始时间")
|
||||
private Date startTime;
|
||||
|
||||
@Schema(title = "截止时间")
|
||||
private Date endTime;
|
||||
|
||||
@Schema(title = "所属单位")
|
||||
private String orgCode;
|
||||
|
||||
@Schema(title = "所属部门")
|
||||
private String deptCode;
|
||||
|
||||
@Schema(title = "姓名")
|
||||
private String realName;
|
||||
|
||||
@Schema(title = "员工编号")
|
||||
private String workNo;
|
||||
|
||||
private List<String> userIds;
|
||||
|
||||
}
|
||||
+21
-2
@@ -11,6 +11,8 @@ import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
@@ -39,23 +41,28 @@ public class PointsRule implements Serializable {
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING)
|
||||
private Long id;
|
||||
|
||||
@Excel(name = "行为周期", width = 15, replace = {"次_1", "日_2", "周_3", "月_4", "季度_5", "年_6"}, orderNum = "3")
|
||||
@Schema(title = "问答频次(1-单次,2-日/次,3-周/次,4-月/次,5-季度/次,6-年/次)")
|
||||
private Integer frequency;
|
||||
|
||||
@Excel(name = "健康分类", width = 15, dicCode = "points_rule_category", orderNum = "1")
|
||||
@Dict(dicCode = "points_rule_category")
|
||||
@Schema(title = "规则类别")
|
||||
private Integer ruleCategory;
|
||||
|
||||
@Excel(name = "健康行为", width = 15, orderNum = "2")
|
||||
@Schema(title = "规则描述")
|
||||
private String ruleDesc;
|
||||
|
||||
@Schema(title = "图标")
|
||||
private String icon;
|
||||
|
||||
@Excel(name = "奖励积分", width = 15, orderNum = "4")
|
||||
@Schema(title = "奖励积分")
|
||||
private BigDecimal points;
|
||||
|
||||
@Schema(title = "状态0-启用,1停用")
|
||||
private Integer status = 0;
|
||||
@Schema(title = "状态1-启用,2停用")
|
||||
private Integer status = 1;
|
||||
|
||||
@Schema(title = "删除标识0-正常,1已删除")
|
||||
@TableLogic
|
||||
@@ -74,4 +81,16 @@ public class PointsRule implements Serializable {
|
||||
@Schema(title = "最后修改时间")
|
||||
private Date lastModifyDate;
|
||||
|
||||
@Schema(title = "周期内打卡次数上限")
|
||||
private Integer checkInUpper;
|
||||
|
||||
@Schema(title = "年额外积分上限")
|
||||
private BigDecimal yearExtraPointUpper;
|
||||
|
||||
@Schema(title = "是否支持打卡叠加得分,0不支持,1支持")
|
||||
private Integer supportCum;
|
||||
|
||||
@Schema(title = "是否需要填写补充信息,0不需要,1需要")
|
||||
private Integer needRemark;
|
||||
|
||||
}
|
||||
|
||||
+19
-4
@@ -9,11 +9,13 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用户积分汇总表 -产生过积分的用户每人一条数据
|
||||
*
|
||||
@@ -39,17 +41,29 @@ public class UserPoints implements Serializable {
|
||||
@Schema(title = "用户部门")
|
||||
private String orgCode;
|
||||
|
||||
@Excel(name = "当前可用积分", width = 15, orderNum = "7")
|
||||
@Schema(title = "当前可用积分")
|
||||
private BigDecimal points;
|
||||
|
||||
@Excel(name = "累计获得积分", width = 15, orderNum = "8")
|
||||
@Schema(title = "历史获得的积分总和")
|
||||
private BigDecimal addPointsSum;
|
||||
|
||||
/**
|
||||
* 记录所有扣除积分的总和,包含兑换消耗、手动扣除的积分
|
||||
*/
|
||||
@Schema(title = "历史扣除积分总和")
|
||||
private BigDecimal deductPointsSum;
|
||||
|
||||
@Schema(title = "状态(0-正常,1-冻结)")
|
||||
private Integer status = 0;
|
||||
/**
|
||||
* 积分兑换记录总和,只记录积分兑换
|
||||
*/
|
||||
@Excel(name = "累计兑换积分", width = 15, orderNum = "9")
|
||||
@Schema(title = "历史兑换积分总和")
|
||||
private BigDecimal exchangePointsSum;
|
||||
|
||||
@Schema(title = "状态(1-正常,2-冻结)")
|
||||
private Integer status = 1;
|
||||
/**
|
||||
* 注意:该字段记录最后一次获得积分当天收获的积分总和,该归档字段的更新会减少后期对积分明细表的查询次数
|
||||
*/
|
||||
@@ -61,8 +75,9 @@ public class UserPoints implements Serializable {
|
||||
@Schema(title = "最新一天消耗积分的总和")
|
||||
private BigDecimal latestDeductDaySum;
|
||||
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
@Excel(name = "最近一次打卡时间", width = 25, format = "yyyy-MM-dd HH:mm:ss", orderNum = "10")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
@Schema(title = "最新获得积分的日期")
|
||||
private Date lastAddDate;
|
||||
|
||||
|
||||
+2
-2
@@ -25,7 +25,7 @@ import java.util.Date;
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@TableName("bank_user_points")
|
||||
@TableName("bank_user_points_details")
|
||||
@Schema(title = "用户积分详情表", description = "用户积分详情表")
|
||||
public class UserPointsDetails implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
@@ -56,7 +56,7 @@ public class UserPointsDetails implements Serializable {
|
||||
/**
|
||||
* @see PointsSourceEnum 来源详见枚举类
|
||||
*/
|
||||
@Schema(title = "来源(survey-问卷积分,use-礼品兑换,violation-违规扣除,expired-过期清除)")
|
||||
@Schema(title = "来源(survey-积分打卡,use-礼品兑换,violation-违规扣除,expired-过期清除)")
|
||||
private String source;
|
||||
|
||||
@Schema(title = "关联业务ID(规则ID,礼品兑换订单Id等)")
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.renkang.bank.model.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author pj
|
||||
* @version 1.0
|
||||
* @description: 用户积分榜单VO
|
||||
* @date 2026/2/6 10:41
|
||||
*/
|
||||
@Data
|
||||
public class UserPointRankingVO {
|
||||
|
||||
@Excel(name = "排名", width = 15, orderNum = "8")
|
||||
@Schema(title = "排名")
|
||||
private Integer ranking;
|
||||
|
||||
@Schema(title = "用户id")
|
||||
private String userId;
|
||||
|
||||
@Excel(name = "姓名", width = 15, orderNum = "3")
|
||||
@Schema(title = "姓名")
|
||||
private String realName;
|
||||
|
||||
@Excel(name = "员工编号", width = 15, orderNum = "4")
|
||||
@Schema(title = "员工编号")
|
||||
private String workNo;
|
||||
|
||||
@Excel(name = "年龄", width = 15, orderNum = "6")
|
||||
@Schema(title = "年龄")
|
||||
private Integer age;
|
||||
|
||||
@Schema(title = "头像")
|
||||
private String avatar;
|
||||
|
||||
@Excel(name = "所属单位", width = 15, orderNum = "1")
|
||||
@Schema(title = "单位名称")
|
||||
private String orgName;
|
||||
|
||||
@Excel(name = "所属部门", width = 15, orderNum = "2")
|
||||
@Schema(title = "部门名称")
|
||||
private String deptName;
|
||||
|
||||
@Schema(title = "性别")
|
||||
private Integer sex;
|
||||
|
||||
@Excel(name = "性别", width = 15, orderNum = "5")
|
||||
@Schema(title = "性别")
|
||||
private String sexName;
|
||||
|
||||
@Excel(name = "日累计积分", width = 15, orderNum = "7")
|
||||
@Schema(title = "积分")
|
||||
private BigDecimal pointSum;
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.renkang.bank.model.vo;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author pj
|
||||
* @version 1.0
|
||||
* @description: 用户积分明细VO
|
||||
* @date 2026/2/6 10:41
|
||||
*/
|
||||
@Data
|
||||
public class UserPointRecordVO {
|
||||
|
||||
@Schema(title = "记录id")
|
||||
private Long id;
|
||||
|
||||
@Schema(title = "得分说明")
|
||||
private String businessInfo;
|
||||
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
@Schema(title = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
@Schema(title = "本次积分变化")
|
||||
private BigDecimal points;
|
||||
|
||||
@Schema(title = "补充信息")
|
||||
private String remark;
|
||||
|
||||
public String getCreateMonthStr() {
|
||||
if (createTime != null) {
|
||||
return DateUtil.format(createTime, "yyyy年-MM月");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package com.renkang.bank.model.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用户积分详情VO
|
||||
*
|
||||
* @author feng
|
||||
* @date 2026-02-05
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(title = "用户积分详情VO", description = "用户积分详情VO")
|
||||
public class UserPointsDeductDetailsVO {
|
||||
|
||||
@Schema(title = "id")
|
||||
private Long id;
|
||||
|
||||
@Schema(title = "用户ID")
|
||||
private String userId;
|
||||
|
||||
@Excel(name = "积分变化", width = 15, orderNum = "2")
|
||||
@Schema(title = "本次积分变化")
|
||||
private BigDecimal points;
|
||||
|
||||
@Excel(name = "支出信息", width = 25, orderNum = "1")
|
||||
@Schema(title = "补充信息")
|
||||
private String remark;
|
||||
|
||||
@Schema(title = "关联业务ID(规则ID,礼品兑换订单Id等)")
|
||||
private Long businessId;
|
||||
|
||||
@Excel(name = "支出时间", width = 25, format = "yyyy-MM-dd HH:mm:ss", orderNum = "3")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
@Schema(title = "创建时间")
|
||||
private Date createTime;
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package com.renkang.bank.model.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用户积分详情VO
|
||||
*
|
||||
* @author feng
|
||||
* @date 2026-02-05
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(title = "用户积分详情VO", description = "用户积分详情VO")
|
||||
public class UserPointsDetailsVO {
|
||||
|
||||
@Schema(title = "id")
|
||||
private Long id;
|
||||
|
||||
@Schema(title = "用户ID")
|
||||
private String userId;
|
||||
|
||||
@Excel(name = "积分变化", width = 15, orderNum = "4")
|
||||
@Schema(title = "本次积分变化")
|
||||
private BigDecimal points;
|
||||
|
||||
@Excel(name = "补充信息", width = 15, orderNum = "2")
|
||||
@Schema(title = "补充信息")
|
||||
private String remark;
|
||||
|
||||
@Schema(title = "关联业务ID(规则ID,礼品兑换订单Id等)")
|
||||
private Long businessId;
|
||||
|
||||
@Excel(name = "健康行为", width = 25, orderNum = "1")
|
||||
@Schema(title = "关联业务详情(可选择性的冗余业务详情:待定)")
|
||||
private String businessInfo;
|
||||
|
||||
@Excel(name = "打卡时间", width = 25, format = "yyyy-MM-dd HH:mm:ss", orderNum = "5")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
@Schema(title = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
@Excel(name = "行为周期", width = 15, replace = {"次_1", "日_2", "周_3", "月_4", "季度_5", "年_6"}, orderNum = "3")
|
||||
@Schema(title = "问答频次(1-单次,2-日/次,3-周/次,4-月/次,5-季度/次,6-年/次)")
|
||||
private Integer frequency;
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.renkang.bank.model.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonSetter;
|
||||
import com.fasterxml.jackson.annotation.Nulls;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author pj
|
||||
* @version 1.0
|
||||
* @description: 用户积分信息vo
|
||||
* @date 2026/2/6 9:31
|
||||
*/
|
||||
@Data
|
||||
public class UserPointsInfoVO {
|
||||
|
||||
@Schema(title = "可用积分")
|
||||
@JsonSetter(nulls = Nulls.SKIP)
|
||||
private BigDecimal points = BigDecimal.ZERO;
|
||||
|
||||
@Schema(title = "累计积分")
|
||||
@JsonSetter(nulls = Nulls.SKIP)
|
||||
private BigDecimal addPointsSum = BigDecimal.ZERO;
|
||||
|
||||
@Schema(title = "累计兑换")
|
||||
@JsonSetter(nulls = Nulls.SKIP)
|
||||
private BigDecimal exchangePointsSum = BigDecimal.ZERO;
|
||||
|
||||
public BigDecimal getPoints() {
|
||||
return points == null ? BigDecimal.ZERO : points;
|
||||
}
|
||||
|
||||
public BigDecimal getAddPointsSum() {
|
||||
return addPointsSum == null ? BigDecimal.ZERO : addPointsSum;
|
||||
}
|
||||
|
||||
public BigDecimal getExchangePointsSum() {
|
||||
return exchangePointsSum == null ? BigDecimal.ZERO : exchangePointsSum;
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.renkang.bank.model.vo;
|
||||
|
||||
import com.renkang.bank.model.po.UserPoints;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
|
||||
/**
|
||||
* @author pj
|
||||
* @version 1.0
|
||||
* @description: 用户积分信息列表VO
|
||||
* @date 2026/2/5 18:51
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class UserPointsListVO extends UserPoints {
|
||||
|
||||
@Excel(name = "姓名", width = 15, orderNum = "3")
|
||||
@Schema(title = "姓名")
|
||||
private String realName;
|
||||
|
||||
@Excel(name = "员工编号", width = 15, orderNum = "4")
|
||||
@Schema(title = "员工编号")
|
||||
private String workNo;
|
||||
|
||||
@Excel(name = "所属单位", width = 15, orderNum = "1")
|
||||
@Schema(title = "所属单位名称")
|
||||
private String orgName;
|
||||
|
||||
@Excel(name = "所属部门", width = 15, orderNum = "2")
|
||||
@Schema(title = "所属部门名称")
|
||||
private String deptName;
|
||||
|
||||
@Excel(name = "性别", width = 15, orderNum = "5")
|
||||
@Schema(title = "性别")
|
||||
private String sexName;
|
||||
|
||||
@Excel(name = "年龄", width = 15, orderNum = "6")
|
||||
@Schema(title = "年龄")
|
||||
private Integer age;
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package com.renkang.bank.model.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author pj
|
||||
* @version 1.0
|
||||
* @description: 员工打卡监测VO
|
||||
* @date 2026/2/5 18:51
|
||||
*/
|
||||
@Data
|
||||
public class UserPointsMonitorVO {
|
||||
|
||||
@Schema(title = "用户id")
|
||||
private String userId;
|
||||
|
||||
@Schema(title = "姓名")
|
||||
private String realName;
|
||||
|
||||
@Schema(title = "员工编号")
|
||||
private String workNo;
|
||||
|
||||
@Schema(title = "所属单位名称")
|
||||
private String orgName;
|
||||
|
||||
@Schema(title = "所属部门名称")
|
||||
private String deptName;
|
||||
|
||||
@Schema(title = "性别")
|
||||
private String sexName;
|
||||
|
||||
@Schema(title = "年龄")
|
||||
private Integer age;
|
||||
|
||||
@Schema(title = "健康行为")
|
||||
private String businessInfo;
|
||||
|
||||
@Schema(title = "补充信息")
|
||||
private String remark;
|
||||
|
||||
@Schema(title = "周期")
|
||||
private Integer frequency;
|
||||
|
||||
@Schema(title = "获取积分")
|
||||
private BigDecimal points;
|
||||
|
||||
@Schema(title = "打卡时间")
|
||||
private Date createTime;
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.renkang.bank.model.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author pj
|
||||
* @version 1.0
|
||||
* @description: 用户积分任务VO
|
||||
* @date 2026/2/6 9:54
|
||||
*/
|
||||
@Data
|
||||
public class UserPointsTaskVO {
|
||||
|
||||
@Schema(title = "规则id")
|
||||
private Long ruleId;
|
||||
|
||||
@Schema(title = "问答频次(1-单次,2-日/次,3-周/次,4-月/次,5-季度/次,6-年/次)")
|
||||
private Integer frequency;
|
||||
|
||||
@Dict(dicCode = "points_rule_category")
|
||||
@Schema(title = "规则类别")
|
||||
private Integer ruleCategory;
|
||||
|
||||
@Schema(title = "规则描述")
|
||||
private String ruleDesc;
|
||||
|
||||
@Schema(title = "图标")
|
||||
private String icon;
|
||||
|
||||
@Schema(title = "奖励积分")
|
||||
private BigDecimal points;
|
||||
|
||||
@Schema(title = "打卡状态,0未打卡,1已打卡")
|
||||
private Integer clockInStatus;
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package com.renkang.bank.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.renkang.bank.model.dto.PointsRulePageDTO;
|
||||
import com.renkang.bank.model.po.PointsRule;
|
||||
import com.renkang.bank.service.IPointsRuleService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @author pj
|
||||
* @version 1.0
|
||||
* @description: 积分规则
|
||||
* @date 2026/2/5 17:53
|
||||
*/
|
||||
@Tag(name = "积分规则")
|
||||
@RestController
|
||||
@RequestMapping("/bank/pointsRule")
|
||||
public class PointsRuleController extends JeecgController<PointsRule, IPointsRuleService> {
|
||||
|
||||
@Autowired
|
||||
private IPointsRuleService iPointsRuleService;
|
||||
|
||||
@Operation(summary = "积分规则-分页列表", description = "积分规则-分页列表")
|
||||
// @RequiresPermissions("bank:points_rule:add")
|
||||
@PostMapping(value = "/pageList")
|
||||
public Result<IPage<PointsRule>> pageList(@RequestBody PointsRulePageDTO dto) {
|
||||
return Result.OK(iPointsRuleService.pageList(dto));
|
||||
}
|
||||
|
||||
@Operation(summary = "积分规则-添加", description = "积分规则-添加")
|
||||
// @RequiresPermissions("bank:points_rule:add")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<Integer> add(@RequestBody PointsRule pointsRule) {
|
||||
return Result.OK("添加成功", iPointsRuleService.add(pointsRule));
|
||||
}
|
||||
|
||||
@Operation(summary = "积分规则-修改", description = "积分规则-修改")
|
||||
// @RequiresPermissions("bank:points_rule:edit")
|
||||
@PostMapping(value = "/edit")
|
||||
public Result<Integer> edit(@RequestBody PointsRule pointsRule) {
|
||||
return Result.OK("修改成功", iPointsRuleService.edit(pointsRule));
|
||||
}
|
||||
|
||||
@Operation(summary = "积分规则-修改状态", description = "积分规则-修改状态")
|
||||
// @RequiresPermissions("bank:points_rule:edit")
|
||||
@GetMapping(value = "/editStatus")
|
||||
public Result<Integer> editStatus(@RequestParam(name = "id") Long id, @RequestParam(name = "status") Integer status) {
|
||||
return Result.OK("修改成功", iPointsRuleService.editStatus(id, status));
|
||||
}
|
||||
|
||||
@Operation(summary = "积分规则-详情", description = "积分规则-详情")
|
||||
// @RequiresPermissions("bank:points_rule:byId")
|
||||
@GetMapping(value = "/byId")
|
||||
public Result<PointsRule> byId(@RequestParam(name = "id") String id) {
|
||||
return Result.OK(iPointsRuleService.byId(id));
|
||||
}
|
||||
|
||||
@Operation(summary = "积分规则-删除", description = "积分规则-删除")
|
||||
// @RequiresPermissions("bank:points_rule:del")
|
||||
@GetMapping(value = "/delete")
|
||||
public Result<Integer> delete(@RequestParam(name = "id") String id) {
|
||||
return Result.OK("删除成功", iPointsRuleService.delete(id));
|
||||
}
|
||||
|
||||
@Operation(summary = "积分规则-批量删除", description = "积分规则-批量删除")
|
||||
// @RequiresPermissions("bank:points_rule:del")
|
||||
@GetMapping(value = "/deleteBatch")
|
||||
public Result<Integer> deleteBatch(@RequestParam(name = "ids") String ids) {
|
||||
if (StringUtils.isBlank(ids)) {
|
||||
return Result.error("请选择需要删除的积分规则");
|
||||
}
|
||||
return Result.OK("删除成功", iPointsRuleService.deleteBatch(ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param conHealthInfo
|
||||
*/
|
||||
@Operation(summary = "积分规则-导出", description = "积分规则-导出")
|
||||
// @RequiresPermissions("bank:points_rule:exportXls")
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, PointsRule conHealthInfo) {
|
||||
return super.exportXls(request, conHealthInfo, PointsRule.class, "积分规则");
|
||||
}
|
||||
|
||||
}
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
package com.renkang.bank.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.renkang.bank.model.dto.UpdUserPointsDTO;
|
||||
import com.renkang.bank.model.dto.UserPointsPageDTO;
|
||||
import com.renkang.bank.model.dto.UserPointsRankingDTO;
|
||||
import com.renkang.bank.model.vo.*;
|
||||
import com.renkang.bank.service.IUserPointsService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author pj
|
||||
* @version 1.0
|
||||
* @description: 用户积分汇总表
|
||||
* @date 2026/2/5 16:42
|
||||
*/
|
||||
@Tag(name = "用户积分信息")
|
||||
@RestController
|
||||
@RequestMapping("/bank/userPoints")
|
||||
public class UserPointsController {
|
||||
|
||||
@Autowired
|
||||
private IUserPointsService iUserPointsService;
|
||||
|
||||
@Operation(summary = "测试积分变更", description = "测试积分变更")
|
||||
@PostMapping(value = "/testUpdateUserPoints")
|
||||
public Result<Boolean> testUpdateUserPoints(@RequestBody UpdUserPointsDTO dto) {
|
||||
return Result.OK(iUserPointsService.testUpdateUserPoints(dto));
|
||||
}
|
||||
|
||||
@Operation(summary = "用户积分信息-分页列表", description = "用户积分信息-分页列表")
|
||||
@PostMapping(value = "/pageList")
|
||||
public Result<IPage<UserPointsListVO>> pageList(@RequestBody UserPointsPageDTO dto) {
|
||||
return Result.OK(iUserPointsService.pageList(dto));
|
||||
}
|
||||
|
||||
@Operation(summary = "用户积分信息-分页列表(导出)", description = "用户积分信息-分页列表(导出)")
|
||||
@PostMapping(value = "/exportUserPoints")
|
||||
public Result<String> exportUserPoints(@RequestBody UserPointsPageDTO dto) {
|
||||
iUserPointsService.exportUserPoints(dto);
|
||||
return Result.OK("导出成功,请在导出记录查看");
|
||||
}
|
||||
|
||||
@Operation(summary = "用户积分信息-积分明细", description = "用户积分信息-积分明细")
|
||||
@PostMapping(value = "/detailPageList")
|
||||
public Result<IPage<UserPointsDetailsVO>> detailPageList(@RequestBody UserPointsPageDTO dto) {
|
||||
return Result.OK(iUserPointsService.detailPageList(dto));
|
||||
}
|
||||
|
||||
@Operation(summary = "用户积分信息-积分明细(导出)", description = "用户积分信息-积分明细(导出)")
|
||||
@PostMapping(value = "/exportPointsDetail")
|
||||
public Result<String> exportPointsDetail(@RequestBody UserPointsPageDTO dto) {
|
||||
iUserPointsService.exportPointsDetail(dto);
|
||||
return Result.OK("导出成功,请在导出记录查看");
|
||||
}
|
||||
|
||||
@Operation(summary = "用户积分信息-扣除积分", description = "用户积分信息-扣除积分")
|
||||
@PostMapping(value = "/deductPoint")
|
||||
public Result<Boolean> deductPoint(@RequestBody UpdUserPointsDTO dto) {
|
||||
return Result.OK(iUserPointsService.deductPoint(dto));
|
||||
}
|
||||
|
||||
@Operation(summary = "用户积分信息-员工打卡监测", description = "用户积分信息-员工打卡监测")
|
||||
@PostMapping(value = "/clockInMonitor")
|
||||
public Result<IPage<UserPointsMonitorVO>> clockInMonitor(@RequestBody UserPointsPageDTO dto) {
|
||||
return Result.OK(iUserPointsService.clockInMonitor(dto));
|
||||
}
|
||||
|
||||
@Operation(summary = "用户积分信息-员工打卡监测(导出)", description = "用户积分信息-员工打卡监测(导出)")
|
||||
@PostMapping(value = "/exportClockInMonitor")
|
||||
public Result<String> exportClockInMonitor(@RequestBody UserPointsPageDTO dto) {
|
||||
iUserPointsService.exportClockInMonitor(dto);
|
||||
return Result.OK("导出成功,请在导出记录查看");
|
||||
}
|
||||
|
||||
@Operation(summary = "用户积分信息-员工积分排名", description = "用户积分信息-员工积分排名")
|
||||
@PostMapping(value = "/userRanking")
|
||||
public Result<IPage<UserPointRankingVO>> userRanking(@RequestBody UserPointsRankingDTO dto) {
|
||||
return Result.OK(iUserPointsService.userRanking(dto));
|
||||
}
|
||||
|
||||
@Operation(summary = "用户积分信息-员工积分排名(导出)", description = "用户积分信息-员工积分排名(导出)")
|
||||
@PostMapping(value = "/exportUserRanking")
|
||||
public Result<String> exportUserRanking(@RequestBody UserPointsRankingDTO dto) {
|
||||
iUserPointsService.exportUserRanking(dto);
|
||||
return Result.OK("导出成功,请在导出记录查看");
|
||||
}
|
||||
|
||||
@Operation(summary = "用户积分信息-app我的积分", description = "用户积分信息-app我的积分")
|
||||
@GetMapping(value = "/app/myPoints")
|
||||
public Result<UserPointsInfoVO> myPoints() {
|
||||
return Result.OK(iUserPointsService.myPoints());
|
||||
}
|
||||
|
||||
@Operation(summary = "用户积分信息-app积分任务", description = "用户积分信息-app积分任务")
|
||||
@GetMapping(value = "/app/pointsTaskList")
|
||||
public Result<List<UserPointsTaskVO>> pointsTaskList() {
|
||||
return Result.OK(iUserPointsService.pointsTaskList());
|
||||
}
|
||||
|
||||
@Operation(summary = "用户积分信息-app积分打卡", description = "用户积分信息-app积分打卡")
|
||||
@PostMapping(value = "/app/pointCheckIn")
|
||||
public Result<Boolean> pointCheckIn(@RequestBody UpdUserPointsDTO dto) {
|
||||
return Result.OK(iUserPointsService.pointCheckIn(dto));
|
||||
}
|
||||
|
||||
@Operation(summary = "用户积分信息-app积分明细", description = "用户积分信息-app积分明细")
|
||||
@PostMapping(value = "/app/pointRecord")
|
||||
public Result<IPage<UserPointRecordVO>> pointRecord(@RequestBody UserPointsPageDTO dto) {
|
||||
return Result.OK(iUserPointsService.pointRecord(dto));
|
||||
}
|
||||
|
||||
@Operation(summary = "用户积分信息-app积分榜单", description = "用户积分信息-app积分榜单")
|
||||
@PostMapping(value = "/app/pointRanking")
|
||||
public Result<IPage<UserPointRankingVO>> pointRanking(@RequestBody UserPointsRankingDTO dto) {
|
||||
return Result.OK(iUserPointsService.pointRanking(dto));
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.renkang.bank.mapper;
|
||||
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.renkang.bank.model.po.PointsRule;
|
||||
import com.renkang.bank.model.vo.UserPointsTaskVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface PointsRuleMapper extends MPJBaseMapper<PointsRule> {
|
||||
|
||||
List<UserPointsTaskVO> pointsTaskList(@Param("userId") String userId);
|
||||
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.renkang.bank.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.renkang.bank.model.dto.UserPointsRankingDTO;
|
||||
import com.renkang.bank.model.po.UserPointsDetails;
|
||||
import com.renkang.bank.model.vo.UserPointRankingVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Mapper
|
||||
public interface UserPointsDetailsMapper extends MPJBaseMapper<UserPointsDetails> {
|
||||
|
||||
IPage<UserPointRankingVO> userRanking(IPage<UserPointRankingVO> page, Date startTime, Date endTime, UserPointsRankingDTO dto);
|
||||
|
||||
IPage<UserPointRankingVO> pointRanking(IPage<UserPointRankingVO> page, Date startTime, Date endTime, String secondOrgCode);
|
||||
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.renkang.bank.mapper;
|
||||
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.renkang.bank.model.po.UserPoints;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* @author: pj
|
||||
* @description: 用户积分
|
||||
* @date 2026/2/5 16:47
|
||||
*/
|
||||
@Mapper
|
||||
public interface UserPointsMapper extends MPJBaseMapper<UserPoints> {
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.renkang.bank.mapper.PointsRuleMapper">
|
||||
|
||||
<select id="pointsTaskList" resultType="com.renkang.bank.model.vo.UserPointsTaskVO">
|
||||
SELECT
|
||||
a.id as ruleId,
|
||||
a.frequency,
|
||||
a.rule_category,
|
||||
a.rule_desc,
|
||||
a.icon,
|
||||
a.points,
|
||||
CASE
|
||||
WHEN a.frequency = 1 THEN -- 单次
|
||||
IF(COUNT(b.id) > 0, 1, 0)
|
||||
WHEN a.frequency = 2 THEN -- 日/次
|
||||
IF(COUNT(CASE WHEN DATE(b.create_time) = CURDATE() THEN 1 END) > 0, 1, 0)
|
||||
WHEN a.frequency = 3 THEN -- 周/次
|
||||
IF(COUNT(CASE WHEN YEARWEEK(b.create_time, 1) = YEARWEEK(CURDATE(), 1) THEN 1 END) > 0, 1, 0)
|
||||
WHEN a.frequency = 4 THEN -- 月/次
|
||||
IF(COUNT(CASE WHEN DATE_FORMAT(b.create_time, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m') THEN 1 END) > 0, 1, 0)
|
||||
WHEN a.frequency = 5 THEN -- 季度/次
|
||||
IF(COUNT(CASE WHEN QUARTER(b.create_time) = QUARTER(CURDATE()) AND YEAR(b.create_time) = YEAR(CURDATE()) THEN 1
|
||||
END) > 0, 1, 0)
|
||||
WHEN a.frequency = 6 THEN -- 年/次
|
||||
IF(COUNT(CASE WHEN YEAR(b.create_time) = YEAR(CURDATE()) THEN 1 END) > 0, 1, 0)
|
||||
ELSE 0
|
||||
END AS clockInStatus
|
||||
FROM
|
||||
bank_points_rule a
|
||||
LEFT JOIN bank_user_points_details b ON b.user_id = #{userId}
|
||||
AND b.change_type = 1
|
||||
AND b.business_id = a.id
|
||||
GROUP BY
|
||||
a.id,a.frequency
|
||||
order by a.frequency
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.renkang.bank.mapper.UserPointsDetailsMapper">
|
||||
|
||||
<select id="userRanking" resultType="com.renkang.bank.model.vo.UserPointRankingVO">
|
||||
<!--定义公共表表达式用于计算每个用户的总积分-->
|
||||
WITH UserPointsSummary AS (
|
||||
SELECT
|
||||
a.user_id,
|
||||
SUM(CASE WHEN a.change_type = 1 THEN a.points ELSE 0 END) -
|
||||
SUM(CASE WHEN a.change_type = 2 THEN a.points ELSE 0 END) AS pointSum
|
||||
FROM
|
||||
bank_user_points_details a
|
||||
INNER JOIN bank_user_points b ON a.user_id = b.user_id
|
||||
<if test="null != dto.orgCode and '' != dto.orgCode">
|
||||
AND b.org_code like concat(#{dto.orgCode},'%')
|
||||
</if>
|
||||
<if test="null != dto.deptCode and '' != dto.deptCode">
|
||||
AND b.org_code like concat(#{dto.deptCode},'%')
|
||||
</if>
|
||||
GROUP BY
|
||||
a.user_id
|
||||
),
|
||||
<!--计算所有用户的排名-->
|
||||
RankedUsers AS (
|
||||
SELECT
|
||||
user_id,
|
||||
pointSum,
|
||||
ROW_NUMBER() OVER (ORDER BY pointSum DESC, user_id ASC) AS ranking
|
||||
FROM
|
||||
UserPointsSummary
|
||||
)
|
||||
<!--主查询:根据是否传入用户 ID 返回结果-->
|
||||
SELECT
|
||||
ranking,
|
||||
user_id,
|
||||
pointSum
|
||||
FROM
|
||||
RankedUsers
|
||||
<where>
|
||||
<if test="dto.userIds != null and dto.userIds.size() > 0">
|
||||
AND user_id in
|
||||
<foreach collection="dto.userIds" item="userId" open="(" separator="," close=")">
|
||||
#{userId}
|
||||
</foreach>
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY
|
||||
pointSum DESC, user_id ASC
|
||||
</select>
|
||||
|
||||
<select id="pointRanking" resultType="com.renkang.bank.model.vo.UserPointRankingVO">
|
||||
WITH UserPointsSummary AS (
|
||||
SELECT
|
||||
a.user_id,
|
||||
SUM( CASE WHEN a.change_type = 1 THEN a.points ELSE 0 END ) - SUM( CASE WHEN a.change_type = 2 THEN a.points
|
||||
ELSE 0 END ) AS pointSum
|
||||
FROM
|
||||
bank_user_points_details a
|
||||
INNER JOIN bank_user_points b ON a.user_id = b.user_id
|
||||
<if test="null != secondOrgCode and '' != secondOrgCode">
|
||||
AND b.org_code like concat(#{secondOrgCode},'%')
|
||||
</if>
|
||||
<where>
|
||||
<if test="startTime != null and endTime != null">
|
||||
AND a.create_time BETWEEN #{startTime} AND #{endTime}
|
||||
</if>
|
||||
</where>
|
||||
GROUP BY
|
||||
a.user_id
|
||||
) SELECT
|
||||
ROW_NUMBER() OVER ( ORDER BY pointSum DESC ) AS ranking,
|
||||
user_id,
|
||||
pointSum
|
||||
FROM
|
||||
UserPointsSummary
|
||||
ORDER BY
|
||||
pointSum DESC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
package com.renkang.bank.redis.config;
|
||||
|
||||
import com.renkang.bank.redis.listener.BankAsyncListener;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.system.vo.SysUserModel;
|
||||
import org.jeecg.enums.ServerEnum;
|
||||
import org.jeecg.redis.RedisStreamKeyEnum;
|
||||
import org.jeecg.util.IPUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.connection.stream.Consumer;
|
||||
import org.springframework.data.redis.connection.stream.ObjectRecord;
|
||||
import org.springframework.data.redis.connection.stream.ReadOffset;
|
||||
import org.springframework.data.redis.connection.stream.StreamOffset;
|
||||
import org.springframework.data.redis.hash.Jackson2HashMapper;
|
||||
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
import org.springframework.data.redis.stream.StreamMessageListenerContainer;
|
||||
|
||||
/**
|
||||
* @author Shunzhi Jiang
|
||||
* @since 2023/6/13
|
||||
*/
|
||||
@Configuration
|
||||
@Slf4j
|
||||
public class BankRedisStreamConfig {
|
||||
|
||||
private final Consumer consumer = Consumer.from(ServerEnum.BANK.getCustomGroup(), IPUtil.getCurrentServiceIp());
|
||||
|
||||
private final ReadOffset readOffset = ReadOffset.lastConsumed();
|
||||
|
||||
private BankAsyncListener bankAsyncListener;
|
||||
|
||||
|
||||
@Autowired
|
||||
public void setDepartAsyncListener(BankAsyncListener bankAsyncListener) {
|
||||
this.bankAsyncListener = bankAsyncListener;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, ObjectRecord<String, SysUserModel>> sysUserModelInterveneStreamOptions(
|
||||
@Qualifier("asyncTaskExecutor") TaskExecutor taskExecutor,
|
||||
StringRedisSerializer stringSerializer,
|
||||
GenericJackson2JsonRedisSerializer jsonSerializer
|
||||
) {
|
||||
return StreamMessageListenerContainer.StreamMessageListenerContainerOptions
|
||||
.builder()
|
||||
// 一次最多获取多少条消息
|
||||
.batchSize(10)
|
||||
// 运行 Stream 的 poll task
|
||||
.executor(taskExecutor)
|
||||
// 可以理解为 Stream Key 的序列化方式
|
||||
.keySerializer(stringSerializer)
|
||||
// 可以理解为 Stream 后方的字段的 key 的序列化方式
|
||||
.hashKeySerializer(stringSerializer)
|
||||
// 可以理解为 Stream 后方的字段的 value 的序列化方式
|
||||
.hashValueSerializer(jsonSerializer)
|
||||
// ObjectRecord 时,将 对象的 filed 和 value 转换成一个 Map 比如:将Book对象转换成map
|
||||
.objectMapper(new Jackson2HashMapper(true))
|
||||
// 将发送到Stream中的Record转换成ObjectRecord,转换成具体的类型是这个地方指定的类型
|
||||
.targetType(SysUserModel.class)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean(initMethod = "start", destroyMethod = "stop")
|
||||
public StreamMessageListenerContainer<String, ObjectRecord<String, SysUserModel>> sysUserModelInterveneStreamMessageListenerContainer(
|
||||
RedisConnectionFactory redisConnectionFactory,
|
||||
StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, ObjectRecord<String, SysUserModel>> options
|
||||
) {
|
||||
StreamMessageListenerContainer<String, ObjectRecord<String, SysUserModel>> container =
|
||||
StreamMessageListenerContainer.create(redisConnectionFactory, options);
|
||||
// 修改用户
|
||||
container.receive(
|
||||
consumer,
|
||||
createStreamOffset(RedisStreamKeyEnum.CHANGE_USER_DEPART),
|
||||
bankAsyncListener
|
||||
);
|
||||
log.info("redisStream配置完成");
|
||||
return container;
|
||||
}
|
||||
|
||||
private StreamOffset<String> createStreamOffset(RedisStreamKeyEnum streamKeyEnum) {
|
||||
return StreamOffset.create(streamKeyEnum.getKey(), readOffset);
|
||||
}
|
||||
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package com.renkang.bank.redis.listener;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.renkang.bank.mapper.UserPointsMapper;
|
||||
import com.renkang.bank.model.po.UserPoints;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.system.vo.SysUserModel;
|
||||
import org.jeecg.enums.ServerEnum;
|
||||
import org.jeecg.redis.RedisStreamKeyEnum;
|
||||
import org.jeecg.redis.RedisStreamUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.connection.stream.ObjectRecord;
|
||||
import org.springframework.data.redis.connection.stream.RecordId;
|
||||
import org.springframework.data.redis.stream.StreamListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Shunzhi Jiang
|
||||
* @since 2023/6/13
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class BankAsyncListener implements StreamListener<String, ObjectRecord<String, SysUserModel>> {
|
||||
@Autowired
|
||||
private RedisStreamUtil redisStreamUtil;
|
||||
@Autowired
|
||||
private UserPointsMapper userPointsMapper;
|
||||
|
||||
@Override
|
||||
public void onMessage(ObjectRecord<String, SysUserModel> message) {
|
||||
String streamKey = message.getStream();
|
||||
SysUserModel model = message.getValue();
|
||||
log.info("收到Redis Stream Key:{}", streamKey);
|
||||
RecordId recordId = message.getId();
|
||||
log.info("ID:{}, DATA: {}", recordId, JSON.toJSONString(model));
|
||||
try {
|
||||
if (RedisStreamKeyEnum.CHANGE_USER_DEPART.getKey().equals(streamKey)) {
|
||||
if (StrUtil.isBlank(model.getId()) || StrUtil.isBlank(model.getOrgCode())) {
|
||||
return;
|
||||
}
|
||||
// 修改用户积分主表单位信息
|
||||
updateUserPointsInfo(model);
|
||||
}
|
||||
ack(message);
|
||||
log.info("Redis Stream消费成功:Key: {}, ID: {}", streamKey, recordId);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis Stream消费异常:Key: {}, ID: {}", streamKey, recordId, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUserPointsInfo(SysUserModel model) {
|
||||
userPointsMapper.update(new LambdaUpdateWrapper<UserPoints>()
|
||||
.eq(UserPoints::getUserId, model.getId())
|
||||
.set(UserPoints::getOrgCode, model.getOrgCode())
|
||||
);
|
||||
}
|
||||
|
||||
private void ack(ObjectRecord<String, SysUserModel> message) {
|
||||
redisStreamUtil.ack(ServerEnum.BANK.getCustomGroup(), message);
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.renkang.bank.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.renkang.bank.model.dto.PointsRulePageDTO;
|
||||
import com.renkang.bank.model.po.PointsRule;
|
||||
|
||||
public interface IPointsRuleService extends IService<PointsRule> {
|
||||
|
||||
IPage<PointsRule> pageList(PointsRulePageDTO dto);
|
||||
|
||||
int add(PointsRule pointsRule);
|
||||
|
||||
int edit(PointsRule pointsRule);
|
||||
|
||||
PointsRule byId(String id);
|
||||
|
||||
int delete(String id);
|
||||
|
||||
int editStatus(Long id, Integer status);
|
||||
|
||||
int deleteBatch(String ids);
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.renkang.bank.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.renkang.bank.model.dto.UpdUserPointsDTO;
|
||||
import com.renkang.bank.model.dto.UserPointsPageDTO;
|
||||
import com.renkang.bank.model.dto.UserPointsRankingDTO;
|
||||
import com.renkang.bank.model.vo.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IUserPointsService {
|
||||
|
||||
boolean testUpdateUserPoints(UpdUserPointsDTO dto);
|
||||
|
||||
IPage<UserPointsListVO> pageList(UserPointsPageDTO dto);
|
||||
|
||||
void exportUserPoints(UserPointsPageDTO dto);
|
||||
|
||||
IPage<UserPointsDetailsVO> detailPageList(UserPointsPageDTO dto);
|
||||
|
||||
void exportPointsDetail(UserPointsPageDTO dto);
|
||||
|
||||
boolean deductPoint(UpdUserPointsDTO dto);
|
||||
|
||||
IPage<UserPointsMonitorVO> clockInMonitor(UserPointsPageDTO dto);
|
||||
|
||||
void exportClockInMonitor(UserPointsPageDTO dto);
|
||||
|
||||
IPage<UserPointRankingVO> userRanking(UserPointsRankingDTO dto);
|
||||
|
||||
void exportUserRanking(UserPointsRankingDTO dto);
|
||||
|
||||
UserPointsInfoVO myPoints();
|
||||
|
||||
List<UserPointsTaskVO> pointsTaskList();
|
||||
|
||||
boolean pointCheckIn(UpdUserPointsDTO dto);
|
||||
|
||||
IPage<UserPointRecordVO> pointRecord(UserPointsPageDTO dto);
|
||||
|
||||
IPage<UserPointRankingVO> pointRanking(UserPointsRankingDTO dto);
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
package com.renkang.bank.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.renkang.bank.mapper.PointsRuleMapper;
|
||||
import com.renkang.bank.model.dto.PointsRulePageDTO;
|
||||
import com.renkang.bank.model.po.PointsRule;
|
||||
import com.renkang.bank.service.IPointsRuleService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.jeecg.global.GlobalUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author pj
|
||||
* @version 1.0
|
||||
* @description: 积分规则
|
||||
* @date 2026/2/5 18:01
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PointsRuleServiceImpl extends ServiceImpl<PointsRuleMapper, PointsRule> implements IPointsRuleService {
|
||||
|
||||
@Override
|
||||
public IPage<PointsRule> pageList(PointsRulePageDTO dto) {
|
||||
Page<PointsRule> page = new Page<>(dto.getPageNo(), dto.getPageSize());
|
||||
LambdaQueryWrapper<PointsRule> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.like(StringUtils.isNotBlank(dto.getRuleDesc()), PointsRule::getRuleDesc, dto.getRuleDesc());
|
||||
queryWrapper.eq(ObjectUtil.isNotNull(dto.getRuleCategory()), PointsRule::getRuleDesc, dto.getRuleCategory());
|
||||
queryWrapper.eq(ObjectUtil.isNotNull(dto.getStatus()), PointsRule::getRuleDesc, dto.getStatus());
|
||||
queryWrapper.orderByDesc(PointsRule::getCreateTime);
|
||||
return baseMapper.selectPage(page, queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int add(PointsRule pointsRule) {
|
||||
String userId = GlobalUtils.getLoginUser().getId();
|
||||
Date date = new Date();
|
||||
pointsRule.setCreateUser(userId);
|
||||
pointsRule.setLastModifyDate(date);
|
||||
pointsRule.setCreateTime(date);
|
||||
return baseMapper.insert(pointsRule);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int edit(PointsRule pointsRule) {
|
||||
pointsRule.setLastModifyDate(new Date());
|
||||
return baseMapper.updateById(pointsRule);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointsRule byId(String id) {
|
||||
return baseMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(String id) {
|
||||
return baseMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int editStatus(Long id, Integer status) {
|
||||
return baseMapper.update(new LambdaUpdateWrapper<PointsRule>()
|
||||
.eq(PointsRule::getId, id)
|
||||
.set(PointsRule::getStatus, status)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteBatch(String ids) {
|
||||
return baseMapper.deleteBatchIds(Arrays.asList(ids.split(",")));
|
||||
}
|
||||
}
|
||||
+688
@@ -0,0 +1,688 @@
|
||||
package com.renkang.bank.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
import com.renkang.bank.constant.HealthBankConstants;
|
||||
import com.renkang.bank.enums.PointsSourceEnum;
|
||||
import com.renkang.bank.mapper.PointsRuleMapper;
|
||||
import com.renkang.bank.mapper.UserPointsDetailsMapper;
|
||||
import com.renkang.bank.mapper.UserPointsMapper;
|
||||
import com.renkang.bank.model.dto.UpdUserPointsDTO;
|
||||
import com.renkang.bank.model.dto.UserPointsPageDTO;
|
||||
import com.renkang.bank.model.dto.UserPointsRankingDTO;
|
||||
import com.renkang.bank.model.po.PointsRule;
|
||||
import com.renkang.bank.model.po.UserPoints;
|
||||
import com.renkang.bank.model.po.UserPointsDetails;
|
||||
import com.renkang.bank.model.vo.*;
|
||||
import com.renkang.bank.service.IUserPointsService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jeecg.common.exception.ExceptionAssertsUtil;
|
||||
import org.jeecg.common.export.GenericExportHandler;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.enums.ExportExcelEnum;
|
||||
import org.jeecg.global.GlobalUtils;
|
||||
import org.jeecg.modules.manager.ISysCache;
|
||||
import org.jeecg.modules.system.entity.SysDepart;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author pj
|
||||
* @version 1.0
|
||||
* @description: 用户积分
|
||||
* @date 2026/2/5 16:49
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UserPointsServiceImpl extends ServiceImpl<UserPointsMapper, UserPoints> implements IUserPointsService {
|
||||
|
||||
private final PointsRuleMapper pointsRuleMapper;
|
||||
private final UserPointsDetailsMapper userPointsDetailsMapper;
|
||||
private final ISysBaseAPI iSysBaseAPI;
|
||||
private final ISysCache sysCache;
|
||||
|
||||
@Override
|
||||
public IPage<UserPointsListVO> pageList(UserPointsPageDTO dto) {
|
||||
Page<UserPointsListVO> page = new Page<>(dto.getPageNo(), dto.getPageSize());
|
||||
MPJLambdaWrapper<UserPoints> queryWrapper = new MPJLambdaWrapper<>();
|
||||
if (StringUtils.isNotBlank(dto.getRealName()) || StringUtils.isNotBlank(dto.getWorkNo())) {
|
||||
//根据姓名和工号查询用户
|
||||
List<String> userIdList = iSysBaseAPI.getUserIdsByDepartAndUsername(null, dto.getRealName(), null, dto.getWorkNo());
|
||||
queryWrapper.in(!userIdList.isEmpty(), UserPoints::getUserId, userIdList);
|
||||
}
|
||||
// 动态排序
|
||||
if (StringUtils.isNotBlank(dto.getColumn())) {
|
||||
// 驼峰转下划线
|
||||
String column = CharSequenceUtil.toUnderlineCase(dto.getColumn());
|
||||
if ("asc".equalsIgnoreCase(dto.getOrder())) {
|
||||
queryWrapper.orderByAsc(column);
|
||||
} else {
|
||||
queryWrapper.orderByDesc(column);
|
||||
}
|
||||
} else {
|
||||
// 默认排序
|
||||
queryWrapper.orderByDesc(UserPoints::getLastAddDate);
|
||||
}
|
||||
if (StringUtils.isNotBlank(dto.getOrgCode())) {
|
||||
queryWrapper.likeRight(UserPoints::getOrgCode, dto.getOrgCode());
|
||||
}
|
||||
if (StringUtils.isNotBlank(dto.getDeptCode())) {
|
||||
queryWrapper.likeRight(UserPoints::getOrgCode, dto.getDeptCode());
|
||||
}
|
||||
Page<UserPointsListVO> voPage = baseMapper.selectJoinPage(page, UserPointsListVO.class, queryWrapper);
|
||||
List<String> userIds = voPage.getRecords().stream().map(UserPoints::getUserId).collect(Collectors.toList());
|
||||
if (!userIds.isEmpty()) {
|
||||
List<LoginUser> loginUsers = iSysBaseAPI.listUserByIdsNew(userIds);
|
||||
voPage.getRecords().forEach(vo -> {
|
||||
LoginUser loginUser = loginUsers.stream().filter(user -> user.getId().equals(vo.getUserId())).findFirst().orElse(null);
|
||||
if (loginUser != null) {
|
||||
vo.setRealName(loginUser.getRealname());
|
||||
vo.setWorkNo(loginUser.getWorkNo());
|
||||
vo.setSexName(ObjectUtil.isNotNull(loginUser.getSex()) && loginUser.getSex().equals(1) ? "女" : "男");
|
||||
vo.setAge(ObjectUtil.isNotNull(loginUser.getAge()) && loginUser.getAge() > 0 ? loginUser.getAge() : null);
|
||||
SysDepart secondDepart = sysCache.getDepartByOrgCode(GlobalUtils.getSecondDepartOrgCode(vo.getOrgCode()));
|
||||
if (ObjectUtil.isNotEmpty(secondDepart)) {
|
||||
vo.setDeptName(secondDepart.getDepartName());
|
||||
}
|
||||
SysDepart thirdDepart = sysCache.getDepartByOrgCode(GlobalUtils.getThirdDepartOrgCode(vo.getOrgCode()));
|
||||
if (ObjectUtil.isNotEmpty(thirdDepart)) {
|
||||
vo.setOrgName(thirdDepart.getDepartName());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return voPage;
|
||||
}
|
||||
|
||||
@Resource
|
||||
private AsyncTaskExecutor asyncTaskExecutor;
|
||||
|
||||
/**
|
||||
* @description: 导出数据(设备数据)
|
||||
* @author PengJ
|
||||
* @date 2025/11/18 14:57
|
||||
*/
|
||||
@Override
|
||||
public void exportUserPoints(UserPointsPageDTO dto) {
|
||||
GenericExportHandler<UserPointsListVO, UserPointsPageDTO> handler =
|
||||
new GenericExportHandler<>(
|
||||
UserPointsListVO.class,
|
||||
ExportExcelEnum.BANK_USER_POINTS,
|
||||
asyncTaskExecutor,
|
||||
log,
|
||||
filter -> {
|
||||
filter.setPageNo(1);
|
||||
filter.setPageSize(-1);
|
||||
List<UserPointsListVO> records = pageList(filter).getRecords();
|
||||
return GenericExportHandler.handleData(records, UserPointsListVO.class);
|
||||
}
|
||||
);
|
||||
handler.exportAsync(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<UserPointsDetailsVO> detailPageList(UserPointsPageDTO dto) {
|
||||
if (StringUtils.isBlank(dto.getUserId())) {
|
||||
ExceptionAssertsUtil.fail("用户id不能为空");
|
||||
}
|
||||
if (ObjectUtil.isNull(dto.getChangeType())) {
|
||||
ExceptionAssertsUtil.fail("收支类型不能为空");
|
||||
}
|
||||
Page<UserPointsDetailsVO> page = new Page<>(dto.getPageNo(), dto.getPageSize());
|
||||
MPJLambdaWrapper<UserPointsDetails> queryWrapper = new MPJLambdaWrapper<>();
|
||||
queryWrapper.select(UserPointsDetails::getId, UserPointsDetails::getBusinessInfo,
|
||||
UserPointsDetails::getPoints, UserPointsDetails::getCreateTime, UserPointsDetails::getChangeType,
|
||||
UserPointsDetails::getRemark, UserPointsDetails::getBusinessId, UserPointsDetails::getUserId);
|
||||
queryWrapper.select(PointsRule::getFrequency);
|
||||
queryWrapper.leftJoin(PointsRule.class, PointsRule::getId, UserPointsDetails::getBusinessId);
|
||||
queryWrapper.eq(UserPointsDetails::getUserId, dto.getUserId());
|
||||
queryWrapper.eq(UserPointsDetails::getChangeType, dto.getChangeType());
|
||||
queryWrapper.orderByDesc(UserPointsDetails::getCreateTime);
|
||||
Page<UserPointsDetailsVO> voPage = userPointsDetailsMapper.selectJoinPage(page, UserPointsDetailsVO.class, queryWrapper);
|
||||
if (dto.getChangeType().equals(HealthBankConstants.CHANGE_TYPE_DEDUCT)) {
|
||||
voPage.getRecords().forEach(vo -> {
|
||||
vo.setPoints(vo.getPoints().multiply(new BigDecimal(-1)));
|
||||
});
|
||||
}
|
||||
return voPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportPointsDetail(UserPointsPageDTO dto) {
|
||||
if (StringUtils.isBlank(dto.getUserId())) {
|
||||
ExceptionAssertsUtil.fail("用户id不能为空");
|
||||
}
|
||||
if (ObjectUtil.isNull(dto.getChangeType())) {
|
||||
ExceptionAssertsUtil.fail("收支类型不能为空");
|
||||
}
|
||||
if (dto.getChangeType().equals(HealthBankConstants.CHANGE_TYPE_ADD)) {
|
||||
GenericExportHandler<UserPointsDetailsVO, UserPointsPageDTO> handler =
|
||||
new GenericExportHandler<>(
|
||||
UserPointsDetailsVO.class,
|
||||
ExportExcelEnum.BANK_POINTS_DETAIL,
|
||||
asyncTaskExecutor,
|
||||
log,
|
||||
filter -> {
|
||||
filter.setPageNo(1);
|
||||
filter.setPageSize(-1);
|
||||
List<UserPointsDetailsVO> records = detailPageList(filter).getRecords();
|
||||
return GenericExportHandler.handleData(records, UserPointsDetailsVO.class);
|
||||
}
|
||||
);
|
||||
handler.exportAsync(dto);
|
||||
} else if (dto.getChangeType().equals(HealthBankConstants.CHANGE_TYPE_DEDUCT)) {
|
||||
GenericExportHandler<UserPointsDeductDetailsVO, UserPointsPageDTO> handler =
|
||||
new GenericExportHandler<>(
|
||||
UserPointsDeductDetailsVO.class,
|
||||
ExportExcelEnum.BANK_POINTS_DETAIL,
|
||||
asyncTaskExecutor,
|
||||
log,
|
||||
filter -> {
|
||||
filter.setPageNo(1);
|
||||
filter.setPageSize(-1);
|
||||
List<UserPointsDetailsVO> records = detailPageList(filter).getRecords();
|
||||
List<UserPointsDeductDetailsVO> voList = BeanUtil.copyToList(records, UserPointsDeductDetailsVO.class);
|
||||
return GenericExportHandler.handleData(voList, UserPointsDeductDetailsVO.class);
|
||||
}
|
||||
);
|
||||
handler.exportAsync(dto);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deductPoint(UpdUserPointsDTO dto) {
|
||||
dto.setSourceType(PointsSourceEnum.TYPE_2_VIOLATION.getSource());
|
||||
LoginUser loginUser = GlobalUtils.getLoginUser();
|
||||
return updateUserPoints(dto, loginUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<UserPointsMonitorVO> clockInMonitor(UserPointsPageDTO dto) {
|
||||
Page<UserPointsMonitorVO> page = new Page<>(dto.getPageNo(), dto.getPageSize());
|
||||
MPJLambdaWrapper<UserPointsDetails> queryWrapper = new MPJLambdaWrapper<>();
|
||||
queryWrapper.selectAll(UserPointsDetails.class);
|
||||
queryWrapper.select(PointsRule::getFrequency);
|
||||
queryWrapper.eq(UserPointsDetails::getSource, PointsSourceEnum.TYPE_1_SURVEY.getSource());
|
||||
if (StringUtils.isNotBlank(dto.getRealName()) || StringUtils.isNotBlank(dto.getWorkNo())) {
|
||||
//根据姓名和工号查询用户
|
||||
List<String> userIdList = iSysBaseAPI.getUserIdsByDepartAndUsername(null, dto.getRealName(), null, dto.getWorkNo());
|
||||
queryWrapper.in(!userIdList.isEmpty(), UserPoints::getUserId, userIdList);
|
||||
}
|
||||
queryWrapper.orderByDesc(UserPointsDetails::getCreateTime);
|
||||
if (StringUtils.isNotBlank(dto.getOrgCode())) {
|
||||
queryWrapper.likeRight(UserPoints::getOrgCode, dto.getOrgCode());
|
||||
}
|
||||
if (StringUtils.isNotBlank(dto.getDeptCode())) {
|
||||
queryWrapper.likeRight(UserPoints::getOrgCode, dto.getDeptCode());
|
||||
}
|
||||
queryWrapper.leftJoin(PointsRule.class, PointsRule::getId, UserPointsDetails::getBusinessId);
|
||||
queryWrapper.orderByDesc(UserPointsDetails::getCreateTime);
|
||||
Page<UserPointsMonitorVO> voPage = userPointsDetailsMapper.selectJoinPage(page, UserPointsMonitorVO.class, queryWrapper);
|
||||
List<String> userIds = voPage.getRecords().stream().map(UserPointsMonitorVO::getUserId).collect(Collectors.toList());
|
||||
if (!userIds.isEmpty()) {
|
||||
List<LoginUser> loginUsers = iSysBaseAPI.listUserByIdsNew(userIds);
|
||||
voPage.getRecords().forEach(vo -> {
|
||||
LoginUser loginUser = loginUsers.stream().filter(user -> user.getId().equals(vo.getUserId())).findFirst().orElse(null);
|
||||
if (loginUser != null) {
|
||||
vo.setRealName(loginUser.getRealname());
|
||||
vo.setWorkNo(loginUser.getWorkNo());
|
||||
vo.setSexName(ObjectUtil.isNotNull(loginUser.getSex()) && loginUser.getSex().equals(1) ? "女" : "男");
|
||||
vo.setAge(ObjectUtil.isNotNull(loginUser.getAge()) && loginUser.getAge() > 0 ? loginUser.getAge() : null);
|
||||
SysDepart secondDepart = sysCache.getDepartByOrgCode(GlobalUtils.getSecondDepartOrgCode(loginUser.getOrgCode()));
|
||||
if (ObjectUtil.isNotEmpty(secondDepart)) {
|
||||
vo.setDeptName(secondDepart.getDepartName());
|
||||
}
|
||||
SysDepart thirdDepart = sysCache.getDepartByOrgCode(GlobalUtils.getThirdDepartOrgCode(loginUser.getOrgCode()));
|
||||
if (ObjectUtil.isNotEmpty(thirdDepart)) {
|
||||
vo.setOrgName(thirdDepart.getDepartName());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return voPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportClockInMonitor(UserPointsPageDTO dto) {
|
||||
GenericExportHandler<UserPointsMonitorVO, UserPointsPageDTO> handler =
|
||||
new GenericExportHandler<>(
|
||||
UserPointsMonitorVO.class,
|
||||
ExportExcelEnum.BANK_CLOCK_IN_RECORD,
|
||||
asyncTaskExecutor,
|
||||
log,
|
||||
filter -> {
|
||||
filter.setPageNo(1);
|
||||
filter.setPageSize(-1);
|
||||
List<UserPointsMonitorVO> records = clockInMonitor(filter).getRecords();
|
||||
return GenericExportHandler.handleData(records, UserPointsMonitorVO.class);
|
||||
}
|
||||
);
|
||||
handler.exportAsync(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<UserPointRankingVO> userRanking(UserPointsRankingDTO dto) {
|
||||
Page<UserPointRankingVO> page = new Page<>(dto.getPageNo(), dto.getPageSize());
|
||||
Date startTime = null;
|
||||
Date endTime = null;
|
||||
Date now = new Date();
|
||||
if (StringUtils.isNotBlank(dto.getRankType())) {
|
||||
if ("0".equals(dto.getRankType())) {
|
||||
// 获取当天的开始时间
|
||||
startTime = DateUtil.beginOfDay(now);
|
||||
// 获取当天的结束时间
|
||||
endTime = DateUtil.endOfDay(now);
|
||||
} else if ("1".equals(dto.getRankType())) {
|
||||
// 获取本周的开始时间(周一)
|
||||
startTime = DateUtil.beginOfWeek(now, true);
|
||||
// 获取本周的结束时间(周日)
|
||||
endTime = DateUtil.endOfWeek(now, true);
|
||||
} else if ("2".equals(dto.getRankType())) {
|
||||
// 获取本月的开始时间
|
||||
startTime = DateUtil.beginOfMonth(now);
|
||||
// 获取本月的结束时间
|
||||
endTime = DateUtil.endOfMonth(now);
|
||||
} else if ("3".equals(dto.getRankType())) {
|
||||
// 获取本季度的开始时间
|
||||
startTime = DateUtil.beginOfQuarter(now);
|
||||
// 获取本季度的结束时间
|
||||
endTime = DateUtil.endOfQuarter(now);
|
||||
} else if ("4".equals(dto.getRankType())) {
|
||||
// 获取本年度的开始时间
|
||||
startTime = DateUtil.beginOfYear(now);
|
||||
// 获取本年度的结束时间
|
||||
endTime = DateUtil.endOfYear(now);
|
||||
} else if ("5".equals(dto.getRankType())) {
|
||||
// 获取指定时间的开始时间
|
||||
startTime = DateUtil.beginOfDay(dto.getStartTime());
|
||||
// 获取指定时间的结束时间
|
||||
endTime = DateUtil.endOfDay(dto.getEndTime());
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotBlank(dto.getRealName()) || StringUtils.isNotBlank(dto.getWorkNo())) {
|
||||
List<String> sysUserIds = iSysBaseAPI.getUserIdsByDepartAndUsername(
|
||||
StringUtils.isNotBlank(dto.getDeptCode()) ? dto.getDeptCode() : dto.getOrgCode(),
|
||||
dto.getRealName(),
|
||||
null,
|
||||
dto.getWorkNo()
|
||||
);
|
||||
if (!sysUserIds.isEmpty()) {
|
||||
dto.setUserIds(sysUserIds);
|
||||
}
|
||||
}
|
||||
IPage<UserPointRankingVO> voiPage = userPointsDetailsMapper.userRanking(page, startTime, endTime, dto);
|
||||
List<String> userIds = voiPage.getRecords().stream().map(UserPointRankingVO::getUserId).collect(Collectors.toList());
|
||||
List<LoginUser> loginUsers = iSysBaseAPI.listUserByIdsNew(userIds);
|
||||
voiPage.getRecords().forEach(vo -> {
|
||||
loginUsers.forEach(loginUser -> {
|
||||
if (vo.getUserId().equals(loginUser.getId())) {
|
||||
vo.setRealName(loginUser.getRealname());
|
||||
vo.setAvatar(loginUser.getAvatar());
|
||||
vo.setSex(loginUser.getSex());
|
||||
vo.setSexName(ObjectUtil.isNotNull(loginUser.getSex()) && loginUser.getSex().equals(1) ? "女" : "男");
|
||||
vo.setWorkNo(loginUser.getWorkNo());
|
||||
vo.setAge(ObjectUtil.isNotNull(loginUser.getAge()) && loginUser.getAge() > 0 ? loginUser.getAge() : null);
|
||||
SysDepart secondDepart = sysCache.getDepartByOrgCode(GlobalUtils.getSecondDepartOrgCode(loginUser.getOrgCode()));
|
||||
if (ObjectUtil.isNotEmpty(secondDepart)) {
|
||||
vo.setDeptName(secondDepart.getDepartName());
|
||||
}
|
||||
SysDepart thirdDepart = sysCache.getDepartByOrgCode(GlobalUtils.getThirdDepartOrgCode(loginUser.getOrgCode()));
|
||||
if (ObjectUtil.isNotEmpty(thirdDepart)) {
|
||||
vo.setOrgName(thirdDepart.getDepartName());
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
return voiPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportUserRanking(UserPointsRankingDTO dto) {
|
||||
GenericExportHandler<UserPointRankingVO, UserPointsRankingDTO> handler =
|
||||
new GenericExportHandler<>(
|
||||
UserPointRankingVO.class,
|
||||
ExportExcelEnum.BANK_USER_RANKING,
|
||||
asyncTaskExecutor,
|
||||
log,
|
||||
filter -> {
|
||||
filter.setPageNo(1);
|
||||
filter.setPageSize(-1);
|
||||
List<UserPointRankingVO> records = userRanking(filter).getRecords();
|
||||
return GenericExportHandler.handleData(records, UserPointRankingVO.class);
|
||||
}
|
||||
);
|
||||
handler.exportAsync(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean testUpdateUserPoints(UpdUserPointsDTO dto) {
|
||||
List<String> sysUserIds = iSysBaseAPI.findSysUserIds(new SysUser());
|
||||
List<LoginUser> loginUsers = iSysBaseAPI.listUserByIdsNew(sysUserIds);
|
||||
loginUsers.forEach(user -> {
|
||||
try {
|
||||
updateUserPoints(dto, user);
|
||||
} catch (Exception e) {
|
||||
log.error("用户:{}({})更新积分异常,入参:{}", user.getRealname(), user.getUsername(), dto, e);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户积分
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
public boolean updateUserPoints(UpdUserPointsDTO dto, LoginUser loginUser) {
|
||||
log.info("------用户:{}({})开始更新积分,入参:{}------", loginUser.getRealname(), loginUser.getUsername(), dto);
|
||||
PointsSourceEnum sourceEnum = PointsSourceEnum.getBySource(dto.getSourceType());
|
||||
if (sourceEnum == null) {
|
||||
log.error("积分类型不存在");
|
||||
ExceptionAssertsUtil.fail("积分类型不存在");
|
||||
}
|
||||
String userId;
|
||||
if (dto.getSourceType().equals(PointsSourceEnum.TYPE_2_VIOLATION.getSource())) {
|
||||
if (StringUtils.isBlank(dto.getUserId())) {
|
||||
log.error("扣减用户id不能为空");
|
||||
ExceptionAssertsUtil.fail("扣减用户id不能为空");
|
||||
}
|
||||
//违规扣除
|
||||
userId = dto.getUserId();
|
||||
} else {
|
||||
userId = loginUser.getId();
|
||||
}
|
||||
UserPoints userPoints = baseMapper.selectOne(new LambdaQueryWrapper<UserPoints>()
|
||||
.eq(UserPoints::getUserId, userId)
|
||||
);
|
||||
boolean isAdd = false;
|
||||
Date date = new Date();
|
||||
UserPointsDetails userPointsDetails = new UserPointsDetails();
|
||||
if (userPoints == null) {
|
||||
isAdd = true;
|
||||
userPoints = new UserPoints();
|
||||
userPoints.setUserId(userId);
|
||||
userPoints.setOrgCode(loginUser.getOrgCode());
|
||||
userPoints.setCreateTime(date);
|
||||
userPointsDetails.setBeforePoints(new BigDecimal(0));
|
||||
} else {
|
||||
userPointsDetails.setBeforePoints(userPoints.getPoints());
|
||||
}
|
||||
userPointsDetails.setUserId(userId);
|
||||
switch (sourceEnum) {
|
||||
case TYPE_1_SURVEY:
|
||||
// 积分打卡
|
||||
PointsRule pointsRule = pointsRuleMapper.selectById(dto.getBusinessId());
|
||||
if (pointsRule == null) {
|
||||
log.error("积分规则不存在");
|
||||
ExceptionAssertsUtil.fail("积分规则不存在");
|
||||
}
|
||||
checkUserPoints(pointsRule, userId);
|
||||
userPointsDetails.setPoints(pointsRule.getPoints());
|
||||
userPointsDetails.setChangeType(HealthBankConstants.CHANGE_TYPE_ADD);
|
||||
userPointsDetails.setSource(sourceEnum.getSource());
|
||||
userPointsDetails.setBusinessId(dto.getBusinessId());
|
||||
userPointsDetails.setBusinessInfo(pointsRule.getRuleDesc());
|
||||
userPointsDetails.setOperatorId(userId);
|
||||
if (StringUtils.isNotBlank(dto.getRemark())) {
|
||||
userPointsDetails.setRemark(dto.getRemark());
|
||||
}
|
||||
if (isAdd) {
|
||||
userPoints.setPoints(pointsRule.getPoints());
|
||||
userPoints.setAddPointsSum(userPoints.getPoints());
|
||||
userPoints.setDeductPointsSum(BigDecimal.valueOf(0));
|
||||
userPoints.setLatestAddDaySum(userPoints.getPoints());
|
||||
userPoints.setLatestDeductDaySum(BigDecimal.valueOf(0));
|
||||
userPoints.setLastAddDate(date);
|
||||
} else {
|
||||
userPoints.setPoints(userPoints.getPoints().add(pointsRule.getPoints()));
|
||||
userPoints.setAddPointsSum(userPoints.getAddPointsSum().add(pointsRule.getPoints()));
|
||||
List<UserPointsDetails> details = userPointsDetailsMapper.selectList(new LambdaQueryWrapper<UserPointsDetails>()
|
||||
.eq(UserPointsDetails::getUserId, userId)
|
||||
.eq(UserPointsDetails::getChangeType, HealthBankConstants.CHANGE_TYPE_ADD)
|
||||
.apply("DATE_FORMAT(create_time, '%Y-%m-%d') = {0}", DateUtil.today())
|
||||
);
|
||||
double sum = details.stream().map(UserPointsDetails::getPoints).mapToDouble(BigDecimal::doubleValue).sum();
|
||||
userPoints.setLatestAddDaySum(BigDecimal.valueOf(sum).add(pointsRule.getPoints()));
|
||||
}
|
||||
break;
|
||||
case TYPE_2_USE:
|
||||
// 礼品兑换
|
||||
userPoints.setLastDeductDate(date);
|
||||
break;
|
||||
case TYPE_2_VIOLATION:
|
||||
// 违规扣除
|
||||
if (isAdd) {
|
||||
ExceptionAssertsUtil.fail("用户积分不存在");
|
||||
}
|
||||
userPoints.setDeductPointsSum(userPoints.getDeductPointsSum().add(dto.getPoints()));
|
||||
BigDecimal subtract = userPoints.getPoints().subtract(dto.getPoints());
|
||||
userPoints.setPoints(subtract.compareTo(BigDecimal.valueOf(0)) < 0 ? BigDecimal.valueOf(0) : subtract);
|
||||
userPointsDetails.setPoints(dto.getPoints());
|
||||
userPointsDetails.setRemark(dto.getRemark());
|
||||
userPointsDetails.setSource(sourceEnum.getSource());
|
||||
userPointsDetails.setChangeType(HealthBankConstants.CHANGE_TYPE_DEDUCT);
|
||||
userPointsDetails.setOperatorId(GlobalUtils.getLoginUser().getId());
|
||||
break;
|
||||
case TYPE_2_EXPIRED:
|
||||
// 过期清除
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
userPointsDetails.setCreateTime(date);
|
||||
userPointsDetails.setAfterPoints(userPoints.getPoints());
|
||||
userPoints.setLastVaryDate(date);
|
||||
boolean b = this.saveOrUpdate(userPoints);
|
||||
if (b) {
|
||||
b = userPointsDetailsMapper.insert(userPointsDetails) > 0;
|
||||
}
|
||||
log.info("======用户:{}({})更新积分结果:{}======", loginUser.getRealname(), loginUser.getUsername(), b);
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户积分
|
||||
*
|
||||
* @param pointsRule 积分规则
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
public void checkUserPoints(PointsRule pointsRule, String userId) {
|
||||
LambdaQueryWrapper<UserPointsDetails> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(UserPointsDetails::getUserId, userId);
|
||||
wrapper.eq(UserPointsDetails::getBusinessId, pointsRule.getId());
|
||||
Long c;
|
||||
Date date = new Date();
|
||||
switch (pointsRule.getFrequency()) {
|
||||
// 单次:检查用户是否已经获得过该积分
|
||||
case 1:
|
||||
break;
|
||||
// 日/次:检查用户当天是否已经获得过该积分
|
||||
case 2:
|
||||
DateTime startOfDay = DateUtil.beginOfDay(date);
|
||||
DateTime endOfDay = DateUtil.endOfDay(date);
|
||||
wrapper.between(UserPointsDetails::getCreateTime, startOfDay, endOfDay);
|
||||
c = userPointsDetailsMapper.selectCount(wrapper);
|
||||
if (c > 0) {
|
||||
ExceptionAssertsUtil.fail("今日已获得该积分");
|
||||
}
|
||||
break;
|
||||
// 周/次:检查用户本周是否已经获得过该积分
|
||||
case 3:
|
||||
DateTime startOfWeek = DateUtil.beginOfWeek(date);
|
||||
DateTime endOfWeek = DateUtil.endOfWeek(date);
|
||||
wrapper.between(UserPointsDetails::getCreateTime, startOfWeek, endOfWeek);
|
||||
c = userPointsDetailsMapper.selectCount(wrapper);
|
||||
if (c > 0) {
|
||||
ExceptionAssertsUtil.fail("本周已获得该积分");
|
||||
}
|
||||
break;
|
||||
// 月/次:检查用户本月是否已经获得过该积分
|
||||
case 4:
|
||||
DateTime startOfMonth = DateUtil.beginOfMonth(date);
|
||||
DateTime endOfMonth = DateUtil.endOfMonth(date);
|
||||
wrapper.between(UserPointsDetails::getCreateTime, startOfMonth, endOfMonth);
|
||||
c = userPointsDetailsMapper.selectCount(wrapper);
|
||||
if (c > 0) {
|
||||
ExceptionAssertsUtil.fail("本月已获得该积分");
|
||||
}
|
||||
break;
|
||||
// 季度/次:检查用户本季度是否已经获得过该积分
|
||||
case 5:
|
||||
DateTime startOfQuarter = DateUtil.beginOfQuarter(date);
|
||||
DateTime endOfQuarter = DateUtil.endOfQuarter(date);
|
||||
wrapper.between(UserPointsDetails::getCreateTime, startOfQuarter, endOfQuarter);
|
||||
c = userPointsDetailsMapper.selectCount(wrapper);
|
||||
if (c > 0) {
|
||||
ExceptionAssertsUtil.fail("本季度已获得该积分");
|
||||
}
|
||||
break;
|
||||
// 年/次:检查用户本年度是否已经获得过该积分
|
||||
case 6:
|
||||
DateTime startOfYear = DateUtil.beginOfYear(date);
|
||||
DateTime endOfYear = DateUtil.endOfYear(date);
|
||||
wrapper.between(UserPointsDetails::getCreateTime, startOfYear, endOfYear);
|
||||
c = userPointsDetailsMapper.selectCount(wrapper);
|
||||
if (c > 0) {
|
||||
ExceptionAssertsUtil.fail("本年已获得该积分");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// 未知规则类型,默认不处理
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* app我的积分
|
||||
*
|
||||
* @return 积分信息
|
||||
*/
|
||||
@Override
|
||||
public UserPointsInfoVO myPoints() {
|
||||
String userId = GlobalUtils.getLoginUser().getId();
|
||||
UserPoints userPoints = baseMapper.selectOne(new LambdaQueryWrapper<UserPoints>()
|
||||
.eq(UserPoints::getUserId, userId)
|
||||
);
|
||||
UserPointsInfoVO vo = new UserPointsInfoVO();
|
||||
if (userPoints != null) {
|
||||
vo.setPoints(userPoints.getPoints());
|
||||
vo.setAddPointsSum(userPoints.getAddPointsSum());
|
||||
vo.setExchangePointsSum(userPoints.getExchangePointsSum());
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* app积分任务
|
||||
*
|
||||
* @return 列表
|
||||
*/
|
||||
@Override
|
||||
public List<UserPointsTaskVO> pointsTaskList() {
|
||||
String userId = GlobalUtils.getLoginUser().getId();
|
||||
return pointsRuleMapper.pointsTaskList(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* app积分打卡
|
||||
*
|
||||
* @param dto 参数
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public boolean pointCheckIn(UpdUserPointsDTO dto) {
|
||||
dto.setSourceType(PointsSourceEnum.TYPE_1_SURVEY.getSource());
|
||||
LoginUser loginUser = GlobalUtils.getLoginUser();
|
||||
return updateUserPoints(dto, loginUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* app积分明细
|
||||
*
|
||||
* @param dto 参数
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public IPage<UserPointRecordVO> pointRecord(UserPointsPageDTO dto) {
|
||||
if (ObjectUtil.isNull(dto.getChangeType())) {
|
||||
ExceptionAssertsUtil.fail("收支类型不能为空");
|
||||
}
|
||||
String userId = GlobalUtils.getLoginUser().getId();
|
||||
Page<UserPointRecordVO> page = new Page<>(dto.getPageNo(), dto.getPageSize());
|
||||
MPJLambdaWrapper<UserPointsDetails> wrapper = new MPJLambdaWrapper<>();
|
||||
wrapper.eq(UserPointsDetails::getUserId, userId);
|
||||
wrapper.eq(UserPointsDetails::getChangeType, dto.getChangeType());
|
||||
wrapper.orderByDesc(UserPointsDetails::getCreateTime);
|
||||
return userPointsDetailsMapper.selectJoinPage(page, UserPointRecordVO.class, wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* app积分榜单
|
||||
*
|
||||
* @param dto 参数
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public IPage<UserPointRankingVO> pointRanking(UserPointsRankingDTO dto) {
|
||||
String orgCode = GlobalUtils.getLoginUser().getOrgCode();
|
||||
String secondOrgCode = GlobalUtils.getSecondDepartOrgCode(orgCode);
|
||||
Page<UserPointRankingVO> page = new Page<>(dto.getPageNo(), dto.getPageSize());
|
||||
Date startTime = null;
|
||||
Date endTime = null;
|
||||
Date now = new Date();
|
||||
if (StringUtils.isNotBlank(dto.getRankType())) {
|
||||
if ("1".equals(dto.getRankType())) {
|
||||
// 获取本周的开始时间(周一)
|
||||
startTime = DateUtil.beginOfWeek(now, true);
|
||||
// 获取本周的结束时间(周日)
|
||||
endTime = DateUtil.endOfWeek(now, true);
|
||||
} else if ("2".equals(dto.getRankType())) {
|
||||
// 获取本月的开始时间
|
||||
startTime = DateUtil.beginOfMonth(now);
|
||||
// 获取本月的结束时间
|
||||
endTime = DateUtil.endOfMonth(now);
|
||||
}
|
||||
}
|
||||
IPage<UserPointRankingVO> voiPage = userPointsDetailsMapper.pointRanking(page, startTime, endTime, secondOrgCode);
|
||||
List<String> userIds = voiPage.getRecords().stream().map(UserPointRankingVO::getUserId).collect(Collectors.toList());
|
||||
List<LoginUser> loginUsers = iSysBaseAPI.listUserByIdsNew(userIds);
|
||||
voiPage.getRecords().forEach(vo -> {
|
||||
loginUsers.forEach(loginUser -> {
|
||||
if (vo.getUserId().equals(loginUser.getId())) {
|
||||
vo.setRealName(loginUser.getRealname());
|
||||
vo.setAvatar(loginUser.getAvatar());
|
||||
vo.setSex(loginUser.getSex());
|
||||
SysDepart secondDepart = sysCache.getDepartByOrgCode(GlobalUtils.getSecondDepartOrgCode(loginUser.getOrgCode()));
|
||||
if (ObjectUtil.isNotEmpty(secondDepart)) {
|
||||
vo.setDeptName(secondDepart.getDepartName());
|
||||
}
|
||||
SysDepart thirdDepart = sysCache.getDepartByOrgCode(GlobalUtils.getThirdDepartOrgCode(loginUser.getOrgCode()));
|
||||
if (ObjectUtil.isNotEmpty(thirdDepart)) {
|
||||
vo.setOrgName(thirdDepart.getDepartName());
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
return voiPage;
|
||||
}
|
||||
}
|
||||
+5
@@ -1,5 +1,6 @@
|
||||
package com.renkang.consultation.dto;
|
||||
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import com.renkang.consultation.entity.ConPage;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
@@ -11,6 +12,10 @@ public class AccountDTO extends ConPage {
|
||||
@Schema(title = "专家姓名")
|
||||
private String doctorName;
|
||||
|
||||
public void setDoctorName(String doctorName) {
|
||||
this.doctorName = doctorName != null ? HtmlUtil.unescape(doctorName) : null;
|
||||
}
|
||||
|
||||
@Schema(title = "医院选择")
|
||||
private String hospitalName;
|
||||
|
||||
|
||||
+5
@@ -1,5 +1,6 @@
|
||||
package com.renkang.consultation.dto;
|
||||
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import com.renkang.consultation.entity.ConPage;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
@@ -10,6 +11,10 @@ public class ConDoctorDTO extends ConPage {
|
||||
|
||||
@Schema(title = "专家姓名")
|
||||
private String doctorName;
|
||||
|
||||
public void setDoctorName(String doctorName) {
|
||||
this.doctorName = doctorName != null ? HtmlUtil.unescape(doctorName) : null;
|
||||
}
|
||||
@Schema(title = "专家编号")
|
||||
private String doctorNo;
|
||||
|
||||
|
||||
+8
@@ -1,5 +1,6 @@
|
||||
package com.renkang.consultation.dto;
|
||||
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.renkang.consultation.entity.ConPage;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
@@ -17,6 +18,9 @@ public class ConEvaluateDTO extends ConPage {
|
||||
|
||||
@Schema(title = "咨询人")
|
||||
private String userName;
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName != null ? HtmlUtil.unescape(userName) : null;
|
||||
}
|
||||
|
||||
@Schema(title = "二级单位id")
|
||||
private String sysOrgSecondId;
|
||||
@@ -27,6 +31,10 @@ public class ConEvaluateDTO extends ConPage {
|
||||
@Schema(title = "咨询专家")
|
||||
private String expertName;
|
||||
|
||||
public void setExpertName(String expertName) {
|
||||
this.expertName = expertName != null ? HtmlUtil.unescape(expertName) : null;
|
||||
}
|
||||
|
||||
@Schema(title = "专家医院")
|
||||
private String expertHospital;
|
||||
|
||||
|
||||
+5
@@ -1,5 +1,6 @@
|
||||
package com.renkang.consultation.dto;
|
||||
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import com.renkang.consultation.entity.ConPage;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
@@ -10,6 +11,10 @@ public class ConHealthInfoAnswerDTO extends ConPage {
|
||||
@Schema(title = "员工姓名")
|
||||
private String fromName;
|
||||
|
||||
public void setFromName(String fromName) {
|
||||
this.fromName = fromName != null ? HtmlUtil.unescape(fromName) : null;
|
||||
}
|
||||
|
||||
@Schema(title = "手机号")
|
||||
private String phone;
|
||||
|
||||
|
||||
+5
@@ -1,5 +1,6 @@
|
||||
package com.renkang.consultation.dto;
|
||||
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import com.renkang.consultation.entity.ConPage;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
@@ -11,6 +12,10 @@ public class ConHelperDTO extends ConPage {
|
||||
@Schema(title = "全科医生姓名")
|
||||
private String userName;
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName != null ? HtmlUtil.unescape(userName) : null;
|
||||
}
|
||||
|
||||
@Schema(title = "状态")
|
||||
private Integer status;
|
||||
|
||||
|
||||
+9
@@ -1,5 +1,6 @@
|
||||
package com.renkang.consultation.dto;
|
||||
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.renkang.consultation.entity.ConPage;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
@@ -17,6 +18,10 @@ public class ConSessionDTO extends ConPage {
|
||||
@Schema(title = "员工姓名")
|
||||
private String fromName;
|
||||
|
||||
public void setFromName(String fromName) {
|
||||
this.fromName = fromName != null ? HtmlUtil.unescape(fromName) : null;
|
||||
}
|
||||
|
||||
@Schema(title = "员工id")
|
||||
private String fromAccount;
|
||||
|
||||
@@ -26,6 +31,10 @@ public class ConSessionDTO extends ConPage {
|
||||
@Schema(title = "专家姓名")
|
||||
private String doctorName;
|
||||
|
||||
public void setDoctorName(String doctorName) {
|
||||
this.doctorName = doctorName != null ? HtmlUtil.unescape(doctorName) : null;
|
||||
}
|
||||
|
||||
@Schema(title = "咨询状态(0待确认 1接收预约 2拒绝预约 3已过期 4已取消 5咨询中 6专家咨询结束 7员工咨询结束 8超时自动结束)")
|
||||
private String contentStatus;
|
||||
|
||||
|
||||
+6
@@ -480,4 +480,10 @@ public class ConSessionApiController {
|
||||
return conSessionApiService.insertUserAndHelperSessionNew();
|
||||
}
|
||||
|
||||
@Operation(summary = "超时关闭视频咨询", description = "超时关闭视频咨询")
|
||||
@GetMapping("/endVideoSession")
|
||||
public Result<String> endVideoSession() {
|
||||
return Result.ok(conSessionApiService.endVideoSession());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
@@ -115,4 +115,6 @@ public interface ConSessionApiService {
|
||||
|
||||
UserSessionCount countForUser();
|
||||
|
||||
String endVideoSession();
|
||||
|
||||
}
|
||||
|
||||
+4
@@ -2114,4 +2114,8 @@ public class ConSessionApiServiceImpl implements ConSessionApiService {
|
||||
return conSessionMapper.selectCount(wrapper).intValue();
|
||||
}
|
||||
|
||||
public String endVideoSession() {
|
||||
return conSessionMapper.endVideoSession();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
@@ -484,4 +484,9 @@ public class ConSessionController extends JeecgController<ConSession, IConSessio
|
||||
return conSessionService.exportXlsConSession(request, dto);
|
||||
}
|
||||
|
||||
@GetMapping("/getPicUrl")
|
||||
public Result<String> getPicUrl(){
|
||||
return Result.ok(conSessionService.getPicUrl());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
@@ -294,4 +294,13 @@ public interface ConSessionMapper extends BaseMapper<ConSession> , MPJBaseMapper
|
||||
@Param("doctorjob")String doctorjob,
|
||||
@Param("contentType")String contentType,
|
||||
@Param("toAccount")String toAccount);
|
||||
|
||||
/**
|
||||
* 音视频咨询过期处理:预约日期已过的视频咨询,有通话记录则改为待评价,无通话记录则改为取消
|
||||
* content_status: 4=待评价,6=取消
|
||||
*/
|
||||
@Update("UPDATE con_session SET content_status = CASE WHEN session_time IS NOT NULL THEN 4 ELSE 6 END " +
|
||||
"WHERE content_type = 2 AND CURDATE() > session_date " +
|
||||
"AND content_status NOT IN (4, 5, 6, 7, 8) AND del_flag = 0 AND status = 1")
|
||||
String endVideoSession();
|
||||
}
|
||||
|
||||
+2
@@ -85,5 +85,7 @@ public interface IConSessionService extends IService<ConSession> {
|
||||
Result<List<com.renkang.im.entity.ImMsgRecordAll>> selectImMessageList(String groupId);
|
||||
|
||||
Result<?> exportXlsConSession(HttpServletRequest request, ConSessionDTO dto);
|
||||
|
||||
String getPicUrl();
|
||||
}
|
||||
|
||||
|
||||
-4
@@ -3,7 +3,6 @@ package com.renkang.consultation.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
@@ -249,9 +248,6 @@ public class ConDoctorServiceImpl extends ServiceImpl<ConDoctorMapper, ConDoctor
|
||||
if (StringUtils.hasLength(dto.getHospitalName())) {
|
||||
conDoctor.setResourceId(dto.getHospitalName());
|
||||
}
|
||||
if (StrUtil.isNotEmpty(dto.getDoctorName())){
|
||||
conDoctor.setDoctorName(HtmlUtil.unescape(dto.getDoctorName()));
|
||||
}
|
||||
IPage<ConDoctor> conDoctorIPage = conDoctorMapper.queryPageList(page, conDoctor);
|
||||
List<ConDoctor> conDoctorList = conDoctorIPage.getRecords();
|
||||
if (CollectionUtils.isEmpty(conDoctorList)) {
|
||||
|
||||
+7
@@ -52,6 +52,7 @@ import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
|
||||
import org.jeecgframework.poi.exception.excel.enums.ExcelExportEnum;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -1264,5 +1265,11 @@ public class ConSessionServiceImpl extends ServiceImpl<ConSessionMapper, ConSess
|
||||
return sendTime;
|
||||
}
|
||||
|
||||
@Value("${banner.picUrl:}")
|
||||
private String bannerPicUrl;
|
||||
public String getPicUrl(){
|
||||
// 读取配置文件的url
|
||||
return bannerPicUrl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
@@ -7,6 +7,7 @@ import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.context.XxlJobHelper;
|
||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.config.shiro.ClientSignThreadLocal;
|
||||
import org.parboiled.common.StringUtils;
|
||||
@@ -53,4 +54,12 @@ public class SyncScheduleJob {
|
||||
return ReturnT.SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@XxlJob(value = "endVideoSession")
|
||||
public Result<String> endVideoSession() {
|
||||
// 20260327 新增 音视频咨询过期处理 规则为:超过预约时间,比如预约的是 12月9日和专家视频沟通,但超过时间一天,即为过期,需要关闭咨询
|
||||
conSessionApiController.endVideoSession();
|
||||
return Result.ok("success");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
@@ -1,5 +1,6 @@
|
||||
package com.renkang.emergency.entity.dto;
|
||||
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@@ -7,6 +8,10 @@ import lombok.Data;
|
||||
public class CallLogDTO {
|
||||
@Schema(description = "姓名")
|
||||
private String realName;
|
||||
|
||||
public void setRealName(String realName) {
|
||||
this.realName = realName != null ? HtmlUtil.unescape(realName) : null;
|
||||
}
|
||||
@Schema(description = "呼叫中心")
|
||||
private String centerId;
|
||||
@Schema(description = "坐席工号")
|
||||
|
||||
+5
@@ -1,5 +1,6 @@
|
||||
package com.renkang.emergency.entity.dto;
|
||||
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
@@ -21,6 +22,10 @@ public class PhoneListDTO {
|
||||
private String phoneType;
|
||||
@Schema(description = "姓名")
|
||||
private String realName;
|
||||
|
||||
public void setRealName(String realName) {
|
||||
this.realName = realName != null ? HtmlUtil.unescape(realName) : null;
|
||||
}
|
||||
/**
|
||||
* 0:全部 1:女 2:男
|
||||
*/
|
||||
|
||||
+5
@@ -1,5 +1,6 @@
|
||||
package com.renkang.emergency.entity.dto;
|
||||
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@@ -9,6 +10,10 @@ public class TblQimoNoticeDTO {
|
||||
private String seatId;
|
||||
@Schema(title = "姓名")
|
||||
private String realName;
|
||||
|
||||
public void setRealName(String realName) {
|
||||
this.realName = realName != null ? HtmlUtil.unescape(realName) : null;
|
||||
}
|
||||
@Schema(title = "所属应急中心")
|
||||
private String centerId;
|
||||
@Schema(title = "orgCode")
|
||||
|
||||
+2
@@ -1,6 +1,7 @@
|
||||
package com.renkang.emergency.controller;
|
||||
|
||||
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.renkang.emergency.entity.EmergencyProfessionUser;
|
||||
import com.renkang.emergency.service.EmergencyProfessionUserService;
|
||||
@@ -40,6 +41,7 @@ public class EmergencyProfessionUserController {
|
||||
@RequestParam(name = "type", defaultValue = "5") Integer type,
|
||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
name = HtmlUtil.unescape(name);
|
||||
IPage<EmergencyProfessionUser> pageList = emergencyProfessionUserService.customPage(name, centerId, type, pageNo, pageSize);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
+4
@@ -6,6 +6,7 @@ import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
@@ -58,6 +59,9 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||
|
||||
@Override
|
||||
public IPage<Order> pageCustom(Page<Order> page, Order order, HttpServletRequest req) {
|
||||
if(StrUtil.isNotBlank(order.getSalvageUserName())){
|
||||
order.setSalvageUserName(HtmlUtil.unescape(order.getSalvageUserName()));
|
||||
}
|
||||
String salvageUserName = order.getSalvageUserName();
|
||||
String initiatorUserName = order.getInitiatorUserName();
|
||||
Order orderCopy = new Order();
|
||||
|
||||
+4
@@ -22,6 +22,10 @@ public class WatchH5IndexItemNewVo {
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private Date dataDate;
|
||||
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date dataDateNew;
|
||||
/**
|
||||
* 注意 当wdType=sleep时此字段返回长睡时长
|
||||
*/
|
||||
|
||||
+4
@@ -1,5 +1,6 @@
|
||||
package com.renkang.watch.bean.request;
|
||||
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
@@ -19,6 +20,9 @@ public class AbnormalEventFilter {
|
||||
private String departOrgCode;
|
||||
// 用户名称
|
||||
private String userName;
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName != null ? HtmlUtil.unescape(userName) : null;
|
||||
}
|
||||
// 工具编码
|
||||
private String watchNo;
|
||||
//员工编号
|
||||
|
||||
+15
@@ -35,6 +35,7 @@ public class AbnormalEvent extends BaseUser {
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "报警时间", format = "yyyy-MM-dd HH:mm:ss", width = 15, orderNum = "10")
|
||||
private Date warnTime;
|
||||
@Excel(name = "回传时间", format = "yyyy-MM-dd HH:mm:ss", width = 15, orderNum = "11")
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(title = "创建日期")
|
||||
@@ -51,4 +52,18 @@ public class AbnormalEvent extends BaseUser {
|
||||
private Date bindDate;
|
||||
@Schema(title = "重点指标用户(0:非重点指标用户 1:大病异常 2:慢病异常 3:指标异常)")
|
||||
private List<WatchKeyUser> keyUserList;
|
||||
/**
|
||||
* 事件ID(用于告警事件与GPS位置更新关联的唯一标识)
|
||||
*/
|
||||
@Excel(name = "事件ID", width = 32, orderNum = "12")
|
||||
@Schema(title = "事件ID")
|
||||
private String eventId;
|
||||
/**
|
||||
* 定位时间(手表定时上报的GPS定位时间)
|
||||
*/
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "定位时间", format = "yyyy-MM-dd HH:mm:ss", width = 20, orderNum = "13")
|
||||
@Schema(title = "定位时间")
|
||||
private Date locateTime;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.renkang.watch.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author TianZi
|
||||
* @date 2023/11/7 14:13
|
||||
*/
|
||||
@Data
|
||||
public class BindDeviceDTO {
|
||||
|
||||
@Schema(title = "手表编号")
|
||||
private String watchNo;
|
||||
}
|
||||
+5
@@ -1,5 +1,6 @@
|
||||
package com.renkang.watch.dto;
|
||||
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
@@ -18,6 +19,10 @@ public class CalorieDataByUserDTO {
|
||||
private Integer pageSize = 10;
|
||||
@Schema(title = "用户姓名")
|
||||
private String realName;
|
||||
|
||||
public void setRealName(String realName) {
|
||||
this.realName = realName != null ? HtmlUtil.unescape(realName) : null;
|
||||
}
|
||||
@Schema(title = "工号")
|
||||
private String workNo;
|
||||
@Schema(title = "用户id组")
|
||||
|
||||
+14
@@ -151,6 +151,20 @@ public class WatchMonitorData implements Serializable {
|
||||
@Excel(name = "部门编码", width = 15)
|
||||
@Schema(title = "部门编码")
|
||||
private java.lang.String orgCode;
|
||||
/**
|
||||
* 事件ID(用于告警事件与GPS位置更新关联的唯一标识)
|
||||
*/
|
||||
@Excel(name = "事件ID", width = 32)
|
||||
@Schema(title = "事件ID")
|
||||
private java.lang.String eventId;
|
||||
/**
|
||||
* 定位时间(手表上报的GPS定位时间,定时上报场景使用)
|
||||
*/
|
||||
@Excel(name = "定位时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(title = "定位时间")
|
||||
private java.util.Date locateTime;
|
||||
|
||||
@Schema(title = "员工编号")
|
||||
@TableField(exist = false)
|
||||
|
||||
+51
-2
@@ -1,22 +1,71 @@
|
||||
package com.renkang.watch.vo.UserData.res;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.renkang.watch.WatchH5IndexItemNewVo;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/** 用户统计数据
|
||||
/**
|
||||
* 用户统计数据
|
||||
*
|
||||
* @author stan
|
||||
* @since 2024-11-04 16:33
|
||||
*/
|
||||
@Data
|
||||
public class UserStat {
|
||||
/**
|
||||
* 数据类型:0=心率 1=血氧 2=压力 3=体温 4=睡眠
|
||||
*/
|
||||
private String type;
|
||||
private BigDecimal latest;
|
||||
private BigDecimal max;
|
||||
private BigDecimal min;
|
||||
private BigDecimal avg;
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date latestTime;
|
||||
|
||||
public UserStat() {
|
||||
}
|
||||
|
||||
public UserStat(WatchH5IndexItemNewVo watchH5IndexItemNewVo) {
|
||||
switch (watchH5IndexItemNewVo.getWdType()) {
|
||||
case "sleep":
|
||||
this.type = "4";
|
||||
break;
|
||||
case "heart_rate":
|
||||
this.type = "0";
|
||||
break;
|
||||
case "stress":
|
||||
this.type = "2";
|
||||
break;
|
||||
case "spo2":
|
||||
this.type = "1";
|
||||
break;
|
||||
case "temperature":
|
||||
this.type = "3";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this.latest = parseSafe(watchH5IndexItemNewVo.getDataValue());
|
||||
this.max = parseSafe(watchH5IndexItemNewVo.getDataMax());
|
||||
this.min = parseSafe(watchH5IndexItemNewVo.getDataMin());
|
||||
this.avg = parseSafe(watchH5IndexItemNewVo.getDataAvg());
|
||||
this.latestTime = watchH5IndexItemNewVo.getDataDateNew();
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全解析字符串为 BigDecimal,入参为 null 或空串时返回 null
|
||||
*
|
||||
* @param value 待解析的字符串数值
|
||||
* @return 解析结果,无效输入返回 null
|
||||
*/
|
||||
private static BigDecimal parseSafe(String value) {
|
||||
if (value == null || value.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return BigDecimal.valueOf(Double.parseDouble(value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,4 +45,15 @@ public class WatchNotifyVo implements Serializable {
|
||||
private Date warnTime;
|
||||
|
||||
private String gpsErrorMsg;
|
||||
|
||||
/**
|
||||
* 事件ID(用于告警事件与GPS位置更新关联的唯一标识)
|
||||
*/
|
||||
private String eventId;
|
||||
|
||||
/**
|
||||
* 定位时间(手表上报的GPS定位时间,定时上报场景使用)
|
||||
*/
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date locateTime;
|
||||
}
|
||||
|
||||
+12
-10
@@ -18,9 +18,14 @@ public class DeptStatData {
|
||||
/**
|
||||
* 已分配设备数
|
||||
*/
|
||||
@Excel(name = "分配设备数", width = 15,orderNum = "4")
|
||||
@Excel(name = "已分配设备数", width = 15,orderNum = "4")
|
||||
private Integer assignedDeviceNums;
|
||||
|
||||
/**
|
||||
* 未分配设备数(入库设备数 - 已分配设备数,仅一、二级部门有值)
|
||||
*/
|
||||
@Excel(name = "未分配设备数", width = 15,orderNum = "5")
|
||||
private Integer undistributedDeviceNums;
|
||||
|
||||
@Excel(name = "入库设备数", width = 15,orderNum = "3")
|
||||
private Integer totalAssignedDeviceNums;
|
||||
@@ -28,25 +33,22 @@ public class DeptStatData {
|
||||
/**
|
||||
* 佩戴人员数
|
||||
*/
|
||||
@Excel(name = "佩戴人员数", width = 15,orderNum = "5")
|
||||
@Excel(name = "佩戴人员数", width = 15,orderNum = "6")
|
||||
private Integer assignedUserNums;
|
||||
/**
|
||||
* 未佩戴人员数
|
||||
*/
|
||||
@Excel(name = "未佩戴人员数", width = 15,orderNum = "6")
|
||||
@Excel(name = "未佩戴人员数", width = 15,orderNum = "7")
|
||||
private Integer undistributedUserNums;
|
||||
|
||||
@Excel(name = "心率异常人数", width = 15,orderNum = "7")
|
||||
@Excel(name = "心率异常人数", width = 15,orderNum = "8")
|
||||
private Integer heartRateNums;
|
||||
@Excel(name = "血氧异常人数", width = 15,orderNum = "8")
|
||||
@Excel(name = "血氧异常人数", width = 15,orderNum = "9")
|
||||
private Integer spo2Nums;
|
||||
@Excel(name = "压力异常人数", width = 15,orderNum = "9")
|
||||
@Excel(name = "压力异常人数", width = 15,orderNum = "10")
|
||||
private Integer stressNums;
|
||||
@Excel(name = "体温异常人数", width = 15,orderNum = "10")
|
||||
@Excel(name = "体温异常人数", width = 15,orderNum = "11")
|
||||
private Integer tempNums;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+11
@@ -20,6 +20,7 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@@ -41,6 +42,16 @@ public class WatchDataApiController {
|
||||
return Result.ok(watchDataApiService.userStatResult(type));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户手表数据(批量返回)
|
||||
*
|
||||
* @return data
|
||||
*/
|
||||
@GetMapping("userWatchDataAll")
|
||||
public Result<List<UserStat>> userStatResultAll(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") Date date) {
|
||||
return Result.ok(watchDataApiService.userStatResultAll(date));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户此刻是否拥有手表
|
||||
*
|
||||
|
||||
+9
@@ -11,6 +11,7 @@ import com.renkang.watch.vo.UserData.res.sleep.WatchDataSleepRes;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface WatchDataApiService {
|
||||
@@ -43,6 +44,14 @@ public interface WatchDataApiService {
|
||||
|
||||
UserStat userStatResult(String type);
|
||||
|
||||
/**
|
||||
* 查询当前登录用户所有健康指标统计数据(按指定日期过滤)
|
||||
*
|
||||
* @param date 查询日期,为 null 时返回最新一条数据
|
||||
* @return 各指标统计结果列表
|
||||
*/
|
||||
List<UserStat> userStatResultAll(Date date);
|
||||
|
||||
Boolean userHaveWatch(String userId);
|
||||
|
||||
UserWatchInfo findWatchInfo(String userId);
|
||||
|
||||
+236
-32
@@ -7,6 +7,8 @@ import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
import com.renkang.watch.WatchH5IndexItemNewVo;
|
||||
import com.renkang.watch.api.bean.response.UserWatchInfo;
|
||||
import com.renkang.watch.api.service.WatchDataApiService;
|
||||
import com.renkang.watch.dto.WatchDataWorkoutDTO;
|
||||
@@ -24,31 +26,34 @@ import com.renkang.watch.vo.UserData.res.bodyTemperature.BodyTempStat;
|
||||
import com.renkang.watch.vo.UserData.res.bodyTemperature.BodyTempStatRes;
|
||||
import com.renkang.watch.vo.UserData.res.heartRate.WatchDataHeartRateRes;
|
||||
import com.renkang.watch.vo.UserData.res.sleep.WatchDataSleepRes;
|
||||
import com.renkang.watch.vo.WatchH5IndexItemVo;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.DateUtils;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import org.jeecg.global.GlobalUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Service
|
||||
public class WatchDataApiServiceImpl implements WatchDataApiService {
|
||||
|
||||
|
||||
@Autowired
|
||||
private WatchDataWorkoutMapper watchDataWorkoutMapper;
|
||||
|
||||
|
||||
@Autowired
|
||||
private WatchStatUserInfoDayHeartRateMapper watchStatUserInfoDayHeartRateMapper;
|
||||
|
||||
|
||||
@Autowired
|
||||
private WatchDataHeartRateMapper watchDataHeartRateMapper;
|
||||
|
||||
@@ -60,9 +65,6 @@ public class WatchDataApiServiceImpl implements WatchDataApiService {
|
||||
@Autowired
|
||||
private WatchStatUserInfoDaySpo2ServiceImpl watchStatUserInfoDaySpo2ServiceImpl;
|
||||
|
||||
@Autowired
|
||||
private WatchStatUserInfoDaySleepMapper watchStatUserInfoDaySleepMapper;
|
||||
|
||||
@Autowired
|
||||
private WatchDataSleepNewMinuteMapper watchDataSleepNewMinuteMapper;
|
||||
|
||||
@@ -96,7 +98,6 @@ public class WatchDataApiServiceImpl implements WatchDataApiService {
|
||||
@Autowired
|
||||
private IWatchDataTemperatureService watchDataTemperatureService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private IWatchDataStressService watchDataStressService;
|
||||
@Autowired
|
||||
@@ -106,12 +107,47 @@ public class WatchDataApiServiceImpl implements WatchDataApiService {
|
||||
@Autowired
|
||||
private WatchUserDataMapper watchUserDataMapper;
|
||||
@Autowired
|
||||
private WatchStatUserInfoDayHeartRateMapper watchStatUserInfoDayHeartRateMapper;
|
||||
@Autowired
|
||||
private WatchStatUserInfoDaySleepMapper watchStatUserInfoDaySleepMapper;
|
||||
@Autowired
|
||||
private WatchStatUserInfoDaySpo2Mapper watchStatUserInfoDaySpo2Mapper;
|
||||
@Autowired
|
||||
private WatchStatUserInfoDayStressMapper watchStatUserInfoDayStressMapper;
|
||||
@Autowired
|
||||
private WatchStatUserInfoDayTempMapper watchStatUserInfoDayTempMapper;
|
||||
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
/** 用户统计全量数据 Redis 缓存 key 前缀 */
|
||||
private static final String USER_STAT_ALL_CACHE_KEY = "watch:userStatAll:";
|
||||
|
||||
private AsyncTaskExecutor asyncTaskExecutor;
|
||||
|
||||
public AsyncTaskExecutor getAsyncTaskExecutor() {
|
||||
if (asyncTaskExecutor == null) {
|
||||
initAsyncExecutor();
|
||||
}
|
||||
return asyncTaskExecutor;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
initAsyncExecutor();
|
||||
}
|
||||
|
||||
private void initAsyncExecutor() {
|
||||
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
|
||||
taskExecutor.setCorePoolSize(150);
|
||||
taskExecutor.setMaxPoolSize(500);
|
||||
taskExecutor.setQueueCapacity(500);
|
||||
taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
|
||||
taskExecutor.setThreadNamePrefix("watch-latest-pool1-");
|
||||
taskExecutor.initialize();
|
||||
asyncTaskExecutor = taskExecutor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Map<String,Object>> selectSportCostListApi() {
|
||||
LoginUser loginUser = GlobalUtils.getLoginUser();
|
||||
@@ -834,20 +870,171 @@ public class WatchDataApiServiceImpl implements WatchDataApiService {
|
||||
String userId = GlobalUtils.getLoginUser().getId();
|
||||
switch (type) {
|
||||
case "0":
|
||||
return handleHeartRate(userId);
|
||||
return handleHeartRate(userId,null);
|
||||
case "1":
|
||||
return handleBloodOxygen(userId);
|
||||
return handleBloodOxygen(userId,null);
|
||||
case "2":
|
||||
return handleStress(userId);
|
||||
return handleStress(userId,null);
|
||||
case "3":
|
||||
return handleBodyTemperature(userId);
|
||||
return handleBodyTemperature(userId,null);
|
||||
case "4":
|
||||
return handleSleep(userId);
|
||||
return handleSleep(userId,null);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserStat> userStatResultAll(Date date) {
|
||||
// 在主线程提前获取 userId,避免子线程无法访问 ThreadLocal 中的登录信息
|
||||
String userId = GlobalUtils.getLoginUser().getId();
|
||||
// 有时间参数时缓存 key 携带日期,避免与无参缓存冲突
|
||||
String cacheKey = USER_STAT_ALL_CACHE_KEY + userId + (date != null ? "_" + date.getTime() : "");
|
||||
|
||||
// 命中 Redis 缓存直接返回
|
||||
Object cached = redisUtil.get(cacheKey);
|
||||
if (cached != null) {
|
||||
return (List<UserStat>) cached;
|
||||
}
|
||||
|
||||
// 构建「数据类型 → 异步查询 Future」映射,消除 switch-case 冗余
|
||||
Map<String, CompletableFuture<WatchH5IndexItemNewVo>> futureMap = new HashMap<>();
|
||||
futureMap.put("sleep", CompletableFuture.supplyAsync(() -> latestSleepData(userId), getAsyncTaskExecutor()));
|
||||
futureMap.put("heart_rate", CompletableFuture.supplyAsync(() -> latestHeartRateData(userId), getAsyncTaskExecutor()));
|
||||
futureMap.put("spo2", CompletableFuture.supplyAsync(() -> latestSpo2Data(userId), getAsyncTaskExecutor()));
|
||||
futureMap.put("stress", CompletableFuture.supplyAsync(() -> latestStressData(userId), getAsyncTaskExecutor()));
|
||||
futureMap.put("temperature", CompletableFuture.supplyAsync(() -> latestTempData(userId), getAsyncTaskExecutor()));
|
||||
|
||||
// 等待全部异步查询完成
|
||||
CompletableFuture.allOf(futureMap.values().toArray(new CompletableFuture[0])).join();
|
||||
|
||||
// 转为顺序流遍历,避免并行流写入 ArrayList 的线程安全问题
|
||||
List<WatchH5IndexItemNewVo> list = new ArrayList<>();
|
||||
emptyItems().sequential().forEach(itemVo -> {
|
||||
CompletableFuture<WatchH5IndexItemNewVo> future = futureMap.get(itemVo.getWdType());
|
||||
// steps 等暂无对应查询的类型直接跳过
|
||||
if (future == null) {
|
||||
return;
|
||||
}
|
||||
WatchH5IndexItemNewVo data = future.join();
|
||||
if (data == null) {
|
||||
data = new WatchH5IndexItemNewVo();
|
||||
}
|
||||
// 将模板字段(wdType、wdTypeName、阈值)合并到结果对象
|
||||
data.fieldCopy(itemVo);
|
||||
// 睡眠数据特殊处理:dataValue 为空时补 "0"
|
||||
if ("sleep".equals(itemVo.getWdType()) && StrUtil.isEmpty(data.getDataValue())) {
|
||||
data.setDataValue("0");
|
||||
}
|
||||
list.add(data);
|
||||
});
|
||||
|
||||
List<UserStat> result = list.stream().map(UserStat::new).collect(Collectors.toList());
|
||||
|
||||
// 写入 Redis 缓存,TTL=3分钟(180秒)
|
||||
redisUtil.set(cacheKey, result, 180);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Stream<WatchH5IndexItemVo> emptyItems() {
|
||||
//睡眠
|
||||
WatchH5IndexItemVo sleepVo = new WatchH5IndexItemVo();
|
||||
sleepVo.setWdType("sleep");
|
||||
//步数
|
||||
WatchH5IndexItemVo stepsVo = new WatchH5IndexItemVo();
|
||||
stepsVo.setWdType("steps");
|
||||
//心率
|
||||
WatchH5IndexItemVo hearRateVo = new WatchH5IndexItemVo();
|
||||
hearRateVo.setWdType("heart_rate");
|
||||
//压力
|
||||
WatchH5IndexItemVo stressVo = new WatchH5IndexItemVo();
|
||||
stressVo.setWdType("stress");
|
||||
//血氧饱和度
|
||||
WatchH5IndexItemVo spo2Vo = new WatchH5IndexItemVo();
|
||||
spo2Vo.setWdType("spo2");
|
||||
//体温
|
||||
WatchH5IndexItemVo tempVo = new WatchH5IndexItemVo();
|
||||
tempVo.setWdType("temperature");
|
||||
List<WatchH5IndexItemVo> list = Arrays.asList(sleepVo, stepsVo, hearRateVo, stressVo, spo2Vo, tempVo);
|
||||
return list.parallelStream()
|
||||
.peek(itemVo -> {
|
||||
itemVo.setWarnMin("0.0");
|
||||
itemVo.setWarnMax("0.0");
|
||||
});
|
||||
}
|
||||
|
||||
private WatchH5IndexItemNewVo latestSleepData(String userId) {
|
||||
MPJLambdaWrapper<WatchStatUserInfoDaySleep> wrapper = new MPJLambdaWrapper<>();
|
||||
//因为睡眠详情页取的是长睡时长作为当天的睡眠时间 , 所以这里保持一致并没有取当天的睡眠总时长
|
||||
wrapper.selectAs(WatchStatUserInfoDaySleep::getLongDurationTotal,WatchH5IndexItemNewVo::getDataValue);
|
||||
wrapper.selectAs(WatchStatUserInfoDaySleep::getDeepSleepTimes,WatchH5IndexItemNewVo::getDataMax);
|
||||
wrapper.selectAs(WatchStatUserInfoDaySleep::getLightSleepTimes,WatchH5IndexItemNewVo::getDataMin);
|
||||
wrapper.selectAs(WatchStatUserInfoDaySleep::getSleepAvg,WatchH5IndexItemNewVo::getDataAvg);
|
||||
wrapper.selectAs(WatchStatUserInfoDaySleep::getLastUploadTime,WatchH5IndexItemNewVo::getDataDateNew);
|
||||
wrapper.eq(WatchStatUserInfoDaySleep::getUserId, userId);
|
||||
wrapper.orderByDesc(WatchStatUserInfoDaySleep::getDataDate);
|
||||
wrapper.last("limit 1");
|
||||
return watchStatUserInfoDaySleepMapper.selectJoinOne(WatchH5IndexItemNewVo.class,wrapper);
|
||||
}
|
||||
|
||||
private WatchH5IndexItemNewVo latestHeartRateData(String userId) {
|
||||
MPJLambdaWrapper<WatchStatUserInfoDayHeartRate> wrapper = new MPJLambdaWrapper<>();
|
||||
// 必须是watch_stat_user_info_day_heart_rate表中new_data字段启用后才能这样查
|
||||
wrapper.selectAs(WatchStatUserInfoDayHeartRate::getNewValue,WatchH5IndexItemNewVo::getDataValue);
|
||||
wrapper.selectAs(WatchStatUserInfoDayHeartRate::getMaxValue,WatchH5IndexItemNewVo::getDataMax);
|
||||
wrapper.selectAs(WatchStatUserInfoDayHeartRate::getMinValue,WatchH5IndexItemNewVo::getDataMin);
|
||||
wrapper.selectAs(WatchStatUserInfoDayHeartRate::getAvgValue,WatchH5IndexItemNewVo::getDataAvg);
|
||||
wrapper.selectAs(WatchStatUserInfoDayHeartRate::getLastUploadTime,WatchH5IndexItemNewVo::getDataDateNew);
|
||||
wrapper.eq(WatchStatUserInfoDayHeartRate::getUserId, userId);
|
||||
wrapper.orderByDesc(WatchStatUserInfoDayHeartRate::getDataDate);
|
||||
wrapper.last("limit 1");
|
||||
return watchStatUserInfoDayHeartRateMapper.selectJoinOne(WatchH5IndexItemNewVo.class,wrapper);
|
||||
}
|
||||
|
||||
private WatchH5IndexItemNewVo latestSpo2Data(String userId) {
|
||||
MPJLambdaWrapper<WatchStatUserInfoDaySpo2> wrapper = new MPJLambdaWrapper<>();
|
||||
// 必须是watch_stat_user_info_day_spo2表中new_data字段启用后才能这样查
|
||||
wrapper.selectAs(WatchStatUserInfoDaySpo2::getNewValue,WatchH5IndexItemNewVo::getDataValue);
|
||||
wrapper.selectAs(WatchStatUserInfoDaySpo2::getMaxValue,WatchH5IndexItemNewVo::getDataMax);
|
||||
wrapper.selectAs(WatchStatUserInfoDaySpo2::getMinValue,WatchH5IndexItemNewVo::getDataMin);
|
||||
wrapper.selectAs(WatchStatUserInfoDaySpo2::getAvgValue,WatchH5IndexItemNewVo::getDataAvg);
|
||||
wrapper.selectAs(WatchStatUserInfoDaySpo2::getLastUploadTime,WatchH5IndexItemNewVo::getDataDateNew);
|
||||
wrapper.eq(WatchStatUserInfoDaySpo2::getUserId, userId);
|
||||
wrapper.orderByDesc(WatchStatUserInfoDaySpo2::getDataDate);
|
||||
wrapper.last("limit 1");
|
||||
return watchStatUserInfoDaySpo2Mapper.selectJoinOne(WatchH5IndexItemNewVo.class,wrapper);
|
||||
}
|
||||
|
||||
private WatchH5IndexItemNewVo latestStressData(String userId) {
|
||||
MPJLambdaWrapper<WatchStatUserInfoDayStress> wrapper = new MPJLambdaWrapper<>();
|
||||
// 必须是watch_stat_user_info_day_stress表中new_data字段启用后才能这样查
|
||||
wrapper.selectAs(WatchStatUserInfoDayStress::getNewValue,WatchH5IndexItemNewVo::getDataValue);
|
||||
wrapper.selectAs(WatchStatUserInfoDayStress::getMaxValue,WatchH5IndexItemNewVo::getDataMax);
|
||||
wrapper.selectAs(WatchStatUserInfoDayStress::getMinValue,WatchH5IndexItemNewVo::getDataMin);
|
||||
wrapper.selectAs(WatchStatUserInfoDayStress::getAvgValue,WatchH5IndexItemNewVo::getDataAvg);
|
||||
wrapper.selectAs(WatchStatUserInfoDayStress::getLastUploadTime,WatchH5IndexItemNewVo::getDataDateNew);
|
||||
wrapper.eq(WatchStatUserInfoDayStress::getUserId, userId);
|
||||
wrapper.orderByDesc(WatchStatUserInfoDayStress::getDataDate);
|
||||
wrapper.last("limit 1");
|
||||
return watchStatUserInfoDayStressMapper.selectJoinOne(WatchH5IndexItemNewVo.class,wrapper);
|
||||
}
|
||||
|
||||
private WatchH5IndexItemNewVo latestTempData(String userId) {
|
||||
MPJLambdaWrapper<WatchStatUserInfoDayTemp> wrapper = new MPJLambdaWrapper<>();
|
||||
// 必须是watch_stat_user_info_day_temp表中new_data字段启用后才能这样查
|
||||
wrapper.selectAs(WatchStatUserInfoDayTemp::getNewValue,WatchH5IndexItemNewVo::getDataValue);
|
||||
wrapper.selectAs(WatchStatUserInfoDayTemp::getMaxValue,WatchH5IndexItemNewVo::getDataMax);
|
||||
wrapper.selectAs(WatchStatUserInfoDayTemp::getMinValue,WatchH5IndexItemNewVo::getDataMin);
|
||||
wrapper.selectAs(WatchStatUserInfoDayTemp::getAvgValue,WatchH5IndexItemNewVo::getDataAvg);
|
||||
wrapper.selectAs(WatchStatUserInfoDayTemp::getLastUploadTime,WatchH5IndexItemNewVo::getDataDateNew);
|
||||
wrapper.eq(WatchStatUserInfoDayTemp::getUserId, userId);
|
||||
wrapper.orderByDesc(WatchStatUserInfoDayTemp::getDataDate);
|
||||
wrapper.last("limit 1");
|
||||
return watchStatUserInfoDayTempMapper.selectJoinOne(WatchH5IndexItemNewVo.class,wrapper);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Boolean userHaveWatch(String userId) {
|
||||
if (StrUtil.isBlank(userId)) {
|
||||
@@ -885,7 +1072,7 @@ public class WatchDataApiServiceImpl implements WatchDataApiService {
|
||||
}
|
||||
|
||||
|
||||
private UserStat handleSleep(String userId) {
|
||||
private UserStat handleSleep(String userId, Date date) {
|
||||
LambdaQueryWrapper<WatchStatUserInfoDaySleep> queryWrapper = Wrappers.lambdaQuery(WatchStatUserInfoDaySleep.class)
|
||||
.select(WatchStatUserInfoDaySleep::getId,
|
||||
WatchStatUserInfoDaySleep::getDeepSleepTimes,
|
||||
@@ -893,13 +1080,15 @@ public class WatchDataApiServiceImpl implements WatchDataApiService {
|
||||
WatchStatUserInfoDaySleep::getDeepLightTimes,
|
||||
WatchStatUserInfoDaySleep::getDataDate)
|
||||
.eq(WatchStatUserInfoDaySleep::getUserId, userId)
|
||||
.orderByDesc(WatchStatUserInfoDaySleep::getDataDate)
|
||||
// 传了日期则精确匹配,否则取最新一条
|
||||
.eq(date != null, WatchStatUserInfoDaySleep::getDataDate, date)
|
||||
.orderByDesc(date == null, WatchStatUserInfoDaySleep::getDataDate)
|
||||
.last("limit 1");
|
||||
|
||||
WatchStatUserInfoDaySleep data = watchStatUserInfoDaySleepMapper.selectOne(queryWrapper);
|
||||
|
||||
if (data == null) {
|
||||
return null;
|
||||
return new UserStat();
|
||||
}
|
||||
|
||||
UserStat stat = new UserStat();
|
||||
@@ -915,15 +1104,15 @@ public class WatchDataApiServiceImpl implements WatchDataApiService {
|
||||
return stat;
|
||||
}
|
||||
|
||||
private UserStat handleBodyTemperature(String userId) {
|
||||
private UserStat handleBodyTemperature(String userId, Date date) {
|
||||
int type = 5;
|
||||
int scale = 1;
|
||||
// 最新数据
|
||||
UserStat userStat = userWatchDataLatest(userId, type, scale);
|
||||
if (userStat == null) {
|
||||
return null;
|
||||
return new UserStat();
|
||||
}
|
||||
LambdaQueryWrapper<WatchStatUserInfoDayTemp> queryWrapper = getQueryWrapper(userId);
|
||||
LambdaQueryWrapper<WatchStatUserInfoDayTemp> queryWrapper = getQueryWrapper(userId, date);
|
||||
WatchStatUserInfoDayTemp data = watchStatUserInfoDayTempMapper.selectOne(queryWrapper);
|
||||
if (data == null) {
|
||||
return userStat;
|
||||
@@ -933,15 +1122,15 @@ public class WatchDataApiServiceImpl implements WatchDataApiService {
|
||||
return userStat;
|
||||
}
|
||||
|
||||
private UserStat handleStress(String userId) {
|
||||
private UserStat handleStress(String userId, Date date) {
|
||||
int type = 3;
|
||||
int scale = 0;
|
||||
// 最新数据
|
||||
UserStat userStat = userWatchDataLatest(userId, type, scale);
|
||||
if (userStat == null) {
|
||||
return null;
|
||||
return new UserStat();
|
||||
}
|
||||
LambdaQueryWrapper<WatchStatUserInfoDayStress> queryWrapper = getQueryWrapper(userId);
|
||||
LambdaQueryWrapper<WatchStatUserInfoDayStress> queryWrapper = getQueryWrapper(userId, date);
|
||||
WatchStatUserInfoDayStress data = watchStatUserInfoDayStressMapper.selectOne(queryWrapper);
|
||||
if (data == null) {
|
||||
return userStat;
|
||||
@@ -951,15 +1140,15 @@ public class WatchDataApiServiceImpl implements WatchDataApiService {
|
||||
return userStat;
|
||||
}
|
||||
|
||||
private UserStat handleBloodOxygen(String userId) {
|
||||
private UserStat handleBloodOxygen(String userId, Date date) {
|
||||
int type = 2;
|
||||
int scale = 0;
|
||||
// 最新数据
|
||||
UserStat userStat = userWatchDataLatest(userId, type, scale);
|
||||
if (userStat == null) {
|
||||
return null;
|
||||
return new UserStat();
|
||||
}
|
||||
LambdaQueryWrapper<WatchStatUserInfoDaySpo2> queryWrapper = getQueryWrapper(userId);
|
||||
LambdaQueryWrapper<WatchStatUserInfoDaySpo2> queryWrapper = getQueryWrapper(userId, date);
|
||||
WatchStatUserInfoDaySpo2 data = watchStatUserInfoDaySpo2Mapper.selectOne(queryWrapper);
|
||||
if (data == null) {
|
||||
return userStat;
|
||||
@@ -969,15 +1158,15 @@ public class WatchDataApiServiceImpl implements WatchDataApiService {
|
||||
return userStat;
|
||||
}
|
||||
|
||||
private UserStat handleHeartRate(String userId) {
|
||||
private UserStat handleHeartRate(String userId, Date date) {
|
||||
int type = 1;
|
||||
int scale = 0;
|
||||
// 最新数据
|
||||
UserStat userStat = userWatchDataLatest(userId, type, scale);
|
||||
if (userStat == null) {
|
||||
return null;
|
||||
return new UserStat();
|
||||
}
|
||||
LambdaQueryWrapper<WatchStatUserInfoDayHeartRate> queryWrapper = getQueryWrapper(userId);
|
||||
LambdaQueryWrapper<WatchStatUserInfoDayHeartRate> queryWrapper = getQueryWrapper(userId, date);
|
||||
WatchStatUserInfoDayHeartRate data = watchStatUserInfoDayHeartRateMapper.selectOne(queryWrapper);
|
||||
if (data == null) {
|
||||
return userStat;
|
||||
@@ -1029,10 +1218,12 @@ public class WatchDataApiServiceImpl implements WatchDataApiService {
|
||||
return stat;
|
||||
}
|
||||
|
||||
private <T> LambdaQueryWrapper<T> getQueryWrapper(String userId) {
|
||||
private <T> LambdaQueryWrapper<T> getQueryWrapper(String userId, Date date) {
|
||||
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("user_id", userId)
|
||||
.orderByDesc("data_date")
|
||||
// 传了日期则精确匹配,否则取最新一条
|
||||
.eq(date != null, "data_date", date)
|
||||
.orderByDesc(date == null, "data_date")
|
||||
.last("limit 1");
|
||||
return queryWrapper.lambda();
|
||||
}
|
||||
@@ -1051,4 +1242,17 @@ public class WatchDataApiServiceImpl implements WatchDataApiService {
|
||||
return BigDecimal.valueOf(value).setScale(0, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置统计数据类型标识,stat 为 null 时直接返回 null
|
||||
*
|
||||
* @param stat UserStat 对象
|
||||
* @param type 类型编码:0=心率 1=血氧 2=压力 3=体温 4=睡眠
|
||||
*/
|
||||
private UserStat setType(UserStat stat, String type) {
|
||||
if (stat != null) {
|
||||
stat.setType(type);
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-2
@@ -336,8 +336,9 @@ public class AsyncImportService {
|
||||
updatedWatchDevice.setBindDate(watchDevice.getBindDate()==null?new Date():watchDevice.getBindDate());
|
||||
updatedWatchDevice.setUpdateDate(new Date());
|
||||
updatedWatchDevice.setUpdateBy(sysUser.getId());
|
||||
updatedWatchDevice.setDeptId(device.getDeptId());
|
||||
updatedWatchDevice.setOrgCode(device.getOrgCode());
|
||||
// 这里修改成以用户的部门为准,更新手表的所属部门
|
||||
updatedWatchDevice.setDeptId(sysCache.getDepartIdByOrgCode(user.getOrgCode()));
|
||||
updatedWatchDevice.setOrgCode(user.getOrgCode());
|
||||
updateList.add(updatedWatchDevice);
|
||||
}
|
||||
info1.setHandleMsg(index + "/" + count);
|
||||
|
||||
+15
@@ -38,6 +38,21 @@ public class WatchApiController {
|
||||
return watchMonitorDataService.notice(json);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新告警事件GPS位置信息接口
|
||||
* 根据 watchNo + eventId 联合定位已有告警数据;
|
||||
* 仅更新GPS相关字段,不推送大屏与短信;
|
||||
* 内部会调用高德接口进行GPS84→GCJ02坐标转换与地址反查。
|
||||
*
|
||||
* @param json 入参(watchNo、eventId、lon、lat、address、locateTime、gpsErrorMsg)
|
||||
* @return 处理结果
|
||||
*/
|
||||
@PostMapping("/updateMonitorGps")
|
||||
@Operation(summary = "更新告警事件GPS位置信息")
|
||||
public AjaxJson updateMonitorGps(@RequestBody JSONObject json) {
|
||||
return watchMonitorDataService.updateMonitorGps(json);
|
||||
}
|
||||
|
||||
@GetMapping("/setData")
|
||||
public AjaxJson setData() {
|
||||
AjaxJson ajaxJson = new AjaxJson();
|
||||
|
||||
+2
-4
@@ -11,10 +11,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
@@ -327,4 +324,5 @@ public class WatchController {
|
||||
// }
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+21
-1
@@ -185,6 +185,12 @@ public class WatchDeviceController extends JeecgController<WatchDevice, IWatchDe
|
||||
return watchDeviceService.bindUser(dto);
|
||||
}
|
||||
|
||||
@Operation(summary = "移动端绑定设备(手表)", description = "移动端绑定设备(手表)")
|
||||
@GetMapping("/app/bindDevice")
|
||||
public Result bindDevice(@RequestParam(name = "watchNo") String watchNo) throws ParseException {
|
||||
return watchDeviceService.bindDevice(watchNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解绑用户
|
||||
*
|
||||
@@ -194,10 +200,18 @@ public class WatchDeviceController extends JeecgController<WatchDevice, IWatchDe
|
||||
@Operation(summary = "解绑用户", description = "解绑用户")
|
||||
@PostMapping(value = "/unbundleUser")
|
||||
@RequiresPermissions("watch:watch_device:unbindUser")
|
||||
public Result unbundleUser(@RequestBody() BindUserDTO dto) throws ParseException {
|
||||
public Result unbundleUser(@RequestBody() BindUserDTO dto) {
|
||||
return watchDeviceService.unbundleUser(dto);
|
||||
}
|
||||
|
||||
@Operation(summary = "移动端解绑设备(手表)", description = "移动端解绑设备(手表)")
|
||||
@GetMapping("/app/unbundleDevice")
|
||||
public Result unbundleDevice(@RequestParam(name = "watchNo") String watchNo) {
|
||||
//移动端暂不允许解绑手表
|
||||
return Result.error("请联系健康管理员解绑");
|
||||
// return watchDeviceService.unbundleDevice(watchNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置上传频次
|
||||
*
|
||||
@@ -343,6 +357,10 @@ public class WatchDeviceController extends JeecgController<WatchDevice, IWatchDe
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
|
||||
WatchDevice watchDevice = watchDeviceService.getById(id);
|
||||
// 已绑定用户的手表不允许删除
|
||||
if (StringUtils.hasLength(watchDevice.getBindUserId())) {
|
||||
return Result.error("该手表已绑定用户,请先解绑后再删除!");
|
||||
}
|
||||
watchDeviceService.removeById(id);
|
||||
// 删除开关
|
||||
LambdaQueryWrapper<WatchDeviceSwitch> queryWrapper = new LambdaQueryWrapper<>();
|
||||
@@ -422,6 +440,8 @@ public class WatchDeviceController extends JeecgController<WatchDevice, IWatchDe
|
||||
}
|
||||
if (!StringUtils.hasLength(deptId) || "undefined".equals(deptId)) {
|
||||
throw new JeecgBootException("部门不能为空");
|
||||
//可为空,空则算入新疆油田公司
|
||||
// deptId = sysCache.getDepartIdByOrgCode("A01");
|
||||
}
|
||||
String sheetName = "设备导入";
|
||||
String fileName = sheetName + "_" + DateUtils.getDate("yyyyMMddHHmmss");
|
||||
|
||||
+5
-1
@@ -43,12 +43,16 @@ public interface IWatchDeviceService extends IService<WatchDevice> {
|
||||
*/
|
||||
Result bindUser(BindUserDTO dto) throws ParseException;
|
||||
|
||||
Result bindDevice(String watchNo) throws ParseException;
|
||||
|
||||
/**
|
||||
* 绑定用户
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
Result unbundleUser(BindUserDTO dto) throws ParseException;
|
||||
Result unbundleUser(BindUserDTO dto);
|
||||
|
||||
Result unbundleDevice(String watchNo);
|
||||
|
||||
/**
|
||||
* 工具开关
|
||||
|
||||
+11
@@ -38,6 +38,17 @@ public interface IWatchMonitorDataService extends IService<WatchMonitorData> {
|
||||
*/
|
||||
AjaxJson notice(JSONObject jsonObject);
|
||||
|
||||
/**
|
||||
* 更新告警事件GPS位置信息
|
||||
* 根据 watchNo + eventId 联合定位已有告警数据;
|
||||
* 缺失任一定位字段则忽略;已存在GPS信息则忽略;
|
||||
* 仅更新数据,不推送大屏与短信。
|
||||
*
|
||||
* @param jsonObject 入参(含 watchNo、eventId、lon、lat、address、locateTime、gpsErrorMsg 等)
|
||||
* @return 处理结果
|
||||
*/
|
||||
AjaxJson updateMonitorGps(JSONObject jsonObject);
|
||||
|
||||
/**
|
||||
* 处理历史数据 orgCode为空的问题
|
||||
* @return
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user