Commit f1f3590c by HlQ

[add]

1.添加账龄分析、合同金额计算以及查询未关联项目的合同功能
2.合同、发票记录、收款记录添加数据权限
3.引入 Redis,token 数据存 Redis 并新增 token 过期时间刷新小功能

[chg] 项目维保状态计算逻辑修改
1 parent 81be82de
Showing 35 changed files with 457 additions and 304 deletions
调用 AppTest.updContractStatus() 方法不存在的合同
```
合同不存在:OPCWX18102401
合同不存在:2015-293
合同不存在:CSRP22065457
合同不存在:CSRS20050236
合同不存在:CSRP22040176
合同不存在:审批编号:202301111436000582807
合同不存在:201909002006
合同不存在:CSRS23085326
合同不存在:2019-206
合同不存在:CSRS20100978
合同不存在:CSRP22065504
合同不存在:SRS22010008
合同不存在:CSRP21073990
合同不存在:CSRS2203014
合同不存在:2016-284
合同不存在:2016-264
合同不存在:2016-269
合同不存在:2016-258
合同不存在:2016-206
合同不存在:2016-217
合同不存在:2017-400
合同不存在:CSRP21030720
合同不存在:CSRP20121316
合同不存在:CSRS20040124
合同不存在:CSRM210522733
合同不存在:CSGS20060534
合同不存在:2017-230
合同不存在:2017-208
合同不存在:CSRS20101007
合同不存在:CSRS22075490/CSRS22075468
合同不存在:CSRM22040183
合同不存在:2016-191
合同不存在:2016-181
合同不存在:2016-183
合同不存在:SCGP20080887
合同不存在:CSRM200121646
合同不存在:CSGI21094494
合同不存在:CSRP22085507
合同不存在:CSRP200040153
合同不存在:CSRS23034930
合同不存在:CSRM2100116
合同不存在:2014-270
合同不存在:2015-401
合同不存在:2017-008
合同不存在:WA20220607001
合同不存在:2019-453
合同不存在:CSRS20010002
合同不存在:20190900206
合同不存在:CSGP201221559
合同不存在:2017-173
合同不存在:CSSRP20111137
合同不存在:2017-147
合同不存在:2017-137
合同不存在:CSRP21052422
合同不存在:CSRP210501822
```
\ No newline at end of file \ No newline at end of file
...@@ -66,10 +66,24 @@ ...@@ -66,10 +66,24 @@
<version>4.5.0</version> <version>4.5.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>cn.dev33</groupId> <groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId> <artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.37.0</version> <version>1.37.0</version>
</dependency> </dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId>
<version>1.37.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>4.2.0</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
package vion;
import vion.vo.UserVO;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Global {
public static final String BASE_URL = "/api";
public static final String ACCOUNT_URL = "/api/account";
public static final String STORE_URL = "/api/store";
public static final String WORK_URL = "/api/work";
public static final String INSPECT_URL = "/api/inspect";
public static final Map<String, UserVO> USERNAME_MAP = new ConcurrentHashMap<>();
}
package vion.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.text.SimpleDateFormat;
/**
* @author HlQ
* @date 2023/12/19
*/
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
//我们为了自己开发方便,一般使用String , Object
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
//序列化配置
//jackson的序列化
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(om.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
// Date序列化 yyyy-MM-dd HH:mm:ss/yyyy-MM-dd hh:mm:ss:SSS
om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss:SSS"));
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
jackson2JsonRedisSerializer.setObjectMapper(om);
//String 的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
//hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
//value的序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
//hash的value也采用jackson的序列化方式
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
...@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; ...@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import vion.Global;
import vion.dto.BaseDTO; import vion.dto.BaseDTO;
import vion.model.Account; import vion.model.Account;
import vion.service.IAccountService; import vion.service.IAccountService;
...@@ -27,7 +26,7 @@ public class AccountController { ...@@ -27,7 +26,7 @@ public class AccountController {
@GetMapping("/account") @GetMapping("/account")
@SaCheckPermission(value = "account:query", orRole = "admin") @SaCheckPermission(value = "account:query", orRole = "admin")
public Account getProductById(Integer id) { public Account getAccountById(Integer id) {
return accountService.getById(id); return accountService.getById(id);
} }
......
...@@ -5,6 +5,7 @@ import cn.hutool.core.lang.Assert; ...@@ -5,6 +5,7 @@ import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Opt; import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
...@@ -109,6 +110,18 @@ public class ContractController { ...@@ -109,6 +110,18 @@ public class ContractController {
.list(); .list();
} }
@GetMapping("/contract/calAmount")
@SaCheckPermission(value = "contract:calAmount", orRole = "admin")
public JSONObject calAmount(ContractDTO dto) {
return contractService.calAmount(dto);
}
@GetMapping("/contract/analyze")
@SaCheckPermission(value = "contract:analyze", orRole = "admin")
public Object analyze(ContractDTO dto) {
return contractService.analyze(dto);
}
@PostMapping("/contractSync") @PostMapping("/contractSync")
@SaCheckPermission(value = "contract:sync", orRole = "admin") @SaCheckPermission(value = "contract:sync", orRole = "admin")
public String manualSyncContract() { public String manualSyncContract() {
......
...@@ -6,7 +6,6 @@ import io.github.linpeilie.Converter; ...@@ -6,7 +6,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.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import vion.Global;
import vion.dto.DictionaryDTO; import vion.dto.DictionaryDTO;
import vion.dto.DictionaryTypeDTO; import vion.dto.DictionaryTypeDTO;
import vion.model.Dictionary; import vion.model.Dictionary;
......
...@@ -6,7 +6,6 @@ import io.github.linpeilie.Converter; ...@@ -6,7 +6,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.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import vion.Global;
import vion.dto.InspectDTO; import vion.dto.InspectDTO;
import vion.model.Inspect; import vion.model.Inspect;
import vion.service.IInspectService; import vion.service.IInspectService;
......
package vion.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import vion.Global;
import vion.dto.ProductDTO;
import vion.model.Product;
import vion.service.IProductService;
import vion.vo.ProductVO;
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
@Slf4j
public class ProductController {
private final IProductService productService;
private final Converter converter;
@GetMapping("/products")
@SaCheckPermission(value = "product:list", orRole = "admin")
public Page<ProductVO> getProductList(ProductDTO productDTO) {
return productService.getProductList(productDTO);
}
@GetMapping("/product")
@SaCheckPermission(value = "product:query", orRole = "admin")
public Product getProductByID(@RequestParam Long projectId) {
return productService.getById(projectId);
}
@PostMapping("/products")
@SaCheckPermission(value = "product:editAndSave", orRole = "admin")
public String saveOrUpdate(@RequestBody ProductDTO productDTO) {
Product data = converter.convert(productDTO, new Product());
return productService.saveOrUpdate(data) ? "成功" : "失败";
}
}
\ No newline at end of file \ No newline at end of file
package vion.controller; package vion.controller;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
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 com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
...@@ -8,7 +9,6 @@ import io.github.linpeilie.Converter; ...@@ -8,7 +9,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.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import vion.Global;
import vion.dto.StatusDTO; import vion.dto.StatusDTO;
import vion.dto.StoreDTO; import vion.dto.StoreDTO;
import vion.model.Store; import vion.model.Store;
...@@ -54,8 +54,9 @@ public class StoreController { ...@@ -54,8 +54,9 @@ public class StoreController {
@PostMapping("/stores") @PostMapping("/stores")
@SaCheckPermission(value = "store:editAndSave", orRole = "admin") @SaCheckPermission(value = "store:editAndSave", orRole = "admin")
public String saveOrUpdate(@RequestBody StoreDTO data, @RequestHeader String token) { public String saveOrUpdate(@RequestBody StoreDTO data) {
UserVO user = Global.USERNAME_MAP.get(token); UserVO user = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
// 创建项目时,默认维保状态为 -- // 创建项目时,默认维保状态为 --
data.setMaintainStatus("--"); data.setMaintainStatus("--");
Store store = converter.convert(data, Store.class); Store store = converter.convert(data, Store.class);
......
...@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; ...@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import vion.Global;
import vion.dto.TaskDTO; import vion.dto.TaskDTO;
import vion.model.FaultLog; import vion.model.FaultLog;
import vion.service.IFaultLogService; import vion.service.IFaultLogService;
......
...@@ -6,7 +6,6 @@ import io.github.linpeilie.Converter; ...@@ -6,7 +6,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.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import vion.Global;
import vion.third.WechatMod; import vion.third.WechatMod;
import vion.dto.TaskTempDTO; import vion.dto.TaskTempDTO;
import vion.model.TaskTemp; import vion.model.TaskTemp;
......
...@@ -13,7 +13,6 @@ import lombok.RequiredArgsConstructor; ...@@ -13,7 +13,6 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
import vion.Global;
import vion.dto.DingDTO; import vion.dto.DingDTO;
import vion.dto.UserDTO; import vion.dto.UserDTO;
import vion.model.RUserRole; import vion.model.RUserRole;
...@@ -75,7 +74,7 @@ public class UserController { ...@@ -75,7 +74,7 @@ public class UserController {
@GetMapping("/user/{token}") @GetMapping("/user/{token}")
@SaCheckPermission(value = "user:token:query", orRole = "admin") @SaCheckPermission(value = "user:token:query", orRole = "admin")
public UserVO getUserByToken(@PathVariable String token) { public UserVO getUserByToken(@PathVariable String token) {
return Global.USERNAME_MAP.get(token); return (UserVO) StpUtil.getTokenSessionByToken(token).get("curLoginUser");
} }
@GetMapping("/orgTree") @GetMapping("/orgTree")
...@@ -111,7 +110,7 @@ public class UserController { ...@@ -111,7 +110,7 @@ public class UserController {
public Object wechatCallback(String code, Long taskTempId) { public Object wechatCallback(String code, Long taskTempId) {
Object obj = wechatMod.wechatCallback(code); Object obj = wechatMod.wechatCallback(code);
if (obj instanceof String) { if (obj instanceof String) {
return taskTempService.lambdaUpdate().set(TaskTemp::getOpenid, obj).eq(TaskTemp::getId, taskTempId).update() ? new ModelAndView("weChatNeedAttention") : new ModelAndView("weChatError"); return taskTempService.lambdaUpdate().set(TaskTemp::getOpenid, obj).eq(TaskTemp::getId, taskTempId).update(new TaskTemp()) ? new ModelAndView("weChatNeedAttention") : new ModelAndView("weChatError");
} else { } else {
return obj; return obj;
} }
......
...@@ -55,10 +55,22 @@ public class ContractDTO extends BaseDTO { ...@@ -55,10 +55,22 @@ public class ContractDTO extends BaseDTO {
*/ */
private Long storeId; private Long storeId;
/** 文件来源 */
private Integer sourceType;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date nodeDate;
@DateTimeFormat(pattern = "yyyy-MM-dd") @DateTimeFormat(pattern = "yyyy-MM-dd")
private Date signDateStart; private Date signDateStart;
@DateTimeFormat(pattern = "yyyy-MM-dd") @DateTimeFormat(pattern = "yyyy-MM-dd")
private Date signDateEnd; private Date signDateEnd;
/**
* 1:查询未关联的合同
* 0:查询所有合同
*/
private int switchFlag;
} }
\ No newline at end of file \ No newline at end of file
package vion.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class ProductDTO extends BaseDTO {
private Long id;
/** 物料编号 */
private String materialNo;
/** 门店id */
private Long storeId;
/** 门店名称 */
private String storeName;
/** 产品名称 */
private String name;
/** 产品型号 */
private Integer functionary;
/** 品牌 */
private Integer brand;
/** 订货数量 */
private Integer productCount;
/** 订货单价 */
private Float productPrice;
/** 定后价小计(单价乘以数量) */
private Float productSubtotal;
/** 订货总价 */
private Float productTotalPrice;
/** 备注 */
private String remark;
/** 集团id */
private Long accountId;
}
...@@ -2,16 +2,21 @@ package vion.interceptor; ...@@ -2,16 +2,21 @@ package vion.interceptor;
import cn.dev33.satoken.interceptor.SaInterceptor; import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration @Configuration
@Slf4j
public class InterceptorConfig implements WebMvcConfigurer { public class InterceptorConfig implements WebMvcConfigurer {
@Override @Override
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin())) registry.addInterceptor(new SaInterceptor(handle -> {
StpUtil.checkLogin();
StpUtil.renewTimeout(3600L);
}))
.addPathPatterns("/api/**") .addPathPatterns("/api/**")
.excludePathPatterns("/api/upLoadFile", "/api/ding/callback/**", "/api/wechat/**", "/error") .excludePathPatterns("/api/upLoadFile", "/api/ding/callback/**", "/api/wechat/**", "/error")
.excludePathPatterns("/api/order/sign/*") .excludePathPatterns("/api/order/sign/*")
......
package vion.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import vion.model.Product;
public interface ProductMapper extends MPJBaseMapper<Product> {
}
...@@ -73,7 +73,7 @@ public class Contract { ...@@ -73,7 +73,7 @@ public class Contract {
private BigDecimal totalAmount; private BigDecimal totalAmount;
/** /**
* 合同已收金额:人工编辑 * 合同已收金额
*/ */
@TableField(value = "paid_amount") @TableField(value = "paid_amount")
private BigDecimal paidAmount; private BigDecimal paidAmount;
...@@ -106,7 +106,7 @@ public class Contract { ...@@ -106,7 +106,7 @@ public class Contract {
/** /**
* 销售人员名称 * 销售人员名称
*/ */
@TableField(value = "sale_name") @TableField(value = "sale_name", condition = SqlCondition.LIKE)
private String saleName; private String saleName;
/** /**
...@@ -164,6 +164,12 @@ public class Contract { ...@@ -164,6 +164,12 @@ public class Contract {
private Date entryTime; private Date entryTime;
/** /**
* 财务状态
*/
@TableField(value = "financial_status")
private Date financialStatus;
/**
* 合同签订付款比例 * 合同签订付款比例
*/ */
@TableField(exist = false) @TableField(exist = false)
......
...@@ -48,6 +48,12 @@ public class ContractPayment { ...@@ -48,6 +48,12 @@ public class ContractPayment {
private Date paymentDate; private Date paymentDate;
/** /**
* 节点日期,指合同到这一阶段时的时间
*/
@TableField(value = "node_date")
private Date nodeDate;
/**
* 创建者 * 创建者
*/ */
@TableField(value = "create_user") @TableField(value = "create_user")
......
package vion.model;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.github.linpeilie.annotations.AutoMapper;
import io.github.linpeilie.annotations.AutoMappers;
import lombok.Data;
import vion.dto.ProductDTO;
import vion.vo.ProductVO;
import java.util.Date;
/**
* 产品信息
*/
@Data
@TableName(value="tbl_product_info")
@AutoMappers({
@AutoMapper(target = ProductVO.class),
@AutoMapper(target = ProductDTO.class),
})
public class Product {
/** 自增列 */
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/** 物料编号 */
private String materialNo;
/** 门店id */
private Long storeId;
/** 产品名称 */
private String name;
/** 产品型号 */
private Integer functionary;
/** 品牌 */
private Integer brand;
/** 订货数量 */
private Integer productCount;
/** 订货单价 */
private Float productPrice;
//定后价小计(单价乘以数** ) */
private Float productSubtotal;
/** 订货总价 */
private Float productTotalPrice;
/** 创建时间 */
@TableField(value = "create_time", fill = FieldFill.INSERT)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
/** 修改时间 */
@TableField(value = "modify_time", fill = FieldFill.INSERT_UPDATE)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date modifyTime;
/** 备注 */
private String remark;
/** 集团id */
private Long accountId;
}
package vion.service; package vion.service;
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.MPJBaseService;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import vion.dto.ContractDTO; import vion.dto.ContractDTO;
import vion.model.Contract; import vion.model.Contract;
import com.github.yulichang.base.MPJBaseService;
import vion.vo.ContractVO; import vion.vo.ContractVO;
/** /**
...@@ -23,4 +24,8 @@ public interface IContractService extends MPJBaseService<Contract>{ ...@@ -23,4 +24,8 @@ public interface IContractService extends MPJBaseService<Contract>{
String updateById(Long id, String contractNo, ContractDTO dto); String updateById(Long id, String contractNo, ContractDTO dto);
JSONObject calAmount(ContractDTO dto);
Object analyze(ContractDTO dto);
} }
\ No newline at end of file \ No newline at end of file
package vion.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseService;
import vion.dto.ProductDTO;
import vion.model.Product;
import vion.vo.ProductVO;
public interface IProductService extends MPJBaseService<Product> {
Page<ProductVO> getProductList(ProductDTO productDTO);
}
package vion.service.impl; package vion.service.impl;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
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.map.MapUtil;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.*;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.Db; import com.baomidou.mybatisplus.extension.toolkit.Db;
...@@ -26,16 +28,12 @@ import vion.dto.ContractDTO; ...@@ -26,16 +28,12 @@ import vion.dto.ContractDTO;
import vion.mapper.ContractMapper; import vion.mapper.ContractMapper;
import vion.model.*; import vion.model.*;
import vion.service.*; import vion.service.*;
import vion.vo.ContractVO; import vion.vo.*;
import vion.vo.StoreVO;
import vion.vo.UserVO;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.math.BigDecimal;
import java.util.Date; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -59,8 +57,28 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont ...@@ -59,8 +57,28 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
@Override @Override
public Page<ContractVO> list(ContractDTO dto) { public Page<ContractVO> list(ContractDTO dto) {
Contract contract = converter.convert(dto, new Contract()); Contract contract = converter.convert(dto, new Contract());
List<Long> contractIdList = new ArrayList<>();
if (dto.getSwitchFlag() == 1) {
contractIdList = contractStoreService.listObjs(Wrappers.<RContractStore>lambdaQuery()
.select(RContractStore::getContractId), o -> Long.valueOf(o.toString()));
}
UserVO userVO = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
String saleName = Opt.ofEmptyAble(userVO.getRoleVOList())
.map(l -> l.stream().map(RoleVO::getCode).collect(Collectors.toList()))
.map(roleCodeList -> {
if (!roleCodeList.contains("admin") && !roleCodeList.contains("shangwu") && !roleCodeList.contains("caiwu")) {
return userVO.getUsername();
} else {
return "";
}
}).orElse("未知");
Page<Contract> contractList = this.lambdaQuery(contract) Page<Contract> contractList = this.lambdaQuery(contract)
.between(ArrayUtil.isAllNotNull(dto.getSignDateStart(), dto.getSignDateEnd()), Contract::getSignDate, dto.getSignDateStart(), dto.getSignDateEnd()) .between(ArrayUtil.isAllNotNull(dto.getSignDateStart(), dto.getSignDateEnd()), Contract::getSignDate, dto.getSignDateStart(), dto.getSignDateEnd())
.notIn(CollUtil.isNotEmpty(contractIdList), Contract::getId, contractIdList)
.eq(StrUtil.isNotBlank(saleName), Contract::getSaleName, saleName)
.orderByDesc(Contract::getEntryTime) .orderByDesc(Contract::getEntryTime)
.page(Page.of(dto.getPageNum(), dto.getPageSize())); .page(Page.of(dto.getPageNum(), dto.getPageSize()));
List<ContractVO> contractVOList = converter.convert(contractList.getRecords(), ContractVO.class); List<ContractVO> contractVOList = converter.convert(contractList.getRecords(), ContractVO.class);
...@@ -109,7 +127,6 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont ...@@ -109,7 +127,6 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
})); }));
} }
@Override @Override
public ContractVO getVOById(Long id) { public ContractVO getVOById(Long id) {
MPJLambdaWrapper<Contract> wrapper = new MPJLambdaWrapper<Contract>() MPJLambdaWrapper<Contract> wrapper = new MPJLambdaWrapper<Contract>()
...@@ -140,18 +157,31 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont ...@@ -140,18 +157,31 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public String updateById(Long id, String contractNo, ContractDTO dto) { public String updateById(Long id, String contractNo, ContractDTO dto) {
Contract existContract = null; // todo 合同状态变更时,添加 nodeDate,未上线待联调
Contract existContract = new Contract();
if (ObjUtil.isNotNull(id)) { if (ObjUtil.isNotNull(id)) {
existContract = this.getById(id); existContract = this.getById(id);
} else if (StrUtil.isNotBlank(contractNo)) { } else if (StrUtil.isNotBlank(contractNo)) {
existContract = this.lambdaQuery().eq(Contract::getContractNo, contractNo).one(); existContract = this.lambdaQuery().eq(Contract::getContractNo, contractNo).one();
} }
Assert.notNull(existContract, "合同不存在"); Assert.isFalse(BeanUtil.isEmpty(existContract), "合同不存在");
// todo 如果当前合同进度在要修改的进度前,此时不能修改合同进度。e.g 当前合同进度是项目验收,此时传参过来到货,那么不能修改
Contract contract = converter.convert(dto, new Contract()); Contract contract = converter.convert(dto, new Contract());
contract.setId(existContract.getId()); Long contractId = existContract.getId();
contract.setId(contractId);
contractPaymentService.calMoney(existContract, contract); contractPaymentService.calMoney(existContract, contract);
if (this.updateById(contract)) { if (this.updateById(contract)) {
Opt.ofNullable(dto.getNodeDate())
.ifPresent(date -> {
contractPaymentService.lambdaUpdate()
.set(ContractPayment::getPaymentDate, date)
.eq(ContractPayment::getContractId, contractId)
.eq(ContractPayment::getPaymentType, dto.getStatus())
.update(new ContractPayment());
});
UserVO userVO = (UserVO) StpUtil.getTokenSession().get("curLoginUser"); UserVO userVO = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
ContractLog contractLog = new ContractLog(); ContractLog contractLog = new ContractLog();
...@@ -181,9 +211,9 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont ...@@ -181,9 +211,9 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
Arrays.stream(fileList).forEach(infile -> { Arrays.stream(fileList).forEach(infile -> {
//上传url地址 //上传url地址
String orgName = infile.getOriginalFilename(); String orgName = infile.getOriginalFilename();
String fileName = orgName.substring(0, orgName.lastIndexOf(".")); String mainName = FileUtil.mainName(orgName);
String fileExt = orgName.substring(orgName.lastIndexOf(".")); String fileExt = FileUtil.extName(orgName);
String filename = fileName + "_" + DateUtil.format(new Date(), "yyyyMMdd_HHmmss") + fileExt; String filename = StrUtil.format("{}_{}.{}", mainName, DateUtil.format(new Date(), "yyyyMMdd_HHmmss"), fileExt);;
String path = fileUrl + FileUtil.FILE_SEPARATOR + "contract" + FileUtil.FILE_SEPARATOR + contract.getId() + FileUtil.FILE_SEPARATOR + filename; String path = fileUrl + FileUtil.FILE_SEPARATOR + "contract" + FileUtil.FILE_SEPARATOR + contract.getId() + FileUtil.FILE_SEPARATOR + filename;
File file = FileUtil.touch(path); File file = FileUtil.touch(path);
try { try {
...@@ -195,10 +225,11 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont ...@@ -195,10 +225,11 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
FileInfo fileInfo = new FileInfo(); FileInfo fileInfo = new FileInfo();
fileInfo.setStoreId(-1L); fileInfo.setStoreId(-1L);
fileInfo.setSourceId(contract.getId()); fileInfo.setSourceId(contract.getId());
fileInfo.setSourceType(5); fileInfo.setSourceType(dto.getSourceType());
fileInfo.setContractId(contract.getId());
fileInfo.setName(filename); fileInfo.setName(filename);
fileInfo.setUrl(path); fileInfo.setUrl(path);
fileInfo.setType(FileUtil.extName(file)); fileInfo.setType(fileExt);
fileInfo.setSha256(SecureUtil.sha256(file).toUpperCase()); fileInfo.setSha256(SecureUtil.sha256(file).toUpperCase());
fileInfo.setUploader(userVO.getUsername()); fileInfo.setUploader(userVO.getUsername());
fileService.save(fileInfo); fileService.save(fileInfo);
...@@ -208,4 +239,103 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont ...@@ -208,4 +239,103 @@ public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Cont
return "更新失败"; return "更新失败";
} }
} }
@Override
public JSONObject calAmount(ContractDTO dto) {
List<Contract> contracts = this.list(Wrappers.lambdaQuery(converter.convert(dto, Contract.class))
.between(ArrayUtil.isAllNotNull(dto.getSignDateStart(), dto.getSignDateEnd()), Contract::getSignDate, dto.getSignDateStart(), dto.getSignDateEnd())
);
JSONObject obj = JSONUtil.createObj()
.set("totalAmount", 0)
.set("paidAmount", 0)
.set("recAmount", 0)
.set("outAmount", 0)
.set("invoiceAmount", 0);
Opt.ofEmptyAble(contracts)
.ifPresent(list -> {
BigDecimal totalAmount = list.stream().map(Contract::getTotalAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal paidAmount = list.stream().map(v -> NumberUtil.max(BigDecimal.ZERO, v.getPaidAmount())).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal recAmount = list.stream().map(v -> NumberUtil.max(BigDecimal.ZERO, v.getReceivableAmount())).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal outAmount = list.stream().map(Contract::getOutstandingAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
List<String> noList = list.stream().map(Contract::getContractNo).collect(Collectors.toList());
List<BigDecimal> invoices = Db.listObjs(Wrappers.lambdaQuery(Invoice.class).select(Invoice::getInvoiceAmount).in(BeanUtil.isNotEmpty(dto), Invoice::getContractNo, noList), Invoice::getInvoiceAmount);
BigDecimal invoiceAmount = invoices.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
obj.set("totalAmount", totalAmount)
.set("paidAmount", paidAmount)
.set("recAmount", recAmount)
.set("outAmount", outAmount)
.set("invoiceAmount", invoiceAmount);
});
return obj;
}
@Override
public Object analyze(ContractDTO dto) {
List<Contract> contractList = this.lambdaQuery(converter.convert(dto, Contract.class))
.ge(Contract::getReceivableAmount, 0)
.between(ArrayUtil.isAllNotNull(dto.getSignDateStart(), dto.getSignDateEnd()), Contract::getSignDate, dto.getSignDateStart(), dto.getSignDateEnd())
.list();
if (CollUtil.isEmpty(contractList)) {
return ListUtil.empty();
}
// todo 优化查询,当下是查询所有
Map<Long, List<ContractPayment>> id2PaymentMap = Opt.ofEmptyAble(contractPaymentService.lambdaQuery().gt(ContractPayment::getPaymentRatio, 0).list())
.map(list -> list.stream().collect(Collectors.groupingBy(ContractPayment::getContractId)))
.orElse(MapUtil.empty());
if (MapUtil.isEmpty(id2PaymentMap)) {
return ListUtil.empty();
}
List<FinancialAgeVO> financialAgeVOList = new ArrayList<>();
contractList.forEach(c -> {
List<ContractPayment> contractPaymentList = id2PaymentMap.get(c.getId());
if (CollUtil.isEmpty(contractPaymentList)) {
return;
}
BigDecimal totalAmount = c.getTotalAmount();
if (NumberUtil.equals(totalAmount, BigDecimal.ZERO)) {
return;
}
BigDecimal paidAmount = c.getPaidAmount();
Map<Integer, Date> type2DateMap = contractPaymentList.stream().collect(HashMap::new, (m, v) -> m.put(v.getPaymentType(), v.getPaymentDate()), HashMap::putAll);
Map<Integer, BigDecimal> type2AmountMap = contractPaymentList.stream().collect(Collectors.toMap(ContractPayment::getPaymentType, v -> NumberUtil.mul(v.getPaymentRatio(), totalAmount)));
TreeMap<Integer, BigDecimal> sortMap = MapUtil.sort(type2AmountMap, Comparator.comparingInt(Integer::intValue));
for (Map.Entry<Integer, BigDecimal> entry : sortMap.entrySet()) {
Integer type = entry.getKey();
BigDecimal curAmount = entry.getValue();
if (NumberUtil.isGreater(paidAmount, BigDecimal.ZERO)) {
paidAmount = NumberUtil.sub(paidAmount, curAmount);
if (NumberUtil.equals(paidAmount, BigDecimal.ZERO)) {
continue;
}
}
if (NumberUtil.isLessOrEqual(paidAmount, BigDecimal.ZERO)) {
FinancialAgeVO financialAgeVO = new FinancialAgeVO();
financialAgeVO.setContractNo(c.getContractNo());
financialAgeVO.setContractName(c.getName());
financialAgeVO.setStatus(type);
financialAgeVO.setAmount(NumberUtil.equals(paidAmount, BigDecimal.ZERO) ? curAmount : BigDecimal.valueOf(Math.abs(paidAmount.doubleValue())));
Date payableDate = type2DateMap.get(type);
Opt.ofNullable(type2DateMap.get(type)).ifPresent(
date -> {
financialAgeVO.setPayableDate(date);
long age = DateUtil.between(new Date(), payableDate, DateUnit.DAY, false);
financialAgeVO.setAge(((int) age));
}
);
financialAgeVOList.add(financialAgeVO);
paidAmount = BigDecimal.ZERO;
}
}
});
// 手动分页
int[] transToStartEnd = PageUtil.transToStartEnd(dto.getPageNum() - 1, dto.getPageSize());
return Page.<FinancialAgeVO>of(dto.getPageNum(), dto.getPageSize(), financialAgeVOList.size()).setRecords(CollUtil.sub(financialAgeVOList, transToStartEnd[0], transToStartEnd[1]));
}
} }
\ No newline at end of file \ No newline at end of file
...@@ -23,12 +23,14 @@ import vion.service.IContractService; ...@@ -23,12 +23,14 @@ import vion.service.IContractService;
import vion.service.IDeliveryRecordService; import vion.service.IDeliveryRecordService;
import vion.service.IFileService; import vion.service.IFileService;
import vion.vo.DeliveryRecordVO; import vion.vo.DeliveryRecordVO;
import vion.vo.RoleVO;
import vion.vo.UserVO; import vion.vo.UserVO;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.stream.Collectors;
/** /**
* @author HlQ * @author HlQ
...@@ -47,11 +49,23 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord ...@@ -47,11 +49,23 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord
@Override @Override
public Page<DeliveryRecordVO> list(DeliveryRecordDTO dto) { public Page<DeliveryRecordVO> list(DeliveryRecordDTO dto) {
UserVO userVO = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
String saleName = Opt.ofEmptyAble(userVO.getRoleVOList())
.map(l -> l.stream().map(RoleVO::getCode).collect(Collectors.toList()))
.map(roleCodeList -> {
if (!roleCodeList.contains("admin") && !roleCodeList.contains("shangwu") && !roleCodeList.contains("caiwu")) {
return userVO.getUsername();
} else {
return "";
}
}).orElse("未知");
MPJLambdaWrapper<DeliveryRecord> wrapper = new MPJLambdaWrapper<>(converter.convert(dto, new DeliveryRecord())) MPJLambdaWrapper<DeliveryRecord> wrapper = new MPJLambdaWrapper<>(converter.convert(dto, new DeliveryRecord()))
.selectAll(DeliveryRecord.class) .selectAll(DeliveryRecord.class)
.selectAs(Contract::getName, DeliveryRecordVO::getContractName) .selectAs(Contract::getName, DeliveryRecordVO::getContractName)
.selectAs(Contract::getCustomerName, DeliveryRecordVO::getCustomerName) .selectAs(Contract::getCustomerName, DeliveryRecordVO::getCustomerName)
.leftJoin(Contract.class, Contract::getContractNo, DeliveryRecord::getContractNo) .leftJoin(Contract.class, Contract::getContractNo, DeliveryRecord::getContractNo)
.eq(StrUtil.isNotBlank(saleName), Contract::getSaleName, saleName)
.like(StrUtil.isNotBlank(dto.getContractName()), Contract::getName, dto.getContractName()) .like(StrUtil.isNotBlank(dto.getContractName()), Contract::getName, dto.getContractName())
.like(StrUtil.isNotBlank(dto.getCustomerName()), Contract::getCustomerName, dto.getCustomerName()) .like(StrUtil.isNotBlank(dto.getCustomerName()), Contract::getCustomerName, dto.getCustomerName())
.orderByDesc(DeliveryRecord::getCreateTime); .orderByDesc(DeliveryRecord::getCreateTime);
...@@ -72,9 +86,9 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord ...@@ -72,9 +86,9 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord
Arrays.stream(fileList).forEach(infile -> { Arrays.stream(fileList).forEach(infile -> {
String orgName = infile.getOriginalFilename(); String orgName = infile.getOriginalFilename();
String fileName = orgName.substring(0, orgName.lastIndexOf(".")); String mainName = FileUtil.mainName(orgName);
String fileExt = orgName.substring(orgName.lastIndexOf(".")); String fileExt = FileUtil.extName(orgName);
String filename = fileName + "_" + DateUtil.format(new Date(), "yyyyMMdd_HHmmss") + fileExt; String filename = StrUtil.format("{}_{}.{}", mainName, DateUtil.format(new Date(), "yyyyMMdd_HHmmss"), fileExt);;
String path = fileUrl + FileUtil.FILE_SEPARATOR + "delivery" + FileUtil.FILE_SEPARATOR + dto.getContractId() + FileUtil.FILE_SEPARATOR + record.getId() + FileUtil.FILE_SEPARATOR + filename; String path = fileUrl + FileUtil.FILE_SEPARATOR + "delivery" + FileUtil.FILE_SEPARATOR + dto.getContractId() + FileUtil.FILE_SEPARATOR + record.getId() + FileUtil.FILE_SEPARATOR + filename;
File file = FileUtil.touch(path); File file = FileUtil.touch(path);
try { try {
...@@ -113,9 +127,9 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord ...@@ -113,9 +127,9 @@ public class DeliveryRecordServiceImpl extends MPJBaseServiceImpl<DeliveryRecord
Arrays.stream(fileList).forEach(infile -> { Arrays.stream(fileList).forEach(infile -> {
String orgName = infile.getOriginalFilename(); String orgName = infile.getOriginalFilename();
String fileName = orgName.substring(0, orgName.lastIndexOf(".")); String mainName = FileUtil.mainName(orgName);
String fileExt = orgName.substring(orgName.lastIndexOf(".")); String fileExt = FileUtil.extName(orgName);
String filename = fileName + "_" + DateUtil.format(new Date(), "yyyyMMdd_HHmmss") + fileExt; String filename = StrUtil.format("{}_{}.{}", mainName, DateUtil.format(new Date(), "yyyyMMdd_HHmmss"), fileExt);;
String path = fileUrl + FileUtil.FILE_SEPARATOR + "delivery" + FileUtil.FILE_SEPARATOR + deliveryRecord.getContractId() + FileUtil.FILE_SEPARATOR + record.getId() + FileUtil.FILE_SEPARATOR + filename; String path = fileUrl + FileUtil.FILE_SEPARATOR + "delivery" + FileUtil.FILE_SEPARATOR + deliveryRecord.getContractId() + FileUtil.FILE_SEPARATOR + record.getId() + FileUtil.FILE_SEPARATOR + filename;
File file = FileUtil.touch(path); File file = FileUtil.touch(path);
try { try {
......
package vion.service.impl; package vion.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.NumberUtil;
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.yulichang.base.MPJBaseServiceImpl; import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import io.github.linpeilie.Converter; import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -14,6 +18,8 @@ import vion.model.Invoice; ...@@ -14,6 +18,8 @@ import vion.model.Invoice;
import vion.service.IContractService; import vion.service.IContractService;
import vion.service.IInvoiceService; import vion.service.IInvoiceService;
import vion.vo.InvoiceVO; import vion.vo.InvoiceVO;
import vion.vo.RoleVO;
import vion.vo.UserVO;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List; import java.util.List;
...@@ -33,8 +39,22 @@ public class InvoiceServiceImpl extends MPJBaseServiceImpl<InvoiceMapper, Invoic ...@@ -33,8 +39,22 @@ public class InvoiceServiceImpl extends MPJBaseServiceImpl<InvoiceMapper, Invoic
@Override @Override
public Page<InvoiceVO> list(InvoiceDTO dto) { public Page<InvoiceVO> list(InvoiceDTO dto) {
Page<Invoice> recPage = this.lambdaQuery(converter.convert(dto, new Invoice())).page(Page.of(dto.getPageNum(), dto.getPageSize())); UserVO userVO = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
return Page.<InvoiceVO>of(recPage.getCurrent(), recPage.getSize(), recPage.getTotal()).setRecords(converter.convert(recPage.getRecords(), InvoiceVO.class)); String saleName = Opt.ofEmptyAble(userVO.getRoleVOList())
.map(l -> l.stream().map(RoleVO::getCode).collect(Collectors.toList()))
.map(roleCodeList -> {
if (!roleCodeList.contains("admin") && !roleCodeList.contains("shangwu") && !roleCodeList.contains("caiwu")) {
return userVO.getUsername();
} else {
return "";
}
}).orElse("未知");
MPJLambdaWrapper<Invoice> wrapper = new MPJLambdaWrapper<>(converter.convert(dto, Invoice.class))
.selectAll(Invoice.class)
.leftJoin(Contract.class, Contract::getContractNo, Invoice::getContractNo)
.eq(StrUtil.isNotBlank(saleName), Contract::getSaleName, saleName);
return this.selectJoinListPage(Page.of(dto.getPageNum(), dto.getPageSize()), InvoiceVO.class, wrapper);
} }
@Override @Override
...@@ -47,7 +67,7 @@ public class InvoiceServiceImpl extends MPJBaseServiceImpl<InvoiceMapper, Invoic ...@@ -47,7 +67,7 @@ public class InvoiceServiceImpl extends MPJBaseServiceImpl<InvoiceMapper, Invoic
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 = contractService.lambdaQuery().eq(Contract::getContractNo, no).one();
contractService.lambdaUpdate().eq(Contract::getContractNo, no).set(Contract::getInvoiceAmount, NumberUtil.add(sum, existContract.getInvoiceAmount())).update(); contractService.lambdaUpdate().eq(Contract::getContractNo, no).set(Contract::getInvoiceAmount, NumberUtil.add(sum, existContract.getInvoiceAmount())).update(new Contract());
}); });
return "成功"; return "成功";
} }
......
package vion.service.impl; package vion.service.impl;
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 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 io.github.linpeilie.Converter; import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -15,6 +19,8 @@ import vion.service.IContractPaymentService; ...@@ -15,6 +19,8 @@ import vion.service.IContractPaymentService;
import vion.service.IContractService; import vion.service.IContractService;
import vion.service.IPaymentService; import vion.service.IPaymentService;
import vion.vo.PaymentVO; import vion.vo.PaymentVO;
import vion.vo.RoleVO;
import vion.vo.UserVO;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List; import java.util.List;
...@@ -35,8 +41,22 @@ public class PaymentServiceImpl extends MPJBaseServiceImpl<PaymentMapper, Paymen ...@@ -35,8 +41,22 @@ public class PaymentServiceImpl extends MPJBaseServiceImpl<PaymentMapper, Paymen
@Override @Override
public Page<PaymentVO> list(PaymentDTO dto) { public Page<PaymentVO> list(PaymentDTO dto) {
Page<Payment> recPage = this.lambdaQuery(converter.convert(dto, new Payment())).page(Page.of(dto.getPageNum(), dto.getPageSize())); UserVO userVO = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
return Page.<PaymentVO>of(recPage.getCurrent(), recPage.getSize(), recPage.getTotal()).setRecords(converter.convert(recPage.getRecords(), PaymentVO.class)); String saleName = Opt.ofEmptyAble(userVO.getRoleVOList())
.map(l -> l.stream().map(RoleVO::getCode).collect(Collectors.toList()))
.map(roleCodeList -> {
if (!roleCodeList.contains("admin") && !roleCodeList.contains("shangwu") && !roleCodeList.contains("caiwu")) {
return userVO.getUsername();
} else {
return "";
}
}).orElse("未知");
MPJLambdaWrapper<Payment> wrapper = new MPJLambdaWrapper<>(converter.convert(dto, Payment.class))
.selectAll(Payment.class)
.leftJoin(Contract.class, Contract::getContractNo, Payment::getContractNo)
.eq(StrUtil.isNotBlank(saleName), Contract::getSaleName, saleName);
return this.selectJoinListPage(Page.of(dto.getPageNum(), dto.getPageSize()), PaymentVO.class, wrapper);
} }
@Override @Override
......
package vion.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import vion.dto.ProductDTO;
import vion.mapper.ProductMapper;
import vion.model.Product;
import vion.model.Store;
import vion.service.IProductService;
import vion.service.IStoreService;
import vion.vo.ProductVO;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class ProductServiceImpl extends MPJBaseServiceImpl<ProductMapper, Product> implements IProductService {
private final IStoreService storeService;
private final Converter converter;
@Override
public Page<ProductVO> getProductList(ProductDTO productDTO) {
Page<Product> productList = this.page(Page.of(productDTO.getPageNum(), productDTO.getPageSize()), Wrappers.<Product>lambdaQuery()
.eq(productDTO.getStoreId() != null, Product::getStoreId, productDTO.getStoreId())
.eq(productDTO.getAccountId() != null, Product::getAccountId, productDTO.getAccountId())
.like(productDTO.getName() != null, Product::getName, productDTO.getName())
.eq(productDTO.getBrand() != null, Product::getBrand, productDTO.getBrand())
.eq(productDTO.getFunctionary() != null, Product::getFunctionary, productDTO.getFunctionary()));
List<Store> storeList = storeService.list();
List<ProductVO> productVOList = new ArrayList<>();
for (Product pro : productList.getRecords()) {
ProductVO productVO = converter.convert(pro, ProductVO.class);
productVO.setStoreName(storeList.stream().filter(store -> store.getId().equals(pro.getStoreId())).collect(Collectors.toList()).get(0).getName());
productVOList.add(productVO);
}
return Page.<ProductVO>of(productDTO.getPageNum(), productDTO.getPageSize(), productList.getTotal()).setRecords(productVOList);
}
}
package vion.service.impl; package vion.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
...@@ -18,7 +19,6 @@ import lombok.RequiredArgsConstructor; ...@@ -18,7 +19,6 @@ import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import vion.Global;
import vion.dto.StatusDTO; import vion.dto.StatusDTO;
import vion.dto.StoreDTO; import vion.dto.StoreDTO;
import vion.mapper.StoreMapper; import vion.mapper.StoreMapper;
...@@ -27,6 +27,7 @@ import vion.model.*; ...@@ -27,6 +27,7 @@ import vion.model.*;
import vion.service.*; import vion.service.*;
import vion.vo.ContractVO; import vion.vo.ContractVO;
import vion.vo.StoreVO; import vion.vo.StoreVO;
import vion.vo.UserVO;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
...@@ -117,6 +118,7 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp ...@@ -117,6 +118,7 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
this.update(Wrappers.<Store>lambdaUpdate() this.update(Wrappers.<Store>lambdaUpdate()
.set(Store::getProjectStage, statusDTO.getProjectStage()) .set(Store::getProjectStage, statusDTO.getProjectStage())
.eq(Store::getId, statusDTO.getStoreId())); .eq(Store::getId, statusDTO.getStoreId()));
UserVO userVO = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
Opt.ofNullable(statusDTO.getFiles()).ifPresent(tmpFiles -> { Opt.ofNullable(statusDTO.getFiles()).ifPresent(tmpFiles -> {
for (MultipartFile infile : tmpFiles) { for (MultipartFile infile : tmpFiles) {
...@@ -141,7 +143,7 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp ...@@ -141,7 +143,7 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
tempFileInfo.setUrl(path); tempFileInfo.setUrl(path);
tempFileInfo.setType(FileUtil.extName(file)); tempFileInfo.setType(FileUtil.extName(file));
tempFileInfo.setSha256(SecureUtil.sha256(file).toUpperCase()); tempFileInfo.setSha256(SecureUtil.sha256(file).toUpperCase());
tempFileInfo.setUploader(Global.USERNAME_MAP.get(token).getUsername()); tempFileInfo.setUploader(userVO.getUsername());
fileService.save(tempFileInfo); fileService.save(tempFileInfo);
} }
...@@ -192,11 +194,10 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp ...@@ -192,11 +194,10 @@ public class StoreServiceImpl extends MPJBaseServiceImpl<StoreMapper, Store> imp
contracts.stream() contracts.stream()
.filter(contract -> ObjUtil.equals(contract.getType(), 1)) .filter(contract -> ObjUtil.equals(contract.getType(), 1))
.forEach(c -> { .forEach(c -> {
Date maintainSdate = c.getMaintainSdate();
Date maintainEdate = c.getMaintainEdate(); Date maintainEdate = c.getMaintainEdate();
if (ArrayUtil.isAllNotNull(maintainSdate, maintainEdate)) { if (ObjUtil.isNotNull(maintainEdate)) {
boolean isIn = DateUtil.isIn(new Date(), maintainSdate, maintainEdate); // 维保结束时间大于等于当前时间,返回 true
maintainStatusSet.add(isIn); maintainStatusSet.add(DateUtil.compare(maintainEdate, new Date()) >= 0);
} }
}); });
s.setMaintainStatus(CollUtil.isEmpty(maintainStatusSet) ? s.getMaintainStatus() : maintainStatusSet.contains(true) ? "在保" : "脱保"); s.setMaintainStatus(CollUtil.isEmpty(maintainStatusSet) ? s.getMaintainStatus() : maintainStatusSet.contains(true) ? "在保" : "脱保");
......
...@@ -23,7 +23,6 @@ import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; ...@@ -23,7 +23,6 @@ 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.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import vion.Global;
import vion.dto.TaskDTO; import vion.dto.TaskDTO;
import vion.mapper.TaskMapper; import vion.mapper.TaskMapper;
import vion.model.Dictionary; import vion.model.Dictionary;
...@@ -126,7 +125,7 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem ...@@ -126,7 +125,7 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Long circTask(TaskDTO data, String token) { public Long circTask(TaskDTO data, String token) {
UserVO user = Global.USERNAME_MAP.get(token); UserVO user = (UserVO) StpUtil.getTokenSession().get("curLoginUser");
Task task = converter.convert(data, Task.class); Task task = converter.convert(data, Task.class);
if (task.getId() == null) { if (task.getId() == null) {
...@@ -232,9 +231,9 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem ...@@ -232,9 +231,9 @@ public class TaskServiceImpl extends MPJBaseServiceImpl<TaskMapper, Task> implem
.ifPresent(fileList -> .ifPresent(fileList ->
Arrays.stream(fileList).forEach(infile -> { Arrays.stream(fileList).forEach(infile -> {
String orgName = infile.getOriginalFilename(); String orgName = infile.getOriginalFilename();
String fileName = orgName.substring(0, orgName.lastIndexOf(".")); String mainName = FileUtil.mainName(orgName);
String fileExt = orgName.substring(orgName.lastIndexOf(".")); String fileExt = FileUtil.extName(orgName);
String filename = fileName + "_" + DateUtil.format(new Date(), "yyyyMMdd_HHmmss") + fileExt; String filename = StrUtil.format("{}_{}.{}", mainName, DateUtil.format(new Date(), "yyyyMMdd_HHmmss"), fileExt);;
String path = fileUrl + FileUtil.FILE_SEPARATOR + data.getStoreId() + FileUtil.FILE_SEPARATOR + task.getId() + FileUtil.FILE_SEPARATOR + filename; String path = fileUrl + FileUtil.FILE_SEPARATOR + data.getStoreId() + FileUtil.FILE_SEPARATOR + task.getId() + FileUtil.FILE_SEPARATOR + filename;
File file = FileUtil.touch(path); File file = FileUtil.touch(path);
try { try {
......
...@@ -86,9 +86,9 @@ public class TaskTempServiceImpl extends MPJBaseServiceImpl<TaskTempMapper, Task ...@@ -86,9 +86,9 @@ public class TaskTempServiceImpl extends MPJBaseServiceImpl<TaskTempMapper, Task
Arrays.stream(fileList).forEach(infile -> { Arrays.stream(fileList).forEach(infile -> {
//上传url地址 //上传url地址
String orgName = infile.getOriginalFilename(); String orgName = infile.getOriginalFilename();
String fileName = orgName.substring(0, orgName.lastIndexOf(".")); String mainName = FileUtil.mainName(orgName);
String fileExt = orgName.substring(orgName.lastIndexOf(".")); String fileExt = FileUtil.extName(orgName);
String filename = fileName + "_" + DateUtil.format(new Date(), "yyyyMMdd_HHmmss") + fileExt; String filename = StrUtil.format("{}_{}.{}", mainName, DateUtil.format(new Date(), "yyyyMMdd_HHmmss"), fileExt);;
String path = fileUrl + FileUtil.FILE_SEPARATOR + 0 + FileUtil.FILE_SEPARATOR + taskTemp.getId() + FileUtil.FILE_SEPARATOR + filename; String path = fileUrl + FileUtil.FILE_SEPARATOR + 0 + FileUtil.FILE_SEPARATOR + taskTemp.getId() + FileUtil.FILE_SEPARATOR + filename;
File file = FileUtil.touch(path); File file = FileUtil.touch(path);
try { try {
......
...@@ -23,7 +23,6 @@ import lombok.RequiredArgsConstructor; ...@@ -23,7 +23,6 @@ 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.stereotype.Component; import org.springframework.stereotype.Component;
import vion.Global;
import vion.dto.DingDTO; import vion.dto.DingDTO;
import vion.model.*; import vion.model.*;
import vion.service.*; import vion.service.*;
...@@ -245,8 +244,6 @@ public class DingMod { ...@@ -245,8 +244,6 @@ public class DingMod {
userVO.setToken(token); userVO.setToken(token);
StpUtil.getTokenSession().set("curLoginUser", userVO); StpUtil.getTokenSession().set("curLoginUser", userVO);
Global.USERNAME_MAP.put(token, userVO);
return userVO; return userVO;
} else if (StrUtil.equals(target, "inside")) { } else if (StrUtil.equals(target, "inside")) {
String response = HttpUtil.post(buildSignUrl(), "{\"tmp_auth_code\":\"" + dto.getCode() + "\"}"); String response = HttpUtil.post(buildSignUrl(), "{\"tmp_auth_code\":\"" + dto.getCode() + "\"}");
...@@ -276,7 +273,6 @@ public class DingMod { ...@@ -276,7 +273,6 @@ public class DingMod {
StpUtil.getTokenSession().set("curLoginUser", userVO); StpUtil.getTokenSession().set("curLoginUser", userVO);
Global.USERNAME_MAP.put(token, userVO);
try { try {
if (ObjUtil.isAllNotEmpty(dto.getStoreId(), dto.getTaskId())) { if (ObjUtil.isAllNotEmpty(dto.getStoreId(), dto.getTaskId())) {
res.sendRedirect("https://yunwei.vionyun.com:8443/wap/workflow-process?token=" + token + "&storeId=" + dto.getStoreId() + "&taskId=" + dto.getTaskId()); res.sendRedirect("https://yunwei.vionyun.com:8443/wap/workflow-process?token=" + token + "&storeId=" + dto.getStoreId() + "&taskId=" + dto.getTaskId());
......
package vion.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* @author HlQ
* @date 2023/12/20
*/
@Data
public class FinancialAgeVO {
private String contractNo;
private String contractName;
/** 账款类型 */
private Integer status;
/** 账款金额 */
private BigDecimal amount;
/** 应付日期 */
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date payableDate;
/** 财龄 */
private Integer age;
}
package vion.vo;
import lombok.Data;
import java.util.Date;
@Data
public class ProductVO {
private Long id;//自增列
private String materialNo;//物料编号
private Long storeId;//门店id
private String storeName;//门店名称
private String name;//产品名称
private Integer functionary;//产品型号
private Integer brand;//品牌
private Integer productCount;//订货数量
private Float productPrice;//订货单价
private Float productSubtotal;//定后价小计(单价乘以数量)
private Float productTotalPrice;//订货总价
private Date createTime;//创建时间
private Date modifyTime;//修改时间
private String remark;//备注
private Long accountId;//集团id
}
debug=false debug=false
################################## DATABASE ######################################## ################################## DATABASE ########################################
spring.datasource.url=jdbc:postgresql://pgm-2ze3cjpyjgjw0bl5uo.pg.rds.aliyuncs.com:1921/work-order #spring.datasource.url=jdbc:postgresql://pgm-2ze3cjpyjgjw0bl5uo.pg.rds.aliyuncs.com:1921/work-order
spring.datasource.username=vion #spring.datasource.username=vion
spring.datasource.password=jkou72j32m4K5d8k #spring.datasource.password=jkou72j32m4K5d8k
spring.datasource.driver-class-name=org.postgresql.Driver #spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.dynamic.primary=master
spring.datasource.dynamic.strict=false
spring.datasource.dynamic.datasource.master.url=jdbc:postgresql://pgm-2ze3cjpyjgjw0bl5uo.pg.rds.aliyuncs.com:1921/work-order
spring.datasource.dynamic.datasource.master.username=vion
spring.datasource.dynamic.datasource.master.password=jkou72j32m4K5d8k
spring.datasource.dynamic.datasource.master.driver-class-name=org.postgresql.Driver
spring.datasource.dynamic.datasource.slave_1.url=jdbc:postgresql://47.102.107.41:5432/f_serv
spring.datasource.dynamic.datasource.slave_1.username=postgres
spring.datasource.dynamic.datasource.slave_1.password=zxl123456
spring.datasource.dynamic.datasource.slave_1.driver-class-name=org.postgresql.Driver
spring.redis.host=r-2zejlb88mng3q50aw7pd.redis.rds.aliyuncs.com
spring.redis.password=RtOTnx2V
spring.redis.port=6379
spring.redis.database=8
server.port=8011 server.port=8011
fileUrl=D:/pic fileUrl=D:/pic
#fileurl=/nas-data/work-order #fileurl=/nas-data/work-order
......
...@@ -175,6 +175,7 @@ ...@@ -175,6 +175,7 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="CONSOLE"/> <appender-ref ref="CONSOLE"/>
<appender-ref ref="DEBUG_FILE"/>
<appender-ref ref="INFO_FILE"/> <appender-ref ref="INFO_FILE"/>
<appender-ref ref="WARN_FILE"/> <appender-ref ref="WARN_FILE"/>
<appender-ref ref="ERROR_FILE"/> <appender-ref ref="ERROR_FILE"/>
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!