add sport

pull/882/head
chanhengseang 2025-05-17 18:22:44 -07:00
parent d6a4749072
commit 28f6c90381
15 changed files with 781 additions and 0 deletions

View File

@ -36,6 +36,11 @@
<artifactId>eladmin-tools</artifactId> <artifactId>eladmin-tools</artifactId>
<version>2.7</version> <version>2.7</version>
</dependency> </dependency>
<dependency>
<groupId>me.zhengjie</groupId>
<artifactId>sport</artifactId>
<version>2.7</version>
</dependency>
<!-- quartz --> <!-- quartz -->
<dependency> <dependency>

View File

@ -0,0 +1,54 @@
create table sport
(
id bigint auto_increment primary key,
name varchar(32) not null comment '名称',
description varchar(255) null comment '描述',
create_time datetime null comment '创建时间',
update_time datetime null comment '更新时间',
icon varchar(255) null comment '图标',
sort int null comment '排序',
enabled bit null comment '是否启用'
);
create table club
(
id bigint auto_increment primary key,
name varchar(32) not null comment '名称',
description varchar(255) null comment '描述',
create_time datetime null comment '创建时间',
update_time datetime null comment '更新时间',
icon varchar(255) null comment '图标',
sort int null comment '排序',
enabled bit null comment '是否启用',
location varchar(255) null comment '位置',
longitude double null comment '经度',
latitude double null comment '纬度'
);
create table court
(
id bigint auto_increment primary key,
club_id bigint null references club (id),
sport_id bigint null references sport (id),
create_time datetime null comment '创建时间',
update_time datetime null comment '更新时间',
amount int not null default 0 comment '数量'
);
create table event
(
id bigint auto_increment primary key,
name varchar(32) not null comment '名称',
description varchar(255) null comment '描述',
format enum ('SINGLE', 'DOUBLE', 'TEAM') not null,
max_player int null comment '最大人数',
location varchar(255) null comment '位置',
image varchar(255) null comment '图片',
create_time datetime null comment '创建时间',
update_time datetime null comment '更新时间',
sort int null comment '排序',
enabled bit null comment '是否启用',
event_time datetime null comment '时间',
club_id bigint null references club (id),
create_by bigint null references sys_user (user_id)
);

View File

@ -0,0 +1,12 @@
create table player(
id bigint auto_increment primary key,
name varchar(32) not null comment '名称',
description varchar(255) null comment '描述',
latitude double null comment '纬度',
longitude double null comment '经度',
profile_image varchar(255) null comment '图片',
create_time datetime null comment '创建时间',
update_time datetime null comment '更新时间',
rate_score double null comment '评分',
user_id int8 null references sys_user (user_id)
)

View File

@ -13,6 +13,7 @@
<module>eladmin-system</module> <module>eladmin-system</module>
<module>eladmin-tools</module> <module>eladmin-tools</module>
<module>eladmin-generator</module> <module>eladmin-generator</module>
<module>sport</module>
</modules> </modules>
<name>ELADMIN 后台管理</name> <name>ELADMIN 后台管理</name>

122
sport/index.vue Normal file
View File

@ -0,0 +1,122 @@
<template>
<div class="app-container">
<!--工具栏-->
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<label class="el-form-item-label">名称</label>
<el-input v-model="query.name" clearable placeholder="名称" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<label class="el-form-item-label">创建时间</label>
<el-input v-model="query.createTime" clearable placeholder="创建时间" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<label class="el-form-item-label">是否启用</label>
<el-input v-model="query.enabled" clearable placeholder="是否启用" style="width: 185px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<rrOperation :crud="crud" />
</div>
<!--如果想在工具栏加入更多按钮可以使用插槽方式 slot = 'left' or 'right'-->
<crudOperation :permission="permission" />
<!--表单组件-->
<el-dialog :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="500px">
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="80px">
<el-form-item label="id">
<el-input v-model="form.id" style="width: 370px;" />
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input v-model="form.name" style="width: 370px;" />
</el-form-item>
<el-form-item label="描述">
<el-input v-model="form.description" :rows="3" type="textarea" style="width: 370px;" />
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker v-model="form.createTime" type="datetime" style="width: 370px;" />
</el-form-item>
<el-form-item label="更新时间">
<el-date-picker v-model="form.updateTime" type="datetime" style="width: 370px;" />
</el-form-item>
<el-form-item label="图标">
<el-input v-model="form.icon" style="width: 370px;" />
</el-form-item>
<el-form-item label="排序">
<el-input v-model="form.sort" style="width: 370px;" />
</el-form-item>
<el-form-item label="是否启用">
未设置字典请手动设置 Radio
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU"></el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU"></el-button>
</div>
</el-dialog>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" size="small" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
<el-table-column type="selection" width="55" />
<el-table-column prop="id" label="id" />
<el-table-column prop="name" label="名称" />
<el-table-column prop="description" label="描述" />
<el-table-column prop="createTime" label="创建时间" />
<el-table-column prop="updateTime" label="更新时间" />
<el-table-column prop="icon" label="图标" />
<el-table-column prop="sort" label="排序" />
<el-table-column prop="enabled" label="是否启用" />
<el-table-column v-if="checkPer(['admin','sport:edit','sport:del'])" label="操作" width="150px" align="center">
<template slot-scope="scope">
<udOperation
:data="scope.row"
:permission="permission"
/>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination />
</div>
</div>
</template>
<script>
import crudSport from '@/api/sport'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
import pagination from '@crud/Pagination'
const defaultForm = { id: null, name: null, description: null, createTime: null, updateTime: null, icon: null, sort: null, enabled: null }
export default {
name: 'Sport',
components: { pagination, crudOperation, rrOperation, udOperation },
mixins: [presenter(), header(), form(defaultForm), crud()],
cruds() {
return CRUD({ title: 'sport', url: 'api/sport', idField: 'id', sort: 'id,desc', crudMethod: { ...crudSport }})
},
data() {
return {
permission: {
add: ['admin', 'sport:add'],
edit: ['admin', 'sport:edit'],
del: ['admin', 'sport:del']
},
rules: {
name: [
{ required: true, message: '名称不能为空', trigger: 'blur' }
]
},
queryTypeOptions: [
{ key: 'name', display_name: '名称' },
{ key: 'createTime', display_name: '创建时间' },
{ key: 'enabled', display_name: '是否启用' }
]
}
},
methods: {
// false
[CRUD.HOOK.beforeRefresh]() {
return true
}
}
}
</script>
<style scoped>
</style>

29
sport/pom.xml Normal file
View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>eladmin</artifactId>
<groupId>me.zhengjie</groupId>
<version>2.7</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<properties>
<hutool.version>5.8.35</hutool.version>
</properties>
<artifactId>sport</artifactId>
<name>sport</name>
<dependencies>
<!--工具包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>me.zhengjie</groupId>
<artifactId>eladmin-tools</artifactId>
<version>2.7</version>
</dependency>
</dependencies>
</project>

27
sport/sport.js Normal file
View File

@ -0,0 +1,27 @@
import request from '@/utils/request'
export function add(data) {
return request({
url: 'api/sport',
method: 'post',
data
})
}
export function del(ids) {
return request({
url: 'api/sport/',
method: 'delete',
data: ids
})
}
export function edit(data) {
return request({
url: 'api/sport',
method: 'put',
data
})
}
export default { add, edit, del }

View File

@ -0,0 +1,82 @@
/*
* 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.domain;
import lombok.Data;
import cn.hutool.core.bean.BeanUtil;
import io.swagger.annotations.ApiModelProperty;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import javax.validation.constraints.*;
import javax.persistence.Entity;
import javax.persistence.Table;
import org.hibernate.annotations.*;
import java.sql.Timestamp;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
* @website https://eladmin.vip
* @description /
* @author Chanheng
* @date 2025-05-17
**/
@Entity
@Data
@Table(name="sport")
public class Sport implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "`id`")
@ApiModelProperty(value = "id")
private Long id;
@Column(name = "`name`",nullable = false)
@NotBlank
@ApiModelProperty(value = "名称")
private String name;
@Column(name = "`description`")
@ApiModelProperty(value = "描述")
private String description;
@Column(name = "`create_time`")
@CreationTimestamp
@ApiModelProperty(value = "创建时间")
private Timestamp createTime;
@Column(name = "`update_time`")
@UpdateTimestamp
@ApiModelProperty(value = "更新时间")
private Timestamp updateTime;
@Column(name = "`icon`")
@ApiModelProperty(value = "图标")
private String icon;
@Column(name = "`sort`")
@ApiModelProperty(value = "排序")
private Integer sort;
@Column(name = "`enabled`")
@ApiModelProperty(value = "是否启用")
private Boolean enabled;
public void copy(Sport source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}

View File

@ -0,0 +1,28 @@
/*
* 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.repository;
import com.srr.domain.Sport;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* @website https://eladmin.vip
* @author Chanheng
* @date 2025-05-17
**/
public interface SportRepository extends JpaRepository<Sport, Long>, JpaSpecificationExecutor<Sport> {
}

View File

@ -0,0 +1,94 @@
/*
* 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.rest;
import me.zhengjie.annotation.Log;
import com.srr.domain.Sport;
import com.srr.service.SportService;
import com.srr.service.dto.SportQueryCriteria;
import me.zhengjie.annotation.rest.AnonymousGetMapping;
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;
import me.zhengjie.utils.PageResult;
import com.srr.service.dto.SportDto;
/**
* @website https://eladmin.vip
* @author Chanheng
* @date 2025-05-17
**/
@RestController
@RequiredArgsConstructor
@Api(tags = "sport")
@RequestMapping("/api/sport")
public class SportController {
private final SportService sportService;
@AnonymousGetMapping(value = "/ping")
public String ping() {
return "pong";
}
@ApiOperation("导出数据")
@GetMapping(value = "/download")
@PreAuthorize("@el.check('sport:list')")
public void exportSport(HttpServletResponse response, SportQueryCriteria criteria) throws IOException {
sportService.download(sportService.queryAll(criteria), response);
}
@GetMapping
@ApiOperation("查询sport")
@PreAuthorize("@el.check('sport:list')")
public ResponseEntity<PageResult<SportDto>> querySport(SportQueryCriteria criteria, Pageable pageable){
return new ResponseEntity<>(sportService.queryAll(criteria,pageable),HttpStatus.OK);
}
@PostMapping
@Log("新增sport")
@ApiOperation("新增sport")
@PreAuthorize("@el.check('sport:add')")
public ResponseEntity<Object> createSport(@Validated @RequestBody Sport resources){
sportService.create(resources);
return new ResponseEntity<>(HttpStatus.CREATED);
}
@PutMapping
@Log("修改sport")
@ApiOperation("修改sport")
@PreAuthorize("@el.check('sport:edit')")
public ResponseEntity<Object> updateSport(@Validated @RequestBody Sport resources){
sportService.update(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@DeleteMapping
@Log("删除sport")
@ApiOperation("删除sport")
@PreAuthorize("@el.check('sport:del')")
public ResponseEntity<Object> deleteSport(@ApiParam(value = "传ID数组[]") @RequestBody Long[] ids) {
sportService.deleteAll(ids);
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@ -0,0 +1,83 @@
/*
* 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.service;
import com.srr.domain.Sport;
import com.srr.service.dto.SportDto;
import com.srr.service.dto.SportQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import me.zhengjie.utils.PageResult;
/**
* @website https://eladmin.vip
* @description
* @author Chanheng
* @date 2025-05-17
**/
public interface SportService {
/**
*
* @param criteria
* @param pageable
* @return Map<String,Object>
*/
PageResult<SportDto> queryAll(SportQueryCriteria criteria, Pageable pageable);
/**
*
* @param criteria
* @return List<SportDto>
*/
List<SportDto> queryAll(SportQueryCriteria criteria);
/**
* ID
* @param id ID
* @return SportDto
*/
SportDto findById(Long id);
/**
*
* @param resources /
*/
void create(Sport resources);
/**
*
* @param resources /
*/
void update(Sport resources);
/**
*
* @param ids /
*/
void deleteAll(Long[] ids);
/**
*
* @param all
* @param response /
* @throws IOException /
*/
void download(List<SportDto> all, HttpServletResponse response) throws IOException;
}

View File

@ -0,0 +1,55 @@
/*
* 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.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.io.Serializable;
import io.swagger.annotations.ApiModelProperty;
/**
* @website https://eladmin.vip
* @description /
* @author Chanheng
* @date 2025-05-17
**/
@Data
public class SportDto implements Serializable {
@ApiModelProperty(value = "id")
private Long id;
@ApiModelProperty(value = "名称")
private String name;
@ApiModelProperty(value = "描述")
private String description;
@ApiModelProperty(value = "创建时间")
private Timestamp createTime;
@ApiModelProperty(value = "更新时间")
private Timestamp updateTime;
@ApiModelProperty(value = "图标")
private String icon;
@ApiModelProperty(value = "排序")
private Integer sort;
@ApiModelProperty(value = "是否启用")
private Boolean enabled;
}

View File

@ -0,0 +1,46 @@
/*
* 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.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.util.List;
import me.zhengjie.annotation.Query;
import io.swagger.annotations.ApiModelProperty;
/**
* @website https://eladmin.vip
* @author Chanheng
* @date 2025-05-17
**/
@Data
public class SportQueryCriteria{
/** 模糊 */
@Query(type = Query.Type.INNER_LIKE)
@ApiModelProperty(value = "名称")
private String name;
/** 精确 */
@Query
@ApiModelProperty(value = "创建时间")
private Timestamp createTime;
/** 精确 */
@Query
@ApiModelProperty(value = "是否启用")
private Boolean enabled;
}

View File

@ -0,0 +1,111 @@
/*
* 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.service.impl;
import com.srr.domain.Sport;
import me.zhengjie.utils.ValidationUtil;
import me.zhengjie.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import com.srr.repository.SportRepository;
import com.srr.service.SportService;
import com.srr.service.dto.SportDto;
import com.srr.service.dto.SportQueryCriteria;
import com.srr.service.mapstruct.SportMapper;
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;
import me.zhengjie.utils.PageResult;
/**
* @website https://eladmin.vip
* @description
* @author Chanheng
* @date 2025-05-17
**/
@Service
@RequiredArgsConstructor
public class SportServiceImpl implements SportService {
private final SportRepository sportRepository;
private final SportMapper sportMapper;
@Override
public PageResult<SportDto> queryAll(SportQueryCriteria criteria, Pageable pageable){
Page<Sport> page = sportRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(sportMapper::toDto));
}
@Override
public List<SportDto> queryAll(SportQueryCriteria criteria){
return sportMapper.toDto(sportRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
@Transactional
public SportDto findById(Long id) {
Sport sport = sportRepository.findById(id).orElseGet(Sport::new);
ValidationUtil.isNull(sport.getId(),"Sport","id",id);
return sportMapper.toDto(sport);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(Sport resources) {
sportRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(Sport resources) {
Sport sport = sportRepository.findById(resources.getId()).orElseGet(Sport::new);
ValidationUtil.isNull( sport.getId(),"Sport","id",resources.getId());
sport.copy(resources);
sportRepository.save(sport);
}
@Override
public void deleteAll(Long[] ids) {
for (Long id : ids) {
sportRepository.deleteById(id);
}
}
@Override
public void download(List<SportDto> all, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>();
for (SportDto sport : all) {
Map<String,Object> map = new LinkedHashMap<>();
map.put("名称", sport.getName());
map.put("描述", sport.getDescription());
map.put("创建时间", sport.getCreateTime());
map.put("更新时间", sport.getUpdateTime());
map.put("图标", sport.getIcon());
map.put("排序", sport.getSort());
map.put("是否启用", sport.getEnabled());
list.add(map);
}
FileUtil.downloadExcel(list, response);
}
}

View File

@ -0,0 +1,32 @@
/*
* 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.service.mapstruct;
import me.zhengjie.base.BaseMapper;
import com.srr.domain.Sport;
import com.srr.service.dto.SportDto;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @website https://eladmin.vip
* @author Chanheng
* @date 2025-05-17
**/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface SportMapper extends BaseMapper<SportDto, Sport> {
}