Commit fd62bb0e by HlQ

[add]

1.添加项目合并功能
2.添加任务批量导入以及导出功能
1 parent f21881fd
......@@ -43,7 +43,7 @@
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
<version>5.8.24</version>
</dependency>
<dependency>
<groupId>io.github.linpeilie</groupId>
......@@ -80,6 +80,11 @@
<version>1.37.0</version>
</dependency>
<dependency>
<groupId>com.github.liaochong</groupId>
<artifactId>myexcel</artifactId>
<version>4.3.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>4.2.0</version>
......
package vion.config;
import cn.hutool.core.lang.Opt;
import com.github.liaochong.myexcel.core.converter.CustomWriteContext;
import com.github.liaochong.myexcel.core.converter.CustomWriteConverter;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import vion.model.User;
/**
* @author HlQ
* @date 2024/1/3
*/
@Component
@RequiredArgsConstructor
public class UserNameConverter implements CustomWriteConverter<Long, String> {
private final RedisTemplate redisTemplate;
@Override
public String convert(Long originalData, CustomWriteContext customWriteContext) {
return Opt.ofNullable(((User) redisTemplate.opsForValue().get("dingtalk:user:" + originalData)))
.map(User::getUsername)
.orElse("未知");
}
}
......@@ -2,7 +2,9 @@ package vion.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
......@@ -129,4 +131,11 @@ public class StoreController {
return storeService.storeScreen();
}
@PostMapping("/store/merge")
@SaCheckPermission(value = "store:merge", orRole = "admin")
public String mergeStore(@RequestBody StoreDTO dto) {
Assert.isFalse(ArrayUtil.hasNull(dto.getSourceId(), dto.getTargetId()), "合并项目id不能为空");
return storeService.mergeStore(dto);
}
}
package vion.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.liaochong.myexcel.core.DefaultExcelBuilder;
import com.github.liaochong.myexcel.utils.AttachmentExportUtil;
import com.github.liaochong.myexcel.utils.WatermarkUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.bind.annotation.*;
import vion.config.UserNameConverter;
import vion.dto.TaskDTO;
import vion.model.FaultLog;
import vion.service.IFaultLogService;
import vion.service.ITaskService;
import vion.vo.TaskVO;
import vion.vo.UserVO;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
......@@ -22,6 +32,7 @@ public class TaskController {
private final ITaskService taskService;
private final IFaultLogService faultLogService;
private final UserNameConverter userNameConverter;
@GetMapping("/tasks")
@SaCheckPermission(value = "task:list", orRole = "admin")
......@@ -62,4 +73,25 @@ public class TaskController {
}
return faultLogList;
}
@PostMapping("/task/batchIns")
@SaCheckPermission(value = "task:batchIns", orRole = "admin")
// todo 未加权限
public String batchIns(@RequestBody List<TaskDTO> data) {
return taskService.batchIns(data);
}
@GetMapping("/task/export")
@SaCheckPermission(value = "task:export", orRole = "admin")
// todo 未加权限
public void defaultBuild(TaskDTO data, HttpServletResponse response) {
UserVO user = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
data.setPageSize(9999);
Page<TaskVO> voPage = taskService.getTaskList(data);
Workbook workbook = DefaultExcelBuilder.of(TaskVO.class)
.binding(userNameConverter)
.build(voPage.getRecords());
WatermarkUtil.addWatermark(workbook, user.getUsername() + "-" + user.getPhone());
AttachmentExportUtil.export(workbook, StrUtil.format("任务列表_{}", DateUtil.formatDateTime(new Date())), response);
}
}
......@@ -57,4 +57,7 @@ public class StoreDTO extends BaseDTO {
private Double percentage;
/** 当前卡点 */
private String stuckPoint;
private Long sourceId;
private Long targetId;
}
......@@ -19,4 +19,6 @@ public interface IStoreService extends MPJBaseService<Store> {
List<StoreVO> storeScreen();
String mergeStore(StoreDTO dto);
}
......@@ -6,6 +6,8 @@ import vion.dto.TaskDTO;
import vion.model.Task;
import vion.vo.TaskVO;
import java.util.List;
public interface ITaskService extends MPJBaseService<Task> {
Page<TaskVO> getTaskList(TaskDTO data);
......@@ -13,4 +15,6 @@ public interface ITaskService extends MPJBaseService<Task> {
TaskVO getTaskById(Long taskId);
Long circTask(TaskDTO data, String token);
String batchIns(List<TaskDTO> data);
}
......@@ -62,6 +62,7 @@ public class ConstructionTeamServiceImpl extends MPJBaseServiceImpl<Construction
.selectAll(RContractTeam.class)
.selectAs(Contract::getContractNo, RContractTeamVO::getContractNo)
.selectAs(Contract::getName, RContractTeamVO::getContractName)
.selectAs(Contract::getStatus, RContractTeamVO::getContractStatus)
.selectAs(ConstructionTeam::getName, RContractTeamVO::getTeamName)
.leftJoin(Contract.class, Contract::getId, RContractTeam::getContractId)
.leftJoin(ConstructionTeam.class, ConstructionTeam::getId, RContractTeam::getCtId)
......
......@@ -9,6 +9,7 @@ import cn.hutool.core.lang.Opt;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
......@@ -19,6 +20,7 @@ import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import vion.dto.StatusDTO;
import vion.dto.StoreDTO;
......@@ -44,6 +46,8 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
private final IRContractStoreService contractStoreService;
private final IContractService contractService;
private final IFileService fileService;
private final IFaultLogService faultLogService;
private final IFormService formService;
private final Converter converter;
// 引入 taskService 会循环依赖
private final TaskMapper taskMapper;
......@@ -125,9 +129,9 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
for (MultipartFile infile : tmpFiles) {
//上传url地址
String orgName = infile.getOriginalFilename();
String fileName = orgName.substring(0, orgName.lastIndexOf("."));
String fileExt = orgName.substring(orgName.lastIndexOf("."));
String filename = fileName + "_" + DateUtil.format(new Date(), "yyyyMMdd_HHmmss") + fileExt;
String mainName = FileUtil.mainName(orgName);
String fileExt = FileUtil.extName(orgName);
String filename = StrUtil.format("{}_{}.{}", mainName, DateUtil.format(new Date(), "yyyyMMdd_HHmmss"), fileExt);;
String path = fileUrl + FileUtil.FILE_SEPARATOR + statusDTO.getStoreId() + FileUtil.FILE_SEPARATOR + statusDTO.getSourceId() + FileUtil.FILE_SEPARATOR + filename;
File file = FileUtil.touch(path);
try {
......@@ -215,7 +219,7 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
@Override
public List<StoreVO> storeScreen() {
MPJLambdaWrapper<Store> wrapper = new MPJLambdaWrapper<Store>()
.select(Store::getTaskDetail, Store::getFinishDate, Store::getPercentage, Store::getStuckPoint, Store::getIsImportant)
.select(Store::getName, Store::getTaskDetail, Store::getFinishDate, Store::getPercentage, Store::getStuckPoint, Store::getIsImportant)
.selectCollection(User.class, StoreVO::getUserNameList, map -> map.result(User::getUsername))
.leftJoin(RStoreUser.class, on -> on.eq(RStoreUser::getStoreId, Store::getId).eq(RStoreUser::getIsMain, 1))
.leftJoin(User.class, User::getId, RStoreUser::getUserId)
......@@ -223,4 +227,35 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
.orderByAsc(Store::getFinishDate);
return this.selectJoinList(StoreVO.class, wrapper);
}
@Override
@Transactional(rollbackFor = Exception.class)
public String mergeStore(StoreDTO dto) {
// targetId 合并到 sourceId
Long sourceId = dto.getSourceId();
Long targetId = dto.getTargetId();
// 项目关联合同合并
Opt.ofEmptyAble(contractStoreService.lambdaQuery().select(RContractStore::getContractId).eq(RContractStore::getStoreId, targetId).list())
.ifPresent(l -> {
List<RContractStore> existList = contractStoreService.lambdaQuery().select(RContractStore::getContractId).eq(RContractStore::getStoreId, sourceId).list();
List<RContractStore> insList = l.stream().filter(v -> !existList.contains(v)).map(v -> {
RContractStore contractStore = new RContractStore();
contractStore.setContractId(v.getContractId());
contractStore.setStoreId(sourceId);
return contractStore;
}).collect(Collectors.toList());
contractStoreService.saveBatch(insList);
contractStoreService.lambdaUpdate().eq(RContractStore::getStoreId, targetId).remove();
});
// 工单相关合并
taskMapper.update(new Task(), Wrappers.lambdaUpdate(Task.class).set(Task::getStoreId, sourceId).eq(Task::getStoreId, targetId));
fileService.lambdaUpdate().set(FileInfo::getStoreId, sourceId).eq(FileInfo::getStoreId, targetId).eq(FileInfo::getSourceType, 3).update();
faultLogService.lambdaUpdate().set(FaultLog::getStoreId, sourceId).eq(FaultLog::getStoreId, targetId).update();
formService.lambdaUpdate().set(Form::getStoreId, sourceId).eq(Form::getStoreId, targetId).update(new Form());
// 删除 targetId 对应的项目
this.removeById(targetId);
return "合并成功";
}
}
......@@ -7,6 +7,7 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
......@@ -95,7 +96,7 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
.leftJoin(Store.class, Store::getId, Task::getStoreId)
.leftJoin(Account.class, Account::getId, Task::getAccountId)
.leftJoin(ServiceOrder.class, ServiceOrder::getTaskId, Task::getId)
.between(data.getStartdate() != null && data.getEnddate() != null, Task::getRepairTime, data.getStartdate(), data.getEnddate())
.between(ArrayUtil.isAllNotNull(data.getStartdate(), data.getEnddate()), Task::getRepairTime, data.getStartdate(), data.getEnddate())
.lt(data.getCurDate() != null, Task::getExpDate, data.getCurDate());
// todo 优化
if (taskIdSet.size() == 1 && CollUtil.get(taskIdSet, 0).equals(-99L)) {
......@@ -257,6 +258,11 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
return task.getId();
}
@Override
public String batchIns(List<TaskDTO> data) {
return this.saveBatch(converter.convert(data, Task.class)) ? "成功" : "失败";
}
JSONObject buildMsg(String userid, String storeName, Task task) {
List<Dictionary> orderStatus = dictionaryService.list(Wrappers.<Dictionary>lambdaQuery().eq(Dictionary::getType, "order_status"));
Map<Integer, String> orderStatusMap = orderStatus.stream().collect(Collectors.toMap(Dictionary::getKey, Dictionary::getValue));
......
package vion.third;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
......@@ -22,6 +20,7 @@ import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import vion.dto.DingDTO;
import vion.model.*;
......@@ -35,6 +34,7 @@ import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
......@@ -58,7 +58,7 @@ public class DingMod {
private final IRRoleResourceService roleResourceService;
private final IDeptService deptService;
private final Converter converter;
private final TimedCache<String, String> timedCache = CacheUtil.newTimedCache(7000 * 1000);
private final RedisTemplate redisTemplate;
/**
* 获取钉钉token
......@@ -66,14 +66,14 @@ public class DingMod {
* @return java.lang.String
*/
public String getToken() {
if (timedCache.containsKey("accessToken")) {
return timedCache.get("accessToken", false);
if (redisTemplate.hasKey("accessToken")) {
redisTemplate.opsForValue().get("dingtalk:accessToken");
}
String res = HttpUtil.get("https://oapi.dingtalk.com/gettoken?appkey=" + appKey + "&appsecret=" + appSecret);
JSONObject jsonObj = JSONUtil.parseObj(res);
if (jsonObj.containsKey("access_token")) {
String accessToken = jsonObj.getStr("access_token");
timedCache.put("accessToken", accessToken);
redisTemplate.opsForValue().set("dingtalk:accessToken", accessToken, 7000, TimeUnit.SECONDS);
return accessToken;
} else {
return "";
......@@ -147,6 +147,8 @@ public class DingMod {
}
}
userService.saveOrUpdate(user, Wrappers.<User>lambdaUpdate().eq(User::getUserid, userid));
User one = userService.lambdaQuery().eq(User::getUserid, userid).one();
redisTemplate.opsForValue().set("dingtalk:user:" + one.getId(), user);
}
}
});
......
......@@ -76,4 +76,6 @@ public class RContractTeamVO {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime;
private Integer contractStatus;
}
\ No newline at end of file
package vion.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.github.liaochong.myexcel.core.annotation.ExcelColumn;
import com.github.liaochong.myexcel.core.annotation.ExcelModel;
import lombok.Data;
import vion.config.UserNameConverter;
import vion.model.FileInfo;
import vion.model.ServiceOrder;
......@@ -9,26 +12,34 @@ import java.util.Date;
import java.util.List;
@Data
@ExcelModel(sheetName = "任务", includeAllField = false)
public class TaskVO {
private Long id;
/** 门店id */
private Long storeId;
/** 门店名称 */
@ExcelColumn(order = 0, title = "项目名称")
private String storeName;
/** 预处理工单id */
private Long taskTempId;
/** 报修日期 */
@ExcelColumn(order = 5, title = "提交时间", format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date repairTime;
/** 故障类型 */
@ExcelColumn(order = 2, title = "故障类型", mapping = "1:相机问题,2:平台功能,3:系统数据,4:需求建议,5:其他问题")
private Integer faultType;
/** 故障说明 */
@ExcelColumn(order = 3, title = "故障说明")
private String faultDescription;
/** 报修人 */
@ExcelColumn(order = 1, title = "客户姓名")
private String repairPeople;
/** 报修人联系方式 */
@ExcelColumn(order = 4, title = "联系方式")
private String repairPhone;
/** 状态:0待确认1进行中2已完成3挂起 */
@ExcelColumn(order = 6, title = "状态", mapping = "0:待确认,1:进行中,2:进行中,3:已完成,4:挂起,5:已关闭")
private Integer status;
/** 解决日期 */
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
......@@ -42,8 +53,10 @@ public class TaskVO {
/** 创建者 */
private Long createUser;
/** 当前处理人 */
@ExcelColumn(order = 7, title = "当前指派", writeConverter = UserNameConverter.class)
private Long activeUser;
/** 截止日期 */
@ExcelColumn(order = 8, title = "截止日期", format = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date expDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!