feat(material): 新增材料相关接口

This commit is contained in:
han0
2023-11-11 12:24:39 +08:00
parent 6ff7bf0caa
commit 6fbe40104c
13 changed files with 521 additions and 2 deletions

22
pom.xml
View File

@@ -14,7 +14,7 @@
<packaging>jar</packaging>
<description>材料管理系统</description>
<properties>
<dep.xxs-common-core.version>2.3.6.8-SNAPSHOT</dep.xxs-common-core.version>
<dep.xxs-common-core.version>2.3.6.10-SNAPSHOT</dep.xxs-common-core.version>
</properties>
<repositories>
<repository>
@@ -128,8 +128,28 @@
<version>${mjkf-xinke.version}</version>
</dependency>
<!---->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatis.plus.version}</version>
</dependency>
<!--MyBatis Plus 代码自动生成模板引擎-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.mitre.dsmiley.httpproxy</groupId>
<artifactId>smiley-http-proxy-servlet</artifactId>
<version>1.12.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>

View File

@@ -74,7 +74,7 @@ import java.util.*;
* @date 2021/10/9 14:24
**/
@Configuration
@MapperScan(basePackages = {"mjkf.xinke.**.mapper, com.bstek.**.mapper"})
@MapperScan(basePackages = {"mjkf.xinke.**.mapper, mjkf.xinke.**.dao, com.bstek.**.mapper"})
public class GlobalConfigure implements WebMvcConfigurer {
private static final String COMMON_REPEAT_SUBMIT_CACHE_KEY = "common-repeatSubmit:";
@@ -142,6 +142,8 @@ public class GlobalConfigure implements WebMvcConfigurer {
"/pay/wx/authNotifyUrl",
"/pay/wx/jsPay",
"/pay/order/sample/doCreateOrder",
"/solr/**",
};
/**

View File

@@ -5,6 +5,7 @@ import cn.dev33.satoken.exception.SaTokenException;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import com.jgy.xxs.core.http.exp.NcHttpException;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.exceptions.PersistenceException;
import org.mybatis.spring.MyBatisSystemException;
@@ -120,6 +121,10 @@ public class GlobalExceptionUtil {
log.error(">>> 数据操作异常:", e);
commonResult = CommonResult.error("数据操作异常");
}
} else if (e instanceof NcHttpException) {
// 通用业务异常,直接返回给前端
NcHttpException ncHttpException = (NcHttpException) e;
commonResult = CommonResult.get(ncHttpException.getMetaCode(), ncHttpException.getMessage(), null);
} else if (e instanceof CommonException) {
// 通用业务异常,直接返回给前端

View File

@@ -28,6 +28,10 @@ public class DataDbMpGenerator {
"STEEL_PLATE",
"STEEL_REBAR",
"STEEL_STRAND",
"MATERIAL",
"MATERIAL_TASK",
"PRICE_PUBLISH",
"PRICE_RESULT",
};
@@ -92,6 +96,7 @@ public class DataDbMpGenerator {
.controllerBuilder()
.enableRestStyle()
.enableHyphenStyle()
;
}

View File

@@ -0,0 +1,36 @@
package mjkf.xinke.main.common.http;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.jgy.xxs.core.http.NcMeta;
import com.jgy.xxs.core.http.NcPagination;
import com.jgy.xxs.core.http.resp.HttpResponse;
import com.jgy.xxs.core.http.resp.NcHttpResponse;
import lombok.Getter;
@Getter
public class FuHttpResponse<T> extends NcHttpResponse<T> {
@JsonIgnore
private NcMeta meta;
@JsonIgnore
private NcPagination pagination;
private String msg;
private int code;
private T data;
public static HttpResponse Builder() {
return new FuHttpResponse();
}
@Override
public HttpResponse<T> build() {
this.msg = this._message;
this.code = this._code;
this.data = this._data;
return this;
}
}

View File

@@ -0,0 +1,51 @@
package mjkf.xinke.main.constant;
import com.jgy.xxs.core.http.exp.NcHttpErrorResponseInterface;
import org.apache.http.HttpStatus;
/**
* HttpErrorResponseEnum
*
* @author han0
* @date 2019-08-19
*/
public enum HttpErrorResponseEnum implements NcHttpErrorResponseInterface {
// 通用异常
SYSTEM_ERROR("系统异常", 500, HttpStatus.SC_INTERNAL_SERVER_ERROR),
BAD_REQUEST("请求数据错误!", 400, HttpStatus.SC_BAD_REQUEST),
FORBIDDEN("没权限访问,请退出重新登录!", 403, HttpStatus.SC_FORBIDDEN),
NOT_FOUND("找不到指定资源", 404, HttpStatus.SC_NOT_FOUND),
//
MATERIAL_NOT_FOUND("找不到指定材料", 404, HttpStatus.SC_NOT_FOUND),
MATERIAL_CANNOT_DELETE_BUILTIN("内建材料不允许删除", 400, HttpStatus.SC_NOT_FOUND),
MATERIAL_ID_REPEAT("材料 id 重复", 400, HttpStatus.SC_NOT_FOUND),
MATERIAL_ID_INVALID("材料 id 无效", 400, HttpStatus.SC_NOT_FOUND),
MATERIAL_PARENT_ID_INVALID("材料 parent_id 无效", 400, HttpStatus.SC_NOT_FOUND),
;
private String message;
private int code;
private int httpStatus;
HttpErrorResponseEnum(String message, int code, int httpStatus) {
this.message = message;
this.code = code;
this.httpStatus = httpStatus;
}
@Override
public String getMessage() {
return this.message;
}
@Override
public int getCode() {
return this.code;
}
@Override
public int getHttpStatusCode() {
return this.httpStatus;
}
}

View File

@@ -0,0 +1,136 @@
package mjkf.xinke.main.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jgy.xxs.core.common.util.CommonUtil;
import com.jgy.xxs.core.http.exp.NcHttpException;
import com.jgy.xxs.core.http.resp.HttpResponse;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import mjkf.xinke.auth.core.pojo.SaBaseLoginUser;
import mjkf.xinke.auth.core.util.StpLoginUserUtil;
import mjkf.xinke.main.common.http.FuHttpResponse;
import mjkf.xinke.main.constant.HttpErrorResponseEnum;
import mjkf.xinke.main.model.db.Material;
import mjkf.xinke.main.model.vo.MaterialCreateRequest;
import mjkf.xinke.main.model.vo.MaterialEditRequest;
import mjkf.xinke.main.service.MaterialService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* <p>
* 材料 前端控制器
* </p>
*
* @author han0
* @since 2023-11-09
*/
@RestController
@RequestMapping("/material")
public class MaterialController {
@Resource
MaterialService materialService;
@ApiOperation("获取材料树")
@GetMapping("/tree")
public HttpResponse getTree () {
QueryWrapper<Material> query = new QueryWrapper<>();
List<Map<String, Object>> maps = materialService.listMaps(query);
maps = maps.stream().map(map -> convertKeysToLowercase(map)).collect(Collectors.toList());
// todo 列转树改为泛型对象入参
List<Map<String, Object>> result = CommonUtil.listToTree(maps, Material.Fields.id, StrUtil.toUnderlineCase(Material.Fields.parentId), "00.00.00.00");
return FuHttpResponse.Builder().dataResponse(result).build();
}
private Map<String, Object> convertKeysToLowercase(Map<String, Object> originalMap) {
Map<String, Object> resultMap = new HashMap<>();
// 遍历原始Map的entry将key转为小写
for (Map.Entry<String, Object> entry : originalMap.entrySet()) {
String lowercaseKey = entry.getKey().toLowerCase();
resultMap.put(lowercaseKey, entry.getValue());
}
return resultMap;
}
@ApiOperation("获取材料列表")
@GetMapping("/")
public HttpResponse list (
@ApiParam(value = "关键字") String keyWord,
@ApiParam(value = "父节点id") String parentId
) {
LambdaQueryWrapper<Material> query = new LambdaQueryWrapper<>();
if (parentId != null){
query.eq(Material::getParentId, parentId);
}
query.and(q -> q
.like(Material::getCategory1, keyWord).or()
.like(Material::getCategory2, keyWord).or()
.like(Material::getCategory3, keyWord).or()
.like(Material::getCategory4, keyWord)
);
var result = materialService.list(query);
return FuHttpResponse.Builder().dataResponse(result).build();
}
@ApiOperation("删除材料")
@DeleteMapping("/{id}")
public HttpResponse delete (
@PathVariable String id
) throws Exception {
var data = materialService.getById(id);
if (data == null) {
throw new NcHttpException(HttpErrorResponseEnum.MATERIAL_NOT_FOUND);
}
if (data.isBuiltin()) {
throw new NcHttpException(HttpErrorResponseEnum.MATERIAL_CANNOT_DELETE_BUILTIN);
}
materialService.removeById(id);
return FuHttpResponse.Builder().dataResponse().build();
}
@ApiOperation("新增材料")
@PostMapping("/")
public HttpResponse create (
@ApiParam("参数") @RequestBody MaterialCreateRequest params
) throws Exception {
params.check();
var user = StpLoginUserUtil.getLoginUser();
var data = materialService.getById(params.getId());
if (data != null) {
throw new NcHttpException(HttpErrorResponseEnum.MATERIAL_ID_REPEAT);
}
data = new Material(params, user);
materialService.save(data);
return FuHttpResponse.Builder().dataResponse(data).build();
}
@ApiOperation("编辑材料")
@PutMapping("/{id}")
public HttpResponse edit (
@PathVariable String id,
@ApiParam("参数") @RequestBody MaterialEditRequest params
) throws Exception {
params.check();
var user = StpLoginUserUtil.getLoginUser();
var data = materialService.getById(id);
if (data == null) {
throw new NcHttpException(HttpErrorResponseEnum.MATERIAL_NOT_FOUND);
}
data.edit(params, user);
return FuHttpResponse.Builder().dataResponse(data).build();
}
}

View File

@@ -0,0 +1,16 @@
package mjkf.xinke.main.dao;
import mjkf.xinke.main.model.db.Material;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 材料 Mapper 接口
* </p>
*
* @author han0
* @since 2023-11-10
*/
public interface MaterialMapper extends BaseMapper<Material> {
}

View File

@@ -0,0 +1,148 @@
package mjkf.xinke.main.model.db;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import java.io.Serializable;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.FieldNameConstants;
import mjkf.xinke.auth.core.pojo.SaBaseLoginUser;
import mjkf.xinke.main.model.vo.MaterialCreateRequest;
import mjkf.xinke.main.model.vo.MaterialEditRequest;
/**
* <p>
* 材料
* </p>
*
* @author han0
* @since 2023-11-10
*/
@Getter
@Setter
@FieldNameConstants
@TableName("MATERIAL")
@ApiModel(value = "Material对象", description = "材料")
public class Material extends Model<Material> {
private static final long serialVersionUID = 1L;
@ApiModelProperty("最后更新人id")
@TableField("UPDATE_USER_ID")
private String updateUserId;
@ApiModelProperty("最后更新人名称")
@TableField("UPDATE_USER_NAME")
private String updateUserName;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@ApiModelProperty("最后更新时间")
@TableField("UPDATE_TIME")
private LocalDateTime updateTime;
@ApiModelProperty("创建人id")
@TableField("CREATE_USER_ID")
private String createUserId;
@ApiModelProperty("创建人名称")
@TableField("CREATE_USER_NAME")
private String createUserName;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@ApiModelProperty("创建时间")
@TableField("CREATE_TIME")
private LocalDateTime createTime;
@ApiModelProperty("删除人id")
@TableField("DELETE_USER_ID")
private String deleteUserId;
@ApiModelProperty("删除人名称")
@TableField("DELETE_USER_NAME")
private String deleteUserName;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@ApiModelProperty("删除时间")
@TableField("DELETE_TIME")
private LocalDateTime deleteTime;
@TableId(value = "ID", type = IdType.AUTO)
private String id;
@TableField("PARENT_ID")
private String parentId;
@ApiModelProperty("分类1")
@TableField("CATEGORY1")
private String category1;
@ApiModelProperty("分类2")
@TableField("CATEGORY2")
private String category2;
@ApiModelProperty("分类3")
@TableField("CATEGORY3")
private String category3;
@ApiModelProperty("分类4")
@TableField("CATEGORY4")
private String category4;
@ApiModelProperty("是否初始内建类型(不允许删除)")
@TableField("IS_BUILTIN")
private Integer isBuiltin;
@ApiModelProperty("材料类别(主材、地材)")
@TableField("`TYPE`")
private Integer type;
@Override
public Serializable pkVal() {
return this.id;
}
public boolean isBuiltin() {
if (this.isBuiltin == null) {
return false;
}
return this.isBuiltin.equals(1);
}
public Material() {}
public Material(MaterialCreateRequest params, SaBaseLoginUser user) {
this.id = params.getId();
this.parentId = params.getParentId();
this.category1 = params.getCategory1();
this.category2 = params.getCategory2();
this.category3 = params.getCategory3();
this.category4 = params.getCategory4();
this.updateTime = LocalDateTime.now();
this.createTime = LocalDateTime.now();
this.createUserName = user.getName();
this.createUserId = user.getId();
}
public void edit(MaterialEditRequest params, SaBaseLoginUser user) {
this.category1 = params.getCategory1();
this.category2 = params.getCategory2();
this.category3 = params.getCategory3();
this.category4 = params.getCategory4();
this.updateTime = LocalDateTime.now();
this.updateUserName = user.getName();
this.updateUserId = user.getId();
}
}

View File

@@ -0,0 +1,47 @@
package mjkf.xinke.main.model.vo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.jgy.xxs.core.http.exp.NcHttpException;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import mjkf.xinke.main.constant.HttpErrorResponseEnum;
@Data
public class MaterialCreateRequest {
@TableId(value = "ID", type = IdType.AUTO)
private String id;
@ApiModelProperty("父级id")
private String parentId;
@ApiModelProperty("分类1")
private String category1;
@ApiModelProperty("分类2")
private String category2;
@ApiModelProperty("分类3")
private String category3;
@ApiModelProperty("分类4")
private String category4;
public void check() throws Exception{
String flag = this.parentId.replace(".00", "");
if (!this.id.contains(flag)) {
throw new NcHttpException(HttpErrorResponseEnum.MATERIAL_ID_INVALID);
}
if ((int) this.id.chars().filter(c -> c == '.').count() != 3) {
throw new NcHttpException(HttpErrorResponseEnum.MATERIAL_ID_INVALID);
}
if ((int) this.parentId.chars().filter(c -> c == '.').count() != 3) {
throw new NcHttpException(HttpErrorResponseEnum.MATERIAL_PARENT_ID_INVALID);
}
if (this.parentId.chars().filter(c -> c == '0').count() < this.id.chars().filter(c -> c == '0').count()) {
throw new NcHttpException(HttpErrorResponseEnum.MATERIAL_ID_INVALID);
}
}
}

View File

@@ -0,0 +1,25 @@
package mjkf.xinke.main.model.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class MaterialEditRequest {
@ApiModelProperty("分类1")
private String category1;
@ApiModelProperty("分类2")
private String category2;
@ApiModelProperty("分类3")
private String category3;
@ApiModelProperty("分类4")
private String category4;
public void check() throws Exception{
}
}

View File

@@ -0,0 +1,12 @@
package mjkf.xinke.main.service;
import mjkf.xinke.main.model.db.Material;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class MaterialService extends ServiceImpl<BaseMapper<Material>, Material> {
}

View File

@@ -0,0 +1,16 @@
package ${package.Service};
import ${package.Entity}.${entity};
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import ${superServiceClassPackage};
import org.springframework.stereotype.Service;
<#if kotlin>
class ${entity}Service : ${superServiceClass}<BaseMapper<${entity}>, ${entity}>
<#else>
@Service
public class ${entity}Service extends ${superServiceClass}<BaseMapper<${entity}>, ${entity}> {
}
</#if>