提交 e254fdc4 authored 作者: douxy's avatar douxy

新增同步【基本单位建议零售价】到勤策

上级 1464786c
...@@ -41,6 +41,9 @@ public class EventCallbackLuzx { ...@@ -41,6 +41,9 @@ public class EventCallbackLuzx {
private String encryptKeyP; private String encryptKeyP;
@Value("${feishu.approval.scfy}") @Value("${feishu.approval.scfy}")
private String scfyCode; private String scfyCode;
@Value("${feishu.approval.xpss_cpdj}")
private String xpssCode;
@Autowired @Autowired
private IEventCallbackService eventCallbackService; private IEventCallbackService eventCallbackService;
@Autowired @Autowired
...@@ -122,9 +125,15 @@ public class EventCallbackLuzx { ...@@ -122,9 +125,15 @@ public class EventCallbackLuzx {
EventCallBackDto eventCallBackDto = JSONObject.parseObject(decrypt, EventCallBackDto.class); EventCallBackDto eventCallBackDto = JSONObject.parseObject(decrypt, EventCallBackDto.class);
EventCallBackDto.Event event = eventCallBackDto.getEvent(); EventCallBackDto.Event event = eventCallBackDto.getEvent();
// 市场推广费用申请(审批实例CODE:258B4D93-96D4-49E4-B9E1-DA6AB45740B0) // 市场推广费用申请(审批实例CODE:258B4D93-96D4-49E4-B9E1-DA6AB45740B0)
if (Constants.FEISHU_APPROVAL_INSTANCE.equals(event.getType()) && scfyCode.equals(event.getApprovalCode())){ // if (Constants.FEISHU_APPROVAL_INSTANCE.equals(event.getType()) && scfyCode.equals(event.getApprovalCode())){
if (!event.getStatus().equals(PlanStatus.PENDING.name())){ // if (!event.getStatus().equals(PlanStatus.PENDING.name())){
eventCallbackService.planCP(event); // eventCallbackService.planCP(event);
// }
// }
// 新品上市产品定价申请 (审批实例CODE: B4DBC1A9-D555-469D-AB69-4F353D8D2985)
if (Constants.FEISHU_APPROVAL_INSTANCE.equals(event.getType()) && xpssCode.equals(event.getApprovalCode())){
if (event.getStatus().equals(PlanStatus.APPROVED.name())){
eventCallbackService.getMinimumSellingPrice(event,xpssCode);
} }
} }
} }
......
package com.sfa.job.service.feishu; package com.sfa.job.service.feishu;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.sfa.common.core.utils.DateUtils;
import com.lark.oapi.service.corehr.v1.model.Offboarding; import com.lark.oapi.service.corehr.v1.model.Offboarding;
import com.lark.oapi.service.corehr.v2.model.*; import com.lark.oapi.service.corehr.v2.model.*;
import com.sfa.common.core.enums.promotion.PlanStatus; import com.sfa.common.core.enums.promotion.PlanStatus;
import com.sfa.common.core.utils.DateUtils;
import com.sfa.common.core.utils.sdk.FeiShuUtil; import com.sfa.common.core.utils.sdk.FeiShuUtil;
import com.sfa.job.domain.promotion.dao.IActivityPlanDao; import com.sfa.job.domain.promotion.dao.IActivityPlanDao;
import com.sfa.job.domain.system.dao.ISysDeptDao; import com.sfa.job.domain.system.dao.ISysDeptDao;
...@@ -14,6 +14,7 @@ import com.sfa.job.pojo.feishu.event.EventCallBackDto; ...@@ -14,6 +14,7 @@ import com.sfa.job.pojo.feishu.event.EventCallBackDto;
import com.sfa.job.pojo.promotion.response.ActivityPlanApprovalDto; import com.sfa.job.pojo.promotion.response.ActivityPlanApprovalDto;
import com.sfa.job.pojo.response.SysEventLogDto; import com.sfa.job.pojo.response.SysEventLogDto;
import com.sfa.job.service.system.IDeptAndUserService; import com.sfa.job.service.system.IDeptAndUserService;
import com.sfa.job.util.QinCeUtils;
import com.sfa.job.util.T100Util; import com.sfa.job.util.T100Util;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
...@@ -21,6 +22,9 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -21,6 +22,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Date; import java.util.Date;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
/** /**
...@@ -45,6 +49,9 @@ public class EventCallbackServiceImpl implements IEventCallbackService{ ...@@ -45,6 +49,9 @@ public class EventCallbackServiceImpl implements IEventCallbackService{
private FeiShuUtil feiShuUtil; private FeiShuUtil feiShuUtil;
@Autowired @Autowired
private T100Util t100Util; private T100Util t100Util;
@Autowired
private QinCeUtils qinCeUtils;
@Override @Override
public void planCP(EventCallBackDto.Event event) { public void planCP(EventCallBackDto.Event event) {
...@@ -214,6 +221,93 @@ public class EventCallbackServiceImpl implements IEventCallbackService{ ...@@ -214,6 +221,93 @@ public class EventCallbackServiceImpl implements IEventCallbackService{
deptAndUserService.userResigned(employeeNo); deptAndUserService.userResigned(employeeNo);
} }
/**
* 获取最小销售价自动设置勤策最小单元售价
*/
@Override
public void getMinimumSellingPrice(EventCallBackDto.Event event ,String approveTemplateCode) {
String fsInstanceId = event.getFsInstanceId();
String approvalInfo = feiShuUtil.getApprovalInfo(fsInstanceId);
log.info("开始处理审批单:{}",fsInstanceId);
log.info("审批单信息:{}",approvalInfo);
if (StringUtils.isBlank(approvalInfo)){
String errorMsg = "审批单" + fsInstanceId + "不存在,终止处理";
log.error("审批单不存在:{}",fsInstanceId);
// 调用封装的错误日志记录方法
recordErrorLog("FeiShu sync QinCe Price ", "FeiShu sync", "fsInstanceId:" + fsInstanceId, errorMsg);
return;
}
// 获取审批单字段ID
Map<String, Object> fieldIdMap = feiShuUtil.getApprovalFormValues(approvalInfo);
if (fieldIdMap.isEmpty()){
String errorMsg = "获取审批单字段ID失败,终止处理";
log.error("获取审批单字段ID失败:{}",approvalInfo);
// 调用封装的错误日志记录方法
recordErrorLog("FeiShu sync QinCe Price ", "FeiShu sync", "approvalInfo:" + approvalInfo, errorMsg);
return;
}
Object productSpec = fieldIdMap.get("productSpec");
String productName = (String)fieldIdMap.get("productName");
String productCode = (String)fieldIdMap.get("productCode");
Object productPrice = fieldIdMap.get("supplyPrice");
if (StringUtils.isBlank(productCode) || productSpec == null || productPrice == null) {
String errorMsg = String.format("审批单%s核心字段缺失:编码=%s, 箱规=%s, 供货价=%s",
fsInstanceId, productCode, productSpec, productPrice);
log.error(errorMsg);
// 调用封装的错误日志记录方法
recordErrorLog("QinCe price sync", "QinCe price", "审批单ID:" + fsInstanceId, errorMsg);
return;
}
Integer productSpecValue = Integer.parseInt(productSpec.toString());
BigDecimal productPriceValue = new BigDecimal(productPrice.toString());
BigDecimal minSellingPrice = productPriceValue.multiply(new BigDecimal(productSpecValue));
log.info("审批单{}解析完成:产品名称={}, 编码={}, 箱规={}, 供货价={}, 最小售价={}", fsInstanceId, productName, productCode, productSpec, productPrice, minSellingPrice);
// 根据产品编码查询勤策的商品信息
try {
// 查询勤策商品完整JSON(包含所有原有字段:商品ID、第三方ID等)
com.alibaba.fastjson.JSONObject qinCeProductJson = qinCeUtils.queryProductInfo(productCode);
if (qinCeProductJson == null || qinCeProductJson.isEmpty()) {
String errorMsg = "勤策未查询到产品编码为" + productCode + "的商品信息";
log.error(errorMsg);
recordErrorLog("QinCe price sync", "QinCe price", "产品编码:" + productCode, errorMsg);
return;
}
log.info("从勤策查询到的原始JSON:{}", qinCeProductJson.toJSONString());
// 校验勤策商品单位信息
if (qinCeProductJson.getJSONArray("prd_units") != null &&
qinCeProductJson.getJSONArray("prd_units").size() <= 1) {
String message = String.format("检测产品编码 %s 的单位信息可能未进行转换", productCode);
feiShuUtil.sendMessageToUserByEmployeeId(message);
}
com.alibaba.fastjson.JSONObject updateJson = buildQinCeModifyParam(qinCeProductJson, minSellingPrice);
// 修改勤策商品信息
boolean isModified = qinCeUtils.modifyProductByFullJson(updateJson);
log.info("同步价格到勤策结果:产品编码={},最小售价={},同步成功={}",
productCode, minSellingPrice, isModified);
// 日志记录
recordErrorLog("QinCe suggest price sync", "QinCe price",
String.format("产品编码:%s,修改字段:prd_suggest_price,修改后值:%s", productCode, minSellingPrice),
isModified ? "同步成功" : "同步失败");
} catch (Exception e) {
String errorMsg = "处理勤策商品信息异常:" + e.getMessage();
log.error("处理勤策商品信息时发生异常,产品编码:{}", productCode, e);
recordErrorLog("QinCe price sync error", "QinCe price", "产品编码:" + productCode, errorMsg);
}
}
private void userAUT100(Employee emp){ private void userAUT100(Employee emp){
String departmentIdV2 = emp.getDepartmentIdV2(); String departmentIdV2 = emp.getDepartmentIdV2();
Department dept = feiShuUtil.getDepartmentCorehr(departmentIdV2); Department dept = feiShuUtil.getDepartmentCorehr(departmentIdV2);
...@@ -284,4 +378,82 @@ public class EventCallbackServiceImpl implements IEventCallbackService{ ...@@ -284,4 +378,82 @@ public class EventCallbackServiceImpl implements IEventCallbackService{
userJson.put("payload",payload); userJson.put("payload",payload);
return t100Util.createOrUpdateUser(userJson); return t100Util.createOrUpdateUser(userJson);
} }
private void recordErrorLog(String eventName, String eventGroup, String requestMsg, String responseMsg) {
try {
SysEventLogDto sysEventLogDto = new SysEventLogDto()
.setEventName(eventName)
.setEventGroup(eventGroup)
.setRequestMsg(JSONObject.toJSONString(requestMsg))
.setResponseMsg(responseMsg);
sysEventLogDao.insert(sysEventLogDto);
} catch (Exception e) {
// 日志记录失败时不影响主流程,仅打印错误
log.error("记录系统错误日志失败,事件名称:{},请求信息:{}", eventName, requestMsg, e);
}
}
private com.alibaba.fastjson.JSONObject buildQinCeModifyParam(com.alibaba.fastjson.JSONObject qinCeProductJson, BigDecimal minSellingPrice) {
com.alibaba.fastjson.JSONObject modifyParam = new com.alibaba.fastjson.JSONObject();
// ========== 定义销售状态映射(文字↔数值) ==========
Map<String, String> saleStatusMap = new HashMap<>();
saleStatusMap.put("停售", "0");
saleStatusMap.put("在售", "1");
saleStatusMap.put("0", "停售");
saleStatusMap.put("1", "在售");
// ========== 2. 顶级字段(严格匹配勤策接口示例字段名) ==========
// 核心标识字段
modifyParam.put("prd_id", StringUtils.defaultString(qinCeProductJson.getString("prd_id")));
// 排序/价格字段
modifyParam.put("prd_suggest_price", minSellingPrice == null ? BigDecimal.ZERO : minSellingPrice);
// 销售状态(核心:停售→在售,映射为标准数值)
String originalSaleStatus = qinCeProductJson.getString("prd_sale_status");
String standardSaleStatus = StringUtils.defaultString(originalSaleStatus);
// 转换为标准数值(0=停售,1=在售)
if (saleStatusMap.containsKey(standardSaleStatus)) {
standardSaleStatus = standardSaleStatus.matches("[01]") ? standardSaleStatus : saleStatusMap.get(standardSaleStatus);
}
// 强制停售→在售
modifyParam.put("prd_sale_status", standardSaleStatus);
// 标签值
String tagValues = String.join(",",
StringUtils.defaultString(qinCeProductJson.getString("with_tag_hot")),
StringUtils.defaultString(qinCeProductJson.getString("with_tag_gift")),
StringUtils.defaultString(qinCeProductJson.getString("with_tag_new")),
StringUtils.defaultString(qinCeProductJson.getString("with_tag_sale")),
StringUtils.defaultString(qinCeProductJson.getString("with_tag_ex1"))
).replaceAll("^,|,$", "");
modifyParam.put("tag_values", tagValues);
modifyParam.put("prd_price", qinCeProductJson.getBigDecimal("prd_price") == null ? BigDecimal.ZERO : qinCeProductJson.getBigDecimal("prd_price"));
com.alibaba.fastjson.JSONArray units = new com.alibaba.fastjson.JSONArray();
com.alibaba.fastjson.JSONArray sourcePrdUnits = qinCeProductJson.getJSONArray("prd_units");
if (sourcePrdUnits != null && !sourcePrdUnits.isEmpty()) {
for (int i = 0; i < sourcePrdUnits.size(); i++) {
com.alibaba.fastjson.JSONObject sourceUnit = sourcePrdUnits.getJSONObject(i);
if (sourceUnit == null) continue;
com.alibaba.fastjson.JSONObject unit = new com.alibaba.fastjson.JSONObject();
// 单位字段严格映射为勤策要求的名称
unit.put("name", StringUtils.defaultString(sourceUnit.getString("prd_unit_name")));
unit.put("is_base", StringUtils.defaultString(sourceUnit.getString("prd_is_base")));
unit.put("ratio", sourceUnit.getBigDecimal("prd_ratio") == null ? 1.00000000 : sourceUnit.getBigDecimal("prd_ratio").doubleValue());
unit.put("bar_code", StringUtils.defaultString(sourceUnit.getString("prd_barcode")));
unit.put("weight", StringUtils.defaultString(sourceUnit.getString("prd_weight")));
unit.put("weight_unit", StringUtils.defaultString(sourceUnit.getString("prd_weight_unit")));
units.add(unit);
}
}
modifyParam.put("units", units);
return modifyParam;
}
} }
...@@ -19,4 +19,10 @@ public interface IEventCallbackService { ...@@ -19,4 +19,10 @@ public interface IEventCallbackService {
void userUpdateByPersonId(String personId); void userUpdateByPersonId(String personId);
void userResigned(String employmentId); void userResigned(String employmentId);
/**
* 自动获取最小销售价设置给勤策
* @param event
*/
void getMinimumSellingPrice(EventCallBackDto.Event event , String approveTemplateCode);
} }
...@@ -52,6 +52,11 @@ public class QinCeUtils { ...@@ -52,6 +52,11 @@ public class QinCeUtils {
public static final String MODIFY_USER = "/api/employee/v3/modifyEmployee/"; public static final String MODIFY_USER = "/api/employee/v3/modifyEmployee/";
// 商品信息查询
public static final String QUERY_PRODUCT_INFO = "/api/product/v1/queryProduct/";
// 商品价格更新
public static final String MODIFY_PRODUCT_PRICE = "/api/pd/v2/modifyProduct/";
public String builderUrl(String sidepath, Map<String, Object> params) { public String builderUrl(String sidepath, Map<String, Object> params) {
String msgId = UUID.randomUUID().toString(); String msgId = UUID.randomUUID().toString();
...@@ -129,4 +134,66 @@ public class QinCeUtils { ...@@ -129,4 +134,66 @@ public class QinCeUtils {
JSONObject jsonObject = postQC(url, params); JSONObject jsonObject = postQC(url, params);
return jsonObject.getJSONArray("response_data"); return jsonObject.getJSONArray("response_data");
} }
/**
* 构建勤策商品查询参数(贴合官方queryProduct接口要求)
* @param productCode 产品编码(官方必传字段)
* @return 符合官方规范的查询参数
*/
public Map<String, Object> queryProductOfficialParams(String productCode) {
Map<String, Object> params = new HashMap<>();
// 官方必传:产品编码(prd_code为勤策官方字段名)
params.put("prd_code", productCode);
return params;
}
/**
* 调用勤策官方查询商品接口(pd/v2/queryProduct)
* @param productCode 产品编码
* @return 商品信息JSON对象(返回第一条数据)
* @throws Exception 接口调用异常
*/
public JSONObject queryProductInfo(String productCode) throws Exception {
Map<String, Object> params = queryProductOfficialParams(productCode);
String url = builderUrl(QUERY_PRODUCT_INFO, params);
log.info("调用勤策官方商品查询接口,URL:{},参数:{}", url, params);
JSONObject result = postQC(url, params);
JSONArray dataArray = result.getJSONArray("response_data");
return CollectionUtils.isEmpty(dataArray) ? null : dataArray.getJSONObject(0);
}
public boolean modifyProductByFullJson(JSONObject fullProductJson) {
// 空值校验
if (fullProductJson == null || fullProductJson.isEmpty()) {
log.error("勤策修改商品的JSON为空,无法调用接口");
return false;
}
try {
// 将JSONObject转为Map,满足builderUrl生成digest的要求(你原有逻辑依赖Map)
Map<String, Object> modifyParams = JSONObject.parseObject(fullProductJson.toJSONString(), Map.class);
// 复用你原有builderUrl方法生成接口地址(传入修改参数Map)
String url = builderUrl(MODIFY_PRODUCT_PRICE, modifyParams);
log.info("调用勤策商品修改接口,URL:{},参数:{}", url, modifyParams);
// 复用你原有postQC方法(保持异常抛出逻辑一致)
JSONObject respObj = postQC(url, modifyParams);
// 解析返回结果(沿用你原有return_code校验逻辑)
String returnCode = respObj.getString("return_code");
if ("0".equals(returnCode)) {
log.info("勤策商品修改成功,修改字段:prd_suggest_price,商品编码:{}", fullProductJson.getString("prd_code"));
return true;
} else {
log.error("勤策商品修改失败,返回信息:{}", respObj);
return false;
}
} catch (Exception e) {
log.error("调用勤策修改商品接口异常,JSON:{}", fullProductJson.toJSONString(), e);
return false;
}
}
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论