queryByUserId(String userId);
15 | }
16 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/sys/role/auth/auth.component.html:
--------------------------------------------------------------------------------
1 |
2 | 0" nzCheckable nzMultiple nzExpandAll [nzData]="treeNodes"
3 | [nzCheckedKeys]="defaultCheckedKeys">
4 |
5 |
9 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/sys/role/menu/menu.component.html:
--------------------------------------------------------------------------------
1 |
2 | 0" nzCheckable nzMultiple nzExpandAll [nzData]="treeNodes"
3 | [nzCheckedKeys]="defaultCheckedKeys">
4 |
5 |
9 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/config/SoccerProperties.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.config;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import org.springframework.boot.context.properties.ConfigurationProperties;
6 | import org.springframework.context.annotation.Configuration;
7 |
8 | /**
9 | * @author duq
10 | * @date 2022/7/17
11 | */
12 | @Getter
13 | @Setter
14 | @Configuration
15 | @ConfigurationProperties(prefix = "soccer")
16 | public class SoccerProperties {
17 | }
18 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/service/SysConfigService.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.service;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 | import com.dqv5.soccer.pojo.SysInfo;
5 | import com.dqv5.soccer.table.SysConfigTable;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * @author duq
11 | * @date 2024/1/16
12 | */
13 | public interface SysConfigService {
14 | List queryAll();
15 |
16 | void setConfig(JSONObject param);
17 |
18 | SysInfo getSysInfo();
19 | }
20 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/config/SystemConfig.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.config;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.web.client.RestTemplate;
6 |
7 | /**
8 | * @author duq
9 | * @date 2022/7/17
10 | */
11 | @Configuration
12 | public class SystemConfig {
13 | @Bean
14 | public RestTemplate getRestTemplate() {
15 | return new RestTemplate();
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/exception/CommonRuntimeException.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.exception;
2 |
3 | /**
4 | * @author duq
5 | * @date 2022/7/17
6 | */
7 | public class CommonRuntimeException extends RuntimeException {
8 | public CommonRuntimeException() {
9 | super();
10 | }
11 |
12 | public CommonRuntimeException(String message) {
13 | super(message);
14 | }
15 |
16 | public CommonRuntimeException(Throwable cause) {
17 | super(cause);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/common/TreeNode.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.common;
2 |
3 | import lombok.Data;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | /**
9 | * @author duq
10 | * @date 2022/7/17
11 | */
12 | @Data
13 | public class TreeNode {
14 | private String key;
15 | private String title;
16 | private Boolean isLeaf;
17 | private List children = new ArrayList<>();
18 | private TreeNodeType type;
19 | private Object origin;
20 |
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/mapper/SysRoleMapper.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.mapper;
2 |
3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
4 | import com.dqv5.soccer.pojo.SysRole;
5 | import com.dqv5.soccer.table.SysRoleTable;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * @author duq
11 | * @date 2022/7/5
12 | */
13 | public interface SysRoleMapper extends BaseMapper {
14 |
15 | List queryList();
16 |
17 | List queryByUserId(String userId);
18 | }
19 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/common/RestReturnEntity.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.common;
2 |
3 | import lombok.Builder;
4 | import lombok.Data;
5 |
6 | /**
7 | * 通用返回值实体类
8 | *
9 | * @author duq
10 | * @date 2022/7/17
11 | */
12 | @Data
13 | @Builder
14 | public class RestReturnEntity {
15 | /**
16 | * 提示信息
17 | */
18 | private String msg;
19 | /**
20 | * 异常信息
21 | */
22 | private String errMsg;
23 | /**
24 | * 数据
25 | */
26 | private T data;
27 |
28 |
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/sys/auth/auth.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/sys/role/role.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/common/Pageable.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.common;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * @author duqian
7 | * @date 2023/12/6
8 | */
9 | @Data
10 | public class Pageable {
11 | private int pageNumber;
12 | private int pageSize;
13 |
14 | public static Pageable of(int pageNumber, int pageSize) {
15 | Pageable pageable = new Pageable();
16 | pageable.setPageNumber(pageNumber);
17 | pageable.setPageSize(pageSize);
18 | return pageable;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/passport/register-result/register-result.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 你的账户:{{email}} 注册成功
5 |
6 |
7 |
10 |
13 |
14 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/mapper/SysMenuMapper.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.mapper;
2 |
3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
4 | import com.dqv5.soccer.table.SysMenuTable;
5 | import com.dqv5.soccer.table.SysRoleTable;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * @author duq
11 | * @date 2022/7/18
12 | */
13 | public interface SysMenuMapper extends BaseMapper {
14 |
15 | List queryByRoleId(String roleId);
16 |
17 | List queryByUserId(String userId);
18 | }
19 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/pojo/AbstractBaseVO.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.pojo;
2 |
3 | import lombok.Data;
4 |
5 | import java.util.Date;
6 |
7 | /**
8 | * @author duq
9 | * @date 2024/1/1
10 | */
11 | @Data
12 | public abstract class AbstractBaseVO {
13 |
14 | private String createdBy;
15 |
16 | private String createdNickName;
17 |
18 | private Date createdDate;
19 |
20 | private String lastModifiedBy;
21 |
22 | private String lastModifiedNickName;
23 |
24 | private Date lastModifiedDate;
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/.eslintignore:
--------------------------------------------------------------------------------
1 | _cli-tpl/
2 | dist/
3 | coverage/
4 |
5 | # Logs
6 | logs
7 | *.log
8 | npm-debug.log*
9 | yarn-debug.log*
10 | yarn-error.log*
11 |
12 | # Dependency directories
13 | node_modules/
14 |
15 | # TypeScript cache
16 | *.tsbuildinfo
17 |
18 | # Optional npm cache directory
19 | .npm
20 |
21 | # Optional eslint cache
22 | .eslintcache
23 |
24 | # Yarn Integrity file
25 | .yarn-integrity
26 |
27 | # dotenv environment variables file
28 | .env
29 | .env.test
30 |
31 | .cache/
32 |
33 | # yarn v2
34 | .yarn
35 |
36 | **/src/index.html
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/sys/auth/edit/edit.component.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/sys/dept/edit/edit.component.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/sys/menu/edit/edit.component.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/sys/role/edit/edit.component.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/sys/user/edit/edit.component.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/file/DiskProperties.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.file;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import org.springframework.boot.context.properties.ConfigurationProperties;
6 | import org.springframework.context.annotation.Configuration;
7 |
8 | /**
9 | * @author duq
10 | * @date 2024/1/23
11 | */
12 | @Getter
13 | @Setter
14 | @Configuration
15 | @ConfigurationProperties(prefix = "soccer.file-store.disk")
16 | public class DiskProperties {
17 | private boolean enable;
18 | private String root;
19 | }
20 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/shared/st-widget/st-widget.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 |
3 | // import { STWidgetRegistry } from '@delon/abc/st';
4 | import { SharedModule } from '../shared.module';
5 |
6 | export const STWIDGET_COMPONENTS = [];
7 |
8 | @NgModule({
9 | declarations: STWIDGET_COMPONENTS,
10 | imports: [SharedModule],
11 | exports: [...STWIDGET_COMPONENTS]
12 | })
13 | export class STWidgetModule {
14 | // constructor(widgetRegistry: STWidgetRegistry) {
15 | // widgetRegistry.register(STImgWidget.KEY, STImgWidget);
16 | // }
17 | }
18 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/mapper/SysUserMapper.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.mapper;
2 |
3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
4 | import com.dqv5.soccer.pojo.SysUser;
5 | import com.dqv5.soccer.pojo.UserQueryParam;
6 | import com.dqv5.soccer.table.SysUserTable;
7 | import org.apache.ibatis.annotations.Param;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * @author duq
13 | * @date 2022/7/5
14 | */
15 | public interface SysUserMapper extends BaseMapper {
16 | List queryList(@Param("param") UserQueryParam param);
17 | }
18 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/service/SysUserService.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.service;
2 |
3 | import com.dqv5.soccer.pojo.SysUser;
4 | import com.dqv5.soccer.pojo.UserQueryParam;
5 | import com.github.pagehelper.PageInfo;
6 |
7 | /**
8 | * @author duq
9 | * @date 2022/7/10
10 | */
11 | public interface SysUserService {
12 | PageInfo queryListForPage(UserQueryParam pageable);
13 |
14 | SysUser findOne(String id);
15 |
16 | void insert(SysUser sysUser);
17 |
18 | void update(SysUser sysUser);
19 |
20 | void deleteById(String id);
21 | }
22 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/table/SysUserDeptTable.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.table;
2 |
3 | import com.baomidou.mybatisplus.annotation.TableName;
4 | import lombok.*;
5 |
6 | import java.io.Serializable;
7 |
8 | @EqualsAndHashCode(callSuper = true)
9 | @Data
10 | @TableName("sys_user_dept")
11 | @Builder
12 | @NoArgsConstructor
13 | @AllArgsConstructor
14 | public class SysUserDeptTable extends AbstractBaseTable implements Serializable {
15 | private static final long serialVersionUID = 1L;
16 | private String userId;
17 | private String deptId;
18 |
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/service/SysFileService.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.service;
2 |
3 | import com.dqv5.soccer.pojo.SysFile;
4 | import org.springframework.web.multipart.MultipartFile;
5 |
6 | import jakarta.servlet.http.HttpServletResponse;
7 |
8 | /**
9 | * @author duqian
10 | * @date 2024/1/23
11 | */
12 |
13 | public interface SysFileService {
14 |
15 | SysFile uploadFile(MultipartFile file);
16 |
17 | SysFile getFileInfo(String id);
18 |
19 | void downloadFile(String id, String dl, HttpServletResponse response);
20 |
21 | void deleteFile(String id);
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/structmapper/SysRoleStructMapper.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.structmapper;
2 |
3 | import com.dqv5.soccer.pojo.SysRole;
4 | import com.dqv5.soccer.table.SysRoleTable;
5 | import org.mapstruct.Mapper;
6 | import org.mapstruct.factory.Mappers;
7 |
8 | /**
9 | * @author duqian
10 | * @date 2025/8/23
11 | */
12 | @Mapper
13 | public interface SysRoleStructMapper {
14 | SysRoleStructMapper INSTANCE = Mappers.getMapper(SysRoleStructMapper.class);
15 |
16 |
17 | SysRole entityToPojo(SysRoleTable entity);
18 |
19 | SysRoleTable pojoToEntity(SysRole pojo);
20 | }
21 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/structmapper/SysUserStructMapper.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.structmapper;
2 |
3 | import com.dqv5.soccer.pojo.SysUser;
4 | import com.dqv5.soccer.table.SysUserTable;
5 | import org.mapstruct.Mapper;
6 | import org.mapstruct.factory.Mappers;
7 |
8 | /**
9 | * @author duqian
10 | * @date 2025/8/23
11 | */
12 | @Mapper
13 | public interface SysUserStructMapper {
14 | SysUserStructMapper INSTANCE = Mappers.getMapper(SysUserStructMapper.class);
15 |
16 |
17 | SysUser entityToPojo(SysUserTable entity);
18 |
19 | SysUserTable pojoToEntity(SysUser pojo);
20 | }
21 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/structmapper/SysAuthStructMapper.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.structmapper;
2 |
3 | import com.dqv5.soccer.pojo.SysAuth;
4 | import com.dqv5.soccer.table.SysAuthTable;
5 | import org.mapstruct.Mapper;
6 | import org.mapstruct.factory.Mappers;
7 |
8 | /**
9 | * @author duqian
10 | * @date 2025/8/23
11 | */
12 | @Mapper
13 | public interface SysAuthStructMapper {
14 | SysAuthStructMapper INSTANCE = Mappers.getMapper(SysAuthStructMapper.class);
15 |
16 |
17 | SysAuth entityToPojo(SysAuthTable entity);
18 |
19 | SysAuthTable pojoToEntity(SysAuth pojo);
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/table/SysUserRoleTable.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.table;
2 |
3 | import com.baomidou.mybatisplus.annotation.TableName;
4 | import lombok.Data;
5 | import lombok.EqualsAndHashCode;
6 |
7 | import java.io.Serializable;
8 |
9 | /**
10 | * @author duq
11 | * @date 2023/12/6
12 | */
13 | @EqualsAndHashCode(callSuper = true)
14 | @Data
15 | @TableName("sys_user_role")
16 | public class SysUserRoleTable extends AbstractBaseTable implements Serializable {
17 | private static final long serialVersionUID = 1L;
18 | private String userId;
19 | private String roleId;
20 | }
21 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/table/SysRoleAuthTable.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.table;
2 |
3 | import com.baomidou.mybatisplus.annotation.TableName;
4 | import lombok.Data;
5 | import lombok.EqualsAndHashCode;
6 |
7 | import java.io.Serializable;
8 |
9 | /**
10 | * @author duq
11 | * @date 2022/7/12
12 | */
13 | @Data
14 | @EqualsAndHashCode(callSuper = true)
15 | @TableName("sys_role_auth")
16 | public class SysRoleAuthTable extends AbstractBaseTable implements Serializable {
17 | private static final long serialVersionUID = 1L;
18 |
19 | private String roleId;
20 | private String authId;
21 | }
22 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/table/SysRoleMenuTable.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.table;
2 |
3 | import com.baomidou.mybatisplus.annotation.TableName;
4 | import lombok.Data;
5 | import lombok.EqualsAndHashCode;
6 |
7 | import java.io.Serializable;
8 |
9 | /**
10 | * @author duq
11 | * @date 2022/7/12
12 | */
13 | @Data
14 | @EqualsAndHashCode(callSuper = true)
15 | @TableName("sys_role_menu")
16 | public class SysRoleMenuTable extends AbstractBaseTable implements Serializable {
17 | private static final long serialVersionUID = 1L;
18 |
19 | private String roleId;
20 | private String menuId;
21 | }
22 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/sys/auth/sys-auth.service.ts:
--------------------------------------------------------------------------------
1 | import {Injectable} from '@angular/core';
2 | import {_HttpClient} from '@delon/theme';
3 | import {map, Observable} from "rxjs";
4 |
5 | @Injectable()
6 | export class SysAuthService {
7 |
8 | constructor(private http: _HttpClient) {
9 | }
10 |
11 | loadAuthFolders(): Observable {
12 | return this.http.get('/api/auth/folders').pipe(
13 | map(res => res.data)
14 | )
15 | }
16 |
17 | loadAuthTree(): Observable {
18 | return this.http.get('/api/auth/tree').pipe(
19 | map(res => res.data)
20 | )
21 | }
22 |
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/Application.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer;
2 |
3 | import org.mybatis.spring.annotation.MapperScan;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
7 |
8 | @SpringBootApplication
9 | @MapperScan({"com.dqv5.soccer.mapper"})
10 | @EnableMethodSecurity
11 | public class Application {
12 |
13 | public static void main(String[] args) {
14 | SpringApplication.run(Application.class, args);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/test.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-unassigned-import */
2 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
3 |
4 | import 'zone.js/testing';
5 | import { getTestBed } from '@angular/core/testing';
6 | import {
7 | BrowserDynamicTestingModule,
8 | platformBrowserDynamicTesting
9 | } from '@angular/platform-browser-dynamic/testing';
10 |
11 | // First, initialize the Angular testing environment.
12 | getTestBed().initTestEnvironment(
13 | BrowserDynamicTestingModule,
14 | platformBrowserDynamicTesting(), {
15 | teardown: { destroyAfterEach: false }
16 | }
17 | );
18 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/security/CustomPasswordEncoder.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.security;
2 |
3 | import org.springframework.security.crypto.password.PasswordEncoder;
4 |
5 | /**
6 | * @author duq
7 | * @date 2022/7/12
8 | */
9 | public class CustomPasswordEncoder implements PasswordEncoder {
10 | @Override
11 | public String encode(CharSequence rawPassword) {
12 | return "" + rawPassword + "";
13 | }
14 |
15 | @Override
16 | public boolean matches(CharSequence rawPassword, String encodedPassword) {
17 | return encode(rawPassword).equals(encodedPassword);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/service/SysDeptService.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.service;
2 |
3 | import com.dqv5.soccer.common.TreeNode;
4 | import com.dqv5.soccer.pojo.SysDept;
5 | import com.dqv5.soccer.table.SysDeptTable;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * @author admin
11 | * @date 2022/7/17
12 | */
13 | public interface SysDeptService {
14 | List queryAll();
15 |
16 | List queryAllTree();
17 |
18 | SysDept findOne(String id);
19 |
20 | void insert(SysDeptTable param);
21 |
22 | void update(SysDeptTable param);
23 |
24 | void deleteById(String id);
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/layout/passport/passport.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |

6 |
{{ app.name }}
7 |
8 |
{{ app.description }}
9 |
10 |
11 |
12 | Copyright
13 | 2022
14 | duqian
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/exception/exception.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component } from '@angular/core';
2 | import { ActivatedRoute } from '@angular/router';
3 | import { ExceptionType } from '@delon/abc/exception';
4 |
5 | @Component({
6 | selector: 'app-exception',
7 | template: ` `,
8 | changeDetection: ChangeDetectionStrategy.OnPush
9 | })
10 | export class ExceptionComponent {
11 | get type(): ExceptionType {
12 | return this.route.snapshot.data['type'];
13 | }
14 |
15 | constructor(private route: ActivatedRoute) {}
16 | }
17 |
--------------------------------------------------------------------------------
/soccer-server/src/main/resources/mapper/mybatis-config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/passport/register-result/register-result.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { ActivatedRoute } from '@angular/router';
3 | import { NzMessageService } from 'ng-zorro-antd/message';
4 |
5 | @Component({
6 | selector: 'passport-register-result',
7 | templateUrl: './register-result.component.html'
8 | })
9 | export class UserRegisterResultComponent {
10 | params = { email: '' };
11 | email = '';
12 | constructor(route: ActivatedRoute, public msg: NzMessageService) {
13 | this.params.email = this.email = route.snapshot.queryParams['email'] || 'ng-alain@example.com';
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/config/InitDataRunner.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.config;
2 |
3 | import com.dqv5.soccer.service.InitDataService;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.boot.CommandLineRunner;
6 | import org.springframework.stereotype.Component;
7 |
8 | import jakarta.annotation.Resource;
9 |
10 | @Component
11 | @Slf4j
12 | public class InitDataRunner implements CommandLineRunner {
13 |
14 | @Resource
15 | private InitDataService initDataService;
16 |
17 | @Override
18 | public void run(String... args) {
19 | initDataService.initData(false);
20 | }
21 |
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.dqv5
7 | soccer
8 | 0.3.0
9 |
10 |
11 | soccer-angular-webapp
12 | 0.3.0
13 | jar
14 | soccer-angular-webapp
15 |
16 |
17 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/structmapper/SysAuthFolderStructMapper.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.structmapper;
2 |
3 | import com.dqv5.soccer.pojo.SysAuthFolder;
4 | import com.dqv5.soccer.table.SysAuthFolderTable;
5 | import org.mapstruct.Mapper;
6 | import org.mapstruct.factory.Mappers;
7 |
8 | /**
9 | * @author duqian
10 | * @date 2025/8/23
11 | */
12 | @Mapper
13 | public interface SysAuthFolderStructMapper {
14 | SysAuthFolderStructMapper INSTANCE = Mappers.getMapper(SysAuthFolderStructMapper.class);
15 |
16 |
17 | SysAuthFolder entityToPojo(SysAuthFolderTable entity);
18 |
19 | SysAuthFolderTable pojoToEntity(SysAuthFolder pojo);
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/file/AmazonS3Properties.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.file;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import org.springframework.boot.context.properties.ConfigurationProperties;
6 | import org.springframework.context.annotation.Configuration;
7 |
8 | /**
9 | * @author duq
10 | * @date 2024/1/23
11 | */
12 | @Getter
13 | @Setter
14 | @Configuration
15 | @ConfigurationProperties(prefix = "soccer.file-store.s3")
16 | public class AmazonS3Properties {
17 | private boolean enable;
18 | private String endpoint;
19 | private String bucketName;
20 | private String accessKey;
21 | private String secretKey;
22 | }
23 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/proxy.conf.js:
--------------------------------------------------------------------------------
1 | /**
2 | * For more configuration, please refer to https://angular.io/guide/build#proxying-to-a-backend-server
3 | *
4 | * 更多配置描述请参考 https://angular.cn/guide/build#proxying-to-a-backend-server
5 | *
6 | * Note: The proxy is only valid for real requests, Mock does not actually generate requests, so the priority of Mock will be higher than the proxy
7 | */
8 | module.exports = {
9 | /**
10 | * The following means that all requests are directed to the backend `https://localhost:9000/`
11 | */
12 | '/api/': {
13 | target: 'http://localhost:8080/',
14 | secure: false, // Ignore invalid SSL certificates
15 | changeOrigin: true
16 | }
17 | };
18 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/service/SysMenuService.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.service;
2 |
3 | import com.dqv5.soccer.common.TreeNode;
4 | import com.dqv5.soccer.pojo.SysMenu;
5 | import com.dqv5.soccer.table.SysMenuTable;
6 |
7 | import java.util.List;
8 |
9 |
10 | /**
11 | * @author admin
12 | * @date 2022/7/17
13 | */
14 | public interface SysMenuService {
15 | List findAll();
16 |
17 | List findAllTree();
18 |
19 | SysMenuTable findOne(String id);
20 |
21 | void insert(SysMenu param);
22 |
23 | void update(SysMenu param);
24 |
25 | void deleteById(String id);
26 |
27 | List queryByUserId(String userId);
28 | }
29 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/structmapper/SysDeptStructMapper.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.structmapper;
2 |
3 | import com.dqv5.soccer.pojo.SysDept;
4 | import com.dqv5.soccer.pojo.SysUser;
5 | import com.dqv5.soccer.table.SysDeptTable;
6 | import com.dqv5.soccer.table.SysUserTable;
7 | import org.mapstruct.Mapper;
8 | import org.mapstruct.factory.Mappers;
9 |
10 | /**
11 | * @author duqian
12 | * @date 2025/8/23
13 | */
14 | @Mapper
15 | public interface SysDeptStructMapper {
16 | SysDeptStructMapper INSTANCE = Mappers.getMapper(SysDeptStructMapper.class);
17 |
18 |
19 | SysDept entityToPojo(SysDeptTable entity);
20 |
21 | SysDeptTable pojoToEntity(SysDept pojo);
22 | }
23 |
--------------------------------------------------------------------------------
/soccer-server/src/main/resources/mapper/sqlMap/SysDeptMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
14 |
15 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/mapper/SysAuthMapper.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.mapper;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
5 | import com.dqv5.soccer.pojo.SysAuth;
6 | import com.dqv5.soccer.table.SysAuthTable;
7 | import org.apache.ibatis.annotations.Param;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * @author duq
13 | * @date 2022/7/18
14 | */
15 | public interface SysAuthMapper extends BaseMapper {
16 |
17 | List queryByRoleId(String roleId);
18 |
19 | List queryByUserId(String userId);
20 |
21 | List queryList(@Param("param") JSONObject param);
22 | }
23 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/shared/json-schema/test/test.widget.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
2 | import { ControlWidget } from '@delon/form';
3 |
4 | @Component({
5 | selector: 'test',
6 | template: `
7 |
8 | test widget
9 |
10 | `,
11 | preserveWhitespaces: false,
12 | changeDetection: ChangeDetectionStrategy.OnPush
13 | })
14 | export class TestWidget extends ControlWidget implements OnInit {
15 | static readonly KEY = 'test';
16 |
17 | ngOnInit(): void {
18 | console.warn('init test widget');
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/soccer-server/src/main/resources/liquibase/common/db.changelog-master.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/common/ConfigValue.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.common;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 |
6 | /**
7 | * @author duq
8 | * @date 2024/1/3
9 | */
10 | @AllArgsConstructor
11 | @Getter
12 | public enum ConfigValue {
13 | SYS_NAME("sys_name", "系统名称", "Soccer"),
14 | SYS_DESC("sys_desc", "系统描述", "Springboot + Angular 开发框架"),
15 | SYS_LOGO_BIG("sys_logo_big", "系统Logo(大)", "https://image.dqv5.com/public/soccer.png"),
16 | SYS_LOGO_SMALL("sys_logo_small", "系统Logo(小)", "https://image.dqv5.com/public/soccer.png"),
17 | ;
18 |
19 | private final String configKey;
20 | private final String configName;
21 | private final String defaultValue;
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/table/AbstractBaseTable.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.table;
2 |
3 | import com.baomidou.mybatisplus.annotation.FieldFill;
4 | import com.baomidou.mybatisplus.annotation.TableField;
5 | import lombok.Data;
6 |
7 | import java.util.Date;
8 |
9 | /**
10 | * @author duq
11 | * @date 2020/4/4
12 | */
13 | @Data
14 | public abstract class AbstractBaseTable {
15 | @TableField(fill = FieldFill.INSERT)
16 | private String createdBy;
17 |
18 | @TableField(fill = FieldFill.INSERT)
19 | private Date createdDate;
20 |
21 | @TableField(fill = FieldFill.INSERT_UPDATE)
22 | private String lastModifiedBy;
23 |
24 | @TableField(fill = FieldFill.INSERT_UPDATE)
25 | private Date lastModifiedDate;
26 | }
27 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # Compiled output
4 | /dist
5 | /tmp
6 | /out-tsc
7 | /bazel-out
8 |
9 | # Node
10 | /node_modules
11 | npm-debug.log
12 | yarn-error.log
13 |
14 | # IDEs and editors
15 | .idea/
16 | .project
17 | .classpath
18 | .c9/
19 | *.launch
20 | .settings/
21 | *.sublime-workspace
22 |
23 | # Visual Studio Code
24 | .vscode/*
25 | !.vscode/settings.json
26 | !.vscode/tasks.json
27 | !.vscode/launch.json
28 | !.vscode/extensions.json
29 | .history/*
30 |
31 | # Miscellaneous
32 | /.angular/cache
33 | .sass-cache/
34 | /connect.lock
35 | /coverage
36 | /libpeerconnection.log
37 | testem.log
38 | /typings
39 |
40 | # System files
41 | .DS_Store
42 | Thumbs.db
43 | /target/
44 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/exception/exception-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { RouterModule, Routes } from '@angular/router';
3 |
4 | import { ExceptionComponent } from './exception.component';
5 | import { ExceptionTriggerComponent } from './trigger.component';
6 |
7 | const routes: Routes = [
8 | { path: '403', component: ExceptionComponent, data: { type: 403 } },
9 | { path: '404', component: ExceptionComponent, data: { type: 404 } },
10 | { path: '500', component: ExceptionComponent, data: { type: 500 } },
11 | { path: 'trigger', component: ExceptionTriggerComponent }
12 | ];
13 |
14 | @NgModule({
15 | imports: [RouterModule.forChild(routes)],
16 | exports: [RouterModule]
17 | })
18 | export class ExceptionRoutingModule {}
19 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/layout/basic/basic.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from '@angular/core';
2 | import {SettingsService, User} from '@delon/theme';
3 | import {LayoutDefaultOptions} from '@delon/theme/layout-default';
4 | import {environment} from '@env/environment';
5 |
6 | @Component({
7 | selector: 'layout-basic',
8 | templateUrl: './basic.component.html',
9 | })
10 | export class LayoutBasicComponent {
11 | options: LayoutDefaultOptions = {
12 | logoExpanded: `./assets/logo-full.svg`,
13 | logoCollapsed: `./assets/logo.svg`,
14 | };
15 | searchToggleStatus = false;
16 | showSettingDrawer = !environment.production;
17 |
18 | get user(): User {
19 | return this.settings.user;
20 | }
21 |
22 | constructor(private settings: SettingsService) {
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/exception/exception.module.ts:
--------------------------------------------------------------------------------
1 | import { CommonModule } from '@angular/common';
2 | import { NgModule } from '@angular/core';
3 | import { ExceptionModule as DelonExceptionModule } from '@delon/abc/exception';
4 | import { NzButtonModule } from 'ng-zorro-antd/button';
5 | import { NzCardModule } from 'ng-zorro-antd/card';
6 |
7 | import { ExceptionRoutingModule } from './exception-routing.module';
8 | import { ExceptionComponent } from './exception.component';
9 | import { ExceptionTriggerComponent } from './trigger.component';
10 |
11 | @NgModule({
12 | imports: [CommonModule, DelonExceptionModule, NzButtonModule, NzCardModule, ExceptionRoutingModule],
13 | declarations: [ExceptionComponent, ExceptionTriggerComponent]
14 | })
15 | export class ExceptionModule {}
16 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/table/SysConfigTable.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.table;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
6 | import lombok.*;
7 |
8 | import java.io.Serializable;
9 |
10 | @EqualsAndHashCode(callSuper = true)
11 | @Data
12 | @TableName("sys_config")
13 | @Builder
14 | @NoArgsConstructor
15 | @AllArgsConstructor
16 | public class SysConfigTable extends AbstractBaseTable implements Serializable {
17 | private static final long serialVersionUID = 1L;
18 |
19 | @TableId(type = IdType.INPUT)
20 | private String configKey;
21 |
22 | private String configValue;
23 |
24 | private String configName;
25 |
26 |
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/table/SysRoleTable.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.table;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 |
9 | import java.io.Serializable;
10 |
11 | /**
12 | * @author duq
13 | * @date 2022/7/12
14 | */
15 | @Data
16 | @EqualsAndHashCode(callSuper = true)
17 | @TableName("sys_role")
18 | public class SysRoleTable extends AbstractBaseTable implements Serializable {
19 | private static final long serialVersionUID = 1L;
20 |
21 | @TableId(type = IdType.ASSIGN_UUID)
22 | private String roleId;
23 | private String roleValue;
24 | private String roleName;
25 | }
26 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/security/JWTAuthenticationEntryPoint.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.security;
2 |
3 | import org.springframework.security.core.AuthenticationException;
4 | import org.springframework.security.web.AuthenticationEntryPoint;
5 |
6 | import jakarta.servlet.ServletException;
7 | import jakarta.servlet.http.HttpServletRequest;
8 | import jakarta.servlet.http.HttpServletResponse;
9 | import java.io.IOException;
10 |
11 | public class JWTAuthenticationEntryPoint implements AuthenticationEntryPoint {
12 | @Override
13 | public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
14 | throws IOException, ServletException {
15 | response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/service/SysRoleService.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.service;
2 |
3 | import com.dqv5.soccer.common.Pageable;
4 | import com.dqv5.soccer.pojo.SysRole;
5 | import com.dqv5.soccer.table.SysRoleTable;
6 | import com.github.pagehelper.PageInfo;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * @author duq
12 | * @date 2022/7/10
13 | */
14 | public interface SysRoleService {
15 |
16 | PageInfo queryListForPage(Pageable pageable);
17 |
18 | SysRole findOne(String id);
19 |
20 | void insert(SysRoleTable param);
21 |
22 | void update(SysRoleTable param);
23 |
24 | void deleteById(String id);
25 |
26 | void saveRoleMenu(SysRole param);
27 |
28 | void saveRoleAuth(SysRole param);
29 |
30 | List queryByUserId(String userId);
31 | }
32 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/table/SysAuthFolderTable.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.table;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
6 | import lombok.*;
7 |
8 | import java.io.Serializable;
9 |
10 | @EqualsAndHashCode(callSuper = true)
11 | @Data
12 | @TableName("sys_auth_folder")
13 | @Builder
14 | @NoArgsConstructor
15 | @AllArgsConstructor
16 | public class SysAuthFolderTable extends AbstractBaseTable implements Serializable {
17 | private static final long serialVersionUID = 1L;
18 |
19 | @TableId(type = IdType.ASSIGN_UUID)
20 | private String authFolderId;
21 |
22 | private String authFolderName;
23 |
24 | private Integer displayIndex;
25 |
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode, ViewEncapsulation } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { NzSafeAny } from 'ng-zorro-antd/core/types';
5 |
6 | import { AppModule } from './app/app.module';
7 | import { environment } from './environments/environment';
8 |
9 |
10 |
11 | if (environment.production) {
12 | enableProdMode();
13 | }
14 |
15 | platformBrowserDynamic()
16 | .bootstrapModule(AppModule, {
17 | defaultEncapsulation: ViewEncapsulation.Emulated,
18 | preserveWhitespaces: false
19 | })
20 | .then(res => {
21 | const win = window as NzSafeAny;
22 | if (win && win.appBootstrap) {
23 | win.appBootstrap();
24 | }
25 | return res;
26 | })
27 | .catch(err => console.error(err));
28 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/file/FileStoreType.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.file;
2 |
3 | import com.dqv5.soccer.exception.CommonRuntimeException;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Getter;
6 |
7 | /**
8 | * @author duq
9 | * @date 2024/2/17
10 | */
11 | @Getter
12 | @AllArgsConstructor
13 | public enum FileStoreType {
14 | Disk(1, "disk"),
15 | AmazonS3(2, "s3"),
16 | ;
17 |
18 | private final int value;
19 | private final String name;
20 |
21 | public static FileStoreType fromName(String name) {
22 | for (FileStoreType value : FileStoreType.values()) {
23 | if (value.getName().equalsIgnoreCase(name)) {
24 | return value;
25 | }
26 | }
27 | throw new CommonRuntimeException("参数异常:" + name);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/layout/basic/widgets/fullscreen.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component, HostListener } from '@angular/core';
2 | import screenfull from 'screenfull';
3 |
4 | @Component({
5 | selector: 'header-fullscreen',
6 | template: `
7 |
8 | {{ status ? '退出全屏' : '全屏' }}
9 | `,
10 | host: {
11 | '[class.flex-1]': 'true'
12 | },
13 | changeDetection: ChangeDetectionStrategy.OnPush
14 | })
15 | export class HeaderFullScreenComponent {
16 | status = false;
17 |
18 | @HostListener('window:resize')
19 | _resize(): void {
20 | this.status = screenfull.isFullscreen;
21 | }
22 |
23 | @HostListener('click')
24 | _click(): void {
25 | if (screenfull.isEnabled) {
26 | screenfull.toggle();
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/sys/config/config.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/table/SysAuthTable.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.table;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
6 | import lombok.*;
7 |
8 | import java.io.Serializable;
9 |
10 | @EqualsAndHashCode(callSuper = true)
11 | @Data
12 | @TableName("sys_auth")
13 | @Builder
14 | @NoArgsConstructor
15 | @AllArgsConstructor
16 | public class SysAuthTable extends AbstractBaseTable implements Serializable {
17 | private static final long serialVersionUID = 1L;
18 |
19 | @TableId(type = IdType.ASSIGN_UUID)
20 | private String authId;
21 |
22 | private String authValue;
23 |
24 | private String authName;
25 |
26 | private String authFolderId;
27 |
28 | private Integer displayIndex;
29 |
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/pojo/SysFile.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.pojo;
2 |
3 | import com.dqv5.soccer.table.SysFileTable;
4 | import lombok.Data;
5 | import lombok.EqualsAndHashCode;
6 | import org.springframework.beans.BeanUtils;
7 |
8 | import java.io.Serializable;
9 |
10 | /**
11 | * @author duq
12 | * @date 2024/2/15
13 | */
14 | @Data
15 | @EqualsAndHashCode(callSuper = true)
16 | public class SysFile extends AbstractBaseVO implements Serializable {
17 | private static final long serialVersionUID = 1L;
18 |
19 | private String fileId;
20 | private String fileName;
21 | private String fileType;
22 | private Long fileSize;
23 | private Integer duration;
24 | private String sha256;
25 | private Integer storeType;
26 | private String storeInfo;
27 | private String remark;
28 | private String url;
29 |
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/table/SysDeptTable.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.table;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 |
9 | import java.io.Serializable;
10 |
11 |
12 | /**
13 | * @author duq
14 | * @date 2024/1/10
15 | */
16 | @Data
17 | @EqualsAndHashCode(callSuper = true)
18 | @TableName("sys_dept")
19 | public class SysDeptTable extends AbstractBaseTable implements Serializable {
20 | private static final long serialVersionUID = 1L;
21 |
22 | @TableId(type = IdType.ASSIGN_UUID)
23 | private String deptId;
24 | private String deptName;
25 | private String deptCode;
26 | private String parentId;
27 | private Integer displayIndex;
28 | }
29 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/sys/user/user.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/structmapper/SysFileStructMapper.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.structmapper;
2 |
3 | import com.dqv5.soccer.pojo.SysFile;
4 | import com.dqv5.soccer.table.SysFileTable;
5 | import org.mapstruct.Mapper;
6 | import org.mapstruct.Mapping;
7 | import org.mapstruct.Named;
8 | import org.mapstruct.factory.Mappers;
9 |
10 | /**
11 | * @author duqian
12 | * @date 2025/8/23
13 | */
14 | @Mapper
15 | public interface SysFileStructMapper {
16 | SysFileStructMapper INSTANCE = Mappers.getMapper(SysFileStructMapper.class);
17 |
18 | @Mapping(source = "fileId", target = "url", qualifiedByName = "appendUrlPrefix")
19 | SysFile entityToPojo(SysFileTable entity);
20 |
21 | SysFileTable pojoToEntity(SysFile pojo);
22 |
23 | @Named("appendUrlPrefix")
24 | default String appendPrefix(String fileId) {
25 | return "/api/file/file/" + fileId;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/utils/JsonUtil.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.utils;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 |
5 | import java.io.IOException;
6 |
7 | /**
8 | * @author duq
9 | * @date 2022/7/17
10 | */
11 | public class JsonUtil {
12 |
13 | private static final ObjectMapper objectMapper = new ObjectMapper();
14 |
15 | public static Object toObject(String jsonInString) {
16 | try {
17 | return objectMapper.readValue(jsonInString, Object.class);
18 | } catch (IOException e) {
19 | e.printStackTrace();
20 | return null;
21 | }
22 | }
23 |
24 | public static String toString(Object obj) {
25 | try {
26 | return objectMapper.writeValueAsString(obj);
27 | } catch (IOException e) {
28 | e.printStackTrace();
29 | return "";
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/service/SysAuthService.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.service;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 | import com.dqv5.soccer.common.Pageable;
5 | import com.dqv5.soccer.pojo.SysAuth;
6 | import com.dqv5.soccer.common.TreeNode;
7 | import com.dqv5.soccer.pojo.SysAuthFolder;
8 | import com.dqv5.soccer.table.SysAuthTable;
9 | import com.github.pagehelper.PageInfo;
10 |
11 | import java.util.List;
12 |
13 | /**
14 | * @author duqian
15 | * @date 2022/7/17
16 | */
17 |
18 | public interface SysAuthService {
19 | List findAuthTree();
20 |
21 | PageInfo queryListForPage(JSONObject param, Pageable pageable);
22 |
23 | List findFolders();
24 |
25 | SysAuthTable findOne(String id);
26 |
27 | void insert(SysAuthTable sysUser);
28 |
29 | void update(SysAuthTable sysUser);
30 |
31 | void deleteById(String id);
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/.stylelintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "stylelint-config-standard",
4 | "stylelint-config-rational-order"
5 | ],
6 | "customSyntax": "postcss-less",
7 | "plugins": [
8 | "stylelint-order",
9 | "stylelint-declaration-block-no-ignored-properties"
10 | ],
11 | "rules": {
12 | "function-no-unknown": null,
13 | "no-descending-specificity": null,
14 | "plugin/declaration-block-no-ignored-properties": true,
15 | "selector-type-no-unknown": [
16 | true,
17 | {
18 | "ignoreTypes": [
19 | "/^g2-/",
20 | "/^nz-/",
21 | "/^app-/"
22 | ]
23 | }
24 | ],
25 | "selector-pseudo-element-no-unknown": [
26 | true,
27 | {
28 | "ignorePseudoElements": [
29 | "ng-deep"
30 | ]
31 | }
32 | ],
33 | "import-notation": "string"
34 | },
35 | "ignoreFiles": [
36 | "src/assets/**/*"
37 | ]
38 | }
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/passport/lock/lock.component.html:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/config/ResourceHandlerConfig.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.config;
2 |
3 | import org.springframework.context.annotation.Configuration;
4 | import org.springframework.http.CacheControl;
5 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
7 |
8 | import java.time.Duration;
9 |
10 | @Configuration
11 | public class ResourceHandlerConfig implements WebMvcConfigurer {
12 |
13 | @Override
14 | public void addResourceHandlers(ResourceHandlerRegistry registry) {
15 | CacheControl cacheControl = CacheControl.maxAge(Duration.ofDays(365)).cachePublic();
16 | registry.addResourceHandler("/web/**").addResourceLocations("classpath:/static/web/").setCacheControl(cacheControl);
17 | registry.addResourceHandler("/swagger-ui/").addResourceLocations("classpath:/META-INF/resources/");
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/layout/basic/widgets/clear-storage.component.ts:
--------------------------------------------------------------------------------
1 | import { ChangeDetectionStrategy, Component, HostListener } from '@angular/core';
2 | import { NzMessageService } from 'ng-zorro-antd/message';
3 | import { NzModalService } from 'ng-zorro-antd/modal';
4 |
5 | @Component({
6 | selector: 'header-clear-storage',
7 | template: `
8 |
9 | 清理本地缓存
10 | `,
11 | host: {
12 | '[class.flex-1]': 'true'
13 | },
14 | changeDetection: ChangeDetectionStrategy.OnPush
15 | })
16 | export class HeaderClearStorageComponent {
17 | constructor(private modalSrv: NzModalService, private messageSrv: NzMessageService) {}
18 |
19 | @HostListener('click')
20 | _click(): void {
21 | this.modalSrv.confirm({
22 | nzTitle: 'Make sure clear all local storage?',
23 | nzOnOk: () => {
24 | localStorage.clear();
25 | this.messageSrv.success('Clear Finished!');
26 | }
27 | });
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/passport/register/register.component.less:
--------------------------------------------------------------------------------
1 | @import '@delon/theme/index';
2 |
3 | :host {
4 | display: block;
5 | width: 368px;
6 | margin: 0 auto;
7 |
8 | ::ng-deep {
9 | h3 {
10 | margin-bottom: 20px;
11 | font-size: 16px;
12 | }
13 |
14 | .submit {
15 | width: 50%;
16 | }
17 |
18 | .login {
19 | float: right;
20 | line-height: @btn-height-lg;
21 | }
22 | }
23 | }
24 |
25 | ::ng-deep {
26 | .register-password-cdk {
27 | .success,
28 | .warning,
29 | .error {
30 | transition: color 0.3s;
31 | }
32 |
33 | .success {
34 | color: @success-color;
35 | }
36 |
37 | .warning {
38 | color: @warning-color;
39 | }
40 |
41 | .error {
42 | color: @error-color;
43 | }
44 |
45 | .progress-pass > .progress {
46 | .ant-progress-bg {
47 | background-color: @warning-color;
48 | }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/layout/passport/passport.component.ts:
--------------------------------------------------------------------------------
1 | import {Component, Inject, OnInit} from '@angular/core';
2 | import {DA_SERVICE_TOKEN, ITokenService} from '@delon/auth';
3 | import {SettingsService} from "@delon/theme";
4 |
5 | @Component({
6 | selector: 'layout-passport',
7 | templateUrl: './passport.component.html',
8 | styleUrls: ['./passport.component.less']
9 | })
10 | export class LayoutPassportComponent implements OnInit {
11 | app: any = {};
12 | links = [
13 | {
14 | title: '帮助',
15 | href: ''
16 | },
17 | {
18 | title: '隐私',
19 | href: ''
20 | },
21 | {
22 | title: '条款',
23 | href: ''
24 | }
25 | ];
26 |
27 | constructor(@Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService,
28 | private settingsService: SettingsService) {
29 | }
30 |
31 | ngOnInit(): void {
32 | this.app = this.settingsService.getApp();
33 | this.tokenService.clear();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/structmapper/SysMenuStructMapper.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.structmapper;
2 |
3 | import com.dqv5.soccer.pojo.SysMenu;
4 | import com.dqv5.soccer.table.SysMenuTable;
5 | import org.mapstruct.Mapper;
6 | import org.mapstruct.Mapping;
7 | import org.mapstruct.factory.Mappers;
8 |
9 | /**
10 | * @author duqian
11 | * @date 2025/8/23
12 | */
13 | @Mapper
14 | public interface SysMenuStructMapper {
15 | SysMenuStructMapper INSTANCE = Mappers.getMapper(SysMenuStructMapper.class);
16 |
17 | SysMenu entityToPojo(SysMenuTable entity);
18 |
19 | SysMenuTable pojoToEntity(SysMenu pojo);
20 |
21 | default Boolean map(Integer value) {
22 | if (value == null) {
23 | return null;
24 | }
25 | return value == 1;
26 | }
27 |
28 | default Integer map(Boolean value) {
29 | if (value == null) {
30 | return null;
31 | }
32 | return value ? 1 : 0;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/table/SysFileTable.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.table;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 |
9 | import java.io.Serializable;
10 |
11 | /**
12 | * @author duq
13 | * @date 2024/2/15
14 | */
15 | @Data
16 | @EqualsAndHashCode(callSuper = true)
17 | @TableName("sys_file")
18 | public class SysFileTable extends AbstractBaseTable implements Serializable {
19 | private static final long serialVersionUID = 1L;
20 |
21 | @TableId(type = IdType.ASSIGN_UUID)
22 | private String fileId;
23 | private String fileName;
24 | private String fileType;
25 | private Long fileSize;
26 | private Integer duration;
27 | private String sha256;
28 | private Integer storeType;
29 | private String storeInfo;
30 | private String remark;
31 | }
32 |
--------------------------------------------------------------------------------
/soccer-server/src/main/resources/mapper/sqlMap/SysMenuMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
12 |
21 |
22 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/shared/utils/treeUtils.ts:
--------------------------------------------------------------------------------
1 | import {NzTreeComponent} from "ng-zorro-antd/tree";
2 | import {NzTreeNode} from "ng-zorro-antd/core/tree/nz-tree-base-node";
3 |
4 | /**
5 | * 获取选中的树节点,包括完全选中节点(及其下级节点)、半选中节点,
6 | *
7 | */
8 | export function getCheckedNodes(treeComponent: NzTreeComponent): NzTreeNode[] {
9 | const halfCheckedNodeList = treeComponent.getHalfCheckedNodeList();
10 | const checkedNodeList = treeComponent.getCheckedNodeList();
11 | const checkedNodeListWithChildren = getAllWithChildren(checkedNodeList);
12 | return [...halfCheckedNodeList, ...checkedNodeListWithChildren];
13 | }
14 |
15 |
16 | function getAllWithChildren(nodeList: NzTreeNode[]): NzTreeNode[] {
17 | let list: NzTreeNode[] = [];
18 | nodeList.forEach(node => {
19 | list.push(node);
20 | if (node.children && node.children.length > 0) {
21 | const childrenList = getAllWithChildren(node.children);
22 | childrenList.forEach(child => list.push(child));
23 | }
24 | });
25 | return list;
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/web/PageController.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.web;
2 |
3 | import io.swagger.v3.oas.annotations.Operation;
4 | import io.swagger.v3.oas.annotations.tags.Tag;
5 | import jakarta.servlet.http.HttpServletRequest;
6 | import lombok.extern.slf4j.Slf4j;
7 | import org.springframework.stereotype.Controller;
8 | import org.springframework.web.bind.annotation.GetMapping;
9 |
10 | /**
11 | * @author admin
12 | * @date 2022/7/17
13 | */
14 | @Slf4j
15 | @Controller
16 | @Tag(name = "页面导航")
17 | public class PageController {
18 |
19 | @GetMapping("/")
20 | @Operation(summary = "首页")
21 | public String index(HttpServletRequest request) {
22 | String url = request.getRequestURI();
23 | url = "redirect:" + url + (url.endsWith("/") ? "" : "/") + "web/";
24 | log.info("url:{}", url);
25 | return url;
26 | }
27 |
28 | @GetMapping("/web/")
29 | @Operation(summary = "web端页面")
30 | public String web() {
31 | return "web/index";
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/pojo/SysRole.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.pojo;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import io.swagger.v3.oas.annotations.media.SchemaProperty;
5 | import lombok.*;
6 |
7 | import java.io.Serializable;
8 | import java.util.ArrayList;
9 | import java.util.List;
10 |
11 | /**
12 | * @author duqian
13 | * @date 2023/12/12
14 | */
15 | @EqualsAndHashCode(callSuper = true)
16 | @Data
17 | @NoArgsConstructor
18 | @AllArgsConstructor
19 | @Builder
20 | @Schema(name = "系统角色")
21 | public class SysRole extends AbstractBaseVO implements Serializable {
22 | @SchemaProperty(name = "角色id")
23 | private String roleId;
24 | @SchemaProperty(name = "角色标识")
25 | private String roleValue;
26 | @SchemaProperty(name = "角色名称")
27 | private String roleName;
28 | @SchemaProperty(name = "关联的菜单")
29 | private List menus = new ArrayList<>();
30 | @SchemaProperty(name = "关联的权限")
31 | private List auths = new ArrayList<>();
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/soccer-server/src/main/resources/mapper/sqlMap/SysUserMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
22 |
23 |
--------------------------------------------------------------------------------
/soccer-server/src/main/resources/mapper/sqlMap/SysRoleMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
16 |
22 |
23 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/passport/callback.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { ActivatedRoute } from '@angular/router';
3 | import { SocialService } from '@delon/auth';
4 | import { SettingsService } from '@delon/theme';
5 |
6 | @Component({
7 | selector: 'app-callback',
8 | template: ``,
9 | providers: [SocialService]
10 | })
11 | export class CallbackComponent implements OnInit {
12 | type = '';
13 |
14 | constructor(private socialService: SocialService, private settingsSrv: SettingsService, private route: ActivatedRoute) {}
15 |
16 | ngOnInit(): void {
17 | this.type = this.route.snapshot.params['type'];
18 | this.mockModel();
19 | }
20 |
21 | private mockModel(): void {
22 | const info = {
23 | token: '123456789',
24 | name: 'cipchk',
25 | email: `${this.type}@${this.type}.com`,
26 | id: 10000,
27 | time: +new Date()
28 | };
29 | this.settingsSrv.setUser({
30 | ...this.settingsSrv.user,
31 | ...info
32 | });
33 | this.socialService.callback(info);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018-2024 杜谦
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/routes.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule, Type } from '@angular/core';
2 | import { SharedModule } from '@shared';
3 |
4 | // dashboard pages
5 | import { DashboardComponent } from './dashboard/dashboard.component';
6 | // single pages
7 | import { CallbackComponent } from './passport/callback.component';
8 | import { UserLockComponent } from './passport/lock/lock.component';
9 | // passport pages
10 | import { UserLoginComponent } from './passport/login/login.component';
11 | import { UserRegisterResultComponent } from './passport/register-result/register-result.component';
12 | import { UserRegisterComponent } from './passport/register/register.component';
13 | import { RouteRoutingModule } from './routes-routing.module';
14 |
15 | const COMPONENTS: Array> = [
16 | DashboardComponent,
17 | // passport pages
18 | UserLoginComponent,
19 | UserRegisterComponent,
20 | UserRegisterResultComponent,
21 | // single pages
22 | CallbackComponent,
23 | UserLockComponent
24 | ];
25 |
26 | @NgModule({
27 | imports: [SharedModule, RouteRoutingModule],
28 | declarations: COMPONENTS
29 | })
30 | export class RoutesModule {}
31 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018-present 卡色
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // This file can be replaced during build by using the `fileReplacements` array.
2 | // `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`.
3 | // The list of file replacements can be found in `angular.json`.
4 |
5 | import { provideMockConfig, mockInterceptor } from '@delon/mock';
6 | import { Environment } from '@delon/theme';
7 |
8 | import * as MOCKDATA from '../../_mock';
9 |
10 | export const environment = {
11 | production: false,
12 | useHash: true,
13 | api: {
14 | baseUrl: '',
15 | refreshTokenEnabled: true,
16 | refreshTokenType: 'auth-refresh'
17 | },
18 | providers: [provideMockConfig({ data: MOCKDATA })],
19 | interceptorFns: [mockInterceptor],
20 | modules: []
21 | } as Environment;
22 |
23 | /*
24 | * In development mode, to ignore zone related error stack frames such as
25 | * `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can
26 | * import the following file, but please comment it out in production mode
27 | * because it will have performance impact when throw error
28 | */
29 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
30 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/exception/trigger.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Inject } from '@angular/core';
2 | import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth';
3 | import { _HttpClient } from '@delon/theme';
4 |
5 | @Component({
6 | selector: 'exception-trigger',
7 | template: `
8 |
9 |
10 |
11 |
12 |
13 |
14 | `
15 | })
16 | export class ExceptionTriggerComponent {
17 | types = [401, 403, 404, 500];
18 |
19 | constructor(private http: _HttpClient, @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService) {}
20 |
21 | go(type: number): void {
22 | this.http.get(`/api/${type}`).subscribe();
23 | }
24 |
25 | refresh(): void {
26 | this.tokenService.set({ token: 'invalid-token' });
27 | // 必须提供一个后端地址,无法通过 Mock 来模拟
28 | this.http.post(`https://localhost:5001/auth`).subscribe(
29 | res => console.warn('成功', res),
30 | err => {
31 | console.log('最后结果失败', err);
32 | }
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/pojo/SysUser.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.pojo;
2 |
3 | import com.fasterxml.jackson.annotation.JsonProperty;
4 | import io.swagger.v3.oas.annotations.media.Schema;
5 | import lombok.*;
6 |
7 | import java.io.Serializable;
8 | import java.util.ArrayList;
9 | import java.util.Date;
10 | import java.util.List;
11 |
12 | /**
13 | * @author duqian
14 | * @date 2023/12/12
15 | */
16 | @EqualsAndHashCode(callSuper = true)
17 | @Data
18 | @NoArgsConstructor
19 | @AllArgsConstructor
20 | @Builder
21 | @Schema(name = "系统用户")
22 | public class SysUser extends AbstractBaseVO implements Serializable {
23 | private static final long serialVersionUID = 1L;
24 | private String userId;
25 | private String account;
26 | @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
27 | private String password;
28 | private String nickName;
29 | private String avatarUrl;
30 | private Integer gender;
31 | private String phone;
32 | private String email;
33 | private Integer status;
34 | private String openid;
35 | private Date lastLoginTime;
36 | private Date lastPasswordResetTime;
37 |
38 | private List depts = new ArrayList<>();
39 |
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/table/SysUserTable.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.table;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
6 | import com.fasterxml.jackson.annotation.JsonProperty;
7 | import lombok.Data;
8 | import lombok.EqualsAndHashCode;
9 |
10 | import java.io.Serializable;
11 | import java.util.Date;
12 |
13 | /**
14 | * @author duq
15 | * @date 2020/7/31
16 | */
17 | @Data
18 | @EqualsAndHashCode(callSuper = true)
19 | @TableName("sys_user")
20 | public class SysUserTable extends AbstractBaseTable implements Serializable {
21 | private static final long serialVersionUID = 1L;
22 | @TableId(type = IdType.ASSIGN_UUID)
23 | private String userId;
24 | private String account;
25 | @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
26 | private String password;
27 | private String nickName;
28 | private String avatarUrl;
29 | private Integer gender;
30 | private String phone;
31 | private String email;
32 | private Integer status;
33 | private String openid;
34 | private Date lastLoginTime;
35 | private Date lastPasswordResetTime;
36 | }
37 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/sys/sys-routing.module.ts:
--------------------------------------------------------------------------------
1 | import {NgModule} from '@angular/core';
2 | import {RouterModule, Routes} from '@angular/router';
3 | import {SysLogComponent} from './log/log.component';
4 | import {SysUserComponent} from './user/user.component';
5 | import {SysRoleComponent} from './role/role.component';
6 | import {SysMenuComponent} from './menu/menu.component';
7 | import {SysAuthComponent} from "./auth/auth.component";
8 | import {SysConfigComponent} from "./config/config.component";
9 | import {SysDeptComponent} from "./dept/dept.component";
10 | import {SysProfileComponent} from "./profile/profile.component";
11 |
12 | const routes: Routes = [
13 | {path: 'user', component: SysUserComponent},
14 | {path: 'role', component: SysRoleComponent},
15 | {path: 'menu', component: SysMenuComponent},
16 | {path: 'auth', component: SysAuthComponent},
17 | {path: 'dept', component: SysDeptComponent},
18 | {path: 'config', component: SysConfigComponent},
19 | {path: 'log', component: SysLogComponent},
20 | {path: 'profile', component: SysProfileComponent},
21 | ];
22 |
23 | @NgModule({
24 | imports: [RouterModule.forChild(routes)],
25 | exports: [RouterModule]
26 | })
27 | export class SysRoutingModule {
28 | }
29 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "outDir": "./dist/out-tsc",
6 | "forceConsistentCasingInFileNames": true,
7 | "strict": true,
8 | "noImplicitOverride": true,
9 | "noPropertyAccessFromIndexSignature": true,
10 | "noImplicitReturns": true,
11 | "noFallthroughCasesInSwitch": true,
12 | "sourceMap": true,
13 | "declaration": false,
14 | "downlevelIteration": true,
15 | "experimentalDecorators": true,
16 | "moduleResolution": "node",
17 | "importHelpers": true,
18 | "target": "ES2022",
19 | "module": "es2020",
20 | "lib": [
21 | "es2020",
22 | "dom"
23 | ],
24 | "paths": {
25 | "@shared": [
26 | "src/app/shared/index"
27 | ],
28 | "@core": [
29 | "src/app/core/index"
30 | ],
31 | "@env/*": [
32 | "src/environments/*"
33 | ]
34 | },
35 | "allowSyntheticDefaultImports": true,
36 | "useDefineForClassFields": false
37 | },
38 | "angularCompilerOptions": {
39 | "enableI18nLegacyMessageIdFormat": false,
40 | "strictInjectionParameters": true,
41 | "strictInputAccessModifiers": true,
42 | "strictTemplates": true
43 | }
44 | }
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/common/auth-value.ts:
--------------------------------------------------------------------------------
1 | export class AuthValue {
2 | static SYS_USER_QUERY = "sys_user_query";
3 | static SYS_USER_INSERT = "sys_user_insert";
4 | static SYS_USER_UPDATE = "sys_user_update";
5 | static SYS_USER_DELETE = "sys_user_delete";
6 |
7 | static SYS_ROLE_QUERY = "sys_role_query";
8 | static SYS_ROLE_INSERT = "sys_role_insert";
9 | static SYS_ROLE_UPDATE = "sys_role_update";
10 | static SYS_ROLE_DELETE = "sys_role_delete";
11 |
12 | static SYS_MENU_QUERY = "sys_menu_query";
13 | static SYS_MENU_INSERT = "sys_menu_insert";
14 | static SYS_MENU_UPDATE = "sys_menu_update";
15 | static SYS_MENU_DELETE = "sys_menu_delete";
16 |
17 | static SYS_AUTH_QUERY = "sys_auth_query";
18 | static SYS_AUTH_INSERT = "sys_auth_insert";
19 | static SYS_AUTH_UPDATE = "sys_auth_update";
20 | static SYS_AUTH_DELETE = "sys_auth_delete";
21 |
22 | static SYS_DEPT_QUERY = "sys_dept_query";
23 | static SYS_DEPT_INSERT = "sys_dept_insert";
24 | static SYS_DEPT_UPDATE = "sys_dept_update";
25 | static SYS_DEPT_DELETE = "sys_dept_delete";
26 |
27 | static SYS_CONFIG_QUERY = "sys_config_query";
28 | static SYS_CONFIG_SET = "sys_config_set";
29 |
30 | static SYS_LOG_QUERY = "sys_log_query";
31 |
32 | static SYS_RE_INIT_DATA = "sys_re_init_data";
33 | }
34 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/passport/login/login.component.less:
--------------------------------------------------------------------------------
1 | @import '@delon/theme/index';
2 |
3 | :host {
4 | display: block;
5 | width: 368px;
6 | margin: 0 auto;
7 |
8 | ::ng-deep {
9 | .ant-tabs .ant-tabs-bar {
10 | margin-bottom: 24px;
11 | text-align: center;
12 | border-bottom: 0;
13 | }
14 |
15 | .ant-tabs-tab {
16 | font-size: 16px;
17 | line-height: 24px;
18 | }
19 |
20 | .ant-input-affix-wrapper .ant-input:not(:first-child) {
21 | padding-left: 4px;
22 | }
23 |
24 | .icon {
25 | margin-left: 16px;
26 | color: rgb(0 0 0 / 20%);
27 | font-size: 24px;
28 | vertical-align: middle;
29 | cursor: pointer;
30 | transition: color 0.3s;
31 |
32 | &:hover {
33 | color: @primary-color;
34 | }
35 | }
36 |
37 | .other {
38 | margin-top: 24px;
39 | line-height: 22px;
40 | text-align: left;
41 |
42 | nz-tooltip {
43 | vertical-align: middle;
44 | }
45 |
46 | .register {
47 | float: right;
48 | }
49 | }
50 | }
51 | }
52 |
53 | [data-theme='dark'] {
54 | :host ::ng-deep {
55 | .icon {
56 | color: rgb(255 255 255 / 20%);
57 |
58 | &:hover {
59 | color: #fff;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/soccer-server/src/test/java/TestMapStruct.java:
--------------------------------------------------------------------------------
1 | import com.dqv5.soccer.pojo.SysMenu;
2 | import com.dqv5.soccer.pojo.SysUser;
3 | import com.dqv5.soccer.structmapper.SysMenuStructMapper;
4 | import com.dqv5.soccer.structmapper.SysUserStructMapper;
5 | import com.dqv5.soccer.table.SysMenuTable;
6 | import com.dqv5.soccer.table.SysUserTable;
7 | import org.junit.jupiter.api.Test;
8 |
9 | import java.util.UUID;
10 |
11 | /**
12 | * @author duqian
13 | * @date 2025/8/23
14 | */
15 | public class TestMapStruct {
16 | @Test
17 | public void testUser() {
18 | SysUserTable table = new SysUserTable();
19 | table.setUserId(UUID.randomUUID().toString());
20 | table.setNickName("test");
21 | table.setPassword("123456");
22 | table.setGender(1);
23 | table.setEmail("test123@demo.edu.cn");
24 | table.setPhone("13800138000");
25 | table.setStatus(1);
26 | SysUser pojo = SysUserStructMapper.INSTANCE.entityToPojo(table);
27 | System.out.println(pojo);
28 | }
29 |
30 | @Test
31 | public void testMenu() {
32 | SysMenuTable table = new SysMenuTable();
33 | table.setHide(0);
34 | table.setHideChildren(1);
35 | SysMenu pojo = SysMenuStructMapper.INSTANCE.entityToPojo(table);
36 | System.out.println(pojo);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/soccer-server/src/main/java/com/dqv5/soccer/table/SysLogTable.java:
--------------------------------------------------------------------------------
1 | package com.dqv5.soccer.table;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.baomidou.mybatisplus.annotation.TableName;
6 | import lombok.AllArgsConstructor;
7 | import lombok.Builder;
8 | import lombok.Data;
9 | import lombok.NoArgsConstructor;
10 |
11 | import java.io.Serializable;
12 | import java.util.Date;
13 |
14 | /**
15 | * 系统日志
16 | *
17 | * @author admin
18 | * @date 2022/7/17
19 | */
20 | @Data
21 | @TableName("sys_log")
22 | @Builder
23 | @NoArgsConstructor
24 | @AllArgsConstructor
25 | public class SysLogTable implements Serializable {
26 | private static final long serialVersionUID = 1L;
27 | @TableId(type = IdType.ASSIGN_UUID)
28 | private String logId;
29 | private String userId;
30 | private String username;
31 | private String nickName;
32 | private String ip;
33 | private String address;
34 | private String className;
35 | private String methodName;
36 | private String methodDesc;
37 | private String args;
38 | private String ua;
39 | private String requestUrl;
40 | private String requestType;
41 | private Integer status;
42 | private String errorInfo;
43 | private Long runTime;
44 | private Date createdDate;
45 | }
46 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/passport/lock/lock.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Inject } from '@angular/core';
2 | import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
3 | import { Router } from '@angular/router';
4 | import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth';
5 | import { SettingsService, User } from '@delon/theme';
6 |
7 | @Component({
8 | selector: 'passport-lock',
9 | templateUrl: './lock.component.html',
10 | styleUrls: ['./lock.component.less']
11 | })
12 | export class UserLockComponent {
13 | f: UntypedFormGroup;
14 |
15 | get user(): User {
16 | return this.settings.user;
17 | }
18 |
19 | constructor(
20 | fb: UntypedFormBuilder,
21 | @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService,
22 | private settings: SettingsService,
23 | private router: Router
24 | ) {
25 | this.f = fb.group({
26 | password: [null, Validators.required]
27 | });
28 | }
29 |
30 | submit(): void {
31 | for (const i in this.f.controls) {
32 | this.f.controls[i].markAsDirty();
33 | this.f.controls[i].updateValueAndValidity();
34 | }
35 | if (this.f.valid) {
36 | console.log('Valid!');
37 | console.log(this.f.value);
38 | this.tokenService.set({
39 | token: '123'
40 | });
41 | this.router.navigate(['dashboard']);
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/soccer-angular-webapp/src/app/routes/sys/log/log.component.ts:
--------------------------------------------------------------------------------
1 | import {Component, OnInit, ViewChild} from '@angular/core';
2 | import {STColumn, STComponent} from '@delon/abc/st';
3 | import {SFSchema} from '@delon/form';
4 | import {ModalHelper, _HttpClient} from '@delon/theme';
5 |
6 | @Component({
7 | selector: 'app-sys-log',
8 | templateUrl: './log.component.html',
9 | })
10 | export class SysLogComponent implements OnInit {
11 | url = `/api/log/list`;
12 | searchSchema: SFSchema = {
13 | properties: {
14 | username: {
15 | type: 'string',
16 | title: '账号'
17 | },
18 | nickName: {
19 | type: 'string',
20 | title: '昵称'
21 | }
22 | }
23 | };
24 | @ViewChild('st') private readonly st!: STComponent;
25 | columns: STColumn[] = [
26 | {title: '编号', type: 'no'},
27 | {title: '账号', index: 'username'},
28 | {title: '昵称', index: 'nickName'},
29 | {title: '请求地址', index: 'requestUrl'},
30 | {title: '耗时', type: 'number', index: 'runTime'},
31 | {title: '时间', type: 'date', index: 'createdDate'},
32 | ];
33 |
34 | constructor(private http: _HttpClient, private modal: ModalHelper) {
35 | }
36 |
37 | ngOnInit(): void {
38 | }
39 |
40 | add(): void {
41 | // this.modal
42 | // .createStatic(FormEditComponent, { i: { id: 0 } })
43 | // .subscribe(() => this.st.reload());
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/soccer-server/src/test/java/TestCache.java:
--------------------------------------------------------------------------------
1 | import com.github.benmanes.caffeine.cache.Cache;
2 | import com.github.benmanes.caffeine.cache.Caffeine;
3 | import org.junit.jupiter.api.Test;
4 |
5 | import java.util.concurrent.TimeUnit;
6 |
7 | /**
8 | * @author duqian
9 | * @date 2025/8/22
10 | */
11 | public class TestCache {
12 | Cache