Quellcode durchsuchen

系统客服值班变更记录明细;客服退款每月明细;增加双重验证明细

zoujiajian vor 2 Jahren
Ursprung
Commit
e49ec53067
19 geänderte Dateien mit 355 neuen und 24 gelöschten Zeilen
  1. 7 0
      netflix-common/src/main/java/com/cyksj/common/constant/Constant.java
  2. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/UserDoubleVerifyCodeChangeRecordMapper.java
  3. 55 0
      netflix-dao/src/main/java/com/cyksj/model/dto/YhServiceChangeDto.java
  4. 2 0
      netflix-dao/src/main/java/com/cyksj/model/dto/YhServiceDto.java
  5. 2 0
      netflix-dao/src/main/java/com/cyksj/model/entity/RefundOrderDon.java
  6. 2 0
      netflix-dao/src/main/java/com/cyksj/model/entity/SysConfigChangeRecord.java
  7. 22 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserDoubleVerifyCodeChangeRecord.java
  8. 2 0
      netflix-dao/src/main/java/com/cyksj/model/request/OrderRefundReq.java
  9. 30 0
      netflix-dao/src/main/java/com/cyksj/model/views/RefundOrderDonServiceDataView.java
  10. 1 1
      netflix-service/src/main/java/com/cyksj/common/service/CropDutyServiceDateService.java
  11. 7 7
      netflix-service/src/main/java/com/cyksj/service/mange/impl/CmsOrderDonServiceImpl.java
  12. 1 1
      netflix-service/src/main/java/com/cyksj/service/order/OrderRefundService.java
  13. 1 1
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
  14. 2 1
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderRefundServiceImpl.java
  15. 1 1
      netflix-service/src/main/java/com/cyksj/service/scheduler/impl/SchedulerServiceImpl.java
  16. 107 4
      netflix-service/src/main/java/com/cyksj/service/sys/impl/SysConfigChangeRecordServiceImpl.java
  17. 45 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsOrderController.java
  18. 33 5
      netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsUserController.java
  19. 22 3
      netflix-web/src/main/java/com/cyksj/web/controller/sys/SysConfigController.java

+ 7 - 0
netflix-common/src/main/java/com/cyksj/common/constant/Constant.java

@@ -250,4 +250,11 @@ public interface Constant {
 	 * 获客链接 值班客服更新定时任务id
 	 * 获客链接 值班客服更新定时任务id
 	 */
 	 */
 	Integer CORP_LINK_JOB_ID = 192;
 	Integer CORP_LINK_JOB_ID = 192;
+
+	String DUTY_SERVICE_CHANGE_MSG = "%s值班人员不足三人【银河录像局】";
+
+	/**
+	 * 系统周末值班客服变更通知手机号
+	 */
+	String DUTY_SERVICE_CHANGE_NOTIFY_PHONE = "17681947535";
 }
 }

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/UserDoubleVerifyCodeChangeRecordMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.UserDoubleVerifyCodeChangeRecord;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: UserDoubleVerifyCodeChangeRecordMapper
+ * 创建者: JavaZou
+ * 创建时间:2024/1/8 16:48
+ */
+public interface UserDoubleVerifyCodeChangeRecordMapper extends BaseMapper<UserDoubleVerifyCodeChangeRecord> {
+}

+ 55 - 0
netflix-dao/src/main/java/com/cyksj/model/dto/YhServiceChangeDto.java

@@ -0,0 +1,55 @@
+package com.cyksj.model.dto;
+
+import cn.hutool.core.util.StrUtil;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: YhServiceChangeDto
+ * 创建者: JavaZou
+ * 创建时间:2024/1/8 17:52
+ */
+@Getter
+@Setter
+public class YhServiceChangeDto {
+	private List<String> beforeSelect;
+
+	private List<String> afterSelect;
+
+	private String sign;
+
+	private Integer index;
+
+	private String date;
+
+	private String workType;
+
+	public String toChangeString() {
+		StringBuilder sb = new StringBuilder();
+		if (StrUtil.equals(sign, "workday")) {
+			sb.append("工作日").append(index == 1 ? "早班" : "晚班");
+		} else if (StrUtil.equals(sign, "Saturday")) {
+			sb.append("周六").append(index == 3 ? "早班" : "晚班");
+		} else if (StrUtil.equals(sign, "Sunday")) {
+			sb.append("周日").append(index == 5 ? "早班" : "晚班");
+		} else {
+			sb.append("节假日").append(date).append(workType);
+		}
+		if (beforeSelect.size() > 0) {
+			sb.append(" - 移除 - ");
+			String beforeCollect = beforeSelect.stream().collect(Collectors.joining("、"));
+			sb.append(beforeCollect);
+		}
+
+		if (afterSelect.size() > 0) {
+			sb.append(" - 增加 - ");
+			String afterCollect = afterSelect.stream().collect(Collectors.joining("、"));
+			sb.append(afterCollect);
+		}
+		return sb.toString();
+	}
+}

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/model/dto/YhServiceDto.java

@@ -39,6 +39,8 @@ public class YhServiceDto {
 
 
 	private String date;
 	private String date;
 
 
+	private String workType;
+
 
 
 	@Getter
 	@Getter
 	@Setter
 	@Setter

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/RefundOrderDon.java

@@ -58,4 +58,6 @@ public class RefundOrderDon extends BaseEntity{
 	 * 默认false
 	 * 默认false
 	 */
 	 */
 	private Boolean isClearBalance;
 	private Boolean isClearBalance;
+
+	private String operator;
 }
 }

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/SysConfigChangeRecord.java

@@ -19,4 +19,6 @@ public class SysConfigChangeRecord extends BaseEntity{
 	private String backValue;
 	private String backValue;
 
 
 	private String operator;
 	private String operator;
+
+	private String changeStr;
 }
 }

+ 22 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserDoubleVerifyCodeChangeRecord.java

@@ -0,0 +1,22 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: UserDoubleVerifyCodeChangeRecord
+ * 创建者: JavaZou
+ * 创建时间:2024/1/8 16:46
+ */
+@Getter
+@Setter
+public class UserDoubleVerifyCodeChangeRecord extends BaseEntity{
+	private Long userId;
+
+	private Integer oldVerifyCheckNum;
+
+	private Integer verifyCheckNum;
+
+	private String operator;
+}

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/model/request/OrderRefundReq.java

@@ -39,4 +39,6 @@ public class OrderRefundReq {
 	 * 补差价余额
 	 * 补差价余额
 	 */
 	 */
 	private BigDecimal refundBalance;
 	private BigDecimal refundBalance;
+
+	private String operator;
 }
 }

+ 30 - 0
netflix-dao/src/main/java/com/cyksj/model/views/RefundOrderDonServiceDataView.java

@@ -0,0 +1,30 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: RefundOrderDonServiceDataView
+ * 创建者: JavaZou
+ * 创建时间:2024/1/8 17:03
+ */
+@Getter
+@Setter
+@SearchBean(tables = "refund_order_don rd inner join order_don o on o.id = rd.order_id :time:",
+		where = "rd.refund_method not in ('EX_CODE','balance')",
+		groupBy = "rd.operator")
+public class RefundOrderDonServiceDataView {
+	@DbField("rd.operator")
+	private String operator;
+
+	@DbField("count(distinct rd.order_id)")
+	private Integer orders;
+
+	@DbField("sum(rd.refund_fee)/100")
+	private BigDecimal refundMoney;
+}

+ 1 - 1
netflix-service/src/main/java/com/cyksj/common/service/CropDutyServiceDateService.java

@@ -34,7 +34,7 @@ public class CropDutyServiceDateService {
 	/**
 	/**
 	 * 返回明天星期几 用户获取对应周期工作客服
 	 * 返回明天星期几 用户获取对应周期工作客服
 	 */
 	 */
-	public static List<YhServiceDto> getDutyService(DayOfWeek nextWorkDay, List<YhServiceDto> workday, List<YhServiceDto> sunday, List<YhServiceDto> saturday, Map<String, List<YhServiceDto>> holidyDateMap, LocalDateTime now) {
+	public static List<YhServiceDto> getDutyService(DayOfWeek nextWorkDay, List<YhServiceDto> workday, List<YhServiceDto> saturday, List<YhServiceDto> sunday, Map<String, List<YhServiceDto>> holidyDateMap, LocalDateTime now) {
 		List<YhServiceDto> holidayServiceIfHoliday = getHolidayServiceIfHoliday(now, holidyDateMap);
 		List<YhServiceDto> holidayServiceIfHoliday = getHolidayServiceIfHoliday(now, holidyDateMap);
 		if (holidayServiceIfHoliday != null) {
 		if (holidayServiceIfHoliday != null) {
 			return holidayServiceIfHoliday;
 			return holidayServiceIfHoliday;

+ 7 - 7
netflix-service/src/main/java/com/cyksj/service/mange/impl/CmsOrderDonServiceImpl.java

@@ -332,7 +332,7 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
         String outNo = orderRefundService.centerRefund(refundReq, orderDon);
         String outNo = orderRefundService.centerRefund(refundReq, orderDon);
         orderDon.setRefundDesc(refundReq.getRefundDesc());
         orderDon.setRefundDesc(refundReq.getRefundDesc());
         //记录退款信息
         //记录退款信息
-	    commonRefund(orderDon, refundReq.getRefundMoney(), goodsDon, sku, outNo, refundType);
+        commonRefund(orderDon, refundReq.getRefundMoney(), refundReq.getOperator(), goodsDon, sku, outNo, refundType);
         //修改订单状态
         //修改订单状态
         orderDon.setStatus(OrderDon.Status.refund);
         orderDon.setStatus(OrderDon.Status.refund);
         orderDonMapper.updateById(orderDon);
         orderDonMapper.updateById(orderDon);
@@ -695,9 +695,9 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
     /**
     /**
      * 退款后 处理关联
      * 退款后 处理关联
      */
      */
-    public void commonRefund(OrderDon orderDon, BigDecimal refundMoney, GoodsDon goodsDon, GoodsDonSku sku, String outNo, String refundType) {
+    public void commonRefund(OrderDon orderDon, BigDecimal refundMoney, String operator, GoodsDon goodsDon, GoodsDonSku sku, String outNo, String refundType) {
         TASK_POOL.execute(() -> {
         TASK_POOL.execute(() -> {
-            orderRefundService.refundRecord(orderDon, refundMoney, goodsDon, sku, outNo, refundType);
+            orderRefundService.refundRecord(orderDon, refundMoney, operator, goodsDon, sku, outNo, refundType);
             //退款一次
             //退款一次
             goodsDonStockService.upStockRelate(null, orderDon.getId(), "refund");
             goodsDonStockService.upStockRelate(null, orderDon.getId(), "refund");
             try {
             try {
@@ -783,7 +783,7 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
                             List<OrderDon> relate_orderDons = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class)
                             List<OrderDon> relate_orderDons = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class)
                                     .in(OrderDon::getId, plusOrderIdList)
                                     .in(OrderDon::getId, plusOrderIdList)
                                     .notIn(OrderDon::getStatus, Constant.noOrderStatus));
                                     .notIn(OrderDon::getStatus, Constant.noOrderStatus));
-                            relate_orderDons.forEach(relate_o->{
+                            relate_orderDons.forEach(relate_o -> {
                                 //扣除用户自身实物权益
                                 //扣除用户自身实物权益
                                 userRealOrderBenefitsService.deductUserRealGoodsBenefits(relate_o.getId());
                                 userRealOrderBenefitsService.deductUserRealGoodsBenefits(relate_o.getId());
                             });
                             });
@@ -803,10 +803,10 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
                         .in(GroupsRelationExpiryRecord::getReBuyOrderId, orderDon.getId())
                         .in(GroupsRelationExpiryRecord::getReBuyOrderId, orderDon.getId())
                         .eq(GroupsRelationExpiryRecord::getRelationId, orderDon.getRelationId()).last("limit 1"));
                         .eq(GroupsRelationExpiryRecord::getRelationId, orderDon.getRelationId()).last("limit 1"));
                 if (groupsRelationExpiryRecord == null) {
                 if (groupsRelationExpiryRecord == null) {
-                    log.info("订单orderId:{}退款,同步是否有重购记录不是直接续费车票",orderDon.getId());
+                    log.info("订单orderId:{}退款,同步是否有重购记录不是直接续费车票", orderDon.getId());
                     List<GroupsRelationExpiryRecord> groupsRelationExpiryRecords = groupsRelationExpiryRecordService.list(Wrappers.lambdaQuery(GroupsRelationExpiryRecord.class)
                     List<GroupsRelationExpiryRecord> groupsRelationExpiryRecords = groupsRelationExpiryRecordService.list(Wrappers.lambdaQuery(GroupsRelationExpiryRecord.class)
                             .in(GroupsRelationExpiryRecord::getReBuyOrderId, orderDon.getId()));
                             .in(GroupsRelationExpiryRecord::getReBuyOrderId, orderDon.getId()));
-                    log.info("订单orderId:{}退款,重购记录不是直接续费车票大小:{}",groupsRelationExpiryRecords.size());
+                    log.info("订单orderId:{}退款,重购记录不是直接续费车票大小:{}", groupsRelationExpiryRecords.size());
                     if (CollUtil.isNotEmpty(groupsRelationExpiryRecords)) {
                     if (CollUtil.isNotEmpty(groupsRelationExpiryRecords)) {
                         groupsRelationExpiryRecords.forEach(data -> {
                         groupsRelationExpiryRecords.forEach(data -> {
                             data.setIsReBuy(false);
                             data.setIsReBuy(false);
@@ -956,7 +956,7 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
             orderDonMapper.updateById(orderDon);
             orderDonMapper.updateById(orderDon);
         }
         }
 
 
-        orderRefundService.refundRecord(orderDon, refundMoney, goodsDon, sku, outNo, refundType);
+        orderRefundService.refundRecord(orderDon, refundMoney, orderRefundReq.getOperator(), goodsDon, sku, outNo, refundType);
     }
     }
 
 
     @Override
     @Override

+ 1 - 1
netflix-service/src/main/java/com/cyksj/service/order/OrderRefundService.java

@@ -20,5 +20,5 @@ public interface OrderRefundService {
 	/**
 	/**
 	 * 退款记录
 	 * 退款记录
 	 */
 	 */
-	void refundRecord(OrderDon orderDon, BigDecimal refundMoney, GoodsDon goodsDon, GoodsDonSku sku, String outRefundNo, String refundType);
+	void refundRecord(OrderDon orderDon, BigDecimal refundMoney, String operator, GoodsDon goodsDon, GoodsDonSku sku, String outRefundNo, String refundType);
 }
 }

+ 1 - 1
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java

@@ -2731,7 +2731,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		clearUserLockingRelation(groupsRelationMapper.selectById(orderDon.getRelationId()), orderDon);
 		clearUserLockingRelation(groupsRelationMapper.selectById(orderDon.getRelationId()), orderDon);
 
 
 		//记录退款
 		//记录退款
-		orderRefundService.refundRecord(orderDon, orderRefundReq.getRefundMoney(), goodsDon, sku, outNo, orderDon.getType().getType());
+		orderRefundService.refundRecord(orderDon, orderRefundReq.getRefundMoney(), null, goodsDon, sku, outNo, orderDon.getType().getType());
 		return;
 		return;
 	}
 	}
 }
 }

+ 2 - 1
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderRefundServiceImpl.java

@@ -84,7 +84,7 @@ public class OrderRefundServiceImpl implements OrderRefundService {
 	}
 	}
 
 
 	@Override
 	@Override
-	public void refundRecord(OrderDon orderDon, BigDecimal refundMoney, GoodsDon goodsDon, GoodsDonSku sku, String outRefundNo, String refundType) {
+	public void refundRecord(OrderDon orderDon, BigDecimal refundMoney, String operator, GoodsDon goodsDon, GoodsDonSku sku, String outRefundNo, String refundType) {
 		RefundOrderDon refund = new RefundOrderDon();
 		RefundOrderDon refund = new RefundOrderDon();
 		refund.setOrderId(orderDon.getId());
 		refund.setOrderId(orderDon.getId());
 		refund.setOutRefundNo(outRefundNo);
 		refund.setOutRefundNo(outRefundNo);
@@ -99,6 +99,7 @@ public class OrderRefundServiceImpl implements OrderRefundService {
 		refund.setSpecVal(sku == null ? null : String.format("%s%s", sku.getSpecVal(), sku.getPrice().divide(BigDecimal.valueOf(100))));
 		refund.setSpecVal(sku == null ? null : String.format("%s%s", sku.getSpecVal(), sku.getPrice().divide(BigDecimal.valueOf(100))));
 		refund.setRefundMethod(orderDon.getType().name());
 		refund.setRefundMethod(orderDon.getType().name());
 		refund.setGoodsType(goodsDon == null ? 0 : goodsDon.getType());
 		refund.setGoodsType(goodsDon == null ? 0 : goodsDon.getType());
+		refund.setOperator(operator);
 		//退款方式
 		//退款方式
 		if (StrUtil.isNotBlank(refundType) && refundType.equals(OrderDon.Type.BALANCE.getType())) {
 		if (StrUtil.isNotBlank(refundType) && refundType.equals(OrderDon.Type.BALANCE.getType())) {
 			refund.setRefundMethod(refundType);
 			refund.setRefundMethod(refundType);

+ 1 - 1
netflix-service/src/main/java/com/cyksj/service/scheduler/impl/SchedulerServiceImpl.java

@@ -220,7 +220,7 @@ public class SchedulerServiceImpl implements SchedulerService {
 							if (sku == null) return;
 							if (sku == null) return;
 							skuMap.putIfAbsent(orderDon.getSkuId(), sku);
 							skuMap.putIfAbsent(orderDon.getSkuId(), sku);
 						}
 						}
-						orderRefundService.refundRecord(orderDon, orderDon.getRefundMoney(), goodsDon, sku, StrUtil.EMPTY, "balance");
+						orderRefundService.refundRecord(orderDon, orderDon.getRefundMoney(), null, goodsDon, sku, StrUtil.EMPTY, "balance");
 						return;
 						return;
 					}
 					}
 					changeTickerRelation(item_groupsId, relationView, source, relationView.getYhsId());
 					changeTickerRelation(item_groupsId, relationView, source, relationView.getYhsId());

+ 107 - 4
netflix-service/src/main/java/com/cyksj/service/sys/impl/SysConfigChangeRecordServiceImpl.java

@@ -1,16 +1,29 @@
 package com.cyksj.service.sys.impl;
 package com.cyksj.service.sys.impl;
 
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.cyksj.common.EnvCommonService;
 import com.cyksj.common.constant.Constant;
 import com.cyksj.common.constant.Constant;
-import com.cyksj.mapper.sys.SysConfigChangeRecordMapper;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.common.util.Jsons;
+import com.cyksj.common.util.SmsUtil;
+import com.cyksj.enums.GatewayApiCode;
 import com.cyksj.mapper.manage.cms.CmsUserMapper;
 import com.cyksj.mapper.manage.cms.CmsUserMapper;
+import com.cyksj.mapper.sys.SysConfigChangeRecordMapper;
+import com.cyksj.model.dto.YhServiceChangeDto;
+import com.cyksj.model.dto.YhServiceDto;
+import com.cyksj.model.entity.CmsUser;
 import com.cyksj.model.entity.SysConfigChangeRecord;
 import com.cyksj.model.entity.SysConfigChangeRecord;
 import com.cyksj.service.sys.SysConfigChangeRecordService;
 import com.cyksj.service.sys.SysConfigChangeRecordService;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
-import java.util.Optional;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 
 
 /**
 /**
  * 项目名: yhlxj
  * 项目名: yhlxj
@@ -23,8 +36,14 @@ import java.util.Optional;
 public class SysConfigChangeRecordServiceImpl extends ServiceImpl<SysConfigChangeRecordMapper, SysConfigChangeRecord> implements SysConfigChangeRecordService {
 public class SysConfigChangeRecordServiceImpl extends ServiceImpl<SysConfigChangeRecordMapper, SysConfigChangeRecord> implements SysConfigChangeRecordService {
 	private final CmsUserMapper cmsUserMapper;
 	private final CmsUserMapper cmsUserMapper;
 
 
+	private final EnvCommonService envCommonService;
+
 	@Override
 	@Override
 	public Boolean changeRecord(Long adminId, String sysKey, String sysValue, String updateValue) throws Exception {
 	public Boolean changeRecord(Long adminId, String sysKey, String sysValue, String updateValue) throws Exception {
+		CmsUser cmsUser = cmsUserMapper.selectById(adminId);
+		if (cmsUser == null) {
+			throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
+		}
 		//保存客服系统配置key前后更新数据
 		//保存客服系统配置key前后更新数据
 		if (Constant.serviceKeys.contains(sysKey)) {
 		if (Constant.serviceKeys.contains(sysKey)) {
 			if (!StrUtil.equals(sysValue, updateValue)) {
 			if (!StrUtil.equals(sysValue, updateValue)) {
@@ -32,12 +51,96 @@ public class SysConfigChangeRecordServiceImpl extends ServiceImpl<SysConfigChang
 				sysConfigChangeRecord.setSysKey(sysKey);
 				sysConfigChangeRecord.setSysKey(sysKey);
 				sysConfigChangeRecord.setPreValue(sysValue);
 				sysConfigChangeRecord.setPreValue(sysValue);
 				sysConfigChangeRecord.setBackValue(updateValue);
 				sysConfigChangeRecord.setBackValue(updateValue);
-				Optional.ofNullable(cmsUserMapper.selectById(adminId))
-						.ifPresent(cm -> sysConfigChangeRecord.setOperator(cm.getNickname()));
+				sysConfigChangeRecord.setOperator(cmsUser.getNickname());
+				if (Constant.serviceKeys.get(0).equals(sysKey)) {
+					//变更记录
+					List<YhServiceDto> before = Jsons.parseList(sysValue, YhServiceDto.class);
+					List<YhServiceDto> after = Jsons.parseList(updateValue, YhServiceDto.class);
+					//周末值班人员缺失 通知
+					StringBuilder weekdayMsgNotifySb = new StringBuilder();
+					//客服值班变更记录
+					StringBuilder changeStr = new StringBuilder();
+					AtomicInteger saturdaySelect = new AtomicInteger(0);
+					AtomicInteger sundaySelect = new AtomicInteger(0);
+					for (int i = 0; i < before.size(); i++) {
+						YhServiceDto beforeServiceDto = before.get(i);
+						//节假日按钮 关闭开启不做处理
+						if (after.size() > i) {
+							YhServiceDto afterServiceDto = after.get(i);
+							//变更记录
+							YhServiceChangeDto changeService = getChangeService(beforeServiceDto, afterServiceDto);
+							if (changeService != null) {
+								if (changeStr.length() > 0) {
+									changeStr.append(";");
+								}
+								changeStr.append(changeService.toChangeString());
+							}
+
+							if ((StrUtil.equals(afterServiceDto.getSign(), "Saturday"))) {
+								saturdaySelect.addAndGet(afterServiceDto.getSelect().size());
+							}
+
+							if (StrUtil.equals(afterServiceDto.getSign(), "Sunday")) {
+								sundaySelect.addAndGet(afterServiceDto.getSelect().size());
+							}
+						}
+					}
+					if (saturdaySelect.get() != 0 && saturdaySelect.get() < 3) {
+						weekdayMsgNotifySb.append("周六");
+					}
+					if (sundaySelect.get() != 0 && sundaySelect.get() < 3) {
+						weekdayMsgNotifySb.append("周日");
+					}
+					if (changeStr.length() > 0) {
+						sysConfigChangeRecord.setChangeStr(changeStr.toString());
+					}
+					if (weekdayMsgNotifySb.length() > 0 && envCommonService.isPrdEnv()) {
+						SmsUtil.sendLuoKey2Msg(Constant.DUTY_SERVICE_CHANGE_NOTIFY_PHONE, String.format(Constant.DUTY_SERVICE_CHANGE_MSG, weekdayMsgNotifySb));
+					}
+				}
 				this.save(sysConfigChangeRecord);
 				this.save(sysConfigChangeRecord);
 				return true;
 				return true;
 			}
 			}
 		}
 		}
 		return false;
 		return false;
 	}
 	}
+
+
+	public YhServiceChangeDto getChangeService(YhServiceDto beforeServiceDto, YhServiceDto afterServiceDto) {
+		Integer index = beforeServiceDto.getIndex();
+		String sign = beforeServiceDto.getSign();
+		String date = beforeServiceDto.getDate();
+		String workType = beforeServiceDto.getWorkType();
+
+		Map<Integer, List<YhServiceDto.CustomerServiceDto>> afterIndxMap = afterServiceDto.getSelect().stream().collect(Collectors.groupingBy(YhServiceDto.CustomerServiceDto::getIndex));
+
+		Map<Integer, List<YhServiceDto.CustomerServiceDto>> beforeIndxMap = beforeServiceDto.getSelect().stream().collect(Collectors.groupingBy(YhServiceDto.CustomerServiceDto::getIndex));
+
+		List<String> beforeSelect = new ArrayList<>();
+		List<String> afterSelect = new ArrayList<>();
+
+		beforeServiceDto.getSelect().forEach(bfSelect -> {
+			if (afterIndxMap.get(bfSelect.getIndex()) == null) {
+				beforeSelect.add(bfSelect.getName());
+			}
+		});
+
+		afterServiceDto.getSelect().forEach(afSelect -> {
+			if (beforeIndxMap.get(afSelect.getIndex()) == null) {
+				afterSelect.add(afSelect.getName());
+			}
+		});
+
+		if (CollUtil.isNotEmpty(beforeSelect) || CollUtil.isNotEmpty(afterSelect)) {
+			YhServiceChangeDto yhServiceChangeDto = new YhServiceChangeDto();
+			yhServiceChangeDto.setSign(sign);
+			yhServiceChangeDto.setIndex(index);
+			yhServiceChangeDto.setDate(date);
+			yhServiceChangeDto.setWorkType(workType);
+			yhServiceChangeDto.setBeforeSelect(beforeSelect);
+			yhServiceChangeDto.setAfterSelect(afterSelect);
+			return yhServiceChangeDto;
+		}
+		return null;
+	}
 }
 }

+ 45 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsOrderController.java

@@ -16,6 +16,7 @@ import com.cyksj.common.util.IoKit;
 import com.cyksj.common.util.Xmls;
 import com.cyksj.common.util.Xmls;
 import com.cyksj.dto.Result;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.BusinessType;
 import com.cyksj.enums.BusinessType;
+import com.cyksj.enums.GatewayApiCode;
 import com.cyksj.enums.GatewayResponse;
 import com.cyksj.enums.GatewayResponse;
 import com.cyksj.mapper.GoodsDonSkuMapper;
 import com.cyksj.mapper.GoodsDonSkuMapper;
 import com.cyksj.mapper.GroupsRelationMapper;
 import com.cyksj.mapper.GroupsRelationMapper;
@@ -25,6 +26,7 @@ import com.cyksj.mapper.channel.ChannelPopularizeMapper;
 import com.cyksj.mapper.channel.UserPayEquipmentAvailableBenefitsMapper;
 import com.cyksj.mapper.channel.UserPayEquipmentAvailableBenefitsMapper;
 import com.cyksj.mapper.channel.UserPayEquipmentReceiveBenefitsRecordMapper;
 import com.cyksj.mapper.channel.UserPayEquipmentReceiveBenefitsRecordMapper;
 import com.cyksj.mapper.manage.RealGoodsOrderHandleMapper;
 import com.cyksj.mapper.manage.RealGoodsOrderHandleMapper;
+import com.cyksj.mapper.manage.cms.CmsUserMapper;
 import com.cyksj.mapper.manage.coupon.CouponMapper;
 import com.cyksj.mapper.manage.coupon.CouponMapper;
 import com.cyksj.mapper.shop.YhShopMapper;
 import com.cyksj.mapper.shop.YhShopMapper;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.entity.*;
@@ -60,6 +62,7 @@ import java.io.OutputStream;
 import java.math.BigDecimal;
 import java.math.BigDecimal;
 import java.util.*;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 
 
 /**
 /**
  * @author chan
  * @author chan
@@ -100,6 +103,8 @@ public class CmsOrderController {
 
 
 	private final YhShopMapper yhShopMapper;
 	private final YhShopMapper yhShopMapper;
 
 
+	private final CmsUserMapper cmsUserMapper;
+
 
 
 	@GetMapping("/get")
 	@GetMapping("/get")
 	@SaCheckPermission("order:view")
 	@SaCheckPermission("order:view")
@@ -582,6 +587,12 @@ public class CmsOrderController {
 	@PostMapping("/unified/refund")
 	@PostMapping("/unified/refund")
 	@Log(module = "订单管理/统一退款", businessType = BusinessType.PUT, isSaveRequestData = true)
 	@Log(module = "订单管理/统一退款", businessType = BusinessType.PUT, isSaveRequestData = true)
 	public Result<String> unifiedRefund(@RequestBody @Validated OrderRefundReq refundReq) throws Exception {
 	public Result<String> unifiedRefund(@RequestBody @Validated OrderRefundReq refundReq) throws Exception {
+		long adminId = StpUtil.getLoginIdAsLong();
+		CmsUser cmsUser = cmsUserMapper.selectById(adminId);
+		if (cmsUser == null) {
+			throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
+		}
+		refundReq.setOperator(cmsUser.getNickname());
 		cmsOrderDonService.unifiedRefund(refundReq);
 		cmsOrderDonService.unifiedRefund(refundReq);
 		return GatewayResponse.SUCCESS.newBuilder().toResult("退款成功");
 		return GatewayResponse.SUCCESS.newBuilder().toResult("退款成功");
 	}
 	}
@@ -681,6 +692,12 @@ public class CmsOrderController {
 	@PutMapping("/refund/price/differ")
 	@PutMapping("/refund/price/differ")
 	@Log(module = "订单管理/订单补差价", businessType = BusinessType.PUT, isSaveRequestData = true)
 	@Log(module = "订单管理/订单补差价", businessType = BusinessType.PUT, isSaveRequestData = true)
 	public Result<String> refundPriceDiffer(@RequestBody OrderRefundReq orderRefundReq) throws Exception {
 	public Result<String> refundPriceDiffer(@RequestBody OrderRefundReq orderRefundReq) throws Exception {
+		long adminId = StpUtil.getLoginIdAsLong();
+		CmsUser cmsUser = cmsUserMapper.selectById(adminId);
+		if (cmsUser == null) {
+			throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
+		}
+		orderRefundReq.setOperator(cmsUser.getNickname());
 		cmsOrderDonService.refundPriceDiffer(orderRefundReq);
 		cmsOrderDonService.refundPriceDiffer(orderRefundReq);
 		return GatewayResponse.SUCCESS.newBuilder().toResult();
 		return GatewayResponse.SUCCESS.newBuilder().toResult();
 	}
 	}
@@ -695,4 +712,32 @@ public class CmsOrderController {
 		return GatewayResponse.SUCCESS.newBuilder().toResult();
 		return GatewayResponse.SUCCESS.newBuilder().toResult();
 	}
 	}
 
 
+
+	/**
+	 * 客服退款每月数据
+	 */
+	@GetMapping("/get/refundOrder/data")
+	public Result<SearchResult<RefundOrderDonServiceDataView>> getRefundOrderData(String startTime, String endTime, String operator) {
+		String time = StrUtil.EMPTY;
+		if (StrUtil.isNotBlank(startTime)) {
+			time += String.format(" and rd.created_time >= '%s'", startTime);
+		}
+		if (StrUtil.isNotBlank(endTime)) {
+			time += String.format(" and rd.created_time < '%s'", endTime);
+		}
+		MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
+		if (StrUtil.isNotBlank(time)) {
+			builder.put("time", time);
+		}
+		if (StrUtil.isEmpty(operator)) {
+			List<CmsUserVO> userVOS = beanSearcher.searchAll(CmsUserVO.class, MapUtils.builder().field(CmsUserVO::getRoleNames, "客服").op(Operator.Contain).build());
+			List<String> collect = userVOS.stream().map(CmsUserVO::getNickname).collect(Collectors.toList());
+			if (CollUtil.isNotEmpty(collect)) {
+				builder.field(RefundOrderDonServiceDataView::getOperator, collect).op(Operator.InList);
+			}
+		}
+		SearchResult<RefundOrderDonServiceDataView> search = beanSearcher.search(RefundOrderDonServiceDataView.class, builder.build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
 }
 }

+ 33 - 5
netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsUserController.java

@@ -1,6 +1,7 @@
 package com.cyksj.web.controller.manage;
 package com.cyksj.web.controller.manage;
 
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alipay.api.AlipayApiException;
 import com.alipay.api.AlipayApiException;
@@ -12,11 +13,9 @@ import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.dto.Result;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.BusinessType;
 import com.cyksj.enums.BusinessType;
 import com.cyksj.enums.GatewayResponse;
 import com.cyksj.enums.GatewayResponse;
-import com.cyksj.mapper.GroupsRelationMapper;
-import com.cyksj.mapper.OrderDonMapper;
-import com.cyksj.mapper.UserFuncPropertyMapper;
-import com.cyksj.mapper.UserMapper;
+import com.cyksj.mapper.*;
 import com.cyksj.mapper.corp.CorpUserFollowRelationMapper;
 import com.cyksj.mapper.corp.CorpUserFollowRelationMapper;
+import com.cyksj.mapper.manage.cms.CmsUserMapper;
 import com.cyksj.mapper.market.task.UserBindDetailMapper;
 import com.cyksj.mapper.market.task.UserBindDetailMapper;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.views.UserView;
 import com.cyksj.model.manage.views.UserView;
@@ -79,6 +78,10 @@ public class CmsUserController{
 
 
     private final UserPayOrderBlockService userPayOrderBlockService;
     private final UserPayOrderBlockService userPayOrderBlockService;
 
 
+    private final CmsUserMapper cmsUserMapper;
+
+    private final UserDoubleVerifyCodeChangeRecordMapper userDoubleVerifyCodeChangeRecordMapper;
+
     @GetMapping("/get")
     @GetMapping("/get")
     public Result<SearchResult<UserView>> get(Long id, String otherPhone, Long sharedId, String userid, Long businessId, String sort, String order) {
     public Result<SearchResult<UserView>> get(Long id, String otherPhone, Long sharedId, String userid, Long businessId, String sort, String order) {
         MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
         MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
@@ -168,16 +171,28 @@ public class CmsUserController{
         }
         }
         UserFuncProperty userFuncProperty = userFuncPropertyMapper.selectOne(Wrappers.lambdaQuery(UserFuncProperty.class)
         UserFuncProperty userFuncProperty = userFuncPropertyMapper.selectOne(Wrappers.lambdaQuery(UserFuncProperty.class)
                 .eq(UserFuncProperty::getUserId, req.getUserId()).last("limit 1"));
                 .eq(UserFuncProperty::getUserId, req.getUserId()).last("limit 1"));
+        Boolean isFirst = false;
         if (userFuncProperty == null) {
         if (userFuncProperty == null) {
             try {
             try {
                 userFuncProperty = new UserFuncProperty();
                 userFuncProperty = new UserFuncProperty();
                 userFuncProperty.setUserId(req.getUserId());
                 userFuncProperty.setUserId(req.getUserId());
                 userFuncProperty.setVerifyCheckNum(req.getVerifyCheckNum());
                 userFuncProperty.setVerifyCheckNum(req.getVerifyCheckNum());
                 userFuncPropertyMapper.insert(userFuncProperty);
                 userFuncPropertyMapper.insert(userFuncProperty);
+                isFirst = true;
             } catch (DuplicateKeyException e) {
             } catch (DuplicateKeyException e) {
 
 
             }
             }
         }
         }
+        if (isFirst || (userFuncProperty.getVerifyCheckNum() != req.getVerifyCheckNum())) {
+            long adminId = StpUtil.getLoginIdAsLong();
+            UserDoubleVerifyCodeChangeRecord userDoubleVerifyCodeChangeRecord = new UserDoubleVerifyCodeChangeRecord();
+            userDoubleVerifyCodeChangeRecord.setUserId(req.getUserId());
+            Optional.ofNullable(cmsUserMapper.selectById(adminId))
+                    .ifPresent(cu -> userDoubleVerifyCodeChangeRecord.setOperator(cu.getNickname()));
+            userDoubleVerifyCodeChangeRecord.setOldVerifyCheckNum(isFirst ? 1 : userFuncProperty.getVerifyCheckNum());
+            userDoubleVerifyCodeChangeRecord.setVerifyCheckNum(req.getVerifyCheckNum());
+            userDoubleVerifyCodeChangeRecordMapper.insert(userDoubleVerifyCodeChangeRecord);
+        }
         userFuncProperty.setVerifyCheckNum(req.getVerifyCheckNum());
         userFuncProperty.setVerifyCheckNum(req.getVerifyCheckNum());
         userFuncPropertyMapper.updateById(userFuncProperty);
         userFuncPropertyMapper.updateById(userFuncProperty);
         return GatewayResponse.SUCCESS.newBuilder().toResult();
         return GatewayResponse.SUCCESS.newBuilder().toResult();
@@ -191,12 +206,25 @@ public class CmsUserController{
         if (userId==null) throw BusinessRuntimeException.getInstance("用户id为空");
         if (userId==null) throw BusinessRuntimeException.getInstance("用户id为空");
         UserFuncProperty userFuncProperty = userFuncPropertyMapper.selectOne(Wrappers.lambdaQuery(UserFuncProperty.class)
         UserFuncProperty userFuncProperty = userFuncPropertyMapper.selectOne(Wrappers.lambdaQuery(UserFuncProperty.class)
                 .eq(UserFuncProperty::getUserId, userId).last("limit 1"));
                 .eq(UserFuncProperty::getUserId, userId).last("limit 1"));
-        //默认
+        //默认1
         Integer verifyCheckNum = 1;
         Integer verifyCheckNum = 1;
         if (userFuncProperty != null) verifyCheckNum = userFuncProperty.getVerifyCheckNum();
         if (userFuncProperty != null) verifyCheckNum = userFuncProperty.getVerifyCheckNum();
         return GatewayResponse.SUCCESS.newBuilder().toResult(verifyCheckNum);
         return GatewayResponse.SUCCESS.newBuilder().toResult(verifyCheckNum);
     }
     }
 
 
+    /**
+     * 用户验证码更变记录列表展示
+     */
+    @GetMapping("/get/verifyCode/change/list/{userId}")
+    public Result<SearchResult<UserDoubleVerifyCodeChangeRecord>> getUserDoubleVerifyCodeChangeRecordByUserId(@PathVariable Long userId) {
+        SearchResult<UserDoubleVerifyCodeChangeRecord> search = beanSearcher.search(UserDoubleVerifyCodeChangeRecord.class, MapUtils.flatBuilder(request.getParameterMap())
+                .field(UserDoubleVerifyCodeChangeRecord::getUserId, userId)
+                .orderBy(UserDoubleVerifyCodeChangeRecord::getId).desc()
+                .build());
+        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+    }
+
+
     /**
     /**
      * 用户加入企业微信客服详情
      * 用户加入企业微信客服详情
      */
      */

+ 22 - 3
netflix-web/src/main/java/com/cyksj/web/controller/sys/SysConfigController.java

@@ -18,21 +18,26 @@ import com.cyksj.model.dto.EquipmentConfigDto;
 import com.cyksj.model.entity.HelpQuestion;
 import com.cyksj.model.entity.HelpQuestion;
 import com.cyksj.model.entity.HelpQuestionClassification;
 import com.cyksj.model.entity.HelpQuestionClassification;
 import com.cyksj.model.entity.SysConfig;
 import com.cyksj.model.entity.SysConfig;
+import com.cyksj.model.entity.SysConfigChangeRecord;
 import com.cyksj.model.views.HelpQuestionClassificationView;
 import com.cyksj.model.views.HelpQuestionClassificationView;
-import com.cyksj.service.corp.CorpFollowService;
 import com.cyksj.service.sys.SysConfigChangeRecordService;
 import com.cyksj.service.sys.SysConfigChangeRecordService;
 import com.cyksj.service.sys.SysConfigService;
 import com.cyksj.service.sys.SysConfigService;
 import com.cyksj.xxljob.XxlJobInfo;
 import com.cyksj.xxljob.XxlJobInfo;
 import com.cyksj.xxljob.XxlJobUtil;
 import com.cyksj.xxljob.XxlJobUtil;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.param.Operator;
+import com.ejlchina.searcher.util.MapUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.*;
 
 
+import javax.servlet.http.HttpServletRequest;
 import java.math.BigDecimal;
 import java.math.BigDecimal;
 import java.util.HashSet;
 import java.util.HashSet;
 
 
-/**
+/** admin/客服运营
  * @author chan
  * @author chan
  * @date 2022/10/20 10:08 AM
  * @date 2022/10/20 10:08 AM
  */
  */
@@ -48,7 +53,9 @@ public class SysConfigController {
 
 
 	private final HelpQuestionClassificationMapper helpQuestionClassificationMapper;
 	private final HelpQuestionClassificationMapper helpQuestionClassificationMapper;
 
 
-	private final CorpFollowService corpFollowService;
+	private final BeanSearcher beanSearcher;
+
+	private final HttpServletRequest request;
 
 
 	private final SysConfigChangeRecordService sysConfigChangeRecordService;
 	private final SysConfigChangeRecordService sysConfigChangeRecordService;
 
 
@@ -157,4 +164,16 @@ public class SysConfigController {
 		return GatewayResponse.SUCCESS.newBuilder().toResult(helpQuestionClassification != null ? true : false);
 		return GatewayResponse.SUCCESS.newBuilder().toResult(helpQuestionClassification != null ? true : false);
 	}
 	}
 
 
+	/**
+	 * 值班客服操作日志
+	 */
+	@GetMapping("/duty/operate/log")
+	public Result<SearchResult<SysConfigChangeRecord>> sysConfigChangeRecordResult() {
+		SearchResult<SysConfigChangeRecord> search = beanSearcher.search(SysConfigChangeRecord.class, MapUtils.flatBuilder(request.getParameterMap())
+				.field(SysConfigChangeRecord::getChangeStr).op(Operator.NotNull)
+				.orderBy(SysConfigChangeRecord::getId).desc()
+				.onlySelect(SysConfigChangeRecord::getId, SysConfigChangeRecord::getOperator, SysConfigChangeRecord::getChangeStr, SysConfigChangeRecord::getCreatedTime)
+				.build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
 }
 }