提交 c96cea93 authored 作者: 窦馨雨's avatar 窦馨雨

合并分支 'dxy' 到 'qa'

增加飞书审批完成同步价格到勤策【基本建议零售价】字段中 查看合并请求 !33
......@@ -133,6 +133,11 @@
<groupId>com.larksuite.oapi</groupId>
<artifactId>oapi-sdk</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
......@@ -61,4 +61,6 @@ public class CacheConstants
*/
public static final String FRONT_VERSION_KEY = "frontVersion:info";
public static final String HUB_USER_MINI_PROGRAM = "fortune_hub:user:mini_program:" ;
public static final String HUB_USER_OFFICE_ACCOUNT = "fortune_hub:user:office_account:";
}
......@@ -13,6 +13,29 @@ public class RoleConstants {
*/
public static final String PRODUCT_QUALITY_CHECK = "cpzjgc";
/**
* 销售(城市经理):促销AP管理 cxapgl
*/
public static final String OPERATION_AP_MANAGER = "cxapgl";
/**
* 战区经理:促销AP管理-战区
*/
public static final String OPERATIONZQ_AP_MANAGER = "cxapglzq";
/**
* 大区总:促销AP管理-大区
*/
public static final String OPERATIONDQ_AP_MANAGER = "cxapgldq";
/**
* 运营中心促销AP管理 yyzxcxapgl
*/
public static final String OPERATION_CENTER_AP_MANAGER = "yyzxcxapgl";
/**
* 大区TM促销AP管理 dqtmcxapgl
*/
public static final String DISTRICT_AP_MANAGER = "dqtmcxapgl";
/**
* 1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限
......
......@@ -62,6 +62,10 @@ public class R<T> implements Serializable
public static <T> R<T> fail(int code, String msg)
{
return restResult(null, code, msg);
}
public static <T> R<T> fail(int code,T data ) {
return restResult(data, code, "请求失败");
}
private static <T> R<T> restResult(T data, int code, String msg)
......
......@@ -44,6 +44,9 @@ public enum ECode implements StatusCode {
ZZ_PRODUCT_QUALITY_EXIST_ERROR(905, "【料号+生产批次+发货日期】已存在,不可重新添加;"),
ZZ_PRODUCT_QUALITY_UPDATE_ERROR(906, "质检报告只能在48小时内更新;"),
ZZ_PRODUCT_QUALITY_DEPT_ERROR(907, "质检报告归属部门与当前登录部门不一致;"),
ZZ_PRODUCT_QUALITY_AP_ERROR(908, "信息仅销售人员、大区TM可修改;"),
SALES_AP_UPDATE_ERROR(909, "请匆修改非【当前月】数据;"),
SALES_AP_EXPORT_ERROR(910, "%s"),
/**
......
package com.sfa.common.core.enums.qince;
import lombok.Getter;
/**
* @author : liqiulin
* @date : 2025-12-29 17
* @describe :
*/
@Getter
public enum QinceEmpStatus {
/**
* 员工账号状态。0:销户,1:正常,2:停用
*/
NORMAL("1", "正常"),
STOP("2", "停用"),
CANCEL("0", "销户");
private String status;
private String desc;
QinceEmpStatus(String status, String desc) {
this.status = status;
this.desc = desc;
}
}
......@@ -19,15 +19,21 @@ import com.lark.oapi.service.contact.v3.model.ChildrenDepartmentReq;
import com.lark.oapi.service.contact.v3.model.ChildrenDepartmentResp;
import com.lark.oapi.service.contact.v3.model.FindByDepartmentUserReq;
import com.lark.oapi.service.contact.v3.model.FindByDepartmentUserResp;
import com.lark.oapi.service.corehr.v1.model.Offboarding;
import com.lark.oapi.service.corehr.v1.model.SearchOffboardingReq;
import com.lark.oapi.service.corehr.v1.model.SearchOffboardingReqBody;
import com.lark.oapi.service.corehr.v1.model.SearchOffboardingResp;
import com.lark.oapi.service.corehr.v2.model.*;
import com.sfa.common.core.enums.ECode;
import com.sfa.common.core.exception.ServiceException;
import com.sfa.common.core.exception.auth.NotLoginException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -53,12 +59,26 @@ public class FeiShuUtil {
@Value("${feishu.bot_1.app_secret}")
private String botAppSecret1;
//飞书获取用户信息
/**
* 飞书获取用户信息
*/
@Value("${feishu.luzx_redirectUri}")
private String redirectUri;
@Value("${feishu.lbxy_redirectUri}")
private String lbxyRedirectUri;
/**
* 飞书群机器人推送,此机器人为勤策消息通知机器人
*/
public static String qinceWebhook;
/**
* 飞书群机器人推送,此机器人为syncprice消息通知机器人
*/
public static String syncpriceWebhook;
/*链路中心*/
public static final String APP_LUZX = "luzx";
/*卤币学院*/
public static final String APP_LBXY = "lbxy";
private static final String UTF_8 = "UTF-8";
......@@ -92,7 +112,7 @@ public class FeiShuUtil {
Response execute = client.newCall(build).execute();
JSONObject rj = JSONObject.parseObject(execute.body().string());
if (!rj.containsKey("access_token")) {
log.error("飞书用户获取失败!", rj.toString());
log.error("飞书获取access_token失败!,入参:{},返回:{}", JSONObject.toJSONString(bodyMap), rj.toString());
throw new NotLoginException(ECode.FEISHU_ACCESS_TOKEN_ERROR);
}
return rj.getString("access_token");
......@@ -423,4 +443,139 @@ public class FeiShuUtil {
}
public Offboarding searchOffboardings(String employmentId) {
try {
Client client = getClientLUZX();
SearchOffboardingReq req = SearchOffboardingReq.newBuilder()
.pageSize(1)
.userIdType("people_corehr_id")
.searchOffboardingReqBody(SearchOffboardingReqBody.newBuilder()
.employmentIds(new String[]{employmentId})
.build())
.build();
// 发起请求
SearchOffboardingResp resp = client.corehr().v1().offboarding().search(req);
// 处理服务端错误
if (!resp.success()) {
log.error("查询员工离职信息异常:code:{},msg:{},body{}", resp.getCode(), resp.getMsg(), new String(resp.getRawResponse().getBody(), UTF_8));
return null;
}
Offboarding item = resp.getData().getItems()[0];
return item;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 从审批信息字符串中提取核心业务值(产品名称、编码、箱规、供货价等)
* @param approvalInfoStr 完整的审批信息JSON字符串(包含form字段的那个字符串)
* @return 提取的核心值Map:key=字段名,value=字段值(已做类型转换)
*/
public Map<String, Object> getApprovalFormValues(String approvalInfoStr) {
// 定义返回的核心值Map,key用固定标识方便调用,value存对应值
Map<String, Object> formValueMap = new HashMap<>();
// 初始化默认值,避免空指针
// 产品名称(字符串)
formValueMap.put("productName", null);
// 产品编码(字符串)
formValueMap.put("productCode", null);
// 产品规格(字符串)
formValueMap.put("productSpec", null);
// 2B供货价(BigDecimal)
formValueMap.put("supplyPrice", null);
// 标准成本(BigDecimal)
formValueMap.put("standardCost", null);
try {
// 校验入参
if (StringUtils.isBlank(approvalInfoStr)) {
log.error("审批信息字符串为空,无法提取字段值");
return formValueMap;
}
// 解析审批信息JSON字符串
JSONObject approvalJson = JSONObject.parseObject(approvalInfoStr);
// 提取form字段(字符串类型的JSON数组)并解析
String formStr = approvalJson.getString("form");
if (StringUtils.isBlank(formStr)) {
log.error("审批信息中form字段为空,无法提取字段值");
return formValueMap;
}
JSONArray formFields = JSONArray.parseArray(formStr);
// 4遍历form数组,提取核心值(按字段名精准匹配)
for (int i = 0; i < formFields.size(); i++) {
JSONObject field = formFields.getJSONObject(i);
String fieldName = field.getString("name");
Object fieldValue = field.get("value");
// 跳过空字段名/空值
if (StringUtils.isBlank(fieldName) || fieldValue == null) {
continue;
}
// 按业务需求提取指定字段,做类型转换和容错
switch (fieldName) {
case "产品名称":
formValueMap.put("productName", fieldValue.toString().trim());
break;
case "产品编码":
formValueMap.put("productCode", fieldValue.toString().trim());
break;
case "产品箱规":
try {
Integer spec = Integer.parseInt(fieldValue.toString().trim());
formValueMap.put("productSpec", spec);
} catch (NumberFormatException e) {
log.error("产品箱规格式错误,值为:{}", fieldValue);
formValueMap.put("productSpec", null);
}
break;
case "2B供货价/出厂价(与T100一致的最小售卖单元)":
try {
BigDecimal price = new BigDecimal(fieldValue.toString().trim());
formValueMap.put("supplyPrice", price);
} catch (NumberFormatException e) {
log.error("2B供货价格式错误,值为:{}", fieldValue);
formValueMap.put("supplyPrice", null);
}
break;
case "标准成本(与T100一致的最小售卖单元)":
try {
BigDecimal cost = new BigDecimal(fieldValue.toString().trim());
formValueMap.put("standardCost", cost);
} catch (NumberFormatException e) {
log.error("标准成本格式错误,值为:{}", fieldValue);
formValueMap.put("standardCost", null);
}
break;
// 如需提取其他字段,直接在case里添加即可
default:
break;
}
}
log.info("审批信息字段提取完成,结果:{}", formValueMap);
} catch (Exception e) {
log.error("解析审批信息、提取字段值异常", e);
}
return formValueMap;
}
@Value("${feishu.group_robot.syncprice_webhook}")
public void setSyncpriceWebhook(String syncpriceWebhook) {
FeiShuUtil.syncpriceWebhook = syncpriceWebhook;
}
@Value("${feishu.group_robot.qince_webhook}")
public void setQinceWebhook(String qinceWebhook) {
FeiShuUtil.qinceWebhook = qinceWebhook;
}
}
package com.sfa.common.core.utils.sdk;
import cn.hutool.core.map.MapUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import java.util.HashMap;
import java.util.Map;
/**
* @author : liqiulin
* @date : 2025-12-29 19
* @describe : 飞书静态工具 类
*/
public class FeiShuUtils {
public static void pustRoot(String rootUrl, String logText) {
Map<String, Object> hint = new HashMap<>();
hint.put("msg_type", "text");
hint.put("content", MapUtil.of("text",logText));
HttpUtil.createPost(rootUrl).body(JSONObject.toJSONString(hint)).execute();
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论