Commit f7cba6fe by HlQ

[add]

1.收货记录新增钉钉消息推送,添加详情页推送
2.设备返修、备件申请字段添加
3.新增标签管理以及项目绑定标签
[fix]
合同列表查询数据权限控制修改逻辑
1 parent 21739ac2
...@@ -85,4 +85,14 @@ public class PaymentController { ...@@ -85,4 +85,14 @@ public class PaymentController {
} }
} }
@GetMapping("/openSafe")
public String openSafe(String code) {
// 校验 redis 里查询 code 相关信息
if (true) {
StpUtil.openSafe("payment", 600);
return "认证成功";
}
return "认证失败";
}
} }
...@@ -2,6 +2,7 @@ package vion.controller; ...@@ -2,6 +2,7 @@ package vion.controller;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Opt; import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
...@@ -94,7 +95,7 @@ public class StoreController { ...@@ -94,7 +95,7 @@ public class StoreController {
@SaCheckPermission(value = "store:calMaintainStatus", orRole = "admin") @SaCheckPermission(value = "store:calMaintainStatus", orRole = "admin")
// todo 权限未加,前端未使用到该接口 // todo 权限未加,前端未使用到该接口
public String manualCalMaintainStatus() { public String manualCalMaintainStatus() {
return storeService.calMaintainStatus(); return storeService.calMaintainStatus(ListUtil.empty());
} }
@GetMapping("/store/user/{storeId}") @GetMapping("/store/user/{storeId}")
...@@ -152,4 +153,10 @@ public class StoreController { ...@@ -152,4 +153,10 @@ public class StoreController {
return storeService.mergeStore(dto); return storeService.mergeStore(dto);
} }
@PostMapping("/store/tag/{id}")
@SaCheckPermission(value = "store:tag", orRole = "admin")
public String addTag(@PathVariable Long id, @RequestBody Long tagId) {
return storeService.addTag(id, tagId);
}
} }
package vion.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import vion.model.Tag;
import vion.service.ITagService;
/**
* 标签管理
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/tag")
public class TagController {
private final ITagService tagServiceImpl;
@GetMapping
@SaCheckPermission(value = "tag:list", orRole = "admin")
public Page<Tag> list(Tag tag) {
return tagServiceImpl.lambdaQuery(tag).page(Page.of(tag.getPageNum(), tag.getPageSize()));
}
@GetMapping("/{id}")
@SaCheckPermission(value = "tag:query", orRole = "admin")
public Tag getById(@PathVariable Long id) {
return tagServiceImpl.getById(id);
}
@PostMapping
@SaCheckPermission(value = "tag:save", orRole = "admin")
public String save(@RequestBody Tag tag) {
return tagServiceImpl.save(tag) ? "新增成功" : "新增失败";
}
@PostMapping("/{id}")
@SaCheckPermission(value = "tag:edit", orRole = "admin")
public String update(@PathVariable Long id, @RequestBody Tag tag) {
tag.setId(id);
return tagServiceImpl.updateById(tag) ? "修改成功" : "修改失败";
}
@DeleteMapping("/{id}")
@SaCheckPermission(value = "tag:remove", orRole = "admin")
public String remove(@PathVariable Long id) {
return tagServiceImpl.removeById(id) ? "删除成功" : "删除失败";
}
}
package vion.cron; package vion.cron;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Opt; import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjUtil;
...@@ -34,6 +35,7 @@ public class ContractRunner { ...@@ -34,6 +35,7 @@ public class ContractRunner {
private final IDictionaryService dictionaryService; private final IDictionaryService dictionaryService;
private final IContractPaymentService contractPaymentService; private final IContractPaymentService contractPaymentService;
private final IRContractUserService contractUserService; private final IRContractUserService contractUserService;
private final IRContractStoreService contractStoreService;
private final IStoreService storeService; private final IStoreService storeService;
private final IPaymentService paymentService; private final IPaymentService paymentService;
private final RedisTemplate redisTemplate; private final RedisTemplate redisTemplate;
...@@ -114,13 +116,22 @@ public class ContractRunner { ...@@ -114,13 +116,22 @@ public class ContractRunner {
return; return;
} }
List<Long> updContractIdList = new ArrayList<>();
insOrUpdContractList.forEach(v -> { insOrUpdContractList.forEach(v -> {
if (no2ContactMap.containsKey(v.getContractNo())) { if (no2ContactMap.containsKey(v.getContractNo())) {
v.setId(no2ContactMap.get(v.getContractNo()).getId()); Long contractId = no2ContactMap.get(v.getContractNo()).getId();
v.setId(contractId);
// 已有合同不更新状态 // 已有合同不更新状态
v.setStatus(null); v.setStatus(null);
updContractIdList.add(contractId);
} }
}); });
// 合同更新,同步调用一下更新项目的维保状态
Opt.ofEmptyAble(contractStoreService.lambdaQuery().in(RContractStore::getContractId, updContractIdList).list())
.map(csList -> csList.stream().map(RContractStore::getStoreId).collect(Collectors.toList()))
.filter(CollUtil::isNotEmpty)
.ifPresent(storeService::calMaintainStatus);
contractService.saveOrUpdateBatch(insOrUpdContractList, 500); contractService.saveOrUpdateBatch(insOrUpdContractList, 500);
insOrUpdContractList.forEach(v -> { insOrUpdContractList.forEach(v -> {
// 合同状态不为空,代表此条记录为新增,需要同步销售人信息到 r_contract_user 表中 // 合同状态不为空,代表此条记录为新增,需要同步销售人信息到 r_contract_user 表中
...@@ -132,6 +143,7 @@ public class ContractRunner { ...@@ -132,6 +143,7 @@ public class ContractRunner {
.orElse(null); .orElse(null);
contractUser.setUserId(userId); contractUser.setUserId(userId);
contractUser.setUsername(v.getSaleName()); contractUser.setUsername(v.getSaleName());
contractUser.setEnterDate(v.getSignDate());
contractUser.setContractId(v.getId()); contractUser.setContractId(v.getId());
contractUser.setContractNo(v.getContractNo()); contractUser.setContractNo(v.getContractNo());
contractUserService.save(contractUser); contractUserService.save(contractUser);
...@@ -239,7 +251,7 @@ public class ContractRunner { ...@@ -239,7 +251,7 @@ public class ContractRunner {
@Scheduled(cron = "0 0 1 * * ?") @Scheduled(cron = "0 0 1 * * ?")
public void calMaintainStatus() { public void calMaintainStatus() {
log.info("【开始】计算门店维保状态"); log.info("【开始】计算门店维保状态");
storeService.calMaintainStatus(); storeService.calMaintainStatus(ListUtil.empty());
log.info("【结束】计算门店维保状态"); log.info("【结束】计算门店维保状态");
} }
......
...@@ -10,15 +10,29 @@ import lombok.Setter; ...@@ -10,15 +10,29 @@ import lombok.Setter;
@Getter @Getter
@Setter @Setter
public class DingDTO { public class DingDTO {
/** 微信拼接的两个 code 参数 */ /**
* 微信拼接的两个 code 参数
*/
private String authCode; private String authCode;
private String code; private String code;
/** 项目id */ /**
* 项目id
*/
private Long storeId; private Long storeId;
/** 工单id */ /**
* 工单id
*/
private Long taskId; private Long taskId;
/** 预工单id */ /**
* 预工单id
*/
private Long taskTempId; private Long taskTempId;
/** 用户id */ /**
* 用户id
*/
private Long userId; private Long userId;
/**
* 发货记录id
*/
private Long deliveryId;
} }
...@@ -181,7 +181,7 @@ public class PointInfoDTO extends BaseDTO { ...@@ -181,7 +181,7 @@ public class PointInfoDTO extends BaseDTO {
/** /**
* 备注 * 备注
*/ */
private String remake; private String remark;
/** /**
* uuid * uuid
......
...@@ -53,6 +53,16 @@ public class RepairRecDTO extends BaseDTO { ...@@ -53,6 +53,16 @@ public class RepairRecDTO extends BaseDTO {
private String phone; private String phone;
/** /**
* 快递单号(用户填写的,他/她寄出去的设备的快递单号)
*/
private String userTrackingNumber;
/**
* 是否借用备件 0:否 1:是
*/
private Integer borrowToggle;
/**
* 设备数量 * 设备数量
*/ */
private Integer deviceNum; private Integer deviceNum;
...@@ -88,6 +98,11 @@ public class RepairRecDTO extends BaseDTO { ...@@ -88,6 +98,11 @@ public class RepairRecDTO extends BaseDTO {
*/ */
private String trackingNumber; private String trackingNumber;
/*
* 状态 1:运输中 2:维修中 3:已发货
*/
private Integer status;
private String uuid; private String uuid;
/** /**
......
...@@ -89,6 +89,16 @@ public class SparePartDTO extends BaseDTO { ...@@ -89,6 +89,16 @@ public class SparePartDTO extends BaseDTO {
private String trackingNumber; private String trackingNumber;
/** /**
* 发货状态 0:未发货 1:已发货
*/
private Integer shipStatus;
/**
* 归还状态 0:未归还 1:已归还
*/
private Integer returnStatus;
/**
* 备注 * 备注
*/ */
private String remark; private String remark;
......
package vion.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import vion.model.RStoreTag;
/**
* @author HlQ
* @date 2024/1/30
*/
public interface RStoreTagMapper extends MPJBaseMapper<RStoreTag> {
}
\ No newline at end of file \ No newline at end of file
package vion.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import vion.model.Tag;
/**
* @author HlQ
* @date 2024/1/30
*/
public interface TagMapper extends MPJBaseMapper<Tag> {
}
\ No newline at end of file \ No newline at end of file
...@@ -149,7 +149,7 @@ public class Contract { ...@@ -149,7 +149,7 @@ public class Contract {
private Integer warrantyPeriod; private Integer warrantyPeriod;
/** /**
* 终验日期 * 终验日期,目前取值为合同阶段为系统初验或者终验的 nodeDate
*/ */
@TableField(value = "final_date") @TableField(value = "final_date")
private Date finalDate; private Date finalDate;
......
...@@ -218,8 +218,8 @@ public class PointInfo { ...@@ -218,8 +218,8 @@ public class PointInfo {
/** /**
* 备注 * 备注
*/ */
@TableField(value = "remake") @TableField(value = "remark")
private String remake; private String remark;
/** /**
* 施工方 * 施工方
......
...@@ -57,6 +57,24 @@ public class RRepairDevice extends BaseDTO { ...@@ -57,6 +57,24 @@ public class RRepairDevice extends BaseDTO {
private String deviceNo; private String deviceNo;
/** /**
* 归还的设备序列号
*/
@TableField(value = "return_device_no")
private String returnDeviceNo;
/**
* 是否原设备发货 0:不是 1:是
*/
@TableField(value = "origin_device")
private Integer originDevice;
/**
* 发货设备序列号
*/
@TableField(value = "origin_device_no")
private String originDeviceNo;
/**
* 设备id * 设备id
*/ */
@TableField(value = "device_id") @TableField(value = "device_id")
......
package vion.model;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.util.Date;
/**
* @author HlQ
* @date 2024/1/30
*/
@Data
@TableName(value = "r_store_tag")
public class RStoreTag {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 项目id
*/
@TableField(value = "store_id")
private Long storeId;
/**
* 标签id
*/
@TableField(value = "tag_id")
private Long tagId;
@TableField(value = "create_time", fill = FieldFill.INSERT)
private Date createTime;
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
}
\ No newline at end of file \ No newline at end of file
...@@ -50,13 +50,13 @@ public class RepairRec { ...@@ -50,13 +50,13 @@ public class RepairRec {
/** /**
* 项目名称(用户填写的) * 项目名称(用户填写的)
*/ */
@TableField(value = "project_name") @TableField(value = "project_name", condition = SqlCondition.LIKE)
private String projectName; private String projectName;
/** /**
* 联系人 * 联系人
*/ */
@TableField(value = "contact") @TableField(value = "contact", condition = SqlCondition.LIKE)
private String contact; private String contact;
/** /**
...@@ -66,6 +66,19 @@ public class RepairRec { ...@@ -66,6 +66,19 @@ public class RepairRec {
private String phone; private String phone;
/** /**
* 快递单号(用户填写的,他/她寄出去的设备的快递单号)
*/
@TableField(value = "user_tracking_number")
private String userTrackingNumber;
/**
* 是否借用备件 0:否 1:是
*/
@TableField(value = "borrow_toggle")
private Integer borrowToggle;
/**
* 设备数量 * 设备数量
*/ */
@TableField(value = "device_num") @TableField(value = "device_num")
...@@ -107,6 +120,12 @@ public class RepairRec { ...@@ -107,6 +120,12 @@ public class RepairRec {
@TableField(value = "tracking_number") @TableField(value = "tracking_number")
private String trackingNumber; private String trackingNumber;
/*
* 状态 1:运输中 2:维修中 3:已发货
*/
@TableField(value = "status")
private Integer status;
@TableField(value = "uuid") @TableField(value = "uuid")
private String uuid; private String uuid;
......
...@@ -50,13 +50,13 @@ public class SparePart { ...@@ -50,13 +50,13 @@ public class SparePart {
/** /**
* 项目名称(用户填写的) * 项目名称(用户填写的)
*/ */
@TableField(value = "project_name") @TableField(value = "project_name", condition = SqlCondition.LIKE)
private String projectName; private String projectName;
/** /**
* 联系人 * 联系人
*/ */
@TableField(value = "contact") @TableField(value = "contact", condition = SqlCondition.LIKE)
private String contact; private String contact;
/** /**
...@@ -108,6 +108,18 @@ public class SparePart { ...@@ -108,6 +108,18 @@ public class SparePart {
private String trackingNumber; private String trackingNumber;
/** /**
* 发货状态 0:未发货 1:已发货
*/
@TableField(value = "ship_status")
private Integer shipStatus;
/**
* 归还状态 0:未归还 1:已归还
*/
@TableField(value = "return_status")
private Integer returnStatus;
/**
* 备注 * 备注
*/ */
@TableField(value = "remark") @TableField(value = "remark")
......
package vion.model;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import vion.dto.BaseDTO;
import java.util.Date;
/**
* @author HlQ
* @date 2024/1/30
*/
@Data
@TableName(value = "tbl_tag")
public class Tag extends BaseDTO {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 名字
*/
@TableField(value = "\"name\"", condition = SqlCondition.LIKE)
private String name;
/**
* 备注
*/
@TableField(value = "remark")
private String remark;
@TableField(value = "create_time", fill = FieldFill.INSERT)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime;
}
\ No newline at end of file \ No newline at end of file
package vion.service;
import com.github.yulichang.base.MPJBaseService;
import vion.model.RStoreTag;
/**
* @author HlQ
* @date 2024/1/30
*/
public interface IRStoreTagService extends MPJBaseService<RStoreTag> {
}
...@@ -15,10 +15,12 @@ public interface IStoreService extends MPJBaseService<Store> { ...@@ -15,10 +15,12 @@ public interface IStoreService extends MPJBaseService<Store> {
String updateStoreStage(StatusDTO statusDTO, String token); String updateStoreStage(StatusDTO statusDTO, String token);
String calMaintainStatus(); String calMaintainStatus(List<Long> storeIdList);
List<StoreVO> storeScreen(); List<StoreVO> storeScreen();
String mergeStore(StoreDTO dto); String mergeStore(StoreDTO dto);
String addTag(Long id, Long tagId);
} }
package vion.service;
import com.github.yulichang.base.MPJBaseService;
import vion.model.Tag;
/**
* @author HlQ
* @date 2024/1/30
*/
public interface ITagService extends MPJBaseService<Tag> {
}
...@@ -422,12 +422,11 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont ...@@ -422,12 +422,11 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
.map(l -> l.stream().map(RoleVO::getCode).collect(Collectors.toSet())) .map(l -> l.stream().map(RoleVO::getCode).collect(Collectors.toSet()))
.orElse(CollUtil.newHashSet()); .orElse(CollUtil.newHashSet());
Assert.notEmpty(roleCodeList, "当前用户角色不详,请联系管理员"); Assert.notEmpty(roleCodeList, "当前用户角色不详,请联系管理员");
String curName; String curName = "";
if (!roleCodeList.contains("admin") && !roleCodeList.contains("shangwu") && !roleCodeList.contains("caiwu")) { boolean isPerm = !roleCodeList.contains("admin") && !roleCodeList.contains("shangwu") && !roleCodeList.contains("caiwu");
if (isPerm) {
// 不是以上三个角色,只能访问自己相关的合同 // 不是以上三个角色,只能访问自己相关的合同
curName = userVO.getUsername(); curName = userVO.getUsername();
} else {
curName = "";
} }
// 根据查询条件的销售人查询关联的合同 // 根据查询条件的销售人查询关联的合同
...@@ -450,10 +449,10 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont ...@@ -450,10 +449,10 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
.map(name -> this.listObjs(Wrappers.<Contract>lambdaQuery() .map(name -> this.listObjs(Wrappers.<Contract>lambdaQuery()
.select(Contract::getId).eq(Contract::getSaleName, name), o -> Long.valueOf(o.toString()))) .select(Contract::getId).eq(Contract::getSaleName, name), o -> Long.valueOf(o.toString())))
.orElse(new ArrayList<>()); .orElse(new ArrayList<>());
Collection<Long> queryContractUserIdList = CollUtil.addAll(contractUserIdList1, contractUserIdList2); Collection<Long> queryContractUserIdList = CollUtil.addAllIfNotContains(contractUserIdList1, contractUserIdList2);
Collection<Long> curContractUserIdList = CollUtil.addAll(contractUserIdList3, contractUserIdList4); Collection<Long> curContractUserIdList = CollUtil.addAllIfNotContains(contractUserIdList3, contractUserIdList4);
Set<Long> allContractUserIdList; Set<Long> allContractUserIdList;
if (CollUtil.isNotEmpty(queryContractUserIdList) && CollUtil.isNotEmpty(curContractUserIdList)) { if (StrUtil.isNotBlank(curName) && StrUtil.isNotBlank(dto.getSaleName())) {
// 当前用户和查询条件的销售人都存在,取交集 // 当前用户和查询条件的销售人都存在,取交集
allContractUserIdList = CollUtil.intersectionDistinct(queryContractUserIdList, curContractUserIdList); allContractUserIdList = CollUtil.intersectionDistinct(queryContractUserIdList, curContractUserIdList);
} else { } else {
...@@ -461,22 +460,33 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont ...@@ -461,22 +460,33 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
} }
Set<Long> finalIdSet; Set<Long> finalIdSet;
if (CollUtil.isNotEmpty(lineContractIdList) && CollUtil.isNotEmpty(allContractUserIdList)) { if (isPerm) {
// 产品线关联的合同和销售人或当前人关联的合同都存在,取交集 // 不是以上三个角色,只能访问自己相关的合同或自己产品线相关的合同
finalIdSet = CollUtil.intersectionDistinct(lineContractIdList, allContractUserIdList); if (ObjUtil.isNotNull(dto.getProductLine())) {
finalIdSet = CollUtil.intersectionDistinct(lineContractIdList, allContractUserIdList);
} else {
finalIdSet = CollUtil.unionDistinct(lineContractIdList, allContractUserIdList);
}
if (CollUtil.isEmpty(finalIdSet)) {
// 根据条件筛选要查询的合同为空,集合补元素 -1,防止数据库查询出错
finalIdSet.add(-1L);
}
} else { } else {
finalIdSet = CollUtil.unionDistinct(lineContractIdList, allContractUserIdList); if (StrUtil.isNotBlank(dto.getSaleName()) && ObjUtil.isNotNull(dto.getProductLine())) {
} finalIdSet = CollUtil.intersectionDistinct(lineContractIdList, allContractUserIdList);
if (CollUtil.isEmpty(finalIdSet)) { } else {
// 根据条件筛选要查询的合同为空,集合补元素 -1,防止数据库查询出错 finalIdSet = CollUtil.unionDistinct(lineContractIdList, allContractUserIdList);
finalIdSet.add(-1L); }
if ((StrUtil.isNotBlank(dto.getSaleName()) || ObjUtil.isNotNull(dto.getProductLine())) && CollUtil.isEmpty(finalIdSet)) {
finalIdSet.add(-1L);
}
} }
// 前端传参中的 saleName 字段已单独处理,这里置空,不参与下一步的 converter.convert // 前端传参中的 saleName 字段已单独处理,这里置空,不参与下一步的 converter.convert
dto.setSaleName(null); dto.setSaleName(null);
MPJLambdaWrapper<Contract> wrapper = new MPJLambdaWrapper<>(converter.convert(dto, Contract.class)) MPJLambdaWrapper<Contract> wrapper = new MPJLambdaWrapper<>(converter.convert(dto, Contract.class))
.selectAll(Contract.class) .selectAll(Contract.class)
.in(CollUtil.isNotEmpty(lineContractIdList) || CollUtil.isNotEmpty(allContractUserIdList), Contract::getId, finalIdSet) .in(CollUtil.isNotEmpty(finalIdSet), Contract::getId, finalIdSet)
.notIn(CollUtil.isNotEmpty(contractIdList), Contract::getId, contractIdList) .notIn(CollUtil.isNotEmpty(contractIdList), Contract::getId, contractIdList)
.between(ArrayUtil.isAllNotNull(dto.getSignDateStart(), dto.getSignDateEnd()), Contract::getSignDate, dto.getSignDateStart(), dto.getSignDateEnd()) .between(ArrayUtil.isAllNotNull(dto.getSignDateStart(), dto.getSignDateEnd()), Contract::getSignDate, dto.getSignDateStart(), dto.getSignDateEnd())
.orderByDesc(Contract::getEntryTime); .orderByDesc(Contract::getEntryTime);
......
...@@ -8,6 +8,7 @@ import cn.hutool.core.map.MapUtil; ...@@ -8,6 +8,7 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
...@@ -162,10 +163,15 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord ...@@ -162,10 +163,15 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord
" \n #### 发货日期:{}" + " \n #### 发货日期:{}" +
" \n #### 发送时间:{}", " \n #### 发送时间:{}",
contract.getName(), contract.getContractNo(), rec.getCourierCompany(), rec.getTrackingNumber(), rec.getConsignee(), DateUtil.formatDate(rec.getShipDate()), DateUtil.now()); contract.getName(), contract.getContractNo(), rec.getCourierCompany(), rec.getTrackingNumber(), rec.getConsignee(), DateUtil.formatDate(rec.getShipDate()), DateUtil.now());
content.set("text", markdown); content.set("markdown", markdown);
content.set("btn_orientation", "1");
msg.set("msgtype", "markdown"); JSONArray jsonArray = new JSONArray();
msg.set("markdown", content); jsonArray.add(new JSONObject().set("title", "查看详情").set("action_url", "https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=dingkrzwks0jpi2di3uo&response_type=code&scope=snsapi_auth&state=STATE&redirect_uri=https%3A%2F%2Fyunwei.vionyun.com%3A8443%2Fyunwei%2Fapi%2Fding%2Fcallback%2Finside%3FdeliveryId%3D" + rec.getId()));
content.set("btn_json_list", jsonArray);
msg.set("msgtype", "action_card");
msg.set("action_card", content);
jsonObj.set("msg", msg); jsonObj.set("msg", msg);
return jsonObj; return jsonObj;
} }
......
package vion.service.impl;
import com.github.yulichang.base.MPJBaseServiceImpl;
import org.springframework.stereotype.Service;
import vion.mapper.RStoreTagMapper;
import vion.model.RStoreTag;
import vion.service.IRStoreTagService;
/**
* @author HlQ
* @date 2024/1/30
*/
@Service
public class RStoreTagServiceImpl extends MPJBaseServiceImpl<RStoreTagMapper, RStoreTag> implements IRStoreTagService {
}
...@@ -85,8 +85,11 @@ public class RepairRecServiceImpl extends MPJBaseServiceImpl<RepairRecMapper, Re ...@@ -85,8 +85,11 @@ public class RepairRecServiceImpl extends MPJBaseServiceImpl<RepairRecMapper, Re
MPJLambdaWrapper<RepairRec> wrapper = new MPJLambdaWrapper<>(converter.convert(dto, RepairRec.class)) MPJLambdaWrapper<RepairRec> wrapper = new MPJLambdaWrapper<>(converter.convert(dto, RepairRec.class))
.selectAll(RepairRec.class) .selectAll(RepairRec.class)
.selectAs(Contract::getName, RepairRecVO::getContractName) .selectAs(Contract::getName, RepairRecVO::getContractName)
.selectAs(Store::getName, RepairRecVO::getStoreName)
.selectAs(Store::getMaintainStatus, RepairRecVO::getMaintainStatus)
.selectCollection(RRepairDevice.class, RepairRecVO::getRepairDeviceList) .selectCollection(RRepairDevice.class, RepairRecVO::getRepairDeviceList)
.leftJoin(Contract.class, Contract::getId, RepairRec::getContractId) .leftJoin(Contract.class, Contract::getId, RepairRec::getContractId)
.leftJoin(Store.class, Store::getId, RepairRec::getStoreId)
.leftJoin(RRepairDevice.class, on -> on.eq(RRepairDevice::getRId, RepairRec::getId).eq(RRepairDevice::getRType, 2)) .leftJoin(RRepairDevice.class, on -> on.eq(RRepairDevice::getRId, RepairRec::getId).eq(RRepairDevice::getRType, 2))
.between(RepairRec::getCreateTime, dto.getCreateTimeStart(), dto.getCreateTimeEnd()) .between(RepairRec::getCreateTime, dto.getCreateTimeStart(), dto.getCreateTimeEnd())
.orderByDesc(RepairRec::getCreateTime); .orderByDesc(RepairRec::getCreateTime);
......
...@@ -30,6 +30,7 @@ import vion.model.*; ...@@ -30,6 +30,7 @@ import vion.model.*;
import vion.service.*; import vion.service.*;
import vion.vo.ContractVO; import vion.vo.ContractVO;
import vion.vo.StoreVO; import vion.vo.StoreVO;
import vion.vo.TagVO;
import vion.vo.UserVO; import vion.vo.UserVO;
import java.io.File; import java.io.File;
...@@ -44,11 +45,14 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp ...@@ -44,11 +45,14 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
private final IAccountService accountService; private final IAccountService accountService;
private final IRContractStoreService contractStoreService; private final IRContractStoreService contractStoreService;
private final IContractPaymentService contractPaymentService;
private final IContractService contractService; private final IContractService contractService;
private final IFileService fileService; private final IFileService fileService;
private final IFaultLogService faultLogService; private final IFaultLogService faultLogService;
private final IFormService formService; private final IFormService formService;
private final IInspectService inspectService; private final IInspectService inspectService;
private final ITagService tagService;
private final IRStoreTagService storeTagService;
private final Converter converter; private final Converter converter;
// 引入 taskService 会循环依赖 // 引入 taskService 会循环依赖
private final TaskMapper taskMapper; private final TaskMapper taskMapper;
...@@ -69,17 +73,32 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp ...@@ -69,17 +73,32 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
List<Long> storeIdList = Opt.ofEmptyAble(storeList.getRecords()) List<Long> storeIdList = Opt.ofEmptyAble(storeList.getRecords())
.map(recs -> recs.stream().map(Store::getId).collect(Collectors.toList())) .map(recs -> recs.stream().map(Store::getId).collect(Collectors.toList()))
.orElse(ListUtil.empty()); .orElse(ListUtil.empty());
// storeId -> 项目绑定的合同的 list
Map<Long, List<RContractStore>> storeIdMap = Opt.ofEmptyAble(storeIdList) Map<Long, List<RContractStore>> storeIdMap = Opt.ofEmptyAble(storeIdList)
.map(l -> contractStoreService.lambdaQuery().in(RContractStore::getStoreId, l).list()) .map(l -> contractStoreService.lambdaQuery().in(RContractStore::getStoreId, l).list())
.map(contractStoreList -> contractStoreList.stream().collect(Collectors.groupingBy(RContractStore::getStoreId))) .map(contractStoreList -> contractStoreList.stream().collect(Collectors.groupingBy(RContractStore::getStoreId)))
.orElse(MapUtil.empty()); .orElse(MapUtil.empty());
Map<Long, Contract> id2ContractMap = Opt.ofEmptyAble(storeIdMap.values()) // 项目绑定的合同的id
List<Long> contractIdList = Opt.ofEmptyAble(storeIdMap.values())
.map(l -> l.stream().flatMap(List::stream).collect(Collectors.toList())) .map(l -> l.stream().flatMap(List::stream).collect(Collectors.toList()))
.filter(CollUtil::isNotEmpty) .filter(CollUtil::isNotEmpty)
.map(contractStoreList -> { .map(contractStoreList -> contractStoreList.stream().map(RContractStore::getContractId).collect(Collectors.toList())).
List<Contract> contractList = contractService.lambdaQuery().in(Contract::getId, contractStoreList.stream().map(RContractStore::getContractId).collect(Collectors.toList())).list(); orElse(ListUtil.empty());
return contractList.stream().collect(Collectors.toMap(Contract::getId, Function.identity())); // contractId -> contract
}) Map<Long, Contract> id2ContractMap = Opt.ofEmptyAble(contractIdList)
.map(l -> contractService.lambdaQuery()
.select(Contract::getId, Contract::getName, Contract::getContractNo, Contract::getType, Contract::getSignDate, Contract::getWarrantyPeriod, Contract::getFinalDate, Contract::getStatus, Contract::getSaleName, Contract::getCustomerName, Contract::getMaintainSdate, Contract::getMaintainEdate)
.in(Contract::getId, l).list())
.map(contractList -> contractList.stream().collect(Collectors.toMap(Contract::getId, Function.identity())))
.orElse(MapUtil.empty());
// contractId -> 合同付款约定
Map<Long, List<ContractPayment>> contractId2CpMap = Opt.ofEmptyAble(contractIdList)
.map(l -> contractPaymentService.lambdaQuery().in(ContractPayment::getContractId, l).in(ContractPayment::getPaymentType, 3, 4).isNotNull(ContractPayment::getNodeDate).list())
.map(contractPaymentList -> contractPaymentList.stream().collect(Collectors.groupingBy(ContractPayment::getContractId, Collectors.collectingAndThen(Collectors.toList(), v -> {
v.sort(Comparator.comparing(ContractPayment::getPaymentType).reversed());
return v;
}))))
.orElse(MapUtil.empty()); .orElse(MapUtil.empty());
Map<Long, List<Long>> store2TaskIdMap = Opt.ofEmptyAble(storeIdList) Map<Long, List<Long>> store2TaskIdMap = Opt.ofEmptyAble(storeIdList)
...@@ -94,6 +113,18 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp ...@@ -94,6 +113,18 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
.map(serviceOrderList -> serviceOrderList.stream().collect(Collectors.groupingBy(ServiceOrder::getTaskId))) .map(serviceOrderList -> serviceOrderList.stream().collect(Collectors.groupingBy(ServiceOrder::getTaskId)))
.orElse(MapUtil.empty()); .orElse(MapUtil.empty());
// storeId -> tagList
Map<Long, List<TagVO>> storeId2TagMap = Opt.ofEmptyAble(storeIdList)
.map(l -> {
MPJLambdaWrapper<Tag> wrapper = new MPJLambdaWrapper<Tag>()
.selectAll(Tag.class)
.leftJoin(RStoreTag.class, RStoreTag::getTagId, Tag::getId)
.in(RStoreTag::getStoreId, l);
return tagService.selectJoinList(TagVO.class, wrapper);
})
.filter(CollUtil::isNotEmpty)
.map(tagVOS -> tagVOS.stream().collect(Collectors.groupingBy(TagVO::getStoreId)))
.orElse(MapUtil.empty());
List<StoreVO> storeVOList = new ArrayList<>(); List<StoreVO> storeVOList = new ArrayList<>();
storeList.getRecords().forEach(item -> { storeList.getRecords().forEach(item -> {
...@@ -102,10 +133,23 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp ...@@ -102,10 +133,23 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
storeVO.setFileNum(store2CntMap.getOrDefault(item.getId(), 0L)); storeVO.setFileNum(store2CntMap.getOrDefault(item.getId(), 0L));
Long storeId = item.getId(); Long storeId = item.getId();
// 关联合同
List<RContractStore> contractStores = storeIdMap.get(storeId); List<RContractStore> contractStores = storeIdMap.get(storeId);
storeVO.setContractCount(Opt.ofEmptyAble(contractStores).map(List::size).orElse(0)); storeVO.setContractCount(Opt.ofEmptyAble(contractStores).map(List::size).orElse(0));
storeVO.setContractVOList(id2ContractMap.values().stream()
.filter(v -> CollUtil.isNotEmpty(contractStores) && contractStores.stream().map(RContractStore::getContractId).collect(Collectors.toList()).contains(v.getId()))
.map(v -> converter.convert(v, ContractVO.class))
.collect(Collectors.toList()));
Contract masterContract = id2ContractMap.getOrDefault(item.getMasterContract(), null); Contract masterContract = id2ContractMap.getOrDefault(item.getMasterContract(), null);
// 关联合同验收时间
Opt.ofNullable(masterContract)
.map(c -> contractId2CpMap.getOrDefault(c.getId(), ListUtil.empty()))
.filter(CollUtil::isNotEmpty)
.map(l -> l.get(0).getNodeDate())
.ifPresent(nodeDate -> masterContract.setFinalDate(nodeDate));
storeVO.setMainContract(Opt.ofNullable(masterContract).map(c -> converter.convert(c, ContractVO.class)).orElse(null)); storeVO.setMainContract(Opt.ofNullable(masterContract).map(c -> converter.convert(c, ContractVO.class)).orElse(null));
storeVO.setTaskCount(store2TaskIdMap.getOrDefault(storeId, ListUtil.empty()).size()); storeVO.setTaskCount(store2TaskIdMap.getOrDefault(storeId, ListUtil.empty()).size());
// 补充服务单 // 补充服务单
...@@ -115,6 +159,8 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp ...@@ -115,6 +159,8 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
.collect(Collectors.toList()); .collect(Collectors.toList());
storeVO.setServiceOrderCount(serviceOrders.size()); storeVO.setServiceOrderCount(serviceOrders.size());
} }
// 关联标签
storeVO.setTagList(storeId2TagMap.getOrDefault(storeId, ListUtil.empty()));
storeVOList.add(storeVO); storeVOList.add(storeVO);
}); });
return Page.<StoreVO>of(data.getPageNum(), data.getPageSize(), storeList.getTotal()).setRecords(storeVOList); return Page.<StoreVO>of(data.getPageNum(), data.getPageSize(), storeList.getTotal()).setRecords(storeVOList);
...@@ -159,8 +205,8 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp ...@@ -159,8 +205,8 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
} }
@Override @Override
public String calMaintainStatus() { public String calMaintainStatus(List<Long> storeIdList) {
List<Store> storeList = this.list(); List<Store> storeList = this.lambdaQuery().in(CollUtil.isNotEmpty(storeIdList), Store::getId, storeIdList).list();
Map<Long, List<Long>> storeId2ContractIdMap = Opt.ofEmptyAble(contractStoreService.list()) Map<Long, List<Long>> storeId2ContractIdMap = Opt.ofEmptyAble(contractStoreService.list())
.map(l -> l.stream().collect(Collectors.groupingBy(RContractStore::getStoreId, Collectors.mapping(RContractStore::getContractId, Collectors.toList())))) .map(l -> l.stream().collect(Collectors.groupingBy(RContractStore::getStoreId, Collectors.mapping(RContractStore::getContractId, Collectors.toList()))))
.orElse(MapUtil.empty()); .orElse(MapUtil.empty());
...@@ -262,4 +308,12 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp ...@@ -262,4 +308,12 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
this.removeById(targetId); this.removeById(targetId);
return "合并成功"; return "合并成功";
} }
@Override
public String addTag(Long id, Long tagId) {
RStoreTag storeTag = new RStoreTag();
storeTag.setStoreId(id);
storeTag.setTagId(tagId);
return storeTagService.save(storeTag) ? "添加成功" : "添加失败";
}
} }
package vion.service.impl;
import com.github.yulichang.base.MPJBaseServiceImpl;
import org.springframework.stereotype.Service;
import vion.mapper.TagMapper;
import vion.model.Tag;
import vion.service.ITagService;
/**
* @author HlQ
* @date 2024/1/30
*/
@Service
public class TagServiceImpl extends MPJBaseServiceImpl<TagMapper, Tag> implements ITagService {
}
...@@ -283,6 +283,8 @@ public class DingMod { ...@@ -283,6 +283,8 @@ public class DingMod {
res.sendRedirect("https://yunwei.vionyun.com:8443/wap/workflow-assign?token=" + token + "&id=" + dto.getTaskTempId()); res.sendRedirect("https://yunwei.vionyun.com:8443/wap/workflow-assign?token=" + token + "&id=" + dto.getTaskTempId());
} else if (ObjUtil.isNotEmpty(dto.getUserId())) { } else if (ObjUtil.isNotEmpty(dto.getUserId())) {
res.sendRedirect("https://yunwei.vionyun.com:8443/wap/workflow-list?token=" + token + "&activeUser=" + dto.getUserId()); res.sendRedirect("https://yunwei.vionyun.com:8443/wap/workflow-list?token=" + token + "&activeUser=" + dto.getUserId());
} else if (ObjUtil.isNotEmpty(dto.getDeliveryId())) {
res.sendRedirect("https://yunwei.vionyun.com:8443/wap/delivery-invoice?token=" + token + "&id=" + dto.getDeliveryId());
} }
} catch (IOException e) { } catch (IOException e) {
log.error("钉钉回调接口重定向失败!", e); log.error("钉钉回调接口重定向失败!", e);
......
...@@ -222,7 +222,7 @@ public class PointInfoVO { ...@@ -222,7 +222,7 @@ public class PointInfoVO {
/** /**
* 备注 * 备注
*/ */
private String remake; private String remark;
/** /**
* 施工方 * 施工方
......
...@@ -28,6 +28,16 @@ public class RepairRecVO { ...@@ -28,6 +28,16 @@ public class RepairRecVO {
private Long storeId; private Long storeId;
/** /**
* 项目名称
*/
private String storeName;
/**
* 维保状态
*/
private String maintainStatus;
/**
* 合同id * 合同id
*/ */
private Long contractId; private Long contractId;
...@@ -58,6 +68,17 @@ public class RepairRecVO { ...@@ -58,6 +68,17 @@ public class RepairRecVO {
private String phone; private String phone;
/** /**
* 快递单号(用户填写的,他/她寄出去的设备的快递单号)
*/
private String userTrackingNumber;
/**
* 是否借用备件 0:否 1:是
*/
private Integer borrowToggle;
/**
* 设备数量 * 设备数量
*/ */
private Integer deviceNum; private Integer deviceNum;
...@@ -93,6 +114,11 @@ public class RepairRecVO { ...@@ -93,6 +114,11 @@ public class RepairRecVO {
*/ */
private String trackingNumber; private String trackingNumber;
/*
* 状态 1:运输中 2:维修中 3:已发货
*/
private Integer status;
private String uuid; private String uuid;
/** /**
......
...@@ -103,6 +103,16 @@ public class SparePartVO { ...@@ -103,6 +103,16 @@ public class SparePartVO {
private String trackingNumber; private String trackingNumber;
/** /**
* 发货状态 0:未发货 1:已发货
*/
private Integer shipStatus;
/**
* 归还状态 0:未归还 1:已归还
*/
private Integer returnStatus;
/**
* 备注 * 备注
*/ */
private String remark; private String remark;
......
...@@ -10,49 +10,85 @@ import java.util.List; ...@@ -10,49 +10,85 @@ import java.util.List;
@Data @Data
public class StoreVO { public class StoreVO {
private Long id; private Long id;
/** 门店名称 */ /**
* 门店名称
*/
private String name; private String name;
/** 销售人 */ /**
* 销售人
*/
private Integer salesperson; private Integer salesperson;
/** 客户姓名 */ /**
* 客户姓名
*/
private String customerName; private String customerName;
/** 实施类型:0纯供货、1供货+安装、3续保、4维修 */ /**
* 实施类型:0纯供货、1供货+安装、3续保、4维修
*/
private Integer implementType; private Integer implementType;
/** 项目状态:0待确认、1进行中、2已完成、3挂起 */ /**
* 项目状态:0待确认、1进行中、2已完成、3挂起
*/
private Integer projectState; private Integer projectState;
/** 联系人(多个联系人逗号隔开) */ /**
* 联系人(多个联系人逗号隔开)
*/
private String contacts; private String contacts;
/** 创建者 */ /**
* 创建者
*/
private Integer createUser; private Integer createUser;
/** 修改者 */ /**
* 修改者
*/
private Integer modifyUser; private Integer modifyUser;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime; private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date modifyTime; private Date modifyTime;
/** 备注 */ /**
* 备注
*/
private String remark; private String remark;
/** 项目阶段 */ /**
* 项目阶段
*/
private Integer projectStage; private Integer projectStage;
/** 集团id */ /**
* 集团id
*/
private Long accountId; private Long accountId;
private String accountName; private String accountName;
private Long fileNum; private Long fileNum;
/** 维保状态(在保、脱保、--) */ /**
* 维保状态(在保、脱保、--)
*/
private String maintainStatus; private String maintainStatus;
/** 产品线属性 */ /**
* 产品线属性
*/
private Integer productLine; private Integer productLine;
/** 是否重点项目 0:不是 1:是 */ /**
* 是否重点项目 0:不是 1:是
*/
private Integer isImportant; private Integer isImportant;
/** 任务详情 */ /**
* 任务详情
*/
private String taskDetail; private String taskDetail;
/** 预计完成日期 */ /**
* 预计完成日期
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date finishDate; private Date finishDate;
/** 完成百分比 */ /**
* 完成百分比
*/
private Double percentage; private Double percentage;
/** 当前卡点 */ /**
* 当前卡点
*/
private String stuckPoint; private String stuckPoint;
private List<String> userNameList; private List<String> userNameList;
...@@ -60,6 +96,7 @@ public class StoreVO { ...@@ -60,6 +96,7 @@ public class StoreVO {
private List<StoreLog> storeLog; private List<StoreLog> storeLog;
private List<ContractVO> contractVOList;
/** /**
* 门店的合同信息 * 门店的合同信息
*/ */
...@@ -76,4 +113,9 @@ public class StoreVO { ...@@ -76,4 +113,9 @@ public class StoreVO {
private Integer taskCount; private Integer taskCount;
private ContractVO mainContract; private ContractVO mainContract;
/**
* 标签
*/
private List<TagVO> tagList;
} }
package vion.vo;
import lombok.Getter;
import lombok.Setter;
/**
* @author HlQ
* @date 2023/11/28
*/
@Getter
@Setter
public class TagVO {
private Long id;
private Long storeId;
private String name;
private String remark;
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!