return event

pull/882/head
chanhengseang 2025-05-26 11:38:40 -07:00
parent 33aaa6a32b
commit 186b685ab5
10 changed files with 203 additions and 70 deletions

View File

@ -23,12 +23,16 @@ import org.springframework.util.StringUtils;
*/ */
public class EntityNotFoundException extends RuntimeException { public class EntityNotFoundException extends RuntimeException {
public EntityNotFoundException(Class clazz, String field, String val) { public EntityNotFoundException(Class<?> clazz, String field, String val) {
super(EntityNotFoundException.generateMessage(clazz.getSimpleName(), field, val)); super(EntityNotFoundException.generateMessage(clazz.getSimpleName(), field, val));
} }
public EntityNotFoundException(Class<?> clazz, String field, Long val) {
super(EntityNotFoundException.generateMessage(clazz.getSimpleName(), field, "" + val));
}
private static String generateMessage(String entity, String field, String val) { private static String generateMessage(String entity, String field, String val) {
return StringUtils.capitalize(entity) return StringUtils.capitalize(entity)
+ " with " + field + " "+ val + " does not exist"; + " with " + field + " " + val + " does not exist";
} }
} }

View File

@ -0,0 +1,4 @@
-- Add tags column to event table
ALTER TABLE event
add column poster_image varchar(255),
ADD COLUMN tags VARCHAR(255) NULL COMMENT 'Tags stored as comma-delimited string';

View File

@ -29,7 +29,7 @@
<logback.version>1.2.9</logback.version> <logback.version>1.2.9</logback.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>17</java.version>
<fastjson2.version>2.0.54</fastjson2.version> <fastjson2.version>2.0.54</fastjson2.version>
<druid.version>1.2.19</druid.version> <druid.version>1.2.19</druid.version>
<commons-pool2.version>2.11.1</commons-pool2.version> <commons-pool2.version>2.11.1</commons-pool2.version>

View File

@ -0,0 +1,49 @@
/*
* Copyright 2019-2025 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 com.srr.converter;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Converter to store List<String> as a comma-delimited string in database
* @author Chanheng
* @date 2025-05-26
*/
@Converter
public class StringListConverter implements AttributeConverter<List<String>, String> {
private static final String DELIMITER = ",";
@Override
public String convertToDatabaseColumn(List<String> stringList) {
if (stringList == null || stringList.isEmpty()) {
return null;
}
return String.join(DELIMITER, stringList);
}
@Override
public List<String> convertToEntityAttribute(String string) {
if (string == null || string.isEmpty()) {
return new ArrayList<>();
}
return new ArrayList<>(Arrays.asList(string.split(DELIMITER)));
}
}

View File

@ -15,6 +15,7 @@
*/ */
package com.srr.domain; package com.srr.domain;
import com.srr.converter.StringListConverter;
import com.srr.enumeration.EventStatus; import com.srr.enumeration.EventStatus;
import com.srr.enumeration.Format; import com.srr.enumeration.Format;
import lombok.Data; import lombok.Data;
@ -24,6 +25,7 @@ import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*; import javax.persistence.*;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.Convert;
import org.hibernate.annotations.*; import org.hibernate.annotations.*;
import java.sql.Timestamp; import java.sql.Timestamp;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
@ -138,6 +140,13 @@ public class Event implements Serializable {
@Column(name = "`allow_wait_list`") @Column(name = "`allow_wait_list`")
private boolean allowWaitList; private boolean allowWaitList;
@Column(name = "`poster_image`")
private String posterImage;
@Column(name = "`tags`")
@Convert(converter = StringListConverter.class)
private List<String> tags = new ArrayList<>();
@ManyToMany @ManyToMany
@JoinTable(name = "event_co_host_player", @JoinTable(name = "event_co_host_player",
joinColumns = {@JoinColumn(name = "event_id",referencedColumnName = "id")}, joinColumns = {@JoinColumn(name = "event_id",referencedColumnName = "id")},

View File

@ -92,7 +92,12 @@ public class EventDto implements Serializable {
@ApiModelProperty(value = "Number of groups") @ApiModelProperty(value = "Number of groups")
private Integer groupCount; private Integer groupCount;
private String posterImage;
@ApiModelProperty(value = "Co-host players") @ApiModelProperty(value = "Co-host players")
private List<PlayerDto> coHostPlayers; private List<PlayerDto> coHostPlayers;
@ApiModelProperty(value = "Tags")
private List<String> tags;
} }

View File

@ -0,0 +1,13 @@
package com.srr.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class JoinEventDto {
private Long playerId;
@NotNull
private Long eventId;
private Long teamId;
}

View File

@ -1,42 +1,47 @@
/* /*
* Copyright 2019-2025 Zheng Jie * Copyright 2019-2025 Zheng Jie
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.srr.rest; package com.srr.rest;
import me.zhengjie.annotation.Log;
import com.srr.domain.Event; import com.srr.domain.Event;
import com.srr.service.EventService; import com.srr.dto.EventDto;
import com.srr.dto.EventQueryCriteria; import com.srr.dto.EventQueryCriteria;
import org.springframework.data.domain.Pageable; import com.srr.dto.JoinEventDto;
import com.srr.enumeration.EventStatus;
import com.srr.service.EventService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.zhengjie.annotation.Log;
import me.zhengjie.utils.PageResult;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import me.zhengjie.utils.PageResult; import java.io.IOException;
import com.srr.dto.EventDto;
/** /**
* @website https://eladmin.vip * @author Chanheng
* @author Chanheng * @website https://eladmin.vip
* @date 2025-05-18 * @date 2025-05-18
**/ **/
@RestController @RestController
@RequiredArgsConstructor @RequiredArgsConstructor
@Api(tags = "event") @Api(tags = "event")
@ -55,26 +60,42 @@ public class EventController {
@GetMapping @GetMapping
@ApiOperation("Query event") @ApiOperation("Query event")
@PreAuthorize("@el.check('event:list')") @PreAuthorize("@el.check('event:list')")
public ResponseEntity<PageResult<EventDto>> queryEvent(EventQueryCriteria criteria, Pageable pageable){ public ResponseEntity<PageResult<EventDto>> queryEvent(EventQueryCriteria criteria, Pageable pageable) {
return new ResponseEntity<>(eventService.queryAll(criteria,pageable),HttpStatus.OK); return new ResponseEntity<>(eventService.queryAll(criteria, pageable), HttpStatus.OK);
} }
@PostMapping @PostMapping
@Log("Add event") @Log("Add event")
@ApiOperation("Add event") @ApiOperation("Add event")
@PreAuthorize("@el.check('event:add')") @PreAuthorize("@el.check('event:add')")
public ResponseEntity<Object> createEvent(@Validated @RequestBody Event resources){ public ResponseEntity<Object> createEvent(@Validated @RequestBody Event resources) {
eventService.create(resources); final var result = eventService.create(resources);
return new ResponseEntity<>(HttpStatus.CREATED); return new ResponseEntity<>(result, HttpStatus.CREATED);
} }
@PutMapping @PutMapping
@Log("Modify event") @Log("Modify event")
@ApiOperation("Modify event") @ApiOperation("Modify event")
@PreAuthorize("@el.check('event:edit')") @PreAuthorize("@el.check('event:edit')")
public ResponseEntity<Object> updateEvent(@Validated @RequestBody Event resources){ public ResponseEntity<Object> updateEvent(@Validated @RequestBody Event resources) {
eventService.update(resources); final var result = eventService.update(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT); return new ResponseEntity<>(result, HttpStatus.OK);
}
@PatchMapping("/{id}/status/{status}")
@Log("Update event status")
@ApiOperation("Update event status")
@PreAuthorize("@el.check('event:edit')")
public ResponseEntity<Object> updateEventStatus(
@PathVariable Long id,
@PathVariable EventStatus status) {
final var result = eventService.updateStatus(id, status);
return new ResponseEntity<>(result, HttpStatus.OK);
}
public ResponseEntity<Object> joinEvent(@PathVariable Long id, @RequestBody JoinEventDto joinEventDto) {
final EventDto result = eventService.joinEvent(joinEventDto);
return new ResponseEntity<>(result, HttpStatus.OK);
} }
@DeleteMapping @DeleteMapping

View File

@ -18,6 +18,7 @@ package com.srr.service;
import com.srr.domain.Event; import com.srr.domain.Event;
import com.srr.dto.EventDto; import com.srr.dto.EventDto;
import com.srr.dto.EventQueryCriteria; import com.srr.dto.EventQueryCriteria;
import com.srr.enumeration.EventStatus;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import java.util.List; import java.util.List;
@ -59,13 +60,15 @@ public interface EventService {
* Create * Create
* @param resources / * @param resources /
*/ */
void create(Event resources); EventDto create(Event resources);
/** /**
* Edit * Edit
* @param resources / * @param resources /
*/ */
void update(Event resources); EventDto update(Event resources);
EventDto updateStatus(Long id, EventStatus status);
/** /**
* Multi-select delete * Multi-select delete

View File

@ -1,21 +1,23 @@
/* /*
* Copyright 2019-2025 Zheng Jie * Copyright 2019-2025 Zheng Jie
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.srr.service.impl; package com.srr.service.impl;
import com.srr.domain.Event; import com.srr.domain.Event;
import com.srr.enumeration.EventStatus;
import me.zhengjie.exception.EntityNotFoundException;
import me.zhengjie.utils.ValidationUtil; import me.zhengjie.utils.ValidationUtil;
import me.zhengjie.utils.FileUtil; import me.zhengjie.utils.FileUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -30,20 +32,24 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import me.zhengjie.utils.PageUtil; import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.QueryHelp; import me.zhengjie.utils.QueryHelp;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.io.IOException; import java.io.IOException;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import me.zhengjie.utils.PageResult; import me.zhengjie.utils.PageResult;
/** /**
* @website https://eladmin.vip * @author Chanheng
* @description * @website https://eladmin.vip
* @author Chanheng * @description
* @date 2025-05-18 * @date 2025-05-18
**/ **/
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class EventServiceImpl implements EventService { public class EventServiceImpl implements EventService {
@ -52,37 +58,56 @@ public class EventServiceImpl implements EventService {
private final EventMapper eventMapper; private final EventMapper eventMapper;
@Override @Override
public PageResult<EventDto> queryAll(EventQueryCriteria criteria, Pageable pageable){ public PageResult<EventDto> queryAll(EventQueryCriteria criteria, Pageable pageable) {
Page<Event> page = eventRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); Page<Event> page = eventRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
return PageUtil.toPage(page.map(eventMapper::toDto)); return PageUtil.toPage(page.map(eventMapper::toDto));
} }
@Override @Override
public List<EventDto> queryAll(EventQueryCriteria criteria){ public List<EventDto> queryAll(EventQueryCriteria criteria) {
return eventMapper.toDto(eventRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder))); return eventMapper.toDto(eventRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
} }
@Override @Override
@Transactional @Transactional
public EventDto findById(Long id) { public EventDto findById(Long id) {
Event event = eventRepository.findById(id).orElseGet(Event::new); Event event = eventRepository.findById(id).orElseGet(Event::new);
ValidationUtil.isNull(event.getId(),"Event","id",id); ValidationUtil.isNull(event.getId(), "Event", "id", id);
return eventMapper.toDto(event); return eventMapper.toDto(event);
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void create(Event resources) { public EventDto create(Event resources) {
eventRepository.save(resources); resources.setStatus(EventStatus.DRAFT);
final var result = eventRepository.save(resources);
return eventMapper.toDto(result);
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void update(Event resources) { public EventDto update(Event resources) {
Event event = eventRepository.findById(resources.getId()).orElseGet(Event::new); Event event = eventRepository.findById(resources.getId()).orElseGet(Event::new);
ValidationUtil.isNull( event.getId(),"Event","id",resources.getId()); ValidationUtil.isNull(event.getId(), "Event", "id", resources.getId());
event.copy(resources); event.copy(resources);
eventRepository.save(event); final var result = eventRepository.save(event);
return eventMapper.toDto(result);
}
@Override
@Transactional(rollbackFor = Exception.class)
public EventDto updateStatus(Long id, EventStatus status) {
Event event = eventRepository.findById(id)
.orElseThrow(() -> new EntityNotFoundException(Event.class, "id", id));
// Only update the status field
event.setStatus(status);
if (status == EventStatus.CHECK_IN) {
event.setCheckInAt(Timestamp.from(Instant.now()));
}
final var result = eventRepository.save(event);
return eventMapper.toDto(result);
} }
@Override @Override
@ -96,7 +121,7 @@ public class EventServiceImpl implements EventService {
public void download(List<EventDto> all, HttpServletResponse response) throws IOException { public void download(List<EventDto> all, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>(); List<Map<String, Object>> list = new ArrayList<>();
for (EventDto event : all) { for (EventDto event : all) {
Map<String,Object> map = new LinkedHashMap<>(); Map<String, Object> map = new LinkedHashMap<>();
map.put("名称", event.getName()); map.put("名称", event.getName());
map.put("描述", event.getDescription()); map.put("描述", event.getDescription());
map.put("SINGLE, DOUBLE", event.getFormat()); map.put("SINGLE, DOUBLE", event.getFormat());
@ -108,8 +133,8 @@ public class EventServiceImpl implements EventService {
map.put("排序", event.getSort()); map.put("排序", event.getSort());
map.put("是否启用", event.getEnabled()); map.put("是否启用", event.getEnabled());
map.put("时间", event.getEventTime()); map.put("时间", event.getEventTime());
map.put(" clubId", event.getClubId()); map.put(" clubId", event.getClubId());
map.put(" createBy", event.getCreateBy()); map.put(" createBy", event.getCreateBy());
list.add(map); list.add(map);
} }
FileUtil.downloadExcel(list, response); FileUtil.downloadExcel(list, response);