init full backend repo with src + deploy config

This commit is contained in:
2025-07-15 11:37:42 +08:00
commit 8dc1824603
24 changed files with 825 additions and 0 deletions

33
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,33 @@
pipeline {
agent any
environment {
SSH_CREDENTIALS_ID = 'alex-ssh-key'
REMOTE_HOST = '117.72.202.202'
REMOTE_USER = 'alex'
REMOTE_DIR = '/home/alex/alex-api'
}
stages {
stage('Build') {
steps {
sh 'mvn clean package -DskipTests'
}
}
stage('Deploy') {
steps {
sshagent([env.SSH_CREDENTIALS_ID]) {
sh """
scp target/alex-api-0.0.1-SNAPSHOT.jar ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}/app/
ssh ${REMOTE_USER}@${REMOTE_HOST} '
cd ${REMOTE_DIR} &&
docker compose down &&
docker compose up -d --build
'
"""
}
}
}
}
}

12
app/Dockerfile Executable file
View File

@ -0,0 +1,12 @@
# 使用轻量级 OpenJDK 运行环境作为基础镜像
FROM openjdk:8-jdk
# 作者信息(可选)
LABEL maintainer="2604434353@qq.com"
# 创建工作目录
WORKDIR /app
# 复制 jar 包到容器中
COPY alex-api-0.0.1-SNAPSHOT.jar app.jar
# 开放容器端口
EXPOSE 8888
# 启动命令
ENTRYPOINT ["java", "-jar", "app.jar"]

BIN
app/alex-api-0.0.1-SNAPSHOT.jar Executable file

Binary file not shown.

15
bin/post-steps.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
PORT=8888
JAR_PATH="/home/alex/alex-api/app/alex-api-0.0.1-SNAPSHOT.jar"
LOG_PATH="/home/alex/alex-api/logs/alex-api.log"
# 检测端口是否被占用
if netstat -tuln | grep -q ":$PORT"; then
echo "Port $PORT is already in use. Not starting application."
exit 0
else
echo "Port $PORT is free. Starting application..."
nohup java -jar "$JAR_PATH" > "$LOG_PATH" 2>&1 &
echo "Application started with PID $!"
fi

13
bin/pre-steps.sh Executable file
View File

@ -0,0 +1,13 @@
#!/bin/bash
pid=$(ps -ef | grep -w java | grep "alex-api-0.0.1-SNAPSHOT.jar" | grep -v grep | awk '{print $2}')
echo "Found pid: $pid"
if [ -z "$pid" ]; then
echo "Java application not running."
else
sudo kill -9 $pid
echo "Java application (pid: $pid) stopping..."
sleep 2
fi

70
docker-compose.yml Executable file
View File

@ -0,0 +1,70 @@
name: alex-api-docker
services:
mysql:
image: mysql:8.0
container_name: mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: ALEXzcz123456
MYSQL_DATABASE: test_alex
MYSQL_USER: alex
MYSQL_PASSWORD: ALEXzcz123456
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
networks:
- alex-bridge-network
redis:
image: redis:6
container_name: redis
command: redis-server --requirepass "ALEXzcz123456"
ports:
- "6379:6379"
volumes:
- redis-data:/data
networks:
- alex-bridge-network
alex-api:
build:
context: /home/alex/alex-api/app
dockerfile: Dockerfile
image: alex-api-image
container_name: alex-api
restart: always
depends_on:
- mysql
- redis
ports:
- "8888:8888"
networks:
- alex-bridge-network
nginx:
image: nginx:latest
container_name: nginx
restart: always
ports:
- "80:80"
volumes:
- /etc/nginx/conf.d/alex-ui.conf:/etc/nginx/conf.d/alex-ui.conf
- /var/www/alex-ui:/var/www/alex-ui
- /var/log/nginx:/var/log/nginx
depends_on:
- alex-api
networks:
- alex-bridge-network
# 声明命名数据卷
volumes:
mysql-data:
external: true # 使用已有的 mysql-data 卷,不创建新卷
redis-data:
external: true
# 创建自定义网络
networks:
alex-bridge-network:
driver: bridge

45
logs/alex-api.log Normal file
View File

@ -0,0 +1,45 @@
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.6.13)
2025-07-15 09:34:11.450 INFO 2719370 --- [ main] com.ctgu.alexapi.AlexApiApplication : Starting AlexApiApplication using Java 17.0.15 on server with PID 2719370 (/home/alex/alex-api/app/alex-api-0.0.1-SNAPSHOT.jar started by alex in /home/alex)
2025-07-15 09:34:11.452 INFO 2719370 --- [ main] com.ctgu.alexapi.AlexApiApplication : The following 1 profile is active: "dev"
2025-07-15 09:34:12.544 INFO 2719370 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
2025-07-15 09:34:12.547 INFO 2719370 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2025-07-15 09:34:12.590 INFO 2719370 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 20 ms. Found 0 Redis repository interfaces.
2025-07-15 09:34:13.738 INFO 2719370 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8888 (http)
2025-07-15 09:34:13.770 INFO 2719370 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2025-07-15 09:34:13.770 INFO 2719370 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.68]
2025-07-15 09:34:13.950 INFO 2719370 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2025-07-15 09:34:13.950 INFO 2719370 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2362 ms
_ _ |_ _ _|_. ___ _ | _
| | |\/|_)(_| | |_\ |_)||_|_\
/ |
3.5.1
2025-07-15 09:34:16.185 INFO 2719370 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8888 (http) with context path ''
2025-07-15 09:34:16.204 INFO 2719370 --- [ main] com.ctgu.alexapi.AlexApiApplication : Started AlexApiApplication in 5.761 seconds (JVM running for 6.61)
2025-07-15 09:45:02.685 INFO 2719370 --- [0.0-8888-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2025-07-15 09:45:02.686 INFO 2719370 --- [0.0-8888-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2025-07-15 09:45:02.687 INFO 2719370 --- [0.0-8888-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
2025-07-15 09:45:02.907 INFO 2719370 --- [0.0-8888-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2025-07-15 09:45:03.268 INFO 2719370 --- [0.0-8888-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2025-07-15 10:55:24.202 INFO 2719370 --- [0.0-8888-exec-3] o.apache.coyote.http11.Http11Processor : Error parsing HTTP request header
Note: further occurrences of HTTP request parsing errors will be logged at DEBUG level.
java.lang.IllegalArgumentException: Invalid character found in method name [0x030x000x00/*0xe00x000x000x000x000x00Cookie: ]. HTTP method names must be tokens
at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:419) ~[tomcat-embed-core-9.0.68.jar!/:na]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:271) ~[tomcat-embed-core-9.0.68.jar!/:na]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.68.jar!/:na]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.68.jar!/:na]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789) ~[tomcat-embed-core-9.0.68.jar!/:na]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.68.jar!/:na]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.68.jar!/:na]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.68.jar!/:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.68.jar!/:na]
at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]

133
pom.xml Normal file
View File

@ -0,0 +1,133 @@
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ctgu</groupId>
<artifactId>alex-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>alex-api</name>
<description>alex-api</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.6.13</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.19.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>2.19.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.7.6</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.ctgu.alexapi.AlexApiApplication</mainClass>
<!-- <skip>true</skip>-->
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,15 @@
package com.ctgu.alexapi;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.ctgu.alexapi.mapper")
public class AlexApiApplication {
public static void main(String[] args) {
SpringApplication.run(AlexApiApplication.class, args);
}
}

View File

@ -0,0 +1,42 @@
package com.ctgu.alexapi.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisConnectionFactory redisConnectionFactory(RedisProperties redisProperties) {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
config.setHostName(redisProperties.getHost());
config.setPort(redisProperties.getPort());
config.setPassword(redisProperties.getPassword());
config.setDatabase(0);
return new LettuceConnectionFactory(config);
}
@Bean(name = "redisTemplate")
public RedisTemplate<String, Object> redisTemplate(
@Qualifier("redisConnectionFactory")RedisConnectionFactory redisConnectionFactory
) {
// 创建 RedisTemplate 对象
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 设置默认的序列化器String 类型)
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
return redisTemplate;
}
}

View File

@ -0,0 +1,36 @@
package com.ctgu.alexapi.controller;
import com.ctgu.alexapi.service.UsersService;
import com.ctgu.alexapi.utils.ApiResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @ClassName UserController
* @Author Alex2
* @Date 2025/7/2 14:43
**/
@RestController
@RequestMapping("/api/users")
public class UsersController {
private final UsersService usersService;
@Autowired
public UsersController(UsersService usersService) {
this.usersService = usersService;
}
// http://localhost:8888/api/users/getAllUser?pageNum=1&pageSize=10
@GetMapping("/getAllUser")
public ApiResult getAllUser(
@RequestParam(value = "pageNum", defaultValue = "0", required = false) Integer pageNum,
@RequestParam(value = "pageSize", defaultValue = "10", required = false) Integer pageSize) {
return usersService.getAllUser(pageNum, pageSize);
}
// http://localhost:8888/api/users/1
@GetMapping("/{id}")
public ApiResult getUserById(@PathVariable("id") Integer id) {
return usersService.getUserById(id);
}
}

View File

@ -0,0 +1,37 @@
package com.ctgu.alexapi.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;
/**
*
* @TableName t_users
*/
@TableName(value ="t_users")
@Data
public class UsersEntity implements Serializable {
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 用户名
*/
@TableField(value = "username")
private String username;
/**
* 密码
*/
@TableField(value = "password")
private String password;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,18 @@
package com.ctgu.alexapi.mapper;
import com.ctgu.alexapi.entity.UsersEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author Alex2
* @description 针对表【t_users】的数据库操作Mapper
* @createDate 2025-07-02 14:37:56
* @Entity com.ctgu.alexapi.entity.UsersEntity
*/
public interface UsersMapper extends BaseMapper<UsersEntity> {
}

View File

@ -0,0 +1,17 @@
package com.ctgu.alexapi.service;
import com.ctgu.alexapi.entity.UsersEntity;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ctgu.alexapi.utils.ApiResult;
/**
* @author Alex2
* @description 针对表【t_users】的数据库操作Service
* @createDate 2025-07-02 14:37:56
*/
public interface UsersService extends IService<UsersEntity> {
ApiResult getAllUser(Integer pageNum, Integer pageSize);
ApiResult getUserById(Integer id);
}

View File

@ -0,0 +1,71 @@
package com.ctgu.alexapi.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctgu.alexapi.entity.UsersEntity;
import com.ctgu.alexapi.service.UsersService;
import com.ctgu.alexapi.mapper.UsersMapper;
import com.ctgu.alexapi.utils.ApiResult;
import com.ctgu.alexapi.utils.Tools;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author Alex2
* @description 针对表【t_users】的数据库操作Service实现
* @createDate 2025-07-02 14:37:56
*/
@Log4j2
@Service
public class UsersServiceImpl extends ServiceImpl<UsersMapper, UsersEntity>
implements UsersService{
private static final String TAG = UsersServiceImpl.class.getSimpleName();
@Autowired
private StringRedisTemplate redisTemplate;
private static final String USER_CACHE_PREFIX = "user:";
@Override
public ApiResult getAllUser(Integer pageNum, Integer pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<UsersEntity> list = query().list();
PageInfo<UsersEntity> pageInfo = new PageInfo<>(list, 5);
return Tools.pageHelperResult(list, pageInfo, TAG);
}
@Override
public ApiResult getUserById(Integer userId) {
String key = USER_CACHE_PREFIX + userId;
// 1. 先从 Redis 取缓存
String cachedUserJson = redisTemplate.opsForValue().get(key);
if (cachedUserJson != null) {
// 有缓存,反序列化后返回
UsersEntity cachedUser = new Gson().fromJson(cachedUserJson, UsersEntity.class);
log.debug("{}: 从缓存获取用户成功 = {}", TAG, cachedUser);
return ApiResult.success("获取用户成功(缓存)", cachedUser);
}
// 2. 缓存没命中,从数据库查
UsersEntity usersEntity = lambdaQuery().eq(UsersEntity::getId, userId).one();
if (usersEntity == null) {
log.error("{}: 用户 Id = {} 不存在", TAG, userId);
return ApiResult.error("用户不存在");
}
// 3. 查到后写入缓存设置过期时间比如10分钟
String userJson = new Gson().toJson(usersEntity);
redisTemplate.opsForValue().set(key, userJson, 10, TimeUnit.MINUTES);
log.debug("{}: 获取用户成功 = {}", TAG, usersEntity);
return ApiResult.success("获取用户成功", usersEntity);
}
}

View File

@ -0,0 +1,100 @@
package com.ctgu.alexapi.utils;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Optional;
@Data
@Builder
@NoArgsConstructor
public class ApiResult implements Serializable {
private static final long serialVersionUID = -8440958610795020343L;
public static final int CODE_SUCCESS = 200;
public static final int CODE_ERROR = 500;
public static final int CODE_WARNING = 501;
public static final int CODE_NOT_PERMISSION = 403;
public static final int CODE_NOE_LOGIN = 401;
public static final int CODE_INVALID_REQUEST = 400;
private int code;
private String msg;
private Object data;
// 构造方法
public ApiResult(int code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
// 静态构造方法
public static ApiResult success() {
return new ApiResult(CODE_SUCCESS, null, null);
}
public static ApiResult success(String msg) {
return new ApiResult(CODE_SUCCESS, msg, null);
}
public static ApiResult success(String msg, Object data) {
return new ApiResult(CODE_SUCCESS, msg, data);
}
public static ApiResult success(Object data) {
return new ApiResult(CODE_SUCCESS, null, data);
}
public static ApiResult error() {
return new ApiResult(CODE_ERROR, "出错了", null);
}
public static ApiResult error(String msg) {
return new ApiResult(CODE_ERROR, msg, null);
}
public static ApiResult error(String msg, Object data) {
return new ApiResult(CODE_ERROR, msg, data);
}
public static ApiResult notLogin() {
return new ApiResult(CODE_NOE_LOGIN, "未登录,请先进行登录", null);
}
public static ApiResult noPermissions() {
return new ApiResult(CODE_NOT_PERMISSION, "权限不足", null);
}
public static ApiResult build(int code, String msg) {
return new ApiResult(code, msg, null);
}
public static ApiResult getByBoolean(boolean b) {
return b ? success() : error();
}
public static ApiResult warning(String msg, Object data) {
return new ApiResult(CODE_WARNING, msg, data);
}
public static ApiResult warning(String msg) {
return new ApiResult(CODE_WARNING, msg, null);
}
public <T> Optional<T> getData(Class<T> clazz) {
return Optional.ofNullable(clazz.cast(data));
}
@Override
public String toString() {
return "ApiResult{" +
"code=" + code +
", msg='" + msg + '\'' +
", data=" + (data != null ? data.toString() : "null") +
'}';
}
}

View File

@ -0,0 +1,16 @@
package com.ctgu.alexapi.utils;
import lombok.Builder;
import lombok.Data;
import java.util.List;
@Data
@Builder
public class PageData<T> {
private Long totalNum; //总条数
private Integer totalPage; //总页数
private List<T> data; //数据
}

View File

@ -0,0 +1,46 @@
package com.ctgu.alexapi.utils;
import com.github.pagehelper.PageInfo;
import lombok.extern.log4j.Log4j2;
import java.util.Collections;
import java.util.List;
@Log4j2
public class Tools {
public static <T> ApiResult pageHelperResult(List<T> list, PageInfo<T> pageInfo, String TAG) {
if (list.isEmpty()) {
log.debug("{} : 获取列表为空 = {}", TAG, Collections.emptyList());
return ApiResult.success("获取列表为空", Collections.emptyList());
}
PageData.PageDataBuilder<T> builder = PageData.builder();
log.debug("{} : 获取列表成功 = {}", TAG, list);
return ApiResult.success("获取列表成功", builder
.totalNum(pageInfo.getTotal())
.totalPage(pageInfo.getPages())
.data(list)
.build());
}
/**
* @Author: Alex
* @Description: 获取图片MD5
*/
public static String getMd5(String url) {
if (url.contains("aliyuncs.com")) {
int lastSlash = url.lastIndexOf('/');
int lastDot = url.lastIndexOf('.');
if (lastSlash != -1 && lastDot != -1 && lastDot > lastSlash) {
return url.substring(lastSlash + 1, lastDot);
}
} else if (url.contains("/image/")) {
int startIndex = url.lastIndexOf("/image/") + "/image/".length();
int endIndex = url.indexOf("?", startIndex);
if (endIndex == -1) {
endIndex = url.length();
}
return url.substring(startIndex, endIndex);
}
return null;
}
}

View File

@ -0,0 +1,12 @@
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test_alex?characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
username: root
password: ALEXzcz123456
redis:
host: localhost
password: ALEXzcz123456
port: 6379
database: 0

View File

@ -0,0 +1,12 @@
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://117.72.202.202:3306/test_alex?characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
username: alex
password: ALEXzcz123456
redis:
host: 117.72.202.202
password: ALEXzcz123456
port: 6379
database: 0

View File

@ -0,0 +1,12 @@
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://117.72.202.202:3306/test_alex?characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
username: alex
password: ALEXzcz123456
redis:
host: 117.72.202.202
password: ALEXzcz123456
port: 6379
database: 0

View File

@ -0,0 +1,41 @@
server:
address: 0.0.0.0
port: 8888
spring:
profiles:
active: dev # 默认激活开发环境
#配置mybatis
mybatis:
configuration:
auto-mapping-behavior: full
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
type-aliases-package: com.anytrek.entity # 配置别名路径
mapper-locations: classpath:mapper/*.xml # 配置 XML 文件位置
#配置mybatis-plus
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
global-config:
db-config:
table-prefix: t_
id-type: auto
#配置分页插件
pagehelper:
helperDialect: mysql
params: count=countSql
reasonable: true
supportMethodsArguments: true
#配置日志
logging:
level:
root: INFO #根日志配置,整个应用程序的默认日志级别为 INFO
com.anytrek: DEBUG #com.anytrek 包下的类的日志级别设置为 DEBUG
org.apache.ibatis: INFO #MyBatis 日志级别设置为 INFO
com.zaxxer.hikari: INFO #HikariCP 的日志级别设置为 INFO
org.springframework.web.socket: DEBUG
org.springframework.web.socket.server.support: DEBUG
org:
springframework:
integration: DEBUG
messaging: DEBUG

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ctgu.alexapi.mapper.UsersMapper">
<resultMap id="BaseResultMap" type="com.ctgu.alexapi.entity.UsersEntity">
<id property="id" column="id" jdbcType="INTEGER"/>
<result property="username" column="username" jdbcType="VARCHAR"/>
<result property="password" column="password" jdbcType="VARCHAR"/>
</resultMap>
<sql id="Base_Column_List">
id,username,password
</sql>
</mapper>

View File

@ -0,0 +1,13 @@
package com.ctgu.alexapi;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class AlexApiApplicationTests {
@Test
void contextLoads() {
}
}