Commit 036393a5 by HlQ

[add]

1.请求日志添加操作人,请求体获取以及 request 可重复读配置
2.添加备件申请、设备返修功能
3.结算差异添加合同额和余额同时抵扣
4.收款、开票、工单和合同验收添加钉钉消息提醒,推送销售
1 parent 8859729b
Showing 47 changed files with 1856 additions and 80 deletions
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
<artifactId>Vion-DevOps</artifactId> <artifactId>Vion-DevOps</artifactId>
<version>1</version> <version>1</version>
<properties> <properties>
<pg.version>42.6.0</pg.version> <pg.version>42.7.0</pg.version>
<sqlserver.version>12.2.0.jre8</sqlserver.version> <sqlserver.version>12.2.0.jre8</sqlserver.version>
<lombok.version>1.18.30</lombok.version> <lombok.version>1.18.30</lombok.version>
<hutool.version>5.8.25</hutool.version> <hutool.version>5.8.25</hutool.version>
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
<mp-join.version>1.4.7.2</mp-join.version> <mp-join.version>1.4.7.2</mp-join.version>
<wx-mp.version>4.6.0</wx-mp.version> <wx-mp.version>4.6.0</wx-mp.version>
<sa-token.verion>1.37.0</sa-token.verion> <sa-token.verion>1.37.0</sa-token.verion>
<myexcel.version>4.3.3</myexcel.version> <myexcel.version>4.5.0</myexcel.version>
</properties> </properties>
<dependencies> <dependencies>
......
package vion.advice; package vion.advice;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil; import cn.hutool.extra.servlet.ServletUtil;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*; import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.MDC; import org.slf4j.MDC;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import vion.vo.UserVO;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
...@@ -33,22 +40,27 @@ public class LogAspect { ...@@ -33,22 +40,27 @@ public class LogAspect {
@Before("logPointcut()") @Before("logPointcut()")
public void doBefore(JoinPoint joinPoint) throws JsonProcessingException { public void doBefore(JoinPoint joinPoint) throws JsonProcessingException {
// 登录等接口,无需登录可访问,根据 token 获取当前用户会抛未登录的异常,需捕获进行处理
String username = Opt.ofTry(() -> (UserVO) StpUtil.getTokenSession().get("curLoginUser"))
.map(UserVO::getUsername)
.orElse("未知");
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (ObjUtil.isNull(attributes)) { if (ObjUtil.isNull(attributes)) {
return; return;
} }
HttpServletRequest request = attributes.getRequest(); HttpServletRequest request = attributes.getRequest();
long startTime = System.currentTimeMillis(); request.setAttribute("startTime", System.currentTimeMillis());
request.setAttribute("startTime", startTime);
String requestId = (String) request.getAttribute("requestId"); MDC.put("requestId", (String) request.getAttribute("requestId"));
MDC.put("requestId", requestId); log.info("Request URL:{}, Method:{}, IP:{}, Operator:{}, Args:{}, Body:{}",
log.info("Request URL:{}, Method:{}, IP:{}, Arguments:{}",
request.getRequestURI(), request.getRequestURI(),
request.getMethod(), request.getMethod(),
ServletUtil.getClientIP(request), ServletUtil.getClientIP(request),
objectMapper.writeValueAsString(request.getParameterMap()) username,
objectMapper.writeValueAsString(request.getParameterMap()),
StrUtil.replaceChars(ServletUtil.getBody(request), " \r\n", "")
); );
} }
......
package vion.config;
import cn.hutool.core.io.IoUtil;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
/**
* 构建可重复读的流
*
* @author HlQ
* @date 2024/1/25
*/
public class RequestWrapper extends HttpServletRequestWrapper {
//参数字节数组
private byte[] requestBody;
//Http请求对象
private HttpServletRequest request;
public RequestWrapper(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public ServletInputStream getInputStream() throws IOException {
// 每次调用此方法时将数据流中的数据读取出来,然后再回填到InputStream之中
// 解决通过@RequestBody和@RequestParam(POST方式)读取一次后控制器拿不到参数问题
if (null == this.requestBody) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
IoUtil.copy(request.getInputStream(), bos);
this.requestBody = bos.toByteArray();
}
final ByteArrayInputStream bis = new ByteArrayInputStream(requestBody);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
@Override
public int read() {
return bis.read();
}
};
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
}
...@@ -152,10 +152,10 @@ public class ContractController { ...@@ -152,10 +152,10 @@ public class ContractController {
@SaCheckPermission(value = "contract:export", orRole = "admin") @SaCheckPermission(value = "contract:export", orRole = "admin")
public void pointExport(ContractDTO dto, HttpServletResponse response) { public void pointExport(ContractDTO dto, HttpServletResponse response) {
UserVO user = (UserVO) StpUtil.getTokenSession().get("curLoginUser"); UserVO user = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
dto.setPageSize(9999); dto.setPageSize(30000);
Page<ContractVO> voPage = contractService.list(dto); Page<ContractVO> voPage = contractService.list(dto);
try (DefaultExcelBuilder<ContractVO> pointInfoVODefaultExcelBuilder = DefaultExcelBuilder.of(ContractVO.class)) { try (DefaultExcelBuilder<ContractVO> defaultExcelBuilder = DefaultExcelBuilder.of(ContractVO.class)) {
Workbook workbook = pointInfoVODefaultExcelBuilder.build(voPage.getRecords()); Workbook workbook = defaultExcelBuilder.build(voPage.getRecords());
// 水印添加指定字体,并在服务器上安装 SimSun 字体,解决中文字体变成方块的问题 // 水印添加指定字体,并在服务器上安装 SimSun 字体,解决中文字体变成方块的问题
Watermark watermark = new Watermark(); Watermark watermark = new Watermark();
watermark.setText(user.getUsername() + "-" + user.getPhone()); watermark.setText(user.getUsername() + "-" + user.getPhone());
......
...@@ -53,6 +53,13 @@ public class PaymentController { ...@@ -53,6 +53,13 @@ public class PaymentController {
return paymentService.save(dto); return paymentService.save(dto);
} }
@PostMapping("/payment/{id}")
@SaCheckPermission(value = "payment:edit", orRole = "admin")
public String update(@PathVariable Long id, @RequestBody PaymentDTO dto) {
dto.setId(id);
return paymentService.update(id, dto);
}
@DeleteMapping("/payment/{id}") @DeleteMapping("/payment/{id}")
@SaCheckPermission(value = "payment:remove", orRole = "admin") @SaCheckPermission(value = "payment:remove", orRole = "admin")
public String delById(@PathVariable Long id, String contractNo) { public String delById(@PathVariable Long id, String contractNo) {
...@@ -63,10 +70,10 @@ public class PaymentController { ...@@ -63,10 +70,10 @@ public class PaymentController {
@SaCheckPermission(value = "contract:export", orRole = "admin") @SaCheckPermission(value = "contract:export", orRole = "admin")
public void pointExport(PaymentDTO dto, HttpServletResponse response) { public void pointExport(PaymentDTO dto, HttpServletResponse response) {
UserVO user = (UserVO) StpUtil.getTokenSession().get("curLoginUser"); UserVO user = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
dto.setPageSize(9999); dto.setPageSize(30000);
Page<PaymentVO> voPage = paymentService.list(dto); Page<PaymentVO> voPage = paymentService.list(dto);
try (DefaultExcelBuilder<PaymentVO> pointInfoVODefaultExcelBuilder = DefaultExcelBuilder.of(PaymentVO.class)) { try (DefaultExcelBuilder<PaymentVO> defaultExcelBuilder = DefaultExcelBuilder.of(PaymentVO.class)) {
Workbook workbook = pointInfoVODefaultExcelBuilder.build(voPage.getRecords()); Workbook workbook = defaultExcelBuilder.build(voPage.getRecords());
// 水印添加指定字体,并在服务器上安装 SimSun 字体,解决中文字体变成方块的问题 // 水印添加指定字体,并在服务器上安装 SimSun 字体,解决中文字体变成方块的问题
Watermark watermark = new Watermark(); Watermark watermark = new Watermark();
watermark.setText(user.getUsername() + "-" + user.getPhone()); watermark.setText(user.getUsername() + "-" + user.getPhone());
......
...@@ -118,11 +118,11 @@ public class PointDesignController { ...@@ -118,11 +118,11 @@ public class PointDesignController {
@SaCheckPermission(value = "point:export", orRole = "admin") @SaCheckPermission(value = "point:export", orRole = "admin")
public void pointExport(PointInfoDTO dto, HttpServletResponse response) { public void pointExport(PointInfoDTO dto, HttpServletResponse response) {
UserVO user = (UserVO) StpUtil.getTokenSession().get("curLoginUser"); UserVO user = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
dto.setPageSize(9999); dto.setPageSize(30000);
Page<PointInfoVO> voPage = pointInfoService.list(dto); Page<PointInfoVO> voPage = pointInfoService.list(dto);
voPage.getRecords().forEach(v -> v.setPointUrl("https://yunwei.vionyun.com:8443/wap/setup-device?uuid=" + v.getUuid())); voPage.getRecords().forEach(v -> v.setPointUrl("https://yunwei.vionyun.com:8443/wap/setup-device?uuid=" + v.getUuid()));
try (DefaultExcelBuilder<PointInfoVO> pointInfoVODefaultExcelBuilder = DefaultExcelBuilder.of(PointInfoVO.class)) { try (DefaultExcelBuilder<PointInfoVO> defaultExcelBuilder = DefaultExcelBuilder.of(PointInfoVO.class)) {
Workbook workbook = pointInfoVODefaultExcelBuilder.build(voPage.getRecords()); Workbook workbook = defaultExcelBuilder.build(voPage.getRecords());
// 水印添加指定字体,并在服务器上安装 SimSun 字体,解决中文字体变成方块的问题 // 水印添加指定字体,并在服务器上安装 SimSun 字体,解决中文字体变成方块的问题
Watermark watermark = new Watermark(); Watermark watermark = new Watermark();
watermark.setText(user.getUsername() + "-" + user.getPhone()); watermark.setText(user.getUsername() + "-" + user.getPhone());
......
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.RRepairDevice;
import vion.service.IRRepairDeviceService;
/**
* 备件、维修与设备关联
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/rRepairDevice")
public class RRepairDeviceController {
private final IRRepairDeviceService repairDeviceService;
@GetMapping("/{id}")
@SaCheckPermission(value = "rRepairDevice:query", orRole = "admin")
public RRepairDevice getById(@PathVariable Long id) {
return repairDeviceService.getById(id);
}
@GetMapping
@SaCheckPermission(value = "rRepairDevice:list", orRole = "admin")
public Page<RRepairDevice> list(RRepairDevice dto) {
return repairDeviceService.lambdaQuery(dto)
.orderByDesc(RRepairDevice::getCreateTime)
.page(Page.of(dto.getPageNum(), dto.getPageSize()));
}
@PostMapping
@SaCheckPermission(value = "rRepairDevice:save", orRole = "admin")
public String save(@RequestBody RRepairDevice dto) {
return repairDeviceService.save(dto) ? "保存成功" : "保存失败";
}
@PostMapping("/{id}")
@SaCheckPermission(value = "rRepairDevice:edit", orRole = "admin")
public String updById(@RequestBody RRepairDevice dto) {
return repairDeviceService.updateById(dto) ? "修改成功" : "修改失败";
}
@DeleteMapping("/{id}")
@SaCheckPermission(value = "rRepairDevice:remove", orRole = "admin")
public String delById(@PathVariable Long id) {
return repairDeviceService.removeById(id) ? "删除成功" : "删除失败";
}
}
package vion.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ArrayUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import vion.dto.RepairRecDTO;
import vion.service.IRepairRecService;
import vion.vo.RepairRecVO;
import java.util.List;
/**
* 返修申请
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/repairRec")
public class RepairRecController {
private final IRepairRecService repairRecService;
@PostMapping("/frontSubmit")
public Object frontSubmit(RepairRecDTO dto) {
return repairRecService.frontSubmit(dto);
}
@GetMapping
@SaCheckPermission(value = "repairRec:list", orRole = "admin")
public List<RepairRecVO> list(RepairRecDTO dto) {
Assert.isTrue(ArrayUtil.isAllNotNull(dto.getCreateTimeStart(), dto.getCreateTimeEnd()), "查询时间范围不能为空");
return repairRecService.list(dto);
}
@GetMapping("/{id}")
@SaCheckPermission(value = "repairRec:query", orRole = "admin")
public RepairRecVO getById(@PathVariable Long id) {
return repairRecService.getRepairRecDetail(id, null);
}
@GetMapping("/get/{uuid}")
public RepairRecVO getByUuid(@PathVariable String uuid) {
return repairRecService.getRepairRecDetail(null, uuid);
}
@PostMapping("/{id}")
@SaCheckPermission(value = "repairRec:edit", orRole = "admin")
public String updById(@PathVariable Long id, @RequestBody RepairRecDTO dto) {
return repairRecService.updById(id, dto);
}
@DeleteMapping("/{id}")
@SaCheckPermission(value = "repairRec:remove", orRole = "admin")
public String delById(@PathVariable Long id) {
return repairRecService.removeById(id) ? "删除成功" : "删除失败";
}
}
...@@ -24,6 +24,7 @@ public class SettlementDiffController { ...@@ -24,6 +24,7 @@ public class SettlementDiffController {
} }
@GetMapping("/settlementDiff/{id}") @GetMapping("/settlementDiff/{id}")
@SaCheckPermission(value = "settlementDiff:query", orRole = "admin")
public SettlementDiffVO getVOById(@PathVariable Long id) { public SettlementDiffVO getVOById(@PathVariable Long id) {
return settlementDiffService.getVOById(id); return settlementDiffService.getVOById(id);
} }
......
package vion.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.github.liaochong.myexcel.core.DefaultStreamExcelBuilder;
import com.github.liaochong.myexcel.core.watermark.Watermark;
import com.github.liaochong.myexcel.utils.AttachmentExportUtil;
import com.github.liaochong.myexcel.utils.WatermarkUtil;
import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.bind.annotation.*;
import vion.dto.SparePartDTO;
import vion.service.ISparePartService;
import vion.vo.SparePartVO;
import vion.vo.UserVO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 备件申请
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/sparePart")
public class SparePartController {
private final ISparePartService sparePartService;
private final Converter converter;
@PostMapping("/frontSubmit")
public Object frontSubmit(SparePartDTO dto) {
return sparePartService.frontSubmit(dto);
}
@GetMapping
@SaCheckPermission(value = "sparePart:list", orRole = "admin")
public List<SparePartVO> list(SparePartDTO dto) {
Assert.isTrue(ArrayUtil.isAllNotNull(dto.getCreateTimeStart(), dto.getCreateTimeEnd()), "查询时间范围不能为空");
return sparePartService.list(dto);
}
@GetMapping("/{id}")
@SaCheckPermission(value = "sparePart:query", orRole = "admin")
public SparePartVO getById(@PathVariable Long id) {
return sparePartService.getSparePartDetail(id, null);
}
@GetMapping("/get/{uuid}")
public SparePartVO getByUuid(@PathVariable String uuid) {
return sparePartService.getSparePartDetail(null, uuid);
}
@PostMapping("/{id}")
@SaCheckPermission(value = "sparePart:edit", orRole = "admin")
public String updById(@PathVariable Long id, @RequestBody SparePartDTO dto) {
return sparePartService.updById(id, dto);
}
@DeleteMapping("/{id}")
@SaCheckPermission(value = "sparePart:remove", orRole = "admin")
public String delById(@PathVariable Long id) {
return sparePartService.removeById(id) ? "删除成功" : "删除失败";
}
@GetMapping("/export")
@SaCheckPermission(value = "sparePart:export", orRole = "admin")
public void sparePartExport(SparePartDTO dto, HttpServletResponse response) {
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();
// 水印添加指定字体,并在服务器上安装 SimSun 字体,解决中文字体变成方块的问题
Watermark watermark = new Watermark();
watermark.setText(user.getUsername() + "-" + user.getPhone());
watermark.setFont(new Font("SimSun", Font.PLAIN, 16));
WatermarkUtil.addWatermark(workbook, watermark);
AttachmentExportUtil.export(workbook, StrUtil.format("备件申请列表_{}", DateUtil.formatDateTime(new Date())), response);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
...@@ -6,6 +6,7 @@ import cn.hutool.core.date.DateUtil; ...@@ -6,6 +6,7 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.liaochong.myexcel.core.DefaultExcelBuilder; import com.github.liaochong.myexcel.core.DefaultExcelBuilder;
import com.github.liaochong.myexcel.core.watermark.Watermark;
import com.github.liaochong.myexcel.utils.AttachmentExportUtil; import com.github.liaochong.myexcel.utils.AttachmentExportUtil;
import com.github.liaochong.myexcel.utils.WatermarkUtil; import com.github.liaochong.myexcel.utils.WatermarkUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
...@@ -21,6 +22,8 @@ import vion.vo.TaskVO; ...@@ -21,6 +22,8 @@ import vion.vo.TaskVO;
import vion.vo.UserVO; import vion.vo.UserVO;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.IOException;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
...@@ -84,12 +87,18 @@ public class TaskController { ...@@ -84,12 +87,18 @@ public class TaskController {
@SaCheckPermission(value = "task:export", orRole = "admin") @SaCheckPermission(value = "task:export", orRole = "admin")
public void taskExport(TaskDTO data, HttpServletResponse response) { public void taskExport(TaskDTO data, HttpServletResponse response) {
UserVO user = (UserVO) StpUtil.getTokenSession().get("curLoginUser"); UserVO user = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
data.setPageSize(9999); data.setPageSize(30000);
Page<TaskVO> voPage = taskService.getTaskList(data); Page<TaskVO> voPage = taskService.getTaskList(data);
Workbook workbook = DefaultExcelBuilder.of(TaskVO.class) try (DefaultExcelBuilder<TaskVO> defaultExcelBuilder = DefaultExcelBuilder.of(TaskVO.class)) {
.binding(userNameConverter) Workbook workbook = defaultExcelBuilder.binding(userNameConverter).build(voPage.getRecords());
.build(voPage.getRecords()); // 水印添加指定字体,并在服务器上安装 SimSun 字体,解决中文字体变成方块的问题
WatermarkUtil.addWatermark(workbook, user.getUsername() + "-" + user.getPhone()); Watermark watermark = new Watermark();
AttachmentExportUtil.export(workbook, StrUtil.format("任务列表_{}", DateUtil.formatDateTime(new Date())), response); watermark.setText(user.getUsername() + "-" + user.getPhone());
watermark.setFont(new Font("SimSun", Font.PLAIN, 16));
WatermarkUtil.addWatermark(workbook, watermark);
AttachmentExportUtil.export(workbook, StrUtil.format("任务列表_{}", DateUtil.formatDateTime(new Date())), response);
} catch (IOException e) {
throw new RuntimeException(e);
}
} }
} }
...@@ -3,16 +3,14 @@ package vion.cron; ...@@ -3,16 +3,14 @@ package vion.cron;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
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.StrUtil; import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import vion.model.Contract; import vion.model.*;
import vion.model.ContractPayment;
import vion.model.Dictionary;
import vion.model.Payment;
import vion.service.*; import vion.service.*;
import java.math.BigDecimal; import java.math.BigDecimal;
...@@ -35,6 +33,7 @@ public class ContractRunner { ...@@ -35,6 +33,7 @@ public class ContractRunner {
private final IContractService contractService; private final IContractService contractService;
private final IDictionaryService dictionaryService; private final IDictionaryService dictionaryService;
private final IContractPaymentService contractPaymentService; private final IContractPaymentService contractPaymentService;
private final IRContractUserService contractUserService;
private final IStoreService storeService; private final IStoreService storeService;
private final IPaymentService paymentService; private final IPaymentService paymentService;
private final RedisTemplate redisTemplate; private final RedisTemplate redisTemplate;
...@@ -123,6 +122,17 @@ public class ContractRunner { ...@@ -123,6 +122,17 @@ public class ContractRunner {
} }
}); });
contractService.saveOrUpdateBatch(insOrUpdContractList, 500); contractService.saveOrUpdateBatch(insOrUpdContractList, 500);
insOrUpdContractList.forEach(v -> {
// 合同状态不为空,代表此条记录为新增,需要同步销售人信息到 r_contract_user 表中
if (ObjUtil.isNotNull(v.getStatus())) {
RContractUser contractUser = new RContractUser();
contractUser.setUserId(Opt.ofNullable(redisTemplate.opsForValue().get("dingtalk:user:name:" + v.getSaleName())).map(Object::toString).orElse(null));
contractUser.setUsername(v.getSaleName());
contractUser.setContractId(v.getId());
contractUser.setContractNo(v.getContractNo());
contractUserService.save(contractUser);
}
});
List<ContractPayment> existContractPaymentList = contractPaymentService.list(); List<ContractPayment> existContractPaymentList = contractPaymentService.list();
Map<Long, Map<Integer, Long>> contractId2PaymentMap = existContractPaymentList.stream().collect(Collectors.groupingBy(ContractPayment::getContractId, Collectors.toMap(ContractPayment::getPaymentType, ContractPayment::getId))); Map<Long, Map<Integer, Long>> contractId2PaymentMap = existContractPaymentList.stream().collect(Collectors.groupingBy(ContractPayment::getContractId, Collectors.toMap(ContractPayment::getPaymentType, ContractPayment::getId)));
......
package vion.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.multipart.MultipartFile;
import java.util.Date;
/**
* @author HlQ
* @date 2024/1/24
*/
@Getter
@Setter
public class RepairRecDTO extends BaseDTO {
private Long id;
/**
* 集团id
*/
private Long accountId;
/**
* 项目id
*/
private Long storeId;
/**
* 合同id
*/
private Long contractId;
/**
* 合同编号
*/
private String contractNo;
/**
* 项目名称(用户填写的)
*/
private String projectName;
/**
* 联系人
*/
private String contact;
/**
* 手机号码
*/
private String phone;
/**
* 设备数量
*/
private Integer deviceNum;
/**
* 收货地址
*/
private String shippingAddress;
/**
* 收货联系人
*/
private String receivingContact;
/**
* 收货联系电话
*/
private String receivingPhone;
/**
* 发货日期
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date shipDate;
/**
* 快递公司
*/
private String courierCompany;
/**
* 快递单号
*/
private String trackingNumber;
private String uuid;
/**
* 微信openid
*/
private String openid;
/**
* 备注
*/
private String remark;
private MultipartFile[] files;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTimeStart;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTimeEnd;
}
\ No newline at end of file \ No newline at end of file
...@@ -41,5 +41,10 @@ public class SettlementDiffDTO extends BaseDTO { ...@@ -41,5 +41,10 @@ public class SettlementDiffDTO extends BaseDTO {
*/ */
private Long operator; private Long operator;
/**
* 备注
*/
private String remark;
private MultipartFile[] files; private MultipartFile[] files;
} }
\ No newline at end of file \ No newline at end of file
package vion.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.multipart.MultipartFile;
import java.util.Date;
/**
* @author HlQ
* @date 2024/1/19
*/
@Getter
@Setter
public class SparePartDTO extends BaseDTO {
private Long id;
/**
* 集团id
*/
private Long accountId;
/**
* 项目id
*/
private Long storeId;
/**
* 合同id
*/
private Long contractId;
/**
* 合同编号
*/
private String contractNo;
/**
* 项目名称(用户填写的)
*/
private String projectName;
/**
* 联系人
*/
private String contact;
/**
* 手机号码
*/
private String phone;
/**
* 设备数量
*/
private Integer deviceNum;
/**
* 收货地址
*/
private String shippingAddress;
/**
* 收货联系人
*/
private String receivingContact;
/**
* 收货联系电话
*/
private String receivingPhone;
/**
* 发货日期
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date shipDate;
/**
* 快递公司
*/
private String courierCompany;
/**
* 快递单号
*/
private String trackingNumber;
/**
* 备注
*/
private String remark;
/**
* uuid
*/
private String uuid;
/** 微信用户id */
private String openid;
private MultipartFile[] files;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTimeStart;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTimeEnd;
}
\ No newline at end of file \ No newline at end of file
...@@ -27,7 +27,7 @@ public class WxDTO { ...@@ -27,7 +27,7 @@ public class WxDTO {
*/ */
private Long id; private Long id;
/** /**
* flag 1:故障保修 2:点位设计 * flag 1:故障保修 2:点位设计 3:备件申请 4:设备返修
*/ */
private Integer flag; private Integer flag;
} }
...@@ -7,8 +7,12 @@ import org.springframework.stereotype.Component; ...@@ -7,8 +7,12 @@ import org.springframework.stereotype.Component;
import vion.dto.WxDTO; import vion.dto.WxDTO;
import vion.event.WxDTOEvent; import vion.event.WxDTOEvent;
import vion.model.RPointWx; import vion.model.RPointWx;
import vion.model.RepairRec;
import vion.model.SparePart;
import vion.model.TaskTemp; import vion.model.TaskTemp;
import vion.service.IRPointWxService; import vion.service.IRPointWxService;
import vion.service.IRepairRecService;
import vion.service.ISparePartService;
import vion.service.ITaskTempService; import vion.service.ITaskTempService;
/** /**
...@@ -22,6 +26,8 @@ public class WxDTOEventListener implements ApplicationListener<WxDTOEvent> { ...@@ -22,6 +26,8 @@ public class WxDTOEventListener implements ApplicationListener<WxDTOEvent> {
private final ITaskTempService taskTempService; private final ITaskTempService taskTempService;
private final IRPointWxService pointWxService; private final IRPointWxService pointWxService;
private final ISparePartService sparePartService;
private final IRepairRecService repairRecService;
@Override @Override
public void onApplicationEvent(WxDTOEvent event) { public void onApplicationEvent(WxDTOEvent event) {
...@@ -35,6 +41,10 @@ public class WxDTOEventListener implements ApplicationListener<WxDTOEvent> { ...@@ -35,6 +41,10 @@ public class WxDTOEventListener implements ApplicationListener<WxDTOEvent> {
updateTaskTemp(openid, id); updateTaskTemp(openid, id);
} else if (flag == 2) { } else if (flag == 2) {
updatePointInfo(openid, nickname, id); updatePointInfo(openid, nickname, id);
} else if (flag == 3) {
updateSparePart(openid, id);
} else if (flag == 4) {
updateRepairRec(openid, id);
} }
} }
...@@ -54,4 +64,20 @@ public class WxDTOEventListener implements ApplicationListener<WxDTOEvent> { ...@@ -54,4 +64,20 @@ public class WxDTOEventListener implements ApplicationListener<WxDTOEvent> {
pointWxService.save(pointWx); pointWxService.save(pointWx);
log.info("点位设计单子[id:{}]绑定openid成功!", id); log.info("点位设计单子[id:{}]绑定openid成功!", id);
} }
private void updateSparePart(String openid, Long id) {
sparePartService.lambdaUpdate()
.set(SparePart::getOpenid, openid)
.eq(SparePart::getId, id)
.update(new SparePart());
log.info("备件申请单子[id:{}]绑定openid成功!", id);
}
private void updateRepairRec(String openid, Long id) {
repairRecService.lambdaUpdate()
.set(RepairRec::getOpenid, openid)
.eq(RepairRec::getId, id)
.update(new RepairRec());
log.info("设备返修单子[id:{}]绑定openid成功!", id);
}
} }
...@@ -28,6 +28,6 @@ public class InterceptorConfig implements WebMvcConfigurer { ...@@ -28,6 +28,6 @@ public class InterceptorConfig implements WebMvcConfigurer {
.excludePathPatterns("/api/getQRCode", "/api/getFollowingOpenid", "/api/verifyScan") .excludePathPatterns("/api/getQRCode", "/api/getFollowingOpenid", "/api/verifyScan")
.excludePathPatterns("/api/point/getBindQRCode", "/api/point/getBindOpenid") .excludePathPatterns("/api/point/getBindQRCode", "/api/point/getBindOpenid")
.excludePathPatterns("/api/point/upd/{uuid}", "/api/point/get/{uuid}", "/api/point/install/submit/{uuid}", "/api/point/client/reject", "/api/point/reject/uuid/{uuid}") .excludePathPatterns("/api/point/upd/{uuid}", "/api/point/get/{uuid}", "/api/point/install/submit/{uuid}", "/api/point/client/reject", "/api/point/reject/uuid/{uuid}")
.excludePathPatterns("/api/sparePart/frontSubmit"); .excludePathPatterns("/api/sparePart/frontSubmit", "/api/repairRec/frontSubmit");
} }
} }
...@@ -2,6 +2,7 @@ package vion.interceptor; ...@@ -2,6 +2,7 @@ package vion.interceptor;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import vion.config.RequestWrapper;
import javax.servlet.*; import javax.servlet.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
...@@ -12,8 +13,13 @@ public class RequestIdFilter implements Filter { ...@@ -12,8 +13,13 @@ public class RequestIdFilter implements Filter {
@Override @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request; if (request instanceof HttpServletRequest) {
httpServletRequest.setAttribute("requestId", IdUtil.fastSimpleUUID()); ServletRequest requestWrapper = new RequestWrapper((HttpServletRequest) request);
chain.doFilter(request, response); requestWrapper.setAttribute("requestId", IdUtil.fastSimpleUUID());
chain.doFilter(requestWrapper, response);
} else {
request.setAttribute("requestId", IdUtil.fastSimpleUUID());
chain.doFilter(request, response);
}
} }
} }
\ No newline at end of file \ No newline at end of file
package vion.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import vion.model.RRepairDevice;
/**
* @author HlQ
* @date 2024/1/25
*/
public interface RRepairDeviceMapper extends MPJBaseMapper<RRepairDevice> {
}
\ No newline at end of file \ No newline at end of file
package vion.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import vion.model.RepairRec;
/**
* @author HlQ
* @date 2024/1/24
*/
public interface RepairRecMapper extends MPJBaseMapper<RepairRec> {
}
\ No newline at end of file \ No newline at end of file
package vion.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import vion.model.SparePart;
/**
* @author HlQ
* @date 2024/1/19
*/
public interface SparePartMapper extends MPJBaseMapper<SparePart> {
}
\ No newline at end of file \ No newline at end of file
...@@ -31,6 +31,7 @@ public class FileInfo { ...@@ -31,6 +31,7 @@ public class FileInfo {
* <br>15结算差异</br> * <br>15结算差异</br>
* <br>16客户提交的门店图纸,17点位设计图,18合同范本,19客户上传的合同,20安装上线,与总部邮件截图</br> * <br>16客户提交的门店图纸,17点位设计图,18合同范本,19客户上传的合同,20安装上线,与总部邮件截图</br>
* <br>21服务单等表单富文本编辑器里传图用这个类型</br> * <br>21服务单等表单富文本编辑器里传图用这个类型</br>
* <br>22备件,23返修</br>
*/ */
private Integer sourceType; private Integer sourceType;
/** 文件来源id */ /** 文件来源id */
......
...@@ -54,7 +54,7 @@ public class RContractUser extends BaseDTO { ...@@ -54,7 +54,7 @@ public class RContractUser extends BaseDTO {
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date enterDate; private Date enterDate;
@TableField(value = "create_time") @TableField(value = "create_time", fill = FieldFill.INSERT)
@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;
} }
\ No newline at end of file \ No newline at end of file
package vion.model;
import com.baomidou.mybatisplus.annotation.*;
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 lombok.Data;
import vion.dto.BaseDTO;
import java.util.Date;
/**
* @author HlQ
* @date 2024/1/25
*/
@Data
@TableName(value = "r_repair_device")
@ExcelModel(includeAllField = false)
public class RRepairDevice extends BaseDTO {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 关联id
*/
@TableField(value = "r_id")
@JsonProperty("rId")
private Long rId;
/**
* 关联类型 1:备件申请 2:设备返修
*/
@TableField(value = "r_type")
@JsonProperty("rType")
private Integer rType;
/**
* 设备名称
*/
@TableField(value = "device_name")
@ExcelColumn(order = 5, title = "设备名称")
private String deviceName;
/**
* 设备类型
*/
@TableField(value = "device_type")
private Integer deviceType;
/**
* 设备序列号
*/
@TableField(value = "device_no")
@ExcelColumn(order = 6, title = "设备序列号")
private String deviceNo;
/**
* 设备id
*/
@TableField(value = "device_id")
private String deviceId;
/**
* 故障描述
*/
@TableField(value = "fault_desc")
private String faultDesc;
/**
* 故障确认
*/
@TableField(value = "fault_confirm")
private String faultConfirm;
/**
* 故障原因
*/
@TableField(value = "fault_reason")
private String faultReason;
/**
* 解决办法
*/
@TableField(value = "fault_solution")
private String faultSolution;
/**
* 维修人
*/
@TableField(value = "maintainer")
private String maintainer;
/**
* 信息
*/
@TableField(value = "info")
private String info;
/**
* 备注
*/
@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.model;
import com.baomidou.mybatisplus.annotation.*;
import io.github.linpeilie.annotations.AutoMapper;
import io.github.linpeilie.annotations.AutoMappers;
import lombok.Data;
import vion.dto.RepairRecDTO;
import vion.vo.RepairRecVO;
import java.util.Date;
/**
* @author HlQ
* @date 2024/1/24
*/
@Data
@TableName(value = "tbl_repair_rec")
@AutoMappers({
@AutoMapper(target = RepairRecVO.class),
@AutoMapper(target = RepairRecDTO.class),
})
public class RepairRec {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 集团id
*/
@TableField(value = "account_id")
private Long accountId;
/**
* 项目id
*/
@TableField(value = "store_id")
private Long storeId;
/**
* 合同id
*/
@TableField(value = "contract_id")
private Long contractId;
/**
* 合同编号
*/
@TableField(value = "contract_no")
private String contractNo;
/**
* 项目名称(用户填写的)
*/
@TableField(value = "project_name")
private String projectName;
/**
* 联系人
*/
@TableField(value = "contact")
private String contact;
/**
* 手机号码
*/
@TableField(value = "phone")
private String phone;
/**
* 设备数量
*/
@TableField(value = "device_num")
private Integer deviceNum;
/**
* 收货地址
*/
@TableField(value = "shipping_address")
private String shippingAddress;
/**
* 收货联系人
*/
@TableField(value = "receiving_contact")
private String receivingContact;
/**
* 收货联系电话
*/
@TableField(value = "receiving_phone")
private String receivingPhone;
/**
* 发货日期
*/
@TableField(value = "ship_date")
private Date shipDate;
/**
* 快递公司
*/
@TableField(value = "courier_company")
private String courierCompany;
/**
* 快递单号
*/
@TableField(value = "tracking_number")
private String trackingNumber;
@TableField(value = "uuid")
private String uuid;
/**
* 微信openid
*/
@TableField(value = "openid")
private String openid;
/**
* 备注
*/
@TableField(value = "remark")
private String remark;
@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
...@@ -61,6 +61,12 @@ public class SettlementDiff { ...@@ -61,6 +61,12 @@ public class SettlementDiff {
private Long operator; private Long operator;
/** /**
* 备注
*/
@TableField(value = "remark")
private String remark;
/**
* 创建时间 * 创建时间
*/ */
@TableField(value = "create_time", fill = FieldFill.INSERT) @TableField(value = "create_time", fill = FieldFill.INSERT)
......
package vion.model;
import com.baomidou.mybatisplus.annotation.*;
import io.github.linpeilie.annotations.AutoMapper;
import io.github.linpeilie.annotations.AutoMappers;
import lombok.Data;
import vion.dto.SparePartDTO;
import vion.vo.SparePartVO;
import java.util.Date;
/**
* @author HlQ
* @date 2024/1/19
*/
@Data
@TableName(value = "tbl_spare_part")
@AutoMappers({
@AutoMapper(target = SparePartVO.class),
@AutoMapper(target = SparePartDTO.class),
})
public class SparePart {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 集团id
*/
@TableField(value = "account_id")
private Long accountId;
/**
* 项目id
*/
@TableField(value = "store_id")
private Long storeId;
/**
* 合同id
*/
@TableField(value = "contract_id")
private Long contractId;
/**
* 合同编号
*/
@TableField(value = "contract_no")
private String contractNo;
/**
* 项目名称(用户填写的)
*/
@TableField(value = "project_name")
private String projectName;
/**
* 联系人
*/
@TableField(value = "contact")
private String contact;
/**
* 手机号码
*/
@TableField(value = "phone")
private String phone;
/**
* 设备数量
*/
@TableField(value = "device_num")
private Integer deviceNum;
/**
* 收货地址
*/
@TableField(value = "shipping_address")
private String shippingAddress;
/**
* 收货联系人
*/
@TableField(value = "receiving_contact")
private String receivingContact;
/**
* 收货联系电话
*/
@TableField(value = "receiving_phone")
private String receivingPhone;
/**
* 发货日期
*/
@TableField(value = "ship_date")
private Date shipDate;
/**
* 快递公司
*/
@TableField(value = "courier_company")
private String courierCompany;
/**
* 快递单号
*/
@TableField(value = "tracking_number")
private String trackingNumber;
/**
* 备注
*/
@TableField(value = "remark")
private String remark;
/**
* uuid
*/
@TableField(value = "uuid")
private String uuid;
/** 微信用户id */
@TableField(value = "openid")
private String openid;
@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
...@@ -14,6 +14,8 @@ public interface IPaymentService extends MPJBaseService<Payment> { ...@@ -14,6 +14,8 @@ public interface IPaymentService extends MPJBaseService<Payment> {
String save(List<PaymentDTO> dto); String save(List<PaymentDTO> dto);
String update(Long id, PaymentDTO dto);
String delById(Long id, String contractNo); String delById(Long id, String contractNo);
} }
package vion.service;
import com.github.yulichang.base.MPJBaseService;
import vion.model.RRepairDevice;
/**
* @author HlQ
* @date 2024/1/25
*/
public interface IRRepairDeviceService extends MPJBaseService<RRepairDevice> {
}
package vion.service;
import com.github.yulichang.base.MPJBaseService;
import vion.dto.RepairRecDTO;
import vion.model.RepairRec;
import vion.vo.RepairRecVO;
import java.util.List;
/**
* @author HlQ
* @date 2024/1/19
*/
public interface IRepairRecService extends MPJBaseService<RepairRec> {
Object frontSubmit(RepairRecDTO dto);
List<RepairRecVO> list(RepairRecDTO dto);
RepairRecVO getRepairRecDetail(Long id, String uuid);
String updById(Long id, RepairRecDTO dto);
}
package vion.service;
import com.github.yulichang.base.MPJBaseService;
import vion.dto.SparePartDTO;
import vion.model.SparePart;
import vion.vo.SparePartVO;
import java.util.List;
/**
* @author HlQ
* @date 2024/1/19
*/
public interface ISparePartService extends MPJBaseService<SparePart> {
Object frontSubmit(SparePartDTO dto);
List<SparePartVO> list(SparePartDTO dto);
SparePartVO getSparePartDetail(Long id, String uuid);
String updById(Long id, SparePartDTO dto);
}
...@@ -41,6 +41,7 @@ public class ContractPaymentServiceImpl extends MPJBaseServiceImpl<ContractPayme ...@@ -41,6 +41,7 @@ public class ContractPaymentServiceImpl extends MPJBaseServiceImpl<ContractPayme
List<SettlementDiff> diffList = settlementDiffMapper.selectList(Wrappers.<SettlementDiff>lambdaQuery().eq(SettlementDiff::getContractId, existContract.getId())); List<SettlementDiff> diffList = settlementDiffMapper.selectList(Wrappers.<SettlementDiff>lambdaQuery().eq(SettlementDiff::getContractId, existContract.getId()));
BigDecimal diffAmount1 = diffList.stream().filter(diff -> diff.getOffsetItem() == 1).map(SettlementDiff::getSettlementDiff).reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal diffAmount1 = diffList.stream().filter(diff -> diff.getOffsetItem() == 1).map(SettlementDiff::getSettlementDiff).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal diffAmount2 = diffList.stream().filter(diff -> diff.getOffsetItem() == 2).map(SettlementDiff::getSettlementDiff).reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal diffAmount2 = diffList.stream().filter(diff -> diff.getOffsetItem() == 2).map(SettlementDiff::getSettlementDiff).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal diffAmount3 = diffList.stream().filter(diff -> diff.getOffsetItem() == 3).map(SettlementDiff::getSettlementDiff).reduce(BigDecimal.ZERO, BigDecimal::add);
Map<Integer, BigDecimal> type2RatioMap = contractPaymentList.stream().collect(Collectors.toMap(ContractPayment::getPaymentType, ContractPayment::getPaymentRatio)); Map<Integer, BigDecimal> type2RatioMap = contractPaymentList.stream().collect(Collectors.toMap(ContractPayment::getPaymentType, ContractPayment::getPaymentRatio));
Integer status = dto.getStatus() == null ? existContract.getStatus() : dto.getStatus(); Integer status = dto.getStatus() == null ? existContract.getStatus() : dto.getStatus();
...@@ -49,11 +50,11 @@ public class ContractPaymentServiceImpl extends MPJBaseServiceImpl<ContractPayme ...@@ -49,11 +50,11 @@ public class ContractPaymentServiceImpl extends MPJBaseServiceImpl<ContractPayme
BigDecimal ratio = type2RatioMap.get(i); BigDecimal ratio = type2RatioMap.get(i);
sumRatio = NumberUtil.add(ratio, sumRatio); sumRatio = NumberUtil.add(ratio, sumRatio);
} }
BigDecimal totalAmount = NumberUtil.add(existContract.getTotalAmount(), diffAmount1); BigDecimal totalAmount = existContract.getTotalAmount();
BigDecimal curAmount = NumberUtil.mul(totalAmount, sumRatio); BigDecimal curAmount = NumberUtil.mul(totalAmount, sumRatio);
BigDecimal paidAmount = ObjUtil.isNull(dto.getPaidAmount()) ? existContract.getPaidAmount() : dto.getPaidAmount(); BigDecimal paidAmount = ObjUtil.isNull(dto.getPaidAmount()) ? existContract.getPaidAmount() : dto.getPaidAmount();
BigDecimal recAmount = NumberUtil.add(NumberUtil.sub(curAmount, paidAmount), diffAmount2); BigDecimal recAmount = NumberUtil.add(NumberUtil.add(NumberUtil.sub(curAmount, paidAmount), diffAmount2), diffAmount3);
BigDecimal outsideAmount = NumberUtil.sub(totalAmount, paidAmount); BigDecimal outsideAmount = NumberUtil.add(NumberUtil.add(NumberUtil.sub(totalAmount, paidAmount), diffAmount1), diffAmount3);
dto.setReceivableAmount(recAmount); dto.setReceivableAmount(recAmount);
dto.setOutstandingAmount(outsideAmount); dto.setOutstandingAmount(outsideAmount);
} }
......
...@@ -28,6 +28,7 @@ import org.springframework.transaction.annotation.Transactional; ...@@ -28,6 +28,7 @@ import org.springframework.transaction.annotation.Transactional;
import vion.dto.ContractDTO; import vion.dto.ContractDTO;
import vion.dto.RContractTeamDTO; import vion.dto.RContractTeamDTO;
import vion.mapper.ContractMapper; import vion.mapper.ContractMapper;
import vion.mapper.SettlementDiffMapper;
import vion.model.*; import vion.model.*;
import vion.service.*; import vion.service.*;
import vion.third.DingMod; import vion.third.DingMod;
...@@ -54,6 +55,8 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont ...@@ -54,6 +55,8 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
private final IContractLogService contractLogService; private final IContractLogService contractLogService;
private final IRContractTeamService contractTeamService; private final IRContractTeamService contractTeamService;
private final IRContractUserService contractUserService; private final IRContractUserService contractUserService;
// 引入 settlementDiffService 会循环依赖
private final SettlementDiffMapper settlementDiffMapper;
private final DingMod dingMod; private final DingMod dingMod;
private final Converter converter; private final Converter converter;
...@@ -66,6 +69,20 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont ...@@ -66,6 +69,20 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
Page<ContractVO> contractVOList = this.selectJoinListPage(Page.of(dto.getPageNum(), dto.getPageSize()), ContractVO.class, result.wrapper); Page<ContractVO> contractVOList = this.selectJoinListPage(Page.of(dto.getPageNum(), dto.getPageSize()), ContractVO.class, result.wrapper);
Opt.ofEmptyAble(settlementDiffMapper.selectList(Wrappers.<SettlementDiff>lambdaQuery()
.in(CollUtil.isNotEmpty(contractVOList.getRecords()), SettlementDiff::getContractId, contractVOList.getRecords().stream().map(ContractVO::getId).collect(Collectors.toList()))))
.map(list -> list.stream().collect(Collectors.groupingBy(SettlementDiff::getContractId, Collectors.reducing(BigDecimal.ZERO, SettlementDiff::getSettlementDiff, BigDecimal::add))))
.ifPresent(map -> contractVOList.getRecords().forEach(vo -> vo.setDiffAmount(map.getOrDefault(vo.getId(), BigDecimal.ZERO))));
Opt.ofEmptyAble(contractUserService.lambdaQuery()
.in(CollUtil.isNotEmpty(contractVOList.getRecords()), RContractUser::getContractId, contractVOList.getRecords().stream().map(ContractVO::getId).collect(Collectors.toList()))
.list())
.map(list -> list.stream().collect(Collectors.groupingBy(RContractUser::getContractId)))
.ifPresent(map -> contractVOList.getRecords().forEach(vo -> map.getOrDefault(vo.getId(), ListUtil.empty()).stream()
.max(Comparator.comparing(RContractUser::getEnterDate))
.map(RContractUser::getUsername)
.ifPresent(vo::setSaleName)));
if (!result.roleCodeList.contains("admin") && !result.roleCodeList.contains("xiaoshou") && !result.roleCodeList.contains("caiwu")) { if (!result.roleCodeList.contains("admin") && !result.roleCodeList.contains("xiaoshou") && !result.roleCodeList.contains("caiwu")) {
contractVOList.getRecords().forEach(vo -> { contractVOList.getRecords().forEach(vo -> {
vo.setTotalAmount(null); vo.setTotalAmount(null);
...@@ -73,6 +90,7 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont ...@@ -73,6 +90,7 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
vo.setReceivableAmount(null); vo.setReceivableAmount(null);
vo.setOutstandingAmount(null); vo.setOutstandingAmount(null);
vo.setInvoiceAmount(null); vo.setInvoiceAmount(null);
vo.setDiffAmount(null);
}); });
} }
completeStoreName(contractVOList.getRecords()); completeStoreName(contractVOList.getRecords());
...@@ -175,41 +193,50 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont ...@@ -175,41 +193,50 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
Contract contract = converter.convert(dto, Contract.class); Contract contract = converter.convert(dto, Contract.class);
Long contractId = existContract.getId(); Long contractId = existContract.getId();
String existContractNo = existContract.getContractNo();
contract.setId(contractId); contract.setId(contractId);
contractPaymentService.calMoney(existContract, contract); contractPaymentService.calMoney(existContract, contract);
if (this.updateById(contract)) { if (this.updateById(contract)) {
Opt.ofNullable(dto.getNodeDate()) Opt.ofNullable(dto.getNodeDate())
.ifPresent(date -> { .ifPresent(date -> contractPaymentService.lambdaUpdate()
contractPaymentService.lambdaUpdate() .set(ContractPayment::getNodeDate, date)
.set(ContractPayment::getPaymentDate, date) .eq(ContractPayment::getContractId, contractId)
.eq(ContractPayment::getContractId, contractId) .eq(ContractPayment::getPaymentType, dto.getStatus())
.eq(ContractPayment::getPaymentType, dto.getStatus()) .update(new ContractPayment()));
.update(new ContractPayment());
});
UserVO userVO = (UserVO) StpUtil.getTokenSession().get("curLoginUser"); UserVO userVO = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
Contract finalExistContract = existContract;
ContractLog contractLog = new ContractLog(); Opt.ofNullable(dto.getStatus())
contractLog.setContractNo(existContract.getContractNo()); .ifPresent(status -> {
if (dto.getStatus() == 1) { String useridStr = Opt.ofEmptyAble(contractUserService.lambdaQuery()
contractLog.setContent("合同:已签订"); .eq(RContractUser::getContractNo, existContractNo).list())
} else if (dto.getStatus() == 2) { .map(l -> l.stream().map(RContractUser::getContractNo).collect(Collectors.joining(",")))
contractLog.setContent("合同:已到货"); .orElse("");
} else if (dto.getStatus() == 3) {
contractLog.setContent("合同:系统验收"); ContractLog contractLog = new ContractLog();
} else if (dto.getStatus() == 4) { contractLog.setContractNo(existContractNo);
contractLog.setContent("合同:项目验收"); if (status == 1) {
} else if (dto.getStatus() == 5) { contractLog.setContent("合同:已签订");
contractLog.setContent("合同:质保"); } else if (status == 2) {
} else if (dto.getStatus() == 6) { contractLog.setContent("合同:已到货");
contractLog.setContent("合同:第一笔维保款"); } else if (status == 3) {
} else if (dto.getStatus() == 7) { contractLog.setContent("合同:系统验收");
contractLog.setContent("合同:第二笔维保款"); dingMod.workMsg(buildMsg(useridStr, dto, finalExistContract, "系统验收(初验)"));
} else if (dto.getStatus() == 8) { } else if (status == 4) {
contractLog.setContent("合同:第三笔维保款"); contractLog.setContent("合同:项目验收");
} dingMod.workMsg(buildMsg(useridStr, dto, finalExistContract, "项目验收(终验)"));
contractLog.setOperator(userVO.getId()); } else if (status == 5) {
contractLogService.save(contractLog); contractLog.setContent("合同:质保");
} else if (status == 6) {
contractLog.setContent("合同:第一笔维保款");
} else if (status == 7) {
contractLog.setContent("合同:第二笔维保款");
} else if (status == 8) {
contractLog.setContent("合同:第三笔维保款");
}
contractLog.setOperator(userVO.getId());
contractLogService.save(contractLog);
});
Opt.ofNullable(dto.getFiles()) Opt.ofNullable(dto.getFiles())
.ifPresent(fileList -> .ifPresent(fileList ->
...@@ -499,6 +526,29 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont ...@@ -499,6 +526,29 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
return jsonObj; return jsonObj;
} }
JSONObject buildMsg(String userid, ContractDTO dto, Contract contract, String statusStr) {
JSONObject jsonObj = new JSONObject();
jsonObj.set("agent_id", 2358374016L);
jsonObj.set("userid_list", userid);
JSONObject msg = new JSONObject();
JSONObject content = new JSONObject();
content.set("title", "验收提醒");
String markdown = StrUtil.format("#### 验收提醒" +
" \n #### 合同编号:**{}**" +
" \n #### 合同名称:**{}**" +
" \n #### 状态:{}" +
" \n #### 验收时间:{}" +
" \n #### 发送时间:{}",
contract.getContractNo(), contract.getName(), statusStr, DateUtil.formatDate(dto.getNodeDate()), DateUtil.now());
content.set("text", markdown);
msg.set("msgtype", "markdown");
msg.set("markdown", content);
jsonObj.set("msg", msg);
return jsonObj;
}
private static class Result { private static class Result {
public final Set<String> roleCodeList; public final Set<String> roleCodeList;
public final MPJLambdaWrapper<Contract> wrapper; public final MPJLambdaWrapper<Contract> wrapper;
......
...@@ -17,7 +17,6 @@ import io.github.linpeilie.Converter; ...@@ -17,7 +17,6 @@ import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import vion.dto.ContractDTO; import vion.dto.ContractDTO;
import vion.dto.DeliveryRecordDTO; import vion.dto.DeliveryRecordDTO;
...@@ -47,9 +46,9 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord ...@@ -47,9 +46,9 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord
private final IFileService fileService; private final IFileService fileService;
private final IContractService contractService; private final IContractService contractService;
private final IRContractUserService contractUserService; private final IRContractUserService contractUserService;
private final IContractPaymentService contractPaymentService;
private final IPointInfoService pointInfoService; private final IPointInfoService pointInfoService;
private final DingMod dingMod; private final DingMod dingMod;
private final RedisTemplate redisTemplate;
private final Converter converter; private final Converter converter;
@Value("${fileUrl:}") @Value("${fileUrl:}")
...@@ -125,6 +124,11 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord ...@@ -125,6 +124,11 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord
log.error("根据发货记录,更新合同状态出错,该合同不存在:{}", record.getContractNo()); log.error("根据发货记录,更新合同状态出错,该合同不存在:{}", record.getContractNo());
} }
if (existContract.getStatus() < 2) { if (existContract.getStatus() < 2) {
// todo 发货后,更新对应合同的付款的节点时间字段 合同id获取不到
/*contractPaymentService.lambdaUpdate()
.set(ContractPayment::getNodeDate, record.getShipDate())
.eq(ContractPayment::getContractId, )
.update(new ContractPayment());*/
contractService.updateById(null, record.getContractNo(), contractDTO); contractService.updateById(null, record.getContractNo(), contractDTO);
} }
// 更新点位信息的发货状态 // 更新点位信息的发货状态
...@@ -138,9 +142,6 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord ...@@ -138,9 +142,6 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord
.ifPresent(p -> pointInfoService.designPush(null, p, "发货")); .ifPresent(p -> pointInfoService.designPush(null, p, "发货"));
List<String> useridList = contractUserService.listObjs(Wrappers.<RContractUser>lambdaQuery().select(RContractUser::getUserId).eq(RContractUser::getContractId, existContract.getId()), Object::toString); List<String> useridList = contractUserService.listObjs(Wrappers.<RContractUser>lambdaQuery().select(RContractUser::getUserId).eq(RContractUser::getContractId, existContract.getId()), Object::toString);
Opt.ofNullable(((User) redisTemplate.opsForValue().get("dingtalk:user:name:" + existContract.getSaleName())))
.map(User::getUserid)
.ifPresent(useridList::add);
dingMod.workMsg(buildMsg(useridList.stream().distinct().collect(Collectors.joining(",")), record, existContract)); dingMod.workMsg(buildMsg(useridList.stream().distinct().collect(Collectors.joining(",")), record, existContract));
} }
...@@ -153,8 +154,8 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord ...@@ -153,8 +154,8 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord
JSONObject content = new JSONObject(); JSONObject content = new JSONObject();
content.set("title", "设备发货提醒"); content.set("title", "设备发货提醒");
String markdown = StrUtil.format("#### 发货通知" + String markdown = StrUtil.format("#### 发货通知" +
" \n #### 合同名称:{}" + " \n #### 合同名称:**{}**" +
" \n #### 合同编号:{}" + " \n #### 合同编号:**{}**" +
" \n #### 快递公司:{}" + " \n #### 快递公司:{}" +
" \n #### 快递单号:{}" + " \n #### 快递单号:{}" +
" \n #### 收件人:{}" + " \n #### 收件人:{}" +
......
package vion.service.impl; package vion.service.impl;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Opt; import cn.hutool.core.lang.Opt;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl; import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.github.yulichang.wrapper.MPJLambdaWrapper;
...@@ -15,15 +20,20 @@ import vion.dto.InvoiceDTO; ...@@ -15,15 +20,20 @@ import vion.dto.InvoiceDTO;
import vion.mapper.InvoiceMapper; import vion.mapper.InvoiceMapper;
import vion.model.Contract; import vion.model.Contract;
import vion.model.Invoice; import vion.model.Invoice;
import vion.model.RContractUser;
import vion.service.IContractService; import vion.service.IContractService;
import vion.service.IInvoiceService; import vion.service.IInvoiceService;
import vion.service.IRContractUserService;
import vion.third.DingMod;
import vion.vo.InvoiceVO; import vion.vo.InvoiceVO;
import vion.vo.RoleVO; import vion.vo.RoleVO;
import vion.vo.UserVO; import vion.vo.UserVO;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
...@@ -35,6 +45,8 @@ import java.util.stream.Collectors; ...@@ -35,6 +45,8 @@ import java.util.stream.Collectors;
public class InvoiceServiceImpl extends MPJBaseServiceImpl<InvoiceMapper, Invoice> implements IInvoiceService { public class InvoiceServiceImpl extends MPJBaseServiceImpl<InvoiceMapper, Invoice> implements IInvoiceService {
private final IContractService contractService; private final IContractService contractService;
private final IRContractUserService contractUserService;
private final DingMod dingMod;
private final Converter converter; private final Converter converter;
@Override @Override
...@@ -63,13 +75,69 @@ public class InvoiceServiceImpl extends MPJBaseServiceImpl<InvoiceMapper, Invoic ...@@ -63,13 +75,69 @@ public class InvoiceServiceImpl extends MPJBaseServiceImpl<InvoiceMapper, Invoic
public String save(List<InvoiceDTO> dto) { public String save(List<InvoiceDTO> dto) {
List<Invoice> invoiceList = converter.convert(dto, Invoice.class); List<Invoice> invoiceList = converter.convert(dto, Invoice.class);
this.saveBatch(invoiceList); this.saveBatch(invoiceList);
List<String> noList = invoiceList.stream().map(Invoice::getContractNo).collect(Collectors.toList());
Map<String, Contract> no2ContractMap = Opt.ofEmptyAble(contractService.lambdaQuery()
.in(Contract::getContractNo, noList).list())
.map(l -> l.stream().collect(Collectors.toMap(Contract::getContractNo, Function.identity())))
.orElse(MapUtil.empty());
Map<String, String> no2UseridMap = Opt.ofEmptyAble(contractUserService.lambdaQuery()
.in(RContractUser::getContractNo, noList).list())
.map(l -> l.stream().collect(Collectors.groupingBy(RContractUser::getContractNo, Collectors.mapping(RContractUser::getUserId, Collectors.joining(",")))))
.orElse(MapUtil.empty());
// 推送钉钉消息
invoiceList.forEach(i -> {
String contractNo = i.getContractNo();
Contract existContract = no2ContractMap.get(contractNo);
if (ObjUtil.isNull(existContract)) {
return;
}
Opt.ofBlankAble(no2UseridMap.get(contractNo))
.ifPresent(useridStr -> dingMod.workMsg(buildMsg(useridStr, i, existContract)));
});
Map<String, List<Invoice>> no2InvoiceMap = invoiceList.stream().collect(Collectors.groupingBy(Invoice::getContractNo)); Map<String, List<Invoice>> no2InvoiceMap = invoiceList.stream().collect(Collectors.groupingBy(Invoice::getContractNo));
List<String> failList = new ArrayList<>();
no2InvoiceMap.forEach((no, list) -> { no2InvoiceMap.forEach((no, list) -> {
BigDecimal sum = list.stream().map(Invoice::getInvoiceAmount).reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal sum = list.stream().map(Invoice::getInvoiceAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
// 根据合同编号查合同 // 根据合同编号查合同
Contract existContract = contractService.lambdaQuery().eq(Contract::getContractNo, no).one(); Contract existContract = no2ContractMap.get(no);
if (ObjUtil.isNull(existContract)) {
failList.add(no);
return;
}
contractService.lambdaUpdate().eq(Contract::getContractNo, no).set(Contract::getInvoiceAmount, NumberUtil.add(sum, existContract.getInvoiceAmount())).update(new Contract()); contractService.lambdaUpdate().eq(Contract::getContractNo, no).set(Contract::getInvoiceAmount, NumberUtil.add(sum, existContract.getInvoiceAmount())).update(new Contract());
}); });
if (CollUtil.isNotEmpty(failList)) {
return StrUtil.format("合同编号为{}的合同不存在", failList.toString());
}
return "成功"; return "成功";
} }
JSONObject buildMsg(String userid, Invoice invoice, Contract contract) {
JSONObject jsonObj = new JSONObject();
jsonObj.set("agent_id", 2358374016L);
jsonObj.set("userid_list", userid);
JSONObject msg = new JSONObject();
JSONObject content = new JSONObject();
content.set("title", "开票提醒");
String markdown = StrUtil.format("#### 开票提醒" +
" \n #### 合同编号:**{}**" +
" \n #### 合同名称:**{}**" +
" \n #### 发票编号:{}" +
" \n #### 发票金额:{}" +
" \n #### 开票时间:{}" +
" \n #### 备注:{}" +
" \n #### 发送时间:{}",
contract.getContractNo(), contract.getName(), invoice.getInvoiceNo(), invoice.getInvoiceAmount(), DateUtil.formatDate(invoice.getInvoicingTime()), invoice.getRemark(), DateUtil.now());
content.set("text", markdown);
msg.set("msgtype", "markdown");
msg.set("markdown", content);
jsonObj.set("msg", msg);
return jsonObj;
}
} }
...@@ -2,11 +2,14 @@ package vion.service.impl; ...@@ -2,11 +2,14 @@ package vion.service.impl;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
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.map.MapUtil;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
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.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl; import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.github.yulichang.wrapper.MPJLambdaWrapper;
...@@ -18,9 +21,12 @@ import vion.dto.PaymentDTO; ...@@ -18,9 +21,12 @@ import vion.dto.PaymentDTO;
import vion.mapper.PaymentMapper; import vion.mapper.PaymentMapper;
import vion.model.Contract; import vion.model.Contract;
import vion.model.Payment; import vion.model.Payment;
import vion.model.RContractUser;
import vion.service.IContractPaymentService; import vion.service.IContractPaymentService;
import vion.service.IContractService; import vion.service.IContractService;
import vion.service.IPaymentService; import vion.service.IPaymentService;
import vion.service.IRContractUserService;
import vion.third.DingMod;
import vion.vo.PaymentVO; import vion.vo.PaymentVO;
import vion.vo.RoleVO; import vion.vo.RoleVO;
import vion.vo.UserVO; import vion.vo.UserVO;
...@@ -29,6 +35,7 @@ import java.math.BigDecimal; ...@@ -29,6 +35,7 @@ import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
...@@ -41,6 +48,8 @@ public class PaymentServiceImpl extends MPJBaseServiceImpl<PaymentMapper, Paymen ...@@ -41,6 +48,8 @@ public class PaymentServiceImpl extends MPJBaseServiceImpl<PaymentMapper, Paymen
private final IContractService contractService; private final IContractService contractService;
private final IContractPaymentService contractPaymentService; private final IContractPaymentService contractPaymentService;
private final IRContractUserService contractUserService;
private final DingMod dingMod;
private final Converter converter; private final Converter converter;
@Override @Override
...@@ -79,6 +88,26 @@ public class PaymentServiceImpl extends MPJBaseServiceImpl<PaymentMapper, Paymen ...@@ -79,6 +88,26 @@ public class PaymentServiceImpl extends MPJBaseServiceImpl<PaymentMapper, Paymen
} }
}); });
List<String> noList = paymentList.stream().map(Payment::getContractNo).collect(Collectors.toList()); List<String> noList = paymentList.stream().map(Payment::getContractNo).collect(Collectors.toList());
Map<String, Contract> no2ContractMap = Opt.ofEmptyAble(contractService.lambdaQuery()
.in(Contract::getContractNo, noList).list())
.map(l -> l.stream().collect(Collectors.toMap(Contract::getContractNo, Function.identity())))
.orElse(MapUtil.empty());
Map<String, String> no2UseridMap = Opt.ofEmptyAble(contractUserService.lambdaQuery()
.in(RContractUser::getContractNo, noList).list())
.map(l -> l.stream().collect(Collectors.groupingBy(RContractUser::getContractNo, Collectors.mapping(RContractUser::getUserId, Collectors.joining(",")))))
.orElse(MapUtil.empty());
// 推送钉钉消息
paymentList.forEach(p -> {
String contractNo = p.getContractNo();
Contract existContract = no2ContractMap.get(contractNo);
if (ObjUtil.isNull(existContract)) {
return;
}
Opt.ofBlankAble(no2UseridMap.get(contractNo))
.ifPresent(useridStr -> dingMod.workMsg(buildMsg(useridStr, p, existContract)));
});
Map<String, List<Payment>> no2PaymentMap = this.lambdaQuery() Map<String, List<Payment>> no2PaymentMap = this.lambdaQuery()
.in(Payment::getContractNo, noList) .in(Payment::getContractNo, noList)
.list() .list()
...@@ -87,7 +116,7 @@ public class PaymentServiceImpl extends MPJBaseServiceImpl<PaymentMapper, Paymen ...@@ -87,7 +116,7 @@ public class PaymentServiceImpl extends MPJBaseServiceImpl<PaymentMapper, Paymen
no2PaymentMap.forEach((no, list) -> { no2PaymentMap.forEach((no, list) -> {
BigDecimal sumAmount = list.stream().map(Payment::getPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal sumAmount = list.stream().map(Payment::getPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
Contract existContract = contractService.lambdaQuery().eq(Contract::getContractNo, no).one(); Contract existContract = no2ContractMap.get(no);
if (ObjUtil.isNull(existContract)) { if (ObjUtil.isNull(existContract)) {
failList.add(no); failList.add(no);
return; return;
...@@ -98,6 +127,7 @@ public class PaymentServiceImpl extends MPJBaseServiceImpl<PaymentMapper, Paymen ...@@ -98,6 +127,7 @@ public class PaymentServiceImpl extends MPJBaseServiceImpl<PaymentMapper, Paymen
updDto.setPaidAmount(sumAmount); updDto.setPaidAmount(sumAmount);
contractPaymentService.calMoney(existContract, updDto); contractPaymentService.calMoney(existContract, updDto);
contractService.updateById(updDto); contractService.updateById(updDto);
}); });
if (CollUtil.isNotEmpty(failList)) { if (CollUtil.isNotEmpty(failList)) {
return StrUtil.format("合同编号为{}的合同不存在", failList.toString()); return StrUtil.format("合同编号为{}的合同不存在", failList.toString());
...@@ -106,6 +136,31 @@ public class PaymentServiceImpl extends MPJBaseServiceImpl<PaymentMapper, Paymen ...@@ -106,6 +136,31 @@ public class PaymentServiceImpl extends MPJBaseServiceImpl<PaymentMapper, Paymen
} }
@Override @Override
public String update(Long id, PaymentDTO dto) {
Payment payment = converter.convert(dto, Payment.class);
if (this.updateById(payment)) {
List<Payment> paymentList = this.lambdaQuery()
.in(Payment::getContractNo, dto.getContractNo())
.list();
BigDecimal sumAmount = paymentList.stream().map(Payment::getPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
Contract existContract = contractService.lambdaQuery().eq(Contract::getContractNo, dto.getContractNo()).one();
if (ObjUtil.isNull(existContract)) {
return "该合同编号对应的合同不存在,只更新已收款信息,合同相关金额无法更新";
}
// 最新的应收款去计算
Contract updDto = new Contract();
updDto.setId(existContract.getId());
updDto.setPaidAmount(sumAmount);
contractPaymentService.calMoney(existContract, updDto);
contractService.updateById(updDto);
return "更新成功";
}
return "更新失败";
}
@Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public String delById(Long id, String contractNo) { public String delById(Long id, String contractNo) {
Contract existContract = contractService.lambdaQuery().eq(Contract::getContractNo, contractNo).one(); Contract existContract = contractService.lambdaQuery().eq(Contract::getContractNo, contractNo).one();
...@@ -122,4 +177,28 @@ public class PaymentServiceImpl extends MPJBaseServiceImpl<PaymentMapper, Paymen ...@@ -122,4 +177,28 @@ public class PaymentServiceImpl extends MPJBaseServiceImpl<PaymentMapper, Paymen
contractService.updateById(updDto); contractService.updateById(updDto);
return "删除成功"; return "删除成功";
} }
JSONObject buildMsg(String userid, Payment payment, Contract contract) {
JSONObject jsonObj = new JSONObject();
jsonObj.set("agent_id", 2358374016L);
jsonObj.set("userid_list", userid);
JSONObject msg = new JSONObject();
JSONObject content = new JSONObject();
content.set("title", "收款提醒");
String markdown = StrUtil.format("#### 收款提醒" +
" \n #### 合同编号:**{}**" +
" \n #### 合同名称:**{}**" +
" \n #### 收款金额:{}" +
" \n #### 收款时间:{}" +
" \n #### 备注:{}" +
" \n #### 发送时间:{}",
contract.getContractNo(), contract.getName(), payment.getPaymentAmount(), DateUtil.formatDate(payment.getCollectionTime()), payment.getRemark(), DateUtil.now());
content.set("text", markdown);
msg.set("msgtype", "markdown");
msg.set("markdown", 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.RRepairDeviceMapper;
import vion.model.RRepairDevice;
import vion.service.IRRepairDeviceService;
/**
* @author HlQ
* @date 2024/1/25
*/
@Service
public class RRepairDeviceServiceImpl extends MPJBaseServiceImpl<RRepairDeviceMapper, RRepairDevice> implements IRRepairDeviceService {
}
package vion.service.impl;
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.IdUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import vion.dto.RepairRecDTO;
import vion.mapper.RepairRecMapper;
import vion.model.*;
import vion.service.IFileService;
import vion.service.IRepairRecService;
import vion.vo.RepairRecVO;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
* @author HlQ
* @date 2024/1/19
*/
@Service
@RequiredArgsConstructor
public class RepairRecServiceImpl extends MPJBaseServiceImpl<RepairRecMapper, RepairRec> implements IRepairRecService {
private final IFileService fileService;
private final Converter converter;
@Value("${fileUrl:}")
private String fileUrl;
@Override
public Object frontSubmit(RepairRecDTO dto) {
dto.setUuid(IdUtil.nanoId());
RepairRec repairRec = converter.convert(dto, RepairRec.class);
if (this.save(repairRec)) {
Opt.ofNullable(dto.getFiles())
.ifPresent(fileList ->
Arrays.stream(fileList).forEach(infile -> {
//上传url地址
String orgName = infile.getOriginalFilename();
String mainName = FileUtil.mainName(orgName);
String fileExt = FileUtil.extName(orgName);
String filename = StrUtil.format("{}_{}.{}", mainName, DateUtil.format(new Date(), "yyyyMMdd_HHmmssSSS"), fileExt);
String path = fileUrl + FileUtil.FILE_SEPARATOR + "repairRec" + FileUtil.FILE_SEPARATOR + repairRec.getId() + FileUtil.FILE_SEPARATOR + filename;
File file = FileUtil.touch(path);
try {
infile.transferTo(file);
} catch (IOException e) {
log.error("保存文件出错", e);
}
FileInfo fileInfo = new FileInfo();
fileInfo.setStoreId(-1L);
fileInfo.setSourceId(repairRec.getId());
fileInfo.setSourceType(23);
fileInfo.setName(filename);
fileInfo.setUrl(path);
fileInfo.setType(fileExt);
fileInfo.setSha256(SecureUtil.sha256(file).toUpperCase());
fileInfo.setUploader(repairRec.getContact());
fileService.save(fileInfo);
}));
return MapUtil.<String, Long>builder()
.put("id", repairRec.getId())
.build();
}
return "提交失败";
}
@Override
public List<RepairRecVO> list(RepairRecDTO dto) {
MPJLambdaWrapper<RepairRec> wrapper = new MPJLambdaWrapper<>(converter.convert(dto, RepairRec.class))
.selectAll(RepairRec.class)
.selectAs(Contract::getName, RepairRecVO::getContractName)
.selectCollection(RRepairDevice.class, RepairRecVO::getRepairDeviceList)
.leftJoin(Contract.class, Contract::getId, RepairRec::getContractId)
.leftJoin(RRepairDevice.class, on -> on.eq(RRepairDevice::getRId, RepairRec::getId).eq(RRepairDevice::getRType, 2))
.between(RepairRec::getCreateTime, dto.getCreateTimeStart(), dto.getCreateTimeEnd())
.orderByDesc(RepairRec::getCreateTime);
return this.selectJoinList(RepairRecVO.class, wrapper);
}
@Override
public RepairRecVO getRepairRecDetail(Long id, String uuid) {
MPJLambdaWrapper<RepairRec> wrapper = new MPJLambdaWrapper<RepairRec>()
.selectAll(PointInfo.class)
.eq(ObjUtil.isNotEmpty(id), RepairRec::getId, id)
.eq(StrUtil.isNotBlank(uuid), RepairRec::getUuid, uuid)
.orderByDesc(PointInfo::getCreateTime);
return this.selectJoinOne(RepairRecVO.class, wrapper);
}
@Override
public String updById(Long id, RepairRecDTO dto) {
return this.updateById(converter.convert(dto, RepairRec.class)) ? "更新成功" : "更新失败";
}
}
package vion.service.impl;
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.IdUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import vion.dto.SparePartDTO;
import vion.mapper.SparePartMapper;
import vion.model.*;
import vion.service.IFileService;
import vion.service.ISparePartService;
import vion.vo.SparePartVO;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
* @author HlQ
* @date 2024/1/19
*/
@Service
@RequiredArgsConstructor
public class SparePartServiceImpl extends MPJBaseServiceImpl<SparePartMapper, SparePart> implements ISparePartService {
private final IFileService fileService;
private final Converter converter;
@Value("${fileUrl:}")
private String fileUrl;
@Override
public Object frontSubmit(SparePartDTO dto) {
dto.setUuid(IdUtil.nanoId());
SparePart sparePart = converter.convert(dto, SparePart.class);
if (this.save(sparePart)) {
Opt.ofNullable(dto.getFiles())
.ifPresent(fileList ->
Arrays.stream(fileList).forEach(infile -> {
//上传url地址
String orgName = infile.getOriginalFilename();
String mainName = FileUtil.mainName(orgName);
String fileExt = FileUtil.extName(orgName);
String filename = StrUtil.format("{}_{}.{}", mainName, DateUtil.format(new Date(), "yyyyMMdd_HHmmssSSS"), fileExt);
String path = fileUrl + FileUtil.FILE_SEPARATOR + "sparePart" + FileUtil.FILE_SEPARATOR + sparePart.getId() + FileUtil.FILE_SEPARATOR + filename;
File file = FileUtil.touch(path);
try {
infile.transferTo(file);
} catch (IOException e) {
log.error("保存文件出错", e);
}
FileInfo fileInfo = new FileInfo();
fileInfo.setStoreId(-1L);
fileInfo.setSourceId(sparePart.getId());
fileInfo.setSourceType(22);
fileInfo.setName(filename);
fileInfo.setUrl(path);
fileInfo.setType(fileExt);
fileInfo.setSha256(SecureUtil.sha256(file).toUpperCase());
fileInfo.setUploader(sparePart.getContact());
fileService.save(fileInfo);
}));
return MapUtil.<String, Long>builder()
.put("id", sparePart.getId())
.build();
}
return "提交失败";
}
@Override
public List<SparePartVO> list(SparePartDTO dto) {
MPJLambdaWrapper<SparePart> wrapper = new MPJLambdaWrapper<>(converter.convert(dto, SparePart.class))
.selectAll(SparePart.class)
.selectAs(Contract::getName, SparePartVO::getContractName)
.selectCollection(RRepairDevice.class, SparePartVO::getRepairDeviceList)
.leftJoin(Contract.class, Contract::getId, SparePart::getContractId)
.leftJoin(RRepairDevice.class, on -> on.eq(RRepairDevice::getRId, SparePart::getId).eq(RRepairDevice::getRType, 1))
.between(SparePart::getCreateTime, dto.getCreateTimeStart(), dto.getCreateTimeEnd())
.orderByDesc(SparePart::getCreateTime);
return this.selectJoinList(SparePartVO.class, wrapper);
}
@Override
public SparePartVO getSparePartDetail(Long id, String uuid) {
MPJLambdaWrapper<SparePart> wrapper = new MPJLambdaWrapper<SparePart>()
.selectAll(PointInfo.class)
.eq(ObjUtil.isNotEmpty(id), SparePart::getId, id)
.eq(StrUtil.isNotBlank(uuid), SparePart::getUuid, uuid)
.orderByDesc(PointInfo::getCreateTime);
return this.selectJoinOne(SparePartVO.class, wrapper);
}
@Override
public String updById(Long id, SparePartDTO dto) {
return this.updateById(converter.convert(dto, SparePart.class)) ? "更新成功" : "更新失败";
}
}
...@@ -20,6 +20,7 @@ import io.github.linpeilie.Converter; ...@@ -20,6 +20,7 @@ import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import vion.dto.TaskDTO; import vion.dto.TaskDTO;
...@@ -52,6 +53,7 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem ...@@ -52,6 +53,7 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
private final DingMod dingMod; private final DingMod dingMod;
private final WechatMod wechatMod; private final WechatMod wechatMod;
private final Converter converter; private final Converter converter;
private final RedisTemplate redisTemplate;
@Value("${fileUrl:}") @Value("${fileUrl:}")
private String fileUrl; private String fileUrl;
...@@ -161,6 +163,11 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem ...@@ -161,6 +163,11 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
.set(TaskTemp::getStoreId, data.getStoreId()) .set(TaskTemp::getStoreId, data.getStoreId())
.eq(TaskTemp::getId, data.getTaskTempId()) .eq(TaskTemp::getId, data.getTaskTempId())
.update(new TaskTemp()); .update(new TaskTemp());
Store store = storeService.getById(data.getStoreId());
Opt.ofNullable((User) redisTemplate.opsForValue().get("dingtalk:user:id:" + store.getSalesperson()))
.map(User::getUserid)
.ifPresent(userid -> dingMod.workMsg(buildMsg2(userid, store.getName(), data)));
} }
} }
...@@ -382,4 +389,26 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem ...@@ -382,4 +389,26 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
jsonObj.set("msg", msg); jsonObj.set("msg", msg);
return jsonObj; return jsonObj;
} }
JSONObject buildMsg2(String userid, String storeName, TaskDTO dto) {
JSONObject jsonObj = new JSONObject();
jsonObj.set("agent_id", 2358374016L);
jsonObj.set("userid_list", userid);
JSONObject msg = new JSONObject();
JSONObject content = new JSONObject();
content.set("title", "工单消息提醒");
String markdown = StrUtil.format("#### 门店信息: **{}**" +
" \n #### 报修人:{}" +
" \n #### 联系方式:{}" +
" \n #### 故障描述:{}" +
" \n #### 发送时间:{}",
storeName, dto.getRepairPeople(), dto.getRepairPhone(), dto.getFaultDescription(), DateUtil.now());
content.set("text", markdown);
msg.set("msgtype", "markdown");
msg.set("markdown", content);
jsonObj.set("msg", msg);
return jsonObj;
}
} }
...@@ -72,6 +72,8 @@ public class WechatMod { ...@@ -72,6 +72,8 @@ public class WechatMod {
* 关注公众号的用户,直接获取 openid,返回前端,前端提交工单(或其他单子)时带上 openid。 * 关注公众号的用户,直接获取 openid,返回前端,前端提交工单(或其他单子)时带上 openid。
* 未关注公众号的用户,直接返回一个页面,提示用户关注公众号。 * 未关注公众号的用户,直接返回一个页面,提示用户关注公众号。
* *
* @param id 提交单子的主键id
* @param flag 1:故障保修 2:点位设计 3:备件申请 4:设备返修
* @param code 授权码 * @param code 授权码
* @return java.lang.Object * @return java.lang.Object
*/ */
......
...@@ -88,6 +88,12 @@ public class ContractVO { ...@@ -88,6 +88,12 @@ public class ContractVO {
private BigDecimal outstandingAmount; private BigDecimal outstandingAmount;
/** /**
* 结算差异
*/
@ExcelColumn(order = 13, title = "结算差异")
private BigDecimal diffAmount;
/**
* 合同签订主体 * 合同签订主体
*/ */
private String subject; private String subject;
...@@ -95,7 +101,7 @@ public class ContractVO { ...@@ -95,7 +101,7 @@ public class ContractVO {
/** /**
* 合同甲方名称 * 合同甲方名称
*/ */
@ExcelColumn(order = 14, title = "甲方名称") @ExcelColumn(order = 15, title = "甲方名称")
private String customerName; private String customerName;
/** /**
...@@ -150,7 +156,7 @@ public class ContractVO { ...@@ -150,7 +156,7 @@ public class ContractVO {
/** /**
* 开票金额 * 开票金额
*/ */
@ExcelColumn(order = 13, title = "已开票") @ExcelColumn(order = 14, title = "已开票")
private BigDecimal invoiceAmount; private BigDecimal invoiceAmount;
/** /**
......
package vion.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import vion.model.RRepairDevice;
import java.util.Date;
import java.util.List;
/**
* @author HlQ
* @date 2024/1/24
*/
@Getter
@Setter
public class RepairRecVO {
private Long id;
/**
* 集团id
*/
private Long accountId;
/**
* 项目id
*/
private Long storeId;
/**
* 合同id
*/
private Long contractId;
/**
* 合同编号
*/
private String contractNo;
/**
* 合同名称
*/
private String contractName;
/**
* 项目名称(用户填写的)
*/
private String projectName;
/**
* 联系人
*/
private String contact;
/**
* 手机号码
*/
private String phone;
/**
* 设备数量
*/
private Integer deviceNum;
/**
* 收货地址
*/
private String shippingAddress;
/**
* 收货联系人
*/
private String receivingContact;
/**
* 收货联系电话
*/
private String receivingPhone;
/**
* 发货日期
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date shipDate;
/**
* 快递公司
*/
private String courierCompany;
/**
* 快递单号
*/
private String trackingNumber;
private String uuid;
/**
* 微信openid
*/
private String openid;
/**
* 备注
*/
private String remark;
@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 updateTime;
private List<RRepairDevice> repairDeviceList;
}
\ No newline at end of file \ No newline at end of file
...@@ -43,6 +43,11 @@ public class SettlementDiffVO { ...@@ -43,6 +43,11 @@ public class SettlementDiffVO {
private Long operator; private Long operator;
/** /**
* 备注
*/
private String remark;
/**
* 创建时间 * 创建时间
*/ */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
......
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 com.github.liaochong.myexcel.core.annotation.MultiColumn;
import lombok.Getter;
import lombok.Setter;
import vion.model.RRepairDevice;
import java.util.Date;
import java.util.List;
/**
* @author HlQ
* @date 2024/1/19
*/
@Getter
@Setter
@ExcelModel(sheetName = "备件申请", includeAllField = false)
public class SparePartVO {
private Long id;
/**
* 集团id
*/
private Long accountId;
/**
* 项目id
*/
private Long storeId;
/**
* 合同id
*/
private Long contractId;
/**
* 合同编号
*/
@ExcelColumn(order = 1, title = "合同编号")
private String contractNo;
/**
* 合同名称
*/
@ExcelColumn(order = 2, title = "合同名称")
private String contractName;
/**
* 项目名称(用户填写的)
*/
@ExcelColumn(order = 0, title = "项目名称")
private String projectName;
/**
* 联系人
*/
@ExcelColumn(order = 3, title = "联系人")
private String contact;
/**
* 手机号码
*/
@ExcelColumn(order = 4, title = "电话")
private String phone;
/**
* 设备数量
*/
private Integer deviceNum;
/**
* 收货地址
*/
private String shippingAddress;
/**
* 收货联系人
*/
private String receivingContact;
/**
* 收货联系电话
*/
private String receivingPhone;
/**
* 发货日期
*/
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date shipDate;
/**
* 快递公司
*/
private String courierCompany;
/**
* 快递单号
*/
private String trackingNumber;
/**
* 备注
*/
private String remark;
/**
* uuid
*/
private String uuid;
/** 微信用户id */
private String openid;
@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 updateTime;
private List<RRepairDevice> repairDeviceList;
/**
* 设备信息
*/
@MultiColumn(classType = RRepairDevice.class)
private RRepairDevice rRepairDevice;
}
\ No newline at end of file \ No newline at end of file
debug=false debug=false
################################## DATABASE ######################################## ################################## DATABASE ########################################
spring.datasource.url=jdbc:postgresql://192.168.9.6:5432/vioncount6.0heze20201109 spring.datasource.url=jdbc:postgresql://pgm-2ze3cjpyjgjw0bl5uo.pg.rds.aliyuncs.com:1921/work-order
spring.datasource.username=postgres spring.datasource.username=vion
spring.datasource.password=vion spring.datasource.password=jkou72j32m4K5d8k
spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.driver-class-name=org.postgresql.Driver
server.port=8088 server.port=8088
\ No newline at end of file \ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!