Commit f7cba6fe by HlQ

[add]

1.收货记录新增钉钉消息推送,添加详情页推送
2.设备返修、备件申请字段添加
3.新增标签管理以及项目绑定标签
[fix]
合同列表查询数据权限控制修改逻辑
1 parent 21739ac2
......@@ -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;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ArrayUtil;
......@@ -94,7 +95,7 @@ public class StoreController {
@SaCheckPermission(value = "store:calMaintainStatus", orRole = "admin")
// todo 权限未加,前端未使用到该接口
public String manualCalMaintainStatus() {
return storeService.calMaintainStatus();
return storeService.calMaintainStatus(ListUtil.empty());
}
@GetMapping("/store/user/{storeId}")
......@@ -152,4 +153,10 @@ public class StoreController {
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;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ObjUtil;
......@@ -34,6 +35,7 @@ public class ContractRunner {
private final IDictionaryService dictionaryService;
private final IContractPaymentService contractPaymentService;
private final IRContractUserService contractUserService;
private final IRContractStoreService contractStoreService;
private final IStoreService storeService;
private final IPaymentService paymentService;
private final RedisTemplate redisTemplate;
......@@ -114,13 +116,22 @@ public class ContractRunner {
return;
}
List<Long> updContractIdList = new ArrayList<>();
insOrUpdContractList.forEach(v -> {
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);
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);
insOrUpdContractList.forEach(v -> {
// 合同状态不为空,代表此条记录为新增,需要同步销售人信息到 r_contract_user 表中
......@@ -132,6 +143,7 @@ public class ContractRunner {
.orElse(null);
contractUser.setUserId(userId);
contractUser.setUsername(v.getSaleName());
contractUser.setEnterDate(v.getSignDate());
contractUser.setContractId(v.getId());
contractUser.setContractNo(v.getContractNo());
contractUserService.save(contractUser);
......@@ -239,7 +251,7 @@ public class ContractRunner {
@Scheduled(cron = "0 0 1 * * ?")
public void calMaintainStatus() {
log.info("【开始】计算门店维保状态");
storeService.calMaintainStatus();
storeService.calMaintainStatus(ListUtil.empty());
log.info("【结束】计算门店维保状态");
}
......
......@@ -10,15 +10,29 @@ import lombok.Setter;
@Getter
@Setter
public class DingDTO {
/** 微信拼接的两个 code 参数 */
/**
* 微信拼接的两个 code 参数
*/
private String authCode;
private String code;
/** 项目id */
/**
* 项目id
*/
private Long storeId;
/** 工单id */
/**
* 工单id
*/
private Long taskId;
/** 预工单id */
/**
* 预工单id
*/
private Long taskTempId;
/** 用户id */
/**
* 用户id
*/
private Long userId;
/**
* 发货记录id
*/
private Long deliveryId;
}
......@@ -181,7 +181,7 @@ public class PointInfoDTO extends BaseDTO {
/**
* 备注
*/
private String remake;
private String remark;
/**
* uuid
......
......@@ -53,6 +53,16 @@ public class RepairRecDTO extends BaseDTO {
private String phone;
/**
* 快递单号(用户填写的,他/她寄出去的设备的快递单号)
*/
private String userTrackingNumber;
/**
* 是否借用备件 0:否 1:是
*/
private Integer borrowToggle;
/**
* 设备数量
*/
private Integer deviceNum;
......@@ -88,6 +98,11 @@ public class RepairRecDTO extends BaseDTO {
*/
private String trackingNumber;
/*
* 状态 1:运输中 2:维修中 3:已发货
*/
private Integer status;
private String uuid;
/**
......
......@@ -89,6 +89,16 @@ public class SparePartDTO extends BaseDTO {
private String trackingNumber;
/**
* 发货状态 0:未发货 1:已发货
*/
private Integer shipStatus;
/**
* 归还状态 0:未归还 1:已归还
*/
private Integer returnStatus;
/**
* 备注
*/
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
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
......@@ -149,7 +149,7 @@ public class Contract {
private Integer warrantyPeriod;
/**
* 终验日期
* 终验日期,目前取值为合同阶段为系统初验或者终验的 nodeDate
*/
@TableField(value = "final_date")
private Date finalDate;
......
......@@ -218,8 +218,8 @@ public class PointInfo {
/**
* 备注
*/
@TableField(value = "remake")
private String remake;
@TableField(value = "remark")
private String remark;
/**
* 施工方
......
......@@ -57,6 +57,24 @@ public class RRepairDevice extends BaseDTO {
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
*/
@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
......@@ -50,13 +50,13 @@ public class RepairRec {
/**
* 项目名称(用户填写的)
*/
@TableField(value = "project_name")
@TableField(value = "project_name", condition = SqlCondition.LIKE)
private String projectName;
/**
* 联系人
*/
@TableField(value = "contact")
@TableField(value = "contact", condition = SqlCondition.LIKE)
private String contact;
/**
......@@ -66,6 +66,19 @@ public class RepairRec {
private String phone;
/**
* 快递单号(用户填写的,他/她寄出去的设备的快递单号)
*/
@TableField(value = "user_tracking_number")
private String userTrackingNumber;
/**
* 是否借用备件 0:否 1:是
*/
@TableField(value = "borrow_toggle")
private Integer borrowToggle;
/**
* 设备数量
*/
@TableField(value = "device_num")
......@@ -107,6 +120,12 @@ public class RepairRec {
@TableField(value = "tracking_number")
private String trackingNumber;
/*
* 状态 1:运输中 2:维修中 3:已发货
*/
@TableField(value = "status")
private Integer status;
@TableField(value = "uuid")
private String uuid;
......
......@@ -50,13 +50,13 @@ public class SparePart {
/**
* 项目名称(用户填写的)
*/
@TableField(value = "project_name")
@TableField(value = "project_name", condition = SqlCondition.LIKE)
private String projectName;
/**
* 联系人
*/
@TableField(value = "contact")
@TableField(value = "contact", condition = SqlCondition.LIKE)
private String contact;
/**
......@@ -108,6 +108,18 @@ public class SparePart {
private String trackingNumber;
/**
* 发货状态 0:未发货 1:已发货
*/
@TableField(value = "ship_status")
private Integer shipStatus;
/**
* 归还状态 0:未归还 1:已归还
*/
@TableField(value = "return_status")
private Integer returnStatus;
/**
* 备注
*/
@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
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> {
String updateStoreStage(StatusDTO statusDTO, String token);
String calMaintainStatus();
String calMaintainStatus(List<Long> storeIdList);
List<StoreVO> storeScreen();
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
.map(l -> l.stream().map(RoleVO::getCode).collect(Collectors.toSet()))
.orElse(CollUtil.newHashSet());
Assert.notEmpty(roleCodeList, "当前用户角色不详,请联系管理员");
String curName;
if (!roleCodeList.contains("admin") && !roleCodeList.contains("shangwu") && !roleCodeList.contains("caiwu")) {
String curName = "";
boolean isPerm = !roleCodeList.contains("admin") && !roleCodeList.contains("shangwu") && !roleCodeList.contains("caiwu");
if (isPerm) {
// 不是以上三个角色,只能访问自己相关的合同
curName = userVO.getUsername();
} else {
curName = "";
}
// 根据查询条件的销售人查询关联的合同
......@@ -450,10 +449,10 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
.map(name -> this.listObjs(Wrappers.<Contract>lambdaQuery()
.select(Contract::getId).eq(Contract::getSaleName, name), o -> Long.valueOf(o.toString())))
.orElse(new ArrayList<>());
Collection<Long> queryContractUserIdList = CollUtil.addAll(contractUserIdList1, contractUserIdList2);
Collection<Long> curContractUserIdList = CollUtil.addAll(contractUserIdList3, contractUserIdList4);
Collection<Long> queryContractUserIdList = CollUtil.addAllIfNotContains(contractUserIdList1, contractUserIdList2);
Collection<Long> curContractUserIdList = CollUtil.addAllIfNotContains(contractUserIdList3, contractUserIdList4);
Set<Long> allContractUserIdList;
if (CollUtil.isNotEmpty(queryContractUserIdList) && CollUtil.isNotEmpty(curContractUserIdList)) {
if (StrUtil.isNotBlank(curName) && StrUtil.isNotBlank(dto.getSaleName())) {
// 当前用户和查询条件的销售人都存在,取交集
allContractUserIdList = CollUtil.intersectionDistinct(queryContractUserIdList, curContractUserIdList);
} else {
......@@ -461,8 +460,9 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
}
Set<Long> finalIdSet;
if (CollUtil.isNotEmpty(lineContractIdList) && CollUtil.isNotEmpty(allContractUserIdList)) {
// 产品线关联的合同和销售人或当前人关联的合同都存在,取交集
if (isPerm) {
// 不是以上三个角色,只能访问自己相关的合同或自己产品线相关的合同
if (ObjUtil.isNotNull(dto.getProductLine())) {
finalIdSet = CollUtil.intersectionDistinct(lineContractIdList, allContractUserIdList);
} else {
finalIdSet = CollUtil.unionDistinct(lineContractIdList, allContractUserIdList);
......@@ -471,12 +471,22 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
// 根据条件筛选要查询的合同为空,集合补元素 -1,防止数据库查询出错
finalIdSet.add(-1L);
}
} else {
if (StrUtil.isNotBlank(dto.getSaleName()) && ObjUtil.isNotNull(dto.getProductLine())) {
finalIdSet = CollUtil.intersectionDistinct(lineContractIdList, allContractUserIdList);
} else {
finalIdSet = CollUtil.unionDistinct(lineContractIdList, allContractUserIdList);
}
if ((StrUtil.isNotBlank(dto.getSaleName()) || ObjUtil.isNotNull(dto.getProductLine())) && CollUtil.isEmpty(finalIdSet)) {
finalIdSet.add(-1L);
}
}
// 前端传参中的 saleName 字段已单独处理,这里置空,不参与下一步的 converter.convert
dto.setSaleName(null);
MPJLambdaWrapper<Contract> wrapper = new MPJLambdaWrapper<>(converter.convert(dto, 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)
.between(ArrayUtil.isAllNotNull(dto.getSignDateStart(), dto.getSignDateEnd()), Contract::getSignDate, dto.getSignDateStart(), dto.getSignDateEnd())
.orderByDesc(Contract::getEntryTime);
......
......@@ -8,6 +8,7 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
......@@ -162,10 +163,15 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord
" \n #### 发货日期:{}" +
" \n #### 发送时间:{}",
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");
msg.set("markdown", content);
JSONArray jsonArray = new JSONArray();
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);
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
MPJLambdaWrapper<RepairRec> wrapper = new MPJLambdaWrapper<>(converter.convert(dto, RepairRec.class))
.selectAll(RepairRec.class)
.selectAs(Contract::getName, RepairRecVO::getContractName)
.selectAs(Store::getName, RepairRecVO::getStoreName)
.selectAs(Store::getMaintainStatus, RepairRecVO::getMaintainStatus)
.selectCollection(RRepairDevice.class, RepairRecVO::getRepairDeviceList)
.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))
.between(RepairRec::getCreateTime, dto.getCreateTimeStart(), dto.getCreateTimeEnd())
.orderByDesc(RepairRec::getCreateTime);
......
......@@ -30,6 +30,7 @@ import vion.model.*;
import vion.service.*;
import vion.vo.ContractVO;
import vion.vo.StoreVO;
import vion.vo.TagVO;
import vion.vo.UserVO;
import java.io.File;
......@@ -44,11 +45,14 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
private final IAccountService accountService;
private final IRContractStoreService contractStoreService;
private final IContractPaymentService contractPaymentService;
private final IContractService contractService;
private final IFileService fileService;
private final IFaultLogService faultLogService;
private final IFormService formService;
private final IInspectService inspectService;
private final ITagService tagService;
private final IRStoreTagService storeTagService;
private final Converter converter;
// 引入 taskService 会循环依赖
private final TaskMapper taskMapper;
......@@ -69,17 +73,32 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
List<Long> storeIdList = Opt.ofEmptyAble(storeList.getRecords())
.map(recs -> recs.stream().map(Store::getId).collect(Collectors.toList()))
.orElse(ListUtil.empty());
// storeId -> 项目绑定的合同的 list
Map<Long, List<RContractStore>> storeIdMap = Opt.ofEmptyAble(storeIdList)
.map(l -> contractStoreService.lambdaQuery().in(RContractStore::getStoreId, l).list())
.map(contractStoreList -> contractStoreList.stream().collect(Collectors.groupingBy(RContractStore::getStoreId)))
.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()))
.filter(CollUtil::isNotEmpty)
.map(contractStoreList -> {
List<Contract> contractList = contractService.lambdaQuery().in(Contract::getId, contractStoreList.stream().map(RContractStore::getContractId).collect(Collectors.toList())).list();
return contractList.stream().collect(Collectors.toMap(Contract::getId, Function.identity()));
})
.map(contractStoreList -> contractStoreList.stream().map(RContractStore::getContractId).collect(Collectors.toList())).
orElse(ListUtil.empty());
// 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());
Map<Long, List<Long>> store2TaskIdMap = Opt.ofEmptyAble(storeIdList)
......@@ -94,6 +113,18 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
.map(serviceOrderList -> serviceOrderList.stream().collect(Collectors.groupingBy(ServiceOrder::getTaskId)))
.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<>();
storeList.getRecords().forEach(item -> {
......@@ -102,10 +133,23 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
storeVO.setFileNum(store2CntMap.getOrDefault(item.getId(), 0L));
Long storeId = item.getId();
// 关联合同
List<RContractStore> contractStores = storeIdMap.get(storeId);
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);
// 关联合同验收时间
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.setTaskCount(store2TaskIdMap.getOrDefault(storeId, ListUtil.empty()).size());
// 补充服务单
......@@ -115,6 +159,8 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
.collect(Collectors.toList());
storeVO.setServiceOrderCount(serviceOrders.size());
}
// 关联标签
storeVO.setTagList(storeId2TagMap.getOrDefault(storeId, ListUtil.empty()));
storeVOList.add(storeVO);
});
return Page.<StoreVO>of(data.getPageNum(), data.getPageSize(), storeList.getTotal()).setRecords(storeVOList);
......@@ -159,8 +205,8 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
}
@Override
public String calMaintainStatus() {
List<Store> storeList = this.list();
public String calMaintainStatus(List<Long> storeIdList) {
List<Store> storeList = this.lambdaQuery().in(CollUtil.isNotEmpty(storeIdList), Store::getId, storeIdList).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()))))
.orElse(MapUtil.empty());
......@@ -262,4 +308,12 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
this.removeById(targetId);
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 {
res.sendRedirect("https://yunwei.vionyun.com:8443/wap/workflow-assign?token=" + token + "&id=" + dto.getTaskTempId());
} else if (ObjUtil.isNotEmpty(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) {
log.error("钉钉回调接口重定向失败!", e);
......
......@@ -222,7 +222,7 @@ public class PointInfoVO {
/**
* 备注
*/
private String remake;
private String remark;
/**
* 施工方
......
......@@ -28,6 +28,16 @@ public class RepairRecVO {
private Long storeId;
/**
* 项目名称
*/
private String storeName;
/**
* 维保状态
*/
private String maintainStatus;
/**
* 合同id
*/
private Long contractId;
......@@ -58,6 +68,17 @@ public class RepairRecVO {
private String phone;
/**
* 快递单号(用户填写的,他/她寄出去的设备的快递单号)
*/
private String userTrackingNumber;
/**
* 是否借用备件 0:否 1:是
*/
private Integer borrowToggle;
/**
* 设备数量
*/
private Integer deviceNum;
......@@ -93,6 +114,11 @@ public class RepairRecVO {
*/
private String trackingNumber;
/*
* 状态 1:运输中 2:维修中 3:已发货
*/
private Integer status;
private String uuid;
/**
......
......@@ -103,6 +103,16 @@ public class SparePartVO {
private String trackingNumber;
/**
* 发货状态 0:未发货 1:已发货
*/
private Integer shipStatus;
/**
* 归还状态 0:未归还 1:已归还
*/
private Integer returnStatus;
/**
* 备注
*/
private String remark;
......
......@@ -10,49 +10,85 @@ import java.util.List;
@Data
public class StoreVO {
private Long id;
/** 门店名称 */
/**
* 门店名称
*/
private String name;
/** 销售人 */
/**
* 销售人
*/
private Integer salesperson;
/** 客户姓名 */
/**
* 客户姓名
*/
private String customerName;
/** 实施类型:0纯供货、1供货+安装、3续保、4维修 */
/**
* 实施类型:0纯供货、1供货+安装、3续保、4维修
*/
private Integer implementType;
/** 项目状态:0待确认、1进行中、2已完成、3挂起 */
/**
* 项目状态:0待确认、1进行中、2已完成、3挂起
*/
private Integer projectState;
/** 联系人(多个联系人逗号隔开) */
/**
* 联系人(多个联系人逗号隔开)
*/
private String contacts;
/** 创建者 */
/**
* 创建者
*/
private Integer createUser;
/** 修改者 */
/**
* 修改者
*/
private Integer modifyUser;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date modifyTime;
/** 备注 */
/**
* 备注
*/
private String remark;
/** 项目阶段 */
/**
* 项目阶段
*/
private Integer projectStage;
/** 集团id */
/**
* 集团id
*/
private Long accountId;
private String accountName;
private Long fileNum;
/** 维保状态(在保、脱保、--) */
/**
* 维保状态(在保、脱保、--)
*/
private String maintainStatus;
/** 产品线属性 */
/**
* 产品线属性
*/
private Integer productLine;
/** 是否重点项目 0:不是 1:是 */
/**
* 是否重点项目 0:不是 1:是
*/
private Integer isImportant;
/** 任务详情 */
/**
* 任务详情
*/
private String taskDetail;
/** 预计完成日期 */
/**
* 预计完成日期
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date finishDate;
/** 完成百分比 */
/**
* 完成百分比
*/
private Double percentage;
/** 当前卡点 */
/**
* 当前卡点
*/
private String stuckPoint;
private List<String> userNameList;
......@@ -60,6 +96,7 @@ public class StoreVO {
private List<StoreLog> storeLog;
private List<ContractVO> contractVOList;
/**
* 门店的合同信息
*/
......@@ -76,4 +113,9 @@ public class StoreVO {
private Integer taskCount;
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!