提交 613f16e6 作者: 方治民

feat: 开发分支合并

...@@ -22,9 +22,11 @@ dependencies { ...@@ -22,9 +22,11 @@ dependencies {
// 本地依赖 // 本地依赖
implementation fileTree(dir: project.rootDir.getPath() + '\\libs', includes: ['*jar']) implementation fileTree(dir: project.rootDir.getPath() + '\\libs', includes: ['*jar'])
// 公共依赖
implementation project(":basic-common:core") implementation project(":basic-common:core")
implementation project(":basic-common:util") implementation project(":basic-common:util")
// 服务依赖
implementation project(":app-push") implementation project(":app-push")
// Optional: Redis // Optional: Redis
...@@ -49,6 +51,7 @@ dependencies { ...@@ -49,6 +51,7 @@ dependencies {
// hutool // hutool
implementation "cn.hutool:hutool-core:${hutoolVersion}" implementation "cn.hutool:hutool-core:${hutoolVersion}"
implementation "cn.hutool:hutool-extra:${hutoolVersion}" implementation "cn.hutool:hutool-extra:${hutoolVersion}"
implementation "cn.hutool:hutool-http:${hutoolVersion}"
// JPA 增加空间字段支持 // JPA 增加空间字段支持
// https://blog.wuwii.com/jpa-spatial.html // https://blog.wuwii.com/jpa-spatial.html
...@@ -59,4 +62,11 @@ dependencies { ...@@ -59,4 +62,11 @@ dependencies {
// JTS 几何对象操作库 // JTS 几何对象操作库
implementation "org.locationtech.jts:jts-core:${jtsVersion}" implementation "org.locationtech.jts:jts-core:${jtsVersion}"
// https://github.com/vladmihalcea/hibernate-types
// hibernate-types-55
implementation "com.vladmihalcea:hibernate-types-55:${hibernateTypesVersion}"
// myexcel
implementation "com.github.liaochong:myexcel:${myexcelVersion}"
} }
...@@ -9,7 +9,7 @@ import javax.persistence.*; ...@@ -9,7 +9,7 @@ import javax.persistence.*;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
import org.hibernate.annotaions.Comment; import org.hibernate.annotations.Comment;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
import org.hibernate.snowflake.SnowflakeId; import org.hibernate.snowflake.SnowflakeId;
......
...@@ -14,6 +14,7 @@ import lombok.experimental.FieldNameConstants; ...@@ -14,6 +14,7 @@ import lombok.experimental.FieldNameConstants;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.annotations.Comment; import org.hibernate.annotations.Comment;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Type;
import org.hibernate.snowflake.SnowflakeId; import org.hibernate.snowflake.SnowflakeId;
import org.locationtech.jts.geom.Point; import org.locationtech.jts.geom.Point;
...@@ -86,6 +87,8 @@ public class LocationBeacon implements Serializable { ...@@ -86,6 +87,8 @@ public class LocationBeacon implements Serializable {
Double distance; Double distance;
@Comment("坐标点信息") @Comment("坐标点信息")
@Type(type = "jts_geometry")
@Column(columnDefinition = "point")
Point point; Point point;
@FieldMapping @FieldMapping
......
...@@ -13,6 +13,7 @@ import lombok.experimental.FieldDefaults; ...@@ -13,6 +13,7 @@ import lombok.experimental.FieldDefaults;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
import org.hibernate.annotations.Comment; import org.hibernate.annotations.Comment;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Type;
import org.hibernate.snowflake.SnowflakeId; import org.hibernate.snowflake.SnowflakeId;
import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Geometry;
...@@ -71,6 +72,8 @@ public class LocationFence implements Serializable { ...@@ -71,6 +72,8 @@ public class LocationFence implements Serializable {
String shapeType; String shapeType;
@Comment("空间信息") @Comment("空间信息")
@Type(type = "jts_geometry")
@Column(columnDefinition = "geometry")
Geometry geometry; Geometry geometry;
@Comment("半径,米/单位(圆形围栏)") @Comment("半径,米/单位(圆形围栏)")
......
/* (C) 2022 YiRing, Inc. */ /* (C) 2022 YiRing, Inc. */
package com.yiring.app.domain.location; package com.yiring.app.domain.location;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSON;
import com.vladmihalcea.hibernate.type.json.JsonType;
import com.yiring.auth.domain.user.User; import com.yiring.auth.domain.user.User;
import com.yiring.common.config.converter.JSONObjectConverter;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
...@@ -18,6 +18,8 @@ import lombok.experimental.FieldNameConstants; ...@@ -18,6 +18,8 @@ import lombok.experimental.FieldNameConstants;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.annotations.Comment; import org.hibernate.annotations.Comment;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.hibernate.snowflake.SnowflakeId; import org.hibernate.snowflake.SnowflakeId;
import org.locationtech.jts.geom.Point; import org.locationtech.jts.geom.Point;
...@@ -39,6 +41,7 @@ import org.locationtech.jts.geom.Point; ...@@ -39,6 +41,7 @@ import org.locationtech.jts.geom.Point;
@FieldNameConstants @FieldNameConstants
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
@Entity @Entity
@TypeDef(name = "json", typeClass = JsonType.class)
@Table(name = "BS_LOCATION_LOG", indexes = { @Index(columnList = "time"), @Index(columnList = "silent") }) @Table(name = "BS_LOCATION_LOG", indexes = { @Index(columnList = "time"), @Index(columnList = "silent") })
@Comment("定位数据") @Comment("定位数据")
public class LocationLog implements Serializable { public class LocationLog implements Serializable {
...@@ -85,7 +88,8 @@ public class LocationLog implements Serializable { ...@@ -85,7 +88,8 @@ public class LocationLog implements Serializable {
BigDecimal altitude; BigDecimal altitude;
@Comment("坐标点信息") @Comment("坐标点信息")
@Column(columnDefinition = "POINT") @Type(type = "jts_geometry")
@Column(columnDefinition = "point")
Point point; Point point;
@Comment("信标集合") @Comment("信标集合")
...@@ -110,12 +114,9 @@ public class LocationLog implements Serializable { ...@@ -110,12 +114,9 @@ public class LocationLog implements Serializable {
String voltUnit; String voltUnit;
@Comment("原始数据") @Comment("原始数据")
@Convert(converter = JSONObjectConverter.class) @org.hibernate.annotations.Type(type = "json")
@Lob @Column(columnDefinition = "json")
@Basic(fetch = FetchType.LAZY) JSON raw;
@Column(columnDefinition = "JSON")
@ToString.Exclude
JSONObject raw;
@Comment("创建时间") @Comment("创建时间")
LocalDateTime createTime; LocalDateTime createTime;
......
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.domain.location;
import java.io.Serializable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
/**
* 定位标签JPA
* @author LJ-2204
* @date 2022/4/14
*/
@Repository
public interface LocationTagRepository
extends JpaRepository<LocationTag, Serializable>, JpaSpecificationExecutor<LocationTag> {}
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.excel.location;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.github.liaochong.myexcel.core.annotation.ExcelColumn;
import com.github.liaochong.myexcel.core.annotation.ExcelModel;
import com.yiring.app.domain.location.LocationTag;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
/**
* 定位标签导出模型
* @author LJ-2204
* @date 2022/4/14
*/
@ExcelModel
@Data
@Builder
@FieldDefaults(level = AccessLevel.PRIVATE)
public class LocationTagExportExcel implements Serializable {
private static final long serialVersionUID = -4549580878785078998L;
@ExcelColumn(title = "主键")
@JsonSerialize(using = ToStringSerializer.class)
Long id;
@ExcelColumn(title = "编号")
String code;
@ExcelColumn(title = "标签类型")
LocationTag.Type type;
@ExcelColumn(title = "状态")
Boolean silent;
@ExcelColumn(title = "imei")
String imei;
@ExcelColumn(title = "电量")
Integer volt;
@ExcelColumn(title = "最近更新时间")
LocalDateTime updateTime;
public static List<LocationTagExportExcel> transforms(List<LocationTag> locationTags) {
return locationTags
.stream()
.map(locationTag ->
LocationTagExportExcel
.builder()
.id(locationTag.getId())
.code(locationTag.getCode())
.type(locationTag.getType())
.silent(locationTag.getSilent())
.imei(locationTag.getImei())
.volt(locationTag.getVolt())
.updateTime(locationTag.getUpdateTime())
.build()
)
.collect(Collectors.toList());
}
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.excel.location;
import com.github.liaochong.myexcel.core.annotation.ExcelColumn;
import com.yiring.app.domain.location.LocationTag;
import java.io.Serializable;
import lombok.*;
import lombok.experimental.FieldDefaults;
/**
* @author LJ-2204
* @date 2022/4/14
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class LocationTagImportExcel implements Serializable {
private static final long serialVersionUID = -8817732062049005201L;
// 编号
@ExcelColumn(index = 0)
String code;
// 标签型号
@ExcelColumn(index = 1)
String type;
// 设备编码
@ExcelColumn(index = 2)
String imei;
public LocationTag transform() {
return LocationTag.builder().code(this.code).type(LocationTag.Type.valueOf(this.type)).imei(this.imei).build();
}
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.param.location;
import com.yiring.app.domain.location.LocationTag;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import lombok.*;
import lombok.experimental.FieldDefaults;
/**
* 定位标签新增入参
* @author LJ-2204
* @date 2022/4/14
*/
@ApiModel("LocationTagAddParam")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class LocationTagAddParam implements Serializable {
private static final long serialVersionUID = -2942040230386389302L;
@ApiModelProperty(value = "编号", example = "BTT88888888", required = true)
String code;
@ApiModelProperty(value = "标签类型", example = "蓝牙人员定位卡", required = true)
LocationTag.Type type;
@ApiModelProperty(value = "imei 设备编码标识", example = "88888888")
String imei;
public LocationTag transform() {
return LocationTag.builder().code(this.code).type(this.type).imei(this.imei).build();
}
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.param.location;
import com.yiring.auth.domain.user.User;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import javax.validation.constraints.NotNull;
import lombok.*;
import lombok.experimental.FieldDefaults;
/**
* 定位标签销毁入参
* @author LJ-2204
* @date 2022/4/14
*/
@ApiModel("LocationTagDeleteParam")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class LocationTagDeleteParam implements Serializable {
private static final long serialVersionUID = 2404060244461070885L;
@ApiModelProperty(value = "id", example = "145235231", required = true)
@NotNull(message = "id 不能为空")
Long id;
@ApiModelProperty(value = "人员", example = "1")
User user;
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.param.location;
import com.yiring.app.domain.location.LocationTag;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import lombok.*;
import lombok.experimental.FieldDefaults;
/**
* 定位标签分页入参
* @author LJ-2204
* @date 2022/4/14
*/
@ApiModel("LocationTagFindParam")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class LocationTagFindParam implements Serializable {
private static final long serialVersionUID = -5134311481372693111L;
@ApiModelProperty(value = "编号", example = "BTT88888888")
String code;
@ApiModelProperty(value = "标签类型", example = "蓝牙人员定位卡")
LocationTag.Type type;
@ApiModelProperty(value = "状态", example = "true")
Boolean silent;
@ApiModelProperty(value = "每页记录数", example = "10")
Integer pageSize;
@ApiModelProperty(value = "页码", example = "1")
Integer pageNo;
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.param.location;
import com.yiring.app.domain.location.LocationTag;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import lombok.*;
import lombok.experimental.FieldDefaults;
/**
* 定位标签修改入参
* @author LJ-2204
* @date 2022/4/14
*/
@ApiModel("LocationTagModifyParam")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class LocationTagModifyParam implements Serializable {
private static final long serialVersionUID = 7711908393372149723L;
@ApiModelProperty(value = "编号", example = "BTT88888888", required = true)
String code;
@ApiModelProperty(value = "标签类型", example = "蓝牙人员定位卡", required = true)
LocationTag.Type type;
@ApiModelProperty(value = "imei 设备编码标识", example = "88888888")
String imei;
public LocationTag transform() {
return LocationTag.builder().code(this.code).type(this.type).imei(this.imei).build();
}
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.param.location.zy;
import cn.hutool.core.util.StrUtil;
import com.yiring.app.domain.location.LocationTag;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import lombok.*;
import lombok.experimental.FieldDefaults;
/**
* zy定位标签新增入参
* @author LJ-2204
* @date 2022/4/15
*/
@ApiModel("ZyLocationTagAddParam")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class ZyLocationTagAddParam implements Serializable {
private static final long serialVersionUID = -8828137320896062620L;
@ApiModelProperty(value = "工厂", example = "100")
String orgId;
@ApiModelProperty(value = "标签类型", example = "蓝牙人员定位卡", required = true)
LocationTag.Type types;
@ApiModelProperty(value = "编号", example = "BTT88888888", required = true)
String tagId;
@ApiModelProperty(value = "实体类型", example = "car", required = true)
String entityType;
public static ZyLocationTagAddParam transform(LocationTag locationTag) {
String entityType = StrUtil.equals(locationTag.getType().name(), "BTT02") ? "car" : "staff";
return ZyLocationTagAddParam
.builder()
.orgId("100")
.tagId(locationTag.getCode())
.types(locationTag.getType())
.entityType(entityType)
.build();
}
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.service.location;
import com.yiring.app.param.location.LocationTagAddParam;
import com.yiring.app.param.location.LocationTagDeleteParam;
import com.yiring.app.param.location.LocationTagFindParam;
import com.yiring.app.param.location.LocationTagModifyParam;
import com.yiring.app.vo.location.LocationTagVo;
import com.yiring.common.core.Result;
import com.yiring.common.param.IdParam;
import com.yiring.common.vo.PageVo;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;
/**
* 定位标签
* @author LJ-2204
* @date 2022/4/14
*/
public interface LocationTagService {
/**
* 新增定位标签
* @param param 入参
* @return Result<String>
*/
Result<String> addLocationTag(LocationTagAddParam param);
/**
* 分页查询
* @param param 入参
* @return Result<PageVo<LocationTagVo>>
*/
Result<PageVo<LocationTagVo>> findLocationTagPage(LocationTagFindParam param);
/**
* 销毁定位标签
* @param param 入参
* @return Result<String>
*/
Result<String> deleteLocationTag(LocationTagDeleteParam param);
/**
* 导出定位标签
* @param param 入参
* @param response 响应信息
*/
void exportLocationTagInfo(LocationTagFindParam param, HttpServletResponse response);
/**
* 导入定位标签
* @param file 文件
* @return Result<String>
*/
Result<String> importLocationTagInfo(MultipartFile file);
/**
* 修改定位标签
* @param param 入参
* @return Result<String>
*/
Result<String> modifyLocationTag(LocationTagModifyParam param, IdParam idParam);
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.service.location.impl;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.liaochong.myexcel.core.DefaultStreamExcelBuilder;
import com.github.liaochong.myexcel.core.SaxExcelReader;
import com.yiring.app.domain.location.LocationTag;
import com.yiring.app.domain.location.LocationTagRepository;
import com.yiring.app.excel.location.LocationTagExportExcel;
import com.yiring.app.excel.location.LocationTagImportExcel;
import com.yiring.app.param.location.LocationTagAddParam;
import com.yiring.app.param.location.LocationTagDeleteParam;
import com.yiring.app.param.location.LocationTagFindParam;
import com.yiring.app.param.location.LocationTagModifyParam;
import com.yiring.app.param.location.zy.ZyLocationTagAddParam;
import com.yiring.app.service.location.LocationTagService;
import com.yiring.app.vo.location.LocationTagVo;
import com.yiring.auth.util.ZyUtil;
import com.yiring.common.core.Result;
import com.yiring.common.core.Status;
import com.yiring.common.param.IdParam;
import com.yiring.common.vo.PageVo;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
/**
* 定位标签
* @author LJ-2204
* @date 2022/4/14
*/
@Transactional(rollbackFor = RuntimeException.class)
@Service
@Slf4j
public class LocationTagServiceImpl implements LocationTagService {
final Integer FACTORY_ID = 100;
@Resource
LocationTagRepository locationTagRepository;
@Override
public Result<String> addLocationTag(LocationTagAddParam param) {
if (hasLocationTagInfoByCode(param.getCode())) return Result.no(Status.BAD_REQUEST, "编号已存在");
LocationTag locationTag = param.transform();
locationTagRepository.save(locationTag);
ZyLocationTagAddParam zyLocationTagAddParam = ZyLocationTagAddParam.transform(locationTag);
List<ZyLocationTagAddParam> of = ListUtil.of(zyLocationTagAddParam);
new Thread(() -> {
Result<Serializable> result = ZyUtil.post("/positionApi/api/tag/saveTag", of, 3000);
if (result.getCode() != 200) throw new RuntimeException(result.getMessage());
})
.start();
return Result.ok();
}
@Override
public Result<PageVo<LocationTagVo>> findLocationTagPage(LocationTagFindParam param) {
Specification<LocationTag> specification = getLocationTagPageSpecification(param);
Sort sort = Sort.by(Sort.Order.desc(LocationTag.Fields.createTime));
if (Objects.nonNull(param.getPageNo()) && Objects.nonNull(param.getPageSize())) {
//分页
Pageable pageable = PageRequest.of(param.getPageNo() - 1, param.getPageSize());
Page<LocationTag> locationTags = locationTagRepository.findAll(specification, pageable);
List<LocationTagVo> locationTagVos = LocationTagVo.transforms(locationTags.getContent());
PageVo<LocationTagVo> page = PageVo.build(locationTagVos, locationTagVos.size());
return Result.ok(page);
} else {
List<LocationTag> locationTags = locationTagRepository.findAll(specification, sort);
List<LocationTagVo> locationTagVos = LocationTagVo.transforms(locationTags);
PageVo<LocationTagVo> page = PageVo.build(locationTagVos, locationTagVos.size());
return Result.ok(page);
}
}
@Override
public Result<String> deleteLocationTag(LocationTagDeleteParam param) {
if (ObjectUtil.isNotEmpty(param.getUser())) return Result.no(Status.BAD_REQUEST, "请先解绑人员");
locationTagRepository.deleteById(param.getId());
return Result.ok();
}
@Override
public void exportLocationTagInfo(LocationTagFindParam param, HttpServletResponse response) {
Specification<LocationTag> specification = getLocationTagPageSpecification(param);
List<LocationTag> locationTags = locationTagRepository.findAll(specification);
List<LocationTagExportExcel> locationTagExportExcels = LocationTagExportExcel.transforms(locationTags);
try (
DefaultStreamExcelBuilder<LocationTagExportExcel> streamExcelBuilder = DefaultStreamExcelBuilder
.of(LocationTagExportExcel.class)
.threadPool(Executors.newFixedThreadPool(2))
.rowHeight(14)
.titleRowHeight(14)
.style(
"cell->vertical-align:center;text-align:center",
"title->vertical-align:center;text-align:center;font-weight:bold;font-family:等线"
)
.start()
) {
streamExcelBuilder.append(locationTagExportExcels);
String fileName = URLEncoder.encode("定位标签信息.xlsx", StandardCharsets.UTF_8);
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
OutputStream out = response.getOutputStream();
Workbook workbook = streamExcelBuilder.fixedTitles().build();
workbook.write(out);
workbook.close();
out.flush();
out.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new RuntimeException("导出岗位信息失败: " + e.getMessage());
}
}
@Override
public Result<String> importLocationTagInfo(MultipartFile file) {
if (file.isEmpty()) throw new RuntimeException("请选择文件");
List<LocationTagImportExcel> locationTagImportExcels;
try (InputStream inputStream = file.getInputStream()) {
locationTagImportExcels =
SaxExcelReader
.of(LocationTagImportExcel.class)
.rowFilter(row -> row.getRowNum() > 0)
.ignoreBlankRow()
.read(inputStream);
} catch (IOException e) {
log.info(e.getMessage());
throw new RuntimeException("文件导入异常");
}
List<LocationTag> locationTags = locationTagImportExcels
.stream()
.map(LocationTagImportExcel::transform)
.collect(Collectors.toList());
locationTags.forEach(locationTag -> {
locationTagRepository
.findOne((root, cq, cb) -> {
List<Predicate> predicates = new ArrayList<>();
if (StrUtil.isNotEmpty(locationTag.getCode())) {
predicates.add(cb.equal(root.get(LocationTag.Fields.code), locationTag.getCode()));
}
return cq.where(predicates.toArray(new Predicate[0])).getRestriction();
})
.ifPresent(temp -> locationTag.setId(temp.getId()));
locationTagRepository.save(locationTag);
});
return Result.ok();
}
@Override
public Result<String> modifyLocationTag(LocationTagModifyParam param, IdParam idParam) {
Optional<LocationTag> locationTagOptional = locationTagRepository.findById(idParam.getId());
if (locationTagOptional.isEmpty()) return Result.no(Status.BAD_REQUEST, "被修改的数据不存在");
LocationTag locationTag = locationTagOptional.get();
if (!StrUtil.equals(locationTag.getCode(), param.getCode())) {
if (hasLocationTagInfoByCode(param.getCode())) return Result.no(Status.BAD_REQUEST, "编号已存在");
}
locationTag = param.transform();
locationTag.setId(idParam.getId());
locationTagRepository.save(locationTag);
return Result.ok();
}
private boolean hasLocationTagInfoByCode(String code) {
LocationTag locationTag = LocationTag.builder().code(code).build();
return locationTagRepository.count(Example.of(locationTag)) > 0;
}
@NotNull
private Specification<LocationTag> getLocationTagPageSpecification(LocationTagFindParam param) {
return (root, cq, cb) -> {
List<Predicate> predicates = ListUtil.toList();
if (StrUtil.isNotEmpty(param.getCode())) {
cb.equal(root.get(LocationTag.Fields.code), param.getCode());
}
if (ObjectUtil.isNotEmpty(param.getType())) {
cb.equal(root.get(LocationTag.Fields.type), param.getType());
}
if (ObjectUtil.isNotEmpty(param.getSilent())) {
cb.equal(root.get(LocationTag.Fields.silent), param.getSilent());
}
Order order = cb.desc(root.get(LocationTag.Fields.createTime));
return cq.orderBy(order).where(predicates.toArray(new Predicate[0])).getRestriction();
};
}
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.vo.location;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.yiring.app.domain.location.LocationTag;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
import lombok.*;
import lombok.experimental.FieldDefaults;
/**
* 定位标签视图
* @author LJ-2204
* @date 2022/4/14
*/
@ApiModel("LocationTagVo")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class LocationTagVo implements Serializable {
private static final long serialVersionUID = -7884163207638158359L;
@JsonSerialize(using = ToStringSerializer.class)
@ApiModelProperty(value = "主键", example = "188354391834")
Long id;
@ApiModelProperty(value = "编号", example = "BTT88888888")
String code;
@ApiModelProperty(value = "标签型号", example = "BTT01")
LocationTag.Type type;
@ApiModelProperty(value = "状态", example = "静止")
Boolean silent;
@ApiModelProperty(value = "电量", example = "1")
Integer volt;
@ApiModelProperty(value = "imei 设备编码", example = "88888888")
String imei;
@ApiModelProperty(value = "最近更新时间", example = "2022-01-01 00:00:00")
LocalDateTime updateTime;
public static List<LocationTagVo> transforms(List<LocationTag> locationTags) {
return locationTags
.stream()
.map(locationTag ->
LocationTagVo
.builder()
.id(locationTag.getId())
.code(locationTag.getCode())
.type(locationTag.getType())
.silent(locationTag.getSilent())
.volt(locationTag.getVolt())
.build()
)
.collect(Collectors.toList());
}
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.web;
import com.yiring.app.param.location.LocationTagAddParam;
import com.yiring.app.param.location.LocationTagDeleteParam;
import com.yiring.app.param.location.LocationTagFindParam;
import com.yiring.app.param.location.LocationTagModifyParam;
import com.yiring.app.service.location.LocationTagService;
import com.yiring.app.vo.location.LocationTagVo;
import com.yiring.common.core.Result;
import com.yiring.common.param.IdParam;
import com.yiring.common.vo.PageVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
/**
* 定位标签
* @author LJ-2204
* @date 2022/4/13
*/
@Slf4j
@Validated
@Api(tags = "定位标签")
@RestController
@RequestMapping("/location/tag/")
public class LocationTagController {
@Resource
LocationTagService locationTagService;
@ApiOperation("新增定位标签")
@PostMapping("addLocationTag")
public Result<String> addLocationTag(@Valid LocationTagAddParam param) {
return locationTagService.addLocationTag(param);
}
@ApiOperation("分页查询")
@GetMapping("findLocationTagPage")
public Result<PageVo<LocationTagVo>> findLocationTagPage(@Valid LocationTagFindParam param) {
return locationTagService.findLocationTagPage(param);
}
@ApiOperation("销毁定位标签")
@DeleteMapping("deleteLocationTag")
public Result<String> deleteLocationTag(@Valid LocationTagDeleteParam param) {
return locationTagService.deleteLocationTag(param);
}
@ApiOperation("导出定位标签")
@GetMapping("exportLocationTagInfo")
public void exportLocationTagInfo(@Valid LocationTagFindParam param, HttpServletResponse response) {
locationTagService.exportLocationTagInfo(param, response);
}
@ApiOperation("导入定位标签")
@PostMapping("importLocationTagInfo")
public Result<String> importLocationTagInfo(@RequestParam("file") MultipartFile file) {
return locationTagService.importLocationTagInfo(file);
}
@ApiOperation("修改定位标签")
@PutMapping("modifyLocationTag")
public Result<String> modifyLocationTag(@Valid LocationTagModifyParam param, IdParam idParam) {
return locationTagService.modifyLocationTag(param, idParam);
}
}
...@@ -18,6 +18,17 @@ dependencies { ...@@ -18,6 +18,17 @@ dependencies {
// hutool-core // hutool-core
implementation "cn.hutool:hutool-core:${hutoolVersion}" implementation "cn.hutool:hutool-core:${hutoolVersion}"
// hutool-json
implementation "cn.hutool:hutool-json:${hutoolVersion}"
// hutool-http
implementation "cn.hutool:hutool-http:${hutoolVersion}"
// fastjson // fastjson
implementation "com.alibaba:fastjson:${fastJsonVersion}" implementation "com.alibaba:fastjson:${fastJsonVersion}"
// myexcel
implementation "com.github.liaochong:myexcel:${myexcelVersion}"
} }
/* (C) 2022 YiRing, Inc. */
package com.yiring.auth.config;
import java.time.Duration;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* Redis Config
* @author LJ-2204
* @date 2022/4/15
*/
@EnableCaching
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setEnableTransactionSupport(true);
redisTemplate.setConnectionFactory(factory);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration config = RedisCacheConfiguration
.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(5))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(
RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())
)
.disableCachingNullValues();
return RedisCacheManager.builder(connectionFactory).cacheDefaults(config).transactionAware().build();
}
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory) {
RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
return redisMessageListenerContainer;
}
}
...@@ -3,6 +3,7 @@ package com.yiring.auth.domain.post; ...@@ -3,6 +3,7 @@ package com.yiring.auth.domain.post;
import java.io.Serializable; import java.io.Serializable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
/** /**
...@@ -12,4 +13,4 @@ import org.springframework.stereotype.Repository; ...@@ -12,4 +13,4 @@ import org.springframework.stereotype.Repository;
*/ */
@Repository @Repository
public interface PostRepository extends JpaRepository<Post, Serializable> {} public interface PostRepository extends JpaRepository<Post, Serializable>, JpaSpecificationExecutor<Post> {}
/* (C) 2022 YiRing, Inc. */
package com.yiring.auth.excel.post;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.github.liaochong.myexcel.core.annotation.ExcelColumn;
import com.github.liaochong.myexcel.core.annotation.ExcelModel;
import com.yiring.auth.domain.post.Post;
import java.util.List;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
/**
* 职位信息导出模型
* @author LJ-2204
* @date 2022/4/13
*/
@ExcelModel
@Data
@Builder
@FieldDefaults(level = AccessLevel.PRIVATE)
public class PostExcel {
@ExcelColumn(title = "编号")
@JsonSerialize(using = ToStringSerializer.class)
Long id;
@ExcelColumn(title = "职位名称")
String name;
@ExcelColumn(title = "职位描述")
String describe;
@ExcelColumn(title = "是否启用")
@JsonSerialize(using = ToStringSerializer.class)
Boolean enable;
public static List<PostExcel> transforms(List<Post> posts) {
return posts
.stream()
.map(post ->
PostExcel
.builder()
.id(post.getId())
.name(post.getName())
.describe(post.getDescribe())
.enable(post.getEnable())
.build()
)
.collect(Collectors.toList());
}
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.auth.param.post;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import lombok.*;
import lombok.experimental.FieldDefaults;
/**
* 职位分页入参
* @author LJ-2204
* @date 2022/4/13
*/
@ApiModel("PostFindParam")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class PostFindParam implements Serializable {
private static final long serialVersionUID = 1926710333813935577L;
@ApiModelProperty(value = "名称", example = "Java")
String name;
@ApiModelProperty(value = "是否启用", example = "true")
Boolean enable;
@ApiModelProperty(value = "每页记录数", example = "10")
Integer pageSize;
@ApiModelProperty(value = "页码", example = "1")
Integer pageNo;
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.auth.param.post;
import com.yiring.auth.domain.post.Post;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import lombok.*;
import lombok.experimental.FieldDefaults;
/**
* 职位信息入参类
* @author LJ-2204
* @date 2022/4/12
*/
@ApiModel("PostParam")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class PostParam implements Serializable {
private static final long serialVersionUID = 5247408856592333466L;
@ApiModelProperty(value = "名称", example = "Java", required = true)
String name;
@ApiModelProperty(value = "描述", example = "描述", required = true)
String describe;
@ApiModelProperty(value = "是否启用", example = "true", required = true)
Boolean enable;
public Post transform() {
return Post.builder().name(this.name).describe(this.describe).enable(this.enable).build();
}
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.auth.service.post;
import com.yiring.auth.param.post.PostFindParam;
import com.yiring.auth.param.post.PostParam;
import com.yiring.auth.vo.post.PostVo;
import com.yiring.common.core.Result;
import com.yiring.common.param.IdParam;
import com.yiring.common.vo.PageVo;
import javax.servlet.http.HttpServletResponse;
/**
* 职位信息
* @author LJ-2204
* @date 2022/4/13
*/
public interface PostService {
/**
* 新增职位信息
* @param postParam 入参
* @return Result<String>
*/
Result<String> addPost(PostParam postParam);
/**
* 修改职位信息
* @param postParam 入参
* @param idParam id
* @return Result<String>
*/
Result<String> modifyPost(PostParam postParam, IdParam idParam);
/**
* 销毁职位信息
* @param idParam id
* @return Result<String>
*/
Result<String> deletePost(IdParam idParam);
/**
* 职位信息分页
* @param param 入参
* @return Result<PageVo<PostVo>>
*/
Result<PageVo<PostVo>> findPostPage(PostFindParam param);
/**
* 详细信息查询
* @param idParam id
* @return Result<PostVo>
*/
Result<PostVo> findPostById(IdParam idParam);
/**
* 根据名称判断是否存在职业信息
* @param name 职业名称
* @return T/F
*/
boolean hasPostInfo(String name);
/**
* 导出职位信息
* @param param 入参
* @param response 响应信息
*/
void exportPostInfo(PostFindParam param, HttpServletResponse response);
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.auth.service.post.impl;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.liaochong.myexcel.core.DefaultStreamExcelBuilder;
import com.yiring.auth.domain.post.Post;
import com.yiring.auth.domain.post.PostRepository;
import com.yiring.auth.excel.post.PostExcel;
import com.yiring.auth.param.post.PostFindParam;
import com.yiring.auth.param.post.PostParam;
import com.yiring.auth.service.post.PostService;
import com.yiring.auth.vo.post.PostVo;
import com.yiring.common.core.Result;
import com.yiring.common.core.Status;
import com.yiring.common.param.IdParam;
import com.yiring.common.vo.PageVo;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Executors;
import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 职位信息
* @author LJ-2204
* @date 2022/4/13
*/
@Transactional(rollbackFor = RuntimeException.class)
@Service
@Slf4j
public class PostServiceImpl implements PostService {
@Resource
PostRepository postRepository;
@Override
public Result<String> addPost(PostParam postParam) {
if (hasPostInfo(postParam.getName())) return Result.no(Status.BAD_REQUEST, "职位已存在");
Post post = postParam.transform();
postRepository.save(post);
return Result.ok();
}
@Override
public Result<String> modifyPost(PostParam postParam, IdParam idParam) {
Optional<Post> postOptional = postRepository.findById(idParam.getId());
if (postOptional.isEmpty()) return Result.no(Status.BAD_REQUEST, "被修改的数据不存在");
Post post = postOptional.get();
if (!StrUtil.equals(post.getName(), postParam.getName())) {
if (hasPostInfo(postParam.getName())) return Result.no(Status.BAD_REQUEST, "职位已存在");
}
post = postParam.transform();
post.setId(idParam.getId());
postRepository.save(post);
return Result.ok();
}
@Override
public Result<String> deletePost(IdParam idParam) {
Post post = Post.builder().id(idParam.getId()).build();
postRepository.delete(post);
return Result.ok();
}
@Override
public Result<PageVo<PostVo>> findPostPage(PostFindParam param) {
Specification<Post> specification = getPostPageSpecification(param);
if (ObjectUtil.isEmpty(param.getPageSize()) && ObjectUtil.isEmpty(param.getPageNo())) {
//分页
Pageable pageable = PageRequest.of(param.getPageNo() - 1, param.getPageSize());
Page<Post> page = postRepository.findAll(specification, pageable);
List<PostVo> postVos = PostVo.transforms(page.getContent());
PageVo<PostVo> pageVo = PageVo.build(postVos, postVos.size());
return Result.ok(pageVo);
} else {
List<Post> posts = postRepository.findAll(specification);
List<PostVo> postVos = PostVo.transforms(posts);
PageVo<PostVo> pageVo = PageVo.build(postVos, postVos.size());
return Result.ok(pageVo);
}
}
@Override
public Result<PostVo> findPostById(IdParam idParam) {
Post post = postRepository.getById(idParam.getId());
PostVo postVo = PostVo.transform(post);
return Result.ok(postVo);
}
@Override
public boolean hasPostInfo(String name) {
Post post = Post.builder().name(name).build();
return postRepository.count(Example.of(post)) > 0;
}
@Override
public void exportPostInfo(PostFindParam param, HttpServletResponse response) {
Specification<Post> specification = getPostPageSpecification(param);
List<Post> postList = postRepository.findAll(specification);
List<PostExcel> postExcels = PostExcel.transforms(postList);
try (
DefaultStreamExcelBuilder<PostExcel> streamExcelBuilder = DefaultStreamExcelBuilder
.of(PostExcel.class)
.threadPool(Executors.newFixedThreadPool(2))
.rowHeight(14)
.titleRowHeight(14)
.style(
"cell->vertical-align:center;text-align:center",
"title->vertical-align:center;text-align:center;font-weight:bold;font-family:等线"
)
.start()
) {
streamExcelBuilder.append(postExcels);
String fileName = URLEncoder.encode("职位信息.xlsx", StandardCharsets.UTF_8);
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
OutputStream out = response.getOutputStream();
Workbook workbook = streamExcelBuilder.fixedTitles().build();
workbook.write(out);
workbook.close();
out.flush();
out.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new RuntimeException("导出岗位信息失败: " + e.getMessage());
}
}
private Specification<Post> getPostPageSpecification(PostFindParam param) {
return (root, cq, cb) -> {
List<Predicate> predicates = ListUtil.toList();
if (StrUtil.isNotEmpty(param.getName())) {
predicates.add(cb.equal(root.get(Post.Fields.name), param.getName()));
}
if (ObjectUtil.isNotEmpty(param.getEnable())) {
predicates.add(cb.equal(root.get(Post.Fields.enable), param.getEnable()));
}
return cq.where(predicates.toArray(new Predicate[0])).getRestriction();
};
}
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.auth.util;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.yiring.common.core.Result;
import com.yiring.common.util.BeanUtils;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import lombok.experimental.UtilityClass;
import org.springframework.data.redis.core.RedisTemplate;
/**
* 真源授权工具
* @author LJ-2204
* @date 2022/4/15
*/
@UtilityClass
public class ZyUtil {
RedisTemplate<String, Object> redisTemplate;
static {
redisTemplate = BeanUtils.getBean("redisTemplate");
}
public final String CLIENT_ID = "sc21080400";
public final String CLIENT_SECRET = "12A14FDC";
public final String GRANT_TYPE = "client_credentials";
public final String KEY = "zy_token";
public final String TOKEN_TYPE = "bearer ";
public final String URL_PREFIX = "http://project.yz-online.com:789";
/**
* 获取token
* @return token
*/
public static String login() {
Object obj = redisTemplate.opsForValue().get(KEY);
if (ObjectUtil.isNotEmpty(obj)) {
return String.valueOf(obj);
}
Map<String, Object> map = MapUtil.createMap(HashMap.class);
map.put("client_id", CLIENT_ID);
map.put("client_secret", CLIENT_SECRET);
map.put("grant_type", GRANT_TYPE);
String json = HttpUtil.get("http://project.yz-online.com:789/positionApi/oauth/token", map);
Map result = JSON.parseObject(json, Map.class);
String access_token = result.get("access_token").toString();
redisTemplate.opsForValue().set(KEY, access_token, 1200, TimeUnit.SECONDS);
return access_token;
}
/**
* 判断token是否有效
* @return T/F
*/
public static boolean getToken() {
return ObjectUtil.isNotEmpty(redisTemplate.opsForValue().get(KEY));
}
/**
* get请求
* @param urlString 路径
* @param obj 参数
* @param timeout 请求时长
* @return json
*/
public static Result get(String urlString, Object obj, int timeout) {
String json = JSONUtil.toJsonStr(obj);
String token = login();
String body = HttpRequest
.get(URL_PREFIX + urlString)
.header(Header.AUTHORIZATION, TOKEN_TYPE + token)
.header(Header.CONTENT_TYPE, "application/json")
.body(json)
.timeout(timeout)
.execute()
.body();
return getResult(body);
}
/**
* post请求
* @param urlString 路径
* @param obj 参数
* @param timeout 请求时长
* @return json
*/
public static Result<Serializable> post(String urlString, Object obj, int timeout) {
String json = JSONUtil.toJsonStr(obj);
String token = login();
String body = HttpRequest
.post(URL_PREFIX + urlString)
.header(Header.AUTHORIZATION, TOKEN_TYPE + token)
.header(Header.CONTENT_TYPE, "application/json")
.body(json)
.timeout(timeout)
.execute()
.body();
return getResult(body);
}
/**
* put请求
* @param urlString 路径
* @param obj 参数
* @param timeout 请求时长
* @return json
*/
public static Result<Serializable> put(String urlString, Object obj, int timeout) {
String json = JSONUtil.toJsonStr(obj);
String token = login();
String body = HttpRequest
.put(URL_PREFIX + urlString)
.header(Header.AUTHORIZATION, TOKEN_TYPE + token)
.header(Header.CONTENT_TYPE, "application/json")
.body(json)
.timeout(timeout)
.execute()
.body();
return getResult(body);
}
/**
* delete请求
* @param urlString 路径
* @param obj 参数
* @param timeout 请求时长
* @return json
*/
public static Result<Serializable> delete(String urlString, Object obj, int timeout) {
String json = JSONUtil.toJsonStr(obj);
String token = login();
String body = HttpRequest
.delete(URL_PREFIX + urlString)
.header(Header.AUTHORIZATION, TOKEN_TYPE + token)
.header(Header.CONTENT_TYPE, "application/json")
.body(json)
.timeout(timeout)
.execute()
.body();
return getResult(body);
}
/**
* 返回类型转换
* @param body json
* @return Result
*/
private static Result<Serializable> getResult(String body) {
Map map = JSONUtil.toBean(body, Map.class);
Integer code = Convert.toInt(map.get("code"));
String msg = Convert.toStr(map.get("msg"));
return Result.builder().code(code).message(msg).build();
}
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.auth.vo.post;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.yiring.auth.domain.post.Post;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;
import lombok.*;
import lombok.experimental.FieldDefaults;
/**
* 职位信息视图
* @author LJ-2204
* @date 2022/4/13
*/
@ApiModel("PostVo")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class PostVo implements Serializable {
private static final long serialVersionUID = 1011259844584399825L;
@JsonSerialize(using = ToStringSerializer.class)
@ApiModelProperty(value = "主键", example = "1")
Long id;
@ApiModelProperty(value = "名称", example = "Java")
String name;
@ApiModelProperty(value = "描述", example = "描述")
String describe;
@ApiModelProperty(value = "是否启用", example = "true")
Boolean enable;
public static PostVo transform(Post post) {
return PostVo
.builder()
.id(post.getId())
.name(post.getName())
.describe(post.getDescribe())
.enable(post.getEnable())
.build();
}
public static List<PostVo> transforms(List<Post> posts) {
return posts
.stream()
.map(post ->
PostVo
.builder()
.id(post.getId())
.name(post.getName())
.describe(post.getDescribe())
.enable(post.getEnable())
.build()
)
.collect(Collectors.toList());
}
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.auth.web.post;
import com.yiring.auth.param.post.PostFindParam;
import com.yiring.auth.param.post.PostParam;
import com.yiring.auth.service.post.PostService;
import com.yiring.auth.vo.post.PostVo;
import com.yiring.common.core.Result;
import com.yiring.common.param.IdParam;
import com.yiring.common.vo.PageVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* 职位信息控制器
* @author LJ-2204
* @date 2022/4/12
*/
@Slf4j
@Validated
@Api(tags = "职位信息")
@RestController
@RequestMapping("/post/")
public class PostController {
@Resource
PostService postService;
@ApiOperation(value = "新增职位")
@PostMapping("addPost")
public Result<String> addPost(@Valid PostParam postParam) {
return postService.addPost(postParam);
}
@ApiOperation(value = "修改职位")
@PutMapping("modifyPost")
public Result<String> modifyPost(@Valid PostParam postParam, @Valid IdParam idParam) {
return postService.modifyPost(postParam, idParam);
}
@ApiOperation(value = "销毁职位")
@DeleteMapping("deletePost")
public Result<String> deletePost(@Valid IdParam idParam) {
return postService.deletePost(idParam);
}
@ApiOperation(value = "分页查询")
@GetMapping("findPostPage")
public Result<PageVo<PostVo>> findPostPage(@Valid PostFindParam param) {
return postService.findPostPage(param);
}
@ApiOperation(value = "详细信息查询")
@GetMapping("findPostById")
public Result<PostVo> findPostById(@Valid IdParam idParam) {
return postService.findPostById(idParam);
}
@ApiOperation(value = "导出职位信息")
@GetMapping("exportPostInfo")
public void exportPostInfo(@Valid PostFindParam param, HttpServletResponse response) {
postService.exportPostInfo(param, response);
}
}
dependencies { dependencies {
// implementation project(":basic-common:util")
implementation 'org.springframework.boot:spring-boot-starter-aop' implementation 'org.springframework.boot:spring-boot-starter-aop'
implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-validation'
......
/* (C) 2022 YiRing, Inc. */
package com.yiring.common.config.converter;
import com.alibaba.fastjson.JSONArray;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
/**
* JSONArray JPA 类型转换
*
* @author Jim
* @version 0.1
* 2022/4/7 18:03
*/
@Converter
public class JSONArrayConverter implements AttributeConverter<JSONArray, String> {
@Override
public String convertToDatabaseColumn(JSONArray json) {
return json.toJSONString();
}
@Override
public JSONArray convertToEntityAttribute(String s) {
return JSONArray.parseArray(s);
}
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.common.config.converter;
import com.alibaba.fastjson.JSONObject;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
/**
* JSONObject JPA 类型转换
*
* @author Jim
* @version 0.1
* 2022/4/7 18:03
*/
@Converter
public class JSONObjectConverter implements AttributeConverter<JSONObject, String> {
@Override
public String convertToDatabaseColumn(JSONObject json) {
return json.toJSONString();
}
@Override
public JSONObject convertToEntityAttribute(String s) {
return JSONObject.parseObject(s);
}
}
...@@ -10,7 +10,7 @@ import javax.persistence.Table; ...@@ -10,7 +10,7 @@ import javax.persistence.Table;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
import org.hibernate.annotaions.Comment; import org.hibernate.annotations.Comment;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
import org.hibernate.snowflake.SnowflakeId; import org.hibernate.snowflake.SnowflakeId;
......
...@@ -10,7 +10,7 @@ import javax.persistence.Table; ...@@ -10,7 +10,7 @@ import javax.persistence.Table;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
import org.hibernate.annotaions.Comment; import org.hibernate.annotations.Comment;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
import org.hibernate.snowflake.SnowflakeId; import org.hibernate.snowflake.SnowflakeId;
......
dependencies { dependencies {
implementation project(":basic-common:core") implementation project(":basic-common:core")
implementation project(":basic-common:redis")
implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-aop' implementation 'org.springframework.boot:spring-boot-starter-aop'
// hutool-extra // hutool-extra
......
/* (C) 2022 YiRing, Inc. */
package com.yiring.common.util;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class BeanUtils implements ApplicationContextAware {
/**
* 以静态变量保存ApplicationContext,可在任意代码中取出ApplicaitonContext.
*/
private static ApplicationContext context;
/**
* 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.
*/
@Override
public void setApplicationContext(ApplicationContext context) {
BeanUtils.context = context;
}
public static ApplicationContext getApplicationContext() {
return context;
}
/**
* 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型. 方法返回值的类型由调用者决定
*/
public static <T> T getBean(String name) {
return (T) context.getBean(name);
}
/// 获取当前环境
public String getActiveProfile() {
return context.getEnvironment().getActiveProfiles()[0];
}
}
/* (C) 2022 YiRing, Inc. */ /* (C) 2022 YiRing, Inc. */
package com.yiring.common.util; package com.yiring.common.util;
import com.yiring.common.core.redis.RedisCache; import com.yiring.common.core.Redis;
import com.yiring.common.dict.Dict; import com.yiring.common.dict.Dict;
import com.yiring.common.util.spring.SpringUtil; import com.yiring.common.util.spring.SpringUtil;
import java.util.Collection; import java.util.Collection;
...@@ -26,7 +26,7 @@ public class DictUtils { ...@@ -26,7 +26,7 @@ public class DictUtils {
* @param dictDatas 字典数据列表 * @param dictDatas 字典数据列表
*/ */
public static void setDictCache(String key, List<Dict> dictDatas) { public static void setDictCache(String key, List<Dict> dictDatas) {
SpringUtil.getBean(RedisCache.class).setCacheObject(getCacheKey(key), dictDatas); SpringUtil.getBean(Redis.class).set(getCacheKey(key), dictDatas);
} }
/** /**
...@@ -36,7 +36,7 @@ public class DictUtils { ...@@ -36,7 +36,7 @@ public class DictUtils {
* @return dictDatas 字典数据列表 * @return dictDatas 字典数据列表
*/ */
public static List<Dict> getDictCache(String key) { public static List<Dict> getDictCache(String key) {
Object cacheObj = SpringUtil.getBean(RedisCache.class).getCacheObject(getCacheKey(key)); Object cacheObj = SpringUtil.getBean(Redis.class).get(getCacheKey(key));
if (StrUtils.isNotNull(cacheObj)) { if (StrUtils.isNotNull(cacheObj)) {
return StrUtils.cast(cacheObj); return StrUtils.cast(cacheObj);
} }
...@@ -141,15 +141,15 @@ public class DictUtils { ...@@ -141,15 +141,15 @@ public class DictUtils {
* @param key 字典键 * @param key 字典键
*/ */
public static void removeDictCache(String key) { public static void removeDictCache(String key) {
SpringUtil.getBean(RedisCache.class).deleteObject(getCacheKey(key)); SpringUtil.getBean(Redis.class).del(getCacheKey(key));
} }
/** /**
* 清空字典缓存 * 清空字典缓存
*/ */
public static void clearDictCache() { public static void clearDictCache() {
Collection<String> keys = SpringUtil.getBean(RedisCache.class).keys("sys_dict:*"); Collection<String> keys = SpringUtil.getBean(Redis.class).get("sys_dict:*");
SpringUtil.getBean(RedisCache.class).deleteObject(keys); SpringUtil.getBean(Redis.class).del(keys);
} }
/** /**
......
...@@ -10,7 +10,7 @@ buildscript { ...@@ -10,7 +10,7 @@ buildscript {
// https://mvnrepository.com/artifact/cn.dev33/sa-token-spring-boot-starter // https://mvnrepository.com/artifact/cn.dev33/sa-token-spring-boot-starter
saTokenVersion = '1.29.1.trial' saTokenVersion = '1.29.1.trial'
// https://mvnrepository.com/artifact/cn.hutool/hutool-all // https://mvnrepository.com/artifact/cn.hutool/hutool-all
hutoolVersion = '5.7.22' hutoolVersion = '5.8.0.M3'
// https://mvnrepository.com/artifact/com.alibaba/fastjson // https://mvnrepository.com/artifact/com.alibaba/fastjson
fastJsonVersion = '1.2.80' fastJsonVersion = '1.2.80'
// https://mvnrepository.com/artifact/com.xuxueli/xxl-job-core // https://mvnrepository.com/artifact/com.xuxueli/xxl-job-core
...@@ -27,6 +27,8 @@ buildscript { ...@@ -27,6 +27,8 @@ buildscript {
jtsVersion = '1.18.2' jtsVersion = '1.18.2'
// https://mvnrepository.com/artifact/com.vladmihalcea/hibernate-types-55 // https://mvnrepository.com/artifact/com.vladmihalcea/hibernate-types-55
hibernateTypesVersion = '2.16.1' hibernateTypesVersion = '2.16.1'
// https://mvnrepository.com/artifact/com.github.liaochong/myexcel
myexcelVersion = '4.1.1'
} }
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论