Skip to content

Commit cfdf243

Browse files
authored
Merge pull request #59 from kongying-tavern/feat/image-api
feat: image alist host
2 parents 501cd38 + df6d7cc commit cfdf243

File tree

31 files changed

+535
-62
lines changed

31 files changed

+535
-62
lines changed

Diff for: .gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ database/**/.back_*
4646
application-datasource-dev.yml
4747
application-datasource-prod.yml
4848
application-datasource-uat.yml
49+
application-image-dev.yml
50+
application-image-prod.yml
51+
application-image-uat.yml
4952

5053
### Docker ###
5154
docker/.env

Diff for: docker/Makefile.toml

+3-13
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,9 @@ check_env
3434
ENV_FILE = get_env ENV_FILE
3535
PROJECT_NAME = get_env PROJECT_NAME
3636
37-
# Generate datasource YAML
38-
yaml_ds_tpl = readfile ./config/api/application-datasource-tpl.yml
39-
yaml_ds_slots = json_parse --collection "[\"PGSQL_USER\", \"PGSQL_PASS\", \"PGSQL_DB\", \"PGSQL_SCHEMA\"]"
40-
yaml_ds_content = replace_env_value ${yaml_ds_tpl} ${yaml_ds_slots}
41-
release ${yaml_ds_slots}
42-
writefile ./cache/application-datasource.yml "${yaml_ds_content}"
43-
44-
# Generate nacos YAML
45-
yaml_nacos_tpl = readfile ./config/api/application-nacos-tpl.yml
46-
yaml_nacos_slots = json_parse --collection "[\"NACOS_USER\", \"NACOS_PASS\"]"
47-
yaml_nacos_content = replace_env_value ${yaml_nacos_tpl} ${yaml_nacos_slots}
48-
release ${yaml_nacos_slots}
49-
writefile ./cache/application-nacos.yml "${yaml_nacos_content}"
37+
replace_env_values_in_file ${ENV_FILE} ./config/api/application-datasource-tpl.yml ./cache/application-datasource.yml
38+
replace_env_values_in_file ${ENV_FILE} ./config/api/application-nacos-tpl.yml ./cache/application-nacos.yml
39+
replace_env_values_in_file ${ENV_FILE} ./config/api/application-image-tpl.yml ./cache/application-image.yml
5040
5141
docker_build "${ENV_FILE}" "${PROJECT_NAME}" "./composer/docker-compose.dev-build.yml"
5242
'''

Diff for: docker/composer/docker-compose.dataenv.yml

+6-8
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,10 @@ services:
2020
restart: always
2121
healthcheck:
2222
test: ["CMD-SHELL", "pg_isready -h localhost -p 5432 -U \"${PGSQL_USER}\" | grep accept || exit 1"]
23-
interval: 5m
24-
timeout: 60s
23+
interval: 30s
24+
timeout: 30s
2525
retries: 3
26-
start_period: 30s
27-
start_interval: 5s
26+
start_period: 2m
2827
nacos:
2928
container_name: gsapi-nacos
3029
hostname: gsapi-nacos
@@ -42,8 +41,7 @@ services:
4241
restart: always
4342
healthcheck:
4443
test: ["CMD-SHELL", "curl -f 'http://localhost:8848/nacos' || exit 1"]
45-
interval: 5m
46-
timeout: 60s
44+
interval: 30s
45+
timeout: 30s
4746
retries: 3
48-
start_period: 60s
49-
start_interval: 5s
47+
start_period: 2m

Diff for: docker/composer/docker-compose.dev-api.yml

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ services:
1616
gsapi-api:
1717
aliases:
1818
- api.local
19+
gsapi-img-alist:
20+
aliases:
21+
- img-alist.local
1922
volumes:
2023
- ${DATA_DIR}/api/logs:/data/logs
2124
ports:

Diff for: docker/composer/docker-compose.dev-build.Dockerfile

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ ADD docker/cache docker/cache
1717
RUN --mount=type=cache,target=/root/.m2,rw \
1818
cp -f ./docker/cache/application-datasource.yml ./genshin-map-config/src/main/resources-dev/application-datasource-dev.yml && \
1919
cp -f ./docker/cache/application-nacos.yml ./genshin-map-config/src/main/resources-dev/application-nacos-dev.yml && \
20+
cp -f ./docker/cache/application-image.yml ./genshin-map-config/src/main/resources-dev/application-image-dev.yml && \
2021
cp -f ./docker/cache/application-nacos.yml ./genshin-map-ability/genshin-map-ability-gateway/src/main/resources/application.yml && \
2122
mvn clean package -s ./docker/config/maven.xml -P dev -f pom.xml && \
2223
mkdir -p ./dist && \

Diff for: docker/composer/docker-compose.img-alist-run.yml

+10-13
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@ services:
1919
restart: always
2020
healthcheck:
2121
test: ["CMD", "redis-cli", "ping"]
22-
interval: 1m
23-
timeout: 60s
22+
interval: 30s
23+
timeout: 30s
2424
retries: 3
25-
start_period: 15s
26-
start_interval: 10s
25+
start_period: 2m
2726
minio:
2827
container_name: gsapi-minio
2928
hostname: gsapi-minio
@@ -45,11 +44,10 @@ services:
4544
restart: always
4645
healthcheck:
4746
test: ["CMD", "bash", "/minio/healthcheck.sh"]
48-
interval: 1m
49-
timeout: 60s
50-
retries: 5
51-
start_period: 30s
52-
start_interval: 5s
47+
interval: 30s
48+
timeout: 30s
49+
retries: 3
50+
start_period: 2m
5351
minio-proxy:
5452
container_name: gsapi-minio-proxy
5553
hostname: gsapi-minio-proxy
@@ -110,11 +108,10 @@ services:
110108
restart: always
111109
healthcheck:
112110
test: ["CMD", "bash", "/alist/healthcheck.sh"]
113-
interval: 1m
114-
timeout: 60s
111+
interval: 30s
112+
timeout: 30s
115113
retries: 3
116-
start_period: 15s
117-
start_interval: 10s
114+
start_period: 2m
118115

119116
# Initialization services
120117
minio-init:

Diff for: docker/config/api/api-core.service

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Wants=network-online.target
88
Type=simple
99
User=root
1010
WorkingDirectory=/data/
11-
ExecStart=/bin/java -server -jar /data/genshin-map-api-core-core-1.0.jar
11+
ExecStart=/bin/java -server -Dfile.encoding=UTF-8 -jar /data/genshin-map-api-core-core-1.0.jar
1212
ExecStop=/bin/kill -s QUIT $MAINPID
1313
Restart=always
1414
StandOutput=syslog

Diff for: docker/config/api/api-gateway.service

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Wants=network-online.target
88
Type=simple
99
User=root
1010
WorkingDirectory=/data/
11-
ExecStart=/bin/java -server -jar /data/genshin-map-ability-gateway-1.0.jar
11+
ExecStart=/bin/java -server -Dfile.encoding=UTF-8 -jar /data/genshin-map-ability-gateway-1.0.jar
1212
ExecStop=/bin/kill -s QUIT $MAINPID
1313
Restart=always
1414
StandOutput=syslog

Diff for: docker/config/api/application-image-tpl.yml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
image:
2+
minio:
3+
endpoint: http://minio-proxy.local:80
4+
key: {{MINIO_KEY}}
5+
secret: {{MINIO_SECRET}}
6+
bucket: {{MINIO_BUCKET_IMAGE}}
7+
static-url-template: http://localhost:{{MINIO_PORT_PROXY}}/[[fullPath]]

Diff for: docker/config/img-alist-builder/minio-init/init.sh

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ function step_init_minio () {
1010
mc admin user svcacct add \
1111
--access-key "${MINIO_KEY}" \
1212
--secret-key "${MINIO_SECRET}" \
13+
--policy /data/policy/uploadService.json \
14+
--name "UploadSvc" \
15+
--description "Image Upload Service" \
1316
minio "${MINIO_ROOT_USERNAME}"
1417
}
1518

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"Version": "2012-10-17",
3+
"Statement": [
4+
{
5+
"Effect": "Allow",
6+
"Action": [
7+
"admin:*"
8+
]
9+
},
10+
{
11+
"Effect": "Allow",
12+
"Action": [
13+
"kms:*"
14+
]
15+
},
16+
{
17+
"Effect": "Allow",
18+
"Action": [
19+
"s3:*"
20+
],
21+
"Resource": [
22+
"arn:aws:s3:::*"
23+
]
24+
}
25+
]
26+
}

Diff for: docker/makefile/util.env.ds

+16-8
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,30 @@ end
3737

3838
fn get_env_map
3939
env_file = get_env ENV_FILE
40-
env_content = readfile "${env_file}"
40+
env_content = readfile "${1}"
4141
env_map = map
4242
map_load_properties ${env_map} "${env_content}"
4343
return ${env_map}
4444
end
4545

46-
fn replace_env_value
47-
env_map = get_env_map
46+
fn replace_env_values
4847
text = set "${1}"
48+
env_map_keys = map_keys ${2}
4949

50-
for key in ${2}
51-
pattern = concat "{{" "${key}" "}}"
52-
val = map_get ${env_map} "${key}"
53-
text = replace "${text}" "${pattern}" "${val}"
50+
for env_key in ${env_map_keys}
51+
env_slot = concat "{{" "${env_key}" "}}"
52+
env_val = map_get ${2} "${env_key}"
53+
text = replace "${text}" "${env_slot}" "${env_val}"
5454
end
5555

56-
release ${env_map}
56+
release ${env_map_keys}
5757
return ${text}
5858
end
59+
60+
fn replace_env_values_in_file
61+
env_map = get_env_map "${1}"
62+
text_src = readfile "${2}"
63+
text_tar = replace_env_values "${text_src}" ${env_map}
64+
writefile "${3}" "${text_tar}"
65+
release ${env_map}
66+
end

Diff for: genshin-map-ability/genshin-map-ability-gateway/src/main/resources/bootstrap.yml

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ genshin:
4444
- /api/punctuate/**
4545
- /api/marker/**
4646
- /api/marker_link/**
47+
- /api/res/**
4748
MAP_MANAGER:
4849
- /api/punctuate_audit/**
4950
- /api/tag/**

Diff for: genshin-map-api/genshin-map-api-core/genshin-map-api-core-core/pom.xml

+6
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@
4949
</dependency>
5050
<!--END Auth用依赖-->
5151

52+
<!-- minio client -->
53+
<dependency>
54+
<groupId>io.minio</groupId>
55+
<artifactId>minio</artifactId>
56+
</dependency>
57+
5258
</dependencies>
5359

5460
</project>

Diff for: genshin-map-api/genshin-map-api-core/genshin-map-api-core-core/src/main/java/site/yuanshen/genshin/core/aspect/WebLogAspect.java

+31-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package site.yuanshen.genshin.core.aspect;
22

33
import com.alibaba.fastjson2.JSON;
4+
import com.alibaba.fastjson2.JSONWriter;
45
import lombok.extern.slf4j.Slf4j;
56
import org.aspectj.lang.JoinPoint;
67
import org.aspectj.lang.ProceedingJoinPoint;
@@ -9,8 +10,11 @@
910
import org.springframework.util.StopWatch;
1011
import org.springframework.web.context.request.RequestContextHolder;
1112
import org.springframework.web.context.request.ServletRequestAttributes;
13+
import org.springframework.web.multipart.MultipartFile;
1214

1315
import javax.servlet.http.HttpServletRequest;
16+
import java.util.ArrayList;
17+
import java.util.List;
1418

1519
/**
1620
* @author kraken
@@ -24,6 +28,30 @@ public class WebLogAspect {
2428
private static final String LINE_SEPARATOR = System.lineSeparator();
2529
public static final ThreadLocal<StopWatch> STOP_WATCH_THREAD_LOCAL = new ThreadLocal<>();
2630

31+
public static final JSONWriter.Feature[] defaultWriteFeatures = new JSONWriter.Feature[]{
32+
JSONWriter.Feature.BrowserCompatible,
33+
JSONWriter.Feature.WriteEnumUsingToString,
34+
JSONWriter.Feature.WriteBigDecimalAsPlain,
35+
JSONWriter.Feature.WriteEnumUsingToString,
36+
JSONWriter.Feature.WriteNonStringKeyAsString
37+
};
38+
39+
private Object[] sanitizeArgs(Object[] args) {
40+
final Object[] sanitizedArgs = List.of(args)
41+
.parallelStream()
42+
.map(arg -> {
43+
if(arg == null) {
44+
return null;
45+
} else if(arg instanceof MultipartFile) {
46+
return "@[Instance MultipartFile]";
47+
} else {
48+
return arg;
49+
}
50+
})
51+
.toArray();
52+
return sanitizedArgs;
53+
}
54+
2755
/**
2856
* 以 controller 包下定义的所有请求为切入点
2957
*/
@@ -64,7 +92,7 @@ public void doBefore(JoinPoint joinPoint) {
6492
+ request.getRemoteAddr()
6593
+ LINE_SEPARATOR
6694
+ "请求入参 : "
67-
+ JSON.toJSONString(joinPoint.getArgs())
95+
+ JSON.toJSONString(sanitizeArgs(joinPoint.getArgs()), defaultWriteFeatures)
6896
+ LINE_SEPARATOR);
6997
}
7098

@@ -101,7 +129,7 @@ public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable
101129
throw e;
102130
} finally {
103131
STOP_WATCH_THREAD_LOCAL.get().stop();
104-
String s = JSON.toJSONString(result);
132+
String s = JSON.toJSONString(result, defaultWriteFeatures);
105133
log.info(
106134
LINE_SEPARATOR
107135
+ "URL : "
@@ -124,4 +152,4 @@ public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable
124152
STOP_WATCH_THREAD_LOCAL.remove();
125153
}
126154
}
127-
}
155+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package site.yuanshen.genshin.core.controller;
2+
3+
import io.swagger.v3.oas.annotations.Operation;
4+
import io.swagger.v3.oas.annotations.tags.Tag;
5+
import lombok.RequiredArgsConstructor;
6+
import org.springframework.web.bind.annotation.*;
7+
import org.springframework.web.multipart.MultipartFile;
8+
import site.yuanshen.common.web.response.R;
9+
import site.yuanshen.common.web.response.RUtils;
10+
import site.yuanshen.data.dto.ResourceUploadDto;
11+
import site.yuanshen.data.vo.ResourceUploadVo;
12+
import site.yuanshen.genshin.core.service.ResourceService;
13+
14+
@RestController
15+
@RequiredArgsConstructor
16+
@RequestMapping("/api/res")
17+
@Tag(name = "resource", description = "资源API")
18+
public class ResourceController {
19+
20+
private final ResourceService resourceService;
21+
22+
@PutMapping("/upload/image")
23+
@Operation(summary = "上传图片", description = "上传图片至图床并返回访问地址")
24+
public R<ResourceUploadVo> uploadImage(@RequestParam(value = "file", required = false) MultipartFile file, @ModelAttribute ResourceUploadVo uploadVo) {
25+
R<ResourceUploadVo> result = RUtils.create(
26+
resourceService.uploadImage(
27+
(new ResourceUploadDto(uploadVo)).withFile(file)
28+
)
29+
);
30+
return result;
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package site.yuanshen.genshin.core.sao;
2+
3+
import io.minio.MinioClient;
4+
import org.springframework.web.multipart.MultipartFile;
5+
import site.yuanshen.common.core.exception.minio.BucketNotFoundException;
6+
import site.yuanshen.common.core.exception.minio.ObjectPutException;
7+
8+
public interface MinioSao {
9+
10+
/**
11+
* 创建 MinIO 客户端连接
12+
*/
13+
MinioClient createClient(String endpoint, String key, String secret);
14+
15+
/**
16+
* 检查存储桶是否存在
17+
*/
18+
boolean bucketExist(MinioClient client, String bucket) throws BucketNotFoundException;
19+
20+
/**
21+
* 检查对象是否存在
22+
*/
23+
boolean objectExists(MinioClient client, String bucket, String object);
24+
25+
String putObject(MinioClient client, String bucket, String object, MultipartFile file) throws ObjectPutException;
26+
}

0 commit comments

Comments
 (0)