diff --git a/eladmin-common/pom.xml b/eladmin-common/pom.xml index 2150b4b7..ef1f52a5 100644 --- a/eladmin-common/pom.xml +++ b/eladmin-common/pom.xml @@ -8,6 +8,18 @@ 2.6 4.0.0 + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + 5.3.4 diff --git a/eladmin-common/src/main/java/me/zhengjie/converter/EnumSetConverter.java b/eladmin-common/src/main/java/me/zhengjie/converter/EnumSetConverter.java new file mode 100644 index 00000000..b0d006ca --- /dev/null +++ b/eladmin-common/src/main/java/me/zhengjie/converter/EnumSetConverter.java @@ -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> extends AttributeConverter, String> { + + Class enumClass(); + + @Override + default String convertToDatabaseColumn(final Set attribute) { + return attribute == null || attribute.isEmpty() ? + null : + attribute.stream().map(T::name) + .sorted() + .collect(Collectors.joining(",")); + } + + @Override + default Set 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(Stream.of(data.split(",")) + .map(String::trim) + .filter(values::contains) + .map(name -> T.valueOf(enumClass(), name)) + .collect(Collectors.toList())); + } +} diff --git a/eladmin-common/src/main/java/me/zhengjie/converter/StringListConverter.java b/eladmin-common/src/main/java/me/zhengjie/converter/StringListConverter.java new file mode 100644 index 00000000..f62b1c44 --- /dev/null +++ b/eladmin-common/src/main/java/me/zhengjie/converter/StringListConverter.java @@ -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, String> { + + @Override + public String convertToDatabaseColumn(final List attribute) { + return attribute == null || attribute.isEmpty() ? null : + String.join("\n", attribute); + } + + @Override + public List convertToEntityAttribute(final String data) { + return data == null || data.isBlank() ? + null : + Arrays.asList(data.split("\n")); + } +} diff --git a/eladmin-common/src/main/java/me/zhengjie/converter/StringMapConverter.java b/eladmin-common/src/main/java/me/zhengjie/converter/StringMapConverter.java new file mode 100644 index 00000000..9ed7f894 --- /dev/null +++ b/eladmin-common/src/main/java/me/zhengjie/converter/StringMapConverter.java @@ -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, String> { + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + @Override + public String convertToDatabaseColumn(final Map value) { + try { + return value == null ? null : OBJECT_MAPPER.writeValueAsString(value); + } catch (final JsonProcessingException e) { + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public Map convertToEntityAttribute(final String value) { + try { + final var type = new TypeReference>() { + }; + return value == null ? null : OBJECT_MAPPER.readValue(value, type); + } catch (final IOException e) { + throw new RuntimeException(e.getMessage()); + } + } + +} diff --git a/eladmin-common/src/main/java/me/zhengjie/converter/StringSetConverter.java b/eladmin-common/src/main/java/me/zhengjie/converter/StringSetConverter.java new file mode 100644 index 00000000..1f06dc59 --- /dev/null +++ b/eladmin-common/src/main/java/me/zhengjie/converter/StringSetConverter.java @@ -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, String> { + + @Override + public String convertToDatabaseColumn(final Set attribute) { + return attribute == null || attribute.isEmpty() ? null : + String.join("\n", attribute); + } + + @Override + public Set convertToEntityAttribute(final String data) { + return data == null || data.isBlank() ? + null : + new LinkedHashSet<>(Arrays.asList(data.split("\n"))); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/portfolio/room/domain/Room.java b/eladmin-system/src/main/java/me/zhengjie/portfolio/room/domain/Room.java new file mode 100644 index 00000000..cde3e788 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/portfolio/room/domain/Room.java @@ -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 images; + + @Column(name = "extra_info") + @Convert(converter = StringListConverter.class) + @ApiModelProperty(value = "extraInfo") + private List extraInfo; + + public void copy(Room source) { + BeanUtil.copyProperties(source, this, CopyOptions.create().setIgnoreNullValue(true)); + } + + public List getImages() { + return images; + } +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/me/zhengjie/portfolio/room/repository/RoomRepository.java b/eladmin-system/src/main/java/me/zhengjie/portfolio/room/repository/RoomRepository.java new file mode 100644 index 00000000..097d8cf2 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/portfolio/room/repository/RoomRepository.java @@ -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, JpaSpecificationExecutor { +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/me/zhengjie/portfolio/room/rest/RoomController.java b/eladmin-system/src/main/java/me/zhengjie/portfolio/room/rest/RoomController.java new file mode 100644 index 00000000..74d28fc1 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/portfolio/room/rest/RoomController.java @@ -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 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 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 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 deleteRoom(@RequestBody Long[] ids) { + roomService.deleteAll(ids); + return new ResponseEntity<>(HttpStatus.OK); + } +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/me/zhengjie/portfolio/room/service/RoomService.java b/eladmin-system/src/main/java/me/zhengjie/portfolio/room/service/RoomService.java new file mode 100644 index 00000000..fe5d8501 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/portfolio/room/service/RoomService.java @@ -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 + */ + Map queryAll(RoomQueryCriteria criteria, Pageable pageable); + + /** + * 查询所有数据不分页 + * @param criteria 条件参数 + * @return List + */ + List 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 all, HttpServletResponse response) throws IOException; +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/me/zhengjie/portfolio/room/service/dto/RoomDto.java b/eladmin-system/src/main/java/me/zhengjie/portfolio/room/service/dto/RoomDto.java new file mode 100644 index 00000000..db07bda1 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/portfolio/room/service/dto/RoomDto.java @@ -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 images; + + private List extraInfo; +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/me/zhengjie/portfolio/room/service/dto/RoomQueryCriteria.java b/eladmin-system/src/main/java/me/zhengjie/portfolio/room/service/dto/RoomQueryCriteria.java new file mode 100644 index 00000000..ea70dcbd --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/portfolio/room/service/dto/RoomQueryCriteria.java @@ -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; +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/me/zhengjie/portfolio/room/service/impl/RoomServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/portfolio/room/service/impl/RoomServiceImpl.java new file mode 100644 index 00000000..61802451 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/portfolio/room/service/impl/RoomServiceImpl.java @@ -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 queryAll(RoomQueryCriteria criteria, Pageable pageable){ + Page page = roomRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(roomMapper::toDto)); + } + + @Override + public List 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 all, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (RoomDto room : all) { + Map 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); + } +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/me/zhengjie/portfolio/room/service/mapstruct/RoomMapper.java b/eladmin-system/src/main/java/me/zhengjie/portfolio/room/service/mapstruct/RoomMapper.java new file mode 100644 index 00000000..4ea3203c --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/portfolio/room/service/mapstruct/RoomMapper.java @@ -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 { + +} \ No newline at end of file diff --git a/eladmin-system/src/main/resources/config/application-dev.yml b/eladmin-system/src/main/resources/config/application-dev.yml index c7188533..2be4ae2e 100644 --- a/eladmin-system/src/main/resources/config/application-dev.yml +++ b/eladmin-system/src/main/resources/config/application-dev.yml @@ -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 # 最小连接数