修复渠道缺陷

This commit is contained in:
DB 2024-02-28 09:35:56 +08:00
parent 7cf5e83e4c
commit 124c3acfaa
14 changed files with 336 additions and 66 deletions

View File

@ -0,0 +1,27 @@
package com.cpop.api.cloudDb.core.dto;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author DB
* @version 1.0.0
* @since 2024-02-26 13:41
*/
@Data
@Accessors(chain = true)
public class CloudBrandDto {
/**
* 品牌名
*/
@SerializedName("name")
private String brandName;
/**
* 品牌云id
*/
@SerializedName("brandId")
private String brandCloudId;
}

View File

@ -0,0 +1,41 @@
package com.cpop.api.cloudDb.handler;
import com.alibaba.fastjson.JSONObject;
import com.cpop.api.cloudDb.core.constant.CloudDbUrl;
import com.cpop.api.cloudDb.core.dto.CloudBrandDto;
import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.exception.UtilException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
/**
* @author DB
* @version 1.0.0
* @since 2024-02-26 13:37
*/
@Component
public class CloudBrandHandler {
@Autowired
private RestTemplate restTemplate;
/**
* 更新品牌
* @author DB
* @since 2024/2/26
* @param dto 云品牌对象
*/
public void updateBrand(CloudBrandDto dto) {
JSONObject jsonBody = new JSONObject();
jsonBody.put("_type", "brandEdit");
jsonBody.put("brandId", dto.getBrandCloudId());
jsonBody.put("name", dto.getBrandName());
JSONObject jsonObject = restTemplate.postForObject(CloudDbUrl.COMMON_USE_URL, jsonBody, JSONObject.class);
if (jsonObject != null) {
if (!jsonObject.getBoolean("success")) {
throw new UtilException(jsonObject.getString("error"));
}
}
}
}

View File

@ -9,6 +9,9 @@ import com.cpop.api.cloudDb.handler.CloudCustomerStudentHandler;
import com.cpop.api.cloudDb.handler.CloudOrderHandler;
import com.cpop.core.utils.SpringUtils;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.Row;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@ -53,4 +56,11 @@ public class CpopCloudDbTests {
null, "f4a7f4c892934490a7550ed1e2f0opiu", null, null, null);
System.out.println(JSONObject.toJSONString(orderPage));
}
@Test
public void getBrandCloudInfo(){
//获取云品牌拓展
Row row = Db.selectOneByQuery("cp_j_brand_extend", QueryWrapper.create().where("brand_id = ?", "97562782126755845"));
System.out.println(row);
}
}

View File

@ -1,12 +1,18 @@
package com.cpop.oam.business.controller.backstage;
import com.cpop.core.base.R;
import com.cpop.core.utils.SpringUtils;
import com.cpop.oam.business.bo.ClueFollowUpBo;
import com.cpop.oam.business.bo.CluePutOffBo;
import com.cpop.oam.business.bo.ClueUpdateBo;
import com.cpop.oam.business.bo.DeptBo;
import com.cpop.oam.business.service.ClueRecordService;
import com.cpop.oam.business.service.SignAreaService;
import com.cpop.oam.business.service.StaffService;
import com.cpop.oam.business.vo.*;
import com.cpop.system.business.entity.DictData;
import com.cpop.system.business.entity.DictType;
import com.cpop.system.business.service.DictDataService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import org.springframework.validation.annotation.Validated;
@ -18,10 +24,16 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import java.io.Serializable;
import java.util.List;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
import static com.cpop.core.base.table.table.SysUserTableDef.SYS_USER;
import static com.cpop.oam.business.entity.table.ClueRecordTableDef.CLUE_RECORD;
import static com.cpop.oam.business.entity.table.SignAreaTableDef.SIGN_AREA;
import static com.cpop.oam.business.entity.table.SignGoalTableDef.SIGN_GOAL;
import static com.cpop.oam.business.entity.table.StaffTableDef.STAFF;
import static com.mybatisflex.core.query.QueryMethods.distinct;
/**
* 线索表 控制层
@ -258,4 +270,46 @@ public class BackstageClueController {
Page<CluePageVo> pageVo = clueService.getMyDevCluePage( city, brandId, storeId, chargeOrPhone);
return R.ok(pageVo);
}
/**
* 描述
* @author DB
* @since 2024/2/27
* @return R<Page<CluePageVo>>
*/
@ApiOperation("获取区域列表")
@GetMapping("/getAreaList")
public R<List<Map<String,String>>> getAreaList() {
List<DictData> dictDataByDictType = SpringUtils.getBean(DictDataService.class).getDictDataByDictType("oam_clue_area")
.stream().sorted(Comparator.comparing(DictData::getDictSort)).collect(Collectors.toList());
List<Map<String,String>> result = new ArrayList<>();
if (!dictDataByDictType.isEmpty()){
dictDataByDictType.forEach(item -> {
Arrays.stream(item.getDictValue().split("/")).forEach(inner->{
Map<String, String> map = new HashMap<>();
map.put("label", inner);
map.put("value", inner);
result.add(map);
});
});
}
return R.ok(result);
}
/**
* 获取市场部员工
* @author DB
* @since 2023/12/13
* @return R<List<StaffVo>>
*/
@GetMapping("/getMarketStaff")
@ApiOperation("获取市场部员工")
public R<List<StaffVo>> getBusinessStaff() {
List<StaffVo> list = SpringUtils.getBean(StaffService.class).queryChain()
.leftJoin(SYS_USER).on(SYS_USER.ID.eq(STAFF.USER_ID))
.where(STAFF.STAFF_TYPE.in(1, 2))
.and(SYS_USER.STATUS.eq(1))
.listAs(StaffVo.class);
return R.ok(list);
}
}

View File

@ -442,40 +442,40 @@ public class BusinessServiceImpl extends ServiceImpl<BusinessMapper, Business> i
private void changeMonthGoal(SignGoal signGoal, Month month) {
switch (month) {
case JANUARY:
signGoal.setJanGoal(signGoal.getJanGoal() + 1);
signGoal.setJanFinish(signGoal.getJanFinish() + 1);
break;
case FEBRUARY:
signGoal.setFebGoal(signGoal.getFebGoal() + 1);
signGoal.setFebFinish(signGoal.getFebFinish() + 1);
break;
case MARCH:
signGoal.setMarGoal(signGoal.getMarGoal() + 1);
signGoal.setMarFinish(signGoal.getMarFinish() + 1);
break;
case APRIL:
signGoal.setAprGoal(signGoal.getAprGoal() + 1);
signGoal.setAprFinish(signGoal.getAprFinish() + 1);
break;
case MAY:
signGoal.setMayGoal(signGoal.getMayGoal() + 1);
signGoal.setMayFinish(signGoal.getMayFinish() + 1);
break;
case JUNE:
signGoal.setJunGoal(signGoal.getJunGoal() + 1);
signGoal.setJunFinish(signGoal.getJunFinish() + 1);
break;
case JULY:
signGoal.setJulGoal(signGoal.getJulGoal() + 1);
signGoal.setJulFinish(signGoal.getJulFinish() + 1);
break;
case AUGUST:
signGoal.setAugGoal(signGoal.getAugGoal() + 1);
signGoal.setAugFinish(signGoal.getAugFinish() + 1);
break;
case SEPTEMBER:
signGoal.setSepGoal(signGoal.getSepGoal() + 1);
signGoal.setSepFinish(signGoal.getSepFinish() + 1);
break;
case OCTOBER:
signGoal.setOctGoal(signGoal.getOctGoal() + 1);
signGoal.setOctFinish(signGoal.getOctFinish() + 1);
break;
case NOVEMBER:
signGoal.setNovGoal(signGoal.getNovGoal() + 1);
signGoal.setNovFinish(signGoal.getNovFinish() + 1);
break;
case DECEMBER:
signGoal.setDecGoal(signGoal.getDecGoal() + 1);
signGoal.setDecFinish(signGoal.getDecFinish() + 1);
break;
}
}

View File

@ -86,14 +86,15 @@ public class CluePutOffServiceImpl extends ServiceImpl<CluePutOffMapper, CluePut
@Override
@Transactional(rollbackFor = Exception.class)
public void putOffAuditSelect(PutOffAuditBo bo) {
JSONObject loginUserInfo = SecurityUtils.getInstance().getLoginUserInfo();
CluePutOff cluePutOff = this.getById(bo.getId());
this.updateChain()
.set(CLUE_PUT_OFF.AUDIT_STATUS, bo.getAuditResult() ? 1 : 2)
.set(CLUE_PUT_OFF.AUDIT_STAFF_ID,loginUserInfo.getString("id"))
.where(CLUE_PUT_OFF.ID.eq(bo.getId()))
.update();
//添加记录
ClueRecord clueRecord = new ClueRecord();
JSONObject loginUserInfo = SecurityUtils.getInstance().getLoginUserInfo();
clueRecord.setRecordStaffId(loginUserInfo.getString("id"))
.setRecordType(7)
.setRecordContent(bo.getAuditResult() ? "延期通过" : "延期拒绝")

View File

@ -5,6 +5,7 @@ import com.cpop.common.utils.StringUtils;
import com.cpop.common.utils.bean.BeanUtils;
import com.cpop.core.base.entity.PageDomain;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.service.RedisService;
import com.cpop.core.utils.SecurityUtils;
import com.cpop.core.utils.SpringUtils;
import com.cpop.core.utils.sql.SqlUtils;
@ -15,7 +16,10 @@ import com.cpop.oam.business.entity.*;
import com.cpop.oam.business.mapper.CluePutOffMapper;
import com.cpop.oam.business.service.*;
import com.cpop.oam.business.vo.*;
import com.cpop.oam.framework.constant.OamRedisConstant;
import com.cpop.system.business.entity.DictData;
import com.cpop.system.business.entity.Store;
import com.cpop.system.business.service.DictDataService;
import com.cpop.system.business.service.StoreService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryOrderBy;
@ -29,7 +33,9 @@ import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.stream.Collectors;
import static com.cpop.oam.business.entity.table.CluePutOffTableDef.CLUE_PUT_OFF;
import static com.cpop.oam.business.entity.table.ClueRecordTableDef.CLUE_RECORD;
@ -76,12 +82,28 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
JSONObject loginUserInfo = SecurityUtils.getInstance().getLoginUserInfo();
queryWrapper.and(CLUE.RESPONSIBLE_STAFF_ID.eq(loginUserInfo.getString("id")));
}
if (StringUtils.isNotBlank(city) && StringUtils.equals("其他", city)) {
int year = LocalDate.now().getYear();
List<String> cityList = SpringUtils.getBean(SignAreaService.class).queryChain()
.select(distinct(SIGN_AREA.CITY))
.leftJoin(SIGN_GOAL).on(SIGN_GOAL.ID.eq(SIGN_AREA.SIGN_GOAL_ID))
.and(SIGN_GOAL.YEAR.eq(year))
.listAs(String.class);
if (cityList == null || cityList.isEmpty()) {
throw new ServiceException("当前年没有设置签约指标,请先设置后再进行操作");
}
//地区
queryWrapper.and(CLUE.CITY.notIn(cityList));
} else if (StringUtils.isNotBlank(city)) {
//地区
queryWrapper.and(CLUE.CITY.eq(city));
}
return this.mapper.paginateAs(Page.of(pageDomain.getPageNum(),pageDomain.getPageSize()),
queryWrapper
.select(CLUE.CITY,CLUE.ID,CLUE.CREATE_TIME,CLUE.DEV_STAFF_ID,CLUE.LAST_FOLLOW_UP_TIME,CLUE.LAST_FOLLOW_UP_CONTENT,CLUE.RECEIPT_TIME,CLUE.STORE_ID)
.select(CLUE.CITY,CLUE.ID,CLUE.CREATE_TIME,CLUE.DEV_STAFF_ID,CLUE.LAST_FOLLOW_UP_TIME,CLUE.LAST_FOLLOW_UP_CONTENT,CLUE.RECEIPT_TIME,CLUE.STORE_ID,CLUE.CLUE_STATUS)
.select(STORE.STORE_NAME,STORE.STORE_ADDR,STORE.PERSON_CHARGE,STORE.PHONE)
.select(BRAND.BRAND_NAME)
.select(STORE_SIGN.EXPIRE_DATE)
.select(STORE_SIGN.EXPIRE_DATE,STORE_SIGN.CREATE_TIME.as(CluePageVo::getStoreSignTime))
// 跟进间隔
.select(dateDiff(now(), CLUE.LAST_FOLLOW_UP_TIME).as(CluePageVo::getFollowUpInterval))
// 签约时间
@ -90,8 +112,6 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
.leftJoin(STORE).on(STORE.ID.eq(CLUE.STORE_ID))
.leftJoin(BRAND).on(BRAND.ID.eq(STORE.BRAND_ID))
.leftJoin(STORE_SIGN).on(STORE_SIGN.STORE_ID.eq(STORE.ID))
//地区
.and(CLUE.CITY.eq(city))
//品牌
.and(BRAND.ID.eq(brandId))
//校区
@ -130,15 +150,15 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
}
case "followUpInterval":
if (pageDomain.getBoolAsc()) {
return column(CluePageVo::getFollowUpInterval).asc();
return column("follow_up_interval").asc();
} else {
return column(CluePageVo::getFollowUpInterval).desc();
return column("follow_up_interval").desc();
}
case "signInterval":
if (pageDomain.getBoolAsc()) {
return column(CluePageVo::getSignInterval).asc();
return column("sign_interval").asc();
} else {
return column(CluePageVo::getSignInterval).desc();
return column("sign_interval").desc();
}
default:
return CLUE.CREATE_TIME.desc();
@ -160,6 +180,7 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
} else {
JSONObject loginUserInfo = SecurityUtils.getInstance().getLoginUserInfo();
queryWrapper.and(SIGN_GOAL.STAFF_ID.eq(loginUserInfo.getString("id")));
staffId = loginUserInfo.getString("id");
}
SignGoalService signGoalService = SpringUtils.getBean(SignGoalService.class);
if (StringUtils.isBlank(signMonth)) {
@ -168,6 +189,10 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
String[] split = signMonth.split("-");
SignGoal signGoal = signGoalService.getOne(queryWrapper.where(SIGN_GOAL.YEAR.eq(Integer.parseInt(split[0]))));
PersonSignGoalVo vo = new PersonSignGoalVo();
Long signNum = this.count(QueryWrapper.create().where(CLUE.RESPONSIBLE_STAFF_ID.eq(staffId)).and(CLUE.CLUE_STATUS.eq(1)));
vo.setSignNum(signNum.intValue());
Long totalNum = this.count(QueryWrapper.create().where(CLUE.RESPONSIBLE_STAFF_ID.eq(staffId)));
vo.setTotalNum(totalNum.intValue());
if (signGoal == null){
return vo;
}
@ -221,10 +246,6 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
vo.setFinishNum(signGoal.getDecFinish());
break;
}
Long signNum = this.count(QueryWrapper.create().where(CLUE.RESPONSIBLE_STAFF_ID.eq(staffId)).and(CLUE.CLUE_STATUS.eq(1)));
vo.setSignNum(signNum.intValue());
Long totalNum = this.count(QueryWrapper.create().where(CLUE.RESPONSIBLE_STAFF_ID.eq(staffId)));
vo.setTotalNum(totalNum.intValue());
return vo;
}
@ -240,6 +261,11 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
JSONObject loginUserInfo = SecurityUtils.getInstance().getLoginUserInfo();
clueRecord.setRecordStaffId(loginUserInfo.getString("id"));
SpringUtils.getBean(ClueRecordService.class).save(clueRecord);
SpringUtils.getBean(ClueService.class).updateChain()
.set(CLUE.LAST_FOLLOW_UP_TIME, LocalDateTime.now())
.set(CLUE.LAST_FOLLOW_UP_CONTENT,bo.getRecordContent())
.where(CLUE.ID.eq(bo.getClueId()))
.update();
}
/**
@ -315,11 +341,19 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
@Override
@Transactional(rollbackFor = Exception.class)
public void cluePutOff(CluePutOffBo bo) {
//查询延期记录
JSONObject loginUserInfo = SecurityUtils.getInstance().getLoginUserInfo();
CluePutOffService cluePutOffService = SpringUtils.getBean(CluePutOffService.class);
long count = cluePutOffService.count(QueryWrapper.create()
.where(CLUE_PUT_OFF.AUDIT_STATUS.eq(0))
.and(CLUE_PUT_OFF.CLUE_ID.eq(bo.getClueId())));
if (count > 0) {
throw new ServiceException("该线索在审核中,请勿重复提交");
}
CluePutOff cluePutOff = BeanUtils.mapToClass(bo, CluePutOff.class);
cluePutOff.setAuditStatus(0)
.setPutOffStaffId(loginUserInfo.getString("id"));
SpringUtils.getBean(CluePutOffService.class).save(cluePutOff);
cluePutOffService.save(cluePutOff);
ClueRecord clueRecord = new ClueRecord();
clueRecord.setClueId(bo.getClueId())
.setRecordStaffId(loginUserInfo.getString("id"))
@ -340,6 +374,7 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
return SpringUtils.getBean(CluePutOffService.class).getMapper().selectListByQueryAs(QueryWrapper.create()
.select(CLUE_PUT_OFF.PUT_OFF_DATE, CLUE_PUT_OFF.PUT_OFF_REASON, CLUE_PUT_OFF.CREATE_TIME, CLUE_PUT_OFF.PUT_OFF_STAFF_ID, CLUE_PUT_OFF.AUDIT_STAFF_ID, CLUE_PUT_OFF.AUDIT_STATUS,
CLUE_PUT_OFF.CREATE_TIME,CLUE_PUT_OFF.PUT_OFF_FILE_URL)
.where(CLUE_PUT_OFF.CLUE_ID.eq(clueId))
.orderBy(CLUE_PUT_OFF.CREATE_TIME.desc()),
CluePutOffVo.class,
//延迟员工
@ -359,7 +394,7 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
if (StringUtils.isNotBlank(auditStaff.getAuditStaffId())) {
return queryChain().select(STAFF.NAME.as(CluePutOffVo::getAuditStaffName))
.from(STAFF)
.where(STAFF.ID.eq(auditStaff.getPutOffStaffId()));
.where(STAFF.ID.eq(auditStaff.getAuditStaffId()));
} else {
return null;
}
@ -381,6 +416,7 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
}
this.updateChain().set(CLUE.CLUE_STATUS, 0)
.set(CLUE.RESPONSIBLE_STAFF_ID, null)
.set(CLUE.RECEIPT_TIME,null)
.where(CLUE.ID.eq(clue.getId()))
.update();
JSONObject loginUserInfo = SecurityUtils.getInstance().getLoginUserInfo();
@ -425,8 +461,6 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
.select(BRAND.BRAND_NAME)
// 跟进间隔
.select(dateDiff(now(), CLUE.LAST_FOLLOW_UP_TIME).as(CluePageVo::getFollowUpInterval))
// 签约时间
.select(dateDiff(now(), CLUE.RECEIPT_TIME).as(CluePageVo::getSignInterval))
.from(CLUE)
.leftJoin(STORE).on(STORE.ID.eq(CLUE.STORE_ID))
.leftJoin(BRAND).on(BRAND.ID.eq(STORE.BRAND_ID))
@ -462,7 +496,15 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
} else {
return null;
}
}));
}),
//脱离间隔
item -> item.field(CluePageVo::getPutOffInterval)
.queryWrapper(putOffInterval -> queryChain().select(dateDiff(now(), CLUE_RECORD.CREATE_TIME).as(CluePageVo::getPutOffInterval))
.from(CLUE_RECORD)
.where(CLUE_RECORD.RECORD_TYPE.eq(4))
.and(CLUE_RECORD.CLUE_ID.eq(putOffInterval.getId()))
.orderBy(CLUE_RECORD.CREATE_TIME.desc())
.limit(1)));
}
/**
@ -485,9 +527,12 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
.leftJoin(SIGN_GOAL).on(SIGN_GOAL.ID.eq(SIGN_AREA.SIGN_GOAL_ID))
.and(SIGN_GOAL.YEAR.eq(year))
.listAs(String.class);
if (cityList == null || cityList.isEmpty()){
if (cityList == null || cityList.isEmpty()) {
throw new ServiceException("当前年没有设置签约指标,请先设置后再进行操作");
}
if (!StringUtils.equals("其他", city)) {
queryWrapper.and(CLUE.CITY.eq(city));
}
return this.mapper.paginateAs(Page.of(pageDomain.getPageNum(),pageDomain.getPageSize()),
queryWrapper
.select(CLUE.CITY,CLUE.ID,CLUE.CREATE_TIME,CLUE.DEV_STAFF_ID,CLUE.LAST_FOLLOW_UP_TIME,CLUE.LAST_FOLLOW_UP_CONTENT,CLUE.RECEIPT_TIME,CLUE.STORE_ID,CLUE.LAST_RECEIPT_TIME,CLUE.LAST_RECEIPT_STAFF_ID)
@ -495,14 +540,11 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
.select(BRAND.BRAND_NAME)
// 跟进间隔
.select(dateDiff(now(), CLUE.LAST_FOLLOW_UP_TIME).as(CluePageVo::getFollowUpInterval))
// 签约时间
.select(dateDiff(now(), CLUE.RECEIPT_TIME).as(CluePageVo::getSignInterval))
.from(CLUE)
.leftJoin(STORE).on(STORE.ID.eq(CLUE.STORE_ID))
.leftJoin(BRAND).on(BRAND.ID.eq(STORE.BRAND_ID))
//地区
.and(CLUE.CITY.notIn(cityList))
.and(CLUE.CITY.eq(city))
//品牌
.and(BRAND.ID.eq(brandId))
//校区
@ -532,7 +574,15 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
} else {
return null;
}
}));
}),
//脱离间隔
item -> item.field(CluePageVo::getPutOffInterval)
.queryWrapper(putOffInterval -> queryChain().select(dateDiff(now(), CLUE_RECORD.CREATE_TIME).as(CluePageVo::getPutOffInterval))
.from(CLUE_RECORD)
.where(CLUE_RECORD.RECORD_TYPE.eq(4))
.and(CLUE_RECORD.CLUE_ID.eq(putOffInterval.getId()))
.orderBy(CLUE_RECORD.CREATE_TIME.desc())
.limit(1)));
}
/**
@ -544,27 +594,47 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
@Override
@Transactional(rollbackFor = Exception.class)
public void clueCollection(String id) {
Clue clue = this.getById(id);
JSONObject loginUserInfo = SecurityUtils.getInstance().getLoginUserInfo();
if (StringUtils.isBlank(clue.getDevStaffId())) {
clue.setDevStaffId(loginUserInfo.getString("id"));
//分布式锁进行幂等处理
RedisService redisService = SpringUtils.getBean(RedisService.class);
//分布式锁进行幂等处理
Lock userIdLock = redisService.distributedLock(OamRedisConstant.CLUE_CLAIM_LOCK + id);
if (userIdLock.tryLock()) {
try {
Clue clue = this.getById(id);
if (StringUtils.isNotBlank(clue.getResponsibleStaffId())){
throw new ServiceException("当前线索已被领取,请刷新页面后重试");
}
JSONObject loginUserInfo = SecurityUtils.getInstance().getLoginUserInfo();
if (StringUtils.isBlank(clue.getDevStaffId())) {
clue.setDevStaffId(loginUserInfo.getString("id"));
}
LocalDateTime now = LocalDateTime.now();
String content = "员工" + loginUserInfo.getString("name") + "领取了该线索";
clue.setResponsibleStaffId(loginUserInfo.getString("id"))
.setReceiptTime(now)
.setLastFollowUpTime(now)
.setLastFollowUpContent(content)
.setLastReceiptStaffId(loginUserInfo.getString("id"))
.setLastReceiptTime(now);
this.updateById(clue);
//插入记录
ClueRecord clueRecord = new ClueRecord();
clueRecord.setClueId(id)
.setRecordType(1)
.setRecordStaffId(loginUserInfo.getString("id"))
.setRecordContent(content);
SpringUtils.getBean(ClueRecordService.class).save(clueRecord);
}catch (Exception e) {
throw new ServiceException(e.getMessage());
} finally {
//释放锁
userIdLock.unlock();
}
} else {
//获取锁失败直接返回空
throw new ServiceException("请勿重复领取");
}
LocalDateTime now = LocalDateTime.now();
String content = "员工" + loginUserInfo.getString("name") + "领取了该线索";
clue.setResponsibleStaffId(loginUserInfo.getString("id"))
.setReceiptTime(now)
.setLastFollowUpTime(now)
.setLastFollowUpContent(content)
.setLastReceiptStaffId(loginUserInfo.getString("id"))
.setLastReceiptTime(now);
this.updateById(clue);
//插入记录
ClueRecord clueRecord = new ClueRecord();
clueRecord.setClueId(id)
.setRecordType(1)
.setRecordStaffId(loginUserInfo.getString("id"))
.setRecordContent(content);
SpringUtils.getBean(ClueRecordService.class).save(clueRecord);
}
/**
@ -582,11 +652,27 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
PageDomain pageDomain = SqlUtils.getInstance().getPageDomain();
QueryWrapper queryWrapper = QueryWrapper.create();
JSONObject loginUserInfo = SecurityUtils.getInstance().getLoginUserInfo();
if (StringUtils.isNotBlank(city) && StringUtils.equals("其他", city)) {
List<String> dictValues = SpringUtils.getBean(DictDataService.class).getDictDataByDictType("oam_clue_area")
.stream().map(DictData::getDictValue).collect(Collectors.toList());
if (dictValues.isEmpty()) {
throw new ServiceException("没有设置线索区域字典,请先设置后再进行操作");
}
List<String> cityList = new ArrayList<>();
dictValues.forEach(item -> {
cityList.addAll(Arrays.asList(item.split("/")));
});
queryWrapper.and(CLUE.CITY.notIn(cityList));
} else if (StringUtils.isNotBlank(city)) {
queryWrapper.and(CLUE.CITY.eq(city));
}
return this.mapper.paginateAs(Page.of(pageDomain.getPageNum(),pageDomain.getPageSize()),
queryWrapper
.select(CLUE.CITY,CLUE.ID,CLUE.CREATE_TIME,CLUE.DEV_STAFF_ID,CLUE.LAST_FOLLOW_UP_TIME,CLUE.LAST_FOLLOW_UP_CONTENT,CLUE.RECEIPT_TIME,CLUE.STORE_ID,CLUE.RESPONSIBLE_STAFF_ID)
.select(CLUE.CITY,CLUE.ID,CLUE.CREATE_TIME,CLUE.DEV_STAFF_ID,CLUE.LAST_FOLLOW_UP_TIME,CLUE.LAST_FOLLOW_UP_CONTENT,CLUE.RECEIPT_TIME,CLUE.STORE_ID,CLUE.RESPONSIBLE_STAFF_ID,
CLUE.CLUE_STATUS)
.select(STORE.STORE_NAME,STORE.STORE_ADDR,STORE.PERSON_CHARGE,STORE.PHONE)
.select(BRAND.BRAND_NAME)
.select(STORE_SIGN.CREATE_TIME.as(CluePageVo::getStoreSignTime))
// 跟进间隔
.select(dateDiff(now(), CLUE.LAST_FOLLOW_UP_TIME).as(CluePageVo::getFollowUpInterval))
// 签约时间
@ -594,9 +680,8 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
.from(CLUE)
.leftJoin(STORE).on(STORE.ID.eq(CLUE.STORE_ID))
.leftJoin(BRAND).on(BRAND.ID.eq(STORE.BRAND_ID))
.leftJoin(STORE_SIGN).on(STORE_SIGN.STORE_ID.eq(STORE.ID))
.and(CLUE.DEV_STAFF_ID.eq(loginUserInfo.getString("id")))
//地区
.and(CLUE.CITY.eq(city))
//品牌
.and(BRAND.ID.eq(brandId))
//校区

View File

@ -218,6 +218,11 @@ public class TaskWorkOrderServiceImpl extends ServiceImpl<TaskWorkOrderMapper, T
@Override
@Transactional(rollbackFor = Exception.class)
public void insertWorkOrder(TaskWorkOrderBo bo) {
//获取当前时间
int hour = LocalDateTime.now().getHour();
if (hour < 9 || hour > 21){
throw new ServiceException("工单提交时间为:9:00-21:00,请明天上午九点后再提交");
}
// 获取值班员工
DutyService dutyService = SpringUtils.getBean(DutyService.class);
Duty duty = dutyService.getOne(QueryWrapper.create().where(DUTY.DUTY_DATE.eq(DateUtils.getDate())));

View File

@ -130,6 +130,12 @@ public class CluePageVo {
@ApiModelProperty(value = "签约间隔")
private Integer signInterval;
/**
* 脱离间隔
*/
@ApiModelProperty(value = "脱离间隔")
private Integer putOffInterval;
/**
* 签约状态(0:待签约;1:已签约;2:警告线索)
*/
@ -161,4 +167,10 @@ public class CluePageVo {
@ApiModelProperty(value = "最后接收员工姓名")
private String lastReceiptStaffName;
/**
* 签约时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime storeSignTime;
}

View File

@ -16,4 +16,9 @@ public interface OamRedisConstant {
* 任务领取幂等锁
*/
String TASK_CLAIM_LOCK = "oam:taskClaimLock:task:";
/**
* 线索领取幂等锁
*/
String CLUE_CLAIM_LOCK = "oam:clueClaimLock:clue:";
}

View File

@ -11,10 +11,13 @@ import com.cpop.oam.business.entity.ClueRecord;
import com.cpop.oam.business.entity.DataImport;
import com.cpop.oam.business.entity.Task;
import com.cpop.oam.business.entity.table.DataImportTableDef;
import com.cpop.oam.business.mapper.ClueMapper;
import com.cpop.oam.business.service.*;
import com.cpop.oam.business.vo.SignGoalConfigInfoVo;
import com.cpop.oam.framework.constant.OamConfigKey;
import com.cpop.oam.framework.enums.OamConfigEnum;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.update.UpdateChain;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
@ -30,6 +33,7 @@ import java.util.stream.Collectors;
import static com.cpop.oam.business.entity.table.ClueTableDef.CLUE;
import static com.cpop.oam.business.entity.table.TaskTableDef.TASK;
import static com.cpop.system.business.entity.table.StoreTableDef.STORE;
/**
@ -164,10 +168,15 @@ public class OamScheduledTasks {
.setRecordType(4)
.setRecordContent("跟进间隔过长");
clueRecords.add(clueRecord);
item.setResponsibleStaffId(null).setClueStatus(0);
});
//批量修改
clueService.updateBatch(followOffClueList);
Db.executeBatch(signOffClueList, ClueMapper.class, (mapper, clue) -> {
UpdateChain.of(mapper)
.set(CLUE.RECEIPT_TIME, null)
.set(CLUE.RESPONSIBLE_STAFF_ID, null)
.set(CLUE.CLUE_STATUS, 0)
.where(CLUE.ID.eq(clue.getId()))
.update();
});
}
//签约脱离
if (!signOffClueList.isEmpty()){
@ -178,7 +187,14 @@ public class OamScheduledTasks {
.setRecordType(4)
.setRecordContent("签约周期过长");
clueRecords.add(clueRecord);
item.setResponsibleStaffId(null).setClueStatus(0);
});
Db.executeBatch(signOffClueList, ClueMapper.class, (mapper, clue) -> {
UpdateChain.of(mapper)
.set(CLUE.RECEIPT_TIME, null)
.set(CLUE.RESPONSIBLE_STAFF_ID, null)
.set(CLUE.CLUE_STATUS, 0)
.where(CLUE.ID.eq(clue.getId()))
.update();
});
clueService.updateBatch(signOffClueList);
}

View File

@ -47,7 +47,7 @@ public class WorkOrderAcceptOverTimeRemindTask implements Job {
phoneList.add(responsibleStaff.getPhoneNumber());
try {
SpringUtils.getBean(WebHookSendHandler.class).webHookSendText(WebHookKeyConstant.ORDER_INFO_BOT, phoneList,
task.getTaskContent() + "\n您有一个工单即将接超时,请尽快接受",
task.getTaskContent() + "\n您有一个工单即将接超时,请尽快接受",
false);
} catch (IOException e) {
throw new ServiceException("发送工单接受超时消息通知失败!");

View File

@ -47,7 +47,7 @@ public class WorkOrderFinishOverTimeRemindTask implements Job {
phoneList.add(recordStaff.getPhoneNumber());
try {
SpringUtils.getBean(WebHookSendHandler.class).webHookSendText(WebHookKeyConstant.ORDER_INFO_BOT, phoneList,
task.getTaskContent() + "\n您有一个工单即将完结超时,请尽快练习相关人员办结",
task.getTaskContent() + "\n您有一个工单即将完结超时,请尽快联系相关人员办结",
false);
} catch (IOException e) {
throw new ServiceException("发送工单完结超时消息通知失败!");

View File

@ -1,11 +1,17 @@
package com.cpop.system.business.controller.backstage;
import com.cpop.api.cloudDb.core.dto.CloudBrandDto;
import com.cpop.api.cloudDb.handler.CloudBrandHandler;
import com.cpop.common.utils.bean.BeanUtils;
import com.cpop.core.base.R;
import com.cpop.core.base.enums.SourceType;
import com.cpop.core.utils.SpringUtils;
import com.cpop.system.business.bo.BrandBo;
import com.cpop.system.business.vo.BrandPageVo;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.Row;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
@ -65,6 +71,14 @@ public class BackstageBrandController {
public R<Void> updateSysBrand(@RequestBody @ApiParam("系统-品牌") @Validated BrandBo bo) {
Brand entity = BeanUtils.mapToClass(bo, Brand.class);
brandService.updateById(entity);
//获取云品牌拓展
Row row = Db.selectOneByQuery("cp_j_brand_extend", QueryWrapper.create().where("brand_id = ?", bo.getId()));
if (row != null){
CloudBrandDto cloudBrandDto = new CloudBrandDto();
cloudBrandDto.setBrandCloudId(row.getString("brand_cloud_id"));
cloudBrandDto.setBrandName(bo.getBrandName());
SpringUtils.getBean(CloudBrandHandler.class).updateBrand(cloudBrandDto);
}
return R.ok();
}