当前位置:网站首页>入职对接-hm项目
入职对接-hm项目
2022-08-02 18:54:00 【HRX98】
1. 首页配置
完成情况
- 接口已全部完成。前端 @黎家富 实现了C端,B端接口还未对接。
设计
- B端设计参看B端设计文档 “设置-租户设置-首页装修和自定义页面”。
- C端详细设计参看wiki “产品管理-首页装修组件定义”。
数据库
home_page 一个首页的全局设置
- 查询C端首页的接口会优先选择对应语言环境、对应租户的首页,若没有,才会选择没有租户id的首页。所以一般都会在表中配置一个没有租户id的首页用于默认配置。
home_page_component 首页的各组件配置
page_id是home_page中的id
一(home_page)对多(home_page_component)
注意component_name是与前端约定好的值,由前端传参。有效值目前有:
- search_box 搜索框
- navigation_buttons 导航按钮
- slide_show 轮播图
- img 图片组件
- health_punch 健康打卡
- health_information 健康资讯
data json格式,用于存储各组件的相关配置,参数是与前端约定好的值,由前端传值。
代码
- hm项目 – HomePageController 和 CustomPageController
2. 智能标签
完成情况
- 前端@程显 后端@舒浙@胡俊扬 均完成
- 标签的增删改查为后端 @胡俊扬 完成。本人完成模块为自动绑定或删除客户标签。
设计
- 参见设计文档
- 客户指标录入时,如果满足某个智能标签的绑定规则,则会在指标录入后绑定此标签到客户,若不满足,且原来客户绑定了此标签,则会删除此标签。
数据库
- customer_label 客户与标签之间的绑定关系
- label 标签
代码
- 标签的增删改查:core项目 – MeterLabelController
- 智能绑定客户标签参见:core项目 – CustomerBodyMetricServiceImpl – calMetricLabel。详细代码如下:
public class CustomerBodyMetricServiceImpl () {
private void calMetricLabel(String tenantId, String customerId, BodyMetricsEntity metricEntity, CustomerBodyMetricsEntity entity) {
String value = entity.getValue();
Map<String, Object> env = getMetricRangeEnv(tenantId, customerId, metricEntity);
MetricRange range = getMetricRange(tenantId, customerId, metricEntity, env);
log.info("customer:{}, metric:{}, range:{}", customerId, metricEntity.getName(), range == null ? "" : range.toString());
if (range == null) {
if (!StringUtils.isEmpty(metricEntity.getDefaultReference())) {
String reference = metricEntity.getDefaultReference();
entity.setReference(reference);
if ("阴性".equals(reference) || "阴".equals(reference) || "negative".equals(reference) || "-".equals(reference)) {
if (value.contains("阳") || value.contains("positive") || value.contains("+")) {
// 阳性
entity.setLabel(String.valueOf(MetricLabelEnum.POSITIVE.getCode()));
} else if (value.contains("阴") || value.contains("negative") || value.contains("-")) {
// 阴性
entity.setLabel(String.valueOf(MetricLabelEnum.NEGATIVE.getCode()));
}
} else {
// value在label的valueEnum中
List<BodyMetricsLabelEntity> labelEntities = bodyMetricsLabelDao.findByMetric(metricEntity.getName());
List<String> valueList = Arrays.asList(value.split(","));
for (BodyMetricsLabelEntity labelEntity : labelEntities) {
String valueEnumeration = labelEntity.getValueEnumeration();
if (!StringUtils.isEmpty(valueEnumeration)) {
List<String> valueEnumList = JSONObject.parseArray(valueEnumeration, String.class);
for (String v : valueList) {
if (valueEnumList.contains(v)) {
entity.setLabel(labelEntity.getLabel());
break;
}
}
if (entity.getLabel() != null) {
break;
}
}
}
}
}
} else {
entity.setReference(range.getReference());
entity.setEnv(JSONObject.toJSONString(env));
// 有参考值的, 全是数值类型
LinearRange linearRange = new LinearRange(range.getXs(), range.getLabels().stream().map(MetricLabel::getLabel).collect(Collectors.toList()));
// 单位转换
UnitEnumerator defaultUnit = UnitEnum.getEnumById(metricEntity.getUnit());
String unit = entity.getUnit();
BigDecimal valueBD = new BigDecimal(value);
BigDecimal standardV = ((NumberValue) com.lanxi.core.model.metric.Metric.from(NumberValue.of(valueBD), (PeerUnit) UnitEnum.getEnumById(unit)).getV((ConvertibleUnit) defaultUnit)).getV();
// 计算标签
String label = linearRange.cal(standardV);
entity.setLabel(label);
// 获取label ranges
Map<String, String> labelRanges = linearRange.getLabelRanges();
entity.setLabelRanges(JSONObject.toJSONString(labelRanges));
// 计算战胜比
List<MetricLabel> labels = doGetMetricLabelDetails(metricEntity.getName(), labelRanges);
Double proportion = null;
// 战胜比是否是100-proportion. 如果首个label是正常, 则战胜比取100-
Boolean reverseProportion = labels.isEmpty() ? false : labels.get(0).isNormal();
for (MetricLabel l : labels) {
if (l.getProportion() == null) {
break;
}
if (proportion == null) {
proportion = 0d;
}
if (l.getLabel().equalsIgnoreCase(label)) {
String rangeStr = labelRanges.get(label);
rangeStr = rangeStr.substring(1, rangeStr.length() - 1);
String[] lowHigh = rangeStr.split(",");
String lowStr = lowHigh[0];
String highStr = lowHigh[1];
BigDecimal low = lowStr.contains("∞") ? BigDecimal.valueOf(Integer.MIN_VALUE) : new BigDecimal(lowStr);
BigDecimal high = highStr.contains("∞") ? BigDecimal.valueOf(Integer.MAX_VALUE) : new BigDecimal(highStr);
proportion += standardV.subtract(low).divide(high.subtract(low), 2, RoundingMode.HALF_UP).doubleValue() / 100 * l.getProportion();
break;
} else {
proportion += l.getProportion();
}
}
if (reverseProportion != null && reverseProportion && proportion != null) {
proportion = 100 - proportion;
}
entity.setProportion(proportion);
}
}
}
3. 智能推送
完成情况
- 接口已全部完成。前端 @柴西雷 未对接。
设计
- B端设计文档:运营 – 智能推送
- C端设计文档:体检页面 (需求中的内容排序,经过与产品@沈永涛 讨论后去除此需求,改为随机取出5条即可)
- 推送的详细逻辑参看wiki “产品管理-智能推送”
遗留问题
- 关于干预方案的推送,目前是从消息点进页面是空白。这是因为推送规则中配置的是干预方案的模板id,而前端没有显示模板的页面,只有显示客户与干预方案关联的页面。需要前端兼容或者C端增加客户添加干预方案的功能(目前只有B端–客户详情中有此功能)等,详情需咨询产品@沈永涛。
数据库
- push_rule 推送规则
- push_rule_setting 智能推送的详细内容配置
代码
- 主要代码在:hm项目 – ServePackageSmartPushProcessor、HealthHutSmartPushProcessor、PowerJobScheduleForSmartPushInitializer 和 SmartPushController
- 在推送逻辑中需要注意的事项:
- 需求要求:满足条件则推送一条,推送的内容不能与上一次内容重复,当所有符合条件的内容都推送完成时,需要从第一条重新开始循环推送。因此在代码中使用最近一条推送记录(message_info表)来控制下一次的推送内容。
- 基于上述,当推送执行到规则内容中的第二条,而此时有人修改推送规则,添加了一条推送内容,但如果此推送内容排在第二条之前,那么此内容只有等到下一次循环时才可以被推送。
边栏推荐
猜你喜欢
随机推荐
E. Add Modulo 10(规律)
【C语言刷题】Leetcode203——移除链表元素
Nature Microbiology综述:聚焦藻际--浮游植物和细菌互作的生态界面
golang刷leetcode 经典(12) 完全二叉树插入器
Jellyfin 打造家庭影院 & 视频硬解 (威联通 QNAP)
Gradle系列——Gradle的build.gradle文件详情,项目发布(基于Gradle文档7.5)day3-3
指针常量和常量指针概述
项目分析(复杂嵌入式系统设计)
请教一个数据库连接池的问题,目前已知是事务未设置超时,又有一块代码事务没有提交,一直把连接给耗尽了,
荐号 | 当一个人不联系你,不拉黑你,原因只有一个……!
移动跨端技术方案分析对比
Sentienl【动态数据源架构设计理念与改造实践】
ETH Zurich重磅综述 | 人脸-素描合成:一个新的挑战
T31开发笔记:metaipc测试
竞赛:糖尿病遗传风险检测挑战赛(科大讯飞)
86.(cesium之家)cesium叠加面接收阴影效果(gltf模型)
深度学习-学习笔记(持续更新)
【C语言刷题】双指针原地修改数组(力扣原题分析)
Unity 打包和切换平台|Build Settings窗口介绍
What are the useful real-time network traffic monitoring software