Commit 8cb74aa8 by HlQ

[add]

1.项目列表支持自定义排序并添加立项日期字段
2.统计进行中项目的项目阶段的数量
3.工单人员分析添加指定人员查询条件
4.只有客户提交的工单才会钉钉提醒销售
1 parent 60c34288
......@@ -2,28 +2,26 @@ package vion.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import org.dromara.hutool.core.bean.BeanUtil;
import org.dromara.hutool.core.date.DateUtil;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.text.StrUtil;
import com.github.liaochong.myexcel.core.DefaultStreamExcelBuilder;
import com.github.liaochong.myexcel.core.watermark.Watermark;
import vion.utils.excel.AttachmentExportUtil;
import com.github.liaochong.myexcel.utils.WatermarkUtil;
import io.github.linpeilie.Converter;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.Workbook;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.date.DateUtil;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.text.StrUtil;
import org.springframework.web.bind.annotation.*;
import vion.dto.SparePartDTO;
import vion.model.RRepairDevice;
import vion.service.ISparePartService;
import vion.utils.excel.AttachmentExportUtil;
import vion.vo.SparePartVO;
import vion.vo.UserVO;
import jakarta.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
......@@ -36,7 +34,6 @@ import java.util.List;
public class SparePartController {
private final ISparePartService sparePartService;
private final Converter converter;
@PostMapping("/frontSubmit")
public Object frontSubmit(SparePartDTO dto) {
......@@ -79,16 +76,17 @@ public class SparePartController {
UserVO user = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
dto.setPageSize(30000);
List<SparePartVO> voPage = sparePartService.list(dto);
try (DefaultStreamExcelBuilder<SparePartVO> defaultStreamExcelBuilder = DefaultStreamExcelBuilder.of(SparePartVO.class).start()) {
List<SparePartVO> res = new ArrayList<>();
voPage.forEach(v -> v.getRepairDeviceList().forEach(r -> {
SparePartVO convert = new SparePartVO();
BeanUtil.copyProperties(v, convert);
convert.setRRepairDevice(r);
res.add(convert);
}));
defaultStreamExcelBuilder.append(res);
Workbook workbook = defaultStreamExcelBuilder.autoMerge().build();
try (DefaultStreamExcelBuilder<SparePartVO> defaultStreamExcelBuilder = DefaultStreamExcelBuilder.of(SparePartVO.class).autoMerge().start()) {
voPage.forEach(v -> {
var name = v.getRepairDeviceList().stream().map(RRepairDevice::getDeviceName).toList();
var no = v.getRepairDeviceList().stream().map(RRepairDevice::getDeviceNo).toList();
var rRepairDevice = new RRepairDevice();
rRepairDevice.setDeviceNameList(name);
rRepairDevice.setDeviceNoList(no);
v.setRRepairDevice(rRepairDevice);
});
defaultStreamExcelBuilder.append(voPage);
Workbook workbook = defaultStreamExcelBuilder.build();
// 水印添加指定字体,并在服务器上安装 SimSun 字体,解决中文字体变成方块的问题
Watermark watermark = new Watermark();
watermark.setText(user.getUsername() + "-" + user.getPhone());
......
......@@ -2,6 +2,7 @@ package vion.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
......@@ -40,8 +41,8 @@ public class StoreController {
@GetMapping("/stores")
@SaCheckPermission(value = "store:list", orRole = "admin")
public Page<StoreVO> getStoreList(StoreDTO data) {
return storeService.getStoreList(data);
public Page<StoreVO> getStoreList(StoreDTO data, @RequestBody(required = false) List<OrderItem> orderItemList) {
return storeService.getStoreList(data, orderItemList);
}
@GetMapping("/store")
......@@ -183,4 +184,10 @@ public class StoreController {
return storeService.stopCron(storeId);
}
@GetMapping("/store/statStage")
@SaCheckPermission(value = "store:statStage", orRole = "admin")
public Map<Integer, Long> statStage() {
return storeService.statState();
}
}
......@@ -143,8 +143,9 @@ public class TaskController {
@SaCheckPermission(value = "task:peopleAnal", orRole = "admin")
public List<Map<String, Object>> peopleAnalysis(@DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
@DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
Integer source) {
return taskService.peopleAnalysis(startDate, endDate, source);
Integer source,
Long userId) {
return taskService.peopleAnalysis(startDate, endDate, source, userId);
}
@GetMapping("/task/proAnal")
......
......@@ -40,6 +40,10 @@ public class StoreDTO extends BaseDTO {
private Date startdate;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date enddate;
/** 立项日期 */
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date estDate;
/** 主合同id */
private Long masterContract;
/** 维保状态 */
......
......@@ -5,10 +5,12 @@ import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.liaochong.myexcel.core.annotation.ExcelColumn;
import com.github.liaochong.myexcel.core.annotation.ExcelModel;
import com.github.liaochong.myexcel.core.annotation.MultiColumn;
import lombok.Data;
import vion.dto.BaseDTO;
import java.util.Date;
import java.util.List;
/**
* @author HlQ
......@@ -40,9 +42,13 @@ public class RRepairDevice extends BaseDTO {
* 设备名称
*/
@TableField(value = "device_name")
@ExcelColumn(order = 5, title = "设备名称")
private String deviceName;
@MultiColumn(classType = String.class)
@ExcelColumn(order = 5, title = "设备名称")
@TableField(exist = false)
private List<String> deviceNameList;
/**
* 设备类型
*/
......@@ -53,9 +59,13 @@ public class RRepairDevice extends BaseDTO {
* 设备序列号
*/
@TableField(value = "device_no")
@ExcelColumn(order = 6, title = "设备序列号")
private String deviceNo;
@MultiColumn(classType = String.class)
@ExcelColumn(order = 6, title = "设备序列号")
@TableField(exist = false)
private List<String> deviceNoList;
/**
* 归还的设备序列号
*/
......
......@@ -57,7 +57,6 @@ public class Store {
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@OrderBy
private Date createTime;
/**
......@@ -71,16 +70,24 @@ public class Store {
* 备注
*/
private String remark;
/**
* 项目阶段
*/
private Integer projectStage;
/**
* 集团id
*/
private Long accountId;
/**
* 立项日期
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date estDate;
/**
* 主合同id
*/
private Long masterContract;
......
package vion.service;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseService;
import org.springframework.web.bind.annotation.RequestParam;
......@@ -13,7 +14,7 @@ import java.util.Map;
public interface IStoreService extends MPJBaseService<Store> {
Page<StoreVO> getStoreList(StoreDTO data);
Page<StoreVO> getStoreList(StoreDTO data, List<OrderItem> orderItemList);
String updateStoreStage(StatusDTO statusDTO, String token);
......@@ -32,4 +33,6 @@ public interface IStoreService extends MPJBaseService<Store> {
String addCron(Long storeId, String storeName, String cronStr, String userId);
String stopCron(Long storeId);
Map<Integer, Long> statState();
}
......@@ -26,7 +26,7 @@ public interface ITaskService extends MPJBaseService<Task> {
String urgeTask(Long taskId, String remark);
List<Map<String, Object>> peopleAnalysis(Date startDate, Date endDate, Integer source);
List<Map<String, Object>> peopleAnalysis(Date startDate, Date endDate, Integer source, Long userId);
List<Map<String, Object>> proAnalysis(Date startDate, Date endDate, Integer source);
......
package vion.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.Db;
......@@ -77,7 +78,7 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
private String fileUrl;
@Override
public Page<StoreVO> getStoreList(StoreDTO data) {
public Page<StoreVO> getStoreList(StoreDTO data, List<OrderItem> orderItemList) {
var storeIdListByTagId = Optional.ofNullable(data.getTagId())
.map(tagId -> storeTagService.lambdaQuery().eq(RStoreTag::getTagId, tagId).list())
.map(storeTagList -> storeTagList.stream().map(RStoreTag::getStoreId).collect(Collectors.toList()))
......@@ -91,11 +92,18 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
.orElse(List.of(-1L));
var store = converter.convert(data, Store.class);
var page = Page.<Store>of(data.getPageNum(), data.getPageSize());
Opt.ofEmptyAble(orderItemList).ifPresent(page::addOrder);
// 单独处理 estDate 字段
var estDate = store.getEstDate();
store.setEstDate(null);
var storeList = this.lambdaQuery(store)
.in(ObjUtil.isNotNull(data.getTagId()), Store::getId, storeIdListByTagId)
.in(ObjUtil.isNotNull(data.getMainUser()), Store::getId, storeIdListByMainUser)
.orderByDesc(Store::getIsImportant, Store::getCreateTime)
.page(Page.of(data.getPageNum(), data.getPageSize()));
.gt(ObjUtil.isNotNull(estDate), Store::getEstDate, estDate)
.page(page);
// todo 缓存
List<Account> accountList = accountService.list();
......@@ -521,6 +529,12 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
return "定时提醒任务移除失败";
}
@Override
public Map<Integer, Long> statState() {
var storeList = this.lambdaQuery().eq(Store::getProjectState, 1).list();
return storeList.stream().collect(Collectors.groupingBy(Store::getProjectStage, Collectors.counting()));
}
JSONObject buildMsg(String storeName, String userid) {
var jsonObj = JSONUtil.ofObj()
.set("agent_id", 2358374016L)
......
......@@ -197,10 +197,13 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
task.setUuid(IdUtil.nanoId());
this.save(task);
// 客户提交的工单提醒给销售
if (ObjUtil.isNotEmpty(data.getTaskTempId())) {
Opt.ofNullable(redissonClient.getBucket(RedisKeyEnum.DING_PREFIX.getVal() + RedisKeyEnum.USER_ID.getVal() + store.getSalesperson()).get())
.map(u -> (User) u)
.map(User::getUserid)
.ifPresent(userid -> dingMod.workMsg(buildMsg2(userid, store.getName(), task)));
}
// 预工单文件在工单创建时,复制一份到工单文件夹下
Opt.ofNullable(data.getTaskTempId())
......@@ -428,11 +431,12 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
}
@Override
public List<Map<String, Object>> peopleAnalysis(Date startDate, Date endDate, Integer source) {
public List<Map<String, Object>> peopleAnalysis(Date startDate, Date endDate, Integer source, Long userId) {
List<Task> taskList = this.lambdaQuery()
.between(ArrayUtil.isAllNotNull(startDate, endDate), Task::getRepairTime, startDate, endDate)
.isNotNull(ObjUtil.equals(source, 1), Task::getTaskTempId)
.isNull(ObjUtil.equals(source, 2), Task::getTaskTempId)
.eq(ObjUtil.isNotNull(userId), Task::getActiveUser, userId)
.list();
List<Store> storeList = storeService.list();
Map<Long, String> id2UsernameMap = userService.list().stream().collect(Collectors.toMap(User::getId, User::getUsername));
......@@ -531,7 +535,7 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
var msg = JSONUtil.ofObj();
var content = JSONUtil.ofObj().set("title", "您有一条新工单请及时处理哦~_~");
String template = """
#### 门店信息: **{}** [FullOfVitality]" +
#### 门店信息: **{}** [FullOfVitality]
#### 任务编号:{}
#### 报修人:{}
#### 联系方式:{}
......@@ -592,7 +596,7 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
var msg = JSONUtil.ofObj();
var content = JSONUtil.ofObj().set("title", "工单转发提醒");
String template = """
#### 门店信息: **{}** [FullOfVitality]`
#### 门店信息: **{}** [FullOfVitality]
#### 任务编号:{}
#### 报修人:{}
#### 联系方式:{}
......
......@@ -46,6 +46,12 @@ public class StoreVO {
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date modifyTime;
/**
* 立项日期
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date estDate;
/**
* 备注
*/
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!