pull/739/head
Chanheng 2022-05-01 22:31:08 +07:00
parent e3e90350d9
commit 75e08c6cd0
14 changed files with 628 additions and 2 deletions

View File

@ -8,6 +8,18 @@
<version>2.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<hutool.version>5.3.4</hutool.version>
</properties>

View File

@ -0,0 +1,34 @@
package me.zhengjie.converter;
import javax.persistence.AttributeConverter;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public interface EnumSetConverter<T extends Enum<T>> extends AttributeConverter<Set<T>, String> {
Class<T> enumClass();
@Override
default String convertToDatabaseColumn(final Set<T> attribute) {
return attribute == null || attribute.isEmpty() ?
null :
attribute.stream().map(T::name)
.sorted()
.collect(Collectors.joining(","));
}
@Override
default Set<T> convertToEntityAttribute(final String data) {
final var values = Arrays.stream(enumClass().getEnumConstants()).map(T::name).collect(Collectors.toSet());
return data == null || data.isBlank() ?
null :
new LinkedHashSet<T>(Stream.of(data.split(","))
.map(String::trim)
.filter(values::contains)
.map(name -> T.valueOf(enumClass(), name))
.collect(Collectors.toList()));
}
}

View File

@ -0,0 +1,23 @@
package me.zhengjie.converter;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.util.Arrays;
import java.util.List;
@Converter
public class StringListConverter implements AttributeConverter<List<String>, String> {
@Override
public String convertToDatabaseColumn(final List<String> attribute) {
return attribute == null || attribute.isEmpty() ? null :
String.join("\n", attribute);
}
@Override
public List<String> convertToEntityAttribute(final String data) {
return data == null || data.isBlank() ?
null :
Arrays.asList(data.split("\n"));
}
}

View File

@ -0,0 +1,37 @@
package me.zhengjie.converter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.io.IOException;
import java.util.Map;
@Converter
public class StringMapConverter implements AttributeConverter<Map<String, String>, String> {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Override
public String convertToDatabaseColumn(final Map<String, String> value) {
try {
return value == null ? null : OBJECT_MAPPER.writeValueAsString(value);
} catch (final JsonProcessingException e) {
throw new RuntimeException(e.getMessage());
}
}
@Override
public Map<String, String> convertToEntityAttribute(final String value) {
try {
final var type = new TypeReference<Map<String, String>>() {
};
return value == null ? null : OBJECT_MAPPER.readValue(value, type);
} catch (final IOException e) {
throw new RuntimeException(e.getMessage());
}
}
}

View File

@ -0,0 +1,24 @@
package me.zhengjie.converter;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
@Converter
public class StringSetConverter implements AttributeConverter<Set<String>, String> {
@Override
public String convertToDatabaseColumn(final Set<String> attribute) {
return attribute == null || attribute.isEmpty() ? null :
String.join("\n", attribute);
}
@Override
public Set<String> convertToEntityAttribute(final String data) {
return data == null || data.isBlank() ?
null :
new LinkedHashSet<>(Arrays.asList(data.split("\n")));
}
}

View File

@ -0,0 +1,81 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.zhengjie.portfolio.room.domain;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import me.zhengjie.converter.StringListConverter;
import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
* @author Chanheng
* @website https://el-admin.vip
* @description /
* @date 2022-05-01
**/
@Entity
@Data
@Table(name = "room")
public class Room implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
@ApiModelProperty(value = "id")
private Long id;
@Column(name = "name", nullable = false)
@NotBlank
@ApiModelProperty(value = "name")
private String name;
@Column(name = "description", nullable = false)
@NotBlank
@ApiModelProperty(value = "description")
private String description;
@Column(name = "images", nullable = false)
@NotNull
@Convert(converter = StringListConverter.class)
@ApiModelProperty(value = "images")
private List<String> images;
@Column(name = "extra_info")
@Convert(converter = StringListConverter.class)
@ApiModelProperty(value = "extraInfo")
private List<String> extraInfo;
public void copy(Room source) {
BeanUtil.copyProperties(source, this, CopyOptions.create().setIgnoreNullValue(true));
}
public List<String> getImages() {
return images;
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.zhengjie.portfolio.room.repository;
import me.zhengjie.portfolio.room.domain.Room;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* @website https://el-admin.vip
* @author Chanheng
* @date 2022-05-01
**/
public interface RoomRepository extends JpaRepository<Room, Long>, JpaSpecificationExecutor<Room> {
}

View File

@ -0,0 +1,87 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.zhengjie.portfolio.room.rest;
import me.zhengjie.annotation.Log;
import me.zhengjie.portfolio.room.domain.Room;
import me.zhengjie.portfolio.room.service.RoomService;
import me.zhengjie.portfolio.room.service.dto.RoomQueryCriteria;
import org.springframework.data.domain.Pageable;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
/**
* @website https://el-admin.vip
* @author Chanheng
* @date 2022-05-01
**/
@RestController
@RequiredArgsConstructor
@Api(tags = "room管理")
@RequestMapping("/api/room")
public class RoomController {
private final RoomService roomService;
@Log("导出数据")
@ApiOperation("导出数据")
@GetMapping(value = "/download")
@PreAuthorize("@el.check('room:list')")
public void exportRoom(HttpServletResponse response, RoomQueryCriteria criteria) throws IOException {
roomService.download(roomService.queryAll(criteria), response);
}
@GetMapping
@Log("查询room")
@ApiOperation("查询room")
@PreAuthorize("@el.check('room:list')")
public ResponseEntity<Object> queryRoom(RoomQueryCriteria criteria, Pageable pageable){
return new ResponseEntity<>(roomService.queryAll(criteria,pageable),HttpStatus.OK);
}
@PostMapping
@Log("新增room")
@ApiOperation("新增room")
@PreAuthorize("@el.check('room:add')")
public ResponseEntity<Object> createRoom(@Validated @RequestBody Room resources){
return new ResponseEntity<>(roomService.create(resources),HttpStatus.CREATED);
}
@PutMapping
@Log("修改room")
@ApiOperation("修改room")
@PreAuthorize("@el.check('room:edit')")
public ResponseEntity<Object> updateRoom(@Validated @RequestBody Room resources){
roomService.update(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@DeleteMapping
@Log("删除room")
@ApiOperation("删除room")
@PreAuthorize("@el.check('room:del')")
public ResponseEntity<Object> deleteRoom(@RequestBody Long[] ids) {
roomService.deleteAll(ids);
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@ -0,0 +1,83 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.zhengjie.portfolio.room.service;
import me.zhengjie.portfolio.room.domain.Room;
import me.zhengjie.portfolio.room.service.dto.RoomDto;
import me.zhengjie.portfolio.room.service.dto.RoomQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
/**
* @website https://el-admin.vip
* @description
* @author Chanheng
* @date 2022-05-01
**/
public interface RoomService {
/**
*
* @param criteria
* @param pageable
* @return Map<String,Object>
*/
Map<String,Object> queryAll(RoomQueryCriteria criteria, Pageable pageable);
/**
*
* @param criteria
* @return List<RoomDto>
*/
List<RoomDto> queryAll(RoomQueryCriteria criteria);
/**
* ID
* @param id ID
* @return RoomDto
*/
RoomDto findById(Long id);
/**
*
* @param resources /
* @return RoomDto
*/
RoomDto create(Room resources);
/**
*
* @param resources /
*/
void update(Room resources);
/**
*
* @param ids /
*/
void deleteAll(Long[] ids);
/**
*
* @param all
* @param response /
* @throws IOException /
*/
void download(List<RoomDto> all, HttpServletResponse response) throws IOException;
}

View File

@ -0,0 +1,41 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.zhengjie.portfolio.room.service.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @author Chanheng
* @website https://el-admin.vip
* @description /
* @date 2022-05-01
**/
@Data
public class RoomDto implements Serializable {
private Long id;
private String name;
private String description;
private List<String> images;
private List<String> extraInfo;
}

View File

@ -0,0 +1,37 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.zhengjie.portfolio.room.service.dto;
import lombok.Data;
import java.util.List;
import me.zhengjie.annotation.Query;
/**
* @website https://el-admin.vip
* @author Chanheng
* @date 2022-05-01
**/
@Data
public class RoomQueryCriteria{
/** 模糊 */
@Query(type = Query.Type.INNER_LIKE)
private String name;
/** 模糊 */
@Query(type = Query.Type.INNER_LIKE)
private String description;
}

View File

@ -0,0 +1,107 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.zhengjie.portfolio.room.service.impl;
import me.zhengjie.portfolio.room.domain.Room;
import me.zhengjie.utils.ValidationUtil;
import me.zhengjie.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import me.zhengjie.portfolio.room.repository.RoomRepository;
import me.zhengjie.portfolio.room.service.RoomService;
import me.zhengjie.portfolio.room.service.dto.RoomDto;
import me.zhengjie.portfolio.room.service.dto.RoomQueryCriteria;
import me.zhengjie.portfolio.room.service.mapstruct.RoomMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.QueryHelp;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;
/**
* @website https://el-admin.vip
* @description
* @author Chanheng
* @date 2022-05-01
**/
@Service
@RequiredArgsConstructor
public class RoomServiceImpl implements RoomService {
private final RoomRepository roomRepository;
private final RoomMapper roomMapper;
@Override
public Map<String,Object> queryAll(RoomQueryCriteria criteria, Pageable pageable){
Page<Room> page = roomRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(roomMapper::toDto));
}
@Override
public List<RoomDto> queryAll(RoomQueryCriteria criteria){
return roomMapper.toDto(roomRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
@Transactional
public RoomDto findById(Long id) {
Room room = roomRepository.findById(id).orElseGet(Room::new);
ValidationUtil.isNull(room.getId(),"Room","id",id);
return roomMapper.toDto(room);
}
@Override
@Transactional(rollbackFor = Exception.class)
public RoomDto create(Room resources) {
return roomMapper.toDto(roomRepository.save(resources));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(Room resources) {
Room room = roomRepository.findById(resources.getId()).orElseGet(Room::new);
ValidationUtil.isNull( room.getId(),"Room","id",resources.getId());
room.copy(resources);
roomRepository.save(room);
}
@Override
public void deleteAll(Long[] ids) {
for (Long id : ids) {
roomRepository.deleteById(id);
}
}
@Override
public void download(List<RoomDto> all, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>();
for (RoomDto room : all) {
Map<String,Object> map = new LinkedHashMap<>();
map.put(" name", room.getName());
map.put(" description", room.getDescription());
map.put(" images", room.getImages());
map.put(" extraInfo", room.getExtraInfo());
list.add(map);
}
FileUtil.downloadExcel(list, response);
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.zhengjie.portfolio.room.service.mapstruct;
import me.zhengjie.base.BaseMapper;
import me.zhengjie.portfolio.room.domain.Room;
import me.zhengjie.portfolio.room.service.dto.RoomDto;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @website https://el-admin.vip
* @author Chanheng
* @date 2022-05-01
**/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface RoomMapper extends BaseMapper<RoomDto, Room> {
}

View File

@ -4,9 +4,9 @@ spring:
druid:
db-type: com.alibaba.druid.pool.DruidDataSource
driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
url: jdbc:log4jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:eladmin}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
url: jdbc:log4jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:eladmin}?serverTimezone=Asia/Phnom_Penh&characterEncoding=utf8&useSSL=false
username: ${DB_USER:root}
password: ${DB_PWD:123456}
password: ${DB_PWD:root}
# 初始连接数
initial-size: 5
# 最小连接数