Merge remote-tracking branch 'origin/develop' into develop
commit
5851bcb479
@ -0,0 +1,26 @@
|
||||
package cn.iocoder.yudao.module.crm.enums;
|
||||
|
||||
/**
|
||||
* CRM 操作日志枚举
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
public interface LogRecordConstants {
|
||||
|
||||
//======================= 客户模块类型 =======================
|
||||
// TODO puhui999: 确保模块命名方式为 module + 子模块名称的方式。统一定义模块名称是为了方便查询各自记录的操作日志,列如说:查询客户【张三的操作日志】就可以 module + bizId
|
||||
String CRM_LEADS = "CRM-线索";
|
||||
String CRM_CUSTOMER = "CRM-客户";
|
||||
String CRM_CONTACT = "CRM-联系人";
|
||||
String CRM_BUSINESS = "CRM-商机";
|
||||
String CRM_CONTRACT = "CRM-合同";
|
||||
String CRM_PRODUCT = "CRM-产品";
|
||||
String CRM_RECEIVABLE = "CRM-回款";
|
||||
String CRM_RECEIVABLE_PLAN = "CRM-回款计划";
|
||||
|
||||
//======================= 客户转移操作日志 =======================
|
||||
|
||||
String TRANSFER_CUSTOMER_LOG_SUCCESS = "把客户【{{#crmCustomer.name}}】的负责人从【{getAdminUserById{#crmCustomer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】";
|
||||
String TRANSFER_CUSTOMER_LOG_FAIL = "";
|
||||
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.clue.vo;
|
||||
|
||||
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 线索转移 Request VO")
|
||||
@Data
|
||||
public class CrmClueTransferReqVO {
|
||||
|
||||
@Schema(description = "线索编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||
@NotNull(message = "线索编号不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 新负责人的用户编号
|
||||
*/
|
||||
@Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||
@NotNull(message = "新负责人的用户编号不能为空")
|
||||
private Long newOwnerUserId;
|
||||
|
||||
/**
|
||||
* 老负责人加入团队后的权限级别。如果 null 说明移除
|
||||
*
|
||||
* 关联 {@link CrmPermissionLevelEnum}
|
||||
*/
|
||||
@Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Integer oldOwnerPermissionLevel;
|
||||
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan;
|
||||
|
||||
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 回款计划转移 Request VO")
|
||||
@Data
|
||||
public class CrmReceivablePlanTransferReqVO {
|
||||
|
||||
@Schema(description = "回款计划编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||
@NotNull(message = "回款计划编号不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 新负责人的用户编号
|
||||
*/
|
||||
@Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||
@NotNull(message = "新负责人的用户编号不能为空")
|
||||
private Long newOwnerUserId;
|
||||
|
||||
/**
|
||||
* 老负责人加入团队后的权限级别。如果 null 说明移除
|
||||
*
|
||||
* 关联 {@link CrmPermissionLevelEnum}
|
||||
*/
|
||||
@Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Integer oldOwnerPermissionLevel;
|
||||
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable;
|
||||
|
||||
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - CRM 回款转移 Request VO")
|
||||
@Data
|
||||
public class CrmReceivableTransferReqVO {
|
||||
|
||||
@Schema(description = "回款编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||
@NotNull(message = "回款编号不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 新负责人的用户编号
|
||||
*/
|
||||
@Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
|
||||
@NotNull(message = "新负责人的用户编号不能为空")
|
||||
private Long newOwnerUserId;
|
||||
|
||||
/**
|
||||
* 老负责人加入团队后的权限级别。如果 null 说明移除
|
||||
*
|
||||
* 关联 {@link CrmPermissionLevelEnum}
|
||||
*/
|
||||
@Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Integer oldOwnerPermissionLevel;
|
||||
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package cn.iocoder.yudao.module.crm.framework.bizlog.function;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
|
||||
import com.mzt.logapi.service.IParseFunction;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY;
|
||||
|
||||
/**
|
||||
* 自定义函数-通过行业编号获取行业信息
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CrmIndustryParseFunction implements IParseFunction {
|
||||
|
||||
@Override
|
||||
public boolean executeBefore() {
|
||||
return true; // 先转换值后对比
|
||||
}
|
||||
|
||||
@Override
|
||||
public String functionName() {
|
||||
return "getIndustryById";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apply(Object value) {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
if (StrUtil.isEmpty(value.toString())) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// 获取行业信息
|
||||
try {
|
||||
return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_INDUSTRY, value.toString());
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package cn.iocoder.yudao.module.crm.framework.bizlog.function;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
|
||||
import com.mzt.logapi.service.IParseFunction;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_LEVEL;
|
||||
|
||||
/**
|
||||
* 自定义函数-通过客户等级编号获取客户等级信息
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CrmLevelParseFunction implements IParseFunction {
|
||||
|
||||
@Override
|
||||
public boolean executeBefore() {
|
||||
return true; // 先转换值后对比
|
||||
}
|
||||
|
||||
@Override
|
||||
public String functionName() {
|
||||
return "getLevel";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apply(Object value) {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
if (StrUtil.isEmpty(value.toString())) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// 获取客户等级信息
|
||||
try {
|
||||
return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_LEVEL, value.toString());
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package cn.iocoder.yudao.module.crm.framework.bizlog.function;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
|
||||
import com.mzt.logapi.service.IParseFunction;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_SOURCE;
|
||||
|
||||
/**
|
||||
* 自定义函数-通过客户来源编号获取客户来源信息
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CrmSourceParseFunction implements IParseFunction {
|
||||
|
||||
@Override
|
||||
public boolean executeBefore() {
|
||||
return true; // 先转换值后对比
|
||||
}
|
||||
|
||||
@Override
|
||||
public String functionName() {
|
||||
return "getSource";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apply(Object value) {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
if (StrUtil.isEmpty(value.toString())) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// 获取客户来源信息
|
||||
try {
|
||||
return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_SOURCE, value.toString());
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
package cn.iocoder.yudao.module.crm.framework.bizlog;
|
||||
@ -0,0 +1,42 @@
|
||||
package cn.iocoder.yudao.module.trade.controller.app.aftersale;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.log.AppAfterSaleLogRespVO;
|
||||
import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleLogDO;
|
||||
import cn.iocoder.yudao.module.trade.service.aftersale.AfterSaleLogService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
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 java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 售后日志")
|
||||
@RestController
|
||||
@RequestMapping("/trade/after-sale-log")
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class AppAfterSaleLogController {
|
||||
|
||||
@Resource
|
||||
private AfterSaleLogService afterSaleLogService;
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得售后日志列表")
|
||||
@Parameter(name = "afterSaleId", description = "售后编号", required = true, example = "1")
|
||||
public CommonResult<List<AppAfterSaleLogRespVO>> getAfterSaleLogList(
|
||||
@RequestParam("afterSaleId") Long afterSaleId) {
|
||||
List<AfterSaleLogDO> logs = afterSaleLogService.getAfterSaleLogList(afterSaleId);
|
||||
return success(BeanUtils.toBean(logs, AppAfterSaleLogRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package cn.iocoder.yudao.module.system.dal.mysql.logger;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface OperateLogV2Mapper extends BaseMapperX<OperateLogV2DO> {
|
||||
|
||||
default PageResult<OperateLogV2DO> selectPage(OperateLogPageReqVO reqVO, Collection<Long> userIds) {
|
||||
LambdaQueryWrapperX<OperateLogV2DO> query = new LambdaQueryWrapperX<OperateLogV2DO>()
|
||||
.likeIfPresent(OperateLogV2DO::getModule, reqVO.getModule())
|
||||
.inIfPresent(OperateLogV2DO::getUserId, userIds);
|
||||
query.orderByDesc(OperateLogV2DO::getId); // 降序
|
||||
return selectPage(reqVO, query);
|
||||
}
|
||||
|
||||
default List<OperateLogV2DO> selectListByModuleAndBizId(String module, Long bizId) {
|
||||
return selectList(new LambdaQueryWrapperX<OperateLogV2DO>()
|
||||
.eq(OperateLogV2DO::getModule, module)
|
||||
.eq(OperateLogV2DO::getBizId, bizId)
|
||||
.orderByDesc(OperateLogV2DO::getCreateTime));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package cn.iocoder.yudao.module.system.framework.bizlog.config;
|
||||
|
||||
import com.mzt.logapi.starter.annotation.EnableLogRecord;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* mzt-biz-log 配置类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableLogRecord(tenant = "") // 貌似用不上 tenant 这玩意给个空好啦
|
||||
public class YudaoOperateLogV2Configuration {
|
||||
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
package cn.iocoder.yudao.module.system.framework.bizlog.function;
|
||||
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import com.mzt.logapi.service.IParseFunction;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 自定义函数-通过用户编号获取用户信息
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AdminUserParseFunction implements IParseFunction {
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@Override
|
||||
public String functionName() {
|
||||
return "getAdminUserById";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apply(Object value) {
|
||||
if (value == null) {
|
||||
//log.warn("(getAdminUserById) 解析异常参数为 null");
|
||||
return "";
|
||||
}
|
||||
if (StrUtil.isEmpty(value.toString())) {
|
||||
//log.warn("(getAdminUserById) 解析异常参数为空");
|
||||
return "";
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
AdminUserRespDTO user = adminUserApi.getUser(Long.parseLong(value.toString()));
|
||||
if (user == null) {
|
||||
log.warn("(getAdminUserById) 获取用户信息失败,参数为:{}", value);
|
||||
return "";
|
||||
}
|
||||
// 返回格式 芋道源码(13888888888)
|
||||
String nickname = user.getNickname();
|
||||
if (ObjUtil.isNotEmpty(user.getMobile())) {
|
||||
return nickname.concat("(").concat(user.getMobile()).concat(")");
|
||||
}
|
||||
return nickname;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
package cn.iocoder.yudao.module.system.framework.bizlog.function;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
|
||||
import com.mzt.logapi.service.IParseFunction;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 自定义函数-通过区域编号获取区域信息
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AreaParseFunction implements IParseFunction {
|
||||
|
||||
@Override
|
||||
public boolean executeBefore() {
|
||||
return true; // 先转换值后对比
|
||||
}
|
||||
|
||||
@Override
|
||||
public String functionName() {
|
||||
return "getAreaById";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apply(Object value) {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
if (StrUtil.isEmpty(value.toString())) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return AreaUtils.format(Integer.parseInt(value.toString()));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
package cn.iocoder.yudao.module.system.framework.bizlog;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue